systemd_run/
identity.rs

1use zbus::zvariant::Value;
2
3enum IdentityInner {
4    Session,
5    UserGroup(String, String),
6    #[allow(dead_code)]
7    Dynamic,
8}
9
10/// The identity for running a transient service on the system service
11/// manager.
12pub struct Identity(IdentityInner);
13
14impl Identity {
15    /// Run the transient service as the the UNIX user `x` and group `y`
16    /// for `UserGroup(x, y)`.
17    ///
18    /// You need to be the `root` user to start a transient service with
19    /// this.  Read `User=` and `Group=` in
20    /// [`systemd.exec(5)`](man:systemd.exec(5)) for details.
21    pub fn user_group<U: AsRef<str>, G: AsRef<str>>(u: U, g: G) -> Self {
22        Self(IdentityInner::UserGroup(
23            u.as_ref().to_owned(),
24            g.as_ref().to_owned(),
25        ))
26    }
27
28    /// Run the transient service as a UNIX user and group pair dynamically
29    /// allocated.
30    ///
31    /// This is unavailable if the feature `systemd_231` is disabled.
32    ///
33    /// You need to be the `root` user to start a transient service with
34    /// this.  Read `DynamicUser=` in
35    /// [`systemd.exec(5)`](man:systemd.exec(5)) for details.
36    #[cfg(feature = "systemd_231")]
37    pub fn dynamic() -> Self {
38        Self(IdentityInner::Dynamic)
39    }
40
41    /// Shorthand for `Self::user_group(u, u)`.
42    pub fn user<T: AsRef<str>>(u: T) -> Self {
43        Self::user_group(u.as_ref(), u.as_ref())
44    }
45
46    /// Shorthand for `Self::user("root")`.
47    pub fn root() -> Self {
48        Self::user("root")
49    }
50}
51
52pub fn session() -> Identity {
53    Identity(IdentityInner::Session)
54}
55
56pub fn is_session(i: &Identity) -> bool {
57    matches!(i, Identity(IdentityInner::Session))
58}
59
60pub fn unit_properties(i: &Identity) -> Vec<(&'static str, Value)> {
61    match i {
62        Identity(IdentityInner::Session) => vec![],
63        Identity(IdentityInner::UserGroup(u, g)) => vec![
64            ("User", Value::from(u.clone())),
65            ("Group", Value::from(g.clone())),
66        ],
67        Identity(IdentityInner::Dynamic) => vec![("DynamicUser", Value::from(true))],
68    }
69}