Use the new modules system in VFS. If a module can't be loaded with the
[samba.git] / source3 / modules / vfs_extd_audit.c
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  *
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 2 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, write to the Free Software
21  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22  */
23
24 #include "config.h"
25 #include <stdio.h>
26 #include <sys/stat.h>
27 #ifdef HAVE_UTIME_H
28 #include <utime.h>
29 #endif
30 #ifdef HAVE_DIRENT_H
31 #include <dirent.h>
32 #endif
33 #include <syslog.h>
34 #ifdef HAVE_FCNTL_H
35 #include <fcntl.h>
36 #endif
37 #include <errno.h>
38 #include <string.h>
39 #include <includes.h>
40 #include <vfs.h>
41
42 #ifndef SYSLOG_FACILITY
43 #define SYSLOG_FACILITY   LOG_USER
44 #endif
45
46 #ifndef SYSLOG_PRIORITY
47 #define SYSLOG_PRIORITY   LOG_NOTICE
48 #endif
49
50 /* Function prototypes */
51
52 static int audit_connect(struct connection_struct *conn, const char *svc, const char *user);
53 static void audit_disconnect(struct connection_struct *conn);
54 static DIR *audit_opendir(struct connection_struct *conn, const char *fname);
55 static int audit_mkdir(struct connection_struct *conn, const char *path, mode_t mode);
56 static int audit_rmdir(struct connection_struct *conn, const char *path);
57 static int audit_open(struct connection_struct *conn, const char *fname, int flags, mode_t mode);
58 static int audit_close(struct files_struct *fsp, int fd);
59 static int audit_rename(struct connection_struct *conn, const char *old, const char *new);
60 static int audit_unlink(struct connection_struct *conn, const char *path);
61 static int audit_chmod(struct connection_struct *conn, const char *path, mode_t mode);
62 static int audit_chmod_acl(struct connection_struct *conn, const char *name, mode_t mode);
63 static int audit_fchmod(struct files_struct *fsp, int fd, mode_t mode);
64 static int audit_fchmod_acl(struct files_struct *fsp, int fd, mode_t mode);
65
66 /* VFS operations */
67
68 static struct vfs_ops default_vfs_ops;   /* For passthrough operation */
69 static struct smb_vfs_handle_struct *audit_handle;
70
71 static vfs_op_tuple audit_ops[] = {
72     
73         /* Disk operations */
74
75         {audit_connect,         SMB_VFS_OP_CONNECT,     SMB_VFS_LAYER_LOGGER},
76         {audit_disconnect,      SMB_VFS_OP_DISCONNECT,  SMB_VFS_LAYER_LOGGER},
77
78         /* Directory operations */
79
80         {audit_opendir,         SMB_VFS_OP_OPENDIR,     SMB_VFS_LAYER_LOGGER},
81         {audit_mkdir,           SMB_VFS_OP_MKDIR,       SMB_VFS_LAYER_LOGGER},
82         {audit_rmdir,           SMB_VFS_OP_RMDIR,       SMB_VFS_LAYER_LOGGER},
83
84         /* File operations */
85
86         {audit_open,            SMB_VFS_OP_OPEN,        SMB_VFS_LAYER_LOGGER},
87         {audit_close,           SMB_VFS_OP_CLOSE,       SMB_VFS_LAYER_LOGGER},
88         {audit_rename,          SMB_VFS_OP_RENAME,      SMB_VFS_LAYER_LOGGER},
89         {audit_unlink,          SMB_VFS_OP_UNLINK,      SMB_VFS_LAYER_LOGGER},
90         {audit_chmod,           SMB_VFS_OP_CHMOD,       SMB_VFS_LAYER_LOGGER},
91         {audit_fchmod,          SMB_VFS_OP_FCHMOD,      SMB_VFS_LAYER_LOGGER},
92         {audit_chmod_acl,       SMB_VFS_OP_CHMOD_ACL,   SMB_VFS_LAYER_LOGGER},
93         {audit_fchmod_acl,      SMB_VFS_OP_FCHMOD_ACL,  SMB_VFS_LAYER_LOGGER},
94         
95         /* Finish VFS operations definition */
96         
97         {NULL,                  SMB_VFS_OP_NOOP,        SMB_VFS_LAYER_NOOP}
98 };
99
100 /* VFS initialisation function.  Return vfs_op_tuple array back to SAMBA. */
101
102 static vfs_op_tuple *audit_init(const struct vfs_ops *def_vfs_ops, 
103                         struct smb_vfs_handle_struct *vfs_handle)
104 {
105         memcpy(&default_vfs_ops, def_vfs_ops, sizeof(struct vfs_ops));
106         
107         audit_handle = vfs_handle;
108
109         openlog("smbd_audit", LOG_PID, SYSLOG_FACILITY);
110         syslog(SYSLOG_PRIORITY, "VFS_INIT: vfs_ops loaded\n");
111
112         return audit_ops;
113 }
114
115 /* Implementation of vfs_ops.  Pass everything on to the default
116    operation but log event first. */
117
118 static int audit_connect(struct connection_struct *conn, const char *svc, const char *user)
119 {
120         syslog(SYSLOG_PRIORITY, "connect to service %s by user %s\n", 
121                svc, user);
122         DEBUG(10, ("Connected to service %s as user %s\n",
123                svc, user));
124
125         return default_vfs_ops.connect(conn, svc, user);
126 }
127
128 static void audit_disconnect(struct connection_struct *conn)
129 {
130         syslog(SYSLOG_PRIORITY, "disconnected\n");
131         DEBUG(10, ("Disconnected from VFS module extd_audit\n"));
132
133         default_vfs_ops.disconnect(conn);
134 }
135
136 static DIR *audit_opendir(struct connection_struct *conn, const char *fname)
137 {
138         DIR *result = default_vfs_ops.opendir(conn, fname);
139
140         syslog(SYSLOG_PRIORITY, "opendir %s %s%s\n",
141                fname,
142                (result == NULL) ? "failed: " : "",
143                (result == NULL) ? strerror(errno) : "");
144         DEBUG(1, ("vfs_extd_audit: opendir %s %s %s",
145                fname,
146                (result == NULL) ? "failed: " : "",
147                (result == NULL) ? strerror(errno) : ""));
148
149         return result;
150 }
151
152 static int audit_mkdir(struct connection_struct *conn, const char *path, mode_t mode)
153 {
154         int result = default_vfs_ops.mkdir(conn, path, mode);
155
156         syslog(SYSLOG_PRIORITY, "mkdir %s %s%s\n", 
157                path,
158                (result < 0) ? "failed: " : "",
159                (result < 0) ? strerror(errno) : "");
160         DEBUG(0, ("vfs_extd_audit: mkdir %s %s %s\n",
161                path,
162                (result < 0) ? "failed: " : "",
163                (result < 0) ? strerror(errno) : ""));
164
165         return result;
166 }
167
168 static int audit_rmdir(struct connection_struct *conn, const char *path)
169 {
170         int result = default_vfs_ops.rmdir(conn, path);
171
172         syslog(SYSLOG_PRIORITY, "rmdir %s %s%s\n", 
173                path, 
174                (result < 0) ? "failed: " : "",
175                (result < 0) ? strerror(errno) : "");
176         DEBUG(0, ("vfs_extd_audit: rmdir %s %s %s\n",
177                path,
178                (result < 0) ? "failed: " : "",
179                (result < 0) ? strerror(errno) : ""));
180
181         return result;
182 }
183
184 static int audit_open(struct connection_struct *conn, const char *fname, int flags, mode_t mode)
185 {
186         int result = default_vfs_ops.open(conn, fname, flags, mode);
187
188         syslog(SYSLOG_PRIORITY, "open %s (fd %d) %s%s%s\n", 
189                fname, result,
190                ((flags & O_WRONLY) || (flags & O_RDWR)) ? "for writing " : "", 
191                (result < 0) ? "failed: " : "",
192                (result < 0) ? strerror(errno) : "");
193         DEBUG(2, ("vfs_extd_audit: open %s %s %s\n",
194                fname,
195                (result < 0) ? "failed: " : "",
196                (result < 0) ? strerror(errno) : ""));
197
198         return result;
199 }
200
201 static int audit_close(struct files_struct *fsp, int fd)
202 {
203         int result = default_vfs_ops.close(fsp, fd);
204
205         syslog(SYSLOG_PRIORITY, "close fd %d %s%s\n",
206                fd,
207                (result < 0) ? "failed: " : "",
208                (result < 0) ? strerror(errno) : "");
209         DEBUG(2, ("vfs_extd_audit: close fd %d %s %s\n",
210                fd,
211                (result < 0) ? "failed: " : "",
212                (result < 0) ? strerror(errno) : ""));
213
214         return result;
215 }
216
217 static int audit_rename(struct connection_struct *conn, const char *old, const char *new)
218 {
219         int result = default_vfs_ops.rename(conn, old, new);
220
221         syslog(SYSLOG_PRIORITY, "rename %s -> %s %s%s\n",
222                old, new,
223                (result < 0) ? "failed: " : "",
224                (result < 0) ? strerror(errno) : "");
225         DEBUG(1, ("vfs_extd_audit: rename old: %s new: %s  %s %s\n",
226                old, new,
227                (result < 0) ? "failed: " : "",
228                (result < 0) ? strerror(errno) : ""));
229
230         return result;    
231 }
232
233 static int audit_unlink(struct connection_struct *conn, const char *path)
234 {
235         int result = default_vfs_ops.unlink(conn, path);
236
237         syslog(SYSLOG_PRIORITY, "unlink %s %s%s\n",
238                path,
239                (result < 0) ? "failed: " : "",
240                (result < 0) ? strerror(errno) : "");
241         DEBUG(0, ("vfs_extd_audit: unlink %s %s %s\n",
242                path,
243                (result < 0) ? "failed: " : "",
244                (result < 0) ? strerror(errno) : ""));
245
246         return result;
247 }
248
249 static int audit_chmod(struct connection_struct *conn, const char *path, mode_t mode)
250 {
251         int result = default_vfs_ops.chmod(conn, path, mode);
252
253         syslog(SYSLOG_PRIORITY, "chmod %s mode 0x%x %s%s\n",
254                path, mode,
255                (result < 0) ? "failed: " : "",
256                (result < 0) ? strerror(errno) : "");
257         DEBUG(1, ("vfs_extd_audit: chmod %s mode 0x%x %s %s\n",
258                path, mode,
259                (result < 0) ? "failed: " : "",
260                (result < 0) ? strerror(errno) : ""));
261
262         return result;
263 }
264
265 static int audit_chmod_acl(struct connection_struct *conn, const char *path, mode_t mode)
266 {
267         int result = default_vfs_ops.chmod_acl(conn, path, mode);
268
269         syslog(SYSLOG_PRIORITY, "chmod_acl %s mode 0x%x %s%s\n",
270                path, mode,
271                (result < 0) ? "failed: " : "",
272                (result < 0) ? strerror(errno) : "");
273         DEBUG(1, ("vfs_extd_audit: chmod_acl %s mode 0x%x %s %s\n",
274                 path, mode,
275                (result < 0) ? "failed: " : "",
276                (result < 0) ? strerror(errno) : ""));
277
278         return result;
279 }
280
281 static int audit_fchmod(struct files_struct *fsp, int fd, mode_t mode)
282 {
283         int result = default_vfs_ops.fchmod(fsp, fd, mode);
284
285         syslog(SYSLOG_PRIORITY, "fchmod %s mode 0x%x %s%s\n",
286                fsp->fsp_name, mode,
287                (result < 0) ? "failed: " : "",
288                (result < 0) ? strerror(errno) : "");
289         DEBUG(1, ("vfs_extd_audit: fchmod %s mode 0x%x %s %s",
290                fsp->fsp_name,  mode,
291                (result < 0) ? "failed: " : "",
292                (result < 0) ? strerror(errno) : ""));
293
294         return result;
295 }
296
297 static int audit_fchmod_acl(struct files_struct *fsp, int fd, mode_t mode)
298 {
299         int result = default_vfs_ops.fchmod_acl(fsp, fd, mode);
300
301         syslog(SYSLOG_PRIORITY, "fchmod_acl %s mode 0x%x %s%s\n",
302                fsp->fsp_name, mode,
303                (result < 0) ? "failed: " : "",
304                (result < 0) ? strerror(errno) : "");
305         DEBUG(1, ("vfs_extd_audit: fchmod_acl %s mode 0x%x %s %s",
306                fsp->fsp_name,  mode,
307                (result < 0) ? "failed: " : "",
308                (result < 0) ? strerror(errno) : ""));
309
310         return result;
311 }
312
313 int vfs_extd_audit_init(void)
314 {
315         return smb_register_vfs("extd_audit", audit_init, SMB_VFS_INTERFACE_VERSION);
316 }