Remove unneeded argument from can_set_delete_on_close(). Ensure
[Samba.git] / source3 / smbd / open.c
blobfd3c6103e9f224e1a8bd1c6dd1aa054ddf55f2d6
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 const struct generic_mapping file_generic_mapping;
27 struct deferred_open_record {
28 bool delayed_for_oplocks;
29 struct file_id id;
32 static NTSTATUS create_file_unixpath(connection_struct *conn,
33 struct smb_request *req,
34 struct smb_filename *smb_fname,
35 uint32_t access_mask,
36 uint32_t share_access,
37 uint32_t create_disposition,
38 uint32_t create_options,
39 uint32_t file_attributes,
40 uint32_t oplock_request,
41 uint64_t allocation_size,
42 struct security_descriptor *sd,
43 struct ea_list *ea_list,
45 files_struct **result,
46 int *pinfo);
48 /****************************************************************************
49 SMB1 file varient of se_access_check. Never test FILE_READ_ATTRIBUTES.
50 ****************************************************************************/
52 NTSTATUS smb1_file_se_access_check(const struct security_descriptor *sd,
53 const NT_USER_TOKEN *token,
54 uint32_t access_desired,
55 uint32_t *access_granted)
57 return se_access_check(sd,
58 token,
59 (access_desired & ~FILE_READ_ATTRIBUTES),
60 access_granted);
63 /****************************************************************************
64 Check if we have open rights.
65 ****************************************************************************/
67 NTSTATUS smbd_check_open_rights(struct connection_struct *conn,
68 const struct smb_filename *smb_fname,
69 uint32_t access_mask,
70 uint32_t *access_granted)
72 /* Check if we have rights to open. */
73 NTSTATUS status;
74 struct security_descriptor *sd = NULL;
76 *access_granted = 0;
78 if (conn->server_info->utok.uid == 0 || conn->admin_user) {
79 /* I'm sorry sir, I didn't know you were root... */
80 *access_granted = access_mask;
81 if (access_mask & SEC_FLAG_MAXIMUM_ALLOWED) {
82 *access_granted |= FILE_GENERIC_ALL;
84 return NT_STATUS_OK;
87 status = SMB_VFS_GET_NT_ACL(conn, smb_fname->base_name,
88 (OWNER_SECURITY_INFORMATION |
89 GROUP_SECURITY_INFORMATION |
90 DACL_SECURITY_INFORMATION),&sd);
92 if (!NT_STATUS_IS_OK(status)) {
93 DEBUG(10, ("smbd_check_open_rights: Could not get acl "
94 "on %s: %s\n",
95 smb_fname_str_dbg(smb_fname),
96 nt_errstr(status)));
97 return status;
100 status = smb1_file_se_access_check(sd,
101 conn->server_info->ptok,
102 access_mask,
103 access_granted);
105 TALLOC_FREE(sd);
107 DEBUG(10,("smbd_check_open_rights: file %s requesting "
108 "0x%x returning 0x%x (%s)\n",
109 smb_fname_str_dbg(smb_fname),
110 (unsigned int)access_mask,
111 (unsigned int)*access_granted,
112 nt_errstr(status) ));
114 return status;
117 /****************************************************************************
118 fd support routines - attempt to do a dos_open.
119 ****************************************************************************/
121 static NTSTATUS fd_open(struct connection_struct *conn,
122 struct smb_filename *smb_fname,
123 files_struct *fsp,
124 int flags,
125 mode_t mode)
127 NTSTATUS status = NT_STATUS_OK;
129 #ifdef O_NOFOLLOW
131 * Never follow symlinks on a POSIX client. The
132 * client should be doing this.
135 if (fsp->posix_open || !lp_symlinks(SNUM(conn))) {
136 flags |= O_NOFOLLOW;
138 #endif
140 fsp->fh->fd = SMB_VFS_OPEN(conn, smb_fname, fsp, flags, mode);
141 if (fsp->fh->fd == -1) {
142 status = map_nt_error_from_unix(errno);
143 if (errno == EMFILE) {
144 static time_t last_warned = 0L;
146 if (time((time_t *) NULL) > last_warned) {
147 DEBUG(0,("Too many open files, unable "
148 "to open more! smbd's max "
149 "open files = %d\n",
150 lp_max_open_files()));
151 last_warned = time((time_t *) NULL);
157 DEBUG(10,("fd_open: name %s, flags = 0%o mode = 0%o, fd = %d. %s\n",
158 smb_fname_str_dbg(smb_fname), flags, (int)mode, fsp->fh->fd,
159 (fsp->fh->fd == -1) ? strerror(errno) : "" ));
161 return status;
164 /****************************************************************************
165 Close the file associated with a fsp.
166 ****************************************************************************/
168 NTSTATUS fd_close(files_struct *fsp)
170 int ret;
172 if (fsp->fh->fd == -1) {
173 return NT_STATUS_OK; /* What we used to call a stat open. */
175 if (fsp->fh->ref_count > 1) {
176 return NT_STATUS_OK; /* Shared handle. Only close last reference. */
179 ret = SMB_VFS_CLOSE(fsp);
180 fsp->fh->fd = -1;
181 if (ret == -1) {
182 return map_nt_error_from_unix(errno);
184 return NT_STATUS_OK;
187 /****************************************************************************
188 Change the ownership of a file to that of the parent directory.
189 Do this by fd if possible.
190 ****************************************************************************/
192 void change_file_owner_to_parent(connection_struct *conn,
193 const char *inherit_from_dir,
194 files_struct *fsp)
196 struct smb_filename *smb_fname_parent = NULL;
197 NTSTATUS status;
198 int ret;
200 status = create_synthetic_smb_fname(talloc_tos(), inherit_from_dir,
201 NULL, NULL, &smb_fname_parent);
202 if (!NT_STATUS_IS_OK(status)) {
203 return;
206 ret = SMB_VFS_STAT(conn, smb_fname_parent);
207 if (ret == -1) {
208 DEBUG(0,("change_file_owner_to_parent: failed to stat parent "
209 "directory %s. Error was %s\n",
210 smb_fname_str_dbg(smb_fname_parent),
211 strerror(errno)));
212 return;
215 become_root();
216 ret = SMB_VFS_FCHOWN(fsp, smb_fname_parent->st.st_ex_uid, (gid_t)-1);
217 unbecome_root();
218 if (ret == -1) {
219 DEBUG(0,("change_file_owner_to_parent: failed to fchown "
220 "file %s to parent directory uid %u. Error "
221 "was %s\n", fsp_str_dbg(fsp),
222 (unsigned int)smb_fname_parent->st.st_ex_uid,
223 strerror(errno) ));
226 DEBUG(10,("change_file_owner_to_parent: changed new file %s to "
227 "parent directory uid %u.\n", fsp_str_dbg(fsp),
228 (unsigned int)smb_fname_parent->st.st_ex_uid));
230 TALLOC_FREE(smb_fname_parent);
233 NTSTATUS change_dir_owner_to_parent(connection_struct *conn,
234 const char *inherit_from_dir,
235 const char *fname,
236 SMB_STRUCT_STAT *psbuf)
238 struct smb_filename *smb_fname_parent = NULL;
239 struct smb_filename *smb_fname_cwd = NULL;
240 char *saved_dir = NULL;
241 TALLOC_CTX *ctx = talloc_tos();
242 NTSTATUS status = NT_STATUS_OK;
243 int ret;
245 status = create_synthetic_smb_fname(ctx, inherit_from_dir, NULL, NULL,
246 &smb_fname_parent);
247 if (!NT_STATUS_IS_OK(status)) {
248 return status;
251 ret = SMB_VFS_STAT(conn, smb_fname_parent);
252 if (ret == -1) {
253 status = map_nt_error_from_unix(errno);
254 DEBUG(0,("change_dir_owner_to_parent: failed to stat parent "
255 "directory %s. Error was %s\n",
256 smb_fname_str_dbg(smb_fname_parent),
257 strerror(errno)));
258 goto out;
261 /* We've already done an lstat into psbuf, and we know it's a
262 directory. If we can cd into the directory and the dev/ino
263 are the same then we can safely chown without races as
264 we're locking the directory in place by being in it. This
265 should work on any UNIX (thanks tridge :-). JRA.
268 saved_dir = vfs_GetWd(ctx,conn);
269 if (!saved_dir) {
270 status = map_nt_error_from_unix(errno);
271 DEBUG(0,("change_dir_owner_to_parent: failed to get "
272 "current working directory. Error was %s\n",
273 strerror(errno)));
274 goto out;
277 /* Chdir into the new path. */
278 if (vfs_ChDir(conn, fname) == -1) {
279 status = map_nt_error_from_unix(errno);
280 DEBUG(0,("change_dir_owner_to_parent: failed to change "
281 "current working directory to %s. Error "
282 "was %s\n", fname, strerror(errno) ));
283 goto chdir;
286 status = create_synthetic_smb_fname(ctx, ".", NULL, NULL,
287 &smb_fname_cwd);
288 if (!NT_STATUS_IS_OK(status)) {
289 return status;
292 ret = SMB_VFS_STAT(conn, smb_fname_cwd);
293 if (ret == -1) {
294 status = map_nt_error_from_unix(errno);
295 DEBUG(0,("change_dir_owner_to_parent: failed to stat "
296 "directory '.' (%s) Error was %s\n",
297 fname, strerror(errno)));
298 goto chdir;
301 /* Ensure we're pointing at the same place. */
302 if (smb_fname_cwd->st.st_ex_dev != psbuf->st_ex_dev ||
303 smb_fname_cwd->st.st_ex_ino != psbuf->st_ex_ino ||
304 smb_fname_cwd->st.st_ex_mode != psbuf->st_ex_mode ) {
305 DEBUG(0,("change_dir_owner_to_parent: "
306 "device/inode/mode on directory %s changed. "
307 "Refusing to chown !\n", fname ));
308 status = NT_STATUS_ACCESS_DENIED;
309 goto chdir;
312 become_root();
313 ret = SMB_VFS_CHOWN(conn, ".", smb_fname_parent->st.st_ex_uid,
314 (gid_t)-1);
315 unbecome_root();
316 if (ret == -1) {
317 status = map_nt_error_from_unix(errno);
318 DEBUG(10,("change_dir_owner_to_parent: failed to chown "
319 "directory %s to parent directory uid %u. "
320 "Error was %s\n", fname,
321 (unsigned int)smb_fname_parent->st.st_ex_uid,
322 strerror(errno) ));
323 goto chdir;
326 DEBUG(10,("change_dir_owner_to_parent: changed ownership of new "
327 "directory %s to parent directory uid %u.\n",
328 fname, (unsigned int)smb_fname_parent->st.st_ex_uid ));
330 chdir:
331 vfs_ChDir(conn,saved_dir);
332 out:
333 TALLOC_FREE(smb_fname_parent);
334 TALLOC_FREE(smb_fname_cwd);
335 return status;
338 /****************************************************************************
339 Open a file.
340 ****************************************************************************/
342 static NTSTATUS open_file(files_struct *fsp,
343 connection_struct *conn,
344 struct smb_request *req,
345 const char *parent_dir,
346 struct smb_filename *smb_fname,
347 int flags,
348 mode_t unx_mode,
349 uint32 access_mask, /* client requested access mask. */
350 uint32 open_access_mask) /* what we're actually using in the open. */
352 NTSTATUS status = NT_STATUS_OK;
353 int accmode = (flags & O_ACCMODE);
354 int local_flags = flags;
355 bool file_existed = VALID_STAT(smb_fname->st);
357 fsp->fh->fd = -1;
358 errno = EPERM;
360 /* Check permissions */
363 * This code was changed after seeing a client open request
364 * containing the open mode of (DENY_WRITE/read-only) with
365 * the 'create if not exist' bit set. The previous code
366 * would fail to open the file read only on a read-only share
367 * as it was checking the flags parameter directly against O_RDONLY,
368 * this was failing as the flags parameter was set to O_RDONLY|O_CREAT.
369 * JRA.
372 if (!CAN_WRITE(conn)) {
373 /* It's a read-only share - fail if we wanted to write. */
374 if(accmode != O_RDONLY || (flags & O_TRUNC) || (flags & O_APPEND)) {
375 DEBUG(3,("Permission denied opening %s\n",
376 smb_fname_str_dbg(smb_fname)));
377 return NT_STATUS_ACCESS_DENIED;
378 } else if(flags & O_CREAT) {
379 /* We don't want to write - but we must make sure that
380 O_CREAT doesn't create the file if we have write
381 access into the directory.
383 flags &= ~(O_CREAT|O_EXCL);
384 local_flags &= ~(O_CREAT|O_EXCL);
389 * This little piece of insanity is inspired by the
390 * fact that an NT client can open a file for O_RDONLY,
391 * but set the create disposition to FILE_EXISTS_TRUNCATE.
392 * If the client *can* write to the file, then it expects to
393 * truncate the file, even though it is opening for readonly.
394 * Quicken uses this stupid trick in backup file creation...
395 * Thanks *greatly* to "David W. Chapman Jr." <dwcjr@inethouston.net>
396 * for helping track this one down. It didn't bite us in 2.0.x
397 * as we always opened files read-write in that release. JRA.
400 if ((accmode == O_RDONLY) && ((flags & O_TRUNC) == O_TRUNC)) {
401 DEBUG(10,("open_file: truncate requested on read-only open "
402 "for file %s\n", smb_fname_str_dbg(smb_fname)));
403 local_flags = (flags & ~O_ACCMODE)|O_RDWR;
406 if ((open_access_mask & (FILE_READ_DATA|FILE_WRITE_DATA|FILE_APPEND_DATA|FILE_EXECUTE)) ||
407 (!file_existed && (local_flags & O_CREAT)) ||
408 ((local_flags & O_TRUNC) == O_TRUNC) ) {
409 const char *wild;
412 * We can't actually truncate here as the file may be locked.
413 * open_file_ntcreate will take care of the truncate later. JRA.
416 local_flags &= ~O_TRUNC;
418 #if defined(O_NONBLOCK) && defined(S_ISFIFO)
420 * We would block on opening a FIFO with no one else on the
421 * other end. Do what we used to do and add O_NONBLOCK to the
422 * open flags. JRA.
425 if (file_existed && S_ISFIFO(smb_fname->st.st_ex_mode)) {
426 local_flags |= O_NONBLOCK;
428 #endif
430 /* Don't create files with Microsoft wildcard characters. */
431 if (fsp->base_fsp) {
433 * wildcard characters are allowed in stream names
434 * only test the basefilename
436 wild = fsp->base_fsp->fsp_name->base_name;
437 } else {
438 wild = smb_fname->base_name;
440 if ((local_flags & O_CREAT) && !file_existed &&
441 ms_has_wild(wild)) {
442 return NT_STATUS_OBJECT_NAME_INVALID;
445 /* Actually do the open */
446 status = fd_open(conn, smb_fname, fsp, local_flags, unx_mode);
447 if (!NT_STATUS_IS_OK(status)) {
448 DEBUG(3,("Error opening file %s (%s) (local_flags=%d) "
449 "(flags=%d)\n", smb_fname_str_dbg(smb_fname),
450 nt_errstr(status),local_flags,flags));
451 return status;
454 if ((local_flags & O_CREAT) && !file_existed) {
456 /* Inherit the ACL if required */
457 if (lp_inherit_perms(SNUM(conn))) {
458 inherit_access_posix_acl(conn, parent_dir,
459 smb_fname->base_name,
460 unx_mode);
463 /* Change the owner if required. */
464 if (lp_inherit_owner(SNUM(conn))) {
465 change_file_owner_to_parent(conn, parent_dir,
466 fsp);
469 notify_fname(conn, NOTIFY_ACTION_ADDED,
470 FILE_NOTIFY_CHANGE_FILE_NAME,
471 smb_fname->base_name);
474 } else {
475 fsp->fh->fd = -1; /* What we used to call a stat open. */
476 if (file_existed) {
477 uint32_t access_granted = 0;
479 status = smbd_check_open_rights(conn,
480 smb_fname,
481 access_mask,
482 &access_granted);
483 if (!NT_STATUS_IS_OK(status)) {
484 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
486 * On NT_STATUS_ACCESS_DENIED, access_granted
487 * contains the denied bits.
490 if ((access_mask & FILE_WRITE_ATTRIBUTES) &&
491 (access_granted & FILE_WRITE_ATTRIBUTES) &&
492 (lp_map_readonly(SNUM(conn)) ||
493 lp_map_archive(SNUM(conn)) ||
494 lp_map_hidden(SNUM(conn)) ||
495 lp_map_system(SNUM(conn)))) {
496 access_granted &= ~FILE_WRITE_ATTRIBUTES;
498 DEBUG(10,("open_file: "
499 "overrode "
500 "FILE_WRITE_"
501 "ATTRIBUTES "
502 "on file %s\n",
503 smb_fname_str_dbg(
504 smb_fname)));
507 if ((access_mask & DELETE_ACCESS) &&
508 (access_granted & DELETE_ACCESS) &&
509 can_delete_file_in_directory(conn,
510 smb_fname)) {
511 /* Were we trying to do a stat open
512 * for delete and didn't get DELETE
513 * access (only) ? Check if the
514 * directory allows DELETE_CHILD.
515 * See here:
516 * http://blogs.msdn.com/oldnewthing/archive/2004/06/04/148426.aspx
517 * for details. */
519 access_granted &= ~DELETE_ACCESS;
521 DEBUG(10,("open_file: "
522 "overrode "
523 "DELETE_ACCESS on "
524 "file %s\n",
525 smb_fname_str_dbg(
526 smb_fname)));
529 if (access_granted != 0) {
530 DEBUG(10,("open_file: Access "
531 "denied on file "
532 "%s\n",
533 smb_fname_str_dbg(
534 smb_fname)));
535 return status;
537 } else if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND) &&
538 fsp->posix_open &&
539 S_ISLNK(smb_fname->st.st_ex_mode)) {
540 /* This is a POSIX stat open for delete
541 * or rename on a symlink that points
542 * nowhere. Allow. */
543 DEBUG(10,("open_file: allowing POSIX "
544 "open on bad symlink %s\n",
545 smb_fname_str_dbg(
546 smb_fname)));
547 } else {
548 DEBUG(10,("open_file: "
549 "smbd_check_open_rights on file "
550 "%s returned %s\n",
551 smb_fname_str_dbg(smb_fname),
552 nt_errstr(status) ));
553 return status;
559 if (!file_existed) {
560 int ret;
562 if (fsp->fh->fd == -1) {
563 ret = SMB_VFS_STAT(conn, smb_fname);
564 } else {
565 ret = SMB_VFS_FSTAT(fsp, &smb_fname->st);
566 /* If we have an fd, this stat should succeed. */
567 if (ret == -1) {
568 DEBUG(0,("Error doing fstat on open file %s "
569 "(%s)\n",
570 smb_fname_str_dbg(smb_fname),
571 strerror(errno) ));
575 /* For a non-io open, this stat failing means file not found. JRA */
576 if (ret == -1) {
577 status = map_nt_error_from_unix(errno);
578 fd_close(fsp);
579 return status;
584 * POSIX allows read-only opens of directories. We don't
585 * want to do this (we use a different code path for this)
586 * so catch a directory open and return an EISDIR. JRA.
589 if(S_ISDIR(smb_fname->st.st_ex_mode)) {
590 fd_close(fsp);
591 errno = EISDIR;
592 return NT_STATUS_FILE_IS_A_DIRECTORY;
595 fsp->mode = smb_fname->st.st_ex_mode;
596 fsp->file_id = vfs_file_id_from_sbuf(conn, &smb_fname->st);
597 fsp->vuid = req ? req->vuid : UID_FIELD_INVALID;
598 fsp->file_pid = req ? req->smbpid : 0;
599 fsp->can_lock = True;
600 fsp->can_read = (access_mask & (FILE_READ_DATA)) ? True : False;
601 if (!CAN_WRITE(conn)) {
602 fsp->can_write = False;
603 } else {
604 fsp->can_write = (access_mask & (FILE_WRITE_DATA | FILE_APPEND_DATA)) ?
605 True : False;
607 fsp->print_file = False;
608 fsp->modified = False;
609 fsp->sent_oplock_break = NO_BREAK_SENT;
610 fsp->is_directory = False;
611 if (conn->aio_write_behind_list &&
612 is_in_path(smb_fname->base_name, conn->aio_write_behind_list,
613 conn->case_sensitive)) {
614 fsp->aio_write_behind = True;
616 status = fsp_set_smb_fname(fsp, smb_fname);
617 if (!NT_STATUS_IS_OK(status)) {
618 fd_close(fsp);
619 errno = map_errno_from_nt_status(status);
620 return status;
623 fsp->wcp = NULL; /* Write cache pointer. */
625 DEBUG(2,("%s opened file %s read=%s write=%s (numopen=%d)\n",
626 conn->server_info->unix_name,
627 smb_fname_str_dbg(smb_fname),
628 BOOLSTR(fsp->can_read), BOOLSTR(fsp->can_write),
629 conn->num_files_open));
631 errno = 0;
632 return NT_STATUS_OK;
635 /*******************************************************************
636 Return True if the filename is one of the special executable types.
637 ********************************************************************/
639 bool is_executable(const char *fname)
641 if ((fname = strrchr_m(fname,'.'))) {
642 if (strequal(fname,".com") ||
643 strequal(fname,".dll") ||
644 strequal(fname,".exe") ||
645 strequal(fname,".sym")) {
646 return True;
649 return False;
652 /****************************************************************************
653 Check if we can open a file with a share mode.
654 Returns True if conflict, False if not.
655 ****************************************************************************/
657 static bool share_conflict(struct share_mode_entry *entry,
658 uint32 access_mask,
659 uint32 share_access)
661 DEBUG(10,("share_conflict: entry->access_mask = 0x%x, "
662 "entry->share_access = 0x%x, "
663 "entry->private_options = 0x%x\n",
664 (unsigned int)entry->access_mask,
665 (unsigned int)entry->share_access,
666 (unsigned int)entry->private_options));
668 DEBUG(10,("share_conflict: access_mask = 0x%x, share_access = 0x%x\n",
669 (unsigned int)access_mask, (unsigned int)share_access));
671 if ((entry->access_mask & (FILE_WRITE_DATA|
672 FILE_APPEND_DATA|
673 FILE_READ_DATA|
674 FILE_EXECUTE|
675 DELETE_ACCESS)) == 0) {
676 DEBUG(10,("share_conflict: No conflict due to "
677 "entry->access_mask = 0x%x\n",
678 (unsigned int)entry->access_mask ));
679 return False;
682 if ((access_mask & (FILE_WRITE_DATA|
683 FILE_APPEND_DATA|
684 FILE_READ_DATA|
685 FILE_EXECUTE|
686 DELETE_ACCESS)) == 0) {
687 DEBUG(10,("share_conflict: No conflict due to "
688 "access_mask = 0x%x\n",
689 (unsigned int)access_mask ));
690 return False;
693 #if 1 /* JRA TEST - Superdebug. */
694 #define CHECK_MASK(num, am, right, sa, share) \
695 DEBUG(10,("share_conflict: [%d] am (0x%x) & right (0x%x) = 0x%x\n", \
696 (unsigned int)(num), (unsigned int)(am), \
697 (unsigned int)(right), (unsigned int)(am)&(right) )); \
698 DEBUG(10,("share_conflict: [%d] sa (0x%x) & share (0x%x) = 0x%x\n", \
699 (unsigned int)(num), (unsigned int)(sa), \
700 (unsigned int)(share), (unsigned int)(sa)&(share) )); \
701 if (((am) & (right)) && !((sa) & (share))) { \
702 DEBUG(10,("share_conflict: check %d conflict am = 0x%x, right = 0x%x, \
703 sa = 0x%x, share = 0x%x\n", (num), (unsigned int)(am), (unsigned int)(right), (unsigned int)(sa), \
704 (unsigned int)(share) )); \
705 return True; \
707 #else
708 #define CHECK_MASK(num, am, right, sa, share) \
709 if (((am) & (right)) && !((sa) & (share))) { \
710 DEBUG(10,("share_conflict: check %d conflict am = 0x%x, right = 0x%x, \
711 sa = 0x%x, share = 0x%x\n", (num), (unsigned int)(am), (unsigned int)(right), (unsigned int)(sa), \
712 (unsigned int)(share) )); \
713 return True; \
715 #endif
717 CHECK_MASK(1, entry->access_mask, FILE_WRITE_DATA | FILE_APPEND_DATA,
718 share_access, FILE_SHARE_WRITE);
719 CHECK_MASK(2, access_mask, FILE_WRITE_DATA | FILE_APPEND_DATA,
720 entry->share_access, FILE_SHARE_WRITE);
722 CHECK_MASK(3, entry->access_mask, FILE_READ_DATA | FILE_EXECUTE,
723 share_access, FILE_SHARE_READ);
724 CHECK_MASK(4, access_mask, FILE_READ_DATA | FILE_EXECUTE,
725 entry->share_access, FILE_SHARE_READ);
727 CHECK_MASK(5, entry->access_mask, DELETE_ACCESS,
728 share_access, FILE_SHARE_DELETE);
729 CHECK_MASK(6, access_mask, DELETE_ACCESS,
730 entry->share_access, FILE_SHARE_DELETE);
732 DEBUG(10,("share_conflict: No conflict.\n"));
733 return False;
736 #if defined(DEVELOPER)
737 static void validate_my_share_entries(int num,
738 struct share_mode_entry *share_entry)
740 files_struct *fsp;
742 if (!procid_is_me(&share_entry->pid)) {
743 return;
746 if (is_deferred_open_entry(share_entry) &&
747 !open_was_deferred(share_entry->op_mid)) {
748 char *str = talloc_asprintf(talloc_tos(),
749 "Got a deferred entry without a request: "
750 "PANIC: %s\n",
751 share_mode_str(talloc_tos(), num, share_entry));
752 smb_panic(str);
755 if (!is_valid_share_mode_entry(share_entry)) {
756 return;
759 fsp = file_find_dif(share_entry->id,
760 share_entry->share_file_id);
761 if (!fsp) {
762 DEBUG(0,("validate_my_share_entries: PANIC : %s\n",
763 share_mode_str(talloc_tos(), num, share_entry) ));
764 smb_panic("validate_my_share_entries: Cannot match a "
765 "share entry with an open file\n");
768 if (is_deferred_open_entry(share_entry) ||
769 is_unused_share_mode_entry(share_entry)) {
770 goto panic;
773 if ((share_entry->op_type == NO_OPLOCK) &&
774 (fsp->oplock_type == FAKE_LEVEL_II_OPLOCK)) {
775 /* Someone has already written to it, but I haven't yet
776 * noticed */
777 return;
780 if (((uint16)fsp->oplock_type) != share_entry->op_type) {
781 goto panic;
784 return;
786 panic:
788 char *str;
789 DEBUG(0,("validate_my_share_entries: PANIC : %s\n",
790 share_mode_str(talloc_tos(), num, share_entry) ));
791 str = talloc_asprintf(talloc_tos(),
792 "validate_my_share_entries: "
793 "file %s, oplock_type = 0x%x, op_type = 0x%x\n",
794 fsp->fsp_name->base_name,
795 (unsigned int)fsp->oplock_type,
796 (unsigned int)share_entry->op_type );
797 smb_panic(str);
800 #endif
802 bool is_stat_open(uint32 access_mask)
804 return (access_mask &&
805 ((access_mask & ~(SYNCHRONIZE_ACCESS| FILE_READ_ATTRIBUTES|
806 FILE_WRITE_ATTRIBUTES))==0) &&
807 ((access_mask & (SYNCHRONIZE_ACCESS|FILE_READ_ATTRIBUTES|
808 FILE_WRITE_ATTRIBUTES)) != 0));
811 /****************************************************************************
812 Deal with share modes
813 Invarient: Share mode must be locked on entry and exit.
814 Returns -1 on error, or number of share modes on success (may be zero).
815 ****************************************************************************/
817 static NTSTATUS open_mode_check(connection_struct *conn,
818 struct share_mode_lock *lck,
819 uint32 access_mask,
820 uint32 share_access,
821 uint32 create_options,
822 bool *file_existed)
824 int i;
826 if(lck->num_share_modes == 0) {
827 return NT_STATUS_OK;
830 *file_existed = True;
832 /* A delete on close prohibits everything */
834 if (lck->delete_on_close) {
835 return NT_STATUS_DELETE_PENDING;
838 if (is_stat_open(access_mask)) {
839 /* Stat open that doesn't trigger oplock breaks or share mode
840 * checks... ! JRA. */
841 return NT_STATUS_OK;
845 * Check if the share modes will give us access.
848 #if defined(DEVELOPER)
849 for(i = 0; i < lck->num_share_modes; i++) {
850 validate_my_share_entries(i, &lck->share_modes[i]);
852 #endif
854 if (!lp_share_modes(SNUM(conn))) {
855 return NT_STATUS_OK;
858 /* Now we check the share modes, after any oplock breaks. */
859 for(i = 0; i < lck->num_share_modes; i++) {
861 if (!is_valid_share_mode_entry(&lck->share_modes[i])) {
862 continue;
865 /* someone else has a share lock on it, check to see if we can
866 * too */
867 if (share_conflict(&lck->share_modes[i],
868 access_mask, share_access)) {
869 return NT_STATUS_SHARING_VIOLATION;
873 return NT_STATUS_OK;
876 static bool is_delete_request(files_struct *fsp) {
877 return ((fsp->access_mask == DELETE_ACCESS) &&
878 (fsp->oplock_type == NO_OPLOCK));
882 * Send a break message to the oplock holder and delay the open for
883 * our client.
886 static NTSTATUS send_break_message(files_struct *fsp,
887 struct share_mode_entry *exclusive,
888 uint16 mid,
889 int oplock_request)
891 NTSTATUS status;
892 char msg[MSG_SMB_SHARE_MODE_ENTRY_SIZE];
894 DEBUG(10, ("Sending break request to PID %s\n",
895 procid_str_static(&exclusive->pid)));
896 exclusive->op_mid = mid;
898 /* Create the message. */
899 share_mode_entry_to_message(msg, exclusive);
901 /* Add in the FORCE_OPLOCK_BREAK_TO_NONE bit in the message if set. We
902 don't want this set in the share mode struct pointed to by lck. */
904 if (oplock_request & FORCE_OPLOCK_BREAK_TO_NONE) {
905 SSVAL(msg,6,exclusive->op_type | FORCE_OPLOCK_BREAK_TO_NONE);
908 status = messaging_send_buf(smbd_messaging_context(), exclusive->pid,
909 MSG_SMB_BREAK_REQUEST,
910 (uint8 *)msg,
911 MSG_SMB_SHARE_MODE_ENTRY_SIZE);
912 if (!NT_STATUS_IS_OK(status)) {
913 DEBUG(3, ("Could not send oplock break message: %s\n",
914 nt_errstr(status)));
917 return status;
921 * 1) No files open at all or internal open: Grant whatever the client wants.
923 * 2) Exclusive (or batch) oplock around: If the requested access is a delete
924 * request, break if the oplock around is a batch oplock. If it's another
925 * requested access type, break.
927 * 3) Only level2 around: Grant level2 and do nothing else.
930 static bool delay_for_oplocks(struct share_mode_lock *lck,
931 files_struct *fsp,
932 uint16 mid,
933 int pass_number,
934 int oplock_request)
936 int i;
937 struct share_mode_entry *exclusive = NULL;
938 bool valid_entry = false;
939 bool have_level2 = false;
940 bool have_a_none_oplock = false;
941 bool allow_level2 = (global_client_caps & CAP_LEVEL_II_OPLOCKS) &&
942 lp_level2_oplocks(SNUM(fsp->conn));
944 if (oplock_request & INTERNAL_OPEN_ONLY) {
945 fsp->oplock_type = NO_OPLOCK;
948 if ((oplock_request & INTERNAL_OPEN_ONLY) || is_stat_open(fsp->access_mask)) {
949 return false;
952 for (i=0; i<lck->num_share_modes; i++) {
954 if (!is_valid_share_mode_entry(&lck->share_modes[i])) {
955 continue;
958 /* At least one entry is not an invalid or deferred entry. */
959 valid_entry = true;
961 if (pass_number == 1) {
962 if (BATCH_OPLOCK_TYPE(lck->share_modes[i].op_type)) {
963 SMB_ASSERT(exclusive == NULL);
964 exclusive = &lck->share_modes[i];
966 } else {
967 if (EXCLUSIVE_OPLOCK_TYPE(lck->share_modes[i].op_type)) {
968 SMB_ASSERT(exclusive == NULL);
969 exclusive = &lck->share_modes[i];
973 if (LEVEL_II_OPLOCK_TYPE(lck->share_modes[i].op_type)) {
974 SMB_ASSERT(exclusive == NULL);
975 have_level2 = true;
978 if (lck->share_modes[i].op_type == NO_OPLOCK) {
979 have_a_none_oplock = true;
983 if (exclusive != NULL) { /* Found an exclusive oplock */
984 bool delay_it = is_delete_request(fsp) ?
985 BATCH_OPLOCK_TYPE(exclusive->op_type) : true;
986 SMB_ASSERT(!have_level2);
987 if (delay_it) {
988 send_break_message(fsp, exclusive, mid, oplock_request);
989 return true;
994 * Match what was requested (fsp->oplock_type) with
995 * what was found in the existing share modes.
998 if (!valid_entry) {
999 /* All entries are placeholders or deferred.
1000 * Directly grant whatever the client wants. */
1001 if (fsp->oplock_type == NO_OPLOCK) {
1002 /* Store a level2 oplock, but don't tell the client */
1003 fsp->oplock_type = FAKE_LEVEL_II_OPLOCK;
1005 } else if (have_a_none_oplock) {
1006 fsp->oplock_type = NO_OPLOCK;
1007 } else if (have_level2) {
1008 if (fsp->oplock_type == NO_OPLOCK ||
1009 fsp->oplock_type == FAKE_LEVEL_II_OPLOCK) {
1010 /* Store a level2 oplock, but don't tell the client */
1011 fsp->oplock_type = FAKE_LEVEL_II_OPLOCK;
1012 } else {
1013 fsp->oplock_type = LEVEL_II_OPLOCK;
1015 } else {
1016 /* This case can never happen. */
1017 SMB_ASSERT(1);
1021 * Don't grant level2 to clients that don't want them
1022 * or if we've turned them off.
1024 if (fsp->oplock_type == LEVEL_II_OPLOCK && !allow_level2) {
1025 fsp->oplock_type = FAKE_LEVEL_II_OPLOCK;
1028 DEBUG(10,("delay_for_oplocks: oplock type 0x%x on file %s\n",
1029 fsp->oplock_type, fsp_str_dbg(fsp)));
1031 /* No delay. */
1032 return false;
1035 bool request_timed_out(struct timeval request_time,
1036 struct timeval timeout)
1038 struct timeval now, end_time;
1039 GetTimeOfDay(&now);
1040 end_time = timeval_sum(&request_time, &timeout);
1041 return (timeval_compare(&end_time, &now) < 0);
1044 /****************************************************************************
1045 Handle the 1 second delay in returning a SHARING_VIOLATION error.
1046 ****************************************************************************/
1048 static void defer_open(struct share_mode_lock *lck,
1049 struct timeval request_time,
1050 struct timeval timeout,
1051 struct smb_request *req,
1052 struct deferred_open_record *state)
1054 int i;
1056 /* Paranoia check */
1058 for (i=0; i<lck->num_share_modes; i++) {
1059 struct share_mode_entry *e = &lck->share_modes[i];
1061 if (!is_deferred_open_entry(e)) {
1062 continue;
1065 if (procid_is_me(&e->pid) && (e->op_mid == req->mid)) {
1066 DEBUG(0, ("Trying to defer an already deferred "
1067 "request: mid=%d, exiting\n", req->mid));
1068 exit_server("attempt to defer a deferred request");
1072 /* End paranoia check */
1074 DEBUG(10,("defer_open_sharing_error: time [%u.%06u] adding deferred "
1075 "open entry for mid %u\n",
1076 (unsigned int)request_time.tv_sec,
1077 (unsigned int)request_time.tv_usec,
1078 (unsigned int)req->mid));
1080 if (!push_deferred_smb_message(req, request_time, timeout,
1081 (char *)state, sizeof(*state))) {
1082 exit_server("push_deferred_smb_message failed");
1084 add_deferred_open(lck, req->mid, request_time, state->id);
1088 /****************************************************************************
1089 On overwrite open ensure that the attributes match.
1090 ****************************************************************************/
1092 bool open_match_attributes(connection_struct *conn,
1093 uint32 old_dos_attr,
1094 uint32 new_dos_attr,
1095 mode_t existing_unx_mode,
1096 mode_t new_unx_mode,
1097 mode_t *returned_unx_mode)
1099 uint32 noarch_old_dos_attr, noarch_new_dos_attr;
1101 noarch_old_dos_attr = (old_dos_attr & ~FILE_ATTRIBUTE_ARCHIVE);
1102 noarch_new_dos_attr = (new_dos_attr & ~FILE_ATTRIBUTE_ARCHIVE);
1104 if((noarch_old_dos_attr == 0 && noarch_new_dos_attr != 0) ||
1105 (noarch_old_dos_attr != 0 && ((noarch_old_dos_attr & noarch_new_dos_attr) == noarch_old_dos_attr))) {
1106 *returned_unx_mode = new_unx_mode;
1107 } else {
1108 *returned_unx_mode = (mode_t)0;
1111 DEBUG(10,("open_match_attributes: old_dos_attr = 0x%x, "
1112 "existing_unx_mode = 0%o, new_dos_attr = 0x%x "
1113 "returned_unx_mode = 0%o\n",
1114 (unsigned int)old_dos_attr,
1115 (unsigned int)existing_unx_mode,
1116 (unsigned int)new_dos_attr,
1117 (unsigned int)*returned_unx_mode ));
1119 /* If we're mapping SYSTEM and HIDDEN ensure they match. */
1120 if (lp_map_system(SNUM(conn)) || lp_store_dos_attributes(SNUM(conn))) {
1121 if ((old_dos_attr & FILE_ATTRIBUTE_SYSTEM) &&
1122 !(new_dos_attr & FILE_ATTRIBUTE_SYSTEM)) {
1123 return False;
1126 if (lp_map_hidden(SNUM(conn)) || lp_store_dos_attributes(SNUM(conn))) {
1127 if ((old_dos_attr & FILE_ATTRIBUTE_HIDDEN) &&
1128 !(new_dos_attr & FILE_ATTRIBUTE_HIDDEN)) {
1129 return False;
1132 return True;
1135 /****************************************************************************
1136 Special FCB or DOS processing in the case of a sharing violation.
1137 Try and find a duplicated file handle.
1138 ****************************************************************************/
1140 NTSTATUS fcb_or_dos_open(struct smb_request *req,
1141 connection_struct *conn,
1142 files_struct *fsp_to_dup_into,
1143 const struct smb_filename *smb_fname,
1144 struct file_id id,
1145 uint16 file_pid,
1146 uint16 vuid,
1147 uint32 access_mask,
1148 uint32 share_access,
1149 uint32 create_options)
1151 files_struct *fsp;
1153 DEBUG(5,("fcb_or_dos_open: attempting old open semantics for "
1154 "file %s.\n", smb_fname_str_dbg(smb_fname)));
1156 for(fsp = file_find_di_first(id); fsp;
1157 fsp = file_find_di_next(fsp)) {
1159 DEBUG(10,("fcb_or_dos_open: checking file %s, fd = %d, "
1160 "vuid = %u, file_pid = %u, private_options = 0x%x "
1161 "access_mask = 0x%x\n", fsp_str_dbg(fsp),
1162 fsp->fh->fd, (unsigned int)fsp->vuid,
1163 (unsigned int)fsp->file_pid,
1164 (unsigned int)fsp->fh->private_options,
1165 (unsigned int)fsp->access_mask ));
1167 if (fsp->fh->fd != -1 &&
1168 fsp->vuid == vuid &&
1169 fsp->file_pid == file_pid &&
1170 (fsp->fh->private_options & (NTCREATEX_OPTIONS_PRIVATE_DENY_DOS |
1171 NTCREATEX_OPTIONS_PRIVATE_DENY_FCB)) &&
1172 (fsp->access_mask & FILE_WRITE_DATA) &&
1173 strequal(fsp->fsp_name->base_name, smb_fname->base_name) &&
1174 strequal(fsp->fsp_name->stream_name,
1175 smb_fname->stream_name)) {
1176 DEBUG(10,("fcb_or_dos_open: file match\n"));
1177 break;
1181 if (!fsp) {
1182 return NT_STATUS_NOT_FOUND;
1185 /* quite an insane set of semantics ... */
1186 if (is_executable(smb_fname->base_name) &&
1187 (fsp->fh->private_options & NTCREATEX_OPTIONS_PRIVATE_DENY_DOS)) {
1188 DEBUG(10,("fcb_or_dos_open: file fail due to is_executable.\n"));
1189 return NT_STATUS_INVALID_PARAMETER;
1192 /* We need to duplicate this fsp. */
1193 return dup_file_fsp(req, fsp, access_mask, share_access,
1194 create_options, fsp_to_dup_into);
1197 /****************************************************************************
1198 Open a file with a share mode - old openX method - map into NTCreate.
1199 ****************************************************************************/
1201 bool map_open_params_to_ntcreate(const struct smb_filename *smb_fname,
1202 int deny_mode, int open_func,
1203 uint32 *paccess_mask,
1204 uint32 *pshare_mode,
1205 uint32 *pcreate_disposition,
1206 uint32 *pcreate_options)
1208 uint32 access_mask;
1209 uint32 share_mode;
1210 uint32 create_disposition;
1211 uint32 create_options = FILE_NON_DIRECTORY_FILE;
1213 DEBUG(10,("map_open_params_to_ntcreate: fname = %s, deny_mode = 0x%x, "
1214 "open_func = 0x%x\n",
1215 smb_fname_str_dbg(smb_fname), (unsigned int)deny_mode,
1216 (unsigned int)open_func ));
1218 /* Create the NT compatible access_mask. */
1219 switch (GET_OPENX_MODE(deny_mode)) {
1220 case DOS_OPEN_EXEC: /* Implies read-only - used to be FILE_READ_DATA */
1221 case DOS_OPEN_RDONLY:
1222 access_mask = FILE_GENERIC_READ;
1223 break;
1224 case DOS_OPEN_WRONLY:
1225 access_mask = FILE_GENERIC_WRITE;
1226 break;
1227 case DOS_OPEN_RDWR:
1228 case DOS_OPEN_FCB:
1229 access_mask = FILE_GENERIC_READ|FILE_GENERIC_WRITE;
1230 break;
1231 default:
1232 DEBUG(10,("map_open_params_to_ntcreate: bad open mode = 0x%x\n",
1233 (unsigned int)GET_OPENX_MODE(deny_mode)));
1234 return False;
1237 /* Create the NT compatible create_disposition. */
1238 switch (open_func) {
1239 case OPENX_FILE_EXISTS_FAIL|OPENX_FILE_CREATE_IF_NOT_EXIST:
1240 create_disposition = FILE_CREATE;
1241 break;
1243 case OPENX_FILE_EXISTS_OPEN:
1244 create_disposition = FILE_OPEN;
1245 break;
1247 case OPENX_FILE_EXISTS_OPEN|OPENX_FILE_CREATE_IF_NOT_EXIST:
1248 create_disposition = FILE_OPEN_IF;
1249 break;
1251 case OPENX_FILE_EXISTS_TRUNCATE:
1252 create_disposition = FILE_OVERWRITE;
1253 break;
1255 case OPENX_FILE_EXISTS_TRUNCATE|OPENX_FILE_CREATE_IF_NOT_EXIST:
1256 create_disposition = FILE_OVERWRITE_IF;
1257 break;
1259 default:
1260 /* From samba4 - to be confirmed. */
1261 if (GET_OPENX_MODE(deny_mode) == DOS_OPEN_EXEC) {
1262 create_disposition = FILE_CREATE;
1263 break;
1265 DEBUG(10,("map_open_params_to_ntcreate: bad "
1266 "open_func 0x%x\n", (unsigned int)open_func));
1267 return False;
1270 /* Create the NT compatible share modes. */
1271 switch (GET_DENY_MODE(deny_mode)) {
1272 case DENY_ALL:
1273 share_mode = FILE_SHARE_NONE;
1274 break;
1276 case DENY_WRITE:
1277 share_mode = FILE_SHARE_READ;
1278 break;
1280 case DENY_READ:
1281 share_mode = FILE_SHARE_WRITE;
1282 break;
1284 case DENY_NONE:
1285 share_mode = FILE_SHARE_READ|FILE_SHARE_WRITE;
1286 break;
1288 case DENY_DOS:
1289 create_options |= NTCREATEX_OPTIONS_PRIVATE_DENY_DOS;
1290 if (is_executable(smb_fname->base_name)) {
1291 share_mode = FILE_SHARE_READ|FILE_SHARE_WRITE;
1292 } else {
1293 if (GET_OPENX_MODE(deny_mode) == DOS_OPEN_RDONLY) {
1294 share_mode = FILE_SHARE_READ;
1295 } else {
1296 share_mode = FILE_SHARE_NONE;
1299 break;
1301 case DENY_FCB:
1302 create_options |= NTCREATEX_OPTIONS_PRIVATE_DENY_FCB;
1303 share_mode = FILE_SHARE_NONE;
1304 break;
1306 default:
1307 DEBUG(10,("map_open_params_to_ntcreate: bad deny_mode 0x%x\n",
1308 (unsigned int)GET_DENY_MODE(deny_mode) ));
1309 return False;
1312 DEBUG(10,("map_open_params_to_ntcreate: file %s, access_mask = 0x%x, "
1313 "share_mode = 0x%x, create_disposition = 0x%x, "
1314 "create_options = 0x%x\n",
1315 smb_fname_str_dbg(smb_fname),
1316 (unsigned int)access_mask,
1317 (unsigned int)share_mode,
1318 (unsigned int)create_disposition,
1319 (unsigned int)create_options ));
1321 if (paccess_mask) {
1322 *paccess_mask = access_mask;
1324 if (pshare_mode) {
1325 *pshare_mode = share_mode;
1327 if (pcreate_disposition) {
1328 *pcreate_disposition = create_disposition;
1330 if (pcreate_options) {
1331 *pcreate_options = create_options;
1334 return True;
1338 static void schedule_defer_open(struct share_mode_lock *lck,
1339 struct timeval request_time,
1340 struct smb_request *req)
1342 struct deferred_open_record state;
1344 /* This is a relative time, added to the absolute
1345 request_time value to get the absolute timeout time.
1346 Note that if this is the second or greater time we enter
1347 this codepath for this particular request mid then
1348 request_time is left as the absolute time of the *first*
1349 time this request mid was processed. This is what allows
1350 the request to eventually time out. */
1352 struct timeval timeout;
1354 /* Normally the smbd we asked should respond within
1355 * OPLOCK_BREAK_TIMEOUT seconds regardless of whether
1356 * the client did, give twice the timeout as a safety
1357 * measure here in case the other smbd is stuck
1358 * somewhere else. */
1360 timeout = timeval_set(OPLOCK_BREAK_TIMEOUT*2, 0);
1362 /* Nothing actually uses state.delayed_for_oplocks
1363 but it's handy to differentiate in debug messages
1364 between a 30 second delay due to oplock break, and
1365 a 1 second delay for share mode conflicts. */
1367 state.delayed_for_oplocks = True;
1368 state.id = lck->id;
1370 if (!request_timed_out(request_time, timeout)) {
1371 defer_open(lck, request_time, timeout, req, &state);
1375 /****************************************************************************
1376 Work out what access_mask to use from what the client sent us.
1377 ****************************************************************************/
1379 static NTSTATUS calculate_access_mask(connection_struct *conn,
1380 const struct smb_filename *smb_fname,
1381 bool file_existed,
1382 uint32_t access_mask,
1383 uint32_t *access_mask_out)
1385 NTSTATUS status;
1388 * Convert GENERIC bits to specific bits.
1391 se_map_generic(&access_mask, &file_generic_mapping);
1393 /* Calculate MAXIMUM_ALLOWED_ACCESS if requested. */
1394 if (access_mask & MAXIMUM_ALLOWED_ACCESS) {
1395 if (file_existed) {
1397 struct security_descriptor *sd;
1398 uint32_t access_granted = 0;
1400 status = SMB_VFS_GET_NT_ACL(conn, smb_fname->base_name,
1401 (OWNER_SECURITY_INFORMATION |
1402 GROUP_SECURITY_INFORMATION |
1403 DACL_SECURITY_INFORMATION),&sd);
1405 if (!NT_STATUS_IS_OK(status)) {
1406 DEBUG(10, ("calculate_access_mask: Could not get acl "
1407 "on file %s: %s\n",
1408 smb_fname_str_dbg(smb_fname),
1409 nt_errstr(status)));
1410 return NT_STATUS_ACCESS_DENIED;
1413 status = smb1_file_se_access_check(sd,
1414 conn->server_info->ptok,
1415 access_mask,
1416 &access_granted);
1418 TALLOC_FREE(sd);
1420 if (!NT_STATUS_IS_OK(status)) {
1421 DEBUG(10, ("calculate_access_mask: Access denied on "
1422 "file %s: when calculating maximum access\n",
1423 smb_fname_str_dbg(smb_fname)));
1424 return NT_STATUS_ACCESS_DENIED;
1427 access_mask = access_granted;
1428 } else {
1429 access_mask = FILE_GENERIC_ALL;
1433 *access_mask_out = access_mask;
1434 return NT_STATUS_OK;
1437 /****************************************************************************
1438 Open a file with a share mode. Passed in an already created files_struct *.
1439 ****************************************************************************/
1441 static NTSTATUS open_file_ntcreate(connection_struct *conn,
1442 struct smb_request *req,
1443 struct smb_filename *smb_fname,
1444 uint32 access_mask, /* access bits (FILE_READ_DATA etc.) */
1445 uint32 share_access, /* share constants (FILE_SHARE_READ etc) */
1446 uint32 create_disposition, /* FILE_OPEN_IF etc. */
1447 uint32 create_options, /* options such as delete on close. */
1448 uint32 new_dos_attributes, /* attributes used for new file. */
1449 int oplock_request, /* internal Samba oplock codes. */
1450 /* Information (FILE_EXISTS etc.) */
1451 int *pinfo,
1452 files_struct *fsp)
1454 int flags=0;
1455 int flags2=0;
1456 bool file_existed = VALID_STAT(smb_fname->st);
1457 bool def_acl = False;
1458 bool posix_open = False;
1459 bool new_file_created = False;
1460 bool clear_ads = false;
1461 struct file_id id;
1462 NTSTATUS fsp_open = NT_STATUS_ACCESS_DENIED;
1463 mode_t new_unx_mode = (mode_t)0;
1464 mode_t unx_mode = (mode_t)0;
1465 int info;
1466 uint32 existing_dos_attributes = 0;
1467 struct pending_message_list *pml = NULL;
1468 struct timeval request_time = timeval_zero();
1469 struct share_mode_lock *lck = NULL;
1470 uint32 open_access_mask = access_mask;
1471 NTSTATUS status;
1472 char *parent_dir;
1474 ZERO_STRUCT(id);
1476 if (conn->printer) {
1478 * Printers are handled completely differently.
1479 * Most of the passed parameters are ignored.
1482 if (pinfo) {
1483 *pinfo = FILE_WAS_CREATED;
1486 DEBUG(10, ("open_file_ntcreate: printer open fname=%s\n",
1487 smb_fname_str_dbg(smb_fname)));
1489 if (!req) {
1490 DEBUG(0,("open_file_ntcreate: printer open without "
1491 "an SMB request!\n"));
1492 return NT_STATUS_INTERNAL_ERROR;
1495 return print_fsp_open(req, conn, smb_fname->base_name,
1496 req->vuid, fsp);
1499 if (!parent_dirname(talloc_tos(), smb_fname->base_name, &parent_dir,
1500 NULL)) {
1501 return NT_STATUS_NO_MEMORY;
1504 if (new_dos_attributes & FILE_FLAG_POSIX_SEMANTICS) {
1505 posix_open = True;
1506 unx_mode = (mode_t)(new_dos_attributes & ~FILE_FLAG_POSIX_SEMANTICS);
1507 new_dos_attributes = 0;
1508 } else {
1509 /* We add aARCH to this as this mode is only used if the file is
1510 * created new. */
1511 unx_mode = unix_mode(conn, new_dos_attributes | aARCH,
1512 smb_fname, parent_dir);
1515 DEBUG(10, ("open_file_ntcreate: fname=%s, dos_attrs=0x%x "
1516 "access_mask=0x%x share_access=0x%x "
1517 "create_disposition = 0x%x create_options=0x%x "
1518 "unix mode=0%o oplock_request=%d\n",
1519 smb_fname_str_dbg(smb_fname), new_dos_attributes,
1520 access_mask, share_access, create_disposition,
1521 create_options, (unsigned int)unx_mode, oplock_request));
1523 if ((req == NULL) && ((oplock_request & INTERNAL_OPEN_ONLY) == 0)) {
1524 DEBUG(0, ("No smb request but not an internal only open!\n"));
1525 return NT_STATUS_INTERNAL_ERROR;
1529 * Only non-internal opens can be deferred at all
1532 if ((req != NULL)
1533 && ((pml = get_open_deferred_message(req->mid)) != NULL)) {
1534 struct deferred_open_record *state =
1535 (struct deferred_open_record *)pml->private_data.data;
1537 /* Remember the absolute time of the original
1538 request with this mid. We'll use it later to
1539 see if this has timed out. */
1541 request_time = pml->request_time;
1543 /* Remove the deferred open entry under lock. */
1544 lck = get_share_mode_lock(talloc_tos(), state->id, NULL, NULL,
1545 NULL);
1546 if (lck == NULL) {
1547 DEBUG(0, ("could not get share mode lock\n"));
1548 } else {
1549 del_deferred_open_entry(lck, req->mid);
1550 TALLOC_FREE(lck);
1553 /* Ensure we don't reprocess this message. */
1554 remove_deferred_open_smb_message(req->mid);
1557 status = check_name(conn, smb_fname->base_name);
1558 if (!NT_STATUS_IS_OK(status)) {
1559 return status;
1562 if (!posix_open) {
1563 new_dos_attributes &= SAMBA_ATTRIBUTES_MASK;
1564 if (file_existed) {
1565 existing_dos_attributes = dos_mode(conn, smb_fname);
1569 /* ignore any oplock requests if oplocks are disabled */
1570 if (!lp_oplocks(SNUM(conn)) || global_client_failed_oplock_break ||
1571 IS_VETO_OPLOCK_PATH(conn, smb_fname->base_name)) {
1572 /* Mask off everything except the private Samba bits. */
1573 oplock_request &= SAMBA_PRIVATE_OPLOCK_MASK;
1576 /* this is for OS/2 long file names - say we don't support them */
1577 if (!lp_posix_pathnames() && strstr(smb_fname->base_name,".+,;=[].")) {
1578 /* OS/2 Workplace shell fix may be main code stream in a later
1579 * release. */
1580 DEBUG(5,("open_file_ntcreate: OS/2 long filenames are not "
1581 "supported.\n"));
1582 if (use_nt_status()) {
1583 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1585 return NT_STATUS_DOS(ERRDOS, ERRcannotopen);
1588 switch( create_disposition ) {
1590 * Currently we're using FILE_SUPERSEDE as the same as
1591 * FILE_OVERWRITE_IF but they really are
1592 * different. FILE_SUPERSEDE deletes an existing file
1593 * (requiring delete access) then recreates it.
1595 case FILE_SUPERSEDE:
1596 /* If file exists replace/overwrite. If file doesn't
1597 * exist create. */
1598 flags2 |= (O_CREAT | O_TRUNC);
1599 clear_ads = true;
1600 break;
1602 case FILE_OVERWRITE_IF:
1603 /* If file exists replace/overwrite. If file doesn't
1604 * exist create. */
1605 flags2 |= (O_CREAT | O_TRUNC);
1606 clear_ads = true;
1607 break;
1609 case FILE_OPEN:
1610 /* If file exists open. If file doesn't exist error. */
1611 if (!file_existed) {
1612 DEBUG(5,("open_file_ntcreate: FILE_OPEN "
1613 "requested for file %s and file "
1614 "doesn't exist.\n",
1615 smb_fname_str_dbg(smb_fname)));
1616 errno = ENOENT;
1617 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1619 break;
1621 case FILE_OVERWRITE:
1622 /* If file exists overwrite. If file doesn't exist
1623 * error. */
1624 if (!file_existed) {
1625 DEBUG(5,("open_file_ntcreate: FILE_OVERWRITE "
1626 "requested for file %s and file "
1627 "doesn't exist.\n",
1628 smb_fname_str_dbg(smb_fname) ));
1629 errno = ENOENT;
1630 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1632 flags2 |= O_TRUNC;
1633 clear_ads = true;
1634 break;
1636 case FILE_CREATE:
1637 /* If file exists error. If file doesn't exist
1638 * create. */
1639 if (file_existed) {
1640 DEBUG(5,("open_file_ntcreate: FILE_CREATE "
1641 "requested for file %s and file "
1642 "already exists.\n",
1643 smb_fname_str_dbg(smb_fname)));
1644 if (S_ISDIR(smb_fname->st.st_ex_mode)) {
1645 errno = EISDIR;
1646 } else {
1647 errno = EEXIST;
1649 return map_nt_error_from_unix(errno);
1651 flags2 |= (O_CREAT|O_EXCL);
1652 break;
1654 case FILE_OPEN_IF:
1655 /* If file exists open. If file doesn't exist
1656 * create. */
1657 flags2 |= O_CREAT;
1658 break;
1660 default:
1661 return NT_STATUS_INVALID_PARAMETER;
1664 /* We only care about matching attributes on file exists and
1665 * overwrite. */
1667 if (!posix_open && file_existed && ((create_disposition == FILE_OVERWRITE) ||
1668 (create_disposition == FILE_OVERWRITE_IF))) {
1669 if (!open_match_attributes(conn, existing_dos_attributes,
1670 new_dos_attributes,
1671 smb_fname->st.st_ex_mode,
1672 unx_mode, &new_unx_mode)) {
1673 DEBUG(5,("open_file_ntcreate: attributes missmatch "
1674 "for file %s (%x %x) (0%o, 0%o)\n",
1675 smb_fname_str_dbg(smb_fname),
1676 existing_dos_attributes,
1677 new_dos_attributes,
1678 (unsigned int)smb_fname->st.st_ex_mode,
1679 (unsigned int)unx_mode ));
1680 errno = EACCES;
1681 return NT_STATUS_ACCESS_DENIED;
1685 status = calculate_access_mask(conn, smb_fname, file_existed,
1686 access_mask,
1687 &access_mask);
1688 if (!NT_STATUS_IS_OK(status)) {
1689 DEBUG(10, ("open_file_ntcreate: calculate_access_mask "
1690 "on file %s returned %s\n",
1691 smb_fname_str_dbg(smb_fname), nt_errstr(status)));
1692 return status;
1695 open_access_mask = access_mask;
1697 if ((flags2 & O_TRUNC) || (oplock_request & FORCE_OPLOCK_BREAK_TO_NONE)) {
1698 open_access_mask |= FILE_WRITE_DATA; /* This will cause oplock breaks. */
1701 DEBUG(10, ("open_file_ntcreate: fname=%s, after mapping "
1702 "access_mask=0x%x\n", smb_fname_str_dbg(smb_fname),
1703 access_mask));
1706 * Note that we ignore the append flag as append does not
1707 * mean the same thing under DOS and Unix.
1710 if ((access_mask & (FILE_WRITE_DATA | FILE_APPEND_DATA)) ||
1711 (oplock_request & FORCE_OPLOCK_BREAK_TO_NONE)) {
1712 /* DENY_DOS opens are always underlying read-write on the
1713 file handle, no matter what the requested access mask
1714 says. */
1715 if ((create_options & NTCREATEX_OPTIONS_PRIVATE_DENY_DOS) ||
1716 access_mask & (FILE_READ_ATTRIBUTES|FILE_READ_DATA|FILE_READ_EA|FILE_EXECUTE)) {
1717 flags = O_RDWR;
1718 } else {
1719 flags = O_WRONLY;
1721 } else {
1722 flags = O_RDONLY;
1726 * Currently we only look at FILE_WRITE_THROUGH for create options.
1729 #if defined(O_SYNC)
1730 if ((create_options & FILE_WRITE_THROUGH) && lp_strict_sync(SNUM(conn))) {
1731 flags2 |= O_SYNC;
1733 #endif /* O_SYNC */
1735 if (posix_open && (access_mask & FILE_APPEND_DATA)) {
1736 flags2 |= O_APPEND;
1739 if (!posix_open && !CAN_WRITE(conn)) {
1741 * We should really return a permission denied error if either
1742 * O_CREAT or O_TRUNC are set, but for compatibility with
1743 * older versions of Samba we just AND them out.
1745 flags2 &= ~(O_CREAT|O_TRUNC);
1749 * Ensure we can't write on a read-only share or file.
1752 if (flags != O_RDONLY && file_existed &&
1753 (!CAN_WRITE(conn) || IS_DOS_READONLY(existing_dos_attributes))) {
1754 DEBUG(5,("open_file_ntcreate: write access requested for "
1755 "file %s on read only %s\n",
1756 smb_fname_str_dbg(smb_fname),
1757 !CAN_WRITE(conn) ? "share" : "file" ));
1758 errno = EACCES;
1759 return NT_STATUS_ACCESS_DENIED;
1762 fsp->file_id = vfs_file_id_from_sbuf(conn, &smb_fname->st);
1763 fsp->share_access = share_access;
1764 fsp->fh->private_options = create_options;
1765 fsp->access_mask = open_access_mask; /* We change this to the
1766 * requested access_mask after
1767 * the open is done. */
1768 fsp->posix_open = posix_open;
1770 /* Ensure no SAMBA_PRIVATE bits can be set. */
1771 fsp->oplock_type = (oplock_request & ~SAMBA_PRIVATE_OPLOCK_MASK);
1773 if (timeval_is_zero(&request_time)) {
1774 request_time = fsp->open_time;
1777 if (file_existed) {
1778 struct timespec old_write_time = smb_fname->st.st_ex_mtime;
1779 id = vfs_file_id_from_sbuf(conn, &smb_fname->st);
1781 lck = get_share_mode_lock(talloc_tos(), id,
1782 conn->connectpath,
1783 smb_fname, &old_write_time);
1785 if (lck == NULL) {
1786 DEBUG(0, ("Could not get share mode lock\n"));
1787 return NT_STATUS_SHARING_VIOLATION;
1790 /* First pass - send break only on batch oplocks. */
1791 if ((req != NULL)
1792 && delay_for_oplocks(lck, fsp, req->mid, 1,
1793 oplock_request)) {
1794 schedule_defer_open(lck, request_time, req);
1795 TALLOC_FREE(lck);
1796 return NT_STATUS_SHARING_VIOLATION;
1799 /* Use the client requested access mask here, not the one we
1800 * open with. */
1801 status = open_mode_check(conn, lck, access_mask, share_access,
1802 create_options, &file_existed);
1804 if (NT_STATUS_IS_OK(status)) {
1805 /* We might be going to allow this open. Check oplock
1806 * status again. */
1807 /* Second pass - send break for both batch or
1808 * exclusive oplocks. */
1809 if ((req != NULL)
1810 && delay_for_oplocks(lck, fsp, req->mid, 2,
1811 oplock_request)) {
1812 schedule_defer_open(lck, request_time, req);
1813 TALLOC_FREE(lck);
1814 return NT_STATUS_SHARING_VIOLATION;
1818 if (NT_STATUS_EQUAL(status, NT_STATUS_DELETE_PENDING)) {
1819 /* DELETE_PENDING is not deferred for a second */
1820 TALLOC_FREE(lck);
1821 return status;
1824 if (!NT_STATUS_IS_OK(status)) {
1825 uint32 can_access_mask;
1826 bool can_access = True;
1828 SMB_ASSERT(NT_STATUS_EQUAL(status, NT_STATUS_SHARING_VIOLATION));
1830 /* Check if this can be done with the deny_dos and fcb
1831 * calls. */
1832 if (create_options &
1833 (NTCREATEX_OPTIONS_PRIVATE_DENY_DOS|
1834 NTCREATEX_OPTIONS_PRIVATE_DENY_FCB)) {
1835 if (req == NULL) {
1836 DEBUG(0, ("DOS open without an SMB "
1837 "request!\n"));
1838 TALLOC_FREE(lck);
1839 return NT_STATUS_INTERNAL_ERROR;
1842 /* Use the client requested access mask here,
1843 * not the one we open with. */
1844 status = fcb_or_dos_open(req,
1845 conn,
1846 fsp,
1847 smb_fname,
1849 req->smbpid,
1850 req->vuid,
1851 access_mask,
1852 share_access,
1853 create_options);
1855 if (NT_STATUS_IS_OK(status)) {
1856 TALLOC_FREE(lck);
1857 if (pinfo) {
1858 *pinfo = FILE_WAS_OPENED;
1860 return NT_STATUS_OK;
1865 * This next line is a subtlety we need for
1866 * MS-Access. If a file open will fail due to share
1867 * permissions and also for security (access) reasons,
1868 * we need to return the access failed error, not the
1869 * share error. We can't open the file due to kernel
1870 * oplock deadlock (it's possible we failed above on
1871 * the open_mode_check()) so use a userspace check.
1874 if (flags & O_RDWR) {
1875 can_access_mask = FILE_READ_DATA|FILE_WRITE_DATA;
1876 } else if (flags & O_WRONLY) {
1877 can_access_mask = FILE_WRITE_DATA;
1878 } else {
1879 can_access_mask = FILE_READ_DATA;
1882 if (((can_access_mask & FILE_WRITE_DATA) &&
1883 !CAN_WRITE(conn)) ||
1884 !can_access_file_data(conn, smb_fname,
1885 can_access_mask)) {
1886 can_access = False;
1890 * If we're returning a share violation, ensure we
1891 * cope with the braindead 1 second delay.
1894 if (!(oplock_request & INTERNAL_OPEN_ONLY) &&
1895 lp_defer_sharing_violations()) {
1896 struct timeval timeout;
1897 struct deferred_open_record state;
1898 int timeout_usecs;
1900 /* this is a hack to speed up torture tests
1901 in 'make test' */
1902 timeout_usecs = lp_parm_int(SNUM(conn),
1903 "smbd","sharedelay",
1904 SHARING_VIOLATION_USEC_WAIT);
1906 /* This is a relative time, added to the absolute
1907 request_time value to get the absolute timeout time.
1908 Note that if this is the second or greater time we enter
1909 this codepath for this particular request mid then
1910 request_time is left as the absolute time of the *first*
1911 time this request mid was processed. This is what allows
1912 the request to eventually time out. */
1914 timeout = timeval_set(0, timeout_usecs);
1916 /* Nothing actually uses state.delayed_for_oplocks
1917 but it's handy to differentiate in debug messages
1918 between a 30 second delay due to oplock break, and
1919 a 1 second delay for share mode conflicts. */
1921 state.delayed_for_oplocks = False;
1922 state.id = id;
1924 if ((req != NULL)
1925 && !request_timed_out(request_time,
1926 timeout)) {
1927 defer_open(lck, request_time, timeout,
1928 req, &state);
1932 TALLOC_FREE(lck);
1933 if (can_access) {
1935 * We have detected a sharing violation here
1936 * so return the correct error code
1938 status = NT_STATUS_SHARING_VIOLATION;
1939 } else {
1940 status = NT_STATUS_ACCESS_DENIED;
1942 return status;
1946 * We exit this block with the share entry *locked*.....
1950 SMB_ASSERT(!file_existed || (lck != NULL));
1953 * Ensure we pay attention to default ACLs on directories if required.
1956 if ((flags2 & O_CREAT) && lp_inherit_acls(SNUM(conn)) &&
1957 (def_acl = directory_has_default_acl(conn, parent_dir))) {
1958 unx_mode = 0777;
1961 DEBUG(4,("calling open_file with flags=0x%X flags2=0x%X mode=0%o, "
1962 "access_mask = 0x%x, open_access_mask = 0x%x\n",
1963 (unsigned int)flags, (unsigned int)flags2,
1964 (unsigned int)unx_mode, (unsigned int)access_mask,
1965 (unsigned int)open_access_mask));
1968 * open_file strips any O_TRUNC flags itself.
1971 fsp_open = open_file(fsp, conn, req, parent_dir, smb_fname,
1972 flags|flags2, unx_mode, access_mask,
1973 open_access_mask);
1975 if (!NT_STATUS_IS_OK(fsp_open)) {
1976 if (lck != NULL) {
1977 TALLOC_FREE(lck);
1979 return fsp_open;
1982 if (!file_existed) {
1983 struct timespec old_write_time = smb_fname->st.st_ex_mtime;
1985 * Deal with the race condition where two smbd's detect the
1986 * file doesn't exist and do the create at the same time. One
1987 * of them will win and set a share mode, the other (ie. this
1988 * one) should check if the requested share mode for this
1989 * create is allowed.
1993 * Now the file exists and fsp is successfully opened,
1994 * fsp->dev and fsp->inode are valid and should replace the
1995 * dev=0,inode=0 from a non existent file. Spotted by
1996 * Nadav Danieli <nadavd@exanet.com>. JRA.
1999 id = fsp->file_id;
2001 lck = get_share_mode_lock(talloc_tos(), id,
2002 conn->connectpath,
2003 smb_fname, &old_write_time);
2005 if (lck == NULL) {
2006 DEBUG(0, ("open_file_ntcreate: Could not get share "
2007 "mode lock for %s\n",
2008 smb_fname_str_dbg(smb_fname)));
2009 fd_close(fsp);
2010 return NT_STATUS_SHARING_VIOLATION;
2013 /* First pass - send break only on batch oplocks. */
2014 if ((req != NULL)
2015 && delay_for_oplocks(lck, fsp, req->mid, 1,
2016 oplock_request)) {
2017 schedule_defer_open(lck, request_time, req);
2018 TALLOC_FREE(lck);
2019 fd_close(fsp);
2020 return NT_STATUS_SHARING_VIOLATION;
2023 status = open_mode_check(conn, lck, access_mask, share_access,
2024 create_options, &file_existed);
2026 if (NT_STATUS_IS_OK(status)) {
2027 /* We might be going to allow this open. Check oplock
2028 * status again. */
2029 /* Second pass - send break for both batch or
2030 * exclusive oplocks. */
2031 if ((req != NULL)
2032 && delay_for_oplocks(lck, fsp, req->mid, 2,
2033 oplock_request)) {
2034 schedule_defer_open(lck, request_time, req);
2035 TALLOC_FREE(lck);
2036 fd_close(fsp);
2037 return NT_STATUS_SHARING_VIOLATION;
2041 if (!NT_STATUS_IS_OK(status)) {
2042 struct deferred_open_record state;
2044 fd_close(fsp);
2046 state.delayed_for_oplocks = False;
2047 state.id = id;
2049 /* Do it all over again immediately. In the second
2050 * round we will find that the file existed and handle
2051 * the DELETE_PENDING and FCB cases correctly. No need
2052 * to duplicate the code here. Essentially this is a
2053 * "goto top of this function", but don't tell
2054 * anybody... */
2056 if (req != NULL) {
2057 defer_open(lck, request_time, timeval_zero(),
2058 req, &state);
2060 TALLOC_FREE(lck);
2061 return status;
2065 * We exit this block with the share entry *locked*.....
2070 SMB_ASSERT(lck != NULL);
2072 /* Delete streams if create_disposition requires it */
2073 if (file_existed && clear_ads &&
2074 !is_ntfs_stream_smb_fname(smb_fname)) {
2075 status = delete_all_streams(conn, smb_fname->base_name);
2076 if (!NT_STATUS_IS_OK(status)) {
2077 TALLOC_FREE(lck);
2078 fd_close(fsp);
2079 return status;
2083 /* note that we ignore failure for the following. It is
2084 basically a hack for NFS, and NFS will never set one of
2085 these only read them. Nobody but Samba can ever set a deny
2086 mode and we have already checked our more authoritative
2087 locking database for permission to set this deny mode. If
2088 the kernel refuses the operations then the kernel is wrong.
2089 note that GPFS supports it as well - jmcd */
2091 if (fsp->fh->fd != -1) {
2092 int ret_flock;
2093 ret_flock = SMB_VFS_KERNEL_FLOCK(fsp, share_access, access_mask);
2094 if(ret_flock == -1 ){
2096 TALLOC_FREE(lck);
2097 fd_close(fsp);
2099 return NT_STATUS_SHARING_VIOLATION;
2104 * At this point onwards, we can guarentee that the share entry
2105 * is locked, whether we created the file or not, and that the
2106 * deny mode is compatible with all current opens.
2110 * If requested, truncate the file.
2113 if (flags2&O_TRUNC) {
2115 * We are modifing the file after open - update the stat
2116 * struct..
2118 if ((SMB_VFS_FTRUNCATE(fsp, 0) == -1) ||
2119 (SMB_VFS_FSTAT(fsp, &smb_fname->st)==-1)) {
2120 status = map_nt_error_from_unix(errno);
2121 TALLOC_FREE(lck);
2122 fd_close(fsp);
2123 return status;
2127 /* Record the options we were opened with. */
2128 fsp->share_access = share_access;
2129 fsp->fh->private_options = create_options;
2131 * According to Samba4, SEC_FILE_READ_ATTRIBUTE is always granted,
2133 fsp->access_mask = access_mask | FILE_READ_ATTRIBUTES;
2135 if (file_existed) {
2136 /* stat opens on existing files don't get oplocks. */
2137 if (is_stat_open(open_access_mask)) {
2138 fsp->oplock_type = NO_OPLOCK;
2141 if (!(flags2 & O_TRUNC)) {
2142 info = FILE_WAS_OPENED;
2143 } else {
2144 info = FILE_WAS_OVERWRITTEN;
2146 } else {
2147 info = FILE_WAS_CREATED;
2150 if (pinfo) {
2151 *pinfo = info;
2155 * Setup the oplock info in both the shared memory and
2156 * file structs.
2159 if (!set_file_oplock(fsp, fsp->oplock_type)) {
2160 /* Could not get the kernel oplock */
2161 fsp->oplock_type = NO_OPLOCK;
2164 if (info == FILE_WAS_OVERWRITTEN || info == FILE_WAS_CREATED || info == FILE_WAS_SUPERSEDED) {
2165 new_file_created = True;
2168 set_share_mode(lck, fsp, conn->server_info->utok.uid, 0,
2169 fsp->oplock_type);
2171 /* Handle strange delete on close create semantics. */
2172 if (create_options & FILE_DELETE_ON_CLOSE) {
2174 status = can_set_delete_on_close(fsp, new_dos_attributes);
2176 if (!NT_STATUS_IS_OK(status)) {
2177 /* Remember to delete the mode we just added. */
2178 del_share_mode(lck, fsp);
2179 TALLOC_FREE(lck);
2180 fd_close(fsp);
2181 return status;
2183 /* Note that here we set the *inital* delete on close flag,
2184 not the regular one. The magic gets handled in close. */
2185 fsp->initial_delete_on_close = True;
2188 if (new_file_created) {
2189 /* Files should be initially set as archive */
2190 if (lp_map_archive(SNUM(conn)) ||
2191 lp_store_dos_attributes(SNUM(conn))) {
2192 if (!posix_open) {
2193 if (file_set_dosmode(conn, smb_fname,
2194 new_dos_attributes | aARCH,
2195 parent_dir, true) == 0) {
2196 unx_mode = smb_fname->st.st_ex_mode;
2203 * Take care of inherited ACLs on created files - if default ACL not
2204 * selected.
2207 if (!posix_open && !file_existed && !def_acl) {
2209 int saved_errno = errno; /* We might get ENOSYS in the next
2210 * call.. */
2212 if (SMB_VFS_FCHMOD_ACL(fsp, unx_mode) == -1 &&
2213 errno == ENOSYS) {
2214 errno = saved_errno; /* Ignore ENOSYS */
2217 } else if (new_unx_mode) {
2219 int ret = -1;
2221 /* Attributes need changing. File already existed. */
2224 int saved_errno = errno; /* We might get ENOSYS in the
2225 * next call.. */
2226 ret = SMB_VFS_FCHMOD_ACL(fsp, new_unx_mode);
2228 if (ret == -1 && errno == ENOSYS) {
2229 errno = saved_errno; /* Ignore ENOSYS */
2230 } else {
2231 DEBUG(5, ("open_file_ntcreate: reset "
2232 "attributes of file %s to 0%o\n",
2233 smb_fname_str_dbg(smb_fname),
2234 (unsigned int)new_unx_mode));
2235 ret = 0; /* Don't do the fchmod below. */
2239 if ((ret == -1) &&
2240 (SMB_VFS_FCHMOD(fsp, new_unx_mode) == -1))
2241 DEBUG(5, ("open_file_ntcreate: failed to reset "
2242 "attributes of file %s to 0%o\n",
2243 smb_fname_str_dbg(smb_fname),
2244 (unsigned int)new_unx_mode));
2247 /* If this is a successful open, we must remove any deferred open
2248 * records. */
2249 if (req != NULL) {
2250 del_deferred_open_entry(lck, req->mid);
2252 TALLOC_FREE(lck);
2254 return NT_STATUS_OK;
2258 /****************************************************************************
2259 Open a file for for write to ensure that we can fchmod it.
2260 ****************************************************************************/
2262 NTSTATUS open_file_fchmod(struct smb_request *req, connection_struct *conn,
2263 struct smb_filename *smb_fname,
2264 files_struct **result)
2266 files_struct *fsp = NULL;
2267 NTSTATUS status;
2269 if (!VALID_STAT(smb_fname->st)) {
2270 return NT_STATUS_INVALID_PARAMETER;
2273 status = file_new(req, conn, &fsp);
2274 if(!NT_STATUS_IS_OK(status)) {
2275 return status;
2278 status = SMB_VFS_CREATE_FILE(
2279 conn, /* conn */
2280 NULL, /* req */
2281 0, /* root_dir_fid */
2282 smb_fname, /* fname */
2283 FILE_WRITE_DATA, /* access_mask */
2284 (FILE_SHARE_READ | FILE_SHARE_WRITE | /* share_access */
2285 FILE_SHARE_DELETE),
2286 FILE_OPEN, /* create_disposition*/
2287 0, /* create_options */
2288 0, /* file_attributes */
2289 0, /* oplock_request */
2290 0, /* allocation_size */
2291 NULL, /* sd */
2292 NULL, /* ea_list */
2293 &fsp, /* result */
2294 NULL); /* pinfo */
2297 * This is not a user visible file open.
2298 * Don't set a share mode.
2301 if (!NT_STATUS_IS_OK(status)) {
2302 file_free(req, fsp);
2303 return status;
2306 *result = fsp;
2307 return NT_STATUS_OK;
2310 /****************************************************************************
2311 Close the fchmod file fd - ensure no locks are lost.
2312 ****************************************************************************/
2314 NTSTATUS close_file_fchmod(struct smb_request *req, files_struct *fsp)
2316 NTSTATUS status = fd_close(fsp);
2317 file_free(req, fsp);
2318 return status;
2321 static NTSTATUS mkdir_internal(connection_struct *conn,
2322 struct smb_filename *smb_dname,
2323 uint32 file_attributes)
2325 mode_t mode;
2326 char *parent_dir;
2327 NTSTATUS status;
2328 bool posix_open = false;
2330 if(!CAN_WRITE(conn)) {
2331 DEBUG(5,("mkdir_internal: failing create on read-only share "
2332 "%s\n", lp_servicename(SNUM(conn))));
2333 return NT_STATUS_ACCESS_DENIED;
2336 status = check_name(conn, smb_dname->base_name);
2337 if (!NT_STATUS_IS_OK(status)) {
2338 return status;
2341 if (!parent_dirname(talloc_tos(), smb_dname->base_name, &parent_dir,
2342 NULL)) {
2343 return NT_STATUS_NO_MEMORY;
2346 if (file_attributes & FILE_FLAG_POSIX_SEMANTICS) {
2347 posix_open = true;
2348 mode = (mode_t)(file_attributes & ~FILE_FLAG_POSIX_SEMANTICS);
2349 } else {
2350 mode = unix_mode(conn, aDIR, smb_dname, parent_dir);
2353 if (SMB_VFS_MKDIR(conn, smb_dname->base_name, mode) != 0) {
2354 return map_nt_error_from_unix(errno);
2357 /* Ensure we're checking for a symlink here.... */
2358 /* We don't want to get caught by a symlink racer. */
2360 if (SMB_VFS_LSTAT(conn, smb_dname) == -1) {
2361 DEBUG(2, ("Could not stat directory '%s' just created: %s\n",
2362 smb_fname_str_dbg(smb_dname), strerror(errno)));
2363 return map_nt_error_from_unix(errno);
2366 if (!S_ISDIR(smb_dname->st.st_ex_mode)) {
2367 DEBUG(0, ("Directory just '%s' created is not a directory\n",
2368 smb_fname_str_dbg(smb_dname)));
2369 return NT_STATUS_ACCESS_DENIED;
2372 if (lp_store_dos_attributes(SNUM(conn))) {
2373 if (!posix_open) {
2374 file_set_dosmode(conn, smb_dname,
2375 file_attributes | aDIR,
2376 parent_dir, true);
2380 if (lp_inherit_perms(SNUM(conn))) {
2381 inherit_access_posix_acl(conn, parent_dir,
2382 smb_dname->base_name, mode);
2385 if (!posix_open) {
2387 * Check if high bits should have been set,
2388 * then (if bits are missing): add them.
2389 * Consider bits automagically set by UNIX, i.e. SGID bit from parent
2390 * dir.
2392 if ((mode & ~(S_IRWXU|S_IRWXG|S_IRWXO)) &&
2393 (mode & ~smb_dname->st.st_ex_mode)) {
2394 SMB_VFS_CHMOD(conn, smb_dname->base_name,
2395 (smb_dname->st.st_ex_mode |
2396 (mode & ~smb_dname->st.st_ex_mode)));
2400 /* Change the owner if required. */
2401 if (lp_inherit_owner(SNUM(conn))) {
2402 change_dir_owner_to_parent(conn, parent_dir,
2403 smb_dname->base_name,
2404 &smb_dname->st);
2407 notify_fname(conn, NOTIFY_ACTION_ADDED, FILE_NOTIFY_CHANGE_DIR_NAME,
2408 smb_dname->base_name);
2410 return NT_STATUS_OK;
2413 /****************************************************************************
2414 Open a directory from an NT SMB call.
2415 ****************************************************************************/
2417 static NTSTATUS open_directory(connection_struct *conn,
2418 struct smb_request *req,
2419 struct smb_filename *smb_dname,
2420 uint32 access_mask,
2421 uint32 share_access,
2422 uint32 create_disposition,
2423 uint32 create_options,
2424 uint32 file_attributes,
2425 int *pinfo,
2426 files_struct **result)
2428 files_struct *fsp = NULL;
2429 bool dir_existed = VALID_STAT(smb_dname->st) ? True : False;
2430 struct share_mode_lock *lck = NULL;
2431 NTSTATUS status;
2432 struct timespec mtimespec;
2433 int info = 0;
2435 SMB_ASSERT(!is_ntfs_stream_smb_fname(smb_dname));
2437 DEBUG(5,("open_directory: opening directory %s, access_mask = 0x%x, "
2438 "share_access = 0x%x create_options = 0x%x, "
2439 "create_disposition = 0x%x, file_attributes = 0x%x\n",
2440 smb_fname_str_dbg(smb_dname),
2441 (unsigned int)access_mask,
2442 (unsigned int)share_access,
2443 (unsigned int)create_options,
2444 (unsigned int)create_disposition,
2445 (unsigned int)file_attributes));
2447 if (!(file_attributes & FILE_FLAG_POSIX_SEMANTICS) &&
2448 (conn->fs_capabilities & FILE_NAMED_STREAMS) &&
2449 is_ntfs_stream_smb_fname(smb_dname)) {
2450 DEBUG(2, ("open_directory: %s is a stream name!\n",
2451 smb_fname_str_dbg(smb_dname)));
2452 return NT_STATUS_NOT_A_DIRECTORY;
2455 status = calculate_access_mask(conn, smb_dname, dir_existed,
2456 access_mask, &access_mask);
2457 if (!NT_STATUS_IS_OK(status)) {
2458 DEBUG(10, ("open_directory: calculate_access_mask "
2459 "on file %s returned %s\n",
2460 smb_fname_str_dbg(smb_dname),
2461 nt_errstr(status)));
2462 return status;
2465 /* We need to support SeSecurityPrivilege for this. */
2466 if (access_mask & SEC_FLAG_SYSTEM_SECURITY) {
2467 DEBUG(10, ("open_directory: open on %s "
2468 "failed - SEC_FLAG_SYSTEM_SECURITY denied.\n",
2469 smb_fname_str_dbg(smb_dname)));
2470 return NT_STATUS_PRIVILEGE_NOT_HELD;
2473 switch( create_disposition ) {
2474 case FILE_OPEN:
2476 info = FILE_WAS_OPENED;
2479 * We want to follow symlinks here.
2482 if (SMB_VFS_STAT(conn, smb_dname) != 0) {
2483 return map_nt_error_from_unix(errno);
2486 break;
2488 case FILE_CREATE:
2490 /* If directory exists error. If directory doesn't
2491 * exist create. */
2493 status = mkdir_internal(conn, smb_dname,
2494 file_attributes);
2496 if (!NT_STATUS_IS_OK(status)) {
2497 DEBUG(2, ("open_directory: unable to create "
2498 "%s. Error was %s\n",
2499 smb_fname_str_dbg(smb_dname),
2500 nt_errstr(status)));
2501 return status;
2504 info = FILE_WAS_CREATED;
2505 break;
2507 case FILE_OPEN_IF:
2509 * If directory exists open. If directory doesn't
2510 * exist create.
2513 status = mkdir_internal(conn, smb_dname,
2514 file_attributes);
2516 if (NT_STATUS_IS_OK(status)) {
2517 info = FILE_WAS_CREATED;
2520 if (NT_STATUS_EQUAL(status,
2521 NT_STATUS_OBJECT_NAME_COLLISION)) {
2522 info = FILE_WAS_OPENED;
2523 status = NT_STATUS_OK;
2526 break;
2528 case FILE_SUPERSEDE:
2529 case FILE_OVERWRITE:
2530 case FILE_OVERWRITE_IF:
2531 default:
2532 DEBUG(5,("open_directory: invalid create_disposition "
2533 "0x%x for directory %s\n",
2534 (unsigned int)create_disposition,
2535 smb_fname_str_dbg(smb_dname)));
2536 return NT_STATUS_INVALID_PARAMETER;
2539 if(!S_ISDIR(smb_dname->st.st_ex_mode)) {
2540 DEBUG(5,("open_directory: %s is not a directory !\n",
2541 smb_fname_str_dbg(smb_dname)));
2542 return NT_STATUS_NOT_A_DIRECTORY;
2545 if (info == FILE_WAS_OPENED) {
2546 uint32_t access_granted = 0;
2547 status = smbd_check_open_rights(conn, smb_dname, access_mask,
2548 &access_granted);
2550 /* Were we trying to do a directory open
2551 * for delete and didn't get DELETE
2552 * access (only) ? Check if the
2553 * directory allows DELETE_CHILD.
2554 * See here:
2555 * http://blogs.msdn.com/oldnewthing/archive/2004/06/04/148426.aspx
2556 * for details. */
2558 if ((NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED) &&
2559 (access_mask & DELETE_ACCESS) &&
2560 (access_granted == DELETE_ACCESS) &&
2561 can_delete_file_in_directory(conn, smb_dname))) {
2562 DEBUG(10,("open_directory: overrode ACCESS_DENIED "
2563 "on directory %s\n",
2564 smb_fname_str_dbg(smb_dname)));
2565 status = NT_STATUS_OK;
2568 if (!NT_STATUS_IS_OK(status)) {
2569 DEBUG(10, ("open_directory: smbd_check_open_rights on "
2570 "file %s failed with %s\n",
2571 smb_fname_str_dbg(smb_dname),
2572 nt_errstr(status)));
2573 return status;
2577 status = file_new(req, conn, &fsp);
2578 if(!NT_STATUS_IS_OK(status)) {
2579 return status;
2583 * Setup the files_struct for it.
2586 fsp->mode = smb_dname->st.st_ex_mode;
2587 fsp->file_id = vfs_file_id_from_sbuf(conn, &smb_dname->st);
2588 fsp->vuid = req ? req->vuid : UID_FIELD_INVALID;
2589 fsp->file_pid = req ? req->smbpid : 0;
2590 fsp->can_lock = False;
2591 fsp->can_read = False;
2592 fsp->can_write = False;
2594 fsp->share_access = share_access;
2595 fsp->fh->private_options = create_options;
2597 * According to Samba4, SEC_FILE_READ_ATTRIBUTE is always granted,
2599 fsp->access_mask = access_mask | FILE_READ_ATTRIBUTES;
2600 fsp->print_file = False;
2601 fsp->modified = False;
2602 fsp->oplock_type = NO_OPLOCK;
2603 fsp->sent_oplock_break = NO_BREAK_SENT;
2604 fsp->is_directory = True;
2605 fsp->posix_open = (file_attributes & FILE_FLAG_POSIX_SEMANTICS) ? True : False;
2606 status = fsp_set_smb_fname(fsp, smb_dname);
2607 if (!NT_STATUS_IS_OK(status)) {
2608 return status;
2611 mtimespec = smb_dname->st.st_ex_mtime;
2613 lck = get_share_mode_lock(talloc_tos(), fsp->file_id,
2614 conn->connectpath, smb_dname, &mtimespec);
2616 if (lck == NULL) {
2617 DEBUG(0, ("open_directory: Could not get share mode lock for "
2618 "%s\n", smb_fname_str_dbg(smb_dname)));
2619 file_free(req, fsp);
2620 return NT_STATUS_SHARING_VIOLATION;
2623 status = open_mode_check(conn, lck, access_mask, share_access,
2624 create_options, &dir_existed);
2626 if (!NT_STATUS_IS_OK(status)) {
2627 TALLOC_FREE(lck);
2628 file_free(req, fsp);
2629 return status;
2632 set_share_mode(lck, fsp, conn->server_info->utok.uid, 0, NO_OPLOCK);
2634 /* For directories the delete on close bit at open time seems
2635 always to be honored on close... See test 19 in Samba4 BASE-DELETE. */
2636 if (create_options & FILE_DELETE_ON_CLOSE) {
2637 status = can_set_delete_on_close(fsp, 0);
2638 if (!NT_STATUS_IS_OK(status) && !NT_STATUS_EQUAL(status, NT_STATUS_DIRECTORY_NOT_EMPTY)) {
2639 TALLOC_FREE(lck);
2640 file_free(req, fsp);
2641 return status;
2644 if (NT_STATUS_IS_OK(status)) {
2645 /* Note that here we set the *inital* delete on close flag,
2646 not the regular one. The magic gets handled in close. */
2647 fsp->initial_delete_on_close = True;
2651 TALLOC_FREE(lck);
2653 if (pinfo) {
2654 *pinfo = info;
2657 *result = fsp;
2658 return NT_STATUS_OK;
2661 NTSTATUS create_directory(connection_struct *conn, struct smb_request *req,
2662 struct smb_filename *smb_dname)
2664 NTSTATUS status;
2665 files_struct *fsp;
2667 status = SMB_VFS_CREATE_FILE(
2668 conn, /* conn */
2669 req, /* req */
2670 0, /* root_dir_fid */
2671 smb_dname, /* fname */
2672 FILE_READ_ATTRIBUTES, /* access_mask */
2673 FILE_SHARE_NONE, /* share_access */
2674 FILE_CREATE, /* create_disposition*/
2675 FILE_DIRECTORY_FILE, /* create_options */
2676 FILE_ATTRIBUTE_DIRECTORY, /* file_attributes */
2677 0, /* oplock_request */
2678 0, /* allocation_size */
2679 NULL, /* sd */
2680 NULL, /* ea_list */
2681 &fsp, /* result */
2682 NULL); /* pinfo */
2684 if (NT_STATUS_IS_OK(status)) {
2685 close_file(req, fsp, NORMAL_CLOSE);
2688 return status;
2691 /****************************************************************************
2692 Receive notification that one of our open files has been renamed by another
2693 smbd process.
2694 ****************************************************************************/
2696 void msg_file_was_renamed(struct messaging_context *msg,
2697 void *private_data,
2698 uint32_t msg_type,
2699 struct server_id server_id,
2700 DATA_BLOB *data)
2702 files_struct *fsp;
2703 char *frm = (char *)data->data;
2704 struct file_id id;
2705 const char *sharepath;
2706 const char *base_name;
2707 const char *stream_name;
2708 struct smb_filename *smb_fname = NULL;
2709 size_t sp_len, bn_len;
2710 NTSTATUS status;
2712 if (data->data == NULL
2713 || data->length < MSG_FILE_RENAMED_MIN_SIZE + 2) {
2714 DEBUG(0, ("msg_file_was_renamed: Got invalid msg len %d\n",
2715 (int)data->length));
2716 return;
2719 /* Unpack the message. */
2720 pull_file_id_24(frm, &id);
2721 sharepath = &frm[24];
2722 sp_len = strlen(sharepath);
2723 base_name = sharepath + sp_len + 1;
2724 bn_len = strlen(base_name);
2725 stream_name = sharepath + sp_len + 1 + bn_len + 1;
2727 /* stream_name must always be NULL if there is no stream. */
2728 if (stream_name[0] == '\0') {
2729 stream_name = NULL;
2732 status = create_synthetic_smb_fname(talloc_tos(), base_name,
2733 stream_name, NULL, &smb_fname);
2734 if (!NT_STATUS_IS_OK(status)) {
2735 return;
2738 DEBUG(10,("msg_file_was_renamed: Got rename message for sharepath %s, new name %s, "
2739 "file_id %s\n",
2740 sharepath, smb_fname_str_dbg(smb_fname),
2741 file_id_string_tos(&id)));
2743 for(fsp = file_find_di_first(id); fsp; fsp = file_find_di_next(fsp)) {
2744 if (memcmp(fsp->conn->connectpath, sharepath, sp_len) == 0) {
2746 DEBUG(10,("msg_file_was_renamed: renaming file fnum %d from %s -> %s\n",
2747 fsp->fnum, fsp_str_dbg(fsp),
2748 smb_fname_str_dbg(smb_fname)));
2749 status = fsp_set_smb_fname(fsp, smb_fname);
2750 if (!NT_STATUS_IS_OK(status)) {
2751 goto out;
2753 } else {
2754 /* TODO. JRA. */
2755 /* Now we have the complete path we can work out if this is
2756 actually within this share and adjust newname accordingly. */
2757 DEBUG(10,("msg_file_was_renamed: share mismatch (sharepath %s "
2758 "not sharepath %s) "
2759 "fnum %d from %s -> %s\n",
2760 fsp->conn->connectpath,
2761 sharepath,
2762 fsp->fnum,
2763 fsp_str_dbg(fsp),
2764 smb_fname_str_dbg(smb_fname)));
2767 out:
2768 TALLOC_FREE(smb_fname);
2769 return;
2773 * If a main file is opened for delete, all streams need to be checked for
2774 * !FILE_SHARE_DELETE. Do this by opening with DELETE_ACCESS.
2775 * If that works, delete them all by setting the delete on close and close.
2778 NTSTATUS open_streams_for_delete(connection_struct *conn,
2779 const char *fname)
2781 struct stream_struct *stream_info;
2782 files_struct **streams;
2783 int i;
2784 unsigned int num_streams;
2785 TALLOC_CTX *frame = talloc_stackframe();
2786 NTSTATUS status;
2788 status = SMB_VFS_STREAMINFO(conn, NULL, fname, talloc_tos(),
2789 &num_streams, &stream_info);
2791 if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_IMPLEMENTED)
2792 || NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
2793 DEBUG(10, ("no streams around\n"));
2794 TALLOC_FREE(frame);
2795 return NT_STATUS_OK;
2798 if (!NT_STATUS_IS_OK(status)) {
2799 DEBUG(10, ("SMB_VFS_STREAMINFO failed: %s\n",
2800 nt_errstr(status)));
2801 goto fail;
2804 DEBUG(10, ("open_streams_for_delete found %d streams\n",
2805 num_streams));
2807 if (num_streams == 0) {
2808 TALLOC_FREE(frame);
2809 return NT_STATUS_OK;
2812 streams = TALLOC_ARRAY(talloc_tos(), files_struct *, num_streams);
2813 if (streams == NULL) {
2814 DEBUG(0, ("talloc failed\n"));
2815 status = NT_STATUS_NO_MEMORY;
2816 goto fail;
2819 for (i=0; i<num_streams; i++) {
2820 struct smb_filename *smb_fname = NULL;
2822 if (strequal(stream_info[i].name, "::$DATA")) {
2823 streams[i] = NULL;
2824 continue;
2827 status = create_synthetic_smb_fname(talloc_tos(), fname,
2828 stream_info[i].name,
2829 NULL, &smb_fname);
2830 if (!NT_STATUS_IS_OK(status)) {
2831 goto fail;
2834 if (SMB_VFS_STAT(conn, smb_fname) == -1) {
2835 DEBUG(10, ("Unable to stat stream: %s\n",
2836 smb_fname_str_dbg(smb_fname)));
2839 status = SMB_VFS_CREATE_FILE(
2840 conn, /* conn */
2841 NULL, /* req */
2842 0, /* root_dir_fid */
2843 smb_fname, /* fname */
2844 DELETE_ACCESS, /* access_mask */
2845 (FILE_SHARE_READ | /* share_access */
2846 FILE_SHARE_WRITE | FILE_SHARE_DELETE),
2847 FILE_OPEN, /* create_disposition*/
2848 NTCREATEX_OPTIONS_PRIVATE_STREAM_DELETE, /* create_options */
2849 FILE_ATTRIBUTE_NORMAL, /* file_attributes */
2850 0, /* oplock_request */
2851 0, /* allocation_size */
2852 NULL, /* sd */
2853 NULL, /* ea_list */
2854 &streams[i], /* result */
2855 NULL); /* pinfo */
2857 if (!NT_STATUS_IS_OK(status)) {
2858 DEBUG(10, ("Could not open stream %s: %s\n",
2859 smb_fname_str_dbg(smb_fname),
2860 nt_errstr(status)));
2862 TALLOC_FREE(smb_fname);
2863 break;
2865 TALLOC_FREE(smb_fname);
2869 * don't touch the variable "status" beyond this point :-)
2872 for (i -= 1 ; i >= 0; i--) {
2873 if (streams[i] == NULL) {
2874 continue;
2877 DEBUG(10, ("Closing stream # %d, %s\n", i,
2878 fsp_str_dbg(streams[i])));
2879 close_file(NULL, streams[i], NORMAL_CLOSE);
2882 fail:
2883 TALLOC_FREE(frame);
2884 return status;
2888 * Wrapper around open_file_ntcreate and open_directory
2891 static NTSTATUS create_file_unixpath(connection_struct *conn,
2892 struct smb_request *req,
2893 struct smb_filename *smb_fname,
2894 uint32_t access_mask,
2895 uint32_t share_access,
2896 uint32_t create_disposition,
2897 uint32_t create_options,
2898 uint32_t file_attributes,
2899 uint32_t oplock_request,
2900 uint64_t allocation_size,
2901 struct security_descriptor *sd,
2902 struct ea_list *ea_list,
2904 files_struct **result,
2905 int *pinfo)
2907 int info = FILE_WAS_OPENED;
2908 files_struct *base_fsp = NULL;
2909 files_struct *fsp = NULL;
2910 NTSTATUS status;
2912 DEBUG(10,("create_file_unixpath: access_mask = 0x%x "
2913 "file_attributes = 0x%x, share_access = 0x%x, "
2914 "create_disposition = 0x%x create_options = 0x%x "
2915 "oplock_request = 0x%x ea_list = 0x%p, sd = 0x%p, "
2916 "fname = %s\n",
2917 (unsigned int)access_mask,
2918 (unsigned int)file_attributes,
2919 (unsigned int)share_access,
2920 (unsigned int)create_disposition,
2921 (unsigned int)create_options,
2922 (unsigned int)oplock_request,
2923 ea_list, sd, smb_fname_str_dbg(smb_fname)));
2925 if (create_options & FILE_OPEN_BY_FILE_ID) {
2926 status = NT_STATUS_NOT_SUPPORTED;
2927 goto fail;
2930 if (create_options & NTCREATEX_OPTIONS_INVALID_PARAM_MASK) {
2931 status = NT_STATUS_INVALID_PARAMETER;
2932 goto fail;
2935 if (req == NULL) {
2936 oplock_request |= INTERNAL_OPEN_ONLY;
2939 if ((conn->fs_capabilities & FILE_NAMED_STREAMS)
2940 && (access_mask & DELETE_ACCESS)
2941 && !is_ntfs_stream_smb_fname(smb_fname)) {
2943 * We can't open a file with DELETE access if any of the
2944 * streams is open without FILE_SHARE_DELETE
2946 status = open_streams_for_delete(conn, smb_fname->base_name);
2948 if (!NT_STATUS_IS_OK(status)) {
2949 goto fail;
2953 /* This is the correct thing to do (check every time) but can_delete
2954 * is expensive (it may have to read the parent directory
2955 * permissions). So for now we're not doing it unless we have a strong
2956 * hint the client is really going to delete this file. If the client
2957 * is forcing FILE_CREATE let the filesystem take care of the
2958 * permissions. */
2960 /* Setting FILE_SHARE_DELETE is the hint. */
2962 if (lp_acl_check_permissions(SNUM(conn))
2963 && (create_disposition != FILE_CREATE)
2964 && (share_access & FILE_SHARE_DELETE)
2965 && (access_mask & DELETE_ACCESS)
2966 && (!(can_delete_file_in_directory(conn, smb_fname) ||
2967 can_access_file_acl(conn, smb_fname, DELETE_ACCESS)))) {
2968 status = NT_STATUS_ACCESS_DENIED;
2969 DEBUG(10,("create_file_unixpath: open file %s "
2970 "for delete ACCESS_DENIED\n",
2971 smb_fname_str_dbg(smb_fname)));
2972 goto fail;
2975 #if 0
2976 /* We need to support SeSecurityPrivilege for this. */
2977 if ((access_mask & SEC_FLAG_SYSTEM_SECURITY) &&
2978 !user_has_privileges(current_user.nt_user_token,
2979 &se_security)) {
2980 status = NT_STATUS_PRIVILEGE_NOT_HELD;
2981 goto fail;
2983 #else
2984 /* We need to support SeSecurityPrivilege for this. */
2985 if (access_mask & SEC_FLAG_SYSTEM_SECURITY) {
2986 status = NT_STATUS_PRIVILEGE_NOT_HELD;
2987 goto fail;
2989 /* Don't allow a SACL set from an NTtrans create until we
2990 * support SeSecurityPrivilege. */
2991 if (!VALID_STAT(smb_fname->st) &&
2992 lp_nt_acl_support(SNUM(conn)) &&
2993 sd && (sd->sacl != NULL)) {
2994 status = NT_STATUS_PRIVILEGE_NOT_HELD;
2995 goto fail;
2997 #endif
2999 if ((conn->fs_capabilities & FILE_NAMED_STREAMS)
3000 && is_ntfs_stream_smb_fname(smb_fname)
3001 && (!(create_options & NTCREATEX_OPTIONS_PRIVATE_STREAM_DELETE))) {
3002 uint32 base_create_disposition;
3003 struct smb_filename *smb_fname_base = NULL;
3005 if (create_options & FILE_DIRECTORY_FILE) {
3006 status = NT_STATUS_NOT_A_DIRECTORY;
3007 goto fail;
3010 switch (create_disposition) {
3011 case FILE_OPEN:
3012 base_create_disposition = FILE_OPEN;
3013 break;
3014 default:
3015 base_create_disposition = FILE_OPEN_IF;
3016 break;
3019 /* Create an smb_filename with stream_name == NULL. */
3020 status = create_synthetic_smb_fname(talloc_tos(),
3021 smb_fname->base_name,
3022 NULL, NULL,
3023 &smb_fname_base);
3024 if (!NT_STATUS_IS_OK(status)) {
3025 goto fail;
3028 if (SMB_VFS_STAT(conn, smb_fname_base) == -1) {
3029 DEBUG(10, ("Unable to stat stream: %s\n",
3030 smb_fname_str_dbg(smb_fname_base)));
3033 /* Open the base file. */
3034 status = create_file_unixpath(conn, NULL, smb_fname_base, 0,
3035 FILE_SHARE_READ
3036 | FILE_SHARE_WRITE
3037 | FILE_SHARE_DELETE,
3038 base_create_disposition,
3039 0, 0, 0, 0, NULL, NULL,
3040 &base_fsp, NULL);
3041 TALLOC_FREE(smb_fname_base);
3043 if (!NT_STATUS_IS_OK(status)) {
3044 DEBUG(10, ("create_file_unixpath for base %s failed: "
3045 "%s\n", smb_fname->base_name,
3046 nt_errstr(status)));
3047 goto fail;
3049 /* we don't need to low level fd */
3050 fd_close(base_fsp);
3054 * If it's a request for a directory open, deal with it separately.
3057 if (create_options & FILE_DIRECTORY_FILE) {
3059 if (create_options & FILE_NON_DIRECTORY_FILE) {
3060 status = NT_STATUS_INVALID_PARAMETER;
3061 goto fail;
3064 /* Can't open a temp directory. IFS kit test. */
3065 if (!(file_attributes & FILE_FLAG_POSIX_SEMANTICS) &&
3066 (file_attributes & FILE_ATTRIBUTE_TEMPORARY)) {
3067 status = NT_STATUS_INVALID_PARAMETER;
3068 goto fail;
3072 * We will get a create directory here if the Win32
3073 * app specified a security descriptor in the
3074 * CreateDirectory() call.
3077 oplock_request = 0;
3078 status = open_directory(
3079 conn, req, smb_fname, access_mask, share_access,
3080 create_disposition, create_options, file_attributes,
3081 &info, &fsp);
3082 } else {
3085 * Ordinary file case.
3088 status = file_new(req, conn, &fsp);
3089 if(!NT_STATUS_IS_OK(status)) {
3090 goto fail;
3094 * We're opening the stream element of a base_fsp
3095 * we already opened. Set up the base_fsp pointer.
3097 if (base_fsp) {
3098 fsp->base_fsp = base_fsp;
3101 status = open_file_ntcreate(conn,
3102 req,
3103 smb_fname,
3104 access_mask,
3105 share_access,
3106 create_disposition,
3107 create_options,
3108 file_attributes,
3109 oplock_request,
3110 &info,
3111 fsp);
3113 if(!NT_STATUS_IS_OK(status)) {
3114 file_free(req, fsp);
3115 fsp = NULL;
3118 if (NT_STATUS_EQUAL(status, NT_STATUS_FILE_IS_A_DIRECTORY)) {
3120 /* A stream open never opens a directory */
3122 if (base_fsp) {
3123 status = NT_STATUS_FILE_IS_A_DIRECTORY;
3124 goto fail;
3128 * Fail the open if it was explicitly a non-directory
3129 * file.
3132 if (create_options & FILE_NON_DIRECTORY_FILE) {
3133 status = NT_STATUS_FILE_IS_A_DIRECTORY;
3134 goto fail;
3137 oplock_request = 0;
3138 status = open_directory(
3139 conn, req, smb_fname, access_mask,
3140 share_access, create_disposition,
3141 create_options, file_attributes,
3142 &info, &fsp);
3146 if (!NT_STATUS_IS_OK(status)) {
3147 goto fail;
3150 fsp->base_fsp = base_fsp;
3153 * According to the MS documentation, the only time the security
3154 * descriptor is applied to the opened file is iff we *created* the
3155 * file; an existing file stays the same.
3157 * Also, it seems (from observation) that you can open the file with
3158 * any access mask but you can still write the sd. We need to override
3159 * the granted access before we call set_sd
3160 * Patch for bug #2242 from Tom Lackemann <cessnatomny@yahoo.com>.
3163 if ((sd != NULL) && (info == FILE_WAS_CREATED)
3164 && lp_nt_acl_support(SNUM(conn))) {
3166 uint32_t sec_info_sent;
3167 uint32_t saved_access_mask = fsp->access_mask;
3169 sec_info_sent = get_sec_info(sd);
3171 fsp->access_mask = FILE_GENERIC_ALL;
3173 /* Convert all the generic bits. */
3174 security_acl_map_generic(sd->dacl, &file_generic_mapping);
3175 security_acl_map_generic(sd->sacl, &file_generic_mapping);
3177 if (sec_info_sent & (OWNER_SECURITY_INFORMATION|
3178 GROUP_SECURITY_INFORMATION|
3179 DACL_SECURITY_INFORMATION|
3180 SACL_SECURITY_INFORMATION)) {
3181 status = SMB_VFS_FSET_NT_ACL(fsp, sec_info_sent, sd);
3184 fsp->access_mask = saved_access_mask;
3186 if (!NT_STATUS_IS_OK(status)) {
3187 goto fail;
3191 if ((ea_list != NULL) &&
3192 ((info == FILE_WAS_CREATED) || (info == FILE_WAS_OVERWRITTEN))) {
3193 status = set_ea(conn, fsp, smb_fname, ea_list);
3194 if (!NT_STATUS_IS_OK(status)) {
3195 goto fail;
3199 if (!fsp->is_directory && S_ISDIR(fsp->fsp_name->st.st_ex_mode)) {
3200 status = NT_STATUS_ACCESS_DENIED;
3201 goto fail;
3204 /* Save the requested allocation size. */
3205 if ((info == FILE_WAS_CREATED) || (info == FILE_WAS_OVERWRITTEN)) {
3206 if (allocation_size
3207 && (allocation_size > fsp->fsp_name->st.st_ex_size)) {
3208 fsp->initial_allocation_size = smb_roundup(
3209 fsp->conn, allocation_size);
3210 if (fsp->is_directory) {
3211 /* Can't set allocation size on a directory. */
3212 status = NT_STATUS_ACCESS_DENIED;
3213 goto fail;
3215 if (vfs_allocate_file_space(
3216 fsp, fsp->initial_allocation_size) == -1) {
3217 status = NT_STATUS_DISK_FULL;
3218 goto fail;
3220 } else {
3221 fsp->initial_allocation_size = smb_roundup(
3222 fsp->conn, (uint64_t)fsp->fsp_name->st.st_ex_size);
3226 DEBUG(10, ("create_file_unixpath: info=%d\n", info));
3228 *result = fsp;
3229 if (pinfo != NULL) {
3230 *pinfo = info;
3233 smb_fname->st = fsp->fsp_name->st;
3235 return NT_STATUS_OK;
3237 fail:
3238 DEBUG(10, ("create_file_unixpath: %s\n", nt_errstr(status)));
3240 if (fsp != NULL) {
3241 if (base_fsp && fsp->base_fsp == base_fsp) {
3243 * The close_file below will close
3244 * fsp->base_fsp.
3246 base_fsp = NULL;
3248 close_file(req, fsp, ERROR_CLOSE);
3249 fsp = NULL;
3251 if (base_fsp != NULL) {
3252 close_file(req, base_fsp, ERROR_CLOSE);
3253 base_fsp = NULL;
3255 return status;
3259 * Calculate the full path name given a relative fid.
3261 NTSTATUS get_relative_fid_filename(connection_struct *conn,
3262 struct smb_request *req,
3263 uint16_t root_dir_fid,
3264 struct smb_filename *smb_fname)
3266 files_struct *dir_fsp;
3267 char *parent_fname = NULL;
3268 char *new_base_name = NULL;
3269 NTSTATUS status;
3271 if (root_dir_fid == 0 || !smb_fname) {
3272 status = NT_STATUS_INTERNAL_ERROR;
3273 goto out;
3276 dir_fsp = file_fsp(req, root_dir_fid);
3278 if (dir_fsp == NULL) {
3279 status = NT_STATUS_INVALID_HANDLE;
3280 goto out;
3283 if (is_ntfs_stream_smb_fname(dir_fsp->fsp_name)) {
3284 status = NT_STATUS_INVALID_HANDLE;
3285 goto out;
3288 if (!dir_fsp->is_directory) {
3291 * Check to see if this is a mac fork of some kind.
3294 if ((conn->fs_capabilities & FILE_NAMED_STREAMS) &&
3295 is_ntfs_stream_smb_fname(smb_fname)) {
3296 status = NT_STATUS_OBJECT_PATH_NOT_FOUND;
3297 goto out;
3301 we need to handle the case when we get a
3302 relative open relative to a file and the
3303 pathname is blank - this is a reopen!
3304 (hint from demyn plantenberg)
3307 status = NT_STATUS_INVALID_HANDLE;
3308 goto out;
3311 if (ISDOT(dir_fsp->fsp_name->base_name)) {
3313 * We're at the toplevel dir, the final file name
3314 * must not contain ./, as this is filtered out
3315 * normally by srvstr_get_path and unix_convert
3316 * explicitly rejects paths containing ./.
3318 parent_fname = talloc_strdup(talloc_tos(), "");
3319 if (parent_fname == NULL) {
3320 status = NT_STATUS_NO_MEMORY;
3321 goto out;
3323 } else {
3324 size_t dir_name_len = strlen(dir_fsp->fsp_name->base_name);
3327 * Copy in the base directory name.
3330 parent_fname = TALLOC_ARRAY(talloc_tos(), char,
3331 dir_name_len+2);
3332 if (parent_fname == NULL) {
3333 status = NT_STATUS_NO_MEMORY;
3334 goto out;
3336 memcpy(parent_fname, dir_fsp->fsp_name->base_name,
3337 dir_name_len+1);
3340 * Ensure it ends in a '/'.
3341 * We used TALLOC_SIZE +2 to add space for the '/'.
3344 if(dir_name_len
3345 && (parent_fname[dir_name_len-1] != '\\')
3346 && (parent_fname[dir_name_len-1] != '/')) {
3347 parent_fname[dir_name_len] = '/';
3348 parent_fname[dir_name_len+1] = '\0';
3352 new_base_name = talloc_asprintf(smb_fname, "%s%s", parent_fname,
3353 smb_fname->base_name);
3354 if (new_base_name == NULL) {
3355 status = NT_STATUS_NO_MEMORY;
3356 goto out;
3359 TALLOC_FREE(smb_fname->base_name);
3360 smb_fname->base_name = new_base_name;
3361 status = NT_STATUS_OK;
3363 out:
3364 TALLOC_FREE(parent_fname);
3365 return status;
3368 NTSTATUS create_file_default(connection_struct *conn,
3369 struct smb_request *req,
3370 uint16_t root_dir_fid,
3371 struct smb_filename *smb_fname,
3372 uint32_t access_mask,
3373 uint32_t share_access,
3374 uint32_t create_disposition,
3375 uint32_t create_options,
3376 uint32_t file_attributes,
3377 uint32_t oplock_request,
3378 uint64_t allocation_size,
3379 struct security_descriptor *sd,
3380 struct ea_list *ea_list,
3381 files_struct **result,
3382 int *pinfo)
3384 int info = FILE_WAS_OPENED;
3385 files_struct *fsp = NULL;
3386 NTSTATUS status;
3388 DEBUG(10,("create_file: access_mask = 0x%x "
3389 "file_attributes = 0x%x, share_access = 0x%x, "
3390 "create_disposition = 0x%x create_options = 0x%x "
3391 "oplock_request = 0x%x "
3392 "root_dir_fid = 0x%x, ea_list = 0x%p, sd = 0x%p, "
3393 "fname = %s\n",
3394 (unsigned int)access_mask,
3395 (unsigned int)file_attributes,
3396 (unsigned int)share_access,
3397 (unsigned int)create_disposition,
3398 (unsigned int)create_options,
3399 (unsigned int)oplock_request,
3400 (unsigned int)root_dir_fid,
3401 ea_list, sd, smb_fname_str_dbg(smb_fname)));
3404 * Calculate the filename from the root_dir_if if necessary.
3407 if (root_dir_fid != 0) {
3408 status = get_relative_fid_filename(conn, req, root_dir_fid,
3409 smb_fname);
3410 if (!NT_STATUS_IS_OK(status)) {
3411 goto fail;
3416 * Check to see if this is a mac fork of some kind.
3419 if (is_ntfs_stream_smb_fname(smb_fname)) {
3420 enum FAKE_FILE_TYPE fake_file_type;
3422 fake_file_type = is_fake_file(smb_fname);
3424 if (fake_file_type != FAKE_FILE_TYPE_NONE) {
3427 * Here we go! support for changing the disk quotas
3428 * --metze
3430 * We need to fake up to open this MAGIC QUOTA file
3431 * and return a valid FID.
3433 * w2k close this file directly after openening xp
3434 * also tries a QUERY_FILE_INFO on the file and then
3435 * close it
3437 status = open_fake_file(req, conn, req->vuid,
3438 fake_file_type, smb_fname,
3439 access_mask, &fsp);
3440 if (!NT_STATUS_IS_OK(status)) {
3441 goto fail;
3444 ZERO_STRUCT(smb_fname->st);
3445 goto done;
3448 if (!(conn->fs_capabilities & FILE_NAMED_STREAMS)) {
3449 status = NT_STATUS_OBJECT_NAME_NOT_FOUND;
3450 goto fail;
3454 /* All file access must go through check_name() */
3456 status = check_name(conn, smb_fname->base_name);
3457 if (!NT_STATUS_IS_OK(status)) {
3458 goto fail;
3461 status = create_file_unixpath(
3462 conn, req, smb_fname, access_mask, share_access,
3463 create_disposition, create_options, file_attributes,
3464 oplock_request, allocation_size, sd, ea_list,
3465 &fsp, &info);
3467 if (!NT_STATUS_IS_OK(status)) {
3468 goto fail;
3471 done:
3472 DEBUG(10, ("create_file: info=%d\n", info));
3474 *result = fsp;
3475 if (pinfo != NULL) {
3476 *pinfo = info;
3478 return NT_STATUS_OK;
3480 fail:
3481 DEBUG(10, ("create_file: %s\n", nt_errstr(status)));
3483 if (fsp != NULL) {
3484 close_file(req, fsp, ERROR_CLOSE);
3485 fsp = NULL;
3487 return status;