Correct PPTP server firewall rules chain.
[tomato/davidwu.git] / release / src / router / samba / source / smbd / open.c
blob9b9e36650fac2ac63884788f7dc5fc75eae53811
1 /*
2 Unix SMB/Netbios implementation.
3 Version 1.9.
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.
22 #include "includes.h"
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))
42 pstrcat(fname,".");
43 fd = dos_open(fname,flags,mode);
46 #if (defined(ENAMETOOLONG) && defined(HAVE_PATHCONF))
47 if ((fd == -1) && (errno == ENAMETOOLONG))
49 int max_len;
50 char *p = strrchr(fname, '/');
52 if (p == fname) /* name is "/xxx" */
54 max_len = pathconf("/", _PC_NAME_MAX);
55 p++;
57 else if ((p == NULL) || (p == fname))
59 p = fname;
60 max_len = pathconf(".", _PC_NAME_MAX);
62 else
64 *p = '\0';
65 max_len = pathconf(fname, _PC_NAME_MAX);
66 *p = '/';
67 p++;
69 if (strlen(p) > max_len)
71 char tmp = p[max_len];
73 p[max_len] = '\0';
74 if ((fd = dos_open(fname,flags,mode)) == -1)
75 p[max_len] = tmp;
78 #endif
79 return fd;
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))
90 return;
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)
101 int i;
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--;
109 return;
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)
119 int i;
120 for(i = 0; i < fd_ptr->uid_cache_count; i++)
121 if(fd_ptr->uid_users_cache[i] == u)
122 return True;
123 return False;
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);
135 if(fd == -1)
136 return;
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;
143 fd_ptr->fd = 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;
157 *err_ret = 0;
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,
162 fd_ptr->ref_count));
164 SMB_ASSERT(fd_ptr->ref_count != 0);
166 fd_ptr->ref_count--;
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)
173 *err_ret = errno;
176 if(fd_ptr->fd_readonly != -1) {
177 if(close(fd_ptr->fd_readonly) < 0) {
178 if(*err_ret == 0)
179 *err_ret = errno;
183 if(fd_ptr->fd_writeonly != -1) {
184 if( close(fd_ptr->fd_writeonly) < 0) {
185 if(*err_ret == 0)
186 *err_ret = errno;
191 * Delete this fd_ptr.
193 fd_ptr_free(fd_ptr);
194 } else {
195 fd_remove_from_uid_cache(fd_ptr, (uid_t)current_user.uid);
198 return ret_ref;
201 /****************************************************************************
202 Shutdown a half-open filestruct. This allows open_file_shared to back out
203 on error.
204 ****************************************************************************/
206 static void close_on_error(files_struct *fsp, connection_struct *conn)
208 int err;
210 close_filestruct(fsp);
212 fd_attempt_close(fsp->fd_ptr,&err);
214 fsp->fd_ptr = NULL;
216 if (fsp->fsp_name) {
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
226 via an exit code.
227 ****************************************************************************/
229 static BOOL check_access_allowed_for_current_user( char *fname, int accmode )
231 pid_t child_pid;
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"));
242 CatchChild();
243 return False;
246 if(child_pid) {
248 * Parent.
250 pid_t wpid;
251 int status_code;
253 while ((wpid = sys_waitpid(child_pid, &status_code, 0)) < 0) {
254 if(errno == EINTR) {
255 errno = 0;
256 continue;
258 DEBUG(0,("check_access_allowed_for_current_user: The process \
259 is no longer waiting ! Error = %s\n", strerror(errno) ));
260 CatchChild();
261 return(False);
265 * Go back to ignoring children.
267 CatchChild();
269 if (child_pid != wpid) {
270 DEBUG(0,("check_access_allowed_for_current_user: We were waiting for the wrong process ID\n"));
271 return(False);
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"));
276 return(False);
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));
280 return(False);
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));
285 return(False);
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));
293 return True;
294 } else {
296 * Child.
298 int fd;
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) {
301 /* Access denied. */
302 _exit(EACCES);
304 close(fd);
305 DEBUG(9,("check_access_allowed_for_current_user: Child - returning ok.\n"));
306 _exit(0);
309 return False;
312 /****************************************************************************
313 check a filename for the pipe string
314 ****************************************************************************/
316 static void check_for_pipe(char *fname)
318 /* special case of pipe opens */
319 char s[10];
320 StrnCpy(s,fname,sizeof(s)-1);
321 strlower(s);
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 /****************************************************************************
330 open a file
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;
337 pstring fname;
338 SMB_STRUCT_STAT statbuf;
339 file_fd_struct *fd_ptr;
340 int accmode = (flags & O_ACCMODE);
342 fsp->open = False;
343 fsp->fd_ptr = 0;
344 fsp->oplock_type = NO_OPLOCK;
345 errno = EPERM;
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.
358 * JRA.
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);
366 return;
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
370 directory.
372 flags &= ~O_CREAT;
376 /* this handles a bug in Win95 - it doesn't say to create the file when it
377 should */
378 if (conn->printer) {
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
389 * open fd table.
391 if(sbuf == 0) {
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);
398 return;
400 sbuf = 0;
401 } else {
402 sbuf = &statbuf;
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)) {
420 fd_ptr->ref_count--;
421 errno = EEXIST;
422 return;
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. */
438 fd_ptr->ref_count--;
439 fd_remove_from_uid_cache(fd_ptr, (uid_t)current_user.uid);
440 errno = EACCES;
441 return;
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
458 * was open for read.
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);
467 fd_ptr->ref_count--;
468 return;
471 } else {
472 int open_flags;
473 /* We need to allocate a new file_fd_struct (this increments the
474 ref_count). */
475 if((fd_ptr = fd_get_new()) == 0)
476 return;
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.
495 #ifdef EROFS
496 if((fd_ptr->fd == -1) && ((errno == EACCES) || (errno == EROFS))) {
497 #else /* No EROFS */
498 if((fd_ptr->fd == -1) && (errno == EACCES)) {
499 #endif /* EROFS */
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))) {
509 pstring dname;
510 SMB_BIG_UINT dum1,dum2,dum3;
511 char *p;
512 pstrcpy(dname,fname);
513 p = strrchr(dname,'/');
514 if (p) *p = 0;
515 if (sys_disk_free(dname,False,&dum1,&dum2,&dum3) < (SMB_BIG_UINT)lp_minprintspace(SNUM(conn))) {
516 int err;
517 if(fd_attempt_close(fd_ptr, &err) == 0)
518 dos_unlink(fname);
519 fsp->fd_ptr = 0;
520 errno = ENOSPC;
521 return;
525 if (fd_ptr->fd < 0)
527 int err;
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);
533 return;
536 if (fd_ptr->fd >= 0)
538 if(sbuf == 0) {
539 /* Do the fstat */
540 if(sys_fstat(fd_ptr->fd, &statbuf) == -1) {
541 int err;
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);
547 return;
549 sbuf = &statbuf;
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;
561 fsp->size = 0;
562 fsp->pos = -1;
563 fsp->open = True;
564 fsp->can_lock = True;
565 fsp->can_read = ((flags & O_WRONLY)==0);
566 fsp->can_write = ((flags & (O_WRONLY|O_RDWR))!=0);
567 fsp->share_mode = 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;
575 fsp->conn = conn;
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
590 * postscript file.
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 /****************************************************************************
608 C. Hoch 11/22/95
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,
614 BOOL *share_locked)
616 if (fsp->can_write){
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;
629 errno = EACCES;
630 unix_ERR_class = ERRDOS;
631 unix_ERR_code = ERRlock;
632 } else {
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")) {
649 return True;
652 return False;
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
662 test routines.
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);
669 if (same_pid) {
670 if (isexe && old_mode == DOS_OPEN_RDONLY &&
671 old_deny == DENY_DOS && new_deny == DENY_READ) {
672 return AFAIL;
674 if (!isexe && old_mode == DOS_OPEN_RDONLY &&
675 old_deny == DENY_DOS && new_deny == DENY_DOS) {
676 return AREAD;
678 if (new_deny == DENY_FCB && old_deny == DENY_DOS) {
679 if (isexe) return AFAIL;
680 if (old_mode == DOS_OPEN_RDONLY) return AFAIL;
681 return AALL;
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;
686 return AFAIL;
689 if (old_deny == DENY_FCB) {
690 if (new_deny == DENY_DOS || new_deny == DENY_FCB) return AALL;
691 return AFAIL;
695 if (old_deny == DENY_DOS || new_deny == DENY_DOS ||
696 old_deny == DENY_FCB || new_deny == DENY_FCB) {
697 if (isexe) {
698 if (old_deny == DENY_FCB || new_deny == DENY_FCB) {
699 return AFAIL;
701 if (old_deny == DENY_DOS) {
702 if (new_deny == DENY_READ &&
703 (old_mode == DOS_OPEN_RDONLY ||
704 old_mode == DOS_OPEN_RDWR)) {
705 return AFAIL;
707 if (new_deny == DENY_WRITE &&
708 (old_mode == DOS_OPEN_WRONLY ||
709 old_mode == DOS_OPEN_RDWR)) {
710 return AFAIL;
712 return AALL;
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)
720 return(AALL);
722 if (old_deny == DENY_READ || new_deny == DENY_READ) return AFAIL;
723 if (old_mode == DOS_OPEN_RDONLY) return(AREAD);
725 return(AFAIL);
728 switch (new_deny)
730 case DENY_WRITE:
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);
734 return(AFAIL);
735 case DENY_READ:
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);
739 return(AFAIL);
740 case DENY_NONE:
741 if (old_deny==DENY_WRITE) return(AREAD);
742 if (old_deny==DENY_READ) return(AWRITE);
743 if (old_deny==DENY_NONE) return(AALL);
744 return(AFAIL);
746 return(AFAIL);
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,
755 char *fname,
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
763 * set.
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",
769 fname ));
770 unix_ERR_class = ERRDOS;
771 unix_ERR_code = ERRnoaccess;
772 return False;
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;
791 return False;
794 if (access_allowed == AREAD)
795 *flags = O_RDONLY;
797 if (access_allowed == AWRITE)
798 *flags = O_WRONLY;
802 return True;
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)
812 int flags=0;
813 int flags2=0;
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;
820 int token = 0;
821 SMB_DEV_T dev = 0;
822 SMB_INO_T inode = 0;
823 int num_share_modes = 0;
824 int oplock_contention_count = 0;
825 BOOL all_current_opens_are_level_II = False;
826 fsp->open = False;
827 fsp->fd_ptr = 0;
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)) {
833 return;
836 /* ignore any oplock requests if oplocks are disabled */
837 if (!lp_oplocks(SNUM(conn)) || global_client_failed_oplock_break) {
838 oplock_request = 0;
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"));
853 return;
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",
859 fname ));
860 errno = EEXIST;
861 return;
864 if (GET_FILE_CREATE_DISPOSITION(ofun) == FILE_CREATE_IF_NOT_EXIST)
865 flags2 |= O_CREAT;
867 if (GET_FILE_OPEN_DISPOSITION(ofun) == FILE_EXISTS_TRUNCATE)
868 flags2 |= O_TRUNC;
870 if (GET_FILE_OPEN_DISPOSITION(ofun) == FILE_EXISTS_FAIL)
871 flags2 |= O_EXCL;
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:
879 flags = O_WRONLY;
880 break;
881 case DOS_OPEN_FCB:
882 fcbopen = True;
883 flags = O_RDWR;
884 break;
885 case DOS_OPEN_RDWR:
886 flags = O_RDWR;
887 break;
888 default:
889 flags = O_RDONLY;
890 break;
893 #if defined(O_SYNC)
894 if (GET_FILE_SYNC_OPENMODE(share_mode)) {
895 flags2 |= O_SYNC;
897 #endif /* O_SYNC */
899 if (flags != O_RDONLY && file_existed &&
900 (!CAN_WRITE(conn) || IS_DOS_READONLY(dos_mode(conn,fname,&sbuf))))
902 if (!fcbopen)
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" ));
906 errno = EACCES;
907 return;
909 flags = O_RDONLY;
912 if (deny_mode > DENY_NONE && deny_mode!=DENY_FCB)
914 DEBUG(2,("Invalid deny mode %d on file %s\n",deny_mode,fname));
915 errno = EINVAL;
916 return;
919 if (lp_share_modes(SNUM(conn)))
921 int i;
922 share_mode_entry *old_shares = 0;
924 if (file_existed)
926 dev = sbuf.st_dev;
927 inode = sbuf.st_ino;
928 lock_share_entry(conn, dev, inode, &token);
929 share_locked = True;
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))
939 BOOL broke_oplock;
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));
974 errno = EACCES;
975 unix_ERR_class = ERRDOS;
976 unix_ERR_code = ERRbadshare;
977 return;
979 lock_share_entry(conn, dev, inode, &token);
980 broke_oplock = True;
981 all_current_opens_are_level_II = False;
982 break;
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
988 if we can too */
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);
993 errno = EACCES;
994 return;
997 } /* end for */
999 if(broke_oplock)
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);
1008 if(old_shares != 0)
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)))
1019 oplock_request = 0;
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)
1030 flags = O_RDONLY;
1031 open_file(fsp,conn,fname,flags,mode,file_existed ? &sbuf : 0 );
1034 if (fsp->open)
1036 int open_mode=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;
1047 switch (flags)
1049 case O_RDONLY:
1050 open_mode = DOS_OPEN_RDONLY;
1051 break;
1052 case O_RDWR:
1053 open_mode = DOS_OPEN_RDWR;
1054 break;
1055 case O_WRONLY:
1056 open_mode = DOS_OPEN_WRONLY;
1057 break;
1060 fsp->share_mode = SET_DENY_MODE(deny_mode) |
1061 SET_OPEN_MODE(open_mode) |
1062 SET_ALLOW_SHARE_DELETE(allow_share_delete);
1064 if (Access)
1065 (*Access) = open_mode;
1067 if (action)
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)))
1079 uint16 port = 0;
1082 * Setup the oplock info in both the shared memory and
1083 * file structs.
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);
1093 } else {
1094 port = 0;
1095 oplock_request = 0;
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) ));
1122 return -1;
1125 if(S_ISDIR(pst->st_mode)) {
1126 DEBUG(0,("open_file_stat: %s is a directory !\n", fname ));
1127 return -1;
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.
1138 fsp->fd_ptr = NULL;
1139 conn->num_files_open++;
1140 fsp->mode = 0;
1141 GetTimeOfDay(&fsp->open_time);
1142 fsp->vuid = current_user.vuid;
1143 fsp->size = 0;
1144 fsp->pos = -1;
1145 fsp->open = True;
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;
1157 fsp->conn = conn;
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. */
1169 return 0;
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;
1180 SMB_STRUCT_STAT st;
1181 BOOL got_stat = False;
1183 if(dos_stat(fname, &st) == 0) {
1184 got_stat = True;
1187 if (got_stat && (GET_FILE_OPEN_DISPOSITION(smb_ofun) == FILE_EXISTS_FAIL)) {
1188 errno = EEXIST; /* Setup so correct error is returned to client. */
1189 return -1;
1192 if (GET_FILE_CREATE_DISPOSITION(smb_ofun) == FILE_CREATE_IF_NOT_EXIST) {
1194 if (got_stat) {
1196 if(!S_ISDIR(st.st_mode)) {
1197 DEBUG(0,("open_directory: %s is not a directory !\n", fname ));
1198 errno = EACCES;
1199 return -1;
1201 *action = FILE_WAS_OPENED;
1203 } else {
1206 * Try and create the directory.
1209 if(!CAN_WRITE(conn)) {
1210 DEBUG(2,("open_directory: failing create on read-only share\n"));
1211 errno = EACCES;
1212 return -1;
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) ));
1218 return -1;
1220 *action = FILE_WAS_CREATED;
1223 } else {
1226 * Don't create - just check that it *was* a directory.
1229 if(!got_stat) {
1230 DEBUG(0,("open_directory: unable to stat name = %s. Error was %s\n",
1231 fname, strerror(errno) ));
1232 return -1;
1235 if(!S_ISDIR(st.st_mode)) {
1236 DEBUG(0,("open_directory: %s is not a directory !\n", fname ));
1237 return -1;
1240 *action = FILE_WAS_OPENED;
1243 DEBUG(5,("open_directory: opening directory %s\n",
1244 fname));
1247 * Setup the files_struct for it.
1250 fsp->fd_ptr = NULL;
1251 conn->num_files_open++;
1252 fsp->mode = 0;
1253 GetTimeOfDay(&fsp->open_time);
1254 fsp->vuid = current_user.vuid;
1255 fsp->size = 0;
1256 fsp->pos = -1;
1257 fsp->open = True;
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;
1268 fsp->conn = conn;
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;
1279 return 0;
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)
1289 int i;
1290 int ret = False;
1291 share_mode_entry *old_shares = 0;
1292 int num_share_modes;
1293 SMB_STRUCT_STAT sbuf;
1294 int token;
1295 pid_t pid = getpid();
1296 SMB_DEV_T dev;
1297 SMB_INO_T inode;
1299 if(!lp_share_modes(SNUM(conn)))
1300 return True;
1302 if (dos_stat(fname,&sbuf) == -1) return(True);
1304 dev = sbuf.st_dev;
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)
1316 BOOL broke_oplock;
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))
1335 #if 0
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
1339 try this....
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.
1368 continue;
1370 else
1371 #endif /* 0 */
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));
1386 return False;
1388 lock_share_entry(conn, dev, inode, &token);
1389 broke_oplock = True;
1390 break;
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))
1400 continue;
1403 * Someone else has a share lock on it, check to see
1404 * if we can too.
1407 if ((GET_DENY_MODE(share_entry->share_mode) != DENY_DOS) || (share_entry->pid != pid))
1408 goto free_and_exit;
1410 } /* end for */
1412 if(broke_oplock)
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
1427 * share modes).
1430 ret = True;
1432 free_and_exit:
1434 unlock_share_entry(conn, dev, inode, token);
1435 if(old_shares != NULL)
1436 free((char *)old_shares);
1437 return(ret);