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 uint16 global_oplock_port
;
28 extern BOOL global_client_failed_oplock_break
;
30 /****************************************************************************
31 fd support routines - attempt to do a dos_open
32 ****************************************************************************/
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 ****************************************************************************/
87 void fd_add_to_uid_cache(file_fd_struct
*fd_ptr
, uid_t u
)
89 if(fd_ptr
->uid_cache_count
>= sizeof(fd_ptr
->uid_users_cache
)/sizeof(uid_t
))
91 fd_ptr
->uid_users_cache
[fd_ptr
->uid_cache_count
++] = u
;
94 /****************************************************************************
95 Remove a uid_t that currently has this file open. This is an optimization only
96 used when multiple sessionsetup's have been done to one smbd.
97 ****************************************************************************/
99 static void fd_remove_from_uid_cache(file_fd_struct
*fd_ptr
, uid_t u
)
102 for(i
= 0; i
< fd_ptr
->uid_cache_count
; i
++)
103 if(fd_ptr
->uid_users_cache
[i
] == u
) {
104 if(i
< (fd_ptr
->uid_cache_count
-1))
105 memmove((char *)&fd_ptr
->uid_users_cache
[i
], (char *)&fd_ptr
->uid_users_cache
[i
+1],
106 sizeof(uid_t
)*(fd_ptr
->uid_cache_count
-1-i
) );
107 fd_ptr
->uid_cache_count
--;
112 /****************************************************************************
113 Check if a uid_t that currently has this file open is present. This is an
114 optimization only used when multiple sessionsetup's have been done to one smbd.
115 ****************************************************************************/
117 static BOOL
fd_is_in_uid_cache(file_fd_struct
*fd_ptr
, uid_t u
)
120 for(i
= 0; i
< fd_ptr
->uid_cache_count
; i
++)
121 if(fd_ptr
->uid_users_cache
[i
] == u
)
126 /****************************************************************************
127 fd support routines - attempt to re-open an already open fd as O_RDWR.
128 Save the already open fd (we cannot close due to POSIX file locking braindamage.
129 ****************************************************************************/
131 static void fd_attempt_reopen(char *fname
, mode_t mode
, file_fd_struct
*fd_ptr
)
133 int fd
= dos_open( fname
, O_RDWR
, mode
);
138 if(fd_ptr
->real_open_flags
== O_RDONLY
)
139 fd_ptr
->fd_readonly
= fd_ptr
->fd
;
140 if(fd_ptr
->real_open_flags
== O_WRONLY
)
141 fd_ptr
->fd_writeonly
= fd_ptr
->fd
;
144 fd_ptr
->real_open_flags
= O_RDWR
;
147 /****************************************************************************
148 fd support routines - attempt to close the file referenced by this fd.
149 Decrements the ref_count and returns it.
150 ****************************************************************************/
152 uint16
fd_attempt_close(file_fd_struct
*fd_ptr
, int *err_ret
)
154 extern struct current_user current_user
;
155 uint16 ret_ref
= fd_ptr
->ref_count
;
159 DEBUG(3,("fd_attempt_close fd = %d, dev = %x, inode = %.0f, open_flags = %d, ref_count = %d.\n",
160 fd_ptr
->fd
, (unsigned int)fd_ptr
->dev
, (double)fd_ptr
->inode
,
161 fd_ptr
->real_open_flags
,
164 SMB_ASSERT(fd_ptr
->ref_count
!= 0);
167 ret_ref
= fd_ptr
->ref_count
;
169 if(fd_ptr
->ref_count
== 0) {
171 if(fd_ptr
->fd
!= -1) {
172 if(close(fd_ptr
->fd
) < 0)
176 if(fd_ptr
->fd_readonly
!= -1) {
177 if(close(fd_ptr
->fd_readonly
) < 0) {
183 if(fd_ptr
->fd_writeonly
!= -1) {
184 if( close(fd_ptr
->fd_writeonly
) < 0) {
191 * Delete this fd_ptr.
195 fd_remove_from_uid_cache(fd_ptr
, (uid_t
)current_user
.uid
);
201 /****************************************************************************
202 Shutdown a half-open filestruct. This allows open_file_shared to back out
204 ****************************************************************************/
206 static void close_on_error(files_struct
*fsp
, connection_struct
*conn
)
210 close_filestruct(fsp
);
212 fd_attempt_close(fsp
->fd_ptr
,&err
);
217 string_free(&fsp
->fsp_name
);
221 /****************************************************************************
222 fd support routines - check that current user has permissions
223 to open this file. Used when uid not found in optimization cache.
224 This is really ugly code, as due to POSIX locking braindamage we must
225 fork and then attempt to open the file, and return success or failure
227 ****************************************************************************/
229 static BOOL
check_access_allowed_for_current_user( char *fname
, int accmode
)
234 * We need to temporarily stop CatchChild from eating
235 * SIGCLD signals as it also eats the exit status code. JRA.
238 CatchChildLeaveStatus();
240 if((child_pid
= fork()) < 0) {
241 DEBUG(0,("check_access_allowed_for_current_user: fork failed.\n"));
253 while ((wpid
= sys_waitpid(child_pid
, &status_code
, 0)) < 0) {
258 DEBUG(0,("check_access_allowed_for_current_user: The process \
259 is no longer waiting ! Error = %s\n", strerror(errno
) ));
265 * Go back to ignoring children.
269 if (child_pid
!= wpid
) {
270 DEBUG(0,("check_access_allowed_for_current_user: We were waiting for the wrong process ID\n"));
273 #if defined(WIFEXITED) && defined(WEXITSTATUS)
274 if (WIFEXITED(status_code
) == 0) {
275 DEBUG(0,("check_access_allowed_for_current_user: The process exited while we were waiting\n"));
278 if (WEXITSTATUS(status_code
) != 0) {
279 DEBUG(9,("check_access_allowed_for_current_user: The status of the process exiting was %d. Returning access denied.\n", status_code
));
282 #else /* defined(WIFEXITED) && defined(WEXITSTATUS) */
283 if(status_code
!= 0) {
284 DEBUG(9,("check_access_allowed_for_current_user: The status of the process exiting was %d. Returning access denied.\n", status_code
));
287 #endif /* defined(WIFEXITED) && defined(WEXITSTATUS) */
290 * Success - the child could open the file.
292 DEBUG(9,("check_access_allowed_for_current_user: The status of the process exiting was %d. Returning access allowed.\n", status_code
));
299 DEBUG(9,("check_access_allowed_for_current_user: Child - attempting to open %s with mode %d.\n", fname
, accmode
));
300 if((fd
= fd_attempt_open( fname
, accmode
, 0)) < 0) {
305 DEBUG(9,("check_access_allowed_for_current_user: Child - returning ok.\n"));
312 /****************************************************************************
313 check a filename for the pipe string
314 ****************************************************************************/
316 static void check_for_pipe(char *fname
)
318 /* special case of pipe opens */
320 StrnCpy(s
,fname
,sizeof(s
)-1);
322 if (strstr(s
,"pipe/")) {
323 DEBUG(3,("Rejecting named pipe open for %s\n",fname
));
324 unix_ERR_class
= ERRSRV
;
325 unix_ERR_code
= ERRaccess
;
329 /****************************************************************************
331 ****************************************************************************/
333 static void open_file(files_struct
*fsp
,connection_struct
*conn
,
334 char *fname1
,int flags
,mode_t mode
, SMB_STRUCT_STAT
*sbuf
)
336 extern struct current_user current_user
;
338 SMB_STRUCT_STAT statbuf
;
339 file_fd_struct
*fd_ptr
;
340 int accmode
= (flags
& O_ACCMODE
);
344 fsp
->oplock_type
= NO_OPLOCK
;
347 pstrcpy(fname
,fname1
);
349 /* check permissions */
352 * This code was changed after seeing a client open request
353 * containing the open mode of (DENY_WRITE/read-only) with
354 * the 'create if not exist' bit set. The previous code
355 * would fail to open the file read only on a read-only share
356 * as it was checking the flags parameter directly against O_RDONLY,
357 * this was failing as the flags parameter was set to O_RDONLY|O_CREAT.
361 if (!CAN_WRITE(conn
) && !conn
->printer
) {
362 /* It's a read-only share - fail if we wanted to write. */
363 if(accmode
!= O_RDONLY
) {
364 DEBUG(3,("Permission denied opening %s\n",fname
));
365 check_for_pipe(fname
);
367 } else if(flags
& O_CREAT
) {
368 /* We don't want to write - but we must make sure that O_CREAT
369 doesn't create the file if we have write access into the
376 /* this handles a bug in Win95 - it doesn't say to create the file when it
379 flags
|= (O_CREAT
|O_EXCL
);
383 if (flags == O_WRONLY)
384 DEBUG(3,("Bug in client? Set O_WRONLY without O_CREAT\n"));
388 * Ensure we have a valid struct stat so we can search the
392 if(dos_stat(fname
, &statbuf
) < 0) {
393 if(errno
!= ENOENT
) {
394 DEBUG(3,("Error doing stat on file %s (%s)\n",
395 fname
,strerror(errno
)));
397 check_for_pipe(fname
);
407 * Check to see if we have this file already
408 * open. If we do, just use the already open fd and increment the
409 * reference count (fd_get_already_open increments the ref_count).
411 if((fd_ptr
= fd_get_already_open(sbuf
))!= 0) {
413 * File was already open.
417 * Check it wasn't open for exclusive use.
419 if((flags
& O_CREAT
) && (flags
& O_EXCL
)) {
426 * Ensure that the user attempting to open
427 * this file has permissions to do so, if
428 * the user who originally opened the file wasn't
429 * the same as the current user.
432 if(!fd_is_in_uid_cache(fd_ptr
, (uid_t
)current_user
.uid
)) {
433 if(!check_access_allowed_for_current_user( fname
, accmode
)) {
434 /* Error - permission denied. */
435 DEBUG(3,("Permission denied opening file %s (flags=%d, accmode = %d)\n",
436 fname
, flags
, accmode
));
437 /* Ensure the ref_count is decremented. */
439 fd_remove_from_uid_cache(fd_ptr
, (uid_t
)current_user
.uid
);
445 fd_add_to_uid_cache(fd_ptr
, (uid_t
)current_user
.uid
);
448 * If not opened O_RDWR try
449 * and do that here - a chmod may have been done
450 * between the last open and now.
452 if(fd_ptr
->real_open_flags
!= O_RDWR
)
453 fd_attempt_reopen(fname
, mode
, fd_ptr
);
456 * Ensure that if we wanted write access
457 * it has been opened for write, and if we wanted read it
460 if(((accmode
== O_WRONLY
) && (fd_ptr
->real_open_flags
== O_RDONLY
)) ||
461 ((accmode
== O_RDONLY
) && (fd_ptr
->real_open_flags
== O_WRONLY
)) ||
462 ((accmode
== O_RDWR
) && (fd_ptr
->real_open_flags
!= O_RDWR
))) {
463 DEBUG(3,("Error opening (already open for flags=%d) file %s (%s) (flags=%d)\n",
464 fd_ptr
->real_open_flags
, fname
,strerror(EACCES
),flags
));
465 check_for_pipe(fname
);
466 fd_remove_from_uid_cache(fd_ptr
, (uid_t
)current_user
.uid
);
473 /* We need to allocate a new file_fd_struct (this increments the
475 if((fd_ptr
= fd_get_new()) == 0)
478 * Whatever the requested flags, attempt read/write access,
479 * as we don't know what flags future file opens may require.
480 * If this fails, try again with the required flags.
481 * Even if we open read/write when only read access was
482 * requested the setting of the can_write flag in
483 * the file_struct will protect us from errant
484 * write requests. We never need to worry about O_APPEND
485 * as this is not set anywhere in Samba.
487 fd_ptr
->real_open_flags
= O_RDWR
;
488 /* Set the flags as needed without the read/write modes. */
489 open_flags
= flags
& ~(O_RDWR
|O_WRONLY
|O_RDONLY
);
490 fd_ptr
->fd
= fd_attempt_open(fname
, open_flags
|O_RDWR
, mode
);
492 * On some systems opening a file for R/W access on a read only
493 * filesystems sets errno to EROFS.
496 if((fd_ptr
->fd
== -1) && ((errno
== EACCES
) || (errno
== EROFS
))) {
498 if((fd_ptr
->fd
== -1) && (errno
== EACCES
)) {
500 if(accmode
!= O_RDWR
) {
501 fd_ptr
->fd
= fd_attempt_open(fname
, open_flags
|accmode
, mode
);
502 fd_ptr
->real_open_flags
= accmode
;
507 if ((fd_ptr
->fd
>=0) &&
508 conn
->printer
&& lp_minprintspace(SNUM(conn
))) {
510 SMB_BIG_UINT dum1
,dum2
,dum3
;
512 pstrcpy(dname
,fname
);
513 p
= strrchr(dname
,'/');
515 if (sys_disk_free(dname
,False
,&dum1
,&dum2
,&dum3
) < (SMB_BIG_UINT
)lp_minprintspace(SNUM(conn
))) {
517 if(fd_attempt_close(fd_ptr
, &err
) == 0)
528 DEBUG(3,("Error opening file %s (%s) (flags=%d)\n",
529 fname
,strerror(errno
),flags
));
530 /* Ensure the ref_count is decremented. */
531 fd_attempt_close(fd_ptr
,&err
);
532 check_for_pipe(fname
);
540 if(sys_fstat(fd_ptr
->fd
, &statbuf
) == -1) {
542 /* Error - backout !! */
543 DEBUG(3,("Error doing fstat on fd %d, file %s (%s)\n",
544 fd_ptr
->fd
, fname
,strerror(errno
)));
545 /* Ensure the ref_count is decremented. */
546 fd_attempt_close(fd_ptr
,&err
);
552 /* Set the correct entries in fd_ptr. */
553 fd_ptr
->dev
= sbuf
->st_dev
;
554 fd_ptr
->inode
= sbuf
->st_ino
;
556 fsp
->fd_ptr
= fd_ptr
;
557 conn
->num_files_open
++;
558 fsp
->mode
= sbuf
->st_mode
;
559 GetTimeOfDay(&fsp
->open_time
);
560 fsp
->vuid
= current_user
.vuid
;
564 fsp
->can_lock
= True
;
565 fsp
->can_read
= ((flags
& O_WRONLY
)==0);
566 fsp
->can_write
= ((flags
& (O_WRONLY
|O_RDWR
))!=0);
568 fsp
->print_file
= conn
->printer
;
569 fsp
->modified
= False
;
570 fsp
->oplock_type
= NO_OPLOCK
;
571 fsp
->sent_oplock_break
= NO_BREAK_SENT
;
572 fsp
->is_directory
= False
;
573 fsp
->stat_open
= False
;
574 fsp
->directory_delete_on_close
= False
;
577 * Note that the file name here is the *untranslated* name
578 * ie. it is still in the DOS codepage sent from the client.
579 * All use of this filename will pass though the sys_xxxx
580 * functions which will do the dos_to_unix translation before
581 * mapping into a UNIX filename. JRA.
583 string_set(&fsp
->fsp_name
,fname
);
584 fsp
->wbmpx_ptr
= NULL
;
585 fsp
->wcp
= NULL
; /* Write cache pointer. */
588 * If the printer is marked as postscript output a leading
589 * file identifier to ensure the file is treated as a raw
591 * This has a similar effect as CtrlD=0 in WIN.INI file.
592 * tim@fsg.com 09/06/94
594 if (fsp
->print_file
&& lp_postscript(SNUM(conn
)) && fsp
->can_write
) {
595 DEBUG(3,("Writing postscript line\n"));
596 write_file(fsp
,"%!\n",-1,3);
599 DEBUG(2,("%s opened file %s read=%s write=%s (numopen=%d)\n",
600 *sesssetup_user
? sesssetup_user
: conn
->user
,fsp
->fsp_name
,
601 BOOLSTR(fsp
->can_read
), BOOLSTR(fsp
->can_write
),
602 conn
->num_files_open
));
607 /****************************************************************************
609 Helper for open_file_shared.
610 Truncate a file after checking locking; close file if locked.
611 **************************************************************************/
613 static void truncate_unless_locked(files_struct
*fsp
, connection_struct
*conn
, int token
,
617 SMB_OFF_T mask2
= ((SMB_OFF_T
)0x3) << (SMB_OFF_T_BITS
-4);
618 SMB_OFF_T mask
= (mask2
<<2);
620 if (is_locked(fsp
,conn
,~mask
,0,F_WRLCK
)){
621 /* If share modes are in force for this connection we
622 have the share entry locked. Unlock it before closing. */
623 if (*share_locked
&& lp_share_modes(SNUM(conn
)))
624 unlock_share_entry( conn
, fsp
->fd_ptr
->dev
,
625 fsp
->fd_ptr
->inode
, token
);
626 close_on_error(fsp
,conn
);
627 /* Share mode no longer locked. */
628 *share_locked
= False
;
630 unix_ERR_class
= ERRDOS
;
631 unix_ERR_code
= ERRlock
;
633 sys_ftruncate(fsp
->fd_ptr
->fd
,0);
639 /*******************************************************************
640 return True if the filename is one of the special executable types
641 ********************************************************************/
642 static BOOL
is_executable(char *fname
)
644 if ((fname
= strrchr(fname
,'.'))) {
645 if (strequal(fname
,".com") ||
646 strequal(fname
,".dll") ||
647 strequal(fname
,".exe") ||
648 strequal(fname
,".sym")) {
655 enum {AFAIL
,AREAD
,AWRITE
,AALL
};
657 /*******************************************************************
658 reproduce the share mode access table
659 this is horrendoously complex, and really can't be justified on any
660 rational grounds except that this is _exactly_ what NT does. See
661 the DENY1 and DENY2 tests in smbtorture for a comprehensive set of
663 ********************************************************************/
664 static int access_table(int new_deny
,int old_deny
,int old_mode
,
665 BOOL same_pid
, BOOL isexe
)
667 if (new_deny
== DENY_ALL
|| old_deny
== DENY_ALL
) return(AFAIL
);
670 if (isexe
&& old_mode
== DOS_OPEN_RDONLY
&&
671 old_deny
== DENY_DOS
&& new_deny
== DENY_READ
) {
674 if (!isexe
&& old_mode
== DOS_OPEN_RDONLY
&&
675 old_deny
== DENY_DOS
&& new_deny
== DENY_DOS
) {
678 if (new_deny
== DENY_FCB
&& old_deny
== DENY_DOS
) {
679 if (isexe
) return AFAIL
;
680 if (old_mode
== DOS_OPEN_RDONLY
) return AFAIL
;
683 if (old_mode
== DOS_OPEN_RDONLY
&& old_deny
== DENY_DOS
) {
684 if (new_deny
== DENY_FCB
|| new_deny
== DENY_READ
) {
685 if (isexe
) return AREAD
;
689 if (old_deny
== DENY_FCB
) {
690 if (new_deny
== DENY_DOS
|| new_deny
== DENY_FCB
) return AALL
;
695 if (old_deny
== DENY_DOS
|| new_deny
== DENY_DOS
||
696 old_deny
== DENY_FCB
|| new_deny
== DENY_FCB
) {
698 if (old_deny
== DENY_FCB
|| new_deny
== DENY_FCB
) {
701 if (old_deny
== DENY_DOS
) {
702 if (new_deny
== DENY_READ
&&
703 (old_mode
== DOS_OPEN_RDONLY
||
704 old_mode
== DOS_OPEN_RDWR
)) {
707 if (new_deny
== DENY_WRITE
&&
708 (old_mode
== DOS_OPEN_WRONLY
||
709 old_mode
== DOS_OPEN_RDWR
)) {
714 if (old_deny
== DENY_NONE
) return AALL
;
715 if (old_deny
== DENY_READ
) return AWRITE
;
716 if (old_deny
== DENY_WRITE
) return AREAD
;
718 /* it isn't a exe, dll, sym or com file */
719 if (old_deny
== new_deny
&& same_pid
)
722 if (old_deny
== DENY_READ
|| new_deny
== DENY_READ
) return AFAIL
;
723 if (old_mode
== DOS_OPEN_RDONLY
) return(AREAD
);
731 if (old_deny
==DENY_WRITE
&& old_mode
==DOS_OPEN_RDONLY
) return(AREAD
);
732 if (old_deny
==DENY_READ
&& old_mode
==DOS_OPEN_RDONLY
) return(AWRITE
);
733 if (old_deny
==DENY_NONE
&& old_mode
==DOS_OPEN_RDONLY
) return(AALL
);
736 if (old_deny
==DENY_WRITE
&& old_mode
==DOS_OPEN_WRONLY
) return(AREAD
);
737 if (old_deny
==DENY_READ
&& old_mode
==DOS_OPEN_WRONLY
) return(AWRITE
);
738 if (old_deny
==DENY_NONE
&& old_mode
==DOS_OPEN_WRONLY
) return(AALL
);
741 if (old_deny
==DENY_WRITE
) return(AREAD
);
742 if (old_deny
==DENY_READ
) return(AWRITE
);
743 if (old_deny
==DENY_NONE
) return(AALL
);
750 /****************************************************************************
751 check if we can open a file with a share mode
752 ****************************************************************************/
754 static int check_share_mode( share_mode_entry
*share
, int deny_mode
,
756 BOOL fcbopen
, int *flags
)
758 int old_open_mode
= GET_OPEN_MODE(share
->share_mode
);
759 int old_deny_mode
= GET_DENY_MODE(share
->share_mode
);
762 * Don't allow any open once the delete on close flag has been
766 if(GET_DELETE_ON_CLOSE_FLAG(share
->share_mode
))
768 DEBUG(5,("check_share_mode: Failing open on file %s as delete on close flag is set.\n",
770 unix_ERR_class
= ERRDOS
;
771 unix_ERR_code
= ERRnoaccess
;
776 int access_allowed
= access_table(deny_mode
,old_deny_mode
,old_open_mode
,
777 (share
->pid
== getpid()),is_executable(fname
));
779 if ((access_allowed
== AFAIL
) ||
780 (!fcbopen
&& (access_allowed
== AREAD
&& *flags
== O_RDWR
)) ||
781 (access_allowed
== AREAD
&& *flags
!= O_RDONLY
) ||
782 (access_allowed
== AWRITE
&& *flags
!= O_WRONLY
))
784 DEBUG(2,("Share violation on file (%d,%d,%d,%d,%s,fcbopen = %d, flags = %d) = %d\n",
785 deny_mode
,old_deny_mode
,old_open_mode
,
786 (int)share
->pid
,fname
, fcbopen
, *flags
, access_allowed
));
788 unix_ERR_class
= ERRDOS
;
789 unix_ERR_code
= ERRbadshare
;
794 if (access_allowed
== AREAD
)
797 if (access_allowed
== AWRITE
)
805 /****************************************************************************
806 open a file with a share mode
807 ****************************************************************************/
809 void open_file_shared(files_struct
*fsp
,connection_struct
*conn
,char *fname
,int share_mode
,int ofun
,
810 mode_t mode
,int oplock_request
, int *Access
,int *action
)
814 int deny_mode
= GET_DENY_MODE(share_mode
);
815 BOOL allow_share_delete
= GET_ALLOW_SHARE_DELETE(share_mode
);
816 SMB_STRUCT_STAT sbuf
;
817 BOOL file_existed
= dos_file_exist(fname
,&sbuf
);
818 BOOL share_locked
= False
;
819 BOOL fcbopen
= False
;
823 int num_share_modes
= 0;
824 int oplock_contention_count
= 0;
825 BOOL all_current_opens_are_level_II
= False
;
829 DEBUG(10,("open_file_shared: fname = %s, share_mode = %x, ofun = %x, mode = %o, oplock request = %d\n",
830 fname
, share_mode
, ofun
, (int)mode
, oplock_request
));
832 if (!check_name(fname
,conn
)) {
836 /* ignore any oplock requests if oplocks are disabled */
837 if (!lp_oplocks(SNUM(conn
)) || global_client_failed_oplock_break
) {
841 /* this is for OS/2 EAs - try and say we don't support them */
842 if (strstr(fname
,".+,;=[]."))
844 unix_ERR_class
= ERRDOS
;
845 /* OS/2 Workplace shell fix may be main code stream in a later release. */
846 #if 1 /* OS2_WPS_FIX - Recent versions of OS/2 need this. */
847 unix_ERR_code
= ERRcannotopen
;
848 #else /* OS2_WPS_FIX */
849 unix_ERR_code
= ERROR_EAS_NOT_SUPPORTED
;
850 #endif /* OS2_WPS_FIX */
852 DEBUG(5,("open_file_shared: OS/2 EA's are not supported.\n"));
856 if ((GET_FILE_OPEN_DISPOSITION(ofun
) == FILE_EXISTS_FAIL
) && file_existed
)
858 DEBUG(5,("open_file_shared: create new requested for file %s and file already exists.\n",
864 if (GET_FILE_CREATE_DISPOSITION(ofun
) == FILE_CREATE_IF_NOT_EXIST
)
867 if (GET_FILE_OPEN_DISPOSITION(ofun
) == FILE_EXISTS_TRUNCATE
)
870 if (GET_FILE_OPEN_DISPOSITION(ofun
) == FILE_EXISTS_FAIL
)
873 /* note that we ignore the append flag as
874 append does not mean the same thing under dos and unix */
876 switch (GET_OPEN_MODE(share_mode
))
878 case DOS_OPEN_WRONLY
:
894 if (GET_FILE_SYNC_OPENMODE(share_mode
)) {
899 if (flags
!= O_RDONLY
&& file_existed
&&
900 (!CAN_WRITE(conn
) || IS_DOS_READONLY(dos_mode(conn
,fname
,&sbuf
))))
904 DEBUG(5,("open_file_shared: read/write access requested for file %s on read only %s\n",
905 fname
, !CAN_WRITE(conn
) ? "share" : "file" ));
912 if (deny_mode
> DENY_NONE
&& deny_mode
!=DENY_FCB
)
914 DEBUG(2,("Invalid deny mode %d on file %s\n",deny_mode
,fname
));
919 if (lp_share_modes(SNUM(conn
)))
922 share_mode_entry
*old_shares
= 0;
928 lock_share_entry(conn
, dev
, inode
, &token
);
930 num_share_modes
= get_share_modes(conn
, token
, dev
, inode
, &old_shares
);
934 * Check if the share modes will give us access.
937 if(share_locked
&& (num_share_modes
!= 0))
944 broke_oplock
= False
;
945 all_current_opens_are_level_II
= True
;
947 for(i
= 0; i
< num_share_modes
; i
++)
949 share_mode_entry
*share_entry
= &old_shares
[i
];
952 * By observation of NetBench, oplocks are broken *before* share
953 * modes are checked. This allows a file to be closed by the client
954 * if the share mode would deny access and the client has an oplock.
955 * Check if someone has an oplock on this file. If so we must break
956 * it before continuing.
958 if((oplock_request
&& EXCLUSIVE_OPLOCK_TYPE(share_entry
->op_type
)) ||
959 (!oplock_request
&& (share_entry
->op_type
!= NO_OPLOCK
)))
962 DEBUG(5,("open_file_shared: breaking oplock (%x) on file %s, \
963 dev = %x, inode = %.0f\n", share_entry
->op_type
, fname
, (unsigned int)dev
, (double)inode
));
965 /* Oplock break.... */
966 unlock_share_entry(conn
, dev
, inode
, token
);
967 if(request_oplock_break(share_entry
, dev
, inode
) == False
)
969 free((char *)old_shares
);
971 DEBUG(0,("open_file_shared: FAILED when breaking oplock (%x) on file %s, \
972 dev = %x, inode = %.0f\n", old_shares
[i
].op_type
, fname
, (unsigned int)dev
, (double)inode
));
975 unix_ERR_class
= ERRDOS
;
976 unix_ERR_code
= ERRbadshare
;
979 lock_share_entry(conn
, dev
, inode
, &token
);
981 all_current_opens_are_level_II
= False
;
983 } else if (!LEVEL_II_OPLOCK_TYPE(share_entry
->op_type
)) {
984 all_current_opens_are_level_II
= False
;
987 /* someone else has a share lock on it, check to see
989 if(check_share_mode(share_entry
, deny_mode
, fname
, fcbopen
, &flags
) == False
)
991 free((char *)old_shares
);
992 unlock_share_entry(conn
, dev
, inode
, token
);
1001 free((char *)old_shares
);
1002 num_share_modes
= get_share_modes(conn
, token
, dev
, inode
, &old_shares
);
1003 oplock_contention_count
++;
1005 } while(broke_oplock
);
1009 free((char *)old_shares
);
1013 * Refuse to grant an oplock in case the contention limit is
1014 * reached when going through the lock list multiple times.
1017 if(oplock_contention_count
>= lp_oplock_contention_limit(SNUM(conn
)))
1020 DEBUG(4,("open_file_shared: oplock contention = %d. Not granting oplock.\n",
1021 oplock_contention_count
));
1024 DEBUG(4,("calling open_file with flags=0x%X flags2=0x%X mode=0%o\n",
1025 flags
,flags2
,(int)mode
));
1027 open_file(fsp
,conn
,fname
,flags
|(flags2
&~(O_TRUNC
)),mode
,file_existed
? &sbuf
: 0);
1028 if (!fsp
->open
&& flags
==O_RDWR
&& errno
!=ENOENT
&& fcbopen
)
1031 open_file(fsp
,conn
,fname
,flags
,mode
,file_existed
? &sbuf
: 0 );
1038 if((share_locked
== False
) && lp_share_modes(SNUM(conn
)))
1040 /* We created the file - thus we must now lock the share entry before creating it. */
1041 dev
= fsp
->fd_ptr
->dev
;
1042 inode
= fsp
->fd_ptr
->inode
;
1043 lock_share_entry(conn
, dev
, inode
, &token
);
1044 share_locked
= True
;
1050 open_mode
= DOS_OPEN_RDONLY
;
1053 open_mode
= DOS_OPEN_RDWR
;
1056 open_mode
= DOS_OPEN_WRONLY
;
1060 fsp
->share_mode
= SET_DENY_MODE(deny_mode
) |
1061 SET_OPEN_MODE(open_mode
) |
1062 SET_ALLOW_SHARE_DELETE(allow_share_delete
);
1065 (*Access
) = open_mode
;
1069 if (file_existed
&& !(flags2
& O_TRUNC
)) *action
= FILE_WAS_OPENED
;
1070 if (!file_existed
) *action
= FILE_WAS_CREATED
;
1071 if (file_existed
&& (flags2
& O_TRUNC
)) *action
= FILE_WAS_OVERWRITTEN
;
1073 /* We must create the share mode entry before truncate as
1074 truncate can fail due to locking and have to close the
1075 file (which expects the share_mode_entry to be there).
1077 if (lp_share_modes(SNUM(conn
)))
1082 * Setup the oplock info in both the shared memory and
1086 if(oplock_request
&& (num_share_modes
== 0) &&
1087 !IS_VETO_OPLOCK_PATH(conn
,fname
) && set_file_oplock(fsp
, oplock_request
) ) {
1088 port
= global_oplock_port
;
1089 } else if (oplock_request
&& all_current_opens_are_level_II
) {
1090 port
= global_oplock_port
;
1091 oplock_request
= LEVEL_II_OPLOCK
;
1092 set_file_oplock(fsp
, oplock_request
);
1098 set_share_mode(token
, fsp
, port
, oplock_request
);
1101 if ((flags2
&O_TRUNC
) && file_existed
)
1102 truncate_unless_locked(fsp
,conn
,token
,&share_locked
);
1105 if (share_locked
&& lp_share_modes(SNUM(conn
)))
1106 unlock_share_entry( conn
, dev
, inode
, token
);
1109 /****************************************************************************
1110 Open a file for permissions read only. Return a pseudo file entry
1111 with the 'stat_open' flag set and a fd_ptr of NULL.
1112 ****************************************************************************/
1114 int open_file_stat(files_struct
*fsp
,connection_struct
*conn
,
1115 char *fname
, int smb_ofun
, SMB_STRUCT_STAT
*pst
, int *action
)
1117 extern struct current_user current_user
;
1119 if(dos_stat(fname
, pst
) < 0) {
1120 DEBUG(0,("open_file_stat: unable to stat name = %s. Error was %s\n",
1121 fname
, strerror(errno
) ));
1125 if(S_ISDIR(pst
->st_mode
)) {
1126 DEBUG(0,("open_file_stat: %s is a directory !\n", fname
));
1130 *action
= FILE_WAS_OPENED
;
1132 DEBUG(5,("open_file_stat: opening file %s as a stat entry\n", fname
));
1135 * Setup the files_struct for it.
1139 conn
->num_files_open
++;
1141 GetTimeOfDay(&fsp
->open_time
);
1142 fsp
->vuid
= current_user
.vuid
;
1146 fsp
->can_lock
= False
;
1147 fsp
->can_read
= False
;
1148 fsp
->can_write
= False
;
1149 fsp
->share_mode
= 0;
1150 fsp
->print_file
= False
;
1151 fsp
->modified
= False
;
1152 fsp
->oplock_type
= NO_OPLOCK
;
1153 fsp
->sent_oplock_break
= NO_BREAK_SENT
;
1154 fsp
->is_directory
= False
;
1155 fsp
->stat_open
= True
;
1156 fsp
->directory_delete_on_close
= False
;
1159 * Note that the file name here is the *untranslated* name
1160 * ie. it is still in the DOS codepage sent from the client.
1161 * All use of this filename will pass though the sys_xxxx
1162 * functions which will do the dos_to_unix translation before
1163 * mapping into a UNIX filename. JRA.
1165 string_set(&fsp
->fsp_name
,fname
);
1166 fsp
->wbmpx_ptr
= NULL
;
1167 fsp
->wcp
= NULL
; /* Write cache pointer. */
1172 /****************************************************************************
1173 Open a directory from an NT SMB call.
1174 ****************************************************************************/
1176 int open_directory(files_struct
*fsp
,connection_struct
*conn
,
1177 char *fname
, int smb_ofun
, mode_t unixmode
, int *action
)
1179 extern struct current_user current_user
;
1181 BOOL got_stat
= False
;
1183 if(dos_stat(fname
, &st
) == 0) {
1187 if (got_stat
&& (GET_FILE_OPEN_DISPOSITION(smb_ofun
) == FILE_EXISTS_FAIL
)) {
1188 errno
= EEXIST
; /* Setup so correct error is returned to client. */
1192 if (GET_FILE_CREATE_DISPOSITION(smb_ofun
) == FILE_CREATE_IF_NOT_EXIST
) {
1196 if(!S_ISDIR(st
.st_mode
)) {
1197 DEBUG(0,("open_directory: %s is not a directory !\n", fname
));
1201 *action
= FILE_WAS_OPENED
;
1206 * Try and create the directory.
1209 if(!CAN_WRITE(conn
)) {
1210 DEBUG(2,("open_directory: failing create on read-only share\n"));
1215 if(dos_mkdir(fname
, unix_mode(conn
,aDIR
, fname
)) < 0) {
1216 DEBUG(0,("open_directory: unable to create %s. Error was %s\n",
1217 fname
, strerror(errno
) ));
1220 *action
= FILE_WAS_CREATED
;
1226 * Don't create - just check that it *was* a directory.
1230 DEBUG(0,("open_directory: unable to stat name = %s. Error was %s\n",
1231 fname
, strerror(errno
) ));
1235 if(!S_ISDIR(st
.st_mode
)) {
1236 DEBUG(0,("open_directory: %s is not a directory !\n", fname
));
1240 *action
= FILE_WAS_OPENED
;
1243 DEBUG(5,("open_directory: opening directory %s\n",
1247 * Setup the files_struct for it.
1251 conn
->num_files_open
++;
1253 GetTimeOfDay(&fsp
->open_time
);
1254 fsp
->vuid
= current_user
.vuid
;
1258 fsp
->can_lock
= True
;
1259 fsp
->can_read
= False
;
1260 fsp
->can_write
= False
;
1261 fsp
->share_mode
= 0;
1262 fsp
->print_file
= False
;
1263 fsp
->modified
= False
;
1264 fsp
->oplock_type
= NO_OPLOCK
;
1265 fsp
->sent_oplock_break
= NO_BREAK_SENT
;
1266 fsp
->is_directory
= True
;
1267 fsp
->directory_delete_on_close
= False
;
1270 * Note that the file name here is the *untranslated* name
1271 * ie. it is still in the DOS codepage sent from the client.
1272 * All use of this filename will pass though the sys_xxxx
1273 * functions which will do the dos_to_unix translation before
1274 * mapping into a UNIX filename. JRA.
1276 string_set(&fsp
->fsp_name
,fname
);
1277 fsp
->wbmpx_ptr
= NULL
;
1282 /*******************************************************************
1283 Check if the share mode on a file allows it to be deleted or unlinked.
1284 Return True if sharing doesn't prevent the operation.
1285 ********************************************************************/
1287 BOOL
check_file_sharing(connection_struct
*conn
,char *fname
, BOOL rename_op
)
1291 share_mode_entry
*old_shares
= 0;
1292 int num_share_modes
;
1293 SMB_STRUCT_STAT sbuf
;
1295 pid_t pid
= getpid();
1299 if(!lp_share_modes(SNUM(conn
)))
1302 if (dos_stat(fname
,&sbuf
) == -1) return(True
);
1305 inode
= sbuf
.st_ino
;
1307 lock_share_entry(conn
, dev
, inode
, &token
);
1308 num_share_modes
= get_share_modes(conn
, token
, dev
, inode
, &old_shares
);
1311 * Check if the share modes will give us access.
1314 if(num_share_modes
!= 0)
1321 broke_oplock
= False
;
1322 for(i
= 0; i
< num_share_modes
; i
++)
1324 share_mode_entry
*share_entry
= &old_shares
[i
];
1327 * Break oplocks before checking share modes. See comment in
1328 * open_file_shared for details.
1329 * Check if someone has an oplock on this file. If so we must
1330 * break it before continuing.
1332 if(BATCH_OPLOCK_TYPE(share_entry
->op_type
))
1337 /* JRA. Try removing this code to see if the new oplock changes
1338 fix the problem. I'm dubious, but Andrew is recommending we
1343 * It appears that the NT redirector may have a bug, in that
1344 * it tries to do an SMBmv on a file that it has open with a
1345 * batch oplock, and then fails to respond to the oplock break
1346 * request. This only seems to occur when the client is doing an
1347 * SMBmv to the smbd it is using - thus we try and detect this
1348 * condition by checking if the file being moved is open and oplocked by
1349 * this smbd process, and then not sending the oplock break in this
1350 * special case. If the file was open with a deny mode that
1351 * prevents the move the SMBmv will fail anyway with a share
1352 * violation error. JRA.
1354 if(rename_op
&& (share_entry
->pid
== pid
))
1357 DEBUG(0,("check_file_sharing: NT redirector workaround - rename attempted on \
1358 batch oplocked file %s, dev = %x, inode = %.0f\n", fname
, (unsigned int)dev
, (double)inode
));
1361 * This next line is a test that allows the deny-mode
1362 * processing to be skipped. This seems to be needed as
1363 * NT insists on the rename succeeding (in Office 9x no less !).
1364 * This should be removed as soon as (a) MS fix the redirector
1365 * bug or (b) NT SMB support in Samba makes NT not issue the
1366 * call (as is my fervent hope). JRA.
1374 DEBUG(5,("check_file_sharing: breaking oplock (%x) on file %s, \
1375 dev = %x, inode = %.0f\n", share_entry
->op_type
, fname
, (unsigned int)dev
, (double)inode
));
1377 /* Oplock break.... */
1378 unlock_share_entry(conn
, dev
, inode
, token
);
1379 if(request_oplock_break(share_entry
, dev
, inode
) == False
)
1381 free((char *)old_shares
);
1383 DEBUG(0,("check_file_sharing: FAILED when breaking oplock (%x) on file %s, \
1384 dev = %x, inode = %.0f\n", old_shares
[i
].op_type
, fname
, (unsigned int)dev
, (double)inode
));
1388 lock_share_entry(conn
, dev
, inode
, &token
);
1389 broke_oplock
= True
;
1395 * If this is a delete request and ALLOW_SHARE_DELETE is set then allow
1396 * this to proceed. This takes precedence over share modes.
1399 if(!rename_op
&& GET_ALLOW_SHARE_DELETE(share_entry
->share_mode
))
1403 * Someone else has a share lock on it, check to see
1407 if ((GET_DENY_MODE(share_entry
->share_mode
) != DENY_DOS
) || (share_entry
->pid
!= pid
))
1414 free((char *)old_shares
);
1415 num_share_modes
= get_share_modes(conn
, token
, dev
, inode
, &old_shares
);
1417 } while(broke_oplock
);
1420 /* XXXX exactly what share mode combinations should be allowed for
1421 deleting/renaming? */
1423 * If we got here then either there were no share modes or
1424 * all share modes were DENY_DOS and the pid == getpid() or
1425 * delete access was requested and all share modes had the
1426 * ALLOW_SHARE_DELETE bit set (takes precedence over other
1434 unlock_share_entry(conn
, dev
, inode
, token
);
1435 if(old_shares
!= NULL
)
1436 free((char *)old_shares
);