ctdb-scripts: Move connection tracking to 10.interface
[samba4-gss.git] / source3 / smbd / smb2_create.c
blob65744e0bf37fb63236d02fc8f558b0c139febd62
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"
35 #include "source3/modules/util_reparse.h"
37 #undef DBGC_CLASS
38 #define DBGC_CLASS DBGC_SMB2
40 int map_smb2_oplock_levels_to_samba(uint8_t in_oplock_level)
42 switch(in_oplock_level) {
43 case SMB2_OPLOCK_LEVEL_NONE:
44 return NO_OPLOCK;
45 case SMB2_OPLOCK_LEVEL_II:
46 return LEVEL_II_OPLOCK;
47 case SMB2_OPLOCK_LEVEL_EXCLUSIVE:
48 return EXCLUSIVE_OPLOCK;
49 case SMB2_OPLOCK_LEVEL_BATCH:
50 return BATCH_OPLOCK;
51 case SMB2_OPLOCK_LEVEL_LEASE:
52 return LEASE_OPLOCK;
53 default:
54 DEBUG(2,("map_smb2_oplock_levels_to_samba: "
55 "unknown level %u\n",
56 (unsigned int)in_oplock_level));
57 return NO_OPLOCK;
61 static uint8_t map_samba_oplock_levels_to_smb2(int oplock_type)
63 if (BATCH_OPLOCK_TYPE(oplock_type)) {
64 return SMB2_OPLOCK_LEVEL_BATCH;
65 } else if (EXCLUSIVE_OPLOCK_TYPE(oplock_type)) {
66 return SMB2_OPLOCK_LEVEL_EXCLUSIVE;
67 } else if (oplock_type == LEVEL_II_OPLOCK) {
68 return SMB2_OPLOCK_LEVEL_II;
69 } else if (oplock_type == LEASE_OPLOCK) {
70 return SMB2_OPLOCK_LEVEL_LEASE;
71 } else {
72 return SMB2_OPLOCK_LEVEL_NONE;
77 MS-FSA 2.1.5.1 Server Requests an Open of a File
78 Trailing '/' or '\\' checker.
79 Must be done before the filename parser removes any
80 trailing characters. If we decide to add this to SMB1
81 NTCreate processing we can make this public.
83 Note this is Windows pathname processing only. When
84 POSIX pathnames are added to SMB2 this will not apply.
87 static NTSTATUS windows_name_trailing_check(const char *name,
88 uint32_t create_options)
90 size_t name_len = strlen(name);
91 char trail_c;
93 if (name_len <= 1) {
94 return NT_STATUS_OK;
97 trail_c = name[name_len-1];
100 * Trailing '/' is always invalid.
102 if (trail_c == '/') {
103 return NT_STATUS_OBJECT_NAME_INVALID;
106 if (create_options & FILE_NON_DIRECTORY_FILE) {
107 if (trail_c == '\\') {
108 return NT_STATUS_OBJECT_NAME_INVALID;
111 return NT_STATUS_OK;
114 static struct tevent_req *smbd_smb2_create_send(TALLOC_CTX *mem_ctx,
115 struct tevent_context *ev,
116 struct smbd_smb2_request *smb2req,
117 uint8_t in_oplock_level,
118 uint32_t in_impersonation_level,
119 uint32_t in_desired_access,
120 uint32_t in_file_attributes,
121 uint32_t in_share_access,
122 uint32_t in_create_disposition,
123 uint32_t _in_create_options,
124 const char *in_name,
125 struct smb2_create_blobs in_context_blobs);
126 static NTSTATUS smbd_smb2_create_recv(struct tevent_req *req,
127 TALLOC_CTX *mem_ctx,
128 uint8_t *out_oplock_level,
129 uint32_t *out_create_action,
130 struct timespec *out_creation_ts,
131 struct timespec *out_last_access_ts,
132 struct timespec *out_last_write_ts,
133 struct timespec *out_change_ts,
134 uint64_t *out_allocation_size,
135 uint64_t *out_end_of_file,
136 uint32_t *out_file_attributes,
137 uint64_t *out_file_id_persistent,
138 uint64_t *out_file_id_volatile,
139 struct smb2_create_blobs *out_context_blobs);
141 static void smbd_smb2_request_create_done(struct tevent_req *tsubreq);
142 NTSTATUS smbd_smb2_request_process_create(struct smbd_smb2_request *smb2req)
144 const uint8_t *inbody;
145 const struct iovec *indyniov;
146 uint8_t in_oplock_level;
147 uint32_t in_impersonation_level;
148 uint32_t in_desired_access;
149 uint32_t in_file_attributes;
150 uint32_t in_share_access;
151 uint32_t in_create_disposition;
152 uint32_t in_create_options;
153 uint16_t in_name_offset;
154 uint16_t in_name_length;
155 DATA_BLOB in_name_buffer;
156 char *in_name_string;
157 size_t in_name_string_size;
158 uint32_t name_offset = 0;
159 uint32_t name_available_length = 0;
160 uint32_t in_context_offset;
161 uint32_t in_context_length;
162 DATA_BLOB in_context_buffer;
163 struct smb2_create_blobs in_context_blobs;
164 uint32_t context_offset = 0;
165 uint32_t context_available_length = 0;
166 uint32_t dyn_offset;
167 NTSTATUS status;
168 bool ok;
169 struct tevent_req *tsubreq;
171 status = smbd_smb2_request_verify_sizes(smb2req, 0x39);
172 if (!NT_STATUS_IS_OK(status)) {
173 return smbd_smb2_request_error(smb2req, status);
175 inbody = SMBD_SMB2_IN_BODY_PTR(smb2req);
177 in_oplock_level = CVAL(inbody, 0x03);
178 in_impersonation_level = IVAL(inbody, 0x04);
179 in_desired_access = IVAL(inbody, 0x18);
180 in_file_attributes = IVAL(inbody, 0x1C);
181 in_share_access = IVAL(inbody, 0x20);
182 in_create_disposition = IVAL(inbody, 0x24);
183 in_create_options = IVAL(inbody, 0x28);
184 in_name_offset = SVAL(inbody, 0x2C);
185 in_name_length = SVAL(inbody, 0x2E);
186 in_context_offset = IVAL(inbody, 0x30);
187 in_context_length = IVAL(inbody, 0x34);
190 * First check if the dynamic name and context buffers
191 * are correctly specified.
193 * Note: That we don't check if the name and context buffers
194 * overlap
197 dyn_offset = SMB2_HDR_BODY + SMBD_SMB2_IN_BODY_LEN(smb2req);
199 if (in_name_offset == 0 && in_name_length == 0) {
200 /* This is ok */
201 name_offset = 0;
202 } else if (in_name_offset < dyn_offset) {
203 return smbd_smb2_request_error(smb2req, NT_STATUS_INVALID_PARAMETER);
204 } else {
205 name_offset = in_name_offset - dyn_offset;
208 indyniov = SMBD_SMB2_IN_DYN_IOV(smb2req);
210 if (name_offset > indyniov->iov_len) {
211 return smbd_smb2_request_error(smb2req, NT_STATUS_INVALID_PARAMETER);
214 name_available_length = indyniov->iov_len - name_offset;
216 if (in_name_length > name_available_length) {
217 return smbd_smb2_request_error(smb2req, NT_STATUS_INVALID_PARAMETER);
220 in_name_buffer.data = (uint8_t *)indyniov->iov_base + name_offset;
221 in_name_buffer.length = in_name_length;
223 if (in_context_offset == 0 && in_context_length == 0) {
224 /* This is ok */
225 context_offset = 0;
226 } else if (in_context_offset < dyn_offset) {
227 return smbd_smb2_request_error(smb2req, NT_STATUS_INVALID_PARAMETER);
228 } else {
229 context_offset = in_context_offset - dyn_offset;
232 if (context_offset > indyniov->iov_len) {
233 return smbd_smb2_request_error(smb2req, NT_STATUS_INVALID_PARAMETER);
236 context_available_length = indyniov->iov_len - context_offset;
238 if (in_context_length > context_available_length) {
239 return smbd_smb2_request_error(smb2req, NT_STATUS_INVALID_PARAMETER);
242 in_context_buffer.data = (uint8_t *)indyniov->iov_base +
243 context_offset;
244 in_context_buffer.length = in_context_length;
247 * Now interpret the name and context buffers
250 ok = convert_string_talloc(smb2req, CH_UTF16, CH_UNIX,
251 in_name_buffer.data,
252 in_name_buffer.length,
253 &in_name_string,
254 &in_name_string_size);
255 if (!ok) {
256 return smbd_smb2_request_error(smb2req, NT_STATUS_ILLEGAL_CHARACTER);
259 if (in_name_buffer.length == 0) {
260 in_name_string_size = 0;
263 if (strlen(in_name_string) != in_name_string_size) {
264 return smbd_smb2_request_error(smb2req, NT_STATUS_OBJECT_NAME_INVALID);
267 ZERO_STRUCT(in_context_blobs);
268 status = smb2_create_blob_parse(smb2req, in_context_buffer, &in_context_blobs);
269 if (!NT_STATUS_IS_OK(status)) {
270 return smbd_smb2_request_error(smb2req, status);
273 if (CHECK_DEBUGLVL(DBGLVL_DEBUG)) {
274 char *str = talloc_asprintf(
275 talloc_tos(),
276 "\nGot %"PRIu32" create blobs\n",
277 in_context_blobs.num_blobs);
278 uint32_t i;
280 for (i=0; i<in_context_blobs.num_blobs; i++) {
281 struct smb2_create_blob *b =
282 &in_context_blobs.blobs[i];
283 talloc_asprintf_addbuf(&str, "[%"PRIu32"]\n", i);
284 dump_data_addbuf(
285 (uint8_t *)b->tag, strlen(b->tag), &str);
286 dump_data_addbuf(
287 b->data.data, b->data.length, &str);
289 DBG_DEBUG("%s", str);
290 TALLOC_FREE(str);
293 tsubreq = smbd_smb2_create_send(smb2req,
294 smb2req->sconn->ev_ctx,
295 smb2req,
296 in_oplock_level,
297 in_impersonation_level,
298 in_desired_access,
299 in_file_attributes,
300 in_share_access,
301 in_create_disposition,
302 in_create_options,
303 in_name_string,
304 in_context_blobs);
305 if (tsubreq == NULL) {
306 smb2req->subreq = NULL;
307 return smbd_smb2_request_error(smb2req, NT_STATUS_NO_MEMORY);
309 tevent_req_set_callback(tsubreq, smbd_smb2_request_create_done, smb2req);
311 return smbd_smb2_request_pending_queue(smb2req, tsubreq, 500);
314 static uint64_t get_mid_from_smb2req(struct smbd_smb2_request *smb2req)
316 uint8_t *reqhdr = SMBD_SMB2_OUT_HDR_PTR(smb2req);
317 return BVAL(reqhdr, SMB2_HDR_MESSAGE_ID);
320 static void smbd_smb2_request_create_done(struct tevent_req *tsubreq)
322 struct smbd_smb2_request *smb2req = tevent_req_callback_data(tsubreq,
323 struct smbd_smb2_request);
324 DATA_BLOB outbody;
325 DATA_BLOB outdyn;
326 uint8_t out_oplock_level = 0;
327 uint32_t out_create_action = 0;
328 connection_struct *conn = smb2req->tcon->compat;
329 struct timespec out_creation_ts = { 0, };
330 struct timespec out_last_access_ts = { 0, };
331 struct timespec out_last_write_ts = { 0, };
332 struct timespec out_change_ts = { 0, };
333 uint64_t out_allocation_size = 0;
334 uint64_t out_end_of_file = 0;
335 uint32_t out_file_attributes = 0;
336 uint64_t out_file_id_persistent = 0;
337 uint64_t out_file_id_volatile = 0;
338 struct smb2_create_blobs out_context_blobs;
339 DATA_BLOB out_context_buffer;
340 uint16_t out_context_buffer_offset = 0;
341 NTSTATUS status;
342 NTSTATUS error; /* transport error */
344 status = smbd_smb2_create_recv(tsubreq,
345 smb2req,
346 &out_oplock_level,
347 &out_create_action,
348 &out_creation_ts,
349 &out_last_access_ts,
350 &out_last_write_ts,
351 &out_change_ts,
352 &out_allocation_size,
353 &out_end_of_file,
354 &out_file_attributes,
355 &out_file_id_persistent,
356 &out_file_id_volatile,
357 &out_context_blobs);
358 if (!NT_STATUS_IS_OK(status)) {
359 if (smbd_smb2_is_compound(smb2req)) {
360 smb2req->compound_create_err = status;
362 error = smbd_smb2_request_error(smb2req, status);
363 if (!NT_STATUS_IS_OK(error)) {
364 smbd_server_connection_terminate(smb2req->xconn,
365 nt_errstr(error));
366 return;
368 return;
371 status = smb2_create_blob_push(smb2req, &out_context_buffer, out_context_blobs);
372 if (!NT_STATUS_IS_OK(status)) {
373 error = smbd_smb2_request_error(smb2req, status);
374 if (!NT_STATUS_IS_OK(error)) {
375 smbd_server_connection_terminate(smb2req->xconn,
376 nt_errstr(error));
377 return;
379 return;
382 if (out_context_buffer.length > 0) {
383 out_context_buffer_offset = SMB2_HDR_BODY + 0x58;
386 outbody = smbd_smb2_generate_outbody(smb2req, 0x58);
387 if (outbody.data == NULL) {
388 error = smbd_smb2_request_error(smb2req, NT_STATUS_NO_MEMORY);
389 if (!NT_STATUS_IS_OK(error)) {
390 smbd_server_connection_terminate(smb2req->xconn,
391 nt_errstr(error));
392 return;
394 return;
397 SSVAL(outbody.data, 0x00, 0x58 + 1); /* struct size */
398 SCVAL(outbody.data, 0x02,
399 out_oplock_level); /* oplock level */
400 SCVAL(outbody.data, 0x03, 0); /* reserved */
401 SIVAL(outbody.data, 0x04,
402 out_create_action); /* create action */
403 put_long_date_full_timespec(conn->ts_res,
404 (char *)outbody.data + 0x08,
405 &out_creation_ts); /* creation time */
406 put_long_date_full_timespec(conn->ts_res,
407 (char *)outbody.data + 0x10,
408 &out_last_access_ts); /* last access time */
409 put_long_date_full_timespec(conn->ts_res,
410 (char *)outbody.data + 0x18,
411 &out_last_write_ts); /* last write time */
412 put_long_date_full_timespec(conn->ts_res,
413 (char *)outbody.data + 0x20,
414 &out_change_ts); /* change time */
415 SBVAL(outbody.data, 0x28,
416 out_allocation_size); /* allocation size */
417 SBVAL(outbody.data, 0x30,
418 out_end_of_file); /* end of file */
419 SIVAL(outbody.data, 0x38,
420 out_file_attributes); /* file attributes */
421 SIVAL(outbody.data, 0x3C, 0); /* reserved */
422 SBVAL(outbody.data, 0x40,
423 out_file_id_persistent); /* file id (persistent) */
424 SBVAL(outbody.data, 0x48,
425 out_file_id_volatile); /* file id (volatile) */
426 SIVAL(outbody.data, 0x50,
427 out_context_buffer_offset); /* create contexts offset */
428 SIVAL(outbody.data, 0x54,
429 out_context_buffer.length); /* create contexts length */
431 outdyn = out_context_buffer;
433 error = smbd_smb2_request_done(smb2req, outbody, &outdyn);
434 if (!NT_STATUS_IS_OK(error)) {
435 smbd_server_connection_terminate(smb2req->xconn,
436 nt_errstr(error));
437 return;
441 static bool smb2_lease_key_valid(const struct smb2_lease_key *key)
443 return ((key->data[0] != 0) || (key->data[1] != 0));
446 static NTSTATUS smbd_smb2_create_durable_lease_check(struct smb_request *smb1req,
447 const char *requested_filename, const struct files_struct *fsp,
448 const struct smb2_lease *lease_ptr)
450 struct files_struct *dirfsp = NULL;
451 char *filename = NULL;
452 struct smb_filename *smb_fname = NULL;
453 uint32_t ucf_flags;
454 NTTIME twrp = fsp->fsp_name->twrp;
455 NTSTATUS status;
456 bool is_dfs = (smb1req->flags2 & FLAGS2_DFS_PATHNAMES);
457 bool is_posix = (fsp->fsp_name->flags & SMB_FILENAME_POSIX_PATH);
459 if (lease_ptr == NULL) {
460 if (fsp->oplock_type != LEASE_OPLOCK) {
461 return NT_STATUS_OK;
463 DEBUG(10, ("Reopened file has lease, but no lease "
464 "requested\n"));
465 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
468 if (fsp->oplock_type != LEASE_OPLOCK) {
469 DEBUG(10, ("Lease requested, but reopened file has no "
470 "lease\n"));
471 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
474 if (!smb2_lease_key_equal(&lease_ptr->lease_key,
475 &fsp->lease->lease.lease_key)) {
476 DEBUG(10, ("Different lease key requested than found "
477 "in reopened file\n"));
478 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
481 if (is_dfs) {
482 const char *non_dfs_requested_filename = NULL;
484 * With a DFS flag set, remove any DFS prefix
485 * before further processing.
487 status = smb2_strip_dfs_path(requested_filename,
488 &non_dfs_requested_filename);
489 if (!NT_STATUS_IS_OK(status)) {
490 return status;
493 * TODO: Note for dealing with reparse point errors.
494 * We will need to remember and store the number of characters
495 * we have removed here, which is
496 * (requested_filename - non_dfs_requested_filename)
497 * in order to correctly report how many characters we
498 * have removed before hitting the reparse point.
499 * This will be a patch needed once we properly
500 * deal with reparse points later.
502 requested_filename = non_dfs_requested_filename;
504 * Now we're no longer dealing with a DFS path, so
505 * remove the flag.
507 smb1req->flags2 &= ~FLAGS2_DFS_PATHNAMES;
508 is_dfs = false;
511 filename = talloc_strdup(talloc_tos(), requested_filename);
512 if (filename == NULL) {
513 return NT_STATUS_NO_MEMORY;
516 /* This also converts '\' to '/' */
517 status = check_path_syntax(filename, is_posix);
518 if (!NT_STATUS_IS_OK(status)) {
519 TALLOC_FREE(filename);
520 return status;
523 ucf_flags = filename_create_ucf_flags(smb1req, FILE_OPEN);
524 status = filename_convert_dirfsp(talloc_tos(),
525 fsp->conn,
526 filename,
527 ucf_flags,
528 twrp,
529 &dirfsp,
530 &smb_fname);
531 TALLOC_FREE(filename);
532 if (!NT_STATUS_IS_OK(status)) {
533 DEBUG(10, ("filename_convert returned %s\n",
534 nt_errstr(status)));
535 return status;
538 if (!strequal(fsp->fsp_name->base_name, smb_fname->base_name)) {
539 DEBUG(10, ("Lease requested for file %s, reopened file "
540 "is named %s\n", smb_fname->base_name,
541 fsp->fsp_name->base_name));
542 TALLOC_FREE(smb_fname);
543 return NT_STATUS_INVALID_PARAMETER;
546 TALLOC_FREE(smb_fname);
548 return NT_STATUS_OK;
551 struct smbd_smb2_create_state {
552 struct tevent_context *ev;
553 struct smbd_smb2_request *smb2req;
554 struct GUID req_guid;
555 struct smb_request *smb1req;
556 bool open_was_deferred;
557 struct tevent_immediate *im;
558 struct timeval request_time;
559 struct file_id id;
560 struct deferred_open_record *open_rec;
561 files_struct *result;
562 bool replay_operation;
563 uint8_t in_oplock_level;
564 uint32_t in_create_disposition;
565 uint32_t in_create_options;
566 int requested_oplock_level;
567 int info;
568 char *fname;
569 struct ea_list *ea_list;
570 NTTIME max_access_time;
571 struct security_descriptor *sec_desc;
572 uint64_t allocation_size;
573 struct GUID _create_guid;
574 struct GUID *create_guid;
575 struct GUID _purge_create_guid;
576 struct GUID *purge_create_guid;
577 bool update_open;
578 bool durable_requested;
579 uint32_t durable_timeout_msec;
580 bool do_durable_reconnect;
581 uint64_t persistent_id;
582 struct smb2_lease lease;
583 struct smb2_lease *lease_ptr;
584 ssize_t lease_len;
585 bool need_replay_cache;
586 struct smbXsrv_open *op;
587 NTTIME twrp_time;
589 struct smb2_create_blob *dhnc;
590 struct smb2_create_blob *dh2c;
591 struct smb2_create_blob *dhnq;
592 struct smb2_create_blob *dh2q;
593 struct smb2_create_blob *rqls;
594 struct smb2_create_blob *exta;
595 struct smb2_create_blob *mxac;
596 struct smb2_create_blob *secd;
597 struct smb2_create_blob *alsi;
598 struct smb2_create_blob *twrp;
599 struct smb2_create_blob *qfid;
600 struct smb2_create_blob *posx;
601 struct smb2_create_blob *svhdx;
603 uint8_t out_oplock_level;
604 uint32_t out_create_action;
605 struct timespec out_creation_ts;
606 struct timespec out_last_access_ts;
607 struct timespec out_last_write_ts;
608 struct timespec out_change_ts;
609 uint64_t out_allocation_size;
610 uint64_t out_end_of_file;
611 uint32_t out_file_attributes;
612 uint64_t out_file_id_persistent;
613 uint64_t out_file_id_volatile;
614 struct smb2_create_blobs *out_context_blobs;
617 static void smbd_smb2_create_purge_replay_cache(struct tevent_req *req,
618 const char *caller_func);
620 static void smbd_smb2_create_cleanup(struct tevent_req *req,
621 enum tevent_req_state req_state)
623 smbd_smb2_create_purge_replay_cache(req, __func__);
626 static NTSTATUS smbd_smb2_create_fetch_create_ctx(
627 struct tevent_req *req,
628 struct smb2_create_blobs *in_context_blobs)
630 struct smbd_smb2_create_state *state = tevent_req_data(
631 req, struct smbd_smb2_create_state);
632 struct smbd_smb2_request *smb2req = state->smb2req;
633 struct smbXsrv_connection *xconn = smb2req->xconn;
635 state->dhnq = smb2_create_blob_find(in_context_blobs,
636 SMB2_CREATE_TAG_DHNQ);
637 state->dhnc = smb2_create_blob_find(in_context_blobs,
638 SMB2_CREATE_TAG_DHNC);
639 state->dh2q = smb2_create_blob_find(in_context_blobs,
640 SMB2_CREATE_TAG_DH2Q);
641 state->dh2c = smb2_create_blob_find(in_context_blobs,
642 SMB2_CREATE_TAG_DH2C);
643 if (xconn->smb2.server.capabilities & SMB2_CAP_LEASING) {
644 state->rqls = smb2_create_blob_find(in_context_blobs,
645 SMB2_CREATE_TAG_RQLS);
648 if (((state->dhnc != NULL) && (state->dh2c != NULL)) ||
649 ((state->dhnc != NULL) && (state->dh2q != NULL)) ||
650 ((state->dh2c != NULL) && (state->dhnq != NULL)) ||
651 ((state->dh2q != NULL) && (state->dh2c != NULL)))
653 /* not both are allowed at the same time */
654 return NT_STATUS_INVALID_PARAMETER;
657 if (state->dhnc != NULL) {
658 uint32_t num_blobs_allowed;
660 if (state->dhnc->data.length != 16) {
661 return NT_STATUS_INVALID_PARAMETER;
665 * According to MS-SMB2: 3.3.5.9.7, "Handling the
666 * SMB2_CREATE_DURABLE_HANDLE_RECONNECT Create Context",
667 * we should ignore an additional dhnq blob, but fail
668 * the request (with status OBJECT_NAME_NOT_FOUND) if
669 * any other extra create blob has been provided.
671 * (Note that the cases of an additional dh2q or dh2c blob
672 * which require a different error code, have been treated
673 * above.)
676 if (state->dhnq != NULL) {
677 num_blobs_allowed = 2;
678 } else {
679 num_blobs_allowed = 1;
682 if (state->rqls != NULL) {
683 num_blobs_allowed += 1;
686 if (in_context_blobs->num_blobs != num_blobs_allowed) {
687 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
691 if (state->dh2c!= NULL) {
692 uint32_t num_blobs_allowed;
694 if (state->dh2c->data.length != 36) {
695 return NT_STATUS_INVALID_PARAMETER;
699 * According to MS-SMB2: 3.3.5.9.12, "Handling the
700 * SMB2_CREATE_DURABLE_HANDLE_RECONNECT_V2 Create Context",
701 * we should fail the request with status
702 * OBJECT_NAME_NOT_FOUND if any other create blob has been
703 * provided.
705 * (Note that the cases of an additional dhnq, dhnc or dh2q
706 * blob which require a different error code, have been
707 * treated above.)
710 num_blobs_allowed = 1;
712 if (state->rqls != NULL) {
713 num_blobs_allowed += 1;
716 if (in_context_blobs->num_blobs != num_blobs_allowed) {
717 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
721 state->exta = smb2_create_blob_find(in_context_blobs,
722 SMB2_CREATE_TAG_EXTA);
723 state->mxac = smb2_create_blob_find(in_context_blobs,
724 SMB2_CREATE_TAG_MXAC);
725 state->secd = smb2_create_blob_find(in_context_blobs,
726 SMB2_CREATE_TAG_SECD);
727 state->alsi = smb2_create_blob_find(in_context_blobs,
728 SMB2_CREATE_TAG_ALSI);
729 state->twrp = smb2_create_blob_find(in_context_blobs,
730 SMB2_CREATE_TAG_TWRP);
731 state->qfid = smb2_create_blob_find(in_context_blobs,
732 SMB2_CREATE_TAG_QFID);
733 if (xconn->protocol >= PROTOCOL_SMB3_02) {
735 * This was introduced with SMB3_02
737 state->svhdx = smb2_create_blob_find(
738 in_context_blobs, SVHDX_OPEN_DEVICE_CONTEXT);
740 if (xconn->smb2.server.posix_extensions_negotiated &&
741 lp_smb3_unix_extensions(SNUM(state->smb1req->conn)))
744 * Negprot only allowed this for proto>=3.11
746 SMB_ASSERT(xconn->protocol >= PROTOCOL_SMB3_11);
748 state->posx = smb2_create_blob_find(
749 in_context_blobs, SMB2_CREATE_TAG_POSIX);
751 * Setting the bool below will cause
752 * ucf_flags_from_smb_request() to
753 * return UCF_POSIX_PATHNAMES in ucf_flags.
755 state->smb1req->posix_pathnames = (state->posx != NULL);
758 return NT_STATUS_OK;
761 static void smbd_smb2_create_before_exec(struct tevent_req *req);
762 static void smbd_smb2_create_after_exec(struct tevent_req *req);
763 static void smbd_smb2_create_finish(struct tevent_req *req);
765 static struct tevent_req *smbd_smb2_create_send(TALLOC_CTX *mem_ctx,
766 struct tevent_context *ev,
767 struct smbd_smb2_request *smb2req,
768 uint8_t in_oplock_level,
769 uint32_t in_impersonation_level,
770 uint32_t in_desired_access,
771 uint32_t in_file_attributes,
772 uint32_t in_share_access,
773 uint32_t in_create_disposition,
774 uint32_t _in_create_options,
775 const char *in_name,
776 struct smb2_create_blobs in_context_blobs)
778 struct tevent_req *req = NULL;
779 struct smbd_smb2_create_state *state = NULL;
780 NTSTATUS status;
781 struct smb_request *smb1req = NULL;
782 struct files_struct *dirfsp = NULL;
783 struct smb_filename *smb_fname = NULL;
784 uint32_t ucf_flags;
785 bool is_dfs = false;
786 bool is_posix = false;
788 req = tevent_req_create(mem_ctx, &state,
789 struct smbd_smb2_create_state);
790 if (req == NULL) {
791 return NULL;
793 *state = (struct smbd_smb2_create_state) {
794 .ev = ev,
795 .smb2req = smb2req,
796 .in_oplock_level = in_oplock_level,
797 .in_create_disposition = in_create_disposition,
798 .in_create_options = _in_create_options,
801 smb1req = smbd_smb2_fake_smb_request(smb2req, NULL);
802 if (tevent_req_nomem(smb1req, req)) {
803 return tevent_req_post(req, state->ev);
805 state->smb1req = smb1req;
807 state->req_guid = smbd_request_guid(smb1req, 0);
809 tevent_req_set_cleanup_fn(req, smbd_smb2_create_cleanup);
811 if (smb2req->subreq == NULL) {
812 DBG_DEBUG("name [%s]\n", in_name);
813 } else {
814 struct smbd_smb2_create_state *old_state = tevent_req_data(
815 smb2req->subreq, struct smbd_smb2_create_state);
817 DBG_DEBUG("reentrant for file %s\n", in_name);
819 state->id = old_state->id;
820 state->request_time = old_state->request_time;
821 state->open_rec = talloc_move(state, &old_state->open_rec);
822 state->open_was_deferred = old_state->open_was_deferred;
823 state->_purge_create_guid = old_state->_purge_create_guid;
824 state->purge_create_guid = old_state->purge_create_guid;
825 old_state->purge_create_guid = NULL;
828 TALLOC_FREE(smb2req->subreq);
829 smb2req->subreq = req;
831 if (lp_fake_oplocks(SNUM(smb2req->tcon->compat))) {
832 state->requested_oplock_level = SMB2_OPLOCK_LEVEL_NONE;
833 } else {
834 state->requested_oplock_level = state->in_oplock_level;
837 /* these are ignored for SMB2 */
838 state->in_create_options &= ~(0x10); /* NTCREATEX_OPTIONS_SYNC_ALERT */
839 state->in_create_options &= ~(0x20); /* NTCREATEX_OPTIONS_ASYNC_ALERT */
841 in_file_attributes &= ~FILE_FLAG_POSIX_SEMANTICS;
843 is_dfs = (smb1req->flags2 & FLAGS2_DFS_PATHNAMES);
844 if (is_dfs) {
845 const char *non_dfs_in_name = NULL;
847 * With a DFS flag set, remove any DFS prefix
848 * before further processing.
850 status = smb2_strip_dfs_path(in_name, &non_dfs_in_name);
851 if (!NT_STATUS_IS_OK(status)) {
852 tevent_req_nterror(req, status);
853 return tevent_req_post(req, state->ev);
856 * TODO: Note for dealing with reparse point errors.
857 * We will need to remember and store the number of characters
858 * we have removed here, which is (non_dfs_in_name - in_name)
859 * in order to correctly report how many characters we
860 * have removed before hitting the reparse point.
861 * This will be a patch needed once we properly
862 * deal with reparse points later.
864 in_name = non_dfs_in_name;
866 * Now we're no longer dealing with a DFS path, so
867 * remove the flag.
869 smb1req->flags2 &= ~FLAGS2_DFS_PATHNAMES;
870 is_dfs = false;
873 state->fname = talloc_strdup(state, in_name);
874 if (tevent_req_nomem(state->fname, req)) {
875 return tevent_req_post(req, state->ev);
878 state->out_context_blobs = talloc_zero(state, struct smb2_create_blobs);
879 if (tevent_req_nomem(state->out_context_blobs, req)) {
880 return tevent_req_post(req, state->ev);
883 status = smbd_smb2_create_fetch_create_ctx(req, &in_context_blobs);
884 if (tevent_req_nterror(req, status)) {
885 return tevent_req_post(req, state->ev);
888 if (IS_IPC(smb1req->conn)) {
889 const char *pipe_name = in_name;
891 if (state->dhnc != NULL || state->dh2c != NULL) {
892 /* durable handles are not supported on IPC$ */
893 tevent_req_nterror(req, NT_STATUS_OBJECT_NAME_NOT_FOUND);
894 return tevent_req_post(req, state->ev);
897 if (!lp_nt_pipe_support()) {
898 tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
899 return tevent_req_post(req, state->ev);
902 status = open_np_file(smb1req, pipe_name, &state->result);
903 if (tevent_req_nterror(req, status)) {
904 return tevent_req_post(req, state->ev);
906 state->info = FILE_WAS_OPENED;
908 smbd_smb2_create_finish(req);
909 return req;
912 if (CAN_PRINT(smb1req->conn)) {
913 if (state->dhnc != NULL || state->dh2c != NULL) {
914 /* durable handles are not supported on printers */
915 tevent_req_nterror(req, NT_STATUS_OBJECT_NAME_NOT_FOUND);
916 return tevent_req_post(req, state->ev);
919 status = file_new(smb1req, smb1req->conn, &state->result);
920 if (tevent_req_nterror(req, status)) {
921 return tevent_req_post(req, state->ev);
924 status = print_spool_open(state->result, in_name,
925 smb1req->vuid);
926 if (tevent_req_nterror(req, status)) {
927 file_free(smb1req, state->result);
928 return tevent_req_post(req, state->ev);
930 state->info = FILE_WAS_CREATED;
932 smbd_smb2_create_finish(req);
933 return req;
936 /* Check for trailing slash specific directory handling. */
937 status = windows_name_trailing_check(state->fname,
938 state->in_create_options);
939 if (tevent_req_nterror(req, status)) {
940 return tevent_req_post(req, state->ev);
943 smbd_smb2_create_before_exec(req);
944 if (!tevent_req_is_in_progress(req)) {
945 return tevent_req_post(req, state->ev);
948 DBG_DEBUG("open execution phase\n");
951 * For the backend file open procedure, there are
952 * three possible modes: replay operation (in which case
953 * there is nothing else to do), durable_reconnect or
954 * new open.
956 if (state->replay_operation) {
957 state->result = state->op->compat;
958 state->result->op = state->op;
959 state->update_open = false;
960 state->info = state->op->create_action;
962 smbd_smb2_create_after_exec(req);
963 if (!tevent_req_is_in_progress(req)) {
964 return tevent_req_post(req, state->ev);
967 smbd_smb2_create_finish(req);
968 return req;
971 if (state->do_durable_reconnect) {
972 DATA_BLOB new_cookie = data_blob_null;
973 NTTIME now = timeval_to_nttime(&smb2req->request_time);
975 status = smb2srv_open_recreate(smb2req->xconn,
976 smb1req->conn->session_info,
977 state->persistent_id,
978 state->create_guid,
979 now,
980 &state->op);
981 if (tevent_req_nterror(req, status)) {
982 DBG_NOTICE("smb2srv_open_recreate failed: %s\n",
983 nt_errstr(status));
984 return tevent_req_post(req, state->ev);
987 DBG_DEBUG("%s to recreate durable handle\n",
988 state->op->global->durable ? "succeeded" : "failed");
990 if (!state->op->global->durable) {
991 talloc_free(state->op);
992 tevent_req_nterror(req,
993 NT_STATUS_OBJECT_NAME_NOT_FOUND);
994 return tevent_req_post(req, state->ev);
997 status = SMB_VFS_DURABLE_RECONNECT(smb1req->conn,
998 smb1req,
999 state->op, /* smbXsrv_open input */
1000 state->op->global->backend_cookie,
1001 state->op, /* TALLOC_CTX */
1002 &state->result,
1003 &new_cookie);
1004 if (!NT_STATUS_IS_OK(status)) {
1005 NTSTATUS return_status;
1007 return_status = NT_STATUS_OBJECT_NAME_NOT_FOUND;
1009 DBG_NOTICE("durable_reconnect failed: %s => %s\n",
1010 nt_errstr(status),
1011 nt_errstr(return_status));
1013 tevent_req_nterror(req, return_status);
1014 return tevent_req_post(req, state->ev);
1017 DBG_DEBUG("oplock_type=%u, lease_ptr==%p\n",
1018 (unsigned)state->result->oplock_type, state->lease_ptr);
1020 status = smbd_smb2_create_durable_lease_check(
1021 smb1req, state->fname, state->result, state->lease_ptr);
1022 if (tevent_req_nterror(req, status)) {
1023 close_file_free(
1024 smb1req, &state->result, SHUTDOWN_CLOSE);
1025 return tevent_req_post(req, state->ev);
1028 data_blob_free(&state->op->global->backend_cookie);
1029 state->op->global->backend_cookie = new_cookie;
1031 state->op->status = NT_STATUS_OK;
1032 state->op->global->disconnect_time = 0;
1034 /* save the timeout for later update */
1035 state->durable_timeout_msec = state->op->global->durable_timeout_msec;
1037 state->update_open = true;
1039 state->info = FILE_WAS_OPENED;
1041 smbd_smb2_create_after_exec(req);
1042 if (!tevent_req_is_in_progress(req)) {
1043 return tevent_req_post(req, state->ev);
1046 smbd_smb2_create_finish(req);
1047 return req;
1050 if (state->requested_oplock_level == SMB2_OPLOCK_LEVEL_LEASE) {
1051 if (state->lease_ptr == NULL) {
1052 state->requested_oplock_level = SMB2_OPLOCK_LEVEL_NONE;
1054 } else {
1055 state->lease_ptr = NULL;
1058 is_posix = (state->posx != NULL);
1060 /* convert '\\' into '/' */
1061 status = check_path_syntax(state->fname, is_posix);
1062 if (tevent_req_nterror(req, status)) {
1063 return tevent_req_post(req, state->ev);
1066 ucf_flags = filename_create_ucf_flags(
1067 smb1req, state->in_create_disposition);
1069 status = filename_convert_dirfsp(
1070 req,
1071 smb1req->conn,
1072 state->fname,
1073 ucf_flags,
1074 state->twrp_time,
1075 &dirfsp,
1076 &smb_fname);
1077 if (tevent_req_nterror(req, status)) {
1078 return tevent_req_post(req, state->ev);
1082 * MS-SMB2: 2.2.13 SMB2 CREATE Request
1083 * ImpersonationLevel ... MUST contain one of the
1084 * following values. The server MUST validate this
1085 * field, but otherwise ignore it.
1087 * NB. The source4/torture/smb2/durable_open.c test
1088 * shows this check is only done on real opens, not
1089 * on durable handle-reopens.
1092 if (in_impersonation_level >
1093 SMB2_IMPERSONATION_DELEGATE) {
1094 tevent_req_nterror(req,
1095 NT_STATUS_BAD_IMPERSONATION_LEVEL);
1096 return tevent_req_post(req, state->ev);
1100 * We know we're going to do a local open, so now
1101 * we must be protocol strict. JRA.
1103 * MS-SMB2: 3.3.5.9 - Receiving an SMB2 CREATE Request
1104 * If the file name length is greater than zero and the
1105 * first character is a path separator character, the
1106 * server MUST fail the request with
1107 * STATUS_INVALID_PARAMETER.
1109 if (in_name[0] == '/') {
1110 /* Names starting with '/' are never allowed. */
1111 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
1112 return tevent_req_post(req, ev);
1114 if (!is_posix && (in_name[0] == '\\')) {
1116 * Windows names starting with '\' are not allowed.
1118 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
1119 return tevent_req_post(req, ev);
1122 status = SMB_VFS_CREATE_FILE(smb1req->conn,
1123 smb1req,
1124 dirfsp,
1125 smb_fname,
1126 in_desired_access,
1127 in_share_access,
1128 state->in_create_disposition,
1129 state->in_create_options,
1130 in_file_attributes,
1131 map_smb2_oplock_levels_to_samba(
1132 state->requested_oplock_level),
1133 state->lease_ptr,
1134 state->allocation_size,
1135 0, /* private_flags */
1136 state->sec_desc,
1137 state->ea_list,
1138 &state->result,
1139 &state->info,
1140 &in_context_blobs,
1141 state->out_context_blobs);
1142 if (NT_STATUS_IS_OK(status) &&
1143 !(state->in_create_options & FILE_OPEN_REPARSE_POINT))
1146 mode_t mode = state->result->fsp_name->st.st_ex_mode;
1148 if (!(S_ISREG(mode) || S_ISDIR(mode))) {
1150 * Only open files and dirs without
1151 * FILE_OPEN_REPARSE_POINT
1153 close_file_free(smb1req, &state->result, ERROR_CLOSE);
1154 status = NT_STATUS_IO_REPARSE_TAG_NOT_HANDLED;
1157 if (!NT_STATUS_IS_OK(status)) {
1158 if (open_was_deferred(smb1req->xconn, smb1req->mid)) {
1159 SMBPROFILE_IOBYTES_ASYNC_SET_IDLE(smb2req->profile);
1160 return req;
1162 tevent_req_nterror(req, status);
1163 return tevent_req_post(req, state->ev);
1165 state->op = state->result->op;
1167 smbd_smb2_create_after_exec(req);
1168 if (!tevent_req_is_in_progress(req)) {
1169 return tevent_req_post(req, state->ev);
1172 smbd_smb2_create_finish(req);
1173 return req;
1176 static void smbd_smb2_create_purge_replay_cache(struct tevent_req *req,
1177 const char *caller_func)
1179 struct smbd_smb2_create_state *state = tevent_req_data(
1180 req, struct smbd_smb2_create_state);
1181 NTSTATUS status;
1183 if (state->purge_create_guid == NULL) {
1184 return;
1187 status = smbXsrv_open_purge_replay_cache(state->smb2req->xconn->client,
1188 state->purge_create_guid);
1189 if (!NT_STATUS_IS_OK(status)) {
1190 struct GUID_txt_buf buf;
1192 D_ERR("%s: smbXsrv_open_purge_replay_cache(%s) %s\n",
1193 caller_func,
1194 GUID_buf_string(state->purge_create_guid, &buf),
1195 nt_errstr(status));
1198 state->purge_create_guid = NULL;
1201 static void smbd_smb2_create_before_exec(struct tevent_req *req)
1203 struct smbd_smb2_create_state *state = tevent_req_data(
1204 req, struct smbd_smb2_create_state);
1205 struct smbd_smb2_request *smb2req = state->smb2req;
1206 NTSTATUS status;
1208 if (state->exta != NULL) {
1209 if (!lp_ea_support(SNUM(smb2req->tcon->compat))) {
1210 tevent_req_nterror(req, NT_STATUS_EAS_NOT_SUPPORTED);
1211 return;
1214 state->ea_list = read_nttrans_ea_list(
1215 state,
1216 (const char *)state->exta->data.data,
1217 state->exta->data.length);
1218 if (state->ea_list == NULL) {
1219 DEBUG(10,("smbd_smb2_create_send: read_ea_name_list failed.\n"));
1220 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
1221 return;
1224 if ((state->posx == NULL) &&
1225 ea_list_has_invalid_name(state->ea_list)) {
1226 tevent_req_nterror(req, STATUS_INVALID_EA_NAME);
1227 return;
1231 if (state->mxac != NULL) {
1232 if (state->mxac->data.length == 0) {
1233 state->max_access_time = 0;
1234 } else if (state->mxac->data.length == 8) {
1235 state->max_access_time = BVAL(state->mxac->data.data, 0);
1236 } else {
1237 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
1238 return;
1242 if (state->secd != NULL) {
1243 enum ndr_err_code ndr_err;
1245 state->sec_desc = talloc_zero(state, struct security_descriptor);
1246 if (tevent_req_nomem(state->sec_desc, req)) {
1247 return;
1250 ndr_err = ndr_pull_struct_blob(&state->secd->data,
1251 state->sec_desc, state->sec_desc,
1252 (ndr_pull_flags_fn_t)ndr_pull_security_descriptor);
1253 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1254 DEBUG(2,("ndr_pull_security_descriptor failed: %s\n",
1255 ndr_errstr(ndr_err)));
1256 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
1257 return;
1261 if (state->dhnq != NULL) {
1262 if (state->dhnq->data.length != 16) {
1263 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
1264 return;
1267 if (state->dh2q != NULL) {
1268 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
1269 return;
1273 * durable handle request is processed below.
1275 state->durable_requested = true;
1277 * Set the timeout to 16 mins.
1279 * TODO: test this against Windows 2012
1280 * as the default for durable v2 is 1 min.
1282 state->durable_timeout_msec = (16*60*1000);
1285 if (state->dh2q != NULL) {
1286 const uint8_t *p = state->dh2q->data.data;
1287 NTTIME now = timeval_to_nttime(&smb2req->request_time);
1288 uint32_t durable_v2_timeout = 0;
1289 DATA_BLOB create_guid_blob;
1290 const uint8_t *hdr;
1291 uint32_t flags;
1293 if (state->dh2q->data.length != 32) {
1294 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
1295 return;
1298 if (state->dhnq != NULL) {
1299 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
1300 return;
1303 durable_v2_timeout = IVAL(p, 0);
1304 create_guid_blob = data_blob_const(p + 16, 16);
1306 status = GUID_from_ndr_blob(&create_guid_blob,
1307 &state->_create_guid);
1308 if (tevent_req_nterror(req, status)) {
1309 return;
1311 state->create_guid = &state->_create_guid;
1314 * we need to store the create_guid later
1316 state->update_open = true;
1319 * And we need to create a cache for replaying the
1320 * create.
1322 state->need_replay_cache = true;
1325 * durable handle v2 request processed below
1327 state->durable_requested = true;
1328 state->durable_timeout_msec = MIN(durable_v2_timeout, 300*1000);
1329 if (state->durable_timeout_msec == 0) {
1331 * Set the timeout to 1 min as default.
1333 * This matches Windows 2012.
1335 state->durable_timeout_msec = (60*1000);
1339 * Check for replay operation.
1340 * Only consider it when we have dh2q.
1341 * If we do not have a replay operation, verify that
1342 * the create_guid is not cached for replay.
1344 hdr = SMBD_SMB2_IN_HDR_PTR(smb2req);
1345 flags = IVAL(hdr, SMB2_HDR_FLAGS);
1346 state->replay_operation =
1347 flags & SMB2_HDR_FLAG_REPLAY_OPERATION;
1349 status = smb2srv_open_lookup_replay_cache(smb2req->xconn,
1350 state->req_guid,
1351 *state->create_guid,
1352 state->fname,
1353 now,
1354 &state->op);
1355 if (NT_STATUS_EQUAL(status, NT_STATUS_FWP_RESERVED)) {
1357 * We've reserved the replay_cache record
1358 * for ourself, indicating we're still
1359 * in progress.
1361 * It means the smbd_smb2_create_cleanup()
1362 * may need to call smbXsrv_open_purge_replay_cache()
1363 * in order to cleanup.
1365 SMB_ASSERT(state->op == NULL);
1366 state->_purge_create_guid = state->_create_guid;
1367 state->purge_create_guid = &state->_purge_create_guid;
1368 status = NT_STATUS_OK;
1369 state->replay_operation = false;
1370 } else if (NT_STATUS_EQUAL(status, NT_STATUS_FILE_NOT_AVAILABLE)) {
1371 tevent_req_nterror(req, status);
1372 return;
1373 } else if (tevent_req_nterror(req, status)) {
1374 DBG_WARNING("smb2srv_open_lookup_replay_cache "
1375 "failed: %s\n", nt_errstr(status));
1376 return;
1377 } else if (!state->replay_operation) {
1379 * If a create without replay operation flag
1380 * is sent but with a create_guid that is
1381 * currently in the replay cache -- fail.
1383 status = NT_STATUS_DUPLICATE_OBJECTID;
1384 (void)tevent_req_nterror(req, status);
1385 return;
1389 if (state->dhnc != NULL) {
1390 state->persistent_id = BVAL(state->dhnc->data.data, 0);
1391 state->do_durable_reconnect = true;
1394 if (state->dh2c != NULL) {
1395 const uint8_t *p = state->dh2c->data.data;
1396 DATA_BLOB create_guid_blob;
1398 state->persistent_id = BVAL(p, 0);
1399 create_guid_blob = data_blob_const(p + 16, 16);
1401 status = GUID_from_ndr_blob(&create_guid_blob,
1402 &state->_create_guid);
1403 if (tevent_req_nterror(req, status)) {
1404 return;
1407 state->create_guid = &state->_create_guid;
1408 state->do_durable_reconnect = true;
1411 if (state->alsi != NULL) {
1412 if (state->alsi->data.length != 8) {
1413 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
1414 return;
1416 state->allocation_size = BVAL(state->alsi->data.data, 0);
1419 if (state->twrp != NULL) {
1420 if (state->twrp->data.length != 8) {
1421 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
1422 return;
1425 state->twrp_time = BVAL(state->twrp->data.data, 0);
1428 if (state->qfid != NULL) {
1429 if (state->qfid->data.length != 0) {
1430 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
1431 return;
1435 if (state->rqls != NULL) {
1436 ssize_t lease_len = -1;
1438 lease_len = smb2_lease_pull(state->rqls->data.data,
1439 state->rqls->data.length,
1440 &state->lease);
1441 if (lease_len == -1) {
1442 tevent_req_nterror(
1443 req, NT_STATUS_INVALID_PARAMETER);
1444 return;
1446 state->lease_ptr = &state->lease;
1448 if (DEBUGLEVEL >= 10) {
1449 DEBUG(10, ("Got lease request size %d\n",
1450 (int)lease_len));
1451 NDR_PRINT_DEBUG(smb2_lease, state->lease_ptr);
1454 if (!smb2_lease_key_valid(&state->lease.lease_key)) {
1455 state->lease_ptr = NULL;
1456 state->requested_oplock_level = SMB2_OPLOCK_LEVEL_NONE;
1459 if ((smb2req->xconn->protocol < PROTOCOL_SMB3_00) &&
1460 (state->lease.lease_version != 1))
1462 DEBUG(10, ("v2 lease key only for SMB3\n"));
1463 state->lease_ptr = NULL;
1467 * Replay with a lease is only allowed if the
1468 * established open carries a lease with the
1469 * same lease key.
1471 if (state->replay_operation) {
1472 struct smb2_lease *op_ls =
1473 &state->op->compat->lease->lease;
1474 int op_oplock = state->op->compat->oplock_type;
1476 if (map_samba_oplock_levels_to_smb2(op_oplock)
1477 != SMB2_OPLOCK_LEVEL_LEASE)
1479 status = NT_STATUS_ACCESS_DENIED;
1480 (void)tevent_req_nterror(req, status);
1481 return;
1483 if (!smb2_lease_key_equal(&state->lease.lease_key,
1484 &op_ls->lease_key))
1486 status = NT_STATUS_ACCESS_DENIED;
1487 (void)tevent_req_nterror(req, status);
1488 return;
1493 if (state->posx != NULL) {
1494 if (state->posx->data.length != 4) {
1495 DBG_DEBUG("Got %zu bytes POSX cctx, expected 4\n",
1496 state->posx->data.length);
1497 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
1498 return;
1503 static void smbd_smb2_create_after_exec(struct tevent_req *req)
1505 struct smbd_smb2_create_state *state = tevent_req_data(
1506 req, struct smbd_smb2_create_state);
1507 connection_struct *conn = state->result->conn;
1508 NTSTATUS status;
1511 * here we have op == result->op
1514 DBG_DEBUG("response construction phase\n");
1516 state->out_file_attributes = fdos_mode(state->result);
1518 if (state->mxac != NULL) {
1519 NTTIME last_write_time;
1521 last_write_time = full_timespec_to_nt_time(
1522 &state->result->fsp_name->st.st_ex_mtime);
1523 if (last_write_time != state->max_access_time) {
1524 uint8_t p[8];
1525 uint32_t max_access_granted;
1526 DATA_BLOB blob = data_blob_const(p, sizeof(p));
1528 status = smbd_calculate_access_mask_fsp(
1529 conn->cwd_fsp,
1530 state->result,
1531 false,
1532 SEC_FLAG_MAXIMUM_ALLOWED,
1533 &max_access_granted);
1535 SIVAL(p, 0, NT_STATUS_V(status));
1536 SIVAL(p, 4, max_access_granted);
1538 status = smb2_create_blob_add(
1539 state->out_context_blobs,
1540 state->out_context_blobs,
1541 SMB2_CREATE_TAG_MXAC,
1542 blob);
1543 if (!NT_STATUS_IS_OK(status)) {
1544 goto fail;
1549 if (!state->replay_operation && state->durable_requested &&
1550 (fsp_lease_type(state->result) & SMB2_LEASE_HANDLE))
1552 status = SMB_VFS_DURABLE_COOKIE(
1553 state->result,
1554 state->op,
1555 &state->op->global->backend_cookie);
1556 if (!NT_STATUS_IS_OK(status)) {
1557 state->op->global->backend_cookie = data_blob_null;
1560 if (!state->replay_operation && state->op->global->backend_cookie.length > 0)
1562 state->update_open = true;
1564 state->op->global->durable = true;
1565 state->op->global->durable_timeout_msec = state->durable_timeout_msec;
1568 if (state->update_open) {
1569 state->op->global->create_guid = state->_create_guid;
1570 if (state->need_replay_cache) {
1571 state->op->flags |= SMBXSRV_OPEN_NEED_REPLAY_CACHE;
1574 status = smbXsrv_open_update(state->op);
1575 DEBUG(10, ("smb2_create_send: smbXsrv_open_update "
1576 "returned %s\n",
1577 nt_errstr(status)));
1578 if (!NT_STATUS_IS_OK(status)) {
1579 goto fail;
1583 * We should not purge the replay cache anymore
1584 * as it's attached to the smbXsrv_open record now.
1586 state->purge_create_guid = NULL;
1589 if (state->dhnq != NULL && state->op->global->durable) {
1590 uint8_t p[8] = { 0, };
1591 DATA_BLOB blob = data_blob_const(p, sizeof(p));
1593 status = smb2_create_blob_add(state->out_context_blobs,
1594 state->out_context_blobs,
1595 SMB2_CREATE_TAG_DHNQ,
1596 blob);
1597 if (!NT_STATUS_IS_OK(status)) {
1598 goto fail;
1602 if (state->dh2q != NULL && state->op->global->durable &&
1604 * For replay operations, we return the dh2q blob
1605 * in the case of oplocks not based on the state of
1606 * the open, but on whether it could have been granted
1607 * for the request data. In the case of leases instead,
1608 * the state of the open is used...
1610 (!state->replay_operation ||
1611 state->in_oplock_level == SMB2_OPLOCK_LEVEL_BATCH ||
1612 state->in_oplock_level == SMB2_OPLOCK_LEVEL_LEASE))
1614 uint8_t p[8] = { 0, };
1615 DATA_BLOB blob = data_blob_const(p, sizeof(p));
1616 uint32_t durable_v2_response_flags = 0;
1618 SIVAL(p, 0, state->op->global->durable_timeout_msec);
1619 SIVAL(p, 4, durable_v2_response_flags);
1621 status = smb2_create_blob_add(state->out_context_blobs,
1622 state->out_context_blobs,
1623 SMB2_CREATE_TAG_DH2Q,
1624 blob);
1625 if (!NT_STATUS_IS_OK(status)) {
1626 goto fail;
1630 if (state->qfid != NULL) {
1631 uint8_t p[32];
1632 SMB_STRUCT_STAT *base_sp = state->result->base_fsp ?
1633 &state->result->base_fsp->fsp_name->st :
1634 &state->result->fsp_name->st;
1635 uint64_t file_id = SMB_VFS_FS_FILE_ID(conn, base_sp);
1636 DATA_BLOB blob = data_blob_const(p, sizeof(p));
1638 ZERO_STRUCT(p);
1640 /* From conversations with Microsoft engineers at
1641 the MS plugfest. The first 8 bytes are the "volume index"
1642 == inode, the second 8 bytes are the "volume id",
1643 == dev. This will be updated in the SMB2 doc. */
1644 SBVAL(p, 0, file_id);
1645 SIVAL(p, 8, base_sp->st_ex_dev);/* FileIndexHigh */
1647 status = smb2_create_blob_add(state->out_context_blobs,
1648 state->out_context_blobs,
1649 SMB2_CREATE_TAG_QFID,
1650 blob);
1651 if (!NT_STATUS_IS_OK(status)) {
1652 goto fail;
1656 if ((state->rqls != NULL) && (state->result->oplock_type == LEASE_OPLOCK)) {
1657 uint8_t buf[52];
1658 struct smb2_lease lease;
1659 size_t lease_len;
1661 lease = state->result->lease->lease;
1663 lease_len = sizeof(buf);
1664 if (lease.lease_version == 1) {
1665 lease_len = 32;
1668 if (!smb2_lease_push(&lease, buf, lease_len)) {
1669 status = NT_STATUS_INTERNAL_ERROR;
1670 goto fail;
1673 status = smb2_create_blob_add(
1674 state, state->out_context_blobs,
1675 SMB2_CREATE_TAG_RQLS,
1676 data_blob_const(buf, lease_len));
1677 if (!NT_STATUS_IS_OK(status)) {
1678 goto fail;
1682 if (state->posx != NULL) {
1683 struct stat_ex *psbuf = &state->result->fsp_name->st;
1684 struct smb3_posix_cc_info cc = {
1685 .nlinks = psbuf->st_ex_nlink,
1686 .posix_mode = unix_mode_to_wire(psbuf->st_ex_mode),
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 (void)fsctl_get_reparse_tag(state->result, &cc.reparse_tag);
1701 ndr_err =
1702 ndr_push_smb3_posix_cc_info(&ndr,
1703 NDR_SCALARS | NDR_BUFFERS,
1704 &cc);
1705 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1706 status = NT_STATUS_INSUFFICIENT_RESOURCES;
1707 goto fail;
1710 status = smb2_create_blob_add(state->out_context_blobs,
1711 state->out_context_blobs,
1712 SMB2_CREATE_TAG_POSIX,
1713 (DATA_BLOB){
1714 .data = buf,
1715 .length = ndr.offset,
1717 if (!NT_STATUS_IS_OK(status)) {
1718 goto fail;
1722 return;
1724 fail:
1725 close_file_free(state->smb1req, &state->result, ERROR_CLOSE);
1726 tevent_req_nterror(req, status);
1729 static void smbd_smb2_create_finish(struct tevent_req *req)
1731 struct smbd_smb2_create_state *state = tevent_req_data(
1732 req, struct smbd_smb2_create_state);
1733 struct smbd_smb2_request *smb2req = state->smb2req;
1734 struct smb_request *smb1req = state->smb1req;
1735 files_struct *result = state->result;
1737 smb2req->compat_chain_fsp = smb1req->chain_fsp;
1739 if (state->replay_operation) {
1740 state->out_oplock_level = state->in_oplock_level;
1741 } else if (lp_fake_oplocks(SNUM(smb2req->tcon->compat))) {
1742 state->out_oplock_level = state->in_oplock_level;
1743 } else {
1744 state->out_oplock_level = map_samba_oplock_levels_to_smb2(result->oplock_type);
1747 if ((state->in_create_disposition == FILE_SUPERSEDE)
1748 && (state->info == FILE_WAS_OVERWRITTEN)) {
1749 state->out_create_action = FILE_WAS_SUPERSEDED;
1750 } else {
1751 state->out_create_action = state->info;
1753 result->op->create_action = state->out_create_action;
1755 state->out_creation_ts = get_create_timespec(smb1req->conn,
1756 result, result->fsp_name);
1757 state->out_last_access_ts = result->fsp_name->st.st_ex_atime;
1758 state->out_last_write_ts = result->fsp_name->st.st_ex_mtime;
1759 state->out_change_ts = get_change_timespec(smb1req->conn,
1760 result, result->fsp_name);
1762 if (lp_dos_filetime_resolution(SNUM(smb2req->tcon->compat))) {
1763 dos_filetime_timespec(&state->out_creation_ts);
1764 dos_filetime_timespec(&state->out_last_access_ts);
1765 dos_filetime_timespec(&state->out_last_write_ts);
1766 dos_filetime_timespec(&state->out_change_ts);
1769 state->out_allocation_size =
1770 SMB_VFS_GET_ALLOC_SIZE(smb1req->conn, result,
1771 &(result->fsp_name->st));
1772 state->out_end_of_file = result->fsp_name->st.st_ex_size;
1773 if (state->out_file_attributes == 0) {
1774 state->out_file_attributes = FILE_ATTRIBUTE_NORMAL;
1776 state->out_file_id_persistent = result->op->global->open_persistent_id;
1777 state->out_file_id_volatile = result->op->global->open_volatile_id;
1779 DBG_DEBUG("%s - %s\n", fsp_str_dbg(result), fsp_fnum_dbg(result));
1781 tevent_req_done(req);
1782 tevent_req_post(req, state->ev);
1785 static NTSTATUS smbd_smb2_create_recv(struct tevent_req *req,
1786 TALLOC_CTX *mem_ctx,
1787 uint8_t *out_oplock_level,
1788 uint32_t *out_create_action,
1789 struct timespec *out_creation_ts,
1790 struct timespec *out_last_access_ts,
1791 struct timespec *out_last_write_ts,
1792 struct timespec *out_change_ts,
1793 uint64_t *out_allocation_size,
1794 uint64_t *out_end_of_file,
1795 uint32_t *out_file_attributes,
1796 uint64_t *out_file_id_persistent,
1797 uint64_t *out_file_id_volatile,
1798 struct smb2_create_blobs *out_context_blobs)
1800 NTSTATUS status;
1801 struct smbd_smb2_create_state *state = tevent_req_data(req,
1802 struct smbd_smb2_create_state);
1804 if (tevent_req_is_nterror(req, &status)) {
1805 tevent_req_received(req);
1806 return status;
1809 *out_oplock_level = state->out_oplock_level;
1810 *out_create_action = state->out_create_action;
1811 *out_creation_ts = state->out_creation_ts;
1812 *out_last_access_ts = state->out_last_access_ts;
1813 *out_last_write_ts = state->out_last_write_ts;
1814 *out_change_ts = state->out_change_ts;
1815 *out_allocation_size = state->out_allocation_size;
1816 *out_end_of_file = state->out_end_of_file;
1817 *out_file_attributes = state->out_file_attributes;
1818 *out_file_id_persistent = state->out_file_id_persistent;
1819 *out_file_id_volatile = state->out_file_id_volatile;
1820 *out_context_blobs = *(state->out_context_blobs);
1822 talloc_steal(mem_ctx, state->out_context_blobs->blobs);
1824 tevent_req_received(req);
1825 return NT_STATUS_OK;
1828 /*********************************************************
1829 Code for dealing with deferred opens.
1830 *********************************************************/
1832 bool get_deferred_open_message_state_smb2(struct smbd_smb2_request *smb2req,
1833 struct timeval *p_request_time,
1834 struct deferred_open_record **open_rec)
1836 struct smbd_smb2_create_state *state = NULL;
1837 struct tevent_req *req = NULL;
1839 if (!smb2req) {
1840 return false;
1842 req = smb2req->subreq;
1843 if (!req) {
1844 return false;
1846 state = tevent_req_data(req, struct smbd_smb2_create_state);
1847 if (!state) {
1848 return false;
1850 if (!state->open_was_deferred) {
1851 return false;
1853 if (p_request_time) {
1854 *p_request_time = state->request_time;
1856 if (open_rec != NULL) {
1857 *open_rec = state->open_rec;
1859 return true;
1862 /*********************************************************
1863 Re-process this call early - requested by message or
1864 close.
1865 *********************************************************/
1867 static struct smbd_smb2_request *find_open_smb2req(
1868 struct smbXsrv_connection *xconn, uint64_t mid)
1870 struct smbd_smb2_request *smb2req;
1872 for (smb2req = xconn->smb2.requests; smb2req; smb2req = smb2req->next) {
1873 uint64_t message_id;
1874 if (smb2req->subreq == NULL) {
1875 /* This message has been processed. */
1876 continue;
1878 if (!tevent_req_is_in_progress(smb2req->subreq)) {
1879 /* This message has been processed. */
1880 continue;
1882 message_id = get_mid_from_smb2req(smb2req);
1883 if (message_id == mid) {
1884 return smb2req;
1887 return NULL;
1890 bool open_was_deferred_smb2(struct smbXsrv_connection *xconn, uint64_t mid)
1892 struct smbd_smb2_create_state *state = NULL;
1893 struct smbd_smb2_request *smb2req;
1895 smb2req = find_open_smb2req(xconn, mid);
1897 if (!smb2req) {
1898 DEBUG(10,("open_was_deferred_smb2: mid %llu smb2req == NULL\n",
1899 (unsigned long long)mid));
1900 return false;
1902 if (!smb2req->subreq) {
1903 return false;
1905 if (!tevent_req_is_in_progress(smb2req->subreq)) {
1906 return false;
1908 state = tevent_req_data(smb2req->subreq,
1909 struct smbd_smb2_create_state);
1910 if (!state) {
1911 return false;
1913 /* It's not in progress if there's no timeout event. */
1914 if (!state->open_was_deferred) {
1915 return false;
1918 DEBUG(10,("open_was_deferred_smb2: mid = %llu\n",
1919 (unsigned long long)mid));
1921 return true;
1924 static void remove_deferred_open_message_smb2_internal(struct smbd_smb2_request *smb2req,
1925 uint64_t mid)
1927 struct smbd_smb2_create_state *state = NULL;
1929 if (!smb2req->subreq) {
1930 return;
1932 if (!tevent_req_is_in_progress(smb2req->subreq)) {
1933 return;
1935 state = tevent_req_data(smb2req->subreq,
1936 struct smbd_smb2_create_state);
1937 if (!state) {
1938 return;
1941 DEBUG(10,("remove_deferred_open_message_smb2_internal: "
1942 "mid %llu\n",
1943 (unsigned long long)mid ));
1945 state->open_was_deferred = false;
1946 /* Ensure we don't have any outstanding immediate event. */
1947 TALLOC_FREE(state->im);
1948 TALLOC_FREE(state->open_rec);
1951 void remove_deferred_open_message_smb2(
1952 struct smbXsrv_connection *xconn, uint64_t mid)
1954 struct smbd_smb2_request *smb2req;
1956 smb2req = find_open_smb2req(xconn, mid);
1958 if (!smb2req) {
1959 DEBUG(10,("remove_deferred_open_message_smb2: "
1960 "can't find mid %llu\n",
1961 (unsigned long long)mid ));
1962 return;
1964 remove_deferred_open_message_smb2_internal(smb2req, mid);
1967 static void smbd_smb2_create_request_dispatch_immediate(struct tevent_context *ctx,
1968 struct tevent_immediate *im,
1969 void *private_data)
1971 struct smbd_smb2_request *smb2req = talloc_get_type_abort(private_data,
1972 struct smbd_smb2_request);
1973 uint64_t mid = get_mid_from_smb2req(smb2req);
1974 NTSTATUS status;
1976 DEBUG(10,("smbd_smb2_create_request_dispatch_immediate: "
1977 "re-dispatching mid %llu\n",
1978 (unsigned long long)mid ));
1980 status = smbd_smb2_request_dispatch(smb2req);
1981 if (!NT_STATUS_IS_OK(status)) {
1982 smbd_server_connection_terminate(smb2req->xconn,
1983 nt_errstr(status));
1984 return;
1988 bool schedule_deferred_open_message_smb2(
1989 struct smbXsrv_connection *xconn, uint64_t mid)
1991 struct smbd_smb2_create_state *state = NULL;
1992 struct smbd_smb2_request *smb2req;
1994 smb2req = find_open_smb2req(xconn, mid);
1996 if (!smb2req) {
1997 DEBUG(10,("schedule_deferred_open_message_smb2: "
1998 "can't find mid %llu\n",
1999 (unsigned long long)mid ));
2000 return false;
2002 if (!smb2req->subreq) {
2003 return false;
2005 if (!tevent_req_is_in_progress(smb2req->subreq)) {
2006 return false;
2008 state = tevent_req_data(smb2req->subreq,
2009 struct smbd_smb2_create_state);
2010 if (!state) {
2011 return false;
2014 /* Ensure we don't have any outstanding immediate event. */
2015 TALLOC_FREE(state->im);
2018 * This is subtle. We must null out the callback
2019 * before rescheduling, else the first call to
2020 * tevent_req_nterror() causes the _receive()
2021 * function to be called, this causing tevent_req_post()
2022 * to crash.
2024 tevent_req_set_callback(smb2req->subreq, NULL, NULL);
2026 state->im = tevent_create_immediate(smb2req);
2027 if (!state->im) {
2028 smbd_server_connection_terminate(smb2req->xconn,
2029 nt_errstr(NT_STATUS_NO_MEMORY));
2030 return false;
2033 DEBUG(10,("schedule_deferred_open_message_smb2: "
2034 "re-processing mid %llu\n",
2035 (unsigned long long)mid ));
2037 tevent_schedule_immediate(state->im,
2038 smb2req->sconn->ev_ctx,
2039 smbd_smb2_create_request_dispatch_immediate,
2040 smb2req);
2042 return true;
2045 static bool smbd_smb2_create_cancel(struct tevent_req *req)
2047 struct smbd_smb2_request *smb2req = NULL;
2048 struct smbd_smb2_create_state *state = tevent_req_data(req,
2049 struct smbd_smb2_create_state);
2050 uint64_t mid;
2052 if (!state) {
2053 return false;
2056 if (!state->smb2req) {
2057 return false;
2060 smb2req = state->smb2req;
2061 mid = get_mid_from_smb2req(smb2req);
2063 if (is_deferred_open_async(state->open_rec)) {
2064 /* Can't cancel an async create. */
2065 return false;
2068 remove_deferred_open_message_smb2_internal(smb2req, mid);
2070 tevent_req_defer_callback(req, smb2req->sconn->ev_ctx);
2071 tevent_req_nterror(req, NT_STATUS_CANCELLED);
2072 return true;
2075 bool push_deferred_open_message_smb2(struct smbd_smb2_request *smb2req,
2076 struct timeval request_time,
2077 struct timeval timeout,
2078 struct file_id id,
2079 struct deferred_open_record *open_rec)
2081 struct tevent_req *req = NULL;
2082 struct smbd_smb2_create_state *state = NULL;
2083 struct timeval end_time;
2085 if (!smb2req) {
2086 return false;
2088 req = smb2req->subreq;
2089 if (!req) {
2090 return false;
2092 state = tevent_req_data(req, struct smbd_smb2_create_state);
2093 if (!state) {
2094 return false;
2096 state->id = id;
2097 state->request_time = request_time;
2098 state->open_rec = talloc_move(state, &open_rec);
2100 /* Re-schedule us to retry on timer expiry. */
2101 end_time = timeval_sum(&request_time, &timeout);
2103 DEBUG(10,("push_deferred_open_message_smb2: "
2104 "timeout at %s\n",
2105 timeval_string(talloc_tos(),
2106 &end_time,
2107 true) ));
2109 state->open_was_deferred = true;
2111 /* allow this request to be canceled */
2112 tevent_req_set_cancel_fn(req, smbd_smb2_create_cancel);
2114 return true;