source: branches/samba-3.3.x/source/smbd/open.c@ 222

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

Update Samba 3.3 branch to 3.3.2

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