2 Unix SMB/CIFS implementation.
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/>.
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"
32 #include "lib/util_ea.h"
33 #include "source3/passdb/lookup_sid.h"
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:
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:
49 case SMB2_OPLOCK_LEVEL_LEASE:
52 DEBUG(2,("map_smb2_oplock_levels_to_samba: "
54 (unsigned int)in_oplock_level));
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;
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);
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;
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,
123 struct smb2_create_blobs in_context_blobs);
124 static NTSTATUS smbd_smb2_create_recv(struct tevent_req *req,
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;
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
195 dyn_offset = SMB2_HDR_BODY + SMBD_SMB2_IN_BODY_LEN(smb2req);
197 if (in_name_offset == 0 && in_name_length == 0) {
200 } else if (in_name_offset < dyn_offset) {
201 return smbd_smb2_request_error(smb2req, NT_STATUS_INVALID_PARAMETER);
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) {
224 } else if (in_context_offset < dyn_offset) {
225 return smbd_smb2_request_error(smb2req, NT_STATUS_INVALID_PARAMETER);
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 +
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,
250 in_name_buffer.length,
252 &in_name_string_size);
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(
274 "\nGot %"PRIu32" create blobs\n",
275 in_context_blobs.num_blobs);
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);
283 (uint8_t *)b->tag, strlen(b->tag), &str);
285 b->data.data, b->data.length, &str);
287 DBG_DEBUG("%s", str);
291 tsubreq = smbd_smb2_create_send(smb2req,
292 smb2req->sconn->ev_ctx,
295 in_impersonation_level,
299 in_create_disposition,
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);
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;
340 NTSTATUS error; /* transport error */
342 status = smbd_smb2_create_recv(tsubreq,
350 &out_allocation_size,
352 &out_file_attributes,
353 &out_file_id_persistent,
354 &out_file_id_volatile,
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,
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,
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,
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,
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;
452 NTTIME twrp = fsp->fsp_name->twrp;
454 bool is_dfs = (smb1req->flags2 & FLAGS2_DFS_PATHNAMES);
455 bool is_posix = (fsp->fsp_name->flags & SMB_FILENAME_POSIX_PATH);
457 if (lease_ptr == NULL) {
458 if (fsp->oplock_type != LEASE_OPLOCK) {
461 DEBUG(10, ("Reopened file has lease, but no lease "
463 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
466 if (fsp->oplock_type != LEASE_OPLOCK) {
467 DEBUG(10, ("Lease requested, but reopened file has no "
469 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
472 if (!smb2_lease_key_equal(&lease_ptr->lease_key,
473 &fsp->lease->lease.lease_key)) {
474 DEBUG(10, ("Different lease key requested than found "
475 "in reopened file\n"));
476 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
480 const char *non_dfs_requested_filename = NULL;
482 * With a DFS flag set, remove any DFS prefix
483 * before further processing.
485 status = smb2_strip_dfs_path(requested_filename,
486 &non_dfs_requested_filename);
487 if (!NT_STATUS_IS_OK(status)) {
491 * TODO: Note for dealing with reparse point errors.
492 * We will need to remember and store the number of characters
493 * we have removed here, which is
494 * (requested_filename - non_dfs_requested_filename)
495 * in order to correctly report how many characters we
496 * have removed before hitting the reparse point.
497 * This will be a patch needed once we properly
498 * deal with reparse points later.
500 requested_filename = non_dfs_requested_filename;
502 * Now we're no longer dealing with a DFS path, so
505 smb1req->flags2 &= ~FLAGS2_DFS_PATHNAMES;
509 filename = talloc_strdup(talloc_tos(), requested_filename);
510 if (filename == NULL) {
511 return NT_STATUS_NO_MEMORY;
514 /* This also converts '\' to '/' */
515 status = check_path_syntax(filename, is_posix);
516 if (!NT_STATUS_IS_OK(status)) {
517 TALLOC_FREE(filename);
521 ucf_flags = filename_create_ucf_flags(smb1req, FILE_OPEN);
522 status = filename_convert_dirfsp(talloc_tos(),
529 TALLOC_FREE(filename);
530 if (!NT_STATUS_IS_OK(status)) {
531 DEBUG(10, ("filename_convert returned %s\n",
536 if (!strequal(fsp->fsp_name->base_name, smb_fname->base_name)) {
537 DEBUG(10, ("Lease requested for file %s, reopened file "
538 "is named %s\n", smb_fname->base_name,
539 fsp->fsp_name->base_name));
540 TALLOC_FREE(smb_fname);
541 return NT_STATUS_INVALID_PARAMETER;
544 TALLOC_FREE(smb_fname);
549 struct smbd_smb2_create_state {
550 struct tevent_context *ev;
551 struct smbd_smb2_request *smb2req;
552 struct GUID req_guid;
553 struct smb_request *smb1req;
554 bool open_was_deferred;
555 struct tevent_immediate *im;
556 struct timeval request_time;
558 struct deferred_open_record *open_rec;
559 files_struct *result;
560 bool replay_operation;
561 uint8_t in_oplock_level;
562 uint32_t in_create_disposition;
563 int requested_oplock_level;
566 struct ea_list *ea_list;
567 NTTIME max_access_time;
568 struct security_descriptor *sec_desc;
569 uint64_t allocation_size;
570 struct GUID _create_guid;
571 struct GUID *create_guid;
572 struct GUID _purge_create_guid;
573 struct GUID *purge_create_guid;
575 bool durable_requested;
576 uint32_t durable_timeout_msec;
577 bool do_durable_reconnect;
578 uint64_t persistent_id;
579 struct smb2_lease lease;
580 struct smb2_lease *lease_ptr;
582 bool need_replay_cache;
583 struct smbXsrv_open *op;
586 struct smb2_create_blob *dhnc;
587 struct smb2_create_blob *dh2c;
588 struct smb2_create_blob *dhnq;
589 struct smb2_create_blob *dh2q;
590 struct smb2_create_blob *rqls;
591 struct smb2_create_blob *exta;
592 struct smb2_create_blob *mxac;
593 struct smb2_create_blob *secd;
594 struct smb2_create_blob *alsi;
595 struct smb2_create_blob *twrp;
596 struct smb2_create_blob *qfid;
597 struct smb2_create_blob *posx;
598 struct smb2_create_blob *svhdx;
600 uint8_t out_oplock_level;
601 uint32_t out_create_action;
602 struct timespec out_creation_ts;
603 struct timespec out_last_access_ts;
604 struct timespec out_last_write_ts;
605 struct timespec out_change_ts;
606 uint64_t out_allocation_size;
607 uint64_t out_end_of_file;
608 uint32_t out_file_attributes;
609 uint64_t out_file_id_persistent;
610 uint64_t out_file_id_volatile;
611 struct smb2_create_blobs *out_context_blobs;
614 static void smbd_smb2_create_purge_replay_cache(struct tevent_req *req,
615 const char *caller_func);
617 static void smbd_smb2_create_cleanup(struct tevent_req *req,
618 enum tevent_req_state req_state)
620 smbd_smb2_create_purge_replay_cache(req, __func__);
623 static NTSTATUS smbd_smb2_create_fetch_create_ctx(
624 struct tevent_req *req,
625 struct smb2_create_blobs *in_context_blobs)
627 struct smbd_smb2_create_state *state = tevent_req_data(
628 req, struct smbd_smb2_create_state);
629 struct smbd_smb2_request *smb2req = state->smb2req;
630 struct smbXsrv_connection *xconn = smb2req->xconn;
632 state->dhnq = smb2_create_blob_find(in_context_blobs,
633 SMB2_CREATE_TAG_DHNQ);
634 state->dhnc = smb2_create_blob_find(in_context_blobs,
635 SMB2_CREATE_TAG_DHNC);
636 state->dh2q = smb2_create_blob_find(in_context_blobs,
637 SMB2_CREATE_TAG_DH2Q);
638 state->dh2c = smb2_create_blob_find(in_context_blobs,
639 SMB2_CREATE_TAG_DH2C);
640 if (xconn->smb2.server.capabilities & SMB2_CAP_LEASING) {
641 state->rqls = smb2_create_blob_find(in_context_blobs,
642 SMB2_CREATE_TAG_RQLS);
645 if (((state->dhnc != NULL) && (state->dh2c != NULL)) ||
646 ((state->dhnc != NULL) && (state->dh2q != NULL)) ||
647 ((state->dh2c != NULL) && (state->dhnq != NULL)) ||
648 ((state->dh2q != NULL) && (state->dh2c != NULL)))
650 /* not both are allowed at the same time */
651 return NT_STATUS_INVALID_PARAMETER;
654 if (state->dhnc != NULL) {
655 uint32_t num_blobs_allowed;
657 if (state->dhnc->data.length != 16) {
658 return NT_STATUS_INVALID_PARAMETER;
662 * According to MS-SMB2: 3.3.5.9.7, "Handling the
663 * SMB2_CREATE_DURABLE_HANDLE_RECONNECT Create Context",
664 * we should ignore an additional dhnq blob, but fail
665 * the request (with status OBJECT_NAME_NOT_FOUND) if
666 * any other extra create blob has been provided.
668 * (Note that the cases of an additional dh2q or dh2c blob
669 * which require a different error code, have been treated
673 if (state->dhnq != NULL) {
674 num_blobs_allowed = 2;
676 num_blobs_allowed = 1;
679 if (state->rqls != NULL) {
680 num_blobs_allowed += 1;
683 if (in_context_blobs->num_blobs != num_blobs_allowed) {
684 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
688 if (state->dh2c!= NULL) {
689 uint32_t num_blobs_allowed;
691 if (state->dh2c->data.length != 36) {
692 return NT_STATUS_INVALID_PARAMETER;
696 * According to MS-SMB2: 3.3.5.9.12, "Handling the
697 * SMB2_CREATE_DURABLE_HANDLE_RECONNECT_V2 Create Context",
698 * we should fail the request with status
699 * OBJECT_NAME_NOT_FOUND if any other create blob has been
702 * (Note that the cases of an additional dhnq, dhnc or dh2q
703 * blob which require a different error code, have been
707 num_blobs_allowed = 1;
709 if (state->rqls != NULL) {
710 num_blobs_allowed += 1;
713 if (in_context_blobs->num_blobs != num_blobs_allowed) {
714 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
718 state->exta = smb2_create_blob_find(in_context_blobs,
719 SMB2_CREATE_TAG_EXTA);
720 state->mxac = smb2_create_blob_find(in_context_blobs,
721 SMB2_CREATE_TAG_MXAC);
722 state->secd = smb2_create_blob_find(in_context_blobs,
723 SMB2_CREATE_TAG_SECD);
724 state->alsi = smb2_create_blob_find(in_context_blobs,
725 SMB2_CREATE_TAG_ALSI);
726 state->twrp = smb2_create_blob_find(in_context_blobs,
727 SMB2_CREATE_TAG_TWRP);
728 state->qfid = smb2_create_blob_find(in_context_blobs,
729 SMB2_CREATE_TAG_QFID);
730 if (xconn->protocol >= PROTOCOL_SMB3_02) {
732 * This was introduced with SMB3_02
734 state->svhdx = smb2_create_blob_find(
735 in_context_blobs, SVHDX_OPEN_DEVICE_CONTEXT);
737 if (xconn->smb2.server.posix_extensions_negotiated) {
739 * Negprot only allowed this for proto>=3.11
741 SMB_ASSERT(xconn->protocol >= PROTOCOL_SMB3_11);
743 state->posx = smb2_create_blob_find(
744 in_context_blobs, SMB2_CREATE_TAG_POSIX);
746 * Setting the bool below will cause
747 * ucf_flags_from_smb_request() to
748 * return UCF_POSIX_PATHNAMES in ucf_flags.
750 state->smb1req->posix_pathnames = (state->posx != NULL);
756 static void smbd_smb2_create_before_exec(struct tevent_req *req);
757 static void smbd_smb2_create_after_exec(struct tevent_req *req);
758 static void smbd_smb2_create_finish(struct tevent_req *req);
760 static struct tevent_req *smbd_smb2_create_send(TALLOC_CTX *mem_ctx,
761 struct tevent_context *ev,
762 struct smbd_smb2_request *smb2req,
763 uint8_t in_oplock_level,
764 uint32_t in_impersonation_level,
765 uint32_t in_desired_access,
766 uint32_t in_file_attributes,
767 uint32_t in_share_access,
768 uint32_t in_create_disposition,
769 uint32_t in_create_options,
771 struct smb2_create_blobs in_context_blobs)
773 struct tevent_req *req = NULL;
774 struct smbd_smb2_create_state *state = NULL;
776 struct smb_request *smb1req = NULL;
777 struct files_struct *dirfsp = NULL;
778 struct smb_filename *smb_fname = NULL;
781 bool is_posix = false;
783 req = tevent_req_create(mem_ctx, &state,
784 struct smbd_smb2_create_state);
788 *state = (struct smbd_smb2_create_state) {
791 .in_oplock_level = in_oplock_level,
792 .in_create_disposition = in_create_disposition,
795 smb1req = smbd_smb2_fake_smb_request(smb2req, NULL);
796 if (tevent_req_nomem(smb1req, req)) {
797 return tevent_req_post(req, state->ev);
799 state->smb1req = smb1req;
801 state->req_guid = smbd_request_guid(smb1req, 0);
803 tevent_req_set_cleanup_fn(req, smbd_smb2_create_cleanup);
805 if (smb2req->subreq == NULL) {
806 DBG_DEBUG("name [%s]\n", in_name);
808 struct smbd_smb2_create_state *old_state = tevent_req_data(
809 smb2req->subreq, struct smbd_smb2_create_state);
811 DBG_DEBUG("reentrant for file %s\n", in_name);
813 state->id = old_state->id;
814 state->request_time = old_state->request_time;
815 state->open_rec = talloc_move(state, &old_state->open_rec);
816 state->open_was_deferred = old_state->open_was_deferred;
817 state->_purge_create_guid = old_state->_purge_create_guid;
818 state->purge_create_guid = old_state->purge_create_guid;
819 old_state->purge_create_guid = NULL;
822 TALLOC_FREE(smb2req->subreq);
823 smb2req->subreq = req;
825 if (lp_fake_oplocks(SNUM(smb2req->tcon->compat))) {
826 state->requested_oplock_level = SMB2_OPLOCK_LEVEL_NONE;
828 state->requested_oplock_level = state->in_oplock_level;
831 /* these are ignored for SMB2 */
832 in_create_options &= ~(0x10);/* NTCREATEX_OPTIONS_SYNC_ALERT */
833 in_create_options &= ~(0x20);/* NTCREATEX_OPTIONS_ASYNC_ALERT */
835 in_file_attributes &= ~FILE_FLAG_POSIX_SEMANTICS;
837 is_dfs = (smb1req->flags2 & FLAGS2_DFS_PATHNAMES);
839 const char *non_dfs_in_name = NULL;
841 * With a DFS flag set, remove any DFS prefix
842 * before further processing.
844 status = smb2_strip_dfs_path(in_name, &non_dfs_in_name);
845 if (!NT_STATUS_IS_OK(status)) {
846 tevent_req_nterror(req, status);
847 return tevent_req_post(req, state->ev);
850 * TODO: Note for dealing with reparse point errors.
851 * We will need to remember and store the number of characters
852 * we have removed here, which is (non_dfs_in_name - in_name)
853 * in order to correctly report how many characters we
854 * have removed before hitting the reparse point.
855 * This will be a patch needed once we properly
856 * deal with reparse points later.
858 in_name = non_dfs_in_name;
860 * Now we're no longer dealing with a DFS path, so
863 smb1req->flags2 &= ~FLAGS2_DFS_PATHNAMES;
867 state->fname = talloc_strdup(state, in_name);
868 if (tevent_req_nomem(state->fname, req)) {
869 return tevent_req_post(req, state->ev);
872 state->out_context_blobs = talloc_zero(state, struct smb2_create_blobs);
873 if (tevent_req_nomem(state->out_context_blobs, req)) {
874 return tevent_req_post(req, state->ev);
877 status = smbd_smb2_create_fetch_create_ctx(req, &in_context_blobs);
878 if (tevent_req_nterror(req, status)) {
879 return tevent_req_post(req, state->ev);
882 if (IS_IPC(smb1req->conn)) {
883 const char *pipe_name = in_name;
885 if (state->dhnc != NULL || state->dh2c != NULL) {
886 /* durable handles are not supported on IPC$ */
887 tevent_req_nterror(req, NT_STATUS_OBJECT_NAME_NOT_FOUND);
888 return tevent_req_post(req, state->ev);
891 if (!lp_nt_pipe_support()) {
892 tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
893 return tevent_req_post(req, state->ev);
896 status = open_np_file(smb1req, pipe_name, &state->result);
897 if (tevent_req_nterror(req, status)) {
898 return tevent_req_post(req, state->ev);
900 state->info = FILE_WAS_OPENED;
902 smbd_smb2_create_finish(req);
906 if (CAN_PRINT(smb1req->conn)) {
907 if (state->dhnc != NULL || state->dh2c != NULL) {
908 /* durable handles are not supported on printers */
909 tevent_req_nterror(req, NT_STATUS_OBJECT_NAME_NOT_FOUND);
910 return tevent_req_post(req, state->ev);
913 status = file_new(smb1req, smb1req->conn, &state->result);
914 if (tevent_req_nterror(req, status)) {
915 return tevent_req_post(req, state->ev);
918 status = print_spool_open(state->result, in_name,
920 if (tevent_req_nterror(req, status)) {
921 file_free(smb1req, state->result);
922 return tevent_req_post(req, state->ev);
924 state->info = FILE_WAS_CREATED;
926 smbd_smb2_create_finish(req);
930 /* Check for trailing slash specific directory handling. */
931 status = windows_name_trailing_check(state->fname, in_create_options);
932 if (tevent_req_nterror(req, status)) {
933 return tevent_req_post(req, state->ev);
936 smbd_smb2_create_before_exec(req);
937 if (!tevent_req_is_in_progress(req)) {
938 return tevent_req_post(req, state->ev);
941 DBG_DEBUG("open execution phase\n");
944 * For the backend file open procedure, there are
945 * three possible modes: replay operation (in which case
946 * there is nothing else to do), durable_reconnect or
949 if (state->replay_operation) {
950 state->result = state->op->compat;
951 state->result->op = state->op;
952 state->update_open = false;
953 state->info = state->op->create_action;
955 smbd_smb2_create_after_exec(req);
956 if (!tevent_req_is_in_progress(req)) {
960 smbd_smb2_create_finish(req);
964 if (state->do_durable_reconnect) {
965 DATA_BLOB new_cookie = data_blob_null;
966 NTTIME now = timeval_to_nttime(&smb2req->request_time);
968 status = smb2srv_open_recreate(smb2req->xconn,
969 smb1req->conn->session_info,
970 state->persistent_id,
974 if (tevent_req_nterror(req, status)) {
975 DBG_NOTICE("smb2srv_open_recreate failed: %s\n",
977 return tevent_req_post(req, state->ev);
980 DBG_DEBUG("%s to recreate durable handle\n",
981 state->op->global->durable ? "succeeded" : "failed");
983 if (!state->op->global->durable) {
984 talloc_free(state->op);
985 tevent_req_nterror(req,
986 NT_STATUS_OBJECT_NAME_NOT_FOUND);
987 return tevent_req_post(req, state->ev);
990 status = SMB_VFS_DURABLE_RECONNECT(smb1req->conn,
992 state->op, /* smbXsrv_open input */
993 state->op->global->backend_cookie,
994 state->op, /* TALLOC_CTX */
997 if (!NT_STATUS_IS_OK(status)) {
998 NTSTATUS return_status;
1000 return_status = NT_STATUS_OBJECT_NAME_NOT_FOUND;
1002 DBG_NOTICE("durable_reconnect failed: %s => %s\n",
1004 nt_errstr(return_status));
1006 tevent_req_nterror(req, return_status);
1007 return tevent_req_post(req, state->ev);
1010 DBG_DEBUG("oplock_type=%u, lease_ptr==%p\n",
1011 (unsigned)state->result->oplock_type, state->lease_ptr);
1013 status = smbd_smb2_create_durable_lease_check(
1014 smb1req, state->fname, state->result, state->lease_ptr);
1015 if (tevent_req_nterror(req, status)) {
1017 smb1req, &state->result, SHUTDOWN_CLOSE);
1018 return tevent_req_post(req, state->ev);
1021 data_blob_free(&state->op->global->backend_cookie);
1022 state->op->global->backend_cookie = new_cookie;
1024 state->op->status = NT_STATUS_OK;
1025 state->op->global->disconnect_time = 0;
1027 /* save the timout for later update */
1028 state->durable_timeout_msec = state->op->global->durable_timeout_msec;
1030 state->update_open = true;
1032 state->info = FILE_WAS_OPENED;
1034 smbd_smb2_create_after_exec(req);
1035 if (!tevent_req_is_in_progress(req)) {
1039 smbd_smb2_create_finish(req);
1043 if (state->requested_oplock_level == SMB2_OPLOCK_LEVEL_LEASE) {
1044 if (state->lease_ptr == NULL) {
1045 state->requested_oplock_level = SMB2_OPLOCK_LEVEL_NONE;
1048 state->lease_ptr = NULL;
1051 is_posix = (state->posx != NULL);
1053 /* convert '\\' into '/' */
1054 status = check_path_syntax(state->fname, is_posix);
1055 if (tevent_req_nterror(req, status)) {
1056 return tevent_req_post(req, state->ev);
1059 ucf_flags = filename_create_ucf_flags(
1060 smb1req, state->in_create_disposition);
1062 status = filename_convert_dirfsp(
1070 if (tevent_req_nterror(req, status)) {
1071 return tevent_req_post(req, state->ev);
1075 * MS-SMB2: 2.2.13 SMB2 CREATE Request
1076 * ImpersonationLevel ... MUST contain one of the
1077 * following values. The server MUST validate this
1078 * field, but otherwise ignore it.
1080 * NB. The source4/torture/smb2/durable_open.c test
1081 * shows this check is only done on real opens, not
1082 * on durable handle-reopens.
1085 if (in_impersonation_level >
1086 SMB2_IMPERSONATION_DELEGATE) {
1087 tevent_req_nterror(req,
1088 NT_STATUS_BAD_IMPERSONATION_LEVEL);
1089 return tevent_req_post(req, state->ev);
1093 * We know we're going to do a local open, so now
1094 * we must be protocol strict. JRA.
1096 * MS-SMB2: 3.3.5.9 - Receiving an SMB2 CREATE Request
1097 * If the file name length is greater than zero and the
1098 * first character is a path separator character, the
1099 * server MUST fail the request with
1100 * STATUS_INVALID_PARAMETER.
1102 if (in_name[0] == '/') {
1103 /* Names starting with '/' are never allowed. */
1104 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
1105 return tevent_req_post(req, ev);
1107 if (!is_posix && (in_name[0] == '\\')) {
1109 * Windows names starting with '\' are not allowed.
1111 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
1112 return tevent_req_post(req, ev);
1115 status = SMB_VFS_CREATE_FILE(smb1req->conn,
1121 state->in_create_disposition,
1124 map_smb2_oplock_levels_to_samba(
1125 state->requested_oplock_level),
1127 state->allocation_size,
1128 0, /* private_flags */
1134 state->out_context_blobs);
1135 if (!NT_STATUS_IS_OK(status)) {
1136 if (open_was_deferred(smb1req->xconn, smb1req->mid)) {
1137 SMBPROFILE_IOBYTES_ASYNC_SET_IDLE(smb2req->profile);
1140 tevent_req_nterror(req, status);
1141 return tevent_req_post(req, state->ev);
1143 state->op = state->result->op;
1145 smbd_smb2_create_after_exec(req);
1146 if (!tevent_req_is_in_progress(req)) {
1150 smbd_smb2_create_finish(req);
1154 static void smbd_smb2_create_purge_replay_cache(struct tevent_req *req,
1155 const char *caller_func)
1157 struct smbd_smb2_create_state *state = tevent_req_data(
1158 req, struct smbd_smb2_create_state);
1161 if (state->purge_create_guid == NULL) {
1165 status = smbXsrv_open_purge_replay_cache(state->smb2req->xconn->client,
1166 state->purge_create_guid);
1167 if (!NT_STATUS_IS_OK(status)) {
1168 struct GUID_txt_buf buf;
1170 D_ERR("%s: smbXsrv_open_purge_replay_cache(%s) %s\n",
1172 GUID_buf_string(state->purge_create_guid, &buf),
1176 state->purge_create_guid = NULL;
1179 static void smbd_smb2_create_before_exec(struct tevent_req *req)
1181 struct smbd_smb2_create_state *state = tevent_req_data(
1182 req, struct smbd_smb2_create_state);
1183 struct smbd_smb2_request *smb2req = state->smb2req;
1186 if (state->exta != NULL) {
1187 if (!lp_ea_support(SNUM(smb2req->tcon->compat))) {
1188 tevent_req_nterror(req, NT_STATUS_EAS_NOT_SUPPORTED);
1192 state->ea_list = read_nttrans_ea_list(
1194 (const char *)state->exta->data.data,
1195 state->exta->data.length);
1196 if (state->ea_list == NULL) {
1197 DEBUG(10,("smbd_smb2_create_send: read_ea_name_list failed.\n"));
1198 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
1202 if ((state->posx == NULL) &&
1203 ea_list_has_invalid_name(state->ea_list)) {
1204 tevent_req_nterror(req, STATUS_INVALID_EA_NAME);
1209 if (state->mxac != NULL) {
1210 if (state->mxac->data.length == 0) {
1211 state->max_access_time = 0;
1212 } else if (state->mxac->data.length == 8) {
1213 state->max_access_time = BVAL(state->mxac->data.data, 0);
1215 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
1220 if (state->secd != NULL) {
1221 enum ndr_err_code ndr_err;
1223 state->sec_desc = talloc_zero(state, struct security_descriptor);
1224 if (tevent_req_nomem(state->sec_desc, req)) {
1228 ndr_err = ndr_pull_struct_blob(&state->secd->data,
1229 state->sec_desc, state->sec_desc,
1230 (ndr_pull_flags_fn_t)ndr_pull_security_descriptor);
1231 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1232 DEBUG(2,("ndr_pull_security_descriptor failed: %s\n",
1233 ndr_errstr(ndr_err)));
1234 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
1239 if (state->dhnq != NULL) {
1240 if (state->dhnq->data.length != 16) {
1241 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
1245 if (state->dh2q != NULL) {
1246 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
1251 * durable handle request is processed below.
1253 state->durable_requested = true;
1255 * Set the timeout to 16 mins.
1257 * TODO: test this against Windows 2012
1258 * as the default for durable v2 is 1 min.
1260 state->durable_timeout_msec = (16*60*1000);
1263 if (state->dh2q != NULL) {
1264 const uint8_t *p = state->dh2q->data.data;
1265 NTTIME now = timeval_to_nttime(&smb2req->request_time);
1266 uint32_t durable_v2_timeout = 0;
1267 DATA_BLOB create_guid_blob;
1271 if (state->dh2q->data.length != 32) {
1272 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
1276 if (state->dhnq != NULL) {
1277 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
1281 durable_v2_timeout = IVAL(p, 0);
1282 create_guid_blob = data_blob_const(p + 16, 16);
1284 status = GUID_from_ndr_blob(&create_guid_blob,
1285 &state->_create_guid);
1286 if (tevent_req_nterror(req, status)) {
1289 state->create_guid = &state->_create_guid;
1292 * we need to store the create_guid later
1294 state->update_open = true;
1297 * And we need to create a cache for replaying the
1300 state->need_replay_cache = true;
1303 * durable handle v2 request processed below
1305 state->durable_requested = true;
1306 state->durable_timeout_msec = MIN(durable_v2_timeout, 300*1000);
1307 if (state->durable_timeout_msec == 0) {
1309 * Set the timeout to 1 min as default.
1311 * This matches Windows 2012.
1313 state->durable_timeout_msec = (60*1000);
1317 * Check for replay operation.
1318 * Only consider it when we have dh2q.
1319 * If we do not have a replay operation, verify that
1320 * the create_guid is not cached for replay.
1322 hdr = SMBD_SMB2_IN_HDR_PTR(smb2req);
1323 flags = IVAL(hdr, SMB2_HDR_FLAGS);
1324 state->replay_operation =
1325 flags & SMB2_HDR_FLAG_REPLAY_OPERATION;
1327 status = smb2srv_open_lookup_replay_cache(smb2req->xconn,
1329 *state->create_guid,
1333 if (NT_STATUS_EQUAL(status, NT_STATUS_FWP_RESERVED)) {
1335 * We've reserved the replay_cache record
1336 * for ourself, indicating we're still
1339 * It means the smbd_smb2_create_cleanup()
1340 * may need to call smbXsrv_open_purge_replay_cache()
1341 * in order to cleanup.
1343 SMB_ASSERT(state->op == NULL);
1344 state->_purge_create_guid = state->_create_guid;
1345 state->purge_create_guid = &state->_purge_create_guid;
1346 status = NT_STATUS_OK;
1347 state->replay_operation = false;
1348 } else if (NT_STATUS_EQUAL(status, NT_STATUS_FILE_NOT_AVAILABLE)) {
1349 tevent_req_nterror(req, status);
1351 } else if (tevent_req_nterror(req, status)) {
1352 DBG_WARNING("smb2srv_open_lookup_replay_cache "
1353 "failed: %s\n", nt_errstr(status));
1355 } else if (!state->replay_operation) {
1357 * If a create without replay operation flag
1358 * is sent but with a create_guid that is
1359 * currently in the replay cache -- fail.
1361 status = NT_STATUS_DUPLICATE_OBJECTID;
1362 (void)tevent_req_nterror(req, status);
1367 if (state->dhnc != NULL) {
1368 state->persistent_id = BVAL(state->dhnc->data.data, 0);
1369 state->do_durable_reconnect = true;
1372 if (state->dh2c != NULL) {
1373 const uint8_t *p = state->dh2c->data.data;
1374 DATA_BLOB create_guid_blob;
1376 state->persistent_id = BVAL(p, 0);
1377 create_guid_blob = data_blob_const(p + 16, 16);
1379 status = GUID_from_ndr_blob(&create_guid_blob,
1380 &state->_create_guid);
1381 if (tevent_req_nterror(req, status)) {
1385 state->create_guid = &state->_create_guid;
1386 state->do_durable_reconnect = true;
1389 if (state->alsi != NULL) {
1390 if (state->alsi->data.length != 8) {
1391 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
1394 state->allocation_size = BVAL(state->alsi->data.data, 0);
1397 if (state->twrp != NULL) {
1398 if (state->twrp->data.length != 8) {
1399 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
1403 state->twrp_time = BVAL(state->twrp->data.data, 0);
1406 if (state->qfid != NULL) {
1407 if (state->qfid->data.length != 0) {
1408 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
1413 if (state->rqls != NULL) {
1414 ssize_t lease_len = -1;
1416 lease_len = smb2_lease_pull(state->rqls->data.data,
1417 state->rqls->data.length,
1419 if (lease_len == -1) {
1421 req, NT_STATUS_INVALID_PARAMETER);
1424 state->lease_ptr = &state->lease;
1426 if (DEBUGLEVEL >= 10) {
1427 DEBUG(10, ("Got lease request size %d\n",
1429 NDR_PRINT_DEBUG(smb2_lease, state->lease_ptr);
1432 if (!smb2_lease_key_valid(&state->lease.lease_key)) {
1433 state->lease_ptr = NULL;
1434 state->requested_oplock_level = SMB2_OPLOCK_LEVEL_NONE;
1437 if ((smb2req->xconn->protocol < PROTOCOL_SMB3_00) &&
1438 (state->lease.lease_version != 1))
1440 DEBUG(10, ("v2 lease key only for SMB3\n"));
1441 state->lease_ptr = NULL;
1445 * Replay with a lease is only allowed if the
1446 * established open carries a lease with the
1449 if (state->replay_operation) {
1450 struct smb2_lease *op_ls =
1451 &state->op->compat->lease->lease;
1452 int op_oplock = state->op->compat->oplock_type;
1454 if (map_samba_oplock_levels_to_smb2(op_oplock)
1455 != SMB2_OPLOCK_LEVEL_LEASE)
1457 status = NT_STATUS_ACCESS_DENIED;
1458 (void)tevent_req_nterror(req, status);
1461 if (!smb2_lease_key_equal(&state->lease.lease_key,
1464 status = NT_STATUS_ACCESS_DENIED;
1465 (void)tevent_req_nterror(req, status);
1471 if (state->posx != NULL) {
1472 if (state->posx->data.length != 4) {
1473 DBG_DEBUG("Got %zu bytes POSX cctx, expected 4\n",
1474 state->posx->data.length);
1475 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
1481 static void smbd_smb2_create_after_exec(struct tevent_req *req)
1483 struct smbd_smb2_create_state *state = tevent_req_data(
1484 req, struct smbd_smb2_create_state);
1485 connection_struct *conn = state->result->conn;
1489 * here we have op == result->op
1492 DBG_DEBUG("response construction phase\n");
1494 state->out_file_attributes = fdos_mode(state->result);
1496 if (state->mxac != NULL) {
1497 NTTIME last_write_time;
1499 last_write_time = full_timespec_to_nt_time(
1500 &state->result->fsp_name->st.st_ex_mtime);
1501 if (last_write_time != state->max_access_time) {
1503 uint32_t max_access_granted;
1504 DATA_BLOB blob = data_blob_const(p, sizeof(p));
1506 status = smbd_calculate_access_mask_fsp(
1510 SEC_FLAG_MAXIMUM_ALLOWED,
1511 &max_access_granted);
1513 SIVAL(p, 0, NT_STATUS_V(status));
1514 SIVAL(p, 4, max_access_granted);
1516 status = smb2_create_blob_add(
1517 state->out_context_blobs,
1518 state->out_context_blobs,
1519 SMB2_CREATE_TAG_MXAC,
1521 if (!NT_STATUS_IS_OK(status)) {
1527 if (!state->replay_operation && state->durable_requested &&
1528 (fsp_lease_type(state->result) & SMB2_LEASE_HANDLE))
1530 status = SMB_VFS_DURABLE_COOKIE(
1533 &state->op->global->backend_cookie);
1534 if (!NT_STATUS_IS_OK(status)) {
1535 state->op->global->backend_cookie = data_blob_null;
1538 if (!state->replay_operation && state->op->global->backend_cookie.length > 0)
1540 state->update_open = true;
1542 state->op->global->durable = true;
1543 state->op->global->durable_timeout_msec = state->durable_timeout_msec;
1546 if (state->update_open) {
1547 state->op->global->create_guid = state->_create_guid;
1548 if (state->need_replay_cache) {
1549 state->op->flags |= SMBXSRV_OPEN_NEED_REPLAY_CACHE;
1552 status = smbXsrv_open_update(state->op);
1553 DEBUG(10, ("smb2_create_send: smbXsrv_open_update "
1555 nt_errstr(status)));
1556 if (!NT_STATUS_IS_OK(status)) {
1561 * We should not purge the replay cache anymore
1562 * as it's attached to the smbXsrv_open record now.
1564 state->purge_create_guid = NULL;
1567 if (state->dhnq != NULL && state->op->global->durable) {
1568 uint8_t p[8] = { 0, };
1569 DATA_BLOB blob = data_blob_const(p, sizeof(p));
1571 status = smb2_create_blob_add(state->out_context_blobs,
1572 state->out_context_blobs,
1573 SMB2_CREATE_TAG_DHNQ,
1575 if (!NT_STATUS_IS_OK(status)) {
1580 if (state->dh2q != NULL && state->op->global->durable &&
1582 * For replay operations, we return the dh2q blob
1583 * in the case of oplocks not based on the state of
1584 * the open, but on whether it could have been granted
1585 * for the request data. In the case of leases instead,
1586 * the state of the open is used...
1588 (!state->replay_operation ||
1589 state->in_oplock_level == SMB2_OPLOCK_LEVEL_BATCH ||
1590 state->in_oplock_level == SMB2_OPLOCK_LEVEL_LEASE))
1592 uint8_t p[8] = { 0, };
1593 DATA_BLOB blob = data_blob_const(p, sizeof(p));
1594 uint32_t durable_v2_response_flags = 0;
1596 SIVAL(p, 0, state->op->global->durable_timeout_msec);
1597 SIVAL(p, 4, durable_v2_response_flags);
1599 status = smb2_create_blob_add(state->out_context_blobs,
1600 state->out_context_blobs,
1601 SMB2_CREATE_TAG_DH2Q,
1603 if (!NT_STATUS_IS_OK(status)) {
1608 if (state->qfid != NULL) {
1610 SMB_STRUCT_STAT *base_sp = state->result->base_fsp ?
1611 &state->result->base_fsp->fsp_name->st :
1612 &state->result->fsp_name->st;
1613 uint64_t file_id = SMB_VFS_FS_FILE_ID(conn, base_sp);
1614 DATA_BLOB blob = data_blob_const(p, sizeof(p));
1618 /* From conversations with Microsoft engineers at
1619 the MS plugfest. The first 8 bytes are the "volume index"
1620 == inode, the second 8 bytes are the "volume id",
1621 == dev. This will be updated in the SMB2 doc. */
1622 SBVAL(p, 0, file_id);
1623 SIVAL(p, 8, base_sp->st_ex_dev);/* FileIndexHigh */
1625 status = smb2_create_blob_add(state->out_context_blobs,
1626 state->out_context_blobs,
1627 SMB2_CREATE_TAG_QFID,
1629 if (!NT_STATUS_IS_OK(status)) {
1634 if ((state->rqls != NULL) && (state->result->oplock_type == LEASE_OPLOCK)) {
1636 struct smb2_lease lease;
1639 lease = state->result->lease->lease;
1641 lease_len = sizeof(buf);
1642 if (lease.lease_version == 1) {
1646 if (!smb2_lease_push(&lease, buf, lease_len)) {
1647 status = NT_STATUS_INTERNAL_ERROR;
1651 status = smb2_create_blob_add(
1652 state, state->out_context_blobs,
1653 SMB2_CREATE_TAG_RQLS,
1654 data_blob_const(buf, lease_len));
1655 if (!NT_STATUS_IS_OK(status)) {
1660 if (state->posx != NULL) {
1661 struct dom_sid owner = { .sid_rev_num = 0, };
1662 struct dom_sid group = { .sid_rev_num = 0, };
1663 struct stat_ex *psbuf = &state->result->fsp_name->st;
1666 uid_to_sid(&owner, psbuf->st_ex_uid);
1667 gid_to_sid(&group, psbuf->st_ex_gid);
1669 cc_len = smb2_posix_cc_info(
1670 conn, 0, psbuf, &owner, &group, NULL, 0);
1673 status = NT_STATUS_INSUFFICIENT_RESOURCES;
1679 * cc_len is 68 + 2 SIDs, allocate on the stack
1681 uint8_t buf[cc_len];
1682 DATA_BLOB blob = { .data = buf, .length = cc_len, };
1693 status = smb2_create_blob_add(
1694 state->out_context_blobs,
1695 state->out_context_blobs,
1696 SMB2_CREATE_TAG_POSIX,
1698 if (!NT_STATUS_IS_OK(status)) {
1707 close_file_free(state->smb1req, &state->result, ERROR_CLOSE);
1708 tevent_req_nterror(req, status);
1709 tevent_req_post(req, state->ev);
1712 static void smbd_smb2_create_finish(struct tevent_req *req)
1714 struct smbd_smb2_create_state *state = tevent_req_data(
1715 req, struct smbd_smb2_create_state);
1716 struct smbd_smb2_request *smb2req = state->smb2req;
1717 struct smb_request *smb1req = state->smb1req;
1718 files_struct *result = state->result;
1720 smb2req->compat_chain_fsp = smb1req->chain_fsp;
1722 if (state->replay_operation) {
1723 state->out_oplock_level = state->in_oplock_level;
1724 } else if (lp_fake_oplocks(SNUM(smb2req->tcon->compat))) {
1725 state->out_oplock_level = state->in_oplock_level;
1727 state->out_oplock_level = map_samba_oplock_levels_to_smb2(result->oplock_type);
1730 if ((state->in_create_disposition == FILE_SUPERSEDE)
1731 && (state->info == FILE_WAS_OVERWRITTEN)) {
1732 state->out_create_action = FILE_WAS_SUPERSEDED;
1734 state->out_create_action = state->info;
1736 result->op->create_action = state->out_create_action;
1738 state->out_creation_ts = get_create_timespec(smb1req->conn,
1739 result, result->fsp_name);
1740 state->out_last_access_ts = result->fsp_name->st.st_ex_atime;
1741 state->out_last_write_ts = result->fsp_name->st.st_ex_mtime;
1742 state->out_change_ts = get_change_timespec(smb1req->conn,
1743 result, result->fsp_name);
1745 if (lp_dos_filetime_resolution(SNUM(smb2req->tcon->compat))) {
1746 dos_filetime_timespec(&state->out_creation_ts);
1747 dos_filetime_timespec(&state->out_last_access_ts);
1748 dos_filetime_timespec(&state->out_last_write_ts);
1749 dos_filetime_timespec(&state->out_change_ts);
1752 state->out_allocation_size =
1753 SMB_VFS_GET_ALLOC_SIZE(smb1req->conn, result,
1754 &(result->fsp_name->st));
1755 state->out_end_of_file = result->fsp_name->st.st_ex_size;
1756 if (state->out_file_attributes == 0) {
1757 state->out_file_attributes = FILE_ATTRIBUTE_NORMAL;
1759 state->out_file_id_persistent = result->op->global->open_persistent_id;
1760 state->out_file_id_volatile = result->op->global->open_volatile_id;
1762 DBG_DEBUG("%s - %s\n", fsp_str_dbg(result), fsp_fnum_dbg(result));
1764 tevent_req_done(req);
1765 tevent_req_post(req, state->ev);
1768 static NTSTATUS smbd_smb2_create_recv(struct tevent_req *req,
1769 TALLOC_CTX *mem_ctx,
1770 uint8_t *out_oplock_level,
1771 uint32_t *out_create_action,
1772 struct timespec *out_creation_ts,
1773 struct timespec *out_last_access_ts,
1774 struct timespec *out_last_write_ts,
1775 struct timespec *out_change_ts,
1776 uint64_t *out_allocation_size,
1777 uint64_t *out_end_of_file,
1778 uint32_t *out_file_attributes,
1779 uint64_t *out_file_id_persistent,
1780 uint64_t *out_file_id_volatile,
1781 struct smb2_create_blobs *out_context_blobs)
1784 struct smbd_smb2_create_state *state = tevent_req_data(req,
1785 struct smbd_smb2_create_state);
1787 if (tevent_req_is_nterror(req, &status)) {
1788 tevent_req_received(req);
1792 *out_oplock_level = state->out_oplock_level;
1793 *out_create_action = state->out_create_action;
1794 *out_creation_ts = state->out_creation_ts;
1795 *out_last_access_ts = state->out_last_access_ts;
1796 *out_last_write_ts = state->out_last_write_ts;
1797 *out_change_ts = state->out_change_ts;
1798 *out_allocation_size = state->out_allocation_size;
1799 *out_end_of_file = state->out_end_of_file;
1800 *out_file_attributes = state->out_file_attributes;
1801 *out_file_id_persistent = state->out_file_id_persistent;
1802 *out_file_id_volatile = state->out_file_id_volatile;
1803 *out_context_blobs = *(state->out_context_blobs);
1805 talloc_steal(mem_ctx, state->out_context_blobs->blobs);
1807 tevent_req_received(req);
1808 return NT_STATUS_OK;
1811 /*********************************************************
1812 Code for dealing with deferred opens.
1813 *********************************************************/
1815 bool get_deferred_open_message_state_smb2(struct smbd_smb2_request *smb2req,
1816 struct timeval *p_request_time,
1817 struct deferred_open_record **open_rec)
1819 struct smbd_smb2_create_state *state = NULL;
1820 struct tevent_req *req = NULL;
1825 req = smb2req->subreq;
1829 state = tevent_req_data(req, struct smbd_smb2_create_state);
1833 if (!state->open_was_deferred) {
1836 if (p_request_time) {
1837 *p_request_time = state->request_time;
1839 if (open_rec != NULL) {
1840 *open_rec = state->open_rec;
1845 /*********************************************************
1846 Re-process this call early - requested by message or
1848 *********************************************************/
1850 static struct smbd_smb2_request *find_open_smb2req(
1851 struct smbXsrv_connection *xconn, uint64_t mid)
1853 struct smbd_smb2_request *smb2req;
1855 for (smb2req = xconn->smb2.requests; smb2req; smb2req = smb2req->next) {
1856 uint64_t message_id;
1857 if (smb2req->subreq == NULL) {
1858 /* This message has been processed. */
1861 if (!tevent_req_is_in_progress(smb2req->subreq)) {
1862 /* This message has been processed. */
1865 message_id = get_mid_from_smb2req(smb2req);
1866 if (message_id == mid) {
1873 bool open_was_deferred_smb2(struct smbXsrv_connection *xconn, uint64_t mid)
1875 struct smbd_smb2_create_state *state = NULL;
1876 struct smbd_smb2_request *smb2req;
1878 smb2req = find_open_smb2req(xconn, mid);
1881 DEBUG(10,("open_was_deferred_smb2: mid %llu smb2req == NULL\n",
1882 (unsigned long long)mid));
1885 if (!smb2req->subreq) {
1888 if (!tevent_req_is_in_progress(smb2req->subreq)) {
1891 state = tevent_req_data(smb2req->subreq,
1892 struct smbd_smb2_create_state);
1896 /* It's not in progress if there's no timeout event. */
1897 if (!state->open_was_deferred) {
1901 DEBUG(10,("open_was_deferred_smb2: mid = %llu\n",
1902 (unsigned long long)mid));
1907 static void remove_deferred_open_message_smb2_internal(struct smbd_smb2_request *smb2req,
1910 struct smbd_smb2_create_state *state = NULL;
1912 if (!smb2req->subreq) {
1915 if (!tevent_req_is_in_progress(smb2req->subreq)) {
1918 state = tevent_req_data(smb2req->subreq,
1919 struct smbd_smb2_create_state);
1924 DEBUG(10,("remove_deferred_open_message_smb2_internal: "
1926 (unsigned long long)mid ));
1928 state->open_was_deferred = false;
1929 /* Ensure we don't have any outstanding immediate event. */
1930 TALLOC_FREE(state->im);
1931 TALLOC_FREE(state->open_rec);
1934 void remove_deferred_open_message_smb2(
1935 struct smbXsrv_connection *xconn, uint64_t mid)
1937 struct smbd_smb2_request *smb2req;
1939 smb2req = find_open_smb2req(xconn, mid);
1942 DEBUG(10,("remove_deferred_open_message_smb2: "
1943 "can't find mid %llu\n",
1944 (unsigned long long)mid ));
1947 remove_deferred_open_message_smb2_internal(smb2req, mid);
1950 static void smbd_smb2_create_request_dispatch_immediate(struct tevent_context *ctx,
1951 struct tevent_immediate *im,
1954 struct smbd_smb2_request *smb2req = talloc_get_type_abort(private_data,
1955 struct smbd_smb2_request);
1956 uint64_t mid = get_mid_from_smb2req(smb2req);
1959 DEBUG(10,("smbd_smb2_create_request_dispatch_immediate: "
1960 "re-dispatching mid %llu\n",
1961 (unsigned long long)mid ));
1963 status = smbd_smb2_request_dispatch(smb2req);
1964 if (!NT_STATUS_IS_OK(status)) {
1965 smbd_server_connection_terminate(smb2req->xconn,
1971 bool schedule_deferred_open_message_smb2(
1972 struct smbXsrv_connection *xconn, uint64_t mid)
1974 struct smbd_smb2_create_state *state = NULL;
1975 struct smbd_smb2_request *smb2req;
1977 smb2req = find_open_smb2req(xconn, mid);
1980 DEBUG(10,("schedule_deferred_open_message_smb2: "
1981 "can't find mid %llu\n",
1982 (unsigned long long)mid ));
1985 if (!smb2req->subreq) {
1988 if (!tevent_req_is_in_progress(smb2req->subreq)) {
1991 state = tevent_req_data(smb2req->subreq,
1992 struct smbd_smb2_create_state);
1997 /* Ensure we don't have any outstanding immediate event. */
1998 TALLOC_FREE(state->im);
2001 * This is subtle. We must null out the callback
2002 * before rescheduling, else the first call to
2003 * tevent_req_nterror() causes the _receive()
2004 * function to be called, this causing tevent_req_post()
2007 tevent_req_set_callback(smb2req->subreq, NULL, NULL);
2009 state->im = tevent_create_immediate(smb2req);
2011 smbd_server_connection_terminate(smb2req->xconn,
2012 nt_errstr(NT_STATUS_NO_MEMORY));
2016 DEBUG(10,("schedule_deferred_open_message_smb2: "
2017 "re-processing mid %llu\n",
2018 (unsigned long long)mid ));
2020 tevent_schedule_immediate(state->im,
2021 smb2req->sconn->ev_ctx,
2022 smbd_smb2_create_request_dispatch_immediate,
2028 static bool smbd_smb2_create_cancel(struct tevent_req *req)
2030 struct smbd_smb2_request *smb2req = NULL;
2031 struct smbd_smb2_create_state *state = tevent_req_data(req,
2032 struct smbd_smb2_create_state);
2039 if (!state->smb2req) {
2043 smb2req = state->smb2req;
2044 mid = get_mid_from_smb2req(smb2req);
2046 if (is_deferred_open_async(state->open_rec)) {
2047 /* Can't cancel an async create. */
2051 remove_deferred_open_message_smb2_internal(smb2req, mid);
2053 tevent_req_defer_callback(req, smb2req->sconn->ev_ctx);
2054 tevent_req_nterror(req, NT_STATUS_CANCELLED);
2058 bool push_deferred_open_message_smb2(struct smbd_smb2_request *smb2req,
2059 struct timeval request_time,
2060 struct timeval timeout,
2062 struct deferred_open_record *open_rec)
2064 struct tevent_req *req = NULL;
2065 struct smbd_smb2_create_state *state = NULL;
2066 struct timeval end_time;
2071 req = smb2req->subreq;
2075 state = tevent_req_data(req, struct smbd_smb2_create_state);
2080 state->request_time = request_time;
2081 state->open_rec = talloc_move(state, &open_rec);
2083 /* Re-schedule us to retry on timer expiry. */
2084 end_time = timeval_sum(&request_time, &timeout);
2086 DEBUG(10,("push_deferred_open_message_smb2: "
2088 timeval_string(talloc_tos(),
2092 state->open_was_deferred = true;
2094 /* allow this request to be canceled */
2095 tevent_req_set_cancel_fn(req, smbd_smb2_create_cancel);