port latest changes from SAMBA_3_0 tree
[Samba.git] / source3 / smbd / open.c
blob5f49640aa496e306986ba57f4bf944e9b47a97b3
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 BOOL global_client_failed_oplock_break;
28 /****************************************************************************
29 fd support routines - attempt to do a dos_open.
30 ****************************************************************************/
32 static int fd_open(struct connection_struct *conn, char *fname,
33 int flags, mode_t mode)
35 int fd;
36 #ifdef O_NOFOLLOW
37 if (!lp_symlinks(SNUM(conn)))
38 flags |= O_NOFOLLOW;
39 #endif
41 fd = SMB_VFS_OPEN(conn,fname,flags,mode);
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);
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) : "" ));
53 return fd;
56 /****************************************************************************
57 Close the file associated with a fsp.
58 ****************************************************************************/
60 int fd_close(struct connection_struct *conn, files_struct *fsp)
62 if (fsp->fd == -1)
63 return 0; /* what we used to call a stat open. */
64 return fd_close_posix(conn, fsp);
68 /****************************************************************************
69 Check a filename for the pipe string.
70 ****************************************************************************/
72 static void check_for_pipe(char *fname)
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;
86 /****************************************************************************
87 Open a file.
88 ****************************************************************************/
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)
93 extern struct current_user current_user;
94 pstring fname;
95 int accmode = (flags & O_ACCMODE);
96 int local_flags = flags;
98 fsp->fd = -1;
99 fsp->oplock_type = NO_OPLOCK;
100 errno = EPERM;
102 pstrcpy(fname,fname1);
104 /* Check permissions */
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.
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.
127 flags &= ~O_CREAT;
128 local_flags &= ~O_CREAT;
133 * This little piece of insanity is inspired by the
134 * fact that an NT client can open a file for O_RDONLY,
135 * but set the create disposition to FILE_EXISTS_TRUNCATE.
136 * If the client *can* write to the file, then it expects to
137 * truncate the file, even though it is opening for readonly.
138 * Quicken uses this stupid trick in backup file creation...
139 * Thanks *greatly* to "David W. Chapman Jr." <dwcjr@inethouston.net>
140 * for helping track this one down. It didn't bite us in 2.0.x
141 * as we always opened files read-write in that release. JRA.
144 if ((accmode == O_RDONLY) && ((flags & O_TRUNC) == O_TRUNC)) {
145 DEBUG(10,("open_file: truncate requested on read-only open for file %s\n",fname ));
146 local_flags = (flags & ~O_ACCMODE)|O_RDWR;
149 if ((desired_access & (FILE_READ_DATA|FILE_WRITE_DATA|FILE_APPEND_DATA|FILE_EXECUTE)) ||
150 (local_flags & O_CREAT) || ((local_flags & O_TRUNC) == O_TRUNC) ) {
153 * We can't actually truncate here as the file may be locked.
154 * open_file_shared will take care of the truncate later. JRA.
157 local_flags &= ~O_TRUNC;
159 #if defined(O_NONBLOCK) && defined(S_ISFIFO)
161 * We would block on opening a FIFO with no one else on the
162 * other end. Do what we used to do and add O_NONBLOCK to the
163 * open flags. JRA.
166 if (VALID_STAT(*psbuf) && S_ISFIFO(psbuf->st_mode))
167 local_flags |= O_NONBLOCK;
168 #endif
170 /* Don't create files with Microsoft wildcard characters. */
171 if ((local_flags & O_CREAT) && !VALID_STAT(*psbuf) && ms_has_wild(fname)) {
172 unix_ERR_class = ERRDOS;
173 unix_ERR_code = ERRinvalidname;
174 unix_ERR_ntstatus = NT_STATUS_OBJECT_NAME_INVALID;
175 return False;
178 /* Actually do the open */
179 fsp->fd = fd_open(conn, fname, local_flags, mode);
180 if (fsp->fd == -1) {
181 DEBUG(3,("Error opening file %s (%s) (local_flags=%d) (flags=%d)\n",
182 fname,strerror(errno),local_flags,flags));
183 check_for_pipe(fname);
184 return False;
187 /* Inherit the ACL if the file was created. */
188 if ((local_flags & O_CREAT) && !VALID_STAT(*psbuf))
189 inherit_access_acl(conn, fname, mode);
191 } else
192 fsp->fd = -1; /* What we used to call a stat open. */
194 if (!VALID_STAT(*psbuf)) {
195 int ret;
197 if (fsp->fd == -1)
198 ret = SMB_VFS_STAT(conn, fname, psbuf);
199 else {
200 ret = SMB_VFS_FSTAT(fsp,fsp->fd,psbuf);
201 /* If we have an fd, this stat should succeed. */
202 if (ret == -1)
203 DEBUG(0,("Error doing fstat on open file %s (%s)\n", fname,strerror(errno) ));
206 /* For a non-io open, this stat failing means file not found. JRA */
207 if (ret == -1) {
208 fd_close(conn, fsp);
209 return False;
214 * POSIX allows read-only opens of directories. We don't
215 * want to do this (we use a different code path for this)
216 * so catch a directory open and return an EISDIR. JRA.
219 if(S_ISDIR(psbuf->st_mode)) {
220 fd_close(conn, fsp);
221 errno = EISDIR;
222 return False;
225 fsp->mode = psbuf->st_mode;
226 fsp->inode = psbuf->st_ino;
227 fsp->dev = psbuf->st_dev;
228 fsp->vuid = current_user.vuid;
229 fsp->size = psbuf->st_size;
230 fsp->pos = -1;
231 fsp->can_lock = True;
232 fsp->can_read = ((flags & O_WRONLY)==0);
233 fsp->can_write = ((flags & (O_WRONLY|O_RDWR))!=0);
234 fsp->share_mode = 0;
235 fsp->desired_access = desired_access;
236 fsp->print_file = False;
237 fsp->modified = False;
238 fsp->oplock_type = NO_OPLOCK;
239 fsp->sent_oplock_break = NO_BREAK_SENT;
240 fsp->is_directory = False;
241 fsp->is_stat = False;
242 fsp->directory_delete_on_close = False;
243 string_set(&fsp->fsp_name,fname);
244 fsp->wcp = NULL; /* Write cache pointer. */
246 DEBUG(2,("%s opened file %s read=%s write=%s (numopen=%d)\n",
247 *current_user_info.smb_name ? current_user_info.smb_name : conn->user,fsp->fsp_name,
248 BOOLSTR(fsp->can_read), BOOLSTR(fsp->can_write),
249 conn->num_files_open + 1));
251 return True;
254 /****************************************************************************
255 C. Hoch 11/22/95
256 Helper for open_file_shared.
257 Truncate a file after checking locking; close file if locked.
258 **************************************************************************/
260 static int truncate_unless_locked(struct connection_struct *conn, files_struct *fsp)
262 SMB_BIG_UINT mask = (SMB_BIG_UINT)-1;
264 if (is_locked(fsp,fsp->conn,mask,0,WRITE_LOCK,True)){
265 errno = EACCES;
266 unix_ERR_class = ERRDOS;
267 unix_ERR_code = ERRlock;
268 unix_ERR_ntstatus = dos_to_ntstatus(ERRDOS, ERRlock);
269 return -1;
270 } else {
271 return SMB_VFS_FTRUNCATE(fsp,fsp->fd,0);
275 /*******************************************************************
276 return True if the filename is one of the special executable types
277 ********************************************************************/
278 static BOOL is_executable(const char *fname)
280 if ((fname = strrchr_m(fname,'.'))) {
281 if (strequal(fname,".com") ||
282 strequal(fname,".dll") ||
283 strequal(fname,".exe") ||
284 strequal(fname,".sym")) {
285 return True;
288 return False;
291 enum {AFAIL,AREAD,AWRITE,AALL};
293 /*******************************************************************
294 reproduce the share mode access table
295 this is horrendoously complex, and really can't be justified on any
296 rational grounds except that this is _exactly_ what NT does. See
297 the DENY1 and DENY2 tests in smbtorture for a comprehensive set of
298 test routines.
299 ********************************************************************/
300 static int access_table(int new_deny,int old_deny,int old_mode,
301 BOOL same_pid, BOOL isexe)
303 if (new_deny == DENY_ALL || old_deny == DENY_ALL) return(AFAIL);
305 if (same_pid) {
306 if (isexe && old_mode == DOS_OPEN_RDONLY &&
307 old_deny == DENY_DOS && new_deny == DENY_READ) {
308 return AFAIL;
310 if (!isexe && old_mode == DOS_OPEN_RDONLY &&
311 old_deny == DENY_DOS && new_deny == DENY_DOS) {
312 return AREAD;
314 if (new_deny == DENY_FCB && old_deny == DENY_DOS) {
315 if (isexe) return AFAIL;
316 if (old_mode == DOS_OPEN_RDONLY) return AFAIL;
317 return AALL;
319 if (old_mode == DOS_OPEN_RDONLY && old_deny == DENY_DOS) {
320 if (new_deny == DENY_FCB || new_deny == DENY_READ) {
321 if (isexe) return AREAD;
322 return AFAIL;
325 if (old_deny == DENY_FCB) {
326 if (new_deny == DENY_DOS || new_deny == DENY_FCB) return AALL;
327 return AFAIL;
331 if (old_deny == DENY_DOS || new_deny == DENY_DOS ||
332 old_deny == DENY_FCB || new_deny == DENY_FCB) {
333 if (isexe) {
334 if (old_deny == DENY_FCB || new_deny == DENY_FCB) {
335 return AFAIL;
337 if (old_deny == DENY_DOS) {
338 if (new_deny == DENY_READ &&
339 (old_mode == DOS_OPEN_RDONLY ||
340 old_mode == DOS_OPEN_RDWR)) {
341 return AFAIL;
343 if (new_deny == DENY_WRITE &&
344 (old_mode == DOS_OPEN_WRONLY ||
345 old_mode == DOS_OPEN_RDWR)) {
346 return AFAIL;
348 return AALL;
350 if (old_deny == DENY_NONE) return AALL;
351 if (old_deny == DENY_READ) return AWRITE;
352 if (old_deny == DENY_WRITE) return AREAD;
354 /* it isn't a exe, dll, sym or com file */
355 if (old_deny == new_deny && same_pid)
356 return(AALL);
358 if (old_deny == DENY_READ || new_deny == DENY_READ) return AFAIL;
359 if (old_mode == DOS_OPEN_RDONLY) return(AREAD);
361 return(AFAIL);
364 switch (new_deny)
366 case DENY_WRITE:
367 if (old_deny==DENY_WRITE && old_mode==DOS_OPEN_RDONLY) return(AREAD);
368 if (old_deny==DENY_READ && old_mode==DOS_OPEN_RDONLY) return(AWRITE);
369 if (old_deny==DENY_NONE && old_mode==DOS_OPEN_RDONLY) return(AALL);
370 return(AFAIL);
371 case DENY_READ:
372 if (old_deny==DENY_WRITE && old_mode==DOS_OPEN_WRONLY) return(AREAD);
373 if (old_deny==DENY_READ && old_mode==DOS_OPEN_WRONLY) return(AWRITE);
374 if (old_deny==DENY_NONE && old_mode==DOS_OPEN_WRONLY) return(AALL);
375 return(AFAIL);
376 case DENY_NONE:
377 if (old_deny==DENY_WRITE) return(AREAD);
378 if (old_deny==DENY_READ) return(AWRITE);
379 if (old_deny==DENY_NONE) return(AALL);
380 return(AFAIL);
382 return(AFAIL);
386 /****************************************************************************
387 check if we can open a file with a share mode
388 ****************************************************************************/
390 static BOOL check_share_mode(connection_struct *conn, share_mode_entry *share, int share_mode, uint32 desired_access,
391 const char *fname, BOOL fcbopen, int *flags)
393 int deny_mode = GET_DENY_MODE(share_mode);
394 int old_open_mode = GET_OPEN_MODE(share->share_mode);
395 int old_deny_mode = GET_DENY_MODE(share->share_mode);
398 * share modes = false means don't bother to check for
399 * DENY mode conflict. This is a *really* bad idea :-). JRA.
402 if(!lp_share_modes(SNUM(conn)))
403 return True;
406 * Don't allow any opens once the delete on close flag has been
407 * set.
410 if (GET_DELETE_ON_CLOSE_FLAG(share->share_mode)) {
411 DEBUG(5,("check_share_mode: Failing open on file %s as delete on close flag is set.\n",
412 fname ));
413 /* Use errno to map to correct error. */
414 unix_ERR_class = SMB_SUCCESS;
415 unix_ERR_code = 0;
416 unix_ERR_ntstatus = NT_STATUS_OK;
417 return False;
420 /* this is a nasty hack, but necessary until we rewrite our open
421 handling to use a NTCreateX call as the basic call.
422 NT may open a file with neither read nor write access, and in
423 this case it expects the open not to conflict with any
424 existing deny modes. This happens (for example) during a
425 "xcopy /o" where the second file descriptor is used for
426 ACL sets
427 (tridge)
431 * This is a bit wierd - the test for desired access not having the
432 * critical bits seems seems odd. Firstly, if both opens have no
433 * critical bits then always ignore. Then check the "allow delete"
434 * then check for either. This probably isn't quite right yet but
435 * gets us much closer. JRA.
439 * If desired_access doesn't contain READ_DATA,WRITE_DATA,APPEND_DATA or EXECUTE
440 * and the existing desired_acces then share modes don't conflict.
443 if ( !(desired_access & (FILE_READ_DATA|FILE_WRITE_DATA|FILE_APPEND_DATA|FILE_EXECUTE)) &&
444 !(share->desired_access & (FILE_READ_DATA|FILE_WRITE_DATA|FILE_APPEND_DATA|FILE_EXECUTE)) ) {
447 * Wrinkle discovered by smbtorture....
448 * If both are non-io open and requester is asking for delete and current open has delete access
449 * but neither open has allowed file share delete then deny.... this is very strange and
450 * seems to be the only case in which non-io opens conflict. JRA.
453 if ((desired_access & DELETE_ACCESS) && (share->desired_access & DELETE_ACCESS) &&
454 (!GET_ALLOW_SHARE_DELETE(share->share_mode) || !GET_ALLOW_SHARE_DELETE(share_mode))) {
455 DEBUG(5,("check_share_mode: Failing open on file %s as delete access requests conflict.\n",
456 fname ));
457 unix_ERR_class = ERRDOS;
458 unix_ERR_code = ERRbadshare;
459 unix_ERR_ntstatus = NT_STATUS_SHARING_VIOLATION;
461 return False;
464 DEBUG(5,("check_share_mode: Allowing open on file %s as both desired access (0x%x) \
465 and existing desired access (0x%x) are non-data opens\n",
466 fname, (unsigned int)desired_access, (unsigned int)share->desired_access ));
467 return True;
471 * If delete access was requested and the existing share mode doesn't have
472 * ALLOW_SHARE_DELETE then deny.
475 if ((desired_access & DELETE_ACCESS) && !GET_ALLOW_SHARE_DELETE(share->share_mode)) {
476 DEBUG(5,("check_share_mode: Failing open on file %s as delete access requested and allow share delete not set.\n",
477 fname ));
478 unix_ERR_class = ERRDOS;
479 unix_ERR_code = ERRbadshare;
480 unix_ERR_ntstatus = NT_STATUS_SHARING_VIOLATION;
482 return False;
486 * The inverse of the above.
487 * If delete access was granted and the new share mode doesn't have
488 * ALLOW_SHARE_DELETE then deny.
491 if ((share->desired_access & DELETE_ACCESS) && !GET_ALLOW_SHARE_DELETE(share_mode)) {
492 DEBUG(5,("check_share_mode: Failing open on file %s as delete access granted and allow share delete not requested.\n",
493 fname ));
494 unix_ERR_class = ERRDOS;
495 unix_ERR_code = ERRbadshare;
496 unix_ERR_ntstatus = NT_STATUS_SHARING_VIOLATION;
498 return False;
502 * If desired_access doesn't contain READ_DATA,WRITE_DATA,APPEND_DATA or EXECUTE
503 * then share modes don't conflict. Likewise with existing desired access.
506 if ( !(desired_access & (FILE_READ_DATA|FILE_WRITE_DATA|FILE_APPEND_DATA|FILE_EXECUTE)) ||
507 !(share->desired_access & (FILE_READ_DATA|FILE_WRITE_DATA|FILE_APPEND_DATA|FILE_EXECUTE)) ) {
508 DEBUG(5,("check_share_mode: Allowing open on file %s as desired access (0x%x) doesn't conflict with\
509 existing desired access (0x%x).\n", fname, (unsigned int)desired_access, (unsigned int)share->desired_access ));
510 return True;
514 int access_allowed = access_table(deny_mode,old_deny_mode,old_open_mode,
515 (share->pid == sys_getpid()),is_executable(fname));
517 if ((access_allowed == AFAIL) ||
518 (!fcbopen && (access_allowed == AREAD && *flags == O_RDWR)) ||
519 (access_allowed == AREAD && *flags != O_RDONLY) ||
520 (access_allowed == AWRITE && *flags != O_WRONLY)) {
522 DEBUG(2,("Share violation on file (%d,%d,%d,%d,%s,fcbopen = %d, flags = %d) = %d\n",
523 deny_mode,old_deny_mode,old_open_mode,
524 (int)share->pid,fname, fcbopen, *flags, access_allowed));
526 unix_ERR_class = ERRDOS;
527 unix_ERR_code = ERRbadshare;
528 unix_ERR_ntstatus = NT_STATUS_SHARING_VIOLATION;
530 return False;
533 if (access_allowed == AREAD)
534 *flags = O_RDONLY;
536 if (access_allowed == AWRITE)
537 *flags = O_WRONLY;
541 return True;
545 #if defined(DEVELOPER)
546 static void validate_my_share_entries(int num, share_mode_entry *share_entry)
548 files_struct *fsp;
550 if (share_entry->pid != sys_getpid())
551 return;
553 fsp = file_find_dif(share_entry->dev, share_entry->inode, share_entry->share_file_id);
554 if (!fsp) {
555 DEBUG(0,("validate_my_share_entries: PANIC : %s\n", share_mode_str(num, share_entry) ));
556 smb_panic("validate_my_share_entries: Cannot match a share entry with an open file\n");
559 if (((uint16)fsp->oplock_type) != share_entry->op_type) {
560 pstring str;
561 DEBUG(0,("validate_my_share_entries: PANIC : %s\n", share_mode_str(num, share_entry) ));
562 slprintf(str, sizeof(str)-1, "validate_my_share_entries: file %s, oplock_type = 0x%x, op_type = 0x%x\n",
563 fsp->fsp_name, (unsigned int)fsp->oplock_type, (unsigned int)share_entry->op_type );
564 smb_panic(str);
567 #endif
569 /****************************************************************************
570 Deal with open deny mode and oplock break processing.
571 Invarient: Share mode must be locked on entry and exit.
572 Returns -1 on error, or number of share modes on success (may be zero).
573 ****************************************************************************/
575 static int open_mode_check(connection_struct *conn, const char *fname, SMB_DEV_T dev,
576 SMB_INO_T inode,
577 uint32 desired_access,
578 int share_mode, int *p_flags, int *p_oplock_request,
579 BOOL *p_all_current_opens_are_level_II)
581 int i;
582 int num_share_modes;
583 int oplock_contention_count = 0;
584 share_mode_entry *old_shares = 0;
585 BOOL fcbopen = False;
586 BOOL broke_oplock;
588 if(GET_OPEN_MODE(share_mode) == DOS_OPEN_FCB)
589 fcbopen = True;
591 num_share_modes = get_share_modes(conn, dev, inode, &old_shares);
593 if(num_share_modes == 0)
594 return 0;
597 * Check if the share modes will give us access.
600 do {
601 share_mode_entry broken_entry;
603 broke_oplock = False;
604 *p_all_current_opens_are_level_II = True;
606 for(i = 0; i < num_share_modes; i++) {
607 share_mode_entry *share_entry = &old_shares[i];
609 #if defined(DEVELOPER)
610 validate_my_share_entries(i, share_entry);
611 #endif
614 * By observation of NetBench, oplocks are broken *before* share
615 * modes are checked. This allows a file to be closed by the client
616 * if the share mode would deny access and the client has an oplock.
617 * Check if someone has an oplock on this file. If so we must break
618 * it before continuing.
621 if((*p_oplock_request && EXCLUSIVE_OPLOCK_TYPE(share_entry->op_type)) ||
622 (!*p_oplock_request && (share_entry->op_type != NO_OPLOCK))) {
624 BOOL opb_ret;
626 DEBUG(5,("open_mode_check: oplock_request = %d, breaking oplock (%x) on file %s, \
627 dev = %x, inode = %.0f\n", *p_oplock_request, share_entry->op_type, fname, (unsigned int)dev, (double)inode));
629 /* Oplock break - unlock to request it. */
630 unlock_share_entry(conn, dev, inode);
632 opb_ret = request_oplock_break(share_entry, False);
634 /* Now relock. */
635 lock_share_entry(conn, dev, inode);
637 if(opb_ret == False) {
638 DEBUG(0,("open_mode_check: FAILED when breaking oplock (%x) on file %s, \
639 dev = %x, inode = %.0f\n", old_shares[i].op_type, fname, (unsigned int)dev, (double)inode));
640 SAFE_FREE(old_shares);
641 errno = EACCES;
642 unix_ERR_class = ERRDOS;
643 unix_ERR_code = ERRbadshare;
644 unix_ERR_ntstatus = NT_STATUS_SHARING_VIOLATION;
645 return -1;
648 broke_oplock = True;
649 broken_entry = *share_entry;
650 break;
652 } else if (!LEVEL_II_OPLOCK_TYPE(share_entry->op_type)) {
653 *p_all_current_opens_are_level_II = False;
656 /* someone else has a share lock on it, check to see if we can too */
657 if (!check_share_mode(conn, share_entry, share_mode, desired_access,
658 fname, fcbopen, p_flags)) {
659 SAFE_FREE(old_shares);
660 errno = EACCES;
661 return -1;
664 } /* end for */
666 if(broke_oplock) {
667 SAFE_FREE(old_shares);
668 num_share_modes = get_share_modes(conn, dev, inode, &old_shares);
669 oplock_contention_count++;
671 /* Paranoia check that this is no longer an exlusive entry. */
672 for(i = 0; i < num_share_modes; i++) {
673 share_mode_entry *share_entry = &old_shares[i];
675 if (share_modes_identical(&broken_entry, share_entry) &&
676 EXCLUSIVE_OPLOCK_TYPE(share_entry->op_type) ) {
679 * This should not happen. The target left this oplock
680 * as exlusive.... The process *must* be dead....
683 DEBUG(0,("open_mode_check: exlusive oplock left by process %d after break ! For file %s, \
684 dev = %x, inode = %.0f. Deleting it to continue...\n", (int)broken_entry.pid, fname, (unsigned int)dev, (double)inode));
686 if (process_exists(broken_entry.pid)) {
687 DEBUG(0,("open_mode_check: Existent process %lu left active oplock.\n",
688 (unsigned long)broken_entry.pid ));
691 if (del_share_entry(dev, inode, &broken_entry, NULL) == -1) {
692 errno = EACCES;
693 unix_ERR_class = ERRDOS;
694 unix_ERR_code = ERRbadshare;
695 unix_ERR_ntstatus = NT_STATUS_SHARING_VIOLATION;
696 return -1;
700 * We must reload the share modes after deleting the
701 * other process's entry.
704 SAFE_FREE(old_shares);
705 num_share_modes = get_share_modes(conn, dev, inode, &old_shares);
706 break;
708 } /* end for paranoia... */
709 } /* end if broke_oplock */
711 } while(broke_oplock);
713 if(old_shares != 0)
714 SAFE_FREE(old_shares);
717 * Refuse to grant an oplock in case the contention limit is
718 * reached when going through the lock list multiple times.
721 if(oplock_contention_count >= lp_oplock_contention_limit(SNUM(conn))) {
722 *p_oplock_request = 0;
723 DEBUG(4,("open_mode_check: oplock contention = %d. Not granting oplock.\n",
724 oplock_contention_count ));
727 return num_share_modes;
730 /****************************************************************************
731 set a kernel flock on a file for NFS interoperability
732 this requires a patch to Linux
733 ****************************************************************************/
734 static void kernel_flock(files_struct *fsp, int deny_mode)
736 #if HAVE_KERNEL_SHARE_MODES
737 int kernel_mode = 0;
738 if (deny_mode == DENY_READ) kernel_mode = LOCK_MAND|LOCK_WRITE;
739 else if (deny_mode == DENY_WRITE) kernel_mode = LOCK_MAND|LOCK_READ;
740 else if (deny_mode == DENY_ALL) kernel_mode = LOCK_MAND;
741 if (kernel_mode) flock(fsp->fd, kernel_mode);
742 #endif
747 static BOOL open_match_attributes(connection_struct *conn, char *path, mode_t existing_mode,
748 mode_t new_mode, mode_t *returned_mode)
750 uint32 old_dos_mode, new_dos_mode;
751 uint32 noarch_old_dos_mode, noarch_new_dos_mode;
752 SMB_STRUCT_STAT sbuf;
754 ZERO_STRUCT(sbuf);
756 sbuf.st_mode = existing_mode;
757 old_dos_mode = dos_mode(conn, path, &sbuf);
759 sbuf.st_mode = new_mode;
760 new_dos_mode = dos_mode(conn, path, &sbuf);
762 noarch_old_dos_mode = (old_dos_mode & ~FILE_ATTRIBUTE_ARCHIVE);
763 noarch_new_dos_mode = (new_dos_mode & ~FILE_ATTRIBUTE_ARCHIVE);
765 if((noarch_old_dos_mode == 0 && noarch_new_dos_mode != 0) ||
766 (noarch_old_dos_mode != 0 && ((noarch_old_dos_mode & noarch_new_dos_mode) == noarch_old_dos_mode)))
767 *returned_mode = new_mode;
768 else
769 *returned_mode = (mode_t)0;
771 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",
772 path,
773 old_dos_mode, (unsigned int)existing_mode, new_dos_mode, (unsigned int)*returned_mode ));
775 /* If we're mapping SYSTEM and HIDDEN ensure they match. */
776 if (lp_map_system(SNUM(conn))) {
777 if ((old_dos_mode & FILE_ATTRIBUTE_SYSTEM) && !(new_dos_mode & FILE_ATTRIBUTE_SYSTEM))
778 return False;
780 if (lp_map_hidden(SNUM(conn))) {
781 if ((old_dos_mode & FILE_ATTRIBUTE_HIDDEN) && !(new_dos_mode & FILE_ATTRIBUTE_HIDDEN))
782 return False;
784 return True;
787 /****************************************************************************
788 Open a file with a share mode.
789 ****************************************************************************/
791 files_struct *open_file_shared(connection_struct *conn,char *fname, SMB_STRUCT_STAT *psbuf,
792 int share_mode,int ofun, mode_t mode,int oplock_request,
793 int *Access,int *action)
795 return open_file_shared1(conn, fname, psbuf, 0, share_mode, ofun, mode,
796 oplock_request, Access, action);
799 /****************************************************************************
800 Open a file with a share mode.
801 ****************************************************************************/
803 files_struct *open_file_shared1(connection_struct *conn,char *fname, SMB_STRUCT_STAT *psbuf,
804 uint32 desired_access,
805 int share_mode,int ofun, mode_t mode,int oplock_request,
806 int *Access,int *action)
808 int flags=0;
809 int flags2=0;
810 int deny_mode = GET_DENY_MODE(share_mode);
811 BOOL allow_share_delete = GET_ALLOW_SHARE_DELETE(share_mode);
812 BOOL delete_on_close = GET_DELETE_ON_CLOSE_FLAG(share_mode);
813 BOOL file_existed = VALID_STAT(*psbuf);
814 BOOL fcbopen = False;
815 BOOL def_acl = False;
816 SMB_DEV_T dev = 0;
817 SMB_INO_T inode = 0;
818 int num_share_modes = 0;
819 BOOL all_current_opens_are_level_II = False;
820 BOOL fsp_open = False;
821 files_struct *fsp = NULL;
822 int open_mode=0;
823 uint16 port = 0;
824 mode_t new_mode = (mode_t)0;
826 if (conn->printer) {
827 /* printers are handled completely differently. Most of the passed parameters are
828 ignored */
829 if (Access)
830 *Access = DOS_OPEN_WRONLY;
831 if (action)
832 *action = FILE_WAS_CREATED;
833 return print_fsp_open(conn, fname);
836 fsp = file_new(conn);
837 if(!fsp)
838 return NULL;
840 DEBUG(10,("open_file_shared: fname = %s, share_mode = %x, ofun = %x, mode = %o, oplock request = %d\n",
841 fname, share_mode, ofun, (int)mode, oplock_request ));
843 if (!check_name(fname,conn)) {
844 file_free(fsp);
845 return NULL;
848 /* ignore any oplock requests if oplocks are disabled */
849 if (!lp_oplocks(SNUM(conn)) || global_client_failed_oplock_break) {
850 oplock_request = 0;
853 /* this is for OS/2 EAs - try and say we don't support them */
854 if (strstr(fname,".+,;=[].")) {
855 unix_ERR_class = ERRDOS;
856 /* OS/2 Workplace shell fix may be main code stream in a later release. */
857 #if 1 /* OS2_WPS_FIX - Recent versions of OS/2 need this. */
858 unix_ERR_code = ERRcannotopen;
859 #else /* OS2_WPS_FIX */
860 unix_ERR_code = ERROR_EAS_NOT_SUPPORTED;
861 #endif /* OS2_WPS_FIX */
863 DEBUG(5,("open_file_shared: OS/2 EA's are not supported.\n"));
864 file_free(fsp);
865 return NULL;
868 if ((GET_FILE_OPEN_DISPOSITION(ofun) == FILE_EXISTS_FAIL) && file_existed) {
869 DEBUG(5,("open_file_shared: create new requested for file %s and file already exists.\n",
870 fname ));
871 file_free(fsp);
872 errno = EEXIST;
873 return NULL;
876 if (CAN_WRITE(conn) && (GET_FILE_CREATE_DISPOSITION(ofun) == FILE_CREATE_IF_NOT_EXIST))
877 flags2 |= O_CREAT;
879 if (CAN_WRITE(conn) && (GET_FILE_OPEN_DISPOSITION(ofun) == FILE_EXISTS_TRUNCATE))
880 flags2 |= O_TRUNC;
882 /* We only care about matching attributes on file exists and truncate. */
883 if (file_existed && (GET_FILE_OPEN_DISPOSITION(ofun) == FILE_EXISTS_TRUNCATE)) {
884 if (!open_match_attributes(conn, fname, psbuf->st_mode, mode, &new_mode)) {
885 DEBUG(5,("open_file_shared: attributes missmatch for file %s (0%o, 0%o)\n",
886 fname, (int)psbuf->st_mode, (int)mode ));
887 file_free(fsp);
888 errno = EACCES;
889 return NULL;
893 if (GET_FILE_OPEN_DISPOSITION(ofun) == FILE_EXISTS_FAIL)
894 flags2 |= O_EXCL;
896 /* note that we ignore the append flag as
897 append does not mean the same thing under dos and unix */
899 switch (GET_OPEN_MODE(share_mode)) {
900 case DOS_OPEN_WRONLY:
901 flags = O_WRONLY;
902 if (desired_access == 0)
903 desired_access = FILE_WRITE_DATA;
904 break;
905 case DOS_OPEN_FCB:
906 fcbopen = True;
907 flags = O_RDWR;
908 if (desired_access == 0)
909 desired_access = FILE_READ_DATA|FILE_WRITE_DATA;
910 break;
911 case DOS_OPEN_RDWR:
912 flags = O_RDWR;
913 if (desired_access == 0)
914 desired_access = FILE_READ_DATA|FILE_WRITE_DATA;
915 break;
916 default:
917 flags = O_RDONLY;
918 if (desired_access == 0)
919 desired_access = FILE_READ_DATA;
920 break;
923 #if defined(O_SYNC)
924 if (GET_FILE_SYNC_OPENMODE(share_mode)) {
925 flags2 |= O_SYNC;
927 #endif /* O_SYNC */
929 if (flags != O_RDONLY && file_existed &&
930 (!CAN_WRITE(conn) || IS_DOS_READONLY(dos_mode(conn,fname,psbuf)))) {
931 if (!fcbopen) {
932 DEBUG(5,("open_file_shared: read/write access requested for file %s on read only %s\n",
933 fname, !CAN_WRITE(conn) ? "share" : "file" ));
934 file_free(fsp);
935 errno = EACCES;
936 return NULL;
938 flags = O_RDONLY;
941 if (deny_mode > DENY_NONE && deny_mode!=DENY_FCB) {
942 DEBUG(2,("Invalid deny mode %d on file %s\n",deny_mode,fname));
943 file_free(fsp);
944 errno = EINVAL;
945 return NULL;
948 if (file_existed) {
950 dev = psbuf->st_dev;
951 inode = psbuf->st_ino;
953 lock_share_entry(conn, dev, inode);
955 num_share_modes = open_mode_check(conn, fname, dev, inode,
956 desired_access,
957 share_mode,
958 &flags, &oplock_request, &all_current_opens_are_level_II);
959 if(num_share_modes == -1) {
962 * This next line is a subtlety we need for MS-Access. If a file open will
963 * fail due to share permissions and also for security (access)
964 * reasons, we need to return the access failed error, not the
965 * share error. This means we must attempt to open the file anyway
966 * in order to get the UNIX access error - even if we're going to
967 * fail the open for share reasons. This is bad, as we're burning
968 * another fd if there are existing locks but there's nothing else
969 * we can do. We also ensure we're not going to create or tuncate
970 * the file as we only want an access decision at this stage. JRA.
972 errno = 0;
973 fsp_open = open_file(fsp,conn,fname,psbuf,
974 flags|(flags2&~(O_TRUNC|O_CREAT)),mode,desired_access);
976 DEBUG(4,("open_file_shared : share_mode deny - calling open_file with \
977 flags=0x%X flags2=0x%X mode=0%o returned %d\n",
978 flags,(flags2&~(O_TRUNC|O_CREAT)),(int)mode,(int)fsp_open ));
980 if (!fsp_open && errno) {
981 unix_ERR_class = ERRDOS;
982 unix_ERR_code = ERRnoaccess;
983 unix_ERR_ntstatus = NT_STATUS_ACCESS_DENIED;
986 unlock_share_entry(conn, dev, inode);
987 if (fsp_open)
988 fd_close(conn, fsp);
989 file_free(fsp);
990 return NULL;
994 * We exit this block with the share entry *locked*.....
999 * Ensure we pay attention to default ACLs on directories if required.
1002 if ((flags2 & O_CREAT) && lp_inherit_acls(SNUM(conn)) &&
1003 (def_acl = directory_has_default_acl(conn, parent_dirname(fname))))
1004 mode = 0777;
1006 DEBUG(4,("calling open_file with flags=0x%X flags2=0x%X mode=0%o\n",
1007 flags,flags2,(int)mode));
1010 * open_file strips any O_TRUNC flags itself.
1013 fsp_open = open_file(fsp,conn,fname,psbuf,flags|flags2,mode,desired_access);
1015 if (!fsp_open && (flags == O_RDWR) && (errno != ENOENT) && fcbopen) {
1016 if((fsp_open = open_file(fsp,conn,fname,psbuf,O_RDONLY,mode,desired_access)) == True)
1017 flags = O_RDONLY;
1020 if (!fsp_open) {
1021 if(file_existed)
1022 unlock_share_entry(conn, dev, inode);
1023 file_free(fsp);
1024 return NULL;
1028 * Deal with the race condition where two smbd's detect the file doesn't
1029 * exist and do the create at the same time. One of them will win and
1030 * set a share mode, the other (ie. this one) should check if the
1031 * requested share mode for this create is allowed.
1034 if (!file_existed) {
1037 * Now the file exists and fsp is successfully opened,
1038 * fsp->dev and fsp->inode are valid and should replace the
1039 * dev=0,inode=0 from a non existent file. Spotted by
1040 * Nadav Danieli <nadavd@exanet.com>. JRA.
1043 dev = fsp->dev;
1044 inode = fsp->inode;
1046 lock_share_entry_fsp(fsp);
1048 num_share_modes = open_mode_check(conn, fname, dev, inode,
1049 desired_access,
1050 share_mode,
1051 &flags, &oplock_request, &all_current_opens_are_level_II);
1053 if(num_share_modes == -1) {
1054 unlock_share_entry_fsp(fsp);
1055 fd_close(conn,fsp);
1056 file_free(fsp);
1057 return NULL;
1061 * If there are any share modes set then the file *did*
1062 * exist. Ensure we return the correct value for action.
1065 if (num_share_modes > 0)
1066 file_existed = True;
1069 * We exit this block with the share entry *locked*.....
1073 /* note that we ignore failure for the following. It is
1074 basically a hack for NFS, and NFS will never set one of
1075 these only read them. Nobody but Samba can ever set a deny
1076 mode and we have already checked our more authoritative
1077 locking database for permission to set this deny mode. If
1078 the kernel refuses the operations then the kernel is wrong */
1079 kernel_flock(fsp, deny_mode);
1082 * At this point onwards, we can guarentee that the share entry
1083 * is locked, whether we created the file or not, and that the
1084 * deny mode is compatible with all current opens.
1088 * If requested, truncate the file.
1091 if (flags2&O_TRUNC) {
1093 * We are modifing the file after open - update the stat struct..
1095 if ((truncate_unless_locked(conn,fsp) == -1) || (SMB_VFS_FSTAT(fsp,fsp->fd,psbuf)==-1)) {
1096 unlock_share_entry_fsp(fsp);
1097 fd_close(conn,fsp);
1098 file_free(fsp);
1099 return NULL;
1103 switch (flags) {
1104 case O_RDONLY:
1105 open_mode = DOS_OPEN_RDONLY;
1106 break;
1107 case O_RDWR:
1108 open_mode = DOS_OPEN_RDWR;
1109 break;
1110 case O_WRONLY:
1111 open_mode = DOS_OPEN_WRONLY;
1112 break;
1115 fsp->share_mode = SET_DENY_MODE(deny_mode) |
1116 SET_OPEN_MODE(open_mode) |
1117 SET_ALLOW_SHARE_DELETE(allow_share_delete);
1119 DEBUG(10,("open_file_shared : share_mode = %x\n", fsp->share_mode ));
1121 if (Access)
1122 (*Access) = open_mode;
1124 if (action) {
1125 if (file_existed && !(flags2 & O_TRUNC))
1126 *action = FILE_WAS_OPENED;
1127 if (!file_existed)
1128 *action = FILE_WAS_CREATED;
1129 if (file_existed && (flags2 & O_TRUNC))
1130 *action = FILE_WAS_OVERWRITTEN;
1134 * Setup the oplock info in both the shared memory and
1135 * file structs.
1138 if(oplock_request && (num_share_modes == 0) &&
1139 !IS_VETO_OPLOCK_PATH(conn,fname) && set_file_oplock(fsp, oplock_request) ) {
1140 port = global_oplock_port;
1141 } else if (oplock_request && all_current_opens_are_level_II) {
1142 port = global_oplock_port;
1143 oplock_request = LEVEL_II_OPLOCK;
1144 set_file_oplock(fsp, oplock_request);
1145 } else {
1146 port = 0;
1147 oplock_request = 0;
1150 set_share_mode(fsp, port, oplock_request);
1152 if (delete_on_close) {
1153 NTSTATUS result = set_delete_on_close_internal(fsp, delete_on_close);
1155 if (NT_STATUS_V(result) != NT_STATUS_V(NT_STATUS_OK)) {
1156 /* Remember to delete the mode we just added. */
1157 del_share_mode(fsp, NULL);
1158 unlock_share_entry_fsp(fsp);
1159 fd_close(conn,fsp);
1160 file_free(fsp);
1161 return NULL;
1166 * Take care of inherited ACLs on created files - if default ACL not
1167 * selected.
1170 if (!file_existed && !def_acl) {
1172 int saved_errno = errno; /* We might get ENOSYS in the next call.. */
1174 if (SMB_VFS_FCHMOD_ACL(fsp, fsp->fd, mode) == -1 && errno == ENOSYS)
1175 errno = saved_errno; /* Ignore ENOSYS */
1177 } else if (new_mode) {
1179 int ret = -1;
1181 /* Attributes need changing. File already existed. */
1184 int saved_errno = errno; /* We might get ENOSYS in the next call.. */
1185 ret = SMB_VFS_FCHMOD_ACL(fsp, fsp->fd, new_mode);
1187 if (ret == -1 && errno == ENOSYS) {
1188 errno = saved_errno; /* Ignore ENOSYS */
1189 } else {
1190 DEBUG(5, ("open_file_shared: failed to reset attributes of file %s to 0%o\n",
1191 fname, (int)new_mode));
1192 ret = 0; /* Don't do the fchmod below. */
1196 if ((ret == -1) && (SMB_VFS_FCHMOD(fsp, fsp->fd, new_mode) == -1))
1197 DEBUG(5, ("open_file_shared: failed to reset attributes of file %s to 0%o\n",
1198 fname, (int)new_mode));
1201 unlock_share_entry_fsp(fsp);
1203 conn->num_files_open++;
1205 return fsp;
1208 /****************************************************************************
1209 Open a file for for write to ensure that we can fchmod it.
1210 ****************************************************************************/
1212 files_struct *open_file_fchmod(connection_struct *conn, const char *fname, SMB_STRUCT_STAT *psbuf)
1214 files_struct *fsp = NULL;
1215 BOOL fsp_open;
1217 if (!VALID_STAT(*psbuf))
1218 return NULL;
1220 fsp = file_new(conn);
1221 if(!fsp)
1222 return NULL;
1224 /* note! we must use a non-zero desired access or we don't get
1225 a real file descriptor. Oh what a twisted web we weave. */
1226 fsp_open = open_file(fsp,conn,fname,psbuf,O_WRONLY,0,FILE_WRITE_DATA);
1229 * This is not a user visible file open.
1230 * Don't set a share mode and don't increment
1231 * the conn->num_files_open.
1234 if (!fsp_open) {
1235 file_free(fsp);
1236 return NULL;
1239 return fsp;
1242 /****************************************************************************
1243 Close the fchmod file fd - ensure no locks are lost.
1244 ****************************************************************************/
1246 int close_file_fchmod(files_struct *fsp)
1248 int ret = fd_close(fsp->conn, fsp);
1249 file_free(fsp);
1250 return ret;
1253 /****************************************************************************
1254 Open a directory from an NT SMB call.
1255 ****************************************************************************/
1257 files_struct *open_directory(connection_struct *conn, char *fname, SMB_STRUCT_STAT *psbuf,
1258 uint32 desired_access, int share_mode, int smb_ofun, mode_t unixmode, int *action)
1260 extern struct current_user current_user;
1261 BOOL got_stat = False;
1262 files_struct *fsp = file_new(conn);
1263 BOOL delete_on_close = GET_DELETE_ON_CLOSE_FLAG(share_mode);
1265 if(!fsp)
1266 return NULL;
1268 if (VALID_STAT(*psbuf))
1269 got_stat = True;
1271 if (got_stat && (GET_FILE_OPEN_DISPOSITION(smb_ofun) == FILE_EXISTS_FAIL)) {
1272 file_free(fsp);
1273 errno = EEXIST; /* Setup so correct error is returned to client. */
1274 return NULL;
1277 if (GET_FILE_CREATE_DISPOSITION(smb_ofun) == FILE_CREATE_IF_NOT_EXIST) {
1279 if (got_stat) {
1281 if(!S_ISDIR(psbuf->st_mode)) {
1282 DEBUG(0,("open_directory: %s is not a directory !\n", fname ));
1283 file_free(fsp);
1284 errno = EACCES;
1285 return NULL;
1287 *action = FILE_WAS_OPENED;
1289 } else {
1292 * Try and create the directory.
1295 if(!CAN_WRITE(conn)) {
1296 DEBUG(2,("open_directory: failing create on read-only share\n"));
1297 file_free(fsp);
1298 errno = EACCES;
1299 return NULL;
1302 if (ms_has_wild(fname)) {
1303 file_free(fsp);
1304 DEBUG(5,("open_directory: failing create on filename %s with wildcards\n", fname));
1305 unix_ERR_class = ERRDOS;
1306 unix_ERR_code = ERRinvalidname;
1307 unix_ERR_ntstatus = NT_STATUS_OBJECT_NAME_INVALID;
1308 return NULL;
1311 if(vfs_MkDir(conn,fname, unix_mode(conn,aDIR, fname)) < 0) {
1312 DEBUG(2,("open_directory: unable to create %s. Error was %s\n",
1313 fname, strerror(errno) ));
1314 file_free(fsp);
1315 return NULL;
1318 if(SMB_VFS_STAT(conn,fname, psbuf) != 0) {
1319 file_free(fsp);
1320 return NULL;
1323 *action = FILE_WAS_CREATED;
1326 } else {
1329 * Don't create - just check that it *was* a directory.
1332 if(!got_stat) {
1333 DEBUG(3,("open_directory: unable to stat name = %s. Error was %s\n",
1334 fname, strerror(errno) ));
1335 file_free(fsp);
1336 return NULL;
1339 if(!S_ISDIR(psbuf->st_mode)) {
1340 DEBUG(0,("open_directory: %s is not a directory !\n", fname ));
1341 file_free(fsp);
1342 return NULL;
1345 *action = FILE_WAS_OPENED;
1348 DEBUG(5,("open_directory: opening directory %s\n", fname));
1351 * Setup the files_struct for it.
1354 fsp->mode = psbuf->st_mode;
1355 fsp->inode = psbuf->st_ino;
1356 fsp->dev = psbuf->st_dev;
1357 fsp->size = psbuf->st_size;
1358 fsp->vuid = current_user.vuid;
1359 fsp->pos = -1;
1360 fsp->can_lock = True;
1361 fsp->can_read = False;
1362 fsp->can_write = False;
1363 fsp->share_mode = share_mode;
1364 fsp->desired_access = desired_access;
1365 fsp->print_file = False;
1366 fsp->modified = False;
1367 fsp->oplock_type = NO_OPLOCK;
1368 fsp->sent_oplock_break = NO_BREAK_SENT;
1369 fsp->is_directory = True;
1370 fsp->is_stat = False;
1371 fsp->directory_delete_on_close = False;
1372 string_set(&fsp->fsp_name,fname);
1374 if (delete_on_close) {
1375 NTSTATUS result = set_delete_on_close_internal(fsp, delete_on_close);
1377 if (NT_STATUS_V(result) != NT_STATUS_V(NT_STATUS_OK)) {
1378 file_free(fsp);
1379 return NULL;
1382 conn->num_files_open++;
1384 return fsp;
1387 /****************************************************************************
1388 Open a pseudo-file (no locking checks - a 'stat' open).
1389 ****************************************************************************/
1391 files_struct *open_file_stat(connection_struct *conn, char *fname, SMB_STRUCT_STAT *psbuf)
1393 extern struct current_user current_user;
1394 files_struct *fsp = NULL;
1396 if (!VALID_STAT(*psbuf))
1397 return NULL;
1399 /* Can't 'stat' open directories. */
1400 if(S_ISDIR(psbuf->st_mode))
1401 return NULL;
1403 fsp = file_new(conn);
1404 if(!fsp)
1405 return NULL;
1407 DEBUG(5,("open_file_stat: 'opening' file %s\n", fname));
1410 * Setup the files_struct for it.
1413 fsp->mode = psbuf->st_mode;
1415 * Don't store dev or inode, we don't want any iterator
1416 * to see this.
1418 fsp->inode = (SMB_INO_T)0;
1419 fsp->dev = (SMB_DEV_T)0;
1420 fsp->size = psbuf->st_size;
1421 fsp->vuid = current_user.vuid;
1422 fsp->pos = -1;
1423 fsp->can_lock = False;
1424 fsp->can_read = False;
1425 fsp->can_write = False;
1426 fsp->share_mode = 0;
1427 fsp->desired_access = 0;
1428 fsp->print_file = False;
1429 fsp->modified = False;
1430 fsp->oplock_type = NO_OPLOCK;
1431 fsp->sent_oplock_break = NO_BREAK_SENT;
1432 fsp->is_directory = False;
1433 fsp->is_stat = True;
1434 fsp->directory_delete_on_close = False;
1435 string_set(&fsp->fsp_name,fname);
1437 conn->num_files_open++;
1439 return fsp;