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