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