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