bd1ead69218d98bce4f9607fcbd660c02f23d8be
[kai/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 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,int 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     int 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) < 
453         lp_minprintspace(SNUM(conn))) {
454       if(fd_attempt_close(fd_ptr) == 0)
455         dos_unlink(fname);
456       fsp->fd_ptr = 0;
457       errno = ENOSPC;
458       return;
459     }
460   }
461     
462   if (fd_ptr->fd < 0)
463   {
464     DEBUG(3,("Error opening file %s (%s) (flags=%d)\n",
465       fname,strerror(errno),flags));
466     /* Ensure the ref_count is decremented. */
467     fd_attempt_close(fd_ptr);
468     check_for_pipe(fname);
469     return;
470   }
471
472   if (fd_ptr->fd >= 0)
473   {
474     if(sbuf == 0) {
475       /* Do the fstat */
476       if(sys_fstat(fd_ptr->fd, &statbuf) == -1) {
477         /* Error - backout !! */
478         DEBUG(3,("Error doing fstat on fd %d, file %s (%s)\n",
479                  fd_ptr->fd, fname,strerror(errno)));
480         /* Ensure the ref_count is decremented. */
481         fd_attempt_close(fd_ptr);
482         return;
483       }
484       sbuf = &statbuf;
485     }
486
487     /* Set the correct entries in fd_ptr. */
488     fd_ptr->dev = sbuf->st_dev;
489     fd_ptr->inode = sbuf->st_ino;
490
491     fsp->fd_ptr = fd_ptr;
492     conn->num_files_open++;
493     fsp->mode = sbuf->st_mode;
494     GetTimeOfDay(&fsp->open_time);
495     fsp->vuid = current_user.vuid;
496     fsp->size = 0;
497     fsp->pos = -1;
498     fsp->open = True;
499     fsp->mmap_ptr = NULL;
500     fsp->mmap_size = 0;
501     fsp->can_lock = True;
502     fsp->can_read = ((flags & O_WRONLY)==0);
503     fsp->can_write = ((flags & (O_WRONLY|O_RDWR))!=0);
504     fsp->share_mode = 0;
505     fsp->print_file = conn->printer;
506     fsp->modified = False;
507     fsp->granted_oplock = False;
508     fsp->sent_oplock_break = False;
509     fsp->is_directory = 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                       int 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 #ifdef LARGE_SMB_INO_T
819             DEBUG(5,("open_file_shared: breaking oplock (%x) on file %s, \
820 dev = %x, inode = %.0f\n", share_entry->op_type, fname, (unsigned int)dev, (double)inode));
821 #else /* LARGE_SMB_INO_T */
822             DEBUG(5,("open_file_shared: breaking oplock (%x) on file %s, \
823 dev = %x, inode = %lx\n", share_entry->op_type, fname, (unsigned int)dev, (unsigned long)inode));
824 #endif /* LARGE_SMB_INO_T */
825
826             /* Oplock break.... */
827             unlock_share_entry(conn, dev, inode, token);
828             if(request_oplock_break(share_entry, dev, inode) == False)
829             {
830               free((char *)old_shares);
831
832 #ifdef LARGE_SMB_INO_T
833               DEBUG(0,("open_file_shared: FAILED when breaking oplock (%x) on file %s, \
834 dev = %x, inode = %.0f\n", old_shares[i].op_type, fname, (unsigned int)dev, (double)inode));
835 #else /* LARGE_SMB_INO_T */
836               DEBUG(0,("open_file_shared: FAILED when breaking oplock (%x) on file %s, \
837 dev = %x, inode = %lx\n", old_shares[i].op_type, fname, (unsigned int)dev, (unsigned long)inode));
838 #endif /* LARGE_SMB_INO_T */
839
840               errno = EACCES;
841               unix_ERR_class = ERRDOS;
842               unix_ERR_code = ERRbadshare;
843               return;
844             }
845             lock_share_entry(conn, dev, inode, &token);
846             broke_oplock = True;
847             break;
848           }
849
850           /* someone else has a share lock on it, check to see 
851              if we can too */
852           if(check_share_mode(share_entry, deny_mode, fname, fcbopen, &flags) == False)
853           {
854             free((char *)old_shares);
855             unlock_share_entry(conn, dev, inode, token);
856             errno = EACCES;
857             unix_ERR_class = ERRDOS;
858             unix_ERR_code = ERRbadshare;
859             return;
860           }
861
862         } /* end for */
863
864         if(broke_oplock)
865         {
866           free((char *)old_shares);
867           num_share_modes = get_share_modes(conn, token, dev, inode, &old_shares);
868         }
869       } while(broke_oplock);
870     }
871
872     if(old_shares != 0)
873       free((char *)old_shares);
874   }
875
876   DEBUG(4,("calling open_file with flags=0x%X flags2=0x%X mode=0%o\n",
877            flags,flags2,mode));
878
879   open_file(fsp,conn,fname,flags|(flags2&~(O_TRUNC)),mode,file_existed ? &sbuf : 0);
880   if (!fsp->open && flags==O_RDWR && errno!=ENOENT && fcbopen) 
881   {
882     flags = O_RDONLY;
883     open_file(fsp,conn,fname,flags,mode,file_existed ? &sbuf : 0 );
884   }
885
886   if (fsp->open) 
887   {
888     int open_mode=0;
889
890     if((share_locked == False) && lp_share_modes(SNUM(conn)))
891     {
892       /* We created the file - thus we must now lock the share entry before creating it. */
893       dev = fsp->fd_ptr->dev;
894       inode = fsp->fd_ptr->inode;
895       lock_share_entry(conn, dev, inode, &token);
896       share_locked = True;
897     }
898
899     switch (flags) 
900     {
901       case O_RDONLY:
902         open_mode = 0;
903         break;
904       case O_RDWR:
905         open_mode = 2;
906         break;
907       case O_WRONLY:
908         open_mode = 1;
909         break;
910     }
911
912     fsp->share_mode = (deny_mode<<4) | open_mode;
913
914     if (Access)
915       (*Access) = open_mode;
916
917     if (action) 
918     {
919       if (file_existed && !(flags2 & O_TRUNC)) *action = FILE_WAS_OPENED;
920       if (!file_existed) *action = FILE_WAS_CREATED;
921       if (file_existed && (flags2 & O_TRUNC)) *action = FILE_WAS_OVERWRITTEN;
922     }
923     /* We must create the share mode entry before truncate as
924        truncate can fail due to locking and have to close the
925        file (which expects the share_mode_entry to be there).
926      */
927     if (lp_share_modes(SNUM(conn)))
928     {
929       uint16 port = 0;
930       /* JRA. Currently this only services Exlcusive and batch
931          oplocks (no other opens on this file). This needs to
932          be extended to level II oplocks (multiple reader
933          oplocks). */
934
935       if(oplock_request && (num_share_modes == 0) && lp_oplocks(SNUM(conn)) && 
936               !IS_VETO_OPLOCK_PATH(conn,fname))
937       {
938         fsp->granted_oplock = True;
939         fsp->sent_oplock_break = False;
940         global_oplocks_open++;
941         port = oplock_port;
942
943 #ifdef LARGE_SMB_INO_T
944         DEBUG(5,("open_file_shared: granted oplock (%x) on file %s, \
945 dev = %x, inode = %.0f\n", oplock_request, fname, (unsigned int)dev, (double)inode));
946 #else /* LARGE_SMB_INO_T */
947         DEBUG(5,("open_file_shared: granted oplock (%x) on file %s, \
948 dev = %x, inode = %lx\n", oplock_request, fname, (unsigned int)dev, (unsigned long)inode));
949 #endif /* LARGE_SMB_INO_T */
950
951       }
952       else
953       {
954         port = 0;
955         oplock_request = 0;
956       }
957       set_share_mode(token, fsp, port, oplock_request);
958     }
959
960     if ((flags2&O_TRUNC) && file_existed)
961       truncate_unless_locked(fsp,conn,token,&share_locked);
962   }
963
964   if (share_locked && lp_share_modes(SNUM(conn)))
965     unlock_share_entry( conn, dev, inode, token);
966 }
967
968
969
970 /****************************************************************************
971  Open a directory from an NT SMB call.
972 ****************************************************************************/
973 int open_directory(files_struct *fsp,connection_struct *conn,
974                    char *fname, int smb_ofun, int unixmode, int *action)
975 {
976         extern struct current_user current_user;
977         SMB_STRUCT_STAT st;
978
979         if (smb_ofun & 0x10) {
980                 /*
981                  * Create the directory.
982                  */
983
984                 if(dos_mkdir(fname, unixmode) < 0) {
985                         DEBUG(0,("open_directory: unable to create %s. Error was %s\n",
986                                  fname, strerror(errno) ));
987                         return -1;
988                 }
989
990                 *action = FILE_WAS_CREATED;
991         } else {
992                 /*
993                  * Check that it *was* a directory.
994                  */
995
996                 if(dos_stat(fname, &st) < 0) {
997                         DEBUG(0,("open_directory: unable to stat name = %s. Error was %s\n",
998                                  fname, strerror(errno) ));
999                         return -1;
1000                 }
1001
1002                 if(!S_ISDIR(st.st_mode)) {
1003                         DEBUG(0,("open_directory: %s is not a directory !\n", fname ));
1004                         return -1;
1005                 }
1006                 *action = FILE_WAS_OPENED;
1007         }
1008         
1009         DEBUG(5,("open_directory: opening directory %s\n",
1010                  fname));
1011
1012         /*
1013          * Setup the files_struct for it.
1014          */
1015         
1016         fsp->fd_ptr = NULL;
1017         conn->num_files_open++;
1018         fsp->mode = 0;
1019         GetTimeOfDay(&fsp->open_time);
1020         fsp->vuid = current_user.vuid;
1021         fsp->size = 0;
1022         fsp->pos = -1;
1023         fsp->open = True;
1024         fsp->mmap_ptr = NULL;
1025         fsp->mmap_size = 0;
1026         fsp->can_lock = True;
1027         fsp->can_read = False;
1028         fsp->can_write = False;
1029         fsp->share_mode = 0;
1030         fsp->print_file = False;
1031         fsp->modified = False;
1032         fsp->granted_oplock = False;
1033         fsp->sent_oplock_break = False;
1034         fsp->is_directory = True;
1035         fsp->conn = conn;
1036         /*
1037          * Note that the file name here is the *untranslated* name
1038          * ie. it is still in the DOS codepage sent from the client.
1039          * All use of this filename will pass though the sys_xxxx
1040          * functions which will do the dos_to_unix translation before
1041          * mapping into a UNIX filename. JRA.
1042          */
1043         string_set(&fsp->fsp_name,fname);
1044         fsp->wbmpx_ptr = NULL;
1045
1046         return 0;
1047 }
1048
1049
1050 /*******************************************************************
1051 check if the share mode on a file allows it to be deleted or unlinked
1052 return True if sharing doesn't prevent the operation
1053 ********************************************************************/
1054 BOOL check_file_sharing(connection_struct *conn,char *fname, BOOL rename_op)
1055 {
1056   int i;
1057   int ret = False;
1058   share_mode_entry *old_shares = 0;
1059   int num_share_modes;
1060   SMB_STRUCT_STAT sbuf;
1061   int token;
1062   int pid = getpid();
1063   SMB_DEV_T dev;
1064   SMB_INO_T inode;
1065
1066   if(!lp_share_modes(SNUM(conn)))
1067     return True;
1068
1069   if (dos_stat(fname,&sbuf) == -1) return(True);
1070
1071   dev = sbuf.st_dev;
1072   inode = sbuf.st_ino;
1073
1074   lock_share_entry(conn, dev, inode, &token);
1075   num_share_modes = get_share_modes(conn, token, dev, inode, &old_shares);
1076
1077   /*
1078    * Check if the share modes will give us access.
1079    */
1080
1081   if(num_share_modes != 0)
1082   {
1083     BOOL broke_oplock;
1084
1085     do
1086     {
1087
1088       broke_oplock = False;
1089       for(i = 0; i < num_share_modes; i++)
1090       {
1091         share_mode_entry *share_entry = &old_shares[i];
1092
1093         /* 
1094          * Break oplocks before checking share modes. See comment in
1095          * open_file_shared for details. 
1096          * Check if someone has an oplock on this file. If so we must 
1097          * break it before continuing. 
1098          */
1099         if(share_entry->op_type & BATCH_OPLOCK)
1100         {
1101
1102           /*
1103            * It appears that the NT redirector may have a bug, in that
1104            * it tries to do an SMBmv on a file that it has open with a
1105            * batch oplock, and then fails to respond to the oplock break
1106            * request. This only seems to occur when the client is doing an
1107            * SMBmv to the smbd it is using - thus we try and detect this
1108            * condition by checking if the file being moved is open and oplocked by
1109            * this smbd process, and then not sending the oplock break in this
1110            * special case. If the file was open with a deny mode that 
1111            * prevents the move the SMBmv will fail anyway with a share
1112            * violation error. JRA.
1113            */
1114           if(rename_op && (share_entry->pid == pid))
1115           {
1116
1117 #ifdef LARGE_SMB_INO_T
1118             DEBUG(0,("check_file_sharing: NT redirector workaround - rename attempted on \
1119 batch oplocked file %s, dev = %x, inode = %.0f\n", fname, (unsigned int)dev, (double)inode));
1120 #else /* LARGE_SMB_INO_T */
1121             DEBUG(0,("check_file_sharing: NT redirector workaround - rename attempted on \
1122 batch oplocked file %s, dev = %x, inode = %lx\n", fname, (unsigned int)dev, (unsigned long)inode));
1123 #endif /* LARGE_SMB_INO_T */
1124
1125             /* 
1126              * This next line is a test that allows the deny-mode
1127              * processing to be skipped. This seems to be needed as
1128              * NT insists on the rename succeeding (in Office 9x no less !).
1129              * This should be removed as soon as (a) MS fix the redirector
1130              * bug or (b) NT SMB support in Samba makes NT not issue the
1131              * call (as is my fervent hope). JRA.
1132              */ 
1133             continue;
1134           }
1135           else
1136           {
1137
1138 #ifdef LARGE_SMB_INO_T
1139             DEBUG(5,("check_file_sharing: breaking oplock (%x) on file %s, \
1140 dev = %x, inode = %.0f\n", share_entry->op_type, fname, (unsigned int)dev, (double)inode));
1141 #else /* LARGE_SMB_INO_T */
1142             DEBUG(5,("check_file_sharing: breaking oplock (%x) on file %s, \
1143 dev = %x, inode = %lx\n", share_entry->op_type, fname, (unsigned int)dev, (unsigned long)inode));
1144 #endif /* LARGE_SMB_INO_T */
1145
1146             /* Oplock break.... */
1147             unlock_share_entry(conn, dev, inode, token);
1148             if(request_oplock_break(share_entry, dev, inode) == False)
1149             {
1150               free((char *)old_shares);
1151
1152 #ifdef LARGE_SMB_INO_T
1153               DEBUG(0,("check_file_sharing: FAILED when breaking oplock (%x) on file %s, \
1154 dev = %x, inode = %.0f\n", old_shares[i].op_type, fname, (unsigned int)dev, (double)inode));
1155 #else /* LARGE_SMB_INO_T */
1156               DEBUG(0,("check_file_sharing: FAILED when breaking oplock (%x) on file %s, \
1157 dev = %x, inode = %lx\n", old_shares[i].op_type, fname, (unsigned int)dev, (unsigned long)inode));
1158 #endif /* LARGE_SMB_INO_T */
1159
1160               return False;
1161             }
1162             lock_share_entry(conn, dev, inode, &token);
1163             broke_oplock = True;
1164             break;
1165           }
1166         }
1167
1168         /* someone else has a share lock on it, check to see 
1169            if we can too */
1170         if ((share_entry->share_mode != DENY_DOS) || (share_entry->pid != pid))
1171           goto free_and_exit;
1172
1173       } /* end for */
1174
1175       if(broke_oplock)
1176       {
1177         free((char *)old_shares);
1178         num_share_modes = get_share_modes(conn, token, dev, inode, &old_shares);
1179       }
1180     } while(broke_oplock);
1181   }
1182
1183   /* XXXX exactly what share mode combinations should be allowed for
1184      deleting/renaming? */
1185   /* If we got here then either there were no share modes or
1186      all share modes were DENY_DOS and the pid == getpid() */
1187   ret = True;
1188
1189 free_and_exit:
1190
1191   unlock_share_entry(conn, dev, inode, token);
1192   if(old_shares != NULL)
1193     free((char *)old_shares);
1194   return(ret);
1195 }
1196
1197