source: branches/samba-3.0/source/smbd/close.c@ 411

Last change on this file since 411 was 62, checked in by Paul Smedley, 18 years ago

Update source to 3.0.25c level

File size: 14.9 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 2 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, write to the Free Software
20 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21*/
22
23#include "includes.h"
24
25extern struct current_user current_user;
26
27/****************************************************************************
28 Run a file if it is a magic script.
29****************************************************************************/
30
31static void check_magic(files_struct *fsp,connection_struct *conn)
32{
33 if (!*lp_magicscript(SNUM(conn)))
34 return;
35
36 DEBUG(5,("checking magic for %s\n",fsp->fsp_name));
37
38 {
39 char *p;
40 if (!(p = strrchr_m(fsp->fsp_name,'/')))
41 p = fsp->fsp_name;
42 else
43 p++;
44
45 if (!strequal(lp_magicscript(SNUM(conn)),p))
46 return;
47 }
48
49 {
50 int ret;
51 pstring magic_output;
52 pstring fname;
53 SMB_STRUCT_STAT st;
54 int tmp_fd, outfd;
55
56 pstrcpy(fname,fsp->fsp_name);
57 if (*lp_magicoutput(SNUM(conn)))
58 pstrcpy(magic_output,lp_magicoutput(SNUM(conn)));
59 else
60 slprintf(magic_output,sizeof(fname)-1, "%s.out",fname);
61
62 chmod(fname,0755);
63 ret = smbrun(fname,&tmp_fd);
64 DEBUG(3,("Invoking magic command %s gave %d\n",fname,ret));
65 unlink(fname);
66 if (ret != 0 || tmp_fd == -1) {
67 if (tmp_fd != -1)
68 close(tmp_fd);
69 return;
70 }
71 outfd = open(magic_output, O_CREAT|O_EXCL|O_RDWR, 0600);
72 if (outfd == -1) {
73 close(tmp_fd);
74 return;
75 }
76
77 if (sys_fstat(tmp_fd,&st) == -1) {
78 close(tmp_fd);
79 close(outfd);
80 return;
81 }
82
83 transfer_file(tmp_fd,outfd,(SMB_OFF_T)st.st_size);
84 close(tmp_fd);
85 close(outfd);
86 }
87}
88
89/****************************************************************************
90 Common code to close a file or a directory.
91****************************************************************************/
92
93static NTSTATUS close_filestruct(files_struct *fsp)
94{
95 NTSTATUS status = NT_STATUS_OK;
96 connection_struct *conn = fsp->conn;
97
98 if (fsp->fh->fd != -1) {
99 if(flush_write_cache(fsp, CLOSE_FLUSH) == -1) {
100 status = map_nt_error_from_unix(errno);
101 }
102 delete_write_cache(fsp);
103 }
104
105 conn->num_files_open--;
106 SAFE_FREE(fsp->wbmpx_ptr);
107 return status;
108}
109
110/****************************************************************************
111 If any deferred opens are waiting on this close, notify them.
112****************************************************************************/
113
114static void notify_deferred_opens(struct share_mode_lock *lck)
115{
116 int i;
117
118 for (i=0; i<lck->num_share_modes; i++) {
119 struct share_mode_entry *e = &lck->share_modes[i];
120
121 if (!is_deferred_open_entry(e)) {
122 continue;
123 }
124
125 if (procid_is_me(&e->pid)) {
126 /*
127 * We need to notify ourself to retry the open. Do
128 * this by finding the queued SMB record, moving it to
129 * the head of the queue and changing the wait time to
130 * zero.
131 */
132 schedule_deferred_open_smb_message(e->op_mid);
133 } else {
134 char msg[MSG_SMB_SHARE_MODE_ENTRY_SIZE];
135
136 share_mode_entry_to_message(msg, e);
137
138 message_send_pid(e->pid, MSG_SMB_OPEN_RETRY,
139 msg, MSG_SMB_SHARE_MODE_ENTRY_SIZE, True);
140 }
141 }
142}
143
144/****************************************************************************
145 Deal with removing a share mode on last close.
146****************************************************************************/
147
148static NTSTATUS close_remove_share_mode(files_struct *fsp,
149 enum file_close_type close_type)
150{
151 connection_struct *conn = fsp->conn;
152 BOOL delete_file = False;
153 struct share_mode_lock *lck;
154 SMB_STRUCT_STAT sbuf;
155 NTSTATUS status = NT_STATUS_OK;
156 int ret;
157
158 /*
159 * Lock the share entries, and determine if we should delete
160 * on close. If so delete whilst the lock is still in effect.
161 * This prevents race conditions with the file being created. JRA.
162 */
163
164 lck = get_share_mode_lock(NULL, fsp->dev, fsp->inode, NULL, NULL);
165
166 if (lck == NULL) {
167 DEBUG(0, ("close_remove_share_mode: Could not get share mode "
168 "lock for file %s\n", fsp->fsp_name));
169 return NT_STATUS_INVALID_PARAMETER;
170 }
171
172 if (!del_share_mode(lck, fsp)) {
173 DEBUG(0, ("close_remove_share_mode: Could not delete share "
174 "entry for file %s\n", fsp->fsp_name));
175 }
176
177 if (fsp->initial_delete_on_close && (lck->delete_token == NULL)) {
178 BOOL became_user = False;
179
180 /* Initial delete on close was set and no one else
181 * wrote a real delete on close. */
182
183 if (current_user.vuid != fsp->vuid) {
184 become_user(conn, fsp->vuid);
185 became_user = True;
186 }
187 set_delete_on_close_lck(lck, True, &current_user.ut);
188 if (became_user) {
189 unbecome_user();
190 }
191 }
192
193 delete_file = lck->delete_on_close;
194
195 if (delete_file) {
196 int i;
197 /* See if others still have the file open. If this is the
198 * case, then don't delete. If all opens are POSIX delete now. */
199 for (i=0; i<lck->num_share_modes; i++) {
200 struct share_mode_entry *e = &lck->share_modes[i];
201 if (is_valid_share_mode_entry(e)) {
202 if (fsp->posix_open && (e->flags & SHARE_MODE_FLAG_POSIX_OPEN)) {
203 continue;
204 }
205 delete_file = False;
206 break;
207 }
208 }
209 }
210
211 /* Notify any deferred opens waiting on this close. */
212 notify_deferred_opens(lck);
213 reply_to_oplock_break_requests(fsp);
214
215 /*
216 * NT can set delete_on_close of the last open
217 * reference to a file.
218 */
219
220 if (!(close_type == NORMAL_CLOSE || close_type == SHUTDOWN_CLOSE)
221 || !delete_file
222 || (lck->delete_token == NULL)) {
223 TALLOC_FREE(lck);
224 return NT_STATUS_OK;
225 }
226
227 /*
228 * Ok, we have to delete the file
229 */
230
231 DEBUG(5,("close_remove_share_mode: file %s. Delete on close was set "
232 "- deleting file.\n", fsp->fsp_name));
233
234 /* Become the user who requested the delete. */
235
236 if (!push_sec_ctx()) {
237 smb_panic("close_remove_share_mode: file %s. failed to push "
238 "sec_ctx.\n");
239 }
240
241 set_sec_ctx(lck->delete_token->uid,
242 lck->delete_token->gid,
243 lck->delete_token->ngroups,
244 lck->delete_token->groups,
245 NULL);
246
247 /* We can only delete the file if the name we have is still valid and
248 hasn't been renamed. */
249
250 if (fsp->posix_open) {
251 ret = SMB_VFS_LSTAT(conn,fsp->fsp_name,&sbuf);
252 } else {
253 ret = SMB_VFS_STAT(conn,fsp->fsp_name,&sbuf);
254 }
255
256 if (ret != 0) {
257 DEBUG(5,("close_remove_share_mode: file %s. Delete on close "
258 "was set and stat failed with error %s\n",
259 fsp->fsp_name, strerror(errno) ));
260 /*
261 * Don't save the errno here, we ignore this error
262 */
263 goto done;
264 }
265
266 if(sbuf.st_dev != fsp->dev || sbuf.st_ino != fsp->inode) {
267 DEBUG(5,("close_remove_share_mode: file %s. Delete on close "
268 "was set and dev and/or inode does not match\n",
269 fsp->fsp_name ));
270 DEBUG(5,("close_remove_share_mode: file %s. stored dev = %x, "
271 "inode = %.0f stat dev = %x, inode = %.0f\n",
272 fsp->fsp_name,
273 (unsigned int)fsp->dev, (double)fsp->inode,
274 (unsigned int)sbuf.st_dev, (double)sbuf.st_ino ));
275 /*
276 * Don't save the errno here, we ignore this error
277 */
278 goto done;
279 }
280
281 if (SMB_VFS_UNLINK(conn,fsp->fsp_name) != 0) {
282 /*
283 * This call can potentially fail as another smbd may
284 * have had the file open with delete on close set and
285 * deleted it when its last reference to this file
286 * went away. Hence we log this but not at debug level
287 * zero.
288 */
289
290 DEBUG(5,("close_remove_share_mode: file %s. Delete on close "
291 "was set and unlink failed with error %s\n",
292 fsp->fsp_name, strerror(errno) ));
293
294 status = map_nt_error_from_unix(errno);
295 }
296
297 notify_fname(conn, NOTIFY_ACTION_REMOVED,
298 FILE_NOTIFY_CHANGE_FILE_NAME,
299 fsp->fsp_name);
300
301 /* As we now have POSIX opens which can unlink
302 * with other open files we may have taken
303 * this code path with more than one share mode
304 * entry - ensure we only delete once by resetting
305 * the delete on close flag. JRA.
306 */
307
308 set_delete_on_close_lck(lck, False, NULL);
309
310 done:
311
312 /* unbecome user. */
313 pop_sec_ctx();
314
315 TALLOC_FREE(lck);
316 return status;
317}
318
319/****************************************************************************
320 Close a file.
321
322 close_type can be NORMAL_CLOSE=0,SHUTDOWN_CLOSE,ERROR_CLOSE.
323 printing and magic scripts are only run on normal close.
324 delete on close is done on normal and shutdown close.
325****************************************************************************/
326
327static NTSTATUS close_normal_file(files_struct *fsp, enum file_close_type close_type)
328{
329 NTSTATUS status = NT_STATUS_OK;
330 NTSTATUS saved_status1 = NT_STATUS_OK;
331 NTSTATUS saved_status2 = NT_STATUS_OK;
332 NTSTATUS saved_status3 = NT_STATUS_OK;
333 connection_struct *conn = fsp->conn;
334
335 if (fsp->aio_write_behind) {
336 /*
337 * If we're finishing write behind on a close we can get a write
338 * error here, we must remember this.
339 */
340 int ret = wait_for_aio_completion(fsp);
341 if (ret) {
342 saved_status1 = map_nt_error_from_unix(ret);
343 }
344 } else {
345 cancel_aio_by_fsp(fsp);
346 }
347
348 /*
349 * If we're flushing on a close we can get a write
350 * error here, we must remember this.
351 */
352
353 saved_status2 = close_filestruct(fsp);
354
355 if (fsp->print_file) {
356 print_fsp_end(fsp, close_type);
357 file_free(fsp);
358 return NT_STATUS_OK;
359 }
360
361 /* If this is an old DOS or FCB open and we have multiple opens on
362 the same handle we only have one share mode. Ensure we only remove
363 the share mode on the last close. */
364
365 if (fsp->fh->ref_count == 1) {
366 /* Should we return on error here... ? */
367 saved_status3 = close_remove_share_mode(fsp, close_type);
368 }
369
370 if(fsp->oplock_type) {
371 release_file_oplock(fsp);
372 }
373
374 locking_close_file(fsp);
375
376 status = fd_close(conn, fsp);
377
378 /* check for magic scripts */
379 if (close_type == NORMAL_CLOSE) {
380 check_magic(fsp,conn);
381 }
382
383 /*
384 * Ensure pending modtime is set after close.
385 */
386
387 if (fsp->pending_modtime_owner && !null_timespec(fsp->pending_modtime)) {
388 set_filetime(conn, fsp->fsp_name, fsp->pending_modtime);
389 } else if (!null_timespec(fsp->last_write_time)) {
390 set_filetime(conn, fsp->fsp_name, fsp->last_write_time);
391 }
392
393 if (NT_STATUS_IS_OK(status)) {
394 if (!NT_STATUS_IS_OK(saved_status1)) {
395 status = saved_status1;
396 } else if (!NT_STATUS_IS_OK(saved_status2)) {
397 status = saved_status2;
398 } else if (!NT_STATUS_IS_OK(saved_status3)) {
399 status = saved_status3;
400 }
401 }
402
403 DEBUG(2,("%s closed file %s (numopen=%d) %s\n",
404 conn->user,fsp->fsp_name,
405 conn->num_files_open,
406 nt_errstr(status) ));
407
408 file_free(fsp);
409 return status;
410}
411
412/****************************************************************************
413 Close a directory opened by an NT SMB call.
414****************************************************************************/
415
416static NTSTATUS close_directory(files_struct *fsp, enum file_close_type close_type)
417{
418 struct share_mode_lock *lck = 0;
419 BOOL delete_dir = False;
420 NTSTATUS status = NT_STATUS_OK;
421
422 /*
423 * NT can set delete_on_close of the last open
424 * reference to a directory also.
425 */
426
427 lck = get_share_mode_lock(NULL, fsp->dev, fsp->inode, NULL, NULL);
428
429 if (lck == NULL) {
430 DEBUG(0, ("close_directory: Could not get share mode lock for %s\n", fsp->fsp_name));
431 return NT_STATUS_INVALID_PARAMETER;
432 }
433
434 if (!del_share_mode(lck, fsp)) {
435 DEBUG(0, ("close_directory: Could not delete share entry for %s\n", fsp->fsp_name));
436 }
437
438 if (fsp->initial_delete_on_close) {
439 BOOL became_user = False;
440
441 /* Initial delete on close was set - for
442 * directories we don't care if anyone else
443 * wrote a real delete on close. */
444
445 if (current_user.vuid != fsp->vuid) {
446 become_user(fsp->conn, fsp->vuid);
447 became_user = True;
448 }
449 send_stat_cache_delete_message(fsp->fsp_name);
450 set_delete_on_close_lck(lck, True, &current_user.ut);
451 if (became_user) {
452 unbecome_user();
453 }
454 }
455
456 delete_dir = lck->delete_on_close;
457
458 if (delete_dir) {
459 int i;
460 /* See if others still have the dir open. If this is the
461 * case, then don't delete. If all opens are POSIX delete now. */
462 for (i=0; i<lck->num_share_modes; i++) {
463 struct share_mode_entry *e = &lck->share_modes[i];
464 if (is_valid_share_mode_entry(e)) {
465 if (fsp->posix_open && (e->flags & SHARE_MODE_FLAG_POSIX_OPEN)) {
466 continue;
467 }
468 delete_dir = False;
469 break;
470 }
471 }
472 }
473
474 if ((close_type == NORMAL_CLOSE || close_type == SHUTDOWN_CLOSE) &&
475 delete_dir &&
476 lck->delete_token) {
477
478 /* Become the user who requested the delete. */
479
480 if (!push_sec_ctx()) {
481 smb_panic("close_directory: failed to push sec_ctx.\n");
482 }
483
484 set_sec_ctx(lck->delete_token->uid,
485 lck->delete_token->gid,
486 lck->delete_token->ngroups,
487 lck->delete_token->groups,
488 NULL);
489
490 TALLOC_FREE(lck);
491
492 status = rmdir_internals(fsp->conn, fsp->fsp_name);
493
494 DEBUG(5,("close_directory: %s. Delete on close was set - "
495 "deleting directory returned %s.\n",
496 fsp->fsp_name, nt_errstr(status)));
497
498 /* unbecome user. */
499 pop_sec_ctx();
500
501 /*
502 * Ensure we remove any change notify requests that would
503 * now fail as the directory has been deleted.
504 */
505
506 if(NT_STATUS_IS_OK(status)) {
507 remove_pending_change_notify_requests_by_fid(fsp, NT_STATUS_DELETE_PENDING);
508 }
509 } else {
510 TALLOC_FREE(lck);
511 remove_pending_change_notify_requests_by_fid(
512 fsp, NT_STATUS_OK);
513 }
514
515 /*
516 * Do the code common to files and directories.
517 */
518 close_filestruct(fsp);
519 file_free(fsp);
520 return status;
521}
522
523/****************************************************************************
524 Close a 'stat file' opened internally.
525****************************************************************************/
526
527NTSTATUS close_stat(files_struct *fsp)
528{
529 /*
530 * Do the code common to files and directories.
531 */
532 close_filestruct(fsp);
533 file_free(fsp);
534 return NT_STATUS_OK;
535}
536
537/****************************************************************************
538 Close a files_struct.
539****************************************************************************/
540
541NTSTATUS close_file(files_struct *fsp, enum file_close_type close_type)
542{
543 if(fsp->is_directory) {
544 return close_directory(fsp, close_type);
545 } else if (fsp->is_stat) {
546 return close_stat(fsp);
547 } else if (fsp->fake_file_handle != NULL) {
548 return close_fake_file(fsp);
549 }
550 return close_normal_file(fsp, close_type);
551}
Note: See TracBrowser for help on using the repository browser.