source: trunk/server/source3/smbd/open.c@ 593

Last change on this file since 593 was 590, checked in by Herwig Bauernfeind, 14 years ago

Samba 3.5: Update trunk to 3.5.6

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