3f38af5dde27a55d6434f589c9290eff4d6479f6
[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->sconn->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         struct smb_filename *smb_fname = NULL;
385         uint32_t ucf_flags;
386         NTSTATUS status;
387
388         if (lease_ptr == NULL) {
389                 if (fsp->oplock_type != LEASE_OPLOCK) {
390                         return NT_STATUS_OK;
391                 }
392                 DEBUG(10, ("Reopened file has lease, but no lease "
393                            "requested\n"));
394                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
395         }
396
397         if (fsp->oplock_type != LEASE_OPLOCK) {
398                 DEBUG(10, ("Lease requested, but reopened file has no "
399                            "lease\n"));
400                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
401         }
402
403         if (!smb2_lease_key_equal(&lease_ptr->lease_key,
404                                   &fsp->lease->lease.lease_key)) {
405                 DEBUG(10, ("Different lease key requested than found "
406                            "in reopened file\n"));
407                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
408         }
409
410         ucf_flags = filename_create_ucf_flags(smb1req, FILE_OPEN);
411         status = filename_convert(talloc_tos(), fsp->conn,
412                                   requested_filename, ucf_flags,
413                                   NULL, &smb_fname);
414         if (!NT_STATUS_IS_OK(status)) {
415                 DEBUG(10, ("filename_convert returned %s\n",
416                            nt_errstr(status)));
417                 return status;
418         }
419
420         if (!strequal(fsp->fsp_name->base_name, smb_fname->base_name)) {
421                 DEBUG(10, ("Lease requested for file %s, reopened file "
422                            "is named %s\n", smb_fname->base_name,
423                            fsp->fsp_name->base_name));
424                 TALLOC_FREE(smb_fname);
425                 return NT_STATUS_INVALID_PARAMETER;
426         }
427
428         TALLOC_FREE(smb_fname);
429
430         return NT_STATUS_OK;
431 }
432
433 struct smbd_smb2_create_state {
434         struct tevent_context *ev;
435         struct smbd_smb2_request *smb2req;
436         struct smb_request *smb1req;
437         bool open_was_deferred;
438         struct tevent_immediate *im;
439         struct timeval request_time;
440         struct file_id id;
441         struct deferred_open_record *open_rec;
442         files_struct *result;
443         bool replay_operation;
444         uint8_t in_oplock_level;
445         uint32_t in_create_disposition;
446         int requested_oplock_level;
447         int info;
448         char *fname;
449         struct ea_list *ea_list;
450         NTTIME max_access_time;
451         struct security_descriptor *sec_desc;
452         uint64_t allocation_size;
453         struct GUID _create_guid;
454         struct GUID *create_guid;
455         bool update_open;
456         bool durable_requested;
457         uint32_t durable_timeout_msec;
458         bool do_durable_reconnect;
459         uint64_t persistent_id;
460         struct smb2_lease lease;
461         struct smb2_lease *lease_ptr;
462         ssize_t lease_len;
463         bool need_replay_cache;
464         struct smbXsrv_open *op;
465
466         struct smb2_create_blob *dhnc;
467         struct smb2_create_blob *dh2c;
468         struct smb2_create_blob *dhnq;
469         struct smb2_create_blob *dh2q;
470         struct smb2_create_blob *rqls;
471         struct smb2_create_blob *exta;
472         struct smb2_create_blob *mxac;
473         struct smb2_create_blob *secd;
474         struct smb2_create_blob *alsi;
475         struct smb2_create_blob *twrp;
476         struct smb2_create_blob *qfid;
477         struct smb2_create_blob *svhdx;
478
479         uint8_t out_oplock_level;
480         uint32_t out_create_action;
481         struct timespec out_creation_ts;
482         struct timespec out_last_access_ts;
483         struct timespec out_last_write_ts;
484         struct timespec out_change_ts;
485         uint64_t out_allocation_size;
486         uint64_t out_end_of_file;
487         uint32_t out_file_attributes;
488         uint64_t out_file_id_persistent;
489         uint64_t out_file_id_volatile;
490         struct smb2_create_blobs *out_context_blobs;
491 };
492
493 static NTSTATUS smbd_smb2_create_fetch_create_ctx(
494         struct tevent_req *req,
495         struct smb2_create_blobs *in_context_blobs)
496 {
497         struct smbd_smb2_create_state *state = tevent_req_data(
498                 req, struct smbd_smb2_create_state);
499
500         state->dhnq = smb2_create_blob_find(in_context_blobs,
501                                             SMB2_CREATE_TAG_DHNQ);
502         state->dhnc = smb2_create_blob_find(in_context_blobs,
503                                             SMB2_CREATE_TAG_DHNC);
504         state->dh2q = smb2_create_blob_find(in_context_blobs,
505                                             SMB2_CREATE_TAG_DH2Q);
506         state->dh2c = smb2_create_blob_find(in_context_blobs,
507                                             SMB2_CREATE_TAG_DH2C);
508         if (state->smb2req->xconn->smb2.server.capabilities & SMB2_CAP_LEASING) {
509                 state->rqls = smb2_create_blob_find(in_context_blobs,
510                                                     SMB2_CREATE_TAG_RQLS);
511         }
512
513         if (((state->dhnc != NULL) && (state->dh2c != NULL)) ||
514             ((state->dhnc != NULL) && (state->dh2q != NULL)) ||
515             ((state->dh2c != NULL) && (state->dhnq != NULL)) ||
516             ((state->dh2q != NULL) && (state->dh2c != NULL)))
517         {
518                 /* not both are allowed at the same time */
519                 return NT_STATUS_INVALID_PARAMETER;
520         }
521
522         if (state->dhnc != NULL) {
523                 uint32_t num_blobs_allowed;
524
525                 if (state->dhnc->data.length != 16) {
526                         return NT_STATUS_INVALID_PARAMETER;
527                 }
528
529                 /*
530                  * According to MS-SMB2: 3.3.5.9.7, "Handling the
531                  * SMB2_CREATE_DURABLE_HANDLE_RECONNECT Create Context",
532                  * we should ignore an additional dhnq blob, but fail
533                  * the request (with status OBJECT_NAME_NOT_FOUND) if
534                  * any other extra create blob has been provided.
535                  *
536                  * (Note that the cases of an additional dh2q or dh2c blob
537                  *  which require a different error code, have been treated
538                  *  above.)
539                  */
540
541                 if (state->dhnq != NULL) {
542                         num_blobs_allowed = 2;
543                 } else {
544                         num_blobs_allowed = 1;
545                 }
546
547                 if (state->rqls != NULL) {
548                         num_blobs_allowed += 1;
549                 }
550
551                 if (in_context_blobs->num_blobs != num_blobs_allowed) {
552                         return NT_STATUS_OBJECT_NAME_NOT_FOUND;
553                 }
554         }
555
556         if (state->dh2c!= NULL) {
557                 uint32_t num_blobs_allowed;
558
559                 if (state->dh2c->data.length != 36) {
560                         return NT_STATUS_INVALID_PARAMETER;
561                 }
562
563                 /*
564                  * According to MS-SMB2: 3.3.5.9.12, "Handling the
565                  * SMB2_CREATE_DURABLE_HANDLE_RECONNECT_V2 Create Context",
566                  * we should fail the request with status
567                  * OBJECT_NAME_NOT_FOUND if any other create blob has been
568                  * provided.
569                  *
570                  * (Note that the cases of an additional dhnq, dhnc or dh2q
571                  *  blob which require a different error code, have been
572                  *  treated above.)
573                  */
574
575                 num_blobs_allowed = 1;
576
577                 if (state->rqls != NULL) {
578                         num_blobs_allowed += 1;
579                 }
580
581                 if (in_context_blobs->num_blobs != num_blobs_allowed) {
582                         return NT_STATUS_OBJECT_NAME_NOT_FOUND;
583                 }
584         }
585
586         state->exta = smb2_create_blob_find(in_context_blobs,
587                                             SMB2_CREATE_TAG_EXTA);
588         state->mxac = smb2_create_blob_find(in_context_blobs,
589                                             SMB2_CREATE_TAG_MXAC);
590         state->secd = smb2_create_blob_find(in_context_blobs,
591                                             SMB2_CREATE_TAG_SECD);
592         state->alsi = smb2_create_blob_find(in_context_blobs,
593                                             SMB2_CREATE_TAG_ALSI);
594         state->twrp = smb2_create_blob_find(in_context_blobs,
595                                             SMB2_CREATE_TAG_TWRP);
596         state->qfid = smb2_create_blob_find(in_context_blobs,
597                                             SMB2_CREATE_TAG_QFID);
598         if (state->smb2req->xconn->protocol >= PROTOCOL_SMB3_02) {
599                 /*
600                  * This was introduced with SMB3_02
601                  */
602                 state->svhdx = smb2_create_blob_find(
603                         in_context_blobs, SVHDX_OPEN_DEVICE_CONTEXT);
604         }
605
606         return NT_STATUS_OK;
607 }
608
609 static void smbd_smb2_create_before_exec(struct tevent_req *req);
610 static void smbd_smb2_create_after_exec(struct tevent_req *req);
611 static void smbd_smb2_create_finish(struct tevent_req *req);
612
613 static struct tevent_req *smbd_smb2_create_send(TALLOC_CTX *mem_ctx,
614                         struct tevent_context *ev,
615                         struct smbd_smb2_request *smb2req,
616                         uint8_t in_oplock_level,
617                         uint32_t in_impersonation_level,
618                         uint32_t in_desired_access,
619                         uint32_t in_file_attributes,
620                         uint32_t in_share_access,
621                         uint32_t in_create_disposition,
622                         uint32_t in_create_options,
623                         const char *in_name,
624                         struct smb2_create_blobs in_context_blobs)
625 {
626         struct tevent_req *req = NULL;
627         struct smbd_smb2_create_state *state = NULL;
628         NTSTATUS status;
629         struct smb_request *smb1req = NULL;
630         struct smb_filename *smb_fname = NULL;
631         uint32_t ucf_flags;
632
633         req = tevent_req_create(mem_ctx, &state,
634                                 struct smbd_smb2_create_state);
635         if (req == NULL) {
636                 return NULL;
637         }
638         *state = (struct smbd_smb2_create_state) {
639                 .ev = ev,
640                 .smb2req = smb2req,
641                 .in_oplock_level = in_oplock_level,
642                 .in_create_disposition = in_create_disposition,
643         };
644
645         smb1req = smbd_smb2_fake_smb_request(smb2req);
646         if (tevent_req_nomem(smb1req, req)) {
647                 return tevent_req_post(req, state->ev);
648         }
649         state->smb1req = smb1req;
650
651         if (smb2req->subreq == NULL) {
652                 DBG_DEBUG("name [%s]\n", in_name);
653         } else {
654                 struct smbd_smb2_create_state *old_state = tevent_req_data(
655                         smb2req->subreq, struct smbd_smb2_create_state);
656
657                 DBG_DEBUG("reentrant for file %s\n", in_name);
658
659                 state->id = old_state->id;
660                 state->request_time = old_state->request_time;
661                 state->open_rec = talloc_move(state, &old_state->open_rec);
662                 state->open_was_deferred = old_state->open_was_deferred;
663         }
664
665         TALLOC_FREE(smb2req->subreq);
666         smb2req->subreq = req;
667
668         if (lp_fake_oplocks(SNUM(smb2req->tcon->compat))) {
669                 state->requested_oplock_level = SMB2_OPLOCK_LEVEL_NONE;
670         } else {
671                 state->requested_oplock_level = state->in_oplock_level;
672         }
673
674         /* these are ignored for SMB2 */
675         in_create_options &= ~(0x10);/* NTCREATEX_OPTIONS_SYNC_ALERT */
676         in_create_options &= ~(0x20);/* NTCREATEX_OPTIONS_ASYNC_ALERT */
677
678         in_file_attributes &= ~FILE_FLAG_POSIX_SEMANTICS;
679
680         state->fname = talloc_strdup(state, in_name);
681         if (tevent_req_nomem(state->fname, req)) {
682                 return tevent_req_post(req, state->ev);
683         }
684
685         state->out_context_blobs = talloc_zero(state, struct smb2_create_blobs);
686         if (tevent_req_nomem(state->out_context_blobs, req)) {
687                 return tevent_req_post(req, state->ev);
688         }
689
690         status = smbd_smb2_create_fetch_create_ctx(req, &in_context_blobs);
691         if (tevent_req_nterror(req, status)) {
692                 return tevent_req_post(req, state->ev);
693         }
694
695         if (IS_IPC(smb1req->conn)) {
696                 const char *pipe_name = in_name;
697
698                 if (state->dhnc != NULL || state->dh2c != NULL) {
699                         /* durable handles are not supported on IPC$ */
700                         tevent_req_nterror(req, NT_STATUS_OBJECT_NAME_NOT_FOUND);
701                         return tevent_req_post(req, state->ev);
702                 }
703
704                 if (!lp_nt_pipe_support()) {
705                         tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
706                         return tevent_req_post(req, state->ev);
707                 }
708
709                 status = open_np_file(smb1req, pipe_name, &state->result);
710                 if (!NT_STATUS_IS_OK(status)) {
711                         tevent_req_nterror(req, status);
712                         return tevent_req_post(req, state->ev);
713                 }
714                 state->info = FILE_WAS_OPENED;
715
716                 smbd_smb2_create_finish(req);
717                 return req;
718
719         } else if (CAN_PRINT(smb1req->conn)) {
720                 if (state->dhnc != NULL || state->dh2c != NULL) {
721                         /* durable handles are not supported on printers */
722                         tevent_req_nterror(req, NT_STATUS_OBJECT_NAME_NOT_FOUND);
723                         return tevent_req_post(req, state->ev);
724                 }
725
726                 status = file_new(smb1req, smb1req->conn, &state->result);
727                 if(!NT_STATUS_IS_OK(status)) {
728                         tevent_req_nterror(req, status);
729                         return tevent_req_post(req, state->ev);
730                 }
731
732                 status = print_spool_open(state->result, in_name,
733                                           smb1req->vuid);
734                 if (!NT_STATUS_IS_OK(status)) {
735                         file_free(smb1req, state->result);
736                         tevent_req_nterror(req, status);
737                         return tevent_req_post(req, state->ev);
738                 }
739                 state->info = FILE_WAS_CREATED;
740
741                 smbd_smb2_create_finish(req);
742                 return req;
743         }
744
745         smbd_smb2_create_before_exec(req);
746         if (!tevent_req_is_in_progress(req)) {
747                 return tevent_req_post(req, state->ev);
748         }
749
750         DBG_DEBUG("open execution phase\n");
751
752         /*
753          * For the backend file open procedure, there are
754          * three possible modes: replay operation (in which case
755          * there is nothing else to do), durable_reconnect or
756          * new open.
757          */
758         if (state->replay_operation) {
759                 state->result = state->op->compat;
760                 state->result->op = state->op;
761                 state->update_open = false;
762                 state->info = state->op->create_action;
763
764                 smbd_smb2_create_after_exec(req);
765                 if (!tevent_req_is_in_progress(req)) {
766                         return req;
767                 }
768
769                 smbd_smb2_create_finish(req);
770                 return req;
771
772         } else if (state->do_durable_reconnect) {
773                 DATA_BLOB new_cookie = data_blob_null;
774                 NTTIME now = timeval_to_nttime(&smb2req->request_time);
775
776                 status = smb2srv_open_recreate(smb2req->xconn,
777                                                smb1req->conn->session_info,
778                                                state->persistent_id,
779                                                state->create_guid,
780                                                now,
781                                                &state->op);
782                 if (!NT_STATUS_IS_OK(status)) {
783                         DBG_NOTICE("smb2srv_open_recreate failed: %s\n",
784                                    nt_errstr(status));
785                         tevent_req_nterror(req, status);
786                         return tevent_req_post(req, state->ev);
787                 }
788
789                 DBG_DEBUG("%s to recreate durable handle\n",
790                           state->op->global->durable ? "succeeded" : "failed");
791
792                 if (!state->op->global->durable) {
793                         talloc_free(state->op);
794                         tevent_req_nterror(req,
795                                            NT_STATUS_OBJECT_NAME_NOT_FOUND);
796                         return tevent_req_post(req, state->ev);
797                 }
798
799                 status = SMB_VFS_DURABLE_RECONNECT(smb1req->conn,
800                                                    smb1req,
801                                                    state->op, /* smbXsrv_open input */
802                                                    state->op->global->backend_cookie,
803                                                    state->op, /* TALLOC_CTX */
804                                                    &state->result,
805                                                    &new_cookie);
806                 if (!NT_STATUS_IS_OK(status)) {
807                         NTSTATUS return_status;
808
809                         return_status = NT_STATUS_OBJECT_NAME_NOT_FOUND;
810
811                         DBG_NOTICE("durable_reconnect failed: %s => %s\n",
812                                    nt_errstr(status),
813                                    nt_errstr(return_status));
814
815                         tevent_req_nterror(req, return_status);
816                         return tevent_req_post(req, state->ev);
817                 }
818
819                 DBG_DEBUG("oplock_type=%u, lease_ptr==%p\n",
820                           (unsigned)state->result->oplock_type, state->lease_ptr);
821
822                 status = smbd_smb2_create_durable_lease_check(
823                         smb1req, state->fname, state->result, state->lease_ptr);
824                 if (!NT_STATUS_IS_OK(status)) {
825                         close_file(smb1req, state->result, SHUTDOWN_CLOSE);
826                         tevent_req_nterror(req, status);
827                         return tevent_req_post(req, state->ev);
828                 }
829
830                 data_blob_free(&state->op->global->backend_cookie);
831                 state->op->global->backend_cookie = new_cookie;
832
833                 state->op->status = NT_STATUS_OK;
834                 state->op->global->disconnect_time = 0;
835
836                 /* save the timout for later update */
837                 state->durable_timeout_msec = state->op->global->durable_timeout_msec;
838
839                 state->update_open = true;
840
841                 state->info = FILE_WAS_OPENED;
842
843                 smbd_smb2_create_after_exec(req);
844                 if (!tevent_req_is_in_progress(req)) {
845                         return req;
846                 }
847
848                 smbd_smb2_create_finish(req);
849                 return req;
850         }
851
852         if (state->requested_oplock_level == SMB2_OPLOCK_LEVEL_LEASE) {
853                 if (state->lease_ptr == NULL) {
854                         state->requested_oplock_level = SMB2_OPLOCK_LEVEL_NONE;
855                 }
856         } else {
857                 state->lease_ptr = NULL;
858         }
859
860         /*
861          * For a DFS path the function parse_dfs_path()
862          * will do the path processing.
863          */
864
865         if (!(smb1req->flags2 & FLAGS2_DFS_PATHNAMES)) {
866                 /* convert '\\' into '/' */
867                 status = check_path_syntax(state->fname);
868                 if (!NT_STATUS_IS_OK(status)) {
869                         tevent_req_nterror(req, status);
870                         return tevent_req_post(req, state->ev);
871                 }
872         }
873
874         ucf_flags = filename_create_ucf_flags(
875                 smb1req, state->in_create_disposition);
876         status = filename_convert(req,
877                                   smb1req->conn,
878                                   state->fname,
879                                   ucf_flags,
880                                   NULL, /* ppath_contains_wcards */
881                                   &smb_fname);
882         if (!NT_STATUS_IS_OK(status)) {
883                 tevent_req_nterror(req, status);
884                 return tevent_req_post(req, state->ev);
885         }
886
887         /*
888          * MS-SMB2: 2.2.13 SMB2 CREATE Request
889          * ImpersonationLevel ... MUST contain one of the
890          * following values. The server MUST validate this
891          * field, but otherwise ignore it.
892          *
893          * NB. The source4/torture/smb2/durable_open.c test
894          * shows this check is only done on real opens, not
895          * on durable handle-reopens.
896          */
897
898         if (in_impersonation_level >
899             SMB2_IMPERSONATION_DELEGATE) {
900                 tevent_req_nterror(req,
901                                    NT_STATUS_BAD_IMPERSONATION_LEVEL);
902                 return tevent_req_post(req, state->ev);
903         }
904
905         /*
906          * We know we're going to do a local open, so now
907          * we must be protocol strict. JRA.
908          *
909          * MS-SMB2: 3.3.5.9 - Receiving an SMB2 CREATE Request
910          * If the file name length is greater than zero and the
911          * first character is a path separator character, the
912          * server MUST fail the request with
913          * STATUS_INVALID_PARAMETER.
914          */
915         if (in_name[0] == '\\' || in_name[0] == '/') {
916                 tevent_req_nterror(req,
917                                    NT_STATUS_INVALID_PARAMETER);
918                 return tevent_req_post(req, state->ev);
919         }
920
921         status = SMB_VFS_CREATE_FILE(smb1req->conn,
922                                      smb1req,
923                                      0, /* root_dir_fid */
924                                      smb_fname,
925                                      in_desired_access,
926                                      in_share_access,
927                                      state->in_create_disposition,
928                                      in_create_options,
929                                      in_file_attributes,
930                                      map_smb2_oplock_levels_to_samba(
931                                              state->requested_oplock_level),
932                                      state->lease_ptr,
933                                      state->allocation_size,
934                                      0, /* private_flags */
935                                      state->sec_desc,
936                                      state->ea_list,
937                                      &state->result,
938                                      &state->info,
939                                      &in_context_blobs,
940                                      state->out_context_blobs);
941         if (!NT_STATUS_IS_OK(status)) {
942                 if (open_was_deferred(smb1req->xconn, smb1req->mid)) {
943                         SMBPROFILE_IOBYTES_ASYNC_SET_IDLE(smb2req->profile);
944                         return req;
945                 }
946                 tevent_req_nterror(req, status);
947                 return tevent_req_post(req, state->ev);
948         }
949         state->op = state->result->op;
950
951         smbd_smb2_create_after_exec(req);
952         if (!tevent_req_is_in_progress(req)) {
953                 return req;
954         }
955
956         smbd_smb2_create_finish(req);
957         return req;
958 }
959
960 static void smbd_smb2_create_before_exec(struct tevent_req *req)
961 {
962         struct smbd_smb2_create_state *state = tevent_req_data(
963                 req, struct smbd_smb2_create_state);
964         struct smb_request *smb1req = state->smb1req;
965         struct smbd_smb2_request *smb2req = state->smb2req;
966         NTSTATUS status;
967
968         if (state->exta != NULL) {
969                 if (!lp_ea_support(SNUM(smb2req->tcon->compat))) {
970                         tevent_req_nterror(req, NT_STATUS_EAS_NOT_SUPPORTED);
971                         return;
972                 }
973
974                 state->ea_list = read_nttrans_ea_list(
975                         state,
976                         (const char *)state->exta->data.data,
977                         state->exta->data.length);
978                 if (state->ea_list == NULL) {
979                         DEBUG(10,("smbd_smb2_create_send: read_ea_name_list failed.\n"));
980                         tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
981                         return;
982                 }
983
984                 /*
985                  * NB. When SMB2+ unix extensions are added,
986                  * we need to relax this check in invalid
987                  * names - we used to not do this if
988                  * lp_posix_pathnames() was false.
989                  */
990                 if (ea_list_has_invalid_name(state->ea_list)) {
991                         tevent_req_nterror(req, STATUS_INVALID_EA_NAME);
992                         return;
993                 }
994         }
995
996         if (state->mxac != NULL) {
997                 if (state->mxac->data.length == 0) {
998                         state->max_access_time = 0;
999                 } else if (state->mxac->data.length == 8) {
1000                         state->max_access_time = BVAL(state->mxac->data.data, 0);
1001                 } else {
1002                         tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
1003                         return;
1004                 }
1005         }
1006
1007         if (state->secd != NULL) {
1008                 enum ndr_err_code ndr_err;
1009
1010                 state->sec_desc = talloc_zero(state, struct security_descriptor);
1011                 if (tevent_req_nomem(state->sec_desc, req)) {
1012                         return;
1013                 }
1014
1015                 ndr_err = ndr_pull_struct_blob(&state->secd->data,
1016                                                state->sec_desc, state->sec_desc,
1017                                                (ndr_pull_flags_fn_t)ndr_pull_security_descriptor);
1018                 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1019                         DEBUG(2,("ndr_pull_security_descriptor failed: %s\n",
1020                                  ndr_errstr(ndr_err)));
1021                         tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
1022                         return;
1023                 }
1024         }
1025
1026         if (state->dhnq != NULL) {
1027                 if (state->dhnq->data.length != 16) {
1028                         tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
1029                         return;
1030                 }
1031
1032                 if (state->dh2q != NULL) {
1033                         tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
1034                         return;
1035                 }
1036
1037                 /*
1038                  * durable handle request is processed below.
1039                  */
1040                 state->durable_requested = true;
1041                 /*
1042                  * Set the timeout to 16 mins.
1043                  *
1044                  * TODO: test this against Windows 2012
1045                  *       as the default for durable v2 is 1 min.
1046                  */
1047                 state->durable_timeout_msec = (16*60*1000);
1048         }
1049
1050         if (state->dh2q != NULL) {
1051                 const uint8_t *p = state->dh2q->data.data;
1052                 uint32_t durable_v2_timeout = 0;
1053                 DATA_BLOB create_guid_blob;
1054                 const uint8_t *hdr;
1055                 uint32_t flags;
1056
1057                 if (state->dh2q->data.length != 32) {
1058                         tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
1059                         return;
1060                 }
1061
1062                 if (state->dhnq != NULL) {
1063                         tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
1064                         return;
1065                 }
1066
1067                 durable_v2_timeout = IVAL(p, 0);
1068                 create_guid_blob = data_blob_const(p + 16, 16);
1069
1070                 status = GUID_from_ndr_blob(&create_guid_blob,
1071                                             &state->_create_guid);
1072                 if (tevent_req_nterror(req, status)) {
1073                         return;
1074                 }
1075                 state->create_guid = &state->_create_guid;
1076
1077                 /*
1078                  * we need to store the create_guid later
1079                  */
1080                 state->update_open = true;
1081
1082                 /*
1083                  * And we need to create a cache for replaying the
1084                  * create.
1085                  */
1086                 state->need_replay_cache = true;
1087
1088                 /*
1089                  * durable handle v2 request processed below
1090                  */
1091                 state->durable_requested = true;
1092                 state->durable_timeout_msec = durable_v2_timeout;
1093                 if (state->durable_timeout_msec == 0) {
1094                         /*
1095                          * Set the timeout to 1 min as default.
1096                          *
1097                          * This matches Windows 2012.
1098                          */
1099                         state->durable_timeout_msec = (60*1000);
1100                 }
1101
1102                 /*
1103                  * Check for replay operation.
1104                  * Only consider it when we have dh2q.
1105                  * If we do not have a replay operation, verify that
1106                  * the create_guid is not cached for replay.
1107                  */
1108                 hdr = SMBD_SMB2_IN_HDR_PTR(smb2req);
1109                 flags = IVAL(hdr, SMB2_HDR_FLAGS);
1110                 state->replay_operation =
1111                         flags & SMB2_HDR_FLAG_REPLAY_OPERATION;
1112
1113                 status = smb2srv_open_lookup_replay_cache(smb2req->xconn,
1114                                                           state->create_guid,
1115                                                           0 /* now */,
1116                                                           &state->op);
1117                 if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) {
1118                         state->replay_operation = false;
1119                 } else if (tevent_req_nterror(req, status)) {
1120                         DBG_WARNING("smb2srv_open_lookup_replay_cache "
1121                                     "failed: %s\n", nt_errstr(status));
1122                         return;
1123                 } else if (!state->replay_operation) {
1124                         /*
1125                          * If a create without replay operation flag
1126                          * is sent but with a create_guid that is
1127                          * currently in the replay cache -- fail.
1128                          */
1129                         status = NT_STATUS_DUPLICATE_OBJECTID;
1130                         (void)tevent_req_nterror(req, status);
1131                         return;
1132                 }
1133         }
1134
1135         if (state->dhnc != NULL) {
1136                 state->persistent_id = BVAL(state->dhnc->data.data, 0);
1137                 state->do_durable_reconnect = true;
1138         }
1139
1140         if (state->dh2c != NULL) {
1141                 const uint8_t *p = state->dh2c->data.data;
1142                 DATA_BLOB create_guid_blob;
1143
1144                 state->persistent_id = BVAL(p, 0);
1145                 create_guid_blob = data_blob_const(p + 16, 16);
1146
1147                 status = GUID_from_ndr_blob(&create_guid_blob,
1148                                             &state->_create_guid);
1149                 if (tevent_req_nterror(req, status)) {
1150                         return;
1151                 }
1152
1153                 state->create_guid = &state->_create_guid;
1154                 state->do_durable_reconnect = true;
1155         }
1156
1157         if (state->alsi != NULL) {
1158                 if (state->alsi->data.length != 8) {
1159                         tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
1160                         return;
1161                 }
1162                 state->allocation_size = BVAL(state->alsi->data.data, 0);
1163         }
1164
1165         if (state->twrp != NULL) {
1166                 NTTIME nttime;
1167                 time_t t;
1168                 struct tm *tm;
1169                 char *tmpname = state->fname;
1170
1171                 if (state->twrp->data.length != 8) {
1172                         tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
1173                         return;
1174                 }
1175
1176                 nttime = BVAL(state->twrp->data.data, 0);
1177                 t = nt_time_to_unix(nttime);
1178                 tm = gmtime(&t);
1179
1180                 state->fname = talloc_asprintf(
1181                         state,
1182                         "%s\\@GMT-%04u.%02u.%02u-%02u.%02u.%02u",
1183                         state->fname,
1184                         tm->tm_year + 1900,
1185                         tm->tm_mon + 1,
1186                         tm->tm_mday,
1187                         tm->tm_hour,
1188                         tm->tm_min,
1189                         tm->tm_sec);
1190                 if (tevent_req_nomem(state->fname, req)) {
1191                         return;
1192                 }
1193                 TALLOC_FREE(tmpname);
1194                 /*
1195                  * Tell filename_create_ucf_flags() this
1196                  * is an @GMT path.
1197                  */
1198                 smb1req->flags2 |= FLAGS2_REPARSE_PATH;
1199         }
1200
1201         if (state->qfid != NULL) {
1202                 if (state->qfid->data.length != 0) {
1203                         tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
1204                         return;
1205                 }
1206         }
1207
1208         if (state->rqls != NULL) {
1209                 ssize_t lease_len = -1;
1210
1211                 lease_len = smb2_lease_pull(state->rqls->data.data,
1212                                             state->rqls->data.length,
1213                                             &state->lease);
1214                 if (lease_len == -1) {
1215                         tevent_req_nterror(
1216                                 req, NT_STATUS_INVALID_PARAMETER);
1217                         return;
1218                 }
1219                 state->lease_ptr = &state->lease;
1220
1221                 if (DEBUGLEVEL >= 10) {
1222                         DEBUG(10, ("Got lease request size %d\n",
1223                                    (int)lease_len));
1224                         NDR_PRINT_DEBUG(smb2_lease, state->lease_ptr);
1225                 }
1226
1227                 if (!smb2_lease_key_valid(&state->lease.lease_key)) {
1228                         state->lease_ptr = NULL;
1229                         state->requested_oplock_level = SMB2_OPLOCK_LEVEL_NONE;
1230                 }
1231
1232                 if ((smb2req->xconn->protocol < PROTOCOL_SMB3_00) &&
1233                     (state->lease.lease_version != 1))
1234                 {
1235                         DEBUG(10, ("v2 lease key only for SMB3\n"));
1236                         state->lease_ptr = NULL;
1237                 }
1238
1239                 /*
1240                  * Replay with a lease is only allowed if the
1241                  * established open carries a lease with the
1242                  * same lease key.
1243                  */
1244                 if (state->replay_operation) {
1245                         struct smb2_lease *op_ls =
1246                                 &state->op->compat->lease->lease;
1247                         int op_oplock = state->op->compat->oplock_type;
1248
1249                         if (map_samba_oplock_levels_to_smb2(op_oplock)
1250                             != SMB2_OPLOCK_LEVEL_LEASE)
1251                         {
1252                                 status = NT_STATUS_ACCESS_DENIED;
1253                                 (void)tevent_req_nterror(req, status);
1254                                 return;
1255                         }
1256                         if (!smb2_lease_key_equal(&state->lease.lease_key,
1257                                                   &op_ls->lease_key))
1258                         {
1259                                 status = NT_STATUS_ACCESS_DENIED;
1260                                 (void)tevent_req_nterror(req, status);
1261                                 return;
1262                         }
1263                 }
1264         }
1265
1266         return;
1267 }
1268
1269 static void smbd_smb2_create_after_exec(struct tevent_req *req)
1270 {
1271         struct smbd_smb2_create_state *state = tevent_req_data(
1272                 req, struct smbd_smb2_create_state);
1273         struct smb_request *smb1req = state->smb1req;
1274         NTSTATUS status;
1275
1276         /*
1277          * here we have op == result->op
1278          */
1279
1280         DEBUG(10, ("smbd_smb2_create_send: "
1281                    "response construction phase\n"));
1282
1283         if (state->mxac != NULL) {
1284                 NTTIME last_write_time;
1285
1286                 last_write_time = unix_timespec_to_nt_time(
1287                         state->result->fsp_name->st.st_ex_mtime);
1288                 if (last_write_time != state->max_access_time) {
1289                         uint8_t p[8];
1290                         uint32_t max_access_granted;
1291                         DATA_BLOB blob = data_blob_const(p, sizeof(p));
1292
1293                         status = smbd_calculate_access_mask(smb1req->conn,
1294                                                             state->result->fsp_name,
1295                                                             false,
1296                                                             SEC_FLAG_MAXIMUM_ALLOWED,
1297                                                             &max_access_granted);
1298
1299                         SIVAL(p, 0, NT_STATUS_V(status));
1300                         SIVAL(p, 4, max_access_granted);
1301
1302                         status = smb2_create_blob_add(
1303                                 state->out_context_blobs,
1304                                 state->out_context_blobs,
1305                                 SMB2_CREATE_TAG_MXAC,
1306                                 blob);
1307                         if (!NT_STATUS_IS_OK(status)) {
1308                                 tevent_req_nterror(req, status);
1309                                 tevent_req_post(req, state->ev);
1310                                 return;
1311                         }
1312                 }
1313         }
1314
1315         if (!state->replay_operation && state->durable_requested &&
1316             (fsp_lease_type(state->result) & SMB2_LEASE_HANDLE))
1317         {
1318                 status = SMB_VFS_DURABLE_COOKIE(
1319                         state->result,
1320                         state->op,
1321                         &state->op->global->backend_cookie);
1322                 if (!NT_STATUS_IS_OK(status)) {
1323                         state->op->global->backend_cookie = data_blob_null;
1324                 }
1325         }
1326         if (!state->replay_operation && state->op->global->backend_cookie.length > 0)
1327         {
1328                 state->update_open = true;
1329
1330                 state->op->global->durable = true;
1331                 state->op->global->durable_timeout_msec = state->durable_timeout_msec;
1332         }
1333
1334         if (state->update_open) {
1335                 state->op->global->create_guid = state->_create_guid;
1336                 if (state->need_replay_cache) {
1337                         state->op->flags |= SMBXSRV_OPEN_NEED_REPLAY_CACHE;
1338                 }
1339
1340                 status = smbXsrv_open_update(state->op);
1341                 DEBUG(10, ("smb2_create_send: smbXsrv_open_update "
1342                            "returned %s\n",
1343                            nt_errstr(status)));
1344                 if (!NT_STATUS_IS_OK(status)) {
1345                         tevent_req_nterror(req, status);
1346                         tevent_req_post(req, state->ev);
1347                         return;
1348                 }
1349         }
1350
1351         if (state->dhnq != NULL && state->op->global->durable) {
1352                 uint8_t p[8] = { 0, };
1353                 DATA_BLOB blob = data_blob_const(p, sizeof(p));
1354
1355                 status = smb2_create_blob_add(state->out_context_blobs,
1356                                               state->out_context_blobs,
1357                                               SMB2_CREATE_TAG_DHNQ,
1358                                               blob);
1359                 if (!NT_STATUS_IS_OK(status)) {
1360                         tevent_req_nterror(req, status);
1361                         tevent_req_post(req, state->ev);
1362                         return;
1363                 }
1364         }
1365
1366         if (state->dh2q != NULL && state->op->global->durable &&
1367             /*
1368              * For replay operations, we return the dh2q blob
1369              * in the case of oplocks not based on the state of
1370              * the open, but on whether it could have been granted
1371              * for the request data. In the case of leases instead,
1372              * the state of the open is used...
1373              */
1374             (!state->replay_operation ||
1375              state->in_oplock_level == SMB2_OPLOCK_LEVEL_BATCH ||
1376              state->in_oplock_level == SMB2_OPLOCK_LEVEL_LEASE))
1377         {
1378                 uint8_t p[8] = { 0, };
1379                 DATA_BLOB blob = data_blob_const(p, sizeof(p));
1380                 uint32_t durable_v2_response_flags = 0;
1381
1382                 SIVAL(p, 0, state->op->global->durable_timeout_msec);
1383                 SIVAL(p, 4, durable_v2_response_flags);
1384
1385                 status = smb2_create_blob_add(state->out_context_blobs,
1386                                               state->out_context_blobs,
1387                                               SMB2_CREATE_TAG_DH2Q,
1388                                               blob);
1389                 if (!NT_STATUS_IS_OK(status)) {
1390                         tevent_req_nterror(req, status);
1391                         tevent_req_post(req, state->ev);
1392                         return;
1393                 }
1394         }
1395
1396         if (state->qfid != NULL) {
1397                 uint8_t p[32];
1398                 uint64_t file_index = get_FileIndex(state->result->conn,
1399                                                     &state->result->fsp_name->st);
1400                 DATA_BLOB blob = data_blob_const(p, sizeof(p));
1401
1402                 ZERO_STRUCT(p);
1403
1404                 /* From conversations with Microsoft engineers at
1405                    the MS plugfest. The first 8 bytes are the "volume index"
1406                    == inode, the second 8 bytes are the "volume id",
1407                    == dev. This will be updated in the SMB2 doc. */
1408                 SBVAL(p, 0, file_index);
1409                 SIVAL(p, 8, state->result->fsp_name->st.st_ex_dev);/* FileIndexHigh */
1410
1411                 status = smb2_create_blob_add(state->out_context_blobs,
1412                                               state->out_context_blobs,
1413                                               SMB2_CREATE_TAG_QFID,
1414                                               blob);
1415                 if (!NT_STATUS_IS_OK(status)) {
1416                         tevent_req_nterror(req, status);
1417                         tevent_req_post(req, state->ev);
1418                         return;
1419                 }
1420         }
1421
1422         if ((state->rqls != NULL) && (state->result->oplock_type == LEASE_OPLOCK)) {
1423                 uint8_t buf[52];
1424                 struct smb2_lease lease;
1425                 size_t lease_len;
1426
1427                 lease = state->result->lease->lease;
1428
1429                 lease_len = sizeof(buf);
1430                 if (lease.lease_version == 1) {
1431                         lease_len = 32;
1432                 }
1433
1434                 if (!smb2_lease_push(&lease, buf, lease_len)) {
1435                         tevent_req_nterror(
1436                                 req, NT_STATUS_INTERNAL_ERROR);
1437                         tevent_req_post(req, state->ev);
1438                         return;
1439                 }
1440
1441                 status = smb2_create_blob_add(
1442                         state, state->out_context_blobs,
1443                         SMB2_CREATE_TAG_RQLS,
1444                         data_blob_const(buf, lease_len));
1445                 if (!NT_STATUS_IS_OK(status)) {
1446                         tevent_req_nterror(req, status);
1447                         tevent_req_post(req, state->ev);
1448                         return;
1449                 }
1450         }
1451
1452         return;
1453 }
1454
1455 static void smbd_smb2_create_finish(struct tevent_req *req)
1456 {
1457         struct smbd_smb2_create_state *state = tevent_req_data(
1458                 req, struct smbd_smb2_create_state);
1459         struct smbd_smb2_request *smb2req = state->smb2req;
1460         struct smb_request *smb1req = state->smb1req;
1461         files_struct *result = state->result;
1462
1463         smb2req->compat_chain_fsp = smb1req->chain_fsp;
1464
1465         if (state->replay_operation) {
1466                 state->out_oplock_level = state->in_oplock_level;
1467         } else if (lp_fake_oplocks(SNUM(smb2req->tcon->compat))) {
1468                 state->out_oplock_level = state->in_oplock_level;
1469         } else {
1470                 state->out_oplock_level = map_samba_oplock_levels_to_smb2(result->oplock_type);
1471         }
1472
1473         if ((state->in_create_disposition == FILE_SUPERSEDE)
1474             && (state->info == FILE_WAS_OVERWRITTEN)) {
1475                 state->out_create_action = FILE_WAS_SUPERSEDED;
1476         } else {
1477                 state->out_create_action = state->info;
1478         }
1479         result->op->create_action = state->out_create_action;
1480         state->out_file_attributes = dos_mode(result->conn,
1481                                            result->fsp_name);
1482
1483         state->out_creation_ts = get_create_timespec(smb1req->conn,
1484                                         result, result->fsp_name);
1485         state->out_last_access_ts = result->fsp_name->st.st_ex_atime;
1486         state->out_last_write_ts = result->fsp_name->st.st_ex_mtime;
1487         state->out_change_ts = get_change_timespec(smb1req->conn,
1488                                         result, result->fsp_name);
1489
1490         if (lp_dos_filetime_resolution(SNUM(smb2req->tcon->compat))) {
1491                 dos_filetime_timespec(&state->out_creation_ts);
1492                 dos_filetime_timespec(&state->out_last_access_ts);
1493                 dos_filetime_timespec(&state->out_last_write_ts);
1494                 dos_filetime_timespec(&state->out_change_ts);
1495         }
1496
1497         state->out_allocation_size =
1498                         SMB_VFS_GET_ALLOC_SIZE(smb1req->conn, result,
1499                                                &(result->fsp_name->st));
1500         state->out_end_of_file = result->fsp_name->st.st_ex_size;
1501         if (state->out_file_attributes == 0) {
1502                 state->out_file_attributes = FILE_ATTRIBUTE_NORMAL;
1503         }
1504         state->out_file_id_persistent = result->op->global->open_persistent_id;
1505         state->out_file_id_volatile = result->op->global->open_volatile_id;
1506
1507         DBG_DEBUG("%s - %s\n", fsp_str_dbg(result), fsp_fnum_dbg(result));
1508
1509         tevent_req_done(req);
1510         tevent_req_post(req, state->ev);
1511         return;
1512 }
1513
1514 static NTSTATUS smbd_smb2_create_recv(struct tevent_req *req,
1515                         TALLOC_CTX *mem_ctx,
1516                         uint8_t *out_oplock_level,
1517                         uint32_t *out_create_action,
1518                         struct timespec *out_creation_ts,
1519                         struct timespec *out_last_access_ts,
1520                         struct timespec *out_last_write_ts,
1521                         struct timespec *out_change_ts,
1522                         uint64_t *out_allocation_size,
1523                         uint64_t *out_end_of_file,
1524                         uint32_t *out_file_attributes,
1525                         uint64_t *out_file_id_persistent,
1526                         uint64_t *out_file_id_volatile,
1527                         struct smb2_create_blobs *out_context_blobs)
1528 {
1529         NTSTATUS status;
1530         struct smbd_smb2_create_state *state = tevent_req_data(req,
1531                                                struct smbd_smb2_create_state);
1532
1533         if (tevent_req_is_nterror(req, &status)) {
1534                 tevent_req_received(req);
1535                 return status;
1536         }
1537
1538         *out_oplock_level       = state->out_oplock_level;
1539         *out_create_action      = state->out_create_action;
1540         *out_creation_ts        = state->out_creation_ts;
1541         *out_last_access_ts     = state->out_last_access_ts;
1542         *out_last_write_ts      = state->out_last_write_ts;
1543         *out_change_ts          = state->out_change_ts;
1544         *out_allocation_size    = state->out_allocation_size;
1545         *out_end_of_file        = state->out_end_of_file;
1546         *out_file_attributes    = state->out_file_attributes;
1547         *out_file_id_persistent = state->out_file_id_persistent;
1548         *out_file_id_volatile   = state->out_file_id_volatile;
1549         *out_context_blobs      = *(state->out_context_blobs);
1550
1551         talloc_steal(mem_ctx, state->out_context_blobs->blobs);
1552
1553         tevent_req_received(req);
1554         return NT_STATUS_OK;
1555 }
1556
1557 /*********************************************************
1558  Code for dealing with deferred opens.
1559 *********************************************************/
1560
1561 bool get_deferred_open_message_state_smb2(struct smbd_smb2_request *smb2req,
1562                         struct timeval *p_request_time,
1563                         struct deferred_open_record **open_rec)
1564 {
1565         struct smbd_smb2_create_state *state = NULL;
1566         struct tevent_req *req = NULL;
1567
1568         if (!smb2req) {
1569                 return false;
1570         }
1571         req = smb2req->subreq;
1572         if (!req) {
1573                 return false;
1574         }
1575         state = tevent_req_data(req, struct smbd_smb2_create_state);
1576         if (!state) {
1577                 return false;
1578         }
1579         if (!state->open_was_deferred) {
1580                 return false;
1581         }
1582         if (p_request_time) {
1583                 *p_request_time = state->request_time;
1584         }
1585         if (open_rec != NULL) {
1586                 *open_rec = state->open_rec;
1587         }
1588         return true;
1589 }
1590
1591 /*********************************************************
1592  Re-process this call early - requested by message or
1593  close.
1594 *********************************************************/
1595
1596 static struct smbd_smb2_request *find_open_smb2req(
1597         struct smbXsrv_connection *xconn, uint64_t mid)
1598 {
1599         struct smbd_smb2_request *smb2req;
1600
1601         for (smb2req = xconn->smb2.requests; smb2req; smb2req = smb2req->next) {
1602                 uint64_t message_id;
1603                 if (smb2req->subreq == NULL) {
1604                         /* This message has been processed. */
1605                         continue;
1606                 }
1607                 if (!tevent_req_is_in_progress(smb2req->subreq)) {
1608                         /* This message has been processed. */
1609                         continue;
1610                 }
1611                 message_id = get_mid_from_smb2req(smb2req);
1612                 if (message_id == mid) {
1613                         return smb2req;
1614                 }
1615         }
1616         return NULL;
1617 }
1618
1619 bool open_was_deferred_smb2(struct smbXsrv_connection *xconn, uint64_t mid)
1620 {
1621         struct smbd_smb2_create_state *state = NULL;
1622         struct smbd_smb2_request *smb2req;
1623
1624         smb2req = find_open_smb2req(xconn, mid);
1625
1626         if (!smb2req) {
1627                 DEBUG(10,("open_was_deferred_smb2: mid %llu smb2req == NULL\n",
1628                         (unsigned long long)mid));
1629                 return false;
1630         }
1631         if (!smb2req->subreq) {
1632                 return false;
1633         }
1634         if (!tevent_req_is_in_progress(smb2req->subreq)) {
1635                 return false;
1636         }
1637         state = tevent_req_data(smb2req->subreq,
1638                         struct smbd_smb2_create_state);
1639         if (!state) {
1640                 return false;
1641         }
1642         /* It's not in progress if there's no timeout event. */
1643         if (!state->open_was_deferred) {
1644                 return false;
1645         }
1646
1647         DEBUG(10,("open_was_deferred_smb2: mid = %llu\n",
1648                         (unsigned long long)mid));
1649
1650         return true;
1651 }
1652
1653 static void remove_deferred_open_message_smb2_internal(struct smbd_smb2_request *smb2req,
1654                                                         uint64_t mid)
1655 {
1656         struct smbd_smb2_create_state *state = NULL;
1657
1658         if (!smb2req->subreq) {
1659                 return;
1660         }
1661         if (!tevent_req_is_in_progress(smb2req->subreq)) {
1662                 return;
1663         }
1664         state = tevent_req_data(smb2req->subreq,
1665                         struct smbd_smb2_create_state);
1666         if (!state) {
1667                 return;
1668         }
1669
1670         DEBUG(10,("remove_deferred_open_message_smb2_internal: "
1671                 "mid %llu\n",
1672                 (unsigned long long)mid ));
1673
1674         state->open_was_deferred = false;
1675         /* Ensure we don't have any outstanding immediate event. */
1676         TALLOC_FREE(state->im);
1677 }
1678
1679 void remove_deferred_open_message_smb2(
1680         struct smbXsrv_connection *xconn, uint64_t mid)
1681 {
1682         struct smbd_smb2_request *smb2req;
1683
1684         smb2req = find_open_smb2req(xconn, mid);
1685
1686         if (!smb2req) {
1687                 DEBUG(10,("remove_deferred_open_message_smb2: "
1688                         "can't find mid %llu\n",
1689                         (unsigned long long)mid ));
1690                 return;
1691         }
1692         remove_deferred_open_message_smb2_internal(smb2req, mid);
1693 }
1694
1695 static void smbd_smb2_create_request_dispatch_immediate(struct tevent_context *ctx,
1696                                         struct tevent_immediate *im,
1697                                         void *private_data)
1698 {
1699         struct smbd_smb2_request *smb2req = talloc_get_type_abort(private_data,
1700                                         struct smbd_smb2_request);
1701         uint64_t mid = get_mid_from_smb2req(smb2req);
1702         NTSTATUS status;
1703
1704         DEBUG(10,("smbd_smb2_create_request_dispatch_immediate: "
1705                 "re-dispatching mid %llu\n",
1706                 (unsigned long long)mid ));
1707
1708         status = smbd_smb2_request_dispatch(smb2req);
1709         if (!NT_STATUS_IS_OK(status)) {
1710                 smbd_server_connection_terminate(smb2req->xconn,
1711                                                  nt_errstr(status));
1712                 return;
1713         }
1714 }
1715
1716 bool schedule_deferred_open_message_smb2(
1717         struct smbXsrv_connection *xconn, uint64_t mid)
1718 {
1719         struct smbd_smb2_create_state *state = NULL;
1720         struct smbd_smb2_request *smb2req;
1721
1722         smb2req = find_open_smb2req(xconn, mid);
1723
1724         if (!smb2req) {
1725                 DEBUG(10,("schedule_deferred_open_message_smb2: "
1726                         "can't find mid %llu\n",
1727                         (unsigned long long)mid ));
1728                 return false;
1729         }
1730         if (!smb2req->subreq) {
1731                 return false;
1732         }
1733         if (!tevent_req_is_in_progress(smb2req->subreq)) {
1734                 return false;
1735         }
1736         state = tevent_req_data(smb2req->subreq,
1737                         struct smbd_smb2_create_state);
1738         if (!state) {
1739                 return false;
1740         }
1741
1742         /* Ensure we don't have any outstanding immediate event. */
1743         TALLOC_FREE(state->im);
1744
1745         /*
1746          * This is subtle. We must null out the callback
1747          * before rescheduling, else the first call to
1748          * tevent_req_nterror() causes the _receive()
1749          * function to be called, this causing tevent_req_post()
1750          * to crash.
1751          */
1752         tevent_req_set_callback(smb2req->subreq, NULL, NULL);
1753
1754         state->im = tevent_create_immediate(smb2req);
1755         if (!state->im) {
1756                 smbd_server_connection_terminate(smb2req->xconn,
1757                         nt_errstr(NT_STATUS_NO_MEMORY));
1758                 return false;
1759         }
1760
1761         DEBUG(10,("schedule_deferred_open_message_smb2: "
1762                 "re-processing mid %llu\n",
1763                 (unsigned long long)mid ));
1764
1765         tevent_schedule_immediate(state->im,
1766                         smb2req->sconn->ev_ctx,
1767                         smbd_smb2_create_request_dispatch_immediate,
1768                         smb2req);
1769
1770         return true;
1771 }
1772
1773 static bool smbd_smb2_create_cancel(struct tevent_req *req)
1774 {
1775         struct smbd_smb2_request *smb2req = NULL;
1776         struct smbd_smb2_create_state *state = tevent_req_data(req,
1777                                 struct smbd_smb2_create_state);
1778         uint64_t mid;
1779
1780         if (!state) {
1781                 return false;
1782         }
1783
1784         if (!state->smb2req) {
1785                 return false;
1786         }
1787
1788         smb2req = state->smb2req;
1789         mid = get_mid_from_smb2req(smb2req);
1790
1791         if (is_deferred_open_async(state->open_rec)) {
1792                 /* Can't cancel an async create. */
1793                 return false;
1794         }
1795
1796         remove_deferred_open_message_smb2_internal(smb2req, mid);
1797
1798         tevent_req_defer_callback(req, smb2req->sconn->ev_ctx);
1799         tevent_req_nterror(req, NT_STATUS_CANCELLED);
1800         return true;
1801 }
1802
1803 bool push_deferred_open_message_smb2(struct smbd_smb2_request *smb2req,
1804                                 struct timeval request_time,
1805                                 struct timeval timeout,
1806                                 struct file_id id,
1807                                 struct deferred_open_record *open_rec)
1808 {
1809         struct tevent_req *req = NULL;
1810         struct smbd_smb2_create_state *state = NULL;
1811         struct timeval end_time;
1812
1813         if (!smb2req) {
1814                 return false;
1815         }
1816         req = smb2req->subreq;
1817         if (!req) {
1818                 return false;
1819         }
1820         state = tevent_req_data(req, struct smbd_smb2_create_state);
1821         if (!state) {
1822                 return false;
1823         }
1824         state->id = id;
1825         state->request_time = request_time;
1826         state->open_rec = talloc_move(state, &open_rec);
1827
1828         /* Re-schedule us to retry on timer expiry. */
1829         end_time = timeval_sum(&request_time, &timeout);
1830
1831         DEBUG(10,("push_deferred_open_message_smb2: "
1832                 "timeout at %s\n",
1833                 timeval_string(talloc_tos(),
1834                                 &end_time,
1835                                 true) ));
1836
1837         state->open_was_deferred = true;
1838
1839         /* allow this request to be canceled */
1840         tevent_req_set_cancel_fn(req, smbd_smb2_create_cancel);
1841
1842         return true;
1843 }