Fix bug 7950 - Samba 3.5.x fails BASE-CREATEX_SHAREMODES_DIR smbtorture4 test
[Samba.git] / source3 / smbd / open.c
blobbd748f9661af75a2c49b6f3c212232aaf7d89502
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"
23 #include "smbd/globals.h"
25 extern struct current_user current_user;
26 extern const struct generic_mapping file_generic_mapping;
28 struct deferred_open_record {
29 bool delayed_for_oplocks;
30 struct file_id id;
33 static NTSTATUS create_file_unixpath(connection_struct *conn,
34 struct smb_request *req,
35 struct smb_filename *smb_fname,
36 uint32_t access_mask,
37 uint32_t share_access,
38 uint32_t create_disposition,
39 uint32_t create_options,
40 uint32_t file_attributes,
41 uint32_t oplock_request,
42 uint64_t allocation_size,
43 struct security_descriptor *sd,
44 struct ea_list *ea_list,
46 files_struct **result,
47 int *pinfo);
49 /****************************************************************************
50 SMB1 file varient of se_access_check. Never test FILE_READ_ATTRIBUTES.
51 ****************************************************************************/
53 NTSTATUS smb1_file_se_access_check(connection_struct *conn,
54 const struct security_descriptor *sd,
55 const NT_USER_TOKEN *token,
56 uint32_t access_desired,
57 uint32_t *access_granted)
59 *access_granted = 0;
61 if (conn->server_info->utok.uid == 0 || conn->admin_user) {
62 /* I'm sorry sir, I didn't know you were root... */
63 *access_granted = access_desired;
64 if (access_desired & SEC_FLAG_MAXIMUM_ALLOWED) {
65 *access_granted |= FILE_GENERIC_ALL;
67 return NT_STATUS_OK;
70 return se_access_check(sd,
71 token,
72 (access_desired & ~FILE_READ_ATTRIBUTES),
73 access_granted);
76 /****************************************************************************
77 Check if we have open rights.
78 ****************************************************************************/
80 NTSTATUS smbd_check_open_rights(struct connection_struct *conn,
81 const struct smb_filename *smb_fname,
82 uint32_t access_mask,
83 uint32_t *access_granted)
85 /* Check if we have rights to open. */
86 NTSTATUS status;
87 struct security_descriptor *sd = NULL;
89 status = SMB_VFS_GET_NT_ACL(conn, smb_fname->base_name,
90 (OWNER_SECURITY_INFORMATION |
91 GROUP_SECURITY_INFORMATION |
92 DACL_SECURITY_INFORMATION),&sd);
94 if (!NT_STATUS_IS_OK(status)) {
95 DEBUG(10, ("smbd_check_open_rights: Could not get acl "
96 "on %s: %s\n",
97 smb_fname_str_dbg(smb_fname),
98 nt_errstr(status)));
99 return status;
102 status = smb1_file_se_access_check(conn,
104 conn->server_info->ptok,
105 access_mask,
106 access_granted);
108 DEBUG(10,("smbd_check_open_rights: file %s requesting "
109 "0x%x returning 0x%x (%s)\n",
110 smb_fname_str_dbg(smb_fname),
111 (unsigned int)access_mask,
112 (unsigned int)*access_granted,
113 nt_errstr(status) ));
115 if (!NT_STATUS_IS_OK(status)) {
116 if (DEBUGLEVEL >= 10) {
117 DEBUG(10,("smbd_check_open_rights: acl for %s is:\n",
118 smb_fname_str_dbg(smb_fname) ));
119 NDR_PRINT_DEBUG(security_descriptor, sd);
123 TALLOC_FREE(sd);
125 return status;
128 /****************************************************************************
129 fd support routines - attempt to do a dos_open.
130 ****************************************************************************/
132 static NTSTATUS fd_open(struct connection_struct *conn,
133 files_struct *fsp,
134 int flags,
135 mode_t mode)
137 struct smb_filename *smb_fname = fsp->fsp_name;
138 NTSTATUS status = NT_STATUS_OK;
140 #ifdef O_NOFOLLOW
142 * Never follow symlinks on a POSIX client. The
143 * client should be doing this.
146 if (fsp->posix_open || !lp_symlinks(SNUM(conn))) {
147 flags |= O_NOFOLLOW;
149 #endif
151 fsp->fh->fd = SMB_VFS_OPEN(conn, smb_fname, fsp, flags, mode);
152 if (fsp->fh->fd == -1) {
153 status = map_nt_error_from_unix(errno);
154 if (errno == EMFILE) {
155 static time_t last_warned = 0L;
157 if (time((time_t *) NULL) > last_warned) {
158 DEBUG(0,("Too many open files, unable "
159 "to open more! smbd's max "
160 "open files = %d\n",
161 lp_max_open_files()));
162 last_warned = time((time_t *) NULL);
168 DEBUG(10,("fd_open: name %s, flags = 0%o mode = 0%o, fd = %d. %s\n",
169 smb_fname_str_dbg(smb_fname), flags, (int)mode, fsp->fh->fd,
170 (fsp->fh->fd == -1) ? strerror(errno) : "" ));
172 return status;
175 /****************************************************************************
176 Close the file associated with a fsp.
177 ****************************************************************************/
179 NTSTATUS fd_close(files_struct *fsp)
181 int ret;
183 if (fsp->fh->fd == -1) {
184 return NT_STATUS_OK; /* What we used to call a stat open. */
186 if (fsp->fh->ref_count > 1) {
187 return NT_STATUS_OK; /* Shared handle. Only close last reference. */
190 ret = SMB_VFS_CLOSE(fsp);
191 fsp->fh->fd = -1;
192 if (ret == -1) {
193 return map_nt_error_from_unix(errno);
195 return NT_STATUS_OK;
198 /****************************************************************************
199 Change the ownership of a file to that of the parent directory.
200 Do this by fd if possible.
201 ****************************************************************************/
203 void change_file_owner_to_parent(connection_struct *conn,
204 const char *inherit_from_dir,
205 files_struct *fsp)
207 struct smb_filename *smb_fname_parent = NULL;
208 NTSTATUS status;
209 int ret;
211 status = create_synthetic_smb_fname(talloc_tos(), inherit_from_dir,
212 NULL, NULL, &smb_fname_parent);
213 if (!NT_STATUS_IS_OK(status)) {
214 return;
217 ret = SMB_VFS_STAT(conn, smb_fname_parent);
218 if (ret == -1) {
219 DEBUG(0,("change_file_owner_to_parent: failed to stat parent "
220 "directory %s. Error was %s\n",
221 smb_fname_str_dbg(smb_fname_parent),
222 strerror(errno)));
223 return;
226 become_root();
227 ret = SMB_VFS_FCHOWN(fsp, smb_fname_parent->st.st_ex_uid, (gid_t)-1);
228 unbecome_root();
229 if (ret == -1) {
230 DEBUG(0,("change_file_owner_to_parent: failed to fchown "
231 "file %s to parent directory uid %u. Error "
232 "was %s\n", fsp_str_dbg(fsp),
233 (unsigned int)smb_fname_parent->st.st_ex_uid,
234 strerror(errno) ));
237 DEBUG(10,("change_file_owner_to_parent: changed new file %s to "
238 "parent directory uid %u.\n", fsp_str_dbg(fsp),
239 (unsigned int)smb_fname_parent->st.st_ex_uid));
241 TALLOC_FREE(smb_fname_parent);
244 NTSTATUS change_dir_owner_to_parent(connection_struct *conn,
245 const char *inherit_from_dir,
246 const char *fname,
247 SMB_STRUCT_STAT *psbuf)
249 struct smb_filename *smb_fname_parent = NULL;
250 struct smb_filename *smb_fname_cwd = NULL;
251 char *saved_dir = NULL;
252 TALLOC_CTX *ctx = talloc_tos();
253 NTSTATUS status = NT_STATUS_OK;
254 int ret;
256 status = create_synthetic_smb_fname(ctx, inherit_from_dir, NULL, NULL,
257 &smb_fname_parent);
258 if (!NT_STATUS_IS_OK(status)) {
259 return status;
262 ret = SMB_VFS_STAT(conn, smb_fname_parent);
263 if (ret == -1) {
264 status = map_nt_error_from_unix(errno);
265 DEBUG(0,("change_dir_owner_to_parent: failed to stat parent "
266 "directory %s. Error was %s\n",
267 smb_fname_str_dbg(smb_fname_parent),
268 strerror(errno)));
269 goto out;
272 /* We've already done an lstat into psbuf, and we know it's a
273 directory. If we can cd into the directory and the dev/ino
274 are the same then we can safely chown without races as
275 we're locking the directory in place by being in it. This
276 should work on any UNIX (thanks tridge :-). JRA.
279 saved_dir = vfs_GetWd(ctx,conn);
280 if (!saved_dir) {
281 status = map_nt_error_from_unix(errno);
282 DEBUG(0,("change_dir_owner_to_parent: failed to get "
283 "current working directory. Error was %s\n",
284 strerror(errno)));
285 goto out;
288 /* Chdir into the new path. */
289 if (vfs_ChDir(conn, fname) == -1) {
290 status = map_nt_error_from_unix(errno);
291 DEBUG(0,("change_dir_owner_to_parent: failed to change "
292 "current working directory to %s. Error "
293 "was %s\n", fname, strerror(errno) ));
294 goto chdir;
297 status = create_synthetic_smb_fname(ctx, ".", NULL, NULL,
298 &smb_fname_cwd);
299 if (!NT_STATUS_IS_OK(status)) {
300 return status;
303 ret = SMB_VFS_STAT(conn, smb_fname_cwd);
304 if (ret == -1) {
305 status = map_nt_error_from_unix(errno);
306 DEBUG(0,("change_dir_owner_to_parent: failed to stat "
307 "directory '.' (%s) Error was %s\n",
308 fname, strerror(errno)));
309 goto chdir;
312 /* Ensure we're pointing at the same place. */
313 if (smb_fname_cwd->st.st_ex_dev != psbuf->st_ex_dev ||
314 smb_fname_cwd->st.st_ex_ino != psbuf->st_ex_ino ||
315 smb_fname_cwd->st.st_ex_mode != psbuf->st_ex_mode ) {
316 DEBUG(0,("change_dir_owner_to_parent: "
317 "device/inode/mode on directory %s changed. "
318 "Refusing to chown !\n", fname ));
319 status = NT_STATUS_ACCESS_DENIED;
320 goto chdir;
323 become_root();
324 ret = SMB_VFS_CHOWN(conn, ".", smb_fname_parent->st.st_ex_uid,
325 (gid_t)-1);
326 unbecome_root();
327 if (ret == -1) {
328 status = map_nt_error_from_unix(errno);
329 DEBUG(10,("change_dir_owner_to_parent: failed to chown "
330 "directory %s to parent directory uid %u. "
331 "Error was %s\n", fname,
332 (unsigned int)smb_fname_parent->st.st_ex_uid,
333 strerror(errno) ));
334 goto chdir;
337 DEBUG(10,("change_dir_owner_to_parent: changed ownership of new "
338 "directory %s to parent directory uid %u.\n",
339 fname, (unsigned int)smb_fname_parent->st.st_ex_uid ));
341 chdir:
342 vfs_ChDir(conn,saved_dir);
343 out:
344 TALLOC_FREE(smb_fname_parent);
345 TALLOC_FREE(smb_fname_cwd);
346 return status;
349 /****************************************************************************
350 Open a file.
351 ****************************************************************************/
353 static NTSTATUS open_file(files_struct *fsp,
354 connection_struct *conn,
355 struct smb_request *req,
356 const char *parent_dir,
357 int flags,
358 mode_t unx_mode,
359 uint32 access_mask, /* client requested access mask. */
360 uint32 open_access_mask) /* what we're actually using in the open. */
362 struct smb_filename *smb_fname = fsp->fsp_name;
363 NTSTATUS status = NT_STATUS_OK;
364 int accmode = (flags & O_ACCMODE);
365 int local_flags = flags;
366 bool file_existed = VALID_STAT(fsp->fsp_name->st);
368 fsp->fh->fd = -1;
369 errno = EPERM;
371 /* Check permissions */
374 * This code was changed after seeing a client open request
375 * containing the open mode of (DENY_WRITE/read-only) with
376 * the 'create if not exist' bit set. The previous code
377 * would fail to open the file read only on a read-only share
378 * as it was checking the flags parameter directly against O_RDONLY,
379 * this was failing as the flags parameter was set to O_RDONLY|O_CREAT.
380 * JRA.
383 if (!CAN_WRITE(conn)) {
384 /* It's a read-only share - fail if we wanted to write. */
385 if(accmode != O_RDONLY || (flags & O_TRUNC) || (flags & O_APPEND)) {
386 DEBUG(3,("Permission denied opening %s\n",
387 smb_fname_str_dbg(smb_fname)));
388 return NT_STATUS_ACCESS_DENIED;
389 } else if(flags & O_CREAT) {
390 /* We don't want to write - but we must make sure that
391 O_CREAT doesn't create the file if we have write
392 access into the directory.
394 flags &= ~(O_CREAT|O_EXCL);
395 local_flags &= ~(O_CREAT|O_EXCL);
400 * This little piece of insanity is inspired by the
401 * fact that an NT client can open a file for O_RDONLY,
402 * but set the create disposition to FILE_EXISTS_TRUNCATE.
403 * If the client *can* write to the file, then it expects to
404 * truncate the file, even though it is opening for readonly.
405 * Quicken uses this stupid trick in backup file creation...
406 * Thanks *greatly* to "David W. Chapman Jr." <dwcjr@inethouston.net>
407 * for helping track this one down. It didn't bite us in 2.0.x
408 * as we always opened files read-write in that release. JRA.
411 if ((accmode == O_RDONLY) && ((flags & O_TRUNC) == O_TRUNC)) {
412 DEBUG(10,("open_file: truncate requested on read-only open "
413 "for file %s\n", smb_fname_str_dbg(smb_fname)));
414 local_flags = (flags & ~O_ACCMODE)|O_RDWR;
417 if ((open_access_mask & (FILE_READ_DATA|FILE_WRITE_DATA|FILE_APPEND_DATA|FILE_EXECUTE)) ||
418 (!file_existed && (local_flags & O_CREAT)) ||
419 ((local_flags & O_TRUNC) == O_TRUNC) ) {
420 const char *wild;
423 * We can't actually truncate here as the file may be locked.
424 * open_file_ntcreate will take care of the truncate later. JRA.
427 local_flags &= ~O_TRUNC;
429 #if defined(O_NONBLOCK) && defined(S_ISFIFO)
431 * We would block on opening a FIFO with no one else on the
432 * other end. Do what we used to do and add O_NONBLOCK to the
433 * open flags. JRA.
436 if (file_existed && S_ISFIFO(smb_fname->st.st_ex_mode)) {
437 local_flags |= O_NONBLOCK;
439 #endif
441 /* Don't create files with Microsoft wildcard characters. */
442 if (fsp->base_fsp) {
444 * wildcard characters are allowed in stream names
445 * only test the basefilename
447 wild = fsp->base_fsp->fsp_name->base_name;
448 } else {
449 wild = smb_fname->base_name;
451 if ((local_flags & O_CREAT) && !file_existed &&
452 ms_has_wild(wild)) {
453 return NT_STATUS_OBJECT_NAME_INVALID;
456 /* Actually do the open */
457 status = fd_open(conn, fsp, local_flags, unx_mode);
458 if (!NT_STATUS_IS_OK(status)) {
459 DEBUG(3,("Error opening file %s (%s) (local_flags=%d) "
460 "(flags=%d)\n", smb_fname_str_dbg(smb_fname),
461 nt_errstr(status),local_flags,flags));
462 return status;
465 if ((local_flags & O_CREAT) && !file_existed) {
467 /* Inherit the ACL if required */
468 if (lp_inherit_perms(SNUM(conn))) {
469 inherit_access_posix_acl(conn, parent_dir,
470 smb_fname->base_name,
471 unx_mode);
474 /* Change the owner if required. */
475 if (lp_inherit_owner(SNUM(conn))) {
476 change_file_owner_to_parent(conn, parent_dir,
477 fsp);
480 notify_fname(conn, NOTIFY_ACTION_ADDED,
481 FILE_NOTIFY_CHANGE_FILE_NAME,
482 smb_fname->base_name);
485 } else {
486 fsp->fh->fd = -1; /* What we used to call a stat open. */
487 if (file_existed) {
488 uint32_t access_granted = 0;
490 status = smbd_check_open_rights(conn,
491 smb_fname,
492 access_mask,
493 &access_granted);
494 if (!NT_STATUS_IS_OK(status)) {
495 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
497 * On NT_STATUS_ACCESS_DENIED, access_granted
498 * contains the denied bits.
501 if ((access_mask & FILE_WRITE_ATTRIBUTES) &&
502 (access_granted & FILE_WRITE_ATTRIBUTES) &&
503 (lp_map_readonly(SNUM(conn)) ||
504 lp_map_archive(SNUM(conn)) ||
505 lp_map_hidden(SNUM(conn)) ||
506 lp_map_system(SNUM(conn)))) {
507 access_granted &= ~FILE_WRITE_ATTRIBUTES;
509 DEBUG(10,("open_file: "
510 "overrode "
511 "FILE_WRITE_"
512 "ATTRIBUTES "
513 "on file %s\n",
514 smb_fname_str_dbg(
515 smb_fname)));
518 if ((access_mask & DELETE_ACCESS) &&
519 (access_granted & DELETE_ACCESS) &&
520 can_delete_file_in_directory(conn,
521 smb_fname)) {
522 /* Were we trying to do a stat open
523 * for delete and didn't get DELETE
524 * access (only) ? Check if the
525 * directory allows DELETE_CHILD.
526 * See here:
527 * http://blogs.msdn.com/oldnewthing/archive/2004/06/04/148426.aspx
528 * for details. */
530 access_granted &= ~DELETE_ACCESS;
532 DEBUG(10,("open_file: "
533 "overrode "
534 "DELETE_ACCESS on "
535 "file %s\n",
536 smb_fname_str_dbg(
537 smb_fname)));
540 if (access_granted != 0) {
541 DEBUG(10,("open_file: Access "
542 "denied on file "
543 "%s\n",
544 smb_fname_str_dbg(
545 smb_fname)));
546 return status;
548 } else if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND) &&
549 fsp->posix_open &&
550 S_ISLNK(smb_fname->st.st_ex_mode)) {
551 /* This is a POSIX stat open for delete
552 * or rename on a symlink that points
553 * nowhere. Allow. */
554 DEBUG(10,("open_file: allowing POSIX "
555 "open on bad symlink %s\n",
556 smb_fname_str_dbg(
557 smb_fname)));
558 } else {
559 DEBUG(10,("open_file: "
560 "smbd_check_open_rights on file "
561 "%s returned %s\n",
562 smb_fname_str_dbg(smb_fname),
563 nt_errstr(status) ));
564 return status;
570 if (!file_existed) {
571 int ret;
573 if (fsp->fh->fd == -1) {
574 ret = SMB_VFS_STAT(conn, smb_fname);
575 } else {
576 ret = SMB_VFS_FSTAT(fsp, &smb_fname->st);
577 /* If we have an fd, this stat should succeed. */
578 if (ret == -1) {
579 DEBUG(0,("Error doing fstat on open file %s "
580 "(%s)\n",
581 smb_fname_str_dbg(smb_fname),
582 strerror(errno) ));
586 /* For a non-io open, this stat failing means file not found. JRA */
587 if (ret == -1) {
588 status = map_nt_error_from_unix(errno);
589 fd_close(fsp);
590 return status;
595 * POSIX allows read-only opens of directories. We don't
596 * want to do this (we use a different code path for this)
597 * so catch a directory open and return an EISDIR. JRA.
600 if(S_ISDIR(smb_fname->st.st_ex_mode)) {
601 fd_close(fsp);
602 errno = EISDIR;
603 return NT_STATUS_FILE_IS_A_DIRECTORY;
606 fsp->mode = smb_fname->st.st_ex_mode;
607 fsp->file_id = vfs_file_id_from_sbuf(conn, &smb_fname->st);
608 fsp->vuid = req ? req->vuid : UID_FIELD_INVALID;
609 fsp->file_pid = req ? req->smbpid : 0;
610 fsp->can_lock = True;
611 fsp->can_read = (access_mask & (FILE_READ_DATA)) ? True : False;
612 if (!CAN_WRITE(conn)) {
613 fsp->can_write = False;
614 } else {
615 fsp->can_write = (access_mask & (FILE_WRITE_DATA | FILE_APPEND_DATA)) ?
616 True : False;
618 fsp->print_file = False;
619 fsp->modified = False;
620 fsp->sent_oplock_break = NO_BREAK_SENT;
621 fsp->is_directory = False;
622 if (conn->aio_write_behind_list &&
623 is_in_path(smb_fname->base_name, conn->aio_write_behind_list,
624 conn->case_sensitive)) {
625 fsp->aio_write_behind = True;
628 fsp->wcp = NULL; /* Write cache pointer. */
630 DEBUG(2,("%s opened file %s read=%s write=%s (numopen=%d)\n",
631 conn->server_info->unix_name,
632 smb_fname_str_dbg(smb_fname),
633 BOOLSTR(fsp->can_read), BOOLSTR(fsp->can_write),
634 conn->num_files_open));
636 errno = 0;
637 return NT_STATUS_OK;
640 /*******************************************************************
641 Return True if the filename is one of the special executable types.
642 ********************************************************************/
644 bool is_executable(const char *fname)
646 if ((fname = strrchr_m(fname,'.'))) {
647 if (strequal(fname,".com") ||
648 strequal(fname,".dll") ||
649 strequal(fname,".exe") ||
650 strequal(fname,".sym")) {
651 return True;
654 return False;
657 /****************************************************************************
658 Check if we can open a file with a share mode.
659 Returns True if conflict, False if not.
660 ****************************************************************************/
662 static bool share_conflict(struct share_mode_entry *entry,
663 uint32 access_mask,
664 uint32 share_access)
666 DEBUG(10,("share_conflict: entry->access_mask = 0x%x, "
667 "entry->share_access = 0x%x, "
668 "entry->private_options = 0x%x\n",
669 (unsigned int)entry->access_mask,
670 (unsigned int)entry->share_access,
671 (unsigned int)entry->private_options));
673 DEBUG(10,("share_conflict: access_mask = 0x%x, share_access = 0x%x\n",
674 (unsigned int)access_mask, (unsigned int)share_access));
676 if ((entry->access_mask & (FILE_WRITE_DATA|
677 FILE_APPEND_DATA|
678 FILE_READ_DATA|
679 FILE_EXECUTE|
680 DELETE_ACCESS)) == 0) {
681 DEBUG(10,("share_conflict: No conflict due to "
682 "entry->access_mask = 0x%x\n",
683 (unsigned int)entry->access_mask ));
684 return False;
687 if ((access_mask & (FILE_WRITE_DATA|
688 FILE_APPEND_DATA|
689 FILE_READ_DATA|
690 FILE_EXECUTE|
691 DELETE_ACCESS)) == 0) {
692 DEBUG(10,("share_conflict: No conflict due to "
693 "access_mask = 0x%x\n",
694 (unsigned int)access_mask ));
695 return False;
698 #if 1 /* JRA TEST - Superdebug. */
699 #define CHECK_MASK(num, am, right, sa, share) \
700 DEBUG(10,("share_conflict: [%d] am (0x%x) & right (0x%x) = 0x%x\n", \
701 (unsigned int)(num), (unsigned int)(am), \
702 (unsigned int)(right), (unsigned int)(am)&(right) )); \
703 DEBUG(10,("share_conflict: [%d] sa (0x%x) & share (0x%x) = 0x%x\n", \
704 (unsigned int)(num), (unsigned int)(sa), \
705 (unsigned int)(share), (unsigned int)(sa)&(share) )); \
706 if (((am) & (right)) && !((sa) & (share))) { \
707 DEBUG(10,("share_conflict: check %d conflict am = 0x%x, right = 0x%x, \
708 sa = 0x%x, share = 0x%x\n", (num), (unsigned int)(am), (unsigned int)(right), (unsigned int)(sa), \
709 (unsigned int)(share) )); \
710 return True; \
712 #else
713 #define CHECK_MASK(num, am, right, sa, share) \
714 if (((am) & (right)) && !((sa) & (share))) { \
715 DEBUG(10,("share_conflict: check %d conflict am = 0x%x, right = 0x%x, \
716 sa = 0x%x, share = 0x%x\n", (num), (unsigned int)(am), (unsigned int)(right), (unsigned int)(sa), \
717 (unsigned int)(share) )); \
718 return True; \
720 #endif
722 CHECK_MASK(1, entry->access_mask, FILE_WRITE_DATA | FILE_APPEND_DATA,
723 share_access, FILE_SHARE_WRITE);
724 CHECK_MASK(2, access_mask, FILE_WRITE_DATA | FILE_APPEND_DATA,
725 entry->share_access, FILE_SHARE_WRITE);
727 CHECK_MASK(3, entry->access_mask, FILE_READ_DATA | FILE_EXECUTE,
728 share_access, FILE_SHARE_READ);
729 CHECK_MASK(4, access_mask, FILE_READ_DATA | FILE_EXECUTE,
730 entry->share_access, FILE_SHARE_READ);
732 CHECK_MASK(5, entry->access_mask, DELETE_ACCESS,
733 share_access, FILE_SHARE_DELETE);
734 CHECK_MASK(6, access_mask, DELETE_ACCESS,
735 entry->share_access, FILE_SHARE_DELETE);
737 DEBUG(10,("share_conflict: No conflict.\n"));
738 return False;
741 #if defined(DEVELOPER)
742 static void validate_my_share_entries(int num,
743 struct share_mode_entry *share_entry)
745 files_struct *fsp;
747 if (!procid_is_me(&share_entry->pid)) {
748 return;
751 if (is_deferred_open_entry(share_entry) &&
752 !open_was_deferred(share_entry->op_mid)) {
753 char *str = talloc_asprintf(talloc_tos(),
754 "Got a deferred entry without a request: "
755 "PANIC: %s\n",
756 share_mode_str(talloc_tos(), num, share_entry));
757 smb_panic(str);
760 if (!is_valid_share_mode_entry(share_entry)) {
761 return;
764 fsp = file_find_dif(share_entry->id,
765 share_entry->share_file_id);
766 if (!fsp) {
767 DEBUG(0,("validate_my_share_entries: PANIC : %s\n",
768 share_mode_str(talloc_tos(), num, share_entry) ));
769 smb_panic("validate_my_share_entries: Cannot match a "
770 "share entry with an open file\n");
773 if (is_deferred_open_entry(share_entry) ||
774 is_unused_share_mode_entry(share_entry)) {
775 goto panic;
778 if ((share_entry->op_type == NO_OPLOCK) &&
779 (fsp->oplock_type == FAKE_LEVEL_II_OPLOCK)) {
780 /* Someone has already written to it, but I haven't yet
781 * noticed */
782 return;
785 if (((uint16)fsp->oplock_type) != share_entry->op_type) {
786 goto panic;
789 return;
791 panic:
793 char *str;
794 DEBUG(0,("validate_my_share_entries: PANIC : %s\n",
795 share_mode_str(talloc_tos(), num, share_entry) ));
796 str = talloc_asprintf(talloc_tos(),
797 "validate_my_share_entries: "
798 "file %s, oplock_type = 0x%x, op_type = 0x%x\n",
799 fsp->fsp_name->base_name,
800 (unsigned int)fsp->oplock_type,
801 (unsigned int)share_entry->op_type );
802 smb_panic(str);
805 #endif
807 bool is_stat_open(uint32 access_mask)
809 return (access_mask &&
810 ((access_mask & ~(SYNCHRONIZE_ACCESS| FILE_READ_ATTRIBUTES|
811 FILE_WRITE_ATTRIBUTES))==0) &&
812 ((access_mask & (SYNCHRONIZE_ACCESS|FILE_READ_ATTRIBUTES|
813 FILE_WRITE_ATTRIBUTES)) != 0));
816 /****************************************************************************
817 Deal with share modes
818 Invarient: Share mode must be locked on entry and exit.
819 Returns -1 on error, or number of share modes on success (may be zero).
820 ****************************************************************************/
822 static NTSTATUS open_mode_check(connection_struct *conn,
823 struct share_mode_lock *lck,
824 uint32 access_mask,
825 uint32 share_access,
826 uint32 create_options,
827 bool *file_existed)
829 int i;
831 if(lck->num_share_modes == 0) {
832 return NT_STATUS_OK;
835 *file_existed = True;
837 /* A delete on close prohibits everything */
839 if (lck->delete_on_close) {
840 return NT_STATUS_DELETE_PENDING;
843 if (is_stat_open(access_mask)) {
844 /* Stat open that doesn't trigger oplock breaks or share mode
845 * checks... ! JRA. */
846 return NT_STATUS_OK;
850 * Check if the share modes will give us access.
853 #if defined(DEVELOPER)
854 for(i = 0; i < lck->num_share_modes; i++) {
855 validate_my_share_entries(i, &lck->share_modes[i]);
857 #endif
859 if (!lp_share_modes(SNUM(conn))) {
860 return NT_STATUS_OK;
863 /* Now we check the share modes, after any oplock breaks. */
864 for(i = 0; i < lck->num_share_modes; i++) {
866 if (!is_valid_share_mode_entry(&lck->share_modes[i])) {
867 continue;
870 /* someone else has a share lock on it, check to see if we can
871 * too */
872 if (share_conflict(&lck->share_modes[i],
873 access_mask, share_access)) {
874 return NT_STATUS_SHARING_VIOLATION;
878 return NT_STATUS_OK;
881 static bool is_delete_request(files_struct *fsp) {
882 return ((fsp->access_mask == DELETE_ACCESS) &&
883 (fsp->oplock_type == NO_OPLOCK));
887 * Send a break message to the oplock holder and delay the open for
888 * our client.
891 static NTSTATUS send_break_message(files_struct *fsp,
892 struct share_mode_entry *exclusive,
893 uint16 mid,
894 int oplock_request)
896 NTSTATUS status;
897 char msg[MSG_SMB_SHARE_MODE_ENTRY_SIZE];
899 DEBUG(10, ("Sending break request to PID %s\n",
900 procid_str_static(&exclusive->pid)));
901 exclusive->op_mid = mid;
903 /* Create the message. */
904 share_mode_entry_to_message(msg, exclusive);
906 /* Add in the FORCE_OPLOCK_BREAK_TO_NONE bit in the message if set. We
907 don't want this set in the share mode struct pointed to by lck. */
909 if (oplock_request & FORCE_OPLOCK_BREAK_TO_NONE) {
910 SSVAL(msg,6,exclusive->op_type | FORCE_OPLOCK_BREAK_TO_NONE);
913 status = messaging_send_buf(smbd_messaging_context(), exclusive->pid,
914 MSG_SMB_BREAK_REQUEST,
915 (uint8 *)msg,
916 MSG_SMB_SHARE_MODE_ENTRY_SIZE);
917 if (!NT_STATUS_IS_OK(status)) {
918 DEBUG(3, ("Could not send oplock break message: %s\n",
919 nt_errstr(status)));
922 return status;
926 * 1) No files open at all or internal open: Grant whatever the client wants.
928 * 2) Exclusive (or batch) oplock around: If the requested access is a delete
929 * request, break if the oplock around is a batch oplock. If it's another
930 * requested access type, break.
932 * 3) Only level2 around: Grant level2 and do nothing else.
935 static bool delay_for_oplocks(struct share_mode_lock *lck,
936 files_struct *fsp,
937 uint16 mid,
938 int pass_number,
939 int oplock_request)
941 int i;
942 struct share_mode_entry *exclusive = NULL;
943 bool valid_entry = false;
944 bool have_level2 = false;
945 bool have_a_none_oplock = false;
946 bool allow_level2 = (global_client_caps & CAP_LEVEL_II_OPLOCKS) &&
947 lp_level2_oplocks(SNUM(fsp->conn));
949 if (oplock_request & INTERNAL_OPEN_ONLY) {
950 fsp->oplock_type = NO_OPLOCK;
953 if ((oplock_request & INTERNAL_OPEN_ONLY) || is_stat_open(fsp->access_mask)) {
954 return false;
957 for (i=0; i<lck->num_share_modes; i++) {
959 if (!is_valid_share_mode_entry(&lck->share_modes[i])) {
960 continue;
963 /* At least one entry is not an invalid or deferred entry. */
964 valid_entry = true;
966 if (pass_number == 1) {
967 if (BATCH_OPLOCK_TYPE(lck->share_modes[i].op_type)) {
968 SMB_ASSERT(exclusive == NULL);
969 exclusive = &lck->share_modes[i];
971 } else {
972 if (EXCLUSIVE_OPLOCK_TYPE(lck->share_modes[i].op_type)) {
973 SMB_ASSERT(exclusive == NULL);
974 exclusive = &lck->share_modes[i];
978 if (LEVEL_II_OPLOCK_TYPE(lck->share_modes[i].op_type)) {
979 SMB_ASSERT(exclusive == NULL);
980 have_level2 = true;
983 if (lck->share_modes[i].op_type == NO_OPLOCK) {
984 have_a_none_oplock = true;
988 if (exclusive != NULL) { /* Found an exclusive oplock */
989 bool delay_it = is_delete_request(fsp) ?
990 BATCH_OPLOCK_TYPE(exclusive->op_type) : true;
991 SMB_ASSERT(!have_level2);
992 if (delay_it) {
993 send_break_message(fsp, exclusive, mid, oplock_request);
994 return true;
999 * Match what was requested (fsp->oplock_type) with
1000 * what was found in the existing share modes.
1003 if (!valid_entry) {
1004 /* All entries are placeholders or deferred.
1005 * Directly grant whatever the client wants. */
1006 if (fsp->oplock_type == NO_OPLOCK) {
1007 /* Store a level2 oplock, but don't tell the client */
1008 fsp->oplock_type = FAKE_LEVEL_II_OPLOCK;
1010 } else if (have_a_none_oplock) {
1011 fsp->oplock_type = NO_OPLOCK;
1012 } else if (have_level2) {
1013 if (fsp->oplock_type == NO_OPLOCK ||
1014 fsp->oplock_type == FAKE_LEVEL_II_OPLOCK) {
1015 /* Store a level2 oplock, but don't tell the client */
1016 fsp->oplock_type = FAKE_LEVEL_II_OPLOCK;
1017 } else {
1018 fsp->oplock_type = LEVEL_II_OPLOCK;
1020 } else {
1021 /* This case can never happen. */
1022 SMB_ASSERT(1);
1026 * Don't grant level2 to clients that don't want them
1027 * or if we've turned them off.
1029 if (fsp->oplock_type == LEVEL_II_OPLOCK && !allow_level2) {
1030 fsp->oplock_type = FAKE_LEVEL_II_OPLOCK;
1033 DEBUG(10,("delay_for_oplocks: oplock type 0x%x on file %s\n",
1034 fsp->oplock_type, fsp_str_dbg(fsp)));
1036 /* No delay. */
1037 return false;
1040 bool request_timed_out(struct timeval request_time,
1041 struct timeval timeout)
1043 struct timeval now, end_time;
1044 GetTimeOfDay(&now);
1045 end_time = timeval_sum(&request_time, &timeout);
1046 return (timeval_compare(&end_time, &now) < 0);
1049 /****************************************************************************
1050 Handle the 1 second delay in returning a SHARING_VIOLATION error.
1051 ****************************************************************************/
1053 static void defer_open(struct share_mode_lock *lck,
1054 struct timeval request_time,
1055 struct timeval timeout,
1056 struct smb_request *req,
1057 struct deferred_open_record *state)
1059 int i;
1061 /* Paranoia check */
1063 for (i=0; i<lck->num_share_modes; i++) {
1064 struct share_mode_entry *e = &lck->share_modes[i];
1066 if (!is_deferred_open_entry(e)) {
1067 continue;
1070 if (procid_is_me(&e->pid) && (e->op_mid == req->mid)) {
1071 DEBUG(0, ("Trying to defer an already deferred "
1072 "request: mid=%d, exiting\n", req->mid));
1073 exit_server("attempt to defer a deferred request");
1077 /* End paranoia check */
1079 DEBUG(10,("defer_open_sharing_error: time [%u.%06u] adding deferred "
1080 "open entry for mid %u\n",
1081 (unsigned int)request_time.tv_sec,
1082 (unsigned int)request_time.tv_usec,
1083 (unsigned int)req->mid));
1085 if (!push_deferred_smb_message(req, request_time, timeout,
1086 (char *)state, sizeof(*state))) {
1087 exit_server("push_deferred_smb_message failed");
1089 add_deferred_open(lck, req->mid, request_time, state->id);
1093 /****************************************************************************
1094 On overwrite open ensure that the attributes match.
1095 ****************************************************************************/
1097 bool open_match_attributes(connection_struct *conn,
1098 uint32 old_dos_attr,
1099 uint32 new_dos_attr,
1100 mode_t existing_unx_mode,
1101 mode_t new_unx_mode,
1102 mode_t *returned_unx_mode)
1104 uint32 noarch_old_dos_attr, noarch_new_dos_attr;
1106 noarch_old_dos_attr = (old_dos_attr & ~FILE_ATTRIBUTE_ARCHIVE);
1107 noarch_new_dos_attr = (new_dos_attr & ~FILE_ATTRIBUTE_ARCHIVE);
1109 if((noarch_old_dos_attr == 0 && noarch_new_dos_attr != 0) ||
1110 (noarch_old_dos_attr != 0 && ((noarch_old_dos_attr & noarch_new_dos_attr) == noarch_old_dos_attr))) {
1111 *returned_unx_mode = new_unx_mode;
1112 } else {
1113 *returned_unx_mode = (mode_t)0;
1116 DEBUG(10,("open_match_attributes: old_dos_attr = 0x%x, "
1117 "existing_unx_mode = 0%o, new_dos_attr = 0x%x "
1118 "returned_unx_mode = 0%o\n",
1119 (unsigned int)old_dos_attr,
1120 (unsigned int)existing_unx_mode,
1121 (unsigned int)new_dos_attr,
1122 (unsigned int)*returned_unx_mode ));
1124 /* If we're mapping SYSTEM and HIDDEN ensure they match. */
1125 if (lp_map_system(SNUM(conn)) || lp_store_dos_attributes(SNUM(conn))) {
1126 if ((old_dos_attr & FILE_ATTRIBUTE_SYSTEM) &&
1127 !(new_dos_attr & FILE_ATTRIBUTE_SYSTEM)) {
1128 return False;
1131 if (lp_map_hidden(SNUM(conn)) || lp_store_dos_attributes(SNUM(conn))) {
1132 if ((old_dos_attr & FILE_ATTRIBUTE_HIDDEN) &&
1133 !(new_dos_attr & FILE_ATTRIBUTE_HIDDEN)) {
1134 return False;
1137 return True;
1140 /****************************************************************************
1141 Special FCB or DOS processing in the case of a sharing violation.
1142 Try and find a duplicated file handle.
1143 ****************************************************************************/
1145 NTSTATUS fcb_or_dos_open(struct smb_request *req,
1146 connection_struct *conn,
1147 files_struct *fsp_to_dup_into,
1148 const struct smb_filename *smb_fname,
1149 struct file_id id,
1150 uint16 file_pid,
1151 uint16 vuid,
1152 uint32 access_mask,
1153 uint32 share_access,
1154 uint32 create_options)
1156 files_struct *fsp;
1158 DEBUG(5,("fcb_or_dos_open: attempting old open semantics for "
1159 "file %s.\n", smb_fname_str_dbg(smb_fname)));
1161 for(fsp = file_find_di_first(id); fsp;
1162 fsp = file_find_di_next(fsp)) {
1164 DEBUG(10,("fcb_or_dos_open: checking file %s, fd = %d, "
1165 "vuid = %u, file_pid = %u, private_options = 0x%x "
1166 "access_mask = 0x%x\n", fsp_str_dbg(fsp),
1167 fsp->fh->fd, (unsigned int)fsp->vuid,
1168 (unsigned int)fsp->file_pid,
1169 (unsigned int)fsp->fh->private_options,
1170 (unsigned int)fsp->access_mask ));
1172 if (fsp->fh->fd != -1 &&
1173 fsp->vuid == vuid &&
1174 fsp->file_pid == file_pid &&
1175 (fsp->fh->private_options & (NTCREATEX_OPTIONS_PRIVATE_DENY_DOS |
1176 NTCREATEX_OPTIONS_PRIVATE_DENY_FCB)) &&
1177 (fsp->access_mask & FILE_WRITE_DATA) &&
1178 strequal(fsp->fsp_name->base_name, smb_fname->base_name) &&
1179 strequal(fsp->fsp_name->stream_name,
1180 smb_fname->stream_name)) {
1181 DEBUG(10,("fcb_or_dos_open: file match\n"));
1182 break;
1186 if (!fsp) {
1187 return NT_STATUS_NOT_FOUND;
1190 /* quite an insane set of semantics ... */
1191 if (is_executable(smb_fname->base_name) &&
1192 (fsp->fh->private_options & NTCREATEX_OPTIONS_PRIVATE_DENY_DOS)) {
1193 DEBUG(10,("fcb_or_dos_open: file fail due to is_executable.\n"));
1194 return NT_STATUS_INVALID_PARAMETER;
1197 /* We need to duplicate this fsp. */
1198 return dup_file_fsp(req, fsp, access_mask, share_access,
1199 create_options, fsp_to_dup_into);
1202 /****************************************************************************
1203 Open a file with a share mode - old openX method - map into NTCreate.
1204 ****************************************************************************/
1206 bool map_open_params_to_ntcreate(const struct smb_filename *smb_fname,
1207 int deny_mode, int open_func,
1208 uint32 *paccess_mask,
1209 uint32 *pshare_mode,
1210 uint32 *pcreate_disposition,
1211 uint32 *pcreate_options)
1213 uint32 access_mask;
1214 uint32 share_mode;
1215 uint32 create_disposition;
1216 uint32 create_options = FILE_NON_DIRECTORY_FILE;
1218 DEBUG(10,("map_open_params_to_ntcreate: fname = %s, deny_mode = 0x%x, "
1219 "open_func = 0x%x\n",
1220 smb_fname_str_dbg(smb_fname), (unsigned int)deny_mode,
1221 (unsigned int)open_func ));
1223 /* Create the NT compatible access_mask. */
1224 switch (GET_OPENX_MODE(deny_mode)) {
1225 case DOS_OPEN_EXEC: /* Implies read-only - used to be FILE_READ_DATA */
1226 case DOS_OPEN_RDONLY:
1227 access_mask = FILE_GENERIC_READ;
1228 break;
1229 case DOS_OPEN_WRONLY:
1230 access_mask = FILE_GENERIC_WRITE;
1231 break;
1232 case DOS_OPEN_RDWR:
1233 case DOS_OPEN_FCB:
1234 access_mask = FILE_GENERIC_READ|FILE_GENERIC_WRITE;
1235 break;
1236 default:
1237 DEBUG(10,("map_open_params_to_ntcreate: bad open mode = 0x%x\n",
1238 (unsigned int)GET_OPENX_MODE(deny_mode)));
1239 return False;
1242 /* Create the NT compatible create_disposition. */
1243 switch (open_func) {
1244 case OPENX_FILE_EXISTS_FAIL|OPENX_FILE_CREATE_IF_NOT_EXIST:
1245 create_disposition = FILE_CREATE;
1246 break;
1248 case OPENX_FILE_EXISTS_OPEN:
1249 create_disposition = FILE_OPEN;
1250 break;
1252 case OPENX_FILE_EXISTS_OPEN|OPENX_FILE_CREATE_IF_NOT_EXIST:
1253 create_disposition = FILE_OPEN_IF;
1254 break;
1256 case OPENX_FILE_EXISTS_TRUNCATE:
1257 create_disposition = FILE_OVERWRITE;
1258 break;
1260 case OPENX_FILE_EXISTS_TRUNCATE|OPENX_FILE_CREATE_IF_NOT_EXIST:
1261 create_disposition = FILE_OVERWRITE_IF;
1262 break;
1264 default:
1265 /* From samba4 - to be confirmed. */
1266 if (GET_OPENX_MODE(deny_mode) == DOS_OPEN_EXEC) {
1267 create_disposition = FILE_CREATE;
1268 break;
1270 DEBUG(10,("map_open_params_to_ntcreate: bad "
1271 "open_func 0x%x\n", (unsigned int)open_func));
1272 return False;
1275 /* Create the NT compatible share modes. */
1276 switch (GET_DENY_MODE(deny_mode)) {
1277 case DENY_ALL:
1278 share_mode = FILE_SHARE_NONE;
1279 break;
1281 case DENY_WRITE:
1282 share_mode = FILE_SHARE_READ;
1283 break;
1285 case DENY_READ:
1286 share_mode = FILE_SHARE_WRITE;
1287 break;
1289 case DENY_NONE:
1290 share_mode = FILE_SHARE_READ|FILE_SHARE_WRITE;
1291 break;
1293 case DENY_DOS:
1294 create_options |= NTCREATEX_OPTIONS_PRIVATE_DENY_DOS;
1295 if (is_executable(smb_fname->base_name)) {
1296 share_mode = FILE_SHARE_READ|FILE_SHARE_WRITE;
1297 } else {
1298 if (GET_OPENX_MODE(deny_mode) == DOS_OPEN_RDONLY) {
1299 share_mode = FILE_SHARE_READ;
1300 } else {
1301 share_mode = FILE_SHARE_NONE;
1304 break;
1306 case DENY_FCB:
1307 create_options |= NTCREATEX_OPTIONS_PRIVATE_DENY_FCB;
1308 share_mode = FILE_SHARE_NONE;
1309 break;
1311 default:
1312 DEBUG(10,("map_open_params_to_ntcreate: bad deny_mode 0x%x\n",
1313 (unsigned int)GET_DENY_MODE(deny_mode) ));
1314 return False;
1317 DEBUG(10,("map_open_params_to_ntcreate: file %s, access_mask = 0x%x, "
1318 "share_mode = 0x%x, create_disposition = 0x%x, "
1319 "create_options = 0x%x\n",
1320 smb_fname_str_dbg(smb_fname),
1321 (unsigned int)access_mask,
1322 (unsigned int)share_mode,
1323 (unsigned int)create_disposition,
1324 (unsigned int)create_options ));
1326 if (paccess_mask) {
1327 *paccess_mask = access_mask;
1329 if (pshare_mode) {
1330 *pshare_mode = share_mode;
1332 if (pcreate_disposition) {
1333 *pcreate_disposition = create_disposition;
1335 if (pcreate_options) {
1336 *pcreate_options = create_options;
1339 return True;
1343 static void schedule_defer_open(struct share_mode_lock *lck,
1344 struct timeval request_time,
1345 struct smb_request *req)
1347 struct deferred_open_record state;
1349 /* This is a relative time, added to the absolute
1350 request_time value to get the absolute timeout time.
1351 Note that if this is the second or greater time we enter
1352 this codepath for this particular request mid then
1353 request_time is left as the absolute time of the *first*
1354 time this request mid was processed. This is what allows
1355 the request to eventually time out. */
1357 struct timeval timeout;
1359 /* Normally the smbd we asked should respond within
1360 * OPLOCK_BREAK_TIMEOUT seconds regardless of whether
1361 * the client did, give twice the timeout as a safety
1362 * measure here in case the other smbd is stuck
1363 * somewhere else. */
1365 timeout = timeval_set(OPLOCK_BREAK_TIMEOUT*2, 0);
1367 /* Nothing actually uses state.delayed_for_oplocks
1368 but it's handy to differentiate in debug messages
1369 between a 30 second delay due to oplock break, and
1370 a 1 second delay for share mode conflicts. */
1372 state.delayed_for_oplocks = True;
1373 state.id = lck->id;
1375 if (!request_timed_out(request_time, timeout)) {
1376 defer_open(lck, request_time, timeout, req, &state);
1380 /****************************************************************************
1381 Work out what access_mask to use from what the client sent us.
1382 ****************************************************************************/
1384 static NTSTATUS calculate_access_mask(connection_struct *conn,
1385 const struct smb_filename *smb_fname,
1386 bool file_existed,
1387 uint32_t access_mask,
1388 uint32_t *access_mask_out)
1390 NTSTATUS status;
1393 * Convert GENERIC bits to specific bits.
1396 se_map_generic(&access_mask, &file_generic_mapping);
1398 /* Calculate MAXIMUM_ALLOWED_ACCESS if requested. */
1399 if (access_mask & MAXIMUM_ALLOWED_ACCESS) {
1400 if (file_existed) {
1402 struct security_descriptor *sd;
1403 uint32_t access_granted = 0;
1405 status = SMB_VFS_GET_NT_ACL(conn, smb_fname->base_name,
1406 (OWNER_SECURITY_INFORMATION |
1407 GROUP_SECURITY_INFORMATION |
1408 DACL_SECURITY_INFORMATION),&sd);
1410 if (!NT_STATUS_IS_OK(status)) {
1411 DEBUG(10, ("calculate_access_mask: Could not get acl "
1412 "on file %s: %s\n",
1413 smb_fname_str_dbg(smb_fname),
1414 nt_errstr(status)));
1415 return NT_STATUS_ACCESS_DENIED;
1418 status = smb1_file_se_access_check(conn,
1420 conn->server_info->ptok,
1421 access_mask,
1422 &access_granted);
1424 TALLOC_FREE(sd);
1426 if (!NT_STATUS_IS_OK(status)) {
1427 DEBUG(10, ("calculate_access_mask: Access denied on "
1428 "file %s: when calculating maximum access\n",
1429 smb_fname_str_dbg(smb_fname)));
1430 return NT_STATUS_ACCESS_DENIED;
1433 access_mask = access_granted;
1434 } else {
1435 access_mask = FILE_GENERIC_ALL;
1439 *access_mask_out = access_mask;
1440 return NT_STATUS_OK;
1443 /****************************************************************************
1444 Open a file with a share mode. Passed in an already created files_struct *.
1445 ****************************************************************************/
1447 static NTSTATUS open_file_ntcreate(connection_struct *conn,
1448 struct smb_request *req,
1449 uint32 access_mask, /* access bits (FILE_READ_DATA etc.) */
1450 uint32 share_access, /* share constants (FILE_SHARE_READ etc) */
1451 uint32 create_disposition, /* FILE_OPEN_IF etc. */
1452 uint32 create_options, /* options such as delete on close. */
1453 uint32 new_dos_attributes, /* attributes used for new file. */
1454 int oplock_request, /* internal Samba oplock codes. */
1455 /* Information (FILE_EXISTS etc.) */
1456 int *pinfo,
1457 files_struct *fsp)
1459 struct smb_filename *smb_fname = fsp->fsp_name;
1460 int flags=0;
1461 int flags2=0;
1462 bool file_existed = VALID_STAT(smb_fname->st);
1463 bool def_acl = False;
1464 bool posix_open = False;
1465 bool new_file_created = False;
1466 bool clear_ads = false;
1467 struct file_id id;
1468 NTSTATUS fsp_open = NT_STATUS_ACCESS_DENIED;
1469 mode_t new_unx_mode = (mode_t)0;
1470 mode_t unx_mode = (mode_t)0;
1471 int info;
1472 uint32 existing_dos_attributes = 0;
1473 struct pending_message_list *pml = NULL;
1474 struct timeval request_time = timeval_zero();
1475 struct share_mode_lock *lck = NULL;
1476 uint32 open_access_mask = access_mask;
1477 NTSTATUS status;
1478 char *parent_dir;
1480 ZERO_STRUCT(id);
1482 /* Windows allows a new file to be created and
1483 silently removes a FILE_ATTRIBUTE_DIRECTORY
1484 sent by the client. Do the same. */
1486 new_dos_attributes &= ~FILE_ATTRIBUTE_DIRECTORY;
1488 if (conn->printer) {
1490 * Printers are handled completely differently.
1491 * Most of the passed parameters are ignored.
1494 if (pinfo) {
1495 *pinfo = FILE_WAS_CREATED;
1498 DEBUG(10, ("open_file_ntcreate: printer open fname=%s\n",
1499 smb_fname_str_dbg(smb_fname)));
1501 if (!req) {
1502 DEBUG(0,("open_file_ntcreate: printer open without "
1503 "an SMB request!\n"));
1504 return NT_STATUS_INTERNAL_ERROR;
1507 return print_fsp_open(req, conn, smb_fname->base_name,
1508 req->vuid, fsp);
1511 if (!parent_dirname(talloc_tos(), smb_fname->base_name, &parent_dir,
1512 NULL)) {
1513 return NT_STATUS_NO_MEMORY;
1516 if (new_dos_attributes & FILE_FLAG_POSIX_SEMANTICS) {
1517 posix_open = True;
1518 unx_mode = (mode_t)(new_dos_attributes & ~FILE_FLAG_POSIX_SEMANTICS);
1519 new_dos_attributes = 0;
1520 } else {
1521 /* We add aARCH to this as this mode is only used if the file is
1522 * created new. */
1523 unx_mode = unix_mode(conn, new_dos_attributes | aARCH,
1524 smb_fname, parent_dir);
1527 DEBUG(10, ("open_file_ntcreate: fname=%s, dos_attrs=0x%x "
1528 "access_mask=0x%x share_access=0x%x "
1529 "create_disposition = 0x%x create_options=0x%x "
1530 "unix mode=0%o oplock_request=%d\n",
1531 smb_fname_str_dbg(smb_fname), new_dos_attributes,
1532 access_mask, share_access, create_disposition,
1533 create_options, (unsigned int)unx_mode, oplock_request));
1535 if ((req == NULL) && ((oplock_request & INTERNAL_OPEN_ONLY) == 0)) {
1536 DEBUG(0, ("No smb request but not an internal only open!\n"));
1537 return NT_STATUS_INTERNAL_ERROR;
1541 * Only non-internal opens can be deferred at all
1544 if ((req != NULL)
1545 && ((pml = get_open_deferred_message(req->mid)) != NULL)) {
1546 struct deferred_open_record *state =
1547 (struct deferred_open_record *)pml->private_data.data;
1549 /* Remember the absolute time of the original
1550 request with this mid. We'll use it later to
1551 see if this has timed out. */
1553 request_time = pml->request_time;
1555 /* Remove the deferred open entry under lock. */
1556 lck = get_share_mode_lock(talloc_tos(), state->id, NULL, NULL,
1557 NULL);
1558 if (lck == NULL) {
1559 DEBUG(0, ("could not get share mode lock\n"));
1560 } else {
1561 del_deferred_open_entry(lck, req->mid);
1562 TALLOC_FREE(lck);
1565 /* Ensure we don't reprocess this message. */
1566 remove_deferred_open_smb_message(req->mid);
1569 status = check_name(conn, smb_fname->base_name);
1570 if (!NT_STATUS_IS_OK(status)) {
1571 return status;
1574 if (!posix_open) {
1575 new_dos_attributes &= SAMBA_ATTRIBUTES_MASK;
1576 if (file_existed) {
1577 existing_dos_attributes = dos_mode(conn, smb_fname);
1581 /* ignore any oplock requests if oplocks are disabled */
1582 if (!lp_oplocks(SNUM(conn)) || global_client_failed_oplock_break ||
1583 IS_VETO_OPLOCK_PATH(conn, smb_fname->base_name)) {
1584 /* Mask off everything except the private Samba bits. */
1585 oplock_request &= SAMBA_PRIVATE_OPLOCK_MASK;
1588 /* this is for OS/2 long file names - say we don't support them */
1589 if (!lp_posix_pathnames() && strstr(smb_fname->base_name,".+,;=[].")) {
1590 /* OS/2 Workplace shell fix may be main code stream in a later
1591 * release. */
1592 DEBUG(5,("open_file_ntcreate: OS/2 long filenames are not "
1593 "supported.\n"));
1594 if (use_nt_status()) {
1595 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1597 return NT_STATUS_DOS(ERRDOS, ERRcannotopen);
1600 switch( create_disposition ) {
1602 * Currently we're using FILE_SUPERSEDE as the same as
1603 * FILE_OVERWRITE_IF but they really are
1604 * different. FILE_SUPERSEDE deletes an existing file
1605 * (requiring delete access) then recreates it.
1607 case FILE_SUPERSEDE:
1608 /* If file exists replace/overwrite. If file doesn't
1609 * exist create. */
1610 flags2 |= (O_CREAT | O_TRUNC);
1611 clear_ads = true;
1612 break;
1614 case FILE_OVERWRITE_IF:
1615 /* If file exists replace/overwrite. If file doesn't
1616 * exist create. */
1617 flags2 |= (O_CREAT | O_TRUNC);
1618 clear_ads = true;
1619 break;
1621 case FILE_OPEN:
1622 /* If file exists open. If file doesn't exist error. */
1623 if (!file_existed) {
1624 DEBUG(5,("open_file_ntcreate: FILE_OPEN "
1625 "requested for file %s and file "
1626 "doesn't exist.\n",
1627 smb_fname_str_dbg(smb_fname)));
1628 errno = ENOENT;
1629 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1631 break;
1633 case FILE_OVERWRITE:
1634 /* If file exists overwrite. If file doesn't exist
1635 * error. */
1636 if (!file_existed) {
1637 DEBUG(5,("open_file_ntcreate: FILE_OVERWRITE "
1638 "requested for file %s and file "
1639 "doesn't exist.\n",
1640 smb_fname_str_dbg(smb_fname) ));
1641 errno = ENOENT;
1642 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1644 flags2 |= O_TRUNC;
1645 clear_ads = true;
1646 break;
1648 case FILE_CREATE:
1649 /* If file exists error. If file doesn't exist
1650 * create. */
1651 if (file_existed) {
1652 DEBUG(5,("open_file_ntcreate: FILE_CREATE "
1653 "requested for file %s and file "
1654 "already exists.\n",
1655 smb_fname_str_dbg(smb_fname)));
1656 if (S_ISDIR(smb_fname->st.st_ex_mode)) {
1657 errno = EISDIR;
1658 } else {
1659 errno = EEXIST;
1661 return map_nt_error_from_unix(errno);
1663 flags2 |= (O_CREAT|O_EXCL);
1664 break;
1666 case FILE_OPEN_IF:
1667 /* If file exists open. If file doesn't exist
1668 * create. */
1669 flags2 |= O_CREAT;
1670 break;
1672 default:
1673 return NT_STATUS_INVALID_PARAMETER;
1676 /* We only care about matching attributes on file exists and
1677 * overwrite. */
1679 if (!posix_open && file_existed && ((create_disposition == FILE_OVERWRITE) ||
1680 (create_disposition == FILE_OVERWRITE_IF))) {
1681 if (!open_match_attributes(conn, existing_dos_attributes,
1682 new_dos_attributes,
1683 smb_fname->st.st_ex_mode,
1684 unx_mode, &new_unx_mode)) {
1685 DEBUG(5,("open_file_ntcreate: attributes missmatch "
1686 "for file %s (%x %x) (0%o, 0%o)\n",
1687 smb_fname_str_dbg(smb_fname),
1688 existing_dos_attributes,
1689 new_dos_attributes,
1690 (unsigned int)smb_fname->st.st_ex_mode,
1691 (unsigned int)unx_mode ));
1692 errno = EACCES;
1693 return NT_STATUS_ACCESS_DENIED;
1697 status = calculate_access_mask(conn, smb_fname, file_existed,
1698 access_mask,
1699 &access_mask);
1700 if (!NT_STATUS_IS_OK(status)) {
1701 DEBUG(10, ("open_file_ntcreate: calculate_access_mask "
1702 "on file %s returned %s\n",
1703 smb_fname_str_dbg(smb_fname), nt_errstr(status)));
1704 return status;
1707 open_access_mask = access_mask;
1709 if ((flags2 & O_TRUNC) || (oplock_request & FORCE_OPLOCK_BREAK_TO_NONE)) {
1710 open_access_mask |= FILE_WRITE_DATA; /* This will cause oplock breaks. */
1713 DEBUG(10, ("open_file_ntcreate: fname=%s, after mapping "
1714 "access_mask=0x%x\n", smb_fname_str_dbg(smb_fname),
1715 access_mask));
1718 * Note that we ignore the append flag as append does not
1719 * mean the same thing under DOS and Unix.
1722 if ((access_mask & (FILE_WRITE_DATA | FILE_APPEND_DATA)) ||
1723 (oplock_request & FORCE_OPLOCK_BREAK_TO_NONE)) {
1724 /* DENY_DOS opens are always underlying read-write on the
1725 file handle, no matter what the requested access mask
1726 says. */
1727 if ((create_options & NTCREATEX_OPTIONS_PRIVATE_DENY_DOS) ||
1728 access_mask & (FILE_READ_ATTRIBUTES|FILE_READ_DATA|FILE_READ_EA|FILE_EXECUTE)) {
1729 flags = O_RDWR;
1730 } else {
1731 flags = O_WRONLY;
1733 } else {
1734 flags = O_RDONLY;
1738 * Currently we only look at FILE_WRITE_THROUGH for create options.
1741 #if defined(O_SYNC)
1742 if ((create_options & FILE_WRITE_THROUGH) && lp_strict_sync(SNUM(conn))) {
1743 flags2 |= O_SYNC;
1745 #endif /* O_SYNC */
1747 if (posix_open && (access_mask & FILE_APPEND_DATA)) {
1748 flags2 |= O_APPEND;
1751 if (!posix_open && !CAN_WRITE(conn)) {
1753 * We should really return a permission denied error if either
1754 * O_CREAT or O_TRUNC are set, but for compatibility with
1755 * older versions of Samba we just AND them out.
1757 flags2 &= ~(O_CREAT|O_TRUNC);
1761 * Ensure we can't write on a read-only share or file.
1764 if (flags != O_RDONLY && file_existed &&
1765 (!CAN_WRITE(conn) || IS_DOS_READONLY(existing_dos_attributes))) {
1766 DEBUG(5,("open_file_ntcreate: write access requested for "
1767 "file %s on read only %s\n",
1768 smb_fname_str_dbg(smb_fname),
1769 !CAN_WRITE(conn) ? "share" : "file" ));
1770 errno = EACCES;
1771 return NT_STATUS_ACCESS_DENIED;
1774 fsp->file_id = vfs_file_id_from_sbuf(conn, &smb_fname->st);
1775 fsp->share_access = share_access;
1776 fsp->fh->private_options = create_options;
1777 fsp->access_mask = open_access_mask; /* We change this to the
1778 * requested access_mask after
1779 * the open is done. */
1780 fsp->posix_open = posix_open;
1782 /* Ensure no SAMBA_PRIVATE bits can be set. */
1783 fsp->oplock_type = (oplock_request & ~SAMBA_PRIVATE_OPLOCK_MASK);
1785 if (timeval_is_zero(&request_time)) {
1786 request_time = fsp->open_time;
1789 if (file_existed) {
1790 struct timespec old_write_time = smb_fname->st.st_ex_mtime;
1791 id = vfs_file_id_from_sbuf(conn, &smb_fname->st);
1793 lck = get_share_mode_lock(talloc_tos(), id,
1794 conn->connectpath,
1795 smb_fname, &old_write_time);
1797 if (lck == NULL) {
1798 DEBUG(0, ("Could not get share mode lock\n"));
1799 return NT_STATUS_SHARING_VIOLATION;
1802 /* First pass - send break only on batch oplocks. */
1803 if ((req != NULL)
1804 && delay_for_oplocks(lck, fsp, req->mid, 1,
1805 oplock_request)) {
1806 schedule_defer_open(lck, request_time, req);
1807 TALLOC_FREE(lck);
1808 return NT_STATUS_SHARING_VIOLATION;
1811 /* Use the client requested access mask here, not the one we
1812 * open with. */
1813 status = open_mode_check(conn, lck, access_mask, share_access,
1814 create_options, &file_existed);
1816 if (NT_STATUS_IS_OK(status)) {
1817 /* We might be going to allow this open. Check oplock
1818 * status again. */
1819 /* Second pass - send break for both batch or
1820 * exclusive oplocks. */
1821 if ((req != NULL)
1822 && delay_for_oplocks(lck, fsp, req->mid, 2,
1823 oplock_request)) {
1824 schedule_defer_open(lck, request_time, req);
1825 TALLOC_FREE(lck);
1826 return NT_STATUS_SHARING_VIOLATION;
1830 if (NT_STATUS_EQUAL(status, NT_STATUS_DELETE_PENDING)) {
1831 /* DELETE_PENDING is not deferred for a second */
1832 TALLOC_FREE(lck);
1833 return status;
1836 if (!NT_STATUS_IS_OK(status)) {
1837 uint32 can_access_mask;
1838 bool can_access = True;
1840 SMB_ASSERT(NT_STATUS_EQUAL(status, NT_STATUS_SHARING_VIOLATION));
1842 /* Check if this can be done with the deny_dos and fcb
1843 * calls. */
1844 if (create_options &
1845 (NTCREATEX_OPTIONS_PRIVATE_DENY_DOS|
1846 NTCREATEX_OPTIONS_PRIVATE_DENY_FCB)) {
1847 if (req == NULL) {
1848 DEBUG(0, ("DOS open without an SMB "
1849 "request!\n"));
1850 TALLOC_FREE(lck);
1851 return NT_STATUS_INTERNAL_ERROR;
1854 /* Use the client requested access mask here,
1855 * not the one we open with. */
1856 status = fcb_or_dos_open(req,
1857 conn,
1858 fsp,
1859 smb_fname,
1861 req->smbpid,
1862 req->vuid,
1863 access_mask,
1864 share_access,
1865 create_options);
1867 if (NT_STATUS_IS_OK(status)) {
1868 TALLOC_FREE(lck);
1869 if (pinfo) {
1870 *pinfo = FILE_WAS_OPENED;
1872 return NT_STATUS_OK;
1877 * This next line is a subtlety we need for
1878 * MS-Access. If a file open will fail due to share
1879 * permissions and also for security (access) reasons,
1880 * we need to return the access failed error, not the
1881 * share error. We can't open the file due to kernel
1882 * oplock deadlock (it's possible we failed above on
1883 * the open_mode_check()) so use a userspace check.
1886 if (flags & O_RDWR) {
1887 can_access_mask = FILE_READ_DATA|FILE_WRITE_DATA;
1888 } else if (flags & O_WRONLY) {
1889 can_access_mask = FILE_WRITE_DATA;
1890 } else {
1891 can_access_mask = FILE_READ_DATA;
1894 if (((can_access_mask & FILE_WRITE_DATA) &&
1895 !CAN_WRITE(conn)) ||
1896 !can_access_file_data(conn, smb_fname,
1897 can_access_mask)) {
1898 can_access = False;
1902 * If we're returning a share violation, ensure we
1903 * cope with the braindead 1 second delay.
1906 if (!(oplock_request & INTERNAL_OPEN_ONLY) &&
1907 lp_defer_sharing_violations()) {
1908 struct timeval timeout;
1909 struct deferred_open_record state;
1910 int timeout_usecs;
1912 /* this is a hack to speed up torture tests
1913 in 'make test' */
1914 timeout_usecs = lp_parm_int(SNUM(conn),
1915 "smbd","sharedelay",
1916 SHARING_VIOLATION_USEC_WAIT);
1918 /* This is a relative time, added to the absolute
1919 request_time value to get the absolute timeout time.
1920 Note that if this is the second or greater time we enter
1921 this codepath for this particular request mid then
1922 request_time is left as the absolute time of the *first*
1923 time this request mid was processed. This is what allows
1924 the request to eventually time out. */
1926 timeout = timeval_set(0, timeout_usecs);
1928 /* Nothing actually uses state.delayed_for_oplocks
1929 but it's handy to differentiate in debug messages
1930 between a 30 second delay due to oplock break, and
1931 a 1 second delay for share mode conflicts. */
1933 state.delayed_for_oplocks = False;
1934 state.id = id;
1936 if ((req != NULL)
1937 && !request_timed_out(request_time,
1938 timeout)) {
1939 defer_open(lck, request_time, timeout,
1940 req, &state);
1944 TALLOC_FREE(lck);
1945 if (can_access) {
1947 * We have detected a sharing violation here
1948 * so return the correct error code
1950 status = NT_STATUS_SHARING_VIOLATION;
1951 } else {
1952 status = NT_STATUS_ACCESS_DENIED;
1954 return status;
1958 * We exit this block with the share entry *locked*.....
1962 SMB_ASSERT(!file_existed || (lck != NULL));
1965 * Ensure we pay attention to default ACLs on directories if required.
1968 if ((flags2 & O_CREAT) && lp_inherit_acls(SNUM(conn)) &&
1969 (def_acl = directory_has_default_acl(conn, parent_dir))) {
1970 unx_mode = (0777 & lp_create_mask(SNUM(conn)));
1973 DEBUG(4,("calling open_file with flags=0x%X flags2=0x%X mode=0%o, "
1974 "access_mask = 0x%x, open_access_mask = 0x%x\n",
1975 (unsigned int)flags, (unsigned int)flags2,
1976 (unsigned int)unx_mode, (unsigned int)access_mask,
1977 (unsigned int)open_access_mask));
1980 * open_file strips any O_TRUNC flags itself.
1983 fsp_open = open_file(fsp, conn, req, parent_dir,
1984 flags|flags2, unx_mode, access_mask,
1985 open_access_mask);
1987 if (!NT_STATUS_IS_OK(fsp_open)) {
1988 if (lck != NULL) {
1989 TALLOC_FREE(lck);
1991 return fsp_open;
1994 if (!file_existed) {
1995 struct timespec old_write_time = smb_fname->st.st_ex_mtime;
1997 * Deal with the race condition where two smbd's detect the
1998 * file doesn't exist and do the create at the same time. One
1999 * of them will win and set a share mode, the other (ie. this
2000 * one) should check if the requested share mode for this
2001 * create is allowed.
2005 * Now the file exists and fsp is successfully opened,
2006 * fsp->dev and fsp->inode are valid and should replace the
2007 * dev=0,inode=0 from a non existent file. Spotted by
2008 * Nadav Danieli <nadavd@exanet.com>. JRA.
2011 id = fsp->file_id;
2013 lck = get_share_mode_lock(talloc_tos(), id,
2014 conn->connectpath,
2015 smb_fname, &old_write_time);
2017 if (lck == NULL) {
2018 DEBUG(0, ("open_file_ntcreate: Could not get share "
2019 "mode lock for %s\n",
2020 smb_fname_str_dbg(smb_fname)));
2021 fd_close(fsp);
2022 return NT_STATUS_SHARING_VIOLATION;
2025 /* First pass - send break only on batch oplocks. */
2026 if ((req != NULL)
2027 && delay_for_oplocks(lck, fsp, req->mid, 1,
2028 oplock_request)) {
2029 schedule_defer_open(lck, request_time, req);
2030 TALLOC_FREE(lck);
2031 fd_close(fsp);
2032 return NT_STATUS_SHARING_VIOLATION;
2035 status = open_mode_check(conn, lck, access_mask, share_access,
2036 create_options, &file_existed);
2038 if (NT_STATUS_IS_OK(status)) {
2039 /* We might be going to allow this open. Check oplock
2040 * status again. */
2041 /* Second pass - send break for both batch or
2042 * exclusive oplocks. */
2043 if ((req != NULL)
2044 && delay_for_oplocks(lck, fsp, req->mid, 2,
2045 oplock_request)) {
2046 schedule_defer_open(lck, request_time, req);
2047 TALLOC_FREE(lck);
2048 fd_close(fsp);
2049 return NT_STATUS_SHARING_VIOLATION;
2053 if (!NT_STATUS_IS_OK(status)) {
2054 struct deferred_open_record state;
2056 fd_close(fsp);
2058 state.delayed_for_oplocks = False;
2059 state.id = id;
2061 /* Do it all over again immediately. In the second
2062 * round we will find that the file existed and handle
2063 * the DELETE_PENDING and FCB cases correctly. No need
2064 * to duplicate the code here. Essentially this is a
2065 * "goto top of this function", but don't tell
2066 * anybody... */
2068 if (req != NULL) {
2069 defer_open(lck, request_time, timeval_zero(),
2070 req, &state);
2072 TALLOC_FREE(lck);
2073 return status;
2077 * We exit this block with the share entry *locked*.....
2082 SMB_ASSERT(lck != NULL);
2084 /* Delete streams if create_disposition requires it */
2085 if (file_existed && clear_ads &&
2086 !is_ntfs_stream_smb_fname(smb_fname)) {
2087 status = delete_all_streams(conn, smb_fname->base_name);
2088 if (!NT_STATUS_IS_OK(status)) {
2089 TALLOC_FREE(lck);
2090 fd_close(fsp);
2091 return status;
2095 /* note that we ignore failure for the following. It is
2096 basically a hack for NFS, and NFS will never set one of
2097 these only read them. Nobody but Samba can ever set a deny
2098 mode and we have already checked our more authoritative
2099 locking database for permission to set this deny mode. If
2100 the kernel refuses the operations then the kernel is wrong.
2101 note that GPFS supports it as well - jmcd */
2103 if (fsp->fh->fd != -1) {
2104 int ret_flock;
2105 ret_flock = SMB_VFS_KERNEL_FLOCK(fsp, share_access, access_mask);
2106 if(ret_flock == -1 ){
2108 TALLOC_FREE(lck);
2109 fd_close(fsp);
2111 return NT_STATUS_SHARING_VIOLATION;
2116 * At this point onwards, we can guarentee that the share entry
2117 * is locked, whether we created the file or not, and that the
2118 * deny mode is compatible with all current opens.
2122 * If requested, truncate the file.
2125 if (flags2&O_TRUNC) {
2127 * We are modifing the file after open - update the stat
2128 * struct..
2130 if ((SMB_VFS_FTRUNCATE(fsp, 0) == -1) ||
2131 (SMB_VFS_FSTAT(fsp, &smb_fname->st)==-1)) {
2132 status = map_nt_error_from_unix(errno);
2133 TALLOC_FREE(lck);
2134 fd_close(fsp);
2135 return status;
2139 /* Record the options we were opened with. */
2140 fsp->share_access = share_access;
2141 fsp->fh->private_options = create_options;
2143 * According to Samba4, SEC_FILE_READ_ATTRIBUTE is always granted,
2145 fsp->access_mask = access_mask | FILE_READ_ATTRIBUTES;
2147 if (file_existed) {
2148 /* stat opens on existing files don't get oplocks. */
2149 if (is_stat_open(open_access_mask)) {
2150 fsp->oplock_type = NO_OPLOCK;
2153 if (!(flags2 & O_TRUNC)) {
2154 info = FILE_WAS_OPENED;
2155 } else {
2156 info = FILE_WAS_OVERWRITTEN;
2158 } else {
2159 info = FILE_WAS_CREATED;
2162 if (pinfo) {
2163 *pinfo = info;
2167 * Setup the oplock info in both the shared memory and
2168 * file structs.
2171 if (!set_file_oplock(fsp, fsp->oplock_type)) {
2172 /* Could not get the kernel oplock */
2173 fsp->oplock_type = NO_OPLOCK;
2176 if (info == FILE_WAS_OVERWRITTEN || info == FILE_WAS_CREATED || info == FILE_WAS_SUPERSEDED) {
2177 new_file_created = True;
2180 set_share_mode(lck, fsp, conn->server_info->utok.uid, 0,
2181 fsp->oplock_type);
2183 /* Handle strange delete on close create semantics. */
2184 if (create_options & FILE_DELETE_ON_CLOSE) {
2186 status = can_set_delete_on_close(fsp, new_dos_attributes);
2188 if (!NT_STATUS_IS_OK(status)) {
2189 /* Remember to delete the mode we just added. */
2190 del_share_mode(lck, fsp);
2191 TALLOC_FREE(lck);
2192 fd_close(fsp);
2193 return status;
2195 /* Note that here we set the *inital* delete on close flag,
2196 not the regular one. The magic gets handled in close. */
2197 fsp->initial_delete_on_close = True;
2200 if (new_file_created) {
2201 /* Files should be initially set as archive */
2202 if (lp_map_archive(SNUM(conn)) ||
2203 lp_store_dos_attributes(SNUM(conn))) {
2204 if (!posix_open) {
2205 if (file_set_dosmode(conn, smb_fname,
2206 new_dos_attributes | aARCH,
2207 parent_dir, true) == 0) {
2208 unx_mode = smb_fname->st.st_ex_mode;
2215 * Take care of inherited ACLs on created files - if default ACL not
2216 * selected.
2219 if (!posix_open && !file_existed && !def_acl) {
2221 int saved_errno = errno; /* We might get ENOSYS in the next
2222 * call.. */
2224 if (SMB_VFS_FCHMOD_ACL(fsp, unx_mode) == -1 &&
2225 errno == ENOSYS) {
2226 errno = saved_errno; /* Ignore ENOSYS */
2229 } else if (new_unx_mode) {
2231 int ret = -1;
2233 /* Attributes need changing. File already existed. */
2236 int saved_errno = errno; /* We might get ENOSYS in the
2237 * next call.. */
2238 ret = SMB_VFS_FCHMOD_ACL(fsp, new_unx_mode);
2240 if (ret == -1 && errno == ENOSYS) {
2241 errno = saved_errno; /* Ignore ENOSYS */
2242 } else {
2243 DEBUG(5, ("open_file_ntcreate: reset "
2244 "attributes of file %s to 0%o\n",
2245 smb_fname_str_dbg(smb_fname),
2246 (unsigned int)new_unx_mode));
2247 ret = 0; /* Don't do the fchmod below. */
2251 if ((ret == -1) &&
2252 (SMB_VFS_FCHMOD(fsp, new_unx_mode) == -1))
2253 DEBUG(5, ("open_file_ntcreate: failed to reset "
2254 "attributes of file %s to 0%o\n",
2255 smb_fname_str_dbg(smb_fname),
2256 (unsigned int)new_unx_mode));
2259 /* If this is a successful open, we must remove any deferred open
2260 * records. */
2261 if (req != NULL) {
2262 del_deferred_open_entry(lck, req->mid);
2264 TALLOC_FREE(lck);
2266 return NT_STATUS_OK;
2270 /****************************************************************************
2271 Open a file for for write to ensure that we can fchmod it.
2272 ****************************************************************************/
2274 NTSTATUS open_file_fchmod(connection_struct *conn,
2275 struct smb_filename *smb_fname,
2276 files_struct **result)
2278 if (!VALID_STAT(smb_fname->st)) {
2279 return NT_STATUS_INVALID_PARAMETER;
2282 return SMB_VFS_CREATE_FILE(
2283 conn, /* conn */
2284 NULL, /* req */
2285 0, /* root_dir_fid */
2286 smb_fname, /* fname */
2287 FILE_WRITE_DATA, /* access_mask */
2288 (FILE_SHARE_READ | FILE_SHARE_WRITE | /* share_access */
2289 FILE_SHARE_DELETE),
2290 FILE_OPEN, /* create_disposition*/
2291 0, /* create_options */
2292 0, /* file_attributes */
2293 INTERNAL_OPEN_ONLY, /* oplock_request */
2294 0, /* allocation_size */
2295 NULL, /* sd */
2296 NULL, /* ea_list */
2297 result, /* result */
2298 NULL); /* pinfo */
2301 static NTSTATUS mkdir_internal(connection_struct *conn,
2302 struct smb_filename *smb_dname,
2303 uint32 file_attributes)
2305 mode_t mode;
2306 char *parent_dir;
2307 NTSTATUS status;
2308 bool posix_open = false;
2310 if(!CAN_WRITE(conn)) {
2311 DEBUG(5,("mkdir_internal: failing create on read-only share "
2312 "%s\n", lp_servicename(SNUM(conn))));
2313 return NT_STATUS_ACCESS_DENIED;
2316 status = check_name(conn, smb_dname->base_name);
2317 if (!NT_STATUS_IS_OK(status)) {
2318 return status;
2321 if (!parent_dirname(talloc_tos(), smb_dname->base_name, &parent_dir,
2322 NULL)) {
2323 return NT_STATUS_NO_MEMORY;
2326 if (file_attributes & FILE_FLAG_POSIX_SEMANTICS) {
2327 posix_open = true;
2328 mode = (mode_t)(file_attributes & ~FILE_FLAG_POSIX_SEMANTICS);
2329 } else {
2330 mode = unix_mode(conn, aDIR, smb_dname, parent_dir);
2333 if (SMB_VFS_MKDIR(conn, smb_dname->base_name, mode) != 0) {
2334 return map_nt_error_from_unix(errno);
2337 /* Ensure we're checking for a symlink here.... */
2338 /* We don't want to get caught by a symlink racer. */
2340 if (SMB_VFS_LSTAT(conn, smb_dname) == -1) {
2341 DEBUG(2, ("Could not stat directory '%s' just created: %s\n",
2342 smb_fname_str_dbg(smb_dname), strerror(errno)));
2343 return map_nt_error_from_unix(errno);
2346 if (!S_ISDIR(smb_dname->st.st_ex_mode)) {
2347 DEBUG(0, ("Directory just '%s' created is not a directory\n",
2348 smb_fname_str_dbg(smb_dname)));
2349 return NT_STATUS_ACCESS_DENIED;
2352 if (lp_store_dos_attributes(SNUM(conn))) {
2353 if (!posix_open) {
2354 file_set_dosmode(conn, smb_dname,
2355 file_attributes | aDIR,
2356 parent_dir, true);
2360 if (lp_inherit_perms(SNUM(conn))) {
2361 inherit_access_posix_acl(conn, parent_dir,
2362 smb_dname->base_name, mode);
2365 if (!posix_open) {
2367 * Check if high bits should have been set,
2368 * then (if bits are missing): add them.
2369 * Consider bits automagically set by UNIX, i.e. SGID bit from parent
2370 * dir.
2372 if ((mode & ~(S_IRWXU|S_IRWXG|S_IRWXO)) &&
2373 (mode & ~smb_dname->st.st_ex_mode)) {
2374 SMB_VFS_CHMOD(conn, smb_dname->base_name,
2375 (smb_dname->st.st_ex_mode |
2376 (mode & ~smb_dname->st.st_ex_mode)));
2380 /* Change the owner if required. */
2381 if (lp_inherit_owner(SNUM(conn))) {
2382 change_dir_owner_to_parent(conn, parent_dir,
2383 smb_dname->base_name,
2384 &smb_dname->st);
2387 notify_fname(conn, NOTIFY_ACTION_ADDED, FILE_NOTIFY_CHANGE_DIR_NAME,
2388 smb_dname->base_name);
2390 return NT_STATUS_OK;
2393 /****************************************************************************
2394 Open a directory from an NT SMB call.
2395 ****************************************************************************/
2397 static NTSTATUS open_directory(connection_struct *conn,
2398 struct smb_request *req,
2399 struct smb_filename *smb_dname,
2400 uint32 access_mask,
2401 uint32 share_access,
2402 uint32 create_disposition,
2403 uint32 create_options,
2404 uint32 file_attributes,
2405 int *pinfo,
2406 files_struct **result)
2408 files_struct *fsp = NULL;
2409 bool dir_existed = VALID_STAT(smb_dname->st) ? True : False;
2410 struct share_mode_lock *lck = NULL;
2411 NTSTATUS status;
2412 struct timespec mtimespec;
2413 int info = 0;
2415 SMB_ASSERT(!is_ntfs_stream_smb_fname(smb_dname));
2417 /* Ensure we have a directory attribute. */
2418 file_attributes |= FILE_ATTRIBUTE_DIRECTORY;
2420 DEBUG(5,("open_directory: opening directory %s, access_mask = 0x%x, "
2421 "share_access = 0x%x create_options = 0x%x, "
2422 "create_disposition = 0x%x, file_attributes = 0x%x\n",
2423 smb_fname_str_dbg(smb_dname),
2424 (unsigned int)access_mask,
2425 (unsigned int)share_access,
2426 (unsigned int)create_options,
2427 (unsigned int)create_disposition,
2428 (unsigned int)file_attributes));
2430 if (!(file_attributes & FILE_FLAG_POSIX_SEMANTICS) &&
2431 (conn->fs_capabilities & FILE_NAMED_STREAMS) &&
2432 is_ntfs_stream_smb_fname(smb_dname)) {
2433 DEBUG(2, ("open_directory: %s is a stream name!\n",
2434 smb_fname_str_dbg(smb_dname)));
2435 return NT_STATUS_NOT_A_DIRECTORY;
2438 status = calculate_access_mask(conn, smb_dname, dir_existed,
2439 access_mask, &access_mask);
2440 if (!NT_STATUS_IS_OK(status)) {
2441 DEBUG(10, ("open_directory: calculate_access_mask "
2442 "on file %s returned %s\n",
2443 smb_fname_str_dbg(smb_dname),
2444 nt_errstr(status)));
2445 return status;
2448 if ((access_mask & SEC_FLAG_SYSTEM_SECURITY) &&
2449 !user_has_privileges(current_user.nt_user_token, &se_security)) {
2450 DEBUG(10, ("open_directory: open on %s "
2451 "failed - SEC_FLAG_SYSTEM_SECURITY denied.\n",
2452 smb_fname_str_dbg(smb_dname)));
2453 return NT_STATUS_PRIVILEGE_NOT_HELD;
2456 switch( create_disposition ) {
2457 case FILE_OPEN:
2459 info = FILE_WAS_OPENED;
2462 * We want to follow symlinks here.
2465 if (SMB_VFS_STAT(conn, smb_dname) != 0) {
2466 return map_nt_error_from_unix(errno);
2469 break;
2471 case FILE_CREATE:
2473 /* If directory exists error. If directory doesn't
2474 * exist create. */
2476 status = mkdir_internal(conn, smb_dname,
2477 file_attributes);
2479 if (!NT_STATUS_IS_OK(status)) {
2480 DEBUG(2, ("open_directory: unable to create "
2481 "%s. Error was %s\n",
2482 smb_fname_str_dbg(smb_dname),
2483 nt_errstr(status)));
2484 return status;
2487 info = FILE_WAS_CREATED;
2488 break;
2490 case FILE_OPEN_IF:
2492 * If directory exists open. If directory doesn't
2493 * exist create.
2496 status = mkdir_internal(conn, smb_dname,
2497 file_attributes);
2499 if (NT_STATUS_IS_OK(status)) {
2500 info = FILE_WAS_CREATED;
2503 if (NT_STATUS_EQUAL(status,
2504 NT_STATUS_OBJECT_NAME_COLLISION)) {
2505 info = FILE_WAS_OPENED;
2506 status = NT_STATUS_OK;
2509 break;
2511 case FILE_SUPERSEDE:
2512 case FILE_OVERWRITE:
2513 case FILE_OVERWRITE_IF:
2514 default:
2515 DEBUG(5,("open_directory: invalid create_disposition "
2516 "0x%x for directory %s\n",
2517 (unsigned int)create_disposition,
2518 smb_fname_str_dbg(smb_dname)));
2519 return NT_STATUS_INVALID_PARAMETER;
2522 if(!S_ISDIR(smb_dname->st.st_ex_mode)) {
2523 DEBUG(5,("open_directory: %s is not a directory !\n",
2524 smb_fname_str_dbg(smb_dname)));
2525 return NT_STATUS_NOT_A_DIRECTORY;
2528 if (info == FILE_WAS_OPENED) {
2529 uint32_t access_granted = 0;
2530 status = smbd_check_open_rights(conn, smb_dname, access_mask,
2531 &access_granted);
2533 /* Were we trying to do a directory open
2534 * for delete and didn't get DELETE
2535 * access (only) ? Check if the
2536 * directory allows DELETE_CHILD.
2537 * See here:
2538 * http://blogs.msdn.com/oldnewthing/archive/2004/06/04/148426.aspx
2539 * for details. */
2541 if ((NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED) &&
2542 (access_mask & DELETE_ACCESS) &&
2543 (access_granted == DELETE_ACCESS) &&
2544 can_delete_file_in_directory(conn, smb_dname))) {
2545 DEBUG(10,("open_directory: overrode ACCESS_DENIED "
2546 "on directory %s\n",
2547 smb_fname_str_dbg(smb_dname)));
2548 status = NT_STATUS_OK;
2551 if (!NT_STATUS_IS_OK(status)) {
2552 DEBUG(10, ("open_directory: smbd_check_open_rights on "
2553 "file %s failed with %s\n",
2554 smb_fname_str_dbg(smb_dname),
2555 nt_errstr(status)));
2556 return status;
2560 status = file_new(req, conn, &fsp);
2561 if(!NT_STATUS_IS_OK(status)) {
2562 return status;
2566 * Setup the files_struct for it.
2569 fsp->mode = smb_dname->st.st_ex_mode;
2570 fsp->file_id = vfs_file_id_from_sbuf(conn, &smb_dname->st);
2571 fsp->vuid = req ? req->vuid : UID_FIELD_INVALID;
2572 fsp->file_pid = req ? req->smbpid : 0;
2573 fsp->can_lock = False;
2574 fsp->can_read = False;
2575 fsp->can_write = False;
2577 fsp->share_access = share_access;
2578 fsp->fh->private_options = create_options;
2580 * According to Samba4, SEC_FILE_READ_ATTRIBUTE is always granted,
2582 fsp->access_mask = access_mask | FILE_READ_ATTRIBUTES;
2583 fsp->print_file = False;
2584 fsp->modified = False;
2585 fsp->oplock_type = NO_OPLOCK;
2586 fsp->sent_oplock_break = NO_BREAK_SENT;
2587 fsp->is_directory = True;
2588 fsp->posix_open = (file_attributes & FILE_FLAG_POSIX_SEMANTICS) ? True : False;
2589 status = fsp_set_smb_fname(fsp, smb_dname);
2590 if (!NT_STATUS_IS_OK(status)) {
2591 return status;
2594 mtimespec = smb_dname->st.st_ex_mtime;
2596 lck = get_share_mode_lock(talloc_tos(), fsp->file_id,
2597 conn->connectpath, smb_dname, &mtimespec);
2599 if (lck == NULL) {
2600 DEBUG(0, ("open_directory: Could not get share mode lock for "
2601 "%s\n", smb_fname_str_dbg(smb_dname)));
2602 file_free(req, fsp);
2603 return NT_STATUS_SHARING_VIOLATION;
2606 status = open_mode_check(conn, lck, access_mask, share_access,
2607 create_options, &dir_existed);
2609 if (!NT_STATUS_IS_OK(status)) {
2610 TALLOC_FREE(lck);
2611 file_free(req, fsp);
2612 return status;
2615 set_share_mode(lck, fsp, conn->server_info->utok.uid, 0, NO_OPLOCK);
2617 /* For directories the delete on close bit at open time seems
2618 always to be honored on close... See test 19 in Samba4 BASE-DELETE. */
2619 if (create_options & FILE_DELETE_ON_CLOSE) {
2620 status = can_set_delete_on_close(fsp, 0);
2621 if (!NT_STATUS_IS_OK(status) && !NT_STATUS_EQUAL(status, NT_STATUS_DIRECTORY_NOT_EMPTY)) {
2622 TALLOC_FREE(lck);
2623 file_free(req, fsp);
2624 return status;
2627 if (NT_STATUS_IS_OK(status)) {
2628 /* Note that here we set the *inital* delete on close flag,
2629 not the regular one. The magic gets handled in close. */
2630 fsp->initial_delete_on_close = True;
2634 TALLOC_FREE(lck);
2636 if (pinfo) {
2637 *pinfo = info;
2640 *result = fsp;
2641 return NT_STATUS_OK;
2644 NTSTATUS create_directory(connection_struct *conn, struct smb_request *req,
2645 struct smb_filename *smb_dname)
2647 NTSTATUS status;
2648 files_struct *fsp;
2650 status = SMB_VFS_CREATE_FILE(
2651 conn, /* conn */
2652 req, /* req */
2653 0, /* root_dir_fid */
2654 smb_dname, /* fname */
2655 FILE_READ_ATTRIBUTES, /* access_mask */
2656 FILE_SHARE_NONE, /* share_access */
2657 FILE_CREATE, /* create_disposition*/
2658 FILE_DIRECTORY_FILE, /* create_options */
2659 FILE_ATTRIBUTE_DIRECTORY, /* file_attributes */
2660 0, /* oplock_request */
2661 0, /* allocation_size */
2662 NULL, /* sd */
2663 NULL, /* ea_list */
2664 &fsp, /* result */
2665 NULL); /* pinfo */
2667 if (NT_STATUS_IS_OK(status)) {
2668 close_file(req, fsp, NORMAL_CLOSE);
2671 return status;
2674 /****************************************************************************
2675 Receive notification that one of our open files has been renamed by another
2676 smbd process.
2677 ****************************************************************************/
2679 void msg_file_was_renamed(struct messaging_context *msg,
2680 void *private_data,
2681 uint32_t msg_type,
2682 struct server_id server_id,
2683 DATA_BLOB *data)
2685 files_struct *fsp;
2686 char *frm = (char *)data->data;
2687 struct file_id id;
2688 const char *sharepath;
2689 const char *base_name;
2690 const char *stream_name;
2691 struct smb_filename *smb_fname = NULL;
2692 size_t sp_len, bn_len;
2693 NTSTATUS status;
2695 if (data->data == NULL
2696 || data->length < MSG_FILE_RENAMED_MIN_SIZE + 2) {
2697 DEBUG(0, ("msg_file_was_renamed: Got invalid msg len %d\n",
2698 (int)data->length));
2699 return;
2702 /* Unpack the message. */
2703 pull_file_id_24(frm, &id);
2704 sharepath = &frm[24];
2705 sp_len = strlen(sharepath);
2706 base_name = sharepath + sp_len + 1;
2707 bn_len = strlen(base_name);
2708 stream_name = sharepath + sp_len + 1 + bn_len + 1;
2710 /* stream_name must always be NULL if there is no stream. */
2711 if (stream_name[0] == '\0') {
2712 stream_name = NULL;
2715 status = create_synthetic_smb_fname(talloc_tos(), base_name,
2716 stream_name, NULL, &smb_fname);
2717 if (!NT_STATUS_IS_OK(status)) {
2718 return;
2721 DEBUG(10,("msg_file_was_renamed: Got rename message for sharepath %s, new name %s, "
2722 "file_id %s\n",
2723 sharepath, smb_fname_str_dbg(smb_fname),
2724 file_id_string_tos(&id)));
2726 for(fsp = file_find_di_first(id); fsp; fsp = file_find_di_next(fsp)) {
2727 if (memcmp(fsp->conn->connectpath, sharepath, sp_len) == 0) {
2729 DEBUG(10,("msg_file_was_renamed: renaming file fnum %d from %s -> %s\n",
2730 fsp->fnum, fsp_str_dbg(fsp),
2731 smb_fname_str_dbg(smb_fname)));
2732 status = fsp_set_smb_fname(fsp, smb_fname);
2733 if (!NT_STATUS_IS_OK(status)) {
2734 goto out;
2736 } else {
2737 /* TODO. JRA. */
2738 /* Now we have the complete path we can work out if this is
2739 actually within this share and adjust newname accordingly. */
2740 DEBUG(10,("msg_file_was_renamed: share mismatch (sharepath %s "
2741 "not sharepath %s) "
2742 "fnum %d from %s -> %s\n",
2743 fsp->conn->connectpath,
2744 sharepath,
2745 fsp->fnum,
2746 fsp_str_dbg(fsp),
2747 smb_fname_str_dbg(smb_fname)));
2750 out:
2751 TALLOC_FREE(smb_fname);
2752 return;
2756 * If a main file is opened for delete, all streams need to be checked for
2757 * !FILE_SHARE_DELETE. Do this by opening with DELETE_ACCESS.
2758 * If that works, delete them all by setting the delete on close and close.
2761 NTSTATUS open_streams_for_delete(connection_struct *conn,
2762 const char *fname)
2764 struct stream_struct *stream_info;
2765 files_struct **streams;
2766 int i;
2767 unsigned int num_streams;
2768 TALLOC_CTX *frame = talloc_stackframe();
2769 NTSTATUS status;
2771 status = SMB_VFS_STREAMINFO(conn, NULL, fname, talloc_tos(),
2772 &num_streams, &stream_info);
2774 if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_IMPLEMENTED)
2775 || NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
2776 DEBUG(10, ("no streams around\n"));
2777 TALLOC_FREE(frame);
2778 return NT_STATUS_OK;
2781 if (!NT_STATUS_IS_OK(status)) {
2782 DEBUG(10, ("SMB_VFS_STREAMINFO failed: %s\n",
2783 nt_errstr(status)));
2784 goto fail;
2787 DEBUG(10, ("open_streams_for_delete found %d streams\n",
2788 num_streams));
2790 if (num_streams == 0) {
2791 TALLOC_FREE(frame);
2792 return NT_STATUS_OK;
2795 streams = TALLOC_ARRAY(talloc_tos(), files_struct *, num_streams);
2796 if (streams == NULL) {
2797 DEBUG(0, ("talloc failed\n"));
2798 status = NT_STATUS_NO_MEMORY;
2799 goto fail;
2802 for (i=0; i<num_streams; i++) {
2803 struct smb_filename *smb_fname = NULL;
2805 if (strequal(stream_info[i].name, "::$DATA")) {
2806 streams[i] = NULL;
2807 continue;
2810 status = create_synthetic_smb_fname(talloc_tos(), fname,
2811 stream_info[i].name,
2812 NULL, &smb_fname);
2813 if (!NT_STATUS_IS_OK(status)) {
2814 goto fail;
2817 if (SMB_VFS_STAT(conn, smb_fname) == -1) {
2818 DEBUG(10, ("Unable to stat stream: %s\n",
2819 smb_fname_str_dbg(smb_fname)));
2822 status = SMB_VFS_CREATE_FILE(
2823 conn, /* conn */
2824 NULL, /* req */
2825 0, /* root_dir_fid */
2826 smb_fname, /* fname */
2827 DELETE_ACCESS, /* access_mask */
2828 (FILE_SHARE_READ | /* share_access */
2829 FILE_SHARE_WRITE | FILE_SHARE_DELETE),
2830 FILE_OPEN, /* create_disposition*/
2831 NTCREATEX_OPTIONS_PRIVATE_STREAM_DELETE, /* create_options */
2832 FILE_ATTRIBUTE_NORMAL, /* file_attributes */
2833 0, /* oplock_request */
2834 0, /* allocation_size */
2835 NULL, /* sd */
2836 NULL, /* ea_list */
2837 &streams[i], /* result */
2838 NULL); /* pinfo */
2840 if (!NT_STATUS_IS_OK(status)) {
2841 DEBUG(10, ("Could not open stream %s: %s\n",
2842 smb_fname_str_dbg(smb_fname),
2843 nt_errstr(status)));
2845 TALLOC_FREE(smb_fname);
2846 break;
2848 TALLOC_FREE(smb_fname);
2852 * don't touch the variable "status" beyond this point :-)
2855 for (i -= 1 ; i >= 0; i--) {
2856 if (streams[i] == NULL) {
2857 continue;
2860 DEBUG(10, ("Closing stream # %d, %s\n", i,
2861 fsp_str_dbg(streams[i])));
2862 close_file(NULL, streams[i], NORMAL_CLOSE);
2865 fail:
2866 TALLOC_FREE(frame);
2867 return status;
2871 * Wrapper around open_file_ntcreate and open_directory
2874 static NTSTATUS create_file_unixpath(connection_struct *conn,
2875 struct smb_request *req,
2876 struct smb_filename *smb_fname,
2877 uint32_t access_mask,
2878 uint32_t share_access,
2879 uint32_t create_disposition,
2880 uint32_t create_options,
2881 uint32_t file_attributes,
2882 uint32_t oplock_request,
2883 uint64_t allocation_size,
2884 struct security_descriptor *sd,
2885 struct ea_list *ea_list,
2887 files_struct **result,
2888 int *pinfo)
2890 int info = FILE_WAS_OPENED;
2891 files_struct *base_fsp = NULL;
2892 files_struct *fsp = NULL;
2893 NTSTATUS status;
2895 DEBUG(10,("create_file_unixpath: access_mask = 0x%x "
2896 "file_attributes = 0x%x, share_access = 0x%x, "
2897 "create_disposition = 0x%x create_options = 0x%x "
2898 "oplock_request = 0x%x ea_list = 0x%p, sd = 0x%p, "
2899 "fname = %s\n",
2900 (unsigned int)access_mask,
2901 (unsigned int)file_attributes,
2902 (unsigned int)share_access,
2903 (unsigned int)create_disposition,
2904 (unsigned int)create_options,
2905 (unsigned int)oplock_request,
2906 ea_list, sd, smb_fname_str_dbg(smb_fname)));
2908 if (create_options & FILE_OPEN_BY_FILE_ID) {
2909 status = NT_STATUS_NOT_SUPPORTED;
2910 goto fail;
2913 if (create_options & NTCREATEX_OPTIONS_INVALID_PARAM_MASK) {
2914 status = NT_STATUS_INVALID_PARAMETER;
2915 goto fail;
2918 if (req == NULL) {
2919 oplock_request |= INTERNAL_OPEN_ONLY;
2922 if ((conn->fs_capabilities & FILE_NAMED_STREAMS)
2923 && (access_mask & DELETE_ACCESS)
2924 && !is_ntfs_stream_smb_fname(smb_fname)) {
2926 * We can't open a file with DELETE access if any of the
2927 * streams is open without FILE_SHARE_DELETE
2929 status = open_streams_for_delete(conn, smb_fname->base_name);
2931 if (!NT_STATUS_IS_OK(status)) {
2932 goto fail;
2936 /* This is the correct thing to do (check every time) but can_delete
2937 * is expensive (it may have to read the parent directory
2938 * permissions). So for now we're not doing it unless we have a strong
2939 * hint the client is really going to delete this file. If the client
2940 * is forcing FILE_CREATE let the filesystem take care of the
2941 * permissions. */
2943 /* Setting FILE_SHARE_DELETE is the hint. */
2945 if (lp_acl_check_permissions(SNUM(conn))
2946 && (create_disposition != FILE_CREATE)
2947 && (share_access & FILE_SHARE_DELETE)
2948 && (access_mask & DELETE_ACCESS)
2949 && (!(can_delete_file_in_directory(conn, smb_fname) ||
2950 can_access_file_acl(conn, smb_fname, DELETE_ACCESS)))) {
2951 status = NT_STATUS_ACCESS_DENIED;
2952 DEBUG(10,("create_file_unixpath: open file %s "
2953 "for delete ACCESS_DENIED\n",
2954 smb_fname_str_dbg(smb_fname)));
2955 goto fail;
2958 if ((access_mask & SEC_FLAG_SYSTEM_SECURITY) &&
2959 !user_has_privileges(current_user.nt_user_token, &se_security)) {
2960 DEBUG(10, ("create_file_unixpath:: open on %s "
2961 "failed - SEC_FLAG_SYSTEM_SECURITY denied.\n",
2962 smb_fname_str_dbg(smb_fname)));
2963 status = NT_STATUS_PRIVILEGE_NOT_HELD;
2964 goto fail;
2967 if ((conn->fs_capabilities & FILE_NAMED_STREAMS)
2968 && is_ntfs_stream_smb_fname(smb_fname)
2969 && (!(create_options & NTCREATEX_OPTIONS_PRIVATE_STREAM_DELETE))) {
2970 uint32 base_create_disposition;
2971 struct smb_filename *smb_fname_base = NULL;
2973 if (create_options & FILE_DIRECTORY_FILE) {
2974 status = NT_STATUS_NOT_A_DIRECTORY;
2975 goto fail;
2978 switch (create_disposition) {
2979 case FILE_OPEN:
2980 base_create_disposition = FILE_OPEN;
2981 break;
2982 default:
2983 base_create_disposition = FILE_OPEN_IF;
2984 break;
2987 /* Create an smb_filename with stream_name == NULL. */
2988 status = create_synthetic_smb_fname(talloc_tos(),
2989 smb_fname->base_name,
2990 NULL, NULL,
2991 &smb_fname_base);
2992 if (!NT_STATUS_IS_OK(status)) {
2993 goto fail;
2996 if (SMB_VFS_STAT(conn, smb_fname_base) == -1) {
2997 DEBUG(10, ("Unable to stat stream: %s\n",
2998 smb_fname_str_dbg(smb_fname_base)));
3001 /* Open the base file. */
3002 status = create_file_unixpath(conn, NULL, smb_fname_base, 0,
3003 FILE_SHARE_READ
3004 | FILE_SHARE_WRITE
3005 | FILE_SHARE_DELETE,
3006 base_create_disposition,
3007 0, 0, 0, 0, NULL, NULL,
3008 &base_fsp, NULL);
3009 TALLOC_FREE(smb_fname_base);
3011 if (!NT_STATUS_IS_OK(status)) {
3012 DEBUG(10, ("create_file_unixpath for base %s failed: "
3013 "%s\n", smb_fname->base_name,
3014 nt_errstr(status)));
3015 goto fail;
3017 /* we don't need to low level fd */
3018 fd_close(base_fsp);
3022 * If it's a request for a directory open, deal with it separately.
3025 if (create_options & FILE_DIRECTORY_FILE) {
3027 if (create_options & FILE_NON_DIRECTORY_FILE) {
3028 status = NT_STATUS_INVALID_PARAMETER;
3029 goto fail;
3032 /* Can't open a temp directory. IFS kit test. */
3033 if (!(file_attributes & FILE_FLAG_POSIX_SEMANTICS) &&
3034 (file_attributes & FILE_ATTRIBUTE_TEMPORARY)) {
3035 status = NT_STATUS_INVALID_PARAMETER;
3036 goto fail;
3040 * We will get a create directory here if the Win32
3041 * app specified a security descriptor in the
3042 * CreateDirectory() call.
3045 oplock_request = 0;
3046 status = open_directory(
3047 conn, req, smb_fname, access_mask, share_access,
3048 create_disposition, create_options, file_attributes,
3049 &info, &fsp);
3050 } else {
3053 * Ordinary file case.
3056 status = file_new(req, conn, &fsp);
3057 if(!NT_STATUS_IS_OK(status)) {
3058 goto fail;
3061 status = fsp_set_smb_fname(fsp, smb_fname);
3062 if (!NT_STATUS_IS_OK(status)) {
3063 goto fail;
3067 * We're opening the stream element of a base_fsp
3068 * we already opened. Set up the base_fsp pointer.
3070 if (base_fsp) {
3071 fsp->base_fsp = base_fsp;
3074 status = open_file_ntcreate(conn,
3075 req,
3076 access_mask,
3077 share_access,
3078 create_disposition,
3079 create_options,
3080 file_attributes,
3081 oplock_request,
3082 &info,
3083 fsp);
3085 if(!NT_STATUS_IS_OK(status)) {
3086 file_free(req, fsp);
3087 fsp = NULL;
3090 if (NT_STATUS_EQUAL(status, NT_STATUS_FILE_IS_A_DIRECTORY)) {
3092 /* A stream open never opens a directory */
3094 if (base_fsp) {
3095 status = NT_STATUS_FILE_IS_A_DIRECTORY;
3096 goto fail;
3100 * Fail the open if it was explicitly a non-directory
3101 * file.
3104 if (create_options & FILE_NON_DIRECTORY_FILE) {
3105 status = NT_STATUS_FILE_IS_A_DIRECTORY;
3106 goto fail;
3109 oplock_request = 0;
3110 status = open_directory(
3111 conn, req, smb_fname, access_mask,
3112 share_access, create_disposition,
3113 create_options, file_attributes,
3114 &info, &fsp);
3118 if (!NT_STATUS_IS_OK(status)) {
3119 goto fail;
3122 fsp->base_fsp = base_fsp;
3125 * According to the MS documentation, the only time the security
3126 * descriptor is applied to the opened file is iff we *created* the
3127 * file; an existing file stays the same.
3129 * Also, it seems (from observation) that you can open the file with
3130 * any access mask but you can still write the sd. We need to override
3131 * the granted access before we call set_sd
3132 * Patch for bug #2242 from Tom Lackemann <cessnatomny@yahoo.com>.
3135 if ((sd != NULL) && (info == FILE_WAS_CREATED)
3136 && lp_nt_acl_support(SNUM(conn))) {
3138 uint32_t sec_info_sent;
3139 uint32_t saved_access_mask = fsp->access_mask;
3141 sec_info_sent = get_sec_info(sd);
3143 fsp->access_mask = FILE_GENERIC_ALL;
3145 /* Convert all the generic bits. */
3146 security_acl_map_generic(sd->dacl, &file_generic_mapping);
3147 security_acl_map_generic(sd->sacl, &file_generic_mapping);
3149 if (sec_info_sent & (OWNER_SECURITY_INFORMATION|
3150 GROUP_SECURITY_INFORMATION|
3151 DACL_SECURITY_INFORMATION|
3152 SACL_SECURITY_INFORMATION)) {
3153 status = SMB_VFS_FSET_NT_ACL(fsp, sec_info_sent, sd);
3156 fsp->access_mask = saved_access_mask;
3158 if (!NT_STATUS_IS_OK(status)) {
3159 goto fail;
3163 if ((ea_list != NULL) &&
3164 ((info == FILE_WAS_CREATED) || (info == FILE_WAS_OVERWRITTEN))) {
3165 status = set_ea(conn, fsp, fsp->fsp_name, ea_list);
3166 if (!NT_STATUS_IS_OK(status)) {
3167 goto fail;
3171 if (!fsp->is_directory && S_ISDIR(fsp->fsp_name->st.st_ex_mode)) {
3172 status = NT_STATUS_ACCESS_DENIED;
3173 goto fail;
3176 /* Save the requested allocation size. */
3177 if ((info == FILE_WAS_CREATED) || (info == FILE_WAS_OVERWRITTEN)) {
3178 if (allocation_size
3179 && (allocation_size > fsp->fsp_name->st.st_ex_size)) {
3180 fsp->initial_allocation_size = smb_roundup(
3181 fsp->conn, allocation_size);
3182 if (fsp->is_directory) {
3183 /* Can't set allocation size on a directory. */
3184 status = NT_STATUS_ACCESS_DENIED;
3185 goto fail;
3187 if (vfs_allocate_file_space(
3188 fsp, fsp->initial_allocation_size) == -1) {
3189 status = NT_STATUS_DISK_FULL;
3190 goto fail;
3192 } else {
3193 fsp->initial_allocation_size = smb_roundup(
3194 fsp->conn, (uint64_t)fsp->fsp_name->st.st_ex_size);
3198 DEBUG(10, ("create_file_unixpath: info=%d\n", info));
3200 *result = fsp;
3201 if (pinfo != NULL) {
3202 *pinfo = info;
3205 smb_fname->st = fsp->fsp_name->st;
3207 return NT_STATUS_OK;
3209 fail:
3210 DEBUG(10, ("create_file_unixpath: %s\n", nt_errstr(status)));
3212 if (fsp != NULL) {
3213 if (base_fsp && fsp->base_fsp == base_fsp) {
3215 * The close_file below will close
3216 * fsp->base_fsp.
3218 base_fsp = NULL;
3220 close_file(req, fsp, ERROR_CLOSE);
3221 fsp = NULL;
3223 if (base_fsp != NULL) {
3224 close_file(req, base_fsp, ERROR_CLOSE);
3225 base_fsp = NULL;
3227 return status;
3231 * Calculate the full path name given a relative fid.
3233 NTSTATUS get_relative_fid_filename(connection_struct *conn,
3234 struct smb_request *req,
3235 uint16_t root_dir_fid,
3236 const struct smb_filename *smb_fname,
3237 struct smb_filename **smb_fname_out)
3239 files_struct *dir_fsp;
3240 char *parent_fname = NULL;
3241 char *new_base_name = NULL;
3242 NTSTATUS status;
3244 if (root_dir_fid == 0 || !smb_fname) {
3245 status = NT_STATUS_INTERNAL_ERROR;
3246 goto out;
3249 dir_fsp = file_fsp(req, root_dir_fid);
3251 if (dir_fsp == NULL) {
3252 status = NT_STATUS_INVALID_HANDLE;
3253 goto out;
3256 if (is_ntfs_stream_smb_fname(dir_fsp->fsp_name)) {
3257 status = NT_STATUS_INVALID_HANDLE;
3258 goto out;
3261 if (!dir_fsp->is_directory) {
3264 * Check to see if this is a mac fork of some kind.
3267 if ((conn->fs_capabilities & FILE_NAMED_STREAMS) &&
3268 is_ntfs_stream_smb_fname(smb_fname)) {
3269 status = NT_STATUS_OBJECT_PATH_NOT_FOUND;
3270 goto out;
3274 we need to handle the case when we get a
3275 relative open relative to a file and the
3276 pathname is blank - this is a reopen!
3277 (hint from demyn plantenberg)
3280 status = NT_STATUS_INVALID_HANDLE;
3281 goto out;
3284 if (ISDOT(dir_fsp->fsp_name->base_name)) {
3286 * We're at the toplevel dir, the final file name
3287 * must not contain ./, as this is filtered out
3288 * normally by srvstr_get_path and unix_convert
3289 * explicitly rejects paths containing ./.
3291 parent_fname = talloc_strdup(talloc_tos(), "");
3292 if (parent_fname == NULL) {
3293 status = NT_STATUS_NO_MEMORY;
3294 goto out;
3296 } else {
3297 size_t dir_name_len = strlen(dir_fsp->fsp_name->base_name);
3300 * Copy in the base directory name.
3303 parent_fname = TALLOC_ARRAY(talloc_tos(), char,
3304 dir_name_len+2);
3305 if (parent_fname == NULL) {
3306 status = NT_STATUS_NO_MEMORY;
3307 goto out;
3309 memcpy(parent_fname, dir_fsp->fsp_name->base_name,
3310 dir_name_len+1);
3313 * Ensure it ends in a '/'.
3314 * We used TALLOC_SIZE +2 to add space for the '/'.
3317 if(dir_name_len
3318 && (parent_fname[dir_name_len-1] != '\\')
3319 && (parent_fname[dir_name_len-1] != '/')) {
3320 parent_fname[dir_name_len] = '/';
3321 parent_fname[dir_name_len+1] = '\0';
3325 new_base_name = talloc_asprintf(talloc_tos(), "%s%s", parent_fname,
3326 smb_fname->base_name);
3327 if (new_base_name == NULL) {
3328 status = NT_STATUS_NO_MEMORY;
3329 goto out;
3332 status = filename_convert(req,
3333 conn,
3334 req->flags2 & FLAGS2_DFS_PATHNAMES,
3335 new_base_name,
3337 NULL,
3338 smb_fname_out);
3339 if (!NT_STATUS_IS_OK(status)) {
3340 goto out;
3343 out:
3344 TALLOC_FREE(parent_fname);
3345 return status;
3348 NTSTATUS create_file_default(connection_struct *conn,
3349 struct smb_request *req,
3350 uint16_t root_dir_fid,
3351 struct smb_filename *smb_fname,
3352 uint32_t access_mask,
3353 uint32_t share_access,
3354 uint32_t create_disposition,
3355 uint32_t create_options,
3356 uint32_t file_attributes,
3357 uint32_t oplock_request,
3358 uint64_t allocation_size,
3359 struct security_descriptor *sd,
3360 struct ea_list *ea_list,
3361 files_struct **result,
3362 int *pinfo)
3364 int info = FILE_WAS_OPENED;
3365 files_struct *fsp = NULL;
3366 NTSTATUS status;
3368 DEBUG(10,("create_file: access_mask = 0x%x "
3369 "file_attributes = 0x%x, share_access = 0x%x, "
3370 "create_disposition = 0x%x create_options = 0x%x "
3371 "oplock_request = 0x%x "
3372 "root_dir_fid = 0x%x, ea_list = 0x%p, sd = 0x%p, "
3373 "fname = %s\n",
3374 (unsigned int)access_mask,
3375 (unsigned int)file_attributes,
3376 (unsigned int)share_access,
3377 (unsigned int)create_disposition,
3378 (unsigned int)create_options,
3379 (unsigned int)oplock_request,
3380 (unsigned int)root_dir_fid,
3381 ea_list, sd, smb_fname_str_dbg(smb_fname)));
3384 * Calculate the filename from the root_dir_if if necessary.
3387 if (root_dir_fid != 0) {
3388 struct smb_filename *smb_fname_out = NULL;
3389 status = get_relative_fid_filename(conn, req, root_dir_fid,
3390 smb_fname, &smb_fname_out);
3391 if (!NT_STATUS_IS_OK(status)) {
3392 goto fail;
3394 smb_fname = smb_fname_out;
3398 * Check to see if this is a mac fork of some kind.
3401 if (is_ntfs_stream_smb_fname(smb_fname)) {
3402 enum FAKE_FILE_TYPE fake_file_type;
3404 fake_file_type = is_fake_file(smb_fname);
3406 if (fake_file_type != FAKE_FILE_TYPE_NONE) {
3409 * Here we go! support for changing the disk quotas
3410 * --metze
3412 * We need to fake up to open this MAGIC QUOTA file
3413 * and return a valid FID.
3415 * w2k close this file directly after openening xp
3416 * also tries a QUERY_FILE_INFO on the file and then
3417 * close it
3419 status = open_fake_file(req, conn, req->vuid,
3420 fake_file_type, smb_fname,
3421 access_mask, &fsp);
3422 if (!NT_STATUS_IS_OK(status)) {
3423 goto fail;
3426 ZERO_STRUCT(smb_fname->st);
3427 goto done;
3430 if (!(conn->fs_capabilities & FILE_NAMED_STREAMS)) {
3431 status = NT_STATUS_OBJECT_NAME_NOT_FOUND;
3432 goto fail;
3436 /* All file access must go through check_name() */
3438 status = check_name(conn, smb_fname->base_name);
3439 if (!NT_STATUS_IS_OK(status)) {
3440 goto fail;
3443 status = create_file_unixpath(
3444 conn, req, smb_fname, access_mask, share_access,
3445 create_disposition, create_options, file_attributes,
3446 oplock_request, allocation_size, sd, ea_list,
3447 &fsp, &info);
3449 if (!NT_STATUS_IS_OK(status)) {
3450 goto fail;
3453 done:
3454 DEBUG(10, ("create_file: info=%d\n", info));
3456 *result = fsp;
3457 if (pinfo != NULL) {
3458 *pinfo = info;
3460 return NT_STATUS_OK;
3462 fail:
3463 DEBUG(10, ("create_file: %s\n", nt_errstr(status)));
3465 if (fsp != NULL) {
3466 close_file(req, fsp, ERROR_CLOSE);
3467 fsp = NULL;
3469 return status;