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