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, int 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, int 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 int fd_attempt_close(file_fd_struct *fd_ptr)
150 extern struct current_user current_user;
152 DEBUG(3,("fd_attempt_close fd = %d, dev = %x, inode = %x, open_flags = %d, ref_count = %d.\n",
153 fd_ptr->fd, fd_ptr->dev, fd_ptr->inode,
154 fd_ptr->real_open_flags,
156 if(fd_ptr->ref_count > 0) {
158 if(fd_ptr->ref_count == 0) {
161 if(fd_ptr->fd_readonly != -1)
162 close(fd_ptr->fd_readonly);
163 if(fd_ptr->fd_writeonly != -1)
164 close(fd_ptr->fd_writeonly);
166 fd_ptr->fd_readonly = -1;
167 fd_ptr->fd_writeonly = -1;
168 fd_ptr->real_open_flags = -1;
169 fd_ptr->dev = (SMB_DEV_T)-1;
170 fd_ptr->inode = (SMB_INO_T)-1;
171 fd_ptr->uid_cache_count = 0;
173 fd_remove_from_uid_cache(fd_ptr, (uid_t)current_user.uid);
176 return fd_ptr->ref_count;
179 /****************************************************************************
180 fd support routines - check that current user has permissions
181 to open this file. Used when uid not found in optimization cache.
182 This is really ugly code, as due to POSIX locking braindamage we must
183 fork and then attempt to open the file, and return success or failure
185 ****************************************************************************/
186 static BOOL check_access_allowed_for_current_user( char *fname, int accmode )
190 if((child_pid = fork()) < 0) {
191 DEBUG(0,("check_access_allowed_for_current_user: fork failed.\n"));
201 if ((wpid = sys_waitpid(child_pid, &status_code, 0)) < 0) {
202 DEBUG(0,("check_access_allowed_for_current_user: The process is no longer waiting!\n"));
206 if (child_pid != wpid) {
207 DEBUG(0,("check_access_allowed_for_current_user: We were waiting for the wrong process ID\n"));
210 #if defined(WIFEXITED) && defined(WEXITSTATUS)
211 if (WIFEXITED(status_code) == 0) {
212 DEBUG(0,("check_access_allowed_for_current_user: The process exited while we were waiting\n"));
215 if (WEXITSTATUS(status_code) != 0) {
216 DEBUG(9,("check_access_allowed_for_current_user: The status of the process exiting was %d. Returning access denied.\n", status_code));
219 #else /* defined(WIFEXITED) && defined(WEXITSTATUS) */
220 if(status_code != 0) {
221 DEBUG(9,("check_access_allowed_for_current_user: The status of the process exiting was %d. Returning access denied.\n", status_code));
224 #endif /* defined(WIFEXITED) && defined(WEXITSTATUS) */
227 * Success - the child could open the file.
229 DEBUG(9,("check_access_allowed_for_current_user: The status of the process exiting was %d. Returning access allowed.\n", status_code));
236 DEBUG(9,("check_access_allowed_for_current_user: Child - attempting to open %s with mode %d.\n", fname, accmode ));
237 if((fd = fd_attempt_open( fname, accmode, 0)) < 0) {
242 DEBUG(9,("check_access_allowed_for_current_user: Child - returning ok.\n"));
249 /****************************************************************************
250 check a filename for the pipe string
251 ****************************************************************************/
252 static void check_for_pipe(char *fname)
254 /* special case of pipe opens */
258 if (strstr(s,"pipe/")) {
259 DEBUG(3,("Rejecting named pipe open for %s\n",fname));
260 unix_ERR_class = ERRSRV;
261 unix_ERR_code = ERRaccess;
265 /****************************************************************************
267 ****************************************************************************/
268 static void open_file(files_struct *fsp,connection_struct *conn,
269 char *fname1,int flags,int mode, SMB_STRUCT_STAT *sbuf)
271 extern struct current_user current_user;
273 SMB_STRUCT_STAT statbuf;
274 file_fd_struct *fd_ptr;
275 int accmode = (flags & (O_RDONLY | O_WRONLY | O_RDWR));
279 fsp->granted_oplock = False;
282 pstrcpy(fname,fname1);
284 /* check permissions */
287 * This code was changed after seeing a client open request
288 * containing the open mode of (DENY_WRITE/read-only) with
289 * the 'create if not exist' bit set. The previous code
290 * would fail to open the file read only on a read-only share
291 * as it was checking the flags parameter directly against O_RDONLY,
292 * this was failing as the flags parameter was set to O_RDONLY|O_CREAT.
296 if (conn->read_only && !conn->printer) {
297 /* It's a read-only share - fail if we wanted to write. */
298 if(accmode != O_RDONLY) {
299 DEBUG(3,("Permission denied opening %s\n",fname));
300 check_for_pipe(fname);
302 } else if(flags & O_CREAT) {
303 /* We don't want to write - but we must make sure that O_CREAT
304 doesn't create the file if we have write access into the
311 /* this handles a bug in Win95 - it doesn't say to create the file when it
318 if (flags == O_WRONLY)
319 DEBUG(3,("Bug in client? Set O_WRONLY without O_CREAT\n"));
323 * Ensure we have a valid struct stat so we can search the
327 if(dos_stat(fname, &statbuf) < 0) {
328 if(errno != ENOENT) {
329 DEBUG(3,("Error doing stat on file %s (%s)\n",
330 fname,strerror(errno)));
332 check_for_pipe(fname);
342 * Check to see if we have this file already
343 * open. If we do, just use the already open fd and increment the
344 * reference count (fd_get_already_open increments the ref_count).
346 if((fd_ptr = fd_get_already_open(sbuf))!= 0) {
348 * File was already open.
352 * Check it wasn't open for exclusive use.
354 if((flags & O_CREAT) && (flags & O_EXCL)) {
361 * Ensure that the user attempting to open
362 * this file has permissions to do so, if
363 * the user who originally opened the file wasn't
364 * the same as the current user.
367 if(!fd_is_in_uid_cache(fd_ptr, (uid_t)current_user.uid)) {
368 if(!check_access_allowed_for_current_user( fname, accmode )) {
369 /* Error - permission denied. */
370 DEBUG(3,("Permission denied opening file %s (flags=%d, accmode = %d)\n",
371 fname, flags, accmode));
372 /* Ensure the ref_count is decremented. */
374 fd_remove_from_uid_cache(fd_ptr, (uid_t)current_user.uid);
380 fd_add_to_uid_cache(fd_ptr, (uid_t)current_user.uid);
383 * If not opened O_RDWR try
384 * and do that here - a chmod may have been done
385 * between the last open and now.
387 if(fd_ptr->real_open_flags != O_RDWR)
388 fd_attempt_reopen(fname, mode, fd_ptr);
391 * Ensure that if we wanted write access
392 * it has been opened for write, and if we wanted read it
395 if(((accmode == O_WRONLY) && (fd_ptr->real_open_flags == O_RDONLY)) ||
396 ((accmode == O_RDONLY) && (fd_ptr->real_open_flags == O_WRONLY)) ||
397 ((accmode == O_RDWR) && (fd_ptr->real_open_flags != O_RDWR))) {
398 DEBUG(3,("Error opening (already open for flags=%d) file %s (%s) (flags=%d)\n",
399 fd_ptr->real_open_flags, fname,strerror(EACCES),flags));
400 check_for_pipe(fname);
401 fd_remove_from_uid_cache(fd_ptr, (uid_t)current_user.uid);
408 /* We need to allocate a new file_fd_struct (this increments the
410 if((fd_ptr = fd_get_new()) == 0)
413 * Whatever the requested flags, attempt read/write access,
414 * as we don't know what flags future file opens may require.
415 * If this fails, try again with the required flags.
416 * Even if we open read/write when only read access was
417 * requested the setting of the can_write flag in
418 * the file_struct will protect us from errant
419 * write requests. We never need to worry about O_APPEND
420 * as this is not set anywhere in Samba.
422 fd_ptr->real_open_flags = O_RDWR;
423 /* Set the flags as needed without the read/write modes. */
424 open_flags = flags & ~(O_RDWR|O_WRONLY|O_RDONLY);
425 fd_ptr->fd = fd_attempt_open(fname, open_flags|O_RDWR, mode);
427 * On some systems opening a file for R/W access on a read only
428 * filesystems sets errno to EROFS.
431 if((fd_ptr->fd == -1) && ((errno == EACCES) || (errno == EROFS))) {
433 if((fd_ptr->fd == -1) && (errno == EACCES)) {
435 if(accmode != O_RDWR) {
436 fd_ptr->fd = fd_attempt_open(fname, open_flags|accmode, mode);
437 fd_ptr->real_open_flags = accmode;
442 if ((fd_ptr->fd >=0) &&
443 conn->printer && lp_minprintspace(SNUM(conn))) {
447 pstrcpy(dname,fname);
448 p = strrchr(dname,'/');
450 if (sys_disk_free(dname,&dum1,&dum2,&dum3) <
451 lp_minprintspace(SNUM(conn))) {
452 fd_attempt_close(fd_ptr);
454 if(fd_ptr->ref_count == 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;
511 * Note that the file name here is the *untranslated* name
512 * ie. it is still in the DOS codepage sent from the client.
513 * All use of this filename will pass though the sys_xxxx
514 * functions which will do the dos_to_unix translation before
515 * mapping into a UNIX filename. JRA.
517 string_set(&fsp->fsp_name,fname);
518 fsp->wbmpx_ptr = NULL;
521 * If the printer is marked as postscript output a leading
522 * file identifier to ensure the file is treated as a raw
524 * This has a similar effect as CtrlD=0 in WIN.INI file.
525 * tim@fsg.com 09/06/94
527 if (fsp->print_file && lp_postscript(SNUM(conn)) && fsp->can_write) {
528 DEBUG(3,("Writing postscript line\n"));
529 write_file(fsp,"%!\n",3);
532 DEBUG(2,("%s opened file %s read=%s write=%s (numopen=%d)\n",
533 *sesssetup_user ? sesssetup_user : conn->user,fsp->fsp_name,
534 BOOLSTR(fsp->can_read), BOOLSTR(fsp->can_write),
535 conn->num_files_open));
540 /* mmap it if read-only */
541 if (!fsp->can_write) {
542 fsp->mmap_size = file_size(fname);
543 fsp->mmap_ptr = (char *)mmap(NULL,fsp->mmap_size,
544 PROT_READ,MAP_SHARED,fsp->fd_ptr->fd,0);
546 if (fsp->mmap_ptr == (char *)-1 || !fsp->mmap_ptr) {
547 DEBUG(3,("Failed to mmap() %s - %s\n",
548 fname,strerror(errno)));
549 fsp->mmap_ptr = NULL;
556 /****************************************************************************
558 Helper for open_file_shared.
559 Truncate a file after checking locking; close file if locked.
560 **************************************************************************/
561 static void truncate_unless_locked(files_struct *fsp, connection_struct *conn, int token,
565 #ifdef LARGE_SMB_OFF_T
566 if (is_locked(fsp,conn,0x3FFFFFFFFFFFFFFFLL,0,F_WRLCK)){
568 if (is_locked(fsp,conn,0x3FFFFFFF,0,F_WRLCK)){
570 /* If share modes are in force for this connection we
571 have the share entry locked. Unlock it before closing. */
572 if (*share_locked && lp_share_modes(SNUM(conn)))
573 unlock_share_entry( conn, fsp->fd_ptr->dev,
574 fsp->fd_ptr->inode, token);
575 close_file(fsp,False);
576 /* Share mode no longer locked. */
577 *share_locked = False;
579 unix_ERR_class = ERRDOS;
580 unix_ERR_code = ERRlock;
583 sys_ftruncate(fsp->fd_ptr->fd,0);
589 /****************************************************************************
590 open a file with a share mode
591 ****************************************************************************/
592 void open_file_shared(files_struct *fsp,connection_struct *conn,char *fname,int share_mode,int ofun,
593 int mode,int oplock_request, int *Access,int *action)
597 int deny_mode = (share_mode>>4)&7;
598 SMB_STRUCT_STAT sbuf;
599 BOOL file_existed = file_exist(fname,&sbuf);
600 BOOL share_locked = False;
601 BOOL fcbopen = False;
605 int num_share_modes = 0;
610 /* this is for OS/2 EAs - try and say we don't support them */
611 if (strstr(fname,".+,;=[]."))
613 unix_ERR_class = ERRDOS;
614 /* OS/2 Workplace shell fix may be main code stream in a later release. */
615 #if 1 /* OS2_WPS_FIX - Recent versions of OS/2 need this. */
616 unix_ERR_code = ERRcannotopen;
617 #else /* OS2_WPS_FIX */
618 unix_ERR_code = ERROR_EAS_NOT_SUPPORTED;
619 #endif /* OS2_WPS_FIX */
624 if ((ofun & 0x3) == 0 && file_existed)
632 if ((ofun & 0x3) == 2)
635 /* note that we ignore the append flag as
636 append does not mean the same thing under dos and unix */
638 switch (share_mode&0xF)
656 if (share_mode&(1<<14)) {
661 if (flags != O_RDONLY && file_existed &&
662 (!CAN_WRITE(conn) || IS_DOS_READONLY(dos_mode(conn,fname,&sbuf))))
672 if (deny_mode > DENY_NONE && deny_mode!=DENY_FCB)
674 DEBUG(2,("Invalid deny mode %d on file %s\n",deny_mode,fname));
679 if (deny_mode == DENY_FCB) deny_mode = DENY_DOS;
681 if (lp_share_modes(SNUM(conn)))
684 share_mode_entry *old_shares = 0;
690 lock_share_entry(conn, dev, inode, &token);
692 num_share_modes = get_share_modes(conn, token, dev, inode, &old_shares);
696 * Check if the share modes will give us access.
699 if(share_locked && (num_share_modes != 0))
706 broke_oplock = False;
707 for(i = 0; i < num_share_modes; i++)
709 share_mode_entry *share_entry = &old_shares[i];
712 * By observation of NetBench, oplocks are broken *before* share
713 * modes are checked. This allows a file to be closed by the client
714 * if the share mode would deny access and the client has an oplock.
715 * Check if someone has an oplock on this file. If so we must break
716 * it before continuing.
718 if(share_entry->op_type & (EXCLUSIVE_OPLOCK|BATCH_OPLOCK))
721 DEBUG(5,("open_file_shared: breaking oplock (%x) on file %s, \
722 dev = %x, inode = %x\n", share_entry->op_type, fname, dev, inode));
724 /* Oplock break.... */
725 unlock_share_entry(conn, dev, inode, token);
726 if(request_oplock_break(share_entry, dev, inode) == False)
728 free((char *)old_shares);
729 DEBUG(0,("open_file_shared: FAILED when breaking oplock (%x) on file %s, \
730 dev = %x, inode = %x\n", old_shares[i].op_type, fname, dev, inode));
732 unix_ERR_class = ERRDOS;
733 unix_ERR_code = ERRbadshare;
736 lock_share_entry(conn, dev, inode, &token);
741 /* someone else has a share lock on it, check to see
743 if(check_share_mode(share_entry, deny_mode, fname, fcbopen, &flags) == False)
745 free((char *)old_shares);
746 unlock_share_entry(conn, dev, inode, token);
748 unix_ERR_class = ERRDOS;
749 unix_ERR_code = ERRbadshare;
757 free((char *)old_shares);
758 num_share_modes = get_share_modes(conn, token, dev, inode, &old_shares);
760 } while(broke_oplock);
764 free((char *)old_shares);
767 DEBUG(4,("calling open_file with flags=0x%X flags2=0x%X mode=0%o\n",
770 open_file(fsp,conn,fname,flags|(flags2&~(O_TRUNC)),mode,file_existed ? &sbuf : 0);
771 if (!fsp->open && flags==O_RDWR && errno!=ENOENT && fcbopen)
774 open_file(fsp,conn,fname,flags,mode,file_existed ? &sbuf : 0 );
781 if((share_locked == False) && lp_share_modes(SNUM(conn)))
783 /* We created the file - thus we must now lock the share entry before creating it. */
784 dev = fsp->fd_ptr->dev;
785 inode = fsp->fd_ptr->inode;
786 lock_share_entry(conn, dev, inode, &token);
803 fsp->share_mode = (deny_mode<<4) | open_mode;
806 (*Access) = open_mode;
810 if (file_existed && !(flags2 & O_TRUNC)) *action = FILE_WAS_OPENED;
811 if (!file_existed) *action = FILE_WAS_CREATED;
812 if (file_existed && (flags2 & O_TRUNC)) *action = FILE_WAS_OVERWRITTEN;
814 /* We must create the share mode entry before truncate as
815 truncate can fail due to locking and have to close the
816 file (which expects the share_mode_entry to be there).
818 if (lp_share_modes(SNUM(conn)))
821 /* JRA. Currently this only services Exlcusive and batch
822 oplocks (no other opens on this file). This needs to
823 be extended to level II oplocks (multiple reader
826 if(oplock_request && (num_share_modes == 0) && lp_oplocks(SNUM(conn)) &&
827 !IS_VETO_OPLOCK_PATH(conn,fname))
829 fsp->granted_oplock = True;
830 fsp->sent_oplock_break = False;
831 global_oplocks_open++;
834 DEBUG(5,("open_file_shared: granted oplock (%x) on file %s, \
835 dev = %x, inode = %x\n", oplock_request, fname, dev, inode));
843 set_share_mode(token, fsp, port, oplock_request);
846 if ((flags2&O_TRUNC) && file_existed)
847 truncate_unless_locked(fsp,conn,token,&share_locked);
850 if (share_locked && lp_share_modes(SNUM(conn)))
851 unlock_share_entry( conn, dev, inode, token);
856 /****************************************************************************
857 Open a directory from an NT SMB call.
858 ****************************************************************************/
859 int open_directory(files_struct *fsp,connection_struct *conn,
860 char *fname, int smb_ofun, int unixmode, int *action)
862 extern struct current_user current_user;
865 if (smb_ofun & 0x10) {
867 * Create the directory.
870 if(dos_mkdir(fname, unixmode) < 0) {
871 DEBUG(0,("open_directory: unable to create %s. Error was %s\n",
872 fname, strerror(errno) ));
876 *action = FILE_WAS_CREATED;
879 * Check that it *was* a directory.
882 if(dos_stat(fname, &st) < 0) {
883 DEBUG(0,("open_directory: unable to stat name = %s. Error was %s\n",
884 fname, strerror(errno) ));
888 if(!S_ISDIR(st.st_mode)) {
889 DEBUG(0,("open_directory: %s is not a directory !\n", fname ));
892 *action = FILE_WAS_OPENED;
895 DEBUG(5,("open_directory: opening directory %s\n",
899 * Setup the files_struct for it.
903 conn->num_files_open++;
905 GetTimeOfDay(&fsp->open_time);
906 fsp->vuid = current_user.vuid;
910 fsp->mmap_ptr = NULL;
912 fsp->can_lock = True;
913 fsp->can_read = False;
914 fsp->can_write = False;
916 fsp->print_file = False;
917 fsp->modified = False;
918 fsp->granted_oplock = False;
919 fsp->sent_oplock_break = False;
920 fsp->is_directory = True;
923 * Note that the file name here is the *untranslated* name
924 * ie. it is still in the DOS codepage sent from the client.
925 * All use of this filename will pass though the sys_xxxx
926 * functions which will do the dos_to_unix translation before
927 * mapping into a UNIX filename. JRA.
929 string_set(&fsp->fsp_name,fname);
930 fsp->wbmpx_ptr = NULL;
935 enum {AFAIL,AREAD,AWRITE,AALL};
937 /*******************************************************************
938 reproduce the share mode access table
939 ********************************************************************/
940 static int access_table(int new_deny,int old_deny,int old_mode,
941 int share_pid,char *fname)
943 if (new_deny == DENY_ALL || old_deny == DENY_ALL) return(AFAIL);
945 if (new_deny == DENY_DOS || old_deny == DENY_DOS) {
947 if (old_deny == new_deny && share_pid == pid)
950 if (old_mode == 0) return(AREAD);
952 /* the new smbpub.zip spec says that if the file extension is
953 .com, .dll, .exe or .sym then allow the open. I will force
954 it to read-only as this seems sensible although the spec is
955 a little unclear on this. */
956 if ((fname = strrchr(fname,'.'))) {
957 if (strequal(fname,".com") ||
958 strequal(fname,".dll") ||
959 strequal(fname,".exe") ||
960 strequal(fname,".sym"))
970 if (old_deny==DENY_WRITE && old_mode==0) return(AREAD);
971 if (old_deny==DENY_READ && old_mode==0) return(AWRITE);
972 if (old_deny==DENY_NONE && old_mode==0) return(AALL);
975 if (old_deny==DENY_WRITE && old_mode==1) return(AREAD);
976 if (old_deny==DENY_READ && old_mode==1) return(AWRITE);
977 if (old_deny==DENY_NONE && old_mode==1) return(AALL);
980 if (old_deny==DENY_WRITE) return(AREAD);
981 if (old_deny==DENY_READ) return(AWRITE);
982 if (old_deny==DENY_NONE) return(AALL);
988 /*******************************************************************
989 check if the share mode on a file allows it to be deleted or unlinked
990 return True if sharing doesn't prevent the operation
991 ********************************************************************/
992 BOOL check_file_sharing(connection_struct *conn,char *fname, BOOL rename_op)
996 share_mode_entry *old_shares = 0;
998 SMB_STRUCT_STAT sbuf;
1004 if(!lp_share_modes(SNUM(conn)))
1007 if (dos_stat(fname,&sbuf) == -1) return(True);
1010 inode = sbuf.st_ino;
1012 lock_share_entry(conn, dev, inode, &token);
1013 num_share_modes = get_share_modes(conn, token, dev, inode, &old_shares);
1016 * Check if the share modes will give us access.
1019 if(num_share_modes != 0)
1026 broke_oplock = False;
1027 for(i = 0; i < num_share_modes; i++)
1029 share_mode_entry *share_entry = &old_shares[i];
1032 * Break oplocks before checking share modes. See comment in
1033 * open_file_shared for details.
1034 * Check if someone has an oplock on this file. If so we must
1035 * break it before continuing.
1037 if(share_entry->op_type & BATCH_OPLOCK)
1041 * It appears that the NT redirector may have a bug, in that
1042 * it tries to do an SMBmv on a file that it has open with a
1043 * batch oplock, and then fails to respond to the oplock break
1044 * request. This only seems to occur when the client is doing an
1045 * SMBmv to the smbd it is using - thus we try and detect this
1046 * condition by checking if the file being moved is open and oplocked by
1047 * this smbd process, and then not sending the oplock break in this
1048 * special case. If the file was open with a deny mode that
1049 * prevents the move the SMBmv will fail anyway with a share
1050 * violation error. JRA.
1052 if(rename_op && (share_entry->pid == pid))
1054 DEBUG(0,("check_file_sharing: NT redirector workaround - rename attempted on \
1055 batch oplocked file %s, dev = %x, inode = %x\n", fname, dev, inode));
1057 * This next line is a test that allows the deny-mode
1058 * processing to be skipped. This seems to be needed as
1059 * NT insists on the rename succeeding (in Office 9x no less !).
1060 * This should be removed as soon as (a) MS fix the redirector
1061 * bug or (b) NT SMB support in Samba makes NT not issue the
1062 * call (as is my fervent hope). JRA.
1068 DEBUG(5,("check_file_sharing: breaking oplock (%x) on file %s, \
1069 dev = %x, inode = %x\n", share_entry->op_type, fname, dev, inode));
1071 /* Oplock break.... */
1072 unlock_share_entry(conn, dev, inode, token);
1073 if(request_oplock_break(share_entry, dev, inode) == False)
1075 free((char *)old_shares);
1076 DEBUG(0,("check_file_sharing: FAILED when breaking oplock (%x) on file %s, \
1077 dev = %x, inode = %x\n", old_shares[i].op_type, fname, dev, inode));
1080 lock_share_entry(conn, dev, inode, &token);
1081 broke_oplock = True;
1086 /* someone else has a share lock on it, check to see
1088 if ((share_entry->share_mode != DENY_DOS) || (share_entry->pid != pid))
1095 free((char *)old_shares);
1096 num_share_modes = get_share_modes(conn, token, dev, inode, &old_shares);
1098 } while(broke_oplock);
1101 /* XXXX exactly what share mode combinations should be allowed for
1102 deleting/renaming? */
1103 /* If we got here then either there were no share modes or
1104 all share modes were DENY_DOS and the pid == getpid() */
1109 unlock_share_entry(conn, dev, inode, token);
1110 if(old_shares != NULL)
1111 free((char *)old_shares);
1115 /****************************************************************************
1116 check if we can open a file with a share mode
1117 ****************************************************************************/
1118 int check_share_mode( share_mode_entry *share, int deny_mode, char *fname,
1119 BOOL fcbopen, int *flags)
1121 int old_open_mode = share->share_mode &0xF;
1122 int old_deny_mode = (share->share_mode >>4)&7;
1124 if (old_deny_mode > 4 || old_open_mode > 2)
1126 DEBUG(0,("Invalid share mode found (%d,%d,%d) on file %s\n",
1127 deny_mode,old_deny_mode,old_open_mode,fname));
1132 int access_allowed = access_table(deny_mode,old_deny_mode,old_open_mode,
1135 if ((access_allowed == AFAIL) ||
1136 (!fcbopen && (access_allowed == AREAD && *flags == O_RDWR)) ||
1137 (access_allowed == AREAD && *flags == O_WRONLY) ||
1138 (access_allowed == AWRITE && *flags == O_RDONLY))
1140 DEBUG(2,("Share violation on file (%d,%d,%d,%d,%s,fcbopen = %d, flags = %d) = %d\n",
1141 deny_mode,old_deny_mode,old_open_mode,
1142 share->pid,fname, fcbopen, *flags, access_allowed));
1146 if (access_allowed == AREAD)
1149 if (access_allowed == AWRITE)