2 Unix SMB/CIFS implementation.
3 file opening and share modes
4 Copyright (C) Andrew Tridgell 1992-1998
5 Copyright (C) Jeremy Allison 2001
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 extern userdom_struct current_user_info;
25 extern uint16 global_oplock_port;
26 extern BOOL global_client_failed_oplock_break;
28 /****************************************************************************
29 fd support routines - attempt to do a dos_open.
30 ****************************************************************************/
32 static int fd_open(struct connection_struct *conn, char *fname,
33 int flags, mode_t mode)
37 if (!lp_symlinks(SNUM(conn)))
41 fd = SMB_VFS_OPEN(conn,fname,flags,mode);
43 /* Fix for files ending in '.' */
44 if((fd == -1) && (errno == ENOENT) &&
45 (strchr_m(fname,'.')==NULL)) {
47 fd = SMB_VFS_OPEN(conn,fname,flags,mode);
50 DEBUG(10,("fd_open: name %s, flags = 0%o mode = 0%o, fd = %d. %s\n", fname,
51 flags, (int)mode, fd, (fd == -1) ? strerror(errno) : "" ));
56 /****************************************************************************
57 Close the file associated with a fsp.
58 ****************************************************************************/
60 int fd_close(struct connection_struct *conn, files_struct *fsp)
63 return 0; /* what we used to call a stat open. */
64 return fd_close_posix(conn, fsp);
68 /****************************************************************************
69 Check a filename for the pipe string.
70 ****************************************************************************/
72 static void check_for_pipe(char *fname)
74 /* special case of pipe opens */
76 StrnCpy(s,fname,sizeof(s)-1);
78 if (strstr(s,"pipe/")) {
79 DEBUG(3,("Rejecting named pipe open for %s\n",fname));
80 unix_ERR_class = ERRSRV;
81 unix_ERR_code = ERRaccess;
82 unix_ERR_ntstatus = NT_STATUS_ACCESS_DENIED;
86 /****************************************************************************
88 ****************************************************************************/
90 static BOOL open_file(files_struct *fsp,connection_struct *conn,
91 const char *fname1,SMB_STRUCT_STAT *psbuf,int flags,mode_t mode, uint32 desired_access)
93 extern struct current_user current_user;
95 int accmode = (flags & O_ACCMODE);
96 int local_flags = flags;
99 fsp->oplock_type = NO_OPLOCK;
102 pstrcpy(fname,fname1);
104 /* Check permissions */
107 * This code was changed after seeing a client open request
108 * containing the open mode of (DENY_WRITE/read-only) with
109 * the 'create if not exist' bit set. The previous code
110 * would fail to open the file read only on a read-only share
111 * as it was checking the flags parameter directly against O_RDONLY,
112 * this was failing as the flags parameter was set to O_RDONLY|O_CREAT.
116 if (!CAN_WRITE(conn)) {
117 /* It's a read-only share - fail if we wanted to write. */
118 if(accmode != O_RDONLY) {
119 DEBUG(3,("Permission denied opening %s\n",fname));
120 check_for_pipe(fname);
122 } else if(flags & O_CREAT) {
123 /* We don't want to write - but we must make sure that O_CREAT
124 doesn't create the file if we have write access into the
132 * This little piece of insanity is inspired by the
133 * fact that an NT client can open a file for O_RDONLY,
134 * but set the create disposition to FILE_EXISTS_TRUNCATE.
135 * If the client *can* write to the file, then it expects to
136 * truncate the file, even though it is opening for readonly.
137 * Quicken uses this stupid trick in backup file creation...
138 * Thanks *greatly* to "David W. Chapman Jr." <dwcjr@inethouston.net>
139 * for helping track this one down. It didn't bite us in 2.0.x
140 * as we always opened files read-write in that release. JRA.
143 if ((accmode == O_RDONLY) && ((flags & O_TRUNC) == O_TRUNC)) {
144 DEBUG(10,("open_file: truncate requested on read-only open for file %s\n",fname ));
145 local_flags = (flags & ~O_ACCMODE)|O_RDWR;
148 if ((desired_access & (FILE_READ_DATA|FILE_WRITE_DATA|FILE_APPEND_DATA|FILE_EXECUTE)) ||
149 (local_flags & O_CREAT) || ((local_flags & O_TRUNC) == O_TRUNC) ) {
152 * We can't actually truncate here as the file may be locked.
153 * open_file_shared will take care of the truncate later. JRA.
156 local_flags &= ~O_TRUNC;
158 #if defined(O_NONBLOCK) && defined(S_ISFIFO)
160 * We would block on opening a FIFO with no one else on the
161 * other end. Do what we used to do and add O_NONBLOCK to the
165 if (VALID_STAT(*psbuf) && S_ISFIFO(psbuf->st_mode))
166 local_flags |= O_NONBLOCK;
169 /* Actually do the open */
170 fsp->fd = fd_open(conn, fname, local_flags, mode);
172 DEBUG(3,("Error opening file %s (%s) (local_flags=%d) (flags=%d)\n",
173 fname,strerror(errno),local_flags,flags));
174 check_for_pipe(fname);
178 /* Inherit the ACL if the file was created. */
179 if ((local_flags & O_CREAT) && !VALID_STAT(*psbuf))
180 inherit_access_acl(conn, fname, mode);
183 fsp->fd = -1; /* What we used to call a stat open. */
185 if (!VALID_STAT(*psbuf)) {
189 ret = SMB_VFS_STAT(conn, fname, psbuf);
191 ret = SMB_VFS_FSTAT(fsp,fsp->fd,psbuf);
192 /* If we have an fd, this stat should succeed. */
194 DEBUG(0,("Error doing fstat on open file %s (%s)\n", fname,strerror(errno) ));
197 /* For a non-io open, this stat failing means file not found. JRA */
205 * POSIX allows read-only opens of directories. We don't
206 * want to do this (we use a different code path for this)
207 * so catch a directory open and return an EISDIR. JRA.
210 if(S_ISDIR(psbuf->st_mode)) {
216 fsp->mode = psbuf->st_mode;
217 fsp->inode = psbuf->st_ino;
218 fsp->dev = psbuf->st_dev;
219 fsp->vuid = current_user.vuid;
220 fsp->size = psbuf->st_size;
222 fsp->can_lock = True;
223 fsp->can_read = ((flags & O_WRONLY)==0);
224 fsp->can_write = ((flags & (O_WRONLY|O_RDWR))!=0);
226 fsp->desired_access = desired_access;
227 fsp->print_file = False;
228 fsp->modified = False;
229 fsp->oplock_type = NO_OPLOCK;
230 fsp->sent_oplock_break = NO_BREAK_SENT;
231 fsp->is_directory = False;
232 fsp->is_stat = False;
233 fsp->directory_delete_on_close = False;
234 string_set(&fsp->fsp_name,fname);
235 fsp->wcp = NULL; /* Write cache pointer. */
237 DEBUG(2,("%s opened file %s read=%s write=%s (numopen=%d)\n",
238 *current_user_info.smb_name ? current_user_info.smb_name : conn->user,fsp->fsp_name,
239 BOOLSTR(fsp->can_read), BOOLSTR(fsp->can_write),
240 conn->num_files_open + 1));
245 /****************************************************************************
247 Helper for open_file_shared.
248 Truncate a file after checking locking; close file if locked.
249 **************************************************************************/
251 static int truncate_unless_locked(struct connection_struct *conn, files_struct *fsp)
253 SMB_BIG_UINT mask = (SMB_BIG_UINT)-1;
255 if (is_locked(fsp,fsp->conn,mask,0,WRITE_LOCK,True)){
257 unix_ERR_class = ERRDOS;
258 unix_ERR_code = ERRlock;
259 unix_ERR_ntstatus = dos_to_ntstatus(ERRDOS, ERRlock);
262 return SMB_VFS_FTRUNCATE(fsp,fsp->fd,0);
266 /*******************************************************************
267 return True if the filename is one of the special executable types
268 ********************************************************************/
269 static BOOL is_executable(const char *fname)
271 if ((fname = strrchr_m(fname,'.'))) {
272 if (strequal(fname,".com") ||
273 strequal(fname,".dll") ||
274 strequal(fname,".exe") ||
275 strequal(fname,".sym")) {
282 enum {AFAIL,AREAD,AWRITE,AALL};
284 /*******************************************************************
285 reproduce the share mode access table
286 this is horrendoously complex, and really can't be justified on any
287 rational grounds except that this is _exactly_ what NT does. See
288 the DENY1 and DENY2 tests in smbtorture for a comprehensive set of
290 ********************************************************************/
291 static int access_table(int new_deny,int old_deny,int old_mode,
292 BOOL same_pid, BOOL isexe)
294 if (new_deny == DENY_ALL || old_deny == DENY_ALL) return(AFAIL);
297 if (isexe && old_mode == DOS_OPEN_RDONLY &&
298 old_deny == DENY_DOS && new_deny == DENY_READ) {
301 if (!isexe && old_mode == DOS_OPEN_RDONLY &&
302 old_deny == DENY_DOS && new_deny == DENY_DOS) {
305 if (new_deny == DENY_FCB && old_deny == DENY_DOS) {
306 if (isexe) return AFAIL;
307 if (old_mode == DOS_OPEN_RDONLY) return AFAIL;
310 if (old_mode == DOS_OPEN_RDONLY && old_deny == DENY_DOS) {
311 if (new_deny == DENY_FCB || new_deny == DENY_READ) {
312 if (isexe) return AREAD;
316 if (old_deny == DENY_FCB) {
317 if (new_deny == DENY_DOS || new_deny == DENY_FCB) return AALL;
322 if (old_deny == DENY_DOS || new_deny == DENY_DOS ||
323 old_deny == DENY_FCB || new_deny == DENY_FCB) {
325 if (old_deny == DENY_FCB || new_deny == DENY_FCB) {
328 if (old_deny == DENY_DOS) {
329 if (new_deny == DENY_READ &&
330 (old_mode == DOS_OPEN_RDONLY ||
331 old_mode == DOS_OPEN_RDWR)) {
334 if (new_deny == DENY_WRITE &&
335 (old_mode == DOS_OPEN_WRONLY ||
336 old_mode == DOS_OPEN_RDWR)) {
341 if (old_deny == DENY_NONE) return AALL;
342 if (old_deny == DENY_READ) return AWRITE;
343 if (old_deny == DENY_WRITE) return AREAD;
345 /* it isn't a exe, dll, sym or com file */
346 if (old_deny == new_deny && same_pid)
349 if (old_deny == DENY_READ || new_deny == DENY_READ) return AFAIL;
350 if (old_mode == DOS_OPEN_RDONLY) return(AREAD);
358 if (old_deny==DENY_WRITE && old_mode==DOS_OPEN_RDONLY) return(AREAD);
359 if (old_deny==DENY_READ && old_mode==DOS_OPEN_RDONLY) return(AWRITE);
360 if (old_deny==DENY_NONE && old_mode==DOS_OPEN_RDONLY) return(AALL);
363 if (old_deny==DENY_WRITE && old_mode==DOS_OPEN_WRONLY) return(AREAD);
364 if (old_deny==DENY_READ && old_mode==DOS_OPEN_WRONLY) return(AWRITE);
365 if (old_deny==DENY_NONE && old_mode==DOS_OPEN_WRONLY) return(AALL);
368 if (old_deny==DENY_WRITE) return(AREAD);
369 if (old_deny==DENY_READ) return(AWRITE);
370 if (old_deny==DENY_NONE) return(AALL);
377 /****************************************************************************
378 check if we can open a file with a share mode
379 ****************************************************************************/
381 static BOOL check_share_mode(connection_struct *conn, share_mode_entry *share, int share_mode, uint32 desired_access,
382 const char *fname, BOOL fcbopen, int *flags)
384 int deny_mode = GET_DENY_MODE(share_mode);
385 int old_open_mode = GET_OPEN_MODE(share->share_mode);
386 int old_deny_mode = GET_DENY_MODE(share->share_mode);
389 * share modes = false means don't bother to check for
390 * DENY mode conflict. This is a *really* bad idea :-). JRA.
393 if(!lp_share_modes(SNUM(conn)))
397 * Don't allow any opens once the delete on close flag has been
401 if (GET_DELETE_ON_CLOSE_FLAG(share->share_mode)) {
402 DEBUG(5,("check_share_mode: Failing open on file %s as delete on close flag is set.\n",
404 /* Use errno to map to correct error. */
405 unix_ERR_class = SMB_SUCCESS;
407 unix_ERR_ntstatus = NT_STATUS_OK;
411 /* this is a nasty hack, but necessary until we rewrite our open
412 handling to use a NTCreateX call as the basic call.
413 NT may open a file with neither read nor write access, and in
414 this case it expects the open not to conflict with any
415 existing deny modes. This happens (for example) during a
416 "xcopy /o" where the second file descriptor is used for
422 * This is a bit wierd - the test for desired access not having the
423 * critical bits seems seems odd. Firstly, if both opens have no
424 * critical bits then always ignore. Then check the "allow delete"
425 * then check for either. This probably isn't quite right yet but
426 * gets us much closer. JRA.
430 * If desired_access doesn't contain READ_DATA,WRITE_DATA,APPEND_DATA or EXECUTE
431 * and the existing desired_acces then share modes don't conflict.
434 if ( !(desired_access & (FILE_READ_DATA|FILE_WRITE_DATA|FILE_APPEND_DATA|FILE_EXECUTE)) &&
435 !(share->desired_access & (FILE_READ_DATA|FILE_WRITE_DATA|FILE_APPEND_DATA|FILE_EXECUTE)) ) {
438 * Wrinkle discovered by smbtorture....
439 * If both are non-io open and requester is asking for delete and current open has delete access
440 * but neither open has allowed file share delete then deny.... this is very strange and
441 * seems to be the only case in which non-io opens conflict. JRA.
444 if ((desired_access & DELETE_ACCESS) && (share->desired_access & DELETE_ACCESS) &&
445 (!GET_ALLOW_SHARE_DELETE(share->share_mode) || !GET_ALLOW_SHARE_DELETE(share_mode))) {
446 DEBUG(5,("check_share_mode: Failing open on file %s as delete access requests conflict.\n",
448 unix_ERR_class = ERRDOS;
449 unix_ERR_code = ERRbadshare;
450 unix_ERR_ntstatus = NT_STATUS_SHARING_VIOLATION;
455 DEBUG(5,("check_share_mode: Allowing open on file %s as both desired access (0x%x) \
456 and existing desired access (0x%x) are non-data opens\n",
457 fname, (unsigned int)desired_access, (unsigned int)share->desired_access ));
462 * If delete access was requested and the existing share mode doesn't have
463 * ALLOW_SHARE_DELETE then deny.
466 if ((desired_access & DELETE_ACCESS) && !GET_ALLOW_SHARE_DELETE(share->share_mode)) {
467 DEBUG(5,("check_share_mode: Failing open on file %s as delete access requested and allow share delete not set.\n",
469 unix_ERR_class = ERRDOS;
470 unix_ERR_code = ERRbadshare;
471 unix_ERR_ntstatus = NT_STATUS_SHARING_VIOLATION;
477 * The inverse of the above.
478 * If delete access was granted and the new share mode doesn't have
479 * ALLOW_SHARE_DELETE then deny.
482 if ((share->desired_access & DELETE_ACCESS) && !GET_ALLOW_SHARE_DELETE(share_mode)) {
483 DEBUG(5,("check_share_mode: Failing open on file %s as delete access granted and allow share delete not requested.\n",
485 unix_ERR_class = ERRDOS;
486 unix_ERR_code = ERRbadshare;
487 unix_ERR_ntstatus = NT_STATUS_SHARING_VIOLATION;
493 * If desired_access doesn't contain READ_DATA,WRITE_DATA,APPEND_DATA or EXECUTE
494 * then share modes don't conflict. Likewise with existing desired access.
497 if ( !(desired_access & (FILE_READ_DATA|FILE_WRITE_DATA|FILE_APPEND_DATA|FILE_EXECUTE)) ||
498 !(share->desired_access & (FILE_READ_DATA|FILE_WRITE_DATA|FILE_APPEND_DATA|FILE_EXECUTE)) ) {
499 DEBUG(5,("check_share_mode: Allowing open on file %s as desired access (0x%x) doesn't conflict with\
500 existing desired access (0x%x).\n", fname, (unsigned int)desired_access, (unsigned int)share->desired_access ));
505 int access_allowed = access_table(deny_mode,old_deny_mode,old_open_mode,
506 (share->pid == sys_getpid()),is_executable(fname));
508 if ((access_allowed == AFAIL) ||
509 (!fcbopen && (access_allowed == AREAD && *flags == O_RDWR)) ||
510 (access_allowed == AREAD && *flags != O_RDONLY) ||
511 (access_allowed == AWRITE && *flags != O_WRONLY)) {
513 DEBUG(2,("Share violation on file (%d,%d,%d,%d,%s,fcbopen = %d, flags = %d) = %d\n",
514 deny_mode,old_deny_mode,old_open_mode,
515 (int)share->pid,fname, fcbopen, *flags, access_allowed));
517 unix_ERR_class = ERRDOS;
518 unix_ERR_code = ERRbadshare;
519 unix_ERR_ntstatus = NT_STATUS_SHARING_VIOLATION;
524 if (access_allowed == AREAD)
527 if (access_allowed == AWRITE)
536 #if defined(DEVELOPER)
537 static void validate_my_share_entries(int num, share_mode_entry *share_entry)
541 if (share_entry->pid != sys_getpid())
544 fsp = file_find_dif(share_entry->dev, share_entry->inode, share_entry->share_file_id);
546 DEBUG(0,("validate_my_share_entries: PANIC : %s\n", share_mode_str(num, share_entry) ));
547 smb_panic("validate_my_share_entries: Cannot match a share entry with an open file\n");
550 if (((uint16)fsp->oplock_type) != share_entry->op_type) {
552 DEBUG(0,("validate_my_share_entries: PANIC : %s\n", share_mode_str(num, share_entry) ));
553 slprintf(str, sizeof(str)-1, "validate_my_share_entries: file %s, oplock_type = 0x%x, op_type = 0x%x\n",
554 fsp->fsp_name, (unsigned int)fsp->oplock_type, (unsigned int)share_entry->op_type );
560 /****************************************************************************
561 Deal with open deny mode and oplock break processing.
562 Invarient: Share mode must be locked on entry and exit.
563 Returns -1 on error, or number of share modes on success (may be zero).
564 ****************************************************************************/
566 static int open_mode_check(connection_struct *conn, const char *fname, SMB_DEV_T dev,
568 uint32 desired_access,
569 int share_mode, int *p_flags, int *p_oplock_request,
570 BOOL *p_all_current_opens_are_level_II)
574 int oplock_contention_count = 0;
575 share_mode_entry *old_shares = 0;
576 BOOL fcbopen = False;
579 if(GET_OPEN_MODE(share_mode) == DOS_OPEN_FCB)
582 num_share_modes = get_share_modes(conn, dev, inode, &old_shares);
584 if(num_share_modes == 0)
588 * Check if the share modes will give us access.
592 share_mode_entry broken_entry;
594 broke_oplock = False;
595 *p_all_current_opens_are_level_II = True;
597 for(i = 0; i < num_share_modes; i++) {
598 share_mode_entry *share_entry = &old_shares[i];
600 #if defined(DEVELOPER)
601 validate_my_share_entries(i, share_entry);
605 * By observation of NetBench, oplocks are broken *before* share
606 * modes are checked. This allows a file to be closed by the client
607 * if the share mode would deny access and the client has an oplock.
608 * Check if someone has an oplock on this file. If so we must break
609 * it before continuing.
612 if((*p_oplock_request && EXCLUSIVE_OPLOCK_TYPE(share_entry->op_type)) ||
613 (!*p_oplock_request && (share_entry->op_type != NO_OPLOCK))) {
617 DEBUG(5,("open_mode_check: oplock_request = %d, breaking oplock (%x) on file %s, \
618 dev = %x, inode = %.0f\n", *p_oplock_request, share_entry->op_type, fname, (unsigned int)dev, (double)inode));
620 /* Oplock break - unlock to request it. */
621 unlock_share_entry(conn, dev, inode);
623 opb_ret = request_oplock_break(share_entry, False);
626 lock_share_entry(conn, dev, inode);
628 if(opb_ret == False) {
629 DEBUG(0,("open_mode_check: FAILED when breaking oplock (%x) on file %s, \
630 dev = %x, inode = %.0f\n", old_shares[i].op_type, fname, (unsigned int)dev, (double)inode));
631 SAFE_FREE(old_shares);
633 unix_ERR_class = ERRDOS;
634 unix_ERR_code = ERRbadshare;
635 unix_ERR_ntstatus = NT_STATUS_SHARING_VIOLATION;
640 broken_entry = *share_entry;
643 } else if (!LEVEL_II_OPLOCK_TYPE(share_entry->op_type)) {
644 *p_all_current_opens_are_level_II = False;
647 /* someone else has a share lock on it, check to see if we can too */
648 if (!check_share_mode(conn, share_entry, share_mode, desired_access,
649 fname, fcbopen, p_flags)) {
650 SAFE_FREE(old_shares);
658 SAFE_FREE(old_shares);
659 num_share_modes = get_share_modes(conn, dev, inode, &old_shares);
660 oplock_contention_count++;
662 /* Paranoia check that this is no longer an exlusive entry. */
663 for(i = 0; i < num_share_modes; i++) {
664 share_mode_entry *share_entry = &old_shares[i];
666 if (share_modes_identical(&broken_entry, share_entry) &&
667 EXCLUSIVE_OPLOCK_TYPE(share_entry->op_type) ) {
670 * This should not happen. The target left this oplock
671 * as exlusive.... The process *must* be dead....
674 DEBUG(0,("open_mode_check: exlusive oplock left by process %d after break ! For file %s, \
675 dev = %x, inode = %.0f. Deleting it to continue...\n", (int)broken_entry.pid, fname, (unsigned int)dev, (double)inode));
677 if (process_exists(broken_entry.pid)) {
678 DEBUG(0,("open_mode_check: Existent process %d left active oplock.\n",
682 if (del_share_entry(dev, inode, &broken_entry, NULL) == -1) {
684 unix_ERR_class = ERRDOS;
685 unix_ERR_code = ERRbadshare;
686 unix_ERR_ntstatus = NT_STATUS_SHARING_VIOLATION;
691 * We must reload the share modes after deleting the
692 * other process's entry.
695 SAFE_FREE(old_shares);
696 num_share_modes = get_share_modes(conn, dev, inode, &old_shares);
699 } /* end for paranoia... */
700 } /* end if broke_oplock */
702 } while(broke_oplock);
705 SAFE_FREE(old_shares);
708 * Refuse to grant an oplock in case the contention limit is
709 * reached when going through the lock list multiple times.
712 if(oplock_contention_count >= lp_oplock_contention_limit(SNUM(conn))) {
713 *p_oplock_request = 0;
714 DEBUG(4,("open_mode_check: oplock contention = %d. Not granting oplock.\n",
715 oplock_contention_count ));
718 return num_share_modes;
721 /****************************************************************************
722 set a kernel flock on a file for NFS interoperability
723 this requires a patch to Linux
724 ****************************************************************************/
725 static void kernel_flock(files_struct *fsp, int deny_mode)
727 #if HAVE_KERNEL_SHARE_MODES
729 if (deny_mode == DENY_READ) kernel_mode = LOCK_MAND|LOCK_WRITE;
730 else if (deny_mode == DENY_WRITE) kernel_mode = LOCK_MAND|LOCK_READ;
731 else if (deny_mode == DENY_ALL) kernel_mode = LOCK_MAND;
732 if (kernel_mode) flock(fsp->fd, kernel_mode);
738 static BOOL open_match_attributes(connection_struct *conn, char *path, mode_t existing_mode,
739 mode_t new_mode, mode_t *returned_mode)
741 uint32 old_dos_mode, new_dos_mode;
742 uint32 noarch_old_dos_mode, noarch_new_dos_mode;
743 SMB_STRUCT_STAT sbuf;
747 sbuf.st_mode = existing_mode;
748 old_dos_mode = dos_mode(conn, path, &sbuf);
750 sbuf.st_mode = new_mode;
751 new_dos_mode = dos_mode(conn, path, &sbuf);
753 noarch_old_dos_mode = (old_dos_mode & ~FILE_ATTRIBUTE_ARCHIVE);
754 noarch_new_dos_mode = (new_dos_mode & ~FILE_ATTRIBUTE_ARCHIVE);
756 if((noarch_old_dos_mode == 0 && noarch_new_dos_mode != 0) ||
757 (noarch_old_dos_mode != 0 && ((noarch_old_dos_mode & noarch_new_dos_mode) == noarch_old_dos_mode)))
758 *returned_mode = new_mode;
760 *returned_mode = (mode_t)0;
762 DEBUG(10,("open_match_attributes: file %s old_dos_mode = 0x%x, existing_mode = 0%o, new_dos_mode = 0x%x returned_mode = 0%o\n",
764 old_dos_mode, (unsigned int)existing_mode, new_dos_mode, (unsigned int)*returned_mode ));
766 /* If we're mapping SYSTEM and HIDDEN ensure they match. */
767 if (lp_map_system(SNUM(conn))) {
768 if ((old_dos_mode & FILE_ATTRIBUTE_SYSTEM) && !(new_dos_mode & FILE_ATTRIBUTE_SYSTEM))
771 if (lp_map_hidden(SNUM(conn))) {
772 if ((old_dos_mode & FILE_ATTRIBUTE_HIDDEN) && !(new_dos_mode & FILE_ATTRIBUTE_HIDDEN))
778 /****************************************************************************
779 Open a file with a share mode.
780 ****************************************************************************/
782 files_struct *open_file_shared(connection_struct *conn,char *fname, SMB_STRUCT_STAT *psbuf,
783 int share_mode,int ofun, mode_t mode,int oplock_request,
784 int *Access,int *action)
786 return open_file_shared1(conn, fname, psbuf, 0, share_mode, ofun, mode,
787 oplock_request, Access, action);
790 /****************************************************************************
791 Open a file with a share mode.
792 ****************************************************************************/
794 files_struct *open_file_shared1(connection_struct *conn,char *fname, SMB_STRUCT_STAT *psbuf,
795 uint32 desired_access,
796 int share_mode,int ofun, mode_t mode,int oplock_request,
797 int *Access,int *action)
801 int deny_mode = GET_DENY_MODE(share_mode);
802 BOOL allow_share_delete = GET_ALLOW_SHARE_DELETE(share_mode);
803 BOOL delete_on_close = GET_DELETE_ON_CLOSE_FLAG(share_mode);
804 BOOL file_existed = VALID_STAT(*psbuf);
805 BOOL fcbopen = False;
806 BOOL def_acl = False;
809 int num_share_modes = 0;
810 BOOL all_current_opens_are_level_II = False;
811 BOOL fsp_open = False;
812 files_struct *fsp = NULL;
815 mode_t new_mode = (mode_t)0;
818 /* printers are handled completely differently. Most of the passed parameters are
821 *Access = DOS_OPEN_WRONLY;
823 *action = FILE_WAS_CREATED;
824 return print_fsp_open(conn, fname);
827 fsp = file_new(conn);
831 DEBUG(10,("open_file_shared: fname = %s, share_mode = %x, ofun = %x, mode = %o, oplock request = %d\n",
832 fname, share_mode, ofun, (int)mode, oplock_request ));
834 if (!check_name(fname,conn)) {
839 /* ignore any oplock requests if oplocks are disabled */
840 if (!lp_oplocks(SNUM(conn)) || global_client_failed_oplock_break) {
844 /* this is for OS/2 EAs - try and say we don't support them */
845 if (strstr(fname,".+,;=[].")) {
846 unix_ERR_class = ERRDOS;
847 /* OS/2 Workplace shell fix may be main code stream in a later release. */
848 #if 1 /* OS2_WPS_FIX - Recent versions of OS/2 need this. */
849 unix_ERR_code = ERRcannotopen;
850 #else /* OS2_WPS_FIX */
851 unix_ERR_code = ERROR_EAS_NOT_SUPPORTED;
852 #endif /* OS2_WPS_FIX */
854 DEBUG(5,("open_file_shared: OS/2 EA's are not supported.\n"));
859 if ((GET_FILE_OPEN_DISPOSITION(ofun) == FILE_EXISTS_FAIL) && file_existed) {
860 DEBUG(5,("open_file_shared: create new requested for file %s and file already exists.\n",
867 if (CAN_WRITE(conn) && (GET_FILE_CREATE_DISPOSITION(ofun) == FILE_CREATE_IF_NOT_EXIST))
870 if (CAN_WRITE(conn) && (GET_FILE_OPEN_DISPOSITION(ofun) == FILE_EXISTS_TRUNCATE))
873 /* We only care about matching attributes on file exists and truncate. */
874 if (file_existed && (GET_FILE_OPEN_DISPOSITION(ofun) == FILE_EXISTS_TRUNCATE)) {
875 if (!open_match_attributes(conn, fname, psbuf->st_mode, mode, &new_mode)) {
876 DEBUG(5,("open_file_shared: attributes missmatch for file %s (0%o, 0%o)\n",
877 fname, psbuf->st_mode, mode ));
884 if (GET_FILE_OPEN_DISPOSITION(ofun) == FILE_EXISTS_FAIL)
887 /* note that we ignore the append flag as
888 append does not mean the same thing under dos and unix */
890 switch (GET_OPEN_MODE(share_mode)) {
891 case DOS_OPEN_WRONLY:
893 if (desired_access == 0)
894 desired_access = FILE_WRITE_DATA;
899 if (desired_access == 0)
900 desired_access = FILE_READ_DATA|FILE_WRITE_DATA;
904 if (desired_access == 0)
905 desired_access = FILE_READ_DATA|FILE_WRITE_DATA;
909 if (desired_access == 0)
910 desired_access = FILE_READ_DATA;
915 if (GET_FILE_SYNC_OPENMODE(share_mode)) {
920 if (flags != O_RDONLY && file_existed &&
921 (!CAN_WRITE(conn) || IS_DOS_READONLY(dos_mode(conn,fname,psbuf)))) {
923 DEBUG(5,("open_file_shared: read/write access requested for file %s on read only %s\n",
924 fname, !CAN_WRITE(conn) ? "share" : "file" ));
932 if (deny_mode > DENY_NONE && deny_mode!=DENY_FCB) {
933 DEBUG(2,("Invalid deny mode %d on file %s\n",deny_mode,fname));
942 inode = psbuf->st_ino;
944 lock_share_entry(conn, dev, inode);
946 num_share_modes = open_mode_check(conn, fname, dev, inode,
949 &flags, &oplock_request, &all_current_opens_are_level_II);
950 if(num_share_modes == -1) {
953 * This next line is a subtlety we need for MS-Access. If a file open will
954 * fail due to share permissions and also for security (access)
955 * reasons, we need to return the access failed error, not the
956 * share error. This means we must attempt to open the file anyway
957 * in order to get the UNIX access error - even if we're going to
958 * fail the open for share reasons. This is bad, as we're burning
959 * another fd if there are existing locks but there's nothing else
960 * we can do. We also ensure we're not going to create or tuncate
961 * the file as we only want an access decision at this stage. JRA.
964 fsp_open = open_file(fsp,conn,fname,psbuf,
965 flags|(flags2&~(O_TRUNC|O_CREAT)),mode,desired_access);
967 DEBUG(4,("open_file_shared : share_mode deny - calling open_file with \
968 flags=0x%X flags2=0x%X mode=0%o returned %d\n",
969 flags,(flags2&~(O_TRUNC|O_CREAT)),(int)mode,(int)fsp_open ));
971 if (!fsp_open && errno) {
972 unix_ERR_class = ERRDOS;
973 unix_ERR_code = ERRnoaccess;
974 unix_ERR_ntstatus = NT_STATUS_ACCESS_DENIED;
977 unlock_share_entry(conn, dev, inode);
985 * We exit this block with the share entry *locked*.....
990 * Ensure we pay attention to default ACLs on directories if required.
993 if ((flags2 & O_CREAT) && lp_inherit_acls(SNUM(conn)) &&
994 (def_acl = directory_has_default_acl(conn, parent_dirname(fname))))
997 DEBUG(4,("calling open_file with flags=0x%X flags2=0x%X mode=0%o\n",
998 flags,flags2,(int)mode));
1001 * open_file strips any O_TRUNC flags itself.
1004 fsp_open = open_file(fsp,conn,fname,psbuf,flags|flags2,mode,desired_access);
1006 if (!fsp_open && (flags == O_RDWR) && (errno != ENOENT) && fcbopen) {
1007 if((fsp_open = open_file(fsp,conn,fname,psbuf,O_RDONLY,mode,desired_access)) == True)
1013 unlock_share_entry(conn, dev, inode);
1019 * Deal with the race condition where two smbd's detect the file doesn't
1020 * exist and do the create at the same time. One of them will win and
1021 * set a share mode, the other (ie. this one) should check if the
1022 * requested share mode for this create is allowed.
1025 if (!file_existed) {
1028 * Now the file exists and fsp is successfully opened,
1029 * fsp->dev and fsp->inode are valid and should replace the
1030 * dev=0,inode=0 from a non existent file. Spotted by
1031 * Nadav Danieli <nadavd@exanet.com>. JRA.
1037 lock_share_entry_fsp(fsp);
1039 num_share_modes = open_mode_check(conn, fname, dev, inode,
1042 &flags, &oplock_request, &all_current_opens_are_level_II);
1044 if(num_share_modes == -1) {
1045 unlock_share_entry_fsp(fsp);
1052 * If there are any share modes set then the file *did*
1053 * exist. Ensure we return the correct value for action.
1056 if (num_share_modes > 0)
1057 file_existed = True;
1060 * We exit this block with the share entry *locked*.....
1064 /* note that we ignore failure for the following. It is
1065 basically a hack for NFS, and NFS will never set one of
1066 these only read them. Nobody but Samba can ever set a deny
1067 mode and we have already checked our more authoritative
1068 locking database for permission to set this deny mode. If
1069 the kernel refuses the operations then the kernel is wrong */
1070 kernel_flock(fsp, deny_mode);
1073 * At this point onwards, we can guarentee that the share entry
1074 * is locked, whether we created the file or not, and that the
1075 * deny mode is compatible with all current opens.
1079 * If requested, truncate the file.
1082 if (flags2&O_TRUNC) {
1084 * We are modifing the file after open - update the stat struct..
1086 if ((truncate_unless_locked(conn,fsp) == -1) || (SMB_VFS_FSTAT(fsp,fsp->fd,psbuf)==-1)) {
1087 unlock_share_entry_fsp(fsp);
1096 open_mode = DOS_OPEN_RDONLY;
1099 open_mode = DOS_OPEN_RDWR;
1102 open_mode = DOS_OPEN_WRONLY;
1106 fsp->share_mode = SET_DENY_MODE(deny_mode) |
1107 SET_OPEN_MODE(open_mode) |
1108 SET_ALLOW_SHARE_DELETE(allow_share_delete);
1110 DEBUG(10,("open_file_shared : share_mode = %x\n", fsp->share_mode ));
1113 (*Access) = open_mode;
1116 if (file_existed && !(flags2 & O_TRUNC))
1117 *action = FILE_WAS_OPENED;
1119 *action = FILE_WAS_CREATED;
1120 if (file_existed && (flags2 & O_TRUNC))
1121 *action = FILE_WAS_OVERWRITTEN;
1125 * Setup the oplock info in both the shared memory and
1129 if(oplock_request && (num_share_modes == 0) &&
1130 !IS_VETO_OPLOCK_PATH(conn,fname) && set_file_oplock(fsp, oplock_request) ) {
1131 port = global_oplock_port;
1132 } else if (oplock_request && all_current_opens_are_level_II) {
1133 port = global_oplock_port;
1134 oplock_request = LEVEL_II_OPLOCK;
1135 set_file_oplock(fsp, oplock_request);
1141 set_share_mode(fsp, port, oplock_request);
1143 if (delete_on_close) {
1144 NTSTATUS result = set_delete_on_close_internal(fsp, delete_on_close);
1146 if (NT_STATUS_V(result) != NT_STATUS_V(NT_STATUS_OK)) {
1147 /* Remember to delete the mode we just added. */
1148 del_share_mode(fsp, NULL);
1149 unlock_share_entry_fsp(fsp);
1157 * Take care of inherited ACLs on created files - if default ACL not
1161 if (!file_existed && !def_acl) {
1163 int saved_errno = errno; /* We might get ENOSYS in the next call.. */
1165 if (SMB_VFS_FCHMOD_ACL(fsp, fsp->fd, mode) == -1 && errno == ENOSYS)
1166 errno = saved_errno; /* Ignore ENOSYS */
1168 } else if (new_mode) {
1172 /* Attributes need changing. File already existed. */
1175 int saved_errno = errno; /* We might get ENOSYS in the next call.. */
1176 ret = SMB_VFS_FCHMOD_ACL(fsp, fsp->fd, new_mode);
1178 if (ret == -1 && errno == ENOSYS) {
1179 errno = saved_errno; /* Ignore ENOSYS */
1181 DEBUG(5, ("open_file_shared: failed to reset attributes of file %s to 0%o\n",
1182 fname, (int)new_mode));
1183 ret = 0; /* Don't do the fchmod below. */
1187 if ((ret == -1) && (SMB_VFS_FCHMOD(fsp, fsp->fd, new_mode) == -1))
1188 DEBUG(5, ("open_file_shared: failed to reset attributes of file %s to 0%o\n",
1189 fname, (int)new_mode));
1192 unlock_share_entry_fsp(fsp);
1194 conn->num_files_open++;
1199 /****************************************************************************
1200 Open a file for for write to ensure that we can fchmod it.
1201 ****************************************************************************/
1203 files_struct *open_file_fchmod(connection_struct *conn, const char *fname, SMB_STRUCT_STAT *psbuf)
1205 files_struct *fsp = NULL;
1208 if (!VALID_STAT(*psbuf))
1211 fsp = file_new(conn);
1215 /* note! we must use a non-zero desired access or we don't get
1216 a real file descriptor. Oh what a twisted web we weave. */
1217 fsp_open = open_file(fsp,conn,fname,psbuf,O_WRONLY,0,FILE_WRITE_DATA);
1220 * This is not a user visible file open.
1221 * Don't set a share mode and don't increment
1222 * the conn->num_files_open.
1233 /****************************************************************************
1234 Close the fchmod file fd - ensure no locks are lost.
1235 ****************************************************************************/
1237 int close_file_fchmod(files_struct *fsp)
1239 int ret = fd_close(fsp->conn, fsp);
1244 /****************************************************************************
1245 Open a directory from an NT SMB call.
1246 ****************************************************************************/
1248 files_struct *open_directory(connection_struct *conn, char *fname, SMB_STRUCT_STAT *psbuf,
1249 uint32 desired_access, int share_mode, int smb_ofun, mode_t unixmode, int *action)
1251 extern struct current_user current_user;
1252 BOOL got_stat = False;
1253 files_struct *fsp = file_new(conn);
1254 BOOL delete_on_close = GET_DELETE_ON_CLOSE_FLAG(share_mode);
1259 if (VALID_STAT(*psbuf))
1262 if (got_stat && (GET_FILE_OPEN_DISPOSITION(smb_ofun) == FILE_EXISTS_FAIL)) {
1264 errno = EEXIST; /* Setup so correct error is returned to client. */
1268 if (GET_FILE_CREATE_DISPOSITION(smb_ofun) == FILE_CREATE_IF_NOT_EXIST) {
1272 if(!S_ISDIR(psbuf->st_mode)) {
1273 DEBUG(0,("open_directory: %s is not a directory !\n", fname ));
1278 *action = FILE_WAS_OPENED;
1283 * Try and create the directory.
1286 if(!CAN_WRITE(conn)) {
1287 DEBUG(2,("open_directory: failing create on read-only share\n"));
1293 if(vfs_MkDir(conn,fname, unix_mode(conn,aDIR, fname)) < 0) {
1294 DEBUG(2,("open_directory: unable to create %s. Error was %s\n",
1295 fname, strerror(errno) ));
1300 if(SMB_VFS_STAT(conn,fname, psbuf) != 0) {
1305 *action = FILE_WAS_CREATED;
1311 * Don't create - just check that it *was* a directory.
1315 DEBUG(3,("open_directory: unable to stat name = %s. Error was %s\n",
1316 fname, strerror(errno) ));
1321 if(!S_ISDIR(psbuf->st_mode)) {
1322 DEBUG(0,("open_directory: %s is not a directory !\n", fname ));
1327 *action = FILE_WAS_OPENED;
1330 DEBUG(5,("open_directory: opening directory %s\n", fname));
1333 * Setup the files_struct for it.
1336 fsp->mode = psbuf->st_mode;
1337 fsp->inode = psbuf->st_ino;
1338 fsp->dev = psbuf->st_dev;
1339 fsp->size = psbuf->st_size;
1340 fsp->vuid = current_user.vuid;
1342 fsp->can_lock = True;
1343 fsp->can_read = False;
1344 fsp->can_write = False;
1345 fsp->share_mode = share_mode;
1346 fsp->desired_access = desired_access;
1347 fsp->print_file = False;
1348 fsp->modified = False;
1349 fsp->oplock_type = NO_OPLOCK;
1350 fsp->sent_oplock_break = NO_BREAK_SENT;
1351 fsp->is_directory = True;
1352 fsp->is_stat = False;
1353 fsp->directory_delete_on_close = False;
1354 string_set(&fsp->fsp_name,fname);
1356 if (delete_on_close) {
1357 NTSTATUS result = set_delete_on_close_internal(fsp, delete_on_close);
1359 if (NT_STATUS_V(result) != NT_STATUS_V(NT_STATUS_OK)) {
1364 conn->num_files_open++;
1369 /****************************************************************************
1370 Open a pseudo-file (no locking checks - a 'stat' open).
1371 ****************************************************************************/
1373 files_struct *open_file_stat(connection_struct *conn, char *fname, SMB_STRUCT_STAT *psbuf)
1375 extern struct current_user current_user;
1376 files_struct *fsp = NULL;
1378 if (!VALID_STAT(*psbuf))
1381 /* Can't 'stat' open directories. */
1382 if(S_ISDIR(psbuf->st_mode))
1385 fsp = file_new(conn);
1389 DEBUG(5,("open_file_stat: 'opening' file %s\n", fname));
1392 * Setup the files_struct for it.
1395 fsp->mode = psbuf->st_mode;
1397 * Don't store dev or inode, we don't want any iterator
1400 fsp->inode = (SMB_INO_T)0;
1401 fsp->dev = (SMB_DEV_T)0;
1402 fsp->size = psbuf->st_size;
1403 fsp->vuid = current_user.vuid;
1405 fsp->can_lock = False;
1406 fsp->can_read = False;
1407 fsp->can_write = False;
1408 fsp->share_mode = 0;
1409 fsp->desired_access = 0;
1410 fsp->print_file = False;
1411 fsp->modified = False;
1412 fsp->oplock_type = NO_OPLOCK;
1413 fsp->sent_oplock_break = NO_BREAK_SENT;
1414 fsp->is_directory = False;
1415 fsp->is_stat = True;
1416 fsp->directory_delete_on_close = False;
1417 string_set(&fsp->fsp_name,fname);
1419 conn->num_files_open++;