diff --git a/Cargo.lock b/Cargo.lock
index 0537202..46d208c 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -142,6 +142,15 @@ version = "1.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b35204fbdc0b3f4446b89fc1ac2cf84a8a68971995d0bf2e925ec7cd960f9cb3"
+[[package]]
+name = "caps"
+version = "0.5.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fd1ddba47aba30b6a889298ad0109c3b8dcb0e8fc993b459daa7067d46f865e0"
+dependencies = [
+ "libc",
+]
+
[[package]]
name = "cc"
version = "1.2.52"
@@ -858,6 +867,7 @@ version = "0.1.0"
dependencies = [
"anyhow",
"bytes",
+ "caps",
"chrono",
"clap",
"clap_complete",
diff --git a/Cargo.toml b/Cargo.toml
index 762f05f..bf6c46e 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -35,6 +35,7 @@ zlink = { version = "0.3.0", features = ["introspection"] }
clap_complete = "4.5.65"
itertools = "0.14.0"
tokio-util = "0.7.18"
+caps = "0.5.6"
[features]
default = ["systemd"]
diff --git a/nix/module.nix b/nix/module.nix
index 74143b1..14f5d59 100644
--- a/nix/module.nix
+++ b/nix/module.nix
@@ -112,6 +112,7 @@ in {
"/etc"
# NOTE: need logind socket for utmp entries
"/run/systemd"
+ "/home"
];
UMask = "0077";
diff --git a/src/proto/finger_protocol.rs b/src/proto/finger_protocol.rs
index 7fcb13d..a0a8358 100644
--- a/src/proto/finger_protocol.rs
+++ b/src/proto/finger_protocol.rs
@@ -587,13 +587,7 @@ impl FingerResponseUserSession {
let messages_on = !line.ends_with("(messages off)");
- Ok(Self {
- tty,
- login_time,
- idle_time,
- host,
- messages_on,
- })
+ Ok(Self::new(tty, login_time, idle_time, host, messages_on))
}
}
diff --git a/src/server/fingerd.rs b/src/server/fingerd.rs
index dbab847..2131e0e 100644
--- a/src/server/fingerd.rs
+++ b/src/server/fingerd.rs
@@ -1,4 +1,8 @@
-use std::{net::hostname, path::Path};
+use std::{
+ net::hostname,
+ os::unix::fs::{MetadataExt, PermissionsExt},
+ path::Path,
+};
use chrono::{DateTime, Duration, Timelike, Utc};
use nix::sys::stat::stat;
@@ -6,6 +10,28 @@ use uucore::utmpx::Utmpx;
use crate::proto::finger_protocol::{FingerResponseUserEntry, FingerResponseUserSession};
+fn read_file_content_if_exists(path: &Path) -> anyhow::Result