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