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