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