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 ));
341 /* Ensure the uid entry is updated. */
342 psbuf->st_ex_uid = smb_fname_parent->st.st_ex_uid;
345 vfs_ChDir(conn,saved_dir);
347 TALLOC_FREE(smb_fname_parent);
348 TALLOC_FREE(smb_fname_cwd);
352 /****************************************************************************
354 ****************************************************************************/
356 static NTSTATUS open_file(files_struct *fsp,
357 connection_struct *conn,
358 struct smb_request *req,
359 const char *parent_dir,
362 uint32 access_mask, /* client requested access mask. */
363 uint32 open_access_mask) /* what we're actually using in the open. */
365 struct smb_filename *smb_fname = fsp->fsp_name;
366 NTSTATUS status = NT_STATUS_OK;
367 int accmode = (flags & O_ACCMODE);
368 int local_flags = flags;
369 bool file_existed = VALID_STAT(fsp->fsp_name->st);
374 /* Check permissions */
377 * This code was changed after seeing a client open request
378 * containing the open mode of (DENY_WRITE/read-only) with
379 * the 'create if not exist' bit set. The previous code
380 * would fail to open the file read only on a read-only share
381 * as it was checking the flags parameter directly against O_RDONLY,
382 * this was failing as the flags parameter was set to O_RDONLY|O_CREAT.
386 if (!CAN_WRITE(conn)) {
387 /* It's a read-only share - fail if we wanted to write. */
388 if(accmode != O_RDONLY || (flags & O_TRUNC) || (flags & O_APPEND)) {
389 DEBUG(3,("Permission denied opening %s\n",
390 smb_fname_str_dbg(smb_fname)));
391 return NT_STATUS_ACCESS_DENIED;
392 } else if(flags & O_CREAT) {
393 /* We don't want to write - but we must make sure that
394 O_CREAT doesn't create the file if we have write
395 access into the directory.
397 flags &= ~(O_CREAT|O_EXCL);
398 local_flags &= ~(O_CREAT|O_EXCL);
403 * This little piece of insanity is inspired by the
404 * fact that an NT client can open a file for O_RDONLY,
405 * but set the create disposition to FILE_EXISTS_TRUNCATE.
406 * If the client *can* write to the file, then it expects to
407 * truncate the file, even though it is opening for readonly.
408 * Quicken uses this stupid trick in backup file creation...
409 * Thanks *greatly* to "David W. Chapman Jr." <dwcjr@inethouston.net>
410 * for helping track this one down. It didn't bite us in 2.0.x
411 * as we always opened files read-write in that release. JRA.
414 if ((accmode == O_RDONLY) && ((flags & O_TRUNC) == O_TRUNC)) {
415 DEBUG(10,("open_file: truncate requested on read-only open "
416 "for file %s\n", smb_fname_str_dbg(smb_fname)));
417 local_flags = (flags & ~O_ACCMODE)|O_RDWR;
420 if ((open_access_mask & (FILE_READ_DATA|FILE_WRITE_DATA|FILE_APPEND_DATA|FILE_EXECUTE)) ||
421 (!file_existed && (local_flags & O_CREAT)) ||
422 ((local_flags & O_TRUNC) == O_TRUNC) ) {
426 * We can't actually truncate here as the file may be locked.
427 * open_file_ntcreate will take care of the truncate later. JRA.
430 local_flags &= ~O_TRUNC;
432 #if defined(O_NONBLOCK) && defined(S_ISFIFO)
434 * We would block on opening a FIFO with no one else on the
435 * other end. Do what we used to do and add O_NONBLOCK to the
439 if (file_existed && S_ISFIFO(smb_fname->st.st_ex_mode)) {
440 local_flags |= O_NONBLOCK;
444 /* Don't create files with Microsoft wildcard characters. */
447 * wildcard characters are allowed in stream names
448 * only test the basefilename
450 wild = fsp->base_fsp->fsp_name->base_name;
452 wild = smb_fname->base_name;
454 if ((local_flags & O_CREAT) && !file_existed &&
456 return NT_STATUS_OBJECT_NAME_INVALID;
459 /* Actually do the open */
460 status = fd_open(conn, fsp, local_flags, unx_mode);
461 if (!NT_STATUS_IS_OK(status)) {
462 DEBUG(3,("Error opening file %s (%s) (local_flags=%d) "
463 "(flags=%d)\n", smb_fname_str_dbg(smb_fname),
464 nt_errstr(status),local_flags,flags));
468 if ((local_flags & O_CREAT) && !file_existed) {
470 /* Inherit the ACL if required */
471 if (lp_inherit_perms(SNUM(conn))) {
472 inherit_access_posix_acl(conn, parent_dir,
473 smb_fname->base_name,
477 /* Change the owner if required. */
478 if (lp_inherit_owner(SNUM(conn))) {
479 change_file_owner_to_parent(conn, parent_dir,
483 notify_fname(conn, NOTIFY_ACTION_ADDED,
484 FILE_NOTIFY_CHANGE_FILE_NAME,
485 smb_fname->base_name);
489 fsp->fh->fd = -1; /* What we used to call a stat open. */
491 uint32_t access_granted = 0;
493 status = smbd_check_open_rights(conn,
497 if (!NT_STATUS_IS_OK(status)) {
498 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
500 * On NT_STATUS_ACCESS_DENIED, access_granted
501 * contains the denied bits.
504 if ((access_mask & FILE_WRITE_ATTRIBUTES) &&
505 (access_granted & FILE_WRITE_ATTRIBUTES) &&
506 (lp_map_readonly(SNUM(conn)) ||
507 lp_map_archive(SNUM(conn)) ||
508 lp_map_hidden(SNUM(conn)) ||
509 lp_map_system(SNUM(conn)))) {
510 access_granted &= ~FILE_WRITE_ATTRIBUTES;
512 DEBUG(10,("open_file: "
521 if ((access_mask & DELETE_ACCESS) &&
522 (access_granted & DELETE_ACCESS) &&
523 can_delete_file_in_directory(conn,
525 /* Were we trying to do a stat open
526 * for delete and didn't get DELETE
527 * access (only) ? Check if the
528 * directory allows DELETE_CHILD.
530 * http://blogs.msdn.com/oldnewthing/archive/2004/06/04/148426.aspx
533 access_granted &= ~DELETE_ACCESS;
535 DEBUG(10,("open_file: "
543 if (access_granted != 0) {
544 DEBUG(10,("open_file: Access "
551 } else if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND) &&
553 S_ISLNK(smb_fname->st.st_ex_mode)) {
554 /* This is a POSIX stat open for delete
555 * or rename on a symlink that points
557 DEBUG(10,("open_file: allowing POSIX "
558 "open on bad symlink %s\n",
562 DEBUG(10,("open_file: "
563 "smbd_check_open_rights on file "
565 smb_fname_str_dbg(smb_fname),
566 nt_errstr(status) ));
576 if (fsp->fh->fd == -1) {
577 ret = SMB_VFS_STAT(conn, smb_fname);
579 ret = SMB_VFS_FSTAT(fsp, &smb_fname->st);
580 /* If we have an fd, this stat should succeed. */
582 DEBUG(0,("Error doing fstat on open file %s "
584 smb_fname_str_dbg(smb_fname),
589 /* For a non-io open, this stat failing means file not found. JRA */
591 status = map_nt_error_from_unix(errno);
598 * POSIX allows read-only opens of directories. We don't
599 * want to do this (we use a different code path for this)
600 * so catch a directory open and return an EISDIR. JRA.
603 if(S_ISDIR(smb_fname->st.st_ex_mode)) {
606 return NT_STATUS_FILE_IS_A_DIRECTORY;
609 fsp->mode = smb_fname->st.st_ex_mode;
610 fsp->file_id = vfs_file_id_from_sbuf(conn, &smb_fname->st);
611 fsp->vuid = req ? req->vuid : UID_FIELD_INVALID;
612 fsp->file_pid = req ? req->smbpid : 0;
613 fsp->can_lock = True;
614 fsp->can_read = (access_mask & (FILE_READ_DATA)) ? True : False;
615 if (!CAN_WRITE(conn)) {
616 fsp->can_write = False;
618 fsp->can_write = (access_mask & (FILE_WRITE_DATA | FILE_APPEND_DATA)) ?
621 fsp->print_file = False;
622 fsp->modified = False;
623 fsp->sent_oplock_break = NO_BREAK_SENT;
624 fsp->is_directory = False;
625 if (conn->aio_write_behind_list &&
626 is_in_path(smb_fname->base_name, conn->aio_write_behind_list,
627 conn->case_sensitive)) {
628 fsp->aio_write_behind = True;
631 fsp->wcp = NULL; /* Write cache pointer. */
633 DEBUG(2,("%s opened file %s read=%s write=%s (numopen=%d)\n",
634 conn->server_info->unix_name,
635 smb_fname_str_dbg(smb_fname),
636 BOOLSTR(fsp->can_read), BOOLSTR(fsp->can_write),
637 conn->num_files_open));
643 /*******************************************************************
644 Return True if the filename is one of the special executable types.
645 ********************************************************************/
647 bool is_executable(const char *fname)
649 if ((fname = strrchr_m(fname,'.'))) {
650 if (strequal(fname,".com") ||
651 strequal(fname,".dll") ||
652 strequal(fname,".exe") ||
653 strequal(fname,".sym")) {
660 /****************************************************************************
661 Check if we can open a file with a share mode.
662 Returns True if conflict, False if not.
663 ****************************************************************************/
665 static bool share_conflict(struct share_mode_entry *entry,
669 DEBUG(10,("share_conflict: entry->access_mask = 0x%x, "
670 "entry->share_access = 0x%x, "
671 "entry->private_options = 0x%x\n",
672 (unsigned int)entry->access_mask,
673 (unsigned int)entry->share_access,
674 (unsigned int)entry->private_options));
676 DEBUG(10,("share_conflict: access_mask = 0x%x, share_access = 0x%x\n",
677 (unsigned int)access_mask, (unsigned int)share_access));
679 if ((entry->access_mask & (FILE_WRITE_DATA|
683 DELETE_ACCESS)) == 0) {
684 DEBUG(10,("share_conflict: No conflict due to "
685 "entry->access_mask = 0x%x\n",
686 (unsigned int)entry->access_mask ));
690 if ((access_mask & (FILE_WRITE_DATA|
694 DELETE_ACCESS)) == 0) {
695 DEBUG(10,("share_conflict: No conflict due to "
696 "access_mask = 0x%x\n",
697 (unsigned int)access_mask ));
701 #if 1 /* JRA TEST - Superdebug. */
702 #define CHECK_MASK(num, am, right, sa, share) \
703 DEBUG(10,("share_conflict: [%d] am (0x%x) & right (0x%x) = 0x%x\n", \
704 (unsigned int)(num), (unsigned int)(am), \
705 (unsigned int)(right), (unsigned int)(am)&(right) )); \
706 DEBUG(10,("share_conflict: [%d] sa (0x%x) & share (0x%x) = 0x%x\n", \
707 (unsigned int)(num), (unsigned int)(sa), \
708 (unsigned int)(share), (unsigned int)(sa)&(share) )); \
709 if (((am) & (right)) && !((sa) & (share))) { \
710 DEBUG(10,("share_conflict: check %d conflict am = 0x%x, right = 0x%x, \
711 sa = 0x%x, share = 0x%x\n", (num), (unsigned int)(am), (unsigned int)(right), (unsigned int)(sa), \
712 (unsigned int)(share) )); \
716 #define CHECK_MASK(num, am, right, sa, share) \
717 if (((am) & (right)) && !((sa) & (share))) { \
718 DEBUG(10,("share_conflict: check %d conflict am = 0x%x, right = 0x%x, \
719 sa = 0x%x, share = 0x%x\n", (num), (unsigned int)(am), (unsigned int)(right), (unsigned int)(sa), \
720 (unsigned int)(share) )); \
725 CHECK_MASK(1, entry->access_mask, FILE_WRITE_DATA | FILE_APPEND_DATA,
726 share_access, FILE_SHARE_WRITE);
727 CHECK_MASK(2, access_mask, FILE_WRITE_DATA | FILE_APPEND_DATA,
728 entry->share_access, FILE_SHARE_WRITE);
730 CHECK_MASK(3, entry->access_mask, FILE_READ_DATA | FILE_EXECUTE,
731 share_access, FILE_SHARE_READ);
732 CHECK_MASK(4, access_mask, FILE_READ_DATA | FILE_EXECUTE,
733 entry->share_access, FILE_SHARE_READ);
735 CHECK_MASK(5, entry->access_mask, DELETE_ACCESS,
736 share_access, FILE_SHARE_DELETE);
737 CHECK_MASK(6, access_mask, DELETE_ACCESS,
738 entry->share_access, FILE_SHARE_DELETE);
740 DEBUG(10,("share_conflict: No conflict.\n"));
744 #if defined(DEVELOPER)
745 static void validate_my_share_entries(int num,
746 struct share_mode_entry *share_entry)
750 if (!procid_is_me(&share_entry->pid)) {
754 if (is_deferred_open_entry(share_entry) &&
755 !open_was_deferred(share_entry->op_mid)) {
756 char *str = talloc_asprintf(talloc_tos(),
757 "Got a deferred entry without a request: "
759 share_mode_str(talloc_tos(), num, share_entry));
763 if (!is_valid_share_mode_entry(share_entry)) {
767 fsp = file_find_dif(share_entry->id,
768 share_entry->share_file_id);
770 DEBUG(0,("validate_my_share_entries: PANIC : %s\n",
771 share_mode_str(talloc_tos(), num, share_entry) ));
772 smb_panic("validate_my_share_entries: Cannot match a "
773 "share entry with an open file\n");
776 if (is_deferred_open_entry(share_entry) ||
777 is_unused_share_mode_entry(share_entry)) {
781 if ((share_entry->op_type == NO_OPLOCK) &&
782 (fsp->oplock_type == FAKE_LEVEL_II_OPLOCK)) {
783 /* Someone has already written to it, but I haven't yet
788 if (((uint16)fsp->oplock_type) != share_entry->op_type) {
797 DEBUG(0,("validate_my_share_entries: PANIC : %s\n",
798 share_mode_str(talloc_tos(), num, share_entry) ));
799 str = talloc_asprintf(talloc_tos(),
800 "validate_my_share_entries: "
801 "file %s, oplock_type = 0x%x, op_type = 0x%x\n",
802 fsp->fsp_name->base_name,
803 (unsigned int)fsp->oplock_type,
804 (unsigned int)share_entry->op_type );
810 bool is_stat_open(uint32 access_mask)
812 return (access_mask &&
813 ((access_mask & ~(SYNCHRONIZE_ACCESS| FILE_READ_ATTRIBUTES|
814 FILE_WRITE_ATTRIBUTES))==0) &&
815 ((access_mask & (SYNCHRONIZE_ACCESS|FILE_READ_ATTRIBUTES|
816 FILE_WRITE_ATTRIBUTES)) != 0));
819 /****************************************************************************
820 Deal with share modes
821 Invarient: Share mode must be locked on entry and exit.
822 Returns -1 on error, or number of share modes on success (may be zero).
823 ****************************************************************************/
825 static NTSTATUS open_mode_check(connection_struct *conn,
826 struct share_mode_lock *lck,
829 uint32 create_options,
834 if(lck->num_share_modes == 0) {
838 *file_existed = True;
840 /* A delete on close prohibits everything */
842 if (lck->delete_on_close) {
843 return NT_STATUS_DELETE_PENDING;
846 if (is_stat_open(access_mask)) {
847 /* Stat open that doesn't trigger oplock breaks or share mode
848 * checks... ! JRA. */
853 * Check if the share modes will give us access.
856 #if defined(DEVELOPER)
857 for(i = 0; i < lck->num_share_modes; i++) {
858 validate_my_share_entries(i, &lck->share_modes[i]);
862 if (!lp_share_modes(SNUM(conn))) {
866 /* Now we check the share modes, after any oplock breaks. */
867 for(i = 0; i < lck->num_share_modes; i++) {
869 if (!is_valid_share_mode_entry(&lck->share_modes[i])) {
873 /* someone else has a share lock on it, check to see if we can
875 if (share_conflict(&lck->share_modes[i],
876 access_mask, share_access)) {
877 return NT_STATUS_SHARING_VIOLATION;
884 static bool is_delete_request(files_struct *fsp) {
885 return ((fsp->access_mask == DELETE_ACCESS) &&
886 (fsp->oplock_type == NO_OPLOCK));
890 * Send a break message to the oplock holder and delay the open for
894 static NTSTATUS send_break_message(files_struct *fsp,
895 struct share_mode_entry *exclusive,
900 char msg[MSG_SMB_SHARE_MODE_ENTRY_SIZE];
902 DEBUG(10, ("Sending break request to PID %s\n",
903 procid_str_static(&exclusive->pid)));
904 exclusive->op_mid = mid;
906 /* Create the message. */
907 share_mode_entry_to_message(msg, exclusive);
909 /* Add in the FORCE_OPLOCK_BREAK_TO_NONE bit in the message if set. We
910 don't want this set in the share mode struct pointed to by lck. */
912 if (oplock_request & FORCE_OPLOCK_BREAK_TO_NONE) {
913 SSVAL(msg,6,exclusive->op_type | FORCE_OPLOCK_BREAK_TO_NONE);
916 status = messaging_send_buf(smbd_messaging_context(), exclusive->pid,
917 MSG_SMB_BREAK_REQUEST,
919 MSG_SMB_SHARE_MODE_ENTRY_SIZE);
920 if (!NT_STATUS_IS_OK(status)) {
921 DEBUG(3, ("Could not send oplock break message: %s\n",
929 * 1) No files open at all or internal open: Grant whatever the client wants.
931 * 2) Exclusive (or batch) oplock around: If the requested access is a delete
932 * request, break if the oplock around is a batch oplock. If it's another
933 * requested access type, break.
935 * 3) Only level2 around: Grant level2 and do nothing else.
938 static bool delay_for_oplocks(struct share_mode_lock *lck,
945 struct share_mode_entry *exclusive = NULL;
946 bool valid_entry = false;
947 bool have_level2 = false;
948 bool have_a_none_oplock = false;
949 bool allow_level2 = (global_client_caps & CAP_LEVEL_II_OPLOCKS) &&
950 lp_level2_oplocks(SNUM(fsp->conn));
952 if (oplock_request & INTERNAL_OPEN_ONLY) {
953 fsp->oplock_type = NO_OPLOCK;
956 if ((oplock_request & INTERNAL_OPEN_ONLY) || is_stat_open(fsp->access_mask)) {
960 for (i=0; i<lck->num_share_modes; i++) {
962 if (!is_valid_share_mode_entry(&lck->share_modes[i])) {
966 /* At least one entry is not an invalid or deferred entry. */
969 if (pass_number == 1) {
970 if (BATCH_OPLOCK_TYPE(lck->share_modes[i].op_type)) {
971 SMB_ASSERT(exclusive == NULL);
972 exclusive = &lck->share_modes[i];
975 if (EXCLUSIVE_OPLOCK_TYPE(lck->share_modes[i].op_type)) {
976 SMB_ASSERT(exclusive == NULL);
977 exclusive = &lck->share_modes[i];
981 if (LEVEL_II_OPLOCK_TYPE(lck->share_modes[i].op_type)) {
982 SMB_ASSERT(exclusive == NULL);
986 if (lck->share_modes[i].op_type == NO_OPLOCK) {
987 have_a_none_oplock = true;
991 if (exclusive != NULL) { /* Found an exclusive oplock */
992 bool delay_it = is_delete_request(fsp) ?
993 BATCH_OPLOCK_TYPE(exclusive->op_type) : true;
994 SMB_ASSERT(!have_level2);
996 send_break_message(fsp, exclusive, mid, oplock_request);
1002 * Match what was requested (fsp->oplock_type) with
1003 * what was found in the existing share modes.
1007 /* All entries are placeholders or deferred.
1008 * Directly grant whatever the client wants. */
1009 if (fsp->oplock_type == NO_OPLOCK) {
1010 /* Store a level2 oplock, but don't tell the client */
1011 fsp->oplock_type = FAKE_LEVEL_II_OPLOCK;
1013 } else if (have_a_none_oplock) {
1014 fsp->oplock_type = NO_OPLOCK;
1015 } else if (have_level2) {
1016 if (fsp->oplock_type == NO_OPLOCK ||
1017 fsp->oplock_type == FAKE_LEVEL_II_OPLOCK) {
1018 /* Store a level2 oplock, but don't tell the client */
1019 fsp->oplock_type = FAKE_LEVEL_II_OPLOCK;
1021 fsp->oplock_type = LEVEL_II_OPLOCK;
1024 /* This case can never happen. */
1029 * Don't grant level2 to clients that don't want them
1030 * or if we've turned them off.
1032 if (fsp->oplock_type == LEVEL_II_OPLOCK && !allow_level2) {
1033 fsp->oplock_type = FAKE_LEVEL_II_OPLOCK;
1036 DEBUG(10,("delay_for_oplocks: oplock type 0x%x on file %s\n",
1037 fsp->oplock_type, fsp_str_dbg(fsp)));
1043 bool request_timed_out(struct timeval request_time,
1044 struct timeval timeout)
1046 struct timeval now, end_time;
1048 end_time = timeval_sum(&request_time, &timeout);
1049 return (timeval_compare(&end_time, &now) < 0);
1052 /****************************************************************************
1053 Handle the 1 second delay in returning a SHARING_VIOLATION error.
1054 ****************************************************************************/
1056 static void defer_open(struct share_mode_lock *lck,
1057 struct timeval request_time,
1058 struct timeval timeout,
1059 struct smb_request *req,
1060 struct deferred_open_record *state)
1064 /* Paranoia check */
1066 for (i=0; i<lck->num_share_modes; i++) {
1067 struct share_mode_entry *e = &lck->share_modes[i];
1069 if (!is_deferred_open_entry(e)) {
1073 if (procid_is_me(&e->pid) && (e->op_mid == req->mid)) {
1074 DEBUG(0, ("Trying to defer an already deferred "
1075 "request: mid=%d, exiting\n", req->mid));
1076 exit_server("attempt to defer a deferred request");
1080 /* End paranoia check */
1082 DEBUG(10,("defer_open_sharing_error: time [%u.%06u] adding deferred "
1083 "open entry for mid %u\n",
1084 (unsigned int)request_time.tv_sec,
1085 (unsigned int)request_time.tv_usec,
1086 (unsigned int)req->mid));
1088 if (!push_deferred_smb_message(req, request_time, timeout,
1089 (char *)state, sizeof(*state))) {
1090 exit_server("push_deferred_smb_message failed");
1092 add_deferred_open(lck, req->mid, request_time, state->id);
1096 /****************************************************************************
1097 On overwrite open ensure that the attributes match.
1098 ****************************************************************************/
1100 bool open_match_attributes(connection_struct *conn,
1101 uint32 old_dos_attr,
1102 uint32 new_dos_attr,
1103 mode_t existing_unx_mode,
1104 mode_t new_unx_mode,
1105 mode_t *returned_unx_mode)
1107 uint32 noarch_old_dos_attr, noarch_new_dos_attr;
1109 noarch_old_dos_attr = (old_dos_attr & ~FILE_ATTRIBUTE_ARCHIVE);
1110 noarch_new_dos_attr = (new_dos_attr & ~FILE_ATTRIBUTE_ARCHIVE);
1112 if((noarch_old_dos_attr == 0 && noarch_new_dos_attr != 0) ||
1113 (noarch_old_dos_attr != 0 && ((noarch_old_dos_attr & noarch_new_dos_attr) == noarch_old_dos_attr))) {
1114 *returned_unx_mode = new_unx_mode;
1116 *returned_unx_mode = (mode_t)0;
1119 DEBUG(10,("open_match_attributes: old_dos_attr = 0x%x, "
1120 "existing_unx_mode = 0%o, new_dos_attr = 0x%x "
1121 "returned_unx_mode = 0%o\n",
1122 (unsigned int)old_dos_attr,
1123 (unsigned int)existing_unx_mode,
1124 (unsigned int)new_dos_attr,
1125 (unsigned int)*returned_unx_mode ));
1127 /* If we're mapping SYSTEM and HIDDEN ensure they match. */
1128 if (lp_map_system(SNUM(conn)) || lp_store_dos_attributes(SNUM(conn))) {
1129 if ((old_dos_attr & FILE_ATTRIBUTE_SYSTEM) &&
1130 !(new_dos_attr & FILE_ATTRIBUTE_SYSTEM)) {
1134 if (lp_map_hidden(SNUM(conn)) || lp_store_dos_attributes(SNUM(conn))) {
1135 if ((old_dos_attr & FILE_ATTRIBUTE_HIDDEN) &&
1136 !(new_dos_attr & FILE_ATTRIBUTE_HIDDEN)) {
1143 /****************************************************************************
1144 Special FCB or DOS processing in the case of a sharing violation.
1145 Try and find a duplicated file handle.
1146 ****************************************************************************/
1148 NTSTATUS fcb_or_dos_open(struct smb_request *req,
1149 connection_struct *conn,
1150 files_struct *fsp_to_dup_into,
1151 const struct smb_filename *smb_fname,
1156 uint32 share_access,
1157 uint32 create_options)
1161 DEBUG(5,("fcb_or_dos_open: attempting old open semantics for "
1162 "file %s.\n", smb_fname_str_dbg(smb_fname)));
1164 for(fsp = file_find_di_first(id); fsp;
1165 fsp = file_find_di_next(fsp)) {
1167 DEBUG(10,("fcb_or_dos_open: checking file %s, fd = %d, "
1168 "vuid = %u, file_pid = %u, private_options = 0x%x "
1169 "access_mask = 0x%x\n", fsp_str_dbg(fsp),
1170 fsp->fh->fd, (unsigned int)fsp->vuid,
1171 (unsigned int)fsp->file_pid,
1172 (unsigned int)fsp->fh->private_options,
1173 (unsigned int)fsp->access_mask ));
1175 if (fsp->fh->fd != -1 &&
1176 fsp->vuid == vuid &&
1177 fsp->file_pid == file_pid &&
1178 (fsp->fh->private_options & (NTCREATEX_OPTIONS_PRIVATE_DENY_DOS |
1179 NTCREATEX_OPTIONS_PRIVATE_DENY_FCB)) &&
1180 (fsp->access_mask & FILE_WRITE_DATA) &&
1181 strequal(fsp->fsp_name->base_name, smb_fname->base_name) &&
1182 strequal(fsp->fsp_name->stream_name,
1183 smb_fname->stream_name)) {
1184 DEBUG(10,("fcb_or_dos_open: file match\n"));
1190 return NT_STATUS_NOT_FOUND;
1193 /* quite an insane set of semantics ... */
1194 if (is_executable(smb_fname->base_name) &&
1195 (fsp->fh->private_options & NTCREATEX_OPTIONS_PRIVATE_DENY_DOS)) {
1196 DEBUG(10,("fcb_or_dos_open: file fail due to is_executable.\n"));
1197 return NT_STATUS_INVALID_PARAMETER;
1200 /* We need to duplicate this fsp. */
1201 return dup_file_fsp(req, fsp, access_mask, share_access,
1202 create_options, fsp_to_dup_into);
1205 /****************************************************************************
1206 Open a file with a share mode - old openX method - map into NTCreate.
1207 ****************************************************************************/
1209 bool map_open_params_to_ntcreate(const struct smb_filename *smb_fname,
1210 int deny_mode, int open_func,
1211 uint32 *paccess_mask,
1212 uint32 *pshare_mode,
1213 uint32 *pcreate_disposition,
1214 uint32 *pcreate_options)
1218 uint32 create_disposition;
1219 uint32 create_options = FILE_NON_DIRECTORY_FILE;
1221 DEBUG(10,("map_open_params_to_ntcreate: fname = %s, deny_mode = 0x%x, "
1222 "open_func = 0x%x\n",
1223 smb_fname_str_dbg(smb_fname), (unsigned int)deny_mode,
1224 (unsigned int)open_func ));
1226 /* Create the NT compatible access_mask. */
1227 switch (GET_OPENX_MODE(deny_mode)) {
1228 case DOS_OPEN_EXEC: /* Implies read-only - used to be FILE_READ_DATA */
1229 case DOS_OPEN_RDONLY:
1230 access_mask = FILE_GENERIC_READ;
1232 case DOS_OPEN_WRONLY:
1233 access_mask = FILE_GENERIC_WRITE;
1237 access_mask = FILE_GENERIC_READ|FILE_GENERIC_WRITE;
1240 DEBUG(10,("map_open_params_to_ntcreate: bad open mode = 0x%x\n",
1241 (unsigned int)GET_OPENX_MODE(deny_mode)));
1245 /* Create the NT compatible create_disposition. */
1246 switch (open_func) {
1247 case OPENX_FILE_EXISTS_FAIL|OPENX_FILE_CREATE_IF_NOT_EXIST:
1248 create_disposition = FILE_CREATE;
1251 case OPENX_FILE_EXISTS_OPEN:
1252 create_disposition = FILE_OPEN;
1255 case OPENX_FILE_EXISTS_OPEN|OPENX_FILE_CREATE_IF_NOT_EXIST:
1256 create_disposition = FILE_OPEN_IF;
1259 case OPENX_FILE_EXISTS_TRUNCATE:
1260 create_disposition = FILE_OVERWRITE;
1263 case OPENX_FILE_EXISTS_TRUNCATE|OPENX_FILE_CREATE_IF_NOT_EXIST:
1264 create_disposition = FILE_OVERWRITE_IF;
1268 /* From samba4 - to be confirmed. */
1269 if (GET_OPENX_MODE(deny_mode) == DOS_OPEN_EXEC) {
1270 create_disposition = FILE_CREATE;
1273 DEBUG(10,("map_open_params_to_ntcreate: bad "
1274 "open_func 0x%x\n", (unsigned int)open_func));
1278 /* Create the NT compatible share modes. */
1279 switch (GET_DENY_MODE(deny_mode)) {
1281 share_mode = FILE_SHARE_NONE;
1285 share_mode = FILE_SHARE_READ;
1289 share_mode = FILE_SHARE_WRITE;
1293 share_mode = FILE_SHARE_READ|FILE_SHARE_WRITE;
1297 create_options |= NTCREATEX_OPTIONS_PRIVATE_DENY_DOS;
1298 if (is_executable(smb_fname->base_name)) {
1299 share_mode = FILE_SHARE_READ|FILE_SHARE_WRITE;
1301 if (GET_OPENX_MODE(deny_mode) == DOS_OPEN_RDONLY) {
1302 share_mode = FILE_SHARE_READ;
1304 share_mode = FILE_SHARE_NONE;
1310 create_options |= NTCREATEX_OPTIONS_PRIVATE_DENY_FCB;
1311 share_mode = FILE_SHARE_NONE;
1315 DEBUG(10,("map_open_params_to_ntcreate: bad deny_mode 0x%x\n",
1316 (unsigned int)GET_DENY_MODE(deny_mode) ));
1320 DEBUG(10,("map_open_params_to_ntcreate: file %s, access_mask = 0x%x, "
1321 "share_mode = 0x%x, create_disposition = 0x%x, "
1322 "create_options = 0x%x\n",
1323 smb_fname_str_dbg(smb_fname),
1324 (unsigned int)access_mask,
1325 (unsigned int)share_mode,
1326 (unsigned int)create_disposition,
1327 (unsigned int)create_options ));
1330 *paccess_mask = access_mask;
1333 *pshare_mode = share_mode;
1335 if (pcreate_disposition) {
1336 *pcreate_disposition = create_disposition;
1338 if (pcreate_options) {
1339 *pcreate_options = create_options;
1346 static void schedule_defer_open(struct share_mode_lock *lck,
1347 struct timeval request_time,
1348 struct smb_request *req)
1350 struct deferred_open_record state;
1352 /* This is a relative time, added to the absolute
1353 request_time value to get the absolute timeout time.
1354 Note that if this is the second or greater time we enter
1355 this codepath for this particular request mid then
1356 request_time is left as the absolute time of the *first*
1357 time this request mid was processed. This is what allows
1358 the request to eventually time out. */
1360 struct timeval timeout;
1362 /* Normally the smbd we asked should respond within
1363 * OPLOCK_BREAK_TIMEOUT seconds regardless of whether
1364 * the client did, give twice the timeout as a safety
1365 * measure here in case the other smbd is stuck
1366 * somewhere else. */
1368 timeout = timeval_set(OPLOCK_BREAK_TIMEOUT*2, 0);
1370 /* Nothing actually uses state.delayed_for_oplocks
1371 but it's handy to differentiate in debug messages
1372 between a 30 second delay due to oplock break, and
1373 a 1 second delay for share mode conflicts. */
1375 state.delayed_for_oplocks = True;
1378 if (!request_timed_out(request_time, timeout)) {
1379 defer_open(lck, request_time, timeout, req, &state);
1383 /****************************************************************************
1384 Work out what access_mask to use from what the client sent us.
1385 ****************************************************************************/
1387 static NTSTATUS calculate_access_mask(connection_struct *conn,
1388 const struct smb_filename *smb_fname,
1390 uint32_t access_mask,
1391 uint32_t *access_mask_out)
1396 * Convert GENERIC bits to specific bits.
1399 se_map_generic(&access_mask, &file_generic_mapping);
1401 /* Calculate MAXIMUM_ALLOWED_ACCESS if requested. */
1402 if (access_mask & MAXIMUM_ALLOWED_ACCESS) {
1405 struct security_descriptor *sd;
1406 uint32_t access_granted = 0;
1408 status = SMB_VFS_GET_NT_ACL(conn, smb_fname->base_name,
1409 (OWNER_SECURITY_INFORMATION |
1410 GROUP_SECURITY_INFORMATION |
1411 DACL_SECURITY_INFORMATION),&sd);
1413 if (!NT_STATUS_IS_OK(status)) {
1414 DEBUG(10, ("calculate_access_mask: Could not get acl "
1416 smb_fname_str_dbg(smb_fname),
1417 nt_errstr(status)));
1418 return NT_STATUS_ACCESS_DENIED;
1421 status = smb1_file_se_access_check(conn,
1423 conn->server_info->ptok,
1429 if (!NT_STATUS_IS_OK(status)) {
1430 DEBUG(10, ("calculate_access_mask: Access denied on "
1431 "file %s: when calculating maximum access\n",
1432 smb_fname_str_dbg(smb_fname)));
1433 return NT_STATUS_ACCESS_DENIED;
1436 access_mask = access_granted;
1438 access_mask = FILE_GENERIC_ALL;
1442 *access_mask_out = access_mask;
1443 return NT_STATUS_OK;
1446 /****************************************************************************
1447 Open a file with a share mode. Passed in an already created files_struct *.
1448 ****************************************************************************/
1450 static NTSTATUS open_file_ntcreate(connection_struct *conn,
1451 struct smb_request *req,
1452 uint32 access_mask, /* access bits (FILE_READ_DATA etc.) */
1453 uint32 share_access, /* share constants (FILE_SHARE_READ etc) */
1454 uint32 create_disposition, /* FILE_OPEN_IF etc. */
1455 uint32 create_options, /* options such as delete on close. */
1456 uint32 new_dos_attributes, /* attributes used for new file. */
1457 int oplock_request, /* internal Samba oplock codes. */
1458 /* Information (FILE_EXISTS etc.) */
1462 struct smb_filename *smb_fname = fsp->fsp_name;
1465 bool file_existed = VALID_STAT(smb_fname->st);
1466 bool def_acl = False;
1467 bool posix_open = False;
1468 bool new_file_created = False;
1469 bool clear_ads = false;
1471 NTSTATUS fsp_open = NT_STATUS_ACCESS_DENIED;
1472 mode_t new_unx_mode = (mode_t)0;
1473 mode_t unx_mode = (mode_t)0;
1475 uint32 existing_dos_attributes = 0;
1476 struct pending_message_list *pml = NULL;
1477 struct timeval request_time = timeval_zero();
1478 struct share_mode_lock *lck = NULL;
1479 uint32 open_access_mask = access_mask;
1485 /* Windows allows a new file to be created and
1486 silently removes a FILE_ATTRIBUTE_DIRECTORY
1487 sent by the client. Do the same. */
1489 new_dos_attributes &= ~FILE_ATTRIBUTE_DIRECTORY;
1491 if (conn->printer) {
1493 * Printers are handled completely differently.
1494 * Most of the passed parameters are ignored.
1498 *pinfo = FILE_WAS_CREATED;
1501 DEBUG(10, ("open_file_ntcreate: printer open fname=%s\n",
1502 smb_fname_str_dbg(smb_fname)));
1505 DEBUG(0,("open_file_ntcreate: printer open without "
1506 "an SMB request!\n"));
1507 return NT_STATUS_INTERNAL_ERROR;
1510 return print_fsp_open(req, conn, smb_fname->base_name,
1514 if (!parent_dirname(talloc_tos(), smb_fname->base_name, &parent_dir,
1516 return NT_STATUS_NO_MEMORY;
1519 if (new_dos_attributes & FILE_FLAG_POSIX_SEMANTICS) {
1521 unx_mode = (mode_t)(new_dos_attributes & ~FILE_FLAG_POSIX_SEMANTICS);
1522 new_dos_attributes = 0;
1524 /* We add aARCH to this as this mode is only used if the file is
1526 unx_mode = unix_mode(conn, new_dos_attributes | aARCH,
1527 smb_fname, parent_dir);
1530 DEBUG(10, ("open_file_ntcreate: fname=%s, dos_attrs=0x%x "
1531 "access_mask=0x%x share_access=0x%x "
1532 "create_disposition = 0x%x create_options=0x%x "
1533 "unix mode=0%o oplock_request=%d\n",
1534 smb_fname_str_dbg(smb_fname), new_dos_attributes,
1535 access_mask, share_access, create_disposition,
1536 create_options, (unsigned int)unx_mode, oplock_request));
1538 if ((req == NULL) && ((oplock_request & INTERNAL_OPEN_ONLY) == 0)) {
1539 DEBUG(0, ("No smb request but not an internal only open!\n"));
1540 return NT_STATUS_INTERNAL_ERROR;
1544 * Only non-internal opens can be deferred at all
1548 && ((pml = get_open_deferred_message(req->mid)) != NULL)) {
1549 struct deferred_open_record *state =
1550 (struct deferred_open_record *)pml->private_data.data;
1552 /* Remember the absolute time of the original
1553 request with this mid. We'll use it later to
1554 see if this has timed out. */
1556 request_time = pml->request_time;
1558 /* Remove the deferred open entry under lock. */
1559 lck = get_share_mode_lock(talloc_tos(), state->id, NULL, NULL,
1562 DEBUG(0, ("could not get share mode lock\n"));
1564 del_deferred_open_entry(lck, req->mid);
1568 /* Ensure we don't reprocess this message. */
1569 remove_deferred_open_smb_message(req->mid);
1572 status = check_name(conn, smb_fname->base_name);
1573 if (!NT_STATUS_IS_OK(status)) {
1578 new_dos_attributes &= SAMBA_ATTRIBUTES_MASK;
1580 existing_dos_attributes = dos_mode(conn, smb_fname);
1584 /* ignore any oplock requests if oplocks are disabled */
1585 if (!lp_oplocks(SNUM(conn)) || global_client_failed_oplock_break ||
1586 IS_VETO_OPLOCK_PATH(conn, smb_fname->base_name)) {
1587 /* Mask off everything except the private Samba bits. */
1588 oplock_request &= SAMBA_PRIVATE_OPLOCK_MASK;
1591 /* this is for OS/2 long file names - say we don't support them */
1592 if (!lp_posix_pathnames() && strstr(smb_fname->base_name,".+,;=[].")) {
1593 /* OS/2 Workplace shell fix may be main code stream in a later
1595 DEBUG(5,("open_file_ntcreate: OS/2 long filenames are not "
1597 if (use_nt_status()) {
1598 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1600 return NT_STATUS_DOS(ERRDOS, ERRcannotopen);
1603 switch( create_disposition ) {
1605 * Currently we're using FILE_SUPERSEDE as the same as
1606 * FILE_OVERWRITE_IF but they really are
1607 * different. FILE_SUPERSEDE deletes an existing file
1608 * (requiring delete access) then recreates it.
1610 case FILE_SUPERSEDE:
1611 /* If file exists replace/overwrite. If file doesn't
1613 flags2 |= (O_CREAT | O_TRUNC);
1617 case FILE_OVERWRITE_IF:
1618 /* If file exists replace/overwrite. If file doesn't
1620 flags2 |= (O_CREAT | O_TRUNC);
1625 /* If file exists open. If file doesn't exist error. */
1626 if (!file_existed) {
1627 DEBUG(5,("open_file_ntcreate: FILE_OPEN "
1628 "requested for file %s and file "
1630 smb_fname_str_dbg(smb_fname)));
1632 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1636 case FILE_OVERWRITE:
1637 /* If file exists overwrite. If file doesn't exist
1639 if (!file_existed) {
1640 DEBUG(5,("open_file_ntcreate: FILE_OVERWRITE "
1641 "requested for file %s and file "
1643 smb_fname_str_dbg(smb_fname) ));
1645 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1652 /* If file exists error. If file doesn't exist
1655 DEBUG(5,("open_file_ntcreate: FILE_CREATE "
1656 "requested for file %s and file "
1657 "already exists.\n",
1658 smb_fname_str_dbg(smb_fname)));
1659 if (S_ISDIR(smb_fname->st.st_ex_mode)) {
1664 return map_nt_error_from_unix(errno);
1666 flags2 |= (O_CREAT|O_EXCL);
1670 /* If file exists open. If file doesn't exist
1676 return NT_STATUS_INVALID_PARAMETER;
1679 /* We only care about matching attributes on file exists and
1682 if (!posix_open && file_existed && ((create_disposition == FILE_OVERWRITE) ||
1683 (create_disposition == FILE_OVERWRITE_IF))) {
1684 if (!open_match_attributes(conn, existing_dos_attributes,
1686 smb_fname->st.st_ex_mode,
1687 unx_mode, &new_unx_mode)) {
1688 DEBUG(5,("open_file_ntcreate: attributes missmatch "
1689 "for file %s (%x %x) (0%o, 0%o)\n",
1690 smb_fname_str_dbg(smb_fname),
1691 existing_dos_attributes,
1693 (unsigned int)smb_fname->st.st_ex_mode,
1694 (unsigned int)unx_mode ));
1696 return NT_STATUS_ACCESS_DENIED;
1700 status = calculate_access_mask(conn, smb_fname, file_existed,
1703 if (!NT_STATUS_IS_OK(status)) {
1704 DEBUG(10, ("open_file_ntcreate: calculate_access_mask "
1705 "on file %s returned %s\n",
1706 smb_fname_str_dbg(smb_fname), nt_errstr(status)));
1710 open_access_mask = access_mask;
1712 if ((flags2 & O_TRUNC) || (oplock_request & FORCE_OPLOCK_BREAK_TO_NONE)) {
1713 open_access_mask |= FILE_WRITE_DATA; /* This will cause oplock breaks. */
1716 DEBUG(10, ("open_file_ntcreate: fname=%s, after mapping "
1717 "access_mask=0x%x\n", smb_fname_str_dbg(smb_fname),
1721 * Note that we ignore the append flag as append does not
1722 * mean the same thing under DOS and Unix.
1725 if ((access_mask & (FILE_WRITE_DATA | FILE_APPEND_DATA)) ||
1726 (oplock_request & FORCE_OPLOCK_BREAK_TO_NONE)) {
1727 /* DENY_DOS opens are always underlying read-write on the
1728 file handle, no matter what the requested access mask
1730 if ((create_options & NTCREATEX_OPTIONS_PRIVATE_DENY_DOS) ||
1731 access_mask & (FILE_READ_ATTRIBUTES|FILE_READ_DATA|FILE_READ_EA|FILE_EXECUTE)) {
1741 * Currently we only look at FILE_WRITE_THROUGH for create options.
1745 if ((create_options & FILE_WRITE_THROUGH) && lp_strict_sync(SNUM(conn))) {
1750 if (posix_open && (access_mask & FILE_APPEND_DATA)) {
1754 if (!posix_open && !CAN_WRITE(conn)) {
1756 * We should really return a permission denied error if either
1757 * O_CREAT or O_TRUNC are set, but for compatibility with
1758 * older versions of Samba we just AND them out.
1760 flags2 &= ~(O_CREAT|O_TRUNC);
1764 * Ensure we can't write on a read-only share or file.
1767 if (flags != O_RDONLY && file_existed &&
1768 (!CAN_WRITE(conn) || IS_DOS_READONLY(existing_dos_attributes))) {
1769 DEBUG(5,("open_file_ntcreate: write access requested for "
1770 "file %s on read only %s\n",
1771 smb_fname_str_dbg(smb_fname),
1772 !CAN_WRITE(conn) ? "share" : "file" ));
1774 return NT_STATUS_ACCESS_DENIED;
1777 fsp->file_id = vfs_file_id_from_sbuf(conn, &smb_fname->st);
1778 fsp->share_access = share_access;
1779 fsp->fh->private_options = create_options;
1780 fsp->access_mask = open_access_mask; /* We change this to the
1781 * requested access_mask after
1782 * the open is done. */
1783 fsp->posix_open = posix_open;
1785 /* Ensure no SAMBA_PRIVATE bits can be set. */
1786 fsp->oplock_type = (oplock_request & ~SAMBA_PRIVATE_OPLOCK_MASK);
1788 if (timeval_is_zero(&request_time)) {
1789 request_time = fsp->open_time;
1793 struct timespec old_write_time = smb_fname->st.st_ex_mtime;
1794 id = vfs_file_id_from_sbuf(conn, &smb_fname->st);
1796 lck = get_share_mode_lock(talloc_tos(), id,
1798 smb_fname, &old_write_time);
1801 DEBUG(0, ("Could not get share mode lock\n"));
1802 return NT_STATUS_SHARING_VIOLATION;
1805 /* First pass - send break only on batch oplocks. */
1807 && delay_for_oplocks(lck, fsp, req->mid, 1,
1809 schedule_defer_open(lck, request_time, req);
1811 return NT_STATUS_SHARING_VIOLATION;
1814 /* Use the client requested access mask here, not the one we
1816 status = open_mode_check(conn, lck, access_mask, share_access,
1817 create_options, &file_existed);
1819 if (NT_STATUS_IS_OK(status)) {
1820 /* We might be going to allow this open. Check oplock
1822 /* Second pass - send break for both batch or
1823 * exclusive oplocks. */
1825 && delay_for_oplocks(lck, fsp, req->mid, 2,
1827 schedule_defer_open(lck, request_time, req);
1829 return NT_STATUS_SHARING_VIOLATION;
1833 if (NT_STATUS_EQUAL(status, NT_STATUS_DELETE_PENDING)) {
1834 /* DELETE_PENDING is not deferred for a second */
1839 if (!NT_STATUS_IS_OK(status)) {
1840 uint32 can_access_mask;
1841 bool can_access = True;
1843 SMB_ASSERT(NT_STATUS_EQUAL(status, NT_STATUS_SHARING_VIOLATION));
1845 /* Check if this can be done with the deny_dos and fcb
1847 if (create_options &
1848 (NTCREATEX_OPTIONS_PRIVATE_DENY_DOS|
1849 NTCREATEX_OPTIONS_PRIVATE_DENY_FCB)) {
1851 DEBUG(0, ("DOS open without an SMB "
1854 return NT_STATUS_INTERNAL_ERROR;
1857 /* Use the client requested access mask here,
1858 * not the one we open with. */
1859 status = fcb_or_dos_open(req,
1870 if (NT_STATUS_IS_OK(status)) {
1873 *pinfo = FILE_WAS_OPENED;
1875 return NT_STATUS_OK;
1880 * This next line is a subtlety we need for
1881 * MS-Access. If a file open will fail due to share
1882 * permissions and also for security (access) reasons,
1883 * we need to return the access failed error, not the
1884 * share error. We can't open the file due to kernel
1885 * oplock deadlock (it's possible we failed above on
1886 * the open_mode_check()) so use a userspace check.
1889 if (flags & O_RDWR) {
1890 can_access_mask = FILE_READ_DATA|FILE_WRITE_DATA;
1891 } else if (flags & O_WRONLY) {
1892 can_access_mask = FILE_WRITE_DATA;
1894 can_access_mask = FILE_READ_DATA;
1897 if (((can_access_mask & FILE_WRITE_DATA) &&
1898 !CAN_WRITE(conn)) ||
1899 !can_access_file_data(conn, smb_fname,
1905 * If we're returning a share violation, ensure we
1906 * cope with the braindead 1 second delay.
1909 if (!(oplock_request & INTERNAL_OPEN_ONLY) &&
1910 lp_defer_sharing_violations()) {
1911 struct timeval timeout;
1912 struct deferred_open_record state;
1915 /* this is a hack to speed up torture tests
1917 timeout_usecs = lp_parm_int(SNUM(conn),
1918 "smbd","sharedelay",
1919 SHARING_VIOLATION_USEC_WAIT);
1921 /* This is a relative time, added to the absolute
1922 request_time value to get the absolute timeout time.
1923 Note that if this is the second or greater time we enter
1924 this codepath for this particular request mid then
1925 request_time is left as the absolute time of the *first*
1926 time this request mid was processed. This is what allows
1927 the request to eventually time out. */
1929 timeout = timeval_set(0, timeout_usecs);
1931 /* Nothing actually uses state.delayed_for_oplocks
1932 but it's handy to differentiate in debug messages
1933 between a 30 second delay due to oplock break, and
1934 a 1 second delay for share mode conflicts. */
1936 state.delayed_for_oplocks = False;
1940 && !request_timed_out(request_time,
1942 defer_open(lck, request_time, timeout,
1950 * We have detected a sharing violation here
1951 * so return the correct error code
1953 status = NT_STATUS_SHARING_VIOLATION;
1955 status = NT_STATUS_ACCESS_DENIED;
1961 * We exit this block with the share entry *locked*.....
1965 SMB_ASSERT(!file_existed || (lck != NULL));
1968 * Ensure we pay attention to default ACLs on directories if required.
1971 if ((flags2 & O_CREAT) && lp_inherit_acls(SNUM(conn)) &&
1972 (def_acl = directory_has_default_acl(conn, parent_dir))) {
1973 unx_mode = (0777 & lp_create_mask(SNUM(conn)));
1976 DEBUG(4,("calling open_file with flags=0x%X flags2=0x%X mode=0%o, "
1977 "access_mask = 0x%x, open_access_mask = 0x%x\n",
1978 (unsigned int)flags, (unsigned int)flags2,
1979 (unsigned int)unx_mode, (unsigned int)access_mask,
1980 (unsigned int)open_access_mask));
1983 * open_file strips any O_TRUNC flags itself.
1986 fsp_open = open_file(fsp, conn, req, parent_dir,
1987 flags|flags2, unx_mode, access_mask,
1990 if (!NT_STATUS_IS_OK(fsp_open)) {
1997 if (!file_existed) {
1998 struct timespec old_write_time = smb_fname->st.st_ex_mtime;
2000 * Deal with the race condition where two smbd's detect the
2001 * file doesn't exist and do the create at the same time. One
2002 * of them will win and set a share mode, the other (ie. this
2003 * one) should check if the requested share mode for this
2004 * create is allowed.
2008 * Now the file exists and fsp is successfully opened,
2009 * fsp->dev and fsp->inode are valid and should replace the
2010 * dev=0,inode=0 from a non existent file. Spotted by
2011 * Nadav Danieli <nadavd@exanet.com>. JRA.
2016 lck = get_share_mode_lock(talloc_tos(), id,
2018 smb_fname, &old_write_time);
2021 DEBUG(0, ("open_file_ntcreate: Could not get share "
2022 "mode lock for %s\n",
2023 smb_fname_str_dbg(smb_fname)));
2025 return NT_STATUS_SHARING_VIOLATION;
2028 /* First pass - send break only on batch oplocks. */
2030 && delay_for_oplocks(lck, fsp, req->mid, 1,
2032 schedule_defer_open(lck, request_time, req);
2035 return NT_STATUS_SHARING_VIOLATION;
2038 status = open_mode_check(conn, lck, access_mask, share_access,
2039 create_options, &file_existed);
2041 if (NT_STATUS_IS_OK(status)) {
2042 /* We might be going to allow this open. Check oplock
2044 /* Second pass - send break for both batch or
2045 * exclusive oplocks. */
2047 && delay_for_oplocks(lck, fsp, req->mid, 2,
2049 schedule_defer_open(lck, request_time, req);
2052 return NT_STATUS_SHARING_VIOLATION;
2056 if (!NT_STATUS_IS_OK(status)) {
2057 struct deferred_open_record state;
2061 state.delayed_for_oplocks = False;
2064 /* Do it all over again immediately. In the second
2065 * round we will find that the file existed and handle
2066 * the DELETE_PENDING and FCB cases correctly. No need
2067 * to duplicate the code here. Essentially this is a
2068 * "goto top of this function", but don't tell
2072 defer_open(lck, request_time, timeval_zero(),
2080 * We exit this block with the share entry *locked*.....
2085 SMB_ASSERT(lck != NULL);
2087 /* Delete streams if create_disposition requires it */
2088 if (file_existed && clear_ads &&
2089 !is_ntfs_stream_smb_fname(smb_fname)) {
2090 status = delete_all_streams(conn, smb_fname->base_name);
2091 if (!NT_STATUS_IS_OK(status)) {
2098 /* note that we ignore failure for the following. It is
2099 basically a hack for NFS, and NFS will never set one of
2100 these only read them. Nobody but Samba can ever set a deny
2101 mode and we have already checked our more authoritative
2102 locking database for permission to set this deny mode. If
2103 the kernel refuses the operations then the kernel is wrong.
2104 note that GPFS supports it as well - jmcd */
2106 if (fsp->fh->fd != -1) {
2108 ret_flock = SMB_VFS_KERNEL_FLOCK(fsp, share_access, access_mask);
2109 if(ret_flock == -1 ){
2114 return NT_STATUS_SHARING_VIOLATION;
2119 * At this point onwards, we can guarentee that the share entry
2120 * is locked, whether we created the file or not, and that the
2121 * deny mode is compatible with all current opens.
2125 * If requested, truncate the file.
2128 if (flags2&O_TRUNC) {
2130 * We are modifing the file after open - update the stat
2133 if ((SMB_VFS_FTRUNCATE(fsp, 0) == -1) ||
2134 (SMB_VFS_FSTAT(fsp, &smb_fname->st)==-1)) {
2135 status = map_nt_error_from_unix(errno);
2142 /* Record the options we were opened with. */
2143 fsp->share_access = share_access;
2144 fsp->fh->private_options = create_options;
2146 * According to Samba4, SEC_FILE_READ_ATTRIBUTE is always granted,
2148 fsp->access_mask = access_mask | FILE_READ_ATTRIBUTES;
2151 /* stat opens on existing files don't get oplocks. */
2152 if (is_stat_open(open_access_mask)) {
2153 fsp->oplock_type = NO_OPLOCK;
2156 if (!(flags2 & O_TRUNC)) {
2157 info = FILE_WAS_OPENED;
2159 info = FILE_WAS_OVERWRITTEN;
2162 info = FILE_WAS_CREATED;
2170 * Setup the oplock info in both the shared memory and
2174 if (!set_file_oplock(fsp, fsp->oplock_type)) {
2175 /* Could not get the kernel oplock */
2176 fsp->oplock_type = NO_OPLOCK;
2179 if (info == FILE_WAS_OVERWRITTEN || info == FILE_WAS_CREATED || info == FILE_WAS_SUPERSEDED) {
2180 new_file_created = True;
2183 set_share_mode(lck, fsp, conn->server_info->utok.uid, 0,
2186 /* Handle strange delete on close create semantics. */
2187 if (create_options & FILE_DELETE_ON_CLOSE) {
2189 status = can_set_delete_on_close(fsp, new_dos_attributes);
2191 if (!NT_STATUS_IS_OK(status)) {
2192 /* Remember to delete the mode we just added. */
2193 del_share_mode(lck, fsp);
2198 /* Note that here we set the *inital* delete on close flag,
2199 not the regular one. The magic gets handled in close. */
2200 fsp->initial_delete_on_close = True;
2203 if (new_file_created) {
2204 /* Files should be initially set as archive */
2205 if (lp_map_archive(SNUM(conn)) ||
2206 lp_store_dos_attributes(SNUM(conn))) {
2208 if (file_set_dosmode(conn, smb_fname,
2209 new_dos_attributes | aARCH,
2210 parent_dir, true) == 0) {
2211 unx_mode = smb_fname->st.st_ex_mode;
2218 * Take care of inherited ACLs on created files - if default ACL not
2222 if (!posix_open && !file_existed && !def_acl) {
2224 int saved_errno = errno; /* We might get ENOSYS in the next
2227 if (SMB_VFS_FCHMOD_ACL(fsp, unx_mode) == -1 &&
2229 errno = saved_errno; /* Ignore ENOSYS */
2232 } else if (new_unx_mode) {
2236 /* Attributes need changing. File already existed. */
2239 int saved_errno = errno; /* We might get ENOSYS in the
2241 ret = SMB_VFS_FCHMOD_ACL(fsp, new_unx_mode);
2243 if (ret == -1 && errno == ENOSYS) {
2244 errno = saved_errno; /* Ignore ENOSYS */
2246 DEBUG(5, ("open_file_ntcreate: reset "
2247 "attributes of file %s to 0%o\n",
2248 smb_fname_str_dbg(smb_fname),
2249 (unsigned int)new_unx_mode));
2250 ret = 0; /* Don't do the fchmod below. */
2255 (SMB_VFS_FCHMOD(fsp, new_unx_mode) == -1))
2256 DEBUG(5, ("open_file_ntcreate: failed to reset "
2257 "attributes of file %s to 0%o\n",
2258 smb_fname_str_dbg(smb_fname),
2259 (unsigned int)new_unx_mode));
2262 /* If this is a successful open, we must remove any deferred open
2265 del_deferred_open_entry(lck, req->mid);
2269 return NT_STATUS_OK;
2273 /****************************************************************************
2274 Open a file for for write to ensure that we can fchmod it.
2275 ****************************************************************************/
2277 NTSTATUS open_file_fchmod(connection_struct *conn,
2278 struct smb_filename *smb_fname,
2279 files_struct **result)
2281 if (!VALID_STAT(smb_fname->st)) {
2282 return NT_STATUS_INVALID_PARAMETER;
2285 return SMB_VFS_CREATE_FILE(
2288 0, /* root_dir_fid */
2289 smb_fname, /* fname */
2290 FILE_WRITE_DATA, /* access_mask */
2291 (FILE_SHARE_READ | FILE_SHARE_WRITE | /* share_access */
2293 FILE_OPEN, /* create_disposition*/
2294 0, /* create_options */
2295 0, /* file_attributes */
2296 INTERNAL_OPEN_ONLY, /* oplock_request */
2297 0, /* allocation_size */
2300 result, /* result */
2304 static NTSTATUS mkdir_internal(connection_struct *conn,
2305 struct smb_filename *smb_dname,
2306 uint32 file_attributes)
2311 bool posix_open = false;
2313 if(!CAN_WRITE(conn)) {
2314 DEBUG(5,("mkdir_internal: failing create on read-only share "
2315 "%s\n", lp_servicename(SNUM(conn))));
2316 return NT_STATUS_ACCESS_DENIED;
2319 status = check_name(conn, smb_dname->base_name);
2320 if (!NT_STATUS_IS_OK(status)) {
2324 if (!parent_dirname(talloc_tos(), smb_dname->base_name, &parent_dir,
2326 return NT_STATUS_NO_MEMORY;
2329 if (file_attributes & FILE_FLAG_POSIX_SEMANTICS) {
2331 mode = (mode_t)(file_attributes & ~FILE_FLAG_POSIX_SEMANTICS);
2333 mode = unix_mode(conn, aDIR, smb_dname, parent_dir);
2336 if (SMB_VFS_MKDIR(conn, smb_dname->base_name, mode) != 0) {
2337 return map_nt_error_from_unix(errno);
2340 /* Ensure we're checking for a symlink here.... */
2341 /* We don't want to get caught by a symlink racer. */
2343 if (SMB_VFS_LSTAT(conn, smb_dname) == -1) {
2344 DEBUG(2, ("Could not stat directory '%s' just created: %s\n",
2345 smb_fname_str_dbg(smb_dname), strerror(errno)));
2346 return map_nt_error_from_unix(errno);
2349 if (!S_ISDIR(smb_dname->st.st_ex_mode)) {
2350 DEBUG(0, ("Directory just '%s' created is not a directory\n",
2351 smb_fname_str_dbg(smb_dname)));
2352 return NT_STATUS_ACCESS_DENIED;
2355 if (lp_store_dos_attributes(SNUM(conn))) {
2357 file_set_dosmode(conn, smb_dname,
2358 file_attributes | aDIR,
2363 if (lp_inherit_perms(SNUM(conn))) {
2364 inherit_access_posix_acl(conn, parent_dir,
2365 smb_dname->base_name, mode);
2370 * Check if high bits should have been set,
2371 * then (if bits are missing): add them.
2372 * Consider bits automagically set by UNIX, i.e. SGID bit from parent
2375 if ((mode & ~(S_IRWXU|S_IRWXG|S_IRWXO)) &&
2376 (mode & ~smb_dname->st.st_ex_mode)) {
2377 SMB_VFS_CHMOD(conn, smb_dname->base_name,
2378 (smb_dname->st.st_ex_mode |
2379 (mode & ~smb_dname->st.st_ex_mode)));
2383 /* Change the owner if required. */
2384 if (lp_inherit_owner(SNUM(conn))) {
2385 change_dir_owner_to_parent(conn, parent_dir,
2386 smb_dname->base_name,
2390 notify_fname(conn, NOTIFY_ACTION_ADDED, FILE_NOTIFY_CHANGE_DIR_NAME,
2391 smb_dname->base_name);
2393 return NT_STATUS_OK;
2396 /****************************************************************************
2397 Open a directory from an NT SMB call.
2398 ****************************************************************************/
2400 static NTSTATUS open_directory(connection_struct *conn,
2401 struct smb_request *req,
2402 struct smb_filename *smb_dname,
2404 uint32 share_access,
2405 uint32 create_disposition,
2406 uint32 create_options,
2407 uint32 file_attributes,
2409 files_struct **result)
2411 files_struct *fsp = NULL;
2412 bool dir_existed = VALID_STAT(smb_dname->st) ? True : False;
2413 struct share_mode_lock *lck = NULL;
2415 struct timespec mtimespec;
2418 SMB_ASSERT(!is_ntfs_stream_smb_fname(smb_dname));
2420 /* Ensure we have a directory attribute. */
2421 file_attributes |= FILE_ATTRIBUTE_DIRECTORY;
2423 DEBUG(5,("open_directory: opening directory %s, access_mask = 0x%x, "
2424 "share_access = 0x%x create_options = 0x%x, "
2425 "create_disposition = 0x%x, file_attributes = 0x%x\n",
2426 smb_fname_str_dbg(smb_dname),
2427 (unsigned int)access_mask,
2428 (unsigned int)share_access,
2429 (unsigned int)create_options,
2430 (unsigned int)create_disposition,
2431 (unsigned int)file_attributes));
2433 if (!(file_attributes & FILE_FLAG_POSIX_SEMANTICS) &&
2434 (conn->fs_capabilities & FILE_NAMED_STREAMS) &&
2435 is_ntfs_stream_smb_fname(smb_dname)) {
2436 DEBUG(2, ("open_directory: %s is a stream name!\n",
2437 smb_fname_str_dbg(smb_dname)));
2438 return NT_STATUS_NOT_A_DIRECTORY;
2441 status = calculate_access_mask(conn, smb_dname, dir_existed,
2442 access_mask, &access_mask);
2443 if (!NT_STATUS_IS_OK(status)) {
2444 DEBUG(10, ("open_directory: calculate_access_mask "
2445 "on file %s returned %s\n",
2446 smb_fname_str_dbg(smb_dname),
2447 nt_errstr(status)));
2451 if ((access_mask & SEC_FLAG_SYSTEM_SECURITY) &&
2452 !user_has_privileges(current_user.nt_user_token, &se_security)) {
2453 DEBUG(10, ("open_directory: open on %s "
2454 "failed - SEC_FLAG_SYSTEM_SECURITY denied.\n",
2455 smb_fname_str_dbg(smb_dname)));
2456 return NT_STATUS_PRIVILEGE_NOT_HELD;
2459 switch( create_disposition ) {
2462 info = FILE_WAS_OPENED;
2465 * We want to follow symlinks here.
2468 if (SMB_VFS_STAT(conn, smb_dname) != 0) {
2469 return map_nt_error_from_unix(errno);
2476 /* If directory exists error. If directory doesn't
2479 status = mkdir_internal(conn, smb_dname,
2482 if (!NT_STATUS_IS_OK(status)) {
2483 DEBUG(2, ("open_directory: unable to create "
2484 "%s. Error was %s\n",
2485 smb_fname_str_dbg(smb_dname),
2486 nt_errstr(status)));
2490 info = FILE_WAS_CREATED;
2495 * If directory exists open. If directory doesn't
2499 status = mkdir_internal(conn, smb_dname,
2502 if (NT_STATUS_IS_OK(status)) {
2503 info = FILE_WAS_CREATED;
2506 if (NT_STATUS_EQUAL(status,
2507 NT_STATUS_OBJECT_NAME_COLLISION)) {
2508 info = FILE_WAS_OPENED;
2509 status = NT_STATUS_OK;
2514 case FILE_SUPERSEDE:
2515 case FILE_OVERWRITE:
2516 case FILE_OVERWRITE_IF:
2518 DEBUG(5,("open_directory: invalid create_disposition "
2519 "0x%x for directory %s\n",
2520 (unsigned int)create_disposition,
2521 smb_fname_str_dbg(smb_dname)));
2522 return NT_STATUS_INVALID_PARAMETER;
2525 if(!S_ISDIR(smb_dname->st.st_ex_mode)) {
2526 DEBUG(5,("open_directory: %s is not a directory !\n",
2527 smb_fname_str_dbg(smb_dname)));
2528 return NT_STATUS_NOT_A_DIRECTORY;
2531 if (info == FILE_WAS_OPENED) {
2532 uint32_t access_granted = 0;
2533 status = smbd_check_open_rights(conn, smb_dname, access_mask,
2536 /* Were we trying to do a directory open
2537 * for delete and didn't get DELETE
2538 * access (only) ? Check if the
2539 * directory allows DELETE_CHILD.
2541 * http://blogs.msdn.com/oldnewthing/archive/2004/06/04/148426.aspx
2544 if ((NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED) &&
2545 (access_mask & DELETE_ACCESS) &&
2546 (access_granted == DELETE_ACCESS) &&
2547 can_delete_file_in_directory(conn, smb_dname))) {
2548 DEBUG(10,("open_directory: overrode ACCESS_DENIED "
2549 "on directory %s\n",
2550 smb_fname_str_dbg(smb_dname)));
2551 status = NT_STATUS_OK;
2554 if (!NT_STATUS_IS_OK(status)) {
2555 DEBUG(10, ("open_directory: smbd_check_open_rights on "
2556 "file %s failed with %s\n",
2557 smb_fname_str_dbg(smb_dname),
2558 nt_errstr(status)));
2563 status = file_new(req, conn, &fsp);
2564 if(!NT_STATUS_IS_OK(status)) {
2569 * Setup the files_struct for it.
2572 fsp->mode = smb_dname->st.st_ex_mode;
2573 fsp->file_id = vfs_file_id_from_sbuf(conn, &smb_dname->st);
2574 fsp->vuid = req ? req->vuid : UID_FIELD_INVALID;
2575 fsp->file_pid = req ? req->smbpid : 0;
2576 fsp->can_lock = False;
2577 fsp->can_read = False;
2578 fsp->can_write = False;
2580 fsp->share_access = share_access;
2581 fsp->fh->private_options = create_options;
2583 * According to Samba4, SEC_FILE_READ_ATTRIBUTE is always granted,
2585 fsp->access_mask = access_mask | FILE_READ_ATTRIBUTES;
2586 fsp->print_file = False;
2587 fsp->modified = False;
2588 fsp->oplock_type = NO_OPLOCK;
2589 fsp->sent_oplock_break = NO_BREAK_SENT;
2590 fsp->is_directory = True;
2591 fsp->posix_open = (file_attributes & FILE_FLAG_POSIX_SEMANTICS) ? True : False;
2592 status = fsp_set_smb_fname(fsp, smb_dname);
2593 if (!NT_STATUS_IS_OK(status)) {
2597 mtimespec = smb_dname->st.st_ex_mtime;
2599 lck = get_share_mode_lock(talloc_tos(), fsp->file_id,
2600 conn->connectpath, smb_dname, &mtimespec);
2603 DEBUG(0, ("open_directory: Could not get share mode lock for "
2604 "%s\n", smb_fname_str_dbg(smb_dname)));
2605 file_free(req, fsp);
2606 return NT_STATUS_SHARING_VIOLATION;
2609 status = open_mode_check(conn, lck, access_mask, share_access,
2610 create_options, &dir_existed);
2612 if (!NT_STATUS_IS_OK(status)) {
2614 file_free(req, fsp);
2618 set_share_mode(lck, fsp, conn->server_info->utok.uid, 0, NO_OPLOCK);
2620 /* For directories the delete on close bit at open time seems
2621 always to be honored on close... See test 19 in Samba4 BASE-DELETE. */
2622 if (create_options & FILE_DELETE_ON_CLOSE) {
2623 status = can_set_delete_on_close(fsp, 0);
2624 if (!NT_STATUS_IS_OK(status) && !NT_STATUS_EQUAL(status, NT_STATUS_DIRECTORY_NOT_EMPTY)) {
2626 file_free(req, fsp);
2630 if (NT_STATUS_IS_OK(status)) {
2631 /* Note that here we set the *inital* delete on close flag,
2632 not the regular one. The magic gets handled in close. */
2633 fsp->initial_delete_on_close = True;
2644 return NT_STATUS_OK;
2647 NTSTATUS create_directory(connection_struct *conn, struct smb_request *req,
2648 struct smb_filename *smb_dname)
2653 status = SMB_VFS_CREATE_FILE(
2656 0, /* root_dir_fid */
2657 smb_dname, /* fname */
2658 FILE_READ_ATTRIBUTES, /* access_mask */
2659 FILE_SHARE_NONE, /* share_access */
2660 FILE_CREATE, /* create_disposition*/
2661 FILE_DIRECTORY_FILE, /* create_options */
2662 FILE_ATTRIBUTE_DIRECTORY, /* file_attributes */
2663 0, /* oplock_request */
2664 0, /* allocation_size */
2670 if (NT_STATUS_IS_OK(status)) {
2671 close_file(req, fsp, NORMAL_CLOSE);
2677 /****************************************************************************
2678 Receive notification that one of our open files has been renamed by another
2680 ****************************************************************************/
2682 void msg_file_was_renamed(struct messaging_context *msg,
2685 struct server_id server_id,
2689 char *frm = (char *)data->data;
2691 const char *sharepath;
2692 const char *base_name;
2693 const char *stream_name;
2694 struct smb_filename *smb_fname = NULL;
2695 size_t sp_len, bn_len;
2698 if (data->data == NULL
2699 || data->length < MSG_FILE_RENAMED_MIN_SIZE + 2) {
2700 DEBUG(0, ("msg_file_was_renamed: Got invalid msg len %d\n",
2701 (int)data->length));
2705 /* Unpack the message. */
2706 pull_file_id_24(frm, &id);
2707 sharepath = &frm[24];
2708 sp_len = strlen(sharepath);
2709 base_name = sharepath + sp_len + 1;
2710 bn_len = strlen(base_name);
2711 stream_name = sharepath + sp_len + 1 + bn_len + 1;
2713 /* stream_name must always be NULL if there is no stream. */
2714 if (stream_name[0] == '\0') {
2718 status = create_synthetic_smb_fname(talloc_tos(), base_name,
2719 stream_name, NULL, &smb_fname);
2720 if (!NT_STATUS_IS_OK(status)) {
2724 DEBUG(10,("msg_file_was_renamed: Got rename message for sharepath %s, new name %s, "
2726 sharepath, smb_fname_str_dbg(smb_fname),
2727 file_id_string_tos(&id)));
2729 for(fsp = file_find_di_first(id); fsp; fsp = file_find_di_next(fsp)) {
2730 if (memcmp(fsp->conn->connectpath, sharepath, sp_len) == 0) {
2732 DEBUG(10,("msg_file_was_renamed: renaming file fnum %d from %s -> %s\n",
2733 fsp->fnum, fsp_str_dbg(fsp),
2734 smb_fname_str_dbg(smb_fname)));
2735 status = fsp_set_smb_fname(fsp, smb_fname);
2736 if (!NT_STATUS_IS_OK(status)) {
2741 /* Now we have the complete path we can work out if this is
2742 actually within this share and adjust newname accordingly. */
2743 DEBUG(10,("msg_file_was_renamed: share mismatch (sharepath %s "
2744 "not sharepath %s) "
2745 "fnum %d from %s -> %s\n",
2746 fsp->conn->connectpath,
2750 smb_fname_str_dbg(smb_fname)));
2754 TALLOC_FREE(smb_fname);
2759 * If a main file is opened for delete, all streams need to be checked for
2760 * !FILE_SHARE_DELETE. Do this by opening with DELETE_ACCESS.
2761 * If that works, delete them all by setting the delete on close and close.
2764 NTSTATUS open_streams_for_delete(connection_struct *conn,
2767 struct stream_struct *stream_info;
2768 files_struct **streams;
2770 unsigned int num_streams;
2771 TALLOC_CTX *frame = talloc_stackframe();
2774 status = SMB_VFS_STREAMINFO(conn, NULL, fname, talloc_tos(),
2775 &num_streams, &stream_info);
2777 if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_IMPLEMENTED)
2778 || NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
2779 DEBUG(10, ("no streams around\n"));
2781 return NT_STATUS_OK;
2784 if (!NT_STATUS_IS_OK(status)) {
2785 DEBUG(10, ("SMB_VFS_STREAMINFO failed: %s\n",
2786 nt_errstr(status)));
2790 DEBUG(10, ("open_streams_for_delete found %d streams\n",
2793 if (num_streams == 0) {
2795 return NT_STATUS_OK;
2798 streams = TALLOC_ARRAY(talloc_tos(), files_struct *, num_streams);
2799 if (streams == NULL) {
2800 DEBUG(0, ("talloc failed\n"));
2801 status = NT_STATUS_NO_MEMORY;
2805 for (i=0; i<num_streams; i++) {
2806 struct smb_filename *smb_fname = NULL;
2808 if (strequal(stream_info[i].name, "::$DATA")) {
2813 status = create_synthetic_smb_fname(talloc_tos(), fname,
2814 stream_info[i].name,
2816 if (!NT_STATUS_IS_OK(status)) {
2820 if (SMB_VFS_STAT(conn, smb_fname) == -1) {
2821 DEBUG(10, ("Unable to stat stream: %s\n",
2822 smb_fname_str_dbg(smb_fname)));
2825 status = SMB_VFS_CREATE_FILE(
2828 0, /* root_dir_fid */
2829 smb_fname, /* fname */
2830 DELETE_ACCESS, /* access_mask */
2831 (FILE_SHARE_READ | /* share_access */
2832 FILE_SHARE_WRITE | FILE_SHARE_DELETE),
2833 FILE_OPEN, /* create_disposition*/
2834 NTCREATEX_OPTIONS_PRIVATE_STREAM_DELETE, /* create_options */
2835 FILE_ATTRIBUTE_NORMAL, /* file_attributes */
2836 0, /* oplock_request */
2837 0, /* allocation_size */
2840 &streams[i], /* result */
2843 if (!NT_STATUS_IS_OK(status)) {
2844 DEBUG(10, ("Could not open stream %s: %s\n",
2845 smb_fname_str_dbg(smb_fname),
2846 nt_errstr(status)));
2848 TALLOC_FREE(smb_fname);
2851 TALLOC_FREE(smb_fname);
2855 * don't touch the variable "status" beyond this point :-)
2858 for (i -= 1 ; i >= 0; i--) {
2859 if (streams[i] == NULL) {
2863 DEBUG(10, ("Closing stream # %d, %s\n", i,
2864 fsp_str_dbg(streams[i])));
2865 close_file(NULL, streams[i], NORMAL_CLOSE);
2874 * Wrapper around open_file_ntcreate and open_directory
2877 static NTSTATUS create_file_unixpath(connection_struct *conn,
2878 struct smb_request *req,
2879 struct smb_filename *smb_fname,
2880 uint32_t access_mask,
2881 uint32_t share_access,
2882 uint32_t create_disposition,
2883 uint32_t create_options,
2884 uint32_t file_attributes,
2885 uint32_t oplock_request,
2886 uint64_t allocation_size,
2887 struct security_descriptor *sd,
2888 struct ea_list *ea_list,
2890 files_struct **result,
2893 int info = FILE_WAS_OPENED;
2894 files_struct *base_fsp = NULL;
2895 files_struct *fsp = NULL;
2898 DEBUG(10,("create_file_unixpath: access_mask = 0x%x "
2899 "file_attributes = 0x%x, share_access = 0x%x, "
2900 "create_disposition = 0x%x create_options = 0x%x "
2901 "oplock_request = 0x%x ea_list = 0x%p, sd = 0x%p, "
2903 (unsigned int)access_mask,
2904 (unsigned int)file_attributes,
2905 (unsigned int)share_access,
2906 (unsigned int)create_disposition,
2907 (unsigned int)create_options,
2908 (unsigned int)oplock_request,
2909 ea_list, sd, smb_fname_str_dbg(smb_fname)));
2911 if (create_options & FILE_OPEN_BY_FILE_ID) {
2912 status = NT_STATUS_NOT_SUPPORTED;
2916 if (create_options & NTCREATEX_OPTIONS_INVALID_PARAM_MASK) {
2917 status = NT_STATUS_INVALID_PARAMETER;
2922 oplock_request |= INTERNAL_OPEN_ONLY;
2925 if ((conn->fs_capabilities & FILE_NAMED_STREAMS)
2926 && (access_mask & DELETE_ACCESS)
2927 && !is_ntfs_stream_smb_fname(smb_fname)) {
2929 * We can't open a file with DELETE access if any of the
2930 * streams is open without FILE_SHARE_DELETE
2932 status = open_streams_for_delete(conn, smb_fname->base_name);
2934 if (!NT_STATUS_IS_OK(status)) {
2939 /* This is the correct thing to do (check every time) but can_delete
2940 * is expensive (it may have to read the parent directory
2941 * permissions). So for now we're not doing it unless we have a strong
2942 * hint the client is really going to delete this file. If the client
2943 * is forcing FILE_CREATE let the filesystem take care of the
2946 /* Setting FILE_SHARE_DELETE is the hint. */
2948 if (lp_acl_check_permissions(SNUM(conn))
2949 && (create_disposition != FILE_CREATE)
2950 && (access_mask & DELETE_ACCESS)
2951 && (!(can_delete_file_in_directory(conn, smb_fname) ||
2952 can_access_file_acl(conn, smb_fname, DELETE_ACCESS)))) {
2953 status = NT_STATUS_ACCESS_DENIED;
2954 DEBUG(10,("create_file_unixpath: open file %s "
2955 "for delete ACCESS_DENIED\n",
2956 smb_fname_str_dbg(smb_fname)));
2960 if ((access_mask & SEC_FLAG_SYSTEM_SECURITY) &&
2961 !user_has_privileges(current_user.nt_user_token, &se_security)) {
2962 DEBUG(10, ("create_file_unixpath:: open on %s "
2963 "failed - SEC_FLAG_SYSTEM_SECURITY denied.\n",
2964 smb_fname_str_dbg(smb_fname)));
2965 status = NT_STATUS_PRIVILEGE_NOT_HELD;
2969 if ((conn->fs_capabilities & FILE_NAMED_STREAMS)
2970 && is_ntfs_stream_smb_fname(smb_fname)
2971 && (!(create_options & NTCREATEX_OPTIONS_PRIVATE_STREAM_DELETE))) {
2972 uint32 base_create_disposition;
2973 struct smb_filename *smb_fname_base = NULL;
2975 if (create_options & FILE_DIRECTORY_FILE) {
2976 status = NT_STATUS_NOT_A_DIRECTORY;
2980 switch (create_disposition) {
2982 base_create_disposition = FILE_OPEN;
2985 base_create_disposition = FILE_OPEN_IF;
2989 /* Create an smb_filename with stream_name == NULL. */
2990 status = create_synthetic_smb_fname(talloc_tos(),
2991 smb_fname->base_name,
2994 if (!NT_STATUS_IS_OK(status)) {
2998 if (SMB_VFS_STAT(conn, smb_fname_base) == -1) {
2999 DEBUG(10, ("Unable to stat stream: %s\n",
3000 smb_fname_str_dbg(smb_fname_base)));
3003 /* Open the base file. */
3004 status = create_file_unixpath(conn, NULL, smb_fname_base, 0,
3007 | FILE_SHARE_DELETE,
3008 base_create_disposition,
3009 0, 0, 0, 0, NULL, NULL,
3011 TALLOC_FREE(smb_fname_base);
3013 if (!NT_STATUS_IS_OK(status)) {
3014 DEBUG(10, ("create_file_unixpath for base %s failed: "
3015 "%s\n", smb_fname->base_name,
3016 nt_errstr(status)));
3019 /* we don't need to low level fd */
3024 * If it's a request for a directory open, deal with it separately.
3027 if (create_options & FILE_DIRECTORY_FILE) {
3029 if (create_options & FILE_NON_DIRECTORY_FILE) {
3030 status = NT_STATUS_INVALID_PARAMETER;
3034 /* Can't open a temp directory. IFS kit test. */
3035 if (!(file_attributes & FILE_FLAG_POSIX_SEMANTICS) &&
3036 (file_attributes & FILE_ATTRIBUTE_TEMPORARY)) {
3037 status = NT_STATUS_INVALID_PARAMETER;
3042 * We will get a create directory here if the Win32
3043 * app specified a security descriptor in the
3044 * CreateDirectory() call.
3048 status = open_directory(
3049 conn, req, smb_fname, access_mask, share_access,
3050 create_disposition, create_options, file_attributes,
3055 * Ordinary file case.
3058 status = file_new(req, conn, &fsp);
3059 if(!NT_STATUS_IS_OK(status)) {
3063 status = fsp_set_smb_fname(fsp, smb_fname);
3064 if (!NT_STATUS_IS_OK(status)) {
3069 * We're opening the stream element of a base_fsp
3070 * we already opened. Set up the base_fsp pointer.
3073 fsp->base_fsp = base_fsp;
3076 status = open_file_ntcreate(conn,
3087 if(!NT_STATUS_IS_OK(status)) {
3088 file_free(req, fsp);
3092 if (NT_STATUS_EQUAL(status, NT_STATUS_FILE_IS_A_DIRECTORY)) {
3094 /* A stream open never opens a directory */
3097 status = NT_STATUS_FILE_IS_A_DIRECTORY;
3102 * Fail the open if it was explicitly a non-directory
3106 if (create_options & FILE_NON_DIRECTORY_FILE) {
3107 status = NT_STATUS_FILE_IS_A_DIRECTORY;
3112 status = open_directory(
3113 conn, req, smb_fname, access_mask,
3114 share_access, create_disposition,
3115 create_options, file_attributes,
3120 if (!NT_STATUS_IS_OK(status)) {
3124 fsp->base_fsp = base_fsp;
3127 * According to the MS documentation, the only time the security
3128 * descriptor is applied to the opened file is iff we *created* the
3129 * file; an existing file stays the same.
3131 * Also, it seems (from observation) that you can open the file with
3132 * any access mask but you can still write the sd. We need to override
3133 * the granted access before we call set_sd
3134 * Patch for bug #2242 from Tom Lackemann <cessnatomny@yahoo.com>.
3137 if ((sd != NULL) && (info == FILE_WAS_CREATED)
3138 && lp_nt_acl_support(SNUM(conn))) {
3140 uint32_t sec_info_sent;
3141 uint32_t saved_access_mask = fsp->access_mask;
3143 sec_info_sent = get_sec_info(sd);
3145 fsp->access_mask = FILE_GENERIC_ALL;
3147 /* Convert all the generic bits. */
3148 security_acl_map_generic(sd->dacl, &file_generic_mapping);
3149 security_acl_map_generic(sd->sacl, &file_generic_mapping);
3151 if (sec_info_sent & (OWNER_SECURITY_INFORMATION|
3152 GROUP_SECURITY_INFORMATION|
3153 DACL_SECURITY_INFORMATION|
3154 SACL_SECURITY_INFORMATION)) {
3155 status = SMB_VFS_FSET_NT_ACL(fsp, sec_info_sent, sd);
3158 fsp->access_mask = saved_access_mask;
3160 if (!NT_STATUS_IS_OK(status)) {
3165 if ((ea_list != NULL) &&
3166 ((info == FILE_WAS_CREATED) || (info == FILE_WAS_OVERWRITTEN))) {
3167 status = set_ea(conn, fsp, fsp->fsp_name, ea_list);
3168 if (!NT_STATUS_IS_OK(status)) {
3173 if (!fsp->is_directory && S_ISDIR(fsp->fsp_name->st.st_ex_mode)) {
3174 status = NT_STATUS_ACCESS_DENIED;
3178 /* Save the requested allocation size. */
3179 if ((info == FILE_WAS_CREATED) || (info == FILE_WAS_OVERWRITTEN)) {
3181 && (allocation_size > fsp->fsp_name->st.st_ex_size)) {
3182 fsp->initial_allocation_size = smb_roundup(
3183 fsp->conn, allocation_size);
3184 if (fsp->is_directory) {
3185 /* Can't set allocation size on a directory. */
3186 status = NT_STATUS_ACCESS_DENIED;
3189 if (vfs_allocate_file_space(
3190 fsp, fsp->initial_allocation_size) == -1) {
3191 status = NT_STATUS_DISK_FULL;
3195 fsp->initial_allocation_size = smb_roundup(
3196 fsp->conn, (uint64_t)fsp->fsp_name->st.st_ex_size);
3200 DEBUG(10, ("create_file_unixpath: info=%d\n", info));
3203 if (pinfo != NULL) {
3207 smb_fname->st = fsp->fsp_name->st;
3209 return NT_STATUS_OK;
3212 DEBUG(10, ("create_file_unixpath: %s\n", nt_errstr(status)));
3215 if (base_fsp && fsp->base_fsp == base_fsp) {
3217 * The close_file below will close
3222 close_file(req, fsp, ERROR_CLOSE);
3225 if (base_fsp != NULL) {
3226 close_file(req, base_fsp, ERROR_CLOSE);
3233 * Calculate the full path name given a relative fid.
3235 NTSTATUS get_relative_fid_filename(connection_struct *conn,
3236 struct smb_request *req,
3237 uint16_t root_dir_fid,
3238 const struct smb_filename *smb_fname,
3239 struct smb_filename **smb_fname_out)
3241 files_struct *dir_fsp;
3242 char *parent_fname = NULL;
3243 char *new_base_name = NULL;
3246 if (root_dir_fid == 0 || !smb_fname) {
3247 status = NT_STATUS_INTERNAL_ERROR;
3251 dir_fsp = file_fsp(req, root_dir_fid);
3253 if (dir_fsp == NULL) {
3254 status = NT_STATUS_INVALID_HANDLE;
3258 if (is_ntfs_stream_smb_fname(dir_fsp->fsp_name)) {
3259 status = NT_STATUS_INVALID_HANDLE;
3263 if (!dir_fsp->is_directory) {
3266 * Check to see if this is a mac fork of some kind.
3269 if ((conn->fs_capabilities & FILE_NAMED_STREAMS) &&
3270 is_ntfs_stream_smb_fname(smb_fname)) {
3271 status = NT_STATUS_OBJECT_PATH_NOT_FOUND;
3276 we need to handle the case when we get a
3277 relative open relative to a file and the
3278 pathname is blank - this is a reopen!
3279 (hint from demyn plantenberg)
3282 status = NT_STATUS_INVALID_HANDLE;
3286 if (ISDOT(dir_fsp->fsp_name->base_name)) {
3288 * We're at the toplevel dir, the final file name
3289 * must not contain ./, as this is filtered out
3290 * normally by srvstr_get_path and unix_convert
3291 * explicitly rejects paths containing ./.
3293 parent_fname = talloc_strdup(talloc_tos(), "");
3294 if (parent_fname == NULL) {
3295 status = NT_STATUS_NO_MEMORY;
3299 size_t dir_name_len = strlen(dir_fsp->fsp_name->base_name);
3302 * Copy in the base directory name.
3305 parent_fname = TALLOC_ARRAY(talloc_tos(), char,
3307 if (parent_fname == NULL) {
3308 status = NT_STATUS_NO_MEMORY;
3311 memcpy(parent_fname, dir_fsp->fsp_name->base_name,
3315 * Ensure it ends in a '/'.
3316 * We used TALLOC_SIZE +2 to add space for the '/'.
3320 && (parent_fname[dir_name_len-1] != '\\')
3321 && (parent_fname[dir_name_len-1] != '/')) {
3322 parent_fname[dir_name_len] = '/';
3323 parent_fname[dir_name_len+1] = '\0';
3327 new_base_name = talloc_asprintf(talloc_tos(), "%s%s", parent_fname,
3328 smb_fname->base_name);
3329 if (new_base_name == NULL) {
3330 status = NT_STATUS_NO_MEMORY;
3334 status = filename_convert(req,
3336 req->flags2 & FLAGS2_DFS_PATHNAMES,
3341 if (!NT_STATUS_IS_OK(status)) {
3346 TALLOC_FREE(parent_fname);
3350 NTSTATUS create_file_default(connection_struct *conn,
3351 struct smb_request *req,
3352 uint16_t root_dir_fid,
3353 struct smb_filename *smb_fname,
3354 uint32_t access_mask,
3355 uint32_t share_access,
3356 uint32_t create_disposition,
3357 uint32_t create_options,
3358 uint32_t file_attributes,
3359 uint32_t oplock_request,
3360 uint64_t allocation_size,
3361 struct security_descriptor *sd,
3362 struct ea_list *ea_list,
3363 files_struct **result,
3366 int info = FILE_WAS_OPENED;
3367 files_struct *fsp = NULL;
3370 DEBUG(10,("create_file: access_mask = 0x%x "
3371 "file_attributes = 0x%x, share_access = 0x%x, "
3372 "create_disposition = 0x%x create_options = 0x%x "
3373 "oplock_request = 0x%x "
3374 "root_dir_fid = 0x%x, ea_list = 0x%p, sd = 0x%p, "
3376 (unsigned int)access_mask,
3377 (unsigned int)file_attributes,
3378 (unsigned int)share_access,
3379 (unsigned int)create_disposition,
3380 (unsigned int)create_options,
3381 (unsigned int)oplock_request,
3382 (unsigned int)root_dir_fid,
3383 ea_list, sd, smb_fname_str_dbg(smb_fname)));
3386 * Calculate the filename from the root_dir_if if necessary.
3389 if (root_dir_fid != 0) {
3390 struct smb_filename *smb_fname_out = NULL;
3391 status = get_relative_fid_filename(conn, req, root_dir_fid,
3392 smb_fname, &smb_fname_out);
3393 if (!NT_STATUS_IS_OK(status)) {
3396 smb_fname = smb_fname_out;
3400 * Check to see if this is a mac fork of some kind.
3403 if (is_ntfs_stream_smb_fname(smb_fname)) {
3404 enum FAKE_FILE_TYPE fake_file_type;
3406 fake_file_type = is_fake_file(smb_fname);
3408 if (fake_file_type != FAKE_FILE_TYPE_NONE) {
3411 * Here we go! support for changing the disk quotas
3414 * We need to fake up to open this MAGIC QUOTA file
3415 * and return a valid FID.
3417 * w2k close this file directly after openening xp
3418 * also tries a QUERY_FILE_INFO on the file and then
3421 status = open_fake_file(req, conn, req->vuid,
3422 fake_file_type, smb_fname,
3424 if (!NT_STATUS_IS_OK(status)) {
3428 ZERO_STRUCT(smb_fname->st);
3432 if (!(conn->fs_capabilities & FILE_NAMED_STREAMS)) {
3433 status = NT_STATUS_OBJECT_NAME_NOT_FOUND;
3438 /* All file access must go through check_name() */
3440 status = check_name(conn, smb_fname->base_name);
3441 if (!NT_STATUS_IS_OK(status)) {
3445 status = create_file_unixpath(
3446 conn, req, smb_fname, access_mask, share_access,
3447 create_disposition, create_options, file_attributes,
3448 oplock_request, allocation_size, sd, ea_list,
3451 if (!NT_STATUS_IS_OK(status)) {
3456 DEBUG(10, ("create_file: info=%d\n", info));
3459 if (pinfo != NULL) {
3462 return NT_STATUS_OK;
3465 DEBUG(10, ("create_file: %s\n", nt_errstr(status)));
3468 close_file(req, fsp, ERROR_CLOSE);