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 uint16 global_smbpid;
27 extern BOOL global_client_failed_oplock_break;
29 /****************************************************************************
30 fd support routines - attempt to do a dos_open.
31 ****************************************************************************/
33 static int fd_open(struct connection_struct *conn, const char *fname,
34 int flags, mode_t mode)
38 if (!lp_symlinks(SNUM(conn)))
42 fd = SMB_VFS_OPEN(conn,fname,flags,mode);
44 DEBUG(10,("fd_open: name %s, flags = 0%o mode = 0%o, fd = %d. %s\n", fname,
45 flags, (int)mode, fd, (fd == -1) ? strerror(errno) : "" ));
50 /****************************************************************************
51 Close the file associated with a fsp.
52 ****************************************************************************/
54 int fd_close(struct connection_struct *conn, files_struct *fsp)
57 return 0; /* what we used to call a stat open. */
58 return fd_close_posix(conn, fsp);
62 /****************************************************************************
63 Check a filename for the pipe string.
64 ****************************************************************************/
66 static void check_for_pipe(const char *fname)
68 /* special case of pipe opens */
70 StrnCpy(s,fname,sizeof(s)-1);
72 if (strstr(s,"pipe/")) {
73 DEBUG(3,("Rejecting named pipe open for %s\n",fname));
74 unix_ERR_class = ERRSRV;
75 unix_ERR_code = ERRaccess;
76 unix_ERR_ntstatus = NT_STATUS_ACCESS_DENIED;
80 /****************************************************************************
82 ****************************************************************************/
84 static BOOL open_file(files_struct *fsp,connection_struct *conn,
85 const char *fname,SMB_STRUCT_STAT *psbuf,int flags,mode_t mode, uint32 desired_access)
87 extern struct current_user current_user;
88 int accmode = (flags & O_ACCMODE);
89 int local_flags = flags;
92 fsp->oplock_type = NO_OPLOCK;
95 /* Check permissions */
98 * This code was changed after seeing a client open request
99 * containing the open mode of (DENY_WRITE/read-only) with
100 * the 'create if not exist' bit set. The previous code
101 * would fail to open the file read only on a read-only share
102 * as it was checking the flags parameter directly against O_RDONLY,
103 * this was failing as the flags parameter was set to O_RDONLY|O_CREAT.
107 if (!CAN_WRITE(conn)) {
108 /* It's a read-only share - fail if we wanted to write. */
109 if(accmode != O_RDONLY) {
110 DEBUG(3,("Permission denied opening %s\n",fname));
111 check_for_pipe(fname);
113 } else if(flags & O_CREAT) {
114 /* We don't want to write - but we must make sure that O_CREAT
115 doesn't create the file if we have write access into the
119 local_flags &= ~O_CREAT;
124 * This little piece of insanity is inspired by the
125 * fact that an NT client can open a file for O_RDONLY,
126 * but set the create disposition to FILE_EXISTS_TRUNCATE.
127 * If the client *can* write to the file, then it expects to
128 * truncate the file, even though it is opening for readonly.
129 * Quicken uses this stupid trick in backup file creation...
130 * Thanks *greatly* to "David W. Chapman Jr." <dwcjr@inethouston.net>
131 * for helping track this one down. It didn't bite us in 2.0.x
132 * as we always opened files read-write in that release. JRA.
135 if ((accmode == O_RDONLY) && ((flags & O_TRUNC) == O_TRUNC)) {
136 DEBUG(10,("open_file: truncate requested on read-only open for file %s\n",fname ));
137 local_flags = (flags & ~O_ACCMODE)|O_RDWR;
140 if ((desired_access & (FILE_READ_DATA|FILE_WRITE_DATA|FILE_APPEND_DATA|FILE_EXECUTE)) ||
141 (local_flags & O_CREAT) || ((local_flags & O_TRUNC) == O_TRUNC) ) {
144 * We can't actually truncate here as the file may be locked.
145 * open_file_shared will take care of the truncate later. JRA.
148 local_flags &= ~O_TRUNC;
150 #if defined(O_NONBLOCK) && defined(S_ISFIFO)
152 * We would block on opening a FIFO with no one else on the
153 * other end. Do what we used to do and add O_NONBLOCK to the
157 if (VALID_STAT(*psbuf) && S_ISFIFO(psbuf->st_mode))
158 local_flags |= O_NONBLOCK;
161 /* Don't create files with Microsoft wildcard characters. */
162 if ((local_flags & O_CREAT) && !VALID_STAT(*psbuf) && ms_has_wild(fname)) {
163 unix_ERR_class = ERRDOS;
164 unix_ERR_code = ERRinvalidname;
165 unix_ERR_ntstatus = NT_STATUS_OBJECT_NAME_INVALID;
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->file_pid = global_smbpid;
221 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 /*******************************************************************
246 return True if the filename is one of the special executable types
247 ********************************************************************/
249 static BOOL is_executable(const char *fname)
251 if ((fname = strrchr_m(fname,'.'))) {
252 if (strequal(fname,".com") ||
253 strequal(fname,".dll") ||
254 strequal(fname,".exe") ||
255 strequal(fname,".sym")) {
262 enum {AFAIL,AREAD,AWRITE,AALL};
264 /*******************************************************************
265 reproduce the share mode access table
266 this is horrendoously complex, and really can't be justified on any
267 rational grounds except that this is _exactly_ what NT does. See
268 the DENY1 and DENY2 tests in smbtorture for a comprehensive set of
270 ********************************************************************/
271 static int access_table(int new_deny,int old_deny,int old_mode,
272 BOOL same_pid, BOOL isexe)
274 if (new_deny == DENY_ALL || old_deny == DENY_ALL) return(AFAIL);
277 if (isexe && old_mode == DOS_OPEN_RDONLY &&
278 old_deny == DENY_DOS && new_deny == DENY_READ) {
281 if (!isexe && old_mode == DOS_OPEN_RDONLY &&
282 old_deny == DENY_DOS && new_deny == DENY_DOS) {
285 if (new_deny == DENY_FCB && old_deny == DENY_DOS) {
286 if (isexe) return AFAIL;
287 if (old_mode == DOS_OPEN_RDONLY) return AFAIL;
290 if (old_mode == DOS_OPEN_RDONLY && old_deny == DENY_DOS) {
291 if (new_deny == DENY_FCB || new_deny == DENY_READ) {
292 if (isexe) return AREAD;
296 if (old_deny == DENY_FCB) {
297 if (new_deny == DENY_DOS || new_deny == DENY_FCB) return AALL;
302 if (old_deny == DENY_DOS || new_deny == DENY_DOS ||
303 old_deny == DENY_FCB || new_deny == DENY_FCB) {
305 if (old_deny == DENY_FCB || new_deny == DENY_FCB) {
308 if (old_deny == DENY_DOS) {
309 if (new_deny == DENY_READ &&
310 (old_mode == DOS_OPEN_RDONLY ||
311 old_mode == DOS_OPEN_RDWR)) {
314 if (new_deny == DENY_WRITE &&
315 (old_mode == DOS_OPEN_WRONLY ||
316 old_mode == DOS_OPEN_RDWR)) {
321 if (old_deny == DENY_NONE) return AALL;
322 if (old_deny == DENY_READ) return AWRITE;
323 if (old_deny == DENY_WRITE) return AREAD;
325 /* it isn't a exe, dll, sym or com file */
326 if (old_deny == new_deny && same_pid)
329 if (old_deny == DENY_READ || new_deny == DENY_READ) return AFAIL;
330 if (old_mode == DOS_OPEN_RDONLY) return(AREAD);
338 if (old_deny==DENY_WRITE && old_mode==DOS_OPEN_RDONLY) return(AREAD);
339 if (old_deny==DENY_READ && old_mode==DOS_OPEN_RDONLY) return(AWRITE);
340 if (old_deny==DENY_NONE && old_mode==DOS_OPEN_RDONLY) return(AALL);
343 if (old_deny==DENY_WRITE && old_mode==DOS_OPEN_WRONLY) return(AREAD);
344 if (old_deny==DENY_READ && old_mode==DOS_OPEN_WRONLY) return(AWRITE);
345 if (old_deny==DENY_NONE && old_mode==DOS_OPEN_WRONLY) return(AALL);
348 if (old_deny==DENY_WRITE) return(AREAD);
349 if (old_deny==DENY_READ) return(AWRITE);
350 if (old_deny==DENY_NONE) return(AALL);
357 /****************************************************************************
358 check if we can open a file with a share mode
359 ****************************************************************************/
361 static BOOL check_share_mode(connection_struct *conn, share_mode_entry *share, int share_mode, uint32 desired_access,
362 const char *fname, BOOL fcbopen, int *flags)
364 int deny_mode = GET_DENY_MODE(share_mode);
365 int old_open_mode = GET_OPEN_MODE(share->share_mode);
366 int old_deny_mode = GET_DENY_MODE(share->share_mode);
369 * share modes = false means don't bother to check for
370 * DENY mode conflict. This is a *really* bad idea :-). JRA.
373 if(!lp_share_modes(SNUM(conn)))
377 * Don't allow any opens once the delete on close flag has been
381 if (GET_DELETE_ON_CLOSE_FLAG(share->share_mode)) {
382 DEBUG(5,("check_share_mode: Failing open on file %s as delete on close flag is set.\n",
384 /* Use errno to map to correct error. */
385 unix_ERR_class = SMB_SUCCESS;
387 unix_ERR_ntstatus = NT_STATUS_OK;
391 /* this is a nasty hack, but necessary until we rewrite our open
392 handling to use a NTCreateX call as the basic call.
393 NT may open a file with neither read nor write access, and in
394 this case it expects the open not to conflict with any
395 existing deny modes. This happens (for example) during a
396 "xcopy /o" where the second file descriptor is used for
402 * This is a bit wierd - the test for desired access not having the
403 * critical bits seems seems odd. Firstly, if both opens have no
404 * critical bits then always ignore. Then check the "allow delete"
405 * then check for either. This probably isn't quite right yet but
406 * gets us much closer. JRA.
410 * If desired_access doesn't contain READ_DATA,WRITE_DATA,APPEND_DATA or EXECUTE
411 * and the existing desired_acces then share modes don't conflict.
414 if ( !(desired_access & (FILE_READ_DATA|FILE_WRITE_DATA|FILE_APPEND_DATA|FILE_EXECUTE)) &&
415 !(share->desired_access & (FILE_READ_DATA|FILE_WRITE_DATA|FILE_APPEND_DATA|FILE_EXECUTE)) ) {
418 * Wrinkle discovered by smbtorture....
419 * If both are non-io open and requester is asking for delete and current open has delete access
420 * but neither open has allowed file share delete then deny.... this is very strange and
421 * seems to be the only case in which non-io opens conflict. JRA.
424 if ((desired_access & DELETE_ACCESS) && (share->desired_access & DELETE_ACCESS) &&
425 (!GET_ALLOW_SHARE_DELETE(share->share_mode) || !GET_ALLOW_SHARE_DELETE(share_mode))) {
426 DEBUG(5,("check_share_mode: Failing open on file %s as delete access requests conflict.\n",
428 unix_ERR_class = ERRDOS;
429 unix_ERR_code = ERRbadshare;
430 unix_ERR_ntstatus = NT_STATUS_SHARING_VIOLATION;
435 DEBUG(5,("check_share_mode: Allowing open on file %s as both desired access (0x%x) \
436 and existing desired access (0x%x) are non-data opens\n",
437 fname, (unsigned int)desired_access, (unsigned int)share->desired_access ));
442 * If delete access was requested and the existing share mode doesn't have
443 * ALLOW_SHARE_DELETE then deny.
446 if ((desired_access & DELETE_ACCESS) && !GET_ALLOW_SHARE_DELETE(share->share_mode)) {
447 DEBUG(5,("check_share_mode: Failing open on file %s as delete access requested and allow share delete not set.\n",
449 unix_ERR_class = ERRDOS;
450 unix_ERR_code = ERRbadshare;
451 unix_ERR_ntstatus = NT_STATUS_SHARING_VIOLATION;
457 * The inverse of the above.
458 * If delete access was granted and the new share mode doesn't have
459 * ALLOW_SHARE_DELETE then deny.
462 if ((share->desired_access & DELETE_ACCESS) && !GET_ALLOW_SHARE_DELETE(share_mode)) {
463 DEBUG(5,("check_share_mode: Failing open on file %s as delete access granted and allow share delete not requested.\n",
465 unix_ERR_class = ERRDOS;
466 unix_ERR_code = ERRbadshare;
467 unix_ERR_ntstatus = NT_STATUS_SHARING_VIOLATION;
473 * If desired_access doesn't contain READ_DATA,WRITE_DATA,APPEND_DATA or EXECUTE
474 * then share modes don't conflict. Likewise with existing desired access.
477 if ( !(desired_access & (FILE_READ_DATA|FILE_WRITE_DATA|FILE_APPEND_DATA|FILE_EXECUTE)) ||
478 !(share->desired_access & (FILE_READ_DATA|FILE_WRITE_DATA|FILE_APPEND_DATA|FILE_EXECUTE)) ) {
479 DEBUG(5,("check_share_mode: Allowing open on file %s as desired access (0x%x) doesn't conflict with\
480 existing desired access (0x%x).\n", fname, (unsigned int)desired_access, (unsigned int)share->desired_access ));
485 int access_allowed = access_table(deny_mode,old_deny_mode,old_open_mode,
486 (share->pid == sys_getpid()),is_executable(fname));
488 if ((access_allowed == AFAIL) ||
489 (!fcbopen && (access_allowed == AREAD && *flags == O_RDWR)) ||
490 (access_allowed == AREAD && *flags != O_RDONLY) ||
491 (access_allowed == AWRITE && *flags != O_WRONLY)) {
493 DEBUG(2,("Share violation on file (%d,%d,%d,%d,%s,fcbopen = %d, flags = %d) = %d\n",
494 deny_mode,old_deny_mode,old_open_mode,
495 (int)share->pid,fname, fcbopen, *flags, access_allowed));
497 unix_ERR_class = ERRDOS;
498 unix_ERR_code = ERRbadshare;
499 unix_ERR_ntstatus = NT_STATUS_SHARING_VIOLATION;
504 if (access_allowed == AREAD)
507 if (access_allowed == AWRITE)
516 #if defined(DEVELOPER)
517 static void validate_my_share_entries(int num, share_mode_entry *share_entry)
521 if (share_entry->pid != sys_getpid())
524 fsp = file_find_dif(share_entry->dev, share_entry->inode, share_entry->share_file_id);
526 DEBUG(0,("validate_my_share_entries: PANIC : %s\n", share_mode_str(num, share_entry) ));
527 smb_panic("validate_my_share_entries: Cannot match a share entry with an open file\n");
530 if (((uint16)fsp->oplock_type) != share_entry->op_type) {
532 DEBUG(0,("validate_my_share_entries: PANIC : %s\n", share_mode_str(num, share_entry) ));
533 slprintf(str, sizeof(str)-1, "validate_my_share_entries: file %s, oplock_type = 0x%x, op_type = 0x%x\n",
534 fsp->fsp_name, (unsigned int)fsp->oplock_type, (unsigned int)share_entry->op_type );
540 /****************************************************************************
541 Deal with open deny mode and oplock break processing.
542 Invarient: Share mode must be locked on entry and exit.
543 Returns -1 on error, or number of share modes on success (may be zero).
544 ****************************************************************************/
546 static int open_mode_check(connection_struct *conn, const char *fname, SMB_DEV_T dev,
548 uint32 desired_access,
549 int share_mode, int *p_flags, int *p_oplock_request,
550 BOOL *p_all_current_opens_are_level_II)
554 int oplock_contention_count = 0;
555 share_mode_entry *old_shares = 0;
556 BOOL fcbopen = False;
559 if(GET_OPEN_MODE(share_mode) == DOS_OPEN_FCB)
562 num_share_modes = get_share_modes(conn, dev, inode, &old_shares);
564 if(num_share_modes == 0)
568 * Check if the share modes will give us access.
572 share_mode_entry broken_entry;
574 broke_oplock = False;
575 *p_all_current_opens_are_level_II = True;
577 for(i = 0; i < num_share_modes; i++) {
578 share_mode_entry *share_entry = &old_shares[i];
580 #if defined(DEVELOPER)
581 validate_my_share_entries(i, share_entry);
585 * By observation of NetBench, oplocks are broken *before* share
586 * modes are checked. This allows a file to be closed by the client
587 * if the share mode would deny access and the client has an oplock.
588 * Check if someone has an oplock on this file. If so we must break
589 * it before continuing.
592 if((*p_oplock_request && EXCLUSIVE_OPLOCK_TYPE(share_entry->op_type)) ||
593 (!*p_oplock_request && (share_entry->op_type != NO_OPLOCK))) {
597 DEBUG(5,("open_mode_check: oplock_request = %d, breaking oplock (%x) on file %s, \
598 dev = %x, inode = %.0f\n", *p_oplock_request, share_entry->op_type, fname, (unsigned int)dev, (double)inode));
600 /* Ensure the reply for the open uses the correct sequence number. */
601 /* This isn't a real deferred packet as it's response will also increment
604 srv_defer_sign_response(get_current_mid());
606 /* Oplock break - unlock to request it. */
607 unlock_share_entry(conn, dev, inode);
609 opb_ret = request_oplock_break(share_entry, False);
612 lock_share_entry(conn, dev, inode);
614 if(opb_ret == False) {
615 DEBUG(0,("open_mode_check: FAILED when breaking oplock (%x) on file %s, \
616 dev = %x, inode = %.0f\n", old_shares[i].op_type, fname, (unsigned int)dev, (double)inode));
617 SAFE_FREE(old_shares);
619 unix_ERR_class = ERRDOS;
620 unix_ERR_code = ERRbadshare;
621 unix_ERR_ntstatus = NT_STATUS_SHARING_VIOLATION;
626 broken_entry = *share_entry;
629 } else if (!LEVEL_II_OPLOCK_TYPE(share_entry->op_type)) {
630 *p_all_current_opens_are_level_II = False;
633 /* someone else has a share lock on it, check to see if we can too */
634 if (!check_share_mode(conn, share_entry, share_mode, desired_access,
635 fname, fcbopen, p_flags)) {
636 SAFE_FREE(old_shares);
644 SAFE_FREE(old_shares);
645 num_share_modes = get_share_modes(conn, dev, inode, &old_shares);
646 oplock_contention_count++;
648 /* Paranoia check that this is no longer an exlusive entry. */
649 for(i = 0; i < num_share_modes; i++) {
650 share_mode_entry *share_entry = &old_shares[i];
652 if (share_modes_identical(&broken_entry, share_entry) &&
653 EXCLUSIVE_OPLOCK_TYPE(share_entry->op_type) ) {
656 * This should not happen. The target left this oplock
657 * as exlusive.... The process *must* be dead....
660 DEBUG(0,("open_mode_check: exlusive oplock left by process %d after break ! For file %s, \
661 dev = %x, inode = %.0f. Deleting it to continue...\n", (int)broken_entry.pid, fname, (unsigned int)dev, (double)inode));
663 if (process_exists(broken_entry.pid)) {
664 DEBUG(0,("open_mode_check: Existent process %lu left active oplock.\n",
665 (unsigned long)broken_entry.pid ));
668 if (del_share_entry(dev, inode, &broken_entry, NULL) == -1) {
670 unix_ERR_class = ERRDOS;
671 unix_ERR_code = ERRbadshare;
672 unix_ERR_ntstatus = NT_STATUS_SHARING_VIOLATION;
677 * We must reload the share modes after deleting the
678 * other process's entry.
681 SAFE_FREE(old_shares);
682 num_share_modes = get_share_modes(conn, dev, inode, &old_shares);
685 } /* end for paranoia... */
686 } /* end if broke_oplock */
688 } while(broke_oplock);
691 SAFE_FREE(old_shares);
694 * Refuse to grant an oplock in case the contention limit is
695 * reached when going through the lock list multiple times.
698 if(oplock_contention_count >= lp_oplock_contention_limit(SNUM(conn))) {
699 *p_oplock_request = 0;
700 DEBUG(4,("open_mode_check: oplock contention = %d. Not granting oplock.\n",
701 oplock_contention_count ));
704 return num_share_modes;
707 /****************************************************************************
708 set a kernel flock on a file for NFS interoperability
709 this requires a patch to Linux
710 ****************************************************************************/
711 static void kernel_flock(files_struct *fsp, int deny_mode)
713 #if HAVE_KERNEL_SHARE_MODES
715 if (deny_mode == DENY_READ) kernel_mode = LOCK_MAND|LOCK_WRITE;
716 else if (deny_mode == DENY_WRITE) kernel_mode = LOCK_MAND|LOCK_READ;
717 else if (deny_mode == DENY_ALL) kernel_mode = LOCK_MAND;
718 if (kernel_mode) flock(fsp->fd, kernel_mode);
724 static BOOL open_match_attributes(connection_struct *conn, const char *path, uint32 old_dos_mode, uint32 new_dos_mode,
725 mode_t existing_mode, mode_t new_mode, mode_t *returned_mode)
727 uint32 noarch_old_dos_mode, noarch_new_dos_mode;
729 noarch_old_dos_mode = (old_dos_mode & ~FILE_ATTRIBUTE_ARCHIVE);
730 noarch_new_dos_mode = (new_dos_mode & ~FILE_ATTRIBUTE_ARCHIVE);
732 if((noarch_old_dos_mode == 0 && noarch_new_dos_mode != 0) ||
733 (noarch_old_dos_mode != 0 && ((noarch_old_dos_mode & noarch_new_dos_mode) == noarch_old_dos_mode)))
734 *returned_mode = new_mode;
736 *returned_mode = (mode_t)0;
738 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",
740 old_dos_mode, (unsigned int)existing_mode, new_dos_mode, (unsigned int)*returned_mode ));
742 /* If we're mapping SYSTEM and HIDDEN ensure they match. */
743 if (lp_map_system(SNUM(conn)) || lp_store_dos_attributes(SNUM(conn))) {
744 if ((old_dos_mode & FILE_ATTRIBUTE_SYSTEM) && !(new_dos_mode & FILE_ATTRIBUTE_SYSTEM))
747 if (lp_map_hidden(SNUM(conn)) || lp_store_dos_attributes(SNUM(conn))) {
748 if ((old_dos_mode & FILE_ATTRIBUTE_HIDDEN) && !(new_dos_mode & FILE_ATTRIBUTE_HIDDEN))
754 /****************************************************************************
755 Open a file with a share mode.
756 ****************************************************************************/
758 files_struct *open_file_shared(connection_struct *conn,char *fname, SMB_STRUCT_STAT *psbuf,
759 int share_mode,int ofun, uint32 new_dos_mode, int oplock_request,
760 int *Access,int *action)
762 return open_file_shared1(conn, fname, psbuf, 0, share_mode, ofun, new_dos_mode,
763 oplock_request, Access, action);
766 /****************************************************************************
767 Open a file with a share mode.
768 ****************************************************************************/
770 files_struct *open_file_shared1(connection_struct *conn,char *fname, SMB_STRUCT_STAT *psbuf,
771 uint32 desired_access,
772 int share_mode,int ofun, uint32 new_dos_mode,
774 int *Access,int *paction)
778 int deny_mode = GET_DENY_MODE(share_mode);
779 BOOL allow_share_delete = GET_ALLOW_SHARE_DELETE(share_mode);
780 BOOL delete_on_close = GET_DELETE_ON_CLOSE_FLAG(share_mode);
781 BOOL file_existed = VALID_STAT(*psbuf);
782 BOOL fcbopen = False;
783 BOOL def_acl = False;
786 int num_share_modes = 0;
787 BOOL all_current_opens_are_level_II = False;
788 BOOL fsp_open = False;
789 files_struct *fsp = NULL;
792 mode_t new_mode = (mode_t)0;
794 uint32 existing_dos_mode = 0;
795 /* We add aARCH to this as this mode is only used if the file is created new. */
796 mode_t mode = unix_mode(conn,new_dos_mode | aARCH,fname);
799 /* printers are handled completely differently. Most of the passed parameters are
802 *Access = DOS_OPEN_WRONLY;
804 *paction = FILE_WAS_CREATED;
805 return print_fsp_open(conn, fname);
808 fsp = file_new(conn);
812 DEBUG(10,("open_file_shared: fname = %s, dos_attrs = %x, share_mode = %x, ofun = %x, mode = %o, oplock request = %d\n",
813 fname, new_dos_mode, share_mode, ofun, (int)mode, oplock_request ));
815 if (!check_name(fname,conn)) {
820 new_dos_mode &= SAMBA_ATTRIBUTES_MASK;
822 existing_dos_mode = dos_mode(conn, fname, psbuf);
825 /* ignore any oplock requests if oplocks are disabled */
826 if (!lp_oplocks(SNUM(conn)) || global_client_failed_oplock_break) {
830 /* this is for OS/2 EAs - try and say we don't support them */
831 if (strstr(fname,".+,;=[].")) {
832 unix_ERR_class = ERRDOS;
833 /* OS/2 Workplace shell fix may be main code stream in a later release. */
834 #if 1 /* OS2_WPS_FIX - Recent versions of OS/2 need this. */
835 unix_ERR_code = ERRcannotopen;
836 #else /* OS2_WPS_FIX */
837 unix_ERR_code = ERROR_EAS_NOT_SUPPORTED;
838 #endif /* OS2_WPS_FIX */
840 DEBUG(5,("open_file_shared: OS/2 EA's are not supported.\n"));
845 if ((GET_FILE_OPEN_DISPOSITION(ofun) == FILE_EXISTS_FAIL) && file_existed) {
846 DEBUG(5,("open_file_shared: create new requested for file %s and file already exists.\n",
849 if (S_ISDIR(psbuf->st_mode)) {
857 if (CAN_WRITE(conn) && (GET_FILE_CREATE_DISPOSITION(ofun) == FILE_CREATE_IF_NOT_EXIST))
860 if (CAN_WRITE(conn) && (GET_FILE_OPEN_DISPOSITION(ofun) == FILE_EXISTS_TRUNCATE))
863 /* We only care about matching attributes on file exists and truncate. */
864 if (file_existed && (GET_FILE_OPEN_DISPOSITION(ofun) == FILE_EXISTS_TRUNCATE)) {
865 if (!open_match_attributes(conn, fname, existing_dos_mode, new_dos_mode,
866 psbuf->st_mode, mode, &new_mode)) {
867 DEBUG(5,("open_file_shared: attributes missmatch for file %s (%x %x) (0%o, 0%o)\n",
868 fname, existing_dos_mode, new_dos_mode,
869 (int)psbuf->st_mode, (int)mode ));
876 if (GET_FILE_OPEN_DISPOSITION(ofun) == FILE_EXISTS_FAIL)
879 /* note that we ignore the append flag as
880 append does not mean the same thing under dos and unix */
882 switch (GET_OPEN_MODE(share_mode)) {
883 case DOS_OPEN_WRONLY:
885 if (desired_access == 0)
886 desired_access = FILE_WRITE_DATA;
891 if (desired_access == 0)
892 desired_access = FILE_READ_DATA|FILE_WRITE_DATA;
896 if (desired_access == 0)
897 desired_access = FILE_READ_DATA|FILE_WRITE_DATA;
901 if (desired_access == 0)
902 desired_access = FILE_READ_DATA;
907 if (GET_FILE_SYNC_OPENMODE(share_mode)) {
912 if (flags != O_RDONLY && file_existed &&
913 (!CAN_WRITE(conn) || IS_DOS_READONLY(existing_dos_mode))) {
915 DEBUG(5,("open_file_shared: read/write access requested for file %s on read only %s\n",
916 fname, !CAN_WRITE(conn) ? "share" : "file" ));
924 if (deny_mode > DENY_NONE && deny_mode!=DENY_FCB) {
925 DEBUG(2,("Invalid deny mode %d on file %s\n",deny_mode,fname));
934 inode = psbuf->st_ino;
936 lock_share_entry(conn, dev, inode);
938 num_share_modes = open_mode_check(conn, fname, dev, inode,
941 &flags, &oplock_request, &all_current_opens_are_level_II);
942 if(num_share_modes == -1) {
945 * This next line is a subtlety we need for MS-Access. If a file open will
946 * fail due to share permissions and also for security (access)
947 * reasons, we need to return the access failed error, not the
948 * share error. This means we must attempt to open the file anyway
949 * in order to get the UNIX access error - even if we're going to
950 * fail the open for share reasons. This is bad, as we're burning
951 * another fd if there are existing locks but there's nothing else
952 * we can do. We also ensure we're not going to create or tuncate
953 * the file as we only want an access decision at this stage. JRA.
956 fsp_open = open_file(fsp,conn,fname,psbuf,
957 flags|(flags2&~(O_TRUNC|O_CREAT)),mode,desired_access);
959 DEBUG(4,("open_file_shared : share_mode deny - calling open_file with \
960 flags=0x%X flags2=0x%X mode=0%o returned %d\n",
961 flags,(flags2&~(O_TRUNC|O_CREAT)),(int)mode,(int)fsp_open ));
963 if (!fsp_open && errno) {
964 unix_ERR_class = ERRDOS;
965 unix_ERR_code = ERRnoaccess;
966 unix_ERR_ntstatus = NT_STATUS_ACCESS_DENIED;
969 unlock_share_entry(conn, dev, inode);
974 * We have detected a sharing violation here
975 * so return the correct error code
977 unix_ERR_class = ERRDOS;
978 unix_ERR_code = ERRbadshare;
979 unix_ERR_ntstatus = NT_STATUS_SHARING_VIOLATION;
984 * We exit this block with the share entry *locked*.....
989 * Ensure we pay attention to default ACLs on directories if required.
992 if ((flags2 & O_CREAT) && lp_inherit_acls(SNUM(conn)) &&
993 (def_acl = directory_has_default_acl(conn, parent_dirname(fname))))
996 DEBUG(4,("calling open_file with flags=0x%X flags2=0x%X mode=0%o\n",
997 flags,flags2,(int)mode));
1000 * open_file strips any O_TRUNC flags itself.
1003 fsp_open = open_file(fsp,conn,fname,psbuf,flags|flags2,mode,desired_access);
1005 if (!fsp_open && (flags == O_RDWR) && (errno != ENOENT) && fcbopen) {
1006 if((fsp_open = open_file(fsp,conn,fname,psbuf,O_RDONLY,mode,desired_access)) == True)
1012 unlock_share_entry(conn, dev, inode);
1018 * Deal with the race condition where two smbd's detect the file doesn't
1019 * exist and do the create at the same time. One of them will win and
1020 * set a share mode, the other (ie. this one) should check if the
1021 * requested share mode for this create is allowed.
1024 if (!file_existed) {
1027 * Now the file exists and fsp is successfully opened,
1028 * fsp->dev and fsp->inode are valid and should replace the
1029 * dev=0,inode=0 from a non existent file. Spotted by
1030 * Nadav Danieli <nadavd@exanet.com>. JRA.
1036 lock_share_entry_fsp(fsp);
1038 num_share_modes = open_mode_check(conn, fname, dev, inode,
1041 &flags, &oplock_request, &all_current_opens_are_level_II);
1043 if(num_share_modes == -1) {
1044 unlock_share_entry_fsp(fsp);
1048 * We have detected a sharing violation here, so
1049 * return the correct code.
1051 unix_ERR_class = ERRDOS;
1052 unix_ERR_code = ERRbadshare;
1053 unix_ERR_ntstatus = NT_STATUS_SHARING_VIOLATION;
1058 * If there are any share modes set then the file *did*
1059 * exist. Ensure we return the correct value for action.
1062 if (num_share_modes > 0)
1063 file_existed = True;
1066 * We exit this block with the share entry *locked*.....
1070 /* note that we ignore failure for the following. It is
1071 basically a hack for NFS, and NFS will never set one of
1072 these only read them. Nobody but Samba can ever set a deny
1073 mode and we have already checked our more authoritative
1074 locking database for permission to set this deny mode. If
1075 the kernel refuses the operations then the kernel is wrong */
1076 kernel_flock(fsp, deny_mode);
1079 * At this point onwards, we can guarentee that the share entry
1080 * is locked, whether we created the file or not, and that the
1081 * deny mode is compatible with all current opens.
1085 * If requested, truncate the file.
1088 if (flags2&O_TRUNC) {
1090 * We are modifing the file after open - update the stat struct..
1092 if ((SMB_VFS_FTRUNCATE(fsp,fsp->fd,0) == -1) || (SMB_VFS_FSTAT(fsp,fsp->fd,psbuf)==-1)) {
1093 unlock_share_entry_fsp(fsp);
1102 open_mode = DOS_OPEN_RDONLY;
1105 open_mode = DOS_OPEN_RDWR;
1108 open_mode = DOS_OPEN_WRONLY;
1112 fsp->share_mode = SET_DENY_MODE(deny_mode) |
1113 SET_OPEN_MODE(open_mode) |
1114 SET_ALLOW_SHARE_DELETE(allow_share_delete);
1116 DEBUG(10,("open_file_shared : share_mode = %x\n", fsp->share_mode ));
1119 (*Access) = open_mode;
1122 if (file_existed && !(flags2 & O_TRUNC))
1123 action = FILE_WAS_OPENED;
1124 if (file_existed && (flags2 & O_TRUNC))
1125 action = FILE_WAS_OVERWRITTEN;
1127 action = FILE_WAS_CREATED;
1134 * Setup the oplock info in both the shared memory and
1138 if(oplock_request && (num_share_modes == 0) &&
1139 !IS_VETO_OPLOCK_PATH(conn,fname) && set_file_oplock(fsp, oplock_request) ) {
1140 port = global_oplock_port;
1141 } else if (oplock_request && all_current_opens_are_level_II) {
1142 port = global_oplock_port;
1143 oplock_request = LEVEL_II_OPLOCK;
1144 set_file_oplock(fsp, oplock_request);
1150 set_share_mode(fsp, port, oplock_request);
1152 if (delete_on_close) {
1153 NTSTATUS result = set_delete_on_close_internal(fsp, delete_on_close);
1155 if (NT_STATUS_V(result) != NT_STATUS_V(NT_STATUS_OK)) {
1156 /* Remember to delete the mode we just added. */
1157 del_share_mode(fsp, NULL);
1158 unlock_share_entry_fsp(fsp);
1165 if (action == FILE_WAS_OVERWRITTEN || action == FILE_WAS_CREATED) {
1166 /* Files should be initially set as archive */
1167 if (lp_map_archive(SNUM(conn)) || lp_store_dos_attributes(SNUM(conn))) {
1168 file_set_dosmode(conn, fname, new_dos_mode | aARCH, NULL);
1173 * Take care of inherited ACLs on created files - if default ACL not
1177 if (!file_existed && !def_acl) {
1179 int saved_errno = errno; /* We might get ENOSYS in the next call.. */
1181 if (SMB_VFS_FCHMOD_ACL(fsp, fsp->fd, mode) == -1 && errno == ENOSYS)
1182 errno = saved_errno; /* Ignore ENOSYS */
1184 } else if (new_mode) {
1188 /* Attributes need changing. File already existed. */
1191 int saved_errno = errno; /* We might get ENOSYS in the next call.. */
1192 ret = SMB_VFS_FCHMOD_ACL(fsp, fsp->fd, new_mode);
1194 if (ret == -1 && errno == ENOSYS) {
1195 errno = saved_errno; /* Ignore ENOSYS */
1197 DEBUG(5, ("open_file_shared: failed to reset attributes of file %s to 0%o\n",
1198 fname, (int)new_mode));
1199 ret = 0; /* Don't do the fchmod below. */
1203 if ((ret == -1) && (SMB_VFS_FCHMOD(fsp, fsp->fd, new_mode) == -1))
1204 DEBUG(5, ("open_file_shared: failed to reset attributes of file %s to 0%o\n",
1205 fname, (int)new_mode));
1208 unlock_share_entry_fsp(fsp);
1210 conn->num_files_open++;
1215 /****************************************************************************
1216 Open a file for for write to ensure that we can fchmod it.
1217 ****************************************************************************/
1219 files_struct *open_file_fchmod(connection_struct *conn, const char *fname, SMB_STRUCT_STAT *psbuf)
1221 files_struct *fsp = NULL;
1224 if (!VALID_STAT(*psbuf))
1227 fsp = file_new(conn);
1231 /* note! we must use a non-zero desired access or we don't get
1232 a real file descriptor. Oh what a twisted web we weave. */
1233 fsp_open = open_file(fsp,conn,fname,psbuf,O_WRONLY,0,FILE_WRITE_DATA);
1236 * This is not a user visible file open.
1237 * Don't set a share mode and don't increment
1238 * the conn->num_files_open.
1249 /****************************************************************************
1250 Close the fchmod file fd - ensure no locks are lost.
1251 ****************************************************************************/
1253 int close_file_fchmod(files_struct *fsp)
1255 int ret = fd_close(fsp->conn, fsp);
1260 /****************************************************************************
1261 Open a directory from an NT SMB call.
1262 ****************************************************************************/
1264 files_struct *open_directory(connection_struct *conn, char *fname, SMB_STRUCT_STAT *psbuf,
1265 uint32 desired_access, int share_mode, int smb_ofun, int *action)
1267 extern struct current_user current_user;
1268 BOOL got_stat = False;
1269 files_struct *fsp = file_new(conn);
1270 BOOL delete_on_close = GET_DELETE_ON_CLOSE_FLAG(share_mode);
1275 if (VALID_STAT(*psbuf))
1278 if (got_stat && (GET_FILE_OPEN_DISPOSITION(smb_ofun) == FILE_EXISTS_FAIL)) {
1280 errno = EEXIST; /* Setup so correct error is returned to client. */
1284 if (GET_FILE_CREATE_DISPOSITION(smb_ofun) == FILE_CREATE_IF_NOT_EXIST) {
1288 if(!S_ISDIR(psbuf->st_mode)) {
1289 DEBUG(0,("open_directory: %s is not a directory !\n", fname ));
1294 *action = FILE_WAS_OPENED;
1299 * Try and create the directory.
1302 if(!CAN_WRITE(conn)) {
1303 DEBUG(2,("open_directory: failing create on read-only share\n"));
1309 if (ms_has_wild(fname)) {
1311 DEBUG(5,("open_directory: failing create on filename %s with wildcards\n", fname));
1312 unix_ERR_class = ERRDOS;
1313 unix_ERR_code = ERRinvalidname;
1314 unix_ERR_ntstatus = NT_STATUS_OBJECT_NAME_INVALID;
1318 if( strchr_m(fname, ':')) {
1320 DEBUG(5,("open_directory: failing create on filename %s with colon in name\n", fname));
1321 unix_ERR_class = ERRDOS;
1322 unix_ERR_code = ERRinvalidname;
1323 unix_ERR_ntstatus = NT_STATUS_NOT_A_DIRECTORY;
1327 if(vfs_MkDir(conn,fname, unix_mode(conn,aDIR, fname)) < 0) {
1328 DEBUG(2,("open_directory: unable to create %s. Error was %s\n",
1329 fname, strerror(errno) ));
1334 if(SMB_VFS_STAT(conn,fname, psbuf) != 0) {
1339 *action = FILE_WAS_CREATED;
1345 * Don't create - just check that it *was* a directory.
1349 DEBUG(3,("open_directory: unable to stat name = %s. Error was %s\n",
1350 fname, strerror(errno) ));
1355 if(!S_ISDIR(psbuf->st_mode)) {
1356 DEBUG(0,("open_directory: %s is not a directory !\n", fname ));
1361 *action = FILE_WAS_OPENED;
1364 DEBUG(5,("open_directory: opening directory %s\n", fname));
1367 * Setup the files_struct for it.
1370 fsp->mode = psbuf->st_mode;
1371 fsp->inode = psbuf->st_ino;
1372 fsp->dev = psbuf->st_dev;
1373 fsp->size = psbuf->st_size;
1374 fsp->vuid = current_user.vuid;
1375 fsp->file_pid = global_smbpid;
1376 fsp->can_lock = True;
1377 fsp->can_read = False;
1378 fsp->can_write = False;
1379 fsp->share_mode = share_mode;
1380 fsp->desired_access = desired_access;
1381 fsp->print_file = False;
1382 fsp->modified = False;
1383 fsp->oplock_type = NO_OPLOCK;
1384 fsp->sent_oplock_break = NO_BREAK_SENT;
1385 fsp->is_directory = True;
1386 fsp->is_stat = False;
1387 fsp->directory_delete_on_close = False;
1388 string_set(&fsp->fsp_name,fname);
1390 if (delete_on_close) {
1391 NTSTATUS result = set_delete_on_close_internal(fsp, delete_on_close);
1393 if (NT_STATUS_V(result) != NT_STATUS_V(NT_STATUS_OK)) {
1398 conn->num_files_open++;
1403 /****************************************************************************
1404 Open a pseudo-file (no locking checks - a 'stat' open).
1405 ****************************************************************************/
1407 files_struct *open_file_stat(connection_struct *conn, char *fname, SMB_STRUCT_STAT *psbuf)
1409 extern struct current_user current_user;
1410 files_struct *fsp = NULL;
1412 if (!VALID_STAT(*psbuf))
1415 /* Can't 'stat' open directories. */
1416 if(S_ISDIR(psbuf->st_mode))
1419 fsp = file_new(conn);
1423 DEBUG(5,("open_file_stat: 'opening' file %s\n", fname));
1426 * Setup the files_struct for it.
1429 fsp->mode = psbuf->st_mode;
1431 * Don't store dev or inode, we don't want any iterator
1434 fsp->inode = (SMB_INO_T)0;
1435 fsp->dev = (SMB_DEV_T)0;
1436 fsp->size = psbuf->st_size;
1437 fsp->vuid = current_user.vuid;
1438 fsp->file_pid = global_smbpid;
1439 fsp->can_lock = False;
1440 fsp->can_read = False;
1441 fsp->can_write = False;
1442 fsp->share_mode = 0;
1443 fsp->desired_access = 0;
1444 fsp->print_file = False;
1445 fsp->modified = False;
1446 fsp->oplock_type = NO_OPLOCK;
1447 fsp->sent_oplock_break = NO_BREAK_SENT;
1448 fsp->is_directory = False;
1449 fsp->is_stat = True;
1450 fsp->directory_delete_on_close = False;
1451 string_set(&fsp->fsp_name,fname);
1453 conn->num_files_open++;