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