Fix problem with "hide unreadable". stat file opens are baaack :-).
[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         share_entry_count = del_share_mode(fsp, &share_entry);
149
150         DEBUG(10,("close_normal_file: share_entry_count = %d for file %s\n",
151                 share_entry_count, fsp->fsp_name ));
152
153         /*
154          * We delete on close if it's the last open, and the
155          * delete on close flag was set in the entry we just deleted.
156          */
157
158         if ((share_entry_count == 0) && share_entry && 
159                         GET_DELETE_ON_CLOSE_FLAG(share_entry->share_mode) )
160                 delete_on_close = True;
161
162         SAFE_FREE(share_entry);
163
164         /*
165          * NT can set delete_on_close of the last open
166          * reference to a file.
167          */
168
169         if (normal_close && delete_on_close) {
170                 DEBUG(5,("close_file: file %s. Delete on close was set - deleting file.\n",
171                         fsp->fsp_name));
172                 if(fsp->conn->vfs_ops.unlink(conn,fsp->fsp_name) != 0) {
173                         /*
174                          * This call can potentially fail as another smbd may have
175                          * had the file open with delete on close set and deleted
176                          * it when its last reference to this file went away. Hence
177                          * we log this but not at debug level zero.
178                          */
179
180                 DEBUG(5,("close_file: file %s. Delete on close was set and unlink failed \
181 with error %s\n", fsp->fsp_name, strerror(errno) ));
182                 }
183         }
184
185         unlock_share_entry_fsp(fsp);
186
187         if(EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type))
188                 release_file_oplock(fsp);
189
190         locking_close_file(fsp);
191
192         err = fd_close(conn, fsp);
193
194         /* check for magic scripts */
195         if (normal_close) {
196                 check_magic(fsp,conn);
197         }
198
199         /*
200          * Ensure pending modtime is set after close.
201          */
202
203         if(fsp->pending_modtime) {
204                 int saved_errno = errno;
205                 set_filetime(conn, fsp->fsp_name, fsp->pending_modtime);
206                 errno = saved_errno;
207         }
208
209         DEBUG(2,("%s closed file %s (numopen=%d) %s\n",
210                  conn->user,fsp->fsp_name,
211                  conn->num_files_open, err ? strerror(err) : ""));
212
213         if (fsp->fsp_name)
214                 string_free(&fsp->fsp_name);
215
216         file_free(fsp);
217
218         if (err == -1 || err1 == -1)
219                 return -1;
220         else
221                 return 0;
222 }
223
224 /****************************************************************************
225  Close a directory opened by an NT SMB call. 
226 ****************************************************************************/
227   
228 static int close_directory(files_struct *fsp, BOOL normal_close)
229 {
230         remove_pending_change_notify_requests_by_fid(fsp);
231
232         /*
233          * NT can set delete_on_close of the last open
234          * reference to a directory also.
235          */
236
237         if (normal_close && fsp->directory_delete_on_close) {
238                 BOOL ok = rmdir_internals(fsp->conn, fsp->fsp_name);
239                 DEBUG(5,("close_directory: %s. Delete on close was set - deleting directory %s.\n",
240                         fsp->fsp_name, ok ? "succeeded" : "failed" ));
241
242                 /*
243                  * Ensure we remove any change notify requests that would
244                  * now fail as the directory has been deleted.
245                  */
246
247                 if(ok)
248                         remove_pending_change_notify_requests_by_filename(fsp);
249         }
250
251         /*
252          * Do the code common to files and directories.
253          */
254         close_filestruct(fsp);
255         
256         if (fsp->fsp_name)
257                 string_free(&fsp->fsp_name);
258         
259         file_free(fsp);
260         return 0;
261 }
262
263 /****************************************************************************
264  Close a 'stat file' opened internally.
265 ****************************************************************************/
266   
267 static int close_stat(files_struct *fsp)
268 {
269         /*
270          * Do the code common to files and directories.
271          */
272         close_filestruct(fsp);
273         
274         if (fsp->fsp_name)
275                 string_free(&fsp->fsp_name);
276         
277         file_free(fsp);
278         return 0;
279 }
280
281 /****************************************************************************
282  Close a files_struct.
283 ****************************************************************************/
284   
285 int close_file(files_struct *fsp, BOOL normal_close)
286 {
287         if(fsp->is_directory)
288                 return close_directory(fsp, normal_close);
289         else if (fsp->is_stat)
290                 return close_stat(fsp);
291         else
292                 return close_normal_file(fsp, normal_close);
293 }