Line data Source code
1 : /*
2 : * Auditing VFS module for samba. Log selected file operations to syslog
3 : * facility.
4 : *
5 : * Copyright (C) Tim Potter 1999-2000
6 : * Copyright (C) Alexander Bokovoy 2002
7 : * Copyright (C) Stefan (metze) Metzmacher 2002
8 : *
9 : * This program is free software; you can redistribute it and/or modify
10 : * it under the terms of the GNU General Public License as published by
11 : * the Free Software Foundation; either version 3 of the License, or
12 : * (at your option) any later version.
13 : *
14 : * This program is distributed in the hope that it will be useful,
15 : * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 : * GNU General Public License for more details.
18 : *
19 : * You should have received a copy of the GNU General Public License
20 : * along with this program; if not, see <http://www.gnu.org/licenses/>.
21 : */
22 :
23 :
24 : #include "includes.h"
25 : #include "system/filesys.h"
26 : #include "system/syslog.h"
27 : #include "smbd/smbd.h"
28 : #include "lib/param/loadparm.h"
29 :
30 : #undef DBGC_CLASS
31 : #define DBGC_CLASS DBGC_VFS
32 :
33 0 : static int audit_syslog_facility(vfs_handle_struct *handle)
34 : {
35 : static const struct enum_list enum_log_facilities[] = {
36 : #ifdef LOG_AUTH
37 : { LOG_AUTH, "AUTH" },
38 : #endif
39 : #ifdef LOG_AUTHPRIV
40 : { LOG_AUTHPRIV, "AUTHPRIV" },
41 : #endif
42 : #ifdef LOG_AUDIT
43 : { LOG_AUDIT, "AUDIT" },
44 : #endif
45 : #ifdef LOG_CONSOLE
46 : { LOG_CONSOLE, "CONSOLE" },
47 : #endif
48 : #ifdef LOG_CRON
49 : { LOG_CRON, "CRON" },
50 : #endif
51 : #ifdef LOG_DAEMON
52 : { LOG_DAEMON, "DAEMON" },
53 : #endif
54 : #ifdef LOG_FTP
55 : { LOG_FTP, "FTP" },
56 : #endif
57 : #ifdef LOG_INSTALL
58 : { LOG_INSTALL, "INSTALL" },
59 : #endif
60 : #ifdef LOG_KERN
61 : { LOG_KERN, "KERN" },
62 : #endif
63 : #ifdef LOG_LAUNCHD
64 : { LOG_LAUNCHD, "LAUNCHD" },
65 : #endif
66 : #ifdef LOG_LFMT
67 : { LOG_LFMT, "LFMT" },
68 : #endif
69 : #ifdef LOG_LPR
70 : { LOG_LPR, "LPR" },
71 : #endif
72 : #ifdef LOG_MAIL
73 : { LOG_MAIL, "MAIL" },
74 : #endif
75 : #ifdef LOG_MEGASAFE
76 : { LOG_MEGASAFE, "MEGASAFE" },
77 : #endif
78 : #ifdef LOG_NETINFO
79 : { LOG_NETINFO, "NETINFO" },
80 : #endif
81 : #ifdef LOG_NEWS
82 : { LOG_NEWS, "NEWS" },
83 : #endif
84 : #ifdef LOG_NFACILITIES
85 : { LOG_NFACILITIES, "NFACILITIES" },
86 : #endif
87 : #ifdef LOG_NTP
88 : { LOG_NTP, "NTP" },
89 : #endif
90 : #ifdef LOG_RAS
91 : { LOG_RAS, "RAS" },
92 : #endif
93 : #ifdef LOG_REMOTEAUTH
94 : { LOG_REMOTEAUTH, "REMOTEAUTH" },
95 : #endif
96 : #ifdef LOG_SECURITY
97 : { LOG_SECURITY, "SECURITY" },
98 : #endif
99 : #ifdef LOG_SYSLOG
100 : { LOG_SYSLOG, "SYSLOG" },
101 : #endif
102 : #ifdef LOG_USER
103 : { LOG_USER, "USER" },
104 : #endif
105 : #ifdef LOG_UUCP
106 : { LOG_UUCP, "UUCP" },
107 : #endif
108 : { LOG_LOCAL0, "LOCAL0" },
109 : { LOG_LOCAL1, "LOCAL1" },
110 : { LOG_LOCAL2, "LOCAL2" },
111 : { LOG_LOCAL3, "LOCAL3" },
112 : { LOG_LOCAL4, "LOCAL4" },
113 : { LOG_LOCAL5, "LOCAL5" },
114 : { LOG_LOCAL6, "LOCAL6" },
115 : { LOG_LOCAL7, "LOCAL7" },
116 : { -1, NULL }
117 : };
118 :
119 : int facility;
120 :
121 0 : facility = lp_parm_enum(SNUM(handle->conn), "audit", "facility", enum_log_facilities, LOG_USER);
122 :
123 0 : return facility;
124 : }
125 :
126 :
127 0 : static int audit_syslog_priority(vfs_handle_struct *handle)
128 : {
129 : static const struct enum_list enum_log_priorities[] = {
130 : { LOG_EMERG, "EMERG" },
131 : { LOG_ALERT, "ALERT" },
132 : { LOG_CRIT, "CRIT" },
133 : { LOG_ERR, "ERR" },
134 : { LOG_WARNING, "WARNING" },
135 : { LOG_NOTICE, "NOTICE" },
136 : { LOG_INFO, "INFO" },
137 : { LOG_DEBUG, "DEBUG" },
138 : { -1, NULL }
139 : };
140 :
141 : int priority;
142 :
143 0 : priority = lp_parm_enum(SNUM(handle->conn), "audit", "priority",
144 : enum_log_priorities, LOG_NOTICE);
145 0 : if (priority == -1) {
146 0 : priority = LOG_WARNING;
147 : }
148 :
149 0 : return priority;
150 : }
151 :
152 : /* Implementation of vfs_ops. Pass everything on to the default
153 : operation but log event first. */
154 :
155 0 : static int audit_connect(vfs_handle_struct *handle, const char *svc, const char *user)
156 : {
157 : int result;
158 :
159 0 : result = SMB_VFS_NEXT_CONNECT(handle, svc, user);
160 0 : if (result < 0) {
161 0 : return result;
162 : }
163 :
164 0 : openlog("smbd_audit", LOG_PID, audit_syslog_facility(handle));
165 :
166 0 : syslog(audit_syslog_priority(handle), "connect to service %s by user %s\n",
167 : svc, user);
168 :
169 0 : return 0;
170 : }
171 :
172 0 : static void audit_disconnect(vfs_handle_struct *handle)
173 : {
174 0 : syslog(audit_syslog_priority(handle), "disconnected\n");
175 0 : SMB_VFS_NEXT_DISCONNECT(handle);
176 :
177 0 : return;
178 : }
179 :
180 0 : static int audit_mkdirat(vfs_handle_struct *handle,
181 : struct files_struct *dirfsp,
182 : const struct smb_filename *smb_fname,
183 : mode_t mode)
184 : {
185 0 : struct smb_filename *full_fname = NULL;
186 : int result;
187 :
188 0 : full_fname = full_path_from_dirfsp_atname(talloc_tos(),
189 : dirfsp,
190 : smb_fname);
191 0 : if (full_fname == NULL) {
192 0 : errno = ENOMEM;
193 0 : return -1;
194 : }
195 :
196 0 : result = SMB_VFS_NEXT_MKDIRAT(handle,
197 : dirfsp,
198 : smb_fname,
199 : mode);
200 :
201 0 : syslog(audit_syslog_priority(handle), "mkdirat %s %s%s\n",
202 : full_fname->base_name,
203 : (result < 0) ? "failed: " : "",
204 0 : (result < 0) ? strerror(errno) : "");
205 :
206 0 : TALLOC_FREE(full_fname);
207 0 : return result;
208 : }
209 :
210 0 : static int audit_openat(vfs_handle_struct *handle,
211 : const struct files_struct *dirfsp,
212 : const struct smb_filename *smb_fname,
213 : struct files_struct *fsp,
214 : const struct vfs_open_how *how)
215 : {
216 : int result;
217 :
218 0 : result = SMB_VFS_NEXT_OPENAT(handle, dirfsp, smb_fname, fsp, how);
219 :
220 0 : syslog(audit_syslog_priority(handle),
221 : "openat %s (fd %d) %s%s%s\n",
222 : fsp_str_dbg(fsp), result,
223 0 : ((how->flags & O_WRONLY) || (how->flags & O_RDWR)) ?
224 : "for writing " : "",
225 : (result < 0) ? "failed: " : "",
226 0 : (result < 0) ? strerror(errno) : "");
227 :
228 0 : return result;
229 : }
230 :
231 0 : static int audit_close(vfs_handle_struct *handle, files_struct *fsp)
232 : {
233 : int result;
234 :
235 0 : result = SMB_VFS_NEXT_CLOSE(handle, fsp);
236 :
237 0 : syslog(audit_syslog_priority(handle), "close fd %d %s%s\n",
238 : fsp_get_pathref_fd(fsp),
239 : (result < 0) ? "failed: " : "",
240 0 : (result < 0) ? strerror(errno) : "");
241 :
242 0 : return result;
243 : }
244 :
245 0 : static int audit_renameat(vfs_handle_struct *handle,
246 : files_struct *srcfsp,
247 : const struct smb_filename *smb_fname_src,
248 : files_struct *dstfsp,
249 : const struct smb_filename *smb_fname_dst)
250 : {
251 0 : struct smb_filename *full_fname_src = NULL;
252 0 : struct smb_filename *full_fname_dst = NULL;
253 : int result;
254 0 : int saved_errno = 0;
255 :
256 0 : full_fname_src = full_path_from_dirfsp_atname(talloc_tos(),
257 : srcfsp,
258 : smb_fname_src);
259 0 : if (full_fname_src == NULL) {
260 0 : errno = ENOMEM;
261 0 : return -1;
262 : }
263 0 : full_fname_dst = full_path_from_dirfsp_atname(talloc_tos(),
264 : dstfsp,
265 : smb_fname_dst);
266 0 : if (full_fname_dst == NULL) {
267 0 : TALLOC_FREE(full_fname_src);
268 0 : errno = ENOMEM;
269 0 : return -1;
270 : }
271 0 : result = SMB_VFS_NEXT_RENAMEAT(handle,
272 : srcfsp,
273 : smb_fname_src,
274 : dstfsp,
275 : smb_fname_dst);
276 0 : if (result == -1) {
277 0 : saved_errno = errno;
278 : }
279 :
280 0 : syslog(audit_syslog_priority(handle), "renameat %s -> %s %s%s\n",
281 : full_fname_src->base_name,
282 : full_fname_dst->base_name,
283 : (result < 0) ? "failed: " : "",
284 0 : (result < 0) ? strerror(errno) : "");
285 :
286 0 : TALLOC_FREE(full_fname_src);
287 0 : TALLOC_FREE(full_fname_dst);
288 :
289 0 : if (saved_errno != 0) {
290 0 : errno = saved_errno;
291 : }
292 :
293 0 : return result;
294 : }
295 :
296 0 : static int audit_unlinkat(vfs_handle_struct *handle,
297 : struct files_struct *dirfsp,
298 : const struct smb_filename *smb_fname,
299 : int flags)
300 : {
301 0 : struct smb_filename *full_fname = NULL;
302 : int result;
303 :
304 0 : full_fname = full_path_from_dirfsp_atname(talloc_tos(),
305 : dirfsp,
306 : smb_fname);
307 0 : if (full_fname == NULL) {
308 0 : return -1;
309 : }
310 :
311 0 : result = SMB_VFS_NEXT_UNLINKAT(handle,
312 : dirfsp,
313 : smb_fname,
314 : flags);
315 :
316 0 : syslog(audit_syslog_priority(handle), "unlinkat %s %s%s\n",
317 : full_fname->base_name,
318 : (result < 0) ? "failed: " : "",
319 0 : (result < 0) ? strerror(errno) : "");
320 :
321 0 : TALLOC_FREE(full_fname);
322 0 : return result;
323 : }
324 :
325 0 : static int audit_fchmod(vfs_handle_struct *handle, files_struct *fsp, mode_t mode)
326 : {
327 : int result;
328 :
329 0 : result = SMB_VFS_NEXT_FCHMOD(handle, fsp, mode);
330 :
331 0 : syslog(audit_syslog_priority(handle), "fchmod %s mode 0x%x %s%s\n",
332 0 : fsp->fsp_name->base_name, mode,
333 : (result < 0) ? "failed: " : "",
334 0 : (result < 0) ? strerror(errno) : "");
335 :
336 0 : return result;
337 : }
338 :
339 : static struct vfs_fn_pointers vfs_audit_fns = {
340 : .connect_fn = audit_connect,
341 : .disconnect_fn = audit_disconnect,
342 : .mkdirat_fn = audit_mkdirat,
343 : .openat_fn = audit_openat,
344 : .close_fn = audit_close,
345 : .renameat_fn = audit_renameat,
346 : .unlinkat_fn = audit_unlinkat,
347 : .fchmod_fn = audit_fchmod,
348 : };
349 :
350 : static_decl_vfs;
351 27 : NTSTATUS vfs_audit_init(TALLOC_CTX *ctx)
352 : {
353 27 : return smb_register_vfs(SMB_VFS_INTERFACE_VERSION, "audit",
354 : &vfs_audit_fns);
355 : }
|