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