r2331: check password script code and example from trunk
[Samba.git] / source / smbd / close.c
blob6de277464425a564ebd9df2600c7af668cb05f23
1 /*
2 Unix SMB/CIFS implementation.
3 file closing
4 Copyright (C) Andrew Tridgell 1992-1998
5 Copyright (C) Jeremy Allison 1992-2004.
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.
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.
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.
22 #include "includes.h"
24 /****************************************************************************
25 Run a file if it is a magic script.
26 ****************************************************************************/
28 static void check_magic(files_struct *fsp,connection_struct *conn)
30 if (!*lp_magicscript(SNUM(conn)))
31 return;
33 DEBUG(5,("checking magic for %s\n",fsp->fsp_name));
36 char *p;
37 if (!(p = strrchr_m(fsp->fsp_name,'/')))
38 p = fsp->fsp_name;
39 else
40 p++;
42 if (!strequal(lp_magicscript(SNUM(conn)),p))
43 return;
47 int ret;
48 pstring magic_output;
49 pstring fname;
50 SMB_STRUCT_STAT st;
51 int tmp_fd, outfd;
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);
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;
68 outfd = open(magic_output, O_CREAT|O_EXCL|O_RDWR, 0600);
69 if (outfd == -1) {
70 close(tmp_fd);
71 return;
74 if (sys_fstat(tmp_fd,&st) == -1) {
75 close(tmp_fd);
76 close(outfd);
77 return;
80 transfer_file(tmp_fd,outfd,(SMB_OFF_T)st.st_size);
81 close(tmp_fd);
82 close(outfd);
86 /****************************************************************************
87 Common code to close a file or a directory.
88 ****************************************************************************/
90 static int close_filestruct(files_struct *fsp)
92 connection_struct *conn = fsp->conn;
93 int ret = 0;
95 if (fsp->fd != -1) {
96 if(flush_write_cache(fsp, CLOSE_FLUSH) == -1)
97 ret = -1;
99 delete_write_cache(fsp);
102 conn->num_files_open--;
103 SAFE_FREE(fsp->wbmpx_ptr);
105 return ret;
108 /****************************************************************************
109 If any deferred opens are waiting on this close, notify them.
110 ****************************************************************************/
112 static void notify_deferred_opens(files_struct *fsp)
114 deferred_open_entry *de_array = NULL;
115 int num_de_entries, i;
116 pid_t mypid = sys_getpid();
118 if (!lp_defer_sharing_violations()) {
119 return;
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) {
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.
131 schedule_sharing_violation_open_smb_message(entry->mid);
132 } else {
133 send_deferred_open_retry_message(entry);
138 /****************************************************************************
139 Close a file.
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 ****************************************************************************/
147 static int close_normal_file(files_struct *fsp, BOOL normal_close)
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;
156 remove_pending_lock_requests_by_fid(fsp);
159 * If we're flushing on a close we can get a write
160 * error here, we must remember this.
163 if (close_filestruct(fsp) == -1)
164 err1 = -1;
166 if (fsp->print_file) {
167 print_fsp_end(fsp, normal_close);
168 file_free(fsp);
169 return 0;
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.
178 lock_share_entry_fsp(fsp);
180 if (fsp->delete_on_close) {
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.
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 ));
195 share_entry_count = del_share_mode(fsp, &share_entry);
197 DEBUG(10,("close_normal_file: share_entry_count = %lu for file %s\n",
198 (unsigned long)share_entry_count, fsp->fsp_name ));
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.
205 if ((share_entry_count == 0) && share_entry &&
206 GET_DELETE_ON_CLOSE_FLAG(share_entry->share_mode) )
207 delete_on_close = True;
209 SAFE_FREE(share_entry);
211 /* Notify any deferred opens waiting on this close. */
212 notify_deferred_opens(fsp);
215 * NT can set delete_on_close of the last open
216 * reference to a file.
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) {
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.
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) ));
233 process_pending_change_notify_queue((time_t)0);
236 unlock_share_entry_fsp(fsp);
238 if(fsp->oplock_type)
239 release_file_oplock(fsp);
241 locking_close_file(fsp);
243 err = fd_close(conn, fsp);
245 /* check for magic scripts */
246 if (normal_close) {
247 check_magic(fsp,conn);
251 * Ensure pending modtime is set after close.
254 if(fsp->pending_modtime) {
255 int saved_errno = errno;
256 set_filetime(conn, fsp->fsp_name, fsp->pending_modtime);
257 errno = saved_errno;
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) : ""));
264 if (fsp->fsp_name)
265 string_free(&fsp->fsp_name);
267 file_free(fsp);
269 if (err == -1 || err1 == -1)
270 return errno;
271 else
272 return 0;
275 /****************************************************************************
276 Close a directory opened by an NT SMB call.
277 ****************************************************************************/
279 static int close_directory(files_struct *fsp, BOOL normal_close)
281 remove_pending_change_notify_requests_by_fid(fsp);
284 * NT can set delete_on_close of the last open
285 * reference to a directory also.
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" ));
294 * Ensure we remove any change notify requests that would
295 * now fail as the directory has been deleted.
298 if(ok)
299 remove_pending_change_notify_requests_by_filename(fsp);
300 process_pending_change_notify_queue((time_t)0);
304 * Do the code common to files and directories.
306 close_filestruct(fsp);
308 if (fsp->fsp_name)
309 string_free(&fsp->fsp_name);
311 file_free(fsp);
312 return 0;
315 /****************************************************************************
316 Close a 'stat file' opened internally.
317 ****************************************************************************/
319 static int close_stat(files_struct *fsp)
322 * Do the code common to files and directories.
324 close_filestruct(fsp);
326 if (fsp->fsp_name)
327 string_free(&fsp->fsp_name);
329 file_free(fsp);
330 return 0;
333 /****************************************************************************
334 Close a files_struct.
335 ****************************************************************************/
337 int close_file(files_struct *fsp, BOOL normal_close)
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);