@@ -1135,6 +1135,41 @@ pub fn setgroups(groups: &[Gid]) -> Result<()> {
1135
1135
Errno :: result ( res) . map ( |_| ( ) )
1136
1136
}
1137
1137
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
+
1138
1173
/// Suspend the thread until a signal is received
1139
1174
///
1140
1175
/// See also [pause(2)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/pause.html)
0 commit comments