Fixed the (incorrect) paranioa fix I put in for the fcntl lock spin.
[samba.git] / source / smbd / close.c
1 /* 
2    Unix SMB/Netbios implementation.
3    Version 1.9.
4    file closing
5    Copyright (C) Andrew Tridgell 1992-1998
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 extern int DEBUGLEVEL;
25
26 /****************************************************************************
27 run a file if it is a magic script
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,st.st_size, NULL,0,0);
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(flush_write_cache(fsp, CLOSE_FLUSH) == -1)
97                 ret = -1;
98
99         delete_write_cache(fsp);
100
101         fsp->is_directory = False; 
102         fsp->stat_open = False; 
103     
104         conn->num_files_open--;
105         if(fsp->wbmpx_ptr) {  
106                 free((char *)fsp->wbmpx_ptr);
107                 fsp->wbmpx_ptr = NULL; 
108         }  
109
110         return ret;
111 }    
112
113 /****************************************************************************
114  Close a file.
115
116  If normal_close is 1 then this came from a normal SMBclose (or equivalent)
117  operation otherwise it came as the result of some other operation such as
118  the closing of the connection. In the latter case printing and
119  magic scripts are not run.
120 ****************************************************************************/
121
122 static int close_normal_file(files_struct *fsp, BOOL normal_close)
123 {
124         share_mode_entry *share_entry = NULL;
125         size_t share_entry_count = 0;
126         BOOL delete_on_close = False;
127         connection_struct *conn = fsp->conn;
128         int err = 0;
129         int err1 = 0;
130
131         remove_pending_lock_requests_by_fid(fsp);
132
133         /*
134          * If we're flushing on a close we can get a write
135          * error here, we must remember this.
136          */
137
138         if (close_filestruct(fsp) == -1)
139                 err1 = -1;
140
141         if (fsp->print_file) {
142                 print_fsp_end(fsp, normal_close);
143                 file_free(fsp);
144                 return 0;
145         }
146
147         /*
148          * Lock the share entries, and determine if we should delete
149          * on close. If so delete whilst the lock is still in effect.
150          * This prevents race conditions with the file being created. JRA.
151          */
152
153         lock_share_entry_fsp(fsp);
154         share_entry_count = del_share_mode(fsp, &share_entry);
155
156         DEBUG(10,("close_normal_file: share_entry_count = %d for file %s\n",
157                 share_entry_count, fsp->fsp_name ));
158
159         /*
160          * We delete on close if it's the last open, and the
161          * delete on close flag was set in the entry we just deleted.
162          */
163
164         if ((share_entry_count == 0) && share_entry && 
165                         GET_DELETE_ON_CLOSE_FLAG(share_entry->share_mode) )
166                 delete_on_close = True;
167
168         safe_free(share_entry);
169
170         /*
171          * NT can set delete_on_close of the last open
172          * reference to a file.
173          */
174
175     if (normal_close && delete_on_close) {
176         DEBUG(5,("close_file: file %s. Delete on close was set - deleting file.\n",
177             fsp->fsp_name));
178                 if(fsp->conn->vfs_ops.unlink(conn,fsp->fsp_name) != 0) {
179           /*
180            * This call can potentially fail as another smbd may have
181            * had the file open with delete on close set and deleted
182            * it when its last reference to this file went away. Hence
183            * we log this but not at debug level zero.
184            */
185
186           DEBUG(5,("close_file: file %s. Delete on close was set and unlink failed \
187 with error %s\n", fsp->fsp_name, strerror(errno) ));
188         }
189     }
190
191         unlock_share_entry_fsp(fsp);
192
193         if(EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type))
194                 release_file_oplock(fsp);
195
196         locking_close_file(fsp);
197
198         err = fd_close(conn, fsp);
199
200         /* check for magic scripts */
201         if (normal_close) {
202                 check_magic(fsp,conn);
203         }
204
205
206         DEBUG(2,("%s closed file %s (numopen=%d) %s\n",
207                  conn->user,fsp->fsp_name,
208                  conn->num_files_open, err ? strerror(err) : ""));
209
210         if (fsp->fsp_name) {
211                 string_free(&fsp->fsp_name);
212         }
213
214         file_free(fsp);
215
216         if (err == -1 || err1 == -1)
217                 return -1;
218         else
219                 return 0;
220 }
221
222 /****************************************************************************
223  Close a directory opened by an NT SMB call. 
224 ****************************************************************************/
225   
226 static int close_directory(files_struct *fsp, BOOL normal_close)
227 {
228         remove_pending_change_notify_requests_by_fid(fsp);
229
230         /*
231          * NT can set delete_on_close of the last open
232          * reference to a directory also.
233          */
234
235         if (normal_close && fsp->directory_delete_on_close) {
236                 BOOL ok = rmdir_internals(fsp->conn, fsp->fsp_name);
237                 DEBUG(5,("close_directory: %s. Delete on close was set - deleting directory %s.\n",
238                         fsp->fsp_name, ok ? "succeeded" : "failed" ));
239
240                 /*
241                  * Ensure we remove any change notify requests that would
242                  * now fail as the directory has been deleted.
243                  */
244
245                 if(ok)
246                         remove_pending_change_notify_requests_by_filename(fsp);
247     }
248
249         /*
250          * Do the code common to files and directories.
251          */
252         close_filestruct(fsp);
253         
254         if (fsp->fsp_name)
255                 string_free(&fsp->fsp_name);
256         
257         file_free(fsp);
258
259         return 0;
260 }
261
262 /****************************************************************************
263  Close a file opened with null permissions in order to read permissions.
264 ****************************************************************************/
265
266 static int close_statfile(files_struct *fsp, BOOL normal_close)
267 {
268         close_filestruct(fsp);
269         
270         if (fsp->fsp_name)
271                 string_free(&fsp->fsp_name);
272         
273         file_free(fsp);
274
275         return 0;
276 }
277
278 /****************************************************************************
279  Close a directory opened by an NT SMB call. 
280 ****************************************************************************/
281   
282 int close_file(files_struct *fsp, BOOL normal_close)
283 {
284         if(fsp->is_directory)
285                 return close_directory(fsp, normal_close);
286         else if(fsp->stat_open)
287                 return close_statfile(fsp, normal_close);
288         return close_normal_file(fsp, normal_close);
289 }