r6225: get rid of warnings from my compiler about nested externs
[Samba/nascimento.git] / source3 / smbd / open.c
blob559994ca46c2e0fd3df110cd8ba2e3da3f63acaa
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-2004
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 struct current_user current_user;
25 extern userdom_struct current_user_info;
26 extern uint16 global_oplock_port;
27 extern uint16 global_smbpid;
28 extern BOOL global_client_failed_oplock_break;
30 struct dev_inode_bundle {
31 SMB_DEV_T dev;
32 SMB_INO_T inode;
35 /****************************************************************************
36 fd support routines - attempt to do a dos_open.
37 ****************************************************************************/
39 static int fd_open(struct connection_struct *conn, const char *fname,
40 int flags, mode_t mode)
42 int fd;
43 #ifdef O_NOFOLLOW
44 if (!lp_symlinks(SNUM(conn)))
45 flags |= O_NOFOLLOW;
46 #endif
48 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(const 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 set_saved_error_triple(ERRSRV, ERRaccess, NT_STATUS_ACCESS_DENIED);
84 /****************************************************************************
85 Change the ownership of a file to that of the parent directory.
86 Do this by fd if possible.
87 ****************************************************************************/
89 void change_owner_to_parent(connection_struct *conn, files_struct *fsp, const char *fname, SMB_STRUCT_STAT *psbuf)
91 const char *parent_path = parent_dirname(fname);
92 SMB_STRUCT_STAT parent_st;
93 int ret;
95 ret = SMB_VFS_STAT(conn, parent_path, &parent_st);
96 if (ret == -1) {
97 DEBUG(0,("change_owner_to_parent: failed to stat parent directory %s. Error was %s\n",
98 parent_path, strerror(errno) ));
99 return;
102 if (fsp && fsp->fd != -1) {
103 become_root();
104 ret = SMB_VFS_FCHOWN(fsp, fsp->fd, parent_st.st_uid, (gid_t)-1);
105 unbecome_root();
106 if (ret == -1) {
107 DEBUG(0,("change_owner_to_parent: failed to fchown file %s to parent directory uid %u. \
108 Error was %s\n",
109 fname, (unsigned int)parent_st.st_uid, strerror(errno) ));
112 DEBUG(10,("change_owner_to_parent: changed new file %s to parent directory uid %u.\n",
113 fname, (unsigned int)parent_st.st_uid ));
115 } else {
116 /* We've already done an lstat into psbuf, and we know it's a directory. If
117 we can cd into the directory and the dev/ino are the same then we can safely
118 chown without races as we're locking the directory in place by being in it.
119 This should work on any UNIX (thanks tridge :-). JRA.
122 pstring saved_dir;
123 SMB_STRUCT_STAT sbuf;
125 if (!vfs_GetWd(conn,saved_dir)) {
126 DEBUG(0,("change_owner_to_parent: failed to get current working directory\n"));
127 return;
130 /* Chdir into the new path. */
131 if (vfs_ChDir(conn, fname) == -1) {
132 DEBUG(0,("change_owner_to_parent: failed to change current working directory to %s. \
133 Error was %s\n", fname, strerror(errno) ));
134 goto out;
137 if (SMB_VFS_STAT(conn,".",&sbuf) == -1) {
138 DEBUG(0,("change_owner_to_parent: failed to stat directory '.' (%s) \
139 Error was %s\n", fname, strerror(errno)));
140 goto out;
143 /* Ensure we're pointing at the same place. */
144 if (sbuf.st_dev != psbuf->st_dev || sbuf.st_ino != psbuf->st_ino || sbuf.st_mode != psbuf->st_mode ) {
145 DEBUG(0,("change_owner_to_parent: device/inode/mode on directory %s changed. Refusing to chown !\n",
146 fname ));
147 goto out;
150 become_root();
151 ret = SMB_VFS_CHOWN(conn, ".", parent_st.st_uid, (gid_t)-1);
152 unbecome_root();
153 if (ret == -1) {
154 DEBUG(10,("change_owner_to_parent: failed to chown directory %s to parent directory uid %u. \
155 Error was %s\n",
156 fname, (unsigned int)parent_st.st_uid, strerror(errno) ));
157 goto out;
160 DEBUG(10,("change_owner_to_parent: changed ownership of new directory %s to parent directory uid %u.\n",
161 fname, (unsigned int)parent_st.st_uid ));
163 out:
165 vfs_ChDir(conn,saved_dir);
169 /****************************************************************************
170 Open a file.
171 ****************************************************************************/
173 static BOOL open_file(files_struct *fsp,connection_struct *conn,
174 const char *fname,SMB_STRUCT_STAT *psbuf,int flags,mode_t mode, uint32 desired_access)
176 int accmode = (flags & O_ACCMODE);
177 int local_flags = flags;
179 fsp->fd = -1;
180 fsp->oplock_type = NO_OPLOCK;
181 errno = EPERM;
183 /* Check permissions */
186 * This code was changed after seeing a client open request
187 * containing the open mode of (DENY_WRITE/read-only) with
188 * the 'create if not exist' bit set. The previous code
189 * would fail to open the file read only on a read-only share
190 * as it was checking the flags parameter directly against O_RDONLY,
191 * this was failing as the flags parameter was set to O_RDONLY|O_CREAT.
192 * JRA.
195 if (!CAN_WRITE(conn)) {
196 /* It's a read-only share - fail if we wanted to write. */
197 if(accmode != O_RDONLY) {
198 DEBUG(3,("Permission denied opening %s\n",fname));
199 check_for_pipe(fname);
200 return False;
201 } else if(flags & O_CREAT) {
202 /* We don't want to write - but we must make sure that O_CREAT
203 doesn't create the file if we have write access into the
204 directory.
206 flags &= ~O_CREAT;
207 local_flags &= ~O_CREAT;
212 * This little piece of insanity is inspired by the
213 * fact that an NT client can open a file for O_RDONLY,
214 * but set the create disposition to FILE_EXISTS_TRUNCATE.
215 * If the client *can* write to the file, then it expects to
216 * truncate the file, even though it is opening for readonly.
217 * Quicken uses this stupid trick in backup file creation...
218 * Thanks *greatly* to "David W. Chapman Jr." <dwcjr@inethouston.net>
219 * for helping track this one down. It didn't bite us in 2.0.x
220 * as we always opened files read-write in that release. JRA.
223 if ((accmode == O_RDONLY) && ((flags & O_TRUNC) == O_TRUNC)) {
224 DEBUG(10,("open_file: truncate requested on read-only open for file %s\n",fname ));
225 local_flags = (flags & ~O_ACCMODE)|O_RDWR;
228 if ((desired_access & (FILE_READ_DATA|FILE_WRITE_DATA|FILE_APPEND_DATA|FILE_EXECUTE)) ||
229 (local_flags & O_CREAT) || ((local_flags & O_TRUNC) == O_TRUNC) ) {
232 * We can't actually truncate here as the file may be locked.
233 * open_file_shared will take care of the truncate later. JRA.
236 local_flags &= ~O_TRUNC;
238 #if defined(O_NONBLOCK) && defined(S_ISFIFO)
240 * We would block on opening a FIFO with no one else on the
241 * other end. Do what we used to do and add O_NONBLOCK to the
242 * open flags. JRA.
245 if (VALID_STAT(*psbuf) && S_ISFIFO(psbuf->st_mode))
246 local_flags |= O_NONBLOCK;
247 #endif
249 /* Don't create files with Microsoft wildcard characters. */
250 if ((local_flags & O_CREAT) && !VALID_STAT(*psbuf) && ms_has_wild(fname)) {
251 set_saved_error_triple(ERRDOS, ERRinvalidname, NT_STATUS_OBJECT_NAME_INVALID);
252 return False;
255 /* Actually do the open */
256 fsp->fd = fd_open(conn, fname, local_flags, mode);
257 if (fsp->fd == -1) {
258 DEBUG(3,("Error opening file %s (%s) (local_flags=%d) (flags=%d)\n",
259 fname,strerror(errno),local_flags,flags));
260 check_for_pipe(fname);
261 return False;
264 /* Inherit the ACL if the file was created. */
265 if ((local_flags & O_CREAT) && !VALID_STAT(*psbuf))
266 inherit_access_acl(conn, fname, mode);
268 } else
269 fsp->fd = -1; /* What we used to call a stat open. */
271 if (!VALID_STAT(*psbuf)) {
272 int ret;
274 if (fsp->fd == -1)
275 ret = SMB_VFS_STAT(conn, fname, psbuf);
276 else {
277 ret = SMB_VFS_FSTAT(fsp,fsp->fd,psbuf);
278 /* If we have an fd, this stat should succeed. */
279 if (ret == -1)
280 DEBUG(0,("Error doing fstat on open file %s (%s)\n", fname,strerror(errno) ));
283 /* For a non-io open, this stat failing means file not found. JRA */
284 if (ret == -1) {
285 fd_close(conn, fsp);
286 return False;
291 * POSIX allows read-only opens of directories. We don't
292 * want to do this (we use a different code path for this)
293 * so catch a directory open and return an EISDIR. JRA.
296 if(S_ISDIR(psbuf->st_mode)) {
297 fd_close(conn, fsp);
298 errno = EISDIR;
299 return False;
302 fsp->mode = psbuf->st_mode;
303 fsp->inode = psbuf->st_ino;
304 fsp->dev = psbuf->st_dev;
305 fsp->vuid = current_user.vuid;
306 fsp->file_pid = global_smbpid;
307 fsp->size = psbuf->st_size;
308 fsp->can_lock = True;
309 fsp->can_read = ((flags & O_WRONLY)==0);
310 fsp->can_write = ((flags & (O_WRONLY|O_RDWR))!=0);
311 fsp->share_mode = 0;
312 fsp->desired_access = desired_access;
313 fsp->print_file = False;
314 fsp->modified = False;
315 fsp->oplock_type = NO_OPLOCK;
316 fsp->sent_oplock_break = NO_BREAK_SENT;
317 fsp->is_directory = False;
318 fsp->is_stat = False;
319 fsp->directory_delete_on_close = False;
320 string_set(&fsp->fsp_name,fname);
321 fsp->wcp = NULL; /* Write cache pointer. */
323 DEBUG(2,("%s opened file %s read=%s write=%s (numopen=%d)\n",
324 *current_user_info.smb_name ? current_user_info.smb_name : conn->user,fsp->fsp_name,
325 BOOLSTR(fsp->can_read), BOOLSTR(fsp->can_write),
326 conn->num_files_open + 1));
328 errno = 0;
329 return True;
332 /*******************************************************************
333 Return True if the filename is one of the special executable types.
334 ********************************************************************/
336 static BOOL is_executable(const char *fname)
338 if ((fname = strrchr_m(fname,'.'))) {
339 if (strequal(fname,".com") ||
340 strequal(fname,".dll") ||
341 strequal(fname,".exe") ||
342 strequal(fname,".sym")) {
343 return True;
346 return False;
349 enum {AFAIL,AREAD,AWRITE,AALL};
351 /*******************************************************************
352 Reproduce the share mode access table.
353 This is horrendoously complex, and really can't be justified on any
354 rational grounds except that this is _exactly_ what NT does. See
355 the DENY1 and DENY2 tests in smbtorture for a comprehensive set of
356 test routines.
357 ********************************************************************/
359 static int access_table(int new_deny,int old_deny,int old_mode,
360 BOOL same_pid, BOOL isexe)
362 if (new_deny == DENY_ALL || old_deny == DENY_ALL) return(AFAIL);
364 if (same_pid) {
365 if (isexe && old_mode == DOS_OPEN_RDONLY &&
366 old_deny == DENY_DOS && new_deny == DENY_READ) {
367 return AFAIL;
369 if (!isexe && old_mode == DOS_OPEN_RDONLY &&
370 old_deny == DENY_DOS && new_deny == DENY_DOS) {
371 return AREAD;
373 if (new_deny == DENY_FCB && old_deny == DENY_DOS) {
374 if (isexe) return AFAIL;
375 if (old_mode == DOS_OPEN_RDONLY) return AFAIL;
376 return AALL;
378 if (old_mode == DOS_OPEN_RDONLY && old_deny == DENY_DOS) {
379 if (new_deny == DENY_FCB || new_deny == DENY_READ) {
380 if (isexe) return AREAD;
381 return AFAIL;
384 if (old_deny == DENY_FCB) {
385 if (new_deny == DENY_DOS || new_deny == DENY_FCB) return AALL;
386 return AFAIL;
390 if (old_deny == DENY_DOS || new_deny == DENY_DOS ||
391 old_deny == DENY_FCB || new_deny == DENY_FCB) {
392 if (isexe) {
393 if (old_deny == DENY_FCB || new_deny == DENY_FCB) {
394 return AFAIL;
396 if (old_deny == DENY_DOS) {
397 if (new_deny == DENY_READ &&
398 (old_mode == DOS_OPEN_RDONLY ||
399 old_mode == DOS_OPEN_RDWR)) {
400 return AFAIL;
402 if (new_deny == DENY_WRITE &&
403 (old_mode == DOS_OPEN_WRONLY ||
404 old_mode == DOS_OPEN_RDWR)) {
405 return AFAIL;
407 return AALL;
409 if (old_deny == DENY_NONE) return AALL;
410 if (old_deny == DENY_READ) return AWRITE;
411 if (old_deny == DENY_WRITE) return AREAD;
413 /* it isn't a exe, dll, sym or com file */
414 if (old_deny == new_deny && same_pid)
415 return(AALL);
417 if (old_deny == DENY_READ || new_deny == DENY_READ) return AFAIL;
418 if (old_mode == DOS_OPEN_RDONLY) return(AREAD);
420 return(AFAIL);
423 switch (new_deny)
425 case DENY_WRITE:
426 if (old_deny==DENY_WRITE && old_mode==DOS_OPEN_RDONLY) return(AREAD);
427 if (old_deny==DENY_READ && old_mode==DOS_OPEN_RDONLY) return(AWRITE);
428 if (old_deny==DENY_NONE && old_mode==DOS_OPEN_RDONLY) return(AALL);
429 return(AFAIL);
430 case DENY_READ:
431 if (old_deny==DENY_WRITE && old_mode==DOS_OPEN_WRONLY) return(AREAD);
432 if (old_deny==DENY_READ && old_mode==DOS_OPEN_WRONLY) return(AWRITE);
433 if (old_deny==DENY_NONE && old_mode==DOS_OPEN_WRONLY) return(AALL);
434 return(AFAIL);
435 case DENY_NONE:
436 if (old_deny==DENY_WRITE) return(AREAD);
437 if (old_deny==DENY_READ) return(AWRITE);
438 if (old_deny==DENY_NONE) return(AALL);
439 return(AFAIL);
441 return(AFAIL);
444 /****************************************************************************
445 Check if we can open a file with a share mode.
446 ****************************************************************************/
448 static BOOL check_share_mode(connection_struct *conn, share_mode_entry *share, int share_mode, uint32 desired_access,
449 const char *fname, BOOL fcbopen, int *flags)
451 int deny_mode = GET_DENY_MODE(share_mode);
452 int old_open_mode = GET_OPEN_MODE(share->share_mode);
453 int old_deny_mode = GET_DENY_MODE(share->share_mode);
454 BOOL non_io_open_request;
455 BOOL non_io_open_existing;
458 * share modes = false means don't bother to check for
459 * DENY mode conflict. This is a *really* bad idea :-). JRA.
462 if(!lp_share_modes(SNUM(conn)))
463 return True;
465 if (desired_access & ~(SYNCHRONIZE_ACCESS|READ_CONTROL_ACCESS|FILE_READ_ATTRIBUTES|FILE_WRITE_ATTRIBUTES)) {
466 non_io_open_request = False;
467 } else {
468 non_io_open_request = True;
471 if (share->desired_access & ~(SYNCHRONIZE_ACCESS|READ_CONTROL_ACCESS|FILE_READ_ATTRIBUTES|FILE_WRITE_ATTRIBUTES)) {
472 non_io_open_existing = False;
473 } else {
474 non_io_open_existing = True;
478 * Don't allow any opens once the delete on close flag has been
479 * set.
482 if (GET_DELETE_ON_CLOSE_FLAG(share->share_mode)) {
483 DEBUG(5,("check_share_mode: Failing open on file %s as delete on close flag is set.\n",
484 fname ));
485 /* Use errno to map to correct error. */
486 set_saved_error_triple(SMB_SUCCESS, 0, NT_STATUS_OK);
487 return False;
490 /* this is a nasty hack, but necessary until we rewrite our open
491 handling to use a NTCreateX call as the basic call.
492 NT may open a file with neither read nor write access, and in
493 this case it expects the open not to conflict with any
494 existing deny modes. This happens (for example) during a
495 "xcopy /o" where the second file descriptor is used for
496 ACL sets
497 (tridge)
501 * This is a bit wierd - the test for desired access not having the
502 * critical bits seems seems odd. Firstly, if both opens have no
503 * critical bits then always ignore. Then check the "allow delete"
504 * then check for either. This probably isn't quite right yet but
505 * gets us much closer. JRA.
509 * If desired_access doesn't contain READ_DATA,WRITE_DATA,APPEND_DATA or EXECUTE
510 * and the existing desired_acces then share modes don't conflict.
513 if (non_io_open_request && non_io_open_existing) {
516 * Wrinkle discovered by smbtorture....
517 * If both are non-io open and requester is asking for delete and current open has delete access
518 * but neither open has allowed file share delete then deny.... this is very strange and
519 * seems to be the only case in which non-io opens conflict. JRA.
522 if ((desired_access & DELETE_ACCESS) && (share->desired_access & DELETE_ACCESS) &&
523 (!GET_ALLOW_SHARE_DELETE(share->share_mode) || !GET_ALLOW_SHARE_DELETE(share_mode))) {
524 DEBUG(5,("check_share_mode: Failing open on file %s as delete access requests conflict.\n",
525 fname ));
526 set_saved_error_triple(ERRDOS, ERRbadshare, NT_STATUS_SHARING_VIOLATION);
527 return False;
530 DEBUG(5,("check_share_mode: Allowing open on file %s as both desired access (0x%x) \
531 and existing desired access (0x%x) are non-data opens\n",
532 fname, (unsigned int)desired_access, (unsigned int)share->desired_access ));
533 return True;
534 } else if (non_io_open_request || non_io_open_existing) {
536 * If either are non-io opens then share modes don't conflict.
538 DEBUG(5,("check_share_mode: One non-io open. Allowing open on file %s as desired access (0x%x) doesn't conflict with\
539 existing desired access (0x%x).\n", fname, (unsigned int)desired_access, (unsigned int)share->desired_access ));
540 return True;
544 * If delete access was requested and the existing share mode doesn't have
545 * ALLOW_SHARE_DELETE then deny.
548 if ((desired_access & DELETE_ACCESS) && !GET_ALLOW_SHARE_DELETE(share->share_mode)) {
549 DEBUG(5,("check_share_mode: Failing open on file %s as delete access requested and allow share delete not set.\n",
550 fname ));
551 set_saved_error_triple(ERRDOS, ERRbadshare, NT_STATUS_SHARING_VIOLATION);
552 return False;
556 * The inverse of the above.
557 * If delete access was granted and the new share mode doesn't have
558 * ALLOW_SHARE_DELETE then deny.
561 if ((share->desired_access & DELETE_ACCESS) && !GET_ALLOW_SHARE_DELETE(share_mode)) {
562 DEBUG(5,("check_share_mode: Failing open on file %s as delete access granted and allow share delete not requested.\n",
563 fname ));
564 set_saved_error_triple(ERRDOS, ERRbadshare, NT_STATUS_SHARING_VIOLATION);
565 return False;
568 #if 0
569 /* Bluarc test may need this ... needs further investigation. */
570 if (deny_mode == DENY_ALL || old_deny_mode == DENY_ALL) {
571 set_saved_error_triple(ERRDOS, ERRbadshare, NT_STATUS_SHARING_VIOLATION);
572 return False;
574 #endif
577 * If desired_access doesn't contain READ_DATA,WRITE_DATA,APPEND_DATA or EXECUTE
578 * then share modes don't conflict. Likewise with existing desired access.
581 if ( !(desired_access & (FILE_READ_DATA|FILE_WRITE_DATA|FILE_APPEND_DATA|FILE_EXECUTE)) ||
582 !(share->desired_access & (FILE_READ_DATA|FILE_WRITE_DATA|FILE_APPEND_DATA|FILE_EXECUTE)) ) {
583 DEBUG(5,("check_share_mode: Allowing open on file %s as desired access (0x%x) doesn't conflict with \
584 existing desired access (0x%x).\n", fname, (unsigned int)desired_access, (unsigned int)share->desired_access ));
585 return True;
589 int access_allowed = access_table(deny_mode,old_deny_mode,old_open_mode,
590 (share->pid == sys_getpid()),is_executable(fname));
592 if ((access_allowed == AFAIL) ||
593 (!fcbopen && (access_allowed == AREAD && *flags == O_RDWR)) ||
594 (access_allowed == AREAD && *flags != O_RDONLY) ||
595 (access_allowed == AWRITE && *flags != O_WRONLY)) {
597 DEBUG(2,("Share violation on file (%d,%d,%d,%d,%s,fcbopen = %d, flags = %d) = %d\n",
598 deny_mode,old_deny_mode,old_open_mode,
599 (int)share->pid,fname, fcbopen, *flags, access_allowed));
601 set_saved_error_triple(ERRDOS, ERRbadshare, NT_STATUS_SHARING_VIOLATION);
602 return False;
605 if (access_allowed == AREAD)
606 *flags = O_RDONLY;
608 if (access_allowed == AWRITE)
609 *flags = O_WRONLY;
613 return True;
617 #if defined(DEVELOPER)
618 static void validate_my_share_entries(int num, share_mode_entry *share_entry)
620 files_struct *fsp;
622 if (share_entry->pid != sys_getpid())
623 return;
625 fsp = file_find_dif(share_entry->dev, share_entry->inode, share_entry->share_file_id);
626 if (!fsp) {
627 DEBUG(0,("validate_my_share_entries: PANIC : %s\n", share_mode_str(num, share_entry) ));
628 smb_panic("validate_my_share_entries: Cannot match a share entry with an open file\n");
631 if (((uint16)fsp->oplock_type) != share_entry->op_type) {
632 pstring str;
633 DEBUG(0,("validate_my_share_entries: PANIC : %s\n", share_mode_str(num, share_entry) ));
634 slprintf(str, sizeof(str)-1, "validate_my_share_entries: file %s, oplock_type = 0x%x, op_type = 0x%x\n",
635 fsp->fsp_name, (unsigned int)fsp->oplock_type, (unsigned int)share_entry->op_type );
636 smb_panic(str);
639 #endif
641 struct share_mode_entry_list {
642 struct share_mode_entry_list *next, *prev;
643 share_mode_entry entry;
646 static void free_broken_entry_list(struct share_mode_entry_list *broken_entry_list)
648 while (broken_entry_list) {
649 struct share_mode_entry_list *broken_entry = broken_entry_list;
650 DLIST_REMOVE(broken_entry_list, broken_entry);
651 SAFE_FREE(broken_entry);
655 /****************************************************************************
656 Deal with open deny mode and oplock break processing.
657 Invarient: Share mode must be locked on entry and exit.
658 Returns -1 on error, or number of share modes on success (may be zero).
659 ****************************************************************************/
661 static int open_mode_check(connection_struct *conn, const char *fname, SMB_DEV_T dev,
662 SMB_INO_T inode,
663 uint32 desired_access,
664 int share_mode, int *p_flags, int *p_oplock_request,
665 BOOL *p_all_current_opens_are_level_II)
667 int i;
668 int num_share_modes;
669 int oplock_contention_count = 0;
670 share_mode_entry *old_shares = NULL;
671 BOOL fcbopen = False;
672 BOOL broke_oplock;
674 if(GET_OPEN_MODE(share_mode) == DOS_OPEN_FCB)
675 fcbopen = True;
677 num_share_modes = get_share_modes(conn, dev, inode, &old_shares);
679 if(num_share_modes == 0) {
680 SAFE_FREE(old_shares);
681 return 0;
684 if (desired_access && ((desired_access & ~(SYNCHRONIZE_ACCESS|FILE_READ_ATTRIBUTES|FILE_WRITE_ATTRIBUTES))==0) &&
685 ((desired_access & (SYNCHRONIZE_ACCESS|FILE_READ_ATTRIBUTES|FILE_WRITE_ATTRIBUTES)) != 0)) {
686 /* Stat open that doesn't trigger oplock breaks or share mode checks... ! JRA. */
687 SAFE_FREE(old_shares);
688 return num_share_modes;
692 * Check if the share modes will give us access.
695 do {
696 struct share_mode_entry_list *broken_entry_list = NULL;
697 struct share_mode_entry_list *broken_entry = NULL;
699 broke_oplock = False;
700 *p_all_current_opens_are_level_II = True;
702 for(i = 0; i < num_share_modes; i++) {
703 BOOL cause_oplock_break = False;
704 share_mode_entry *share_entry = &old_shares[i];
706 #if defined(DEVELOPER)
707 validate_my_share_entries(i, share_entry);
708 #endif
711 * By observation of NetBench, oplocks are broken *before* share
712 * modes are checked. This allows a file to be closed by the client
713 * if the share mode would deny access and the client has an oplock.
714 * Check if someone has an oplock on this file. If so we must break
715 * it before continuing.
718 /* Was this a delete this file request ? */
719 if (!*p_oplock_request && desired_access == DELETE_ACCESS &&
720 !BATCH_OPLOCK_TYPE(share_entry->op_type)) {
721 /* Don't break the oplock in this case. */
722 cause_oplock_break = False;
723 } else if((*p_oplock_request && EXCLUSIVE_OPLOCK_TYPE(share_entry->op_type)) ||
724 (!*p_oplock_request && (share_entry->op_type != NO_OPLOCK))) {
725 cause_oplock_break = True;
728 if(cause_oplock_break) {
729 BOOL opb_ret;
731 DEBUG(5,("open_mode_check: oplock_request = %d, breaking oplock (%x) on file %s, \
732 dev = %x, inode = %.0f\n", *p_oplock_request, share_entry->op_type, fname, (unsigned int)dev, (double)inode));
734 /* Ensure the reply for the open uses the correct sequence number. */
735 /* This isn't a real deferred packet as it's response will also increment
736 * the sequence.
738 srv_defer_sign_response(get_current_mid());
740 /* Oplock break - unlock to request it. */
741 unlock_share_entry(conn, dev, inode);
743 opb_ret = request_oplock_break(share_entry);
745 /* Now relock. */
746 lock_share_entry(conn, dev, inode);
748 if(opb_ret == False) {
749 DEBUG(0,("open_mode_check: FAILED when breaking oplock (%x) on file %s, \
750 dev = %x, inode = %.0f\n", old_shares[i].op_type, fname, (unsigned int)dev, (double)inode));
751 SAFE_FREE(old_shares);
752 set_saved_error_triple(ERRDOS, ERRbadshare, NT_STATUS_SHARING_VIOLATION);
753 return -1;
756 broken_entry = SMB_MALLOC_P(struct share_mode_entry_list);
757 if (!broken_entry) {
758 smb_panic("open_mode_check: malloc fail.\n");
760 broken_entry->entry = *share_entry;
761 DLIST_ADD(broken_entry_list, broken_entry);
762 broke_oplock = True;
764 } else if (!LEVEL_II_OPLOCK_TYPE(share_entry->op_type)) {
765 *p_all_current_opens_are_level_II = False;
767 } /* end for */
769 if (broke_oplock) {
770 /* Update the current open table. */
771 SAFE_FREE(old_shares);
772 num_share_modes = get_share_modes(conn, dev, inode, &old_shares);
775 /* Now we check the share modes, after any oplock breaks. */
776 for(i = 0; i < num_share_modes; i++) {
777 share_mode_entry *share_entry = &old_shares[i];
779 /* someone else has a share lock on it, check to see if we can too */
780 if (!check_share_mode(conn, share_entry, share_mode, desired_access,
781 fname, fcbopen, p_flags)) {
782 SAFE_FREE(old_shares);
783 free_broken_entry_list(broken_entry_list);
784 errno = EACCES;
785 return -1;
789 for(broken_entry = broken_entry_list; broken_entry; broken_entry = broken_entry->next) {
790 oplock_contention_count++;
792 /* Paranoia check that this is no longer an exlusive entry. */
793 for(i = 0; i < num_share_modes; i++) {
794 share_mode_entry *share_entry = &old_shares[i];
796 if (share_modes_identical(&broken_entry->entry, share_entry) &&
797 EXCLUSIVE_OPLOCK_TYPE(share_entry->op_type) ) {
800 * This should not happen. The target left this oplock
801 * as exlusive.... The process *must* be dead....
804 DEBUG(0,("open_mode_check: exlusive oplock left by process %d \
805 after break ! For file %s, dev = %x, inode = %.0f. Deleting it to continue...\n",
806 (int)broken_entry->entry.pid, fname, (unsigned int)dev, (double)inode));
808 if (process_exists(broken_entry->entry.pid)) {
809 DEBUG(0,("open_mode_check: Existent process %lu left active oplock.\n",
810 (unsigned long)broken_entry->entry.pid ));
813 if (del_share_entry(dev, inode, &broken_entry->entry, NULL) == -1) {
814 free_broken_entry_list(broken_entry_list);
815 errno = EACCES;
816 set_saved_error_triple(ERRDOS, ERRbadshare, NT_STATUS_SHARING_VIOLATION);
817 return -1;
821 * We must reload the share modes after deleting the
822 * other process's entry.
825 SAFE_FREE(old_shares);
826 num_share_modes = get_share_modes(conn, dev, inode, &old_shares);
827 break;
829 } /* end for paranoia... */
830 } /* end for broken_entry */
831 free_broken_entry_list(broken_entry_list);
832 } while(broke_oplock);
835 * Refuse to grant an oplock in case the contention limit is
836 * reached when going through the lock list multiple times.
839 if(oplock_contention_count >= lp_oplock_contention_limit(SNUM(conn))) {
840 *p_oplock_request = 0;
841 DEBUG(4,("open_mode_check: oplock contention = %d. Not granting oplock.\n",
842 oplock_contention_count ));
845 SAFE_FREE(old_shares);
846 return num_share_modes;
849 /****************************************************************************
850 Delete the record for a handled deferred open entry.
851 ****************************************************************************/
853 static void delete_defered_open_entry_record(connection_struct *conn, SMB_DEV_T dev, SMB_INO_T inode)
855 uint16 mid = get_current_mid();
856 pid_t mypid = sys_getpid();
857 deferred_open_entry *de_array = NULL;
858 int num_de_entries, i;
860 if (!lp_defer_sharing_violations()) {
861 return;
864 num_de_entries = get_deferred_opens(conn, dev, inode, &de_array);
865 for (i = 0; i < num_de_entries; i++) {
866 deferred_open_entry *entry = &de_array[i];
867 if (entry->pid == mypid && entry->mid == mid && entry->dev == dev &&
868 entry->inode == inode) {
870 /* Remove the deferred open entry from the array. */
871 delete_deferred_open_entry(entry);
872 SAFE_FREE(de_array);
873 return;
876 SAFE_FREE(de_array);
879 /****************************************************************************
880 Handle the 1 second delay in returning a SHARING_VIOLATION error.
881 ****************************************************************************/
883 void defer_open_sharing_error(connection_struct *conn, struct timeval *ptv,
884 char *fname, SMB_DEV_T dev, SMB_INO_T inode)
886 uint16 mid = get_current_mid();
887 pid_t mypid = sys_getpid();
888 deferred_open_entry *de_array = NULL;
889 int num_de_entries, i;
890 struct dev_inode_bundle dib;
892 if (!lp_defer_sharing_violations()) {
893 return;
896 dib.dev = dev;
897 dib.inode = inode;
899 num_de_entries = get_deferred_opens(conn, dev, inode, &de_array);
900 for (i = 0; i < num_de_entries; i++) {
901 deferred_open_entry *entry = &de_array[i];
902 if (entry->pid == mypid && entry->mid == mid) {
904 * Check if a 1 second timeout has expired.
906 if (usec_time_diff(ptv, &entry->time) > SHARING_VIOLATION_USEC_WAIT) {
907 DEBUG(10,("defer_open_sharing_error: Deleting deferred open entry for mid %u, \
908 file %s\n",
909 (unsigned int)mid, fname ));
911 /* Expired, return a real error. */
912 /* Remove the deferred open entry from the array. */
914 delete_deferred_open_entry(entry);
915 SAFE_FREE(de_array);
916 return;
919 * If the timeout hasn't expired yet and we still have a sharing violation,
920 * just leave the entry in the deferred open array alone. We do need to
921 * reschedule this open call though (with the original created time).
923 DEBUG(10,("defer_open_sharing_error: time [%u.%06u] updating \
924 deferred open entry for mid %u, file %s\n",
925 (unsigned int)entry->time.tv_sec,
926 (unsigned int)entry->time.tv_usec,
927 (unsigned int)mid, fname ));
929 push_sharing_violation_open_smb_message(&entry->time, (char *)&dib, sizeof(dib));
930 SAFE_FREE(de_array);
931 return;
935 DEBUG(10,("defer_open_sharing_error: time [%u.%06u] adding deferred open entry for mid %u, file %s\n",
936 (unsigned int)ptv->tv_sec, (unsigned int)ptv->tv_usec, (unsigned int)mid, fname ));
938 if (!push_sharing_violation_open_smb_message(ptv, (char *)&dib, sizeof(dib))) {
939 SAFE_FREE(de_array);
940 return;
942 if (!add_deferred_open(mid, ptv, dev, inode, global_oplock_port, fname)) {
943 remove_sharing_violation_open_smb_message(mid);
947 * Push the MID of this packet on the signing queue.
948 * We only do this once, the first time we push the packet
949 * onto the deferred open queue, as this has a side effect
950 * of incrementing the response sequence number.
953 srv_defer_sign_response(mid);
955 SAFE_FREE(de_array);
958 /****************************************************************************
959 Set a kernel flock on a file for NFS interoperability.
960 This requires a patch to Linux.
961 ****************************************************************************/
963 static void kernel_flock(files_struct *fsp, int deny_mode)
965 #if HAVE_KERNEL_SHARE_MODES
966 int kernel_mode = 0;
967 if (deny_mode == DENY_READ) kernel_mode = LOCK_MAND|LOCK_WRITE;
968 else if (deny_mode == DENY_WRITE) kernel_mode = LOCK_MAND|LOCK_READ;
969 else if (deny_mode == DENY_ALL) kernel_mode = LOCK_MAND;
970 if (kernel_mode) flock(fsp->fd, kernel_mode);
971 #endif
976 static BOOL open_match_attributes(connection_struct *conn, const char *path, uint32 old_dos_mode, uint32 new_dos_mode,
977 mode_t existing_mode, mode_t new_mode, mode_t *returned_mode)
979 uint32 noarch_old_dos_mode, noarch_new_dos_mode;
981 noarch_old_dos_mode = (old_dos_mode & ~FILE_ATTRIBUTE_ARCHIVE);
982 noarch_new_dos_mode = (new_dos_mode & ~FILE_ATTRIBUTE_ARCHIVE);
984 if((noarch_old_dos_mode == 0 && noarch_new_dos_mode != 0) ||
985 (noarch_old_dos_mode != 0 && ((noarch_old_dos_mode & noarch_new_dos_mode) == noarch_old_dos_mode)))
986 *returned_mode = new_mode;
987 else
988 *returned_mode = (mode_t)0;
990 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",
991 path,
992 old_dos_mode, (unsigned int)existing_mode, new_dos_mode, (unsigned int)*returned_mode ));
994 /* If we're mapping SYSTEM and HIDDEN ensure they match. */
995 if (lp_map_system(SNUM(conn)) || lp_store_dos_attributes(SNUM(conn))) {
996 if ((old_dos_mode & FILE_ATTRIBUTE_SYSTEM) && !(new_dos_mode & FILE_ATTRIBUTE_SYSTEM))
997 return False;
999 if (lp_map_hidden(SNUM(conn)) || lp_store_dos_attributes(SNUM(conn))) {
1000 if ((old_dos_mode & FILE_ATTRIBUTE_HIDDEN) && !(new_dos_mode & FILE_ATTRIBUTE_HIDDEN))
1001 return False;
1003 return True;
1006 /****************************************************************************
1007 Open a file with a share mode.
1008 ****************************************************************************/
1010 files_struct *open_file_shared(connection_struct *conn,char *fname, SMB_STRUCT_STAT *psbuf,
1011 int share_mode,int ofun, uint32 new_dos_mode, int oplock_request,
1012 int *Access,int *action)
1014 return open_file_shared1(conn, fname, psbuf, 0, share_mode, ofun, new_dos_mode,
1015 oplock_request, Access, action);
1018 /****************************************************************************
1019 Open a file with a share mode.
1020 ****************************************************************************/
1022 files_struct *open_file_shared1(connection_struct *conn,char *fname, SMB_STRUCT_STAT *psbuf,
1023 uint32 desired_access,
1024 int share_mode,int ofun, uint32 new_dos_mode,
1025 int oplock_request,
1026 int *Access,int *paction)
1028 int flags=0;
1029 int flags2=0;
1030 int deny_mode = GET_DENY_MODE(share_mode);
1031 BOOL allow_share_delete = GET_ALLOW_SHARE_DELETE(share_mode);
1032 BOOL delete_on_close = GET_DELETE_ON_CLOSE_FLAG(share_mode);
1033 BOOL file_existed = VALID_STAT(*psbuf);
1034 BOOL fcbopen = False;
1035 BOOL def_acl = False;
1036 BOOL add_share_mode = True;
1037 BOOL internal_only_open = False;
1038 SMB_DEV_T dev = 0;
1039 SMB_INO_T inode = 0;
1040 int num_share_modes = 0;
1041 BOOL all_current_opens_are_level_II = False;
1042 BOOL fsp_open = False;
1043 files_struct *fsp = NULL;
1044 int open_mode=0;
1045 uint16 port = 0;
1046 mode_t new_mode = (mode_t)0;
1047 int action;
1048 uint32 existing_dos_mode = 0;
1049 struct pending_message_list *pml = NULL;
1050 uint16 mid = get_current_mid();
1051 /* We add aARCH to this as this mode is only used if the file is created new. */
1052 mode_t mode = unix_mode(conn,new_dos_mode | aARCH,fname, True);
1054 if (oplock_request == INTERNAL_OPEN_ONLY) {
1055 internal_only_open = True;
1056 oplock_request = 0;
1059 if ((pml = get_open_deferred_message(mid)) != NULL) {
1060 struct dev_inode_bundle dib;
1062 memcpy(&dib, pml->private_data.data, sizeof(dib));
1064 /* There could be a race condition where the dev/inode pair
1065 has changed since we deferred the message. If so, just
1066 remove the deferred open entry and return sharing violation. */
1068 /* If the timeout value is non-zero, we need to just
1069 return sharing violation. Don't retry the open
1070 as we were not notified of a close and we don't want to
1071 trigger another spurious oplock break. */
1073 if (!file_existed || dib.dev != psbuf->st_dev || dib.inode != psbuf->st_ino ||
1074 pml->msg_time.tv_sec || pml->msg_time.tv_usec) {
1075 /* Ensure we don't reprocess this message. */
1076 remove_sharing_violation_open_smb_message(mid);
1078 /* Now remove the deferred open entry under lock. */
1079 lock_share_entry(conn, dib.dev, dib.inode);
1080 delete_defered_open_entry_record(conn, dib.dev, dib.inode);
1081 unlock_share_entry(conn, dib.dev, dib.inode);
1083 set_saved_error_triple(ERRDOS, ERRbadshare, NT_STATUS_SHARING_VIOLATION);
1084 return NULL;
1086 /* Ensure we don't reprocess this message. */
1087 remove_sharing_violation_open_smb_message(mid);
1091 if (conn->printer) {
1092 /* printers are handled completely differently. Most of the passed parameters are
1093 ignored */
1094 if (Access)
1095 *Access = DOS_OPEN_WRONLY;
1096 if (paction)
1097 *paction = FILE_WAS_CREATED;
1098 return print_fsp_open(conn, fname);
1101 DEBUG(10,("open_file_shared: fname = %s, dos_attrs = %x, share_mode = %x, ofun = %x, mode = %o, oplock request = %d\n",
1102 fname, new_dos_mode, share_mode, ofun, (int)mode, oplock_request ));
1104 if (!check_name(fname,conn)) {
1105 return NULL;
1108 new_dos_mode &= SAMBA_ATTRIBUTES_MASK;
1109 if (file_existed) {
1110 existing_dos_mode = dos_mode(conn, fname, psbuf);
1113 /* ignore any oplock requests if oplocks are disabled */
1114 if (!lp_oplocks(SNUM(conn)) || global_client_failed_oplock_break) {
1115 oplock_request = 0;
1118 /* this is for OS/2 long file names - say we don't support them */
1119 if (strstr(fname,".+,;=[].")) {
1120 /* OS/2 Workplace shell fix may be main code stream in a later release. */
1121 set_saved_error_triple(ERRDOS, ERRcannotopen, NT_STATUS_OBJECT_NAME_NOT_FOUND);
1122 DEBUG(5,("open_file_shared: OS/2 long filenames are not supported.\n"));
1123 return NULL;
1126 if ((GET_FILE_OPEN_DISPOSITION(ofun) == FILE_EXISTS_FAIL) && file_existed) {
1127 DEBUG(5,("open_file_shared: create new requested for file %s and file already exists.\n",
1128 fname ));
1129 if (S_ISDIR(psbuf->st_mode)) {
1130 errno = EISDIR;
1131 } else {
1132 errno = EEXIST;
1134 return NULL;
1137 if (CAN_WRITE(conn) && (GET_FILE_CREATE_DISPOSITION(ofun) == FILE_CREATE_IF_NOT_EXIST))
1138 flags2 |= O_CREAT;
1140 if (CAN_WRITE(conn) && (GET_FILE_OPEN_DISPOSITION(ofun) == FILE_EXISTS_TRUNCATE))
1141 flags2 |= O_TRUNC;
1143 /* We only care about matching attributes on file exists and truncate. */
1144 if (file_existed && (GET_FILE_OPEN_DISPOSITION(ofun) == FILE_EXISTS_TRUNCATE)) {
1145 if (!open_match_attributes(conn, fname, existing_dos_mode, new_dos_mode,
1146 psbuf->st_mode, mode, &new_mode)) {
1147 DEBUG(5,("open_file_shared: attributes missmatch for file %s (%x %x) (0%o, 0%o)\n",
1148 fname, existing_dos_mode, new_dos_mode,
1149 (int)psbuf->st_mode, (int)mode ));
1150 errno = EACCES;
1151 return NULL;
1155 if (GET_FILE_OPEN_DISPOSITION(ofun) == FILE_EXISTS_FAIL)
1156 flags2 |= O_EXCL;
1158 /* note that we ignore the append flag as
1159 append does not mean the same thing under dos and unix */
1161 switch (GET_OPEN_MODE(share_mode)) {
1162 case DOS_OPEN_RDONLY:
1163 flags = O_RDONLY;
1164 if (desired_access == 0)
1165 desired_access = FILE_READ_DATA;
1166 break;
1167 case DOS_OPEN_WRONLY:
1168 flags = O_WRONLY;
1169 if (desired_access == 0)
1170 desired_access = FILE_WRITE_DATA;
1171 break;
1172 case DOS_OPEN_FCB:
1173 fcbopen = True;
1174 flags = O_RDWR;
1175 if (desired_access == 0)
1176 desired_access = FILE_READ_DATA|FILE_WRITE_DATA;
1177 break;
1178 case DOS_OPEN_RDWR:
1179 case DOS_OPEN_EXEC:
1180 flags = O_RDWR;
1181 if (desired_access == 0)
1182 desired_access = FILE_READ_DATA|FILE_WRITE_DATA;
1183 break;
1184 default:
1185 /* Force DOS error. */
1186 set_saved_error_triple(ERRDOS, ERRinvalidparam, NT_STATUS_INVALID);
1187 return NULL;
1190 #if defined(O_SYNC)
1191 if (GET_FILE_SYNC_OPENMODE(share_mode)) {
1192 flags2 |= O_SYNC;
1194 #endif /* O_SYNC */
1196 if (flags != O_RDONLY && file_existed &&
1197 (!CAN_WRITE(conn) || IS_DOS_READONLY(existing_dos_mode))) {
1198 if (!fcbopen) {
1199 DEBUG(5,("open_file_shared: read/write access requested for file %s on read only %s\n",
1200 fname, !CAN_WRITE(conn) ? "share" : "file" ));
1201 errno = EACCES;
1202 return NULL;
1204 flags = O_RDONLY;
1207 if (deny_mode > DENY_NONE && deny_mode!=DENY_FCB) {
1208 DEBUG(2,("Invalid deny mode %d on file %s\n",deny_mode,fname));
1209 errno = EINVAL;
1210 return NULL;
1213 if (desired_access && ((desired_access & ~(SYNCHRONIZE_ACCESS|FILE_READ_ATTRIBUTES|FILE_WRITE_ATTRIBUTES))==0) &&
1214 ((desired_access & (SYNCHRONIZE_ACCESS|FILE_READ_ATTRIBUTES|FILE_WRITE_ATTRIBUTES)) != 0)) {
1215 /* Stat open that doesn't trigger oplock breaks or share mode checks... ! JRA. */
1216 deny_mode = DENY_NONE;
1217 if (file_existed) {
1218 oplock_request = 0;
1219 add_share_mode = False;
1220 flags2 &= ~O_CREAT;
1224 fsp = file_new(conn);
1225 if(!fsp)
1226 return NULL;
1228 if (file_existed) {
1230 dev = psbuf->st_dev;
1231 inode = psbuf->st_ino;
1233 lock_share_entry(conn, dev, inode);
1235 num_share_modes = open_mode_check(conn, fname, dev, inode,
1236 desired_access,
1237 share_mode,
1238 &flags, &oplock_request, &all_current_opens_are_level_II);
1239 if(num_share_modes == -1) {
1242 * This next line is a subtlety we need for MS-Access. If a file open will
1243 * fail due to share permissions and also for security (access)
1244 * reasons, we need to return the access failed error, not the
1245 * share error. This means we must attempt to open the file anyway
1246 * in order to get the UNIX access error - even if we're going to
1247 * fail the open for share reasons. This is bad, as we're burning
1248 * another fd if there are existing locks but there's nothing else
1249 * we can do. We also ensure we're not going to create or tuncate
1250 * the file as we only want an access decision at this stage. JRA.
1252 errno = 0;
1253 fsp_open = open_file(fsp,conn,fname,psbuf,
1254 flags|(flags2&~(O_TRUNC|O_CREAT)),mode,desired_access);
1256 DEBUG(4,("open_file_shared : share_mode deny - calling open_file with \
1257 flags=0x%X flags2=0x%X mode=0%o returned %d\n",
1258 flags,(flags2&~(O_TRUNC|O_CREAT)),(int)mode,(int)fsp_open ));
1260 if (!fsp_open && errno) {
1261 /* Default error. */
1262 set_saved_error_triple(ERRDOS, ERRnoaccess, NT_STATUS_ACCESS_DENIED);
1266 * If we're returning a share violation, ensure we cope with
1267 * the braindead 1 second delay.
1270 if (!internal_only_open) {
1271 NTSTATUS status;
1272 get_saved_error_triple(NULL, NULL, &status);
1273 if (NT_STATUS_EQUAL(status,NT_STATUS_SHARING_VIOLATION)) {
1274 /* The fsp->open_time here represents the current time of day. */
1275 defer_open_sharing_error(conn, &fsp->open_time, fname, dev, inode);
1279 unlock_share_entry(conn, dev, inode);
1280 if (fsp_open) {
1281 fd_close(conn, fsp);
1283 * We have detected a sharing violation here
1284 * so return the correct error code
1286 set_saved_error_triple(ERRDOS, ERRbadshare, NT_STATUS_SHARING_VIOLATION);
1288 file_free(fsp);
1289 return NULL;
1293 * We exit this block with the share entry *locked*.....
1298 * Ensure we pay attention to default ACLs on directories if required.
1301 if ((flags2 & O_CREAT) && lp_inherit_acls(SNUM(conn)) &&
1302 (def_acl = directory_has_default_acl(conn, parent_dirname(fname))))
1303 mode = 0777;
1305 DEBUG(4,("calling open_file with flags=0x%X flags2=0x%X mode=0%o\n",
1306 flags,flags2,(int)mode));
1309 * open_file strips any O_TRUNC flags itself.
1312 fsp_open = open_file(fsp,conn,fname,psbuf,flags|flags2,mode,desired_access);
1314 if (!fsp_open && (flags == O_RDWR) && (errno != ENOENT) && fcbopen) {
1315 if((fsp_open = open_file(fsp,conn,fname,psbuf,O_RDONLY,mode,desired_access)) == True)
1316 flags = O_RDONLY;
1319 if (!fsp_open) {
1320 if(file_existed)
1321 unlock_share_entry(conn, dev, inode);
1322 file_free(fsp);
1323 return NULL;
1327 * Deal with the race condition where two smbd's detect the file doesn't
1328 * exist and do the create at the same time. One of them will win and
1329 * set a share mode, the other (ie. this one) should check if the
1330 * requested share mode for this create is allowed.
1333 if (!file_existed) {
1336 * Now the file exists and fsp is successfully opened,
1337 * fsp->dev and fsp->inode are valid and should replace the
1338 * dev=0,inode=0 from a non existent file. Spotted by
1339 * Nadav Danieli <nadavd@exanet.com>. JRA.
1342 dev = fsp->dev;
1343 inode = fsp->inode;
1345 lock_share_entry_fsp(fsp);
1347 num_share_modes = open_mode_check(conn, fname, dev, inode,
1348 desired_access,
1349 share_mode,
1350 &flags, &oplock_request, &all_current_opens_are_level_II);
1352 if(num_share_modes == -1) {
1354 * If we're returning a share violation, ensure we cope with
1355 * the braindead 1 second delay.
1358 NTSTATUS status;
1359 get_saved_error_triple(NULL, NULL, &status);
1360 if (NT_STATUS_EQUAL(status,NT_STATUS_SHARING_VIOLATION)) {
1361 /* The fsp->open_time here represents the current time of day. */
1362 defer_open_sharing_error(conn, &fsp->open_time, fname, dev, inode);
1365 unlock_share_entry_fsp(fsp);
1366 fd_close(conn,fsp);
1367 file_free(fsp);
1369 * We have detected a sharing violation here, so
1370 * return the correct code.
1372 set_saved_error_triple(ERRDOS, ERRbadshare, NT_STATUS_SHARING_VIOLATION);
1373 return NULL;
1377 * If there are any share modes set then the file *did*
1378 * exist. Ensure we return the correct value for action.
1381 if (num_share_modes > 0)
1382 file_existed = True;
1385 * We exit this block with the share entry *locked*.....
1389 /* note that we ignore failure for the following. It is
1390 basically a hack for NFS, and NFS will never set one of
1391 these only read them. Nobody but Samba can ever set a deny
1392 mode and we have already checked our more authoritative
1393 locking database for permission to set this deny mode. If
1394 the kernel refuses the operations then the kernel is wrong */
1395 kernel_flock(fsp, deny_mode);
1398 * At this point onwards, we can guarentee that the share entry
1399 * is locked, whether we created the file or not, and that the
1400 * deny mode is compatible with all current opens.
1404 * If requested, truncate the file.
1407 if (flags2&O_TRUNC) {
1409 * We are modifing the file after open - update the stat struct..
1411 if ((SMB_VFS_FTRUNCATE(fsp,fsp->fd,0) == -1) || (SMB_VFS_FSTAT(fsp,fsp->fd,psbuf)==-1)) {
1412 unlock_share_entry_fsp(fsp);
1413 fd_close(conn,fsp);
1414 file_free(fsp);
1415 return NULL;
1419 switch (flags) {
1420 case O_RDONLY:
1421 open_mode = DOS_OPEN_RDONLY;
1422 break;
1423 case O_RDWR:
1424 open_mode = DOS_OPEN_RDWR;
1425 break;
1426 case O_WRONLY:
1427 open_mode = DOS_OPEN_WRONLY;
1428 break;
1431 fsp->share_mode = SET_DENY_MODE(deny_mode) |
1432 SET_OPEN_MODE(open_mode) |
1433 SET_ALLOW_SHARE_DELETE(allow_share_delete);
1435 DEBUG(10,("open_file_shared : share_mode = %x\n", fsp->share_mode ));
1437 if (Access) {
1438 (*Access) = (SET_DENY_MODE(deny_mode) | SET_OPEN_MODE(open_mode));
1441 action = 0;
1443 if (file_existed && !(flags2 & O_TRUNC))
1444 action = FILE_WAS_OPENED;
1445 if (file_existed && (flags2 & O_TRUNC))
1446 action = FILE_WAS_OVERWRITTEN;
1447 if (!file_existed) {
1448 action = FILE_WAS_CREATED;
1449 /* Change the owner if required. */
1450 if (lp_inherit_owner(SNUM(conn))) {
1451 change_owner_to_parent(conn, fsp, fsp->fsp_name, psbuf);
1455 if (paction) {
1456 *paction = action;
1460 * Setup the oplock info in both the shared memory and
1461 * file structs.
1464 if(oplock_request && (num_share_modes == 0) &&
1465 !IS_VETO_OPLOCK_PATH(conn,fname) && set_file_oplock(fsp, oplock_request) ) {
1466 port = global_oplock_port;
1467 } else if (oplock_request && all_current_opens_are_level_II) {
1468 port = global_oplock_port;
1469 oplock_request = LEVEL_II_OPLOCK;
1470 set_file_oplock(fsp, oplock_request);
1471 } else {
1472 port = 0;
1473 oplock_request = 0;
1476 if (add_share_mode) {
1477 set_share_mode(fsp, port, oplock_request);
1480 if (delete_on_close) {
1481 uint32 dosmode = existing_dos_mode;
1482 NTSTATUS result;
1484 if (action == FILE_WAS_OVERWRITTEN || action == FILE_WAS_CREATED) {
1485 dosmode = new_dos_mode;
1487 result = set_delete_on_close_internal(fsp, delete_on_close, dosmode);
1489 if (NT_STATUS_V(result) != NT_STATUS_V(NT_STATUS_OK)) {
1490 uint8 u_e_c;
1491 uint32 u_e_code;
1492 /* Remember to delete the mode we just added. */
1493 if (add_share_mode) {
1494 del_share_mode(fsp, NULL);
1496 unlock_share_entry_fsp(fsp);
1497 fd_close(conn,fsp);
1498 file_free(fsp);
1499 ntstatus_to_dos(result, &u_e_c, &u_e_code);
1500 set_saved_error_triple(u_e_c, u_e_code, result);
1501 return NULL;
1505 if (action == FILE_WAS_OVERWRITTEN || action == FILE_WAS_CREATED) {
1506 /* Files should be initially set as archive */
1507 if (lp_map_archive(SNUM(conn)) || lp_store_dos_attributes(SNUM(conn))) {
1508 file_set_dosmode(conn, fname, new_dos_mode | aARCH, NULL, True);
1513 * Take care of inherited ACLs on created files - if default ACL not
1514 * selected.
1517 if (!file_existed && !def_acl) {
1519 int saved_errno = errno; /* We might get ENOSYS in the next call.. */
1521 if (SMB_VFS_FCHMOD_ACL(fsp, fsp->fd, mode) == -1 && errno == ENOSYS)
1522 errno = saved_errno; /* Ignore ENOSYS */
1524 } else if (new_mode) {
1526 int ret = -1;
1528 /* Attributes need changing. File already existed. */
1531 int saved_errno = errno; /* We might get ENOSYS in the next call.. */
1532 ret = SMB_VFS_FCHMOD_ACL(fsp, fsp->fd, new_mode);
1534 if (ret == -1 && errno == ENOSYS) {
1535 errno = saved_errno; /* Ignore ENOSYS */
1536 } else {
1537 DEBUG(5, ("open_file_shared: failed to reset attributes of file %s to 0%o\n",
1538 fname, (int)new_mode));
1539 ret = 0; /* Don't do the fchmod below. */
1543 if ((ret == -1) && (SMB_VFS_FCHMOD(fsp, fsp->fd, new_mode) == -1))
1544 DEBUG(5, ("open_file_shared: failed to reset attributes of file %s to 0%o\n",
1545 fname, (int)new_mode));
1548 /* If this is a successful open, we must remove any deferred open records. */
1549 delete_defered_open_entry_record(conn, fsp->dev, fsp->inode);
1550 unlock_share_entry_fsp(fsp);
1552 conn->num_files_open++;
1554 return fsp;
1557 /****************************************************************************
1558 Open a file for for write to ensure that we can fchmod it.
1559 ****************************************************************************/
1561 files_struct *open_file_fchmod(connection_struct *conn, const char *fname, SMB_STRUCT_STAT *psbuf)
1563 files_struct *fsp = NULL;
1564 BOOL fsp_open;
1566 if (!VALID_STAT(*psbuf))
1567 return NULL;
1569 fsp = file_new(conn);
1570 if(!fsp)
1571 return NULL;
1573 /* note! we must use a non-zero desired access or we don't get
1574 a real file descriptor. Oh what a twisted web we weave. */
1575 fsp_open = open_file(fsp,conn,fname,psbuf,O_WRONLY,0,FILE_WRITE_DATA);
1578 * This is not a user visible file open.
1579 * Don't set a share mode and don't increment
1580 * the conn->num_files_open.
1583 if (!fsp_open) {
1584 file_free(fsp);
1585 return NULL;
1588 return fsp;
1591 /****************************************************************************
1592 Close the fchmod file fd - ensure no locks are lost.
1593 ****************************************************************************/
1595 int close_file_fchmod(files_struct *fsp)
1597 int ret = fd_close(fsp->conn, fsp);
1598 file_free(fsp);
1599 return ret;
1602 /****************************************************************************
1603 Open a directory from an NT SMB call.
1604 ****************************************************************************/
1606 files_struct *open_directory(connection_struct *conn, const char *fname, SMB_STRUCT_STAT *psbuf,
1607 uint32 desired_access, int share_mode, int smb_ofun, int *action)
1609 BOOL got_stat = False;
1610 files_struct *fsp = file_new(conn);
1611 BOOL delete_on_close = GET_DELETE_ON_CLOSE_FLAG(share_mode);
1613 if(!fsp)
1614 return NULL;
1616 if (VALID_STAT(*psbuf))
1617 got_stat = True;
1619 if (got_stat && (GET_FILE_OPEN_DISPOSITION(smb_ofun) == FILE_EXISTS_FAIL)) {
1620 file_free(fsp);
1621 errno = EEXIST; /* Setup so correct error is returned to client. */
1622 return NULL;
1625 if (GET_FILE_CREATE_DISPOSITION(smb_ofun) == FILE_CREATE_IF_NOT_EXIST) {
1627 if (got_stat) {
1629 if(!S_ISDIR(psbuf->st_mode)) {
1630 DEBUG(0,("open_directory: %s is not a directory !\n", fname ));
1631 file_free(fsp);
1632 errno = EACCES;
1633 return NULL;
1635 *action = FILE_WAS_OPENED;
1637 } else {
1640 * Try and create the directory.
1643 /* We know bad_path is false as it's caught earlier. */
1645 NTSTATUS status = mkdir_internal(conn, fname, False);
1647 if (!NT_STATUS_IS_OK(status)) {
1648 DEBUG(2,("open_directory: unable to create %s. Error was %s\n",
1649 fname, strerror(errno) ));
1650 file_free(fsp);
1651 /* Ensure we return the correct NT status to the client. */
1652 set_saved_error_triple(0, 0, status);
1653 return NULL;
1656 /* Ensure we're checking for a symlink here.... */
1657 /* We don't want to get caught by a symlink racer. */
1659 if(SMB_VFS_LSTAT(conn,fname, psbuf) != 0) {
1660 file_free(fsp);
1661 return NULL;
1664 if(!S_ISDIR(psbuf->st_mode)) {
1665 DEBUG(0,("open_directory: %s is not a directory !\n", fname ));
1666 file_free(fsp);
1667 return NULL;
1670 *action = FILE_WAS_CREATED;
1673 } else {
1676 * Don't create - just check that it *was* a directory.
1679 if(!got_stat) {
1680 DEBUG(3,("open_directory: unable to stat name = %s. Error was %s\n",
1681 fname, strerror(errno) ));
1682 file_free(fsp);
1683 return NULL;
1686 if(!S_ISDIR(psbuf->st_mode)) {
1687 DEBUG(0,("open_directory: %s is not a directory !\n", fname ));
1688 file_free(fsp);
1689 return NULL;
1692 *action = FILE_WAS_OPENED;
1695 DEBUG(5,("open_directory: opening directory %s\n", fname));
1698 * Setup the files_struct for it.
1701 fsp->mode = psbuf->st_mode;
1702 fsp->inode = psbuf->st_ino;
1703 fsp->dev = psbuf->st_dev;
1704 fsp->size = psbuf->st_size;
1705 fsp->vuid = current_user.vuid;
1706 fsp->file_pid = global_smbpid;
1707 fsp->can_lock = True;
1708 fsp->can_read = False;
1709 fsp->can_write = False;
1710 fsp->share_mode = share_mode;
1711 fsp->desired_access = desired_access;
1712 fsp->print_file = False;
1713 fsp->modified = False;
1714 fsp->oplock_type = NO_OPLOCK;
1715 fsp->sent_oplock_break = NO_BREAK_SENT;
1716 fsp->is_directory = True;
1717 fsp->is_stat = False;
1718 fsp->directory_delete_on_close = False;
1719 string_set(&fsp->fsp_name,fname);
1721 if (delete_on_close) {
1722 NTSTATUS status = set_delete_on_close_internal(fsp, delete_on_close, 0);
1724 if (!NT_STATUS_IS_OK(status)) {
1725 file_free(fsp);
1726 return NULL;
1730 /* Change the owner if required. */
1731 if ((*action == FILE_WAS_CREATED) && lp_inherit_owner(SNUM(conn))) {
1732 change_owner_to_parent(conn, fsp, fsp->fsp_name, psbuf);
1735 conn->num_files_open++;
1737 return fsp;
1740 /****************************************************************************
1741 Open a pseudo-file (no locking checks - a 'stat' open).
1742 ****************************************************************************/
1744 files_struct *open_file_stat(connection_struct *conn, char *fname, SMB_STRUCT_STAT *psbuf)
1746 files_struct *fsp = NULL;
1748 if (!VALID_STAT(*psbuf))
1749 return NULL;
1751 /* Can't 'stat' open directories. */
1752 if(S_ISDIR(psbuf->st_mode))
1753 return NULL;
1755 fsp = file_new(conn);
1756 if(!fsp)
1757 return NULL;
1759 DEBUG(5,("open_file_stat: 'opening' file %s\n", fname));
1762 * Setup the files_struct for it.
1765 fsp->mode = psbuf->st_mode;
1766 fsp->inode = psbuf->st_ino;
1767 fsp->dev = psbuf->st_dev;
1768 fsp->size = psbuf->st_size;
1769 fsp->vuid = current_user.vuid;
1770 fsp->file_pid = global_smbpid;
1771 fsp->can_lock = False;
1772 fsp->can_read = False;
1773 fsp->can_write = False;
1774 fsp->share_mode = 0;
1775 fsp->desired_access = 0;
1776 fsp->print_file = False;
1777 fsp->modified = False;
1778 fsp->oplock_type = NO_OPLOCK;
1779 fsp->sent_oplock_break = NO_BREAK_SENT;
1780 fsp->is_directory = False;
1781 fsp->is_stat = True;
1782 fsp->directory_delete_on_close = False;
1783 string_set(&fsp->fsp_name,fname);
1785 conn->num_files_open++;
1787 return fsp;