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 353663 : static NTSTATUS check_magic(struct files_struct *fsp)
44 : {
45 576 : int ret;
46 576 : const struct loadparm_substitution *lp_sub =
47 353663 : loadparm_s3_global_substitution();
48 353663 : const char *magic_output = NULL;
49 576 : SMB_STRUCT_STAT st;
50 576 : int tmp_fd, outfd;
51 353663 : TALLOC_CTX *ctx = NULL;
52 576 : const char *p;
53 353663 : struct connection_struct *conn = fsp->conn;
54 353663 : char *fname = NULL;
55 576 : NTSTATUS status;
56 :
57 353663 : if (!*lp_magic_script(talloc_tos(), lp_sub, SNUM(conn))) {
58 353663 : 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 149291 : NTSTATUS delete_all_streams(connection_struct *conn,
154 : const struct smb_filename *smb_fname)
155 : {
156 149291 : struct stream_struct *stream_info = NULL;
157 381 : unsigned int i;
158 149291 : unsigned int num_streams = 0;
159 149291 : TALLOC_CTX *frame = talloc_stackframe();
160 381 : NTSTATUS status;
161 :
162 149291 : status = vfs_fstreaminfo(smb_fname->fsp, talloc_tos(),
163 : &num_streams, &stream_info);
164 :
165 149291 : 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 149291 : 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 149291 : DEBUG(10, ("delete_all_streams found %d streams\n",
178 : num_streams));
179 :
180 149291 : if (num_streams == 0) {
181 10552 : TALLOC_FREE(frame);
182 10552 : return NT_STATUS_OK;
183 : }
184 :
185 278096 : for (i=0; i<num_streams; i++) {
186 318 : int res;
187 318 : struct smb_filename *smb_fname_stream;
188 :
189 139357 : if (strequal(stream_info[i].name, "::$DATA")) {
190 138684 : 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 138739 : fail:
225 138739 : TALLOC_FREE(frame);
226 138739 : return status;
227 : }
228 :
229 : struct has_other_nonposix_opens_state {
230 : files_struct *fsp;
231 : bool found_another;
232 : };
233 :
234 170999 : static bool has_other_nonposix_opens_fn(
235 : struct share_mode_entry *e,
236 : bool *modified,
237 : void *private_data)
238 : {
239 170999 : struct has_other_nonposix_opens_state *state = private_data;
240 170999 : struct files_struct *fsp = state->fsp;
241 :
242 170999 : if (e->name_hash != fsp->name_hash) {
243 4 : return false;
244 : }
245 170995 : if (e->flags & SHARE_MODE_FLAG_POSIX_OPEN) {
246 1592 : return false;
247 : }
248 169403 : if (e->share_file_id == fh_get_gen_id(fsp->fh)) {
249 169147 : struct server_id self = messaging_server_id(
250 169147 : fsp->conn->sconn->msg_ctx);
251 169147 : if (server_id_equal(&self, &e->pid)) {
252 169146 : 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 170812 : bool has_other_nonposix_opens(struct share_mode_lock *lck,
264 : struct files_struct *fsp)
265 : {
266 170812 : struct has_other_nonposix_opens_state state = { .fsp = fsp };
267 350 : bool ok;
268 :
269 170812 : ok = share_mode_forall_entries(
270 : lck, has_other_nonposix_opens_fn, &state);
271 170812 : if (!ok) {
272 0 : return false;
273 : }
274 170812 : 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 441251 : static void close_share_mode_lock_prepare(struct share_mode_lock *lck,
291 : bool *keep_locked,
292 : void *private_data)
293 : {
294 441251 : struct close_share_mode_lock_state *state =
295 : (struct close_share_mode_lock_state *)private_data;
296 441251 : 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 441251 : *keep_locked = false;
305 :
306 441251 : 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 441251 : 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 440284 : } else if (fsp->fsp_flags.update_write_time_on_close) {
327 : /* Someone had a pending write. */
328 100 : if (is_omit_timespec(&fsp->close_write_time)) {
329 69 : 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 69 : 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 441391 : if (fsp->fsp_flags.initial_delete_on_close &&
342 137010 : !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 137003 : fsp->fsp_flags.delete_on_close = true;
347 137003 : set_delete_on_close_lck(fsp, lck,
348 137003 : fsp->conn->session_info->security_token,
349 137003 : fsp->conn->session_info->unix_token);
350 : }
351 :
352 611815 : state->delete_object = is_delete_on_close_set(lck, fsp->name_hash) &&
353 170564 : !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 441251 : normal_close = (state->close_type == NORMAL_CLOSE || state->close_type == SHUTDOWN_CLOSE);
361 441251 : 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 441251 : if (!state->delete_object) {
369 270936 : ok = del_share_mode(lck, fsp);
370 270936 : 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 270936 : 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 170315 : *keep_locked = true;
384 :
385 170315 : state->got_tokens = get_delete_on_close_token(lck, fsp->name_hash,
386 : &state->del_nt_token, &state->del_token);
387 170315 : if (state->close_type != ERROR_CLOSE) {
388 170315 : SMB_ASSERT(state->got_tokens);
389 : }
390 : }
391 :
392 170315 : static void close_share_mode_lock_cleanup(struct share_mode_lock *lck,
393 : void *private_data)
394 : {
395 170315 : struct close_share_mode_lock_state *state =
396 : (struct close_share_mode_lock_state *)private_data;
397 170315 : struct files_struct *fsp = state->fsp;
398 336 : bool ok;
399 :
400 170315 : if (state->reset_delete_on_close) {
401 159216 : reset_delete_on_close_lck(fsp, lck);
402 : }
403 :
404 170315 : ok = del_share_mode(lck, fsp);
405 170315 : 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 170315 : }
410 :
411 : /****************************************************************************
412 : Deal with removing a share mode on last close.
413 : ****************************************************************************/
414 :
415 356892 : static NTSTATUS close_remove_share_mode(files_struct *fsp,
416 : enum file_close_type close_type)
417 : {
418 356892 : connection_struct *conn = fsp->conn;
419 356892 : struct close_share_mode_lock_state lck_state = {};
420 356892 : bool changed_user = false;
421 356892 : NTSTATUS status = NT_STATUS_OK;
422 592 : NTSTATUS tmp_status;
423 592 : NTSTATUS ulstatus;
424 592 : struct file_id id;
425 356892 : struct smb_filename *parent_fname = NULL;
426 356892 : struct smb_filename *base_fname = NULL;
427 592 : int ret;
428 :
429 : /* Ensure any pending write time updates are done. */
430 356892 : if (fsp->update_write_time_event) {
431 5194 : 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 356892 : lck_state = (struct close_share_mode_lock_state) {
441 : .fsp = fsp,
442 : .object_type = "file",
443 : .close_type = close_type,
444 : };
445 :
446 356892 : 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 356892 : 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 356892 : 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 356892 : if (!lck_state.delete_object) {
467 197672 : status = NT_STATUS_OK;
468 197672 : goto done;
469 : }
470 :
471 : /*
472 : * Ok, we have to delete the file
473 : */
474 159220 : lck_state.cleanup_fn = close_share_mode_lock_cleanup;
475 :
476 159220 : 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 159220 : fsp->fsp_flags.update_write_time_on_close = false;
483 :
484 159492 : if (lck_state.got_tokens &&
485 159220 : !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 159220 : tmp_status = vfs_stat_fsp(fsp);
512 159220 : 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 159220 : id = vfs_file_id_from_sbuf(conn, &fsp->fsp_name->st);
523 :
524 159220 : 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 159216 : 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 159216 : 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 159216 : status = parent_pathref(talloc_tos(),
568 : conn->cwd_fsp,
569 159216 : fsp->fsp_name,
570 : &parent_fname,
571 : &base_fname);
572 159216 : if (!NT_STATUS_IS_OK(status)) {
573 0 : goto done;
574 : }
575 :
576 159216 : ret = SMB_VFS_UNLINKAT(conn,
577 : parent_fname->fsp,
578 : base_fname,
579 : 0);
580 159216 : TALLOC_FREE(parent_fname);
581 159216 : base_fname = NULL;
582 159216 : 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 159216 : fsp->fsp_flags.delete_on_close = false;
606 159216 : lck_state.reset_delete_on_close = true;
607 :
608 356572 : done:
609 :
610 356892 : if (changed_user) {
611 : /* unbecome user. */
612 210 : pop_sec_ctx();
613 : }
614 :
615 356892 : if (fsp->fsp_flags.kernel_share_modes_taken) {
616 : /* remove filesystem sharemodes */
617 0 : ret = SMB_VFS_FILESYSTEM_SHAREMODE(fsp, 0, 0);
618 0 : if (ret == -1) {
619 0 : DBG_INFO("Removing file system sharemode for "
620 : "%s failed: %s\n",
621 : fsp_str_dbg(fsp), strerror(errno));
622 : }
623 : }
624 :
625 356892 : ulstatus = share_mode_entry_prepare_unlock(&lck_state.prepare_state,
626 : lck_state.cleanup_fn,
627 592 : &lck_state);
628 356892 : if (!NT_STATUS_IS_OK(ulstatus)) {
629 0 : DBG_ERR("share_mode_entry_prepare_unlock() failed for %s - %s\n",
630 : fsp_str_dbg(fsp), nt_errstr(ulstatus));
631 0 : smb_panic("share_mode_entry_prepare_unlock() failed!");
632 : }
633 :
634 356892 : if (lck_state.delete_object) {
635 : /*
636 : * Do the notification after we released the share
637 : * mode lock. Inside notify_fname we take out another
638 : * tdb lock. With ctdb also accessing our databases,
639 : * this can lead to deadlocks. Putting this notify
640 : * after the TALLOC_FREE(lck) above we avoid locking
641 : * two records simultaneously. Notifies are async and
642 : * informational only, so calling the notify_fname
643 : * without holding the share mode lock should not do
644 : * any harm.
645 : */
646 159220 : notify_fname(conn, NOTIFY_ACTION_REMOVED,
647 : FILE_NOTIFY_CHANGE_FILE_NAME,
648 159220 : fsp->fsp_name->base_name);
649 : }
650 :
651 356892 : return status;
652 : }
653 :
654 31988 : void set_close_write_time(struct files_struct *fsp, struct timespec ts)
655 : {
656 31988 : DEBUG(6,("close_write_time: %s" , time_to_asc(convert_timespec_to_time_t(ts))));
657 :
658 31988 : if (is_omit_timespec(&ts)) {
659 30602 : return;
660 : }
661 1098 : fsp->fsp_flags.write_time_forced = false;
662 1098 : fsp->fsp_flags.update_write_time_on_close = true;
663 1098 : fsp->close_write_time = ts;
664 : }
665 :
666 25 : static void update_write_time_on_close_share_mode_fn(struct share_mode_lock *lck,
667 : void *private_data)
668 : {
669 1 : struct files_struct *fsp =
670 25 : talloc_get_type_abort(private_data,
671 : struct files_struct);
672 25 : NTTIME share_mtime = share_mode_changed_write_time(lck);
673 :
674 : /*
675 : * On close if we're changing the real file time we
676 : * must update it in the open file db too.
677 : */
678 25 : share_mode_set_old_write_time(lck, fsp->close_write_time);
679 :
680 : /*
681 : * Close write times overwrite sticky write times
682 : * so we must replace any sticky write time here.
683 : */
684 25 : if (!null_nttime(share_mtime)) {
685 16 : share_mode_set_changed_write_time(lck, fsp->close_write_time);
686 : }
687 25 : }
688 :
689 357005 : static NTSTATUS update_write_time_on_close(struct files_struct *fsp)
690 : {
691 593 : struct smb_file_time ft;
692 593 : NTSTATUS status;
693 :
694 357005 : init_smb_file_time(&ft);
695 :
696 357005 : if (!(fsp->fsp_flags.update_write_time_on_close)) {
697 355953 : return NT_STATUS_OK;
698 : }
699 :
700 1052 : if (is_omit_timespec(&fsp->close_write_time)) {
701 5 : fsp->close_write_time = timespec_current();
702 : }
703 :
704 : /* Ensure we have a valid stat struct for the source. */
705 1052 : status = vfs_stat_fsp(fsp);
706 1052 : if (!NT_STATUS_IS_OK(status)) {
707 0 : return status;
708 : }
709 :
710 1052 : if (!VALID_STAT(fsp->fsp_name->st)) {
711 : /* if it doesn't seem to be a real file */
712 0 : return NT_STATUS_OK;
713 : }
714 :
715 : /*
716 : * We're being called after close_remove_share_mode() inside
717 : * close_normal_file() so it's quite normal to not have an
718 : * existing share. So just ignore the result of
719 : * share_mode_do_locked_vfs_denied()...
720 : */
721 1052 : share_mode_do_locked_vfs_denied(fsp->file_id,
722 : update_write_time_on_close_share_mode_fn,
723 : fsp);
724 :
725 1052 : ft.mtime = fsp->close_write_time;
726 : /* As this is a close based update, we are not directly changing the
727 : file attributes from a client call, but indirectly from a write. */
728 1052 : status = smb_set_file_time(fsp->conn, fsp, fsp->fsp_name, &ft, false);
729 1052 : if (!NT_STATUS_IS_OK(status)) {
730 0 : DEBUG(10,("update_write_time_on_close: smb_set_file_time "
731 : "on file %s returned %s\n",
732 : fsp_str_dbg(fsp),
733 : nt_errstr(status)));
734 0 : return status;
735 : }
736 :
737 1052 : return status;
738 : }
739 :
740 1423973 : static NTSTATUS ntstatus_keeperror(NTSTATUS s1, NTSTATUS s2)
741 : {
742 1423973 : if (!NT_STATUS_IS_OK(s1)) {
743 0 : return s1;
744 : }
745 1423973 : return s2;
746 : }
747 :
748 458385 : static void assert_no_pending_aio(struct files_struct *fsp,
749 : enum file_close_type close_type)
750 : {
751 458385 : struct smbXsrv_client *client = global_smbXsrv_client;
752 1559 : size_t num_connections_alive;
753 458385 : unsigned num_requests = fsp->num_aio_requests;
754 :
755 458385 : if (num_requests == 0) {
756 456824 : return;
757 : }
758 :
759 2 : num_connections_alive = smbXsrv_client_valid_connections(client);
760 :
761 2 : if (close_type == SHUTDOWN_CLOSE && num_connections_alive == 0) {
762 : /*
763 : * fsp->aio_requests and the contents (fsp->aio_requests[x])
764 : * are both independently owned by fsp and are not in a
765 : * talloc hierarchy. This allows the fsp->aio_requests array to
766 : * be reallocated independently of the array contents so it can
767 : * grow on demand.
768 : *
769 : * This means we must ensure order of deallocation
770 : * on a SHUTDOWN_CLOSE by deallocating the fsp->aio_requests[x]
771 : * contents first, as their destructors access the
772 : * fsp->aio_request array. If we don't deallocate them
773 : * first, when fsp is deallocated fsp->aio_requests
774 : * could have been deallocated *before* its contents
775 : * fsp->aio_requests[x], causing a crash.
776 : */
777 6 : while (fsp->num_aio_requests != 0) {
778 : /*
779 : * NB. We *MUST* use
780 : * talloc_free(fsp->aio_requests[0]),
781 : * and *NOT* TALLOC_FREE() here, as
782 : * TALLOC_FREE(fsp->aio_requests[0])
783 : * will overwrite any new contents of
784 : * fsp->aio_requests[0] that were
785 : * copied into it via the destructor
786 : * aio_del_req_from_fsp().
787 : *
788 : * BUG: https://bugzilla.samba.org/show_bug.cgi?id=14515
789 : */
790 4 : talloc_free(fsp->aio_requests[0]);
791 : }
792 2 : return;
793 : }
794 :
795 0 : DBG_ERR("fsp->num_aio_requests=%u\n", num_requests);
796 0 : smb_panic("can not close with outstanding aio requests");
797 1559 : return;
798 : }
799 :
800 : /****************************************************************************
801 : Close a file.
802 :
803 : close_type can be NORMAL_CLOSE=0,SHUTDOWN_CLOSE,ERROR_CLOSE.
804 : printing and magic scripts are only run on normal close.
805 : delete on close is done on normal and shutdown close.
806 : ****************************************************************************/
807 :
808 357165 : static NTSTATUS close_normal_file(struct smb_request *req, files_struct *fsp,
809 : enum file_close_type close_type)
810 : {
811 357165 : NTSTATUS status = NT_STATUS_OK;
812 593 : NTSTATUS tmp;
813 357165 : connection_struct *conn = fsp->conn;
814 357165 : bool is_durable = false;
815 :
816 357165 : SMB_ASSERT(fsp->fsp_flags.is_fsa);
817 :
818 357165 : assert_no_pending_aio(fsp, close_type);
819 :
820 357213 : while (talloc_array_length(fsp->blocked_smb1_lock_reqs) != 0) {
821 48 : smbd_smb1_brl_finish_by_req(
822 48 : fsp->blocked_smb1_lock_reqs[0],
823 48 : NT_STATUS_RANGE_NOT_LOCKED);
824 : }
825 :
826 : /*
827 : * If we're flushing on a close we can get a write
828 : * error here, we must remember this.
829 : */
830 :
831 357165 : if (NT_STATUS_IS_OK(status) && fsp->op != NULL) {
832 349269 : is_durable = fsp->op->global->durable;
833 : }
834 :
835 357165 : if (close_type != SHUTDOWN_CLOSE) {
836 355654 : is_durable = false;
837 : }
838 :
839 356589 : if (is_durable) {
840 168 : DATA_BLOB new_cookie = data_blob_null;
841 :
842 168 : tmp = SMB_VFS_DURABLE_DISCONNECT(fsp,
843 : fsp->op->global->backend_cookie,
844 : fsp->op,
845 : &new_cookie);
846 168 : if (NT_STATUS_IS_OK(tmp)) {
847 0 : struct timeval tv;
848 0 : NTTIME now;
849 :
850 160 : if (req != NULL) {
851 28 : tv = req->request_time;
852 : } else {
853 132 : tv = timeval_current();
854 : }
855 160 : now = timeval_to_nttime(&tv);
856 :
857 160 : data_blob_free(&fsp->op->global->backend_cookie);
858 160 : fsp->op->global->backend_cookie = new_cookie;
859 :
860 160 : fsp->op->compat = NULL;
861 160 : tmp = smbXsrv_open_close(fsp->op, now);
862 160 : if (!NT_STATUS_IS_OK(tmp)) {
863 0 : DEBUG(1, ("Failed to update smbXsrv_open "
864 : "record when disconnecting durable "
865 : "handle for file %s: %s - "
866 : "proceeding with normal close\n",
867 : fsp_str_dbg(fsp), nt_errstr(tmp)));
868 : }
869 160 : scavenger_schedule_disconnected(fsp);
870 : } else {
871 8 : DEBUG(1, ("Failed to disconnect durable handle for "
872 : "file %s: %s - proceeding with normal "
873 : "close\n", fsp_str_dbg(fsp), nt_errstr(tmp)));
874 : }
875 168 : if (!NT_STATUS_IS_OK(tmp)) {
876 8 : is_durable = false;
877 : }
878 : }
879 :
880 357165 : if (is_durable) {
881 : /*
882 : * This is the case where we successfully disconnected
883 : * a durable handle and closed the underlying file.
884 : * In all other cases, we proceed with a genuine close.
885 : */
886 160 : DEBUG(10, ("%s disconnected durable handle for file %s\n",
887 : conn->session_info->unix_info->unix_name,
888 : fsp_str_dbg(fsp)));
889 160 : return NT_STATUS_OK;
890 : }
891 :
892 357005 : if (fsp->op != NULL) {
893 : /*
894 : * Make sure the handle is not marked as durable anymore
895 : */
896 349109 : fsp->op->global->durable = false;
897 : }
898 :
899 : /* If this is an old DOS or FCB open and we have multiple opens on
900 : the same handle we only have one share mode. Ensure we only remove
901 : the share mode on the last close. */
902 :
903 357005 : if (fh_get_refcount(fsp->fh) == 1) {
904 : /* Should we return on error here... ? */
905 356892 : tmp = close_remove_share_mode(fsp, close_type);
906 356892 : status = ntstatus_keeperror(status, tmp);
907 : }
908 :
909 357005 : locking_close_file(fsp, close_type);
910 :
911 : /*
912 : * Ensure pending modtime is set before closing underlying fd.
913 : */
914 :
915 357005 : tmp = update_write_time_on_close(fsp);
916 357005 : if (NT_STATUS_EQUAL(tmp, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
917 : /*
918 : * Someone renamed the file or a parent directory containing
919 : * this file. We can't do anything about this, eat the error.
920 : */
921 0 : tmp = NT_STATUS_OK;
922 : }
923 357005 : status = ntstatus_keeperror(status, tmp);
924 :
925 357005 : tmp = fd_close(fsp);
926 357005 : status = ntstatus_keeperror(status, tmp);
927 :
928 : /* check for magic scripts */
929 357005 : if (close_type == NORMAL_CLOSE) {
930 353663 : tmp = check_magic(fsp);
931 353663 : status = ntstatus_keeperror(status, tmp);
932 : }
933 :
934 357005 : DEBUG(2,("%s closed file %s (numopen=%d) %s\n",
935 : conn->session_info->unix_info->unix_name, fsp_str_dbg(fsp),
936 : conn->num_files_open - 1,
937 : nt_errstr(status) ));
938 :
939 357005 : return status;
940 : }
941 : /****************************************************************************
942 : Function used by reply_rmdir to delete an entire directory
943 : tree recursively. Return True on ok, False on fail.
944 : ****************************************************************************/
945 :
946 0 : NTSTATUS recursive_rmdir(TALLOC_CTX *ctx,
947 : connection_struct *conn,
948 : struct smb_filename *smb_dname)
949 : {
950 0 : const char *dname = NULL;
951 0 : char *talloced = NULL;
952 0 : struct smb_Dir *dir_hnd = NULL;
953 0 : struct files_struct *dirfsp = NULL;
954 0 : int retval;
955 0 : NTSTATUS status = NT_STATUS_OK;
956 :
957 0 : SMB_ASSERT(!is_ntfs_stream_smb_fname(smb_dname));
958 :
959 0 : status = OpenDir(talloc_tos(),
960 : conn,
961 : smb_dname,
962 : NULL,
963 : 0,
964 : &dir_hnd);
965 0 : if (!NT_STATUS_IS_OK(status)) {
966 0 : return status;
967 : }
968 :
969 0 : dirfsp = dir_hnd_fetch_fsp(dir_hnd);
970 :
971 0 : while ((dname = ReadDirName(dir_hnd, &talloced))) {
972 0 : struct smb_filename *atname = NULL;
973 0 : struct smb_filename *smb_dname_full = NULL;
974 0 : char *fullname = NULL;
975 0 : bool do_break = true;
976 0 : int unlink_flags = 0;
977 :
978 0 : if (ISDOT(dname) || ISDOTDOT(dname)) {
979 0 : TALLOC_FREE(talloced);
980 0 : continue;
981 : }
982 :
983 : /* Construct the full name. */
984 0 : fullname = talloc_asprintf(ctx,
985 : "%s/%s",
986 : smb_dname->base_name,
987 : dname);
988 0 : if (!fullname) {
989 0 : status = NT_STATUS_NO_MEMORY;
990 0 : goto err_break;
991 : }
992 :
993 0 : smb_dname_full = synthetic_smb_fname(talloc_tos(),
994 : fullname,
995 : NULL,
996 : NULL,
997 : smb_dname->twrp,
998 : smb_dname->flags);
999 0 : if (smb_dname_full == NULL) {
1000 0 : status = NT_STATUS_NO_MEMORY;
1001 0 : goto err_break;
1002 : }
1003 :
1004 0 : if (SMB_VFS_LSTAT(conn, smb_dname_full) != 0) {
1005 0 : status = map_nt_error_from_unix(errno);
1006 0 : goto err_break;
1007 : }
1008 :
1009 0 : if (smb_dname_full->st.st_ex_mode & S_IFDIR) {
1010 0 : status = recursive_rmdir(ctx, conn, smb_dname_full);
1011 0 : if (!NT_STATUS_IS_OK(status)) {
1012 0 : goto err_break;
1013 : }
1014 0 : unlink_flags = AT_REMOVEDIR;
1015 : }
1016 :
1017 0 : status = synthetic_pathref(talloc_tos(),
1018 : dirfsp,
1019 : dname,
1020 : NULL,
1021 0 : &smb_dname_full->st,
1022 : smb_dname_full->twrp,
1023 : smb_dname_full->flags,
1024 : &atname);
1025 0 : if (!NT_STATUS_IS_OK(status)) {
1026 0 : goto err_break;
1027 : }
1028 :
1029 0 : if (!is_visible_fsp(atname->fsp)) {
1030 0 : TALLOC_FREE(smb_dname_full);
1031 0 : TALLOC_FREE(fullname);
1032 0 : TALLOC_FREE(talloced);
1033 0 : TALLOC_FREE(atname);
1034 0 : continue;
1035 : }
1036 :
1037 0 : retval = SMB_VFS_UNLINKAT(conn,
1038 : dirfsp,
1039 : atname,
1040 : unlink_flags);
1041 0 : if (retval != 0) {
1042 0 : status = map_nt_error_from_unix(errno);
1043 0 : goto err_break;
1044 : }
1045 :
1046 : /* Successful iteration. */
1047 0 : do_break = false;
1048 :
1049 0 : err_break:
1050 0 : TALLOC_FREE(smb_dname_full);
1051 0 : TALLOC_FREE(fullname);
1052 0 : TALLOC_FREE(talloced);
1053 0 : TALLOC_FREE(atname);
1054 0 : if (do_break) {
1055 0 : break;
1056 : }
1057 : }
1058 0 : TALLOC_FREE(dir_hnd);
1059 0 : return status;
1060 : }
1061 :
1062 : /****************************************************************************
1063 : The internals of the rmdir code - called elsewhere.
1064 : ****************************************************************************/
1065 :
1066 11095 : static NTSTATUS rmdir_internals(TALLOC_CTX *ctx, struct files_struct *fsp)
1067 : {
1068 11095 : struct connection_struct *conn = fsp->conn;
1069 11095 : struct smb_filename *smb_dname = fsp->fsp_name;
1070 11095 : struct smb_filename *parent_fname = NULL;
1071 11095 : struct smb_filename *at_fname = NULL;
1072 11095 : const char *dname = NULL;
1073 11095 : char *talloced = NULL;
1074 11095 : struct smb_Dir *dir_hnd = NULL;
1075 11095 : struct files_struct *dirfsp = NULL;
1076 11095 : int unlink_flags = 0;
1077 64 : NTSTATUS status;
1078 64 : int ret;
1079 :
1080 11095 : SMB_ASSERT(!is_ntfs_stream_smb_fname(smb_dname));
1081 :
1082 11095 : status = parent_pathref(talloc_tos(),
1083 : conn->cwd_fsp,
1084 11095 : fsp->fsp_name,
1085 : &parent_fname,
1086 : &at_fname);
1087 11095 : if (!NT_STATUS_IS_OK(status)) {
1088 0 : return status;
1089 : }
1090 :
1091 : /*
1092 : * Todo: use SMB_VFS_STATX() once it's available.
1093 : */
1094 :
1095 : /* Might be a symlink. */
1096 11095 : ret = SMB_VFS_LSTAT(conn, smb_dname);
1097 11095 : if (ret != 0) {
1098 0 : TALLOC_FREE(parent_fname);
1099 0 : return map_nt_error_from_unix(errno);
1100 : }
1101 :
1102 11095 : if (S_ISLNK(smb_dname->st.st_ex_mode)) {
1103 : /* Is what it points to a directory ? */
1104 0 : ret = SMB_VFS_STAT(conn, smb_dname);
1105 0 : if (ret != 0) {
1106 0 : TALLOC_FREE(parent_fname);
1107 0 : return map_nt_error_from_unix(errno);
1108 : }
1109 0 : if (!(S_ISDIR(smb_dname->st.st_ex_mode))) {
1110 0 : TALLOC_FREE(parent_fname);
1111 0 : return NT_STATUS_NOT_A_DIRECTORY;
1112 : }
1113 : } else {
1114 11031 : unlink_flags = AT_REMOVEDIR;
1115 : }
1116 :
1117 11095 : ret = SMB_VFS_UNLINKAT(conn,
1118 : parent_fname->fsp,
1119 : at_fname,
1120 : unlink_flags);
1121 11095 : if (ret == 0) {
1122 11087 : TALLOC_FREE(parent_fname);
1123 11087 : notify_fname(conn, NOTIFY_ACTION_REMOVED,
1124 : FILE_NOTIFY_CHANGE_DIR_NAME,
1125 11087 : smb_dname->base_name);
1126 11087 : return NT_STATUS_OK;
1127 : }
1128 :
1129 8 : if (!((errno == ENOTEMPTY) || (errno == EEXIST))) {
1130 0 : DEBUG(3,("rmdir_internals: couldn't remove directory %s : "
1131 : "%s\n", smb_fname_str_dbg(smb_dname),
1132 : strerror(errno)));
1133 0 : TALLOC_FREE(parent_fname);
1134 0 : return map_nt_error_from_unix(errno);
1135 : }
1136 :
1137 : /*
1138 : * Here we know the initial directory unlink failed with
1139 : * ENOTEMPTY or EEXIST so we know there are objects within.
1140 : * If we don't have permission to delete files non
1141 : * visible to the client just fail the directory delete.
1142 : */
1143 :
1144 8 : if (!lp_delete_veto_files(SNUM(conn))) {
1145 2 : status = NT_STATUS_DIRECTORY_NOT_EMPTY;
1146 2 : goto err;
1147 : }
1148 :
1149 : /*
1150 : * Check to see if the only thing in this directory are
1151 : * files non-visible to the client. If not, fail the delete.
1152 : */
1153 :
1154 6 : status = OpenDir(talloc_tos(),
1155 : conn,
1156 : smb_dname,
1157 : NULL,
1158 : 0,
1159 : &dir_hnd);
1160 6 : if (!NT_STATUS_IS_OK(status)) {
1161 : /*
1162 : * Note, we deliberately squash the error here
1163 : * to avoid leaking information about what we
1164 : * can't delete.
1165 : */
1166 0 : status = NT_STATUS_DIRECTORY_NOT_EMPTY;
1167 0 : goto err;
1168 : }
1169 :
1170 6 : dirfsp = dir_hnd_fetch_fsp(dir_hnd);
1171 :
1172 22 : while ((dname = ReadDirName(dir_hnd, &talloced)) != NULL) {
1173 18 : struct smb_filename *smb_dname_full = NULL;
1174 18 : struct smb_filename *direntry_fname = NULL;
1175 18 : char *fullname = NULL;
1176 0 : int retval;
1177 :
1178 18 : if (ISDOT(dname) || ISDOTDOT(dname)) {
1179 12 : TALLOC_FREE(talloced);
1180 16 : continue;
1181 : }
1182 6 : if (IS_VETO_PATH(conn, dname)) {
1183 2 : TALLOC_FREE(talloced);
1184 2 : continue;
1185 : }
1186 :
1187 4 : fullname = talloc_asprintf(talloc_tos(),
1188 : "%s/%s",
1189 : smb_dname->base_name,
1190 : dname);
1191 :
1192 4 : if (fullname == NULL) {
1193 0 : TALLOC_FREE(talloced);
1194 0 : status = NT_STATUS_NO_MEMORY;
1195 0 : goto err;
1196 : }
1197 :
1198 4 : smb_dname_full = synthetic_smb_fname(talloc_tos(),
1199 : fullname,
1200 : NULL,
1201 : NULL,
1202 : smb_dname->twrp,
1203 : smb_dname->flags);
1204 4 : if (smb_dname_full == NULL) {
1205 0 : TALLOC_FREE(talloced);
1206 0 : TALLOC_FREE(fullname);
1207 0 : status = NT_STATUS_NO_MEMORY;
1208 0 : goto err;
1209 : }
1210 :
1211 4 : retval = SMB_VFS_LSTAT(conn, smb_dname_full);
1212 4 : if (retval != 0) {
1213 0 : status = map_nt_error_from_unix(errno);
1214 0 : TALLOC_FREE(talloced);
1215 0 : TALLOC_FREE(fullname);
1216 0 : TALLOC_FREE(smb_dname_full);
1217 0 : goto err;
1218 : }
1219 :
1220 4 : if (S_ISLNK(smb_dname_full->st.st_ex_mode)) {
1221 : /* Could it be an msdfs link ? */
1222 4 : if (lp_host_msdfs() &&
1223 2 : lp_msdfs_root(SNUM(conn))) {
1224 0 : struct smb_filename *smb_atname;
1225 0 : smb_atname = synthetic_smb_fname(talloc_tos(),
1226 : dname,
1227 : NULL,
1228 0 : &smb_dname_full->st,
1229 0 : fsp->fsp_name->twrp,
1230 0 : fsp->fsp_name->flags);
1231 0 : if (smb_atname == NULL) {
1232 0 : TALLOC_FREE(talloced);
1233 0 : TALLOC_FREE(fullname);
1234 0 : TALLOC_FREE(smb_dname_full);
1235 0 : status = NT_STATUS_NO_MEMORY;
1236 0 : goto err;
1237 : }
1238 0 : if (is_msdfs_link(fsp, smb_atname)) {
1239 0 : TALLOC_FREE(talloced);
1240 0 : TALLOC_FREE(fullname);
1241 0 : TALLOC_FREE(smb_dname_full);
1242 0 : TALLOC_FREE(smb_atname);
1243 0 : DBG_DEBUG("got msdfs link name %s "
1244 : "- can't delete directory %s\n",
1245 : dname,
1246 : fsp_str_dbg(fsp));
1247 0 : status = NT_STATUS_DIRECTORY_NOT_EMPTY;
1248 0 : goto err;
1249 : }
1250 0 : TALLOC_FREE(smb_atname);
1251 : }
1252 :
1253 : /* Not a DFS link - could it be a dangling symlink ? */
1254 2 : retval = SMB_VFS_STAT(conn, smb_dname_full);
1255 2 : if (retval == -1 && (errno == ENOENT || errno == ELOOP)) {
1256 : /*
1257 : * Dangling symlink.
1258 : * Allow delete as "delete veto files = yes"
1259 : */
1260 2 : TALLOC_FREE(talloced);
1261 2 : TALLOC_FREE(fullname);
1262 2 : TALLOC_FREE(smb_dname_full);
1263 2 : continue;
1264 : }
1265 :
1266 0 : DBG_DEBUG("got symlink name %s - "
1267 : "can't delete directory %s\n",
1268 : dname,
1269 : fsp_str_dbg(fsp));
1270 0 : TALLOC_FREE(talloced);
1271 0 : TALLOC_FREE(fullname);
1272 0 : TALLOC_FREE(smb_dname_full);
1273 0 : status = NT_STATUS_DIRECTORY_NOT_EMPTY;
1274 0 : goto err;
1275 : }
1276 :
1277 : /* Not a symlink, get a pathref. */
1278 2 : status = synthetic_pathref(talloc_tos(),
1279 : dirfsp,
1280 : dname,
1281 : NULL,
1282 2 : &smb_dname_full->st,
1283 : smb_dname->twrp,
1284 : smb_dname->flags,
1285 : &direntry_fname);
1286 2 : if (!NT_STATUS_IS_OK(status)) {
1287 0 : TALLOC_FREE(talloced);
1288 0 : TALLOC_FREE(fullname);
1289 0 : TALLOC_FREE(smb_dname_full);
1290 0 : goto err;
1291 : }
1292 :
1293 2 : if (!is_visible_fsp(direntry_fname->fsp)) {
1294 0 : TALLOC_FREE(talloced);
1295 0 : TALLOC_FREE(fullname);
1296 0 : TALLOC_FREE(smb_dname_full);
1297 0 : TALLOC_FREE(direntry_fname);
1298 0 : continue;
1299 : }
1300 :
1301 : /*
1302 : * We found a client visible name.
1303 : * We cannot delete this directory.
1304 : */
1305 2 : DBG_DEBUG("got name %s - "
1306 : "can't delete directory %s\n",
1307 : dname,
1308 : fsp_str_dbg(fsp));
1309 2 : TALLOC_FREE(talloced);
1310 2 : TALLOC_FREE(fullname);
1311 2 : TALLOC_FREE(smb_dname_full);
1312 2 : TALLOC_FREE(direntry_fname);
1313 2 : status = NT_STATUS_DIRECTORY_NOT_EMPTY;
1314 2 : goto err;
1315 : }
1316 :
1317 : /* Do a recursive delete. */
1318 4 : RewindDir(dir_hnd);
1319 :
1320 16 : while ((dname = ReadDirName(dir_hnd, &talloced)) != NULL) {
1321 12 : struct smb_filename *direntry_fname = NULL;
1322 12 : struct smb_filename *smb_dname_full = NULL;
1323 12 : char *fullname = NULL;
1324 12 : bool do_break = true;
1325 0 : int retval;
1326 :
1327 12 : if (ISDOT(dname) || ISDOTDOT(dname)) {
1328 8 : TALLOC_FREE(talloced);
1329 8 : continue;
1330 : }
1331 :
1332 4 : fullname = talloc_asprintf(ctx,
1333 : "%s/%s",
1334 : smb_dname->base_name,
1335 : dname);
1336 :
1337 4 : if (fullname == NULL) {
1338 0 : status = NT_STATUS_NO_MEMORY;
1339 0 : goto err_break;
1340 : }
1341 :
1342 4 : smb_dname_full = synthetic_smb_fname(talloc_tos(),
1343 : fullname,
1344 : NULL,
1345 : NULL,
1346 : smb_dname->twrp,
1347 : smb_dname->flags);
1348 4 : if (smb_dname_full == NULL) {
1349 0 : status = NT_STATUS_NO_MEMORY;
1350 0 : goto err_break;
1351 : }
1352 :
1353 : /*
1354 : * Todo: use SMB_VFS_STATX() once that's available.
1355 : */
1356 :
1357 4 : retval = SMB_VFS_LSTAT(conn, smb_dname_full);
1358 4 : if (retval != 0) {
1359 0 : status = map_nt_error_from_unix(errno);
1360 0 : goto err_break;
1361 : }
1362 :
1363 : /*
1364 : * We are only dealing with VETO'ed objects
1365 : * here. If it's a symlink, just delete the
1366 : * link without caring what it is pointing
1367 : * to.
1368 : */
1369 4 : if (S_ISLNK(smb_dname_full->st.st_ex_mode)) {
1370 2 : direntry_fname = synthetic_smb_fname(talloc_tos(),
1371 : dname,
1372 : NULL,
1373 2 : &smb_dname_full->st,
1374 : smb_dname->twrp,
1375 : smb_dname->flags);
1376 2 : if (direntry_fname == NULL) {
1377 0 : status = NT_STATUS_NO_MEMORY;
1378 0 : goto err_break;
1379 : }
1380 : } else {
1381 2 : status = synthetic_pathref(talloc_tos(),
1382 : dirfsp,
1383 : dname,
1384 : NULL,
1385 2 : &smb_dname_full->st,
1386 : smb_dname->twrp,
1387 : smb_dname->flags,
1388 : &direntry_fname);
1389 2 : if (!NT_STATUS_IS_OK(status)) {
1390 0 : goto err_break;
1391 : }
1392 :
1393 2 : if (!is_visible_fsp(direntry_fname->fsp)) {
1394 0 : TALLOC_FREE(fullname);
1395 0 : TALLOC_FREE(smb_dname_full);
1396 0 : TALLOC_FREE(talloced);
1397 0 : TALLOC_FREE(direntry_fname);
1398 0 : continue;
1399 : }
1400 : }
1401 :
1402 4 : unlink_flags = 0;
1403 :
1404 4 : if (smb_dname_full->st.st_ex_mode & S_IFDIR) {
1405 0 : status = recursive_rmdir(ctx, conn, smb_dname_full);
1406 0 : if (!NT_STATUS_IS_OK(status)) {
1407 0 : goto err_break;
1408 : }
1409 0 : unlink_flags = AT_REMOVEDIR;
1410 : }
1411 :
1412 4 : retval = SMB_VFS_UNLINKAT(conn,
1413 : dirfsp,
1414 : direntry_fname,
1415 : unlink_flags);
1416 4 : if (retval != 0) {
1417 0 : status = map_nt_error_from_unix(errno);
1418 0 : goto err_break;
1419 : }
1420 :
1421 : /* Successful iteration. */
1422 4 : do_break = false;
1423 :
1424 4 : err_break:
1425 4 : TALLOC_FREE(fullname);
1426 4 : TALLOC_FREE(smb_dname_full);
1427 4 : TALLOC_FREE(talloced);
1428 4 : TALLOC_FREE(direntry_fname);
1429 4 : if (do_break) {
1430 0 : break;
1431 : }
1432 : }
1433 :
1434 : /* If we get here, we know NT_STATUS_IS_OK(status) */
1435 4 : SMB_ASSERT(NT_STATUS_IS_OK(status));
1436 :
1437 : /* Retry the rmdir */
1438 4 : ret = SMB_VFS_UNLINKAT(conn,
1439 : parent_fname->fsp,
1440 : at_fname,
1441 : AT_REMOVEDIR);
1442 4 : if (ret != 0) {
1443 0 : status = map_nt_error_from_unix(errno);
1444 : }
1445 :
1446 4 : err:
1447 :
1448 8 : TALLOC_FREE(dir_hnd);
1449 8 : TALLOC_FREE(parent_fname);
1450 :
1451 8 : if (!NT_STATUS_IS_OK(status)) {
1452 4 : DBG_NOTICE("couldn't remove directory %s : "
1453 : "%s\n", smb_fname_str_dbg(smb_dname),
1454 : nt_errstr(status));
1455 4 : return status;
1456 : }
1457 :
1458 4 : notify_fname(conn, NOTIFY_ACTION_REMOVED,
1459 : FILE_NOTIFY_CHANGE_DIR_NAME,
1460 4 : smb_dname->base_name);
1461 :
1462 4 : return status;
1463 : }
1464 :
1465 : /****************************************************************************
1466 : Close a directory opened by an NT SMB call.
1467 : ****************************************************************************/
1468 :
1469 84359 : static NTSTATUS close_directory(struct smb_request *req, files_struct *fsp,
1470 : enum file_close_type close_type)
1471 : {
1472 84359 : connection_struct *conn = fsp->conn;
1473 84359 : struct close_share_mode_lock_state lck_state = {};
1474 84359 : bool changed_user = false;
1475 84359 : NTSTATUS status = NT_STATUS_OK;
1476 84359 : NTSTATUS status1 = NT_STATUS_OK;
1477 346 : NTSTATUS notify_status;
1478 346 : NTSTATUS ulstatus;
1479 :
1480 84359 : SMB_ASSERT(fsp->fsp_flags.is_fsa);
1481 :
1482 84359 : if (fsp->conn->sconn->using_smb2) {
1483 60478 : notify_status = NT_STATUS_NOTIFY_CLEANUP;
1484 : } else {
1485 23881 : notify_status = NT_STATUS_OK;
1486 : }
1487 :
1488 84359 : assert_no_pending_aio(fsp, close_type);
1489 :
1490 : /*
1491 : * NT can set delete_on_close of the last open
1492 : * reference to a directory also.
1493 : */
1494 :
1495 84359 : lck_state = (struct close_share_mode_lock_state) {
1496 : .fsp = fsp,
1497 : .object_type = "directory",
1498 : .close_type = close_type,
1499 : };
1500 :
1501 84359 : status = share_mode_entry_prepare_lock_del(&lck_state.prepare_state,
1502 : fsp->file_id,
1503 : close_share_mode_lock_prepare,
1504 346 : &lck_state);
1505 84359 : if (!NT_STATUS_IS_OK(status)) {
1506 0 : DBG_ERR("share_mode_entry_prepare_lock_del() failed for %s - %s\n",
1507 : fsp_str_dbg(fsp), nt_errstr(status));
1508 0 : return status;
1509 : }
1510 :
1511 : /*
1512 : * We don't have directory leases yet, so assert it in order
1513 : * to skip release_file_oplock().
1514 : */
1515 84359 : SMB_ASSERT(fsp->oplock_type == NO_OPLOCK);
1516 :
1517 : /*
1518 : * NT can set delete_on_close of the last open
1519 : * reference to a file.
1520 : */
1521 :
1522 84359 : if (!lck_state.delete_object) {
1523 73264 : status = NT_STATUS_OK;
1524 73264 : goto done;
1525 : }
1526 :
1527 : /*
1528 : * Ok, we have to delete the directory
1529 : */
1530 11095 : lck_state.cleanup_fn = close_share_mode_lock_cleanup;
1531 :
1532 11159 : if (lck_state.got_tokens &&
1533 11095 : !unix_token_equal(lck_state.del_token, get_current_utok(conn)))
1534 : {
1535 : /* Become the user who requested the delete. */
1536 :
1537 11 : DBG_INFO("dir %s. Change user to uid %u\n",
1538 : fsp_str_dbg(fsp),
1539 : (unsigned int)lck_state.del_token->uid);
1540 :
1541 11 : if (!push_sec_ctx()) {
1542 0 : smb_panic("close_directory: failed to push sec_ctx.\n");
1543 : }
1544 :
1545 11 : set_sec_ctx(lck_state.del_token->uid,
1546 11 : lck_state.del_token->gid,
1547 11 : lck_state.del_token->ngroups,
1548 11 : lck_state.del_token->groups,
1549 : lck_state.del_nt_token);
1550 :
1551 11 : changed_user = true;
1552 : }
1553 :
1554 11095 : if ((fsp->conn->fs_capabilities & FILE_NAMED_STREAMS)
1555 10548 : && !is_ntfs_stream_smb_fname(fsp->fsp_name)) {
1556 :
1557 10548 : status = delete_all_streams(fsp->conn, fsp->fsp_name);
1558 10548 : if (!NT_STATUS_IS_OK(status)) {
1559 0 : DEBUG(5, ("delete_all_streams failed: %s\n",
1560 : nt_errstr(status)));
1561 0 : goto done;
1562 : }
1563 : }
1564 :
1565 11095 : status = rmdir_internals(talloc_tos(), fsp);
1566 :
1567 11095 : DEBUG(5,("close_directory: %s. Delete on close was set - "
1568 : "deleting directory returned %s.\n",
1569 : fsp_str_dbg(fsp), nt_errstr(status)));
1570 :
1571 : /*
1572 : * Ensure we remove any change notify requests that would
1573 : * now fail as the directory has been deleted.
1574 : */
1575 :
1576 11095 : if (NT_STATUS_IS_OK(status)) {
1577 11091 : notify_status = NT_STATUS_DELETE_PENDING;
1578 : }
1579 :
1580 4 : done:
1581 84359 : if (changed_user) {
1582 : /* unbecome user. */
1583 11 : pop_sec_ctx();
1584 : }
1585 :
1586 84359 : ulstatus = share_mode_entry_prepare_unlock(&lck_state.prepare_state,
1587 : lck_state.cleanup_fn,
1588 346 : &lck_state);
1589 84359 : if (!NT_STATUS_IS_OK(ulstatus)) {
1590 0 : DBG_ERR("share_mode_entry_prepare_unlock() failed for %s - %s\n",
1591 : fsp_str_dbg(fsp), nt_errstr(ulstatus));
1592 0 : smb_panic("share_mode_entry_prepare_unlock() failed!");
1593 : }
1594 :
1595 84359 : remove_pending_change_notify_requests_by_fid(fsp, notify_status);
1596 :
1597 84359 : status1 = fd_close(fsp);
1598 :
1599 84359 : if (!NT_STATUS_IS_OK(status1)) {
1600 0 : DEBUG(0, ("Could not close dir! fname=%s, fd=%d, err=%d=%s\n",
1601 : fsp_str_dbg(fsp), fsp_get_pathref_fd(fsp), errno,
1602 : strerror(errno)));
1603 : }
1604 :
1605 84359 : if (NT_STATUS_IS_OK(status) && !NT_STATUS_IS_OK(status1)) {
1606 0 : status = status1;
1607 : }
1608 84359 : return status;
1609 : }
1610 :
1611 : /****************************************************************************
1612 : Rundown all SMB-related dependencies of a files struct
1613 : ****************************************************************************/
1614 :
1615 584285 : NTSTATUS close_file_smb(struct smb_request *req,
1616 : struct files_struct *fsp,
1617 : enum file_close_type close_type)
1618 : {
1619 2121 : NTSTATUS status;
1620 :
1621 : /*
1622 : * This fsp can never be an internal dirfsp. They must
1623 : * be explicitly closed by TALLOC_FREE of the dir handle.
1624 : */
1625 584285 : SMB_ASSERT(!fsp->fsp_flags.is_dirfsp);
1626 :
1627 : /*
1628 : * Never call directly on a base fsp
1629 : */
1630 584285 : SMB_ASSERT(fsp->stream_fsp == NULL);
1631 :
1632 584285 : if (fsp->fake_file_handle != NULL) {
1633 : /*
1634 : * Named pipes are opened as fake files and
1635 : * can have pending aio requests. Ensure
1636 : * we clear out all pending aio on force
1637 : * shutdown of named pipes also.
1638 : * BUG: https://bugzilla.samba.org/show_bug.cgi?id=15423
1639 : */
1640 16861 : assert_no_pending_aio(fsp, close_type);
1641 16861 : status = close_fake_file(req, fsp);
1642 567424 : } else if (fsp->print_file != NULL) {
1643 : /* FIXME: return spool errors */
1644 28 : print_spool_end(fsp, close_type);
1645 28 : fd_close(fsp);
1646 28 : status = NT_STATUS_OK;
1647 567396 : } else if (!fsp->fsp_flags.is_fsa) {
1648 125872 : if (close_type == NORMAL_CLOSE) {
1649 0 : DBG_ERR("unexpected NORMAL_CLOSE for [%s] "
1650 : "is_fsa[%u] is_pathref[%u] is_directory[%u]\n",
1651 : fsp_str_dbg(fsp),
1652 : fsp->fsp_flags.is_fsa,
1653 : fsp->fsp_flags.is_pathref,
1654 : fsp->fsp_flags.is_directory);
1655 : }
1656 125872 : SMB_ASSERT(close_type != NORMAL_CLOSE);
1657 125872 : fd_close(fsp);
1658 125872 : status = NT_STATUS_OK;
1659 441524 : } else if (fsp->fsp_flags.is_directory) {
1660 84359 : status = close_directory(req, fsp, close_type);
1661 : } else {
1662 357165 : status = close_normal_file(req, fsp, close_type);
1663 : }
1664 :
1665 584285 : if (fsp_is_alternate_stream(fsp)) {
1666 : /*
1667 : * fsp was a stream, its base_fsp can't be a stream
1668 : * as well
1669 : */
1670 7229 : SMB_ASSERT(!fsp_is_alternate_stream(fsp->base_fsp));
1671 :
1672 : /*
1673 : * There's a 1:1 relationship between fsp and a base_fsp
1674 : */
1675 7229 : SMB_ASSERT(fsp->base_fsp->stream_fsp == fsp);
1676 :
1677 : /*
1678 : * Make base_fsp look standalone now
1679 : */
1680 7229 : fsp->base_fsp->stream_fsp = NULL;
1681 :
1682 7229 : close_file_free(req, &fsp->base_fsp, close_type);
1683 : }
1684 :
1685 584285 : fsp_unbind_smb(req, fsp);
1686 :
1687 584285 : return status;
1688 : }
1689 :
1690 98875 : NTSTATUS close_file_free(struct smb_request *req,
1691 : struct files_struct **_fsp,
1692 : enum file_close_type close_type)
1693 : {
1694 98875 : struct files_struct *fsp = *_fsp;
1695 1062 : NTSTATUS status;
1696 :
1697 98875 : status = close_file_smb(req, fsp, close_type);
1698 :
1699 98875 : file_free(req, fsp);
1700 98875 : *_fsp = NULL;
1701 :
1702 98875 : return status;
1703 : }
1704 :
1705 : /****************************************************************************
1706 : Deal with an (authorized) message to close a file given the share mode
1707 : entry.
1708 : ****************************************************************************/
1709 :
1710 0 : void msg_close_file(struct messaging_context *msg_ctx,
1711 : void *private_data,
1712 : uint32_t msg_type,
1713 : struct server_id server_id,
1714 : DATA_BLOB *data)
1715 : {
1716 0 : files_struct *fsp = NULL;
1717 0 : struct file_id id;
1718 0 : struct share_mode_entry e;
1719 0 : struct smbd_server_connection *sconn =
1720 0 : talloc_get_type_abort(private_data,
1721 : struct smbd_server_connection);
1722 :
1723 0 : message_to_share_mode_entry(&id, &e, (char *)data->data);
1724 :
1725 0 : if(DEBUGLVL(10)) {
1726 0 : char *sm_str = share_mode_str(NULL, 0, &id, &e);
1727 0 : if (!sm_str) {
1728 0 : smb_panic("talloc failed");
1729 : }
1730 0 : DEBUG(10,("msg_close_file: got request to close share mode "
1731 : "entry %s\n", sm_str));
1732 0 : TALLOC_FREE(sm_str);
1733 : }
1734 :
1735 0 : fsp = file_find_dif(sconn, id, e.share_file_id);
1736 0 : if (!fsp) {
1737 0 : DEBUG(10,("msg_close_file: failed to find file.\n"));
1738 0 : return;
1739 : }
1740 0 : close_file_free(NULL, &fsp, NORMAL_CLOSE);
1741 : }
|