]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
nfs4: log remove procedure + add multi-proc support
authorVictor Julien <victor@inliniac.net>
Sat, 21 Jul 2018 16:13:32 +0000 (18:13 +0200)
committerVictor Julien <victor@inliniac.net>
Mon, 23 Jul 2018 17:56:08 +0000 (19:56 +0200)
Add TX creation for NFS4 transactions. Start with the 'REMOVE' procedure.

Start on logging all procs. In NFS4 COMPOUND records there are multiple
procedures. One of them can be considered the 'main' procedure, with others
as supporting utility. This patch adds the first step in supporting to
track those in the TX for logging and inspection.

rust/src/nfs/nfs4.rs

index f3a9a75212d7585adfdb453caba0d7e3f09a51a3..14b1f8a3bd482c9fd788ba9b0c39675c57369347 100644 (file)
@@ -123,6 +123,32 @@ impl NFSState {
         }
     }
 
+    fn new_tx_v4<'b>(&mut self, r: &RpcPacket<'b>,
+            xidmap: &NFSRequestXidMap, procedure: u32,
+            _aux_opcodes: &Vec<u32>)
+    {
+        let mut tx = self.new_tx();
+        tx.xid = r.hdr.xid;
+        tx.procedure = procedure;
+        tx.request_done = true;
+        tx.file_name = xidmap.file_name.to_vec();
+        tx.nfs_version = r.progver as u16;
+        tx.file_handle = xidmap.file_handle.to_vec();
+
+        tx.auth_type = r.creds_flavor;
+        match r.creds {
+            RpcRequestCreds::Unix(ref u) => {
+                tx.request_machine_name = u.machine_name_buf.to_vec();
+                tx.request_uid = u.uid;
+                tx.request_gid = u.gid;
+            },
+            _ => { },
+        }
+        SCLogDebug!("NFSv4: TX created: ID {} XID {} PROCEDURE {}",
+                tx.id, tx.xid, tx.procedure);
+        self.transactions.push(tx);
+    }
+
     /* A normal READ request looks like: PUTFH (file handle) READ (read opts).
      * We need the file handle for the READ.
      */
@@ -131,12 +157,15 @@ impl NFSState {
             xidmap: &mut NFSRequestXidMap)
     {
         let mut last_putfh : Option<&'b[u8]> = None;
+        let mut main_opcode : u32 = 0;
+        let mut aux_opcodes : Vec<u32> = Vec::new();
 
         for c in &cr.commands {
             SCLogDebug!("c {:?}", c);
             match c {
                 &Nfs4RequestContent::PutFH(ref rd) => {
                     last_putfh = Some(rd.value);
+                    aux_opcodes.push(NFSPROC4_PUTFH);
                 }
                 &Nfs4RequestContent::Read(ref rd) => {
                     SCLogDebug!("READv4: {:?}", rd);
@@ -169,6 +198,11 @@ impl NFSState {
                 &Nfs4RequestContent::Close(ref rd) => {
                     SCLogDebug!("CLOSEv4: {:?}", rd);
                 }
+                &Nfs4RequestContent::Remove(ref rd) => {
+                    SCLogDebug!("REMOVEv4: {:?}", rd);
+                    xidmap.file_name = rd.to_vec();
+                    main_opcode = NFSPROC4_REMOVE;
+                }
                 &Nfs4RequestContent::SetClientId(ref rd) => {
                     SCLogDebug!("SETCLIENTIDv4: client id {} r_netid {} r_addr {}",
                             String::from_utf8_lossy(&rd.client_id),
@@ -178,6 +212,10 @@ impl NFSState {
                 &_ => { },
             }
         }
+
+        if main_opcode != 0 {
+            self.new_tx_v4(r, &xidmap, main_opcode, &aux_opcodes);
+        }
     }
 
     /// complete request record
@@ -247,6 +285,8 @@ impl NFSState {
             xidmap: &mut NFSRequestXidMap)
     {
         let mut insert_filename_with_getfh = false;
+        let mut main_opcode_status : u32 = 0;
+        let mut main_opcode_status_set : bool = false;
 
         for c in &cr.commands {
             SCLogDebug!("c {:?}", c);
@@ -265,6 +305,8 @@ impl NFSState {
                 }
                 &Nfs4ResponseContent::Remove(s) => {
                     SCLogDebug!("REMOVE4: status {}", s);
+                    main_opcode_status = s;
+                    main_opcode_status_set = true;
                 },
                 &Nfs4ResponseContent::Read(s, ref rd) => {
                     if let &Some(ref rd) = rd {
@@ -305,6 +347,11 @@ impl NFSState {
                 &_ => { },
             }
         }
+
+        if main_opcode_status_set {
+            let resp_handle = Vec::new();
+            self.mark_response_tx_done(r.hdr.xid, r.reply_state, main_opcode_status, &resp_handle);
+        }
     }
 
     pub fn process_reply_record_v4<'b>(&mut self, r: &RpcReplyPacket<'b>,