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