Ok - this is the 'expose 64 bit to the clients' checkin.
[sfrench/samba-autobuild/.git] / source / smbd / open.c
1 /* 
2    Unix SMB/Netbios implementation.
3    Version 1.9.
4    file opening and share modes
5    Copyright (C) Andrew Tridgell 1992-1998
6    
7    This program is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 2 of the License, or
10    (at your option) any later version.
11    
12    This program is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16    
17    You should have received a copy of the GNU General Public License
18    along with this program; if not, write to the Free Software
19    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 */
21
22 #include "includes.h"
23
24 extern int DEBUGLEVEL;
25
26 extern pstring sesssetup_user;
27 extern 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->delete_on_close = False;
511     fsp->conn = conn;
512     /*
513      * Note that the file name here is the *untranslated* name
514      * ie. it is still in the DOS codepage sent from the client.
515      * All use of this filename will pass though the sys_xxxx
516      * functions which will do the dos_to_unix translation before
517      * mapping into a UNIX filename. JRA.
518      */
519     string_set(&fsp->fsp_name,fname);
520     fsp->wbmpx_ptr = NULL;      
521
522     /*
523      * If the printer is marked as postscript output a leading
524      * file identifier to ensure the file is treated as a raw
525      * postscript file.
526      * This has a similar effect as CtrlD=0 in WIN.INI file.
527      * tim@fsg.com 09/06/94
528      */
529     if (fsp->print_file && lp_postscript(SNUM(conn)) && fsp->can_write) {
530             DEBUG(3,("Writing postscript line\n"));
531             write_file(fsp,"%!\n",3);
532     }
533       
534     DEBUG(2,("%s opened file %s read=%s write=%s (numopen=%d)\n",
535              *sesssetup_user ? sesssetup_user : conn->user,fsp->fsp_name,
536              BOOLSTR(fsp->can_read), BOOLSTR(fsp->can_write),
537              conn->num_files_open));
538
539   }
540
541 #if WITH_MMAP
542   /* mmap it if read-only */
543   if (!fsp->can_write) {
544           fsp->mmap_size = file_size(fname);
545           fsp->mmap_ptr = (char *)mmap(NULL,fsp->mmap_size,
546                                        PROT_READ,MAP_SHARED,fsp->fd_ptr->fd,0);
547
548           if (fsp->mmap_ptr == (char *)-1 || !fsp->mmap_ptr) {
549                   DEBUG(3,("Failed to mmap() %s - %s\n",
550                            fname,strerror(errno)));
551                   fsp->mmap_ptr = NULL;
552           }
553   }
554 #endif
555 }
556
557
558 /****************************************************************************
559   C. Hoch 11/22/95
560   Helper for open_file_shared. 
561   Truncate a file after checking locking; close file if locked.
562   **************************************************************************/
563 static void truncate_unless_locked(files_struct *fsp, connection_struct *conn, int token, 
564                                    BOOL *share_locked)
565 {
566   if (fsp->can_write){
567 #ifdef LARGE_SMB_OFF_T
568     if (is_locked(fsp,conn,0x3FFFFFFFFFFFFFFFLL,0,F_WRLCK)){
569 #else
570     if (is_locked(fsp,conn,0x3FFFFFFF,0,F_WRLCK)){
571 #endif
572       /* If share modes are in force for this connection we
573          have the share entry locked. Unlock it before closing. */
574       if (*share_locked && lp_share_modes(SNUM(conn)))
575         unlock_share_entry( conn, fsp->fd_ptr->dev, 
576                             fsp->fd_ptr->inode, token);
577       close_file(fsp,False);   
578       /* Share mode no longer locked. */
579       *share_locked = False;
580       errno = EACCES;
581       unix_ERR_class = ERRDOS;
582       unix_ERR_code = ERRlock;
583     }
584     else
585       sys_ftruncate(fsp->fd_ptr->fd,0); 
586   }
587 }
588
589
590 enum {AFAIL,AREAD,AWRITE,AALL};
591
592 /*******************************************************************
593 reproduce the share mode access table
594 ********************************************************************/
595 static int access_table(int new_deny,int old_deny,int old_mode,
596                         int share_pid,char *fname)
597 {
598   if (new_deny == DENY_ALL || old_deny == DENY_ALL) return(AFAIL);
599
600   if (new_deny == DENY_DOS || old_deny == DENY_DOS) {
601     int pid = getpid();
602     if (old_deny == new_deny && share_pid == pid) 
603         return(AALL);    
604
605     if (old_mode == 0) return(AREAD);
606
607     /* the new smbpub.zip spec says that if the file extension is
608        .com, .dll, .exe or .sym then allow the open. I will force
609        it to read-only as this seems sensible although the spec is
610        a little unclear on this. */
611     if ((fname = strrchr(fname,'.'))) {
612       if (strequal(fname,".com") ||
613           strequal(fname,".dll") ||
614           strequal(fname,".exe") ||
615           strequal(fname,".sym"))
616         return(AREAD);
617     }
618
619     return(AFAIL);
620   }
621
622   switch (new_deny) 
623     {
624     case DENY_WRITE:
625       if (old_deny==DENY_WRITE && old_mode==0) return(AREAD);
626       if (old_deny==DENY_READ && old_mode==0) return(AWRITE);
627       if (old_deny==DENY_NONE && old_mode==0) return(AALL);
628       return(AFAIL);
629     case DENY_READ:
630       if (old_deny==DENY_WRITE && old_mode==1) return(AREAD);
631       if (old_deny==DENY_READ && old_mode==1) return(AWRITE);
632       if (old_deny==DENY_NONE && old_mode==1) return(AALL);
633       return(AFAIL);
634     case DENY_NONE:
635       if (old_deny==DENY_WRITE) return(AREAD);
636       if (old_deny==DENY_READ) return(AWRITE);
637       if (old_deny==DENY_NONE) return(AALL);
638       return(AFAIL);      
639     }
640   return(AFAIL);      
641 }
642
643
644 /****************************************************************************
645 check if we can open a file with a share mode
646 ****************************************************************************/
647 static int check_share_mode( share_mode_entry *share, int deny_mode, 
648                              char *fname,
649                              BOOL fcbopen, int *flags)
650 {
651   int old_open_mode = share->share_mode &0xF;
652   int old_deny_mode = (share->share_mode >>4)&7;
653
654   if (old_deny_mode > 4 || old_open_mode > 2)
655   {
656     DEBUG(0,("Invalid share mode found (%d,%d,%d) on file %s\n",
657                deny_mode,old_deny_mode,old_open_mode,fname));
658     return False;
659   }
660
661   {
662     int access_allowed = access_table(deny_mode,old_deny_mode,old_open_mode,
663                                 share->pid,fname);
664
665     if ((access_allowed == AFAIL) ||
666         (!fcbopen && (access_allowed == AREAD && *flags == O_RDWR)) ||
667         (access_allowed == AREAD && *flags == O_WRONLY) ||
668         (access_allowed == AWRITE && *flags == O_RDONLY))
669     {
670       DEBUG(2,("Share violation on file (%d,%d,%d,%d,%s,fcbopen = %d, flags = %d) = %d\n",
671                 deny_mode,old_deny_mode,old_open_mode,
672                 share->pid,fname, fcbopen, *flags, access_allowed));
673       return False;
674     }
675
676     if (access_allowed == AREAD)
677       *flags = O_RDONLY;
678
679     if (access_allowed == AWRITE)
680       *flags = O_WRONLY;
681
682   }
683   return True;
684 }
685
686
687 /****************************************************************************
688 open a file with a share mode
689 ****************************************************************************/
690 void open_file_shared(files_struct *fsp,connection_struct *conn,char *fname,int share_mode,int ofun,
691                       int mode,int oplock_request, int *Access,int *action)
692 {
693   int flags=0;
694   int flags2=0;
695   int deny_mode = (share_mode>>4)&7;
696   SMB_STRUCT_STAT sbuf;
697   BOOL file_existed = file_exist(fname,&sbuf);
698   BOOL share_locked = False;
699   BOOL fcbopen = False;
700   int token;
701   SMB_DEV_T dev = 0;
702   SMB_INO_T inode = 0;
703   int num_share_modes = 0;
704
705   fsp->open = False;
706   fsp->fd_ptr = 0;
707
708   /* this is for OS/2 EAs - try and say we don't support them */
709   if (strstr(fname,".+,;=[].")) 
710   {
711     unix_ERR_class = ERRDOS;
712     /* OS/2 Workplace shell fix may be main code stream in a later release. */ 
713 #if 1 /* OS2_WPS_FIX - Recent versions of OS/2 need this. */
714     unix_ERR_code = ERRcannotopen;
715 #else /* OS2_WPS_FIX */
716     unix_ERR_code = ERROR_EAS_NOT_SUPPORTED;
717 #endif /* OS2_WPS_FIX */
718
719     return;
720   }
721
722   if ((ofun & 0x3) == 0 && file_existed)  
723   {
724     errno = EEXIST;
725     return;
726   }
727       
728   if (ofun & 0x10)
729     flags2 |= O_CREAT;
730   if ((ofun & 0x3) == 2)
731     flags2 |= O_TRUNC;
732
733   /* note that we ignore the append flag as 
734      append does not mean the same thing under dos and unix */
735
736   switch (share_mode&0xF)
737   {
738     case 1: 
739       flags = O_WRONLY; 
740       break;
741     case 0xF: 
742       fcbopen = True;
743       flags = O_RDWR; 
744       break;
745     case 2: 
746       flags = O_RDWR; 
747       break;
748     default:
749       flags = O_RDONLY;
750       break;
751   }
752
753 #if defined(O_SYNC)
754   if (share_mode&(1<<14)) {
755           flags2 |= O_SYNC;
756   }
757 #endif /* O_SYNC */
758   
759   if (flags != O_RDONLY && file_existed && 
760       (!CAN_WRITE(conn) || IS_DOS_READONLY(dos_mode(conn,fname,&sbuf)))) 
761   {
762     if (!fcbopen) 
763     {
764       errno = EACCES;
765       return;
766     }
767     flags = O_RDONLY;
768   }
769
770   if (deny_mode > DENY_NONE && deny_mode!=DENY_FCB) 
771   {
772     DEBUG(2,("Invalid deny mode %d on file %s\n",deny_mode,fname));
773     errno = EINVAL;
774     return;
775   }
776
777   if (deny_mode == DENY_FCB) deny_mode = DENY_DOS;
778
779   if (lp_share_modes(SNUM(conn))) 
780   {
781     int i;
782     share_mode_entry *old_shares = 0;
783
784     if (file_existed)
785     {
786       dev = sbuf.st_dev;
787       inode = sbuf.st_ino;
788       lock_share_entry(conn, dev, inode, &token);
789       share_locked = True;
790       num_share_modes = get_share_modes(conn, token, dev, inode, &old_shares);
791     }
792
793     /*
794      * Check if the share modes will give us access.
795      */
796
797     if(share_locked && (num_share_modes != 0))
798     {
799       BOOL broke_oplock;
800
801       do
802       {
803
804         broke_oplock = False;
805         for(i = 0; i < num_share_modes; i++)
806         {
807           share_mode_entry *share_entry = &old_shares[i];
808
809           /* 
810            * By observation of NetBench, oplocks are broken *before* share
811            * modes are checked. This allows a file to be closed by the client
812            * if the share mode would deny access and the client has an oplock. 
813            * Check if someone has an oplock on this file. If so we must break 
814            * it before continuing. 
815            */
816           if(share_entry->op_type & (EXCLUSIVE_OPLOCK|BATCH_OPLOCK))
817           {
818
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
822             /* Oplock break.... */
823             unlock_share_entry(conn, dev, inode, token);
824             if(request_oplock_break(share_entry, dev, inode) == False)
825             {
826               free((char *)old_shares);
827
828               DEBUG(0,("open_file_shared: FAILED when breaking oplock (%x) on file %s, \
829 dev = %x, inode = %.0f\n", old_shares[i].op_type, fname, (unsigned int)dev, (double)inode));
830
831               errno = EACCES;
832               unix_ERR_class = ERRDOS;
833               unix_ERR_code = ERRbadshare;
834               return;
835             }
836             lock_share_entry(conn, dev, inode, &token);
837             broke_oplock = True;
838             break;
839           }
840
841           /* someone else has a share lock on it, check to see 
842              if we can too */
843           if(check_share_mode(share_entry, deny_mode, fname, fcbopen, &flags) == False)
844           {
845             free((char *)old_shares);
846             unlock_share_entry(conn, dev, inode, token);
847             errno = EACCES;
848             unix_ERR_class = ERRDOS;
849             unix_ERR_code = ERRbadshare;
850             return;
851           }
852
853         } /* end for */
854
855         if(broke_oplock)
856         {
857           free((char *)old_shares);
858           num_share_modes = get_share_modes(conn, token, dev, inode, &old_shares);
859         }
860       } while(broke_oplock);
861     }
862
863     if(old_shares != 0)
864       free((char *)old_shares);
865   }
866
867   DEBUG(4,("calling open_file with flags=0x%X flags2=0x%X mode=0%o\n",
868            flags,flags2,mode));
869
870   open_file(fsp,conn,fname,flags|(flags2&~(O_TRUNC)),mode,file_existed ? &sbuf : 0);
871   if (!fsp->open && flags==O_RDWR && errno!=ENOENT && fcbopen) 
872   {
873     flags = O_RDONLY;
874     open_file(fsp,conn,fname,flags,mode,file_existed ? &sbuf : 0 );
875   }
876
877   if (fsp->open) 
878   {
879     int open_mode=0;
880
881     if((share_locked == False) && lp_share_modes(SNUM(conn)))
882     {
883       /* We created the file - thus we must now lock the share entry before creating it. */
884       dev = fsp->fd_ptr->dev;
885       inode = fsp->fd_ptr->inode;
886       lock_share_entry(conn, dev, inode, &token);
887       share_locked = True;
888     }
889
890     switch (flags) 
891     {
892       case O_RDONLY:
893         open_mode = 0;
894         break;
895       case O_RDWR:
896         open_mode = 2;
897         break;
898       case O_WRONLY:
899         open_mode = 1;
900         break;
901     }
902
903     fsp->share_mode = (deny_mode<<4) | open_mode;
904
905     if (Access)
906       (*Access) = open_mode;
907
908     if (action) 
909     {
910       if (file_existed && !(flags2 & O_TRUNC)) *action = FILE_WAS_OPENED;
911       if (!file_existed) *action = FILE_WAS_CREATED;
912       if (file_existed && (flags2 & O_TRUNC)) *action = FILE_WAS_OVERWRITTEN;
913     }
914     /* We must create the share mode entry before truncate as
915        truncate can fail due to locking and have to close the
916        file (which expects the share_mode_entry to be there).
917      */
918     if (lp_share_modes(SNUM(conn)))
919     {
920       uint16 port = 0;
921       /* JRA. Currently this only services Exlcusive and batch
922          oplocks (no other opens on this file). This needs to
923          be extended to level II oplocks (multiple reader
924          oplocks). */
925
926       if(oplock_request && (num_share_modes == 0) && lp_oplocks(SNUM(conn)) && 
927               !IS_VETO_OPLOCK_PATH(conn,fname))
928       {
929         fsp->granted_oplock = True;
930         fsp->sent_oplock_break = False;
931         global_oplocks_open++;
932         port = oplock_port;
933
934         DEBUG(5,("open_file_shared: granted oplock (%x) on file %s, \
935 dev = %x, inode = %.0f\n", oplock_request, fname, (unsigned int)dev, (double)inode));
936
937       }
938       else
939       {
940         port = 0;
941         oplock_request = 0;
942       }
943       set_share_mode(token, fsp, port, oplock_request);
944     }
945
946     if ((flags2&O_TRUNC) && file_existed)
947       truncate_unless_locked(fsp,conn,token,&share_locked);
948   }
949
950   if (share_locked && lp_share_modes(SNUM(conn)))
951     unlock_share_entry( conn, dev, inode, token);
952 }
953
954
955
956 /****************************************************************************
957  Open a directory from an NT SMB call.
958 ****************************************************************************/
959 int open_directory(files_struct *fsp,connection_struct *conn,
960                    char *fname, int smb_ofun, int unixmode, int *action)
961 {
962         extern struct current_user current_user;
963         SMB_STRUCT_STAT st;
964
965         if (smb_ofun & 0x10) {
966                 /*
967                  * Create the directory.
968                  */
969
970                 if(dos_mkdir(fname, unixmode) < 0) {
971                         DEBUG(0,("open_directory: unable to create %s. Error was %s\n",
972                                  fname, strerror(errno) ));
973                         return -1;
974                 }
975
976                 *action = FILE_WAS_CREATED;
977         } else {
978                 /*
979                  * Check that it *was* a directory.
980                  */
981
982                 if(dos_stat(fname, &st) < 0) {
983                         DEBUG(0,("open_directory: unable to stat name = %s. Error was %s\n",
984                                  fname, strerror(errno) ));
985                         return -1;
986                 }
987
988                 if(!S_ISDIR(st.st_mode)) {
989                         DEBUG(0,("open_directory: %s is not a directory !\n", fname ));
990                         return -1;
991                 }
992                 *action = FILE_WAS_OPENED;
993         }
994         
995         DEBUG(5,("open_directory: opening directory %s\n",
996                  fname));
997
998         /*
999          * Setup the files_struct for it.
1000          */
1001         
1002         fsp->fd_ptr = NULL;
1003         conn->num_files_open++;
1004         fsp->mode = 0;
1005         GetTimeOfDay(&fsp->open_time);
1006         fsp->vuid = current_user.vuid;
1007         fsp->size = 0;
1008         fsp->pos = -1;
1009         fsp->open = True;
1010         fsp->mmap_ptr = NULL;
1011         fsp->mmap_size = 0;
1012         fsp->can_lock = True;
1013         fsp->can_read = False;
1014         fsp->can_write = False;
1015         fsp->share_mode = 0;
1016         fsp->print_file = False;
1017         fsp->modified = False;
1018         fsp->granted_oplock = False;
1019         fsp->sent_oplock_break = False;
1020         fsp->is_directory = True;
1021         fsp->conn = conn;
1022         /*
1023          * Note that the file name here is the *untranslated* name
1024          * ie. it is still in the DOS codepage sent from the client.
1025          * All use of this filename will pass though the sys_xxxx
1026          * functions which will do the dos_to_unix translation before
1027          * mapping into a UNIX filename. JRA.
1028          */
1029         string_set(&fsp->fsp_name,fname);
1030         fsp->wbmpx_ptr = NULL;
1031
1032         return 0;
1033 }
1034
1035
1036 /*******************************************************************
1037 check if the share mode on a file allows it to be deleted or unlinked
1038 return True if sharing doesn't prevent the operation
1039 ********************************************************************/
1040 BOOL check_file_sharing(connection_struct *conn,char *fname, BOOL rename_op)
1041 {
1042   int i;
1043   int ret = False;
1044   share_mode_entry *old_shares = 0;
1045   int num_share_modes;
1046   SMB_STRUCT_STAT sbuf;
1047   int token;
1048   int pid = getpid();
1049   SMB_DEV_T dev;
1050   SMB_INO_T inode;
1051
1052   if(!lp_share_modes(SNUM(conn)))
1053     return True;
1054
1055   if (dos_stat(fname,&sbuf) == -1) return(True);
1056
1057   dev = sbuf.st_dev;
1058   inode = sbuf.st_ino;
1059
1060   lock_share_entry(conn, dev, inode, &token);
1061   num_share_modes = get_share_modes(conn, token, dev, inode, &old_shares);
1062
1063   /*
1064    * Check if the share modes will give us access.
1065    */
1066
1067   if(num_share_modes != 0)
1068   {
1069     BOOL broke_oplock;
1070
1071     do
1072     {
1073
1074       broke_oplock = False;
1075       for(i = 0; i < num_share_modes; i++)
1076       {
1077         share_mode_entry *share_entry = &old_shares[i];
1078
1079         /* 
1080          * Break oplocks before checking share modes. See comment in
1081          * open_file_shared for details. 
1082          * Check if someone has an oplock on this file. If so we must 
1083          * break it before continuing. 
1084          */
1085         if(share_entry->op_type & BATCH_OPLOCK)
1086         {
1087
1088           /*
1089            * It appears that the NT redirector may have a bug, in that
1090            * it tries to do an SMBmv on a file that it has open with a
1091            * batch oplock, and then fails to respond to the oplock break
1092            * request. This only seems to occur when the client is doing an
1093            * SMBmv to the smbd it is using - thus we try and detect this
1094            * condition by checking if the file being moved is open and oplocked by
1095            * this smbd process, and then not sending the oplock break in this
1096            * special case. If the file was open with a deny mode that 
1097            * prevents the move the SMBmv will fail anyway with a share
1098            * violation error. JRA.
1099            */
1100           if(rename_op && (share_entry->pid == pid))
1101           {
1102
1103             DEBUG(0,("check_file_sharing: NT redirector workaround - rename attempted on \
1104 batch oplocked file %s, dev = %x, inode = %.0f\n", fname, (unsigned int)dev, (double)inode));
1105
1106             /* 
1107              * This next line is a test that allows the deny-mode
1108              * processing to be skipped. This seems to be needed as
1109              * NT insists on the rename succeeding (in Office 9x no less !).
1110              * This should be removed as soon as (a) MS fix the redirector
1111              * bug or (b) NT SMB support in Samba makes NT not issue the
1112              * call (as is my fervent hope). JRA.
1113              */ 
1114             continue;
1115           }
1116           else
1117           {
1118
1119             DEBUG(5,("check_file_sharing: breaking oplock (%x) on file %s, \
1120 dev = %x, inode = %.0f\n", share_entry->op_type, fname, (unsigned int)dev, (double)inode));
1121
1122             /* Oplock break.... */
1123             unlock_share_entry(conn, dev, inode, token);
1124             if(request_oplock_break(share_entry, dev, inode) == False)
1125             {
1126               free((char *)old_shares);
1127
1128               DEBUG(0,("check_file_sharing: FAILED when breaking oplock (%x) on file %s, \
1129 dev = %x, inode = %.0f\n", old_shares[i].op_type, fname, (unsigned int)dev, (double)inode));
1130
1131               return False;
1132             }
1133             lock_share_entry(conn, dev, inode, &token);
1134             broke_oplock = True;
1135             break;
1136           }
1137         }
1138
1139         /* someone else has a share lock on it, check to see 
1140            if we can too */
1141         if ((share_entry->share_mode != DENY_DOS) || (share_entry->pid != pid))
1142           goto free_and_exit;
1143
1144       } /* end for */
1145
1146       if(broke_oplock)
1147       {
1148         free((char *)old_shares);
1149         num_share_modes = get_share_modes(conn, token, dev, inode, &old_shares);
1150       }
1151     } while(broke_oplock);
1152   }
1153
1154   /* XXXX exactly what share mode combinations should be allowed for
1155      deleting/renaming? */
1156   /* If we got here then either there were no share modes or
1157      all share modes were DENY_DOS and the pid == getpid() */
1158   ret = True;
1159
1160 free_and_exit:
1161
1162   unlock_share_entry(conn, dev, inode, token);
1163   if(old_shares != NULL)
1164     free((char *)old_shares);
1165   return(ret);
1166 }
1167
1168