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