s3: smbd: Allow fchmod from the NFS-style mode ACL in set_nt_acl() for a SMB2 POSIX...
[Samba.git] / source3 / smbd / smb2_create.c
blob8a40717235c4ef61b16abc3ef07cfb05b9b5a2c6
1 /*
2 Unix SMB/CIFS implementation.
3 Core SMB2 server
5 Copyright (C) Stefan Metzmacher 2009
6 Copyright (C) Jeremy Allison 2010
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program. If not, see <http://www.gnu.org/licenses/>.
22 #include "includes.h"
23 #include "printing.h"
24 #include "smbd/smbd.h"
25 #include "smbd/globals.h"
26 #include "smbd/smbXsrv_open.h"
27 #include "../libcli/smb/smb_common.h"
28 #include "../librpc/gen_ndr/ndr_security.h"
29 #include "../librpc/gen_ndr/ndr_smb2_lease_struct.h"
30 #include "../librpc/gen_ndr/ndr_smb3posix.h"
31 #include "../lib/util/tevent_ntstatus.h"
32 #include "messages.h"
33 #include "lib/util_ea.h"
34 #include "source3/passdb/lookup_sid.h"
36 #undef DBGC_CLASS
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:
43 return NO_OPLOCK;
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:
49 return BATCH_OPLOCK;
50 case SMB2_OPLOCK_LEVEL_LEASE:
51 return LEASE_OPLOCK;
52 default:
53 DEBUG(2,("map_smb2_oplock_levels_to_samba: "
54 "unknown level %u\n",
55 (unsigned int)in_oplock_level));
56 return NO_OPLOCK;
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;
70 } else {
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);
90 char trail_c;
92 if (name_len <= 1) {
93 return NT_STATUS_OK;
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;
110 return NT_STATUS_OK;
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,
123 const char *in_name,
124 struct smb2_create_blobs in_context_blobs);
125 static NTSTATUS smbd_smb2_create_recv(struct tevent_req *req,
126 TALLOC_CTX *mem_ctx,
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;
165 uint32_t dyn_offset;
166 NTSTATUS status;
167 bool ok;
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
193 * overlap
196 dyn_offset = SMB2_HDR_BODY + SMBD_SMB2_IN_BODY_LEN(smb2req);
198 if (in_name_offset == 0 && in_name_length == 0) {
199 /* This is ok */
200 name_offset = 0;
201 } else if (in_name_offset < dyn_offset) {
202 return smbd_smb2_request_error(smb2req, NT_STATUS_INVALID_PARAMETER);
203 } else {
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) {
223 /* This is ok */
224 context_offset = 0;
225 } else if (in_context_offset < dyn_offset) {
226 return smbd_smb2_request_error(smb2req, NT_STATUS_INVALID_PARAMETER);
227 } else {
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 +
242 context_offset;
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,
250 in_name_buffer.data,
251 in_name_buffer.length,
252 &in_name_string,
253 &in_name_string_size);
254 if (!ok) {
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(
274 talloc_tos(),
275 "\nGot %"PRIu32" create blobs\n",
276 in_context_blobs.num_blobs);
277 uint32_t i;
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);
283 dump_data_addbuf(
284 (uint8_t *)b->tag, strlen(b->tag), &str);
285 dump_data_addbuf(
286 b->data.data, b->data.length, &str);
288 DBG_DEBUG("%s", str);
289 TALLOC_FREE(str);
292 tsubreq = smbd_smb2_create_send(smb2req,
293 smb2req->sconn->ev_ctx,
294 smb2req,
295 in_oplock_level,
296 in_impersonation_level,
297 in_desired_access,
298 in_file_attributes,
299 in_share_access,
300 in_create_disposition,
301 in_create_options,
302 in_name_string,
303 in_context_blobs);
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);
323 DATA_BLOB outbody;
324 DATA_BLOB outdyn;
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;
340 NTSTATUS status;
341 NTSTATUS error; /* transport error */
343 status = smbd_smb2_create_recv(tsubreq,
344 smb2req,
345 &out_oplock_level,
346 &out_create_action,
347 &out_creation_ts,
348 &out_last_access_ts,
349 &out_last_write_ts,
350 &out_change_ts,
351 &out_allocation_size,
352 &out_end_of_file,
353 &out_file_attributes,
354 &out_file_id_persistent,
355 &out_file_id_volatile,
356 &out_context_blobs);
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,
364 nt_errstr(error));
365 return;
367 return;
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,
375 nt_errstr(error));
376 return;
378 return;
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,
390 nt_errstr(error));
391 return;
393 return;
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,
435 nt_errstr(error));
436 return;
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;
452 uint32_t ucf_flags;
453 NTTIME twrp = fsp->fsp_name->twrp;
454 NTSTATUS status;
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) {
460 return NT_STATUS_OK;
462 DEBUG(10, ("Reopened file has lease, but no lease "
463 "requested\n"));
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 "
469 "lease\n"));
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;
480 if (is_dfs) {
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)) {
489 return 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
504 * remove the flag.
506 smb1req->flags2 &= ~FLAGS2_DFS_PATHNAMES;
507 is_dfs = false;
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);
519 return status;
522 ucf_flags = filename_create_ucf_flags(smb1req, FILE_OPEN);
523 status = filename_convert_dirfsp(talloc_tos(),
524 fsp->conn,
525 filename,
526 ucf_flags,
527 twrp,
528 &dirfsp,
529 &smb_fname);
530 TALLOC_FREE(filename);
531 if (!NT_STATUS_IS_OK(status)) {
532 DEBUG(10, ("filename_convert returned %s\n",
533 nt_errstr(status)));
534 return status;
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);
547 return NT_STATUS_OK;
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;
558 struct file_id id;
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 uint32_t in_create_options;
565 int requested_oplock_level;
566 int info;
567 char *fname;
568 struct ea_list *ea_list;
569 NTTIME max_access_time;
570 struct security_descriptor *sec_desc;
571 uint64_t allocation_size;
572 struct GUID _create_guid;
573 struct GUID *create_guid;
574 struct GUID _purge_create_guid;
575 struct GUID *purge_create_guid;
576 bool update_open;
577 bool durable_requested;
578 uint32_t durable_timeout_msec;
579 bool do_durable_reconnect;
580 uint64_t persistent_id;
581 struct smb2_lease lease;
582 struct smb2_lease *lease_ptr;
583 ssize_t lease_len;
584 bool need_replay_cache;
585 struct smbXsrv_open *op;
586 NTTIME twrp_time;
588 struct smb2_create_blob *dhnc;
589 struct smb2_create_blob *dh2c;
590 struct smb2_create_blob *dhnq;
591 struct smb2_create_blob *dh2q;
592 struct smb2_create_blob *rqls;
593 struct smb2_create_blob *exta;
594 struct smb2_create_blob *mxac;
595 struct smb2_create_blob *secd;
596 struct smb2_create_blob *alsi;
597 struct smb2_create_blob *twrp;
598 struct smb2_create_blob *qfid;
599 struct smb2_create_blob *posx;
600 struct smb2_create_blob *svhdx;
602 uint8_t out_oplock_level;
603 uint32_t out_create_action;
604 struct timespec out_creation_ts;
605 struct timespec out_last_access_ts;
606 struct timespec out_last_write_ts;
607 struct timespec out_change_ts;
608 uint64_t out_allocation_size;
609 uint64_t out_end_of_file;
610 uint32_t out_file_attributes;
611 uint64_t out_file_id_persistent;
612 uint64_t out_file_id_volatile;
613 struct smb2_create_blobs *out_context_blobs;
616 static void smbd_smb2_create_purge_replay_cache(struct tevent_req *req,
617 const char *caller_func);
619 static void smbd_smb2_create_cleanup(struct tevent_req *req,
620 enum tevent_req_state req_state)
622 smbd_smb2_create_purge_replay_cache(req, __func__);
625 static NTSTATUS smbd_smb2_create_fetch_create_ctx(
626 struct tevent_req *req,
627 struct smb2_create_blobs *in_context_blobs)
629 struct smbd_smb2_create_state *state = tevent_req_data(
630 req, struct smbd_smb2_create_state);
631 struct smbd_smb2_request *smb2req = state->smb2req;
632 struct smbXsrv_connection *xconn = smb2req->xconn;
634 state->dhnq = smb2_create_blob_find(in_context_blobs,
635 SMB2_CREATE_TAG_DHNQ);
636 state->dhnc = smb2_create_blob_find(in_context_blobs,
637 SMB2_CREATE_TAG_DHNC);
638 state->dh2q = smb2_create_blob_find(in_context_blobs,
639 SMB2_CREATE_TAG_DH2Q);
640 state->dh2c = smb2_create_blob_find(in_context_blobs,
641 SMB2_CREATE_TAG_DH2C);
642 if (xconn->smb2.server.capabilities & SMB2_CAP_LEASING) {
643 state->rqls = smb2_create_blob_find(in_context_blobs,
644 SMB2_CREATE_TAG_RQLS);
647 if (((state->dhnc != NULL) && (state->dh2c != NULL)) ||
648 ((state->dhnc != NULL) && (state->dh2q != NULL)) ||
649 ((state->dh2c != NULL) && (state->dhnq != NULL)) ||
650 ((state->dh2q != NULL) && (state->dh2c != NULL)))
652 /* not both are allowed at the same time */
653 return NT_STATUS_INVALID_PARAMETER;
656 if (state->dhnc != NULL) {
657 uint32_t num_blobs_allowed;
659 if (state->dhnc->data.length != 16) {
660 return NT_STATUS_INVALID_PARAMETER;
664 * According to MS-SMB2: 3.3.5.9.7, "Handling the
665 * SMB2_CREATE_DURABLE_HANDLE_RECONNECT Create Context",
666 * we should ignore an additional dhnq blob, but fail
667 * the request (with status OBJECT_NAME_NOT_FOUND) if
668 * any other extra create blob has been provided.
670 * (Note that the cases of an additional dh2q or dh2c blob
671 * which require a different error code, have been treated
672 * above.)
675 if (state->dhnq != NULL) {
676 num_blobs_allowed = 2;
677 } else {
678 num_blobs_allowed = 1;
681 if (state->rqls != NULL) {
682 num_blobs_allowed += 1;
685 if (in_context_blobs->num_blobs != num_blobs_allowed) {
686 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
690 if (state->dh2c!= NULL) {
691 uint32_t num_blobs_allowed;
693 if (state->dh2c->data.length != 36) {
694 return NT_STATUS_INVALID_PARAMETER;
698 * According to MS-SMB2: 3.3.5.9.12, "Handling the
699 * SMB2_CREATE_DURABLE_HANDLE_RECONNECT_V2 Create Context",
700 * we should fail the request with status
701 * OBJECT_NAME_NOT_FOUND if any other create blob has been
702 * provided.
704 * (Note that the cases of an additional dhnq, dhnc or dh2q
705 * blob which require a different error code, have been
706 * treated above.)
709 num_blobs_allowed = 1;
711 if (state->rqls != NULL) {
712 num_blobs_allowed += 1;
715 if (in_context_blobs->num_blobs != num_blobs_allowed) {
716 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
720 state->exta = smb2_create_blob_find(in_context_blobs,
721 SMB2_CREATE_TAG_EXTA);
722 state->mxac = smb2_create_blob_find(in_context_blobs,
723 SMB2_CREATE_TAG_MXAC);
724 state->secd = smb2_create_blob_find(in_context_blobs,
725 SMB2_CREATE_TAG_SECD);
726 state->alsi = smb2_create_blob_find(in_context_blobs,
727 SMB2_CREATE_TAG_ALSI);
728 state->twrp = smb2_create_blob_find(in_context_blobs,
729 SMB2_CREATE_TAG_TWRP);
730 state->qfid = smb2_create_blob_find(in_context_blobs,
731 SMB2_CREATE_TAG_QFID);
732 if (xconn->protocol >= PROTOCOL_SMB3_02) {
734 * This was introduced with SMB3_02
736 state->svhdx = smb2_create_blob_find(
737 in_context_blobs, SVHDX_OPEN_DEVICE_CONTEXT);
739 if (xconn->smb2.server.posix_extensions_negotiated &&
740 lp_smb3_unix_extensions(SNUM(state->smb1req->conn)))
743 * Negprot only allowed this for proto>=3.11
745 SMB_ASSERT(xconn->protocol >= PROTOCOL_SMB3_11);
747 state->posx = smb2_create_blob_find(
748 in_context_blobs, SMB2_CREATE_TAG_POSIX);
750 * Setting the bool below will cause
751 * ucf_flags_from_smb_request() to
752 * return UCF_POSIX_PATHNAMES in ucf_flags.
754 state->smb1req->posix_pathnames = (state->posx != NULL);
757 return NT_STATUS_OK;
760 static void smbd_smb2_create_before_exec(struct tevent_req *req);
761 static void smbd_smb2_create_after_exec(struct tevent_req *req);
762 static void smbd_smb2_create_finish(struct tevent_req *req);
764 static struct tevent_req *smbd_smb2_create_send(TALLOC_CTX *mem_ctx,
765 struct tevent_context *ev,
766 struct smbd_smb2_request *smb2req,
767 uint8_t in_oplock_level,
768 uint32_t in_impersonation_level,
769 uint32_t in_desired_access,
770 uint32_t in_file_attributes,
771 uint32_t in_share_access,
772 uint32_t in_create_disposition,
773 uint32_t _in_create_options,
774 const char *in_name,
775 struct smb2_create_blobs in_context_blobs)
777 struct tevent_req *req = NULL;
778 struct smbd_smb2_create_state *state = NULL;
779 NTSTATUS status;
780 struct smb_request *smb1req = NULL;
781 struct files_struct *dirfsp = NULL;
782 struct smb_filename *smb_fname = NULL;
783 uint32_t ucf_flags;
784 bool is_dfs = false;
785 bool is_posix = false;
787 req = tevent_req_create(mem_ctx, &state,
788 struct smbd_smb2_create_state);
789 if (req == NULL) {
790 return NULL;
792 *state = (struct smbd_smb2_create_state) {
793 .ev = ev,
794 .smb2req = smb2req,
795 .in_oplock_level = in_oplock_level,
796 .in_create_disposition = in_create_disposition,
797 .in_create_options = _in_create_options,
800 smb1req = smbd_smb2_fake_smb_request(smb2req, NULL);
801 if (tevent_req_nomem(smb1req, req)) {
802 return tevent_req_post(req, state->ev);
804 state->smb1req = smb1req;
806 state->req_guid = smbd_request_guid(smb1req, 0);
808 tevent_req_set_cleanup_fn(req, smbd_smb2_create_cleanup);
810 if (smb2req->subreq == NULL) {
811 DBG_DEBUG("name [%s]\n", in_name);
812 } else {
813 struct smbd_smb2_create_state *old_state = tevent_req_data(
814 smb2req->subreq, struct smbd_smb2_create_state);
816 DBG_DEBUG("reentrant for file %s\n", in_name);
818 state->id = old_state->id;
819 state->request_time = old_state->request_time;
820 state->open_rec = talloc_move(state, &old_state->open_rec);
821 state->open_was_deferred = old_state->open_was_deferred;
822 state->_purge_create_guid = old_state->_purge_create_guid;
823 state->purge_create_guid = old_state->purge_create_guid;
824 old_state->purge_create_guid = NULL;
827 TALLOC_FREE(smb2req->subreq);
828 smb2req->subreq = req;
830 if (lp_fake_oplocks(SNUM(smb2req->tcon->compat))) {
831 state->requested_oplock_level = SMB2_OPLOCK_LEVEL_NONE;
832 } else {
833 state->requested_oplock_level = state->in_oplock_level;
836 /* these are ignored for SMB2 */
837 state->in_create_options &= ~(0x10); /* NTCREATEX_OPTIONS_SYNC_ALERT */
838 state->in_create_options &= ~(0x20); /* NTCREATEX_OPTIONS_ASYNC_ALERT */
840 in_file_attributes &= ~FILE_FLAG_POSIX_SEMANTICS;
842 is_dfs = (smb1req->flags2 & FLAGS2_DFS_PATHNAMES);
843 if (is_dfs) {
844 const char *non_dfs_in_name = NULL;
846 * With a DFS flag set, remove any DFS prefix
847 * before further processing.
849 status = smb2_strip_dfs_path(in_name, &non_dfs_in_name);
850 if (!NT_STATUS_IS_OK(status)) {
851 tevent_req_nterror(req, status);
852 return tevent_req_post(req, state->ev);
855 * TODO: Note for dealing with reparse point errors.
856 * We will need to remember and store the number of characters
857 * we have removed here, which is (non_dfs_in_name - in_name)
858 * in order to correctly report how many characters we
859 * have removed before hitting the reparse point.
860 * This will be a patch needed once we properly
861 * deal with reparse points later.
863 in_name = non_dfs_in_name;
865 * Now we're no longer dealing with a DFS path, so
866 * remove the flag.
868 smb1req->flags2 &= ~FLAGS2_DFS_PATHNAMES;
869 is_dfs = false;
872 state->fname = talloc_strdup(state, in_name);
873 if (tevent_req_nomem(state->fname, req)) {
874 return tevent_req_post(req, state->ev);
877 state->out_context_blobs = talloc_zero(state, struct smb2_create_blobs);
878 if (tevent_req_nomem(state->out_context_blobs, req)) {
879 return tevent_req_post(req, state->ev);
882 status = smbd_smb2_create_fetch_create_ctx(req, &in_context_blobs);
883 if (tevent_req_nterror(req, status)) {
884 return tevent_req_post(req, state->ev);
887 if (IS_IPC(smb1req->conn)) {
888 const char *pipe_name = in_name;
890 if (state->dhnc != NULL || state->dh2c != NULL) {
891 /* durable handles are not supported on IPC$ */
892 tevent_req_nterror(req, NT_STATUS_OBJECT_NAME_NOT_FOUND);
893 return tevent_req_post(req, state->ev);
896 if (!lp_nt_pipe_support()) {
897 tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
898 return tevent_req_post(req, state->ev);
901 status = open_np_file(smb1req, pipe_name, &state->result);
902 if (tevent_req_nterror(req, status)) {
903 return tevent_req_post(req, state->ev);
905 state->info = FILE_WAS_OPENED;
907 smbd_smb2_create_finish(req);
908 return req;
911 if (CAN_PRINT(smb1req->conn)) {
912 if (state->dhnc != NULL || state->dh2c != NULL) {
913 /* durable handles are not supported on printers */
914 tevent_req_nterror(req, NT_STATUS_OBJECT_NAME_NOT_FOUND);
915 return tevent_req_post(req, state->ev);
918 status = file_new(smb1req, smb1req->conn, &state->result);
919 if (tevent_req_nterror(req, status)) {
920 return tevent_req_post(req, state->ev);
923 status = print_spool_open(state->result, in_name,
924 smb1req->vuid);
925 if (tevent_req_nterror(req, status)) {
926 file_free(smb1req, state->result);
927 return tevent_req_post(req, state->ev);
929 state->info = FILE_WAS_CREATED;
931 smbd_smb2_create_finish(req);
932 return req;
935 /* Check for trailing slash specific directory handling. */
936 status = windows_name_trailing_check(state->fname,
937 state->in_create_options);
938 if (tevent_req_nterror(req, status)) {
939 return tevent_req_post(req, state->ev);
942 smbd_smb2_create_before_exec(req);
943 if (!tevent_req_is_in_progress(req)) {
944 return tevent_req_post(req, state->ev);
947 DBG_DEBUG("open execution phase\n");
950 * For the backend file open procedure, there are
951 * three possible modes: replay operation (in which case
952 * there is nothing else to do), durable_reconnect or
953 * new open.
955 if (state->replay_operation) {
956 state->result = state->op->compat;
957 state->result->op = state->op;
958 state->update_open = false;
959 state->info = state->op->create_action;
961 smbd_smb2_create_after_exec(req);
962 if (!tevent_req_is_in_progress(req)) {
963 return tevent_req_post(req, state->ev);
966 smbd_smb2_create_finish(req);
967 return req;
970 if (state->do_durable_reconnect) {
971 DATA_BLOB new_cookie = data_blob_null;
972 NTTIME now = timeval_to_nttime(&smb2req->request_time);
974 status = smb2srv_open_recreate(smb2req->xconn,
975 smb1req->conn->session_info,
976 state->persistent_id,
977 state->create_guid,
978 now,
979 &state->op);
980 if (tevent_req_nterror(req, status)) {
981 DBG_NOTICE("smb2srv_open_recreate failed: %s\n",
982 nt_errstr(status));
983 return tevent_req_post(req, state->ev);
986 DBG_DEBUG("%s to recreate durable handle\n",
987 state->op->global->durable ? "succeeded" : "failed");
989 if (!state->op->global->durable) {
990 talloc_free(state->op);
991 tevent_req_nterror(req,
992 NT_STATUS_OBJECT_NAME_NOT_FOUND);
993 return tevent_req_post(req, state->ev);
996 status = SMB_VFS_DURABLE_RECONNECT(smb1req->conn,
997 smb1req,
998 state->op, /* smbXsrv_open input */
999 state->op->global->backend_cookie,
1000 state->op, /* TALLOC_CTX */
1001 &state->result,
1002 &new_cookie);
1003 if (!NT_STATUS_IS_OK(status)) {
1004 NTSTATUS return_status;
1006 return_status = NT_STATUS_OBJECT_NAME_NOT_FOUND;
1008 DBG_NOTICE("durable_reconnect failed: %s => %s\n",
1009 nt_errstr(status),
1010 nt_errstr(return_status));
1012 tevent_req_nterror(req, return_status);
1013 return tevent_req_post(req, state->ev);
1016 DBG_DEBUG("oplock_type=%u, lease_ptr==%p\n",
1017 (unsigned)state->result->oplock_type, state->lease_ptr);
1019 status = smbd_smb2_create_durable_lease_check(
1020 smb1req, state->fname, state->result, state->lease_ptr);
1021 if (tevent_req_nterror(req, status)) {
1022 close_file_free(
1023 smb1req, &state->result, SHUTDOWN_CLOSE);
1024 return tevent_req_post(req, state->ev);
1027 data_blob_free(&state->op->global->backend_cookie);
1028 state->op->global->backend_cookie = new_cookie;
1030 state->op->status = NT_STATUS_OK;
1031 state->op->global->disconnect_time = 0;
1033 /* save the timeout for later update */
1034 state->durable_timeout_msec = state->op->global->durable_timeout_msec;
1036 state->update_open = true;
1038 state->info = FILE_WAS_OPENED;
1040 smbd_smb2_create_after_exec(req);
1041 if (!tevent_req_is_in_progress(req)) {
1042 return tevent_req_post(req, state->ev);
1045 smbd_smb2_create_finish(req);
1046 return req;
1049 if (state->requested_oplock_level == SMB2_OPLOCK_LEVEL_LEASE) {
1050 if (state->lease_ptr == NULL) {
1051 state->requested_oplock_level = SMB2_OPLOCK_LEVEL_NONE;
1053 } else {
1054 state->lease_ptr = NULL;
1057 is_posix = (state->posx != NULL);
1059 /* convert '\\' into '/' */
1060 status = check_path_syntax(state->fname, is_posix);
1061 if (tevent_req_nterror(req, status)) {
1062 return tevent_req_post(req, state->ev);
1065 ucf_flags = filename_create_ucf_flags(
1066 smb1req, state->in_create_disposition);
1068 status = filename_convert_dirfsp(
1069 req,
1070 smb1req->conn,
1071 state->fname,
1072 ucf_flags,
1073 state->twrp_time,
1074 &dirfsp,
1075 &smb_fname);
1076 if (tevent_req_nterror(req, status)) {
1077 return tevent_req_post(req, state->ev);
1081 * MS-SMB2: 2.2.13 SMB2 CREATE Request
1082 * ImpersonationLevel ... MUST contain one of the
1083 * following values. The server MUST validate this
1084 * field, but otherwise ignore it.
1086 * NB. The source4/torture/smb2/durable_open.c test
1087 * shows this check is only done on real opens, not
1088 * on durable handle-reopens.
1091 if (in_impersonation_level >
1092 SMB2_IMPERSONATION_DELEGATE) {
1093 tevent_req_nterror(req,
1094 NT_STATUS_BAD_IMPERSONATION_LEVEL);
1095 return tevent_req_post(req, state->ev);
1099 * We know we're going to do a local open, so now
1100 * we must be protocol strict. JRA.
1102 * MS-SMB2: 3.3.5.9 - Receiving an SMB2 CREATE Request
1103 * If the file name length is greater than zero and the
1104 * first character is a path separator character, the
1105 * server MUST fail the request with
1106 * STATUS_INVALID_PARAMETER.
1108 if (in_name[0] == '/') {
1109 /* Names starting with '/' are never allowed. */
1110 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
1111 return tevent_req_post(req, ev);
1113 if (!is_posix && (in_name[0] == '\\')) {
1115 * Windows names starting with '\' are not allowed.
1117 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
1118 return tevent_req_post(req, ev);
1121 status = SMB_VFS_CREATE_FILE(smb1req->conn,
1122 smb1req,
1123 dirfsp,
1124 smb_fname,
1125 in_desired_access,
1126 in_share_access,
1127 state->in_create_disposition,
1128 state->in_create_options,
1129 in_file_attributes,
1130 map_smb2_oplock_levels_to_samba(
1131 state->requested_oplock_level),
1132 state->lease_ptr,
1133 state->allocation_size,
1134 0, /* private_flags */
1135 state->sec_desc,
1136 state->ea_list,
1137 &state->result,
1138 &state->info,
1139 &in_context_blobs,
1140 state->out_context_blobs);
1141 if (NT_STATUS_IS_OK(status) &&
1142 !(state->in_create_options & FILE_OPEN_REPARSE_POINT))
1145 mode_t mode = state->result->fsp_name->st.st_ex_mode;
1147 if (!(S_ISREG(mode) || S_ISDIR(mode))) {
1149 * Only open files and dirs without
1150 * FILE_OPEN_REPARSE_POINT
1152 close_file_free(smb1req, &state->result, ERROR_CLOSE);
1153 status = NT_STATUS_IO_REPARSE_TAG_NOT_HANDLED;
1156 if (!NT_STATUS_IS_OK(status)) {
1157 if (open_was_deferred(smb1req->xconn, smb1req->mid)) {
1158 SMBPROFILE_IOBYTES_ASYNC_SET_IDLE(smb2req->profile);
1159 return req;
1161 tevent_req_nterror(req, status);
1162 return tevent_req_post(req, state->ev);
1164 state->op = state->result->op;
1166 smbd_smb2_create_after_exec(req);
1167 if (!tevent_req_is_in_progress(req)) {
1168 return tevent_req_post(req, state->ev);
1171 smbd_smb2_create_finish(req);
1172 return req;
1175 static void smbd_smb2_create_purge_replay_cache(struct tevent_req *req,
1176 const char *caller_func)
1178 struct smbd_smb2_create_state *state = tevent_req_data(
1179 req, struct smbd_smb2_create_state);
1180 NTSTATUS status;
1182 if (state->purge_create_guid == NULL) {
1183 return;
1186 status = smbXsrv_open_purge_replay_cache(state->smb2req->xconn->client,
1187 state->purge_create_guid);
1188 if (!NT_STATUS_IS_OK(status)) {
1189 struct GUID_txt_buf buf;
1191 D_ERR("%s: smbXsrv_open_purge_replay_cache(%s) %s\n",
1192 caller_func,
1193 GUID_buf_string(state->purge_create_guid, &buf),
1194 nt_errstr(status));
1197 state->purge_create_guid = NULL;
1200 static void smbd_smb2_create_before_exec(struct tevent_req *req)
1202 struct smbd_smb2_create_state *state = tevent_req_data(
1203 req, struct smbd_smb2_create_state);
1204 struct smbd_smb2_request *smb2req = state->smb2req;
1205 NTSTATUS status;
1207 if (state->exta != NULL) {
1208 if (!lp_ea_support(SNUM(smb2req->tcon->compat))) {
1209 tevent_req_nterror(req, NT_STATUS_EAS_NOT_SUPPORTED);
1210 return;
1213 state->ea_list = read_nttrans_ea_list(
1214 state,
1215 (const char *)state->exta->data.data,
1216 state->exta->data.length);
1217 if (state->ea_list == NULL) {
1218 DEBUG(10,("smbd_smb2_create_send: read_ea_name_list failed.\n"));
1219 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
1220 return;
1223 if ((state->posx == NULL) &&
1224 ea_list_has_invalid_name(state->ea_list)) {
1225 tevent_req_nterror(req, STATUS_INVALID_EA_NAME);
1226 return;
1230 if (state->mxac != NULL) {
1231 if (state->mxac->data.length == 0) {
1232 state->max_access_time = 0;
1233 } else if (state->mxac->data.length == 8) {
1234 state->max_access_time = BVAL(state->mxac->data.data, 0);
1235 } else {
1236 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
1237 return;
1241 if (state->secd != NULL) {
1242 enum ndr_err_code ndr_err;
1244 state->sec_desc = talloc_zero(state, struct security_descriptor);
1245 if (tevent_req_nomem(state->sec_desc, req)) {
1246 return;
1249 ndr_err = ndr_pull_struct_blob(&state->secd->data,
1250 state->sec_desc, state->sec_desc,
1251 (ndr_pull_flags_fn_t)ndr_pull_security_descriptor);
1252 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1253 DEBUG(2,("ndr_pull_security_descriptor failed: %s\n",
1254 ndr_errstr(ndr_err)));
1255 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
1256 return;
1260 if (state->dhnq != NULL) {
1261 if (state->dhnq->data.length != 16) {
1262 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
1263 return;
1266 if (state->dh2q != NULL) {
1267 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
1268 return;
1272 * durable handle request is processed below.
1274 state->durable_requested = true;
1276 * Set the timeout to 16 mins.
1278 * TODO: test this against Windows 2012
1279 * as the default for durable v2 is 1 min.
1281 state->durable_timeout_msec = (16*60*1000);
1284 if (state->dh2q != NULL) {
1285 const uint8_t *p = state->dh2q->data.data;
1286 NTTIME now = timeval_to_nttime(&smb2req->request_time);
1287 uint32_t durable_v2_timeout = 0;
1288 DATA_BLOB create_guid_blob;
1289 const uint8_t *hdr;
1290 uint32_t flags;
1292 if (state->dh2q->data.length != 32) {
1293 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
1294 return;
1297 if (state->dhnq != NULL) {
1298 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
1299 return;
1302 durable_v2_timeout = IVAL(p, 0);
1303 create_guid_blob = data_blob_const(p + 16, 16);
1305 status = GUID_from_ndr_blob(&create_guid_blob,
1306 &state->_create_guid);
1307 if (tevent_req_nterror(req, status)) {
1308 return;
1310 state->create_guid = &state->_create_guid;
1313 * we need to store the create_guid later
1315 state->update_open = true;
1318 * And we need to create a cache for replaying the
1319 * create.
1321 state->need_replay_cache = true;
1324 * durable handle v2 request processed below
1326 state->durable_requested = true;
1327 state->durable_timeout_msec = MIN(durable_v2_timeout, 300*1000);
1328 if (state->durable_timeout_msec == 0) {
1330 * Set the timeout to 1 min as default.
1332 * This matches Windows 2012.
1334 state->durable_timeout_msec = (60*1000);
1338 * Check for replay operation.
1339 * Only consider it when we have dh2q.
1340 * If we do not have a replay operation, verify that
1341 * the create_guid is not cached for replay.
1343 hdr = SMBD_SMB2_IN_HDR_PTR(smb2req);
1344 flags = IVAL(hdr, SMB2_HDR_FLAGS);
1345 state->replay_operation =
1346 flags & SMB2_HDR_FLAG_REPLAY_OPERATION;
1348 status = smb2srv_open_lookup_replay_cache(smb2req->xconn,
1349 state->req_guid,
1350 *state->create_guid,
1351 state->fname,
1352 now,
1353 &state->op);
1354 if (NT_STATUS_EQUAL(status, NT_STATUS_FWP_RESERVED)) {
1356 * We've reserved the replay_cache record
1357 * for ourself, indicating we're still
1358 * in progress.
1360 * It means the smbd_smb2_create_cleanup()
1361 * may need to call smbXsrv_open_purge_replay_cache()
1362 * in order to cleanup.
1364 SMB_ASSERT(state->op == NULL);
1365 state->_purge_create_guid = state->_create_guid;
1366 state->purge_create_guid = &state->_purge_create_guid;
1367 status = NT_STATUS_OK;
1368 state->replay_operation = false;
1369 } else if (NT_STATUS_EQUAL(status, NT_STATUS_FILE_NOT_AVAILABLE)) {
1370 tevent_req_nterror(req, status);
1371 return;
1372 } else if (tevent_req_nterror(req, status)) {
1373 DBG_WARNING("smb2srv_open_lookup_replay_cache "
1374 "failed: %s\n", nt_errstr(status));
1375 return;
1376 } else if (!state->replay_operation) {
1378 * If a create without replay operation flag
1379 * is sent but with a create_guid that is
1380 * currently in the replay cache -- fail.
1382 status = NT_STATUS_DUPLICATE_OBJECTID;
1383 (void)tevent_req_nterror(req, status);
1384 return;
1388 if (state->dhnc != NULL) {
1389 state->persistent_id = BVAL(state->dhnc->data.data, 0);
1390 state->do_durable_reconnect = true;
1393 if (state->dh2c != NULL) {
1394 const uint8_t *p = state->dh2c->data.data;
1395 DATA_BLOB create_guid_blob;
1397 state->persistent_id = BVAL(p, 0);
1398 create_guid_blob = data_blob_const(p + 16, 16);
1400 status = GUID_from_ndr_blob(&create_guid_blob,
1401 &state->_create_guid);
1402 if (tevent_req_nterror(req, status)) {
1403 return;
1406 state->create_guid = &state->_create_guid;
1407 state->do_durable_reconnect = true;
1410 if (state->alsi != NULL) {
1411 if (state->alsi->data.length != 8) {
1412 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
1413 return;
1415 state->allocation_size = BVAL(state->alsi->data.data, 0);
1418 if (state->twrp != NULL) {
1419 if (state->twrp->data.length != 8) {
1420 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
1421 return;
1424 state->twrp_time = BVAL(state->twrp->data.data, 0);
1427 if (state->qfid != NULL) {
1428 if (state->qfid->data.length != 0) {
1429 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
1430 return;
1434 if (state->rqls != NULL) {
1435 ssize_t lease_len = -1;
1437 lease_len = smb2_lease_pull(state->rqls->data.data,
1438 state->rqls->data.length,
1439 &state->lease);
1440 if (lease_len == -1) {
1441 tevent_req_nterror(
1442 req, NT_STATUS_INVALID_PARAMETER);
1443 return;
1445 state->lease_ptr = &state->lease;
1447 if (DEBUGLEVEL >= 10) {
1448 DEBUG(10, ("Got lease request size %d\n",
1449 (int)lease_len));
1450 NDR_PRINT_DEBUG(smb2_lease, state->lease_ptr);
1453 if (!smb2_lease_key_valid(&state->lease.lease_key)) {
1454 state->lease_ptr = NULL;
1455 state->requested_oplock_level = SMB2_OPLOCK_LEVEL_NONE;
1458 if ((smb2req->xconn->protocol < PROTOCOL_SMB3_00) &&
1459 (state->lease.lease_version != 1))
1461 DEBUG(10, ("v2 lease key only for SMB3\n"));
1462 state->lease_ptr = NULL;
1466 * Replay with a lease is only allowed if the
1467 * established open carries a lease with the
1468 * same lease key.
1470 if (state->replay_operation) {
1471 struct smb2_lease *op_ls =
1472 &state->op->compat->lease->lease;
1473 int op_oplock = state->op->compat->oplock_type;
1475 if (map_samba_oplock_levels_to_smb2(op_oplock)
1476 != SMB2_OPLOCK_LEVEL_LEASE)
1478 status = NT_STATUS_ACCESS_DENIED;
1479 (void)tevent_req_nterror(req, status);
1480 return;
1482 if (!smb2_lease_key_equal(&state->lease.lease_key,
1483 &op_ls->lease_key))
1485 status = NT_STATUS_ACCESS_DENIED;
1486 (void)tevent_req_nterror(req, status);
1487 return;
1492 if (state->posx != NULL) {
1493 if (state->posx->data.length != 4) {
1494 DBG_DEBUG("Got %zu bytes POSX cctx, expected 4\n",
1495 state->posx->data.length);
1496 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
1497 return;
1502 static void smbd_smb2_create_after_exec(struct tevent_req *req)
1504 struct smbd_smb2_create_state *state = tevent_req_data(
1505 req, struct smbd_smb2_create_state);
1506 connection_struct *conn = state->result->conn;
1507 NTSTATUS status;
1510 * here we have op == result->op
1513 DBG_DEBUG("response construction phase\n");
1515 state->out_file_attributes = fdos_mode(state->result);
1517 if (state->mxac != NULL) {
1518 NTTIME last_write_time;
1520 last_write_time = full_timespec_to_nt_time(
1521 &state->result->fsp_name->st.st_ex_mtime);
1522 if (last_write_time != state->max_access_time) {
1523 uint8_t p[8];
1524 uint32_t max_access_granted;
1525 DATA_BLOB blob = data_blob_const(p, sizeof(p));
1527 status = smbd_calculate_access_mask_fsp(
1528 conn->cwd_fsp,
1529 state->result,
1530 false,
1531 SEC_FLAG_MAXIMUM_ALLOWED,
1532 &max_access_granted);
1534 SIVAL(p, 0, NT_STATUS_V(status));
1535 SIVAL(p, 4, max_access_granted);
1537 status = smb2_create_blob_add(
1538 state->out_context_blobs,
1539 state->out_context_blobs,
1540 SMB2_CREATE_TAG_MXAC,
1541 blob);
1542 if (!NT_STATUS_IS_OK(status)) {
1543 goto fail;
1548 if (!state->replay_operation && state->durable_requested &&
1549 (fsp_lease_type(state->result) & SMB2_LEASE_HANDLE))
1551 status = SMB_VFS_DURABLE_COOKIE(
1552 state->result,
1553 state->op,
1554 &state->op->global->backend_cookie);
1555 if (!NT_STATUS_IS_OK(status)) {
1556 state->op->global->backend_cookie = data_blob_null;
1559 if (!state->replay_operation && state->op->global->backend_cookie.length > 0)
1561 state->update_open = true;
1563 state->op->global->durable = true;
1564 state->op->global->durable_timeout_msec = state->durable_timeout_msec;
1567 if (state->update_open) {
1568 state->op->global->create_guid = state->_create_guid;
1569 if (state->need_replay_cache) {
1570 state->op->flags |= SMBXSRV_OPEN_NEED_REPLAY_CACHE;
1573 status = smbXsrv_open_update(state->op);
1574 DEBUG(10, ("smb2_create_send: smbXsrv_open_update "
1575 "returned %s\n",
1576 nt_errstr(status)));
1577 if (!NT_STATUS_IS_OK(status)) {
1578 goto fail;
1582 * We should not purge the replay cache anymore
1583 * as it's attached to the smbXsrv_open record now.
1585 state->purge_create_guid = NULL;
1588 if (state->dhnq != NULL && state->op->global->durable) {
1589 uint8_t p[8] = { 0, };
1590 DATA_BLOB blob = data_blob_const(p, sizeof(p));
1592 status = smb2_create_blob_add(state->out_context_blobs,
1593 state->out_context_blobs,
1594 SMB2_CREATE_TAG_DHNQ,
1595 blob);
1596 if (!NT_STATUS_IS_OK(status)) {
1597 goto fail;
1601 if (state->dh2q != NULL && state->op->global->durable &&
1603 * For replay operations, we return the dh2q blob
1604 * in the case of oplocks not based on the state of
1605 * the open, but on whether it could have been granted
1606 * for the request data. In the case of leases instead,
1607 * the state of the open is used...
1609 (!state->replay_operation ||
1610 state->in_oplock_level == SMB2_OPLOCK_LEVEL_BATCH ||
1611 state->in_oplock_level == SMB2_OPLOCK_LEVEL_LEASE))
1613 uint8_t p[8] = { 0, };
1614 DATA_BLOB blob = data_blob_const(p, sizeof(p));
1615 uint32_t durable_v2_response_flags = 0;
1617 SIVAL(p, 0, state->op->global->durable_timeout_msec);
1618 SIVAL(p, 4, durable_v2_response_flags);
1620 status = smb2_create_blob_add(state->out_context_blobs,
1621 state->out_context_blobs,
1622 SMB2_CREATE_TAG_DH2Q,
1623 blob);
1624 if (!NT_STATUS_IS_OK(status)) {
1625 goto fail;
1629 if (state->qfid != NULL) {
1630 uint8_t p[32];
1631 SMB_STRUCT_STAT *base_sp = state->result->base_fsp ?
1632 &state->result->base_fsp->fsp_name->st :
1633 &state->result->fsp_name->st;
1634 uint64_t file_id = SMB_VFS_FS_FILE_ID(conn, base_sp);
1635 DATA_BLOB blob = data_blob_const(p, sizeof(p));
1637 ZERO_STRUCT(p);
1639 /* From conversations with Microsoft engineers at
1640 the MS plugfest. The first 8 bytes are the "volume index"
1641 == inode, the second 8 bytes are the "volume id",
1642 == dev. This will be updated in the SMB2 doc. */
1643 SBVAL(p, 0, file_id);
1644 SIVAL(p, 8, base_sp->st_ex_dev);/* FileIndexHigh */
1646 status = smb2_create_blob_add(state->out_context_blobs,
1647 state->out_context_blobs,
1648 SMB2_CREATE_TAG_QFID,
1649 blob);
1650 if (!NT_STATUS_IS_OK(status)) {
1651 goto fail;
1655 if ((state->rqls != NULL) && (state->result->oplock_type == LEASE_OPLOCK)) {
1656 uint8_t buf[52];
1657 struct smb2_lease lease;
1658 size_t lease_len;
1660 lease = state->result->lease->lease;
1662 lease_len = sizeof(buf);
1663 if (lease.lease_version == 1) {
1664 lease_len = 32;
1667 if (!smb2_lease_push(&lease, buf, lease_len)) {
1668 status = NT_STATUS_INTERNAL_ERROR;
1669 goto fail;
1672 status = smb2_create_blob_add(
1673 state, state->out_context_blobs,
1674 SMB2_CREATE_TAG_RQLS,
1675 data_blob_const(buf, lease_len));
1676 if (!NT_STATUS_IS_OK(status)) {
1677 goto fail;
1681 if (state->posx != NULL) {
1682 struct stat_ex *psbuf = &state->result->fsp_name->st;
1683 struct smb3_posix_cc_info cc = {
1684 .nlinks = psbuf->st_ex_nlink,
1685 .posix_perms = unix_perms_to_wire(psbuf->st_ex_mode &
1686 ~S_IFMT),
1688 uint8_t buf[sizeof(struct smb3_posix_cc_info)];
1689 struct ndr_push ndr = {
1690 .data = buf,
1691 .alloc_size = sizeof(buf),
1692 .fixed_buf_size = true,
1694 enum ndr_err_code ndr_err;
1696 uid_to_sid(&cc.owner, psbuf->st_ex_uid);
1697 gid_to_sid(&cc.group, psbuf->st_ex_gid);
1699 ndr_err =
1700 ndr_push_smb3_posix_cc_info(&ndr,
1701 NDR_SCALARS | NDR_BUFFERS,
1702 &cc);
1703 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1704 status = NT_STATUS_INSUFFICIENT_RESOURCES;
1705 goto fail;
1708 status = smb2_create_blob_add(state->out_context_blobs,
1709 state->out_context_blobs,
1710 SMB2_CREATE_TAG_POSIX,
1711 (DATA_BLOB){
1712 .data = buf,
1713 .length = ndr.offset,
1715 if (!NT_STATUS_IS_OK(status)) {
1716 goto fail;
1720 return;
1722 fail:
1723 close_file_free(state->smb1req, &state->result, ERROR_CLOSE);
1724 tevent_req_nterror(req, status);
1727 static void smbd_smb2_create_finish(struct tevent_req *req)
1729 struct smbd_smb2_create_state *state = tevent_req_data(
1730 req, struct smbd_smb2_create_state);
1731 struct smbd_smb2_request *smb2req = state->smb2req;
1732 struct smb_request *smb1req = state->smb1req;
1733 files_struct *result = state->result;
1735 smb2req->compat_chain_fsp = smb1req->chain_fsp;
1737 if (state->replay_operation) {
1738 state->out_oplock_level = state->in_oplock_level;
1739 } else if (lp_fake_oplocks(SNUM(smb2req->tcon->compat))) {
1740 state->out_oplock_level = state->in_oplock_level;
1741 } else {
1742 state->out_oplock_level = map_samba_oplock_levels_to_smb2(result->oplock_type);
1745 if ((state->in_create_disposition == FILE_SUPERSEDE)
1746 && (state->info == FILE_WAS_OVERWRITTEN)) {
1747 state->out_create_action = FILE_WAS_SUPERSEDED;
1748 } else {
1749 state->out_create_action = state->info;
1751 result->op->create_action = state->out_create_action;
1753 state->out_creation_ts = get_create_timespec(smb1req->conn,
1754 result, result->fsp_name);
1755 state->out_last_access_ts = result->fsp_name->st.st_ex_atime;
1756 state->out_last_write_ts = result->fsp_name->st.st_ex_mtime;
1757 state->out_change_ts = get_change_timespec(smb1req->conn,
1758 result, result->fsp_name);
1760 if (lp_dos_filetime_resolution(SNUM(smb2req->tcon->compat))) {
1761 dos_filetime_timespec(&state->out_creation_ts);
1762 dos_filetime_timespec(&state->out_last_access_ts);
1763 dos_filetime_timespec(&state->out_last_write_ts);
1764 dos_filetime_timespec(&state->out_change_ts);
1767 state->out_allocation_size =
1768 SMB_VFS_GET_ALLOC_SIZE(smb1req->conn, result,
1769 &(result->fsp_name->st));
1770 state->out_end_of_file = result->fsp_name->st.st_ex_size;
1771 if (state->out_file_attributes == 0) {
1772 state->out_file_attributes = FILE_ATTRIBUTE_NORMAL;
1774 state->out_file_id_persistent = result->op->global->open_persistent_id;
1775 state->out_file_id_volatile = result->op->global->open_volatile_id;
1777 DBG_DEBUG("%s - %s\n", fsp_str_dbg(result), fsp_fnum_dbg(result));
1779 tevent_req_done(req);
1780 tevent_req_post(req, state->ev);
1783 static NTSTATUS smbd_smb2_create_recv(struct tevent_req *req,
1784 TALLOC_CTX *mem_ctx,
1785 uint8_t *out_oplock_level,
1786 uint32_t *out_create_action,
1787 struct timespec *out_creation_ts,
1788 struct timespec *out_last_access_ts,
1789 struct timespec *out_last_write_ts,
1790 struct timespec *out_change_ts,
1791 uint64_t *out_allocation_size,
1792 uint64_t *out_end_of_file,
1793 uint32_t *out_file_attributes,
1794 uint64_t *out_file_id_persistent,
1795 uint64_t *out_file_id_volatile,
1796 struct smb2_create_blobs *out_context_blobs)
1798 NTSTATUS status;
1799 struct smbd_smb2_create_state *state = tevent_req_data(req,
1800 struct smbd_smb2_create_state);
1802 if (tevent_req_is_nterror(req, &status)) {
1803 tevent_req_received(req);
1804 return status;
1807 *out_oplock_level = state->out_oplock_level;
1808 *out_create_action = state->out_create_action;
1809 *out_creation_ts = state->out_creation_ts;
1810 *out_last_access_ts = state->out_last_access_ts;
1811 *out_last_write_ts = state->out_last_write_ts;
1812 *out_change_ts = state->out_change_ts;
1813 *out_allocation_size = state->out_allocation_size;
1814 *out_end_of_file = state->out_end_of_file;
1815 *out_file_attributes = state->out_file_attributes;
1816 *out_file_id_persistent = state->out_file_id_persistent;
1817 *out_file_id_volatile = state->out_file_id_volatile;
1818 *out_context_blobs = *(state->out_context_blobs);
1820 talloc_steal(mem_ctx, state->out_context_blobs->blobs);
1822 tevent_req_received(req);
1823 return NT_STATUS_OK;
1826 /*********************************************************
1827 Code for dealing with deferred opens.
1828 *********************************************************/
1830 bool get_deferred_open_message_state_smb2(struct smbd_smb2_request *smb2req,
1831 struct timeval *p_request_time,
1832 struct deferred_open_record **open_rec)
1834 struct smbd_smb2_create_state *state = NULL;
1835 struct tevent_req *req = NULL;
1837 if (!smb2req) {
1838 return false;
1840 req = smb2req->subreq;
1841 if (!req) {
1842 return false;
1844 state = tevent_req_data(req, struct smbd_smb2_create_state);
1845 if (!state) {
1846 return false;
1848 if (!state->open_was_deferred) {
1849 return false;
1851 if (p_request_time) {
1852 *p_request_time = state->request_time;
1854 if (open_rec != NULL) {
1855 *open_rec = state->open_rec;
1857 return true;
1860 /*********************************************************
1861 Re-process this call early - requested by message or
1862 close.
1863 *********************************************************/
1865 static struct smbd_smb2_request *find_open_smb2req(
1866 struct smbXsrv_connection *xconn, uint64_t mid)
1868 struct smbd_smb2_request *smb2req;
1870 for (smb2req = xconn->smb2.requests; smb2req; smb2req = smb2req->next) {
1871 uint64_t message_id;
1872 if (smb2req->subreq == NULL) {
1873 /* This message has been processed. */
1874 continue;
1876 if (!tevent_req_is_in_progress(smb2req->subreq)) {
1877 /* This message has been processed. */
1878 continue;
1880 message_id = get_mid_from_smb2req(smb2req);
1881 if (message_id == mid) {
1882 return smb2req;
1885 return NULL;
1888 bool open_was_deferred_smb2(struct smbXsrv_connection *xconn, uint64_t mid)
1890 struct smbd_smb2_create_state *state = NULL;
1891 struct smbd_smb2_request *smb2req;
1893 smb2req = find_open_smb2req(xconn, mid);
1895 if (!smb2req) {
1896 DEBUG(10,("open_was_deferred_smb2: mid %llu smb2req == NULL\n",
1897 (unsigned long long)mid));
1898 return false;
1900 if (!smb2req->subreq) {
1901 return false;
1903 if (!tevent_req_is_in_progress(smb2req->subreq)) {
1904 return false;
1906 state = tevent_req_data(smb2req->subreq,
1907 struct smbd_smb2_create_state);
1908 if (!state) {
1909 return false;
1911 /* It's not in progress if there's no timeout event. */
1912 if (!state->open_was_deferred) {
1913 return false;
1916 DEBUG(10,("open_was_deferred_smb2: mid = %llu\n",
1917 (unsigned long long)mid));
1919 return true;
1922 static void remove_deferred_open_message_smb2_internal(struct smbd_smb2_request *smb2req,
1923 uint64_t mid)
1925 struct smbd_smb2_create_state *state = NULL;
1927 if (!smb2req->subreq) {
1928 return;
1930 if (!tevent_req_is_in_progress(smb2req->subreq)) {
1931 return;
1933 state = tevent_req_data(smb2req->subreq,
1934 struct smbd_smb2_create_state);
1935 if (!state) {
1936 return;
1939 DEBUG(10,("remove_deferred_open_message_smb2_internal: "
1940 "mid %llu\n",
1941 (unsigned long long)mid ));
1943 state->open_was_deferred = false;
1944 /* Ensure we don't have any outstanding immediate event. */
1945 TALLOC_FREE(state->im);
1946 TALLOC_FREE(state->open_rec);
1949 void remove_deferred_open_message_smb2(
1950 struct smbXsrv_connection *xconn, uint64_t mid)
1952 struct smbd_smb2_request *smb2req;
1954 smb2req = find_open_smb2req(xconn, mid);
1956 if (!smb2req) {
1957 DEBUG(10,("remove_deferred_open_message_smb2: "
1958 "can't find mid %llu\n",
1959 (unsigned long long)mid ));
1960 return;
1962 remove_deferred_open_message_smb2_internal(smb2req, mid);
1965 static void smbd_smb2_create_request_dispatch_immediate(struct tevent_context *ctx,
1966 struct tevent_immediate *im,
1967 void *private_data)
1969 struct smbd_smb2_request *smb2req = talloc_get_type_abort(private_data,
1970 struct smbd_smb2_request);
1971 uint64_t mid = get_mid_from_smb2req(smb2req);
1972 NTSTATUS status;
1974 DEBUG(10,("smbd_smb2_create_request_dispatch_immediate: "
1975 "re-dispatching mid %llu\n",
1976 (unsigned long long)mid ));
1978 status = smbd_smb2_request_dispatch(smb2req);
1979 if (!NT_STATUS_IS_OK(status)) {
1980 smbd_server_connection_terminate(smb2req->xconn,
1981 nt_errstr(status));
1982 return;
1986 bool schedule_deferred_open_message_smb2(
1987 struct smbXsrv_connection *xconn, uint64_t mid)
1989 struct smbd_smb2_create_state *state = NULL;
1990 struct smbd_smb2_request *smb2req;
1992 smb2req = find_open_smb2req(xconn, mid);
1994 if (!smb2req) {
1995 DEBUG(10,("schedule_deferred_open_message_smb2: "
1996 "can't find mid %llu\n",
1997 (unsigned long long)mid ));
1998 return false;
2000 if (!smb2req->subreq) {
2001 return false;
2003 if (!tevent_req_is_in_progress(smb2req->subreq)) {
2004 return false;
2006 state = tevent_req_data(smb2req->subreq,
2007 struct smbd_smb2_create_state);
2008 if (!state) {
2009 return false;
2012 /* Ensure we don't have any outstanding immediate event. */
2013 TALLOC_FREE(state->im);
2016 * This is subtle. We must null out the callback
2017 * before rescheduling, else the first call to
2018 * tevent_req_nterror() causes the _receive()
2019 * function to be called, this causing tevent_req_post()
2020 * to crash.
2022 tevent_req_set_callback(smb2req->subreq, NULL, NULL);
2024 state->im = tevent_create_immediate(smb2req);
2025 if (!state->im) {
2026 smbd_server_connection_terminate(smb2req->xconn,
2027 nt_errstr(NT_STATUS_NO_MEMORY));
2028 return false;
2031 DEBUG(10,("schedule_deferred_open_message_smb2: "
2032 "re-processing mid %llu\n",
2033 (unsigned long long)mid ));
2035 tevent_schedule_immediate(state->im,
2036 smb2req->sconn->ev_ctx,
2037 smbd_smb2_create_request_dispatch_immediate,
2038 smb2req);
2040 return true;
2043 static bool smbd_smb2_create_cancel(struct tevent_req *req)
2045 struct smbd_smb2_request *smb2req = NULL;
2046 struct smbd_smb2_create_state *state = tevent_req_data(req,
2047 struct smbd_smb2_create_state);
2048 uint64_t mid;
2050 if (!state) {
2051 return false;
2054 if (!state->smb2req) {
2055 return false;
2058 smb2req = state->smb2req;
2059 mid = get_mid_from_smb2req(smb2req);
2061 if (is_deferred_open_async(state->open_rec)) {
2062 /* Can't cancel an async create. */
2063 return false;
2066 remove_deferred_open_message_smb2_internal(smb2req, mid);
2068 tevent_req_defer_callback(req, smb2req->sconn->ev_ctx);
2069 tevent_req_nterror(req, NT_STATUS_CANCELLED);
2070 return true;
2073 bool push_deferred_open_message_smb2(struct smbd_smb2_request *smb2req,
2074 struct timeval request_time,
2075 struct timeval timeout,
2076 struct file_id id,
2077 struct deferred_open_record *open_rec)
2079 struct tevent_req *req = NULL;
2080 struct smbd_smb2_create_state *state = NULL;
2081 struct timeval end_time;
2083 if (!smb2req) {
2084 return false;
2086 req = smb2req->subreq;
2087 if (!req) {
2088 return false;
2090 state = tevent_req_data(req, struct smbd_smb2_create_state);
2091 if (!state) {
2092 return false;
2094 state->id = id;
2095 state->request_time = request_time;
2096 state->open_rec = talloc_move(state, &open_rec);
2098 /* Re-schedule us to retry on timer expiry. */
2099 end_time = timeval_sum(&request_time, &timeout);
2101 DEBUG(10,("push_deferred_open_message_smb2: "
2102 "timeout at %s\n",
2103 timeval_string(talloc_tos(),
2104 &end_time,
2105 true) ));
2107 state->open_was_deferred = true;
2109 /* allow this request to be canceled */
2110 tevent_req_set_cancel_fn(req, smbd_smb2_create_cancel);
2112 return true;