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