Line data Source code
1 : /*
2 : Unix SMB/CIFS implementation.
3 : file closing
4 : Copyright (C) Andrew Tridgell 1992-1998
5 : Copyright (C) Jeremy Allison 1992-2007.
6 : Copyright (C) Volker Lendecke 2005
7 :
8 : This program is free software; you can redistribute it and/or modify
9 : it under the terms of the GNU General Public License as published by
10 : the Free Software Foundation; either version 3 of the License, or
11 : (at your option) any later version.
12 :
13 : This program is distributed in the hope that it will be useful,
14 : but WITHOUT ANY WARRANTY; without even the implied warranty of
15 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 : GNU General Public License for more details.
17 :
18 : You should have received a copy of the GNU General Public License
19 : along with this program. If not, see <http://www.gnu.org/licenses/>.
20 : */
21 :
22 : #include "includes.h"
23 : #include "system/filesys.h"
24 : #include "lib/util/server_id.h"
25 : #include "printing.h"
26 : #include "locking/share_mode_lock.h"
27 : #include "smbd/smbd.h"
28 : #include "smbd/globals.h"
29 : #include "smbd/smbXsrv_open.h"
30 : #include "smbd/scavenger.h"
31 : #include "fake_file.h"
32 : #include "transfer_file.h"
33 : #include "auth.h"
34 : #include "messages.h"
35 : #include "../librpc/gen_ndr/open_files.h"
36 : #include "lib/util/tevent_ntstatus.h"
37 :
38 : /****************************************************************************
39 : Run a file if it is a magic script.
40 : ****************************************************************************/
41 :
42 353651 : static NTSTATUS check_magic(struct files_struct *fsp)
43 : {
44 576 : int ret;
45 576 : const struct loadparm_substitution *lp_sub =
46 353651 : loadparm_s3_global_substitution();
47 353651 : const char *magic_output = NULL;
48 576 : SMB_STRUCT_STAT st;
49 576 : int tmp_fd, outfd;
50 353651 : TALLOC_CTX *ctx = NULL;
51 576 : const char *p;
52 353651 : struct connection_struct *conn = fsp->conn;
53 353651 : char *fname = NULL;
54 576 : NTSTATUS status;
55 :
56 353651 : if (!*lp_magic_script(talloc_tos(), lp_sub, SNUM(conn))) {
57 353651 : return NT_STATUS_OK;
58 : }
59 :
60 0 : DEBUG(5,("checking magic for %s\n", fsp_str_dbg(fsp)));
61 :
62 0 : ctx = talloc_stackframe();
63 :
64 0 : fname = fsp->fsp_name->base_name;
65 :
66 0 : if (!(p = strrchr_m(fname,'/'))) {
67 0 : p = fname;
68 : } else {
69 0 : p++;
70 : }
71 :
72 0 : if (!strequal(lp_magic_script(talloc_tos(), lp_sub, SNUM(conn)),p)) {
73 0 : status = NT_STATUS_OK;
74 0 : goto out;
75 : }
76 :
77 0 : if (*lp_magic_output(talloc_tos(), lp_sub, SNUM(conn))) {
78 0 : magic_output = lp_magic_output(talloc_tos(), lp_sub, SNUM(conn));
79 : } else {
80 0 : magic_output = talloc_asprintf(ctx,
81 : "%s.out",
82 : fname);
83 : }
84 0 : if (!magic_output) {
85 0 : status = NT_STATUS_NO_MEMORY;
86 0 : goto out;
87 : }
88 :
89 : /* Ensure we don't depend on user's PATH. */
90 0 : p = talloc_asprintf(ctx, "./%s", fname);
91 0 : if (!p) {
92 0 : status = NT_STATUS_NO_MEMORY;
93 0 : goto out;
94 : }
95 :
96 0 : if (chmod(fname, 0755) == -1) {
97 0 : status = map_nt_error_from_unix(errno);
98 0 : goto out;
99 : }
100 0 : ret = smbrun(p, &tmp_fd, NULL);
101 0 : DEBUG(3,("Invoking magic command %s gave %d\n",
102 : p,ret));
103 :
104 0 : unlink(fname);
105 0 : if (ret != 0 || tmp_fd == -1) {
106 0 : if (tmp_fd != -1) {
107 0 : close(tmp_fd);
108 : }
109 0 : status = NT_STATUS_UNSUCCESSFUL;
110 0 : goto out;
111 : }
112 0 : outfd = open(magic_output, O_CREAT|O_EXCL|O_RDWR, 0600);
113 0 : if (outfd == -1) {
114 0 : int err = errno;
115 0 : close(tmp_fd);
116 0 : status = map_nt_error_from_unix(err);
117 0 : goto out;
118 : }
119 :
120 0 : if (sys_fstat(tmp_fd, &st, false) == -1) {
121 0 : int err = errno;
122 0 : close(tmp_fd);
123 0 : close(outfd);
124 0 : status = map_nt_error_from_unix(err);
125 0 : goto out;
126 : }
127 :
128 0 : if (transfer_file(tmp_fd,outfd,(off_t)st.st_ex_size) == (off_t)-1) {
129 0 : int err = errno;
130 0 : close(tmp_fd);
131 0 : close(outfd);
132 0 : status = map_nt_error_from_unix(err);
133 0 : goto out;
134 : }
135 0 : close(tmp_fd);
136 0 : if (close(outfd) == -1) {
137 0 : status = map_nt_error_from_unix(errno);
138 0 : goto out;
139 : }
140 :
141 0 : status = NT_STATUS_OK;
142 :
143 0 : out:
144 0 : TALLOC_FREE(ctx);
145 0 : return status;
146 : }
147 :
148 : /****************************************************************************
149 : Delete all streams
150 : ****************************************************************************/
151 :
152 149294 : NTSTATUS delete_all_streams(connection_struct *conn,
153 : const struct smb_filename *smb_fname)
154 : {
155 149294 : struct stream_struct *stream_info = NULL;
156 381 : unsigned int i;
157 149294 : unsigned int num_streams = 0;
158 149294 : TALLOC_CTX *frame = talloc_stackframe();
159 381 : NTSTATUS status;
160 :
161 149294 : status = vfs_fstreaminfo(smb_fname->fsp, talloc_tos(),
162 : &num_streams, &stream_info);
163 :
164 149294 : if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_IMPLEMENTED)) {
165 0 : DEBUG(10, ("no streams around\n"));
166 0 : TALLOC_FREE(frame);
167 0 : return NT_STATUS_OK;
168 : }
169 :
170 149294 : if (!NT_STATUS_IS_OK(status)) {
171 0 : DEBUG(10, ("vfs_fstreaminfo failed: %s\n",
172 : nt_errstr(status)));
173 0 : goto fail;
174 : }
175 :
176 149294 : DEBUG(10, ("delete_all_streams found %d streams\n",
177 : num_streams));
178 :
179 149294 : if (num_streams == 0) {
180 10552 : TALLOC_FREE(frame);
181 10552 : return NT_STATUS_OK;
182 : }
183 :
184 278102 : for (i=0; i<num_streams; i++) {
185 318 : int res;
186 318 : struct smb_filename *smb_fname_stream;
187 :
188 139360 : if (strequal(stream_info[i].name, "::$DATA")) {
189 138687 : continue;
190 : }
191 :
192 673 : status = synthetic_pathref(talloc_tos(),
193 : conn->cwd_fsp,
194 673 : smb_fname->base_name,
195 673 : stream_info[i].name,
196 : NULL,
197 673 : smb_fname->twrp,
198 673 : (smb_fname->flags &
199 : ~SMB_FILENAME_POSIX_PATH),
200 : &smb_fname_stream);
201 673 : if (!NT_STATUS_IS_OK(status)) {
202 0 : DEBUG(0, ("talloc_aprintf failed\n"));
203 0 : status = NT_STATUS_NO_MEMORY;
204 0 : goto fail;
205 : }
206 :
207 673 : res = SMB_VFS_UNLINKAT(conn,
208 : conn->cwd_fsp,
209 : smb_fname_stream,
210 : 0);
211 :
212 673 : if (res == -1) {
213 0 : status = map_nt_error_from_unix(errno);
214 0 : DEBUG(10, ("Could not delete stream %s: %s\n",
215 : smb_fname_str_dbg(smb_fname_stream),
216 : strerror(errno)));
217 0 : TALLOC_FREE(smb_fname_stream);
218 0 : break;
219 : }
220 673 : TALLOC_FREE(smb_fname_stream);
221 : }
222 :
223 138742 : fail:
224 138742 : TALLOC_FREE(frame);
225 138742 : return status;
226 : }
227 :
228 : struct has_other_nonposix_opens_state {
229 : files_struct *fsp;
230 : bool found_another;
231 : };
232 :
233 170997 : static bool has_other_nonposix_opens_fn(
234 : struct share_mode_entry *e,
235 : bool *modified,
236 : void *private_data)
237 : {
238 170997 : struct has_other_nonposix_opens_state *state = private_data;
239 170997 : struct files_struct *fsp = state->fsp;
240 :
241 170997 : if (e->name_hash != fsp->name_hash) {
242 4 : return false;
243 : }
244 170993 : if (e->flags & SHARE_MODE_FLAG_POSIX_OPEN) {
245 1617 : return false;
246 : }
247 169376 : if (e->share_file_id == fh_get_gen_id(fsp->fh)) {
248 169120 : struct server_id self = messaging_server_id(
249 169120 : fsp->conn->sconn->msg_ctx);
250 169120 : if (server_id_equal(&self, &e->pid)) {
251 169119 : return false;
252 : }
253 : }
254 257 : if (share_entry_stale_pid(e)) {
255 0 : return false;
256 : }
257 :
258 257 : state->found_another = true;
259 257 : return true;
260 : }
261 :
262 170810 : bool has_other_nonposix_opens(struct share_mode_lock *lck,
263 : struct files_struct *fsp)
264 : {
265 170810 : struct has_other_nonposix_opens_state state = { .fsp = fsp };
266 350 : bool ok;
267 :
268 170810 : ok = share_mode_forall_entries(
269 : lck, has_other_nonposix_opens_fn, &state);
270 170810 : if (!ok) {
271 0 : return false;
272 : }
273 170810 : return state.found_another;
274 : }
275 :
276 : struct close_share_mode_lock_state {
277 : struct share_mode_entry_prepare_state prepare_state;
278 : const char *object_type;
279 : struct files_struct *fsp;
280 : enum file_close_type close_type;
281 : bool delete_object;
282 : bool got_tokens;
283 : const struct security_unix_token *del_token;
284 : const struct security_token *del_nt_token;
285 : bool reset_delete_on_close;
286 : share_mode_entry_prepare_unlock_fn_t cleanup_fn;
287 : };
288 :
289 439390 : static void close_share_mode_lock_prepare(struct share_mode_lock *lck,
290 : bool *keep_locked,
291 : void *private_data)
292 : {
293 439390 : struct close_share_mode_lock_state *state =
294 : (struct close_share_mode_lock_state *)private_data;
295 439390 : struct files_struct *fsp = state->fsp;
296 938 : bool normal_close;
297 938 : bool ok;
298 :
299 : /*
300 : * By default drop the g_lock again if we leave the
301 : * tdb chainlock.
302 : */
303 439390 : *keep_locked = false;
304 :
305 439390 : if (fsp->oplock_type != NO_OPLOCK) {
306 2524 : ok = remove_share_oplock(lck, fsp);
307 2524 : if (!ok) {
308 0 : struct file_id_buf buf;
309 :
310 0 : DBG_ERR("failed to remove share oplock for "
311 : "%s %s, %s, %s\n",
312 : state->object_type,
313 : fsp_str_dbg(fsp), fsp_fnum_dbg(fsp),
314 : file_id_str_buf(fsp->file_id, &buf));
315 : }
316 : }
317 :
318 439390 : if (fsp->fsp_flags.write_time_forced) {
319 967 : NTTIME mtime = share_mode_changed_write_time(lck);
320 967 : struct timespec ts = nt_time_to_full_timespec(mtime);
321 :
322 967 : DBG_DEBUG("write time forced for %s %s\n",
323 : state->object_type, fsp_str_dbg(fsp));
324 967 : set_close_write_time(fsp, ts);
325 438423 : } else if (fsp->fsp_flags.update_write_time_on_close) {
326 : /* Someone had a pending write. */
327 100 : if (is_omit_timespec(&fsp->close_write_time)) {
328 69 : DBG_DEBUG("update to current time for %s %s\n",
329 : state->object_type, fsp_str_dbg(fsp));
330 : /* Update to current time due to "normal" write. */
331 69 : set_close_write_time(fsp, timespec_current());
332 : } else {
333 31 : DBG_DEBUG("write time pending for %s %s\n",
334 : state->object_type, fsp_str_dbg(fsp));
335 : /* Update to time set on close call. */
336 31 : set_close_write_time(fsp, fsp->close_write_time);
337 : }
338 : }
339 :
340 439530 : if (fsp->fsp_flags.initial_delete_on_close &&
341 137008 : !is_delete_on_close_set(lck, fsp->name_hash)) {
342 : /* Initial delete on close was set and no one else
343 : * wrote a real delete on close. */
344 :
345 137001 : fsp->fsp_flags.delete_on_close = true;
346 137001 : set_delete_on_close_lck(fsp, lck,
347 137001 : fsp->conn->session_info->security_token,
348 137001 : fsp->conn->session_info->unix_token);
349 : }
350 :
351 609952 : state->delete_object = is_delete_on_close_set(lck, fsp->name_hash) &&
352 170562 : !has_other_nonposix_opens(lck, fsp);
353 :
354 : /*
355 : * NT can set delete_on_close of the last open
356 : * reference to a file.
357 : */
358 :
359 439390 : normal_close = (state->close_type == NORMAL_CLOSE || state->close_type == SHUTDOWN_CLOSE);
360 439390 : if (!normal_close) {
361 : /*
362 : * Never try to delete the file/directory for ERROR_CLOSE
363 : */
364 2613 : state->delete_object = false;
365 : }
366 :
367 439390 : if (!state->delete_object) {
368 269077 : ok = del_share_mode(lck, fsp);
369 269077 : if (!ok) {
370 0 : DBG_ERR("Could not delete share entry for %s %s\n",
371 : state->object_type, fsp_str_dbg(fsp));
372 : }
373 269077 : return;
374 : }
375 :
376 : /*
377 : * We're going to remove the file/directory
378 : * so keep the g_lock after the tdb chainlock
379 : * is left, so we hold the share_mode_lock
380 : * also during the deletion
381 : */
382 170313 : *keep_locked = true;
383 :
384 170313 : state->got_tokens = get_delete_on_close_token(lck, fsp->name_hash,
385 : &state->del_nt_token, &state->del_token);
386 170313 : if (state->close_type != ERROR_CLOSE) {
387 170313 : SMB_ASSERT(state->got_tokens);
388 : }
389 : }
390 :
391 170313 : static void close_share_mode_lock_cleanup(struct share_mode_lock *lck,
392 : void *private_data)
393 : {
394 170313 : struct close_share_mode_lock_state *state =
395 : (struct close_share_mode_lock_state *)private_data;
396 170313 : struct files_struct *fsp = state->fsp;
397 336 : bool ok;
398 :
399 170313 : if (state->reset_delete_on_close) {
400 159214 : reset_delete_on_close_lck(fsp, lck);
401 : }
402 :
403 170313 : ok = del_share_mode(lck, fsp);
404 170313 : if (!ok) {
405 0 : DBG_ERR("Could not delete share entry for %s %s\n",
406 : state->object_type, fsp_str_dbg(fsp));
407 : }
408 170313 : }
409 :
410 : /****************************************************************************
411 : Deal with removing a share mode on last close.
412 : ****************************************************************************/
413 :
414 356882 : static NTSTATUS close_remove_share_mode(files_struct *fsp,
415 : enum file_close_type close_type)
416 : {
417 356882 : connection_struct *conn = fsp->conn;
418 356882 : struct close_share_mode_lock_state lck_state = {};
419 356882 : bool changed_user = false;
420 356882 : NTSTATUS status = NT_STATUS_OK;
421 592 : NTSTATUS tmp_status;
422 592 : NTSTATUS ulstatus;
423 592 : struct file_id id;
424 356882 : struct smb_filename *parent_fname = NULL;
425 356882 : struct smb_filename *base_fname = NULL;
426 592 : int ret;
427 :
428 : /* Ensure any pending write time updates are done. */
429 356882 : if (fsp->update_write_time_event) {
430 5183 : fsp_flush_write_time_update(fsp);
431 : }
432 :
433 : /*
434 : * Lock the share entries, and determine if we should delete
435 : * on close. If so delete whilst the lock is still in effect.
436 : * This prevents race conditions with the file being created. JRA.
437 : */
438 :
439 356882 : lck_state = (struct close_share_mode_lock_state) {
440 : .fsp = fsp,
441 : .object_type = "file",
442 : .close_type = close_type,
443 : };
444 :
445 356882 : status = share_mode_entry_prepare_lock_del(&lck_state.prepare_state,
446 : fsp->file_id,
447 : close_share_mode_lock_prepare,
448 592 : &lck_state);
449 356882 : if (!NT_STATUS_IS_OK(status)) {
450 0 : DBG_ERR("share_mode_entry_prepare_lock_del() failed for %s - %s\n",
451 : fsp_str_dbg(fsp), nt_errstr(status));
452 0 : return status;
453 : }
454 :
455 : /* Remove the oplock before potentially deleting the file. */
456 356882 : if (fsp->oplock_type != NO_OPLOCK) {
457 2524 : release_file_oplock(fsp);
458 : }
459 :
460 : /*
461 : * NT can set delete_on_close of the last open
462 : * reference to a file.
463 : */
464 :
465 356882 : if (!lck_state.delete_object) {
466 197664 : status = NT_STATUS_OK;
467 197664 : goto done;
468 : }
469 :
470 : /*
471 : * Ok, we have to delete the file
472 : */
473 159218 : lck_state.cleanup_fn = close_share_mode_lock_cleanup;
474 :
475 159218 : DEBUG(5,("close_remove_share_mode: file %s. Delete on close was set "
476 : "- deleting file.\n", fsp_str_dbg(fsp)));
477 :
478 : /*
479 : * Don't try to update the write time when we delete the file
480 : */
481 159218 : fsp->fsp_flags.update_write_time_on_close = false;
482 :
483 159490 : if (lck_state.got_tokens &&
484 159218 : !unix_token_equal(lck_state.del_token, get_current_utok(conn)))
485 : {
486 : /* Become the user who requested the delete. */
487 :
488 210 : DEBUG(5,("close_remove_share_mode: file %s. "
489 : "Change user to uid %u\n",
490 : fsp_str_dbg(fsp),
491 : (unsigned int)lck_state.del_token->uid));
492 :
493 210 : if (!push_sec_ctx()) {
494 0 : smb_panic("close_remove_share_mode: file %s. failed to push "
495 : "sec_ctx.\n");
496 : }
497 :
498 210 : set_sec_ctx(lck_state.del_token->uid,
499 210 : lck_state.del_token->gid,
500 210 : lck_state.del_token->ngroups,
501 210 : lck_state.del_token->groups,
502 : lck_state.del_nt_token);
503 :
504 210 : changed_user = true;
505 : }
506 :
507 : /* We can only delete the file if the name we have is still valid and
508 : hasn't been renamed. */
509 :
510 159218 : tmp_status = vfs_stat_fsp(fsp);
511 159218 : if (!NT_STATUS_IS_OK(tmp_status)) {
512 0 : DEBUG(5,("close_remove_share_mode: file %s. Delete on close "
513 : "was set and stat failed with error %s\n",
514 : fsp_str_dbg(fsp), nt_errstr(tmp_status)));
515 : /*
516 : * Don't save the errno here, we ignore this error
517 : */
518 0 : goto done;
519 : }
520 :
521 159218 : id = vfs_file_id_from_sbuf(conn, &fsp->fsp_name->st);
522 :
523 159218 : if (!file_id_equal(&fsp->file_id, &id)) {
524 0 : struct file_id_buf ftmp1, ftmp2;
525 4 : DEBUG(5,("close_remove_share_mode: file %s. Delete on close "
526 : "was set and dev and/or inode does not match\n",
527 : fsp_str_dbg(fsp)));
528 4 : DEBUG(5,("close_remove_share_mode: file %s. stored file_id %s, "
529 : "stat file_id %s\n",
530 : fsp_str_dbg(fsp),
531 : file_id_str_buf(fsp->file_id, &ftmp1),
532 : file_id_str_buf(id, &ftmp2)));
533 : /*
534 : * Don't save the errno here, we ignore this error
535 : */
536 4 : goto done;
537 : }
538 :
539 159214 : if ((conn->fs_capabilities & FILE_NAMED_STREAMS)
540 138449 : && !fsp_is_alternate_stream(fsp)) {
541 :
542 137991 : status = delete_all_streams(conn, fsp->fsp_name);
543 :
544 137991 : if (!NT_STATUS_IS_OK(status)) {
545 0 : DEBUG(5, ("delete_all_streams failed: %s\n",
546 : nt_errstr(status)));
547 0 : goto done;
548 : }
549 : }
550 :
551 159214 : if (fsp->fsp_flags.kernel_share_modes_taken) {
552 : /*
553 : * A file system sharemode could block the unlink;
554 : * remove filesystem sharemodes first.
555 : */
556 0 : ret = SMB_VFS_FILESYSTEM_SHAREMODE(fsp, 0, 0);
557 0 : if (ret == -1) {
558 0 : DBG_INFO("Removing file system sharemode for %s "
559 : "failed: %s\n",
560 : fsp_str_dbg(fsp), strerror(errno));
561 : }
562 :
563 0 : fsp->fsp_flags.kernel_share_modes_taken = false;
564 : }
565 :
566 159214 : status = parent_pathref(talloc_tos(),
567 : conn->cwd_fsp,
568 159214 : fsp->fsp_name,
569 : &parent_fname,
570 : &base_fname);
571 159214 : if (!NT_STATUS_IS_OK(status)) {
572 0 : goto done;
573 : }
574 :
575 159214 : ret = SMB_VFS_UNLINKAT(conn,
576 : parent_fname->fsp,
577 : base_fname,
578 : 0);
579 159214 : TALLOC_FREE(parent_fname);
580 159214 : base_fname = NULL;
581 159214 : if (ret != 0) {
582 : /*
583 : * This call can potentially fail as another smbd may
584 : * have had the file open with delete on close set and
585 : * deleted it when its last reference to this file
586 : * went away. Hence we log this but not at debug level
587 : * zero.
588 : */
589 :
590 0 : DEBUG(5,("close_remove_share_mode: file %s. Delete on close "
591 : "was set and unlink failed with error %s\n",
592 : fsp_str_dbg(fsp), strerror(errno)));
593 :
594 0 : status = map_nt_error_from_unix(errno);
595 : }
596 :
597 : /* As we now have POSIX opens which can unlink
598 : * with other open files we may have taken
599 : * this code path with more than one share mode
600 : * entry - ensure we only delete once by resetting
601 : * the delete on close flag. JRA.
602 : */
603 :
604 159214 : fsp->fsp_flags.delete_on_close = false;
605 159214 : lck_state.reset_delete_on_close = true;
606 :
607 356562 : done:
608 :
609 356882 : if (changed_user) {
610 : /* unbecome user. */
611 210 : pop_sec_ctx();
612 : }
613 :
614 356882 : if (fsp->fsp_flags.kernel_share_modes_taken) {
615 : /* remove filesystem sharemodes */
616 0 : ret = SMB_VFS_FILESYSTEM_SHAREMODE(fsp, 0, 0);
617 0 : if (ret == -1) {
618 0 : DBG_INFO("Removing file system sharemode for "
619 : "%s failed: %s\n",
620 : fsp_str_dbg(fsp), strerror(errno));
621 : }
622 : }
623 :
624 356882 : ulstatus = share_mode_entry_prepare_unlock(&lck_state.prepare_state,
625 : lck_state.cleanup_fn,
626 592 : &lck_state);
627 356882 : if (!NT_STATUS_IS_OK(ulstatus)) {
628 0 : DBG_ERR("share_mode_entry_prepare_unlock() failed for %s - %s\n",
629 : fsp_str_dbg(fsp), nt_errstr(ulstatus));
630 0 : smb_panic("share_mode_entry_prepare_unlock() failed!");
631 : }
632 :
633 356882 : if (lck_state.delete_object) {
634 : /*
635 : * Do the notification after we released the share
636 : * mode lock. Inside notify_fname we take out another
637 : * tdb lock. With ctdb also accessing our databases,
638 : * this can lead to deadlocks. Putting this notify
639 : * after the TALLOC_FREE(lck) above we avoid locking
640 : * two records simultaneously. Notifies are async and
641 : * informational only, so calling the notify_fname
642 : * without holding the share mode lock should not do
643 : * any harm.
644 : */
645 159218 : notify_fname(conn, NOTIFY_ACTION_REMOVED,
646 : FILE_NOTIFY_CHANGE_FILE_NAME,
647 159218 : fsp->fsp_name->base_name);
648 : }
649 :
650 356882 : return status;
651 : }
652 :
653 31983 : void set_close_write_time(struct files_struct *fsp, struct timespec ts)
654 : {
655 31983 : DEBUG(6,("close_write_time: %s" , time_to_asc(convert_timespec_to_time_t(ts))));
656 :
657 31983 : if (is_omit_timespec(&ts)) {
658 30597 : return;
659 : }
660 1098 : fsp->fsp_flags.write_time_forced = false;
661 1098 : fsp->fsp_flags.update_write_time_on_close = true;
662 1098 : fsp->close_write_time = ts;
663 : }
664 :
665 25 : static void update_write_time_on_close_share_mode_fn(struct share_mode_lock *lck,
666 : void *private_data)
667 : {
668 1 : struct files_struct *fsp =
669 25 : talloc_get_type_abort(private_data,
670 : struct files_struct);
671 25 : NTTIME share_mtime = share_mode_changed_write_time(lck);
672 :
673 : /*
674 : * On close if we're changing the real file time we
675 : * must update it in the open file db too.
676 : */
677 25 : share_mode_set_old_write_time(lck, fsp->close_write_time);
678 :
679 : /*
680 : * Close write times overwrite sticky write times
681 : * so we must replace any sticky write time here.
682 : */
683 25 : if (!null_nttime(share_mtime)) {
684 16 : share_mode_set_changed_write_time(lck, fsp->close_write_time);
685 : }
686 25 : }
687 :
688 356995 : static NTSTATUS update_write_time_on_close(struct files_struct *fsp)
689 : {
690 593 : struct smb_file_time ft;
691 593 : NTSTATUS status;
692 :
693 356995 : init_smb_file_time(&ft);
694 :
695 356995 : if (!(fsp->fsp_flags.update_write_time_on_close)) {
696 355943 : return NT_STATUS_OK;
697 : }
698 :
699 1052 : if (is_omit_timespec(&fsp->close_write_time)) {
700 5 : fsp->close_write_time = timespec_current();
701 : }
702 :
703 : /* Ensure we have a valid stat struct for the source. */
704 1052 : status = vfs_stat_fsp(fsp);
705 1052 : if (!NT_STATUS_IS_OK(status)) {
706 0 : return status;
707 : }
708 :
709 1052 : if (!VALID_STAT(fsp->fsp_name->st)) {
710 : /* if it doesn't seem to be a real file */
711 0 : return NT_STATUS_OK;
712 : }
713 :
714 : /*
715 : * We're being called after close_remove_share_mode() inside
716 : * close_normal_file() so it's quite normal to not have an
717 : * existing share. So just ignore the result of
718 : * share_mode_do_locked_vfs_denied()...
719 : */
720 1052 : share_mode_do_locked_vfs_denied(fsp->file_id,
721 : update_write_time_on_close_share_mode_fn,
722 : fsp);
723 :
724 1052 : ft.mtime = fsp->close_write_time;
725 : /* As this is a close based update, we are not directly changing the
726 : file attributes from a client call, but indirectly from a write. */
727 1052 : status = smb_set_file_time(fsp->conn, fsp, fsp->fsp_name, &ft, false);
728 1052 : if (!NT_STATUS_IS_OK(status)) {
729 0 : DEBUG(10,("update_write_time_on_close: smb_set_file_time "
730 : "on file %s returned %s\n",
731 : fsp_str_dbg(fsp),
732 : nt_errstr(status)));
733 0 : return status;
734 : }
735 :
736 1052 : return status;
737 : }
738 :
739 1423931 : static NTSTATUS ntstatus_keeperror(NTSTATUS s1, NTSTATUS s2)
740 : {
741 1423931 : if (!NT_STATUS_IS_OK(s1)) {
742 0 : return s1;
743 : }
744 1423931 : return s2;
745 : }
746 :
747 456520 : static void assert_no_pending_aio(struct files_struct *fsp,
748 : enum file_close_type close_type)
749 : {
750 456520 : struct smbXsrv_client *client = global_smbXsrv_client;
751 1559 : size_t num_connections_alive;
752 456520 : unsigned num_requests = fsp->num_aio_requests;
753 :
754 456520 : if (num_requests == 0) {
755 454959 : return;
756 : }
757 :
758 2 : num_connections_alive = smbXsrv_client_valid_connections(client);
759 :
760 2 : if (close_type == SHUTDOWN_CLOSE && num_connections_alive == 0) {
761 : /*
762 : * fsp->aio_requests and the contents (fsp->aio_requests[x])
763 : * are both independently owned by fsp and are not in a
764 : * talloc hierarchy. This allows the fsp->aio_requests array to
765 : * be reallocated independently of the array contents so it can
766 : * grow on demand.
767 : *
768 : * This means we must ensure order of deallocation
769 : * on a SHUTDOWN_CLOSE by deallocating the fsp->aio_requests[x]
770 : * contents first, as their destructors access the
771 : * fsp->aio_request array. If we don't deallocate them
772 : * first, when fsp is deallocated fsp->aio_requests
773 : * could have been deallocated *before* its contents
774 : * fsp->aio_requests[x], causing a crash.
775 : */
776 6 : while (fsp->num_aio_requests != 0) {
777 : /*
778 : * NB. We *MUST* use
779 : * talloc_free(fsp->aio_requests[0]),
780 : * and *NOT* TALLOC_FREE() here, as
781 : * TALLOC_FREE(fsp->aio_requests[0])
782 : * will overwrite any new contents of
783 : * fsp->aio_requests[0] that were
784 : * copied into it via the destructor
785 : * aio_del_req_from_fsp().
786 : *
787 : * BUG: https://bugzilla.samba.org/show_bug.cgi?id=14515
788 : */
789 4 : talloc_free(fsp->aio_requests[0]);
790 : }
791 2 : return;
792 : }
793 :
794 0 : DBG_ERR("fsp->num_aio_requests=%u\n", num_requests);
795 0 : smb_panic("can not close with outstanding aio requests");
796 1559 : return;
797 : }
798 :
799 : /****************************************************************************
800 : Close a file.
801 :
802 : close_type can be NORMAL_CLOSE=0,SHUTDOWN_CLOSE,ERROR_CLOSE.
803 : printing and magic scripts are only run on normal close.
804 : delete on close is done on normal and shutdown close.
805 : ****************************************************************************/
806 :
807 357155 : static NTSTATUS close_normal_file(struct smb_request *req, files_struct *fsp,
808 : enum file_close_type close_type)
809 : {
810 357155 : NTSTATUS status = NT_STATUS_OK;
811 593 : NTSTATUS tmp;
812 357155 : connection_struct *conn = fsp->conn;
813 357155 : bool is_durable = false;
814 :
815 357155 : SMB_ASSERT(fsp->fsp_flags.is_fsa);
816 :
817 357155 : assert_no_pending_aio(fsp, close_type);
818 :
819 357203 : while (talloc_array_length(fsp->blocked_smb1_lock_reqs) != 0) {
820 48 : smbd_smb1_brl_finish_by_req(
821 48 : fsp->blocked_smb1_lock_reqs[0],
822 48 : NT_STATUS_RANGE_NOT_LOCKED);
823 : }
824 :
825 : /*
826 : * If we're flushing on a close we can get a write
827 : * error here, we must remember this.
828 : */
829 :
830 357155 : if (NT_STATUS_IS_OK(status) && fsp->op != NULL) {
831 349259 : is_durable = fsp->op->global->durable;
832 : }
833 :
834 357155 : if (close_type != SHUTDOWN_CLOSE) {
835 355642 : is_durable = false;
836 : }
837 :
838 356579 : if (is_durable) {
839 168 : DATA_BLOB new_cookie = data_blob_null;
840 :
841 168 : tmp = SMB_VFS_DURABLE_DISCONNECT(fsp,
842 : fsp->op->global->backend_cookie,
843 : fsp->op,
844 : &new_cookie);
845 168 : if (NT_STATUS_IS_OK(tmp)) {
846 0 : struct timeval tv;
847 0 : NTTIME now;
848 :
849 160 : if (req != NULL) {
850 28 : tv = req->request_time;
851 : } else {
852 132 : tv = timeval_current();
853 : }
854 160 : now = timeval_to_nttime(&tv);
855 :
856 160 : data_blob_free(&fsp->op->global->backend_cookie);
857 160 : fsp->op->global->backend_cookie = new_cookie;
858 :
859 160 : fsp->op->compat = NULL;
860 160 : tmp = smbXsrv_open_close(fsp->op, now);
861 160 : if (!NT_STATUS_IS_OK(tmp)) {
862 0 : DEBUG(1, ("Failed to update smbXsrv_open "
863 : "record when disconnecting durable "
864 : "handle for file %s: %s - "
865 : "proceeding with normal close\n",
866 : fsp_str_dbg(fsp), nt_errstr(tmp)));
867 : }
868 160 : scavenger_schedule_disconnected(fsp);
869 : } else {
870 8 : DEBUG(1, ("Failed to disconnect durable handle for "
871 : "file %s: %s - proceeding with normal "
872 : "close\n", fsp_str_dbg(fsp), nt_errstr(tmp)));
873 : }
874 168 : if (!NT_STATUS_IS_OK(tmp)) {
875 8 : is_durable = false;
876 : }
877 : }
878 :
879 357155 : if (is_durable) {
880 : /*
881 : * This is the case where we successfully disconnected
882 : * a durable handle and closed the underlying file.
883 : * In all other cases, we proceed with a genuine close.
884 : */
885 160 : DEBUG(10, ("%s disconnected durable handle for file %s\n",
886 : conn->session_info->unix_info->unix_name,
887 : fsp_str_dbg(fsp)));
888 160 : return NT_STATUS_OK;
889 : }
890 :
891 356995 : if (fsp->op != NULL) {
892 : /*
893 : * Make sure the handle is not marked as durable anymore
894 : */
895 349099 : fsp->op->global->durable = false;
896 : }
897 :
898 : /* If this is an old DOS or FCB open and we have multiple opens on
899 : the same handle we only have one share mode. Ensure we only remove
900 : the share mode on the last close. */
901 :
902 356995 : if (fh_get_refcount(fsp->fh) == 1) {
903 : /* Should we return on error here... ? */
904 356882 : tmp = close_remove_share_mode(fsp, close_type);
905 356882 : status = ntstatus_keeperror(status, tmp);
906 : }
907 :
908 356995 : locking_close_file(fsp, close_type);
909 :
910 : /*
911 : * Ensure pending modtime is set before closing underlying fd.
912 : */
913 :
914 356995 : tmp = update_write_time_on_close(fsp);
915 356995 : if (NT_STATUS_EQUAL(tmp, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
916 : /*
917 : * Someone renamed the file or a parent directory containing
918 : * this file. We can't do anything about this, eat the error.
919 : */
920 0 : tmp = NT_STATUS_OK;
921 : }
922 356995 : status = ntstatus_keeperror(status, tmp);
923 :
924 356995 : tmp = fd_close(fsp);
925 356995 : status = ntstatus_keeperror(status, tmp);
926 :
927 : /* check for magic scripts */
928 356995 : if (close_type == NORMAL_CLOSE) {
929 353651 : tmp = check_magic(fsp);
930 353651 : status = ntstatus_keeperror(status, tmp);
931 : }
932 :
933 356995 : DEBUG(2,("%s closed file %s (numopen=%d) %s\n",
934 : conn->session_info->unix_info->unix_name, fsp_str_dbg(fsp),
935 : conn->num_files_open - 1,
936 : nt_errstr(status) ));
937 :
938 356995 : return status;
939 : }
940 : /****************************************************************************
941 : Function used by reply_rmdir to delete an entire directory
942 : tree recursively. Return True on ok, False on fail.
943 : ****************************************************************************/
944 :
945 0 : NTSTATUS recursive_rmdir(TALLOC_CTX *ctx,
946 : connection_struct *conn,
947 : struct smb_filename *smb_dname)
948 : {
949 0 : const char *dname = NULL;
950 0 : char *talloced = NULL;
951 0 : struct smb_Dir *dir_hnd = NULL;
952 0 : struct files_struct *dirfsp = NULL;
953 0 : int retval;
954 0 : NTSTATUS status = NT_STATUS_OK;
955 :
956 0 : SMB_ASSERT(!is_ntfs_stream_smb_fname(smb_dname));
957 :
958 0 : status = OpenDir(talloc_tos(),
959 : conn,
960 : smb_dname,
961 : NULL,
962 : 0,
963 : &dir_hnd);
964 0 : if (!NT_STATUS_IS_OK(status)) {
965 0 : return status;
966 : }
967 :
968 0 : dirfsp = dir_hnd_fetch_fsp(dir_hnd);
969 :
970 0 : while ((dname = ReadDirName(dir_hnd, &talloced))) {
971 0 : struct smb_filename *atname = NULL;
972 0 : struct smb_filename *smb_dname_full = NULL;
973 0 : char *fullname = NULL;
974 0 : bool do_break = true;
975 0 : int unlink_flags = 0;
976 :
977 0 : if (ISDOT(dname) || ISDOTDOT(dname)) {
978 0 : TALLOC_FREE(talloced);
979 0 : continue;
980 : }
981 :
982 : /* Construct the full name. */
983 0 : fullname = talloc_asprintf(ctx,
984 : "%s/%s",
985 : smb_dname->base_name,
986 : dname);
987 0 : if (!fullname) {
988 0 : status = NT_STATUS_NO_MEMORY;
989 0 : goto err_break;
990 : }
991 :
992 0 : smb_dname_full = synthetic_smb_fname(talloc_tos(),
993 : fullname,
994 : NULL,
995 : NULL,
996 : smb_dname->twrp,
997 : smb_dname->flags);
998 0 : if (smb_dname_full == NULL) {
999 0 : status = NT_STATUS_NO_MEMORY;
1000 0 : goto err_break;
1001 : }
1002 :
1003 0 : if (SMB_VFS_LSTAT(conn, smb_dname_full) != 0) {
1004 0 : status = map_nt_error_from_unix(errno);
1005 0 : goto err_break;
1006 : }
1007 :
1008 0 : if (smb_dname_full->st.st_ex_mode & S_IFDIR) {
1009 0 : status = recursive_rmdir(ctx, conn, smb_dname_full);
1010 0 : if (!NT_STATUS_IS_OK(status)) {
1011 0 : goto err_break;
1012 : }
1013 0 : unlink_flags = AT_REMOVEDIR;
1014 : }
1015 :
1016 0 : status = synthetic_pathref(talloc_tos(),
1017 : dirfsp,
1018 : dname,
1019 : NULL,
1020 0 : &smb_dname_full->st,
1021 : smb_dname_full->twrp,
1022 : smb_dname_full->flags,
1023 : &atname);
1024 0 : if (!NT_STATUS_IS_OK(status)) {
1025 0 : goto err_break;
1026 : }
1027 :
1028 0 : if (!is_visible_fsp(atname->fsp)) {
1029 0 : TALLOC_FREE(smb_dname_full);
1030 0 : TALLOC_FREE(fullname);
1031 0 : TALLOC_FREE(talloced);
1032 0 : TALLOC_FREE(atname);
1033 0 : continue;
1034 : }
1035 :
1036 0 : retval = SMB_VFS_UNLINKAT(conn,
1037 : dirfsp,
1038 : atname,
1039 : unlink_flags);
1040 0 : if (retval != 0) {
1041 0 : status = map_nt_error_from_unix(errno);
1042 0 : goto err_break;
1043 : }
1044 :
1045 : /* Successful iteration. */
1046 0 : do_break = false;
1047 :
1048 0 : err_break:
1049 0 : TALLOC_FREE(smb_dname_full);
1050 0 : TALLOC_FREE(fullname);
1051 0 : TALLOC_FREE(talloced);
1052 0 : TALLOC_FREE(atname);
1053 0 : if (do_break) {
1054 0 : break;
1055 : }
1056 : }
1057 0 : TALLOC_FREE(dir_hnd);
1058 0 : return status;
1059 : }
1060 :
1061 : /****************************************************************************
1062 : The internals of the rmdir code - called elsewhere.
1063 : ****************************************************************************/
1064 :
1065 11095 : static NTSTATUS rmdir_internals(TALLOC_CTX *ctx, struct files_struct *fsp)
1066 : {
1067 11095 : struct connection_struct *conn = fsp->conn;
1068 11095 : struct smb_filename *smb_dname = fsp->fsp_name;
1069 11095 : struct smb_filename *parent_fname = NULL;
1070 11095 : struct smb_filename *at_fname = NULL;
1071 11095 : const char *dname = NULL;
1072 11095 : char *talloced = NULL;
1073 11095 : struct smb_Dir *dir_hnd = NULL;
1074 11095 : struct files_struct *dirfsp = NULL;
1075 11095 : int unlink_flags = 0;
1076 64 : NTSTATUS status;
1077 64 : int ret;
1078 :
1079 11095 : SMB_ASSERT(!is_ntfs_stream_smb_fname(smb_dname));
1080 :
1081 11095 : status = parent_pathref(talloc_tos(),
1082 : conn->cwd_fsp,
1083 11095 : fsp->fsp_name,
1084 : &parent_fname,
1085 : &at_fname);
1086 11095 : if (!NT_STATUS_IS_OK(status)) {
1087 0 : return status;
1088 : }
1089 :
1090 : /*
1091 : * Todo: use SMB_VFS_STATX() once it's available.
1092 : */
1093 :
1094 : /* Might be a symlink. */
1095 11095 : ret = SMB_VFS_LSTAT(conn, smb_dname);
1096 11095 : if (ret != 0) {
1097 0 : TALLOC_FREE(parent_fname);
1098 0 : return map_nt_error_from_unix(errno);
1099 : }
1100 :
1101 11095 : if (S_ISLNK(smb_dname->st.st_ex_mode)) {
1102 : /* Is what it points to a directory ? */
1103 0 : ret = SMB_VFS_STAT(conn, smb_dname);
1104 0 : if (ret != 0) {
1105 0 : TALLOC_FREE(parent_fname);
1106 0 : return map_nt_error_from_unix(errno);
1107 : }
1108 0 : if (!(S_ISDIR(smb_dname->st.st_ex_mode))) {
1109 0 : TALLOC_FREE(parent_fname);
1110 0 : return NT_STATUS_NOT_A_DIRECTORY;
1111 : }
1112 : } else {
1113 11031 : unlink_flags = AT_REMOVEDIR;
1114 : }
1115 :
1116 11095 : ret = SMB_VFS_UNLINKAT(conn,
1117 : parent_fname->fsp,
1118 : at_fname,
1119 : unlink_flags);
1120 11095 : if (ret == 0) {
1121 11087 : TALLOC_FREE(parent_fname);
1122 11087 : notify_fname(conn, NOTIFY_ACTION_REMOVED,
1123 : FILE_NOTIFY_CHANGE_DIR_NAME,
1124 11087 : smb_dname->base_name);
1125 11087 : return NT_STATUS_OK;
1126 : }
1127 :
1128 8 : if (!((errno == ENOTEMPTY) || (errno == EEXIST))) {
1129 0 : DEBUG(3,("rmdir_internals: couldn't remove directory %s : "
1130 : "%s\n", smb_fname_str_dbg(smb_dname),
1131 : strerror(errno)));
1132 0 : TALLOC_FREE(parent_fname);
1133 0 : return map_nt_error_from_unix(errno);
1134 : }
1135 :
1136 : /*
1137 : * Here we know the initial directory unlink failed with
1138 : * ENOTEMPTY or EEXIST so we know there are objects within.
1139 : * If we don't have permission to delete files non
1140 : * visible to the client just fail the directory delete.
1141 : */
1142 :
1143 8 : if (!lp_delete_veto_files(SNUM(conn))) {
1144 2 : status = NT_STATUS_DIRECTORY_NOT_EMPTY;
1145 2 : goto err;
1146 : }
1147 :
1148 : /*
1149 : * Check to see if the only thing in this directory are
1150 : * files non-visible to the client. If not, fail the delete.
1151 : */
1152 :
1153 6 : status = OpenDir(talloc_tos(),
1154 : conn,
1155 : smb_dname,
1156 : NULL,
1157 : 0,
1158 : &dir_hnd);
1159 6 : if (!NT_STATUS_IS_OK(status)) {
1160 : /*
1161 : * Note, we deliberately squash the error here
1162 : * to avoid leaking information about what we
1163 : * can't delete.
1164 : */
1165 0 : status = NT_STATUS_DIRECTORY_NOT_EMPTY;
1166 0 : goto err;
1167 : }
1168 :
1169 6 : dirfsp = dir_hnd_fetch_fsp(dir_hnd);
1170 :
1171 22 : while ((dname = ReadDirName(dir_hnd, &talloced)) != NULL) {
1172 18 : struct smb_filename *smb_dname_full = NULL;
1173 18 : struct smb_filename *direntry_fname = NULL;
1174 18 : char *fullname = NULL;
1175 0 : int retval;
1176 :
1177 18 : if (ISDOT(dname) || ISDOTDOT(dname)) {
1178 12 : TALLOC_FREE(talloced);
1179 16 : continue;
1180 : }
1181 6 : if (IS_VETO_PATH(conn, dname)) {
1182 2 : TALLOC_FREE(talloced);
1183 2 : continue;
1184 : }
1185 :
1186 4 : fullname = talloc_asprintf(talloc_tos(),
1187 : "%s/%s",
1188 : smb_dname->base_name,
1189 : dname);
1190 :
1191 4 : if (fullname == NULL) {
1192 0 : TALLOC_FREE(talloced);
1193 0 : status = NT_STATUS_NO_MEMORY;
1194 0 : goto err;
1195 : }
1196 :
1197 4 : smb_dname_full = synthetic_smb_fname(talloc_tos(),
1198 : fullname,
1199 : NULL,
1200 : NULL,
1201 : smb_dname->twrp,
1202 : smb_dname->flags);
1203 4 : if (smb_dname_full == NULL) {
1204 0 : TALLOC_FREE(talloced);
1205 0 : TALLOC_FREE(fullname);
1206 0 : status = NT_STATUS_NO_MEMORY;
1207 0 : goto err;
1208 : }
1209 :
1210 4 : retval = SMB_VFS_LSTAT(conn, smb_dname_full);
1211 4 : if (retval != 0) {
1212 0 : status = map_nt_error_from_unix(errno);
1213 0 : TALLOC_FREE(talloced);
1214 0 : TALLOC_FREE(fullname);
1215 0 : TALLOC_FREE(smb_dname_full);
1216 0 : goto err;
1217 : }
1218 :
1219 4 : if (S_ISLNK(smb_dname_full->st.st_ex_mode)) {
1220 : /* Could it be an msdfs link ? */
1221 4 : if (lp_host_msdfs() &&
1222 2 : lp_msdfs_root(SNUM(conn))) {
1223 0 : struct smb_filename *smb_atname;
1224 0 : smb_atname = synthetic_smb_fname(talloc_tos(),
1225 : dname,
1226 : NULL,
1227 0 : &smb_dname_full->st,
1228 0 : fsp->fsp_name->twrp,
1229 0 : fsp->fsp_name->flags);
1230 0 : if (smb_atname == NULL) {
1231 0 : TALLOC_FREE(talloced);
1232 0 : TALLOC_FREE(fullname);
1233 0 : TALLOC_FREE(smb_dname_full);
1234 0 : status = NT_STATUS_NO_MEMORY;
1235 0 : goto err;
1236 : }
1237 0 : if (is_msdfs_link(fsp, smb_atname)) {
1238 0 : TALLOC_FREE(talloced);
1239 0 : TALLOC_FREE(fullname);
1240 0 : TALLOC_FREE(smb_dname_full);
1241 0 : TALLOC_FREE(smb_atname);
1242 0 : DBG_DEBUG("got msdfs link name %s "
1243 : "- can't delete directory %s\n",
1244 : dname,
1245 : fsp_str_dbg(fsp));
1246 0 : status = NT_STATUS_DIRECTORY_NOT_EMPTY;
1247 0 : goto err;
1248 : }
1249 0 : TALLOC_FREE(smb_atname);
1250 : }
1251 :
1252 : /* Not a DFS link - could it be a dangling symlink ? */
1253 2 : retval = SMB_VFS_STAT(conn, smb_dname_full);
1254 2 : if (retval == -1 && (errno == ENOENT || errno == ELOOP)) {
1255 : /*
1256 : * Dangling symlink.
1257 : * Allow delete as "delete veto files = yes"
1258 : */
1259 2 : TALLOC_FREE(talloced);
1260 2 : TALLOC_FREE(fullname);
1261 2 : TALLOC_FREE(smb_dname_full);
1262 2 : continue;
1263 : }
1264 :
1265 0 : DBG_DEBUG("got symlink name %s - "
1266 : "can't delete directory %s\n",
1267 : dname,
1268 : fsp_str_dbg(fsp));
1269 0 : TALLOC_FREE(talloced);
1270 0 : TALLOC_FREE(fullname);
1271 0 : TALLOC_FREE(smb_dname_full);
1272 0 : status = NT_STATUS_DIRECTORY_NOT_EMPTY;
1273 0 : goto err;
1274 : }
1275 :
1276 : /* Not a symlink, get a pathref. */
1277 2 : status = synthetic_pathref(talloc_tos(),
1278 : dirfsp,
1279 : dname,
1280 : NULL,
1281 2 : &smb_dname_full->st,
1282 : smb_dname->twrp,
1283 : smb_dname->flags,
1284 : &direntry_fname);
1285 2 : if (!NT_STATUS_IS_OK(status)) {
1286 0 : TALLOC_FREE(talloced);
1287 0 : TALLOC_FREE(fullname);
1288 0 : TALLOC_FREE(smb_dname_full);
1289 0 : goto err;
1290 : }
1291 :
1292 2 : if (!is_visible_fsp(direntry_fname->fsp)) {
1293 0 : TALLOC_FREE(talloced);
1294 0 : TALLOC_FREE(fullname);
1295 0 : TALLOC_FREE(smb_dname_full);
1296 0 : TALLOC_FREE(direntry_fname);
1297 0 : continue;
1298 : }
1299 :
1300 : /*
1301 : * We found a client visible name.
1302 : * We cannot delete this directory.
1303 : */
1304 2 : DBG_DEBUG("got name %s - "
1305 : "can't delete directory %s\n",
1306 : dname,
1307 : fsp_str_dbg(fsp));
1308 2 : TALLOC_FREE(talloced);
1309 2 : TALLOC_FREE(fullname);
1310 2 : TALLOC_FREE(smb_dname_full);
1311 2 : TALLOC_FREE(direntry_fname);
1312 2 : status = NT_STATUS_DIRECTORY_NOT_EMPTY;
1313 2 : goto err;
1314 : }
1315 :
1316 : /* Do a recursive delete. */
1317 4 : RewindDir(dir_hnd);
1318 :
1319 16 : while ((dname = ReadDirName(dir_hnd, &talloced)) != NULL) {
1320 12 : struct smb_filename *direntry_fname = NULL;
1321 12 : struct smb_filename *smb_dname_full = NULL;
1322 12 : char *fullname = NULL;
1323 12 : bool do_break = true;
1324 0 : int retval;
1325 :
1326 12 : if (ISDOT(dname) || ISDOTDOT(dname)) {
1327 8 : TALLOC_FREE(talloced);
1328 8 : continue;
1329 : }
1330 :
1331 4 : fullname = talloc_asprintf(ctx,
1332 : "%s/%s",
1333 : smb_dname->base_name,
1334 : dname);
1335 :
1336 4 : if (fullname == NULL) {
1337 0 : status = NT_STATUS_NO_MEMORY;
1338 0 : goto err_break;
1339 : }
1340 :
1341 4 : smb_dname_full = synthetic_smb_fname(talloc_tos(),
1342 : fullname,
1343 : NULL,
1344 : NULL,
1345 : smb_dname->twrp,
1346 : smb_dname->flags);
1347 4 : if (smb_dname_full == NULL) {
1348 0 : status = NT_STATUS_NO_MEMORY;
1349 0 : goto err_break;
1350 : }
1351 :
1352 : /*
1353 : * Todo: use SMB_VFS_STATX() once that's available.
1354 : */
1355 :
1356 4 : retval = SMB_VFS_LSTAT(conn, smb_dname_full);
1357 4 : if (retval != 0) {
1358 0 : status = map_nt_error_from_unix(errno);
1359 0 : goto err_break;
1360 : }
1361 :
1362 : /*
1363 : * We are only dealing with VETO'ed objects
1364 : * here. If it's a symlink, just delete the
1365 : * link without caring what it is pointing
1366 : * to.
1367 : */
1368 4 : if (S_ISLNK(smb_dname_full->st.st_ex_mode)) {
1369 2 : direntry_fname = synthetic_smb_fname(talloc_tos(),
1370 : dname,
1371 : NULL,
1372 2 : &smb_dname_full->st,
1373 : smb_dname->twrp,
1374 : smb_dname->flags);
1375 2 : if (direntry_fname == NULL) {
1376 0 : status = NT_STATUS_NO_MEMORY;
1377 0 : goto err_break;
1378 : }
1379 : } else {
1380 2 : status = synthetic_pathref(talloc_tos(),
1381 : dirfsp,
1382 : dname,
1383 : NULL,
1384 2 : &smb_dname_full->st,
1385 : smb_dname->twrp,
1386 : smb_dname->flags,
1387 : &direntry_fname);
1388 2 : if (!NT_STATUS_IS_OK(status)) {
1389 0 : goto err_break;
1390 : }
1391 :
1392 2 : if (!is_visible_fsp(direntry_fname->fsp)) {
1393 0 : TALLOC_FREE(fullname);
1394 0 : TALLOC_FREE(smb_dname_full);
1395 0 : TALLOC_FREE(talloced);
1396 0 : TALLOC_FREE(direntry_fname);
1397 0 : continue;
1398 : }
1399 : }
1400 :
1401 4 : unlink_flags = 0;
1402 :
1403 4 : if (smb_dname_full->st.st_ex_mode & S_IFDIR) {
1404 0 : status = recursive_rmdir(ctx, conn, smb_dname_full);
1405 0 : if (!NT_STATUS_IS_OK(status)) {
1406 0 : goto err_break;
1407 : }
1408 0 : unlink_flags = AT_REMOVEDIR;
1409 : }
1410 :
1411 4 : retval = SMB_VFS_UNLINKAT(conn,
1412 : dirfsp,
1413 : direntry_fname,
1414 : unlink_flags);
1415 4 : if (retval != 0) {
1416 0 : status = map_nt_error_from_unix(errno);
1417 0 : goto err_break;
1418 : }
1419 :
1420 : /* Successful iteration. */
1421 4 : do_break = false;
1422 :
1423 4 : err_break:
1424 4 : TALLOC_FREE(fullname);
1425 4 : TALLOC_FREE(smb_dname_full);
1426 4 : TALLOC_FREE(talloced);
1427 4 : TALLOC_FREE(direntry_fname);
1428 4 : if (do_break) {
1429 0 : break;
1430 : }
1431 : }
1432 :
1433 : /* If we get here, we know NT_STATUS_IS_OK(status) */
1434 4 : SMB_ASSERT(NT_STATUS_IS_OK(status));
1435 :
1436 : /* Retry the rmdir */
1437 4 : ret = SMB_VFS_UNLINKAT(conn,
1438 : parent_fname->fsp,
1439 : at_fname,
1440 : AT_REMOVEDIR);
1441 4 : if (ret != 0) {
1442 0 : status = map_nt_error_from_unix(errno);
1443 : }
1444 :
1445 4 : err:
1446 :
1447 8 : TALLOC_FREE(dir_hnd);
1448 8 : TALLOC_FREE(parent_fname);
1449 :
1450 8 : if (!NT_STATUS_IS_OK(status)) {
1451 4 : DBG_NOTICE("couldn't remove directory %s : "
1452 : "%s\n", smb_fname_str_dbg(smb_dname),
1453 : nt_errstr(status));
1454 4 : return status;
1455 : }
1456 :
1457 4 : notify_fname(conn, NOTIFY_ACTION_REMOVED,
1458 : FILE_NOTIFY_CHANGE_DIR_NAME,
1459 4 : smb_dname->base_name);
1460 :
1461 4 : return status;
1462 : }
1463 :
1464 : /****************************************************************************
1465 : Close a directory opened by an NT SMB call.
1466 : ****************************************************************************/
1467 :
1468 82508 : static NTSTATUS close_directory(struct smb_request *req, files_struct *fsp,
1469 : enum file_close_type close_type)
1470 : {
1471 82508 : connection_struct *conn = fsp->conn;
1472 82508 : struct close_share_mode_lock_state lck_state = {};
1473 82508 : bool changed_user = false;
1474 82508 : NTSTATUS status = NT_STATUS_OK;
1475 82508 : NTSTATUS status1 = NT_STATUS_OK;
1476 346 : NTSTATUS notify_status;
1477 346 : NTSTATUS ulstatus;
1478 :
1479 82508 : SMB_ASSERT(fsp->fsp_flags.is_fsa);
1480 :
1481 82508 : if (fsp->conn->sconn->using_smb2) {
1482 58631 : notify_status = NT_STATUS_NOTIFY_CLEANUP;
1483 : } else {
1484 23877 : notify_status = NT_STATUS_OK;
1485 : }
1486 :
1487 82508 : assert_no_pending_aio(fsp, close_type);
1488 :
1489 : /*
1490 : * NT can set delete_on_close of the last open
1491 : * reference to a directory also.
1492 : */
1493 :
1494 82508 : lck_state = (struct close_share_mode_lock_state) {
1495 : .fsp = fsp,
1496 : .object_type = "directory",
1497 : .close_type = close_type,
1498 : };
1499 :
1500 82508 : status = share_mode_entry_prepare_lock_del(&lck_state.prepare_state,
1501 : fsp->file_id,
1502 : close_share_mode_lock_prepare,
1503 346 : &lck_state);
1504 82508 : if (!NT_STATUS_IS_OK(status)) {
1505 0 : DBG_ERR("share_mode_entry_prepare_lock_del() failed for %s - %s\n",
1506 : fsp_str_dbg(fsp), nt_errstr(status));
1507 0 : return status;
1508 : }
1509 :
1510 : /*
1511 : * We don't have directory leases yet, so assert it in order
1512 : * to skip release_file_oplock().
1513 : */
1514 82508 : SMB_ASSERT(fsp->oplock_type == NO_OPLOCK);
1515 :
1516 : /*
1517 : * NT can set delete_on_close of the last open
1518 : * reference to a file.
1519 : */
1520 :
1521 82508 : if (!lck_state.delete_object) {
1522 71413 : status = NT_STATUS_OK;
1523 71413 : goto done;
1524 : }
1525 :
1526 : /*
1527 : * Ok, we have to delete the directory
1528 : */
1529 11095 : lck_state.cleanup_fn = close_share_mode_lock_cleanup;
1530 :
1531 11159 : if (lck_state.got_tokens &&
1532 11095 : !unix_token_equal(lck_state.del_token, get_current_utok(conn)))
1533 : {
1534 : /* Become the user who requested the delete. */
1535 :
1536 11 : DBG_INFO("dir %s. Change user to uid %u\n",
1537 : fsp_str_dbg(fsp),
1538 : (unsigned int)lck_state.del_token->uid);
1539 :
1540 11 : if (!push_sec_ctx()) {
1541 0 : smb_panic("close_directory: failed to push sec_ctx.\n");
1542 : }
1543 :
1544 11 : set_sec_ctx(lck_state.del_token->uid,
1545 11 : lck_state.del_token->gid,
1546 11 : lck_state.del_token->ngroups,
1547 11 : lck_state.del_token->groups,
1548 : lck_state.del_nt_token);
1549 :
1550 11 : changed_user = true;
1551 : }
1552 :
1553 11095 : if ((fsp->conn->fs_capabilities & FILE_NAMED_STREAMS)
1554 10548 : && !is_ntfs_stream_smb_fname(fsp->fsp_name)) {
1555 :
1556 10548 : status = delete_all_streams(fsp->conn, fsp->fsp_name);
1557 10548 : if (!NT_STATUS_IS_OK(status)) {
1558 0 : DEBUG(5, ("delete_all_streams failed: %s\n",
1559 : nt_errstr(status)));
1560 0 : goto done;
1561 : }
1562 : }
1563 :
1564 11095 : status = rmdir_internals(talloc_tos(), fsp);
1565 :
1566 11095 : DEBUG(5,("close_directory: %s. Delete on close was set - "
1567 : "deleting directory returned %s.\n",
1568 : fsp_str_dbg(fsp), nt_errstr(status)));
1569 :
1570 : /*
1571 : * Ensure we remove any change notify requests that would
1572 : * now fail as the directory has been deleted.
1573 : */
1574 :
1575 11095 : if (NT_STATUS_IS_OK(status)) {
1576 11091 : notify_status = NT_STATUS_DELETE_PENDING;
1577 : }
1578 :
1579 4 : done:
1580 82508 : if (changed_user) {
1581 : /* unbecome user. */
1582 11 : pop_sec_ctx();
1583 : }
1584 :
1585 82508 : ulstatus = share_mode_entry_prepare_unlock(&lck_state.prepare_state,
1586 : lck_state.cleanup_fn,
1587 346 : &lck_state);
1588 82508 : if (!NT_STATUS_IS_OK(ulstatus)) {
1589 0 : DBG_ERR("share_mode_entry_prepare_unlock() failed for %s - %s\n",
1590 : fsp_str_dbg(fsp), nt_errstr(ulstatus));
1591 0 : smb_panic("share_mode_entry_prepare_unlock() failed!");
1592 : }
1593 :
1594 82508 : remove_pending_change_notify_requests_by_fid(fsp, notify_status);
1595 :
1596 82508 : status1 = fd_close(fsp);
1597 :
1598 82508 : if (!NT_STATUS_IS_OK(status1)) {
1599 0 : DEBUG(0, ("Could not close dir! fname=%s, fd=%d, err=%d=%s\n",
1600 : fsp_str_dbg(fsp), fsp_get_pathref_fd(fsp), errno,
1601 : strerror(errno)));
1602 : }
1603 :
1604 82508 : if (NT_STATUS_IS_OK(status) && !NT_STATUS_IS_OK(status1)) {
1605 0 : status = status1;
1606 : }
1607 82508 : return status;
1608 : }
1609 :
1610 : /****************************************************************************
1611 : Rundown all SMB-related dependencies of a files struct
1612 : ****************************************************************************/
1613 :
1614 582479 : NTSTATUS close_file_smb(struct smb_request *req,
1615 : struct files_struct *fsp,
1616 : enum file_close_type close_type)
1617 : {
1618 2121 : NTSTATUS status;
1619 :
1620 : /*
1621 : * This fsp can never be an internal dirfsp. They must
1622 : * be explicitly closed by TALLOC_FREE of the dir handle.
1623 : */
1624 582479 : SMB_ASSERT(!fsp->fsp_flags.is_dirfsp);
1625 :
1626 : /*
1627 : * Never call directly on a base fsp
1628 : */
1629 582479 : SMB_ASSERT(fsp->stream_fsp == NULL);
1630 :
1631 582479 : if (fsp->fake_file_handle != NULL) {
1632 : /*
1633 : * Named pipes are opened as fake files and
1634 : * can have pending aio requests. Ensure
1635 : * we clear out all pending aio on force
1636 : * shutdown of named pipes also.
1637 : * BUG: https://bugzilla.samba.org/show_bug.cgi?id=15423
1638 : */
1639 16857 : assert_no_pending_aio(fsp, close_type);
1640 16857 : status = close_fake_file(req, fsp);
1641 565622 : } else if (fsp->print_file != NULL) {
1642 : /* FIXME: return spool errors */
1643 28 : print_spool_end(fsp, close_type);
1644 28 : fd_close(fsp);
1645 28 : status = NT_STATUS_OK;
1646 565594 : } else if (!fsp->fsp_flags.is_fsa) {
1647 125931 : if (close_type == NORMAL_CLOSE) {
1648 0 : DBG_ERR("unexpected NORMAL_CLOSE for [%s] "
1649 : "is_fsa[%u] is_pathref[%u] is_directory[%u]\n",
1650 : fsp_str_dbg(fsp),
1651 : fsp->fsp_flags.is_fsa,
1652 : fsp->fsp_flags.is_pathref,
1653 : fsp->fsp_flags.is_directory);
1654 : }
1655 125931 : SMB_ASSERT(close_type != NORMAL_CLOSE);
1656 125931 : fd_close(fsp);
1657 125931 : status = NT_STATUS_OK;
1658 439663 : } else if (fsp->fsp_flags.is_directory) {
1659 82508 : status = close_directory(req, fsp, close_type);
1660 : } else {
1661 357155 : status = close_normal_file(req, fsp, close_type);
1662 : }
1663 :
1664 582479 : if (fsp_is_alternate_stream(fsp)) {
1665 : /*
1666 : * fsp was a stream, its base_fsp can't be a stream
1667 : * as well
1668 : */
1669 7229 : SMB_ASSERT(!fsp_is_alternate_stream(fsp->base_fsp));
1670 :
1671 : /*
1672 : * There's a 1:1 relationship between fsp and a base_fsp
1673 : */
1674 7229 : SMB_ASSERT(fsp->base_fsp->stream_fsp == fsp);
1675 :
1676 : /*
1677 : * Make base_fsp look standalone now
1678 : */
1679 7229 : fsp->base_fsp->stream_fsp = NULL;
1680 :
1681 7229 : close_file_free(req, &fsp->base_fsp, close_type);
1682 : }
1683 :
1684 582479 : fsp_unbind_smb(req, fsp);
1685 :
1686 582479 : return status;
1687 : }
1688 :
1689 98781 : NTSTATUS close_file_free(struct smb_request *req,
1690 : struct files_struct **_fsp,
1691 : enum file_close_type close_type)
1692 : {
1693 98781 : struct files_struct *fsp = *_fsp;
1694 1059 : NTSTATUS status;
1695 :
1696 98781 : status = close_file_smb(req, fsp, close_type);
1697 :
1698 98781 : file_free(req, fsp);
1699 98781 : *_fsp = NULL;
1700 :
1701 98781 : return status;
1702 : }
1703 :
1704 : /****************************************************************************
1705 : Deal with an (authorized) message to close a file given the share mode
1706 : entry.
1707 : ****************************************************************************/
1708 :
1709 0 : void msg_close_file(struct messaging_context *msg_ctx,
1710 : void *private_data,
1711 : uint32_t msg_type,
1712 : struct server_id server_id,
1713 : DATA_BLOB *data)
1714 : {
1715 0 : files_struct *fsp = NULL;
1716 0 : struct file_id id;
1717 0 : struct share_mode_entry e;
1718 0 : struct smbd_server_connection *sconn =
1719 0 : talloc_get_type_abort(private_data,
1720 : struct smbd_server_connection);
1721 :
1722 0 : message_to_share_mode_entry(&id, &e, (char *)data->data);
1723 :
1724 0 : if(DEBUGLVL(10)) {
1725 0 : char *sm_str = share_mode_str(NULL, 0, &id, &e);
1726 0 : if (!sm_str) {
1727 0 : smb_panic("talloc failed");
1728 : }
1729 0 : DEBUG(10,("msg_close_file: got request to close share mode "
1730 : "entry %s\n", sm_str));
1731 0 : TALLOC_FREE(sm_str);
1732 : }
1733 :
1734 0 : fsp = file_find_dif(sconn, id, e.share_file_id);
1735 0 : if (!fsp) {
1736 0 : DEBUG(10,("msg_close_file: failed to find file.\n"));
1737 0 : return;
1738 : }
1739 0 : close_file_free(NULL, &fsp, NORMAL_CLOSE);
1740 : }
|