More 64 bit stuff - now the fcntl locks are 64 bit clean.
[samba.git] / source3 / smbd / open.c
1 /* 
2    Unix SMB/Netbios implementation.
3    Version 1.9.
4    file opening and share modes
5    Copyright (C) Andrew Tridgell 1992-1998
6    
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.
11    
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.
16    
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.
20 */
21
22 #include "includes.h"
23
24 extern int DEBUGLEVEL;
25
26 extern pstring sesssetup_user;
27 extern int global_oplocks_open;
28 extern uint16 oplock_port;
29
30
31 /****************************************************************************
32 fd support routines - attempt to do a dos_open
33 ****************************************************************************/
34 static int fd_attempt_open(char *fname, int flags, int mode)
35 {
36   int fd = dos_open(fname,flags,mode);
37
38   /* Fix for files ending in '.' */
39   if((fd == -1) && (errno == ENOENT) &&
40      (strchr(fname,'.')==NULL))
41     {
42       pstrcat(fname,".");
43       fd = dos_open(fname,flags,mode);
44     }
45
46 #if (defined(ENAMETOOLONG) && defined(HAVE_PATHCONF))
47   if ((fd == -1) && (errno == ENAMETOOLONG))
48     {
49       int max_len;
50       char *p = strrchr(fname, '/');
51
52       if (p == fname)   /* name is "/xxx" */
53         {
54           max_len = pathconf("/", _PC_NAME_MAX);
55           p++;
56         }
57       else if ((p == NULL) || (p == fname))
58         {
59           p = fname;
60           max_len = pathconf(".", _PC_NAME_MAX);
61         }
62       else
63         {
64           *p = '\0';
65           max_len = pathconf(fname, _PC_NAME_MAX);
66           *p = '/';
67           p++;
68         }
69       if (strlen(p) > max_len)
70         {
71           char tmp = p[max_len];
72
73           p[max_len] = '\0';
74           if ((fd = dos_open(fname,flags,mode)) == -1)
75             p[max_len] = tmp;
76         }
77     }
78 #endif
79   return fd;
80 }
81
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)
87 {
88   if(fd_ptr->uid_cache_count >= sizeof(fd_ptr->uid_users_cache)/sizeof(uid_t))
89     return;
90   fd_ptr->uid_users_cache[fd_ptr->uid_cache_count++] = u;
91 }
92
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)
98 {
99   int i;
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--;
106     }
107   return;
108 }
109
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)
115 {
116   int i;
117   for(i = 0; i < fd_ptr->uid_cache_count; i++)
118     if(fd_ptr->uid_users_cache[i] == u)
119       return True;
120   return False;
121 }
122
123
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)
129 {
130   int fd = dos_open( fname, O_RDWR, mode);
131
132   if(fd == -1)
133     return;
134
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;
139
140   fd_ptr->fd = fd;
141   fd_ptr->real_open_flags = O_RDWR;
142 }
143
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)
149 {
150   extern struct current_user current_user;
151
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,
155           fd_ptr->ref_count));
156   if(fd_ptr->ref_count > 0) {
157     fd_ptr->ref_count--;
158     if(fd_ptr->ref_count == 0) {
159       if(fd_ptr->fd != -1)
160         close(fd_ptr->fd);
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);
165       fd_ptr->fd = -1;
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;
172     } else {
173       fd_remove_from_uid_cache(fd_ptr, (uid_t)current_user.uid);
174     }
175   } 
176  return fd_ptr->ref_count;
177 }
178
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
184 via an exit code.
185 ****************************************************************************/
186 static BOOL check_access_allowed_for_current_user( char *fname, int accmode )
187 {
188   pid_t child_pid;
189
190   if((child_pid = fork()) < 0) {
191     DEBUG(0,("check_access_allowed_for_current_user: fork failed.\n"));
192     return False;
193   }
194
195   if(child_pid) {
196     /*
197      * Parent.
198      */
199     pid_t wpid;
200     int status_code;
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"));
203       return(False);
204     }
205
206     if (child_pid != wpid) {
207       DEBUG(0,("check_access_allowed_for_current_user: We were waiting for the wrong process ID\n"));
208       return(False);
209     }
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"));
213       return(False);
214     }
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));
217       return(False);
218     }
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));
222       return(False);
223     }
224 #endif /* defined(WIFEXITED) && defined(WEXITSTATUS) */
225
226     /*
227      * Success - the child could open the file.
228      */
229     DEBUG(9,("check_access_allowed_for_current_user: The status of the process exiting was %d. Returning access allowed.\n", status_code));
230     return True;
231   } else {
232     /*
233      * Child.
234      */
235     int fd;
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) {
238       /* Access denied. */
239       _exit(EACCES);
240     }
241     close(fd);
242     DEBUG(9,("check_access_allowed_for_current_user: Child - returning ok.\n"));
243     _exit(0);
244   }
245
246   return False;
247 }
248
249 /****************************************************************************
250 check a filename for the pipe string
251 ****************************************************************************/
252 static void check_for_pipe(char *fname)
253 {
254         /* special case of pipe opens */
255         char s[10];
256         StrnCpy(s,fname,9);
257         strlower(s);
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;
262         }
263 }
264
265 /****************************************************************************
266 open a file
267 ****************************************************************************/
268 static void open_file(files_struct *fsp,connection_struct *conn,
269                       char *fname1,int flags,int mode, SMB_STRUCT_STAT *sbuf)
270 {
271   extern struct current_user current_user;
272   pstring fname;
273   SMB_STRUCT_STAT statbuf;
274   file_fd_struct *fd_ptr;
275   int accmode = (flags & (O_RDONLY | O_WRONLY | O_RDWR));
276
277   fsp->open = False;
278   fsp->fd_ptr = 0;
279   fsp->granted_oplock = False;
280   errno = EPERM;
281
282   pstrcpy(fname,fname1);
283
284   /* check permissions */
285
286   /*
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.
293    * JRA.
294    */
295
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);
301       return;
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
305          directory.
306        */
307       flags &= ~O_CREAT;
308     }
309   }
310
311   /* this handles a bug in Win95 - it doesn't say to create the file when it 
312      should */
313   if (conn->printer) {
314           flags |= O_CREAT;
315   }
316
317 /*
318   if (flags == O_WRONLY)
319     DEBUG(3,("Bug in client? Set O_WRONLY without O_CREAT\n"));
320 */
321
322   /*
323    * Ensure we have a valid struct stat so we can search the
324    * open fd table.
325    */
326   if(sbuf == 0) {
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)));
331
332         check_for_pipe(fname);
333         return;
334       }
335       sbuf = 0;
336     } else {
337       sbuf = &statbuf;
338     }
339   }
340
341   /*
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).
345    */
346   if((fd_ptr = fd_get_already_open(sbuf))!= 0) {
347     /*
348      * File was already open.
349      */
350
351     /* 
352      * Check it wasn't open for exclusive use.
353      */
354     if((flags & O_CREAT) && (flags & O_EXCL)) {
355       fd_ptr->ref_count--;
356       errno = EEXIST;
357       return;
358     }
359
360     /*
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.
365      */
366
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. */
373         fd_ptr->ref_count--;
374         fd_remove_from_uid_cache(fd_ptr, (uid_t)current_user.uid);
375         errno = EACCES;
376         return;
377       }
378     }
379
380     fd_add_to_uid_cache(fd_ptr, (uid_t)current_user.uid);
381
382     /* 
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. 
386      */
387     if(fd_ptr->real_open_flags != O_RDWR)
388       fd_attempt_reopen(fname, mode, fd_ptr);
389
390     /*
391      * Ensure that if we wanted write access
392      * it has been opened for write, and if we wanted read it
393      * was open for read. 
394      */
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);
402       fd_ptr->ref_count--;
403       return;
404     }
405
406   } else {
407     int open_flags;
408     /* We need to allocate a new file_fd_struct (this increments the
409        ref_count). */
410     if((fd_ptr = fd_get_new()) == 0)
411       return;
412     /*
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.
421      */
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);
426     /*
427      * On some systems opening a file for R/W access on a read only
428      * filesystems sets errno to EROFS.
429      */
430 #ifdef EROFS
431     if((fd_ptr->fd == -1) && ((errno == EACCES) || (errno == EROFS))) {
432 #else /* No EROFS */
433     if((fd_ptr->fd == -1) && (errno == EACCES)) {
434 #endif /* EROFS */
435       if(accmode != O_RDWR) {
436         fd_ptr->fd = fd_attempt_open(fname, open_flags|accmode, mode);
437         fd_ptr->real_open_flags = accmode;
438       }
439     }
440   }
441
442   if ((fd_ptr->fd >=0) && 
443       conn->printer && lp_minprintspace(SNUM(conn))) {
444     pstring dname;
445     int dum1,dum2,dum3;
446     char *p;
447     pstrcpy(dname,fname);
448     p = strrchr(dname,'/');
449     if (p) *p = 0;
450     if (sys_disk_free(dname,&dum1,&dum2,&dum3) < 
451         lp_minprintspace(SNUM(conn))) {
452       fd_attempt_close(fd_ptr);
453       fsp->fd_ptr = 0;
454       if(fd_ptr->ref_count == 0)
455         dos_unlink(fname);
456       errno = ENOSPC;
457       return;
458     }
459   }
460     
461   if (fd_ptr->fd < 0)
462   {
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);
468     return;
469   }
470
471   if (fd_ptr->fd >= 0)
472   {
473     if(sbuf == 0) {
474       /* Do the fstat */
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);
481         return;
482       }
483       sbuf = &statbuf;
484     }
485
486     /* Set the correct entries in fd_ptr. */
487     fd_ptr->dev = sbuf->st_dev;
488     fd_ptr->inode = sbuf->st_ino;
489
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;
495     fsp->size = 0;
496     fsp->pos = -1;
497     fsp->open = True;
498     fsp->mmap_ptr = NULL;
499     fsp->mmap_size = 0;
500     fsp->can_lock = True;
501     fsp->can_read = ((flags & O_WRONLY)==0);
502     fsp->can_write = ((flags & (O_WRONLY|O_RDWR))!=0);
503     fsp->share_mode = 0;
504     fsp->print_file = conn->printer;
505     fsp->modified = False;
506     fsp->granted_oplock = False;
507     fsp->sent_oplock_break = False;
508     fsp->is_directory = False;
509     fsp->conn = conn;
510     /*
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.
516      */
517     string_set(&fsp->fsp_name,fname);
518     fsp->wbmpx_ptr = NULL;      
519
520     /*
521      * If the printer is marked as postscript output a leading
522      * file identifier to ensure the file is treated as a raw
523      * postscript file.
524      * This has a similar effect as CtrlD=0 in WIN.INI file.
525      * tim@fsg.com 09/06/94
526      */
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);
530     }
531       
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));
536
537   }
538
539 #if WITH_MMAP
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);
545
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;
550           }
551   }
552 #endif
553 }
554
555
556 /****************************************************************************
557   C. Hoch 11/22/95
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, 
562                                    BOOL *share_locked)
563 {
564   if (fsp->can_write){
565 #ifdef LARGE_SMB_OFF_T
566     if (is_locked(fsp,conn,0x3FFFFFFFFFFFFFFFLL,0,F_WRLCK)){
567 #else
568     if (is_locked(fsp,conn,0x3FFFFFFF,0,F_WRLCK)){
569 #endif
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;
578       errno = EACCES;
579       unix_ERR_class = ERRDOS;
580       unix_ERR_code = ERRlock;
581     }
582     else
583       sys_ftruncate(fsp->fd_ptr->fd,0); 
584   }
585 }
586
587
588
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)
594 {
595   int flags=0;
596   int flags2=0;
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;
602   int token;
603   SMB_DEV_T dev = 0;
604   SMB_INO_T inode = 0;
605   int num_share_modes = 0;
606
607   fsp->open = False;
608   fsp->fd_ptr = 0;
609
610   /* this is for OS/2 EAs - try and say we don't support them */
611   if (strstr(fname,".+,;=[].")) 
612   {
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 */
620
621     return;
622   }
623
624   if ((ofun & 0x3) == 0 && file_existed)  
625   {
626     errno = EEXIST;
627     return;
628   }
629       
630   if (ofun & 0x10)
631     flags2 |= O_CREAT;
632   if ((ofun & 0x3) == 2)
633     flags2 |= O_TRUNC;
634
635   /* note that we ignore the append flag as 
636      append does not mean the same thing under dos and unix */
637
638   switch (share_mode&0xF)
639   {
640     case 1: 
641       flags = O_WRONLY; 
642       break;
643     case 0xF: 
644       fcbopen = True;
645       flags = O_RDWR; 
646       break;
647     case 2: 
648       flags = O_RDWR; 
649       break;
650     default:
651       flags = O_RDONLY;
652       break;
653   }
654
655 #if defined(O_SYNC)
656   if (share_mode&(1<<14)) {
657           flags2 |= O_SYNC;
658   }
659 #endif /* O_SYNC */
660   
661   if (flags != O_RDONLY && file_existed && 
662       (!CAN_WRITE(conn) || IS_DOS_READONLY(dos_mode(conn,fname,&sbuf)))) 
663   {
664     if (!fcbopen) 
665     {
666       errno = EACCES;
667       return;
668     }
669     flags = O_RDONLY;
670   }
671
672   if (deny_mode > DENY_NONE && deny_mode!=DENY_FCB) 
673   {
674     DEBUG(2,("Invalid deny mode %d on file %s\n",deny_mode,fname));
675     errno = EINVAL;
676     return;
677   }
678
679   if (deny_mode == DENY_FCB) deny_mode = DENY_DOS;
680
681   if (lp_share_modes(SNUM(conn))) 
682   {
683     int i;
684     share_mode_entry *old_shares = 0;
685
686     if (file_existed)
687     {
688       dev = sbuf.st_dev;
689       inode = sbuf.st_ino;
690       lock_share_entry(conn, dev, inode, &token);
691       share_locked = True;
692       num_share_modes = get_share_modes(conn, token, dev, inode, &old_shares);
693     }
694
695     /*
696      * Check if the share modes will give us access.
697      */
698
699     if(share_locked && (num_share_modes != 0))
700     {
701       BOOL broke_oplock;
702
703       do
704       {
705
706         broke_oplock = False;
707         for(i = 0; i < num_share_modes; i++)
708         {
709           share_mode_entry *share_entry = &old_shares[i];
710
711           /* 
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. 
717            */
718           if(share_entry->op_type & (EXCLUSIVE_OPLOCK|BATCH_OPLOCK))
719           {
720
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));
723
724             /* Oplock break.... */
725             unlock_share_entry(conn, dev, inode, token);
726             if(request_oplock_break(share_entry, dev, inode) == False)
727             {
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));
731               errno = EACCES;
732               unix_ERR_class = ERRDOS;
733               unix_ERR_code = ERRbadshare;
734               return;
735             }
736             lock_share_entry(conn, dev, inode, &token);
737             broke_oplock = True;
738             break;
739           }
740
741           /* someone else has a share lock on it, check to see 
742              if we can too */
743           if(check_share_mode(share_entry, deny_mode, fname, fcbopen, &flags) == False)
744           {
745             free((char *)old_shares);
746             unlock_share_entry(conn, dev, inode, token);
747             errno = EACCES;
748             unix_ERR_class = ERRDOS;
749             unix_ERR_code = ERRbadshare;
750             return;
751           }
752
753         } /* end for */
754
755         if(broke_oplock)
756         {
757           free((char *)old_shares);
758           num_share_modes = get_share_modes(conn, token, dev, inode, &old_shares);
759         }
760       } while(broke_oplock);
761     }
762
763     if(old_shares != 0)
764       free((char *)old_shares);
765   }
766
767   DEBUG(4,("calling open_file with flags=0x%X flags2=0x%X mode=0%o\n",
768            flags,flags2,mode));
769
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) 
772   {
773     flags = O_RDONLY;
774     open_file(fsp,conn,fname,flags,mode,file_existed ? &sbuf : 0 );
775   }
776
777   if (fsp->open) 
778   {
779     int open_mode=0;
780
781     if((share_locked == False) && lp_share_modes(SNUM(conn)))
782     {
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);
787       share_locked = True;
788     }
789
790     switch (flags) 
791     {
792       case O_RDONLY:
793         open_mode = 0;
794         break;
795       case O_RDWR:
796         open_mode = 2;
797         break;
798       case O_WRONLY:
799         open_mode = 1;
800         break;
801     }
802
803     fsp->share_mode = (deny_mode<<4) | open_mode;
804
805     if (Access)
806       (*Access) = open_mode;
807
808     if (action) 
809     {
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;
813     }
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).
817      */
818     if (lp_share_modes(SNUM(conn)))
819     {
820       uint16 port = 0;
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
824          oplocks). */
825
826       if(oplock_request && (num_share_modes == 0) && lp_oplocks(SNUM(conn)) && 
827               !IS_VETO_OPLOCK_PATH(conn,fname))
828       {
829         fsp->granted_oplock = True;
830         fsp->sent_oplock_break = False;
831         global_oplocks_open++;
832         port = oplock_port;
833
834         DEBUG(5,("open_file_shared: granted oplock (%x) on file %s, \
835 dev = %x, inode = %x\n", oplock_request, fname, dev, inode));
836
837       }
838       else
839       {
840         port = 0;
841         oplock_request = 0;
842       }
843       set_share_mode(token, fsp, port, oplock_request);
844     }
845
846     if ((flags2&O_TRUNC) && file_existed)
847       truncate_unless_locked(fsp,conn,token,&share_locked);
848   }
849
850   if (share_locked && lp_share_modes(SNUM(conn)))
851     unlock_share_entry( conn, dev, inode, token);
852 }
853
854
855
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)
861 {
862         extern struct current_user current_user;
863         SMB_STRUCT_STAT st;
864
865         if (smb_ofun & 0x10) {
866                 /*
867                  * Create the directory.
868                  */
869
870                 if(dos_mkdir(fname, unixmode) < 0) {
871                         DEBUG(0,("open_directory: unable to create %s. Error was %s\n",
872                                  fname, strerror(errno) ));
873                         return -1;
874                 }
875
876                 *action = FILE_WAS_CREATED;
877         } else {
878                 /*
879                  * Check that it *was* a directory.
880                  */
881
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) ));
885                         return -1;
886                 }
887
888                 if(!S_ISDIR(st.st_mode)) {
889                         DEBUG(0,("open_directory: %s is not a directory !\n", fname ));
890                         return -1;
891                 }
892                 *action = FILE_WAS_OPENED;
893         }
894         
895         DEBUG(5,("open_directory: opening directory %s\n",
896                  fname));
897
898         /*
899          * Setup the files_struct for it.
900          */
901         
902         fsp->fd_ptr = NULL;
903         conn->num_files_open++;
904         fsp->mode = 0;
905         GetTimeOfDay(&fsp->open_time);
906         fsp->vuid = current_user.vuid;
907         fsp->size = 0;
908         fsp->pos = -1;
909         fsp->open = True;
910         fsp->mmap_ptr = NULL;
911         fsp->mmap_size = 0;
912         fsp->can_lock = True;
913         fsp->can_read = False;
914         fsp->can_write = False;
915         fsp->share_mode = 0;
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;
921         fsp->conn = conn;
922         /*
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.
928          */
929         string_set(&fsp->fsp_name,fname);
930         fsp->wbmpx_ptr = NULL;
931
932         return 0;
933 }
934
935 enum {AFAIL,AREAD,AWRITE,AALL};
936
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)
942 {
943   if (new_deny == DENY_ALL || old_deny == DENY_ALL) return(AFAIL);
944
945   if (new_deny == DENY_DOS || old_deny == DENY_DOS) {
946     int pid = getpid();
947     if (old_deny == new_deny && share_pid == pid) 
948         return(AALL);    
949
950     if (old_mode == 0) return(AREAD);
951
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"))
961         return(AREAD);
962     }
963
964     return(AFAIL);
965   }
966
967   switch (new_deny) 
968     {
969     case DENY_WRITE:
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);
973       return(AFAIL);
974     case DENY_READ:
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);
978       return(AFAIL);
979     case DENY_NONE:
980       if (old_deny==DENY_WRITE) return(AREAD);
981       if (old_deny==DENY_READ) return(AWRITE);
982       if (old_deny==DENY_NONE) return(AALL);
983       return(AFAIL);      
984     }
985   return(AFAIL);      
986 }
987
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)
993 {
994   int i;
995   int ret = False;
996   share_mode_entry *old_shares = 0;
997   int num_share_modes;
998   SMB_STRUCT_STAT sbuf;
999   int token;
1000   int pid = getpid();
1001   SMB_DEV_T dev;
1002   SMB_INO_T inode;
1003
1004   if(!lp_share_modes(SNUM(conn)))
1005     return True;
1006
1007   if (dos_stat(fname,&sbuf) == -1) return(True);
1008
1009   dev = sbuf.st_dev;
1010   inode = sbuf.st_ino;
1011
1012   lock_share_entry(conn, dev, inode, &token);
1013   num_share_modes = get_share_modes(conn, token, dev, inode, &old_shares);
1014
1015   /*
1016    * Check if the share modes will give us access.
1017    */
1018
1019   if(num_share_modes != 0)
1020   {
1021     BOOL broke_oplock;
1022
1023     do
1024     {
1025
1026       broke_oplock = False;
1027       for(i = 0; i < num_share_modes; i++)
1028       {
1029         share_mode_entry *share_entry = &old_shares[i];
1030
1031         /* 
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. 
1036          */
1037         if(share_entry->op_type & BATCH_OPLOCK)
1038         {
1039
1040           /*
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.
1051            */
1052           if(rename_op && (share_entry->pid == pid))
1053           {
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));
1056             /* 
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.
1063              */ 
1064             continue;
1065           }
1066           else
1067           {
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));
1070
1071             /* Oplock break.... */
1072             unlock_share_entry(conn, dev, inode, token);
1073             if(request_oplock_break(share_entry, dev, inode) == False)
1074             {
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));
1078               return False;
1079             }
1080             lock_share_entry(conn, dev, inode, &token);
1081             broke_oplock = True;
1082             break;
1083           }
1084         }
1085
1086         /* someone else has a share lock on it, check to see 
1087            if we can too */
1088         if ((share_entry->share_mode != DENY_DOS) || (share_entry->pid != pid))
1089           goto free_and_exit;
1090
1091       } /* end for */
1092
1093       if(broke_oplock)
1094       {
1095         free((char *)old_shares);
1096         num_share_modes = get_share_modes(conn, token, dev, inode, &old_shares);
1097       }
1098     } while(broke_oplock);
1099   }
1100
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() */
1105   ret = True;
1106
1107 free_and_exit:
1108
1109   unlock_share_entry(conn, dev, inode, token);
1110   if(old_shares != NULL)
1111     free((char *)old_shares);
1112   return(ret);
1113 }
1114
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)
1120 {
1121   int old_open_mode = share->share_mode &0xF;
1122   int old_deny_mode = (share->share_mode >>4)&7;
1123
1124   if (old_deny_mode > 4 || old_open_mode > 2)
1125   {
1126     DEBUG(0,("Invalid share mode found (%d,%d,%d) on file %s\n",
1127                deny_mode,old_deny_mode,old_open_mode,fname));
1128     return False;
1129   }
1130
1131   {
1132     int access_allowed = access_table(deny_mode,old_deny_mode,old_open_mode,
1133                                 share->pid,fname);
1134
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))
1139     {
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));
1143       return False;
1144     }
1145
1146     if (access_allowed == AREAD)
1147       *flags = O_RDONLY;
1148
1149     if (access_allowed == AWRITE)
1150       *flags = O_WRONLY;
1151
1152   }
1153   return True;
1154 }
1155