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/>.
23 #include "smbd/globals.h"
25 extern const struct generic_mapping file_generic_mapping;
27 struct deferred_open_record {
28 bool delayed_for_oplocks;
32 static NTSTATUS create_file_unixpath(connection_struct *conn,
33 struct smb_request *req,
34 struct smb_filename *smb_fname,
36 uint32_t share_access,
37 uint32_t create_disposition,
38 uint32_t create_options,
39 uint32_t file_attributes,
40 uint32_t oplock_request,
41 uint64_t allocation_size,
42 uint32_t private_flags,
43 struct security_descriptor *sd,
44 struct ea_list *ea_list,
46 files_struct **result,
49 /****************************************************************************
50 SMB1 file varient of se_access_check. Never test FILE_READ_ATTRIBUTES.
51 ****************************************************************************/
53 NTSTATUS smb1_file_se_access_check(struct connection_struct *conn,
54 const struct security_descriptor *sd,
55 const NT_USER_TOKEN *token,
56 uint32_t access_desired,
57 uint32_t *access_granted)
61 if (get_current_uid(conn) == (uid_t)0) {
62 /* I'm sorry sir, I didn't know you were root... */
63 *access_granted = access_desired;
64 if (access_desired & SEC_FLAG_MAXIMUM_ALLOWED) {
65 *access_granted |= FILE_GENERIC_ALL;
70 return se_access_check(sd,
72 (access_desired & ~FILE_READ_ATTRIBUTES),
76 /****************************************************************************
77 Check if we have open rights.
78 ****************************************************************************/
80 NTSTATUS smbd_check_open_rights(struct connection_struct *conn,
81 const struct smb_filename *smb_fname,
83 uint32_t *access_granted)
85 /* Check if we have rights to open. */
87 struct security_descriptor *sd = NULL;
89 status = SMB_VFS_GET_NT_ACL(conn, smb_fname->base_name,
90 (OWNER_SECURITY_INFORMATION |
91 GROUP_SECURITY_INFORMATION |
92 DACL_SECURITY_INFORMATION),&sd);
94 if (!NT_STATUS_IS_OK(status)) {
95 DEBUG(10, ("smbd_check_open_rights: Could not get acl "
97 smb_fname_str_dbg(smb_fname),
102 status = smb1_file_se_access_check(conn,
104 get_current_nttok(conn),
108 DEBUG(10,("smbd_check_open_rights: file %s requesting "
109 "0x%x returning 0x%x (%s)\n",
110 smb_fname_str_dbg(smb_fname),
111 (unsigned int)access_mask,
112 (unsigned int)*access_granted,
113 nt_errstr(status) ));
115 if (!NT_STATUS_IS_OK(status)) {
116 if (DEBUGLEVEL >= 10) {
117 DEBUG(10,("smbd_check_open_rights: acl for %s is:\n",
118 smb_fname_str_dbg(smb_fname) ));
119 NDR_PRINT_DEBUG(security_descriptor, sd);
128 /****************************************************************************
129 fd support routines - attempt to do a dos_open.
130 ****************************************************************************/
132 static NTSTATUS fd_open(struct connection_struct *conn,
137 struct smb_filename *smb_fname = fsp->fsp_name;
138 NTSTATUS status = NT_STATUS_OK;
142 * Never follow symlinks on a POSIX client. The
143 * client should be doing this.
146 if (fsp->posix_open || !lp_symlinks(SNUM(conn))) {
151 fsp->fh->fd = SMB_VFS_OPEN(conn, smb_fname, fsp, flags, mode);
152 if (fsp->fh->fd == -1) {
153 status = map_nt_error_from_unix(errno);
154 if (errno == EMFILE) {
155 static time_t last_warned = 0L;
157 if (time((time_t *) NULL) > last_warned) {
158 DEBUG(0,("Too many open files, unable "
159 "to open more! smbd's max "
161 lp_max_open_files()));
162 last_warned = time((time_t *) NULL);
168 DEBUG(10,("fd_open: name %s, flags = 0%o mode = 0%o, fd = %d. %s\n",
169 smb_fname_str_dbg(smb_fname), flags, (int)mode, fsp->fh->fd,
170 (fsp->fh->fd == -1) ? strerror(errno) : "" ));
175 /****************************************************************************
176 Close the file associated with a fsp.
177 ****************************************************************************/
179 NTSTATUS fd_close(files_struct *fsp)
183 if (fsp->fh->fd == -1) {
184 return NT_STATUS_OK; /* What we used to call a stat open. */
186 if (fsp->fh->ref_count > 1) {
187 return NT_STATUS_OK; /* Shared handle. Only close last reference. */
190 ret = SMB_VFS_CLOSE(fsp);
193 return map_nt_error_from_unix(errno);
198 /****************************************************************************
199 Change the ownership of a file to that of the parent directory.
200 Do this by fd if possible.
201 ****************************************************************************/
203 void change_file_owner_to_parent(connection_struct *conn,
204 const char *inherit_from_dir,
207 struct smb_filename *smb_fname_parent = NULL;
211 status = create_synthetic_smb_fname(talloc_tos(), inherit_from_dir,
212 NULL, NULL, &smb_fname_parent);
213 if (!NT_STATUS_IS_OK(status)) {
217 ret = SMB_VFS_STAT(conn, smb_fname_parent);
219 DEBUG(0,("change_file_owner_to_parent: failed to stat parent "
220 "directory %s. Error was %s\n",
221 smb_fname_str_dbg(smb_fname_parent),
227 ret = SMB_VFS_FCHOWN(fsp, smb_fname_parent->st.st_ex_uid, (gid_t)-1);
230 DEBUG(0,("change_file_owner_to_parent: failed to fchown "
231 "file %s to parent directory uid %u. Error "
232 "was %s\n", fsp_str_dbg(fsp),
233 (unsigned int)smb_fname_parent->st.st_ex_uid,
237 DEBUG(10,("change_file_owner_to_parent: changed new file %s to "
238 "parent directory uid %u.\n", fsp_str_dbg(fsp),
239 (unsigned int)smb_fname_parent->st.st_ex_uid));
241 TALLOC_FREE(smb_fname_parent);
244 NTSTATUS change_dir_owner_to_parent(connection_struct *conn,
245 const char *inherit_from_dir,
247 SMB_STRUCT_STAT *psbuf)
249 struct smb_filename *smb_fname_parent = NULL;
250 struct smb_filename *smb_fname_cwd = NULL;
251 char *saved_dir = NULL;
252 TALLOC_CTX *ctx = talloc_tos();
253 NTSTATUS status = NT_STATUS_OK;
256 status = create_synthetic_smb_fname(ctx, inherit_from_dir, NULL, NULL,
258 if (!NT_STATUS_IS_OK(status)) {
262 ret = SMB_VFS_STAT(conn, smb_fname_parent);
264 status = map_nt_error_from_unix(errno);
265 DEBUG(0,("change_dir_owner_to_parent: failed to stat parent "
266 "directory %s. Error was %s\n",
267 smb_fname_str_dbg(smb_fname_parent),
272 /* We've already done an lstat into psbuf, and we know it's a
273 directory. If we can cd into the directory and the dev/ino
274 are the same then we can safely chown without races as
275 we're locking the directory in place by being in it. This
276 should work on any UNIX (thanks tridge :-). JRA.
279 saved_dir = vfs_GetWd(ctx,conn);
281 status = map_nt_error_from_unix(errno);
282 DEBUG(0,("change_dir_owner_to_parent: failed to get "
283 "current working directory. Error was %s\n",
288 /* Chdir into the new path. */
289 if (vfs_ChDir(conn, fname) == -1) {
290 status = map_nt_error_from_unix(errno);
291 DEBUG(0,("change_dir_owner_to_parent: failed to change "
292 "current working directory to %s. Error "
293 "was %s\n", fname, strerror(errno) ));
297 status = create_synthetic_smb_fname(ctx, ".", NULL, NULL,
299 if (!NT_STATUS_IS_OK(status)) {
303 ret = SMB_VFS_STAT(conn, smb_fname_cwd);
305 status = map_nt_error_from_unix(errno);
306 DEBUG(0,("change_dir_owner_to_parent: failed to stat "
307 "directory '.' (%s) Error was %s\n",
308 fname, strerror(errno)));
312 /* Ensure we're pointing at the same place. */
313 if (smb_fname_cwd->st.st_ex_dev != psbuf->st_ex_dev ||
314 smb_fname_cwd->st.st_ex_ino != psbuf->st_ex_ino ||
315 smb_fname_cwd->st.st_ex_mode != psbuf->st_ex_mode ) {
316 DEBUG(0,("change_dir_owner_to_parent: "
317 "device/inode/mode on directory %s changed. "
318 "Refusing to chown !\n", fname ));
319 status = NT_STATUS_ACCESS_DENIED;
324 ret = SMB_VFS_CHOWN(conn, ".", smb_fname_parent->st.st_ex_uid,
328 status = map_nt_error_from_unix(errno);
329 DEBUG(10,("change_dir_owner_to_parent: failed to chown "
330 "directory %s to parent directory uid %u. "
331 "Error was %s\n", fname,
332 (unsigned int)smb_fname_parent->st.st_ex_uid,
337 DEBUG(10,("change_dir_owner_to_parent: changed ownership of new "
338 "directory %s to parent directory uid %u.\n",
339 fname, (unsigned int)smb_fname_parent->st.st_ex_uid ));
342 vfs_ChDir(conn,saved_dir);
344 TALLOC_FREE(smb_fname_parent);
345 TALLOC_FREE(smb_fname_cwd);
349 /****************************************************************************
351 ****************************************************************************/
353 static NTSTATUS open_file(files_struct *fsp,
354 connection_struct *conn,
355 struct smb_request *req,
356 const char *parent_dir,
359 uint32 access_mask, /* client requested access mask. */
360 uint32 open_access_mask) /* what we're actually using in the open. */
362 struct smb_filename *smb_fname = fsp->fsp_name;
363 NTSTATUS status = NT_STATUS_OK;
364 int accmode = (flags & O_ACCMODE);
365 int local_flags = flags;
366 bool file_existed = VALID_STAT(fsp->fsp_name->st);
371 /* Check permissions */
374 * This code was changed after seeing a client open request
375 * containing the open mode of (DENY_WRITE/read-only) with
376 * the 'create if not exist' bit set. The previous code
377 * would fail to open the file read only on a read-only share
378 * as it was checking the flags parameter directly against O_RDONLY,
379 * this was failing as the flags parameter was set to O_RDONLY|O_CREAT.
383 if (!CAN_WRITE(conn)) {
384 /* It's a read-only share - fail if we wanted to write. */
385 if(accmode != O_RDONLY || (flags & O_TRUNC) || (flags & O_APPEND)) {
386 DEBUG(3,("Permission denied opening %s\n",
387 smb_fname_str_dbg(smb_fname)));
388 return NT_STATUS_ACCESS_DENIED;
389 } else if(flags & O_CREAT) {
390 /* We don't want to write - but we must make sure that
391 O_CREAT doesn't create the file if we have write
392 access into the directory.
394 flags &= ~(O_CREAT|O_EXCL);
395 local_flags &= ~(O_CREAT|O_EXCL);
400 * This little piece of insanity is inspired by the
401 * fact that an NT client can open a file for O_RDONLY,
402 * but set the create disposition to FILE_EXISTS_TRUNCATE.
403 * If the client *can* write to the file, then it expects to
404 * truncate the file, even though it is opening for readonly.
405 * Quicken uses this stupid trick in backup file creation...
406 * Thanks *greatly* to "David W. Chapman Jr." <dwcjr@inethouston.net>
407 * for helping track this one down. It didn't bite us in 2.0.x
408 * as we always opened files read-write in that release. JRA.
411 if ((accmode == O_RDONLY) && ((flags & O_TRUNC) == O_TRUNC)) {
412 DEBUG(10,("open_file: truncate requested on read-only open "
413 "for file %s\n", smb_fname_str_dbg(smb_fname)));
414 local_flags = (flags & ~O_ACCMODE)|O_RDWR;
417 if ((open_access_mask & (FILE_READ_DATA|FILE_WRITE_DATA|FILE_APPEND_DATA|FILE_EXECUTE)) ||
418 (!file_existed && (local_flags & O_CREAT)) ||
419 ((local_flags & O_TRUNC) == O_TRUNC) ) {
423 * We can't actually truncate here as the file may be locked.
424 * open_file_ntcreate will take care of the truncate later. JRA.
427 local_flags &= ~O_TRUNC;
429 #if defined(O_NONBLOCK) && defined(S_ISFIFO)
431 * We would block on opening a FIFO with no one else on the
432 * other end. Do what we used to do and add O_NONBLOCK to the
436 if (file_existed && S_ISFIFO(smb_fname->st.st_ex_mode)) {
437 local_flags |= O_NONBLOCK;
441 /* Don't create files with Microsoft wildcard characters. */
444 * wildcard characters are allowed in stream names
445 * only test the basefilename
447 wild = fsp->base_fsp->fsp_name->base_name;
449 wild = smb_fname->base_name;
451 if ((local_flags & O_CREAT) && !file_existed &&
453 return NT_STATUS_OBJECT_NAME_INVALID;
456 /* Actually do the open */
457 status = fd_open(conn, fsp, local_flags, unx_mode);
458 if (!NT_STATUS_IS_OK(status)) {
459 DEBUG(3,("Error opening file %s (%s) (local_flags=%d) "
460 "(flags=%d)\n", smb_fname_str_dbg(smb_fname),
461 nt_errstr(status),local_flags,flags));
465 if ((local_flags & O_CREAT) && !file_existed) {
467 /* Inherit the ACL if required */
468 if (lp_inherit_perms(SNUM(conn))) {
469 inherit_access_posix_acl(conn, parent_dir,
470 smb_fname->base_name,
474 /* Change the owner if required. */
475 if (lp_inherit_owner(SNUM(conn))) {
476 change_file_owner_to_parent(conn, parent_dir,
480 notify_fname(conn, NOTIFY_ACTION_ADDED,
481 FILE_NOTIFY_CHANGE_FILE_NAME,
482 smb_fname->base_name);
486 fsp->fh->fd = -1; /* What we used to call a stat open. */
488 uint32_t access_granted = 0;
490 status = smbd_check_open_rights(conn,
494 if (!NT_STATUS_IS_OK(status)) {
495 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
497 * On NT_STATUS_ACCESS_DENIED, access_granted
498 * contains the denied bits.
501 if ((access_mask & FILE_WRITE_ATTRIBUTES) &&
502 (access_granted & FILE_WRITE_ATTRIBUTES) &&
503 (lp_map_readonly(SNUM(conn)) ||
504 lp_map_archive(SNUM(conn)) ||
505 lp_map_hidden(SNUM(conn)) ||
506 lp_map_system(SNUM(conn)))) {
507 access_granted &= ~FILE_WRITE_ATTRIBUTES;
509 DEBUG(10,("open_file: "
518 if ((access_mask & DELETE_ACCESS) &&
519 (access_granted & DELETE_ACCESS) &&
520 can_delete_file_in_directory(conn,
522 /* Were we trying to do a stat open
523 * for delete and didn't get DELETE
524 * access (only) ? Check if the
525 * directory allows DELETE_CHILD.
527 * http://blogs.msdn.com/oldnewthing/archive/2004/06/04/148426.aspx
530 access_granted &= ~DELETE_ACCESS;
532 DEBUG(10,("open_file: "
540 if (access_granted != 0) {
541 DEBUG(10,("open_file: Access "
548 } else if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND) &&
550 S_ISLNK(smb_fname->st.st_ex_mode)) {
551 /* This is a POSIX stat open for delete
552 * or rename on a symlink that points
554 DEBUG(10,("open_file: allowing POSIX "
555 "open on bad symlink %s\n",
559 DEBUG(10,("open_file: "
560 "smbd_check_open_rights on file "
562 smb_fname_str_dbg(smb_fname),
563 nt_errstr(status) ));
573 if (fsp->fh->fd == -1) {
574 ret = SMB_VFS_STAT(conn, smb_fname);
576 ret = SMB_VFS_FSTAT(fsp, &smb_fname->st);
577 /* If we have an fd, this stat should succeed. */
579 DEBUG(0,("Error doing fstat on open file %s "
581 smb_fname_str_dbg(smb_fname),
586 /* For a non-io open, this stat failing means file not found. JRA */
588 status = map_nt_error_from_unix(errno);
595 * POSIX allows read-only opens of directories. We don't
596 * want to do this (we use a different code path for this)
597 * so catch a directory open and return an EISDIR. JRA.
600 if(S_ISDIR(smb_fname->st.st_ex_mode)) {
603 return NT_STATUS_FILE_IS_A_DIRECTORY;
606 fsp->mode = smb_fname->st.st_ex_mode;
607 fsp->file_id = vfs_file_id_from_sbuf(conn, &smb_fname->st);
608 fsp->vuid = req ? req->vuid : UID_FIELD_INVALID;
609 fsp->file_pid = req ? req->smbpid : 0;
610 fsp->can_lock = True;
611 fsp->can_read = (access_mask & (FILE_READ_DATA)) ? True : False;
612 if (!CAN_WRITE(conn)) {
613 fsp->can_write = False;
615 fsp->can_write = (access_mask & (FILE_WRITE_DATA | FILE_APPEND_DATA)) ?
618 fsp->print_file = False;
619 fsp->modified = False;
620 fsp->sent_oplock_break = NO_BREAK_SENT;
621 fsp->is_directory = False;
622 if (conn->aio_write_behind_list &&
623 is_in_path(smb_fname->base_name, conn->aio_write_behind_list,
624 conn->case_sensitive)) {
625 fsp->aio_write_behind = True;
628 fsp->wcp = NULL; /* Write cache pointer. */
630 DEBUG(2,("%s opened file %s read=%s write=%s (numopen=%d)\n",
631 conn->server_info->unix_name,
632 smb_fname_str_dbg(smb_fname),
633 BOOLSTR(fsp->can_read), BOOLSTR(fsp->can_write),
634 conn->num_files_open));
640 /*******************************************************************
641 Return True if the filename is one of the special executable types.
642 ********************************************************************/
644 bool is_executable(const char *fname)
646 if ((fname = strrchr_m(fname,'.'))) {
647 if (strequal(fname,".com") ||
648 strequal(fname,".dll") ||
649 strequal(fname,".exe") ||
650 strequal(fname,".sym")) {
657 /****************************************************************************
658 Check if we can open a file with a share mode.
659 Returns True if conflict, False if not.
660 ****************************************************************************/
662 static bool share_conflict(struct share_mode_entry *entry,
666 DEBUG(10,("share_conflict: entry->access_mask = 0x%x, "
667 "entry->share_access = 0x%x, "
668 "entry->private_options = 0x%x\n",
669 (unsigned int)entry->access_mask,
670 (unsigned int)entry->share_access,
671 (unsigned int)entry->private_options));
673 DEBUG(10,("share_conflict: access_mask = 0x%x, share_access = 0x%x\n",
674 (unsigned int)access_mask, (unsigned int)share_access));
676 if ((entry->access_mask & (FILE_WRITE_DATA|
680 DELETE_ACCESS)) == 0) {
681 DEBUG(10,("share_conflict: No conflict due to "
682 "entry->access_mask = 0x%x\n",
683 (unsigned int)entry->access_mask ));
687 if ((access_mask & (FILE_WRITE_DATA|
691 DELETE_ACCESS)) == 0) {
692 DEBUG(10,("share_conflict: No conflict due to "
693 "access_mask = 0x%x\n",
694 (unsigned int)access_mask ));
698 #if 1 /* JRA TEST - Superdebug. */
699 #define CHECK_MASK(num, am, right, sa, share) \
700 DEBUG(10,("share_conflict: [%d] am (0x%x) & right (0x%x) = 0x%x\n", \
701 (unsigned int)(num), (unsigned int)(am), \
702 (unsigned int)(right), (unsigned int)(am)&(right) )); \
703 DEBUG(10,("share_conflict: [%d] sa (0x%x) & share (0x%x) = 0x%x\n", \
704 (unsigned int)(num), (unsigned int)(sa), \
705 (unsigned int)(share), (unsigned int)(sa)&(share) )); \
706 if (((am) & (right)) && !((sa) & (share))) { \
707 DEBUG(10,("share_conflict: check %d conflict am = 0x%x, right = 0x%x, \
708 sa = 0x%x, share = 0x%x\n", (num), (unsigned int)(am), (unsigned int)(right), (unsigned int)(sa), \
709 (unsigned int)(share) )); \
713 #define CHECK_MASK(num, am, right, sa, share) \
714 if (((am) & (right)) && !((sa) & (share))) { \
715 DEBUG(10,("share_conflict: check %d conflict am = 0x%x, right = 0x%x, \
716 sa = 0x%x, share = 0x%x\n", (num), (unsigned int)(am), (unsigned int)(right), (unsigned int)(sa), \
717 (unsigned int)(share) )); \
722 CHECK_MASK(1, entry->access_mask, FILE_WRITE_DATA | FILE_APPEND_DATA,
723 share_access, FILE_SHARE_WRITE);
724 CHECK_MASK(2, access_mask, FILE_WRITE_DATA | FILE_APPEND_DATA,
725 entry->share_access, FILE_SHARE_WRITE);
727 CHECK_MASK(3, entry->access_mask, FILE_READ_DATA | FILE_EXECUTE,
728 share_access, FILE_SHARE_READ);
729 CHECK_MASK(4, access_mask, FILE_READ_DATA | FILE_EXECUTE,
730 entry->share_access, FILE_SHARE_READ);
732 CHECK_MASK(5, entry->access_mask, DELETE_ACCESS,
733 share_access, FILE_SHARE_DELETE);
734 CHECK_MASK(6, access_mask, DELETE_ACCESS,
735 entry->share_access, FILE_SHARE_DELETE);
737 DEBUG(10,("share_conflict: No conflict.\n"));
741 #if defined(DEVELOPER)
742 static void validate_my_share_entries(int num,
743 struct share_mode_entry *share_entry)
747 if (!procid_is_me(&share_entry->pid)) {
751 if (is_deferred_open_entry(share_entry) &&
752 !open_was_deferred(share_entry->op_mid)) {
753 char *str = talloc_asprintf(talloc_tos(),
754 "Got a deferred entry without a request: "
756 share_mode_str(talloc_tos(), num, share_entry));
760 if (!is_valid_share_mode_entry(share_entry)) {
764 fsp = file_find_dif(share_entry->id,
765 share_entry->share_file_id);
767 DEBUG(0,("validate_my_share_entries: PANIC : %s\n",
768 share_mode_str(talloc_tos(), num, share_entry) ));
769 smb_panic("validate_my_share_entries: Cannot match a "
770 "share entry with an open file\n");
773 if (is_deferred_open_entry(share_entry) ||
774 is_unused_share_mode_entry(share_entry)) {
778 if ((share_entry->op_type == NO_OPLOCK) &&
779 (fsp->oplock_type == FAKE_LEVEL_II_OPLOCK)) {
780 /* Someone has already written to it, but I haven't yet
785 if (((uint16)fsp->oplock_type) != share_entry->op_type) {
794 DEBUG(0,("validate_my_share_entries: PANIC : %s\n",
795 share_mode_str(talloc_tos(), num, share_entry) ));
796 str = talloc_asprintf(talloc_tos(),
797 "validate_my_share_entries: "
798 "file %s, oplock_type = 0x%x, op_type = 0x%x\n",
799 fsp->fsp_name->base_name,
800 (unsigned int)fsp->oplock_type,
801 (unsigned int)share_entry->op_type );
807 bool is_stat_open(uint32 access_mask)
809 return (access_mask &&
810 ((access_mask & ~(SYNCHRONIZE_ACCESS| FILE_READ_ATTRIBUTES|
811 FILE_WRITE_ATTRIBUTES))==0) &&
812 ((access_mask & (SYNCHRONIZE_ACCESS|FILE_READ_ATTRIBUTES|
813 FILE_WRITE_ATTRIBUTES)) != 0));
816 /****************************************************************************
817 Deal with share modes
818 Invarient: Share mode must be locked on entry and exit.
819 Returns -1 on error, or number of share modes on success (may be zero).
820 ****************************************************************************/
822 static NTSTATUS open_mode_check(connection_struct *conn,
823 struct share_mode_lock *lck,
826 uint32 create_options,
831 if(lck->num_share_modes == 0) {
835 *file_existed = True;
837 /* A delete on close prohibits everything */
839 if (lck->delete_on_close) {
840 return NT_STATUS_DELETE_PENDING;
843 if (is_stat_open(access_mask)) {
844 /* Stat open that doesn't trigger oplock breaks or share mode
845 * checks... ! JRA. */
850 * Check if the share modes will give us access.
853 #if defined(DEVELOPER)
854 for(i = 0; i < lck->num_share_modes; i++) {
855 validate_my_share_entries(i, &lck->share_modes[i]);
859 if (!lp_share_modes(SNUM(conn))) {
863 /* Now we check the share modes, after any oplock breaks. */
864 for(i = 0; i < lck->num_share_modes; i++) {
866 if (!is_valid_share_mode_entry(&lck->share_modes[i])) {
870 /* someone else has a share lock on it, check to see if we can
872 if (share_conflict(&lck->share_modes[i],
873 access_mask, share_access)) {
874 return NT_STATUS_SHARING_VIOLATION;
881 static bool is_delete_request(files_struct *fsp) {
882 return ((fsp->access_mask == DELETE_ACCESS) &&
883 (fsp->oplock_type == NO_OPLOCK));
887 * Send a break message to the oplock holder and delay the open for
891 static NTSTATUS send_break_message(files_struct *fsp,
892 struct share_mode_entry *exclusive,
897 char msg[MSG_SMB_SHARE_MODE_ENTRY_SIZE];
899 DEBUG(10, ("Sending break request to PID %s\n",
900 procid_str_static(&exclusive->pid)));
901 exclusive->op_mid = mid;
903 /* Create the message. */
904 share_mode_entry_to_message(msg, exclusive);
906 /* Add in the FORCE_OPLOCK_BREAK_TO_NONE bit in the message if set. We
907 don't want this set in the share mode struct pointed to by lck. */
909 if (oplock_request & FORCE_OPLOCK_BREAK_TO_NONE) {
910 SSVAL(msg,OP_BREAK_MSG_OP_TYPE_OFFSET,
911 exclusive->op_type | FORCE_OPLOCK_BREAK_TO_NONE);
914 status = messaging_send_buf(smbd_messaging_context(), exclusive->pid,
915 MSG_SMB_BREAK_REQUEST,
917 MSG_SMB_SHARE_MODE_ENTRY_SIZE);
918 if (!NT_STATUS_IS_OK(status)) {
919 DEBUG(3, ("Could not send oplock break message: %s\n",
927 * 1) No files open at all or internal open: Grant whatever the client wants.
929 * 2) Exclusive (or batch) oplock around: If the requested access is a delete
930 * request, break if the oplock around is a batch oplock. If it's another
931 * requested access type, break.
933 * 3) Only level2 around: Grant level2 and do nothing else.
936 static bool delay_for_oplocks(struct share_mode_lock *lck,
943 struct share_mode_entry *exclusive = NULL;
944 bool valid_entry = false;
945 bool have_level2 = false;
946 bool have_a_none_oplock = false;
947 bool allow_level2 = (global_client_caps & CAP_LEVEL_II_OPLOCKS) &&
948 lp_level2_oplocks(SNUM(fsp->conn));
950 if (oplock_request & INTERNAL_OPEN_ONLY) {
951 fsp->oplock_type = NO_OPLOCK;
954 if ((oplock_request & INTERNAL_OPEN_ONLY) || is_stat_open(fsp->access_mask)) {
958 for (i=0; i<lck->num_share_modes; i++) {
960 if (!is_valid_share_mode_entry(&lck->share_modes[i])) {
964 /* At least one entry is not an invalid or deferred entry. */
967 if (pass_number == 1) {
968 if (BATCH_OPLOCK_TYPE(lck->share_modes[i].op_type)) {
969 SMB_ASSERT(exclusive == NULL);
970 exclusive = &lck->share_modes[i];
973 if (EXCLUSIVE_OPLOCK_TYPE(lck->share_modes[i].op_type)) {
974 SMB_ASSERT(exclusive == NULL);
975 exclusive = &lck->share_modes[i];
979 if (LEVEL_II_OPLOCK_TYPE(lck->share_modes[i].op_type)) {
980 SMB_ASSERT(exclusive == NULL);
984 if (lck->share_modes[i].op_type == NO_OPLOCK) {
985 have_a_none_oplock = true;
989 if (exclusive != NULL) { /* Found an exclusive oplock */
990 bool delay_it = is_delete_request(fsp) ?
991 BATCH_OPLOCK_TYPE(exclusive->op_type) : true;
992 SMB_ASSERT(!have_level2);
994 send_break_message(fsp, exclusive, mid, oplock_request);
1000 * Match what was requested (fsp->oplock_type) with
1001 * what was found in the existing share modes.
1005 /* All entries are placeholders or deferred.
1006 * Directly grant whatever the client wants. */
1007 if (fsp->oplock_type == NO_OPLOCK) {
1008 /* Store a level2 oplock, but don't tell the client */
1009 fsp->oplock_type = FAKE_LEVEL_II_OPLOCK;
1011 } else if (have_a_none_oplock) {
1012 fsp->oplock_type = NO_OPLOCK;
1013 } else if (have_level2) {
1014 if (fsp->oplock_type == NO_OPLOCK ||
1015 fsp->oplock_type == FAKE_LEVEL_II_OPLOCK) {
1016 /* Store a level2 oplock, but don't tell the client */
1017 fsp->oplock_type = FAKE_LEVEL_II_OPLOCK;
1019 fsp->oplock_type = LEVEL_II_OPLOCK;
1022 /* This case can never happen. */
1027 * Don't grant level2 to clients that don't want them
1028 * or if we've turned them off.
1030 if (fsp->oplock_type == LEVEL_II_OPLOCK && !allow_level2) {
1031 fsp->oplock_type = FAKE_LEVEL_II_OPLOCK;
1034 DEBUG(10,("delay_for_oplocks: oplock type 0x%x on file %s\n",
1035 fsp->oplock_type, fsp_str_dbg(fsp)));
1041 bool request_timed_out(struct timeval request_time,
1042 struct timeval timeout)
1044 struct timeval now, end_time;
1046 end_time = timeval_sum(&request_time, &timeout);
1047 return (timeval_compare(&end_time, &now) < 0);
1050 /****************************************************************************
1051 Handle the 1 second delay in returning a SHARING_VIOLATION error.
1052 ****************************************************************************/
1054 static void defer_open(struct share_mode_lock *lck,
1055 struct timeval request_time,
1056 struct timeval timeout,
1057 struct smb_request *req,
1058 struct deferred_open_record *state)
1062 /* Paranoia check */
1064 for (i=0; i<lck->num_share_modes; i++) {
1065 struct share_mode_entry *e = &lck->share_modes[i];
1067 if (!is_deferred_open_entry(e)) {
1071 if (procid_is_me(&e->pid) && (e->op_mid == req->mid)) {
1072 DEBUG(0, ("Trying to defer an already deferred "
1073 "request: mid=%llu, exiting\n",
1074 (unsigned long long)req->mid));
1075 exit_server("attempt to defer a deferred request");
1079 /* End paranoia check */
1081 DEBUG(10,("defer_open_sharing_error: time [%u.%06u] adding deferred "
1082 "open entry for mid %llu\n",
1083 (unsigned int)request_time.tv_sec,
1084 (unsigned int)request_time.tv_usec,
1085 (unsigned long long)req->mid));
1087 if (!push_deferred_open_message_smb(req, request_time, timeout,
1088 state->id, (char *)state, sizeof(*state))) {
1089 exit_server("push_deferred_open_message_smb failed");
1091 add_deferred_open(lck, req->mid, request_time, state->id);
1095 /****************************************************************************
1096 On overwrite open ensure that the attributes match.
1097 ****************************************************************************/
1099 bool open_match_attributes(connection_struct *conn,
1100 uint32 old_dos_attr,
1101 uint32 new_dos_attr,
1102 mode_t existing_unx_mode,
1103 mode_t new_unx_mode,
1104 mode_t *returned_unx_mode)
1106 uint32 noarch_old_dos_attr, noarch_new_dos_attr;
1108 noarch_old_dos_attr = (old_dos_attr & ~FILE_ATTRIBUTE_ARCHIVE);
1109 noarch_new_dos_attr = (new_dos_attr & ~FILE_ATTRIBUTE_ARCHIVE);
1111 if((noarch_old_dos_attr == 0 && noarch_new_dos_attr != 0) ||
1112 (noarch_old_dos_attr != 0 && ((noarch_old_dos_attr & noarch_new_dos_attr) == noarch_old_dos_attr))) {
1113 *returned_unx_mode = new_unx_mode;
1115 *returned_unx_mode = (mode_t)0;
1118 DEBUG(10,("open_match_attributes: old_dos_attr = 0x%x, "
1119 "existing_unx_mode = 0%o, new_dos_attr = 0x%x "
1120 "returned_unx_mode = 0%o\n",
1121 (unsigned int)old_dos_attr,
1122 (unsigned int)existing_unx_mode,
1123 (unsigned int)new_dos_attr,
1124 (unsigned int)*returned_unx_mode ));
1126 /* If we're mapping SYSTEM and HIDDEN ensure they match. */
1127 if (lp_map_system(SNUM(conn)) || lp_store_dos_attributes(SNUM(conn))) {
1128 if ((old_dos_attr & FILE_ATTRIBUTE_SYSTEM) &&
1129 !(new_dos_attr & FILE_ATTRIBUTE_SYSTEM)) {
1133 if (lp_map_hidden(SNUM(conn)) || lp_store_dos_attributes(SNUM(conn))) {
1134 if ((old_dos_attr & FILE_ATTRIBUTE_HIDDEN) &&
1135 !(new_dos_attr & FILE_ATTRIBUTE_HIDDEN)) {
1142 /****************************************************************************
1143 Special FCB or DOS processing in the case of a sharing violation.
1144 Try and find a duplicated file handle.
1145 ****************************************************************************/
1147 NTSTATUS fcb_or_dos_open(struct smb_request *req,
1148 connection_struct *conn,
1149 files_struct *fsp_to_dup_into,
1150 const struct smb_filename *smb_fname,
1155 uint32 share_access,
1156 uint32 create_options)
1160 DEBUG(5,("fcb_or_dos_open: attempting old open semantics for "
1161 "file %s.\n", smb_fname_str_dbg(smb_fname)));
1163 for(fsp = file_find_di_first(id); fsp;
1164 fsp = file_find_di_next(fsp)) {
1166 DEBUG(10,("fcb_or_dos_open: checking file %s, fd = %d, "
1167 "vuid = %u, file_pid = %u, private_options = 0x%x "
1168 "access_mask = 0x%x\n", fsp_str_dbg(fsp),
1169 fsp->fh->fd, (unsigned int)fsp->vuid,
1170 (unsigned int)fsp->file_pid,
1171 (unsigned int)fsp->fh->private_options,
1172 (unsigned int)fsp->access_mask ));
1174 if (fsp->fh->fd != -1 &&
1175 fsp->vuid == vuid &&
1176 fsp->file_pid == file_pid &&
1177 (fsp->fh->private_options & (NTCREATEX_OPTIONS_PRIVATE_DENY_DOS |
1178 NTCREATEX_OPTIONS_PRIVATE_DENY_FCB)) &&
1179 (fsp->access_mask & FILE_WRITE_DATA) &&
1180 strequal(fsp->fsp_name->base_name, smb_fname->base_name) &&
1181 strequal(fsp->fsp_name->stream_name,
1182 smb_fname->stream_name)) {
1183 DEBUG(10,("fcb_or_dos_open: file match\n"));
1189 return NT_STATUS_NOT_FOUND;
1192 /* quite an insane set of semantics ... */
1193 if (is_executable(smb_fname->base_name) &&
1194 (fsp->fh->private_options & NTCREATEX_OPTIONS_PRIVATE_DENY_DOS)) {
1195 DEBUG(10,("fcb_or_dos_open: file fail due to is_executable.\n"));
1196 return NT_STATUS_INVALID_PARAMETER;
1199 /* We need to duplicate this fsp. */
1200 return dup_file_fsp(req, fsp, access_mask, share_access,
1201 create_options, fsp_to_dup_into);
1204 /****************************************************************************
1205 Open a file with a share mode - old openX method - map into NTCreate.
1206 ****************************************************************************/
1208 bool map_open_params_to_ntcreate(const struct smb_filename *smb_fname,
1209 int deny_mode, int open_func,
1210 uint32 *paccess_mask,
1211 uint32 *pshare_mode,
1212 uint32 *pcreate_disposition,
1213 uint32 *pcreate_options,
1214 uint32_t *pprivate_flags)
1218 uint32 create_disposition;
1219 uint32 create_options = FILE_NON_DIRECTORY_FILE;
1220 uint32_t private_flags = 0;
1222 DEBUG(10,("map_open_params_to_ntcreate: fname = %s, deny_mode = 0x%x, "
1223 "open_func = 0x%x\n",
1224 smb_fname_str_dbg(smb_fname), (unsigned int)deny_mode,
1225 (unsigned int)open_func ));
1227 /* Create the NT compatible access_mask. */
1228 switch (GET_OPENX_MODE(deny_mode)) {
1229 case DOS_OPEN_EXEC: /* Implies read-only - used to be FILE_READ_DATA */
1230 case DOS_OPEN_RDONLY:
1231 access_mask = FILE_GENERIC_READ;
1233 case DOS_OPEN_WRONLY:
1234 access_mask = FILE_GENERIC_WRITE;
1238 access_mask = FILE_GENERIC_READ|FILE_GENERIC_WRITE;
1241 DEBUG(10,("map_open_params_to_ntcreate: bad open mode = 0x%x\n",
1242 (unsigned int)GET_OPENX_MODE(deny_mode)));
1246 /* Create the NT compatible create_disposition. */
1247 switch (open_func) {
1248 case OPENX_FILE_EXISTS_FAIL|OPENX_FILE_CREATE_IF_NOT_EXIST:
1249 create_disposition = FILE_CREATE;
1252 case OPENX_FILE_EXISTS_OPEN:
1253 create_disposition = FILE_OPEN;
1256 case OPENX_FILE_EXISTS_OPEN|OPENX_FILE_CREATE_IF_NOT_EXIST:
1257 create_disposition = FILE_OPEN_IF;
1260 case OPENX_FILE_EXISTS_TRUNCATE:
1261 create_disposition = FILE_OVERWRITE;
1264 case OPENX_FILE_EXISTS_TRUNCATE|OPENX_FILE_CREATE_IF_NOT_EXIST:
1265 create_disposition = FILE_OVERWRITE_IF;
1269 /* From samba4 - to be confirmed. */
1270 if (GET_OPENX_MODE(deny_mode) == DOS_OPEN_EXEC) {
1271 create_disposition = FILE_CREATE;
1274 DEBUG(10,("map_open_params_to_ntcreate: bad "
1275 "open_func 0x%x\n", (unsigned int)open_func));
1279 /* Create the NT compatible share modes. */
1280 switch (GET_DENY_MODE(deny_mode)) {
1282 share_mode = FILE_SHARE_NONE;
1286 share_mode = FILE_SHARE_READ;
1290 share_mode = FILE_SHARE_WRITE;
1294 share_mode = FILE_SHARE_READ|FILE_SHARE_WRITE;
1298 private_flags |= NTCREATEX_OPTIONS_PRIVATE_DENY_DOS;
1299 if (is_executable(smb_fname->base_name)) {
1300 share_mode = FILE_SHARE_READ|FILE_SHARE_WRITE;
1302 if (GET_OPENX_MODE(deny_mode) == DOS_OPEN_RDONLY) {
1303 share_mode = FILE_SHARE_READ;
1305 share_mode = FILE_SHARE_NONE;
1311 private_flags |= NTCREATEX_OPTIONS_PRIVATE_DENY_FCB;
1312 share_mode = FILE_SHARE_NONE;
1316 DEBUG(10,("map_open_params_to_ntcreate: bad deny_mode 0x%x\n",
1317 (unsigned int)GET_DENY_MODE(deny_mode) ));
1321 DEBUG(10,("map_open_params_to_ntcreate: file %s, access_mask = 0x%x, "
1322 "share_mode = 0x%x, create_disposition = 0x%x, "
1323 "create_options = 0x%x private_flags = 0x%x\n",
1324 smb_fname_str_dbg(smb_fname),
1325 (unsigned int)access_mask,
1326 (unsigned int)share_mode,
1327 (unsigned int)create_disposition,
1328 (unsigned int)create_options,
1329 (unsigned int)private_flags));
1332 *paccess_mask = access_mask;
1335 *pshare_mode = share_mode;
1337 if (pcreate_disposition) {
1338 *pcreate_disposition = create_disposition;
1340 if (pcreate_options) {
1341 *pcreate_options = create_options;
1343 if (pprivate_flags) {
1344 *pprivate_flags = private_flags;
1351 static void schedule_defer_open(struct share_mode_lock *lck,
1352 struct timeval request_time,
1353 struct smb_request *req)
1355 struct deferred_open_record state;
1357 /* This is a relative time, added to the absolute
1358 request_time value to get the absolute timeout time.
1359 Note that if this is the second or greater time we enter
1360 this codepath for this particular request mid then
1361 request_time is left as the absolute time of the *first*
1362 time this request mid was processed. This is what allows
1363 the request to eventually time out. */
1365 struct timeval timeout;
1367 /* Normally the smbd we asked should respond within
1368 * OPLOCK_BREAK_TIMEOUT seconds regardless of whether
1369 * the client did, give twice the timeout as a safety
1370 * measure here in case the other smbd is stuck
1371 * somewhere else. */
1373 timeout = timeval_set(OPLOCK_BREAK_TIMEOUT*2, 0);
1375 /* Nothing actually uses state.delayed_for_oplocks
1376 but it's handy to differentiate in debug messages
1377 between a 30 second delay due to oplock break, and
1378 a 1 second delay for share mode conflicts. */
1380 state.delayed_for_oplocks = True;
1383 if (!request_timed_out(request_time, timeout)) {
1384 defer_open(lck, request_time, timeout, req, &state);
1388 /****************************************************************************
1389 Work out what access_mask to use from what the client sent us.
1390 ****************************************************************************/
1392 static NTSTATUS calculate_access_mask(connection_struct *conn,
1393 const struct smb_filename *smb_fname,
1395 uint32_t access_mask,
1396 uint32_t *access_mask_out)
1401 * Convert GENERIC bits to specific bits.
1404 se_map_generic(&access_mask, &file_generic_mapping);
1406 /* Calculate MAXIMUM_ALLOWED_ACCESS if requested. */
1407 if (access_mask & MAXIMUM_ALLOWED_ACCESS) {
1410 struct security_descriptor *sd;
1411 uint32_t access_granted = 0;
1413 status = SMB_VFS_GET_NT_ACL(conn, smb_fname->base_name,
1414 (OWNER_SECURITY_INFORMATION |
1415 GROUP_SECURITY_INFORMATION |
1416 DACL_SECURITY_INFORMATION),&sd);
1418 if (!NT_STATUS_IS_OK(status)) {
1419 DEBUG(10, ("calculate_access_mask: Could not get acl "
1421 smb_fname_str_dbg(smb_fname),
1422 nt_errstr(status)));
1423 return NT_STATUS_ACCESS_DENIED;
1426 status = smb1_file_se_access_check(conn,
1428 get_current_nttok(conn),
1434 if (!NT_STATUS_IS_OK(status)) {
1435 DEBUG(10, ("calculate_access_mask: Access denied on "
1436 "file %s: when calculating maximum access\n",
1437 smb_fname_str_dbg(smb_fname)));
1438 return NT_STATUS_ACCESS_DENIED;
1441 access_mask = access_granted;
1443 access_mask = FILE_GENERIC_ALL;
1447 *access_mask_out = access_mask;
1448 return NT_STATUS_OK;
1451 /****************************************************************************
1452 Remove the deferred open entry under lock.
1453 ****************************************************************************/
1455 void remove_deferred_open_entry(struct file_id id, uint64_t mid)
1457 struct share_mode_lock *lck = get_share_mode_lock(talloc_tos(), id,
1460 DEBUG(0, ("could not get share mode lock\n"));
1462 del_deferred_open_entry(lck, mid);
1467 /****************************************************************************
1468 Open a file with a share mode. Passed in an already created files_struct *.
1469 ****************************************************************************/
1471 static NTSTATUS open_file_ntcreate(connection_struct *conn,
1472 struct smb_request *req,
1473 uint32 access_mask, /* access bits (FILE_READ_DATA etc.) */
1474 uint32 share_access, /* share constants (FILE_SHARE_READ etc) */
1475 uint32 create_disposition, /* FILE_OPEN_IF etc. */
1476 uint32 create_options, /* options such as delete on close. */
1477 uint32 new_dos_attributes, /* attributes used for new file. */
1478 int oplock_request, /* internal Samba oplock codes. */
1479 /* Information (FILE_EXISTS etc.) */
1480 uint32_t private_flags, /* Samba specific flags. */
1484 struct smb_filename *smb_fname = fsp->fsp_name;
1487 bool file_existed = VALID_STAT(smb_fname->st);
1488 bool def_acl = False;
1489 bool posix_open = False;
1490 bool new_file_created = False;
1491 bool clear_ads = false;
1493 NTSTATUS fsp_open = NT_STATUS_ACCESS_DENIED;
1494 mode_t new_unx_mode = (mode_t)0;
1495 mode_t unx_mode = (mode_t)0;
1497 uint32 existing_dos_attributes = 0;
1498 struct timeval request_time = timeval_zero();
1499 struct share_mode_lock *lck = NULL;
1500 uint32 open_access_mask = access_mask;
1506 if (conn->printer) {
1508 * Printers are handled completely differently.
1509 * Most of the passed parameters are ignored.
1513 *pinfo = FILE_WAS_CREATED;
1516 DEBUG(10, ("open_file_ntcreate: printer open fname=%s\n",
1517 smb_fname_str_dbg(smb_fname)));
1520 DEBUG(0,("open_file_ntcreate: printer open without "
1521 "an SMB request!\n"));
1522 return NT_STATUS_INTERNAL_ERROR;
1525 return print_fsp_open(req, conn, smb_fname->base_name,
1529 if (!parent_dirname(talloc_tos(), smb_fname->base_name, &parent_dir,
1531 return NT_STATUS_NO_MEMORY;
1534 if (new_dos_attributes & FILE_FLAG_POSIX_SEMANTICS) {
1536 unx_mode = (mode_t)(new_dos_attributes & ~FILE_FLAG_POSIX_SEMANTICS);
1537 new_dos_attributes = 0;
1539 /* We add aARCH to this as this mode is only used if the file is
1541 unx_mode = unix_mode(conn, new_dos_attributes | aARCH,
1542 smb_fname, parent_dir);
1545 DEBUG(10, ("open_file_ntcreate: fname=%s, dos_attrs=0x%x "
1546 "access_mask=0x%x share_access=0x%x "
1547 "create_disposition = 0x%x create_options=0x%x "
1548 "unix mode=0%o oplock_request=%d private_flags = 0x%x\n",
1549 smb_fname_str_dbg(smb_fname), new_dos_attributes,
1550 access_mask, share_access, create_disposition,
1551 create_options, (unsigned int)unx_mode, oplock_request,
1552 (unsigned int)private_flags));
1554 if ((req == NULL) && ((oplock_request & INTERNAL_OPEN_ONLY) == 0)) {
1555 DEBUG(0, ("No smb request but not an internal only open!\n"));
1556 return NT_STATUS_INTERNAL_ERROR;
1560 * Only non-internal opens can be deferred at all
1565 if (get_deferred_open_message_state(req,
1569 struct deferred_open_record *state = (struct deferred_open_record *)ptr;
1570 /* Remember the absolute time of the original
1571 request with this mid. We'll use it later to
1572 see if this has timed out. */
1574 /* Remove the deferred open entry under lock. */
1575 remove_deferred_open_entry(state->id, req->mid);
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)) || global_client_failed_oplock_break ||
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))) {
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 (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;
2225 * Take care of inherited ACLs on created files - if default ACL not
2229 if (!posix_open && !file_existed && !def_acl) {
2231 int saved_errno = errno; /* We might get ENOSYS in the next
2234 if (SMB_VFS_FCHMOD_ACL(fsp, unx_mode) == -1 &&
2236 errno = saved_errno; /* Ignore ENOSYS */
2239 } else if (new_unx_mode) {
2243 /* Attributes need changing. File already existed. */
2246 int saved_errno = errno; /* We might get ENOSYS in the
2248 ret = SMB_VFS_FCHMOD_ACL(fsp, new_unx_mode);
2250 if (ret == -1 && errno == ENOSYS) {
2251 errno = saved_errno; /* Ignore ENOSYS */
2253 DEBUG(5, ("open_file_ntcreate: reset "
2254 "attributes of file %s to 0%o\n",
2255 smb_fname_str_dbg(smb_fname),
2256 (unsigned int)new_unx_mode));
2257 ret = 0; /* Don't do the fchmod below. */
2262 (SMB_VFS_FCHMOD(fsp, new_unx_mode) == -1))
2263 DEBUG(5, ("open_file_ntcreate: failed to reset "
2264 "attributes of file %s to 0%o\n",
2265 smb_fname_str_dbg(smb_fname),
2266 (unsigned int)new_unx_mode));
2269 /* If this is a successful open, we must remove any deferred open
2272 del_deferred_open_entry(lck, req->mid);
2276 return NT_STATUS_OK;
2280 /****************************************************************************
2281 Open a file for for write to ensure that we can fchmod it.
2282 ****************************************************************************/
2284 NTSTATUS open_file_fchmod(struct smb_request *req, connection_struct *conn,
2285 struct smb_filename *smb_fname,
2286 files_struct **result)
2288 files_struct *fsp = NULL;
2291 if (!VALID_STAT(smb_fname->st)) {
2292 return NT_STATUS_INVALID_PARAMETER;
2295 status = file_new(req, conn, &fsp);
2296 if(!NT_STATUS_IS_OK(status)) {
2300 status = SMB_VFS_CREATE_FILE(
2303 0, /* root_dir_fid */
2304 smb_fname, /* fname */
2305 FILE_WRITE_DATA, /* access_mask */
2306 (FILE_SHARE_READ | FILE_SHARE_WRITE | /* share_access */
2308 FILE_OPEN, /* create_disposition*/
2309 0, /* create_options */
2310 0, /* file_attributes */
2311 0, /* oplock_request */
2312 0, /* allocation_size */
2313 0, /* private_flags */
2320 * This is not a user visible file open.
2321 * Don't set a share mode.
2324 if (!NT_STATUS_IS_OK(status)) {
2325 file_free(req, fsp);
2330 return NT_STATUS_OK;
2333 /****************************************************************************
2334 Close the fchmod file fd - ensure no locks are lost.
2335 ****************************************************************************/
2337 NTSTATUS close_file_fchmod(struct smb_request *req, files_struct *fsp)
2339 NTSTATUS status = fd_close(fsp);
2340 file_free(req, fsp);
2344 static NTSTATUS mkdir_internal(connection_struct *conn,
2345 struct smb_filename *smb_dname,
2346 uint32 file_attributes)
2351 bool posix_open = false;
2353 if(!CAN_WRITE(conn)) {
2354 DEBUG(5,("mkdir_internal: failing create on read-only share "
2355 "%s\n", lp_servicename(SNUM(conn))));
2356 return NT_STATUS_ACCESS_DENIED;
2359 status = check_name(conn, smb_dname->base_name);
2360 if (!NT_STATUS_IS_OK(status)) {
2364 if (!parent_dirname(talloc_tos(), smb_dname->base_name, &parent_dir,
2366 return NT_STATUS_NO_MEMORY;
2369 if (file_attributes & FILE_FLAG_POSIX_SEMANTICS) {
2371 mode = (mode_t)(file_attributes & ~FILE_FLAG_POSIX_SEMANTICS);
2373 mode = unix_mode(conn, aDIR, smb_dname, parent_dir);
2376 if (SMB_VFS_MKDIR(conn, smb_dname->base_name, mode) != 0) {
2377 return map_nt_error_from_unix(errno);
2380 /* Ensure we're checking for a symlink here.... */
2381 /* We don't want to get caught by a symlink racer. */
2383 if (SMB_VFS_LSTAT(conn, smb_dname) == -1) {
2384 DEBUG(2, ("Could not stat directory '%s' just created: %s\n",
2385 smb_fname_str_dbg(smb_dname), strerror(errno)));
2386 return map_nt_error_from_unix(errno);
2389 if (!S_ISDIR(smb_dname->st.st_ex_mode)) {
2390 DEBUG(0, ("Directory just '%s' created is not a directory\n",
2391 smb_fname_str_dbg(smb_dname)));
2392 return NT_STATUS_ACCESS_DENIED;
2395 if (lp_store_dos_attributes(SNUM(conn))) {
2397 file_set_dosmode(conn, smb_dname,
2398 file_attributes | aDIR,
2403 if (lp_inherit_perms(SNUM(conn))) {
2404 inherit_access_posix_acl(conn, parent_dir,
2405 smb_dname->base_name, mode);
2410 * Check if high bits should have been set,
2411 * then (if bits are missing): add them.
2412 * Consider bits automagically set by UNIX, i.e. SGID bit from parent
2415 if ((mode & ~(S_IRWXU|S_IRWXG|S_IRWXO)) &&
2416 (mode & ~smb_dname->st.st_ex_mode)) {
2417 SMB_VFS_CHMOD(conn, smb_dname->base_name,
2418 (smb_dname->st.st_ex_mode |
2419 (mode & ~smb_dname->st.st_ex_mode)));
2423 /* Change the owner if required. */
2424 if (lp_inherit_owner(SNUM(conn))) {
2425 change_dir_owner_to_parent(conn, parent_dir,
2426 smb_dname->base_name,
2430 notify_fname(conn, NOTIFY_ACTION_ADDED, FILE_NOTIFY_CHANGE_DIR_NAME,
2431 smb_dname->base_name);
2433 return NT_STATUS_OK;
2436 /****************************************************************************
2437 Open a directory from an NT SMB call.
2438 ****************************************************************************/
2440 static NTSTATUS open_directory(connection_struct *conn,
2441 struct smb_request *req,
2442 struct smb_filename *smb_dname,
2444 uint32 share_access,
2445 uint32 create_disposition,
2446 uint32 create_options,
2447 uint32 file_attributes,
2449 files_struct **result)
2451 files_struct *fsp = NULL;
2452 bool dir_existed = VALID_STAT(smb_dname->st) ? True : False;
2453 struct share_mode_lock *lck = NULL;
2455 struct timespec mtimespec;
2458 SMB_ASSERT(!is_ntfs_stream_smb_fname(smb_dname));
2460 DEBUG(5,("open_directory: opening directory %s, access_mask = 0x%x, "
2461 "share_access = 0x%x create_options = 0x%x, "
2462 "create_disposition = 0x%x, file_attributes = 0x%x\n",
2463 smb_fname_str_dbg(smb_dname),
2464 (unsigned int)access_mask,
2465 (unsigned int)share_access,
2466 (unsigned int)create_options,
2467 (unsigned int)create_disposition,
2468 (unsigned int)file_attributes));
2470 if (!(file_attributes & FILE_FLAG_POSIX_SEMANTICS) &&
2471 (conn->fs_capabilities & FILE_NAMED_STREAMS) &&
2472 is_ntfs_stream_smb_fname(smb_dname)) {
2473 DEBUG(2, ("open_directory: %s is a stream name!\n",
2474 smb_fname_str_dbg(smb_dname)));
2475 return NT_STATUS_NOT_A_DIRECTORY;
2478 status = calculate_access_mask(conn, smb_dname, dir_existed,
2479 access_mask, &access_mask);
2480 if (!NT_STATUS_IS_OK(status)) {
2481 DEBUG(10, ("open_directory: calculate_access_mask "
2482 "on file %s returned %s\n",
2483 smb_fname_str_dbg(smb_dname),
2484 nt_errstr(status)));
2488 /* We need to support SeSecurityPrivilege for this. */
2489 if (access_mask & SEC_FLAG_SYSTEM_SECURITY) {
2490 DEBUG(10, ("open_directory: open on %s "
2491 "failed - SEC_FLAG_SYSTEM_SECURITY denied.\n",
2492 smb_fname_str_dbg(smb_dname)));
2493 return NT_STATUS_PRIVILEGE_NOT_HELD;
2496 switch( create_disposition ) {
2499 info = FILE_WAS_OPENED;
2502 * We want to follow symlinks here.
2505 if (SMB_VFS_STAT(conn, smb_dname) != 0) {
2506 return map_nt_error_from_unix(errno);
2513 /* If directory exists error. If directory doesn't
2516 status = mkdir_internal(conn, smb_dname,
2519 if (!NT_STATUS_IS_OK(status)) {
2520 DEBUG(2, ("open_directory: unable to create "
2521 "%s. Error was %s\n",
2522 smb_fname_str_dbg(smb_dname),
2523 nt_errstr(status)));
2527 info = FILE_WAS_CREATED;
2532 * If directory exists open. If directory doesn't
2536 status = mkdir_internal(conn, smb_dname,
2539 if (NT_STATUS_IS_OK(status)) {
2540 info = FILE_WAS_CREATED;
2543 if (NT_STATUS_EQUAL(status,
2544 NT_STATUS_OBJECT_NAME_COLLISION)) {
2545 info = FILE_WAS_OPENED;
2546 status = NT_STATUS_OK;
2551 case FILE_SUPERSEDE:
2552 case FILE_OVERWRITE:
2553 case FILE_OVERWRITE_IF:
2555 DEBUG(5,("open_directory: invalid create_disposition "
2556 "0x%x for directory %s\n",
2557 (unsigned int)create_disposition,
2558 smb_fname_str_dbg(smb_dname)));
2559 return NT_STATUS_INVALID_PARAMETER;
2562 if(!S_ISDIR(smb_dname->st.st_ex_mode)) {
2563 DEBUG(5,("open_directory: %s is not a directory !\n",
2564 smb_fname_str_dbg(smb_dname)));
2565 return NT_STATUS_NOT_A_DIRECTORY;
2568 if (info == FILE_WAS_OPENED) {
2569 uint32_t access_granted = 0;
2570 status = smbd_check_open_rights(conn, smb_dname, access_mask,
2573 /* Were we trying to do a directory open
2574 * for delete and didn't get DELETE
2575 * access (only) ? Check if the
2576 * directory allows DELETE_CHILD.
2578 * http://blogs.msdn.com/oldnewthing/archive/2004/06/04/148426.aspx
2581 if ((NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED) &&
2582 (access_mask & DELETE_ACCESS) &&
2583 (access_granted == DELETE_ACCESS) &&
2584 can_delete_file_in_directory(conn, smb_dname))) {
2585 DEBUG(10,("open_directory: overrode ACCESS_DENIED "
2586 "on directory %s\n",
2587 smb_fname_str_dbg(smb_dname)));
2588 status = NT_STATUS_OK;
2591 if (!NT_STATUS_IS_OK(status)) {
2592 DEBUG(10, ("open_directory: smbd_check_open_rights on "
2593 "file %s failed with %s\n",
2594 smb_fname_str_dbg(smb_dname),
2595 nt_errstr(status)));
2600 status = file_new(req, conn, &fsp);
2601 if(!NT_STATUS_IS_OK(status)) {
2606 * Setup the files_struct for it.
2609 fsp->mode = smb_dname->st.st_ex_mode;
2610 fsp->file_id = vfs_file_id_from_sbuf(conn, &smb_dname->st);
2611 fsp->vuid = req ? req->vuid : UID_FIELD_INVALID;
2612 fsp->file_pid = req ? req->smbpid : 0;
2613 fsp->can_lock = False;
2614 fsp->can_read = False;
2615 fsp->can_write = False;
2617 fsp->share_access = share_access;
2618 fsp->fh->private_options = 0;
2620 * According to Samba4, SEC_FILE_READ_ATTRIBUTE is always granted,
2622 fsp->access_mask = access_mask | FILE_READ_ATTRIBUTES;
2623 fsp->print_file = False;
2624 fsp->modified = False;
2625 fsp->oplock_type = NO_OPLOCK;
2626 fsp->sent_oplock_break = NO_BREAK_SENT;
2627 fsp->is_directory = True;
2628 fsp->posix_open = (file_attributes & FILE_FLAG_POSIX_SEMANTICS) ? True : False;
2629 status = fsp_set_smb_fname(fsp, smb_dname);
2630 if (!NT_STATUS_IS_OK(status)) {
2634 mtimespec = smb_dname->st.st_ex_mtime;
2636 lck = get_share_mode_lock(talloc_tos(), fsp->file_id,
2637 conn->connectpath, smb_dname, &mtimespec);
2640 DEBUG(0, ("open_directory: Could not get share mode lock for "
2641 "%s\n", smb_fname_str_dbg(smb_dname)));
2642 file_free(req, fsp);
2643 return NT_STATUS_SHARING_VIOLATION;
2646 status = open_mode_check(conn, lck, access_mask, share_access,
2647 create_options, &dir_existed);
2649 if (!NT_STATUS_IS_OK(status)) {
2651 file_free(req, fsp);
2655 set_share_mode(lck, fsp, get_current_uid(conn), 0, NO_OPLOCK);
2657 /* For directories the delete on close bit at open time seems
2658 always to be honored on close... See test 19 in Samba4 BASE-DELETE. */
2659 if (create_options & FILE_DELETE_ON_CLOSE) {
2660 status = can_set_delete_on_close(fsp, 0);
2661 if (!NT_STATUS_IS_OK(status) && !NT_STATUS_EQUAL(status, NT_STATUS_DIRECTORY_NOT_EMPTY)) {
2663 file_free(req, fsp);
2667 if (NT_STATUS_IS_OK(status)) {
2668 /* Note that here we set the *inital* delete on close flag,
2669 not the regular one. The magic gets handled in close. */
2670 fsp->initial_delete_on_close = True;
2681 return NT_STATUS_OK;
2684 NTSTATUS create_directory(connection_struct *conn, struct smb_request *req,
2685 struct smb_filename *smb_dname)
2690 status = SMB_VFS_CREATE_FILE(
2693 0, /* root_dir_fid */
2694 smb_dname, /* fname */
2695 FILE_READ_ATTRIBUTES, /* access_mask */
2696 FILE_SHARE_NONE, /* share_access */
2697 FILE_CREATE, /* create_disposition*/
2698 FILE_DIRECTORY_FILE, /* create_options */
2699 FILE_ATTRIBUTE_DIRECTORY, /* file_attributes */
2700 0, /* oplock_request */
2701 0, /* allocation_size */
2702 0, /* private_flags */
2708 if (NT_STATUS_IS_OK(status)) {
2709 close_file(req, fsp, NORMAL_CLOSE);
2715 /****************************************************************************
2716 Receive notification that one of our open files has been renamed by another
2718 ****************************************************************************/
2720 void msg_file_was_renamed(struct messaging_context *msg,
2723 struct server_id server_id,
2727 char *frm = (char *)data->data;
2729 const char *sharepath;
2730 const char *base_name;
2731 const char *stream_name;
2732 struct smb_filename *smb_fname = NULL;
2733 size_t sp_len, bn_len;
2736 if (data->data == NULL
2737 || data->length < MSG_FILE_RENAMED_MIN_SIZE + 2) {
2738 DEBUG(0, ("msg_file_was_renamed: Got invalid msg len %d\n",
2739 (int)data->length));
2743 /* Unpack the message. */
2744 pull_file_id_24(frm, &id);
2745 sharepath = &frm[24];
2746 sp_len = strlen(sharepath);
2747 base_name = sharepath + sp_len + 1;
2748 bn_len = strlen(base_name);
2749 stream_name = sharepath + sp_len + 1 + bn_len + 1;
2751 /* stream_name must always be NULL if there is no stream. */
2752 if (stream_name[0] == '\0') {
2756 status = create_synthetic_smb_fname(talloc_tos(), base_name,
2757 stream_name, NULL, &smb_fname);
2758 if (!NT_STATUS_IS_OK(status)) {
2762 DEBUG(10,("msg_file_was_renamed: Got rename message for sharepath %s, new name %s, "
2764 sharepath, smb_fname_str_dbg(smb_fname),
2765 file_id_string_tos(&id)));
2767 for(fsp = file_find_di_first(id); fsp; fsp = file_find_di_next(fsp)) {
2768 if (memcmp(fsp->conn->connectpath, sharepath, sp_len) == 0) {
2770 DEBUG(10,("msg_file_was_renamed: renaming file fnum %d from %s -> %s\n",
2771 fsp->fnum, fsp_str_dbg(fsp),
2772 smb_fname_str_dbg(smb_fname)));
2773 status = fsp_set_smb_fname(fsp, smb_fname);
2774 if (!NT_STATUS_IS_OK(status)) {
2779 /* Now we have the complete path we can work out if this is
2780 actually within this share and adjust newname accordingly. */
2781 DEBUG(10,("msg_file_was_renamed: share mismatch (sharepath %s "
2782 "not sharepath %s) "
2783 "fnum %d from %s -> %s\n",
2784 fsp->conn->connectpath,
2788 smb_fname_str_dbg(smb_fname)));
2792 TALLOC_FREE(smb_fname);
2797 * If a main file is opened for delete, all streams need to be checked for
2798 * !FILE_SHARE_DELETE. Do this by opening with DELETE_ACCESS.
2799 * If that works, delete them all by setting the delete on close and close.
2802 NTSTATUS open_streams_for_delete(connection_struct *conn,
2805 struct stream_struct *stream_info;
2806 files_struct **streams;
2808 unsigned int num_streams;
2809 TALLOC_CTX *frame = talloc_stackframe();
2812 status = SMB_VFS_STREAMINFO(conn, NULL, fname, talloc_tos(),
2813 &num_streams, &stream_info);
2815 if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_IMPLEMENTED)
2816 || NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
2817 DEBUG(10, ("no streams around\n"));
2819 return NT_STATUS_OK;
2822 if (!NT_STATUS_IS_OK(status)) {
2823 DEBUG(10, ("SMB_VFS_STREAMINFO failed: %s\n",
2824 nt_errstr(status)));
2828 DEBUG(10, ("open_streams_for_delete found %d streams\n",
2831 if (num_streams == 0) {
2833 return NT_STATUS_OK;
2836 streams = TALLOC_ARRAY(talloc_tos(), files_struct *, num_streams);
2837 if (streams == NULL) {
2838 DEBUG(0, ("talloc failed\n"));
2839 status = NT_STATUS_NO_MEMORY;
2843 for (i=0; i<num_streams; i++) {
2844 struct smb_filename *smb_fname = NULL;
2846 if (strequal(stream_info[i].name, "::$DATA")) {
2851 status = create_synthetic_smb_fname(talloc_tos(), fname,
2852 stream_info[i].name,
2854 if (!NT_STATUS_IS_OK(status)) {
2858 if (SMB_VFS_STAT(conn, smb_fname) == -1) {
2859 DEBUG(10, ("Unable to stat stream: %s\n",
2860 smb_fname_str_dbg(smb_fname)));
2863 status = SMB_VFS_CREATE_FILE(
2866 0, /* root_dir_fid */
2867 smb_fname, /* fname */
2868 DELETE_ACCESS, /* access_mask */
2869 (FILE_SHARE_READ | /* share_access */
2870 FILE_SHARE_WRITE | FILE_SHARE_DELETE),
2871 FILE_OPEN, /* create_disposition*/
2872 0, /* create_options */
2873 FILE_ATTRIBUTE_NORMAL, /* file_attributes */
2874 0, /* oplock_request */
2875 0, /* allocation_size */
2876 NTCREATEX_OPTIONS_PRIVATE_STREAM_DELETE, /* private_flags */
2879 &streams[i], /* result */
2882 if (!NT_STATUS_IS_OK(status)) {
2883 DEBUG(10, ("Could not open stream %s: %s\n",
2884 smb_fname_str_dbg(smb_fname),
2885 nt_errstr(status)));
2887 TALLOC_FREE(smb_fname);
2890 TALLOC_FREE(smb_fname);
2894 * don't touch the variable "status" beyond this point :-)
2897 for (i -= 1 ; i >= 0; i--) {
2898 if (streams[i] == NULL) {
2902 DEBUG(10, ("Closing stream # %d, %s\n", i,
2903 fsp_str_dbg(streams[i])));
2904 close_file(NULL, streams[i], NORMAL_CLOSE);
2913 * Wrapper around open_file_ntcreate and open_directory
2916 static NTSTATUS create_file_unixpath(connection_struct *conn,
2917 struct smb_request *req,
2918 struct smb_filename *smb_fname,
2919 uint32_t access_mask,
2920 uint32_t share_access,
2921 uint32_t create_disposition,
2922 uint32_t create_options,
2923 uint32_t file_attributes,
2924 uint32_t oplock_request,
2925 uint64_t allocation_size,
2926 uint32_t private_flags,
2927 struct security_descriptor *sd,
2928 struct ea_list *ea_list,
2930 files_struct **result,
2933 int info = FILE_WAS_OPENED;
2934 files_struct *base_fsp = NULL;
2935 files_struct *fsp = NULL;
2938 DEBUG(10,("create_file_unixpath: access_mask = 0x%x "
2939 "file_attributes = 0x%x, share_access = 0x%x, "
2940 "create_disposition = 0x%x create_options = 0x%x "
2941 "oplock_request = 0x%x private_flags = 0x%x "
2942 "ea_list = 0x%p, sd = 0x%p, "
2944 (unsigned int)access_mask,
2945 (unsigned int)file_attributes,
2946 (unsigned int)share_access,
2947 (unsigned int)create_disposition,
2948 (unsigned int)create_options,
2949 (unsigned int)oplock_request,
2950 (unsigned int)private_flags,
2951 ea_list, sd, smb_fname_str_dbg(smb_fname)));
2953 if (create_options & FILE_OPEN_BY_FILE_ID) {
2954 status = NT_STATUS_NOT_SUPPORTED;
2958 if (create_options & NTCREATEX_OPTIONS_INVALID_PARAM_MASK) {
2959 status = NT_STATUS_INVALID_PARAMETER;
2964 oplock_request |= INTERNAL_OPEN_ONLY;
2967 if ((conn->fs_capabilities & FILE_NAMED_STREAMS)
2968 && (access_mask & DELETE_ACCESS)
2969 && !is_ntfs_stream_smb_fname(smb_fname)) {
2971 * We can't open a file with DELETE access if any of the
2972 * streams is open without FILE_SHARE_DELETE
2974 status = open_streams_for_delete(conn, smb_fname->base_name);
2976 if (!NT_STATUS_IS_OK(status)) {
2981 /* This is the correct thing to do (check every time) but can_delete
2982 * is expensive (it may have to read the parent directory
2983 * permissions). So for now we're not doing it unless we have a strong
2984 * hint the client is really going to delete this file. If the client
2985 * is forcing FILE_CREATE let the filesystem take care of the
2988 /* Setting FILE_SHARE_DELETE is the hint. */
2990 if (lp_acl_check_permissions(SNUM(conn))
2991 && (create_disposition != FILE_CREATE)
2992 && (share_access & FILE_SHARE_DELETE)
2993 && (access_mask & DELETE_ACCESS)
2994 && (!(can_delete_file_in_directory(conn, smb_fname) ||
2995 can_access_file_acl(conn, smb_fname, DELETE_ACCESS)))) {
2996 status = NT_STATUS_ACCESS_DENIED;
2997 DEBUG(10,("create_file_unixpath: open file %s "
2998 "for delete ACCESS_DENIED\n",
2999 smb_fname_str_dbg(smb_fname)));
3004 /* We need to support SeSecurityPrivilege for this. */
3005 if ((access_mask & SEC_FLAG_SYSTEM_SECURITY) &&
3006 !user_has_privileges(current_user.nt_user_token,
3008 status = NT_STATUS_PRIVILEGE_NOT_HELD;
3012 /* We need to support SeSecurityPrivilege for this. */
3013 if (access_mask & SEC_FLAG_SYSTEM_SECURITY) {
3014 status = NT_STATUS_PRIVILEGE_NOT_HELD;
3017 /* Don't allow a SACL set from an NTtrans create until we
3018 * support SeSecurityPrivilege. */
3019 if (!VALID_STAT(smb_fname->st) &&
3020 lp_nt_acl_support(SNUM(conn)) &&
3021 sd && (sd->sacl != NULL)) {
3022 status = NT_STATUS_PRIVILEGE_NOT_HELD;
3027 if ((conn->fs_capabilities & FILE_NAMED_STREAMS)
3028 && is_ntfs_stream_smb_fname(smb_fname)
3029 && (!(private_flags & NTCREATEX_OPTIONS_PRIVATE_STREAM_DELETE))) {
3030 uint32 base_create_disposition;
3031 struct smb_filename *smb_fname_base = NULL;
3033 if (create_options & FILE_DIRECTORY_FILE) {
3034 status = NT_STATUS_NOT_A_DIRECTORY;
3038 switch (create_disposition) {
3040 base_create_disposition = FILE_OPEN;
3043 base_create_disposition = FILE_OPEN_IF;
3047 /* Create an smb_filename with stream_name == NULL. */
3048 status = create_synthetic_smb_fname(talloc_tos(),
3049 smb_fname->base_name,
3052 if (!NT_STATUS_IS_OK(status)) {
3056 if (SMB_VFS_STAT(conn, smb_fname_base) == -1) {
3057 DEBUG(10, ("Unable to stat stream: %s\n",
3058 smb_fname_str_dbg(smb_fname_base)));
3061 /* Open the base file. */
3062 status = create_file_unixpath(conn, NULL, smb_fname_base, 0,
3065 | FILE_SHARE_DELETE,
3066 base_create_disposition,
3067 0, 0, 0, 0, 0, NULL, NULL,
3069 TALLOC_FREE(smb_fname_base);
3071 if (!NT_STATUS_IS_OK(status)) {
3072 DEBUG(10, ("create_file_unixpath for base %s failed: "
3073 "%s\n", smb_fname->base_name,
3074 nt_errstr(status)));
3077 /* we don't need to low level fd */
3082 * If it's a request for a directory open, deal with it separately.
3085 if (create_options & FILE_DIRECTORY_FILE) {
3087 if (create_options & FILE_NON_DIRECTORY_FILE) {
3088 status = NT_STATUS_INVALID_PARAMETER;
3092 /* Can't open a temp directory. IFS kit test. */
3093 if (!(file_attributes & FILE_FLAG_POSIX_SEMANTICS) &&
3094 (file_attributes & FILE_ATTRIBUTE_TEMPORARY)) {
3095 status = NT_STATUS_INVALID_PARAMETER;
3100 * We will get a create directory here if the Win32
3101 * app specified a security descriptor in the
3102 * CreateDirectory() call.
3106 status = open_directory(
3107 conn, req, smb_fname, access_mask, share_access,
3108 create_disposition, create_options, file_attributes,
3113 * Ordinary file case.
3116 status = file_new(req, conn, &fsp);
3117 if(!NT_STATUS_IS_OK(status)) {
3121 status = fsp_set_smb_fname(fsp, smb_fname);
3122 if (!NT_STATUS_IS_OK(status)) {
3127 * We're opening the stream element of a base_fsp
3128 * we already opened. Set up the base_fsp pointer.
3131 fsp->base_fsp = base_fsp;
3134 status = open_file_ntcreate(conn,
3146 if(!NT_STATUS_IS_OK(status)) {
3147 file_free(req, fsp);
3151 if (NT_STATUS_EQUAL(status, NT_STATUS_FILE_IS_A_DIRECTORY)) {
3153 /* A stream open never opens a directory */
3156 status = NT_STATUS_FILE_IS_A_DIRECTORY;
3161 * Fail the open if it was explicitly a non-directory
3165 if (create_options & FILE_NON_DIRECTORY_FILE) {
3166 status = NT_STATUS_FILE_IS_A_DIRECTORY;
3171 status = open_directory(
3172 conn, req, smb_fname, access_mask,
3173 share_access, create_disposition,
3174 create_options, file_attributes,
3179 if (!NT_STATUS_IS_OK(status)) {
3183 fsp->base_fsp = base_fsp;
3186 * According to the MS documentation, the only time the security
3187 * descriptor is applied to the opened file is iff we *created* the
3188 * file; an existing file stays the same.
3190 * Also, it seems (from observation) that you can open the file with
3191 * any access mask but you can still write the sd. We need to override
3192 * the granted access before we call set_sd
3193 * Patch for bug #2242 from Tom Lackemann <cessnatomny@yahoo.com>.
3196 if ((sd != NULL) && (info == FILE_WAS_CREATED)
3197 && lp_nt_acl_support(SNUM(conn))) {
3199 uint32_t sec_info_sent;
3200 uint32_t saved_access_mask = fsp->access_mask;
3202 sec_info_sent = get_sec_info(sd);
3204 fsp->access_mask = FILE_GENERIC_ALL;
3206 /* Convert all the generic bits. */
3207 security_acl_map_generic(sd->dacl, &file_generic_mapping);
3208 security_acl_map_generic(sd->sacl, &file_generic_mapping);
3210 if (sec_info_sent & (OWNER_SECURITY_INFORMATION|
3211 GROUP_SECURITY_INFORMATION|
3212 DACL_SECURITY_INFORMATION|
3213 SACL_SECURITY_INFORMATION)) {
3214 status = SMB_VFS_FSET_NT_ACL(fsp, sec_info_sent, sd);
3217 fsp->access_mask = saved_access_mask;
3219 if (!NT_STATUS_IS_OK(status)) {
3224 if ((ea_list != NULL) &&
3225 ((info == FILE_WAS_CREATED) || (info == FILE_WAS_OVERWRITTEN))) {
3226 status = set_ea(conn, fsp, fsp->fsp_name, ea_list);
3227 if (!NT_STATUS_IS_OK(status)) {
3232 if (!fsp->is_directory && S_ISDIR(fsp->fsp_name->st.st_ex_mode)) {
3233 status = NT_STATUS_ACCESS_DENIED;
3237 /* Save the requested allocation size. */
3238 if ((info == FILE_WAS_CREATED) || (info == FILE_WAS_OVERWRITTEN)) {
3240 && (allocation_size > fsp->fsp_name->st.st_ex_size)) {
3241 fsp->initial_allocation_size = smb_roundup(
3242 fsp->conn, allocation_size);
3243 if (fsp->is_directory) {
3244 /* Can't set allocation size on a directory. */
3245 status = NT_STATUS_ACCESS_DENIED;
3248 if (vfs_allocate_file_space(
3249 fsp, fsp->initial_allocation_size) == -1) {
3250 status = NT_STATUS_DISK_FULL;
3254 fsp->initial_allocation_size = smb_roundup(
3255 fsp->conn, (uint64_t)fsp->fsp_name->st.st_ex_size);
3259 DEBUG(10, ("create_file_unixpath: info=%d\n", info));
3262 if (pinfo != NULL) {
3266 smb_fname->st = fsp->fsp_name->st;
3268 return NT_STATUS_OK;
3271 DEBUG(10, ("create_file_unixpath: %s\n", nt_errstr(status)));
3274 if (base_fsp && fsp->base_fsp == base_fsp) {
3276 * The close_file below will close
3281 close_file(req, fsp, ERROR_CLOSE);
3284 if (base_fsp != NULL) {
3285 close_file(req, base_fsp, ERROR_CLOSE);
3292 * Calculate the full path name given a relative fid.
3294 NTSTATUS get_relative_fid_filename(connection_struct *conn,
3295 struct smb_request *req,
3296 uint16_t root_dir_fid,
3297 struct smb_filename *smb_fname)
3299 files_struct *dir_fsp;
3300 char *parent_fname = NULL;
3301 char *new_base_name = NULL;
3304 if (root_dir_fid == 0 || !smb_fname) {
3305 status = NT_STATUS_INTERNAL_ERROR;
3309 dir_fsp = file_fsp(req, root_dir_fid);
3311 if (dir_fsp == NULL) {
3312 status = NT_STATUS_INVALID_HANDLE;
3316 if (is_ntfs_stream_smb_fname(dir_fsp->fsp_name)) {
3317 status = NT_STATUS_INVALID_HANDLE;
3321 if (!dir_fsp->is_directory) {
3324 * Check to see if this is a mac fork of some kind.
3327 if ((conn->fs_capabilities & FILE_NAMED_STREAMS) &&
3328 is_ntfs_stream_smb_fname(smb_fname)) {
3329 status = NT_STATUS_OBJECT_PATH_NOT_FOUND;
3334 we need to handle the case when we get a
3335 relative open relative to a file and the
3336 pathname is blank - this is a reopen!
3337 (hint from demyn plantenberg)
3340 status = NT_STATUS_INVALID_HANDLE;
3344 if (ISDOT(dir_fsp->fsp_name->base_name)) {
3346 * We're at the toplevel dir, the final file name
3347 * must not contain ./, as this is filtered out
3348 * normally by srvstr_get_path and unix_convert
3349 * explicitly rejects paths containing ./.
3351 parent_fname = talloc_strdup(talloc_tos(), "");
3352 if (parent_fname == NULL) {
3353 status = NT_STATUS_NO_MEMORY;
3357 size_t dir_name_len = strlen(dir_fsp->fsp_name->base_name);
3360 * Copy in the base directory name.
3363 parent_fname = TALLOC_ARRAY(talloc_tos(), char,
3365 if (parent_fname == NULL) {
3366 status = NT_STATUS_NO_MEMORY;
3369 memcpy(parent_fname, dir_fsp->fsp_name->base_name,
3373 * Ensure it ends in a '/'.
3374 * We used TALLOC_SIZE +2 to add space for the '/'.
3378 && (parent_fname[dir_name_len-1] != '\\')
3379 && (parent_fname[dir_name_len-1] != '/')) {
3380 parent_fname[dir_name_len] = '/';
3381 parent_fname[dir_name_len+1] = '\0';
3385 new_base_name = talloc_asprintf(smb_fname, "%s%s", parent_fname,
3386 smb_fname->base_name);
3387 if (new_base_name == NULL) {
3388 status = NT_STATUS_NO_MEMORY;
3392 TALLOC_FREE(smb_fname->base_name);
3393 smb_fname->base_name = new_base_name;
3394 status = NT_STATUS_OK;
3397 TALLOC_FREE(parent_fname);
3401 NTSTATUS create_file_default(connection_struct *conn,
3402 struct smb_request *req,
3403 uint16_t root_dir_fid,
3404 struct smb_filename *smb_fname,
3405 uint32_t access_mask,
3406 uint32_t share_access,
3407 uint32_t create_disposition,
3408 uint32_t create_options,
3409 uint32_t file_attributes,
3410 uint32_t oplock_request,
3411 uint64_t allocation_size,
3412 uint32_t private_flags,
3413 struct security_descriptor *sd,
3414 struct ea_list *ea_list,
3415 files_struct **result,
3418 int info = FILE_WAS_OPENED;
3419 files_struct *fsp = NULL;
3422 DEBUG(10,("create_file: access_mask = 0x%x "
3423 "file_attributes = 0x%x, share_access = 0x%x, "
3424 "create_disposition = 0x%x create_options = 0x%x "
3425 "oplock_request = 0x%x "
3426 "private_flags = 0x%x "
3427 "root_dir_fid = 0x%x, ea_list = 0x%p, sd = 0x%p, "
3429 (unsigned int)access_mask,
3430 (unsigned int)file_attributes,
3431 (unsigned int)share_access,
3432 (unsigned int)create_disposition,
3433 (unsigned int)create_options,
3434 (unsigned int)oplock_request,
3435 (unsigned int)private_flags,
3436 (unsigned int)root_dir_fid,
3437 ea_list, sd, smb_fname_str_dbg(smb_fname)));
3440 * Calculate the filename from the root_dir_if if necessary.
3443 if (root_dir_fid != 0) {
3444 status = get_relative_fid_filename(conn, req, root_dir_fid,
3446 if (!NT_STATUS_IS_OK(status)) {
3452 * Check to see if this is a mac fork of some kind.
3455 if (is_ntfs_stream_smb_fname(smb_fname)) {
3456 enum FAKE_FILE_TYPE fake_file_type;
3458 fake_file_type = is_fake_file(smb_fname);
3460 if (fake_file_type != FAKE_FILE_TYPE_NONE) {
3463 * Here we go! support for changing the disk quotas
3466 * We need to fake up to open this MAGIC QUOTA file
3467 * and return a valid FID.
3469 * w2k close this file directly after openening xp
3470 * also tries a QUERY_FILE_INFO on the file and then
3473 status = open_fake_file(req, conn, req->vuid,
3474 fake_file_type, smb_fname,
3476 if (!NT_STATUS_IS_OK(status)) {
3480 ZERO_STRUCT(smb_fname->st);
3484 if (!(conn->fs_capabilities & FILE_NAMED_STREAMS)) {
3485 status = NT_STATUS_OBJECT_NAME_NOT_FOUND;
3490 /* All file access must go through check_name() */
3492 status = check_name(conn, smb_fname->base_name);
3493 if (!NT_STATUS_IS_OK(status)) {
3497 status = create_file_unixpath(
3498 conn, req, smb_fname, access_mask, share_access,
3499 create_disposition, create_options, file_attributes,
3500 oplock_request, allocation_size, private_flags,
3504 if (!NT_STATUS_IS_OK(status)) {
3509 DEBUG(10, ("create_file: info=%d\n", info));
3512 if (pinfo != NULL) {
3515 return NT_STATUS_OK;
3518 DEBUG(10, ("create_file: %s\n", nt_errstr(status)));
3521 close_file(req, fsp, ERROR_CLOSE);