r20524: Simplify logic of close_remove_share_mode().
[amitay/samba.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-2004.
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 /****************************************************************************
26  Run a file if it is a magic script.
27 ****************************************************************************/
28
29 static void check_magic(files_struct *fsp,connection_struct *conn)
30 {
31         if (!*lp_magicscript(SNUM(conn)))
32                 return;
33
34         DEBUG(5,("checking magic for %s\n",fsp->fsp_name));
35
36         {
37                 char *p;
38                 if (!(p = strrchr_m(fsp->fsp_name,'/')))
39                         p = fsp->fsp_name;
40                 else
41                         p++;
42
43                 if (!strequal(lp_magicscript(SNUM(conn)),p))
44                         return;
45         }
46
47         {
48                 int ret;
49                 pstring magic_output;
50                 pstring fname;
51                 SMB_STRUCT_STAT st;
52                 int tmp_fd, outfd;
53
54                 pstrcpy(fname,fsp->fsp_name);
55                 if (*lp_magicoutput(SNUM(conn)))
56                         pstrcpy(magic_output,lp_magicoutput(SNUM(conn)));
57                 else
58                         slprintf(magic_output,sizeof(fname)-1, "%s.out",fname);
59
60                 chmod(fname,0755);
61                 ret = smbrun(fname,&tmp_fd);
62                 DEBUG(3,("Invoking magic command %s gave %d\n",fname,ret));
63                 unlink(fname);
64                 if (ret != 0 || tmp_fd == -1) {
65                         if (tmp_fd != -1)
66                                 close(tmp_fd);
67                         return;
68                 }
69                 outfd = open(magic_output, O_CREAT|O_EXCL|O_RDWR, 0600);
70                 if (outfd == -1) {
71                         close(tmp_fd);
72                         return;
73                 }
74
75                 if (sys_fstat(tmp_fd,&st) == -1) {
76                         close(tmp_fd);
77                         close(outfd);
78                         return;
79                 }
80
81                 transfer_file(tmp_fd,outfd,(SMB_OFF_T)st.st_size);
82                 close(tmp_fd);
83                 close(outfd);
84         }
85 }
86
87 /****************************************************************************
88   Common code to close a file or a directory.
89 ****************************************************************************/
90
91 static int close_filestruct(files_struct *fsp)
92 {   
93         connection_struct *conn = fsp->conn;
94         int ret = 0;
95     
96         if (fsp->fh->fd != -1) {
97                 if(flush_write_cache(fsp, CLOSE_FLUSH) == -1)
98                         ret = -1;
99
100                 delete_write_cache(fsp);
101         }
102
103         conn->num_files_open--;
104         SAFE_FREE(fsp->wbmpx_ptr);
105
106         return ret;
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                         message_send_pid(e->pid, MSG_SMB_OPEN_RETRY,
138                                          msg, MSG_SMB_SHARE_MODE_ENTRY_SIZE, True);
139                 }
140         }
141 }
142
143 /****************************************************************************
144  Deal with removing a share mode on last close.
145 ****************************************************************************/
146
147 static int close_remove_share_mode(files_struct *fsp, enum file_close_type close_type)
148 {
149         connection_struct *conn = fsp->conn;
150         BOOL delete_file = False;
151         struct share_mode_lock *lck;
152         SMB_STRUCT_STAT sbuf;
153
154         /*
155          * Lock the share entries, and determine if we should delete
156          * on close. If so delete whilst the lock is still in effect.
157          * This prevents race conditions with the file being created. JRA.
158          */
159
160         lck = get_share_mode_lock(NULL, fsp->dev, fsp->inode, NULL, NULL);
161
162         if (lck == NULL) {
163                 DEBUG(0, ("close_remove_share_mode: Could not get share mode "
164                           "lock for file %s\n", fsp->fsp_name));
165                 return EINVAL;
166         }
167
168         if (!del_share_mode(lck, fsp)) {
169                 DEBUG(0, ("close_remove_share_mode: Could not delete share "
170                           "entry for file %s\n", fsp->fsp_name));
171         }
172
173         delete_file = (lck->delete_on_close | lck->initial_delete_on_close);
174
175         if (delete_file) {
176                 int i;
177                 /* See if others still have the file open. If this is the
178                  * case, then don't delete */
179                 for (i=0; i<lck->num_share_modes; i++) {
180                         if (is_valid_share_mode_entry(&lck->share_modes[i])) {
181                                 delete_file = False;
182                                 break;
183                         }
184                 }
185         }
186
187         /* Notify any deferred opens waiting on this close. */
188         notify_deferred_opens(lck);
189         reply_to_oplock_break_requests(fsp);
190
191         /*
192          * NT can set delete_on_close of the last open
193          * reference to a file.
194          */
195
196         if (!(close_type == NORMAL_CLOSE || close_type == SHUTDOWN_CLOSE)
197             || !delete_file
198             || (lck->delete_token == NULL)) {
199                 TALLOC_FREE(lck);
200                 return 0;
201         }
202
203         /*
204          * Ok, we have to delete the file
205          */
206
207         DEBUG(5,("close_remove_share_mode: file %s. Delete on close was set "
208                  "- deleting file.\n", fsp->fsp_name));
209
210         /* Become the user who requested the delete. */
211
212         if (!push_sec_ctx()) {
213                 smb_panic("close_remove_share_mode: file %s. failed to push "
214                           "sec_ctx.\n");
215         }
216
217         set_sec_ctx(lck->delete_token->uid,
218                     lck->delete_token->gid,
219                     lck->delete_token->ngroups,
220                     lck->delete_token->groups,
221                     NULL);
222
223         /* We can only delete the file if the name we have is still valid and
224            hasn't been renamed. */
225         
226         if(SMB_VFS_STAT(conn,fsp->fsp_name,&sbuf) != 0) {
227                 DEBUG(5,("close_remove_share_mode: file %s. Delete on close "
228                          "was set and stat failed with error %s\n",
229                          fsp->fsp_name, strerror(errno) ));
230                 goto done;
231         }
232
233         if(sbuf.st_dev != fsp->dev || sbuf.st_ino != fsp->inode) {
234                 DEBUG(5,("close_remove_share_mode: file %s. Delete on close "
235                          "was set and dev and/or inode does not match\n",
236                          fsp->fsp_name ));
237                 DEBUG(5,("close_remove_share_mode: file %s. stored dev = %x, "
238                          "inode = %.0f stat dev = %x, inode = %.0f\n",
239                          fsp->fsp_name,
240                          (unsigned int)fsp->dev, (double)fsp->inode,
241                          (unsigned int)sbuf.st_dev, (double)sbuf.st_ino ));
242                 goto done;
243         }
244
245         if (SMB_VFS_UNLINK(conn,fsp->fsp_name) != 0) {
246                 /*
247                  * This call can potentially fail as another smbd may
248                  * have had the file open with delete on close set and
249                  * deleted it when its last reference to this file
250                  * went away. Hence we log this but not at debug level
251                  * zero.
252                  */
253
254                 DEBUG(5,("close_remove_share_mode: file %s. Delete on close "
255                          "was set and unlink failed with error %s\n",
256                          fsp->fsp_name, strerror(errno) ));
257                 goto done;
258         }
259
260  done:
261         /* unbecome user. */
262         pop_sec_ctx();
263         
264         process_pending_change_notify_queue((time_t)0);
265
266         TALLOC_FREE(lck);
267         return 0;
268 }
269
270 /****************************************************************************
271  Close a file.
272
273  close_type can be NORMAL_CLOSE=0,SHUTDOWN_CLOSE,ERROR_CLOSE.
274  printing and magic scripts are only run on normal close.
275  delete on close is done on normal and shutdown close.
276 ****************************************************************************/
277
278 static int close_normal_file(files_struct *fsp, enum file_close_type close_type)
279 {
280         connection_struct *conn = fsp->conn;
281         int saved_errno = 0;
282         int err = 0;
283         int err1 = 0;
284
285         if (fsp->aio_write_behind) {
286                 /*
287                  * If we're finishing write behind on a close we can get a write
288                  * error here, we must remember this.
289                  */
290                 int ret = wait_for_aio_completion(fsp);
291                 if (ret) {
292                         saved_errno = ret;
293                         err1 = -1;
294                 }
295         } else {
296                 cancel_aio_by_fsp(fsp);
297         }
298  
299         /*
300          * If we're flushing on a close we can get a write
301          * error here, we must remember this.
302          */
303
304         if (close_filestruct(fsp) == -1) {
305                 saved_errno = errno;
306                 err1 = -1;
307         }
308
309         if (fsp->print_file) {
310                 print_fsp_end(fsp, close_type);
311                 file_free(fsp);
312                 return 0;
313         }
314
315         /* If this is an old DOS or FCB open and we have multiple opens on
316            the same handle we only have one share mode. Ensure we only remove
317            the share mode on the last close. */
318
319         if (fsp->fh->ref_count == 1) {
320                 /* Should we return on error here... ? */
321                 close_remove_share_mode(fsp, close_type);
322         }
323
324         if(fsp->oplock_type) {
325                 release_file_oplock(fsp);
326         }
327
328         locking_close_file(fsp);
329
330         err = fd_close(conn, fsp);
331
332         /* Only save errno if fd_close failed and we don't already
333            have an errno saved from a flush call. */
334         if ((err1 != -1) && (err == -1)) {
335                 saved_errno = errno;
336         }
337
338         /* check for magic scripts */
339         if (close_type == NORMAL_CLOSE) {
340                 check_magic(fsp,conn);
341         }
342
343         /*
344          * Ensure pending modtime is set after close.
345          */
346
347         if(fsp->pending_modtime && fsp->pending_modtime_owner) {
348                 set_filetime(conn, fsp->fsp_name, fsp->pending_modtime);
349         } else if (fsp->last_write_time) {
350                 set_filetime(conn, fsp->fsp_name, fsp->last_write_time);
351         }
352
353         DEBUG(2,("%s closed file %s (numopen=%d) %s\n",
354                 conn->user,fsp->fsp_name,
355                 conn->num_files_open,
356                 (err == -1 || err1 == -1) ? strerror(saved_errno) : ""));
357
358         file_free(fsp);
359
360         if (err == -1 || err1 == -1) {
361                 errno = saved_errno;
362                 return saved_errno;
363         } else {
364                 return 0;
365         }
366 }
367
368 /****************************************************************************
369  Close a directory opened by an NT SMB call. 
370 ****************************************************************************/
371   
372 static int close_directory(files_struct *fsp, enum file_close_type close_type)
373 {
374         struct share_mode_lock *lck = 0;
375         BOOL delete_dir = False;
376
377         /*
378          * NT can set delete_on_close of the last open
379          * reference to a directory also.
380          */
381
382         lck = get_share_mode_lock(NULL, fsp->dev, fsp->inode, NULL, NULL);
383
384         if (lck == NULL) {
385                 DEBUG(0, ("close_directory: Could not get share mode lock for %s\n", fsp->fsp_name));
386                 return EINVAL;
387         }
388
389         if (!del_share_mode(lck, fsp)) {
390                 DEBUG(0, ("close_directory: Could not delete share entry for %s\n", fsp->fsp_name));
391         }
392
393         delete_dir = (lck->delete_on_close | lck->initial_delete_on_close);
394
395         if ((close_type == NORMAL_CLOSE || close_type == SHUTDOWN_CLOSE) &&
396                                 delete_dir &&
397                                 lck->delete_token) {
398                 BOOL ok;
399         
400                 /* Become the user who requested the delete. */
401
402                 if (!push_sec_ctx()) {
403                         smb_panic("close_directory: failed to push sec_ctx.\n");
404                 }
405
406                 set_sec_ctx(lck->delete_token->uid,
407                                 lck->delete_token->gid,
408                                 lck->delete_token->ngroups,
409                                 lck->delete_token->groups,
410                                 NULL);
411
412                 TALLOC_FREE(lck);
413
414                 ok = rmdir_internals(fsp->conn, fsp->fsp_name);
415
416                 DEBUG(5,("close_directory: %s. Delete on close was set - deleting directory %s.\n",
417                         fsp->fsp_name, ok ? "succeeded" : "failed" ));
418
419                 /* unbecome user. */
420                 pop_sec_ctx();
421
422                 /*
423                  * Ensure we remove any change notify requests that would
424                  * now fail as the directory has been deleted.
425                  */
426
427                 if(ok) {
428                         remove_pending_change_notify_requests_by_fid(fsp, NT_STATUS_DELETE_PENDING);
429                         remove_pending_change_notify_requests_by_filename(fsp, NT_STATUS_DELETE_PENDING);
430
431                 }
432                 process_pending_change_notify_queue((time_t)0);
433         } else {
434                 TALLOC_FREE(lck);
435                 remove_pending_change_notify_requests_by_fid(
436                         fsp, NT_STATUS_OK);
437         }
438
439         /*
440          * Do the code common to files and directories.
441          */
442         close_filestruct(fsp);
443         file_free(fsp);
444         return 0;
445 }
446
447 /****************************************************************************
448  Close a 'stat file' opened internally.
449 ****************************************************************************/
450   
451 static int close_stat(files_struct *fsp)
452 {
453         /*
454          * Do the code common to files and directories.
455          */
456         close_filestruct(fsp);
457         file_free(fsp);
458         return 0;
459 }
460
461 /****************************************************************************
462  Close a files_struct.
463 ****************************************************************************/
464   
465 int close_file(files_struct *fsp, enum file_close_type close_type)
466 {
467         if(fsp->is_directory)
468                 return close_directory(fsp, close_type);
469         else if (fsp->is_stat)
470                 return close_stat(fsp);
471         else if (fsp->fake_file_handle != NULL)
472                 return close_fake_file(fsp);
473         else
474                 return close_normal_file(fsp, close_type);
475 }