found a much simpler case that kills the posix locking
[kai/samba.git] / source3 / smbd / open.c
1 /* 
2    Unix SMB/Netbios implementation.
3    Version 1.9.
4    file opening and share modes
5    Copyright (C) Andrew Tridgell 1992-1998
6    
7    This program is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 2 of the License, or
10    (at your option) any later version.
11    
12    This program is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16    
17    You should have received a copy of the GNU General Public License
18    along with this program; if not, write to the Free Software
19    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 */
21
22 #include "includes.h"
23
24 extern int DEBUGLEVEL;
25
26 extern pstring sesssetup_user;
27 extern uint16 global_oplock_port;
28 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_open(struct connection_struct *conn, char *fname, 
35                    int flags, mode_t mode)
36 {
37         int fd = conn->vfs_ops.open(dos_to_unix(fname,False),flags,mode);
38
39         /* Fix for files ending in '.' */
40         if((fd == -1) && (errno == ENOENT) &&
41            (strchr(fname,'.')==NULL)) {
42                 pstrcat(fname,".");
43                 fd = conn->vfs_ops.open(dos_to_unix(fname,False),flags,mode);
44         }
45
46         DEBUG(10,("fd_open: name %s, mode = %d, fd = %d. %s\n", fname, (int)mode, fd,
47                 (fd == -1) ? strerror(errno) : "" ));
48
49         return fd;
50 }
51
52 /****************************************************************************
53  Close the file associated with a fsp.
54 ****************************************************************************/
55
56 int fd_close(struct connection_struct *conn, files_struct *fsp)
57 {
58         return fd_close_posix(conn, fsp);
59 }
60
61
62 /****************************************************************************
63  Check a filename for the pipe string.
64 ****************************************************************************/
65
66 static void check_for_pipe(char *fname)
67 {
68         /* special case of pipe opens */
69         char s[10];
70         StrnCpy(s,fname,sizeof(s)-1);
71         strlower(s);
72         if (strstr(s,"pipe/")) {
73                 DEBUG(3,("Rejecting named pipe open for %s\n",fname));
74                 unix_ERR_class = ERRSRV;
75                 unix_ERR_code = ERRaccess;
76         }
77 }
78
79 /****************************************************************************
80  Open a file.
81 ****************************************************************************/
82
83 static BOOL open_file(files_struct *fsp,connection_struct *conn,
84                       char *fname1,int flags,mode_t mode)
85 {
86         extern struct current_user current_user;
87         pstring fname;
88         int accmode = (flags & O_ACCMODE);
89         SMB_STRUCT_STAT sbuf;
90
91         fsp->fd = -1;
92         fsp->oplock_type = NO_OPLOCK;
93         errno = EPERM;
94
95         pstrcpy(fname,fname1);
96
97         /* Check permissions */
98
99         /*
100          * This code was changed after seeing a client open request 
101          * containing the open mode of (DENY_WRITE/read-only) with
102          * the 'create if not exist' bit set. The previous code
103          * would fail to open the file read only on a read-only share
104          * as it was checking the flags parameter  directly against O_RDONLY,
105          * this was failing as the flags parameter was set to O_RDONLY|O_CREAT.
106          * JRA.
107          */
108
109         if (!CAN_WRITE(conn)) {
110                 /* It's a read-only share - fail if we wanted to write. */
111                 if(accmode != O_RDONLY) {
112                         DEBUG(3,("Permission denied opening %s\n",fname));
113                         check_for_pipe(fname);
114                         return False;
115                 } else if(flags & O_CREAT) {
116                         /* We don't want to write - but we must make sure that O_CREAT
117                            doesn't create the file if we have write access into the
118                            directory.
119                         */
120                         flags &= ~O_CREAT;
121                 }
122         }
123
124         /* actually do the open */
125         fsp->fd = fd_open(conn, fname, flags, mode);
126
127         if (fsp->fd == -1)  {
128                 DEBUG(3,("Error opening file %s (%s) (flags=%d)\n",
129                          fname,strerror(errno),flags));
130                 check_for_pipe(fname);
131                 return False;
132         }
133
134         conn->vfs_ops.fstat(fsp->fd, &sbuf);
135
136         /*
137          * POSIX allows read-only opens of directories. We don't
138          * want to do this (we use a different code path for this)
139          * so catch a directory open and return an EISDIR. JRA.
140          */
141
142         if(S_ISDIR(sbuf.st_mode)) {
143                 fd_close(conn, fsp);
144                 errno = EISDIR;
145                 return False;
146         }
147
148         fsp->mode = sbuf.st_mode;
149         fsp->inode = sbuf.st_ino;
150         fsp->dev = sbuf.st_dev;
151         GetTimeOfDay(&fsp->open_time);
152         fsp->vuid = current_user.vuid;
153         fsp->size = 0;
154         fsp->pos = -1;
155         fsp->can_lock = True;
156         fsp->can_read = ((flags & O_WRONLY)==0);
157         fsp->can_write = ((flags & (O_WRONLY|O_RDWR))!=0);
158         fsp->share_mode = 0;
159         fsp->print_file = False;
160         fsp->modified = False;
161         fsp->oplock_type = NO_OPLOCK;
162         fsp->sent_oplock_break = NO_BREAK_SENT;
163         fsp->is_directory = False;
164         fsp->stat_open = False;
165         fsp->directory_delete_on_close = False;
166         fsp->conn = conn;
167         /*
168          * Note that the file name here is the *untranslated* name
169          * ie. it is still in the DOS codepage sent from the client.
170          * All use of this filename will pass though the sys_xxxx
171          * functions which will do the dos_to_unix translation before
172          * mapping into a UNIX filename. JRA.
173          */
174         string_set(&fsp->fsp_name,fname);
175         fsp->wbmpx_ptr = NULL;      
176         fsp->wcp = NULL; /* Write cache pointer. */
177
178         DEBUG(2,("%s opened file %s read=%s write=%s (numopen=%d)\n",
179                  *sesssetup_user ? sesssetup_user : conn->user,fsp->fsp_name,
180                  BOOLSTR(fsp->can_read), BOOLSTR(fsp->can_write),
181                  conn->num_files_open + 1));
182
183         return True;
184 }
185
186 /****************************************************************************
187   C. Hoch 11/22/95
188   Helper for open_file_shared. 
189   Truncate a file after checking locking; close file if locked.
190   **************************************************************************/
191
192 static int truncate_unless_locked(struct connection_struct *conn, files_struct *fsp)
193 {
194         SMB_BIG_UINT mask = (SMB_BIG_UINT)-1;
195
196         if (!fsp->can_write)
197                 return -1;
198
199         if (is_locked(fsp,fsp->conn,mask,0,WRITE_LOCK)){
200                 errno = EACCES;
201                 unix_ERR_class = ERRDOS;
202                 unix_ERR_code = ERRlock;
203                 return -1;
204         } else {
205                 return conn->vfs_ops.ftruncate(fsp->fd,0); 
206         }
207 }
208
209 /*******************************************************************
210 return True if the filename is one of the special executable types
211 ********************************************************************/
212 static BOOL is_executable(const char *fname)
213 {
214         if ((fname = strrchr(fname,'.'))) {
215                 if (strequal(fname,".com") ||
216                     strequal(fname,".dll") ||
217                     strequal(fname,".exe") ||
218                     strequal(fname,".sym")) {
219                         return True;
220                 }
221         }
222         return False;
223 }
224
225 enum {AFAIL,AREAD,AWRITE,AALL};
226
227 /*******************************************************************
228 reproduce the share mode access table
229 this is horrendoously complex, and really can't be justified on any
230 rational grounds except that this is _exactly_ what NT does. See
231 the DENY1 and DENY2 tests in smbtorture for a comprehensive set of
232 test routines.
233 ********************************************************************/
234 static int access_table(int new_deny,int old_deny,int old_mode,
235                         BOOL same_pid, BOOL isexe)
236 {
237           if (new_deny == DENY_ALL || old_deny == DENY_ALL) return(AFAIL);
238
239           if (same_pid) {
240                   if (isexe && old_mode == DOS_OPEN_RDONLY && 
241                       old_deny == DENY_DOS && new_deny == DENY_READ) {
242                           return AFAIL;
243                   }
244                   if (!isexe && old_mode == DOS_OPEN_RDONLY && 
245                       old_deny == DENY_DOS && new_deny == DENY_DOS) {
246                           return AREAD;
247                   }
248                   if (new_deny == DENY_FCB && old_deny == DENY_DOS) {
249                           if (isexe) return AFAIL;
250                           if (old_mode == DOS_OPEN_RDONLY) return AFAIL;
251                           return AALL;
252                   }
253                   if (old_mode == DOS_OPEN_RDONLY && old_deny == DENY_DOS) {
254                           if (new_deny == DENY_FCB || new_deny == DENY_READ) {
255                                   if (isexe) return AREAD;
256                                   return AFAIL;
257                           }
258                   }
259                   if (old_deny == DENY_FCB) {
260                           if (new_deny == DENY_DOS || new_deny == DENY_FCB) return AALL;
261                           return AFAIL;
262                   }
263           }
264
265           if (old_deny == DENY_DOS || new_deny == DENY_DOS || 
266               old_deny == DENY_FCB || new_deny == DENY_FCB) {
267                   if (isexe) {
268                           if (old_deny == DENY_FCB || new_deny == DENY_FCB) {
269                                   return AFAIL;
270                           }
271                           if (old_deny == DENY_DOS) {
272                                   if (new_deny == DENY_READ && 
273                                       (old_mode == DOS_OPEN_RDONLY || 
274                                        old_mode == DOS_OPEN_RDWR)) {
275                                           return AFAIL;
276                                   }
277                                   if (new_deny == DENY_WRITE && 
278                                       (old_mode == DOS_OPEN_WRONLY || 
279                                        old_mode == DOS_OPEN_RDWR)) {
280                                           return AFAIL;
281                                   }
282                                   return AALL;
283                           }
284                           if (old_deny == DENY_NONE) return AALL;
285                           if (old_deny == DENY_READ) return AWRITE;
286                           if (old_deny == DENY_WRITE) return AREAD;
287                   }
288                   /* it isn't a exe, dll, sym or com file */
289                   if (old_deny == new_deny && same_pid)
290                           return(AALL);    
291
292                   if (old_deny == DENY_READ || new_deny == DENY_READ) return AFAIL;
293                   if (old_mode == DOS_OPEN_RDONLY) return(AREAD);
294                   
295                   return(AFAIL);
296           }
297           
298           switch (new_deny) 
299                   {
300                   case DENY_WRITE:
301                           if (old_deny==DENY_WRITE && old_mode==DOS_OPEN_RDONLY) return(AREAD);
302                           if (old_deny==DENY_READ && old_mode==DOS_OPEN_RDONLY) return(AWRITE);
303                           if (old_deny==DENY_NONE && old_mode==DOS_OPEN_RDONLY) return(AALL);
304                           return(AFAIL);
305                   case DENY_READ:
306                           if (old_deny==DENY_WRITE && old_mode==DOS_OPEN_WRONLY) return(AREAD);
307                           if (old_deny==DENY_READ && old_mode==DOS_OPEN_WRONLY) return(AWRITE);
308                           if (old_deny==DENY_NONE && old_mode==DOS_OPEN_WRONLY) return(AALL);
309                           return(AFAIL);
310                   case DENY_NONE:
311                           if (old_deny==DENY_WRITE) return(AREAD);
312                           if (old_deny==DENY_READ) return(AWRITE);
313                           if (old_deny==DENY_NONE) return(AALL);
314                           return(AFAIL);      
315                   }
316           return(AFAIL);      
317 }
318
319
320 /****************************************************************************
321 check if we can open a file with a share mode
322 ****************************************************************************/
323
324 static int check_share_mode( share_mode_entry *share, int deny_mode, 
325                              const char *fname, BOOL fcbopen, int *flags)
326 {
327         int old_open_mode = GET_OPEN_MODE(share->share_mode);
328         int old_deny_mode = GET_DENY_MODE(share->share_mode);
329
330         /*
331          * Don't allow any open once the delete on close flag has been
332          * set.
333          */
334
335         if(GET_DELETE_ON_CLOSE_FLAG(share->share_mode)) {
336                 DEBUG(5,("check_share_mode: Failing open on file %s as delete on close flag is set.\n",
337                         fname ));
338                 unix_ERR_class = ERRDOS;
339                 unix_ERR_code = ERRnoaccess;
340                 return False;
341         }
342
343         {
344                 int access_allowed = access_table(deny_mode,old_deny_mode,old_open_mode,
345                                                                                 (share->pid == sys_getpid()),is_executable(fname));
346
347                 if ((access_allowed == AFAIL) ||
348                         (!fcbopen && (access_allowed == AREAD && *flags == O_RDWR)) ||
349                         (access_allowed == AREAD && *flags != O_RDONLY) ||
350                         (access_allowed == AWRITE && *flags != O_WRONLY)) {
351
352                         DEBUG(2,("Share violation on file (%d,%d,%d,%d,%s,fcbopen = %d, flags = %d) = %d\n",
353                                 deny_mode,old_deny_mode,old_open_mode,
354                                 (int)share->pid,fname, fcbopen, *flags, access_allowed));
355
356                         unix_ERR_class = ERRDOS;
357                         unix_ERR_code = ERRbadshare;
358
359                         return False;
360                 }
361
362                 if (access_allowed == AREAD)
363                         *flags = O_RDONLY;
364
365                 if (access_allowed == AWRITE)
366                         *flags = O_WRONLY;
367
368         }
369
370         return True;
371 }
372
373 /****************************************************************************
374  Deal with open deny mode and oplock break processing.
375  Invarient: Share mode must be locked on entry and exit.
376  Returns -1 on error, or number of share modes on success (may be zero).
377 ****************************************************************************/
378
379 static int open_mode_check(connection_struct *conn, const char *fname, SMB_DEV_T dev,
380                                                         SMB_INO_T inode, int share_mode, int *p_flags, int *p_oplock_request,
381                                                         BOOL *p_all_current_opens_are_level_II)
382 {
383   int i;
384   int num_share_modes;
385   int oplock_contention_count = 0;
386   share_mode_entry *old_shares = 0;
387   BOOL fcbopen = False;
388   int deny_mode = GET_DENY_MODE(share_mode);
389   BOOL broke_oplock;    
390
391   if(GET_OPEN_MODE(share_mode) == DOS_OPEN_FCB)
392     fcbopen = True;
393
394   num_share_modes = get_share_modes(conn, dev, inode, &old_shares);
395
396   if(num_share_modes == 0)
397     return 0;
398
399   /*
400    * Check if the share modes will give us access.
401    */
402
403   do {
404
405     broke_oplock = False;
406     *p_all_current_opens_are_level_II = True;
407
408     for(i = 0; i < num_share_modes; i++) {
409       share_mode_entry *share_entry = &old_shares[i];
410
411       /* 
412        * By observation of NetBench, oplocks are broken *before* share
413        * modes are checked. This allows a file to be closed by the client
414        * if the share mode would deny access and the client has an oplock. 
415        * Check if someone has an oplock on this file. If so we must break 
416        * it before continuing. 
417        */
418
419       if((*p_oplock_request && EXCLUSIVE_OPLOCK_TYPE(share_entry->op_type)) ||
420          (!*p_oplock_request && (share_entry->op_type != NO_OPLOCK))) {
421
422         BOOL opb_ret;
423
424         DEBUG(5,("open_mode_check: breaking oplock (%x) on file %s, \
425 dev = %x, inode = %.0f\n", share_entry->op_type, fname, (unsigned int)dev, (double)inode));
426
427         /* Oplock break - unlock to request it. */
428         unlock_share_entry(conn, dev, inode);
429
430         opb_ret = request_oplock_break(share_entry, dev, inode);
431
432         /* Now relock. */
433         lock_share_entry(conn, dev, inode);
434
435         if(opb_ret == False) {
436           free((char *)old_shares);
437           DEBUG(0,("open_mode_check: FAILED when breaking oplock (%x) on file %s, \
438 dev = %x, inode = %.0f\n", old_shares[i].op_type, fname, (unsigned int)dev, (double)inode));
439           errno = EACCES;
440           unix_ERR_class = ERRDOS;
441           unix_ERR_code = ERRbadshare;
442           return -1;
443         }
444
445         broke_oplock = True;
446         *p_all_current_opens_are_level_II = False;
447         break;
448
449       } else if (!LEVEL_II_OPLOCK_TYPE(share_entry->op_type)) {
450         *p_all_current_opens_are_level_II = False;
451       }
452
453       /* someone else has a share lock on it, check to see 
454          if we can too */
455
456       if(check_share_mode(share_entry, deny_mode, fname, fcbopen, p_flags) == False) {
457         free((char *)old_shares);
458         errno = EACCES;
459         return -1;
460       }
461
462     } /* end for */
463
464     if(broke_oplock) {
465       free((char *)old_shares);
466       num_share_modes = get_share_modes(conn, dev, inode, &old_shares);
467       oplock_contention_count++;
468     }
469   } while(broke_oplock);
470
471   if(old_shares != 0)
472     free((char *)old_shares);
473
474   /*
475    * Refuse to grant an oplock in case the contention limit is
476    * reached when going through the lock list multiple times.
477    */
478
479   if(oplock_contention_count >= lp_oplock_contention_limit(SNUM(conn))) {
480     *p_oplock_request = 0;
481     DEBUG(4,("open_mode_check: oplock contention = %d. Not granting oplock.\n",
482           oplock_contention_count ));
483   }
484
485   return num_share_modes;
486 }
487
488 /****************************************************************************
489  Open a file with a share mode.
490 ****************************************************************************/
491
492 files_struct *open_file_shared(connection_struct *conn,char *fname,int share_mode,int ofun,
493                       mode_t mode,int oplock_request, int *Access,int *action)
494 {
495         int flags=0;
496         int flags2=0;
497         int deny_mode = GET_DENY_MODE(share_mode);
498         BOOL allow_share_delete = GET_ALLOW_SHARE_DELETE(share_mode);
499         SMB_STRUCT_STAT sbuf;
500         BOOL file_existed = vfs_file_exist(conn, fname, &sbuf);
501         BOOL fcbopen = False;
502         SMB_DEV_T dev = 0;
503         SMB_INO_T inode = 0;
504         int num_share_modes = 0;
505         BOOL all_current_opens_are_level_II = False;
506         BOOL fsp_open = False;
507         files_struct *fsp = NULL;
508         int open_mode=0;
509         uint16 port = 0;
510
511         if (conn->printer) {
512                 /* printers are handled completely differently. Most of the passed parameters are
513                         ignored */
514                 *Access = DOS_OPEN_WRONLY;
515                 *action = FILE_WAS_CREATED;
516                 return print_fsp_open(conn, fname);
517         }
518
519         fsp = file_new();
520         if(!fsp)
521                 return NULL;
522
523         fsp->fd = -1;
524
525         DEBUG(10,("open_file_shared: fname = %s, share_mode = %x, ofun = %x, mode = %o, oplock request = %d\n",
526                 fname, share_mode, ofun, (int)mode,  oplock_request ));
527
528         if (!check_name(fname,conn)) {
529                 file_free(fsp);
530                 return NULL;
531         } 
532
533         /* ignore any oplock requests if oplocks are disabled */
534         if (!lp_oplocks(SNUM(conn)) || global_client_failed_oplock_break) {
535                 oplock_request = 0;
536         }
537
538         /* this is for OS/2 EAs - try and say we don't support them */
539         if (strstr(fname,".+,;=[].")) {
540                 unix_ERR_class = ERRDOS;
541                 /* OS/2 Workplace shell fix may be main code stream in a later release. */ 
542 #if 1 /* OS2_WPS_FIX - Recent versions of OS/2 need this. */
543                 unix_ERR_code = ERRcannotopen;
544 #else /* OS2_WPS_FIX */
545                 unix_ERR_code = ERROR_EAS_NOT_SUPPORTED;
546 #endif /* OS2_WPS_FIX */
547
548                 DEBUG(5,("open_file_shared: OS/2 EA's are not supported.\n"));
549                 file_free(fsp);
550                 return NULL;
551         }
552
553         if ((GET_FILE_OPEN_DISPOSITION(ofun) == FILE_EXISTS_FAIL) && file_existed)  {
554                 DEBUG(5,("open_file_shared: create new requested for file %s and file already exists.\n",
555                         fname ));
556                 file_free(fsp);
557                 errno = EEXIST;
558                 return NULL;
559         }
560       
561         if (GET_FILE_CREATE_DISPOSITION(ofun) == FILE_CREATE_IF_NOT_EXIST)
562                 flags2 |= O_CREAT;
563
564         if (GET_FILE_OPEN_DISPOSITION(ofun) == FILE_EXISTS_TRUNCATE)
565                 flags2 |= O_TRUNC;
566
567         if (GET_FILE_OPEN_DISPOSITION(ofun) == FILE_EXISTS_FAIL)
568                 flags2 |= O_EXCL;
569
570         /* note that we ignore the append flag as 
571                 append does not mean the same thing under dos and unix */
572
573         switch (GET_OPEN_MODE(share_mode)) {
574                 case DOS_OPEN_WRONLY: 
575                         flags = O_WRONLY; 
576                         break;
577                 case DOS_OPEN_FCB: 
578                         fcbopen = True;
579                         flags = O_RDWR; 
580                         break;
581                 case DOS_OPEN_RDWR: 
582                         flags = O_RDWR; 
583                         break;
584                 default:
585                         flags = O_RDONLY;
586                         break;
587         }
588
589 #if defined(O_SYNC)
590         if (GET_FILE_SYNC_OPENMODE(share_mode)) {
591                 flags2 |= O_SYNC;
592         }
593 #endif /* O_SYNC */
594   
595         if (flags != O_RDONLY && file_existed && 
596                         (!CAN_WRITE(conn) || IS_DOS_READONLY(dos_mode(conn,fname,&sbuf)))) {
597                 if (!fcbopen) {
598                         DEBUG(5,("open_file_shared: read/write access requested for file %s on read only %s\n",
599                                 fname, !CAN_WRITE(conn) ? "share" : "file" ));
600                         file_free(fsp);
601                         errno = EACCES;
602                         return NULL;
603                 }
604                 flags = O_RDONLY;
605         }
606
607         if (deny_mode > DENY_NONE && deny_mode!=DENY_FCB) {
608                 DEBUG(2,("Invalid deny mode %d on file %s\n",deny_mode,fname));
609                 file_free(fsp);
610                 errno = EINVAL;
611                 return NULL;
612         }
613
614         if (file_existed) {
615                 dev = sbuf.st_dev;
616                 inode = sbuf.st_ino;
617
618                 lock_share_entry(conn, dev, inode);
619
620                 num_share_modes = open_mode_check(conn, fname, dev, inode, share_mode,
621                                                                 &flags, &oplock_request, &all_current_opens_are_level_II);
622                 if(num_share_modes == -1) {
623                         unlock_share_entry(conn, dev, inode);
624                         file_free(fsp);
625                         return NULL;
626                 }
627
628                 /*
629                  * We exit this block with the share entry *locked*.....
630                  */
631         }
632
633         DEBUG(4,("calling open_file with flags=0x%X flags2=0x%X mode=0%o\n",
634                         flags,flags2,(int)mode));
635
636         fsp_open = open_file(fsp,conn,fname,flags|(flags2&~(O_TRUNC)),mode);
637
638         if (!fsp_open && (flags == O_RDWR) && (errno != ENOENT) && fcbopen) {
639                 if((fsp_open = open_file(fsp,conn,fname,O_RDONLY,mode)) == True)
640                         flags = O_RDONLY;
641         }
642
643         if (!fsp_open) {
644                 if(file_existed)
645                         unlock_share_entry(conn, dev, inode);
646                 file_free(fsp);
647                 return NULL;
648         }
649
650         /*
651          * Deal with the race condition where two smbd's detect the file doesn't
652          * exist and do the create at the same time. One of them will win and
653          * set a share mode, the other (ie. this one) should check if the
654          * requested share mode for this create is allowed.
655          */
656
657         if (!file_existed) { 
658
659                 lock_share_entry_fsp(fsp);
660
661                 num_share_modes = open_mode_check(conn, fname, dev, inode, share_mode,
662                                                                 &flags, &oplock_request, &all_current_opens_are_level_II);
663
664                 if(num_share_modes == -1) {
665                         unlock_share_entry_fsp(fsp);
666                         fd_close(conn,fsp);
667                         file_free(fsp);
668                         return NULL;
669                 }
670
671                 /*
672                  * We exit this block with the share entry *locked*.....
673                  */
674         }
675
676         /*
677          * At this point onwards, we can guarentee that the share entry
678          * is locked, whether we created the file or not, and that the
679          * deny mode is compatible with all current opens.
680          */
681
682         /*
683          * If requested, truncate the file.
684          */
685
686         if ((flags2&O_TRUNC) && (truncate_unless_locked(conn,fsp) == -1)) {
687                 unlock_share_entry_fsp(fsp);
688                 fd_close(conn,fsp);
689                 file_free(fsp);
690                 return NULL;
691         }
692
693         switch (flags) {
694                 case O_RDONLY:
695                         open_mode = DOS_OPEN_RDONLY;
696                         break;
697                 case O_RDWR:
698                         open_mode = DOS_OPEN_RDWR;
699                         break;
700                 case O_WRONLY:
701                         open_mode = DOS_OPEN_WRONLY;
702                         break;
703         }
704
705         fsp->share_mode = SET_DENY_MODE(deny_mode) | 
706                                                 SET_OPEN_MODE(open_mode) | 
707                                                 SET_ALLOW_SHARE_DELETE(allow_share_delete);
708
709         if (Access)
710                 (*Access) = open_mode;
711
712         if (action) {
713                 if (file_existed && !(flags2 & O_TRUNC))
714                         *action = FILE_WAS_OPENED;
715                 if (!file_existed)
716                         *action = FILE_WAS_CREATED;
717                 if (file_existed && (flags2 & O_TRUNC))
718                         *action = FILE_WAS_OVERWRITTEN;
719         }
720
721         /* 
722          * Setup the oplock info in both the shared memory and
723          * file structs.
724          */
725
726         if(oplock_request && (num_share_modes == 0) && 
727                         !IS_VETO_OPLOCK_PATH(conn,fname) && set_file_oplock(fsp, oplock_request) ) {
728                 port = global_oplock_port;
729         } else if (oplock_request && all_current_opens_are_level_II) {
730                 port = global_oplock_port;
731                 oplock_request = LEVEL_II_OPLOCK;
732                 set_file_oplock(fsp, oplock_request);
733         } else {
734                 port = 0;
735                 oplock_request = 0;
736         }
737
738         set_share_mode(fsp, port, oplock_request);
739
740         unlock_share_entry_fsp(fsp);
741
742         conn->num_files_open++;
743
744         return fsp;
745 }
746
747 /****************************************************************************
748  Open a file for permissions read only. Return a pseudo file entry
749  with the 'stat_open' flag set 
750 ****************************************************************************/
751
752 files_struct *open_file_stat(connection_struct *conn,
753                    char *fname, int smb_ofun, SMB_STRUCT_STAT *pst, int *action)
754 {
755         extern struct current_user current_user;
756         files_struct *fsp = file_new();
757
758         if(!fsp)
759                 return NULL;
760
761         if(conn->vfs_ops.stat(dos_to_unix(fname, False), pst) < 0) {
762                 DEBUG(0,("open_file_stat: unable to stat name = %s. Error was %s\n",
763                          fname, strerror(errno) ));
764                 file_free(fsp);
765                 return NULL;
766         }
767
768         if(S_ISDIR(pst->st_mode)) {
769                 DEBUG(0,("open_file_stat: %s is a directory !\n", fname ));
770                 file_free(fsp);
771                 return NULL;
772         }
773
774         *action = FILE_WAS_OPENED;
775         
776         DEBUG(5,("open_file_stat: opening file %s as a stat entry\n", fname));
777
778         /*
779          * Setup the files_struct for it.
780          */
781         
782         fsp->fd = -1;
783         fsp->mode = 0;
784         GetTimeOfDay(&fsp->open_time);
785         fsp->vuid = current_user.vuid;
786         fsp->size = 0;
787         fsp->pos = -1;
788         fsp->can_lock = False;
789         fsp->can_read = False;
790         fsp->can_write = False;
791         fsp->share_mode = 0;
792         fsp->print_file = False;
793         fsp->modified = False;
794         fsp->oplock_type = NO_OPLOCK;
795         fsp->sent_oplock_break = NO_BREAK_SENT;
796         fsp->is_directory = False;
797         fsp->stat_open = True;
798         fsp->directory_delete_on_close = False;
799         fsp->conn = conn;
800         /*
801          * Note that the file name here is the *untranslated* name
802          * ie. it is still in the DOS codepage sent from the client.
803          * All use of this filename will pass though the sys_xxxx
804          * functions which will do the dos_to_unix translation before
805          * mapping into a UNIX filename. JRA.
806          */
807         string_set(&fsp->fsp_name,fname);
808         fsp->wbmpx_ptr = NULL;
809     fsp->wcp = NULL; /* Write cache pointer. */
810
811         conn->num_files_open++;
812
813         return fsp;
814 }
815
816 /****************************************************************************
817  Open a directory from an NT SMB call.
818 ****************************************************************************/
819
820 files_struct *open_directory(connection_struct *conn,
821                    char *fname, int smb_ofun, mode_t unixmode, int *action)
822 {
823         extern struct current_user current_user;
824         SMB_STRUCT_STAT st;
825         BOOL got_stat = False;
826         files_struct *fsp = file_new();
827
828         if(!fsp)
829                 return NULL;
830
831         if(conn->vfs_ops.stat(dos_to_unix(fname, False), &st) == 0) {
832                 got_stat = True;
833         }
834
835         if (got_stat && (GET_FILE_OPEN_DISPOSITION(smb_ofun) == FILE_EXISTS_FAIL)) {
836                 file_free(fsp);
837                 errno = EEXIST; /* Setup so correct error is returned to client. */
838                 return NULL;
839         }
840
841         if (GET_FILE_CREATE_DISPOSITION(smb_ofun) == FILE_CREATE_IF_NOT_EXIST) {
842
843                 if (got_stat) {
844
845                         if(!S_ISDIR(st.st_mode)) {
846                                 DEBUG(0,("open_directory: %s is not a directory !\n", fname ));
847                                 file_free(fsp);
848                                 errno = EACCES;
849                                 return NULL;
850                         }
851                         *action = FILE_WAS_OPENED;
852
853                 } else {
854
855                         /*
856                          * Try and create the directory.
857                          */
858
859                         if(!CAN_WRITE(conn)) {
860                                 DEBUG(2,("open_directory: failing create on read-only share\n"));
861                                 file_free(fsp);
862                                 errno = EACCES;
863                                 return NULL;
864                         }
865
866                         if(conn->vfs_ops.mkdir(dos_to_unix(fname, False), 
867                                                unix_mode(conn,aDIR, fname)) < 0) {
868                                 DEBUG(0,("open_directory: unable to create %s. Error was %s\n",
869                                          fname, strerror(errno) ));
870                                 file_free(fsp);
871                                 return NULL;
872                         }
873                         *action = FILE_WAS_CREATED;
874
875                 }
876         } else {
877
878                 /*
879                  * Don't create - just check that it *was* a directory.
880                  */
881
882                 if(!got_stat) {
883                         DEBUG(0,("open_directory: unable to stat name = %s. Error was %s\n",
884                                  fname, strerror(errno) ));
885                         file_free(fsp);
886                         return NULL;
887                 }
888
889                 if(!S_ISDIR(st.st_mode)) {
890                         DEBUG(0,("open_directory: %s is not a directory !\n", fname ));
891                         file_free(fsp);
892                         return NULL;
893                 }
894
895                 *action = FILE_WAS_OPENED;
896         }
897         
898         DEBUG(5,("open_directory: opening directory %s\n",
899                  fname));
900
901         /*
902          * Setup the files_struct for it.
903          */
904         
905         fsp->fd = -1;
906         fsp->mode = 0;
907         GetTimeOfDay(&fsp->open_time);
908         fsp->vuid = current_user.vuid;
909         fsp->size = 0;
910         fsp->pos = -1;
911         fsp->can_lock = True;
912         fsp->can_read = False;
913         fsp->can_write = False;
914         fsp->share_mode = 0;
915         fsp->print_file = False;
916         fsp->modified = False;
917         fsp->oplock_type = NO_OPLOCK;
918         fsp->sent_oplock_break = NO_BREAK_SENT;
919         fsp->is_directory = True;
920         fsp->directory_delete_on_close = False;
921         fsp->conn = conn;
922         /*
923          * Note that the file name here is the *untranslated* name
924          * ie. it is still in the DOS codepage sent from the client.
925          * All use of this filename will pass though the sys_xxxx
926          * functions which will do the dos_to_unix translation before
927          * mapping into a UNIX filename. JRA.
928          */
929         string_set(&fsp->fsp_name,fname);
930         fsp->wbmpx_ptr = NULL;
931
932         conn->num_files_open++;
933
934         return fsp;
935 }
936
937 /*******************************************************************
938  Check if the share mode on a file allows it to be deleted or unlinked.
939  Return True if sharing doesn't prevent the operation.
940 ********************************************************************/
941
942 BOOL check_file_sharing(connection_struct *conn,char *fname, BOOL rename_op)
943 {
944   int i;
945   int ret = False;
946   share_mode_entry *old_shares = 0;
947   int num_share_modes;
948   SMB_STRUCT_STAT sbuf;
949   pid_t pid = sys_getpid();
950   SMB_DEV_T dev;
951   SMB_INO_T inode;
952
953   if (conn->vfs_ops.stat(dos_to_unix(fname,False),&sbuf) == -1)
954     return(True);
955
956   dev = sbuf.st_dev;
957   inode = sbuf.st_ino;
958
959   lock_share_entry(conn, dev, inode);
960   num_share_modes = get_share_modes(conn, dev, inode, &old_shares);
961
962   /*
963    * Check if the share modes will give us access.
964    */
965
966   if(num_share_modes != 0)
967   {
968     BOOL broke_oplock;
969
970     do
971     {
972
973       broke_oplock = False;
974       for(i = 0; i < num_share_modes; i++)
975       {
976         share_mode_entry *share_entry = &old_shares[i];
977
978         /* 
979          * Break oplocks before checking share modes. See comment in
980          * open_file_shared for details. 
981          * Check if someone has an oplock on this file. If so we must 
982          * break it before continuing. 
983          */
984         if(BATCH_OPLOCK_TYPE(share_entry->op_type))
985         {
986
987 #if 0
988
989 /* JRA. Try removing this code to see if the new oplock changes
990    fix the problem. I'm dubious, but Andrew is recommending we
991    try this....
992 */
993
994           /*
995            * It appears that the NT redirector may have a bug, in that
996            * it tries to do an SMBmv on a file that it has open with a
997            * batch oplock, and then fails to respond to the oplock break
998            * request. This only seems to occur when the client is doing an
999            * SMBmv to the smbd it is using - thus we try and detect this
1000            * condition by checking if the file being moved is open and oplocked by
1001            * this smbd process, and then not sending the oplock break in this
1002            * special case. If the file was open with a deny mode that 
1003            * prevents the move the SMBmv will fail anyway with a share
1004            * violation error. JRA.
1005            */
1006           if(rename_op && (share_entry->pid == pid))
1007           {
1008
1009             DEBUG(0,("check_file_sharing: NT redirector workaround - rename attempted on \
1010 batch oplocked file %s, dev = %x, inode = %.0f\n", fname, (unsigned int)dev, (double)inode));
1011
1012             /* 
1013              * This next line is a test that allows the deny-mode
1014              * processing to be skipped. This seems to be needed as
1015              * NT insists on the rename succeeding (in Office 9x no less !).
1016              * This should be removed as soon as (a) MS fix the redirector
1017              * bug or (b) NT SMB support in Samba makes NT not issue the
1018              * call (as is my fervent hope). JRA.
1019              */ 
1020             continue;
1021           }
1022           else
1023 #endif /* 0 */
1024           {
1025
1026             DEBUG(5,("check_file_sharing: breaking oplock (%x) on file %s, \
1027 dev = %x, inode = %.0f\n", share_entry->op_type, fname, (unsigned int)dev, (double)inode));
1028
1029             /* Oplock break.... */
1030             unlock_share_entry(conn, dev, inode);
1031             if(request_oplock_break(share_entry, dev, inode) == False)
1032             {
1033               free((char *)old_shares);
1034
1035               DEBUG(0,("check_file_sharing: FAILED when breaking oplock (%x) on file %s, \
1036 dev = %x, inode = %.0f\n", old_shares[i].op_type, fname, (unsigned int)dev, (double)inode));
1037
1038               return False;
1039             }
1040             lock_share_entry(conn, dev, inode);
1041             broke_oplock = True;
1042             break;
1043           }
1044         }
1045
1046         /* 
1047          * If this is a delete request and ALLOW_SHARE_DELETE is set then allow 
1048          * this to proceed. This takes precedence over share modes.
1049          */
1050
1051         if(!rename_op && GET_ALLOW_SHARE_DELETE(share_entry->share_mode))
1052           continue;
1053
1054         /* 
1055          * Someone else has a share lock on it, check to see 
1056          * if we can too.
1057          */
1058
1059         if ((GET_DENY_MODE(share_entry->share_mode) != DENY_DOS) || 
1060             (share_entry->pid != pid))
1061           goto free_and_exit;
1062
1063       } /* end for */
1064
1065       if(broke_oplock)
1066       {
1067         free((char *)old_shares);
1068         num_share_modes = get_share_modes(conn, dev, inode, &old_shares);
1069       }
1070     } while(broke_oplock);
1071   }
1072
1073   /* XXXX exactly what share mode combinations should be allowed for
1074      deleting/renaming? */
1075   /* 
1076    * If we got here then either there were no share modes or
1077    * all share modes were DENY_DOS and the pid == getpid() or
1078    * delete access was requested and all share modes had the
1079    * ALLOW_SHARE_DELETE bit set (takes precedence over other
1080    * share modes).
1081    */
1082
1083   ret = True;
1084
1085 free_and_exit:
1086
1087   unlock_share_entry(conn, dev, inode);
1088   if(old_shares != NULL)
1089     free((char *)old_shares);
1090   return(ret);
1091 }