smbd: Use smb3posix marshalling in smbd_smb2_create_after_exec()
[Samba.git] / source3 / smbd / smb2_create.c
blobd71dfc3083fc42a6f3d843bee77e28590c8b3021
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 int requested_oplock_level;
565 int info;
566 char *fname;
567 struct ea_list *ea_list;
568 NTTIME max_access_time;
569 struct security_descriptor *sec_desc;
570 uint64_t allocation_size;
571 struct GUID _create_guid;
572 struct GUID *create_guid;
573 struct GUID _purge_create_guid;
574 struct GUID *purge_create_guid;
575 bool update_open;
576 bool durable_requested;
577 uint32_t durable_timeout_msec;
578 bool do_durable_reconnect;
579 uint64_t persistent_id;
580 struct smb2_lease lease;
581 struct smb2_lease *lease_ptr;
582 ssize_t lease_len;
583 bool need_replay_cache;
584 struct smbXsrv_open *op;
585 NTTIME twrp_time;
587 struct smb2_create_blob *dhnc;
588 struct smb2_create_blob *dh2c;
589 struct smb2_create_blob *dhnq;
590 struct smb2_create_blob *dh2q;
591 struct smb2_create_blob *rqls;
592 struct smb2_create_blob *exta;
593 struct smb2_create_blob *mxac;
594 struct smb2_create_blob *secd;
595 struct smb2_create_blob *alsi;
596 struct smb2_create_blob *twrp;
597 struct smb2_create_blob *qfid;
598 struct smb2_create_blob *posx;
599 struct smb2_create_blob *svhdx;
601 uint8_t out_oplock_level;
602 uint32_t out_create_action;
603 struct timespec out_creation_ts;
604 struct timespec out_last_access_ts;
605 struct timespec out_last_write_ts;
606 struct timespec out_change_ts;
607 uint64_t out_allocation_size;
608 uint64_t out_end_of_file;
609 uint32_t out_file_attributes;
610 uint64_t out_file_id_persistent;
611 uint64_t out_file_id_volatile;
612 struct smb2_create_blobs *out_context_blobs;
615 static void smbd_smb2_create_purge_replay_cache(struct tevent_req *req,
616 const char *caller_func);
618 static void smbd_smb2_create_cleanup(struct tevent_req *req,
619 enum tevent_req_state req_state)
621 smbd_smb2_create_purge_replay_cache(req, __func__);
624 static NTSTATUS smbd_smb2_create_fetch_create_ctx(
625 struct tevent_req *req,
626 struct smb2_create_blobs *in_context_blobs)
628 struct smbd_smb2_create_state *state = tevent_req_data(
629 req, struct smbd_smb2_create_state);
630 struct smbd_smb2_request *smb2req = state->smb2req;
631 struct smbXsrv_connection *xconn = smb2req->xconn;
633 state->dhnq = smb2_create_blob_find(in_context_blobs,
634 SMB2_CREATE_TAG_DHNQ);
635 state->dhnc = smb2_create_blob_find(in_context_blobs,
636 SMB2_CREATE_TAG_DHNC);
637 state->dh2q = smb2_create_blob_find(in_context_blobs,
638 SMB2_CREATE_TAG_DH2Q);
639 state->dh2c = smb2_create_blob_find(in_context_blobs,
640 SMB2_CREATE_TAG_DH2C);
641 if (xconn->smb2.server.capabilities & SMB2_CAP_LEASING) {
642 state->rqls = smb2_create_blob_find(in_context_blobs,
643 SMB2_CREATE_TAG_RQLS);
646 if (((state->dhnc != NULL) && (state->dh2c != NULL)) ||
647 ((state->dhnc != NULL) && (state->dh2q != NULL)) ||
648 ((state->dh2c != NULL) && (state->dhnq != NULL)) ||
649 ((state->dh2q != NULL) && (state->dh2c != NULL)))
651 /* not both are allowed at the same time */
652 return NT_STATUS_INVALID_PARAMETER;
655 if (state->dhnc != NULL) {
656 uint32_t num_blobs_allowed;
658 if (state->dhnc->data.length != 16) {
659 return NT_STATUS_INVALID_PARAMETER;
663 * According to MS-SMB2: 3.3.5.9.7, "Handling the
664 * SMB2_CREATE_DURABLE_HANDLE_RECONNECT Create Context",
665 * we should ignore an additional dhnq blob, but fail
666 * the request (with status OBJECT_NAME_NOT_FOUND) if
667 * any other extra create blob has been provided.
669 * (Note that the cases of an additional dh2q or dh2c blob
670 * which require a different error code, have been treated
671 * above.)
674 if (state->dhnq != NULL) {
675 num_blobs_allowed = 2;
676 } else {
677 num_blobs_allowed = 1;
680 if (state->rqls != NULL) {
681 num_blobs_allowed += 1;
684 if (in_context_blobs->num_blobs != num_blobs_allowed) {
685 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
689 if (state->dh2c!= NULL) {
690 uint32_t num_blobs_allowed;
692 if (state->dh2c->data.length != 36) {
693 return NT_STATUS_INVALID_PARAMETER;
697 * According to MS-SMB2: 3.3.5.9.12, "Handling the
698 * SMB2_CREATE_DURABLE_HANDLE_RECONNECT_V2 Create Context",
699 * we should fail the request with status
700 * OBJECT_NAME_NOT_FOUND if any other create blob has been
701 * provided.
703 * (Note that the cases of an additional dhnq, dhnc or dh2q
704 * blob which require a different error code, have been
705 * treated above.)
708 num_blobs_allowed = 1;
710 if (state->rqls != NULL) {
711 num_blobs_allowed += 1;
714 if (in_context_blobs->num_blobs != num_blobs_allowed) {
715 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
719 state->exta = smb2_create_blob_find(in_context_blobs,
720 SMB2_CREATE_TAG_EXTA);
721 state->mxac = smb2_create_blob_find(in_context_blobs,
722 SMB2_CREATE_TAG_MXAC);
723 state->secd = smb2_create_blob_find(in_context_blobs,
724 SMB2_CREATE_TAG_SECD);
725 state->alsi = smb2_create_blob_find(in_context_blobs,
726 SMB2_CREATE_TAG_ALSI);
727 state->twrp = smb2_create_blob_find(in_context_blobs,
728 SMB2_CREATE_TAG_TWRP);
729 state->qfid = smb2_create_blob_find(in_context_blobs,
730 SMB2_CREATE_TAG_QFID);
731 if (xconn->protocol >= PROTOCOL_SMB3_02) {
733 * This was introduced with SMB3_02
735 state->svhdx = smb2_create_blob_find(
736 in_context_blobs, SVHDX_OPEN_DEVICE_CONTEXT);
738 if (xconn->smb2.server.posix_extensions_negotiated) {
740 * Negprot only allowed this for proto>=3.11
742 SMB_ASSERT(xconn->protocol >= PROTOCOL_SMB3_11);
744 state->posx = smb2_create_blob_find(
745 in_context_blobs, SMB2_CREATE_TAG_POSIX);
747 * Setting the bool below will cause
748 * ucf_flags_from_smb_request() to
749 * return UCF_POSIX_PATHNAMES in ucf_flags.
751 state->smb1req->posix_pathnames = (state->posx != NULL);
754 return NT_STATUS_OK;
757 static void smbd_smb2_create_before_exec(struct tevent_req *req);
758 static void smbd_smb2_create_after_exec(struct tevent_req *req);
759 static void smbd_smb2_create_finish(struct tevent_req *req);
761 static struct tevent_req *smbd_smb2_create_send(TALLOC_CTX *mem_ctx,
762 struct tevent_context *ev,
763 struct smbd_smb2_request *smb2req,
764 uint8_t in_oplock_level,
765 uint32_t in_impersonation_level,
766 uint32_t in_desired_access,
767 uint32_t in_file_attributes,
768 uint32_t in_share_access,
769 uint32_t in_create_disposition,
770 uint32_t in_create_options,
771 const char *in_name,
772 struct smb2_create_blobs in_context_blobs)
774 struct tevent_req *req = NULL;
775 struct smbd_smb2_create_state *state = NULL;
776 NTSTATUS status;
777 struct smb_request *smb1req = NULL;
778 struct files_struct *dirfsp = NULL;
779 struct smb_filename *smb_fname = NULL;
780 uint32_t ucf_flags;
781 bool is_dfs = false;
782 bool is_posix = false;
784 req = tevent_req_create(mem_ctx, &state,
785 struct smbd_smb2_create_state);
786 if (req == NULL) {
787 return NULL;
789 *state = (struct smbd_smb2_create_state) {
790 .ev = ev,
791 .smb2req = smb2req,
792 .in_oplock_level = in_oplock_level,
793 .in_create_disposition = in_create_disposition,
796 smb1req = smbd_smb2_fake_smb_request(smb2req, NULL);
797 if (tevent_req_nomem(smb1req, req)) {
798 return tevent_req_post(req, state->ev);
800 state->smb1req = smb1req;
802 state->req_guid = smbd_request_guid(smb1req, 0);
804 tevent_req_set_cleanup_fn(req, smbd_smb2_create_cleanup);
806 if (smb2req->subreq == NULL) {
807 DBG_DEBUG("name [%s]\n", in_name);
808 } else {
809 struct smbd_smb2_create_state *old_state = tevent_req_data(
810 smb2req->subreq, struct smbd_smb2_create_state);
812 DBG_DEBUG("reentrant for file %s\n", in_name);
814 state->id = old_state->id;
815 state->request_time = old_state->request_time;
816 state->open_rec = talloc_move(state, &old_state->open_rec);
817 state->open_was_deferred = old_state->open_was_deferred;
818 state->_purge_create_guid = old_state->_purge_create_guid;
819 state->purge_create_guid = old_state->purge_create_guid;
820 old_state->purge_create_guid = NULL;
823 TALLOC_FREE(smb2req->subreq);
824 smb2req->subreq = req;
826 if (lp_fake_oplocks(SNUM(smb2req->tcon->compat))) {
827 state->requested_oplock_level = SMB2_OPLOCK_LEVEL_NONE;
828 } else {
829 state->requested_oplock_level = state->in_oplock_level;
832 /* these are ignored for SMB2 */
833 in_create_options &= ~(0x10);/* NTCREATEX_OPTIONS_SYNC_ALERT */
834 in_create_options &= ~(0x20);/* NTCREATEX_OPTIONS_ASYNC_ALERT */
836 in_file_attributes &= ~FILE_FLAG_POSIX_SEMANTICS;
838 is_dfs = (smb1req->flags2 & FLAGS2_DFS_PATHNAMES);
839 if (is_dfs) {
840 const char *non_dfs_in_name = NULL;
842 * With a DFS flag set, remove any DFS prefix
843 * before further processing.
845 status = smb2_strip_dfs_path(in_name, &non_dfs_in_name);
846 if (!NT_STATUS_IS_OK(status)) {
847 tevent_req_nterror(req, status);
848 return tevent_req_post(req, state->ev);
851 * TODO: Note for dealing with reparse point errors.
852 * We will need to remember and store the number of characters
853 * we have removed here, which is (non_dfs_in_name - in_name)
854 * in order to correctly report how many characters we
855 * have removed before hitting the reparse point.
856 * This will be a patch needed once we properly
857 * deal with reparse points later.
859 in_name = non_dfs_in_name;
861 * Now we're no longer dealing with a DFS path, so
862 * remove the flag.
864 smb1req->flags2 &= ~FLAGS2_DFS_PATHNAMES;
865 is_dfs = false;
868 state->fname = talloc_strdup(state, in_name);
869 if (tevent_req_nomem(state->fname, req)) {
870 return tevent_req_post(req, state->ev);
873 state->out_context_blobs = talloc_zero(state, struct smb2_create_blobs);
874 if (tevent_req_nomem(state->out_context_blobs, req)) {
875 return tevent_req_post(req, state->ev);
878 status = smbd_smb2_create_fetch_create_ctx(req, &in_context_blobs);
879 if (tevent_req_nterror(req, status)) {
880 return tevent_req_post(req, state->ev);
883 if (IS_IPC(smb1req->conn)) {
884 const char *pipe_name = in_name;
886 if (state->dhnc != NULL || state->dh2c != NULL) {
887 /* durable handles are not supported on IPC$ */
888 tevent_req_nterror(req, NT_STATUS_OBJECT_NAME_NOT_FOUND);
889 return tevent_req_post(req, state->ev);
892 if (!lp_nt_pipe_support()) {
893 tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
894 return tevent_req_post(req, state->ev);
897 status = open_np_file(smb1req, pipe_name, &state->result);
898 if (tevent_req_nterror(req, status)) {
899 return tevent_req_post(req, state->ev);
901 state->info = FILE_WAS_OPENED;
903 smbd_smb2_create_finish(req);
904 return req;
907 if (CAN_PRINT(smb1req->conn)) {
908 if (state->dhnc != NULL || state->dh2c != NULL) {
909 /* durable handles are not supported on printers */
910 tevent_req_nterror(req, NT_STATUS_OBJECT_NAME_NOT_FOUND);
911 return tevent_req_post(req, state->ev);
914 status = file_new(smb1req, smb1req->conn, &state->result);
915 if (tevent_req_nterror(req, status)) {
916 return tevent_req_post(req, state->ev);
919 status = print_spool_open(state->result, in_name,
920 smb1req->vuid);
921 if (tevent_req_nterror(req, status)) {
922 file_free(smb1req, state->result);
923 return tevent_req_post(req, state->ev);
925 state->info = FILE_WAS_CREATED;
927 smbd_smb2_create_finish(req);
928 return req;
931 /* Check for trailing slash specific directory handling. */
932 status = windows_name_trailing_check(state->fname, in_create_options);
933 if (tevent_req_nterror(req, status)) {
934 return tevent_req_post(req, state->ev);
937 smbd_smb2_create_before_exec(req);
938 if (!tevent_req_is_in_progress(req)) {
939 return tevent_req_post(req, state->ev);
942 DBG_DEBUG("open execution phase\n");
945 * For the backend file open procedure, there are
946 * three possible modes: replay operation (in which case
947 * there is nothing else to do), durable_reconnect or
948 * new open.
950 if (state->replay_operation) {
951 state->result = state->op->compat;
952 state->result->op = state->op;
953 state->update_open = false;
954 state->info = state->op->create_action;
956 smbd_smb2_create_after_exec(req);
957 if (!tevent_req_is_in_progress(req)) {
958 return tevent_req_post(req, state->ev);
961 smbd_smb2_create_finish(req);
962 return req;
965 if (state->do_durable_reconnect) {
966 DATA_BLOB new_cookie = data_blob_null;
967 NTTIME now = timeval_to_nttime(&smb2req->request_time);
969 status = smb2srv_open_recreate(smb2req->xconn,
970 smb1req->conn->session_info,
971 state->persistent_id,
972 state->create_guid,
973 now,
974 &state->op);
975 if (tevent_req_nterror(req, status)) {
976 DBG_NOTICE("smb2srv_open_recreate failed: %s\n",
977 nt_errstr(status));
978 return tevent_req_post(req, state->ev);
981 DBG_DEBUG("%s to recreate durable handle\n",
982 state->op->global->durable ? "succeeded" : "failed");
984 if (!state->op->global->durable) {
985 talloc_free(state->op);
986 tevent_req_nterror(req,
987 NT_STATUS_OBJECT_NAME_NOT_FOUND);
988 return tevent_req_post(req, state->ev);
991 status = SMB_VFS_DURABLE_RECONNECT(smb1req->conn,
992 smb1req,
993 state->op, /* smbXsrv_open input */
994 state->op->global->backend_cookie,
995 state->op, /* TALLOC_CTX */
996 &state->result,
997 &new_cookie);
998 if (!NT_STATUS_IS_OK(status)) {
999 NTSTATUS return_status;
1001 return_status = NT_STATUS_OBJECT_NAME_NOT_FOUND;
1003 DBG_NOTICE("durable_reconnect failed: %s => %s\n",
1004 nt_errstr(status),
1005 nt_errstr(return_status));
1007 tevent_req_nterror(req, return_status);
1008 return tevent_req_post(req, state->ev);
1011 DBG_DEBUG("oplock_type=%u, lease_ptr==%p\n",
1012 (unsigned)state->result->oplock_type, state->lease_ptr);
1014 status = smbd_smb2_create_durable_lease_check(
1015 smb1req, state->fname, state->result, state->lease_ptr);
1016 if (tevent_req_nterror(req, status)) {
1017 close_file_free(
1018 smb1req, &state->result, SHUTDOWN_CLOSE);
1019 return tevent_req_post(req, state->ev);
1022 data_blob_free(&state->op->global->backend_cookie);
1023 state->op->global->backend_cookie = new_cookie;
1025 state->op->status = NT_STATUS_OK;
1026 state->op->global->disconnect_time = 0;
1028 /* save the timeout for later update */
1029 state->durable_timeout_msec = state->op->global->durable_timeout_msec;
1031 state->update_open = true;
1033 state->info = FILE_WAS_OPENED;
1035 smbd_smb2_create_after_exec(req);
1036 if (!tevent_req_is_in_progress(req)) {
1037 return tevent_req_post(req, state->ev);
1040 smbd_smb2_create_finish(req);
1041 return req;
1044 if (state->requested_oplock_level == SMB2_OPLOCK_LEVEL_LEASE) {
1045 if (state->lease_ptr == NULL) {
1046 state->requested_oplock_level = SMB2_OPLOCK_LEVEL_NONE;
1048 } else {
1049 state->lease_ptr = NULL;
1052 is_posix = (state->posx != NULL);
1054 /* convert '\\' into '/' */
1055 status = check_path_syntax(state->fname, is_posix);
1056 if (tevent_req_nterror(req, status)) {
1057 return tevent_req_post(req, state->ev);
1060 ucf_flags = filename_create_ucf_flags(
1061 smb1req, state->in_create_disposition);
1063 status = filename_convert_dirfsp(
1064 req,
1065 smb1req->conn,
1066 state->fname,
1067 ucf_flags,
1068 state->twrp_time,
1069 &dirfsp,
1070 &smb_fname);
1071 if (tevent_req_nterror(req, status)) {
1072 return tevent_req_post(req, state->ev);
1076 * MS-SMB2: 2.2.13 SMB2 CREATE Request
1077 * ImpersonationLevel ... MUST contain one of the
1078 * following values. The server MUST validate this
1079 * field, but otherwise ignore it.
1081 * NB. The source4/torture/smb2/durable_open.c test
1082 * shows this check is only done on real opens, not
1083 * on durable handle-reopens.
1086 if (in_impersonation_level >
1087 SMB2_IMPERSONATION_DELEGATE) {
1088 tevent_req_nterror(req,
1089 NT_STATUS_BAD_IMPERSONATION_LEVEL);
1090 return tevent_req_post(req, state->ev);
1094 * We know we're going to do a local open, so now
1095 * we must be protocol strict. JRA.
1097 * MS-SMB2: 3.3.5.9 - Receiving an SMB2 CREATE Request
1098 * If the file name length is greater than zero and the
1099 * first character is a path separator character, the
1100 * server MUST fail the request with
1101 * STATUS_INVALID_PARAMETER.
1103 if (in_name[0] == '/') {
1104 /* Names starting with '/' are never allowed. */
1105 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
1106 return tevent_req_post(req, ev);
1108 if (!is_posix && (in_name[0] == '\\')) {
1110 * Windows names starting with '\' are not allowed.
1112 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
1113 return tevent_req_post(req, ev);
1116 status = SMB_VFS_CREATE_FILE(smb1req->conn,
1117 smb1req,
1118 dirfsp,
1119 smb_fname,
1120 in_desired_access,
1121 in_share_access,
1122 state->in_create_disposition,
1123 in_create_options,
1124 in_file_attributes,
1125 map_smb2_oplock_levels_to_samba(
1126 state->requested_oplock_level),
1127 state->lease_ptr,
1128 state->allocation_size,
1129 0, /* private_flags */
1130 state->sec_desc,
1131 state->ea_list,
1132 &state->result,
1133 &state->info,
1134 &in_context_blobs,
1135 state->out_context_blobs);
1136 if (!NT_STATUS_IS_OK(status)) {
1137 if (open_was_deferred(smb1req->xconn, smb1req->mid)) {
1138 SMBPROFILE_IOBYTES_ASYNC_SET_IDLE(smb2req->profile);
1139 return req;
1141 tevent_req_nterror(req, status);
1142 return tevent_req_post(req, state->ev);
1144 state->op = state->result->op;
1146 smbd_smb2_create_after_exec(req);
1147 if (!tevent_req_is_in_progress(req)) {
1148 return tevent_req_post(req, state->ev);
1151 smbd_smb2_create_finish(req);
1152 return req;
1155 static void smbd_smb2_create_purge_replay_cache(struct tevent_req *req,
1156 const char *caller_func)
1158 struct smbd_smb2_create_state *state = tevent_req_data(
1159 req, struct smbd_smb2_create_state);
1160 NTSTATUS status;
1162 if (state->purge_create_guid == NULL) {
1163 return;
1166 status = smbXsrv_open_purge_replay_cache(state->smb2req->xconn->client,
1167 state->purge_create_guid);
1168 if (!NT_STATUS_IS_OK(status)) {
1169 struct GUID_txt_buf buf;
1171 D_ERR("%s: smbXsrv_open_purge_replay_cache(%s) %s\n",
1172 caller_func,
1173 GUID_buf_string(state->purge_create_guid, &buf),
1174 nt_errstr(status));
1177 state->purge_create_guid = NULL;
1180 static void smbd_smb2_create_before_exec(struct tevent_req *req)
1182 struct smbd_smb2_create_state *state = tevent_req_data(
1183 req, struct smbd_smb2_create_state);
1184 struct smbd_smb2_request *smb2req = state->smb2req;
1185 NTSTATUS status;
1187 if (state->exta != NULL) {
1188 if (!lp_ea_support(SNUM(smb2req->tcon->compat))) {
1189 tevent_req_nterror(req, NT_STATUS_EAS_NOT_SUPPORTED);
1190 return;
1193 state->ea_list = read_nttrans_ea_list(
1194 state,
1195 (const char *)state->exta->data.data,
1196 state->exta->data.length);
1197 if (state->ea_list == NULL) {
1198 DEBUG(10,("smbd_smb2_create_send: read_ea_name_list failed.\n"));
1199 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
1200 return;
1203 if ((state->posx == NULL) &&
1204 ea_list_has_invalid_name(state->ea_list)) {
1205 tevent_req_nterror(req, STATUS_INVALID_EA_NAME);
1206 return;
1210 if (state->mxac != NULL) {
1211 if (state->mxac->data.length == 0) {
1212 state->max_access_time = 0;
1213 } else if (state->mxac->data.length == 8) {
1214 state->max_access_time = BVAL(state->mxac->data.data, 0);
1215 } else {
1216 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
1217 return;
1221 if (state->secd != NULL) {
1222 enum ndr_err_code ndr_err;
1224 state->sec_desc = talloc_zero(state, struct security_descriptor);
1225 if (tevent_req_nomem(state->sec_desc, req)) {
1226 return;
1229 ndr_err = ndr_pull_struct_blob(&state->secd->data,
1230 state->sec_desc, state->sec_desc,
1231 (ndr_pull_flags_fn_t)ndr_pull_security_descriptor);
1232 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1233 DEBUG(2,("ndr_pull_security_descriptor failed: %s\n",
1234 ndr_errstr(ndr_err)));
1235 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
1236 return;
1240 if (state->dhnq != NULL) {
1241 if (state->dhnq->data.length != 16) {
1242 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
1243 return;
1246 if (state->dh2q != NULL) {
1247 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
1248 return;
1252 * durable handle request is processed below.
1254 state->durable_requested = true;
1256 * Set the timeout to 16 mins.
1258 * TODO: test this against Windows 2012
1259 * as the default for durable v2 is 1 min.
1261 state->durable_timeout_msec = (16*60*1000);
1264 if (state->dh2q != NULL) {
1265 const uint8_t *p = state->dh2q->data.data;
1266 NTTIME now = timeval_to_nttime(&smb2req->request_time);
1267 uint32_t durable_v2_timeout = 0;
1268 DATA_BLOB create_guid_blob;
1269 const uint8_t *hdr;
1270 uint32_t flags;
1272 if (state->dh2q->data.length != 32) {
1273 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
1274 return;
1277 if (state->dhnq != NULL) {
1278 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
1279 return;
1282 durable_v2_timeout = IVAL(p, 0);
1283 create_guid_blob = data_blob_const(p + 16, 16);
1285 status = GUID_from_ndr_blob(&create_guid_blob,
1286 &state->_create_guid);
1287 if (tevent_req_nterror(req, status)) {
1288 return;
1290 state->create_guid = &state->_create_guid;
1293 * we need to store the create_guid later
1295 state->update_open = true;
1298 * And we need to create a cache for replaying the
1299 * create.
1301 state->need_replay_cache = true;
1304 * durable handle v2 request processed below
1306 state->durable_requested = true;
1307 state->durable_timeout_msec = MIN(durable_v2_timeout, 300*1000);
1308 if (state->durable_timeout_msec == 0) {
1310 * Set the timeout to 1 min as default.
1312 * This matches Windows 2012.
1314 state->durable_timeout_msec = (60*1000);
1318 * Check for replay operation.
1319 * Only consider it when we have dh2q.
1320 * If we do not have a replay operation, verify that
1321 * the create_guid is not cached for replay.
1323 hdr = SMBD_SMB2_IN_HDR_PTR(smb2req);
1324 flags = IVAL(hdr, SMB2_HDR_FLAGS);
1325 state->replay_operation =
1326 flags & SMB2_HDR_FLAG_REPLAY_OPERATION;
1328 status = smb2srv_open_lookup_replay_cache(smb2req->xconn,
1329 state->req_guid,
1330 *state->create_guid,
1331 state->fname,
1332 now,
1333 &state->op);
1334 if (NT_STATUS_EQUAL(status, NT_STATUS_FWP_RESERVED)) {
1336 * We've reserved the replay_cache record
1337 * for ourself, indicating we're still
1338 * in progress.
1340 * It means the smbd_smb2_create_cleanup()
1341 * may need to call smbXsrv_open_purge_replay_cache()
1342 * in order to cleanup.
1344 SMB_ASSERT(state->op == NULL);
1345 state->_purge_create_guid = state->_create_guid;
1346 state->purge_create_guid = &state->_purge_create_guid;
1347 status = NT_STATUS_OK;
1348 state->replay_operation = false;
1349 } else if (NT_STATUS_EQUAL(status, NT_STATUS_FILE_NOT_AVAILABLE)) {
1350 tevent_req_nterror(req, status);
1351 return;
1352 } else if (tevent_req_nterror(req, status)) {
1353 DBG_WARNING("smb2srv_open_lookup_replay_cache "
1354 "failed: %s\n", nt_errstr(status));
1355 return;
1356 } else if (!state->replay_operation) {
1358 * If a create without replay operation flag
1359 * is sent but with a create_guid that is
1360 * currently in the replay cache -- fail.
1362 status = NT_STATUS_DUPLICATE_OBJECTID;
1363 (void)tevent_req_nterror(req, status);
1364 return;
1368 if (state->dhnc != NULL) {
1369 state->persistent_id = BVAL(state->dhnc->data.data, 0);
1370 state->do_durable_reconnect = true;
1373 if (state->dh2c != NULL) {
1374 const uint8_t *p = state->dh2c->data.data;
1375 DATA_BLOB create_guid_blob;
1377 state->persistent_id = BVAL(p, 0);
1378 create_guid_blob = data_blob_const(p + 16, 16);
1380 status = GUID_from_ndr_blob(&create_guid_blob,
1381 &state->_create_guid);
1382 if (tevent_req_nterror(req, status)) {
1383 return;
1386 state->create_guid = &state->_create_guid;
1387 state->do_durable_reconnect = true;
1390 if (state->alsi != NULL) {
1391 if (state->alsi->data.length != 8) {
1392 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
1393 return;
1395 state->allocation_size = BVAL(state->alsi->data.data, 0);
1398 if (state->twrp != NULL) {
1399 if (state->twrp->data.length != 8) {
1400 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
1401 return;
1404 state->twrp_time = BVAL(state->twrp->data.data, 0);
1407 if (state->qfid != NULL) {
1408 if (state->qfid->data.length != 0) {
1409 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
1410 return;
1414 if (state->rqls != NULL) {
1415 ssize_t lease_len = -1;
1417 lease_len = smb2_lease_pull(state->rqls->data.data,
1418 state->rqls->data.length,
1419 &state->lease);
1420 if (lease_len == -1) {
1421 tevent_req_nterror(
1422 req, NT_STATUS_INVALID_PARAMETER);
1423 return;
1425 state->lease_ptr = &state->lease;
1427 if (DEBUGLEVEL >= 10) {
1428 DEBUG(10, ("Got lease request size %d\n",
1429 (int)lease_len));
1430 NDR_PRINT_DEBUG(smb2_lease, state->lease_ptr);
1433 if (!smb2_lease_key_valid(&state->lease.lease_key)) {
1434 state->lease_ptr = NULL;
1435 state->requested_oplock_level = SMB2_OPLOCK_LEVEL_NONE;
1438 if ((smb2req->xconn->protocol < PROTOCOL_SMB3_00) &&
1439 (state->lease.lease_version != 1))
1441 DEBUG(10, ("v2 lease key only for SMB3\n"));
1442 state->lease_ptr = NULL;
1446 * Replay with a lease is only allowed if the
1447 * established open carries a lease with the
1448 * same lease key.
1450 if (state->replay_operation) {
1451 struct smb2_lease *op_ls =
1452 &state->op->compat->lease->lease;
1453 int op_oplock = state->op->compat->oplock_type;
1455 if (map_samba_oplock_levels_to_smb2(op_oplock)
1456 != SMB2_OPLOCK_LEVEL_LEASE)
1458 status = NT_STATUS_ACCESS_DENIED;
1459 (void)tevent_req_nterror(req, status);
1460 return;
1462 if (!smb2_lease_key_equal(&state->lease.lease_key,
1463 &op_ls->lease_key))
1465 status = NT_STATUS_ACCESS_DENIED;
1466 (void)tevent_req_nterror(req, status);
1467 return;
1472 if (state->posx != NULL) {
1473 if (state->posx->data.length != 4) {
1474 DBG_DEBUG("Got %zu bytes POSX cctx, expected 4\n",
1475 state->posx->data.length);
1476 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
1477 return;
1482 static void smbd_smb2_create_after_exec(struct tevent_req *req)
1484 struct smbd_smb2_create_state *state = tevent_req_data(
1485 req, struct smbd_smb2_create_state);
1486 connection_struct *conn = state->result->conn;
1487 NTSTATUS status;
1490 * here we have op == result->op
1493 DBG_DEBUG("response construction phase\n");
1495 state->out_file_attributes = fdos_mode(state->result);
1497 if (state->mxac != NULL) {
1498 NTTIME last_write_time;
1500 last_write_time = full_timespec_to_nt_time(
1501 &state->result->fsp_name->st.st_ex_mtime);
1502 if (last_write_time != state->max_access_time) {
1503 uint8_t p[8];
1504 uint32_t max_access_granted;
1505 DATA_BLOB blob = data_blob_const(p, sizeof(p));
1507 status = smbd_calculate_access_mask_fsp(
1508 conn->cwd_fsp,
1509 state->result,
1510 false,
1511 SEC_FLAG_MAXIMUM_ALLOWED,
1512 &max_access_granted);
1514 SIVAL(p, 0, NT_STATUS_V(status));
1515 SIVAL(p, 4, max_access_granted);
1517 status = smb2_create_blob_add(
1518 state->out_context_blobs,
1519 state->out_context_blobs,
1520 SMB2_CREATE_TAG_MXAC,
1521 blob);
1522 if (!NT_STATUS_IS_OK(status)) {
1523 goto fail;
1528 if (!state->replay_operation && state->durable_requested &&
1529 (fsp_lease_type(state->result) & SMB2_LEASE_HANDLE))
1531 status = SMB_VFS_DURABLE_COOKIE(
1532 state->result,
1533 state->op,
1534 &state->op->global->backend_cookie);
1535 if (!NT_STATUS_IS_OK(status)) {
1536 state->op->global->backend_cookie = data_blob_null;
1539 if (!state->replay_operation && state->op->global->backend_cookie.length > 0)
1541 state->update_open = true;
1543 state->op->global->durable = true;
1544 state->op->global->durable_timeout_msec = state->durable_timeout_msec;
1547 if (state->update_open) {
1548 state->op->global->create_guid = state->_create_guid;
1549 if (state->need_replay_cache) {
1550 state->op->flags |= SMBXSRV_OPEN_NEED_REPLAY_CACHE;
1553 status = smbXsrv_open_update(state->op);
1554 DEBUG(10, ("smb2_create_send: smbXsrv_open_update "
1555 "returned %s\n",
1556 nt_errstr(status)));
1557 if (!NT_STATUS_IS_OK(status)) {
1558 goto fail;
1562 * We should not purge the replay cache anymore
1563 * as it's attached to the smbXsrv_open record now.
1565 state->purge_create_guid = NULL;
1568 if (state->dhnq != NULL && state->op->global->durable) {
1569 uint8_t p[8] = { 0, };
1570 DATA_BLOB blob = data_blob_const(p, sizeof(p));
1572 status = smb2_create_blob_add(state->out_context_blobs,
1573 state->out_context_blobs,
1574 SMB2_CREATE_TAG_DHNQ,
1575 blob);
1576 if (!NT_STATUS_IS_OK(status)) {
1577 goto fail;
1581 if (state->dh2q != NULL && state->op->global->durable &&
1583 * For replay operations, we return the dh2q blob
1584 * in the case of oplocks not based on the state of
1585 * the open, but on whether it could have been granted
1586 * for the request data. In the case of leases instead,
1587 * the state of the open is used...
1589 (!state->replay_operation ||
1590 state->in_oplock_level == SMB2_OPLOCK_LEVEL_BATCH ||
1591 state->in_oplock_level == SMB2_OPLOCK_LEVEL_LEASE))
1593 uint8_t p[8] = { 0, };
1594 DATA_BLOB blob = data_blob_const(p, sizeof(p));
1595 uint32_t durable_v2_response_flags = 0;
1597 SIVAL(p, 0, state->op->global->durable_timeout_msec);
1598 SIVAL(p, 4, durable_v2_response_flags);
1600 status = smb2_create_blob_add(state->out_context_blobs,
1601 state->out_context_blobs,
1602 SMB2_CREATE_TAG_DH2Q,
1603 blob);
1604 if (!NT_STATUS_IS_OK(status)) {
1605 goto fail;
1609 if (state->qfid != NULL) {
1610 uint8_t p[32];
1611 SMB_STRUCT_STAT *base_sp = state->result->base_fsp ?
1612 &state->result->base_fsp->fsp_name->st :
1613 &state->result->fsp_name->st;
1614 uint64_t file_id = SMB_VFS_FS_FILE_ID(conn, base_sp);
1615 DATA_BLOB blob = data_blob_const(p, sizeof(p));
1617 ZERO_STRUCT(p);
1619 /* From conversations with Microsoft engineers at
1620 the MS plugfest. The first 8 bytes are the "volume index"
1621 == inode, the second 8 bytes are the "volume id",
1622 == dev. This will be updated in the SMB2 doc. */
1623 SBVAL(p, 0, file_id);
1624 SIVAL(p, 8, base_sp->st_ex_dev);/* FileIndexHigh */
1626 status = smb2_create_blob_add(state->out_context_blobs,
1627 state->out_context_blobs,
1628 SMB2_CREATE_TAG_QFID,
1629 blob);
1630 if (!NT_STATUS_IS_OK(status)) {
1631 goto fail;
1635 if ((state->rqls != NULL) && (state->result->oplock_type == LEASE_OPLOCK)) {
1636 uint8_t buf[52];
1637 struct smb2_lease lease;
1638 size_t lease_len;
1640 lease = state->result->lease->lease;
1642 lease_len = sizeof(buf);
1643 if (lease.lease_version == 1) {
1644 lease_len = 32;
1647 if (!smb2_lease_push(&lease, buf, lease_len)) {
1648 status = NT_STATUS_INTERNAL_ERROR;
1649 goto fail;
1652 status = smb2_create_blob_add(
1653 state, state->out_context_blobs,
1654 SMB2_CREATE_TAG_RQLS,
1655 data_blob_const(buf, lease_len));
1656 if (!NT_STATUS_IS_OK(status)) {
1657 goto fail;
1661 if (state->posx != NULL) {
1662 struct stat_ex *psbuf = &state->result->fsp_name->st;
1663 struct smb3_posix_cc_info cc = {
1664 .nlinks = psbuf->st_ex_nlink,
1665 .posix_perms = unix_perms_to_wire(psbuf->st_ex_mode &
1666 ~S_IFMT),
1668 uint8_t buf[sizeof(struct smb3_posix_cc_info)];
1669 struct ndr_push ndr = {
1670 .data = buf,
1671 .alloc_size = sizeof(buf),
1672 .fixed_buf_size = true,
1674 enum ndr_err_code ndr_err;
1676 ndr_err =
1677 ndr_push_smb3_posix_cc_info(&ndr,
1678 NDR_SCALARS | NDR_BUFFERS,
1679 &cc);
1680 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1681 status = NT_STATUS_INSUFFICIENT_RESOURCES;
1682 goto fail;
1685 status = smb2_create_blob_add(state->out_context_blobs,
1686 state->out_context_blobs,
1687 SMB2_CREATE_TAG_POSIX,
1688 (DATA_BLOB){
1689 .data = buf,
1690 .length = ndr.offset,
1692 if (!NT_STATUS_IS_OK(status)) {
1693 goto fail;
1697 return;
1699 fail:
1700 close_file_free(state->smb1req, &state->result, ERROR_CLOSE);
1701 tevent_req_nterror(req, status);
1704 static void smbd_smb2_create_finish(struct tevent_req *req)
1706 struct smbd_smb2_create_state *state = tevent_req_data(
1707 req, struct smbd_smb2_create_state);
1708 struct smbd_smb2_request *smb2req = state->smb2req;
1709 struct smb_request *smb1req = state->smb1req;
1710 files_struct *result = state->result;
1712 smb2req->compat_chain_fsp = smb1req->chain_fsp;
1714 if (state->replay_operation) {
1715 state->out_oplock_level = state->in_oplock_level;
1716 } else if (lp_fake_oplocks(SNUM(smb2req->tcon->compat))) {
1717 state->out_oplock_level = state->in_oplock_level;
1718 } else {
1719 state->out_oplock_level = map_samba_oplock_levels_to_smb2(result->oplock_type);
1722 if ((state->in_create_disposition == FILE_SUPERSEDE)
1723 && (state->info == FILE_WAS_OVERWRITTEN)) {
1724 state->out_create_action = FILE_WAS_SUPERSEDED;
1725 } else {
1726 state->out_create_action = state->info;
1728 result->op->create_action = state->out_create_action;
1730 state->out_creation_ts = get_create_timespec(smb1req->conn,
1731 result, result->fsp_name);
1732 state->out_last_access_ts = result->fsp_name->st.st_ex_atime;
1733 state->out_last_write_ts = result->fsp_name->st.st_ex_mtime;
1734 state->out_change_ts = get_change_timespec(smb1req->conn,
1735 result, result->fsp_name);
1737 if (lp_dos_filetime_resolution(SNUM(smb2req->tcon->compat))) {
1738 dos_filetime_timespec(&state->out_creation_ts);
1739 dos_filetime_timespec(&state->out_last_access_ts);
1740 dos_filetime_timespec(&state->out_last_write_ts);
1741 dos_filetime_timespec(&state->out_change_ts);
1744 state->out_allocation_size =
1745 SMB_VFS_GET_ALLOC_SIZE(smb1req->conn, result,
1746 &(result->fsp_name->st));
1747 state->out_end_of_file = result->fsp_name->st.st_ex_size;
1748 if (state->out_file_attributes == 0) {
1749 state->out_file_attributes = FILE_ATTRIBUTE_NORMAL;
1751 state->out_file_id_persistent = result->op->global->open_persistent_id;
1752 state->out_file_id_volatile = result->op->global->open_volatile_id;
1754 DBG_DEBUG("%s - %s\n", fsp_str_dbg(result), fsp_fnum_dbg(result));
1756 tevent_req_done(req);
1757 tevent_req_post(req, state->ev);
1760 static NTSTATUS smbd_smb2_create_recv(struct tevent_req *req,
1761 TALLOC_CTX *mem_ctx,
1762 uint8_t *out_oplock_level,
1763 uint32_t *out_create_action,
1764 struct timespec *out_creation_ts,
1765 struct timespec *out_last_access_ts,
1766 struct timespec *out_last_write_ts,
1767 struct timespec *out_change_ts,
1768 uint64_t *out_allocation_size,
1769 uint64_t *out_end_of_file,
1770 uint32_t *out_file_attributes,
1771 uint64_t *out_file_id_persistent,
1772 uint64_t *out_file_id_volatile,
1773 struct smb2_create_blobs *out_context_blobs)
1775 NTSTATUS status;
1776 struct smbd_smb2_create_state *state = tevent_req_data(req,
1777 struct smbd_smb2_create_state);
1779 if (tevent_req_is_nterror(req, &status)) {
1780 tevent_req_received(req);
1781 return status;
1784 *out_oplock_level = state->out_oplock_level;
1785 *out_create_action = state->out_create_action;
1786 *out_creation_ts = state->out_creation_ts;
1787 *out_last_access_ts = state->out_last_access_ts;
1788 *out_last_write_ts = state->out_last_write_ts;
1789 *out_change_ts = state->out_change_ts;
1790 *out_allocation_size = state->out_allocation_size;
1791 *out_end_of_file = state->out_end_of_file;
1792 *out_file_attributes = state->out_file_attributes;
1793 *out_file_id_persistent = state->out_file_id_persistent;
1794 *out_file_id_volatile = state->out_file_id_volatile;
1795 *out_context_blobs = *(state->out_context_blobs);
1797 talloc_steal(mem_ctx, state->out_context_blobs->blobs);
1799 tevent_req_received(req);
1800 return NT_STATUS_OK;
1803 /*********************************************************
1804 Code for dealing with deferred opens.
1805 *********************************************************/
1807 bool get_deferred_open_message_state_smb2(struct smbd_smb2_request *smb2req,
1808 struct timeval *p_request_time,
1809 struct deferred_open_record **open_rec)
1811 struct smbd_smb2_create_state *state = NULL;
1812 struct tevent_req *req = NULL;
1814 if (!smb2req) {
1815 return false;
1817 req = smb2req->subreq;
1818 if (!req) {
1819 return false;
1821 state = tevent_req_data(req, struct smbd_smb2_create_state);
1822 if (!state) {
1823 return false;
1825 if (!state->open_was_deferred) {
1826 return false;
1828 if (p_request_time) {
1829 *p_request_time = state->request_time;
1831 if (open_rec != NULL) {
1832 *open_rec = state->open_rec;
1834 return true;
1837 /*********************************************************
1838 Re-process this call early - requested by message or
1839 close.
1840 *********************************************************/
1842 static struct smbd_smb2_request *find_open_smb2req(
1843 struct smbXsrv_connection *xconn, uint64_t mid)
1845 struct smbd_smb2_request *smb2req;
1847 for (smb2req = xconn->smb2.requests; smb2req; smb2req = smb2req->next) {
1848 uint64_t message_id;
1849 if (smb2req->subreq == NULL) {
1850 /* This message has been processed. */
1851 continue;
1853 if (!tevent_req_is_in_progress(smb2req->subreq)) {
1854 /* This message has been processed. */
1855 continue;
1857 message_id = get_mid_from_smb2req(smb2req);
1858 if (message_id == mid) {
1859 return smb2req;
1862 return NULL;
1865 bool open_was_deferred_smb2(struct smbXsrv_connection *xconn, uint64_t mid)
1867 struct smbd_smb2_create_state *state = NULL;
1868 struct smbd_smb2_request *smb2req;
1870 smb2req = find_open_smb2req(xconn, mid);
1872 if (!smb2req) {
1873 DEBUG(10,("open_was_deferred_smb2: mid %llu smb2req == NULL\n",
1874 (unsigned long long)mid));
1875 return false;
1877 if (!smb2req->subreq) {
1878 return false;
1880 if (!tevent_req_is_in_progress(smb2req->subreq)) {
1881 return false;
1883 state = tevent_req_data(smb2req->subreq,
1884 struct smbd_smb2_create_state);
1885 if (!state) {
1886 return false;
1888 /* It's not in progress if there's no timeout event. */
1889 if (!state->open_was_deferred) {
1890 return false;
1893 DEBUG(10,("open_was_deferred_smb2: mid = %llu\n",
1894 (unsigned long long)mid));
1896 return true;
1899 static void remove_deferred_open_message_smb2_internal(struct smbd_smb2_request *smb2req,
1900 uint64_t mid)
1902 struct smbd_smb2_create_state *state = NULL;
1904 if (!smb2req->subreq) {
1905 return;
1907 if (!tevent_req_is_in_progress(smb2req->subreq)) {
1908 return;
1910 state = tevent_req_data(smb2req->subreq,
1911 struct smbd_smb2_create_state);
1912 if (!state) {
1913 return;
1916 DEBUG(10,("remove_deferred_open_message_smb2_internal: "
1917 "mid %llu\n",
1918 (unsigned long long)mid ));
1920 state->open_was_deferred = false;
1921 /* Ensure we don't have any outstanding immediate event. */
1922 TALLOC_FREE(state->im);
1923 TALLOC_FREE(state->open_rec);
1926 void remove_deferred_open_message_smb2(
1927 struct smbXsrv_connection *xconn, uint64_t mid)
1929 struct smbd_smb2_request *smb2req;
1931 smb2req = find_open_smb2req(xconn, mid);
1933 if (!smb2req) {
1934 DEBUG(10,("remove_deferred_open_message_smb2: "
1935 "can't find mid %llu\n",
1936 (unsigned long long)mid ));
1937 return;
1939 remove_deferred_open_message_smb2_internal(smb2req, mid);
1942 static void smbd_smb2_create_request_dispatch_immediate(struct tevent_context *ctx,
1943 struct tevent_immediate *im,
1944 void *private_data)
1946 struct smbd_smb2_request *smb2req = talloc_get_type_abort(private_data,
1947 struct smbd_smb2_request);
1948 uint64_t mid = get_mid_from_smb2req(smb2req);
1949 NTSTATUS status;
1951 DEBUG(10,("smbd_smb2_create_request_dispatch_immediate: "
1952 "re-dispatching mid %llu\n",
1953 (unsigned long long)mid ));
1955 status = smbd_smb2_request_dispatch(smb2req);
1956 if (!NT_STATUS_IS_OK(status)) {
1957 smbd_server_connection_terminate(smb2req->xconn,
1958 nt_errstr(status));
1959 return;
1963 bool schedule_deferred_open_message_smb2(
1964 struct smbXsrv_connection *xconn, uint64_t mid)
1966 struct smbd_smb2_create_state *state = NULL;
1967 struct smbd_smb2_request *smb2req;
1969 smb2req = find_open_smb2req(xconn, mid);
1971 if (!smb2req) {
1972 DEBUG(10,("schedule_deferred_open_message_smb2: "
1973 "can't find mid %llu\n",
1974 (unsigned long long)mid ));
1975 return false;
1977 if (!smb2req->subreq) {
1978 return false;
1980 if (!tevent_req_is_in_progress(smb2req->subreq)) {
1981 return false;
1983 state = tevent_req_data(smb2req->subreq,
1984 struct smbd_smb2_create_state);
1985 if (!state) {
1986 return false;
1989 /* Ensure we don't have any outstanding immediate event. */
1990 TALLOC_FREE(state->im);
1993 * This is subtle. We must null out the callback
1994 * before rescheduling, else the first call to
1995 * tevent_req_nterror() causes the _receive()
1996 * function to be called, this causing tevent_req_post()
1997 * to crash.
1999 tevent_req_set_callback(smb2req->subreq, NULL, NULL);
2001 state->im = tevent_create_immediate(smb2req);
2002 if (!state->im) {
2003 smbd_server_connection_terminate(smb2req->xconn,
2004 nt_errstr(NT_STATUS_NO_MEMORY));
2005 return false;
2008 DEBUG(10,("schedule_deferred_open_message_smb2: "
2009 "re-processing mid %llu\n",
2010 (unsigned long long)mid ));
2012 tevent_schedule_immediate(state->im,
2013 smb2req->sconn->ev_ctx,
2014 smbd_smb2_create_request_dispatch_immediate,
2015 smb2req);
2017 return true;
2020 static bool smbd_smb2_create_cancel(struct tevent_req *req)
2022 struct smbd_smb2_request *smb2req = NULL;
2023 struct smbd_smb2_create_state *state = tevent_req_data(req,
2024 struct smbd_smb2_create_state);
2025 uint64_t mid;
2027 if (!state) {
2028 return false;
2031 if (!state->smb2req) {
2032 return false;
2035 smb2req = state->smb2req;
2036 mid = get_mid_from_smb2req(smb2req);
2038 if (is_deferred_open_async(state->open_rec)) {
2039 /* Can't cancel an async create. */
2040 return false;
2043 remove_deferred_open_message_smb2_internal(smb2req, mid);
2045 tevent_req_defer_callback(req, smb2req->sconn->ev_ctx);
2046 tevent_req_nterror(req, NT_STATUS_CANCELLED);
2047 return true;
2050 bool push_deferred_open_message_smb2(struct smbd_smb2_request *smb2req,
2051 struct timeval request_time,
2052 struct timeval timeout,
2053 struct file_id id,
2054 struct deferred_open_record *open_rec)
2056 struct tevent_req *req = NULL;
2057 struct smbd_smb2_create_state *state = NULL;
2058 struct timeval end_time;
2060 if (!smb2req) {
2061 return false;
2063 req = smb2req->subreq;
2064 if (!req) {
2065 return false;
2067 state = tevent_req_data(req, struct smbd_smb2_create_state);
2068 if (!state) {
2069 return false;
2071 state->id = id;
2072 state->request_time = request_time;
2073 state->open_rec = talloc_move(state, &open_rec);
2075 /* Re-schedule us to retry on timer expiry. */
2076 end_time = timeval_sum(&request_time, &timeout);
2078 DEBUG(10,("push_deferred_open_message_smb2: "
2079 "timeout at %s\n",
2080 timeval_string(talloc_tos(),
2081 &end_time,
2082 true) ));
2084 state->open_was_deferred = true;
2086 /* allow this request to be canceled */
2087 tevent_req_set_cancel_fn(req, smbd_smb2_create_cancel);
2089 return true;