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) John H Terpstra, 2003
8 : * Copyright (C) Stefan (metze) Metzmacher, 2003
9 : *
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 3 of the License, or
13 : * (at your option) any later version.
14 : *
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.
19 : *
20 : * You should have received a copy of the GNU General Public License
21 : * along with this program; if not, see <http://www.gnu.org/licenses/>.
22 : */
23 :
24 :
25 : #include "includes.h"
26 : #include "system/filesys.h"
27 : #include "system/syslog.h"
28 : #include "smbd/smbd.h"
29 : #include "lib/param/loadparm.h"
30 :
31 : static int vfs_extd_audit_debug_level = DBGC_VFS;
32 :
33 : #undef DBGC_CLASS
34 : #define DBGC_CLASS vfs_extd_audit_debug_level
35 :
36 0 : static int audit_syslog_facility(vfs_handle_struct *handle)
37 : {
38 : static const struct enum_list enum_log_facilities[] = {
39 : #ifdef LOG_AUTH
40 : { LOG_AUTH, "AUTH" },
41 : #endif
42 : #ifdef LOG_AUTHPRIV
43 : { LOG_AUTHPRIV, "AUTHPRIV" },
44 : #endif
45 : #ifdef LOG_AUDIT
46 : { LOG_AUDIT, "AUDIT" },
47 : #endif
48 : #ifdef LOG_CONSOLE
49 : { LOG_CONSOLE, "CONSOLE" },
50 : #endif
51 : #ifdef LOG_CRON
52 : { LOG_CRON, "CRON" },
53 : #endif
54 : #ifdef LOG_DAEMON
55 : { LOG_DAEMON, "DAEMON" },
56 : #endif
57 : #ifdef LOG_FTP
58 : { LOG_FTP, "FTP" },
59 : #endif
60 : #ifdef LOG_INSTALL
61 : { LOG_INSTALL, "INSTALL" },
62 : #endif
63 : #ifdef LOG_KERN
64 : { LOG_KERN, "KERN" },
65 : #endif
66 : #ifdef LOG_LAUNCHD
67 : { LOG_LAUNCHD, "LAUNCHD" },
68 : #endif
69 : #ifdef LOG_LFMT
70 : { LOG_LFMT, "LFMT" },
71 : #endif
72 : #ifdef LOG_LPR
73 : { LOG_LPR, "LPR" },
74 : #endif
75 : #ifdef LOG_MAIL
76 : { LOG_MAIL, "MAIL" },
77 : #endif
78 : #ifdef LOG_MEGASAFE
79 : { LOG_MEGASAFE, "MEGASAFE" },
80 : #endif
81 : #ifdef LOG_NETINFO
82 : { LOG_NETINFO, "NETINFO" },
83 : #endif
84 : #ifdef LOG_NEWS
85 : { LOG_NEWS, "NEWS" },
86 : #endif
87 : #ifdef LOG_NFACILITIES
88 : { LOG_NFACILITIES, "NFACILITIES" },
89 : #endif
90 : #ifdef LOG_NTP
91 : { LOG_NTP, "NTP" },
92 : #endif
93 : #ifdef LOG_RAS
94 : { LOG_RAS, "RAS" },
95 : #endif
96 : #ifdef LOG_REMOTEAUTH
97 : { LOG_REMOTEAUTH, "REMOTEAUTH" },
98 : #endif
99 : #ifdef LOG_SECURITY
100 : { LOG_SECURITY, "SECURITY" },
101 : #endif
102 : #ifdef LOG_SYSLOG
103 : { LOG_SYSLOG, "SYSLOG" },
104 : #endif
105 : #ifdef LOG_USER
106 : { LOG_USER, "USER" },
107 : #endif
108 : #ifdef LOG_UUCP
109 : { LOG_UUCP, "UUCP" },
110 : #endif
111 : { LOG_LOCAL0, "LOCAL0" },
112 : { LOG_LOCAL1, "LOCAL1" },
113 : { LOG_LOCAL2, "LOCAL2" },
114 : { LOG_LOCAL3, "LOCAL3" },
115 : { LOG_LOCAL4, "LOCAL4" },
116 : { LOG_LOCAL5, "LOCAL5" },
117 : { LOG_LOCAL6, "LOCAL6" },
118 : { LOG_LOCAL7, "LOCAL7" },
119 : { -1, NULL }
120 : };
121 :
122 : int facility;
123 :
124 0 : facility = lp_parm_enum(SNUM(handle->conn), "extd_audit", "facility", enum_log_facilities, LOG_USER);
125 :
126 0 : return facility;
127 : }
128 :
129 :
130 0 : static int audit_syslog_priority(vfs_handle_struct *handle)
131 : {
132 : static const struct enum_list enum_log_priorities[] = {
133 : { LOG_EMERG, "EMERG" },
134 : { LOG_ALERT, "ALERT" },
135 : { LOG_CRIT, "CRIT" },
136 : { LOG_ERR, "ERR" },
137 : { LOG_WARNING, "WARNING" },
138 : { LOG_NOTICE, "NOTICE" },
139 : { LOG_INFO, "INFO" },
140 : { LOG_DEBUG, "DEBUG" },
141 : { -1, NULL }
142 : };
143 :
144 : int priority;
145 :
146 0 : priority = lp_parm_enum(SNUM(handle->conn), "extd_audit", "priority",
147 : enum_log_priorities, LOG_NOTICE);
148 0 : if (priority == -1) {
149 0 : priority = LOG_WARNING;
150 : }
151 :
152 0 : return priority;
153 : }
154 :
155 : /* Implementation of vfs_ops. Pass everything on to the default
156 : operation but log event first. */
157 :
158 0 : static int audit_connect(vfs_handle_struct *handle, const char *svc, const char *user)
159 : {
160 0 : int result = SMB_VFS_NEXT_CONNECT(handle, svc, user);
161 :
162 0 : if (result < 0) {
163 0 : return result;
164 : }
165 :
166 0 : openlog("smbd_audit", LOG_PID, audit_syslog_facility(handle));
167 :
168 0 : if (lp_syslog() > 0) {
169 0 : syslog(audit_syslog_priority(handle),
170 : "connect to service %s by user %s\n",
171 : svc, user);
172 : }
173 0 : DEBUG(10, ("Connected to service %s as user %s\n",
174 : svc, user));
175 :
176 0 : return 0;
177 : }
178 :
179 0 : static void audit_disconnect(vfs_handle_struct *handle)
180 : {
181 0 : if (lp_syslog() > 0) {
182 0 : syslog(audit_syslog_priority(handle), "disconnected\n");
183 : }
184 0 : DEBUG(10, ("Disconnected from VFS module extd_audit\n"));
185 0 : SMB_VFS_NEXT_DISCONNECT(handle);
186 :
187 0 : return;
188 : }
189 :
190 0 : static int audit_mkdirat(vfs_handle_struct *handle,
191 : struct files_struct *dirfsp,
192 : const struct smb_filename *smb_fname,
193 : mode_t mode)
194 : {
195 0 : struct smb_filename *full_fname = NULL;
196 : int result;
197 :
198 0 : full_fname = full_path_from_dirfsp_atname(talloc_tos(),
199 : dirfsp,
200 : smb_fname);
201 0 : if (full_fname == NULL) {
202 0 : errno = ENOMEM;
203 0 : return -1;
204 : }
205 :
206 0 : result = SMB_VFS_NEXT_MKDIRAT(handle,
207 : dirfsp,
208 : smb_fname,
209 : mode);
210 :
211 0 : if (lp_syslog() > 0) {
212 0 : syslog(audit_syslog_priority(handle), "mkdirat %s %s%s\n",
213 : full_fname->base_name,
214 : (result < 0) ? "failed: " : "",
215 0 : (result < 0) ? strerror(errno) : "");
216 : }
217 0 : DEBUG(0, ("vfs_extd_audit: mkdirat %s %s %s\n",
218 : full_fname->base_name,
219 : (result < 0) ? "failed: " : "",
220 : (result < 0) ? strerror(errno) : ""));
221 :
222 0 : TALLOC_FREE(full_fname);
223 0 : return result;
224 : }
225 :
226 0 : static int audit_openat(vfs_handle_struct *handle,
227 : const struct files_struct *dirfsp,
228 : const struct smb_filename *smb_fname,
229 : files_struct *fsp,
230 : const struct vfs_open_how *how)
231 : {
232 : int ret;
233 :
234 0 : ret = SMB_VFS_NEXT_OPENAT(handle, dirfsp, smb_fname, fsp, how);
235 :
236 0 : if (lp_syslog() > 0) {
237 0 : syslog(audit_syslog_priority(handle),
238 : "openat %s/%s (fd %d) %s%s%s\n",
239 0 : smb_fname_str_dbg(fsp->fsp_name),
240 0 : smb_fname->base_name,
241 : ret,
242 0 : ((how->flags & O_WRONLY) || (how->flags & O_RDWR)) ?
243 : "for writing " : "",
244 : (ret < 0) ? "failed: " : "",
245 0 : (ret < 0) ? strerror(errno) : "");
246 : }
247 0 : DEBUG(2, ("vfs_extd_audit: open %s/%s %s %s\n",
248 : smb_fname_str_dbg(fsp->fsp_name),
249 : smb_fname_str_dbg(smb_fname),
250 : (ret < 0) ? "failed: " : "",
251 : (ret < 0) ? strerror(errno) : ""));
252 :
253 0 : return ret;
254 : }
255 :
256 0 : static int audit_close(vfs_handle_struct *handle, files_struct *fsp)
257 : {
258 : int result;
259 :
260 0 : result = SMB_VFS_NEXT_CLOSE(handle, fsp);
261 :
262 0 : if (lp_syslog() > 0) {
263 0 : syslog(audit_syslog_priority(handle), "close fd %d %s%s\n",
264 : fsp_get_pathref_fd(fsp),
265 : (result < 0) ? "failed: " : "",
266 0 : (result < 0) ? strerror(errno) : "");
267 : }
268 0 : DEBUG(2, ("vfs_extd_audit: close fd %d %s %s\n",
269 : fsp_get_pathref_fd(fsp),
270 : (result < 0) ? "failed: " : "",
271 : (result < 0) ? strerror(errno) : ""));
272 :
273 0 : return result;
274 : }
275 :
276 0 : static int audit_renameat(vfs_handle_struct *handle,
277 : files_struct *srcfsp,
278 : const struct smb_filename *smb_fname_src,
279 : files_struct *dstfsp,
280 : const struct smb_filename *smb_fname_dst)
281 : {
282 0 : struct smb_filename *full_fname_src = NULL;
283 0 : struct smb_filename *full_fname_dst = NULL;
284 : int result;
285 0 : int saved_errno = 0;
286 :
287 0 : full_fname_src = full_path_from_dirfsp_atname(talloc_tos(),
288 : srcfsp,
289 : smb_fname_src);
290 0 : if (full_fname_src == NULL) {
291 0 : errno = ENOMEM;
292 0 : return -1;
293 : }
294 :
295 0 : full_fname_dst = full_path_from_dirfsp_atname(talloc_tos(),
296 : dstfsp,
297 : smb_fname_dst);
298 0 : if (full_fname_dst == NULL) {
299 0 : TALLOC_FREE(full_fname_src);
300 0 : errno = ENOMEM;
301 0 : return -1;
302 : }
303 :
304 0 : result = SMB_VFS_NEXT_RENAMEAT(handle,
305 : srcfsp,
306 : smb_fname_src,
307 : dstfsp,
308 : smb_fname_dst);
309 0 : if (result == -1) {
310 0 : saved_errno = errno;
311 : }
312 0 : if (lp_syslog() > 0) {
313 0 : syslog(audit_syslog_priority(handle), "renameat %s -> %s %s%s\n",
314 : full_fname_src->base_name,
315 : full_fname_dst->base_name,
316 : (result < 0) ? "failed: " : "",
317 0 : (result < 0) ? strerror(saved_errno) : "");
318 : }
319 0 : DEBUG(1, ("vfs_extd_audit: renameat old: %s newname: %s %s %s\n",
320 : smb_fname_str_dbg(full_fname_src),
321 : smb_fname_str_dbg(full_fname_dst),
322 : (result < 0) ? "failed: " : "",
323 : (result < 0) ? strerror(saved_errno) : ""));
324 :
325 0 : TALLOC_FREE(full_fname_src);
326 0 : TALLOC_FREE(full_fname_dst);
327 :
328 0 : if (result == -1) {
329 0 : errno = saved_errno;
330 : }
331 0 : return result;
332 : }
333 :
334 0 : static int audit_unlinkat(vfs_handle_struct *handle,
335 : struct files_struct *dirfsp,
336 : const struct smb_filename *smb_fname,
337 : int flags)
338 : {
339 0 : struct smb_filename *full_fname = NULL;
340 : int result;
341 :
342 0 : full_fname = full_path_from_dirfsp_atname(talloc_tos(),
343 : dirfsp,
344 : smb_fname);
345 0 : if (full_fname == NULL) {
346 0 : return -1;
347 : }
348 :
349 0 : result = SMB_VFS_NEXT_UNLINKAT(handle,
350 : dirfsp,
351 : smb_fname,
352 : flags);
353 :
354 0 : if (lp_syslog() > 0) {
355 0 : syslog(audit_syslog_priority(handle), "unlinkat %s %s%s\n",
356 : full_fname->base_name,
357 : (result < 0) ? "failed: " : "",
358 0 : (result < 0) ? strerror(errno) : "");
359 : }
360 0 : DBG_ERR("unlinkat %s %s %s\n",
361 : smb_fname_str_dbg(full_fname),
362 : (result < 0) ? "failed: " : "",
363 : (result < 0) ? strerror(errno) : "");
364 :
365 0 : TALLOC_FREE(full_fname);
366 0 : return result;
367 : }
368 :
369 0 : static int audit_fchmod(vfs_handle_struct *handle, files_struct *fsp, mode_t mode)
370 : {
371 : int result;
372 :
373 0 : result = SMB_VFS_NEXT_FCHMOD(handle, fsp, mode);
374 :
375 0 : if (lp_syslog() > 0) {
376 0 : syslog(audit_syslog_priority(handle), "fchmod %s mode 0x%x %s%s\n",
377 0 : fsp->fsp_name->base_name, mode,
378 : (result < 0) ? "failed: " : "",
379 0 : (result < 0) ? strerror(errno) : "");
380 : }
381 0 : DEBUG(1, ("vfs_extd_audit: fchmod %s mode 0x%x %s %s\n",
382 : fsp_str_dbg(fsp), (unsigned int)mode,
383 : (result < 0) ? "failed: " : "",
384 : (result < 0) ? strerror(errno) : ""));
385 :
386 0 : return result;
387 : }
388 :
389 : static struct vfs_fn_pointers vfs_extd_audit_fns = {
390 : .connect_fn = audit_connect,
391 : .disconnect_fn = audit_disconnect,
392 : .mkdirat_fn = audit_mkdirat,
393 : .openat_fn = audit_openat,
394 : .close_fn = audit_close,
395 : .renameat_fn = audit_renameat,
396 : .unlinkat_fn = audit_unlinkat,
397 : .fchmod_fn = audit_fchmod,
398 : };
399 :
400 : static_decl_vfs;
401 27 : NTSTATUS vfs_extd_audit_init(TALLOC_CTX *ctx)
402 : {
403 27 : NTSTATUS ret = smb_register_vfs(SMB_VFS_INTERFACE_VERSION,
404 : "extd_audit", &vfs_extd_audit_fns);
405 :
406 27 : if (!NT_STATUS_IS_OK(ret))
407 0 : return ret;
408 :
409 27 : vfs_extd_audit_debug_level = debug_add_class("extd_audit");
410 27 : if (vfs_extd_audit_debug_level == -1) {
411 0 : vfs_extd_audit_debug_level = DBGC_VFS;
412 0 : DEBUG(0, ("vfs_extd_audit: Couldn't register custom debugging class!\n"));
413 : } else {
414 27 : DEBUG(10, ("vfs_extd_audit: Debug class number of 'extd_audit': %d\n", vfs_extd_audit_debug_level));
415 : }
416 :
417 27 : return ret;
418 : }
|