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