2 Unix SMB/Netbios implementation.
4 file opening and share modes
5 Copyright (C) Andrew Tridgell 1992-1998
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 int DEBUGLEVEL;
26 extern pstring sesssetup_user;
27 extern int global_oplocks_open;
28 extern uint16 oplock_port;
31 /****************************************************************************
32 fd support routines - attempt to do a dos_open
33 ****************************************************************************/
34 static int fd_attempt_open(char *fname, int flags, mode_t mode)
36 int fd = dos_open(fname,flags,mode);
38 /* Fix for files ending in '.' */
39 if((fd == -1) && (errno == ENOENT) &&
40 (strchr(fname,'.')==NULL))
43 fd = dos_open(fname,flags,mode);
46 #if (defined(ENAMETOOLONG) && defined(HAVE_PATHCONF))
47 if ((fd == -1) && (errno == ENAMETOOLONG))
50 char *p = strrchr(fname, '/');
52 if (p == fname) /* name is "/xxx" */
54 max_len = pathconf("/", _PC_NAME_MAX);
57 else if ((p == NULL) || (p == fname))
60 max_len = pathconf(".", _PC_NAME_MAX);
65 max_len = pathconf(fname, _PC_NAME_MAX);
69 if (strlen(p) > max_len)
71 char tmp = p[max_len];
74 if ((fd = dos_open(fname,flags,mode)) == -1)
82 /****************************************************************************
83 Cache a uid_t currently with this file open. This is an optimization only
84 used when multiple sessionsetup's have been done to one smbd.
85 ****************************************************************************/
86 void fd_add_to_uid_cache(file_fd_struct *fd_ptr, uid_t u)
88 if(fd_ptr->uid_cache_count >= sizeof(fd_ptr->uid_users_cache)/sizeof(uid_t))
90 fd_ptr->uid_users_cache[fd_ptr->uid_cache_count++] = u;
93 /****************************************************************************
94 Remove a uid_t that currently has this file open. This is an optimization only
95 used when multiple sessionsetup's have been done to one smbd.
96 ****************************************************************************/
97 static void fd_remove_from_uid_cache(file_fd_struct *fd_ptr, uid_t u)
100 for(i = 0; i < fd_ptr->uid_cache_count; i++)
101 if(fd_ptr->uid_users_cache[i] == u) {
102 if(i < (fd_ptr->uid_cache_count-1))
103 memmove((char *)&fd_ptr->uid_users_cache[i], (char *)&fd_ptr->uid_users_cache[i+1],
104 sizeof(uid_t)*(fd_ptr->uid_cache_count-1-i) );
105 fd_ptr->uid_cache_count--;
110 /****************************************************************************
111 Check if a uid_t that currently has this file open is present. This is an
112 optimization only used when multiple sessionsetup's have been done to one smbd.
113 ****************************************************************************/
114 static BOOL fd_is_in_uid_cache(file_fd_struct *fd_ptr, uid_t u)
117 for(i = 0; i < fd_ptr->uid_cache_count; i++)
118 if(fd_ptr->uid_users_cache[i] == u)
124 /****************************************************************************
125 fd support routines - attempt to re-open an already open fd as O_RDWR.
126 Save the already open fd (we cannot close due to POSIX file locking braindamage.
127 ****************************************************************************/
128 static void fd_attempt_reopen(char *fname, mode_t mode, file_fd_struct *fd_ptr)
130 int fd = dos_open( fname, O_RDWR, mode);
135 if(fd_ptr->real_open_flags == O_RDONLY)
136 fd_ptr->fd_readonly = fd_ptr->fd;
137 if(fd_ptr->real_open_flags == O_WRONLY)
138 fd_ptr->fd_writeonly = fd_ptr->fd;
141 fd_ptr->real_open_flags = O_RDWR;
144 /****************************************************************************
145 fd support routines - attempt to close the file referenced by this fd.
146 Decrements the ref_count and returns it.
147 ****************************************************************************/
148 uint16 fd_attempt_close(file_fd_struct *fd_ptr)
150 extern struct current_user current_user;
151 uint16 ret_ref = fd_ptr->ref_count;
153 DEBUG(3,("fd_attempt_close fd = %d, dev = %x, inode = %.0f, open_flags = %d, ref_count = %d.\n",
154 fd_ptr->fd, (unsigned int)fd_ptr->dev, (double)fd_ptr->inode,
155 fd_ptr->real_open_flags,
158 SMB_ASSERT(fd_ptr->ref_count != 0);
161 ret_ref = fd_ptr->ref_count;
163 if(fd_ptr->ref_count == 0) {
166 if(fd_ptr->fd_readonly != -1)
167 close(fd_ptr->fd_readonly);
168 if(fd_ptr->fd_writeonly != -1)
169 close(fd_ptr->fd_writeonly);
171 * Delete this fd_ptr.
175 fd_remove_from_uid_cache(fd_ptr, (uid_t)current_user.uid);
181 /****************************************************************************
182 fd support routines - check that current user has permissions
183 to open this file. Used when uid not found in optimization cache.
184 This is really ugly code, as due to POSIX locking braindamage we must
185 fork and then attempt to open the file, and return success or failure
187 ****************************************************************************/
188 static BOOL check_access_allowed_for_current_user( char *fname, int accmode )
192 if((child_pid = fork()) < 0) {
193 DEBUG(0,("check_access_allowed_for_current_user: fork failed.\n"));
203 if ((wpid = sys_waitpid(child_pid, &status_code, 0)) < 0) {
204 DEBUG(0,("check_access_allowed_for_current_user: The process is no longer waiting!\n"));
208 if (child_pid != wpid) {
209 DEBUG(0,("check_access_allowed_for_current_user: We were waiting for the wrong process ID\n"));
212 #if defined(WIFEXITED) && defined(WEXITSTATUS)
213 if (WIFEXITED(status_code) == 0) {
214 DEBUG(0,("check_access_allowed_for_current_user: The process exited while we were waiting\n"));
217 if (WEXITSTATUS(status_code) != 0) {
218 DEBUG(9,("check_access_allowed_for_current_user: The status of the process exiting was %d. Returning access denied.\n", status_code));
221 #else /* defined(WIFEXITED) && defined(WEXITSTATUS) */
222 if(status_code != 0) {
223 DEBUG(9,("check_access_allowed_for_current_user: The status of the process exiting was %d. Returning access denied.\n", status_code));
226 #endif /* defined(WIFEXITED) && defined(WEXITSTATUS) */
229 * Success - the child could open the file.
231 DEBUG(9,("check_access_allowed_for_current_user: The status of the process exiting was %d. Returning access allowed.\n", status_code));
238 DEBUG(9,("check_access_allowed_for_current_user: Child - attempting to open %s with mode %d.\n", fname, accmode ));
239 if((fd = fd_attempt_open( fname, accmode, 0)) < 0) {
244 DEBUG(9,("check_access_allowed_for_current_user: Child - returning ok.\n"));
251 /****************************************************************************
252 check a filename for the pipe string
253 ****************************************************************************/
254 static void check_for_pipe(char *fname)
256 /* special case of pipe opens */
260 if (strstr(s,"pipe/")) {
261 DEBUG(3,("Rejecting named pipe open for %s\n",fname));
262 unix_ERR_class = ERRSRV;
263 unix_ERR_code = ERRaccess;
267 /****************************************************************************
269 ****************************************************************************/
270 static void open_file(files_struct *fsp,connection_struct *conn,
271 char *fname1,int flags,mode_t mode, SMB_STRUCT_STAT *sbuf)
273 extern struct current_user current_user;
275 SMB_STRUCT_STAT statbuf;
276 file_fd_struct *fd_ptr;
277 int accmode = (flags & (O_RDONLY | O_WRONLY | O_RDWR));
281 fsp->granted_oplock = False;
284 pstrcpy(fname,fname1);
286 /* check permissions */
289 * This code was changed after seeing a client open request
290 * containing the open mode of (DENY_WRITE/read-only) with
291 * the 'create if not exist' bit set. The previous code
292 * would fail to open the file read only on a read-only share
293 * as it was checking the flags parameter directly against O_RDONLY,
294 * this was failing as the flags parameter was set to O_RDONLY|O_CREAT.
298 if (conn->read_only && !conn->printer) {
299 /* It's a read-only share - fail if we wanted to write. */
300 if(accmode != O_RDONLY) {
301 DEBUG(3,("Permission denied opening %s\n",fname));
302 check_for_pipe(fname);
304 } else if(flags & O_CREAT) {
305 /* We don't want to write - but we must make sure that O_CREAT
306 doesn't create the file if we have write access into the
313 /* this handles a bug in Win95 - it doesn't say to create the file when it
320 if (flags == O_WRONLY)
321 DEBUG(3,("Bug in client? Set O_WRONLY without O_CREAT\n"));
325 * Ensure we have a valid struct stat so we can search the
329 if(dos_stat(fname, &statbuf) < 0) {
330 if(errno != ENOENT) {
331 DEBUG(3,("Error doing stat on file %s (%s)\n",
332 fname,strerror(errno)));
334 check_for_pipe(fname);
344 * Check to see if we have this file already
345 * open. If we do, just use the already open fd and increment the
346 * reference count (fd_get_already_open increments the ref_count).
348 if((fd_ptr = fd_get_already_open(sbuf))!= 0) {
350 * File was already open.
354 * Check it wasn't open for exclusive use.
356 if((flags & O_CREAT) && (flags & O_EXCL)) {
363 * Ensure that the user attempting to open
364 * this file has permissions to do so, if
365 * the user who originally opened the file wasn't
366 * the same as the current user.
369 if(!fd_is_in_uid_cache(fd_ptr, (uid_t)current_user.uid)) {
370 if(!check_access_allowed_for_current_user( fname, accmode )) {
371 /* Error - permission denied. */
372 DEBUG(3,("Permission denied opening file %s (flags=%d, accmode = %d)\n",
373 fname, flags, accmode));
374 /* Ensure the ref_count is decremented. */
376 fd_remove_from_uid_cache(fd_ptr, (uid_t)current_user.uid);
382 fd_add_to_uid_cache(fd_ptr, (uid_t)current_user.uid);
385 * If not opened O_RDWR try
386 * and do that here - a chmod may have been done
387 * between the last open and now.
389 if(fd_ptr->real_open_flags != O_RDWR)
390 fd_attempt_reopen(fname, mode, fd_ptr);
393 * Ensure that if we wanted write access
394 * it has been opened for write, and if we wanted read it
397 if(((accmode == O_WRONLY) && (fd_ptr->real_open_flags == O_RDONLY)) ||
398 ((accmode == O_RDONLY) && (fd_ptr->real_open_flags == O_WRONLY)) ||
399 ((accmode == O_RDWR) && (fd_ptr->real_open_flags != O_RDWR))) {
400 DEBUG(3,("Error opening (already open for flags=%d) file %s (%s) (flags=%d)\n",
401 fd_ptr->real_open_flags, fname,strerror(EACCES),flags));
402 check_for_pipe(fname);
403 fd_remove_from_uid_cache(fd_ptr, (uid_t)current_user.uid);
410 /* We need to allocate a new file_fd_struct (this increments the
412 if((fd_ptr = fd_get_new()) == 0)
415 * Whatever the requested flags, attempt read/write access,
416 * as we don't know what flags future file opens may require.
417 * If this fails, try again with the required flags.
418 * Even if we open read/write when only read access was
419 * requested the setting of the can_write flag in
420 * the file_struct will protect us from errant
421 * write requests. We never need to worry about O_APPEND
422 * as this is not set anywhere in Samba.
424 fd_ptr->real_open_flags = O_RDWR;
425 /* Set the flags as needed without the read/write modes. */
426 open_flags = flags & ~(O_RDWR|O_WRONLY|O_RDONLY);
427 fd_ptr->fd = fd_attempt_open(fname, open_flags|O_RDWR, mode);
429 * On some systems opening a file for R/W access on a read only
430 * filesystems sets errno to EROFS.
433 if((fd_ptr->fd == -1) && ((errno == EACCES) || (errno == EROFS))) {
435 if((fd_ptr->fd == -1) && (errno == EACCES)) {
437 if(accmode != O_RDWR) {
438 fd_ptr->fd = fd_attempt_open(fname, open_flags|accmode, mode);
439 fd_ptr->real_open_flags = accmode;
444 if ((fd_ptr->fd >=0) &&
445 conn->printer && lp_minprintspace(SNUM(conn))) {
447 SMB_BIG_UINT dum1,dum2,dum3;
449 pstrcpy(dname,fname);
450 p = strrchr(dname,'/');
452 if (sys_disk_free(dname,&dum1,&dum2,&dum3) < (SMB_BIG_UINT)lp_minprintspace(SNUM(conn))) {
453 if(fd_attempt_close(fd_ptr) == 0)
463 DEBUG(3,("Error opening file %s (%s) (flags=%d)\n",
464 fname,strerror(errno),flags));
465 /* Ensure the ref_count is decremented. */
466 fd_attempt_close(fd_ptr);
467 check_for_pipe(fname);
475 if(sys_fstat(fd_ptr->fd, &statbuf) == -1) {
476 /* Error - backout !! */
477 DEBUG(3,("Error doing fstat on fd %d, file %s (%s)\n",
478 fd_ptr->fd, fname,strerror(errno)));
479 /* Ensure the ref_count is decremented. */
480 fd_attempt_close(fd_ptr);
486 /* Set the correct entries in fd_ptr. */
487 fd_ptr->dev = sbuf->st_dev;
488 fd_ptr->inode = sbuf->st_ino;
490 fsp->fd_ptr = fd_ptr;
491 conn->num_files_open++;
492 fsp->mode = sbuf->st_mode;
493 GetTimeOfDay(&fsp->open_time);
494 fsp->vuid = current_user.vuid;
498 fsp->mmap_ptr = NULL;
500 fsp->can_lock = True;
501 fsp->can_read = ((flags & O_WRONLY)==0);
502 fsp->can_write = ((flags & (O_WRONLY|O_RDWR))!=0);
504 fsp->print_file = conn->printer;
505 fsp->modified = False;
506 fsp->granted_oplock = False;
507 fsp->sent_oplock_break = False;
508 fsp->is_directory = False;
509 fsp->delete_on_close = False;
512 * Note that the file name here is the *untranslated* name
513 * ie. it is still in the DOS codepage sent from the client.
514 * All use of this filename will pass though the sys_xxxx
515 * functions which will do the dos_to_unix translation before
516 * mapping into a UNIX filename. JRA.
518 string_set(&fsp->fsp_name,fname);
519 fsp->wbmpx_ptr = NULL;
522 * If the printer is marked as postscript output a leading
523 * file identifier to ensure the file is treated as a raw
525 * This has a similar effect as CtrlD=0 in WIN.INI file.
526 * tim@fsg.com 09/06/94
528 if (fsp->print_file && lp_postscript(SNUM(conn)) && fsp->can_write) {
529 DEBUG(3,("Writing postscript line\n"));
530 write_file(fsp,"%!\n",3);
533 DEBUG(2,("%s opened file %s read=%s write=%s (numopen=%d)\n",
534 *sesssetup_user ? sesssetup_user : conn->user,fsp->fsp_name,
535 BOOLSTR(fsp->can_read), BOOLSTR(fsp->can_write),
536 conn->num_files_open));
541 /* mmap it if read-only */
542 if (!fsp->can_write) {
543 fsp->mmap_size = file_size(fname);
544 fsp->mmap_ptr = (char *)mmap(NULL,fsp->mmap_size,
545 PROT_READ,MAP_SHARED,fsp->fd_ptr->fd,0);
547 if (fsp->mmap_ptr == (char *)-1 || !fsp->mmap_ptr) {
548 DEBUG(3,("Failed to mmap() %s - %s\n",
549 fname,strerror(errno)));
550 fsp->mmap_ptr = NULL;
557 /****************************************************************************
559 Helper for open_file_shared.
560 Truncate a file after checking locking; close file if locked.
561 **************************************************************************/
562 static void truncate_unless_locked(files_struct *fsp, connection_struct *conn, int token,
566 #ifdef LARGE_SMB_OFF_T
567 if (is_locked(fsp,conn,0x3FFFFFFFFFFFFFFFLL,0,F_WRLCK)){
569 if (is_locked(fsp,conn,0x3FFFFFFF,0,F_WRLCK)){
571 /* If share modes are in force for this connection we
572 have the share entry locked. Unlock it before closing. */
573 if (*share_locked && lp_share_modes(SNUM(conn)))
574 unlock_share_entry( conn, fsp->fd_ptr->dev,
575 fsp->fd_ptr->inode, token);
576 close_file(fsp,False);
577 /* Share mode no longer locked. */
578 *share_locked = False;
580 unix_ERR_class = ERRDOS;
581 unix_ERR_code = ERRlock;
584 sys_ftruncate(fsp->fd_ptr->fd,0);
589 enum {AFAIL,AREAD,AWRITE,AALL};
591 /*******************************************************************
592 reproduce the share mode access table
593 ********************************************************************/
594 static int access_table(int new_deny,int old_deny,int old_mode,
595 int share_pid,char *fname)
597 if (new_deny == DENY_ALL || old_deny == DENY_ALL) return(AFAIL);
599 if (new_deny == DENY_DOS || old_deny == DENY_DOS) {
601 if (old_deny == new_deny && share_pid == pid)
604 if (old_mode == 0) return(AREAD);
606 /* the new smbpub.zip spec says that if the file extension is
607 .com, .dll, .exe or .sym then allow the open. I will force
608 it to read-only as this seems sensible although the spec is
609 a little unclear on this. */
610 if ((fname = strrchr(fname,'.'))) {
611 if (strequal(fname,".com") ||
612 strequal(fname,".dll") ||
613 strequal(fname,".exe") ||
614 strequal(fname,".sym"))
624 if (old_deny==DENY_WRITE && old_mode==0) return(AREAD);
625 if (old_deny==DENY_READ && old_mode==0) return(AWRITE);
626 if (old_deny==DENY_NONE && old_mode==0) return(AALL);
629 if (old_deny==DENY_WRITE && old_mode==1) return(AREAD);
630 if (old_deny==DENY_READ && old_mode==1) return(AWRITE);
631 if (old_deny==DENY_NONE && old_mode==1) return(AALL);
634 if (old_deny==DENY_WRITE) return(AREAD);
635 if (old_deny==DENY_READ) return(AWRITE);
636 if (old_deny==DENY_NONE) return(AALL);
643 /****************************************************************************
644 check if we can open a file with a share mode
645 ****************************************************************************/
646 static int check_share_mode( share_mode_entry *share, int deny_mode,
648 BOOL fcbopen, int *flags)
650 int old_open_mode = share->share_mode &0xF;
651 int old_deny_mode = (share->share_mode >>4)&7;
653 if (old_deny_mode > 4 || old_open_mode > 2)
655 DEBUG(0,("Invalid share mode found (%d,%d,%d) on file %s\n",
656 deny_mode,old_deny_mode,old_open_mode,fname));
661 int access_allowed = access_table(deny_mode,old_deny_mode,old_open_mode,
664 if ((access_allowed == AFAIL) ||
665 (!fcbopen && (access_allowed == AREAD && *flags == O_RDWR)) ||
666 (access_allowed == AREAD && *flags == O_WRONLY) ||
667 (access_allowed == AWRITE && *flags == O_RDONLY))
669 DEBUG(2,("Share violation on file (%d,%d,%d,%d,%s,fcbopen = %d, flags = %d) = %d\n",
670 deny_mode,old_deny_mode,old_open_mode,
671 share->pid,fname, fcbopen, *flags, access_allowed));
675 if (access_allowed == AREAD)
678 if (access_allowed == AWRITE)
686 /****************************************************************************
687 open a file with a share mode
688 ****************************************************************************/
689 void open_file_shared(files_struct *fsp,connection_struct *conn,char *fname,int share_mode,int ofun,
690 mode_t mode,int oplock_request, int *Access,int *action)
694 int deny_mode = (share_mode>>4)&7;
695 SMB_STRUCT_STAT sbuf;
696 BOOL file_existed = file_exist(fname,&sbuf);
697 BOOL share_locked = False;
698 BOOL fcbopen = False;
702 int num_share_modes = 0;
707 /* this is for OS/2 EAs - try and say we don't support them */
708 if (strstr(fname,".+,;=[]."))
710 unix_ERR_class = ERRDOS;
711 /* OS/2 Workplace shell fix may be main code stream in a later release. */
712 #if 1 /* OS2_WPS_FIX - Recent versions of OS/2 need this. */
713 unix_ERR_code = ERRcannotopen;
714 #else /* OS2_WPS_FIX */
715 unix_ERR_code = ERROR_EAS_NOT_SUPPORTED;
716 #endif /* OS2_WPS_FIX */
721 if ((ofun & 0x3) == 0 && file_existed)
729 if ((ofun & 0x3) == 2)
732 /* note that we ignore the append flag as
733 append does not mean the same thing under dos and unix */
735 switch (share_mode&0xF)
753 if (share_mode&(1<<14)) {
758 if (flags != O_RDONLY && file_existed &&
759 (!CAN_WRITE(conn) || IS_DOS_READONLY(dos_mode(conn,fname,&sbuf))))
769 if (deny_mode > DENY_NONE && deny_mode!=DENY_FCB)
771 DEBUG(2,("Invalid deny mode %d on file %s\n",deny_mode,fname));
776 if (deny_mode == DENY_FCB) deny_mode = DENY_DOS;
778 if (lp_share_modes(SNUM(conn)))
781 share_mode_entry *old_shares = 0;
787 lock_share_entry(conn, dev, inode, &token);
789 num_share_modes = get_share_modes(conn, token, dev, inode, &old_shares);
793 * Check if the share modes will give us access.
796 if(share_locked && (num_share_modes != 0))
803 broke_oplock = False;
804 for(i = 0; i < num_share_modes; i++)
806 share_mode_entry *share_entry = &old_shares[i];
809 * By observation of NetBench, oplocks are broken *before* share
810 * modes are checked. This allows a file to be closed by the client
811 * if the share mode would deny access and the client has an oplock.
812 * Check if someone has an oplock on this file. If so we must break
813 * it before continuing.
815 if(share_entry->op_type & (EXCLUSIVE_OPLOCK|BATCH_OPLOCK))
818 DEBUG(5,("open_file_shared: breaking oplock (%x) on file %s, \
819 dev = %x, inode = %.0f\n", share_entry->op_type, fname, (unsigned int)dev, (double)inode));
821 /* Oplock break.... */
822 unlock_share_entry(conn, dev, inode, token);
823 if(request_oplock_break(share_entry, dev, inode) == False)
825 free((char *)old_shares);
827 DEBUG(0,("open_file_shared: FAILED when breaking oplock (%x) on file %s, \
828 dev = %x, inode = %.0f\n", old_shares[i].op_type, fname, (unsigned int)dev, (double)inode));
831 unix_ERR_class = ERRDOS;
832 unix_ERR_code = ERRbadshare;
835 lock_share_entry(conn, dev, inode, &token);
840 /* someone else has a share lock on it, check to see
842 if(check_share_mode(share_entry, deny_mode, fname, fcbopen, &flags) == False)
844 free((char *)old_shares);
845 unlock_share_entry(conn, dev, inode, token);
847 unix_ERR_class = ERRDOS;
848 unix_ERR_code = ERRbadshare;
856 free((char *)old_shares);
857 num_share_modes = get_share_modes(conn, token, dev, inode, &old_shares);
859 } while(broke_oplock);
863 free((char *)old_shares);
866 DEBUG(4,("calling open_file with flags=0x%X flags2=0x%X mode=0%o\n",
867 flags,flags2,(int)mode));
869 open_file(fsp,conn,fname,flags|(flags2&~(O_TRUNC)),mode,file_existed ? &sbuf : 0);
870 if (!fsp->open && flags==O_RDWR && errno!=ENOENT && fcbopen)
873 open_file(fsp,conn,fname,flags,mode,file_existed ? &sbuf : 0 );
880 if((share_locked == False) && lp_share_modes(SNUM(conn)))
882 /* We created the file - thus we must now lock the share entry before creating it. */
883 dev = fsp->fd_ptr->dev;
884 inode = fsp->fd_ptr->inode;
885 lock_share_entry(conn, dev, inode, &token);
902 fsp->share_mode = (deny_mode<<4) | open_mode;
905 (*Access) = open_mode;
909 if (file_existed && !(flags2 & O_TRUNC)) *action = FILE_WAS_OPENED;
910 if (!file_existed) *action = FILE_WAS_CREATED;
911 if (file_existed && (flags2 & O_TRUNC)) *action = FILE_WAS_OVERWRITTEN;
913 /* We must create the share mode entry before truncate as
914 truncate can fail due to locking and have to close the
915 file (which expects the share_mode_entry to be there).
917 if (lp_share_modes(SNUM(conn)))
920 /* JRA. Currently this only services Exlcusive and batch
921 oplocks (no other opens on this file). This needs to
922 be extended to level II oplocks (multiple reader
925 if(oplock_request && (num_share_modes == 0) && lp_oplocks(SNUM(conn)) &&
926 !IS_VETO_OPLOCK_PATH(conn,fname))
928 fsp->granted_oplock = True;
929 fsp->sent_oplock_break = False;
930 global_oplocks_open++;
933 DEBUG(5,("open_file_shared: granted oplock (%x) on file %s, \
934 dev = %x, inode = %.0f\n", oplock_request, fname, (unsigned int)dev, (double)inode));
942 set_share_mode(token, fsp, port, oplock_request);
945 if ((flags2&O_TRUNC) && file_existed)
946 truncate_unless_locked(fsp,conn,token,&share_locked);
949 if (share_locked && lp_share_modes(SNUM(conn)))
950 unlock_share_entry( conn, dev, inode, token);
955 /****************************************************************************
956 Open a directory from an NT SMB call.
957 ****************************************************************************/
958 int open_directory(files_struct *fsp,connection_struct *conn,
959 char *fname, int smb_ofun, mode_t unixmode, int *action)
961 extern struct current_user current_user;
964 if (smb_ofun & 0x10) {
966 * Create the directory.
969 if(dos_mkdir(fname, unixmode) < 0) {
970 DEBUG(0,("open_directory: unable to create %s. Error was %s\n",
971 fname, strerror(errno) ));
975 *action = FILE_WAS_CREATED;
978 * Check that it *was* a directory.
981 if(dos_stat(fname, &st) < 0) {
982 DEBUG(0,("open_directory: unable to stat name = %s. Error was %s\n",
983 fname, strerror(errno) ));
987 if(!S_ISDIR(st.st_mode)) {
988 DEBUG(0,("open_directory: %s is not a directory !\n", fname ));
991 *action = FILE_WAS_OPENED;
994 DEBUG(5,("open_directory: opening directory %s\n",
998 * Setup the files_struct for it.
1002 conn->num_files_open++;
1004 GetTimeOfDay(&fsp->open_time);
1005 fsp->vuid = current_user.vuid;
1009 fsp->mmap_ptr = NULL;
1011 fsp->can_lock = True;
1012 fsp->can_read = False;
1013 fsp->can_write = False;
1014 fsp->share_mode = 0;
1015 fsp->print_file = False;
1016 fsp->modified = False;
1017 fsp->granted_oplock = False;
1018 fsp->sent_oplock_break = False;
1019 fsp->is_directory = True;
1022 * Note that the file name here is the *untranslated* name
1023 * ie. it is still in the DOS codepage sent from the client.
1024 * All use of this filename will pass though the sys_xxxx
1025 * functions which will do the dos_to_unix translation before
1026 * mapping into a UNIX filename. JRA.
1028 string_set(&fsp->fsp_name,fname);
1029 fsp->wbmpx_ptr = NULL;
1035 /*******************************************************************
1036 check if the share mode on a file allows it to be deleted or unlinked
1037 return True if sharing doesn't prevent the operation
1038 ********************************************************************/
1039 BOOL check_file_sharing(connection_struct *conn,char *fname, BOOL rename_op)
1043 share_mode_entry *old_shares = 0;
1044 int num_share_modes;
1045 SMB_STRUCT_STAT sbuf;
1051 if(!lp_share_modes(SNUM(conn)))
1054 if (dos_stat(fname,&sbuf) == -1) return(True);
1057 inode = sbuf.st_ino;
1059 lock_share_entry(conn, dev, inode, &token);
1060 num_share_modes = get_share_modes(conn, token, dev, inode, &old_shares);
1063 * Check if the share modes will give us access.
1066 if(num_share_modes != 0)
1073 broke_oplock = False;
1074 for(i = 0; i < num_share_modes; i++)
1076 share_mode_entry *share_entry = &old_shares[i];
1079 * Break oplocks before checking share modes. See comment in
1080 * open_file_shared for details.
1081 * Check if someone has an oplock on this file. If so we must
1082 * break it before continuing.
1084 if(share_entry->op_type & BATCH_OPLOCK)
1088 * It appears that the NT redirector may have a bug, in that
1089 * it tries to do an SMBmv on a file that it has open with a
1090 * batch oplock, and then fails to respond to the oplock break
1091 * request. This only seems to occur when the client is doing an
1092 * SMBmv to the smbd it is using - thus we try and detect this
1093 * condition by checking if the file being moved is open and oplocked by
1094 * this smbd process, and then not sending the oplock break in this
1095 * special case. If the file was open with a deny mode that
1096 * prevents the move the SMBmv will fail anyway with a share
1097 * violation error. JRA.
1099 if(rename_op && (share_entry->pid == pid))
1102 DEBUG(0,("check_file_sharing: NT redirector workaround - rename attempted on \
1103 batch oplocked file %s, dev = %x, inode = %.0f\n", fname, (unsigned int)dev, (double)inode));
1106 * This next line is a test that allows the deny-mode
1107 * processing to be skipped. This seems to be needed as
1108 * NT insists on the rename succeeding (in Office 9x no less !).
1109 * This should be removed as soon as (a) MS fix the redirector
1110 * bug or (b) NT SMB support in Samba makes NT not issue the
1111 * call (as is my fervent hope). JRA.
1118 DEBUG(5,("check_file_sharing: breaking oplock (%x) on file %s, \
1119 dev = %x, inode = %.0f\n", share_entry->op_type, fname, (unsigned int)dev, (double)inode));
1121 /* Oplock break.... */
1122 unlock_share_entry(conn, dev, inode, token);
1123 if(request_oplock_break(share_entry, dev, inode) == False)
1125 free((char *)old_shares);
1127 DEBUG(0,("check_file_sharing: FAILED when breaking oplock (%x) on file %s, \
1128 dev = %x, inode = %.0f\n", old_shares[i].op_type, fname, (unsigned int)dev, (double)inode));
1132 lock_share_entry(conn, dev, inode, &token);
1133 broke_oplock = True;
1138 /* someone else has a share lock on it, check to see
1140 if ((share_entry->share_mode != DENY_DOS) || (share_entry->pid != pid))
1147 free((char *)old_shares);
1148 num_share_modes = get_share_modes(conn, token, dev, inode, &old_shares);
1150 } while(broke_oplock);
1153 /* XXXX exactly what share mode combinations should be allowed for
1154 deleting/renaming? */
1155 /* If we got here then either there were no share modes or
1156 all share modes were DENY_DOS and the pid == getpid() */
1161 unlock_share_entry(conn, dev, inode, token);
1162 if(old_shares != NULL)
1163 free((char *)old_shares);