@@ -14,7 +14,7 @@ use anyhow::{Context, anyhow};
1414use directories_next:: BaseDirs ;
1515use ipnet:: Ipv4Net ;
1616use log:: { debug, info, warn} ;
17- use nix:: unistd:: { Group , User } ;
17+ use nix:: unistd:: { Gid , Group , Uid , User } ;
1818pub use open_hosts:: open_hosts;
1919pub use open_ports:: open_ports;
2020use rand:: prelude:: IndexedRandom ;
@@ -33,6 +33,8 @@ use which::which;
3333
3434thread_local ! {
3535 static CONFIG_DIR_OVERRIDE : std:: cell:: RefCell <Option <PathBuf >> = const { std:: cell:: RefCell :: new( None ) } ;
36+ static CONFIG_OWNER_OVERRIDE : std:: cell:: RefCell <Option <( Uid , Gid ) >> =
37+ const { std:: cell:: RefCell :: new( None ) } ;
3638}
3739
3840static DAEMON_MODE : std:: sync:: atomic:: AtomicBool = std:: sync:: atomic:: AtomicBool :: new ( false ) ;
@@ -52,6 +54,10 @@ pub fn set_config_dir_override(path: Option<PathBuf>) {
5254 CONFIG_DIR_OVERRIDE . with ( |ov| * ov. borrow_mut ( ) = path) ;
5355}
5456
57+ pub fn set_config_owner_override ( owner : Option < ( Uid , Gid ) > ) {
58+ CONFIG_OWNER_OVERRIDE . with ( |ov| * ov. borrow_mut ( ) = owner) ;
59+ }
60+
5561pub fn config_dir ( ) -> anyhow:: Result < PathBuf > {
5662 // Respect thread-local override first (used by daemon to select the connecting user's config).
5763 if let Some ( override_path) = CONFIG_DIR_OVERRIDE . with ( |ov| ov. borrow ( ) . clone ( ) )
@@ -176,14 +182,26 @@ pub fn set_config_permissions() -> anyhow::Result<()> {
176182 use std:: os:: unix:: fs:: PermissionsExt ;
177183
178184 let check_dir = vopono_dir ( ) ?;
179- let username = get_username ( ) ?;
180- let group = get_group ( & username) ?;
185+ let ( user, group) = CONFIG_OWNER_OVERRIDE
186+ . with ( |ov| * ov. borrow ( ) )
187+ . map_or_else (
188+ || -> anyhow:: Result < ( Option < Uid > , Option < Gid > ) > {
189+ let username = get_username ( ) ?;
190+ let group_name = get_group ( & username) ?;
191+ let user = User :: from_name ( & username) ?
192+ . map ( |x| x. uid )
193+ . ok_or_else ( || anyhow ! ( "Failed to resolve uid for user '{username}'" ) ) ?;
194+ let group = Group :: from_name ( & group_name) ?
195+ . map ( |x| x. gid )
196+ . ok_or_else ( || anyhow ! ( "Failed to resolve gid for group '{group_name}'" ) ) ?;
197+ Ok ( ( Some ( user) , Some ( group) ) )
198+ } ,
199+ |( uid, gid) | Ok ( ( Some ( uid) , Some ( gid) ) ) ,
200+ ) ?;
181201
182202 let file_permissions = Permissions :: from_mode ( 0o640 ) ;
183203 let dir_permissions = Permissions :: from_mode ( 0o750 ) ;
184204
185- let group = nix:: unistd:: Group :: from_name ( & group) ?. map ( |x| x. gid ) ;
186- let user = nix:: unistd:: User :: from_name ( & username) ?. map ( |x| x. uid ) ;
187205 for entry in WalkDir :: new ( check_dir) . into_iter ( ) . filter_map ( |e| e. ok ( ) ) {
188206 let path = entry. path ( ) ;
189207 nix:: unistd:: chown ( path, user, group) ?;
0 commit comments