s4:dsdb:tests: Also pass tests if asserted identity is present
[Samba.git] / source3 / smbd / smb2_create.c
blob856bf9e50de71b3f5c79898072aebdec380280dc
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 "../lib/util/tevent_ntstatus.h"
31 #include "messages.h"
32 #include "lib/util_ea.h"
34 #undef DBGC_CLASS
35 #define DBGC_CLASS DBGC_SMB2
37 int map_smb2_oplock_levels_to_samba(uint8_t in_oplock_level)
39 switch(in_oplock_level) {
40 case SMB2_OPLOCK_LEVEL_NONE:
41 return NO_OPLOCK;
42 case SMB2_OPLOCK_LEVEL_II:
43 return LEVEL_II_OPLOCK;
44 case SMB2_OPLOCK_LEVEL_EXCLUSIVE:
45 return EXCLUSIVE_OPLOCK;
46 case SMB2_OPLOCK_LEVEL_BATCH:
47 return BATCH_OPLOCK;
48 case SMB2_OPLOCK_LEVEL_LEASE:
49 return LEASE_OPLOCK;
50 default:
51 DEBUG(2,("map_smb2_oplock_levels_to_samba: "
52 "unknown level %u\n",
53 (unsigned int)in_oplock_level));
54 return NO_OPLOCK;
58 static uint8_t map_samba_oplock_levels_to_smb2(int oplock_type)
60 if (BATCH_OPLOCK_TYPE(oplock_type)) {
61 return SMB2_OPLOCK_LEVEL_BATCH;
62 } else if (EXCLUSIVE_OPLOCK_TYPE(oplock_type)) {
63 return SMB2_OPLOCK_LEVEL_EXCLUSIVE;
64 } else if (oplock_type == LEVEL_II_OPLOCK) {
65 return SMB2_OPLOCK_LEVEL_II;
66 } else if (oplock_type == LEASE_OPLOCK) {
67 return SMB2_OPLOCK_LEVEL_LEASE;
68 } else {
69 return SMB2_OPLOCK_LEVEL_NONE;
74 MS-FSA 2.1.5.1 Server Requests an Open of a File
75 Trailing '/' or '\\' checker.
76 Must be done before the filename parser removes any
77 trailing characters. If we decide to add this to SMB1
78 NTCreate processing we can make this public.
80 Note this is Windows pathname processing only. When
81 POSIX pathnames are added to SMB2 this will not apply.
84 static NTSTATUS windows_name_trailing_check(const char *name,
85 uint32_t create_options)
87 size_t name_len = strlen(name);
88 char trail_c;
90 if (name_len <= 1) {
91 return NT_STATUS_OK;
94 trail_c = name[name_len-1];
97 * Trailing '/' is always invalid.
99 if (trail_c == '/') {
100 return NT_STATUS_OBJECT_NAME_INVALID;
103 if (create_options & FILE_NON_DIRECTORY_FILE) {
104 if (trail_c == '\\') {
105 return NT_STATUS_OBJECT_NAME_INVALID;
108 return NT_STATUS_OK;
111 static struct tevent_req *smbd_smb2_create_send(TALLOC_CTX *mem_ctx,
112 struct tevent_context *ev,
113 struct smbd_smb2_request *smb2req,
114 uint8_t in_oplock_level,
115 uint32_t in_impersonation_level,
116 uint32_t in_desired_access,
117 uint32_t in_file_attributes,
118 uint32_t in_share_access,
119 uint32_t in_create_disposition,
120 uint32_t in_create_options,
121 const char *in_name,
122 struct smb2_create_blobs in_context_blobs);
123 static NTSTATUS smbd_smb2_create_recv(struct tevent_req *req,
124 TALLOC_CTX *mem_ctx,
125 uint8_t *out_oplock_level,
126 uint32_t *out_create_action,
127 struct timespec *out_creation_ts,
128 struct timespec *out_last_access_ts,
129 struct timespec *out_last_write_ts,
130 struct timespec *out_change_ts,
131 uint64_t *out_allocation_size,
132 uint64_t *out_end_of_file,
133 uint32_t *out_file_attributes,
134 uint64_t *out_file_id_persistent,
135 uint64_t *out_file_id_volatile,
136 struct smb2_create_blobs *out_context_blobs);
138 static void smbd_smb2_request_create_done(struct tevent_req *tsubreq);
139 NTSTATUS smbd_smb2_request_process_create(struct smbd_smb2_request *smb2req)
141 const uint8_t *inbody;
142 const struct iovec *indyniov;
143 uint8_t in_oplock_level;
144 uint32_t in_impersonation_level;
145 uint32_t in_desired_access;
146 uint32_t in_file_attributes;
147 uint32_t in_share_access;
148 uint32_t in_create_disposition;
149 uint32_t in_create_options;
150 uint16_t in_name_offset;
151 uint16_t in_name_length;
152 DATA_BLOB in_name_buffer;
153 char *in_name_string;
154 size_t in_name_string_size;
155 uint32_t name_offset = 0;
156 uint32_t name_available_length = 0;
157 uint32_t in_context_offset;
158 uint32_t in_context_length;
159 DATA_BLOB in_context_buffer;
160 struct smb2_create_blobs in_context_blobs;
161 uint32_t context_offset = 0;
162 uint32_t context_available_length = 0;
163 uint32_t dyn_offset;
164 NTSTATUS status;
165 bool ok;
166 struct tevent_req *tsubreq;
168 status = smbd_smb2_request_verify_sizes(smb2req, 0x39);
169 if (!NT_STATUS_IS_OK(status)) {
170 return smbd_smb2_request_error(smb2req, status);
172 inbody = SMBD_SMB2_IN_BODY_PTR(smb2req);
174 in_oplock_level = CVAL(inbody, 0x03);
175 in_impersonation_level = IVAL(inbody, 0x04);
176 in_desired_access = IVAL(inbody, 0x18);
177 in_file_attributes = IVAL(inbody, 0x1C);
178 in_share_access = IVAL(inbody, 0x20);
179 in_create_disposition = IVAL(inbody, 0x24);
180 in_create_options = IVAL(inbody, 0x28);
181 in_name_offset = SVAL(inbody, 0x2C);
182 in_name_length = SVAL(inbody, 0x2E);
183 in_context_offset = IVAL(inbody, 0x30);
184 in_context_length = IVAL(inbody, 0x34);
187 * First check if the dynamic name and context buffers
188 * are correctly specified.
190 * Note: That we don't check if the name and context buffers
191 * overlap
194 dyn_offset = SMB2_HDR_BODY + SMBD_SMB2_IN_BODY_LEN(smb2req);
196 if (in_name_offset == 0 && in_name_length == 0) {
197 /* This is ok */
198 name_offset = 0;
199 } else if (in_name_offset < dyn_offset) {
200 return smbd_smb2_request_error(smb2req, NT_STATUS_INVALID_PARAMETER);
201 } else {
202 name_offset = in_name_offset - dyn_offset;
205 indyniov = SMBD_SMB2_IN_DYN_IOV(smb2req);
207 if (name_offset > indyniov->iov_len) {
208 return smbd_smb2_request_error(smb2req, NT_STATUS_INVALID_PARAMETER);
211 name_available_length = indyniov->iov_len - name_offset;
213 if (in_name_length > name_available_length) {
214 return smbd_smb2_request_error(smb2req, NT_STATUS_INVALID_PARAMETER);
217 in_name_buffer.data = (uint8_t *)indyniov->iov_base + name_offset;
218 in_name_buffer.length = in_name_length;
220 if (in_context_offset == 0 && in_context_length == 0) {
221 /* This is ok */
222 context_offset = 0;
223 } else if (in_context_offset < dyn_offset) {
224 return smbd_smb2_request_error(smb2req, NT_STATUS_INVALID_PARAMETER);
225 } else {
226 context_offset = in_context_offset - dyn_offset;
229 if (context_offset > indyniov->iov_len) {
230 return smbd_smb2_request_error(smb2req, NT_STATUS_INVALID_PARAMETER);
233 context_available_length = indyniov->iov_len - context_offset;
235 if (in_context_length > context_available_length) {
236 return smbd_smb2_request_error(smb2req, NT_STATUS_INVALID_PARAMETER);
239 in_context_buffer.data = (uint8_t *)indyniov->iov_base +
240 context_offset;
241 in_context_buffer.length = in_context_length;
244 * Now interpret the name and context buffers
247 ok = convert_string_talloc(smb2req, CH_UTF16, CH_UNIX,
248 in_name_buffer.data,
249 in_name_buffer.length,
250 &in_name_string,
251 &in_name_string_size);
252 if (!ok) {
253 return smbd_smb2_request_error(smb2req, NT_STATUS_ILLEGAL_CHARACTER);
256 if (in_name_buffer.length == 0) {
257 in_name_string_size = 0;
260 if (strlen(in_name_string) != in_name_string_size) {
261 return smbd_smb2_request_error(smb2req, NT_STATUS_OBJECT_NAME_INVALID);
264 ZERO_STRUCT(in_context_blobs);
265 status = smb2_create_blob_parse(smb2req, in_context_buffer, &in_context_blobs);
266 if (!NT_STATUS_IS_OK(status)) {
267 return smbd_smb2_request_error(smb2req, status);
270 tsubreq = smbd_smb2_create_send(smb2req,
271 smb2req->sconn->ev_ctx,
272 smb2req,
273 in_oplock_level,
274 in_impersonation_level,
275 in_desired_access,
276 in_file_attributes,
277 in_share_access,
278 in_create_disposition,
279 in_create_options,
280 in_name_string,
281 in_context_blobs);
282 if (tsubreq == NULL) {
283 smb2req->subreq = NULL;
284 return smbd_smb2_request_error(smb2req, NT_STATUS_NO_MEMORY);
286 tevent_req_set_callback(tsubreq, smbd_smb2_request_create_done, smb2req);
288 return smbd_smb2_request_pending_queue(smb2req, tsubreq, 500);
291 static uint64_t get_mid_from_smb2req(struct smbd_smb2_request *smb2req)
293 uint8_t *reqhdr = SMBD_SMB2_OUT_HDR_PTR(smb2req);
294 return BVAL(reqhdr, SMB2_HDR_MESSAGE_ID);
297 static void smbd_smb2_request_create_done(struct tevent_req *tsubreq)
299 struct smbd_smb2_request *smb2req = tevent_req_callback_data(tsubreq,
300 struct smbd_smb2_request);
301 DATA_BLOB outbody;
302 DATA_BLOB outdyn;
303 uint8_t out_oplock_level = 0;
304 uint32_t out_create_action = 0;
305 connection_struct *conn = smb2req->tcon->compat;
306 struct timespec out_creation_ts = { 0, };
307 struct timespec out_last_access_ts = { 0, };
308 struct timespec out_last_write_ts = { 0, };
309 struct timespec out_change_ts = { 0, };
310 uint64_t out_allocation_size = 0;
311 uint64_t out_end_of_file = 0;
312 uint32_t out_file_attributes = 0;
313 uint64_t out_file_id_persistent = 0;
314 uint64_t out_file_id_volatile = 0;
315 struct smb2_create_blobs out_context_blobs;
316 DATA_BLOB out_context_buffer;
317 uint16_t out_context_buffer_offset = 0;
318 NTSTATUS status;
319 NTSTATUS error; /* transport error */
321 status = smbd_smb2_create_recv(tsubreq,
322 smb2req,
323 &out_oplock_level,
324 &out_create_action,
325 &out_creation_ts,
326 &out_last_access_ts,
327 &out_last_write_ts,
328 &out_change_ts,
329 &out_allocation_size,
330 &out_end_of_file,
331 &out_file_attributes,
332 &out_file_id_persistent,
333 &out_file_id_volatile,
334 &out_context_blobs);
335 if (!NT_STATUS_IS_OK(status)) {
336 if (smbd_smb2_is_compound(smb2req)) {
337 smb2req->compound_create_err = status;
339 error = smbd_smb2_request_error(smb2req, status);
340 if (!NT_STATUS_IS_OK(error)) {
341 smbd_server_connection_terminate(smb2req->xconn,
342 nt_errstr(error));
343 return;
345 return;
348 status = smb2_create_blob_push(smb2req, &out_context_buffer, out_context_blobs);
349 if (!NT_STATUS_IS_OK(status)) {
350 error = smbd_smb2_request_error(smb2req, status);
351 if (!NT_STATUS_IS_OK(error)) {
352 smbd_server_connection_terminate(smb2req->xconn,
353 nt_errstr(error));
354 return;
356 return;
359 if (out_context_buffer.length > 0) {
360 out_context_buffer_offset = SMB2_HDR_BODY + 0x58;
363 outbody = smbd_smb2_generate_outbody(smb2req, 0x58);
364 if (outbody.data == NULL) {
365 error = smbd_smb2_request_error(smb2req, NT_STATUS_NO_MEMORY);
366 if (!NT_STATUS_IS_OK(error)) {
367 smbd_server_connection_terminate(smb2req->xconn,
368 nt_errstr(error));
369 return;
371 return;
374 SSVAL(outbody.data, 0x00, 0x58 + 1); /* struct size */
375 SCVAL(outbody.data, 0x02,
376 out_oplock_level); /* oplock level */
377 SCVAL(outbody.data, 0x03, 0); /* reserved */
378 SIVAL(outbody.data, 0x04,
379 out_create_action); /* create action */
380 put_long_date_full_timespec(conn->ts_res,
381 (char *)outbody.data + 0x08,
382 &out_creation_ts); /* creation time */
383 put_long_date_full_timespec(conn->ts_res,
384 (char *)outbody.data + 0x10,
385 &out_last_access_ts); /* last access time */
386 put_long_date_full_timespec(conn->ts_res,
387 (char *)outbody.data + 0x18,
388 &out_last_write_ts); /* last write time */
389 put_long_date_full_timespec(conn->ts_res,
390 (char *)outbody.data + 0x20,
391 &out_change_ts); /* change time */
392 SBVAL(outbody.data, 0x28,
393 out_allocation_size); /* allocation size */
394 SBVAL(outbody.data, 0x30,
395 out_end_of_file); /* end of file */
396 SIVAL(outbody.data, 0x38,
397 out_file_attributes); /* file attributes */
398 SIVAL(outbody.data, 0x3C, 0); /* reserved */
399 SBVAL(outbody.data, 0x40,
400 out_file_id_persistent); /* file id (persistent) */
401 SBVAL(outbody.data, 0x48,
402 out_file_id_volatile); /* file id (volatile) */
403 SIVAL(outbody.data, 0x50,
404 out_context_buffer_offset); /* create contexts offset */
405 SIVAL(outbody.data, 0x54,
406 out_context_buffer.length); /* create contexts length */
408 outdyn = out_context_buffer;
410 error = smbd_smb2_request_done(smb2req, outbody, &outdyn);
411 if (!NT_STATUS_IS_OK(error)) {
412 smbd_server_connection_terminate(smb2req->xconn,
413 nt_errstr(error));
414 return;
418 static bool smb2_lease_key_valid(const struct smb2_lease_key *key)
420 return ((key->data[0] != 0) || (key->data[1] != 0));
423 static NTSTATUS smbd_smb2_create_durable_lease_check(struct smb_request *smb1req,
424 const char *requested_filename, const struct files_struct *fsp,
425 const struct smb2_lease *lease_ptr)
427 char *filename = NULL;
428 struct smb_filename *smb_fname = NULL;
429 uint32_t ucf_flags;
430 NTSTATUS status;
432 if (lease_ptr == NULL) {
433 if (fsp->oplock_type != LEASE_OPLOCK) {
434 return NT_STATUS_OK;
436 DEBUG(10, ("Reopened file has lease, but no lease "
437 "requested\n"));
438 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
441 if (fsp->oplock_type != LEASE_OPLOCK) {
442 DEBUG(10, ("Lease requested, but reopened file has no "
443 "lease\n"));
444 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
447 if (!smb2_lease_key_equal(&lease_ptr->lease_key,
448 &fsp->lease->lease.lease_key)) {
449 DEBUG(10, ("Different lease key requested than found "
450 "in reopened file\n"));
451 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
454 filename = talloc_strdup(talloc_tos(), requested_filename);
455 if (filename == NULL) {
456 return NT_STATUS_NO_MEMORY;
459 /* This also converts '\' to '/' */
460 status = check_path_syntax(filename);
461 if (!NT_STATUS_IS_OK(status)) {
462 TALLOC_FREE(filename);
463 return status;
466 ucf_flags = filename_create_ucf_flags(smb1req, FILE_OPEN);
467 status = filename_convert(talloc_tos(), fsp->conn,
468 filename, ucf_flags,
469 0, &smb_fname);
470 TALLOC_FREE(filename);
471 if (!NT_STATUS_IS_OK(status)) {
472 DEBUG(10, ("filename_convert returned %s\n",
473 nt_errstr(status)));
474 return status;
477 if (!strequal(fsp->fsp_name->base_name, smb_fname->base_name)) {
478 DEBUG(10, ("Lease requested for file %s, reopened file "
479 "is named %s\n", smb_fname->base_name,
480 fsp->fsp_name->base_name));
481 TALLOC_FREE(smb_fname);
482 return NT_STATUS_INVALID_PARAMETER;
485 TALLOC_FREE(smb_fname);
487 return NT_STATUS_OK;
490 struct smbd_smb2_create_state {
491 struct tevent_context *ev;
492 struct smbd_smb2_request *smb2req;
493 struct GUID req_guid;
494 struct smb_request *smb1req;
495 bool open_was_deferred;
496 struct tevent_immediate *im;
497 struct timeval request_time;
498 struct file_id id;
499 struct deferred_open_record *open_rec;
500 files_struct *result;
501 bool replay_operation;
502 uint8_t in_oplock_level;
503 uint32_t in_create_disposition;
504 int requested_oplock_level;
505 int info;
506 char *fname;
507 struct ea_list *ea_list;
508 NTTIME max_access_time;
509 struct security_descriptor *sec_desc;
510 uint64_t allocation_size;
511 struct GUID _create_guid;
512 struct GUID *create_guid;
513 struct GUID _purge_create_guid;
514 struct GUID *purge_create_guid;
515 bool update_open;
516 bool durable_requested;
517 uint32_t durable_timeout_msec;
518 bool do_durable_reconnect;
519 uint64_t persistent_id;
520 struct smb2_lease lease;
521 struct smb2_lease *lease_ptr;
522 ssize_t lease_len;
523 bool need_replay_cache;
524 struct smbXsrv_open *op;
525 NTTIME twrp_time;
527 struct smb2_create_blob *dhnc;
528 struct smb2_create_blob *dh2c;
529 struct smb2_create_blob *dhnq;
530 struct smb2_create_blob *dh2q;
531 struct smb2_create_blob *rqls;
532 struct smb2_create_blob *exta;
533 struct smb2_create_blob *mxac;
534 struct smb2_create_blob *secd;
535 struct smb2_create_blob *alsi;
536 struct smb2_create_blob *twrp;
537 struct smb2_create_blob *qfid;
538 struct smb2_create_blob *svhdx;
540 uint8_t out_oplock_level;
541 uint32_t out_create_action;
542 struct timespec out_creation_ts;
543 struct timespec out_last_access_ts;
544 struct timespec out_last_write_ts;
545 struct timespec out_change_ts;
546 uint64_t out_allocation_size;
547 uint64_t out_end_of_file;
548 uint32_t out_file_attributes;
549 uint64_t out_file_id_persistent;
550 uint64_t out_file_id_volatile;
551 struct smb2_create_blobs *out_context_blobs;
554 static void smbd_smb2_create_purge_replay_cache(struct tevent_req *req,
555 const char *caller_func);
557 static void smbd_smb2_create_cleanup(struct tevent_req *req,
558 enum tevent_req_state req_state)
560 smbd_smb2_create_purge_replay_cache(req, __func__);
563 static NTSTATUS smbd_smb2_create_fetch_create_ctx(
564 struct tevent_req *req,
565 struct smb2_create_blobs *in_context_blobs)
567 struct smbd_smb2_create_state *state = tevent_req_data(
568 req, struct smbd_smb2_create_state);
571 * For now, remove the posix create context from the wire. We
572 * are using it inside smbd and will properly use it once
573 * smb3.11 unix extensions will be done. So in the future we
574 * will remove it only if unix extensions are not negotiated.
576 smb2_create_blob_remove(in_context_blobs, SMB2_CREATE_TAG_POSIX);
578 state->dhnq = smb2_create_blob_find(in_context_blobs,
579 SMB2_CREATE_TAG_DHNQ);
580 state->dhnc = smb2_create_blob_find(in_context_blobs,
581 SMB2_CREATE_TAG_DHNC);
582 state->dh2q = smb2_create_blob_find(in_context_blobs,
583 SMB2_CREATE_TAG_DH2Q);
584 state->dh2c = smb2_create_blob_find(in_context_blobs,
585 SMB2_CREATE_TAG_DH2C);
586 if (state->smb2req->xconn->smb2.server.capabilities & SMB2_CAP_LEASING) {
587 state->rqls = smb2_create_blob_find(in_context_blobs,
588 SMB2_CREATE_TAG_RQLS);
591 if (((state->dhnc != NULL) && (state->dh2c != NULL)) ||
592 ((state->dhnc != NULL) && (state->dh2q != NULL)) ||
593 ((state->dh2c != NULL) && (state->dhnq != NULL)) ||
594 ((state->dh2q != NULL) && (state->dh2c != NULL)))
596 /* not both are allowed at the same time */
597 return NT_STATUS_INVALID_PARAMETER;
600 if (state->dhnc != NULL) {
601 uint32_t num_blobs_allowed;
603 if (state->dhnc->data.length != 16) {
604 return NT_STATUS_INVALID_PARAMETER;
608 * According to MS-SMB2: 3.3.5.9.7, "Handling the
609 * SMB2_CREATE_DURABLE_HANDLE_RECONNECT Create Context",
610 * we should ignore an additional dhnq blob, but fail
611 * the request (with status OBJECT_NAME_NOT_FOUND) if
612 * any other extra create blob has been provided.
614 * (Note that the cases of an additional dh2q or dh2c blob
615 * which require a different error code, have been treated
616 * above.)
619 if (state->dhnq != NULL) {
620 num_blobs_allowed = 2;
621 } else {
622 num_blobs_allowed = 1;
625 if (state->rqls != NULL) {
626 num_blobs_allowed += 1;
629 if (in_context_blobs->num_blobs != num_blobs_allowed) {
630 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
634 if (state->dh2c!= NULL) {
635 uint32_t num_blobs_allowed;
637 if (state->dh2c->data.length != 36) {
638 return NT_STATUS_INVALID_PARAMETER;
642 * According to MS-SMB2: 3.3.5.9.12, "Handling the
643 * SMB2_CREATE_DURABLE_HANDLE_RECONNECT_V2 Create Context",
644 * we should fail the request with status
645 * OBJECT_NAME_NOT_FOUND if any other create blob has been
646 * provided.
648 * (Note that the cases of an additional dhnq, dhnc or dh2q
649 * blob which require a different error code, have been
650 * treated above.)
653 num_blobs_allowed = 1;
655 if (state->rqls != NULL) {
656 num_blobs_allowed += 1;
659 if (in_context_blobs->num_blobs != num_blobs_allowed) {
660 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
664 state->exta = smb2_create_blob_find(in_context_blobs,
665 SMB2_CREATE_TAG_EXTA);
666 state->mxac = smb2_create_blob_find(in_context_blobs,
667 SMB2_CREATE_TAG_MXAC);
668 state->secd = smb2_create_blob_find(in_context_blobs,
669 SMB2_CREATE_TAG_SECD);
670 state->alsi = smb2_create_blob_find(in_context_blobs,
671 SMB2_CREATE_TAG_ALSI);
672 state->twrp = smb2_create_blob_find(in_context_blobs,
673 SMB2_CREATE_TAG_TWRP);
674 state->qfid = smb2_create_blob_find(in_context_blobs,
675 SMB2_CREATE_TAG_QFID);
676 if (state->smb2req->xconn->protocol >= PROTOCOL_SMB3_02) {
678 * This was introduced with SMB3_02
680 state->svhdx = smb2_create_blob_find(
681 in_context_blobs, SVHDX_OPEN_DEVICE_CONTEXT);
684 return NT_STATUS_OK;
687 static void smbd_smb2_create_before_exec(struct tevent_req *req);
688 static void smbd_smb2_create_after_exec(struct tevent_req *req);
689 static void smbd_smb2_create_finish(struct tevent_req *req);
691 static struct tevent_req *smbd_smb2_create_send(TALLOC_CTX *mem_ctx,
692 struct tevent_context *ev,
693 struct smbd_smb2_request *smb2req,
694 uint8_t in_oplock_level,
695 uint32_t in_impersonation_level,
696 uint32_t in_desired_access,
697 uint32_t in_file_attributes,
698 uint32_t in_share_access,
699 uint32_t in_create_disposition,
700 uint32_t in_create_options,
701 const char *in_name,
702 struct smb2_create_blobs in_context_blobs)
704 struct tevent_req *req = NULL;
705 struct smbd_smb2_create_state *state = NULL;
706 NTSTATUS status;
707 struct smb_request *smb1req = NULL;
708 struct smb_filename *smb_fname = NULL;
709 uint32_t ucf_flags;
711 req = tevent_req_create(mem_ctx, &state,
712 struct smbd_smb2_create_state);
713 if (req == NULL) {
714 return NULL;
716 *state = (struct smbd_smb2_create_state) {
717 .ev = ev,
718 .smb2req = smb2req,
719 .in_oplock_level = in_oplock_level,
720 .in_create_disposition = in_create_disposition,
723 smb1req = smbd_smb2_fake_smb_request(smb2req);
724 if (tevent_req_nomem(smb1req, req)) {
725 return tevent_req_post(req, state->ev);
727 state->smb1req = smb1req;
729 state->req_guid = smbd_request_guid(smb1req, 0);
731 tevent_req_set_cleanup_fn(req, smbd_smb2_create_cleanup);
733 if (smb2req->subreq == NULL) {
734 DBG_DEBUG("name [%s]\n", in_name);
735 } else {
736 struct smbd_smb2_create_state *old_state = tevent_req_data(
737 smb2req->subreq, struct smbd_smb2_create_state);
739 DBG_DEBUG("reentrant for file %s\n", in_name);
741 state->id = old_state->id;
742 state->request_time = old_state->request_time;
743 state->open_rec = talloc_move(state, &old_state->open_rec);
744 state->open_was_deferred = old_state->open_was_deferred;
745 state->_purge_create_guid = old_state->_purge_create_guid;
746 state->purge_create_guid = old_state->purge_create_guid;
747 old_state->purge_create_guid = NULL;
750 TALLOC_FREE(smb2req->subreq);
751 smb2req->subreq = req;
753 if (lp_fake_oplocks(SNUM(smb2req->tcon->compat))) {
754 state->requested_oplock_level = SMB2_OPLOCK_LEVEL_NONE;
755 } else {
756 state->requested_oplock_level = state->in_oplock_level;
759 /* these are ignored for SMB2 */
760 in_create_options &= ~(0x10);/* NTCREATEX_OPTIONS_SYNC_ALERT */
761 in_create_options &= ~(0x20);/* NTCREATEX_OPTIONS_ASYNC_ALERT */
763 in_file_attributes &= ~FILE_FLAG_POSIX_SEMANTICS;
765 state->fname = talloc_strdup(state, in_name);
766 if (tevent_req_nomem(state->fname, req)) {
767 return tevent_req_post(req, state->ev);
770 state->out_context_blobs = talloc_zero(state, struct smb2_create_blobs);
771 if (tevent_req_nomem(state->out_context_blobs, req)) {
772 return tevent_req_post(req, state->ev);
775 status = smbd_smb2_create_fetch_create_ctx(req, &in_context_blobs);
776 if (tevent_req_nterror(req, status)) {
777 return tevent_req_post(req, state->ev);
780 if (IS_IPC(smb1req->conn)) {
781 const char *pipe_name = in_name;
783 if (state->dhnc != NULL || state->dh2c != NULL) {
784 /* durable handles are not supported on IPC$ */
785 tevent_req_nterror(req, NT_STATUS_OBJECT_NAME_NOT_FOUND);
786 return tevent_req_post(req, state->ev);
789 if (!lp_nt_pipe_support()) {
790 tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
791 return tevent_req_post(req, state->ev);
794 status = open_np_file(smb1req, pipe_name, &state->result);
795 if (!NT_STATUS_IS_OK(status)) {
796 tevent_req_nterror(req, status);
797 return tevent_req_post(req, state->ev);
799 state->info = FILE_WAS_OPENED;
801 smbd_smb2_create_finish(req);
802 return req;
805 if (CAN_PRINT(smb1req->conn)) {
806 if (state->dhnc != NULL || state->dh2c != NULL) {
807 /* durable handles are not supported on printers */
808 tevent_req_nterror(req, NT_STATUS_OBJECT_NAME_NOT_FOUND);
809 return tevent_req_post(req, state->ev);
812 status = file_new(smb1req, smb1req->conn, &state->result);
813 if(!NT_STATUS_IS_OK(status)) {
814 tevent_req_nterror(req, status);
815 return tevent_req_post(req, state->ev);
818 status = print_spool_open(state->result, in_name,
819 smb1req->vuid);
820 if (!NT_STATUS_IS_OK(status)) {
821 file_free(smb1req, state->result);
822 tevent_req_nterror(req, status);
823 return tevent_req_post(req, state->ev);
825 state->info = FILE_WAS_CREATED;
827 smbd_smb2_create_finish(req);
828 return req;
831 /* Check for trailing slash specific directory handling. */
832 status = windows_name_trailing_check(state->fname, in_create_options);
833 if (!NT_STATUS_IS_OK(status)) {
834 tevent_req_nterror(req, status);
835 return tevent_req_post(req, state->ev);
838 smbd_smb2_create_before_exec(req);
839 if (!tevent_req_is_in_progress(req)) {
840 return tevent_req_post(req, state->ev);
843 DBG_DEBUG("open execution phase\n");
846 * For the backend file open procedure, there are
847 * three possible modes: replay operation (in which case
848 * there is nothing else to do), durable_reconnect or
849 * new open.
851 if (state->replay_operation) {
852 state->result = state->op->compat;
853 state->result->op = state->op;
854 state->update_open = false;
855 state->info = state->op->create_action;
857 smbd_smb2_create_after_exec(req);
858 if (!tevent_req_is_in_progress(req)) {
859 return req;
862 smbd_smb2_create_finish(req);
863 return req;
866 if (state->do_durable_reconnect) {
867 DATA_BLOB new_cookie = data_blob_null;
868 NTTIME now = timeval_to_nttime(&smb2req->request_time);
870 status = smb2srv_open_recreate(smb2req->xconn,
871 smb1req->conn->session_info,
872 state->persistent_id,
873 state->create_guid,
874 now,
875 &state->op);
876 if (!NT_STATUS_IS_OK(status)) {
877 DBG_NOTICE("smb2srv_open_recreate failed: %s\n",
878 nt_errstr(status));
879 tevent_req_nterror(req, status);
880 return tevent_req_post(req, state->ev);
883 DBG_DEBUG("%s to recreate durable handle\n",
884 state->op->global->durable ? "succeeded" : "failed");
886 if (!state->op->global->durable) {
887 talloc_free(state->op);
888 tevent_req_nterror(req,
889 NT_STATUS_OBJECT_NAME_NOT_FOUND);
890 return tevent_req_post(req, state->ev);
893 status = SMB_VFS_DURABLE_RECONNECT(smb1req->conn,
894 smb1req,
895 state->op, /* smbXsrv_open input */
896 state->op->global->backend_cookie,
897 state->op, /* TALLOC_CTX */
898 &state->result,
899 &new_cookie);
900 if (!NT_STATUS_IS_OK(status)) {
901 NTSTATUS return_status;
903 return_status = NT_STATUS_OBJECT_NAME_NOT_FOUND;
905 DBG_NOTICE("durable_reconnect failed: %s => %s\n",
906 nt_errstr(status),
907 nt_errstr(return_status));
909 tevent_req_nterror(req, return_status);
910 return tevent_req_post(req, state->ev);
913 DBG_DEBUG("oplock_type=%u, lease_ptr==%p\n",
914 (unsigned)state->result->oplock_type, state->lease_ptr);
916 status = smbd_smb2_create_durable_lease_check(
917 smb1req, state->fname, state->result, state->lease_ptr);
918 if (!NT_STATUS_IS_OK(status)) {
919 close_file_free(
920 smb1req, &state->result, SHUTDOWN_CLOSE);
921 tevent_req_nterror(req, status);
922 return tevent_req_post(req, state->ev);
925 data_blob_free(&state->op->global->backend_cookie);
926 state->op->global->backend_cookie = new_cookie;
928 state->op->status = NT_STATUS_OK;
929 state->op->global->disconnect_time = 0;
931 /* save the timout for later update */
932 state->durable_timeout_msec = state->op->global->durable_timeout_msec;
934 state->update_open = true;
936 state->info = FILE_WAS_OPENED;
938 smbd_smb2_create_after_exec(req);
939 if (!tevent_req_is_in_progress(req)) {
940 return req;
943 smbd_smb2_create_finish(req);
944 return req;
947 if (state->requested_oplock_level == SMB2_OPLOCK_LEVEL_LEASE) {
948 if (state->lease_ptr == NULL) {
949 state->requested_oplock_level = SMB2_OPLOCK_LEVEL_NONE;
951 } else {
952 state->lease_ptr = NULL;
956 * For a DFS path the function parse_dfs_path()
957 * will do the path processing.
960 if (!(smb1req->flags2 & FLAGS2_DFS_PATHNAMES)) {
961 /* convert '\\' into '/' */
962 status = check_path_syntax(state->fname);
963 if (!NT_STATUS_IS_OK(status)) {
964 tevent_req_nterror(req, status);
965 return tevent_req_post(req, state->ev);
969 ucf_flags = filename_create_ucf_flags(
970 smb1req, state->in_create_disposition);
971 status = filename_convert(req,
972 smb1req->conn,
973 state->fname,
974 ucf_flags,
975 state->twrp_time,
976 &smb_fname);
977 if (!NT_STATUS_IS_OK(status)) {
978 tevent_req_nterror(req, status);
979 return tevent_req_post(req, state->ev);
983 * MS-SMB2: 2.2.13 SMB2 CREATE Request
984 * ImpersonationLevel ... MUST contain one of the
985 * following values. The server MUST validate this
986 * field, but otherwise ignore it.
988 * NB. The source4/torture/smb2/durable_open.c test
989 * shows this check is only done on real opens, not
990 * on durable handle-reopens.
993 if (in_impersonation_level >
994 SMB2_IMPERSONATION_DELEGATE) {
995 tevent_req_nterror(req,
996 NT_STATUS_BAD_IMPERSONATION_LEVEL);
997 return tevent_req_post(req, state->ev);
1001 * We know we're going to do a local open, so now
1002 * we must be protocol strict. JRA.
1004 * MS-SMB2: 3.3.5.9 - Receiving an SMB2 CREATE Request
1005 * If the file name length is greater than zero and the
1006 * first character is a path separator character, the
1007 * server MUST fail the request with
1008 * STATUS_INVALID_PARAMETER.
1010 if (in_name[0] == '\\' || in_name[0] == '/') {
1011 tevent_req_nterror(req,
1012 NT_STATUS_INVALID_PARAMETER);
1013 return tevent_req_post(req, state->ev);
1016 status = SMB_VFS_CREATE_FILE(smb1req->conn,
1017 smb1req,
1018 smb_fname,
1019 in_desired_access,
1020 in_share_access,
1021 state->in_create_disposition,
1022 in_create_options,
1023 in_file_attributes,
1024 map_smb2_oplock_levels_to_samba(
1025 state->requested_oplock_level),
1026 state->lease_ptr,
1027 state->allocation_size,
1028 0, /* private_flags */
1029 state->sec_desc,
1030 state->ea_list,
1031 &state->result,
1032 &state->info,
1033 &in_context_blobs,
1034 state->out_context_blobs);
1035 if (!NT_STATUS_IS_OK(status)) {
1036 if (open_was_deferred(smb1req->xconn, smb1req->mid)) {
1037 SMBPROFILE_IOBYTES_ASYNC_SET_IDLE(smb2req->profile);
1038 return req;
1040 tevent_req_nterror(req, status);
1041 return tevent_req_post(req, state->ev);
1043 state->op = state->result->op;
1045 smbd_smb2_create_after_exec(req);
1046 if (!tevent_req_is_in_progress(req)) {
1047 return req;
1050 smbd_smb2_create_finish(req);
1051 return req;
1054 static void smbd_smb2_create_purge_replay_cache(struct tevent_req *req,
1055 const char *caller_func)
1057 struct smbd_smb2_create_state *state = tevent_req_data(
1058 req, struct smbd_smb2_create_state);
1059 NTSTATUS status;
1061 if (state->purge_create_guid == NULL) {
1062 return;
1065 status = smbXsrv_open_purge_replay_cache(state->smb2req->xconn->client,
1066 state->purge_create_guid);
1067 if (!NT_STATUS_IS_OK(status)) {
1068 struct GUID_txt_buf buf;
1070 D_ERR("%s: smbXsrv_open_purge_replay_cache(%s) %s\n",
1071 caller_func,
1072 GUID_buf_string(state->purge_create_guid, &buf),
1073 nt_errstr(status));
1076 state->purge_create_guid = NULL;
1079 static void smbd_smb2_create_before_exec(struct tevent_req *req)
1081 struct smbd_smb2_create_state *state = tevent_req_data(
1082 req, struct smbd_smb2_create_state);
1083 struct smbd_smb2_request *smb2req = state->smb2req;
1084 NTSTATUS status;
1086 if (state->exta != NULL) {
1087 if (!lp_ea_support(SNUM(smb2req->tcon->compat))) {
1088 tevent_req_nterror(req, NT_STATUS_EAS_NOT_SUPPORTED);
1089 return;
1092 state->ea_list = read_nttrans_ea_list(
1093 state,
1094 (const char *)state->exta->data.data,
1095 state->exta->data.length);
1096 if (state->ea_list == NULL) {
1097 DEBUG(10,("smbd_smb2_create_send: read_ea_name_list failed.\n"));
1098 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
1099 return;
1103 * NB. When SMB2+ unix extensions are added,
1104 * we need to relax this check in invalid
1105 * names - we used to not do this if
1106 * lp_posix_pathnames() was false.
1108 if (ea_list_has_invalid_name(state->ea_list)) {
1109 tevent_req_nterror(req, STATUS_INVALID_EA_NAME);
1110 return;
1114 if (state->mxac != NULL) {
1115 if (state->mxac->data.length == 0) {
1116 state->max_access_time = 0;
1117 } else if (state->mxac->data.length == 8) {
1118 state->max_access_time = BVAL(state->mxac->data.data, 0);
1119 } else {
1120 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
1121 return;
1125 if (state->secd != NULL) {
1126 enum ndr_err_code ndr_err;
1128 state->sec_desc = talloc_zero(state, struct security_descriptor);
1129 if (tevent_req_nomem(state->sec_desc, req)) {
1130 return;
1133 ndr_err = ndr_pull_struct_blob(&state->secd->data,
1134 state->sec_desc, state->sec_desc,
1135 (ndr_pull_flags_fn_t)ndr_pull_security_descriptor);
1136 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1137 DEBUG(2,("ndr_pull_security_descriptor failed: %s\n",
1138 ndr_errstr(ndr_err)));
1139 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
1140 return;
1144 if (state->dhnq != NULL) {
1145 if (state->dhnq->data.length != 16) {
1146 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
1147 return;
1150 if (state->dh2q != NULL) {
1151 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
1152 return;
1156 * durable handle request is processed below.
1158 state->durable_requested = true;
1160 * Set the timeout to 16 mins.
1162 * TODO: test this against Windows 2012
1163 * as the default for durable v2 is 1 min.
1165 state->durable_timeout_msec = (16*60*1000);
1168 if (state->dh2q != NULL) {
1169 const uint8_t *p = state->dh2q->data.data;
1170 NTTIME now = timeval_to_nttime(&smb2req->request_time);
1171 uint32_t durable_v2_timeout = 0;
1172 DATA_BLOB create_guid_blob;
1173 const uint8_t *hdr;
1174 uint32_t flags;
1176 if (state->dh2q->data.length != 32) {
1177 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
1178 return;
1181 if (state->dhnq != NULL) {
1182 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
1183 return;
1186 durable_v2_timeout = IVAL(p, 0);
1187 create_guid_blob = data_blob_const(p + 16, 16);
1189 status = GUID_from_ndr_blob(&create_guid_blob,
1190 &state->_create_guid);
1191 if (tevent_req_nterror(req, status)) {
1192 return;
1194 state->create_guid = &state->_create_guid;
1197 * we need to store the create_guid later
1199 state->update_open = true;
1202 * And we need to create a cache for replaying the
1203 * create.
1205 state->need_replay_cache = true;
1208 * durable handle v2 request processed below
1210 state->durable_requested = true;
1211 state->durable_timeout_msec = MIN(durable_v2_timeout, 300*1000);
1212 if (state->durable_timeout_msec == 0) {
1214 * Set the timeout to 1 min as default.
1216 * This matches Windows 2012.
1218 state->durable_timeout_msec = (60*1000);
1222 * Check for replay operation.
1223 * Only consider it when we have dh2q.
1224 * If we do not have a replay operation, verify that
1225 * the create_guid is not cached for replay.
1227 hdr = SMBD_SMB2_IN_HDR_PTR(smb2req);
1228 flags = IVAL(hdr, SMB2_HDR_FLAGS);
1229 state->replay_operation =
1230 flags & SMB2_HDR_FLAG_REPLAY_OPERATION;
1232 status = smb2srv_open_lookup_replay_cache(smb2req->xconn,
1233 state->req_guid,
1234 *state->create_guid,
1235 state->fname,
1236 now,
1237 &state->op);
1238 if (NT_STATUS_EQUAL(status, NT_STATUS_FWP_RESERVED)) {
1240 * We've reserved the replay_cache record
1241 * for ourself, indicating we're still
1242 * in progress.
1244 * It means the smbd_smb2_create_cleanup()
1245 * may need to call smbXsrv_open_purge_replay_cache()
1246 * in order to cleanup.
1248 SMB_ASSERT(state->op == NULL);
1249 state->_purge_create_guid = state->_create_guid;
1250 state->purge_create_guid = &state->_purge_create_guid;
1251 status = NT_STATUS_OK;
1252 state->replay_operation = false;
1253 } else if (NT_STATUS_EQUAL(status, NT_STATUS_FILE_NOT_AVAILABLE)) {
1254 tevent_req_nterror(req, status);
1255 return;
1256 } else if (!NT_STATUS_IS_OK(status)) {
1257 DBG_WARNING("smb2srv_open_lookup_replay_cache "
1258 "failed: %s\n", nt_errstr(status));
1259 tevent_req_nterror(req, status);
1260 return;
1261 } else if (!state->replay_operation) {
1263 * If a create without replay operation flag
1264 * is sent but with a create_guid that is
1265 * currently in the replay cache -- fail.
1267 status = NT_STATUS_DUPLICATE_OBJECTID;
1268 (void)tevent_req_nterror(req, status);
1269 return;
1273 if (state->dhnc != NULL) {
1274 state->persistent_id = BVAL(state->dhnc->data.data, 0);
1275 state->do_durable_reconnect = true;
1278 if (state->dh2c != NULL) {
1279 const uint8_t *p = state->dh2c->data.data;
1280 DATA_BLOB create_guid_blob;
1282 state->persistent_id = BVAL(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;
1291 state->create_guid = &state->_create_guid;
1292 state->do_durable_reconnect = true;
1295 if (state->alsi != NULL) {
1296 if (state->alsi->data.length != 8) {
1297 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
1298 return;
1300 state->allocation_size = BVAL(state->alsi->data.data, 0);
1303 if (state->twrp != NULL) {
1304 if (state->twrp->data.length != 8) {
1305 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
1306 return;
1309 state->twrp_time = BVAL(state->twrp->data.data, 0);
1312 if (state->qfid != NULL) {
1313 if (state->qfid->data.length != 0) {
1314 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
1315 return;
1319 if (state->rqls != NULL) {
1320 ssize_t lease_len = -1;
1322 lease_len = smb2_lease_pull(state->rqls->data.data,
1323 state->rqls->data.length,
1324 &state->lease);
1325 if (lease_len == -1) {
1326 tevent_req_nterror(
1327 req, NT_STATUS_INVALID_PARAMETER);
1328 return;
1330 state->lease_ptr = &state->lease;
1332 if (DEBUGLEVEL >= 10) {
1333 DEBUG(10, ("Got lease request size %d\n",
1334 (int)lease_len));
1335 NDR_PRINT_DEBUG(smb2_lease, state->lease_ptr);
1338 if (!smb2_lease_key_valid(&state->lease.lease_key)) {
1339 state->lease_ptr = NULL;
1340 state->requested_oplock_level = SMB2_OPLOCK_LEVEL_NONE;
1343 if ((smb2req->xconn->protocol < PROTOCOL_SMB3_00) &&
1344 (state->lease.lease_version != 1))
1346 DEBUG(10, ("v2 lease key only for SMB3\n"));
1347 state->lease_ptr = NULL;
1351 * Replay with a lease is only allowed if the
1352 * established open carries a lease with the
1353 * same lease key.
1355 if (state->replay_operation) {
1356 struct smb2_lease *op_ls =
1357 &state->op->compat->lease->lease;
1358 int op_oplock = state->op->compat->oplock_type;
1360 if (map_samba_oplock_levels_to_smb2(op_oplock)
1361 != SMB2_OPLOCK_LEVEL_LEASE)
1363 status = NT_STATUS_ACCESS_DENIED;
1364 (void)tevent_req_nterror(req, status);
1365 return;
1367 if (!smb2_lease_key_equal(&state->lease.lease_key,
1368 &op_ls->lease_key))
1370 status = NT_STATUS_ACCESS_DENIED;
1371 (void)tevent_req_nterror(req, status);
1372 return;
1378 static void smbd_smb2_create_after_exec(struct tevent_req *req)
1380 struct smbd_smb2_create_state *state = tevent_req_data(
1381 req, struct smbd_smb2_create_state);
1382 NTSTATUS status;
1385 * here we have op == result->op
1388 DEBUG(10, ("smbd_smb2_create_send: "
1389 "response construction phase\n"));
1391 state->out_file_attributes = fdos_mode(state->result);
1393 if (state->mxac != NULL) {
1394 NTTIME last_write_time;
1396 last_write_time = full_timespec_to_nt_time(
1397 &state->result->fsp_name->st.st_ex_mtime);
1398 if (last_write_time != state->max_access_time) {
1399 uint8_t p[8];
1400 uint32_t max_access_granted;
1401 DATA_BLOB blob = data_blob_const(p, sizeof(p));
1403 status = smbd_calculate_access_mask_fsp(
1404 state->result->conn->cwd_fsp,
1405 state->result,
1406 false,
1407 SEC_FLAG_MAXIMUM_ALLOWED,
1408 &max_access_granted);
1410 SIVAL(p, 0, NT_STATUS_V(status));
1411 SIVAL(p, 4, max_access_granted);
1413 status = smb2_create_blob_add(
1414 state->out_context_blobs,
1415 state->out_context_blobs,
1416 SMB2_CREATE_TAG_MXAC,
1417 blob);
1418 if (!NT_STATUS_IS_OK(status)) {
1419 tevent_req_nterror(req, status);
1420 tevent_req_post(req, state->ev);
1421 return;
1426 if (!state->replay_operation && state->durable_requested &&
1427 (fsp_lease_type(state->result) & SMB2_LEASE_HANDLE))
1429 status = SMB_VFS_DURABLE_COOKIE(
1430 state->result,
1431 state->op,
1432 &state->op->global->backend_cookie);
1433 if (!NT_STATUS_IS_OK(status)) {
1434 state->op->global->backend_cookie = data_blob_null;
1437 if (!state->replay_operation && state->op->global->backend_cookie.length > 0)
1439 state->update_open = true;
1441 state->op->global->durable = true;
1442 state->op->global->durable_timeout_msec = state->durable_timeout_msec;
1445 if (state->update_open) {
1446 state->op->global->create_guid = state->_create_guid;
1447 if (state->need_replay_cache) {
1448 state->op->flags |= SMBXSRV_OPEN_NEED_REPLAY_CACHE;
1451 status = smbXsrv_open_update(state->op);
1452 DEBUG(10, ("smb2_create_send: smbXsrv_open_update "
1453 "returned %s\n",
1454 nt_errstr(status)));
1455 if (!NT_STATUS_IS_OK(status)) {
1456 tevent_req_nterror(req, status);
1457 tevent_req_post(req, state->ev);
1458 return;
1462 * We should not purge the replay cache anymore
1463 * as it's attached to the smbXsrv_open record now.
1465 state->purge_create_guid = NULL;
1468 if (state->dhnq != NULL && state->op->global->durable) {
1469 uint8_t p[8] = { 0, };
1470 DATA_BLOB blob = data_blob_const(p, sizeof(p));
1472 status = smb2_create_blob_add(state->out_context_blobs,
1473 state->out_context_blobs,
1474 SMB2_CREATE_TAG_DHNQ,
1475 blob);
1476 if (!NT_STATUS_IS_OK(status)) {
1477 tevent_req_nterror(req, status);
1478 tevent_req_post(req, state->ev);
1479 return;
1483 if (state->dh2q != NULL && state->op->global->durable &&
1485 * For replay operations, we return the dh2q blob
1486 * in the case of oplocks not based on the state of
1487 * the open, but on whether it could have been granted
1488 * for the request data. In the case of leases instead,
1489 * the state of the open is used...
1491 (!state->replay_operation ||
1492 state->in_oplock_level == SMB2_OPLOCK_LEVEL_BATCH ||
1493 state->in_oplock_level == SMB2_OPLOCK_LEVEL_LEASE))
1495 uint8_t p[8] = { 0, };
1496 DATA_BLOB blob = data_blob_const(p, sizeof(p));
1497 uint32_t durable_v2_response_flags = 0;
1499 SIVAL(p, 0, state->op->global->durable_timeout_msec);
1500 SIVAL(p, 4, durable_v2_response_flags);
1502 status = smb2_create_blob_add(state->out_context_blobs,
1503 state->out_context_blobs,
1504 SMB2_CREATE_TAG_DH2Q,
1505 blob);
1506 if (!NT_STATUS_IS_OK(status)) {
1507 tevent_req_nterror(req, status);
1508 tevent_req_post(req, state->ev);
1509 return;
1513 if (state->qfid != NULL) {
1514 uint8_t p[32];
1515 SMB_STRUCT_STAT *base_sp = state->result->base_fsp ?
1516 &state->result->base_fsp->fsp_name->st :
1517 &state->result->fsp_name->st;
1518 uint64_t file_id = SMB_VFS_FS_FILE_ID(
1519 state->result->conn, base_sp);
1520 DATA_BLOB blob = data_blob_const(p, sizeof(p));
1522 ZERO_STRUCT(p);
1524 /* From conversations with Microsoft engineers at
1525 the MS plugfest. The first 8 bytes are the "volume index"
1526 == inode, the second 8 bytes are the "volume id",
1527 == dev. This will be updated in the SMB2 doc. */
1528 SBVAL(p, 0, file_id);
1529 SIVAL(p, 8, base_sp->st_ex_dev);/* FileIndexHigh */
1531 status = smb2_create_blob_add(state->out_context_blobs,
1532 state->out_context_blobs,
1533 SMB2_CREATE_TAG_QFID,
1534 blob);
1535 if (!NT_STATUS_IS_OK(status)) {
1536 tevent_req_nterror(req, status);
1537 tevent_req_post(req, state->ev);
1538 return;
1542 if ((state->rqls != NULL) && (state->result->oplock_type == LEASE_OPLOCK)) {
1543 uint8_t buf[52];
1544 struct smb2_lease lease;
1545 size_t lease_len;
1547 lease = state->result->lease->lease;
1549 lease_len = sizeof(buf);
1550 if (lease.lease_version == 1) {
1551 lease_len = 32;
1554 if (!smb2_lease_push(&lease, buf, lease_len)) {
1555 tevent_req_nterror(
1556 req, NT_STATUS_INTERNAL_ERROR);
1557 tevent_req_post(req, state->ev);
1558 return;
1561 status = smb2_create_blob_add(
1562 state, state->out_context_blobs,
1563 SMB2_CREATE_TAG_RQLS,
1564 data_blob_const(buf, lease_len));
1565 if (!NT_STATUS_IS_OK(status)) {
1566 tevent_req_nterror(req, status);
1567 tevent_req_post(req, state->ev);
1568 return;
1572 return;
1575 static void smbd_smb2_create_finish(struct tevent_req *req)
1577 struct smbd_smb2_create_state *state = tevent_req_data(
1578 req, struct smbd_smb2_create_state);
1579 struct smbd_smb2_request *smb2req = state->smb2req;
1580 struct smb_request *smb1req = state->smb1req;
1581 files_struct *result = state->result;
1583 smb2req->compat_chain_fsp = smb1req->chain_fsp;
1585 if (state->replay_operation) {
1586 state->out_oplock_level = state->in_oplock_level;
1587 } else if (lp_fake_oplocks(SNUM(smb2req->tcon->compat))) {
1588 state->out_oplock_level = state->in_oplock_level;
1589 } else {
1590 state->out_oplock_level = map_samba_oplock_levels_to_smb2(result->oplock_type);
1593 if ((state->in_create_disposition == FILE_SUPERSEDE)
1594 && (state->info == FILE_WAS_OVERWRITTEN)) {
1595 state->out_create_action = FILE_WAS_SUPERSEDED;
1596 } else {
1597 state->out_create_action = state->info;
1599 result->op->create_action = state->out_create_action;
1601 state->out_creation_ts = get_create_timespec(smb1req->conn,
1602 result, result->fsp_name);
1603 state->out_last_access_ts = result->fsp_name->st.st_ex_atime;
1604 state->out_last_write_ts = result->fsp_name->st.st_ex_mtime;
1605 state->out_change_ts = get_change_timespec(smb1req->conn,
1606 result, result->fsp_name);
1608 if (lp_dos_filetime_resolution(SNUM(smb2req->tcon->compat))) {
1609 dos_filetime_timespec(&state->out_creation_ts);
1610 dos_filetime_timespec(&state->out_last_access_ts);
1611 dos_filetime_timespec(&state->out_last_write_ts);
1612 dos_filetime_timespec(&state->out_change_ts);
1615 state->out_allocation_size =
1616 SMB_VFS_GET_ALLOC_SIZE(smb1req->conn, result,
1617 &(result->fsp_name->st));
1618 state->out_end_of_file = result->fsp_name->st.st_ex_size;
1619 if (state->out_file_attributes == 0) {
1620 state->out_file_attributes = FILE_ATTRIBUTE_NORMAL;
1622 state->out_file_id_persistent = result->op->global->open_persistent_id;
1623 state->out_file_id_volatile = result->op->global->open_volatile_id;
1625 DBG_DEBUG("%s - %s\n", fsp_str_dbg(result), fsp_fnum_dbg(result));
1627 tevent_req_done(req);
1628 tevent_req_post(req, state->ev);
1631 static NTSTATUS smbd_smb2_create_recv(struct tevent_req *req,
1632 TALLOC_CTX *mem_ctx,
1633 uint8_t *out_oplock_level,
1634 uint32_t *out_create_action,
1635 struct timespec *out_creation_ts,
1636 struct timespec *out_last_access_ts,
1637 struct timespec *out_last_write_ts,
1638 struct timespec *out_change_ts,
1639 uint64_t *out_allocation_size,
1640 uint64_t *out_end_of_file,
1641 uint32_t *out_file_attributes,
1642 uint64_t *out_file_id_persistent,
1643 uint64_t *out_file_id_volatile,
1644 struct smb2_create_blobs *out_context_blobs)
1646 NTSTATUS status;
1647 struct smbd_smb2_create_state *state = tevent_req_data(req,
1648 struct smbd_smb2_create_state);
1650 if (tevent_req_is_nterror(req, &status)) {
1651 tevent_req_received(req);
1652 return status;
1655 *out_oplock_level = state->out_oplock_level;
1656 *out_create_action = state->out_create_action;
1657 *out_creation_ts = state->out_creation_ts;
1658 *out_last_access_ts = state->out_last_access_ts;
1659 *out_last_write_ts = state->out_last_write_ts;
1660 *out_change_ts = state->out_change_ts;
1661 *out_allocation_size = state->out_allocation_size;
1662 *out_end_of_file = state->out_end_of_file;
1663 *out_file_attributes = state->out_file_attributes;
1664 *out_file_id_persistent = state->out_file_id_persistent;
1665 *out_file_id_volatile = state->out_file_id_volatile;
1666 *out_context_blobs = *(state->out_context_blobs);
1668 talloc_steal(mem_ctx, state->out_context_blobs->blobs);
1670 tevent_req_received(req);
1671 return NT_STATUS_OK;
1674 /*********************************************************
1675 Code for dealing with deferred opens.
1676 *********************************************************/
1678 bool get_deferred_open_message_state_smb2(struct smbd_smb2_request *smb2req,
1679 struct timeval *p_request_time,
1680 struct deferred_open_record **open_rec)
1682 struct smbd_smb2_create_state *state = NULL;
1683 struct tevent_req *req = NULL;
1685 if (!smb2req) {
1686 return false;
1688 req = smb2req->subreq;
1689 if (!req) {
1690 return false;
1692 state = tevent_req_data(req, struct smbd_smb2_create_state);
1693 if (!state) {
1694 return false;
1696 if (!state->open_was_deferred) {
1697 return false;
1699 if (p_request_time) {
1700 *p_request_time = state->request_time;
1702 if (open_rec != NULL) {
1703 *open_rec = state->open_rec;
1705 return true;
1708 /*********************************************************
1709 Re-process this call early - requested by message or
1710 close.
1711 *********************************************************/
1713 static struct smbd_smb2_request *find_open_smb2req(
1714 struct smbXsrv_connection *xconn, uint64_t mid)
1716 struct smbd_smb2_request *smb2req;
1718 for (smb2req = xconn->smb2.requests; smb2req; smb2req = smb2req->next) {
1719 uint64_t message_id;
1720 if (smb2req->subreq == NULL) {
1721 /* This message has been processed. */
1722 continue;
1724 if (!tevent_req_is_in_progress(smb2req->subreq)) {
1725 /* This message has been processed. */
1726 continue;
1728 message_id = get_mid_from_smb2req(smb2req);
1729 if (message_id == mid) {
1730 return smb2req;
1733 return NULL;
1736 bool open_was_deferred_smb2(struct smbXsrv_connection *xconn, uint64_t mid)
1738 struct smbd_smb2_create_state *state = NULL;
1739 struct smbd_smb2_request *smb2req;
1741 smb2req = find_open_smb2req(xconn, mid);
1743 if (!smb2req) {
1744 DEBUG(10,("open_was_deferred_smb2: mid %llu smb2req == NULL\n",
1745 (unsigned long long)mid));
1746 return false;
1748 if (!smb2req->subreq) {
1749 return false;
1751 if (!tevent_req_is_in_progress(smb2req->subreq)) {
1752 return false;
1754 state = tevent_req_data(smb2req->subreq,
1755 struct smbd_smb2_create_state);
1756 if (!state) {
1757 return false;
1759 /* It's not in progress if there's no timeout event. */
1760 if (!state->open_was_deferred) {
1761 return false;
1764 DEBUG(10,("open_was_deferred_smb2: mid = %llu\n",
1765 (unsigned long long)mid));
1767 return true;
1770 static void remove_deferred_open_message_smb2_internal(struct smbd_smb2_request *smb2req,
1771 uint64_t mid)
1773 struct smbd_smb2_create_state *state = NULL;
1775 if (!smb2req->subreq) {
1776 return;
1778 if (!tevent_req_is_in_progress(smb2req->subreq)) {
1779 return;
1781 state = tevent_req_data(smb2req->subreq,
1782 struct smbd_smb2_create_state);
1783 if (!state) {
1784 return;
1787 DEBUG(10,("remove_deferred_open_message_smb2_internal: "
1788 "mid %llu\n",
1789 (unsigned long long)mid ));
1791 state->open_was_deferred = false;
1792 /* Ensure we don't have any outstanding immediate event. */
1793 TALLOC_FREE(state->im);
1794 TALLOC_FREE(state->open_rec);
1797 void remove_deferred_open_message_smb2(
1798 struct smbXsrv_connection *xconn, uint64_t mid)
1800 struct smbd_smb2_request *smb2req;
1802 smb2req = find_open_smb2req(xconn, mid);
1804 if (!smb2req) {
1805 DEBUG(10,("remove_deferred_open_message_smb2: "
1806 "can't find mid %llu\n",
1807 (unsigned long long)mid ));
1808 return;
1810 remove_deferred_open_message_smb2_internal(smb2req, mid);
1813 static void smbd_smb2_create_request_dispatch_immediate(struct tevent_context *ctx,
1814 struct tevent_immediate *im,
1815 void *private_data)
1817 struct smbd_smb2_request *smb2req = talloc_get_type_abort(private_data,
1818 struct smbd_smb2_request);
1819 uint64_t mid = get_mid_from_smb2req(smb2req);
1820 NTSTATUS status;
1822 DEBUG(10,("smbd_smb2_create_request_dispatch_immediate: "
1823 "re-dispatching mid %llu\n",
1824 (unsigned long long)mid ));
1826 status = smbd_smb2_request_dispatch(smb2req);
1827 if (!NT_STATUS_IS_OK(status)) {
1828 smbd_server_connection_terminate(smb2req->xconn,
1829 nt_errstr(status));
1830 return;
1834 bool schedule_deferred_open_message_smb2(
1835 struct smbXsrv_connection *xconn, uint64_t mid)
1837 struct smbd_smb2_create_state *state = NULL;
1838 struct smbd_smb2_request *smb2req;
1840 smb2req = find_open_smb2req(xconn, mid);
1842 if (!smb2req) {
1843 DEBUG(10,("schedule_deferred_open_message_smb2: "
1844 "can't find mid %llu\n",
1845 (unsigned long long)mid ));
1846 return false;
1848 if (!smb2req->subreq) {
1849 return false;
1851 if (!tevent_req_is_in_progress(smb2req->subreq)) {
1852 return false;
1854 state = tevent_req_data(smb2req->subreq,
1855 struct smbd_smb2_create_state);
1856 if (!state) {
1857 return false;
1860 /* Ensure we don't have any outstanding immediate event. */
1861 TALLOC_FREE(state->im);
1864 * This is subtle. We must null out the callback
1865 * before rescheduling, else the first call to
1866 * tevent_req_nterror() causes the _receive()
1867 * function to be called, this causing tevent_req_post()
1868 * to crash.
1870 tevent_req_set_callback(smb2req->subreq, NULL, NULL);
1872 state->im = tevent_create_immediate(smb2req);
1873 if (!state->im) {
1874 smbd_server_connection_terminate(smb2req->xconn,
1875 nt_errstr(NT_STATUS_NO_MEMORY));
1876 return false;
1879 DEBUG(10,("schedule_deferred_open_message_smb2: "
1880 "re-processing mid %llu\n",
1881 (unsigned long long)mid ));
1883 tevent_schedule_immediate(state->im,
1884 smb2req->sconn->ev_ctx,
1885 smbd_smb2_create_request_dispatch_immediate,
1886 smb2req);
1888 return true;
1891 static bool smbd_smb2_create_cancel(struct tevent_req *req)
1893 struct smbd_smb2_request *smb2req = NULL;
1894 struct smbd_smb2_create_state *state = tevent_req_data(req,
1895 struct smbd_smb2_create_state);
1896 uint64_t mid;
1898 if (!state) {
1899 return false;
1902 if (!state->smb2req) {
1903 return false;
1906 smb2req = state->smb2req;
1907 mid = get_mid_from_smb2req(smb2req);
1909 if (is_deferred_open_async(state->open_rec)) {
1910 /* Can't cancel an async create. */
1911 return false;
1914 remove_deferred_open_message_smb2_internal(smb2req, mid);
1916 tevent_req_defer_callback(req, smb2req->sconn->ev_ctx);
1917 tevent_req_nterror(req, NT_STATUS_CANCELLED);
1918 return true;
1921 bool push_deferred_open_message_smb2(struct smbd_smb2_request *smb2req,
1922 struct timeval request_time,
1923 struct timeval timeout,
1924 struct file_id id,
1925 struct deferred_open_record *open_rec)
1927 struct tevent_req *req = NULL;
1928 struct smbd_smb2_create_state *state = NULL;
1929 struct timeval end_time;
1931 if (!smb2req) {
1932 return false;
1934 req = smb2req->subreq;
1935 if (!req) {
1936 return false;
1938 state = tevent_req_data(req, struct smbd_smb2_create_state);
1939 if (!state) {
1940 return false;
1942 state->id = id;
1943 state->request_time = request_time;
1944 state->open_rec = talloc_move(state, &open_rec);
1946 /* Re-schedule us to retry on timer expiry. */
1947 end_time = timeval_sum(&request_time, &timeout);
1949 DEBUG(10,("push_deferred_open_message_smb2: "
1950 "timeout at %s\n",
1951 timeval_string(talloc_tos(),
1952 &end_time,
1953 true) ));
1955 state->open_was_deferred = true;
1957 /* allow this request to be canceled */
1958 tevent_req_set_cancel_fn(req, smbd_smb2_create_cancel);
1960 return true;