Whamcloud - gitweb
b=7354
[fs/lustre-release.git] / lustre / smfs / audit_mds.c
1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2  * vim:expandtab:shiftwidth=8:tabstop=8:
3  *
4  *  lustre/smfs/audit_mds.c
5  *  Lustre filesystem audit part for MDS
6  *
7  *  Copyright (C) 2004 Cluster File Systems, Inc.
8  *
9  *   This file is part of Lustre, http://www.lustre.org.
10  *
11  *   Lustre is free software; you can redistribute it and/or
12  *   modify it under the terms of version 2 of the GNU General Public
13  *   License as published by the Free Software Foundation.
14  *
15  *   Lustre 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 Lustre; if not, write to the Free Software
22  *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23  */
24 #ifndef EXPORT_SYMTAB
25 # define EXPORT_SYMTAB
26 #endif
27
28 #define DEBUG_SUBSYSTEM S_SM
29
30 #include <linux/kmod.h>
31 #include <linux/init.h>
32 #include <linux/fs.h>
33 #include <linux/slab.h>
34 #include <linux/obd_class.h>
35 #include <linux/obd.h>
36 #include <linux/lustre_lib.h>
37 #include <linux/lustre_log.h>
38 #include <linux/lustre_fsfilt.h>
39 #include <linux/lustre_smfs.h>
40 #include <linux/lustre_audit.h>
41 #include "smfs_internal.h"
42
43 static inline int audit_fill_id_rec (char **pbuf, struct inode * inode)
44 {
45         struct fsfilt_operations *fsfilt = I2FOPS(inode);
46         struct audit_id_record * rec = (void*)(*pbuf);
47         int len = sizeof(*rec);
48         struct lustre_fid fid;
49         int rc = 0;
50         
51         rec->au_num = inode->i_ino;
52         rec->au_type = (S_IFMT & inode->i_mode);
53         rec->au_gen = inode->i_generation;
54         
55         //fid & mdsnum
56         rc = fsfilt->fs_get_md(I2CI(inode), &fid, sizeof(fid), EA_SID);
57         if (rc > 0) {
58                 rec->au_fid = fid.lf_id;
59                 rec->au_mds = fid.lf_group;
60         }
61         
62         *pbuf += len;
63         return len;
64 }
65
66 int static audit_mds_create_rec(struct inode * parent, void * arg,
67                                 struct audit_priv * priv, char * buffer,
68                                 __u32 * type)
69 {
70         struct hook_msg * msg = arg;
71         struct audit_record * rec = (void*)buffer;
72         char * pbuf = buffer + sizeof(*rec); 
73         struct inode * inode = msg->dentry->d_inode;
74         int len = sizeof(*rec);
75
76         rec->opcode = AUDIT_CREATE;
77         if (priv->result == 0) { //successfull operation
78                 len += audit_fill_id_rec(&pbuf, inode);
79                 *type = SMFS_AUDIT_GEN_REC;
80         }
81         else { //failed operation
82                 len += audit_fill_id_rec(&pbuf, parent);
83                 len += audit_fill_name_rec(&pbuf, msg->dentry->d_name.name,
84                                            msg->dentry->d_name.len);
85                 
86                 *type = SMFS_AUDIT_NAME_REC;
87         }
88         return len;
89 }
90
91 int static audit_mds_link_rec(struct inode * parent, void * arg, 
92                               struct audit_priv * priv, char * buffer,
93                               __u32 *type)
94 {
95         struct hook_link_msg * msg = arg;
96         struct audit_record * rec = (void*)buffer;
97         char * pbuf = buffer + sizeof(*rec);
98         struct inode * inode = msg->dentry->d_inode;
99         int len = sizeof(*rec);
100
101         rec->opcode = AUDIT_LINK;
102         
103         /* these things will be needed always */
104         len += audit_fill_id_rec(&pbuf, inode);
105         len += audit_fill_id_rec(&pbuf, parent);
106         len += audit_fill_name_rec(&pbuf, msg->dentry->d_name.name,
107                                    msg->dentry->d_name.len);
108         *type = SMFS_AUDIT_NAME_REC;
109         
110         return len;
111 }
112
113 int static audit_mds_unlink_rec(struct inode * parent, void * arg,
114                                 struct audit_priv * priv, char * buffer,
115                                 __u32 *type)
116 {
117         struct hook_unlink_msg * msg = arg;
118         struct inode * inode = msg->dentry->d_inode;
119         struct audit_record * rec = (void*)buffer;
120         char * pbuf = buffer + sizeof(*rec);
121         int len = sizeof(*rec);
122               
123         rec->opcode = AUDIT_UNLINK;
124         
125         
126         len += audit_fill_id_rec(&pbuf, inode);
127         len += audit_fill_id_rec(&pbuf, parent);
128         if (priv->result == 0) {
129                 len += audit_fill_name_rec(&pbuf, msg->dentry->d_name.name,
130                                    msg->dentry->d_name.len);
131                 *type = SMFS_AUDIT_NAME_REC;
132         } else {
133                 //in case of failure name shouldn't be saved
134                 *type = SMFS_AUDIT_GEN_REC;
135         }
136         
137         return len;
138 }
139
140 int static audit_mds_rename_rec(struct inode * parent, void * arg, 
141                                 struct audit_priv * priv, char * buffer,
142                                 __u32 *type)
143 {
144         struct hook_rename_msg * msg = arg;
145         struct inode * inode = msg->dentry->d_inode;
146         struct audit_record * rec = (void*)buffer;
147         char * pbuf = buffer + sizeof(*rec);
148         int len = sizeof(*rec);
149         
150         rec->opcode = AUDIT_RENAME;
151         
152         len += audit_fill_id_rec(&pbuf, inode);
153         if (priv->result == 0) {
154                 len += audit_fill_id_rec(&pbuf, msg->old_dir);
155                 len += audit_fill_name_rec(&pbuf, msg->dentry->d_name.name,
156                                            msg->dentry->d_name.len);
157         } else { 
158                 len += audit_fill_id_rec(&pbuf, msg->new_dir);
159                 len += audit_fill_name_rec(&pbuf, msg->new_dentry->d_name.name,
160                                            msg->new_dentry->d_name.len);
161         }
162         
163         *type = SMFS_AUDIT_NAME_REC;
164                 
165         return len;
166
167 }
168
169 int static audit_mds_setattr_rec(struct inode * inode, void * arg, 
170                               struct audit_priv * priv, char * buffer,
171                               __u32 *type)
172 {
173         //struct hook_attr_msg * msg = arg;
174         struct audit_record * rec = (void*)buffer;
175         char * pbuf = buffer + sizeof(*rec);
176         int len = sizeof(*rec);
177         
178         rec->opcode = AUDIT_SETATTR;
179         len += audit_fill_id_rec(&pbuf, inode);
180         *type = SMFS_AUDIT_GEN_REC;
181                 
182         return len;
183 }
184
185 int static audit_mds_readlink_rec(struct inode * inode, void * arg, 
186                                   struct audit_priv * priv, char * buffer,
187                                   __u32 *type)
188 {
189         //struct hook_symlink_msg * msg = arg;
190         struct audit_record * rec = (void*)buffer;
191         char * pbuf = buffer + sizeof(*rec);
192         int len = sizeof(*rec);
193         
194         rec->opcode = AUDIT_READLINK;
195         len += audit_fill_id_rec(&pbuf, inode);
196         *type = SMFS_AUDIT_GEN_REC;
197                 
198         return len;
199 }
200
201 int static audit_mds_readdir_rec(struct inode * inode, void * arg, 
202                                  struct audit_priv * priv, char * buffer,
203                                  __u32 *type)
204 {
205         struct audit_record * rec = (void*)buffer;
206         char * pbuf = buffer + sizeof(*rec);
207         int len = sizeof(*rec);
208         
209         rec->opcode = AUDIT_READDIR;
210         len += audit_fill_id_rec(&pbuf, inode);
211         *type = SMFS_AUDIT_GEN_REC;
212                 
213         return len;
214 }
215
216 /* for special records from failed auth and open/stat*/
217 int audit_mds_special_rec(struct inode * inode, void * arg,
218                           struct audit_priv * priv, char *buffer,
219                           __u32 * type)
220 {
221         struct audit_info * info = arg;
222         struct audit_msg * msg = &info->m;
223         struct audit_record * rec = (void*)buffer;
224         char * pbuf = buffer + sizeof(*rec);
225         int len = sizeof(*rec);
226                 
227         //rewrite some fields
228         rec->opcode = msg->code;
229         rec->result = msg->result;
230         rec->uid = msg->uid;
231         rec->gid = msg->gid;
232         rec->nid = msg->nid;
233         
234         /* check id is valid */
235         LASSERT(id_ino(&msg->id));
236         LASSERT(id_fid(&msg->id));
237         // LASSERT(id_type(&msg->id) & S_IFMT);
238         
239         len += audit_rec_from_id(&pbuf, &msg->id);
240         switch (rec->opcode)
241         {
242                 case AUDIT_OPEN:
243                 case AUDIT_CREATE:
244                 case AUDIT_STAT:
245                         if (info->name && info->namelen > 0) { 
246                                 len += audit_fill_name_rec(&pbuf,
247                                                            info->name,
248                                                            info->namelen);
249                                 *type = SMFS_AUDIT_NAME_REC;
250                                 break;
251                         }
252                 default:
253                         *type = SMFS_AUDIT_GEN_REC;
254         }
255         
256         return len;
257 }
258
259 static audit_get_op audit_mds_record[HOOK_MAX] = {
260         [HOOK_CREATE]     audit_mds_create_rec,
261         [HOOK_LINK]       audit_mds_link_rec,
262         [HOOK_UNLINK]     audit_mds_unlink_rec,
263         [HOOK_SYMLINK]    audit_mds_create_rec,
264         [HOOK_READLINK]   audit_mds_readlink_rec,
265         [HOOK_MKDIR]      audit_mds_create_rec,
266         [HOOK_RMDIR]      audit_mds_unlink_rec,
267         [HOOK_MKNOD]      audit_mds_create_rec,
268         [HOOK_RENAME]     audit_mds_rename_rec,
269         [HOOK_SETATTR]    audit_mds_setattr_rec,
270         [HOOK_F_SETATTR]  audit_mds_setattr_rec,
271         [HOOK_SPECIAL]    audit_mds_special_rec,
272         [HOOK_READDIR]    audit_mds_readdir_rec,
273 };
274
275 int audit_mds_setup(struct obd_device * obd, struct super_block *sb,
276                     struct audit_priv *priv) 
277 {
278         int rc;
279         struct smfs_super_info * smb = S2SMI(sb);
280         struct llog_ctxt **ctxt = &priv->audit_ctxt;
281         
282         //this will do OBD_ALLOC() for ctxt
283         rc = llog_catalog_setup(ctxt, AUDIT_MDS_NAME, smb->smsi_exp,
284                                 smb->smsi_ctxt, smb->sm_fsfilt,
285                                 smb->smsi_logs_dir, smb->smsi_objects_dir);
286
287         /* export audit llog ctxt */
288         if (*ctxt) {
289                 (*ctxt)->loc_idx = LLOG_AUDIT_ORIG_CTXT;
290                 (*ctxt)->loc_obd = obd;
291                 (*ctxt)->loc_llogs = &obd->obd_llogs;
292                 (*ctxt)->loc_llogs->llog_ctxt[LLOG_AUDIT_ORIG_CTXT] = *ctxt;
293         }
294         priv->audit_get_record = &audit_mds_record;
295         return 0;
296 }