Fix from matt.zinkevicius@hp.com to stop files being created on read-only
[kai/samba.git] / source / smbd / open.c
1 /* 
2    Unix SMB/CIFS implementation.
3    file opening and share modes
4    Copyright (C) Andrew Tridgell 1992-1998
5    Copyright (C) Jeremy Allison 2001
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 userdom_struct current_user_info;
25 extern uint16 global_oplock_port;
26 extern BOOL global_client_failed_oplock_break;
27
28 /****************************************************************************
29  fd support routines - attempt to do a dos_open.
30 ****************************************************************************/
31
32 static int fd_open(struct connection_struct *conn, char *fname, 
33                    int flags, mode_t mode)
34 {
35         int fd;
36 #ifdef O_NOFOLLOW
37         if (!lp_symlinks(SNUM(conn)))
38                 flags |= O_NOFOLLOW;
39 #endif
40
41         fd = SMB_VFS_OPEN(conn,fname,flags,mode);
42
43         /* Fix for files ending in '.' */
44         if((fd == -1) && (errno == ENOENT) &&
45            (strchr_m(fname,'.')==NULL)) {
46                 pstrcat(fname,".");
47                 fd = SMB_VFS_OPEN(conn,fname,flags,mode);
48         }
49
50         DEBUG(10,("fd_open: name %s, flags = 0%o mode = 0%o, fd = %d. %s\n", fname,
51                 flags, (int)mode, fd, (fd == -1) ? strerror(errno) : "" ));
52
53         return fd;
54 }
55
56 /****************************************************************************
57  Close the file associated with a fsp.
58 ****************************************************************************/
59
60 int fd_close(struct connection_struct *conn, files_struct *fsp)
61 {
62         if (fsp->fd == -1)
63                 return 0; /* what we used to call a stat open. */
64         return fd_close_posix(conn, fsp);
65 }
66
67
68 /****************************************************************************
69  Check a filename for the pipe string.
70 ****************************************************************************/
71
72 static void check_for_pipe(char *fname)
73 {
74         /* special case of pipe opens */
75         char s[10];
76         StrnCpy(s,fname,sizeof(s)-1);
77         strlower_m(s);
78         if (strstr(s,"pipe/")) {
79                 DEBUG(3,("Rejecting named pipe open for %s\n",fname));
80                 unix_ERR_class = ERRSRV;
81                 unix_ERR_code = ERRaccess;
82                 unix_ERR_ntstatus = NT_STATUS_ACCESS_DENIED;
83         }
84 }
85
86 /****************************************************************************
87  Open a file.
88 ****************************************************************************/
89
90 static BOOL open_file(files_struct *fsp,connection_struct *conn,
91                       const char *fname1,SMB_STRUCT_STAT *psbuf,int flags,mode_t mode, uint32 desired_access)
92 {
93         extern struct current_user current_user;
94         pstring fname;
95         int accmode = (flags & O_ACCMODE);
96         int local_flags = flags;
97
98         fsp->fd = -1;
99         fsp->oplock_type = NO_OPLOCK;
100         errno = EPERM;
101
102         pstrcpy(fname,fname1);
103
104         /* Check permissions */
105
106         /*
107          * This code was changed after seeing a client open request 
108          * containing the open mode of (DENY_WRITE/read-only) with
109          * the 'create if not exist' bit set. The previous code
110          * would fail to open the file read only on a read-only share
111          * as it was checking the flags parameter  directly against O_RDONLY,
112          * this was failing as the flags parameter was set to O_RDONLY|O_CREAT.
113          * JRA.
114          */
115
116         if (!CAN_WRITE(conn)) {
117                 /* It's a read-only share - fail if we wanted to write. */
118                 if(accmode != O_RDONLY) {
119                         DEBUG(3,("Permission denied opening %s\n",fname));
120                         check_for_pipe(fname);
121                         return False;
122                 } else if(flags & O_CREAT) {
123                         /* We don't want to write - but we must make sure that O_CREAT
124                            doesn't create the file if we have write access into the
125                            directory.
126                         */
127                         flags &= ~O_CREAT;
128                         local_flags &= ~O_CREAT;
129                 }
130         }
131
132         /*
133          * This little piece of insanity is inspired by the
134          * fact that an NT client can open a file for O_RDONLY,
135          * but set the create disposition to FILE_EXISTS_TRUNCATE.
136          * If the client *can* write to the file, then it expects to
137          * truncate the file, even though it is opening for readonly.
138          * Quicken uses this stupid trick in backup file creation...
139          * Thanks *greatly* to "David W. Chapman Jr." <dwcjr@inethouston.net>
140          * for helping track this one down. It didn't bite us in 2.0.x
141          * as we always opened files read-write in that release. JRA.
142          */
143
144         if ((accmode == O_RDONLY) && ((flags & O_TRUNC) == O_TRUNC)) {
145                 DEBUG(10,("open_file: truncate requested on read-only open for file %s\n",fname ));
146                 local_flags = (flags & ~O_ACCMODE)|O_RDWR;
147         }
148
149         if ((desired_access & (FILE_READ_DATA|FILE_WRITE_DATA|FILE_APPEND_DATA|FILE_EXECUTE)) ||
150                         (local_flags & O_CREAT) || ((local_flags & O_TRUNC) == O_TRUNC) ) {
151
152                 /*
153                  * We can't actually truncate here as the file may be locked.
154                  * open_file_shared will take care of the truncate later. JRA.
155                  */
156
157                 local_flags &= ~O_TRUNC;
158
159 #if defined(O_NONBLOCK) && defined(S_ISFIFO)
160                 /*
161                  * We would block on opening a FIFO with no one else on the
162                  * other end. Do what we used to do and add O_NONBLOCK to the
163                  * open flags. JRA.
164                  */
165
166                 if (VALID_STAT(*psbuf) && S_ISFIFO(psbuf->st_mode))
167                         local_flags |= O_NONBLOCK;
168 #endif
169
170                 /* Actually do the open */
171                 fsp->fd = fd_open(conn, fname, local_flags, mode);
172                 if (fsp->fd == -1)  {
173                         DEBUG(3,("Error opening file %s (%s) (local_flags=%d) (flags=%d)\n",
174                                  fname,strerror(errno),local_flags,flags));
175                         check_for_pipe(fname);
176                         return False;
177                 }
178
179                 /* Inherit the ACL if the file was created. */
180                 if ((local_flags & O_CREAT) && !VALID_STAT(*psbuf))
181                         inherit_access_acl(conn, fname, mode);
182
183         } else
184                 fsp->fd = -1; /* What we used to call a stat open. */
185
186         if (!VALID_STAT(*psbuf)) {
187                 int ret;
188
189                 if (fsp->fd == -1)
190                         ret = SMB_VFS_STAT(conn, fname, psbuf);
191                 else {
192                         ret = SMB_VFS_FSTAT(fsp,fsp->fd,psbuf);
193                         /* If we have an fd, this stat should succeed. */
194                         if (ret == -1)
195                                 DEBUG(0,("Error doing fstat on open file %s (%s)\n", fname,strerror(errno) ));
196                 }
197
198                 /* For a non-io open, this stat failing means file not found. JRA */
199                 if (ret == -1) {
200                         fd_close(conn, fsp);
201                         return False;
202                 }
203         }
204
205         /*
206          * POSIX allows read-only opens of directories. We don't
207          * want to do this (we use a different code path for this)
208          * so catch a directory open and return an EISDIR. JRA.
209          */
210
211         if(S_ISDIR(psbuf->st_mode)) {
212                 fd_close(conn, fsp);
213                 errno = EISDIR;
214                 return False;
215         }
216
217         fsp->mode = psbuf->st_mode;
218         fsp->inode = psbuf->st_ino;
219         fsp->dev = psbuf->st_dev;
220         fsp->vuid = current_user.vuid;
221         fsp->size = psbuf->st_size;
222         fsp->pos = -1;
223         fsp->can_lock = True;
224         fsp->can_read = ((flags & O_WRONLY)==0);
225         fsp->can_write = ((flags & (O_WRONLY|O_RDWR))!=0);
226         fsp->share_mode = 0;
227         fsp->desired_access = desired_access;
228         fsp->print_file = False;
229         fsp->modified = False;
230         fsp->oplock_type = NO_OPLOCK;
231         fsp->sent_oplock_break = NO_BREAK_SENT;
232         fsp->is_directory = False;
233         fsp->is_stat = False;
234         fsp->directory_delete_on_close = False;
235         string_set(&fsp->fsp_name,fname);
236         fsp->wcp = NULL; /* Write cache pointer. */
237
238         DEBUG(2,("%s opened file %s read=%s write=%s (numopen=%d)\n",
239                  *current_user_info.smb_name ? current_user_info.smb_name : conn->user,fsp->fsp_name,
240                  BOOLSTR(fsp->can_read), BOOLSTR(fsp->can_write),
241                  conn->num_files_open + 1));
242
243         return True;
244 }
245
246 /****************************************************************************
247   C. Hoch 11/22/95
248   Helper for open_file_shared. 
249   Truncate a file after checking locking; close file if locked.
250   **************************************************************************/
251
252 static int truncate_unless_locked(struct connection_struct *conn, files_struct *fsp)
253 {
254         SMB_BIG_UINT mask = (SMB_BIG_UINT)-1;
255
256         if (is_locked(fsp,fsp->conn,mask,0,WRITE_LOCK,True)){
257                 errno = EACCES;
258                 unix_ERR_class = ERRDOS;
259                 unix_ERR_code = ERRlock;
260                 unix_ERR_ntstatus = dos_to_ntstatus(ERRDOS, ERRlock);
261                 return -1;
262         } else {
263                 return SMB_VFS_FTRUNCATE(fsp,fsp->fd,0); 
264         }
265 }
266
267 /*******************************************************************
268 return True if the filename is one of the special executable types
269 ********************************************************************/
270 static BOOL is_executable(const char *fname)
271 {
272         if ((fname = strrchr_m(fname,'.'))) {
273                 if (strequal(fname,".com") ||
274                     strequal(fname,".dll") ||
275                     strequal(fname,".exe") ||
276                     strequal(fname,".sym")) {
277                         return True;
278                 }
279         }
280         return False;
281 }
282
283 enum {AFAIL,AREAD,AWRITE,AALL};
284
285 /*******************************************************************
286 reproduce the share mode access table
287 this is horrendoously complex, and really can't be justified on any
288 rational grounds except that this is _exactly_ what NT does. See
289 the DENY1 and DENY2 tests in smbtorture for a comprehensive set of
290 test routines.
291 ********************************************************************/
292 static int access_table(int new_deny,int old_deny,int old_mode,
293                         BOOL same_pid, BOOL isexe)
294 {
295           if (new_deny == DENY_ALL || old_deny == DENY_ALL) return(AFAIL);
296
297           if (same_pid) {
298                   if (isexe && old_mode == DOS_OPEN_RDONLY && 
299                       old_deny == DENY_DOS && new_deny == DENY_READ) {
300                           return AFAIL;
301                   }
302                   if (!isexe && old_mode == DOS_OPEN_RDONLY && 
303                       old_deny == DENY_DOS && new_deny == DENY_DOS) {
304                           return AREAD;
305                   }
306                   if (new_deny == DENY_FCB && old_deny == DENY_DOS) {
307                           if (isexe) return AFAIL;
308                           if (old_mode == DOS_OPEN_RDONLY) return AFAIL;
309                           return AALL;
310                   }
311                   if (old_mode == DOS_OPEN_RDONLY && old_deny == DENY_DOS) {
312                           if (new_deny == DENY_FCB || new_deny == DENY_READ) {
313                                   if (isexe) return AREAD;
314                                   return AFAIL;
315                           }
316                   }
317                   if (old_deny == DENY_FCB) {
318                           if (new_deny == DENY_DOS || new_deny == DENY_FCB) return AALL;
319                           return AFAIL;
320                   }
321           }
322
323           if (old_deny == DENY_DOS || new_deny == DENY_DOS || 
324               old_deny == DENY_FCB || new_deny == DENY_FCB) {
325                   if (isexe) {
326                           if (old_deny == DENY_FCB || new_deny == DENY_FCB) {
327                                   return AFAIL;
328                           }
329                           if (old_deny == DENY_DOS) {
330                                   if (new_deny == DENY_READ && 
331                                       (old_mode == DOS_OPEN_RDONLY || 
332                                        old_mode == DOS_OPEN_RDWR)) {
333                                           return AFAIL;
334                                   }
335                                   if (new_deny == DENY_WRITE && 
336                                       (old_mode == DOS_OPEN_WRONLY || 
337                                        old_mode == DOS_OPEN_RDWR)) {
338                                           return AFAIL;
339                                   }
340                                   return AALL;
341                           }
342                           if (old_deny == DENY_NONE) return AALL;
343                           if (old_deny == DENY_READ) return AWRITE;
344                           if (old_deny == DENY_WRITE) return AREAD;
345                   }
346                   /* it isn't a exe, dll, sym or com file */
347                   if (old_deny == new_deny && same_pid)
348                           return(AALL);    
349
350                   if (old_deny == DENY_READ || new_deny == DENY_READ) return AFAIL;
351                   if (old_mode == DOS_OPEN_RDONLY) return(AREAD);
352                   
353                   return(AFAIL);
354           }
355           
356           switch (new_deny) 
357                   {
358                   case DENY_WRITE:
359                           if (old_deny==DENY_WRITE && old_mode==DOS_OPEN_RDONLY) return(AREAD);
360                           if (old_deny==DENY_READ && old_mode==DOS_OPEN_RDONLY) return(AWRITE);
361                           if (old_deny==DENY_NONE && old_mode==DOS_OPEN_RDONLY) return(AALL);
362                           return(AFAIL);
363                   case DENY_READ:
364                           if (old_deny==DENY_WRITE && old_mode==DOS_OPEN_WRONLY) return(AREAD);
365                           if (old_deny==DENY_READ && old_mode==DOS_OPEN_WRONLY) return(AWRITE);
366                           if (old_deny==DENY_NONE && old_mode==DOS_OPEN_WRONLY) return(AALL);
367                           return(AFAIL);
368                   case DENY_NONE:
369                           if (old_deny==DENY_WRITE) return(AREAD);
370                           if (old_deny==DENY_READ) return(AWRITE);
371                           if (old_deny==DENY_NONE) return(AALL);
372                           return(AFAIL);      
373                   }
374           return(AFAIL);      
375 }
376
377
378 /****************************************************************************
379 check if we can open a file with a share mode
380 ****************************************************************************/
381
382 static BOOL check_share_mode(connection_struct *conn, share_mode_entry *share, int share_mode, uint32 desired_access,
383                              const char *fname, BOOL fcbopen, int *flags)
384 {
385         int deny_mode = GET_DENY_MODE(share_mode);
386         int old_open_mode = GET_OPEN_MODE(share->share_mode);
387         int old_deny_mode = GET_DENY_MODE(share->share_mode);
388
389         /*
390          * share modes = false means don't bother to check for
391          * DENY mode conflict. This is a *really* bad idea :-). JRA.
392          */
393
394         if(!lp_share_modes(SNUM(conn)))
395                 return True;
396
397         /*
398          * Don't allow any opens once the delete on close flag has been
399          * set.
400          */
401
402         if (GET_DELETE_ON_CLOSE_FLAG(share->share_mode)) {
403                 DEBUG(5,("check_share_mode: Failing open on file %s as delete on close flag is set.\n",
404                         fname ));
405                 /* Use errno to map to correct error. */
406                 unix_ERR_class = SMB_SUCCESS;
407                 unix_ERR_code = 0;
408                 unix_ERR_ntstatus = NT_STATUS_OK;
409                 return False;
410         }
411
412         /* this is a nasty hack, but necessary until we rewrite our open
413            handling to use a NTCreateX call as the basic call.
414            NT may open a file with neither read nor write access, and in
415                    this case it expects the open not to conflict with any
416                    existing deny modes. This happens (for example) during a
417                    "xcopy /o" where the second file descriptor is used for
418                    ACL sets
419                    (tridge)
420         */
421
422         /*
423          * This is a bit wierd - the test for desired access not having the
424          * critical bits seems seems odd. Firstly, if both opens have no
425          * critical bits then always ignore. Then check the "allow delete"
426          * then check for either. This probably isn't quite right yet but
427          * gets us much closer. JRA.
428          */
429
430         /*
431          * If desired_access doesn't contain READ_DATA,WRITE_DATA,APPEND_DATA or EXECUTE
432          * and the existing desired_acces then share modes don't conflict.
433          */
434
435         if ( !(desired_access & (FILE_READ_DATA|FILE_WRITE_DATA|FILE_APPEND_DATA|FILE_EXECUTE)) &&
436                 !(share->desired_access & (FILE_READ_DATA|FILE_WRITE_DATA|FILE_APPEND_DATA|FILE_EXECUTE)) ) {
437
438                 /*
439                  * Wrinkle discovered by smbtorture....
440                  * If both are non-io open and requester is asking for delete and current open has delete access
441                  * but neither open has allowed file share delete then deny.... this is very strange and
442                  * seems to be the only case in which non-io opens conflict. JRA.
443                  */
444
445                 if ((desired_access & DELETE_ACCESS) && (share->desired_access & DELETE_ACCESS) && 
446                                 (!GET_ALLOW_SHARE_DELETE(share->share_mode) || !GET_ALLOW_SHARE_DELETE(share_mode))) {
447                         DEBUG(5,("check_share_mode: Failing open on file %s as delete access requests conflict.\n",
448                                 fname ));
449                         unix_ERR_class = ERRDOS;
450                         unix_ERR_code = ERRbadshare;
451                         unix_ERR_ntstatus = NT_STATUS_SHARING_VIOLATION;
452
453                         return False;
454                 }
455
456                 DEBUG(5,("check_share_mode: Allowing open on file %s as both desired access (0x%x) \
457 and existing desired access (0x%x) are non-data opens\n", 
458                         fname, (unsigned int)desired_access, (unsigned int)share->desired_access ));
459                 return True;
460         }
461
462         /*
463          * If delete access was requested and the existing share mode doesn't have
464          * ALLOW_SHARE_DELETE then deny.
465          */
466
467         if ((desired_access & DELETE_ACCESS) && !GET_ALLOW_SHARE_DELETE(share->share_mode)) {
468                 DEBUG(5,("check_share_mode: Failing open on file %s as delete access requested and allow share delete not set.\n",
469                         fname ));
470                 unix_ERR_class = ERRDOS;
471                 unix_ERR_code = ERRbadshare;
472                 unix_ERR_ntstatus = NT_STATUS_SHARING_VIOLATION;
473
474                 return False;
475         }
476
477         /*
478          * The inverse of the above.
479          * If delete access was granted and the new share mode doesn't have
480          * ALLOW_SHARE_DELETE then deny.
481          */
482
483         if ((share->desired_access & DELETE_ACCESS) && !GET_ALLOW_SHARE_DELETE(share_mode)) {
484                 DEBUG(5,("check_share_mode: Failing open on file %s as delete access granted and allow share delete not requested.\n",
485                         fname ));
486                 unix_ERR_class = ERRDOS;
487                 unix_ERR_code = ERRbadshare;
488                 unix_ERR_ntstatus = NT_STATUS_SHARING_VIOLATION;
489
490                 return False;
491         }
492
493         /*
494          * If desired_access doesn't contain READ_DATA,WRITE_DATA,APPEND_DATA or EXECUTE
495          * then share modes don't conflict. Likewise with existing desired access.
496          */
497
498         if ( !(desired_access & (FILE_READ_DATA|FILE_WRITE_DATA|FILE_APPEND_DATA|FILE_EXECUTE)) ||
499                 !(share->desired_access & (FILE_READ_DATA|FILE_WRITE_DATA|FILE_APPEND_DATA|FILE_EXECUTE)) ) {
500                 DEBUG(5,("check_share_mode: Allowing open on file %s as desired access (0x%x) doesn't conflict with\
501 existing desired access (0x%x).\n", fname, (unsigned int)desired_access, (unsigned int)share->desired_access ));
502                 return True;
503         }
504
505         {
506                 int access_allowed = access_table(deny_mode,old_deny_mode,old_open_mode,
507                                                 (share->pid == sys_getpid()),is_executable(fname));
508
509                 if ((access_allowed == AFAIL) ||
510                         (!fcbopen && (access_allowed == AREAD && *flags == O_RDWR)) ||
511                         (access_allowed == AREAD && *flags != O_RDONLY) ||
512                         (access_allowed == AWRITE && *flags != O_WRONLY)) {
513
514                         DEBUG(2,("Share violation on file (%d,%d,%d,%d,%s,fcbopen = %d, flags = %d) = %d\n",
515                                 deny_mode,old_deny_mode,old_open_mode,
516                                 (int)share->pid,fname, fcbopen, *flags, access_allowed));
517
518                         unix_ERR_class = ERRDOS;
519                         unix_ERR_code = ERRbadshare;
520                         unix_ERR_ntstatus = NT_STATUS_SHARING_VIOLATION;
521
522                         return False;
523                 }
524
525                 if (access_allowed == AREAD)
526                         *flags = O_RDONLY;
527
528                 if (access_allowed == AWRITE)
529                         *flags = O_WRONLY;
530
531         }
532
533         return True;
534 }
535
536
537 #if defined(DEVELOPER)
538 static void validate_my_share_entries(int num, share_mode_entry *share_entry)
539 {
540         files_struct *fsp;
541
542         if (share_entry->pid != sys_getpid())
543                 return;
544
545         fsp = file_find_dif(share_entry->dev, share_entry->inode, share_entry->share_file_id);
546         if (!fsp) {
547                 DEBUG(0,("validate_my_share_entries: PANIC : %s\n", share_mode_str(num, share_entry) ));
548                 smb_panic("validate_my_share_entries: Cannot match a share entry with an open file\n");
549         }
550
551         if (((uint16)fsp->oplock_type) != share_entry->op_type) {
552                 pstring str;
553                 DEBUG(0,("validate_my_share_entries: PANIC : %s\n", share_mode_str(num, share_entry) ));
554                 slprintf(str, sizeof(str)-1, "validate_my_share_entries: file %s, oplock_type = 0x%x, op_type = 0x%x\n",
555                                 fsp->fsp_name, (unsigned int)fsp->oplock_type, (unsigned int)share_entry->op_type );
556                 smb_panic(str);
557         }
558 }
559 #endif
560
561 /****************************************************************************
562  Deal with open deny mode and oplock break processing.
563  Invarient: Share mode must be locked on entry and exit.
564  Returns -1 on error, or number of share modes on success (may be zero).
565 ****************************************************************************/
566
567 static int open_mode_check(connection_struct *conn, const char *fname, SMB_DEV_T dev,
568                            SMB_INO_T inode, 
569                            uint32 desired_access,
570                            int share_mode, int *p_flags, int *p_oplock_request,
571                            BOOL *p_all_current_opens_are_level_II)
572 {
573         int i;
574         int num_share_modes;
575         int oplock_contention_count = 0;
576         share_mode_entry *old_shares = 0;
577         BOOL fcbopen = False;
578         BOOL broke_oplock;      
579         
580         if(GET_OPEN_MODE(share_mode) == DOS_OPEN_FCB)
581                 fcbopen = True;
582         
583         num_share_modes = get_share_modes(conn, dev, inode, &old_shares);
584         
585         if(num_share_modes == 0)
586                 return 0;
587         
588         /*
589          * Check if the share modes will give us access.
590          */
591         
592         do {
593                 share_mode_entry broken_entry;
594                 
595                 broke_oplock = False;
596                 *p_all_current_opens_are_level_II = True;
597                 
598                 for(i = 0; i < num_share_modes; i++) {
599                         share_mode_entry *share_entry = &old_shares[i];
600                         
601 #if defined(DEVELOPER)
602                         validate_my_share_entries(i, share_entry);
603 #endif
604
605                         /* 
606                          * By observation of NetBench, oplocks are broken *before* share
607                          * modes are checked. This allows a file to be closed by the client
608                          * if the share mode would deny access and the client has an oplock. 
609                          * Check if someone has an oplock on this file. If so we must break 
610                          * it before continuing. 
611                          */
612                         
613                         if((*p_oplock_request && EXCLUSIVE_OPLOCK_TYPE(share_entry->op_type)) ||
614                            (!*p_oplock_request && (share_entry->op_type != NO_OPLOCK))) {
615                                 
616                                 BOOL opb_ret;
617
618                                 DEBUG(5,("open_mode_check: oplock_request = %d, breaking oplock (%x) on file %s, \
619 dev = %x, inode = %.0f\n", *p_oplock_request, share_entry->op_type, fname, (unsigned int)dev, (double)inode));
620                                 
621                                 /* Oplock break - unlock to request it. */
622                                 unlock_share_entry(conn, dev, inode);
623                                 
624                                 opb_ret = request_oplock_break(share_entry, False);
625                                 
626                                 /* Now relock. */
627                                 lock_share_entry(conn, dev, inode);
628                                 
629                                 if(opb_ret == False) {
630                                         DEBUG(0,("open_mode_check: FAILED when breaking oplock (%x) on file %s, \
631 dev = %x, inode = %.0f\n", old_shares[i].op_type, fname, (unsigned int)dev, (double)inode));
632                                         SAFE_FREE(old_shares);
633                                         errno = EACCES;
634                                         unix_ERR_class = ERRDOS;
635                                         unix_ERR_code = ERRbadshare;
636                                         unix_ERR_ntstatus = NT_STATUS_SHARING_VIOLATION;
637                                         return -1;
638                                 }
639                                 
640                                 broke_oplock = True;
641                                 broken_entry = *share_entry;
642                                 break;
643                                 
644                         } else if (!LEVEL_II_OPLOCK_TYPE(share_entry->op_type)) {
645                                 *p_all_current_opens_are_level_II = False;
646                         }
647                         
648                         /* someone else has a share lock on it, check to see if we can too */
649                         if (!check_share_mode(conn, share_entry, share_mode, desired_access,
650                                                 fname, fcbopen, p_flags)) {
651                                 SAFE_FREE(old_shares);
652                                 errno = EACCES;
653                                 return -1;
654                         }
655                         
656                 } /* end for */
657                 
658                 if(broke_oplock) {
659                         SAFE_FREE(old_shares);
660                         num_share_modes = get_share_modes(conn, dev, inode, &old_shares);
661                         oplock_contention_count++;
662                         
663                         /* Paranoia check that this is no longer an exlusive entry. */
664                         for(i = 0; i < num_share_modes; i++) {
665                                 share_mode_entry *share_entry = &old_shares[i];
666                                 
667                                 if (share_modes_identical(&broken_entry, share_entry) && 
668                                     EXCLUSIVE_OPLOCK_TYPE(share_entry->op_type) ) {
669                                         
670                                         /*
671                                          * This should not happen. The target left this oplock
672                                          * as exlusive.... The process *must* be dead.... 
673                                          */
674                                         
675                                         DEBUG(0,("open_mode_check: exlusive oplock left by process %d after break ! For file %s, \
676 dev = %x, inode = %.0f. Deleting it to continue...\n", (int)broken_entry.pid, fname, (unsigned int)dev, (double)inode));
677                                         
678                                         if (process_exists(broken_entry.pid)) {
679                                                 DEBUG(0,("open_mode_check: Existent process %lu left active oplock.\n",
680                                                          (unsigned long)broken_entry.pid ));
681                                         }
682                                         
683                                         if (del_share_entry(dev, inode, &broken_entry, NULL) == -1) {
684                                                 errno = EACCES;
685                                                 unix_ERR_class = ERRDOS;
686                                                 unix_ERR_code = ERRbadshare;
687                                                 unix_ERR_ntstatus = NT_STATUS_SHARING_VIOLATION;
688                                                 return -1;
689                                         }
690                                         
691                                         /*
692                                          * We must reload the share modes after deleting the 
693                                          * other process's entry.
694                                          */
695                                         
696                                         SAFE_FREE(old_shares);
697                                         num_share_modes = get_share_modes(conn, dev, inode, &old_shares);
698                                         break;
699                                 }
700                         } /* end for paranoia... */
701                 } /* end if broke_oplock */
702                 
703         } while(broke_oplock);
704         
705         if(old_shares != 0)
706                 SAFE_FREE(old_shares);
707         
708         /*
709          * Refuse to grant an oplock in case the contention limit is
710          * reached when going through the lock list multiple times.
711          */
712         
713         if(oplock_contention_count >= lp_oplock_contention_limit(SNUM(conn))) {
714                 *p_oplock_request = 0;
715                 DEBUG(4,("open_mode_check: oplock contention = %d. Not granting oplock.\n",
716                          oplock_contention_count ));
717         }
718         
719         return num_share_modes;
720 }
721
722 /****************************************************************************
723 set a kernel flock on a file for NFS interoperability
724 this requires a patch to Linux
725 ****************************************************************************/
726 static void kernel_flock(files_struct *fsp, int deny_mode)
727 {
728 #if HAVE_KERNEL_SHARE_MODES
729         int kernel_mode = 0;
730         if (deny_mode == DENY_READ) kernel_mode = LOCK_MAND|LOCK_WRITE;
731         else if (deny_mode == DENY_WRITE) kernel_mode = LOCK_MAND|LOCK_READ;
732         else if (deny_mode == DENY_ALL) kernel_mode = LOCK_MAND;
733         if (kernel_mode) flock(fsp->fd, kernel_mode);
734 #endif
735         ;;
736 }
737
738
739 static BOOL open_match_attributes(connection_struct *conn, char *path, mode_t existing_mode,
740                 mode_t new_mode, mode_t *returned_mode)
741 {
742         uint32 old_dos_mode, new_dos_mode;
743         uint32 noarch_old_dos_mode, noarch_new_dos_mode;
744         SMB_STRUCT_STAT sbuf;
745
746         ZERO_STRUCT(sbuf);
747
748         sbuf.st_mode = existing_mode;
749         old_dos_mode = dos_mode(conn, path, &sbuf);
750
751         sbuf.st_mode = new_mode;
752         new_dos_mode = dos_mode(conn, path, &sbuf);
753
754         noarch_old_dos_mode = (old_dos_mode & ~FILE_ATTRIBUTE_ARCHIVE);
755         noarch_new_dos_mode = (new_dos_mode & ~FILE_ATTRIBUTE_ARCHIVE);
756
757         if((noarch_old_dos_mode == 0 && noarch_new_dos_mode != 0) || 
758            (noarch_old_dos_mode != 0 && ((noarch_old_dos_mode & noarch_new_dos_mode) == noarch_old_dos_mode)))
759                 *returned_mode = new_mode;
760         else
761                 *returned_mode = (mode_t)0;
762
763         DEBUG(10,("open_match_attributes: file %s old_dos_mode = 0x%x, existing_mode = 0%o, new_dos_mode = 0x%x returned_mode = 0%o\n",
764                 path,
765                 old_dos_mode, (unsigned int)existing_mode, new_dos_mode, (unsigned int)*returned_mode ));
766
767         /* If we're mapping SYSTEM and HIDDEN ensure they match. */
768         if (lp_map_system(SNUM(conn))) {
769                 if ((old_dos_mode & FILE_ATTRIBUTE_SYSTEM) && !(new_dos_mode & FILE_ATTRIBUTE_SYSTEM))
770                         return False;
771         }
772         if (lp_map_hidden(SNUM(conn))) {
773                 if ((old_dos_mode & FILE_ATTRIBUTE_HIDDEN) && !(new_dos_mode & FILE_ATTRIBUTE_HIDDEN))
774                         return False;
775         }
776         return True;
777 }
778
779 /****************************************************************************
780  Open a file with a share mode.
781 ****************************************************************************/
782
783 files_struct *open_file_shared(connection_struct *conn,char *fname, SMB_STRUCT_STAT *psbuf, 
784                                int share_mode,int ofun, mode_t mode,int oplock_request, 
785                                int *Access,int *action)
786 {
787         return open_file_shared1(conn, fname, psbuf, 0, share_mode, ofun, mode, 
788                                  oplock_request, Access, action);
789 }
790
791 /****************************************************************************
792  Open a file with a share mode.
793 ****************************************************************************/
794
795 files_struct *open_file_shared1(connection_struct *conn,char *fname, SMB_STRUCT_STAT *psbuf, 
796                                 uint32 desired_access, 
797                                 int share_mode,int ofun, mode_t mode,int oplock_request, 
798                                 int *Access,int *action)
799 {
800         int flags=0;
801         int flags2=0;
802         int deny_mode = GET_DENY_MODE(share_mode);
803         BOOL allow_share_delete = GET_ALLOW_SHARE_DELETE(share_mode);
804         BOOL delete_on_close = GET_DELETE_ON_CLOSE_FLAG(share_mode);
805         BOOL file_existed = VALID_STAT(*psbuf);
806         BOOL fcbopen = False;
807         BOOL def_acl = False;
808         SMB_DEV_T dev = 0;
809         SMB_INO_T inode = 0;
810         int num_share_modes = 0;
811         BOOL all_current_opens_are_level_II = False;
812         BOOL fsp_open = False;
813         files_struct *fsp = NULL;
814         int open_mode=0;
815         uint16 port = 0;
816         mode_t new_mode = (mode_t)0;
817
818         if (conn->printer) {
819                 /* printers are handled completely differently. Most of the passed parameters are
820                         ignored */
821                 if (Access)
822                         *Access = DOS_OPEN_WRONLY;
823                 if (action)
824                         *action = FILE_WAS_CREATED;
825                 return print_fsp_open(conn, fname);
826         }
827
828         fsp = file_new(conn);
829         if(!fsp)
830                 return NULL;
831
832         DEBUG(10,("open_file_shared: fname = %s, share_mode = %x, ofun = %x, mode = %o, oplock request = %d\n",
833                 fname, share_mode, ofun, (int)mode,  oplock_request ));
834
835         if (!check_name(fname,conn)) {
836                 file_free(fsp);
837                 return NULL;
838         } 
839
840         /* ignore any oplock requests if oplocks are disabled */
841         if (!lp_oplocks(SNUM(conn)) || global_client_failed_oplock_break) {
842                 oplock_request = 0;
843         }
844
845         /* this is for OS/2 EAs - try and say we don't support them */
846         if (strstr(fname,".+,;=[].")) {
847                 unix_ERR_class = ERRDOS;
848                 /* OS/2 Workplace shell fix may be main code stream in a later release. */ 
849 #if 1 /* OS2_WPS_FIX - Recent versions of OS/2 need this. */
850                 unix_ERR_code = ERRcannotopen;
851 #else /* OS2_WPS_FIX */
852                 unix_ERR_code = ERROR_EAS_NOT_SUPPORTED;
853 #endif /* OS2_WPS_FIX */
854
855                 DEBUG(5,("open_file_shared: OS/2 EA's are not supported.\n"));
856                 file_free(fsp);
857                 return NULL;
858         }
859
860         if ((GET_FILE_OPEN_DISPOSITION(ofun) == FILE_EXISTS_FAIL) && file_existed)  {
861                 DEBUG(5,("open_file_shared: create new requested for file %s and file already exists.\n",
862                         fname ));
863                 file_free(fsp);
864                 errno = EEXIST;
865                 return NULL;
866         }
867       
868         if (CAN_WRITE(conn) && (GET_FILE_CREATE_DISPOSITION(ofun) == FILE_CREATE_IF_NOT_EXIST))
869                 flags2 |= O_CREAT;
870
871         if (CAN_WRITE(conn) && (GET_FILE_OPEN_DISPOSITION(ofun) == FILE_EXISTS_TRUNCATE))
872                 flags2 |= O_TRUNC;
873
874         /* We only care about matching attributes on file exists and truncate. */
875         if (file_existed && (GET_FILE_OPEN_DISPOSITION(ofun) == FILE_EXISTS_TRUNCATE)) {
876                 if (!open_match_attributes(conn, fname, psbuf->st_mode, mode, &new_mode)) {
877                         DEBUG(5,("open_file_shared: attributes missmatch for file %s (0%o, 0%o)\n",
878                                                 fname, (int)psbuf->st_mode, (int)mode ));
879                         file_free(fsp);
880                         errno = EACCES;
881                         return NULL;
882                 }
883         }
884
885         if (GET_FILE_OPEN_DISPOSITION(ofun) == FILE_EXISTS_FAIL)
886                 flags2 |= O_EXCL;
887
888         /* note that we ignore the append flag as 
889                 append does not mean the same thing under dos and unix */
890
891         switch (GET_OPEN_MODE(share_mode)) {
892                 case DOS_OPEN_WRONLY: 
893                         flags = O_WRONLY; 
894                         if (desired_access == 0)
895                                 desired_access = FILE_WRITE_DATA;
896                         break;
897                 case DOS_OPEN_FCB: 
898                         fcbopen = True;
899                         flags = O_RDWR; 
900                         if (desired_access == 0)
901                                 desired_access = FILE_READ_DATA|FILE_WRITE_DATA;
902                         break;
903                 case DOS_OPEN_RDWR: 
904                         flags = O_RDWR; 
905                         if (desired_access == 0)
906                                 desired_access = FILE_READ_DATA|FILE_WRITE_DATA;
907                         break;
908                 default:
909                         flags = O_RDONLY;
910                         if (desired_access == 0)
911                                 desired_access = FILE_READ_DATA;
912                         break;
913         }
914
915 #if defined(O_SYNC)
916         if (GET_FILE_SYNC_OPENMODE(share_mode)) {
917                 flags2 |= O_SYNC;
918         }
919 #endif /* O_SYNC */
920   
921         if (flags != O_RDONLY && file_existed && 
922                         (!CAN_WRITE(conn) || IS_DOS_READONLY(dos_mode(conn,fname,psbuf)))) {
923                 if (!fcbopen) {
924                         DEBUG(5,("open_file_shared: read/write access requested for file %s on read only %s\n",
925                                 fname, !CAN_WRITE(conn) ? "share" : "file" ));
926                         file_free(fsp);
927                         errno = EACCES;
928                         return NULL;
929                 }
930                 flags = O_RDONLY;
931         }
932
933         if (deny_mode > DENY_NONE && deny_mode!=DENY_FCB) {
934                 DEBUG(2,("Invalid deny mode %d on file %s\n",deny_mode,fname));
935                 file_free(fsp);
936                 errno = EINVAL;
937                 return NULL;
938         }
939
940         if (file_existed) {
941
942                 dev = psbuf->st_dev;
943                 inode = psbuf->st_ino;
944
945                 lock_share_entry(conn, dev, inode);
946
947                 num_share_modes = open_mode_check(conn, fname, dev, inode, 
948                                                   desired_access,
949                                                   share_mode,
950                                                   &flags, &oplock_request, &all_current_opens_are_level_II);
951                 if(num_share_modes == -1) {
952
953                         /*
954                          * This next line is a subtlety we need for MS-Access. If a file open will
955                          * fail due to share permissions and also for security (access)
956                          * reasons, we need to return the access failed error, not the
957                          * share error. This means we must attempt to open the file anyway
958                          * in order to get the UNIX access error - even if we're going to
959                          * fail the open for share reasons. This is bad, as we're burning
960                          * another fd if there are existing locks but there's nothing else
961                          * we can do. We also ensure we're not going to create or tuncate
962                          * the file as we only want an access decision at this stage. JRA.
963                          */
964                         errno = 0;
965                         fsp_open = open_file(fsp,conn,fname,psbuf,
966                                                 flags|(flags2&~(O_TRUNC|O_CREAT)),mode,desired_access);
967
968                         DEBUG(4,("open_file_shared : share_mode deny - calling open_file with \
969 flags=0x%X flags2=0x%X mode=0%o returned %d\n",
970                                 flags,(flags2&~(O_TRUNC|O_CREAT)),(int)mode,(int)fsp_open ));
971
972                         if (!fsp_open && errno) {
973                                 unix_ERR_class = ERRDOS;
974                                 unix_ERR_code = ERRnoaccess;
975                                 unix_ERR_ntstatus = NT_STATUS_ACCESS_DENIED;
976                         }
977
978                         unlock_share_entry(conn, dev, inode);
979                         if (fsp_open)
980                                 fd_close(conn, fsp);
981                         file_free(fsp);
982                         return NULL;
983                 }
984
985                 /*
986                  * We exit this block with the share entry *locked*.....
987                  */
988         }
989
990         /*
991          * Ensure we pay attention to default ACLs on directories if required.
992          */
993
994         if ((flags2 & O_CREAT) && lp_inherit_acls(SNUM(conn)) &&
995                         (def_acl = directory_has_default_acl(conn, parent_dirname(fname))))
996                 mode = 0777;
997
998         DEBUG(4,("calling open_file with flags=0x%X flags2=0x%X mode=0%o\n",
999                         flags,flags2,(int)mode));
1000
1001         /*
1002          * open_file strips any O_TRUNC flags itself.
1003          */
1004
1005         fsp_open = open_file(fsp,conn,fname,psbuf,flags|flags2,mode,desired_access);
1006
1007         if (!fsp_open && (flags == O_RDWR) && (errno != ENOENT) && fcbopen) {
1008                 if((fsp_open = open_file(fsp,conn,fname,psbuf,O_RDONLY,mode,desired_access)) == True)
1009                         flags = O_RDONLY;
1010         }
1011
1012         if (!fsp_open) {
1013                 if(file_existed)
1014                         unlock_share_entry(conn, dev, inode);
1015                 file_free(fsp);
1016                 return NULL;
1017         }
1018
1019         /*
1020          * Deal with the race condition where two smbd's detect the file doesn't
1021          * exist and do the create at the same time. One of them will win and
1022          * set a share mode, the other (ie. this one) should check if the
1023          * requested share mode for this create is allowed.
1024          */
1025
1026         if (!file_existed) { 
1027
1028                 /*
1029                  * Now the file exists and fsp is successfully opened,
1030                  * fsp->dev and fsp->inode are valid and should replace the
1031                  * dev=0,inode=0 from a non existent file. Spotted by
1032                  * Nadav Danieli <nadavd@exanet.com>. JRA.
1033                  */
1034
1035                 dev = fsp->dev;
1036                 inode = fsp->inode;
1037
1038                 lock_share_entry_fsp(fsp);
1039
1040                 num_share_modes = open_mode_check(conn, fname, dev, inode, 
1041                                                   desired_access,
1042                                                   share_mode,
1043                                                   &flags, &oplock_request, &all_current_opens_are_level_II);
1044
1045                 if(num_share_modes == -1) {
1046                         unlock_share_entry_fsp(fsp);
1047                         fd_close(conn,fsp);
1048                         file_free(fsp);
1049                         return NULL;
1050                 }
1051
1052                 /*
1053                  * If there are any share modes set then the file *did*
1054                  * exist. Ensure we return the correct value for action.
1055                  */
1056
1057                 if (num_share_modes > 0)
1058                         file_existed = True;
1059
1060                 /*
1061                  * We exit this block with the share entry *locked*.....
1062                  */
1063         }
1064
1065         /* note that we ignore failure for the following. It is
1066            basically a hack for NFS, and NFS will never set one of
1067            these only read them. Nobody but Samba can ever set a deny
1068            mode and we have already checked our more authoritative
1069            locking database for permission to set this deny mode. If
1070            the kernel refuses the operations then the kernel is wrong */
1071         kernel_flock(fsp, deny_mode);
1072
1073         /*
1074          * At this point onwards, we can guarentee that the share entry
1075          * is locked, whether we created the file or not, and that the
1076          * deny mode is compatible with all current opens.
1077          */
1078
1079         /*
1080          * If requested, truncate the file.
1081          */
1082
1083         if (flags2&O_TRUNC) {
1084                 /*
1085                  * We are modifing the file after open - update the stat struct..
1086                  */
1087                 if ((truncate_unless_locked(conn,fsp) == -1) || (SMB_VFS_FSTAT(fsp,fsp->fd,psbuf)==-1)) {
1088                         unlock_share_entry_fsp(fsp);
1089                         fd_close(conn,fsp);
1090                         file_free(fsp);
1091                         return NULL;
1092                 }
1093         }
1094
1095         switch (flags) {
1096                 case O_RDONLY:
1097                         open_mode = DOS_OPEN_RDONLY;
1098                         break;
1099                 case O_RDWR:
1100                         open_mode = DOS_OPEN_RDWR;
1101                         break;
1102                 case O_WRONLY:
1103                         open_mode = DOS_OPEN_WRONLY;
1104                         break;
1105         }
1106
1107         fsp->share_mode = SET_DENY_MODE(deny_mode) | 
1108                                                 SET_OPEN_MODE(open_mode) | 
1109                                                 SET_ALLOW_SHARE_DELETE(allow_share_delete);
1110
1111         DEBUG(10,("open_file_shared : share_mode = %x\n", fsp->share_mode ));
1112
1113         if (Access)
1114                 (*Access) = open_mode;
1115
1116         if (action) {
1117                 if (file_existed && !(flags2 & O_TRUNC))
1118                         *action = FILE_WAS_OPENED;
1119                 if (!file_existed)
1120                         *action = FILE_WAS_CREATED;
1121                 if (file_existed && (flags2 & O_TRUNC))
1122                         *action = FILE_WAS_OVERWRITTEN;
1123         }
1124
1125         /* 
1126          * Setup the oplock info in both the shared memory and
1127          * file structs.
1128          */
1129
1130         if(oplock_request && (num_share_modes == 0) && 
1131                         !IS_VETO_OPLOCK_PATH(conn,fname) && set_file_oplock(fsp, oplock_request) ) {
1132                 port = global_oplock_port;
1133         } else if (oplock_request && all_current_opens_are_level_II) {
1134                 port = global_oplock_port;
1135                 oplock_request = LEVEL_II_OPLOCK;
1136                 set_file_oplock(fsp, oplock_request);
1137         } else {
1138                 port = 0;
1139                 oplock_request = 0;
1140         }
1141
1142         set_share_mode(fsp, port, oplock_request);
1143
1144         if (delete_on_close) {
1145                 NTSTATUS result = set_delete_on_close_internal(fsp, delete_on_close);
1146
1147                 if (NT_STATUS_V(result) !=  NT_STATUS_V(NT_STATUS_OK)) {
1148                         /* Remember to delete the mode we just added. */
1149                         del_share_mode(fsp, NULL);
1150                         unlock_share_entry_fsp(fsp);
1151                         fd_close(conn,fsp);
1152                         file_free(fsp);
1153                         return NULL;
1154                 }
1155         }
1156         
1157         /*
1158          * Take care of inherited ACLs on created files - if default ACL not
1159          * selected.
1160          */
1161
1162         if (!file_existed && !def_acl) {
1163
1164                 int saved_errno = errno; /* We might get ENOSYS in the next call.. */
1165
1166                 if (SMB_VFS_FCHMOD_ACL(fsp, fsp->fd, mode) == -1 && errno == ENOSYS)
1167                         errno = saved_errno; /* Ignore ENOSYS */
1168
1169         } else if (new_mode) {
1170
1171                 int ret = -1;
1172
1173                 /* Attributes need changing. File already existed. */
1174
1175                 {
1176                         int saved_errno = errno; /* We might get ENOSYS in the next call.. */
1177                         ret = SMB_VFS_FCHMOD_ACL(fsp, fsp->fd, new_mode);
1178
1179                         if (ret == -1 && errno == ENOSYS) {
1180                                 errno = saved_errno; /* Ignore ENOSYS */
1181                         } else {
1182                                 DEBUG(5, ("open_file_shared: failed to reset attributes of file %s to 0%o\n",
1183                                         fname, (int)new_mode));
1184                                 ret = 0; /* Don't do the fchmod below. */
1185                         }
1186                 }
1187
1188                 if ((ret == -1) && (SMB_VFS_FCHMOD(fsp, fsp->fd, new_mode) == -1))
1189                         DEBUG(5, ("open_file_shared: failed to reset attributes of file %s to 0%o\n",
1190                                 fname, (int)new_mode));
1191         }
1192
1193         unlock_share_entry_fsp(fsp);
1194
1195         conn->num_files_open++;
1196
1197         return fsp;
1198 }
1199
1200 /****************************************************************************
1201  Open a file for for write to ensure that we can fchmod it.
1202 ****************************************************************************/
1203
1204 files_struct *open_file_fchmod(connection_struct *conn, const char *fname, SMB_STRUCT_STAT *psbuf)
1205 {
1206         files_struct *fsp = NULL;
1207         BOOL fsp_open;
1208
1209         if (!VALID_STAT(*psbuf))
1210                 return NULL;
1211
1212         fsp = file_new(conn);
1213         if(!fsp)
1214                 return NULL;
1215
1216         /* note! we must use a non-zero desired access or we don't get
1217            a real file descriptor. Oh what a twisted web we weave. */
1218         fsp_open = open_file(fsp,conn,fname,psbuf,O_WRONLY,0,FILE_WRITE_DATA);
1219
1220         /* 
1221          * This is not a user visible file open.
1222          * Don't set a share mode and don't increment
1223          * the conn->num_files_open.
1224          */
1225
1226         if (!fsp_open) {
1227                 file_free(fsp);
1228                 return NULL;
1229         }
1230
1231         return fsp;
1232 }
1233
1234 /****************************************************************************
1235  Close the fchmod file fd - ensure no locks are lost.
1236 ****************************************************************************/
1237
1238 int close_file_fchmod(files_struct *fsp)
1239 {
1240         int ret = fd_close(fsp->conn, fsp);
1241         file_free(fsp);
1242         return ret;
1243 }
1244
1245 /****************************************************************************
1246  Open a directory from an NT SMB call.
1247 ****************************************************************************/
1248
1249 files_struct *open_directory(connection_struct *conn, char *fname, SMB_STRUCT_STAT *psbuf,
1250                         uint32 desired_access, int share_mode, int smb_ofun, mode_t unixmode, int *action)
1251 {
1252         extern struct current_user current_user;
1253         BOOL got_stat = False;
1254         files_struct *fsp = file_new(conn);
1255         BOOL delete_on_close = GET_DELETE_ON_CLOSE_FLAG(share_mode);
1256
1257         if(!fsp)
1258                 return NULL;
1259
1260         if (VALID_STAT(*psbuf))
1261                 got_stat = True;
1262
1263         if (got_stat && (GET_FILE_OPEN_DISPOSITION(smb_ofun) == FILE_EXISTS_FAIL)) {
1264                 file_free(fsp);
1265                 errno = EEXIST; /* Setup so correct error is returned to client. */
1266                 return NULL;
1267         }
1268
1269         if (GET_FILE_CREATE_DISPOSITION(smb_ofun) == FILE_CREATE_IF_NOT_EXIST) {
1270
1271                 if (got_stat) {
1272
1273                         if(!S_ISDIR(psbuf->st_mode)) {
1274                                 DEBUG(0,("open_directory: %s is not a directory !\n", fname ));
1275                                 file_free(fsp);
1276                                 errno = EACCES;
1277                                 return NULL;
1278                         }
1279                         *action = FILE_WAS_OPENED;
1280
1281                 } else {
1282
1283                         /*
1284                          * Try and create the directory.
1285                          */
1286
1287                         if(!CAN_WRITE(conn)) {
1288                                 DEBUG(2,("open_directory: failing create on read-only share\n"));
1289                                 file_free(fsp);
1290                                 errno = EACCES;
1291                                 return NULL;
1292                         }
1293
1294                         if(vfs_MkDir(conn,fname, unix_mode(conn,aDIR, fname)) < 0) {
1295                                 DEBUG(2,("open_directory: unable to create %s. Error was %s\n",
1296                                          fname, strerror(errno) ));
1297                                 file_free(fsp);
1298                                 return NULL;
1299                         }
1300
1301                         if(SMB_VFS_STAT(conn,fname, psbuf) != 0) {
1302                                 file_free(fsp);
1303                                 return NULL;
1304                         }
1305
1306                         *action = FILE_WAS_CREATED;
1307
1308                 }
1309         } else {
1310
1311                 /*
1312                  * Don't create - just check that it *was* a directory.
1313                  */
1314
1315                 if(!got_stat) {
1316                         DEBUG(3,("open_directory: unable to stat name = %s. Error was %s\n",
1317                                  fname, strerror(errno) ));
1318                         file_free(fsp);
1319                         return NULL;
1320                 }
1321
1322                 if(!S_ISDIR(psbuf->st_mode)) {
1323                         DEBUG(0,("open_directory: %s is not a directory !\n", fname ));
1324                         file_free(fsp);
1325                         return NULL;
1326                 }
1327
1328                 *action = FILE_WAS_OPENED;
1329         }
1330         
1331         DEBUG(5,("open_directory: opening directory %s\n", fname));
1332
1333         /*
1334          * Setup the files_struct for it.
1335          */
1336         
1337         fsp->mode = psbuf->st_mode;
1338         fsp->inode = psbuf->st_ino;
1339         fsp->dev = psbuf->st_dev;
1340         fsp->size = psbuf->st_size;
1341         fsp->vuid = current_user.vuid;
1342         fsp->pos = -1;
1343         fsp->can_lock = True;
1344         fsp->can_read = False;
1345         fsp->can_write = False;
1346         fsp->share_mode = share_mode;
1347         fsp->desired_access = desired_access;
1348         fsp->print_file = False;
1349         fsp->modified = False;
1350         fsp->oplock_type = NO_OPLOCK;
1351         fsp->sent_oplock_break = NO_BREAK_SENT;
1352         fsp->is_directory = True;
1353         fsp->is_stat = False;
1354         fsp->directory_delete_on_close = False;
1355         string_set(&fsp->fsp_name,fname);
1356
1357         if (delete_on_close) {
1358                 NTSTATUS result = set_delete_on_close_internal(fsp, delete_on_close);
1359
1360                 if (NT_STATUS_V(result) !=  NT_STATUS_V(NT_STATUS_OK)) {
1361                         file_free(fsp);
1362                         return NULL;
1363                 }
1364         }
1365         conn->num_files_open++;
1366
1367         return fsp;
1368 }
1369
1370 /****************************************************************************
1371  Open a pseudo-file (no locking checks - a 'stat' open).
1372 ****************************************************************************/
1373
1374 files_struct *open_file_stat(connection_struct *conn, char *fname, SMB_STRUCT_STAT *psbuf)
1375 {
1376         extern struct current_user current_user;
1377         files_struct *fsp = NULL;
1378
1379         if (!VALID_STAT(*psbuf))
1380                 return NULL;
1381
1382         /* Can't 'stat' open directories. */
1383         if(S_ISDIR(psbuf->st_mode))
1384                 return NULL;
1385
1386         fsp = file_new(conn);
1387         if(!fsp)
1388                 return NULL;
1389
1390         DEBUG(5,("open_file_stat: 'opening' file %s\n", fname));
1391
1392         /*
1393          * Setup the files_struct for it.
1394          */
1395         
1396         fsp->mode = psbuf->st_mode;
1397         /* 
1398          * Don't store dev or inode, we don't want any iterator
1399          * to see this.
1400          */
1401         fsp->inode = (SMB_INO_T)0;
1402         fsp->dev = (SMB_DEV_T)0;
1403         fsp->size = psbuf->st_size;
1404         fsp->vuid = current_user.vuid;
1405         fsp->pos = -1;
1406         fsp->can_lock = False;
1407         fsp->can_read = False;
1408         fsp->can_write = False;
1409         fsp->share_mode = 0;
1410         fsp->desired_access = 0;
1411         fsp->print_file = False;
1412         fsp->modified = False;
1413         fsp->oplock_type = NO_OPLOCK;
1414         fsp->sent_oplock_break = NO_BREAK_SENT;
1415         fsp->is_directory = False;
1416         fsp->is_stat = True;
1417         fsp->directory_delete_on_close = False;
1418         string_set(&fsp->fsp_name,fname);
1419
1420         conn->num_files_open++;
1421
1422         return fsp;
1423 }