Whamcloud - gitweb
b=8654
[fs/lustre-release.git] / lustre / mds / mds_audit.c
index 71d1697..08c54b4 100644 (file)
 #include <linux/lprocfs_status.h>
 #include <linux/lustre_commit_confd.h>
 #include <linux/lustre_acl.h>
-#include <linux/lustre_audit.h>
 #include "mds_internal.h"
 
-int mds_audit_stat(struct ptlrpc_request *req, struct lustre_id * id,
-                   struct dentry * dentry, int ret)
+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;
-        struct inode * inode = dentry->d_inode;
         ptl_nid_t nid = req->rq_peer.peer_id.nid;
-        struct audit_info info;
-        int rc = 0, len = sizeof(info);
+        struct inode *inode = dentry->d_inode;
+        struct inode *parent = dentry->d_parent->d_inode;
+        struct audit_info info = {
+                .child = inode,
+                .name = NULL,
+                .namelen = 0,
+        };
+        int rc = 0;
         ENTRY;
         
-        LASSERT(inode);
-        LASSERT(id);
-        memcpy(&info.m.id, id, sizeof(*id));
+        /* don't catch request to cross-ref */
+        if (dentry->d_flags & DCACHE_CROSS_REF)
+                RETURN(0);
+        
         info.m.nid = nid;
         info.m.uid = current->uid;
         info.m.gid = current->gid;
         info.m.result = ret;
