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