@@ -1070,6 +1070,41 @@ pub fn setgroups(groups: &[Gid]) -> Result<()> {
1070
1070
Errno :: result ( res) . map ( |_| ( ) )
1071
1071
}
1072
1072
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
+
1073
1108
#[ inline]
1074
1109
pub fn pause ( ) -> Result < ( ) > {
1075
1110
let res = unsafe { libc:: pause ( ) } ;
0 commit comments