Skip to content

Commit 705100d

Browse files
vthibcathay4t
authored andcommitted
feat: add set_enabled and set_pid helpers
The `enable_events` is convenient for a process that enables the audit daemon once. However, when there is a need to disable/enable at will, it does not work well. For example, take something like this: ``` let (connection, handle, receiver) = new_connection().unwrap(); tokio::task::spawn(connection); // Works well handle.enable_events().await.unwrap(); ... // Now disable audit: drop((handle, receiver)); // Now we want to re-enable audit: let (connection, handle, receiver) = new_connection().unwrap(); tokio::task::spawn(connection); // This fails on errno: -17, ie EEXIST handle.enable_events().await.unwrap(); ``` The reason this fails is because, while the drop did disable audit, the pid is still set. The second call to enable_events thus fails because the "AUDIT_SET_PID" call returns EEXIST (pid is already set to this exact pid). Now, it could be possible to handle the EEXIST error on `enable_events` and consider that this is OK. However, it's not necessarily clear on which parameter this error is returned (the SET_PID or the SET_ENABLED). In addition, there is still the issue that we disabled audit, while letting the pid set, which is a bit ugly. By adding the two lower levels helpers (set_enabled, set_pid), it is possible to do things more cleanly: ``` let (connection, handle, receiver) = new_connection().unwrap(); tokio::task::spawn(connection); // Works well handle.set_pid(std::process::id()).await.unwrap(); handle.set_enabled(true).await.unwrap(); // Now disable audit: handle.set_pid(0).await.unwrap(); handle.set_enabled(false).await.unwrap(); drop((handle, receiver)); // Now we want to re-enable audit: let (connection, handle, receiver) = new_connection().unwrap(); tokio::task::spawn(connection); // Works well handle.set_pid(std::process::id()).await.unwrap(); handle.set_enabled(true).await.unwrap(); ```
1 parent f76c719 commit 705100d

File tree

1 file changed

+40
-1
lines changed

1 file changed

+40
-1
lines changed

src/handle.rs

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,14 @@ impl Handle {
126126
}
127127
}
128128

129-
/// Enable receiving audit events
129+
/// Enable receiving events in this process.
130+
///
131+
/// This function enable events and set the PID in a single message.
132+
///
133+
/// This works well if done once in the process life. If however you need to
134+
/// disable and enable events, you will want to call the
135+
/// `Handle::set_enabled` and `Handle::set_pid` directly, so as to
136+
/// handle the errors in a more granular manner.
130137
pub async fn enable_events(&mut self) -> Result<(), Error> {
131138
let mut status = StatusMessage::new();
132139
status.enabled = 1;
@@ -137,6 +144,38 @@ impl Handle {
137144
self.acked_request(req).await
138145
}
139146

147+
/// Set whether to enable the audit daemon or not.
148+
///
149+
/// When enabling the audit daemon with this function, you should ensure
150+
/// that you set the PID of the current process already with a call to
151+
/// `Handle::set_pid`.
152+
///
153+
/// See `Handle::enable_events` for a more convenient helper to enable
154+
/// events in a single call.
155+
pub async fn set_enabled(&mut self, value: bool) -> Result<(), Error> {
156+
let mut status = StatusMessage::new();
157+
status.enabled = if value { 1 } else { 0 };
158+
status.mask = AUDIT_STATUS_ENABLED;
159+
let mut req = NetlinkMessage::from(AuditMessage::SetStatus(status));
160+
req.header.flags = NLM_F_REQUEST | NLM_F_ACK;
161+
self.acked_request(req).await
162+
}
163+
164+
/// Set the PID to which audit messages should be addressed.
165+
///
166+
/// You probably want to use either:
167+
/// - Your own pid, to receive audit events
168+
/// - 0, to unset the PID restriction, for example when disabling the audit
169+
/// connection.
170+
pub async fn set_pid(&mut self, pid: u32) -> Result<(), Error> {
171+
let mut status = StatusMessage::new();
172+
status.pid = pid;
173+
status.mask = AUDIT_STATUS_PID;
174+
let mut req = NetlinkMessage::from(AuditMessage::SetStatus(status));
175+
req.header.flags = NLM_F_REQUEST | NLM_F_ACK;
176+
self.acked_request(req).await
177+
}
178+
140179
/// Get current audit status
141180
pub async fn get_status(&mut self) -> Result<StatusMessage, Error> {
142181
let mut req = NetlinkMessage::from(AuditMessage::GetStatus(None));

0 commit comments

Comments
 (0)