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