clap_permission_flag/
lib.rs

1#![deny(missing_docs)]
2#![doc = include_str!("../README.md")]
3#![cfg_attr(test, deny(warnings))]
4
5use clap::Parser;
6
7#[cfg(unix)]
8extern crate privdrop;
9
10use std::ffi::OsString;
11#[cfg(feature = "chroot")]
12use std::path::PathBuf;
13
14/// Error type for this crate
15#[derive(Debug, thiserror::Error)]
16pub enum Error {
17    /// Error variant if privileges could not be dropped
18    #[cfg(unix)]
19    #[error("Privileges could not be dropped")]
20    PrivDrop(#[from] privdrop::PrivDropError),
21}
22
23#[cfg(unix)]
24mod supported {
25    use super::*;
26
27    /// Drop permissions of a CLI using clap.
28    #[derive(Parser, Debug)]
29    pub struct Permission {
30        /// Change the process user
31        #[clap(short = 'u', long = "user", value_parser)]
32        user: Option<OsString>,
33        /// Change the process group
34        #[clap(short = 'g', long = "group", value_parser)]
35        group: Option<OsString>,
36        /// Change the process root directory
37        #[cfg(feature = "chroot")]
38        #[clap(long = "chroot", value_parser)]
39        chroot: Option<PathBuf>,
40    }
41
42    impl Permission {
43        /// Drop privileges.
44        pub fn drop(self) -> Result<(), Error> {
45            let mut drop = privdrop::PrivDrop::default();
46
47            if let Some(user) = self.user {
48                drop = drop.user(&user);
49            }
50
51            if let Some(group) = self.group {
52                drop = drop.group(&group);
53            }
54
55            #[cfg(feature = "chroot")]
56            {
57                if let Some(chroot) = self.chroot {
58                    drop = drop.chroot(&chroot);
59                }
60            }
61
62            drop.apply()?;
63            Ok(())
64        }
65
66        /// Get the user.
67        pub fn user(&self) -> &Option<OsString> {
68            &self.user
69        }
70
71        /// Get the group.
72        pub fn group(&self) -> &Option<OsString> {
73            &self.group
74        }
75
76        /// Get the chroot directory.
77        #[cfg(feature = "chroot")]
78        pub fn chroot(&self) -> &Option<PathBuf> {
79            &self.chroot
80        }
81    }
82}
83
84#[cfg(not(unix))]
85mod stub {
86    use super::*;
87
88    /// Drop permissions of a CLI using clap.
89    #[derive(Parser, Debug)]
90    pub struct Permission {}
91
92    impl Permission {
93        /// Drop privileges.
94        pub fn drop(self) -> Result<(), Error> {
95            Ok(())
96        }
97
98        /// Get the user.
99        pub fn user(&self) -> &Option<OsString> {
100            &None
101        }
102
103        /// Get the group.
104        pub fn group(&self) -> &Option<OsString> {
105            &None
106        }
107
108        /// Get the chroot directory.
109        #[cfg(feature = "chroot")]
110        pub fn chroot(&self) -> &Option<PathBuf> {
111            &None
112        }
113    }
114}
115
116#[cfg(unix)]
117pub use supported::*;
118
119#[cfg(not(unix))]
120pub use stub::*;