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