source: branches/samba-3.2.x/source/smbd/open.c@ 228

Last change on this file since 228 was 228, checked in by Herwig Bauernfeind, 16 years ago

Update 3.2 branch to 3.2.6

File size: 88.2 KB
Line 
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
7
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.
12
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.
17
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/>.
20*/
21
22#include "includes.h"
23
24extern const struct generic_mapping file_generic_mapping;
25extern struct current_user current_user;
26extern userdom_struct current_user_info;
27extern bool global_client_failed_oplock_break;
28
29struct deferred_open_record {
30 bool delayed_for_oplocks;
31 struct file_id id;
32};
33
34/****************************************************************************
35 fd support routines - attempt to do a dos_open.
36****************************************************************************/
37
38static NTSTATUS fd_open(struct connection_struct *conn,
39 const char *fname,
40 files_struct *fsp,
41 int flags,
42 mode_t mode)
43{
44 NTSTATUS status = NT_STATUS_OK;
45
46#ifdef O_NOFOLLOW
47 /*
48 * Never follow symlinks on a POSIX client. The
49 * client should be doing this.
50 */
51
52 if (fsp->posix_open || !lp_symlinks(SNUM(conn))) {
53 flags |= O_NOFOLLOW;
54 }
55#endif
56
57 fsp->fh->fd = SMB_VFS_OPEN(conn,fname,fsp,flags,mode);
58 if (fsp->fh->fd == -1) {
59 status = map_nt_error_from_unix(errno);
60 }
61
62 DEBUG(10,("fd_open: name %s, flags = 0%o mode = 0%o, fd = %d. %s\n",
63 fname, flags, (int)mode, fsp->fh->fd,
64 (fsp->fh->fd == -1) ? strerror(errno) : "" ));
65
66 return status;
67}
68
69/****************************************************************************
70 Close the file associated with a fsp.
71****************************************************************************/
72
73NTSTATUS fd_close(files_struct *fsp)
74{
75 int ret;
76
77 if (fsp->fh->fd == -1) {
78 return NT_STATUS_OK; /* What we used to call a stat open. */
79 }
80 if (fsp->fh->ref_count > 1) {
81 return NT_STATUS_OK; /* Shared handle. Only close last reference. */
82 }
83
84 ret = SMB_VFS_CLOSE(fsp);
85 fsp->fh->fd = -1;
86 if (ret == -1) {
87 return map_nt_error_from_unix(errno);
88 }
89 return NT_STATUS_OK;
90}
91
92/****************************************************************************
93 Change the ownership of a file to that of the parent directory.
94 Do this by fd if possible.
95****************************************************************************/
96
97static void change_file_owner_to_parent(connection_struct *conn,
98 const char *inherit_from_dir,
99 files_struct *fsp)
100{
101 SMB_STRUCT_STAT parent_st;
102 int ret;
103
104 ret = SMB_VFS_STAT(conn, inherit_from_dir, &parent_st);
105 if (ret == -1) {
106 DEBUG(0,("change_file_owner_to_parent: failed to stat parent "
107 "directory %s. Error was %s\n",
108 inherit_from_dir, strerror(errno) ));
109 return;
110 }
111
112 become_root();
113 ret = SMB_VFS_FCHOWN(fsp, parent_st.st_uid, (gid_t)-1);
114 unbecome_root();
115 if (ret == -1) {
116 DEBUG(0,("change_file_owner_to_parent: failed to fchown "
117 "file %s to parent directory uid %u. Error "
118 "was %s\n", fsp->fsp_name,
119 (unsigned int)parent_st.st_uid,
120 strerror(errno) ));
121 }
122
123 DEBUG(10,("change_file_owner_to_parent: changed new file %s to "
124 "parent directory uid %u.\n", fsp->fsp_name,
125 (unsigned int)parent_st.st_uid ));
126}
127
128static NTSTATUS change_dir_owner_to_parent(connection_struct *conn,
129 const char *inherit_from_dir,
130 const char *fname,
131 SMB_STRUCT_STAT *psbuf)
132{
133 char *saved_dir = NULL;
134 SMB_STRUCT_STAT sbuf;
135 SMB_STRUCT_STAT parent_st;
136 TALLOC_CTX *ctx = talloc_tos();
137 NTSTATUS status = NT_STATUS_OK;
138 int ret;
139
140 ret = SMB_VFS_STAT(conn, inherit_from_dir, &parent_st);
141 if (ret == -1) {
142 status = map_nt_error_from_unix(errno);
143 DEBUG(0,("change_dir_owner_to_parent: failed to stat parent "
144 "directory %s. Error was %s\n",
145 inherit_from_dir, strerror(errno) ));
146 return status;
147 }
148
149 /* We've already done an lstat into psbuf, and we know it's a
150 directory. If we can cd into the directory and the dev/ino
151 are the same then we can safely chown without races as
152 we're locking the directory in place by being in it. This
153 should work on any UNIX (thanks tridge :-). JRA.
154 */
155
156 saved_dir = vfs_GetWd(ctx,conn);
157 if (!saved_dir) {
158 status = map_nt_error_from_unix(errno);
159 DEBUG(0,("change_dir_owner_to_parent: failed to get "
160 "current working directory. Error was %s\n",
161 strerror(errno)));
162 return status;
163 }
164
165 /* Chdir into the new path. */
166 if (vfs_ChDir(conn, fname) == -1) {
167 status = map_nt_error_from_unix(errno);
168 DEBUG(0,("change_dir_owner_to_parent: failed to change "
169 "current working directory to %s. Error "
170 "was %s\n", fname, strerror(errno) ));
171 goto out;
172 }
173
174 if (SMB_VFS_STAT(conn,".",&sbuf) == -1) {
175 status = map_nt_error_from_unix(errno);
176 DEBUG(0,("change_dir_owner_to_parent: failed to stat "
177 "directory '.' (%s) Error was %s\n",
178 fname, strerror(errno)));
179 goto out;
180 }
181
182 /* Ensure we're pointing at the same place. */
183 if (sbuf.st_dev != psbuf->st_dev ||
184 sbuf.st_ino != psbuf->st_ino ||
185 sbuf.st_mode != psbuf->st_mode ) {
186 DEBUG(0,("change_dir_owner_to_parent: "
187 "device/inode/mode on directory %s changed. "
188 "Refusing to chown !\n", fname ));
189 status = NT_STATUS_ACCESS_DENIED;
190 goto out;
191 }
192
193 become_root();
194 ret = SMB_VFS_CHOWN(conn, ".", parent_st.st_uid, (gid_t)-1);
195 unbecome_root();
196 if (ret == -1) {
197 status = map_nt_error_from_unix(errno);
198 DEBUG(10,("change_dir_owner_to_parent: failed to chown "
199 "directory %s to parent directory uid %u. "
200 "Error was %s\n", fname,
201 (unsigned int)parent_st.st_uid, strerror(errno) ));
202 goto out;
203 }
204
205 DEBUG(10,("change_dir_owner_to_parent: changed ownership of new "
206 "directory %s to parent directory uid %u.\n",
207 fname, (unsigned int)parent_st.st_uid ));
208
209 out:
210
211 vfs_ChDir(conn,saved_dir);
212 return status;
213}
214
215/****************************************************************************
216 Open a file.
217****************************************************************************/
218
219static NTSTATUS open_file(files_struct *fsp,
220 connection_struct *conn,
221 struct smb_request *req,
222 const char *parent_dir,
223 const char *name,
224 const char *path,
225 SMB_STRUCT_STAT *psbuf,
226 int flags,
227 mode_t unx_mode,
228 uint32 access_mask, /* client requested access mask. */
229 uint32 open_access_mask) /* what we're actually using in the open. */
230{
231 NTSTATUS status = NT_STATUS_OK;
232 int accmode = (flags & O_ACCMODE);
233 int local_flags = flags;
234 bool file_existed = VALID_STAT(*psbuf);
235
236 fsp->fh->fd = -1;
237 errno = EPERM;
238
239 /* Check permissions */
240
241 /*
242 * This code was changed after seeing a client open request
243 * containing the open mode of (DENY_WRITE/read-only) with
244 * the 'create if not exist' bit set. The previous code
245 * would fail to open the file read only on a read-only share
246 * as it was checking the flags parameter directly against O_RDONLY,
247 * this was failing as the flags parameter was set to O_RDONLY|O_CREAT.
248 * JRA.
249 */
250
251 if (!CAN_WRITE(conn)) {
252 /* It's a read-only share - fail if we wanted to write. */
253 if(accmode != O_RDONLY) {
254 DEBUG(3,("Permission denied opening %s\n", path));
255 return NT_STATUS_ACCESS_DENIED;
256 } else if(flags & O_CREAT) {
257 /* We don't want to write - but we must make sure that
258 O_CREAT doesn't create the file if we have write
259 access into the directory.
260 */
261 flags &= ~O_CREAT;
262 local_flags &= ~O_CREAT;
263 }
264 }
265
266 /*
267 * This little piece of insanity is inspired by the
268 * fact that an NT client can open a file for O_RDONLY,
269 * but set the create disposition to FILE_EXISTS_TRUNCATE.
270 * If the client *can* write to the file, then it expects to
271 * truncate the file, even though it is opening for readonly.
272 * Quicken uses this stupid trick in backup file creation...
273 * Thanks *greatly* to "David W. Chapman Jr." <dwcjr@inethouston.net>
274 * for helping track this one down. It didn't bite us in 2.0.x
275 * as we always opened files read-write in that release. JRA.
276 */
277
278 if ((accmode == O_RDONLY) && ((flags & O_TRUNC) == O_TRUNC)) {
279 DEBUG(10,("open_file: truncate requested on read-only open "
280 "for file %s\n", path));
281 local_flags = (flags & ~O_ACCMODE)|O_RDWR;
282 }
283
284 if ((open_access_mask & (FILE_READ_DATA|FILE_WRITE_DATA|FILE_APPEND_DATA|FILE_EXECUTE)) ||
285 (!file_existed && (local_flags & O_CREAT)) ||
286 ((local_flags & O_TRUNC) == O_TRUNC) ) {
287 const char *wild;
288
289 /*
290 * We can't actually truncate here as the file may be locked.
291 * open_file_ntcreate will take care of the truncate later. JRA.
292 */
293
294 local_flags &= ~O_TRUNC;
295
296#if defined(O_NONBLOCK) && defined(S_ISFIFO)
297 /*
298 * We would block on opening a FIFO with no one else on the
299 * other end. Do what we used to do and add O_NONBLOCK to the
300 * open flags. JRA.
301 */
302
303 if (file_existed && S_ISFIFO(psbuf->st_mode)) {
304 local_flags |= O_NONBLOCK;
305 }
306#endif
307
308 /* Don't create files with Microsoft wildcard characters. */
309 if (fsp->base_fsp) {
310 /*
311 * wildcard characters are allowed in stream names
312 * only test the basefilename
313 */
314 wild = fsp->base_fsp->fsp_name;
315 } else {
316 wild = path;
317 }
318 if ((local_flags & O_CREAT) && !file_existed &&
319 ms_has_wild(wild)) {
320 return NT_STATUS_OBJECT_NAME_INVALID;
321 }
322
323 /* Actually do the open */
324 status = fd_open(conn, path, fsp, local_flags, unx_mode);
325 if (!NT_STATUS_IS_OK(status)) {
326 DEBUG(3,("Error opening file %s (%s) (local_flags=%d) "
327 "(flags=%d)\n",
328 path,nt_errstr(status),local_flags,flags));
329 return status;
330 }
331
332 if ((local_flags & O_CREAT) && !file_existed) {
333
334 /* Inherit the ACL if required */
335 if (lp_inherit_perms(SNUM(conn))) {
336 inherit_access_acl(conn, parent_dir, path,
337 unx_mode);
338 }
339
340 /* Change the owner if required. */
341 if (lp_inherit_owner(SNUM(conn))) {
342 change_file_owner_to_parent(conn, parent_dir,
343 fsp);
344 }
345
346 notify_fname(conn, NOTIFY_ACTION_ADDED,
347 FILE_NOTIFY_CHANGE_FILE_NAME, path);
348 }
349
350 } else {
351 fsp->fh->fd = -1; /* What we used to call a stat open. */
352 }
353
354 if (!file_existed) {
355 int ret;
356
357 if (fsp->fh->fd == -1) {
358 ret = SMB_VFS_STAT(conn, path, psbuf);
359 } else {
360 ret = SMB_VFS_FSTAT(fsp, psbuf);
361 /* If we have an fd, this stat should succeed. */
362 if (ret == -1) {
363 DEBUG(0,("Error doing fstat on open file %s "
364 "(%s)\n", path,strerror(errno) ));
365 }
366 }
367
368 /* For a non-io open, this stat failing means file not found. JRA */
369 if (ret == -1) {
370 status = map_nt_error_from_unix(errno);
371 fd_close(fsp);
372 return status;
373 }
374 }
375
376 /*
377 * POSIX allows read-only opens of directories. We don't
378 * want to do this (we use a different code path for this)
379 * so catch a directory open and return an EISDIR. JRA.
380 */
381
382 if(S_ISDIR(psbuf->st_mode)) {
383 fd_close(fsp);
384 errno = EISDIR;
385 return NT_STATUS_FILE_IS_A_DIRECTORY;
386 }
387
388 fsp->mode = psbuf->st_mode;
389 fsp->file_id = vfs_file_id_from_sbuf(conn, psbuf);
390 fsp->vuid = req ? req->vuid : UID_FIELD_INVALID;
391 fsp->file_pid = req ? req->smbpid : 0;
392 fsp->can_lock = True;
393 fsp->can_read = (access_mask & (FILE_READ_DATA)) ? True : False;
394 if (!CAN_WRITE(conn)) {
395 fsp->can_write = False;
396 } else {
397 fsp->can_write = (access_mask & (FILE_WRITE_DATA | FILE_APPEND_DATA)) ?
398 True : False;
399 }
400 fsp->print_file = False;
401 fsp->modified = False;
402 fsp->sent_oplock_break = NO_BREAK_SENT;
403 fsp->is_directory = False;
404 fsp->is_stat = False;
405 if (conn->aio_write_behind_list &&
406 is_in_path(path, conn->aio_write_behind_list, conn->case_sensitive)) {
407 fsp->aio_write_behind = True;
408 }
409
410 string_set(&fsp->fsp_name, path);
411 fsp->wcp = NULL; /* Write cache pointer. */
412
413 DEBUG(2,("%s opened file %s read=%s write=%s (numopen=%d)\n",
414 *current_user_info.smb_name ?
415 current_user_info.smb_name : conn->user,fsp->fsp_name,
416 BOOLSTR(fsp->can_read), BOOLSTR(fsp->can_write),
417 conn->num_files_open));
418
419 errno = 0;
420 return NT_STATUS_OK;
421}
422
423/*******************************************************************
424 Return True if the filename is one of the special executable types.
425********************************************************************/
426
427static bool is_executable(const char *fname)
428{
429 if ((fname = strrchr_m(fname,'.'))) {
430 if (strequal(fname,".com") ||
431 strequal(fname,".dll") ||
432 strequal(fname,".exe") ||
433 strequal(fname,".sym")) {
434 return True;
435 }
436 }
437 return False;
438}
439
440/****************************************************************************
441 Check if we can open a file with a share mode.
442 Returns True if conflict, False if not.
443****************************************************************************/
444
445static bool share_conflict(struct share_mode_entry *entry,
446 uint32 access_mask,
447 uint32 share_access)
448{
449 DEBUG(10,("share_conflict: entry->access_mask = 0x%x, "
450 "entry->share_access = 0x%x, "
451 "entry->private_options = 0x%x\n",
452 (unsigned int)entry->access_mask,
453 (unsigned int)entry->share_access,
454 (unsigned int)entry->private_options));
455
456 DEBUG(10,("share_conflict: access_mask = 0x%x, share_access = 0x%x\n",
457 (unsigned int)access_mask, (unsigned int)share_access));
458
459 if ((entry->access_mask & (FILE_WRITE_DATA|
460 FILE_APPEND_DATA|
461 FILE_READ_DATA|
462 FILE_EXECUTE|
463 DELETE_ACCESS)) == 0) {
464 DEBUG(10,("share_conflict: No conflict due to "
465 "entry->access_mask = 0x%x\n",
466 (unsigned int)entry->access_mask ));
467 return False;
468 }
469
470 if ((access_mask & (FILE_WRITE_DATA|
471 FILE_APPEND_DATA|
472 FILE_READ_DATA|
473 FILE_EXECUTE|
474 DELETE_ACCESS)) == 0) {
475 DEBUG(10,("share_conflict: No conflict due to "
476 "access_mask = 0x%x\n",
477 (unsigned int)access_mask ));
478 return False;
479 }
480
481#if 1 /* JRA TEST - Superdebug. */
482#define CHECK_MASK(num, am, right, sa, share) \
483 DEBUG(10,("share_conflict: [%d] am (0x%x) & right (0x%x) = 0x%x\n", \
484 (unsigned int)(num), (unsigned int)(am), \
485 (unsigned int)(right), (unsigned int)(am)&(right) )); \
486 DEBUG(10,("share_conflict: [%d] sa (0x%x) & share (0x%x) = 0x%x\n", \
487 (unsigned int)(num), (unsigned int)(sa), \
488 (unsigned int)(share), (unsigned int)(sa)&(share) )); \
489 if (((am) & (right)) && !((sa) & (share))) { \
490 DEBUG(10,("share_conflict: check %d conflict am = 0x%x, right = 0x%x, \
491sa = 0x%x, share = 0x%x\n", (num), (unsigned int)(am), (unsigned int)(right), (unsigned int)(sa), \
492 (unsigned int)(share) )); \
493 return True; \
494 }
495#else
496#define CHECK_MASK(num, am, right, sa, share) \
497 if (((am) & (right)) && !((sa) & (share))) { \
498 DEBUG(10,("share_conflict: check %d conflict am = 0x%x, right = 0x%x, \
499sa = 0x%x, share = 0x%x\n", (num), (unsigned int)(am), (unsigned int)(right), (unsigned int)(sa), \
500 (unsigned int)(share) )); \
501 return True; \
502 }
503#endif
504
505 CHECK_MASK(1, entry->access_mask, FILE_WRITE_DATA | FILE_APPEND_DATA,
506 share_access, FILE_SHARE_WRITE);
507 CHECK_MASK(2, access_mask, FILE_WRITE_DATA | FILE_APPEND_DATA,
508 entry->share_access, FILE_SHARE_WRITE);
509
510 CHECK_MASK(3, entry->access_mask, FILE_READ_DATA | FILE_EXECUTE,
511 share_access, FILE_SHARE_READ);
512 CHECK_MASK(4, access_mask, FILE_READ_DATA | FILE_EXECUTE,
513 entry->share_access, FILE_SHARE_READ);
514
515 CHECK_MASK(5, entry->access_mask, DELETE_ACCESS,
516 share_access, FILE_SHARE_DELETE);
517 CHECK_MASK(6, access_mask, DELETE_ACCESS,
518 entry->share_access, FILE_SHARE_DELETE);
519
520 DEBUG(10,("share_conflict: No conflict.\n"));
521 return False;
522}
523
524#if defined(DEVELOPER)
525static void validate_my_share_entries(int num,
526 struct share_mode_entry *share_entry)
527{
528 files_struct *fsp;
529
530 if (!procid_is_me(&share_entry->pid)) {
531 return;
532 }
533
534 if (is_deferred_open_entry(share_entry) &&
535 !open_was_deferred(share_entry->op_mid)) {
536 char *str = talloc_asprintf(talloc_tos(),
537 "Got a deferred entry without a request: "
538 "PANIC: %s\n",
539 share_mode_str(talloc_tos(), num, share_entry));
540 smb_panic(str);
541 }
542
543 if (!is_valid_share_mode_entry(share_entry)) {
544 return;
545 }
546
547 fsp = file_find_dif(share_entry->id,
548 share_entry->share_file_id);
549 if (!fsp) {
550 DEBUG(0,("validate_my_share_entries: PANIC : %s\n",
551 share_mode_str(talloc_tos(), num, share_entry) ));
552 smb_panic("validate_my_share_entries: Cannot match a "
553 "share entry with an open file\n");
554 }
555
556 if (is_deferred_open_entry(share_entry) ||
557 is_unused_share_mode_entry(share_entry)) {
558 goto panic;
559 }
560
561 if ((share_entry->op_type == NO_OPLOCK) &&
562 (fsp->oplock_type == FAKE_LEVEL_II_OPLOCK)) {
563 /* Someone has already written to it, but I haven't yet
564 * noticed */
565 return;
566 }
567
568 if (((uint16)fsp->oplock_type) != share_entry->op_type) {
569 goto panic;
570 }
571
572 return;
573
574 panic:
575 {
576 char *str;
577 DEBUG(0,("validate_my_share_entries: PANIC : %s\n",
578 share_mode_str(talloc_tos(), num, share_entry) ));
579 str = talloc_asprintf(talloc_tos(),
580 "validate_my_share_entries: "
581 "file %s, oplock_type = 0x%x, op_type = 0x%x\n",
582 fsp->fsp_name, (unsigned int)fsp->oplock_type,
583 (unsigned int)share_entry->op_type );
584 smb_panic(str);
585 }
586}
587#endif
588
589static bool is_stat_open(uint32 access_mask)
590{
591 return (access_mask &&
592 ((access_mask & ~(SYNCHRONIZE_ACCESS| FILE_READ_ATTRIBUTES|
593 FILE_WRITE_ATTRIBUTES))==0) &&
594 ((access_mask & (SYNCHRONIZE_ACCESS|FILE_READ_ATTRIBUTES|
595 FILE_WRITE_ATTRIBUTES)) != 0));
596}
597
598/****************************************************************************
599 Deal with share modes
600 Invarient: Share mode must be locked on entry and exit.
601 Returns -1 on error, or number of share modes on success (may be zero).
602****************************************************************************/
603
604static NTSTATUS open_mode_check(connection_struct *conn,
605 const char *fname,
606 struct share_mode_lock *lck,
607 uint32 access_mask,
608 uint32 share_access,
609 uint32 create_options,
610 bool *file_existed)
611{
612 int i;
613
614 if(lck->num_share_modes == 0) {
615 return NT_STATUS_OK;
616 }
617
618 *file_existed = True;
619
620 /* A delete on close prohibits everything */
621
622 if (lck->delete_on_close) {
623 return NT_STATUS_DELETE_PENDING;
624 }
625
626 if (is_stat_open(access_mask)) {
627 /* Stat open that doesn't trigger oplock breaks or share mode
628 * checks... ! JRA. */
629 return NT_STATUS_OK;
630 }
631
632 /*
633 * Check if the share modes will give us access.
634 */
635
636#if defined(DEVELOPER)
637 for(i = 0; i < lck->num_share_modes; i++) {
638 validate_my_share_entries(i, &lck->share_modes[i]);
639 }
640#endif
641
642 if (!lp_share_modes(SNUM(conn))) {
643 return NT_STATUS_OK;
644 }
645
646 /* Now we check the share modes, after any oplock breaks. */
647 for(i = 0; i < lck->num_share_modes; i++) {
648
649 if (!is_valid_share_mode_entry(&lck->share_modes[i])) {
650 continue;
651 }
652
653 /* someone else has a share lock on it, check to see if we can
654 * too */
655 if (share_conflict(&lck->share_modes[i],
656 access_mask, share_access)) {
657 return NT_STATUS_SHARING_VIOLATION;
658 }
659 }
660
661 return NT_STATUS_OK;
662}
663
664static bool is_delete_request(files_struct *fsp) {
665 return ((fsp->access_mask == DELETE_ACCESS) &&
666 (fsp->oplock_type == NO_OPLOCK));
667}
668
669/*
670 * 1) No files open at all or internal open: Grant whatever the client wants.
671 *
672 * 2) Exclusive (or batch) oplock around: If the requested access is a delete
673 * request, break if the oplock around is a batch oplock. If it's another
674 * requested access type, break.
675 *
676 * 3) Only level2 around: Grant level2 and do nothing else.
677 */
678
679static bool delay_for_oplocks(struct share_mode_lock *lck,
680 files_struct *fsp,
681 uint16 mid,
682 int pass_number,
683 int oplock_request)
684{
685 int i;
686 struct share_mode_entry *exclusive = NULL;
687 bool valid_entry = False;
688 bool delay_it = False;
689 bool have_level2 = False;
690 NTSTATUS status;
691 char msg[MSG_SMB_SHARE_MODE_ENTRY_SIZE];
692
693 if (oplock_request & INTERNAL_OPEN_ONLY) {
694 fsp->oplock_type = NO_OPLOCK;
695 }
696
697 if ((oplock_request & INTERNAL_OPEN_ONLY) || is_stat_open(fsp->access_mask)) {
698 return False;
699 }
700
701 for (i=0; i<lck->num_share_modes; i++) {
702
703 if (!is_valid_share_mode_entry(&lck->share_modes[i])) {
704 continue;
705 }
706
707 /* At least one entry is not an invalid or deferred entry. */
708 valid_entry = True;
709
710 if (pass_number == 1) {
711 if (BATCH_OPLOCK_TYPE(lck->share_modes[i].op_type)) {
712 SMB_ASSERT(exclusive == NULL);
713 exclusive = &lck->share_modes[i];
714 }
715 } else {
716 if (EXCLUSIVE_OPLOCK_TYPE(lck->share_modes[i].op_type)) {
717 SMB_ASSERT(exclusive == NULL);
718 exclusive = &lck->share_modes[i];
719 }
720 }
721
722 if (lck->share_modes[i].op_type == LEVEL_II_OPLOCK) {
723 SMB_ASSERT(exclusive == NULL);
724 have_level2 = True;
725 }
726 }
727
728 if (!valid_entry) {
729 /* All entries are placeholders or deferred.
730 * Directly grant whatever the client wants. */
731 if (fsp->oplock_type == NO_OPLOCK) {
732 /* Store a level2 oplock, but don't tell the client */
733 fsp->oplock_type = FAKE_LEVEL_II_OPLOCK;
734 }
735 return False;
736 }
737
738 if (exclusive != NULL) { /* Found an exclusive oplock */
739 SMB_ASSERT(!have_level2);
740 delay_it = is_delete_request(fsp) ?
741 BATCH_OPLOCK_TYPE(exclusive->op_type) : True;
742 }
743
744 if (EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type)) {
745 /* We can at most grant level2 as there are other
746 * level2 or NO_OPLOCK entries. */
747 fsp->oplock_type = LEVEL_II_OPLOCK;
748 }
749
750 if ((fsp->oplock_type == NO_OPLOCK) && have_level2) {
751 /* Store a level2 oplock, but don't tell the client */
752 fsp->oplock_type = FAKE_LEVEL_II_OPLOCK;
753 }
754
755 if (!delay_it) {
756 return False;
757 }
758
759 /*
760 * Send a break message to the oplock holder and delay the open for
761 * our client.
762 */
763
764 DEBUG(10, ("Sending break request to PID %s\n",
765 procid_str_static(&exclusive->pid)));
766 exclusive->op_mid = mid;
767
768 /* Create the message. */
769 share_mode_entry_to_message(msg, exclusive);
770
771 /* Add in the FORCE_OPLOCK_BREAK_TO_NONE bit in the message if set. We
772 don't want this set in the share mode struct pointed to by lck. */
773
774 if (oplock_request & FORCE_OPLOCK_BREAK_TO_NONE) {
775 SSVAL(msg,6,exclusive->op_type | FORCE_OPLOCK_BREAK_TO_NONE);
776 }
777
778 status = messaging_send_buf(smbd_messaging_context(), exclusive->pid,
779 MSG_SMB_BREAK_REQUEST,
780 (uint8 *)msg,
781 MSG_SMB_SHARE_MODE_ENTRY_SIZE);
782 if (!NT_STATUS_IS_OK(status)) {
783 DEBUG(3, ("Could not send oplock break message: %s\n",
784 nt_errstr(status)));
785 }
786
787 return True;
788}
789
790static bool request_timed_out(struct timeval request_time,
791 struct timeval timeout)
792{
793 struct timeval now, end_time;
794 GetTimeOfDay(&now);
795 end_time = timeval_sum(&request_time, &timeout);
796 return (timeval_compare(&end_time, &now) < 0);
797}
798
799/****************************************************************************
800 Handle the 1 second delay in returning a SHARING_VIOLATION error.
801****************************************************************************/
802
803static void defer_open(struct share_mode_lock *lck,
804 struct timeval request_time,
805 struct timeval timeout,
806 struct smb_request *req,
807 struct deferred_open_record *state)
808{
809 int i;
810
811 /* Paranoia check */
812
813 for (i=0; i<lck->num_share_modes; i++) {
814 struct share_mode_entry *e = &lck->share_modes[i];
815
816 if (!is_deferred_open_entry(e)) {
817 continue;
818 }
819
820 if (procid_is_me(&e->pid) && (e->op_mid == req->mid)) {
821 DEBUG(0, ("Trying to defer an already deferred "
822 "request: mid=%d, exiting\n", req->mid));
823 exit_server("attempt to defer a deferred request");
824 }
825 }
826
827 /* End paranoia check */
828
829 DEBUG(10,("defer_open_sharing_error: time [%u.%06u] adding deferred "
830 "open entry for mid %u\n",
831 (unsigned int)request_time.tv_sec,
832 (unsigned int)request_time.tv_usec,
833 (unsigned int)req->mid));
834
835 if (!push_deferred_smb_message(req, request_time, timeout,
836 (char *)state, sizeof(*state))) {
837 exit_server("push_deferred_smb_message failed");
838 }
839 add_deferred_open(lck, req->mid, request_time, state->id);
840
841 /*
842 * Push the MID of this packet on the signing queue.
843 * We only do this once, the first time we push the packet
844 * onto the deferred open queue, as this has a side effect
845 * of incrementing the response sequence number.
846 */
847
848 srv_defer_sign_response(req->mid);
849}
850
851
852/****************************************************************************
853 On overwrite open ensure that the attributes match.
854****************************************************************************/
855
856static bool open_match_attributes(connection_struct *conn,
857 const char *path,
858 uint32 old_dos_attr,
859 uint32 new_dos_attr,
860 mode_t existing_unx_mode,
861 mode_t new_unx_mode,
862 mode_t *returned_unx_mode)
863{
864 uint32 noarch_old_dos_attr, noarch_new_dos_attr;
865
866 noarch_old_dos_attr = (old_dos_attr & ~FILE_ATTRIBUTE_ARCHIVE);
867 noarch_new_dos_attr = (new_dos_attr & ~FILE_ATTRIBUTE_ARCHIVE);
868
869 if((noarch_old_dos_attr == 0 && noarch_new_dos_attr != 0) ||
870 (noarch_old_dos_attr != 0 && ((noarch_old_dos_attr & noarch_new_dos_attr) == noarch_old_dos_attr))) {
871 *returned_unx_mode = new_unx_mode;
872 } else {
873 *returned_unx_mode = (mode_t)0;
874 }
875
876 DEBUG(10,("open_match_attributes: file %s old_dos_attr = 0x%x, "
877 "existing_unx_mode = 0%o, new_dos_attr = 0x%x "
878 "returned_unx_mode = 0%o\n",
879 path,
880 (unsigned int)old_dos_attr,
881 (unsigned int)existing_unx_mode,
882 (unsigned int)new_dos_attr,
883 (unsigned int)*returned_unx_mode ));
884
885 /* If we're mapping SYSTEM and HIDDEN ensure they match. */
886 if (lp_map_system(SNUM(conn)) || lp_store_dos_attributes(SNUM(conn))) {
887 if ((old_dos_attr & FILE_ATTRIBUTE_SYSTEM) &&
888 !(new_dos_attr & FILE_ATTRIBUTE_SYSTEM)) {
889 return False;
890 }
891 }
892 if (lp_map_hidden(SNUM(conn)) || lp_store_dos_attributes(SNUM(conn))) {
893 if ((old_dos_attr & FILE_ATTRIBUTE_HIDDEN) &&
894 !(new_dos_attr & FILE_ATTRIBUTE_HIDDEN)) {
895 return False;
896 }
897 }
898 return True;
899}
900
901/****************************************************************************
902 Special FCB or DOS processing in the case of a sharing violation.
903 Try and find a duplicated file handle.
904****************************************************************************/
905
906static NTSTATUS fcb_or_dos_open(connection_struct *conn,
907 files_struct *fsp_to_dup_into,
908 const char *fname,
909 struct file_id id,
910 uint16 file_pid,
911 uint16 vuid,
912 uint32 access_mask,
913 uint32 share_access,
914 uint32 create_options)
915{
916 files_struct *fsp;
917
918 DEBUG(5,("fcb_or_dos_open: attempting old open semantics for "
919 "file %s.\n", fname ));
920
921 for(fsp = file_find_di_first(id); fsp;
922 fsp = file_find_di_next(fsp)) {
923
924 DEBUG(10,("fcb_or_dos_open: checking file %s, fd = %d, "
925 "vuid = %u, file_pid = %u, private_options = 0x%x "
926 "access_mask = 0x%x\n", fsp->fsp_name,
927 fsp->fh->fd, (unsigned int)fsp->vuid,
928 (unsigned int)fsp->file_pid,
929 (unsigned int)fsp->fh->private_options,
930 (unsigned int)fsp->access_mask ));
931
932 if (fsp->fh->fd != -1 &&
933 fsp->vuid == vuid &&
934 fsp->file_pid == file_pid &&
935 (fsp->fh->private_options & (NTCREATEX_OPTIONS_PRIVATE_DENY_DOS |
936 NTCREATEX_OPTIONS_PRIVATE_DENY_FCB)) &&
937 (fsp->access_mask & FILE_WRITE_DATA) &&
938 strequal(fsp->fsp_name, fname)) {
939 DEBUG(10,("fcb_or_dos_open: file match\n"));
940 break;
941 }
942 }
943
944 if (!fsp) {
945 return NT_STATUS_NOT_FOUND;
946 }
947
948 /* quite an insane set of semantics ... */
949 if (is_executable(fname) &&
950 (fsp->fh->private_options & NTCREATEX_OPTIONS_PRIVATE_DENY_DOS)) {
951 DEBUG(10,("fcb_or_dos_open: file fail due to is_executable.\n"));
952 return NT_STATUS_INVALID_PARAMETER;
953 }
954
955 /* We need to duplicate this fsp. */
956 dup_file_fsp(fsp, access_mask, share_access,
957 create_options, fsp_to_dup_into);
958
959 return NT_STATUS_OK;
960}
961
962/****************************************************************************
963 Open a file with a share mode - old openX method - map into NTCreate.
964****************************************************************************/
965
966bool map_open_params_to_ntcreate(const char *fname, int deny_mode, int open_func,
967 uint32 *paccess_mask,
968 uint32 *pshare_mode,
969 uint32 *pcreate_disposition,
970 uint32 *pcreate_options)
971{
972 uint32 access_mask;
973 uint32 share_mode;
974 uint32 create_disposition;
975 uint32 create_options = 0;
976
977 DEBUG(10,("map_open_params_to_ntcreate: fname = %s, deny_mode = 0x%x, "
978 "open_func = 0x%x\n",
979 fname, (unsigned int)deny_mode, (unsigned int)open_func ));
980
981 /* Create the NT compatible access_mask. */
982 switch (GET_OPENX_MODE(deny_mode)) {
983 case DOS_OPEN_EXEC: /* Implies read-only - used to be FILE_READ_DATA */
984 case DOS_OPEN_RDONLY:
985 access_mask = FILE_GENERIC_READ;
986 break;
987 case DOS_OPEN_WRONLY:
988 access_mask = FILE_GENERIC_WRITE;
989 break;
990 case DOS_OPEN_RDWR:
991 case DOS_OPEN_FCB:
992 access_mask = FILE_GENERIC_READ|FILE_GENERIC_WRITE;
993 break;
994 default:
995 DEBUG(10,("map_open_params_to_ntcreate: bad open mode = 0x%x\n",
996 (unsigned int)GET_OPENX_MODE(deny_mode)));
997 return False;
998 }
999
1000 /* Create the NT compatible create_disposition. */
1001 switch (open_func) {
1002 case OPENX_FILE_EXISTS_FAIL|OPENX_FILE_CREATE_IF_NOT_EXIST:
1003 create_disposition = FILE_CREATE;
1004 break;
1005
1006 case OPENX_FILE_EXISTS_OPEN:
1007 create_disposition = FILE_OPEN;
1008 break;
1009
1010 case OPENX_FILE_EXISTS_OPEN|OPENX_FILE_CREATE_IF_NOT_EXIST:
1011 create_disposition = FILE_OPEN_IF;
1012 break;
1013
1014 case OPENX_FILE_EXISTS_TRUNCATE:
1015 create_disposition = FILE_OVERWRITE;
1016 break;
1017
1018 case OPENX_FILE_EXISTS_TRUNCATE|OPENX_FILE_CREATE_IF_NOT_EXIST:
1019 create_disposition = FILE_OVERWRITE_IF;
1020 break;
1021
1022 default:
1023 /* From samba4 - to be confirmed. */
1024 if (GET_OPENX_MODE(deny_mode) == DOS_OPEN_EXEC) {
1025 create_disposition = FILE_CREATE;
1026 break;
1027 }
1028 DEBUG(10,("map_open_params_to_ntcreate: bad "
1029 "open_func 0x%x\n", (unsigned int)open_func));
1030 return False;
1031 }
1032
1033 /* Create the NT compatible share modes. */
1034 switch (GET_DENY_MODE(deny_mode)) {
1035 case DENY_ALL:
1036 share_mode = FILE_SHARE_NONE;
1037 break;
1038
1039 case DENY_WRITE:
1040 share_mode = FILE_SHARE_READ;
1041 break;
1042
1043 case DENY_READ:
1044 share_mode = FILE_SHARE_WRITE;
1045 break;
1046
1047 case DENY_NONE:
1048 share_mode = FILE_SHARE_READ|FILE_SHARE_WRITE;
1049 break;
1050
1051 case DENY_DOS:
1052 create_options |= NTCREATEX_OPTIONS_PRIVATE_DENY_DOS;
1053 if (is_executable(fname)) {
1054 share_mode = FILE_SHARE_READ|FILE_SHARE_WRITE;
1055 } else {
1056 if (GET_OPENX_MODE(deny_mode) == DOS_OPEN_RDONLY) {
1057 share_mode = FILE_SHARE_READ;
1058 } else {
1059 share_mode = FILE_SHARE_NONE;
1060 }
1061 }
1062 break;
1063
1064 case DENY_FCB:
1065 create_options |= NTCREATEX_OPTIONS_PRIVATE_DENY_FCB;
1066 share_mode = FILE_SHARE_NONE;
1067 break;
1068
1069 default:
1070 DEBUG(10,("map_open_params_to_ntcreate: bad deny_mode 0x%x\n",
1071 (unsigned int)GET_DENY_MODE(deny_mode) ));
1072 return False;
1073 }
1074
1075 DEBUG(10,("map_open_params_to_ntcreate: file %s, access_mask = 0x%x, "
1076 "share_mode = 0x%x, create_disposition = 0x%x, "
1077 "create_options = 0x%x\n",
1078 fname,
1079 (unsigned int)access_mask,
1080 (unsigned int)share_mode,
1081 (unsigned int)create_disposition,
1082 (unsigned int)create_options ));
1083
1084 if (paccess_mask) {
1085 *paccess_mask = access_mask;
1086 }
1087 if (pshare_mode) {
1088 *pshare_mode = share_mode;
1089 }
1090 if (pcreate_disposition) {
1091 *pcreate_disposition = create_disposition;
1092 }
1093 if (pcreate_options) {
1094 *pcreate_options = create_options;
1095 }
1096
1097 return True;
1098
1099}
1100
1101static void schedule_defer_open(struct share_mode_lock *lck,
1102 struct timeval request_time,
1103 struct smb_request *req)
1104{
1105 struct deferred_open_record state;
1106
1107 /* This is a relative time, added to the absolute
1108 request_time value to get the absolute timeout time.
1109 Note that if this is the second or greater time we enter
1110 this codepath for this particular request mid then
1111 request_time is left as the absolute time of the *first*
1112 time this request mid was processed. This is what allows
1113 the request to eventually time out. */
1114
1115 struct timeval timeout;
1116
1117 /* Normally the smbd we asked should respond within
1118 * OPLOCK_BREAK_TIMEOUT seconds regardless of whether
1119 * the client did, give twice the timeout as a safety
1120 * measure here in case the other smbd is stuck
1121 * somewhere else. */
1122
1123 timeout = timeval_set(OPLOCK_BREAK_TIMEOUT*2, 0);
1124
1125 /* Nothing actually uses state.delayed_for_oplocks
1126 but it's handy to differentiate in debug messages
1127 between a 30 second delay due to oplock break, and
1128 a 1 second delay for share mode conflicts. */
1129
1130 state.delayed_for_oplocks = True;
1131 state.id = lck->id;
1132
1133 if (!request_timed_out(request_time, timeout)) {
1134 defer_open(lck, request_time, timeout, req, &state);
1135 }
1136}
1137
1138/****************************************************************************
1139 Open a file with a share mode. Passed in an already created files_struct *.
1140****************************************************************************/
1141
1142static NTSTATUS open_file_ntcreate_internal(connection_struct *conn,
1143 struct smb_request *req,
1144 const char *fname,
1145 SMB_STRUCT_STAT *psbuf,
1146 uint32 access_mask, /* access bits (FILE_READ_DATA etc.) */
1147 uint32 share_access, /* share constants (FILE_SHARE_READ etc) */
1148 uint32 create_disposition, /* FILE_OPEN_IF etc. */
1149 uint32 create_options, /* options such as delete on close. */
1150 uint32 new_dos_attributes, /* attributes used for new file. */
1151 int oplock_request, /* internal Samba oplock codes. */
1152 /* Information (FILE_EXISTS etc.) */
1153 int *pinfo,
1154 files_struct *fsp)
1155{
1156 int flags=0;
1157 int flags2=0;
1158 bool file_existed = VALID_STAT(*psbuf);
1159 bool def_acl = False;
1160 bool posix_open = False;
1161 bool new_file_created = False;
1162 struct file_id id;
1163 NTSTATUS fsp_open = NT_STATUS_ACCESS_DENIED;
1164 mode_t new_unx_mode = (mode_t)0;
1165 mode_t unx_mode = (mode_t)0;
1166 int info;
1167 uint32 existing_dos_attributes = 0;
1168 struct pending_message_list *pml = NULL;
1169 struct timeval request_time = timeval_zero();
1170 struct share_mode_lock *lck = NULL;
1171 uint32 open_access_mask = access_mask;
1172 NTSTATUS status;
1173 int ret_flock;
1174 char *parent_dir;
1175 const char *newname;
1176
1177 ZERO_STRUCT(id);
1178
1179 if (conn->printer) {
1180 /*
1181 * Printers are handled completely differently.
1182 * Most of the passed parameters are ignored.
1183 */
1184
1185 if (pinfo) {
1186 *pinfo = FILE_WAS_CREATED;
1187 }
1188
1189 DEBUG(10, ("open_file_ntcreate: printer open fname=%s\n", fname));
1190
1191 return print_fsp_open(conn, fname, fsp);
1192 }
1193
1194 if (!parent_dirname_talloc(talloc_tos(), fname, &parent_dir,
1195 &newname)) {
1196 return NT_STATUS_NO_MEMORY;
1197 }
1198
1199 if (new_dos_attributes & FILE_FLAG_POSIX_SEMANTICS) {
1200 posix_open = True;
1201 unx_mode = (mode_t)(new_dos_attributes & ~FILE_FLAG_POSIX_SEMANTICS);
1202 new_dos_attributes = 0;
1203 } else {
1204 /* We add aARCH to this as this mode is only used if the file is
1205 * created new. */
1206 unx_mode = unix_mode(conn, new_dos_attributes | aARCH, fname,
1207 parent_dir);
1208 }
1209
1210 DEBUG(10, ("open_file_ntcreate: fname=%s, dos_attrs=0x%x "
1211 "access_mask=0x%x share_access=0x%x "
1212 "create_disposition = 0x%x create_options=0x%x "
1213 "unix mode=0%o oplock_request=%d\n",
1214 fname, new_dos_attributes, access_mask, share_access,
1215 create_disposition, create_options, unx_mode,
1216 oplock_request));
1217
1218 if ((req == NULL) && ((oplock_request & INTERNAL_OPEN_ONLY) == 0)) {
1219 DEBUG(0, ("No smb request but not an internal only open!\n"));
1220 return NT_STATUS_INTERNAL_ERROR;
1221 }
1222
1223 /*
1224 * Only non-internal opens can be deferred at all
1225 */
1226
1227 if ((req != NULL)
1228 && ((pml = get_open_deferred_message(req->mid)) != NULL)) {
1229 struct deferred_open_record *state =
1230 (struct deferred_open_record *)pml->private_data.data;
1231
1232 /* Remember the absolute time of the original
1233 request with this mid. We'll use it later to
1234 see if this has timed out. */
1235
1236 request_time = pml->request_time;
1237
1238 /* Remove the deferred open entry under lock. */
1239 lck = get_share_mode_lock(talloc_tos(), state->id, NULL, NULL,
1240 NULL);
1241 if (lck == NULL) {
1242 DEBUG(0, ("could not get share mode lock\n"));
1243 } else {
1244 del_deferred_open_entry(lck, req->mid);
1245 TALLOC_FREE(lck);
1246 }
1247
1248 /* Ensure we don't reprocess this message. */
1249 remove_deferred_open_smb_message(req->mid);
1250 }
1251
1252 status = check_name(conn, fname);
1253 if (!NT_STATUS_IS_OK(status)) {
1254 return status;
1255 }
1256
1257 if (!posix_open) {
1258 new_dos_attributes &= SAMBA_ATTRIBUTES_MASK;
1259 if (file_existed) {
1260 existing_dos_attributes = dos_mode(conn, fname, psbuf);
1261 }
1262 }
1263
1264 /* ignore any oplock requests if oplocks are disabled */
1265 if (!lp_oplocks(SNUM(conn)) || global_client_failed_oplock_break ||
1266 IS_VETO_OPLOCK_PATH(conn, fname)) {
1267 /* Mask off everything except the private Samba bits. */
1268 oplock_request &= SAMBA_PRIVATE_OPLOCK_MASK;
1269 }
1270
1271 /* this is for OS/2 long file names - say we don't support them */
1272 if (!lp_posix_pathnames() && strstr(fname,".+,;=[].")) {
1273 /* OS/2 Workplace shell fix may be main code stream in a later
1274 * release. */
1275 DEBUG(5,("open_file_ntcreate: OS/2 long filenames are not "
1276 "supported.\n"));
1277 if (use_nt_status()) {
1278 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1279 }
1280 return NT_STATUS_DOS(ERRDOS, ERRcannotopen);
1281 }
1282
1283 switch( create_disposition ) {
1284 /*
1285 * Currently we're using FILE_SUPERSEDE as the same as
1286 * FILE_OVERWRITE_IF but they really are
1287 * different. FILE_SUPERSEDE deletes an existing file
1288 * (requiring delete access) then recreates it.
1289 */
1290 case FILE_SUPERSEDE:
1291 /* If file exists replace/overwrite. If file doesn't
1292 * exist create. */
1293 flags2 |= (O_CREAT | O_TRUNC);
1294 break;
1295
1296 case FILE_OVERWRITE_IF:
1297 /* If file exists replace/overwrite. If file doesn't
1298 * exist create. */
1299 flags2 |= (O_CREAT | O_TRUNC);
1300 break;
1301
1302 case FILE_OPEN:
1303 /* If file exists open. If file doesn't exist error. */
1304 if (!file_existed) {
1305 DEBUG(5,("open_file_ntcreate: FILE_OPEN "
1306 "requested for file %s and file "
1307 "doesn't exist.\n", fname ));
1308 errno = ENOENT;
1309 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1310 }
1311 break;
1312
1313 case FILE_OVERWRITE:
1314 /* If file exists overwrite. If file doesn't exist
1315 * error. */
1316 if (!file_existed) {
1317 DEBUG(5,("open_file_ntcreate: FILE_OVERWRITE "
1318 "requested for file %s and file "
1319 "doesn't exist.\n", fname ));
1320 errno = ENOENT;
1321 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1322 }
1323 flags2 |= O_TRUNC;
1324 break;
1325
1326 case FILE_CREATE:
1327 /* If file exists error. If file doesn't exist
1328 * create. */
1329 if (file_existed) {
1330 DEBUG(5,("open_file_ntcreate: FILE_CREATE "
1331 "requested for file %s and file "
1332 "already exists.\n", fname ));
1333 if (S_ISDIR(psbuf->st_mode)) {
1334 errno = EISDIR;
1335 } else {
1336 errno = EEXIST;
1337 }
1338 return map_nt_error_from_unix(errno);
1339 }
1340 flags2 |= (O_CREAT|O_EXCL);
1341 break;
1342
1343 case FILE_OPEN_IF:
1344 /* If file exists open. If file doesn't exist
1345 * create. */
1346 flags2 |= O_CREAT;
1347 break;
1348
1349 default:
1350 return NT_STATUS_INVALID_PARAMETER;
1351 }
1352
1353 /* We only care about matching attributes on file exists and
1354 * overwrite. */
1355
1356 if (!posix_open && file_existed && ((create_disposition == FILE_OVERWRITE) ||
1357 (create_disposition == FILE_OVERWRITE_IF))) {
1358 if (!open_match_attributes(conn, fname,
1359 existing_dos_attributes,
1360 new_dos_attributes, psbuf->st_mode,
1361 unx_mode, &new_unx_mode)) {
1362 DEBUG(5,("open_file_ntcreate: attributes missmatch "
1363 "for file %s (%x %x) (0%o, 0%o)\n",
1364 fname, existing_dos_attributes,
1365 new_dos_attributes,
1366 (unsigned int)psbuf->st_mode,
1367 (unsigned int)unx_mode ));
1368 errno = EACCES;
1369 return NT_STATUS_ACCESS_DENIED;
1370 }
1371 }
1372
1373 /* This is a nasty hack - must fix... JRA. */
1374 if (access_mask == MAXIMUM_ALLOWED_ACCESS) {
1375 open_access_mask = access_mask = FILE_GENERIC_ALL;
1376 }
1377
1378 /*
1379 * Convert GENERIC bits to specific bits.
1380 */
1381
1382 se_map_generic(&access_mask, &file_generic_mapping);
1383 open_access_mask = access_mask;
1384
1385 if ((flags2 & O_TRUNC) || (oplock_request & FORCE_OPLOCK_BREAK_TO_NONE)) {
1386 open_access_mask |= FILE_WRITE_DATA; /* This will cause oplock breaks. */
1387 }
1388
1389 DEBUG(10, ("open_file_ntcreate: fname=%s, after mapping "
1390 "access_mask=0x%x\n", fname, access_mask ));
1391
1392 /*
1393 * Note that we ignore the append flag as append does not
1394 * mean the same thing under DOS and Unix.
1395 */
1396
1397 if ((access_mask & (FILE_WRITE_DATA | FILE_APPEND_DATA)) ||
1398 (oplock_request & FORCE_OPLOCK_BREAK_TO_NONE)) {
1399 /* DENY_DOS opens are always underlying read-write on the
1400 file handle, no matter what the requested access mask
1401 says. */
1402 if ((create_options & NTCREATEX_OPTIONS_PRIVATE_DENY_DOS) ||
1403 access_mask & (FILE_READ_ATTRIBUTES|FILE_READ_DATA|FILE_READ_EA|FILE_EXECUTE)) {
1404 flags = O_RDWR;
1405 } else {
1406 flags = O_WRONLY;
1407 }
1408 } else {
1409 flags = O_RDONLY;
1410 }
1411
1412 /*
1413 * Currently we only look at FILE_WRITE_THROUGH for create options.
1414 */
1415
1416#if defined(O_SYNC)
1417 if ((create_options & FILE_WRITE_THROUGH) && lp_strict_sync(SNUM(conn))) {
1418 flags2 |= O_SYNC;
1419 }
1420#endif /* O_SYNC */
1421
1422 if (posix_open && (access_mask & FILE_APPEND_DATA)) {
1423 flags2 |= O_APPEND;
1424 }
1425
1426 if (!posix_open && !CAN_WRITE(conn)) {
1427 /*
1428 * We should really return a permission denied error if either
1429 * O_CREAT or O_TRUNC are set, but for compatibility with
1430 * older versions of Samba we just AND them out.
1431 */
1432 flags2 &= ~(O_CREAT|O_TRUNC);
1433 }
1434
1435 /*
1436 * Ensure we can't write on a read-only share or file.
1437 */
1438
1439 if (flags != O_RDONLY && file_existed &&
1440 (!CAN_WRITE(conn) || IS_DOS_READONLY(existing_dos_attributes))) {
1441 DEBUG(5,("open_file_ntcreate: write access requested for "
1442 "file %s on read only %s\n",
1443 fname, !CAN_WRITE(conn) ? "share" : "file" ));
1444 errno = EACCES;
1445 return NT_STATUS_ACCESS_DENIED;
1446 }
1447
1448 fsp->file_id = vfs_file_id_from_sbuf(conn, psbuf);
1449 fsp->share_access = share_access;
1450 fsp->fh->private_options = create_options;
1451 fsp->access_mask = open_access_mask; /* We change this to the
1452 * requested access_mask after
1453 * the open is done. */
1454 fsp->posix_open = posix_open;
1455
1456 /* Ensure no SAMBA_PRIVATE bits can be set. */
1457 fsp->oplock_type = (oplock_request & ~SAMBA_PRIVATE_OPLOCK_MASK);
1458
1459 if (timeval_is_zero(&request_time)) {
1460 request_time = fsp->open_time;
1461 }
1462
1463 if (file_existed) {
1464 struct timespec old_write_time = get_mtimespec(psbuf);
1465 id = vfs_file_id_from_sbuf(conn, psbuf);
1466
1467 lck = get_share_mode_lock(talloc_tos(), id,
1468 conn->connectpath,
1469 fname, &old_write_time);
1470
1471 if (lck == NULL) {
1472 DEBUG(0, ("Could not get share mode lock\n"));
1473 return NT_STATUS_SHARING_VIOLATION;
1474 }
1475
1476 /* First pass - send break only on batch oplocks. */
1477 if ((req != NULL)
1478 && delay_for_oplocks(lck, fsp, req->mid, 1,
1479 oplock_request)) {
1480 schedule_defer_open(lck, request_time, req);
1481 TALLOC_FREE(lck);
1482 return NT_STATUS_SHARING_VIOLATION;
1483 }
1484
1485 /* Use the client requested access mask here, not the one we
1486 * open with. */
1487 status = open_mode_check(conn, fname, lck,
1488 access_mask, share_access,
1489 create_options, &file_existed);
1490
1491 if (NT_STATUS_IS_OK(status)) {
1492 /* We might be going to allow this open. Check oplock
1493 * status again. */
1494 /* Second pass - send break for both batch or
1495 * exclusive oplocks. */
1496 if ((req != NULL)
1497 && delay_for_oplocks(lck, fsp, req->mid, 2,
1498 oplock_request)) {
1499 schedule_defer_open(lck, request_time, req);
1500 TALLOC_FREE(lck);
1501 return NT_STATUS_SHARING_VIOLATION;
1502 }
1503 }
1504
1505 if (NT_STATUS_EQUAL(status, NT_STATUS_DELETE_PENDING)) {
1506 /* DELETE_PENDING is not deferred for a second */
1507 TALLOC_FREE(lck);
1508 return status;
1509 }
1510
1511 if (!NT_STATUS_IS_OK(status)) {
1512 uint32 can_access_mask;
1513 bool can_access = True;
1514
1515 SMB_ASSERT(NT_STATUS_EQUAL(status, NT_STATUS_SHARING_VIOLATION));
1516
1517 /* Check if this can be done with the deny_dos and fcb
1518 * calls. */
1519 if (create_options &
1520 (NTCREATEX_OPTIONS_PRIVATE_DENY_DOS|
1521 NTCREATEX_OPTIONS_PRIVATE_DENY_FCB)) {
1522 if (req == NULL) {
1523 DEBUG(0, ("DOS open without an SMB "
1524 "request!\n"));
1525 TALLOC_FREE(lck);
1526 return NT_STATUS_INTERNAL_ERROR;
1527 }
1528
1529 /* Use the client requested access mask here,
1530 * not the one we open with. */
1531 status = fcb_or_dos_open(conn,
1532 fsp,
1533 fname,
1534 id,
1535 req->smbpid,
1536 req->vuid,
1537 access_mask,
1538 share_access,
1539 create_options);
1540
1541 if (NT_STATUS_IS_OK(status)) {
1542 TALLOC_FREE(lck);
1543 if (pinfo) {
1544 *pinfo = FILE_WAS_OPENED;
1545 }
1546 return NT_STATUS_OK;
1547 }
1548 }
1549
1550 /*
1551 * This next line is a subtlety we need for
1552 * MS-Access. If a file open will fail due to share
1553 * permissions and also for security (access) reasons,
1554 * we need to return the access failed error, not the
1555 * share error. We can't open the file due to kernel
1556 * oplock deadlock (it's possible we failed above on
1557 * the open_mode_check()) so use a userspace check.
1558 */
1559
1560 if (flags & O_RDWR) {
1561 can_access_mask = FILE_READ_DATA|FILE_WRITE_DATA;
1562 } else if (flags & O_WRONLY) {
1563 can_access_mask = FILE_WRITE_DATA;
1564 } else {
1565 can_access_mask = FILE_READ_DATA;
1566 }
1567
1568 if (((can_access_mask & FILE_WRITE_DATA) && !CAN_WRITE(conn)) ||
1569 !can_access_file(conn,fname,psbuf,can_access_mask)) {
1570 can_access = False;
1571 }
1572
1573 /*
1574 * If we're returning a share violation, ensure we
1575 * cope with the braindead 1 second delay.
1576 */
1577
1578 if (!(oplock_request & INTERNAL_OPEN_ONLY) &&
1579 lp_defer_sharing_violations()) {
1580 struct timeval timeout;
1581 struct deferred_open_record state;
1582 int timeout_usecs;
1583
1584 /* this is a hack to speed up torture tests
1585 in 'make test' */
1586 timeout_usecs = lp_parm_int(SNUM(conn),
1587 "smbd","sharedelay",
1588 SHARING_VIOLATION_USEC_WAIT);
1589
1590 /* This is a relative time, added to the absolute
1591 request_time value to get the absolute timeout time.
1592 Note that if this is the second or greater time we enter
1593 this codepath for this particular request mid then
1594 request_time is left as the absolute time of the *first*
1595 time this request mid was processed. This is what allows
1596 the request to eventually time out. */
1597
1598 timeout = timeval_set(0, timeout_usecs);
1599
1600 /* Nothing actually uses state.delayed_for_oplocks
1601 but it's handy to differentiate in debug messages
1602 between a 30 second delay due to oplock break, and
1603 a 1 second delay for share mode conflicts. */
1604
1605 state.delayed_for_oplocks = False;
1606 state.id = id;
1607
1608 if ((req != NULL)
1609 && !request_timed_out(request_time,
1610 timeout)) {
1611 defer_open(lck, request_time, timeout,
1612 req, &state);
1613 }
1614 }
1615
1616 TALLOC_FREE(lck);
1617 if (can_access) {
1618 /*
1619 * We have detected a sharing violation here
1620 * so return the correct error code
1621 */
1622 status = NT_STATUS_SHARING_VIOLATION;
1623 } else {
1624 status = NT_STATUS_ACCESS_DENIED;
1625 }
1626 return status;
1627 }
1628
1629 /*
1630 * We exit this block with the share entry *locked*.....
1631 */
1632 }
1633
1634 SMB_ASSERT(!file_existed || (lck != NULL));
1635
1636 /*
1637 * Ensure we pay attention to default ACLs on directories if required.
1638 */
1639
1640 if ((flags2 & O_CREAT) && lp_inherit_acls(SNUM(conn)) &&
1641 (def_acl = directory_has_default_acl(conn, parent_dir))) {
1642 unx_mode = 0777;
1643 }
1644
1645 DEBUG(4,("calling open_file with flags=0x%X flags2=0x%X mode=0%o, "
1646 "access_mask = 0x%x, open_access_mask = 0x%x\n",
1647 (unsigned int)flags, (unsigned int)flags2,
1648 (unsigned int)unx_mode, (unsigned int)access_mask,
1649 (unsigned int)open_access_mask));
1650
1651 /*
1652 * open_file strips any O_TRUNC flags itself.
1653 */
1654
1655 fsp_open = open_file(fsp, conn, req, parent_dir, newname, fname, psbuf,
1656 flags|flags2, unx_mode, access_mask,
1657 open_access_mask);
1658
1659 if (!NT_STATUS_IS_OK(fsp_open)) {
1660 if (lck != NULL) {
1661 TALLOC_FREE(lck);
1662 }
1663 return fsp_open;
1664 }
1665
1666 if (!file_existed) {
1667 struct timespec old_write_time = get_mtimespec(psbuf);
1668 /*
1669 * Deal with the race condition where two smbd's detect the
1670 * file doesn't exist and do the create at the same time. One
1671 * of them will win and set a share mode, the other (ie. this
1672 * one) should check if the requested share mode for this
1673 * create is allowed.
1674 */
1675
1676 /*
1677 * Now the file exists and fsp is successfully opened,
1678 * fsp->dev and fsp->inode are valid and should replace the
1679 * dev=0,inode=0 from a non existent file. Spotted by
1680 * Nadav Danieli <nadavd@exanet.com>. JRA.
1681 */
1682
1683 id = fsp->file_id;
1684
1685 lck = get_share_mode_lock(talloc_tos(), id,
1686 conn->connectpath,
1687 fname, &old_write_time);
1688
1689 if (lck == NULL) {
1690 DEBUG(0, ("open_file_ntcreate: Could not get share "
1691 "mode lock for %s\n", fname));
1692 fd_close(fsp);
1693 return NT_STATUS_SHARING_VIOLATION;
1694 }
1695
1696 /* First pass - send break only on batch oplocks. */
1697 if ((req != NULL)
1698 && delay_for_oplocks(lck, fsp, req->mid, 1,
1699 oplock_request)) {
1700 schedule_defer_open(lck, request_time, req);
1701 TALLOC_FREE(lck);
1702 fd_close(fsp);
1703 return NT_STATUS_SHARING_VIOLATION;
1704 }
1705
1706 status = open_mode_check(conn, fname, lck,
1707 access_mask, share_access,
1708 create_options, &file_existed);
1709
1710 if (NT_STATUS_IS_OK(status)) {
1711 /* We might be going to allow this open. Check oplock
1712 * status again. */
1713 /* Second pass - send break for both batch or
1714 * exclusive oplocks. */
1715 if ((req != NULL)
1716 && delay_for_oplocks(lck, fsp, req->mid, 2,
1717 oplock_request)) {
1718 schedule_defer_open(lck, request_time, req);
1719 TALLOC_FREE(lck);
1720 fd_close(fsp);
1721 return NT_STATUS_SHARING_VIOLATION;
1722 }
1723 }
1724
1725 if (!NT_STATUS_IS_OK(status)) {
1726 struct deferred_open_record state;
1727
1728 fd_close(fsp);
1729
1730 state.delayed_for_oplocks = False;
1731 state.id = id;
1732
1733 /* Do it all over again immediately. In the second
1734 * round we will find that the file existed and handle
1735 * the DELETE_PENDING and FCB cases correctly. No need
1736 * to duplicate the code here. Essentially this is a
1737 * "goto top of this function", but don't tell
1738 * anybody... */
1739
1740 if (req != NULL) {
1741 defer_open(lck, request_time, timeval_zero(),
1742 req, &state);
1743 }
1744 TALLOC_FREE(lck);
1745 return status;
1746 }
1747
1748 /*
1749 * We exit this block with the share entry *locked*.....
1750 */
1751
1752 }
1753
1754 SMB_ASSERT(lck != NULL);
1755
1756 /* note that we ignore failure for the following. It is
1757 basically a hack for NFS, and NFS will never set one of
1758 these only read them. Nobody but Samba can ever set a deny
1759 mode and we have already checked our more authoritative
1760 locking database for permission to set this deny mode. If
1761 the kernel refuses the operations then the kernel is wrong.
1762 note that GPFS supports it as well - jmcd */
1763
1764 if (fsp->fh->fd != -1) {
1765 ret_flock = SMB_VFS_KERNEL_FLOCK(fsp, share_access);
1766 if(ret_flock == -1 ){
1767
1768 TALLOC_FREE(lck);
1769 fd_close(fsp);
1770
1771 return NT_STATUS_SHARING_VIOLATION;
1772 }
1773 }
1774
1775 /*
1776 * At this point onwards, we can guarentee that the share entry
1777 * is locked, whether we created the file or not, and that the
1778 * deny mode is compatible with all current opens.
1779 */
1780
1781 /*
1782 * If requested, truncate the file.
1783 */
1784
1785 if (flags2&O_TRUNC) {
1786 /*
1787 * We are modifing the file after open - update the stat
1788 * struct..
1789 */
1790 if ((SMB_VFS_FTRUNCATE(fsp, 0) == -1) ||
1791 (SMB_VFS_FSTAT(fsp, psbuf)==-1)) {
1792 status = map_nt_error_from_unix(errno);
1793 TALLOC_FREE(lck);
1794 fd_close(fsp);
1795 return status;
1796 }
1797 }
1798
1799 /* Record the options we were opened with. */
1800 fsp->share_access = share_access;
1801 fsp->fh->private_options = create_options;
1802 fsp->access_mask = access_mask;
1803
1804 if (file_existed) {
1805 /* stat opens on existing files don't get oplocks. */
1806 if (is_stat_open(open_access_mask)) {
1807 fsp->oplock_type = NO_OPLOCK;
1808 }
1809
1810 if (!(flags2 & O_TRUNC)) {
1811 info = FILE_WAS_OPENED;
1812 } else {
1813 info = FILE_WAS_OVERWRITTEN;
1814 }
1815 } else {
1816 info = FILE_WAS_CREATED;
1817 }
1818
1819 if (pinfo) {
1820 *pinfo = info;
1821 }
1822
1823 /*
1824 * Setup the oplock info in both the shared memory and
1825 * file structs.
1826 */
1827
1828 if ((fsp->oplock_type != NO_OPLOCK) &&
1829 (fsp->oplock_type != FAKE_LEVEL_II_OPLOCK)) {
1830 if (!set_file_oplock(fsp, fsp->oplock_type)) {
1831 /* Could not get the kernel oplock */
1832 fsp->oplock_type = NO_OPLOCK;
1833 }
1834 }
1835
1836 if (info == FILE_WAS_OVERWRITTEN || info == FILE_WAS_CREATED || info == FILE_WAS_SUPERSEDED) {
1837 new_file_created = True;
1838 }
1839
1840 set_share_mode(lck, fsp, current_user.ut.uid, 0, fsp->oplock_type, new_file_created);
1841
1842 /* Handle strange delete on close create semantics. */
1843 if ((create_options & FILE_DELETE_ON_CLOSE)
1844 && (((conn->fs_capabilities & FILE_NAMED_STREAMS)
1845 && is_ntfs_stream_name(fname))
1846 || can_set_initial_delete_on_close(lck))) {
1847 status = can_set_delete_on_close(fsp, True, new_dos_attributes);
1848
1849 if (!NT_STATUS_IS_OK(status)) {
1850 /* Remember to delete the mode we just added. */
1851 del_share_mode(lck, fsp);
1852 TALLOC_FREE(lck);
1853 fd_close(fsp);
1854 return status;
1855 }
1856 /* Note that here we set the *inital* delete on close flag,
1857 not the regular one. The magic gets handled in close. */
1858 fsp->initial_delete_on_close = True;
1859 }
1860
1861 if (new_file_created) {
1862 /* Files should be initially set as archive */
1863 if (lp_map_archive(SNUM(conn)) ||
1864 lp_store_dos_attributes(SNUM(conn))) {
1865 if (!posix_open) {
1866 SMB_STRUCT_STAT tmp_sbuf;
1867 SET_STAT_INVALID(tmp_sbuf);
1868 if (file_set_dosmode(
1869 conn, fname,
1870 new_dos_attributes | aARCH,
1871 &tmp_sbuf, parent_dir,
1872 true) == 0) {
1873 unx_mode = tmp_sbuf.st_mode;
1874 }
1875 }
1876 }
1877 }
1878
1879 /*
1880 * Take care of inherited ACLs on created files - if default ACL not
1881 * selected.
1882 */
1883
1884 if (!posix_open && !file_existed && !def_acl) {
1885
1886 int saved_errno = errno; /* We might get ENOSYS in the next
1887 * call.. */
1888
1889 if (SMB_VFS_FCHMOD_ACL(fsp, unx_mode) == -1 &&
1890 errno == ENOSYS) {
1891 errno = saved_errno; /* Ignore ENOSYS */
1892 }
1893
1894 } else if (new_unx_mode) {
1895
1896 int ret = -1;
1897
1898 /* Attributes need changing. File already existed. */
1899
1900 {
1901 int saved_errno = errno; /* We might get ENOSYS in the
1902 * next call.. */
1903 ret = SMB_VFS_FCHMOD_ACL(fsp, new_unx_mode);
1904
1905 if (ret == -1 && errno == ENOSYS) {
1906 errno = saved_errno; /* Ignore ENOSYS */
1907 } else {
1908 DEBUG(5, ("open_file_ntcreate: reset "
1909 "attributes of file %s to 0%o\n",
1910 fname, (unsigned int)new_unx_mode));
1911 ret = 0; /* Don't do the fchmod below. */
1912 }
1913 }
1914
1915 if ((ret == -1) &&
1916 (SMB_VFS_FCHMOD(fsp, new_unx_mode) == -1))
1917 DEBUG(5, ("open_file_ntcreate: failed to reset "
1918 "attributes of file %s to 0%o\n",
1919 fname, (unsigned int)new_unx_mode));
1920 }
1921
1922 /* If this is a successful open, we must remove any deferred open
1923 * records. */
1924 if (req != NULL) {
1925 del_deferred_open_entry(lck, req->mid);
1926 }
1927 TALLOC_FREE(lck);
1928
1929 return NT_STATUS_OK;
1930}
1931
1932/****************************************************************************
1933 Open a file with a share mode.
1934****************************************************************************/
1935
1936NTSTATUS open_file_ntcreate(connection_struct *conn,
1937 struct smb_request *req,
1938 const char *fname,
1939 SMB_STRUCT_STAT *psbuf,
1940 uint32 access_mask, /* access bits (FILE_READ_DATA etc.) */
1941 uint32 share_access, /* share constants (FILE_SHARE_READ etc) */
1942 uint32 create_disposition, /* FILE_OPEN_IF etc. */
1943 uint32 create_options, /* options such as delete on close. */
1944 uint32 new_dos_attributes, /* attributes used for new file. */
1945 int oplock_request, /* internal Samba oplock codes. */
1946 /* Information (FILE_EXISTS etc.) */
1947 int *pinfo,
1948 files_struct **result)
1949{
1950 NTSTATUS status;
1951 files_struct *fsp = NULL;
1952
1953 *result = NULL;
1954
1955 status = file_new(conn, &fsp);
1956 if(!NT_STATUS_IS_OK(status)) {
1957 return status;
1958 }
1959
1960 status = open_file_ntcreate_internal(conn,
1961 req,
1962 fname,
1963 psbuf,
1964 access_mask,
1965 share_access,
1966 create_disposition,
1967 create_options,
1968 new_dos_attributes,
1969 oplock_request,
1970 pinfo,
1971 fsp);
1972
1973 if(!NT_STATUS_IS_OK(status)) {
1974 file_free(fsp);
1975 return status;
1976 }
1977
1978 *result = fsp;
1979 return status;
1980}
1981
1982/****************************************************************************
1983 Open a file for for write to ensure that we can fchmod it.
1984****************************************************************************/
1985
1986NTSTATUS open_file_fchmod(connection_struct *conn, const char *fname,
1987 SMB_STRUCT_STAT *psbuf, files_struct **result)
1988{
1989 files_struct *fsp = NULL;
1990 NTSTATUS status;
1991
1992 if (!VALID_STAT(*psbuf)) {
1993 return NT_STATUS_INVALID_PARAMETER;
1994 }
1995
1996 status = file_new(conn, &fsp);
1997 if(!NT_STATUS_IS_OK(status)) {
1998 return status;
1999 }
2000
2001 /* note! we must use a non-zero desired access or we don't get
2002 a real file descriptor. Oh what a twisted web we weave. */
2003 status = open_file(fsp, conn, NULL, NULL, NULL, fname, psbuf, O_WRONLY,
2004 0, FILE_WRITE_DATA, FILE_WRITE_DATA);
2005
2006 /*
2007 * This is not a user visible file open.
2008 * Don't set a share mode.
2009 */
2010
2011 if (!NT_STATUS_IS_OK(status)) {
2012 file_free(fsp);
2013 return status;
2014 }
2015
2016 *result = fsp;
2017 return NT_STATUS_OK;
2018}
2019
2020/****************************************************************************
2021 Close the fchmod file fd - ensure no locks are lost.
2022****************************************************************************/
2023
2024NTSTATUS close_file_fchmod(files_struct *fsp)
2025{
2026 NTSTATUS status = fd_close(fsp);
2027 file_free(fsp);
2028 return status;
2029}
2030
2031static NTSTATUS mkdir_internal(connection_struct *conn,
2032 const char *name,
2033 uint32 file_attributes,
2034 SMB_STRUCT_STAT *psbuf)
2035{
2036 mode_t mode;
2037 char *parent_dir;
2038 const char *dirname;
2039 NTSTATUS status;
2040 bool posix_open = false;
2041
2042 if(!CAN_WRITE(conn)) {
2043 DEBUG(5,("mkdir_internal: failing create on read-only share "
2044 "%s\n", lp_servicename(SNUM(conn))));
2045 return NT_STATUS_ACCESS_DENIED;
2046 }
2047
2048 status = check_name(conn, name);
2049 if (!NT_STATUS_IS_OK(status)) {
2050 return status;
2051 }
2052
2053 if (!parent_dirname_talloc(talloc_tos(), name, &parent_dir,
2054 &dirname)) {
2055 return NT_STATUS_NO_MEMORY;
2056 }
2057
2058 if (file_attributes & FILE_FLAG_POSIX_SEMANTICS) {
2059 posix_open = true;
2060 mode = (mode_t)(file_attributes & ~FILE_FLAG_POSIX_SEMANTICS);
2061 } else {
2062 mode = unix_mode(conn, aDIR, name, parent_dir);
2063 }
2064
2065 if (SMB_VFS_MKDIR(conn, name, mode) != 0) {
2066 return map_nt_error_from_unix(errno);
2067 }
2068
2069 /* Ensure we're checking for a symlink here.... */
2070 /* We don't want to get caught by a symlink racer. */
2071
2072 if (SMB_VFS_LSTAT(conn, name, psbuf) == -1) {
2073 DEBUG(2, ("Could not stat directory '%s' just created: %s\n",
2074 name, strerror(errno)));
2075 return map_nt_error_from_unix(errno);
2076 }
2077
2078 if (!S_ISDIR(psbuf->st_mode)) {
2079 DEBUG(0, ("Directory just '%s' created is not a directory\n",
2080 name));
2081 return NT_STATUS_ACCESS_DENIED;
2082 }
2083
2084 if (lp_store_dos_attributes(SNUM(conn))) {
2085 if (!posix_open) {
2086 file_set_dosmode(conn, name,
2087 file_attributes | aDIR, NULL,
2088 parent_dir,
2089 true);
2090 }
2091 }
2092
2093 if (lp_inherit_perms(SNUM(conn))) {
2094 inherit_access_acl(conn, parent_dir, name, mode);
2095 }
2096
2097 if (!(file_attributes & FILE_FLAG_POSIX_SEMANTICS)) {
2098 /*
2099 * Check if high bits should have been set,
2100 * then (if bits are missing): add them.
2101 * Consider bits automagically set by UNIX, i.e. SGID bit from parent
2102 * dir.
2103 */
2104 if (mode & ~(S_IRWXU|S_IRWXG|S_IRWXO) && (mode & ~psbuf->st_mode)) {
2105 SMB_VFS_CHMOD(conn, name,
2106 psbuf->st_mode | (mode & ~psbuf->st_mode));
2107 }
2108 }
2109
2110 /* Change the owner if required. */
2111 if (lp_inherit_owner(SNUM(conn))) {
2112 change_dir_owner_to_parent(conn, parent_dir, name, psbuf);
2113 }
2114
2115 notify_fname(conn, NOTIFY_ACTION_ADDED, FILE_NOTIFY_CHANGE_DIR_NAME,
2116 name);
2117
2118 return NT_STATUS_OK;
2119}
2120
2121/****************************************************************************
2122 Open a directory from an NT SMB call.
2123****************************************************************************/
2124
2125NTSTATUS open_directory(connection_struct *conn,
2126 struct smb_request *req,
2127 const char *fname,
2128 SMB_STRUCT_STAT *psbuf,
2129 uint32 access_mask,
2130 uint32 share_access,
2131 uint32 create_disposition,
2132 uint32 create_options,
2133 uint32 file_attributes,
2134 int *pinfo,
2135 files_struct **result)
2136{
2137 files_struct *fsp = NULL;
2138 bool dir_existed = VALID_STAT(*psbuf) ? True : False;
2139 struct share_mode_lock *lck = NULL;
2140 NTSTATUS status;
2141 struct timespec mtimespec;
2142 int info = 0;
2143
2144 DEBUG(5,("open_directory: opening directory %s, access_mask = 0x%x, "
2145 "share_access = 0x%x create_options = 0x%x, "
2146 "create_disposition = 0x%x, file_attributes = 0x%x\n",
2147 fname,
2148 (unsigned int)access_mask,
2149 (unsigned int)share_access,
2150 (unsigned int)create_options,
2151 (unsigned int)create_disposition,
2152 (unsigned int)file_attributes));
2153
2154 if (!(file_attributes & FILE_FLAG_POSIX_SEMANTICS) &&
2155 (conn->fs_capabilities & FILE_NAMED_STREAMS) &&
2156 is_ntfs_stream_name(fname)) {
2157 DEBUG(2, ("open_directory: %s is a stream name!\n", fname));
2158 return NT_STATUS_NOT_A_DIRECTORY;
2159 }
2160
2161 switch( create_disposition ) {
2162 case FILE_OPEN:
2163
2164 info = FILE_WAS_OPENED;
2165
2166 /*
2167 * We want to follow symlinks here.
2168 */
2169
2170 if (SMB_VFS_STAT(conn, fname, psbuf) != 0) {
2171 return map_nt_error_from_unix(errno);
2172 }
2173
2174 break;
2175
2176 case FILE_CREATE:
2177
2178 /* If directory exists error. If directory doesn't
2179 * exist create. */
2180
2181 status = mkdir_internal(conn,
2182 fname,
2183 file_attributes,
2184 psbuf);
2185
2186 if (!NT_STATUS_IS_OK(status)) {
2187 DEBUG(2, ("open_directory: unable to create "
2188 "%s. Error was %s\n", fname,
2189 nt_errstr(status)));
2190 return status;
2191 }
2192
2193 info = FILE_WAS_CREATED;
2194 break;
2195
2196 case FILE_OPEN_IF:
2197 /*
2198 * If directory exists open. If directory doesn't
2199 * exist create.
2200 */
2201
2202 status = mkdir_internal(conn,
2203 fname,
2204 file_attributes,
2205 psbuf);
2206
2207 if (NT_STATUS_IS_OK(status)) {
2208 info = FILE_WAS_CREATED;
2209 }
2210
2211 if (NT_STATUS_EQUAL(status,
2212 NT_STATUS_OBJECT_NAME_COLLISION)) {
2213 info = FILE_WAS_OPENED;
2214 status = NT_STATUS_OK;
2215 }
2216
2217 break;
2218
2219 case FILE_SUPERSEDE:
2220 case FILE_OVERWRITE:
2221 case FILE_OVERWRITE_IF:
2222 default:
2223 DEBUG(5,("open_directory: invalid create_disposition "
2224 "0x%x for directory %s\n",
2225 (unsigned int)create_disposition, fname));
2226 return NT_STATUS_INVALID_PARAMETER;
2227 }
2228
2229 if(!S_ISDIR(psbuf->st_mode)) {
2230 DEBUG(5,("open_directory: %s is not a directory !\n",
2231 fname ));
2232 return NT_STATUS_NOT_A_DIRECTORY;
2233 }
2234
2235 status = file_new(conn, &fsp);
2236 if(!NT_STATUS_IS_OK(status)) {
2237 return status;
2238 }
2239
2240 /*
2241 * Setup the files_struct for it.
2242 */
2243
2244 fsp->mode = psbuf->st_mode;
2245 fsp->file_id = vfs_file_id_from_sbuf(conn, psbuf);
2246 fsp->vuid = req ? req->vuid : UID_FIELD_INVALID;
2247 fsp->file_pid = req ? req->smbpid : 0;
2248 fsp->can_lock = False;
2249 fsp->can_read = False;
2250 fsp->can_write = False;
2251
2252 fsp->share_access = share_access;
2253 fsp->fh->private_options = create_options;
2254 fsp->access_mask = access_mask;
2255
2256 fsp->print_file = False;
2257 fsp->modified = False;
2258 fsp->oplock_type = NO_OPLOCK;
2259 fsp->sent_oplock_break = NO_BREAK_SENT;
2260 fsp->is_directory = True;
2261 fsp->is_stat = False;
2262 fsp->posix_open = (file_attributes & FILE_FLAG_POSIX_SEMANTICS) ? True : False;
2263
2264 string_set(&fsp->fsp_name,fname);
2265
2266 mtimespec = get_mtimespec(psbuf);
2267
2268 lck = get_share_mode_lock(talloc_tos(), fsp->file_id,
2269 conn->connectpath,
2270 fname, &mtimespec);
2271
2272 if (lck == NULL) {
2273 DEBUG(0, ("open_directory: Could not get share mode lock for %s\n", fname));
2274 file_free(fsp);
2275 return NT_STATUS_SHARING_VIOLATION;
2276 }
2277
2278 status = open_mode_check(conn, fname, lck,
2279 access_mask, share_access,
2280 create_options, &dir_existed);
2281
2282 if (!NT_STATUS_IS_OK(status)) {
2283 TALLOC_FREE(lck);
2284 file_free(fsp);
2285 return status;
2286 }
2287
2288 set_share_mode(lck, fsp, current_user.ut.uid, 0, NO_OPLOCK, True);
2289
2290 /* For directories the delete on close bit at open time seems
2291 always to be honored on close... See test 19 in Samba4 BASE-DELETE. */
2292 if (create_options & FILE_DELETE_ON_CLOSE) {
2293 status = can_set_delete_on_close(fsp, True, 0);
2294 if (!NT_STATUS_IS_OK(status) && !NT_STATUS_EQUAL(status, NT_STATUS_DIRECTORY_NOT_EMPTY)) {
2295 TALLOC_FREE(lck);
2296 file_free(fsp);
2297 return status;
2298 }
2299
2300 if (NT_STATUS_IS_OK(status)) {
2301 /* Note that here we set the *inital* delete on close flag,
2302 not the regular one. The magic gets handled in close. */
2303 fsp->initial_delete_on_close = True;
2304 }
2305 }
2306
2307 TALLOC_FREE(lck);
2308
2309 if (pinfo) {
2310 *pinfo = info;
2311 }
2312
2313 *result = fsp;
2314 return NT_STATUS_OK;
2315}
2316
2317NTSTATUS create_directory(connection_struct *conn, struct smb_request *req, const char *directory)
2318{
2319 NTSTATUS status;
2320 SMB_STRUCT_STAT sbuf;
2321 files_struct *fsp;
2322
2323 SET_STAT_INVALID(sbuf);
2324
2325 status = open_directory(conn, req, directory, &sbuf,
2326 FILE_READ_ATTRIBUTES, /* Just a stat open */
2327 FILE_SHARE_NONE, /* Ignored for stat opens */
2328 FILE_CREATE,
2329 0,
2330 FILE_ATTRIBUTE_DIRECTORY,
2331 NULL,
2332 &fsp);
2333
2334 if (NT_STATUS_IS_OK(status)) {
2335 close_file(fsp, NORMAL_CLOSE);
2336 }
2337
2338 return status;
2339}
2340
2341/****************************************************************************
2342 Open a pseudo-file (no locking checks - a 'stat' open).
2343****************************************************************************/
2344
2345NTSTATUS open_file_stat(connection_struct *conn, struct smb_request *req,
2346 const char *fname, SMB_STRUCT_STAT *psbuf,
2347 files_struct **result)
2348{
2349 files_struct *fsp = NULL;
2350 NTSTATUS status;
2351
2352 if (!VALID_STAT(*psbuf)) {
2353 return NT_STATUS_INVALID_PARAMETER;
2354 }
2355
2356 /* Can't 'stat' open directories. */
2357 if(S_ISDIR(psbuf->st_mode)) {
2358 return NT_STATUS_FILE_IS_A_DIRECTORY;
2359 }
2360
2361 status = file_new(conn, &fsp);
2362 if(!NT_STATUS_IS_OK(status)) {
2363 return status;
2364 }
2365
2366 DEBUG(5,("open_file_stat: 'opening' file %s\n", fname));
2367
2368 /*
2369 * Setup the files_struct for it.
2370 */
2371
2372 fsp->mode = psbuf->st_mode;
2373 fsp->file_id = vfs_file_id_from_sbuf(conn, psbuf);
2374 fsp->vuid = req ? req->vuid : UID_FIELD_INVALID;
2375 fsp->file_pid = req ? req->smbpid : 0;
2376 fsp->can_lock = False;
2377 fsp->can_read = False;
2378 fsp->can_write = False;
2379 fsp->print_file = False;
2380 fsp->modified = False;
2381 fsp->oplock_type = NO_OPLOCK;
2382 fsp->sent_oplock_break = NO_BREAK_SENT;
2383 fsp->is_directory = False;
2384 fsp->is_stat = True;
2385 string_set(&fsp->fsp_name,fname);
2386
2387 *result = fsp;
2388 return NT_STATUS_OK;
2389}
2390
2391/****************************************************************************
2392 Receive notification that one of our open files has been renamed by another
2393 smbd process.
2394****************************************************************************/
2395
2396void msg_file_was_renamed(struct messaging_context *msg,
2397 void *private_data,
2398 uint32_t msg_type,
2399 struct server_id server_id,
2400 DATA_BLOB *data)
2401{
2402 files_struct *fsp;
2403 char *frm = (char *)data->data;
2404 struct file_id id;
2405 const char *sharepath;
2406 const char *newname;
2407 size_t sp_len;
2408
2409 if (data->data == NULL
2410 || data->length < MSG_FILE_RENAMED_MIN_SIZE + 2) {
2411 DEBUG(0, ("msg_file_was_renamed: Got invalid msg len %d\n",
2412 (int)data->length));
2413 return;
2414 }
2415
2416 /* Unpack the message. */
2417 pull_file_id_16(frm, &id);
2418 sharepath = &frm[16];
2419 newname = sharepath + strlen(sharepath) + 1;
2420 sp_len = strlen(sharepath);
2421
2422 DEBUG(10,("msg_file_was_renamed: Got rename message for sharepath %s, new name %s, "
2423 "file_id %s\n",
2424 sharepath, newname, file_id_string_tos(&id)));
2425
2426 for(fsp = file_find_di_first(id); fsp; fsp = file_find_di_next(fsp)) {
2427 if (memcmp(fsp->conn->connectpath, sharepath, sp_len) == 0) {
2428 DEBUG(10,("msg_file_was_renamed: renaming file fnum %d from %s -> %s\n",
2429 fsp->fnum, fsp->fsp_name, newname ));
2430 string_set(&fsp->fsp_name, newname);
2431 } else {
2432 /* TODO. JRA. */
2433 /* Now we have the complete path we can work out if this is
2434 actually within this share and adjust newname accordingly. */
2435 DEBUG(10,("msg_file_was_renamed: share mismatch (sharepath %s "
2436 "not sharepath %s) "
2437 "fnum %d from %s -> %s\n",
2438 fsp->conn->connectpath,
2439 sharepath,
2440 fsp->fnum,
2441 fsp->fsp_name,
2442 newname ));
2443 }
2444 }
2445}
2446
2447struct case_semantics_state {
2448 connection_struct *conn;
2449 bool case_sensitive;
2450 bool case_preserve;
2451 bool short_case_preserve;
2452};
2453
2454/****************************************************************************
2455 Restore case semantics.
2456****************************************************************************/
2457static int restore_case_semantics(struct case_semantics_state *state)
2458{
2459 state->conn->case_sensitive = state->case_sensitive;
2460 state->conn->case_preserve = state->case_preserve;
2461 state->conn->short_case_preserve = state->short_case_preserve;
2462 return 0;
2463}
2464
2465/****************************************************************************
2466 Save case semantics.
2467****************************************************************************/
2468static struct case_semantics_state *set_posix_case_semantics(TALLOC_CTX *mem_ctx,
2469 connection_struct *conn)
2470{
2471 struct case_semantics_state *result;
2472
2473 if (!(result = talloc(mem_ctx, struct case_semantics_state))) {
2474 DEBUG(0, ("talloc failed\n"));
2475 return NULL;
2476 }
2477
2478 result->conn = conn;
2479 result->case_sensitive = conn->case_sensitive;
2480 result->case_preserve = conn->case_preserve;
2481 result->short_case_preserve = conn->short_case_preserve;
2482
2483 /* Set to POSIX. */
2484 conn->case_sensitive = True;
2485 conn->case_preserve = True;
2486 conn->short_case_preserve = True;
2487
2488 talloc_set_destructor(result, restore_case_semantics);
2489
2490 return result;
2491}
2492
2493/*
2494 * If a main file is opened for delete, all streams need to be checked for
2495 * !FILE_SHARE_DELETE. Do this by opening with DELETE_ACCESS.
2496 * If that works, delete them all by setting the delete on close and close.
2497 */
2498
2499static NTSTATUS open_streams_for_delete(connection_struct *conn,
2500 const char *fname)
2501{
2502 struct stream_struct *stream_info;
2503 files_struct **streams;
2504 int i;
2505 unsigned int num_streams;
2506 TALLOC_CTX *frame = talloc_stackframe();
2507 NTSTATUS status;
2508
2509 status = SMB_VFS_STREAMINFO(conn, NULL, fname, talloc_tos(),
2510 &num_streams, &stream_info);
2511
2512 if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_IMPLEMENTED)
2513 || NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
2514 DEBUG(10, ("no streams around\n"));
2515 TALLOC_FREE(frame);
2516 return NT_STATUS_OK;
2517 }
2518
2519 if (!NT_STATUS_IS_OK(status)) {
2520 DEBUG(10, ("SMB_VFS_STREAMINFO failed: %s\n",
2521 nt_errstr(status)));
2522 goto fail;
2523 }
2524
2525 DEBUG(10, ("open_streams_for_delete found %d streams\n",
2526 num_streams));
2527
2528 if (num_streams == 0) {
2529 TALLOC_FREE(frame);
2530 return NT_STATUS_OK;
2531 }
2532
2533 streams = TALLOC_ARRAY(talloc_tos(), files_struct *, num_streams);
2534 if (streams == NULL) {
2535 DEBUG(0, ("talloc failed\n"));
2536 status = NT_STATUS_NO_MEMORY;
2537 goto fail;
2538 }
2539
2540 for (i=0; i<num_streams; i++) {
2541 char *streamname;
2542
2543 if (strequal(stream_info[i].name, "::$DATA")) {
2544 streams[i] = NULL;
2545 continue;
2546 }
2547
2548 streamname = talloc_asprintf(talloc_tos(), "%s%s", fname,
2549 stream_info[i].name);
2550
2551 if (streamname == NULL) {
2552 DEBUG(0, ("talloc_aprintf failed\n"));
2553 status = NT_STATUS_NO_MEMORY;
2554 goto fail;
2555 }
2556
2557 status = create_file_unixpath
2558 (conn, /* conn */
2559 NULL, /* req */
2560 streamname, /* fname */
2561 DELETE_ACCESS, /* access_mask */
2562 FILE_SHARE_READ | FILE_SHARE_WRITE
2563 | FILE_SHARE_DELETE, /* share_access */
2564 FILE_OPEN, /* create_disposition*/
2565 NTCREATEX_OPTIONS_PRIVATE_STREAM_DELETE, /* create_options */
2566 FILE_ATTRIBUTE_NORMAL, /* file_attributes */
2567 0, /* oplock_request */
2568 0, /* allocation_size */
2569 NULL, /* sd */
2570 NULL, /* ea_list */
2571 &streams[i], /* result */
2572 NULL, /* pinfo */
2573 NULL); /* psbuf */
2574
2575 TALLOC_FREE(streamname);
2576
2577 if (!NT_STATUS_IS_OK(status)) {
2578 DEBUG(10, ("Could not open stream %s: %s\n",
2579 streamname, nt_errstr(status)));
2580 break;
2581 }
2582 }
2583
2584 /*
2585 * don't touch the variable "status" beyond this point :-)
2586 */
2587
2588 for (i -= 1 ; i >= 0; i--) {
2589 if (streams[i] == NULL) {
2590 continue;
2591 }
2592
2593 DEBUG(10, ("Closing stream # %d, %s\n", i,
2594 streams[i]->fsp_name));
2595 close_file(streams[i], NORMAL_CLOSE);
2596 }
2597
2598 fail:
2599 TALLOC_FREE(frame);
2600 return status;
2601}
2602
2603/*
2604 * Wrapper around open_file_ntcreate and open_directory
2605 */
2606
2607NTSTATUS create_file_unixpath(connection_struct *conn,
2608 struct smb_request *req,
2609 const char *fname,
2610 uint32_t access_mask,
2611 uint32_t share_access,
2612 uint32_t create_disposition,
2613 uint32_t create_options,
2614 uint32_t file_attributes,
2615 uint32_t oplock_request,
2616 SMB_BIG_UINT allocation_size,
2617 struct security_descriptor *sd,
2618 struct ea_list *ea_list,
2619
2620 files_struct **result,
2621 int *pinfo,
2622 SMB_STRUCT_STAT *psbuf)
2623{
2624 SMB_STRUCT_STAT sbuf;
2625 int info = FILE_WAS_OPENED;
2626 files_struct *base_fsp = NULL;
2627 files_struct *fsp = NULL;
2628 NTSTATUS status;
2629
2630 DEBUG(10,("create_file_unixpath: access_mask = 0x%x "
2631 "file_attributes = 0x%x, share_access = 0x%x, "
2632 "create_disposition = 0x%x create_options = 0x%x "
2633 "oplock_request = 0x%x ea_list = 0x%p, sd = 0x%p, "
2634 "fname = %s\n",
2635 (unsigned int)access_mask,
2636 (unsigned int)file_attributes,
2637 (unsigned int)share_access,
2638 (unsigned int)create_disposition,
2639 (unsigned int)create_options,
2640 (unsigned int)oplock_request,
2641 ea_list, sd, fname));
2642
2643 if (create_options & FILE_OPEN_BY_FILE_ID) {
2644 status = NT_STATUS_NOT_SUPPORTED;
2645 goto fail;
2646 }
2647
2648 if (create_options & NTCREATEX_OPTIONS_INVALID_PARAM_MASK) {
2649 status = NT_STATUS_INVALID_PARAMETER;
2650 goto fail;
2651 }
2652
2653 if (req == NULL) {
2654 oplock_request |= INTERNAL_OPEN_ONLY;
2655 }
2656
2657 if (psbuf != NULL) {
2658 sbuf = *psbuf;
2659 }
2660 else {
2661 if (SMB_VFS_STAT(conn, fname, &sbuf) == -1) {
2662 SET_STAT_INVALID(sbuf);
2663 }
2664 }
2665
2666 if ((conn->fs_capabilities & FILE_NAMED_STREAMS)
2667 && (access_mask & DELETE_ACCESS)
2668 && !is_ntfs_stream_name(fname)) {
2669 /*
2670 * We can't open a file with DELETE access if any of the
2671 * streams is open without FILE_SHARE_DELETE
2672 */
2673 status = open_streams_for_delete(conn, fname);
2674
2675 if (!NT_STATUS_IS_OK(status)) {
2676 goto fail;
2677 }
2678 }
2679
2680 /* This is the correct thing to do (check every time) but can_delete
2681 * is expensive (it may have to read the parent directory
2682 * permissions). So for now we're not doing it unless we have a strong
2683 * hint the client is really going to delete this file. If the client
2684 * is forcing FILE_CREATE let the filesystem take care of the
2685 * permissions. */
2686
2687 /* Setting FILE_SHARE_DELETE is the hint. */
2688
2689 if (lp_acl_check_permissions(SNUM(conn))
2690 && (create_disposition != FILE_CREATE)
2691 && (share_access & FILE_SHARE_DELETE)
2692 && (access_mask & DELETE_ACCESS)
2693 && (!can_delete_file_in_directory(conn, fname))) {
2694 status = NT_STATUS_ACCESS_DENIED;
2695 goto fail;
2696 }
2697
2698#if 0
2699 /* We need to support SeSecurityPrivilege for this. */
2700 if ((access_mask & SEC_RIGHT_SYSTEM_SECURITY) &&
2701 !user_has_privileges(current_user.nt_user_token,
2702 &se_security)) {
2703 status = NT_STATUS_PRIVILEGE_NOT_HELD;
2704 goto fail;
2705 }
2706#endif
2707
2708 if ((conn->fs_capabilities & FILE_NAMED_STREAMS)
2709 && is_ntfs_stream_name(fname)
2710 && (!(create_options & NTCREATEX_OPTIONS_PRIVATE_STREAM_DELETE))) {
2711 char *base;
2712 uint32 base_create_disposition;
2713
2714 if (create_options & FILE_DIRECTORY_FILE) {
2715 status = NT_STATUS_NOT_A_DIRECTORY;
2716 goto fail;
2717 }
2718
2719 status = split_ntfs_stream_name(talloc_tos(), fname,
2720 &base, NULL);
2721 if (!NT_STATUS_IS_OK(status)) {
2722 DEBUG(10, ("create_file_unixpath: "
2723 "split_ntfs_stream_name failed: %s\n",
2724 nt_errstr(status)));
2725 goto fail;
2726 }
2727
2728 SMB_ASSERT(!is_ntfs_stream_name(base)); /* paranoia.. */
2729
2730 switch (create_disposition) {
2731 case FILE_OPEN:
2732 base_create_disposition = FILE_OPEN;
2733 break;
2734 default:
2735 base_create_disposition = FILE_OPEN_IF;
2736 break;
2737 }
2738
2739 DEBUG(10, ("Recursing into create_file_unixpath for "
2740 "base %s\n", base));
2741
2742 status = create_file_unixpath(conn, NULL, base, 0,
2743 FILE_SHARE_READ
2744 | FILE_SHARE_WRITE
2745 | FILE_SHARE_DELETE,
2746 base_create_disposition,
2747 0, 0, 0, 0, NULL, NULL,
2748 &base_fsp, NULL, NULL);
2749 if (!NT_STATUS_IS_OK(status)) {
2750 DEBUG(10, ("create_file_unixpath for base %s failed: "
2751 "%s\n", base, nt_errstr(status)));
2752 goto fail;
2753 }
2754 /* we don't need to low level fd */
2755 fd_close(base_fsp);
2756 }
2757
2758 /*
2759 * If it's a request for a directory open, deal with it separately.
2760 */
2761
2762 if (create_options & FILE_DIRECTORY_FILE) {
2763
2764 if (create_options & FILE_NON_DIRECTORY_FILE) {
2765 status = NT_STATUS_INVALID_PARAMETER;
2766 goto fail;
2767 }
2768
2769 /* Can't open a temp directory. IFS kit test. */
2770 if (file_attributes & FILE_ATTRIBUTE_TEMPORARY) {
2771 status = NT_STATUS_INVALID_PARAMETER;
2772 goto fail;
2773 }
2774
2775 /*
2776 * We will get a create directory here if the Win32
2777 * app specified a security descriptor in the
2778 * CreateDirectory() call.
2779 */
2780
2781 oplock_request = 0;
2782 status = open_directory(
2783 conn, req, fname, &sbuf, access_mask, share_access,
2784 create_disposition, create_options, file_attributes,
2785 &info, &fsp);
2786 } else {
2787
2788 /*
2789 * Ordinary file case.
2790 */
2791
2792 if (base_fsp) {
2793 /*
2794 * We're opening the stream element of a base_fsp
2795 * we already opened. We need to initialize
2796 * the fsp first, and set up the base_fsp pointer.
2797 */
2798 status = file_new(conn, &fsp);
2799 if(!NT_STATUS_IS_OK(status)) {
2800 goto fail;
2801 }
2802
2803 fsp->base_fsp = base_fsp;
2804
2805 status = open_file_ntcreate_internal(conn,
2806 req,
2807 fname,
2808 &sbuf,
2809 access_mask,
2810 share_access,
2811 create_disposition,
2812 create_options,
2813 file_attributes,
2814 oplock_request,
2815 &info,
2816 fsp);
2817
2818 if(!NT_STATUS_IS_OK(status)) {
2819 file_free(fsp);
2820 fsp = NULL;
2821 }
2822 } else {
2823 status = open_file_ntcreate(
2824 conn, req, fname, &sbuf, access_mask, share_access,
2825 create_disposition, create_options, file_attributes,
2826 oplock_request, &info, &fsp);
2827 }
2828
2829 if (NT_STATUS_EQUAL(status, NT_STATUS_FILE_IS_A_DIRECTORY)) {
2830
2831 /* A stream open never opens a directory */
2832
2833 if (base_fsp) {
2834 status = NT_STATUS_FILE_IS_A_DIRECTORY;
2835 goto fail;
2836 }
2837
2838 /*
2839 * Fail the open if it was explicitly a non-directory
2840 * file.
2841 */
2842
2843 if (create_options & FILE_NON_DIRECTORY_FILE) {
2844 status = NT_STATUS_FILE_IS_A_DIRECTORY;
2845 goto fail;
2846 }
2847
2848 oplock_request = 0;
2849 status = open_directory(
2850 conn, req, fname, &sbuf, access_mask,
2851 share_access, create_disposition,
2852 create_options, file_attributes,
2853 &info, &fsp);
2854 }
2855 }
2856
2857 if (!NT_STATUS_IS_OK(status)) {
2858 goto fail;
2859 }
2860
2861 fsp->base_fsp = base_fsp;
2862
2863 /*
2864 * According to the MS documentation, the only time the security
2865 * descriptor is applied to the opened file is iff we *created* the
2866 * file; an existing file stays the same.
2867 *
2868 * Also, it seems (from observation) that you can open the file with
2869 * any access mask but you can still write the sd. We need to override
2870 * the granted access before we call set_sd
2871 * Patch for bug #2242 from Tom Lackemann <cessnatomny@yahoo.com>.
2872 */
2873
2874 if ((sd != NULL) && (info == FILE_WAS_CREATED)
2875 && lp_nt_acl_support(SNUM(conn))) {
2876
2877 uint32_t sec_info_sent = ALL_SECURITY_INFORMATION;
2878 uint32_t saved_access_mask = fsp->access_mask;
2879
2880 if (sd->owner_sid == NULL) {
2881 sec_info_sent &= ~OWNER_SECURITY_INFORMATION;
2882 }
2883 if (sd->group_sid == NULL) {
2884 sec_info_sent &= ~GROUP_SECURITY_INFORMATION;
2885 }
2886 if (sd->sacl == NULL) {
2887 sec_info_sent &= ~SACL_SECURITY_INFORMATION;
2888 }
2889 if (sd->dacl == NULL) {
2890 sec_info_sent &= ~DACL_SECURITY_INFORMATION;
2891 }
2892
2893 fsp->access_mask = FILE_GENERIC_ALL;
2894
2895 status = SMB_VFS_FSET_NT_ACL(fsp, sec_info_sent, sd);
2896
2897 fsp->access_mask = saved_access_mask;
2898
2899 if (!NT_STATUS_IS_OK(status)) {
2900 goto fail;
2901 }
2902 }
2903
2904 if ((ea_list != NULL) && (info == FILE_WAS_CREATED)) {
2905 status = set_ea(conn, fsp, fname, ea_list);
2906 if (!NT_STATUS_IS_OK(status)) {
2907 goto fail;
2908 }
2909 }
2910
2911 if (!fsp->is_directory && S_ISDIR(sbuf.st_mode)) {
2912 status = NT_STATUS_ACCESS_DENIED;
2913 goto fail;
2914 }
2915
2916 /* Save the requested allocation size. */
2917 if ((info == FILE_WAS_CREATED) || (info == FILE_WAS_OVERWRITTEN)) {
2918 if (allocation_size
2919 && (allocation_size > sbuf.st_size)) {
2920 fsp->initial_allocation_size = smb_roundup(
2921 fsp->conn, allocation_size);
2922 if (fsp->is_directory) {
2923 /* Can't set allocation size on a directory. */
2924 status = NT_STATUS_ACCESS_DENIED;
2925 goto fail;
2926 }
2927 if (vfs_allocate_file_space(
2928 fsp, fsp->initial_allocation_size) == -1) {
2929 status = NT_STATUS_DISK_FULL;
2930 goto fail;
2931 }
2932 } else {
2933 fsp->initial_allocation_size = smb_roundup(
2934 fsp->conn, (SMB_BIG_UINT)sbuf.st_size);
2935 }
2936 }
2937
2938 DEBUG(10, ("create_file_unixpath: info=%d\n", info));
2939
2940 *result = fsp;
2941 if (pinfo != NULL) {
2942 *pinfo = info;
2943 }
2944 if (psbuf != NULL) {
2945 if ((fsp->fh == NULL) || (fsp->fh->fd == -1)) {
2946 *psbuf = sbuf;
2947 }
2948 else {
2949 SMB_VFS_FSTAT(fsp, psbuf);
2950 }
2951 }
2952 return NT_STATUS_OK;
2953
2954 fail:
2955 DEBUG(10, ("create_file_unixpath: %s\n", nt_errstr(status)));
2956
2957 if (fsp != NULL) {
2958 if (base_fsp && fsp->base_fsp == base_fsp) {
2959 /*
2960 * The close_file below will close
2961 * fsp->base_fsp.
2962 */
2963 base_fsp = NULL;
2964 }
2965 close_file(fsp, ERROR_CLOSE);
2966 fsp = NULL;
2967 }
2968 if (base_fsp != NULL) {
2969 close_file(base_fsp, ERROR_CLOSE);
2970 base_fsp = NULL;
2971 }
2972 return status;
2973}
2974
2975NTSTATUS create_file(connection_struct *conn,
2976 struct smb_request *req,
2977 uint16_t root_dir_fid,
2978 const char *fname,
2979 uint32_t access_mask,
2980 uint32_t share_access,
2981 uint32_t create_disposition,
2982 uint32_t create_options,
2983 uint32_t file_attributes,
2984 uint32_t oplock_request,
2985 SMB_BIG_UINT allocation_size,
2986 struct security_descriptor *sd,
2987 struct ea_list *ea_list,
2988
2989 files_struct **result,
2990 int *pinfo,
2991 SMB_STRUCT_STAT *psbuf)
2992{
2993 struct case_semantics_state *case_state = NULL;
2994 SMB_STRUCT_STAT sbuf;
2995 int info = FILE_WAS_OPENED;
2996 files_struct *fsp = NULL;
2997 NTSTATUS status;
2998
2999 DEBUG(10,("create_file: access_mask = 0x%x "
3000 "file_attributes = 0x%x, share_access = 0x%x, "
3001 "create_disposition = 0x%x create_options = 0x%x "
3002 "oplock_request = 0x%x "
3003 "root_dir_fid = 0x%x, ea_list = 0x%p, sd = 0x%p, "
3004 "fname = %s\n",
3005 (unsigned int)access_mask,
3006 (unsigned int)file_attributes,
3007 (unsigned int)share_access,
3008 (unsigned int)create_disposition,
3009 (unsigned int)create_options,
3010 (unsigned int)oplock_request,
3011 (unsigned int)root_dir_fid,
3012 ea_list, sd, fname));
3013
3014 /*
3015 * Get the file name.
3016 */
3017
3018 if (root_dir_fid != 0) {
3019 /*
3020 * This filename is relative to a directory fid.
3021 */
3022 char *parent_fname = NULL;
3023 files_struct *dir_fsp = file_fsp(root_dir_fid);
3024
3025 if (dir_fsp == NULL) {
3026 status = NT_STATUS_INVALID_HANDLE;
3027 goto fail;
3028 }
3029
3030 if (!dir_fsp->is_directory) {
3031
3032 /*
3033 * Check to see if this is a mac fork of some kind.
3034 */
3035
3036 if ((conn->fs_capabilities & FILE_NAMED_STREAMS) &&
3037 is_ntfs_stream_name(fname)) {
3038 status = NT_STATUS_OBJECT_PATH_NOT_FOUND;
3039 goto fail;
3040 }
3041
3042 /*
3043 we need to handle the case when we get a
3044 relative open relative to a file and the
3045 pathname is blank - this is a reopen!
3046 (hint from demyn plantenberg)
3047 */
3048
3049 status = NT_STATUS_INVALID_HANDLE;
3050 goto fail;
3051 }
3052
3053 if (ISDOT(dir_fsp->fsp_name)) {
3054 /*
3055 * We're at the toplevel dir, the final file name
3056 * must not contain ./, as this is filtered out
3057 * normally by srvstr_get_path and unix_convert
3058 * explicitly rejects paths containing ./.
3059 */
3060 parent_fname = talloc_strdup(talloc_tos(), "");
3061 if (parent_fname == NULL) {
3062 status = NT_STATUS_NO_MEMORY;
3063 goto fail;
3064 }
3065 } else {
3066 size_t dir_name_len = strlen(dir_fsp->fsp_name);
3067
3068 /*
3069 * Copy in the base directory name.
3070 */
3071
3072 parent_fname = TALLOC_ARRAY(talloc_tos(), char,
3073 dir_name_len+2);
3074 if (parent_fname == NULL) {
3075 status = NT_STATUS_NO_MEMORY;
3076 goto fail;
3077 }
3078 memcpy(parent_fname, dir_fsp->fsp_name,
3079 dir_name_len+1);
3080
3081 /*
3082 * Ensure it ends in a '/'.
3083 * We used TALLOC_SIZE +2 to add space for the '/'.
3084 */
3085
3086 if(dir_name_len
3087 && (parent_fname[dir_name_len-1] != '\\')
3088 && (parent_fname[dir_name_len-1] != '/')) {
3089 parent_fname[dir_name_len] = '/';
3090 parent_fname[dir_name_len+1] = '\0';
3091 }
3092 }
3093
3094 fname = talloc_asprintf(talloc_tos(), "%s%s", parent_fname,
3095 fname);
3096 if (fname == NULL) {
3097 status = NT_STATUS_NO_MEMORY;
3098 goto fail;
3099 }
3100 }
3101
3102 /*
3103 * Check to see if this is a mac fork of some kind.
3104 */
3105
3106 if (is_ntfs_stream_name(fname)) {
3107 enum FAKE_FILE_TYPE fake_file_type;
3108
3109 fake_file_type = is_fake_file(fname);
3110
3111 if (fake_file_type != FAKE_FILE_TYPE_NONE) {
3112
3113 /*
3114 * Here we go! support for changing the disk quotas
3115 * --metze
3116 *
3117 * We need to fake up to open this MAGIC QUOTA file
3118 * and return a valid FID.
3119 *
3120 * w2k close this file directly after openening xp
3121 * also tries a QUERY_FILE_INFO on the file and then
3122 * close it
3123 */
3124
3125 status = open_fake_file(conn, fake_file_type, fname,
3126 access_mask, &fsp);
3127 if (!NT_STATUS_IS_OK(status)) {
3128 goto fail;
3129 }
3130
3131 ZERO_STRUCT(sbuf);
3132 goto done;
3133 }
3134
3135 if (!(conn->fs_capabilities & FILE_NAMED_STREAMS)) {
3136 status = NT_STATUS_OBJECT_PATH_NOT_FOUND;
3137 goto fail;
3138 }
3139 }
3140
3141 if ((req != NULL) && (req->flags2 & FLAGS2_DFS_PATHNAMES)) {
3142 char *resolved_fname;
3143
3144 status = resolve_dfspath(talloc_tos(), conn, true, fname,
3145 &resolved_fname);
3146
3147 if (!NT_STATUS_IS_OK(status)) {
3148 /*
3149 * For PATH_NOT_COVERED we had
3150 * reply_botherror(req, NT_STATUS_PATH_NOT_COVERED,
3151 * ERRSRV, ERRbadpath);
3152 * Need to fix in callers
3153 */
3154 goto fail;
3155 }
3156 fname = resolved_fname;
3157 }
3158
3159 /*
3160 * Check if POSIX semantics are wanted.
3161 */
3162
3163 if (file_attributes & FILE_FLAG_POSIX_SEMANTICS) {
3164 case_state = set_posix_case_semantics(talloc_tos(), conn);
3165 file_attributes &= ~FILE_FLAG_POSIX_SEMANTICS;
3166 }
3167
3168 {
3169 char *converted_fname;
3170
3171 SET_STAT_INVALID(sbuf);
3172
3173 status = unix_convert(talloc_tos(), conn, fname, False,
3174 &converted_fname, NULL, &sbuf);
3175 if (!NT_STATUS_IS_OK(status)) {
3176 goto fail;
3177 }
3178 fname = converted_fname;
3179 }
3180
3181 TALLOC_FREE(case_state);
3182
3183 /* All file access must go through check_name() */
3184
3185 status = check_name(conn, fname);
3186 if (!NT_STATUS_IS_OK(status)) {
3187 goto fail;
3188 }
3189
3190 status = create_file_unixpath(
3191 conn, req, fname, access_mask, share_access,
3192 create_disposition, create_options, file_attributes,
3193 oplock_request, allocation_size, sd, ea_list,
3194 &fsp, &info, &sbuf);
3195
3196 if (!NT_STATUS_IS_OK(status)) {
3197 goto fail;
3198 }
3199
3200 done:
3201 DEBUG(10, ("create_file: info=%d\n", info));
3202
3203 *result = fsp;
3204 if (pinfo != NULL) {
3205 *pinfo = info;
3206 }
3207 if (psbuf != NULL) {
3208 *psbuf = sbuf;
3209 }
3210 return NT_STATUS_OK;
3211
3212 fail:
3213 DEBUG(10, ("create_file: %s\n", nt_errstr(status)));
3214
3215 if (fsp != NULL) {
3216 close_file(fsp, ERROR_CLOSE);
3217 fsp = NULL;
3218 }
3219 return status;
3220}
Note: See TracBrowser for help on using the repository browser.