50111f62bbf2f74adb7f983fad0d2438e87d256e
[sfrench/samba-autobuild/.git] / source3 / 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         /* As we now have POSIX opens which can unlink
291          * with other open files we may have taken
292          * this code path with more than one share mode
293          * entry - ensure we only delete once by resetting
294          * the delete on close flag. JRA.
295          */
296
297         set_delete_on_close_lck(lck, False, NULL);
298
299  done:
300
301         /* unbecome user. */
302         pop_sec_ctx();
303         
304         TALLOC_FREE(lck);
305         return status;
306 }
307
308 /****************************************************************************
309  Close a file.
310
311  close_type can be NORMAL_CLOSE=0,SHUTDOWN_CLOSE,ERROR_CLOSE.
312  printing and magic scripts are only run on normal close.
313  delete on close is done on normal and shutdown close.
314 ****************************************************************************/
315
316 static NTSTATUS close_normal_file(files_struct *fsp, enum file_close_type close_type)
317 {
318         NTSTATUS status = NT_STATUS_OK;
319         NTSTATUS saved_status1 = NT_STATUS_OK;
320         NTSTATUS saved_status2 = NT_STATUS_OK;
321         connection_struct *conn = fsp->conn;
322
323         cancel_aio_by_fsp(fsp);
324  
325         /*
326          * If we're flushing on a close we can get a write
327          * error here, we must remember this.
328          */
329
330         saved_status1 = close_filestruct(fsp);
331
332         if (fsp->print_file) {
333                 print_fsp_end(fsp, close_type);
334                 file_free(fsp);
335                 return NT_STATUS_OK;
336         }
337
338         /* If this is an old DOS or FCB open and we have multiple opens on
339            the same handle we only have one share mode. Ensure we only remove
340            the share mode on the last close. */
341
342         if (fsp->fh->ref_count == 1) {
343                 /* Should we return on error here... ? */
344                 saved_status2 = close_remove_share_mode(fsp, close_type);
345         }
346
347         if(fsp->oplock_type) {
348                 release_file_oplock(fsp);
349         }
350
351         locking_close_file(fsp);
352
353         status = fd_close(conn, fsp);
354
355         /* check for magic scripts */
356         if (close_type == NORMAL_CLOSE) {
357                 check_magic(fsp,conn);
358         }
359
360         /*
361          * Ensure pending modtime is set after close.
362          */
363
364         if(fsp->pending_modtime && fsp->pending_modtime_owner) {
365                 set_filetime(conn, fsp->fsp_name, fsp->pending_modtime);
366         } else if (fsp->last_write_time) {
367                 set_filetime(conn, fsp->fsp_name, fsp->last_write_time);
368         }
369
370         if (NT_STATUS_IS_OK(status)) {
371                 if (!NT_STATUS_IS_OK(saved_status1)) {
372                         status = saved_status1;
373                 } else if (!NT_STATUS_IS_OK(saved_status2)) {
374                         status = saved_status2;
375                 }
376         }
377
378         DEBUG(2,("%s closed file %s (numopen=%d) %s\n",
379                 conn->user,fsp->fsp_name,
380                 conn->num_files_open,
381                 nt_errstr(status) ));
382
383         file_free(fsp);
384         return status;
385 }
386
387 /****************************************************************************
388  Close a directory opened by an NT SMB call. 
389 ****************************************************************************/
390   
391 static NTSTATUS close_directory(files_struct *fsp, enum file_close_type close_type)
392 {
393         struct share_mode_lock *lck = 0;
394         BOOL delete_dir = False;
395         NTSTATUS status = NT_STATUS_OK;
396
397         /*
398          * NT can set delete_on_close of the last open
399          * reference to a directory also.
400          */
401
402         lck = get_share_mode_lock(NULL, fsp->dev, fsp->inode, NULL, NULL);
403
404         if (lck == NULL) {
405                 DEBUG(0, ("close_directory: Could not get share mode lock for %s\n", fsp->fsp_name));
406                 return NT_STATUS_INVALID_PARAMETER;
407         }
408
409         if (!del_share_mode(lck, fsp)) {
410                 DEBUG(0, ("close_directory: Could not delete share entry for %s\n", fsp->fsp_name));
411         }
412
413         if (fsp->initial_delete_on_close) {
414                 BOOL became_user = False;
415
416                 /* Initial delete on close was set - for
417                  * directories we don't care if anyone else
418                  * wrote a real delete on close. */
419
420                 if (current_user.vuid != fsp->vuid) {
421                         become_user(fsp->conn, fsp->vuid);
422                         became_user = True;
423                 }
424                 send_stat_cache_delete_message(fsp->fsp_name);
425                 set_delete_on_close_lck(lck, True, &current_user.ut);
426                 if (became_user) {
427                         unbecome_user();
428                 }
429         }
430
431         delete_dir = lck->delete_on_close;
432
433         if (delete_dir) {
434                 int i;
435                 /* See if others still have the dir open. If this is the
436                  * case, then don't delete. If all opens are POSIX delete now. */
437                 for (i=0; i<lck->num_share_modes; i++) {
438                         struct share_mode_entry *e = &lck->share_modes[i];
439                         if (is_valid_share_mode_entry(e)) {
440                                 if (fsp->posix_open && (e->flags & SHARE_MODE_FLAG_POSIX_OPEN)) {
441                                         continue;
442                                 }
443                                 delete_dir = False;
444                                 break;
445                         }
446                 }
447         }
448
449         if ((close_type == NORMAL_CLOSE || close_type == SHUTDOWN_CLOSE) &&
450                                 delete_dir &&
451                                 lck->delete_token) {
452         
453                 /* Become the user who requested the delete. */
454
455                 if (!push_sec_ctx()) {
456                         smb_panic("close_directory: failed to push sec_ctx.\n");
457                 }
458
459                 set_sec_ctx(lck->delete_token->uid,
460                                 lck->delete_token->gid,
461                                 lck->delete_token->ngroups,
462                                 lck->delete_token->groups,
463                                 NULL);
464
465                 TALLOC_FREE(lck);
466
467                 status = rmdir_internals(fsp->conn, fsp->fsp_name);
468
469                 DEBUG(5,("close_directory: %s. Delete on close was set - "
470                          "deleting directory returned %s.\n",
471                          fsp->fsp_name, nt_errstr(status)));
472
473                 /* unbecome user. */
474                 pop_sec_ctx();
475
476                 /*
477                  * Ensure we remove any change notify requests that would
478                  * now fail as the directory has been deleted.
479                  */
480
481                 if(NT_STATUS_IS_OK(status)) {
482                         remove_pending_change_notify_requests_by_fid(fsp, NT_STATUS_DELETE_PENDING);
483                 }
484         } else {
485                 TALLOC_FREE(lck);
486                 remove_pending_change_notify_requests_by_fid(
487                         fsp, NT_STATUS_OK);
488         }
489
490         /*
491          * Do the code common to files and directories.
492          */
493         close_filestruct(fsp);
494         file_free(fsp);
495         return status;
496 }
497
498 /****************************************************************************
499  Close a 'stat file' opened internally.
500 ****************************************************************************/
501   
502 NTSTATUS close_stat(files_struct *fsp)
503 {
504         /*
505          * Do the code common to files and directories.
506          */
507         close_filestruct(fsp);
508         file_free(fsp);
509         return NT_STATUS_OK;
510 }
511
512 /****************************************************************************
513  Close a files_struct.
514 ****************************************************************************/
515   
516 NTSTATUS close_file(files_struct *fsp, enum file_close_type close_type)
517 {
518         if(fsp->is_directory) {
519                 return close_directory(fsp, close_type);
520         } else if (fsp->is_stat) {
521                 return close_stat(fsp);
522         } else if (fsp->fake_file_handle != NULL) {
523                 return close_fake_file(fsp);
524         }
525         return close_normal_file(fsp, close_type);
526 }