0d08114a2750dd4fe619920f8de9ca2c53e8e965
[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,("%s: sendfile_short_send "
290                                  "failed for file %s (%s) for client %s. "
291                                  "Terminating\n",
292                                  __func__,
293                                  fsp_str_dbg(fsp), strerror(saved_errno),
294                                  smbXsrv_connection_dbg(xconn)));
295                         exit_server_cleanly("smb2_sendfile_send_data: "
296                                 "sendfile_short_send failed");
297                 }
298         }
299
300         init_strict_lock_struct(fsp,
301                                 fsp->op->global->open_persistent_id,
302                                 in_offset,
303                                 in_length,
304                                 READ_LOCK,
305                                 &lock);
306
307         SMB_VFS_STRICT_UNLOCK(fsp->conn, fsp, &lock);
308         return 0;
309 }
310
311 static NTSTATUS schedule_smb2_sendfile_read(struct smbd_smb2_request *smb2req,
312                                         struct smbd_smb2_read_state *state)
313 {
314         files_struct *fsp = state->fsp;
315
316         /*
317          * We cannot use sendfile if...
318          * We were not configured to do so OR
319          * Signing is active OR
320          * This is a compound SMB2 operation OR
321          * fsp is a STREAM file OR
322          * We're using a write cache OR
323          * It's not a regular file OR
324          * Requested offset is greater than file size OR
325          * there's not enough data in the file.
326          * Phew :-). Luckily this means most
327          * reads on most normal files. JRA.
328         */
329
330         if (!lp__use_sendfile(SNUM(fsp->conn)) ||
331             smb2req->do_signing ||
332             smb2req->do_encryption ||
333             smb2req->in.vector_count >= (2*SMBD_SMB2_NUM_IOV_PER_REQ) ||
334             (fsp->base_fsp != NULL) ||
335             (fsp->wcp != NULL) ||
336             (!S_ISREG(fsp->fsp_name->st.st_ex_mode)) ||
337             (state->in_offset >= fsp->fsp_name->st.st_ex_size) ||
338             (fsp->fsp_name->st.st_ex_size < state->in_offset + state->in_length))
339         {
340                 return NT_STATUS_RETRY;
341         }
342
343         /* We've already checked there's this amount of data
344            to read. */
345         state->out_data.length = state->in_length;
346         state->out_remaining = 0;
347
348         state->out_headers = data_blob_const(state->_out_hdr_buf,
349                                              sizeof(state->_out_hdr_buf));
350         return NT_STATUS_OK;
351 }
352
353 static void smbd_smb2_read_pipe_done(struct tevent_req *subreq);
354
355 /*******************************************************************
356  Common read complete processing function for both synchronous and
357  asynchronous reads.
358 *******************************************************************/
359
360 NTSTATUS smb2_read_complete(struct tevent_req *req, ssize_t nread, int err)
361 {
362         struct smbd_smb2_read_state *state = tevent_req_data(req,
363                                         struct smbd_smb2_read_state);
364         files_struct *fsp = state->fsp;
365
366         if (nread < 0) {
367                 NTSTATUS status = map_nt_error_from_unix(err);
368
369                 DEBUG( 3,( "smb2_read_complete: file %s nread = %d. "
370                         "Error = %s (NTSTATUS %s)\n",
371                         fsp_str_dbg(fsp),
372                         (int)nread,
373                         strerror(err),
374                         nt_errstr(status)));
375
376                 return status;
377         }
378         if (nread == 0 && state->in_length != 0) {
379                 DEBUG(5,("smb2_read_complete: read_file[%s] end of file\n",
380                         fsp_str_dbg(fsp)));
381                 return NT_STATUS_END_OF_FILE;
382         }
383
384         if (nread < state->in_minimum) {
385                 DEBUG(5,("smb2_read_complete: read_file[%s] read less %d than "
386                         "minimum requested %u. Returning end of file\n",
387                         fsp_str_dbg(fsp),
388                         (int)nread,
389                         (unsigned int)state->in_minimum));
390                 return NT_STATUS_END_OF_FILE;
391         }
392
393         DEBUG(3,("smbd_smb2_read: %s, file %s, length=%lu offset=%lu read=%lu\n",
394                 fsp_fnum_dbg(fsp),
395                 fsp_str_dbg(fsp),
396                 (unsigned long)state->in_length,
397                 (unsigned long)state->in_offset,
398                 (unsigned long)nread));
399
400         state->out_data.length = nread;
401         state->out_remaining = 0;
402
403         return NT_STATUS_OK;
404 }
405
406 static bool smbd_smb2_read_cancel(struct tevent_req *req)
407 {
408         struct smbd_smb2_read_state *state =
409                 tevent_req_data(req,
410                 struct smbd_smb2_read_state);
411
412         return cancel_smb2_aio(state->smbreq);
413 }
414
415 static struct tevent_req *smbd_smb2_read_send(TALLOC_CTX *mem_ctx,
416                                               struct tevent_context *ev,
417                                               struct smbd_smb2_request *smb2req,
418                                               struct files_struct *fsp,
419                                               uint32_t in_length,
420                                               uint64_t in_offset,
421                                               uint32_t in_minimum,
422                                               uint32_t in_remaining)
423 {
424         NTSTATUS status;
425         struct tevent_req *req = NULL;
426         struct smbd_smb2_read_state *state = NULL;
427         struct smb_request *smbreq = NULL;
428         connection_struct *conn = smb2req->tcon->compat;
429         ssize_t nread = -1;
430         struct lock_struct lock;
431         int saved_errno;
432
433         req = tevent_req_create(mem_ctx, &state,
434                                 struct smbd_smb2_read_state);
435         if (req == NULL) {
436                 return NULL;
437         }
438         state->smb2req = smb2req;
439         state->in_length = in_length;
440         state->in_offset = in_offset;
441         state->in_minimum = in_minimum;
442         state->out_data = data_blob_null;
443         state->out_remaining = 0;
444
445         DEBUG(10,("smbd_smb2_read: %s - %s\n",
446                   fsp_str_dbg(fsp), fsp_fnum_dbg(fsp)));
447
448         smbreq = smbd_smb2_fake_smb_request(smb2req);
449         if (tevent_req_nomem(smbreq, req)) {
450                 return tevent_req_post(req, ev);
451         }
452         state->smbreq = smbreq;
453
454         if (fsp->is_directory) {
455                 tevent_req_nterror(req, NT_STATUS_INVALID_DEVICE_REQUEST);
456                 return tevent_req_post(req, ev);
457         }
458
459         state->fsp = fsp;
460
461         if (IS_IPC(smbreq->conn)) {
462                 struct tevent_req *subreq = NULL;
463
464                 state->out_data = data_blob_talloc(state, NULL, in_length);
465                 if (in_length > 0 && tevent_req_nomem(state->out_data.data, req)) {
466                         return tevent_req_post(req, ev);
467                 }
468
469                 if (!fsp_is_np(fsp)) {
470                         tevent_req_nterror(req, NT_STATUS_FILE_CLOSED);
471                         return tevent_req_post(req, ev);
472                 }
473
474                 subreq = np_read_send(state, ev,
475                                       fsp->fake_file_handle,
476                                       state->out_data.data,
477                                       state->out_data.length);
478                 if (tevent_req_nomem(subreq, req)) {
479                         return tevent_req_post(req, ev);
480                 }
481                 tevent_req_set_callback(subreq,
482                                         smbd_smb2_read_pipe_done,
483                                         req);
484                 return req;
485         }
486
487         if (!CHECK_READ(fsp, smbreq)) {
488                 tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
489                 return tevent_req_post(req, ev);
490         }
491
492         status = schedule_smb2_aio_read(fsp->conn,
493                                 smbreq,
494                                 fsp,
495                                 state,
496                                 &state->out_data,
497                                 (off_t)in_offset,
498                                 (size_t)in_length);
499
500         if (NT_STATUS_IS_OK(status)) {
501                 /*
502                  * Doing an async read, allow this
503                  * request to be canceled
504                  */
505                 tevent_req_set_cancel_fn(req, smbd_smb2_read_cancel);
506                 return req;
507         }
508
509         if (!NT_STATUS_EQUAL(status, NT_STATUS_RETRY)) {
510                 /* Real error in setting up aio. Fail. */
511                 tevent_req_nterror(req, status);
512                 return tevent_req_post(req, ev);
513         }
514
515         /* Fallback to synchronous. */
516
517         init_strict_lock_struct(fsp,
518                                 fsp->op->global->open_persistent_id,
519                                 in_offset,
520                                 in_length,
521                                 READ_LOCK,
522                                 &lock);
523
524         if (!SMB_VFS_STRICT_LOCK(conn, fsp, &lock)) {
525                 tevent_req_nterror(req, NT_STATUS_FILE_LOCK_CONFLICT);
526                 return tevent_req_post(req, ev);
527         }
528
529         /* Try sendfile in preference. */
530         status = schedule_smb2_sendfile_read(smb2req, state);
531         if (NT_STATUS_IS_OK(status)) {
532                 tevent_req_done(req);
533                 return tevent_req_post(req, ev);
534         } else {
535                 if (!NT_STATUS_EQUAL(status, NT_STATUS_RETRY)) {
536                         SMB_VFS_STRICT_UNLOCK(conn, fsp, &lock);
537                         tevent_req_nterror(req, status);
538                         return tevent_req_post(req, ev);
539                 }
540         }
541
542         /* Ok, read into memory. Allocate the out buffer. */
543         state->out_data = data_blob_talloc(state, NULL, in_length);
544         if (in_length > 0 && tevent_req_nomem(state->out_data.data, req)) {
545                 SMB_VFS_STRICT_UNLOCK(conn, fsp, &lock);
546                 return tevent_req_post(req, ev);
547         }
548
549         nread = read_file(fsp,
550                           (char *)state->out_data.data,
551                           in_offset,
552                           in_length);
553
554         saved_errno = errno;
555
556         SMB_VFS_STRICT_UNLOCK(conn, fsp, &lock);
557
558         DEBUG(10,("smbd_smb2_read: file %s, %s, offset=%llu "
559                 "len=%llu returned %lld\n",
560                 fsp_str_dbg(fsp),
561                 fsp_fnum_dbg(fsp),
562                 (unsigned long long)in_offset,
563                 (unsigned long long)in_length,
564                 (long long)nread));
565
566         status = smb2_read_complete(req, nread, saved_errno);
567         if (!NT_STATUS_IS_OK(status)) {
568                 tevent_req_nterror(req, status);
569         } else {
570                 /* Success. */
571                 tevent_req_done(req);
572         }
573         return tevent_req_post(req, ev);
574 }
575
576 static void smbd_smb2_read_pipe_done(struct tevent_req *subreq)
577 {
578         struct tevent_req *req = tevent_req_callback_data(subreq,
579                                  struct tevent_req);
580         struct smbd_smb2_read_state *state = tevent_req_data(req,
581                                              struct smbd_smb2_read_state);
582         NTSTATUS status;
583         ssize_t nread = -1;
584         bool is_data_outstanding;
585
586         status = np_read_recv(subreq, &nread, &is_data_outstanding);
587         TALLOC_FREE(subreq);
588         if (!NT_STATUS_IS_OK(status)) {
589                 NTSTATUS old = status;
590                 status = nt_status_np_pipe(old);
591                 tevent_req_nterror(req, status);
592                 return;
593         }
594
595         if (nread == 0 && state->out_data.length != 0) {
596                 tevent_req_nterror(req, NT_STATUS_END_OF_FILE);
597                 return;
598         }
599
600         state->out_data.length = nread;
601         state->out_remaining = 0;
602
603         /*
604          * TODO: add STATUS_BUFFER_OVERFLOW handling, once we also
605          * handle it in SMB1 pipe_read_andx_done().
606          */
607
608         tevent_req_done(req);
609 }
610
611 static NTSTATUS smbd_smb2_read_recv(struct tevent_req *req,
612                                     TALLOC_CTX *mem_ctx,
613                                     DATA_BLOB *out_data,
614                                     uint32_t *out_remaining)
615 {
616         NTSTATUS status;
617         struct smbd_smb2_read_state *state = tevent_req_data(req,
618                                              struct smbd_smb2_read_state);
619
620         if (tevent_req_is_nterror(req, &status)) {
621                 tevent_req_received(req);
622                 return status;
623         }
624
625         *out_data = state->out_data;
626         talloc_steal(mem_ctx, out_data->data);
627         *out_remaining = state->out_remaining;
628
629         if (state->out_headers.length > 0) {
630                 talloc_steal(mem_ctx, state);
631                 talloc_set_destructor(state, smb2_smb2_read_state_deny_destructor);
632                 tevent_req_received(req);
633                 state->smb2req->queue_entry.sendfile_header = &state->out_headers;
634                 talloc_set_destructor(state, smb2_sendfile_send_data);
635         } else {
636                 tevent_req_received(req);
637         }
638
639         return NT_STATUS_OK;
640 }