1
Fork 0
mirror of https://github.com/RGBCube/uutils-coreutils synced 2025-07-29 12:07:46 +00:00

Merge pull request #262 from ebfe/fix-group-foo

id/groups: fix group list handling
This commit is contained in:
Oly Mi 2014-06-17 18:10:40 +04:00
commit a2d5dc4995
2 changed files with 70 additions and 69 deletions

View file

@ -13,7 +13,7 @@ use self::libc::funcs::posix88::unistd::getgroups;
use std::vec::Vec; use std::vec::Vec;
use std::io::IoError; use std::os;
use std::ptr::read; use std::ptr::read;
use std::str::raw::from_c_str; use std::str::raw::from_c_str;
@ -85,7 +85,7 @@ extern {
pub fn getpwnam(login: *c_char) -> *c_passwd; pub fn getpwnam(login: *c_char) -> *c_passwd;
pub fn getgrouplist(name: *c_char, pub fn getgrouplist(name: *c_char,
basegid: gid_t, basegid: gid_t,
groups: *gid_t, groups: *mut gid_t,
ngroups: *mut c_int) -> c_int; ngroups: *mut c_int) -> c_int;
pub fn getgrgid(gid: gid_t) -> *c_group; pub fn getgrgid(gid: gid_t) -> *c_group;
pub fn getgrnam(name: *c_char) -> *c_group; pub fn getgrnam(name: *c_char) -> *c_group;
@ -137,46 +137,61 @@ pub fn get_group(groupname: &str) -> Option<c_group> {
} }
} }
static NGROUPS: i32 = 20; pub fn get_group_list(name: *c_char, gid: gid_t) -> Result<Vec<gid_t>, int> {
let mut ngroups = 0 as c_int;
unsafe { getgrouplist(name, gid, 0 as *mut gid_t, &mut ngroups) };
let mut groups = Vec::from_elem(ngroups as uint, 0 as gid_t);
let err = unsafe { getgrouplist(name, gid, groups.as_mut_ptr(), &mut ngroups) };
if err == -1 {
Err(os::errno())
} else {
groups.truncate(ngroups as uint);
Ok(groups)
}
}
pub fn get_groups() -> Result<Vec<gid_t>, int> {
let ngroups = unsafe { getgroups(0, 0 as *mut gid_t) };
if ngroups == -1 {
return Err(os::errno());
}
let mut groups = Vec::from_elem(ngroups as uint, 0 as gid_t);
let ngroups = unsafe { getgroups(ngroups, groups.as_mut_ptr()) };
if ngroups == -1 {
Err(os::errno())
} else {
groups.truncate(ngroups as uint);
Ok(groups)
}
}
pub fn group(possible_pw: Option<c_passwd>, nflag: bool) { pub fn group(possible_pw: Option<c_passwd>, nflag: bool) {
let mut groups = Vec::with_capacity(NGROUPS as uint);
let mut ngroups;
if possible_pw.is_some() { let groups = match possible_pw {
ngroups = NGROUPS; Some(pw) => get_group_list(pw.pw_name, pw.pw_gid),
unsafe { None => get_groups(),
getgrouplist( };
possible_pw.unwrap().pw_name,
possible_pw.unwrap().pw_gid,
groups.as_ptr(),
&mut ngroups);
}
} else {
ngroups = unsafe {
getgroups(NGROUPS, groups.as_mut_ptr() as *mut gid_t)
};
}
if ngroups < 0 { match groups {
crash!(1, "{}", IoError::last_error()); Err(errno) =>
} crash!(1, "failed to get group list (errno={:d})", errno),
Ok(groups) => {
unsafe { groups.set_len(ngroups as uint) }; for &g in groups.iter() {
if nflag {
for &g in groups.iter() { let group = unsafe { getgrgid(g) };
if nflag { if group.is_not_null() {
let group = unsafe { getgrgid(g) }; let name = unsafe {
if group.is_not_null() { from_c_str(read(group).gr_name)
let name = unsafe { };
from_c_str(read(group).gr_name) print!("{:s} ", name);
}; }
print!("{:s} ", name); } else {
print!("{:u} ", g);
}
} }
} else { println!("");
print!("{:u} ", g);
} }
} }
println!("");
} }

View file

