Skip to content

Commit 5aceb17

Browse files
committed
unistd: Add initgroups()
1 parent d82fa57 commit 5aceb17

File tree

1 file changed

+35
-0
lines changed

1 file changed

+35
-0
lines changed

src/unistd.rs

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1070,6 +1070,41 @@ pub fn setgroups(groups: &[Gid]) -> Result<()> {
10701070
Errno::result(res).map(|_| ())
10711071
}
10721072

1073+
/// Initialize the supplementary group access list. Sets the supplementary
1074+
/// group IDs for the calling process using all groups that `user` is a member
1075+
/// of. The additional group `group` is also added to the list.
1076+
///
1077+
/// [Further reading](http://man7.org/linux/man-pages/man3/initgroups.3.html)
1078+
///
1079+
/// # Examples
1080+
///
1081+
/// `initgroups` can be used when dropping privileges from the root user to
1082+
/// another user. For example, given the user `www-data`, we could look up the
1083+
/// UID and GID for the user in the system's password database (usually found
1084+
/// in `/etc/passwd`). If the `www-data` user's UID and GID were `33` and `33`,
1085+
/// respectively, one could switch user as follows:
1086+
/// ```
1087+
/// let user = CString::new("www-data").unwrap();
1088+
/// let uid = Uid::from_raw(33);
1089+
/// let gid = Gid::from_raw(33);
1090+
/// initgroups(&user, gid)?;
1091+
/// setgid(gid)?;
1092+
/// setuid(uid)?;
1093+
/// ```
1094+
pub fn initgroups(user: &CString, group: Gid) -> Result<()> {
1095+
cfg_if! {
1096+
if #[cfg(any(target_os = "ios", target_os = "macos"))] {
1097+
type initgroups_group_t = c_int;
1098+
} else {
1099+
type initgroups_group_t = gid_t;
1100+
}
1101+
}
1102+
let gid: gid_t = group.into();
1103+
let res = unsafe { libc::initgroups(user.as_ptr(), gid as initgroups_group_t) };
1104+
1105+
Errno::result(res).map(|_| ())
1106+
}
1107+
10731108
#[inline]
10741109
pub fn pause() -> Result<()> {
10751110
let res = unsafe { libc::pause() };

0 commit comments

Comments
 (0)