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 "../librpc/gen_ndr/ndr_smb3posix.h"
31 #include "../lib/util/tevent_ntstatus.h"
33 #include "lib/util_ea.h"
34 #include "source3/passdb/lookup_sid.h"
37 #define DBGC_CLASS DBGC_SMB2
39 int map_smb2_oplock_levels_to_samba(uint8_t in_oplock_level)
41 switch(in_oplock_level) {
42 case SMB2_OPLOCK_LEVEL_NONE:
44 case SMB2_OPLOCK_LEVEL_II:
45 return LEVEL_II_OPLOCK;
46 case SMB2_OPLOCK_LEVEL_EXCLUSIVE:
47 return EXCLUSIVE_OPLOCK;
48 case SMB2_OPLOCK_LEVEL_BATCH:
50 case SMB2_OPLOCK_LEVEL_LEASE:
53 DEBUG(2,("map_smb2_oplock_levels_to_samba: "
55 (unsigned int)in_oplock_level));
60 static uint8_t map_samba_oplock_levels_to_smb2(int oplock_type)
62 if (BATCH_OPLOCK_TYPE(oplock_type)) {
63 return SMB2_OPLOCK_LEVEL_BATCH;
64 } else if (EXCLUSIVE_OPLOCK_TYPE(oplock_type)) {
65 return SMB2_OPLOCK_LEVEL_EXCLUSIVE;
66 } else if (oplock_type == LEVEL_II_OPLOCK) {
67 return SMB2_OPLOCK_LEVEL_II;
68 } else if (oplock_type == LEASE_OPLOCK) {
69 return SMB2_OPLOCK_LEVEL_LEASE;
71 return SMB2_OPLOCK_LEVEL_NONE;
76 MS-FSA 2.1.5.1 Server Requests an Open of a File
77 Trailing '/' or '\\' checker.
78 Must be done before the filename parser removes any
79 trailing characters. If we decide to add this to SMB1
80 NTCreate processing we can make this public.
82 Note this is Windows pathname processing only. When
83 POSIX pathnames are added to SMB2 this will not apply.
86 static NTSTATUS windows_name_trailing_check(const char *name,
87 uint32_t create_options)
89 size_t name_len = strlen(name);
96 trail_c = name[name_len-1];
99 * Trailing '/' is always invalid.
101 if (trail_c == '/') {
102 return NT_STATUS_OBJECT_NAME_INVALID;
105 if (create_options & FILE_NON_DIRECTORY_FILE) {
106 if (trail_c == '\\') {
107 return NT_STATUS_OBJECT_NAME_INVALID;
113 static struct tevent_req *smbd_smb2_create_send(TALLOC_CTX *mem_ctx,
114 struct tevent_context *ev,
115 struct smbd_smb2_request *smb2req,
116 uint8_t in_oplock_level,
117 uint32_t in_impersonation_level,
118 uint32_t in_desired_access,
119 uint32_t in_file_attributes,
120 uint32_t in_share_access,
121 uint32_t in_create_disposition,
122 uint32_t in_create_options,
124 struct smb2_create_blobs in_context_blobs);
125 static NTSTATUS smbd_smb2_create_recv(struct tevent_req *req,
127 uint8_t *out_oplock_level,
128 uint32_t *out_create_action,
129 struct timespec *out_creation_ts,
130 struct timespec *out_last_access_ts,
131 struct timespec *out_last_write_ts,
132 struct timespec *out_change_ts,
133 uint64_t *out_allocation_size,
134 uint64_t *out_end_of_file,
135 uint32_t *out_file_attributes,
136 uint64_t *out_file_id_persistent,
137 uint64_t *out_file_id_volatile,
138 struct smb2_create_blobs *out_context_blobs);
140 static void smbd_smb2_request_create_done(struct tevent_req *tsubreq);
141 NTSTATUS smbd_smb2_request_process_create(struct smbd_smb2_request *smb2req)
143 const uint8_t *inbody;
144 const struct iovec *indyniov;
145 uint8_t in_oplock_level;
146 uint32_t in_impersonation_level;
147 uint32_t in_desired_access;
148 uint32_t in_file_attributes;
149 uint32_t in_share_access;
150 uint32_t in_create_disposition;
151 uint32_t in_create_options;
152 uint16_t in_name_offset;
153 uint16_t in_name_length;
154 DATA_BLOB in_name_buffer;
155 char *in_name_string;
156 size_t in_name_string_size;
157 uint32_t name_offset = 0;
158 uint32_t name_available_length = 0;
159 uint32_t in_context_offset;
160 uint32_t in_context_length;
161 DATA_BLOB in_context_buffer;
162 struct smb2_create_blobs in_context_blobs;
163 uint32_t context_offset = 0;
164 uint32_t context_available_length = 0;
168 struct tevent_req *tsubreq;
170 status = smbd_smb2_request_verify_sizes(smb2req, 0x39);
171 if (!NT_STATUS_IS_OK(status)) {
172 return smbd_smb2_request_error(smb2req, status);
174 inbody = SMBD_SMB2_IN_BODY_PTR(smb2req);
176 in_oplock_level = CVAL(inbody, 0x03);
177 in_impersonation_level = IVAL(inbody, 0x04);
178 in_desired_access = IVAL(inbody, 0x18);
179 in_file_attributes = IVAL(inbody, 0x1C);
180 in_share_access = IVAL(inbody, 0x20);
181 in_create_disposition = IVAL(inbody, 0x24);
182 in_create_options = IVAL(inbody, 0x28);
183 in_name_offset = SVAL(inbody, 0x2C);
184 in_name_length = SVAL(inbody, 0x2E);
185 in_context_offset = IVAL(inbody, 0x30);
186 in_context_length = IVAL(inbody, 0x34);
189 * First check if the dynamic name and context buffers
190 * are correctly specified.
192 * Note: That we don't check if the name and context buffers
196 dyn_offset = SMB2_HDR_BODY + SMBD_SMB2_IN_BODY_LEN(smb2req);
198 if (in_name_offset == 0 && in_name_length == 0) {
201 } else if (in_name_offset < dyn_offset) {
202 return smbd_smb2_request_error(smb2req, NT_STATUS_INVALID_PARAMETER);
204 name_offset = in_name_offset - dyn_offset;
207 indyniov = SMBD_SMB2_IN_DYN_IOV(smb2req);
209 if (name_offset > indyniov->iov_len) {
210 return smbd_smb2_request_error(smb2req, NT_STATUS_INVALID_PARAMETER);
213 name_available_length = indyniov->iov_len - name_offset;
215 if (in_name_length > name_available_length) {
216 return smbd_smb2_request_error(smb2req, NT_STATUS_INVALID_PARAMETER);
219 in_name_buffer.data = (uint8_t *)indyniov->iov_base + name_offset;
220 in_name_buffer.length = in_name_length;
222 if (in_context_offset == 0 && in_context_length == 0) {
225 } else if (in_context_offset < dyn_offset) {
226 return smbd_smb2_request_error(smb2req, NT_STATUS_INVALID_PARAMETER);
228 context_offset = in_context_offset - dyn_offset;
231 if (context_offset > indyniov->iov_len) {
232 return smbd_smb2_request_error(smb2req, NT_STATUS_INVALID_PARAMETER);
235 context_available_length = indyniov->iov_len - context_offset;
237 if (in_context_length > context_available_length) {
238 return smbd_smb2_request_error(smb2req, NT_STATUS_INVALID_PARAMETER);
241 in_context_buffer.data = (uint8_t *)indyniov->iov_base +
243 in_context_buffer.length = in_context_length;
246 * Now interpret the name and context buffers
249 ok = convert_string_talloc(smb2req, CH_UTF16, CH_UNIX,
251 in_name_buffer.length,
253 &in_name_string_size);
255 return smbd_smb2_request_error(smb2req, NT_STATUS_ILLEGAL_CHARACTER);
258 if (in_name_buffer.length == 0) {
259 in_name_string_size = 0;
262 if (strlen(in_name_string) != in_name_string_size) {
263 return smbd_smb2_request_error(smb2req, NT_STATUS_OBJECT_NAME_INVALID);
266 ZERO_STRUCT(in_context_blobs);
267 status = smb2_create_blob_parse(smb2req, in_context_buffer, &in_context_blobs);
268 if (!NT_STATUS_IS_OK(status)) {
269 return smbd_smb2_request_error(smb2req, status);
272 if (CHECK_DEBUGLVL(DBGLVL_DEBUG)) {
273 char *str = talloc_asprintf(
275 "\nGot %"PRIu32" create blobs\n",
276 in_context_blobs.num_blobs);
279 for (i=0; i<in_context_blobs.num_blobs; i++) {
280 struct smb2_create_blob *b =
281 &in_context_blobs.blobs[i];
282 talloc_asprintf_addbuf(&str, "[%"PRIu32"]\n", i);
284 (uint8_t *)b->tag, strlen(b->tag), &str);
286 b->data.data, b->data.length, &str);
288 DBG_DEBUG("%s", str);
292 tsubreq = smbd_smb2_create_send(smb2req,
293 smb2req->sconn->ev_ctx,
296 in_impersonation_level,
300 in_create_disposition,
304 if (tsubreq == NULL) {
305 smb2req->subreq = NULL;
306 return smbd_smb2_request_error(smb2req, NT_STATUS_NO_MEMORY);
308 tevent_req_set_callback(tsubreq, smbd_smb2_request_create_done, smb2req);
310 return smbd_smb2_request_pending_queue(smb2req, tsubreq, 500);
313 static uint64_t get_mid_from_smb2req(struct smbd_smb2_request *smb2req)
315 uint8_t *reqhdr = SMBD_SMB2_OUT_HDR_PTR(smb2req);
316 return BVAL(reqhdr, SMB2_HDR_MESSAGE_ID);
319 static void smbd_smb2_request_create_done(struct tevent_req *tsubreq)
321 struct smbd_smb2_request *smb2req = tevent_req_callback_data(tsubreq,
322 struct smbd_smb2_request);
325 uint8_t out_oplock_level = 0;
326 uint32_t out_create_action = 0;
327 connection_struct *conn = smb2req->tcon->compat;
328 struct timespec out_creation_ts = { 0, };
329 struct timespec out_last_access_ts = { 0, };
330 struct timespec out_last_write_ts = { 0, };
331 struct timespec out_change_ts = { 0, };
332 uint64_t out_allocation_size = 0;
333 uint64_t out_end_of_file = 0;
334 uint32_t out_file_attributes = 0;
335 uint64_t out_file_id_persistent = 0;
336 uint64_t out_file_id_volatile = 0;
337 struct smb2_create_blobs out_context_blobs;
338 DATA_BLOB out_context_buffer;
339 uint16_t out_context_buffer_offset = 0;
341 NTSTATUS error; /* transport error */
343 status = smbd_smb2_create_recv(tsubreq,
351 &out_allocation_size,
353 &out_file_attributes,
354 &out_file_id_persistent,
355 &out_file_id_volatile,
357 if (!NT_STATUS_IS_OK(status)) {
358 if (smbd_smb2_is_compound(smb2req)) {
359 smb2req->compound_create_err = status;
361 error = smbd_smb2_request_error(smb2req, status);
362 if (!NT_STATUS_IS_OK(error)) {
363 smbd_server_connection_terminate(smb2req->xconn,
370 status = smb2_create_blob_push(smb2req, &out_context_buffer, out_context_blobs);
371 if (!NT_STATUS_IS_OK(status)) {
372 error = smbd_smb2_request_error(smb2req, status);
373 if (!NT_STATUS_IS_OK(error)) {
374 smbd_server_connection_terminate(smb2req->xconn,
381 if (out_context_buffer.length > 0) {
382 out_context_buffer_offset = SMB2_HDR_BODY + 0x58;
385 outbody = smbd_smb2_generate_outbody(smb2req, 0x58);
386 if (outbody.data == NULL) {
387 error = smbd_smb2_request_error(smb2req, NT_STATUS_NO_MEMORY);
388 if (!NT_STATUS_IS_OK(error)) {
389 smbd_server_connection_terminate(smb2req->xconn,
396 SSVAL(outbody.data, 0x00, 0x58 + 1); /* struct size */
397 SCVAL(outbody.data, 0x02,
398 out_oplock_level); /* oplock level */
399 SCVAL(outbody.data, 0x03, 0); /* reserved */
400 SIVAL(outbody.data, 0x04,
401 out_create_action); /* create action */
402 put_long_date_full_timespec(conn->ts_res,
403 (char *)outbody.data + 0x08,
404 &out_creation_ts); /* creation time */
405 put_long_date_full_timespec(conn->ts_res,
406 (char *)outbody.data + 0x10,
407 &out_last_access_ts); /* last access time */
408 put_long_date_full_timespec(conn->ts_res,
409 (char *)outbody.data + 0x18,
410 &out_last_write_ts); /* last write time */
411 put_long_date_full_timespec(conn->ts_res,
412 (char *)outbody.data + 0x20,
413 &out_change_ts); /* change time */
414 SBVAL(outbody.data, 0x28,
415 out_allocation_size); /* allocation size */
416 SBVAL(outbody.data, 0x30,
417 out_end_of_file); /* end of file */
418 SIVAL(outbody.data, 0x38,
419 out_file_attributes); /* file attributes */
420 SIVAL(outbody.data, 0x3C, 0); /* reserved */
421 SBVAL(outbody.data, 0x40,
422 out_file_id_persistent); /* file id (persistent) */
423 SBVAL(outbody.data, 0x48,
424 out_file_id_volatile); /* file id (volatile) */
425 SIVAL(outbody.data, 0x50,
426 out_context_buffer_offset); /* create contexts offset */
427 SIVAL(outbody.data, 0x54,
428 out_context_buffer.length); /* create contexts length */
430 outdyn = out_context_buffer;
432 error = smbd_smb2_request_done(smb2req, outbody, &outdyn);
433 if (!NT_STATUS_IS_OK(error)) {
434 smbd_server_connection_terminate(smb2req->xconn,
440 static bool smb2_lease_key_valid(const struct smb2_lease_key *key)
442 return ((key->data[0] != 0) || (key->data[1] != 0));
445 static NTSTATUS smbd_smb2_create_durable_lease_check(struct smb_request *smb1req,
446 const char *requested_filename, const struct files_struct *fsp,
447 const struct smb2_lease *lease_ptr)
449 struct files_struct *dirfsp = NULL;
450 char *filename = NULL;
451 struct smb_filename *smb_fname = NULL;
453 NTTIME twrp = fsp->fsp_name->twrp;
455 bool is_dfs = (smb1req->flags2 & FLAGS2_DFS_PATHNAMES);
456 bool is_posix = (fsp->fsp_name->flags & SMB_FILENAME_POSIX_PATH);
458 if (lease_ptr == NULL) {
459 if (fsp->oplock_type != LEASE_OPLOCK) {
462 DEBUG(10, ("Reopened file has lease, but no lease "
464 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
467 if (fsp->oplock_type != LEASE_OPLOCK) {
468 DEBUG(10, ("Lease requested, but reopened file has no "
470 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
473 if (!smb2_lease_key_equal(&lease_ptr->lease_key,
474 &fsp->lease->lease.lease_key)) {
475 DEBUG(10, ("Different lease key requested than found "
476 "in reopened file\n"));
477 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
481 const char *non_dfs_requested_filename = NULL;
483 * With a DFS flag set, remove any DFS prefix
484 * before further processing.
486 status = smb2_strip_dfs_path(requested_filename,
487 &non_dfs_requested_filename);
488 if (!NT_STATUS_IS_OK(status)) {
492 * TODO: Note for dealing with reparse point errors.
493 * We will need to remember and store the number of characters
494 * we have removed here, which is
495 * (requested_filename - non_dfs_requested_filename)
496 * in order to correctly report how many characters we
497 * have removed before hitting the reparse point.
498 * This will be a patch needed once we properly
499 * deal with reparse points later.
501 requested_filename = non_dfs_requested_filename;
503 * Now we're no longer dealing with a DFS path, so
506 smb1req->flags2 &= ~FLAGS2_DFS_PATHNAMES;
510 filename = talloc_strdup(talloc_tos(), requested_filename);
511 if (filename == NULL) {
512 return NT_STATUS_NO_MEMORY;
515 /* This also converts '\' to '/' */
516 status = check_path_syntax(filename, is_posix);
517 if (!NT_STATUS_IS_OK(status)) {
518 TALLOC_FREE(filename);
522 ucf_flags = filename_create_ucf_flags(smb1req, FILE_OPEN);
523 status = filename_convert_dirfsp(talloc_tos(),
530 TALLOC_FREE(filename);
531 if (!NT_STATUS_IS_OK(status)) {
532 DEBUG(10, ("filename_convert returned %s\n",
537 if (!strequal(fsp->fsp_name->base_name, smb_fname->base_name)) {
538 DEBUG(10, ("Lease requested for file %s, reopened file "
539 "is named %s\n", smb_fname->base_name,
540 fsp->fsp_name->base_name));
541 TALLOC_FREE(smb_fname);
542 return NT_STATUS_INVALID_PARAMETER;
545 TALLOC_FREE(smb_fname);
550 struct smbd_smb2_create_state {
551 struct tevent_context *ev;
552 struct smbd_smb2_request *smb2req;
553 struct GUID req_guid;
554 struct smb_request *smb1req;
555 bool open_was_deferred;
556 struct tevent_immediate *im;
557 struct timeval request_time;
559 struct deferred_open_record *open_rec;
560 files_struct *result;
561 bool replay_operation;
562 uint8_t in_oplock_level;
563 uint32_t in_create_disposition;
564 int requested_oplock_level;
567 struct ea_list *ea_list;
568 NTTIME max_access_time;
569 struct security_descriptor *sec_desc;
570 uint64_t allocation_size;
571 struct GUID _create_guid;
572 struct GUID *create_guid;
573 struct GUID _purge_create_guid;
574 struct GUID *purge_create_guid;
576 bool durable_requested;
577 uint32_t durable_timeout_msec;
578 bool do_durable_reconnect;
579 uint64_t persistent_id;
580 struct smb2_lease lease;
581 struct smb2_lease *lease_ptr;
583 bool need_replay_cache;
584 struct smbXsrv_open *op;
587 struct smb2_create_blob *dhnc;
588 struct smb2_create_blob *dh2c;
589 struct smb2_create_blob *dhnq;
590 struct smb2_create_blob *dh2q;
591 struct smb2_create_blob *rqls;
592 struct smb2_create_blob *exta;
593 struct smb2_create_blob *mxac;
594 struct smb2_create_blob *secd;
595 struct smb2_create_blob *alsi;
596 struct smb2_create_blob *twrp;
597 struct smb2_create_blob *qfid;
598 struct smb2_create_blob *posx;
599 struct smb2_create_blob *svhdx;
601 uint8_t out_oplock_level;
602 uint32_t out_create_action;
603 struct timespec out_creation_ts;
604 struct timespec out_last_access_ts;
605 struct timespec out_last_write_ts;
606 struct timespec out_change_ts;
607 uint64_t out_allocation_size;
608 uint64_t out_end_of_file;
609 uint32_t out_file_attributes;
610 uint64_t out_file_id_persistent;
611 uint64_t out_file_id_volatile;
612 struct smb2_create_blobs *out_context_blobs;
615 static void smbd_smb2_create_purge_replay_cache(struct tevent_req *req,
616 const char *caller_func);
618 static void smbd_smb2_create_cleanup(struct tevent_req *req,
619 enum tevent_req_state req_state)
621 smbd_smb2_create_purge_replay_cache(req, __func__);
624 static NTSTATUS smbd_smb2_create_fetch_create_ctx(
625 struct tevent_req *req,
626 struct smb2_create_blobs *in_context_blobs)
628 struct smbd_smb2_create_state *state = tevent_req_data(
629 req, struct smbd_smb2_create_state);
630 struct smbd_smb2_request *smb2req = state->smb2req;
631 struct smbXsrv_connection *xconn = smb2req->xconn;
633 state->dhnq = smb2_create_blob_find(in_context_blobs,
634 SMB2_CREATE_TAG_DHNQ);
635 state->dhnc = smb2_create_blob_find(in_context_blobs,
636 SMB2_CREATE_TAG_DHNC);
637 state->dh2q = smb2_create_blob_find(in_context_blobs,
638 SMB2_CREATE_TAG_DH2Q);
639 state->dh2c = smb2_create_blob_find(in_context_blobs,
640 SMB2_CREATE_TAG_DH2C);
641 if (xconn->smb2.server.capabilities & SMB2_CAP_LEASING) {
642 state->rqls = smb2_create_blob_find(in_context_blobs,
643 SMB2_CREATE_TAG_RQLS);
646 if (((state->dhnc != NULL) && (state->dh2c != NULL)) ||
647 ((state->dhnc != NULL) && (state->dh2q != NULL)) ||
648 ((state->dh2c != NULL) && (state->dhnq != NULL)) ||
649 ((state->dh2q != NULL) && (state->dh2c != NULL)))
651 /* not both are allowed at the same time */
652 return NT_STATUS_INVALID_PARAMETER;
655 if (state->dhnc != NULL) {
656 uint32_t num_blobs_allowed;
658 if (state->dhnc->data.length != 16) {
659 return NT_STATUS_INVALID_PARAMETER;
663 * According to MS-SMB2: 3.3.5.9.7, "Handling the
664 * SMB2_CREATE_DURABLE_HANDLE_RECONNECT Create Context",
665 * we should ignore an additional dhnq blob, but fail
666 * the request (with status OBJECT_NAME_NOT_FOUND) if
667 * any other extra create blob has been provided.
669 * (Note that the cases of an additional dh2q or dh2c blob
670 * which require a different error code, have been treated
674 if (state->dhnq != NULL) {
675 num_blobs_allowed = 2;
677 num_blobs_allowed = 1;
680 if (state->rqls != NULL) {
681 num_blobs_allowed += 1;
684 if (in_context_blobs->num_blobs != num_blobs_allowed) {
685 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
689 if (state->dh2c!= NULL) {
690 uint32_t num_blobs_allowed;
692 if (state->dh2c->data.length != 36) {
693 return NT_STATUS_INVALID_PARAMETER;
697 * According to MS-SMB2: 3.3.5.9.12, "Handling the
698 * SMB2_CREATE_DURABLE_HANDLE_RECONNECT_V2 Create Context",
699 * we should fail the request with status
700 * OBJECT_NAME_NOT_FOUND if any other create blob has been
703 * (Note that the cases of an additional dhnq, dhnc or dh2q
704 * blob which require a different error code, have been
708 num_blobs_allowed = 1;
710 if (state->rqls != NULL) {
711 num_blobs_allowed += 1;
714 if (in_context_blobs->num_blobs != num_blobs_allowed) {
715 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
719 state->exta = smb2_create_blob_find(in_context_blobs,
720 SMB2_CREATE_TAG_EXTA);
721 state->mxac = smb2_create_blob_find(in_context_blobs,
722 SMB2_CREATE_TAG_MXAC);
723 state->secd = smb2_create_blob_find(in_context_blobs,
724 SMB2_CREATE_TAG_SECD);
725 state->alsi = smb2_create_blob_find(in_context_blobs,
726 SMB2_CREATE_TAG_ALSI);
727 state->twrp = smb2_create_blob_find(in_context_blobs,
728 SMB2_CREATE_TAG_TWRP);
729 state->qfid = smb2_create_blob_find(in_context_blobs,
730 SMB2_CREATE_TAG_QFID);
731 if (xconn->protocol >= PROTOCOL_SMB3_02) {
733 * This was introduced with SMB3_02
735 state->svhdx = smb2_create_blob_find(
736 in_context_blobs, SVHDX_OPEN_DEVICE_CONTEXT);
738 if (xconn->smb2.server.posix_extensions_negotiated) {
740 * Negprot only allowed this for proto>=3.11
742 SMB_ASSERT(xconn->protocol >= PROTOCOL_SMB3_11);
744 state->posx = smb2_create_blob_find(
745 in_context_blobs, SMB2_CREATE_TAG_POSIX);
747 * Setting the bool below will cause
748 * ucf_flags_from_smb_request() to
749 * return UCF_POSIX_PATHNAMES in ucf_flags.
751 state->smb1req->posix_pathnames = (state->posx != NULL);
757 static void smbd_smb2_create_before_exec(struct tevent_req *req);
758 static void smbd_smb2_create_after_exec(struct tevent_req *req);
759 static void smbd_smb2_create_finish(struct tevent_req *req);
761 static struct tevent_req *smbd_smb2_create_send(TALLOC_CTX *mem_ctx,
762 struct tevent_context *ev,
763 struct smbd_smb2_request *smb2req,
764 uint8_t in_oplock_level,
765 uint32_t in_impersonation_level,
766 uint32_t in_desired_access,
767 uint32_t in_file_attributes,
768 uint32_t in_share_access,
769 uint32_t in_create_disposition,
770 uint32_t in_create_options,
772 struct smb2_create_blobs in_context_blobs)
774 struct tevent_req *req = NULL;
775 struct smbd_smb2_create_state *state = NULL;
777 struct smb_request *smb1req = NULL;
778 struct files_struct *dirfsp = NULL;
779 struct smb_filename *smb_fname = NULL;
782 bool is_posix = false;
784 req = tevent_req_create(mem_ctx, &state,
785 struct smbd_smb2_create_state);
789 *state = (struct smbd_smb2_create_state) {
792 .in_oplock_level = in_oplock_level,
793 .in_create_disposition = in_create_disposition,
796 smb1req = smbd_smb2_fake_smb_request(smb2req, NULL);
797 if (tevent_req_nomem(smb1req, req)) {
798 return tevent_req_post(req, state->ev);
800 state->smb1req = smb1req;
802 state->req_guid = smbd_request_guid(smb1req, 0);
804 tevent_req_set_cleanup_fn(req, smbd_smb2_create_cleanup);
806 if (smb2req->subreq == NULL) {
807 DBG_DEBUG("name [%s]\n", in_name);
809 struct smbd_smb2_create_state *old_state = tevent_req_data(
810 smb2req->subreq, struct smbd_smb2_create_state);
812 DBG_DEBUG("reentrant for file %s\n", in_name);
814 state->id = old_state->id;
815 state->request_time = old_state->request_time;
816 state->open_rec = talloc_move(state, &old_state->open_rec);
817 state->open_was_deferred = old_state->open_was_deferred;
818 state->_purge_create_guid = old_state->_purge_create_guid;
819 state->purge_create_guid = old_state->purge_create_guid;
820 old_state->purge_create_guid = NULL;
823 TALLOC_FREE(smb2req->subreq);
824 smb2req->subreq = req;
826 if (lp_fake_oplocks(SNUM(smb2req->tcon->compat))) {
827 state->requested_oplock_level = SMB2_OPLOCK_LEVEL_NONE;
829 state->requested_oplock_level = state->in_oplock_level;
832 /* these are ignored for SMB2 */
833 in_create_options &= ~(0x10);/* NTCREATEX_OPTIONS_SYNC_ALERT */
834 in_create_options &= ~(0x20);/* NTCREATEX_OPTIONS_ASYNC_ALERT */
836 in_file_attributes &= ~FILE_FLAG_POSIX_SEMANTICS;
838 is_dfs = (smb1req->flags2 & FLAGS2_DFS_PATHNAMES);
840 const char *non_dfs_in_name = NULL;
842 * With a DFS flag set, remove any DFS prefix
843 * before further processing.
845 status = smb2_strip_dfs_path(in_name, &non_dfs_in_name);
846 if (!NT_STATUS_IS_OK(status)) {
847 tevent_req_nterror(req, status);
848 return tevent_req_post(req, state->ev);
851 * TODO: Note for dealing with reparse point errors.
852 * We will need to remember and store the number of characters
853 * we have removed here, which is (non_dfs_in_name - in_name)
854 * in order to correctly report how many characters we
855 * have removed before hitting the reparse point.
856 * This will be a patch needed once we properly
857 * deal with reparse points later.
859 in_name = non_dfs_in_name;
861 * Now we're no longer dealing with a DFS path, so
864 smb1req->flags2 &= ~FLAGS2_DFS_PATHNAMES;
868 state->fname = talloc_strdup(state, in_name);
869 if (tevent_req_nomem(state->fname, req)) {
870 return tevent_req_post(req, state->ev);
873 state->out_context_blobs = talloc_zero(state, struct smb2_create_blobs);
874 if (tevent_req_nomem(state->out_context_blobs, req)) {
875 return tevent_req_post(req, state->ev);
878 status = smbd_smb2_create_fetch_create_ctx(req, &in_context_blobs);
879 if (tevent_req_nterror(req, status)) {
880 return tevent_req_post(req, state->ev);
883 if (IS_IPC(smb1req->conn)) {
884 const char *pipe_name = in_name;
886 if (state->dhnc != NULL || state->dh2c != NULL) {
887 /* durable handles are not supported on IPC$ */
888 tevent_req_nterror(req, NT_STATUS_OBJECT_NAME_NOT_FOUND);
889 return tevent_req_post(req, state->ev);
892 if (!lp_nt_pipe_support()) {
893 tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
894 return tevent_req_post(req, state->ev);
897 status = open_np_file(smb1req, pipe_name, &state->result);
898 if (tevent_req_nterror(req, status)) {
899 return tevent_req_post(req, state->ev);
901 state->info = FILE_WAS_OPENED;
903 smbd_smb2_create_finish(req);
907 if (CAN_PRINT(smb1req->conn)) {
908 if (state->dhnc != NULL || state->dh2c != NULL) {
909 /* durable handles are not supported on printers */
910 tevent_req_nterror(req, NT_STATUS_OBJECT_NAME_NOT_FOUND);
911 return tevent_req_post(req, state->ev);
914 status = file_new(smb1req, smb1req->conn, &state->result);
915 if (tevent_req_nterror(req, status)) {
916 return tevent_req_post(req, state->ev);
919 status = print_spool_open(state->result, in_name,
921 if (tevent_req_nterror(req, status)) {
922 file_free(smb1req, state->result);
923 return tevent_req_post(req, state->ev);
925 state->info = FILE_WAS_CREATED;
927 smbd_smb2_create_finish(req);
931 /* Check for trailing slash specific directory handling. */
932 status = windows_name_trailing_check(state->fname, in_create_options);
933 if (tevent_req_nterror(req, status)) {
934 return tevent_req_post(req, state->ev);
937 smbd_smb2_create_before_exec(req);
938 if (!tevent_req_is_in_progress(req)) {
939 return tevent_req_post(req, state->ev);
942 DBG_DEBUG("open execution phase\n");
945 * For the backend file open procedure, there are
946 * three possible modes: replay operation (in which case
947 * there is nothing else to do), durable_reconnect or
950 if (state->replay_operation) {
951 state->result = state->op->compat;
952 state->result->op = state->op;
953 state->update_open = false;
954 state->info = state->op->create_action;
956 smbd_smb2_create_after_exec(req);
957 if (!tevent_req_is_in_progress(req)) {
958 return tevent_req_post(req, state->ev);
961 smbd_smb2_create_finish(req);
965 if (state->do_durable_reconnect) {
966 DATA_BLOB new_cookie = data_blob_null;
967 NTTIME now = timeval_to_nttime(&smb2req->request_time);
969 status = smb2srv_open_recreate(smb2req->xconn,
970 smb1req->conn->session_info,
971 state->persistent_id,
975 if (tevent_req_nterror(req, status)) {
976 DBG_NOTICE("smb2srv_open_recreate failed: %s\n",
978 return tevent_req_post(req, state->ev);
981 DBG_DEBUG("%s to recreate durable handle\n",
982 state->op->global->durable ? "succeeded" : "failed");
984 if (!state->op->global->durable) {
985 talloc_free(state->op);
986 tevent_req_nterror(req,
987 NT_STATUS_OBJECT_NAME_NOT_FOUND);
988 return tevent_req_post(req, state->ev);
991 status = SMB_VFS_DURABLE_RECONNECT(smb1req->conn,
993 state->op, /* smbXsrv_open input */
994 state->op->global->backend_cookie,
995 state->op, /* TALLOC_CTX */
998 if (!NT_STATUS_IS_OK(status)) {
999 NTSTATUS return_status;
1001 return_status = NT_STATUS_OBJECT_NAME_NOT_FOUND;
1003 DBG_NOTICE("durable_reconnect failed: %s => %s\n",
1005 nt_errstr(return_status));
1007 tevent_req_nterror(req, return_status);
1008 return tevent_req_post(req, state->ev);
1011 DBG_DEBUG("oplock_type=%u, lease_ptr==%p\n",
1012 (unsigned)state->result->oplock_type, state->lease_ptr);
1014 status = smbd_smb2_create_durable_lease_check(
1015 smb1req, state->fname, state->result, state->lease_ptr);
1016 if (tevent_req_nterror(req, status)) {
1018 smb1req, &state->result, SHUTDOWN_CLOSE);
1019 return tevent_req_post(req, state->ev);
1022 data_blob_free(&state->op->global->backend_cookie);
1023 state->op->global->backend_cookie = new_cookie;
1025 state->op->status = NT_STATUS_OK;
1026 state->op->global->disconnect_time = 0;
1028 /* save the timeout for later update */
1029 state->durable_timeout_msec = state->op->global->durable_timeout_msec;
1031 state->update_open = true;
1033 state->info = FILE_WAS_OPENED;
1035 smbd_smb2_create_after_exec(req);
1036 if (!tevent_req_is_in_progress(req)) {
1037 return tevent_req_post(req, state->ev);
1040 smbd_smb2_create_finish(req);
1044 if (state->requested_oplock_level == SMB2_OPLOCK_LEVEL_LEASE) {
1045 if (state->lease_ptr == NULL) {
1046 state->requested_oplock_level = SMB2_OPLOCK_LEVEL_NONE;
1049 state->lease_ptr = NULL;
1052 is_posix = (state->posx != NULL);
1054 /* convert '\\' into '/' */
1055 status = check_path_syntax(state->fname, is_posix);
1056 if (tevent_req_nterror(req, status)) {
1057 return tevent_req_post(req, state->ev);
1060 ucf_flags = filename_create_ucf_flags(
1061 smb1req, state->in_create_disposition);
1063 status = filename_convert_dirfsp(
1071 if (tevent_req_nterror(req, status)) {
1072 return tevent_req_post(req, state->ev);
1076 * MS-SMB2: 2.2.13 SMB2 CREATE Request
1077 * ImpersonationLevel ... MUST contain one of the
1078 * following values. The server MUST validate this
1079 * field, but otherwise ignore it.
1081 * NB. The source4/torture/smb2/durable_open.c test
1082 * shows this check is only done on real opens, not
1083 * on durable handle-reopens.
1086 if (in_impersonation_level >
1087 SMB2_IMPERSONATION_DELEGATE) {
1088 tevent_req_nterror(req,
1089 NT_STATUS_BAD_IMPERSONATION_LEVEL);
1090 return tevent_req_post(req, state->ev);
1094 * We know we're going to do a local open, so now
1095 * we must be protocol strict. JRA.
1097 * MS-SMB2: 3.3.5.9 - Receiving an SMB2 CREATE Request
1098 * If the file name length is greater than zero and the
1099 * first character is a path separator character, the
1100 * server MUST fail the request with
1101 * STATUS_INVALID_PARAMETER.
1103 if (in_name[0] == '/') {
1104 /* Names starting with '/' are never allowed. */
1105 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
1106 return tevent_req_post(req, ev);
1108 if (!is_posix && (in_name[0] == '\\')) {
1110 * Windows names starting with '\' are not allowed.
1112 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
1113 return tevent_req_post(req, ev);
1116 status = SMB_VFS_CREATE_FILE(smb1req->conn,
1122 state->in_create_disposition,
1125 map_smb2_oplock_levels_to_samba(
1126 state->requested_oplock_level),
1128 state->allocation_size,
1129 0, /* private_flags */
1135 state->out_context_blobs);
1136 if (!NT_STATUS_IS_OK(status)) {
1137 if (open_was_deferred(smb1req->xconn, smb1req->mid)) {
1138 SMBPROFILE_IOBYTES_ASYNC_SET_IDLE(smb2req->profile);
1141 tevent_req_nterror(req, status);
1142 return tevent_req_post(req, state->ev);
1144 state->op = state->result->op;
1146 smbd_smb2_create_after_exec(req);
1147 if (!tevent_req_is_in_progress(req)) {
1148 return tevent_req_post(req, state->ev);
1151 smbd_smb2_create_finish(req);
1155 static void smbd_smb2_create_purge_replay_cache(struct tevent_req *req,
1156 const char *caller_func)
1158 struct smbd_smb2_create_state *state = tevent_req_data(
1159 req, struct smbd_smb2_create_state);
1162 if (state->purge_create_guid == NULL) {
1166 status = smbXsrv_open_purge_replay_cache(state->smb2req->xconn->client,
1167 state->purge_create_guid);
1168 if (!NT_STATUS_IS_OK(status)) {
1169 struct GUID_txt_buf buf;
1171 D_ERR("%s: smbXsrv_open_purge_replay_cache(%s) %s\n",
1173 GUID_buf_string(state->purge_create_guid, &buf),
1177 state->purge_create_guid = NULL;
1180 static void smbd_smb2_create_before_exec(struct tevent_req *req)
1182 struct smbd_smb2_create_state *state = tevent_req_data(
1183 req, struct smbd_smb2_create_state);
1184 struct smbd_smb2_request *smb2req = state->smb2req;
1187 if (state->exta != NULL) {
1188 if (!lp_ea_support(SNUM(smb2req->tcon->compat))) {
1189 tevent_req_nterror(req, NT_STATUS_EAS_NOT_SUPPORTED);
1193 state->ea_list = read_nttrans_ea_list(
1195 (const char *)state->exta->data.data,
1196 state->exta->data.length);
1197 if (state->ea_list == NULL) {
1198 DEBUG(10,("smbd_smb2_create_send: read_ea_name_list failed.\n"));
1199 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
1203 if ((state->posx == NULL) &&
1204 ea_list_has_invalid_name(state->ea_list)) {
1205 tevent_req_nterror(req, STATUS_INVALID_EA_NAME);
1210 if (state->mxac != NULL) {
1211 if (state->mxac->data.length == 0) {
1212 state->max_access_time = 0;
1213 } else if (state->mxac->data.length == 8) {
1214 state->max_access_time = BVAL(state->mxac->data.data, 0);
1216 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
1221 if (state->secd != NULL) {
1222 enum ndr_err_code ndr_err;
1224 state->sec_desc = talloc_zero(state, struct security_descriptor);
1225 if (tevent_req_nomem(state->sec_desc, req)) {
1229 ndr_err = ndr_pull_struct_blob(&state->secd->data,
1230 state->sec_desc, state->sec_desc,
1231 (ndr_pull_flags_fn_t)ndr_pull_security_descriptor);
1232 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1233 DEBUG(2,("ndr_pull_security_descriptor failed: %s\n",
1234 ndr_errstr(ndr_err)));
1235 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
1240 if (state->dhnq != NULL) {
1241 if (state->dhnq->data.length != 16) {
1242 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
1246 if (state->dh2q != NULL) {
1247 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
1252 * durable handle request is processed below.
1254 state->durable_requested = true;
1256 * Set the timeout to 16 mins.
1258 * TODO: test this against Windows 2012
1259 * as the default for durable v2 is 1 min.
1261 state->durable_timeout_msec = (16*60*1000);
1264 if (state->dh2q != NULL) {
1265 const uint8_t *p = state->dh2q->data.data;
1266 NTTIME now = timeval_to_nttime(&smb2req->request_time);
1267 uint32_t durable_v2_timeout = 0;
1268 DATA_BLOB create_guid_blob;
1272 if (state->dh2q->data.length != 32) {
1273 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
1277 if (state->dhnq != NULL) {
1278 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
1282 durable_v2_timeout = IVAL(p, 0);
1283 create_guid_blob = data_blob_const(p + 16, 16);
1285 status = GUID_from_ndr_blob(&create_guid_blob,
1286 &state->_create_guid);
1287 if (tevent_req_nterror(req, status)) {
1290 state->create_guid = &state->_create_guid;
1293 * we need to store the create_guid later
1295 state->update_open = true;
1298 * And we need to create a cache for replaying the
1301 state->need_replay_cache = true;
1304 * durable handle v2 request processed below
1306 state->durable_requested = true;
1307 state->durable_timeout_msec = MIN(durable_v2_timeout, 300*1000);
1308 if (state->durable_timeout_msec == 0) {
1310 * Set the timeout to 1 min as default.
1312 * This matches Windows 2012.
1314 state->durable_timeout_msec = (60*1000);
1318 * Check for replay operation.
1319 * Only consider it when we have dh2q.
1320 * If we do not have a replay operation, verify that
1321 * the create_guid is not cached for replay.
1323 hdr = SMBD_SMB2_IN_HDR_PTR(smb2req);
1324 flags = IVAL(hdr, SMB2_HDR_FLAGS);
1325 state->replay_operation =
1326 flags & SMB2_HDR_FLAG_REPLAY_OPERATION;
1328 status = smb2srv_open_lookup_replay_cache(smb2req->xconn,
1330 *state->create_guid,
1334 if (NT_STATUS_EQUAL(status, NT_STATUS_FWP_RESERVED)) {
1336 * We've reserved the replay_cache record
1337 * for ourself, indicating we're still
1340 * It means the smbd_smb2_create_cleanup()
1341 * may need to call smbXsrv_open_purge_replay_cache()
1342 * in order to cleanup.
1344 SMB_ASSERT(state->op == NULL);
1345 state->_purge_create_guid = state->_create_guid;
1346 state->purge_create_guid = &state->_purge_create_guid;
1347 status = NT_STATUS_OK;
1348 state->replay_operation = false;
1349 } else if (NT_STATUS_EQUAL(status, NT_STATUS_FILE_NOT_AVAILABLE)) {
1350 tevent_req_nterror(req, status);
1352 } else if (tevent_req_nterror(req, status)) {
1353 DBG_WARNING("smb2srv_open_lookup_replay_cache "
1354 "failed: %s\n", nt_errstr(status));
1356 } else if (!state->replay_operation) {
1358 * If a create without replay operation flag
1359 * is sent but with a create_guid that is
1360 * currently in the replay cache -- fail.
1362 status = NT_STATUS_DUPLICATE_OBJECTID;
1363 (void)tevent_req_nterror(req, status);
1368 if (state->dhnc != NULL) {
1369 state->persistent_id = BVAL(state->dhnc->data.data, 0);
1370 state->do_durable_reconnect = true;
1373 if (state->dh2c != NULL) {
1374 const uint8_t *p = state->dh2c->data.data;
1375 DATA_BLOB create_guid_blob;
1377 state->persistent_id = BVAL(p, 0);
1378 create_guid_blob = data_blob_const(p + 16, 16);
1380 status = GUID_from_ndr_blob(&create_guid_blob,
1381 &state->_create_guid);
1382 if (tevent_req_nterror(req, status)) {
1386 state->create_guid = &state->_create_guid;
1387 state->do_durable_reconnect = true;
1390 if (state->alsi != NULL) {
1391 if (state->alsi->data.length != 8) {
1392 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
1395 state->allocation_size = BVAL(state->alsi->data.data, 0);
1398 if (state->twrp != NULL) {
1399 if (state->twrp->data.length != 8) {
1400 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
1404 state->twrp_time = BVAL(state->twrp->data.data, 0);
1407 if (state->qfid != NULL) {
1408 if (state->qfid->data.length != 0) {
1409 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
1414 if (state->rqls != NULL) {
1415 ssize_t lease_len = -1;
1417 lease_len = smb2_lease_pull(state->rqls->data.data,
1418 state->rqls->data.length,
1420 if (lease_len == -1) {
1422 req, NT_STATUS_INVALID_PARAMETER);
1425 state->lease_ptr = &state->lease;
1427 if (DEBUGLEVEL >= 10) {
1428 DEBUG(10, ("Got lease request size %d\n",
1430 NDR_PRINT_DEBUG(smb2_lease, state->lease_ptr);
1433 if (!smb2_lease_key_valid(&state->lease.lease_key)) {
1434 state->lease_ptr = NULL;
1435 state->requested_oplock_level = SMB2_OPLOCK_LEVEL_NONE;
1438 if ((smb2req->xconn->protocol < PROTOCOL_SMB3_00) &&
1439 (state->lease.lease_version != 1))
1441 DEBUG(10, ("v2 lease key only for SMB3\n"));
1442 state->lease_ptr = NULL;
1446 * Replay with a lease is only allowed if the
1447 * established open carries a lease with the
1450 if (state->replay_operation) {
1451 struct smb2_lease *op_ls =
1452 &state->op->compat->lease->lease;
1453 int op_oplock = state->op->compat->oplock_type;
1455 if (map_samba_oplock_levels_to_smb2(op_oplock)
1456 != SMB2_OPLOCK_LEVEL_LEASE)
1458 status = NT_STATUS_ACCESS_DENIED;
1459 (void)tevent_req_nterror(req, status);
1462 if (!smb2_lease_key_equal(&state->lease.lease_key,
1465 status = NT_STATUS_ACCESS_DENIED;
1466 (void)tevent_req_nterror(req, status);
1472 if (state->posx != NULL) {
1473 if (state->posx->data.length != 4) {
1474 DBG_DEBUG("Got %zu bytes POSX cctx, expected 4\n",
1475 state->posx->data.length);
1476 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
1482 static void smbd_smb2_create_after_exec(struct tevent_req *req)
1484 struct smbd_smb2_create_state *state = tevent_req_data(
1485 req, struct smbd_smb2_create_state);
1486 connection_struct *conn = state->result->conn;
1490 * here we have op == result->op
1493 DBG_DEBUG("response construction phase\n");
1495 state->out_file_attributes = fdos_mode(state->result);
1497 if (state->mxac != NULL) {
1498 NTTIME last_write_time;
1500 last_write_time = full_timespec_to_nt_time(
1501 &state->result->fsp_name->st.st_ex_mtime);
1502 if (last_write_time != state->max_access_time) {
1504 uint32_t max_access_granted;
1505 DATA_BLOB blob = data_blob_const(p, sizeof(p));
1507 status = smbd_calculate_access_mask_fsp(
1511 SEC_FLAG_MAXIMUM_ALLOWED,
1512 &max_access_granted);
1514 SIVAL(p, 0, NT_STATUS_V(status));
1515 SIVAL(p, 4, max_access_granted);
1517 status = smb2_create_blob_add(
1518 state->out_context_blobs,
1519 state->out_context_blobs,
1520 SMB2_CREATE_TAG_MXAC,
1522 if (!NT_STATUS_IS_OK(status)) {
1528 if (!state->replay_operation && state->durable_requested &&
1529 (fsp_lease_type(state->result) & SMB2_LEASE_HANDLE))
1531 status = SMB_VFS_DURABLE_COOKIE(
1534 &state->op->global->backend_cookie);
1535 if (!NT_STATUS_IS_OK(status)) {
1536 state->op->global->backend_cookie = data_blob_null;
1539 if (!state->replay_operation && state->op->global->backend_cookie.length > 0)
1541 state->update_open = true;
1543 state->op->global->durable = true;
1544 state->op->global->durable_timeout_msec = state->durable_timeout_msec;
1547 if (state->update_open) {
1548 state->op->global->create_guid = state->_create_guid;
1549 if (state->need_replay_cache) {
1550 state->op->flags |= SMBXSRV_OPEN_NEED_REPLAY_CACHE;
1553 status = smbXsrv_open_update(state->op);
1554 DEBUG(10, ("smb2_create_send: smbXsrv_open_update "
1556 nt_errstr(status)));
1557 if (!NT_STATUS_IS_OK(status)) {
1562 * We should not purge the replay cache anymore
1563 * as it's attached to the smbXsrv_open record now.
1565 state->purge_create_guid = NULL;
1568 if (state->dhnq != NULL && state->op->global->durable) {
1569 uint8_t p[8] = { 0, };
1570 DATA_BLOB blob = data_blob_const(p, sizeof(p));
1572 status = smb2_create_blob_add(state->out_context_blobs,
1573 state->out_context_blobs,
1574 SMB2_CREATE_TAG_DHNQ,
1576 if (!NT_STATUS_IS_OK(status)) {
1581 if (state->dh2q != NULL && state->op->global->durable &&
1583 * For replay operations, we return the dh2q blob
1584 * in the case of oplocks not based on the state of
1585 * the open, but on whether it could have been granted
1586 * for the request data. In the case of leases instead,
1587 * the state of the open is used...
1589 (!state->replay_operation ||
1590 state->in_oplock_level == SMB2_OPLOCK_LEVEL_BATCH ||
1591 state->in_oplock_level == SMB2_OPLOCK_LEVEL_LEASE))
1593 uint8_t p[8] = { 0, };
1594 DATA_BLOB blob = data_blob_const(p, sizeof(p));
1595 uint32_t durable_v2_response_flags = 0;
1597 SIVAL(p, 0, state->op->global->durable_timeout_msec);
1598 SIVAL(p, 4, durable_v2_response_flags);
1600 status = smb2_create_blob_add(state->out_context_blobs,
1601 state->out_context_blobs,
1602 SMB2_CREATE_TAG_DH2Q,
1604 if (!NT_STATUS_IS_OK(status)) {
1609 if (state->qfid != NULL) {
1611 SMB_STRUCT_STAT *base_sp = state->result->base_fsp ?
1612 &state->result->base_fsp->fsp_name->st :
1613 &state->result->fsp_name->st;
1614 uint64_t file_id = SMB_VFS_FS_FILE_ID(conn, base_sp);
1615 DATA_BLOB blob = data_blob_const(p, sizeof(p));
1619 /* From conversations with Microsoft engineers at
1620 the MS plugfest. The first 8 bytes are the "volume index"
1621 == inode, the second 8 bytes are the "volume id",
1622 == dev. This will be updated in the SMB2 doc. */
1623 SBVAL(p, 0, file_id);
1624 SIVAL(p, 8, base_sp->st_ex_dev);/* FileIndexHigh */
1626 status = smb2_create_blob_add(state->out_context_blobs,
1627 state->out_context_blobs,
1628 SMB2_CREATE_TAG_QFID,
1630 if (!NT_STATUS_IS_OK(status)) {
1635 if ((state->rqls != NULL) && (state->result->oplock_type == LEASE_OPLOCK)) {
1637 struct smb2_lease lease;
1640 lease = state->result->lease->lease;
1642 lease_len = sizeof(buf);
1643 if (lease.lease_version == 1) {
1647 if (!smb2_lease_push(&lease, buf, lease_len)) {
1648 status = NT_STATUS_INTERNAL_ERROR;
1652 status = smb2_create_blob_add(
1653 state, state->out_context_blobs,
1654 SMB2_CREATE_TAG_RQLS,
1655 data_blob_const(buf, lease_len));
1656 if (!NT_STATUS_IS_OK(status)) {
1661 if (state->posx != NULL) {
1662 struct stat_ex *psbuf = &state->result->fsp_name->st;
1663 struct smb3_posix_cc_info cc = {
1664 .nlinks = psbuf->st_ex_nlink,
1665 .posix_perms = unix_perms_to_wire(psbuf->st_ex_mode &
1668 uint8_t buf[sizeof(struct smb3_posix_cc_info)];
1669 struct ndr_push ndr = {
1671 .alloc_size = sizeof(buf),
1672 .fixed_buf_size = true,
1674 enum ndr_err_code ndr_err;
1676 uid_to_sid(&cc.owner, psbuf->st_ex_uid);
1677 gid_to_sid(&cc.group, psbuf->st_ex_gid);
1680 ndr_push_smb3_posix_cc_info(&ndr,
1681 NDR_SCALARS | NDR_BUFFERS,
1683 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1684 status = NT_STATUS_INSUFFICIENT_RESOURCES;
1688 status = smb2_create_blob_add(state->out_context_blobs,
1689 state->out_context_blobs,
1690 SMB2_CREATE_TAG_POSIX,
1693 .length = ndr.offset,
1695 if (!NT_STATUS_IS_OK(status)) {
1703 close_file_free(state->smb1req, &state->result, ERROR_CLOSE);
1704 tevent_req_nterror(req, status);
1707 static void smbd_smb2_create_finish(struct tevent_req *req)
1709 struct smbd_smb2_create_state *state = tevent_req_data(
1710 req, struct smbd_smb2_create_state);
1711 struct smbd_smb2_request *smb2req = state->smb2req;
1712 struct smb_request *smb1req = state->smb1req;
1713 files_struct *result = state->result;
1715 smb2req->compat_chain_fsp = smb1req->chain_fsp;
1717 if (state->replay_operation) {
1718 state->out_oplock_level = state->in_oplock_level;
1719 } else if (lp_fake_oplocks(SNUM(smb2req->tcon->compat))) {
1720 state->out_oplock_level = state->in_oplock_level;
1722 state->out_oplock_level = map_samba_oplock_levels_to_smb2(result->oplock_type);
1725 if ((state->in_create_disposition == FILE_SUPERSEDE)
1726 && (state->info == FILE_WAS_OVERWRITTEN)) {
1727 state->out_create_action = FILE_WAS_SUPERSEDED;
1729 state->out_create_action = state->info;
1731 result->op->create_action = state->out_create_action;
1733 state->out_creation_ts = get_create_timespec(smb1req->conn,
1734 result, result->fsp_name);
1735 state->out_last_access_ts = result->fsp_name->st.st_ex_atime;
1736 state->out_last_write_ts = result->fsp_name->st.st_ex_mtime;
1737 state->out_change_ts = get_change_timespec(smb1req->conn,
1738 result, result->fsp_name);
1740 if (lp_dos_filetime_resolution(SNUM(smb2req->tcon->compat))) {
1741 dos_filetime_timespec(&state->out_creation_ts);
1742 dos_filetime_timespec(&state->out_last_access_ts);
1743 dos_filetime_timespec(&state->out_last_write_ts);
1744 dos_filetime_timespec(&state->out_change_ts);
1747 state->out_allocation_size =
1748 SMB_VFS_GET_ALLOC_SIZE(smb1req->conn, result,
1749 &(result->fsp_name->st));
1750 state->out_end_of_file = result->fsp_name->st.st_ex_size;
1751 if (state->out_file_attributes == 0) {
1752 state->out_file_attributes = FILE_ATTRIBUTE_NORMAL;
1754 state->out_file_id_persistent = result->op->global->open_persistent_id;
1755 state->out_file_id_volatile = result->op->global->open_volatile_id;
1757 DBG_DEBUG("%s - %s\n", fsp_str_dbg(result), fsp_fnum_dbg(result));
1759 tevent_req_done(req);
1760 tevent_req_post(req, state->ev);
1763 static NTSTATUS smbd_smb2_create_recv(struct tevent_req *req,
1764 TALLOC_CTX *mem_ctx,
1765 uint8_t *out_oplock_level,
1766 uint32_t *out_create_action,
1767 struct timespec *out_creation_ts,
1768 struct timespec *out_last_access_ts,
1769 struct timespec *out_last_write_ts,
1770 struct timespec *out_change_ts,
1771 uint64_t *out_allocation_size,
1772 uint64_t *out_end_of_file,
1773 uint32_t *out_file_attributes,
1774 uint64_t *out_file_id_persistent,
1775 uint64_t *out_file_id_volatile,
1776 struct smb2_create_blobs *out_context_blobs)
1779 struct smbd_smb2_create_state *state = tevent_req_data(req,
1780 struct smbd_smb2_create_state);
1782 if (tevent_req_is_nterror(req, &status)) {
1783 tevent_req_received(req);
1787 *out_oplock_level = state->out_oplock_level;
1788 *out_create_action = state->out_create_action;
1789 *out_creation_ts = state->out_creation_ts;
1790 *out_last_access_ts = state->out_last_access_ts;
1791 *out_last_write_ts = state->out_last_write_ts;
1792 *out_change_ts = state->out_change_ts;
1793 *out_allocation_size = state->out_allocation_size;
1794 *out_end_of_file = state->out_end_of_file;
1795 *out_file_attributes = state->out_file_attributes;
1796 *out_file_id_persistent = state->out_file_id_persistent;
1797 *out_file_id_volatile = state->out_file_id_volatile;
1798 *out_context_blobs = *(state->out_context_blobs);
1800 talloc_steal(mem_ctx, state->out_context_blobs->blobs);
1802 tevent_req_received(req);
1803 return NT_STATUS_OK;
1806 /*********************************************************
1807 Code for dealing with deferred opens.
1808 *********************************************************/
1810 bool get_deferred_open_message_state_smb2(struct smbd_smb2_request *smb2req,
1811 struct timeval *p_request_time,
1812 struct deferred_open_record **open_rec)
1814 struct smbd_smb2_create_state *state = NULL;
1815 struct tevent_req *req = NULL;
1820 req = smb2req->subreq;
1824 state = tevent_req_data(req, struct smbd_smb2_create_state);
1828 if (!state->open_was_deferred) {
1831 if (p_request_time) {
1832 *p_request_time = state->request_time;
1834 if (open_rec != NULL) {
1835 *open_rec = state->open_rec;
1840 /*********************************************************
1841 Re-process this call early - requested by message or
1843 *********************************************************/
1845 static struct smbd_smb2_request *find_open_smb2req(
1846 struct smbXsrv_connection *xconn, uint64_t mid)
1848 struct smbd_smb2_request *smb2req;
1850 for (smb2req = xconn->smb2.requests; smb2req; smb2req = smb2req->next) {
1851 uint64_t message_id;
1852 if (smb2req->subreq == NULL) {
1853 /* This message has been processed. */
1856 if (!tevent_req_is_in_progress(smb2req->subreq)) {
1857 /* This message has been processed. */
1860 message_id = get_mid_from_smb2req(smb2req);
1861 if (message_id == mid) {
1868 bool open_was_deferred_smb2(struct smbXsrv_connection *xconn, uint64_t mid)
1870 struct smbd_smb2_create_state *state = NULL;
1871 struct smbd_smb2_request *smb2req;
1873 smb2req = find_open_smb2req(xconn, mid);
1876 DEBUG(10,("open_was_deferred_smb2: mid %llu smb2req == NULL\n",
1877 (unsigned long long)mid));
1880 if (!smb2req->subreq) {
1883 if (!tevent_req_is_in_progress(smb2req->subreq)) {
1886 state = tevent_req_data(smb2req->subreq,
1887 struct smbd_smb2_create_state);
1891 /* It's not in progress if there's no timeout event. */
1892 if (!state->open_was_deferred) {
1896 DEBUG(10,("open_was_deferred_smb2: mid = %llu\n",
1897 (unsigned long long)mid));
1902 static void remove_deferred_open_message_smb2_internal(struct smbd_smb2_request *smb2req,
1905 struct smbd_smb2_create_state *state = NULL;
1907 if (!smb2req->subreq) {
1910 if (!tevent_req_is_in_progress(smb2req->subreq)) {
1913 state = tevent_req_data(smb2req->subreq,
1914 struct smbd_smb2_create_state);
1919 DEBUG(10,("remove_deferred_open_message_smb2_internal: "
1921 (unsigned long long)mid ));
1923 state->open_was_deferred = false;
1924 /* Ensure we don't have any outstanding immediate event. */
1925 TALLOC_FREE(state->im);
1926 TALLOC_FREE(state->open_rec);
1929 void remove_deferred_open_message_smb2(
1930 struct smbXsrv_connection *xconn, uint64_t mid)
1932 struct smbd_smb2_request *smb2req;
1934 smb2req = find_open_smb2req(xconn, mid);
1937 DEBUG(10,("remove_deferred_open_message_smb2: "
1938 "can't find mid %llu\n",
1939 (unsigned long long)mid ));
1942 remove_deferred_open_message_smb2_internal(smb2req, mid);
1945 static void smbd_smb2_create_request_dispatch_immediate(struct tevent_context *ctx,
1946 struct tevent_immediate *im,
1949 struct smbd_smb2_request *smb2req = talloc_get_type_abort(private_data,
1950 struct smbd_smb2_request);
1951 uint64_t mid = get_mid_from_smb2req(smb2req);
1954 DEBUG(10,("smbd_smb2_create_request_dispatch_immediate: "
1955 "re-dispatching mid %llu\n",
1956 (unsigned long long)mid ));
1958 status = smbd_smb2_request_dispatch(smb2req);
1959 if (!NT_STATUS_IS_OK(status)) {
1960 smbd_server_connection_terminate(smb2req->xconn,
1966 bool schedule_deferred_open_message_smb2(
1967 struct smbXsrv_connection *xconn, uint64_t mid)
1969 struct smbd_smb2_create_state *state = NULL;
1970 struct smbd_smb2_request *smb2req;
1972 smb2req = find_open_smb2req(xconn, mid);
1975 DEBUG(10,("schedule_deferred_open_message_smb2: "
1976 "can't find mid %llu\n",
1977 (unsigned long long)mid ));
1980 if (!smb2req->subreq) {
1983 if (!tevent_req_is_in_progress(smb2req->subreq)) {
1986 state = tevent_req_data(smb2req->subreq,
1987 struct smbd_smb2_create_state);
1992 /* Ensure we don't have any outstanding immediate event. */
1993 TALLOC_FREE(state->im);
1996 * This is subtle. We must null out the callback
1997 * before rescheduling, else the first call to
1998 * tevent_req_nterror() causes the _receive()
1999 * function to be called, this causing tevent_req_post()
2002 tevent_req_set_callback(smb2req->subreq, NULL, NULL);
2004 state->im = tevent_create_immediate(smb2req);
2006 smbd_server_connection_terminate(smb2req->xconn,
2007 nt_errstr(NT_STATUS_NO_MEMORY));
2011 DEBUG(10,("schedule_deferred_open_message_smb2: "
2012 "re-processing mid %llu\n",
2013 (unsigned long long)mid ));
2015 tevent_schedule_immediate(state->im,
2016 smb2req->sconn->ev_ctx,
2017 smbd_smb2_create_request_dispatch_immediate,
2023 static bool smbd_smb2_create_cancel(struct tevent_req *req)
2025 struct smbd_smb2_request *smb2req = NULL;
2026 struct smbd_smb2_create_state *state = tevent_req_data(req,
2027 struct smbd_smb2_create_state);
2034 if (!state->smb2req) {
2038 smb2req = state->smb2req;
2039 mid = get_mid_from_smb2req(smb2req);
2041 if (is_deferred_open_async(state->open_rec)) {
2042 /* Can't cancel an async create. */
2046 remove_deferred_open_message_smb2_internal(smb2req, mid);
2048 tevent_req_defer_callback(req, smb2req->sconn->ev_ctx);
2049 tevent_req_nterror(req, NT_STATUS_CANCELLED);
2053 bool push_deferred_open_message_smb2(struct smbd_smb2_request *smb2req,
2054 struct timeval request_time,
2055 struct timeval timeout,
2057 struct deferred_open_record *open_rec)
2059 struct tevent_req *req = NULL;
2060 struct smbd_smb2_create_state *state = NULL;
2061 struct timeval end_time;
2066 req = smb2req->subreq;
2070 state = tevent_req_data(req, struct smbd_smb2_create_state);
2075 state->request_time = request_time;
2076 state->open_rec = talloc_move(state, &open_rec);
2078 /* Re-schedule us to retry on timer expiry. */
2079 end_time = timeval_sum(&request_time, &timeout);
2081 DEBUG(10,("push_deferred_open_message_smb2: "
2083 timeval_string(talloc_tos(),
2087 state->open_was_deferred = true;
2089 /* allow this request to be canceled */
2090 tevent_req_set_cancel_fn(req, smbd_smb2_create_cancel);