Add some debug in s4's winbind server
[Samba/gebeck_regimport.git] / source3 / smbd / open.c
blob722e46106889c6058a8c6b9b16a5a9d80ed16d6c
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 "printing.h"
24 #include "smbd/globals.h"
25 #include "fake_file.h"
26 #include "librpc/gen_ndr/messaging.h"
27 #include "../libcli/security/security.h"
28 #include "../librpc/gen_ndr/ndr_security.h"
30 extern const struct generic_mapping file_generic_mapping;
32 struct deferred_open_record {
33 bool delayed_for_oplocks;
34 struct file_id id;
37 /****************************************************************************
38 SMB1 file varient of se_access_check. Never test FILE_READ_ATTRIBUTES.
39 ****************************************************************************/
41 NTSTATUS smb1_file_se_access_check(struct connection_struct *conn,
42 const struct security_descriptor *sd,
43 const struct security_token *token,
44 uint32_t access_desired,
45 uint32_t *access_granted)
47 *access_granted = 0;
49 if (get_current_uid(conn) == (uid_t)0) {
50 /* I'm sorry sir, I didn't know you were root... */
51 *access_granted = access_desired;
52 if (access_desired & SEC_FLAG_MAXIMUM_ALLOWED) {
53 *access_granted |= FILE_GENERIC_ALL;
55 return NT_STATUS_OK;
58 return se_access_check(sd,
59 token,
60 (access_desired & ~FILE_READ_ATTRIBUTES),
61 access_granted);
64 /****************************************************************************
65 Check if we have open rights.
66 ****************************************************************************/
68 NTSTATUS smbd_check_open_rights(struct connection_struct *conn,
69 const struct smb_filename *smb_fname,
70 uint32_t access_mask,
71 uint32_t *access_granted)
73 /* Check if we have rights to open. */
74 NTSTATUS status;
75 struct security_descriptor *sd = NULL;
77 status = SMB_VFS_GET_NT_ACL(conn, smb_fname->base_name,
78 (SECINFO_OWNER |
79 SECINFO_GROUP |
80 SECINFO_DACL),&sd);
82 if (!NT_STATUS_IS_OK(status)) {
83 DEBUG(10, ("smbd_check_open_rights: Could not get acl "
84 "on %s: %s\n",
85 smb_fname_str_dbg(smb_fname),
86 nt_errstr(status)));
87 return status;
90 status = smb1_file_se_access_check(conn,
91 sd,
92 get_current_nttok(conn),
93 access_mask,
94 access_granted);
96 DEBUG(10,("smbd_check_open_rights: file %s requesting "
97 "0x%x returning 0x%x (%s)\n",
98 smb_fname_str_dbg(smb_fname),
99 (unsigned int)access_mask,
100 (unsigned int)*access_granted,
101 nt_errstr(status) ));
103 if (!NT_STATUS_IS_OK(status)) {
104 if (DEBUGLEVEL >= 10) {
105 DEBUG(10,("smbd_check_open_rights: acl for %s is:\n",
106 smb_fname_str_dbg(smb_fname) ));
107 NDR_PRINT_DEBUG(security_descriptor, sd);
111 TALLOC_FREE(sd);
113 return status;
116 /****************************************************************************
117 fd support routines - attempt to do a dos_open.
118 ****************************************************************************/
120 static NTSTATUS fd_open(struct connection_struct *conn,
121 files_struct *fsp,
122 int flags,
123 mode_t mode)
125 struct smb_filename *smb_fname = fsp->fsp_name;
126 NTSTATUS status = NT_STATUS_OK;
128 #ifdef O_NOFOLLOW
130 * Never follow symlinks on a POSIX client. The
131 * client should be doing this.
134 if (fsp->posix_open || !lp_symlinks(SNUM(conn))) {
135 flags |= O_NOFOLLOW;
137 #endif
139 fsp->fh->fd = SMB_VFS_OPEN(conn, smb_fname, fsp, flags, mode);
140 if (fsp->fh->fd == -1) {
141 status = map_nt_error_from_unix(errno);
142 if (errno == EMFILE) {
143 static time_t last_warned = 0L;
145 if (time((time_t *) NULL) > last_warned) {
146 DEBUG(0,("Too many open files, unable "
147 "to open more! smbd's max "
148 "open files = %d\n",
149 lp_max_open_files()));
150 last_warned = time((time_t *) NULL);
156 DEBUG(10,("fd_open: name %s, flags = 0%o mode = 0%o, fd = %d. %s\n",
157 smb_fname_str_dbg(smb_fname), flags, (int)mode, fsp->fh->fd,
158 (fsp->fh->fd == -1) ? strerror(errno) : "" ));
160 return status;
163 /****************************************************************************
164 Close the file associated with a fsp.
165 ****************************************************************************/
167 NTSTATUS fd_close(files_struct *fsp)
169 int ret;
171 if (fsp->fh->fd == -1) {
172 return NT_STATUS_OK; /* What we used to call a stat open. */
174 if (fsp->fh->ref_count > 1) {
175 return NT_STATUS_OK; /* Shared handle. Only close last reference. */
178 ret = SMB_VFS_CLOSE(fsp);
179 fsp->fh->fd = -1;
180 if (ret == -1) {
181 return map_nt_error_from_unix(errno);
183 return NT_STATUS_OK;
186 /****************************************************************************
187 Change the ownership of a file to that of the parent directory.
188 Do this by fd if possible.
189 ****************************************************************************/
191 void change_file_owner_to_parent(connection_struct *conn,
192 const char *inherit_from_dir,
193 files_struct *fsp)
195 struct smb_filename *smb_fname_parent = NULL;
196 NTSTATUS status;
197 int ret;
199 status = create_synthetic_smb_fname(talloc_tos(), inherit_from_dir,
200 NULL, NULL, &smb_fname_parent);
201 if (!NT_STATUS_IS_OK(status)) {
202 return;
205 ret = SMB_VFS_STAT(conn, smb_fname_parent);
206 if (ret == -1) {
207 DEBUG(0,("change_file_owner_to_parent: failed to stat parent "
208 "directory %s. Error was %s\n",
209 smb_fname_str_dbg(smb_fname_parent),
210 strerror(errno)));
211 return;
214 become_root();
215 ret = SMB_VFS_FCHOWN(fsp, smb_fname_parent->st.st_ex_uid, (gid_t)-1);
216 unbecome_root();
217 if (ret == -1) {
218 DEBUG(0,("change_file_owner_to_parent: failed to fchown "
219 "file %s to parent directory uid %u. Error "
220 "was %s\n", fsp_str_dbg(fsp),
221 (unsigned int)smb_fname_parent->st.st_ex_uid,
222 strerror(errno) ));
225 DEBUG(10,("change_file_owner_to_parent: changed new file %s to "
226 "parent directory uid %u.\n", fsp_str_dbg(fsp),
227 (unsigned int)smb_fname_parent->st.st_ex_uid));
229 TALLOC_FREE(smb_fname_parent);
232 NTSTATUS change_dir_owner_to_parent(connection_struct *conn,
233 const char *inherit_from_dir,
234 const char *fname,
235 SMB_STRUCT_STAT *psbuf)
237 struct smb_filename *smb_fname_parent = NULL;
238 struct smb_filename *smb_fname_cwd = NULL;
239 char *saved_dir = NULL;
240 TALLOC_CTX *ctx = talloc_tos();
241 NTSTATUS status = NT_STATUS_OK;
242 int ret;
244 status = create_synthetic_smb_fname(ctx, inherit_from_dir, NULL, NULL,
245 &smb_fname_parent);
246 if (!NT_STATUS_IS_OK(status)) {
247 return status;
250 ret = SMB_VFS_STAT(conn, smb_fname_parent);
251 if (ret == -1) {
252 status = map_nt_error_from_unix(errno);
253 DEBUG(0,("change_dir_owner_to_parent: failed to stat parent "
254 "directory %s. Error was %s\n",
255 smb_fname_str_dbg(smb_fname_parent),
256 strerror(errno)));
257 goto out;
260 /* We've already done an lstat into psbuf, and we know it's a
261 directory. If we can cd into the directory and the dev/ino
262 are the same then we can safely chown without races as
263 we're locking the directory in place by being in it. This
264 should work on any UNIX (thanks tridge :-). JRA.
267 saved_dir = vfs_GetWd(ctx,conn);
268 if (!saved_dir) {
269 status = map_nt_error_from_unix(errno);
270 DEBUG(0,("change_dir_owner_to_parent: failed to get "
271 "current working directory. Error was %s\n",
272 strerror(errno)));
273 goto out;
276 /* Chdir into the new path. */
277 if (vfs_ChDir(conn, fname) == -1) {
278 status = map_nt_error_from_unix(errno);
279 DEBUG(0,("change_dir_owner_to_parent: failed to change "
280 "current working directory to %s. Error "
281 "was %s\n", fname, strerror(errno) ));
282 goto chdir;
285 status = create_synthetic_smb_fname(ctx, ".", NULL, NULL,
286 &smb_fname_cwd);
287 if (!NT_STATUS_IS_OK(status)) {
288 return status;
291 ret = SMB_VFS_STAT(conn, smb_fname_cwd);
292 if (ret == -1) {
293 status = map_nt_error_from_unix(errno);
294 DEBUG(0,("change_dir_owner_to_parent: failed to stat "
295 "directory '.' (%s) Error was %s\n",
296 fname, strerror(errno)));
297 goto chdir;
300 /* Ensure we're pointing at the same place. */
301 if (smb_fname_cwd->st.st_ex_dev != psbuf->st_ex_dev ||
302 smb_fname_cwd->st.st_ex_ino != psbuf->st_ex_ino ||
303 smb_fname_cwd->st.st_ex_mode != psbuf->st_ex_mode ) {
304 DEBUG(0,("change_dir_owner_to_parent: "
305 "device/inode/mode on directory %s changed. "
306 "Refusing to chown !\n", fname ));
307 status = NT_STATUS_ACCESS_DENIED;
308 goto chdir;
311 become_root();
312 ret = SMB_VFS_CHOWN(conn, ".", smb_fname_parent->st.st_ex_uid,
313 (gid_t)-1);
314 unbecome_root();
315 if (ret == -1) {
316 status = map_nt_error_from_unix(errno);
317 DEBUG(10,("change_dir_owner_to_parent: failed to chown "
318 "directory %s to parent directory uid %u. "
319 "Error was %s\n", fname,
320 (unsigned int)smb_fname_parent->st.st_ex_uid,
321 strerror(errno) ));
322 goto chdir;
325 DEBUG(10,("change_dir_owner_to_parent: changed ownership of new "
326 "directory %s to parent directory uid %u.\n",
327 fname, (unsigned int)smb_fname_parent->st.st_ex_uid ));
329 chdir:
330 vfs_ChDir(conn,saved_dir);
331 out:
332 TALLOC_FREE(smb_fname_parent);
333 TALLOC_FREE(smb_fname_cwd);
334 return status;
337 /****************************************************************************
338 Open a file.
339 ****************************************************************************/
341 static NTSTATUS open_file(files_struct *fsp,
342 connection_struct *conn,
343 struct smb_request *req,
344 const char *parent_dir,
345 int flags,
346 mode_t unx_mode,
347 uint32 access_mask, /* client requested access mask. */
348 uint32 open_access_mask) /* what we're actually using in the open. */
350 struct smb_filename *smb_fname = fsp->fsp_name;
351 NTSTATUS status = NT_STATUS_OK;
352 int accmode = (flags & O_ACCMODE);
353 int local_flags = flags;
354 bool file_existed = VALID_STAT(fsp->fsp_name->st);
356 fsp->fh->fd = -1;
357 errno = EPERM;
359 /* Check permissions */
362 * This code was changed after seeing a client open request
363 * containing the open mode of (DENY_WRITE/read-only) with
364 * the 'create if not exist' bit set. The previous code
365 * would fail to open the file read only on a read-only share
366 * as it was checking the flags parameter directly against O_RDONLY,
367 * this was failing as the flags parameter was set to O_RDONLY|O_CREAT.
368 * JRA.
371 if (!CAN_WRITE(conn)) {
372 /* It's a read-only share - fail if we wanted to write. */
373 if(accmode != O_RDONLY || (flags & O_TRUNC) || (flags & O_APPEND)) {
374 DEBUG(3,("Permission denied opening %s\n",
375 smb_fname_str_dbg(smb_fname)));
376 return NT_STATUS_ACCESS_DENIED;
377 } else if(flags & O_CREAT) {
378 /* We don't want to write - but we must make sure that
379 O_CREAT doesn't create the file if we have write
380 access into the directory.
382 flags &= ~(O_CREAT|O_EXCL);
383 local_flags &= ~(O_CREAT|O_EXCL);
388 * This little piece of insanity is inspired by the
389 * fact that an NT client can open a file for O_RDONLY,
390 * but set the create disposition to FILE_EXISTS_TRUNCATE.
391 * If the client *can* write to the file, then it expects to
392 * truncate the file, even though it is opening for readonly.
393 * Quicken uses this stupid trick in backup file creation...
394 * Thanks *greatly* to "David W. Chapman Jr." <dwcjr@inethouston.net>
395 * for helping track this one down. It didn't bite us in 2.0.x
396 * as we always opened files read-write in that release. JRA.
399 if ((accmode == O_RDONLY) && ((flags & O_TRUNC) == O_TRUNC)) {
400 DEBUG(10,("open_file: truncate requested on read-only open "
401 "for file %s\n", smb_fname_str_dbg(smb_fname)));
402 local_flags = (flags & ~O_ACCMODE)|O_RDWR;
405 if ((open_access_mask & (FILE_READ_DATA|FILE_WRITE_DATA|FILE_APPEND_DATA|FILE_EXECUTE)) ||
406 (!file_existed && (local_flags & O_CREAT)) ||
407 ((local_flags & O_TRUNC) == O_TRUNC) ) {
408 const char *wild;
411 * We can't actually truncate here as the file may be locked.
412 * open_file_ntcreate will take care of the truncate later. JRA.
415 local_flags &= ~O_TRUNC;
417 #if defined(O_NONBLOCK) && defined(S_ISFIFO)
419 * We would block on opening a FIFO with no one else on the
420 * other end. Do what we used to do and add O_NONBLOCK to the
421 * open flags. JRA.
424 if (file_existed && S_ISFIFO(smb_fname->st.st_ex_mode)) {
425 local_flags |= O_NONBLOCK;
427 #endif
429 /* Don't create files with Microsoft wildcard characters. */
430 if (fsp->base_fsp) {
432 * wildcard characters are allowed in stream names
433 * only test the basefilename
435 wild = fsp->base_fsp->fsp_name->base_name;
436 } else {
437 wild = smb_fname->base_name;
439 if ((local_flags & O_CREAT) && !file_existed &&
440 ms_has_wild(wild)) {
441 return NT_STATUS_OBJECT_NAME_INVALID;
444 /* Actually do the open */
445 status = fd_open(conn, fsp, local_flags, unx_mode);
446 if (!NT_STATUS_IS_OK(status)) {
447 DEBUG(3,("Error opening file %s (%s) (local_flags=%d) "
448 "(flags=%d)\n", smb_fname_str_dbg(smb_fname),
449 nt_errstr(status),local_flags,flags));
450 return status;
453 if ((local_flags & O_CREAT) && !file_existed) {
455 /* Inherit the ACL if required */
456 if (lp_inherit_perms(SNUM(conn))) {
457 inherit_access_posix_acl(conn, parent_dir,
458 smb_fname->base_name,
459 unx_mode);
462 /* Change the owner if required. */
463 if (lp_inherit_owner(SNUM(conn))) {
464 change_file_owner_to_parent(conn, parent_dir,
465 fsp);
468 notify_fname(conn, NOTIFY_ACTION_ADDED,
469 FILE_NOTIFY_CHANGE_FILE_NAME,
470 smb_fname->base_name);
473 } else {
474 fsp->fh->fd = -1; /* What we used to call a stat open. */
475 if (file_existed) {
476 uint32_t access_granted = 0;
478 status = smbd_check_open_rights(conn,
479 smb_fname,
480 access_mask,
481 &access_granted);
482 if (!NT_STATUS_IS_OK(status)) {
483 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
485 * On NT_STATUS_ACCESS_DENIED, access_granted
486 * contains the denied bits.
489 if ((access_mask & FILE_WRITE_ATTRIBUTES) &&
490 (access_granted & FILE_WRITE_ATTRIBUTES) &&
491 (lp_map_readonly(SNUM(conn)) ||
492 lp_map_archive(SNUM(conn)) ||
493 lp_map_hidden(SNUM(conn)) ||
494 lp_map_system(SNUM(conn)))) {
495 access_granted &= ~FILE_WRITE_ATTRIBUTES;
497 DEBUG(10,("open_file: "
498 "overrode "
499 "FILE_WRITE_"
500 "ATTRIBUTES "
501 "on file %s\n",
502 smb_fname_str_dbg(
503 smb_fname)));
506 if ((access_mask & DELETE_ACCESS) &&
507 (access_granted & DELETE_ACCESS) &&
508 can_delete_file_in_directory(conn,
509 smb_fname)) {
510 /* Were we trying to do a stat open
511 * for delete and didn't get DELETE
512 * access (only) ? Check if the
513 * directory allows DELETE_CHILD.
514 * See here:
515 * http://blogs.msdn.com/oldnewthing/archive/2004/06/04/148426.aspx
516 * for details. */
518 access_granted &= ~DELETE_ACCESS;
520 DEBUG(10,("open_file: "
521 "overrode "
522 "DELETE_ACCESS on "
523 "file %s\n",
524 smb_fname_str_dbg(
525 smb_fname)));
528 if (access_granted != 0) {
529 DEBUG(10,("open_file: Access "
530 "denied on file "
531 "%s\n",
532 smb_fname_str_dbg(
533 smb_fname)));
534 return status;
536 } else if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND) &&
537 fsp->posix_open &&
538 S_ISLNK(smb_fname->st.st_ex_mode)) {
539 /* This is a POSIX stat open for delete
540 * or rename on a symlink that points
541 * nowhere. Allow. */
542 DEBUG(10,("open_file: allowing POSIX "
543 "open on bad symlink %s\n",
544 smb_fname_str_dbg(
545 smb_fname)));
546 } else {
547 DEBUG(10,("open_file: "
548 "smbd_check_open_rights on file "
549 "%s returned %s\n",
550 smb_fname_str_dbg(smb_fname),
551 nt_errstr(status) ));
552 return status;
558 if (!file_existed) {
559 int ret;
561 if (fsp->fh->fd == -1) {
562 ret = SMB_VFS_STAT(conn, smb_fname);
563 } else {
564 ret = SMB_VFS_FSTAT(fsp, &smb_fname->st);
565 /* If we have an fd, this stat should succeed. */
566 if (ret == -1) {
567 DEBUG(0,("Error doing fstat on open file %s "
568 "(%s)\n",
569 smb_fname_str_dbg(smb_fname),
570 strerror(errno) ));
574 /* For a non-io open, this stat failing means file not found. JRA */
575 if (ret == -1) {
576 status = map_nt_error_from_unix(errno);
577 fd_close(fsp);
578 return status;
583 * POSIX allows read-only opens of directories. We don't
584 * want to do this (we use a different code path for this)
585 * so catch a directory open and return an EISDIR. JRA.
588 if(S_ISDIR(smb_fname->st.st_ex_mode)) {
589 fd_close(fsp);
590 errno = EISDIR;
591 return NT_STATUS_FILE_IS_A_DIRECTORY;
594 fsp->mode = smb_fname->st.st_ex_mode;
595 fsp->file_id = vfs_file_id_from_sbuf(conn, &smb_fname->st);
596 fsp->vuid = req ? req->vuid : UID_FIELD_INVALID;
597 fsp->file_pid = req ? req->smbpid : 0;
598 fsp->can_lock = True;
599 fsp->can_read = (access_mask & (FILE_READ_DATA)) ? True : False;
600 if (!CAN_WRITE(conn)) {
601 fsp->can_write = False;
602 } else {
603 fsp->can_write = (access_mask & (FILE_WRITE_DATA | FILE_APPEND_DATA)) ?
604 True : False;
606 fsp->print_file = NULL;
607 fsp->modified = False;
608 fsp->sent_oplock_break = NO_BREAK_SENT;
609 fsp->is_directory = False;
610 if (conn->aio_write_behind_list &&
611 is_in_path(smb_fname->base_name, conn->aio_write_behind_list,
612 conn->case_sensitive)) {
613 fsp->aio_write_behind = True;
616 fsp->wcp = NULL; /* Write cache pointer. */
618 DEBUG(2,("%s opened file %s read=%s write=%s (numopen=%d)\n",
619 conn->server_info->unix_name,
620 smb_fname_str_dbg(smb_fname),
621 BOOLSTR(fsp->can_read), BOOLSTR(fsp->can_write),
622 conn->num_files_open));
624 errno = 0;
625 return NT_STATUS_OK;
628 /*******************************************************************
629 Return True if the filename is one of the special executable types.
630 ********************************************************************/
632 bool is_executable(const char *fname)
634 if ((fname = strrchr_m(fname,'.'))) {
635 if (strequal(fname,".com") ||
636 strequal(fname,".dll") ||
637 strequal(fname,".exe") ||
638 strequal(fname,".sym")) {
639 return True;
642 return False;
645 /****************************************************************************
646 Check if we can open a file with a share mode.
647 Returns True if conflict, False if not.
648 ****************************************************************************/
650 static bool share_conflict(struct share_mode_entry *entry,
651 uint32 access_mask,
652 uint32 share_access)
654 DEBUG(10,("share_conflict: entry->access_mask = 0x%x, "
655 "entry->share_access = 0x%x, "
656 "entry->private_options = 0x%x\n",
657 (unsigned int)entry->access_mask,
658 (unsigned int)entry->share_access,
659 (unsigned int)entry->private_options));
661 DEBUG(10,("share_conflict: access_mask = 0x%x, share_access = 0x%x\n",
662 (unsigned int)access_mask, (unsigned int)share_access));
664 if ((entry->access_mask & (FILE_WRITE_DATA|
665 FILE_APPEND_DATA|
666 FILE_READ_DATA|
667 FILE_EXECUTE|
668 DELETE_ACCESS)) == 0) {
669 DEBUG(10,("share_conflict: No conflict due to "
670 "entry->access_mask = 0x%x\n",
671 (unsigned int)entry->access_mask ));
672 return False;
675 if ((access_mask & (FILE_WRITE_DATA|
676 FILE_APPEND_DATA|
677 FILE_READ_DATA|
678 FILE_EXECUTE|
679 DELETE_ACCESS)) == 0) {
680 DEBUG(10,("share_conflict: No conflict due to "
681 "access_mask = 0x%x\n",
682 (unsigned int)access_mask ));
683 return False;
686 #if 1 /* JRA TEST - Superdebug. */
687 #define CHECK_MASK(num, am, right, sa, share) \
688 DEBUG(10,("share_conflict: [%d] am (0x%x) & right (0x%x) = 0x%x\n", \
689 (unsigned int)(num), (unsigned int)(am), \
690 (unsigned int)(right), (unsigned int)(am)&(right) )); \
691 DEBUG(10,("share_conflict: [%d] sa (0x%x) & share (0x%x) = 0x%x\n", \
692 (unsigned int)(num), (unsigned int)(sa), \
693 (unsigned int)(share), (unsigned int)(sa)&(share) )); \
694 if (((am) & (right)) && !((sa) & (share))) { \
695 DEBUG(10,("share_conflict: check %d conflict am = 0x%x, right = 0x%x, \
696 sa = 0x%x, share = 0x%x\n", (num), (unsigned int)(am), (unsigned int)(right), (unsigned int)(sa), \
697 (unsigned int)(share) )); \
698 return True; \
700 #else
701 #define CHECK_MASK(num, am, right, sa, share) \
702 if (((am) & (right)) && !((sa) & (share))) { \
703 DEBUG(10,("share_conflict: check %d conflict am = 0x%x, right = 0x%x, \
704 sa = 0x%x, share = 0x%x\n", (num), (unsigned int)(am), (unsigned int)(right), (unsigned int)(sa), \
705 (unsigned int)(share) )); \
706 return True; \
708 #endif
710 CHECK_MASK(1, entry->access_mask, FILE_WRITE_DATA | FILE_APPEND_DATA,
711 share_access, FILE_SHARE_WRITE);
712 CHECK_MASK(2, access_mask, FILE_WRITE_DATA | FILE_APPEND_DATA,
713 entry->share_access, FILE_SHARE_WRITE);
715 CHECK_MASK(3, entry->access_mask, FILE_READ_DATA | FILE_EXECUTE,
716 share_access, FILE_SHARE_READ);
717 CHECK_MASK(4, access_mask, FILE_READ_DATA | FILE_EXECUTE,
718 entry->share_access, FILE_SHARE_READ);
720 CHECK_MASK(5, entry->access_mask, DELETE_ACCESS,
721 share_access, FILE_SHARE_DELETE);
722 CHECK_MASK(6, access_mask, DELETE_ACCESS,
723 entry->share_access, FILE_SHARE_DELETE);
725 DEBUG(10,("share_conflict: No conflict.\n"));
726 return False;
729 #if defined(DEVELOPER)
730 static void validate_my_share_entries(struct smbd_server_connection *sconn,
731 int num,
732 struct share_mode_entry *share_entry)
734 files_struct *fsp;
736 if (!procid_is_me(&share_entry->pid)) {
737 return;
740 if (is_deferred_open_entry(share_entry) &&
741 !open_was_deferred(share_entry->op_mid)) {
742 char *str = talloc_asprintf(talloc_tos(),
743 "Got a deferred entry without a request: "
744 "PANIC: %s\n",
745 share_mode_str(talloc_tos(), num, share_entry));
746 smb_panic(str);
749 if (!is_valid_share_mode_entry(share_entry)) {
750 return;
753 fsp = file_find_dif(sconn, share_entry->id,
754 share_entry->share_file_id);
755 if (!fsp) {
756 DEBUG(0,("validate_my_share_entries: PANIC : %s\n",
757 share_mode_str(talloc_tos(), num, share_entry) ));
758 smb_panic("validate_my_share_entries: Cannot match a "
759 "share entry with an open file\n");
762 if (is_deferred_open_entry(share_entry) ||
763 is_unused_share_mode_entry(share_entry)) {
764 goto panic;
767 if ((share_entry->op_type == NO_OPLOCK) &&
768 (fsp->oplock_type == FAKE_LEVEL_II_OPLOCK)) {
769 /* Someone has already written to it, but I haven't yet
770 * noticed */
771 return;
774 if (((uint16)fsp->oplock_type) != share_entry->op_type) {
775 goto panic;
778 return;
780 panic:
782 char *str;
783 DEBUG(0,("validate_my_share_entries: PANIC : %s\n",
784 share_mode_str(talloc_tos(), num, share_entry) ));
785 str = talloc_asprintf(talloc_tos(),
786 "validate_my_share_entries: "
787 "file %s, oplock_type = 0x%x, op_type = 0x%x\n",
788 fsp->fsp_name->base_name,
789 (unsigned int)fsp->oplock_type,
790 (unsigned int)share_entry->op_type );
791 smb_panic(str);
794 #endif
796 bool is_stat_open(uint32 access_mask)
798 return (access_mask &&
799 ((access_mask & ~(SYNCHRONIZE_ACCESS| FILE_READ_ATTRIBUTES|
800 FILE_WRITE_ATTRIBUTES))==0) &&
801 ((access_mask & (SYNCHRONIZE_ACCESS|FILE_READ_ATTRIBUTES|
802 FILE_WRITE_ATTRIBUTES)) != 0));
805 /****************************************************************************
806 Deal with share modes
807 Invarient: Share mode must be locked on entry and exit.
808 Returns -1 on error, or number of share modes on success (may be zero).
809 ****************************************************************************/
811 static NTSTATUS open_mode_check(connection_struct *conn,
812 struct share_mode_lock *lck,
813 uint32 access_mask,
814 uint32 share_access,
815 uint32 create_options,
816 bool *file_existed)
818 int i;
820 if(lck->num_share_modes == 0) {
821 return NT_STATUS_OK;
824 *file_existed = True;
826 /* A delete on close prohibits everything */
828 if (lck->delete_on_close) {
829 return NT_STATUS_DELETE_PENDING;
832 if (is_stat_open(access_mask)) {
833 /* Stat open that doesn't trigger oplock breaks or share mode
834 * checks... ! JRA. */
835 return NT_STATUS_OK;
839 * Check if the share modes will give us access.
842 #if defined(DEVELOPER)
843 for(i = 0; i < lck->num_share_modes; i++) {
844 validate_my_share_entries(conn->sconn, i,
845 &lck->share_modes[i]);
847 #endif
849 if (!lp_share_modes(SNUM(conn))) {
850 return NT_STATUS_OK;
853 /* Now we check the share modes, after any oplock breaks. */
854 for(i = 0; i < lck->num_share_modes; i++) {
856 if (!is_valid_share_mode_entry(&lck->share_modes[i])) {
857 continue;
860 /* someone else has a share lock on it, check to see if we can
861 * too */
862 if (share_conflict(&lck->share_modes[i],
863 access_mask, share_access)) {
864 return NT_STATUS_SHARING_VIOLATION;
868 return NT_STATUS_OK;
871 static bool is_delete_request(files_struct *fsp) {
872 return ((fsp->access_mask == DELETE_ACCESS) &&
873 (fsp->oplock_type == NO_OPLOCK));
877 * Send a break message to the oplock holder and delay the open for
878 * our client.
881 static NTSTATUS send_break_message(files_struct *fsp,
882 struct share_mode_entry *exclusive,
883 uint64_t mid,
884 int oplock_request)
886 NTSTATUS status;
887 char msg[MSG_SMB_SHARE_MODE_ENTRY_SIZE];
889 DEBUG(10, ("Sending break request to PID %s\n",
890 procid_str_static(&exclusive->pid)));
891 exclusive->op_mid = mid;
893 /* Create the message. */
894 share_mode_entry_to_message(msg, exclusive);
896 /* Add in the FORCE_OPLOCK_BREAK_TO_NONE bit in the message if set. We
897 don't want this set in the share mode struct pointed to by lck. */
899 if (oplock_request & FORCE_OPLOCK_BREAK_TO_NONE) {
900 SSVAL(msg,OP_BREAK_MSG_OP_TYPE_OFFSET,
901 exclusive->op_type | FORCE_OPLOCK_BREAK_TO_NONE);
904 status = messaging_send_buf(fsp->conn->sconn->msg_ctx, exclusive->pid,
905 MSG_SMB_BREAK_REQUEST,
906 (uint8 *)msg,
907 MSG_SMB_SHARE_MODE_ENTRY_SIZE);
908 if (!NT_STATUS_IS_OK(status)) {
909 DEBUG(3, ("Could not send oplock break message: %s\n",
910 nt_errstr(status)));
913 return status;
917 * 1) No files open at all or internal open: Grant whatever the client wants.
919 * 2) Exclusive (or batch) oplock around: If the requested access is a delete
920 * request, break if the oplock around is a batch oplock. If it's another
921 * requested access type, break.
923 * 3) Only level2 around: Grant level2 and do nothing else.
926 static bool delay_for_oplocks(struct share_mode_lock *lck,
927 files_struct *fsp,
928 uint64_t mid,
929 int pass_number,
930 int oplock_request)
932 int i;
933 struct share_mode_entry *exclusive = NULL;
934 bool valid_entry = false;
935 bool have_level2 = false;
936 bool have_a_none_oplock = false;
937 bool allow_level2 = (global_client_caps & CAP_LEVEL_II_OPLOCKS) &&
938 lp_level2_oplocks(SNUM(fsp->conn));
940 if (oplock_request & INTERNAL_OPEN_ONLY) {
941 fsp->oplock_type = NO_OPLOCK;
944 if ((oplock_request & INTERNAL_OPEN_ONLY) || is_stat_open(fsp->access_mask)) {
945 return false;
948 for (i=0; i<lck->num_share_modes; i++) {
950 if (!is_valid_share_mode_entry(&lck->share_modes[i])) {
951 continue;
954 /* At least one entry is not an invalid or deferred entry. */
955 valid_entry = true;
957 if (pass_number == 1) {
958 if (BATCH_OPLOCK_TYPE(lck->share_modes[i].op_type)) {
959 SMB_ASSERT(exclusive == NULL);
960 exclusive = &lck->share_modes[i];
962 } else {
963 if (EXCLUSIVE_OPLOCK_TYPE(lck->share_modes[i].op_type)) {
964 SMB_ASSERT(exclusive == NULL);
965 exclusive = &lck->share_modes[i];
969 if (LEVEL_II_OPLOCK_TYPE(lck->share_modes[i].op_type)) {
970 SMB_ASSERT(exclusive == NULL);
971 have_level2 = true;
974 if (lck->share_modes[i].op_type == NO_OPLOCK) {
975 have_a_none_oplock = true;
979 if (exclusive != NULL) { /* Found an exclusive oplock */
980 bool delay_it = is_delete_request(fsp) ?
981 BATCH_OPLOCK_TYPE(exclusive->op_type) : true;
982 SMB_ASSERT(!have_level2);
983 if (delay_it) {
984 send_break_message(fsp, exclusive, mid, oplock_request);
985 return true;
990 * Match what was requested (fsp->oplock_type) with
991 * what was found in the existing share modes.
994 if (!valid_entry) {
995 /* All entries are placeholders or deferred.
996 * Directly grant whatever the client wants. */
997 if (fsp->oplock_type == NO_OPLOCK) {
998 /* Store a level2 oplock, but don't tell the client */
999 fsp->oplock_type = FAKE_LEVEL_II_OPLOCK;
1001 } else if (have_a_none_oplock) {
1002 fsp->oplock_type = NO_OPLOCK;
1003 } else if (have_level2) {
1004 if (fsp->oplock_type == NO_OPLOCK ||
1005 fsp->oplock_type == FAKE_LEVEL_II_OPLOCK) {
1006 /* Store a level2 oplock, but don't tell the client */
1007 fsp->oplock_type = FAKE_LEVEL_II_OPLOCK;
1008 } else {
1009 fsp->oplock_type = LEVEL_II_OPLOCK;
1011 } else {
1012 /* This case can never happen. */
1013 SMB_ASSERT(1);
1017 * Don't grant level2 to clients that don't want them
1018 * or if we've turned them off.
1020 if (fsp->oplock_type == LEVEL_II_OPLOCK && !allow_level2) {
1021 fsp->oplock_type = FAKE_LEVEL_II_OPLOCK;
1024 DEBUG(10,("delay_for_oplocks: oplock type 0x%x on file %s\n",
1025 fsp->oplock_type, fsp_str_dbg(fsp)));
1027 /* No delay. */
1028 return false;
1031 bool request_timed_out(struct timeval request_time,
1032 struct timeval timeout)
1034 struct timeval now, end_time;
1035 GetTimeOfDay(&now);
1036 end_time = timeval_sum(&request_time, &timeout);
1037 return (timeval_compare(&end_time, &now) < 0);
1040 /****************************************************************************
1041 Handle the 1 second delay in returning a SHARING_VIOLATION error.
1042 ****************************************************************************/
1044 static void defer_open(struct share_mode_lock *lck,
1045 struct timeval request_time,
1046 struct timeval timeout,
1047 struct smb_request *req,
1048 struct deferred_open_record *state)
1050 int i;
1052 /* Paranoia check */
1054 for (i=0; i<lck->num_share_modes; i++) {
1055 struct share_mode_entry *e = &lck->share_modes[i];
1057 if (!is_deferred_open_entry(e)) {
1058 continue;
1061 if (procid_is_me(&e->pid) && (e->op_mid == req->mid)) {
1062 DEBUG(0, ("Trying to defer an already deferred "
1063 "request: mid=%llu, exiting\n",
1064 (unsigned long long)req->mid));
1065 exit_server("attempt to defer a deferred request");
1069 /* End paranoia check */
1071 DEBUG(10,("defer_open_sharing_error: time [%u.%06u] adding deferred "
1072 "open entry for mid %llu\n",
1073 (unsigned int)request_time.tv_sec,
1074 (unsigned int)request_time.tv_usec,
1075 (unsigned long long)req->mid));
1077 if (!push_deferred_open_message_smb(req, request_time, timeout,
1078 state->id, (char *)state, sizeof(*state))) {
1079 exit_server("push_deferred_open_message_smb failed");
1081 add_deferred_open(lck, req->mid, request_time,
1082 sconn_server_id(req->sconn), state->id);
1086 /****************************************************************************
1087 On overwrite open ensure that the attributes match.
1088 ****************************************************************************/
1090 bool open_match_attributes(connection_struct *conn,
1091 uint32 old_dos_attr,
1092 uint32 new_dos_attr,
1093 mode_t existing_unx_mode,
1094 mode_t new_unx_mode,
1095 mode_t *returned_unx_mode)
1097 uint32 noarch_old_dos_attr, noarch_new_dos_attr;
1099 noarch_old_dos_attr = (old_dos_attr & ~FILE_ATTRIBUTE_ARCHIVE);
1100 noarch_new_dos_attr = (new_dos_attr & ~FILE_ATTRIBUTE_ARCHIVE);
1102 if((noarch_old_dos_attr == 0 && noarch_new_dos_attr != 0) ||
1103 (noarch_old_dos_attr != 0 && ((noarch_old_dos_attr & noarch_new_dos_attr) == noarch_old_dos_attr))) {
1104 *returned_unx_mode = new_unx_mode;
1105 } else {
1106 *returned_unx_mode = (mode_t)0;
1109 DEBUG(10,("open_match_attributes: old_dos_attr = 0x%x, "
1110 "existing_unx_mode = 0%o, new_dos_attr = 0x%x "
1111 "returned_unx_mode = 0%o\n",
1112 (unsigned int)old_dos_attr,
1113 (unsigned int)existing_unx_mode,
1114 (unsigned int)new_dos_attr,
1115 (unsigned int)*returned_unx_mode ));
1117 /* If we're mapping SYSTEM and HIDDEN ensure they match. */
1118 if (lp_map_system(SNUM(conn)) || lp_store_dos_attributes(SNUM(conn))) {
1119 if ((old_dos_attr & FILE_ATTRIBUTE_SYSTEM) &&
1120 !(new_dos_attr & FILE_ATTRIBUTE_SYSTEM)) {
1121 return False;
1124 if (lp_map_hidden(SNUM(conn)) || lp_store_dos_attributes(SNUM(conn))) {
1125 if ((old_dos_attr & FILE_ATTRIBUTE_HIDDEN) &&
1126 !(new_dos_attr & FILE_ATTRIBUTE_HIDDEN)) {
1127 return False;
1130 return True;
1133 /****************************************************************************
1134 Special FCB or DOS processing in the case of a sharing violation.
1135 Try and find a duplicated file handle.
1136 ****************************************************************************/
1138 NTSTATUS fcb_or_dos_open(struct smb_request *req,
1139 connection_struct *conn,
1140 files_struct *fsp_to_dup_into,
1141 const struct smb_filename *smb_fname,
1142 struct file_id id,
1143 uint16 file_pid,
1144 uint16 vuid,
1145 uint32 access_mask,
1146 uint32 share_access,
1147 uint32 create_options)
1149 files_struct *fsp;
1151 DEBUG(5,("fcb_or_dos_open: attempting old open semantics for "
1152 "file %s.\n", smb_fname_str_dbg(smb_fname)));
1154 for(fsp = file_find_di_first(conn->sconn, id); fsp;
1155 fsp = file_find_di_next(fsp)) {
1157 DEBUG(10,("fcb_or_dos_open: checking file %s, fd = %d, "
1158 "vuid = %u, file_pid = %u, private_options = 0x%x "
1159 "access_mask = 0x%x\n", fsp_str_dbg(fsp),
1160 fsp->fh->fd, (unsigned int)fsp->vuid,
1161 (unsigned int)fsp->file_pid,
1162 (unsigned int)fsp->fh->private_options,
1163 (unsigned int)fsp->access_mask ));
1165 if (fsp->fh->fd != -1 &&
1166 fsp->vuid == vuid &&
1167 fsp->file_pid == file_pid &&
1168 (fsp->fh->private_options & (NTCREATEX_OPTIONS_PRIVATE_DENY_DOS |
1169 NTCREATEX_OPTIONS_PRIVATE_DENY_FCB)) &&
1170 (fsp->access_mask & FILE_WRITE_DATA) &&
1171 strequal(fsp->fsp_name->base_name, smb_fname->base_name) &&
1172 strequal(fsp->fsp_name->stream_name,
1173 smb_fname->stream_name)) {
1174 DEBUG(10,("fcb_or_dos_open: file match\n"));
1175 break;
1179 if (!fsp) {
1180 return NT_STATUS_NOT_FOUND;
1183 /* quite an insane set of semantics ... */
1184 if (is_executable(smb_fname->base_name) &&
1185 (fsp->fh->private_options & NTCREATEX_OPTIONS_PRIVATE_DENY_DOS)) {
1186 DEBUG(10,("fcb_or_dos_open: file fail due to is_executable.\n"));
1187 return NT_STATUS_INVALID_PARAMETER;
1190 /* We need to duplicate this fsp. */
1191 return dup_file_fsp(req, fsp, access_mask, share_access,
1192 create_options, fsp_to_dup_into);
1195 /****************************************************************************
1196 Open a file with a share mode - old openX method - map into NTCreate.
1197 ****************************************************************************/
1199 bool map_open_params_to_ntcreate(const struct smb_filename *smb_fname,
1200 int deny_mode, int open_func,
1201 uint32 *paccess_mask,
1202 uint32 *pshare_mode,
1203 uint32 *pcreate_disposition,
1204 uint32 *pcreate_options,
1205 uint32_t *pprivate_flags)
1207 uint32 access_mask;
1208 uint32 share_mode;
1209 uint32 create_disposition;
1210 uint32 create_options = FILE_NON_DIRECTORY_FILE;
1211 uint32_t private_flags = 0;
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 private_flags |= 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 private_flags |= 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 private_flags = 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,
1320 (unsigned int)private_flags));
1322 if (paccess_mask) {
1323 *paccess_mask = access_mask;
1325 if (pshare_mode) {
1326 *pshare_mode = share_mode;
1328 if (pcreate_disposition) {
1329 *pcreate_disposition = create_disposition;
1331 if (pcreate_options) {
1332 *pcreate_options = create_options;
1334 if (pprivate_flags) {
1335 *pprivate_flags = private_flags;
1338 return True;
1342 static void schedule_defer_open(struct share_mode_lock *lck,
1343 struct timeval request_time,
1344 struct smb_request *req)
1346 struct deferred_open_record state;
1348 /* This is a relative time, added to the absolute
1349 request_time value to get the absolute timeout time.
1350 Note that if this is the second or greater time we enter
1351 this codepath for this particular request mid then
1352 request_time is left as the absolute time of the *first*
1353 time this request mid was processed. This is what allows
1354 the request to eventually time out. */
1356 struct timeval timeout;
1358 /* Normally the smbd we asked should respond within
1359 * OPLOCK_BREAK_TIMEOUT seconds regardless of whether
1360 * the client did, give twice the timeout as a safety
1361 * measure here in case the other smbd is stuck
1362 * somewhere else. */
1364 timeout = timeval_set(OPLOCK_BREAK_TIMEOUT*2, 0);
1366 /* Nothing actually uses state.delayed_for_oplocks
1367 but it's handy to differentiate in debug messages
1368 between a 30 second delay due to oplock break, and
1369 a 1 second delay for share mode conflicts. */
1371 state.delayed_for_oplocks = True;
1372 state.id = lck->id;
1374 if (!request_timed_out(request_time, timeout)) {
1375 defer_open(lck, request_time, timeout, req, &state);
1379 /****************************************************************************
1380 Work out what access_mask to use from what the client sent us.
1381 ****************************************************************************/
1383 static NTSTATUS calculate_access_mask(connection_struct *conn,
1384 const struct smb_filename *smb_fname,
1385 bool file_existed,
1386 uint32_t access_mask,
1387 uint32_t *access_mask_out)
1389 NTSTATUS status;
1392 * Convert GENERIC bits to specific bits.
1395 se_map_generic(&access_mask, &file_generic_mapping);
1397 /* Calculate MAXIMUM_ALLOWED_ACCESS if requested. */
1398 if (access_mask & MAXIMUM_ALLOWED_ACCESS) {
1399 if (file_existed) {
1401 struct security_descriptor *sd;
1402 uint32_t access_granted = 0;
1404 status = SMB_VFS_GET_NT_ACL(conn, smb_fname->base_name,
1405 (SECINFO_OWNER |
1406 SECINFO_GROUP |
1407 SECINFO_DACL),&sd);
1409 if (!NT_STATUS_IS_OK(status)) {
1410 DEBUG(10, ("calculate_access_mask: Could not get acl "
1411 "on file %s: %s\n",
1412 smb_fname_str_dbg(smb_fname),
1413 nt_errstr(status)));
1414 return NT_STATUS_ACCESS_DENIED;
1417 status = smb1_file_se_access_check(conn,
1419 get_current_nttok(conn),
1420 access_mask,
1421 &access_granted);
1423 TALLOC_FREE(sd);
1425 if (!NT_STATUS_IS_OK(status)) {
1426 DEBUG(10, ("calculate_access_mask: Access denied on "
1427 "file %s: when calculating maximum access\n",
1428 smb_fname_str_dbg(smb_fname)));
1429 return NT_STATUS_ACCESS_DENIED;
1432 access_mask = access_granted;
1433 } else {
1434 access_mask = FILE_GENERIC_ALL;
1438 *access_mask_out = access_mask;
1439 return NT_STATUS_OK;
1442 /****************************************************************************
1443 Remove the deferred open entry under lock.
1444 ****************************************************************************/
1446 void remove_deferred_open_entry(struct file_id id, uint64_t mid,
1447 struct server_id pid)
1449 struct share_mode_lock *lck = get_share_mode_lock(talloc_tos(), id,
1450 NULL, NULL, NULL);
1451 if (lck == NULL) {
1452 DEBUG(0, ("could not get share mode lock\n"));
1453 } else {
1454 del_deferred_open_entry(lck, mid, pid);
1455 TALLOC_FREE(lck);
1459 /****************************************************************************
1460 Open a file with a share mode. Passed in an already created files_struct *.
1461 ****************************************************************************/
1463 static NTSTATUS open_file_ntcreate(connection_struct *conn,
1464 struct smb_request *req,
1465 uint32 access_mask, /* access bits (FILE_READ_DATA etc.) */
1466 uint32 share_access, /* share constants (FILE_SHARE_READ etc) */
1467 uint32 create_disposition, /* FILE_OPEN_IF etc. */
1468 uint32 create_options, /* options such as delete on close. */
1469 uint32 new_dos_attributes, /* attributes used for new file. */
1470 int oplock_request, /* internal Samba oplock codes. */
1471 /* Information (FILE_EXISTS etc.) */
1472 uint32_t private_flags, /* Samba specific flags. */
1473 int *pinfo,
1474 files_struct *fsp)
1476 struct smb_filename *smb_fname = fsp->fsp_name;
1477 int flags=0;
1478 int flags2=0;
1479 bool file_existed = VALID_STAT(smb_fname->st);
1480 bool def_acl = False;
1481 bool posix_open = False;
1482 bool new_file_created = False;
1483 bool clear_ads = false;
1484 struct file_id id;
1485 NTSTATUS fsp_open = NT_STATUS_ACCESS_DENIED;
1486 mode_t new_unx_mode = (mode_t)0;
1487 mode_t unx_mode = (mode_t)0;
1488 int info;
1489 uint32 existing_dos_attributes = 0;
1490 struct timeval request_time = timeval_zero();
1491 struct share_mode_lock *lck = NULL;
1492 uint32 open_access_mask = access_mask;
1493 NTSTATUS status;
1494 char *parent_dir;
1496 ZERO_STRUCT(id);
1498 /* Windows allows a new file to be created and
1499 silently removes a FILE_ATTRIBUTE_DIRECTORY
1500 sent by the client. Do the same. */
1502 new_dos_attributes &= ~FILE_ATTRIBUTE_DIRECTORY;
1504 if (conn->printer) {
1506 * Printers are handled completely differently.
1507 * Most of the passed parameters are ignored.
1510 if (pinfo) {
1511 *pinfo = FILE_WAS_CREATED;
1514 DEBUG(10, ("open_file_ntcreate: printer open fname=%s\n",
1515 smb_fname_str_dbg(smb_fname)));
1517 if (!req) {
1518 DEBUG(0,("open_file_ntcreate: printer open without "
1519 "an SMB request!\n"));
1520 return NT_STATUS_INTERNAL_ERROR;
1523 return print_spool_open(fsp, smb_fname->base_name,
1524 req->vuid);
1527 if (!parent_dirname(talloc_tos(), smb_fname->base_name, &parent_dir,
1528 NULL)) {
1529 return NT_STATUS_NO_MEMORY;
1532 if (new_dos_attributes & FILE_FLAG_POSIX_SEMANTICS) {
1533 posix_open = True;
1534 unx_mode = (mode_t)(new_dos_attributes & ~FILE_FLAG_POSIX_SEMANTICS);
1535 new_dos_attributes = 0;
1536 } else {
1537 /* We add aARCH to this as this mode is only used if the file is
1538 * created new. */
1539 unx_mode = unix_mode(conn, new_dos_attributes | aARCH,
1540 smb_fname, parent_dir);
1543 DEBUG(10, ("open_file_ntcreate: fname=%s, dos_attrs=0x%x "
1544 "access_mask=0x%x share_access=0x%x "
1545 "create_disposition = 0x%x create_options=0x%x "
1546 "unix mode=0%o oplock_request=%d private_flags = 0x%x\n",
1547 smb_fname_str_dbg(smb_fname), new_dos_attributes,
1548 access_mask, share_access, create_disposition,
1549 create_options, (unsigned int)unx_mode, oplock_request,
1550 (unsigned int)private_flags));
1552 if ((req == NULL) && ((oplock_request & INTERNAL_OPEN_ONLY) == 0)) {
1553 DEBUG(0, ("No smb request but not an internal only open!\n"));
1554 return NT_STATUS_INTERNAL_ERROR;
1558 * Only non-internal opens can be deferred at all
1561 if (req) {
1562 void *ptr;
1563 if (get_deferred_open_message_state(req,
1564 &request_time,
1565 &ptr)) {
1567 struct deferred_open_record *state = (struct deferred_open_record *)ptr;
1568 /* Remember the absolute time of the original
1569 request with this mid. We'll use it later to
1570 see if this has timed out. */
1572 /* Remove the deferred open entry under lock. */
1573 remove_deferred_open_entry(
1574 state->id, req->mid,
1575 sconn_server_id(req->sconn));
1577 /* Ensure we don't reprocess this message. */
1578 remove_deferred_open_message_smb(req->mid);
1582 status = check_name(conn, smb_fname->base_name);
1583 if (!NT_STATUS_IS_OK(status)) {
1584 return status;
1587 if (!posix_open) {
1588 new_dos_attributes &= SAMBA_ATTRIBUTES_MASK;
1589 if (file_existed) {
1590 existing_dos_attributes = dos_mode(conn, smb_fname);
1594 /* ignore any oplock requests if oplocks are disabled */
1595 if (!lp_oplocks(SNUM(conn)) ||
1596 IS_VETO_OPLOCK_PATH(conn, smb_fname->base_name)) {
1597 /* Mask off everything except the private Samba bits. */
1598 oplock_request &= SAMBA_PRIVATE_OPLOCK_MASK;
1601 /* this is for OS/2 long file names - say we don't support them */
1602 if (!lp_posix_pathnames() && strstr(smb_fname->base_name,".+,;=[].")) {
1603 /* OS/2 Workplace shell fix may be main code stream in a later
1604 * release. */
1605 DEBUG(5,("open_file_ntcreate: OS/2 long filenames are not "
1606 "supported.\n"));
1607 if (use_nt_status()) {
1608 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1610 return NT_STATUS_DOS(ERRDOS, ERRcannotopen);
1613 switch( create_disposition ) {
1615 * Currently we're using FILE_SUPERSEDE as the same as
1616 * FILE_OVERWRITE_IF but they really are
1617 * different. FILE_SUPERSEDE deletes an existing file
1618 * (requiring delete access) then recreates it.
1620 case FILE_SUPERSEDE:
1621 /* If file exists replace/overwrite. If file doesn't
1622 * exist create. */
1623 flags2 |= (O_CREAT | O_TRUNC);
1624 clear_ads = true;
1625 break;
1627 case FILE_OVERWRITE_IF:
1628 /* If file exists replace/overwrite. If file doesn't
1629 * exist create. */
1630 flags2 |= (O_CREAT | O_TRUNC);
1631 clear_ads = true;
1632 break;
1634 case FILE_OPEN:
1635 /* If file exists open. If file doesn't exist error. */
1636 if (!file_existed) {
1637 DEBUG(5,("open_file_ntcreate: FILE_OPEN "
1638 "requested for file %s and file "
1639 "doesn't exist.\n",
1640 smb_fname_str_dbg(smb_fname)));
1641 errno = ENOENT;
1642 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1644 break;
1646 case FILE_OVERWRITE:
1647 /* If file exists overwrite. If file doesn't exist
1648 * error. */
1649 if (!file_existed) {
1650 DEBUG(5,("open_file_ntcreate: FILE_OVERWRITE "
1651 "requested for file %s and file "
1652 "doesn't exist.\n",
1653 smb_fname_str_dbg(smb_fname) ));
1654 errno = ENOENT;
1655 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1657 flags2 |= O_TRUNC;
1658 clear_ads = true;
1659 break;
1661 case FILE_CREATE:
1662 /* If file exists error. If file doesn't exist
1663 * create. */
1664 if (file_existed) {
1665 DEBUG(5,("open_file_ntcreate: FILE_CREATE "
1666 "requested for file %s and file "
1667 "already exists.\n",
1668 smb_fname_str_dbg(smb_fname)));
1669 if (S_ISDIR(smb_fname->st.st_ex_mode)) {
1670 errno = EISDIR;
1671 } else {
1672 errno = EEXIST;
1674 return map_nt_error_from_unix(errno);
1676 flags2 |= (O_CREAT|O_EXCL);
1677 break;
1679 case FILE_OPEN_IF:
1680 /* If file exists open. If file doesn't exist
1681 * create. */
1682 flags2 |= O_CREAT;
1683 break;
1685 default:
1686 return NT_STATUS_INVALID_PARAMETER;
1689 /* We only care about matching attributes on file exists and
1690 * overwrite. */
1692 if (!posix_open && file_existed && ((create_disposition == FILE_OVERWRITE) ||
1693 (create_disposition == FILE_OVERWRITE_IF))) {
1694 if (!open_match_attributes(conn, existing_dos_attributes,
1695 new_dos_attributes,
1696 smb_fname->st.st_ex_mode,
1697 unx_mode, &new_unx_mode)) {
1698 DEBUG(5,("open_file_ntcreate: attributes missmatch "
1699 "for file %s (%x %x) (0%o, 0%o)\n",
1700 smb_fname_str_dbg(smb_fname),
1701 existing_dos_attributes,
1702 new_dos_attributes,
1703 (unsigned int)smb_fname->st.st_ex_mode,
1704 (unsigned int)unx_mode ));
1705 errno = EACCES;
1706 return NT_STATUS_ACCESS_DENIED;
1710 status = calculate_access_mask(conn, smb_fname, file_existed,
1711 access_mask,
1712 &access_mask);
1713 if (!NT_STATUS_IS_OK(status)) {
1714 DEBUG(10, ("open_file_ntcreate: calculate_access_mask "
1715 "on file %s returned %s\n",
1716 smb_fname_str_dbg(smb_fname), nt_errstr(status)));
1717 return status;
1720 open_access_mask = access_mask;
1722 if ((flags2 & O_TRUNC) || (oplock_request & FORCE_OPLOCK_BREAK_TO_NONE)) {
1723 open_access_mask |= FILE_WRITE_DATA; /* This will cause oplock breaks. */
1726 DEBUG(10, ("open_file_ntcreate: fname=%s, after mapping "
1727 "access_mask=0x%x\n", smb_fname_str_dbg(smb_fname),
1728 access_mask));
1731 * Note that we ignore the append flag as append does not
1732 * mean the same thing under DOS and Unix.
1735 if ((access_mask & (FILE_WRITE_DATA | FILE_APPEND_DATA)) ||
1736 (oplock_request & FORCE_OPLOCK_BREAK_TO_NONE)) {
1737 /* DENY_DOS opens are always underlying read-write on the
1738 file handle, no matter what the requested access mask
1739 says. */
1740 if ((private_flags & NTCREATEX_OPTIONS_PRIVATE_DENY_DOS) ||
1741 access_mask & (FILE_READ_ATTRIBUTES|FILE_READ_DATA|FILE_READ_EA|FILE_EXECUTE)) {
1742 flags = O_RDWR;
1743 } else {
1744 flags = O_WRONLY;
1746 } else {
1747 flags = O_RDONLY;
1751 * Currently we only look at FILE_WRITE_THROUGH for create options.
1754 #if defined(O_SYNC)
1755 if ((create_options & FILE_WRITE_THROUGH) && lp_strict_sync(SNUM(conn))) {
1756 flags2 |= O_SYNC;
1758 #endif /* O_SYNC */
1760 if (posix_open && (access_mask & FILE_APPEND_DATA)) {
1761 flags2 |= O_APPEND;
1764 if (!posix_open && !CAN_WRITE(conn)) {
1766 * We should really return a permission denied error if either
1767 * O_CREAT or O_TRUNC are set, but for compatibility with
1768 * older versions of Samba we just AND them out.
1770 flags2 &= ~(O_CREAT|O_TRUNC);
1774 * Ensure we can't write on a read-only share or file.
1777 if (flags != O_RDONLY && file_existed &&
1778 (!CAN_WRITE(conn) || IS_DOS_READONLY(existing_dos_attributes))) {
1779 DEBUG(5,("open_file_ntcreate: write access requested for "
1780 "file %s on read only %s\n",
1781 smb_fname_str_dbg(smb_fname),
1782 !CAN_WRITE(conn) ? "share" : "file" ));
1783 errno = EACCES;
1784 return NT_STATUS_ACCESS_DENIED;
1787 fsp->file_id = vfs_file_id_from_sbuf(conn, &smb_fname->st);
1788 fsp->share_access = share_access;
1789 fsp->fh->private_options = private_flags;
1790 fsp->access_mask = open_access_mask; /* We change this to the
1791 * requested access_mask after
1792 * the open is done. */
1793 fsp->posix_open = posix_open;
1795 /* Ensure no SAMBA_PRIVATE bits can be set. */
1796 fsp->oplock_type = (oplock_request & ~SAMBA_PRIVATE_OPLOCK_MASK);
1798 if (timeval_is_zero(&request_time)) {
1799 request_time = fsp->open_time;
1802 if (file_existed) {
1803 struct timespec old_write_time = smb_fname->st.st_ex_mtime;
1804 id = vfs_file_id_from_sbuf(conn, &smb_fname->st);
1806 lck = get_share_mode_lock(talloc_tos(), id,
1807 conn->connectpath,
1808 smb_fname, &old_write_time);
1810 if (lck == NULL) {
1811 DEBUG(0, ("Could not get share mode lock\n"));
1812 return NT_STATUS_SHARING_VIOLATION;
1815 /* First pass - send break only on batch oplocks. */
1816 if ((req != NULL)
1817 && delay_for_oplocks(lck, fsp, req->mid, 1,
1818 oplock_request)) {
1819 schedule_defer_open(lck, request_time, req);
1820 TALLOC_FREE(lck);
1821 return NT_STATUS_SHARING_VIOLATION;
1824 /* Use the client requested access mask here, not the one we
1825 * open with. */
1826 status = open_mode_check(conn, lck, access_mask, share_access,
1827 create_options, &file_existed);
1829 if (NT_STATUS_IS_OK(status)) {
1830 /* We might be going to allow this open. Check oplock
1831 * status again. */
1832 /* Second pass - send break for both batch or
1833 * exclusive oplocks. */
1834 if ((req != NULL)
1835 && delay_for_oplocks(lck, fsp, req->mid, 2,
1836 oplock_request)) {
1837 schedule_defer_open(lck, request_time, req);
1838 TALLOC_FREE(lck);
1839 return NT_STATUS_SHARING_VIOLATION;
1843 if (NT_STATUS_EQUAL(status, NT_STATUS_DELETE_PENDING)) {
1844 /* DELETE_PENDING is not deferred for a second */
1845 TALLOC_FREE(lck);
1846 return status;
1849 if (!NT_STATUS_IS_OK(status)) {
1850 uint32 can_access_mask;
1851 bool can_access = True;
1853 SMB_ASSERT(NT_STATUS_EQUAL(status, NT_STATUS_SHARING_VIOLATION));
1855 /* Check if this can be done with the deny_dos and fcb
1856 * calls. */
1857 if (private_flags &
1858 (NTCREATEX_OPTIONS_PRIVATE_DENY_DOS|
1859 NTCREATEX_OPTIONS_PRIVATE_DENY_FCB)) {
1860 if (req == NULL) {
1861 DEBUG(0, ("DOS open without an SMB "
1862 "request!\n"));
1863 TALLOC_FREE(lck);
1864 return NT_STATUS_INTERNAL_ERROR;
1867 /* Use the client requested access mask here,
1868 * not the one we open with. */
1869 status = fcb_or_dos_open(req,
1870 conn,
1871 fsp,
1872 smb_fname,
1874 req->smbpid,
1875 req->vuid,
1876 access_mask,
1877 share_access,
1878 create_options);
1880 if (NT_STATUS_IS_OK(status)) {
1881 TALLOC_FREE(lck);
1882 if (pinfo) {
1883 *pinfo = FILE_WAS_OPENED;
1885 return NT_STATUS_OK;
1890 * This next line is a subtlety we need for
1891 * MS-Access. If a file open will fail due to share
1892 * permissions and also for security (access) reasons,
1893 * we need to return the access failed error, not the
1894 * share error. We can't open the file due to kernel
1895 * oplock deadlock (it's possible we failed above on
1896 * the open_mode_check()) so use a userspace check.
1899 if (flags & O_RDWR) {
1900 can_access_mask = FILE_READ_DATA|FILE_WRITE_DATA;
1901 } else if (flags & O_WRONLY) {
1902 can_access_mask = FILE_WRITE_DATA;
1903 } else {
1904 can_access_mask = FILE_READ_DATA;
1907 if (((can_access_mask & FILE_WRITE_DATA) &&
1908 !CAN_WRITE(conn)) ||
1909 !can_access_file_data(conn, smb_fname,
1910 can_access_mask)) {
1911 can_access = False;
1915 * If we're returning a share violation, ensure we
1916 * cope with the braindead 1 second delay.
1919 if (!(oplock_request & INTERNAL_OPEN_ONLY) &&
1920 lp_defer_sharing_violations()) {
1921 struct timeval timeout;
1922 struct deferred_open_record state;
1923 int timeout_usecs;
1925 /* this is a hack to speed up torture tests
1926 in 'make test' */
1927 timeout_usecs = lp_parm_int(SNUM(conn),
1928 "smbd","sharedelay",
1929 SHARING_VIOLATION_USEC_WAIT);
1931 /* This is a relative time, added to the absolute
1932 request_time value to get the absolute timeout time.
1933 Note that if this is the second or greater time we enter
1934 this codepath for this particular request mid then
1935 request_time is left as the absolute time of the *first*
1936 time this request mid was processed. This is what allows
1937 the request to eventually time out. */
1939 timeout = timeval_set(0, timeout_usecs);
1941 /* Nothing actually uses state.delayed_for_oplocks
1942 but it's handy to differentiate in debug messages
1943 between a 30 second delay due to oplock break, and
1944 a 1 second delay for share mode conflicts. */
1946 state.delayed_for_oplocks = False;
1947 state.id = id;
1949 if ((req != NULL)
1950 && !request_timed_out(request_time,
1951 timeout)) {
1952 defer_open(lck, request_time, timeout,
1953 req, &state);
1957 TALLOC_FREE(lck);
1958 if (can_access) {
1960 * We have detected a sharing violation here
1961 * so return the correct error code
1963 status = NT_STATUS_SHARING_VIOLATION;
1964 } else {
1965 status = NT_STATUS_ACCESS_DENIED;
1967 return status;
1971 * We exit this block with the share entry *locked*.....
1975 SMB_ASSERT(!file_existed || (lck != NULL));
1978 * Ensure we pay attention to default ACLs on directories if required.
1981 if ((flags2 & O_CREAT) && lp_inherit_acls(SNUM(conn)) &&
1982 (def_acl = directory_has_default_acl(conn, parent_dir))) {
1983 unx_mode = (0777 & lp_create_mask(SNUM(conn)));
1986 DEBUG(4,("calling open_file with flags=0x%X flags2=0x%X mode=0%o, "
1987 "access_mask = 0x%x, open_access_mask = 0x%x\n",
1988 (unsigned int)flags, (unsigned int)flags2,
1989 (unsigned int)unx_mode, (unsigned int)access_mask,
1990 (unsigned int)open_access_mask));
1993 * open_file strips any O_TRUNC flags itself.
1996 fsp_open = open_file(fsp, conn, req, parent_dir,
1997 flags|flags2, unx_mode, access_mask,
1998 open_access_mask);
2000 if (!NT_STATUS_IS_OK(fsp_open)) {
2001 if (lck != NULL) {
2002 TALLOC_FREE(lck);
2004 return fsp_open;
2007 if (!file_existed) {
2008 struct timespec old_write_time = smb_fname->st.st_ex_mtime;
2010 * Deal with the race condition where two smbd's detect the
2011 * file doesn't exist and do the create at the same time. One
2012 * of them will win and set a share mode, the other (ie. this
2013 * one) should check if the requested share mode for this
2014 * create is allowed.
2018 * Now the file exists and fsp is successfully opened,
2019 * fsp->dev and fsp->inode are valid and should replace the
2020 * dev=0,inode=0 from a non existent file. Spotted by
2021 * Nadav Danieli <nadavd@exanet.com>. JRA.
2024 id = fsp->file_id;
2026 lck = get_share_mode_lock(talloc_tos(), id,
2027 conn->connectpath,
2028 smb_fname, &old_write_time);
2030 if (lck == NULL) {
2031 DEBUG(0, ("open_file_ntcreate: Could not get share "
2032 "mode lock for %s\n",
2033 smb_fname_str_dbg(smb_fname)));
2034 fd_close(fsp);
2035 return NT_STATUS_SHARING_VIOLATION;
2038 /* First pass - send break only on batch oplocks. */
2039 if ((req != NULL)
2040 && delay_for_oplocks(lck, fsp, req->mid, 1,
2041 oplock_request)) {
2042 schedule_defer_open(lck, request_time, req);
2043 TALLOC_FREE(lck);
2044 fd_close(fsp);
2045 return NT_STATUS_SHARING_VIOLATION;
2048 status = open_mode_check(conn, lck, access_mask, share_access,
2049 create_options, &file_existed);
2051 if (NT_STATUS_IS_OK(status)) {
2052 /* We might be going to allow this open. Check oplock
2053 * status again. */
2054 /* Second pass - send break for both batch or
2055 * exclusive oplocks. */
2056 if ((req != NULL)
2057 && delay_for_oplocks(lck, fsp, req->mid, 2,
2058 oplock_request)) {
2059 schedule_defer_open(lck, request_time, req);
2060 TALLOC_FREE(lck);
2061 fd_close(fsp);
2062 return NT_STATUS_SHARING_VIOLATION;
2066 if (!NT_STATUS_IS_OK(status)) {
2067 struct deferred_open_record state;
2069 fd_close(fsp);
2071 state.delayed_for_oplocks = False;
2072 state.id = id;
2074 /* Do it all over again immediately. In the second
2075 * round we will find that the file existed and handle
2076 * the DELETE_PENDING and FCB cases correctly. No need
2077 * to duplicate the code here. Essentially this is a
2078 * "goto top of this function", but don't tell
2079 * anybody... */
2081 if (req != NULL) {
2082 defer_open(lck, request_time, timeval_zero(),
2083 req, &state);
2085 TALLOC_FREE(lck);
2086 return status;
2090 * We exit this block with the share entry *locked*.....
2095 SMB_ASSERT(lck != NULL);
2097 /* Delete streams if create_disposition requires it */
2098 if (file_existed && clear_ads &&
2099 !is_ntfs_stream_smb_fname(smb_fname)) {
2100 status = delete_all_streams(conn, smb_fname->base_name);
2101 if (!NT_STATUS_IS_OK(status)) {
2102 TALLOC_FREE(lck);
2103 fd_close(fsp);
2104 return status;
2108 /* note that we ignore failure for the following. It is
2109 basically a hack for NFS, and NFS will never set one of
2110 these only read them. Nobody but Samba can ever set a deny
2111 mode and we have already checked our more authoritative
2112 locking database for permission to set this deny mode. If
2113 the kernel refuses the operations then the kernel is wrong.
2114 note that GPFS supports it as well - jmcd */
2116 if (fsp->fh->fd != -1) {
2117 int ret_flock;
2118 ret_flock = SMB_VFS_KERNEL_FLOCK(fsp, share_access, access_mask);
2119 if(ret_flock == -1 ){
2121 TALLOC_FREE(lck);
2122 fd_close(fsp);
2124 return NT_STATUS_SHARING_VIOLATION;
2129 * At this point onwards, we can guarentee that the share entry
2130 * is locked, whether we created the file or not, and that the
2131 * deny mode is compatible with all current opens.
2135 * If requested, truncate the file.
2138 if (file_existed && (flags2&O_TRUNC)) {
2140 * We are modifing the file after open - update the stat
2141 * struct..
2143 if ((SMB_VFS_FTRUNCATE(fsp, 0) == -1) ||
2144 (SMB_VFS_FSTAT(fsp, &smb_fname->st)==-1)) {
2145 status = map_nt_error_from_unix(errno);
2146 TALLOC_FREE(lck);
2147 fd_close(fsp);
2148 return status;
2153 * According to Samba4, SEC_FILE_READ_ATTRIBUTE is always granted,
2155 fsp->access_mask = access_mask | FILE_READ_ATTRIBUTES;
2157 if (file_existed) {
2158 /* stat opens on existing files don't get oplocks. */
2159 if (is_stat_open(open_access_mask)) {
2160 fsp->oplock_type = NO_OPLOCK;
2163 if (!(flags2 & O_TRUNC)) {
2164 info = FILE_WAS_OPENED;
2165 } else {
2166 info = FILE_WAS_OVERWRITTEN;
2168 } else {
2169 info = FILE_WAS_CREATED;
2172 if (pinfo) {
2173 *pinfo = info;
2177 * Setup the oplock info in both the shared memory and
2178 * file structs.
2181 if (!set_file_oplock(fsp, fsp->oplock_type)) {
2182 /* Could not get the kernel oplock */
2183 fsp->oplock_type = NO_OPLOCK;
2186 if (info == FILE_WAS_OVERWRITTEN || info == FILE_WAS_CREATED || info == FILE_WAS_SUPERSEDED) {
2187 new_file_created = True;
2190 set_share_mode(lck, fsp, get_current_uid(conn), 0,
2191 fsp->oplock_type);
2193 /* Handle strange delete on close create semantics. */
2194 if (create_options & FILE_DELETE_ON_CLOSE) {
2196 status = can_set_delete_on_close(fsp, new_dos_attributes);
2198 if (!NT_STATUS_IS_OK(status)) {
2199 /* Remember to delete the mode we just added. */
2200 del_share_mode(lck, fsp);
2201 TALLOC_FREE(lck);
2202 fd_close(fsp);
2203 return status;
2205 /* Note that here we set the *inital* delete on close flag,
2206 not the regular one. The magic gets handled in close. */
2207 fsp->initial_delete_on_close = True;
2210 if (new_file_created) {
2211 /* Files should be initially set as archive */
2212 if (lp_map_archive(SNUM(conn)) ||
2213 lp_store_dos_attributes(SNUM(conn))) {
2214 if (!posix_open) {
2215 if (file_set_dosmode(conn, smb_fname,
2216 new_dos_attributes | aARCH,
2217 parent_dir, true) == 0) {
2218 unx_mode = smb_fname->st.st_ex_mode;
2224 /* Determine sparse flag. */
2225 if (posix_open) {
2226 /* POSIX opens are sparse by default. */
2227 fsp->is_sparse = true;
2228 } else {
2229 fsp->is_sparse = (file_existed &&
2230 (existing_dos_attributes & FILE_ATTRIBUTE_SPARSE));
2234 * Take care of inherited ACLs on created files - if default ACL not
2235 * selected.
2238 if (!posix_open && !file_existed && !def_acl) {
2240 int saved_errno = errno; /* We might get ENOSYS in the next
2241 * call.. */
2243 if (SMB_VFS_FCHMOD_ACL(fsp, unx_mode) == -1 &&
2244 errno == ENOSYS) {
2245 errno = saved_errno; /* Ignore ENOSYS */
2248 } else if (new_unx_mode) {
2250 int ret = -1;
2252 /* Attributes need changing. File already existed. */
2255 int saved_errno = errno; /* We might get ENOSYS in the
2256 * next call.. */
2257 ret = SMB_VFS_FCHMOD_ACL(fsp, new_unx_mode);
2259 if (ret == -1 && errno == ENOSYS) {
2260 errno = saved_errno; /* Ignore ENOSYS */
2261 } else {
2262 DEBUG(5, ("open_file_ntcreate: reset "
2263 "attributes of file %s to 0%o\n",
2264 smb_fname_str_dbg(smb_fname),
2265 (unsigned int)new_unx_mode));
2266 ret = 0; /* Don't do the fchmod below. */
2270 if ((ret == -1) &&
2271 (SMB_VFS_FCHMOD(fsp, new_unx_mode) == -1))
2272 DEBUG(5, ("open_file_ntcreate: failed to reset "
2273 "attributes of file %s to 0%o\n",
2274 smb_fname_str_dbg(smb_fname),
2275 (unsigned int)new_unx_mode));
2278 /* If this is a successful open, we must remove any deferred open
2279 * records. */
2280 if (req != NULL) {
2281 del_deferred_open_entry(lck, req->mid,
2282 sconn_server_id(req->sconn));
2284 TALLOC_FREE(lck);
2286 return NT_STATUS_OK;
2290 /****************************************************************************
2291 Open a file for for write to ensure that we can fchmod it.
2292 ****************************************************************************/
2294 NTSTATUS open_file_fchmod(connection_struct *conn,
2295 struct smb_filename *smb_fname,
2296 files_struct **result)
2298 if (!VALID_STAT(smb_fname->st)) {
2299 return NT_STATUS_INVALID_PARAMETER;
2302 return SMB_VFS_CREATE_FILE(
2303 conn, /* conn */
2304 NULL, /* req */
2305 0, /* root_dir_fid */
2306 smb_fname, /* fname */
2307 FILE_WRITE_DATA, /* access_mask */
2308 (FILE_SHARE_READ | FILE_SHARE_WRITE | /* share_access */
2309 FILE_SHARE_DELETE),
2310 FILE_OPEN, /* create_disposition*/
2311 0, /* create_options */
2312 0, /* file_attributes */
2313 INTERNAL_OPEN_ONLY, /* oplock_request */
2314 0, /* allocation_size */
2315 0, /* private_flags */
2316 NULL, /* sd */
2317 NULL, /* ea_list */
2318 result, /* result */
2319 NULL); /* pinfo */
2322 static NTSTATUS mkdir_internal(connection_struct *conn,
2323 struct smb_filename *smb_dname,
2324 uint32 file_attributes)
2326 mode_t mode;
2327 char *parent_dir;
2328 NTSTATUS status;
2329 bool posix_open = false;
2331 if(!CAN_WRITE(conn)) {
2332 DEBUG(5,("mkdir_internal: failing create on read-only share "
2333 "%s\n", lp_servicename(SNUM(conn))));
2334 return NT_STATUS_ACCESS_DENIED;
2337 status = check_name(conn, smb_dname->base_name);
2338 if (!NT_STATUS_IS_OK(status)) {
2339 return status;
2342 if (!parent_dirname(talloc_tos(), smb_dname->base_name, &parent_dir,
2343 NULL)) {
2344 return NT_STATUS_NO_MEMORY;
2347 if (file_attributes & FILE_FLAG_POSIX_SEMANTICS) {
2348 posix_open = true;
2349 mode = (mode_t)(file_attributes & ~FILE_FLAG_POSIX_SEMANTICS);
2350 } else {
2351 mode = unix_mode(conn, aDIR, smb_dname, parent_dir);
2354 if (SMB_VFS_MKDIR(conn, smb_dname->base_name, mode) != 0) {
2355 return map_nt_error_from_unix(errno);
2358 /* Ensure we're checking for a symlink here.... */
2359 /* We don't want to get caught by a symlink racer. */
2361 if (SMB_VFS_LSTAT(conn, smb_dname) == -1) {
2362 DEBUG(2, ("Could not stat directory '%s' just created: %s\n",
2363 smb_fname_str_dbg(smb_dname), strerror(errno)));
2364 return map_nt_error_from_unix(errno);
2367 if (!S_ISDIR(smb_dname->st.st_ex_mode)) {
2368 DEBUG(0, ("Directory just '%s' created is not a directory\n",
2369 smb_fname_str_dbg(smb_dname)));
2370 return NT_STATUS_ACCESS_DENIED;
2373 if (lp_store_dos_attributes(SNUM(conn))) {
2374 if (!posix_open) {
2375 file_set_dosmode(conn, smb_dname,
2376 file_attributes | aDIR,
2377 parent_dir, true);
2381 if (lp_inherit_perms(SNUM(conn))) {
2382 inherit_access_posix_acl(conn, parent_dir,
2383 smb_dname->base_name, mode);
2386 if (!posix_open) {
2388 * Check if high bits should have been set,
2389 * then (if bits are missing): add them.
2390 * Consider bits automagically set by UNIX, i.e. SGID bit from parent
2391 * dir.
2393 if ((mode & ~(S_IRWXU|S_IRWXG|S_IRWXO)) &&
2394 (mode & ~smb_dname->st.st_ex_mode)) {
2395 SMB_VFS_CHMOD(conn, smb_dname->base_name,
2396 (smb_dname->st.st_ex_mode |
2397 (mode & ~smb_dname->st.st_ex_mode)));
2401 /* Change the owner if required. */
2402 if (lp_inherit_owner(SNUM(conn))) {
2403 change_dir_owner_to_parent(conn, parent_dir,
2404 smb_dname->base_name,
2405 &smb_dname->st);
2408 notify_fname(conn, NOTIFY_ACTION_ADDED, FILE_NOTIFY_CHANGE_DIR_NAME,
2409 smb_dname->base_name);
2411 return NT_STATUS_OK;
2414 /****************************************************************************
2415 Open a directory from an NT SMB call.
2416 ****************************************************************************/
2418 static NTSTATUS open_directory(connection_struct *conn,
2419 struct smb_request *req,
2420 struct smb_filename *smb_dname,
2421 uint32 access_mask,
2422 uint32 share_access,
2423 uint32 create_disposition,
2424 uint32 create_options,
2425 uint32 file_attributes,
2426 int *pinfo,
2427 files_struct **result)
2429 files_struct *fsp = NULL;
2430 bool dir_existed = VALID_STAT(smb_dname->st) ? True : False;
2431 struct share_mode_lock *lck = NULL;
2432 NTSTATUS status;
2433 struct timespec mtimespec;
2434 int info = 0;
2436 SMB_ASSERT(!is_ntfs_stream_smb_fname(smb_dname));
2438 /* Ensure we have a directory attribute. */
2439 file_attributes |= FILE_ATTRIBUTE_DIRECTORY;
2441 DEBUG(5,("open_directory: opening directory %s, access_mask = 0x%x, "
2442 "share_access = 0x%x create_options = 0x%x, "
2443 "create_disposition = 0x%x, file_attributes = 0x%x\n",
2444 smb_fname_str_dbg(smb_dname),
2445 (unsigned int)access_mask,
2446 (unsigned int)share_access,
2447 (unsigned int)create_options,
2448 (unsigned int)create_disposition,
2449 (unsigned int)file_attributes));
2451 if (!(file_attributes & FILE_FLAG_POSIX_SEMANTICS) &&
2452 (conn->fs_capabilities & FILE_NAMED_STREAMS) &&
2453 is_ntfs_stream_smb_fname(smb_dname)) {
2454 DEBUG(2, ("open_directory: %s is a stream name!\n",
2455 smb_fname_str_dbg(smb_dname)));
2456 return NT_STATUS_NOT_A_DIRECTORY;
2459 status = calculate_access_mask(conn, smb_dname, dir_existed,
2460 access_mask, &access_mask);
2461 if (!NT_STATUS_IS_OK(status)) {
2462 DEBUG(10, ("open_directory: calculate_access_mask "
2463 "on file %s returned %s\n",
2464 smb_fname_str_dbg(smb_dname),
2465 nt_errstr(status)));
2466 return status;
2469 if ((access_mask & SEC_FLAG_SYSTEM_SECURITY) &&
2470 !security_token_has_privilege(get_current_nttok(conn),
2471 SEC_PRIV_SECURITY)) {
2472 DEBUG(10, ("open_directory: open on %s "
2473 "failed - SEC_FLAG_SYSTEM_SECURITY denied.\n",
2474 smb_fname_str_dbg(smb_dname)));
2475 return NT_STATUS_PRIVILEGE_NOT_HELD;
2478 switch( create_disposition ) {
2479 case FILE_OPEN:
2481 info = FILE_WAS_OPENED;
2484 * We want to follow symlinks here.
2487 if (SMB_VFS_STAT(conn, smb_dname) != 0) {
2488 return map_nt_error_from_unix(errno);
2491 break;
2493 case FILE_CREATE:
2495 /* If directory exists error. If directory doesn't
2496 * exist create. */
2498 status = mkdir_internal(conn, smb_dname,
2499 file_attributes);
2501 if (!NT_STATUS_IS_OK(status)) {
2502 DEBUG(2, ("open_directory: unable to create "
2503 "%s. Error was %s\n",
2504 smb_fname_str_dbg(smb_dname),
2505 nt_errstr(status)));
2506 return status;
2509 info = FILE_WAS_CREATED;
2510 break;
2512 case FILE_OPEN_IF:
2514 * If directory exists open. If directory doesn't
2515 * exist create.
2518 status = mkdir_internal(conn, smb_dname,
2519 file_attributes);
2521 if (NT_STATUS_IS_OK(status)) {
2522 info = FILE_WAS_CREATED;
2525 if (NT_STATUS_EQUAL(status,
2526 NT_STATUS_OBJECT_NAME_COLLISION)) {
2527 info = FILE_WAS_OPENED;
2528 status = NT_STATUS_OK;
2531 break;
2533 case FILE_SUPERSEDE:
2534 case FILE_OVERWRITE:
2535 case FILE_OVERWRITE_IF:
2536 default:
2537 DEBUG(5,("open_directory: invalid create_disposition "
2538 "0x%x for directory %s\n",
2539 (unsigned int)create_disposition,
2540 smb_fname_str_dbg(smb_dname)));
2541 return NT_STATUS_INVALID_PARAMETER;
2544 if(!S_ISDIR(smb_dname->st.st_ex_mode)) {
2545 DEBUG(5,("open_directory: %s is not a directory !\n",
2546 smb_fname_str_dbg(smb_dname)));
2547 return NT_STATUS_NOT_A_DIRECTORY;
2550 if (info == FILE_WAS_OPENED) {
2551 uint32_t access_granted = 0;
2552 status = smbd_check_open_rights(conn, smb_dname, access_mask,
2553 &access_granted);
2555 /* Were we trying to do a directory open
2556 * for delete and didn't get DELETE
2557 * access (only) ? Check if the
2558 * directory allows DELETE_CHILD.
2559 * See here:
2560 * http://blogs.msdn.com/oldnewthing/archive/2004/06/04/148426.aspx
2561 * for details. */
2563 if ((NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED) &&
2564 (access_mask & DELETE_ACCESS) &&
2565 (access_granted == DELETE_ACCESS) &&
2566 can_delete_file_in_directory(conn, smb_dname))) {
2567 DEBUG(10,("open_directory: overrode ACCESS_DENIED "
2568 "on directory %s\n",
2569 smb_fname_str_dbg(smb_dname)));
2570 status = NT_STATUS_OK;
2573 if (!NT_STATUS_IS_OK(status)) {
2574 DEBUG(10, ("open_directory: smbd_check_open_rights on "
2575 "file %s failed with %s\n",
2576 smb_fname_str_dbg(smb_dname),
2577 nt_errstr(status)));
2578 return status;
2582 status = file_new(req, conn, &fsp);
2583 if(!NT_STATUS_IS_OK(status)) {
2584 return status;
2588 * Setup the files_struct for it.
2591 fsp->mode = smb_dname->st.st_ex_mode;
2592 fsp->file_id = vfs_file_id_from_sbuf(conn, &smb_dname->st);
2593 fsp->vuid = req ? req->vuid : UID_FIELD_INVALID;
2594 fsp->file_pid = req ? req->smbpid : 0;
2595 fsp->can_lock = False;
2596 fsp->can_read = False;
2597 fsp->can_write = False;
2599 fsp->share_access = share_access;
2600 fsp->fh->private_options = 0;
2602 * According to Samba4, SEC_FILE_READ_ATTRIBUTE is always granted,
2604 fsp->access_mask = access_mask | FILE_READ_ATTRIBUTES;
2605 fsp->print_file = NULL;
2606 fsp->modified = False;
2607 fsp->oplock_type = NO_OPLOCK;
2608 fsp->sent_oplock_break = NO_BREAK_SENT;
2609 fsp->is_directory = True;
2610 fsp->posix_open = (file_attributes & FILE_FLAG_POSIX_SEMANTICS) ? True : False;
2611 status = fsp_set_smb_fname(fsp, smb_dname);
2612 if (!NT_STATUS_IS_OK(status)) {
2613 return status;
2616 mtimespec = smb_dname->st.st_ex_mtime;
2618 lck = get_share_mode_lock(talloc_tos(), fsp->file_id,
2619 conn->connectpath, smb_dname, &mtimespec);
2621 if (lck == NULL) {
2622 DEBUG(0, ("open_directory: Could not get share mode lock for "
2623 "%s\n", smb_fname_str_dbg(smb_dname)));
2624 file_free(req, fsp);
2625 return NT_STATUS_SHARING_VIOLATION;
2628 status = open_mode_check(conn, lck, access_mask, share_access,
2629 create_options, &dir_existed);
2631 if (!NT_STATUS_IS_OK(status)) {
2632 TALLOC_FREE(lck);
2633 file_free(req, fsp);
2634 return status;
2637 set_share_mode(lck, fsp, get_current_uid(conn), 0, NO_OPLOCK);
2639 /* For directories the delete on close bit at open time seems
2640 always to be honored on close... See test 19 in Samba4 BASE-DELETE. */
2641 if (create_options & FILE_DELETE_ON_CLOSE) {
2642 status = can_set_delete_on_close(fsp, 0);
2643 if (!NT_STATUS_IS_OK(status) && !NT_STATUS_EQUAL(status, NT_STATUS_DIRECTORY_NOT_EMPTY)) {
2644 TALLOC_FREE(lck);
2645 file_free(req, fsp);
2646 return status;
2649 if (NT_STATUS_IS_OK(status)) {
2650 /* Note that here we set the *inital* delete on close flag,
2651 not the regular one. The magic gets handled in close. */
2652 fsp->initial_delete_on_close = True;
2656 TALLOC_FREE(lck);
2658 if (pinfo) {
2659 *pinfo = info;
2662 *result = fsp;
2663 return NT_STATUS_OK;
2666 NTSTATUS create_directory(connection_struct *conn, struct smb_request *req,
2667 struct smb_filename *smb_dname)
2669 NTSTATUS status;
2670 files_struct *fsp;
2672 status = SMB_VFS_CREATE_FILE(
2673 conn, /* conn */
2674 req, /* req */
2675 0, /* root_dir_fid */
2676 smb_dname, /* fname */
2677 FILE_READ_ATTRIBUTES, /* access_mask */
2678 FILE_SHARE_NONE, /* share_access */
2679 FILE_CREATE, /* create_disposition*/
2680 FILE_DIRECTORY_FILE, /* create_options */
2681 FILE_ATTRIBUTE_DIRECTORY, /* file_attributes */
2682 0, /* oplock_request */
2683 0, /* allocation_size */
2684 0, /* private_flags */
2685 NULL, /* sd */
2686 NULL, /* ea_list */
2687 &fsp, /* result */
2688 NULL); /* pinfo */
2690 if (NT_STATUS_IS_OK(status)) {
2691 close_file(req, fsp, NORMAL_CLOSE);
2694 return status;
2697 /****************************************************************************
2698 Receive notification that one of our open files has been renamed by another
2699 smbd process.
2700 ****************************************************************************/
2702 void msg_file_was_renamed(struct messaging_context *msg,
2703 void *private_data,
2704 uint32_t msg_type,
2705 struct server_id server_id,
2706 DATA_BLOB *data)
2708 struct smbd_server_connection *sconn;
2709 files_struct *fsp;
2710 char *frm = (char *)data->data;
2711 struct file_id id;
2712 const char *sharepath;
2713 const char *base_name;
2714 const char *stream_name;
2715 struct smb_filename *smb_fname = NULL;
2716 size_t sp_len, bn_len;
2717 NTSTATUS status;
2719 sconn = msg_ctx_to_sconn(msg);
2720 if (sconn == NULL) {
2721 DEBUG(1, ("could not find sconn\n"));
2722 return;
2725 if (data->data == NULL
2726 || data->length < MSG_FILE_RENAMED_MIN_SIZE + 2) {
2727 DEBUG(0, ("msg_file_was_renamed: Got invalid msg len %d\n",
2728 (int)data->length));
2729 return;
2732 /* Unpack the message. */
2733 pull_file_id_24(frm, &id);
2734 sharepath = &frm[24];
2735 sp_len = strlen(sharepath);
2736 base_name = sharepath + sp_len + 1;
2737 bn_len = strlen(base_name);
2738 stream_name = sharepath + sp_len + 1 + bn_len + 1;
2740 /* stream_name must always be NULL if there is no stream. */
2741 if (stream_name[0] == '\0') {
2742 stream_name = NULL;
2745 status = create_synthetic_smb_fname(talloc_tos(), base_name,
2746 stream_name, NULL, &smb_fname);
2747 if (!NT_STATUS_IS_OK(status)) {
2748 return;
2751 DEBUG(10,("msg_file_was_renamed: Got rename message for sharepath %s, new name %s, "
2752 "file_id %s\n",
2753 sharepath, smb_fname_str_dbg(smb_fname),
2754 file_id_string_tos(&id)));
2756 for(fsp = file_find_di_first(sconn, id); fsp;
2757 fsp = file_find_di_next(fsp)) {
2758 if (memcmp(fsp->conn->connectpath, sharepath, sp_len) == 0) {
2760 DEBUG(10,("msg_file_was_renamed: renaming file fnum %d from %s -> %s\n",
2761 fsp->fnum, fsp_str_dbg(fsp),
2762 smb_fname_str_dbg(smb_fname)));
2763 status = fsp_set_smb_fname(fsp, smb_fname);
2764 if (!NT_STATUS_IS_OK(status)) {
2765 goto out;
2767 } else {
2768 /* TODO. JRA. */
2769 /* Now we have the complete path we can work out if this is
2770 actually within this share and adjust newname accordingly. */
2771 DEBUG(10,("msg_file_was_renamed: share mismatch (sharepath %s "
2772 "not sharepath %s) "
2773 "fnum %d from %s -> %s\n",
2774 fsp->conn->connectpath,
2775 sharepath,
2776 fsp->fnum,
2777 fsp_str_dbg(fsp),
2778 smb_fname_str_dbg(smb_fname)));
2781 out:
2782 TALLOC_FREE(smb_fname);
2783 return;
2787 * If a main file is opened for delete, all streams need to be checked for
2788 * !FILE_SHARE_DELETE. Do this by opening with DELETE_ACCESS.
2789 * If that works, delete them all by setting the delete on close and close.
2792 NTSTATUS open_streams_for_delete(connection_struct *conn,
2793 const char *fname)
2795 struct stream_struct *stream_info;
2796 files_struct **streams;
2797 int i;
2798 unsigned int num_streams;
2799 TALLOC_CTX *frame = talloc_stackframe();
2800 NTSTATUS status;
2802 status = SMB_VFS_STREAMINFO(conn, NULL, fname, talloc_tos(),
2803 &num_streams, &stream_info);
2805 if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_IMPLEMENTED)
2806 || NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
2807 DEBUG(10, ("no streams around\n"));
2808 TALLOC_FREE(frame);
2809 return NT_STATUS_OK;
2812 if (!NT_STATUS_IS_OK(status)) {
2813 DEBUG(10, ("SMB_VFS_STREAMINFO failed: %s\n",
2814 nt_errstr(status)));
2815 goto fail;
2818 DEBUG(10, ("open_streams_for_delete found %d streams\n",
2819 num_streams));
2821 if (num_streams == 0) {
2822 TALLOC_FREE(frame);
2823 return NT_STATUS_OK;
2826 streams = TALLOC_ARRAY(talloc_tos(), files_struct *, num_streams);
2827 if (streams == NULL) {
2828 DEBUG(0, ("talloc failed\n"));
2829 status = NT_STATUS_NO_MEMORY;
2830 goto fail;
2833 for (i=0; i<num_streams; i++) {
2834 struct smb_filename *smb_fname = NULL;
2836 if (strequal(stream_info[i].name, "::$DATA")) {
2837 streams[i] = NULL;
2838 continue;
2841 status = create_synthetic_smb_fname(talloc_tos(), fname,
2842 stream_info[i].name,
2843 NULL, &smb_fname);
2844 if (!NT_STATUS_IS_OK(status)) {
2845 goto fail;
2848 if (SMB_VFS_STAT(conn, smb_fname) == -1) {
2849 DEBUG(10, ("Unable to stat stream: %s\n",
2850 smb_fname_str_dbg(smb_fname)));
2853 status = SMB_VFS_CREATE_FILE(
2854 conn, /* conn */
2855 NULL, /* req */
2856 0, /* root_dir_fid */
2857 smb_fname, /* fname */
2858 DELETE_ACCESS, /* access_mask */
2859 (FILE_SHARE_READ | /* share_access */
2860 FILE_SHARE_WRITE | FILE_SHARE_DELETE),
2861 FILE_OPEN, /* create_disposition*/
2862 0, /* create_options */
2863 FILE_ATTRIBUTE_NORMAL, /* file_attributes */
2864 0, /* oplock_request */
2865 0, /* allocation_size */
2866 NTCREATEX_OPTIONS_PRIVATE_STREAM_DELETE, /* private_flags */
2867 NULL, /* sd */
2868 NULL, /* ea_list */
2869 &streams[i], /* result */
2870 NULL); /* pinfo */
2872 if (!NT_STATUS_IS_OK(status)) {
2873 DEBUG(10, ("Could not open stream %s: %s\n",
2874 smb_fname_str_dbg(smb_fname),
2875 nt_errstr(status)));
2877 TALLOC_FREE(smb_fname);
2878 break;
2880 TALLOC_FREE(smb_fname);
2884 * don't touch the variable "status" beyond this point :-)
2887 for (i -= 1 ; i >= 0; i--) {
2888 if (streams[i] == NULL) {
2889 continue;
2892 DEBUG(10, ("Closing stream # %d, %s\n", i,
2893 fsp_str_dbg(streams[i])));
2894 close_file(NULL, streams[i], NORMAL_CLOSE);
2897 fail:
2898 TALLOC_FREE(frame);
2899 return status;
2903 * Wrapper around open_file_ntcreate and open_directory
2906 static NTSTATUS create_file_unixpath(connection_struct *conn,
2907 struct smb_request *req,
2908 struct smb_filename *smb_fname,
2909 uint32_t access_mask,
2910 uint32_t share_access,
2911 uint32_t create_disposition,
2912 uint32_t create_options,
2913 uint32_t file_attributes,
2914 uint32_t oplock_request,
2915 uint64_t allocation_size,
2916 uint32_t private_flags,
2917 struct security_descriptor *sd,
2918 struct ea_list *ea_list,
2920 files_struct **result,
2921 int *pinfo)
2923 int info = FILE_WAS_OPENED;
2924 files_struct *base_fsp = NULL;
2925 files_struct *fsp = NULL;
2926 NTSTATUS status;
2928 DEBUG(10,("create_file_unixpath: access_mask = 0x%x "
2929 "file_attributes = 0x%x, share_access = 0x%x, "
2930 "create_disposition = 0x%x create_options = 0x%x "
2931 "oplock_request = 0x%x private_flags = 0x%x "
2932 "ea_list = 0x%p, sd = 0x%p, "
2933 "fname = %s\n",
2934 (unsigned int)access_mask,
2935 (unsigned int)file_attributes,
2936 (unsigned int)share_access,
2937 (unsigned int)create_disposition,
2938 (unsigned int)create_options,
2939 (unsigned int)oplock_request,
2940 (unsigned int)private_flags,
2941 ea_list, sd, smb_fname_str_dbg(smb_fname)));
2943 if (create_options & FILE_OPEN_BY_FILE_ID) {
2944 status = NT_STATUS_NOT_SUPPORTED;
2945 goto fail;
2948 if (create_options & NTCREATEX_OPTIONS_INVALID_PARAM_MASK) {
2949 status = NT_STATUS_INVALID_PARAMETER;
2950 goto fail;
2953 if (req == NULL) {
2954 oplock_request |= INTERNAL_OPEN_ONLY;
2957 if ((conn->fs_capabilities & FILE_NAMED_STREAMS)
2958 && (access_mask & DELETE_ACCESS)
2959 && !is_ntfs_stream_smb_fname(smb_fname)) {
2961 * We can't open a file with DELETE access if any of the
2962 * streams is open without FILE_SHARE_DELETE
2964 status = open_streams_for_delete(conn, smb_fname->base_name);
2966 if (!NT_STATUS_IS_OK(status)) {
2967 goto fail;
2971 /* This is the correct thing to do (check every time) but can_delete
2972 * is expensive (it may have to read the parent directory
2973 * permissions). So for now we're not doing it unless we have a strong
2974 * hint the client is really going to delete this file. If the client
2975 * is forcing FILE_CREATE let the filesystem take care of the
2976 * permissions. */
2978 /* Setting FILE_SHARE_DELETE is the hint. */
2980 if (lp_acl_check_permissions(SNUM(conn))
2981 && (create_disposition != FILE_CREATE)
2982 && (share_access & FILE_SHARE_DELETE)
2983 && (access_mask & DELETE_ACCESS)
2984 && (!(can_delete_file_in_directory(conn, smb_fname) ||
2985 can_access_file_acl(conn, smb_fname, DELETE_ACCESS)))) {
2986 status = NT_STATUS_ACCESS_DENIED;
2987 DEBUG(10,("create_file_unixpath: open file %s "
2988 "for delete ACCESS_DENIED\n",
2989 smb_fname_str_dbg(smb_fname)));
2990 goto fail;
2993 if ((access_mask & SEC_FLAG_SYSTEM_SECURITY) &&
2994 !security_token_has_privilege(get_current_nttok(conn),
2995 SEC_PRIV_SECURITY)) {
2996 DEBUG(10, ("create_file_unixpath: open on %s "
2997 "failed - SEC_FLAG_SYSTEM_SECURITY denied.\n",
2998 smb_fname_str_dbg(smb_fname)));
2999 status = NT_STATUS_PRIVILEGE_NOT_HELD;
3000 goto fail;
3003 if ((conn->fs_capabilities & FILE_NAMED_STREAMS)
3004 && is_ntfs_stream_smb_fname(smb_fname)
3005 && (!(private_flags & NTCREATEX_OPTIONS_PRIVATE_STREAM_DELETE))) {
3006 uint32 base_create_disposition;
3007 struct smb_filename *smb_fname_base = NULL;
3009 if (create_options & FILE_DIRECTORY_FILE) {
3010 status = NT_STATUS_NOT_A_DIRECTORY;
3011 goto fail;
3014 switch (create_disposition) {
3015 case FILE_OPEN:
3016 base_create_disposition = FILE_OPEN;
3017 break;
3018 default:
3019 base_create_disposition = FILE_OPEN_IF;
3020 break;
3023 /* Create an smb_filename with stream_name == NULL. */
3024 status = create_synthetic_smb_fname(talloc_tos(),
3025 smb_fname->base_name,
3026 NULL, NULL,
3027 &smb_fname_base);
3028 if (!NT_STATUS_IS_OK(status)) {
3029 goto fail;
3032 if (SMB_VFS_STAT(conn, smb_fname_base) == -1) {
3033 DEBUG(10, ("Unable to stat stream: %s\n",
3034 smb_fname_str_dbg(smb_fname_base)));
3037 /* Open the base file. */
3038 status = create_file_unixpath(conn, NULL, smb_fname_base, 0,
3039 FILE_SHARE_READ
3040 | FILE_SHARE_WRITE
3041 | FILE_SHARE_DELETE,
3042 base_create_disposition,
3043 0, 0, 0, 0, 0, NULL, NULL,
3044 &base_fsp, NULL);
3045 TALLOC_FREE(smb_fname_base);
3047 if (!NT_STATUS_IS_OK(status)) {
3048 DEBUG(10, ("create_file_unixpath for base %s failed: "
3049 "%s\n", smb_fname->base_name,
3050 nt_errstr(status)));
3051 goto fail;
3053 /* we don't need to low level fd */
3054 fd_close(base_fsp);
3058 * If it's a request for a directory open, deal with it separately.
3061 if (create_options & FILE_DIRECTORY_FILE) {
3063 if (create_options & FILE_NON_DIRECTORY_FILE) {
3064 status = NT_STATUS_INVALID_PARAMETER;
3065 goto fail;
3068 /* Can't open a temp directory. IFS kit test. */
3069 if (!(file_attributes & FILE_FLAG_POSIX_SEMANTICS) &&
3070 (file_attributes & FILE_ATTRIBUTE_TEMPORARY)) {
3071 status = NT_STATUS_INVALID_PARAMETER;
3072 goto fail;
3076 * We will get a create directory here if the Win32
3077 * app specified a security descriptor in the
3078 * CreateDirectory() call.
3081 oplock_request = 0;
3082 status = open_directory(
3083 conn, req, smb_fname, access_mask, share_access,
3084 create_disposition, create_options, file_attributes,
3085 &info, &fsp);
3086 } else {
3089 * Ordinary file case.
3092 status = file_new(req, conn, &fsp);
3093 if(!NT_STATUS_IS_OK(status)) {
3094 goto fail;
3097 status = fsp_set_smb_fname(fsp, smb_fname);
3098 if (!NT_STATUS_IS_OK(status)) {
3099 goto fail;
3103 * We're opening the stream element of a base_fsp
3104 * we already opened. Set up the base_fsp pointer.
3106 if (base_fsp) {
3107 fsp->base_fsp = base_fsp;
3110 status = open_file_ntcreate(conn,
3111 req,
3112 access_mask,
3113 share_access,
3114 create_disposition,
3115 create_options,
3116 file_attributes,
3117 oplock_request,
3118 private_flags,
3119 &info,
3120 fsp);
3122 if(!NT_STATUS_IS_OK(status)) {
3123 file_free(req, fsp);
3124 fsp = NULL;
3127 if (NT_STATUS_EQUAL(status, NT_STATUS_FILE_IS_A_DIRECTORY)) {
3129 /* A stream open never opens a directory */
3131 if (base_fsp) {
3132 status = NT_STATUS_FILE_IS_A_DIRECTORY;
3133 goto fail;
3137 * Fail the open if it was explicitly a non-directory
3138 * file.
3141 if (create_options & FILE_NON_DIRECTORY_FILE) {
3142 status = NT_STATUS_FILE_IS_A_DIRECTORY;
3143 goto fail;
3146 oplock_request = 0;
3147 status = open_directory(
3148 conn, req, smb_fname, access_mask,
3149 share_access, create_disposition,
3150 create_options, file_attributes,
3151 &info, &fsp);
3155 if (!NT_STATUS_IS_OK(status)) {
3156 goto fail;
3159 fsp->base_fsp = base_fsp;
3162 * According to the MS documentation, the only time the security
3163 * descriptor is applied to the opened file is iff we *created* the
3164 * file; an existing file stays the same.
3166 * Also, it seems (from observation) that you can open the file with
3167 * any access mask but you can still write the sd. We need to override
3168 * the granted access before we call set_sd
3169 * Patch for bug #2242 from Tom Lackemann <cessnatomny@yahoo.com>.
3172 if ((sd != NULL) && (info == FILE_WAS_CREATED)
3173 && lp_nt_acl_support(SNUM(conn))) {
3175 uint32_t sec_info_sent;
3176 uint32_t saved_access_mask = fsp->access_mask;
3178 sec_info_sent = get_sec_info(sd);
3180 fsp->access_mask = FILE_GENERIC_ALL;
3182 /* Convert all the generic bits. */
3183 security_acl_map_generic(sd->dacl, &file_generic_mapping);
3184 security_acl_map_generic(sd->sacl, &file_generic_mapping);
3186 if (sec_info_sent & (SECINFO_OWNER|
3187 SECINFO_GROUP|
3188 SECINFO_DACL|
3189 SECINFO_SACL)) {
3190 status = SMB_VFS_FSET_NT_ACL(fsp, sec_info_sent, sd);
3193 fsp->access_mask = saved_access_mask;
3195 if (!NT_STATUS_IS_OK(status)) {
3196 goto fail;
3200 if ((ea_list != NULL) &&
3201 ((info == FILE_WAS_CREATED) || (info == FILE_WAS_OVERWRITTEN))) {
3202 status = set_ea(conn, fsp, fsp->fsp_name, ea_list);
3203 if (!NT_STATUS_IS_OK(status)) {
3204 goto fail;
3208 if (!fsp->is_directory && S_ISDIR(fsp->fsp_name->st.st_ex_mode)) {
3209 status = NT_STATUS_ACCESS_DENIED;
3210 goto fail;
3213 /* Save the requested allocation size. */
3214 if ((info == FILE_WAS_CREATED) || (info == FILE_WAS_OVERWRITTEN)) {
3215 if (allocation_size
3216 && (allocation_size > fsp->fsp_name->st.st_ex_size)) {
3217 fsp->initial_allocation_size = smb_roundup(
3218 fsp->conn, allocation_size);
3219 if (fsp->is_directory) {
3220 /* Can't set allocation size on a directory. */
3221 status = NT_STATUS_ACCESS_DENIED;
3222 goto fail;
3224 if (vfs_allocate_file_space(
3225 fsp, fsp->initial_allocation_size) == -1) {
3226 status = NT_STATUS_DISK_FULL;
3227 goto fail;
3229 } else {
3230 fsp->initial_allocation_size = smb_roundup(
3231 fsp->conn, (uint64_t)fsp->fsp_name->st.st_ex_size);
3235 DEBUG(10, ("create_file_unixpath: info=%d\n", info));
3237 *result = fsp;
3238 if (pinfo != NULL) {
3239 *pinfo = info;
3242 smb_fname->st = fsp->fsp_name->st;
3244 return NT_STATUS_OK;
3246 fail:
3247 DEBUG(10, ("create_file_unixpath: %s\n", nt_errstr(status)));
3249 if (fsp != NULL) {
3250 if (base_fsp && fsp->base_fsp == base_fsp) {
3252 * The close_file below will close
3253 * fsp->base_fsp.
3255 base_fsp = NULL;
3257 close_file(req, fsp, ERROR_CLOSE);
3258 fsp = NULL;
3260 if (base_fsp != NULL) {
3261 close_file(req, base_fsp, ERROR_CLOSE);
3262 base_fsp = NULL;
3264 return status;
3268 * Calculate the full path name given a relative fid.
3270 NTSTATUS get_relative_fid_filename(connection_struct *conn,
3271 struct smb_request *req,
3272 uint16_t root_dir_fid,
3273 struct smb_filename *smb_fname)
3275 files_struct *dir_fsp;
3276 char *parent_fname = NULL;
3277 char *new_base_name = NULL;
3278 NTSTATUS status;
3280 if (root_dir_fid == 0 || !smb_fname) {
3281 status = NT_STATUS_INTERNAL_ERROR;
3282 goto out;
3285 dir_fsp = file_fsp(req, root_dir_fid);
3287 if (dir_fsp == NULL) {
3288 status = NT_STATUS_INVALID_HANDLE;
3289 goto out;
3292 if (is_ntfs_stream_smb_fname(dir_fsp->fsp_name)) {
3293 status = NT_STATUS_INVALID_HANDLE;
3294 goto out;
3297 if (!dir_fsp->is_directory) {
3300 * Check to see if this is a mac fork of some kind.
3303 if ((conn->fs_capabilities & FILE_NAMED_STREAMS) &&
3304 is_ntfs_stream_smb_fname(smb_fname)) {
3305 status = NT_STATUS_OBJECT_PATH_NOT_FOUND;
3306 goto out;
3310 we need to handle the case when we get a
3311 relative open relative to a file and the
3312 pathname is blank - this is a reopen!
3313 (hint from demyn plantenberg)
3316 status = NT_STATUS_INVALID_HANDLE;
3317 goto out;
3320 if (ISDOT(dir_fsp->fsp_name->base_name)) {
3322 * We're at the toplevel dir, the final file name
3323 * must not contain ./, as this is filtered out
3324 * normally by srvstr_get_path and unix_convert
3325 * explicitly rejects paths containing ./.
3327 parent_fname = talloc_strdup(talloc_tos(), "");
3328 if (parent_fname == NULL) {
3329 status = NT_STATUS_NO_MEMORY;
3330 goto out;
3332 } else {
3333 size_t dir_name_len = strlen(dir_fsp->fsp_name->base_name);
3336 * Copy in the base directory name.
3339 parent_fname = TALLOC_ARRAY(talloc_tos(), char,
3340 dir_name_len+2);
3341 if (parent_fname == NULL) {
3342 status = NT_STATUS_NO_MEMORY;
3343 goto out;
3345 memcpy(parent_fname, dir_fsp->fsp_name->base_name,
3346 dir_name_len+1);
3349 * Ensure it ends in a '/'.
3350 * We used TALLOC_SIZE +2 to add space for the '/'.
3353 if(dir_name_len
3354 && (parent_fname[dir_name_len-1] != '\\')
3355 && (parent_fname[dir_name_len-1] != '/')) {
3356 parent_fname[dir_name_len] = '/';
3357 parent_fname[dir_name_len+1] = '\0';
3361 new_base_name = talloc_asprintf(smb_fname, "%s%s", parent_fname,
3362 smb_fname->base_name);
3363 if (new_base_name == NULL) {
3364 status = NT_STATUS_NO_MEMORY;
3365 goto out;
3368 TALLOC_FREE(smb_fname->base_name);
3369 smb_fname->base_name = new_base_name;
3370 status = NT_STATUS_OK;
3372 out:
3373 TALLOC_FREE(parent_fname);
3374 return status;
3377 NTSTATUS create_file_default(connection_struct *conn,
3378 struct smb_request *req,
3379 uint16_t root_dir_fid,
3380 struct smb_filename *smb_fname,
3381 uint32_t access_mask,
3382 uint32_t share_access,
3383 uint32_t create_disposition,
3384 uint32_t create_options,
3385 uint32_t file_attributes,
3386 uint32_t oplock_request,
3387 uint64_t allocation_size,
3388 uint32_t private_flags,
3389 struct security_descriptor *sd,
3390 struct ea_list *ea_list,
3391 files_struct **result,
3392 int *pinfo)
3394 int info = FILE_WAS_OPENED;
3395 files_struct *fsp = NULL;
3396 NTSTATUS status;
3397 bool stream_name = false;
3399 DEBUG(10,("create_file: access_mask = 0x%x "
3400 "file_attributes = 0x%x, share_access = 0x%x, "
3401 "create_disposition = 0x%x create_options = 0x%x "
3402 "oplock_request = 0x%x "
3403 "private_flags = 0x%x "
3404 "root_dir_fid = 0x%x, ea_list = 0x%p, sd = 0x%p, "
3405 "fname = %s\n",
3406 (unsigned int)access_mask,
3407 (unsigned int)file_attributes,
3408 (unsigned int)share_access,
3409 (unsigned int)create_disposition,
3410 (unsigned int)create_options,
3411 (unsigned int)oplock_request,
3412 (unsigned int)private_flags,
3413 (unsigned int)root_dir_fid,
3414 ea_list, sd, smb_fname_str_dbg(smb_fname)));
3417 * Calculate the filename from the root_dir_if if necessary.
3420 if (root_dir_fid != 0) {
3421 status = get_relative_fid_filename(conn, req, root_dir_fid,
3422 smb_fname);
3423 if (!NT_STATUS_IS_OK(status)) {
3424 goto fail;
3429 * Check to see if this is a mac fork of some kind.
3432 stream_name = is_ntfs_stream_smb_fname(smb_fname);
3433 if (stream_name) {
3434 enum FAKE_FILE_TYPE fake_file_type;
3436 fake_file_type = is_fake_file(smb_fname);
3438 if (fake_file_type != FAKE_FILE_TYPE_NONE) {
3441 * Here we go! support for changing the disk quotas
3442 * --metze
3444 * We need to fake up to open this MAGIC QUOTA file
3445 * and return a valid FID.
3447 * w2k close this file directly after openening xp
3448 * also tries a QUERY_FILE_INFO on the file and then
3449 * close it
3451 status = open_fake_file(req, conn, req->vuid,
3452 fake_file_type, smb_fname,
3453 access_mask, &fsp);
3454 if (!NT_STATUS_IS_OK(status)) {
3455 goto fail;
3458 ZERO_STRUCT(smb_fname->st);
3459 goto done;
3462 if (!(conn->fs_capabilities & FILE_NAMED_STREAMS)) {
3463 status = NT_STATUS_OBJECT_NAME_NOT_FOUND;
3464 goto fail;
3468 /* All file access must go through check_name() */
3470 status = check_name(conn, smb_fname->base_name);
3471 if (!NT_STATUS_IS_OK(status)) {
3472 goto fail;
3475 if (stream_name && is_ntfs_default_stream_smb_fname(smb_fname)) {
3476 int ret;
3477 smb_fname->stream_name = NULL;
3478 /* We have to handle this error here. */
3479 if (create_options & FILE_DIRECTORY_FILE) {
3480 status = NT_STATUS_NOT_A_DIRECTORY;
3481 goto fail;
3483 if (lp_posix_pathnames()) {
3484 ret = SMB_VFS_LSTAT(conn, smb_fname);
3485 } else {
3486 ret = SMB_VFS_STAT(conn, smb_fname);
3489 if (ret == 0 && VALID_STAT_OF_DIR(smb_fname->st)) {
3490 status = NT_STATUS_FILE_IS_A_DIRECTORY;
3491 goto fail;
3495 status = create_file_unixpath(
3496 conn, req, smb_fname, access_mask, share_access,
3497 create_disposition, create_options, file_attributes,
3498 oplock_request, allocation_size, private_flags,
3499 sd, ea_list,
3500 &fsp, &info);
3502 if (!NT_STATUS_IS_OK(status)) {
3503 goto fail;
3506 done:
3507 DEBUG(10, ("create_file: info=%d\n", info));
3509 *result = fsp;
3510 if (pinfo != NULL) {
3511 *pinfo = info;
3513 return NT_STATUS_OK;
3515 fail:
3516 DEBUG(10, ("create_file: %s\n", nt_errstr(status)));
3518 if (fsp != NULL) {
3519 close_file(req, fsp, ERROR_CLOSE);
3520 fsp = NULL;
3522 return status;