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