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