2 * Auditing VFS module for samba. Log selected file operations to syslog
5 * Copyright (C) Tim Potter, 1999-2000
6 * Copyright (C) Alexander Bokovoy, 2002
7 * Copyright (C) John H Terpstra, 2003
8 * Copyright (C) Stefan (metze) Metzmacher, 2003
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
28 extern struct current_user current_user;
30 static int vfs_extd_audit_debug_level = DBGC_VFS;
33 #define DBGC_CLASS vfs_extd_audit_debug_level
35 /* Function prototypes */
37 static int audit_connect(vfs_handle_struct *handle, connection_struct *conn, const char *svc, const char *user);
38 static void audit_disconnect(vfs_handle_struct *handle, connection_struct *conn);
39 static DIR *audit_opendir(vfs_handle_struct *handle, connection_struct *conn, const char *fname);
40 static int audit_mkdir(vfs_handle_struct *handle, connection_struct *conn, const char *path, mode_t mode);
41 static int audit_rmdir(vfs_handle_struct *handle, connection_struct *conn, const char *path);
42 static int audit_open(vfs_handle_struct *handle, connection_struct *conn, const char *fname, int flags, mode_t mode);
43 static int audit_close(vfs_handle_struct *handle, files_struct *fsp, int fd);
44 static int audit_rename(vfs_handle_struct *handle, connection_struct *conn, const char *old, const char *new);
45 static int audit_unlink(vfs_handle_struct *handle, connection_struct *conn, const char *path);
46 static int audit_chmod(vfs_handle_struct *handle, connection_struct *conn, const char *path, mode_t mode);
47 static int audit_chmod_acl(vfs_handle_struct *handle, connection_struct *conn, const char *name, mode_t mode);
48 static int audit_fchmod(vfs_handle_struct *handle, files_struct *fsp, int fd, mode_t mode);
49 static int audit_fchmod_acl(vfs_handle_struct *handle, files_struct *fsp, int fd, mode_t mode);
53 static vfs_op_tuple audit_op_tuples[] = {
57 {SMB_VFS_OP(audit_connect), SMB_VFS_OP_CONNECT, SMB_VFS_LAYER_LOGGER},
58 {SMB_VFS_OP(audit_disconnect), SMB_VFS_OP_DISCONNECT, SMB_VFS_LAYER_LOGGER},
60 /* Directory operations */
62 {SMB_VFS_OP(audit_opendir), SMB_VFS_OP_OPENDIR, SMB_VFS_LAYER_LOGGER},
63 {SMB_VFS_OP(audit_mkdir), SMB_VFS_OP_MKDIR, SMB_VFS_LAYER_LOGGER},
64 {SMB_VFS_OP(audit_rmdir), SMB_VFS_OP_RMDIR, SMB_VFS_LAYER_LOGGER},
68 {SMB_VFS_OP(audit_open), SMB_VFS_OP_OPEN, SMB_VFS_LAYER_LOGGER},
69 {SMB_VFS_OP(audit_close), SMB_VFS_OP_CLOSE, SMB_VFS_LAYER_LOGGER},
70 {SMB_VFS_OP(audit_rename), SMB_VFS_OP_RENAME, SMB_VFS_LAYER_LOGGER},
71 {SMB_VFS_OP(audit_unlink), SMB_VFS_OP_UNLINK, SMB_VFS_LAYER_LOGGER},
72 {SMB_VFS_OP(audit_chmod), SMB_VFS_OP_CHMOD, SMB_VFS_LAYER_LOGGER},
73 {SMB_VFS_OP(audit_fchmod), SMB_VFS_OP_FCHMOD, SMB_VFS_LAYER_LOGGER},
74 {SMB_VFS_OP(audit_chmod_acl), SMB_VFS_OP_CHMOD_ACL, SMB_VFS_LAYER_LOGGER},
75 {SMB_VFS_OP(audit_fchmod_acl), SMB_VFS_OP_FCHMOD_ACL, SMB_VFS_LAYER_LOGGER},
77 /* Finish VFS operations definition */
79 {SMB_VFS_OP(NULL), SMB_VFS_OP_NOOP, SMB_VFS_LAYER_NOOP}
83 static int audit_syslog_facility(vfs_handle_struct *handle)
85 /* fix me: let this be configurable by:
86 * lp_param_enum(SNUM(handle->conn),(handle->param?handle->param:"extd_audit"),"syslog facility",
87 * audit_enum_facility,LOG_USER);
93 static int audit_syslog_priority(vfs_handle_struct *handle)
95 /* fix me: let this be configurable by:
96 * lp_param_enum(SNUM(handle->conn),(handle->param?handle->param:"extd_audit"),"syslog priority",
97 * audit_enum_priority,LOG_NOTICE);
102 /* Implementation of vfs_ops. Pass everything on to the default
103 operation but log event first. */
105 static int audit_connect(vfs_handle_struct *handle, connection_struct *conn, const char *svc, const char *user)
109 openlog("smbd_audit", LOG_PID, audit_syslog_facility(handle));
111 if (lp_parm_bool(SNUM(handle->conn), "extd_audit", "parseable",
113 syslog(audit_syslog_priority(handle),
114 "%d|%s|connect|%s\n", current_user.uid,
115 handle->conn->client_address, svc);
117 syslog(audit_syslog_priority(handle),
118 "connect to service %s by user %s\n", svc, user);
119 DEBUG(10, ("Connected to service %s as user %s\n",
123 result = SMB_VFS_NEXT_CONNECT(handle, conn, svc, user);
128 static void audit_disconnect(vfs_handle_struct *handle, connection_struct *conn)
130 if (lp_parm_bool(SNUM(handle->conn), "extd_audit", "parseable",
132 syslog(audit_syslog_priority(handle),
133 "%d|%s|disconnect|%s\n", current_user.uid,
134 handle->conn->client_address,
135 lp_servicename(SNUM(conn)));
137 syslog(audit_syslog_priority(handle), "disconnected\n");
138 DEBUG(10, ("Disconnected from VFS module extd_audit\n"));
141 SMB_VFS_NEXT_DISCONNECT(handle, conn);
146 static DIR *audit_opendir(vfs_handle_struct *handle, connection_struct *conn, const char *fname)
150 result = SMB_VFS_NEXT_OPENDIR(handle, conn, fname);
152 if (lp_parm_bool(SNUM(handle->conn), "extd_audit", "parseable",
154 syslog(audit_syslog_priority(handle),
155 "%d|%s|opendir|%s\n", current_user.uid,
156 handle->conn->client_address, fname);
158 syslog(audit_syslog_priority(handle), "opendir %s %s%s\n",
160 (result == NULL) ? "failed: " : "",
161 (result == NULL) ? strerror(errno) : "");
162 DEBUG(1, ("vfs_extd_audit: opendir %s %s %s\n",
164 (result == NULL) ? "failed: " : "",
165 (result == NULL) ? strerror(errno) : ""));
171 static int audit_mkdir(vfs_handle_struct *handle, connection_struct *conn, const char *path, mode_t mode)
175 result = SMB_VFS_NEXT_MKDIR(handle, conn, path, mode);
177 if (lp_parm_bool(SNUM(handle->conn), "extd_audit", "parseable",
179 syslog(audit_syslog_priority(handle),
180 "%d|%s|mkdir|%s\n", current_user.uid,
181 handle->conn->client_address, path);
183 syslog(audit_syslog_priority(handle), "mkdir %s %s%s\n",
185 (result < 0) ? "failed: " : "",
186 (result < 0) ? strerror(errno) : "");
187 DEBUG(0, ("vfs_extd_audit: mkdir %s %s %s\n",
189 (result < 0) ? "failed: " : "",
190 (result < 0) ? strerror(errno) : ""));
196 static int audit_rmdir(vfs_handle_struct *handle, connection_struct *conn, const char *path)
200 result = SMB_VFS_NEXT_RMDIR(handle, conn, path);
202 if (lp_parm_bool(SNUM(handle->conn), "extd_audit", "parseable",
204 syslog(audit_syslog_priority(handle),
205 "%d|%s|rmdir|%s\n", current_user.uid,
206 handle->conn->client_address, path);
208 syslog(audit_syslog_priority(handle), "rmdir %s %s%s\n",
210 (result < 0) ? "failed: " : "",
211 (result < 0) ? strerror(errno) : "");
212 DEBUG(0, ("vfs_extd_audit: rmdir %s %s %s\n",
214 (result < 0) ? "failed: " : "",
215 (result < 0) ? strerror(errno) : ""));
221 static int audit_open(vfs_handle_struct *handle, connection_struct *conn, const char *fname, int flags, mode_t mode)
225 result = SMB_VFS_NEXT_OPEN(handle, conn, fname, flags, mode);
227 if (lp_parm_bool(SNUM(handle->conn), "extd_audit", "parseable",
229 syslog(audit_syslog_priority(handle),
230 "%d|%s|open|%s|%s\n", current_user.uid,
231 handle->conn->client_address,
232 ((flags & O_WRONLY) || (flags & O_RDWR))?"w":"r",
235 syslog(audit_syslog_priority(handle),
236 "open %s (fd %d) %s%s%s\n",
238 ((flags & O_WRONLY) || (flags & O_RDWR))
239 ? "for writing " : "",
240 (result < 0) ? "failed: " : "",
241 (result < 0) ? strerror(errno) : "");
242 DEBUG(2, ("vfs_extd_audit: open %s %s %s\n",
244 (result < 0) ? "failed: " : "",
245 (result < 0) ? strerror(errno) : ""));
251 static int audit_close(vfs_handle_struct *handle, files_struct *fsp, int fd)
255 result = SMB_VFS_NEXT_CLOSE(handle, fsp, fd);
257 if (lp_parm_bool(SNUM(handle->conn), "extd_audit", "parseable",
259 syslog(audit_syslog_priority(handle),
260 "%d|%s|close|%s\n", current_user.uid,
261 handle->conn->client_address, fsp->fsp_name);
263 syslog(audit_syslog_priority(handle), "close fd %d %s%s\n",
265 (result < 0) ? "failed: " : "",
266 (result < 0) ? strerror(errno) : "");
267 DEBUG(2, ("vfs_extd_audit: close fd %d %s %s\n",
269 (result < 0) ? "failed: " : "",
270 (result < 0) ? strerror(errno) : ""));
276 static int audit_rename(vfs_handle_struct *handle, connection_struct *conn, const char *old, const char *new)
280 result = SMB_VFS_NEXT_RENAME(handle, conn, old, new);
282 if (lp_parm_bool(SNUM(handle->conn), "extd_audit", "parseable",
284 syslog(audit_syslog_priority(handle),
285 "%d|%s|rename|%s|%s\n", current_user.uid,
286 handle->conn->client_address, old, new);
288 syslog(audit_syslog_priority(handle), "rename %s -> %s %s%s\n",
290 (result < 0) ? "failed: " : "",
291 (result < 0) ? strerror(errno) : "");
292 DEBUG(1, ("vfs_extd_audit: rename old: %s new: %s %s %s\n",
294 (result < 0) ? "failed: " : "",
295 (result < 0) ? strerror(errno) : ""));
301 static int audit_unlink(vfs_handle_struct *handle, connection_struct *conn, const char *path)
305 result = SMB_VFS_NEXT_UNLINK(handle, conn, path);
307 if (lp_parm_bool(SNUM(handle->conn), "extd_audit", "parseable",
309 syslog(audit_syslog_priority(handle),
310 "%d|%s|unlink|%s\n", current_user.uid,
311 handle->conn->client_address, path);
313 syslog(audit_syslog_priority(handle), "unlink %s %s%s\n",
315 (result < 0) ? "failed: " : "",
316 (result < 0) ? strerror(errno) : "");
317 DEBUG(0, ("vfs_extd_audit: unlink %s %s %s\n",
319 (result < 0) ? "failed: " : "",
320 (result < 0) ? strerror(errno) : ""));
326 static int audit_chmod(vfs_handle_struct *handle, connection_struct *conn, const char *path, mode_t mode)
330 result = SMB_VFS_NEXT_CHMOD(handle, conn, path, mode);
332 if (lp_parm_bool(SNUM(handle->conn), "extd_audit", "parseable",
334 syslog(audit_syslog_priority(handle),
335 "%d|%s|chmod|%s|%o\n", current_user.uid,
336 handle->conn->client_address, path, mode);
338 syslog(audit_syslog_priority(handle),
339 "chmod %s mode 0x%x %s%s\n",
341 (result < 0) ? "failed: " : "",
342 (result < 0) ? strerror(errno) : "");
343 DEBUG(1, ("vfs_extd_audit: chmod %s mode 0x%x %s %s\n",
345 (result < 0) ? "failed: " : "",
346 (result < 0) ? strerror(errno) : ""));
352 static int audit_chmod_acl(vfs_handle_struct *handle, connection_struct *conn, const char *path, mode_t mode)
356 result = SMB_VFS_NEXT_CHMOD_ACL(handle, conn, path, mode);
358 if (lp_parm_bool(SNUM(handle->conn), "extd_audit", "parseable",
360 syslog(audit_syslog_priority(handle),
361 "%d|%s|chmod_acl|%s|%o\n", current_user.uid,
362 handle->conn->client_address, path, mode);
364 syslog(audit_syslog_priority(handle),
365 "chmod_acl %s mode 0x%x %s%s\n",
367 (result < 0) ? "failed: " : "",
368 (result < 0) ? strerror(errno) : "");
369 DEBUG(1, ("vfs_extd_audit: chmod_acl %s mode 0x%x %s %s\n",
371 (result < 0) ? "failed: " : "",
372 (result < 0) ? strerror(errno) : ""));
378 static int audit_fchmod(vfs_handle_struct *handle, files_struct *fsp, int fd, mode_t mode)
382 result = SMB_VFS_NEXT_FCHMOD(handle, fsp, fd, mode);
384 if (lp_parm_bool(SNUM(handle->conn), "extd_audit", "parseable",
386 syslog(audit_syslog_priority(handle),
387 "%d|%s|fchmod|%s|%o\n", current_user.uid,
388 handle->conn->client_address, fsp->fsp_name, mode);
390 syslog(audit_syslog_priority(handle),
391 "fchmod %s mode 0x%x %s%s\n",
393 (result < 0) ? "failed: " : "",
394 (result < 0) ? strerror(errno) : "");
395 DEBUG(1, ("vfs_extd_audit: fchmod %s mode 0x%x %s %s",
397 (result < 0) ? "failed: " : "",
398 (result < 0) ? strerror(errno) : ""));
404 static int audit_fchmod_acl(vfs_handle_struct *handle, files_struct *fsp, int fd, mode_t mode)
408 result = SMB_VFS_NEXT_FCHMOD_ACL(handle, fsp, fd, mode);
410 if (lp_parm_bool(SNUM(handle->conn), "extd_audit", "parseable",
412 syslog(audit_syslog_priority(handle),
413 "%d|%s|fchmod_acl|%s|%o\n", current_user.uid,
414 handle->conn->client_address, fsp->fsp_name, mode);
416 syslog(audit_syslog_priority(handle),
417 "fchmod_acl %s mode 0x%x %s%s\n",
419 (result < 0) ? "failed: " : "",
420 (result < 0) ? strerror(errno) : "");
421 DEBUG(1, ("vfs_extd_audit: fchmod_acl %s mode 0x%x %s %s",
423 (result < 0) ? "failed: " : "",
424 (result < 0) ? strerror(errno) : ""));
430 NTSTATUS vfs_extd_audit_init(void)
432 NTSTATUS ret = smb_register_vfs(SMB_VFS_INTERFACE_VERSION, "extd_audit", audit_op_tuples);
434 if (!NT_STATUS_IS_OK(ret))
437 vfs_extd_audit_debug_level = debug_add_class("extd_audit");
438 if (vfs_extd_audit_debug_level == -1) {
439 vfs_extd_audit_debug_level = DBGC_VFS;
440 DEBUG(0, ("vfs_extd_audit: Couldn't register custom debugging class!\n"));
442 DEBUG(10, ("vfs_extd_audit: Debug class number of 'extd_audit': %d\n", vfs_extd_audit_debug_level));