Correct PPTP server firewall rules chain.
[tomato/davidwu.git] / release / src / router / samba / source / smbd / close.c
blob33a7405e08f1a0ec5590db6977797c6e84929d3d
1 /*
2 Unix SMB/Netbios implementation.
3 Version 1.9.
4 file closing
5 Copyright (C) Andrew Tridgell 1992-1998
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 extern int DEBUGLEVEL;
26 /****************************************************************************
27 run a file if it is a magic script
28 ****************************************************************************/
29 static void check_magic(files_struct *fsp,connection_struct *conn)
31 if (!*lp_magicscript(SNUM(conn)))
32 return;
34 DEBUG(5,("checking magic for %s\n",fsp->fsp_name));
37 char *p;
38 if (!(p = strrchr(fsp->fsp_name,'/')))
39 p = fsp->fsp_name;
40 else
41 p++;
43 if (!strequal(lp_magicscript(SNUM(conn)),p))
44 return;
48 int ret;
49 pstring magic_output;
50 pstring fname;
51 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);
58 chmod(fname,0755);
59 ret = smbrun(fname,magic_output,False);
60 DEBUG(3,("Invoking magic command %s gave %d\n",fname,ret));
61 unlink(fname);
65 /****************************************************************************
66 Common code to close a file or a directory.
67 ****************************************************************************/
69 void close_filestruct(files_struct *fsp)
71 connection_struct *conn = fsp->conn;
73 flush_write_cache(fsp, CLOSE_FLUSH);
75 fsp->open = False;
76 fsp->is_directory = False;
78 conn->num_files_open--;
79 if(fsp->wbmpx_ptr) {
80 free((char *)fsp->wbmpx_ptr);
81 fsp->wbmpx_ptr = NULL;
85 /****************************************************************************
86 Close a file - possibly invalidating the read prediction.
88 If normal_close is 1 then this came from a normal SMBclose (or equivalent)
89 operation otherwise it came as the result of some other operation such as
90 the closing of the connection. In the latter case printing and
91 magic scripts are not run.
92 ****************************************************************************/
94 static int close_normal_file(files_struct *fsp, BOOL normal_close)
96 SMB_DEV_T dev = fsp->fd_ptr->dev;
97 SMB_INO_T inode = fsp->fd_ptr->inode;
98 int token;
99 BOOL last_reference = False;
100 BOOL delete_on_close = fsp->fd_ptr->delete_on_close;
101 connection_struct *conn = fsp->conn;
102 int err = 0;
104 remove_pending_lock_requests_by_fid(fsp);
106 close_filestruct(fsp);
108 #if USE_READ_PREDICTION
109 invalidate_read_prediction(fsp->fd_ptr->fd);
110 #endif
112 if (lp_share_modes(SNUM(conn))) {
113 lock_share_entry(conn, dev, inode, &token);
114 del_share_mode(token, fsp);
115 unlock_share_entry(conn, dev, inode, token);
118 if(EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type))
119 release_file_oplock(fsp);
121 if(fd_attempt_close(fsp->fd_ptr,&err) == 0)
122 last_reference = True;
124 fsp->fd_ptr = NULL;
125 #ifdef PRINTING
126 /* NT uses smbclose to start a print - weird */
127 if (normal_close && fsp->print_file)
128 print_file(conn, fsp);
129 #endif
130 /* check for magic scripts */
131 if (normal_close) {
132 check_magic(fsp,conn);
136 * NT can set delete_on_close of the last open
137 * reference to a file.
140 if (normal_close && last_reference && delete_on_close) {
141 DEBUG(5,("close_file: file %s. Delete on close was set - deleting file.\n",
142 fsp->fsp_name));
143 if(dos_unlink(fsp->fsp_name) != 0) {
146 * This call can potentially fail as another smbd may have
147 * had the file open with delete on close set and deleted
148 * it when its last reference to this file went away. Hence
149 * we log this but not at debug level zero.
152 DEBUG(5,("close_file: file %s. Delete on close was set and unlink failed \
153 with error %s\n", fsp->fsp_name, strerror(errno) ));
157 DEBUG(2,("%s closed file %s (numopen=%d) %s\n",
158 conn->user,fsp->fsp_name,
159 conn->num_files_open, err ? strerror(err) : ""));
161 if (fsp->fsp_name) {
162 string_free(&fsp->fsp_name);
165 file_free(fsp);
167 return err;
170 /****************************************************************************
171 Close a directory opened by an NT SMB call.
172 ****************************************************************************/
174 static int close_directory(files_struct *fsp, BOOL normal_close)
176 remove_pending_change_notify_requests_by_fid(fsp);
179 * NT can set delete_on_close of the last open
180 * reference to a directory also.
183 if (normal_close && fsp->directory_delete_on_close) {
184 BOOL ok = rmdir_internals(fsp->conn, fsp->fsp_name);
185 DEBUG(5,("close_directory: %s. Delete on close was set - deleting directory %s.\n",
186 fsp->fsp_name, ok ? "succeeded" : "failed" ));
189 * Ensure we remove any change notify requests that would
190 * now fail as the directory has been deleted.
193 if(ok)
194 remove_pending_change_notify_requests_by_filename(fsp);
198 * Do the code common to files and directories.
200 close_filestruct(fsp);
202 if (fsp->fsp_name)
203 string_free(&fsp->fsp_name);
205 file_free(fsp);
207 return 0;
210 /****************************************************************************
211 Close a file opened with null permissions in order to read permissions.
212 ****************************************************************************/
214 static int close_statfile(files_struct *fsp, BOOL normal_close)
216 close_filestruct(fsp);
218 if (fsp->fsp_name)
219 string_free(&fsp->fsp_name);
221 file_free(fsp);
223 return 0;
226 /****************************************************************************
227 Close a directory opened by an NT SMB call.
228 ****************************************************************************/
230 int close_file(files_struct *fsp, BOOL normal_close)
232 if(fsp->is_directory)
233 return close_directory(fsp, normal_close);
234 else if(fsp->stat_open)
235 return close_statfile(fsp, normal_close);
236 return close_normal_file(fsp, normal_close);