s3: smbd: Remove 'is_dfs' parameter to check_path_syntax_smb2().
[Samba.git] / source3 / smbd / smb2_create.c
blobc17562e93e180c97a1a2cf15b866578edd2ef0c2
1 /*
2 Unix SMB/CIFS implementation.
3 Core SMB2 server
5 Copyright (C) Stefan Metzmacher 2009
6 Copyright (C) Jeremy Allison 2010
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.
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.
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/>.
22 #include "includes.h"
23 #include "printing.h"
24 #include "smbd/smbd.h"
25 #include "smbd/globals.h"
26 #include "smbd/smbXsrv_open.h"
27 #include "../libcli/smb/smb_common.h"
28 #include "../librpc/gen_ndr/ndr_security.h"
29 #include "../librpc/gen_ndr/ndr_smb2_lease_struct.h"
30 #include "../lib/util/tevent_ntstatus.h"
31 #include "messages.h"
32 #include "lib/util_ea.h"
33 #include "source3/passdb/lookup_sid.h"
35 #undef DBGC_CLASS
36 #define DBGC_CLASS DBGC_SMB2
38 int map_smb2_oplock_levels_to_samba(uint8_t in_oplock_level)
40 switch(in_oplock_level) {
41 case SMB2_OPLOCK_LEVEL_NONE:
42 return NO_OPLOCK;
43 case SMB2_OPLOCK_LEVEL_II:
44 return LEVEL_II_OPLOCK;
45 case SMB2_OPLOCK_LEVEL_EXCLUSIVE:
46 return EXCLUSIVE_OPLOCK;
47 case SMB2_OPLOCK_LEVEL_BATCH:
48 return BATCH_OPLOCK;
49 case SMB2_OPLOCK_LEVEL_LEASE:
50 return LEASE_OPLOCK;
51 default:
52 DEBUG(2,("map_smb2_oplock_levels_to_samba: "
53 "unknown level %u\n",
54 (unsigned int)in_oplock_level));
55 return NO_OPLOCK;
59 static uint8_t map_samba_oplock_levels_to_smb2(int oplock_type)
61 if (BATCH_OPLOCK_TYPE(oplock_type)) {
62 return SMB2_OPLOCK_LEVEL_BATCH;
63 } else if (EXCLUSIVE_OPLOCK_TYPE(oplock_type)) {
64 return SMB2_OPLOCK_LEVEL_EXCLUSIVE;
65 } else if (oplock_type == LEVEL_II_OPLOCK) {
66 return SMB2_OPLOCK_LEVEL_II;
67 } else if (oplock_type == LEASE_OPLOCK) {
68 return SMB2_OPLOCK_LEVEL_LEASE;
69 } else {
70 return SMB2_OPLOCK_LEVEL_NONE;
75 MS-FSA 2.1.5.1 Server Requests an Open of a File
76 Trailing '/' or '\\' checker.
77 Must be done before the filename parser removes any
78 trailing characters. If we decide to add this to SMB1
79 NTCreate processing we can make this public.
81 Note this is Windows pathname processing only. When
82 POSIX pathnames are added to SMB2 this will not apply.
85 static NTSTATUS windows_name_trailing_check(const char *name,
86 uint32_t create_options)
88 size_t name_len = strlen(name);
89 char trail_c;
91 if (name_len <= 1) {
92 return NT_STATUS_OK;
95 trail_c = name[name_len-1];
98 * Trailing '/' is always invalid.
100 if (trail_c == '/') {
101 return NT_STATUS_OBJECT_NAME_INVALID;
104 if (create_options & FILE_NON_DIRECTORY_FILE) {
105 if (trail_c == '\\') {
106 return NT_STATUS_OBJECT_NAME_INVALID;
109 return NT_STATUS_OK;
112 static struct tevent_req *smbd_smb2_create_send(TALLOC_CTX *mem_ctx,
113 struct tevent_context *ev,
114 struct smbd_smb2_request *smb2req,
115 uint8_t in_oplock_level,
116 uint32_t in_impersonation_level,
117 uint32_t in_desired_access,
118 uint32_t in_file_attributes,
119 uint32_t in_share_access,
120 uint32_t in_create_disposition,
121 uint32_t in_create_options,
122 const char *in_name,
123 struct smb2_create_blobs in_context_blobs);
124 static NTSTATUS smbd_smb2_create_recv(struct tevent_req *req,
125 TALLOC_CTX *mem_ctx,
126 uint8_t *out_oplock_level,
127 uint32_t *out_create_action,
128 struct timespec *out_creation_ts,
129 struct timespec *out_last_access_ts,
130 struct timespec *out_last_write_ts,
131 struct timespec *out_change_ts,
132 uint64_t *out_allocation_size,
133 uint64_t *out_end_of_file,
134 uint32_t *out_file_attributes,
135 uint64_t *out_file_id_persistent,
136 uint64_t *out_file_id_volatile,
137 struct smb2_create_blobs *out_context_blobs);
139 static void smbd_smb2_request_create_done(struct tevent_req *tsubreq);
140 NTSTATUS smbd_smb2_request_process_create(struct smbd_smb2_request *smb2req)
142 const uint8_t *inbody;
143 const struct iovec *indyniov;
144 uint8_t in_oplock_level;
145 uint32_t in_impersonation_level;
146 uint32_t in_desired_access;
147 uint32_t in_file_attributes;
148 uint32_t in_share_access;
149 uint32_t in_create_disposition;
150 uint32_t in_create_options;
151 uint16_t in_name_offset;
152 uint16_t in_name_length;
153 DATA_BLOB in_name_buffer;
154 char *in_name_string;
155 size_t in_name_string_size;
156 uint32_t name_offset = 0;
157 uint32_t name_available_length = 0;
158 uint32_t in_context_offset;
159 uint32_t in_context_length;
160 DATA_BLOB in_context_buffer;
161 struct smb2_create_blobs in_context_blobs;
162 uint32_t context_offset = 0;
163 uint32_t context_available_length = 0;
164 uint32_t dyn_offset;
165 NTSTATUS status;
166 bool ok;
167 struct tevent_req *tsubreq;
169 status = smbd_smb2_request_verify_sizes(smb2req, 0x39);
170 if (!NT_STATUS_IS_OK(status)) {
171 return smbd_smb2_request_error(smb2req, status);
173 inbody = SMBD_SMB2_IN_BODY_PTR(smb2req);
175 in_oplock_level = CVAL(inbody, 0x03);
176 in_impersonation_level = IVAL(inbody, 0x04);
177 in_desired_access = IVAL(inbody, 0x18);
178 in_file_attributes = IVAL(inbody, 0x1C);
179 in_share_access = IVAL(inbody, 0x20);
180 in_create_disposition = IVAL(inbody, 0x24);
181 in_create_options = IVAL(inbody, 0x28);
182 in_name_offset = SVAL(inbody, 0x2C);
183 in_name_length = SVAL(inbody, 0x2E);
184 in_context_offset = IVAL(inbody, 0x30);
185 in_context_length = IVAL(inbody, 0x34);
188 * First check if the dynamic name and context buffers
189 * are correctly specified.
191 * Note: That we don't check if the name and context buffers
192 * overlap
195 dyn_offset = SMB2_HDR_BODY + SMBD_SMB2_IN_BODY_LEN(smb2req);
197 if (in_name_offset == 0 && in_name_length == 0) {
198 /* This is ok */
199 name_offset = 0;
200 } else if (in_name_offset < dyn_offset) {
201 return smbd_smb2_request_error(smb2req, NT_STATUS_INVALID_PARAMETER);
202 } else {
203 name_offset = in_name_offset - dyn_offset;
206 indyniov = SMBD_SMB2_IN_DYN_IOV(smb2req);
208 if (name_offset > indyniov->iov_len) {
209 return smbd_smb2_request_error(smb2req, NT_STATUS_INVALID_PARAMETER);
212 name_available_length = indyniov->iov_len - name_offset;
214 if (in_name_length > name_available_length) {
215 return smbd_smb2_request_error(smb2req, NT_STATUS_INVALID_PARAMETER);
218 in_name_buffer.data = (uint8_t *)indyniov->iov_base + name_offset;
219 in_name_buffer.length = in_name_length;
221 if (in_context_offset == 0 && in_context_length == 0) {
222 /* This is ok */
223 context_offset = 0;
224 } else if (in_context_offset < dyn_offset) {
225 return smbd_smb2_request_error(smb2req, NT_STATUS_INVALID_PARAMETER);
226 } else {
227 context_offset = in_context_offset - dyn_offset;
230 if (context_offset > indyniov->iov_len) {
231 return smbd_smb2_request_error(smb2req, NT_STATUS_INVALID_PARAMETER);
234 context_available_length = indyniov->iov_len - context_offset;
236 if (in_context_length > context_available_length) {
237 return smbd_smb2_request_error(smb2req, NT_STATUS_INVALID_PARAMETER);
240 in_context_buffer.data = (uint8_t *)indyniov->iov_base +
241 context_offset;
242 in_context_buffer.length = in_context_length;
245 * Now interpret the name and context buffers
248 ok = convert_string_talloc(smb2req, CH_UTF16, CH_UNIX,
249 in_name_buffer.data,
250 in_name_buffer.length,
251 &in_name_string,
252 &in_name_string_size);
253 if (!ok) {
254 return smbd_smb2_request_error(smb2req, NT_STATUS_ILLEGAL_CHARACTER);
257 if (in_name_buffer.length == 0) {
258 in_name_string_size = 0;
261 if (strlen(in_name_string) != in_name_string_size) {
262 return smbd_smb2_request_error(smb2req, NT_STATUS_OBJECT_NAME_INVALID);
265 ZERO_STRUCT(in_context_blobs);
266 status = smb2_create_blob_parse(smb2req, in_context_buffer, &in_context_blobs);
267 if (!NT_STATUS_IS_OK(status)) {
268 return smbd_smb2_request_error(smb2req, status);
271 if (CHECK_DEBUGLVL(DBGLVL_DEBUG)) {
272 char *str = talloc_asprintf(
273 talloc_tos(),
274 "\nGot %"PRIu32" create blobs\n",
275 in_context_blobs.num_blobs);
276 uint32_t i;
278 for (i=0; i<in_context_blobs.num_blobs; i++) {
279 struct smb2_create_blob *b =
280 &in_context_blobs.blobs[i];
281 talloc_asprintf_addbuf(&str, "[%"PRIu32"]\n", i);
282 dump_data_addbuf(
283 (uint8_t *)b->tag, strlen(b->tag), &str);
284 dump_data_addbuf(
285 b->data.data, b->data.length, &str);
287 DBG_DEBUG("%s", str);
288 TALLOC_FREE(str);
291 tsubreq = smbd_smb2_create_send(smb2req,
292 smb2req->sconn->ev_ctx,
293 smb2req,
294 in_oplock_level,
295 in_impersonation_level,
296 in_desired_access,
297 in_file_attributes,
298 in_share_access,
299 in_create_disposition,
300 in_create_options,
301 in_name_string,
302 in_context_blobs);
303 if (tsubreq == NULL) {
304 smb2req->subreq = NULL;
305 return smbd_smb2_request_error(smb2req, NT_STATUS_NO_MEMORY);
307 tevent_req_set_callback(tsubreq, smbd_smb2_request_create_done, smb2req);
309 return smbd_smb2_request_pending_queue(smb2req, tsubreq, 500);
312 static uint64_t get_mid_from_smb2req(struct smbd_smb2_request *smb2req)
314 uint8_t *reqhdr = SMBD_SMB2_OUT_HDR_PTR(smb2req);
315 return BVAL(reqhdr, SMB2_HDR_MESSAGE_ID);
318 static void smbd_smb2_request_create_done(struct tevent_req *tsubreq)
320 struct smbd_smb2_request *smb2req = tevent_req_callback_data(tsubreq,
321 struct smbd_smb2_request);
322 DATA_BLOB outbody;
323 DATA_BLOB outdyn;
324 uint8_t out_oplock_level = 0;
325 uint32_t out_create_action = 0;
326 connection_struct *conn = smb2req->tcon->compat;
327 struct timespec out_creation_ts = { 0, };
328 struct timespec out_last_access_ts = { 0, };
329 struct timespec out_last_write_ts = { 0, };
330 struct timespec out_change_ts = { 0, };
331 uint64_t out_allocation_size = 0;
332 uint64_t out_end_of_file = 0;
333 uint32_t out_file_attributes = 0;
334 uint64_t out_file_id_persistent = 0;
335 uint64_t out_file_id_volatile = 0;
336 struct smb2_create_blobs out_context_blobs;
337 DATA_BLOB out_context_buffer;
338 uint16_t out_context_buffer_offset = 0;
339 NTSTATUS status;
340 NTSTATUS error; /* transport error */
342 status = smbd_smb2_create_recv(tsubreq,
343 smb2req,
344 &out_oplock_level,
345 &out_create_action,
346 &out_creation_ts,
347 &out_last_access_ts,
348 &out_last_write_ts,
349 &out_change_ts,
350 &out_allocation_size,
351 &out_end_of_file,
352 &out_file_attributes,
353 &out_file_id_persistent,
354 &out_file_id_volatile,
355 &out_context_blobs);
356 if (!NT_STATUS_IS_OK(status)) {
357 if (smbd_smb2_is_compound(smb2req)) {
358 smb2req->compound_create_err = status;
360 error = smbd_smb2_request_error(smb2req, status);
361 if (!NT_STATUS_IS_OK(error)) {
362 smbd_server_connection_terminate(smb2req->xconn,
363 nt_errstr(error));
364 return;
366 return;
369 status = smb2_create_blob_push(smb2req, &out_context_buffer, out_context_blobs);
370 if (!NT_STATUS_IS_OK(status)) {
371 error = smbd_smb2_request_error(smb2req, status);
372 if (!NT_STATUS_IS_OK(error)) {
373 smbd_server_connection_terminate(smb2req->xconn,
374 nt_errstr(error));
375 return;
377 return;
380 if (out_context_buffer.length > 0) {
381 out_context_buffer_offset = SMB2_HDR_BODY + 0x58;
384 outbody = smbd_smb2_generate_outbody(smb2req, 0x58);
385 if (outbody.data == NULL) {
386 error = smbd_smb2_request_error(smb2req, NT_STATUS_NO_MEMORY);
387 if (!NT_STATUS_IS_OK(error)) {
388 smbd_server_connection_terminate(smb2req->xconn,
389 nt_errstr(error));
390 return;
392 return;
395 SSVAL(outbody.data, 0x00, 0x58 + 1); /* struct size */
396 SCVAL(outbody.data, 0x02,
397 out_oplock_level); /* oplock level */
398 SCVAL(outbody.data, 0x03, 0); /* reserved */
399 SIVAL(outbody.data, 0x04,
400 out_create_action); /* create action */
401 put_long_date_full_timespec(conn->ts_res,
402 (char *)outbody.data + 0x08,
403 &out_creation_ts); /* creation time */
404 put_long_date_full_timespec(conn->ts_res,
405 (char *)outbody.data + 0x10,
406 &out_last_access_ts); /* last access time */
407 put_long_date_full_timespec(conn->ts_res,
408 (char *)outbody.data + 0x18,
409 &out_last_write_ts); /* last write time */
410 put_long_date_full_timespec(conn->ts_res,
411 (char *)outbody.data + 0x20,
412 &out_change_ts); /* change time */
413 SBVAL(outbody.data, 0x28,
414 out_allocation_size); /* allocation size */
415 SBVAL(outbody.data, 0x30,
416 out_end_of_file); /* end of file */
417 SIVAL(outbody.data, 0x38,
418 out_file_attributes); /* file attributes */
419 SIVAL(outbody.data, 0x3C, 0); /* reserved */
420 SBVAL(outbody.data, 0x40,
421 out_file_id_persistent); /* file id (persistent) */
422 SBVAL(outbody.data, 0x48,
423 out_file_id_volatile); /* file id (volatile) */
424 SIVAL(outbody.data, 0x50,
425 out_context_buffer_offset); /* create contexts offset */
426 SIVAL(outbody.data, 0x54,
427 out_context_buffer.length); /* create contexts length */
429 outdyn = out_context_buffer;
431 error = smbd_smb2_request_done(smb2req, outbody, &outdyn);
432 if (!NT_STATUS_IS_OK(error)) {
433 smbd_server_connection_terminate(smb2req->xconn,
434 nt_errstr(error));
435 return;
439 static bool smb2_lease_key_valid(const struct smb2_lease_key *key)
441 return ((key->data[0] != 0) || (key->data[1] != 0));
444 static NTSTATUS smbd_smb2_create_durable_lease_check(struct smb_request *smb1req,
445 const char *requested_filename, const struct files_struct *fsp,
446 const struct smb2_lease *lease_ptr)
448 struct files_struct *dirfsp = NULL;
449 char *filename = NULL;
450 struct smb_filename *smb_fname = NULL;
451 uint32_t ucf_flags;
452 NTTIME twrp = fsp->fsp_name->twrp;
453 NTSTATUS status;
454 bool is_dfs = (smb1req->flags2 & FLAGS2_DFS_PATHNAMES);
456 if (lease_ptr == NULL) {
457 if (fsp->oplock_type != LEASE_OPLOCK) {
458 return NT_STATUS_OK;
460 DEBUG(10, ("Reopened file has lease, but no lease "
461 "requested\n"));
462 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
465 if (fsp->oplock_type != LEASE_OPLOCK) {
466 DEBUG(10, ("Lease requested, but reopened file has no "
467 "lease\n"));
468 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
471 if (!smb2_lease_key_equal(&lease_ptr->lease_key,
472 &fsp->lease->lease.lease_key)) {
473 DEBUG(10, ("Different lease key requested than found "
474 "in reopened file\n"));
475 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
478 if (is_dfs) {
479 const char *non_dfs_requested_filename = NULL;
481 * With a DFS flag set, remove any DFS prefix
482 * before further processing.
484 status = smb2_strip_dfs_path(requested_filename,
485 &non_dfs_requested_filename);
486 if (!NT_STATUS_IS_OK(status)) {
487 return status;
490 * TODO: Note for dealing with reparse point errors.
491 * We will need to remember and store the number of characters
492 * we have removed here, which is
493 * (requested_filename - non_dfs_requested_filename)
494 * in order to correctly report how many characters we
495 * have removed before hitting the reparse point.
496 * This will be a patch needed once we properly
497 * deal with reparse points later.
499 requested_filename = non_dfs_requested_filename;
501 * Now we're no longer dealing with a DFS path, so
502 * remove the flag.
504 smb1req->flags2 &= ~FLAGS2_DFS_PATHNAMES;
505 is_dfs = false;
508 filename = talloc_strdup(talloc_tos(), requested_filename);
509 if (filename == NULL) {
510 return NT_STATUS_NO_MEMORY;
513 /* This also converts '\' to '/' */
514 status = check_path_syntax_smb2(filename);
515 if (!NT_STATUS_IS_OK(status)) {
516 TALLOC_FREE(filename);
517 return status;
520 ucf_flags = filename_create_ucf_flags(smb1req, FILE_OPEN);
521 status = filename_convert_dirfsp(talloc_tos(),
522 fsp->conn,
523 filename,
524 ucf_flags,
525 twrp,
526 &dirfsp,
527 &smb_fname);
528 TALLOC_FREE(filename);
529 if (!NT_STATUS_IS_OK(status)) {
530 DEBUG(10, ("filename_convert returned %s\n",
531 nt_errstr(status)));
532 return status;
535 if (!strequal(fsp->fsp_name->base_name, smb_fname->base_name)) {
536 DEBUG(10, ("Lease requested for file %s, reopened file "
537 "is named %s\n", smb_fname->base_name,
538 fsp->fsp_name->base_name));
539 TALLOC_FREE(smb_fname);
540 return NT_STATUS_INVALID_PARAMETER;
543 TALLOC_FREE(smb_fname);
545 return NT_STATUS_OK;
548 struct smbd_smb2_create_state {
549 struct tevent_context *ev;
550 struct smbd_smb2_request *smb2req;
551 struct GUID req_guid;
552 struct smb_request *smb1req;
553 bool open_was_deferred;
554 struct tevent_immediate *im;
555 struct timeval request_time;
556 struct file_id id;
557 struct deferred_open_record *open_rec;
558 files_struct *result;
559 bool replay_operation;
560 uint8_t in_oplock_level;
561 uint32_t in_create_disposition;
562 int requested_oplock_level;
563 int info;
564 char *fname;
565 struct ea_list *ea_list;
566 NTTIME max_access_time;
567 struct security_descriptor *sec_desc;
568 uint64_t allocation_size;
569 struct GUID _create_guid;
570 struct GUID *create_guid;
571 struct GUID _purge_create_guid;
572 struct GUID *purge_create_guid;
573 bool update_open;
574 bool durable_requested;
575 uint32_t durable_timeout_msec;
576 bool do_durable_reconnect;
577 uint64_t persistent_id;
578 struct smb2_lease lease;
579 struct smb2_lease *lease_ptr;
580 ssize_t lease_len;
581 bool need_replay_cache;
582 struct smbXsrv_open *op;
583 NTTIME twrp_time;
585 struct smb2_create_blob *dhnc;
586 struct smb2_create_blob *dh2c;
587 struct smb2_create_blob *dhnq;
588 struct smb2_create_blob *dh2q;
589 struct smb2_create_blob *rqls;
590 struct smb2_create_blob *exta;
591 struct smb2_create_blob *mxac;
592 struct smb2_create_blob *secd;
593 struct smb2_create_blob *alsi;
594 struct smb2_create_blob *twrp;
595 struct smb2_create_blob *qfid;
596 struct smb2_create_blob *posx;
597 struct smb2_create_blob *svhdx;
599 uint8_t out_oplock_level;
600 uint32_t out_create_action;
601 struct timespec out_creation_ts;
602 struct timespec out_last_access_ts;
603 struct timespec out_last_write_ts;
604 struct timespec out_change_ts;
605 uint64_t out_allocation_size;
606 uint64_t out_end_of_file;
607 uint32_t out_file_attributes;
608 uint64_t out_file_id_persistent;
609 uint64_t out_file_id_volatile;
610 struct smb2_create_blobs *out_context_blobs;
613 static void smbd_smb2_create_purge_replay_cache(struct tevent_req *req,
614 const char *caller_func);
616 static void smbd_smb2_create_cleanup(struct tevent_req *req,
617 enum tevent_req_state req_state)
619 smbd_smb2_create_purge_replay_cache(req, __func__);
622 static NTSTATUS smbd_smb2_create_fetch_create_ctx(
623 struct tevent_req *req,
624 struct smb2_create_blobs *in_context_blobs)
626 struct smbd_smb2_create_state *state = tevent_req_data(
627 req, struct smbd_smb2_create_state);
628 struct smbd_smb2_request *smb2req = state->smb2req;
629 struct smbXsrv_connection *xconn = smb2req->xconn;
631 state->dhnq = smb2_create_blob_find(in_context_blobs,
632 SMB2_CREATE_TAG_DHNQ);
633 state->dhnc = smb2_create_blob_find(in_context_blobs,
634 SMB2_CREATE_TAG_DHNC);
635 state->dh2q = smb2_create_blob_find(in_context_blobs,
636 SMB2_CREATE_TAG_DH2Q);
637 state->dh2c = smb2_create_blob_find(in_context_blobs,
638 SMB2_CREATE_TAG_DH2C);
639 if (xconn->smb2.server.capabilities & SMB2_CAP_LEASING) {
640 state->rqls = smb2_create_blob_find(in_context_blobs,
641 SMB2_CREATE_TAG_RQLS);
644 if (((state->dhnc != NULL) && (state->dh2c != NULL)) ||
645 ((state->dhnc != NULL) && (state->dh2q != NULL)) ||
646 ((state->dh2c != NULL) && (state->dhnq != NULL)) ||
647 ((state->dh2q != NULL) && (state->dh2c != NULL)))
649 /* not both are allowed at the same time */
650 return NT_STATUS_INVALID_PARAMETER;
653 if (state->dhnc != NULL) {
654 uint32_t num_blobs_allowed;
656 if (state->dhnc->data.length != 16) {
657 return NT_STATUS_INVALID_PARAMETER;
661 * According to MS-SMB2: 3.3.5.9.7, "Handling the
662 * SMB2_CREATE_DURABLE_HANDLE_RECONNECT Create Context",
663 * we should ignore an additional dhnq blob, but fail
664 * the request (with status OBJECT_NAME_NOT_FOUND) if
665 * any other extra create blob has been provided.
667 * (Note that the cases of an additional dh2q or dh2c blob
668 * which require a different error code, have been treated
669 * above.)
672 if (state->dhnq != NULL) {
673 num_blobs_allowed = 2;
674 } else {
675 num_blobs_allowed = 1;
678 if (state->rqls != NULL) {
679 num_blobs_allowed += 1;
682 if (in_context_blobs->num_blobs != num_blobs_allowed) {
683 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
687 if (state->dh2c!= NULL) {
688 uint32_t num_blobs_allowed;
690 if (state->dh2c->data.length != 36) {
691 return NT_STATUS_INVALID_PARAMETER;
695 * According to MS-SMB2: 3.3.5.9.12, "Handling the
696 * SMB2_CREATE_DURABLE_HANDLE_RECONNECT_V2 Create Context",
697 * we should fail the request with status
698 * OBJECT_NAME_NOT_FOUND if any other create blob has been
699 * provided.
701 * (Note that the cases of an additional dhnq, dhnc or dh2q
702 * blob which require a different error code, have been
703 * treated above.)
706 num_blobs_allowed = 1;
708 if (state->rqls != NULL) {
709 num_blobs_allowed += 1;
712 if (in_context_blobs->num_blobs != num_blobs_allowed) {
713 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
717 state->exta = smb2_create_blob_find(in_context_blobs,
718 SMB2_CREATE_TAG_EXTA);
719 state->mxac = smb2_create_blob_find(in_context_blobs,
720 SMB2_CREATE_TAG_MXAC);
721 state->secd = smb2_create_blob_find(in_context_blobs,
722 SMB2_CREATE_TAG_SECD);
723 state->alsi = smb2_create_blob_find(in_context_blobs,
724 SMB2_CREATE_TAG_ALSI);
725 state->twrp = smb2_create_blob_find(in_context_blobs,
726 SMB2_CREATE_TAG_TWRP);
727 state->qfid = smb2_create_blob_find(in_context_blobs,
728 SMB2_CREATE_TAG_QFID);
729 if (xconn->protocol >= PROTOCOL_SMB3_02) {
731 * This was introduced with SMB3_02
733 state->svhdx = smb2_create_blob_find(
734 in_context_blobs, SVHDX_OPEN_DEVICE_CONTEXT);
736 if (xconn->smb2.server.posix_extensions_negotiated) {
738 * Negprot only allowed this for proto>=3.11
740 SMB_ASSERT(xconn->protocol >= PROTOCOL_SMB3_11);
742 state->posx = smb2_create_blob_find(
743 in_context_blobs, SMB2_CREATE_TAG_POSIX);
746 return NT_STATUS_OK;
749 static void smbd_smb2_create_before_exec(struct tevent_req *req);
750 static void smbd_smb2_create_after_exec(struct tevent_req *req);
751 static void smbd_smb2_create_finish(struct tevent_req *req);
753 static struct tevent_req *smbd_smb2_create_send(TALLOC_CTX *mem_ctx,
754 struct tevent_context *ev,
755 struct smbd_smb2_request *smb2req,
756 uint8_t in_oplock_level,
757 uint32_t in_impersonation_level,
758 uint32_t in_desired_access,
759 uint32_t in_file_attributes,
760 uint32_t in_share_access,
761 uint32_t in_create_disposition,
762 uint32_t in_create_options,
763 const char *in_name,
764 struct smb2_create_blobs in_context_blobs)
766 struct tevent_req *req = NULL;
767 struct smbd_smb2_create_state *state = NULL;
768 NTSTATUS status;
769 struct smb_request *smb1req = NULL;
770 struct files_struct *dirfsp = NULL;
771 struct smb_filename *smb_fname = NULL;
772 uint32_t ucf_flags;
773 bool is_dfs = false;
775 req = tevent_req_create(mem_ctx, &state,
776 struct smbd_smb2_create_state);
777 if (req == NULL) {
778 return NULL;
780 *state = (struct smbd_smb2_create_state) {
781 .ev = ev,
782 .smb2req = smb2req,
783 .in_oplock_level = in_oplock_level,
784 .in_create_disposition = in_create_disposition,
787 smb1req = smbd_smb2_fake_smb_request(smb2req);
788 if (tevent_req_nomem(smb1req, req)) {
789 return tevent_req_post(req, state->ev);
791 state->smb1req = smb1req;
793 state->req_guid = smbd_request_guid(smb1req, 0);
795 tevent_req_set_cleanup_fn(req, smbd_smb2_create_cleanup);
797 if (smb2req->subreq == NULL) {
798 DBG_DEBUG("name [%s]\n", in_name);
799 } else {
800 struct smbd_smb2_create_state *old_state = tevent_req_data(
801 smb2req->subreq, struct smbd_smb2_create_state);
803 DBG_DEBUG("reentrant for file %s\n", in_name);
805 state->id = old_state->id;
806 state->request_time = old_state->request_time;
807 state->open_rec = talloc_move(state, &old_state->open_rec);
808 state->open_was_deferred = old_state->open_was_deferred;
809 state->_purge_create_guid = old_state->_purge_create_guid;
810 state->purge_create_guid = old_state->purge_create_guid;
811 old_state->purge_create_guid = NULL;
814 TALLOC_FREE(smb2req->subreq);
815 smb2req->subreq = req;
817 if (lp_fake_oplocks(SNUM(smb2req->tcon->compat))) {
818 state->requested_oplock_level = SMB2_OPLOCK_LEVEL_NONE;
819 } else {
820 state->requested_oplock_level = state->in_oplock_level;
823 /* these are ignored for SMB2 */
824 in_create_options &= ~(0x10);/* NTCREATEX_OPTIONS_SYNC_ALERT */
825 in_create_options &= ~(0x20);/* NTCREATEX_OPTIONS_ASYNC_ALERT */
827 in_file_attributes &= ~FILE_FLAG_POSIX_SEMANTICS;
829 is_dfs = (smb1req->flags2 & FLAGS2_DFS_PATHNAMES);
830 if (is_dfs) {
831 const char *non_dfs_in_name = NULL;
833 * With a DFS flag set, remove any DFS prefix
834 * before further processing.
836 status = smb2_strip_dfs_path(in_name, &non_dfs_in_name);
837 if (!NT_STATUS_IS_OK(status)) {
838 tevent_req_nterror(req, status);
839 return tevent_req_post(req, state->ev);
842 * TODO: Note for dealing with reparse point errors.
843 * We will need to remember and store the number of characters
844 * we have removed here, which is (non_dfs_in_name - in_name)
845 * in order to correctly report how many characters we
846 * have removed before hitting the reparse point.
847 * This will be a patch needed once we properly
848 * deal with reparse points later.
850 in_name = non_dfs_in_name;
852 * Now we're no longer dealing with a DFS path, so
853 * remove the flag.
855 smb1req->flags2 &= ~FLAGS2_DFS_PATHNAMES;
856 is_dfs = false;
859 state->fname = talloc_strdup(state, in_name);
860 if (tevent_req_nomem(state->fname, req)) {
861 return tevent_req_post(req, state->ev);
864 state->out_context_blobs = talloc_zero(state, struct smb2_create_blobs);
865 if (tevent_req_nomem(state->out_context_blobs, req)) {
866 return tevent_req_post(req, state->ev);
869 status = smbd_smb2_create_fetch_create_ctx(req, &in_context_blobs);
870 if (tevent_req_nterror(req, status)) {
871 return tevent_req_post(req, state->ev);
874 if (IS_IPC(smb1req->conn)) {
875 const char *pipe_name = in_name;
877 if (state->dhnc != NULL || state->dh2c != NULL) {
878 /* durable handles are not supported on IPC$ */
879 tevent_req_nterror(req, NT_STATUS_OBJECT_NAME_NOT_FOUND);
880 return tevent_req_post(req, state->ev);
883 if (!lp_nt_pipe_support()) {
884 tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
885 return tevent_req_post(req, state->ev);
888 status = open_np_file(smb1req, pipe_name, &state->result);
889 if (tevent_req_nterror(req, status)) {
890 return tevent_req_post(req, state->ev);
892 state->info = FILE_WAS_OPENED;
894 smbd_smb2_create_finish(req);
895 return req;
898 if (CAN_PRINT(smb1req->conn)) {
899 if (state->dhnc != NULL || state->dh2c != NULL) {
900 /* durable handles are not supported on printers */
901 tevent_req_nterror(req, NT_STATUS_OBJECT_NAME_NOT_FOUND);
902 return tevent_req_post(req, state->ev);
905 status = file_new(smb1req, smb1req->conn, &state->result);
906 if (tevent_req_nterror(req, status)) {
907 return tevent_req_post(req, state->ev);
910 status = print_spool_open(state->result, in_name,
911 smb1req->vuid);
912 if (tevent_req_nterror(req, status)) {
913 file_free(smb1req, state->result);
914 return tevent_req_post(req, state->ev);
916 state->info = FILE_WAS_CREATED;
918 smbd_smb2_create_finish(req);
919 return req;
922 /* Check for trailing slash specific directory handling. */
923 status = windows_name_trailing_check(state->fname, in_create_options);
924 if (tevent_req_nterror(req, status)) {
925 return tevent_req_post(req, state->ev);
928 smbd_smb2_create_before_exec(req);
929 if (!tevent_req_is_in_progress(req)) {
930 return tevent_req_post(req, state->ev);
933 DBG_DEBUG("open execution phase\n");
936 * For the backend file open procedure, there are
937 * three possible modes: replay operation (in which case
938 * there is nothing else to do), durable_reconnect or
939 * new open.
941 if (state->replay_operation) {
942 state->result = state->op->compat;
943 state->result->op = state->op;
944 state->update_open = false;
945 state->info = state->op->create_action;
947 smbd_smb2_create_after_exec(req);
948 if (!tevent_req_is_in_progress(req)) {
949 return req;
952 smbd_smb2_create_finish(req);
953 return req;
956 if (state->do_durable_reconnect) {
957 DATA_BLOB new_cookie = data_blob_null;
958 NTTIME now = timeval_to_nttime(&smb2req->request_time);
960 status = smb2srv_open_recreate(smb2req->xconn,
961 smb1req->conn->session_info,
962 state->persistent_id,
963 state->create_guid,
964 now,
965 &state->op);
966 if (tevent_req_nterror(req, status)) {
967 DBG_NOTICE("smb2srv_open_recreate failed: %s\n",
968 nt_errstr(status));
969 return tevent_req_post(req, state->ev);
972 DBG_DEBUG("%s to recreate durable handle\n",
973 state->op->global->durable ? "succeeded" : "failed");
975 if (!state->op->global->durable) {
976 talloc_free(state->op);
977 tevent_req_nterror(req,
978 NT_STATUS_OBJECT_NAME_NOT_FOUND);
979 return tevent_req_post(req, state->ev);
982 status = SMB_VFS_DURABLE_RECONNECT(smb1req->conn,
983 smb1req,
984 state->op, /* smbXsrv_open input */
985 state->op->global->backend_cookie,
986 state->op, /* TALLOC_CTX */
987 &state->result,
988 &new_cookie);
989 if (!NT_STATUS_IS_OK(status)) {
990 NTSTATUS return_status;
992 return_status = NT_STATUS_OBJECT_NAME_NOT_FOUND;
994 DBG_NOTICE("durable_reconnect failed: %s => %s\n",
995 nt_errstr(status),
996 nt_errstr(return_status));
998 tevent_req_nterror(req, return_status);
999 return tevent_req_post(req, state->ev);
1002 DBG_DEBUG("oplock_type=%u, lease_ptr==%p\n",
1003 (unsigned)state->result->oplock_type, state->lease_ptr);
1005 status = smbd_smb2_create_durable_lease_check(
1006 smb1req, state->fname, state->result, state->lease_ptr);
1007 if (tevent_req_nterror(req, status)) {
1008 close_file_free(
1009 smb1req, &state->result, SHUTDOWN_CLOSE);
1010 return tevent_req_post(req, state->ev);
1013 data_blob_free(&state->op->global->backend_cookie);
1014 state->op->global->backend_cookie = new_cookie;
1016 state->op->status = NT_STATUS_OK;
1017 state->op->global->disconnect_time = 0;
1019 /* save the timout for later update */
1020 state->durable_timeout_msec = state->op->global->durable_timeout_msec;
1022 state->update_open = true;
1024 state->info = FILE_WAS_OPENED;
1026 smbd_smb2_create_after_exec(req);
1027 if (!tevent_req_is_in_progress(req)) {
1028 return req;
1031 smbd_smb2_create_finish(req);
1032 return req;
1035 if (state->requested_oplock_level == SMB2_OPLOCK_LEVEL_LEASE) {
1036 if (state->lease_ptr == NULL) {
1037 state->requested_oplock_level = SMB2_OPLOCK_LEVEL_NONE;
1039 } else {
1040 state->lease_ptr = NULL;
1043 /* convert '\\' into '/' */
1044 status = check_path_syntax_smb2(state->fname);
1045 if (tevent_req_nterror(req, status)) {
1046 return tevent_req_post(req, state->ev);
1049 ucf_flags = filename_create_ucf_flags(
1050 smb1req, state->in_create_disposition);
1052 status = filename_convert_dirfsp(
1053 req,
1054 smb1req->conn,
1055 state->fname,
1056 ucf_flags,
1057 state->twrp_time,
1058 &dirfsp,
1059 &smb_fname);
1060 if (tevent_req_nterror(req, status)) {
1061 return tevent_req_post(req, state->ev);
1065 * MS-SMB2: 2.2.13 SMB2 CREATE Request
1066 * ImpersonationLevel ... MUST contain one of the
1067 * following values. The server MUST validate this
1068 * field, but otherwise ignore it.
1070 * NB. The source4/torture/smb2/durable_open.c test
1071 * shows this check is only done on real opens, not
1072 * on durable handle-reopens.
1075 if (in_impersonation_level >
1076 SMB2_IMPERSONATION_DELEGATE) {
1077 tevent_req_nterror(req,
1078 NT_STATUS_BAD_IMPERSONATION_LEVEL);
1079 return tevent_req_post(req, state->ev);
1083 * We know we're going to do a local open, so now
1084 * we must be protocol strict. JRA.
1086 * MS-SMB2: 3.3.5.9 - Receiving an SMB2 CREATE Request
1087 * If the file name length is greater than zero and the
1088 * first character is a path separator character, the
1089 * server MUST fail the request with
1090 * STATUS_INVALID_PARAMETER.
1092 if (in_name[0] == '\\' || in_name[0] == '/') {
1093 tevent_req_nterror(req,
1094 NT_STATUS_INVALID_PARAMETER);
1095 return tevent_req_post(req, state->ev);
1098 status = SMB_VFS_CREATE_FILE(smb1req->conn,
1099 smb1req,
1100 dirfsp,
1101 smb_fname,
1102 in_desired_access,
1103 in_share_access,
1104 state->in_create_disposition,
1105 in_create_options,
1106 in_file_attributes,
1107 map_smb2_oplock_levels_to_samba(
1108 state->requested_oplock_level),
1109 state->lease_ptr,
1110 state->allocation_size,
1111 0, /* private_flags */
1112 state->sec_desc,
1113 state->ea_list,
1114 &state->result,
1115 &state->info,
1116 &in_context_blobs,
1117 state->out_context_blobs);
1118 if (!NT_STATUS_IS_OK(status)) {
1119 if (open_was_deferred(smb1req->xconn, smb1req->mid)) {
1120 SMBPROFILE_IOBYTES_ASYNC_SET_IDLE(smb2req->profile);
1121 return req;
1123 tevent_req_nterror(req, status);
1124 return tevent_req_post(req, state->ev);
1126 state->op = state->result->op;
1128 smbd_smb2_create_after_exec(req);
1129 if (!tevent_req_is_in_progress(req)) {
1130 return req;
1133 smbd_smb2_create_finish(req);
1134 return req;
1137 static void smbd_smb2_create_purge_replay_cache(struct tevent_req *req,
1138 const char *caller_func)
1140 struct smbd_smb2_create_state *state = tevent_req_data(
1141 req, struct smbd_smb2_create_state);
1142 NTSTATUS status;
1144 if (state->purge_create_guid == NULL) {
1145 return;
1148 status = smbXsrv_open_purge_replay_cache(state->smb2req->xconn->client,
1149 state->purge_create_guid);
1150 if (!NT_STATUS_IS_OK(status)) {
1151 struct GUID_txt_buf buf;
1153 D_ERR("%s: smbXsrv_open_purge_replay_cache(%s) %s\n",
1154 caller_func,
1155 GUID_buf_string(state->purge_create_guid, &buf),
1156 nt_errstr(status));
1159 state->purge_create_guid = NULL;
1162 static void smbd_smb2_create_before_exec(struct tevent_req *req)
1164 struct smbd_smb2_create_state *state = tevent_req_data(
1165 req, struct smbd_smb2_create_state);
1166 struct smbd_smb2_request *smb2req = state->smb2req;
1167 NTSTATUS status;
1169 if (state->exta != NULL) {
1170 if (!lp_ea_support(SNUM(smb2req->tcon->compat))) {
1171 tevent_req_nterror(req, NT_STATUS_EAS_NOT_SUPPORTED);
1172 return;
1175 state->ea_list = read_nttrans_ea_list(
1176 state,
1177 (const char *)state->exta->data.data,
1178 state->exta->data.length);
1179 if (state->ea_list == NULL) {
1180 DEBUG(10,("smbd_smb2_create_send: read_ea_name_list failed.\n"));
1181 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
1182 return;
1186 * NB. When SMB2+ unix extensions are added,
1187 * we need to relax this check in invalid
1188 * names - we used to not do this if
1189 * lp_posix_pathnames() was false.
1191 if (ea_list_has_invalid_name(state->ea_list)) {
1192 tevent_req_nterror(req, STATUS_INVALID_EA_NAME);
1193 return;
1197 if (state->mxac != NULL) {
1198 if (state->mxac->data.length == 0) {
1199 state->max_access_time = 0;
1200 } else if (state->mxac->data.length == 8) {
1201 state->max_access_time = BVAL(state->mxac->data.data, 0);
1202 } else {
1203 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
1204 return;
1208 if (state->secd != NULL) {
1209 enum ndr_err_code ndr_err;
1211 state->sec_desc = talloc_zero(state, struct security_descriptor);
1212 if (tevent_req_nomem(state->sec_desc, req)) {
1213 return;
1216 ndr_err = ndr_pull_struct_blob(&state->secd->data,
1217 state->sec_desc, state->sec_desc,
1218 (ndr_pull_flags_fn_t)ndr_pull_security_descriptor);
1219 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1220 DEBUG(2,("ndr_pull_security_descriptor failed: %s\n",
1221 ndr_errstr(ndr_err)));
1222 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
1223 return;
1227 if (state->dhnq != NULL) {
1228 if (state->dhnq->data.length != 16) {
1229 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
1230 return;
1233 if (state->dh2q != NULL) {
1234 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
1235 return;
1239 * durable handle request is processed below.
1241 state->durable_requested = true;
1243 * Set the timeout to 16 mins.
1245 * TODO: test this against Windows 2012
1246 * as the default for durable v2 is 1 min.
1248 state->durable_timeout_msec = (16*60*1000);
1251 if (state->dh2q != NULL) {
1252 const uint8_t *p = state->dh2q->data.data;
1253 NTTIME now = timeval_to_nttime(&smb2req->request_time);
1254 uint32_t durable_v2_timeout = 0;
1255 DATA_BLOB create_guid_blob;
1256 const uint8_t *hdr;
1257 uint32_t flags;
1259 if (state->dh2q->data.length != 32) {
1260 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
1261 return;
1264 if (state->dhnq != NULL) {
1265 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
1266 return;
1269 durable_v2_timeout = IVAL(p, 0);
1270 create_guid_blob = data_blob_const(p + 16, 16);
1272 status = GUID_from_ndr_blob(&create_guid_blob,
1273 &state->_create_guid);
1274 if (tevent_req_nterror(req, status)) {
1275 return;
1277 state->create_guid = &state->_create_guid;
1280 * we need to store the create_guid later
1282 state->update_open = true;
1285 * And we need to create a cache for replaying the
1286 * create.
1288 state->need_replay_cache = true;
1291 * durable handle v2 request processed below
1293 state->durable_requested = true;
1294 state->durable_timeout_msec = MIN(durable_v2_timeout, 300*1000);
1295 if (state->durable_timeout_msec == 0) {
1297 * Set the timeout to 1 min as default.
1299 * This matches Windows 2012.
1301 state->durable_timeout_msec = (60*1000);
1305 * Check for replay operation.
1306 * Only consider it when we have dh2q.
1307 * If we do not have a replay operation, verify that
1308 * the create_guid is not cached for replay.
1310 hdr = SMBD_SMB2_IN_HDR_PTR(smb2req);
1311 flags = IVAL(hdr, SMB2_HDR_FLAGS);
1312 state->replay_operation =
1313 flags & SMB2_HDR_FLAG_REPLAY_OPERATION;
1315 status = smb2srv_open_lookup_replay_cache(smb2req->xconn,
1316 state->req_guid,
1317 *state->create_guid,
1318 state->fname,
1319 now,
1320 &state->op);
1321 if (NT_STATUS_EQUAL(status, NT_STATUS_FWP_RESERVED)) {
1323 * We've reserved the replay_cache record
1324 * for ourself, indicating we're still
1325 * in progress.
1327 * It means the smbd_smb2_create_cleanup()
1328 * may need to call smbXsrv_open_purge_replay_cache()
1329 * in order to cleanup.
1331 SMB_ASSERT(state->op == NULL);
1332 state->_purge_create_guid = state->_create_guid;
1333 state->purge_create_guid = &state->_purge_create_guid;
1334 status = NT_STATUS_OK;
1335 state->replay_operation = false;
1336 } else if (NT_STATUS_EQUAL(status, NT_STATUS_FILE_NOT_AVAILABLE)) {
1337 tevent_req_nterror(req, status);
1338 return;
1339 } else if (tevent_req_nterror(req, status)) {
1340 DBG_WARNING("smb2srv_open_lookup_replay_cache "
1341 "failed: %s\n", nt_errstr(status));
1342 return;
1343 } else if (!state->replay_operation) {
1345 * If a create without replay operation flag
1346 * is sent but with a create_guid that is
1347 * currently in the replay cache -- fail.
1349 status = NT_STATUS_DUPLICATE_OBJECTID;
1350 (void)tevent_req_nterror(req, status);
1351 return;
1355 if (state->dhnc != NULL) {
1356 state->persistent_id = BVAL(state->dhnc->data.data, 0);
1357 state->do_durable_reconnect = true;
1360 if (state->dh2c != NULL) {
1361 const uint8_t *p = state->dh2c->data.data;
1362 DATA_BLOB create_guid_blob;
1364 state->persistent_id = BVAL(p, 0);
1365 create_guid_blob = data_blob_const(p + 16, 16);
1367 status = GUID_from_ndr_blob(&create_guid_blob,
1368 &state->_create_guid);
1369 if (tevent_req_nterror(req, status)) {
1370 return;
1373 state->create_guid = &state->_create_guid;
1374 state->do_durable_reconnect = true;
1377 if (state->alsi != NULL) {
1378 if (state->alsi->data.length != 8) {
1379 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
1380 return;
1382 state->allocation_size = BVAL(state->alsi->data.data, 0);
1385 if (state->twrp != NULL) {
1386 if (state->twrp->data.length != 8) {
1387 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
1388 return;
1391 state->twrp_time = BVAL(state->twrp->data.data, 0);
1394 if (state->qfid != NULL) {
1395 if (state->qfid->data.length != 0) {
1396 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
1397 return;
1401 if (state->rqls != NULL) {
1402 ssize_t lease_len = -1;
1404 lease_len = smb2_lease_pull(state->rqls->data.data,
1405 state->rqls->data.length,
1406 &state->lease);
1407 if (lease_len == -1) {
1408 tevent_req_nterror(
1409 req, NT_STATUS_INVALID_PARAMETER);
1410 return;
1412 state->lease_ptr = &state->lease;
1414 if (DEBUGLEVEL >= 10) {
1415 DEBUG(10, ("Got lease request size %d\n",
1416 (int)lease_len));
1417 NDR_PRINT_DEBUG(smb2_lease, state->lease_ptr);
1420 if (!smb2_lease_key_valid(&state->lease.lease_key)) {
1421 state->lease_ptr = NULL;
1422 state->requested_oplock_level = SMB2_OPLOCK_LEVEL_NONE;
1425 if ((smb2req->xconn->protocol < PROTOCOL_SMB3_00) &&
1426 (state->lease.lease_version != 1))
1428 DEBUG(10, ("v2 lease key only for SMB3\n"));
1429 state->lease_ptr = NULL;
1433 * Replay with a lease is only allowed if the
1434 * established open carries a lease with the
1435 * same lease key.
1437 if (state->replay_operation) {
1438 struct smb2_lease *op_ls =
1439 &state->op->compat->lease->lease;
1440 int op_oplock = state->op->compat->oplock_type;
1442 if (map_samba_oplock_levels_to_smb2(op_oplock)
1443 != SMB2_OPLOCK_LEVEL_LEASE)
1445 status = NT_STATUS_ACCESS_DENIED;
1446 (void)tevent_req_nterror(req, status);
1447 return;
1449 if (!smb2_lease_key_equal(&state->lease.lease_key,
1450 &op_ls->lease_key))
1452 status = NT_STATUS_ACCESS_DENIED;
1453 (void)tevent_req_nterror(req, status);
1454 return;
1459 if (state->posx != NULL) {
1460 if (state->posx->data.length != 4) {
1461 DBG_DEBUG("Got %zu bytes POSX cctx, expected 4\n",
1462 state->posx->data.length);
1463 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
1464 return;
1469 static void smbd_smb2_create_after_exec(struct tevent_req *req)
1471 struct smbd_smb2_create_state *state = tevent_req_data(
1472 req, struct smbd_smb2_create_state);
1473 connection_struct *conn = state->result->conn;
1474 NTSTATUS status;
1477 * here we have op == result->op
1480 DEBUG(10, ("smbd_smb2_create_send: "
1481 "response construction phase\n"));
1483 state->out_file_attributes = fdos_mode(state->result);
1485 if (state->mxac != NULL) {
1486 NTTIME last_write_time;
1488 last_write_time = full_timespec_to_nt_time(
1489 &state->result->fsp_name->st.st_ex_mtime);
1490 if (last_write_time != state->max_access_time) {
1491 uint8_t p[8];
1492 uint32_t max_access_granted;
1493 DATA_BLOB blob = data_blob_const(p, sizeof(p));
1495 status = smbd_calculate_access_mask_fsp(
1496 conn->cwd_fsp,
1497 state->result,
1498 false,
1499 SEC_FLAG_MAXIMUM_ALLOWED,
1500 &max_access_granted);
1502 SIVAL(p, 0, NT_STATUS_V(status));
1503 SIVAL(p, 4, max_access_granted);
1505 status = smb2_create_blob_add(
1506 state->out_context_blobs,
1507 state->out_context_blobs,
1508 SMB2_CREATE_TAG_MXAC,
1509 blob);
1510 if (!NT_STATUS_IS_OK(status)) {
1511 goto fail;
1516 if (!state->replay_operation && state->durable_requested &&
1517 (fsp_lease_type(state->result) & SMB2_LEASE_HANDLE))
1519 status = SMB_VFS_DURABLE_COOKIE(
1520 state->result,
1521 state->op,
1522 &state->op->global->backend_cookie);
1523 if (!NT_STATUS_IS_OK(status)) {
1524 state->op->global->backend_cookie = data_blob_null;
1527 if (!state->replay_operation && state->op->global->backend_cookie.length > 0)
1529 state->update_open = true;
1531 state->op->global->durable = true;
1532 state->op->global->durable_timeout_msec = state->durable_timeout_msec;
1535 if (state->update_open) {
1536 state->op->global->create_guid = state->_create_guid;
1537 if (state->need_replay_cache) {
1538 state->op->flags |= SMBXSRV_OPEN_NEED_REPLAY_CACHE;
1541 status = smbXsrv_open_update(state->op);
1542 DEBUG(10, ("smb2_create_send: smbXsrv_open_update "
1543 "returned %s\n",
1544 nt_errstr(status)));
1545 if (!NT_STATUS_IS_OK(status)) {
1546 goto fail;
1550 * We should not purge the replay cache anymore
1551 * as it's attached to the smbXsrv_open record now.
1553 state->purge_create_guid = NULL;
1556 if (state->dhnq != NULL && state->op->global->durable) {
1557 uint8_t p[8] = { 0, };
1558 DATA_BLOB blob = data_blob_const(p, sizeof(p));
1560 status = smb2_create_blob_add(state->out_context_blobs,
1561 state->out_context_blobs,
1562 SMB2_CREATE_TAG_DHNQ,
1563 blob);
1564 if (!NT_STATUS_IS_OK(status)) {
1565 goto fail;
1569 if (state->dh2q != NULL && state->op->global->durable &&
1571 * For replay operations, we return the dh2q blob
1572 * in the case of oplocks not based on the state of
1573 * the open, but on whether it could have been granted
1574 * for the request data. In the case of leases instead,
1575 * the state of the open is used...
1577 (!state->replay_operation ||
1578 state->in_oplock_level == SMB2_OPLOCK_LEVEL_BATCH ||
1579 state->in_oplock_level == SMB2_OPLOCK_LEVEL_LEASE))
1581 uint8_t p[8] = { 0, };
1582 DATA_BLOB blob = data_blob_const(p, sizeof(p));
1583 uint32_t durable_v2_response_flags = 0;
1585 SIVAL(p, 0, state->op->global->durable_timeout_msec);
1586 SIVAL(p, 4, durable_v2_response_flags);
1588 status = smb2_create_blob_add(state->out_context_blobs,
1589 state->out_context_blobs,
1590 SMB2_CREATE_TAG_DH2Q,
1591 blob);
1592 if (!NT_STATUS_IS_OK(status)) {
1593 goto fail;
1597 if (state->qfid != NULL) {
1598 uint8_t p[32];
1599 SMB_STRUCT_STAT *base_sp = state->result->base_fsp ?
1600 &state->result->base_fsp->fsp_name->st :
1601 &state->result->fsp_name->st;
1602 uint64_t file_id = SMB_VFS_FS_FILE_ID(conn, base_sp);
1603 DATA_BLOB blob = data_blob_const(p, sizeof(p));
1605 ZERO_STRUCT(p);
1607 /* From conversations with Microsoft engineers at
1608 the MS plugfest. The first 8 bytes are the "volume index"
1609 == inode, the second 8 bytes are the "volume id",
1610 == dev. This will be updated in the SMB2 doc. */
1611 SBVAL(p, 0, file_id);
1612 SIVAL(p, 8, base_sp->st_ex_dev);/* FileIndexHigh */
1614 status = smb2_create_blob_add(state->out_context_blobs,
1615 state->out_context_blobs,
1616 SMB2_CREATE_TAG_QFID,
1617 blob);
1618 if (!NT_STATUS_IS_OK(status)) {
1619 goto fail;
1623 if ((state->rqls != NULL) && (state->result->oplock_type == LEASE_OPLOCK)) {
1624 uint8_t buf[52];
1625 struct smb2_lease lease;
1626 size_t lease_len;
1628 lease = state->result->lease->lease;
1630 lease_len = sizeof(buf);
1631 if (lease.lease_version == 1) {
1632 lease_len = 32;
1635 if (!smb2_lease_push(&lease, buf, lease_len)) {
1636 status = NT_STATUS_INTERNAL_ERROR;
1637 goto fail;
1640 status = smb2_create_blob_add(
1641 state, state->out_context_blobs,
1642 SMB2_CREATE_TAG_RQLS,
1643 data_blob_const(buf, lease_len));
1644 if (!NT_STATUS_IS_OK(status)) {
1645 goto fail;
1649 if (state->posx != NULL) {
1650 struct dom_sid owner = { .sid_rev_num = 0, };
1651 struct dom_sid group = { .sid_rev_num = 0, };
1652 struct stat_ex *psbuf = &state->result->fsp_name->st;
1653 ssize_t cc_len;
1655 uid_to_sid(&owner, psbuf->st_ex_uid);
1656 gid_to_sid(&group, psbuf->st_ex_gid);
1658 cc_len = smb2_posix_cc_info(
1659 conn, 0, psbuf, &owner, &group, NULL, 0);
1661 if (cc_len == -1) {
1662 status = NT_STATUS_INSUFFICIENT_RESOURCES;
1663 goto fail;
1668 * cc_len is 68 + 2 SIDs, allocate on the stack
1670 uint8_t buf[cc_len];
1671 DATA_BLOB blob = { .data = buf, .length = cc_len, };
1673 smb2_posix_cc_info(
1674 conn,
1676 psbuf,
1677 &owner,
1678 &group,
1679 buf,
1680 sizeof(buf));
1682 status = smb2_create_blob_add(
1683 state->out_context_blobs,
1684 state->out_context_blobs,
1685 SMB2_CREATE_TAG_POSIX,
1686 blob);
1687 if (!NT_STATUS_IS_OK(status)) {
1688 goto fail;
1693 return;
1695 fail:
1696 close_file_free(state->smb1req, &state->result, ERROR_CLOSE);
1697 tevent_req_nterror(req, status);
1698 tevent_req_post(req, state->ev);
1701 static void smbd_smb2_create_finish(struct tevent_req *req)
1703 struct smbd_smb2_create_state *state = tevent_req_data(
1704 req, struct smbd_smb2_create_state);
1705 struct smbd_smb2_request *smb2req = state->smb2req;
1706 struct smb_request *smb1req = state->smb1req;
1707 files_struct *result = state->result;
1709 smb2req->compat_chain_fsp = smb1req->chain_fsp;
1711 if (state->replay_operation) {
1712 state->out_oplock_level = state->in_oplock_level;
1713 } else if (lp_fake_oplocks(SNUM(smb2req->tcon->compat))) {
1714 state->out_oplock_level = state->in_oplock_level;
1715 } else {
1716 state->out_oplock_level = map_samba_oplock_levels_to_smb2(result->oplock_type);
1719 if ((state->in_create_disposition == FILE_SUPERSEDE)
1720 && (state->info == FILE_WAS_OVERWRITTEN)) {
1721 state->out_create_action = FILE_WAS_SUPERSEDED;
1722 } else {
1723 state->out_create_action = state->info;
1725 result->op->create_action = state->out_create_action;
1727 state->out_creation_ts = get_create_timespec(smb1req->conn,
1728 result, result->fsp_name);
1729 state->out_last_access_ts = result->fsp_name->st.st_ex_atime;
1730 state->out_last_write_ts = result->fsp_name->st.st_ex_mtime;
1731 state->out_change_ts = get_change_timespec(smb1req->conn,
1732 result, result->fsp_name);
1734 if (lp_dos_filetime_resolution(SNUM(smb2req->tcon->compat))) {
1735 dos_filetime_timespec(&state->out_creation_ts);
1736 dos_filetime_timespec(&state->out_last_access_ts);
1737 dos_filetime_timespec(&state->out_last_write_ts);
1738 dos_filetime_timespec(&state->out_change_ts);
1741 state->out_allocation_size =
1742 SMB_VFS_GET_ALLOC_SIZE(smb1req->conn, result,
1743 &(result->fsp_name->st));
1744 state->out_end_of_file = result->fsp_name->st.st_ex_size;
1745 if (state->out_file_attributes == 0) {
1746 state->out_file_attributes = FILE_ATTRIBUTE_NORMAL;
1748 state->out_file_id_persistent = result->op->global->open_persistent_id;
1749 state->out_file_id_volatile = result->op->global->open_volatile_id;
1751 DBG_DEBUG("%s - %s\n", fsp_str_dbg(result), fsp_fnum_dbg(result));
1753 tevent_req_done(req);
1754 tevent_req_post(req, state->ev);
1757 static NTSTATUS smbd_smb2_create_recv(struct tevent_req *req,
1758 TALLOC_CTX *mem_ctx,
1759 uint8_t *out_oplock_level,
1760 uint32_t *out_create_action,
1761 struct timespec *out_creation_ts,
1762 struct timespec *out_last_access_ts,
1763 struct timespec *out_last_write_ts,
1764 struct timespec *out_change_ts,
1765 uint64_t *out_allocation_size,
1766 uint64_t *out_end_of_file,
1767 uint32_t *out_file_attributes,
1768 uint64_t *out_file_id_persistent,
1769 uint64_t *out_file_id_volatile,
1770 struct smb2_create_blobs *out_context_blobs)
1772 NTSTATUS status;
1773 struct smbd_smb2_create_state *state = tevent_req_data(req,
1774 struct smbd_smb2_create_state);
1776 if (tevent_req_is_nterror(req, &status)) {
1777 tevent_req_received(req);
1778 return status;
1781 *out_oplock_level = state->out_oplock_level;
1782 *out_create_action = state->out_create_action;
1783 *out_creation_ts = state->out_creation_ts;
1784 *out_last_access_ts = state->out_last_access_ts;
1785 *out_last_write_ts = state->out_last_write_ts;
1786 *out_change_ts = state->out_change_ts;
1787 *out_allocation_size = state->out_allocation_size;
1788 *out_end_of_file = state->out_end_of_file;
1789 *out_file_attributes = state->out_file_attributes;
1790 *out_file_id_persistent = state->out_file_id_persistent;
1791 *out_file_id_volatile = state->out_file_id_volatile;
1792 *out_context_blobs = *(state->out_context_blobs);
1794 talloc_steal(mem_ctx, state->out_context_blobs->blobs);
1796 tevent_req_received(req);
1797 return NT_STATUS_OK;
1800 /*********************************************************
1801 Code for dealing with deferred opens.
1802 *********************************************************/
1804 bool get_deferred_open_message_state_smb2(struct smbd_smb2_request *smb2req,
1805 struct timeval *p_request_time,
1806 struct deferred_open_record **open_rec)
1808 struct smbd_smb2_create_state *state = NULL;
1809 struct tevent_req *req = NULL;
1811 if (!smb2req) {
1812 return false;
1814 req = smb2req->subreq;
1815 if (!req) {
1816 return false;
1818 state = tevent_req_data(req, struct smbd_smb2_create_state);
1819 if (!state) {
1820 return false;
1822 if (!state->open_was_deferred) {
1823 return false;
1825 if (p_request_time) {
1826 *p_request_time = state->request_time;
1828 if (open_rec != NULL) {
1829 *open_rec = state->open_rec;
1831 return true;
1834 /*********************************************************
1835 Re-process this call early - requested by message or
1836 close.
1837 *********************************************************/
1839 static struct smbd_smb2_request *find_open_smb2req(
1840 struct smbXsrv_connection *xconn, uint64_t mid)
1842 struct smbd_smb2_request *smb2req;
1844 for (smb2req = xconn->smb2.requests; smb2req; smb2req = smb2req->next) {
1845 uint64_t message_id;
1846 if (smb2req->subreq == NULL) {
1847 /* This message has been processed. */
1848 continue;
1850 if (!tevent_req_is_in_progress(smb2req->subreq)) {
1851 /* This message has been processed. */
1852 continue;
1854 message_id = get_mid_from_smb2req(smb2req);
1855 if (message_id == mid) {
1856 return smb2req;
1859 return NULL;
1862 bool open_was_deferred_smb2(struct smbXsrv_connection *xconn, uint64_t mid)
1864 struct smbd_smb2_create_state *state = NULL;
1865 struct smbd_smb2_request *smb2req;
1867 smb2req = find_open_smb2req(xconn, mid);
1869 if (!smb2req) {
1870 DEBUG(10,("open_was_deferred_smb2: mid %llu smb2req == NULL\n",
1871 (unsigned long long)mid));
1872 return false;
1874 if (!smb2req->subreq) {
1875 return false;
1877 if (!tevent_req_is_in_progress(smb2req->subreq)) {
1878 return false;
1880 state = tevent_req_data(smb2req->subreq,
1881 struct smbd_smb2_create_state);
1882 if (!state) {
1883 return false;
1885 /* It's not in progress if there's no timeout event. */
1886 if (!state->open_was_deferred) {
1887 return false;
1890 DEBUG(10,("open_was_deferred_smb2: mid = %llu\n",
1891 (unsigned long long)mid));
1893 return true;
1896 static void remove_deferred_open_message_smb2_internal(struct smbd_smb2_request *smb2req,
1897 uint64_t mid)
1899 struct smbd_smb2_create_state *state = NULL;
1901 if (!smb2req->subreq) {
1902 return;
1904 if (!tevent_req_is_in_progress(smb2req->subreq)) {
1905 return;
1907 state = tevent_req_data(smb2req->subreq,
1908 struct smbd_smb2_create_state);
1909 if (!state) {
1910 return;
1913 DEBUG(10,("remove_deferred_open_message_smb2_internal: "
1914 "mid %llu\n",
1915 (unsigned long long)mid ));
1917 state->open_was_deferred = false;
1918 /* Ensure we don't have any outstanding immediate event. */
1919 TALLOC_FREE(state->im);
1920 TALLOC_FREE(state->open_rec);
1923 void remove_deferred_open_message_smb2(
1924 struct smbXsrv_connection *xconn, uint64_t mid)
1926 struct smbd_smb2_request *smb2req;
1928 smb2req = find_open_smb2req(xconn, mid);
1930 if (!smb2req) {
1931 DEBUG(10,("remove_deferred_open_message_smb2: "
1932 "can't find mid %llu\n",
1933 (unsigned long long)mid ));
1934 return;
1936 remove_deferred_open_message_smb2_internal(smb2req, mid);
1939 static void smbd_smb2_create_request_dispatch_immediate(struct tevent_context *ctx,
1940 struct tevent_immediate *im,
1941 void *private_data)
1943 struct smbd_smb2_request *smb2req = talloc_get_type_abort(private_data,
1944 struct smbd_smb2_request);
1945 uint64_t mid = get_mid_from_smb2req(smb2req);
1946 NTSTATUS status;
1948 DEBUG(10,("smbd_smb2_create_request_dispatch_immediate: "
1949 "re-dispatching mid %llu\n",
1950 (unsigned long long)mid ));
1952 status = smbd_smb2_request_dispatch(smb2req);
1953 if (!NT_STATUS_IS_OK(status)) {
1954 smbd_server_connection_terminate(smb2req->xconn,
1955 nt_errstr(status));
1956 return;
1960 bool schedule_deferred_open_message_smb2(
1961 struct smbXsrv_connection *xconn, uint64_t mid)
1963 struct smbd_smb2_create_state *state = NULL;
1964 struct smbd_smb2_request *smb2req;
1966 smb2req = find_open_smb2req(xconn, mid);
1968 if (!smb2req) {
1969 DEBUG(10,("schedule_deferred_open_message_smb2: "
1970 "can't find mid %llu\n",
1971 (unsigned long long)mid ));
1972 return false;
1974 if (!smb2req->subreq) {
1975 return false;
1977 if (!tevent_req_is_in_progress(smb2req->subreq)) {
1978 return false;
1980 state = tevent_req_data(smb2req->subreq,
1981 struct smbd_smb2_create_state);
1982 if (!state) {
1983 return false;
1986 /* Ensure we don't have any outstanding immediate event. */
1987 TALLOC_FREE(state->im);
1990 * This is subtle. We must null out the callback
1991 * before rescheduling, else the first call to
1992 * tevent_req_nterror() causes the _receive()
1993 * function to be called, this causing tevent_req_post()
1994 * to crash.
1996 tevent_req_set_callback(smb2req->subreq, NULL, NULL);
1998 state->im = tevent_create_immediate(smb2req);
1999 if (!state->im) {
2000 smbd_server_connection_terminate(smb2req->xconn,
2001 nt_errstr(NT_STATUS_NO_MEMORY));
2002 return false;
2005 DEBUG(10,("schedule_deferred_open_message_smb2: "
2006 "re-processing mid %llu\n",
2007 (unsigned long long)mid ));
2009 tevent_schedule_immediate(state->im,
2010 smb2req->sconn->ev_ctx,
2011 smbd_smb2_create_request_dispatch_immediate,
2012 smb2req);
2014 return true;
2017 static bool smbd_smb2_create_cancel(struct tevent_req *req)
2019 struct smbd_smb2_request *smb2req = NULL;
2020 struct smbd_smb2_create_state *state = tevent_req_data(req,
2021 struct smbd_smb2_create_state);
2022 uint64_t mid;
2024 if (!state) {
2025 return false;
2028 if (!state->smb2req) {
2029 return false;
2032 smb2req = state->smb2req;
2033 mid = get_mid_from_smb2req(smb2req);
2035 if (is_deferred_open_async(state->open_rec)) {
2036 /* Can't cancel an async create. */
2037 return false;
2040 remove_deferred_open_message_smb2_internal(smb2req, mid);
2042 tevent_req_defer_callback(req, smb2req->sconn->ev_ctx);
2043 tevent_req_nterror(req, NT_STATUS_CANCELLED);
2044 return true;
2047 bool push_deferred_open_message_smb2(struct smbd_smb2_request *smb2req,
2048 struct timeval request_time,
2049 struct timeval timeout,
2050 struct file_id id,
2051 struct deferred_open_record *open_rec)
2053 struct tevent_req *req = NULL;
2054 struct smbd_smb2_create_state *state = NULL;
2055 struct timeval end_time;
2057 if (!smb2req) {
2058 return false;
2060 req = smb2req->subreq;
2061 if (!req) {
2062 return false;
2064 state = tevent_req_data(req, struct smbd_smb2_create_state);
2065 if (!state) {
2066 return false;
2068 state->id = id;
2069 state->request_time = request_time;
2070 state->open_rec = talloc_move(state, &open_rec);
2072 /* Re-schedule us to retry on timer expiry. */
2073 end_time = timeval_sum(&request_time, &timeout);
2075 DEBUG(10,("push_deferred_open_message_smb2: "
2076 "timeout at %s\n",
2077 timeval_string(talloc_tos(),
2078 &end_time,
2079 true) ));
2081 state->open_was_deferred = true;
2083 /* allow this request to be canceled */
2084 tevent_req_set_cancel_fn(req, smbd_smb2_create_cancel);
2086 return true;