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 struct current_user current_user;
26 extern const struct generic_mapping file_generic_mapping;
28 struct deferred_open_record {
29 bool delayed_for_oplocks;
33 static NTSTATUS create_file_unixpath(connection_struct *conn,
34 struct smb_request *req,
35 struct smb_filename *smb_fname,
37 uint32_t share_access,
38 uint32_t create_disposition,
39 uint32_t create_options,
40 uint32_t file_attributes,
41 uint32_t oplock_request,
42 uint64_t allocation_size,
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(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 (conn->server_info->utok.uid == 0 || conn->admin_user) {
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 conn->server_info->ptok,
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,6,exclusive->op_type | FORCE_OPLOCK_BREAK_TO_NONE);
913 status = messaging_send_buf(smbd_messaging_context(), exclusive->pid,
914 MSG_SMB_BREAK_REQUEST,
916 MSG_SMB_SHARE_MODE_ENTRY_SIZE);
917 if (!NT_STATUS_IS_OK(status)) {
918 DEBUG(3, ("Could not send oplock break message: %s\n",
926 * 1) No files open at all or internal open: Grant whatever the client wants.
928 * 2) Exclusive (or batch) oplock around: If the requested access is a delete
929 * request, break if the oplock around is a batch oplock. If it's another
930 * requested access type, break.
932 * 3) Only level2 around: Grant level2 and do nothing else.
935 static bool delay_for_oplocks(struct share_mode_lock *lck,
942 struct share_mode_entry *exclusive = NULL;
943 bool valid_entry = false;
944 bool have_level2 = false;
945 bool have_a_none_oplock = false;
946 bool allow_level2 = (global_client_caps & CAP_LEVEL_II_OPLOCKS) &&
947 lp_level2_oplocks(SNUM(fsp->conn));
949 if (oplock_request & INTERNAL_OPEN_ONLY) {
950 fsp->oplock_type = NO_OPLOCK;
953 if ((oplock_request & INTERNAL_OPEN_ONLY) || is_stat_open(fsp->access_mask)) {
957 for (i=0; i<lck->num_share_modes; i++) {
959 if (!is_valid_share_mode_entry(&lck->share_modes[i])) {
963 /* At least one entry is not an invalid or deferred entry. */
966 if (pass_number == 1) {
967 if (BATCH_OPLOCK_TYPE(lck->share_modes[i].op_type)) {
968 SMB_ASSERT(exclusive == NULL);
969 exclusive = &lck->share_modes[i];
972 if (EXCLUSIVE_OPLOCK_TYPE(lck->share_modes[i].op_type)) {
973 SMB_ASSERT(exclusive == NULL);
974 exclusive = &lck->share_modes[i];
978 if (LEVEL_II_OPLOCK_TYPE(lck->share_modes[i].op_type)) {
979 SMB_ASSERT(exclusive == NULL);
983 if (lck->share_modes[i].op_type == NO_OPLOCK) {
984 have_a_none_oplock = true;
988 if (exclusive != NULL) { /* Found an exclusive oplock */
989 bool delay_it = is_delete_request(fsp) ?
990 BATCH_OPLOCK_TYPE(exclusive->op_type) : true;
991 SMB_ASSERT(!have_level2);
993 send_break_message(fsp, exclusive, mid, oplock_request);
999 * Match what was requested (fsp->oplock_type) with
1000 * what was found in the existing share modes.
1004 /* All entries are placeholders or deferred.
1005 * Directly grant whatever the client wants. */
1006 if (fsp->oplock_type == NO_OPLOCK) {
1007 /* Store a level2 oplock, but don't tell the client */
1008 fsp->oplock_type = FAKE_LEVEL_II_OPLOCK;
1010 } else if (have_a_none_oplock) {
1011 fsp->oplock_type = NO_OPLOCK;
1012 } else if (have_level2) {
1013 if (fsp->oplock_type == NO_OPLOCK ||
1014 fsp->oplock_type == FAKE_LEVEL_II_OPLOCK) {
1015 /* Store a level2 oplock, but don't tell the client */
1016 fsp->oplock_type = FAKE_LEVEL_II_OPLOCK;
1018 fsp->oplock_type = LEVEL_II_OPLOCK;
1021 /* This case can never happen. */
1026 * Don't grant level2 to clients that don't want them
1027 * or if we've turned them off.
1029 if (fsp->oplock_type == LEVEL_II_OPLOCK && !allow_level2) {
1030 fsp->oplock_type = FAKE_LEVEL_II_OPLOCK;
1033 DEBUG(10,("delay_for_oplocks: oplock type 0x%x on file %s\n",
1034 fsp->oplock_type, fsp_str_dbg(fsp)));
1040 bool request_timed_out(struct timeval request_time,
1041 struct timeval timeout)
1043 struct timeval now, end_time;
1045 end_time = timeval_sum(&request_time, &timeout);
1046 return (timeval_compare(&end_time, &now) < 0);
1049 /****************************************************************************
1050 Handle the 1 second delay in returning a SHARING_VIOLATION error.
1051 ****************************************************************************/
1053 static void defer_open(struct share_mode_lock *lck,
1054 struct timeval request_time,
1055 struct timeval timeout,
1056 struct smb_request *req,
1057 struct deferred_open_record *state)
1061 /* Paranoia check */
1063 for (i=0; i<lck->num_share_modes; i++) {
1064 struct share_mode_entry *e = &lck->share_modes[i];
1066 if (!is_deferred_open_entry(e)) {
1070 if (procid_is_me(&e->pid) && (e->op_mid == req->mid)) {
1071 DEBUG(0, ("Trying to defer an already deferred "
1072 "request: mid=%d, exiting\n", req->mid));
1073 exit_server("attempt to defer a deferred request");
1077 /* End paranoia check */
1079 DEBUG(10,("defer_open_sharing_error: time [%u.%06u] adding deferred "
1080 "open entry for mid %u\n",
1081 (unsigned int)request_time.tv_sec,
1082 (unsigned int)request_time.tv_usec,
1083 (unsigned int)req->mid));
1085 if (!push_deferred_smb_message(req, request_time, timeout,
1086 (char *)state, sizeof(*state))) {
1087 exit_server("push_deferred_smb_message failed");
1089 add_deferred_open(lck, req->mid, request_time, state->id);
1093 /****************************************************************************
1094 On overwrite open ensure that the attributes match.
1095 ****************************************************************************/
1097 bool open_match_attributes(connection_struct *conn,
1098 uint32 old_dos_attr,
1099 uint32 new_dos_attr,
1100 mode_t existing_unx_mode,
1101 mode_t new_unx_mode,
1102 mode_t *returned_unx_mode)
1104 uint32 noarch_old_dos_attr, noarch_new_dos_attr;
1106 noarch_old_dos_attr = (old_dos_attr & ~FILE_ATTRIBUTE_ARCHIVE);
1107 noarch_new_dos_attr = (new_dos_attr & ~FILE_ATTRIBUTE_ARCHIVE);
1109 if((noarch_old_dos_attr == 0 && noarch_new_dos_attr != 0) ||
1110 (noarch_old_dos_attr != 0 && ((noarch_old_dos_attr & noarch_new_dos_attr) == noarch_old_dos_attr))) {
1111 *returned_unx_mode = new_unx_mode;
1113 *returned_unx_mode = (mode_t)0;
1116 DEBUG(10,("open_match_attributes: old_dos_attr = 0x%x, "
1117 "existing_unx_mode = 0%o, new_dos_attr = 0x%x "
1118 "returned_unx_mode = 0%o\n",
1119 (unsigned int)old_dos_attr,
1120 (unsigned int)existing_unx_mode,
1121 (unsigned int)new_dos_attr,
1122 (unsigned int)*returned_unx_mode ));
1124 /* If we're mapping SYSTEM and HIDDEN ensure they match. */
1125 if (lp_map_system(SNUM(conn)) || lp_store_dos_attributes(SNUM(conn))) {
1126 if ((old_dos_attr & FILE_ATTRIBUTE_SYSTEM) &&
1127 !(new_dos_attr & FILE_ATTRIBUTE_SYSTEM)) {
1131 if (lp_map_hidden(SNUM(conn)) || lp_store_dos_attributes(SNUM(conn))) {
1132 if ((old_dos_attr & FILE_ATTRIBUTE_HIDDEN) &&
1133 !(new_dos_attr & FILE_ATTRIBUTE_HIDDEN)) {
1140 /****************************************************************************
1141 Special FCB or DOS processing in the case of a sharing violation.
1142 Try and find a duplicated file handle.
1143 ****************************************************************************/
1145 NTSTATUS fcb_or_dos_open(struct smb_request *req,
1146 connection_struct *conn,
1147 files_struct *fsp_to_dup_into,
1148 const struct smb_filename *smb_fname,
1153 uint32 share_access,
1154 uint32 create_options)
1158 DEBUG(5,("fcb_or_dos_open: attempting old open semantics for "
1159 "file %s.\n", smb_fname_str_dbg(smb_fname)));
1161 for(fsp = file_find_di_first(id); fsp;
1162 fsp = file_find_di_next(fsp)) {
1164 DEBUG(10,("fcb_or_dos_open: checking file %s, fd = %d, "
1165 "vuid = %u, file_pid = %u, private_options = 0x%x "
1166 "access_mask = 0x%x\n", fsp_str_dbg(fsp),
1167 fsp->fh->fd, (unsigned int)fsp->vuid,
1168 (unsigned int)fsp->file_pid,
1169 (unsigned int)fsp->fh->private_options,
1170 (unsigned int)fsp->access_mask ));
1172 if (fsp->fh->fd != -1 &&
1173 fsp->vuid == vuid &&
1174 fsp->file_pid == file_pid &&
1175 (fsp->fh->private_options & (NTCREATEX_OPTIONS_PRIVATE_DENY_DOS |
1176 NTCREATEX_OPTIONS_PRIVATE_DENY_FCB)) &&
1177 (fsp->access_mask & FILE_WRITE_DATA) &&
1178 strequal(fsp->fsp_name->base_name, smb_fname->base_name) &&
1179 strequal(fsp->fsp_name->stream_name,
1180 smb_fname->stream_name)) {
1181 DEBUG(10,("fcb_or_dos_open: file match\n"));
1187 return NT_STATUS_NOT_FOUND;
1190 /* quite an insane set of semantics ... */
1191 if (is_executable(smb_fname->base_name) &&
1192 (fsp->fh->private_options & NTCREATEX_OPTIONS_PRIVATE_DENY_DOS)) {
1193 DEBUG(10,("fcb_or_dos_open: file fail due to is_executable.\n"));
1194 return NT_STATUS_INVALID_PARAMETER;
1197 /* We need to duplicate this fsp. */
1198 return dup_file_fsp(req, fsp, access_mask, share_access,
1199 create_options, fsp_to_dup_into);
1202 /****************************************************************************
1203 Open a file with a share mode - old openX method - map into NTCreate.
1204 ****************************************************************************/
1206 bool map_open_params_to_ntcreate(const struct smb_filename *smb_fname,
1207 int deny_mode, int open_func,
1208 uint32 *paccess_mask,
1209 uint32 *pshare_mode,
1210 uint32 *pcreate_disposition,
1211 uint32 *pcreate_options)
1215 uint32 create_disposition;
1216 uint32 create_options = FILE_NON_DIRECTORY_FILE;
1218 DEBUG(10,("map_open_params_to_ntcreate: fname = %s, deny_mode = 0x%x, "
1219 "open_func = 0x%x\n",
1220 smb_fname_str_dbg(smb_fname), (unsigned int)deny_mode,
1221 (unsigned int)open_func ));
1223 /* Create the NT compatible access_mask. */
1224 switch (GET_OPENX_MODE(deny_mode)) {
1225 case DOS_OPEN_EXEC: /* Implies read-only - used to be FILE_READ_DATA */
1226 case DOS_OPEN_RDONLY:
1227 access_mask = FILE_GENERIC_READ;
1229 case DOS_OPEN_WRONLY:
1230 access_mask = FILE_GENERIC_WRITE;
1234 access_mask = FILE_GENERIC_READ|FILE_GENERIC_WRITE;
1237 DEBUG(10,("map_open_params_to_ntcreate: bad open mode = 0x%x\n",
1238 (unsigned int)GET_OPENX_MODE(deny_mode)));
1242 /* Create the NT compatible create_disposition. */
1243 switch (open_func) {
1244 case OPENX_FILE_EXISTS_FAIL|OPENX_FILE_CREATE_IF_NOT_EXIST:
1245 create_disposition = FILE_CREATE;
1248 case OPENX_FILE_EXISTS_OPEN:
1249 create_disposition = FILE_OPEN;
1252 case OPENX_FILE_EXISTS_OPEN|OPENX_FILE_CREATE_IF_NOT_EXIST:
1253 create_disposition = FILE_OPEN_IF;
1256 case OPENX_FILE_EXISTS_TRUNCATE:
1257 create_disposition = FILE_OVERWRITE;
1260 case OPENX_FILE_EXISTS_TRUNCATE|OPENX_FILE_CREATE_IF_NOT_EXIST:
1261 create_disposition = FILE_OVERWRITE_IF;
1265 /* From samba4 - to be confirmed. */
1266 if (GET_OPENX_MODE(deny_mode) == DOS_OPEN_EXEC) {
1267 create_disposition = FILE_CREATE;
1270 DEBUG(10,("map_open_params_to_ntcreate: bad "
1271 "open_func 0x%x\n", (unsigned int)open_func));
1275 /* Create the NT compatible share modes. */
1276 switch (GET_DENY_MODE(deny_mode)) {
1278 share_mode = FILE_SHARE_NONE;
1282 share_mode = FILE_SHARE_READ;
1286 share_mode = FILE_SHARE_WRITE;
1290 share_mode = FILE_SHARE_READ|FILE_SHARE_WRITE;
1294 create_options |= NTCREATEX_OPTIONS_PRIVATE_DENY_DOS;
1295 if (is_executable(smb_fname->base_name)) {
1296 share_mode = FILE_SHARE_READ|FILE_SHARE_WRITE;
1298 if (GET_OPENX_MODE(deny_mode) == DOS_OPEN_RDONLY) {
1299 share_mode = FILE_SHARE_READ;
1301 share_mode = FILE_SHARE_NONE;
1307 create_options |= NTCREATEX_OPTIONS_PRIVATE_DENY_FCB;
1308 share_mode = FILE_SHARE_NONE;
1312 DEBUG(10,("map_open_params_to_ntcreate: bad deny_mode 0x%x\n",
1313 (unsigned int)GET_DENY_MODE(deny_mode) ));
1317 DEBUG(10,("map_open_params_to_ntcreate: file %s, access_mask = 0x%x, "
1318 "share_mode = 0x%x, create_disposition = 0x%x, "
1319 "create_options = 0x%x\n",
1320 smb_fname_str_dbg(smb_fname),
1321 (unsigned int)access_mask,
1322 (unsigned int)share_mode,
1323 (unsigned int)create_disposition,
1324 (unsigned int)create_options ));
1327 *paccess_mask = access_mask;
1330 *pshare_mode = share_mode;
1332 if (pcreate_disposition) {
1333 *pcreate_disposition = create_disposition;
1335 if (pcreate_options) {
1336 *pcreate_options = create_options;
1343 static void schedule_defer_open(struct share_mode_lock *lck,
1344 struct timeval request_time,
1345 struct smb_request *req)
1347 struct deferred_open_record state;
1349 /* This is a relative time, added to the absolute
1350 request_time value to get the absolute timeout time.
1351 Note that if this is the second or greater time we enter
1352 this codepath for this particular request mid then
1353 request_time is left as the absolute time of the *first*
1354 time this request mid was processed. This is what allows
1355 the request to eventually time out. */
1357 struct timeval timeout;
1359 /* Normally the smbd we asked should respond within
1360 * OPLOCK_BREAK_TIMEOUT seconds regardless of whether
1361 * the client did, give twice the timeout as a safety
1362 * measure here in case the other smbd is stuck
1363 * somewhere else. */
1365 timeout = timeval_set(OPLOCK_BREAK_TIMEOUT*2, 0);
1367 /* Nothing actually uses state.delayed_for_oplocks
1368 but it's handy to differentiate in debug messages
1369 between a 30 second delay due to oplock break, and
1370 a 1 second delay for share mode conflicts. */
1372 state.delayed_for_oplocks = True;
1375 if (!request_timed_out(request_time, timeout)) {
1376 defer_open(lck, request_time, timeout, req, &state);
1380 /****************************************************************************
1381 Work out what access_mask to use from what the client sent us.
1382 ****************************************************************************/
1384 static NTSTATUS calculate_access_mask(connection_struct *conn,
1385 const struct smb_filename *smb_fname,
1387 uint32_t access_mask,
1388 uint32_t *access_mask_out)
1393 * Convert GENERIC bits to specific bits.
1396 se_map_generic(&access_mask, &file_generic_mapping);
1398 /* Calculate MAXIMUM_ALLOWED_ACCESS if requested. */
1399 if (access_mask & MAXIMUM_ALLOWED_ACCESS) {
1402 struct security_descriptor *sd;
1403 uint32_t access_granted = 0;
1405 status = SMB_VFS_GET_NT_ACL(conn, smb_fname->base_name,
1406 (OWNER_SECURITY_INFORMATION |
1407 GROUP_SECURITY_INFORMATION |
1408 DACL_SECURITY_INFORMATION),&sd);
1410 if (!NT_STATUS_IS_OK(status)) {
1411 DEBUG(10, ("calculate_access_mask: Could not get acl "
1413 smb_fname_str_dbg(smb_fname),
1414 nt_errstr(status)));
1415 return NT_STATUS_ACCESS_DENIED;
1418 status = smb1_file_se_access_check(conn,
1420 conn->server_info->ptok,
1426 if (!NT_STATUS_IS_OK(status)) {
1427 DEBUG(10, ("calculate_access_mask: Access denied on "
1428 "file %s: when calculating maximum access\n",
1429 smb_fname_str_dbg(smb_fname)));
1430 return NT_STATUS_ACCESS_DENIED;
1433 access_mask = access_granted;
1435 access_mask = FILE_GENERIC_ALL;
1439 *access_mask_out = access_mask;
1440 return NT_STATUS_OK;
1443 /****************************************************************************
1444 Open a file with a share mode. Passed in an already created files_struct *.
1445 ****************************************************************************/
1447 static NTSTATUS open_file_ntcreate(connection_struct *conn,
1448 struct smb_request *req,
1449 uint32 access_mask, /* access bits (FILE_READ_DATA etc.) */
1450 uint32 share_access, /* share constants (FILE_SHARE_READ etc) */
1451 uint32 create_disposition, /* FILE_OPEN_IF etc. */
1452 uint32 create_options, /* options such as delete on close. */
1453 uint32 new_dos_attributes, /* attributes used for new file. */
1454 int oplock_request, /* internal Samba oplock codes. */
1455 /* Information (FILE_EXISTS etc.) */
1459 struct smb_filename *smb_fname = fsp->fsp_name;
1462 bool file_existed = VALID_STAT(smb_fname->st);
1463 bool def_acl = False;
1464 bool posix_open = False;
1465 bool new_file_created = False;
1466 bool clear_ads = false;
1468 NTSTATUS fsp_open = NT_STATUS_ACCESS_DENIED;
1469 mode_t new_unx_mode = (mode_t)0;
1470 mode_t unx_mode = (mode_t)0;
1472 uint32 existing_dos_attributes = 0;
1473 struct pending_message_list *pml = NULL;
1474 struct timeval request_time = timeval_zero();
1475 struct share_mode_lock *lck = NULL;
1476 uint32 open_access_mask = access_mask;
1482 /* Windows allows a new file to be created and
1483 silently removes a FILE_ATTRIBUTE_DIRECTORY
1484 sent by the client. Do the same. */
1486 new_dos_attributes &= ~FILE_ATTRIBUTE_DIRECTORY;
1488 if (conn->printer) {
1490 * Printers are handled completely differently.
1491 * Most of the passed parameters are ignored.
1495 *pinfo = FILE_WAS_CREATED;
1498 DEBUG(10, ("open_file_ntcreate: printer open fname=%s\n",
1499 smb_fname_str_dbg(smb_fname)));
1502 DEBUG(0,("open_file_ntcreate: printer open without "
1503 "an SMB request!\n"));
1504 return NT_STATUS_INTERNAL_ERROR;
1507 return print_fsp_open(req, conn, smb_fname->base_name,
1511 if (!parent_dirname(talloc_tos(), smb_fname->base_name, &parent_dir,
1513 return NT_STATUS_NO_MEMORY;
1516 if (new_dos_attributes & FILE_FLAG_POSIX_SEMANTICS) {
1518 unx_mode = (mode_t)(new_dos_attributes & ~FILE_FLAG_POSIX_SEMANTICS);
1519 new_dos_attributes = 0;
1521 /* We add aARCH to this as this mode is only used if the file is
1523 unx_mode = unix_mode(conn, new_dos_attributes | aARCH,
1524 smb_fname, parent_dir);
1527 DEBUG(10, ("open_file_ntcreate: fname=%s, dos_attrs=0x%x "
1528 "access_mask=0x%x share_access=0x%x "
1529 "create_disposition = 0x%x create_options=0x%x "
1530 "unix mode=0%o oplock_request=%d\n",
1531 smb_fname_str_dbg(smb_fname), new_dos_attributes,
1532 access_mask, share_access, create_disposition,
1533 create_options, (unsigned int)unx_mode, oplock_request));
1535 if ((req == NULL) && ((oplock_request & INTERNAL_OPEN_ONLY) == 0)) {
1536 DEBUG(0, ("No smb request but not an internal only open!\n"));
1537 return NT_STATUS_INTERNAL_ERROR;
1541 * Only non-internal opens can be deferred at all
1545 && ((pml = get_open_deferred_message(req->mid)) != NULL)) {
1546 struct deferred_open_record *state =
1547 (struct deferred_open_record *)pml->private_data.data;
1549 /* Remember the absolute time of the original
1550 request with this mid. We'll use it later to
1551 see if this has timed out. */
1553 request_time = pml->request_time;
1555 /* Remove the deferred open entry under lock. */
1556 lck = get_share_mode_lock(talloc_tos(), state->id, NULL, NULL,
1559 DEBUG(0, ("could not get share mode lock\n"));
1561 del_deferred_open_entry(lck, req->mid);
1565 /* Ensure we don't reprocess this message. */
1566 remove_deferred_open_smb_message(req->mid);
1569 status = check_name(conn, smb_fname->base_name);
1570 if (!NT_STATUS_IS_OK(status)) {
1575 new_dos_attributes &= SAMBA_ATTRIBUTES_MASK;
1577 existing_dos_attributes = dos_mode(conn, smb_fname);
1581 /* ignore any oplock requests if oplocks are disabled */
1582 if (!lp_oplocks(SNUM(conn)) || global_client_failed_oplock_break ||
1583 IS_VETO_OPLOCK_PATH(conn, smb_fname->base_name)) {
1584 /* Mask off everything except the private Samba bits. */
1585 oplock_request &= SAMBA_PRIVATE_OPLOCK_MASK;
1588 /* this is for OS/2 long file names - say we don't support them */
1589 if (!lp_posix_pathnames() && strstr(smb_fname->base_name,".+,;=[].")) {
1590 /* OS/2 Workplace shell fix may be main code stream in a later
1592 DEBUG(5,("open_file_ntcreate: OS/2 long filenames are not "
1594 if (use_nt_status()) {
1595 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1597 return NT_STATUS_DOS(ERRDOS, ERRcannotopen);
1600 switch( create_disposition ) {
1602 * Currently we're using FILE_SUPERSEDE as the same as
1603 * FILE_OVERWRITE_IF but they really are
1604 * different. FILE_SUPERSEDE deletes an existing file
1605 * (requiring delete access) then recreates it.
1607 case FILE_SUPERSEDE:
1608 /* If file exists replace/overwrite. If file doesn't
1610 flags2 |= (O_CREAT | O_TRUNC);
1614 case FILE_OVERWRITE_IF:
1615 /* If file exists replace/overwrite. If file doesn't
1617 flags2 |= (O_CREAT | O_TRUNC);
1622 /* If file exists open. If file doesn't exist error. */
1623 if (!file_existed) {
1624 DEBUG(5,("open_file_ntcreate: FILE_OPEN "
1625 "requested for file %s and file "
1627 smb_fname_str_dbg(smb_fname)));
1629 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1633 case FILE_OVERWRITE:
1634 /* If file exists overwrite. If file doesn't exist
1636 if (!file_existed) {
1637 DEBUG(5,("open_file_ntcreate: FILE_OVERWRITE "
1638 "requested for file %s and file "
1640 smb_fname_str_dbg(smb_fname) ));
1642 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1649 /* If file exists error. If file doesn't exist
1652 DEBUG(5,("open_file_ntcreate: FILE_CREATE "
1653 "requested for file %s and file "
1654 "already exists.\n",
1655 smb_fname_str_dbg(smb_fname)));
1656 if (S_ISDIR(smb_fname->st.st_ex_mode)) {
1661 return map_nt_error_from_unix(errno);
1663 flags2 |= (O_CREAT|O_EXCL);
1667 /* If file exists open. If file doesn't exist
1673 return NT_STATUS_INVALID_PARAMETER;
1676 /* We only care about matching attributes on file exists and
1679 if (!posix_open && file_existed && ((create_disposition == FILE_OVERWRITE) ||
1680 (create_disposition == FILE_OVERWRITE_IF))) {
1681 if (!open_match_attributes(conn, existing_dos_attributes,
1683 smb_fname->st.st_ex_mode,
1684 unx_mode, &new_unx_mode)) {
1685 DEBUG(5,("open_file_ntcreate: attributes missmatch "
1686 "for file %s (%x %x) (0%o, 0%o)\n",
1687 smb_fname_str_dbg(smb_fname),
1688 existing_dos_attributes,
1690 (unsigned int)smb_fname->st.st_ex_mode,
1691 (unsigned int)unx_mode ));
1693 return NT_STATUS_ACCESS_DENIED;
1697 status = calculate_access_mask(conn, smb_fname, file_existed,
1700 if (!NT_STATUS_IS_OK(status)) {
1701 DEBUG(10, ("open_file_ntcreate: calculate_access_mask "
1702 "on file %s returned %s\n",
1703 smb_fname_str_dbg(smb_fname), nt_errstr(status)));
1707 open_access_mask = access_mask;
1709 if ((flags2 & O_TRUNC) || (oplock_request & FORCE_OPLOCK_BREAK_TO_NONE)) {
1710 open_access_mask |= FILE_WRITE_DATA; /* This will cause oplock breaks. */
1713 DEBUG(10, ("open_file_ntcreate: fname=%s, after mapping "
1714 "access_mask=0x%x\n", smb_fname_str_dbg(smb_fname),
1718 * Note that we ignore the append flag as append does not
1719 * mean the same thing under DOS and Unix.
1722 if ((access_mask & (FILE_WRITE_DATA | FILE_APPEND_DATA)) ||
1723 (oplock_request & FORCE_OPLOCK_BREAK_TO_NONE)) {
1724 /* DENY_DOS opens are always underlying read-write on the
1725 file handle, no matter what the requested access mask
1727 if ((create_options & NTCREATEX_OPTIONS_PRIVATE_DENY_DOS) ||
1728 access_mask & (FILE_READ_ATTRIBUTES|FILE_READ_DATA|FILE_READ_EA|FILE_EXECUTE)) {
1738 * Currently we only look at FILE_WRITE_THROUGH for create options.
1742 if ((create_options & FILE_WRITE_THROUGH) && lp_strict_sync(SNUM(conn))) {
1747 if (posix_open && (access_mask & FILE_APPEND_DATA)) {
1751 if (!posix_open && !CAN_WRITE(conn)) {
1753 * We should really return a permission denied error if either
1754 * O_CREAT or O_TRUNC are set, but for compatibility with
1755 * older versions of Samba we just AND them out.
1757 flags2 &= ~(O_CREAT|O_TRUNC);
1761 * Ensure we can't write on a read-only share or file.
1764 if (flags != O_RDONLY && file_existed &&
1765 (!CAN_WRITE(conn) || IS_DOS_READONLY(existing_dos_attributes))) {
1766 DEBUG(5,("open_file_ntcreate: write access requested for "
1767 "file %s on read only %s\n",
1768 smb_fname_str_dbg(smb_fname),
1769 !CAN_WRITE(conn) ? "share" : "file" ));
1771 return NT_STATUS_ACCESS_DENIED;
1774 fsp->file_id = vfs_file_id_from_sbuf(conn, &smb_fname->st);
1775 fsp->share_access = share_access;
1776 fsp->fh->private_options = create_options;
1777 fsp->access_mask = open_access_mask; /* We change this to the
1778 * requested access_mask after
1779 * the open is done. */
1780 fsp->posix_open = posix_open;
1782 /* Ensure no SAMBA_PRIVATE bits can be set. */
1783 fsp->oplock_type = (oplock_request & ~SAMBA_PRIVATE_OPLOCK_MASK);
1785 if (timeval_is_zero(&request_time)) {
1786 request_time = fsp->open_time;
1790 struct timespec old_write_time = smb_fname->st.st_ex_mtime;
1791 id = vfs_file_id_from_sbuf(conn, &smb_fname->st);
1793 lck = get_share_mode_lock(talloc_tos(), id,
1795 smb_fname, &old_write_time);
1798 DEBUG(0, ("Could not get share mode lock\n"));
1799 return NT_STATUS_SHARING_VIOLATION;
1802 /* First pass - send break only on batch oplocks. */
1804 && delay_for_oplocks(lck, fsp, req->mid, 1,
1806 schedule_defer_open(lck, request_time, req);
1808 return NT_STATUS_SHARING_VIOLATION;
1811 /* Use the client requested access mask here, not the one we
1813 status = open_mode_check(conn, lck, access_mask, share_access,
1814 create_options, &file_existed);
1816 if (NT_STATUS_IS_OK(status)) {
1817 /* We might be going to allow this open. Check oplock
1819 /* Second pass - send break for both batch or
1820 * exclusive oplocks. */
1822 && delay_for_oplocks(lck, fsp, req->mid, 2,
1824 schedule_defer_open(lck, request_time, req);
1826 return NT_STATUS_SHARING_VIOLATION;
1830 if (NT_STATUS_EQUAL(status, NT_STATUS_DELETE_PENDING)) {
1831 /* DELETE_PENDING is not deferred for a second */
1836 if (!NT_STATUS_IS_OK(status)) {
1837 uint32 can_access_mask;
1838 bool can_access = True;
1840 SMB_ASSERT(NT_STATUS_EQUAL(status, NT_STATUS_SHARING_VIOLATION));
1842 /* Check if this can be done with the deny_dos and fcb
1844 if (create_options &
1845 (NTCREATEX_OPTIONS_PRIVATE_DENY_DOS|
1846 NTCREATEX_OPTIONS_PRIVATE_DENY_FCB)) {
1848 DEBUG(0, ("DOS open without an SMB "
1851 return NT_STATUS_INTERNAL_ERROR;
1854 /* Use the client requested access mask here,
1855 * not the one we open with. */
1856 status = fcb_or_dos_open(req,
1867 if (NT_STATUS_IS_OK(status)) {
1870 *pinfo = FILE_WAS_OPENED;
1872 return NT_STATUS_OK;
1877 * This next line is a subtlety we need for
1878 * MS-Access. If a file open will fail due to share
1879 * permissions and also for security (access) reasons,
1880 * we need to return the access failed error, not the
1881 * share error. We can't open the file due to kernel
1882 * oplock deadlock (it's possible we failed above on
1883 * the open_mode_check()) so use a userspace check.
1886 if (flags & O_RDWR) {
1887 can_access_mask = FILE_READ_DATA|FILE_WRITE_DATA;
1888 } else if (flags & O_WRONLY) {
1889 can_access_mask = FILE_WRITE_DATA;
1891 can_access_mask = FILE_READ_DATA;
1894 if (((can_access_mask & FILE_WRITE_DATA) &&
1895 !CAN_WRITE(conn)) ||
1896 !can_access_file_data(conn, smb_fname,
1902 * If we're returning a share violation, ensure we
1903 * cope with the braindead 1 second delay.
1906 if (!(oplock_request & INTERNAL_OPEN_ONLY) &&
1907 lp_defer_sharing_violations()) {
1908 struct timeval timeout;
1909 struct deferred_open_record state;
1912 /* this is a hack to speed up torture tests
1914 timeout_usecs = lp_parm_int(SNUM(conn),
1915 "smbd","sharedelay",
1916 SHARING_VIOLATION_USEC_WAIT);
1918 /* This is a relative time, added to the absolute
1919 request_time value to get the absolute timeout time.
1920 Note that if this is the second or greater time we enter
1921 this codepath for this particular request mid then
1922 request_time is left as the absolute time of the *first*
1923 time this request mid was processed. This is what allows
1924 the request to eventually time out. */
1926 timeout = timeval_set(0, timeout_usecs);
1928 /* Nothing actually uses state.delayed_for_oplocks
1929 but it's handy to differentiate in debug messages
1930 between a 30 second delay due to oplock break, and
1931 a 1 second delay for share mode conflicts. */
1933 state.delayed_for_oplocks = False;
1937 && !request_timed_out(request_time,
1939 defer_open(lck, request_time, timeout,
1947 * We have detected a sharing violation here
1948 * so return the correct error code
1950 status = NT_STATUS_SHARING_VIOLATION;
1952 status = NT_STATUS_ACCESS_DENIED;
1958 * We exit this block with the share entry *locked*.....
1962 SMB_ASSERT(!file_existed || (lck != NULL));
1965 * Ensure we pay attention to default ACLs on directories if required.
1968 if ((flags2 & O_CREAT) && lp_inherit_acls(SNUM(conn)) &&
1969 (def_acl = directory_has_default_acl(conn, parent_dir))) {
1970 unx_mode = (0777 & lp_create_mask(SNUM(conn)));
1973 DEBUG(4,("calling open_file with flags=0x%X flags2=0x%X mode=0%o, "
1974 "access_mask = 0x%x, open_access_mask = 0x%x\n",
1975 (unsigned int)flags, (unsigned int)flags2,
1976 (unsigned int)unx_mode, (unsigned int)access_mask,
1977 (unsigned int)open_access_mask));
1980 * open_file strips any O_TRUNC flags itself.
1983 fsp_open = open_file(fsp, conn, req, parent_dir,
1984 flags|flags2, unx_mode, access_mask,
1987 if (!NT_STATUS_IS_OK(fsp_open)) {
1994 if (!file_existed) {
1995 struct timespec old_write_time = smb_fname->st.st_ex_mtime;
1997 * Deal with the race condition where two smbd's detect the
1998 * file doesn't exist and do the create at the same time. One
1999 * of them will win and set a share mode, the other (ie. this
2000 * one) should check if the requested share mode for this
2001 * create is allowed.
2005 * Now the file exists and fsp is successfully opened,
2006 * fsp->dev and fsp->inode are valid and should replace the
2007 * dev=0,inode=0 from a non existent file. Spotted by
2008 * Nadav Danieli <nadavd@exanet.com>. JRA.
2013 lck = get_share_mode_lock(talloc_tos(), id,
2015 smb_fname, &old_write_time);
2018 DEBUG(0, ("open_file_ntcreate: Could not get share "
2019 "mode lock for %s\n",
2020 smb_fname_str_dbg(smb_fname)));
2022 return NT_STATUS_SHARING_VIOLATION;
2025 /* First pass - send break only on batch oplocks. */
2027 && delay_for_oplocks(lck, fsp, req->mid, 1,
2029 schedule_defer_open(lck, request_time, req);
2032 return NT_STATUS_SHARING_VIOLATION;
2035 status = open_mode_check(conn, lck, access_mask, share_access,
2036 create_options, &file_existed);
2038 if (NT_STATUS_IS_OK(status)) {
2039 /* We might be going to allow this open. Check oplock
2041 /* Second pass - send break for both batch or
2042 * exclusive oplocks. */
2044 && delay_for_oplocks(lck, fsp, req->mid, 2,
2046 schedule_defer_open(lck, request_time, req);
2049 return NT_STATUS_SHARING_VIOLATION;
2053 if (!NT_STATUS_IS_OK(status)) {
2054 struct deferred_open_record state;
2058 state.delayed_for_oplocks = False;
2061 /* Do it all over again immediately. In the second
2062 * round we will find that the file existed and handle
2063 * the DELETE_PENDING and FCB cases correctly. No need
2064 * to duplicate the code here. Essentially this is a
2065 * "goto top of this function", but don't tell
2069 defer_open(lck, request_time, timeval_zero(),
2077 * We exit this block with the share entry *locked*.....
2082 SMB_ASSERT(lck != NULL);
2084 /* Delete streams if create_disposition requires it */
2085 if (file_existed && clear_ads &&
2086 !is_ntfs_stream_smb_fname(smb_fname)) {
2087 status = delete_all_streams(conn, smb_fname->base_name);
2088 if (!NT_STATUS_IS_OK(status)) {
2095 /* note that we ignore failure for the following. It is
2096 basically a hack for NFS, and NFS will never set one of
2097 these only read them. Nobody but Samba can ever set a deny
2098 mode and we have already checked our more authoritative
2099 locking database for permission to set this deny mode. If
2100 the kernel refuses the operations then the kernel is wrong.
2101 note that GPFS supports it as well - jmcd */
2103 if (fsp->fh->fd != -1) {
2105 ret_flock = SMB_VFS_KERNEL_FLOCK(fsp, share_access, access_mask);
2106 if(ret_flock == -1 ){
2111 return NT_STATUS_SHARING_VIOLATION;
2116 * At this point onwards, we can guarentee that the share entry
2117 * is locked, whether we created the file or not, and that the
2118 * deny mode is compatible with all current opens.
2122 * If requested, truncate the file.
2125 if (flags2&O_TRUNC) {
2127 * We are modifing the file after open - update the stat
2130 if ((SMB_VFS_FTRUNCATE(fsp, 0) == -1) ||
2131 (SMB_VFS_FSTAT(fsp, &smb_fname->st)==-1)) {
2132 status = map_nt_error_from_unix(errno);
2139 /* Record the options we were opened with. */
2140 fsp->share_access = share_access;
2141 fsp->fh->private_options = create_options;
2143 * According to Samba4, SEC_FILE_READ_ATTRIBUTE is always granted,
2145 fsp->access_mask = access_mask | FILE_READ_ATTRIBUTES;
2148 /* stat opens on existing files don't get oplocks. */
2149 if (is_stat_open(open_access_mask)) {
2150 fsp->oplock_type = NO_OPLOCK;
2153 if (!(flags2 & O_TRUNC)) {
2154 info = FILE_WAS_OPENED;
2156 info = FILE_WAS_OVERWRITTEN;
2159 info = FILE_WAS_CREATED;
2167 * Setup the oplock info in both the shared memory and
2171 if (!set_file_oplock(fsp, fsp->oplock_type)) {
2172 /* Could not get the kernel oplock */
2173 fsp->oplock_type = NO_OPLOCK;
2176 if (info == FILE_WAS_OVERWRITTEN || info == FILE_WAS_CREATED || info == FILE_WAS_SUPERSEDED) {
2177 new_file_created = True;
2180 set_share_mode(lck, fsp, conn->server_info->utok.uid, 0,
2183 /* Handle strange delete on close create semantics. */
2184 if (create_options & FILE_DELETE_ON_CLOSE) {
2186 status = can_set_delete_on_close(fsp, new_dos_attributes);
2188 if (!NT_STATUS_IS_OK(status)) {
2189 /* Remember to delete the mode we just added. */
2190 del_share_mode(lck, fsp);
2195 /* Note that here we set the *inital* delete on close flag,
2196 not the regular one. The magic gets handled in close. */
2197 fsp->initial_delete_on_close = True;
2200 if (new_file_created) {
2201 /* Files should be initially set as archive */
2202 if (lp_map_archive(SNUM(conn)) ||
2203 lp_store_dos_attributes(SNUM(conn))) {
2205 if (file_set_dosmode(conn, smb_fname,
2206 new_dos_attributes | aARCH,
2207 parent_dir, true) == 0) {
2208 unx_mode = smb_fname->st.st_ex_mode;
2215 * Take care of inherited ACLs on created files - if default ACL not
2219 if (!posix_open && !file_existed && !def_acl) {
2221 int saved_errno = errno; /* We might get ENOSYS in the next
2224 if (SMB_VFS_FCHMOD_ACL(fsp, unx_mode) == -1 &&
2226 errno = saved_errno; /* Ignore ENOSYS */
2229 } else if (new_unx_mode) {
2233 /* Attributes need changing. File already existed. */
2236 int saved_errno = errno; /* We might get ENOSYS in the
2238 ret = SMB_VFS_FCHMOD_ACL(fsp, new_unx_mode);
2240 if (ret == -1 && errno == ENOSYS) {
2241 errno = saved_errno; /* Ignore ENOSYS */
2243 DEBUG(5, ("open_file_ntcreate: reset "
2244 "attributes of file %s to 0%o\n",
2245 smb_fname_str_dbg(smb_fname),
2246 (unsigned int)new_unx_mode));
2247 ret = 0; /* Don't do the fchmod below. */
2252 (SMB_VFS_FCHMOD(fsp, new_unx_mode) == -1))
2253 DEBUG(5, ("open_file_ntcreate: failed to reset "
2254 "attributes of file %s to 0%o\n",
2255 smb_fname_str_dbg(smb_fname),
2256 (unsigned int)new_unx_mode));
2259 /* If this is a successful open, we must remove any deferred open
2262 del_deferred_open_entry(lck, req->mid);
2266 return NT_STATUS_OK;
2270 /****************************************************************************
2271 Open a file for for write to ensure that we can fchmod it.
2272 ****************************************************************************/
2274 NTSTATUS open_file_fchmod(struct smb_request *req, connection_struct *conn,
2275 struct smb_filename *smb_fname,
2276 files_struct **result)
2278 files_struct *fsp = NULL;
2281 if (!VALID_STAT(smb_fname->st)) {
2282 return NT_STATUS_INVALID_PARAMETER;
2285 status = file_new(req, conn, &fsp);
2286 if(!NT_STATUS_IS_OK(status)) {
2290 status = SMB_VFS_CREATE_FILE(
2293 0, /* root_dir_fid */
2294 smb_fname, /* fname */
2295 FILE_WRITE_DATA, /* access_mask */
2296 (FILE_SHARE_READ | FILE_SHARE_WRITE | /* share_access */
2298 FILE_OPEN, /* create_disposition*/
2299 0, /* create_options */
2300 0, /* file_attributes */
2301 0, /* oplock_request */
2302 0, /* allocation_size */
2309 * This is not a user visible file open.
2310 * Don't set a share mode.
2313 if (!NT_STATUS_IS_OK(status)) {
2314 file_free(req, fsp);
2319 return NT_STATUS_OK;
2322 /****************************************************************************
2323 Close the fchmod file fd - ensure no locks are lost.
2324 ****************************************************************************/
2326 NTSTATUS close_file_fchmod(struct smb_request *req, files_struct *fsp)
2328 NTSTATUS status = fd_close(fsp);
2329 file_free(req, fsp);
2333 static NTSTATUS mkdir_internal(connection_struct *conn,
2334 struct smb_filename *smb_dname,
2335 uint32 file_attributes)
2340 bool posix_open = false;
2342 if(!CAN_WRITE(conn)) {
2343 DEBUG(5,("mkdir_internal: failing create on read-only share "
2344 "%s\n", lp_servicename(SNUM(conn))));
2345 return NT_STATUS_ACCESS_DENIED;
2348 status = check_name(conn, smb_dname->base_name);
2349 if (!NT_STATUS_IS_OK(status)) {
2353 if (!parent_dirname(talloc_tos(), smb_dname->base_name, &parent_dir,
2355 return NT_STATUS_NO_MEMORY;
2358 if (file_attributes & FILE_FLAG_POSIX_SEMANTICS) {
2360 mode = (mode_t)(file_attributes & ~FILE_FLAG_POSIX_SEMANTICS);
2362 mode = unix_mode(conn, aDIR, smb_dname, parent_dir);
2365 if (SMB_VFS_MKDIR(conn, smb_dname->base_name, mode) != 0) {
2366 return map_nt_error_from_unix(errno);
2369 /* Ensure we're checking for a symlink here.... */
2370 /* We don't want to get caught by a symlink racer. */
2372 if (SMB_VFS_LSTAT(conn, smb_dname) == -1) {
2373 DEBUG(2, ("Could not stat directory '%s' just created: %s\n",
2374 smb_fname_str_dbg(smb_dname), strerror(errno)));
2375 return map_nt_error_from_unix(errno);
2378 if (!S_ISDIR(smb_dname->st.st_ex_mode)) {
2379 DEBUG(0, ("Directory just '%s' created is not a directory\n",
2380 smb_fname_str_dbg(smb_dname)));
2381 return NT_STATUS_ACCESS_DENIED;
2384 if (lp_store_dos_attributes(SNUM(conn))) {
2386 file_set_dosmode(conn, smb_dname,
2387 file_attributes | aDIR,
2392 if (lp_inherit_perms(SNUM(conn))) {
2393 inherit_access_posix_acl(conn, parent_dir,
2394 smb_dname->base_name, mode);
2399 * Check if high bits should have been set,
2400 * then (if bits are missing): add them.
2401 * Consider bits automagically set by UNIX, i.e. SGID bit from parent
2404 if ((mode & ~(S_IRWXU|S_IRWXG|S_IRWXO)) &&
2405 (mode & ~smb_dname->st.st_ex_mode)) {
2406 SMB_VFS_CHMOD(conn, smb_dname->base_name,
2407 (smb_dname->st.st_ex_mode |
2408 (mode & ~smb_dname->st.st_ex_mode)));
2412 /* Change the owner if required. */
2413 if (lp_inherit_owner(SNUM(conn))) {
2414 change_dir_owner_to_parent(conn, parent_dir,
2415 smb_dname->base_name,
2419 notify_fname(conn, NOTIFY_ACTION_ADDED, FILE_NOTIFY_CHANGE_DIR_NAME,
2420 smb_dname->base_name);
2422 return NT_STATUS_OK;
2425 /****************************************************************************
2426 Open a directory from an NT SMB call.
2427 ****************************************************************************/
2429 static NTSTATUS open_directory(connection_struct *conn,
2430 struct smb_request *req,
2431 struct smb_filename *smb_dname,
2433 uint32 share_access,
2434 uint32 create_disposition,
2435 uint32 create_options,
2436 uint32 file_attributes,
2438 files_struct **result)
2440 files_struct *fsp = NULL;
2441 bool dir_existed = VALID_STAT(smb_dname->st) ? True : False;
2442 struct share_mode_lock *lck = NULL;
2444 struct timespec mtimespec;
2447 SMB_ASSERT(!is_ntfs_stream_smb_fname(smb_dname));
2449 /* Ensure we have a directory attribute. */
2450 file_attributes |= FILE_ATTRIBUTE_DIRECTORY;
2452 DEBUG(5,("open_directory: opening directory %s, access_mask = 0x%x, "
2453 "share_access = 0x%x create_options = 0x%x, "
2454 "create_disposition = 0x%x, file_attributes = 0x%x\n",
2455 smb_fname_str_dbg(smb_dname),
2456 (unsigned int)access_mask,
2457 (unsigned int)share_access,
2458 (unsigned int)create_options,
2459 (unsigned int)create_disposition,
2460 (unsigned int)file_attributes));
2462 if (!(file_attributes & FILE_FLAG_POSIX_SEMANTICS) &&
2463 (conn->fs_capabilities & FILE_NAMED_STREAMS) &&
2464 is_ntfs_stream_smb_fname(smb_dname)) {
2465 DEBUG(2, ("open_directory: %s is a stream name!\n",
2466 smb_fname_str_dbg(smb_dname)));
2467 return NT_STATUS_NOT_A_DIRECTORY;
2470 status = calculate_access_mask(conn, smb_dname, dir_existed,
2471 access_mask, &access_mask);
2472 if (!NT_STATUS_IS_OK(status)) {
2473 DEBUG(10, ("open_directory: calculate_access_mask "
2474 "on file %s returned %s\n",
2475 smb_fname_str_dbg(smb_dname),
2476 nt_errstr(status)));
2480 if ((access_mask & SEC_FLAG_SYSTEM_SECURITY) &&
2481 !user_has_privileges(current_user.nt_user_token, &se_security)) {
2482 DEBUG(10, ("open_directory: open on %s "
2483 "failed - SEC_FLAG_SYSTEM_SECURITY denied.\n",
2484 smb_fname_str_dbg(smb_dname)));
2485 return NT_STATUS_PRIVILEGE_NOT_HELD;
2488 switch( create_disposition ) {
2491 info = FILE_WAS_OPENED;
2494 * We want to follow symlinks here.
2497 if (SMB_VFS_STAT(conn, smb_dname) != 0) {
2498 return map_nt_error_from_unix(errno);
2505 /* If directory exists error. If directory doesn't
2508 status = mkdir_internal(conn, smb_dname,
2511 if (!NT_STATUS_IS_OK(status)) {
2512 DEBUG(2, ("open_directory: unable to create "
2513 "%s. Error was %s\n",
2514 smb_fname_str_dbg(smb_dname),
2515 nt_errstr(status)));
2519 info = FILE_WAS_CREATED;
2524 * If directory exists open. If directory doesn't
2528 status = mkdir_internal(conn, smb_dname,
2531 if (NT_STATUS_IS_OK(status)) {
2532 info = FILE_WAS_CREATED;
2535 if (NT_STATUS_EQUAL(status,
2536 NT_STATUS_OBJECT_NAME_COLLISION)) {
2537 info = FILE_WAS_OPENED;
2538 status = NT_STATUS_OK;
2543 case FILE_SUPERSEDE:
2544 case FILE_OVERWRITE:
2545 case FILE_OVERWRITE_IF:
2547 DEBUG(5,("open_directory: invalid create_disposition "
2548 "0x%x for directory %s\n",
2549 (unsigned int)create_disposition,
2550 smb_fname_str_dbg(smb_dname)));
2551 return NT_STATUS_INVALID_PARAMETER;
2554 if(!S_ISDIR(smb_dname->st.st_ex_mode)) {
2555 DEBUG(5,("open_directory: %s is not a directory !\n",
2556 smb_fname_str_dbg(smb_dname)));
2557 return NT_STATUS_NOT_A_DIRECTORY;
2560 if (info == FILE_WAS_OPENED) {
2561 uint32_t access_granted = 0;
2562 status = smbd_check_open_rights(conn, smb_dname, access_mask,
2565 /* Were we trying to do a directory open
2566 * for delete and didn't get DELETE
2567 * access (only) ? Check if the
2568 * directory allows DELETE_CHILD.
2570 * http://blogs.msdn.com/oldnewthing/archive/2004/06/04/148426.aspx
2573 if ((NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED) &&
2574 (access_mask & DELETE_ACCESS) &&
2575 (access_granted == DELETE_ACCESS) &&
2576 can_delete_file_in_directory(conn, smb_dname))) {
2577 DEBUG(10,("open_directory: overrode ACCESS_DENIED "
2578 "on directory %s\n",
2579 smb_fname_str_dbg(smb_dname)));
2580 status = NT_STATUS_OK;
2583 if (!NT_STATUS_IS_OK(status)) {
2584 DEBUG(10, ("open_directory: smbd_check_open_rights on "
2585 "file %s failed with %s\n",
2586 smb_fname_str_dbg(smb_dname),
2587 nt_errstr(status)));
2592 status = file_new(req, conn, &fsp);
2593 if(!NT_STATUS_IS_OK(status)) {
2598 * Setup the files_struct for it.
2601 fsp->mode = smb_dname->st.st_ex_mode;
2602 fsp->file_id = vfs_file_id_from_sbuf(conn, &smb_dname->st);
2603 fsp->vuid = req ? req->vuid : UID_FIELD_INVALID;
2604 fsp->file_pid = req ? req->smbpid : 0;
2605 fsp->can_lock = False;
2606 fsp->can_read = False;
2607 fsp->can_write = False;
2609 fsp->share_access = share_access;
2610 fsp->fh->private_options = create_options;
2612 * According to Samba4, SEC_FILE_READ_ATTRIBUTE is always granted,
2614 fsp->access_mask = access_mask | FILE_READ_ATTRIBUTES;
2615 fsp->print_file = False;
2616 fsp->modified = False;
2617 fsp->oplock_type = NO_OPLOCK;
2618 fsp->sent_oplock_break = NO_BREAK_SENT;
2619 fsp->is_directory = True;
2620 fsp->posix_open = (file_attributes & FILE_FLAG_POSIX_SEMANTICS) ? True : False;
2621 status = fsp_set_smb_fname(fsp, smb_dname);
2622 if (!NT_STATUS_IS_OK(status)) {
2626 mtimespec = smb_dname->st.st_ex_mtime;
2628 lck = get_share_mode_lock(talloc_tos(), fsp->file_id,
2629 conn->connectpath, smb_dname, &mtimespec);
2632 DEBUG(0, ("open_directory: Could not get share mode lock for "
2633 "%s\n", smb_fname_str_dbg(smb_dname)));
2634 file_free(req, fsp);
2635 return NT_STATUS_SHARING_VIOLATION;
2638 status = open_mode_check(conn, lck, access_mask, share_access,
2639 create_options, &dir_existed);
2641 if (!NT_STATUS_IS_OK(status)) {
2643 file_free(req, fsp);
2647 set_share_mode(lck, fsp, conn->server_info->utok.uid, 0, NO_OPLOCK);
2649 /* For directories the delete on close bit at open time seems
2650 always to be honored on close... See test 19 in Samba4 BASE-DELETE. */
2651 if (create_options & FILE_DELETE_ON_CLOSE) {
2652 status = can_set_delete_on_close(fsp, 0);
2653 if (!NT_STATUS_IS_OK(status) && !NT_STATUS_EQUAL(status, NT_STATUS_DIRECTORY_NOT_EMPTY)) {
2655 file_free(req, fsp);
2659 if (NT_STATUS_IS_OK(status)) {
2660 /* Note that here we set the *inital* delete on close flag,
2661 not the regular one. The magic gets handled in close. */
2662 fsp->initial_delete_on_close = True;
2673 return NT_STATUS_OK;
2676 NTSTATUS create_directory(connection_struct *conn, struct smb_request *req,
2677 struct smb_filename *smb_dname)
2682 status = SMB_VFS_CREATE_FILE(
2685 0, /* root_dir_fid */
2686 smb_dname, /* fname */
2687 FILE_READ_ATTRIBUTES, /* access_mask */
2688 FILE_SHARE_NONE, /* share_access */
2689 FILE_CREATE, /* create_disposition*/
2690 FILE_DIRECTORY_FILE, /* create_options */
2691 FILE_ATTRIBUTE_DIRECTORY, /* file_attributes */
2692 0, /* oplock_request */
2693 0, /* allocation_size */
2699 if (NT_STATUS_IS_OK(status)) {
2700 close_file(req, fsp, NORMAL_CLOSE);
2706 /****************************************************************************
2707 Receive notification that one of our open files has been renamed by another
2709 ****************************************************************************/
2711 void msg_file_was_renamed(struct messaging_context *msg,
2714 struct server_id server_id,
2718 char *frm = (char *)data->data;
2720 const char *sharepath;
2721 const char *base_name;
2722 const char *stream_name;
2723 struct smb_filename *smb_fname = NULL;
2724 size_t sp_len, bn_len;
2727 if (data->data == NULL
2728 || data->length < MSG_FILE_RENAMED_MIN_SIZE + 2) {
2729 DEBUG(0, ("msg_file_was_renamed: Got invalid msg len %d\n",
2730 (int)data->length));
2734 /* Unpack the message. */
2735 pull_file_id_24(frm, &id);
2736 sharepath = &frm[24];
2737 sp_len = strlen(sharepath);
2738 base_name = sharepath + sp_len + 1;
2739 bn_len = strlen(base_name);
2740 stream_name = sharepath + sp_len + 1 + bn_len + 1;
2742 /* stream_name must always be NULL if there is no stream. */
2743 if (stream_name[0] == '\0') {
2747 status = create_synthetic_smb_fname(talloc_tos(), base_name,
2748 stream_name, NULL, &smb_fname);
2749 if (!NT_STATUS_IS_OK(status)) {
2753 DEBUG(10,("msg_file_was_renamed: Got rename message for sharepath %s, new name %s, "
2755 sharepath, smb_fname_str_dbg(smb_fname),
2756 file_id_string_tos(&id)));
2758 for(fsp = file_find_di_first(id); fsp; fsp = file_find_di_next(fsp)) {
2759 if (memcmp(fsp->conn->connectpath, sharepath, sp_len) == 0) {
2761 DEBUG(10,("msg_file_was_renamed: renaming file fnum %d from %s -> %s\n",
2762 fsp->fnum, fsp_str_dbg(fsp),
2763 smb_fname_str_dbg(smb_fname)));
2764 status = fsp_set_smb_fname(fsp, smb_fname);
2765 if (!NT_STATUS_IS_OK(status)) {
2770 /* Now we have the complete path we can work out if this is
2771 actually within this share and adjust newname accordingly. */
2772 DEBUG(10,("msg_file_was_renamed: share mismatch (sharepath %s "
2773 "not sharepath %s) "
2774 "fnum %d from %s -> %s\n",
2775 fsp->conn->connectpath,
2779 smb_fname_str_dbg(smb_fname)));
2783 TALLOC_FREE(smb_fname);
2788 * If a main file is opened for delete, all streams need to be checked for
2789 * !FILE_SHARE_DELETE. Do this by opening with DELETE_ACCESS.
2790 * If that works, delete them all by setting the delete on close and close.
2793 NTSTATUS open_streams_for_delete(connection_struct *conn,
2796 struct stream_struct *stream_info;
2797 files_struct **streams;
2799 unsigned int num_streams;
2800 TALLOC_CTX *frame = talloc_stackframe();
2803 status = SMB_VFS_STREAMINFO(conn, NULL, fname, talloc_tos(),
2804 &num_streams, &stream_info);
2806 if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_IMPLEMENTED)
2807 || NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
2808 DEBUG(10, ("no streams around\n"));
2810 return NT_STATUS_OK;
2813 if (!NT_STATUS_IS_OK(status)) {
2814 DEBUG(10, ("SMB_VFS_STREAMINFO failed: %s\n",
2815 nt_errstr(status)));
2819 DEBUG(10, ("open_streams_for_delete found %d streams\n",
2822 if (num_streams == 0) {
2824 return NT_STATUS_OK;
2827 streams = TALLOC_ARRAY(talloc_tos(), files_struct *, num_streams);
2828 if (streams == NULL) {
2829 DEBUG(0, ("talloc failed\n"));
2830 status = NT_STATUS_NO_MEMORY;
2834 for (i=0; i<num_streams; i++) {
2835 struct smb_filename *smb_fname = NULL;
2837 if (strequal(stream_info[i].name, "::$DATA")) {
2842 status = create_synthetic_smb_fname(talloc_tos(), fname,
2843 stream_info[i].name,
2845 if (!NT_STATUS_IS_OK(status)) {
2849 if (SMB_VFS_STAT(conn, smb_fname) == -1) {
2850 DEBUG(10, ("Unable to stat stream: %s\n",
2851 smb_fname_str_dbg(smb_fname)));
2854 status = SMB_VFS_CREATE_FILE(
2857 0, /* root_dir_fid */
2858 smb_fname, /* fname */
2859 DELETE_ACCESS, /* access_mask */
2860 (FILE_SHARE_READ | /* share_access */
2861 FILE_SHARE_WRITE | FILE_SHARE_DELETE),
2862 FILE_OPEN, /* create_disposition*/
2863 NTCREATEX_OPTIONS_PRIVATE_STREAM_DELETE, /* create_options */
2864 FILE_ATTRIBUTE_NORMAL, /* file_attributes */
2865 0, /* oplock_request */
2866 0, /* allocation_size */
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 struct security_descriptor *sd,
2917 struct ea_list *ea_list,
2919 files_struct **result,
2922 int info = FILE_WAS_OPENED;
2923 files_struct *base_fsp = NULL;
2924 files_struct *fsp = NULL;
2927 DEBUG(10,("create_file_unixpath: access_mask = 0x%x "
2928 "file_attributes = 0x%x, share_access = 0x%x, "
2929 "create_disposition = 0x%x create_options = 0x%x "
2930 "oplock_request = 0x%x ea_list = 0x%p, sd = 0x%p, "
2932 (unsigned int)access_mask,
2933 (unsigned int)file_attributes,
2934 (unsigned int)share_access,
2935 (unsigned int)create_disposition,
2936 (unsigned int)create_options,
2937 (unsigned int)oplock_request,
2938 ea_list, sd, smb_fname_str_dbg(smb_fname)));
2940 if (create_options & FILE_OPEN_BY_FILE_ID) {
2941 status = NT_STATUS_NOT_SUPPORTED;
2945 if (create_options & NTCREATEX_OPTIONS_INVALID_PARAM_MASK) {
2946 status = NT_STATUS_INVALID_PARAMETER;
2951 oplock_request |= INTERNAL_OPEN_ONLY;
2954 if ((conn->fs_capabilities & FILE_NAMED_STREAMS)
2955 && (access_mask & DELETE_ACCESS)
2956 && !is_ntfs_stream_smb_fname(smb_fname)) {
2958 * We can't open a file with DELETE access if any of the
2959 * streams is open without FILE_SHARE_DELETE
2961 status = open_streams_for_delete(conn, smb_fname->base_name);
2963 if (!NT_STATUS_IS_OK(status)) {
2968 /* This is the correct thing to do (check every time) but can_delete
2969 * is expensive (it may have to read the parent directory
2970 * permissions). So for now we're not doing it unless we have a strong
2971 * hint the client is really going to delete this file. If the client
2972 * is forcing FILE_CREATE let the filesystem take care of the
2975 /* Setting FILE_SHARE_DELETE is the hint. */
2977 if (lp_acl_check_permissions(SNUM(conn))
2978 && (create_disposition != FILE_CREATE)
2979 && (share_access & FILE_SHARE_DELETE)
2980 && (access_mask & DELETE_ACCESS)
2981 && (!(can_delete_file_in_directory(conn, smb_fname) ||
2982 can_access_file_acl(conn, smb_fname, DELETE_ACCESS)))) {
2983 status = NT_STATUS_ACCESS_DENIED;
2984 DEBUG(10,("create_file_unixpath: open file %s "
2985 "for delete ACCESS_DENIED\n",
2986 smb_fname_str_dbg(smb_fname)));
2990 if ((access_mask & SEC_FLAG_SYSTEM_SECURITY) &&
2991 !user_has_privileges(current_user.nt_user_token, &se_security)) {
2992 DEBUG(10, ("create_file_unixpath:: open on %s "
2993 "failed - SEC_FLAG_SYSTEM_SECURITY denied.\n",
2994 smb_fname_str_dbg(smb_fname)));
2995 status = NT_STATUS_PRIVILEGE_NOT_HELD;
2999 if ((conn->fs_capabilities & FILE_NAMED_STREAMS)
3000 && is_ntfs_stream_smb_fname(smb_fname)
3001 && (!(create_options & NTCREATEX_OPTIONS_PRIVATE_STREAM_DELETE))) {
3002 uint32 base_create_disposition;
3003 struct smb_filename *smb_fname_base = NULL;
3005 if (create_options & FILE_DIRECTORY_FILE) {
3006 status = NT_STATUS_NOT_A_DIRECTORY;
3010 switch (create_disposition) {
3012 base_create_disposition = FILE_OPEN;
3015 base_create_disposition = FILE_OPEN_IF;
3019 /* Create an smb_filename with stream_name == NULL. */
3020 status = create_synthetic_smb_fname(talloc_tos(),
3021 smb_fname->base_name,
3024 if (!NT_STATUS_IS_OK(status)) {
3028 if (SMB_VFS_STAT(conn, smb_fname_base) == -1) {
3029 DEBUG(10, ("Unable to stat stream: %s\n",
3030 smb_fname_str_dbg(smb_fname_base)));
3033 /* Open the base file. */
3034 status = create_file_unixpath(conn, NULL, smb_fname_base, 0,
3037 | FILE_SHARE_DELETE,
3038 base_create_disposition,
3039 0, 0, 0, 0, NULL, NULL,
3041 TALLOC_FREE(smb_fname_base);
3043 if (!NT_STATUS_IS_OK(status)) {
3044 DEBUG(10, ("create_file_unixpath for base %s failed: "
3045 "%s\n", smb_fname->base_name,
3046 nt_errstr(status)));
3049 /* we don't need to low level fd */
3054 * If it's a request for a directory open, deal with it separately.
3057 if (create_options & FILE_DIRECTORY_FILE) {
3059 if (create_options & FILE_NON_DIRECTORY_FILE) {
3060 status = NT_STATUS_INVALID_PARAMETER;
3064 /* Can't open a temp directory. IFS kit test. */
3065 if (!(file_attributes & FILE_FLAG_POSIX_SEMANTICS) &&
3066 (file_attributes & FILE_ATTRIBUTE_TEMPORARY)) {
3067 status = NT_STATUS_INVALID_PARAMETER;
3072 * We will get a create directory here if the Win32
3073 * app specified a security descriptor in the
3074 * CreateDirectory() call.
3078 status = open_directory(
3079 conn, req, smb_fname, access_mask, share_access,
3080 create_disposition, create_options, file_attributes,
3085 * Ordinary file case.
3088 status = file_new(req, conn, &fsp);
3089 if(!NT_STATUS_IS_OK(status)) {
3093 status = fsp_set_smb_fname(fsp, smb_fname);
3094 if (!NT_STATUS_IS_OK(status)) {
3099 * We're opening the stream element of a base_fsp
3100 * we already opened. Set up the base_fsp pointer.
3103 fsp->base_fsp = base_fsp;
3106 status = open_file_ntcreate(conn,
3117 if(!NT_STATUS_IS_OK(status)) {
3118 file_free(req, fsp);
3122 if (NT_STATUS_EQUAL(status, NT_STATUS_FILE_IS_A_DIRECTORY)) {
3124 /* A stream open never opens a directory */
3127 status = NT_STATUS_FILE_IS_A_DIRECTORY;
3132 * Fail the open if it was explicitly a non-directory
3136 if (create_options & FILE_NON_DIRECTORY_FILE) {
3137 status = NT_STATUS_FILE_IS_A_DIRECTORY;
3142 status = open_directory(
3143 conn, req, smb_fname, access_mask,
3144 share_access, create_disposition,
3145 create_options, file_attributes,
3150 if (!NT_STATUS_IS_OK(status)) {
3154 fsp->base_fsp = base_fsp;
3157 * According to the MS documentation, the only time the security
3158 * descriptor is applied to the opened file is iff we *created* the
3159 * file; an existing file stays the same.
3161 * Also, it seems (from observation) that you can open the file with
3162 * any access mask but you can still write the sd. We need to override
3163 * the granted access before we call set_sd
3164 * Patch for bug #2242 from Tom Lackemann <cessnatomny@yahoo.com>.
3167 if ((sd != NULL) && (info == FILE_WAS_CREATED)
3168 && lp_nt_acl_support(SNUM(conn))) {
3170 uint32_t sec_info_sent;
3171 uint32_t saved_access_mask = fsp->access_mask;
3173 sec_info_sent = get_sec_info(sd);
3175 fsp->access_mask = FILE_GENERIC_ALL;
3177 /* Convert all the generic bits. */
3178 security_acl_map_generic(sd->dacl, &file_generic_mapping);
3179 security_acl_map_generic(sd->sacl, &file_generic_mapping);
3181 if (sec_info_sent & (OWNER_SECURITY_INFORMATION|
3182 GROUP_SECURITY_INFORMATION|
3183 DACL_SECURITY_INFORMATION|
3184 SACL_SECURITY_INFORMATION)) {
3185 status = SMB_VFS_FSET_NT_ACL(fsp, sec_info_sent, sd);
3188 fsp->access_mask = saved_access_mask;
3190 if (!NT_STATUS_IS_OK(status)) {
3195 if ((ea_list != NULL) &&
3196 ((info == FILE_WAS_CREATED) || (info == FILE_WAS_OVERWRITTEN))) {
3197 status = set_ea(conn, fsp, fsp->fsp_name, ea_list);
3198 if (!NT_STATUS_IS_OK(status)) {
3203 if (!fsp->is_directory && S_ISDIR(fsp->fsp_name->st.st_ex_mode)) {
3204 status = NT_STATUS_ACCESS_DENIED;
3208 /* Save the requested allocation size. */
3209 if ((info == FILE_WAS_CREATED) || (info == FILE_WAS_OVERWRITTEN)) {
3211 && (allocation_size > fsp->fsp_name->st.st_ex_size)) {
3212 fsp->initial_allocation_size = smb_roundup(
3213 fsp->conn, allocation_size);
3214 if (fsp->is_directory) {
3215 /* Can't set allocation size on a directory. */
3216 status = NT_STATUS_ACCESS_DENIED;
3219 if (vfs_allocate_file_space(
3220 fsp, fsp->initial_allocation_size) == -1) {
3221 status = NT_STATUS_DISK_FULL;
3225 fsp->initial_allocation_size = smb_roundup(
3226 fsp->conn, (uint64_t)fsp->fsp_name->st.st_ex_size);
3230 DEBUG(10, ("create_file_unixpath: info=%d\n", info));
3233 if (pinfo != NULL) {
3237 smb_fname->st = fsp->fsp_name->st;
3239 return NT_STATUS_OK;
3242 DEBUG(10, ("create_file_unixpath: %s\n", nt_errstr(status)));
3245 if (base_fsp && fsp->base_fsp == base_fsp) {
3247 * The close_file below will close
3252 close_file(req, fsp, ERROR_CLOSE);
3255 if (base_fsp != NULL) {
3256 close_file(req, base_fsp, ERROR_CLOSE);
3263 * Calculate the full path name given a relative fid.
3265 NTSTATUS get_relative_fid_filename(connection_struct *conn,
3266 struct smb_request *req,
3267 uint16_t root_dir_fid,
3268 struct smb_filename *smb_fname)
3270 files_struct *dir_fsp;
3271 char *parent_fname = NULL;
3272 char *new_base_name = NULL;
3275 if (root_dir_fid == 0 || !smb_fname) {
3276 status = NT_STATUS_INTERNAL_ERROR;
3280 dir_fsp = file_fsp(req, root_dir_fid);
3282 if (dir_fsp == NULL) {
3283 status = NT_STATUS_INVALID_HANDLE;
3287 if (is_ntfs_stream_smb_fname(dir_fsp->fsp_name)) {
3288 status = NT_STATUS_INVALID_HANDLE;
3292 if (!dir_fsp->is_directory) {
3295 * Check to see if this is a mac fork of some kind.
3298 if ((conn->fs_capabilities & FILE_NAMED_STREAMS) &&
3299 is_ntfs_stream_smb_fname(smb_fname)) {
3300 status = NT_STATUS_OBJECT_PATH_NOT_FOUND;
3305 we need to handle the case when we get a
3306 relative open relative to a file and the
3307 pathname is blank - this is a reopen!
3308 (hint from demyn plantenberg)
3311 status = NT_STATUS_INVALID_HANDLE;
3315 if (ISDOT(dir_fsp->fsp_name->base_name)) {
3317 * We're at the toplevel dir, the final file name
3318 * must not contain ./, as this is filtered out
3319 * normally by srvstr_get_path and unix_convert
3320 * explicitly rejects paths containing ./.
3322 parent_fname = talloc_strdup(talloc_tos(), "");
3323 if (parent_fname == NULL) {
3324 status = NT_STATUS_NO_MEMORY;
3328 size_t dir_name_len = strlen(dir_fsp->fsp_name->base_name);
3331 * Copy in the base directory name.
3334 parent_fname = TALLOC_ARRAY(talloc_tos(), char,
3336 if (parent_fname == NULL) {
3337 status = NT_STATUS_NO_MEMORY;
3340 memcpy(parent_fname, dir_fsp->fsp_name->base_name,
3344 * Ensure it ends in a '/'.
3345 * We used TALLOC_SIZE +2 to add space for the '/'.
3349 && (parent_fname[dir_name_len-1] != '\\')
3350 && (parent_fname[dir_name_len-1] != '/')) {
3351 parent_fname[dir_name_len] = '/';
3352 parent_fname[dir_name_len+1] = '\0';
3356 new_base_name = talloc_asprintf(smb_fname, "%s%s", parent_fname,
3357 smb_fname->base_name);
3358 if (new_base_name == NULL) {
3359 status = NT_STATUS_NO_MEMORY;
3363 TALLOC_FREE(smb_fname->base_name);
3364 smb_fname->base_name = new_base_name;
3365 status = NT_STATUS_OK;
3368 TALLOC_FREE(parent_fname);
3372 NTSTATUS create_file_default(connection_struct *conn,
3373 struct smb_request *req,
3374 uint16_t root_dir_fid,
3375 struct smb_filename *smb_fname,
3376 uint32_t access_mask,
3377 uint32_t share_access,
3378 uint32_t create_disposition,
3379 uint32_t create_options,
3380 uint32_t file_attributes,
3381 uint32_t oplock_request,
3382 uint64_t allocation_size,
3383 struct security_descriptor *sd,
3384 struct ea_list *ea_list,
3385 files_struct **result,
3388 int info = FILE_WAS_OPENED;
3389 files_struct *fsp = NULL;
3392 DEBUG(10,("create_file: access_mask = 0x%x "
3393 "file_attributes = 0x%x, share_access = 0x%x, "
3394 "create_disposition = 0x%x create_options = 0x%x "
3395 "oplock_request = 0x%x "
3396 "root_dir_fid = 0x%x, ea_list = 0x%p, sd = 0x%p, "
3398 (unsigned int)access_mask,
3399 (unsigned int)file_attributes,
3400 (unsigned int)share_access,
3401 (unsigned int)create_disposition,
3402 (unsigned int)create_options,
3403 (unsigned int)oplock_request,
3404 (unsigned int)root_dir_fid,
3405 ea_list, sd, smb_fname_str_dbg(smb_fname)));
3408 * Calculate the filename from the root_dir_if if necessary.
3411 if (root_dir_fid != 0) {
3412 status = get_relative_fid_filename(conn, req, root_dir_fid,
3414 if (!NT_STATUS_IS_OK(status)) {
3420 * Check to see if this is a mac fork of some kind.
3423 if (is_ntfs_stream_smb_fname(smb_fname)) {
3424 enum FAKE_FILE_TYPE fake_file_type;
3426 fake_file_type = is_fake_file(smb_fname);
3428 if (fake_file_type != FAKE_FILE_TYPE_NONE) {
3431 * Here we go! support for changing the disk quotas
3434 * We need to fake up to open this MAGIC QUOTA file
3435 * and return a valid FID.
3437 * w2k close this file directly after openening xp
3438 * also tries a QUERY_FILE_INFO on the file and then
3441 status = open_fake_file(req, conn, req->vuid,
3442 fake_file_type, smb_fname,
3444 if (!NT_STATUS_IS_OK(status)) {
3448 ZERO_STRUCT(smb_fname->st);
3452 if (!(conn->fs_capabilities & FILE_NAMED_STREAMS)) {
3453 status = NT_STATUS_OBJECT_NAME_NOT_FOUND;
3458 /* All file access must go through check_name() */
3460 status = check_name(conn, smb_fname->base_name);
3461 if (!NT_STATUS_IS_OK(status)) {
3465 status = create_file_unixpath(
3466 conn, req, smb_fname, access_mask, share_access,
3467 create_disposition, create_options, file_attributes,
3468 oplock_request, allocation_size, sd, ea_list,
3471 if (!NT_STATUS_IS_OK(status)) {
3476 DEBUG(10, ("create_file: info=%d\n", info));
3479 if (pinfo != NULL) {
3482 return NT_STATUS_OK;
3485 DEBUG(10, ("create_file: %s\n", nt_errstr(status)));
3488 close_file(req, fsp, ERROR_CLOSE);