Revert "smbd: implement smbd_impersonate_{conn_vuid,conn_sess,root,guest}_create...
[samba.git] / source3 / smbd / smb2_create.c
1 /*
2    Unix SMB/CIFS implementation.
3    Core SMB2 server
4
5    Copyright (C) Stefan Metzmacher 2009
6    Copyright (C) Jeremy Allison 2010
7
8    This program is free software; you can redistribute it and/or modify
9    it under the terms of the GNU General Public License as published by
10    the Free Software Foundation; either version 3 of the License, or
11    (at your option) any later version.
12
13    This program is distributed in the hope that it will be useful,
14    but WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16    GNU General Public License for more details.
17
18    You should have received a copy of the GNU General Public License
19    along with this program.  If not, see <http://www.gnu.org/licenses/>.
20 */
21
22 #include "includes.h"
23 #include "printing.h"
24 #include "smbd/smbd.h"
25 #include "smbd/globals.h"
26 #include "../libcli/smb/smb_common.h"
27 #include "../librpc/gen_ndr/ndr_security.h"
28 #include "../librpc/gen_ndr/ndr_smb2_lease_struct.h"
29 #include "../lib/util/tevent_ntstatus.h"
30 #include "messages.h"
31
32 #undef DBGC_CLASS
33 #define DBGC_CLASS DBGC_SMB2
34
35 int map_smb2_oplock_levels_to_samba(uint8_t in_oplock_level)
36 {
37         switch(in_oplock_level) {
38         case SMB2_OPLOCK_LEVEL_NONE:
39                 return NO_OPLOCK;
40         case SMB2_OPLOCK_LEVEL_II:
41                 return LEVEL_II_OPLOCK;
42         case SMB2_OPLOCK_LEVEL_EXCLUSIVE:
43                 return EXCLUSIVE_OPLOCK;
44         case SMB2_OPLOCK_LEVEL_BATCH:
45                 return BATCH_OPLOCK;
46         case SMB2_OPLOCK_LEVEL_LEASE:
47                 return LEASE_OPLOCK;
48         default:
49                 DEBUG(2,("map_smb2_oplock_levels_to_samba: "
50                         "unknown level %u\n",
51                         (unsigned int)in_oplock_level));
52                 return NO_OPLOCK;
53         }
54 }
55
56 static uint8_t map_samba_oplock_levels_to_smb2(int oplock_type)
57 {
58         if (BATCH_OPLOCK_TYPE(oplock_type)) {
59                 return SMB2_OPLOCK_LEVEL_BATCH;
60         } else if (EXCLUSIVE_OPLOCK_TYPE(oplock_type)) {
61                 return SMB2_OPLOCK_LEVEL_EXCLUSIVE;
62         } else if (oplock_type == LEVEL_II_OPLOCK) {
63                 return SMB2_OPLOCK_LEVEL_II;
64         } else if (oplock_type == LEASE_OPLOCK) {
65                 return SMB2_OPLOCK_LEVEL_LEASE;
66         } else {
67                 return SMB2_OPLOCK_LEVEL_NONE;
68         }
69 }
70
71 static struct tevent_req *smbd_smb2_create_send(TALLOC_CTX *mem_ctx,
72                         struct tevent_context *ev,
73                         struct smbd_smb2_request *smb2req,
74                         uint8_t in_oplock_level,
75                         uint32_t in_impersonation_level,
76                         uint32_t in_desired_access,
77                         uint32_t in_file_attributes,
78                         uint32_t in_share_access,
79                         uint32_t in_create_disposition,
80                         uint32_t in_create_options,
81                         const char *in_name,
82                         struct smb2_create_blobs in_context_blobs);
83 static NTSTATUS smbd_smb2_create_recv(struct tevent_req *req,
84                         TALLOC_CTX *mem_ctx,
85                         uint8_t *out_oplock_level,
86                         uint32_t *out_create_action,
87                         struct timespec *out_creation_ts,
88                         struct timespec *out_last_access_ts,
89                         struct timespec *out_last_write_ts,
90                         struct timespec *out_change_ts,
91                         uint64_t *out_allocation_size,
92                         uint64_t *out_end_of_file,
93                         uint32_t *out_file_attributes,
94                         uint64_t *out_file_id_persistent,
95                         uint64_t *out_file_id_volatile,
96                         struct smb2_create_blobs *out_context_blobs);
97
98 static void smbd_smb2_request_create_done(struct tevent_req *tsubreq);
99 NTSTATUS smbd_smb2_request_process_create(struct smbd_smb2_request *smb2req)
100 {
101         const uint8_t *inbody;
102         const struct iovec *indyniov;
103         uint8_t in_oplock_level;
104         uint32_t in_impersonation_level;
105         uint32_t in_desired_access;
106         uint32_t in_file_attributes;
107         uint32_t in_share_access;
108         uint32_t in_create_disposition;
109         uint32_t in_create_options;
110         uint16_t in_name_offset;
111         uint16_t in_name_length;
112         DATA_BLOB in_name_buffer;
113         char *in_name_string;
114         size_t in_name_string_size;
115         uint32_t name_offset = 0;
116         uint32_t name_available_length = 0;
117         uint32_t in_context_offset;
118         uint32_t in_context_length;
119         DATA_BLOB in_context_buffer;
120         struct smb2_create_blobs in_context_blobs;
121         uint32_t context_offset = 0;
122         uint32_t context_available_length = 0;
123         uint32_t dyn_offset;
124         NTSTATUS status;
125         bool ok;
126         struct tevent_req *tsubreq;
127
128         status = smbd_smb2_request_verify_sizes(smb2req, 0x39);
129         if (!NT_STATUS_IS_OK(status)) {
130                 return smbd_smb2_request_error(smb2req, status);
131         }
132         inbody = SMBD_SMB2_IN_BODY_PTR(smb2req);
133
134         in_oplock_level         = CVAL(inbody, 0x03);
135         in_impersonation_level  = IVAL(inbody, 0x04);
136         in_desired_access       = IVAL(inbody, 0x18);
137         in_file_attributes      = IVAL(inbody, 0x1C);
138         in_share_access         = IVAL(inbody, 0x20);
139         in_create_disposition   = IVAL(inbody, 0x24);
140         in_create_options       = IVAL(inbody, 0x28);
141         in_name_offset          = SVAL(inbody, 0x2C);
142         in_name_length          = SVAL(inbody, 0x2E);
143         in_context_offset       = IVAL(inbody, 0x30);
144         in_context_length       = IVAL(inbody, 0x34);
145
146         /*
147          * First check if the dynamic name and context buffers
148          * are correctly specified.
149          *
150          * Note: That we don't check if the name and context buffers
151          *       overlap
152          */
153
154         dyn_offset = SMB2_HDR_BODY + SMBD_SMB2_IN_BODY_LEN(smb2req);
155
156         if (in_name_offset == 0 && in_name_length == 0) {
157                 /* This is ok */
158                 name_offset = 0;
159         } else if (in_name_offset < dyn_offset) {
160                 return smbd_smb2_request_error(smb2req, NT_STATUS_INVALID_PARAMETER);
161         } else {
162                 name_offset = in_name_offset - dyn_offset;
163         }
164
165         indyniov = SMBD_SMB2_IN_DYN_IOV(smb2req);
166
167         if (name_offset > indyniov->iov_len) {
168                 return smbd_smb2_request_error(smb2req, NT_STATUS_INVALID_PARAMETER);
169         }
170
171         name_available_length = indyniov->iov_len - name_offset;
172
173         if (in_name_length > name_available_length) {
174                 return smbd_smb2_request_error(smb2req, NT_STATUS_INVALID_PARAMETER);
175         }
176
177         in_name_buffer.data = (uint8_t *)indyniov->iov_base + name_offset;
178         in_name_buffer.length = in_name_length;
179
180         if (in_context_offset == 0 && in_context_length == 0) {
181                 /* This is ok */
182                 context_offset = 0;
183         } else if (in_context_offset < dyn_offset) {
184                 return smbd_smb2_request_error(smb2req, NT_STATUS_INVALID_PARAMETER);
185         } else {
186                 context_offset = in_context_offset - dyn_offset;
187         }
188
189         if (context_offset > indyniov->iov_len) {
190                 return smbd_smb2_request_error(smb2req, NT_STATUS_INVALID_PARAMETER);
191         }
192
193         context_available_length = indyniov->iov_len - context_offset;
194
195         if (in_context_length > context_available_length) {
196                 return smbd_smb2_request_error(smb2req, NT_STATUS_INVALID_PARAMETER);
197         }
198
199         in_context_buffer.data = (uint8_t *)indyniov->iov_base +
200                 context_offset;
201         in_context_buffer.length = in_context_length;
202
203         /*
204          * Now interpret the name and context buffers
205          */
206
207         ok = convert_string_talloc(smb2req, CH_UTF16, CH_UNIX,
208                                    in_name_buffer.data,
209                                    in_name_buffer.length,
210                                    &in_name_string,
211                                    &in_name_string_size);
212         if (!ok) {
213                 return smbd_smb2_request_error(smb2req, NT_STATUS_ILLEGAL_CHARACTER);
214         }
215
216         if (in_name_buffer.length == 0) {
217                 in_name_string_size = 0;
218         }
219
220         if (strlen(in_name_string) != in_name_string_size) {
221                 return smbd_smb2_request_error(smb2req, NT_STATUS_OBJECT_NAME_INVALID);
222         }
223
224         ZERO_STRUCT(in_context_blobs);
225         status = smb2_create_blob_parse(smb2req, in_context_buffer, &in_context_blobs);
226         if (!NT_STATUS_IS_OK(status)) {
227                 return smbd_smb2_request_error(smb2req, status);
228         }
229
230         tsubreq = smbd_smb2_create_send(smb2req,
231                                        smb2req->ev_ctx,
232                                        smb2req,
233                                        in_oplock_level,
234                                        in_impersonation_level,
235                                        in_desired_access,
236                                        in_file_attributes,
237                                        in_share_access,
238                                        in_create_disposition,
239                                        in_create_options,
240                                        in_name_string,
241                                        in_context_blobs);
242         if (tsubreq == NULL) {
243                 smb2req->subreq = NULL;
244                 return smbd_smb2_request_error(smb2req, NT_STATUS_NO_MEMORY);
245         }
246         tevent_req_set_callback(tsubreq, smbd_smb2_request_create_done, smb2req);
247
248         return smbd_smb2_request_pending_queue(smb2req, tsubreq, 500);
249 }
250
251 static uint64_t get_mid_from_smb2req(struct smbd_smb2_request *smb2req)
252 {
253         uint8_t *reqhdr = SMBD_SMB2_OUT_HDR_PTR(smb2req);
254         return BVAL(reqhdr, SMB2_HDR_MESSAGE_ID);
255 }
256
257 static void smbd_smb2_request_create_done(struct tevent_req *tsubreq)
258 {
259         struct smbd_smb2_request *smb2req = tevent_req_callback_data(tsubreq,
260                                         struct smbd_smb2_request);
261         DATA_BLOB outbody;
262         DATA_BLOB outdyn;
263         uint8_t out_oplock_level = 0;
264         uint32_t out_create_action = 0;
265         connection_struct *conn = smb2req->tcon->compat;
266         struct timespec out_creation_ts = { 0, };
267         struct timespec out_last_access_ts = { 0, };
268         struct timespec out_last_write_ts = { 0, };
269         struct timespec out_change_ts = { 0, };
270         uint64_t out_allocation_size = 0;
271         uint64_t out_end_of_file = 0;
272         uint32_t out_file_attributes = 0;
273         uint64_t out_file_id_persistent = 0;
274         uint64_t out_file_id_volatile = 0;
275         struct smb2_create_blobs out_context_blobs;
276         DATA_BLOB out_context_buffer;
277         uint16_t out_context_buffer_offset = 0;
278         NTSTATUS status;
279         NTSTATUS error; /* transport error */
280
281         status = smbd_smb2_create_recv(tsubreq,
282                                        smb2req,
283                                        &out_oplock_level,
284                                        &out_create_action,
285                                        &out_creation_ts,
286                                        &out_last_access_ts,
287                                        &out_last_write_ts,
288                                        &out_change_ts,
289                                        &out_allocation_size,
290                                        &out_end_of_file,
291                                        &out_file_attributes,
292                                        &out_file_id_persistent,
293                                        &out_file_id_volatile,
294                                        &out_context_blobs);
295         if (!NT_STATUS_IS_OK(status)) {
296                 error = smbd_smb2_request_error(smb2req, status);
297                 if (!NT_STATUS_IS_OK(error)) {
298                         smbd_server_connection_terminate(smb2req->xconn,
299                                                          nt_errstr(error));
300                         return;
301                 }
302                 return;
303         }
304
305         status = smb2_create_blob_push(smb2req, &out_context_buffer, out_context_blobs);
306         if (!NT_STATUS_IS_OK(status)) {
307                 error = smbd_smb2_request_error(smb2req, status);
308                 if (!NT_STATUS_IS_OK(error)) {
309                         smbd_server_connection_terminate(smb2req->xconn,
310                                                          nt_errstr(error));
311                         return;
312                 }
313                 return;
314         }
315
316         if (out_context_buffer.length > 0) {
317                 out_context_buffer_offset = SMB2_HDR_BODY + 0x58;
318         }
319
320         outbody = smbd_smb2_generate_outbody(smb2req, 0x58);
321         if (outbody.data == NULL) {
322                 error = smbd_smb2_request_error(smb2req, NT_STATUS_NO_MEMORY);
323                 if (!NT_STATUS_IS_OK(error)) {
324                         smbd_server_connection_terminate(smb2req->xconn,
325                                                          nt_errstr(error));
326                         return;
327                 }
328                 return;
329         }
330
331         SSVAL(outbody.data, 0x00, 0x58 + 1);    /* struct size */
332         SCVAL(outbody.data, 0x02,
333               out_oplock_level);                /* oplock level */
334         SCVAL(outbody.data, 0x03, 0);           /* reserved */
335         SIVAL(outbody.data, 0x04,
336               out_create_action);               /* create action */
337         put_long_date_timespec(conn->ts_res,
338               (char *)outbody.data + 0x08,
339               out_creation_ts);                 /* creation time */
340         put_long_date_timespec(conn->ts_res,
341               (char *)outbody.data + 0x10,
342               out_last_access_ts);              /* last access time */
343         put_long_date_timespec(conn->ts_res,
344               (char *)outbody.data + 0x18,
345               out_last_write_ts);               /* last write time */
346         put_long_date_timespec(conn->ts_res,
347               (char *)outbody.data + 0x20,
348               out_change_ts);                   /* change time */
349         SBVAL(outbody.data, 0x28,
350               out_allocation_size);             /* allocation size */
351         SBVAL(outbody.data, 0x30,
352               out_end_of_file);                 /* end of file */
353         SIVAL(outbody.data, 0x38,
354               out_file_attributes);             /* file attributes */
355         SIVAL(outbody.data, 0x3C, 0);           /* reserved */
356         SBVAL(outbody.data, 0x40,
357               out_file_id_persistent);          /* file id (persistent) */
358         SBVAL(outbody.data, 0x48,
359               out_file_id_volatile);            /* file id (volatile) */
360         SIVAL(outbody.data, 0x50,
361               out_context_buffer_offset);       /* create contexts offset */
362         SIVAL(outbody.data, 0x54,
363               out_context_buffer.length);       /* create contexts length */
364
365         outdyn = out_context_buffer;
366
367         error = smbd_smb2_request_done(smb2req, outbody, &outdyn);
368         if (!NT_STATUS_IS_OK(error)) {
369                 smbd_server_connection_terminate(smb2req->xconn,
370                                                  nt_errstr(error));
371                 return;
372         }
373 }
374
375 static bool smb2_lease_key_valid(const struct smb2_lease_key *key)
376 {
377         return ((key->data[0] != 0) || (key->data[1] != 0));
378 }
379
380 static NTSTATUS smbd_smb2_create_durable_lease_check(struct smb_request *smb1req,
381         const char *requested_filename, const struct files_struct *fsp,
382         const struct smb2_lease *lease_ptr)
383 {
384         char *filename = NULL;
385         struct smb_filename *smb_fname = NULL;
386         uint32_t ucf_flags;
387         NTSTATUS status;
388
389         if (lease_ptr == NULL) {
390                 if (fsp->oplock_type != LEASE_OPLOCK) {
391                         return NT_STATUS_OK;
392                 }
393                 DEBUG(10, ("Reopened file has lease, but no lease "
394                            "requested\n"));
395                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
396         }
397
398         if (fsp->oplock_type != LEASE_OPLOCK) {
399                 DEBUG(10, ("Lease requested, but reopened file has no "
400                            "lease\n"));
401                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
402         }
403
404         if (!smb2_lease_key_equal(&lease_ptr->lease_key,
405                                   &fsp->lease->lease.lease_key)) {
406                 DEBUG(10, ("Different lease key requested than found "
407                            "in reopened file\n"));
408                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
409         }
410
411         filename = talloc_strdup(talloc_tos(), requested_filename);
412         if (filename == NULL) {
413                 return NT_STATUS_NO_MEMORY;
414         }
415
416         /* This also converts '\' to '/' */
417         status = check_path_syntax(filename);
418         if (!NT_STATUS_IS_OK(status)) {
419                 TALLOC_FREE(filename);
420                 return status;
421         }
422
423         ucf_flags = filename_create_ucf_flags(smb1req, FILE_OPEN);
424         status = filename_convert(talloc_tos(), fsp->conn,
425                                   filename, ucf_flags,
426                                   NULL, NULL, &smb_fname);
427         TALLOC_FREE(filename);
428         if (!NT_STATUS_IS_OK(status)) {
429                 DEBUG(10, ("filename_convert returned %s\n",
430                            nt_errstr(status)));
431                 return status;
432         }
433
434         if (!strequal(fsp->fsp_name->base_name, smb_fname->base_name)) {
435                 DEBUG(10, ("Lease requested for file %s, reopened file "
436                            "is named %s\n", smb_fname->base_name,
437                            fsp->fsp_name->base_name));
438                 TALLOC_FREE(smb_fname);
439                 return NT_STATUS_INVALID_PARAMETER;
440         }
441
442         TALLOC_FREE(smb_fname);
443
444         return NT_STATUS_OK;
445 }
446
447 struct smbd_smb2_create_state {
448         struct tevent_context *ev;
449         struct smbd_smb2_request *smb2req;
450         struct smb_request *smb1req;
451         bool open_was_deferred;
452         struct tevent_immediate *im;
453         struct timeval request_time;
454         struct file_id id;
455         struct deferred_open_record *open_rec;
456         files_struct *result;
457         bool replay_operation;
458         uint8_t in_oplock_level;
459         uint32_t in_create_disposition;
460         int requested_oplock_level;
461         int info;
462         char *fname;
463         struct ea_list *ea_list;
464         NTTIME max_access_time;
465         struct security_descriptor *sec_desc;
466         uint64_t allocation_size;
467         struct GUID _create_guid;
468         struct GUID *create_guid;
469         bool update_open;
470         bool durable_requested;
471         uint32_t durable_timeout_msec;
472         bool do_durable_reconnect;
473         uint64_t persistent_id;
474         struct smb2_lease lease;
475         struct smb2_lease *lease_ptr;
476         ssize_t lease_len;
477         bool need_replay_cache;
478         struct smbXsrv_open *op;
479         time_t twrp_time;
480         time_t *twrp_timep;
481
482         struct smb2_create_blob *dhnc;
483         struct smb2_create_blob *dh2c;
484         struct smb2_create_blob *dhnq;
485         struct smb2_create_blob *dh2q;
486         struct smb2_create_blob *rqls;
487         struct smb2_create_blob *exta;
488         struct smb2_create_blob *mxac;
489         struct smb2_create_blob *secd;
490         struct smb2_create_blob *alsi;
491         struct smb2_create_blob *twrp;
492         struct smb2_create_blob *qfid;
493         struct smb2_create_blob *svhdx;
494
495         uint8_t out_oplock_level;
496         uint32_t out_create_action;
497         struct timespec out_creation_ts;
498         struct timespec out_last_access_ts;
499         struct timespec out_last_write_ts;
500         struct timespec out_change_ts;
501         uint64_t out_allocation_size;
502         uint64_t out_end_of_file;
503         uint32_t out_file_attributes;
504         uint64_t out_file_id_persistent;
505         uint64_t out_file_id_volatile;
506         struct smb2_create_blobs *out_context_blobs;
507 };
508
509 static NTSTATUS smbd_smb2_create_fetch_create_ctx(
510         struct tevent_req *req,
511         struct smb2_create_blobs *in_context_blobs)
512 {
513         struct smbd_smb2_create_state *state = tevent_req_data(
514                 req, struct smbd_smb2_create_state);
515
516         state->dhnq = smb2_create_blob_find(in_context_blobs,
517                                             SMB2_CREATE_TAG_DHNQ);
518         state->dhnc = smb2_create_blob_find(in_context_blobs,
519                                             SMB2_CREATE_TAG_DHNC);
520         state->dh2q = smb2_create_blob_find(in_context_blobs,
521                                             SMB2_CREATE_TAG_DH2Q);
522         state->dh2c = smb2_create_blob_find(in_context_blobs,
523                                             SMB2_CREATE_TAG_DH2C);
524         if (state->smb2req->xconn->smb2.server.capabilities & SMB2_CAP_LEASING) {
525                 state->rqls = smb2_create_blob_find(in_context_blobs,
526                                                     SMB2_CREATE_TAG_RQLS);
527         }
528
529         if (((state->dhnc != NULL) && (state->dh2c != NULL)) ||
530             ((state->dhnc != NULL) && (state->dh2q != NULL)) ||
531             ((state->dh2c != NULL) && (state->dhnq != NULL)) ||
532             ((state->dh2q != NULL) && (state->dh2c != NULL)))
533         {
534                 /* not both are allowed at the same time */
535                 return NT_STATUS_INVALID_PARAMETER;
536         }
537
538         if (state->dhnc != NULL) {
539                 uint32_t num_blobs_allowed;
540
541                 if (state->dhnc->data.length != 16) {
542                         return NT_STATUS_INVALID_PARAMETER;
543                 }
544
545                 /*
546                  * According to MS-SMB2: 3.3.5.9.7, "Handling the
547                  * SMB2_CREATE_DURABLE_HANDLE_RECONNECT Create Context",
548                  * we should ignore an additional dhnq blob, but fail
549                  * the request (with status OBJECT_NAME_NOT_FOUND) if
550                  * any other extra create blob has been provided.
551                  *
552                  * (Note that the cases of an additional dh2q or dh2c blob
553                  *  which require a different error code, have been treated
554                  *  above.)
555                  */
556
557                 if (state->dhnq != NULL) {
558                         num_blobs_allowed = 2;
559                 } else {
560                         num_blobs_allowed = 1;
561                 }
562
563                 if (state->rqls != NULL) {
564                         num_blobs_allowed += 1;
565                 }
566
567                 if (in_context_blobs->num_blobs != num_blobs_allowed) {
568                         return NT_STATUS_OBJECT_NAME_NOT_FOUND;
569                 }
570         }
571
572         if (state->dh2c!= NULL) {
573                 uint32_t num_blobs_allowed;
574
575                 if (state->dh2c->data.length != 36) {
576                         return NT_STATUS_INVALID_PARAMETER;
577                 }
578
579                 /*
580                  * According to MS-SMB2: 3.3.5.9.12, "Handling the
581                  * SMB2_CREATE_DURABLE_HANDLE_RECONNECT_V2 Create Context",
582                  * we should fail the request with status
583                  * OBJECT_NAME_NOT_FOUND if any other create blob has been
584                  * provided.
585                  *
586                  * (Note that the cases of an additional dhnq, dhnc or dh2q
587                  *  blob which require a different error code, have been
588                  *  treated above.)
589                  */
590
591                 num_blobs_allowed = 1;
592
593                 if (state->rqls != NULL) {
594                         num_blobs_allowed += 1;
595                 }
596
597                 if (in_context_blobs->num_blobs != num_blobs_allowed) {
598                         return NT_STATUS_OBJECT_NAME_NOT_FOUND;
599                 }
600         }
601
602         state->exta = smb2_create_blob_find(in_context_blobs,
603                                             SMB2_CREATE_TAG_EXTA);
604         state->mxac = smb2_create_blob_find(in_context_blobs,
605                                             SMB2_CREATE_TAG_MXAC);
606         state->secd = smb2_create_blob_find(in_context_blobs,
607                                             SMB2_CREATE_TAG_SECD);
608         state->alsi = smb2_create_blob_find(in_context_blobs,
609                                             SMB2_CREATE_TAG_ALSI);
610         state->twrp = smb2_create_blob_find(in_context_blobs,
611                                             SMB2_CREATE_TAG_TWRP);
612         state->qfid = smb2_create_blob_find(in_context_blobs,
613                                             SMB2_CREATE_TAG_QFID);
614         if (state->smb2req->xconn->protocol >= PROTOCOL_SMB3_02) {
615                 /*
616                  * This was introduced with SMB3_02
617                  */
618                 state->svhdx = smb2_create_blob_find(
619                         in_context_blobs, SVHDX_OPEN_DEVICE_CONTEXT);
620         }
621
622         return NT_STATUS_OK;
623 }
624
625 static void smbd_smb2_create_before_exec(struct tevent_req *req);
626 static void smbd_smb2_create_after_exec(struct tevent_req *req);
627 static void smbd_smb2_create_finish(struct tevent_req *req);
628
629 static struct tevent_req *smbd_smb2_create_send(TALLOC_CTX *mem_ctx,
630                         struct tevent_context *ev,
631                         struct smbd_smb2_request *smb2req,
632                         uint8_t in_oplock_level,
633                         uint32_t in_impersonation_level,
634                         uint32_t in_desired_access,
635                         uint32_t in_file_attributes,
636                         uint32_t in_share_access,
637                         uint32_t in_create_disposition,
638                         uint32_t in_create_options,
639                         const char *in_name,
640                         struct smb2_create_blobs in_context_blobs)
641 {
642         struct tevent_req *req = NULL;
643         struct smbd_smb2_create_state *state = NULL;
644         NTSTATUS status;
645         struct smb_request *smb1req = NULL;
646         struct smb_filename *smb_fname = NULL;
647         uint32_t ucf_flags;
648
649         req = tevent_req_create(mem_ctx, &state,
650                                 struct smbd_smb2_create_state);
651         if (req == NULL) {
652                 return NULL;
653         }
654         *state = (struct smbd_smb2_create_state) {
655                 .ev = ev,
656                 .smb2req = smb2req,
657                 .in_oplock_level = in_oplock_level,
658                 .in_create_disposition = in_create_disposition,
659         };
660
661         smb1req = smbd_smb2_fake_smb_request(smb2req);
662         if (tevent_req_nomem(smb1req, req)) {
663                 return tevent_req_post(req, state->ev);
664         }
665         state->smb1req = smb1req;
666
667         if (smb2req->subreq == NULL) {
668                 DBG_DEBUG("name [%s]\n", in_name);
669         } else {
670                 struct smbd_smb2_create_state *old_state = tevent_req_data(
671                         smb2req->subreq, struct smbd_smb2_create_state);
672
673                 DBG_DEBUG("reentrant for file %s\n", in_name);
674
675                 state->id = old_state->id;
676                 state->request_time = old_state->request_time;
677                 state->open_rec = talloc_move(state, &old_state->open_rec);
678                 state->open_was_deferred = old_state->open_was_deferred;
679         }
680
681         TALLOC_FREE(smb2req->subreq);
682         smb2req->subreq = req;
683
684         if (lp_fake_oplocks(SNUM(smb2req->tcon->compat))) {
685                 state->requested_oplock_level = SMB2_OPLOCK_LEVEL_NONE;
686         } else {
687                 state->requested_oplock_level = state->in_oplock_level;
688         }
689
690         /* these are ignored for SMB2 */
691         in_create_options &= ~(0x10);/* NTCREATEX_OPTIONS_SYNC_ALERT */
692         in_create_options &= ~(0x20);/* NTCREATEX_OPTIONS_ASYNC_ALERT */
693
694         in_file_attributes &= ~FILE_FLAG_POSIX_SEMANTICS;
695
696         state->fname = talloc_strdup(state, in_name);
697         if (tevent_req_nomem(state->fname, req)) {
698                 return tevent_req_post(req, state->ev);
699         }
700
701         state->out_context_blobs = talloc_zero(state, struct smb2_create_blobs);
702         if (tevent_req_nomem(state->out_context_blobs, req)) {
703                 return tevent_req_post(req, state->ev);
704         }
705
706         status = smbd_smb2_create_fetch_create_ctx(req, &in_context_blobs);
707         if (tevent_req_nterror(req, status)) {
708                 return tevent_req_post(req, state->ev);
709         }
710
711         if (IS_IPC(smb1req->conn)) {
712                 const char *pipe_name = in_name;
713
714                 if (state->dhnc != NULL || state->dh2c != NULL) {
715                         /* durable handles are not supported on IPC$ */
716                         tevent_req_nterror(req, NT_STATUS_OBJECT_NAME_NOT_FOUND);
717                         return tevent_req_post(req, state->ev);
718                 }
719
720                 if (!lp_nt_pipe_support()) {
721                         tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
722                         return tevent_req_post(req, state->ev);
723                 }
724
725                 status = open_np_file(smb1req, pipe_name, &state->result);
726                 if (!NT_STATUS_IS_OK(status)) {
727                         tevent_req_nterror(req, status);
728                         return tevent_req_post(req, state->ev);
729                 }
730                 state->info = FILE_WAS_OPENED;
731
732                 smbd_smb2_create_finish(req);
733                 return req;
734
735         } else if (CAN_PRINT(smb1req->conn)) {
736                 if (state->dhnc != NULL || state->dh2c != NULL) {
737                         /* durable handles are not supported on printers */
738                         tevent_req_nterror(req, NT_STATUS_OBJECT_NAME_NOT_FOUND);
739                         return tevent_req_post(req, state->ev);
740                 }
741
742                 status = file_new(smb1req, smb1req->conn, &state->result);
743                 if(!NT_STATUS_IS_OK(status)) {
744                         tevent_req_nterror(req, status);
745                         return tevent_req_post(req, state->ev);
746                 }
747
748                 status = print_spool_open(state->result, in_name,
749                                           smb1req->vuid);
750                 if (!NT_STATUS_IS_OK(status)) {
751                         file_free(smb1req, state->result);
752                         tevent_req_nterror(req, status);
753                         return tevent_req_post(req, state->ev);
754                 }
755                 state->info = FILE_WAS_CREATED;
756
757                 smbd_smb2_create_finish(req);
758                 return req;
759         }
760
761         smbd_smb2_create_before_exec(req);
762         if (!tevent_req_is_in_progress(req)) {
763                 return tevent_req_post(req, state->ev);
764         }
765
766         DBG_DEBUG("open execution phase\n");
767
768         /*
769          * For the backend file open procedure, there are
770          * three possible modes: replay operation (in which case
771          * there is nothing else to do), durable_reconnect or
772          * new open.
773          */
774         if (state->replay_operation) {
775                 state->result = state->op->compat;
776                 state->result->op = state->op;
777                 state->update_open = false;
778                 state->info = state->op->create_action;
779
780                 smbd_smb2_create_after_exec(req);
781                 if (!tevent_req_is_in_progress(req)) {
782                         return req;
783                 }
784
785                 smbd_smb2_create_finish(req);
786                 return req;
787
788         } else if (state->do_durable_reconnect) {
789                 DATA_BLOB new_cookie = data_blob_null;
790                 NTTIME now = timeval_to_nttime(&smb2req->request_time);
791
792                 status = smb2srv_open_recreate(smb2req->xconn,
793                                                smb1req->conn->session_info,
794                                                state->persistent_id,
795                                                state->create_guid,
796                                                now,
797                                                &state->op);
798                 if (!NT_STATUS_IS_OK(status)) {
799                         DBG_NOTICE("smb2srv_open_recreate failed: %s\n",
800                                    nt_errstr(status));
801                         tevent_req_nterror(req, status);
802                         return tevent_req_post(req, state->ev);
803                 }
804
805                 DBG_DEBUG("%s to recreate durable handle\n",
806                           state->op->global->durable ? "succeeded" : "failed");
807
808                 if (!state->op->global->durable) {
809                         talloc_free(state->op);
810                         tevent_req_nterror(req,
811                                            NT_STATUS_OBJECT_NAME_NOT_FOUND);
812                         return tevent_req_post(req, state->ev);
813                 }
814
815                 status = SMB_VFS_DURABLE_RECONNECT(smb1req->conn,
816                                                    smb1req,
817                                                    state->op, /* smbXsrv_open input */
818                                                    state->op->global->backend_cookie,
819                                                    state->op, /* TALLOC_CTX */
820                                                    &state->result,
821                                                    &new_cookie);
822                 if (!NT_STATUS_IS_OK(status)) {
823                         NTSTATUS return_status;
824
825                         return_status = NT_STATUS_OBJECT_NAME_NOT_FOUND;
826
827                         DBG_NOTICE("durable_reconnect failed: %s => %s\n",
828                                    nt_errstr(status),
829                                    nt_errstr(return_status));
830
831                         tevent_req_nterror(req, return_status);
832                         return tevent_req_post(req, state->ev);
833                 }
834
835                 DBG_DEBUG("oplock_type=%u, lease_ptr==%p\n",
836                           (unsigned)state->result->oplock_type, state->lease_ptr);
837
838                 status = smbd_smb2_create_durable_lease_check(
839                         smb1req, state->fname, state->result, state->lease_ptr);
840                 if (!NT_STATUS_IS_OK(status)) {
841                         close_file(smb1req, state->result, SHUTDOWN_CLOSE);
842                         tevent_req_nterror(req, status);
843                         return tevent_req_post(req, state->ev);
844                 }
845
846                 data_blob_free(&state->op->global->backend_cookie);
847                 state->op->global->backend_cookie = new_cookie;
848
849                 state->op->status = NT_STATUS_OK;
850                 state->op->global->disconnect_time = 0;
851
852                 /* save the timout for later update */
853                 state->durable_timeout_msec = state->op->global->durable_timeout_msec;
854
855                 state->update_open = true;
856
857                 state->info = FILE_WAS_OPENED;
858
859                 smbd_smb2_create_after_exec(req);
860                 if (!tevent_req_is_in_progress(req)) {
861                         return req;
862                 }
863
864                 smbd_smb2_create_finish(req);
865                 return req;
866         }
867
868         if (state->requested_oplock_level == SMB2_OPLOCK_LEVEL_LEASE) {
869                 if (state->lease_ptr == NULL) {
870                         state->requested_oplock_level = SMB2_OPLOCK_LEVEL_NONE;
871                 }
872         } else {
873                 state->lease_ptr = NULL;
874         }
875
876         /*
877          * For a DFS path the function parse_dfs_path()
878          * will do the path processing.
879          */
880
881         if (!(smb1req->flags2 & FLAGS2_DFS_PATHNAMES)) {
882                 /* convert '\\' into '/' */
883                 status = check_path_syntax(state->fname);
884                 if (!NT_STATUS_IS_OK(status)) {
885                         tevent_req_nterror(req, status);
886                         return tevent_req_post(req, state->ev);
887                 }
888         }
889
890         ucf_flags = filename_create_ucf_flags(
891                 smb1req, state->in_create_disposition);
892         status = filename_convert(req,
893                                   smb1req->conn,
894                                   state->fname,
895                                   ucf_flags,
896                                   state->twrp_timep,
897                                   NULL, /* ppath_contains_wcards */
898                                   &smb_fname);
899         if (!NT_STATUS_IS_OK(status)) {
900                 tevent_req_nterror(req, status);
901                 return tevent_req_post(req, state->ev);
902         }
903
904         /*
905          * MS-SMB2: 2.2.13 SMB2 CREATE Request
906          * ImpersonationLevel ... MUST contain one of the
907          * following values. The server MUST validate this
908          * field, but otherwise ignore it.
909          *
910          * NB. The source4/torture/smb2/durable_open.c test
911          * shows this check is only done on real opens, not
912          * on durable handle-reopens.
913          */
914
915         if (in_impersonation_level >
916             SMB2_IMPERSONATION_DELEGATE) {
917                 tevent_req_nterror(req,
918                                    NT_STATUS_BAD_IMPERSONATION_LEVEL);
919                 return tevent_req_post(req, state->ev);
920         }
921
922         /*
923          * We know we're going to do a local open, so now
924          * we must be protocol strict. JRA.
925          *
926          * MS-SMB2: 3.3.5.9 - Receiving an SMB2 CREATE Request
927          * If the file name length is greater than zero and the
928          * first character is a path separator character, the
929          * server MUST fail the request with
930          * STATUS_INVALID_PARAMETER.
931          */
932         if (in_name[0] == '\\' || in_name[0] == '/') {
933                 tevent_req_nterror(req,
934                                    NT_STATUS_INVALID_PARAMETER);
935                 return tevent_req_post(req, state->ev);
936         }
937
938         status = SMB_VFS_CREATE_FILE(smb1req->conn,
939                                      smb1req,
940                                      0, /* root_dir_fid */
941                                      smb_fname,
942                                      in_desired_access,
943                                      in_share_access,
944                                      state->in_create_disposition,
945                                      in_create_options,
946                                      in_file_attributes,
947                                      map_smb2_oplock_levels_to_samba(
948                                              state->requested_oplock_level),
949                                      state->lease_ptr,
950                                      state->allocation_size,
951                                      0, /* private_flags */
952                                      state->sec_desc,
953                                      state->ea_list,
954                                      &state->result,
955                                      &state->info,
956                                      &in_context_blobs,
957                                      state->out_context_blobs);
958         if (!NT_STATUS_IS_OK(status)) {
959                 if (open_was_deferred(smb1req->xconn, smb1req->mid)) {
960                         SMBPROFILE_IOBYTES_ASYNC_SET_IDLE(smb2req->profile);
961                         return req;
962                 }
963                 tevent_req_nterror(req, status);
964                 return tevent_req_post(req, state->ev);
965         }
966         state->op = state->result->op;
967
968         smbd_smb2_create_after_exec(req);
969         if (!tevent_req_is_in_progress(req)) {
970                 return req;
971         }
972
973         smbd_smb2_create_finish(req);
974         return req;
975 }
976
977 static void smbd_smb2_create_before_exec(struct tevent_req *req)
978 {
979         struct smbd_smb2_create_state *state = tevent_req_data(
980                 req, struct smbd_smb2_create_state);
981         struct smb_request *smb1req = state->smb1req;
982         struct smbd_smb2_request *smb2req = state->smb2req;
983         NTSTATUS status;
984
985         if (state->exta != NULL) {
986                 if (!lp_ea_support(SNUM(smb2req->tcon->compat))) {
987                         tevent_req_nterror(req, NT_STATUS_EAS_NOT_SUPPORTED);
988                         return;
989                 }
990
991                 state->ea_list = read_nttrans_ea_list(
992                         state,
993                         (const char *)state->exta->data.data,
994                         state->exta->data.length);
995                 if (state->ea_list == NULL) {
996                         DEBUG(10,("smbd_smb2_create_send: read_ea_name_list failed.\n"));
997                         tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
998                         return;
999                 }
1000
1001                 /*
1002                  * NB. When SMB2+ unix extensions are added,
1003                  * we need to relax this check in invalid
1004                  * names - we used to not do this if
1005                  * lp_posix_pathnames() was false.
1006                  */
1007                 if (ea_list_has_invalid_name(state->ea_list)) {
1008                         tevent_req_nterror(req, STATUS_INVALID_EA_NAME);
1009                         return;
1010                 }
1011         }
1012
1013         if (state->mxac != NULL) {
1014                 if (state->mxac->data.length == 0) {
1015                         state->max_access_time = 0;
1016                 } else if (state->mxac->data.length == 8) {
1017                         state->max_access_time = BVAL(state->mxac->data.data, 0);
1018                 } else {
1019                         tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
1020                         return;
1021                 }
1022         }
1023
1024         if (state->secd != NULL) {
1025                 enum ndr_err_code ndr_err;
1026
1027                 state->sec_desc = talloc_zero(state, struct security_descriptor);
1028                 if (tevent_req_nomem(state->sec_desc, req)) {
1029                         return;
1030                 }
1031
1032                 ndr_err = ndr_pull_struct_blob(&state->secd->data,
1033                                                state->sec_desc, state->sec_desc,
1034                                                (ndr_pull_flags_fn_t)ndr_pull_security_descriptor);
1035                 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1036                         DEBUG(2,("ndr_pull_security_descriptor failed: %s\n",
1037                                  ndr_errstr(ndr_err)));
1038                         tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
1039                         return;
1040                 }
1041         }
1042
1043         if (state->dhnq != NULL) {
1044                 if (state->dhnq->data.length != 16) {
1045                         tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
1046                         return;
1047                 }
1048
1049                 if (state->dh2q != NULL) {
1050                         tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
1051                         return;
1052                 }
1053
1054                 /*
1055                  * durable handle request is processed below.
1056                  */
1057                 state->durable_requested = true;
1058                 /*
1059                  * Set the timeout to 16 mins.
1060                  *
1061                  * TODO: test this against Windows 2012
1062                  *       as the default for durable v2 is 1 min.
1063                  */
1064                 state->durable_timeout_msec = (16*60*1000);
1065         }
1066
1067         if (state->dh2q != NULL) {
1068                 const uint8_t *p = state->dh2q->data.data;
1069                 uint32_t durable_v2_timeout = 0;
1070                 DATA_BLOB create_guid_blob;
1071                 const uint8_t *hdr;
1072                 uint32_t flags;
1073
1074                 if (state->dh2q->data.length != 32) {
1075                         tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
1076                         return;
1077                 }
1078
1079                 if (state->dhnq != NULL) {
1080                         tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
1081                         return;
1082                 }
1083
1084                 durable_v2_timeout = IVAL(p, 0);
1085                 create_guid_blob = data_blob_const(p + 16, 16);
1086
1087                 status = GUID_from_ndr_blob(&create_guid_blob,
1088                                             &state->_create_guid);
1089                 if (tevent_req_nterror(req, status)) {
1090                         return;
1091                 }
1092                 state->create_guid = &state->_create_guid;
1093
1094                 /*
1095                  * we need to store the create_guid later
1096                  */
1097                 state->update_open = true;
1098
1099                 /*
1100                  * And we need to create a cache for replaying the
1101                  * create.
1102                  */
1103                 state->need_replay_cache = true;
1104
1105                 /*
1106                  * durable handle v2 request processed below
1107                  */
1108                 state->durable_requested = true;
1109                 state->durable_timeout_msec = durable_v2_timeout;
1110                 if (state->durable_timeout_msec == 0) {
1111                         /*
1112                          * Set the timeout to 1 min as default.
1113                          *
1114                          * This matches Windows 2012.
1115                          */
1116                         state->durable_timeout_msec = (60*1000);
1117                 }
1118
1119                 /*
1120                  * Check for replay operation.
1121                  * Only consider it when we have dh2q.
1122                  * If we do not have a replay operation, verify that
1123                  * the create_guid is not cached for replay.
1124                  */
1125                 hdr = SMBD_SMB2_IN_HDR_PTR(smb2req);
1126                 flags = IVAL(hdr, SMB2_HDR_FLAGS);
1127                 state->replay_operation =
1128                         flags & SMB2_HDR_FLAG_REPLAY_OPERATION;
1129
1130                 status = smb2srv_open_lookup_replay_cache(smb2req->xconn,
1131                                                           state->create_guid,
1132                                                           0 /* now */,
1133                                                           &state->op);
1134                 if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) {
1135                         state->replay_operation = false;
1136                 } else if (tevent_req_nterror(req, status)) {
1137                         DBG_WARNING("smb2srv_open_lookup_replay_cache "
1138                                     "failed: %s\n", nt_errstr(status));
1139                         return;
1140                 } else if (!state->replay_operation) {
1141                         /*
1142                          * If a create without replay operation flag
1143                          * is sent but with a create_guid that is
1144                          * currently in the replay cache -- fail.
1145                          */
1146                         status = NT_STATUS_DUPLICATE_OBJECTID;
1147                         (void)tevent_req_nterror(req, status);
1148                         return;
1149                 }
1150         }
1151
1152         if (state->dhnc != NULL) {
1153                 state->persistent_id = BVAL(state->dhnc->data.data, 0);
1154                 state->do_durable_reconnect = true;
1155         }
1156
1157         if (state->dh2c != NULL) {
1158                 const uint8_t *p = state->dh2c->data.data;
1159                 DATA_BLOB create_guid_blob;
1160
1161                 state->persistent_id = BVAL(p, 0);
1162                 create_guid_blob = data_blob_const(p + 16, 16);
1163
1164                 status = GUID_from_ndr_blob(&create_guid_blob,
1165                                             &state->_create_guid);
1166                 if (tevent_req_nterror(req, status)) {
1167                         return;
1168                 }
1169
1170                 state->create_guid = &state->_create_guid;
1171                 state->do_durable_reconnect = true;
1172         }
1173
1174         if (state->alsi != NULL) {
1175                 if (state->alsi->data.length != 8) {
1176                         tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
1177                         return;
1178                 }
1179                 state->allocation_size = BVAL(state->alsi->data.data, 0);
1180         }
1181
1182         if (state->twrp != NULL) {
1183                 NTTIME nttime;
1184
1185                 if (state->twrp->data.length != 8) {
1186                         tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
1187                         return;
1188                 }
1189
1190                 nttime = BVAL(state->twrp->data.data, 0);
1191                 state->twrp_time = nt_time_to_unix(nttime);
1192                 state->twrp_timep = &state->twrp_time;
1193
1194                 smb1req->flags2 |= FLAGS2_REPARSE_PATH;
1195         }
1196
1197         if (state->qfid != NULL) {
1198                 if (state->qfid->data.length != 0) {
1199                         tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
1200                         return;
1201                 }
1202         }
1203
1204         if (state->rqls != NULL) {
1205                 ssize_t lease_len = -1;
1206
1207                 lease_len = smb2_lease_pull(state->rqls->data.data,
1208                                             state->rqls->data.length,
1209                                             &state->lease);
1210                 if (lease_len == -1) {
1211                         tevent_req_nterror(
1212                                 req, NT_STATUS_INVALID_PARAMETER);
1213                         return;
1214                 }
1215                 state->lease_ptr = &state->lease;
1216
1217                 if (DEBUGLEVEL >= 10) {
1218                         DEBUG(10, ("Got lease request size %d\n",
1219                                    (int)lease_len));
1220                         NDR_PRINT_DEBUG(smb2_lease, state->lease_ptr);
1221                 }
1222
1223                 if (!smb2_lease_key_valid(&state->lease.lease_key)) {
1224                         state->lease_ptr = NULL;
1225                         state->requested_oplock_level = SMB2_OPLOCK_LEVEL_NONE;
1226                 }
1227
1228                 if ((smb2req->xconn->protocol < PROTOCOL_SMB3_00) &&
1229                     (state->lease.lease_version != 1))
1230                 {
1231                         DEBUG(10, ("v2 lease key only for SMB3\n"));
1232                         state->lease_ptr = NULL;
1233                 }
1234
1235                 /*
1236                  * Replay with a lease is only allowed if the
1237                  * established open carries a lease with the
1238                  * same lease key.
1239                  */
1240                 if (state->replay_operation) {
1241                         struct smb2_lease *op_ls =
1242                                 &state->op->compat->lease->lease;
1243                         int op_oplock = state->op->compat->oplock_type;
1244
1245                         if (map_samba_oplock_levels_to_smb2(op_oplock)
1246                             != SMB2_OPLOCK_LEVEL_LEASE)
1247                         {
1248                                 status = NT_STATUS_ACCESS_DENIED;
1249                                 (void)tevent_req_nterror(req, status);
1250                                 return;
1251                         }
1252                         if (!smb2_lease_key_equal(&state->lease.lease_key,
1253                                                   &op_ls->lease_key))
1254                         {
1255                                 status = NT_STATUS_ACCESS_DENIED;
1256                                 (void)tevent_req_nterror(req, status);
1257                                 return;
1258                         }
1259                 }
1260         }
1261
1262         return;
1263 }
1264
1265 static void smbd_smb2_create_after_exec(struct tevent_req *req)
1266 {
1267         struct smbd_smb2_create_state *state = tevent_req_data(
1268                 req, struct smbd_smb2_create_state);
1269         struct smb_request *smb1req = state->smb1req;
1270         NTSTATUS status;
1271
1272         /*
1273          * here we have op == result->op
1274          */
1275
1276         DEBUG(10, ("smbd_smb2_create_send: "
1277                    "response construction phase\n"));
1278
1279         if (state->mxac != NULL) {
1280                 NTTIME last_write_time;
1281
1282                 last_write_time = unix_timespec_to_nt_time(
1283                         state->result->fsp_name->st.st_ex_mtime);
1284                 if (last_write_time != state->max_access_time) {
1285                         uint8_t p[8];
1286                         uint32_t max_access_granted;
1287                         DATA_BLOB blob = data_blob_const(p, sizeof(p));
1288
1289                         status = smbd_calculate_access_mask(smb1req->conn,
1290                                                             state->result->fsp_name,
1291                                                             false,
1292                                                             SEC_FLAG_MAXIMUM_ALLOWED,
1293                                                             &max_access_granted);
1294
1295                         SIVAL(p, 0, NT_STATUS_V(status));
1296                         SIVAL(p, 4, max_access_granted);
1297
1298                         status = smb2_create_blob_add(
1299                                 state->out_context_blobs,
1300                                 state->out_context_blobs,
1301                                 SMB2_CREATE_TAG_MXAC,
1302                                 blob);
1303                         if (!NT_STATUS_IS_OK(status)) {
1304                                 tevent_req_nterror(req, status);
1305                                 tevent_req_post(req, state->ev);
1306                                 return;
1307                         }
1308                 }
1309         }
1310
1311         if (!state->replay_operation && state->durable_requested &&
1312             (fsp_lease_type(state->result) & SMB2_LEASE_HANDLE))
1313         {
1314                 status = SMB_VFS_DURABLE_COOKIE(
1315                         state->result,
1316                         state->op,
1317                         &state->op->global->backend_cookie);
1318                 if (!NT_STATUS_IS_OK(status)) {
1319                         state->op->global->backend_cookie = data_blob_null;
1320                 }
1321         }
1322         if (!state->replay_operation && state->op->global->backend_cookie.length > 0)
1323         {
1324                 state->update_open = true;
1325
1326                 state->op->global->durable = true;
1327                 state->op->global->durable_timeout_msec = state->durable_timeout_msec;
1328         }
1329
1330         if (state->update_open) {
1331                 state->op->global->create_guid = state->_create_guid;
1332                 if (state->need_replay_cache) {
1333                         state->op->flags |= SMBXSRV_OPEN_NEED_REPLAY_CACHE;
1334                 }
1335
1336                 status = smbXsrv_open_update(state->op);
1337                 DEBUG(10, ("smb2_create_send: smbXsrv_open_update "
1338                            "returned %s\n",
1339                            nt_errstr(status)));
1340                 if (!NT_STATUS_IS_OK(status)) {
1341                         tevent_req_nterror(req, status);
1342                         tevent_req_post(req, state->ev);
1343                         return;
1344                 }
1345         }
1346
1347         if (state->dhnq != NULL && state->op->global->durable) {
1348                 uint8_t p[8] = { 0, };
1349                 DATA_BLOB blob = data_blob_const(p, sizeof(p));
1350
1351                 status = smb2_create_blob_add(state->out_context_blobs,
1352                                               state->out_context_blobs,
1353                                               SMB2_CREATE_TAG_DHNQ,
1354                                               blob);
1355                 if (!NT_STATUS_IS_OK(status)) {
1356                         tevent_req_nterror(req, status);
1357                         tevent_req_post(req, state->ev);
1358                         return;
1359                 }
1360         }
1361
1362         if (state->dh2q != NULL && state->op->global->durable &&
1363             /*
1364              * For replay operations, we return the dh2q blob
1365              * in the case of oplocks not based on the state of
1366              * the open, but on whether it could have been granted
1367              * for the request data. In the case of leases instead,
1368              * the state of the open is used...
1369              */
1370             (!state->replay_operation ||
1371              state->in_oplock_level == SMB2_OPLOCK_LEVEL_BATCH ||
1372              state->in_oplock_level == SMB2_OPLOCK_LEVEL_LEASE))
1373         {
1374                 uint8_t p[8] = { 0, };
1375                 DATA_BLOB blob = data_blob_const(p, sizeof(p));
1376                 uint32_t durable_v2_response_flags = 0;
1377
1378                 SIVAL(p, 0, state->op->global->durable_timeout_msec);
1379                 SIVAL(p, 4, durable_v2_response_flags);
1380
1381                 status = smb2_create_blob_add(state->out_context_blobs,
1382                                               state->out_context_blobs,
1383                                               SMB2_CREATE_TAG_DH2Q,
1384                                               blob);
1385                 if (!NT_STATUS_IS_OK(status)) {
1386                         tevent_req_nterror(req, status);
1387                         tevent_req_post(req, state->ev);
1388                         return;
1389                 }
1390         }
1391
1392         if (state->qfid != NULL) {
1393                 uint8_t p[32];
1394                 uint64_t file_index = get_FileIndex(state->result->conn,
1395                                                     &state->result->fsp_name->st);
1396                 DATA_BLOB blob = data_blob_const(p, sizeof(p));
1397
1398                 ZERO_STRUCT(p);
1399
1400                 /* From conversations with Microsoft engineers at
1401                    the MS plugfest. The first 8 bytes are the "volume index"
1402                    == inode, the second 8 bytes are the "volume id",
1403                    == dev. This will be updated in the SMB2 doc. */
1404                 SBVAL(p, 0, file_index);
1405                 SIVAL(p, 8, state->result->fsp_name->st.st_ex_dev);/* FileIndexHigh */
1406
1407                 status = smb2_create_blob_add(state->out_context_blobs,
1408                                               state->out_context_blobs,
1409                                               SMB2_CREATE_TAG_QFID,
1410                                               blob);
1411                 if (!NT_STATUS_IS_OK(status)) {
1412                         tevent_req_nterror(req, status);
1413                         tevent_req_post(req, state->ev);
1414                         return;
1415                 }
1416         }
1417
1418         if ((state->rqls != NULL) && (state->result->oplock_type == LEASE_OPLOCK)) {
1419                 uint8_t buf[52];
1420                 struct smb2_lease lease;
1421                 size_t lease_len;
1422
1423                 lease = state->result->lease->lease;
1424
1425                 lease_len = sizeof(buf);
1426                 if (lease.lease_version == 1) {
1427                         lease_len = 32;
1428                 }
1429
1430                 if (!smb2_lease_push(&lease, buf, lease_len)) {
1431                         tevent_req_nterror(
1432                                 req, NT_STATUS_INTERNAL_ERROR);
1433                         tevent_req_post(req, state->ev);
1434                         return;
1435                 }
1436
1437                 status = smb2_create_blob_add(
1438                         state, state->out_context_blobs,
1439                         SMB2_CREATE_TAG_RQLS,
1440                         data_blob_const(buf, lease_len));
1441                 if (!NT_STATUS_IS_OK(status)) {
1442                         tevent_req_nterror(req, status);
1443                         tevent_req_post(req, state->ev);
1444                         return;
1445                 }
1446         }
1447
1448         return;
1449 }
1450
1451 static void smbd_smb2_create_finish(struct tevent_req *req)
1452 {
1453         struct smbd_smb2_create_state *state = tevent_req_data(
1454                 req, struct smbd_smb2_create_state);
1455         struct smbd_smb2_request *smb2req = state->smb2req;
1456         struct smb_request *smb1req = state->smb1req;
1457         files_struct *result = state->result;
1458
1459         smb2req->compat_chain_fsp = smb1req->chain_fsp;
1460
1461         if (state->replay_operation) {
1462                 state->out_oplock_level = state->in_oplock_level;
1463         } else if (lp_fake_oplocks(SNUM(smb2req->tcon->compat))) {
1464                 state->out_oplock_level = state->in_oplock_level;
1465         } else {
1466                 state->out_oplock_level = map_samba_oplock_levels_to_smb2(result->oplock_type);
1467         }
1468
1469         if ((state->in_create_disposition == FILE_SUPERSEDE)
1470             && (state->info == FILE_WAS_OVERWRITTEN)) {
1471                 state->out_create_action = FILE_WAS_SUPERSEDED;
1472         } else {
1473                 state->out_create_action = state->info;
1474         }
1475         result->op->create_action = state->out_create_action;
1476         state->out_file_attributes = dos_mode(result->conn,
1477                                            result->fsp_name);
1478
1479         state->out_creation_ts = get_create_timespec(smb1req->conn,
1480                                         result, result->fsp_name);
1481         state->out_last_access_ts = result->fsp_name->st.st_ex_atime;
1482         state->out_last_write_ts = result->fsp_name->st.st_ex_mtime;
1483         state->out_change_ts = get_change_timespec(smb1req->conn,
1484                                         result, result->fsp_name);
1485
1486         if (lp_dos_filetime_resolution(SNUM(smb2req->tcon->compat))) {
1487                 dos_filetime_timespec(&state->out_creation_ts);
1488                 dos_filetime_timespec(&state->out_last_access_ts);
1489                 dos_filetime_timespec(&state->out_last_write_ts);
1490                 dos_filetime_timespec(&state->out_change_ts);
1491         }
1492
1493         state->out_allocation_size =
1494                         SMB_VFS_GET_ALLOC_SIZE(smb1req->conn, result,
1495                                                &(result->fsp_name->st));
1496         state->out_end_of_file = result->fsp_name->st.st_ex_size;
1497         if (state->out_file_attributes == 0) {
1498                 state->out_file_attributes = FILE_ATTRIBUTE_NORMAL;
1499         }
1500         state->out_file_id_persistent = result->op->global->open_persistent_id;
1501         state->out_file_id_volatile = result->op->global->open_volatile_id;
1502
1503         DBG_DEBUG("%s - %s\n", fsp_str_dbg(result), fsp_fnum_dbg(result));
1504
1505         tevent_req_done(req);
1506         tevent_req_post(req, state->ev);
1507         return;
1508 }
1509
1510 static NTSTATUS smbd_smb2_create_recv(struct tevent_req *req,
1511                         TALLOC_CTX *mem_ctx,
1512                         uint8_t *out_oplock_level,
1513                         uint32_t *out_create_action,
1514                         struct timespec *out_creation_ts,
1515                         struct timespec *out_last_access_ts,
1516                         struct timespec *out_last_write_ts,
1517                         struct timespec *out_change_ts,
1518                         uint64_t *out_allocation_size,
1519                         uint64_t *out_end_of_file,
1520                         uint32_t *out_file_attributes,
1521                         uint64_t *out_file_id_persistent,
1522                         uint64_t *out_file_id_volatile,
1523                         struct smb2_create_blobs *out_context_blobs)
1524 {
1525         NTSTATUS status;
1526         struct smbd_smb2_create_state *state = tevent_req_data(req,
1527                                                struct smbd_smb2_create_state);
1528
1529         if (tevent_req_is_nterror(req, &status)) {
1530                 tevent_req_received(req);
1531                 return status;
1532         }
1533
1534         *out_oplock_level       = state->out_oplock_level;
1535         *out_create_action      = state->out_create_action;
1536         *out_creation_ts        = state->out_creation_ts;
1537         *out_last_access_ts     = state->out_last_access_ts;
1538         *out_last_write_ts      = state->out_last_write_ts;
1539         *out_change_ts          = state->out_change_ts;
1540         *out_allocation_size    = state->out_allocation_size;
1541         *out_end_of_file        = state->out_end_of_file;
1542         *out_file_attributes    = state->out_file_attributes;
1543         *out_file_id_persistent = state->out_file_id_persistent;
1544         *out_file_id_volatile   = state->out_file_id_volatile;
1545         *out_context_blobs      = *(state->out_context_blobs);
1546
1547         talloc_steal(mem_ctx, state->out_context_blobs->blobs);
1548
1549         tevent_req_received(req);
1550         return NT_STATUS_OK;
1551 }
1552
1553 /*********************************************************
1554  Code for dealing with deferred opens.
1555 *********************************************************/
1556
1557 bool get_deferred_open_message_state_smb2(struct smbd_smb2_request *smb2req,
1558                         struct timeval *p_request_time,
1559                         struct deferred_open_record **open_rec)
1560 {
1561         struct smbd_smb2_create_state *state = NULL;
1562         struct tevent_req *req = NULL;
1563
1564         if (!smb2req) {
1565                 return false;
1566         }
1567         req = smb2req->subreq;
1568         if (!req) {
1569                 return false;
1570         }
1571         state = tevent_req_data(req, struct smbd_smb2_create_state);
1572         if (!state) {
1573                 return false;
1574         }
1575         if (!state->open_was_deferred) {
1576                 return false;
1577         }
1578         if (p_request_time) {
1579                 *p_request_time = state->request_time;
1580         }
1581         if (open_rec != NULL) {
1582                 *open_rec = state->open_rec;
1583         }
1584         return true;
1585 }
1586
1587 /*********************************************************
1588  Re-process this call early - requested by message or
1589  close.
1590 *********************************************************/
1591
1592 static struct smbd_smb2_request *find_open_smb2req(
1593         struct smbXsrv_connection *xconn, uint64_t mid)
1594 {
1595         struct smbd_smb2_request *smb2req;
1596
1597         for (smb2req = xconn->smb2.requests; smb2req; smb2req = smb2req->next) {
1598                 uint64_t message_id;
1599                 if (smb2req->subreq == NULL) {
1600                         /* This message has been processed. */
1601                         continue;
1602                 }
1603                 if (!tevent_req_is_in_progress(smb2req->subreq)) {
1604                         /* This message has been processed. */
1605                         continue;
1606                 }
1607                 message_id = get_mid_from_smb2req(smb2req);
1608                 if (message_id == mid) {
1609                         return smb2req;
1610                 }
1611         }
1612         return NULL;
1613 }
1614
1615 bool open_was_deferred_smb2(struct smbXsrv_connection *xconn, uint64_t mid)
1616 {
1617         struct smbd_smb2_create_state *state = NULL;
1618         struct smbd_smb2_request *smb2req;
1619
1620         smb2req = find_open_smb2req(xconn, mid);
1621
1622         if (!smb2req) {
1623                 DEBUG(10,("open_was_deferred_smb2: mid %llu smb2req == NULL\n",
1624                         (unsigned long long)mid));
1625                 return false;
1626         }
1627         if (!smb2req->subreq) {
1628                 return false;
1629         }
1630         if (!tevent_req_is_in_progress(smb2req->subreq)) {
1631                 return false;
1632         }
1633         state = tevent_req_data(smb2req->subreq,
1634                         struct smbd_smb2_create_state);
1635         if (!state) {
1636                 return false;
1637         }
1638         /* It's not in progress if there's no timeout event. */
1639         if (!state->open_was_deferred) {
1640                 return false;
1641         }
1642
1643         DEBUG(10,("open_was_deferred_smb2: mid = %llu\n",
1644                         (unsigned long long)mid));
1645
1646         return true;
1647 }
1648
1649 static void remove_deferred_open_message_smb2_internal(struct smbd_smb2_request *smb2req,
1650                                                         uint64_t mid)
1651 {
1652         struct smbd_smb2_create_state *state = NULL;
1653
1654         if (!smb2req->subreq) {
1655                 return;
1656         }
1657         if (!tevent_req_is_in_progress(smb2req->subreq)) {
1658                 return;
1659         }
1660         state = tevent_req_data(smb2req->subreq,
1661                         struct smbd_smb2_create_state);
1662         if (!state) {
1663                 return;
1664         }
1665
1666         DEBUG(10,("remove_deferred_open_message_smb2_internal: "
1667                 "mid %llu\n",
1668                 (unsigned long long)mid ));
1669
1670         state->open_was_deferred = false;
1671         /* Ensure we don't have any outstanding immediate event. */
1672         TALLOC_FREE(state->im);
1673 }
1674
1675 void remove_deferred_open_message_smb2(
1676         struct smbXsrv_connection *xconn, uint64_t mid)
1677 {
1678         struct smbd_smb2_request *smb2req;
1679
1680         smb2req = find_open_smb2req(xconn, mid);
1681
1682         if (!smb2req) {
1683                 DEBUG(10,("remove_deferred_open_message_smb2: "
1684                         "can't find mid %llu\n",
1685                         (unsigned long long)mid ));
1686                 return;
1687         }
1688         remove_deferred_open_message_smb2_internal(smb2req, mid);
1689 }
1690
1691 static void smbd_smb2_create_request_dispatch_immediate(struct tevent_context *ctx,
1692                                         struct tevent_immediate *im,
1693                                         void *private_data)
1694 {
1695         struct smbd_smb2_request *smb2req = talloc_get_type_abort(private_data,
1696                                         struct smbd_smb2_request);
1697         uint64_t mid = get_mid_from_smb2req(smb2req);
1698         NTSTATUS status;
1699
1700         DEBUG(10,("smbd_smb2_create_request_dispatch_immediate: "
1701                 "re-dispatching mid %llu\n",
1702                 (unsigned long long)mid ));
1703
1704         status = smbd_smb2_request_dispatch(smb2req);
1705         if (!NT_STATUS_IS_OK(status)) {
1706                 smbd_server_connection_terminate(smb2req->xconn,
1707                                                  nt_errstr(status));
1708                 return;
1709         }
1710 }
1711
1712 bool schedule_deferred_open_message_smb2(
1713         struct smbXsrv_connection *xconn, uint64_t mid)
1714 {
1715         struct smbd_smb2_create_state *state = NULL;
1716         struct smbd_smb2_request *smb2req;
1717
1718         smb2req = find_open_smb2req(xconn, mid);
1719
1720         if (!smb2req) {
1721                 DEBUG(10,("schedule_deferred_open_message_smb2: "
1722                         "can't find mid %llu\n",
1723                         (unsigned long long)mid ));
1724                 return false;
1725         }
1726         if (!smb2req->subreq) {
1727                 return false;
1728         }
1729         if (!tevent_req_is_in_progress(smb2req->subreq)) {
1730                 return false;
1731         }
1732         state = tevent_req_data(smb2req->subreq,
1733                         struct smbd_smb2_create_state);
1734         if (!state) {
1735                 return false;
1736         }
1737
1738         /* Ensure we don't have any outstanding immediate event. */
1739         TALLOC_FREE(state->im);
1740
1741         /*
1742          * This is subtle. We must null out the callback
1743          * before rescheduling, else the first call to
1744          * tevent_req_nterror() causes the _receive()
1745          * function to be called, this causing tevent_req_post()
1746          * to crash.
1747          */
1748         tevent_req_set_callback(smb2req->subreq, NULL, NULL);
1749
1750         state->im = tevent_create_immediate(smb2req);
1751         if (!state->im) {
1752                 smbd_server_connection_terminate(smb2req->xconn,
1753                         nt_errstr(NT_STATUS_NO_MEMORY));
1754                 return false;
1755         }
1756
1757         DEBUG(10,("schedule_deferred_open_message_smb2: "
1758                 "re-processing mid %llu\n",
1759                 (unsigned long long)mid ));
1760
1761         tevent_schedule_immediate(state->im,
1762                         smb2req->ev_ctx,
1763                         smbd_smb2_create_request_dispatch_immediate,
1764                         smb2req);
1765
1766         return true;
1767 }
1768
1769 static bool smbd_smb2_create_cancel(struct tevent_req *req)
1770 {
1771         struct smbd_smb2_request *smb2req = NULL;
1772         struct smbd_smb2_create_state *state = tevent_req_data(req,
1773                                 struct smbd_smb2_create_state);
1774         uint64_t mid;
1775
1776         if (!state) {
1777                 return false;
1778         }
1779
1780         if (!state->smb2req) {
1781                 return false;
1782         }
1783
1784         smb2req = state->smb2req;
1785         mid = get_mid_from_smb2req(smb2req);
1786
1787         if (is_deferred_open_async(state->open_rec)) {
1788                 /* Can't cancel an async create. */
1789                 return false;
1790         }
1791
1792         remove_deferred_open_message_smb2_internal(smb2req, mid);
1793
1794         tevent_req_defer_callback(req, smb2req->ev_ctx);
1795         tevent_req_nterror(req, NT_STATUS_CANCELLED);
1796         return true;
1797 }
1798
1799 bool push_deferred_open_message_smb2(struct smbd_smb2_request *smb2req,
1800                                 struct timeval request_time,
1801                                 struct timeval timeout,
1802                                 struct file_id id,
1803                                 struct deferred_open_record *open_rec)
1804 {
1805         struct tevent_req *req = NULL;
1806         struct smbd_smb2_create_state *state = NULL;
1807         struct timeval end_time;
1808
1809         if (!smb2req) {
1810                 return false;
1811         }
1812         req = smb2req->subreq;
1813         if (!req) {
1814                 return false;
1815         }
1816         state = tevent_req_data(req, struct smbd_smb2_create_state);
1817         if (!state) {
1818                 return false;
1819         }
1820         state->id = id;
1821         state->request_time = request_time;
1822         state->open_rec = talloc_move(state, &open_rec);
1823
1824         /* Re-schedule us to retry on timer expiry. */
1825         end_time = timeval_sum(&request_time, &timeout);
1826
1827         DEBUG(10,("push_deferred_open_message_smb2: "
1828                 "timeout at %s\n",
1829                 timeval_string(talloc_tos(),
1830                                 &end_time,
1831                                 true) ));
1832
1833         state->open_was_deferred = true;
1834
1835         /* allow this request to be canceled */
1836         tevent_req_set_cancel_fn(req, smbd_smb2_create_cancel);
1837
1838         return true;
1839 }