[GLUE] Rsync SAMBA_3_2_0 SVN r25598 in order to create the v3-2-test branch.
[Samba/gebeck_regimport.git] / source3 / smbd / open.c
blobfbc6f9ab64103d07d3fff69c8c8443e6106fddb7
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
6 Copyright (C) Volker Lendecke 2005
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program. If not, see <http://www.gnu.org/licenses/>.
22 #include "includes.h"
24 extern const struct generic_mapping file_generic_mapping;
25 extern struct current_user current_user;
26 extern userdom_struct current_user_info;
27 extern BOOL global_client_failed_oplock_break;
29 struct deferred_open_record {
30 BOOL delayed_for_oplocks;
31 struct file_id id;
34 /****************************************************************************
35 fd support routines - attempt to do a dos_open.
36 ****************************************************************************/
38 static NTSTATUS fd_open(struct connection_struct *conn,
39 const char *fname,
40 files_struct *fsp,
41 int flags,
42 mode_t mode)
44 NTSTATUS status = NT_STATUS_OK;
46 #ifdef O_NOFOLLOW
47 /*
48 * Never follow symlinks on a POSIX client. The
49 * client should be doing this.
52 if (fsp->posix_open || !lp_symlinks(SNUM(conn))) {
53 flags |= O_NOFOLLOW;
55 #endif
57 fsp->fh->fd = SMB_VFS_OPEN(conn,fname,fsp,flags,mode);
58 if (fsp->fh->fd == -1) {
59 status = map_nt_error_from_unix(errno);
62 DEBUG(10,("fd_open: name %s, flags = 0%o mode = 0%o, fd = %d. %s\n",
63 fname, flags, (int)mode, fsp->fh->fd,
64 (fsp->fh->fd == -1) ? strerror(errno) : "" ));
66 return status;
69 /****************************************************************************
70 Close the file associated with a fsp.
71 ****************************************************************************/
73 NTSTATUS fd_close(struct connection_struct *conn, files_struct *fsp)
75 if (fsp->fh->fd == -1) {
76 return NT_STATUS_OK; /* What we used to call a stat open. */
78 if (fsp->fh->ref_count > 1) {
79 return NT_STATUS_OK; /* Shared handle. Only close last reference. */
81 return fd_close_posix(conn, fsp);
84 /****************************************************************************
85 Change the ownership of a file to that of the parent directory.
86 Do this by fd if possible.
87 ****************************************************************************/
89 static void change_file_owner_to_parent(connection_struct *conn,
90 const char *inherit_from_dir,
91 files_struct *fsp)
93 SMB_STRUCT_STAT parent_st;
94 int ret;
96 ret = SMB_VFS_STAT(conn, inherit_from_dir, &parent_st);
97 if (ret == -1) {
98 DEBUG(0,("change_file_owner_to_parent: failed to stat parent "
99 "directory %s. Error was %s\n",
100 inherit_from_dir, strerror(errno) ));
101 return;
104 become_root();
105 ret = SMB_VFS_FCHOWN(fsp, fsp->fh->fd, parent_st.st_uid, (gid_t)-1);
106 unbecome_root();
107 if (ret == -1) {
108 DEBUG(0,("change_file_owner_to_parent: failed to fchown "
109 "file %s to parent directory uid %u. Error "
110 "was %s\n", fsp->fsp_name,
111 (unsigned int)parent_st.st_uid,
112 strerror(errno) ));
115 DEBUG(10,("change_file_owner_to_parent: changed new file %s to "
116 "parent directory uid %u.\n", fsp->fsp_name,
117 (unsigned int)parent_st.st_uid ));
120 static NTSTATUS change_dir_owner_to_parent(connection_struct *conn,
121 const char *inherit_from_dir,
122 const char *fname,
123 SMB_STRUCT_STAT *psbuf)
125 char *saved_dir = NULL;
126 SMB_STRUCT_STAT sbuf;
127 SMB_STRUCT_STAT parent_st;
128 TALLOC_CTX *ctx = talloc_stackframe();
129 NTSTATUS status = NT_STATUS_OK;
130 int ret;
132 ret = SMB_VFS_STAT(conn, inherit_from_dir, &parent_st);
133 if (ret == -1) {
134 status = map_nt_error_from_unix(errno);
135 DEBUG(0,("change_dir_owner_to_parent: failed to stat parent "
136 "directory %s. Error was %s\n",
137 inherit_from_dir, strerror(errno) ));
138 TALLOC_FREE(ctx);
139 return status;
142 /* We've already done an lstat into psbuf, and we know it's a
143 directory. If we can cd into the directory and the dev/ino
144 are the same then we can safely chown without races as
145 we're locking the directory in place by being in it. This
146 should work on any UNIX (thanks tridge :-). JRA.
149 saved_dir = vfs_GetWd(ctx,conn);
150 if (!saved_dir) {
151 status = map_nt_error_from_unix(errno);
152 DEBUG(0,("change_dir_owner_to_parent: failed to get "
153 "current working directory. Error was %s\n",
154 strerror(errno)));
155 TALLOC_FREE(ctx);
156 return status;
159 /* Chdir into the new path. */
160 if (vfs_ChDir(conn, fname) == -1) {
161 status = map_nt_error_from_unix(errno);
162 DEBUG(0,("change_dir_owner_to_parent: failed to change "
163 "current working directory to %s. Error "
164 "was %s\n", fname, strerror(errno) ));
165 goto out;
168 if (SMB_VFS_STAT(conn,".",&sbuf) == -1) {
169 status = map_nt_error_from_unix(errno);
170 DEBUG(0,("change_dir_owner_to_parent: failed to stat "
171 "directory '.' (%s) Error was %s\n",
172 fname, strerror(errno)));
173 goto out;
176 /* Ensure we're pointing at the same place. */
177 if (sbuf.st_dev != psbuf->st_dev ||
178 sbuf.st_ino != psbuf->st_ino ||
179 sbuf.st_mode != psbuf->st_mode ) {
180 DEBUG(0,("change_dir_owner_to_parent: "
181 "device/inode/mode on directory %s changed. "
182 "Refusing to chown !\n", fname ));
183 status = NT_STATUS_ACCESS_DENIED;
184 goto out;
187 become_root();
188 ret = SMB_VFS_CHOWN(conn, ".", parent_st.st_uid, (gid_t)-1);
189 unbecome_root();
190 if (ret == -1) {
191 status = map_nt_error_from_unix(errno);
192 DEBUG(10,("change_dir_owner_to_parent: failed to chown "
193 "directory %s to parent directory uid %u. "
194 "Error was %s\n", fname,
195 (unsigned int)parent_st.st_uid, strerror(errno) ));
196 goto out;
199 DEBUG(10,("change_dir_owner_to_parent: changed ownership of new "
200 "directory %s to parent directory uid %u.\n",
201 fname, (unsigned int)parent_st.st_uid ));
203 out:
205 TALLOC_FREE(ctx);
206 vfs_ChDir(conn,saved_dir);
207 return status;
210 /****************************************************************************
211 Open a file.
212 ****************************************************************************/
214 static NTSTATUS open_file(files_struct *fsp,
215 connection_struct *conn,
216 struct smb_request *req,
217 const char *parent_dir,
218 const char *name,
219 const char *path,
220 SMB_STRUCT_STAT *psbuf,
221 int flags,
222 mode_t unx_mode,
223 uint32 access_mask, /* client requested access mask. */
224 uint32 open_access_mask) /* what we're actually using in the open. */
226 NTSTATUS status = NT_STATUS_OK;
227 int accmode = (flags & O_ACCMODE);
228 int local_flags = flags;
229 BOOL file_existed = VALID_STAT(*psbuf);
231 fsp->fh->fd = -1;
232 errno = EPERM;
234 /* Check permissions */
237 * This code was changed after seeing a client open request
238 * containing the open mode of (DENY_WRITE/read-only) with
239 * the 'create if not exist' bit set. The previous code
240 * would fail to open the file read only on a read-only share
241 * as it was checking the flags parameter directly against O_RDONLY,
242 * this was failing as the flags parameter was set to O_RDONLY|O_CREAT.
243 * JRA.
246 if (!CAN_WRITE(conn)) {
247 /* It's a read-only share - fail if we wanted to write. */
248 if(accmode != O_RDONLY) {
249 DEBUG(3,("Permission denied opening %s\n", path));
250 return NT_STATUS_ACCESS_DENIED;
251 } else if(flags & O_CREAT) {
252 /* We don't want to write - but we must make sure that
253 O_CREAT doesn't create the file if we have write
254 access into the directory.
256 flags &= ~O_CREAT;
257 local_flags &= ~O_CREAT;
262 * This little piece of insanity is inspired by the
263 * fact that an NT client can open a file for O_RDONLY,
264 * but set the create disposition to FILE_EXISTS_TRUNCATE.
265 * If the client *can* write to the file, then it expects to
266 * truncate the file, even though it is opening for readonly.
267 * Quicken uses this stupid trick in backup file creation...
268 * Thanks *greatly* to "David W. Chapman Jr." <dwcjr@inethouston.net>
269 * for helping track this one down. It didn't bite us in 2.0.x
270 * as we always opened files read-write in that release. JRA.
273 if ((accmode == O_RDONLY) && ((flags & O_TRUNC) == O_TRUNC)) {
274 DEBUG(10,("open_file: truncate requested on read-only open "
275 "for file %s\n", path));
276 local_flags = (flags & ~O_ACCMODE)|O_RDWR;
279 if ((open_access_mask & (FILE_READ_DATA|FILE_WRITE_DATA|FILE_APPEND_DATA|FILE_EXECUTE)) ||
280 (!file_existed && (local_flags & O_CREAT)) ||
281 ((local_flags & O_TRUNC) == O_TRUNC) ) {
284 * We can't actually truncate here as the file may be locked.
285 * open_file_ntcreate will take care of the truncate later. JRA.
288 local_flags &= ~O_TRUNC;
290 #if defined(O_NONBLOCK) && defined(S_ISFIFO)
292 * We would block on opening a FIFO with no one else on the
293 * other end. Do what we used to do and add O_NONBLOCK to the
294 * open flags. JRA.
297 if (file_existed && S_ISFIFO(psbuf->st_mode)) {
298 local_flags |= O_NONBLOCK;
300 #endif
302 /* Don't create files with Microsoft wildcard characters. */
303 if ((local_flags & O_CREAT) && !file_existed &&
304 ms_has_wild(path)) {
305 return NT_STATUS_OBJECT_NAME_INVALID;
308 /* Actually do the open */
309 status = fd_open(conn, path, fsp, local_flags, unx_mode);
310 if (!NT_STATUS_IS_OK(status)) {
311 DEBUG(3,("Error opening file %s (%s) (local_flags=%d) "
312 "(flags=%d)\n",
313 path,nt_errstr(status),local_flags,flags));
314 return status;
317 if ((local_flags & O_CREAT) && !file_existed) {
319 /* Inherit the ACL if required */
320 if (lp_inherit_perms(SNUM(conn))) {
321 inherit_access_acl(conn, parent_dir, path,
322 unx_mode);
325 /* Change the owner if required. */
326 if (lp_inherit_owner(SNUM(conn))) {
327 change_file_owner_to_parent(conn, parent_dir,
328 fsp);
331 notify_fname(conn, NOTIFY_ACTION_ADDED,
332 FILE_NOTIFY_CHANGE_FILE_NAME, path);
335 } else {
336 fsp->fh->fd = -1; /* What we used to call a stat open. */
339 if (!file_existed) {
340 int ret;
342 if (fsp->fh->fd == -1) {
343 ret = SMB_VFS_STAT(conn, path, psbuf);
344 } else {
345 ret = SMB_VFS_FSTAT(fsp,fsp->fh->fd,psbuf);
346 /* If we have an fd, this stat should succeed. */
347 if (ret == -1) {
348 DEBUG(0,("Error doing fstat on open file %s "
349 "(%s)\n", path,strerror(errno) ));
353 /* For a non-io open, this stat failing means file not found. JRA */
354 if (ret == -1) {
355 status = map_nt_error_from_unix(errno);
356 fd_close(conn, fsp);
357 return status;
362 * POSIX allows read-only opens of directories. We don't
363 * want to do this (we use a different code path for this)
364 * so catch a directory open and return an EISDIR. JRA.
367 if(S_ISDIR(psbuf->st_mode)) {
368 fd_close(conn, fsp);
369 errno = EISDIR;
370 return NT_STATUS_FILE_IS_A_DIRECTORY;
373 fsp->mode = psbuf->st_mode;
374 fsp->file_id = vfs_file_id_from_sbuf(conn, psbuf);
375 fsp->vuid = req ? req->vuid : UID_FIELD_INVALID;
376 fsp->file_pid = req ? req->smbpid : 0;
377 fsp->can_lock = True;
378 fsp->can_read = (access_mask & (FILE_READ_DATA)) ? True : False;
379 if (!CAN_WRITE(conn)) {
380 fsp->can_write = False;
381 } else {
382 fsp->can_write = (access_mask & (FILE_WRITE_DATA | FILE_APPEND_DATA)) ?
383 True : False;
385 fsp->print_file = False;
386 fsp->modified = False;
387 fsp->sent_oplock_break = NO_BREAK_SENT;
388 fsp->is_directory = False;
389 fsp->is_stat = False;
390 if (conn->aio_write_behind_list &&
391 is_in_path(path, conn->aio_write_behind_list, conn->case_sensitive)) {
392 fsp->aio_write_behind = True;
395 string_set(&fsp->fsp_name, path);
396 fsp->wcp = NULL; /* Write cache pointer. */
398 DEBUG(2,("%s opened file %s read=%s write=%s (numopen=%d)\n",
399 *current_user_info.smb_name ?
400 current_user_info.smb_name : conn->user,fsp->fsp_name,
401 BOOLSTR(fsp->can_read), BOOLSTR(fsp->can_write),
402 conn->num_files_open + 1));
404 errno = 0;
405 return NT_STATUS_OK;
408 /*******************************************************************
409 Return True if the filename is one of the special executable types.
410 ********************************************************************/
412 static BOOL is_executable(const char *fname)
414 if ((fname = strrchr_m(fname,'.'))) {
415 if (strequal(fname,".com") ||
416 strequal(fname,".dll") ||
417 strequal(fname,".exe") ||
418 strequal(fname,".sym")) {
419 return True;
422 return False;
425 /****************************************************************************
426 Check if we can open a file with a share mode.
427 Returns True if conflict, False if not.
428 ****************************************************************************/
430 static BOOL share_conflict(struct share_mode_entry *entry,
431 uint32 access_mask,
432 uint32 share_access)
434 DEBUG(10,("share_conflict: entry->access_mask = 0x%x, "
435 "entry->share_access = 0x%x, "
436 "entry->private_options = 0x%x\n",
437 (unsigned int)entry->access_mask,
438 (unsigned int)entry->share_access,
439 (unsigned int)entry->private_options));
441 DEBUG(10,("share_conflict: access_mask = 0x%x, share_access = 0x%x\n",
442 (unsigned int)access_mask, (unsigned int)share_access));
444 if ((entry->access_mask & (FILE_WRITE_DATA|
445 FILE_APPEND_DATA|
446 FILE_READ_DATA|
447 FILE_EXECUTE|
448 DELETE_ACCESS)) == 0) {
449 DEBUG(10,("share_conflict: No conflict due to "
450 "entry->access_mask = 0x%x\n",
451 (unsigned int)entry->access_mask ));
452 return False;
455 if ((access_mask & (FILE_WRITE_DATA|
456 FILE_APPEND_DATA|
457 FILE_READ_DATA|
458 FILE_EXECUTE|
459 DELETE_ACCESS)) == 0) {
460 DEBUG(10,("share_conflict: No conflict due to "
461 "access_mask = 0x%x\n",
462 (unsigned int)access_mask ));
463 return False;
466 #if 1 /* JRA TEST - Superdebug. */
467 #define CHECK_MASK(num, am, right, sa, share) \
468 DEBUG(10,("share_conflict: [%d] am (0x%x) & right (0x%x) = 0x%x\n", \
469 (unsigned int)(num), (unsigned int)(am), \
470 (unsigned int)(right), (unsigned int)(am)&(right) )); \
471 DEBUG(10,("share_conflict: [%d] sa (0x%x) & share (0x%x) = 0x%x\n", \
472 (unsigned int)(num), (unsigned int)(sa), \
473 (unsigned int)(share), (unsigned int)(sa)&(share) )); \
474 if (((am) & (right)) && !((sa) & (share))) { \
475 DEBUG(10,("share_conflict: check %d conflict am = 0x%x, right = 0x%x, \
476 sa = 0x%x, share = 0x%x\n", (num), (unsigned int)(am), (unsigned int)(right), (unsigned int)(sa), \
477 (unsigned int)(share) )); \
478 return True; \
480 #else
481 #define CHECK_MASK(num, am, right, sa, share) \
482 if (((am) & (right)) && !((sa) & (share))) { \
483 DEBUG(10,("share_conflict: check %d conflict am = 0x%x, right = 0x%x, \
484 sa = 0x%x, share = 0x%x\n", (num), (unsigned int)(am), (unsigned int)(right), (unsigned int)(sa), \
485 (unsigned int)(share) )); \
486 return True; \
488 #endif
490 CHECK_MASK(1, entry->access_mask, FILE_WRITE_DATA | FILE_APPEND_DATA,
491 share_access, FILE_SHARE_WRITE);
492 CHECK_MASK(2, access_mask, FILE_WRITE_DATA | FILE_APPEND_DATA,
493 entry->share_access, FILE_SHARE_WRITE);
495 CHECK_MASK(3, entry->access_mask, FILE_READ_DATA | FILE_EXECUTE,
496 share_access, FILE_SHARE_READ);
497 CHECK_MASK(4, access_mask, FILE_READ_DATA | FILE_EXECUTE,
498 entry->share_access, FILE_SHARE_READ);
500 CHECK_MASK(5, entry->access_mask, DELETE_ACCESS,
501 share_access, FILE_SHARE_DELETE);
502 CHECK_MASK(6, access_mask, DELETE_ACCESS,
503 entry->share_access, FILE_SHARE_DELETE);
505 DEBUG(10,("share_conflict: No conflict.\n"));
506 return False;
509 #if defined(DEVELOPER)
510 static void validate_my_share_entries(int num,
511 struct share_mode_entry *share_entry)
513 files_struct *fsp;
515 if (!procid_is_me(&share_entry->pid)) {
516 return;
519 if (is_deferred_open_entry(share_entry) &&
520 !open_was_deferred(share_entry->op_mid)) {
521 char *str = talloc_asprintf(talloc_tos(),
522 "Got a deferred entry without a request: "
523 "PANIC: %s\n",
524 share_mode_str(num, share_entry));
525 smb_panic(str);
528 if (!is_valid_share_mode_entry(share_entry)) {
529 return;
532 fsp = file_find_dif(share_entry->id,
533 share_entry->share_file_id);
534 if (!fsp) {
535 DEBUG(0,("validate_my_share_entries: PANIC : %s\n",
536 share_mode_str(num, share_entry) ));
537 smb_panic("validate_my_share_entries: Cannot match a "
538 "share entry with an open file\n");
541 if (is_deferred_open_entry(share_entry) ||
542 is_unused_share_mode_entry(share_entry)) {
543 goto panic;
546 if ((share_entry->op_type == NO_OPLOCK) &&
547 (fsp->oplock_type == FAKE_LEVEL_II_OPLOCK)) {
548 /* Someone has already written to it, but I haven't yet
549 * noticed */
550 return;
553 if (((uint16)fsp->oplock_type) != share_entry->op_type) {
554 goto panic;
557 return;
559 panic:
561 char *str;
562 DEBUG(0,("validate_my_share_entries: PANIC : %s\n",
563 share_mode_str(num, share_entry) ));
564 str = talloc_asprintf(talloc_tos(),
565 "validate_my_share_entries: "
566 "file %s, oplock_type = 0x%x, op_type = 0x%x\n",
567 fsp->fsp_name, (unsigned int)fsp->oplock_type,
568 (unsigned int)share_entry->op_type );
569 smb_panic(str);
572 #endif
574 static BOOL is_stat_open(uint32 access_mask)
576 return (access_mask &&
577 ((access_mask & ~(SYNCHRONIZE_ACCESS| FILE_READ_ATTRIBUTES|
578 FILE_WRITE_ATTRIBUTES))==0) &&
579 ((access_mask & (SYNCHRONIZE_ACCESS|FILE_READ_ATTRIBUTES|
580 FILE_WRITE_ATTRIBUTES)) != 0));
583 /****************************************************************************
584 Deal with share modes
585 Invarient: Share mode must be locked on entry and exit.
586 Returns -1 on error, or number of share modes on success (may be zero).
587 ****************************************************************************/
589 static NTSTATUS open_mode_check(connection_struct *conn,
590 const char *fname,
591 struct share_mode_lock *lck,
592 uint32 access_mask,
593 uint32 share_access,
594 uint32 create_options,
595 BOOL *file_existed)
597 int i;
599 if(lck->num_share_modes == 0) {
600 return NT_STATUS_OK;
603 *file_existed = True;
605 if (is_stat_open(access_mask)) {
606 /* Stat open that doesn't trigger oplock breaks or share mode
607 * checks... ! JRA. */
608 return NT_STATUS_OK;
611 /* A delete on close prohibits everything */
613 if (lck->delete_on_close) {
614 return NT_STATUS_DELETE_PENDING;
618 * Check if the share modes will give us access.
621 #if defined(DEVELOPER)
622 for(i = 0; i < lck->num_share_modes; i++) {
623 validate_my_share_entries(i, &lck->share_modes[i]);
625 #endif
627 if (!lp_share_modes(SNUM(conn))) {
628 return NT_STATUS_OK;
631 /* Now we check the share modes, after any oplock breaks. */
632 for(i = 0; i < lck->num_share_modes; i++) {
634 if (!is_valid_share_mode_entry(&lck->share_modes[i])) {
635 continue;
638 /* someone else has a share lock on it, check to see if we can
639 * too */
640 if (share_conflict(&lck->share_modes[i],
641 access_mask, share_access)) {
642 return NT_STATUS_SHARING_VIOLATION;
646 return NT_STATUS_OK;
649 static BOOL is_delete_request(files_struct *fsp) {
650 return ((fsp->access_mask == DELETE_ACCESS) &&
651 (fsp->oplock_type == NO_OPLOCK));
655 * 1) No files open at all or internal open: Grant whatever the client wants.
657 * 2) Exclusive (or batch) oplock around: If the requested access is a delete
658 * request, break if the oplock around is a batch oplock. If it's another
659 * requested access type, break.
661 * 3) Only level2 around: Grant level2 and do nothing else.
664 static BOOL delay_for_oplocks(struct share_mode_lock *lck,
665 files_struct *fsp,
666 uint16 mid,
667 int pass_number,
668 int oplock_request)
670 int i;
671 struct share_mode_entry *exclusive = NULL;
672 BOOL valid_entry = False;
673 BOOL delay_it = False;
674 BOOL have_level2 = False;
675 NTSTATUS status;
676 char msg[MSG_SMB_SHARE_MODE_ENTRY_SIZE];
678 if (oplock_request & INTERNAL_OPEN_ONLY) {
679 fsp->oplock_type = NO_OPLOCK;
682 if ((oplock_request & INTERNAL_OPEN_ONLY) || is_stat_open(fsp->access_mask)) {
683 return False;
686 for (i=0; i<lck->num_share_modes; i++) {
688 if (!is_valid_share_mode_entry(&lck->share_modes[i])) {
689 continue;
692 /* At least one entry is not an invalid or deferred entry. */
693 valid_entry = True;
695 if (pass_number == 1) {
696 if (BATCH_OPLOCK_TYPE(lck->share_modes[i].op_type)) {
697 SMB_ASSERT(exclusive == NULL);
698 exclusive = &lck->share_modes[i];
700 } else {
701 if (EXCLUSIVE_OPLOCK_TYPE(lck->share_modes[i].op_type)) {
702 SMB_ASSERT(exclusive == NULL);
703 exclusive = &lck->share_modes[i];
707 if (lck->share_modes[i].op_type == LEVEL_II_OPLOCK) {
708 SMB_ASSERT(exclusive == NULL);
709 have_level2 = True;
713 if (!valid_entry) {
714 /* All entries are placeholders or deferred.
715 * Directly grant whatever the client wants. */
716 if (fsp->oplock_type == NO_OPLOCK) {
717 /* Store a level2 oplock, but don't tell the client */
718 fsp->oplock_type = FAKE_LEVEL_II_OPLOCK;
720 return False;
723 if (exclusive != NULL) { /* Found an exclusive oplock */
724 SMB_ASSERT(!have_level2);
725 delay_it = is_delete_request(fsp) ?
726 BATCH_OPLOCK_TYPE(exclusive->op_type) : True;
729 if (EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type)) {
730 /* We can at most grant level2 as there are other
731 * level2 or NO_OPLOCK entries. */
732 fsp->oplock_type = LEVEL_II_OPLOCK;
735 if ((fsp->oplock_type == NO_OPLOCK) && have_level2) {
736 /* Store a level2 oplock, but don't tell the client */
737 fsp->oplock_type = FAKE_LEVEL_II_OPLOCK;
740 if (!delay_it) {
741 return False;
745 * Send a break message to the oplock holder and delay the open for
746 * our client.
749 DEBUG(10, ("Sending break request to PID %s\n",
750 procid_str_static(&exclusive->pid)));
751 exclusive->op_mid = mid;
753 /* Create the message. */
754 share_mode_entry_to_message(msg, exclusive);
756 /* Add in the FORCE_OPLOCK_BREAK_TO_NONE bit in the message if set. We
757 don't want this set in the share mode struct pointed to by lck. */
759 if (oplock_request & FORCE_OPLOCK_BREAK_TO_NONE) {
760 SSVAL(msg,6,exclusive->op_type | FORCE_OPLOCK_BREAK_TO_NONE);
763 status = messaging_send_buf(smbd_messaging_context(), exclusive->pid,
764 MSG_SMB_BREAK_REQUEST,
765 (uint8 *)msg,
766 MSG_SMB_SHARE_MODE_ENTRY_SIZE);
767 if (!NT_STATUS_IS_OK(status)) {
768 DEBUG(3, ("Could not send oplock break message: %s\n",
769 nt_errstr(status)));
772 return True;
775 static BOOL request_timed_out(struct timeval request_time,
776 struct timeval timeout)
778 struct timeval now, end_time;
779 GetTimeOfDay(&now);
780 end_time = timeval_sum(&request_time, &timeout);
781 return (timeval_compare(&end_time, &now) < 0);
784 /****************************************************************************
785 Handle the 1 second delay in returning a SHARING_VIOLATION error.
786 ****************************************************************************/
788 static void defer_open(struct share_mode_lock *lck,
789 struct timeval request_time,
790 struct timeval timeout,
791 struct smb_request *req,
792 struct deferred_open_record *state)
794 int i;
796 /* Paranoia check */
798 for (i=0; i<lck->num_share_modes; i++) {
799 struct share_mode_entry *e = &lck->share_modes[i];
801 if (!is_deferred_open_entry(e)) {
802 continue;
805 if (procid_is_me(&e->pid) && (e->op_mid == req->mid)) {
806 DEBUG(0, ("Trying to defer an already deferred "
807 "request: mid=%d, exiting\n", req->mid));
808 exit_server("attempt to defer a deferred request");
812 /* End paranoia check */
814 DEBUG(10,("defer_open_sharing_error: time [%u.%06u] adding deferred "
815 "open entry for mid %u\n",
816 (unsigned int)request_time.tv_sec,
817 (unsigned int)request_time.tv_usec,
818 (unsigned int)req->mid));
820 if (!push_deferred_smb_message(req, request_time, timeout,
821 (char *)state, sizeof(*state))) {
822 exit_server("push_deferred_smb_message failed");
824 add_deferred_open(lck, req->mid, request_time, state->id);
827 * Push the MID of this packet on the signing queue.
828 * We only do this once, the first time we push the packet
829 * onto the deferred open queue, as this has a side effect
830 * of incrementing the response sequence number.
833 srv_defer_sign_response(req->mid);
837 /****************************************************************************
838 On overwrite open ensure that the attributes match.
839 ****************************************************************************/
841 static BOOL open_match_attributes(connection_struct *conn,
842 const char *path,
843 uint32 old_dos_attr,
844 uint32 new_dos_attr,
845 mode_t existing_unx_mode,
846 mode_t new_unx_mode,
847 mode_t *returned_unx_mode)
849 uint32 noarch_old_dos_attr, noarch_new_dos_attr;
851 noarch_old_dos_attr = (old_dos_attr & ~FILE_ATTRIBUTE_ARCHIVE);
852 noarch_new_dos_attr = (new_dos_attr & ~FILE_ATTRIBUTE_ARCHIVE);
854 if((noarch_old_dos_attr == 0 && noarch_new_dos_attr != 0) ||
855 (noarch_old_dos_attr != 0 && ((noarch_old_dos_attr & noarch_new_dos_attr) == noarch_old_dos_attr))) {
856 *returned_unx_mode = new_unx_mode;
857 } else {
858 *returned_unx_mode = (mode_t)0;
861 DEBUG(10,("open_match_attributes: file %s old_dos_attr = 0x%x, "
862 "existing_unx_mode = 0%o, new_dos_attr = 0x%x "
863 "returned_unx_mode = 0%o\n",
864 path,
865 (unsigned int)old_dos_attr,
866 (unsigned int)existing_unx_mode,
867 (unsigned int)new_dos_attr,
868 (unsigned int)*returned_unx_mode ));
870 /* If we're mapping SYSTEM and HIDDEN ensure they match. */
871 if (lp_map_system(SNUM(conn)) || lp_store_dos_attributes(SNUM(conn))) {
872 if ((old_dos_attr & FILE_ATTRIBUTE_SYSTEM) &&
873 !(new_dos_attr & FILE_ATTRIBUTE_SYSTEM)) {
874 return False;
877 if (lp_map_hidden(SNUM(conn)) || lp_store_dos_attributes(SNUM(conn))) {
878 if ((old_dos_attr & FILE_ATTRIBUTE_HIDDEN) &&
879 !(new_dos_attr & FILE_ATTRIBUTE_HIDDEN)) {
880 return False;
883 return True;
886 /****************************************************************************
887 Special FCB or DOS processing in the case of a sharing violation.
888 Try and find a duplicated file handle.
889 ****************************************************************************/
891 static files_struct *fcb_or_dos_open(connection_struct *conn,
892 const char *fname,
893 struct file_id id,
894 uint16 file_pid,
895 uint16 vuid,
896 uint32 access_mask,
897 uint32 share_access,
898 uint32 create_options)
900 files_struct *fsp;
901 files_struct *dup_fsp;
903 DEBUG(5,("fcb_or_dos_open: attempting old open semantics for "
904 "file %s.\n", fname ));
906 for(fsp = file_find_di_first(id); fsp;
907 fsp = file_find_di_next(fsp)) {
909 DEBUG(10,("fcb_or_dos_open: checking file %s, fd = %d, "
910 "vuid = %u, file_pid = %u, private_options = 0x%x "
911 "access_mask = 0x%x\n", fsp->fsp_name,
912 fsp->fh->fd, (unsigned int)fsp->vuid,
913 (unsigned int)fsp->file_pid,
914 (unsigned int)fsp->fh->private_options,
915 (unsigned int)fsp->access_mask ));
917 if (fsp->fh->fd != -1 &&
918 fsp->vuid == vuid &&
919 fsp->file_pid == file_pid &&
920 (fsp->fh->private_options & (NTCREATEX_OPTIONS_PRIVATE_DENY_DOS |
921 NTCREATEX_OPTIONS_PRIVATE_DENY_FCB)) &&
922 (fsp->access_mask & FILE_WRITE_DATA) &&
923 strequal(fsp->fsp_name, fname)) {
924 DEBUG(10,("fcb_or_dos_open: file match\n"));
925 break;
929 if (!fsp) {
930 return NULL;
933 /* quite an insane set of semantics ... */
934 if (is_executable(fname) &&
935 (fsp->fh->private_options & NTCREATEX_OPTIONS_PRIVATE_DENY_DOS)) {
936 DEBUG(10,("fcb_or_dos_open: file fail due to is_executable.\n"));
937 return NULL;
940 /* We need to duplicate this fsp. */
941 if (!NT_STATUS_IS_OK(dup_file_fsp(fsp, access_mask, share_access,
942 create_options, &dup_fsp))) {
943 return NULL;
946 return dup_fsp;
949 /****************************************************************************
950 Open a file with a share mode - old openX method - map into NTCreate.
951 ****************************************************************************/
953 BOOL map_open_params_to_ntcreate(const char *fname, int deny_mode, int open_func,
954 uint32 *paccess_mask,
955 uint32 *pshare_mode,
956 uint32 *pcreate_disposition,
957 uint32 *pcreate_options)
959 uint32 access_mask;
960 uint32 share_mode;
961 uint32 create_disposition;
962 uint32 create_options = 0;
964 DEBUG(10,("map_open_params_to_ntcreate: fname = %s, deny_mode = 0x%x, "
965 "open_func = 0x%x\n",
966 fname, (unsigned int)deny_mode, (unsigned int)open_func ));
968 /* Create the NT compatible access_mask. */
969 switch (GET_OPENX_MODE(deny_mode)) {
970 case DOS_OPEN_EXEC: /* Implies read-only - used to be FILE_READ_DATA */
971 case DOS_OPEN_RDONLY:
972 access_mask = FILE_GENERIC_READ;
973 break;
974 case DOS_OPEN_WRONLY:
975 access_mask = FILE_GENERIC_WRITE;
976 break;
977 case DOS_OPEN_RDWR:
978 case DOS_OPEN_FCB:
979 access_mask = FILE_GENERIC_READ|FILE_GENERIC_WRITE;
980 break;
981 default:
982 DEBUG(10,("map_open_params_to_ntcreate: bad open mode = 0x%x\n",
983 (unsigned int)GET_OPENX_MODE(deny_mode)));
984 return False;
987 /* Create the NT compatible create_disposition. */
988 switch (open_func) {
989 case OPENX_FILE_EXISTS_FAIL|OPENX_FILE_CREATE_IF_NOT_EXIST:
990 create_disposition = FILE_CREATE;
991 break;
993 case OPENX_FILE_EXISTS_OPEN:
994 create_disposition = FILE_OPEN;
995 break;
997 case OPENX_FILE_EXISTS_OPEN|OPENX_FILE_CREATE_IF_NOT_EXIST:
998 create_disposition = FILE_OPEN_IF;
999 break;
1001 case OPENX_FILE_EXISTS_TRUNCATE:
1002 create_disposition = FILE_OVERWRITE;
1003 break;
1005 case OPENX_FILE_EXISTS_TRUNCATE|OPENX_FILE_CREATE_IF_NOT_EXIST:
1006 create_disposition = FILE_OVERWRITE_IF;
1007 break;
1009 default:
1010 /* From samba4 - to be confirmed. */
1011 if (GET_OPENX_MODE(deny_mode) == DOS_OPEN_EXEC) {
1012 create_disposition = FILE_CREATE;
1013 break;
1015 DEBUG(10,("map_open_params_to_ntcreate: bad "
1016 "open_func 0x%x\n", (unsigned int)open_func));
1017 return False;
1020 /* Create the NT compatible share modes. */
1021 switch (GET_DENY_MODE(deny_mode)) {
1022 case DENY_ALL:
1023 share_mode = FILE_SHARE_NONE;
1024 break;
1026 case DENY_WRITE:
1027 share_mode = FILE_SHARE_READ;
1028 break;
1030 case DENY_READ:
1031 share_mode = FILE_SHARE_WRITE;
1032 break;
1034 case DENY_NONE:
1035 share_mode = FILE_SHARE_READ|FILE_SHARE_WRITE;
1036 break;
1038 case DENY_DOS:
1039 create_options |= NTCREATEX_OPTIONS_PRIVATE_DENY_DOS;
1040 if (is_executable(fname)) {
1041 share_mode = FILE_SHARE_READ|FILE_SHARE_WRITE;
1042 } else {
1043 if (GET_OPENX_MODE(deny_mode) == DOS_OPEN_RDONLY) {
1044 share_mode = FILE_SHARE_READ;
1045 } else {
1046 share_mode = FILE_SHARE_NONE;
1049 break;
1051 case DENY_FCB:
1052 create_options |= NTCREATEX_OPTIONS_PRIVATE_DENY_FCB;
1053 share_mode = FILE_SHARE_NONE;
1054 break;
1056 default:
1057 DEBUG(10,("map_open_params_to_ntcreate: bad deny_mode 0x%x\n",
1058 (unsigned int)GET_DENY_MODE(deny_mode) ));
1059 return False;
1062 DEBUG(10,("map_open_params_to_ntcreate: file %s, access_mask = 0x%x, "
1063 "share_mode = 0x%x, create_disposition = 0x%x, "
1064 "create_options = 0x%x\n",
1065 fname,
1066 (unsigned int)access_mask,
1067 (unsigned int)share_mode,
1068 (unsigned int)create_disposition,
1069 (unsigned int)create_options ));
1071 if (paccess_mask) {
1072 *paccess_mask = access_mask;
1074 if (pshare_mode) {
1075 *pshare_mode = share_mode;
1077 if (pcreate_disposition) {
1078 *pcreate_disposition = create_disposition;
1080 if (pcreate_options) {
1081 *pcreate_options = create_options;
1084 return True;
1088 static void schedule_defer_open(struct share_mode_lock *lck,
1089 struct timeval request_time,
1090 struct smb_request *req)
1092 struct deferred_open_record state;
1094 /* This is a relative time, added to the absolute
1095 request_time value to get the absolute timeout time.
1096 Note that if this is the second or greater time we enter
1097 this codepath for this particular request mid then
1098 request_time is left as the absolute time of the *first*
1099 time this request mid was processed. This is what allows
1100 the request to eventually time out. */
1102 struct timeval timeout;
1104 /* Normally the smbd we asked should respond within
1105 * OPLOCK_BREAK_TIMEOUT seconds regardless of whether
1106 * the client did, give twice the timeout as a safety
1107 * measure here in case the other smbd is stuck
1108 * somewhere else. */
1110 timeout = timeval_set(OPLOCK_BREAK_TIMEOUT*2, 0);
1112 /* Nothing actually uses state.delayed_for_oplocks
1113 but it's handy to differentiate in debug messages
1114 between a 30 second delay due to oplock break, and
1115 a 1 second delay for share mode conflicts. */
1117 state.delayed_for_oplocks = True;
1118 state.id = lck->id;
1120 if (!request_timed_out(request_time, timeout)) {
1121 defer_open(lck, request_time, timeout, req, &state);
1125 /****************************************************************************
1126 Open a file with a share mode.
1127 ****************************************************************************/
1129 NTSTATUS open_file_ntcreate(connection_struct *conn,
1130 struct smb_request *req,
1131 const char *fname,
1132 SMB_STRUCT_STAT *psbuf,
1133 uint32 access_mask, /* access bits (FILE_READ_DATA etc.) */
1134 uint32 share_access, /* share constants (FILE_SHARE_READ etc) */
1135 uint32 create_disposition, /* FILE_OPEN_IF etc. */
1136 uint32 create_options, /* options such as delete on close. */
1137 uint32 new_dos_attributes, /* attributes used for new file. */
1138 int oplock_request, /* internal Samba oplock codes. */
1139 /* Information (FILE_EXISTS etc.) */
1140 int *pinfo,
1141 files_struct **result)
1143 int flags=0;
1144 int flags2=0;
1145 BOOL file_existed = VALID_STAT(*psbuf);
1146 BOOL def_acl = False;
1147 BOOL posix_open = False;
1148 BOOL new_file_created = False;
1149 struct file_id id;
1150 NTSTATUS fsp_open = NT_STATUS_ACCESS_DENIED;
1151 files_struct *fsp = NULL;
1152 mode_t new_unx_mode = (mode_t)0;
1153 mode_t unx_mode = (mode_t)0;
1154 int info;
1155 uint32 existing_dos_attributes = 0;
1156 struct pending_message_list *pml = NULL;
1157 struct timeval request_time = timeval_zero();
1158 struct share_mode_lock *lck = NULL;
1159 uint32 open_access_mask = access_mask;
1160 NTSTATUS status;
1161 int ret_flock;
1162 char *parent_dir;
1163 const char *newname;
1165 ZERO_STRUCT(id);
1167 if (conn->printer) {
1169 * Printers are handled completely differently.
1170 * Most of the passed parameters are ignored.
1173 if (pinfo) {
1174 *pinfo = FILE_WAS_CREATED;
1177 DEBUG(10, ("open_file_ntcreate: printer open fname=%s\n", fname));
1179 return print_fsp_open(conn, fname, result);
1182 if (!parent_dirname_talloc(talloc_tos(), fname, &parent_dir,
1183 &newname)) {
1184 return NT_STATUS_NO_MEMORY;
1187 if (new_dos_attributes & FILE_FLAG_POSIX_SEMANTICS) {
1188 posix_open = True;
1189 unx_mode = (mode_t)(new_dos_attributes & ~FILE_FLAG_POSIX_SEMANTICS);
1190 new_dos_attributes = 0;
1191 } else {
1192 /* We add aARCH to this as this mode is only used if the file is
1193 * created new. */
1194 unx_mode = unix_mode(conn, new_dos_attributes | aARCH, fname,
1195 parent_dir);
1198 DEBUG(10, ("open_file_ntcreate: fname=%s, dos_attrs=0x%x "
1199 "access_mask=0x%x share_access=0x%x "
1200 "create_disposition = 0x%x create_options=0x%x "
1201 "unix mode=0%o oplock_request=%d\n",
1202 fname, new_dos_attributes, access_mask, share_access,
1203 create_disposition, create_options, unx_mode,
1204 oplock_request));
1206 if ((req == NULL) && ((oplock_request & INTERNAL_OPEN_ONLY) == 0)) {
1207 DEBUG(0, ("No smb request but not an internal only open!\n"));
1208 return NT_STATUS_INTERNAL_ERROR;
1212 * Only non-internal opens can be deferred at all
1215 if ((req != NULL)
1216 && ((pml = get_open_deferred_message(req->mid)) != NULL)) {
1217 struct deferred_open_record *state =
1218 (struct deferred_open_record *)pml->private_data.data;
1220 /* Remember the absolute time of the original
1221 request with this mid. We'll use it later to
1222 see if this has timed out. */
1224 request_time = pml->request_time;
1226 /* Remove the deferred open entry under lock. */
1227 lck = get_share_mode_lock(NULL, state->id, NULL, NULL);
1228 if (lck == NULL) {
1229 DEBUG(0, ("could not get share mode lock\n"));
1230 } else {
1231 del_deferred_open_entry(lck, req->mid);
1232 TALLOC_FREE(lck);
1235 /* Ensure we don't reprocess this message. */
1236 remove_deferred_open_smb_message(req->mid);
1239 status = check_name(conn, fname);
1240 if (!NT_STATUS_IS_OK(status)) {
1241 return status;
1244 if (!posix_open) {
1245 new_dos_attributes &= SAMBA_ATTRIBUTES_MASK;
1246 if (file_existed) {
1247 existing_dos_attributes = dos_mode(conn, fname, psbuf);
1251 /* ignore any oplock requests if oplocks are disabled */
1252 if (!lp_oplocks(SNUM(conn)) || global_client_failed_oplock_break ||
1253 IS_VETO_OPLOCK_PATH(conn, fname)) {
1254 /* Mask off everything except the private Samba bits. */
1255 oplock_request &= SAMBA_PRIVATE_OPLOCK_MASK;
1258 /* this is for OS/2 long file names - say we don't support them */
1259 if (!lp_posix_pathnames() && strstr(fname,".+,;=[].")) {
1260 /* OS/2 Workplace shell fix may be main code stream in a later
1261 * release. */
1262 DEBUG(5,("open_file_ntcreate: OS/2 long filenames are not "
1263 "supported.\n"));
1264 if (use_nt_status()) {
1265 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1267 return NT_STATUS_DOS(ERRDOS, ERRcannotopen);
1270 switch( create_disposition ) {
1272 * Currently we're using FILE_SUPERSEDE as the same as
1273 * FILE_OVERWRITE_IF but they really are
1274 * different. FILE_SUPERSEDE deletes an existing file
1275 * (requiring delete access) then recreates it.
1277 case FILE_SUPERSEDE:
1278 /* If file exists replace/overwrite. If file doesn't
1279 * exist create. */
1280 flags2 |= (O_CREAT | O_TRUNC);
1281 break;
1283 case FILE_OVERWRITE_IF:
1284 /* If file exists replace/overwrite. If file doesn't
1285 * exist create. */
1286 flags2 |= (O_CREAT | O_TRUNC);
1287 break;
1289 case FILE_OPEN:
1290 /* If file exists open. If file doesn't exist error. */
1291 if (!file_existed) {
1292 DEBUG(5,("open_file_ntcreate: FILE_OPEN "
1293 "requested for file %s and file "
1294 "doesn't exist.\n", fname ));
1295 errno = ENOENT;
1296 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1298 break;
1300 case FILE_OVERWRITE:
1301 /* If file exists overwrite. If file doesn't exist
1302 * error. */
1303 if (!file_existed) {
1304 DEBUG(5,("open_file_ntcreate: FILE_OVERWRITE "
1305 "requested for file %s and file "
1306 "doesn't exist.\n", fname ));
1307 errno = ENOENT;
1308 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1310 flags2 |= O_TRUNC;
1311 break;
1313 case FILE_CREATE:
1314 /* If file exists error. If file doesn't exist
1315 * create. */
1316 if (file_existed) {
1317 DEBUG(5,("open_file_ntcreate: FILE_CREATE "
1318 "requested for file %s and file "
1319 "already exists.\n", fname ));
1320 if (S_ISDIR(psbuf->st_mode)) {
1321 errno = EISDIR;
1322 } else {
1323 errno = EEXIST;
1325 return map_nt_error_from_unix(errno);
1327 flags2 |= (O_CREAT|O_EXCL);
1328 break;
1330 case FILE_OPEN_IF:
1331 /* If file exists open. If file doesn't exist
1332 * create. */
1333 flags2 |= O_CREAT;
1334 break;
1336 default:
1337 return NT_STATUS_INVALID_PARAMETER;
1340 /* We only care about matching attributes on file exists and
1341 * overwrite. */
1343 if (!posix_open && file_existed && ((create_disposition == FILE_OVERWRITE) ||
1344 (create_disposition == FILE_OVERWRITE_IF))) {
1345 if (!open_match_attributes(conn, fname,
1346 existing_dos_attributes,
1347 new_dos_attributes, psbuf->st_mode,
1348 unx_mode, &new_unx_mode)) {
1349 DEBUG(5,("open_file_ntcreate: attributes missmatch "
1350 "for file %s (%x %x) (0%o, 0%o)\n",
1351 fname, existing_dos_attributes,
1352 new_dos_attributes,
1353 (unsigned int)psbuf->st_mode,
1354 (unsigned int)unx_mode ));
1355 errno = EACCES;
1356 return NT_STATUS_ACCESS_DENIED;
1360 /* This is a nasty hack - must fix... JRA. */
1361 if (access_mask == MAXIMUM_ALLOWED_ACCESS) {
1362 open_access_mask = access_mask = FILE_GENERIC_ALL;
1366 * Convert GENERIC bits to specific bits.
1369 se_map_generic(&access_mask, &file_generic_mapping);
1370 open_access_mask = access_mask;
1372 if (flags2 & O_TRUNC) {
1373 open_access_mask |= FILE_WRITE_DATA; /* This will cause oplock breaks. */
1376 DEBUG(10, ("open_file_ntcreate: fname=%s, after mapping "
1377 "access_mask=0x%x\n", fname, access_mask ));
1380 * Note that we ignore the append flag as append does not
1381 * mean the same thing under DOS and Unix.
1384 if (access_mask & (FILE_WRITE_DATA | FILE_APPEND_DATA)) {
1385 /* DENY_DOS opens are always underlying read-write on the
1386 file handle, no matter what the requested access mask
1387 says. */
1388 if ((create_options & NTCREATEX_OPTIONS_PRIVATE_DENY_DOS) ||
1389 access_mask & (FILE_READ_ATTRIBUTES|FILE_READ_DATA|FILE_READ_EA|FILE_EXECUTE)) {
1390 flags = O_RDWR;
1391 } else {
1392 flags = O_WRONLY;
1394 } else {
1395 flags = O_RDONLY;
1399 * Currently we only look at FILE_WRITE_THROUGH for create options.
1402 #if defined(O_SYNC)
1403 if ((create_options & FILE_WRITE_THROUGH) && lp_strict_sync(SNUM(conn))) {
1404 flags2 |= O_SYNC;
1406 #endif /* O_SYNC */
1408 if (posix_open & (access_mask & FILE_APPEND_DATA)) {
1409 flags2 |= O_APPEND;
1412 if (!posix_open && !CAN_WRITE(conn)) {
1414 * We should really return a permission denied error if either
1415 * O_CREAT or O_TRUNC are set, but for compatibility with
1416 * older versions of Samba we just AND them out.
1418 flags2 &= ~(O_CREAT|O_TRUNC);
1422 * Ensure we can't write on a read-only share or file.
1425 if (flags != O_RDONLY && file_existed &&
1426 (!CAN_WRITE(conn) || IS_DOS_READONLY(existing_dos_attributes))) {
1427 DEBUG(5,("open_file_ntcreate: write access requested for "
1428 "file %s on read only %s\n",
1429 fname, !CAN_WRITE(conn) ? "share" : "file" ));
1430 errno = EACCES;
1431 return NT_STATUS_ACCESS_DENIED;
1434 status = file_new(conn, &fsp);
1435 if(!NT_STATUS_IS_OK(status)) {
1436 return status;
1439 fsp->file_id = vfs_file_id_from_sbuf(conn, psbuf);
1440 fsp->share_access = share_access;
1441 fsp->fh->private_options = create_options;
1442 fsp->access_mask = open_access_mask; /* We change this to the
1443 * requested access_mask after
1444 * the open is done. */
1445 fsp->posix_open = posix_open;
1447 /* Ensure no SAMBA_PRIVATE bits can be set. */
1448 fsp->oplock_type = (oplock_request & ~SAMBA_PRIVATE_OPLOCK_MASK);
1450 if (timeval_is_zero(&request_time)) {
1451 request_time = fsp->open_time;
1454 if (file_existed) {
1455 id = vfs_file_id_from_sbuf(conn, psbuf);
1457 lck = get_share_mode_lock(NULL, id,
1458 conn->connectpath,
1459 fname);
1461 if (lck == NULL) {
1462 file_free(fsp);
1463 DEBUG(0, ("Could not get share mode lock\n"));
1464 return NT_STATUS_SHARING_VIOLATION;
1467 /* First pass - send break only on batch oplocks. */
1468 if ((req != NULL)
1469 && delay_for_oplocks(lck, fsp, req->mid, 1,
1470 oplock_request)) {
1471 schedule_defer_open(lck, request_time, req);
1472 TALLOC_FREE(lck);
1473 file_free(fsp);
1474 return NT_STATUS_SHARING_VIOLATION;
1477 /* Use the client requested access mask here, not the one we
1478 * open with. */
1479 status = open_mode_check(conn, fname, lck,
1480 access_mask, share_access,
1481 create_options, &file_existed);
1483 if (NT_STATUS_IS_OK(status)) {
1484 /* We might be going to allow this open. Check oplock
1485 * status again. */
1486 /* Second pass - send break for both batch or
1487 * exclusive oplocks. */
1488 if ((req != NULL)
1489 && delay_for_oplocks(lck, fsp, req->mid, 2,
1490 oplock_request)) {
1491 schedule_defer_open(lck, request_time, req);
1492 TALLOC_FREE(lck);
1493 file_free(fsp);
1494 return NT_STATUS_SHARING_VIOLATION;
1498 if (NT_STATUS_EQUAL(status, NT_STATUS_DELETE_PENDING)) {
1499 /* DELETE_PENDING is not deferred for a second */
1500 TALLOC_FREE(lck);
1501 file_free(fsp);
1502 return status;
1505 if (!NT_STATUS_IS_OK(status)) {
1506 uint32 can_access_mask;
1507 BOOL can_access = True;
1509 SMB_ASSERT(NT_STATUS_EQUAL(status, NT_STATUS_SHARING_VIOLATION));
1511 /* Check if this can be done with the deny_dos and fcb
1512 * calls. */
1513 if (create_options &
1514 (NTCREATEX_OPTIONS_PRIVATE_DENY_DOS|
1515 NTCREATEX_OPTIONS_PRIVATE_DENY_FCB)) {
1516 files_struct *fsp_dup;
1518 if (req == NULL) {
1519 DEBUG(0, ("DOS open without an SMB "
1520 "request!\n"));
1521 TALLOC_FREE(lck);
1522 file_free(fsp);
1523 return NT_STATUS_INTERNAL_ERROR;
1526 /* Use the client requested access mask here,
1527 * not the one we open with. */
1528 fsp_dup = fcb_or_dos_open(conn, fname, id,
1529 req->smbpid,
1530 req->vuid,
1531 access_mask,
1532 share_access,
1533 create_options);
1535 if (fsp_dup) {
1536 TALLOC_FREE(lck);
1537 file_free(fsp);
1538 if (pinfo) {
1539 *pinfo = FILE_WAS_OPENED;
1541 conn->num_files_open++;
1542 *result = fsp_dup;
1543 return NT_STATUS_OK;
1548 * This next line is a subtlety we need for
1549 * MS-Access. If a file open will fail due to share
1550 * permissions and also for security (access) reasons,
1551 * we need to return the access failed error, not the
1552 * share error. We can't open the file due to kernel
1553 * oplock deadlock (it's possible we failed above on
1554 * the open_mode_check()) so use a userspace check.
1557 if (flags & O_RDWR) {
1558 can_access_mask = FILE_READ_DATA|FILE_WRITE_DATA;
1559 } else if (flags & O_WRONLY) {
1560 can_access_mask = FILE_WRITE_DATA;
1561 } else {
1562 can_access_mask = FILE_READ_DATA;
1565 if (((can_access_mask & FILE_WRITE_DATA) && !CAN_WRITE(conn)) ||
1566 !can_access_file(conn,fname,psbuf,can_access_mask)) {
1567 can_access = False;
1571 * If we're returning a share violation, ensure we
1572 * cope with the braindead 1 second delay.
1575 if (!(oplock_request & INTERNAL_OPEN_ONLY) &&
1576 lp_defer_sharing_violations()) {
1577 struct timeval timeout;
1578 struct deferred_open_record state;
1579 int timeout_usecs;
1581 /* this is a hack to speed up torture tests
1582 in 'make test' */
1583 timeout_usecs = lp_parm_int(SNUM(conn),
1584 "smbd","sharedelay",
1585 SHARING_VIOLATION_USEC_WAIT);
1587 /* This is a relative time, added to the absolute
1588 request_time value to get the absolute timeout time.
1589 Note that if this is the second or greater time we enter
1590 this codepath for this particular request mid then
1591 request_time is left as the absolute time of the *first*
1592 time this request mid was processed. This is what allows
1593 the request to eventually time out. */
1595 timeout = timeval_set(0, timeout_usecs);
1597 /* Nothing actually uses state.delayed_for_oplocks
1598 but it's handy to differentiate in debug messages
1599 between a 30 second delay due to oplock break, and
1600 a 1 second delay for share mode conflicts. */
1602 state.delayed_for_oplocks = False;
1603 state.id = id;
1605 if ((req != NULL)
1606 && !request_timed_out(request_time,
1607 timeout)) {
1608 defer_open(lck, request_time, timeout,
1609 req, &state);
1613 TALLOC_FREE(lck);
1614 if (can_access) {
1616 * We have detected a sharing violation here
1617 * so return the correct error code
1619 status = NT_STATUS_SHARING_VIOLATION;
1620 } else {
1621 status = NT_STATUS_ACCESS_DENIED;
1623 file_free(fsp);
1624 return status;
1628 * We exit this block with the share entry *locked*.....
1632 SMB_ASSERT(!file_existed || (lck != NULL));
1635 * Ensure we pay attention to default ACLs on directories if required.
1638 if ((flags2 & O_CREAT) && lp_inherit_acls(SNUM(conn)) &&
1639 (def_acl = directory_has_default_acl(conn, parent_dir))) {
1640 unx_mode = 0777;
1643 DEBUG(4,("calling open_file with flags=0x%X flags2=0x%X mode=0%o, "
1644 "access_mask = 0x%x, open_access_mask = 0x%x\n",
1645 (unsigned int)flags, (unsigned int)flags2,
1646 (unsigned int)unx_mode, (unsigned int)access_mask,
1647 (unsigned int)open_access_mask));
1650 * open_file strips any O_TRUNC flags itself.
1653 fsp_open = open_file(fsp, conn, req, parent_dir, newname, fname, psbuf,
1654 flags|flags2, unx_mode, access_mask,
1655 open_access_mask);
1657 if (!NT_STATUS_IS_OK(fsp_open)) {
1658 if (lck != NULL) {
1659 TALLOC_FREE(lck);
1661 file_free(fsp);
1662 return fsp_open;
1665 if (!file_existed) {
1668 * Deal with the race condition where two smbd's detect the
1669 * file doesn't exist and do the create at the same time. One
1670 * of them will win and set a share mode, the other (ie. this
1671 * one) should check if the requested share mode for this
1672 * create is allowed.
1676 * Now the file exists and fsp is successfully opened,
1677 * fsp->dev and fsp->inode are valid and should replace the
1678 * dev=0,inode=0 from a non existent file. Spotted by
1679 * Nadav Danieli <nadavd@exanet.com>. JRA.
1682 id = fsp->file_id;
1684 lck = get_share_mode_lock(NULL, id,
1685 conn->connectpath,
1686 fname);
1688 if (lck == NULL) {
1689 DEBUG(0, ("open_file_ntcreate: Could not get share "
1690 "mode lock for %s\n", fname));
1691 fd_close(conn, fsp);
1692 file_free(fsp);
1693 return NT_STATUS_SHARING_VIOLATION;
1696 /* First pass - send break only on batch oplocks. */
1697 if ((req != NULL)
1698 && delay_for_oplocks(lck, fsp, req->mid, 1,
1699 oplock_request)) {
1700 schedule_defer_open(lck, request_time, req);
1701 TALLOC_FREE(lck);
1702 fd_close(conn, fsp);
1703 file_free(fsp);
1704 return NT_STATUS_SHARING_VIOLATION;
1707 status = open_mode_check(conn, fname, lck,
1708 access_mask, share_access,
1709 create_options, &file_existed);
1711 if (NT_STATUS_IS_OK(status)) {
1712 /* We might be going to allow this open. Check oplock
1713 * status again. */
1714 /* Second pass - send break for both batch or
1715 * exclusive oplocks. */
1716 if ((req != NULL)
1717 && delay_for_oplocks(lck, fsp, req->mid, 2,
1718 oplock_request)) {
1719 schedule_defer_open(lck, request_time, req);
1720 TALLOC_FREE(lck);
1721 fd_close(conn, fsp);
1722 file_free(fsp);
1723 return NT_STATUS_SHARING_VIOLATION;
1727 if (!NT_STATUS_IS_OK(status)) {
1728 struct deferred_open_record state;
1730 fd_close(conn, fsp);
1731 file_free(fsp);
1733 state.delayed_for_oplocks = False;
1734 state.id = id;
1736 /* Do it all over again immediately. In the second
1737 * round we will find that the file existed and handle
1738 * the DELETE_PENDING and FCB cases correctly. No need
1739 * to duplicate the code here. Essentially this is a
1740 * "goto top of this function", but don't tell
1741 * anybody... */
1743 if (req != NULL) {
1744 defer_open(lck, request_time, timeval_zero(),
1745 req, &state);
1747 TALLOC_FREE(lck);
1748 return status;
1752 * We exit this block with the share entry *locked*.....
1757 SMB_ASSERT(lck != NULL);
1759 /* note that we ignore failure for the following. It is
1760 basically a hack for NFS, and NFS will never set one of
1761 these only read them. Nobody but Samba can ever set a deny
1762 mode and we have already checked our more authoritative
1763 locking database for permission to set this deny mode. If
1764 the kernel refuses the operations then the kernel is wrong.
1765 note that GPFS supports it as well - jmcd */
1767 ret_flock = SMB_VFS_KERNEL_FLOCK(fsp, fsp->fh->fd, share_access);
1768 if(ret_flock == -1 ){
1770 TALLOC_FREE(lck);
1771 fd_close(conn, fsp);
1772 file_free(fsp);
1774 return NT_STATUS_SHARING_VIOLATION;
1778 * At this point onwards, we can guarentee that the share entry
1779 * is locked, whether we created the file or not, and that the
1780 * deny mode is compatible with all current opens.
1784 * If requested, truncate the file.
1787 if (flags2&O_TRUNC) {
1789 * We are modifing the file after open - update the stat
1790 * struct..
1792 if ((SMB_VFS_FTRUNCATE(fsp,fsp->fh->fd,0) == -1) ||
1793 (SMB_VFS_FSTAT(fsp,fsp->fh->fd,psbuf)==-1)) {
1794 status = map_nt_error_from_unix(errno);
1795 TALLOC_FREE(lck);
1796 fd_close(conn,fsp);
1797 file_free(fsp);
1798 return status;
1802 /* Record the options we were opened with. */
1803 fsp->share_access = share_access;
1804 fsp->fh->private_options = create_options;
1805 fsp->access_mask = access_mask;
1807 if (file_existed) {
1808 /* stat opens on existing files don't get oplocks. */
1809 if (is_stat_open(open_access_mask)) {
1810 fsp->oplock_type = NO_OPLOCK;
1813 if (!(flags2 & O_TRUNC)) {
1814 info = FILE_WAS_OPENED;
1815 } else {
1816 info = FILE_WAS_OVERWRITTEN;
1818 } else {
1819 info = FILE_WAS_CREATED;
1822 if (pinfo) {
1823 *pinfo = info;
1827 * Setup the oplock info in both the shared memory and
1828 * file structs.
1831 if ((fsp->oplock_type != NO_OPLOCK) &&
1832 (fsp->oplock_type != FAKE_LEVEL_II_OPLOCK)) {
1833 if (!set_file_oplock(fsp, fsp->oplock_type)) {
1834 /* Could not get the kernel oplock */
1835 fsp->oplock_type = NO_OPLOCK;
1839 if (info == FILE_WAS_OVERWRITTEN || info == FILE_WAS_CREATED || info == FILE_WAS_SUPERSEDED) {
1840 new_file_created = True;
1843 set_share_mode(lck, fsp, current_user.ut.uid, 0, fsp->oplock_type, new_file_created);
1845 /* Handle strange delete on close create semantics. */
1846 if ((create_options & FILE_DELETE_ON_CLOSE) && can_set_initial_delete_on_close(lck)) {
1847 status = can_set_delete_on_close(fsp, True, new_dos_attributes);
1849 if (!NT_STATUS_IS_OK(status)) {
1850 /* Remember to delete the mode we just added. */
1851 del_share_mode(lck, fsp);
1852 TALLOC_FREE(lck);
1853 fd_close(conn,fsp);
1854 file_free(fsp);
1855 return status;
1857 /* Note that here we set the *inital* delete on close flag,
1858 not the regular one. The magic gets handled in close. */
1859 fsp->initial_delete_on_close = True;
1862 if (new_file_created) {
1863 /* Files should be initially set as archive */
1864 if (lp_map_archive(SNUM(conn)) ||
1865 lp_store_dos_attributes(SNUM(conn))) {
1866 if (!posix_open) {
1867 file_set_dosmode(conn, fname,
1868 new_dos_attributes | aARCH, NULL,
1869 parent_dir);
1875 * Take care of inherited ACLs on created files - if default ACL not
1876 * selected.
1879 if (!posix_open && !file_existed && !def_acl) {
1881 int saved_errno = errno; /* We might get ENOSYS in the next
1882 * call.. */
1884 if (SMB_VFS_FCHMOD_ACL(fsp, fsp->fh->fd, unx_mode) == -1 &&
1885 errno == ENOSYS) {
1886 errno = saved_errno; /* Ignore ENOSYS */
1889 } else if (new_unx_mode) {
1891 int ret = -1;
1893 /* Attributes need changing. File already existed. */
1896 int saved_errno = errno; /* We might get ENOSYS in the
1897 * next call.. */
1898 ret = SMB_VFS_FCHMOD_ACL(fsp, fsp->fh->fd,
1899 new_unx_mode);
1901 if (ret == -1 && errno == ENOSYS) {
1902 errno = saved_errno; /* Ignore ENOSYS */
1903 } else {
1904 DEBUG(5, ("open_file_ntcreate: reset "
1905 "attributes of file %s to 0%o\n",
1906 fname, (unsigned int)new_unx_mode));
1907 ret = 0; /* Don't do the fchmod below. */
1911 if ((ret == -1) &&
1912 (SMB_VFS_FCHMOD(fsp, fsp->fh->fd, new_unx_mode) == -1))
1913 DEBUG(5, ("open_file_ntcreate: failed to reset "
1914 "attributes of file %s to 0%o\n",
1915 fname, (unsigned int)new_unx_mode));
1918 /* If this is a successful open, we must remove any deferred open
1919 * records. */
1920 if (req != NULL) {
1921 del_deferred_open_entry(lck, req->mid);
1923 TALLOC_FREE(lck);
1925 conn->num_files_open++;
1927 *result = fsp;
1928 return NT_STATUS_OK;
1931 /****************************************************************************
1932 Open a file for for write to ensure that we can fchmod it.
1933 ****************************************************************************/
1935 NTSTATUS open_file_fchmod(connection_struct *conn, const char *fname,
1936 SMB_STRUCT_STAT *psbuf, files_struct **result)
1938 files_struct *fsp = NULL;
1939 NTSTATUS status;
1941 if (!VALID_STAT(*psbuf)) {
1942 return NT_STATUS_INVALID_PARAMETER;
1945 status = file_new(conn, &fsp);
1946 if(!NT_STATUS_IS_OK(status)) {
1947 return status;
1950 /* note! we must use a non-zero desired access or we don't get
1951 a real file descriptor. Oh what a twisted web we weave. */
1952 status = open_file(fsp, conn, NULL, NULL, NULL, fname, psbuf, O_WRONLY,
1953 0, FILE_WRITE_DATA, FILE_WRITE_DATA);
1956 * This is not a user visible file open.
1957 * Don't set a share mode and don't increment
1958 * the conn->num_files_open.
1961 if (!NT_STATUS_IS_OK(status)) {
1962 file_free(fsp);
1963 return status;
1966 *result = fsp;
1967 return NT_STATUS_OK;
1970 /****************************************************************************
1971 Close the fchmod file fd - ensure no locks are lost.
1972 ****************************************************************************/
1974 NTSTATUS close_file_fchmod(files_struct *fsp)
1976 NTSTATUS status = fd_close(fsp->conn, fsp);
1977 file_free(fsp);
1978 return status;
1981 static NTSTATUS mkdir_internal(connection_struct *conn,
1982 const char *name,
1983 uint32 file_attributes,
1984 SMB_STRUCT_STAT *psbuf)
1986 mode_t mode;
1987 char *parent_dir;
1988 const char *dirname;
1989 NTSTATUS status;
1990 bool posix_open = false;
1992 if(!CAN_WRITE(conn)) {
1993 DEBUG(5,("mkdir_internal: failing create on read-only share "
1994 "%s\n", lp_servicename(SNUM(conn))));
1995 return NT_STATUS_ACCESS_DENIED;
1998 status = check_name(conn, name);
1999 if (!NT_STATUS_IS_OK(status)) {
2000 return status;
2003 if (!parent_dirname_talloc(talloc_tos(), name, &parent_dir,
2004 &dirname)) {
2005 return NT_STATUS_NO_MEMORY;
2008 if (file_attributes & FILE_FLAG_POSIX_SEMANTICS) {
2009 posix_open = true;
2010 mode = (mode_t)(file_attributes & ~FILE_FLAG_POSIX_SEMANTICS);
2011 } else {
2012 mode = unix_mode(conn, aDIR, name, parent_dir);
2015 if (SMB_VFS_MKDIR(conn, name, mode) != 0) {
2016 return map_nt_error_from_unix(errno);
2019 /* Ensure we're checking for a symlink here.... */
2020 /* We don't want to get caught by a symlink racer. */
2022 if (SMB_VFS_LSTAT(conn, name, psbuf) == -1) {
2023 DEBUG(2, ("Could not stat directory '%s' just created: %s\n",
2024 name, strerror(errno)));
2025 return map_nt_error_from_unix(errno);
2028 if (!S_ISDIR(psbuf->st_mode)) {
2029 DEBUG(0, ("Directory just '%s' created is not a directory\n",
2030 name));
2031 return NT_STATUS_ACCESS_DENIED;
2034 if (lp_store_dos_attributes(SNUM(conn))) {
2035 if (!posix_open) {
2036 file_set_dosmode(conn, name,
2037 file_attributes | aDIR, NULL,
2038 parent_dir);
2042 if (lp_inherit_perms(SNUM(conn))) {
2043 inherit_access_acl(conn, parent_dir, name, mode);
2046 if (!(file_attributes & FILE_FLAG_POSIX_SEMANTICS)) {
2048 * Check if high bits should have been set,
2049 * then (if bits are missing): add them.
2050 * Consider bits automagically set by UNIX, i.e. SGID bit from parent
2051 * dir.
2053 if (mode & ~(S_IRWXU|S_IRWXG|S_IRWXO) && (mode & ~psbuf->st_mode)) {
2054 SMB_VFS_CHMOD(conn, name,
2055 psbuf->st_mode | (mode & ~psbuf->st_mode));
2059 /* Change the owner if required. */
2060 if (lp_inherit_owner(SNUM(conn))) {
2061 change_dir_owner_to_parent(conn, parent_dir, name, psbuf);
2064 notify_fname(conn, NOTIFY_ACTION_ADDED, FILE_NOTIFY_CHANGE_DIR_NAME,
2065 name);
2067 return NT_STATUS_OK;
2070 /****************************************************************************
2071 Open a directory from an NT SMB call.
2072 ****************************************************************************/
2074 NTSTATUS open_directory(connection_struct *conn,
2075 struct smb_request *req,
2076 const char *fname,
2077 SMB_STRUCT_STAT *psbuf,
2078 uint32 access_mask,
2079 uint32 share_access,
2080 uint32 create_disposition,
2081 uint32 create_options,
2082 uint32 file_attributes,
2083 int *pinfo,
2084 files_struct **result)
2086 files_struct *fsp = NULL;
2087 BOOL dir_existed = VALID_STAT(*psbuf) ? True : False;
2088 struct share_mode_lock *lck = NULL;
2089 NTSTATUS status;
2090 int info = 0;
2092 DEBUG(5,("open_directory: opening directory %s, access_mask = 0x%x, "
2093 "share_access = 0x%x create_options = 0x%x, "
2094 "create_disposition = 0x%x, file_attributes = 0x%x\n",
2095 fname,
2096 (unsigned int)access_mask,
2097 (unsigned int)share_access,
2098 (unsigned int)create_options,
2099 (unsigned int)create_disposition,
2100 (unsigned int)file_attributes));
2102 if (is_ntfs_stream_name(fname)) {
2103 DEBUG(0,("open_directory: %s is a stream name!\n", fname ));
2104 return NT_STATUS_NOT_A_DIRECTORY;
2107 switch( create_disposition ) {
2108 case FILE_OPEN:
2110 info = FILE_WAS_OPENED;
2113 * We want to follow symlinks here.
2116 if (SMB_VFS_STAT(conn, fname, psbuf) != 0) {
2117 return map_nt_error_from_unix(errno);
2120 break;
2122 case FILE_CREATE:
2124 /* If directory exists error. If directory doesn't
2125 * exist create. */
2127 status = mkdir_internal(conn,
2128 fname,
2129 file_attributes,
2130 psbuf);
2132 if (!NT_STATUS_IS_OK(status)) {
2133 DEBUG(2, ("open_directory: unable to create "
2134 "%s. Error was %s\n", fname,
2135 nt_errstr(status)));
2136 return status;
2139 info = FILE_WAS_CREATED;
2140 break;
2142 case FILE_OPEN_IF:
2144 * If directory exists open. If directory doesn't
2145 * exist create.
2148 status = mkdir_internal(conn,
2149 fname,
2150 file_attributes,
2151 psbuf);
2153 if (NT_STATUS_IS_OK(status)) {
2154 info = FILE_WAS_CREATED;
2157 if (NT_STATUS_EQUAL(status,
2158 NT_STATUS_OBJECT_NAME_COLLISION)) {
2159 info = FILE_WAS_OPENED;
2160 status = NT_STATUS_OK;
2163 break;
2165 case FILE_SUPERSEDE:
2166 case FILE_OVERWRITE:
2167 case FILE_OVERWRITE_IF:
2168 default:
2169 DEBUG(5,("open_directory: invalid create_disposition "
2170 "0x%x for directory %s\n",
2171 (unsigned int)create_disposition, fname));
2172 return NT_STATUS_INVALID_PARAMETER;
2175 if(!S_ISDIR(psbuf->st_mode)) {
2176 DEBUG(5,("open_directory: %s is not a directory !\n",
2177 fname ));
2178 return NT_STATUS_NOT_A_DIRECTORY;
2181 status = file_new(conn, &fsp);
2182 if(!NT_STATUS_IS_OK(status)) {
2183 return status;
2187 * Setup the files_struct for it.
2190 fsp->mode = psbuf->st_mode;
2191 fsp->file_id = vfs_file_id_from_sbuf(conn, psbuf);
2192 fsp->vuid = req ? req->vuid : UID_FIELD_INVALID;
2193 fsp->file_pid = req ? req->smbpid : 0;
2194 fsp->can_lock = False;
2195 fsp->can_read = False;
2196 fsp->can_write = False;
2198 fsp->share_access = share_access;
2199 fsp->fh->private_options = create_options;
2200 fsp->access_mask = access_mask;
2202 fsp->print_file = False;
2203 fsp->modified = False;
2204 fsp->oplock_type = NO_OPLOCK;
2205 fsp->sent_oplock_break = NO_BREAK_SENT;
2206 fsp->is_directory = True;
2207 fsp->is_stat = False;
2208 fsp->posix_open = (file_attributes & FILE_FLAG_POSIX_SEMANTICS) ? True : False;
2210 string_set(&fsp->fsp_name,fname);
2212 lck = get_share_mode_lock(NULL, fsp->file_id,
2213 conn->connectpath,
2214 fname);
2216 if (lck == NULL) {
2217 DEBUG(0, ("open_directory: Could not get share mode lock for %s\n", fname));
2218 file_free(fsp);
2219 return NT_STATUS_SHARING_VIOLATION;
2222 status = open_mode_check(conn, fname, lck,
2223 access_mask, share_access,
2224 create_options, &dir_existed);
2226 if (!NT_STATUS_IS_OK(status)) {
2227 TALLOC_FREE(lck);
2228 file_free(fsp);
2229 return status;
2232 set_share_mode(lck, fsp, current_user.ut.uid, 0, NO_OPLOCK, True);
2234 /* For directories the delete on close bit at open time seems
2235 always to be honored on close... See test 19 in Samba4 BASE-DELETE. */
2236 if (create_options & FILE_DELETE_ON_CLOSE) {
2237 status = can_set_delete_on_close(fsp, True, 0);
2238 if (!NT_STATUS_IS_OK(status) && !NT_STATUS_EQUAL(status, NT_STATUS_DIRECTORY_NOT_EMPTY)) {
2239 TALLOC_FREE(lck);
2240 file_free(fsp);
2241 return status;
2244 if (NT_STATUS_IS_OK(status)) {
2245 /* Note that here we set the *inital* delete on close flag,
2246 not the regular one. The magic gets handled in close. */
2247 fsp->initial_delete_on_close = True;
2251 TALLOC_FREE(lck);
2253 if (pinfo) {
2254 *pinfo = info;
2257 conn->num_files_open++;
2259 *result = fsp;
2260 return NT_STATUS_OK;
2263 NTSTATUS create_directory(connection_struct *conn, const char *directory)
2265 NTSTATUS status;
2266 SMB_STRUCT_STAT sbuf;
2267 files_struct *fsp;
2269 SET_STAT_INVALID(sbuf);
2271 status = open_directory(conn, NULL, directory, &sbuf,
2272 FILE_READ_ATTRIBUTES, /* Just a stat open */
2273 FILE_SHARE_NONE, /* Ignored for stat opens */
2274 FILE_CREATE,
2276 FILE_ATTRIBUTE_DIRECTORY,
2277 NULL,
2278 &fsp);
2280 if (NT_STATUS_IS_OK(status)) {
2281 close_file(fsp, NORMAL_CLOSE);
2284 return status;
2287 /****************************************************************************
2288 Open a pseudo-file (no locking checks - a 'stat' open).
2289 ****************************************************************************/
2291 NTSTATUS open_file_stat(connection_struct *conn, struct smb_request *req,
2292 const char *fname, SMB_STRUCT_STAT *psbuf,
2293 files_struct **result)
2295 files_struct *fsp = NULL;
2296 NTSTATUS status;
2298 if (!VALID_STAT(*psbuf)) {
2299 return NT_STATUS_INVALID_PARAMETER;
2302 /* Can't 'stat' open directories. */
2303 if(S_ISDIR(psbuf->st_mode)) {
2304 return NT_STATUS_FILE_IS_A_DIRECTORY;
2307 status = file_new(conn, &fsp);
2308 if(!NT_STATUS_IS_OK(status)) {
2309 return status;
2312 DEBUG(5,("open_file_stat: 'opening' file %s\n", fname));
2315 * Setup the files_struct for it.
2318 fsp->mode = psbuf->st_mode;
2319 fsp->file_id = vfs_file_id_from_sbuf(conn, psbuf);
2320 fsp->vuid = req ? req->vuid : UID_FIELD_INVALID;
2321 fsp->file_pid = req ? req->smbpid : 0;
2322 fsp->can_lock = False;
2323 fsp->can_read = False;
2324 fsp->can_write = False;
2325 fsp->print_file = False;
2326 fsp->modified = False;
2327 fsp->oplock_type = NO_OPLOCK;
2328 fsp->sent_oplock_break = NO_BREAK_SENT;
2329 fsp->is_directory = False;
2330 fsp->is_stat = True;
2331 string_set(&fsp->fsp_name,fname);
2333 conn->num_files_open++;
2335 *result = fsp;
2336 return NT_STATUS_OK;
2339 /****************************************************************************
2340 Receive notification that one of our open files has been renamed by another
2341 smbd process.
2342 ****************************************************************************/
2344 void msg_file_was_renamed(struct messaging_context *msg,
2345 void *private_data,
2346 uint32_t msg_type,
2347 struct server_id server_id,
2348 DATA_BLOB *data)
2350 files_struct *fsp;
2351 char *frm = (char *)data->data;
2352 struct file_id id;
2353 const char *sharepath;
2354 const char *newname;
2355 size_t sp_len;
2357 if (data->data == NULL
2358 || data->length < MSG_FILE_RENAMED_MIN_SIZE + 2) {
2359 DEBUG(0, ("msg_file_was_renamed: Got invalid msg len %d\n",
2360 (int)data->length));
2361 return;
2364 /* Unpack the message. */
2365 pull_file_id_16(frm, &id);
2366 sharepath = &frm[16];
2367 newname = sharepath + strlen(sharepath) + 1;
2368 sp_len = strlen(sharepath);
2370 DEBUG(10,("msg_file_was_renamed: Got rename message for sharepath %s, new name %s, "
2371 "file_id %s\n",
2372 sharepath, newname, file_id_string_tos(&id)));
2374 for(fsp = file_find_di_first(id); fsp; fsp = file_find_di_next(fsp)) {
2375 if (memcmp(fsp->conn->connectpath, sharepath, sp_len) == 0) {
2376 DEBUG(10,("msg_file_was_renamed: renaming file fnum %d from %s -> %s\n",
2377 fsp->fnum, fsp->fsp_name, newname ));
2378 string_set(&fsp->fsp_name, newname);
2379 } else {
2380 /* TODO. JRA. */
2381 /* Now we have the complete path we can work out if this is
2382 actually within this share and adjust newname accordingly. */
2383 DEBUG(10,("msg_file_was_renamed: share mismatch (sharepath %s "
2384 "not sharepath %s) "
2385 "fnum %d from %s -> %s\n",
2386 fsp->conn->connectpath,
2387 sharepath,
2388 fsp->fnum,
2389 fsp->fsp_name,
2390 newname ));