r20261: merge 20260 from samba_3_0_24
[sfrench/samba-autobuild/.git] / source3 / modules / vfs_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) 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 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
25 #include "includes.h"
26
27 #undef DBGC_CLASS
28 #define DBGC_CLASS DBGC_VFS
29
30 /* Function prototypes */
31
32 static int audit_connect(vfs_handle_struct *handle, const char *svc, const char *user);
33 static void audit_disconnect(vfs_handle_struct *handle);
34 static SMB_STRUCT_DIR *audit_opendir(vfs_handle_struct *handle, const char *fname, const char *mask, uint32 attr);
35 static int audit_mkdir(vfs_handle_struct *handle, const char *path, mode_t mode);
36 static int audit_rmdir(vfs_handle_struct *handle, const char *path);
37 static int audit_open(vfs_handle_struct *handle, const char *fname, files_struct *fsp, int flags, mode_t mode);
38 static int audit_close(vfs_handle_struct *handle, files_struct *fsp, int fd);
39 static int audit_rename(vfs_handle_struct *handle, const char *oldname, const char *newname);
40 static int audit_unlink(vfs_handle_struct *handle, const char *path);
41 static int audit_chmod(vfs_handle_struct *handle, const char *path, mode_t mode);
42 static int audit_chmod_acl(vfs_handle_struct *handle, const char *name, mode_t mode);
43 static int audit_fchmod(vfs_handle_struct *handle, files_struct *fsp, int fd, mode_t mode);
44 static int audit_fchmod_acl(vfs_handle_struct *handle, files_struct *fsp, int fd, mode_t mode);
45
46 /* VFS operations */
47
48 static vfs_op_tuple audit_op_tuples[] = {
49     
50         /* Disk operations */
51
52         {SMB_VFS_OP(audit_connect),     SMB_VFS_OP_CONNECT,     SMB_VFS_LAYER_LOGGER},
53         {SMB_VFS_OP(audit_disconnect),  SMB_VFS_OP_DISCONNECT,  SMB_VFS_LAYER_LOGGER},
54
55         /* Directory operations */
56
57         {SMB_VFS_OP(audit_opendir),     SMB_VFS_OP_OPENDIR,     SMB_VFS_LAYER_LOGGER},
58         {SMB_VFS_OP(audit_mkdir),               SMB_VFS_OP_MKDIR,       SMB_VFS_LAYER_LOGGER},
59         {SMB_VFS_OP(audit_rmdir),               SMB_VFS_OP_RMDIR,       SMB_VFS_LAYER_LOGGER},
60
61         /* File operations */
62
63         {SMB_VFS_OP(audit_open),                SMB_VFS_OP_OPEN,        SMB_VFS_LAYER_LOGGER},
64         {SMB_VFS_OP(audit_close),               SMB_VFS_OP_CLOSE,       SMB_VFS_LAYER_LOGGER},
65         {SMB_VFS_OP(audit_rename),              SMB_VFS_OP_RENAME,      SMB_VFS_LAYER_LOGGER},
66         {SMB_VFS_OP(audit_unlink),              SMB_VFS_OP_UNLINK,      SMB_VFS_LAYER_LOGGER},
67         {SMB_VFS_OP(audit_chmod),               SMB_VFS_OP_CHMOD,       SMB_VFS_LAYER_LOGGER},
68         {SMB_VFS_OP(audit_fchmod),              SMB_VFS_OP_FCHMOD,      SMB_VFS_LAYER_LOGGER},
69         {SMB_VFS_OP(audit_chmod_acl),   SMB_VFS_OP_CHMOD_ACL,   SMB_VFS_LAYER_LOGGER},
70         {SMB_VFS_OP(audit_fchmod_acl),  SMB_VFS_OP_FCHMOD_ACL,  SMB_VFS_LAYER_LOGGER},
71         
72         /* Finish VFS operations definition */
73         
74         {SMB_VFS_OP(NULL),                      SMB_VFS_OP_NOOP,        SMB_VFS_LAYER_NOOP}
75 };
76
77
78 static int audit_syslog_facility(vfs_handle_struct *handle)
79 {
80         static const struct enum_list enum_log_facilities[] = {
81                 { LOG_USER, "USER" },
82                 { LOG_LOCAL0, "LOCAL0" },
83                 { LOG_LOCAL1, "LOCAL1" },
84                 { LOG_LOCAL2, "LOCAL2" },
85                 { LOG_LOCAL3, "LOCAL3" },
86                 { LOG_LOCAL4, "LOCAL4" },
87                 { LOG_LOCAL5, "LOCAL5" },
88                 { LOG_LOCAL6, "LOCAL6" },
89                 { LOG_LOCAL7, "LOCAL7" }
90         };
91
92         int facility;
93
94         facility = lp_parm_enum(SNUM(handle->conn), "audit", "facility", enum_log_facilities, LOG_USER);
95
96         return facility;
97 }
98
99
100 static int audit_syslog_priority(vfs_handle_struct *handle)
101 {
102         static const struct enum_list enum_log_priorities[] = {
103                 { LOG_EMERG, "EMERG" },
104                 { LOG_ALERT, "ALERT" },
105                 { LOG_CRIT, "CRIT" },
106                 { LOG_ERR, "ERR" },
107                 { LOG_WARNING, "WARNING" },
108                 { LOG_NOTICE, "NOTICE" },
109                 { LOG_INFO, "INFO" },
110                 { LOG_DEBUG, "DEBUG" }
111         };
112
113         int priority;
114
115         priority = lp_parm_enum(SNUM(handle->conn), "audit", "priority", enum_log_priorities, LOG_NOTICE);
116
117         return priority;
118 }
119
120 /* Implementation of vfs_ops.  Pass everything on to the default
121    operation but log event first. */
122
123 static int audit_connect(vfs_handle_struct *handle, const char *svc, const char *user)
124 {
125         int result;
126         
127         openlog("smbd_audit", LOG_PID, audit_syslog_facility(handle));
128
129         syslog(audit_syslog_priority(handle), "connect to service %s by user %s\n", 
130                svc, user);
131
132         result = SMB_VFS_NEXT_CONNECT(handle, svc, user);
133
134         return result;
135 }
136
137 static void audit_disconnect(vfs_handle_struct *handle)
138 {
139         syslog(audit_syslog_priority(handle), "disconnected\n");
140         SMB_VFS_NEXT_DISCONNECT(handle);
141
142         return;
143 }
144
145 static SMB_STRUCT_DIR *audit_opendir(vfs_handle_struct *handle, const char *fname, const char *mask, uint32 attr)
146 {
147         SMB_STRUCT_DIR *result;
148         
149         result = SMB_VFS_NEXT_OPENDIR(handle, fname, mask, attr);
150
151         syslog(audit_syslog_priority(handle), "opendir %s %s%s\n",
152                fname,
153                (result == NULL) ? "failed: " : "",
154                (result == NULL) ? strerror(errno) : "");
155
156         return result;
157 }
158
159 static int audit_mkdir(vfs_handle_struct *handle, const char *path, mode_t mode)
160 {
161         int result;
162         
163         result = SMB_VFS_NEXT_MKDIR(handle, path, mode);
164         
165         syslog(audit_syslog_priority(handle), "mkdir %s %s%s\n", 
166                path,
167                (result < 0) ? "failed: " : "",
168                (result < 0) ? strerror(errno) : "");
169
170         return result;
171 }
172
173 static int audit_rmdir(vfs_handle_struct *handle, const char *path)
174 {
175         int result;
176
177         result = SMB_VFS_NEXT_RMDIR(handle, path);
178
179         syslog(audit_syslog_priority(handle), "rmdir %s %s%s\n", 
180                path, 
181                (result < 0) ? "failed: " : "",
182                (result < 0) ? strerror(errno) : "");
183
184         return result;
185 }
186
187 static int audit_open(vfs_handle_struct *handle, const char *fname, files_struct *fsp, int flags, mode_t mode)
188 {
189         int result;
190
191         result = SMB_VFS_NEXT_OPEN(handle, fname, fsp, flags, mode);
192
193         syslog(audit_syslog_priority(handle), "open %s (fd %d) %s%s%s\n", 
194                fname, result,
195                ((flags & O_WRONLY) || (flags & O_RDWR)) ? "for writing " : "", 
196                (result < 0) ? "failed: " : "",
197                (result < 0) ? strerror(errno) : "");
198
199         return result;
200 }
201
202 static int audit_close(vfs_handle_struct *handle, files_struct *fsp, int fd)
203 {
204         int result;
205
206         result = SMB_VFS_NEXT_CLOSE(handle, fsp, fd);
207
208         syslog(audit_syslog_priority(handle), "close fd %d %s%s\n",
209                fd,
210                (result < 0) ? "failed: " : "",
211                (result < 0) ? strerror(errno) : "");
212
213         return result;
214 }
215
216 static int audit_rename(vfs_handle_struct *handle, const char *oldname, const char *newname)
217 {
218         int result;
219
220         result = SMB_VFS_NEXT_RENAME(handle, oldname, newname);
221
222         syslog(audit_syslog_priority(handle), "rename %s -> %s %s%s\n",
223                oldname, newname,
224                (result < 0) ? "failed: " : "",
225                (result < 0) ? strerror(errno) : "");
226
227         return result;    
228 }
229
230 static int audit_unlink(vfs_handle_struct *handle, const char *path)
231 {
232         int result;
233
234         result = SMB_VFS_NEXT_UNLINK(handle, path);
235
236         syslog(audit_syslog_priority(handle), "unlink %s %s%s\n",
237                path,
238                (result < 0) ? "failed: " : "",
239                (result < 0) ? strerror(errno) : "");
240
241         return result;
242 }
243
244 static int audit_chmod(vfs_handle_struct *handle, const char *path, mode_t mode)
245 {
246         int result;
247
248         result = SMB_VFS_NEXT_CHMOD(handle, path, mode);
249
250         syslog(audit_syslog_priority(handle), "chmod %s mode 0x%x %s%s\n",
251                path, mode,
252                (result < 0) ? "failed: " : "",
253                (result < 0) ? strerror(errno) : "");
254
255         return result;
256 }
257
258 static int audit_chmod_acl(vfs_handle_struct *handle, const char *path, mode_t mode)
259 {
260         int result;
261
262         result = SMB_VFS_NEXT_CHMOD_ACL(handle, path, mode);
263
264         syslog(audit_syslog_priority(handle), "chmod_acl %s mode 0x%x %s%s\n",
265                path, mode,
266                (result < 0) ? "failed: " : "",
267                (result < 0) ? strerror(errno) : "");
268
269         return result;
270 }
271
272 static int audit_fchmod(vfs_handle_struct *handle, files_struct *fsp, int fd, mode_t mode)
273 {
274         int result;
275
276         result = SMB_VFS_NEXT_FCHMOD(handle, fsp, fd, mode);
277
278         syslog(audit_syslog_priority(handle), "fchmod %s mode 0x%x %s%s\n",
279                fsp->fsp_name, mode,
280                (result < 0) ? "failed: " : "",
281                (result < 0) ? strerror(errno) : "");
282
283         return result;
284 }
285
286 static int audit_fchmod_acl(vfs_handle_struct *handle, files_struct *fsp, int fd, mode_t mode)
287 {
288         int result;
289
290         result = SMB_VFS_NEXT_FCHMOD_ACL(handle, fsp, fd, mode);
291
292         syslog(audit_syslog_priority(handle), "fchmod_acl %s mode 0x%x %s%s\n",
293                fsp->fsp_name, mode,
294                (result < 0) ? "failed: " : "",
295                (result < 0) ? strerror(errno) : "");
296
297         return result;
298 }
299
300 NTSTATUS vfs_audit_init(void);
301 NTSTATUS vfs_audit_init(void)
302 {
303         return smb_register_vfs(SMB_VFS_INTERFACE_VERSION, "audit", audit_op_tuples);
304 }