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:
commit
a2d5dc4995
2 changed files with 70 additions and 69 deletions
|
@ -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!("");
|
|
||||||
}
|
}
|
||||||
|
|
50
id/id.rs
50
id/id.rs
|
@ -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!("");
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue