struct audit_info {
struct audit_msg m;
+ struct inode * child;
char * name;
__u32 namelen;
};
GOTO(cleanup, rc);
cleanup:
- /* audit stuff for getattr */
- if (resent_req == 0 && (dparent || dchild)) {
- struct inode * au_inode = NULL;
-
- if (dchild && dchild->d_inode) {
- au_inode = dchild->d_inode;
- mds_audit_stat(req, &body->id1, au_inode,
- NULL, 0, rc);
- } else {
- au_inode = dparent->d_inode;
- mds_audit_stat(req, &body->id1, au_inode,
- name, namesize - 1, rc);
- }
- }
switch (cleanup_phase) {
case 2:
if (resent_req == 0) {
+ mds_audit(req, dchild, name, namesize - 1,
+ AUDIT_STAT, rc);
if (rc && DENTRY_VALID(dchild))
ldlm_lock_decref(child_lockh, LCK_PR);
if (name)
#include <linux/lustre_acl.h>
#include "mds_internal.h"
-int mds_audit_stat(struct ptlrpc_request *req, struct lustre_id * id,
- struct inode *inode, char *name, int namelen, int ret)
-{
- struct obd_device *obd = req->rq_export->exp_obd;
- ptl_nid_t nid = req->rq_peer.peer_id.nid;
- struct audit_info info = {
- .name = NULL,
- .namelen = 0,
- };
- int rc = 0, len = sizeof(info);
-
- ENTRY;
-
- LASSERT(inode);
- LASSERT(id);
- info.m.id = *id;
- info.m.nid = nid;
- info.m.uid = current->uid;
- info.m.gid = current->gid;
- info.m.result = ret;
- info.m.code = AUDIT_STAT;
- if (ret) {
- info.name = name;
- info.namelen = namelen;
- }
- // send info to local fs
- fsfilt_set_info(obd, inode->i_sb, inode,
- 10, "audit_info", len, (void*)&info);
-
- RETURN(rc);
-}
-
-int mds_audit_perm(struct ptlrpc_request *req, struct inode *inode, audit_op op)
+int mds_audit(struct ptlrpc_request *req, struct dentry *dentry,
+ char *name, int namelen, audit_op op, int ret)
{
struct obd_device *obd = req->rq_export->exp_obd;
ptl_nid_t nid = req->rq_peer.peer_id.nid;
+ struct inode *inode = dentry->d_inode;
+ struct inode *parent = dentry->d_parent->d_inode;
struct audit_info info = {
+ .child = inode,
.name = NULL,
.namelen = 0,
};
ENTRY;
- LASSERT(inode);
info.m.nid = nid;
info.m.uid = current->uid;
info.m.gid = current->gid;
- info.m.result = -EACCES;
+ info.m.result = ret;
info.m.code = op;
- /* failed access, log child id only */
- mds_pack_inode2id(obd, &info.m.id, inode, 1);
-
- fsfilt_set_info(obd, inode->i_sb, inode,
- 10, "audit_info", sizeof(info), (void*)&info);
-
- RETURN(rc);
-}
-
-int mds_audit_open(struct ptlrpc_request *req, struct lustre_id * id,
- struct inode *inode, char *name, int namelen, int ret)
-{
- struct obd_device *obd = req->rq_export->exp_obd;
- ptl_nid_t nid = req->rq_peer.peer_id.nid;
- struct audit_info info = {
- .name = NULL,
- .namelen = 0,
- };
- int rc = 0, len = sizeof(info);
-
- ENTRY;
-
- LASSERT(inode);
- info.m.id = (*id);
- info.m.nid = nid;
- info.m.uid = current->uid;
- info.m.gid = current->gid;
- info.m.result = ret;
- info.m.code = AUDIT_OPEN;
- if (ret) {
+ if (!inode) {
+ inode = parent;
info.name = name;
info.namelen = namelen;
}
-
- fsfilt_set_info(obd, inode->i_sb, inode,
- 10, "audit_info", len, (void*)&info);
+ mds_pack_inode2id(obd, &info.m.id, inode, 1);
+
+ fsfilt_set_info(obd, parent->i_sb, parent,
+ 10, "audit_info", sizeof(info), (void*)&info);
RETURN(rc);
}
if (name && namelen > 0) {
dchild = ll_lookup_one_len(name, dparent, namelen);
if (!IS_ERR(dchild)) {
- if (dchild->d_flags & DCACHE_CROSS_REF) {
- //TODO: we should know audit setting for this
- //so remote call is needed
- } else {
+ if (!dchild->d_flags & DCACHE_CROSS_REF) {
inode = dchild->d_inode;
info.name = NULL;
info.namelen = 0;
int mds_audit_open(struct ptlrpc_request *, struct lustre_id *,
struct inode *, char*, int, int);
int mds_audit_reint(struct ptlrpc_request *, struct mds_update_record *);
-int mds_audit_perm(struct ptlrpc_request *, struct inode *, audit_op);
+int mds_audit(struct ptlrpc_request *, struct dentry *, char *,
+ int, audit_op, int);
/* mds_acl.c */
struct upcall_cache *__mds_get_global_rmtacl_upcall_cache(void);
int mds_init_rmtacl_upcall_cache(void);
mds_lock_new_child(obd, dchild->d_inode, NULL);
}
/* audit stuff for OPEN */
- if (offset == 3 && (dchild->d_inode || dparent)) {
- struct lustre_id au_id;
- struct inode * au_inode = dchild->d_inode;
-
- if (au_inode == NULL) {
- au_inode = dparent->d_inode;
- au_id = *(rec->ur_id1);
- mds_audit_open(req, &au_id, au_inode,
- rec->ur_name, rec->ur_namelen - 1,
- rc);
- } else {
- if (fid == 0)
- mds_read_inode_sid(obd, au_inode, &au_id);
- else
- mds_inode2id(obd, &au_id, au_inode, fid);
- mds_audit_open(req, &au_id, au_inode,
- NULL, 0, rc);
- }
+ if (offset == 3) {
+ mds_audit(req, dchild, rec->ur_name,
+ rec->ur_namelen - 1, AUDIT_OPEN, rc);
}
l_dput(dchild);
switch (cleanup_phase) {
case 2: /* child dentry */
if (rc == -EACCES)
- mds_audit_perm(req, dchild->d_inode, AUDIT_CREATE);
+ mds_audit(req, dchild, rec->ur_name,
+ rec->ur_namelen - 1, AUDIT_CREATE, rc);
l_dput(dchild);
case 1: /* locked parent dentry */
#ifdef S_PDIROPS
/* catching failed permissions check for audit */
if (rc == -EACCES)
- mds_audit_perm(req, dchild->d_inode, AUDIT_UNLINK);
+ mds_audit(req, dchild, NULL, 0, AUDIT_UNLINK, rc);
l_dput(dchild);
l_dput(dchild);
struct smfs_inode_info * smi = I2SMI(inode);
int rc = 0;
+ /* omit __iopen__ dir */
+ if (inode->i_ino == SMFS_IOPEN_INO) {
+ *mask = AUDIT_OFF;
+ RETURN(-ENOENT);
+ }
if (smi->au_info.au_valid)
*mask = smi->au_info.au_mask;
else {
- rc = fsfilt->fs_get_xattr(I2CI(inode), AUDIT_ATTR_EA, mask, sizeof(*mask));
+ rc = fsfilt->fs_get_xattr(I2CI(inode), AUDIT_ATTR_EA,
+ mask, sizeof(*mask));
if (rc <= 0)
*mask = AUDIT_OFF;
smi->au_info.au_valid = 1;
smi->au_info.au_mask = *mask;
}
- return 0;
+ RETURN(0);
}
/* is called also from fsfilt_smfs_get_info */
priv = smfs_get_plg_priv(S2SMI(sb), SMFS_PLG_AUDIT);
- /* omit __iopen__ dir */
- if (parent->i_ino == SMFS_IOPEN_INO)
- RETURN(-ENOENT);
-
if (!priv)
RETURN(-ENOENT);
(*mask) = priv->a_mask;
RETURN(0);
}
- /* get inode audit EA */
- smfs_get_inode_audit(parent, mask);
- /* check if parent has audit */
- if (IS_AUDIT(*mask))
- RETURN(0);
- if (!inode)
- RETURN(-ENOENT);
+ /* get inode audit EA */
+ if (parent) {
+ smfs_get_inode_audit(parent, mask);
+ /* check if parent has audit */
+ if (IS_AUDIT(*mask))
+ RETURN(0);
+ }
- smfs_get_inode_audit(inode, mask);
- if (IS_AUDIT(*mask))
- RETURN(0);
+ if (inode) {
+ smfs_get_inode_audit(inode, mask);
+ if (IS_AUDIT(*mask))
+ RETURN(0);
+ }
RETURN(-ENODATA);
}
struct audit_priv * priv, void * msg)
{
audit_op code;
+ struct inode * inode = NULL;
__u64 mask = 0;
int rc = 0;
if (hook == HOOK_SPECIAL) {
struct audit_info * info = msg;
code = info->m.code;
+ inode = info->child;
}
- else
+ else {
+ inode = get_inode_from_hook(hook, msg);
code = hook2audit(hook);
-
- rc = smfs_get_audit(parent->i_sb, parent,
- get_inode_from_hook(hook, msg),
- &mask);
+ }
+
+ rc = smfs_get_audit(parent->i_sb, parent, inode, &mask);
+
if (rc < 0)
RETURN(0);
+
//should only failures be audited?
if (ret >= 0 && IS_AUDIT_OP(mask, AUDIT_FAIL))
RETURN(0);
LASSERT(inode);
smi = I2SMI(inode);
+ /* save audit EA in inode_info */
+ if (rc >= 0) {
+ smi->au_info.au_mask = *mask;
+ smi->au_info.au_valid = 1;
+ }
+
handle = fsfilt->fs_start(inode, FSFILT_OP_SETATTR, NULL, 0);
if (IS_ERR(handle))
RETURN(PTR_ERR(handle));
if (fsfilt->fs_set_xattr)
rc = fsfilt->fs_set_xattr(inode, handle, AUDIT_ATTR_EA,
mask, sizeof(*mask));
- /* save audit EA in inode_info */
- if (rc >= 0) {
- smi->au_info.au_mask = *mask;
- smi->au_info.au_valid = 1;
- }
-
fsfilt->fs_commit(inode->i_sb, inode, handle, 1);
RETURN(rc);
else {
//if dir then set audit for childs also
if (S_ISDIR(st.st_mode)) {
- rc = set_dir_audit(argv[3], mask);
+ //rc = set_dir_audit(argv[3], mask | AUD_BIT(AUDIT_DIR));
}
}
//set audit for file/dir itself