f485fe9f0b668998e20c2559b9f3be3c8847f868
[nivanova/samba-autobuild/.git] / source3 / smbd / smb2_read.c
1 /*
2    Unix SMB/CIFS implementation.
3    Core SMB2 server
4
5    Copyright (C) Stefan Metzmacher 2009
6
7    This program is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 3 of the License, or
10    (at your option) any later version.
11
12    This program is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16
17    You should have received a copy of the GNU General Public License
18    along with this program.  If not, see <http://www.gnu.org/licenses/>.
19 */
20
21 #include "includes.h"
22 #include "system/filesys.h"
23 #include "smbd/smbd.h"
24 #include "smbd/globals.h"
25 #include "../libcli/smb/smb_common.h"
26 #include "libcli/security/security.h"
27 #include "../lib/util/tevent_ntstatus.h"
28 #include "rpc_server/srv_pipe_hnd.h"
29
30 static struct tevent_req *smbd_smb2_read_send(TALLOC_CTX *mem_ctx,
31                                               struct tevent_context *ev,
32                                               struct smbd_smb2_request *smb2req,
33                                               struct files_struct *in_fsp,
34                                               uint32_t in_length,
35                                               uint64_t in_offset,
36                                               uint32_t in_minimum,
37                                               uint32_t in_remaining);
38 static NTSTATUS smbd_smb2_read_recv(struct tevent_req *req,
39                                     TALLOC_CTX *mem_ctx,
40                                     DATA_BLOB *out_data,
41                                     uint32_t *out_remaining);
42
43 static void smbd_smb2_request_read_done(struct tevent_req *subreq);
44 NTSTATUS smbd_smb2_request_process_read(struct smbd_smb2_request *req)
45 {
46         struct smbXsrv_connection *xconn = req->xconn;
47         NTSTATUS status;
48         const uint8_t *inbody;
49         uint32_t in_length;
50         uint64_t in_offset;
51         uint64_t in_file_id_persistent;
52         uint64_t in_file_id_volatile;
53         struct files_struct *in_fsp;
54         uint32_t in_minimum_count;
55         uint32_t in_remaining_bytes;
56         struct tevent_req *subreq;
57
58         status = smbd_smb2_request_verify_sizes(req, 0x31);
59         if (!NT_STATUS_IS_OK(status)) {
60                 return smbd_smb2_request_error(req, status);
61         }
62         inbody = SMBD_SMB2_IN_BODY_PTR(req);
63
64         in_length               = IVAL(inbody, 0x04);
65         in_offset               = BVAL(inbody, 0x08);
66         in_file_id_persistent   = BVAL(inbody, 0x10);
67         in_file_id_volatile     = BVAL(inbody, 0x18);
68         in_minimum_count        = IVAL(inbody, 0x20);
69         in_remaining_bytes      = IVAL(inbody, 0x28);
70
71         /* check the max read size */
72         if (in_length > xconn->smb2.server.max_read) {
73                 DEBUG(2,("smbd_smb2_request_process_read: "
74                          "client ignored max read: %s: 0x%08X: 0x%08X\n",
75                         __location__, in_length, xconn->smb2.server.max_read));
76                 return smbd_smb2_request_error(req, NT_STATUS_INVALID_PARAMETER);
77         }
78
79         status = smbd_smb2_request_verify_creditcharge(req, in_length);
80         if (!NT_STATUS_IS_OK(status)) {
81                 return smbd_smb2_request_error(req, status);
82         }
83
84         in_fsp = file_fsp_smb2(req, in_file_id_persistent, in_file_id_volatile);
85         if (in_fsp == NULL) {
86                 return smbd_smb2_request_error(req, NT_STATUS_FILE_CLOSED);
87         }
88
89         subreq = smbd_smb2_read_send(req, req->sconn->ev_ctx,
90                                      req, in_fsp,
91                                      in_length,
92                                      in_offset,
93                                      in_minimum_count,
94                                      in_remaining_bytes);
95         if (subreq == NULL) {
96                 return smbd_smb2_request_error(req, NT_STATUS_NO_MEMORY);
97         }
98         tevent_req_set_callback(subreq, smbd_smb2_request_read_done, req);
99
100         return smbd_smb2_request_pending_queue(req, subreq, 500);
101 }
102
103 static void smbd_smb2_request_read_done(struct tevent_req *subreq)
104 {
105         struct smbd_smb2_request *req = tevent_req_callback_data(subreq,
106                                         struct smbd_smb2_request);
107         DATA_BLOB outbody;
108         DATA_BLOB outdyn;
109         uint8_t out_data_offset;
110         DATA_BLOB out_data_buffer = data_blob_null;
111         uint32_t out_data_remaining = 0;
112         NTSTATUS status;
113         NTSTATUS error; /* transport error */
114
115         status = smbd_smb2_read_recv(subreq,
116                                      req,
117                                      &out_data_buffer,
118                                      &out_data_remaining);
119         TALLOC_FREE(subreq);
120         if (!NT_STATUS_IS_OK(status)) {
121                 error = smbd_smb2_request_error(req, status);
122                 if (!NT_STATUS_IS_OK(error)) {
123                         smbd_server_connection_terminate(req->xconn,
124                                                          nt_errstr(error));
125                         return;
126                 }
127                 return;
128         }
129
130         out_data_offset = SMB2_HDR_BODY + 0x10;
131
132         outbody = smbd_smb2_generate_outbody(req, 0x10);
133         if (outbody.data == NULL) {
134                 error = smbd_smb2_request_error(req, NT_STATUS_NO_MEMORY);
135                 if (!NT_STATUS_IS_OK(error)) {
136                         smbd_server_connection_terminate(req->xconn,
137                                                          nt_errstr(error));
138                         return;
139                 }
140                 return;
141         }
142
143         SSVAL(outbody.data, 0x00, 0x10 + 1);    /* struct size */
144         SCVAL(outbody.data, 0x02,
145               out_data_offset);                 /* data offset */
146         SCVAL(outbody.data, 0x03, 0);           /* reserved */
147         SIVAL(outbody.data, 0x04,
148               out_data_buffer.length);          /* data length */
149         SIVAL(outbody.data, 0x08,
150               out_data_remaining);              /* data remaining */
151         SIVAL(outbody.data, 0x0C, 0);           /* reserved */
152
153         outdyn = out_data_buffer;
154
155         error = smbd_smb2_request_done(req, outbody, &outdyn);
156         if (!NT_STATUS_IS_OK(error)) {
157                 smbd_server_connection_terminate(req->xconn,
158                                                  nt_errstr(error));
159                 return;
160         }
161 }
162
163 struct smbd_smb2_read_state {
164         struct smbd_smb2_request *smb2req;
165         struct smb_request *smbreq;
166         files_struct *fsp;
167         uint32_t in_length;
168         uint64_t in_offset;
169         uint32_t in_minimum;
170         DATA_BLOB out_headers;
171         uint8_t _out_hdr_buf[NBT_HDR_SIZE + SMB2_HDR_BODY + 0x10];
172         DATA_BLOB out_data;
173         uint32_t out_remaining;
174 };
175
176 static int smb2_smb2_read_state_deny_destructor(struct smbd_smb2_read_state *state)
177 {
178         return -1;
179 }
180
181 /* struct smbd_smb2_read_state destructor. Send the SMB2_READ data. */
182 static int smb2_sendfile_send_data(struct smbd_smb2_read_state *state)
183 {
184         struct lock_struct lock;
185         uint32_t in_length = state->in_length;
186         uint64_t in_offset = state->in_offset;
187         files_struct *fsp = state->fsp;
188         const DATA_BLOB *hdr = state->smb2req->queue_entry.sendfile_header;
189         struct smbXsrv_connection *xconn = state->smb2req->xconn;
190         ssize_t nread;
191         ssize_t ret;
192         int saved_errno;
193
194         nread = SMB_VFS_SENDFILE(xconn->transport.sock,
195                                  fsp,
196                                  hdr,
197                                  in_offset,
198                                  in_length);
199         DEBUG(10,("smb2_sendfile_send_data: SMB_VFS_SENDFILE returned %d on file %s\n",
200                 (int)nread,
201                 fsp_str_dbg(fsp) ));
202
203         if (nread == -1) {
204                 saved_errno = errno;
205
206                 /*
207                  * Returning ENOSYS means no data at all was sent.
208                    Do this as a normal read. */
209                 if (errno == ENOSYS) {
210                         goto normal_read;
211                 }
212
213                 if (errno == EINTR) {
214                         /*
215                          * Special hack for broken Linux with no working sendfile. If we
216                          * return EINTR we sent the header but not the rest of the data.
217                          * Fake this up by doing read/write calls.
218                          */
219                         set_use_sendfile(SNUM(fsp->conn), false);
220                         nread = fake_sendfile(xconn, fsp, in_offset, in_length);
221                         if (nread == -1) {
222                                 saved_errno = errno;
223                                 DEBUG(0,("smb2_sendfile_send_data: fake_sendfile "
224                                          "failed for file %s (%s) for client %s. "
225                                          "Terminating\n",
226                                          fsp_str_dbg(fsp), strerror(saved_errno),
227                                          smbXsrv_connection_dbg(xconn)));
228                                 exit_server_cleanly("smb2_sendfile_send_data: "
229                                         "fake_sendfile failed");
230                         }
231                         goto out;
232                 }
233
234                 DEBUG(0,("smb2_sendfile_send_data: sendfile failed for file "
235                          "%s (%s) for client %s. Terminating\n",
236                          fsp_str_dbg(fsp), strerror(saved_errno),
237                          smbXsrv_connection_dbg(xconn)));
238                 exit_server_cleanly("smb2_sendfile_send_data: sendfile failed");
239         } else if (nread == 0) {
240                 /*
241                  * Some sendfile implementations return 0 to indicate
242                  * that there was a short read, but nothing was
243                  * actually written to the socket.  In this case,
244                  * fallback to the normal read path so the header gets
245                  * the correct byte count.
246                  */
247                 DEBUG(3, ("send_file_readX: sendfile sent zero bytes "
248                         "falling back to the normal read: %s\n",
249                         fsp_str_dbg(fsp)));
250                 goto normal_read;
251         }
252
253         /*
254          * We got a short read
255          */
256         goto out;
257
258 normal_read:
259         /* Send out the header. */
260         ret = write_data(xconn->transport.sock,
261                          (const char *)hdr->data, hdr->length);
262         if (ret != hdr->length) {
263                 saved_errno = errno;
264                 DEBUG(0,("smb2_sendfile_send_data: write_data failed for file "
265                          "%s (%s) for client %s. Terminating\n",
266                          fsp_str_dbg(fsp), strerror(saved_errno),
267                          smbXsrv_connection_dbg(xconn)));
268                 exit_server_cleanly("smb2_sendfile_send_data: write_data failed");
269         }
270         nread = fake_sendfile(xconn, fsp, in_offset, in_length);
271         if (nread == -1) {
272                 saved_errno = errno;
273                 DEBUG(0,("smb2_sendfile_send_data: fake_sendfile "
274                          "failed for file %s (%s) for client %s. "
275                          "Terminating\n",
276                          fsp_str_dbg(fsp), strerror(saved_errno),
277                          smbXsrv_connection_dbg(xconn)));
278                 exit_server_cleanly("smb2_sendfile_send_data: "
279                         "fake_sendfile failed");
280         }
281
282   out:
283
284         if (nread < in_length) {
285                 ret = sendfile_short_send(xconn, fsp, nread,
286                                           hdr->length, in_length);
287                 if (ret == -1) {
288                         saved_errno = errno;
289                         DEBUG(0,("smb2_sendfile_send_data: sendfile_short_send "
290                                  "failed for file %s (%s) for client %s. "
291                                  "Terminating\n",
292                                  fsp_str_dbg(fsp), strerror(saved_errno),
293                                  smbXsrv_connection_dbg(xconn)));
294                         exit_server_cleanly("smb2_sendfile_send_data: "
295                                 "sendfile_short_send failed");
296                 }
297         }
298
299         init_strict_lock_struct(fsp,
300                                 fsp->op->global->open_persistent_id,
301                                 in_offset,
302                                 in_length,
303                                 READ_LOCK,
304                                 &lock);
305
306         SMB_VFS_STRICT_UNLOCK(fsp->conn, fsp, &lock);
307         return 0;
308 }
309
310 static NTSTATUS schedule_smb2_sendfile_read(struct smbd_smb2_request *smb2req,
311                                         struct smbd_smb2_read_state *state)
312 {
313         files_struct *fsp = state->fsp;
314
315         /*
316          * We cannot use sendfile if...
317          * We were not configured to do so OR
318          * Signing is active OR
319          * This is a compound SMB2 operation OR
320          * fsp is a STREAM file OR
321          * We're using a write cache OR
322          * It's not a regular file OR
323          * Requested offset is greater than file size OR
324          * there's not enough data in the file.
325          * Phew :-). Luckily this means most
326          * reads on most normal files. JRA.
327         */
328
329         if (!lp__use_sendfile(SNUM(fsp->conn)) ||
330             smb2req->do_signing ||
331             smb2req->do_encryption ||
332             smb2req->in.vector_count >= (2*SMBD_SMB2_NUM_IOV_PER_REQ) ||
333             (fsp->base_fsp != NULL) ||
334             (fsp->wcp != NULL) ||
335             (!S_ISREG(fsp->fsp_name->st.st_ex_mode)) ||
336             (state->in_offset >= fsp->fsp_name->st.st_ex_size) ||
337             (fsp->fsp_name->st.st_ex_size < state->in_offset + state->in_length))
338         {
339                 return NT_STATUS_RETRY;
340         }
341
342         /* We've already checked there's this amount of data
343            to read. */
344         state->out_data.length = state->in_length;
345         state->out_remaining = 0;
346
347         state->out_headers = data_blob_const(state->_out_hdr_buf,
348                                              sizeof(state->_out_hdr_buf));
349         return NT_STATUS_OK;
350 }
351
352 static void smbd_smb2_read_pipe_done(struct tevent_req *subreq);
353
354 /*******************************************************************
355  Common read complete processing function for both synchronous and
356  asynchronous reads.
357 *******************************************************************/
358
359 NTSTATUS smb2_read_complete(struct tevent_req *req, ssize_t nread, int err)
360 {
361         struct smbd_smb2_read_state *state = tevent_req_data(req,
362                                         struct smbd_smb2_read_state);
363         files_struct *fsp = state->fsp;
364
365         if (nread < 0) {
366                 NTSTATUS status = map_nt_error_from_unix(err);
367
368                 DEBUG( 3,( "smb2_read_complete: file %s nread = %d. "
369                         "Error = %s (NTSTATUS %s)\n",
370                         fsp_str_dbg(fsp),
371                         (int)nread,
372                         strerror(err),
373                         nt_errstr(status)));
374
375                 return status;
376         }
377         if (nread == 0 && state->in_length != 0) {
378                 DEBUG(5,("smb2_read_complete: read_file[%s] end of file\n",
379                         fsp_str_dbg(fsp)));
380                 return NT_STATUS_END_OF_FILE;
381         }
382
383         if (nread < state->in_minimum) {
384                 DEBUG(5,("smb2_read_complete: read_file[%s] read less %d than "
385                         "minimum requested %u. Returning end of file\n",
386                         fsp_str_dbg(fsp),
387                         (int)nread,
388                         (unsigned int)state->in_minimum));
389                 return NT_STATUS_END_OF_FILE;
390         }
391
392         DEBUG(3,("smbd_smb2_read: %s, file %s, length=%lu offset=%lu read=%lu\n",
393                 fsp_fnum_dbg(fsp),
394                 fsp_str_dbg(fsp),
395                 (unsigned long)state->in_length,
396                 (unsigned long)state->in_offset,
397                 (unsigned long)nread));
398
399         state->out_data.length = nread;
400         state->out_remaining = 0;
401
402         return NT_STATUS_OK;
403 }
404
405 static bool smbd_smb2_read_cancel(struct tevent_req *req)
406 {
407         struct smbd_smb2_read_state *state =
408                 tevent_req_data(req,
409                 struct smbd_smb2_read_state);
410
411         return cancel_smb2_aio(state->smbreq);
412 }
413
414 static struct tevent_req *smbd_smb2_read_send(TALLOC_CTX *mem_ctx,
415                                               struct tevent_context *ev,
416                                               struct smbd_smb2_request *smb2req,
417                                               struct files_struct *fsp,
418                                               uint32_t in_length,
419                                               uint64_t in_offset,
420                                               uint32_t in_minimum,
421                                               uint32_t in_remaining)
422 {
423         NTSTATUS status;
424         struct tevent_req *req = NULL;
425         struct smbd_smb2_read_state *state = NULL;
426         struct smb_request *smbreq = NULL;
427         connection_struct *conn = smb2req->tcon->compat;
428         ssize_t nread = -1;
429         struct lock_struct lock;
430         int saved_errno;
431
432         req = tevent_req_create(mem_ctx, &state,
433                                 struct smbd_smb2_read_state);
434         if (req == NULL) {
435                 return NULL;
436         }
437         state->smb2req = smb2req;
438         state->in_length = in_length;
439         state->in_offset = in_offset;
440         state->in_minimum = in_minimum;
441         state->out_data = data_blob_null;
442         state->out_remaining = 0;
443
444         DEBUG(10,("smbd_smb2_read: %s - %s\n",
445                   fsp_str_dbg(fsp), fsp_fnum_dbg(fsp)));
446
447         smbreq = smbd_smb2_fake_smb_request(smb2req);
448         if (tevent_req_nomem(smbreq, req)) {
449                 return tevent_req_post(req, ev);
450         }
451         state->smbreq = smbreq;
452
453         if (fsp->is_directory) {
454                 tevent_req_nterror(req, NT_STATUS_INVALID_DEVICE_REQUEST);
455                 return tevent_req_post(req, ev);
456         }
457
458         state->fsp = fsp;
459
460         if (IS_IPC(smbreq->conn)) {
461                 struct tevent_req *subreq = NULL;
462
463                 state->out_data = data_blob_talloc(state, NULL, in_length);
464                 if (in_length > 0 && tevent_req_nomem(state->out_data.data, req)) {
465                         return tevent_req_post(req, ev);
466                 }
467
468                 if (!fsp_is_np(fsp)) {
469                         tevent_req_nterror(req, NT_STATUS_FILE_CLOSED);
470                         return tevent_req_post(req, ev);
471                 }
472
473                 subreq = np_read_send(state, ev,
474                                       fsp->fake_file_handle,
475                                       state->out_data.data,
476                                       state->out_data.length);
477                 if (tevent_req_nomem(subreq, req)) {
478                         return tevent_req_post(req, ev);
479                 }
480                 tevent_req_set_callback(subreq,
481                                         smbd_smb2_read_pipe_done,
482                                         req);
483                 return req;
484         }
485
486         if (!CHECK_READ(fsp, smbreq)) {
487                 tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
488                 return tevent_req_post(req, ev);
489         }
490
491         status = schedule_smb2_aio_read(fsp->conn,
492                                 smbreq,
493                                 fsp,
494                                 state,
495                                 &state->out_data,
496                                 (off_t)in_offset,
497                                 (size_t)in_length);
498
499         if (NT_STATUS_IS_OK(status)) {
500                 /*
501                  * Doing an async read, allow this
502                  * request to be canceled
503                  */
504                 tevent_req_set_cancel_fn(req, smbd_smb2_read_cancel);
505                 return req;
506         }
507
508         if (!NT_STATUS_EQUAL(status, NT_STATUS_RETRY)) {
509                 /* Real error in setting up aio. Fail. */
510                 tevent_req_nterror(req, status);
511                 return tevent_req_post(req, ev);
512         }
513
514         /* Fallback to synchronous. */
515
516         init_strict_lock_struct(fsp,
517                                 fsp->op->global->open_persistent_id,
518                                 in_offset,
519                                 in_length,
520                                 READ_LOCK,
521                                 &lock);
522
523         if (!SMB_VFS_STRICT_LOCK(conn, fsp, &lock)) {
524                 tevent_req_nterror(req, NT_STATUS_FILE_LOCK_CONFLICT);
525                 return tevent_req_post(req, ev);
526         }
527
528         /* Try sendfile in preference. */
529         status = schedule_smb2_sendfile_read(smb2req, state);
530         if (NT_STATUS_IS_OK(status)) {
531                 tevent_req_done(req);
532                 return tevent_req_post(req, ev);
533         } else {
534                 if (!NT_STATUS_EQUAL(status, NT_STATUS_RETRY)) {
535                         SMB_VFS_STRICT_UNLOCK(conn, fsp, &lock);
536                         tevent_req_nterror(req, status);
537                         return tevent_req_post(req, ev);
538                 }
539         }
540
541         /* Ok, read into memory. Allocate the out buffer. */
542         state->out_data = data_blob_talloc(state, NULL, in_length);
543         if (in_length > 0 && tevent_req_nomem(state->out_data.data, req)) {
544                 SMB_VFS_STRICT_UNLOCK(conn, fsp, &lock);
545                 return tevent_req_post(req, ev);
546         }
547
548         nread = read_file(fsp,
549                           (char *)state->out_data.data,
550                           in_offset,
551                           in_length);
552
553         saved_errno = errno;
554
555         SMB_VFS_STRICT_UNLOCK(conn, fsp, &lock);
556
557         DEBUG(10,("smbd_smb2_read: file %s, %s, offset=%llu "
558                 "len=%llu returned %lld\n",
559                 fsp_str_dbg(fsp),
560                 fsp_fnum_dbg(fsp),
561                 (unsigned long long)in_offset,
562                 (unsigned long long)in_length,
563                 (long long)nread));
564
565         status = smb2_read_complete(req, nread, saved_errno);
566         if (!NT_STATUS_IS_OK(status)) {
567                 tevent_req_nterror(req, status);
568         } else {
569                 /* Success. */
570                 tevent_req_done(req);
571         }
572         return tevent_req_post(req, ev);
573 }
574
575 static void smbd_smb2_read_pipe_done(struct tevent_req *subreq)
576 {
577         struct tevent_req *req = tevent_req_callback_data(subreq,
578                                  struct tevent_req);
579         struct smbd_smb2_read_state *state = tevent_req_data(req,
580                                              struct smbd_smb2_read_state);
581         NTSTATUS status;
582         ssize_t nread = -1;
583         bool is_data_outstanding;
584
585         status = np_read_recv(subreq, &nread, &is_data_outstanding);
586         TALLOC_FREE(subreq);
587         if (!NT_STATUS_IS_OK(status)) {
588                 NTSTATUS old = status;
589                 status = nt_status_np_pipe(old);
590                 tevent_req_nterror(req, status);
591                 return;
592         }
593
594         if (nread == 0 && state->out_data.length != 0) {
595                 tevent_req_nterror(req, NT_STATUS_END_OF_FILE);
596                 return;
597         }
598
599         state->out_data.length = nread;
600         state->out_remaining = 0;
601
602         /*
603          * TODO: add STATUS_BUFFER_OVERFLOW handling, once we also
604          * handle it in SMB1 pipe_read_andx_done().
605          */
606
607         tevent_req_done(req);
608 }
609
610 static NTSTATUS smbd_smb2_read_recv(struct tevent_req *req,
611                                     TALLOC_CTX *mem_ctx,
612                                     DATA_BLOB *out_data,
613                                     uint32_t *out_remaining)
614 {
615         NTSTATUS status;
616         struct smbd_smb2_read_state *state = tevent_req_data(req,
617                                              struct smbd_smb2_read_state);
618
619         if (tevent_req_is_nterror(req, &status)) {
620                 tevent_req_received(req);
621                 return status;
622         }
623
624         *out_data = state->out_data;
625         talloc_steal(mem_ctx, out_data->data);
626         *out_remaining = state->out_remaining;
627
628         if (state->out_headers.length > 0) {
629                 talloc_steal(mem_ctx, state);
630                 talloc_set_destructor(state, smb2_smb2_read_state_deny_destructor);
631                 tevent_req_received(req);
632                 state->smb2req->queue_entry.sendfile_header = &state->out_headers;
633                 talloc_set_destructor(state, smb2_sendfile_send_data);
634         } else {
635                 tevent_req_received(req);
636         }
637
638         return NT_STATUS_OK;
639 }