-        info.m.code = AUDIT_STAT;
-   
-        //send info to local fs
-        fsfilt_set_info(obd, inode->i_sb, inode,
-                        10, "audit_info", len, (void*)&info);
-
-        RETURN(rc);
-}
-
-int mds_audit_open(struct ptlrpc_request *req, struct mds_update_record * rec,
-                   int ret)
-{
-        struct obd_device *obd = req->rq_export->exp_obd;
-        struct inode * inode = NULL;
-        ptl_nid_t nid = req->rq_peer.peer_id.nid;
-        struct audit_info info;
-        int rc = 0, len = sizeof(info);
-        
-        struct dentry * dparent = NULL;
+        info.m.code = op;
         
-        dparent = mds_id2dentry(obd, rec->ur_id1, NULL);
-        if (IS_ERR(dparent)) {
-                rc = PTR_ERR(dparent);
-                RETURN(rc);
+        if (!inode) {
+                inode = parent;
+                info.name = name;
+                info.namelen = namelen;
         }
-        inode = dparent->d_inode;
-        
-        info.m.id = *(rec->ur_id1);
-        info.m.nid = nid;
-        info.m.uid = rec->ur_uc.luc_uid;
-        info.m.gid = rec->ur_uc.luc_gid;
-        info.m.result = ret;
-        info.m.code = AUDIT_OPEN;
-        info.name = rec->ur_name;
-        info.namelen = rec->ur_namelen;
+        mds_pack_inode2id(obd, &info.m.id, inode, 1);
+                
+        fsfilt_set_info(obd, parent->i_sb, parent,
+                        10, "audit_info", sizeof(info), (void*)&info);
         
-        //send info to local fs
-        fsfilt_set_info(obd, inode->i_sb, inode,
-                        10, "audit_info", len, (void*)&info);
-
-        l_dput(dparent);
-
         RETURN(rc);
 }
 
@@ -124,34 +99,83 @@ int mds_audit_auth(struct ptlrpc_request *req, struct lvfs_ucred * uc,
         struct obd_device *obd = req->rq_export->exp_obd;
         ptl_nid_t nid = req->rq_peer.peer_id.nid;
         int rc = 0;
-        struct dentry * dparent;
+        struct dentry * dparent, *dchild = NULL;
         struct inode * inode;
         struct audit_info info;
         
         ENTRY;
         
         dparent = mds_id2dentry(obd, id, NULL);
-        if (IS_ERR(dparent)) {
-                rc = PTR_ERR(dparent);
-                GOTO(out, rc);
+        if (IS_ERR(dparent) || !dparent->d_inode) {
+                CERROR("can't find inode "LPU64"\n", id_ino(id));
+                if (!IS_ERR(dparent))
+                        l_dput(dparent);
+                RETURN(-ENOENT);
         }
         inode = dparent->d_inode;
         
         info.m.nid = nid;
         info.m.uid = uc->luc_uid;
         info.m.gid = uc->luc_gid;
-        info.m.id = (*id);
         info.m.result = -EPERM;
         info.m.code = op;
         info.name = name;
         info.namelen = namelen;
+
+        if (name && namelen > 0) {
+                dchild = ll_lookup_one_len(name, dparent, namelen);
+                if (!IS_ERR(dchild)) {
+                        if (!dchild->d_flags & DCACHE_CROSS_REF) {
+                                inode = dchild->d_inode;
+                                info.name = NULL;
+                                info.namelen = 0;
+                        }
+                }
+        }
+        
+        mds_pack_inode2id(obd, &info.m.id, inode, 1);
         
         fsfilt_set_info(obd, inode->i_sb, inode,
                         10, "audit_info", sizeof(info), &info);
         l_dput(dparent);
 
         EXIT;
- out:
+
+        return rc;
+}
+
+int mds_audit_reint(struct ptlrpc_request *req,
+                    struct mds_update_record *rec)
+{
+        audit_op code = AUDIT_UNKNOWN;
+        int rc = 0;
+        
+        switch (rec->ur_opcode) {
+                case REINT_SETATTR:
+                        code = AUDIT_SETATTR;
+                        break;
+                case REINT_CREATE:
+                        code = AUDIT_CREATE;
+                        break;
+                case REINT_LINK:
+                        code = AUDIT_LINK;
+                        break;
+                case REINT_UNLINK:
+                        code = AUDIT_UNLINK;
+                        break;
+                case REINT_RENAME:                        
+                        code = AUDIT_RENAME;
+                        break;
+                case REINT_OPEN:
+                        code = AUDIT_OPEN;
+                        break;
+                default:
+                        CERROR("Wrong opcode in reint\n");
+                        LBUG();
+        }
+        
+        rc = mds_audit_auth(req, &rec->ur_uc, code, rec->ur_id1,  
+                            rec->ur_name, rec->ur_namelen - 1);
         return rc;
 }
 
@@ -166,6 +190,7 @@ static int mds_set_obj_audit(struct obd_device * obd, struct inode * inode,
         };
         int len, rc = 0;
         void *lmm = NULL;
+        ENTRY;
         
         down(&inode->i_sem);
         len = fsfilt_get_md(obd, inode, NULL, 0, EA_LOV);
@@ -223,21 +248,23 @@ int mds_set_audit(struct obd_device * obd, void * val)
         ENTRY;
         
         //push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
-
-        dentry = mds_id2dentry(obd, &msg->id, NULL);
-        if (IS_ERR(dentry)) {
-                CERROR("Cannot get dentry\n");
-                RETURN(PTR_ERR(dentry));
+        if (IS_AUDIT_OP(msg->attr, AUDIT_FS) == 0) {
+                dentry = mds_id2dentry(obd, &msg->id, NULL);
+                if (IS_ERR(dentry)) {
+                        CERROR("Cannot get dentry "DLID4" err=%li\n", OLID4(&msg->id),
+                                PTR_ERR(dentry));
+                        RETURN(PTR_ERR(dentry));
+                }
+                inode = dentry->d_inode;
         }
-            
-        inode = dentry->d_inode;
-        fsfilt_set_info(obd, inode->i_sb, inode,
+        fsfilt_set_info(obd, obd->u.mds.mds_sb, inode,
                         5, "audit", sizeof(msg->attr), &msg->attr);
         
-        if (S_ISREG(inode->i_mode) && !IS_AUDIT_OP(msg->attr, AUDIT_FS))
+        if (inode && S_ISREG(inode->i_mode))
                 mds_set_obj_audit(obd, inode, &msg->attr);
         
-        l_dput(dentry);
+        if (dentry)
+                l_dput(dentry);
         
         //pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);