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