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