2 Unix SMB/CIFS implementation.
3 file opening and share modes
4 Copyright (C) Andrew Tridgell 1992-1998
5 Copyright (C) Jeremy Allison 2001-2004
6 Copyright (C) Volker Lendecke 2005
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program. If not, see <http://www.gnu.org/licenses/>.
23 #include "smbd/globals.h"
25 extern const struct generic_mapping file_generic_mapping;
27 struct deferred_open_record {
28 bool delayed_for_oplocks;
32 static NTSTATUS create_file_unixpath(connection_struct *conn,
33 struct smb_request *req,
34 struct smb_filename *smb_fname,
36 uint32_t share_access,
37 uint32_t create_disposition,
38 uint32_t create_options,
39 uint32_t file_attributes,
40 uint32_t oplock_request,
41 uint64_t allocation_size,
42 struct security_descriptor *sd,
43 struct ea_list *ea_list,
45 files_struct **result,
48 /****************************************************************************
49 SMB1 file varient of se_access_check. Never test FILE_READ_ATTRIBUTES.
50 ****************************************************************************/
52 NTSTATUS smb1_file_se_access_check(const struct security_descriptor *sd,
53 const NT_USER_TOKEN *token,
54 uint32_t access_desired,
55 uint32_t *access_granted)
57 return se_access_check(sd,
59 (access_desired & ~FILE_READ_ATTRIBUTES),
63 /****************************************************************************
64 Check if we have open rights.
65 ****************************************************************************/
67 NTSTATUS smbd_check_open_rights(struct connection_struct *conn,
68 const struct smb_filename *smb_fname,
70 uint32_t *access_granted)
72 /* Check if we have rights to open. */
74 struct security_descriptor *sd = NULL;
78 if (conn->server_info->utok.uid == 0 || conn->admin_user) {
79 /* I'm sorry sir, I didn't know you were root... */
80 *access_granted = access_mask;
81 if (access_mask & SEC_FLAG_MAXIMUM_ALLOWED) {
82 *access_granted |= FILE_GENERIC_ALL;
87 status = SMB_VFS_GET_NT_ACL(conn, smb_fname->base_name,
88 (OWNER_SECURITY_INFORMATION |
89 GROUP_SECURITY_INFORMATION |
90 DACL_SECURITY_INFORMATION),&sd);
92 if (!NT_STATUS_IS_OK(status)) {
93 DEBUG(10, ("smbd_check_open_rights: Could not get acl "
95 smb_fname_str_dbg(smb_fname),
100 status = smb1_file_se_access_check(sd,
101 conn->server_info->ptok,
107 DEBUG(10,("smbd_check_open_rights: file %s requesting "
108 "0x%x returning 0x%x (%s)\n",
109 smb_fname_str_dbg(smb_fname),
110 (unsigned int)access_mask,
111 (unsigned int)*access_granted,
112 nt_errstr(status) ));
117 /****************************************************************************
118 fd support routines - attempt to do a dos_open.
119 ****************************************************************************/
121 static NTSTATUS fd_open(struct connection_struct *conn,
126 struct smb_filename *smb_fname = fsp->fsp_name;
127 NTSTATUS status = NT_STATUS_OK;
131 * Never follow symlinks on a POSIX client. The
132 * client should be doing this.
135 if (fsp->posix_open || !lp_symlinks(SNUM(conn))) {
140 fsp->fh->fd = SMB_VFS_OPEN(conn, smb_fname, fsp, flags, mode);
141 if (fsp->fh->fd == -1) {
142 status = map_nt_error_from_unix(errno);
143 if (errno == EMFILE) {
144 static time_t last_warned = 0L;
146 if (time((time_t *) NULL) > last_warned) {
147 DEBUG(0,("Too many open files, unable "
148 "to open more! smbd's max "
150 lp_max_open_files()));
151 last_warned = time((time_t *) NULL);
157 DEBUG(10,("fd_open: name %s, flags = 0%o mode = 0%o, fd = %d. %s\n",
158 smb_fname_str_dbg(smb_fname), flags, (int)mode, fsp->fh->fd,
159 (fsp->fh->fd == -1) ? strerror(errno) : "" ));
164 /****************************************************************************
165 Close the file associated with a fsp.
166 ****************************************************************************/
168 NTSTATUS fd_close(files_struct *fsp)
172 if (fsp->fh->fd == -1) {
173 return NT_STATUS_OK; /* What we used to call a stat open. */
175 if (fsp->fh->ref_count > 1) {
176 return NT_STATUS_OK; /* Shared handle. Only close last reference. */
179 ret = SMB_VFS_CLOSE(fsp);
182 return map_nt_error_from_unix(errno);
187 /****************************************************************************
188 Change the ownership of a file to that of the parent directory.
189 Do this by fd if possible.
190 ****************************************************************************/
192 void change_file_owner_to_parent(connection_struct *conn,
193 const char *inherit_from_dir,
196 struct smb_filename *smb_fname_parent = NULL;
200 status = create_synthetic_smb_fname(talloc_tos(), inherit_from_dir,
201 NULL, NULL, &smb_fname_parent);
202 if (!NT_STATUS_IS_OK(status)) {
206 ret = SMB_VFS_STAT(conn, smb_fname_parent);
208 DEBUG(0,("change_file_owner_to_parent: failed to stat parent "
209 "directory %s. Error was %s\n",
210 smb_fname_str_dbg(smb_fname_parent),
216 ret = SMB_VFS_FCHOWN(fsp, smb_fname_parent->st.st_ex_uid, (gid_t)-1);
219 DEBUG(0,("change_file_owner_to_parent: failed to fchown "
220 "file %s to parent directory uid %u. Error "
221 "was %s\n", fsp_str_dbg(fsp),
222 (unsigned int)smb_fname_parent->st.st_ex_uid,
226 DEBUG(10,("change_file_owner_to_parent: changed new file %s to "
227 "parent directory uid %u.\n", fsp_str_dbg(fsp),
228 (unsigned int)smb_fname_parent->st.st_ex_uid));
230 TALLOC_FREE(smb_fname_parent);
233 NTSTATUS change_dir_owner_to_parent(connection_struct *conn,
234 const char *inherit_from_dir,
236 SMB_STRUCT_STAT *psbuf)
238 struct smb_filename *smb_fname_parent = NULL;
239 struct smb_filename *smb_fname_cwd = NULL;
240 char *saved_dir = NULL;
241 TALLOC_CTX *ctx = talloc_tos();
242 NTSTATUS status = NT_STATUS_OK;
245 status = create_synthetic_smb_fname(ctx, inherit_from_dir, NULL, NULL,
247 if (!NT_STATUS_IS_OK(status)) {
251 ret = SMB_VFS_STAT(conn, smb_fname_parent);
253 status = map_nt_error_from_unix(errno);
254 DEBUG(0,("change_dir_owner_to_parent: failed to stat parent "
255 "directory %s. Error was %s\n",
256 smb_fname_str_dbg(smb_fname_parent),
261 /* We've already done an lstat into psbuf, and we know it's a
262 directory. If we can cd into the directory and the dev/ino
263 are the same then we can safely chown without races as
264 we're locking the directory in place by being in it. This
265 should work on any UNIX (thanks tridge :-). JRA.
268 saved_dir = vfs_GetWd(ctx,conn);
270 status = map_nt_error_from_unix(errno);
271 DEBUG(0,("change_dir_owner_to_parent: failed to get "
272 "current working directory. Error was %s\n",
277 /* Chdir into the new path. */
278 if (vfs_ChDir(conn, fname) == -1) {
279 status = map_nt_error_from_unix(errno);
280 DEBUG(0,("change_dir_owner_to_parent: failed to change "
281 "current working directory to %s. Error "
282 "was %s\n", fname, strerror(errno) ));
286 status = create_synthetic_smb_fname(ctx, ".", NULL, NULL,
288 if (!NT_STATUS_IS_OK(status)) {
292 ret = SMB_VFS_STAT(conn, smb_fname_cwd);
294 status = map_nt_error_from_unix(errno);
295 DEBUG(0,("change_dir_owner_to_parent: failed to stat "
296 "directory '.' (%s) Error was %s\n",
297 fname, strerror(errno)));
301 /* Ensure we're pointing at the same place. */
302 if (smb_fname_cwd->st.st_ex_dev != psbuf->st_ex_dev ||
303 smb_fname_cwd->st.st_ex_ino != psbuf->st_ex_ino ||
304 smb_fname_cwd->st.st_ex_mode != psbuf->st_ex_mode ) {
305 DEBUG(0,("change_dir_owner_to_parent: "
306 "device/inode/mode on directory %s changed. "
307 "Refusing to chown !\n", fname ));
308 status = NT_STATUS_ACCESS_DENIED;
313 ret = SMB_VFS_CHOWN(conn, ".", smb_fname_parent->st.st_ex_uid,
317 status = map_nt_error_from_unix(errno);
318 DEBUG(10,("change_dir_owner_to_parent: failed to chown "
319 "directory %s to parent directory uid %u. "
320 "Error was %s\n", fname,
321 (unsigned int)smb_fname_parent->st.st_ex_uid,
326 DEBUG(10,("change_dir_owner_to_parent: changed ownership of new "
327 "directory %s to parent directory uid %u.\n",
328 fname, (unsigned int)smb_fname_parent->st.st_ex_uid ));
331 vfs_ChDir(conn,saved_dir);
333 TALLOC_FREE(smb_fname_parent);
334 TALLOC_FREE(smb_fname_cwd);
338 /****************************************************************************
340 ****************************************************************************/
342 static NTSTATUS open_file(files_struct *fsp,
343 connection_struct *conn,
344 struct smb_request *req,
345 const char *parent_dir,
348 uint32 access_mask, /* client requested access mask. */
349 uint32 open_access_mask) /* what we're actually using in the open. */
351 struct smb_filename *smb_fname = fsp->fsp_name;
352 NTSTATUS status = NT_STATUS_OK;
353 int accmode = (flags & O_ACCMODE);
354 int local_flags = flags;
355 bool file_existed = VALID_STAT(fsp->fsp_name->st);
360 /* Check permissions */
363 * This code was changed after seeing a client open request
364 * containing the open mode of (DENY_WRITE/read-only) with
365 * the 'create if not exist' bit set. The previous code
366 * would fail to open the file read only on a read-only share
367 * as it was checking the flags parameter directly against O_RDONLY,
368 * this was failing as the flags parameter was set to O_RDONLY|O_CREAT.
372 if (!CAN_WRITE(conn)) {
373 /* It's a read-only share - fail if we wanted to write. */
374 if(accmode != O_RDONLY || (flags & O_TRUNC) || (flags & O_APPEND)) {
375 DEBUG(3,("Permission denied opening %s\n",
376 smb_fname_str_dbg(smb_fname)));
377 return NT_STATUS_ACCESS_DENIED;
378 } else if(flags & O_CREAT) {
379 /* We don't want to write - but we must make sure that
380 O_CREAT doesn't create the file if we have write
381 access into the directory.
383 flags &= ~(O_CREAT|O_EXCL);
384 local_flags &= ~(O_CREAT|O_EXCL);
389 * This little piece of insanity is inspired by the
390 * fact that an NT client can open a file for O_RDONLY,
391 * but set the create disposition to FILE_EXISTS_TRUNCATE.
392 * If the client *can* write to the file, then it expects to
393 * truncate the file, even though it is opening for readonly.
394 * Quicken uses this stupid trick in backup file creation...
395 * Thanks *greatly* to "David W. Chapman Jr." <dwcjr@inethouston.net>
396 * for helping track this one down. It didn't bite us in 2.0.x
397 * as we always opened files read-write in that release. JRA.
400 if ((accmode == O_RDONLY) && ((flags & O_TRUNC) == O_TRUNC)) {
401 DEBUG(10,("open_file: truncate requested on read-only open "
402 "for file %s\n", smb_fname_str_dbg(smb_fname)));
403 local_flags = (flags & ~O_ACCMODE)|O_RDWR;
406 if ((open_access_mask & (FILE_READ_DATA|FILE_WRITE_DATA|FILE_APPEND_DATA|FILE_EXECUTE)) ||
407 (!file_existed && (local_flags & O_CREAT)) ||
408 ((local_flags & O_TRUNC) == O_TRUNC) ) {
412 * We can't actually truncate here as the file may be locked.
413 * open_file_ntcreate will take care of the truncate later. JRA.
416 local_flags &= ~O_TRUNC;
418 #if defined(O_NONBLOCK) && defined(S_ISFIFO)
420 * We would block on opening a FIFO with no one else on the
421 * other end. Do what we used to do and add O_NONBLOCK to the
425 if (file_existed && S_ISFIFO(smb_fname->st.st_ex_mode)) {
426 local_flags |= O_NONBLOCK;
430 /* Don't create files with Microsoft wildcard characters. */
433 * wildcard characters are allowed in stream names
434 * only test the basefilename
436 wild = fsp->base_fsp->fsp_name->base_name;
438 wild = smb_fname->base_name;
440 if ((local_flags & O_CREAT) && !file_existed &&
442 return NT_STATUS_OBJECT_NAME_INVALID;
445 /* Actually do the open */
446 status = fd_open(conn, fsp, local_flags, unx_mode);
447 if (!NT_STATUS_IS_OK(status)) {
448 DEBUG(3,("Error opening file %s (%s) (local_flags=%d) "
449 "(flags=%d)\n", smb_fname_str_dbg(smb_fname),
450 nt_errstr(status),local_flags,flags));
454 if ((local_flags & O_CREAT) && !file_existed) {
456 /* Inherit the ACL if required */
457 if (lp_inherit_perms(SNUM(conn))) {
458 inherit_access_posix_acl(conn, parent_dir,
459 smb_fname->base_name,
463 /* Change the owner if required. */
464 if (lp_inherit_owner(SNUM(conn))) {
465 change_file_owner_to_parent(conn, parent_dir,
469 notify_fname(conn, NOTIFY_ACTION_ADDED,
470 FILE_NOTIFY_CHANGE_FILE_NAME,
471 smb_fname->base_name);
475 fsp->fh->fd = -1; /* What we used to call a stat open. */
477 uint32_t access_granted = 0;
479 status = smbd_check_open_rights(conn,
483 if (!NT_STATUS_IS_OK(status)) {
484 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
486 * On NT_STATUS_ACCESS_DENIED, access_granted
487 * contains the denied bits.
490 if ((access_mask & FILE_WRITE_ATTRIBUTES) &&
491 (access_granted & FILE_WRITE_ATTRIBUTES) &&
492 (lp_map_readonly(SNUM(conn)) ||
493 lp_map_archive(SNUM(conn)) ||
494 lp_map_hidden(SNUM(conn)) ||
495 lp_map_system(SNUM(conn)))) {
496 access_granted &= ~FILE_WRITE_ATTRIBUTES;
498 DEBUG(10,("open_file: "
507 if ((access_mask & DELETE_ACCESS) &&
508 (access_granted & DELETE_ACCESS) &&
509 can_delete_file_in_directory(conn,
511 /* Were we trying to do a stat open
512 * for delete and didn't get DELETE
513 * access (only) ? Check if the
514 * directory allows DELETE_CHILD.
516 * http://blogs.msdn.com/oldnewthing/archive/2004/06/04/148426.aspx
519 access_granted &= ~DELETE_ACCESS;
521 DEBUG(10,("open_file: "
529 if (access_granted != 0) {
530 DEBUG(10,("open_file: Access "
537 } else if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND) &&
539 S_ISLNK(smb_fname->st.st_ex_mode)) {
540 /* This is a POSIX stat open for delete
541 * or rename on a symlink that points
543 DEBUG(10,("open_file: allowing POSIX "
544 "open on bad symlink %s\n",
548 DEBUG(10,("open_file: "
549 "smbd_check_open_rights on file "
551 smb_fname_str_dbg(smb_fname),
552 nt_errstr(status) ));
562 if (fsp->fh->fd == -1) {
563 ret = SMB_VFS_STAT(conn, smb_fname);
565 ret = SMB_VFS_FSTAT(fsp, &smb_fname->st);
566 /* If we have an fd, this stat should succeed. */
568 DEBUG(0,("Error doing fstat on open file %s "
570 smb_fname_str_dbg(smb_fname),
575 /* For a non-io open, this stat failing means file not found. JRA */
577 status = map_nt_error_from_unix(errno);
584 * POSIX allows read-only opens of directories. We don't
585 * want to do this (we use a different code path for this)
586 * so catch a directory open and return an EISDIR. JRA.
589 if(S_ISDIR(smb_fname->st.st_ex_mode)) {
592 return NT_STATUS_FILE_IS_A_DIRECTORY;
595 fsp->mode = smb_fname->st.st_ex_mode;
596 fsp->file_id = vfs_file_id_from_sbuf(conn, &smb_fname->st);
597 fsp->vuid = req ? req->vuid : UID_FIELD_INVALID;
598 fsp->file_pid = req ? req->smbpid : 0;
599 fsp->can_lock = True;
600 fsp->can_read = (access_mask & (FILE_READ_DATA)) ? True : False;
601 if (!CAN_WRITE(conn)) {
602 fsp->can_write = False;
604 fsp->can_write = (access_mask & (FILE_WRITE_DATA | FILE_APPEND_DATA)) ?
607 fsp->print_file = False;
608 fsp->modified = False;
609 fsp->sent_oplock_break = NO_BREAK_SENT;
610 fsp->is_directory = False;
611 if (conn->aio_write_behind_list &&
612 is_in_path(smb_fname->base_name, conn->aio_write_behind_list,
613 conn->case_sensitive)) {
614 fsp->aio_write_behind = True;
617 fsp->wcp = NULL; /* Write cache pointer. */
619 DEBUG(2,("%s opened file %s read=%s write=%s (numopen=%d)\n",
620 conn->server_info->unix_name,
621 smb_fname_str_dbg(smb_fname),
622 BOOLSTR(fsp->can_read), BOOLSTR(fsp->can_write),
623 conn->num_files_open));
629 /*******************************************************************
630 Return True if the filename is one of the special executable types.
631 ********************************************************************/
633 bool is_executable(const char *fname)
635 if ((fname = strrchr_m(fname,'.'))) {
636 if (strequal(fname,".com") ||
637 strequal(fname,".dll") ||
638 strequal(fname,".exe") ||
639 strequal(fname,".sym")) {
646 /****************************************************************************
647 Check if we can open a file with a share mode.
648 Returns True if conflict, False if not.
649 ****************************************************************************/
651 static bool share_conflict(struct share_mode_entry *entry,
655 DEBUG(10,("share_conflict: entry->access_mask = 0x%x, "
656 "entry->share_access = 0x%x, "
657 "entry->private_options = 0x%x\n",
658 (unsigned int)entry->access_mask,
659 (unsigned int)entry->share_access,
660 (unsigned int)entry->private_options));
662 DEBUG(10,("share_conflict: access_mask = 0x%x, share_access = 0x%x\n",
663 (unsigned int)access_mask, (unsigned int)share_access));
665 if ((entry->access_mask & (FILE_WRITE_DATA|
669 DELETE_ACCESS)) == 0) {
670 DEBUG(10,("share_conflict: No conflict due to "
671 "entry->access_mask = 0x%x\n",
672 (unsigned int)entry->access_mask ));
676 if ((access_mask & (FILE_WRITE_DATA|
680 DELETE_ACCESS)) == 0) {
681 DEBUG(10,("share_conflict: No conflict due to "
682 "access_mask = 0x%x\n",
683 (unsigned int)access_mask ));
687 #if 1 /* JRA TEST - Superdebug. */
688 #define CHECK_MASK(num, am, right, sa, share) \
689 DEBUG(10,("share_conflict: [%d] am (0x%x) & right (0x%x) = 0x%x\n", \
690 (unsigned int)(num), (unsigned int)(am), \
691 (unsigned int)(right), (unsigned int)(am)&(right) )); \
692 DEBUG(10,("share_conflict: [%d] sa (0x%x) & share (0x%x) = 0x%x\n", \
693 (unsigned int)(num), (unsigned int)(sa), \
694 (unsigned int)(share), (unsigned int)(sa)&(share) )); \
695 if (((am) & (right)) && !((sa) & (share))) { \
696 DEBUG(10,("share_conflict: check %d conflict am = 0x%x, right = 0x%x, \
697 sa = 0x%x, share = 0x%x\n", (num), (unsigned int)(am), (unsigned int)(right), (unsigned int)(sa), \
698 (unsigned int)(share) )); \
702 #define CHECK_MASK(num, am, right, sa, share) \
703 if (((am) & (right)) && !((sa) & (share))) { \
704 DEBUG(10,("share_conflict: check %d conflict am = 0x%x, right = 0x%x, \
705 sa = 0x%x, share = 0x%x\n", (num), (unsigned int)(am), (unsigned int)(right), (unsigned int)(sa), \
706 (unsigned int)(share) )); \
711 CHECK_MASK(1, entry->access_mask, FILE_WRITE_DATA | FILE_APPEND_DATA,
712 share_access, FILE_SHARE_WRITE);
713 CHECK_MASK(2, access_mask, FILE_WRITE_DATA | FILE_APPEND_DATA,
714 entry->share_access, FILE_SHARE_WRITE);
716 CHECK_MASK(3, entry->access_mask, FILE_READ_DATA | FILE_EXECUTE,
717 share_access, FILE_SHARE_READ);
718 CHECK_MASK(4, access_mask, FILE_READ_DATA | FILE_EXECUTE,
719 entry->share_access, FILE_SHARE_READ);
721 CHECK_MASK(5, entry->access_mask, DELETE_ACCESS,
722 share_access, FILE_SHARE_DELETE);
723 CHECK_MASK(6, access_mask, DELETE_ACCESS,
724 entry->share_access, FILE_SHARE_DELETE);
726 DEBUG(10,("share_conflict: No conflict.\n"));
730 #if defined(DEVELOPER)
731 static void validate_my_share_entries(int num,
732 struct share_mode_entry *share_entry)
736 if (!procid_is_me(&share_entry->pid)) {
740 if (is_deferred_open_entry(share_entry) &&
741 !open_was_deferred(share_entry->op_mid)) {
742 char *str = talloc_asprintf(talloc_tos(),
743 "Got a deferred entry without a request: "
745 share_mode_str(talloc_tos(), num, share_entry));
749 if (!is_valid_share_mode_entry(share_entry)) {
753 fsp = file_find_dif(share_entry->id,
754 share_entry->share_file_id);
756 DEBUG(0,("validate_my_share_entries: PANIC : %s\n",
757 share_mode_str(talloc_tos(), num, share_entry) ));
758 smb_panic("validate_my_share_entries: Cannot match a "
759 "share entry with an open file\n");
762 if (is_deferred_open_entry(share_entry) ||
763 is_unused_share_mode_entry(share_entry)) {
767 if ((share_entry->op_type == NO_OPLOCK) &&
768 (fsp->oplock_type == FAKE_LEVEL_II_OPLOCK)) {
769 /* Someone has already written to it, but I haven't yet
774 if (((uint16)fsp->oplock_type) != share_entry->op_type) {
783 DEBUG(0,("validate_my_share_entries: PANIC : %s\n",
784 share_mode_str(talloc_tos(), num, share_entry) ));
785 str = talloc_asprintf(talloc_tos(),
786 "validate_my_share_entries: "
787 "file %s, oplock_type = 0x%x, op_type = 0x%x\n",
788 fsp->fsp_name->base_name,
789 (unsigned int)fsp->oplock_type,
790 (unsigned int)share_entry->op_type );
796 bool is_stat_open(uint32 access_mask)
798 return (access_mask &&
799 ((access_mask & ~(SYNCHRONIZE_ACCESS| FILE_READ_ATTRIBUTES|
800 FILE_WRITE_ATTRIBUTES))==0) &&
801 ((access_mask & (SYNCHRONIZE_ACCESS|FILE_READ_ATTRIBUTES|
802 FILE_WRITE_ATTRIBUTES)) != 0));
805 /****************************************************************************
806 Deal with share modes
807 Invarient: Share mode must be locked on entry and exit.
808 Returns -1 on error, or number of share modes on success (may be zero).
809 ****************************************************************************/
811 static NTSTATUS open_mode_check(connection_struct *conn,
812 struct share_mode_lock *lck,
815 uint32 create_options,
820 if(lck->num_share_modes == 0) {
824 *file_existed = True;
826 /* A delete on close prohibits everything */
828 if (lck->delete_on_close) {
829 return NT_STATUS_DELETE_PENDING;
832 if (is_stat_open(access_mask)) {
833 /* Stat open that doesn't trigger oplock breaks or share mode
834 * checks... ! JRA. */
839 * Check if the share modes will give us access.
842 #if defined(DEVELOPER)
843 for(i = 0; i < lck->num_share_modes; i++) {
844 validate_my_share_entries(i, &lck->share_modes[i]);
848 if (!lp_share_modes(SNUM(conn))) {
852 /* Now we check the share modes, after any oplock breaks. */
853 for(i = 0; i < lck->num_share_modes; i++) {
855 if (!is_valid_share_mode_entry(&lck->share_modes[i])) {
859 /* someone else has a share lock on it, check to see if we can
861 if (share_conflict(&lck->share_modes[i],
862 access_mask, share_access)) {
863 return NT_STATUS_SHARING_VIOLATION;
870 static bool is_delete_request(files_struct *fsp) {
871 return ((fsp->access_mask == DELETE_ACCESS) &&
872 (fsp->oplock_type == NO_OPLOCK));
876 * Send a break message to the oplock holder and delay the open for
880 static NTSTATUS send_break_message(files_struct *fsp,
881 struct share_mode_entry *exclusive,
886 char msg[MSG_SMB_SHARE_MODE_ENTRY_SIZE];
888 DEBUG(10, ("Sending break request to PID %s\n",
889 procid_str_static(&exclusive->pid)));
890 exclusive->op_mid = mid;
892 /* Create the message. */
893 share_mode_entry_to_message(msg, exclusive);
895 /* Add in the FORCE_OPLOCK_BREAK_TO_NONE bit in the message if set. We
896 don't want this set in the share mode struct pointed to by lck. */
898 if (oplock_request & FORCE_OPLOCK_BREAK_TO_NONE) {
899 SSVAL(msg,6,exclusive->op_type | FORCE_OPLOCK_BREAK_TO_NONE);
902 status = messaging_send_buf(smbd_messaging_context(), exclusive->pid,
903 MSG_SMB_BREAK_REQUEST,
905 MSG_SMB_SHARE_MODE_ENTRY_SIZE);
906 if (!NT_STATUS_IS_OK(status)) {
907 DEBUG(3, ("Could not send oplock break message: %s\n",
915 * 1) No files open at all or internal open: Grant whatever the client wants.
917 * 2) Exclusive (or batch) oplock around: If the requested access is a delete
918 * request, break if the oplock around is a batch oplock. If it's another
919 * requested access type, break.
921 * 3) Only level2 around: Grant level2 and do nothing else.
924 static bool delay_for_oplocks(struct share_mode_lock *lck,
931 struct share_mode_entry *exclusive = NULL;
932 bool valid_entry = false;
933 bool have_level2 = false;
934 bool have_a_none_oplock = false;
935 bool allow_level2 = (global_client_caps & CAP_LEVEL_II_OPLOCKS) &&
936 lp_level2_oplocks(SNUM(fsp->conn));
938 if (oplock_request & INTERNAL_OPEN_ONLY) {
939 fsp->oplock_type = NO_OPLOCK;
942 if ((oplock_request & INTERNAL_OPEN_ONLY) || is_stat_open(fsp->access_mask)) {
946 for (i=0; i<lck->num_share_modes; i++) {
948 if (!is_valid_share_mode_entry(&lck->share_modes[i])) {
952 /* At least one entry is not an invalid or deferred entry. */
955 if (pass_number == 1) {
956 if (BATCH_OPLOCK_TYPE(lck->share_modes[i].op_type)) {
957 SMB_ASSERT(exclusive == NULL);
958 exclusive = &lck->share_modes[i];
961 if (EXCLUSIVE_OPLOCK_TYPE(lck->share_modes[i].op_type)) {
962 SMB_ASSERT(exclusive == NULL);
963 exclusive = &lck->share_modes[i];
967 if (LEVEL_II_OPLOCK_TYPE(lck->share_modes[i].op_type)) {
968 SMB_ASSERT(exclusive == NULL);
972 if (lck->share_modes[i].op_type == NO_OPLOCK) {
973 have_a_none_oplock = true;
977 if (exclusive != NULL) { /* Found an exclusive oplock */
978 bool delay_it = is_delete_request(fsp) ?
979 BATCH_OPLOCK_TYPE(exclusive->op_type) : true;
980 SMB_ASSERT(!have_level2);
982 send_break_message(fsp, exclusive, mid, oplock_request);
988 * Match what was requested (fsp->oplock_type) with
989 * what was found in the existing share modes.
993 /* All entries are placeholders or deferred.
994 * Directly grant whatever the client wants. */
995 if (fsp->oplock_type == NO_OPLOCK) {
996 /* Store a level2 oplock, but don't tell the client */
997 fsp->oplock_type = FAKE_LEVEL_II_OPLOCK;
999 } else if (have_a_none_oplock) {
1000 fsp->oplock_type = NO_OPLOCK;
1001 } else if (have_level2) {
1002 if (fsp->oplock_type == NO_OPLOCK ||
1003 fsp->oplock_type == FAKE_LEVEL_II_OPLOCK) {
1004 /* Store a level2 oplock, but don't tell the client */
1005 fsp->oplock_type = FAKE_LEVEL_II_OPLOCK;
1007 fsp->oplock_type = LEVEL_II_OPLOCK;
1010 /* This case can never happen. */
1015 * Don't grant level2 to clients that don't want them
1016 * or if we've turned them off.
1018 if (fsp->oplock_type == LEVEL_II_OPLOCK && !allow_level2) {
1019 fsp->oplock_type = FAKE_LEVEL_II_OPLOCK;
1022 DEBUG(10,("delay_for_oplocks: oplock type 0x%x on file %s\n",
1023 fsp->oplock_type, fsp_str_dbg(fsp)));
1029 bool request_timed_out(struct timeval request_time,
1030 struct timeval timeout)
1032 struct timeval now, end_time;
1034 end_time = timeval_sum(&request_time, &timeout);
1035 return (timeval_compare(&end_time, &now) < 0);
1038 /****************************************************************************
1039 Handle the 1 second delay in returning a SHARING_VIOLATION error.
1040 ****************************************************************************/
1042 static void defer_open(struct share_mode_lock *lck,
1043 struct timeval request_time,
1044 struct timeval timeout,
1045 struct smb_request *req,
1046 struct deferred_open_record *state)
1050 /* Paranoia check */
1052 for (i=0; i<lck->num_share_modes; i++) {
1053 struct share_mode_entry *e = &lck->share_modes[i];
1055 if (!is_deferred_open_entry(e)) {
1059 if (procid_is_me(&e->pid) && (e->op_mid == req->mid)) {
1060 DEBUG(0, ("Trying to defer an already deferred "
1061 "request: mid=%d, exiting\n", req->mid));
1062 exit_server("attempt to defer a deferred request");
1066 /* End paranoia check */
1068 DEBUG(10,("defer_open_sharing_error: time [%u.%06u] adding deferred "
1069 "open entry for mid %u\n",
1070 (unsigned int)request_time.tv_sec,
1071 (unsigned int)request_time.tv_usec,
1072 (unsigned int)req->mid));
1074 if (!push_deferred_smb_message(req, request_time, timeout,
1075 (char *)state, sizeof(*state))) {
1076 exit_server("push_deferred_smb_message failed");
1078 add_deferred_open(lck, req->mid, request_time, state->id);
1082 /****************************************************************************
1083 On overwrite open ensure that the attributes match.
1084 ****************************************************************************/
1086 bool open_match_attributes(connection_struct *conn,
1087 uint32 old_dos_attr,
1088 uint32 new_dos_attr,
1089 mode_t existing_unx_mode,
1090 mode_t new_unx_mode,
1091 mode_t *returned_unx_mode)
1093 uint32 noarch_old_dos_attr, noarch_new_dos_attr;
1095 noarch_old_dos_attr = (old_dos_attr & ~FILE_ATTRIBUTE_ARCHIVE);
1096 noarch_new_dos_attr = (new_dos_attr & ~FILE_ATTRIBUTE_ARCHIVE);
1098 if((noarch_old_dos_attr == 0 && noarch_new_dos_attr != 0) ||
1099 (noarch_old_dos_attr != 0 && ((noarch_old_dos_attr & noarch_new_dos_attr) == noarch_old_dos_attr))) {
1100 *returned_unx_mode = new_unx_mode;
1102 *returned_unx_mode = (mode_t)0;
1105 DEBUG(10,("open_match_attributes: old_dos_attr = 0x%x, "
1106 "existing_unx_mode = 0%o, new_dos_attr = 0x%x "
1107 "returned_unx_mode = 0%o\n",
1108 (unsigned int)old_dos_attr,
1109 (unsigned int)existing_unx_mode,
1110 (unsigned int)new_dos_attr,
1111 (unsigned int)*returned_unx_mode ));
1113 /* If we're mapping SYSTEM and HIDDEN ensure they match. */
1114 if (lp_map_system(SNUM(conn)) || lp_store_dos_attributes(SNUM(conn))) {
1115 if ((old_dos_attr & FILE_ATTRIBUTE_SYSTEM) &&
1116 !(new_dos_attr & FILE_ATTRIBUTE_SYSTEM)) {
1120 if (lp_map_hidden(SNUM(conn)) || lp_store_dos_attributes(SNUM(conn))) {
1121 if ((old_dos_attr & FILE_ATTRIBUTE_HIDDEN) &&
1122 !(new_dos_attr & FILE_ATTRIBUTE_HIDDEN)) {
1129 /****************************************************************************
1130 Special FCB or DOS processing in the case of a sharing violation.
1131 Try and find a duplicated file handle.
1132 ****************************************************************************/
1134 NTSTATUS fcb_or_dos_open(struct smb_request *req,
1135 connection_struct *conn,
1136 files_struct *fsp_to_dup_into,
1137 const struct smb_filename *smb_fname,
1142 uint32 share_access,
1143 uint32 create_options)
1147 DEBUG(5,("fcb_or_dos_open: attempting old open semantics for "
1148 "file %s.\n", smb_fname_str_dbg(smb_fname)));
1150 for(fsp = file_find_di_first(id); fsp;
1151 fsp = file_find_di_next(fsp)) {
1153 DEBUG(10,("fcb_or_dos_open: checking file %s, fd = %d, "
1154 "vuid = %u, file_pid = %u, private_options = 0x%x "
1155 "access_mask = 0x%x\n", fsp_str_dbg(fsp),
1156 fsp->fh->fd, (unsigned int)fsp->vuid,
1157 (unsigned int)fsp->file_pid,
1158 (unsigned int)fsp->fh->private_options,
1159 (unsigned int)fsp->access_mask ));
1161 if (fsp->fh->fd != -1 &&
1162 fsp->vuid == vuid &&
1163 fsp->file_pid == file_pid &&
1164 (fsp->fh->private_options & (NTCREATEX_OPTIONS_PRIVATE_DENY_DOS |
1165 NTCREATEX_OPTIONS_PRIVATE_DENY_FCB)) &&
1166 (fsp->access_mask & FILE_WRITE_DATA) &&
1167 strequal(fsp->fsp_name->base_name, smb_fname->base_name) &&
1168 strequal(fsp->fsp_name->stream_name,
1169 smb_fname->stream_name)) {
1170 DEBUG(10,("fcb_or_dos_open: file match\n"));
1176 return NT_STATUS_NOT_FOUND;
1179 /* quite an insane set of semantics ... */
1180 if (is_executable(smb_fname->base_name) &&
1181 (fsp->fh->private_options & NTCREATEX_OPTIONS_PRIVATE_DENY_DOS)) {
1182 DEBUG(10,("fcb_or_dos_open: file fail due to is_executable.\n"));
1183 return NT_STATUS_INVALID_PARAMETER;
1186 /* We need to duplicate this fsp. */
1187 return dup_file_fsp(req, fsp, access_mask, share_access,
1188 create_options, fsp_to_dup_into);
1191 /****************************************************************************
1192 Open a file with a share mode - old openX method - map into NTCreate.
1193 ****************************************************************************/
1195 bool map_open_params_to_ntcreate(const struct smb_filename *smb_fname,
1196 int deny_mode, int open_func,
1197 uint32 *paccess_mask,
1198 uint32 *pshare_mode,
1199 uint32 *pcreate_disposition,
1200 uint32 *pcreate_options)
1204 uint32 create_disposition;
1205 uint32 create_options = FILE_NON_DIRECTORY_FILE;
1207 DEBUG(10,("map_open_params_to_ntcreate: fname = %s, deny_mode = 0x%x, "
1208 "open_func = 0x%x\n",
1209 smb_fname_str_dbg(smb_fname), (unsigned int)deny_mode,
1210 (unsigned int)open_func ));
1212 /* Create the NT compatible access_mask. */
1213 switch (GET_OPENX_MODE(deny_mode)) {
1214 case DOS_OPEN_EXEC: /* Implies read-only - used to be FILE_READ_DATA */
1215 case DOS_OPEN_RDONLY:
1216 access_mask = FILE_GENERIC_READ;
1218 case DOS_OPEN_WRONLY:
1219 access_mask = FILE_GENERIC_WRITE;
1223 access_mask = FILE_GENERIC_READ|FILE_GENERIC_WRITE;
1226 DEBUG(10,("map_open_params_to_ntcreate: bad open mode = 0x%x\n",
1227 (unsigned int)GET_OPENX_MODE(deny_mode)));
1231 /* Create the NT compatible create_disposition. */
1232 switch (open_func) {
1233 case OPENX_FILE_EXISTS_FAIL|OPENX_FILE_CREATE_IF_NOT_EXIST:
1234 create_disposition = FILE_CREATE;
1237 case OPENX_FILE_EXISTS_OPEN:
1238 create_disposition = FILE_OPEN;
1241 case OPENX_FILE_EXISTS_OPEN|OPENX_FILE_CREATE_IF_NOT_EXIST:
1242 create_disposition = FILE_OPEN_IF;
1245 case OPENX_FILE_EXISTS_TRUNCATE:
1246 create_disposition = FILE_OVERWRITE;
1249 case OPENX_FILE_EXISTS_TRUNCATE|OPENX_FILE_CREATE_IF_NOT_EXIST:
1250 create_disposition = FILE_OVERWRITE_IF;
1254 /* From samba4 - to be confirmed. */
1255 if (GET_OPENX_MODE(deny_mode) == DOS_OPEN_EXEC) {
1256 create_disposition = FILE_CREATE;
1259 DEBUG(10,("map_open_params_to_ntcreate: bad "
1260 "open_func 0x%x\n", (unsigned int)open_func));
1264 /* Create the NT compatible share modes. */
1265 switch (GET_DENY_MODE(deny_mode)) {
1267 share_mode = FILE_SHARE_NONE;
1271 share_mode = FILE_SHARE_READ;
1275 share_mode = FILE_SHARE_WRITE;
1279 share_mode = FILE_SHARE_READ|FILE_SHARE_WRITE;
1283 create_options |= NTCREATEX_OPTIONS_PRIVATE_DENY_DOS;
1284 if (is_executable(smb_fname->base_name)) {
1285 share_mode = FILE_SHARE_READ|FILE_SHARE_WRITE;
1287 if (GET_OPENX_MODE(deny_mode) == DOS_OPEN_RDONLY) {
1288 share_mode = FILE_SHARE_READ;
1290 share_mode = FILE_SHARE_NONE;
1296 create_options |= NTCREATEX_OPTIONS_PRIVATE_DENY_FCB;
1297 share_mode = FILE_SHARE_NONE;
1301 DEBUG(10,("map_open_params_to_ntcreate: bad deny_mode 0x%x\n",
1302 (unsigned int)GET_DENY_MODE(deny_mode) ));
1306 DEBUG(10,("map_open_params_to_ntcreate: file %s, access_mask = 0x%x, "
1307 "share_mode = 0x%x, create_disposition = 0x%x, "
1308 "create_options = 0x%x\n",
1309 smb_fname_str_dbg(smb_fname),
1310 (unsigned int)access_mask,
1311 (unsigned int)share_mode,
1312 (unsigned int)create_disposition,
1313 (unsigned int)create_options ));
1316 *paccess_mask = access_mask;
1319 *pshare_mode = share_mode;
1321 if (pcreate_disposition) {
1322 *pcreate_disposition = create_disposition;
1324 if (pcreate_options) {
1325 *pcreate_options = create_options;
1332 static void schedule_defer_open(struct share_mode_lock *lck,
1333 struct timeval request_time,
1334 struct smb_request *req)
1336 struct deferred_open_record state;
1338 /* This is a relative time, added to the absolute
1339 request_time value to get the absolute timeout time.
1340 Note that if this is the second or greater time we enter
1341 this codepath for this particular request mid then
1342 request_time is left as the absolute time of the *first*
1343 time this request mid was processed. This is what allows
1344 the request to eventually time out. */
1346 struct timeval timeout;
1348 /* Normally the smbd we asked should respond within
1349 * OPLOCK_BREAK_TIMEOUT seconds regardless of whether
1350 * the client did, give twice the timeout as a safety
1351 * measure here in case the other smbd is stuck
1352 * somewhere else. */
1354 timeout = timeval_set(OPLOCK_BREAK_TIMEOUT*2, 0);
1356 /* Nothing actually uses state.delayed_for_oplocks
1357 but it's handy to differentiate in debug messages
1358 between a 30 second delay due to oplock break, and
1359 a 1 second delay for share mode conflicts. */
1361 state.delayed_for_oplocks = True;
1364 if (!request_timed_out(request_time, timeout)) {
1365 defer_open(lck, request_time, timeout, req, &state);
1369 /****************************************************************************
1370 Work out what access_mask to use from what the client sent us.
1371 ****************************************************************************/
1373 static NTSTATUS calculate_access_mask(connection_struct *conn,
1374 const struct smb_filename *smb_fname,
1376 uint32_t access_mask,
1377 uint32_t *access_mask_out)
1382 * Convert GENERIC bits to specific bits.
1385 se_map_generic(&access_mask, &file_generic_mapping);
1387 /* Calculate MAXIMUM_ALLOWED_ACCESS if requested. */
1388 if (access_mask & MAXIMUM_ALLOWED_ACCESS) {
1391 struct security_descriptor *sd;
1392 uint32_t access_granted = 0;
1394 status = SMB_VFS_GET_NT_ACL(conn, smb_fname->base_name,
1395 (OWNER_SECURITY_INFORMATION |
1396 GROUP_SECURITY_INFORMATION |
1397 DACL_SECURITY_INFORMATION),&sd);
1399 if (!NT_STATUS_IS_OK(status)) {
1400 DEBUG(10, ("calculate_access_mask: Could not get acl "
1402 smb_fname_str_dbg(smb_fname),
1403 nt_errstr(status)));
1404 return NT_STATUS_ACCESS_DENIED;
1407 status = smb1_file_se_access_check(sd,
1408 conn->server_info->ptok,
1414 if (!NT_STATUS_IS_OK(status)) {
1415 DEBUG(10, ("calculate_access_mask: Access denied on "
1416 "file %s: when calculating maximum access\n",
1417 smb_fname_str_dbg(smb_fname)));
1418 return NT_STATUS_ACCESS_DENIED;
1421 access_mask = access_granted;
1423 access_mask = FILE_GENERIC_ALL;
1427 *access_mask_out = access_mask;
1428 return NT_STATUS_OK;
1431 /****************************************************************************
1432 Open a file with a share mode. Passed in an already created files_struct *.
1433 ****************************************************************************/
1435 static NTSTATUS open_file_ntcreate(connection_struct *conn,
1436 struct smb_request *req,
1437 uint32 access_mask, /* access bits (FILE_READ_DATA etc.) */
1438 uint32 share_access, /* share constants (FILE_SHARE_READ etc) */
1439 uint32 create_disposition, /* FILE_OPEN_IF etc. */
1440 uint32 create_options, /* options such as delete on close. */
1441 uint32 new_dos_attributes, /* attributes used for new file. */
1442 int oplock_request, /* internal Samba oplock codes. */
1443 /* Information (FILE_EXISTS etc.) */
1447 struct smb_filename *smb_fname = fsp->fsp_name;
1450 bool file_existed = VALID_STAT(smb_fname->st);
1451 bool def_acl = False;
1452 bool posix_open = False;
1453 bool new_file_created = False;
1454 bool clear_ads = false;
1456 NTSTATUS fsp_open = NT_STATUS_ACCESS_DENIED;
1457 mode_t new_unx_mode = (mode_t)0;
1458 mode_t unx_mode = (mode_t)0;
1460 uint32 existing_dos_attributes = 0;
1461 struct pending_message_list *pml = NULL;
1462 struct timeval request_time = timeval_zero();
1463 struct share_mode_lock *lck = NULL;
1464 uint32 open_access_mask = access_mask;
1470 if (conn->printer) {
1472 * Printers are handled completely differently.
1473 * Most of the passed parameters are ignored.
1477 *pinfo = FILE_WAS_CREATED;
1480 DEBUG(10, ("open_file_ntcreate: printer open fname=%s\n",
1481 smb_fname_str_dbg(smb_fname)));
1484 DEBUG(0,("open_file_ntcreate: printer open without "
1485 "an SMB request!\n"));
1486 return NT_STATUS_INTERNAL_ERROR;
1489 return print_fsp_open(req, conn, smb_fname->base_name,
1493 if (!parent_dirname(talloc_tos(), smb_fname->base_name, &parent_dir,
1495 return NT_STATUS_NO_MEMORY;
1498 if (new_dos_attributes & FILE_FLAG_POSIX_SEMANTICS) {
1500 unx_mode = (mode_t)(new_dos_attributes & ~FILE_FLAG_POSIX_SEMANTICS);
1501 new_dos_attributes = 0;
1503 /* We add aARCH to this as this mode is only used if the file is
1505 unx_mode = unix_mode(conn, new_dos_attributes | aARCH,
1506 smb_fname, parent_dir);
1509 DEBUG(10, ("open_file_ntcreate: fname=%s, dos_attrs=0x%x "
1510 "access_mask=0x%x share_access=0x%x "
1511 "create_disposition = 0x%x create_options=0x%x "
1512 "unix mode=0%o oplock_request=%d\n",
1513 smb_fname_str_dbg(smb_fname), new_dos_attributes,
1514 access_mask, share_access, create_disposition,
1515 create_options, (unsigned int)unx_mode, oplock_request));
1517 if ((req == NULL) && ((oplock_request & INTERNAL_OPEN_ONLY) == 0)) {
1518 DEBUG(0, ("No smb request but not an internal only open!\n"));
1519 return NT_STATUS_INTERNAL_ERROR;
1523 * Only non-internal opens can be deferred at all
1527 && ((pml = get_open_deferred_message(req->mid)) != NULL)) {
1528 struct deferred_open_record *state =
1529 (struct deferred_open_record *)pml->private_data.data;
1531 /* Remember the absolute time of the original
1532 request with this mid. We'll use it later to
1533 see if this has timed out. */
1535 request_time = pml->request_time;
1537 /* Remove the deferred open entry under lock. */
1538 lck = get_share_mode_lock(talloc_tos(), state->id, NULL, NULL,
1541 DEBUG(0, ("could not get share mode lock\n"));
1543 del_deferred_open_entry(lck, req->mid);
1547 /* Ensure we don't reprocess this message. */
1548 remove_deferred_open_smb_message(req->mid);
1551 status = check_name(conn, smb_fname->base_name);
1552 if (!NT_STATUS_IS_OK(status)) {
1557 new_dos_attributes &= SAMBA_ATTRIBUTES_MASK;
1559 existing_dos_attributes = dos_mode(conn, smb_fname);
1563 /* ignore any oplock requests if oplocks are disabled */
1564 if (!lp_oplocks(SNUM(conn)) || global_client_failed_oplock_break ||
1565 IS_VETO_OPLOCK_PATH(conn, smb_fname->base_name)) {
1566 /* Mask off everything except the private Samba bits. */
1567 oplock_request &= SAMBA_PRIVATE_OPLOCK_MASK;
1570 /* this is for OS/2 long file names - say we don't support them */
1571 if (!lp_posix_pathnames() && strstr(smb_fname->base_name,".+,;=[].")) {
1572 /* OS/2 Workplace shell fix may be main code stream in a later
1574 DEBUG(5,("open_file_ntcreate: OS/2 long filenames are not "
1576 if (use_nt_status()) {
1577 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1579 return NT_STATUS_DOS(ERRDOS, ERRcannotopen);
1582 switch( create_disposition ) {
1584 * Currently we're using FILE_SUPERSEDE as the same as
1585 * FILE_OVERWRITE_IF but they really are
1586 * different. FILE_SUPERSEDE deletes an existing file
1587 * (requiring delete access) then recreates it.
1589 case FILE_SUPERSEDE:
1590 /* If file exists replace/overwrite. If file doesn't
1592 flags2 |= (O_CREAT | O_TRUNC);
1596 case FILE_OVERWRITE_IF:
1597 /* If file exists replace/overwrite. If file doesn't
1599 flags2 |= (O_CREAT | O_TRUNC);
1604 /* If file exists open. If file doesn't exist error. */
1605 if (!file_existed) {
1606 DEBUG(5,("open_file_ntcreate: FILE_OPEN "
1607 "requested for file %s and file "
1609 smb_fname_str_dbg(smb_fname)));
1611 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1615 case FILE_OVERWRITE:
1616 /* If file exists overwrite. If file doesn't exist
1618 if (!file_existed) {
1619 DEBUG(5,("open_file_ntcreate: FILE_OVERWRITE "
1620 "requested for file %s and file "
1622 smb_fname_str_dbg(smb_fname) ));
1624 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1631 /* If file exists error. If file doesn't exist
1634 DEBUG(5,("open_file_ntcreate: FILE_CREATE "
1635 "requested for file %s and file "
1636 "already exists.\n",
1637 smb_fname_str_dbg(smb_fname)));
1638 if (S_ISDIR(smb_fname->st.st_ex_mode)) {
1643 return map_nt_error_from_unix(errno);
1645 flags2 |= (O_CREAT|O_EXCL);
1649 /* If file exists open. If file doesn't exist
1655 return NT_STATUS_INVALID_PARAMETER;
1658 /* We only care about matching attributes on file exists and
1661 if (!posix_open && file_existed && ((create_disposition == FILE_OVERWRITE) ||
1662 (create_disposition == FILE_OVERWRITE_IF))) {
1663 if (!open_match_attributes(conn, existing_dos_attributes,
1665 smb_fname->st.st_ex_mode,
1666 unx_mode, &new_unx_mode)) {
1667 DEBUG(5,("open_file_ntcreate: attributes missmatch "
1668 "for file %s (%x %x) (0%o, 0%o)\n",
1669 smb_fname_str_dbg(smb_fname),
1670 existing_dos_attributes,
1672 (unsigned int)smb_fname->st.st_ex_mode,
1673 (unsigned int)unx_mode ));
1675 return NT_STATUS_ACCESS_DENIED;
1679 status = calculate_access_mask(conn, smb_fname, file_existed,
1682 if (!NT_STATUS_IS_OK(status)) {
1683 DEBUG(10, ("open_file_ntcreate: calculate_access_mask "
1684 "on file %s returned %s\n",
1685 smb_fname_str_dbg(smb_fname), nt_errstr(status)));
1689 open_access_mask = access_mask;
1691 if ((flags2 & O_TRUNC) || (oplock_request & FORCE_OPLOCK_BREAK_TO_NONE)) {
1692 open_access_mask |= FILE_WRITE_DATA; /* This will cause oplock breaks. */
1695 DEBUG(10, ("open_file_ntcreate: fname=%s, after mapping "
1696 "access_mask=0x%x\n", smb_fname_str_dbg(smb_fname),
1700 * Note that we ignore the append flag as append does not
1701 * mean the same thing under DOS and Unix.
1704 if ((access_mask & (FILE_WRITE_DATA | FILE_APPEND_DATA)) ||
1705 (oplock_request & FORCE_OPLOCK_BREAK_TO_NONE)) {
1706 /* DENY_DOS opens are always underlying read-write on the
1707 file handle, no matter what the requested access mask
1709 if ((create_options & NTCREATEX_OPTIONS_PRIVATE_DENY_DOS) ||
1710 access_mask & (FILE_READ_ATTRIBUTES|FILE_READ_DATA|FILE_READ_EA|FILE_EXECUTE)) {
1720 * Currently we only look at FILE_WRITE_THROUGH for create options.
1724 if ((create_options & FILE_WRITE_THROUGH) && lp_strict_sync(SNUM(conn))) {
1729 if (posix_open && (access_mask & FILE_APPEND_DATA)) {
1733 if (!posix_open && !CAN_WRITE(conn)) {
1735 * We should really return a permission denied error if either
1736 * O_CREAT or O_TRUNC are set, but for compatibility with
1737 * older versions of Samba we just AND them out.
1739 flags2 &= ~(O_CREAT|O_TRUNC);
1743 * Ensure we can't write on a read-only share or file.
1746 if (flags != O_RDONLY && file_existed &&
1747 (!CAN_WRITE(conn) || IS_DOS_READONLY(existing_dos_attributes))) {
1748 DEBUG(5,("open_file_ntcreate: write access requested for "
1749 "file %s on read only %s\n",
1750 smb_fname_str_dbg(smb_fname),
1751 !CAN_WRITE(conn) ? "share" : "file" ));
1753 return NT_STATUS_ACCESS_DENIED;
1756 fsp->file_id = vfs_file_id_from_sbuf(conn, &smb_fname->st);
1757 fsp->share_access = share_access;
1758 fsp->fh->private_options = create_options;
1759 fsp->access_mask = open_access_mask; /* We change this to the
1760 * requested access_mask after
1761 * the open is done. */
1762 fsp->posix_open = posix_open;
1764 /* Ensure no SAMBA_PRIVATE bits can be set. */
1765 fsp->oplock_type = (oplock_request & ~SAMBA_PRIVATE_OPLOCK_MASK);
1767 if (timeval_is_zero(&request_time)) {
1768 request_time = fsp->open_time;
1772 struct timespec old_write_time = smb_fname->st.st_ex_mtime;
1773 id = vfs_file_id_from_sbuf(conn, &smb_fname->st);
1775 lck = get_share_mode_lock(talloc_tos(), id,
1777 smb_fname, &old_write_time);
1780 DEBUG(0, ("Could not get share mode lock\n"));
1781 return NT_STATUS_SHARING_VIOLATION;
1784 /* First pass - send break only on batch oplocks. */
1786 && delay_for_oplocks(lck, fsp, req->mid, 1,
1788 schedule_defer_open(lck, request_time, req);
1790 return NT_STATUS_SHARING_VIOLATION;
1793 /* Use the client requested access mask here, not the one we
1795 status = open_mode_check(conn, lck, access_mask, share_access,
1796 create_options, &file_existed);
1798 if (NT_STATUS_IS_OK(status)) {
1799 /* We might be going to allow this open. Check oplock
1801 /* Second pass - send break for both batch or
1802 * exclusive oplocks. */
1804 && delay_for_oplocks(lck, fsp, req->mid, 2,
1806 schedule_defer_open(lck, request_time, req);
1808 return NT_STATUS_SHARING_VIOLATION;
1812 if (NT_STATUS_EQUAL(status, NT_STATUS_DELETE_PENDING)) {
1813 /* DELETE_PENDING is not deferred for a second */
1818 if (!NT_STATUS_IS_OK(status)) {
1819 uint32 can_access_mask;
1820 bool can_access = True;
1822 SMB_ASSERT(NT_STATUS_EQUAL(status, NT_STATUS_SHARING_VIOLATION));
1824 /* Check if this can be done with the deny_dos and fcb
1826 if (create_options &
1827 (NTCREATEX_OPTIONS_PRIVATE_DENY_DOS|
1828 NTCREATEX_OPTIONS_PRIVATE_DENY_FCB)) {
1830 DEBUG(0, ("DOS open without an SMB "
1833 return NT_STATUS_INTERNAL_ERROR;
1836 /* Use the client requested access mask here,
1837 * not the one we open with. */
1838 status = fcb_or_dos_open(req,
1849 if (NT_STATUS_IS_OK(status)) {
1852 *pinfo = FILE_WAS_OPENED;
1854 return NT_STATUS_OK;
1859 * This next line is a subtlety we need for
1860 * MS-Access. If a file open will fail due to share
1861 * permissions and also for security (access) reasons,
1862 * we need to return the access failed error, not the
1863 * share error. We can't open the file due to kernel
1864 * oplock deadlock (it's possible we failed above on
1865 * the open_mode_check()) so use a userspace check.
1868 if (flags & O_RDWR) {
1869 can_access_mask = FILE_READ_DATA|FILE_WRITE_DATA;
1870 } else if (flags & O_WRONLY) {
1871 can_access_mask = FILE_WRITE_DATA;
1873 can_access_mask = FILE_READ_DATA;
1876 if (((can_access_mask & FILE_WRITE_DATA) &&
1877 !CAN_WRITE(conn)) ||
1878 !can_access_file_data(conn, smb_fname,
1884 * If we're returning a share violation, ensure we
1885 * cope with the braindead 1 second delay.
1888 if (!(oplock_request & INTERNAL_OPEN_ONLY) &&
1889 lp_defer_sharing_violations()) {
1890 struct timeval timeout;
1891 struct deferred_open_record state;
1894 /* this is a hack to speed up torture tests
1896 timeout_usecs = lp_parm_int(SNUM(conn),
1897 "smbd","sharedelay",
1898 SHARING_VIOLATION_USEC_WAIT);
1900 /* This is a relative time, added to the absolute
1901 request_time value to get the absolute timeout time.
1902 Note that if this is the second or greater time we enter
1903 this codepath for this particular request mid then
1904 request_time is left as the absolute time of the *first*
1905 time this request mid was processed. This is what allows
1906 the request to eventually time out. */
1908 timeout = timeval_set(0, timeout_usecs);
1910 /* Nothing actually uses state.delayed_for_oplocks
1911 but it's handy to differentiate in debug messages
1912 between a 30 second delay due to oplock break, and
1913 a 1 second delay for share mode conflicts. */
1915 state.delayed_for_oplocks = False;
1919 && !request_timed_out(request_time,
1921 defer_open(lck, request_time, timeout,
1929 * We have detected a sharing violation here
1930 * so return the correct error code
1932 status = NT_STATUS_SHARING_VIOLATION;
1934 status = NT_STATUS_ACCESS_DENIED;
1940 * We exit this block with the share entry *locked*.....
1944 SMB_ASSERT(!file_existed || (lck != NULL));
1947 * Ensure we pay attention to default ACLs on directories if required.
1950 if ((flags2 & O_CREAT) && lp_inherit_acls(SNUM(conn)) &&
1951 (def_acl = directory_has_default_acl(conn, parent_dir))) {
1955 DEBUG(4,("calling open_file with flags=0x%X flags2=0x%X mode=0%o, "
1956 "access_mask = 0x%x, open_access_mask = 0x%x\n",
1957 (unsigned int)flags, (unsigned int)flags2,
1958 (unsigned int)unx_mode, (unsigned int)access_mask,
1959 (unsigned int)open_access_mask));
1962 * open_file strips any O_TRUNC flags itself.
1965 fsp_open = open_file(fsp, conn, req, parent_dir,
1966 flags|flags2, unx_mode, access_mask,
1969 if (!NT_STATUS_IS_OK(fsp_open)) {
1976 if (!file_existed) {
1977 struct timespec old_write_time = smb_fname->st.st_ex_mtime;
1979 * Deal with the race condition where two smbd's detect the
1980 * file doesn't exist and do the create at the same time. One
1981 * of them will win and set a share mode, the other (ie. this
1982 * one) should check if the requested share mode for this
1983 * create is allowed.
1987 * Now the file exists and fsp is successfully opened,
1988 * fsp->dev and fsp->inode are valid and should replace the
1989 * dev=0,inode=0 from a non existent file. Spotted by
1990 * Nadav Danieli <nadavd@exanet.com>. JRA.
1995 lck = get_share_mode_lock(talloc_tos(), id,
1997 smb_fname, &old_write_time);
2000 DEBUG(0, ("open_file_ntcreate: Could not get share "
2001 "mode lock for %s\n",
2002 smb_fname_str_dbg(smb_fname)));
2004 return NT_STATUS_SHARING_VIOLATION;
2007 /* First pass - send break only on batch oplocks. */
2009 && delay_for_oplocks(lck, fsp, req->mid, 1,
2011 schedule_defer_open(lck, request_time, req);
2014 return NT_STATUS_SHARING_VIOLATION;
2017 status = open_mode_check(conn, lck, access_mask, share_access,
2018 create_options, &file_existed);
2020 if (NT_STATUS_IS_OK(status)) {
2021 /* We might be going to allow this open. Check oplock
2023 /* Second pass - send break for both batch or
2024 * exclusive oplocks. */
2026 && delay_for_oplocks(lck, fsp, req->mid, 2,
2028 schedule_defer_open(lck, request_time, req);
2031 return NT_STATUS_SHARING_VIOLATION;
2035 if (!NT_STATUS_IS_OK(status)) {
2036 struct deferred_open_record state;
2040 state.delayed_for_oplocks = False;
2043 /* Do it all over again immediately. In the second
2044 * round we will find that the file existed and handle
2045 * the DELETE_PENDING and FCB cases correctly. No need
2046 * to duplicate the code here. Essentially this is a
2047 * "goto top of this function", but don't tell
2051 defer_open(lck, request_time, timeval_zero(),
2059 * We exit this block with the share entry *locked*.....
2064 SMB_ASSERT(lck != NULL);
2066 /* Delete streams if create_disposition requires it */
2067 if (file_existed && clear_ads &&
2068 !is_ntfs_stream_smb_fname(smb_fname)) {
2069 status = delete_all_streams(conn, smb_fname->base_name);
2070 if (!NT_STATUS_IS_OK(status)) {
2077 /* note that we ignore failure for the following. It is
2078 basically a hack for NFS, and NFS will never set one of
2079 these only read them. Nobody but Samba can ever set a deny
2080 mode and we have already checked our more authoritative
2081 locking database for permission to set this deny mode. If
2082 the kernel refuses the operations then the kernel is wrong.
2083 note that GPFS supports it as well - jmcd */
2085 if (fsp->fh->fd != -1) {
2087 ret_flock = SMB_VFS_KERNEL_FLOCK(fsp, share_access, access_mask);
2088 if(ret_flock == -1 ){
2093 return NT_STATUS_SHARING_VIOLATION;
2098 * At this point onwards, we can guarentee that the share entry
2099 * is locked, whether we created the file or not, and that the
2100 * deny mode is compatible with all current opens.
2104 * If requested, truncate the file.
2107 if (flags2&O_TRUNC) {
2109 * We are modifing the file after open - update the stat
2112 if ((SMB_VFS_FTRUNCATE(fsp, 0) == -1) ||
2113 (SMB_VFS_FSTAT(fsp, &smb_fname->st)==-1)) {
2114 status = map_nt_error_from_unix(errno);
2121 /* Record the options we were opened with. */
2122 fsp->share_access = share_access;
2123 fsp->fh->private_options = create_options;
2125 * According to Samba4, SEC_FILE_READ_ATTRIBUTE is always granted,
2127 fsp->access_mask = access_mask | FILE_READ_ATTRIBUTES;
2130 /* stat opens on existing files don't get oplocks. */
2131 if (is_stat_open(open_access_mask)) {
2132 fsp->oplock_type = NO_OPLOCK;
2135 if (!(flags2 & O_TRUNC)) {
2136 info = FILE_WAS_OPENED;
2138 info = FILE_WAS_OVERWRITTEN;
2141 info = FILE_WAS_CREATED;
2149 * Setup the oplock info in both the shared memory and
2153 if (!set_file_oplock(fsp, fsp->oplock_type)) {
2154 /* Could not get the kernel oplock */
2155 fsp->oplock_type = NO_OPLOCK;
2158 if (info == FILE_WAS_OVERWRITTEN || info == FILE_WAS_CREATED || info == FILE_WAS_SUPERSEDED) {
2159 new_file_created = True;
2162 set_share_mode(lck, fsp, conn->server_info->utok.uid, 0,
2165 /* Handle strange delete on close create semantics. */
2166 if (create_options & FILE_DELETE_ON_CLOSE) {
2168 status = can_set_delete_on_close(fsp, new_dos_attributes);
2170 if (!NT_STATUS_IS_OK(status)) {
2171 /* Remember to delete the mode we just added. */
2172 del_share_mode(lck, fsp);
2177 /* Note that here we set the *inital* delete on close flag,
2178 not the regular one. The magic gets handled in close. */
2179 fsp->initial_delete_on_close = True;
2182 if (new_file_created) {
2183 /* Files should be initially set as archive */
2184 if (lp_map_archive(SNUM(conn)) ||
2185 lp_store_dos_attributes(SNUM(conn))) {
2187 if (file_set_dosmode(conn, smb_fname,
2188 new_dos_attributes | aARCH,
2189 parent_dir, true) == 0) {
2190 unx_mode = smb_fname->st.st_ex_mode;
2197 * Take care of inherited ACLs on created files - if default ACL not
2201 if (!posix_open && !file_existed && !def_acl) {
2203 int saved_errno = errno; /* We might get ENOSYS in the next
2206 if (SMB_VFS_FCHMOD_ACL(fsp, unx_mode) == -1 &&
2208 errno = saved_errno; /* Ignore ENOSYS */
2211 } else if (new_unx_mode) {
2215 /* Attributes need changing. File already existed. */
2218 int saved_errno = errno; /* We might get ENOSYS in the
2220 ret = SMB_VFS_FCHMOD_ACL(fsp, new_unx_mode);
2222 if (ret == -1 && errno == ENOSYS) {
2223 errno = saved_errno; /* Ignore ENOSYS */
2225 DEBUG(5, ("open_file_ntcreate: reset "
2226 "attributes of file %s to 0%o\n",
2227 smb_fname_str_dbg(smb_fname),
2228 (unsigned int)new_unx_mode));
2229 ret = 0; /* Don't do the fchmod below. */
2234 (SMB_VFS_FCHMOD(fsp, new_unx_mode) == -1))
2235 DEBUG(5, ("open_file_ntcreate: failed to reset "
2236 "attributes of file %s to 0%o\n",
2237 smb_fname_str_dbg(smb_fname),
2238 (unsigned int)new_unx_mode));
2241 /* If this is a successful open, we must remove any deferred open
2244 del_deferred_open_entry(lck, req->mid);
2248 return NT_STATUS_OK;
2252 /****************************************************************************
2253 Open a file for for write to ensure that we can fchmod it.
2254 ****************************************************************************/
2256 NTSTATUS open_file_fchmod(struct smb_request *req, connection_struct *conn,
2257 struct smb_filename *smb_fname,
2258 files_struct **result)
2260 files_struct *fsp = NULL;
2263 if (!VALID_STAT(smb_fname->st)) {
2264 return NT_STATUS_INVALID_PARAMETER;
2267 status = file_new(req, conn, &fsp);
2268 if(!NT_STATUS_IS_OK(status)) {
2272 status = SMB_VFS_CREATE_FILE(
2275 0, /* root_dir_fid */
2276 smb_fname, /* fname */
2277 FILE_WRITE_DATA, /* access_mask */
2278 (FILE_SHARE_READ | FILE_SHARE_WRITE | /* share_access */
2280 FILE_OPEN, /* create_disposition*/
2281 0, /* create_options */
2282 0, /* file_attributes */
2283 0, /* oplock_request */
2284 0, /* allocation_size */
2291 * This is not a user visible file open.
2292 * Don't set a share mode.
2295 if (!NT_STATUS_IS_OK(status)) {
2296 file_free(req, fsp);
2301 return NT_STATUS_OK;
2304 /****************************************************************************
2305 Close the fchmod file fd - ensure no locks are lost.
2306 ****************************************************************************/
2308 NTSTATUS close_file_fchmod(struct smb_request *req, files_struct *fsp)
2310 NTSTATUS status = fd_close(fsp);
2311 file_free(req, fsp);
2315 static NTSTATUS mkdir_internal(connection_struct *conn,
2316 struct smb_filename *smb_dname,
2317 uint32 file_attributes)
2322 bool posix_open = false;
2324 if(!CAN_WRITE(conn)) {
2325 DEBUG(5,("mkdir_internal: failing create on read-only share "
2326 "%s\n", lp_servicename(SNUM(conn))));
2327 return NT_STATUS_ACCESS_DENIED;
2330 status = check_name(conn, smb_dname->base_name);
2331 if (!NT_STATUS_IS_OK(status)) {
2335 if (!parent_dirname(talloc_tos(), smb_dname->base_name, &parent_dir,
2337 return NT_STATUS_NO_MEMORY;
2340 if (file_attributes & FILE_FLAG_POSIX_SEMANTICS) {
2342 mode = (mode_t)(file_attributes & ~FILE_FLAG_POSIX_SEMANTICS);
2344 mode = unix_mode(conn, aDIR, smb_dname, parent_dir);
2347 if (SMB_VFS_MKDIR(conn, smb_dname->base_name, mode) != 0) {
2348 return map_nt_error_from_unix(errno);
2351 /* Ensure we're checking for a symlink here.... */
2352 /* We don't want to get caught by a symlink racer. */
2354 if (SMB_VFS_LSTAT(conn, smb_dname) == -1) {
2355 DEBUG(2, ("Could not stat directory '%s' just created: %s\n",
2356 smb_fname_str_dbg(smb_dname), strerror(errno)));
2357 return map_nt_error_from_unix(errno);
2360 if (!S_ISDIR(smb_dname->st.st_ex_mode)) {
2361 DEBUG(0, ("Directory just '%s' created is not a directory\n",
2362 smb_fname_str_dbg(smb_dname)));
2363 return NT_STATUS_ACCESS_DENIED;
2366 if (lp_store_dos_attributes(SNUM(conn))) {
2368 file_set_dosmode(conn, smb_dname,
2369 file_attributes | aDIR,
2374 if (lp_inherit_perms(SNUM(conn))) {
2375 inherit_access_posix_acl(conn, parent_dir,
2376 smb_dname->base_name, mode);
2381 * Check if high bits should have been set,
2382 * then (if bits are missing): add them.
2383 * Consider bits automagically set by UNIX, i.e. SGID bit from parent
2386 if ((mode & ~(S_IRWXU|S_IRWXG|S_IRWXO)) &&
2387 (mode & ~smb_dname->st.st_ex_mode)) {
2388 SMB_VFS_CHMOD(conn, smb_dname->base_name,
2389 (smb_dname->st.st_ex_mode |
2390 (mode & ~smb_dname->st.st_ex_mode)));
2394 /* Change the owner if required. */
2395 if (lp_inherit_owner(SNUM(conn))) {
2396 change_dir_owner_to_parent(conn, parent_dir,
2397 smb_dname->base_name,
2401 notify_fname(conn, NOTIFY_ACTION_ADDED, FILE_NOTIFY_CHANGE_DIR_NAME,
2402 smb_dname->base_name);
2404 return NT_STATUS_OK;
2407 /****************************************************************************
2408 Open a directory from an NT SMB call.
2409 ****************************************************************************/
2411 static NTSTATUS open_directory(connection_struct *conn,
2412 struct smb_request *req,
2413 struct smb_filename *smb_dname,
2415 uint32 share_access,
2416 uint32 create_disposition,
2417 uint32 create_options,
2418 uint32 file_attributes,
2420 files_struct **result)
2422 files_struct *fsp = NULL;
2423 bool dir_existed = VALID_STAT(smb_dname->st) ? True : False;
2424 struct share_mode_lock *lck = NULL;
2426 struct timespec mtimespec;
2429 SMB_ASSERT(!is_ntfs_stream_smb_fname(smb_dname));
2431 DEBUG(5,("open_directory: opening directory %s, access_mask = 0x%x, "
2432 "share_access = 0x%x create_options = 0x%x, "
2433 "create_disposition = 0x%x, file_attributes = 0x%x\n",
2434 smb_fname_str_dbg(smb_dname),
2435 (unsigned int)access_mask,
2436 (unsigned int)share_access,
2437 (unsigned int)create_options,
2438 (unsigned int)create_disposition,
2439 (unsigned int)file_attributes));
2441 if (!(file_attributes & FILE_FLAG_POSIX_SEMANTICS) &&
2442 (conn->fs_capabilities & FILE_NAMED_STREAMS) &&
2443 is_ntfs_stream_smb_fname(smb_dname)) {
2444 DEBUG(2, ("open_directory: %s is a stream name!\n",
2445 smb_fname_str_dbg(smb_dname)));
2446 return NT_STATUS_NOT_A_DIRECTORY;
2449 status = calculate_access_mask(conn, smb_dname, dir_existed,
2450 access_mask, &access_mask);
2451 if (!NT_STATUS_IS_OK(status)) {
2452 DEBUG(10, ("open_directory: calculate_access_mask "
2453 "on file %s returned %s\n",
2454 smb_fname_str_dbg(smb_dname),
2455 nt_errstr(status)));
2459 /* We need to support SeSecurityPrivilege for this. */
2460 if (access_mask & SEC_FLAG_SYSTEM_SECURITY) {
2461 DEBUG(10, ("open_directory: open on %s "
2462 "failed - SEC_FLAG_SYSTEM_SECURITY denied.\n",
2463 smb_fname_str_dbg(smb_dname)));
2464 return NT_STATUS_PRIVILEGE_NOT_HELD;
2467 switch( create_disposition ) {
2470 info = FILE_WAS_OPENED;
2473 * We want to follow symlinks here.
2476 if (SMB_VFS_STAT(conn, smb_dname) != 0) {
2477 return map_nt_error_from_unix(errno);
2484 /* If directory exists error. If directory doesn't
2487 status = mkdir_internal(conn, smb_dname,
2490 if (!NT_STATUS_IS_OK(status)) {
2491 DEBUG(2, ("open_directory: unable to create "
2492 "%s. Error was %s\n",
2493 smb_fname_str_dbg(smb_dname),
2494 nt_errstr(status)));
2498 info = FILE_WAS_CREATED;
2503 * If directory exists open. If directory doesn't
2507 status = mkdir_internal(conn, smb_dname,
2510 if (NT_STATUS_IS_OK(status)) {
2511 info = FILE_WAS_CREATED;
2514 if (NT_STATUS_EQUAL(status,
2515 NT_STATUS_OBJECT_NAME_COLLISION)) {
2516 info = FILE_WAS_OPENED;
2517 status = NT_STATUS_OK;
2522 case FILE_SUPERSEDE:
2523 case FILE_OVERWRITE:
2524 case FILE_OVERWRITE_IF:
2526 DEBUG(5,("open_directory: invalid create_disposition "
2527 "0x%x for directory %s\n",
2528 (unsigned int)create_disposition,
2529 smb_fname_str_dbg(smb_dname)));
2530 return NT_STATUS_INVALID_PARAMETER;
2533 if(!S_ISDIR(smb_dname->st.st_ex_mode)) {
2534 DEBUG(5,("open_directory: %s is not a directory !\n",
2535 smb_fname_str_dbg(smb_dname)));
2536 return NT_STATUS_NOT_A_DIRECTORY;
2539 if (info == FILE_WAS_OPENED) {
2540 uint32_t access_granted = 0;
2541 status = smbd_check_open_rights(conn, smb_dname, access_mask,
2544 /* Were we trying to do a directory open
2545 * for delete and didn't get DELETE
2546 * access (only) ? Check if the
2547 * directory allows DELETE_CHILD.
2549 * http://blogs.msdn.com/oldnewthing/archive/2004/06/04/148426.aspx
2552 if ((NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED) &&
2553 (access_mask & DELETE_ACCESS) &&
2554 (access_granted == DELETE_ACCESS) &&
2555 can_delete_file_in_directory(conn, smb_dname))) {
2556 DEBUG(10,("open_directory: overrode ACCESS_DENIED "
2557 "on directory %s\n",
2558 smb_fname_str_dbg(smb_dname)));
2559 status = NT_STATUS_OK;
2562 if (!NT_STATUS_IS_OK(status)) {
2563 DEBUG(10, ("open_directory: smbd_check_open_rights on "
2564 "file %s failed with %s\n",
2565 smb_fname_str_dbg(smb_dname),
2566 nt_errstr(status)));
2571 status = file_new(req, conn, &fsp);
2572 if(!NT_STATUS_IS_OK(status)) {
2577 * Setup the files_struct for it.
2580 fsp->mode = smb_dname->st.st_ex_mode;
2581 fsp->file_id = vfs_file_id_from_sbuf(conn, &smb_dname->st);
2582 fsp->vuid = req ? req->vuid : UID_FIELD_INVALID;
2583 fsp->file_pid = req ? req->smbpid : 0;
2584 fsp->can_lock = False;
2585 fsp->can_read = False;
2586 fsp->can_write = False;
2588 fsp->share_access = share_access;
2589 fsp->fh->private_options = create_options;
2591 * According to Samba4, SEC_FILE_READ_ATTRIBUTE is always granted,
2593 fsp->access_mask = access_mask | FILE_READ_ATTRIBUTES;
2594 fsp->print_file = False;
2595 fsp->modified = False;
2596 fsp->oplock_type = NO_OPLOCK;
2597 fsp->sent_oplock_break = NO_BREAK_SENT;
2598 fsp->is_directory = True;
2599 fsp->posix_open = (file_attributes & FILE_FLAG_POSIX_SEMANTICS) ? True : False;
2600 status = fsp_set_smb_fname(fsp, smb_dname);
2601 if (!NT_STATUS_IS_OK(status)) {
2605 mtimespec = smb_dname->st.st_ex_mtime;
2607 lck = get_share_mode_lock(talloc_tos(), fsp->file_id,
2608 conn->connectpath, smb_dname, &mtimespec);
2611 DEBUG(0, ("open_directory: Could not get share mode lock for "
2612 "%s\n", smb_fname_str_dbg(smb_dname)));
2613 file_free(req, fsp);
2614 return NT_STATUS_SHARING_VIOLATION;
2617 status = open_mode_check(conn, lck, access_mask, share_access,
2618 create_options, &dir_existed);
2620 if (!NT_STATUS_IS_OK(status)) {
2622 file_free(req, fsp);
2626 set_share_mode(lck, fsp, conn->server_info->utok.uid, 0, NO_OPLOCK);
2628 /* For directories the delete on close bit at open time seems
2629 always to be honored on close... See test 19 in Samba4 BASE-DELETE. */
2630 if (create_options & FILE_DELETE_ON_CLOSE) {
2631 status = can_set_delete_on_close(fsp, 0);
2632 if (!NT_STATUS_IS_OK(status) && !NT_STATUS_EQUAL(status, NT_STATUS_DIRECTORY_NOT_EMPTY)) {
2634 file_free(req, fsp);
2638 if (NT_STATUS_IS_OK(status)) {
2639 /* Note that here we set the *inital* delete on close flag,
2640 not the regular one. The magic gets handled in close. */
2641 fsp->initial_delete_on_close = True;
2652 return NT_STATUS_OK;
2655 NTSTATUS create_directory(connection_struct *conn, struct smb_request *req,
2656 struct smb_filename *smb_dname)
2661 status = SMB_VFS_CREATE_FILE(
2664 0, /* root_dir_fid */
2665 smb_dname, /* fname */
2666 FILE_READ_ATTRIBUTES, /* access_mask */
2667 FILE_SHARE_NONE, /* share_access */
2668 FILE_CREATE, /* create_disposition*/
2669 FILE_DIRECTORY_FILE, /* create_options */
2670 FILE_ATTRIBUTE_DIRECTORY, /* file_attributes */
2671 0, /* oplock_request */
2672 0, /* allocation_size */
2678 if (NT_STATUS_IS_OK(status)) {
2679 close_file(req, fsp, NORMAL_CLOSE);
2685 /****************************************************************************
2686 Receive notification that one of our open files has been renamed by another
2688 ****************************************************************************/
2690 void msg_file_was_renamed(struct messaging_context *msg,
2693 struct server_id server_id,
2697 char *frm = (char *)data->data;
2699 const char *sharepath;
2700 const char *base_name;
2701 const char *stream_name;
2702 struct smb_filename *smb_fname = NULL;
2703 size_t sp_len, bn_len;
2706 if (data->data == NULL
2707 || data->length < MSG_FILE_RENAMED_MIN_SIZE + 2) {
2708 DEBUG(0, ("msg_file_was_renamed: Got invalid msg len %d\n",
2709 (int)data->length));
2713 /* Unpack the message. */
2714 pull_file_id_24(frm, &id);
2715 sharepath = &frm[24];
2716 sp_len = strlen(sharepath);
2717 base_name = sharepath + sp_len + 1;
2718 bn_len = strlen(base_name);
2719 stream_name = sharepath + sp_len + 1 + bn_len + 1;
2721 /* stream_name must always be NULL if there is no stream. */
2722 if (stream_name[0] == '\0') {
2726 status = create_synthetic_smb_fname(talloc_tos(), base_name,
2727 stream_name, NULL, &smb_fname);
2728 if (!NT_STATUS_IS_OK(status)) {
2732 DEBUG(10,("msg_file_was_renamed: Got rename message for sharepath %s, new name %s, "
2734 sharepath, smb_fname_str_dbg(smb_fname),
2735 file_id_string_tos(&id)));
2737 for(fsp = file_find_di_first(id); fsp; fsp = file_find_di_next(fsp)) {
2738 if (memcmp(fsp->conn->connectpath, sharepath, sp_len) == 0) {
2740 DEBUG(10,("msg_file_was_renamed: renaming file fnum %d from %s -> %s\n",
2741 fsp->fnum, fsp_str_dbg(fsp),
2742 smb_fname_str_dbg(smb_fname)));
2743 status = fsp_set_smb_fname(fsp, smb_fname);
2744 if (!NT_STATUS_IS_OK(status)) {
2749 /* Now we have the complete path we can work out if this is
2750 actually within this share and adjust newname accordingly. */
2751 DEBUG(10,("msg_file_was_renamed: share mismatch (sharepath %s "
2752 "not sharepath %s) "
2753 "fnum %d from %s -> %s\n",
2754 fsp->conn->connectpath,
2758 smb_fname_str_dbg(smb_fname)));
2762 TALLOC_FREE(smb_fname);
2767 * If a main file is opened for delete, all streams need to be checked for
2768 * !FILE_SHARE_DELETE. Do this by opening with DELETE_ACCESS.
2769 * If that works, delete them all by setting the delete on close and close.
2772 NTSTATUS open_streams_for_delete(connection_struct *conn,
2775 struct stream_struct *stream_info;
2776 files_struct **streams;
2778 unsigned int num_streams;
2779 TALLOC_CTX *frame = talloc_stackframe();
2782 status = SMB_VFS_STREAMINFO(conn, NULL, fname, talloc_tos(),
2783 &num_streams, &stream_info);
2785 if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_IMPLEMENTED)
2786 || NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
2787 DEBUG(10, ("no streams around\n"));
2789 return NT_STATUS_OK;
2792 if (!NT_STATUS_IS_OK(status)) {
2793 DEBUG(10, ("SMB_VFS_STREAMINFO failed: %s\n",
2794 nt_errstr(status)));
2798 DEBUG(10, ("open_streams_for_delete found %d streams\n",
2801 if (num_streams == 0) {
2803 return NT_STATUS_OK;
2806 streams = TALLOC_ARRAY(talloc_tos(), files_struct *, num_streams);
2807 if (streams == NULL) {
2808 DEBUG(0, ("talloc failed\n"));
2809 status = NT_STATUS_NO_MEMORY;
2813 for (i=0; i<num_streams; i++) {
2814 struct smb_filename *smb_fname = NULL;
2816 if (strequal(stream_info[i].name, "::$DATA")) {
2821 status = create_synthetic_smb_fname(talloc_tos(), fname,
2822 stream_info[i].name,
2824 if (!NT_STATUS_IS_OK(status)) {
2828 if (SMB_VFS_STAT(conn, smb_fname) == -1) {
2829 DEBUG(10, ("Unable to stat stream: %s\n",
2830 smb_fname_str_dbg(smb_fname)));
2833 status = SMB_VFS_CREATE_FILE(
2836 0, /* root_dir_fid */
2837 smb_fname, /* fname */
2838 DELETE_ACCESS, /* access_mask */
2839 (FILE_SHARE_READ | /* share_access */
2840 FILE_SHARE_WRITE | FILE_SHARE_DELETE),
2841 FILE_OPEN, /* create_disposition*/
2842 NTCREATEX_OPTIONS_PRIVATE_STREAM_DELETE, /* create_options */
2843 FILE_ATTRIBUTE_NORMAL, /* file_attributes */
2844 0, /* oplock_request */
2845 0, /* allocation_size */
2848 &streams[i], /* result */
2851 if (!NT_STATUS_IS_OK(status)) {
2852 DEBUG(10, ("Could not open stream %s: %s\n",
2853 smb_fname_str_dbg(smb_fname),
2854 nt_errstr(status)));
2856 TALLOC_FREE(smb_fname);
2859 TALLOC_FREE(smb_fname);
2863 * don't touch the variable "status" beyond this point :-)
2866 for (i -= 1 ; i >= 0; i--) {
2867 if (streams[i] == NULL) {
2871 DEBUG(10, ("Closing stream # %d, %s\n", i,
2872 fsp_str_dbg(streams[i])));
2873 close_file(NULL, streams[i], NORMAL_CLOSE);
2882 * Wrapper around open_file_ntcreate and open_directory
2885 static NTSTATUS create_file_unixpath(connection_struct *conn,
2886 struct smb_request *req,
2887 struct smb_filename *smb_fname,
2888 uint32_t access_mask,
2889 uint32_t share_access,
2890 uint32_t create_disposition,
2891 uint32_t create_options,
2892 uint32_t file_attributes,
2893 uint32_t oplock_request,
2894 uint64_t allocation_size,
2895 struct security_descriptor *sd,
2896 struct ea_list *ea_list,
2898 files_struct **result,
2901 int info = FILE_WAS_OPENED;
2902 files_struct *base_fsp = NULL;
2903 files_struct *fsp = NULL;
2906 DEBUG(10,("create_file_unixpath: access_mask = 0x%x "
2907 "file_attributes = 0x%x, share_access = 0x%x, "
2908 "create_disposition = 0x%x create_options = 0x%x "
2909 "oplock_request = 0x%x ea_list = 0x%p, sd = 0x%p, "
2911 (unsigned int)access_mask,
2912 (unsigned int)file_attributes,
2913 (unsigned int)share_access,
2914 (unsigned int)create_disposition,
2915 (unsigned int)create_options,
2916 (unsigned int)oplock_request,
2917 ea_list, sd, smb_fname_str_dbg(smb_fname)));
2919 if (create_options & FILE_OPEN_BY_FILE_ID) {
2920 status = NT_STATUS_NOT_SUPPORTED;
2924 if (create_options & NTCREATEX_OPTIONS_INVALID_PARAM_MASK) {
2925 status = NT_STATUS_INVALID_PARAMETER;
2930 oplock_request |= INTERNAL_OPEN_ONLY;
2933 if ((conn->fs_capabilities & FILE_NAMED_STREAMS)
2934 && (access_mask & DELETE_ACCESS)
2935 && !is_ntfs_stream_smb_fname(smb_fname)) {
2937 * We can't open a file with DELETE access if any of the
2938 * streams is open without FILE_SHARE_DELETE
2940 status = open_streams_for_delete(conn, smb_fname->base_name);
2942 if (!NT_STATUS_IS_OK(status)) {
2947 /* This is the correct thing to do (check every time) but can_delete
2948 * is expensive (it may have to read the parent directory
2949 * permissions). So for now we're not doing it unless we have a strong
2950 * hint the client is really going to delete this file. If the client
2951 * is forcing FILE_CREATE let the filesystem take care of the
2954 /* Setting FILE_SHARE_DELETE is the hint. */
2956 if (lp_acl_check_permissions(SNUM(conn))
2957 && (create_disposition != FILE_CREATE)
2958 && (share_access & FILE_SHARE_DELETE)
2959 && (access_mask & DELETE_ACCESS)
2960 && (!(can_delete_file_in_directory(conn, smb_fname) ||
2961 can_access_file_acl(conn, smb_fname, DELETE_ACCESS)))) {
2962 status = NT_STATUS_ACCESS_DENIED;
2963 DEBUG(10,("create_file_unixpath: open file %s "
2964 "for delete ACCESS_DENIED\n",
2965 smb_fname_str_dbg(smb_fname)));
2970 /* We need to support SeSecurityPrivilege for this. */
2971 if ((access_mask & SEC_FLAG_SYSTEM_SECURITY) &&
2972 !user_has_privileges(current_user.nt_user_token,
2974 status = NT_STATUS_PRIVILEGE_NOT_HELD;
2978 /* We need to support SeSecurityPrivilege for this. */
2979 if (access_mask & SEC_FLAG_SYSTEM_SECURITY) {
2980 status = NT_STATUS_PRIVILEGE_NOT_HELD;
2983 /* Don't allow a SACL set from an NTtrans create until we
2984 * support SeSecurityPrivilege. */
2985 if (!VALID_STAT(smb_fname->st) &&
2986 lp_nt_acl_support(SNUM(conn)) &&
2987 sd && (sd->sacl != NULL)) {
2988 status = NT_STATUS_PRIVILEGE_NOT_HELD;
2993 if ((conn->fs_capabilities & FILE_NAMED_STREAMS)
2994 && is_ntfs_stream_smb_fname(smb_fname)
2995 && (!(create_options & NTCREATEX_OPTIONS_PRIVATE_STREAM_DELETE))) {
2996 uint32 base_create_disposition;
2997 struct smb_filename *smb_fname_base = NULL;
2999 if (create_options & FILE_DIRECTORY_FILE) {
3000 status = NT_STATUS_NOT_A_DIRECTORY;
3004 switch (create_disposition) {
3006 base_create_disposition = FILE_OPEN;
3009 base_create_disposition = FILE_OPEN_IF;
3013 /* Create an smb_filename with stream_name == NULL. */
3014 status = create_synthetic_smb_fname(talloc_tos(),
3015 smb_fname->base_name,
3018 if (!NT_STATUS_IS_OK(status)) {
3022 if (SMB_VFS_STAT(conn, smb_fname_base) == -1) {
3023 DEBUG(10, ("Unable to stat stream: %s\n",
3024 smb_fname_str_dbg(smb_fname_base)));
3027 /* Open the base file. */
3028 status = create_file_unixpath(conn, NULL, smb_fname_base, 0,
3031 | FILE_SHARE_DELETE,
3032 base_create_disposition,
3033 0, 0, 0, 0, NULL, NULL,
3035 TALLOC_FREE(smb_fname_base);
3037 if (!NT_STATUS_IS_OK(status)) {
3038 DEBUG(10, ("create_file_unixpath for base %s failed: "
3039 "%s\n", smb_fname->base_name,
3040 nt_errstr(status)));
3043 /* we don't need to low level fd */
3048 * If it's a request for a directory open, deal with it separately.
3051 if (create_options & FILE_DIRECTORY_FILE) {
3053 if (create_options & FILE_NON_DIRECTORY_FILE) {
3054 status = NT_STATUS_INVALID_PARAMETER;
3058 /* Can't open a temp directory. IFS kit test. */
3059 if (!(file_attributes & FILE_FLAG_POSIX_SEMANTICS) &&
3060 (file_attributes & FILE_ATTRIBUTE_TEMPORARY)) {
3061 status = NT_STATUS_INVALID_PARAMETER;
3066 * We will get a create directory here if the Win32
3067 * app specified a security descriptor in the
3068 * CreateDirectory() call.
3072 status = open_directory(
3073 conn, req, smb_fname, access_mask, share_access,
3074 create_disposition, create_options, file_attributes,
3079 * Ordinary file case.
3082 status = file_new(req, conn, &fsp);
3083 if(!NT_STATUS_IS_OK(status)) {
3087 status = fsp_set_smb_fname(fsp, smb_fname);
3088 if (!NT_STATUS_IS_OK(status)) {
3093 * We're opening the stream element of a base_fsp
3094 * we already opened. Set up the base_fsp pointer.
3097 fsp->base_fsp = base_fsp;
3100 status = open_file_ntcreate(conn,
3111 if(!NT_STATUS_IS_OK(status)) {
3112 file_free(req, fsp);
3116 if (NT_STATUS_EQUAL(status, NT_STATUS_FILE_IS_A_DIRECTORY)) {
3118 /* A stream open never opens a directory */
3121 status = NT_STATUS_FILE_IS_A_DIRECTORY;
3126 * Fail the open if it was explicitly a non-directory
3130 if (create_options & FILE_NON_DIRECTORY_FILE) {
3131 status = NT_STATUS_FILE_IS_A_DIRECTORY;
3136 status = open_directory(
3137 conn, req, smb_fname, access_mask,
3138 share_access, create_disposition,
3139 create_options, file_attributes,
3144 if (!NT_STATUS_IS_OK(status)) {
3148 fsp->base_fsp = base_fsp;
3151 * According to the MS documentation, the only time the security
3152 * descriptor is applied to the opened file is iff we *created* the
3153 * file; an existing file stays the same.
3155 * Also, it seems (from observation) that you can open the file with
3156 * any access mask but you can still write the sd. We need to override
3157 * the granted access before we call set_sd
3158 * Patch for bug #2242 from Tom Lackemann <cessnatomny@yahoo.com>.
3161 if ((sd != NULL) && (info == FILE_WAS_CREATED)
3162 && lp_nt_acl_support(SNUM(conn))) {
3164 uint32_t sec_info_sent;
3165 uint32_t saved_access_mask = fsp->access_mask;
3167 sec_info_sent = get_sec_info(sd);
3169 fsp->access_mask = FILE_GENERIC_ALL;
3171 /* Convert all the generic bits. */
3172 security_acl_map_generic(sd->dacl, &file_generic_mapping);
3173 security_acl_map_generic(sd->sacl, &file_generic_mapping);
3175 if (sec_info_sent & (OWNER_SECURITY_INFORMATION|
3176 GROUP_SECURITY_INFORMATION|
3177 DACL_SECURITY_INFORMATION|
3178 SACL_SECURITY_INFORMATION)) {
3179 status = SMB_VFS_FSET_NT_ACL(fsp, sec_info_sent, sd);
3182 fsp->access_mask = saved_access_mask;
3184 if (!NT_STATUS_IS_OK(status)) {
3189 if ((ea_list != NULL) &&
3190 ((info == FILE_WAS_CREATED) || (info == FILE_WAS_OVERWRITTEN))) {
3191 status = set_ea(conn, fsp, fsp->fsp_name, ea_list);
3192 if (!NT_STATUS_IS_OK(status)) {
3197 if (!fsp->is_directory && S_ISDIR(fsp->fsp_name->st.st_ex_mode)) {
3198 status = NT_STATUS_ACCESS_DENIED;
3202 /* Save the requested allocation size. */
3203 if ((info == FILE_WAS_CREATED) || (info == FILE_WAS_OVERWRITTEN)) {
3205 && (allocation_size > fsp->fsp_name->st.st_ex_size)) {
3206 fsp->initial_allocation_size = smb_roundup(
3207 fsp->conn, allocation_size);
3208 if (fsp->is_directory) {
3209 /* Can't set allocation size on a directory. */
3210 status = NT_STATUS_ACCESS_DENIED;
3213 if (vfs_allocate_file_space(
3214 fsp, fsp->initial_allocation_size) == -1) {
3215 status = NT_STATUS_DISK_FULL;
3219 fsp->initial_allocation_size = smb_roundup(
3220 fsp->conn, (uint64_t)fsp->fsp_name->st.st_ex_size);
3224 DEBUG(10, ("create_file_unixpath: info=%d\n", info));
3227 if (pinfo != NULL) {
3231 smb_fname->st = fsp->fsp_name->st;
3233 return NT_STATUS_OK;
3236 DEBUG(10, ("create_file_unixpath: %s\n", nt_errstr(status)));
3239 if (base_fsp && fsp->base_fsp == base_fsp) {
3241 * The close_file below will close
3246 close_file(req, fsp, ERROR_CLOSE);
3249 if (base_fsp != NULL) {
3250 close_file(req, base_fsp, ERROR_CLOSE);
3257 * Calculate the full path name given a relative fid.
3259 NTSTATUS get_relative_fid_filename(connection_struct *conn,
3260 struct smb_request *req,
3261 uint16_t root_dir_fid,
3262 struct smb_filename *smb_fname)
3264 files_struct *dir_fsp;
3265 char *parent_fname = NULL;
3266 char *new_base_name = NULL;
3269 if (root_dir_fid == 0 || !smb_fname) {
3270 status = NT_STATUS_INTERNAL_ERROR;
3274 dir_fsp = file_fsp(req, root_dir_fid);
3276 if (dir_fsp == NULL) {
3277 status = NT_STATUS_INVALID_HANDLE;
3281 if (is_ntfs_stream_smb_fname(dir_fsp->fsp_name)) {
3282 status = NT_STATUS_INVALID_HANDLE;
3286 if (!dir_fsp->is_directory) {
3289 * Check to see if this is a mac fork of some kind.
3292 if ((conn->fs_capabilities & FILE_NAMED_STREAMS) &&
3293 is_ntfs_stream_smb_fname(smb_fname)) {
3294 status = NT_STATUS_OBJECT_PATH_NOT_FOUND;
3299 we need to handle the case when we get a
3300 relative open relative to a file and the
3301 pathname is blank - this is a reopen!
3302 (hint from demyn plantenberg)
3305 status = NT_STATUS_INVALID_HANDLE;
3309 if (ISDOT(dir_fsp->fsp_name->base_name)) {
3311 * We're at the toplevel dir, the final file name
3312 * must not contain ./, as this is filtered out
3313 * normally by srvstr_get_path and unix_convert
3314 * explicitly rejects paths containing ./.
3316 parent_fname = talloc_strdup(talloc_tos(), "");
3317 if (parent_fname == NULL) {
3318 status = NT_STATUS_NO_MEMORY;
3322 size_t dir_name_len = strlen(dir_fsp->fsp_name->base_name);
3325 * Copy in the base directory name.
3328 parent_fname = TALLOC_ARRAY(talloc_tos(), char,
3330 if (parent_fname == NULL) {
3331 status = NT_STATUS_NO_MEMORY;
3334 memcpy(parent_fname, dir_fsp->fsp_name->base_name,
3338 * Ensure it ends in a '/'.
3339 * We used TALLOC_SIZE +2 to add space for the '/'.
3343 && (parent_fname[dir_name_len-1] != '\\')
3344 && (parent_fname[dir_name_len-1] != '/')) {
3345 parent_fname[dir_name_len] = '/';
3346 parent_fname[dir_name_len+1] = '\0';
3350 new_base_name = talloc_asprintf(smb_fname, "%s%s", parent_fname,
3351 smb_fname->base_name);
3352 if (new_base_name == NULL) {
3353 status = NT_STATUS_NO_MEMORY;
3357 TALLOC_FREE(smb_fname->base_name);
3358 smb_fname->base_name = new_base_name;
3359 status = NT_STATUS_OK;
3362 TALLOC_FREE(parent_fname);
3366 NTSTATUS create_file_default(connection_struct *conn,
3367 struct smb_request *req,
3368 uint16_t root_dir_fid,
3369 struct smb_filename *smb_fname,
3370 uint32_t access_mask,
3371 uint32_t share_access,
3372 uint32_t create_disposition,
3373 uint32_t create_options,
3374 uint32_t file_attributes,
3375 uint32_t oplock_request,
3376 uint64_t allocation_size,
3377 struct security_descriptor *sd,
3378 struct ea_list *ea_list,
3379 files_struct **result,
3382 int info = FILE_WAS_OPENED;
3383 files_struct *fsp = NULL;
3386 DEBUG(10,("create_file: access_mask = 0x%x "
3387 "file_attributes = 0x%x, share_access = 0x%x, "
3388 "create_disposition = 0x%x create_options = 0x%x "
3389 "oplock_request = 0x%x "
3390 "root_dir_fid = 0x%x, ea_list = 0x%p, sd = 0x%p, "
3392 (unsigned int)access_mask,
3393 (unsigned int)file_attributes,
3394 (unsigned int)share_access,
3395 (unsigned int)create_disposition,
3396 (unsigned int)create_options,
3397 (unsigned int)oplock_request,
3398 (unsigned int)root_dir_fid,
3399 ea_list, sd, smb_fname_str_dbg(smb_fname)));
3402 * Calculate the filename from the root_dir_if if necessary.
3405 if (root_dir_fid != 0) {
3406 status = get_relative_fid_filename(conn, req, root_dir_fid,
3408 if (!NT_STATUS_IS_OK(status)) {
3414 * Check to see if this is a mac fork of some kind.
3417 if (is_ntfs_stream_smb_fname(smb_fname)) {
3418 enum FAKE_FILE_TYPE fake_file_type;
3420 fake_file_type = is_fake_file(smb_fname);
3422 if (fake_file_type != FAKE_FILE_TYPE_NONE) {
3425 * Here we go! support for changing the disk quotas
3428 * We need to fake up to open this MAGIC QUOTA file
3429 * and return a valid FID.
3431 * w2k close this file directly after openening xp
3432 * also tries a QUERY_FILE_INFO on the file and then
3435 status = open_fake_file(req, conn, req->vuid,
3436 fake_file_type, smb_fname,
3438 if (!NT_STATUS_IS_OK(status)) {
3442 ZERO_STRUCT(smb_fname->st);
3446 if (!(conn->fs_capabilities & FILE_NAMED_STREAMS)) {
3447 status = NT_STATUS_OBJECT_NAME_NOT_FOUND;
3452 /* All file access must go through check_name() */
3454 status = check_name(conn, smb_fname->base_name);
3455 if (!NT_STATUS_IS_OK(status)) {
3459 status = create_file_unixpath(
3460 conn, req, smb_fname, access_mask, share_access,
3461 create_disposition, create_options, file_attributes,
3462 oplock_request, allocation_size, sd, ea_list,
3465 if (!NT_STATUS_IS_OK(status)) {
3470 DEBUG(10, ("create_file: info=%d\n", info));
3473 if (pinfo != NULL) {
3476 return NT_STATUS_OK;
3479 DEBUG(10, ("create_file: %s\n", nt_errstr(status)));
3482 close_file(req, fsp, ERROR_CLOSE);