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