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