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