Line data Source code
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 : Copyright (C) Ralph Boehme 2017
8 :
9 : This program is free software; you can redistribute it and/or modify
10 : it under the terms of the GNU General Public License as published by
11 : the Free Software Foundation; either version 3 of the License, or
12 : (at your option) any later version.
13 :
14 : This program is distributed in the hope that it will be useful,
15 : but WITHOUT ANY WARRANTY; without even the implied warranty of
16 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 : GNU General Public License for more details.
18 :
19 : You should have received a copy of the GNU General Public License
20 : along with this program. If not, see <http://www.gnu.org/licenses/>.
21 : */
22 :
23 : #include "includes.h"
24 : #include "system/filesys.h"
25 : #include "lib/util/server_id.h"
26 : #include "printing.h"
27 : #include "locking/share_mode_lock.h"
28 : #include "smbd/smbd.h"
29 : #include "smbd/globals.h"
30 : #include "fake_file.h"
31 : #include "../libcli/security/security.h"
32 : #include "../librpc/gen_ndr/ndr_security.h"
33 : #include "../librpc/gen_ndr/ndr_open_files.h"
34 : #include "../librpc/gen_ndr/idmap.h"
35 : #include "../librpc/gen_ndr/ioctl.h"
36 : #include "passdb/lookup_sid.h"
37 : #include "auth.h"
38 : #include "serverid.h"
39 : #include "messages.h"
40 : #include "source3/lib/dbwrap/dbwrap_watch.h"
41 : #include "locking/leases_db.h"
42 : #include "librpc/gen_ndr/ndr_leases_db.h"
43 : #include "lib/util/time_basic.h"
44 :
45 : extern const struct generic_mapping file_generic_mapping;
46 :
47 : struct deferred_open_record {
48 : struct smbXsrv_connection *xconn;
49 : uint64_t mid;
50 :
51 : bool async_open;
52 :
53 : /*
54 : * Timer for async opens, needed because they don't use a watch on
55 : * a locking.tdb record. This is currently only used for real async
56 : * opens and just terminates smbd if the async open times out.
57 : */
58 : struct tevent_timer *te;
59 :
60 : /*
61 : * For the samba kernel oplock case we use both a timeout and
62 : * a watch on locking.tdb. This way in case it's smbd holding
63 : * the kernel oplock we get directly notified for the retry
64 : * once the kernel oplock is properly broken. Store the req
65 : * here so that it can be timely discarded once the timer
66 : * above fires.
67 : */
68 : struct tevent_req *watch_req;
69 : };
70 :
71 : /****************************************************************************
72 : If the requester wanted DELETE_ACCESS and was rejected because
73 : the file ACL didn't include DELETE_ACCESS, see if the parent ACL
74 : overrides this.
75 : ****************************************************************************/
76 :
77 22 : static bool parent_override_delete(connection_struct *conn,
78 : struct files_struct *dirfsp,
79 : const struct smb_filename *smb_fname,
80 : uint32_t access_mask,
81 : uint32_t rejected_mask)
82 : {
83 26 : if ((access_mask & DELETE_ACCESS) &&
84 16 : (rejected_mask & DELETE_ACCESS) &&
85 8 : can_delete_file_in_directory(conn,
86 : dirfsp,
87 : smb_fname))
88 : {
89 6 : return true;
90 : }
91 16 : return false;
92 : }
93 :
94 : /****************************************************************************
95 : Check if we have open rights.
96 : ****************************************************************************/
97 :
98 10766 : static NTSTATUS smbd_check_access_rights_fname(
99 : struct connection_struct *conn,
100 : const struct smb_filename *smb_fname,
101 : bool use_privs,
102 : uint32_t access_mask,
103 : uint32_t do_not_check_mask)
104 : {
105 : uint32_t rejected_share_access;
106 : uint32_t effective_access;
107 :
108 10766 : rejected_share_access = access_mask & ~(conn->share_access);
109 :
110 10766 : if (rejected_share_access) {
111 0 : DBG_DEBUG("rejected share access 0x%"PRIx32" on "
112 : "%s (0x%"PRIx32")\n",
113 : access_mask,
114 : smb_fname_str_dbg(smb_fname),
115 : rejected_share_access);
116 0 : return NT_STATUS_ACCESS_DENIED;
117 : }
118 :
119 10766 : effective_access = access_mask & ~do_not_check_mask;
120 10766 : if (effective_access == 0) {
121 6216 : DBG_DEBUG("do_not_check_mask override on %s. Granting 0x%x for free.\n",
122 : smb_fname_str_dbg(smb_fname),
123 : (unsigned int)access_mask);
124 6216 : return NT_STATUS_OK;
125 : }
126 :
127 4550 : if (!use_privs && get_current_uid(conn) == (uid_t)0) {
128 : /* I'm sorry sir, I didn't know you were root... */
129 1755 : DBG_DEBUG("root override on %s. Granting 0x%x\n",
130 : smb_fname_str_dbg(smb_fname),
131 : (unsigned int)access_mask);
132 1755 : return NT_STATUS_OK;
133 : }
134 :
135 3295 : if ((access_mask & DELETE_ACCESS) &&
136 615 : !lp_acl_check_permissions(SNUM(conn)))
137 : {
138 0 : DBG_DEBUG("Not checking ACL on DELETE_ACCESS on file %s. "
139 : "Granting 0x%"PRIx32"\n",
140 : smb_fname_str_dbg(smb_fname),
141 : access_mask);
142 0 : return NT_STATUS_OK;
143 : }
144 :
145 3270 : if (access_mask == DELETE_ACCESS &&
146 1056 : VALID_STAT(smb_fname->st) &&
147 581 : S_ISLNK(smb_fname->st.st_ex_mode))
148 : {
149 : /* We can always delete a symlink. */
150 0 : DBG_DEBUG("Not checking ACL on DELETE_ACCESS on symlink %s.\n",
151 : smb_fname_str_dbg(smb_fname));
152 0 : return NT_STATUS_OK;
153 : }
154 :
155 2795 : return NT_STATUS_MORE_PROCESSING_REQUIRED;
156 : }
157 :
158 2795 : static NTSTATUS smbd_check_access_rights_sd(
159 : struct connection_struct *conn,
160 : struct files_struct *dirfsp,
161 : const struct smb_filename *smb_fname,
162 : struct security_descriptor *sd,
163 : bool use_privs,
164 : uint32_t access_mask,
165 : uint32_t do_not_check_mask)
166 : {
167 2795 : uint32_t rejected_mask = access_mask;
168 : NTSTATUS status;
169 :
170 2795 : if (sd == NULL) {
171 0 : goto access_denied;
172 : }
173 :
174 2795 : status = se_file_access_check(sd,
175 : get_current_nttok(conn),
176 : use_privs,
177 2795 : (access_mask & ~do_not_check_mask),
178 : &rejected_mask);
179 :
180 2795 : DBG_DEBUG("File [%s] requesting [0x%"PRIx32"] "
181 : "returning [0x%"PRIx32"] (%s)\n",
182 : smb_fname_str_dbg(smb_fname),
183 : access_mask,
184 : rejected_mask,
185 : nt_errstr(status));
186 :
187 2795 : if (!NT_STATUS_IS_OK(status)) {
188 22 : if (DEBUGLEVEL >= 10) {
189 0 : DBG_DEBUG("acl for %s is:\n",
190 : smb_fname_str_dbg(smb_fname));
191 0 : NDR_PRINT_DEBUG(security_descriptor, sd);
192 : }
193 : }
194 :
195 2795 : TALLOC_FREE(sd);
196 :
197 2808 : if (NT_STATUS_IS_OK(status) ||
198 22 : !NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED))
199 : {
200 2773 : return status;
201 : }
202 :
203 : /* Here we know status == NT_STATUS_ACCESS_DENIED. */
204 :
205 22 : access_denied:
206 :
207 23 : if ((access_mask & FILE_WRITE_ATTRIBUTES) &&
208 2 : (rejected_mask & FILE_WRITE_ATTRIBUTES) &&
209 1 : !lp_store_dos_attributes(SNUM(conn)) &&
210 0 : (lp_map_readonly(SNUM(conn)) ||
211 0 : lp_map_archive(SNUM(conn)) ||
212 0 : lp_map_hidden(SNUM(conn)) ||
213 0 : lp_map_system(SNUM(conn))))
214 : {
215 0 : rejected_mask &= ~FILE_WRITE_ATTRIBUTES;
216 :
217 0 : DBG_DEBUG("overrode FILE_WRITE_ATTRIBUTES on file %s\n",
218 : smb_fname_str_dbg(smb_fname));
219 : }
220 :
221 22 : if (parent_override_delete(conn,
222 : dirfsp,
223 : smb_fname,
224 : access_mask,
225 : rejected_mask))
226 : {
227 : /*
228 : * Were we trying to do an open for delete and didn't get DELETE
229 : * access. Check if the directory allows DELETE_CHILD.
230 : * See here:
231 : * http://blogs.msdn.com/oldnewthing/archive/2004/06/04/148426.aspx
232 : * for details.
233 : */
234 :
235 6 : rejected_mask &= ~DELETE_ACCESS;
236 :
237 6 : DBG_DEBUG("Overrode DELETE_ACCESS on file %s\n",
238 : smb_fname_str_dbg(smb_fname));
239 : }
240 :
241 22 : if (rejected_mask != 0) {
242 16 : return NT_STATUS_ACCESS_DENIED;
243 : }
244 6 : return NT_STATUS_OK;
245 : }
246 :
247 10766 : NTSTATUS smbd_check_access_rights_fsp(struct files_struct *dirfsp,
248 : struct files_struct *fsp,
249 : bool use_privs,
250 : uint32_t access_mask)
251 : {
252 10766 : struct security_descriptor *sd = NULL;
253 10766 : uint32_t do_not_check_mask = 0;
254 : NTSTATUS status;
255 :
256 : /* Cope with fake/printer fsp's. */
257 10766 : if (fsp->fake_file_handle != NULL || fsp->print_file != NULL) {
258 0 : if ((fsp->access_mask & access_mask) != access_mask) {
259 0 : return NT_STATUS_ACCESS_DENIED;
260 : }
261 0 : return NT_STATUS_OK;
262 : }
263 :
264 10766 : if (fsp_get_pathref_fd(fsp) == -1) {
265 : /*
266 : * This is a POSIX open on a symlink. For the pathname
267 : * version of this function we used to return the st_mode
268 : * bits turned into an NT ACL. For a symlink the mode bits
269 : * are always rwxrwxrwx which means the pathname version always
270 : * returned NT_STATUS_OK for a symlink. For the handle reference
271 : * to a symlink use the handle access bits.
272 : */
273 0 : if ((fsp->access_mask & access_mask) != access_mask) {
274 0 : return NT_STATUS_ACCESS_DENIED;
275 : }
276 0 : return NT_STATUS_OK;
277 : }
278 :
279 : /*
280 : * If we can access the path to this file, by
281 : * default we have FILE_READ_ATTRIBUTES from the
282 : * containing directory. See the section:
283 : * "Algorithm to Check Access to an Existing File"
284 : * in MS-FSA.pdf.
285 : *
286 : * se_file_access_check() also takes care of
287 : * owner WRITE_DAC and READ_CONTROL.
288 : */
289 10766 : do_not_check_mask = FILE_READ_ATTRIBUTES;
290 :
291 : /*
292 : * Samba 3.6 and earlier granted execute access even
293 : * if the ACL did not contain execute rights.
294 : * Samba 4.0 is more correct and checks it.
295 : * The compatibilty mode allows one to skip this check
296 : * to smoothen upgrades.
297 : */
298 10766 : if (lp_acl_allow_execute_always(SNUM(fsp->conn))) {
299 0 : do_not_check_mask |= FILE_EXECUTE;
300 : }
301 :
302 20484 : status = smbd_check_access_rights_fname(fsp->conn,
303 10766 : fsp->fsp_name,
304 : use_privs,
305 : access_mask,
306 : do_not_check_mask);
307 10766 : if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
308 7971 : return status;
309 : }
310 :
311 2795 : status = SMB_VFS_FGET_NT_ACL(metadata_fsp(fsp),
312 : (SECINFO_OWNER |
313 : SECINFO_GROUP |
314 : SECINFO_DACL),
315 : talloc_tos(),
316 : &sd);
317 2795 : if (!NT_STATUS_IS_OK(status)) {
318 0 : DBG_DEBUG("Could not get acl on %s: %s\n",
319 : fsp_str_dbg(fsp),
320 : nt_errstr(status));
321 0 : return status;
322 : }
323 :
324 4922 : return smbd_check_access_rights_sd(fsp->conn,
325 : dirfsp,
326 2795 : fsp->fsp_name,
327 : sd,
328 : use_privs,
329 : access_mask,
330 : do_not_check_mask);
331 : }
332 :
333 : /*
334 : * Given an fsp that represents a parent directory,
335 : * check if the requested access can be granted.
336 : */
337 1358 : NTSTATUS check_parent_access_fsp(struct files_struct *fsp,
338 : uint32_t access_mask)
339 : {
340 : NTSTATUS status;
341 1358 : struct security_descriptor *parent_sd = NULL;
342 1358 : uint32_t access_granted = 0;
343 1358 : struct share_mode_lock *lck = NULL;
344 : uint32_t name_hash;
345 : bool delete_on_close_set;
346 1358 : TALLOC_CTX *frame = talloc_stackframe();
347 :
348 1358 : if (get_current_uid(fsp->conn) == (uid_t)0) {
349 : /* I'm sorry sir, I didn't know you were root... */
350 677 : DBG_DEBUG("root override on %s. Granting 0x%x\n",
351 : fsp_str_dbg(fsp),
352 : (unsigned int)access_mask);
353 677 : status = NT_STATUS_OK;
354 677 : goto out;
355 : }
356 :
357 681 : status = SMB_VFS_FGET_NT_ACL(fsp,
358 : SECINFO_DACL,
359 : frame,
360 : &parent_sd);
361 :
362 681 : if (!NT_STATUS_IS_OK(status)) {
363 0 : DBG_INFO("SMB_VFS_FGET_NT_ACL failed for "
364 : "%s with error %s\n",
365 : fsp_str_dbg(fsp),
366 : nt_errstr(status));
367 0 : goto out;
368 : }
369 :
370 : /*
371 : * If we can access the path to this file, by
372 : * default we have FILE_READ_ATTRIBUTES from the
373 : * containing directory. See the section:
374 : * "Algorithm to Check Access to an Existing File"
375 : * in MS-FSA.pdf.
376 : *
377 : * se_file_access_check() also takes care of
378 : * owner WRITE_DAC and READ_CONTROL.
379 : */
380 1197 : status = se_file_access_check(parent_sd,
381 681 : get_current_nttok(fsp->conn),
382 : false,
383 : (access_mask & ~FILE_READ_ATTRIBUTES),
384 : &access_granted);
385 681 : if(!NT_STATUS_IS_OK(status)) {
386 0 : DBG_INFO("access check "
387 : "on directory %s for mask 0x%x returned (0x%x) %s\n",
388 : fsp_str_dbg(fsp),
389 : access_mask,
390 : access_granted,
391 : nt_errstr(status));
392 0 : goto out;
393 : }
394 :
395 681 : if (!(access_mask & (SEC_DIR_ADD_FILE | SEC_DIR_ADD_SUBDIR))) {
396 0 : status = NT_STATUS_OK;
397 0 : goto out;
398 : }
399 681 : if (!lp_check_parent_directory_delete_on_close(SNUM(fsp->conn))) {
400 644 : status = NT_STATUS_OK;
401 644 : goto out;
402 : }
403 :
404 : /* Check if the directory has delete-on-close set */
405 37 : status = file_name_hash(fsp->conn,
406 37 : fsp->fsp_name->base_name,
407 : &name_hash);
408 37 : if (!NT_STATUS_IS_OK(status)) {
409 0 : goto out;
410 : }
411 :
412 : /*
413 : * Don't take a lock here. We just need a snapshot
414 : * of the current state of delete on close and this is
415 : * called in a codepath where we may already have a lock
416 : * (and we explicitly can't hold 2 locks at the same time
417 : * as that may deadlock).
418 : */
419 37 : lck = fetch_share_mode_unlocked(frame, fsp->file_id);
420 37 : if (lck == NULL) {
421 21 : status = NT_STATUS_OK;
422 21 : goto out;
423 : }
424 :
425 16 : delete_on_close_set = is_delete_on_close_set(lck, name_hash);
426 16 : if (delete_on_close_set) {
427 0 : status = NT_STATUS_DELETE_PENDING;
428 0 : goto out;
429 : }
430 :
431 16 : status = NT_STATUS_OK;
432 :
433 1358 : out:
434 1358 : TALLOC_FREE(frame);
435 1358 : return status;
436 : }
437 :
438 : /****************************************************************************
439 : Ensure when opening a base file for a stream open that we have permissions
440 : to do so given the access mask on the base file.
441 : ****************************************************************************/
442 :
443 56 : static NTSTATUS check_base_file_access(struct files_struct *fsp,
444 : uint32_t access_mask)
445 : {
446 : NTSTATUS status;
447 :
448 56 : status = smbd_calculate_access_mask_fsp(fsp->conn->cwd_fsp,
449 : fsp,
450 : false,
451 : access_mask,
452 : &access_mask);
453 56 : if (!NT_STATUS_IS_OK(status)) {
454 0 : DEBUG(10, ("smbd_calculate_access_mask "
455 : "on file %s returned %s\n",
456 : fsp_str_dbg(fsp),
457 : nt_errstr(status)));
458 0 : return status;
459 : }
460 :
461 56 : if (access_mask & (FILE_WRITE_DATA|FILE_APPEND_DATA)) {
462 : uint32_t dosattrs;
463 16 : if (!CAN_WRITE(fsp->conn)) {
464 0 : return NT_STATUS_ACCESS_DENIED;
465 : }
466 16 : dosattrs = fdos_mode(fsp);
467 16 : if (IS_DOS_READONLY(dosattrs)) {
468 0 : return NT_STATUS_ACCESS_DENIED;
469 : }
470 : }
471 :
472 56 : return smbd_check_access_rights_fsp(fsp->conn->cwd_fsp,
473 : fsp,
474 : false,
475 : access_mask);
476 : }
477 :
478 : /****************************************************************************
479 : Handle differing symlink errno's
480 : ****************************************************************************/
481 :
482 2493 : static NTSTATUS link_errno_convert(int err)
483 : {
484 : #if defined(ENOTSUP) && defined(OSF1)
485 : /* handle special Tru64 errno */
486 : if (err == ENOTSUP) {
487 : err = ELOOP;
488 : }
489 : #endif /* ENOTSUP */
490 : #ifdef EFTYPE
491 : /* fix broken NetBSD errno */
492 : if (err == EFTYPE) {
493 : err = ELOOP;
494 : }
495 : #endif /* EFTYPE */
496 : /* fix broken FreeBSD errno */
497 2493 : if (err == EMLINK) {
498 0 : err = ELOOP;
499 : }
500 2493 : if (err == ELOOP) {
501 0 : return NT_STATUS_STOPPED_ON_SYMLINK;
502 : }
503 2493 : return map_nt_error_from_unix(err);
504 : }
505 :
506 : static NTSTATUS non_widelink_open(const struct files_struct *dirfsp,
507 : files_struct *fsp,
508 : struct smb_filename *smb_fname,
509 : const struct vfs_open_how *how,
510 : unsigned int link_depth);
511 :
512 : /****************************************************************************
513 : Follow a symlink in userspace.
514 : ****************************************************************************/
515 :
516 1880 : static NTSTATUS process_symlink_open(const struct files_struct *dirfsp,
517 : files_struct *fsp,
518 : struct smb_filename *smb_fname,
519 : const struct vfs_open_how *how,
520 : unsigned int link_depth)
521 : {
522 1880 : struct connection_struct *conn = dirfsp->conn;
523 1880 : const char *conn_rootdir = NULL;
524 1880 : struct smb_filename conn_rootdir_fname = { 0 };
525 1880 : char *link_target = NULL;
526 1880 : int link_len = -1;
527 1880 : struct smb_filename *oldwd_fname = NULL;
528 1880 : size_t rootdir_len = 0;
529 1880 : struct smb_filename *resolved_fname = NULL;
530 1880 : char *resolved_name = NULL;
531 1880 : bool matched = false;
532 1880 : struct smb_filename *full_fname = NULL;
533 : NTSTATUS status;
534 :
535 1880 : conn_rootdir = SMB_VFS_CONNECTPATH(conn, smb_fname);
536 1880 : if (conn_rootdir == NULL) {
537 0 : return NT_STATUS_NO_MEMORY;
538 : }
539 : /*
540 : * With shadow_copy2 conn_rootdir can be talloc_freed
541 : * whilst we use it in this function. We must take a copy.
542 : */
543 1880 : conn_rootdir_fname.base_name = talloc_strdup(talloc_tos(),
544 : conn_rootdir);
545 1880 : if (conn_rootdir_fname.base_name == NULL) {
546 0 : return NT_STATUS_NO_MEMORY;
547 : }
548 :
549 : /*
550 : * Ensure we don't get stuck in a symlink loop.
551 : */
552 1880 : link_depth++;
553 1880 : if (link_depth >= 20) {
554 0 : status = NT_STATUS_STOPPED_ON_SYMLINK;
555 0 : goto out;
556 : }
557 :
558 : /* Allocate space for the link target. */
559 1880 : link_target = talloc_array(talloc_tos(), char, PATH_MAX);
560 1880 : if (link_target == NULL) {
561 0 : status = NT_STATUS_NO_MEMORY;
562 0 : goto out;
563 : }
564 :
565 : /*
566 : * Read the link target. We do this just to verify that smb_fname indeed
567 : * points at a symbolic link and return NT_STATUS_NOT_A_DIRECTORY
568 : * and failure in case smb_fname is NOT a symlink.
569 : *
570 : * The caller needs this piece of information to distinguish two cases
571 : * where open() fails with errno=ENOTDIR, cf the comment in
572 : * non_widelink_open().
573 : *
574 : * We rely on SMB_VFS_REALPATH() to resolve the path including the
575 : * symlink. Once we have SMB_VFS_STATX() or something similar in our VFS
576 : * we may want to use that instead of SMB_VFS_READLINKAT().
577 : */
578 1880 : link_len = SMB_VFS_READLINKAT(conn,
579 : dirfsp,
580 : smb_fname,
581 : link_target,
582 : PATH_MAX - 1);
583 1880 : if (link_len == -1) {
584 0 : status = NT_STATUS_INVALID_PARAMETER;
585 0 : goto out;
586 : }
587 :
588 1880 : full_fname = full_path_from_dirfsp_atname(
589 : talloc_tos(), dirfsp, smb_fname);
590 1880 : if (full_fname == NULL) {
591 0 : status = NT_STATUS_NO_MEMORY;
592 0 : goto out;
593 : }
594 :
595 : /* Convert to an absolute path. */
596 1880 : resolved_fname = SMB_VFS_REALPATH(conn, talloc_tos(), full_fname);
597 1880 : if (resolved_fname == NULL) {
598 956 : status = map_nt_error_from_unix(errno);
599 956 : goto out;
600 : }
601 924 : resolved_name = resolved_fname->base_name;
602 :
603 : /*
604 : * We know conn_rootdir starts with '/' and
605 : * does not end in '/'. FIXME ! Should we
606 : * smb_assert this ?
607 : */
608 924 : rootdir_len = strlen(conn_rootdir_fname.base_name);
609 :
610 924 : matched = (strncmp(conn_rootdir_fname.base_name,
611 : resolved_name,
612 : rootdir_len) == 0);
613 924 : if (!matched) {
614 0 : status = NT_STATUS_STOPPED_ON_SYMLINK;
615 0 : goto out;
616 : }
617 :
618 : /*
619 : * Turn into a path relative to the share root.
620 : */
621 924 : if (resolved_name[rootdir_len] == '\0') {
622 : /* Link to the root of the share. */
623 24 : TALLOC_FREE(smb_fname->base_name);
624 24 : smb_fname->base_name = talloc_strdup(smb_fname, ".");
625 900 : } else if (resolved_name[rootdir_len] == '/') {
626 888 : TALLOC_FREE(smb_fname->base_name);
627 888 : smb_fname->base_name = talloc_strdup(smb_fname,
628 888 : &resolved_name[rootdir_len+1]);
629 : } else {
630 12 : status = NT_STATUS_STOPPED_ON_SYMLINK;
631 12 : goto out;
632 : }
633 :
634 912 : if (smb_fname->base_name == NULL) {
635 0 : status = NT_STATUS_NO_MEMORY;
636 0 : goto out;
637 : }
638 :
639 912 : oldwd_fname = vfs_GetWd(talloc_tos(), dirfsp->conn);
640 912 : if (oldwd_fname == NULL) {
641 0 : status = map_nt_error_from_unix(errno);
642 0 : goto out;
643 : }
644 :
645 : /* Ensure we operate from the root of the share. */
646 912 : if (vfs_ChDir(conn, &conn_rootdir_fname) == -1) {
647 0 : status = map_nt_error_from_unix(errno);
648 0 : goto out;
649 : }
650 :
651 : /*
652 : * And do it all again... As smb_fname is not relative to the passed in
653 : * dirfsp anymore, we pass conn->cwd_fsp as dirfsp to
654 : * non_widelink_open() to trigger the chdir(parentdir) logic.
655 : */
656 912 : status = non_widelink_open(conn->cwd_fsp,
657 : fsp,
658 : smb_fname,
659 : how,
660 : link_depth);
661 :
662 1880 : out:
663 :
664 1880 : TALLOC_FREE(resolved_fname);
665 1880 : TALLOC_FREE(link_target);
666 1880 : TALLOC_FREE(conn_rootdir_fname.base_name);
667 1880 : if (oldwd_fname != NULL) {
668 912 : int ret = vfs_ChDir(conn, oldwd_fname);
669 912 : if (ret == -1) {
670 0 : smb_panic("unable to get back to old directory\n");
671 : }
672 912 : TALLOC_FREE(oldwd_fname);
673 : }
674 :
675 1880 : return status;
676 : }
677 :
678 : /****************************************************************************
679 : Non-widelink open.
680 : ****************************************************************************/
681 :
682 119562 : static NTSTATUS non_widelink_open(const struct files_struct *dirfsp,
683 : files_struct *fsp,
684 : struct smb_filename *smb_fname,
685 : const struct vfs_open_how *_how,
686 : unsigned int link_depth)
687 : {
688 119562 : struct connection_struct *conn = fsp->conn;
689 : NTSTATUS saved_status;
690 119562 : NTSTATUS status = NT_STATUS_OK;
691 119562 : int fd = -1;
692 119562 : struct smb_filename *orig_fsp_name = fsp->fsp_name;
693 119562 : struct smb_filename *smb_fname_rel = NULL;
694 119562 : struct smb_filename *oldwd_fname = NULL;
695 119562 : struct smb_filename *parent_dir_fname = NULL;
696 119562 : bool have_opath = false;
697 119562 : bool is_share_root = false;
698 119562 : struct vfs_open_how how = *_how;
699 : int ret;
700 :
701 : #ifdef O_PATH
702 119562 : have_opath = true;
703 : #endif
704 :
705 119562 : SMB_ASSERT(!fsp_is_alternate_stream(fsp));
706 :
707 119562 : if (smb_fname->base_name[0] == '/') {
708 35609 : const char *connpath = SMB_VFS_CONNECTPATH(conn, smb_fname);
709 35609 : int cmp = strcmp(connpath, smb_fname->base_name);
710 :
711 35609 : if (cmp == 0) {
712 28882 : is_share_root = true;
713 : }
714 : }
715 :
716 159798 : if (!is_share_root && (dirfsp == conn->cwd_fsp)) {
717 60920 : struct smb_filename *smb_fname_dot = NULL;
718 :
719 60920 : status = SMB_VFS_PARENT_PATHNAME(fsp->conn,
720 : talloc_tos(),
721 : smb_fname,
722 : &parent_dir_fname,
723 : &smb_fname_rel);
724 60920 : if (!NT_STATUS_IS_OK(status)) {
725 0 : goto out;
726 : }
727 :
728 60920 : if (!ISDOT(parent_dir_fname->base_name)) {
729 13926 : oldwd_fname = vfs_GetWd(talloc_tos(), conn);
730 13926 : if (oldwd_fname == NULL) {
731 0 : status = map_nt_error_from_unix(errno);
732 0 : goto out;
733 : }
734 :
735 : /* Pin parent directory in place. */
736 13926 : if (vfs_ChDir(conn, parent_dir_fname) == -1) {
737 819 : status = map_nt_error_from_unix(errno);
738 819 : goto out;
739 : }
740 : }
741 :
742 60101 : smb_fname_dot = synthetic_smb_fname(
743 : parent_dir_fname,
744 : ".",
745 : NULL,
746 : NULL,
747 : 0,
748 : smb_fname->flags);
749 60101 : if (smb_fname_dot == NULL) {
750 0 : status = NT_STATUS_NO_MEMORY;
751 0 : goto out;
752 : }
753 :
754 : /* Ensure the relative path is below the share. */
755 60101 : status = check_reduced_name(conn, parent_dir_fname, smb_fname_dot);
756 60101 : TALLOC_FREE(smb_fname_dot);
757 60101 : if (!NT_STATUS_IS_OK(status)) {
758 9033 : goto out;
759 : }
760 :
761 : /* Setup fsp->fsp_name to be relative to cwd */
762 51068 : fsp->fsp_name = smb_fname_rel;
763 : } else {
764 : /*
765 : * fsp->fsp_name is unchanged as it is already correctly
766 : * relative to conn->cwd.
767 : */
768 58642 : smb_fname_rel = smb_fname;
769 : }
770 :
771 109710 : if (!is_share_root) {
772 80828 : char *slash = strchr_m(smb_fname_rel->base_name, '/');
773 80828 : SMB_ASSERT(slash == NULL);
774 : }
775 :
776 109710 : how.flags |= O_NOFOLLOW;
777 :
778 109710 : fd = SMB_VFS_OPENAT(conn,
779 : dirfsp,
780 : smb_fname_rel,
781 : fsp,
782 : &how);
783 109710 : if (fd == -1) {
784 2493 : status = link_errno_convert(errno);
785 : }
786 109710 : fsp_set_fd(fsp, fd);
787 :
788 111686 : if ((fd == -1) &&
789 2493 : NT_STATUS_EQUAL(status, NT_STATUS_STOPPED_ON_SYMLINK) &&
790 0 : fsp->fsp_flags.is_pathref &&
791 0 : !have_opath) {
792 0 : ret = SMB_VFS_FSTATAT(
793 : fsp->conn,
794 : dirfsp,
795 : smb_fname_rel,
796 : &fsp->fsp_name->st,
797 : AT_SYMLINK_NOFOLLOW);
798 0 : if (ret == -1) {
799 0 : status = map_nt_error_from_unix(errno);
800 0 : DBG_DEBUG("fstatat(%s) failed: %s\n",
801 : smb_fname_str_dbg(smb_fname),
802 : strerror(errno));
803 0 : goto out;
804 : }
805 0 : orig_fsp_name->st = fsp->fsp_name->st;
806 : }
807 :
808 109710 : if (fd != -1) {
809 107217 : status = vfs_stat_fsp(fsp);
810 107217 : if (!NT_STATUS_IS_OK(status)) {
811 0 : goto out;
812 : }
813 107217 : orig_fsp_name->st = fsp->fsp_name->st;
814 : }
815 :
816 109710 : if (!is_ntfs_stream_smb_fname(fsp->fsp_name) &&
817 104937 : fsp->fsp_flags.is_pathref &&
818 : have_opath)
819 : {
820 : /*
821 : * Opening with O_PATH and O_NOFOLLOW opens a handle on the
822 : * symlink. In follow symlink=yes mode we must avoid this and
823 : * instead should open a handle on the symlink target.
824 : *
825 : * Check for this case by doing an fstat, forcing
826 : * process_symlink_open() codepath down below by setting fd=-1
827 : * and errno=ELOOP.
828 : */
829 104937 : if (S_ISLNK(fsp->fsp_name->st.st_ex_mode)) {
830 1884 : status = fd_close(fsp);
831 1884 : SMB_ASSERT(NT_STATUS_IS_OK(status));
832 1884 : fd = -1;
833 1884 : status = NT_STATUS_STOPPED_ON_SYMLINK;
834 : }
835 : }
836 :
837 112630 : if ((fd == -1) &&
838 6353 : (NT_STATUS_EQUAL(status, NT_STATUS_STOPPED_ON_SYMLINK) ||
839 2493 : NT_STATUS_EQUAL(status, NT_STATUS_NOT_A_DIRECTORY)))
840 : {
841 : /*
842 : * Trying to open a symlink to a directory with O_NOFOLLOW and
843 : * O_DIRECTORY can return either of ELOOP and ENOTDIR. So
844 : * ENOTDIR really means: might be a symlink, but we're not sure.
845 : * In this case, we just assume there's a symlink. If we were
846 : * wrong, process_symlink_open() will return EINVAL. We check
847 : * this below, and fall back to returning the initial
848 : * saved_errno.
849 : *
850 : * BUG: https://bugzilla.samba.org/show_bug.cgi?id=12860
851 : */
852 1884 : saved_status = status;
853 :
854 1884 : if (fsp->fsp_name->flags & SMB_FILENAME_POSIX_PATH) {
855 : /* Never follow symlinks on posix open. */
856 2 : goto out;
857 : }
858 1884 : if (!lp_follow_symlinks(SNUM(conn))) {
859 : /* Explicitly no symlinks. */
860 4 : goto out;
861 : }
862 :
863 1880 : fsp->fsp_name = orig_fsp_name;
864 :
865 : /*
866 : * We may have a symlink. Follow in userspace
867 : * to ensure it's under the share definition.
868 : */
869 1880 : status = process_symlink_open(dirfsp,
870 : fsp,
871 : smb_fname_rel,
872 : &how,
873 : link_depth);
874 1880 : if (NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER) &&
875 0 : NT_STATUS_EQUAL(saved_status, NT_STATUS_NOT_A_DIRECTORY))
876 : {
877 0 : status = saved_status;
878 : }
879 : }
880 :
881 204921 : out:
882 119562 : fsp->fsp_name = orig_fsp_name;
883 :
884 119562 : TALLOC_FREE(parent_dir_fname);
885 :
886 119562 : if (oldwd_fname != NULL) {
887 13926 : ret = vfs_ChDir(conn, oldwd_fname);
888 13926 : if (ret == -1) {
889 0 : smb_panic("unable to get back to old directory\n");
890 : }
891 13926 : TALLOC_FREE(oldwd_fname);
892 : }
893 119562 : return status;
894 : }
895 :
896 : /****************************************************************************
897 : fd support routines - attempt to do a dos_open.
898 : ****************************************************************************/
899 :
900 118740 : NTSTATUS fd_openat(const struct files_struct *dirfsp,
901 : struct smb_filename *smb_fname,
902 : files_struct *fsp,
903 : const struct vfs_open_how *_how)
904 : {
905 118740 : struct vfs_open_how how = *_how;
906 118740 : struct connection_struct *conn = fsp->conn;
907 118740 : NTSTATUS status = NT_STATUS_OK;
908 118740 : bool fsp_is_stream = fsp_is_alternate_stream(fsp);
909 118740 : bool smb_fname_is_stream = is_named_stream(smb_fname);
910 :
911 118740 : SMB_ASSERT(fsp_is_stream == smb_fname_is_stream);
912 :
913 : /*
914 : * Never follow symlinks on a POSIX client. The
915 : * client should be doing this.
916 : */
917 :
918 118740 : if ((fsp->posix_flags & FSP_POSIX_FLAGS_OPEN) || !lp_follow_symlinks(SNUM(conn))) {
919 1080 : how.flags |= O_NOFOLLOW;
920 : }
921 :
922 118740 : if (fsp_is_stream) {
923 : int fd;
924 :
925 90 : fd = SMB_VFS_OPENAT(
926 : conn,
927 : NULL, /* stream open is relative to fsp->base_fsp */
928 : smb_fname,
929 : fsp,
930 : &how);
931 90 : if (fd == -1) {
932 10 : status = map_nt_error_from_unix(errno);
933 : }
934 90 : fsp_set_fd(fsp, fd);
935 :
936 90 : if (fd != -1) {
937 80 : status = vfs_stat_fsp(fsp);
938 80 : if (!NT_STATUS_IS_OK(status)) {
939 0 : DBG_DEBUG("vfs_stat_fsp failed: %s\n",
940 : nt_errstr(status));
941 0 : fd_close(fsp);
942 : }
943 : }
944 :
945 90 : return status;
946 : }
947 :
948 : /*
949 : * Only follow symlinks within a share
950 : * definition.
951 : */
952 118650 : status = non_widelink_open(dirfsp, fsp, smb_fname, &how, 0);
953 118650 : if (!NT_STATUS_IS_OK(status)) {
954 13317 : if (NT_STATUS_EQUAL(status, NT_STATUS_TOO_MANY_OPENED_FILES)) {
955 : static time_t last_warned = 0L;
956 :
957 0 : if (time((time_t *) NULL) > last_warned) {
958 0 : DEBUG(0,("Too many open files, unable "
959 : "to open more! smbd's max "
960 : "open files = %d\n",
961 : lp_max_open_files()));
962 0 : last_warned = time((time_t *) NULL);
963 : }
964 : }
965 :
966 13317 : DBG_DEBUG("name %s, flags = 0%o mode = 0%o, fd = %d. %s\n",
967 : smb_fname_str_dbg(smb_fname),
968 : how.flags,
969 : (int)how.mode,
970 : fsp_get_pathref_fd(fsp),
971 : nt_errstr(status));
972 13317 : return status;
973 : }
974 :
975 105333 : DBG_DEBUG("name %s, flags = 0%o mode = 0%o, fd = %d\n",
976 : smb_fname_str_dbg(smb_fname),
977 : how.flags,
978 : (int)how.mode,
979 : fsp_get_pathref_fd(fsp));
980 :
981 105333 : return status;
982 : }
983 :
984 : /****************************************************************************
985 : Close the file associated with a fsp.
986 : ****************************************************************************/
987 :
988 134388 : NTSTATUS fd_close(files_struct *fsp)
989 : {
990 : NTSTATUS status;
991 : int ret;
992 :
993 134388 : if (fsp == fsp->conn->cwd_fsp) {
994 0 : return NT_STATUS_OK;
995 : }
996 :
997 134388 : if (fsp->fsp_flags.fstat_before_close) {
998 0 : status = vfs_stat_fsp(fsp);
999 0 : if (!NT_STATUS_IS_OK(status)) {
1000 0 : return status;
1001 : }
1002 : }
1003 :
1004 134388 : if (fsp->dptr) {
1005 2165 : dptr_CloseDir(fsp);
1006 : }
1007 134388 : if (fsp_get_pathref_fd(fsp) == -1) {
1008 : /*
1009 : * Either a directory where the dptr_CloseDir() already closed
1010 : * the fd or a stat open.
1011 : */
1012 16718 : return NT_STATUS_OK;
1013 : }
1014 117670 : if (fh_get_refcount(fsp->fh) > 1) {
1015 0 : return NT_STATUS_OK; /* Shared handle. Only close last reference. */
1016 : }
1017 :
1018 117670 : ret = SMB_VFS_CLOSE(fsp);
1019 117670 : fsp_set_fd(fsp, -1);
1020 117670 : if (ret == -1) {
1021 0 : return map_nt_error_from_unix(errno);
1022 : }
1023 117670 : return NT_STATUS_OK;
1024 : }
1025 :
1026 : /****************************************************************************
1027 : Change the ownership of a file to that of the parent directory.
1028 : Do this by fd if possible.
1029 : ****************************************************************************/
1030 :
1031 0 : static void change_file_owner_to_parent_fsp(struct files_struct *parent_fsp,
1032 : struct files_struct *fsp)
1033 : {
1034 : int ret;
1035 :
1036 0 : if (parent_fsp->fsp_name->st.st_ex_uid == fsp->fsp_name->st.st_ex_uid) {
1037 : /* Already this uid - no need to change. */
1038 0 : DBG_DEBUG("file %s is already owned by uid %u\n",
1039 : fsp_str_dbg(fsp),
1040 : (unsigned int)fsp->fsp_name->st.st_ex_uid);
1041 0 : return;
1042 : }
1043 :
1044 0 : become_root();
1045 0 : ret = SMB_VFS_FCHOWN(fsp,
1046 : parent_fsp->fsp_name->st.st_ex_uid,
1047 : (gid_t)-1);
1048 0 : unbecome_root();
1049 0 : if (ret == -1) {
1050 0 : DBG_ERR("failed to fchown "
1051 : "file %s to parent directory uid %u. Error "
1052 : "was %s\n",
1053 : fsp_str_dbg(fsp),
1054 : (unsigned int)parent_fsp->fsp_name->st.st_ex_uid,
1055 : strerror(errno));
1056 : } else {
1057 0 : DBG_DEBUG("changed new file %s to "
1058 : "parent directory uid %u.\n",
1059 : fsp_str_dbg(fsp),
1060 : (unsigned int)parent_fsp->fsp_name->st.st_ex_uid);
1061 : /* Ensure the uid entry is updated. */
1062 0 : fsp->fsp_name->st.st_ex_uid =
1063 0 : parent_fsp->fsp_name->st.st_ex_uid;
1064 : }
1065 : }
1066 :
1067 0 : static NTSTATUS change_dir_owner_to_parent_fsp(struct files_struct *parent_fsp,
1068 : struct files_struct *fsp)
1069 : {
1070 : NTSTATUS status;
1071 : int ret;
1072 :
1073 0 : if (parent_fsp->fsp_name->st.st_ex_uid == fsp->fsp_name->st.st_ex_uid) {
1074 : /* Already this uid - no need to change. */
1075 0 : DBG_DEBUG("directory %s is already owned by uid %u\n",
1076 : fsp_str_dbg(fsp),
1077 : (unsigned int)fsp->fsp_name->st.st_ex_uid);
1078 0 : return NT_STATUS_OK;
1079 : }
1080 :
1081 0 : become_root();
1082 0 : ret = SMB_VFS_FCHOWN(fsp,
1083 : parent_fsp->fsp_name->st.st_ex_uid,
1084 : (gid_t)-1);
1085 0 : unbecome_root();
1086 0 : if (ret == -1) {
1087 0 : status = map_nt_error_from_unix(errno);
1088 0 : DBG_ERR("failed to chown "
1089 : "directory %s to parent directory uid %u. "
1090 : "Error was %s\n",
1091 : fsp_str_dbg(fsp),
1092 : (unsigned int)parent_fsp->fsp_name->st.st_ex_uid,
1093 : nt_errstr(status));
1094 0 : return status;
1095 : }
1096 :
1097 0 : DBG_DEBUG("changed ownership of new "
1098 : "directory %s to parent directory uid %u.\n",
1099 : fsp_str_dbg(fsp),
1100 : (unsigned int)parent_fsp->fsp_name->st.st_ex_uid);
1101 :
1102 : /* Ensure the uid entry is updated. */
1103 0 : fsp->fsp_name->st.st_ex_uid = parent_fsp->fsp_name->st.st_ex_uid;
1104 :
1105 0 : return NT_STATUS_OK;
1106 : }
1107 :
1108 : /****************************************************************************
1109 : Open a file - returning a guaranteed ATOMIC indication of if the
1110 : file was created or not.
1111 : ****************************************************************************/
1112 :
1113 607 : static NTSTATUS fd_open_atomic(struct files_struct *dirfsp,
1114 : struct smb_filename *smb_fname,
1115 : files_struct *fsp,
1116 : int flags,
1117 : mode_t mode,
1118 : bool *file_created)
1119 : {
1120 607 : struct vfs_open_how how = { .flags = flags, .mode = mode, };
1121 607 : NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
1122 : NTSTATUS retry_status;
1123 607 : bool file_existed = VALID_STAT(smb_fname->st);
1124 :
1125 607 : if (!(how.flags & O_CREAT)) {
1126 : /*
1127 : * We're not creating the file, just pass through.
1128 : */
1129 1 : status = fd_openat(dirfsp, smb_fname, fsp, &how);
1130 1 : *file_created = false;
1131 1 : return status;
1132 : }
1133 :
1134 606 : if (how.flags & O_EXCL) {
1135 : /*
1136 : * Fail if already exists, just pass through.
1137 : */
1138 23 : status = fd_openat(dirfsp, smb_fname, fsp, &how);
1139 :
1140 : /*
1141 : * Here we've opened with O_CREAT|O_EXCL. If that went
1142 : * NT_STATUS_OK, we *know* we created this file.
1143 : */
1144 23 : *file_created = NT_STATUS_IS_OK(status);
1145 :
1146 23 : return status;
1147 : }
1148 :
1149 : /*
1150 : * Now it gets tricky. We have O_CREAT, but not O_EXCL.
1151 : * To know absolutely if we created the file or not,
1152 : * we can never call O_CREAT without O_EXCL. So if
1153 : * we think the file existed, try without O_CREAT|O_EXCL.
1154 : * If we think the file didn't exist, try with
1155 : * O_CREAT|O_EXCL.
1156 : *
1157 : * The big problem here is dangling symlinks. Opening
1158 : * without O_NOFOLLOW means both bad symlink
1159 : * and missing path return -1, ENOENT from open(). As POSIX
1160 : * is pathname based it's not possible to tell
1161 : * the difference between these two cases in a
1162 : * non-racy way, so change to try only two attempts before
1163 : * giving up.
1164 : *
1165 : * We don't have this problem for the O_NOFOLLOW
1166 : * case as it just returns NT_STATUS_OBJECT_PATH_NOT_FOUND
1167 : * mapped from the ELOOP POSIX error.
1168 : */
1169 :
1170 583 : if (file_existed) {
1171 0 : how.flags = flags & ~(O_CREAT);
1172 0 : retry_status = NT_STATUS_OBJECT_NAME_NOT_FOUND;
1173 : } else {
1174 583 : how.flags = flags | O_EXCL;
1175 583 : retry_status = NT_STATUS_OBJECT_NAME_COLLISION;
1176 : }
1177 :
1178 583 : status = fd_openat(dirfsp, smb_fname, fsp, &how);
1179 583 : if (NT_STATUS_IS_OK(status)) {
1180 583 : *file_created = !file_existed;
1181 583 : return NT_STATUS_OK;
1182 : }
1183 0 : if (NT_STATUS_EQUAL(status, retry_status)) {
1184 :
1185 0 : file_existed = !file_existed;
1186 :
1187 0 : DBG_DEBUG("File %s %s. Retry.\n",
1188 : fsp_str_dbg(fsp),
1189 : file_existed ? "existed" : "did not exist");
1190 :
1191 0 : if (file_existed) {
1192 0 : how.flags = flags & ~(O_CREAT);
1193 : } else {
1194 0 : how.flags = flags | O_EXCL;
1195 : }
1196 :
1197 0 : status = fd_openat(dirfsp, smb_fname, fsp, &how);
1198 : }
1199 :
1200 0 : *file_created = (NT_STATUS_IS_OK(status) && !file_existed);
1201 0 : return status;
1202 : }
1203 :
1204 3412 : static NTSTATUS reopen_from_procfd(struct files_struct *fsp,
1205 : int flags,
1206 : mode_t mode)
1207 : {
1208 3412 : struct vfs_open_how how = { .flags = flags, .mode = mode };
1209 : struct smb_filename proc_fname;
1210 3412 : const char *p = NULL;
1211 : char buf[PATH_MAX];
1212 : int old_fd;
1213 : int new_fd;
1214 : NTSTATUS status;
1215 :
1216 3412 : if (!fsp->fsp_flags.have_proc_fds) {
1217 607 : return NT_STATUS_MORE_PROCESSING_REQUIRED;
1218 : }
1219 :
1220 2805 : old_fd = fsp_get_pathref_fd(fsp);
1221 2805 : if (old_fd == -1) {
1222 0 : return NT_STATUS_MORE_PROCESSING_REQUIRED;
1223 : }
1224 :
1225 2805 : if (!fsp->fsp_flags.is_pathref) {
1226 0 : DBG_ERR("[%s] is not a pathref\n",
1227 : fsp_str_dbg(fsp));
1228 : #ifdef DEVELOPER
1229 0 : smb_panic("Not a pathref");
1230 : #endif
1231 : return NT_STATUS_INVALID_HANDLE;
1232 : }
1233 :
1234 2805 : p = sys_proc_fd_path(old_fd, buf, sizeof(buf));
1235 2805 : if (p == NULL) {
1236 0 : return NT_STATUS_NO_MEMORY;
1237 : }
1238 :
1239 2805 : proc_fname = (struct smb_filename) {
1240 : .base_name = discard_const_p(char, p),
1241 : };
1242 :
1243 2805 : fsp->fsp_flags.is_pathref = false;
1244 :
1245 2805 : new_fd = SMB_VFS_OPENAT(fsp->conn,
1246 : fsp->conn->cwd_fsp,
1247 : &proc_fname,
1248 : fsp,
1249 : &how);
1250 2805 : if (new_fd == -1) {
1251 4 : status = map_nt_error_from_unix(errno);
1252 4 : fd_close(fsp);
1253 4 : return status;
1254 : }
1255 :
1256 2801 : status = fd_close(fsp);
1257 2801 : if (!NT_STATUS_IS_OK(status)) {
1258 0 : return status;
1259 : }
1260 :
1261 2801 : fsp_set_fd(fsp, new_fd);
1262 2801 : return NT_STATUS_OK;
1263 : }
1264 :
1265 3412 : static NTSTATUS reopen_from_fsp(struct files_struct *dirfsp,
1266 : struct smb_filename *smb_fname,
1267 : struct files_struct *fsp,
1268 : int flags,
1269 : mode_t mode,
1270 : bool *p_file_created)
1271 : {
1272 3412 : bool __unused_file_created = false;
1273 : NTSTATUS status;
1274 :
1275 3412 : if (p_file_created == NULL) {
1276 2244 : p_file_created = &__unused_file_created;
1277 : }
1278 :
1279 : /*
1280 : * TODO: should we move this to the VFS layer?
1281 : * SMB_VFS_REOPEN_FSP()?
1282 : */
1283 :
1284 3412 : status = reopen_from_procfd(fsp,
1285 : flags,
1286 : mode);
1287 3412 : if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1288 2805 : return status;
1289 : }
1290 :
1291 : /*
1292 : * Close the existing pathref fd and set the fsp flag
1293 : * is_pathref to false so we get a "normal" fd this time.
1294 : */
1295 607 : status = fd_close(fsp);
1296 607 : if (!NT_STATUS_IS_OK(status)) {
1297 0 : return status;
1298 : }
1299 :
1300 607 : fsp->fsp_flags.is_pathref = false;
1301 :
1302 607 : status = fd_open_atomic(
1303 : dirfsp,
1304 : smb_fname,
1305 : fsp,
1306 : flags,
1307 : mode,
1308 : p_file_created);
1309 607 : return status;
1310 : }
1311 :
1312 : /****************************************************************************
1313 : Open a file.
1314 : ****************************************************************************/
1315 :
1316 6324 : static NTSTATUS open_file(struct smb_request *req,
1317 : struct files_struct *dirfsp,
1318 : struct smb_filename *smb_fname_atname,
1319 : files_struct *fsp,
1320 : int flags,
1321 : mode_t unx_mode,
1322 : uint32_t access_mask, /* client requested access mask. */
1323 : uint32_t open_access_mask, /* what we're actually using in the open. */
1324 : uint32_t private_flags,
1325 : bool *p_file_created)
1326 : {
1327 6324 : connection_struct *conn = fsp->conn;
1328 6324 : struct smb_filename *smb_fname = fsp->fsp_name;
1329 6324 : NTSTATUS status = NT_STATUS_OK;
1330 6324 : int accmode = (flags & O_ACCMODE);
1331 6324 : int local_flags = flags;
1332 6324 : bool file_existed = VALID_STAT(fsp->fsp_name->st);
1333 6324 : uint32_t need_fd_mask =
1334 : FILE_READ_DATA |
1335 : FILE_WRITE_DATA |
1336 : FILE_APPEND_DATA |
1337 : FILE_EXECUTE |
1338 : SEC_FLAG_SYSTEM_SECURITY;
1339 6324 : bool creating = !file_existed && (flags & O_CREAT);
1340 6324 : bool truncating = (flags & O_TRUNC);
1341 6324 : bool open_fd = false;
1342 6324 : bool posix_open = (fsp->posix_flags & FSP_POSIX_FLAGS_OPEN);
1343 :
1344 : /*
1345 : * Catch early an attempt to open an existing
1346 : * directory as a file.
1347 : */
1348 6324 : if (file_existed && S_ISDIR(fsp->fsp_name->st.st_ex_mode)) {
1349 4455 : return NT_STATUS_FILE_IS_A_DIRECTORY;
1350 : }
1351 :
1352 : /* Check permissions */
1353 :
1354 : /*
1355 : * This code was changed after seeing a client open request
1356 : * containing the open mode of (DENY_WRITE/read-only) with
1357 : * the 'create if not exist' bit set. The previous code
1358 : * would fail to open the file read only on a read-only share
1359 : * as it was checking the flags parameter directly against O_RDONLY,
1360 : * this was failing as the flags parameter was set to O_RDONLY|O_CREAT.
1361 : * JRA.
1362 : */
1363 :
1364 1869 : if (!CAN_WRITE(conn)) {
1365 : /* It's a read-only share - fail if we wanted to write. */
1366 0 : if(accmode != O_RDONLY || (flags & O_TRUNC) || (flags & O_APPEND)) {
1367 0 : DEBUG(3,("Permission denied opening %s\n",
1368 : smb_fname_str_dbg(smb_fname)));
1369 0 : return NT_STATUS_ACCESS_DENIED;
1370 : }
1371 0 : if (flags & O_CREAT) {
1372 : /* We don't want to write - but we must make sure that
1373 : O_CREAT doesn't create the file if we have write
1374 : access into the directory.
1375 : */
1376 0 : flags &= ~(O_CREAT|O_EXCL);
1377 0 : local_flags &= ~(O_CREAT|O_EXCL);
1378 : }
1379 : }
1380 :
1381 : /*
1382 : * This little piece of insanity is inspired by the
1383 : * fact that an NT client can open a file for O_RDONLY,
1384 : * but set the create disposition to FILE_EXISTS_TRUNCATE.
1385 : * If the client *can* write to the file, then it expects to
1386 : * truncate the file, even though it is opening for readonly.
1387 : * Quicken uses this stupid trick in backup file creation...
1388 : * Thanks *greatly* to "David W. Chapman Jr." <dwcjr@inethouston.net>
1389 : * for helping track this one down. It didn't bite us in 2.0.x
1390 : * as we always opened files read-write in that release. JRA.
1391 : */
1392 :
1393 1869 : if ((accmode == O_RDONLY) && ((flags & O_TRUNC) == O_TRUNC)) {
1394 0 : DEBUG(10,("open_file: truncate requested on read-only open "
1395 : "for file %s\n", smb_fname_str_dbg(smb_fname)));
1396 0 : local_flags = (flags & ~O_ACCMODE)|O_RDWR;
1397 : }
1398 :
1399 1869 : if ((open_access_mask & need_fd_mask) || creating || truncating) {
1400 1172 : open_fd = true;
1401 : }
1402 :
1403 1869 : if (open_fd) {
1404 : const char *wild;
1405 : int ret;
1406 :
1407 : #if defined(O_NONBLOCK) && defined(S_ISFIFO)
1408 : /*
1409 : * We would block on opening a FIFO with no one else on the
1410 : * other end. Do what we used to do and add O_NONBLOCK to the
1411 : * open flags. JRA.
1412 : */
1413 :
1414 1172 : if (file_existed && S_ISFIFO(smb_fname->st.st_ex_mode)) {
1415 0 : local_flags &= ~O_TRUNC; /* Can't truncate a FIFO. */
1416 0 : local_flags |= O_NONBLOCK;
1417 0 : truncating = false;
1418 : }
1419 : #endif
1420 :
1421 : /* Don't create files with Microsoft wildcard characters. */
1422 1172 : if (fsp_is_alternate_stream(fsp)) {
1423 : /*
1424 : * wildcard characters are allowed in stream names
1425 : * only test the basefilename
1426 : */
1427 24 : wild = fsp->base_fsp->fsp_name->base_name;
1428 : } else {
1429 1148 : wild = smb_fname->base_name;
1430 : }
1431 1670 : if ((local_flags & O_CREAT) && !file_existed &&
1432 1212 : !(fsp->posix_flags & FSP_POSIX_FLAGS_PATHNAMES) &&
1433 606 : ms_has_wild(wild)) {
1434 0 : return NT_STATUS_OBJECT_NAME_INVALID;
1435 : }
1436 :
1437 : /* Can we access this file ? */
1438 1172 : if (!fsp_is_alternate_stream(fsp)) {
1439 : /* Only do this check on non-stream open. */
1440 1148 : if (file_existed) {
1441 560 : status = smbd_check_access_rights_fsp(
1442 : dirfsp,
1443 : fsp,
1444 : false,
1445 : open_access_mask);
1446 :
1447 560 : if (!NT_STATUS_IS_OK(status)) {
1448 4 : DBG_DEBUG("smbd_check_access_rights_fsp"
1449 : " on file %s returned %s\n",
1450 : fsp_str_dbg(fsp),
1451 : nt_errstr(status));
1452 : }
1453 :
1454 564 : if (!NT_STATUS_IS_OK(status) &&
1455 4 : !NT_STATUS_EQUAL(status,
1456 : NT_STATUS_OBJECT_NAME_NOT_FOUND))
1457 : {
1458 4 : return status;
1459 : }
1460 :
1461 556 : if (NT_STATUS_EQUAL(status,
1462 : NT_STATUS_OBJECT_NAME_NOT_FOUND))
1463 : {
1464 0 : DEBUG(10, ("open_file: "
1465 : "file %s vanished since we "
1466 : "checked for existence.\n",
1467 : smb_fname_str_dbg(smb_fname)));
1468 0 : file_existed = false;
1469 0 : SET_STAT_INVALID(fsp->fsp_name->st);
1470 : }
1471 : }
1472 :
1473 1144 : if (!file_existed) {
1474 588 : if (!(local_flags & O_CREAT)) {
1475 : /* File didn't exist and no O_CREAT. */
1476 0 : return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1477 : }
1478 :
1479 588 : status = check_parent_access_fsp(
1480 : dirfsp,
1481 : SEC_DIR_ADD_FILE);
1482 588 : if (!NT_STATUS_IS_OK(status)) {
1483 0 : DBG_DEBUG("check_parent_access_fsp on "
1484 : "directory %s for file %s "
1485 : "returned %s\n",
1486 : smb_fname_str_dbg(
1487 : dirfsp->fsp_name),
1488 : smb_fname_str_dbg(smb_fname),
1489 : nt_errstr(status));
1490 0 : return status;
1491 : }
1492 : }
1493 : }
1494 :
1495 : /*
1496 : * Actually do the open - if O_TRUNC is needed handle it
1497 : * below under the share mode lock.
1498 : */
1499 1168 : status = reopen_from_fsp(dirfsp,
1500 : smb_fname_atname,
1501 : fsp,
1502 : local_flags & ~O_TRUNC,
1503 : unx_mode,
1504 : p_file_created);
1505 1168 : if (NT_STATUS_EQUAL(status, NT_STATUS_STOPPED_ON_SYMLINK)) {
1506 : /*
1507 : * POSIX client that hit a symlink. We don't want to
1508 : * return NT_STATUS_STOPPED_ON_SYMLINK to avoid handling
1509 : * this special error code in all callers, so we map
1510 : * this to NT_STATUS_OBJECT_NAME_NOT_FOUND to match
1511 : * openat_pathref_fsp().
1512 : */
1513 0 : status = NT_STATUS_OBJECT_NAME_NOT_FOUND;
1514 : }
1515 1168 : if (!NT_STATUS_IS_OK(status)) {
1516 1 : DEBUG(3,("Error opening file %s (%s) (local_flags=%d) "
1517 : "(flags=%d)\n", smb_fname_str_dbg(smb_fname),
1518 : nt_errstr(status),local_flags,flags));
1519 1 : return status;
1520 : }
1521 :
1522 1167 : if (local_flags & O_NONBLOCK) {
1523 : /*
1524 : * GPFS can return ETIMEDOUT for pread on
1525 : * nonblocking file descriptors when files
1526 : * migrated to tape need to be recalled. I
1527 : * could imagine this happens elsewhere
1528 : * too. With blocking file descriptors this
1529 : * does not happen.
1530 : */
1531 1167 : ret = vfs_set_blocking(fsp, true);
1532 1167 : if (ret == -1) {
1533 0 : status = map_nt_error_from_unix(errno);
1534 0 : DBG_WARNING("Could not set fd to blocking: "
1535 : "%s\n", strerror(errno));
1536 0 : fd_close(fsp);
1537 0 : return status;
1538 : }
1539 : }
1540 :
1541 1167 : if (*p_file_created) {
1542 : /* We created this file. */
1543 :
1544 605 : bool need_re_stat = false;
1545 : /* Do all inheritance work after we've
1546 : done a successful fstat call and filled
1547 : in the stat struct in fsp->fsp_name. */
1548 :
1549 : /* Inherit the ACL if required */
1550 605 : if (lp_inherit_permissions(SNUM(conn))) {
1551 0 : inherit_access_posix_acl(conn,
1552 : dirfsp,
1553 : smb_fname,
1554 : unx_mode);
1555 0 : need_re_stat = true;
1556 : }
1557 :
1558 : /* Change the owner if required. */
1559 605 : if (lp_inherit_owner(SNUM(conn)) != INHERIT_OWNER_NO) {
1560 0 : change_file_owner_to_parent_fsp(dirfsp, fsp);
1561 0 : need_re_stat = true;
1562 : }
1563 :
1564 605 : if (need_re_stat) {
1565 0 : status = vfs_stat_fsp(fsp);
1566 : /*
1567 : * If we have an fd, this stat should succeed.
1568 : */
1569 0 : if (!NT_STATUS_IS_OK(status)) {
1570 0 : DBG_ERR("Error doing fstat on open "
1571 : "file %s (%s)\n",
1572 : smb_fname_str_dbg(smb_fname),
1573 : nt_errstr(status));
1574 0 : fd_close(fsp);
1575 0 : return status;
1576 : }
1577 : }
1578 :
1579 605 : notify_fname(conn, NOTIFY_ACTION_ADDED,
1580 : FILE_NOTIFY_CHANGE_FILE_NAME,
1581 605 : smb_fname->base_name);
1582 : }
1583 : } else {
1584 697 : if (!file_existed) {
1585 : /* File must exist for a stat open. */
1586 0 : return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1587 : }
1588 :
1589 697 : if (S_ISLNK(smb_fname->st.st_ex_mode) &&
1590 0 : !posix_open)
1591 : {
1592 : /*
1593 : * Don't allow stat opens on symlinks directly unless
1594 : * it's a POSIX open. Match the return code from
1595 : * openat_pathref_fsp().
1596 : */
1597 0 : return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1598 : }
1599 :
1600 697 : if (!fsp->fsp_flags.is_pathref) {
1601 : /*
1602 : * There is only one legit case where end up here:
1603 : * openat_pathref_fsp() failed to open a symlink, so the
1604 : * fsp was created by fsp_new() which doesn't set
1605 : * is_pathref. Other then that, we should always have a
1606 : * pathref fsp at this point. The subsequent checks
1607 : * assert this.
1608 : */
1609 0 : if (!(smb_fname->flags & SMB_FILENAME_POSIX_PATH)) {
1610 0 : DBG_ERR("[%s] is not a POSIX pathname\n",
1611 : smb_fname_str_dbg(smb_fname));
1612 0 : return NT_STATUS_INTERNAL_ERROR;
1613 : }
1614 0 : if (!S_ISLNK(smb_fname->st.st_ex_mode)) {
1615 0 : DBG_ERR("[%s] is not a symlink\n",
1616 : smb_fname_str_dbg(smb_fname));
1617 0 : return NT_STATUS_INTERNAL_ERROR;
1618 : }
1619 0 : if (fsp_get_pathref_fd(fsp) != -1) {
1620 0 : DBG_ERR("fd for [%s] is not -1: fd [%d]\n",
1621 : smb_fname_str_dbg(smb_fname),
1622 : fsp_get_pathref_fd(fsp));
1623 0 : return NT_STATUS_INTERNAL_ERROR;
1624 : }
1625 : }
1626 :
1627 : /*
1628 : * Access to streams is checked by checking the basefile and
1629 : * that has alreay been checked by check_base_file_access()
1630 : * in create_file_unixpath().
1631 : */
1632 697 : if (!fsp_is_alternate_stream(fsp)) {
1633 657 : status = smbd_check_access_rights_fsp(dirfsp,
1634 : fsp,
1635 : false,
1636 : open_access_mask);
1637 :
1638 657 : if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND) &&
1639 0 : posix_open &&
1640 0 : S_ISLNK(smb_fname->st.st_ex_mode)) {
1641 : /* This is a POSIX stat open for delete
1642 : * or rename on a symlink that points
1643 : * nowhere. Allow. */
1644 0 : DEBUG(10,("open_file: allowing POSIX "
1645 : "open on bad symlink %s\n",
1646 : smb_fname_str_dbg(smb_fname)));
1647 0 : status = NT_STATUS_OK;
1648 : }
1649 :
1650 657 : if (!NT_STATUS_IS_OK(status)) {
1651 2 : DBG_DEBUG("smbd_check_access_rights_fsp on file "
1652 : "%s returned %s\n",
1653 : fsp_str_dbg(fsp),
1654 : nt_errstr(status));
1655 2 : return status;
1656 : }
1657 : }
1658 : }
1659 :
1660 1862 : fsp->file_id = vfs_file_id_from_sbuf(conn, &smb_fname->st);
1661 1862 : fsp->vuid = req ? req->vuid : UID_FIELD_INVALID;
1662 1862 : fsp->file_pid = req ? req->smbpid : 0;
1663 1862 : fsp->fsp_flags.can_lock = true;
1664 1862 : fsp->fsp_flags.can_read = ((access_mask & FILE_READ_DATA) != 0);
1665 1862 : fsp->fsp_flags.can_write =
1666 3724 : CAN_WRITE(conn) &&
1667 1862 : ((access_mask & (FILE_WRITE_DATA | FILE_APPEND_DATA)) != 0);
1668 1862 : fsp->print_file = NULL;
1669 1862 : fsp->fsp_flags.modified = false;
1670 1862 : fsp->sent_oplock_break = NO_BREAK_SENT;
1671 1862 : fsp->fsp_flags.is_directory = false;
1672 1862 : if (conn->aio_write_behind_list &&
1673 0 : is_in_path(smb_fname->base_name, conn->aio_write_behind_list,
1674 0 : posix_open ? true: conn->case_sensitive)) {
1675 0 : fsp->fsp_flags.aio_write_behind = true;
1676 : }
1677 :
1678 1862 : DEBUG(2,("%s opened file %s read=%s write=%s (numopen=%d)\n",
1679 : conn->session_info->unix_info->unix_name,
1680 : smb_fname_str_dbg(smb_fname),
1681 : BOOLSTR(fsp->fsp_flags.can_read),
1682 : BOOLSTR(fsp->fsp_flags.can_write),
1683 : conn->num_files_open));
1684 :
1685 1862 : return NT_STATUS_OK;
1686 : }
1687 :
1688 72 : static bool mask_conflict(
1689 : uint32_t new_access,
1690 : uint32_t existing_access,
1691 : uint32_t access_mask,
1692 : uint32_t new_sharemode,
1693 : uint32_t existing_sharemode,
1694 : uint32_t sharemode_mask)
1695 : {
1696 72 : bool want_access = (new_access & access_mask);
1697 72 : bool allow_existing = (existing_sharemode & sharemode_mask);
1698 72 : bool have_access = (existing_access & access_mask);
1699 72 : bool allow_new = (new_sharemode & sharemode_mask);
1700 :
1701 72 : if (want_access && !allow_existing) {
1702 36 : DBG_DEBUG("Access request 0x%"PRIx32"/0x%"PRIx32" conflicts "
1703 : "with existing sharemode 0x%"PRIx32"/0x%"PRIx32"\n",
1704 : new_access,
1705 : access_mask,
1706 : existing_sharemode,
1707 : sharemode_mask);
1708 36 : return true;
1709 : }
1710 36 : if (have_access && !allow_new) {
1711 2 : DBG_DEBUG("Sharemode request 0x%"PRIx32"/0x%"PRIx32" conflicts "
1712 : "with existing access 0x%"PRIx32"/0x%"PRIx32"\n",
1713 : new_sharemode,
1714 : sharemode_mask,
1715 : existing_access,
1716 : access_mask);
1717 2 : return true;
1718 : }
1719 34 : return false;
1720 : }
1721 :
1722 : /****************************************************************************
1723 : Check if we can open a file with a share mode.
1724 : Returns True if conflict, False if not.
1725 : ****************************************************************************/
1726 :
1727 : static const uint32_t conflicting_access =
1728 : FILE_WRITE_DATA|
1729 : FILE_APPEND_DATA|
1730 : FILE_READ_DATA|
1731 : FILE_EXECUTE|
1732 : DELETE_ACCESS;
1733 :
1734 5119 : static bool share_conflict(uint32_t e_access_mask,
1735 : uint32_t e_share_access,
1736 : uint32_t access_mask,
1737 : uint32_t share_access)
1738 : {
1739 : bool conflict;
1740 :
1741 5119 : DBG_DEBUG("existing access_mask = 0x%"PRIx32", "
1742 : "existing share access = 0x%"PRIx32", "
1743 : "access_mask = 0x%"PRIx32", "
1744 : "share_access = 0x%"PRIx32"\n",
1745 : e_access_mask,
1746 : e_share_access,
1747 : access_mask,
1748 : share_access);
1749 :
1750 5119 : if ((e_access_mask & conflicting_access) == 0) {
1751 5094 : DBG_DEBUG("No conflict due to "
1752 : "existing access_mask = 0x%"PRIx32"\n",
1753 : e_access_mask);
1754 5094 : return false;
1755 : }
1756 25 : if ((access_mask & conflicting_access) == 0) {
1757 1 : DBG_DEBUG("No conflict due to access_mask = 0x%"PRIx32"\n",
1758 : access_mask);
1759 1 : return false;
1760 : }
1761 :
1762 24 : conflict = mask_conflict(
1763 : access_mask, e_access_mask, FILE_WRITE_DATA | FILE_APPEND_DATA,
1764 : share_access, e_share_access, FILE_SHARE_WRITE);
1765 24 : conflict |= mask_conflict(
1766 : access_mask, e_access_mask, FILE_READ_DATA | FILE_EXECUTE,
1767 : share_access, e_share_access, FILE_SHARE_READ);
1768 24 : conflict |= mask_conflict(
1769 : access_mask, e_access_mask, DELETE_ACCESS,
1770 : share_access, e_share_access, FILE_SHARE_DELETE);
1771 :
1772 24 : DBG_DEBUG("conflict=%s\n", conflict ? "true" : "false");
1773 24 : return conflict;
1774 : }
1775 :
1776 : #if defined(DEVELOPER)
1777 :
1778 : struct validate_my_share_entries_state {
1779 : struct smbd_server_connection *sconn;
1780 : struct file_id fid;
1781 : struct server_id self;
1782 : };
1783 :
1784 28 : static bool validate_my_share_entries_fn(
1785 : struct share_mode_entry *e,
1786 : bool *modified,
1787 : void *private_data)
1788 : {
1789 28 : struct validate_my_share_entries_state *state = private_data;
1790 : files_struct *fsp;
1791 :
1792 28 : if (!server_id_equal(&state->self, &e->pid)) {
1793 8 : return false;
1794 : }
1795 :
1796 20 : if (e->op_mid == 0) {
1797 : /* INTERNAL_OPEN_ONLY */
1798 0 : return false;
1799 : }
1800 :
1801 20 : fsp = file_find_dif(state->sconn, state->fid, e->share_file_id);
1802 20 : if (!fsp) {
1803 0 : DBG_ERR("PANIC : %s\n",
1804 : share_mode_str(talloc_tos(), 0, &state->fid, e));
1805 0 : smb_panic("validate_my_share_entries: Cannot match a "
1806 : "share entry with an open file\n");
1807 : }
1808 :
1809 20 : if (((uint16_t)fsp->oplock_type) != e->op_type) {
1810 0 : goto panic;
1811 : }
1812 :
1813 20 : return false;
1814 :
1815 0 : panic:
1816 : {
1817 : char *str;
1818 0 : DBG_ERR("validate_my_share_entries: PANIC : %s\n",
1819 : share_mode_str(talloc_tos(), 0, &state->fid, e));
1820 0 : str = talloc_asprintf(talloc_tos(),
1821 : "validate_my_share_entries: "
1822 : "file %s, oplock_type = 0x%x, op_type = 0x%x\n",
1823 0 : fsp->fsp_name->base_name,
1824 0 : (unsigned int)fsp->oplock_type,
1825 0 : (unsigned int)e->op_type);
1826 0 : smb_panic(str);
1827 : }
1828 :
1829 : return false;
1830 : }
1831 : #endif
1832 :
1833 : /**
1834 : * Allowed access mask for stat opens relevant to oplocks
1835 : **/
1836 19648 : bool is_oplock_stat_open(uint32_t access_mask)
1837 : {
1838 19648 : const uint32_t stat_open_bits =
1839 : (SYNCHRONIZE_ACCESS|
1840 : FILE_READ_ATTRIBUTES|
1841 : FILE_WRITE_ATTRIBUTES);
1842 :
1843 35076 : return (((access_mask & stat_open_bits) != 0) &&
1844 15428 : ((access_mask & ~stat_open_bits) == 0));
1845 : }
1846 :
1847 : /**
1848 : * Allowed access mask for stat opens relevant to leases
1849 : **/
1850 0 : bool is_lease_stat_open(uint32_t access_mask)
1851 : {
1852 0 : const uint32_t stat_open_bits =
1853 : (SYNCHRONIZE_ACCESS|
1854 : FILE_READ_ATTRIBUTES|
1855 : FILE_WRITE_ATTRIBUTES|
1856 : READ_CONTROL_ACCESS);
1857 :
1858 0 : return (((access_mask & stat_open_bits) != 0) &&
1859 0 : ((access_mask & ~stat_open_bits) == 0));
1860 : }
1861 :
1862 : struct has_delete_on_close_state {
1863 : bool ret;
1864 : };
1865 :
1866 0 : static bool has_delete_on_close_fn(
1867 : struct share_mode_entry *e,
1868 : bool *modified,
1869 : void *private_data)
1870 : {
1871 0 : struct has_delete_on_close_state *state = private_data;
1872 0 : state->ret = !share_entry_stale_pid(e);
1873 0 : return state->ret;
1874 : }
1875 :
1876 12080 : static bool has_delete_on_close(struct share_mode_lock *lck,
1877 : uint32_t name_hash)
1878 : {
1879 12080 : struct has_delete_on_close_state state = { .ret = false };
1880 : bool ok;
1881 :
1882 12080 : if (!is_delete_on_close_set(lck, name_hash)) {
1883 12080 : return false;
1884 : }
1885 :
1886 0 : ok= share_mode_forall_entries(lck, has_delete_on_close_fn, &state);
1887 0 : if (!ok) {
1888 0 : DBG_DEBUG("share_mode_forall_entries failed\n");
1889 0 : return false;
1890 : }
1891 0 : return state.ret;
1892 : }
1893 :
1894 12066 : static void share_mode_flags_restrict(
1895 : struct share_mode_lock *lck,
1896 : uint32_t access_mask,
1897 : uint32_t share_mode,
1898 : uint32_t lease_type)
1899 : {
1900 : uint32_t existing_access_mask, existing_share_mode;
1901 : uint32_t existing_lease_type;
1902 :
1903 12066 : share_mode_flags_get(
1904 : lck,
1905 : &existing_access_mask,
1906 : &existing_share_mode,
1907 : &existing_lease_type);
1908 :
1909 12066 : existing_access_mask |= access_mask;
1910 12066 : if (access_mask & conflicting_access) {
1911 4619 : existing_share_mode &= share_mode;
1912 : }
1913 12066 : existing_lease_type |= lease_type;
1914 :
1915 12066 : share_mode_flags_set(
1916 : lck,
1917 : existing_access_mask,
1918 : existing_share_mode,
1919 : existing_lease_type,
1920 : NULL);
1921 12066 : }
1922 :
1923 : /****************************************************************************
1924 : Deal with share modes
1925 : Invariant: Share mode must be locked on entry and exit.
1926 : Returns -1 on error, or number of share modes on success (may be zero).
1927 : ****************************************************************************/
1928 :
1929 : struct open_mode_check_state {
1930 : struct file_id fid;
1931 : uint32_t access_mask;
1932 : uint32_t share_access;
1933 : uint32_t lease_type;
1934 : };
1935 :
1936 15 : static bool open_mode_check_fn(
1937 : struct share_mode_entry *e,
1938 : bool *modified,
1939 : void *private_data)
1940 : {
1941 15 : struct open_mode_check_state *state = private_data;
1942 : bool disconnected, stale;
1943 : uint32_t access_mask, share_access, lease_type;
1944 :
1945 15 : disconnected = server_id_is_disconnected(&e->pid);
1946 15 : if (disconnected) {
1947 0 : return false;
1948 : }
1949 :
1950 15 : access_mask = state->access_mask | e->access_mask;
1951 15 : share_access = state->share_access;
1952 15 : if (e->access_mask & conflicting_access) {
1953 15 : share_access &= e->share_access;
1954 : }
1955 15 : lease_type = state->lease_type | get_lease_type(e, state->fid);
1956 :
1957 16 : if ((access_mask == state->access_mask) &&
1958 2 : (share_access == state->share_access) &&
1959 1 : (lease_type == state->lease_type)) {
1960 1 : return false;
1961 : }
1962 :
1963 14 : stale = share_entry_stale_pid(e);
1964 14 : if (stale) {
1965 0 : return false;
1966 : }
1967 :
1968 14 : state->access_mask = access_mask;
1969 14 : state->share_access = share_access;
1970 14 : state->lease_type = lease_type;
1971 :
1972 14 : return false;
1973 : }
1974 :
1975 12080 : static NTSTATUS open_mode_check(connection_struct *conn,
1976 : struct file_id fid,
1977 : struct share_mode_lock *lck,
1978 : uint32_t access_mask,
1979 : uint32_t share_access)
1980 : {
1981 : struct open_mode_check_state state;
1982 : bool ok, conflict;
1983 12080 : bool modified = false;
1984 :
1985 12080 : if (is_oplock_stat_open(access_mask)) {
1986 : /* Stat open that doesn't trigger oplock breaks or share mode
1987 : * checks... ! JRA. */
1988 6961 : return NT_STATUS_OK;
1989 : }
1990 :
1991 : /*
1992 : * Check if the share modes will give us access.
1993 : */
1994 :
1995 : #if defined(DEVELOPER)
1996 : {
1997 9483 : struct validate_my_share_entries_state validate_state = {
1998 5119 : .sconn = conn->sconn,
1999 : .fid = fid,
2000 5119 : .self = messaging_server_id(conn->sconn->msg_ctx),
2001 : };
2002 5119 : ok = share_mode_forall_entries(
2003 : lck, validate_my_share_entries_fn, &validate_state);
2004 5119 : SMB_ASSERT(ok);
2005 : }
2006 : #endif
2007 :
2008 5119 : share_mode_flags_get(
2009 : lck, &state.access_mask, &state.share_access, NULL);
2010 :
2011 5119 : conflict = share_conflict(
2012 : state.access_mask,
2013 : state.share_access,
2014 : access_mask,
2015 : share_access);
2016 5119 : if (!conflict) {
2017 5105 : DBG_DEBUG("No conflict due to share_mode_flags access\n");
2018 5105 : return NT_STATUS_OK;
2019 : }
2020 :
2021 14 : state = (struct open_mode_check_state) {
2022 : .fid = fid,
2023 : .share_access = (FILE_SHARE_READ|
2024 : FILE_SHARE_WRITE|
2025 : FILE_SHARE_DELETE),
2026 : };
2027 :
2028 : /*
2029 : * Walk the share mode array to recalculate d->flags
2030 : */
2031 :
2032 14 : ok = share_mode_forall_entries(lck, open_mode_check_fn, &state);
2033 14 : if (!ok) {
2034 0 : DBG_DEBUG("share_mode_forall_entries failed\n");
2035 0 : return NT_STATUS_INTERNAL_ERROR;
2036 : }
2037 :
2038 14 : share_mode_flags_set(
2039 : lck,
2040 : state.access_mask,
2041 : state.share_access,
2042 : state.lease_type,
2043 : &modified);
2044 14 : if (!modified) {
2045 : /*
2046 : * We only end up here if we had a sharing violation
2047 : * from d->flags and have recalculated it.
2048 : */
2049 14 : return NT_STATUS_SHARING_VIOLATION;
2050 : }
2051 :
2052 0 : conflict = share_conflict(
2053 : state.access_mask,
2054 : state.share_access,
2055 : access_mask,
2056 : share_access);
2057 0 : if (!conflict) {
2058 0 : DBG_DEBUG("No conflict due to share_mode_flags access\n");
2059 0 : return NT_STATUS_OK;
2060 : }
2061 :
2062 0 : return NT_STATUS_SHARING_VIOLATION;
2063 : }
2064 :
2065 : /*
2066 : * Send a break message to the oplock holder and delay the open for
2067 : * our client.
2068 : */
2069 :
2070 0 : NTSTATUS send_break_message(struct messaging_context *msg_ctx,
2071 : const struct file_id *id,
2072 : const struct share_mode_entry *exclusive,
2073 : uint16_t break_to)
2074 : {
2075 0 : struct oplock_break_message msg = {
2076 : .id = *id,
2077 0 : .share_file_id = exclusive->share_file_id,
2078 : .break_to = break_to,
2079 : };
2080 : enum ndr_err_code ndr_err;
2081 : DATA_BLOB blob;
2082 : NTSTATUS status;
2083 :
2084 0 : if (DEBUGLVL(10)) {
2085 : struct server_id_buf buf;
2086 0 : DBG_DEBUG("Sending break message to %s\n",
2087 : server_id_str_buf(exclusive->pid, &buf));
2088 0 : NDR_PRINT_DEBUG(oplock_break_message, &msg);
2089 : }
2090 :
2091 0 : ndr_err = ndr_push_struct_blob(
2092 : &blob,
2093 : talloc_tos(),
2094 : &msg,
2095 : (ndr_push_flags_fn_t)ndr_push_oplock_break_message);
2096 0 : if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
2097 0 : DBG_WARNING("ndr_push_oplock_break_message failed: %s\n",
2098 : ndr_errstr(ndr_err));
2099 0 : return ndr_map_error2ntstatus(ndr_err);
2100 : }
2101 :
2102 0 : status = messaging_send(
2103 : msg_ctx, exclusive->pid, MSG_SMB_BREAK_REQUEST, &blob);
2104 0 : TALLOC_FREE(blob.data);
2105 0 : if (!NT_STATUS_IS_OK(status)) {
2106 0 : DEBUG(3, ("Could not send oplock break message: %s\n",
2107 : nt_errstr(status)));
2108 : }
2109 :
2110 0 : return status;
2111 : }
2112 :
2113 : struct validate_oplock_types_state {
2114 : bool valid;
2115 : bool batch;
2116 : bool ex_or_batch;
2117 : bool level2;
2118 : bool no_oplock;
2119 : uint32_t num_non_stat_opens;
2120 : };
2121 :
2122 20 : static bool validate_oplock_types_fn(
2123 : struct share_mode_entry *e,
2124 : bool *modified,
2125 : void *private_data)
2126 : {
2127 20 : struct validate_oplock_types_state *state = private_data;
2128 :
2129 20 : if (e->op_mid == 0) {
2130 : /* INTERNAL_OPEN_ONLY */
2131 0 : return false;
2132 : }
2133 :
2134 20 : if (e->op_type == NO_OPLOCK && is_oplock_stat_open(e->access_mask)) {
2135 : /*
2136 : * We ignore stat opens in the table - they always
2137 : * have NO_OPLOCK and never get or cause breaks. JRA.
2138 : */
2139 0 : return false;
2140 : }
2141 :
2142 20 : state->num_non_stat_opens += 1;
2143 :
2144 20 : if (BATCH_OPLOCK_TYPE(e->op_type)) {
2145 : /* batch - can only be one. */
2146 0 : if (share_entry_stale_pid(e)) {
2147 0 : DBG_DEBUG("Found stale batch oplock\n");
2148 0 : return false;
2149 : }
2150 0 : if (state->ex_or_batch ||
2151 0 : state->batch ||
2152 0 : state->level2 ||
2153 0 : state->no_oplock) {
2154 0 : DBG_ERR("Bad batch oplock entry\n");
2155 0 : state->valid = false;
2156 0 : return true;
2157 : }
2158 0 : state->batch = true;
2159 : }
2160 :
2161 20 : if (EXCLUSIVE_OPLOCK_TYPE(e->op_type)) {
2162 0 : if (share_entry_stale_pid(e)) {
2163 0 : DBG_DEBUG("Found stale duplicate oplock\n");
2164 0 : return false;
2165 : }
2166 : /* Exclusive or batch - can only be one. */
2167 0 : if (state->ex_or_batch ||
2168 0 : state->level2 ||
2169 0 : state->no_oplock) {
2170 0 : DBG_ERR("Bad exclusive or batch oplock entry\n");
2171 0 : state->valid = false;
2172 0 : return true;
2173 : }
2174 0 : state->ex_or_batch = true;
2175 : }
2176 :
2177 20 : if (LEVEL_II_OPLOCK_TYPE(e->op_type)) {
2178 0 : if (state->batch || state->ex_or_batch) {
2179 0 : if (share_entry_stale_pid(e)) {
2180 0 : DBG_DEBUG("Found stale LevelII oplock\n");
2181 0 : return false;
2182 : }
2183 0 : DBG_DEBUG("Bad levelII oplock entry\n");
2184 0 : state->valid = false;
2185 0 : return true;
2186 : }
2187 0 : state->level2 = true;
2188 : }
2189 :
2190 20 : if (e->op_type == NO_OPLOCK) {
2191 20 : if (state->batch || state->ex_or_batch) {
2192 0 : if (share_entry_stale_pid(e)) {
2193 0 : DBG_DEBUG("Found stale NO_OPLOCK entry\n");
2194 0 : return false;
2195 : }
2196 0 : DBG_ERR("Bad no oplock entry\n");
2197 0 : state->valid = false;
2198 0 : return true;
2199 : }
2200 20 : state->no_oplock = true;
2201 : }
2202 :
2203 20 : return false;
2204 : }
2205 :
2206 : /*
2207 : * Do internal consistency checks on the share mode for a file.
2208 : */
2209 :
2210 1862 : static bool validate_oplock_types(struct share_mode_lock *lck)
2211 : {
2212 1862 : struct validate_oplock_types_state state = { .valid = true };
2213 : static bool skip_validation;
2214 : bool validate;
2215 : bool ok;
2216 :
2217 1862 : if (skip_validation) {
2218 0 : return true;
2219 : }
2220 :
2221 1862 : validate = lp_parm_bool(-1, "smbd", "validate_oplock_types", false);
2222 1862 : if (!validate) {
2223 0 : DBG_DEBUG("smbd:validate_oplock_types not set to yes\n");
2224 0 : skip_validation = true;
2225 0 : return true;
2226 : }
2227 :
2228 1862 : ok = share_mode_forall_entries(lck, validate_oplock_types_fn, &state);
2229 1862 : if (!ok) {
2230 0 : DBG_DEBUG("share_mode_forall_entries failed\n");
2231 0 : return false;
2232 : }
2233 1862 : if (!state.valid) {
2234 0 : DBG_DEBUG("Got invalid oplock configuration\n");
2235 0 : return false;
2236 : }
2237 :
2238 1862 : if ((state.batch || state.ex_or_batch) &&
2239 0 : (state.num_non_stat_opens != 1)) {
2240 0 : DBG_WARNING("got batch (%d) or ex (%d) non-exclusively "
2241 : "(%"PRIu32")\n",
2242 : (int)state.batch,
2243 : (int)state.ex_or_batch,
2244 : state.num_non_stat_opens);
2245 0 : return false;
2246 : }
2247 :
2248 1862 : return true;
2249 : }
2250 :
2251 20 : static bool is_same_lease(const files_struct *fsp,
2252 : const struct share_mode_entry *e,
2253 : const struct smb2_lease *lease)
2254 : {
2255 20 : if (e->op_type != LEASE_OPLOCK) {
2256 20 : return false;
2257 : }
2258 0 : if (lease == NULL) {
2259 0 : return false;
2260 : }
2261 :
2262 0 : return smb2_lease_equal(fsp_client_guid(fsp),
2263 : &lease->lease_key,
2264 : &e->client_guid,
2265 : &e->lease_key);
2266 : }
2267 :
2268 1818 : static bool file_has_brlocks(files_struct *fsp)
2269 : {
2270 : struct byte_range_lock *br_lck;
2271 :
2272 1818 : br_lck = brl_get_locks_readonly(fsp);
2273 1818 : if (!br_lck)
2274 0 : return false;
2275 :
2276 1818 : return (brl_num_locks(br_lck) > 0);
2277 : }
2278 :
2279 0 : struct fsp_lease *find_fsp_lease(struct files_struct *new_fsp,
2280 : const struct smb2_lease_key *key,
2281 : uint32_t current_state,
2282 : uint16_t lease_version,
2283 : uint16_t lease_epoch)
2284 : {
2285 : struct files_struct *fsp;
2286 :
2287 : /*
2288 : * TODO: Measure how expensive this loop is with thousands of open
2289 : * handles...
2290 : */
2291 :
2292 0 : for (fsp = file_find_di_first(new_fsp->conn->sconn, new_fsp->file_id, true);
2293 0 : fsp != NULL;
2294 0 : fsp = file_find_di_next(fsp, true)) {
2295 :
2296 0 : if (fsp == new_fsp) {
2297 0 : continue;
2298 : }
2299 0 : if (fsp->oplock_type != LEASE_OPLOCK) {
2300 0 : continue;
2301 : }
2302 0 : if (smb2_lease_key_equal(&fsp->lease->lease.lease_key, key)) {
2303 0 : fsp->lease->ref_count += 1;
2304 0 : return fsp->lease;
2305 : }
2306 : }
2307 :
2308 : /* Not found - must be leased in another smbd. */
2309 0 : new_fsp->lease = talloc_zero(new_fsp->conn->sconn, struct fsp_lease);
2310 0 : if (new_fsp->lease == NULL) {
2311 0 : return NULL;
2312 : }
2313 0 : new_fsp->lease->ref_count = 1;
2314 0 : new_fsp->lease->sconn = new_fsp->conn->sconn;
2315 0 : new_fsp->lease->lease.lease_key = *key;
2316 0 : new_fsp->lease->lease.lease_state = current_state;
2317 : /*
2318 : * We internally treat all leases as V2 and update
2319 : * the epoch, but when sending breaks it matters if
2320 : * the requesting lease was v1 or v2.
2321 : */
2322 0 : new_fsp->lease->lease.lease_version = lease_version;
2323 0 : new_fsp->lease->lease.lease_epoch = lease_epoch;
2324 0 : return new_fsp->lease;
2325 : }
2326 :
2327 0 : static NTSTATUS try_lease_upgrade(struct files_struct *fsp,
2328 : struct share_mode_lock *lck,
2329 : const struct GUID *client_guid,
2330 : const struct smb2_lease *lease,
2331 : uint32_t granted)
2332 : {
2333 : bool do_upgrade;
2334 : uint32_t current_state, breaking_to_requested, breaking_to_required;
2335 : bool breaking;
2336 : uint16_t lease_version, epoch;
2337 : uint32_t existing, requested;
2338 : NTSTATUS status;
2339 :
2340 0 : status = leases_db_get(
2341 : client_guid,
2342 : &lease->lease_key,
2343 0 : &fsp->file_id,
2344 : ¤t_state,
2345 : &breaking,
2346 : &breaking_to_requested,
2347 : &breaking_to_required,
2348 : &lease_version,
2349 : &epoch);
2350 0 : if (!NT_STATUS_IS_OK(status)) {
2351 0 : return status;
2352 : }
2353 :
2354 0 : fsp->lease = find_fsp_lease(
2355 : fsp,
2356 : &lease->lease_key,
2357 : current_state,
2358 : lease_version,
2359 : epoch);
2360 0 : if (fsp->lease == NULL) {
2361 0 : DEBUG(1, ("Did not find existing lease for file %s\n",
2362 : fsp_str_dbg(fsp)));
2363 0 : return NT_STATUS_NO_MEMORY;
2364 : }
2365 :
2366 : /*
2367 : * Upgrade only if the requested lease is a strict upgrade.
2368 : */
2369 0 : existing = current_state;
2370 0 : requested = lease->lease_state;
2371 :
2372 : /*
2373 : * Tricky: This test makes sure that "requested" is a
2374 : * strict bitwise superset of "existing".
2375 : */
2376 0 : do_upgrade = ((existing & requested) == existing);
2377 :
2378 : /*
2379 : * Upgrade only if there's a change.
2380 : */
2381 0 : do_upgrade &= (granted != existing);
2382 :
2383 : /*
2384 : * Upgrade only if other leases don't prevent what was asked
2385 : * for.
2386 : */
2387 0 : do_upgrade &= (granted == requested);
2388 :
2389 : /*
2390 : * only upgrade if we are not in breaking state
2391 : */
2392 0 : do_upgrade &= !breaking;
2393 :
2394 0 : DEBUG(10, ("existing=%"PRIu32", requested=%"PRIu32", "
2395 : "granted=%"PRIu32", do_upgrade=%d\n",
2396 : existing, requested, granted, (int)do_upgrade));
2397 :
2398 0 : if (do_upgrade) {
2399 : NTSTATUS set_status;
2400 :
2401 0 : current_state = granted;
2402 0 : epoch += 1;
2403 :
2404 0 : set_status = leases_db_set(
2405 : client_guid,
2406 : &lease->lease_key,
2407 : current_state,
2408 : breaking,
2409 : breaking_to_requested,
2410 : breaking_to_required,
2411 : lease_version,
2412 : epoch);
2413 :
2414 0 : if (!NT_STATUS_IS_OK(set_status)) {
2415 0 : DBG_DEBUG("leases_db_set failed: %s\n",
2416 : nt_errstr(set_status));
2417 0 : return set_status;
2418 : }
2419 : }
2420 :
2421 0 : fsp_lease_update(fsp);
2422 :
2423 0 : return NT_STATUS_OK;
2424 : }
2425 :
2426 0 : static NTSTATUS grant_new_fsp_lease(struct files_struct *fsp,
2427 : struct share_mode_lock *lck,
2428 : const struct GUID *client_guid,
2429 : const struct smb2_lease *lease,
2430 : uint32_t granted)
2431 : {
2432 : NTSTATUS status;
2433 :
2434 0 : fsp->lease = talloc_zero(fsp->conn->sconn, struct fsp_lease);
2435 0 : if (fsp->lease == NULL) {
2436 0 : return NT_STATUS_INSUFFICIENT_RESOURCES;
2437 : }
2438 0 : fsp->lease->ref_count = 1;
2439 0 : fsp->lease->sconn = fsp->conn->sconn;
2440 0 : fsp->lease->lease.lease_version = lease->lease_version;
2441 0 : fsp->lease->lease.lease_key = lease->lease_key;
2442 0 : fsp->lease->lease.lease_state = granted;
2443 0 : fsp->lease->lease.lease_epoch = lease->lease_epoch + 1;
2444 :
2445 0 : status = leases_db_add(client_guid,
2446 : &lease->lease_key,
2447 0 : &fsp->file_id,
2448 0 : fsp->lease->lease.lease_state,
2449 0 : fsp->lease->lease.lease_version,
2450 0 : fsp->lease->lease.lease_epoch,
2451 0 : fsp->conn->connectpath,
2452 0 : fsp->fsp_name->base_name,
2453 0 : fsp->fsp_name->stream_name);
2454 0 : if (!NT_STATUS_IS_OK(status)) {
2455 0 : DEBUG(10, ("%s: leases_db_add failed: %s\n", __func__,
2456 : nt_errstr(status)));
2457 0 : TALLOC_FREE(fsp->lease);
2458 0 : return NT_STATUS_INSUFFICIENT_RESOURCES;
2459 : }
2460 :
2461 : /*
2462 : * We used to set lck->data->modified=true here without
2463 : * actually modifying lck->data, triggering a needless
2464 : * writeback of lck->data.
2465 : *
2466 : * Apart from that writeback, setting modified=true has the
2467 : * effect of triggering all waiters for this file to
2468 : * retry. This only makes sense if any blocking condition
2469 : * (i.e. waiting for a lease to be downgraded or removed) is
2470 : * gone. This routine here only adds a lease, so it will never
2471 : * free up resources that blocked waiters can now claim. So
2472 : * that second effect also does not matter in this
2473 : * routine. Thus setting lck->data->modified=true does not
2474 : * need to be done here.
2475 : */
2476 :
2477 0 : return NT_STATUS_OK;
2478 : }
2479 :
2480 0 : static NTSTATUS grant_fsp_lease(struct files_struct *fsp,
2481 : struct share_mode_lock *lck,
2482 : const struct smb2_lease *lease,
2483 : uint32_t granted)
2484 : {
2485 0 : const struct GUID *client_guid = fsp_client_guid(fsp);
2486 : NTSTATUS status;
2487 :
2488 0 : status = try_lease_upgrade(fsp, lck, client_guid, lease, granted);
2489 :
2490 0 : if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) {
2491 0 : status = grant_new_fsp_lease(
2492 : fsp, lck, client_guid, lease, granted);
2493 : }
2494 :
2495 0 : return status;
2496 : }
2497 :
2498 1818 : static int map_lease_type_to_oplock(uint32_t lease_type)
2499 : {
2500 1818 : int result = NO_OPLOCK;
2501 :
2502 1818 : switch (lease_type) {
2503 124 : case SMB2_LEASE_READ|SMB2_LEASE_WRITE|SMB2_LEASE_HANDLE:
2504 124 : result = BATCH_OPLOCK|EXCLUSIVE_OPLOCK;
2505 124 : break;
2506 0 : case SMB2_LEASE_READ|SMB2_LEASE_WRITE:
2507 0 : result = EXCLUSIVE_OPLOCK;
2508 0 : break;
2509 0 : case SMB2_LEASE_READ|SMB2_LEASE_HANDLE:
2510 : case SMB2_LEASE_READ:
2511 0 : result = LEVEL_II_OPLOCK;
2512 0 : break;
2513 : }
2514 :
2515 1818 : return result;
2516 : }
2517 :
2518 : struct delay_for_oplock_state {
2519 : struct files_struct *fsp;
2520 : const struct smb2_lease *lease;
2521 : bool will_overwrite;
2522 : uint32_t delay_mask;
2523 : bool first_open_attempt;
2524 : bool got_handle_lease;
2525 : bool got_oplock;
2526 : bool have_other_lease;
2527 : bool delay;
2528 : };
2529 :
2530 20 : static bool delay_for_oplock_fn(
2531 : struct share_mode_entry *e,
2532 : bool *modified,
2533 : void *private_data)
2534 : {
2535 20 : struct delay_for_oplock_state *state = private_data;
2536 20 : struct files_struct *fsp = state->fsp;
2537 20 : const struct smb2_lease *lease = state->lease;
2538 20 : bool e_is_lease = (e->op_type == LEASE_OPLOCK);
2539 20 : uint32_t e_lease_type = SMB2_LEASE_NONE;
2540 : uint32_t break_to;
2541 20 : bool lease_is_breaking = false;
2542 :
2543 20 : if (e_is_lease) {
2544 : NTSTATUS status;
2545 :
2546 0 : if (lease != NULL) {
2547 0 : bool our_lease = is_same_lease(fsp, e, lease);
2548 0 : if (our_lease) {
2549 0 : DBG_DEBUG("Ignoring our own lease\n");
2550 0 : return false;
2551 : }
2552 : }
2553 :
2554 0 : status = leases_db_get(
2555 0 : &e->client_guid,
2556 0 : &e->lease_key,
2557 0 : &fsp->file_id,
2558 : &e_lease_type, /* current_state */
2559 : &lease_is_breaking,
2560 : NULL, /* breaking_to_requested */
2561 : NULL, /* breaking_to_required */
2562 : NULL, /* lease_version */
2563 : NULL); /* epoch */
2564 :
2565 : /*
2566 : * leases_db_get() can return NT_STATUS_NOT_FOUND
2567 : * if the share_mode_entry e is stale and the
2568 : * lease record was already removed. In this case return
2569 : * false so the traverse continues.
2570 : */
2571 :
2572 0 : if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND) &&
2573 0 : share_entry_stale_pid(e))
2574 : {
2575 : struct GUID_txt_buf guid_strbuf;
2576 : struct file_id_buf file_id_strbuf;
2577 0 : DBG_DEBUG("leases_db_get for client_guid [%s] "
2578 : "lease_key [%"PRIu64"/%"PRIu64"] "
2579 : "file_id [%s] failed for stale "
2580 : "share_mode_entry\n",
2581 : GUID_buf_string(&e->client_guid, &guid_strbuf),
2582 : e->lease_key.data[0],
2583 : e->lease_key.data[1],
2584 : file_id_str_buf(fsp->file_id, &file_id_strbuf));
2585 0 : return false;
2586 : }
2587 0 : if (!NT_STATUS_IS_OK(status)) {
2588 : struct GUID_txt_buf guid_strbuf;
2589 : struct file_id_buf file_id_strbuf;
2590 0 : DBG_ERR("leases_db_get for client_guid [%s] "
2591 : "lease_key [%"PRIu64"/%"PRIu64"] "
2592 : "file_id [%s] failed: %s\n",
2593 : GUID_buf_string(&e->client_guid, &guid_strbuf),
2594 : e->lease_key.data[0],
2595 : e->lease_key.data[1],
2596 : file_id_str_buf(fsp->file_id, &file_id_strbuf),
2597 : nt_errstr(status));
2598 0 : smb_panic("leases_db_get() failed");
2599 : }
2600 : } else {
2601 20 : e_lease_type = get_lease_type(e, fsp->file_id);
2602 : }
2603 :
2604 34 : if (!state->got_handle_lease &&
2605 20 : ((e_lease_type & SMB2_LEASE_HANDLE) != 0) &&
2606 0 : !share_entry_stale_pid(e)) {
2607 0 : state->got_handle_lease = true;
2608 : }
2609 :
2610 34 : if (!state->got_oplock &&
2611 34 : (e->op_type != LEASE_OPLOCK) &&
2612 20 : !share_entry_stale_pid(e)) {
2613 20 : state->got_oplock = true;
2614 : }
2615 :
2616 34 : if (!state->have_other_lease &&
2617 34 : !is_same_lease(fsp, e, lease) &&
2618 20 : !share_entry_stale_pid(e)) {
2619 20 : state->have_other_lease = true;
2620 : }
2621 :
2622 20 : if (e_is_lease && is_lease_stat_open(fsp->access_mask)) {
2623 0 : return false;
2624 : }
2625 :
2626 20 : break_to = e_lease_type & ~state->delay_mask;
2627 :
2628 20 : if (state->will_overwrite) {
2629 1 : break_to &= ~(SMB2_LEASE_HANDLE|SMB2_LEASE_READ);
2630 : }
2631 :
2632 20 : DBG_DEBUG("e_lease_type %u, will_overwrite: %u\n",
2633 : (unsigned)e_lease_type,
2634 : (unsigned)state->will_overwrite);
2635 :
2636 20 : if ((e_lease_type & ~break_to) == 0) {
2637 20 : if (lease_is_breaking) {
2638 0 : state->delay = true;
2639 : }
2640 20 : return false;
2641 : }
2642 :
2643 0 : if (share_entry_stale_pid(e)) {
2644 0 : return false;
2645 : }
2646 :
2647 0 : if (state->will_overwrite) {
2648 : /*
2649 : * If we break anyway break to NONE directly.
2650 : * Otherwise vfs_set_filelen() will trigger the
2651 : * break.
2652 : */
2653 0 : break_to &= ~(SMB2_LEASE_READ|SMB2_LEASE_WRITE);
2654 : }
2655 :
2656 0 : if (!e_is_lease) {
2657 : /*
2658 : * Oplocks only support breaking to R or NONE.
2659 : */
2660 0 : break_to &= ~(SMB2_LEASE_HANDLE|SMB2_LEASE_WRITE);
2661 : }
2662 :
2663 0 : DBG_DEBUG("breaking from %d to %d\n",
2664 : (int)e_lease_type,
2665 : (int)break_to);
2666 0 : send_break_message(
2667 0 : fsp->conn->sconn->msg_ctx, &fsp->file_id, e, break_to);
2668 0 : if (e_lease_type & state->delay_mask) {
2669 0 : state->delay = true;
2670 : }
2671 0 : if (lease_is_breaking && !state->first_open_attempt) {
2672 0 : state->delay = true;
2673 : }
2674 :
2675 0 : return false;
2676 : };
2677 :
2678 1830 : static NTSTATUS delay_for_oplock(files_struct *fsp,
2679 : int oplock_request,
2680 : const struct smb2_lease *lease,
2681 : struct share_mode_lock *lck,
2682 : bool have_sharing_violation,
2683 : uint32_t create_disposition,
2684 : bool first_open_attempt)
2685 : {
2686 1830 : struct delay_for_oplock_state state = {
2687 : .fsp = fsp,
2688 : .lease = lease,
2689 : .first_open_attempt = first_open_attempt,
2690 : };
2691 : uint32_t granted;
2692 : NTSTATUS status;
2693 : bool ok;
2694 :
2695 1830 : if (is_oplock_stat_open(fsp->access_mask)) {
2696 201 : goto grant;
2697 : }
2698 :
2699 1629 : state.delay_mask = have_sharing_violation ?
2700 1629 : SMB2_LEASE_HANDLE : SMB2_LEASE_WRITE;
2701 :
2702 1629 : switch (create_disposition) {
2703 518 : case FILE_SUPERSEDE:
2704 : case FILE_OVERWRITE:
2705 : case FILE_OVERWRITE_IF:
2706 518 : state.will_overwrite = true;
2707 518 : break;
2708 1111 : default:
2709 1111 : state.will_overwrite = false;
2710 1111 : break;
2711 : }
2712 :
2713 1629 : ok = share_mode_forall_entries(lck, delay_for_oplock_fn, &state);
2714 1629 : if (!ok) {
2715 0 : return NT_STATUS_INTERNAL_ERROR;
2716 : }
2717 :
2718 1629 : if (state.delay) {
2719 0 : return NT_STATUS_RETRY;
2720 : }
2721 :
2722 1629 : grant:
2723 1830 : if (have_sharing_violation) {
2724 12 : return NT_STATUS_SHARING_VIOLATION;
2725 : }
2726 :
2727 1818 : if (oplock_request == LEASE_OPLOCK) {
2728 0 : if (lease == NULL) {
2729 : /*
2730 : * The SMB2 layer should have checked this
2731 : */
2732 0 : return NT_STATUS_INTERNAL_ERROR;
2733 : }
2734 :
2735 0 : granted = lease->lease_state;
2736 :
2737 0 : if (lp_kernel_oplocks(SNUM(fsp->conn))) {
2738 0 : DEBUG(10, ("No lease granted because kernel oplocks are enabled\n"));
2739 0 : granted = SMB2_LEASE_NONE;
2740 : }
2741 0 : if ((granted & (SMB2_LEASE_READ|SMB2_LEASE_WRITE)) == 0) {
2742 0 : DEBUG(10, ("No read or write lease requested\n"));
2743 0 : granted = SMB2_LEASE_NONE;
2744 : }
2745 0 : if (granted == SMB2_LEASE_WRITE) {
2746 0 : DEBUG(10, ("pure write lease requested\n"));
2747 0 : granted = SMB2_LEASE_NONE;
2748 : }
2749 0 : if (granted == (SMB2_LEASE_WRITE|SMB2_LEASE_HANDLE)) {
2750 0 : DEBUG(10, ("write and handle lease requested\n"));
2751 0 : granted = SMB2_LEASE_NONE;
2752 : }
2753 : } else {
2754 1818 : granted = map_oplock_to_lease_type(
2755 1818 : oplock_request & ~SAMBA_PRIVATE_OPLOCK_MASK);
2756 : }
2757 :
2758 1818 : if (lp_locking(fsp->conn->params) && file_has_brlocks(fsp)) {
2759 1 : DBG_DEBUG("file %s has byte range locks\n",
2760 : fsp_str_dbg(fsp));
2761 1 : granted &= ~SMB2_LEASE_READ;
2762 : }
2763 :
2764 1818 : if (state.have_other_lease) {
2765 : /*
2766 : * Can grant only one writer
2767 : */
2768 8 : granted &= ~SMB2_LEASE_WRITE;
2769 : }
2770 :
2771 1818 : if ((granted & SMB2_LEASE_READ) && !(granted & SMB2_LEASE_WRITE)) {
2772 0 : bool allow_level2 =
2773 0 : (global_client_caps & CAP_LEVEL_II_OPLOCKS) &&
2774 0 : lp_level2_oplocks(SNUM(fsp->conn));
2775 :
2776 0 : if (!allow_level2) {
2777 0 : granted = SMB2_LEASE_NONE;
2778 : }
2779 : }
2780 :
2781 1818 : if (oplock_request == LEASE_OPLOCK) {
2782 0 : if (state.got_oplock) {
2783 0 : granted &= ~SMB2_LEASE_HANDLE;
2784 : }
2785 :
2786 0 : fsp->oplock_type = LEASE_OPLOCK;
2787 :
2788 0 : status = grant_fsp_lease(fsp, lck, lease, granted);
2789 0 : if (!NT_STATUS_IS_OK(status)) {
2790 0 : return status;
2791 :
2792 : }
2793 :
2794 0 : DBG_DEBUG("lease_state=%d\n", fsp->lease->lease.lease_state);
2795 : } else {
2796 1818 : if (state.got_handle_lease) {
2797 0 : granted = SMB2_LEASE_NONE;
2798 : }
2799 :
2800 1818 : fsp->oplock_type = map_lease_type_to_oplock(granted);
2801 :
2802 1818 : status = set_file_oplock(fsp);
2803 1818 : if (!NT_STATUS_IS_OK(status)) {
2804 : /*
2805 : * Could not get the kernel oplock
2806 : */
2807 0 : fsp->oplock_type = NO_OPLOCK;
2808 : }
2809 : }
2810 :
2811 1818 : if (granted & SMB2_LEASE_READ) {
2812 : uint32_t acc, sh, ls;
2813 124 : share_mode_flags_get(lck, &acc, &sh, &ls);
2814 124 : ls |= SMB2_LEASE_READ;
2815 124 : share_mode_flags_set(lck, acc, sh, ls, NULL);
2816 : }
2817 :
2818 1818 : DBG_DEBUG("oplock type 0x%x on file %s\n",
2819 : fsp->oplock_type, fsp_str_dbg(fsp));
2820 :
2821 1818 : return NT_STATUS_OK;
2822 : }
2823 :
2824 1862 : static NTSTATUS handle_share_mode_lease(
2825 : files_struct *fsp,
2826 : struct share_mode_lock *lck,
2827 : uint32_t create_disposition,
2828 : uint32_t access_mask,
2829 : uint32_t share_access,
2830 : int oplock_request,
2831 : const struct smb2_lease *lease,
2832 : bool first_open_attempt)
2833 : {
2834 1862 : bool sharing_violation = false;
2835 : NTSTATUS status;
2836 :
2837 1862 : status = open_mode_check(
2838 1862 : fsp->conn, fsp->file_id, lck, access_mask, share_access);
2839 1862 : if (NT_STATUS_EQUAL(status, NT_STATUS_SHARING_VIOLATION)) {
2840 12 : sharing_violation = true;
2841 12 : status = NT_STATUS_OK; /* handled later */
2842 : }
2843 :
2844 1862 : if (!NT_STATUS_IS_OK(status)) {
2845 0 : return status;
2846 : }
2847 :
2848 1862 : if (oplock_request == INTERNAL_OPEN_ONLY) {
2849 32 : if (sharing_violation) {
2850 0 : DBG_DEBUG("Sharing violation for internal open\n");
2851 0 : return NT_STATUS_SHARING_VIOLATION;
2852 : }
2853 :
2854 : /*
2855 : * Internal opens never do oplocks or leases. We don't
2856 : * need to go through delay_for_oplock().
2857 : */
2858 32 : fsp->oplock_type = NO_OPLOCK;
2859 :
2860 32 : return NT_STATUS_OK;
2861 : }
2862 :
2863 1830 : status = delay_for_oplock(
2864 : fsp,
2865 : oplock_request,
2866 : lease,
2867 : lck,
2868 : sharing_violation,
2869 : create_disposition,
2870 : first_open_attempt);
2871 1830 : if (!NT_STATUS_IS_OK(status)) {
2872 12 : return status;
2873 : }
2874 :
2875 1818 : return NT_STATUS_OK;
2876 : }
2877 :
2878 0 : static bool request_timed_out(struct smb_request *req, struct timeval timeout)
2879 : {
2880 : struct timeval now, end_time;
2881 0 : GetTimeOfDay(&now);
2882 0 : end_time = timeval_sum(&req->request_time, &timeout);
2883 0 : return (timeval_compare(&end_time, &now) < 0);
2884 : }
2885 :
2886 : struct defer_open_state {
2887 : struct smbXsrv_connection *xconn;
2888 : uint64_t mid;
2889 : };
2890 :
2891 : static void defer_open_done(struct tevent_req *req);
2892 :
2893 : /**
2894 : * Defer an open and watch a locking.tdb record
2895 : *
2896 : * This defers an open that gets rescheduled once the locking.tdb record watch
2897 : * is triggered by a change to the record.
2898 : *
2899 : * It is used to defer opens that triggered an oplock break and for the SMB1
2900 : * sharing violation delay.
2901 : **/
2902 0 : static void defer_open(struct share_mode_lock *lck,
2903 : struct timeval timeout,
2904 : struct smb_request *req,
2905 : struct file_id id)
2906 : {
2907 0 : struct deferred_open_record *open_rec = NULL;
2908 : struct timeval abs_timeout;
2909 : struct defer_open_state *watch_state;
2910 : struct tevent_req *watch_req;
2911 : struct timeval_buf tvbuf1, tvbuf2;
2912 : struct file_id_buf fbuf;
2913 : bool ok;
2914 :
2915 0 : abs_timeout = timeval_sum(&req->request_time, &timeout);
2916 :
2917 0 : DBG_DEBUG("request time [%s] timeout [%s] mid [%" PRIu64 "] "
2918 : "file_id [%s]\n",
2919 : timeval_str_buf(&req->request_time, false, true, &tvbuf1),
2920 : timeval_str_buf(&abs_timeout, false, true, &tvbuf2),
2921 : req->mid,
2922 : file_id_str_buf(id, &fbuf));
2923 :
2924 0 : open_rec = talloc_zero(NULL, struct deferred_open_record);
2925 0 : if (open_rec == NULL) {
2926 0 : TALLOC_FREE(lck);
2927 0 : exit_server("talloc failed");
2928 : }
2929 :
2930 0 : watch_state = talloc(open_rec, struct defer_open_state);
2931 0 : if (watch_state == NULL) {
2932 0 : exit_server("talloc failed");
2933 : }
2934 0 : watch_state->xconn = req->xconn;
2935 0 : watch_state->mid = req->mid;
2936 :
2937 0 : DBG_DEBUG("defering mid %" PRIu64 "\n", req->mid);
2938 :
2939 0 : watch_req = share_mode_watch_send(
2940 : watch_state,
2941 0 : req->sconn->ev_ctx,
2942 : lck,
2943 0 : (struct server_id){0});
2944 0 : if (watch_req == NULL) {
2945 0 : exit_server("Could not watch share mode record");
2946 : }
2947 0 : tevent_req_set_callback(watch_req, defer_open_done, watch_state);
2948 :
2949 0 : ok = tevent_req_set_endtime(watch_req, req->sconn->ev_ctx, abs_timeout);
2950 0 : if (!ok) {
2951 0 : exit_server("tevent_req_set_endtime failed");
2952 : }
2953 :
2954 0 : ok = push_deferred_open_message_smb(req, timeout, id, open_rec);
2955 0 : if (!ok) {
2956 0 : TALLOC_FREE(lck);
2957 0 : exit_server("push_deferred_open_message_smb failed");
2958 : }
2959 0 : }
2960 :
2961 0 : static void defer_open_done(struct tevent_req *req)
2962 : {
2963 0 : struct defer_open_state *state = tevent_req_callback_data(
2964 : req, struct defer_open_state);
2965 : NTSTATUS status;
2966 : bool ret;
2967 :
2968 0 : status = share_mode_watch_recv(req, NULL, NULL);
2969 0 : TALLOC_FREE(req);
2970 0 : if (!NT_STATUS_IS_OK(status)) {
2971 0 : DEBUG(5, ("dbwrap_watched_watch_recv returned %s\n",
2972 : nt_errstr(status)));
2973 : /*
2974 : * Even if it failed, retry anyway. TODO: We need a way to
2975 : * tell a re-scheduled open about that error.
2976 : */
2977 : }
2978 :
2979 0 : DEBUG(10, ("scheduling mid %llu\n", (unsigned long long)state->mid));
2980 :
2981 0 : ret = schedule_deferred_open_message_smb(state->xconn, state->mid);
2982 0 : SMB_ASSERT(ret);
2983 0 : TALLOC_FREE(state);
2984 0 : }
2985 :
2986 : /**
2987 : * Actually attempt the kernel oplock polling open.
2988 : */
2989 :
2990 0 : static void poll_open_fn(struct tevent_context *ev,
2991 : struct tevent_timer *te,
2992 : struct timeval current_time,
2993 : void *private_data)
2994 : {
2995 0 : struct deferred_open_record *open_rec = talloc_get_type_abort(
2996 : private_data, struct deferred_open_record);
2997 : bool ok;
2998 :
2999 0 : TALLOC_FREE(open_rec->watch_req);
3000 :
3001 0 : ok = schedule_deferred_open_message_smb(
3002 : open_rec->xconn, open_rec->mid);
3003 0 : if (!ok) {
3004 0 : exit_server("schedule_deferred_open_message_smb failed");
3005 : }
3006 0 : DBG_DEBUG("timer fired. Retrying open !\n");
3007 0 : }
3008 :
3009 : static void poll_open_done(struct tevent_req *subreq);
3010 :
3011 : /**
3012 : * Reschedule an open for 1 second from now, if not timed out.
3013 : **/
3014 0 : static bool setup_poll_open(
3015 : struct smb_request *req,
3016 : struct share_mode_lock *lck,
3017 : struct file_id id,
3018 : struct timeval max_timeout,
3019 : struct timeval interval)
3020 : {
3021 : bool ok;
3022 0 : struct deferred_open_record *open_rec = NULL;
3023 : struct timeval endtime, next_interval;
3024 : struct file_id_buf ftmp;
3025 :
3026 0 : if (request_timed_out(req, max_timeout)) {
3027 0 : return false;
3028 : }
3029 :
3030 0 : open_rec = talloc_zero(NULL, struct deferred_open_record);
3031 0 : if (open_rec == NULL) {
3032 0 : DBG_WARNING("talloc failed\n");
3033 0 : return false;
3034 : }
3035 0 : open_rec->xconn = req->xconn;
3036 0 : open_rec->mid = req->mid;
3037 :
3038 : /*
3039 : * Make sure open_rec->te does not come later than the
3040 : * request's maximum endtime.
3041 : */
3042 :
3043 0 : endtime = timeval_sum(&req->request_time, &max_timeout);
3044 0 : next_interval = timeval_current_ofs(interval.tv_sec, interval.tv_usec);
3045 0 : next_interval = timeval_min(&endtime, &next_interval);
3046 :
3047 0 : open_rec->te = tevent_add_timer(
3048 : req->sconn->ev_ctx,
3049 : open_rec,
3050 : next_interval,
3051 : poll_open_fn,
3052 : open_rec);
3053 0 : if (open_rec->te == NULL) {
3054 0 : DBG_WARNING("tevent_add_timer failed\n");
3055 0 : TALLOC_FREE(open_rec);
3056 0 : return false;
3057 : }
3058 :
3059 0 : if (lck != NULL) {
3060 0 : open_rec->watch_req = share_mode_watch_send(
3061 : open_rec,
3062 0 : req->sconn->ev_ctx,
3063 : lck,
3064 0 : (struct server_id) {0});
3065 0 : if (open_rec->watch_req == NULL) {
3066 0 : DBG_WARNING("share_mode_watch_send failed\n");
3067 0 : TALLOC_FREE(open_rec);
3068 0 : return false;
3069 : }
3070 0 : tevent_req_set_callback(
3071 : open_rec->watch_req, poll_open_done, open_rec);
3072 : }
3073 :
3074 0 : ok = push_deferred_open_message_smb(req, max_timeout, id, open_rec);
3075 0 : if (!ok) {
3076 0 : DBG_WARNING("push_deferred_open_message_smb failed\n");
3077 0 : TALLOC_FREE(open_rec);
3078 0 : return false;
3079 : }
3080 :
3081 0 : DBG_DEBUG("poll request time [%s] mid [%" PRIu64 "] file_id [%s]\n",
3082 : timeval_string(talloc_tos(), &req->request_time, false),
3083 : req->mid,
3084 : file_id_str_buf(id, &ftmp));
3085 :
3086 0 : return true;
3087 : }
3088 :
3089 0 : static void poll_open_done(struct tevent_req *subreq)
3090 : {
3091 0 : struct deferred_open_record *open_rec = tevent_req_callback_data(
3092 : subreq, struct deferred_open_record);
3093 : NTSTATUS status;
3094 : bool ok;
3095 :
3096 0 : status = share_mode_watch_recv(subreq, NULL, NULL);
3097 0 : TALLOC_FREE(subreq);
3098 0 : open_rec->watch_req = NULL;
3099 0 : TALLOC_FREE(open_rec->te);
3100 :
3101 0 : DBG_DEBUG("dbwrap_watched_watch_recv returned %s\n",
3102 : nt_errstr(status));
3103 :
3104 0 : ok = schedule_deferred_open_message_smb(
3105 : open_rec->xconn, open_rec->mid);
3106 0 : if (!ok) {
3107 0 : exit_server("schedule_deferred_open_message_smb failed");
3108 : }
3109 0 : }
3110 :
3111 0 : bool defer_smb1_sharing_violation(struct smb_request *req)
3112 : {
3113 : bool ok;
3114 : int timeout_usecs;
3115 :
3116 0 : if (!lp_defer_sharing_violations()) {
3117 0 : return false;
3118 : }
3119 :
3120 : /*
3121 : * Try every 200msec up to (by default) one second. To be
3122 : * precise, according to behaviour note <247> in [MS-CIFS],
3123 : * the server tries 5 times. But up to one second should be
3124 : * close enough.
3125 : */
3126 :
3127 0 : timeout_usecs = lp_parm_int(
3128 0 : SNUM(req->conn),
3129 : "smbd",
3130 : "sharedelay",
3131 : SHARING_VIOLATION_USEC_WAIT);
3132 :
3133 0 : ok = setup_poll_open(
3134 : req,
3135 : NULL,
3136 0 : (struct file_id) {0},
3137 0 : (struct timeval) { .tv_usec = timeout_usecs },
3138 0 : (struct timeval) { .tv_usec = 200000 });
3139 0 : return ok;
3140 : }
3141 :
3142 : /****************************************************************************
3143 : On overwrite open ensure that the attributes match.
3144 : ****************************************************************************/
3145 :
3146 69 : static bool open_match_attributes(connection_struct *conn,
3147 : uint32_t old_dos_attr,
3148 : uint32_t new_dos_attr,
3149 : mode_t new_unx_mode,
3150 : mode_t *returned_unx_mode)
3151 : {
3152 : uint32_t noarch_old_dos_attr, noarch_new_dos_attr;
3153 :
3154 69 : noarch_old_dos_attr = (old_dos_attr & ~FILE_ATTRIBUTE_ARCHIVE);
3155 69 : noarch_new_dos_attr = (new_dos_attr & ~FILE_ATTRIBUTE_ARCHIVE);
3156 :
3157 69 : if((noarch_old_dos_attr == 0 && noarch_new_dos_attr != 0) ||
3158 6 : (noarch_old_dos_attr != 0 && ((noarch_old_dos_attr & noarch_new_dos_attr) == noarch_old_dos_attr))) {
3159 0 : *returned_unx_mode = new_unx_mode;
3160 : } else {
3161 69 : *returned_unx_mode = (mode_t)0;
3162 : }
3163 :
3164 69 : DEBUG(10,("open_match_attributes: old_dos_attr = 0x%x, "
3165 : "new_dos_attr = 0x%x "
3166 : "returned_unx_mode = 0%o\n",
3167 : (unsigned int)old_dos_attr,
3168 : (unsigned int)new_dos_attr,
3169 : (unsigned int)*returned_unx_mode ));
3170 :
3171 : /* If we're mapping SYSTEM and HIDDEN ensure they match. */
3172 69 : if (lp_map_system(SNUM(conn)) || lp_store_dos_attributes(SNUM(conn))) {
3173 69 : if ((old_dos_attr & FILE_ATTRIBUTE_SYSTEM) &&
3174 0 : !(new_dos_attr & FILE_ATTRIBUTE_SYSTEM)) {
3175 0 : return False;
3176 : }
3177 : }
3178 69 : if (lp_map_hidden(SNUM(conn)) || lp_store_dos_attributes(SNUM(conn))) {
3179 69 : if ((old_dos_attr & FILE_ATTRIBUTE_HIDDEN) &&
3180 0 : !(new_dos_attr & FILE_ATTRIBUTE_HIDDEN)) {
3181 0 : return False;
3182 : }
3183 : }
3184 69 : return True;
3185 : }
3186 :
3187 0 : static void schedule_defer_open(struct share_mode_lock *lck,
3188 : struct file_id id,
3189 : struct smb_request *req)
3190 : {
3191 : /* This is a relative time, added to the absolute
3192 : request_time value to get the absolute timeout time.
3193 : Note that if this is the second or greater time we enter
3194 : this codepath for this particular request mid then
3195 : request_time is left as the absolute time of the *first*
3196 : time this request mid was processed. This is what allows
3197 : the request to eventually time out. */
3198 :
3199 : struct timeval timeout;
3200 :
3201 : /* Normally the smbd we asked should respond within
3202 : * OPLOCK_BREAK_TIMEOUT seconds regardless of whether
3203 : * the client did, give twice the timeout as a safety
3204 : * measure here in case the other smbd is stuck
3205 : * somewhere else. */
3206 :
3207 0 : timeout = timeval_set(OPLOCK_BREAK_TIMEOUT*2, 0);
3208 :
3209 0 : if (request_timed_out(req, timeout)) {
3210 0 : return;
3211 : }
3212 :
3213 0 : defer_open(lck, timeout, req, id);
3214 : }
3215 :
3216 : /****************************************************************************
3217 : Reschedule an open call that went asynchronous.
3218 : ****************************************************************************/
3219 :
3220 0 : static void schedule_async_open_timer(struct tevent_context *ev,
3221 : struct tevent_timer *te,
3222 : struct timeval current_time,
3223 : void *private_data)
3224 : {
3225 0 : exit_server("async open timeout");
3226 : }
3227 :
3228 0 : static void schedule_async_open(struct smb_request *req)
3229 : {
3230 0 : struct deferred_open_record *open_rec = NULL;
3231 0 : struct timeval timeout = timeval_set(20, 0);
3232 : bool ok;
3233 :
3234 0 : if (request_timed_out(req, timeout)) {
3235 0 : return;
3236 : }
3237 :
3238 0 : open_rec = talloc_zero(NULL, struct deferred_open_record);
3239 0 : if (open_rec == NULL) {
3240 0 : exit_server("deferred_open_record_create failed");
3241 : }
3242 0 : open_rec->async_open = true;
3243 :
3244 0 : ok = push_deferred_open_message_smb(
3245 0 : req, timeout, (struct file_id){0}, open_rec);
3246 0 : if (!ok) {
3247 0 : exit_server("push_deferred_open_message_smb failed");
3248 : }
3249 :
3250 0 : open_rec->te = tevent_add_timer(req->sconn->ev_ctx,
3251 : req,
3252 : timeval_current_ofs(20, 0),
3253 : schedule_async_open_timer,
3254 : open_rec);
3255 0 : if (open_rec->te == NULL) {
3256 0 : exit_server("tevent_add_timer failed");
3257 : }
3258 : }
3259 :
3260 : /****************************************************************************
3261 : Work out what access_mask to use from what the client sent us.
3262 : ****************************************************************************/
3263 :
3264 41 : static NTSTATUS smbd_calculate_maximum_allowed_access_fsp(
3265 : struct files_struct *dirfsp,
3266 : struct files_struct *fsp,
3267 : bool use_privs,
3268 : uint32_t *p_access_mask)
3269 : {
3270 41 : struct security_descriptor *sd = NULL;
3271 41 : uint32_t access_granted = 0;
3272 : NTSTATUS status;
3273 :
3274 : /* Cope with symlinks */
3275 41 : if (fsp == NULL || fsp_get_pathref_fd(fsp) == -1) {
3276 16 : *p_access_mask = FILE_GENERIC_ALL;
3277 16 : return NT_STATUS_OK;
3278 : }
3279 :
3280 : /* Cope with fake/printer fsp's. */
3281 25 : if (fsp->fake_file_handle != NULL || fsp->print_file != NULL) {
3282 0 : *p_access_mask = FILE_GENERIC_ALL;
3283 0 : return NT_STATUS_OK;
3284 : }
3285 :
3286 25 : if (!use_privs && (get_current_uid(fsp->conn) == (uid_t)0)) {
3287 12 : *p_access_mask |= FILE_GENERIC_ALL;
3288 12 : return NT_STATUS_OK;
3289 : }
3290 :
3291 13 : status = SMB_VFS_FGET_NT_ACL(metadata_fsp(fsp),
3292 : (SECINFO_OWNER |
3293 : SECINFO_GROUP |
3294 : SECINFO_DACL),
3295 : talloc_tos(),
3296 : &sd);
3297 :
3298 13 : if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
3299 : /*
3300 : * File did not exist
3301 : */
3302 0 : *p_access_mask = FILE_GENERIC_ALL;
3303 0 : return NT_STATUS_OK;
3304 : }
3305 13 : if (!NT_STATUS_IS_OK(status)) {
3306 0 : DBG_ERR("Could not get acl on file %s: %s\n",
3307 : fsp_str_dbg(fsp),
3308 : nt_errstr(status));
3309 0 : return status;
3310 : }
3311 :
3312 : /*
3313 : * If we can access the path to this file, by
3314 : * default we have FILE_READ_ATTRIBUTES from the
3315 : * containing directory. See the section:
3316 : * "Algorithm to Check Access to an Existing File"
3317 : * in MS-FSA.pdf.
3318 : *
3319 : * se_file_access_check()
3320 : * also takes care of owner WRITE_DAC and READ_CONTROL.
3321 : */
3322 26 : status = se_file_access_check(sd,
3323 13 : get_current_nttok(fsp->conn),
3324 : use_privs,
3325 13 : (*p_access_mask & ~FILE_READ_ATTRIBUTES),
3326 : &access_granted);
3327 :
3328 13 : TALLOC_FREE(sd);
3329 :
3330 13 : if (!NT_STATUS_IS_OK(status)) {
3331 0 : DBG_ERR("Status %s on file %s: "
3332 : "when calculating maximum access\n",
3333 : nt_errstr(status),
3334 : fsp_str_dbg(fsp));
3335 0 : return status;
3336 : }
3337 :
3338 13 : *p_access_mask = (access_granted | FILE_READ_ATTRIBUTES);
3339 :
3340 13 : if (!(access_granted & DELETE_ACCESS)) {
3341 0 : if (can_delete_file_in_directory(fsp->conn,
3342 : dirfsp,
3343 0 : fsp->fsp_name)) {
3344 0 : *p_access_mask |= DELETE_ACCESS;
3345 : }
3346 : }
3347 :
3348 13 : return NT_STATUS_OK;
3349 : }
3350 :
3351 17291 : NTSTATUS smbd_calculate_access_mask_fsp(struct files_struct *dirfsp,
3352 : struct files_struct *fsp,
3353 : bool use_privs,
3354 : uint32_t access_mask,
3355 : uint32_t *access_mask_out)
3356 : {
3357 : NTSTATUS status;
3358 17291 : uint32_t orig_access_mask = access_mask;
3359 : uint32_t rejected_share_access;
3360 :
3361 17291 : if (access_mask & SEC_MASK_INVALID) {
3362 0 : DBG_DEBUG("access_mask [%8x] contains invalid bits\n",
3363 : access_mask);
3364 0 : return NT_STATUS_ACCESS_DENIED;
3365 : }
3366 :
3367 : /*
3368 : * Convert GENERIC bits to specific bits.
3369 : */
3370 :
3371 17291 : se_map_generic(&access_mask, &file_generic_mapping);
3372 :
3373 : /* Calculate MAXIMUM_ALLOWED_ACCESS if requested. */
3374 17291 : if (access_mask & MAXIMUM_ALLOWED_ACCESS) {
3375 :
3376 41 : status = smbd_calculate_maximum_allowed_access_fsp(
3377 : dirfsp,
3378 : fsp,
3379 : use_privs,
3380 : &access_mask);
3381 :
3382 41 : if (!NT_STATUS_IS_OK(status)) {
3383 0 : return status;
3384 : }
3385 :
3386 41 : access_mask &= fsp->conn->share_access;
3387 : }
3388 :
3389 17291 : rejected_share_access = access_mask & ~(fsp->conn->share_access);
3390 :
3391 17291 : if (rejected_share_access) {
3392 0 : DBG_INFO("Access denied on file %s: "
3393 : "rejected by share access mask[0x%08X] "
3394 : "orig[0x%08X] mapped[0x%08X] reject[0x%08X]\n",
3395 : fsp_str_dbg(fsp),
3396 : fsp->conn->share_access,
3397 : orig_access_mask, access_mask,
3398 : rejected_share_access);
3399 0 : return NT_STATUS_ACCESS_DENIED;
3400 : }
3401 :
3402 17291 : *access_mask_out = access_mask;
3403 17291 : return NT_STATUS_OK;
3404 : }
3405 :
3406 : /****************************************************************************
3407 : Remove the deferred open entry under lock.
3408 : ****************************************************************************/
3409 :
3410 : /****************************************************************************
3411 : Return true if this is a state pointer to an asynchronous create.
3412 : ****************************************************************************/
3413 :
3414 0 : bool is_deferred_open_async(const struct deferred_open_record *rec)
3415 : {
3416 0 : return rec->async_open;
3417 : }
3418 :
3419 1245 : static bool clear_ads(uint32_t create_disposition)
3420 : {
3421 1245 : bool ret = false;
3422 :
3423 1245 : switch (create_disposition) {
3424 70 : case FILE_SUPERSEDE:
3425 : case FILE_OVERWRITE_IF:
3426 : case FILE_OVERWRITE:
3427 70 : ret = true;
3428 70 : break;
3429 1175 : default:
3430 1175 : break;
3431 : }
3432 1245 : return ret;
3433 : }
3434 :
3435 6324 : static int disposition_to_open_flags(uint32_t create_disposition)
3436 : {
3437 6324 : int ret = 0;
3438 :
3439 : /*
3440 : * Currently we're using FILE_SUPERSEDE as the same as
3441 : * FILE_OVERWRITE_IF but they really are
3442 : * different. FILE_SUPERSEDE deletes an existing file
3443 : * (requiring delete access) then recreates it.
3444 : */
3445 :
3446 6324 : switch (create_disposition) {
3447 517 : case FILE_SUPERSEDE:
3448 : case FILE_OVERWRITE_IF:
3449 : /*
3450 : * If file exists replace/overwrite. If file doesn't
3451 : * exist create.
3452 : */
3453 517 : ret = O_CREAT|O_TRUNC;
3454 517 : break;
3455 :
3456 5615 : case FILE_OPEN:
3457 : /*
3458 : * If file exists open. If file doesn't exist error.
3459 : */
3460 5615 : ret = 0;
3461 5615 : break;
3462 :
3463 1 : case FILE_OVERWRITE:
3464 : /*
3465 : * If file exists overwrite. If file doesn't exist
3466 : * error.
3467 : */
3468 1 : ret = O_TRUNC;
3469 1 : break;
3470 :
3471 23 : case FILE_CREATE:
3472 : /*
3473 : * If file exists error. If file doesn't exist create.
3474 : */
3475 23 : ret = O_CREAT|O_EXCL;
3476 23 : break;
3477 :
3478 168 : case FILE_OPEN_IF:
3479 : /*
3480 : * If file exists open. If file doesn't exist create.
3481 : */
3482 168 : ret = O_CREAT;
3483 168 : break;
3484 : }
3485 6324 : return ret;
3486 : }
3487 :
3488 6324 : static int calculate_open_access_flags(uint32_t access_mask,
3489 : uint32_t private_flags)
3490 : {
3491 : bool need_write, need_read;
3492 :
3493 : /*
3494 : * Note that we ignore the append flag as append does not
3495 : * mean the same thing under DOS and Unix.
3496 : */
3497 :
3498 6324 : need_write = (access_mask & (FILE_WRITE_DATA | FILE_APPEND_DATA));
3499 6324 : if (!need_write) {
3500 5630 : return O_RDONLY;
3501 : }
3502 :
3503 : /* DENY_DOS opens are always underlying read-write on the
3504 : file handle, no matter what the requested access mask
3505 : says. */
3506 :
3507 694 : need_read =
3508 1388 : ((private_flags & NTCREATEX_FLAG_DENY_DOS) ||
3509 694 : access_mask & (FILE_READ_ATTRIBUTES|FILE_READ_DATA|
3510 : FILE_READ_EA|FILE_EXECUTE));
3511 :
3512 694 : if (!need_read) {
3513 423 : return O_WRONLY;
3514 : }
3515 271 : return O_RDWR;
3516 : }
3517 :
3518 : /****************************************************************************
3519 : Open a file with a share mode. Passed in an already created files_struct *.
3520 : ****************************************************************************/
3521 :
3522 6512 : static NTSTATUS open_file_ntcreate(connection_struct *conn,
3523 : struct smb_request *req,
3524 : uint32_t access_mask, /* access bits (FILE_READ_DATA etc.) */
3525 : uint32_t share_access, /* share constants (FILE_SHARE_READ etc) */
3526 : uint32_t create_disposition, /* FILE_OPEN_IF etc. */
3527 : uint32_t create_options, /* options such as delete on close. */
3528 : uint32_t new_dos_attributes, /* attributes used for new file. */
3529 : int oplock_request, /* internal Samba oplock codes. */
3530 : const struct smb2_lease *lease,
3531 : /* Information (FILE_EXISTS etc.) */
3532 : uint32_t private_flags, /* Samba specific flags. */
3533 : struct smb_filename *parent_dir_fname, /* parent. */
3534 : struct smb_filename *smb_fname_atname, /* atname relative to parent. */
3535 : int *pinfo,
3536 : files_struct *fsp)
3537 : {
3538 6512 : struct smb_filename *smb_fname = fsp->fsp_name;
3539 6512 : int flags=0;
3540 6512 : int flags2=0;
3541 6512 : bool file_existed = VALID_STAT(smb_fname->st);
3542 6512 : bool def_acl = False;
3543 6512 : bool posix_open = False;
3544 6512 : bool new_file_created = False;
3545 6512 : bool first_open_attempt = true;
3546 6512 : NTSTATUS fsp_open = NT_STATUS_ACCESS_DENIED;
3547 6512 : mode_t new_unx_mode = (mode_t)0;
3548 6512 : mode_t unx_mode = (mode_t)0;
3549 : int info;
3550 6512 : uint32_t existing_dos_attributes = 0;
3551 6512 : struct share_mode_lock *lck = NULL;
3552 6512 : uint32_t open_access_mask = access_mask;
3553 6512 : const struct smb2_lease_key *lease_key = NULL;
3554 : NTSTATUS status;
3555 6512 : SMB_STRUCT_STAT saved_stat = smb_fname->st;
3556 : struct timespec old_write_time;
3557 6512 : bool setup_poll = false;
3558 : bool ok;
3559 :
3560 6512 : if (conn->printer) {
3561 : /*
3562 : * Printers are handled completely differently.
3563 : * Most of the passed parameters are ignored.
3564 : */
3565 :
3566 0 : if (pinfo) {
3567 0 : *pinfo = FILE_WAS_CREATED;
3568 : }
3569 :
3570 0 : DEBUG(10, ("open_file_ntcreate: printer open fname=%s\n",
3571 : smb_fname_str_dbg(smb_fname)));
3572 :
3573 0 : if (!req) {
3574 0 : DEBUG(0,("open_file_ntcreate: printer open without "
3575 : "an SMB request!\n"));
3576 0 : return NT_STATUS_INTERNAL_ERROR;
3577 : }
3578 :
3579 0 : return print_spool_open(fsp, smb_fname->base_name,
3580 : req->vuid);
3581 : }
3582 :
3583 6512 : if (new_dos_attributes & FILE_FLAG_POSIX_SEMANTICS) {
3584 0 : posix_open = True;
3585 0 : unx_mode = (mode_t)(new_dos_attributes & ~FILE_FLAG_POSIX_SEMANTICS);
3586 0 : new_dos_attributes = 0;
3587 : } else {
3588 : /* Windows allows a new file to be created and
3589 : silently removes a FILE_ATTRIBUTE_DIRECTORY
3590 : sent by the client. Do the same. */
3591 :
3592 6512 : new_dos_attributes &= ~FILE_ATTRIBUTE_DIRECTORY;
3593 :
3594 : /* We add FILE_ATTRIBUTE_ARCHIVE to this as this mode is only used if the file is
3595 : * created new. */
3596 6512 : unx_mode = unix_mode(
3597 : conn,
3598 : new_dos_attributes | FILE_ATTRIBUTE_ARCHIVE,
3599 : smb_fname,
3600 : parent_dir_fname->fsp);
3601 : }
3602 :
3603 6512 : DEBUG(10, ("open_file_ntcreate: fname=%s, dos_attrs=0x%x "
3604 : "access_mask=0x%x share_access=0x%x "
3605 : "create_disposition = 0x%x create_options=0x%x "
3606 : "unix mode=0%o oplock_request=%d private_flags = 0x%x\n",
3607 : smb_fname_str_dbg(smb_fname), new_dos_attributes,
3608 : access_mask, share_access, create_disposition,
3609 : create_options, (unsigned int)unx_mode, oplock_request,
3610 : (unsigned int)private_flags));
3611 :
3612 6512 : if (req == NULL) {
3613 : /* Ensure req == NULL means INTERNAL_OPEN_ONLY */
3614 80 : SMB_ASSERT(oplock_request == INTERNAL_OPEN_ONLY);
3615 : } else {
3616 : /* And req != NULL means no INTERNAL_OPEN_ONLY */
3617 6432 : SMB_ASSERT(((oplock_request & INTERNAL_OPEN_ONLY) == 0));
3618 : }
3619 :
3620 : /*
3621 : * Only non-internal opens can be deferred at all
3622 : */
3623 :
3624 6512 : if (req) {
3625 : struct deferred_open_record *open_rec;
3626 6432 : if (get_deferred_open_message_state(req, NULL, &open_rec)) {
3627 :
3628 : /* If it was an async create retry, the file
3629 : didn't exist. */
3630 :
3631 0 : if (is_deferred_open_async(open_rec)) {
3632 0 : SET_STAT_INVALID(smb_fname->st);
3633 0 : file_existed = false;
3634 : }
3635 :
3636 : /* Ensure we don't reprocess this message. */
3637 0 : remove_deferred_open_message_smb(req->xconn, req->mid);
3638 :
3639 0 : first_open_attempt = false;
3640 : }
3641 : }
3642 :
3643 6512 : if (!posix_open) {
3644 6512 : new_dos_attributes &= SAMBA_ATTRIBUTES_MASK;
3645 6512 : if (file_existed) {
3646 : /*
3647 : * Only use stored DOS attributes for checks
3648 : * against requested attributes (below via
3649 : * open_match_attributes()), cf bug #11992
3650 : * for details. -slow
3651 : */
3652 5721 : uint32_t attr = 0;
3653 :
3654 5721 : status = vfs_fget_dos_attributes(smb_fname->fsp, &attr);
3655 5721 : if (NT_STATUS_IS_OK(status)) {
3656 1453 : existing_dos_attributes = attr;
3657 : }
3658 : }
3659 : }
3660 :
3661 : /* ignore any oplock requests if oplocks are disabled */
3662 6512 : if (!lp_oplocks(SNUM(conn)) ||
3663 6512 : IS_VETO_OPLOCK_PATH(conn, smb_fname->base_name)) {
3664 : /* Mask off everything except the private Samba bits. */
3665 0 : oplock_request &= SAMBA_PRIVATE_OPLOCK_MASK;
3666 : }
3667 :
3668 : /* this is for OS/2 long file names - say we don't support them */
3669 12498 : if (req != NULL && !req->posix_pathnames &&
3670 6432 : strstr(smb_fname->base_name,".+,;=[].")) {
3671 : /* OS/2 Workplace shell fix may be main code stream in a later
3672 : * release. */
3673 0 : DEBUG(5,("open_file_ntcreate: OS/2 long filenames are not "
3674 : "supported.\n"));
3675 0 : if (use_nt_status()) {
3676 0 : return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3677 : }
3678 0 : return NT_STATUS_DOS(ERRDOS, ERRcannotopen);
3679 : }
3680 :
3681 6512 : switch( create_disposition ) {
3682 5798 : case FILE_OPEN:
3683 : /* If file exists open. If file doesn't exist error. */
3684 5798 : if (!file_existed) {
3685 183 : DEBUG(5,("open_file_ntcreate: FILE_OPEN "
3686 : "requested for file %s and file "
3687 : "doesn't exist.\n",
3688 : smb_fname_str_dbg(smb_fname)));
3689 183 : return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3690 : }
3691 5615 : break;
3692 :
3693 2 : case FILE_OVERWRITE:
3694 : /* If file exists overwrite. If file doesn't exist
3695 : * error. */
3696 2 : if (!file_existed) {
3697 1 : DEBUG(5,("open_file_ntcreate: FILE_OVERWRITE "
3698 : "requested for file %s and file "
3699 : "doesn't exist.\n",
3700 : smb_fname_str_dbg(smb_fname) ));
3701 1 : return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3702 : }
3703 1 : break;
3704 :
3705 25 : case FILE_CREATE:
3706 : /* If file exists error. If file doesn't exist
3707 : * create. */
3708 25 : if (file_existed) {
3709 2 : DEBUG(5,("open_file_ntcreate: FILE_CREATE "
3710 : "requested for file %s and file "
3711 : "already exists.\n",
3712 : smb_fname_str_dbg(smb_fname)));
3713 2 : if (S_ISDIR(smb_fname->st.st_ex_mode)) {
3714 0 : return NT_STATUS_FILE_IS_A_DIRECTORY;
3715 : }
3716 2 : return NT_STATUS_OBJECT_NAME_COLLISION;
3717 : }
3718 23 : break;
3719 :
3720 685 : case FILE_SUPERSEDE:
3721 : case FILE_OVERWRITE_IF:
3722 : case FILE_OPEN_IF:
3723 685 : break;
3724 2 : default:
3725 2 : return NT_STATUS_INVALID_PARAMETER;
3726 : }
3727 :
3728 6324 : flags2 = disposition_to_open_flags(create_disposition);
3729 :
3730 : /* We only care about matching attributes on file exists and
3731 : * overwrite. */
3732 :
3733 6324 : if (!posix_open && file_existed &&
3734 5717 : ((create_disposition == FILE_OVERWRITE) ||
3735 : (create_disposition == FILE_OVERWRITE_IF))) {
3736 69 : if (!open_match_attributes(conn, existing_dos_attributes,
3737 : new_dos_attributes,
3738 : unx_mode, &new_unx_mode)) {
3739 0 : DEBUG(5,("open_file_ntcreate: attributes mismatch "
3740 : "for file %s (%x %x) (0%o, 0%o)\n",
3741 : smb_fname_str_dbg(smb_fname),
3742 : existing_dos_attributes,
3743 : new_dos_attributes,
3744 : (unsigned int)smb_fname->st.st_ex_mode,
3745 : (unsigned int)unx_mode ));
3746 0 : return NT_STATUS_ACCESS_DENIED;
3747 : }
3748 : }
3749 :
3750 6324 : status = smbd_calculate_access_mask_fsp(parent_dir_fname->fsp,
3751 : smb_fname->fsp,
3752 : false,
3753 : access_mask,
3754 : &access_mask);
3755 6324 : if (!NT_STATUS_IS_OK(status)) {
3756 0 : DBG_DEBUG("smbd_calculate_access_mask_fsp "
3757 : "on file %s returned %s\n",
3758 : smb_fname_str_dbg(smb_fname),
3759 : nt_errstr(status));
3760 0 : return status;
3761 : }
3762 :
3763 6324 : open_access_mask = access_mask;
3764 :
3765 6324 : if (flags2 & O_TRUNC) {
3766 518 : open_access_mask |= FILE_WRITE_DATA; /* This will cause oplock breaks. */
3767 : }
3768 :
3769 6324 : if (file_existed) {
3770 : /*
3771 : * stat opens on existing files don't get oplocks.
3772 : * They can get leases.
3773 : *
3774 : * Note that we check for stat open on the *open_access_mask*,
3775 : * i.e. the access mask we actually used to do the open,
3776 : * not the one the client asked for (which is in
3777 : * fsp->access_mask). This is due to the fact that
3778 : * FILE_OVERWRITE and FILE_OVERWRITE_IF add in O_TRUNC,
3779 : * which adds FILE_WRITE_DATA to open_access_mask.
3780 : */
3781 5718 : if (is_oplock_stat_open(open_access_mask) && lease == NULL) {
3782 4186 : oplock_request = NO_OPLOCK;
3783 : }
3784 : }
3785 :
3786 6324 : DEBUG(10, ("open_file_ntcreate: fname=%s, after mapping "
3787 : "access_mask=0x%x\n", smb_fname_str_dbg(smb_fname),
3788 : access_mask));
3789 :
3790 : /*
3791 : * Note that we ignore the append flag as append does not
3792 : * mean the same thing under DOS and Unix.
3793 : */
3794 :
3795 6324 : flags = calculate_open_access_flags(access_mask, private_flags);
3796 :
3797 : /*
3798 : * Currently we only look at FILE_WRITE_THROUGH for create options.
3799 : */
3800 :
3801 : #if defined(O_SYNC)
3802 6324 : if ((create_options & FILE_WRITE_THROUGH) && lp_strict_sync(SNUM(conn))) {
3803 0 : flags2 |= O_SYNC;
3804 : }
3805 : #endif /* O_SYNC */
3806 :
3807 6324 : if (posix_open && (access_mask & FILE_APPEND_DATA)) {
3808 0 : flags2 |= O_APPEND;
3809 : }
3810 :
3811 6324 : if (!posix_open && !CAN_WRITE(conn)) {
3812 : /*
3813 : * We should really return a permission denied error if either
3814 : * O_CREAT or O_TRUNC are set, but for compatibility with
3815 : * older versions of Samba we just AND them out.
3816 : */
3817 0 : flags2 &= ~(O_CREAT|O_TRUNC);
3818 : }
3819 :
3820 : /*
3821 : * With kernel oplocks the open breaking an oplock
3822 : * blocks until the oplock holder has given up the
3823 : * oplock or closed the file. We prevent this by always
3824 : * trying to open the file with O_NONBLOCK (see "man
3825 : * fcntl" on Linux).
3826 : *
3827 : * If a process that doesn't use the smbd open files
3828 : * database or communication methods holds a kernel
3829 : * oplock we must periodically poll for available open
3830 : * using O_NONBLOCK.
3831 : */
3832 6324 : flags2 |= O_NONBLOCK;
3833 :
3834 : /*
3835 : * Ensure we can't write on a read-only share or file.
3836 : */
3837 :
3838 6414 : if (flags != O_RDONLY && file_existed &&
3839 191 : (!CAN_WRITE(conn) || IS_DOS_READONLY(existing_dos_attributes))) {
3840 0 : DEBUG(5,("open_file_ntcreate: write access requested for "
3841 : "file %s on read only %s\n",
3842 : smb_fname_str_dbg(smb_fname),
3843 : !CAN_WRITE(conn) ? "share" : "file" ));
3844 0 : return NT_STATUS_ACCESS_DENIED;
3845 : }
3846 :
3847 6324 : if (VALID_STAT(smb_fname->st)) {
3848 : /*
3849 : * Only try and create a file id before open
3850 : * for an existing file. For a file being created
3851 : * this won't do anything useful until the file
3852 : * exists and has a valid stat struct.
3853 : */
3854 5718 : fsp->file_id = vfs_file_id_from_sbuf(conn, &smb_fname->st);
3855 : }
3856 6324 : fh_set_private_options(fsp->fh, private_flags);
3857 6324 : fsp->access_mask = open_access_mask; /* We change this to the
3858 : * requested access_mask after
3859 : * the open is done. */
3860 6324 : if (posix_open) {
3861 0 : fsp->posix_flags |= FSP_POSIX_FLAGS_ALL;
3862 : }
3863 :
3864 6799 : if ((create_options & FILE_DELETE_ON_CLOSE) &&
3865 622 : (flags2 & O_CREAT) &&
3866 106 : !file_existed) {
3867 : /* Delete on close semantics for new files. */
3868 106 : status = can_set_delete_on_close(fsp,
3869 : new_dos_attributes);
3870 106 : if (!NT_STATUS_IS_OK(status)) {
3871 0 : fd_close(fsp);
3872 0 : return status;
3873 : }
3874 : }
3875 :
3876 : /*
3877 : * Ensure we pay attention to default ACLs on directories if required.
3878 : */
3879 :
3880 7024 : if ((flags2 & O_CREAT) && lp_inherit_acls(SNUM(conn)) &&
3881 700 : (def_acl = directory_has_default_acl_fsp(parent_dir_fname->fsp)))
3882 : {
3883 700 : unx_mode = (0777 & lp_create_mask(SNUM(conn)));
3884 : }
3885 :
3886 6324 : DEBUG(4,("calling open_file with flags=0x%X flags2=0x%X mode=0%o, "
3887 : "access_mask = 0x%x, open_access_mask = 0x%x\n",
3888 : (unsigned int)flags, (unsigned int)flags2,
3889 : (unsigned int)unx_mode, (unsigned int)access_mask,
3890 : (unsigned int)open_access_mask));
3891 :
3892 6324 : fsp_open = open_file(req,
3893 : parent_dir_fname->fsp,
3894 : smb_fname_atname,
3895 : fsp,
3896 : flags|flags2,
3897 : unx_mode,
3898 : access_mask,
3899 : open_access_mask,
3900 : private_flags,
3901 : &new_file_created);
3902 6324 : if (NT_STATUS_EQUAL(fsp_open, NT_STATUS_NETWORK_BUSY)) {
3903 0 : if (file_existed && S_ISFIFO(fsp->fsp_name->st.st_ex_mode)) {
3904 0 : DEBUG(10, ("FIFO busy\n"));
3905 0 : return NT_STATUS_NETWORK_BUSY;
3906 : }
3907 0 : if (req == NULL) {
3908 0 : DEBUG(10, ("Internal open busy\n"));
3909 0 : return NT_STATUS_NETWORK_BUSY;
3910 : }
3911 : /*
3912 : * This handles the kernel oplock case:
3913 : *
3914 : * the file has an active kernel oplock and the open() returned
3915 : * EWOULDBLOCK/EAGAIN which maps to NETWORK_BUSY.
3916 : *
3917 : * "Samba locking.tdb oplocks" are handled below after acquiring
3918 : * the sharemode lock with get_share_mode_lock().
3919 : */
3920 0 : setup_poll = true;
3921 : }
3922 :
3923 6324 : if (NT_STATUS_EQUAL(fsp_open, NT_STATUS_RETRY)) {
3924 : /*
3925 : * EINTR from the open(2) syscall. Just setup a retry
3926 : * in a bit. We can't use the sys_write() tight retry
3927 : * loop here, as we might have to actually deal with
3928 : * lease-break signals to avoid a deadlock.
3929 : */
3930 0 : setup_poll = true;
3931 : }
3932 :
3933 6324 : if (setup_poll) {
3934 : /*
3935 : * From here on we assume this is an oplock break triggered
3936 : */
3937 :
3938 0 : lck = get_existing_share_mode_lock(talloc_tos(), fsp->file_id);
3939 :
3940 0 : if ((lck != NULL) && !validate_oplock_types(lck)) {
3941 0 : smb_panic("validate_oplock_types failed");
3942 : }
3943 :
3944 : /*
3945 : * Retry once a second. If there's a share_mode_lock
3946 : * around, also wait for it in case it was smbd
3947 : * holding that kernel oplock that can quickly tell us
3948 : * the oplock got removed.
3949 : */
3950 :
3951 0 : setup_poll_open(
3952 : req,
3953 : lck,
3954 : fsp->file_id,
3955 : timeval_set(OPLOCK_BREAK_TIMEOUT*2, 0),
3956 : timeval_set(1, 0));
3957 :
3958 0 : TALLOC_FREE(lck);
3959 :
3960 0 : return NT_STATUS_SHARING_VIOLATION;
3961 : }
3962 :
3963 6324 : if (!NT_STATUS_IS_OK(fsp_open)) {
3964 4462 : bool wait_for_aio = NT_STATUS_EQUAL(
3965 : fsp_open, NT_STATUS_MORE_PROCESSING_REQUIRED);
3966 4462 : if (wait_for_aio) {
3967 0 : schedule_async_open(req);
3968 : }
3969 4462 : return fsp_open;
3970 : }
3971 :
3972 1862 : if (new_file_created) {
3973 : /*
3974 : * As we atomically create using O_CREAT|O_EXCL,
3975 : * then if new_file_created is true, then
3976 : * file_existed *MUST* have been false (even
3977 : * if the file was previously detected as being
3978 : * there).
3979 : */
3980 605 : file_existed = false;
3981 : }
3982 :
3983 1862 : if (file_existed && !check_same_dev_ino(&saved_stat, &smb_fname->st)) {
3984 : /*
3985 : * The file did exist, but some other (local or NFS)
3986 : * process either renamed/unlinked and re-created the
3987 : * file with different dev/ino after we walked the path,
3988 : * but before we did the open. We could retry the
3989 : * open but it's a rare enough case it's easier to
3990 : * just fail the open to prevent creating any problems
3991 : * in the open file db having the wrong dev/ino key.
3992 : */
3993 0 : fd_close(fsp);
3994 0 : DBG_WARNING("file %s - dev/ino mismatch. "
3995 : "Old (dev=%ju, ino=%ju). "
3996 : "New (dev=%ju, ino=%ju). Failing open "
3997 : "with NT_STATUS_ACCESS_DENIED.\n",
3998 : smb_fname_str_dbg(smb_fname),
3999 : (uintmax_t)saved_stat.st_ex_dev,
4000 : (uintmax_t)saved_stat.st_ex_ino,
4001 : (uintmax_t)smb_fname->st.st_ex_dev,
4002 : (uintmax_t)smb_fname->st.st_ex_ino);
4003 0 : return NT_STATUS_ACCESS_DENIED;
4004 : }
4005 :
4006 1862 : old_write_time = smb_fname->st.st_ex_mtime;
4007 :
4008 : /*
4009 : * Deal with the race condition where two smbd's detect the
4010 : * file doesn't exist and do the create at the same time. One
4011 : * of them will win and set a share mode, the other (ie. this
4012 : * one) should check if the requested share mode for this
4013 : * create is allowed.
4014 : */
4015 :
4016 : /*
4017 : * Now the file exists and fsp is successfully opened,
4018 : * fsp->dev and fsp->inode are valid and should replace the
4019 : * dev=0,inode=0 from a non existent file. Spotted by
4020 : * Nadav Danieli <nadavd@exanet.com>. JRA.
4021 : */
4022 :
4023 1862 : lck = get_share_mode_lock(talloc_tos(), fsp->file_id,
4024 1862 : conn->connectpath,
4025 : smb_fname, &old_write_time);
4026 :
4027 1862 : if (lck == NULL) {
4028 0 : DEBUG(0, ("open_file_ntcreate: Could not get share "
4029 : "mode lock for %s\n",
4030 : smb_fname_str_dbg(smb_fname)));
4031 0 : fd_close(fsp);
4032 0 : return NT_STATUS_SHARING_VIOLATION;
4033 : }
4034 :
4035 : /* Get the types we need to examine. */
4036 1862 : if (!validate_oplock_types(lck)) {
4037 0 : smb_panic("validate_oplock_types failed");
4038 : }
4039 :
4040 1862 : if (has_delete_on_close(lck, fsp->name_hash)) {
4041 0 : TALLOC_FREE(lck);
4042 0 : fd_close(fsp);
4043 0 : return NT_STATUS_DELETE_PENDING;
4044 : }
4045 :
4046 1862 : status = handle_share_mode_lease(
4047 : fsp,
4048 : lck,
4049 : create_disposition,
4050 : access_mask,
4051 : share_access,
4052 : oplock_request,
4053 : lease,
4054 : first_open_attempt);
4055 :
4056 1862 : if (NT_STATUS_EQUAL(status, NT_STATUS_RETRY)) {
4057 0 : schedule_defer_open(lck, fsp->file_id, req);
4058 0 : TALLOC_FREE(lck);
4059 0 : fd_close(fsp);
4060 0 : return NT_STATUS_SHARING_VIOLATION;
4061 : }
4062 :
4063 1862 : if (!NT_STATUS_IS_OK(status)) {
4064 12 : TALLOC_FREE(lck);
4065 12 : fd_close(fsp);
4066 12 : return status;
4067 : }
4068 :
4069 1850 : if (fsp->oplock_type == LEASE_OPLOCK) {
4070 0 : lease_key = &lease->lease_key;
4071 : }
4072 :
4073 1850 : share_mode_flags_restrict(lck, access_mask, share_access, 0);
4074 :
4075 5260 : ok = set_share_mode(
4076 : lck,
4077 : fsp,
4078 1850 : get_current_uid(fsp->conn),
4079 : req ? req->mid : 0,
4080 1850 : fsp->oplock_type,
4081 : lease_key,
4082 : share_access,
4083 : access_mask);
4084 1850 : if (!ok) {
4085 0 : if (fsp->oplock_type == LEASE_OPLOCK) {
4086 0 : status = remove_lease_if_stale(
4087 : lck,
4088 : fsp_client_guid(fsp),
4089 0 : &fsp->lease->lease.lease_key);
4090 0 : if (!NT_STATUS_IS_OK(status)) {
4091 0 : DBG_WARNING("remove_lease_if_stale "
4092 : "failed: %s\n",
4093 : nt_errstr(status));
4094 : }
4095 : }
4096 0 : TALLOC_FREE(lck);
4097 0 : fd_close(fsp);
4098 0 : return NT_STATUS_NO_MEMORY;
4099 : }
4100 :
4101 : /* Should we atomically (to the client at least) truncate ? */
4102 2913 : if ((!new_file_created) &&
4103 1312 : (flags2 & O_TRUNC) &&
4104 70 : (S_ISREG(fsp->fsp_name->st.st_ex_mode))) {
4105 : int ret;
4106 :
4107 70 : ret = SMB_VFS_FTRUNCATE(fsp, 0);
4108 70 : if (ret != 0) {
4109 0 : status = map_nt_error_from_unix(errno);
4110 0 : del_share_mode(lck, fsp);
4111 0 : TALLOC_FREE(lck);
4112 0 : fd_close(fsp);
4113 0 : return status;
4114 : }
4115 70 : notify_fname(fsp->conn, NOTIFY_ACTION_MODIFIED,
4116 : FILE_NOTIFY_CHANGE_SIZE
4117 : | FILE_NOTIFY_CHANGE_ATTRIBUTES,
4118 70 : fsp->fsp_name->base_name);
4119 : }
4120 :
4121 : /*
4122 : * We have the share entry *locked*.....
4123 : */
4124 :
4125 : /* Delete streams if create_disposition requires it */
4126 3095 : if (!new_file_created &&
4127 1312 : clear_ads(create_disposition) &&
4128 70 : !fsp_is_alternate_stream(fsp)) {
4129 64 : status = delete_all_streams(conn, smb_fname);
4130 64 : if (!NT_STATUS_IS_OK(status)) {
4131 0 : del_share_mode(lck, fsp);
4132 0 : TALLOC_FREE(lck);
4133 0 : fd_close(fsp);
4134 0 : return status;
4135 : }
4136 : }
4137 :
4138 3005 : if (!fsp->fsp_flags.is_pathref &&
4139 2310 : fsp_get_io_fd(fsp) != -1 &&
4140 1155 : lp_kernel_share_modes(SNUM(conn)))
4141 : {
4142 : int ret;
4143 : /*
4144 : * Beware: streams implementing VFS modules may
4145 : * implement streams in a way that fsp will have the
4146 : * basefile open in the fsp fd, so lacking a distinct
4147 : * fd for the stream the file-system sharemode will
4148 : * apply on the basefile which is wrong. The actual
4149 : * check is deferred to the VFS module implementing
4150 : * the file-system sharemode call.
4151 : */
4152 0 : ret = SMB_VFS_FILESYSTEM_SHAREMODE(fsp,
4153 : share_access,
4154 : access_mask);
4155 0 : if (ret == -1){
4156 0 : del_share_mode(lck, fsp);
4157 0 : TALLOC_FREE(lck);
4158 0 : fd_close(fsp);
4159 :
4160 0 : return NT_STATUS_SHARING_VIOLATION;
4161 : }
4162 :
4163 0 : fsp->fsp_flags.kernel_share_modes_taken = true;
4164 : }
4165 :
4166 : /*
4167 : * At this point onwards, we can guarantee that the share entry
4168 : * is locked, whether we created the file or not, and that the
4169 : * deny mode is compatible with all current opens.
4170 : */
4171 :
4172 : /*
4173 : * According to Samba4, SEC_FILE_READ_ATTRIBUTE is always granted,
4174 : * but we don't have to store this - just ignore it on access check.
4175 : */
4176 1850 : if (conn->sconn->using_smb2) {
4177 : /*
4178 : * SMB2 doesn't return it (according to Microsoft tests).
4179 : * Test Case: TestSuite_ScenarioNo009GrantedAccessTestS0
4180 : * File created with access = 0x7 (Read, Write, Delete)
4181 : * Query Info on file returns 0x87 (Read, Write, Delete, Read Attributes)
4182 : */
4183 1850 : fsp->access_mask = access_mask;
4184 : } else {
4185 : /* But SMB1 does. */
4186 0 : fsp->access_mask = access_mask | FILE_READ_ATTRIBUTES;
4187 : }
4188 :
4189 1850 : if (new_file_created) {
4190 605 : info = FILE_WAS_CREATED;
4191 : } else {
4192 1245 : if (flags2 & O_TRUNC) {
4193 70 : info = FILE_WAS_OVERWRITTEN;
4194 : } else {
4195 1175 : info = FILE_WAS_OPENED;
4196 : }
4197 : }
4198 :
4199 1850 : if (pinfo) {
4200 1850 : *pinfo = info;
4201 : }
4202 :
4203 : /* Handle strange delete on close create semantics. */
4204 1850 : if (create_options & FILE_DELETE_ON_CLOSE) {
4205 556 : if (!new_file_created) {
4206 450 : status = can_set_delete_on_close(fsp,
4207 : existing_dos_attributes);
4208 :
4209 450 : if (!NT_STATUS_IS_OK(status)) {
4210 : /* Remember to delete the mode we just added. */
4211 0 : del_share_mode(lck, fsp);
4212 0 : TALLOC_FREE(lck);
4213 0 : fd_close(fsp);
4214 0 : return status;
4215 : }
4216 : }
4217 : /* Note that here we set the *initial* delete on close flag,
4218 : not the regular one. The magic gets handled in close. */
4219 556 : fsp->fsp_flags.initial_delete_on_close = true;
4220 : }
4221 :
4222 1850 : if (info != FILE_WAS_OPENED) {
4223 : /* Overwritten files should be initially set as archive */
4224 1335 : if ((info == FILE_WAS_OVERWRITTEN && lp_map_archive(SNUM(conn))) ||
4225 660 : lp_store_dos_attributes(SNUM(conn))) {
4226 675 : (void)fdos_mode(fsp);
4227 675 : if (!posix_open) {
4228 675 : if (file_set_dosmode(conn, smb_fname,
4229 : new_dos_attributes | FILE_ATTRIBUTE_ARCHIVE,
4230 : parent_dir_fname, true) == 0) {
4231 675 : unx_mode = smb_fname->st.st_ex_mode;
4232 : }
4233 : }
4234 : }
4235 : }
4236 :
4237 : /* Determine sparse flag. */
4238 1850 : if (posix_open) {
4239 : /* POSIX opens are sparse by default. */
4240 0 : fsp->fsp_flags.is_sparse = true;
4241 : } else {
4242 1850 : fsp->fsp_flags.is_sparse =
4243 1850 : (existing_dos_attributes & FILE_ATTRIBUTE_SPARSE);
4244 : }
4245 :
4246 : /*
4247 : * Take care of inherited ACLs on created files - if default ACL not
4248 : * selected.
4249 : */
4250 :
4251 1850 : if (!posix_open && new_file_created && !def_acl) {
4252 6 : if (unx_mode != smb_fname->st.st_ex_mode) {
4253 0 : int ret = SMB_VFS_FCHMOD(fsp, unx_mode);
4254 0 : if (ret == -1) {
4255 0 : DBG_INFO("failed to reset "
4256 : "attributes of file %s to 0%o\n",
4257 : smb_fname_str_dbg(smb_fname),
4258 : (unsigned int)unx_mode);
4259 : }
4260 : }
4261 :
4262 1846 : } else if (new_unx_mode) {
4263 : /*
4264 : * We only get here in the case of:
4265 : *
4266 : * a). Not a POSIX open.
4267 : * b). File already existed.
4268 : * c). File was overwritten.
4269 : * d). Requested DOS attributes didn't match
4270 : * the DOS attributes on the existing file.
4271 : *
4272 : * In that case new_unx_mode has been set
4273 : * equal to the calculated mode (including
4274 : * possible inheritance of the mode from the
4275 : * containing directory).
4276 : *
4277 : * Note this mode was calculated with the
4278 : * DOS attribute FILE_ATTRIBUTE_ARCHIVE added,
4279 : * so the mode change here is suitable for
4280 : * an overwritten file.
4281 : */
4282 :
4283 0 : if (new_unx_mode != smb_fname->st.st_ex_mode) {
4284 0 : int ret = SMB_VFS_FCHMOD(fsp, new_unx_mode);
4285 0 : if (ret == -1) {
4286 0 : DBG_INFO("failed to reset "
4287 : "attributes of file %s to 0%o\n",
4288 : smb_fname_str_dbg(smb_fname),
4289 : (unsigned int)new_unx_mode);
4290 : }
4291 : }
4292 : }
4293 :
4294 : {
4295 : /*
4296 : * Deal with other opens having a modified write time.
4297 : */
4298 1850 : struct timespec write_time = get_share_mode_write_time(lck);
4299 :
4300 1850 : if (!is_omit_timespec(&write_time)) {
4301 1850 : update_stat_ex_mtime(&fsp->fsp_name->st, write_time);
4302 : }
4303 : }
4304 :
4305 1850 : TALLOC_FREE(lck);
4306 :
4307 1850 : return NT_STATUS_OK;
4308 : }
4309 :
4310 750 : static NTSTATUS mkdir_internal(connection_struct *conn,
4311 : struct smb_filename *parent_dir_fname, /* parent. */
4312 : struct smb_filename *smb_fname_atname, /* atname relative to parent. */
4313 : struct smb_filename *smb_dname, /* full pathname from root of share. */
4314 : uint32_t file_attributes,
4315 : struct files_struct *fsp)
4316 : {
4317 694 : const struct loadparm_substitution *lp_sub =
4318 56 : loadparm_s3_global_substitution();
4319 : mode_t mode;
4320 : NTSTATUS status;
4321 750 : bool posix_open = false;
4322 750 : bool need_re_stat = false;
4323 750 : uint32_t access_mask = SEC_DIR_ADD_SUBDIR;
4324 750 : struct vfs_open_how how = { .flags = O_RDONLY|O_DIRECTORY, };
4325 : int ret;
4326 :
4327 750 : if (!CAN_WRITE(conn) || (access_mask & ~(conn->share_access))) {
4328 0 : DEBUG(5,("mkdir_internal: failing share access "
4329 : "%s\n", lp_servicename(talloc_tos(), lp_sub, SNUM(conn))));
4330 0 : return NT_STATUS_ACCESS_DENIED;
4331 : }
4332 :
4333 750 : if (file_attributes & FILE_FLAG_POSIX_SEMANTICS) {
4334 0 : posix_open = true;
4335 0 : mode = (mode_t)(file_attributes & ~FILE_FLAG_POSIX_SEMANTICS);
4336 : } else {
4337 750 : mode = unix_mode(conn,
4338 : FILE_ATTRIBUTE_DIRECTORY,
4339 : smb_dname,
4340 : parent_dir_fname->fsp);
4341 : }
4342 :
4343 750 : status = check_parent_access_fsp(parent_dir_fname->fsp, access_mask);
4344 750 : if(!NT_STATUS_IS_OK(status)) {
4345 0 : DBG_INFO("check_parent_access_fsp "
4346 : "on directory %s for path %s returned %s\n",
4347 : smb_fname_str_dbg(parent_dir_fname),
4348 : smb_dname->base_name,
4349 : nt_errstr(status));
4350 0 : return status;
4351 : }
4352 :
4353 750 : if (lp_inherit_acls(SNUM(conn))) {
4354 746 : if (directory_has_default_acl_fsp(parent_dir_fname->fsp)) {
4355 742 : mode = (0777 & lp_directory_mask(SNUM(conn)));
4356 : }
4357 : }
4358 :
4359 750 : ret = SMB_VFS_MKDIRAT(conn,
4360 : parent_dir_fname->fsp,
4361 : smb_fname_atname,
4362 : mode);
4363 750 : if (ret != 0) {
4364 1 : return map_nt_error_from_unix(errno);
4365 : }
4366 :
4367 : /*
4368 : * Make this a pathref fsp for now. open_directory() will reopen as a
4369 : * full fsp.
4370 : */
4371 749 : fsp->fsp_flags.is_pathref = true;
4372 :
4373 749 : status = fd_openat(parent_dir_fname->fsp, smb_fname_atname, fsp, &how);
4374 749 : if (!NT_STATUS_IS_OK(status)) {
4375 0 : return status;
4376 : }
4377 :
4378 : /* Ensure we're checking for a symlink here.... */
4379 : /* We don't want to get caught by a symlink racer. */
4380 :
4381 749 : status = vfs_stat_fsp(fsp);
4382 749 : if (!NT_STATUS_IS_OK(status)) {
4383 0 : DEBUG(2, ("Could not stat directory '%s' just created: %s\n",
4384 : smb_fname_str_dbg(smb_dname), nt_errstr(status)));
4385 0 : return status;
4386 : }
4387 :
4388 749 : if (!S_ISDIR(smb_dname->st.st_ex_mode)) {
4389 0 : DEBUG(0, ("Directory '%s' just created is not a directory !\n",
4390 : smb_fname_str_dbg(smb_dname)));
4391 0 : return NT_STATUS_NOT_A_DIRECTORY;
4392 : }
4393 :
4394 749 : if (lp_store_dos_attributes(SNUM(conn)) && !posix_open) {
4395 749 : file_set_dosmode(conn,
4396 : smb_dname,
4397 : file_attributes | FILE_ATTRIBUTE_DIRECTORY,
4398 : parent_dir_fname,
4399 : true);
4400 : }
4401 :
4402 749 : if (lp_inherit_permissions(SNUM(conn))) {
4403 0 : inherit_access_posix_acl(conn, parent_dir_fname->fsp,
4404 : smb_dname, mode);
4405 0 : need_re_stat = true;
4406 : }
4407 :
4408 749 : if (!posix_open) {
4409 : /*
4410 : * Check if high bits should have been set,
4411 : * then (if bits are missing): add them.
4412 : * Consider bits automagically set by UNIX, i.e. SGID bit from parent
4413 : * dir.
4414 : */
4415 749 : if ((mode & ~(S_IRWXU|S_IRWXG|S_IRWXO)) &&
4416 0 : (mode & ~smb_dname->st.st_ex_mode)) {
4417 0 : SMB_VFS_FCHMOD(fsp,
4418 : (smb_dname->st.st_ex_mode |
4419 : (mode & ~smb_dname->st.st_ex_mode)));
4420 0 : need_re_stat = true;
4421 : }
4422 : }
4423 :
4424 : /* Change the owner if required. */
4425 749 : if (lp_inherit_owner(SNUM(conn)) != INHERIT_OWNER_NO) {
4426 0 : change_dir_owner_to_parent_fsp(parent_dir_fname->fsp,
4427 : fsp);
4428 0 : need_re_stat = true;
4429 : }
4430 :
4431 749 : if (need_re_stat) {
4432 0 : status = vfs_stat_fsp(fsp);
4433 0 : if (!NT_STATUS_IS_OK(status)) {
4434 0 : DEBUG(2, ("Could not stat directory '%s' just created: %s\n",
4435 : smb_fname_str_dbg(smb_dname), nt_errstr(status)));
4436 0 : return status;
4437 : }
4438 : }
4439 :
4440 749 : notify_fname(conn, NOTIFY_ACTION_ADDED, FILE_NOTIFY_CHANGE_DIR_NAME,
4441 749 : smb_dname->base_name);
4442 :
4443 749 : return NT_STATUS_OK;
4444 : }
4445 :
4446 : /****************************************************************************
4447 : Open a directory from an NT SMB call.
4448 : ****************************************************************************/
4449 :
4450 10908 : static NTSTATUS open_directory(connection_struct *conn,
4451 : struct smb_request *req,
4452 : uint32_t access_mask,
4453 : uint32_t share_access,
4454 : uint32_t create_disposition,
4455 : uint32_t create_options,
4456 : uint32_t file_attributes,
4457 : struct smb_filename *parent_dir_fname,
4458 : struct smb_filename *smb_fname_atname,
4459 : int *pinfo,
4460 : struct files_struct *fsp)
4461 : {
4462 10908 : struct smb_filename *smb_dname = fsp->fsp_name;
4463 10908 : bool dir_existed = VALID_STAT(smb_dname->st);
4464 10908 : struct share_mode_lock *lck = NULL;
4465 : NTSTATUS status;
4466 : struct timespec mtimespec;
4467 10908 : int info = 0;
4468 : bool ok;
4469 : uint32_t need_fd_access;
4470 :
4471 10908 : if (is_ntfs_stream_smb_fname(smb_dname)) {
4472 0 : DEBUG(2, ("open_directory: %s is a stream name!\n",
4473 : smb_fname_str_dbg(smb_dname)));
4474 0 : return NT_STATUS_NOT_A_DIRECTORY;
4475 : }
4476 :
4477 10908 : if (!(file_attributes & FILE_FLAG_POSIX_SEMANTICS)) {
4478 : /* Ensure we have a directory attribute. */
4479 10908 : file_attributes |= FILE_ATTRIBUTE_DIRECTORY;
4480 : }
4481 :
4482 10908 : DBG_INFO("opening directory %s, access_mask = 0x%"PRIx32", "
4483 : "share_access = 0x%"PRIx32" create_options = 0x%"PRIx32", "
4484 : "create_disposition = 0x%"PRIx32", "
4485 : "file_attributes = 0x%"PRIx32"\n",
4486 : smb_fname_str_dbg(smb_dname),
4487 : access_mask,
4488 : share_access,
4489 : create_options,
4490 : create_disposition,
4491 : file_attributes);
4492 :
4493 10908 : status = smbd_calculate_access_mask_fsp(parent_dir_fname->fsp,
4494 : smb_dname->fsp,
4495 : false,
4496 : access_mask,
4497 : &access_mask);
4498 10908 : if (!NT_STATUS_IS_OK(status)) {
4499 0 : DBG_DEBUG("smbd_calculate_access_mask_fsp "
4500 : "on file %s returned %s\n",
4501 : smb_fname_str_dbg(smb_dname),
4502 : nt_errstr(status));
4503 0 : return status;
4504 : }
4505 :
4506 11137 : if ((access_mask & SEC_FLAG_SYSTEM_SECURITY) &&
4507 231 : !security_token_has_privilege(get_current_nttok(conn),
4508 : SEC_PRIV_SECURITY)) {
4509 0 : DEBUG(10, ("open_directory: open on %s "
4510 : "failed - SEC_FLAG_SYSTEM_SECURITY denied.\n",
4511 : smb_fname_str_dbg(smb_dname)));
4512 0 : return NT_STATUS_PRIVILEGE_NOT_HELD;
4513 : }
4514 :
4515 10908 : switch( create_disposition ) {
4516 10096 : case FILE_OPEN:
4517 :
4518 10096 : if (!dir_existed) {
4519 277 : return NT_STATUS_OBJECT_NAME_NOT_FOUND;
4520 : }
4521 :
4522 9819 : info = FILE_WAS_OPENED;
4523 9819 : break;
4524 :
4525 786 : case FILE_CREATE:
4526 :
4527 : /* If directory exists error. If directory doesn't
4528 : * exist create. */
4529 :
4530 786 : if (dir_existed) {
4531 42 : status = NT_STATUS_OBJECT_NAME_COLLISION;
4532 42 : DEBUG(2, ("open_directory: unable to create "
4533 : "%s. Error was %s\n",
4534 : smb_fname_str_dbg(smb_dname),
4535 : nt_errstr(status)));
4536 42 : return status;
4537 : }
4538 :
4539 744 : status = mkdir_internal(conn,
4540 : parent_dir_fname,
4541 : smb_fname_atname,
4542 : smb_dname,
4543 : file_attributes,
4544 : fsp);
4545 :
4546 744 : if (!NT_STATUS_IS_OK(status)) {
4547 0 : DEBUG(2, ("open_directory: unable to create "
4548 : "%s. Error was %s\n",
4549 : smb_fname_str_dbg(smb_dname),
4550 : nt_errstr(status)));
4551 0 : return status;
4552 : }
4553 :
4554 744 : info = FILE_WAS_CREATED;
4555 744 : break;
4556 :
4557 26 : case FILE_OPEN_IF:
4558 : /*
4559 : * If directory exists open. If directory doesn't
4560 : * exist create.
4561 : */
4562 :
4563 26 : if (dir_existed) {
4564 20 : status = NT_STATUS_OK;
4565 20 : info = FILE_WAS_OPENED;
4566 : } else {
4567 6 : status = mkdir_internal(conn,
4568 : parent_dir_fname,
4569 : smb_fname_atname,
4570 : smb_dname,
4571 : file_attributes,
4572 : fsp);
4573 :
4574 6 : if (NT_STATUS_IS_OK(status)) {
4575 5 : info = FILE_WAS_CREATED;
4576 : } else {
4577 : /* Cope with create race. */
4578 1 : if (!NT_STATUS_EQUAL(status,
4579 : NT_STATUS_OBJECT_NAME_COLLISION)) {
4580 0 : DEBUG(2, ("open_directory: unable to create "
4581 : "%s. Error was %s\n",
4582 : smb_fname_str_dbg(smb_dname),
4583 : nt_errstr(status)));
4584 0 : return status;
4585 : }
4586 :
4587 : /*
4588 : * If mkdir_internal() returned
4589 : * NT_STATUS_OBJECT_NAME_COLLISION
4590 : * we still must lstat the path.
4591 : */
4592 :
4593 1 : if (SMB_VFS_LSTAT(conn, smb_dname)
4594 : == -1) {
4595 0 : DEBUG(2, ("Could not stat "
4596 : "directory '%s' just "
4597 : "opened: %s\n",
4598 : smb_fname_str_dbg(
4599 : smb_dname),
4600 : strerror(errno)));
4601 0 : return map_nt_error_from_unix(
4602 0 : errno);
4603 : }
4604 :
4605 1 : info = FILE_WAS_OPENED;
4606 : }
4607 : }
4608 :
4609 26 : break;
4610 :
4611 0 : case FILE_SUPERSEDE:
4612 : case FILE_OVERWRITE:
4613 : case FILE_OVERWRITE_IF:
4614 : default:
4615 0 : DEBUG(5,("open_directory: invalid create_disposition "
4616 : "0x%x for directory %s\n",
4617 : (unsigned int)create_disposition,
4618 : smb_fname_str_dbg(smb_dname)));
4619 0 : return NT_STATUS_INVALID_PARAMETER;
4620 : }
4621 :
4622 10589 : if(!S_ISDIR(smb_dname->st.st_ex_mode)) {
4623 367 : DEBUG(5,("open_directory: %s is not a directory !\n",
4624 : smb_fname_str_dbg(smb_dname)));
4625 367 : return NT_STATUS_NOT_A_DIRECTORY;
4626 : }
4627 :
4628 : /*
4629 : * Setup the files_struct for it.
4630 : */
4631 :
4632 10222 : fsp->file_id = vfs_file_id_from_sbuf(conn, &smb_dname->st);
4633 10222 : fsp->vuid = req ? req->vuid : UID_FIELD_INVALID;
4634 10222 : fsp->file_pid = req ? req->smbpid : 0;
4635 10222 : fsp->fsp_flags.can_lock = false;
4636 10222 : fsp->fsp_flags.can_read = false;
4637 10222 : fsp->fsp_flags.can_write = false;
4638 :
4639 10222 : fh_set_private_options(fsp->fh, 0);
4640 : /*
4641 : * According to Samba4, SEC_FILE_READ_ATTRIBUTE is always granted,
4642 : */
4643 10222 : fsp->access_mask = access_mask | FILE_READ_ATTRIBUTES;
4644 10222 : fsp->print_file = NULL;
4645 10222 : fsp->fsp_flags.modified = false;
4646 10222 : fsp->oplock_type = NO_OPLOCK;
4647 10222 : fsp->sent_oplock_break = NO_BREAK_SENT;
4648 10222 : fsp->fsp_flags.is_directory = true;
4649 10222 : if (file_attributes & FILE_FLAG_POSIX_SEMANTICS) {
4650 0 : fsp->posix_flags |= FSP_POSIX_FLAGS_ALL;
4651 : }
4652 :
4653 : /* Don't store old timestamps for directory
4654 : handles in the internal database. We don't
4655 : update them in there if new objects
4656 : are created in the directory. Currently
4657 : we only update timestamps on file writes.
4658 : See bug #9870.
4659 : */
4660 10222 : mtimespec = make_omit_timespec();
4661 :
4662 : /*
4663 : * Obviously for FILE_LIST_DIRECTORY we need to reopen to get an fd
4664 : * usable for reading a directory. SMB2_FLUSH may be called on
4665 : * directories opened with FILE_ADD_FILE and FILE_ADD_SUBDIRECTORY so
4666 : * for those we need to reopen as well.
4667 : */
4668 10222 : need_fd_access =
4669 : FILE_LIST_DIRECTORY |
4670 : FILE_ADD_FILE |
4671 : FILE_ADD_SUBDIRECTORY;
4672 :
4673 10222 : if (access_mask & need_fd_access) {
4674 4005 : status = reopen_from_fsp(
4675 2244 : fsp->conn->cwd_fsp,
4676 : fsp->fsp_name,
4677 : fsp,
4678 : O_RDONLY | O_DIRECTORY,
4679 : 0,
4680 : NULL);
4681 2244 : if (!NT_STATUS_IS_OK(status)) {
4682 4 : DBG_INFO("Could not open fd for [%s]: %s\n",
4683 : smb_fname_str_dbg(smb_dname),
4684 : nt_errstr(status));
4685 4 : return status;
4686 : }
4687 : }
4688 :
4689 10218 : status = vfs_stat_fsp(fsp);
4690 10218 : if (!NT_STATUS_IS_OK(status)) {
4691 0 : fd_close(fsp);
4692 0 : return status;
4693 : }
4694 :
4695 10218 : if(!S_ISDIR(fsp->fsp_name->st.st_ex_mode)) {
4696 0 : DEBUG(5,("open_directory: %s is not a directory !\n",
4697 : smb_fname_str_dbg(smb_dname)));
4698 0 : fd_close(fsp);
4699 0 : return NT_STATUS_NOT_A_DIRECTORY;
4700 : }
4701 :
4702 : /* Ensure there was no race condition. We need to check
4703 : * dev/inode but not permissions, as these can change
4704 : * legitimately */
4705 10218 : if (!check_same_dev_ino(&smb_dname->st, &fsp->fsp_name->st)) {
4706 0 : DEBUG(5,("open_directory: stat struct differs for "
4707 : "directory %s.\n",
4708 : smb_fname_str_dbg(smb_dname)));
4709 0 : fd_close(fsp);
4710 0 : return NT_STATUS_ACCESS_DENIED;
4711 : }
4712 :
4713 10218 : if (info == FILE_WAS_OPENED) {
4714 9469 : status = smbd_check_access_rights_fsp(parent_dir_fname->fsp,
4715 : fsp,
4716 : false,
4717 : access_mask);
4718 9469 : if (!NT_STATUS_IS_OK(status)) {
4719 0 : DBG_DEBUG("smbd_check_access_rights_fsp on "
4720 : "file %s failed with %s\n",
4721 : fsp_str_dbg(fsp),
4722 : nt_errstr(status));
4723 0 : fd_close(fsp);
4724 0 : return status;
4725 : }
4726 : }
4727 :
4728 10218 : lck = get_share_mode_lock(talloc_tos(), fsp->file_id,
4729 10218 : conn->connectpath, smb_dname,
4730 : &mtimespec);
4731 :
4732 10218 : if (lck == NULL) {
4733 0 : DEBUG(0, ("open_directory: Could not get share mode lock for "
4734 : "%s\n", smb_fname_str_dbg(smb_dname)));
4735 0 : fd_close(fsp);
4736 0 : return NT_STATUS_SHARING_VIOLATION;
4737 : }
4738 :
4739 10218 : if (has_delete_on_close(lck, fsp->name_hash)) {
4740 0 : TALLOC_FREE(lck);
4741 0 : fd_close(fsp);
4742 0 : return NT_STATUS_DELETE_PENDING;
4743 : }
4744 :
4745 10218 : status = open_mode_check(conn, fsp->file_id, lck,
4746 : access_mask, share_access);
4747 :
4748 10218 : if (!NT_STATUS_IS_OK(status)) {
4749 2 : TALLOC_FREE(lck);
4750 2 : fd_close(fsp);
4751 2 : return status;
4752 : }
4753 :
4754 10216 : share_mode_flags_restrict(lck, access_mask, share_access, 0);
4755 :
4756 10216 : ok = set_share_mode(
4757 : lck,
4758 : fsp,
4759 : get_current_uid(conn),
4760 : req ? req->mid : 0,
4761 : NO_OPLOCK,
4762 : NULL,
4763 : share_access,
4764 : fsp->access_mask);
4765 10216 : if (!ok) {
4766 0 : TALLOC_FREE(lck);
4767 0 : fd_close(fsp);
4768 0 : return NT_STATUS_NO_MEMORY;
4769 : }
4770 :
4771 : /* For directories the delete on close bit at open time seems
4772 : always to be honored on close... See test 19 in Samba4 BASE-DELETE. */
4773 10216 : if (create_options & FILE_DELETE_ON_CLOSE) {
4774 12 : status = can_set_delete_on_close(fsp, 0);
4775 12 : if (!NT_STATUS_IS_OK(status) && !NT_STATUS_EQUAL(status, NT_STATUS_DIRECTORY_NOT_EMPTY)) {
4776 0 : del_share_mode(lck, fsp);
4777 0 : TALLOC_FREE(lck);
4778 0 : fd_close(fsp);
4779 0 : return status;
4780 : }
4781 :
4782 12 : if (NT_STATUS_IS_OK(status)) {
4783 : /* Note that here we set the *initial* delete on close flag,
4784 : not the regular one. The magic gets handled in close. */
4785 10 : fsp->fsp_flags.initial_delete_on_close = true;
4786 : }
4787 : }
4788 :
4789 : {
4790 : /*
4791 : * Deal with other opens having a modified write time. Is this
4792 : * possible for directories?
4793 : */
4794 10216 : struct timespec write_time = get_share_mode_write_time(lck);
4795 :
4796 10216 : if (!is_omit_timespec(&write_time)) {
4797 0 : update_stat_ex_mtime(&fsp->fsp_name->st, write_time);
4798 : }
4799 : }
4800 :
4801 10216 : TALLOC_FREE(lck);
4802 :
4803 10216 : if (pinfo) {
4804 10216 : *pinfo = info;
4805 : }
4806 :
4807 10216 : return NT_STATUS_OK;
4808 : }
4809 :
4810 0 : NTSTATUS create_directory(connection_struct *conn,
4811 : struct smb_request *req,
4812 : struct files_struct *dirfsp,
4813 : struct smb_filename *smb_dname)
4814 : {
4815 : NTSTATUS status;
4816 : files_struct *fsp;
4817 :
4818 0 : status = SMB_VFS_CREATE_FILE(
4819 : conn, /* conn */
4820 : req, /* req */
4821 : dirfsp, /* dirfsp */
4822 : smb_dname, /* fname */
4823 : FILE_READ_ATTRIBUTES, /* access_mask */
4824 : FILE_SHARE_NONE, /* share_access */
4825 : FILE_CREATE, /* create_disposition*/
4826 : FILE_DIRECTORY_FILE, /* create_options */
4827 : FILE_ATTRIBUTE_DIRECTORY, /* file_attributes */
4828 : 0, /* oplock_request */
4829 : NULL, /* lease */
4830 : 0, /* allocation_size */
4831 : 0, /* private_flags */
4832 : NULL, /* sd */
4833 : NULL, /* ea_list */
4834 : &fsp, /* result */
4835 : NULL, /* pinfo */
4836 : NULL, NULL); /* create context */
4837 :
4838 0 : if (NT_STATUS_IS_OK(status)) {
4839 0 : close_file_free(req, &fsp, NORMAL_CLOSE);
4840 : }
4841 :
4842 0 : return status;
4843 : }
4844 :
4845 : /****************************************************************************
4846 : Receive notification that one of our open files has been renamed by another
4847 : smbd process.
4848 : ****************************************************************************/
4849 :
4850 0 : void msg_file_was_renamed(struct messaging_context *msg_ctx,
4851 : void *private_data,
4852 : uint32_t msg_type,
4853 : struct server_id src,
4854 : DATA_BLOB *data)
4855 : {
4856 0 : struct file_rename_message *msg = NULL;
4857 : enum ndr_err_code ndr_err;
4858 : files_struct *fsp;
4859 0 : struct smb_filename *smb_fname = NULL;
4860 0 : struct smbd_server_connection *sconn =
4861 0 : talloc_get_type_abort(private_data,
4862 : struct smbd_server_connection);
4863 :
4864 0 : msg = talloc(talloc_tos(), struct file_rename_message);
4865 0 : if (msg == NULL) {
4866 0 : DBG_WARNING("talloc failed\n");
4867 0 : return;
4868 : }
4869 :
4870 0 : ndr_err = ndr_pull_struct_blob_all(
4871 : data,
4872 : msg,
4873 : msg,
4874 : (ndr_pull_flags_fn_t)ndr_pull_file_rename_message);
4875 0 : if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
4876 0 : DBG_DEBUG("ndr_pull_oplock_break_message failed: %s\n",
4877 : ndr_errstr(ndr_err));
4878 0 : goto out;
4879 : }
4880 0 : if (DEBUGLEVEL >= 10) {
4881 : struct server_id_buf buf;
4882 0 : DBG_DEBUG("Got rename message from %s\n",
4883 : server_id_str_buf(src, &buf));
4884 0 : NDR_PRINT_DEBUG(file_rename_message, msg);
4885 : }
4886 :
4887 : /* stream_name must always be NULL if there is no stream. */
4888 0 : if ((msg->stream_name != NULL) && (msg->stream_name[0] == '\0')) {
4889 0 : msg->stream_name = NULL;
4890 : }
4891 :
4892 0 : smb_fname = synthetic_smb_fname(msg,
4893 : msg->base_name,
4894 : msg->stream_name,
4895 : NULL,
4896 : 0,
4897 : 0);
4898 0 : if (smb_fname == NULL) {
4899 0 : DBG_DEBUG("synthetic_smb_fname failed\n");
4900 0 : goto out;
4901 : }
4902 :
4903 0 : fsp = file_find_dif(sconn, msg->id, msg->share_file_id);
4904 0 : if (fsp == NULL) {
4905 0 : DBG_DEBUG("fsp not found\n");
4906 0 : goto out;
4907 : }
4908 :
4909 0 : if (strcmp(fsp->conn->connectpath, msg->servicepath) == 0) {
4910 : SMB_STRUCT_STAT fsp_orig_sbuf;
4911 : NTSTATUS status;
4912 0 : DBG_DEBUG("renaming file %s from %s -> %s\n",
4913 : fsp_fnum_dbg(fsp),
4914 : fsp_str_dbg(fsp),
4915 : smb_fname_str_dbg(smb_fname));
4916 :
4917 : /*
4918 : * The incoming smb_fname here has an
4919 : * invalid stat struct from synthetic_smb_fname()
4920 : * above.
4921 : * Preserve the existing stat from the
4922 : * open fsp after fsp_set_smb_fname()
4923 : * overwrites with the invalid stat.
4924 : *
4925 : * (We could just copy this into
4926 : * smb_fname->st, but keep this code
4927 : * identical to the fix in rename_open_files()
4928 : * for clarity.
4929 : *
4930 : * We will do an fstat before returning
4931 : * any of this metadata to the client anyway.
4932 : */
4933 0 : fsp_orig_sbuf = fsp->fsp_name->st;
4934 0 : status = fsp_set_smb_fname(fsp, smb_fname);
4935 0 : if (!NT_STATUS_IS_OK(status)) {
4936 0 : DBG_DEBUG("fsp_set_smb_fname failed: %s\n",
4937 : nt_errstr(status));
4938 : }
4939 0 : fsp->fsp_name->st = fsp_orig_sbuf;
4940 : } else {
4941 : /* TODO. JRA. */
4942 : /*
4943 : * Now we have the complete path we can work out if
4944 : * this is actually within this share and adjust
4945 : * newname accordingly.
4946 : */
4947 0 : DBG_DEBUG("share mismatch (sharepath %s not sharepath %s) "
4948 : "%s from %s -> %s\n",
4949 : fsp->conn->connectpath,
4950 : msg->servicepath,
4951 : fsp_fnum_dbg(fsp),
4952 : fsp_str_dbg(fsp),
4953 : smb_fname_str_dbg(smb_fname));
4954 : }
4955 0 : out:
4956 0 : TALLOC_FREE(msg);
4957 : }
4958 :
4959 : /*
4960 : * If a main file is opened for delete, all streams need to be checked for
4961 : * !FILE_SHARE_DELETE. Do this by opening with DELETE_ACCESS.
4962 : * If that works, delete them all by setting the delete on close and close.
4963 : */
4964 :
4965 1642 : static NTSTATUS open_streams_for_delete(connection_struct *conn,
4966 : const struct smb_filename *smb_fname)
4967 : {
4968 1642 : struct stream_struct *stream_info = NULL;
4969 1642 : files_struct **streams = NULL;
4970 : int j;
4971 1642 : unsigned int i, num_streams = 0;
4972 1642 : TALLOC_CTX *frame = talloc_stackframe();
4973 1642 : const struct smb_filename *pathref = NULL;
4974 : NTSTATUS status;
4975 :
4976 1642 : if (smb_fname->fsp == NULL) {
4977 315 : struct smb_filename *tmp = NULL;
4978 492 : status = synthetic_pathref(frame,
4979 : conn->cwd_fsp,
4980 315 : smb_fname->base_name,
4981 : NULL,
4982 : NULL,
4983 138 : smb_fname->twrp,
4984 138 : smb_fname->flags,
4985 : &tmp);
4986 315 : if (!NT_STATUS_IS_OK(status)) {
4987 315 : if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_IMPLEMENTED)
4988 315 : || NT_STATUS_EQUAL(status,
4989 : NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
4990 315 : DBG_DEBUG("no streams around\n");
4991 315 : TALLOC_FREE(frame);
4992 315 : return NT_STATUS_OK;
4993 : }
4994 0 : DBG_DEBUG("synthetic_pathref failed: %s\n",
4995 : nt_errstr(status));
4996 0 : goto fail;
4997 : }
4998 0 : pathref = tmp;
4999 : } else {
5000 1327 : pathref = smb_fname;
5001 : }
5002 1327 : status = vfs_fstreaminfo(pathref->fsp, talloc_tos(),
5003 : &num_streams, &stream_info);
5004 :
5005 1327 : if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_IMPLEMENTED)
5006 1327 : || NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
5007 0 : DEBUG(10, ("no streams around\n"));
5008 0 : TALLOC_FREE(frame);
5009 0 : return NT_STATUS_OK;
5010 : }
5011 :
5012 1327 : if (!NT_STATUS_IS_OK(status)) {
5013 0 : DEBUG(10, ("vfs_fstreaminfo failed: %s\n",
5014 : nt_errstr(status)));
5015 0 : goto fail;
5016 : }
5017 :
5018 1327 : DEBUG(10, ("open_streams_for_delete found %d streams\n",
5019 : num_streams));
5020 :
5021 1327 : if (num_streams == 0) {
5022 825 : TALLOC_FREE(frame);
5023 825 : return NT_STATUS_OK;
5024 : }
5025 :
5026 502 : streams = talloc_array(talloc_tos(), files_struct *, num_streams);
5027 502 : if (streams == NULL) {
5028 0 : DEBUG(0, ("talloc failed\n"));
5029 0 : status = NT_STATUS_NO_MEMORY;
5030 0 : goto fail;
5031 : }
5032 :
5033 1012 : for (i=0; i<num_streams; i++) {
5034 : struct smb_filename *smb_fname_cp;
5035 :
5036 510 : if (strequal(stream_info[i].name, "::$DATA")) {
5037 494 : streams[i] = NULL;
5038 494 : continue;
5039 : }
5040 :
5041 24 : smb_fname_cp = synthetic_smb_fname(talloc_tos(),
5042 16 : smb_fname->base_name,
5043 16 : stream_info[i].name,
5044 : NULL,
5045 8 : smb_fname->twrp,
5046 16 : (smb_fname->flags &
5047 : ~SMB_FILENAME_POSIX_PATH));
5048 16 : if (smb_fname_cp == NULL) {
5049 0 : status = NT_STATUS_NO_MEMORY;
5050 0 : goto fail;
5051 : }
5052 :
5053 16 : status = openat_pathref_fsp(conn->cwd_fsp, smb_fname_cp);
5054 16 : if (!NT_STATUS_IS_OK(status)) {
5055 0 : DBG_DEBUG("Unable to open stream [%s]: %s\n",
5056 : smb_fname_str_dbg(smb_fname_cp),
5057 : nt_errstr(status));
5058 0 : TALLOC_FREE(smb_fname_cp);
5059 0 : break;
5060 : }
5061 :
5062 16 : status = SMB_VFS_CREATE_FILE(
5063 : conn, /* conn */
5064 : NULL, /* req */
5065 : NULL, /* dirfsp */
5066 : smb_fname_cp, /* fname */
5067 : DELETE_ACCESS, /* access_mask */
5068 : (FILE_SHARE_READ | /* share_access */
5069 : FILE_SHARE_WRITE | FILE_SHARE_DELETE),
5070 : FILE_OPEN, /* create_disposition*/
5071 : 0, /* create_options */
5072 : FILE_ATTRIBUTE_NORMAL, /* file_attributes */
5073 : 0, /* oplock_request */
5074 : NULL, /* lease */
5075 : 0, /* allocation_size */
5076 : 0, /* private_flags */
5077 : NULL, /* sd */
5078 : NULL, /* ea_list */
5079 : &streams[i], /* result */
5080 : NULL, /* pinfo */
5081 : NULL, NULL); /* create context */
5082 :
5083 16 : if (!NT_STATUS_IS_OK(status)) {
5084 0 : DEBUG(10, ("Could not open stream %s: %s\n",
5085 : smb_fname_str_dbg(smb_fname_cp),
5086 : nt_errstr(status)));
5087 :
5088 0 : TALLOC_FREE(smb_fname_cp);
5089 0 : break;
5090 : }
5091 16 : TALLOC_FREE(smb_fname_cp);
5092 : }
5093 :
5094 : /*
5095 : * don't touch the variable "status" beyond this point :-)
5096 : */
5097 :
5098 1012 : for (j = i-1 ; j >= 0; j--) {
5099 510 : if (streams[j] == NULL) {
5100 494 : continue;
5101 : }
5102 :
5103 16 : DEBUG(10, ("Closing stream # %d, %s\n", j,
5104 : fsp_str_dbg(streams[j])));
5105 16 : close_file_free(NULL, &streams[j], NORMAL_CLOSE);
5106 : }
5107 :
5108 502 : fail:
5109 502 : TALLOC_FREE(frame);
5110 502 : return status;
5111 : }
5112 :
5113 : /*********************************************************************
5114 : Create a default ACL by inheriting from the parent. If no inheritance
5115 : from the parent available, don't set anything. This will leave the actual
5116 : permissions the new file or directory already got from the filesystem
5117 : as the NT ACL when read.
5118 : *********************************************************************/
5119 :
5120 1325 : static NTSTATUS inherit_new_acl(files_struct *dirfsp, files_struct *fsp)
5121 : {
5122 1325 : TALLOC_CTX *frame = talloc_stackframe();
5123 1325 : struct security_descriptor *parent_desc = NULL;
5124 1325 : NTSTATUS status = NT_STATUS_OK;
5125 1325 : struct security_descriptor *psd = NULL;
5126 1325 : const struct dom_sid *owner_sid = NULL;
5127 1325 : const struct dom_sid *group_sid = NULL;
5128 1325 : uint32_t security_info_sent = (SECINFO_OWNER | SECINFO_GROUP | SECINFO_DACL);
5129 1325 : struct security_token *token = fsp->conn->session_info->security_token;
5130 1325 : bool inherit_owner =
5131 1325 : (lp_inherit_owner(SNUM(fsp->conn)) == INHERIT_OWNER_WINDOWS_AND_UNIX);
5132 1325 : bool inheritable_components = false;
5133 1325 : bool try_builtin_administrators = false;
5134 1325 : const struct dom_sid *BA_U_sid = NULL;
5135 1325 : const struct dom_sid *BA_G_sid = NULL;
5136 1325 : bool try_system = false;
5137 1325 : const struct dom_sid *SY_U_sid = NULL;
5138 1325 : const struct dom_sid *SY_G_sid = NULL;
5139 1325 : size_t size = 0;
5140 : bool ok;
5141 :
5142 1325 : status = SMB_VFS_FGET_NT_ACL(dirfsp,
5143 : (SECINFO_OWNER | SECINFO_GROUP | SECINFO_DACL),
5144 : frame,
5145 : &parent_desc);
5146 1325 : if (!NT_STATUS_IS_OK(status)) {
5147 0 : TALLOC_FREE(frame);
5148 0 : return status;
5149 : }
5150 :
5151 1325 : inheritable_components = sd_has_inheritable_components(parent_desc,
5152 1325 : fsp->fsp_flags.is_directory);
5153 :
5154 1325 : if (!inheritable_components && !inherit_owner) {
5155 4 : TALLOC_FREE(frame);
5156 : /* Nothing to inherit and not setting owner. */
5157 4 : return NT_STATUS_OK;
5158 : }
5159 :
5160 : /* Create an inherited descriptor from the parent. */
5161 :
5162 1321 : if (DEBUGLEVEL >= 10) {
5163 0 : DEBUG(10,("inherit_new_acl: parent acl for %s is:\n",
5164 : fsp_str_dbg(fsp) ));
5165 0 : NDR_PRINT_DEBUG(security_descriptor, parent_desc);
5166 : }
5167 :
5168 : /* Inherit from parent descriptor if "inherit owner" set. */
5169 1321 : if (inherit_owner) {
5170 0 : owner_sid = parent_desc->owner_sid;
5171 0 : group_sid = parent_desc->group_sid;
5172 : }
5173 :
5174 1321 : if (owner_sid == NULL) {
5175 1321 : if (security_token_has_builtin_administrators(token)) {
5176 1137 : try_builtin_administrators = true;
5177 184 : } else if (security_token_is_system(token)) {
5178 0 : try_builtin_administrators = true;
5179 0 : try_system = true;
5180 : }
5181 : }
5182 :
5183 2491 : if (group_sid == NULL &&
5184 1321 : token->num_sids == PRIMARY_GROUP_SID_INDEX)
5185 : {
5186 0 : if (security_token_is_system(token)) {
5187 0 : try_builtin_administrators = true;
5188 0 : try_system = true;
5189 : }
5190 : }
5191 :
5192 1321 : if (try_builtin_administrators) {
5193 1137 : struct unixid ids = { .id = 0 };
5194 :
5195 1137 : ok = sids_to_unixids(&global_sid_Builtin_Administrators, 1, &ids);
5196 1137 : if (ok) {
5197 1137 : switch (ids.type) {
5198 990 : case ID_TYPE_BOTH:
5199 990 : BA_U_sid = &global_sid_Builtin_Administrators;
5200 990 : BA_G_sid = &global_sid_Builtin_Administrators;
5201 990 : break;
5202 0 : case ID_TYPE_UID:
5203 0 : BA_U_sid = &global_sid_Builtin_Administrators;
5204 0 : break;
5205 147 : case ID_TYPE_GID:
5206 147 : BA_G_sid = &global_sid_Builtin_Administrators;
5207 147 : break;
5208 0 : default:
5209 0 : break;
5210 : }
5211 0 : }
5212 : }
5213 :
5214 1321 : if (try_system) {
5215 0 : struct unixid ids = { .id = 0 };
5216 :
5217 0 : ok = sids_to_unixids(&global_sid_System, 1, &ids);
5218 0 : if (ok) {
5219 0 : switch (ids.type) {
5220 0 : case ID_TYPE_BOTH:
5221 0 : SY_U_sid = &global_sid_System;
5222 0 : SY_G_sid = &global_sid_System;
5223 0 : break;
5224 0 : case ID_TYPE_UID:
5225 0 : SY_U_sid = &global_sid_System;
5226 0 : break;
5227 0 : case ID_TYPE_GID:
5228 0 : SY_G_sid = &global_sid_System;
5229 0 : break;
5230 0 : default:
5231 0 : break;
5232 : }
5233 0 : }
5234 : }
5235 :
5236 1321 : if (owner_sid == NULL) {
5237 1321 : owner_sid = BA_U_sid;
5238 : }
5239 :
5240 1321 : if (owner_sid == NULL) {
5241 331 : owner_sid = SY_U_sid;
5242 : }
5243 :
5244 1321 : if (group_sid == NULL) {
5245 1321 : group_sid = SY_G_sid;
5246 : }
5247 :
5248 1321 : if (try_system && group_sid == NULL) {
5249 0 : group_sid = BA_G_sid;
5250 : }
5251 :
5252 1321 : if (owner_sid == NULL) {
5253 331 : owner_sid = &token->sids[PRIMARY_USER_SID_INDEX];
5254 : }
5255 1321 : if (group_sid == NULL) {
5256 1321 : if (token->num_sids == PRIMARY_GROUP_SID_INDEX) {
5257 0 : group_sid = &token->sids[PRIMARY_USER_SID_INDEX];
5258 : } else {
5259 1321 : group_sid = &token->sids[PRIMARY_GROUP_SID_INDEX];
5260 : }
5261 : }
5262 :
5263 1321 : status = se_create_child_secdesc(frame,
5264 : &psd,
5265 : &size,
5266 : parent_desc,
5267 : owner_sid,
5268 : group_sid,
5269 1321 : fsp->fsp_flags.is_directory);
5270 1321 : if (!NT_STATUS_IS_OK(status)) {
5271 0 : TALLOC_FREE(frame);
5272 0 : return status;
5273 : }
5274 :
5275 : /* If inheritable_components == false,
5276 : se_create_child_secdesc()
5277 : creates a security descriptor with a NULL dacl
5278 : entry, but with SEC_DESC_DACL_PRESENT. We need
5279 : to remove that flag. */
5280 :
5281 1321 : if (!inheritable_components) {
5282 0 : security_info_sent &= ~SECINFO_DACL;
5283 0 : psd->type &= ~SEC_DESC_DACL_PRESENT;
5284 : }
5285 :
5286 1321 : if (DEBUGLEVEL >= 10) {
5287 0 : DEBUG(10,("inherit_new_acl: child acl for %s is:\n",
5288 : fsp_str_dbg(fsp) ));
5289 0 : NDR_PRINT_DEBUG(security_descriptor, psd);
5290 : }
5291 :
5292 1321 : if (inherit_owner) {
5293 : /* We need to be root to force this. */
5294 0 : become_root();
5295 : }
5296 1321 : status = SMB_VFS_FSET_NT_ACL(metadata_fsp(fsp),
5297 : security_info_sent,
5298 : psd);
5299 1321 : if (inherit_owner) {
5300 0 : unbecome_root();
5301 : }
5302 1321 : TALLOC_FREE(frame);
5303 1321 : return status;
5304 : }
5305 :
5306 : /*
5307 : * If we already have a lease, it must match the new file id. [MS-SMB2]
5308 : * 3.3.5.9.8 speaks about INVALID_PARAMETER if an already used lease key is
5309 : * used for a different file name.
5310 : */
5311 :
5312 : struct lease_match_state {
5313 : /* Input parameters. */
5314 : TALLOC_CTX *mem_ctx;
5315 : const char *servicepath;
5316 : const struct smb_filename *fname;
5317 : bool file_existed;
5318 : struct file_id id;
5319 : /* Return parameters. */
5320 : uint32_t num_file_ids;
5321 : struct file_id *ids;
5322 : NTSTATUS match_status;
5323 : };
5324 :
5325 : /*************************************************************
5326 : File doesn't exist but this lease key+guid is already in use.
5327 :
5328 : This is only allowable in the dynamic share case where the
5329 : service path must be different.
5330 :
5331 : There is a small race condition here in the multi-connection
5332 : case where a client sends two create calls on different connections,
5333 : where the file doesn't exist and one smbd creates the leases_db
5334 : entry first, but this will get fixed by the multichannel cleanup
5335 : when all identical client_guids get handled by a single smbd.
5336 : **************************************************************/
5337 :
5338 0 : static void lease_match_parser_new_file(
5339 : uint32_t num_files,
5340 : const struct leases_db_file *files,
5341 : struct lease_match_state *state)
5342 : {
5343 : uint32_t i;
5344 :
5345 0 : for (i = 0; i < num_files; i++) {
5346 0 : const struct leases_db_file *f = &files[i];
5347 0 : if (strequal(state->servicepath, f->servicepath)) {
5348 0 : state->match_status = NT_STATUS_INVALID_PARAMETER;
5349 0 : return;
5350 : }
5351 : }
5352 :
5353 : /* Dynamic share case. Break leases on all other files. */
5354 0 : state->match_status = leases_db_copy_file_ids(state->mem_ctx,
5355 : num_files,
5356 : files,
5357 : &state->ids);
5358 0 : if (!NT_STATUS_IS_OK(state->match_status)) {
5359 0 : return;
5360 : }
5361 :
5362 0 : state->num_file_ids = num_files;
5363 0 : state->match_status = NT_STATUS_OPLOCK_NOT_GRANTED;
5364 0 : return;
5365 : }
5366 :
5367 0 : static void lease_match_parser(
5368 : uint32_t num_files,
5369 : const struct leases_db_file *files,
5370 : void *private_data)
5371 : {
5372 0 : struct lease_match_state *state =
5373 : (struct lease_match_state *)private_data;
5374 : uint32_t i;
5375 :
5376 0 : if (!state->file_existed) {
5377 : /*
5378 : * Deal with name mismatch or
5379 : * possible dynamic share case separately
5380 : * to make code clearer.
5381 : */
5382 0 : lease_match_parser_new_file(num_files,
5383 : files,
5384 : state);
5385 0 : return;
5386 : }
5387 :
5388 : /* File existed. */
5389 0 : state->match_status = NT_STATUS_OK;
5390 :
5391 0 : for (i = 0; i < num_files; i++) {
5392 0 : const struct leases_db_file *f = &files[i];
5393 :
5394 : /* Everything should be the same. */
5395 0 : if (!file_id_equal(&state->id, &f->id)) {
5396 : /*
5397 : * The client asked for a lease on a
5398 : * file that doesn't match the file_id
5399 : * in the database.
5400 : *
5401 : * Maybe this is a dynamic share, i.e.
5402 : * a share where the servicepath is
5403 : * different for different users (e.g.
5404 : * the [HOMES] share.
5405 : *
5406 : * If the servicepath is different, but the requested
5407 : * file name + stream name is the same then this is
5408 : * a dynamic share, the client is using the same share
5409 : * name and doesn't know that the underlying servicepath
5410 : * is different. It was expecting a lease on the
5411 : * same file. Return NT_STATUS_OPLOCK_NOT_GRANTED
5412 : * to break leases
5413 : *
5414 : * Otherwise the client has messed up, or is
5415 : * testing our error codes, so return
5416 : * NT_STATUS_INVALID_PARAMETER.
5417 : */
5418 0 : if (!strequal(f->servicepath, state->servicepath) &&
5419 0 : strequal(f->base_name, state->fname->base_name) &&
5420 0 : strequal(f->stream_name, state->fname->stream_name))
5421 0 : {
5422 : /*
5423 : * Name is the same but servicepath is
5424 : * different, dynamic share. Break leases.
5425 : */
5426 0 : state->match_status =
5427 : NT_STATUS_OPLOCK_NOT_GRANTED;
5428 : } else {
5429 0 : state->match_status =
5430 : NT_STATUS_INVALID_PARAMETER;
5431 : }
5432 0 : break;
5433 : }
5434 0 : if (!strequal(f->servicepath, state->servicepath)) {
5435 0 : state->match_status = NT_STATUS_INVALID_PARAMETER;
5436 0 : break;
5437 : }
5438 0 : if (!strequal(f->base_name, state->fname->base_name)) {
5439 0 : state->match_status = NT_STATUS_INVALID_PARAMETER;
5440 0 : break;
5441 : }
5442 0 : if (!strequal(f->stream_name, state->fname->stream_name)) {
5443 0 : state->match_status = NT_STATUS_INVALID_PARAMETER;
5444 0 : break;
5445 : }
5446 : }
5447 :
5448 0 : if (NT_STATUS_IS_OK(state->match_status)) {
5449 : /*
5450 : * Common case - just opening another handle on a
5451 : * file on a non-dynamic share.
5452 : */
5453 0 : return;
5454 : }
5455 :
5456 0 : if (NT_STATUS_EQUAL(state->match_status, NT_STATUS_INVALID_PARAMETER)) {
5457 : /* Mismatched path. Error back to client. */
5458 0 : return;
5459 : }
5460 :
5461 : /*
5462 : * File id mismatch. Dynamic share case NT_STATUS_OPLOCK_NOT_GRANTED.
5463 : * Don't allow leases.
5464 : */
5465 :
5466 0 : state->match_status = leases_db_copy_file_ids(state->mem_ctx,
5467 : num_files,
5468 : files,
5469 : &state->ids);
5470 0 : if (!NT_STATUS_IS_OK(state->match_status)) {
5471 0 : return;
5472 : }
5473 :
5474 0 : state->num_file_ids = num_files;
5475 0 : state->match_status = NT_STATUS_OPLOCK_NOT_GRANTED;
5476 0 : return;
5477 : }
5478 :
5479 : struct lease_match_break_state {
5480 : struct messaging_context *msg_ctx;
5481 : const struct smb2_lease_key *lease_key;
5482 : struct file_id id;
5483 :
5484 : bool found_lease;
5485 : uint16_t version;
5486 : uint16_t epoch;
5487 : };
5488 :
5489 0 : static bool lease_match_break_fn(
5490 : struct share_mode_entry *e,
5491 : void *private_data)
5492 : {
5493 0 : struct lease_match_break_state *state = private_data;
5494 : bool stale, equal;
5495 0 : uint32_t e_lease_type = SMB2_LEASE_NONE;
5496 : NTSTATUS status;
5497 :
5498 0 : stale = share_entry_stale_pid(e);
5499 0 : if (stale) {
5500 0 : return false;
5501 : }
5502 :
5503 0 : equal = smb2_lease_key_equal(&e->lease_key, state->lease_key);
5504 0 : if (!equal) {
5505 0 : return false;
5506 : }
5507 :
5508 0 : status = leases_db_get(
5509 0 : &e->client_guid,
5510 0 : &e->lease_key,
5511 0 : &state->id,
5512 : &e_lease_type, /* current_state */
5513 : NULL, /* breaking */
5514 : NULL, /* breaking_to_requested */
5515 : NULL, /* breaking_to_required */
5516 : &state->version, /* lease_version */
5517 : &state->epoch); /* epoch */
5518 0 : if (NT_STATUS_IS_OK(status)) {
5519 0 : state->found_lease = true;
5520 : } else {
5521 0 : DBG_WARNING("Could not find version/epoch: %s\n",
5522 : nt_errstr(status));
5523 0 : return false;
5524 : }
5525 :
5526 0 : if (e_lease_type == SMB2_LEASE_NONE) {
5527 0 : return false;
5528 : }
5529 0 : send_break_message(state->msg_ctx, &state->id, e, SMB2_LEASE_NONE);
5530 :
5531 : /*
5532 : * Windows 7 and 8 lease clients are broken in that they will
5533 : * not respond to lease break requests whilst waiting for an
5534 : * outstanding open request on that lease handle on the same
5535 : * TCP connection, due to holding an internal inode lock.
5536 : *
5537 : * This means we can't reschedule ourselves here, but must
5538 : * return from the create.
5539 : *
5540 : * Work around:
5541 : *
5542 : * Send the breaks and then return SMB2_LEASE_NONE in the
5543 : * lease handle to cause them to acknowledge the lease
5544 : * break. Consultation with Microsoft engineering confirmed
5545 : * this approach is safe.
5546 : */
5547 :
5548 0 : return false;
5549 : }
5550 :
5551 0 : static NTSTATUS lease_match(connection_struct *conn,
5552 : struct smb_request *req,
5553 : const struct smb2_lease_key *lease_key,
5554 : const char *servicepath,
5555 : const struct smb_filename *fname,
5556 : uint16_t *p_version,
5557 : uint16_t *p_epoch)
5558 : {
5559 0 : struct smbd_server_connection *sconn = req->sconn;
5560 0 : TALLOC_CTX *tos = talloc_tos();
5561 0 : struct lease_match_state state = {
5562 : .mem_ctx = tos,
5563 : .servicepath = servicepath,
5564 : .fname = fname,
5565 : .match_status = NT_STATUS_OK
5566 : };
5567 : uint32_t i;
5568 : NTSTATUS status;
5569 :
5570 0 : state.file_existed = VALID_STAT(fname->st);
5571 0 : if (state.file_existed) {
5572 0 : state.id = vfs_file_id_from_sbuf(conn, &fname->st);
5573 : }
5574 :
5575 0 : status = leases_db_parse(&sconn->client->global->client_guid,
5576 : lease_key, lease_match_parser, &state);
5577 0 : if (!NT_STATUS_IS_OK(status)) {
5578 : /*
5579 : * Not found or error means okay: We can make the lease pass
5580 : */
5581 0 : return NT_STATUS_OK;
5582 : }
5583 0 : if (!NT_STATUS_EQUAL(state.match_status, NT_STATUS_OPLOCK_NOT_GRANTED)) {
5584 : /*
5585 : * Anything but NT_STATUS_OPLOCK_NOT_GRANTED, let the caller
5586 : * deal with it.
5587 : */
5588 0 : return state.match_status;
5589 : }
5590 :
5591 : /* We have to break all existing leases. */
5592 0 : for (i = 0; i < state.num_file_ids; i++) {
5593 0 : struct lease_match_break_state break_state = {
5594 0 : .msg_ctx = conn->sconn->msg_ctx,
5595 : .lease_key = lease_key,
5596 : };
5597 : struct share_mode_lock *lck;
5598 : bool ok;
5599 :
5600 0 : if (file_id_equal(&state.ids[i], &state.id)) {
5601 : /* Don't need to break our own file. */
5602 0 : continue;
5603 : }
5604 :
5605 0 : break_state.id = state.ids[i];
5606 :
5607 0 : lck = get_existing_share_mode_lock(
5608 : talloc_tos(), break_state.id);
5609 0 : if (lck == NULL) {
5610 : /* Race condition - file already closed. */
5611 0 : continue;
5612 : }
5613 :
5614 0 : ok = share_mode_forall_leases(
5615 : lck, lease_match_break_fn, &break_state);
5616 0 : if (!ok) {
5617 0 : DBG_DEBUG("share_mode_forall_leases failed\n");
5618 0 : continue;
5619 : }
5620 :
5621 0 : TALLOC_FREE(lck);
5622 :
5623 0 : if (break_state.found_lease) {
5624 0 : *p_version = break_state.version;
5625 0 : *p_epoch = break_state.epoch;
5626 : }
5627 : }
5628 : /*
5629 : * Ensure we don't grant anything more so we
5630 : * never upgrade.
5631 : */
5632 0 : return NT_STATUS_OPLOCK_NOT_GRANTED;
5633 : }
5634 :
5635 : /*
5636 : * Wrapper around open_file_ntcreate and open_directory
5637 : */
5638 :
5639 12977 : static NTSTATUS create_file_unixpath(connection_struct *conn,
5640 : struct smb_request *req,
5641 : struct files_struct *dirfsp,
5642 : struct smb_filename *smb_fname,
5643 : uint32_t access_mask,
5644 : uint32_t share_access,
5645 : uint32_t create_disposition,
5646 : uint32_t create_options,
5647 : uint32_t file_attributes,
5648 : uint32_t oplock_request,
5649 : const struct smb2_lease *lease,
5650 : uint64_t allocation_size,
5651 : uint32_t private_flags,
5652 : struct security_descriptor *sd,
5653 : struct ea_list *ea_list,
5654 :
5655 : files_struct **result,
5656 : int *pinfo)
5657 : {
5658 : struct smb2_lease none_lease;
5659 12977 : int info = FILE_WAS_OPENED;
5660 12977 : files_struct *base_fsp = NULL;
5661 12977 : files_struct *fsp = NULL;
5662 12977 : bool free_fsp_on_error = false;
5663 : NTSTATUS status;
5664 : int ret;
5665 12977 : struct smb_filename *parent_dir_fname = NULL;
5666 12977 : struct smb_filename *smb_fname_atname = NULL;
5667 :
5668 12977 : DBG_DEBUG("access_mask = 0x%"PRIx32" "
5669 : "file_attributes = 0x%"PRIx32" "
5670 : "share_access = 0x%"PRIx32" "
5671 : "create_disposition = 0x%"PRIx32" "
5672 : "create_options = 0x%"PRIx32" "
5673 : "oplock_request = 0x%"PRIx32" "
5674 : "private_flags = 0x%"PRIx32" "
5675 : "ea_list = %p, "
5676 : "sd = %p, "
5677 : "fname = %s\n",
5678 : access_mask,
5679 : file_attributes,
5680 : share_access,
5681 : create_disposition,
5682 : create_options,
5683 : oplock_request,
5684 : private_flags,
5685 : ea_list,
5686 : sd,
5687 : smb_fname_str_dbg(smb_fname));
5688 :
5689 12977 : if (create_options & FILE_OPEN_BY_FILE_ID) {
5690 0 : status = NT_STATUS_NOT_SUPPORTED;
5691 0 : goto fail;
5692 : }
5693 :
5694 12977 : if (create_options & NTCREATEX_OPTIONS_INVALID_PARAM_MASK) {
5695 1 : status = NT_STATUS_INVALID_PARAMETER;
5696 1 : goto fail;
5697 : }
5698 :
5699 12976 : if (req == NULL) {
5700 80 : oplock_request |= INTERNAL_OPEN_ONLY;
5701 : }
5702 :
5703 12976 : if (lease != NULL) {
5704 0 : uint16_t epoch = lease->lease_epoch;
5705 0 : uint16_t version = lease->lease_version;
5706 :
5707 0 : if (req == NULL) {
5708 0 : DBG_WARNING("Got lease on internal open\n");
5709 0 : status = NT_STATUS_INTERNAL_ERROR;
5710 0 : goto fail;
5711 : }
5712 :
5713 0 : status = lease_match(conn,
5714 : req,
5715 : &lease->lease_key,
5716 0 : conn->connectpath,
5717 : smb_fname,
5718 : &version,
5719 : &epoch);
5720 0 : if (NT_STATUS_EQUAL(status, NT_STATUS_OPLOCK_NOT_GRANTED)) {
5721 : /* Dynamic share file. No leases and update epoch... */
5722 0 : none_lease = *lease;
5723 0 : none_lease.lease_state = SMB2_LEASE_NONE;
5724 0 : none_lease.lease_epoch = epoch;
5725 0 : none_lease.lease_version = version;
5726 0 : lease = &none_lease;
5727 0 : } else if (!NT_STATUS_IS_OK(status)) {
5728 0 : goto fail;
5729 : }
5730 : }
5731 :
5732 12976 : if ((conn->fs_capabilities & FILE_NAMED_STREAMS)
5733 12976 : && (access_mask & DELETE_ACCESS)
5734 1658 : && !is_named_stream(smb_fname)) {
5735 : /*
5736 : * We can't open a file with DELETE access if any of the
5737 : * streams is open without FILE_SHARE_DELETE
5738 : */
5739 1642 : status = open_streams_for_delete(conn, smb_fname);
5740 :
5741 1642 : if (!NT_STATUS_IS_OK(status)) {
5742 0 : goto fail;
5743 : }
5744 : }
5745 :
5746 12976 : if (access_mask & SEC_FLAG_SYSTEM_SECURITY) {
5747 : bool ok;
5748 :
5749 298 : ok = security_token_has_privilege(get_current_nttok(conn),
5750 : SEC_PRIV_SECURITY);
5751 298 : if (!ok) {
5752 0 : DBG_DEBUG("open on %s failed - "
5753 : "SEC_FLAG_SYSTEM_SECURITY denied.\n",
5754 : smb_fname_str_dbg(smb_fname));
5755 0 : status = NT_STATUS_PRIVILEGE_NOT_HELD;
5756 0 : goto fail;
5757 : }
5758 :
5759 298 : if (conn->sconn->using_smb2 &&
5760 : (access_mask == SEC_FLAG_SYSTEM_SECURITY))
5761 : {
5762 : /*
5763 : * No other bits set. Windows SMB2 refuses this.
5764 : * See smbtorture3 SMB2-SACL test.
5765 : *
5766 : * Note this is an SMB2-only behavior,
5767 : * smbtorture3 SMB1-SYSTEM-SECURITY already tests
5768 : * that SMB1 allows this.
5769 : */
5770 0 : status = NT_STATUS_ACCESS_DENIED;
5771 0 : goto fail;
5772 : }
5773 : }
5774 :
5775 : /*
5776 : * Files or directories can't be opened DELETE_ON_CLOSE without
5777 : * delete access.
5778 : * BUG: https://bugzilla.samba.org/show_bug.cgi?id=13358
5779 : */
5780 12976 : if (create_options & FILE_DELETE_ON_CLOSE) {
5781 742 : if ((access_mask & DELETE_ACCESS) == 0) {
5782 0 : status = NT_STATUS_INVALID_PARAMETER;
5783 0 : goto fail;
5784 : }
5785 : }
5786 :
5787 12976 : if ((conn->fs_capabilities & FILE_NAMED_STREAMS)
5788 12976 : && is_named_stream(smb_fname))
5789 : {
5790 : uint32_t base_create_disposition;
5791 64 : struct smb_filename *smb_fname_base = NULL;
5792 : uint32_t base_privflags;
5793 :
5794 64 : if (create_options & FILE_DIRECTORY_FILE) {
5795 0 : DBG_DEBUG("Can't open a stream as directory\n");
5796 0 : status = NT_STATUS_NOT_A_DIRECTORY;
5797 0 : goto fail;
5798 : }
5799 :
5800 64 : switch (create_disposition) {
5801 40 : case FILE_OPEN:
5802 40 : base_create_disposition = FILE_OPEN;
5803 40 : break;
5804 24 : default:
5805 24 : base_create_disposition = FILE_OPEN_IF;
5806 24 : break;
5807 : }
5808 :
5809 64 : smb_fname_base = cp_smb_filename_nostream(
5810 : talloc_tos(), smb_fname);
5811 :
5812 64 : if (smb_fname_base == NULL) {
5813 0 : status = NT_STATUS_NO_MEMORY;
5814 0 : goto fail;
5815 : }
5816 :
5817 : /*
5818 : * We may be creating the basefile as part of creating the
5819 : * stream, so it's legal if the basefile doesn't exist at this
5820 : * point, the create_file_unixpath() below will create it. But
5821 : * if the basefile exists we want a handle so we can fstat() it.
5822 : */
5823 :
5824 64 : ret = vfs_stat(conn, smb_fname_base);
5825 64 : if (ret == -1 && errno != ENOENT) {
5826 0 : status = map_nt_error_from_unix(errno);
5827 0 : TALLOC_FREE(smb_fname_base);
5828 0 : goto fail;
5829 : }
5830 64 : if (ret == 0) {
5831 56 : status = openat_pathref_fsp(conn->cwd_fsp,
5832 : smb_fname_base);
5833 56 : if (!NT_STATUS_IS_OK(status)) {
5834 0 : DBG_ERR("open_smb_fname_fsp [%s] failed: %s\n",
5835 : smb_fname_str_dbg(smb_fname_base),
5836 : nt_errstr(status));
5837 0 : TALLOC_FREE(smb_fname_base);
5838 0 : goto fail;
5839 : }
5840 :
5841 : /*
5842 : * https://bugzilla.samba.org/show_bug.cgi?id=10229
5843 : * We need to check if the requested access mask
5844 : * could be used to open the underlying file (if
5845 : * it existed), as we're passing in zero for the
5846 : * access mask to the base filename.
5847 : */
5848 56 : status = check_base_file_access(smb_fname_base->fsp,
5849 : access_mask);
5850 :
5851 56 : if (!NT_STATUS_IS_OK(status)) {
5852 0 : DEBUG(10, ("Permission check "
5853 : "for base %s failed: "
5854 : "%s\n", smb_fname->base_name,
5855 : nt_errstr(status)));
5856 0 : TALLOC_FREE(smb_fname_base);
5857 0 : goto fail;
5858 : }
5859 : }
5860 :
5861 64 : base_privflags = NTCREATEX_FLAG_STREAM_BASEOPEN;
5862 :
5863 : /* Open the base file. */
5864 64 : status = create_file_unixpath(conn,
5865 : NULL,
5866 : dirfsp,
5867 : smb_fname_base,
5868 : 0,
5869 : FILE_SHARE_READ
5870 : | FILE_SHARE_WRITE
5871 : | FILE_SHARE_DELETE,
5872 : base_create_disposition,
5873 : 0,
5874 : 0,
5875 : 0,
5876 : NULL,
5877 : 0,
5878 : base_privflags,
5879 : NULL,
5880 : NULL,
5881 : &base_fsp,
5882 : NULL);
5883 64 : TALLOC_FREE(smb_fname_base);
5884 :
5885 64 : if (!NT_STATUS_IS_OK(status)) {
5886 0 : DEBUG(10, ("create_file_unixpath for base %s failed: "
5887 : "%s\n", smb_fname->base_name,
5888 : nt_errstr(status)));
5889 0 : goto fail;
5890 : }
5891 : }
5892 :
5893 12976 : if (smb_fname->fsp != NULL) {
5894 :
5895 11158 : fsp = smb_fname->fsp;
5896 :
5897 : /*
5898 : * We're about to use smb_fname->fsp for the fresh open.
5899 : *
5900 : * Every fsp passed in via smb_fname->fsp already
5901 : * holds a fsp->fsp_name. If it is already this
5902 : * fsp->fsp_name that we got passed in as our input
5903 : * argument smb_fname, these two are assumed to have
5904 : * the same lifetime: Every fsp hangs of "conn", and
5905 : * fsp->fsp_name is its talloc child.
5906 : */
5907 :
5908 11158 : if (smb_fname != smb_fname->fsp->fsp_name) {
5909 : /*
5910 : * "smb_fname" is temporary in this case, but
5911 : * the destructor of smb_fname would also tear
5912 : * down the fsp we're about to use. Unlink
5913 : * them from each other.
5914 : */
5915 11158 : smb_fname_fsp_unlink(smb_fname);
5916 :
5917 : /*
5918 : * "fsp" is ours now
5919 : */
5920 11158 : free_fsp_on_error = true;
5921 : }
5922 :
5923 11158 : status = fsp_bind_smb(fsp, req);
5924 11158 : if (!NT_STATUS_IS_OK(status)) {
5925 0 : goto fail;
5926 : }
5927 :
5928 11158 : if (fsp_is_alternate_stream(fsp)) {
5929 46 : struct files_struct *tmp_base_fsp = fsp->base_fsp;
5930 :
5931 46 : fsp_set_base_fsp(fsp, NULL);
5932 :
5933 46 : fd_close(tmp_base_fsp);
5934 46 : file_free(NULL, tmp_base_fsp);
5935 : }
5936 : } else {
5937 : /*
5938 : * No fsp passed in that we can use, create one
5939 : */
5940 1818 : status = file_new(req, conn, &fsp);
5941 1818 : if(!NT_STATUS_IS_OK(status)) {
5942 0 : goto fail;
5943 : }
5944 1818 : free_fsp_on_error = true;
5945 :
5946 1818 : status = fsp_set_smb_fname(fsp, smb_fname);
5947 1818 : if (!NT_STATUS_IS_OK(status)) {
5948 0 : goto fail;
5949 : }
5950 : }
5951 :
5952 12976 : SMB_ASSERT(fsp->fsp_name->fsp != NULL);
5953 12976 : SMB_ASSERT(fsp->fsp_name->fsp == fsp);
5954 :
5955 12976 : if (base_fsp) {
5956 : /*
5957 : * We're opening the stream element of a
5958 : * base_fsp we already opened. Set up the
5959 : * base_fsp pointer.
5960 : */
5961 64 : fsp_set_base_fsp(fsp, base_fsp);
5962 : }
5963 :
5964 12976 : if (dirfsp != NULL) {
5965 12944 : status = SMB_VFS_PARENT_PATHNAME(
5966 : conn,
5967 : talloc_tos(),
5968 : smb_fname,
5969 : &parent_dir_fname,
5970 : &smb_fname_atname);
5971 12944 : if (!NT_STATUS_IS_OK(status)) {
5972 0 : goto fail;
5973 : }
5974 : } else {
5975 : /*
5976 : * Get a pathref on the parent. We can re-use this for
5977 : * multiple calls to check parent ACLs etc. to avoid
5978 : * pathname calls.
5979 : */
5980 32 : status = parent_pathref(talloc_tos(),
5981 : conn->cwd_fsp,
5982 : smb_fname,
5983 : &parent_dir_fname,
5984 : &smb_fname_atname);
5985 32 : if (!NT_STATUS_IS_OK(status)) {
5986 0 : goto fail;
5987 : }
5988 :
5989 32 : dirfsp = parent_dir_fname->fsp;
5990 32 : status = fsp_set_smb_fname(dirfsp, parent_dir_fname);
5991 32 : if (!NT_STATUS_IS_OK(status)) {
5992 0 : goto fail;
5993 : }
5994 : }
5995 :
5996 : /*
5997 : * If it's a request for a directory open, deal with it separately.
5998 : */
5999 :
6000 12976 : if (create_options & FILE_DIRECTORY_FILE) {
6001 :
6002 6464 : if (create_options & FILE_NON_DIRECTORY_FILE) {
6003 0 : status = NT_STATUS_INVALID_PARAMETER;
6004 0 : goto fail;
6005 : }
6006 :
6007 : /* Can't open a temp directory. IFS kit test. */
6008 12108 : if (!(file_attributes & FILE_FLAG_POSIX_SEMANTICS) &&
6009 6464 : (file_attributes & FILE_ATTRIBUTE_TEMPORARY)) {
6010 0 : status = NT_STATUS_INVALID_PARAMETER;
6011 0 : goto fail;
6012 : }
6013 :
6014 : /*
6015 : * We will get a create directory here if the Win32
6016 : * app specified a security descriptor in the
6017 : * CreateDirectory() call.
6018 : */
6019 :
6020 6464 : oplock_request = 0;
6021 6464 : status = open_directory(conn,
6022 : req,
6023 : access_mask,
6024 : share_access,
6025 : create_disposition,
6026 : create_options,
6027 : file_attributes,
6028 : dirfsp->fsp_name,
6029 : smb_fname_atname,
6030 : &info,
6031 : fsp);
6032 : } else {
6033 :
6034 : /*
6035 : * Ordinary file case.
6036 : */
6037 :
6038 6512 : if (allocation_size) {
6039 26 : fsp->initial_allocation_size = smb_roundup(fsp->conn,
6040 : allocation_size);
6041 : }
6042 :
6043 6512 : status = open_file_ntcreate(conn,
6044 : req,
6045 : access_mask,
6046 : share_access,
6047 : create_disposition,
6048 : create_options,
6049 : file_attributes,
6050 : oplock_request,
6051 : lease,
6052 : private_flags,
6053 : dirfsp->fsp_name,
6054 : smb_fname_atname,
6055 : &info,
6056 : fsp);
6057 6512 : if (NT_STATUS_EQUAL(status, NT_STATUS_FILE_IS_A_DIRECTORY)) {
6058 :
6059 : /* A stream open never opens a directory */
6060 :
6061 4455 : if (base_fsp) {
6062 0 : status = NT_STATUS_FILE_IS_A_DIRECTORY;
6063 0 : goto fail;
6064 : }
6065 :
6066 : /*
6067 : * Fail the open if it was explicitly a non-directory
6068 : * file.
6069 : */
6070 :
6071 4455 : if (create_options & FILE_NON_DIRECTORY_FILE) {
6072 11 : status = NT_STATUS_FILE_IS_A_DIRECTORY;
6073 11 : goto fail;
6074 : }
6075 :
6076 4444 : oplock_request = 0;
6077 4444 : status = open_directory(conn,
6078 : req,
6079 : access_mask,
6080 : share_access,
6081 : create_disposition,
6082 : create_options,
6083 : file_attributes,
6084 : dirfsp->fsp_name,
6085 : smb_fname_atname,
6086 : &info,
6087 : fsp);
6088 : }
6089 : }
6090 :
6091 12965 : if (!NT_STATUS_IS_OK(status)) {
6092 899 : goto fail;
6093 : }
6094 :
6095 12066 : fsp->fsp_flags.is_fsa = true;
6096 :
6097 12067 : if ((ea_list != NULL) &&
6098 1 : ((info == FILE_WAS_CREATED) || (info == FILE_WAS_OVERWRITTEN))) {
6099 1 : status = set_ea(conn, fsp, ea_list);
6100 1 : if (!NT_STATUS_IS_OK(status)) {
6101 0 : goto fail;
6102 : }
6103 : }
6104 :
6105 13626 : if (!fsp->fsp_flags.is_directory &&
6106 1850 : S_ISDIR(fsp->fsp_name->st.st_ex_mode))
6107 : {
6108 0 : status = NT_STATUS_ACCESS_DENIED;
6109 0 : goto fail;
6110 : }
6111 :
6112 : /* Save the requested allocation size. */
6113 12066 : if ((info == FILE_WAS_CREATED) || (info == FILE_WAS_OVERWRITTEN)) {
6114 2681 : if ((allocation_size > (uint64_t)fsp->fsp_name->st.st_ex_size)
6115 20 : && !(fsp->fsp_flags.is_directory))
6116 : {
6117 19 : fsp->initial_allocation_size = smb_roundup(
6118 19 : fsp->conn, allocation_size);
6119 38 : if (vfs_allocate_file_space(
6120 19 : fsp, fsp->initial_allocation_size) == -1) {
6121 0 : status = NT_STATUS_DISK_FULL;
6122 0 : goto fail;
6123 : }
6124 : } else {
6125 2643 : fsp->initial_allocation_size = smb_roundup(
6126 2643 : fsp->conn, (uint64_t)fsp->fsp_name->st.st_ex_size);
6127 : }
6128 : } else {
6129 10642 : fsp->initial_allocation_size = 0;
6130 : }
6131 :
6132 13420 : if ((info == FILE_WAS_CREATED) &&
6133 2544 : lp_nt_acl_support(SNUM(conn)) &&
6134 1354 : !fsp_is_alternate_stream(fsp)) {
6135 1336 : if (sd != NULL) {
6136 : /*
6137 : * According to the MS documentation, the only time the security
6138 : * descriptor is applied to the opened file is iff we *created* the
6139 : * file; an existing file stays the same.
6140 : *
6141 : * Also, it seems (from observation) that you can open the file with
6142 : * any access mask but you can still write the sd. We need to override
6143 : * the granted access before we call set_sd
6144 : * Patch for bug #2242 from Tom Lackemann <cessnatomny@yahoo.com>.
6145 : */
6146 :
6147 : uint32_t sec_info_sent;
6148 7 : uint32_t saved_access_mask = fsp->access_mask;
6149 :
6150 7 : sec_info_sent = get_sec_info(sd);
6151 :
6152 7 : fsp->access_mask = FILE_GENERIC_ALL;
6153 :
6154 7 : if (sec_info_sent & (SECINFO_OWNER|
6155 : SECINFO_GROUP|
6156 : SECINFO_DACL|
6157 : SECINFO_SACL)) {
6158 6 : status = set_sd(fsp, sd, sec_info_sent);
6159 : }
6160 :
6161 7 : fsp->access_mask = saved_access_mask;
6162 :
6163 7 : if (!NT_STATUS_IS_OK(status)) {
6164 0 : goto fail;
6165 : }
6166 1329 : } else if (lp_inherit_acls(SNUM(conn))) {
6167 : /* Inherit from parent. Errors here are not fatal. */
6168 1325 : status = inherit_new_acl(dirfsp, fsp);
6169 1325 : if (!NT_STATUS_IS_OK(status)) {
6170 0 : DEBUG(10,("inherit_new_acl: failed for %s with %s\n",
6171 : fsp_str_dbg(fsp),
6172 : nt_errstr(status) ));
6173 : }
6174 : }
6175 : }
6176 :
6177 12066 : if ((conn->fs_capabilities & FILE_FILE_COMPRESSION)
6178 0 : && (create_options & FILE_NO_COMPRESSION)
6179 0 : && (info == FILE_WAS_CREATED)) {
6180 0 : status = SMB_VFS_SET_COMPRESSION(conn, fsp, fsp,
6181 : COMPRESSION_FORMAT_NONE);
6182 0 : if (!NT_STATUS_IS_OK(status)) {
6183 0 : DEBUG(1, ("failed to disable compression: %s\n",
6184 : nt_errstr(status)));
6185 : }
6186 : }
6187 :
6188 12066 : DEBUG(10, ("create_file_unixpath: info=%d\n", info));
6189 :
6190 12066 : *result = fsp;
6191 12066 : if (pinfo != NULL) {
6192 12002 : *pinfo = info;
6193 : }
6194 :
6195 12066 : smb_fname->st = fsp->fsp_name->st;
6196 :
6197 12066 : TALLOC_FREE(parent_dir_fname);
6198 :
6199 12066 : return NT_STATUS_OK;
6200 :
6201 911 : fail:
6202 911 : DEBUG(10, ("create_file_unixpath: %s\n", nt_errstr(status)));
6203 :
6204 911 : if (fsp != NULL) {
6205 : /*
6206 : * The close_file below will close
6207 : * fsp->base_fsp.
6208 : */
6209 910 : base_fsp = NULL;
6210 910 : close_file_smb(req, fsp, ERROR_CLOSE);
6211 910 : if (free_fsp_on_error) {
6212 910 : file_free(req, fsp);
6213 910 : fsp = NULL;
6214 : }
6215 : }
6216 911 : if (base_fsp != NULL) {
6217 0 : close_file_free(req, &base_fsp, ERROR_CLOSE);
6218 : }
6219 :
6220 911 : TALLOC_FREE(parent_dir_fname);
6221 :
6222 911 : return status;
6223 : }
6224 :
6225 12914 : NTSTATUS create_file_default(connection_struct *conn,
6226 : struct smb_request *req,
6227 : struct files_struct *dirfsp,
6228 : struct smb_filename *smb_fname,
6229 : uint32_t access_mask,
6230 : uint32_t share_access,
6231 : uint32_t create_disposition,
6232 : uint32_t create_options,
6233 : uint32_t file_attributes,
6234 : uint32_t oplock_request,
6235 : const struct smb2_lease *lease,
6236 : uint64_t allocation_size,
6237 : uint32_t private_flags,
6238 : struct security_descriptor *sd,
6239 : struct ea_list *ea_list,
6240 : files_struct **result,
6241 : int *pinfo,
6242 : const struct smb2_create_blobs *in_context_blobs,
6243 : struct smb2_create_blobs *out_context_blobs)
6244 : {
6245 12914 : int info = FILE_WAS_OPENED;
6246 12914 : files_struct *fsp = NULL;
6247 : NTSTATUS status;
6248 12914 : bool stream_name = false;
6249 12914 : struct smb2_create_blob *posx = NULL;
6250 :
6251 12914 : DBG_DEBUG("create_file: access_mask = 0x%x "
6252 : "file_attributes = 0x%x, share_access = 0x%x, "
6253 : "create_disposition = 0x%x create_options = 0x%x "
6254 : "oplock_request = 0x%x "
6255 : "private_flags = 0x%x "
6256 : "ea_list = %p, sd = %p, "
6257 : "fname = %s\n",
6258 : (unsigned int)access_mask,
6259 : (unsigned int)file_attributes,
6260 : (unsigned int)share_access,
6261 : (unsigned int)create_disposition,
6262 : (unsigned int)create_options,
6263 : (unsigned int)oplock_request,
6264 : (unsigned int)private_flags,
6265 : ea_list,
6266 : sd,
6267 : smb_fname_str_dbg(smb_fname));
6268 :
6269 12914 : if (req != NULL) {
6270 : /*
6271 : * Remember the absolute time of the original request
6272 : * with this mid. We'll use it later to see if this
6273 : * has timed out.
6274 : */
6275 12898 : get_deferred_open_message_state(req, &req->request_time, NULL);
6276 : }
6277 :
6278 : /*
6279 : * Check to see if this is a mac fork of some kind.
6280 : */
6281 :
6282 12914 : stream_name = is_ntfs_stream_smb_fname(smb_fname);
6283 12914 : if (stream_name) {
6284 : enum FAKE_FILE_TYPE fake_file_type;
6285 :
6286 65 : fake_file_type = is_fake_file(smb_fname);
6287 :
6288 65 : if (req != NULL && fake_file_type != FAKE_FILE_TYPE_NONE) {
6289 :
6290 : /*
6291 : * Here we go! support for changing the disk quotas
6292 : * --metze
6293 : *
6294 : * We need to fake up to open this MAGIC QUOTA file
6295 : * and return a valid FID.
6296 : *
6297 : * w2k close this file directly after openening xp
6298 : * also tries a QUERY_FILE_INFO on the file and then
6299 : * close it
6300 : */
6301 1 : status = open_fake_file(req, conn, req->vuid,
6302 : fake_file_type, smb_fname,
6303 : access_mask, &fsp);
6304 1 : if (!NT_STATUS_IS_OK(status)) {
6305 0 : goto fail;
6306 : }
6307 :
6308 1 : ZERO_STRUCT(smb_fname->st);
6309 1 : goto done;
6310 : }
6311 :
6312 64 : if (!(conn->fs_capabilities & FILE_NAMED_STREAMS)) {
6313 0 : status = NT_STATUS_OBJECT_NAME_INVALID;
6314 0 : goto fail;
6315 : }
6316 : }
6317 :
6318 12913 : if (is_ntfs_default_stream_smb_fname(smb_fname)) {
6319 : int ret;
6320 : /* We have to handle this error here. */
6321 0 : if (create_options & FILE_DIRECTORY_FILE) {
6322 0 : status = NT_STATUS_NOT_A_DIRECTORY;
6323 0 : goto fail;
6324 : }
6325 0 : ret = vfs_stat(conn, smb_fname);
6326 0 : if (ret == 0 && VALID_STAT_OF_DIR(smb_fname->st)) {
6327 0 : status = NT_STATUS_FILE_IS_A_DIRECTORY;
6328 0 : goto fail;
6329 : }
6330 : }
6331 :
6332 12913 : posx = smb2_create_blob_find(
6333 : in_context_blobs, SMB2_CREATE_TAG_POSIX);
6334 12913 : if (posx != NULL) {
6335 0 : uint32_t wire_mode_bits = 0;
6336 0 : mode_t mode_bits = 0;
6337 0 : SMB_STRUCT_STAT sbuf = { 0 };
6338 0 : enum perm_type ptype =
6339 : (create_options & FILE_DIRECTORY_FILE) ?
6340 0 : PERM_NEW_DIR : PERM_NEW_FILE;
6341 :
6342 0 : if (posx->data.length != 4) {
6343 0 : status = NT_STATUS_INVALID_PARAMETER;
6344 0 : goto fail;
6345 : }
6346 :
6347 0 : wire_mode_bits = IVAL(posx->data.data, 0);
6348 0 : status = unix_perms_from_wire(
6349 : conn, &sbuf, wire_mode_bits, ptype, &mode_bits);
6350 0 : if (!NT_STATUS_IS_OK(status)) {
6351 0 : goto fail;
6352 : }
6353 : /*
6354 : * Remove type info from mode, leaving only the
6355 : * permissions and setuid/gid bits.
6356 : */
6357 0 : mode_bits &= ~S_IFMT;
6358 :
6359 0 : file_attributes = (FILE_FLAG_POSIX_SEMANTICS | mode_bits);
6360 : }
6361 :
6362 12913 : status = create_file_unixpath(conn,
6363 : req,
6364 : dirfsp,
6365 : smb_fname,
6366 : access_mask,
6367 : share_access,
6368 : create_disposition,
6369 : create_options,
6370 : file_attributes,
6371 : oplock_request,
6372 : lease,
6373 : allocation_size,
6374 : private_flags,
6375 : sd,
6376 : ea_list,
6377 : &fsp,
6378 : &info);
6379 12913 : if (!NT_STATUS_IS_OK(status)) {
6380 911 : goto fail;
6381 : }
6382 :
6383 22849 : done:
6384 12003 : DEBUG(10, ("create_file: info=%d\n", info));
6385 :
6386 12003 : *result = fsp;
6387 12003 : if (pinfo != NULL) {
6388 11987 : *pinfo = info;
6389 : }
6390 12003 : return NT_STATUS_OK;
6391 :
6392 911 : fail:
6393 911 : DEBUG(10, ("create_file: %s\n", nt_errstr(status)));
6394 :
6395 911 : if (fsp != NULL) {
6396 0 : close_file_free(req, &fsp, ERROR_CLOSE);
6397 : }
6398 911 : return status;
6399 : }
|