@@ -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]
10741109pub fn pause ( ) -> Result < ( ) > {
10751110 let res = unsafe { libc:: pause ( ) } ;
0 commit comments