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