1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2 * vim:expandtab:shiftwidth=8:tabstop=8:
4 * lustre/smfs/audit_mds.c
5 * Lustre filesystem audit part for MDS
7 * Copyright (C) 2004 Cluster File Systems, Inc.
9 * This file is part of Lustre, http://www.lustre.org.
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.
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.
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.
25 # define EXPORT_SYMTAB
28 #define DEBUG_SUBSYSTEM S_SM
30 #include <linux/kmod.h>
31 #include <linux/init.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"
43 static inline int audit_fill_id_rec (char **pbuf, struct inode * inode)
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;
51 rec->au_num = inode->i_ino;
52 rec->au_type = (S_IFMT & inode->i_mode);
53 rec->au_gen = inode->i_generation;
56 rc = fsfilt->fs_get_md(I2CI(inode), &fid, sizeof(fid), EA_SID);
58 rec->au_fid = fid.lf_id;
59 rec->au_mds = fid.lf_group;
61 //try to add group at least
62 rec->au_mds = S2SMI(inode->i_sb)->smsi_exp->exp_obd->u.mds.mds_num;
69 int static audit_mds_create_rec(struct inode * parent, void * arg,
70 struct audit_priv * priv, char * buffer,
73 struct hook_msg * msg = arg;
74 struct audit_record * rec = (void*)buffer;
75 char * pbuf = buffer + sizeof(*rec);
76 struct inode * inode = msg->dentry->d_inode;
77 int len = sizeof(*rec);
79 rec->opcode = AUDIT_CREATE;
80 if (priv->result == 0) { //successfull operation
81 len += audit_fill_id_rec(&pbuf, inode);
82 *type = SMFS_AUDIT_GEN_REC;
84 else { //failed operation
85 len += audit_fill_id_rec(&pbuf, parent);
86 len += audit_fill_name_rec(&pbuf, msg->dentry->d_name.name,
87 msg->dentry->d_name.len);
89 *type = SMFS_AUDIT_NAME_REC;
94 int static audit_mds_link_rec(struct inode * parent, void * arg,
95 struct audit_priv * priv, char * buffer,
98 struct hook_link_msg * msg = arg;
99 struct audit_record * rec = (void*)buffer;
100 char * pbuf = buffer + sizeof(*rec);
101 struct inode * inode = msg->dentry->d_inode;
102 int len = sizeof(*rec);
104 rec->opcode = AUDIT_LINK;
106 /* these things will be needed always */
107 len += audit_fill_id_rec(&pbuf, inode);
108 len += audit_fill_id_rec(&pbuf, parent);
109 len += audit_fill_name_rec(&pbuf, msg->dentry->d_name.name,
110 msg->dentry->d_name.len);
111 *type = SMFS_AUDIT_NAME_REC;
116 int static audit_mds_unlink_rec(struct inode * parent, void * arg,
117 struct audit_priv * priv, char * buffer,
120 struct hook_unlink_msg * msg = arg;
121 struct inode * inode = msg->dentry->d_inode;
122 struct audit_record * rec = (void*)buffer;
123 char * pbuf = buffer + sizeof(*rec);
124 int len = sizeof(*rec);
126 rec->opcode = AUDIT_UNLINK;
129 len += audit_fill_id_rec(&pbuf, inode);
130 len += audit_fill_id_rec(&pbuf, parent);
131 if (priv->result == 0) {
132 len += audit_fill_name_rec(&pbuf, msg->dentry->d_name.name,
133 msg->dentry->d_name.len);
134 *type = SMFS_AUDIT_NAME_REC;
136 //in case of failure name shouldn't be saved
137 *type = SMFS_AUDIT_GEN_REC;
143 int static audit_mds_rename_rec(struct inode * parent, void * arg,
144 struct audit_priv * priv, char * buffer,
147 struct hook_rename_msg * msg = arg;
148 struct inode * inode = msg->dentry->d_inode;
149 struct audit_record * rec = (void*)buffer;
150 char * pbuf = buffer + sizeof(*rec);
151 int len = sizeof(*rec);
153 rec->opcode = AUDIT_RENAME;
155 len += audit_fill_id_rec(&pbuf, inode);
156 if (priv->result == 0) {
157 len += audit_fill_id_rec(&pbuf, msg->old_dir);
158 len += audit_fill_name_rec(&pbuf, msg->dentry->d_name.name,
159 msg->dentry->d_name.len);
161 len += audit_fill_id_rec(&pbuf, msg->new_dir);
162 len += audit_fill_name_rec(&pbuf, msg->new_dentry->d_name.name,
163 msg->new_dentry->d_name.len);
166 *type = SMFS_AUDIT_NAME_REC;
172 int static audit_mds_setattr_rec(struct inode * inode, void * arg,
173 struct audit_priv * priv, char * buffer,
176 /*struct hook_attr_msg * msg = arg;*/
177 struct audit_record * rec = (void*)buffer;
178 char * pbuf = buffer + sizeof(*rec);
179 int len = sizeof(*rec);
181 rec->opcode = AUDIT_SETATTR;
182 len += audit_fill_id_rec(&pbuf, inode);
183 *type = SMFS_AUDIT_GEN_REC;
188 int static audit_mds_readlink_rec(struct inode * inode, void * arg,
189 struct audit_priv * priv, char * buffer,
192 //struct hook_symlink_msg * msg = arg;
193 struct audit_record * rec = (void*)buffer;
194 char * pbuf = buffer + sizeof(*rec);
195 int len = sizeof(*rec);
197 rec->opcode = AUDIT_READLINK;
198 len += audit_fill_id_rec(&pbuf, inode);
199 *type = SMFS_AUDIT_GEN_REC;
204 int static audit_mds_readdir_rec(struct inode * inode, void * arg,
205 struct audit_priv * priv, char * buffer,
208 struct audit_record * rec = (void*)buffer;
209 char * pbuf = buffer + sizeof(*rec);
210 int len = sizeof(*rec);
212 rec->opcode = AUDIT_READDIR;
213 len += audit_fill_id_rec(&pbuf, inode);
214 *type = SMFS_AUDIT_GEN_REC;
219 /* for special records from failed auth and open/stat*/
220 int audit_mds_special_rec(struct inode * inode, void * arg,
221 struct audit_priv * priv, char *buffer,
224 struct audit_info * info = arg;
225 struct audit_msg * msg = &info->m;
226 struct audit_record * rec = (void*)buffer;
227 char * pbuf = buffer + sizeof(*rec);
228 int len = sizeof(*rec);
230 //rewrite some fields
231 rec->opcode = msg->code;
232 rec->result = msg->result;
237 /* check id is valid */
238 LASSERT(id_ino(&msg->id));
239 LASSERT(id_fid(&msg->id));
240 // LASSERT(id_type(&msg->id) & S_IFMT);
242 len += audit_rec_from_id(&pbuf, &msg->id);
248 if (info->name && info->namelen > 0) {
249 len += audit_fill_name_rec(&pbuf,
252 *type = SMFS_AUDIT_NAME_REC;
256 *type = SMFS_AUDIT_GEN_REC;
262 static audit_get_op audit_mds_record[HOOK_MAX] = {
263 [HOOK_CREATE] audit_mds_create_rec,
264 [HOOK_LINK] audit_mds_link_rec,
265 [HOOK_UNLINK] audit_mds_unlink_rec,
266 [HOOK_SYMLINK] audit_mds_create_rec,
267 [HOOK_READLINK] audit_mds_readlink_rec,
268 [HOOK_MKDIR] audit_mds_create_rec,
269 [HOOK_RMDIR] audit_mds_unlink_rec,
270 [HOOK_MKNOD] audit_mds_create_rec,
271 [HOOK_RENAME] audit_mds_rename_rec,
272 [HOOK_SETATTR] audit_mds_setattr_rec,
273 [HOOK_F_SETATTR] audit_mds_setattr_rec,
274 [HOOK_SPECIAL] audit_mds_special_rec,
275 [HOOK_READDIR] audit_mds_readdir_rec,
278 int audit_mds_setup(struct obd_device * obd, struct super_block *sb,
279 struct audit_priv *priv)
282 struct smfs_super_info * smb = S2SMI(sb);
283 struct llog_ctxt **ctxt = &priv->audit_ctxt;
285 //this will do OBD_ALLOC() for ctxt
286 rc = llog_catalog_setup(ctxt, AUDIT_MDS_NAME, smb->smsi_exp,
287 smb->smsi_ctxt, smb->sm_fsfilt,
288 smb->smsi_logs_dir, smb->smsi_objects_dir);
290 /* export audit llog ctxt */
292 (*ctxt)->loc_idx = LLOG_AUDIT_ORIG_CTXT;
293 (*ctxt)->loc_obd = obd;
294 (*ctxt)->loc_llogs = &obd->obd_llogs;
295 (*ctxt)->loc_llogs->llog_ctxt[LLOG_AUDIT_ORIG_CTXT] = *ctxt;
297 priv->audit_get_record = &audit_mds_record;