@ -21,19 +21,19 @@ extern crate libc;
use std::os; use std::os;
use std::ptr::read; use std::ptr::read;
use libc::{ use libc::{
c_char,
c_int, c_int,
gid_t,
uid_t, uid_t,
getgid, getgid,
getuid getuid
}; };
use libc::funcs::posix88::unistd::{getegid, geteuid, getgroups, getlogin}; use libc::funcs::posix88::unistd::{getegid, geteuid, getlogin};
use std::str::raw::from_c_str; use std::str::raw::from_c_str;
use getopts::{getopts, optflag, usage}; use getopts::{getopts, optflag, usage};
use c_types::{ use c_types::{
c_passwd, c_passwd,
c_group, c_group,
get_groups,
get_group_list,
get_pw_from_args, get_pw_from_args,
getpwuid, getpwuid,
group group
@ -80,10 +80,6 @@ mod audit {
extern { extern {
fn getgrgid(gid: uid_t) -> *c_group; fn getgrgid(gid: uid_t) -> *c_group;
fn getgrouplist(name: *c_char,
basegid: gid_t,
groups: *gid_t,
ngroups: *mut c_int) -> c_int;
} }
static NAME: &'static str = "id"; static NAME: &'static str = "id";
@ -191,9 +187,9 @@ pub fn uumain(args: Vec<String>) -> int {
} }
if possible_pw.is_some() { if possible_pw.is_some() {
id_print(possible_pw, true, false, false) id_print(possible_pw, false, false)
} else { } else {
id_print(possible_pw, false, true, true) id_print(possible_pw, true, true)
} }
0 0
@ -311,8 +307,6 @@ fn pline(possible_pw: Option<c_passwd>) {
pw_shell); pw_shell);
} }
static NGROUPS: i32 = 20;
#[cfg(target_os = "linux")] #[cfg(target_os = "linux")]
fn auditid() { } fn auditid() { }
@ -321,7 +315,7 @@ fn auditid() {
let auditinfo: audit::c_auditinfo_addr_t = unsafe { audit::uninitialized() }; let auditinfo: audit::c_auditinfo_addr_t = unsafe { audit::uninitialized() };
let address = &auditinfo as *audit::c_auditinfo_addr_t; let address = &auditinfo as *audit::c_auditinfo_addr_t;
if unsafe { audit::getaudit(address) } < 0 { if unsafe { audit::getaudit(address) } < 0 {
println!("Couldlnt retrieve information"); println!("couldn't retrieve information");
return; return;
} }
@ -333,7 +327,6 @@ fn auditid() {
} }
fn id_print(possible_pw: Option<c_passwd>, fn id_print(possible_pw: Option<c_passwd>,
use_ggl: bool,
p_euid: bool, p_euid: bool,
p_egid: bool) { p_egid: bool) {
@ -348,19 +341,14 @@ fn id_print(possible_pw: Option<c_passwd>,
gid = unsafe { getgid() }; gid = unsafe { getgid() };
} }
let mut ngroups; let groups = match possible_pw {
let mut groups = Vec::with_capacity(NGROUPS as uint); Some(pw) => get_group_list(pw.pw_name, pw.pw_gid),
None => get_groups(),
};
if use_ggl && possible_pw.is_some() { let groups = groups.unwrap_or_else(|errno| {
ngroups = NGROUPS; crash!(1, "failed to get group list (errno={:d})", errno);
let pw_name = possible_pw.unwrap().pw_name; });
unsafe { getgrouplist(pw_name, gid, groups.as_ptr(), &mut ngroups) };
} else {
ngroups = unsafe {
getgroups(NGROUPS, groups.as_mut_ptr() as *mut u32)
};
}
if possible_pw.is_some() { if possible_pw.is_some() {
print!( print!(
@ -391,7 +379,7 @@ fn id_print(possible_pw: Option<c_passwd>,
} }
let egid = unsafe { getegid() }; let egid = unsafe { getegid() };
if p_egid && (egid != gid as u32) { if p_egid && (egid != gid) {
print!(" egid={:u}", egid); print!(" egid={:u}", egid);
unsafe { unsafe {
let grp = getgrgid(egid); let grp = getgrgid(egid);
@ -401,16 +389,14 @@ fn id_print(possible_pw: Option<c_passwd>,
} }
} }
unsafe { groups.set_len(ngroups as uint) }; if groups.len() > 0 {
if ngroups > 0 {
print!(" groups="); print!(" groups=");
let mut first = true; let mut first = true;
for &gr in groups.iter() { for &gr in groups.iter() {
if !first { print!(",") } if !first { print!(",") }
print!("{:u}", gr); print!("{:u}", gr);
let group = unsafe { getgrgid(gr as u32) }; let group = unsafe { getgrgid(gr) };
if group.is_not_null() { if group.is_not_null() {
let name = unsafe { let name = unsafe {
from_c_str(read(group).gr_name) from_c_str(read(group).gr_name)
@ -419,7 +405,7 @@ fn id_print(possible_pw: Option<c_passwd>,
} }
first = false first = false
} }
println!("");
} }
println!("");
} }