a72469f2b249b5a45cce2fa5b28e61084b8ad589
[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 #ifdef LARGE_SMB_INO_T
153   DEBUG(3,("fd_attempt_close fd = %d, dev = %x, inode = %.0f, open_flags = %d, ref_count = %d.\n",
154           fd_ptr->fd, (unsigned int)fd_ptr->dev, (double)fd_ptr->inode,
155           fd_ptr->real_open_flags,
156           fd_ptr->ref_count));
157 #else /* LARGE_SMB_INO_T */
158   DEBUG(3,("fd_attempt_close fd = %d, dev = %x, inode = %lx, open_flags = %d, ref_count = %d.\n",
159           fd_ptr->fd, (unsigned int)fd_ptr->dev, (unsigned long)fd_ptr->inode,
160           fd_ptr->real_open_flags,
161           fd_ptr->ref_count));
162 #endif /* LARGE_SMB_INO_T */
163
164   if(fd_ptr->ref_count > 0) {
165     fd_ptr->ref_count--;
166     if(fd_ptr->ref_count == 0) {
167       if(fd_ptr->fd != -1)
168         close(fd_ptr->fd);
169       if(fd_ptr->fd_readonly != -1)
170         close(fd_ptr->fd_readonly);
171       if(fd_ptr->fd_writeonly != -1)
172         close(fd_ptr->fd_writeonly);
173       /*
174        * Delete this fd_ptr.
175        */
176       fd_ptr_free(fd_ptr);
177     } else {
178       fd_remove_from_uid_cache(fd_ptr, (uid_t)current_user.uid);
179     }
180   } 
181  return fd_ptr->ref_count;
182 }
183
184 /****************************************************************************
185 fd support routines - check that current user has permissions
186 to open this file. Used when uid not found in optimization cache.
187 This is really ugly code, as due to POSIX locking braindamage we must
188 fork and then attempt to open the file, and return success or failure
189 via an exit code.
190 ****************************************************************************/
191 static BOOL check_access_allowed_for_current_user( char *fname, int accmode )
192 {
193   pid_t child_pid;
194
195   if((child_pid = fork()) < 0) {
196     DEBUG(0,("check_access_allowed_for_current_user: fork failed.\n"));
197     return False;
198   }
199
200   if(child_pid) {
201     /*
202      * Parent.
203      */
204     pid_t wpid;
205     int status_code;
206     if ((wpid = sys_waitpid(child_pid, &status_code, 0)) < 0) {
207       DEBUG(0,("check_access_allowed_for_current_user: The process is no longer waiting!\n"));
208       return(False);
209     }
210
211     if (child_pid != wpid) {
212       DEBUG(0,("check_access_allowed_for_current_user: We were waiting for the wrong process ID\n"));
213       return(False);
214     }
215 #if defined(WIFEXITED) && defined(WEXITSTATUS)
216     if (WIFEXITED(status_code) == 0) {
217       DEBUG(0,("check_access_allowed_for_current_user: The process exited while we were waiting\n"));
218       return(False);
219     }
220     if (WEXITSTATUS(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 #else /* defined(WIFEXITED) && defined(WEXITSTATUS) */
225     if(status_code != 0) {
226       DEBUG(9,("check_access_allowed_for_current_user: The status of the process exiting was %d. Returning access denied.\n", status_code));
227       return(False);
228     }
229 #endif /* defined(WIFEXITED) && defined(WEXITSTATUS) */
230
231     /*
232      * Success - the child could open the file.
233      */
234     DEBUG(9,("check_access_allowed_for_current_user: The status of the process exiting was %d. Returning access allowed.\n", status_code));
235     return True;
236   } else {
237     /*
238      * Child.
239      */
240     int fd;
241     DEBUG(9,("check_access_allowed_for_current_user: Child - attempting to open %s with mode %d.\n", fname, accmode ));
242     if((fd = fd_attempt_open( fname, accmode, 0)) < 0) {
243       /* Access denied. */
244       _exit(EACCES);
245     }
246     close(fd);
247     DEBUG(9,("check_access_allowed_for_current_user: Child - returning ok.\n"));
248     _exit(0);
249   }
250
251   return False;
252 }
253
254 /****************************************************************************
255 check a filename for the pipe string
256 ****************************************************************************/
257 static void check_for_pipe(char *fname)
258 {
259         /* special case of pipe opens */
260         char s[10];
261         StrnCpy(s,fname,9);
262         strlower(s);
263         if (strstr(s,"pipe/")) {
264                 DEBUG(3,("Rejecting named pipe open for %s\n",fname));
265                 unix_ERR_class = ERRSRV;
266                 unix_ERR_code = ERRaccess;
267         }
268 }
269
270 /****************************************************************************
271 open a file
272 ****************************************************************************/
273 static void open_file(files_struct *fsp,connection_struct *conn,
274                       char *fname1,int flags,int mode, SMB_STRUCT_STAT *sbuf)
275 {
276   extern struct current_user current_user;
277   pstring fname;
278   SMB_STRUCT_STAT statbuf;
279   file_fd_struct *fd_ptr;
280   int accmode = (flags & (O_RDONLY | O_WRONLY | O_RDWR));
281
282   fsp->open = False;
283   fsp->fd_ptr = 0;
284   fsp->granted_oplock = False;
285   errno = EPERM;
286
287   pstrcpy(fname,fname1);
288
289   /* check permissions */
290
291   /*
292    * This code was changed after seeing a client open request 
293    * containing the open mode of (DENY_WRITE/read-only) with
294    * the 'create if not exist' bit set. The previous code
295    * would fail to open the file read only on a read-only share
296    * as it was checking the flags parameter  directly against O_RDONLY,
297    * this was failing as the flags parameter was set to O_RDONLY|O_CREAT.
298    * JRA.
299    */
300
301   if (conn->read_only && !conn->printer) {
302     /* It's a read-only share - fail if we wanted to write. */
303     if(accmode != O_RDONLY) {
304       DEBUG(3,("Permission denied opening %s\n",fname));
305       check_for_pipe(fname);
306       return;
307     } else if(flags & O_CREAT) {
308       /* We don't want to write - but we must make sure that O_CREAT
309          doesn't create the file if we have write access into the
310          directory.
311        */
312       flags &= ~O_CREAT;
313     }
314   }
315
316   /* this handles a bug in Win95 - it doesn't say to create the file when it 
317      should */
318   if (conn->printer) {
319           flags |= O_CREAT;
320   }
321
322 /*
323   if (flags == O_WRONLY)
324     DEBUG(3,("Bug in client? Set O_WRONLY without O_CREAT\n"));
325 */
326
327   /*
328    * Ensure we have a valid struct stat so we can search the
329    * open fd table.
330    */
331   if(sbuf == 0) {
332     if(dos_stat(fname, &statbuf) < 0) {
333       if(errno != ENOENT) {
334         DEBUG(3,("Error doing stat on file %s (%s)\n",
335                  fname,strerror(errno)));
336
337         check_for_pipe(fname);
338         return;
339       }
340       sbuf = 0;
341     } else {
342       sbuf = &statbuf;
343     }
344   }
345
346   /*
347    * Check to see if we have this file already
348    * open. If we do, just use the already open fd and increment the
349    * reference count (fd_get_already_open increments the ref_count).
350    */
351   if((fd_ptr = fd_get_already_open(sbuf))!= 0) {
352     /*
353      * File was already open.
354      */
355
356     /* 
357      * Check it wasn't open for exclusive use.
358      */
359     if((flags & O_CREAT) && (flags & O_EXCL)) {
360       fd_ptr->ref_count--;
361       errno = EEXIST;
362       return;
363     }
364
365     /*
366      * Ensure that the user attempting to open
367      * this file has permissions to do so, if
368      * the user who originally opened the file wasn't
369      * the same as the current user.
370      */
371
372     if(!fd_is_in_uid_cache(fd_ptr, (uid_t)current_user.uid)) {
373       if(!check_access_allowed_for_current_user( fname, accmode )) {
374         /* Error - permission denied. */
375         DEBUG(3,("Permission denied opening file %s (flags=%d, accmode = %d)\n",
376               fname, flags, accmode));
377         /* Ensure the ref_count is decremented. */
378         fd_ptr->ref_count--;
379         fd_remove_from_uid_cache(fd_ptr, (uid_t)current_user.uid);
380         errno = EACCES;
381         return;
382       }
383     }
384
385     fd_add_to_uid_cache(fd_ptr, (uid_t)current_user.uid);
386
387     /* 
388      * If not opened O_RDWR try
389      * and do that here - a chmod may have been done
390      * between the last open and now. 
391      */
392     if(fd_ptr->real_open_flags != O_RDWR)
393       fd_attempt_reopen(fname, mode, fd_ptr);
394
395     /*
396      * Ensure that if we wanted write access
397      * it has been opened for write, and if we wanted read it
398      * was open for read. 
399      */
400     if(((accmode == O_WRONLY) && (fd_ptr->real_open_flags == O_RDONLY)) ||
401        ((accmode == O_RDONLY) && (fd_ptr->real_open_flags == O_WRONLY)) ||
402        ((accmode == O_RDWR) && (fd_ptr->real_open_flags != O_RDWR))) {
403       DEBUG(3,("Error opening (already open for flags=%d) file %s (%s) (flags=%d)\n",
404                fd_ptr->real_open_flags, fname,strerror(EACCES),flags));
405       check_for_pipe(fname);
406       fd_remove_from_uid_cache(fd_ptr, (uid_t)current_user.uid);
407       fd_ptr->ref_count--;
408       return;
409     }
410
411   } else {
412     int open_flags;
413     /* We need to allocate a new file_fd_struct (this increments the
414        ref_count). */
415     if((fd_ptr = fd_get_new()) == 0)
416       return;
417     /*
418      * Whatever the requested flags, attempt read/write access,
419      * as we don't know what flags future file opens may require.
420      * If this fails, try again with the required flags. 
421      * Even if we open read/write when only read access was 
422      * requested the setting of the can_write flag in
423      * the file_struct will protect us from errant
424      * write requests. We never need to worry about O_APPEND
425      * as this is not set anywhere in Samba.
426      */
427     fd_ptr->real_open_flags = O_RDWR;
428     /* Set the flags as needed without the read/write modes. */
429     open_flags = flags & ~(O_RDWR|O_WRONLY|O_RDONLY);
430     fd_ptr->fd = fd_attempt_open(fname, open_flags|O_RDWR, mode);
431     /*
432      * On some systems opening a file for R/W access on a read only
433      * filesystems sets errno to EROFS.
434      */
435 #ifdef EROFS
436     if((fd_ptr->fd == -1) && ((errno == EACCES) || (errno == EROFS))) {
437 #else /* No EROFS */
438     if((fd_ptr->fd == -1) && (errno == EACCES)) {
439 #endif /* EROFS */
440       if(accmode != O_RDWR) {
441         fd_ptr->fd = fd_attempt_open(fname, open_flags|accmode, mode);
442         fd_ptr->real_open_flags = accmode;
443       }
444     }
445   }
446
447   if ((fd_ptr->fd >=0) && 
448       conn->printer && lp_minprintspace(SNUM(conn))) {
449     pstring dname;
450     int dum1,dum2,dum3;
451     char *p;
452     pstrcpy(dname,fname);
453     p = strrchr(dname,'/');
454     if (p) *p = 0;
455     if (sys_disk_free(dname,&dum1,&dum2,&dum3) < 
456         lp_minprintspace(SNUM(conn))) {
457       if(fd_attempt_close(fd_ptr) == 0)
458         dos_unlink(fname);
459       fsp->fd_ptr = 0;
460       errno = ENOSPC;
461       return;
462     }
463   }
464     
465   if (fd_ptr->fd < 0)
466   {
467     DEBUG(3,("Error opening file %s (%s) (flags=%d)\n",
468       fname,strerror(errno),flags));
469     /* Ensure the ref_count is decremented. */
470     fd_attempt_close(fd_ptr);
471     check_for_pipe(fname);
472     return;
473   }
474
475   if (fd_ptr->fd >= 0)
476   {
477     if(sbuf == 0) {
478       /* Do the fstat */
479       if(sys_fstat(fd_ptr->fd, &statbuf) == -1) {
480         /* Error - backout !! */
481         DEBUG(3,("Error doing fstat on fd %d, file %s (%s)\n",
482                  fd_ptr->fd, fname,strerror(errno)));
483         /* Ensure the ref_count is decremented. */
484         fd_attempt_close(fd_ptr);
485         return;
486       }
487       sbuf = &statbuf;
488     }
489
490     /* Set the correct entries in fd_ptr. */
491     fd_ptr->dev = sbuf->st_dev;
492     fd_ptr->inode = sbuf->st_ino;
493
494     fsp->fd_ptr = fd_ptr;
495     conn->num_files_open++;
496     fsp->mode = sbuf->st_mode;
497     GetTimeOfDay(&fsp->open_time);
498     fsp->vuid = current_user.vuid;
499     fsp->size = 0;
500     fsp->pos = -1;
501     fsp->open = True;
502     fsp->mmap_ptr = NULL;
503     fsp->mmap_size = 0;
504     fsp->can_lock = True;
505     fsp->can_read = ((flags & O_WRONLY)==0);
506     fsp->can_write = ((flags & (O_WRONLY|O_RDWR))!=0);
507     fsp->share_mode = 0;
508     fsp->print_file = conn->printer;
509     fsp->modified = False;
510     fsp->granted_oplock = False;
511     fsp->sent_oplock_break = False;
512     fsp->is_directory = False;
513     fsp->conn = conn;
514     /*
515      * Note that the file name here is the *untranslated* name
516      * ie. it is still in the DOS codepage sent from the client.
517      * All use of this filename will pass though the sys_xxxx
518      * functions which will do the dos_to_unix translation before
519      * mapping into a UNIX filename. JRA.
520      */
521     string_set(&fsp->fsp_name,fname);
522     fsp->wbmpx_ptr = NULL;      
523
524     /*
525      * If the printer is marked as postscript output a leading
526      * file identifier to ensure the file is treated as a raw
527      * postscript file.
528      * This has a similar effect as CtrlD=0 in WIN.INI file.
529      * tim@fsg.com 09/06/94
530      */
531     if (fsp->print_file && lp_postscript(SNUM(conn)) && fsp->can_write) {
532             DEBUG(3,("Writing postscript line\n"));
533             write_file(fsp,"%!\n",3);
534     }
535       
536     DEBUG(2,("%s opened file %s read=%s write=%s (numopen=%d)\n",
537              *sesssetup_user ? sesssetup_user : conn->user,fsp->fsp_name,
538              BOOLSTR(fsp->can_read), BOOLSTR(fsp->can_write),
539              conn->num_files_open));
540
541   }
542
543 #if WITH_MMAP
544   /* mmap it if read-only */
545   if (!fsp->can_write) {
546           fsp->mmap_size = file_size(fname);
547           fsp->mmap_ptr = (char *)mmap(NULL,fsp->mmap_size,
548                                        PROT_READ,MAP_SHARED,fsp->fd_ptr->fd,0);
549
550           if (fsp->mmap_ptr == (char *)-1 || !fsp->mmap_ptr) {
551                   DEBUG(3,("Failed to mmap() %s - %s\n",
552                            fname,strerror(errno)));
553                   fsp->mmap_ptr = NULL;
554           }
555   }
556 #endif
557 }
558
559
560 /****************************************************************************
561   C. Hoch 11/22/95
562   Helper for open_file_shared. 
563   Truncate a file after checking locking; close file if locked.
564   **************************************************************************/
565 static void truncate_unless_locked(files_struct *fsp, connection_struct *conn, int token, 
566                                    BOOL *share_locked)
567 {
568   if (fsp->can_write){
569 #ifdef LARGE_SMB_OFF_T
570     if (is_locked(fsp,conn,0x3FFFFFFFFFFFFFFFLL,0,F_WRLCK)){
571 #else
572     if (is_locked(fsp,conn,0x3FFFFFFF,0,F_WRLCK)){
573 #endif
574       /* If share modes are in force for this connection we
575          have the share entry locked. Unlock it before closing. */
576       if (*share_locked && lp_share_modes(SNUM(conn)))
577         unlock_share_entry( conn, fsp->fd_ptr->dev, 
578                             fsp->fd_ptr->inode, token);
579       close_file(fsp,False);   
580       /* Share mode no longer locked. */
581       *share_locked = False;
582       errno = EACCES;
583       unix_ERR_class = ERRDOS;
584       unix_ERR_code = ERRlock;
585     }
586     else
587       sys_ftruncate(fsp->fd_ptr->fd,0); 
588   }
589 }
590
591
592
593 /****************************************************************************
594 open a file with a share mode
595 ****************************************************************************/
596 void open_file_shared(files_struct *fsp,connection_struct *conn,char *fname,int share_mode,int ofun,
597                       int mode,int oplock_request, int *Access,int *action)
598 {
599   int flags=0;
600   int flags2=0;
601   int deny_mode = (share_mode>>4)&7;
602   SMB_STRUCT_STAT sbuf;
603   BOOL file_existed = file_exist(fname,&sbuf);
604   BOOL share_locked = False;
605   BOOL fcbopen = False;
606   int token;
607   SMB_DEV_T dev = 0;
608   SMB_INO_T inode = 0;
609   int num_share_modes = 0;
610
611   fsp->open = False;
612   fsp->fd_ptr = 0;
613
614   /* this is for OS/2 EAs - try and say we don't support them */
615   if (strstr(fname,".+,;=[].")) 
616   {
617     unix_ERR_class = ERRDOS;
618     /* OS/2 Workplace shell fix may be main code stream in a later release. */ 
619 #if 1 /* OS2_WPS_FIX - Recent versions of OS/2 need this. */
620     unix_ERR_code = ERRcannotopen;
621 #else /* OS2_WPS_FIX */
622     unix_ERR_code = ERROR_EAS_NOT_SUPPORTED;
623 #endif /* OS2_WPS_FIX */
624
625     return;
626   }
627
628   if ((ofun & 0x3) == 0 && file_existed)  
629   {
630     errno = EEXIST;
631     return;
632   }
633       
634   if (ofun & 0x10)
635     flags2 |= O_CREAT;
636   if ((ofun & 0x3) == 2)
637     flags2 |= O_TRUNC;
638
639   /* note that we ignore the append flag as 
640      append does not mean the same thing under dos and unix */
641
642   switch (share_mode&0xF)
643   {
644     case 1: 
645       flags = O_WRONLY; 
646       break;
647     case 0xF: 
648       fcbopen = True;
649       flags = O_RDWR; 
650       break;
651     case 2: 
652       flags = O_RDWR; 
653       break;
654     default:
655       flags = O_RDONLY;
656       break;
657   }
658
659 #if defined(O_SYNC)
660   if (share_mode&(1<<14)) {
661           flags2 |= O_SYNC;
662   }
663 #endif /* O_SYNC */
664   
665   if (flags != O_RDONLY && file_existed && 
666       (!CAN_WRITE(conn) || IS_DOS_READONLY(dos_mode(conn,fname,&sbuf)))) 
667   {
668     if (!fcbopen) 
669     {
670       errno = EACCES;
671       return;
672     }
673     flags = O_RDONLY;
674   }
675
676   if (deny_mode > DENY_NONE && deny_mode!=DENY_FCB) 
677   {
678     DEBUG(2,("Invalid deny mode %d on file %s\n",deny_mode,fname));
679     errno = EINVAL;
680     return;
681   }
682
683   if (deny_mode == DENY_FCB) deny_mode = DENY_DOS;
684
685   if (lp_share_modes(SNUM(conn))) 
686   {
687     int i;
688     share_mode_entry *old_shares = 0;
689
690     if (file_existed)
691     {
692       dev = sbuf.st_dev;
693       inode = sbuf.st_ino;
694       lock_share_entry(conn, dev, inode, &token);
695       share_locked = True;
696       num_share_modes = get_share_modes(conn, token, dev, inode, &old_shares);
697     }
698
699     /*
700      * Check if the share modes will give us access.
701      */
702
703     if(share_locked && (num_share_modes != 0))
704     {
705       BOOL broke_oplock;
706
707       do
708       {
709
710         broke_oplock = False;
711         for(i = 0; i < num_share_modes; i++)
712         {
713           share_mode_entry *share_entry = &old_shares[i];
714
715           /* 
716            * By observation of NetBench, oplocks are broken *before* share
717            * modes are checked. This allows a file to be closed by the client
718            * if the share mode would deny access and the client has an oplock. 
719            * Check if someone has an oplock on this file. If so we must break 
720            * it before continuing. 
721            */
722           if(share_entry->op_type & (EXCLUSIVE_OPLOCK|BATCH_OPLOCK))
723           {
724
725 #ifdef LARGE_SMB_INO_T
726             DEBUG(5,("open_file_shared: breaking oplock (%x) on file %s, \
727 dev = %x, inode = %.0f\n", share_entry->op_type, fname, (unsigned int)dev, (double)inode));
728 #else /* LARGE_SMB_INO_T */
729             DEBUG(5,("open_file_shared: breaking oplock (%x) on file %s, \
730 dev = %x, inode = %lx\n", share_entry->op_type, fname, (unsigned int)dev, (unsigned long)inode));
731 #endif /* LARGE_SMB_INO_T */
732
733             /* Oplock break.... */
734             unlock_share_entry(conn, dev, inode, token);
735             if(request_oplock_break(share_entry, dev, inode) == False)
736             {
737               free((char *)old_shares);
738
739 #ifdef LARGE_SMB_INO_T
740               DEBUG(0,("open_file_shared: FAILED when breaking oplock (%x) on file %s, \
741 dev = %x, inode = %.0f\n", old_shares[i].op_type, fname, (unsigned int)dev, (double)inode));
742 #else /* LARGE_SMB_INO_T */
743               DEBUG(0,("open_file_shared: FAILED when breaking oplock (%x) on file %s, \
744 dev = %x, inode = %lx\n", old_shares[i].op_type, fname, (unsigned int)dev, (unsigned long)inode));
745 #endif /* LARGE_SMB_INO_T */
746
747               errno = EACCES;
748               unix_ERR_class = ERRDOS;
749               unix_ERR_code = ERRbadshare;
750               return;
751             }
752             lock_share_entry(conn, dev, inode, &token);
753             broke_oplock = True;
754             break;
755           }
756
757           /* someone else has a share lock on it, check to see 
758              if we can too */
759           if(check_share_mode(share_entry, deny_mode, fname, fcbopen, &flags) == False)
760           {
761             free((char *)old_shares);
762             unlock_share_entry(conn, dev, inode, token);
763             errno = EACCES;
764             unix_ERR_class = ERRDOS;
765             unix_ERR_code = ERRbadshare;
766             return;
767           }
768
769         } /* end for */
770
771         if(broke_oplock)
772         {
773           free((char *)old_shares);
774           num_share_modes = get_share_modes(conn, token, dev, inode, &old_shares);
775         }
776       } while(broke_oplock);
777     }
778
779     if(old_shares != 0)
780       free((char *)old_shares);
781   }
782
783   DEBUG(4,("calling open_file with flags=0x%X flags2=0x%X mode=0%o\n",
784            flags,flags2,mode));
785
786   open_file(fsp,conn,fname,flags|(flags2&~(O_TRUNC)),mode,file_existed ? &sbuf : 0);
787   if (!fsp->open && flags==O_RDWR && errno!=ENOENT && fcbopen) 
788   {
789     flags = O_RDONLY;
790     open_file(fsp,conn,fname,flags,mode,file_existed ? &sbuf : 0 );
791   }
792
793   if (fsp->open) 
794   {
795     int open_mode=0;
796
797     if((share_locked == False) && lp_share_modes(SNUM(conn)))
798     {
799       /* We created the file - thus we must now lock the share entry before creating it. */
800       dev = fsp->fd_ptr->dev;
801       inode = fsp->fd_ptr->inode;
802       lock_share_entry(conn, dev, inode, &token);
803       share_locked = True;
804     }
805
806     switch (flags) 
807     {
808       case O_RDONLY:
809         open_mode = 0;
810         break;
811       case O_RDWR:
812         open_mode = 2;
813         break;
814       case O_WRONLY:
815         open_mode = 1;
816         break;
817     }
818
819     fsp->share_mode = (deny_mode<<4) | open_mode;
820
821     if (Access)
822       (*Access) = open_mode;
823
824     if (action) 
825     {
826       if (file_existed && !(flags2 & O_TRUNC)) *action = FILE_WAS_OPENED;
827       if (!file_existed) *action = FILE_WAS_CREATED;
828       if (file_existed && (flags2 & O_TRUNC)) *action = FILE_WAS_OVERWRITTEN;
829     }
830     /* We must create the share mode entry before truncate as
831        truncate can fail due to locking and have to close the
832        file (which expects the share_mode_entry to be there).
833      */
834     if (lp_share_modes(SNUM(conn)))
835     {
836       uint16 port = 0;
837       /* JRA. Currently this only services Exlcusive and batch
838          oplocks (no other opens on this file). This needs to
839          be extended to level II oplocks (multiple reader
840          oplocks). */
841
842       if(oplock_request && (num_share_modes == 0) && lp_oplocks(SNUM(conn)) && 
843               !IS_VETO_OPLOCK_PATH(conn,fname))
844       {
845         fsp->granted_oplock = True;
846         fsp->sent_oplock_break = False;
847         global_oplocks_open++;
848         port = oplock_port;
849
850 #ifdef LARGE_SMB_INO_T
851         DEBUG(5,("open_file_shared: granted oplock (%x) on file %s, \
852 dev = %x, inode = %.0f\n", oplock_request, fname, (unsigned int)dev, (double)inode));
853 #else /* LARGE_SMB_INO_T */
854         DEBUG(5,("open_file_shared: granted oplock (%x) on file %s, \
855 dev = %x, inode = %lx\n", oplock_request, fname, (unsigned int)dev, (double)inode));
856 #endif /* LARGE_SMB_INO_T */
857
858       }
859       else
860       {
861         port = 0;
862         oplock_request = 0;
863       }
864       set_share_mode(token, fsp, port, oplock_request);
865     }
866
867     if ((flags2&O_TRUNC) && file_existed)
868       truncate_unless_locked(fsp,conn,token,&share_locked);
869   }
870
871   if (share_locked && lp_share_modes(SNUM(conn)))
872     unlock_share_entry( conn, dev, inode, token);
873 }
874
875
876
877 /****************************************************************************
878  Open a directory from an NT SMB call.
879 ****************************************************************************/
880 int open_directory(files_struct *fsp,connection_struct *conn,
881                    char *fname, int smb_ofun, int unixmode, int *action)
882 {
883         extern struct current_user current_user;
884         SMB_STRUCT_STAT st;
885
886         if (smb_ofun & 0x10) {
887                 /*
888                  * Create the directory.
889                  */
890
891                 if(dos_mkdir(fname, unixmode) < 0) {
892                         DEBUG(0,("open_directory: unable to create %s. Error was %s\n",
893                                  fname, strerror(errno) ));
894                         return -1;
895                 }
896
897                 *action = FILE_WAS_CREATED;
898         } else {
899                 /*
900                  * Check that it *was* a directory.
901                  */
902
903                 if(dos_stat(fname, &st) < 0) {
904                         DEBUG(0,("open_directory: unable to stat name = %s. Error was %s\n",
905                                  fname, strerror(errno) ));
906                         return -1;
907                 }
908
909                 if(!S_ISDIR(st.st_mode)) {
910                         DEBUG(0,("open_directory: %s is not a directory !\n", fname ));
911                         return -1;
912                 }
913                 *action = FILE_WAS_OPENED;
914         }
915         
916         DEBUG(5,("open_directory: opening directory %s\n",
917                  fname));
918
919         /*
920          * Setup the files_struct for it.
921          */
922         
923         fsp->fd_ptr = NULL;
924         conn->num_files_open++;
925         fsp->mode = 0;
926         GetTimeOfDay(&fsp->open_time);
927         fsp->vuid = current_user.vuid;
928         fsp->size = 0;
929         fsp->pos = -1;
930         fsp->open = True;
931         fsp->mmap_ptr = NULL;
932         fsp->mmap_size = 0;
933         fsp->can_lock = True;
934         fsp->can_read = False;
935         fsp->can_write = False;
936         fsp->share_mode = 0;
937         fsp->print_file = False;
938         fsp->modified = False;
939         fsp->granted_oplock = False;
940         fsp->sent_oplock_break = False;
941         fsp->is_directory = True;
942         fsp->conn = conn;
943         /*
944          * Note that the file name here is the *untranslated* name
945          * ie. it is still in the DOS codepage sent from the client.
946          * All use of this filename will pass though the sys_xxxx
947          * functions which will do the dos_to_unix translation before
948          * mapping into a UNIX filename. JRA.
949          */
950         string_set(&fsp->fsp_name,fname);
951         fsp->wbmpx_ptr = NULL;
952
953         return 0;
954 }
955
956 enum {AFAIL,AREAD,AWRITE,AALL};
957
958 /*******************************************************************
959 reproduce the share mode access table
960 ********************************************************************/
961 static int access_table(int new_deny,int old_deny,int old_mode,
962                         int share_pid,char *fname)
963 {
964   if (new_deny == DENY_ALL || old_deny == DENY_ALL) return(AFAIL);
965
966   if (new_deny == DENY_DOS || old_deny == DENY_DOS) {
967     int pid = getpid();
968     if (old_deny == new_deny && share_pid == pid) 
969         return(AALL);    
970
971     if (old_mode == 0) return(AREAD);
972
973     /* the new smbpub.zip spec says that if the file extension is
974        .com, .dll, .exe or .sym then allow the open. I will force
975        it to read-only as this seems sensible although the spec is
976        a little unclear on this. */
977     if ((fname = strrchr(fname,'.'))) {
978       if (strequal(fname,".com") ||
979           strequal(fname,".dll") ||
980           strequal(fname,".exe") ||
981           strequal(fname,".sym"))
982         return(AREAD);
983     }
984
985     return(AFAIL);
986   }
987
988   switch (new_deny) 
989     {
990     case DENY_WRITE:
991       if (old_deny==DENY_WRITE && old_mode==0) return(AREAD);
992       if (old_deny==DENY_READ && old_mode==0) return(AWRITE);
993       if (old_deny==DENY_NONE && old_mode==0) return(AALL);
994       return(AFAIL);
995     case DENY_READ:
996       if (old_deny==DENY_WRITE && old_mode==1) return(AREAD);
997       if (old_deny==DENY_READ && old_mode==1) return(AWRITE);
998       if (old_deny==DENY_NONE && old_mode==1) return(AALL);
999       return(AFAIL);
1000     case DENY_NONE:
1001       if (old_deny==DENY_WRITE) return(AREAD);
1002       if (old_deny==DENY_READ) return(AWRITE);
1003       if (old_deny==DENY_NONE) return(AALL);
1004       return(AFAIL);      
1005     }
1006   return(AFAIL);      
1007 }
1008
1009 /*******************************************************************
1010 check if the share mode on a file allows it to be deleted or unlinked
1011 return True if sharing doesn't prevent the operation
1012 ********************************************************************/
1013 BOOL check_file_sharing(connection_struct *conn,char *fname, BOOL rename_op)
1014 {
1015   int i;
1016   int ret = False;
1017   share_mode_entry *old_shares = 0;
1018   int num_share_modes;
1019   SMB_STRUCT_STAT sbuf;
1020   int token;
1021   int pid = getpid();
1022   SMB_DEV_T dev;
1023   SMB_INO_T inode;
1024
1025   if(!lp_share_modes(SNUM(conn)))
1026     return True;
1027
1028   if (dos_stat(fname,&sbuf) == -1) return(True);
1029
1030   dev = sbuf.st_dev;
1031   inode = sbuf.st_ino;
1032
1033   lock_share_entry(conn, dev, inode, &token);
1034   num_share_modes = get_share_modes(conn, token, dev, inode, &old_shares);
1035
1036   /*
1037    * Check if the share modes will give us access.
1038    */
1039
1040   if(num_share_modes != 0)
1041   {
1042     BOOL broke_oplock;
1043
1044     do
1045     {
1046
1047       broke_oplock = False;
1048       for(i = 0; i < num_share_modes; i++)
1049       {
1050         share_mode_entry *share_entry = &old_shares[i];
1051
1052         /* 
1053          * Break oplocks before checking share modes. See comment in
1054          * open_file_shared for details. 
1055          * Check if someone has an oplock on this file. If so we must 
1056          * break it before continuing. 
1057          */
1058         if(share_entry->op_type & BATCH_OPLOCK)
1059         {
1060
1061           /*
1062            * It appears that the NT redirector may have a bug, in that
1063            * it tries to do an SMBmv on a file that it has open with a
1064            * batch oplock, and then fails to respond to the oplock break
1065            * request. This only seems to occur when the client is doing an
1066            * SMBmv to the smbd it is using - thus we try and detect this
1067            * condition by checking if the file being moved is open and oplocked by
1068            * this smbd process, and then not sending the oplock break in this
1069            * special case. If the file was open with a deny mode that 
1070            * prevents the move the SMBmv will fail anyway with a share
1071            * violation error. JRA.
1072            */
1073           if(rename_op && (share_entry->pid == pid))
1074           {
1075
1076 #ifdef LARGE_SMB_INO_T
1077             DEBUG(0,("check_file_sharing: NT redirector workaround - rename attempted on \
1078 batch oplocked file %s, dev = %x, inode = %.0f\n", fname, (unsigned int)dev, (double)inode));
1079 #else /* LARGE_SMB_INO_T */
1080             DEBUG(0,("check_file_sharing: NT redirector workaround - rename attempted on \
1081 batch oplocked file %s, dev = %x, inode = %lx\n", fname, (unsigned int)dev, (unsigned long)inode));
1082 #endif /* LARGE_SMB_INO_T */
1083
1084             /* 
1085              * This next line is a test that allows the deny-mode
1086              * processing to be skipped. This seems to be needed as
1087              * NT insists on the rename succeeding (in Office 9x no less !).
1088              * This should be removed as soon as (a) MS fix the redirector
1089              * bug or (b) NT SMB support in Samba makes NT not issue the
1090              * call (as is my fervent hope). JRA.
1091              */ 
1092             continue;
1093           }
1094           else
1095           {
1096
1097 #ifdef LARGE_SMB_INO_T
1098             DEBUG(5,("check_file_sharing: breaking oplock (%x) on file %s, \
1099 dev = %x, inode = %.0f\n", share_entry->op_type, fname, (unsigned int)dev, (double)inode));
1100 #else /* LARGE_SMB_INO_T */
1101             DEBUG(5,("check_file_sharing: breaking oplock (%x) on file %s, \
1102 dev = %x, inode = %lx\n", share_entry->op_type, fname, (unsigned int)dev, (unsigned long)inode));
1103 #endif /* LARGE_SMB_INO_T */
1104
1105             /* Oplock break.... */
1106             unlock_share_entry(conn, dev, inode, token);
1107             if(request_oplock_break(share_entry, dev, inode) == False)
1108             {
1109               free((char *)old_shares);
1110
1111 #ifdef LARGE_SMB_INO_T
1112               DEBUG(0,("check_file_sharing: FAILED when breaking oplock (%x) on file %s, \
1113 dev = %x, inode = %.0f\n", old_shares[i].op_type, fname, (unsigned int)dev, (double)inode));
1114 #else /* LARGE_SMB_INO_T */
1115               DEBUG(0,("check_file_sharing: FAILED when breaking oplock (%x) on file %s, \
1116 dev = %x, inode = %lx\n", old_shares[i].op_type, fname, (unsigned int)dev, (unsigned long)inode));
1117 #endif /* LARGE_SMB_INO_T */
1118
1119               return False;
1120             }
1121             lock_share_entry(conn, dev, inode, &token);
1122             broke_oplock = True;
1123             break;
1124           }
1125         }
1126
1127         /* someone else has a share lock on it, check to see 
1128            if we can too */
1129         if ((share_entry->share_mode != DENY_DOS) || (share_entry->pid != pid))
1130           goto free_and_exit;
1131
1132       } /* end for */
1133
1134       if(broke_oplock)
1135       {
1136         free((char *)old_shares);
1137         num_share_modes = get_share_modes(conn, token, dev, inode, &old_shares);
1138       }
1139     } while(broke_oplock);
1140   }
1141
1142   /* XXXX exactly what share mode combinations should be allowed for
1143      deleting/renaming? */
1144   /* If we got here then either there were no share modes or
1145      all share modes were DENY_DOS and the pid == getpid() */
1146   ret = True;
1147
1148 free_and_exit:
1149
1150   unlock_share_entry(conn, dev, inode, token);
1151   if(old_shares != NULL)
1152     free((char *)old_shares);
1153   return(ret);
1154 }
1155
1156 /****************************************************************************
1157 check if we can open a file with a share mode
1158 ****************************************************************************/
1159 int check_share_mode( share_mode_entry *share, int deny_mode, char *fname,
1160                       BOOL fcbopen, int *flags)
1161 {
1162   int old_open_mode = share->share_mode &0xF;
1163   int old_deny_mode = (share->share_mode >>4)&7;
1164
1165   if (old_deny_mode > 4 || old_open_mode > 2)
1166   {
1167     DEBUG(0,("Invalid share mode found (%d,%d,%d) on file %s\n",
1168                deny_mode,old_deny_mode,old_open_mode,fname));
1169     return False;
1170   }
1171
1172   {
1173     int access_allowed = access_table(deny_mode,old_deny_mode,old_open_mode,
1174                                 share->pid,fname);
1175
1176     if ((access_allowed == AFAIL) ||
1177         (!fcbopen && (access_allowed == AREAD && *flags == O_RDWR)) ||
1178         (access_allowed == AREAD && *flags == O_WRONLY) ||
1179         (access_allowed == AWRITE && *flags == O_RDONLY))
1180     {
1181       DEBUG(2,("Share violation on file (%d,%d,%d,%d,%s,fcbopen = %d, flags = %d) = %d\n",
1182                 deny_mode,old_deny_mode,old_open_mode,
1183                 share->pid,fname, fcbopen, *flags, access_allowed));
1184       return False;
1185     }
1186
1187     if (access_allowed == AREAD)
1188       *flags = O_RDONLY;
1189
1190     if (access_allowed == AWRITE)
1191       *flags = O_WRONLY;
1192
1193   }
1194   return True;
1195 }
1196