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

Merge pull request #254 from ebfe/groups

c_types: handle errors from getgroups()/getgrouplist()
This commit is contained in:
Arcterus 2014-06-16 13:54:44 -07:00
commit 9f78e46484
3 changed files with 39 additions and 34 deletions

View file

@ -13,6 +13,7 @@ use self::libc::funcs::posix88::unistd::getgroups;
use std::vec::Vec; use std::vec::Vec;
use std::io::IoError;
use std::ptr::read; use std::ptr::read;
use std::str::raw::from_c_str; use std::str::raw::from_c_str;
@ -20,8 +21,8 @@ use std::str::raw::from_c_str;
pub struct c_passwd { pub struct c_passwd {
pub pw_name: *c_char, /* user name */ pub pw_name: *c_char, /* user name */
pub pw_passwd: *c_char, /* user name */ pub pw_passwd: *c_char, /* user name */
pub pw_uid: c_int, /* user uid */ pub pw_uid: uid_t, /* user uid */
pub pw_gid: c_int, /* user gid */ pub pw_gid: gid_t, /* user gid */
pub pw_change: time_t, pub pw_change: time_t,
pub pw_class: *c_char, pub pw_class: *c_char,
pub pw_gecos: *c_char, pub pw_gecos: *c_char,
@ -34,8 +35,8 @@ pub struct c_passwd {
pub struct c_passwd { pub struct c_passwd {
pub pw_name: *c_char, /* user name */ pub pw_name: *c_char, /* user name */
pub pw_passwd: *c_char, /* user name */ pub pw_passwd: *c_char, /* user name */
pub pw_uid: c_int, /* user uid */ pub pw_uid: uid_t, /* user uid */
pub pw_gid: c_int, /* user gid */ pub pw_gid: gid_t, /* user gid */
pub pw_gecos: *c_char, pub pw_gecos: *c_char,
pub pw_dir: *c_char, pub pw_dir: *c_char,
pub pw_shell: *c_char, pub pw_shell: *c_char,
@ -80,13 +81,13 @@ pub struct c_tm {
} }
extern { extern {
pub fn getpwuid(uid: c_int) -> *c_passwd; pub fn getpwuid(uid: uid_t) -> *c_passwd;
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: c_int, basegid: gid_t,
groups: *c_int, groups: *gid_t,
ngroups: *mut c_int) -> c_int; ngroups: *mut c_int) -> c_int;
pub fn getgrgid(gid: uid_t) -> *c_group; pub fn getgrgid(gid: gid_t) -> *c_group;
} }
pub fn get_pw_from_args(free: &Vec<String>) -> Option<c_passwd> { pub fn get_pw_from_args(free: &Vec<String>) -> Option<c_passwd> {
@ -95,8 +96,8 @@ pub fn get_pw_from_args(free: &Vec<String>) -> Option<c_passwd> {
// Passed user as id // Passed user as id
if username.chars().all(|c| c.is_digit()) { if username.chars().all(|c| c.is_digit()) {
let id = from_str::<i32>(username).unwrap(); let id = from_str::<u32>(username).unwrap();
let pw_pointer = unsafe { getpwuid(id) }; let pw_pointer = unsafe { getpwuid(id as uid_t) };
if pw_pointer.is_not_null() { if pw_pointer.is_not_null() {
Some(unsafe { read(pw_pointer) }) Some(unsafe { read(pw_pointer) })
@ -137,16 +138,19 @@ pub fn group(possible_pw: Option<c_passwd>, nflag: bool) {
} }
} else { } else {
ngroups = unsafe { ngroups = unsafe {
getgroups(NGROUPS, groups.as_mut_ptr() as *mut u32) getgroups(NGROUPS, groups.as_mut_ptr() as *mut gid_t)
}; };
} }
if ngroups < 0 {
crash!(1, "{}", IoError::last_error());
}
unsafe { groups.set_len(ngroups as uint) }; unsafe { groups.set_len(ngroups as uint) };
for &g in groups.iter() { for &g in groups.iter() {
if nflag { if nflag {
let group = unsafe { getgrgid(g as u32) }; let group = unsafe { getgrgid(g) };
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)
@ -154,7 +158,7 @@ pub fn group(possible_pw: Option<c_passwd>, nflag: bool) {
print!("{:s} ", name); print!("{:s} ", name);
} }
} else { } else {
print!("{:d} ", g); print!("{:u} ", g);
} }
} }

View file

@ -23,6 +23,7 @@ use std::ptr::read;
use libc::{ use libc::{
c_char, c_char,
c_int, c_int,
gid_t,
uid_t, uid_t,
getgid, getgid,
getuid getuid
@ -80,8 +81,8 @@ mod audit {
extern { extern {
fn getgrgid(gid: uid_t) -> *c_group; fn getgrgid(gid: uid_t) -> *c_group;
fn getgrouplist(name: *c_char, fn getgrouplist(name: *c_char,
basegid: c_int, basegid: gid_t,
groups: *c_int, groups: *gid_t,
ngroups: *mut c_int) -> c_int; ngroups: *mut c_int) -> c_int;
} }
@ -136,11 +137,11 @@ pub fn uumain(args: Vec<String>) -> int {
possible_pw.unwrap().pw_gid possible_pw.unwrap().pw_gid
} else { } else {
if rflag { if rflag {
unsafe { getgid() as i32 } unsafe { getgid() }
} else { } else {
unsafe { getegid() as i32 } unsafe { getegid() }
} }
} as u32; };
let gr = unsafe { getgrgid(id) }; let gr = unsafe { getgrgid(id) };
if nflag && gr.is_not_null() { if nflag && gr.is_not_null() {
@ -156,9 +157,9 @@ pub fn uumain(args: Vec<String>) -> int {
let id = if possible_pw.is_some() { let id = if possible_pw.is_some() {
possible_pw.unwrap().pw_uid possible_pw.unwrap().pw_uid
} else if rflag { } else if rflag {
unsafe { getgid() as i32 } unsafe { getgid() }
} else { } else {
unsafe { getegid() as i32 } unsafe { getegid() }
}; };
let pw = unsafe { getpwuid(id) }; let pw = unsafe { getpwuid(id) };
@ -168,7 +169,7 @@ pub fn uumain(args: Vec<String>) -> int {
}; };
println!("{:s}", pw_name); println!("{:s}", pw_name);
} else { } else {
println!("{:d}", id); println!("{:u}", id);
} }
return 0; return 0;
@ -208,7 +209,7 @@ fn pretty(possible_pw: Option<c_passwd>) {
} else { } else {
let login = unsafe { from_c_str(getlogin()) }; let login = unsafe { from_c_str(getlogin()) };
let rid = unsafe { getuid() }; let rid = unsafe { getuid() };
let pw = unsafe { getpwuid(rid as i32) }; let pw = unsafe { getpwuid(rid) };
let is_same_user = unsafe { let is_same_user = unsafe {
from_c_str(read(pw).pw_name) == login from_c_str(read(pw).pw_name) == login
@ -228,7 +229,7 @@ fn pretty(possible_pw: Option<c_passwd>) {
let eid = unsafe { getegid() }; let eid = unsafe { getegid() };
if eid == rid { if eid == rid {
let pw = unsafe { getpwuid(eid as i32) }; let pw = unsafe { getpwuid(eid) };
if pw.is_not_null() { if pw.is_not_null() {
println!( println!(
"euid\t{:s}", "euid\t{:s}",
@ -288,7 +289,7 @@ fn pline(possible_pw: Option<c_passwd>) {
#[cfg(target_os = "linux")] #[cfg(target_os = "linux")]
fn pline(possible_pw: Option<c_passwd>) { fn pline(possible_pw: Option<c_passwd>) {
let pw = if possible_pw.is_none() { let pw = if possible_pw.is_none() {
unsafe { read(getpwuid(getuid() as i32)) } unsafe { read(getpwuid(getuid())) }
} else { } else {
possible_pw.unwrap() possible_pw.unwrap()
}; };
@ -300,7 +301,7 @@ fn pline(possible_pw: Option<c_passwd>) {
let pw_shell = unsafe { from_c_str(pw.pw_shell) }; let pw_shell = unsafe { from_c_str(pw.pw_shell) };
println!( println!(
"{:s}:{:s}:{:d}:{:d}:{:s}:{:s}:{:s}", "{:s}:{:s}:{:u}:{:u}:{:s}:{:s}:{:s}",
pw_name, pw_name,
pw_passwd, pw_passwd,
pw.pw_uid, pw.pw_uid,
@ -343,8 +344,8 @@ fn id_print(possible_pw: Option<c_passwd>,
uid = possible_pw.unwrap().pw_uid; uid = possible_pw.unwrap().pw_uid;
gid = possible_pw.unwrap().pw_gid; gid = possible_pw.unwrap().pw_gid;
} else { } else {
uid = unsafe { getuid() as i32 }; uid = unsafe { getuid() };
gid = unsafe { getgid() as i32 }; gid = unsafe { getgid() };
} }
let mut ngroups; let mut ngroups;
@ -363,15 +364,15 @@ fn id_print(possible_pw: Option<c_passwd>,
if possible_pw.is_some() { if possible_pw.is_some() {
print!( print!(
"uid={:d}({:s})", "uid={:u}({:s})",
uid, uid,
unsafe { from_c_str(possible_pw.unwrap().pw_name) }); unsafe { from_c_str(possible_pw.unwrap().pw_name) });
} else { } else {
print!("uid={:u}", unsafe { getuid() }); print!("uid={:u}", unsafe { getuid() });
} }
print!(" gid={:d}", gid); print!(" gid={:u}", gid);
let gr = unsafe { getgrgid(gid as u32) }; let gr = unsafe { getgrgid(gid) };
if gr.is_not_null() { if gr.is_not_null() {
print!( print!(
"({:s})", "({:s})",
@ -379,9 +380,9 @@ fn id_print(possible_pw: Option<c_passwd>,
} }
let euid = unsafe { geteuid() }; let euid = unsafe { geteuid() };
if p_euid && (euid != uid as u32) { if p_euid && (euid != uid) {
print!(" euid={:u}", euid); print!(" euid={:u}", euid);
let pw = unsafe { getpwuid(euid as i32) }; let pw = unsafe { getpwuid(euid) };
if pw.is_not_null() { if pw.is_not_null() {
print!( print!(
"({:s})", "({:s})",
@ -408,7 +409,7 @@ fn id_print(possible_pw: Option<c_passwd>,
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!("{:d}", gr); print!("{:u}", gr);
let group = unsafe { getgrgid(gr as u32) }; let group = unsafe { getgrgid(gr as u32) };
if group.is_not_null() { if group.is_not_null() {
let name = unsafe { let name = unsafe {

View file

@ -32,7 +32,7 @@ mod platform {
#[path = "../../common/c_types.rs"] mod c_types; #[path = "../../common/c_types.rs"] mod c_types;
extern { extern {
pub fn geteuid() -> libc::c_int; pub fn geteuid() -> libc::uid_t;
} }
pub unsafe fn getusername() -> String { pub unsafe fn getusername() -> String {