r23779: Change from v2 or later to v3 or later.
[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 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, 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                         messaging_send_buf(smbd_messaging_context(),
139                                            e->pid, MSG_SMB_OPEN_RETRY,
140                                            (uint8 *)msg,
141                                            MSG_SMB_SHARE_MODE_ENTRY_SIZE);
142                 }
143         }
144 }
145
146 /****************************************************************************
147  Deal with removing a share mode on last close.
148 ****************************************************************************/
149
150 static NTSTATUS close_remove_share_mode(files_struct *fsp,
151                                         enum file_close_type close_type)
152 {
153         connection_struct *conn = fsp->conn;
154         BOOL delete_file = False;
155         struct share_mode_lock *lck;
156         SMB_STRUCT_STAT sbuf;
157         NTSTATUS status = NT_STATUS_OK;
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(SMB_VFS_STAT(conn,fsp->fsp_name,&sbuf) != 0) {
253                 DEBUG(5,("close_remove_share_mode: file %s. Delete on close "
254                          "was set and stat failed with error %s\n",
255                          fsp->fsp_name, strerror(errno) ));
256                 /*
257                  * Don't save the errno here, we ignore this error
258                  */
259                 goto done;
260         }
261
262         id = file_id_sbuf(&sbuf);
263
264         if (!file_id_equal(&fsp->file_id, &id)) {
265                 DEBUG(5,("close_remove_share_mode: file %s. Delete on close "
266                          "was set and dev and/or inode does not match\n",
267                          fsp->fsp_name ));
268                 DEBUG(5,("close_remove_share_mode: file %s. stored file_id %s, "
269                          "stat file_id %s\n",
270                          fsp->fsp_name,
271                          file_id_static_string(&fsp->file_id),
272                          file_id_static_string2(&id)));
273                 /*
274                  * Don't save the errno here, we ignore this error
275                  */
276                 goto done;
277         }
278
279         if (SMB_VFS_UNLINK(conn,fsp->fsp_name) != 0) {
280                 /*
281                  * This call can potentially fail as another smbd may
282                  * have had the file open with delete on close set and
283                  * deleted it when its last reference to this file
284                  * went away. Hence we log this but not at debug level
285                  * zero.
286                  */
287
288                 DEBUG(5,("close_remove_share_mode: file %s. Delete on close "
289                          "was set and unlink failed with error %s\n",
290                          fsp->fsp_name, strerror(errno) ));
291
292                 status = map_nt_error_from_unix(errno);
293         }
294
295         notify_fname(conn, NOTIFY_ACTION_REMOVED,
296                      FILE_NOTIFY_CHANGE_FILE_NAME,
297                      fsp->fsp_name);
298
299         /* As we now have POSIX opens which can unlink
300          * with other open files we may have taken
301          * this code path with more than one share mode
302          * entry - ensure we only delete once by resetting
303          * the delete on close flag. JRA.
304          */
305
306         set_delete_on_close_lck(lck, False, NULL);
307
308  done:
309
310         /* unbecome user. */
311         pop_sec_ctx();
312         
313         TALLOC_FREE(lck);
314         return status;
315 }
316
317 /****************************************************************************
318  Close a file.
319
320  close_type can be NORMAL_CLOSE=0,SHUTDOWN_CLOSE,ERROR_CLOSE.
321  printing and magic scripts are only run on normal close.
322  delete on close is done on normal and shutdown close.
323 ****************************************************************************/
324
325 static NTSTATUS close_normal_file(files_struct *fsp, enum file_close_type close_type)
326 {
327         NTSTATUS status = NT_STATUS_OK;
328         NTSTATUS saved_status1 = NT_STATUS_OK;
329         NTSTATUS saved_status2 = NT_STATUS_OK;
330         connection_struct *conn = fsp->conn;
331
332         cancel_aio_by_fsp(fsp);
333  
334         /*
335          * If we're flushing on a close we can get a write
336          * error here, we must remember this.
337          */
338
339         saved_status1 = close_filestruct(fsp);
340
341         if (fsp->print_file) {
342                 print_fsp_end(fsp, close_type);
343                 file_free(fsp);
344                 return NT_STATUS_OK;
345         }
346
347         /* If this is an old DOS or FCB open and we have multiple opens on
348            the same handle we only have one share mode. Ensure we only remove
349            the share mode on the last close. */
350
351         if (fsp->fh->ref_count == 1) {
352                 /* Should we return on error here... ? */
353                 saved_status2 = close_remove_share_mode(fsp, close_type);
354         }
355
356         if(fsp->oplock_type) {
357                 release_file_oplock(fsp);
358         }
359
360         locking_close_file(smbd_messaging_context(), fsp);
361
362         status = fd_close(conn, fsp);
363
364         /* check for magic scripts */
365         if (close_type == NORMAL_CLOSE) {
366                 check_magic(fsp,conn);
367         }
368
369         /*
370          * Ensure pending modtime is set after close.
371          */
372
373         if (fsp->pending_modtime_owner && !null_timespec(fsp->pending_modtime)) {
374                 set_filetime(conn, fsp->fsp_name, fsp->pending_modtime);
375         } else if (!null_timespec(fsp->last_write_time)) {
376                 set_filetime(conn, fsp->fsp_name, fsp->last_write_time);
377         }
378
379         if (NT_STATUS_IS_OK(status)) {
380                 if (!NT_STATUS_IS_OK(saved_status1)) {
381                         status = saved_status1;
382                 } else if (!NT_STATUS_IS_OK(saved_status2)) {
383                         status = saved_status2;
384                 }
385         }
386
387         DEBUG(2,("%s closed file %s (numopen=%d) %s\n",
388                 conn->user,fsp->fsp_name,
389                 conn->num_files_open,
390                 nt_errstr(status) ));
391
392         file_free(fsp);
393         return status;
394 }
395
396 /****************************************************************************
397  Close a directory opened by an NT SMB call. 
398 ****************************************************************************/
399   
400 static NTSTATUS close_directory(files_struct *fsp, enum file_close_type close_type)
401 {
402         struct share_mode_lock *lck = 0;
403         BOOL delete_dir = False;
404         NTSTATUS status = NT_STATUS_OK;
405
406         /*
407          * NT can set delete_on_close of the last open
408          * reference to a directory also.
409          */
410
411         lck = get_share_mode_lock(NULL, fsp->file_id, NULL, NULL);
412
413         if (lck == NULL) {
414                 DEBUG(0, ("close_directory: Could not get share mode lock for %s\n", fsp->fsp_name));
415                 return NT_STATUS_INVALID_PARAMETER;
416         }
417
418         if (!del_share_mode(lck, fsp)) {
419                 DEBUG(0, ("close_directory: Could not delete share entry for %s\n", fsp->fsp_name));
420         }
421
422         if (fsp->initial_delete_on_close) {
423                 BOOL became_user = False;
424
425                 /* Initial delete on close was set - for
426                  * directories we don't care if anyone else
427                  * wrote a real delete on close. */
428
429                 if (current_user.vuid != fsp->vuid) {
430                         become_user(fsp->conn, fsp->vuid);
431                         became_user = True;
432                 }
433                 send_stat_cache_delete_message(fsp->fsp_name);
434                 set_delete_on_close_lck(lck, True, &current_user.ut);
435                 if (became_user) {
436                         unbecome_user();
437                 }
438         }
439
440         delete_dir = lck->delete_on_close;
441
442         if (delete_dir) {
443                 int i;
444                 /* See if others still have the dir open. If this is the
445                  * case, then don't delete. If all opens are POSIX delete now. */
446                 for (i=0; i<lck->num_share_modes; i++) {
447                         struct share_mode_entry *e = &lck->share_modes[i];
448                         if (is_valid_share_mode_entry(e)) {
449                                 if (fsp->posix_open && (e->flags & SHARE_MODE_FLAG_POSIX_OPEN)) {
450                                         continue;
451                                 }
452                                 delete_dir = False;
453                                 break;
454                         }
455                 }
456         }
457
458         if ((close_type == NORMAL_CLOSE || close_type == SHUTDOWN_CLOSE) &&
459                                 delete_dir &&
460                                 lck->delete_token) {
461         
462                 /* Become the user who requested the delete. */
463
464                 if (!push_sec_ctx()) {
465                         smb_panic("close_directory: failed to push sec_ctx.\n");
466                 }
467
468                 set_sec_ctx(lck->delete_token->uid,
469                                 lck->delete_token->gid,
470                                 lck->delete_token->ngroups,
471                                 lck->delete_token->groups,
472                                 NULL);
473
474                 TALLOC_FREE(lck);
475
476                 status = rmdir_internals(fsp->conn, fsp->fsp_name);
477
478                 DEBUG(5,("close_directory: %s. Delete on close was set - "
479                          "deleting directory returned %s.\n",
480                          fsp->fsp_name, nt_errstr(status)));
481
482                 /* unbecome user. */
483                 pop_sec_ctx();
484
485                 /*
486                  * Ensure we remove any change notify requests that would
487                  * now fail as the directory has been deleted.
488                  */
489
490                 if(NT_STATUS_IS_OK(status)) {
491                         remove_pending_change_notify_requests_by_fid(fsp, NT_STATUS_DELETE_PENDING);
492                 }
493         } else {
494                 TALLOC_FREE(lck);
495                 remove_pending_change_notify_requests_by_fid(
496                         fsp, NT_STATUS_OK);
497         }
498
499         /*
500          * Do the code common to files and directories.
501          */
502         close_filestruct(fsp);
503         file_free(fsp);
504         return status;
505 }
506
507 /****************************************************************************
508  Close a 'stat file' opened internally.
509 ****************************************************************************/
510   
511 NTSTATUS close_stat(files_struct *fsp)
512 {
513         /*
514          * Do the code common to files and directories.
515          */
516         close_filestruct(fsp);
517         file_free(fsp);
518         return NT_STATUS_OK;
519 }
520
521 /****************************************************************************
522  Close a files_struct.
523 ****************************************************************************/
524   
525 NTSTATUS close_file(files_struct *fsp, enum file_close_type close_type)
526 {
527         if(fsp->is_directory) {
528                 return close_directory(fsp, close_type);
529         } else if (fsp->is_stat) {
530                 return close_stat(fsp);
531         } else if (fsp->fake_file_handle != NULL) {
532                 return close_fake_file(fsp);
533         }
534         return close_normal_file(fsp, close_type);
535 }