r740: Fix Bug #1301. Return NT_STATUS_SHARING_VIOLATION when share mode locking
[Samba/bb.git] / source3 / smbd / open.c
blob235a455f3027c9dcb966dcac7966431a4cea13da
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
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.
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.
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.
22 #include "includes.h"
24 extern userdom_struct current_user_info;
25 extern uint16 global_oplock_port;
26 extern uint16 global_smbpid;
27 extern BOOL global_client_failed_oplock_break;
29 /****************************************************************************
30 fd support routines - attempt to do a dos_open.
31 ****************************************************************************/
33 static int fd_open(struct connection_struct *conn, const char *fname,
34 int flags, mode_t mode)
36 int fd;
37 #ifdef O_NOFOLLOW
38 if (!lp_symlinks(SNUM(conn)))
39 flags |= O_NOFOLLOW;
40 #endif
42 fd = SMB_VFS_OPEN(conn,fname,flags,mode);
44 DEBUG(10,("fd_open: name %s, flags = 0%o mode = 0%o, fd = %d. %s\n", fname,
45 flags, (int)mode, fd, (fd == -1) ? strerror(errno) : "" ));
47 return fd;
50 /****************************************************************************
51 Close the file associated with a fsp.
52 ****************************************************************************/
54 int fd_close(struct connection_struct *conn, files_struct *fsp)
56 if (fsp->fd == -1)
57 return 0; /* what we used to call a stat open. */
58 return fd_close_posix(conn, fsp);
62 /****************************************************************************
63 Check a filename for the pipe string.
64 ****************************************************************************/
66 static void check_for_pipe(const char *fname)
68 /* special case of pipe opens */
69 char s[10];
70 StrnCpy(s,fname,sizeof(s)-1);
71 strlower_m(s);
72 if (strstr(s,"pipe/")) {
73 DEBUG(3,("Rejecting named pipe open for %s\n",fname));
74 unix_ERR_class = ERRSRV;
75 unix_ERR_code = ERRaccess;
76 unix_ERR_ntstatus = NT_STATUS_ACCESS_DENIED;
80 /****************************************************************************
81 Open a file.
82 ****************************************************************************/
84 static BOOL open_file(files_struct *fsp,connection_struct *conn,
85 const char *fname,SMB_STRUCT_STAT *psbuf,int flags,mode_t mode, uint32 desired_access)
87 extern struct current_user current_user;
88 int accmode = (flags & O_ACCMODE);
89 int local_flags = flags;
91 fsp->fd = -1;
92 fsp->oplock_type = NO_OPLOCK;
93 errno = EPERM;
95 /* Check permissions */
98 * This code was changed after seeing a client open request
99 * containing the open mode of (DENY_WRITE/read-only) with
100 * the 'create if not exist' bit set. The previous code
101 * would fail to open the file read only on a read-only share
102 * as it was checking the flags parameter directly against O_RDONLY,
103 * this was failing as the flags parameter was set to O_RDONLY|O_CREAT.
104 * JRA.
107 if (!CAN_WRITE(conn)) {
108 /* It's a read-only share - fail if we wanted to write. */
109 if(accmode != O_RDONLY) {
110 DEBUG(3,("Permission denied opening %s\n",fname));
111 check_for_pipe(fname);
112 return False;
113 } else if(flags & O_CREAT) {
114 /* We don't want to write - but we must make sure that O_CREAT
115 doesn't create the file if we have write access into the
116 directory.
118 flags &= ~O_CREAT;
119 local_flags &= ~O_CREAT;
124 * This little piece of insanity is inspired by the
125 * fact that an NT client can open a file for O_RDONLY,
126 * but set the create disposition to FILE_EXISTS_TRUNCATE.
127 * If the client *can* write to the file, then it expects to
128 * truncate the file, even though it is opening for readonly.
129 * Quicken uses this stupid trick in backup file creation...
130 * Thanks *greatly* to "David W. Chapman Jr." <dwcjr@inethouston.net>
131 * for helping track this one down. It didn't bite us in 2.0.x
132 * as we always opened files read-write in that release. JRA.
135 if ((accmode == O_RDONLY) && ((flags & O_TRUNC) == O_TRUNC)) {
136 DEBUG(10,("open_file: truncate requested on read-only open for file %s\n",fname ));
137 local_flags = (flags & ~O_ACCMODE)|O_RDWR;
140 if ((desired_access & (FILE_READ_DATA|FILE_WRITE_DATA|FILE_APPEND_DATA|FILE_EXECUTE)) ||
141 (local_flags & O_CREAT) || ((local_flags & O_TRUNC) == O_TRUNC) ) {
144 * We can't actually truncate here as the file may be locked.
145 * open_file_shared will take care of the truncate later. JRA.
148 local_flags &= ~O_TRUNC;
150 #if defined(O_NONBLOCK) && defined(S_ISFIFO)
152 * We would block on opening a FIFO with no one else on the
153 * other end. Do what we used to do and add O_NONBLOCK to the
154 * open flags. JRA.
157 if (VALID_STAT(*psbuf) && S_ISFIFO(psbuf->st_mode))
158 local_flags |= O_NONBLOCK;
159 #endif
161 /* Don't create files with Microsoft wildcard characters. */
162 if ((local_flags & O_CREAT) && !VALID_STAT(*psbuf) && ms_has_wild(fname)) {
163 unix_ERR_class = ERRDOS;
164 unix_ERR_code = ERRinvalidname;
165 unix_ERR_ntstatus = NT_STATUS_OBJECT_NAME_INVALID;
166 return False;
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;
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);
182 } else
183 fsp->fd = -1; /* What we used to call a stat open. */
185 if (!VALID_STAT(*psbuf)) {
186 int ret;
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) ));
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;
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.
210 if(S_ISDIR(psbuf->st_mode)) {
211 fd_close(conn, fsp);
212 errno = EISDIR;
213 return False;
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->file_pid = global_smbpid;
221 fsp->size = psbuf->st_size;
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. */
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));
242 return True;
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 **************************************************************************/
251 static int truncate_unless_locked(struct connection_struct *conn, files_struct *fsp)
253 SMB_BIG_UINT mask = (SMB_BIG_UINT)-1;
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);
266 /*******************************************************************
267 return True if the filename is one of the special executable types
268 ********************************************************************/
269 static BOOL is_executable(const char *fname)
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;
279 return False;
282 enum {AFAIL,AREAD,AWRITE,AALL};
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)
294 if (new_deny == DENY_ALL || old_deny == DENY_ALL) return(AFAIL);
296 if (same_pid) {
297 if (isexe && old_mode == DOS_OPEN_RDONLY &&
298 old_deny == DENY_DOS && new_deny == DENY_READ) {
299 return AFAIL;
301 if (!isexe && old_mode == DOS_OPEN_RDONLY &&
302 old_deny == DENY_DOS && new_deny == DENY_DOS) {
303 return AREAD;
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;
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;
316 if (old_deny == DENY_FCB) {
317 if (new_deny == DENY_DOS || new_deny == DENY_FCB) return AALL;
318 return AFAIL;
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;
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;
334 if (new_deny == DENY_WRITE &&
335 (old_mode == DOS_OPEN_WRONLY ||
336 old_mode == DOS_OPEN_RDWR)) {
337 return AFAIL;
339 return AALL;
341 if (old_deny == DENY_NONE) return AALL;
342 if (old_deny == DENY_READ) return AWRITE;
343 if (old_deny == DENY_WRITE) return AREAD;
345 /* it isn't a exe, dll, sym or com file */
346 if (old_deny == new_deny && same_pid)
347 return(AALL);
349 if (old_deny == DENY_READ || new_deny == DENY_READ) return AFAIL;
350 if (old_mode == DOS_OPEN_RDONLY) return(AREAD);
352 return(AFAIL);
355 switch (new_deny)
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);
373 return(AFAIL);
377 /****************************************************************************
378 check if we can open a file with a share mode
379 ****************************************************************************/
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)
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);
389 * share modes = false means don't bother to check for
390 * DENY mode conflict. This is a *really* bad idea :-). JRA.
393 if(!lp_share_modes(SNUM(conn)))
394 return True;
397 * Don't allow any opens once the delete on close flag has been
398 * set.
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;
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)
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.
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.
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)) ) {
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.
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;
452 return False;
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;
462 * If delete access was requested and the existing share mode doesn't have
463 * ALLOW_SHARE_DELETE then deny.
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;
473 return False;
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.
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;
489 return False;
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.
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;
505 int access_allowed = access_table(deny_mode,old_deny_mode,old_open_mode,
506 (share->pid == sys_getpid()),is_executable(fname));
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)) {
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));
517 unix_ERR_class = ERRDOS;
518 unix_ERR_code = ERRbadshare;
519 unix_ERR_ntstatus = NT_STATUS_SHARING_VIOLATION;
521 return False;
524 if (access_allowed == AREAD)
525 *flags = O_RDONLY;
527 if (access_allowed == AWRITE)
528 *flags = O_WRONLY;
532 return True;
536 #if defined(DEVELOPER)
537 static void validate_my_share_entries(int num, share_mode_entry *share_entry)
539 files_struct *fsp;
541 if (share_entry->pid != sys_getpid())
542 return;
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");
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);
558 #endif
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 ****************************************************************************/
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)
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;
579 if(GET_OPEN_MODE(share_mode) == DOS_OPEN_FCB)
580 fcbopen = True;
582 num_share_modes = get_share_modes(conn, dev, inode, &old_shares);
584 if(num_share_modes == 0)
585 return 0;
588 * Check if the share modes will give us access.
591 do {
592 share_mode_entry broken_entry;
594 broke_oplock = False;
595 *p_all_current_opens_are_level_II = True;
597 for(i = 0; i < num_share_modes; i++) {
598 share_mode_entry *share_entry = &old_shares[i];
600 #if defined(DEVELOPER)
601 validate_my_share_entries(i, share_entry);
602 #endif
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.
612 if((*p_oplock_request && EXCLUSIVE_OPLOCK_TYPE(share_entry->op_type)) ||
613 (!*p_oplock_request && (share_entry->op_type != NO_OPLOCK))) {
615 BOOL opb_ret;
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));
620 /* Ensure the reply for the open uses the correct sequence number. */
621 /* This isn't a real deferred packet as it's response will also increment
622 * the sequence.
624 srv_defer_sign_response(get_current_mid());
626 /* Oplock break - unlock to request it. */
627 unlock_share_entry(conn, dev, inode);
629 opb_ret = request_oplock_break(share_entry, False);
631 /* Now relock. */
632 lock_share_entry(conn, dev, inode);
634 if(opb_ret == False) {
635 DEBUG(0,("open_mode_check: FAILED when breaking oplock (%x) on file %s, \
636 dev = %x, inode = %.0f\n", old_shares[i].op_type, fname, (unsigned int)dev, (double)inode));
637 SAFE_FREE(old_shares);
638 errno = EACCES;
639 unix_ERR_class = ERRDOS;
640 unix_ERR_code = ERRbadshare;
641 unix_ERR_ntstatus = NT_STATUS_SHARING_VIOLATION;
642 return -1;
645 broke_oplock = True;
646 broken_entry = *share_entry;
647 break;
649 } else if (!LEVEL_II_OPLOCK_TYPE(share_entry->op_type)) {
650 *p_all_current_opens_are_level_II = False;
653 /* someone else has a share lock on it, check to see if we can too */
654 if (!check_share_mode(conn, share_entry, share_mode, desired_access,
655 fname, fcbopen, p_flags)) {
656 SAFE_FREE(old_shares);
657 errno = EACCES;
658 return -1;
661 } /* end for */
663 if(broke_oplock) {
664 SAFE_FREE(old_shares);
665 num_share_modes = get_share_modes(conn, dev, inode, &old_shares);
666 oplock_contention_count++;
668 /* Paranoia check that this is no longer an exlusive entry. */
669 for(i = 0; i < num_share_modes; i++) {
670 share_mode_entry *share_entry = &old_shares[i];
672 if (share_modes_identical(&broken_entry, share_entry) &&
673 EXCLUSIVE_OPLOCK_TYPE(share_entry->op_type) ) {
676 * This should not happen. The target left this oplock
677 * as exlusive.... The process *must* be dead....
680 DEBUG(0,("open_mode_check: exlusive oplock left by process %d after break ! For file %s, \
681 dev = %x, inode = %.0f. Deleting it to continue...\n", (int)broken_entry.pid, fname, (unsigned int)dev, (double)inode));
683 if (process_exists(broken_entry.pid)) {
684 DEBUG(0,("open_mode_check: Existent process %lu left active oplock.\n",
685 (unsigned long)broken_entry.pid ));
688 if (del_share_entry(dev, inode, &broken_entry, NULL) == -1) {
689 errno = EACCES;
690 unix_ERR_class = ERRDOS;
691 unix_ERR_code = ERRbadshare;
692 unix_ERR_ntstatus = NT_STATUS_SHARING_VIOLATION;
693 return -1;
697 * We must reload the share modes after deleting the
698 * other process's entry.
701 SAFE_FREE(old_shares);
702 num_share_modes = get_share_modes(conn, dev, inode, &old_shares);
703 break;
705 } /* end for paranoia... */
706 } /* end if broke_oplock */
708 } while(broke_oplock);
710 if(old_shares != 0)
711 SAFE_FREE(old_shares);
714 * Refuse to grant an oplock in case the contention limit is
715 * reached when going through the lock list multiple times.
718 if(oplock_contention_count >= lp_oplock_contention_limit(SNUM(conn))) {
719 *p_oplock_request = 0;
720 DEBUG(4,("open_mode_check: oplock contention = %d. Not granting oplock.\n",
721 oplock_contention_count ));
724 return num_share_modes;
727 /****************************************************************************
728 set a kernel flock on a file for NFS interoperability
729 this requires a patch to Linux
730 ****************************************************************************/
731 static void kernel_flock(files_struct *fsp, int deny_mode)
733 #if HAVE_KERNEL_SHARE_MODES
734 int kernel_mode = 0;
735 if (deny_mode == DENY_READ) kernel_mode = LOCK_MAND|LOCK_WRITE;
736 else if (deny_mode == DENY_WRITE) kernel_mode = LOCK_MAND|LOCK_READ;
737 else if (deny_mode == DENY_ALL) kernel_mode = LOCK_MAND;
738 if (kernel_mode) flock(fsp->fd, kernel_mode);
739 #endif
744 static BOOL open_match_attributes(connection_struct *conn, const char *path, uint32 old_dos_mode, uint32 new_dos_mode,
745 mode_t existing_mode, mode_t new_mode, mode_t *returned_mode)
747 uint32 noarch_old_dos_mode, noarch_new_dos_mode;
749 noarch_old_dos_mode = (old_dos_mode & ~FILE_ATTRIBUTE_ARCHIVE);
750 noarch_new_dos_mode = (new_dos_mode & ~FILE_ATTRIBUTE_ARCHIVE);
752 if((noarch_old_dos_mode == 0 && noarch_new_dos_mode != 0) ||
753 (noarch_old_dos_mode != 0 && ((noarch_old_dos_mode & noarch_new_dos_mode) == noarch_old_dos_mode)))
754 *returned_mode = new_mode;
755 else
756 *returned_mode = (mode_t)0;
758 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",
759 path,
760 old_dos_mode, (unsigned int)existing_mode, new_dos_mode, (unsigned int)*returned_mode ));
762 /* If we're mapping SYSTEM and HIDDEN ensure they match. */
763 if (lp_map_system(SNUM(conn)) || lp_store_dos_attributes(SNUM(conn))) {
764 if ((old_dos_mode & FILE_ATTRIBUTE_SYSTEM) && !(new_dos_mode & FILE_ATTRIBUTE_SYSTEM))
765 return False;
767 if (lp_map_hidden(SNUM(conn)) || lp_store_dos_attributes(SNUM(conn))) {
768 if ((old_dos_mode & FILE_ATTRIBUTE_HIDDEN) && !(new_dos_mode & FILE_ATTRIBUTE_HIDDEN))
769 return False;
771 return True;
774 /****************************************************************************
775 Open a file with a share mode.
776 ****************************************************************************/
778 files_struct *open_file_shared(connection_struct *conn,char *fname, SMB_STRUCT_STAT *psbuf,
779 int share_mode,int ofun, uint32 new_dos_mode, int oplock_request,
780 int *Access,int *action)
782 return open_file_shared1(conn, fname, psbuf, 0, share_mode, ofun, new_dos_mode,
783 oplock_request, Access, action);
786 /****************************************************************************
787 Open a file with a share mode.
788 ****************************************************************************/
790 files_struct *open_file_shared1(connection_struct *conn,char *fname, SMB_STRUCT_STAT *psbuf,
791 uint32 desired_access,
792 int share_mode,int ofun, uint32 new_dos_mode,
793 int oplock_request,
794 int *Access,int *paction)
796 int flags=0;
797 int flags2=0;
798 int deny_mode = GET_DENY_MODE(share_mode);
799 BOOL allow_share_delete = GET_ALLOW_SHARE_DELETE(share_mode);
800 BOOL delete_on_close = GET_DELETE_ON_CLOSE_FLAG(share_mode);
801 BOOL file_existed = VALID_STAT(*psbuf);
802 BOOL fcbopen = False;
803 BOOL def_acl = False;
804 SMB_DEV_T dev = 0;
805 SMB_INO_T inode = 0;
806 int num_share_modes = 0;
807 BOOL all_current_opens_are_level_II = False;
808 BOOL fsp_open = False;
809 files_struct *fsp = NULL;
810 int open_mode=0;
811 uint16 port = 0;
812 mode_t new_mode = (mode_t)0;
813 int action;
814 uint32 existing_dos_mode = 0;
815 /* We add aARCH to this as this mode is only used if the file is created new. */
816 mode_t mode = unix_mode(conn,new_dos_mode | aARCH,fname);
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 *paction = FILE_WAS_CREATED;
825 return print_fsp_open(conn, fname);
828 fsp = file_new(conn);
829 if(!fsp)
830 return NULL;
832 DEBUG(10,("open_file_shared: fname = %s, dos_attrs = %x, share_mode = %x, ofun = %x, mode = %o, oplock request = %d\n",
833 fname, new_dos_mode, share_mode, ofun, (int)mode, oplock_request ));
835 if (!check_name(fname,conn)) {
836 file_free(fsp);
837 return NULL;
840 new_dos_mode &= SAMBA_ATTRIBUTES_MASK;
841 if (file_existed) {
842 existing_dos_mode = dos_mode(conn, fname, psbuf);
845 /* ignore any oplock requests if oplocks are disabled */
846 if (!lp_oplocks(SNUM(conn)) || global_client_failed_oplock_break) {
847 oplock_request = 0;
850 /* this is for OS/2 EAs - try and say we don't support them */
851 if (strstr(fname,".+,;=[].")) {
852 unix_ERR_class = ERRDOS;
853 /* OS/2 Workplace shell fix may be main code stream in a later release. */
854 #if 1 /* OS2_WPS_FIX - Recent versions of OS/2 need this. */
855 unix_ERR_code = ERRcannotopen;
856 #else /* OS2_WPS_FIX */
857 unix_ERR_code = ERROR_EAS_NOT_SUPPORTED;
858 #endif /* OS2_WPS_FIX */
860 DEBUG(5,("open_file_shared: OS/2 EA's are not supported.\n"));
861 file_free(fsp);
862 return NULL;
865 if ((GET_FILE_OPEN_DISPOSITION(ofun) == FILE_EXISTS_FAIL) && file_existed) {
866 DEBUG(5,("open_file_shared: create new requested for file %s and file already exists.\n",
867 fname ));
868 file_free(fsp);
869 if (S_ISDIR(psbuf->st_mode)) {
870 errno = EISDIR;
871 } else {
872 errno = EEXIST;
874 return NULL;
877 if (CAN_WRITE(conn) && (GET_FILE_CREATE_DISPOSITION(ofun) == FILE_CREATE_IF_NOT_EXIST))
878 flags2 |= O_CREAT;
880 if (CAN_WRITE(conn) && (GET_FILE_OPEN_DISPOSITION(ofun) == FILE_EXISTS_TRUNCATE))
881 flags2 |= O_TRUNC;
883 /* We only care about matching attributes on file exists and truncate. */
884 if (file_existed && (GET_FILE_OPEN_DISPOSITION(ofun) == FILE_EXISTS_TRUNCATE)) {
885 if (!open_match_attributes(conn, fname, existing_dos_mode, new_dos_mode,
886 psbuf->st_mode, mode, &new_mode)) {
887 DEBUG(5,("open_file_shared: attributes missmatch for file %s (%x %x) (0%o, 0%o)\n",
888 fname, existing_dos_mode, new_dos_mode,
889 (int)psbuf->st_mode, (int)mode ));
890 file_free(fsp);
891 errno = EACCES;
892 return NULL;
896 if (GET_FILE_OPEN_DISPOSITION(ofun) == FILE_EXISTS_FAIL)
897 flags2 |= O_EXCL;
899 /* note that we ignore the append flag as
900 append does not mean the same thing under dos and unix */
902 switch (GET_OPEN_MODE(share_mode)) {
903 case DOS_OPEN_WRONLY:
904 flags = O_WRONLY;
905 if (desired_access == 0)
906 desired_access = FILE_WRITE_DATA;
907 break;
908 case DOS_OPEN_FCB:
909 fcbopen = True;
910 flags = O_RDWR;
911 if (desired_access == 0)
912 desired_access = FILE_READ_DATA|FILE_WRITE_DATA;
913 break;
914 case DOS_OPEN_RDWR:
915 flags = O_RDWR;
916 if (desired_access == 0)
917 desired_access = FILE_READ_DATA|FILE_WRITE_DATA;
918 break;
919 default:
920 flags = O_RDONLY;
921 if (desired_access == 0)
922 desired_access = FILE_READ_DATA;
923 break;
926 #if defined(O_SYNC)
927 if (GET_FILE_SYNC_OPENMODE(share_mode)) {
928 flags2 |= O_SYNC;
930 #endif /* O_SYNC */
932 if (flags != O_RDONLY && file_existed &&
933 (!CAN_WRITE(conn) || IS_DOS_READONLY(existing_dos_mode))) {
934 if (!fcbopen) {
935 DEBUG(5,("open_file_shared: read/write access requested for file %s on read only %s\n",
936 fname, !CAN_WRITE(conn) ? "share" : "file" ));
937 file_free(fsp);
938 errno = EACCES;
939 return NULL;
941 flags = O_RDONLY;
944 if (deny_mode > DENY_NONE && deny_mode!=DENY_FCB) {
945 DEBUG(2,("Invalid deny mode %d on file %s\n",deny_mode,fname));
946 file_free(fsp);
947 errno = EINVAL;
948 return NULL;
951 if (file_existed) {
953 dev = psbuf->st_dev;
954 inode = psbuf->st_ino;
956 lock_share_entry(conn, dev, inode);
958 num_share_modes = open_mode_check(conn, fname, dev, inode,
959 desired_access,
960 share_mode,
961 &flags, &oplock_request, &all_current_opens_are_level_II);
962 if(num_share_modes == -1) {
965 * This next line is a subtlety we need for MS-Access. If a file open will
966 * fail due to share permissions and also for security (access)
967 * reasons, we need to return the access failed error, not the
968 * share error. This means we must attempt to open the file anyway
969 * in order to get the UNIX access error - even if we're going to
970 * fail the open for share reasons. This is bad, as we're burning
971 * another fd if there are existing locks but there's nothing else
972 * we can do. We also ensure we're not going to create or tuncate
973 * the file as we only want an access decision at this stage. JRA.
975 errno = 0;
976 fsp_open = open_file(fsp,conn,fname,psbuf,
977 flags|(flags2&~(O_TRUNC|O_CREAT)),mode,desired_access);
979 DEBUG(4,("open_file_shared : share_mode deny - calling open_file with \
980 flags=0x%X flags2=0x%X mode=0%o returned %d\n",
981 flags,(flags2&~(O_TRUNC|O_CREAT)),(int)mode,(int)fsp_open ));
983 if (!fsp_open && errno) {
984 unix_ERR_class = ERRDOS;
985 unix_ERR_code = ERRnoaccess;
986 unix_ERR_ntstatus = NT_STATUS_ACCESS_DENIED;
989 unlock_share_entry(conn, dev, inode);
990 if (fsp_open)
991 fd_close(conn, fsp);
992 file_free(fsp);
994 * We have detected a sharing violation here
995 * so return the correct error code
997 unix_ERR_class = ERRDOS;
998 unix_ERR_code = ERRbadshare;
999 unix_ERR_ntstatus = NT_STATUS_SHARING_VIOLATION;
1000 return NULL;
1004 * We exit this block with the share entry *locked*.....
1009 * Ensure we pay attention to default ACLs on directories if required.
1012 if ((flags2 & O_CREAT) && lp_inherit_acls(SNUM(conn)) &&
1013 (def_acl = directory_has_default_acl(conn, parent_dirname(fname))))
1014 mode = 0777;
1016 DEBUG(4,("calling open_file with flags=0x%X flags2=0x%X mode=0%o\n",
1017 flags,flags2,(int)mode));
1020 * open_file strips any O_TRUNC flags itself.
1023 fsp_open = open_file(fsp,conn,fname,psbuf,flags|flags2,mode,desired_access);
1025 if (!fsp_open && (flags == O_RDWR) && (errno != ENOENT) && fcbopen) {
1026 if((fsp_open = open_file(fsp,conn,fname,psbuf,O_RDONLY,mode,desired_access)) == True)
1027 flags = O_RDONLY;
1030 if (!fsp_open) {
1031 if(file_existed)
1032 unlock_share_entry(conn, dev, inode);
1033 file_free(fsp);
1034 return NULL;
1038 * Deal with the race condition where two smbd's detect the file doesn't
1039 * exist and do the create at the same time. One of them will win and
1040 * set a share mode, the other (ie. this one) should check if the
1041 * requested share mode for this create is allowed.
1044 if (!file_existed) {
1047 * Now the file exists and fsp is successfully opened,
1048 * fsp->dev and fsp->inode are valid and should replace the
1049 * dev=0,inode=0 from a non existent file. Spotted by
1050 * Nadav Danieli <nadavd@exanet.com>. JRA.
1053 dev = fsp->dev;
1054 inode = fsp->inode;
1056 lock_share_entry_fsp(fsp);
1058 num_share_modes = open_mode_check(conn, fname, dev, inode,
1059 desired_access,
1060 share_mode,
1061 &flags, &oplock_request, &all_current_opens_are_level_II);
1063 if(num_share_modes == -1) {
1064 unlock_share_entry_fsp(fsp);
1065 fd_close(conn,fsp);
1066 file_free(fsp);
1068 * We have detected a sharing violation here, so
1069 * return the correct code.
1071 unix_ERR_class = ERRDOS;
1072 unix_ERR_code = ERRbadshare;
1073 unix_ERR_ntstatus = NT_STATUS_SHARING_VIOLATION;
1074 return NULL;
1078 * If there are any share modes set then the file *did*
1079 * exist. Ensure we return the correct value for action.
1082 if (num_share_modes > 0)
1083 file_existed = True;
1086 * We exit this block with the share entry *locked*.....
1090 /* note that we ignore failure for the following. It is
1091 basically a hack for NFS, and NFS will never set one of
1092 these only read them. Nobody but Samba can ever set a deny
1093 mode and we have already checked our more authoritative
1094 locking database for permission to set this deny mode. If
1095 the kernel refuses the operations then the kernel is wrong */
1096 kernel_flock(fsp, deny_mode);
1099 * At this point onwards, we can guarentee that the share entry
1100 * is locked, whether we created the file or not, and that the
1101 * deny mode is compatible with all current opens.
1105 * If requested, truncate the file.
1108 if (flags2&O_TRUNC) {
1110 * We are modifing the file after open - update the stat struct..
1112 if ((truncate_unless_locked(conn,fsp) == -1) || (SMB_VFS_FSTAT(fsp,fsp->fd,psbuf)==-1)) {
1113 unlock_share_entry_fsp(fsp);
1114 fd_close(conn,fsp);
1115 file_free(fsp);
1116 return NULL;
1120 switch (flags) {
1121 case O_RDONLY:
1122 open_mode = DOS_OPEN_RDONLY;
1123 break;
1124 case O_RDWR:
1125 open_mode = DOS_OPEN_RDWR;
1126 break;
1127 case O_WRONLY:
1128 open_mode = DOS_OPEN_WRONLY;
1129 break;
1132 fsp->share_mode = SET_DENY_MODE(deny_mode) |
1133 SET_OPEN_MODE(open_mode) |
1134 SET_ALLOW_SHARE_DELETE(allow_share_delete);
1136 DEBUG(10,("open_file_shared : share_mode = %x\n", fsp->share_mode ));
1138 if (Access) {
1139 (*Access) = open_mode;
1142 if (file_existed && !(flags2 & O_TRUNC))
1143 action = FILE_WAS_OPENED;
1144 if (file_existed && (flags2 & O_TRUNC))
1145 action = FILE_WAS_OVERWRITTEN;
1146 if (!file_existed)
1147 action = FILE_WAS_CREATED;
1149 if (paction) {
1150 *paction = action;
1154 * Setup the oplock info in both the shared memory and
1155 * file structs.
1158 if(oplock_request && (num_share_modes == 0) &&
1159 !IS_VETO_OPLOCK_PATH(conn,fname) && set_file_oplock(fsp, oplock_request) ) {
1160 port = global_oplock_port;
1161 } else if (oplock_request && all_current_opens_are_level_II) {
1162 port = global_oplock_port;
1163 oplock_request = LEVEL_II_OPLOCK;
1164 set_file_oplock(fsp, oplock_request);
1165 } else {
1166 port = 0;
1167 oplock_request = 0;
1170 set_share_mode(fsp, port, oplock_request);
1172 if (delete_on_close) {
1173 NTSTATUS result = set_delete_on_close_internal(fsp, delete_on_close);
1175 if (NT_STATUS_V(result) != NT_STATUS_V(NT_STATUS_OK)) {
1176 /* Remember to delete the mode we just added. */
1177 del_share_mode(fsp, NULL);
1178 unlock_share_entry_fsp(fsp);
1179 fd_close(conn,fsp);
1180 file_free(fsp);
1181 return NULL;
1185 if (action == FILE_WAS_OVERWRITTEN || action == FILE_WAS_CREATED) {
1186 /* Files should be initially set as archive */
1187 if (lp_map_archive(SNUM(conn)) || lp_store_dos_attributes(SNUM(conn))) {
1188 file_set_dosmode(conn, fname, new_dos_mode | aARCH, NULL);
1193 * Take care of inherited ACLs on created files - if default ACL not
1194 * selected.
1197 if (!file_existed && !def_acl) {
1199 int saved_errno = errno; /* We might get ENOSYS in the next call.. */
1201 if (SMB_VFS_FCHMOD_ACL(fsp, fsp->fd, mode) == -1 && errno == ENOSYS)
1202 errno = saved_errno; /* Ignore ENOSYS */
1204 } else if (new_mode) {
1206 int ret = -1;
1208 /* Attributes need changing. File already existed. */
1211 int saved_errno = errno; /* We might get ENOSYS in the next call.. */
1212 ret = SMB_VFS_FCHMOD_ACL(fsp, fsp->fd, new_mode);
1214 if (ret == -1 && errno == ENOSYS) {
1215 errno = saved_errno; /* Ignore ENOSYS */
1216 } else {
1217 DEBUG(5, ("open_file_shared: failed to reset attributes of file %s to 0%o\n",
1218 fname, (int)new_mode));
1219 ret = 0; /* Don't do the fchmod below. */
1223 if ((ret == -1) && (SMB_VFS_FCHMOD(fsp, fsp->fd, new_mode) == -1))
1224 DEBUG(5, ("open_file_shared: failed to reset attributes of file %s to 0%o\n",
1225 fname, (int)new_mode));
1228 unlock_share_entry_fsp(fsp);
1230 conn->num_files_open++;
1232 return fsp;
1235 /****************************************************************************
1236 Open a file for for write to ensure that we can fchmod it.
1237 ****************************************************************************/
1239 files_struct *open_file_fchmod(connection_struct *conn, const char *fname, SMB_STRUCT_STAT *psbuf)
1241 files_struct *fsp = NULL;
1242 BOOL fsp_open;
1244 if (!VALID_STAT(*psbuf))
1245 return NULL;
1247 fsp = file_new(conn);
1248 if(!fsp)
1249 return NULL;
1251 /* note! we must use a non-zero desired access or we don't get
1252 a real file descriptor. Oh what a twisted web we weave. */
1253 fsp_open = open_file(fsp,conn,fname,psbuf,O_WRONLY,0,FILE_WRITE_DATA);
1256 * This is not a user visible file open.
1257 * Don't set a share mode and don't increment
1258 * the conn->num_files_open.
1261 if (!fsp_open) {
1262 file_free(fsp);
1263 return NULL;
1266 return fsp;
1269 /****************************************************************************
1270 Close the fchmod file fd - ensure no locks are lost.
1271 ****************************************************************************/
1273 int close_file_fchmod(files_struct *fsp)
1275 int ret = fd_close(fsp->conn, fsp);
1276 file_free(fsp);
1277 return ret;
1280 /****************************************************************************
1281 Open a directory from an NT SMB call.
1282 ****************************************************************************/
1284 files_struct *open_directory(connection_struct *conn, char *fname, SMB_STRUCT_STAT *psbuf,
1285 uint32 desired_access, int share_mode, int smb_ofun, int *action)
1287 extern struct current_user current_user;
1288 BOOL got_stat = False;
1289 files_struct *fsp = file_new(conn);
1290 BOOL delete_on_close = GET_DELETE_ON_CLOSE_FLAG(share_mode);
1292 if(!fsp)
1293 return NULL;
1295 if (VALID_STAT(*psbuf))
1296 got_stat = True;
1298 if (got_stat && (GET_FILE_OPEN_DISPOSITION(smb_ofun) == FILE_EXISTS_FAIL)) {
1299 file_free(fsp);
1300 errno = EEXIST; /* Setup so correct error is returned to client. */
1301 return NULL;
1304 if (GET_FILE_CREATE_DISPOSITION(smb_ofun) == FILE_CREATE_IF_NOT_EXIST) {
1306 if (got_stat) {
1308 if(!S_ISDIR(psbuf->st_mode)) {
1309 DEBUG(0,("open_directory: %s is not a directory !\n", fname ));
1310 file_free(fsp);
1311 errno = EACCES;
1312 return NULL;
1314 *action = FILE_WAS_OPENED;
1316 } else {
1319 * Try and create the directory.
1322 if(!CAN_WRITE(conn)) {
1323 DEBUG(2,("open_directory: failing create on read-only share\n"));
1324 file_free(fsp);
1325 errno = EACCES;
1326 return NULL;
1329 if (ms_has_wild(fname)) {
1330 file_free(fsp);
1331 DEBUG(5,("open_directory: failing create on filename %s with wildcards\n", fname));
1332 unix_ERR_class = ERRDOS;
1333 unix_ERR_code = ERRinvalidname;
1334 unix_ERR_ntstatus = NT_STATUS_OBJECT_NAME_INVALID;
1335 return NULL;
1338 if( strchr_m(fname, ':')) {
1339 file_free(fsp);
1340 DEBUG(5,("open_directory: failing create on filename %s with colon in name\n", fname));
1341 unix_ERR_class = ERRDOS;
1342 unix_ERR_code = ERRinvalidname;
1343 unix_ERR_ntstatus = NT_STATUS_NOT_A_DIRECTORY;
1344 return NULL;
1347 if(vfs_MkDir(conn,fname, unix_mode(conn,aDIR, fname)) < 0) {
1348 DEBUG(2,("open_directory: unable to create %s. Error was %s\n",
1349 fname, strerror(errno) ));
1350 file_free(fsp);
1351 return NULL;
1354 if(SMB_VFS_STAT(conn,fname, psbuf) != 0) {
1355 file_free(fsp);
1356 return NULL;
1359 *action = FILE_WAS_CREATED;
1362 } else {
1365 * Don't create - just check that it *was* a directory.
1368 if(!got_stat) {
1369 DEBUG(3,("open_directory: unable to stat name = %s. Error was %s\n",
1370 fname, strerror(errno) ));
1371 file_free(fsp);
1372 return NULL;
1375 if(!S_ISDIR(psbuf->st_mode)) {
1376 DEBUG(0,("open_directory: %s is not a directory !\n", fname ));
1377 file_free(fsp);
1378 return NULL;
1381 *action = FILE_WAS_OPENED;
1384 DEBUG(5,("open_directory: opening directory %s\n", fname));
1387 * Setup the files_struct for it.
1390 fsp->mode = psbuf->st_mode;
1391 fsp->inode = psbuf->st_ino;
1392 fsp->dev = psbuf->st_dev;
1393 fsp->size = psbuf->st_size;
1394 fsp->vuid = current_user.vuid;
1395 fsp->file_pid = global_smbpid;
1396 fsp->can_lock = True;
1397 fsp->can_read = False;
1398 fsp->can_write = False;
1399 fsp->share_mode = share_mode;
1400 fsp->desired_access = desired_access;
1401 fsp->print_file = False;
1402 fsp->modified = False;
1403 fsp->oplock_type = NO_OPLOCK;
1404 fsp->sent_oplock_break = NO_BREAK_SENT;
1405 fsp->is_directory = True;
1406 fsp->is_stat = False;
1407 fsp->directory_delete_on_close = False;
1408 string_set(&fsp->fsp_name,fname);
1410 if (delete_on_close) {
1411 NTSTATUS result = set_delete_on_close_internal(fsp, delete_on_close);
1413 if (NT_STATUS_V(result) != NT_STATUS_V(NT_STATUS_OK)) {
1414 file_free(fsp);
1415 return NULL;
1418 conn->num_files_open++;
1420 return fsp;
1423 /****************************************************************************
1424 Open a pseudo-file (no locking checks - a 'stat' open).
1425 ****************************************************************************/
1427 files_struct *open_file_stat(connection_struct *conn, char *fname, SMB_STRUCT_STAT *psbuf)
1429 extern struct current_user current_user;
1430 files_struct *fsp = NULL;
1432 if (!VALID_STAT(*psbuf))
1433 return NULL;
1435 /* Can't 'stat' open directories. */
1436 if(S_ISDIR(psbuf->st_mode))
1437 return NULL;
1439 fsp = file_new(conn);
1440 if(!fsp)
1441 return NULL;
1443 DEBUG(5,("open_file_stat: 'opening' file %s\n", fname));
1446 * Setup the files_struct for it.
1449 fsp->mode = psbuf->st_mode;
1451 * Don't store dev or inode, we don't want any iterator
1452 * to see this.
1454 fsp->inode = (SMB_INO_T)0;
1455 fsp->dev = (SMB_DEV_T)0;
1456 fsp->size = psbuf->st_size;
1457 fsp->vuid = current_user.vuid;
1458 fsp->file_pid = global_smbpid;
1459 fsp->can_lock = False;
1460 fsp->can_read = False;
1461 fsp->can_write = False;
1462 fsp->share_mode = 0;
1463 fsp->desired_access = 0;
1464 fsp->print_file = False;
1465 fsp->modified = False;
1466 fsp->oplock_type = NO_OPLOCK;
1467 fsp->sent_oplock_break = NO_BREAK_SENT;
1468 fsp->is_directory = False;
1469 fsp->is_stat = True;
1470 fsp->directory_delete_on_close = False;
1471 string_set(&fsp->fsp_name,fname);
1473 conn->num_files_open++;
1475 return fsp;