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