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