2 Unix SMB/CIFS implementation.
3 file opening and share modes
4 Copyright (C) Andrew Tridgell 1992-1998
5 Copyright (C) Jeremy Allison 2001-2004
6 Copyright (C) Volker Lendecke 2005
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/globals.h"
25 #include "fake_file.h"
26 #include "librpc/gen_ndr/messaging.h"
27 #include "../libcli/security/security.h"
28 #include "../librpc/gen_ndr/ndr_security.h"
30 extern const struct generic_mapping file_generic_mapping
;
32 struct deferred_open_record
{
33 bool delayed_for_oplocks
;
37 /****************************************************************************
38 SMB1 file varient of se_access_check. Never test FILE_READ_ATTRIBUTES.
39 ****************************************************************************/
41 NTSTATUS
smb1_file_se_access_check(struct connection_struct
*conn
,
42 const struct security_descriptor
*sd
,
43 const struct security_token
*token
,
44 uint32_t access_desired
,
45 uint32_t *access_granted
)
49 if (get_current_uid(conn
) == (uid_t
)0) {
50 /* I'm sorry sir, I didn't know you were root... */
51 *access_granted
= access_desired
;
52 if (access_desired
& SEC_FLAG_MAXIMUM_ALLOWED
) {
53 *access_granted
|= FILE_GENERIC_ALL
;
58 return se_access_check(sd
,
60 (access_desired
& ~FILE_READ_ATTRIBUTES
),
64 /****************************************************************************
65 Check if we have open rights.
66 ****************************************************************************/
68 NTSTATUS
smbd_check_open_rights(struct connection_struct
*conn
,
69 const struct smb_filename
*smb_fname
,
71 uint32_t *access_granted
)
73 /* Check if we have rights to open. */
75 struct security_descriptor
*sd
= NULL
;
77 status
= SMB_VFS_GET_NT_ACL(conn
, smb_fname
->base_name
,
82 if (!NT_STATUS_IS_OK(status
)) {
83 DEBUG(10, ("smbd_check_open_rights: Could not get acl "
85 smb_fname_str_dbg(smb_fname
),
90 status
= smb1_file_se_access_check(conn
,
92 get_current_nttok(conn
),
96 DEBUG(10,("smbd_check_open_rights: file %s requesting "
97 "0x%x returning 0x%x (%s)\n",
98 smb_fname_str_dbg(smb_fname
),
99 (unsigned int)access_mask
,
100 (unsigned int)*access_granted
,
101 nt_errstr(status
) ));
103 if (!NT_STATUS_IS_OK(status
)) {
104 if (DEBUGLEVEL
>= 10) {
105 DEBUG(10,("smbd_check_open_rights: acl for %s is:\n",
106 smb_fname_str_dbg(smb_fname
) ));
107 NDR_PRINT_DEBUG(security_descriptor
, sd
);
116 /****************************************************************************
117 fd support routines - attempt to do a dos_open.
118 ****************************************************************************/
120 static NTSTATUS
fd_open(struct connection_struct
*conn
,
125 struct smb_filename
*smb_fname
= fsp
->fsp_name
;
126 NTSTATUS status
= NT_STATUS_OK
;
130 * Never follow symlinks on a POSIX client. The
131 * client should be doing this.
134 if (fsp
->posix_open
|| !lp_symlinks(SNUM(conn
))) {
139 fsp
->fh
->fd
= SMB_VFS_OPEN(conn
, smb_fname
, fsp
, flags
, mode
);
140 if (fsp
->fh
->fd
== -1) {
141 status
= map_nt_error_from_unix(errno
);
142 if (errno
== EMFILE
) {
143 static time_t last_warned
= 0L;
145 if (time((time_t *) NULL
) > last_warned
) {
146 DEBUG(0,("Too many open files, unable "
147 "to open more! smbd's max "
149 lp_max_open_files()));
150 last_warned
= time((time_t *) NULL
);
156 DEBUG(10,("fd_open: name %s, flags = 0%o mode = 0%o, fd = %d. %s\n",
157 smb_fname_str_dbg(smb_fname
), flags
, (int)mode
, fsp
->fh
->fd
,
158 (fsp
->fh
->fd
== -1) ? strerror(errno
) : "" ));
163 /****************************************************************************
164 Close the file associated with a fsp.
165 ****************************************************************************/
167 NTSTATUS
fd_close(files_struct
*fsp
)
171 if (fsp
->fh
->fd
== -1) {
172 return NT_STATUS_OK
; /* What we used to call a stat open. */
174 if (fsp
->fh
->ref_count
> 1) {
175 return NT_STATUS_OK
; /* Shared handle. Only close last reference. */
178 ret
= SMB_VFS_CLOSE(fsp
);
181 return map_nt_error_from_unix(errno
);
186 /****************************************************************************
187 Change the ownership of a file to that of the parent directory.
188 Do this by fd if possible.
189 ****************************************************************************/
191 void change_file_owner_to_parent(connection_struct
*conn
,
192 const char *inherit_from_dir
,
195 struct smb_filename
*smb_fname_parent
= NULL
;
199 status
= create_synthetic_smb_fname(talloc_tos(), inherit_from_dir
,
200 NULL
, NULL
, &smb_fname_parent
);
201 if (!NT_STATUS_IS_OK(status
)) {
205 ret
= SMB_VFS_STAT(conn
, smb_fname_parent
);
207 DEBUG(0,("change_file_owner_to_parent: failed to stat parent "
208 "directory %s. Error was %s\n",
209 smb_fname_str_dbg(smb_fname_parent
),
215 ret
= SMB_VFS_FCHOWN(fsp
, smb_fname_parent
->st
.st_ex_uid
, (gid_t
)-1);
218 DEBUG(0,("change_file_owner_to_parent: failed to fchown "
219 "file %s to parent directory uid %u. Error "
220 "was %s\n", fsp_str_dbg(fsp
),
221 (unsigned int)smb_fname_parent
->st
.st_ex_uid
,
225 DEBUG(10,("change_file_owner_to_parent: changed new file %s to "
226 "parent directory uid %u.\n", fsp_str_dbg(fsp
),
227 (unsigned int)smb_fname_parent
->st
.st_ex_uid
));
229 TALLOC_FREE(smb_fname_parent
);
232 NTSTATUS
change_dir_owner_to_parent(connection_struct
*conn
,
233 const char *inherit_from_dir
,
235 SMB_STRUCT_STAT
*psbuf
)
237 struct smb_filename
*smb_fname_parent
= NULL
;
238 struct smb_filename
*smb_fname_cwd
= NULL
;
239 char *saved_dir
= NULL
;
240 TALLOC_CTX
*ctx
= talloc_tos();
241 NTSTATUS status
= NT_STATUS_OK
;
244 status
= create_synthetic_smb_fname(ctx
, inherit_from_dir
, NULL
, NULL
,
246 if (!NT_STATUS_IS_OK(status
)) {
250 ret
= SMB_VFS_STAT(conn
, smb_fname_parent
);
252 status
= map_nt_error_from_unix(errno
);
253 DEBUG(0,("change_dir_owner_to_parent: failed to stat parent "
254 "directory %s. Error was %s\n",
255 smb_fname_str_dbg(smb_fname_parent
),
260 /* We've already done an lstat into psbuf, and we know it's a
261 directory. If we can cd into the directory and the dev/ino
262 are the same then we can safely chown without races as
263 we're locking the directory in place by being in it. This
264 should work on any UNIX (thanks tridge :-). JRA.
267 saved_dir
= vfs_GetWd(ctx
,conn
);
269 status
= map_nt_error_from_unix(errno
);
270 DEBUG(0,("change_dir_owner_to_parent: failed to get "
271 "current working directory. Error was %s\n",
276 /* Chdir into the new path. */
277 if (vfs_ChDir(conn
, fname
) == -1) {
278 status
= map_nt_error_from_unix(errno
);
279 DEBUG(0,("change_dir_owner_to_parent: failed to change "
280 "current working directory to %s. Error "
281 "was %s\n", fname
, strerror(errno
) ));
285 status
= create_synthetic_smb_fname(ctx
, ".", NULL
, NULL
,
287 if (!NT_STATUS_IS_OK(status
)) {
291 ret
= SMB_VFS_STAT(conn
, smb_fname_cwd
);
293 status
= map_nt_error_from_unix(errno
);
294 DEBUG(0,("change_dir_owner_to_parent: failed to stat "
295 "directory '.' (%s) Error was %s\n",
296 fname
, strerror(errno
)));
300 /* Ensure we're pointing at the same place. */
301 if (smb_fname_cwd
->st
.st_ex_dev
!= psbuf
->st_ex_dev
||
302 smb_fname_cwd
->st
.st_ex_ino
!= psbuf
->st_ex_ino
||
303 smb_fname_cwd
->st
.st_ex_mode
!= psbuf
->st_ex_mode
) {
304 DEBUG(0,("change_dir_owner_to_parent: "
305 "device/inode/mode on directory %s changed. "
306 "Refusing to chown !\n", fname
));
307 status
= NT_STATUS_ACCESS_DENIED
;
312 ret
= SMB_VFS_CHOWN(conn
, ".", smb_fname_parent
->st
.st_ex_uid
,
316 status
= map_nt_error_from_unix(errno
);
317 DEBUG(10,("change_dir_owner_to_parent: failed to chown "
318 "directory %s to parent directory uid %u. "
319 "Error was %s\n", fname
,
320 (unsigned int)smb_fname_parent
->st
.st_ex_uid
,
325 DEBUG(10,("change_dir_owner_to_parent: changed ownership of new "
326 "directory %s to parent directory uid %u.\n",
327 fname
, (unsigned int)smb_fname_parent
->st
.st_ex_uid
));
330 vfs_ChDir(conn
,saved_dir
);
332 TALLOC_FREE(smb_fname_parent
);
333 TALLOC_FREE(smb_fname_cwd
);
337 /****************************************************************************
339 ****************************************************************************/
341 static NTSTATUS
open_file(files_struct
*fsp
,
342 connection_struct
*conn
,
343 struct smb_request
*req
,
344 const char *parent_dir
,
347 uint32 access_mask
, /* client requested access mask. */
348 uint32 open_access_mask
) /* what we're actually using in the open. */
350 struct smb_filename
*smb_fname
= fsp
->fsp_name
;
351 NTSTATUS status
= NT_STATUS_OK
;
352 int accmode
= (flags
& O_ACCMODE
);
353 int local_flags
= flags
;
354 bool file_existed
= VALID_STAT(fsp
->fsp_name
->st
);
359 /* Check permissions */
362 * This code was changed after seeing a client open request
363 * containing the open mode of (DENY_WRITE/read-only) with
364 * the 'create if not exist' bit set. The previous code
365 * would fail to open the file read only on a read-only share
366 * as it was checking the flags parameter directly against O_RDONLY,
367 * this was failing as the flags parameter was set to O_RDONLY|O_CREAT.
371 if (!CAN_WRITE(conn
)) {
372 /* It's a read-only share - fail if we wanted to write. */
373 if(accmode
!= O_RDONLY
|| (flags
& O_TRUNC
) || (flags
& O_APPEND
)) {
374 DEBUG(3,("Permission denied opening %s\n",
375 smb_fname_str_dbg(smb_fname
)));
376 return NT_STATUS_ACCESS_DENIED
;
377 } else if(flags
& O_CREAT
) {
378 /* We don't want to write - but we must make sure that
379 O_CREAT doesn't create the file if we have write
380 access into the directory.
382 flags
&= ~(O_CREAT
|O_EXCL
);
383 local_flags
&= ~(O_CREAT
|O_EXCL
);
388 * This little piece of insanity is inspired by the
389 * fact that an NT client can open a file for O_RDONLY,
390 * but set the create disposition to FILE_EXISTS_TRUNCATE.
391 * If the client *can* write to the file, then it expects to
392 * truncate the file, even though it is opening for readonly.
393 * Quicken uses this stupid trick in backup file creation...
394 * Thanks *greatly* to "David W. Chapman Jr." <dwcjr@inethouston.net>
395 * for helping track this one down. It didn't bite us in 2.0.x
396 * as we always opened files read-write in that release. JRA.
399 if ((accmode
== O_RDONLY
) && ((flags
& O_TRUNC
) == O_TRUNC
)) {
400 DEBUG(10,("open_file: truncate requested on read-only open "
401 "for file %s\n", smb_fname_str_dbg(smb_fname
)));
402 local_flags
= (flags
& ~O_ACCMODE
)|O_RDWR
;
405 if ((open_access_mask
& (FILE_READ_DATA
|FILE_WRITE_DATA
|FILE_APPEND_DATA
|FILE_EXECUTE
)) ||
406 (!file_existed
&& (local_flags
& O_CREAT
)) ||
407 ((local_flags
& O_TRUNC
) == O_TRUNC
) ) {
411 * We can't actually truncate here as the file may be locked.
412 * open_file_ntcreate will take care of the truncate later. JRA.
415 local_flags
&= ~O_TRUNC
;
417 #if defined(O_NONBLOCK) && defined(S_ISFIFO)
419 * We would block on opening a FIFO with no one else on the
420 * other end. Do what we used to do and add O_NONBLOCK to the
424 if (file_existed
&& S_ISFIFO(smb_fname
->st
.st_ex_mode
)) {
425 local_flags
|= O_NONBLOCK
;
429 /* Don't create files with Microsoft wildcard characters. */
432 * wildcard characters are allowed in stream names
433 * only test the basefilename
435 wild
= fsp
->base_fsp
->fsp_name
->base_name
;
437 wild
= smb_fname
->base_name
;
439 if ((local_flags
& O_CREAT
) && !file_existed
&&
441 return NT_STATUS_OBJECT_NAME_INVALID
;
444 /* Actually do the open */
445 status
= fd_open(conn
, fsp
, local_flags
, unx_mode
);
446 if (!NT_STATUS_IS_OK(status
)) {
447 DEBUG(3,("Error opening file %s (%s) (local_flags=%d) "
448 "(flags=%d)\n", smb_fname_str_dbg(smb_fname
),
449 nt_errstr(status
),local_flags
,flags
));
453 if ((local_flags
& O_CREAT
) && !file_existed
) {
455 /* Inherit the ACL if required */
456 if (lp_inherit_perms(SNUM(conn
))) {
457 inherit_access_posix_acl(conn
, parent_dir
,
458 smb_fname
->base_name
,
462 /* Change the owner if required. */
463 if (lp_inherit_owner(SNUM(conn
))) {
464 change_file_owner_to_parent(conn
, parent_dir
,
468 notify_fname(conn
, NOTIFY_ACTION_ADDED
,
469 FILE_NOTIFY_CHANGE_FILE_NAME
,
470 smb_fname
->base_name
);
474 fsp
->fh
->fd
= -1; /* What we used to call a stat open. */
476 uint32_t access_granted
= 0;
478 status
= smbd_check_open_rights(conn
,
482 if (!NT_STATUS_IS_OK(status
)) {
483 if (NT_STATUS_EQUAL(status
, NT_STATUS_ACCESS_DENIED
)) {
485 * On NT_STATUS_ACCESS_DENIED, access_granted
486 * contains the denied bits.
489 if ((access_mask
& FILE_WRITE_ATTRIBUTES
) &&
490 (access_granted
& FILE_WRITE_ATTRIBUTES
) &&
491 (lp_map_readonly(SNUM(conn
)) ||
492 lp_map_archive(SNUM(conn
)) ||
493 lp_map_hidden(SNUM(conn
)) ||
494 lp_map_system(SNUM(conn
)))) {
495 access_granted
&= ~FILE_WRITE_ATTRIBUTES
;
497 DEBUG(10,("open_file: "
506 if ((access_mask
& DELETE_ACCESS
) &&
507 (access_granted
& DELETE_ACCESS
) &&
508 can_delete_file_in_directory(conn
,
510 /* Were we trying to do a stat open
511 * for delete and didn't get DELETE
512 * access (only) ? Check if the
513 * directory allows DELETE_CHILD.
515 * http://blogs.msdn.com/oldnewthing/archive/2004/06/04/148426.aspx
518 access_granted
&= ~DELETE_ACCESS
;
520 DEBUG(10,("open_file: "
528 if (access_granted
!= 0) {
529 DEBUG(10,("open_file: Access "
536 } else if (NT_STATUS_EQUAL(status
, NT_STATUS_OBJECT_NAME_NOT_FOUND
) &&
538 S_ISLNK(smb_fname
->st
.st_ex_mode
)) {
539 /* This is a POSIX stat open for delete
540 * or rename on a symlink that points
542 DEBUG(10,("open_file: allowing POSIX "
543 "open on bad symlink %s\n",
547 DEBUG(10,("open_file: "
548 "smbd_check_open_rights on file "
550 smb_fname_str_dbg(smb_fname
),
551 nt_errstr(status
) ));
561 if (fsp
->fh
->fd
== -1) {
562 ret
= SMB_VFS_STAT(conn
, smb_fname
);
564 ret
= SMB_VFS_FSTAT(fsp
, &smb_fname
->st
);
565 /* If we have an fd, this stat should succeed. */
567 DEBUG(0,("Error doing fstat on open file %s "
569 smb_fname_str_dbg(smb_fname
),
574 /* For a non-io open, this stat failing means file not found. JRA */
576 status
= map_nt_error_from_unix(errno
);
583 * POSIX allows read-only opens of directories. We don't
584 * want to do this (we use a different code path for this)
585 * so catch a directory open and return an EISDIR. JRA.
588 if(S_ISDIR(smb_fname
->st
.st_ex_mode
)) {
591 return NT_STATUS_FILE_IS_A_DIRECTORY
;
594 fsp
->mode
= smb_fname
->st
.st_ex_mode
;
595 fsp
->file_id
= vfs_file_id_from_sbuf(conn
, &smb_fname
->st
);
596 fsp
->vuid
= req
? req
->vuid
: UID_FIELD_INVALID
;
597 fsp
->file_pid
= req
? req
->smbpid
: 0;
598 fsp
->can_lock
= True
;
599 fsp
->can_read
= (access_mask
& (FILE_READ_DATA
)) ? True
: False
;
600 if (!CAN_WRITE(conn
)) {
601 fsp
->can_write
= False
;
603 fsp
->can_write
= (access_mask
& (FILE_WRITE_DATA
| FILE_APPEND_DATA
)) ?
606 fsp
->print_file
= NULL
;
607 fsp
->modified
= False
;
608 fsp
->sent_oplock_break
= NO_BREAK_SENT
;
609 fsp
->is_directory
= False
;
610 if (conn
->aio_write_behind_list
&&
611 is_in_path(smb_fname
->base_name
, conn
->aio_write_behind_list
,
612 conn
->case_sensitive
)) {
613 fsp
->aio_write_behind
= True
;
616 fsp
->wcp
= NULL
; /* Write cache pointer. */
618 DEBUG(2,("%s opened file %s read=%s write=%s (numopen=%d)\n",
619 conn
->server_info
->unix_name
,
620 smb_fname_str_dbg(smb_fname
),
621 BOOLSTR(fsp
->can_read
), BOOLSTR(fsp
->can_write
),
622 conn
->num_files_open
));
628 /*******************************************************************
629 Return True if the filename is one of the special executable types.
630 ********************************************************************/
632 bool is_executable(const char *fname
)
634 if ((fname
= strrchr_m(fname
,'.'))) {
635 if (strequal(fname
,".com") ||
636 strequal(fname
,".dll") ||
637 strequal(fname
,".exe") ||
638 strequal(fname
,".sym")) {
645 /****************************************************************************
646 Check if we can open a file with a share mode.
647 Returns True if conflict, False if not.
648 ****************************************************************************/
650 static bool share_conflict(struct share_mode_entry
*entry
,
654 DEBUG(10,("share_conflict: entry->access_mask = 0x%x, "
655 "entry->share_access = 0x%x, "
656 "entry->private_options = 0x%x\n",
657 (unsigned int)entry
->access_mask
,
658 (unsigned int)entry
->share_access
,
659 (unsigned int)entry
->private_options
));
661 DEBUG(10,("share_conflict: access_mask = 0x%x, share_access = 0x%x\n",
662 (unsigned int)access_mask
, (unsigned int)share_access
));
664 if ((entry
->access_mask
& (FILE_WRITE_DATA
|
668 DELETE_ACCESS
)) == 0) {
669 DEBUG(10,("share_conflict: No conflict due to "
670 "entry->access_mask = 0x%x\n",
671 (unsigned int)entry
->access_mask
));
675 if ((access_mask
& (FILE_WRITE_DATA
|
679 DELETE_ACCESS
)) == 0) {
680 DEBUG(10,("share_conflict: No conflict due to "
681 "access_mask = 0x%x\n",
682 (unsigned int)access_mask
));
686 #if 1 /* JRA TEST - Superdebug. */
687 #define CHECK_MASK(num, am, right, sa, share) \
688 DEBUG(10,("share_conflict: [%d] am (0x%x) & right (0x%x) = 0x%x\n", \
689 (unsigned int)(num), (unsigned int)(am), \
690 (unsigned int)(right), (unsigned int)(am)&(right) )); \
691 DEBUG(10,("share_conflict: [%d] sa (0x%x) & share (0x%x) = 0x%x\n", \
692 (unsigned int)(num), (unsigned int)(sa), \
693 (unsigned int)(share), (unsigned int)(sa)&(share) )); \
694 if (((am) & (right)) && !((sa) & (share))) { \
695 DEBUG(10,("share_conflict: check %d conflict am = 0x%x, right = 0x%x, \
696 sa = 0x%x, share = 0x%x\n", (num), (unsigned int)(am), (unsigned int)(right), (unsigned int)(sa), \
697 (unsigned int)(share) )); \
701 #define CHECK_MASK(num, am, right, sa, share) \
702 if (((am) & (right)) && !((sa) & (share))) { \
703 DEBUG(10,("share_conflict: check %d conflict am = 0x%x, right = 0x%x, \
704 sa = 0x%x, share = 0x%x\n", (num), (unsigned int)(am), (unsigned int)(right), (unsigned int)(sa), \
705 (unsigned int)(share) )); \
710 CHECK_MASK(1, entry
->access_mask
, FILE_WRITE_DATA
| FILE_APPEND_DATA
,
711 share_access
, FILE_SHARE_WRITE
);
712 CHECK_MASK(2, access_mask
, FILE_WRITE_DATA
| FILE_APPEND_DATA
,
713 entry
->share_access
, FILE_SHARE_WRITE
);
715 CHECK_MASK(3, entry
->access_mask
, FILE_READ_DATA
| FILE_EXECUTE
,
716 share_access
, FILE_SHARE_READ
);
717 CHECK_MASK(4, access_mask
, FILE_READ_DATA
| FILE_EXECUTE
,
718 entry
->share_access
, FILE_SHARE_READ
);
720 CHECK_MASK(5, entry
->access_mask
, DELETE_ACCESS
,
721 share_access
, FILE_SHARE_DELETE
);
722 CHECK_MASK(6, access_mask
, DELETE_ACCESS
,
723 entry
->share_access
, FILE_SHARE_DELETE
);
725 DEBUG(10,("share_conflict: No conflict.\n"));
729 #if defined(DEVELOPER)
730 static void validate_my_share_entries(struct smbd_server_connection
*sconn
,
732 struct share_mode_entry
*share_entry
)
736 if (!procid_is_me(&share_entry
->pid
)) {
740 if (is_deferred_open_entry(share_entry
) &&
741 !open_was_deferred(share_entry
->op_mid
)) {
742 char *str
= talloc_asprintf(talloc_tos(),
743 "Got a deferred entry without a request: "
745 share_mode_str(talloc_tos(), num
, share_entry
));
749 if (!is_valid_share_mode_entry(share_entry
)) {
753 fsp
= file_find_dif(sconn
, share_entry
->id
,
754 share_entry
->share_file_id
);
756 DEBUG(0,("validate_my_share_entries: PANIC : %s\n",
757 share_mode_str(talloc_tos(), num
, share_entry
) ));
758 smb_panic("validate_my_share_entries: Cannot match a "
759 "share entry with an open file\n");
762 if (is_deferred_open_entry(share_entry
) ||
763 is_unused_share_mode_entry(share_entry
)) {
767 if ((share_entry
->op_type
== NO_OPLOCK
) &&
768 (fsp
->oplock_type
== FAKE_LEVEL_II_OPLOCK
)) {
769 /* Someone has already written to it, but I haven't yet
774 if (((uint16
)fsp
->oplock_type
) != share_entry
->op_type
) {
783 DEBUG(0,("validate_my_share_entries: PANIC : %s\n",
784 share_mode_str(talloc_tos(), num
, share_entry
) ));
785 str
= talloc_asprintf(talloc_tos(),
786 "validate_my_share_entries: "
787 "file %s, oplock_type = 0x%x, op_type = 0x%x\n",
788 fsp
->fsp_name
->base_name
,
789 (unsigned int)fsp
->oplock_type
,
790 (unsigned int)share_entry
->op_type
);
796 bool is_stat_open(uint32 access_mask
)
798 return (access_mask
&&
799 ((access_mask
& ~(SYNCHRONIZE_ACCESS
| FILE_READ_ATTRIBUTES
|
800 FILE_WRITE_ATTRIBUTES
))==0) &&
801 ((access_mask
& (SYNCHRONIZE_ACCESS
|FILE_READ_ATTRIBUTES
|
802 FILE_WRITE_ATTRIBUTES
)) != 0));
805 /****************************************************************************
806 Deal with share modes
807 Invarient: Share mode must be locked on entry and exit.
808 Returns -1 on error, or number of share modes on success (may be zero).
809 ****************************************************************************/
811 static NTSTATUS
open_mode_check(connection_struct
*conn
,
812 struct share_mode_lock
*lck
,
815 uint32 create_options
,
820 if(lck
->num_share_modes
== 0) {
824 *file_existed
= True
;
826 /* A delete on close prohibits everything */
828 if (lck
->delete_on_close
) {
829 return NT_STATUS_DELETE_PENDING
;
832 if (is_stat_open(access_mask
)) {
833 /* Stat open that doesn't trigger oplock breaks or share mode
834 * checks... ! JRA. */
839 * Check if the share modes will give us access.
842 #if defined(DEVELOPER)
843 for(i
= 0; i
< lck
->num_share_modes
; i
++) {
844 validate_my_share_entries(conn
->sconn
, i
,
845 &lck
->share_modes
[i
]);
849 if (!lp_share_modes(SNUM(conn
))) {
853 /* Now we check the share modes, after any oplock breaks. */
854 for(i
= 0; i
< lck
->num_share_modes
; i
++) {
856 if (!is_valid_share_mode_entry(&lck
->share_modes
[i
])) {
860 /* someone else has a share lock on it, check to see if we can
862 if (share_conflict(&lck
->share_modes
[i
],
863 access_mask
, share_access
)) {
864 return NT_STATUS_SHARING_VIOLATION
;
871 static bool is_delete_request(files_struct
*fsp
) {
872 return ((fsp
->access_mask
== DELETE_ACCESS
) &&
873 (fsp
->oplock_type
== NO_OPLOCK
));
877 * Send a break message to the oplock holder and delay the open for
881 static NTSTATUS
send_break_message(files_struct
*fsp
,
882 struct share_mode_entry
*exclusive
,
887 char msg
[MSG_SMB_SHARE_MODE_ENTRY_SIZE
];
889 DEBUG(10, ("Sending break request to PID %s\n",
890 procid_str_static(&exclusive
->pid
)));
891 exclusive
->op_mid
= mid
;
893 /* Create the message. */
894 share_mode_entry_to_message(msg
, exclusive
);
896 /* Add in the FORCE_OPLOCK_BREAK_TO_NONE bit in the message if set. We
897 don't want this set in the share mode struct pointed to by lck. */
899 if (oplock_request
& FORCE_OPLOCK_BREAK_TO_NONE
) {
900 SSVAL(msg
,OP_BREAK_MSG_OP_TYPE_OFFSET
,
901 exclusive
->op_type
| FORCE_OPLOCK_BREAK_TO_NONE
);
904 status
= messaging_send_buf(fsp
->conn
->sconn
->msg_ctx
, exclusive
->pid
,
905 MSG_SMB_BREAK_REQUEST
,
907 MSG_SMB_SHARE_MODE_ENTRY_SIZE
);
908 if (!NT_STATUS_IS_OK(status
)) {
909 DEBUG(3, ("Could not send oplock break message: %s\n",
917 * 1) No files open at all or internal open: Grant whatever the client wants.
919 * 2) Exclusive (or batch) oplock around: If the requested access is a delete
920 * request, break if the oplock around is a batch oplock. If it's another
921 * requested access type, break.
923 * 3) Only level2 around: Grant level2 and do nothing else.
926 static bool delay_for_oplocks(struct share_mode_lock
*lck
,
933 struct share_mode_entry
*exclusive
= NULL
;
934 bool valid_entry
= false;
935 bool have_level2
= false;
936 bool have_a_none_oplock
= false;
937 bool allow_level2
= (global_client_caps
& CAP_LEVEL_II_OPLOCKS
) &&
938 lp_level2_oplocks(SNUM(fsp
->conn
));
940 if (oplock_request
& INTERNAL_OPEN_ONLY
) {
941 fsp
->oplock_type
= NO_OPLOCK
;
944 if ((oplock_request
& INTERNAL_OPEN_ONLY
) || is_stat_open(fsp
->access_mask
)) {
948 for (i
=0; i
<lck
->num_share_modes
; i
++) {
950 if (!is_valid_share_mode_entry(&lck
->share_modes
[i
])) {
954 /* At least one entry is not an invalid or deferred entry. */
957 if (pass_number
== 1) {
958 if (BATCH_OPLOCK_TYPE(lck
->share_modes
[i
].op_type
)) {
959 SMB_ASSERT(exclusive
== NULL
);
960 exclusive
= &lck
->share_modes
[i
];
963 if (EXCLUSIVE_OPLOCK_TYPE(lck
->share_modes
[i
].op_type
)) {
964 SMB_ASSERT(exclusive
== NULL
);
965 exclusive
= &lck
->share_modes
[i
];
969 if (LEVEL_II_OPLOCK_TYPE(lck
->share_modes
[i
].op_type
)) {
970 SMB_ASSERT(exclusive
== NULL
);
974 if (lck
->share_modes
[i
].op_type
== NO_OPLOCK
) {
975 have_a_none_oplock
= true;
979 if (exclusive
!= NULL
) { /* Found an exclusive oplock */
980 bool delay_it
= is_delete_request(fsp
) ?
981 BATCH_OPLOCK_TYPE(exclusive
->op_type
) : true;
982 SMB_ASSERT(!have_level2
);
984 send_break_message(fsp
, exclusive
, mid
, oplock_request
);
990 * Match what was requested (fsp->oplock_type) with
991 * what was found in the existing share modes.
995 /* All entries are placeholders or deferred.
996 * Directly grant whatever the client wants. */
997 if (fsp
->oplock_type
== NO_OPLOCK
) {
998 /* Store a level2 oplock, but don't tell the client */
999 fsp
->oplock_type
= FAKE_LEVEL_II_OPLOCK
;
1001 } else if (have_a_none_oplock
) {
1002 fsp
->oplock_type
= NO_OPLOCK
;
1003 } else if (have_level2
) {
1004 if (fsp
->oplock_type
== NO_OPLOCK
||
1005 fsp
->oplock_type
== FAKE_LEVEL_II_OPLOCK
) {
1006 /* Store a level2 oplock, but don't tell the client */
1007 fsp
->oplock_type
= FAKE_LEVEL_II_OPLOCK
;
1009 fsp
->oplock_type
= LEVEL_II_OPLOCK
;
1012 /* This case can never happen. */
1017 * Don't grant level2 to clients that don't want them
1018 * or if we've turned them off.
1020 if (fsp
->oplock_type
== LEVEL_II_OPLOCK
&& !allow_level2
) {
1021 fsp
->oplock_type
= FAKE_LEVEL_II_OPLOCK
;
1024 DEBUG(10,("delay_for_oplocks: oplock type 0x%x on file %s\n",
1025 fsp
->oplock_type
, fsp_str_dbg(fsp
)));
1031 bool request_timed_out(struct timeval request_time
,
1032 struct timeval timeout
)
1034 struct timeval now
, end_time
;
1036 end_time
= timeval_sum(&request_time
, &timeout
);
1037 return (timeval_compare(&end_time
, &now
) < 0);
1040 /****************************************************************************
1041 Handle the 1 second delay in returning a SHARING_VIOLATION error.
1042 ****************************************************************************/
1044 static void defer_open(struct share_mode_lock
*lck
,
1045 struct timeval request_time
,
1046 struct timeval timeout
,
1047 struct smb_request
*req
,
1048 struct deferred_open_record
*state
)
1052 /* Paranoia check */
1054 for (i
=0; i
<lck
->num_share_modes
; i
++) {
1055 struct share_mode_entry
*e
= &lck
->share_modes
[i
];
1057 if (!is_deferred_open_entry(e
)) {
1061 if (procid_is_me(&e
->pid
) && (e
->op_mid
== req
->mid
)) {
1062 DEBUG(0, ("Trying to defer an already deferred "
1063 "request: mid=%llu, exiting\n",
1064 (unsigned long long)req
->mid
));
1065 exit_server("attempt to defer a deferred request");
1069 /* End paranoia check */
1071 DEBUG(10,("defer_open_sharing_error: time [%u.%06u] adding deferred "
1072 "open entry for mid %llu\n",
1073 (unsigned int)request_time
.tv_sec
,
1074 (unsigned int)request_time
.tv_usec
,
1075 (unsigned long long)req
->mid
));
1077 if (!push_deferred_open_message_smb(req
, request_time
, timeout
,
1078 state
->id
, (char *)state
, sizeof(*state
))) {
1079 exit_server("push_deferred_open_message_smb failed");
1081 add_deferred_open(lck
, req
->mid
, request_time
,
1082 sconn_server_id(req
->sconn
), state
->id
);
1086 /****************************************************************************
1087 On overwrite open ensure that the attributes match.
1088 ****************************************************************************/
1090 bool open_match_attributes(connection_struct
*conn
,
1091 uint32 old_dos_attr
,
1092 uint32 new_dos_attr
,
1093 mode_t existing_unx_mode
,
1094 mode_t new_unx_mode
,
1095 mode_t
*returned_unx_mode
)
1097 uint32 noarch_old_dos_attr
, noarch_new_dos_attr
;
1099 noarch_old_dos_attr
= (old_dos_attr
& ~FILE_ATTRIBUTE_ARCHIVE
);
1100 noarch_new_dos_attr
= (new_dos_attr
& ~FILE_ATTRIBUTE_ARCHIVE
);
1102 if((noarch_old_dos_attr
== 0 && noarch_new_dos_attr
!= 0) ||
1103 (noarch_old_dos_attr
!= 0 && ((noarch_old_dos_attr
& noarch_new_dos_attr
) == noarch_old_dos_attr
))) {
1104 *returned_unx_mode
= new_unx_mode
;
1106 *returned_unx_mode
= (mode_t
)0;
1109 DEBUG(10,("open_match_attributes: old_dos_attr = 0x%x, "
1110 "existing_unx_mode = 0%o, new_dos_attr = 0x%x "
1111 "returned_unx_mode = 0%o\n",
1112 (unsigned int)old_dos_attr
,
1113 (unsigned int)existing_unx_mode
,
1114 (unsigned int)new_dos_attr
,
1115 (unsigned int)*returned_unx_mode
));
1117 /* If we're mapping SYSTEM and HIDDEN ensure they match. */
1118 if (lp_map_system(SNUM(conn
)) || lp_store_dos_attributes(SNUM(conn
))) {
1119 if ((old_dos_attr
& FILE_ATTRIBUTE_SYSTEM
) &&
1120 !(new_dos_attr
& FILE_ATTRIBUTE_SYSTEM
)) {
1124 if (lp_map_hidden(SNUM(conn
)) || lp_store_dos_attributes(SNUM(conn
))) {
1125 if ((old_dos_attr
& FILE_ATTRIBUTE_HIDDEN
) &&
1126 !(new_dos_attr
& FILE_ATTRIBUTE_HIDDEN
)) {
1133 /****************************************************************************
1134 Special FCB or DOS processing in the case of a sharing violation.
1135 Try and find a duplicated file handle.
1136 ****************************************************************************/
1138 NTSTATUS
fcb_or_dos_open(struct smb_request
*req
,
1139 connection_struct
*conn
,
1140 files_struct
*fsp_to_dup_into
,
1141 const struct smb_filename
*smb_fname
,
1146 uint32 share_access
,
1147 uint32 create_options
)
1151 DEBUG(5,("fcb_or_dos_open: attempting old open semantics for "
1152 "file %s.\n", smb_fname_str_dbg(smb_fname
)));
1154 for(fsp
= file_find_di_first(conn
->sconn
, id
); fsp
;
1155 fsp
= file_find_di_next(fsp
)) {
1157 DEBUG(10,("fcb_or_dos_open: checking file %s, fd = %d, "
1158 "vuid = %u, file_pid = %u, private_options = 0x%x "
1159 "access_mask = 0x%x\n", fsp_str_dbg(fsp
),
1160 fsp
->fh
->fd
, (unsigned int)fsp
->vuid
,
1161 (unsigned int)fsp
->file_pid
,
1162 (unsigned int)fsp
->fh
->private_options
,
1163 (unsigned int)fsp
->access_mask
));
1165 if (fsp
->fh
->fd
!= -1 &&
1166 fsp
->vuid
== vuid
&&
1167 fsp
->file_pid
== file_pid
&&
1168 (fsp
->fh
->private_options
& (NTCREATEX_OPTIONS_PRIVATE_DENY_DOS
|
1169 NTCREATEX_OPTIONS_PRIVATE_DENY_FCB
)) &&
1170 (fsp
->access_mask
& FILE_WRITE_DATA
) &&
1171 strequal(fsp
->fsp_name
->base_name
, smb_fname
->base_name
) &&
1172 strequal(fsp
->fsp_name
->stream_name
,
1173 smb_fname
->stream_name
)) {
1174 DEBUG(10,("fcb_or_dos_open: file match\n"));
1180 return NT_STATUS_NOT_FOUND
;
1183 /* quite an insane set of semantics ... */
1184 if (is_executable(smb_fname
->base_name
) &&
1185 (fsp
->fh
->private_options
& NTCREATEX_OPTIONS_PRIVATE_DENY_DOS
)) {
1186 DEBUG(10,("fcb_or_dos_open: file fail due to is_executable.\n"));
1187 return NT_STATUS_INVALID_PARAMETER
;
1190 /* We need to duplicate this fsp. */
1191 return dup_file_fsp(req
, fsp
, access_mask
, share_access
,
1192 create_options
, fsp_to_dup_into
);
1195 /****************************************************************************
1196 Open a file with a share mode - old openX method - map into NTCreate.
1197 ****************************************************************************/
1199 bool map_open_params_to_ntcreate(const struct smb_filename
*smb_fname
,
1200 int deny_mode
, int open_func
,
1201 uint32
*paccess_mask
,
1202 uint32
*pshare_mode
,
1203 uint32
*pcreate_disposition
,
1204 uint32
*pcreate_options
,
1205 uint32_t *pprivate_flags
)
1209 uint32 create_disposition
;
1210 uint32 create_options
= FILE_NON_DIRECTORY_FILE
;
1211 uint32_t private_flags
= 0;
1213 DEBUG(10,("map_open_params_to_ntcreate: fname = %s, deny_mode = 0x%x, "
1214 "open_func = 0x%x\n",
1215 smb_fname_str_dbg(smb_fname
), (unsigned int)deny_mode
,
1216 (unsigned int)open_func
));
1218 /* Create the NT compatible access_mask. */
1219 switch (GET_OPENX_MODE(deny_mode
)) {
1220 case DOS_OPEN_EXEC
: /* Implies read-only - used to be FILE_READ_DATA */
1221 case DOS_OPEN_RDONLY
:
1222 access_mask
= FILE_GENERIC_READ
;
1224 case DOS_OPEN_WRONLY
:
1225 access_mask
= FILE_GENERIC_WRITE
;
1229 access_mask
= FILE_GENERIC_READ
|FILE_GENERIC_WRITE
;
1232 DEBUG(10,("map_open_params_to_ntcreate: bad open mode = 0x%x\n",
1233 (unsigned int)GET_OPENX_MODE(deny_mode
)));
1237 /* Create the NT compatible create_disposition. */
1238 switch (open_func
) {
1239 case OPENX_FILE_EXISTS_FAIL
|OPENX_FILE_CREATE_IF_NOT_EXIST
:
1240 create_disposition
= FILE_CREATE
;
1243 case OPENX_FILE_EXISTS_OPEN
:
1244 create_disposition
= FILE_OPEN
;
1247 case OPENX_FILE_EXISTS_OPEN
|OPENX_FILE_CREATE_IF_NOT_EXIST
:
1248 create_disposition
= FILE_OPEN_IF
;
1251 case OPENX_FILE_EXISTS_TRUNCATE
:
1252 create_disposition
= FILE_OVERWRITE
;
1255 case OPENX_FILE_EXISTS_TRUNCATE
|OPENX_FILE_CREATE_IF_NOT_EXIST
:
1256 create_disposition
= FILE_OVERWRITE_IF
;
1260 /* From samba4 - to be confirmed. */
1261 if (GET_OPENX_MODE(deny_mode
) == DOS_OPEN_EXEC
) {
1262 create_disposition
= FILE_CREATE
;
1265 DEBUG(10,("map_open_params_to_ntcreate: bad "
1266 "open_func 0x%x\n", (unsigned int)open_func
));
1270 /* Create the NT compatible share modes. */
1271 switch (GET_DENY_MODE(deny_mode
)) {
1273 share_mode
= FILE_SHARE_NONE
;
1277 share_mode
= FILE_SHARE_READ
;
1281 share_mode
= FILE_SHARE_WRITE
;
1285 share_mode
= FILE_SHARE_READ
|FILE_SHARE_WRITE
;
1289 private_flags
|= NTCREATEX_OPTIONS_PRIVATE_DENY_DOS
;
1290 if (is_executable(smb_fname
->base_name
)) {
1291 share_mode
= FILE_SHARE_READ
|FILE_SHARE_WRITE
;
1293 if (GET_OPENX_MODE(deny_mode
) == DOS_OPEN_RDONLY
) {
1294 share_mode
= FILE_SHARE_READ
;
1296 share_mode
= FILE_SHARE_NONE
;
1302 private_flags
|= NTCREATEX_OPTIONS_PRIVATE_DENY_FCB
;
1303 share_mode
= FILE_SHARE_NONE
;
1307 DEBUG(10,("map_open_params_to_ntcreate: bad deny_mode 0x%x\n",
1308 (unsigned int)GET_DENY_MODE(deny_mode
) ));
1312 DEBUG(10,("map_open_params_to_ntcreate: file %s, access_mask = 0x%x, "
1313 "share_mode = 0x%x, create_disposition = 0x%x, "
1314 "create_options = 0x%x private_flags = 0x%x\n",
1315 smb_fname_str_dbg(smb_fname
),
1316 (unsigned int)access_mask
,
1317 (unsigned int)share_mode
,
1318 (unsigned int)create_disposition
,
1319 (unsigned int)create_options
,
1320 (unsigned int)private_flags
));
1323 *paccess_mask
= access_mask
;
1326 *pshare_mode
= share_mode
;
1328 if (pcreate_disposition
) {
1329 *pcreate_disposition
= create_disposition
;
1331 if (pcreate_options
) {
1332 *pcreate_options
= create_options
;
1334 if (pprivate_flags
) {
1335 *pprivate_flags
= private_flags
;
1342 static void schedule_defer_open(struct share_mode_lock
*lck
,
1343 struct timeval request_time
,
1344 struct smb_request
*req
)
1346 struct deferred_open_record state
;
1348 /* This is a relative time, added to the absolute
1349 request_time value to get the absolute timeout time.
1350 Note that if this is the second or greater time we enter
1351 this codepath for this particular request mid then
1352 request_time is left as the absolute time of the *first*
1353 time this request mid was processed. This is what allows
1354 the request to eventually time out. */
1356 struct timeval timeout
;
1358 /* Normally the smbd we asked should respond within
1359 * OPLOCK_BREAK_TIMEOUT seconds regardless of whether
1360 * the client did, give twice the timeout as a safety
1361 * measure here in case the other smbd is stuck
1362 * somewhere else. */
1364 timeout
= timeval_set(OPLOCK_BREAK_TIMEOUT
*2, 0);
1366 /* Nothing actually uses state.delayed_for_oplocks
1367 but it's handy to differentiate in debug messages
1368 between a 30 second delay due to oplock break, and
1369 a 1 second delay for share mode conflicts. */
1371 state
.delayed_for_oplocks
= True
;
1374 if (!request_timed_out(request_time
, timeout
)) {
1375 defer_open(lck
, request_time
, timeout
, req
, &state
);
1379 /****************************************************************************
1380 Work out what access_mask to use from what the client sent us.
1381 ****************************************************************************/
1383 static NTSTATUS
calculate_access_mask(connection_struct
*conn
,
1384 const struct smb_filename
*smb_fname
,
1386 uint32_t access_mask
,
1387 uint32_t *access_mask_out
)
1392 * Convert GENERIC bits to specific bits.
1395 se_map_generic(&access_mask
, &file_generic_mapping
);
1397 /* Calculate MAXIMUM_ALLOWED_ACCESS if requested. */
1398 if (access_mask
& MAXIMUM_ALLOWED_ACCESS
) {
1401 struct security_descriptor
*sd
;
1402 uint32_t access_granted
= 0;
1404 status
= SMB_VFS_GET_NT_ACL(conn
, smb_fname
->base_name
,
1409 if (!NT_STATUS_IS_OK(status
)) {
1410 DEBUG(10, ("calculate_access_mask: Could not get acl "
1412 smb_fname_str_dbg(smb_fname
),
1413 nt_errstr(status
)));
1414 return NT_STATUS_ACCESS_DENIED
;
1417 status
= smb1_file_se_access_check(conn
,
1419 get_current_nttok(conn
),
1425 if (!NT_STATUS_IS_OK(status
)) {
1426 DEBUG(10, ("calculate_access_mask: Access denied on "
1427 "file %s: when calculating maximum access\n",
1428 smb_fname_str_dbg(smb_fname
)));
1429 return NT_STATUS_ACCESS_DENIED
;
1432 access_mask
= access_granted
;
1434 access_mask
= FILE_GENERIC_ALL
;
1438 *access_mask_out
= access_mask
;
1439 return NT_STATUS_OK
;
1442 /****************************************************************************
1443 Remove the deferred open entry under lock.
1444 ****************************************************************************/
1446 void remove_deferred_open_entry(struct file_id id
, uint64_t mid
,
1447 struct server_id pid
)
1449 struct share_mode_lock
*lck
= get_share_mode_lock(talloc_tos(), id
,
1452 DEBUG(0, ("could not get share mode lock\n"));
1454 del_deferred_open_entry(lck
, mid
, pid
);
1459 /****************************************************************************
1460 Open a file with a share mode. Passed in an already created files_struct *.
1461 ****************************************************************************/
1463 static NTSTATUS
open_file_ntcreate(connection_struct
*conn
,
1464 struct smb_request
*req
,
1465 uint32 access_mask
, /* access bits (FILE_READ_DATA etc.) */
1466 uint32 share_access
, /* share constants (FILE_SHARE_READ etc) */
1467 uint32 create_disposition
, /* FILE_OPEN_IF etc. */
1468 uint32 create_options
, /* options such as delete on close. */
1469 uint32 new_dos_attributes
, /* attributes used for new file. */
1470 int oplock_request
, /* internal Samba oplock codes. */
1471 /* Information (FILE_EXISTS etc.) */
1472 uint32_t private_flags
, /* Samba specific flags. */
1476 struct smb_filename
*smb_fname
= fsp
->fsp_name
;
1479 bool file_existed
= VALID_STAT(smb_fname
->st
);
1480 bool def_acl
= False
;
1481 bool posix_open
= False
;
1482 bool new_file_created
= False
;
1483 bool clear_ads
= false;
1485 NTSTATUS fsp_open
= NT_STATUS_ACCESS_DENIED
;
1486 mode_t new_unx_mode
= (mode_t
)0;
1487 mode_t unx_mode
= (mode_t
)0;
1489 uint32 existing_dos_attributes
= 0;
1490 struct timeval request_time
= timeval_zero();
1491 struct share_mode_lock
*lck
= NULL
;
1492 uint32 open_access_mask
= access_mask
;
1498 /* Windows allows a new file to be created and
1499 silently removes a FILE_ATTRIBUTE_DIRECTORY
1500 sent by the client. Do the same. */
1502 new_dos_attributes
&= ~FILE_ATTRIBUTE_DIRECTORY
;
1504 if (conn
->printer
) {
1506 * Printers are handled completely differently.
1507 * Most of the passed parameters are ignored.
1511 *pinfo
= FILE_WAS_CREATED
;
1514 DEBUG(10, ("open_file_ntcreate: printer open fname=%s\n",
1515 smb_fname_str_dbg(smb_fname
)));
1518 DEBUG(0,("open_file_ntcreate: printer open without "
1519 "an SMB request!\n"));
1520 return NT_STATUS_INTERNAL_ERROR
;
1523 return print_spool_open(fsp
, smb_fname
->base_name
,
1527 if (!parent_dirname(talloc_tos(), smb_fname
->base_name
, &parent_dir
,
1529 return NT_STATUS_NO_MEMORY
;
1532 if (new_dos_attributes
& FILE_FLAG_POSIX_SEMANTICS
) {
1534 unx_mode
= (mode_t
)(new_dos_attributes
& ~FILE_FLAG_POSIX_SEMANTICS
);
1535 new_dos_attributes
= 0;
1537 /* We add aARCH to this as this mode is only used if the file is
1539 unx_mode
= unix_mode(conn
, new_dos_attributes
| aARCH
,
1540 smb_fname
, parent_dir
);
1543 DEBUG(10, ("open_file_ntcreate: fname=%s, dos_attrs=0x%x "
1544 "access_mask=0x%x share_access=0x%x "
1545 "create_disposition = 0x%x create_options=0x%x "
1546 "unix mode=0%o oplock_request=%d private_flags = 0x%x\n",
1547 smb_fname_str_dbg(smb_fname
), new_dos_attributes
,
1548 access_mask
, share_access
, create_disposition
,
1549 create_options
, (unsigned int)unx_mode
, oplock_request
,
1550 (unsigned int)private_flags
));
1552 if ((req
== NULL
) && ((oplock_request
& INTERNAL_OPEN_ONLY
) == 0)) {
1553 DEBUG(0, ("No smb request but not an internal only open!\n"));
1554 return NT_STATUS_INTERNAL_ERROR
;
1558 * Only non-internal opens can be deferred at all
1563 if (get_deferred_open_message_state(req
,
1567 struct deferred_open_record
*state
= (struct deferred_open_record
*)ptr
;
1568 /* Remember the absolute time of the original
1569 request with this mid. We'll use it later to
1570 see if this has timed out. */
1572 /* Remove the deferred open entry under lock. */
1573 remove_deferred_open_entry(
1574 state
->id
, req
->mid
,
1575 sconn_server_id(req
->sconn
));
1577 /* Ensure we don't reprocess this message. */
1578 remove_deferred_open_message_smb(req
->mid
);
1582 status
= check_name(conn
, smb_fname
->base_name
);
1583 if (!NT_STATUS_IS_OK(status
)) {
1588 new_dos_attributes
&= SAMBA_ATTRIBUTES_MASK
;
1590 existing_dos_attributes
= dos_mode(conn
, smb_fname
);
1594 /* ignore any oplock requests if oplocks are disabled */
1595 if (!lp_oplocks(SNUM(conn
)) ||
1596 IS_VETO_OPLOCK_PATH(conn
, smb_fname
->base_name
)) {
1597 /* Mask off everything except the private Samba bits. */
1598 oplock_request
&= SAMBA_PRIVATE_OPLOCK_MASK
;
1601 /* this is for OS/2 long file names - say we don't support them */
1602 if (!lp_posix_pathnames() && strstr(smb_fname
->base_name
,".+,;=[].")) {
1603 /* OS/2 Workplace shell fix may be main code stream in a later
1605 DEBUG(5,("open_file_ntcreate: OS/2 long filenames are not "
1607 if (use_nt_status()) {
1608 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
1610 return NT_STATUS_DOS(ERRDOS
, ERRcannotopen
);
1613 switch( create_disposition
) {
1615 * Currently we're using FILE_SUPERSEDE as the same as
1616 * FILE_OVERWRITE_IF but they really are
1617 * different. FILE_SUPERSEDE deletes an existing file
1618 * (requiring delete access) then recreates it.
1620 case FILE_SUPERSEDE
:
1621 /* If file exists replace/overwrite. If file doesn't
1623 flags2
|= (O_CREAT
| O_TRUNC
);
1627 case FILE_OVERWRITE_IF
:
1628 /* If file exists replace/overwrite. If file doesn't
1630 flags2
|= (O_CREAT
| O_TRUNC
);
1635 /* If file exists open. If file doesn't exist error. */
1636 if (!file_existed
) {
1637 DEBUG(5,("open_file_ntcreate: FILE_OPEN "
1638 "requested for file %s and file "
1640 smb_fname_str_dbg(smb_fname
)));
1642 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
1646 case FILE_OVERWRITE
:
1647 /* If file exists overwrite. If file doesn't exist
1649 if (!file_existed
) {
1650 DEBUG(5,("open_file_ntcreate: FILE_OVERWRITE "
1651 "requested for file %s and file "
1653 smb_fname_str_dbg(smb_fname
) ));
1655 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
1662 /* If file exists error. If file doesn't exist
1665 DEBUG(5,("open_file_ntcreate: FILE_CREATE "
1666 "requested for file %s and file "
1667 "already exists.\n",
1668 smb_fname_str_dbg(smb_fname
)));
1669 if (S_ISDIR(smb_fname
->st
.st_ex_mode
)) {
1674 return map_nt_error_from_unix(errno
);
1676 flags2
|= (O_CREAT
|O_EXCL
);
1680 /* If file exists open. If file doesn't exist
1686 return NT_STATUS_INVALID_PARAMETER
;
1689 /* We only care about matching attributes on file exists and
1692 if (!posix_open
&& file_existed
&& ((create_disposition
== FILE_OVERWRITE
) ||
1693 (create_disposition
== FILE_OVERWRITE_IF
))) {
1694 if (!open_match_attributes(conn
, existing_dos_attributes
,
1696 smb_fname
->st
.st_ex_mode
,
1697 unx_mode
, &new_unx_mode
)) {
1698 DEBUG(5,("open_file_ntcreate: attributes missmatch "
1699 "for file %s (%x %x) (0%o, 0%o)\n",
1700 smb_fname_str_dbg(smb_fname
),
1701 existing_dos_attributes
,
1703 (unsigned int)smb_fname
->st
.st_ex_mode
,
1704 (unsigned int)unx_mode
));
1706 return NT_STATUS_ACCESS_DENIED
;
1710 status
= calculate_access_mask(conn
, smb_fname
, file_existed
,
1713 if (!NT_STATUS_IS_OK(status
)) {
1714 DEBUG(10, ("open_file_ntcreate: calculate_access_mask "
1715 "on file %s returned %s\n",
1716 smb_fname_str_dbg(smb_fname
), nt_errstr(status
)));
1720 open_access_mask
= access_mask
;
1722 if ((flags2
& O_TRUNC
) || (oplock_request
& FORCE_OPLOCK_BREAK_TO_NONE
)) {
1723 open_access_mask
|= FILE_WRITE_DATA
; /* This will cause oplock breaks. */
1726 DEBUG(10, ("open_file_ntcreate: fname=%s, after mapping "
1727 "access_mask=0x%x\n", smb_fname_str_dbg(smb_fname
),
1731 * Note that we ignore the append flag as append does not
1732 * mean the same thing under DOS and Unix.
1735 if ((access_mask
& (FILE_WRITE_DATA
| FILE_APPEND_DATA
)) ||
1736 (oplock_request
& FORCE_OPLOCK_BREAK_TO_NONE
)) {
1737 /* DENY_DOS opens are always underlying read-write on the
1738 file handle, no matter what the requested access mask
1740 if ((private_flags
& NTCREATEX_OPTIONS_PRIVATE_DENY_DOS
) ||
1741 access_mask
& (FILE_READ_ATTRIBUTES
|FILE_READ_DATA
|FILE_READ_EA
|FILE_EXECUTE
)) {
1751 * Currently we only look at FILE_WRITE_THROUGH for create options.
1755 if ((create_options
& FILE_WRITE_THROUGH
) && lp_strict_sync(SNUM(conn
))) {
1760 if (posix_open
&& (access_mask
& FILE_APPEND_DATA
)) {
1764 if (!posix_open
&& !CAN_WRITE(conn
)) {
1766 * We should really return a permission denied error if either
1767 * O_CREAT or O_TRUNC are set, but for compatibility with
1768 * older versions of Samba we just AND them out.
1770 flags2
&= ~(O_CREAT
|O_TRUNC
);
1774 * Ensure we can't write on a read-only share or file.
1777 if (flags
!= O_RDONLY
&& file_existed
&&
1778 (!CAN_WRITE(conn
) || IS_DOS_READONLY(existing_dos_attributes
))) {
1779 DEBUG(5,("open_file_ntcreate: write access requested for "
1780 "file %s on read only %s\n",
1781 smb_fname_str_dbg(smb_fname
),
1782 !CAN_WRITE(conn
) ? "share" : "file" ));
1784 return NT_STATUS_ACCESS_DENIED
;
1787 fsp
->file_id
= vfs_file_id_from_sbuf(conn
, &smb_fname
->st
);
1788 fsp
->share_access
= share_access
;
1789 fsp
->fh
->private_options
= private_flags
;
1790 fsp
->access_mask
= open_access_mask
; /* We change this to the
1791 * requested access_mask after
1792 * the open is done. */
1793 fsp
->posix_open
= posix_open
;
1795 /* Ensure no SAMBA_PRIVATE bits can be set. */
1796 fsp
->oplock_type
= (oplock_request
& ~SAMBA_PRIVATE_OPLOCK_MASK
);
1798 if (timeval_is_zero(&request_time
)) {
1799 request_time
= fsp
->open_time
;
1803 struct timespec old_write_time
= smb_fname
->st
.st_ex_mtime
;
1804 id
= vfs_file_id_from_sbuf(conn
, &smb_fname
->st
);
1806 lck
= get_share_mode_lock(talloc_tos(), id
,
1808 smb_fname
, &old_write_time
);
1811 DEBUG(0, ("Could not get share mode lock\n"));
1812 return NT_STATUS_SHARING_VIOLATION
;
1815 /* First pass - send break only on batch oplocks. */
1817 && delay_for_oplocks(lck
, fsp
, req
->mid
, 1,
1819 schedule_defer_open(lck
, request_time
, req
);
1821 return NT_STATUS_SHARING_VIOLATION
;
1824 /* Use the client requested access mask here, not the one we
1826 status
= open_mode_check(conn
, lck
, access_mask
, share_access
,
1827 create_options
, &file_existed
);
1829 if (NT_STATUS_IS_OK(status
)) {
1830 /* We might be going to allow this open. Check oplock
1832 /* Second pass - send break for both batch or
1833 * exclusive oplocks. */
1835 && delay_for_oplocks(lck
, fsp
, req
->mid
, 2,
1837 schedule_defer_open(lck
, request_time
, req
);
1839 return NT_STATUS_SHARING_VIOLATION
;
1843 if (NT_STATUS_EQUAL(status
, NT_STATUS_DELETE_PENDING
)) {
1844 /* DELETE_PENDING is not deferred for a second */
1849 if (!NT_STATUS_IS_OK(status
)) {
1850 uint32 can_access_mask
;
1851 bool can_access
= True
;
1853 SMB_ASSERT(NT_STATUS_EQUAL(status
, NT_STATUS_SHARING_VIOLATION
));
1855 /* Check if this can be done with the deny_dos and fcb
1858 (NTCREATEX_OPTIONS_PRIVATE_DENY_DOS
|
1859 NTCREATEX_OPTIONS_PRIVATE_DENY_FCB
)) {
1861 DEBUG(0, ("DOS open without an SMB "
1864 return NT_STATUS_INTERNAL_ERROR
;
1867 /* Use the client requested access mask here,
1868 * not the one we open with. */
1869 status
= fcb_or_dos_open(req
,
1880 if (NT_STATUS_IS_OK(status
)) {
1883 *pinfo
= FILE_WAS_OPENED
;
1885 return NT_STATUS_OK
;
1890 * This next line is a subtlety we need for
1891 * MS-Access. If a file open will fail due to share
1892 * permissions and also for security (access) reasons,
1893 * we need to return the access failed error, not the
1894 * share error. We can't open the file due to kernel
1895 * oplock deadlock (it's possible we failed above on
1896 * the open_mode_check()) so use a userspace check.
1899 if (flags
& O_RDWR
) {
1900 can_access_mask
= FILE_READ_DATA
|FILE_WRITE_DATA
;
1901 } else if (flags
& O_WRONLY
) {
1902 can_access_mask
= FILE_WRITE_DATA
;
1904 can_access_mask
= FILE_READ_DATA
;
1907 if (((can_access_mask
& FILE_WRITE_DATA
) &&
1908 !CAN_WRITE(conn
)) ||
1909 !can_access_file_data(conn
, smb_fname
,
1915 * If we're returning a share violation, ensure we
1916 * cope with the braindead 1 second delay.
1919 if (!(oplock_request
& INTERNAL_OPEN_ONLY
) &&
1920 lp_defer_sharing_violations()) {
1921 struct timeval timeout
;
1922 struct deferred_open_record state
;
1925 /* this is a hack to speed up torture tests
1927 timeout_usecs
= lp_parm_int(SNUM(conn
),
1928 "smbd","sharedelay",
1929 SHARING_VIOLATION_USEC_WAIT
);
1931 /* This is a relative time, added to the absolute
1932 request_time value to get the absolute timeout time.
1933 Note that if this is the second or greater time we enter
1934 this codepath for this particular request mid then
1935 request_time is left as the absolute time of the *first*
1936 time this request mid was processed. This is what allows
1937 the request to eventually time out. */
1939 timeout
= timeval_set(0, timeout_usecs
);
1941 /* Nothing actually uses state.delayed_for_oplocks
1942 but it's handy to differentiate in debug messages
1943 between a 30 second delay due to oplock break, and
1944 a 1 second delay for share mode conflicts. */
1946 state
.delayed_for_oplocks
= False
;
1950 && !request_timed_out(request_time
,
1952 defer_open(lck
, request_time
, timeout
,
1960 * We have detected a sharing violation here
1961 * so return the correct error code
1963 status
= NT_STATUS_SHARING_VIOLATION
;
1965 status
= NT_STATUS_ACCESS_DENIED
;
1971 * We exit this block with the share entry *locked*.....
1975 SMB_ASSERT(!file_existed
|| (lck
!= NULL
));
1978 * Ensure we pay attention to default ACLs on directories if required.
1981 if ((flags2
& O_CREAT
) && lp_inherit_acls(SNUM(conn
)) &&
1982 (def_acl
= directory_has_default_acl(conn
, parent_dir
))) {
1983 unx_mode
= (0777 & lp_create_mask(SNUM(conn
)));
1986 DEBUG(4,("calling open_file with flags=0x%X flags2=0x%X mode=0%o, "
1987 "access_mask = 0x%x, open_access_mask = 0x%x\n",
1988 (unsigned int)flags
, (unsigned int)flags2
,
1989 (unsigned int)unx_mode
, (unsigned int)access_mask
,
1990 (unsigned int)open_access_mask
));
1993 * open_file strips any O_TRUNC flags itself.
1996 fsp_open
= open_file(fsp
, conn
, req
, parent_dir
,
1997 flags
|flags2
, unx_mode
, access_mask
,
2000 if (!NT_STATUS_IS_OK(fsp_open
)) {
2007 if (!file_existed
) {
2008 struct timespec old_write_time
= smb_fname
->st
.st_ex_mtime
;
2010 * Deal with the race condition where two smbd's detect the
2011 * file doesn't exist and do the create at the same time. One
2012 * of them will win and set a share mode, the other (ie. this
2013 * one) should check if the requested share mode for this
2014 * create is allowed.
2018 * Now the file exists and fsp is successfully opened,
2019 * fsp->dev and fsp->inode are valid and should replace the
2020 * dev=0,inode=0 from a non existent file. Spotted by
2021 * Nadav Danieli <nadavd@exanet.com>. JRA.
2026 lck
= get_share_mode_lock(talloc_tos(), id
,
2028 smb_fname
, &old_write_time
);
2031 DEBUG(0, ("open_file_ntcreate: Could not get share "
2032 "mode lock for %s\n",
2033 smb_fname_str_dbg(smb_fname
)));
2035 return NT_STATUS_SHARING_VIOLATION
;
2038 /* First pass - send break only on batch oplocks. */
2040 && delay_for_oplocks(lck
, fsp
, req
->mid
, 1,
2042 schedule_defer_open(lck
, request_time
, req
);
2045 return NT_STATUS_SHARING_VIOLATION
;
2048 status
= open_mode_check(conn
, lck
, access_mask
, share_access
,
2049 create_options
, &file_existed
);
2051 if (NT_STATUS_IS_OK(status
)) {
2052 /* We might be going to allow this open. Check oplock
2054 /* Second pass - send break for both batch or
2055 * exclusive oplocks. */
2057 && delay_for_oplocks(lck
, fsp
, req
->mid
, 2,
2059 schedule_defer_open(lck
, request_time
, req
);
2062 return NT_STATUS_SHARING_VIOLATION
;
2066 if (!NT_STATUS_IS_OK(status
)) {
2067 struct deferred_open_record state
;
2071 state
.delayed_for_oplocks
= False
;
2074 /* Do it all over again immediately. In the second
2075 * round we will find that the file existed and handle
2076 * the DELETE_PENDING and FCB cases correctly. No need
2077 * to duplicate the code here. Essentially this is a
2078 * "goto top of this function", but don't tell
2082 defer_open(lck
, request_time
, timeval_zero(),
2090 * We exit this block with the share entry *locked*.....
2095 SMB_ASSERT(lck
!= NULL
);
2097 /* Delete streams if create_disposition requires it */
2098 if (file_existed
&& clear_ads
&&
2099 !is_ntfs_stream_smb_fname(smb_fname
)) {
2100 status
= delete_all_streams(conn
, smb_fname
->base_name
);
2101 if (!NT_STATUS_IS_OK(status
)) {
2108 /* note that we ignore failure for the following. It is
2109 basically a hack for NFS, and NFS will never set one of
2110 these only read them. Nobody but Samba can ever set a deny
2111 mode and we have already checked our more authoritative
2112 locking database for permission to set this deny mode. If
2113 the kernel refuses the operations then the kernel is wrong.
2114 note that GPFS supports it as well - jmcd */
2116 if (fsp
->fh
->fd
!= -1) {
2118 ret_flock
= SMB_VFS_KERNEL_FLOCK(fsp
, share_access
, access_mask
);
2119 if(ret_flock
== -1 ){
2124 return NT_STATUS_SHARING_VIOLATION
;
2129 * At this point onwards, we can guarentee that the share entry
2130 * is locked, whether we created the file or not, and that the
2131 * deny mode is compatible with all current opens.
2135 * If requested, truncate the file.
2138 if (file_existed
&& (flags2
&O_TRUNC
)) {
2140 * We are modifing the file after open - update the stat
2143 if ((SMB_VFS_FTRUNCATE(fsp
, 0) == -1) ||
2144 (SMB_VFS_FSTAT(fsp
, &smb_fname
->st
)==-1)) {
2145 status
= map_nt_error_from_unix(errno
);
2153 * According to Samba4, SEC_FILE_READ_ATTRIBUTE is always granted,
2155 fsp
->access_mask
= access_mask
| FILE_READ_ATTRIBUTES
;
2158 /* stat opens on existing files don't get oplocks. */
2159 if (is_stat_open(open_access_mask
)) {
2160 fsp
->oplock_type
= NO_OPLOCK
;
2163 if (!(flags2
& O_TRUNC
)) {
2164 info
= FILE_WAS_OPENED
;
2166 info
= FILE_WAS_OVERWRITTEN
;
2169 info
= FILE_WAS_CREATED
;
2177 * Setup the oplock info in both the shared memory and
2181 if (!set_file_oplock(fsp
, fsp
->oplock_type
)) {
2182 /* Could not get the kernel oplock */
2183 fsp
->oplock_type
= NO_OPLOCK
;
2186 if (info
== FILE_WAS_OVERWRITTEN
|| info
== FILE_WAS_CREATED
|| info
== FILE_WAS_SUPERSEDED
) {
2187 new_file_created
= True
;
2190 set_share_mode(lck
, fsp
, get_current_uid(conn
), 0,
2193 /* Handle strange delete on close create semantics. */
2194 if (create_options
& FILE_DELETE_ON_CLOSE
) {
2196 status
= can_set_delete_on_close(fsp
, new_dos_attributes
);
2198 if (!NT_STATUS_IS_OK(status
)) {
2199 /* Remember to delete the mode we just added. */
2200 del_share_mode(lck
, fsp
);
2205 /* Note that here we set the *inital* delete on close flag,
2206 not the regular one. The magic gets handled in close. */
2207 fsp
->initial_delete_on_close
= True
;
2210 if (new_file_created
) {
2211 /* Files should be initially set as archive */
2212 if (lp_map_archive(SNUM(conn
)) ||
2213 lp_store_dos_attributes(SNUM(conn
))) {
2215 if (file_set_dosmode(conn
, smb_fname
,
2216 new_dos_attributes
| aARCH
,
2217 parent_dir
, true) == 0) {
2218 unx_mode
= smb_fname
->st
.st_ex_mode
;
2224 /* Determine sparse flag. */
2226 /* POSIX opens are sparse by default. */
2227 fsp
->is_sparse
= true;
2229 fsp
->is_sparse
= (file_existed
&&
2230 (existing_dos_attributes
& FILE_ATTRIBUTE_SPARSE
));
2234 * Take care of inherited ACLs on created files - if default ACL not
2238 if (!posix_open
&& !file_existed
&& !def_acl
) {
2240 int saved_errno
= errno
; /* We might get ENOSYS in the next
2243 if (SMB_VFS_FCHMOD_ACL(fsp
, unx_mode
) == -1 &&
2245 errno
= saved_errno
; /* Ignore ENOSYS */
2248 } else if (new_unx_mode
) {
2252 /* Attributes need changing. File already existed. */
2255 int saved_errno
= errno
; /* We might get ENOSYS in the
2257 ret
= SMB_VFS_FCHMOD_ACL(fsp
, new_unx_mode
);
2259 if (ret
== -1 && errno
== ENOSYS
) {
2260 errno
= saved_errno
; /* Ignore ENOSYS */
2262 DEBUG(5, ("open_file_ntcreate: reset "
2263 "attributes of file %s to 0%o\n",
2264 smb_fname_str_dbg(smb_fname
),
2265 (unsigned int)new_unx_mode
));
2266 ret
= 0; /* Don't do the fchmod below. */
2271 (SMB_VFS_FCHMOD(fsp
, new_unx_mode
) == -1))
2272 DEBUG(5, ("open_file_ntcreate: failed to reset "
2273 "attributes of file %s to 0%o\n",
2274 smb_fname_str_dbg(smb_fname
),
2275 (unsigned int)new_unx_mode
));
2278 /* If this is a successful open, we must remove any deferred open
2281 del_deferred_open_entry(lck
, req
->mid
,
2282 sconn_server_id(req
->sconn
));
2286 return NT_STATUS_OK
;
2290 /****************************************************************************
2291 Open a file for for write to ensure that we can fchmod it.
2292 ****************************************************************************/
2294 NTSTATUS
open_file_fchmod(connection_struct
*conn
,
2295 struct smb_filename
*smb_fname
,
2296 files_struct
**result
)
2298 if (!VALID_STAT(smb_fname
->st
)) {
2299 return NT_STATUS_INVALID_PARAMETER
;
2302 return SMB_VFS_CREATE_FILE(
2305 0, /* root_dir_fid */
2306 smb_fname
, /* fname */
2307 FILE_WRITE_DATA
, /* access_mask */
2308 (FILE_SHARE_READ
| FILE_SHARE_WRITE
| /* share_access */
2310 FILE_OPEN
, /* create_disposition*/
2311 0, /* create_options */
2312 0, /* file_attributes */
2313 INTERNAL_OPEN_ONLY
, /* oplock_request */
2314 0, /* allocation_size */
2315 0, /* private_flags */
2318 result
, /* result */
2322 static NTSTATUS
mkdir_internal(connection_struct
*conn
,
2323 struct smb_filename
*smb_dname
,
2324 uint32 file_attributes
)
2329 bool posix_open
= false;
2331 if(!CAN_WRITE(conn
)) {
2332 DEBUG(5,("mkdir_internal: failing create on read-only share "
2333 "%s\n", lp_servicename(SNUM(conn
))));
2334 return NT_STATUS_ACCESS_DENIED
;
2337 status
= check_name(conn
, smb_dname
->base_name
);
2338 if (!NT_STATUS_IS_OK(status
)) {
2342 if (!parent_dirname(talloc_tos(), smb_dname
->base_name
, &parent_dir
,
2344 return NT_STATUS_NO_MEMORY
;
2347 if (file_attributes
& FILE_FLAG_POSIX_SEMANTICS
) {
2349 mode
= (mode_t
)(file_attributes
& ~FILE_FLAG_POSIX_SEMANTICS
);
2351 mode
= unix_mode(conn
, aDIR
, smb_dname
, parent_dir
);
2354 if (SMB_VFS_MKDIR(conn
, smb_dname
->base_name
, mode
) != 0) {
2355 return map_nt_error_from_unix(errno
);
2358 /* Ensure we're checking for a symlink here.... */
2359 /* We don't want to get caught by a symlink racer. */
2361 if (SMB_VFS_LSTAT(conn
, smb_dname
) == -1) {
2362 DEBUG(2, ("Could not stat directory '%s' just created: %s\n",
2363 smb_fname_str_dbg(smb_dname
), strerror(errno
)));
2364 return map_nt_error_from_unix(errno
);
2367 if (!S_ISDIR(smb_dname
->st
.st_ex_mode
)) {
2368 DEBUG(0, ("Directory just '%s' created is not a directory\n",
2369 smb_fname_str_dbg(smb_dname
)));
2370 return NT_STATUS_ACCESS_DENIED
;
2373 if (lp_store_dos_attributes(SNUM(conn
))) {
2375 file_set_dosmode(conn
, smb_dname
,
2376 file_attributes
| aDIR
,
2381 if (lp_inherit_perms(SNUM(conn
))) {
2382 inherit_access_posix_acl(conn
, parent_dir
,
2383 smb_dname
->base_name
, mode
);
2388 * Check if high bits should have been set,
2389 * then (if bits are missing): add them.
2390 * Consider bits automagically set by UNIX, i.e. SGID bit from parent
2393 if ((mode
& ~(S_IRWXU
|S_IRWXG
|S_IRWXO
)) &&
2394 (mode
& ~smb_dname
->st
.st_ex_mode
)) {
2395 SMB_VFS_CHMOD(conn
, smb_dname
->base_name
,
2396 (smb_dname
->st
.st_ex_mode
|
2397 (mode
& ~smb_dname
->st
.st_ex_mode
)));
2401 /* Change the owner if required. */
2402 if (lp_inherit_owner(SNUM(conn
))) {
2403 change_dir_owner_to_parent(conn
, parent_dir
,
2404 smb_dname
->base_name
,
2408 notify_fname(conn
, NOTIFY_ACTION_ADDED
, FILE_NOTIFY_CHANGE_DIR_NAME
,
2409 smb_dname
->base_name
);
2411 return NT_STATUS_OK
;
2414 /****************************************************************************
2415 Open a directory from an NT SMB call.
2416 ****************************************************************************/
2418 static NTSTATUS
open_directory(connection_struct
*conn
,
2419 struct smb_request
*req
,
2420 struct smb_filename
*smb_dname
,
2422 uint32 share_access
,
2423 uint32 create_disposition
,
2424 uint32 create_options
,
2425 uint32 file_attributes
,
2427 files_struct
**result
)
2429 files_struct
*fsp
= NULL
;
2430 bool dir_existed
= VALID_STAT(smb_dname
->st
) ? True
: False
;
2431 struct share_mode_lock
*lck
= NULL
;
2433 struct timespec mtimespec
;
2436 SMB_ASSERT(!is_ntfs_stream_smb_fname(smb_dname
));
2438 /* Ensure we have a directory attribute. */
2439 file_attributes
|= FILE_ATTRIBUTE_DIRECTORY
;
2441 DEBUG(5,("open_directory: opening directory %s, access_mask = 0x%x, "
2442 "share_access = 0x%x create_options = 0x%x, "
2443 "create_disposition = 0x%x, file_attributes = 0x%x\n",
2444 smb_fname_str_dbg(smb_dname
),
2445 (unsigned int)access_mask
,
2446 (unsigned int)share_access
,
2447 (unsigned int)create_options
,
2448 (unsigned int)create_disposition
,
2449 (unsigned int)file_attributes
));
2451 if (!(file_attributes
& FILE_FLAG_POSIX_SEMANTICS
) &&
2452 (conn
->fs_capabilities
& FILE_NAMED_STREAMS
) &&
2453 is_ntfs_stream_smb_fname(smb_dname
)) {
2454 DEBUG(2, ("open_directory: %s is a stream name!\n",
2455 smb_fname_str_dbg(smb_dname
)));
2456 return NT_STATUS_NOT_A_DIRECTORY
;
2459 status
= calculate_access_mask(conn
, smb_dname
, dir_existed
,
2460 access_mask
, &access_mask
);
2461 if (!NT_STATUS_IS_OK(status
)) {
2462 DEBUG(10, ("open_directory: calculate_access_mask "
2463 "on file %s returned %s\n",
2464 smb_fname_str_dbg(smb_dname
),
2465 nt_errstr(status
)));
2469 if ((access_mask
& SEC_FLAG_SYSTEM_SECURITY
) &&
2470 !security_token_has_privilege(get_current_nttok(conn
),
2471 SEC_PRIV_SECURITY
)) {
2472 DEBUG(10, ("open_directory: open on %s "
2473 "failed - SEC_FLAG_SYSTEM_SECURITY denied.\n",
2474 smb_fname_str_dbg(smb_dname
)));
2475 return NT_STATUS_PRIVILEGE_NOT_HELD
;
2478 switch( create_disposition
) {
2481 info
= FILE_WAS_OPENED
;
2484 * We want to follow symlinks here.
2487 if (SMB_VFS_STAT(conn
, smb_dname
) != 0) {
2488 return map_nt_error_from_unix(errno
);
2495 /* If directory exists error. If directory doesn't
2498 status
= mkdir_internal(conn
, smb_dname
,
2501 if (!NT_STATUS_IS_OK(status
)) {
2502 DEBUG(2, ("open_directory: unable to create "
2503 "%s. Error was %s\n",
2504 smb_fname_str_dbg(smb_dname
),
2505 nt_errstr(status
)));
2509 info
= FILE_WAS_CREATED
;
2514 * If directory exists open. If directory doesn't
2518 status
= mkdir_internal(conn
, smb_dname
,
2521 if (NT_STATUS_IS_OK(status
)) {
2522 info
= FILE_WAS_CREATED
;
2525 if (NT_STATUS_EQUAL(status
,
2526 NT_STATUS_OBJECT_NAME_COLLISION
)) {
2527 info
= FILE_WAS_OPENED
;
2528 status
= NT_STATUS_OK
;
2533 case FILE_SUPERSEDE
:
2534 case FILE_OVERWRITE
:
2535 case FILE_OVERWRITE_IF
:
2537 DEBUG(5,("open_directory: invalid create_disposition "
2538 "0x%x for directory %s\n",
2539 (unsigned int)create_disposition
,
2540 smb_fname_str_dbg(smb_dname
)));
2541 return NT_STATUS_INVALID_PARAMETER
;
2544 if(!S_ISDIR(smb_dname
->st
.st_ex_mode
)) {
2545 DEBUG(5,("open_directory: %s is not a directory !\n",
2546 smb_fname_str_dbg(smb_dname
)));
2547 return NT_STATUS_NOT_A_DIRECTORY
;
2550 if (info
== FILE_WAS_OPENED
) {
2551 uint32_t access_granted
= 0;
2552 status
= smbd_check_open_rights(conn
, smb_dname
, access_mask
,
2555 /* Were we trying to do a directory open
2556 * for delete and didn't get DELETE
2557 * access (only) ? Check if the
2558 * directory allows DELETE_CHILD.
2560 * http://blogs.msdn.com/oldnewthing/archive/2004/06/04/148426.aspx
2563 if ((NT_STATUS_EQUAL(status
, NT_STATUS_ACCESS_DENIED
) &&
2564 (access_mask
& DELETE_ACCESS
) &&
2565 (access_granted
== DELETE_ACCESS
) &&
2566 can_delete_file_in_directory(conn
, smb_dname
))) {
2567 DEBUG(10,("open_directory: overrode ACCESS_DENIED "
2568 "on directory %s\n",
2569 smb_fname_str_dbg(smb_dname
)));
2570 status
= NT_STATUS_OK
;
2573 if (!NT_STATUS_IS_OK(status
)) {
2574 DEBUG(10, ("open_directory: smbd_check_open_rights on "
2575 "file %s failed with %s\n",
2576 smb_fname_str_dbg(smb_dname
),
2577 nt_errstr(status
)));
2582 status
= file_new(req
, conn
, &fsp
);
2583 if(!NT_STATUS_IS_OK(status
)) {
2588 * Setup the files_struct for it.
2591 fsp
->mode
= smb_dname
->st
.st_ex_mode
;
2592 fsp
->file_id
= vfs_file_id_from_sbuf(conn
, &smb_dname
->st
);
2593 fsp
->vuid
= req
? req
->vuid
: UID_FIELD_INVALID
;
2594 fsp
->file_pid
= req
? req
->smbpid
: 0;
2595 fsp
->can_lock
= False
;
2596 fsp
->can_read
= False
;
2597 fsp
->can_write
= False
;
2599 fsp
->share_access
= share_access
;
2600 fsp
->fh
->private_options
= 0;
2602 * According to Samba4, SEC_FILE_READ_ATTRIBUTE is always granted,
2604 fsp
->access_mask
= access_mask
| FILE_READ_ATTRIBUTES
;
2605 fsp
->print_file
= NULL
;
2606 fsp
->modified
= False
;
2607 fsp
->oplock_type
= NO_OPLOCK
;
2608 fsp
->sent_oplock_break
= NO_BREAK_SENT
;
2609 fsp
->is_directory
= True
;
2610 fsp
->posix_open
= (file_attributes
& FILE_FLAG_POSIX_SEMANTICS
) ? True
: False
;
2611 status
= fsp_set_smb_fname(fsp
, smb_dname
);
2612 if (!NT_STATUS_IS_OK(status
)) {
2616 mtimespec
= smb_dname
->st
.st_ex_mtime
;
2618 lck
= get_share_mode_lock(talloc_tos(), fsp
->file_id
,
2619 conn
->connectpath
, smb_dname
, &mtimespec
);
2622 DEBUG(0, ("open_directory: Could not get share mode lock for "
2623 "%s\n", smb_fname_str_dbg(smb_dname
)));
2624 file_free(req
, fsp
);
2625 return NT_STATUS_SHARING_VIOLATION
;
2628 status
= open_mode_check(conn
, lck
, access_mask
, share_access
,
2629 create_options
, &dir_existed
);
2631 if (!NT_STATUS_IS_OK(status
)) {
2633 file_free(req
, fsp
);
2637 set_share_mode(lck
, fsp
, get_current_uid(conn
), 0, NO_OPLOCK
);
2639 /* For directories the delete on close bit at open time seems
2640 always to be honored on close... See test 19 in Samba4 BASE-DELETE. */
2641 if (create_options
& FILE_DELETE_ON_CLOSE
) {
2642 status
= can_set_delete_on_close(fsp
, 0);
2643 if (!NT_STATUS_IS_OK(status
) && !NT_STATUS_EQUAL(status
, NT_STATUS_DIRECTORY_NOT_EMPTY
)) {
2645 file_free(req
, fsp
);
2649 if (NT_STATUS_IS_OK(status
)) {
2650 /* Note that here we set the *inital* delete on close flag,
2651 not the regular one. The magic gets handled in close. */
2652 fsp
->initial_delete_on_close
= True
;
2663 return NT_STATUS_OK
;
2666 NTSTATUS
create_directory(connection_struct
*conn
, struct smb_request
*req
,
2667 struct smb_filename
*smb_dname
)
2672 status
= SMB_VFS_CREATE_FILE(
2675 0, /* root_dir_fid */
2676 smb_dname
, /* fname */
2677 FILE_READ_ATTRIBUTES
, /* access_mask */
2678 FILE_SHARE_NONE
, /* share_access */
2679 FILE_CREATE
, /* create_disposition*/
2680 FILE_DIRECTORY_FILE
, /* create_options */
2681 FILE_ATTRIBUTE_DIRECTORY
, /* file_attributes */
2682 0, /* oplock_request */
2683 0, /* allocation_size */
2684 0, /* private_flags */
2690 if (NT_STATUS_IS_OK(status
)) {
2691 close_file(req
, fsp
, NORMAL_CLOSE
);
2697 /****************************************************************************
2698 Receive notification that one of our open files has been renamed by another
2700 ****************************************************************************/
2702 void msg_file_was_renamed(struct messaging_context
*msg
,
2705 struct server_id server_id
,
2708 struct smbd_server_connection
*sconn
;
2710 char *frm
= (char *)data
->data
;
2712 const char *sharepath
;
2713 const char *base_name
;
2714 const char *stream_name
;
2715 struct smb_filename
*smb_fname
= NULL
;
2716 size_t sp_len
, bn_len
;
2719 sconn
= msg_ctx_to_sconn(msg
);
2720 if (sconn
== NULL
) {
2721 DEBUG(1, ("could not find sconn\n"));
2725 if (data
->data
== NULL
2726 || data
->length
< MSG_FILE_RENAMED_MIN_SIZE
+ 2) {
2727 DEBUG(0, ("msg_file_was_renamed: Got invalid msg len %d\n",
2728 (int)data
->length
));
2732 /* Unpack the message. */
2733 pull_file_id_24(frm
, &id
);
2734 sharepath
= &frm
[24];
2735 sp_len
= strlen(sharepath
);
2736 base_name
= sharepath
+ sp_len
+ 1;
2737 bn_len
= strlen(base_name
);
2738 stream_name
= sharepath
+ sp_len
+ 1 + bn_len
+ 1;
2740 /* stream_name must always be NULL if there is no stream. */
2741 if (stream_name
[0] == '\0') {
2745 status
= create_synthetic_smb_fname(talloc_tos(), base_name
,
2746 stream_name
, NULL
, &smb_fname
);
2747 if (!NT_STATUS_IS_OK(status
)) {
2751 DEBUG(10,("msg_file_was_renamed: Got rename message for sharepath %s, new name %s, "
2753 sharepath
, smb_fname_str_dbg(smb_fname
),
2754 file_id_string_tos(&id
)));
2756 for(fsp
= file_find_di_first(sconn
, id
); fsp
;
2757 fsp
= file_find_di_next(fsp
)) {
2758 if (memcmp(fsp
->conn
->connectpath
, sharepath
, sp_len
) == 0) {
2760 DEBUG(10,("msg_file_was_renamed: renaming file fnum %d from %s -> %s\n",
2761 fsp
->fnum
, fsp_str_dbg(fsp
),
2762 smb_fname_str_dbg(smb_fname
)));
2763 status
= fsp_set_smb_fname(fsp
, smb_fname
);
2764 if (!NT_STATUS_IS_OK(status
)) {
2769 /* Now we have the complete path we can work out if this is
2770 actually within this share and adjust newname accordingly. */
2771 DEBUG(10,("msg_file_was_renamed: share mismatch (sharepath %s "
2772 "not sharepath %s) "
2773 "fnum %d from %s -> %s\n",
2774 fsp
->conn
->connectpath
,
2778 smb_fname_str_dbg(smb_fname
)));
2782 TALLOC_FREE(smb_fname
);
2787 * If a main file is opened for delete, all streams need to be checked for
2788 * !FILE_SHARE_DELETE. Do this by opening with DELETE_ACCESS.
2789 * If that works, delete them all by setting the delete on close and close.
2792 NTSTATUS
open_streams_for_delete(connection_struct
*conn
,
2795 struct stream_struct
*stream_info
;
2796 files_struct
**streams
;
2798 unsigned int num_streams
;
2799 TALLOC_CTX
*frame
= talloc_stackframe();
2802 status
= SMB_VFS_STREAMINFO(conn
, NULL
, fname
, talloc_tos(),
2803 &num_streams
, &stream_info
);
2805 if (NT_STATUS_EQUAL(status
, NT_STATUS_NOT_IMPLEMENTED
)
2806 || NT_STATUS_EQUAL(status
, NT_STATUS_OBJECT_NAME_NOT_FOUND
)) {
2807 DEBUG(10, ("no streams around\n"));
2809 return NT_STATUS_OK
;
2812 if (!NT_STATUS_IS_OK(status
)) {
2813 DEBUG(10, ("SMB_VFS_STREAMINFO failed: %s\n",
2814 nt_errstr(status
)));
2818 DEBUG(10, ("open_streams_for_delete found %d streams\n",
2821 if (num_streams
== 0) {
2823 return NT_STATUS_OK
;
2826 streams
= TALLOC_ARRAY(talloc_tos(), files_struct
*, num_streams
);
2827 if (streams
== NULL
) {
2828 DEBUG(0, ("talloc failed\n"));
2829 status
= NT_STATUS_NO_MEMORY
;
2833 for (i
=0; i
<num_streams
; i
++) {
2834 struct smb_filename
*smb_fname
= NULL
;
2836 if (strequal(stream_info
[i
].name
, "::$DATA")) {
2841 status
= create_synthetic_smb_fname(talloc_tos(), fname
,
2842 stream_info
[i
].name
,
2844 if (!NT_STATUS_IS_OK(status
)) {
2848 if (SMB_VFS_STAT(conn
, smb_fname
) == -1) {
2849 DEBUG(10, ("Unable to stat stream: %s\n",
2850 smb_fname_str_dbg(smb_fname
)));
2853 status
= SMB_VFS_CREATE_FILE(
2856 0, /* root_dir_fid */
2857 smb_fname
, /* fname */
2858 DELETE_ACCESS
, /* access_mask */
2859 (FILE_SHARE_READ
| /* share_access */
2860 FILE_SHARE_WRITE
| FILE_SHARE_DELETE
),
2861 FILE_OPEN
, /* create_disposition*/
2862 0, /* create_options */
2863 FILE_ATTRIBUTE_NORMAL
, /* file_attributes */
2864 0, /* oplock_request */
2865 0, /* allocation_size */
2866 NTCREATEX_OPTIONS_PRIVATE_STREAM_DELETE
, /* private_flags */
2869 &streams
[i
], /* result */
2872 if (!NT_STATUS_IS_OK(status
)) {
2873 DEBUG(10, ("Could not open stream %s: %s\n",
2874 smb_fname_str_dbg(smb_fname
),
2875 nt_errstr(status
)));
2877 TALLOC_FREE(smb_fname
);
2880 TALLOC_FREE(smb_fname
);
2884 * don't touch the variable "status" beyond this point :-)
2887 for (i
-= 1 ; i
>= 0; i
--) {
2888 if (streams
[i
] == NULL
) {
2892 DEBUG(10, ("Closing stream # %d, %s\n", i
,
2893 fsp_str_dbg(streams
[i
])));
2894 close_file(NULL
, streams
[i
], NORMAL_CLOSE
);
2903 * Wrapper around open_file_ntcreate and open_directory
2906 static NTSTATUS
create_file_unixpath(connection_struct
*conn
,
2907 struct smb_request
*req
,
2908 struct smb_filename
*smb_fname
,
2909 uint32_t access_mask
,
2910 uint32_t share_access
,
2911 uint32_t create_disposition
,
2912 uint32_t create_options
,
2913 uint32_t file_attributes
,
2914 uint32_t oplock_request
,
2915 uint64_t allocation_size
,
2916 uint32_t private_flags
,
2917 struct security_descriptor
*sd
,
2918 struct ea_list
*ea_list
,
2920 files_struct
**result
,
2923 int info
= FILE_WAS_OPENED
;
2924 files_struct
*base_fsp
= NULL
;
2925 files_struct
*fsp
= NULL
;
2928 DEBUG(10,("create_file_unixpath: access_mask = 0x%x "
2929 "file_attributes = 0x%x, share_access = 0x%x, "
2930 "create_disposition = 0x%x create_options = 0x%x "
2931 "oplock_request = 0x%x private_flags = 0x%x "
2932 "ea_list = 0x%p, sd = 0x%p, "
2934 (unsigned int)access_mask
,
2935 (unsigned int)file_attributes
,
2936 (unsigned int)share_access
,
2937 (unsigned int)create_disposition
,
2938 (unsigned int)create_options
,
2939 (unsigned int)oplock_request
,
2940 (unsigned int)private_flags
,
2941 ea_list
, sd
, smb_fname_str_dbg(smb_fname
)));
2943 if (create_options
& FILE_OPEN_BY_FILE_ID
) {
2944 status
= NT_STATUS_NOT_SUPPORTED
;
2948 if (create_options
& NTCREATEX_OPTIONS_INVALID_PARAM_MASK
) {
2949 status
= NT_STATUS_INVALID_PARAMETER
;
2954 oplock_request
|= INTERNAL_OPEN_ONLY
;
2957 if ((conn
->fs_capabilities
& FILE_NAMED_STREAMS
)
2958 && (access_mask
& DELETE_ACCESS
)
2959 && !is_ntfs_stream_smb_fname(smb_fname
)) {
2961 * We can't open a file with DELETE access if any of the
2962 * streams is open without FILE_SHARE_DELETE
2964 status
= open_streams_for_delete(conn
, smb_fname
->base_name
);
2966 if (!NT_STATUS_IS_OK(status
)) {
2971 /* This is the correct thing to do (check every time) but can_delete
2972 * is expensive (it may have to read the parent directory
2973 * permissions). So for now we're not doing it unless we have a strong
2974 * hint the client is really going to delete this file. If the client
2975 * is forcing FILE_CREATE let the filesystem take care of the
2978 /* Setting FILE_SHARE_DELETE is the hint. */
2980 if (lp_acl_check_permissions(SNUM(conn
))
2981 && (create_disposition
!= FILE_CREATE
)
2982 && (share_access
& FILE_SHARE_DELETE
)
2983 && (access_mask
& DELETE_ACCESS
)
2984 && (!(can_delete_file_in_directory(conn
, smb_fname
) ||
2985 can_access_file_acl(conn
, smb_fname
, DELETE_ACCESS
)))) {
2986 status
= NT_STATUS_ACCESS_DENIED
;
2987 DEBUG(10,("create_file_unixpath: open file %s "
2988 "for delete ACCESS_DENIED\n",
2989 smb_fname_str_dbg(smb_fname
)));
2993 if ((access_mask
& SEC_FLAG_SYSTEM_SECURITY
) &&
2994 !security_token_has_privilege(get_current_nttok(conn
),
2995 SEC_PRIV_SECURITY
)) {
2996 DEBUG(10, ("create_file_unixpath: open on %s "
2997 "failed - SEC_FLAG_SYSTEM_SECURITY denied.\n",
2998 smb_fname_str_dbg(smb_fname
)));
2999 status
= NT_STATUS_PRIVILEGE_NOT_HELD
;
3003 if ((conn
->fs_capabilities
& FILE_NAMED_STREAMS
)
3004 && is_ntfs_stream_smb_fname(smb_fname
)
3005 && (!(private_flags
& NTCREATEX_OPTIONS_PRIVATE_STREAM_DELETE
))) {
3006 uint32 base_create_disposition
;
3007 struct smb_filename
*smb_fname_base
= NULL
;
3009 if (create_options
& FILE_DIRECTORY_FILE
) {
3010 status
= NT_STATUS_NOT_A_DIRECTORY
;
3014 switch (create_disposition
) {
3016 base_create_disposition
= FILE_OPEN
;
3019 base_create_disposition
= FILE_OPEN_IF
;
3023 /* Create an smb_filename with stream_name == NULL. */
3024 status
= create_synthetic_smb_fname(talloc_tos(),
3025 smb_fname
->base_name
,
3028 if (!NT_STATUS_IS_OK(status
)) {
3032 if (SMB_VFS_STAT(conn
, smb_fname_base
) == -1) {
3033 DEBUG(10, ("Unable to stat stream: %s\n",
3034 smb_fname_str_dbg(smb_fname_base
)));
3037 /* Open the base file. */
3038 status
= create_file_unixpath(conn
, NULL
, smb_fname_base
, 0,
3041 | FILE_SHARE_DELETE
,
3042 base_create_disposition
,
3043 0, 0, 0, 0, 0, NULL
, NULL
,
3045 TALLOC_FREE(smb_fname_base
);
3047 if (!NT_STATUS_IS_OK(status
)) {
3048 DEBUG(10, ("create_file_unixpath for base %s failed: "
3049 "%s\n", smb_fname
->base_name
,
3050 nt_errstr(status
)));
3053 /* we don't need to low level fd */
3058 * If it's a request for a directory open, deal with it separately.
3061 if (create_options
& FILE_DIRECTORY_FILE
) {
3063 if (create_options
& FILE_NON_DIRECTORY_FILE
) {
3064 status
= NT_STATUS_INVALID_PARAMETER
;
3068 /* Can't open a temp directory. IFS kit test. */
3069 if (!(file_attributes
& FILE_FLAG_POSIX_SEMANTICS
) &&
3070 (file_attributes
& FILE_ATTRIBUTE_TEMPORARY
)) {
3071 status
= NT_STATUS_INVALID_PARAMETER
;
3076 * We will get a create directory here if the Win32
3077 * app specified a security descriptor in the
3078 * CreateDirectory() call.
3082 status
= open_directory(
3083 conn
, req
, smb_fname
, access_mask
, share_access
,
3084 create_disposition
, create_options
, file_attributes
,
3089 * Ordinary file case.
3092 status
= file_new(req
, conn
, &fsp
);
3093 if(!NT_STATUS_IS_OK(status
)) {
3097 status
= fsp_set_smb_fname(fsp
, smb_fname
);
3098 if (!NT_STATUS_IS_OK(status
)) {
3103 * We're opening the stream element of a base_fsp
3104 * we already opened. Set up the base_fsp pointer.
3107 fsp
->base_fsp
= base_fsp
;
3110 status
= open_file_ntcreate(conn
,
3122 if(!NT_STATUS_IS_OK(status
)) {
3123 file_free(req
, fsp
);
3127 if (NT_STATUS_EQUAL(status
, NT_STATUS_FILE_IS_A_DIRECTORY
)) {
3129 /* A stream open never opens a directory */
3132 status
= NT_STATUS_FILE_IS_A_DIRECTORY
;
3137 * Fail the open if it was explicitly a non-directory
3141 if (create_options
& FILE_NON_DIRECTORY_FILE
) {
3142 status
= NT_STATUS_FILE_IS_A_DIRECTORY
;
3147 status
= open_directory(
3148 conn
, req
, smb_fname
, access_mask
,
3149 share_access
, create_disposition
,
3150 create_options
, file_attributes
,
3155 if (!NT_STATUS_IS_OK(status
)) {
3159 fsp
->base_fsp
= base_fsp
;
3162 * According to the MS documentation, the only time the security
3163 * descriptor is applied to the opened file is iff we *created* the
3164 * file; an existing file stays the same.
3166 * Also, it seems (from observation) that you can open the file with
3167 * any access mask but you can still write the sd. We need to override
3168 * the granted access before we call set_sd
3169 * Patch for bug #2242 from Tom Lackemann <cessnatomny@yahoo.com>.
3172 if ((sd
!= NULL
) && (info
== FILE_WAS_CREATED
)
3173 && lp_nt_acl_support(SNUM(conn
))) {
3175 uint32_t sec_info_sent
;
3176 uint32_t saved_access_mask
= fsp
->access_mask
;
3178 sec_info_sent
= get_sec_info(sd
);
3180 fsp
->access_mask
= FILE_GENERIC_ALL
;
3182 /* Convert all the generic bits. */
3183 security_acl_map_generic(sd
->dacl
, &file_generic_mapping
);
3184 security_acl_map_generic(sd
->sacl
, &file_generic_mapping
);
3186 if (sec_info_sent
& (SECINFO_OWNER
|
3190 status
= SMB_VFS_FSET_NT_ACL(fsp
, sec_info_sent
, sd
);
3193 fsp
->access_mask
= saved_access_mask
;
3195 if (!NT_STATUS_IS_OK(status
)) {
3200 if ((ea_list
!= NULL
) &&
3201 ((info
== FILE_WAS_CREATED
) || (info
== FILE_WAS_OVERWRITTEN
))) {
3202 status
= set_ea(conn
, fsp
, fsp
->fsp_name
, ea_list
);
3203 if (!NT_STATUS_IS_OK(status
)) {
3208 if (!fsp
->is_directory
&& S_ISDIR(fsp
->fsp_name
->st
.st_ex_mode
)) {
3209 status
= NT_STATUS_ACCESS_DENIED
;
3213 /* Save the requested allocation size. */
3214 if ((info
== FILE_WAS_CREATED
) || (info
== FILE_WAS_OVERWRITTEN
)) {
3216 && (allocation_size
> fsp
->fsp_name
->st
.st_ex_size
)) {
3217 fsp
->initial_allocation_size
= smb_roundup(
3218 fsp
->conn
, allocation_size
);
3219 if (fsp
->is_directory
) {
3220 /* Can't set allocation size on a directory. */
3221 status
= NT_STATUS_ACCESS_DENIED
;
3224 if (vfs_allocate_file_space(
3225 fsp
, fsp
->initial_allocation_size
) == -1) {
3226 status
= NT_STATUS_DISK_FULL
;
3230 fsp
->initial_allocation_size
= smb_roundup(
3231 fsp
->conn
, (uint64_t)fsp
->fsp_name
->st
.st_ex_size
);
3235 DEBUG(10, ("create_file_unixpath: info=%d\n", info
));
3238 if (pinfo
!= NULL
) {
3242 smb_fname
->st
= fsp
->fsp_name
->st
;
3244 return NT_STATUS_OK
;
3247 DEBUG(10, ("create_file_unixpath: %s\n", nt_errstr(status
)));
3250 if (base_fsp
&& fsp
->base_fsp
== base_fsp
) {
3252 * The close_file below will close
3257 close_file(req
, fsp
, ERROR_CLOSE
);
3260 if (base_fsp
!= NULL
) {
3261 close_file(req
, base_fsp
, ERROR_CLOSE
);
3268 * Calculate the full path name given a relative fid.
3270 NTSTATUS
get_relative_fid_filename(connection_struct
*conn
,
3271 struct smb_request
*req
,
3272 uint16_t root_dir_fid
,
3273 struct smb_filename
*smb_fname
)
3275 files_struct
*dir_fsp
;
3276 char *parent_fname
= NULL
;
3277 char *new_base_name
= NULL
;
3280 if (root_dir_fid
== 0 || !smb_fname
) {
3281 status
= NT_STATUS_INTERNAL_ERROR
;
3285 dir_fsp
= file_fsp(req
, root_dir_fid
);
3287 if (dir_fsp
== NULL
) {
3288 status
= NT_STATUS_INVALID_HANDLE
;
3292 if (is_ntfs_stream_smb_fname(dir_fsp
->fsp_name
)) {
3293 status
= NT_STATUS_INVALID_HANDLE
;
3297 if (!dir_fsp
->is_directory
) {
3300 * Check to see if this is a mac fork of some kind.
3303 if ((conn
->fs_capabilities
& FILE_NAMED_STREAMS
) &&
3304 is_ntfs_stream_smb_fname(smb_fname
)) {
3305 status
= NT_STATUS_OBJECT_PATH_NOT_FOUND
;
3310 we need to handle the case when we get a
3311 relative open relative to a file and the
3312 pathname is blank - this is a reopen!
3313 (hint from demyn plantenberg)
3316 status
= NT_STATUS_INVALID_HANDLE
;
3320 if (ISDOT(dir_fsp
->fsp_name
->base_name
)) {
3322 * We're at the toplevel dir, the final file name
3323 * must not contain ./, as this is filtered out
3324 * normally by srvstr_get_path and unix_convert
3325 * explicitly rejects paths containing ./.
3327 parent_fname
= talloc_strdup(talloc_tos(), "");
3328 if (parent_fname
== NULL
) {
3329 status
= NT_STATUS_NO_MEMORY
;
3333 size_t dir_name_len
= strlen(dir_fsp
->fsp_name
->base_name
);
3336 * Copy in the base directory name.
3339 parent_fname
= TALLOC_ARRAY(talloc_tos(), char,
3341 if (parent_fname
== NULL
) {
3342 status
= NT_STATUS_NO_MEMORY
;
3345 memcpy(parent_fname
, dir_fsp
->fsp_name
->base_name
,
3349 * Ensure it ends in a '/'.
3350 * We used TALLOC_SIZE +2 to add space for the '/'.
3354 && (parent_fname
[dir_name_len
-1] != '\\')
3355 && (parent_fname
[dir_name_len
-1] != '/')) {
3356 parent_fname
[dir_name_len
] = '/';
3357 parent_fname
[dir_name_len
+1] = '\0';
3361 new_base_name
= talloc_asprintf(smb_fname
, "%s%s", parent_fname
,
3362 smb_fname
->base_name
);
3363 if (new_base_name
== NULL
) {
3364 status
= NT_STATUS_NO_MEMORY
;
3368 TALLOC_FREE(smb_fname
->base_name
);
3369 smb_fname
->base_name
= new_base_name
;
3370 status
= NT_STATUS_OK
;
3373 TALLOC_FREE(parent_fname
);
3377 NTSTATUS
create_file_default(connection_struct
*conn
,
3378 struct smb_request
*req
,
3379 uint16_t root_dir_fid
,
3380 struct smb_filename
*smb_fname
,
3381 uint32_t access_mask
,
3382 uint32_t share_access
,
3383 uint32_t create_disposition
,
3384 uint32_t create_options
,
3385 uint32_t file_attributes
,
3386 uint32_t oplock_request
,
3387 uint64_t allocation_size
,
3388 uint32_t private_flags
,
3389 struct security_descriptor
*sd
,
3390 struct ea_list
*ea_list
,
3391 files_struct
**result
,
3394 int info
= FILE_WAS_OPENED
;
3395 files_struct
*fsp
= NULL
;
3397 bool stream_name
= false;
3399 DEBUG(10,("create_file: access_mask = 0x%x "
3400 "file_attributes = 0x%x, share_access = 0x%x, "
3401 "create_disposition = 0x%x create_options = 0x%x "
3402 "oplock_request = 0x%x "
3403 "private_flags = 0x%x "
3404 "root_dir_fid = 0x%x, ea_list = 0x%p, sd = 0x%p, "
3406 (unsigned int)access_mask
,
3407 (unsigned int)file_attributes
,
3408 (unsigned int)share_access
,
3409 (unsigned int)create_disposition
,
3410 (unsigned int)create_options
,
3411 (unsigned int)oplock_request
,
3412 (unsigned int)private_flags
,
3413 (unsigned int)root_dir_fid
,
3414 ea_list
, sd
, smb_fname_str_dbg(smb_fname
)));
3417 * Calculate the filename from the root_dir_if if necessary.
3420 if (root_dir_fid
!= 0) {
3421 status
= get_relative_fid_filename(conn
, req
, root_dir_fid
,
3423 if (!NT_STATUS_IS_OK(status
)) {
3429 * Check to see if this is a mac fork of some kind.
3432 stream_name
= is_ntfs_stream_smb_fname(smb_fname
);
3434 enum FAKE_FILE_TYPE fake_file_type
;
3436 fake_file_type
= is_fake_file(smb_fname
);
3438 if (fake_file_type
!= FAKE_FILE_TYPE_NONE
) {
3441 * Here we go! support for changing the disk quotas
3444 * We need to fake up to open this MAGIC QUOTA file
3445 * and return a valid FID.
3447 * w2k close this file directly after openening xp
3448 * also tries a QUERY_FILE_INFO on the file and then
3451 status
= open_fake_file(req
, conn
, req
->vuid
,
3452 fake_file_type
, smb_fname
,
3454 if (!NT_STATUS_IS_OK(status
)) {
3458 ZERO_STRUCT(smb_fname
->st
);
3462 if (!(conn
->fs_capabilities
& FILE_NAMED_STREAMS
)) {
3463 status
= NT_STATUS_OBJECT_NAME_NOT_FOUND
;
3468 /* All file access must go through check_name() */
3470 status
= check_name(conn
, smb_fname
->base_name
);
3471 if (!NT_STATUS_IS_OK(status
)) {
3475 if (stream_name
&& is_ntfs_default_stream_smb_fname(smb_fname
)) {
3477 smb_fname
->stream_name
= NULL
;
3478 /* We have to handle this error here. */
3479 if (create_options
& FILE_DIRECTORY_FILE
) {
3480 status
= NT_STATUS_NOT_A_DIRECTORY
;
3483 if (lp_posix_pathnames()) {
3484 ret
= SMB_VFS_LSTAT(conn
, smb_fname
);
3486 ret
= SMB_VFS_STAT(conn
, smb_fname
);
3489 if (ret
== 0 && VALID_STAT_OF_DIR(smb_fname
->st
)) {
3490 status
= NT_STATUS_FILE_IS_A_DIRECTORY
;
3495 status
= create_file_unixpath(
3496 conn
, req
, smb_fname
, access_mask
, share_access
,
3497 create_disposition
, create_options
, file_attributes
,
3498 oplock_request
, allocation_size
, private_flags
,
3502 if (!NT_STATUS_IS_OK(status
)) {
3507 DEBUG(10, ("create_file: info=%d\n", info
));
3510 if (pinfo
!= NULL
) {
3513 return NT_STATUS_OK
;
3516 DEBUG(10, ("create_file: %s\n", nt_errstr(status
)));
3519 close_file(req
, fsp
, ERROR_CLOSE
);