@@ -1135,6 +1135,41 @@ pub fn setgroups(groups: &[Gid]) -> Result<()> {
11351135 Errno :: result ( res) . map ( |_| ( ) )
11361136}
11371137
1138+ /// Initialize the supplementary group access list. Sets the supplementary
1139+ /// group IDs for the calling process using all groups that `user` is a member
1140+ /// of. The additional group `group` is also added to the list.
1141+ ///
1142+ /// [Further reading](http://man7.org/linux/man-pages/man3/initgroups.3.html)
1143+ ///
1144+ /// # Examples
1145+ ///
1146+ /// `initgroups` can be used when dropping privileges from the root user to
1147+ /// another user. For example, given the user `www-data`, we could look up the
1148+ /// UID and GID for the user in the system's password database (usually found
1149+ /// in `/etc/passwd`). If the `www-data` user's UID and GID were `33` and `33`,
1150+ /// respectively, one could switch user as follows:
1151+ /// ```
1152+ /// let user = CString::new("www-data").unwrap();
1153+ /// let uid = Uid::from_raw(33);
1154+ /// let gid = Gid::from_raw(33);
1155+ /// initgroups(&user, gid)?;
1156+ /// setgid(gid)?;
1157+ /// setuid(uid)?;
1158+ /// ```
1159+ pub fn initgroups ( user : & CString , group : Gid ) -> Result < ( ) > {
1160+ cfg_if ! {
1161+ if #[ cfg( any( target_os = "ios" , target_os = "macos" ) ) ] {
1162+ type initgroups_group_t = c_int;
1163+ } else {
1164+ type initgroups_group_t = gid_t;
1165+ }
1166+ }
1167+ let gid: gid_t = group. into ( ) ;
1168+ let res = unsafe { libc:: initgroups ( user. as_ptr ( ) , gid as initgroups_group_t ) } ;
1169+
1170+ Errno :: result ( res) . map ( |_| ( ) )
1171+ }
1172+
11381173/// Suspend the thread until a signal is received
11391174///
11401175/// See also [pause(2)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/pause.html)
0 commit comments