source: branches/samba-3.2.x/source/smbd/close.c@ 228

Last change on this file since 228 was 228, checked in by Herwig Bauernfeind, 16 years ago

Update 3.2 branch to 3.2.6

File size: 20.1 KB
Line 
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
24extern struct current_user current_user;
25
26/****************************************************************************
27 Run a file if it is a magic script.
28****************************************************************************/
29
30static void check_magic(struct files_struct *fsp)
31{
32 int ret;
33 const char *magic_output = NULL;
34 SMB_STRUCT_STAT st;
35 int tmp_fd, outfd;
36 TALLOC_CTX *ctx = NULL;
37 const char *p;
38 struct connection_struct *conn = fsp->conn;
39
40 if (!*lp_magicscript(SNUM(conn))) {
41 return;
42 }
43
44 DEBUG(5,("checking magic for %s\n",fsp->fsp_name));
45
46 if (!(p = strrchr_m(fsp->fsp_name,'/'))) {
47 p = fsp->fsp_name;
48 } else {
49 p++;
50 }
51
52 if (!strequal(lp_magicscript(SNUM(conn)),p)) {
53 return;
54 }
55
56 ctx = talloc_stackframe();
57
58 if (*lp_magicoutput(SNUM(conn))) {
59 magic_output = lp_magicoutput(SNUM(conn));
60 } else {
61 magic_output = talloc_asprintf(ctx,
62 "%s.out",
63 fsp->fsp_name);
64 }
65 if (!magic_output) {
66 TALLOC_FREE(ctx);
67 return;
68 }
69
70 chmod(fsp->fsp_name,0755);
71 ret = smbrun(fsp->fsp_name,&tmp_fd);
72 DEBUG(3,("Invoking magic command %s gave %d\n",
73 fsp->fsp_name,ret));
74
75 unlink(fsp->fsp_name);
76 if (ret != 0 || tmp_fd == -1) {
77 if (tmp_fd != -1) {
78 close(tmp_fd);
79 }
80 TALLOC_FREE(ctx);
81 return;
82 }
83 outfd = open(magic_output, O_CREAT|O_EXCL|O_RDWR, 0600);
84 if (outfd == -1) {
85 close(tmp_fd);
86 TALLOC_FREE(ctx);
87 return;
88 }
89
90 if (sys_fstat(tmp_fd,&st) == -1) {
91 close(tmp_fd);
92 close(outfd);
93 return;
94 }
95
96 transfer_file(tmp_fd,outfd,(SMB_OFF_T)st.st_size);
97 close(tmp_fd);
98 close(outfd);
99 TALLOC_FREE(ctx);
100}
101
102/****************************************************************************
103 Common code to close a file or a directory.
104****************************************************************************/
105
106static NTSTATUS close_filestruct(files_struct *fsp)
107{
108 NTSTATUS status = NT_STATUS_OK;
109
110 if (fsp->fh->fd != -1) {
111 if(flush_write_cache(fsp, CLOSE_FLUSH) == -1) {
112 status = map_nt_error_from_unix(errno);
113 }
114 delete_write_cache(fsp);
115 }
116
117 return status;
118}
119
120/****************************************************************************
121 If any deferred opens are waiting on this close, notify them.
122****************************************************************************/
123
124static void notify_deferred_opens(struct share_mode_lock *lck)
125{
126 int i;
127
128 for (i=0; i<lck->num_share_modes; i++) {
129 struct share_mode_entry *e = &lck->share_modes[i];
130
131 if (!is_deferred_open_entry(e)) {
132 continue;
133 }
134
135 if (procid_is_me(&e->pid)) {
136 /*
137 * We need to notify ourself to retry the open. Do
138 * this by finding the queued SMB record, moving it to
139 * the head of the queue and changing the wait time to
140 * zero.
141 */
142 schedule_deferred_open_smb_message(e->op_mid);
143 } else {
144 char msg[MSG_SMB_SHARE_MODE_ENTRY_SIZE];
145
146 share_mode_entry_to_message(msg, e);
147
148 messaging_send_buf(smbd_messaging_context(),
149 e->pid, MSG_SMB_OPEN_RETRY,
150 (uint8 *)msg,
151 MSG_SMB_SHARE_MODE_ENTRY_SIZE);
152 }
153 }
154}
155
156/****************************************************************************
157 Delete all streams
158****************************************************************************/
159
160static NTSTATUS delete_all_streams(connection_struct *conn, const char *fname)
161{
162 struct stream_struct *stream_info;
163 int i;
164 unsigned int num_streams;
165 TALLOC_CTX *frame = talloc_stackframe();
166 NTSTATUS status;
167
168 status = SMB_VFS_STREAMINFO(conn, NULL, fname, talloc_tos(),
169 &num_streams, &stream_info);
170
171 if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_IMPLEMENTED)) {
172 DEBUG(10, ("no streams around\n"));
173 TALLOC_FREE(frame);
174 return NT_STATUS_OK;
175 }
176
177 if (!NT_STATUS_IS_OK(status)) {
178 DEBUG(10, ("SMB_VFS_STREAMINFO failed: %s\n",
179 nt_errstr(status)));
180 goto fail;
181 }
182
183 DEBUG(10, ("delete_all_streams found %d streams\n",
184 num_streams));
185
186 if (num_streams == 0) {
187 TALLOC_FREE(frame);
188 return NT_STATUS_OK;
189 }
190
191 for (i=0; i<num_streams; i++) {
192 int res;
193 char *streamname;
194
195 if (strequal(stream_info[i].name, "::$DATA")) {
196 continue;
197 }
198
199 streamname = talloc_asprintf(talloc_tos(), "%s%s", fname,
200 stream_info[i].name);
201
202 if (streamname == NULL) {
203 DEBUG(0, ("talloc_aprintf failed\n"));
204 status = NT_STATUS_NO_MEMORY;
205 goto fail;
206 }
207
208 res = SMB_VFS_UNLINK(conn, streamname);
209
210 TALLOC_FREE(streamname);
211
212 if (res == -1) {
213 status = map_nt_error_from_unix(errno);
214 DEBUG(10, ("Could not delete stream %s: %s\n",
215 streamname, strerror(errno)));
216 break;
217 }
218 }
219
220 fail:
221 TALLOC_FREE(frame);
222 return status;
223}
224
225/****************************************************************************
226 Deal with removing a share mode on last close.
227****************************************************************************/
228
229static NTSTATUS close_remove_share_mode(files_struct *fsp,
230 enum file_close_type close_type)
231{
232 connection_struct *conn = fsp->conn;
233 bool delete_file = false;
234 bool changed_user = false;
235 struct share_mode_lock *lck;
236 SMB_STRUCT_STAT sbuf;
237 NTSTATUS status = NT_STATUS_OK;
238 int ret;
239 struct file_id id;
240
241 /*
242 * Lock the share entries, and determine if we should delete
243 * on close. If so delete whilst the lock is still in effect.
244 * This prevents race conditions with the file being created. JRA.
245 */
246
247 lck = get_share_mode_lock(talloc_tos(), fsp->file_id, NULL, NULL,
248 NULL);
249
250 if (lck == NULL) {
251 DEBUG(0, ("close_remove_share_mode: Could not get share mode "
252 "lock for file %s\n", fsp->fsp_name));
253 return NT_STATUS_INVALID_PARAMETER;
254 }
255
256 if (fsp->write_time_forced) {
257 set_close_write_time(fsp, lck->changed_write_time);
258 }
259
260 if (!del_share_mode(lck, fsp)) {
261 DEBUG(0, ("close_remove_share_mode: Could not delete share "
262 "entry for file %s\n", fsp->fsp_name));
263 }
264
265 if (fsp->initial_delete_on_close && (lck->delete_token == NULL)) {
266 bool became_user = False;
267
268 /* Initial delete on close was set and no one else
269 * wrote a real delete on close. */
270
271 if (current_user.vuid != fsp->vuid) {
272 become_user(conn, fsp->vuid);
273 became_user = True;
274 }
275 set_delete_on_close_lck(lck, True, &current_user.ut);
276 if (became_user) {
277 unbecome_user();
278 }
279 }
280
281 delete_file = lck->delete_on_close;
282
283 if (delete_file) {
284 int i;
285 /* See if others still have the file open. If this is the
286 * case, then don't delete. If all opens are POSIX delete now. */
287 for (i=0; i<lck->num_share_modes; i++) {
288 struct share_mode_entry *e = &lck->share_modes[i];
289 if (is_valid_share_mode_entry(e)) {
290 if (fsp->posix_open && (e->flags & SHARE_MODE_FLAG_POSIX_OPEN)) {
291 continue;
292 }
293 delete_file = False;
294 break;
295 }
296 }
297 }
298
299 /* Notify any deferred opens waiting on this close. */
300 notify_deferred_opens(lck);
301 reply_to_oplock_break_requests(fsp);
302
303 /*
304 * NT can set delete_on_close of the last open
305 * reference to a file.
306 */
307
308 if (!(close_type == NORMAL_CLOSE || close_type == SHUTDOWN_CLOSE)
309 || !delete_file
310 || (lck->delete_token == NULL)) {
311 TALLOC_FREE(lck);
312 return NT_STATUS_OK;
313 }
314
315 /*
316 * Ok, we have to delete the file
317 */
318
319 DEBUG(5,("close_remove_share_mode: file %s. Delete on close was set "
320 "- deleting file.\n", fsp->fsp_name));
321
322 /*
323 * Don't try to update the write time when we delete the file
324 */
325 fsp->update_write_time_on_close = false;
326
327 if (!unix_token_equal(lck->delete_token, &current_user.ut)) {
328 /* Become the user who requested the delete. */
329
330 DEBUG(5,("close_remove_share_mode: file %s. "
331 "Change user to uid %u\n",
332 fsp->fsp_name,
333 (unsigned int)lck->delete_token->uid));
334
335 if (!push_sec_ctx()) {
336 smb_panic("close_remove_share_mode: file %s. failed to push "
337 "sec_ctx.\n");
338 }
339
340 set_sec_ctx(lck->delete_token->uid,
341 lck->delete_token->gid,
342 lck->delete_token->ngroups,
343 lck->delete_token->groups,
344 NULL);
345
346 changed_user = true;
347 }
348
349 /* We can only delete the file if the name we have is still valid and
350 hasn't been renamed. */
351
352 if (fsp->posix_open) {
353 ret = SMB_VFS_LSTAT(conn,fsp->fsp_name,&sbuf);
354 } else {
355 ret = SMB_VFS_STAT(conn,fsp->fsp_name,&sbuf);
356 }
357
358 if (ret != 0) {
359 DEBUG(5,("close_remove_share_mode: file %s. Delete on close "
360 "was set and stat failed with error %s\n",
361 fsp->fsp_name, strerror(errno) ));
362 /*
363 * Don't save the errno here, we ignore this error
364 */
365 goto done;
366 }
367
368 id = vfs_file_id_from_sbuf(conn, &sbuf);
369
370 if (!file_id_equal(&fsp->file_id, &id)) {
371 DEBUG(5,("close_remove_share_mode: file %s. Delete on close "
372 "was set and dev and/or inode does not match\n",
373 fsp->fsp_name ));
374 DEBUG(5,("close_remove_share_mode: file %s. stored file_id %s, "
375 "stat file_id %s\n",
376 fsp->fsp_name,
377 file_id_string_tos(&fsp->file_id),
378 file_id_string_tos(&id)));
379 /*
380 * Don't save the errno here, we ignore this error
381 */
382 goto done;
383 }
384
385 if ((conn->fs_capabilities & FILE_NAMED_STREAMS)
386 && !is_ntfs_stream_name(fsp->fsp_name)) {
387
388 status = delete_all_streams(conn, fsp->fsp_name);
389
390 if (!NT_STATUS_IS_OK(status)) {
391 DEBUG(5, ("delete_all_streams failed: %s\n",
392 nt_errstr(status)));
393 goto done;
394 }
395 }
396
397
398 if (SMB_VFS_UNLINK(conn,fsp->fsp_name) != 0) {
399 /*
400 * This call can potentially fail as another smbd may
401 * have had the file open with delete on close set and
402 * deleted it when its last reference to this file
403 * went away. Hence we log this but not at debug level
404 * zero.
405 */
406
407 DEBUG(5,("close_remove_share_mode: file %s. Delete on close "
408 "was set and unlink failed with error %s\n",
409 fsp->fsp_name, strerror(errno) ));
410
411 status = map_nt_error_from_unix(errno);
412 }
413
414 notify_fname(conn, NOTIFY_ACTION_REMOVED,
415 FILE_NOTIFY_CHANGE_FILE_NAME,
416 fsp->fsp_name);
417
418 /* As we now have POSIX opens which can unlink
419 * with other open files we may have taken
420 * this code path with more than one share mode
421 * entry - ensure we only delete once by resetting
422 * the delete on close flag. JRA.
423 */
424
425 set_delete_on_close_lck(lck, False, NULL);
426
427 done:
428
429 if (changed_user) {
430 /* unbecome user. */
431 pop_sec_ctx();
432 }
433
434 TALLOC_FREE(lck);
435 return status;
436}
437
438void set_close_write_time(struct files_struct *fsp, struct timespec ts)
439{
440 DEBUG(6,("close_write_time: %s" , time_to_asc(convert_timespec_to_time_t(ts))));
441
442 if (null_timespec(ts)) {
443 return;
444 }
445 /*
446 * if the write time on close is explict set, then don't
447 * need to fix it up to the value in the locking db
448 */
449 fsp->write_time_forced = false;
450
451 fsp->update_write_time_on_close = true;
452 fsp->close_write_time = ts;
453}
454
455static NTSTATUS update_write_time_on_close(struct files_struct *fsp)
456{
457 SMB_STRUCT_STAT sbuf;
458 struct timespec ts[2];
459 NTSTATUS status;
460
461 ZERO_STRUCT(sbuf);
462 ZERO_STRUCT(ts);
463
464 if (!fsp->update_write_time_on_close) {
465 return NT_STATUS_OK;
466 }
467
468 if (null_timespec(fsp->close_write_time)) {
469 fsp->close_write_time = timespec_current();
470 }
471
472 /* Ensure we have a valid stat struct for the source. */
473 if (fsp->fh->fd != -1) {
474 if (SMB_VFS_FSTAT(fsp, &sbuf) == -1) {
475 return map_nt_error_from_unix(errno);
476 }
477 } else {
478 if (SMB_VFS_STAT(fsp->conn,fsp->fsp_name,&sbuf) == -1) {
479 return map_nt_error_from_unix(errno);
480 }
481 }
482
483 if (!VALID_STAT(sbuf)) {
484 /* if it doesn't seem to be a real file */
485 return NT_STATUS_OK;
486 }
487
488 ts[1] = fsp->close_write_time;
489 status = smb_set_file_time(fsp->conn, fsp, fsp->fsp_name,
490 &sbuf, ts, true);
491 if (!NT_STATUS_IS_OK(status)) {
492 return status;
493 }
494
495 return NT_STATUS_OK;
496}
497
498/****************************************************************************
499 Close a file.
500
501 close_type can be NORMAL_CLOSE=0,SHUTDOWN_CLOSE,ERROR_CLOSE.
502 printing and magic scripts are only run on normal close.
503 delete on close is done on normal and shutdown close.
504****************************************************************************/
505
506static NTSTATUS close_normal_file(files_struct *fsp, enum file_close_type close_type)
507{
508 NTSTATUS status = NT_STATUS_OK;
509 NTSTATUS saved_status1 = NT_STATUS_OK;
510 NTSTATUS saved_status2 = NT_STATUS_OK;
511 NTSTATUS saved_status3 = NT_STATUS_OK;
512 NTSTATUS saved_status4 = NT_STATUS_OK;
513 connection_struct *conn = fsp->conn;
514
515 if (fsp->aio_write_behind) {
516 /*
517 * If we're finishing write behind on a close we can get a write
518 * error here, we must remember this.
519 */
520 int ret = wait_for_aio_completion(fsp);
521 if (ret) {
522 saved_status1 = map_nt_error_from_unix(ret);
523 }
524 } else {
525 cancel_aio_by_fsp(fsp);
526 }
527
528 /*
529 * If we're flushing on a close we can get a write
530 * error here, we must remember this.
531 */
532
533 saved_status2 = close_filestruct(fsp);
534
535 if (fsp->print_file) {
536 print_fsp_end(fsp, close_type);
537 file_free(fsp);
538 return NT_STATUS_OK;
539 }
540
541 /* If this is an old DOS or FCB open and we have multiple opens on
542 the same handle we only have one share mode. Ensure we only remove
543 the share mode on the last close. */
544
545 if (fsp->fh->ref_count == 1) {
546 /* Should we return on error here... ? */
547 saved_status3 = close_remove_share_mode(fsp, close_type);
548 }
549
550 if(fsp->oplock_type) {
551 release_file_oplock(fsp);
552 }
553
554 locking_close_file(smbd_messaging_context(), fsp);
555
556 status = fd_close(fsp);
557
558 /* check for magic scripts */
559 if (close_type == NORMAL_CLOSE) {
560 check_magic(fsp);
561 }
562
563 /*
564 * Ensure pending modtime is set after close.
565 */
566
567 saved_status4 = update_write_time_on_close(fsp);
568
569 if (NT_STATUS_IS_OK(status)) {
570 if (!NT_STATUS_IS_OK(saved_status1)) {
571 status = saved_status1;
572 } else if (!NT_STATUS_IS_OK(saved_status2)) {
573 status = saved_status2;
574 } else if (!NT_STATUS_IS_OK(saved_status3)) {
575 status = saved_status3;
576 } else if (!NT_STATUS_IS_OK(saved_status4)) {
577 status = saved_status4;
578 }
579 }
580
581 DEBUG(2,("%s closed file %s (numopen=%d) %s\n",
582 conn->user,fsp->fsp_name,
583 conn->num_files_open - 1,
584 nt_errstr(status) ));
585
586 file_free(fsp);
587 return status;
588}
589
590/****************************************************************************
591 Close a directory opened by an NT SMB call.
592****************************************************************************/
593
594static NTSTATUS close_directory(files_struct *fsp, enum file_close_type close_type)
595{
596 struct share_mode_lock *lck = 0;
597 bool delete_dir = False;
598 NTSTATUS status = NT_STATUS_OK;
599
600 /*
601 * NT can set delete_on_close of the last open
602 * reference to a directory also.
603 */
604
605 lck = get_share_mode_lock(talloc_tos(), fsp->file_id, NULL, NULL,
606 NULL);
607
608 if (lck == NULL) {
609 DEBUG(0, ("close_directory: Could not get share mode lock for %s\n", fsp->fsp_name));
610 return NT_STATUS_INVALID_PARAMETER;
611 }
612
613 if (!del_share_mode(lck, fsp)) {
614 DEBUG(0, ("close_directory: Could not delete share entry for %s\n", fsp->fsp_name));
615 }
616
617 if (fsp->initial_delete_on_close) {
618 bool became_user = False;
619
620 /* Initial delete on close was set - for
621 * directories we don't care if anyone else
622 * wrote a real delete on close. */
623
624 if (current_user.vuid != fsp->vuid) {
625 become_user(fsp->conn, fsp->vuid);
626 became_user = True;
627 }
628 send_stat_cache_delete_message(fsp->fsp_name);
629 set_delete_on_close_lck(lck, True, &current_user.ut);
630 if (became_user) {
631 unbecome_user();
632 }
633 }
634
635 delete_dir = lck->delete_on_close;
636
637 if (delete_dir) {
638 int i;
639 /* See if others still have the dir open. If this is the
640 * case, then don't delete. If all opens are POSIX delete now. */
641 for (i=0; i<lck->num_share_modes; i++) {
642 struct share_mode_entry *e = &lck->share_modes[i];
643 if (is_valid_share_mode_entry(e)) {
644 if (fsp->posix_open && (e->flags & SHARE_MODE_FLAG_POSIX_OPEN)) {
645 continue;
646 }
647 delete_dir = False;
648 break;
649 }
650 }
651 }
652
653 if ((close_type == NORMAL_CLOSE || close_type == SHUTDOWN_CLOSE) &&
654 delete_dir &&
655 lck->delete_token) {
656
657 /* Become the user who requested the delete. */
658
659 if (!push_sec_ctx()) {
660 smb_panic("close_directory: failed to push sec_ctx.\n");
661 }
662
663 set_sec_ctx(lck->delete_token->uid,
664 lck->delete_token->gid,
665 lck->delete_token->ngroups,
666 lck->delete_token->groups,
667 NULL);
668
669 TALLOC_FREE(lck);
670
671 status = rmdir_internals(talloc_tos(),
672 fsp->conn, fsp->fsp_name);
673
674 DEBUG(5,("close_directory: %s. Delete on close was set - "
675 "deleting directory returned %s.\n",
676 fsp->fsp_name, nt_errstr(status)));
677
678 /* unbecome user. */
679 pop_sec_ctx();
680
681 /*
682 * Ensure we remove any change notify requests that would
683 * now fail as the directory has been deleted.
684 */
685
686 if(NT_STATUS_IS_OK(status)) {
687 remove_pending_change_notify_requests_by_fid(fsp, NT_STATUS_DELETE_PENDING);
688 }
689 } else {
690 TALLOC_FREE(lck);
691 remove_pending_change_notify_requests_by_fid(
692 fsp, NT_STATUS_OK);
693 }
694
695 /*
696 * Do the code common to files and directories.
697 */
698 close_filestruct(fsp);
699 file_free(fsp);
700 return status;
701}
702
703/****************************************************************************
704 Close a 'stat file' opened internally.
705****************************************************************************/
706
707static NTSTATUS close_stat(files_struct *fsp)
708{
709 /*
710 * Do the code common to files and directories.
711 */
712 close_filestruct(fsp);
713 file_free(fsp);
714 return NT_STATUS_OK;
715}
716
717/****************************************************************************
718 Close a files_struct.
719****************************************************************************/
720
721NTSTATUS close_file(files_struct *fsp, enum file_close_type close_type)
722{
723 NTSTATUS status;
724 struct files_struct *base_fsp = fsp->base_fsp;
725
726 if(fsp->is_directory) {
727 status = close_directory(fsp, close_type);
728 } else if (fsp->is_stat) {
729 status = close_stat(fsp);
730 } else if (fsp->fake_file_handle != NULL) {
731 status = close_fake_file(fsp);
732 } else {
733 status = close_normal_file(fsp, close_type);
734 }
735
736 if ((base_fsp != NULL) && (close_type != SHUTDOWN_CLOSE)) {
737
738 /*
739 * fsp was a stream, the base fsp can't be a stream as well
740 *
741 * For SHUTDOWN_CLOSE this is not possible here, because
742 * SHUTDOWN_CLOSE only happens from files.c which walks the
743 * complete list of files. If we mess with more than one fsp
744 * those loops will become confused.
745 */
746
747 SMB_ASSERT(base_fsp->base_fsp == NULL);
748 close_file(base_fsp, close_type);
749 }
750
751 return status;
752}
753
754/****************************************************************************
755 Deal with an (authorized) message to close a file given the share mode
756 entry.
757****************************************************************************/
758
759void msg_close_file(struct messaging_context *msg_ctx,
760 void *private_data,
761 uint32_t msg_type,
762 struct server_id server_id,
763 DATA_BLOB *data)
764{
765 files_struct *fsp = NULL;
766 struct share_mode_entry e;
767
768 message_to_share_mode_entry(&e, (char *)data->data);
769
770 if(DEBUGLVL(10)) {
771 char *sm_str = share_mode_str(NULL, 0, &e);
772 if (!sm_str) {
773 smb_panic("talloc failed");
774 }
775 DEBUG(10,("msg_close_file: got request to close share mode "
776 "entry %s\n", sm_str));
777 TALLOC_FREE(sm_str);
778 }
779
780 fsp = file_find_dif(e.id, e.share_file_id);
781 if (!fsp) {
782 DEBUG(10,("msg_close_file: failed to find file.\n"));
783 return;
784 }
785 close_file(fsp, NORMAL_CLOSE);
786}
Note: See TracBrowser for help on using the repository browser.