r2016: Add message to ease access-control-debugging.
[ira/wip.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    
7    This program is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 2 of the License, or
10    (at your option) any later version.
11    
12    This program is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16    
17    You should have received a copy of the GNU General Public License
18    along with this program; if not, write to the Free Software
19    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 */
21
22 #include "includes.h"
23
24 /****************************************************************************
25  Run a file if it is a magic script.
26 ****************************************************************************/
27
28 static void check_magic(files_struct *fsp,connection_struct *conn)
29 {
30         if (!*lp_magicscript(SNUM(conn)))
31                 return;
32
33         DEBUG(5,("checking magic for %s\n",fsp->fsp_name));
34
35         {
36                 char *p;
37                 if (!(p = strrchr_m(fsp->fsp_name,'/')))
38                         p = fsp->fsp_name;
39                 else
40                         p++;
41
42                 if (!strequal(lp_magicscript(SNUM(conn)),p))
43                         return;
44         }
45
46         {
47                 int ret;
48                 pstring magic_output;
49                 pstring fname;
50                 SMB_STRUCT_STAT st;
51                 int tmp_fd, outfd;
52
53                 pstrcpy(fname,fsp->fsp_name);
54                 if (*lp_magicoutput(SNUM(conn)))
55                         pstrcpy(magic_output,lp_magicoutput(SNUM(conn)));
56                 else
57                         slprintf(magic_output,sizeof(fname)-1, "%s.out",fname);
58
59                 chmod(fname,0755);
60                 ret = smbrun(fname,&tmp_fd);
61                 DEBUG(3,("Invoking magic command %s gave %d\n",fname,ret));
62                 unlink(fname);
63                 if (ret != 0 || tmp_fd == -1) {
64                         if (tmp_fd != -1)
65                                 close(tmp_fd);
66                         return;
67                 }
68                 outfd = open(magic_output, O_CREAT|O_EXCL|O_RDWR, 0600);
69                 if (outfd == -1) {
70                         close(tmp_fd);
71                         return;
72                 }
73
74                 if (sys_fstat(tmp_fd,&st) == -1) {
75                         close(tmp_fd);
76                         close(outfd);
77                         return;
78                 }
79
80                 transfer_file(tmp_fd,outfd,(SMB_OFF_T)st.st_size);
81                 close(tmp_fd);
82                 close(outfd);
83         }
84 }
85
86 /****************************************************************************
87   Common code to close a file or a directory.
88 ****************************************************************************/
89
90 static int close_filestruct(files_struct *fsp)
91 {   
92         connection_struct *conn = fsp->conn;
93         int ret = 0;
94     
95         if (fsp->fd != -1) {
96                 if(flush_write_cache(fsp, CLOSE_FLUSH) == -1)
97                         ret = -1;
98
99                 delete_write_cache(fsp);
100         }
101
102         conn->num_files_open--;
103         SAFE_FREE(fsp->wbmpx_ptr);
104
105         return ret;
106 }    
107
108 /****************************************************************************
109  If any deferred opens are waiting on this close, notify them.
110 ****************************************************************************/
111
112 static void notify_deferred_opens(files_struct *fsp)
113 {
114         deferred_open_entry *de_array = NULL;
115         int num_de_entries, i;
116         pid_t mypid = sys_getpid();
117
118         if (!lp_defer_sharing_violations()) {
119                 return;
120         }
121
122         num_de_entries = get_deferred_opens(fsp->conn, fsp->dev, fsp->inode, &de_array);
123         for (i = 0; i < num_de_entries; i++) {
124                 deferred_open_entry *entry = &de_array[i];
125                 if (entry->pid == mypid) {
126                         /*
127                          * We need to notify ourself to retry the open.
128                          * Do this by finding the queued SMB record, moving it
129                          * to the head of the queue and changing the wait time to zero.
130                          */
131                         schedule_sharing_violation_open_smb_message(entry->mid);
132                 } else {
133                         send_deferred_open_retry_message(entry);
134                 }
135         }
136 }
137
138 /****************************************************************************
139  Close a file.
140
141  If normal_close is 1 then this came from a normal SMBclose (or equivalent)
142  operation otherwise it came as the result of some other operation such as
143  the closing of the connection. In the latter case printing and
144  magic scripts are not run.
145 ****************************************************************************/
146
147 static int close_normal_file(files_struct *fsp, BOOL normal_close)
148 {
149         share_mode_entry *share_entry = NULL;
150         size_t share_entry_count = 0;
151         BOOL delete_on_close = False;
152         connection_struct *conn = fsp->conn;
153         int err = 0;
154         int err1 = 0;
155
156         remove_pending_lock_requests_by_fid(fsp);
157
158         /*
159          * If we're flushing on a close we can get a write
160          * error here, we must remember this.
161          */
162
163         if (close_filestruct(fsp) == -1)
164                 err1 = -1;
165
166         if (fsp->print_file) {
167                 print_fsp_end(fsp, normal_close);
168                 file_free(fsp);
169                 return 0;
170         }
171
172         /*
173          * Lock the share entries, and determine if we should delete
174          * on close. If so delete whilst the lock is still in effect.
175          * This prevents race conditions with the file being created. JRA.
176          */
177
178         lock_share_entry_fsp(fsp);
179
180         if (fsp->delete_on_close) {
181
182                 /*
183                  * Modify the share mode entry for all files open
184                  * on this device and inode to tell other smbds we have
185                  * changed the delete on close flag. The last closer will delete the file
186                  * if flag is set.
187                  */
188
189                 NTSTATUS status =set_delete_on_close_over_all(fsp, fsp->delete_on_close);
190                 if (NT_STATUS_V(status) !=  NT_STATUS_V(NT_STATUS_OK))
191                         DEBUG(0,("close_normal_file: failed to change delete on close flag for file %s\n",
192                                 fsp->fsp_name ));
193         }
194
195         share_entry_count = del_share_mode(fsp, &share_entry);
196
197         DEBUG(10,("close_normal_file: share_entry_count = %lu for file %s\n",
198                 (unsigned long)share_entry_count, fsp->fsp_name ));
199
200         /*
201          * We delete on close if it's the last open, and the
202          * delete on close flag was set in the entry we just deleted.
203          */
204
205         if ((share_entry_count == 0) && share_entry && 
206                         GET_DELETE_ON_CLOSE_FLAG(share_entry->share_mode) )
207                 delete_on_close = True;
208
209         SAFE_FREE(share_entry);
210
211         /* Notify any deferred opens waiting on this close. */
212         notify_deferred_opens(fsp);
213
214         /*
215          * NT can set delete_on_close of the last open
216          * reference to a file.
217          */
218
219         if (normal_close && delete_on_close) {
220                 DEBUG(5,("close_file: file %s. Delete on close was set - deleting file.\n",
221                         fsp->fsp_name));
222                 if(SMB_VFS_UNLINK(conn,fsp->fsp_name) != 0) {
223                         /*
224                          * This call can potentially fail as another smbd may have
225                          * had the file open with delete on close set and deleted
226                          * it when its last reference to this file went away. Hence
227                          * we log this but not at debug level zero.
228                          */
229
230                 DEBUG(5,("close_file: file %s. Delete on close was set and unlink failed \
231 with error %s\n", fsp->fsp_name, strerror(errno) ));
232                 }
233                 process_pending_change_notify_queue((time_t)0);
234         }
235
236         unlock_share_entry_fsp(fsp);
237
238         if(fsp->oplock_type)
239                 release_file_oplock(fsp);
240
241         locking_close_file(fsp);
242
243         err = fd_close(conn, fsp);
244
245         /* check for magic scripts */
246         if (normal_close) {
247                 check_magic(fsp,conn);
248         }
249
250         /*
251          * Ensure pending modtime is set after close.
252          */
253
254         if(fsp->pending_modtime) {
255                 int saved_errno = errno;
256                 set_filetime(conn, fsp->fsp_name, fsp->pending_modtime);
257                 errno = saved_errno;
258         }
259
260         DEBUG(2,("%s closed file %s (numopen=%d) %s\n",
261                  conn->user,fsp->fsp_name,
262                  conn->num_files_open, err ? strerror(err) : ""));
263
264         if (fsp->fsp_name)
265                 string_free(&fsp->fsp_name);
266
267         file_free(fsp);
268
269         if (err == -1 || err1 == -1)
270                 return errno;
271         else
272                 return 0;
273 }
274
275 /****************************************************************************
276  Close a directory opened by an NT SMB call. 
277 ****************************************************************************/
278   
279 static int close_directory(files_struct *fsp, BOOL normal_close)
280 {
281         remove_pending_change_notify_requests_by_fid(fsp);
282
283         /*
284          * NT can set delete_on_close of the last open
285          * reference to a directory also.
286          */
287
288         if (normal_close && fsp->directory_delete_on_close) {
289                 BOOL ok = rmdir_internals(fsp->conn, fsp->fsp_name);
290                 DEBUG(5,("close_directory: %s. Delete on close was set - deleting directory %s.\n",
291                         fsp->fsp_name, ok ? "succeeded" : "failed" ));
292
293                 /*
294                  * Ensure we remove any change notify requests that would
295                  * now fail as the directory has been deleted.
296                  */
297
298                 if(ok)
299                         remove_pending_change_notify_requests_by_filename(fsp);
300                 process_pending_change_notify_queue((time_t)0);
301         }
302
303         /*
304          * Do the code common to files and directories.
305          */
306         close_filestruct(fsp);
307         
308         if (fsp->fsp_name)
309                 string_free(&fsp->fsp_name);
310         
311         file_free(fsp);
312         return 0;
313 }
314
315 /****************************************************************************
316  Close a 'stat file' opened internally.
317 ****************************************************************************/
318   
319 static int close_stat(files_struct *fsp)
320 {
321         /*
322          * Do the code common to files and directories.
323          */
324         close_filestruct(fsp);
325         
326         if (fsp->fsp_name)
327                 string_free(&fsp->fsp_name);
328         
329         file_free(fsp);
330         return 0;
331 }
332
333 /****************************************************************************
334  Close a files_struct.
335 ****************************************************************************/
336   
337 int close_file(files_struct *fsp, BOOL normal_close)
338 {
339         if(fsp->is_directory)
340                 return close_directory(fsp, normal_close);
341         else if (fsp->is_stat)
342                 return close_stat(fsp);
343         else
344                 return close_normal_file(fsp, normal_close);
345 }