r22784: fixed change notify for delete on close
[sfrench/samba-autobuild/.git] / source / smbd / close.c
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
25 extern struct current_user current_user;
26
27 /****************************************************************************
28  Run a file if it is a magic script.
29 ****************************************************************************/
30
31 static 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
93 static 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
114 static 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
148 static 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
157         /*
158          * Lock the share entries, and determine if we should delete
159          * on close. If so delete whilst the lock is still in effect.
160          * This prevents race conditions with the file being created. JRA.
161          */
162
163         lck = get_share_mode_lock(NULL, fsp->dev, fsp->inode, NULL, NULL);
164
165         if (lck == NULL) {
166                 DEBUG(0, ("close_remove_share_mode: Could not get share mode "
167                           "lock for file %s\n", fsp->fsp_name));
168                 return NT_STATUS_INVALID_PARAMETER;
169         }
170
171         if (!del_share_mode(lck, fsp)) {
172                 DEBUG(0, ("close_remove_share_mode: Could not delete share "
173                           "entry for file %s\n", fsp->fsp_name));
174         }
175
176         if (fsp->initial_delete_on_close && (lck->delete_token == NULL)) {
177                 BOOL became_user = False;
178
179                 /* Initial delete on close was set and no one else
180                  * wrote a real delete on close. */
181
182                 if (current_user.vuid != fsp->vuid) {
183                         become_user(conn, fsp->vuid);
184                         became_user = True;
185                 }
186                 set_delete_on_close_lck(lck, True, &current_user.ut);
187                 if (became_user) {
188                         unbecome_user();
189                 }
190         }
191
192         delete_file = lck->delete_on_close;
193
194         if (delete_file) {
195                 int i;
196                 /* See if others still have the file open. If this is the
197                  * case, then don't delete. If all opens are POSIX delete now. */
198                 for (i=0; i<lck->num_share_modes; i++) {
199                         struct share_mode_entry *e = &lck->share_modes[i];
200                         if (is_valid_share_mode_entry(e)) {
201                                 if (fsp->posix_open && (e->flags & SHARE_MODE_FLAG_POSIX_OPEN)) {
202                                         continue;
203                                 }
204                                 delete_file = False;
205                                 break;
206                         }
207                 }
208         }
209
210         /* Notify any deferred opens waiting on this close. */
211         notify_deferred_opens(lck);
212         reply_to_oplock_break_requests(fsp);
213
214         /*
215          * NT can set delete_on_close of the last open
216          * reference to a file.
217          */
218
219         if (!(close_type == NORMAL_CLOSE || close_type == SHUTDOWN_CLOSE)
220             || !delete_file
221             || (lck->delete_token == NULL)) {
222                 TALLOC_FREE(lck);
223                 return NT_STATUS_OK;
224         }
225
226         /*
227          * Ok, we have to delete the file
228          */
229
230         DEBUG(5,("close_remove_share_mode: file %s. Delete on close was set "
231                  "- deleting file.\n", fsp->fsp_name));
232
233         /* Become the user who requested the delete. */
234
235         if (!push_sec_ctx()) {
236                 smb_panic("close_remove_share_mode: file %s. failed to push "
237                           "sec_ctx.\n");
238         }
239
240         set_sec_ctx(lck->delete_token->uid,
241                     lck->delete_token->gid,
242                     lck->delete_token->ngroups,
243                     lck->delete_token->groups,
244                     NULL);
245
246         /* We can only delete the file if the name we have is still valid and
247            hasn't been renamed. */
248         
249         if(SMB_VFS_STAT(conn,fsp->fsp_name,&sbuf) != 0) {
250                 DEBUG(5,("close_remove_share_mode: file %s. Delete on close "
251                          "was set and stat failed with error %s\n",
252                          fsp->fsp_name, strerror(errno) ));
253                 /*
254                  * Don't save the errno here, we ignore this error
255                  */
256                 goto done;
257         }
258
259         if(sbuf.st_dev != fsp->dev || sbuf.st_ino != fsp->inode) {
260                 DEBUG(5,("close_remove_share_mode: file %s. Delete on close "
261                          "was set and dev and/or inode does not match\n",
262                          fsp->fsp_name ));
263                 DEBUG(5,("close_remove_share_mode: file %s. stored dev = %x, "
264                          "inode = %.0f stat dev = %x, inode = %.0f\n",
265                          fsp->fsp_name,
266                          (unsigned int)fsp->dev, (double)fsp->inode,
267                          (unsigned int)sbuf.st_dev, (double)sbuf.st_ino ));
268                 /*
269                  * Don't save the errno here, we ignore this error
270                  */
271                 goto done;
272         }
273
274         if (SMB_VFS_UNLINK(conn,fsp->fsp_name) != 0) {
275                 /*
276                  * This call can potentially fail as another smbd may
277                  * have had the file open with delete on close set and
278                  * deleted it when its last reference to this file
279                  * went away. Hence we log this but not at debug level
280                  * zero.
281                  */
282
283                 DEBUG(5,("close_remove_share_mode: file %s. Delete on close "
284                          "was set and unlink failed with error %s\n",
285                          fsp->fsp_name, strerror(errno) ));
286
287                 status = map_nt_error_from_unix(errno);
288         }
289
290         notify_fname(conn, NOTIFY_ACTION_REMOVED,
291                      FILE_NOTIFY_CHANGE_FILE_NAME,
292                      fsp->fsp_name);
293
294         /* As we now have POSIX opens which can unlink
295          * with other open files we may have taken
296          * this code path with more than one share mode
297          * entry - ensure we only delete once by resetting
298          * the delete on close flag. JRA.
299          */
300
301         set_delete_on_close_lck(lck, False, NULL);
302
303  done:
304
305         /* unbecome user. */
306         pop_sec_ctx();
307         
308         TALLOC_FREE(lck);
309         return status;
310 }
311
312 /****************************************************************************
313  Close a file.
314
315  close_type can be NORMAL_CLOSE=0,SHUTDOWN_CLOSE,ERROR_CLOSE.
316  printing and magic scripts are only run on normal close.
317  delete on close is done on normal and shutdown close.
318 ****************************************************************************/
319
320 static NTSTATUS close_normal_file(files_struct *fsp, enum file_close_type close_type)
321 {
322         NTSTATUS status = NT_STATUS_OK;
323         NTSTATUS saved_status1 = NT_STATUS_OK;
324         NTSTATUS saved_status2 = NT_STATUS_OK;
325         connection_struct *conn = fsp->conn;
326
327         cancel_aio_by_fsp(fsp);
328  
329         /*
330          * If we're flushing on a close we can get a write
331          * error here, we must remember this.
332          */
333
334         saved_status1 = close_filestruct(fsp);
335
336         if (fsp->print_file) {
337                 print_fsp_end(fsp, close_type);
338                 file_free(fsp);
339                 return NT_STATUS_OK;
340         }
341
342         /* If this is an old DOS or FCB open and we have multiple opens on
343            the same handle we only have one share mode. Ensure we only remove
344            the share mode on the last close. */
345
346         if (fsp->fh->ref_count == 1) {
347                 /* Should we return on error here... ? */
348                 saved_status2 = close_remove_share_mode(fsp, close_type);
349         }
350
351         if(fsp->oplock_type) {
352                 release_file_oplock(fsp);
353         }
354
355         locking_close_file(fsp);
356
357         status = fd_close(conn, fsp);
358
359         /* check for magic scripts */
360         if (close_type == NORMAL_CLOSE) {
361                 check_magic(fsp,conn);
362         }
363
364         /*
365          * Ensure pending modtime is set after close.
366          */
367
368         if (fsp->pending_modtime_owner && !null_timespec(fsp->pending_modtime)) {
369                 set_filetime(conn, fsp->fsp_name, fsp->pending_modtime);
370         } else if (!null_timespec(fsp->last_write_time)) {
371                 set_filetime(conn, fsp->fsp_name, fsp->last_write_time);
372         }
373
374         if (NT_STATUS_IS_OK(status)) {
375                 if (!NT_STATUS_IS_OK(saved_status1)) {
376                         status = saved_status1;
377                 } else if (!NT_STATUS_IS_OK(saved_status2)) {
378                         status = saved_status2;
379                 }
380         }
381
382         DEBUG(2,("%s closed file %s (numopen=%d) %s\n",
383                 conn->user,fsp->fsp_name,
384                 conn->num_files_open,
385                 nt_errstr(status) ));
386
387         file_free(fsp);
388         return status;
389 }
390
391 /****************************************************************************
392  Close a directory opened by an NT SMB call. 
393 ****************************************************************************/
394   
395 static NTSTATUS close_directory(files_struct *fsp, enum file_close_type close_type)
396 {
397         struct share_mode_lock *lck = 0;
398         BOOL delete_dir = False;
399         NTSTATUS status = NT_STATUS_OK;
400
401         /*
402          * NT can set delete_on_close of the last open
403          * reference to a directory also.
404          */
405
406         lck = get_share_mode_lock(NULL, fsp->dev, fsp->inode, NULL, NULL);
407
408         if (lck == NULL) {
409                 DEBUG(0, ("close_directory: Could not get share mode lock for %s\n", fsp->fsp_name));
410                 return NT_STATUS_INVALID_PARAMETER;
411         }
412
413         if (!del_share_mode(lck, fsp)) {
414                 DEBUG(0, ("close_directory: Could not delete share entry for %s\n", fsp->fsp_name));
415         }
416
417         if (fsp->initial_delete_on_close) {
418                 BOOL became_user = False;
419
420                 /* Initial delete on close was set - for
421                  * directories we don't care if anyone else
422                  * wrote a real delete on close. */
423
424                 if (current_user.vuid != fsp->vuid) {
425                         become_user(fsp->conn, fsp->vuid);
426                         became_user = True;
427                 }
428                 send_stat_cache_delete_message(fsp->fsp_name);
429                 set_delete_on_close_lck(lck, True, &current_user.ut);
430                 if (became_user) {
431                         unbecome_user();
432                 }
433         }
434
435         delete_dir = lck->delete_on_close;
436
437         if (delete_dir) {
438                 int i;
439                 /* See if others still have the dir open. If this is the
440                  * case, then don't delete. If all opens are POSIX delete now. */
441                 for (i=0; i<lck->num_share_modes; i++) {
442                         struct share_mode_entry *e = &lck->share_modes[i];
443                         if (is_valid_share_mode_entry(e)) {
444                                 if (fsp->posix_open && (e->flags & SHARE_MODE_FLAG_POSIX_OPEN)) {
445                                         continue;
446                                 }
447                                 delete_dir = False;
448                                 break;
449                         }
450                 }
451         }
452
453         if ((close_type == NORMAL_CLOSE || close_type == SHUTDOWN_CLOSE) &&
454                                 delete_dir &&
455                                 lck->delete_token) {
456         
457                 /* Become the user who requested the delete. */
458
459                 if (!push_sec_ctx()) {
460                         smb_panic("close_directory: failed to push sec_ctx.\n");
461                 }
462
463                 set_sec_ctx(lck->delete_token->uid,
464                                 lck->delete_token->gid,
465                                 lck->delete_token->ngroups,
466                                 lck->delete_token->groups,
467                                 NULL);
468
469                 TALLOC_FREE(lck);
470
471                 status = rmdir_internals(fsp->conn, fsp->fsp_name);
472
473                 DEBUG(5,("close_directory: %s. Delete on close was set - "
474                          "deleting directory returned %s.\n",
475                          fsp->fsp_name, nt_errstr(status)));
476
477                 /* unbecome user. */
478                 pop_sec_ctx();
479
480                 /*
481                  * Ensure we remove any change notify requests that would
482                  * now fail as the directory has been deleted.
483                  */
484
485                 if(NT_STATUS_IS_OK(status)) {
486                         remove_pending_change_notify_requests_by_fid(fsp, NT_STATUS_DELETE_PENDING);
487                 }
488         } else {
489                 TALLOC_FREE(lck);
490                 remove_pending_change_notify_requests_by_fid(
491                         fsp, NT_STATUS_OK);
492         }
493
494         /*
495          * Do the code common to files and directories.
496          */
497         close_filestruct(fsp);
498         file_free(fsp);
499         return status;
500 }
501
502 /****************************************************************************
503  Close a 'stat file' opened internally.
504 ****************************************************************************/
505   
506 NTSTATUS close_stat(files_struct *fsp)
507 {
508         /*
509          * Do the code common to files and directories.
510          */
511         close_filestruct(fsp);
512         file_free(fsp);
513         return NT_STATUS_OK;
514 }
515
516 /****************************************************************************
517  Close a files_struct.
518 ****************************************************************************/
519   
520 NTSTATUS close_file(files_struct *fsp, enum file_close_type close_type)
521 {
522         if(fsp->is_directory) {
523                 return close_directory(fsp, close_type);
524         } else if (fsp->is_stat) {
525                 return close_stat(fsp);
526         } else if (fsp->fake_file_handle != NULL) {
527                 return close_fake_file(fsp);
528         }
529         return close_normal_file(fsp, close_type);
530 }