A fix to allow configure to find iconv on a number of systems including those
[Samba/gebeck_regimport.git] / source3 / smbd / open.c
blobef7ace862ae3455bd571f3675cd40b25203e5459
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, 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 /* Fix for files ending in '.' */
45 if((fd == -1) && (errno == ENOENT) &&
46 (strchr_m(fname,'.')==NULL)) {
47 pstrcat(fname,".");
48 fd = SMB_VFS_OPEN(conn,fname,flags,mode);
51 DEBUG(10,("fd_open: name %s, flags = 0%o mode = 0%o, fd = %d. %s\n", fname,
52 flags, (int)mode, fd, (fd == -1) ? strerror(errno) : "" ));
54 return fd;
57 /****************************************************************************
58 Close the file associated with a fsp.
59 ****************************************************************************/
61 int fd_close(struct connection_struct *conn, files_struct *fsp)
63 if (fsp->fd == -1)
64 return 0; /* what we used to call a stat open. */
65 return fd_close_posix(conn, fsp);
69 /****************************************************************************
70 Check a filename for the pipe string.
71 ****************************************************************************/
73 static void check_for_pipe(char *fname)
75 /* special case of pipe opens */
76 char s[10];
77 StrnCpy(s,fname,sizeof(s)-1);
78 strlower_m(s);
79 if (strstr(s,"pipe/")) {
80 DEBUG(3,("Rejecting named pipe open for %s\n",fname));
81 unix_ERR_class = ERRSRV;
82 unix_ERR_code = ERRaccess;
83 unix_ERR_ntstatus = NT_STATUS_ACCESS_DENIED;
87 /****************************************************************************
88 Open a file.
89 ****************************************************************************/
91 static BOOL open_file(files_struct *fsp,connection_struct *conn,
92 const char *fname1,SMB_STRUCT_STAT *psbuf,int flags,mode_t mode, uint32 desired_access)
94 extern struct current_user current_user;
95 pstring fname;
96 int accmode = (flags & O_ACCMODE);
97 int local_flags = flags;
99 fsp->fd = -1;
100 fsp->oplock_type = NO_OPLOCK;
101 errno = EPERM;
103 pstrcpy(fname,fname1);
105 /* Check permissions */
108 * This code was changed after seeing a client open request
109 * containing the open mode of (DENY_WRITE/read-only) with
110 * the 'create if not exist' bit set. The previous code
111 * would fail to open the file read only on a read-only share
112 * as it was checking the flags parameter directly against O_RDONLY,
113 * this was failing as the flags parameter was set to O_RDONLY|O_CREAT.
114 * JRA.
117 if (!CAN_WRITE(conn)) {
118 /* It's a read-only share - fail if we wanted to write. */
119 if(accmode != O_RDONLY) {
120 DEBUG(3,("Permission denied opening %s\n",fname));
121 check_for_pipe(fname);
122 return False;
123 } else if(flags & O_CREAT) {
124 /* We don't want to write - but we must make sure that O_CREAT
125 doesn't create the file if we have write access into the
126 directory.
128 flags &= ~O_CREAT;
129 local_flags &= ~O_CREAT;
134 * This little piece of insanity is inspired by the
135 * fact that an NT client can open a file for O_RDONLY,
136 * but set the create disposition to FILE_EXISTS_TRUNCATE.
137 * If the client *can* write to the file, then it expects to
138 * truncate the file, even though it is opening for readonly.
139 * Quicken uses this stupid trick in backup file creation...
140 * Thanks *greatly* to "David W. Chapman Jr." <dwcjr@inethouston.net>
141 * for helping track this one down. It didn't bite us in 2.0.x
142 * as we always opened files read-write in that release. JRA.
145 if ((accmode == O_RDONLY) && ((flags & O_TRUNC) == O_TRUNC)) {
146 DEBUG(10,("open_file: truncate requested on read-only open for file %s\n",fname ));
147 local_flags = (flags & ~O_ACCMODE)|O_RDWR;
150 if ((desired_access & (FILE_READ_DATA|FILE_WRITE_DATA|FILE_APPEND_DATA|FILE_EXECUTE)) ||
151 (local_flags & O_CREAT) || ((local_flags & O_TRUNC) == O_TRUNC) ) {
154 * We can't actually truncate here as the file may be locked.
155 * open_file_shared will take care of the truncate later. JRA.
158 local_flags &= ~O_TRUNC;
160 #if defined(O_NONBLOCK) && defined(S_ISFIFO)
162 * We would block on opening a FIFO with no one else on the
163 * other end. Do what we used to do and add O_NONBLOCK to the
164 * open flags. JRA.
167 if (VALID_STAT(*psbuf) && S_ISFIFO(psbuf->st_mode))
168 local_flags |= O_NONBLOCK;
169 #endif
171 /* Don't create files with Microsoft wildcard characters. */
172 if ((local_flags & O_CREAT) && !VALID_STAT(*psbuf) && ms_has_wild(fname)) {
173 unix_ERR_class = ERRDOS;
174 unix_ERR_code = ERRinvalidname;
175 unix_ERR_ntstatus = NT_STATUS_OBJECT_NAME_INVALID;
176 return False;
179 /* Actually do the open */
180 fsp->fd = fd_open(conn, fname, local_flags, mode);
181 if (fsp->fd == -1) {
182 DEBUG(3,("Error opening file %s (%s) (local_flags=%d) (flags=%d)\n",
183 fname,strerror(errno),local_flags,flags));
184 check_for_pipe(fname);
185 return False;
188 /* Inherit the ACL if the file was created. */
189 if ((local_flags & O_CREAT) && !VALID_STAT(*psbuf))
190 inherit_access_acl(conn, fname, mode);
192 } else
193 fsp->fd = -1; /* What we used to call a stat open. */
195 if (!VALID_STAT(*psbuf)) {
196 int ret;
198 if (fsp->fd == -1)
199 ret = SMB_VFS_STAT(conn, fname, psbuf);
200 else {
201 ret = SMB_VFS_FSTAT(fsp,fsp->fd,psbuf);
202 /* If we have an fd, this stat should succeed. */
203 if (ret == -1)
204 DEBUG(0,("Error doing fstat on open file %s (%s)\n", fname,strerror(errno) ));
207 /* For a non-io open, this stat failing means file not found. JRA */
208 if (ret == -1) {
209 fd_close(conn, fsp);
210 return False;
215 * POSIX allows read-only opens of directories. We don't
216 * want to do this (we use a different code path for this)
217 * so catch a directory open and return an EISDIR. JRA.
220 if(S_ISDIR(psbuf->st_mode)) {
221 fd_close(conn, fsp);
222 errno = EISDIR;
223 return False;
226 fsp->mode = psbuf->st_mode;
227 fsp->inode = psbuf->st_ino;
228 fsp->dev = psbuf->st_dev;
229 fsp->vuid = current_user.vuid;
230 fsp->file_pid = global_smbpid;
231 fsp->size = psbuf->st_size;
232 fsp->can_lock = True;
233 fsp->can_read = ((flags & O_WRONLY)==0);
234 fsp->can_write = ((flags & (O_WRONLY|O_RDWR))!=0);
235 fsp->share_mode = 0;
236 fsp->desired_access = desired_access;
237 fsp->print_file = False;
238 fsp->modified = False;
239 fsp->oplock_type = NO_OPLOCK;
240 fsp->sent_oplock_break = NO_BREAK_SENT;
241 fsp->is_directory = False;
242 fsp->is_stat = False;
243 fsp->directory_delete_on_close = False;
244 string_set(&fsp->fsp_name,fname);
245 fsp->wcp = NULL; /* Write cache pointer. */
247 DEBUG(2,("%s opened file %s read=%s write=%s (numopen=%d)\n",
248 *current_user_info.smb_name ? current_user_info.smb_name : conn->user,fsp->fsp_name,
249 BOOLSTR(fsp->can_read), BOOLSTR(fsp->can_write),
250 conn->num_files_open + 1));
252 return True;
255 /****************************************************************************
256 C. Hoch 11/22/95
257 Helper for open_file_shared.
258 Truncate a file after checking locking; close file if locked.
259 **************************************************************************/
261 static int truncate_unless_locked(struct connection_struct *conn, files_struct *fsp)
263 SMB_BIG_UINT mask = (SMB_BIG_UINT)-1;
265 if (is_locked(fsp,fsp->conn,mask,0,WRITE_LOCK,True)){
266 errno = EACCES;
267 unix_ERR_class = ERRDOS;
268 unix_ERR_code = ERRlock;
269 unix_ERR_ntstatus = dos_to_ntstatus(ERRDOS, ERRlock);
270 return -1;
271 } else {
272 return SMB_VFS_FTRUNCATE(fsp,fsp->fd,0);
276 /*******************************************************************
277 return True if the filename is one of the special executable types
278 ********************************************************************/
279 static BOOL is_executable(const char *fname)
281 if ((fname = strrchr_m(fname,'.'))) {
282 if (strequal(fname,".com") ||
283 strequal(fname,".dll") ||
284 strequal(fname,".exe") ||
285 strequal(fname,".sym")) {
286 return True;
289 return False;
292 enum {AFAIL,AREAD,AWRITE,AALL};
294 /*******************************************************************
295 reproduce the share mode access table
296 this is horrendoously complex, and really can't be justified on any
297 rational grounds except that this is _exactly_ what NT does. See
298 the DENY1 and DENY2 tests in smbtorture for a comprehensive set of
299 test routines.
300 ********************************************************************/
301 static int access_table(int new_deny,int old_deny,int old_mode,
302 BOOL same_pid, BOOL isexe)
304 if (new_deny == DENY_ALL || old_deny == DENY_ALL) return(AFAIL);
306 if (same_pid) {
307 if (isexe && old_mode == DOS_OPEN_RDONLY &&
308 old_deny == DENY_DOS && new_deny == DENY_READ) {
309 return AFAIL;
311 if (!isexe && old_mode == DOS_OPEN_RDONLY &&
312 old_deny == DENY_DOS && new_deny == DENY_DOS) {
313 return AREAD;
315 if (new_deny == DENY_FCB && old_deny == DENY_DOS) {
316 if (isexe) return AFAIL;
317 if (old_mode == DOS_OPEN_RDONLY) return AFAIL;
318 return AALL;
320 if (old_mode == DOS_OPEN_RDONLY && old_deny == DENY_DOS) {
321 if (new_deny == DENY_FCB || new_deny == DENY_READ) {
322 if (isexe) return AREAD;
323 return AFAIL;
326 if (old_deny == DENY_FCB) {
327 if (new_deny == DENY_DOS || new_deny == DENY_FCB) return AALL;
328 return AFAIL;
332 if (old_deny == DENY_DOS || new_deny == DENY_DOS ||
333 old_deny == DENY_FCB || new_deny == DENY_FCB) {
334 if (isexe) {
335 if (old_deny == DENY_FCB || new_deny == DENY_FCB) {
336 return AFAIL;
338 if (old_deny == DENY_DOS) {
339 if (new_deny == DENY_READ &&
340 (old_mode == DOS_OPEN_RDONLY ||
341 old_mode == DOS_OPEN_RDWR)) {
342 return AFAIL;
344 if (new_deny == DENY_WRITE &&
345 (old_mode == DOS_OPEN_WRONLY ||
346 old_mode == DOS_OPEN_RDWR)) {
347 return AFAIL;
349 return AALL;
351 if (old_deny == DENY_NONE) return AALL;
352 if (old_deny == DENY_READ) return AWRITE;
353 if (old_deny == DENY_WRITE) return AREAD;
355 /* it isn't a exe, dll, sym or com file */
356 if (old_deny == new_deny && same_pid)
357 return(AALL);
359 if (old_deny == DENY_READ || new_deny == DENY_READ) return AFAIL;
360 if (old_mode == DOS_OPEN_RDONLY) return(AREAD);
362 return(AFAIL);
365 switch (new_deny)
367 case DENY_WRITE:
368 if (old_deny==DENY_WRITE && old_mode==DOS_OPEN_RDONLY) return(AREAD);
369 if (old_deny==DENY_READ && old_mode==DOS_OPEN_RDONLY) return(AWRITE);
370 if (old_deny==DENY_NONE && old_mode==DOS_OPEN_RDONLY) return(AALL);
371 return(AFAIL);
372 case DENY_READ:
373 if (old_deny==DENY_WRITE && old_mode==DOS_OPEN_WRONLY) return(AREAD);
374 if (old_deny==DENY_READ && old_mode==DOS_OPEN_WRONLY) return(AWRITE);
375 if (old_deny==DENY_NONE && old_mode==DOS_OPEN_WRONLY) return(AALL);
376 return(AFAIL);
377 case DENY_NONE:
378 if (old_deny==DENY_WRITE) return(AREAD);
379 if (old_deny==DENY_READ) return(AWRITE);
380 if (old_deny==DENY_NONE) return(AALL);
381 return(AFAIL);
383 return(AFAIL);
387 /****************************************************************************
388 check if we can open a file with a share mode
389 ****************************************************************************/
391 static BOOL check_share_mode(connection_struct *conn, share_mode_entry *share, int share_mode, uint32 desired_access,
392 const char *fname, BOOL fcbopen, int *flags)
394 int deny_mode = GET_DENY_MODE(share_mode);
395 int old_open_mode = GET_OPEN_MODE(share->share_mode);
396 int old_deny_mode = GET_DENY_MODE(share->share_mode);
399 * share modes = false means don't bother to check for
400 * DENY mode conflict. This is a *really* bad idea :-). JRA.
403 if(!lp_share_modes(SNUM(conn)))
404 return True;
407 * Don't allow any opens once the delete on close flag has been
408 * set.
411 if (GET_DELETE_ON_CLOSE_FLAG(share->share_mode)) {
412 DEBUG(5,("check_share_mode: Failing open on file %s as delete on close flag is set.\n",
413 fname ));
414 /* Use errno to map to correct error. */
415 unix_ERR_class = SMB_SUCCESS;
416 unix_ERR_code = 0;
417 unix_ERR_ntstatus = NT_STATUS_OK;
418 return False;
421 /* this is a nasty hack, but necessary until we rewrite our open
422 handling to use a NTCreateX call as the basic call.
423 NT may open a file with neither read nor write access, and in
424 this case it expects the open not to conflict with any
425 existing deny modes. This happens (for example) during a
426 "xcopy /o" where the second file descriptor is used for
427 ACL sets
428 (tridge)
432 * This is a bit wierd - the test for desired access not having the
433 * critical bits seems seems odd. Firstly, if both opens have no
434 * critical bits then always ignore. Then check the "allow delete"
435 * then check for either. This probably isn't quite right yet but
436 * gets us much closer. JRA.
440 * If desired_access doesn't contain READ_DATA,WRITE_DATA,APPEND_DATA or EXECUTE
441 * and the existing desired_acces then share modes don't conflict.
444 if ( !(desired_access & (FILE_READ_DATA|FILE_WRITE_DATA|FILE_APPEND_DATA|FILE_EXECUTE)) &&
445 !(share->desired_access & (FILE_READ_DATA|FILE_WRITE_DATA|FILE_APPEND_DATA|FILE_EXECUTE)) ) {
448 * Wrinkle discovered by smbtorture....
449 * If both are non-io open and requester is asking for delete and current open has delete access
450 * but neither open has allowed file share delete then deny.... this is very strange and
451 * seems to be the only case in which non-io opens conflict. JRA.
454 if ((desired_access & DELETE_ACCESS) && (share->desired_access & DELETE_ACCESS) &&
455 (!GET_ALLOW_SHARE_DELETE(share->share_mode) || !GET_ALLOW_SHARE_DELETE(share_mode))) {
456 DEBUG(5,("check_share_mode: Failing open on file %s as delete access requests conflict.\n",
457 fname ));
458 unix_ERR_class = ERRDOS;
459 unix_ERR_code = ERRbadshare;
460 unix_ERR_ntstatus = NT_STATUS_SHARING_VIOLATION;
462 return False;
465 DEBUG(5,("check_share_mode: Allowing open on file %s as both desired access (0x%x) \
466 and existing desired access (0x%x) are non-data opens\n",
467 fname, (unsigned int)desired_access, (unsigned int)share->desired_access ));
468 return True;
472 * If delete access was requested and the existing share mode doesn't have
473 * ALLOW_SHARE_DELETE then deny.
476 if ((desired_access & DELETE_ACCESS) && !GET_ALLOW_SHARE_DELETE(share->share_mode)) {
477 DEBUG(5,("check_share_mode: Failing open on file %s as delete access requested and allow share delete not set.\n",
478 fname ));
479 unix_ERR_class = ERRDOS;
480 unix_ERR_code = ERRbadshare;
481 unix_ERR_ntstatus = NT_STATUS_SHARING_VIOLATION;
483 return False;
487 * The inverse of the above.
488 * If delete access was granted and the new share mode doesn't have
489 * ALLOW_SHARE_DELETE then deny.
492 if ((share->desired_access & DELETE_ACCESS) && !GET_ALLOW_SHARE_DELETE(share_mode)) {
493 DEBUG(5,("check_share_mode: Failing open on file %s as delete access granted and allow share delete not requested.\n",
494 fname ));
495 unix_ERR_class = ERRDOS;
496 unix_ERR_code = ERRbadshare;
497 unix_ERR_ntstatus = NT_STATUS_SHARING_VIOLATION;
499 return False;
503 * If desired_access doesn't contain READ_DATA,WRITE_DATA,APPEND_DATA or EXECUTE
504 * then share modes don't conflict. Likewise with existing desired access.
507 if ( !(desired_access & (FILE_READ_DATA|FILE_WRITE_DATA|FILE_APPEND_DATA|FILE_EXECUTE)) ||
508 !(share->desired_access & (FILE_READ_DATA|FILE_WRITE_DATA|FILE_APPEND_DATA|FILE_EXECUTE)) ) {
509 DEBUG(5,("check_share_mode: Allowing open on file %s as desired access (0x%x) doesn't conflict with\
510 existing desired access (0x%x).\n", fname, (unsigned int)desired_access, (unsigned int)share->desired_access ));
511 return True;
515 int access_allowed = access_table(deny_mode,old_deny_mode,old_open_mode,
516 (share->pid == sys_getpid()),is_executable(fname));
518 if ((access_allowed == AFAIL) ||
519 (!fcbopen && (access_allowed == AREAD && *flags == O_RDWR)) ||
520 (access_allowed == AREAD && *flags != O_RDONLY) ||
521 (access_allowed == AWRITE && *flags != O_WRONLY)) {
523 DEBUG(2,("Share violation on file (%d,%d,%d,%d,%s,fcbopen = %d, flags = %d) = %d\n",
524 deny_mode,old_deny_mode,old_open_mode,
525 (int)share->pid,fname, fcbopen, *flags, access_allowed));
527 unix_ERR_class = ERRDOS;
528 unix_ERR_code = ERRbadshare;
529 unix_ERR_ntstatus = NT_STATUS_SHARING_VIOLATION;
531 return False;
534 if (access_allowed == AREAD)
535 *flags = O_RDONLY;
537 if (access_allowed == AWRITE)
538 *flags = O_WRONLY;
542 return True;
546 #if defined(DEVELOPER)
547 static void validate_my_share_entries(int num, share_mode_entry *share_entry)
549 files_struct *fsp;
551 if (share_entry->pid != sys_getpid())
552 return;
554 fsp = file_find_dif(share_entry->dev, share_entry->inode, share_entry->share_file_id);
555 if (!fsp) {
556 DEBUG(0,("validate_my_share_entries: PANIC : %s\n", share_mode_str(num, share_entry) ));
557 smb_panic("validate_my_share_entries: Cannot match a share entry with an open file\n");
560 if (((uint16)fsp->oplock_type) != share_entry->op_type) {
561 pstring str;
562 DEBUG(0,("validate_my_share_entries: PANIC : %s\n", share_mode_str(num, share_entry) ));
563 slprintf(str, sizeof(str)-1, "validate_my_share_entries: file %s, oplock_type = 0x%x, op_type = 0x%x\n",
564 fsp->fsp_name, (unsigned int)fsp->oplock_type, (unsigned int)share_entry->op_type );
565 smb_panic(str);
568 #endif
570 /****************************************************************************
571 Deal with open deny mode and oplock break processing.
572 Invarient: Share mode must be locked on entry and exit.
573 Returns -1 on error, or number of share modes on success (may be zero).
574 ****************************************************************************/
576 static int open_mode_check(connection_struct *conn, const char *fname, SMB_DEV_T dev,
577 SMB_INO_T inode,
578 uint32 desired_access,
579 int share_mode, int *p_flags, int *p_oplock_request,
580 BOOL *p_all_current_opens_are_level_II)
582 int i;
583 int num_share_modes;
584 int oplock_contention_count = 0;
585 share_mode_entry *old_shares = 0;
586 BOOL fcbopen = False;
587 BOOL broke_oplock;
589 if(GET_OPEN_MODE(share_mode) == DOS_OPEN_FCB)
590 fcbopen = True;
592 num_share_modes = get_share_modes(conn, dev, inode, &old_shares);
594 if(num_share_modes == 0)
595 return 0;
598 * Check if the share modes will give us access.
601 do {
602 share_mode_entry broken_entry;
604 broke_oplock = False;
605 *p_all_current_opens_are_level_II = True;
607 for(i = 0; i < num_share_modes; i++) {
608 share_mode_entry *share_entry = &old_shares[i];
610 #if defined(DEVELOPER)
611 validate_my_share_entries(i, share_entry);
612 #endif
615 * By observation of NetBench, oplocks are broken *before* share
616 * modes are checked. This allows a file to be closed by the client
617 * if the share mode would deny access and the client has an oplock.
618 * Check if someone has an oplock on this file. If so we must break
619 * it before continuing.
622 if((*p_oplock_request && EXCLUSIVE_OPLOCK_TYPE(share_entry->op_type)) ||
623 (!*p_oplock_request && (share_entry->op_type != NO_OPLOCK))) {
625 BOOL opb_ret;
627 DEBUG(5,("open_mode_check: oplock_request = %d, breaking oplock (%x) on file %s, \
628 dev = %x, inode = %.0f\n", *p_oplock_request, share_entry->op_type, fname, (unsigned int)dev, (double)inode));
630 /* Ensure the reply for the open uses the correct sequence number. */
631 /* This isn't a real deferred packet as it's response will also increment
632 * the sequence.
634 srv_defer_sign_response(get_current_mid());
636 /* Oplock break - unlock to request it. */
637 unlock_share_entry(conn, dev, inode);
639 opb_ret = request_oplock_break(share_entry, False);
641 /* Now relock. */
642 lock_share_entry(conn, dev, inode);
644 if(opb_ret == False) {
645 DEBUG(0,("open_mode_check: FAILED when breaking oplock (%x) on file %s, \
646 dev = %x, inode = %.0f\n", old_shares[i].op_type, fname, (unsigned int)dev, (double)inode));
647 SAFE_FREE(old_shares);
648 errno = EACCES;
649 unix_ERR_class = ERRDOS;
650 unix_ERR_code = ERRbadshare;
651 unix_ERR_ntstatus = NT_STATUS_SHARING_VIOLATION;
652 return -1;
655 broke_oplock = True;
656 broken_entry = *share_entry;
657 break;
659 } else if (!LEVEL_II_OPLOCK_TYPE(share_entry->op_type)) {
660 *p_all_current_opens_are_level_II = False;
663 /* someone else has a share lock on it, check to see if we can too */
664 if (!check_share_mode(conn, share_entry, share_mode, desired_access,
665 fname, fcbopen, p_flags)) {
666 SAFE_FREE(old_shares);
667 errno = EACCES;
668 return -1;
671 } /* end for */
673 if(broke_oplock) {
674 SAFE_FREE(old_shares);
675 num_share_modes = get_share_modes(conn, dev, inode, &old_shares);
676 oplock_contention_count++;
678 /* Paranoia check that this is no longer an exlusive entry. */
679 for(i = 0; i < num_share_modes; i++) {
680 share_mode_entry *share_entry = &old_shares[i];
682 if (share_modes_identical(&broken_entry, share_entry) &&
683 EXCLUSIVE_OPLOCK_TYPE(share_entry->op_type) ) {
686 * This should not happen. The target left this oplock
687 * as exlusive.... The process *must* be dead....
690 DEBUG(0,("open_mode_check: exlusive oplock left by process %d after break ! For file %s, \
691 dev = %x, inode = %.0f. Deleting it to continue...\n", (int)broken_entry.pid, fname, (unsigned int)dev, (double)inode));
693 if (process_exists(broken_entry.pid)) {
694 DEBUG(0,("open_mode_check: Existent process %lu left active oplock.\n",
695 (unsigned long)broken_entry.pid ));
698 if (del_share_entry(dev, inode, &broken_entry, NULL) == -1) {
699 errno = EACCES;
700 unix_ERR_class = ERRDOS;
701 unix_ERR_code = ERRbadshare;
702 unix_ERR_ntstatus = NT_STATUS_SHARING_VIOLATION;
703 return -1;
707 * We must reload the share modes after deleting the
708 * other process's entry.
711 SAFE_FREE(old_shares);
712 num_share_modes = get_share_modes(conn, dev, inode, &old_shares);
713 break;
715 } /* end for paranoia... */
716 } /* end if broke_oplock */
718 } while(broke_oplock);
720 if(old_shares != 0)
721 SAFE_FREE(old_shares);
724 * Refuse to grant an oplock in case the contention limit is
725 * reached when going through the lock list multiple times.
728 if(oplock_contention_count >= lp_oplock_contention_limit(SNUM(conn))) {
729 *p_oplock_request = 0;
730 DEBUG(4,("open_mode_check: oplock contention = %d. Not granting oplock.\n",
731 oplock_contention_count ));
734 return num_share_modes;
737 /****************************************************************************
738 set a kernel flock on a file for NFS interoperability
739 this requires a patch to Linux
740 ****************************************************************************/
741 static void kernel_flock(files_struct *fsp, int deny_mode)
743 #if HAVE_KERNEL_SHARE_MODES
744 int kernel_mode = 0;
745 if (deny_mode == DENY_READ) kernel_mode = LOCK_MAND|LOCK_WRITE;
746 else if (deny_mode == DENY_WRITE) kernel_mode = LOCK_MAND|LOCK_READ;
747 else if (deny_mode == DENY_ALL) kernel_mode = LOCK_MAND;
748 if (kernel_mode) flock(fsp->fd, kernel_mode);
749 #endif
754 static BOOL open_match_attributes(connection_struct *conn, char *path, mode_t existing_mode,
755 mode_t new_mode, mode_t *returned_mode)
757 uint32 old_dos_mode, new_dos_mode;
758 uint32 noarch_old_dos_mode, noarch_new_dos_mode;
759 SMB_STRUCT_STAT sbuf;
761 ZERO_STRUCT(sbuf);
763 sbuf.st_mode = existing_mode;
764 old_dos_mode = dos_mode(conn, path, &sbuf);
766 sbuf.st_mode = new_mode;
767 new_dos_mode = dos_mode(conn, path, &sbuf);
769 noarch_old_dos_mode = (old_dos_mode & ~FILE_ATTRIBUTE_ARCHIVE);
770 noarch_new_dos_mode = (new_dos_mode & ~FILE_ATTRIBUTE_ARCHIVE);
772 if((noarch_old_dos_mode == 0 && noarch_new_dos_mode != 0) ||
773 (noarch_old_dos_mode != 0 && ((noarch_old_dos_mode & noarch_new_dos_mode) == noarch_old_dos_mode)))
774 *returned_mode = new_mode;
775 else
776 *returned_mode = (mode_t)0;
778 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",
779 path,
780 old_dos_mode, (unsigned int)existing_mode, new_dos_mode, (unsigned int)*returned_mode ));
782 /* If we're mapping SYSTEM and HIDDEN ensure they match. */
783 if (lp_map_system(SNUM(conn))) {
784 if ((old_dos_mode & FILE_ATTRIBUTE_SYSTEM) && !(new_dos_mode & FILE_ATTRIBUTE_SYSTEM))
785 return False;
787 if (lp_map_hidden(SNUM(conn))) {
788 if ((old_dos_mode & FILE_ATTRIBUTE_HIDDEN) && !(new_dos_mode & FILE_ATTRIBUTE_HIDDEN))
789 return False;
791 return True;
794 /****************************************************************************
795 Open a file with a share mode.
796 ****************************************************************************/
798 files_struct *open_file_shared(connection_struct *conn,char *fname, SMB_STRUCT_STAT *psbuf,
799 int share_mode,int ofun, mode_t mode,int oplock_request,
800 int *Access,int *action)
802 return open_file_shared1(conn, fname, psbuf, 0, share_mode, ofun, mode,
803 oplock_request, Access, action);
806 /****************************************************************************
807 Open a file with a share mode.
808 ****************************************************************************/
810 files_struct *open_file_shared1(connection_struct *conn,char *fname, SMB_STRUCT_STAT *psbuf,
811 uint32 desired_access,
812 int share_mode,int ofun, mode_t mode,int oplock_request,
813 int *Access,int *action)
815 int flags=0;
816 int flags2=0;
817 int deny_mode = GET_DENY_MODE(share_mode);
818 BOOL allow_share_delete = GET_ALLOW_SHARE_DELETE(share_mode);
819 BOOL delete_on_close = GET_DELETE_ON_CLOSE_FLAG(share_mode);
820 BOOL file_existed = VALID_STAT(*psbuf);
821 BOOL fcbopen = False;
822 BOOL def_acl = False;
823 SMB_DEV_T dev = 0;
824 SMB_INO_T inode = 0;
825 int num_share_modes = 0;
826 BOOL all_current_opens_are_level_II = False;
827 BOOL fsp_open = False;
828 files_struct *fsp = NULL;
829 int open_mode=0;
830 uint16 port = 0;
831 mode_t new_mode = (mode_t)0;
833 if (conn->printer) {
834 /* printers are handled completely differently. Most of the passed parameters are
835 ignored */
836 if (Access)
837 *Access = DOS_OPEN_WRONLY;
838 if (action)
839 *action = FILE_WAS_CREATED;
840 return print_fsp_open(conn, fname);
843 fsp = file_new(conn);
844 if(!fsp)
845 return NULL;
847 DEBUG(10,("open_file_shared: fname = %s, share_mode = %x, ofun = %x, mode = %o, oplock request = %d\n",
848 fname, share_mode, ofun, (int)mode, oplock_request ));
850 if (!check_name(fname,conn)) {
851 file_free(fsp);
852 return NULL;
855 /* ignore any oplock requests if oplocks are disabled */
856 if (!lp_oplocks(SNUM(conn)) || global_client_failed_oplock_break) {
857 oplock_request = 0;
860 /* this is for OS/2 EAs - try and say we don't support them */
861 if (strstr(fname,".+,;=[].")) {
862 unix_ERR_class = ERRDOS;
863 /* OS/2 Workplace shell fix may be main code stream in a later release. */
864 #if 1 /* OS2_WPS_FIX - Recent versions of OS/2 need this. */
865 unix_ERR_code = ERRcannotopen;
866 #else /* OS2_WPS_FIX */
867 unix_ERR_code = ERROR_EAS_NOT_SUPPORTED;
868 #endif /* OS2_WPS_FIX */
870 DEBUG(5,("open_file_shared: OS/2 EA's are not supported.\n"));
871 file_free(fsp);
872 return NULL;
875 if ((GET_FILE_OPEN_DISPOSITION(ofun) == FILE_EXISTS_FAIL) && file_existed) {
876 DEBUG(5,("open_file_shared: create new requested for file %s and file already exists.\n",
877 fname ));
878 file_free(fsp);
879 errno = EEXIST;
880 return NULL;
883 if (CAN_WRITE(conn) && (GET_FILE_CREATE_DISPOSITION(ofun) == FILE_CREATE_IF_NOT_EXIST))
884 flags2 |= O_CREAT;
886 if (CAN_WRITE(conn) && (GET_FILE_OPEN_DISPOSITION(ofun) == FILE_EXISTS_TRUNCATE))
887 flags2 |= O_TRUNC;
889 /* We only care about matching attributes on file exists and truncate. */
890 if (file_existed && (GET_FILE_OPEN_DISPOSITION(ofun) == FILE_EXISTS_TRUNCATE)) {
891 if (!open_match_attributes(conn, fname, psbuf->st_mode, mode, &new_mode)) {
892 DEBUG(5,("open_file_shared: attributes missmatch for file %s (0%o, 0%o)\n",
893 fname, (int)psbuf->st_mode, (int)mode ));
894 file_free(fsp);
895 errno = EACCES;
896 return NULL;
900 if (GET_FILE_OPEN_DISPOSITION(ofun) == FILE_EXISTS_FAIL)
901 flags2 |= O_EXCL;
903 /* note that we ignore the append flag as
904 append does not mean the same thing under dos and unix */
906 switch (GET_OPEN_MODE(share_mode)) {
907 case DOS_OPEN_WRONLY:
908 flags = O_WRONLY;
909 if (desired_access == 0)
910 desired_access = FILE_WRITE_DATA;
911 break;
912 case DOS_OPEN_FCB:
913 fcbopen = True;
914 flags = O_RDWR;
915 if (desired_access == 0)
916 desired_access = FILE_READ_DATA|FILE_WRITE_DATA;
917 break;
918 case DOS_OPEN_RDWR:
919 flags = O_RDWR;
920 if (desired_access == 0)
921 desired_access = FILE_READ_DATA|FILE_WRITE_DATA;
922 break;
923 default:
924 flags = O_RDONLY;
925 if (desired_access == 0)
926 desired_access = FILE_READ_DATA;
927 break;
930 #if defined(O_SYNC)
931 if (GET_FILE_SYNC_OPENMODE(share_mode)) {
932 flags2 |= O_SYNC;
934 #endif /* O_SYNC */
936 if (flags != O_RDONLY && file_existed &&
937 (!CAN_WRITE(conn) || IS_DOS_READONLY(dos_mode(conn,fname,psbuf)))) {
938 if (!fcbopen) {
939 DEBUG(5,("open_file_shared: read/write access requested for file %s on read only %s\n",
940 fname, !CAN_WRITE(conn) ? "share" : "file" ));
941 file_free(fsp);
942 errno = EACCES;
943 return NULL;
945 flags = O_RDONLY;
948 if (deny_mode > DENY_NONE && deny_mode!=DENY_FCB) {
949 DEBUG(2,("Invalid deny mode %d on file %s\n",deny_mode,fname));
950 file_free(fsp);
951 errno = EINVAL;
952 return NULL;
955 if (file_existed) {
957 dev = psbuf->st_dev;
958 inode = psbuf->st_ino;
960 lock_share_entry(conn, dev, inode);
962 num_share_modes = open_mode_check(conn, fname, dev, inode,
963 desired_access,
964 share_mode,
965 &flags, &oplock_request, &all_current_opens_are_level_II);
966 if(num_share_modes == -1) {
969 * This next line is a subtlety we need for MS-Access. If a file open will
970 * fail due to share permissions and also for security (access)
971 * reasons, we need to return the access failed error, not the
972 * share error. This means we must attempt to open the file anyway
973 * in order to get the UNIX access error - even if we're going to
974 * fail the open for share reasons. This is bad, as we're burning
975 * another fd if there are existing locks but there's nothing else
976 * we can do. We also ensure we're not going to create or tuncate
977 * the file as we only want an access decision at this stage. JRA.
979 errno = 0;
980 fsp_open = open_file(fsp,conn,fname,psbuf,
981 flags|(flags2&~(O_TRUNC|O_CREAT)),mode,desired_access);
983 DEBUG(4,("open_file_shared : share_mode deny - calling open_file with \
984 flags=0x%X flags2=0x%X mode=0%o returned %d\n",
985 flags,(flags2&~(O_TRUNC|O_CREAT)),(int)mode,(int)fsp_open ));
987 if (!fsp_open && errno) {
988 unix_ERR_class = ERRDOS;
989 unix_ERR_code = ERRnoaccess;
990 unix_ERR_ntstatus = NT_STATUS_ACCESS_DENIED;
993 unlock_share_entry(conn, dev, inode);
994 if (fsp_open)
995 fd_close(conn, fsp);
996 file_free(fsp);
997 return NULL;
1001 * We exit this block with the share entry *locked*.....
1006 * Ensure we pay attention to default ACLs on directories if required.
1009 if ((flags2 & O_CREAT) && lp_inherit_acls(SNUM(conn)) &&
1010 (def_acl = directory_has_default_acl(conn, parent_dirname(fname))))
1011 mode = 0777;
1013 DEBUG(4,("calling open_file with flags=0x%X flags2=0x%X mode=0%o\n",
1014 flags,flags2,(int)mode));
1017 * open_file strips any O_TRUNC flags itself.
1020 fsp_open = open_file(fsp,conn,fname,psbuf,flags|flags2,mode,desired_access);
1022 if (!fsp_open && (flags == O_RDWR) && (errno != ENOENT) && fcbopen) {
1023 if((fsp_open = open_file(fsp,conn,fname,psbuf,O_RDONLY,mode,desired_access)) == True)
1024 flags = O_RDONLY;
1027 if (!fsp_open) {
1028 if(file_existed)
1029 unlock_share_entry(conn, dev, inode);
1030 file_free(fsp);
1031 return NULL;
1035 * Deal with the race condition where two smbd's detect the file doesn't
1036 * exist and do the create at the same time. One of them will win and
1037 * set a share mode, the other (ie. this one) should check if the
1038 * requested share mode for this create is allowed.
1041 if (!file_existed) {
1044 * Now the file exists and fsp is successfully opened,
1045 * fsp->dev and fsp->inode are valid and should replace the
1046 * dev=0,inode=0 from a non existent file. Spotted by
1047 * Nadav Danieli <nadavd@exanet.com>. JRA.
1050 dev = fsp->dev;
1051 inode = fsp->inode;
1053 lock_share_entry_fsp(fsp);
1055 num_share_modes = open_mode_check(conn, fname, dev, inode,
1056 desired_access,
1057 share_mode,
1058 &flags, &oplock_request, &all_current_opens_are_level_II);
1060 if(num_share_modes == -1) {
1061 unlock_share_entry_fsp(fsp);
1062 fd_close(conn,fsp);
1063 file_free(fsp);
1064 return NULL;
1068 * If there are any share modes set then the file *did*
1069 * exist. Ensure we return the correct value for action.
1072 if (num_share_modes > 0)
1073 file_existed = True;
1076 * We exit this block with the share entry *locked*.....
1080 /* note that we ignore failure for the following. It is
1081 basically a hack for NFS, and NFS will never set one of
1082 these only read them. Nobody but Samba can ever set a deny
1083 mode and we have already checked our more authoritative
1084 locking database for permission to set this deny mode. If
1085 the kernel refuses the operations then the kernel is wrong */
1086 kernel_flock(fsp, deny_mode);
1089 * At this point onwards, we can guarentee that the share entry
1090 * is locked, whether we created the file or not, and that the
1091 * deny mode is compatible with all current opens.
1095 * If requested, truncate the file.
1098 if (flags2&O_TRUNC) {
1100 * We are modifing the file after open - update the stat struct..
1102 if ((truncate_unless_locked(conn,fsp) == -1) || (SMB_VFS_FSTAT(fsp,fsp->fd,psbuf)==-1)) {
1103 unlock_share_entry_fsp(fsp);
1104 fd_close(conn,fsp);
1105 file_free(fsp);
1106 return NULL;
1110 switch (flags) {
1111 case O_RDONLY:
1112 open_mode = DOS_OPEN_RDONLY;
1113 break;
1114 case O_RDWR:
1115 open_mode = DOS_OPEN_RDWR;
1116 break;
1117 case O_WRONLY:
1118 open_mode = DOS_OPEN_WRONLY;
1119 break;
1122 fsp->share_mode = SET_DENY_MODE(deny_mode) |
1123 SET_OPEN_MODE(open_mode) |
1124 SET_ALLOW_SHARE_DELETE(allow_share_delete);
1126 DEBUG(10,("open_file_shared : share_mode = %x\n", fsp->share_mode ));
1128 if (Access)
1129 (*Access) = open_mode;
1131 if (action) {
1132 if (file_existed && !(flags2 & O_TRUNC))
1133 *action = FILE_WAS_OPENED;
1134 if (!file_existed)
1135 *action = FILE_WAS_CREATED;
1136 if (file_existed && (flags2 & O_TRUNC))
1137 *action = FILE_WAS_OVERWRITTEN;
1141 * Setup the oplock info in both the shared memory and
1142 * file structs.
1145 if(oplock_request && (num_share_modes == 0) &&
1146 !IS_VETO_OPLOCK_PATH(conn,fname) && set_file_oplock(fsp, oplock_request) ) {
1147 port = global_oplock_port;
1148 } else if (oplock_request && all_current_opens_are_level_II) {
1149 port = global_oplock_port;
1150 oplock_request = LEVEL_II_OPLOCK;
1151 set_file_oplock(fsp, oplock_request);
1152 } else {
1153 port = 0;
1154 oplock_request = 0;
1157 set_share_mode(fsp, port, oplock_request);
1159 if (delete_on_close) {
1160 NTSTATUS result = set_delete_on_close_internal(fsp, delete_on_close);
1162 if (NT_STATUS_V(result) != NT_STATUS_V(NT_STATUS_OK)) {
1163 /* Remember to delete the mode we just added. */
1164 del_share_mode(fsp, NULL);
1165 unlock_share_entry_fsp(fsp);
1166 fd_close(conn,fsp);
1167 file_free(fsp);
1168 return NULL;
1173 * Take care of inherited ACLs on created files - if default ACL not
1174 * selected.
1177 if (!file_existed && !def_acl) {
1179 int saved_errno = errno; /* We might get ENOSYS in the next call.. */
1181 if (SMB_VFS_FCHMOD_ACL(fsp, fsp->fd, mode) == -1 && errno == ENOSYS)
1182 errno = saved_errno; /* Ignore ENOSYS */
1184 } else if (new_mode) {
1186 int ret = -1;
1188 /* Attributes need changing. File already existed. */
1191 int saved_errno = errno; /* We might get ENOSYS in the next call.. */
1192 ret = SMB_VFS_FCHMOD_ACL(fsp, fsp->fd, new_mode);
1194 if (ret == -1 && errno == ENOSYS) {
1195 errno = saved_errno; /* Ignore ENOSYS */
1196 } else {
1197 DEBUG(5, ("open_file_shared: failed to reset attributes of file %s to 0%o\n",
1198 fname, (int)new_mode));
1199 ret = 0; /* Don't do the fchmod below. */
1203 if ((ret == -1) && (SMB_VFS_FCHMOD(fsp, fsp->fd, new_mode) == -1))
1204 DEBUG(5, ("open_file_shared: failed to reset attributes of file %s to 0%o\n",
1205 fname, (int)new_mode));
1208 unlock_share_entry_fsp(fsp);
1210 conn->num_files_open++;
1212 return fsp;
1215 /****************************************************************************
1216 Open a file for for write to ensure that we can fchmod it.
1217 ****************************************************************************/
1219 files_struct *open_file_fchmod(connection_struct *conn, const char *fname, SMB_STRUCT_STAT *psbuf)
1221 files_struct *fsp = NULL;
1222 BOOL fsp_open;
1224 if (!VALID_STAT(*psbuf))
1225 return NULL;
1227 fsp = file_new(conn);
1228 if(!fsp)
1229 return NULL;
1231 /* note! we must use a non-zero desired access or we don't get
1232 a real file descriptor. Oh what a twisted web we weave. */
1233 fsp_open = open_file(fsp,conn,fname,psbuf,O_WRONLY,0,FILE_WRITE_DATA);
1236 * This is not a user visible file open.
1237 * Don't set a share mode and don't increment
1238 * the conn->num_files_open.
1241 if (!fsp_open) {
1242 file_free(fsp);
1243 return NULL;
1246 return fsp;
1249 /****************************************************************************
1250 Close the fchmod file fd - ensure no locks are lost.
1251 ****************************************************************************/
1253 int close_file_fchmod(files_struct *fsp)
1255 int ret = fd_close(fsp->conn, fsp);
1256 file_free(fsp);
1257 return ret;
1260 /****************************************************************************
1261 Open a directory from an NT SMB call.
1262 ****************************************************************************/
1264 files_struct *open_directory(connection_struct *conn, char *fname, SMB_STRUCT_STAT *psbuf,
1265 uint32 desired_access, int share_mode, int smb_ofun, mode_t unixmode, int *action)
1267 extern struct current_user current_user;
1268 BOOL got_stat = False;
1269 files_struct *fsp = file_new(conn);
1270 BOOL delete_on_close = GET_DELETE_ON_CLOSE_FLAG(share_mode);
1272 if(!fsp)
1273 return NULL;
1275 if (VALID_STAT(*psbuf))
1276 got_stat = True;
1278 if (got_stat && (GET_FILE_OPEN_DISPOSITION(smb_ofun) == FILE_EXISTS_FAIL)) {
1279 file_free(fsp);
1280 errno = EEXIST; /* Setup so correct error is returned to client. */
1281 return NULL;
1284 if (GET_FILE_CREATE_DISPOSITION(smb_ofun) == FILE_CREATE_IF_NOT_EXIST) {
1286 if (got_stat) {
1288 if(!S_ISDIR(psbuf->st_mode)) {
1289 DEBUG(0,("open_directory: %s is not a directory !\n", fname ));
1290 file_free(fsp);
1291 errno = EACCES;
1292 return NULL;
1294 *action = FILE_WAS_OPENED;
1296 } else {
1299 * Try and create the directory.
1302 if(!CAN_WRITE(conn)) {
1303 DEBUG(2,("open_directory: failing create on read-only share\n"));
1304 file_free(fsp);
1305 errno = EACCES;
1306 return NULL;
1309 if (ms_has_wild(fname)) {
1310 file_free(fsp);
1311 DEBUG(5,("open_directory: failing create on filename %s with wildcards\n", fname));
1312 unix_ERR_class = ERRDOS;
1313 unix_ERR_code = ERRinvalidname;
1314 unix_ERR_ntstatus = NT_STATUS_OBJECT_NAME_INVALID;
1315 return NULL;
1318 if(vfs_MkDir(conn,fname, unix_mode(conn,aDIR, fname)) < 0) {
1319 DEBUG(2,("open_directory: unable to create %s. Error was %s\n",
1320 fname, strerror(errno) ));
1321 file_free(fsp);
1322 return NULL;
1325 if(SMB_VFS_STAT(conn,fname, psbuf) != 0) {
1326 file_free(fsp);
1327 return NULL;
1330 *action = FILE_WAS_CREATED;
1333 } else {
1336 * Don't create - just check that it *was* a directory.
1339 if(!got_stat) {
1340 DEBUG(3,("open_directory: unable to stat name = %s. Error was %s\n",
1341 fname, strerror(errno) ));
1342 file_free(fsp);
1343 return NULL;
1346 if(!S_ISDIR(psbuf->st_mode)) {
1347 DEBUG(0,("open_directory: %s is not a directory !\n", fname ));
1348 file_free(fsp);
1349 return NULL;
1352 *action = FILE_WAS_OPENED;
1355 DEBUG(5,("open_directory: opening directory %s\n", fname));
1358 * Setup the files_struct for it.
1361 fsp->mode = psbuf->st_mode;
1362 fsp->inode = psbuf->st_ino;
1363 fsp->dev = psbuf->st_dev;
1364 fsp->size = psbuf->st_size;
1365 fsp->vuid = current_user.vuid;
1366 fsp->file_pid = global_smbpid;
1367 fsp->can_lock = True;
1368 fsp->can_read = False;
1369 fsp->can_write = False;
1370 fsp->share_mode = share_mode;
1371 fsp->desired_access = desired_access;
1372 fsp->print_file = False;
1373 fsp->modified = False;
1374 fsp->oplock_type = NO_OPLOCK;
1375 fsp->sent_oplock_break = NO_BREAK_SENT;
1376 fsp->is_directory = True;
1377 fsp->is_stat = False;
1378 fsp->directory_delete_on_close = False;
1379 string_set(&fsp->fsp_name,fname);
1381 if (delete_on_close) {
1382 NTSTATUS result = set_delete_on_close_internal(fsp, delete_on_close);
1384 if (NT_STATUS_V(result) != NT_STATUS_V(NT_STATUS_OK)) {
1385 file_free(fsp);
1386 return NULL;
1389 conn->num_files_open++;
1391 return fsp;
1394 /****************************************************************************
1395 Open a pseudo-file (no locking checks - a 'stat' open).
1396 ****************************************************************************/
1398 files_struct *open_file_stat(connection_struct *conn, char *fname, SMB_STRUCT_STAT *psbuf)
1400 extern struct current_user current_user;
1401 files_struct *fsp = NULL;
1403 if (!VALID_STAT(*psbuf))
1404 return NULL;
1406 /* Can't 'stat' open directories. */
1407 if(S_ISDIR(psbuf->st_mode))
1408 return NULL;
1410 fsp = file_new(conn);
1411 if(!fsp)
1412 return NULL;
1414 DEBUG(5,("open_file_stat: 'opening' file %s\n", fname));
1417 * Setup the files_struct for it.
1420 fsp->mode = psbuf->st_mode;
1422 * Don't store dev or inode, we don't want any iterator
1423 * to see this.
1425 fsp->inode = (SMB_INO_T)0;
1426 fsp->dev = (SMB_DEV_T)0;
1427 fsp->size = psbuf->st_size;
1428 fsp->vuid = current_user.vuid;
1429 fsp->file_pid = global_smbpid;
1430 fsp->can_lock = False;
1431 fsp->can_read = False;
1432 fsp->can_write = False;
1433 fsp->share_mode = 0;
1434 fsp->desired_access = 0;
1435 fsp->print_file = False;
1436 fsp->modified = False;
1437 fsp->oplock_type = NO_OPLOCK;
1438 fsp->sent_oplock_break = NO_BREAK_SENT;
1439 fsp->is_directory = False;
1440 fsp->is_stat = True;
1441 fsp->directory_delete_on_close = False;
1442 string_set(&fsp->fsp_name,fname);
1444 conn->num_files_open++;
1446 return fsp;