From 0cabf243bd6984f99c211448c5a54ef8819d8676 Mon Sep 17 00:00:00 2001 From: Konstantin Stepanov Date: Tue, 21 Jul 2015 11:39:32 +0300 Subject: [PATCH] add switch user/group functionality --- src/lib.rs | 38 +++++++++++++++++++++++++++++++++++++- 1 file changed, 37 insertions(+), 1 deletion(-) diff --git a/src/lib.rs b/src/lib.rs index 5035f0b..23e79c1 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -127,7 +127,7 @@ use std::ptr::read; use std::str::from_utf8_unchecked; use std::collections::HashMap; use std::collections::hash_map::Entry::{Occupied, Vacant}; -use std::io::Error as IoError; +use std::io; pub mod mock; @@ -636,6 +636,42 @@ pub fn set_both_gid(rgid: gid_t, egid: git_t) -> Result<(), io::Error> { } } +pub struct SwitchUserGuard { + uid: uid_t, + gid: gid_t, + euid: euid_t, + egid: egid_t, +} + +impl Drop for SwitchUserGuard { + fn drop(&mut self) { + set_both_uid(self.uid, self.euid); + set_both_gid(self.gid, self.egid); + } +} + +/// Safely switch user and group for the current scope. +/// Requires root access. +/// +/// ```rust +/// { +/// let guard = switch_user_group(1001, 1001, 1001, 1001); +/// // current and effective user and group ids are 1001 +/// } +/// // back to the old values +pub fn switch_user_group(uid: uid_t, gid: git_t, euid: uid_t, egid: gid_t) -> Result { + let current_state = SwitchUserGuard { + uid: get_current_uid(), + gid: get_current_gid(), + euid: get_effective_uid(), + egid: get_effective_gid(), + }; + + try!(set_both_uid(uid, euid)); + try!(set_both_gid(gid, egid)); + Ok(current_state) +} + #[cfg(test)] mod test { use super::{Users, OSUsers, get_current_username};