coreutils/src/id/id.rs

302 lines
9 KiB
Rust
Raw Normal View History

#![crate_name = "uu_id"]
2016-08-19 18:10:18 +00:00
// This file is part of the uutils coreutils package.
//
// (c) Alan Andrade <alan.andradec@gmail.com>
// (c) Jian Zeng <anonymousknight96 AT gmail.com>
//
// For the full copyright and license information, please view the LICENSE
// file that was distributed with this source code.
//
// Synced with:
// http://ftp-archive.freebsd.org/mirror/FreeBSD-Archive/old-releases/i386/1.0-RELEASE/ports/shellutils/src/id.c
// http://www.opensource.apple.com/source/shell_cmds/shell_cmds-118/id/id.c
//
2014-03-31 16:40:21 +00:00
#![allow(non_camel_case_types)]
2016-08-19 18:10:18 +00:00
#![allow(dead_code)]
#[macro_use]
extern crate uucore;
2016-08-19 18:10:18 +00:00
pub use uucore::libc;
use uucore::libc::{getlogin, uid_t};
use uucore::entries::{self, Passwd, Group, Locate};
use uucore::process::{getgid, getuid, getegid, geteuid};
use std::io::Write;
2016-08-19 18:10:18 +00:00
use std::ffi::CStr;
2016-08-19 18:10:18 +00:00
macro_rules! cstr2cow {
($v:expr) => (
unsafe { CStr::from_ptr($v).to_string_lossy() }
)
}
#[cfg(not(target_os = "linu"))]
mod audit {
2014-05-28 04:11:49 +00:00
pub use std::mem::uninitialized;
2016-08-19 18:10:18 +00:00
use super::libc::{uid_t, pid_t, c_int, c_uint, uint64_t, dev_t};
2016-08-19 18:10:18 +00:00
pub type au_id_t = uid_t;
pub type au_asid_t = pid_t;
pub type au_event_t = c_uint;
2016-08-19 18:10:18 +00:00
pub type au_emod_t = c_uint;
pub type au_class_t = c_int;
2014-09-23 22:42:25 +00:00
#[repr(C)]
pub struct au_mask {
pub am_success: c_uint,
2016-08-19 18:10:18 +00:00
pub am_failure: c_uint,
}
pub type au_mask_t = au_mask;
2014-09-23 22:42:25 +00:00
#[repr(C)]
pub struct au_tid_addr {
pub port: dev_t,
}
pub type au_tid_addr_t = au_tid_addr;
2014-09-23 22:42:25 +00:00
#[repr(C)]
pub struct c_auditinfo_addr {
2016-08-19 18:10:18 +00:00
pub ai_auid: au_id_t, // Audit user ID
pub ai_mask: au_mask_t, // Audit masks.
pub ai_termid: au_tid_addr_t, // Terminal ID.
pub ai_asid: au_asid_t, // Audit session ID.
pub ai_flags: uint64_t, // Audit session flags
}
pub type c_auditinfo_addr_t = c_auditinfo_addr;
2016-08-19 18:10:18 +00:00
extern "C" {
pub fn getaudit(auditinfo_addr: *mut c_auditinfo_addr_t) -> c_int;
}
}
2016-08-19 18:10:18 +00:00
static SYNTAX: &'static str = "[OPTION]... [USER]";
static SUMMARY: &'static str = "Print user and group information for the specified USER,\n or (when USER omitted) for the current user.";
2014-02-23 22:18:04 +00:00
pub fn uumain(args: Vec<String>) -> i32 {
2016-08-19 18:10:18 +00:00
let mut opts = new_coreopts!(SYNTAX, SUMMARY, "");
opts.optflag("A",
"",
"Display the process audit (not available on Linux)");
opts.optflag("G", "", "Display the different group IDs");
opts.optflag("g", "", "Display the effective group ID as a number");
2016-08-19 18:10:18 +00:00
opts.optflag("n",
"",
"Display the name of the user or group ID for the -G, -g and -u options");
opts.optflag("P", "", "Display the id as a password file entry");
opts.optflag("p", "", "Make the output human-readable");
opts.optflag("r", "", "Display the real ID for the -g and -u options");
opts.optflag("u", "", "Display the effective user ID as a number");
2016-08-19 18:10:18 +00:00
let matches = opts.parse(args);
if matches.opt_present("A") {
auditid();
return 0;
}
2016-08-19 18:10:18 +00:00
let possible_pw = if matches.free.is_empty() {
None
} else {
match Passwd::locate(matches.free[0].as_str()) {
Ok(p) => Some(p),
Err(_) => crash!(1, "No such user/group: {}", matches.free[0]),
}
};
let nflag = matches.opt_present("n");
let uflag = matches.opt_present("u");
let gflag = matches.opt_present("g");
let rflag = matches.opt_present("r");
if gflag {
2016-08-19 18:10:18 +00:00
let id = possible_pw.map(|p| p.gid()).unwrap_or(if rflag {
getgid()
} else {
2016-08-19 18:10:18 +00:00
getegid()
});
println!("{}",
if nflag {
entries::gid2grp(id).unwrap_or(id.to_string())
} else {
id.to_string()
});
return 0;
}
if uflag {
2016-08-19 18:10:18 +00:00
let id = possible_pw.map(|p| p.uid()).unwrap_or(if rflag {
getuid()
} else {
2016-08-19 18:10:18 +00:00
geteuid()
});
println!("{}",
if nflag {
entries::uid2usr(id).unwrap_or(id.to_string())
} else {
id.to_string()
});
return 0;
}
if matches.opt_present("G") {
2016-08-19 18:10:18 +00:00
println!("{}",
if nflag {
possible_pw.map(|p| p.belongs_to())
.unwrap_or(entries::get_groups().unwrap())
.iter()
.map(|&id| entries::gid2grp(id).unwrap())
.collect::<Vec<_>>()
.join(" ")
} else {
possible_pw.map(|p| p.belongs_to())
.unwrap_or(entries::get_groups().unwrap())
.iter()
.map(|&id| id.to_string())
.collect::<Vec<_>>()
.join(" ")
});
return 0;
}
if matches.opt_present("P") {
2016-08-19 18:10:18 +00:00
pline(possible_pw.map(|v| v.uid()));
return 0;
};
if matches.opt_present("p") {
pretty(possible_pw);
return 0;
}
if possible_pw.is_some() {
2014-06-17 12:28:19 +00:00
id_print(possible_pw, false, false)
} else {
2014-06-17 12:28:19 +00:00
id_print(possible_pw, true, true)
}
0
}
2016-08-19 18:10:18 +00:00
fn pretty(possible_pw: Option<Passwd>) {
if let Some(p) = possible_pw {
print!("uid\t{}\ngroups\t", p.name());
println!("{}",
p.belongs_to().iter().map(|&gr| entries::gid2grp(gr).unwrap()).collect::<Vec<_>>().join(" "));
} else {
2016-08-19 18:10:18 +00:00
let login = cstr2cow!(getlogin() as *const _);
let rid = getuid();
if let Ok(p) = Passwd::locate(rid) {
if login == p.name() {
println!("login\t{}", login);
}
println!("uid\t{}", p.name());
} else {
2016-08-19 18:10:18 +00:00
println!("uid\t{}", rid);
}
2016-08-19 18:10:18 +00:00
let eid = getegid();
if eid == rid {
2016-08-19 18:10:18 +00:00
if let Ok(p) = Passwd::locate(eid) {
println!("euid\t{}", p.name());
} else {
2014-11-21 09:09:43 +00:00
println!("euid\t{}", eid);
}
}
2016-08-19 18:10:18 +00:00
let rid = getgid();
if rid != eid {
2016-08-19 18:10:18 +00:00
if let Ok(g) = Group::locate(rid) {
println!("euid\t{}", g.name());
} else {
2016-08-19 18:10:18 +00:00
println!("euid\t{}", rid);
}
}
2016-08-19 18:10:18 +00:00
println!("groups\t{}",
entries::get_groups()
.unwrap()
.iter()
.map(|&gr| entries::gid2grp(gr).unwrap())
.collect::<Vec<_>>()
.join(" "));
}
}
2014-10-02 17:55:06 +00:00
#[cfg(any(target_os = "macos", target_os = "freebsd"))]
2016-08-19 18:10:18 +00:00
fn pline(possible_uid: Option<uid_t>) {
let uid = possible_uid.unwrap_or(getuid());
let pw = Passwd::locate(uid).unwrap();
println!("{}:{}:{}:{}:{}:{}:{}:{}:{}:{}",
pw.name(),
pw.user_passwd(),
pw.uid(),
pw.gid(),
pw.user_access_class(),
pw.passwd_change_time(),
pw.expiration(),
pw.user_info(),
pw.user_dir(),
pw.user_shell());
2014-06-15 10:23:41 +00:00
}
#[cfg(target_os = "linux")]
2016-08-19 18:10:18 +00:00
fn pline(possible_uid: Option<uid_t>) {
let uid = possible_uid.unwrap_or(getuid());
let pw = Passwd::locate(uid).unwrap();
println!("{}:{}:{}:{}:{}:{}:{}",
pw.name(),
pw.user_passwd(),
pw.uid(),
pw.gid(),
pw.user_info(),
pw.user_dir(),
pw.user_shell());
}
#[cfg(target_os = "linux")]
2016-08-19 18:10:18 +00:00
fn auditid() {}
#[cfg(not(target_os = "linux"))]
fn auditid() {
2014-07-01 00:28:02 +00:00
let mut auditinfo: audit::c_auditinfo_addr_t = unsafe { audit::uninitialized() };
let address = &mut auditinfo as *mut audit::c_auditinfo_addr_t;
2016-08-19 18:10:18 +00:00
if unsafe { audit::getaudit(address) } < 0 {
2014-06-17 12:48:37 +00:00
println!("couldn't retrieve information");
return;
}
2014-11-21 09:09:43 +00:00
println!("auid={}", auditinfo.ai_auid);
println!("mask.success=0x{:x}", auditinfo.ai_mask.am_success);
println!("mask.failure=0x{:x}", auditinfo.ai_mask.am_failure);
println!("termid.port=0x{:x}", auditinfo.ai_termid.port);
2014-11-21 09:09:43 +00:00
println!("asid={}", auditinfo.ai_asid);
}
2016-08-19 18:10:18 +00:00
fn id_print(possible_pw: Option<Passwd>, p_euid: bool, p_egid: bool) {
let (uid, gid) = possible_pw.map(|p| (p.uid(), p.gid())).unwrap_or((getuid(), getgid()));;
2016-08-19 18:10:18 +00:00
let groups = Passwd::locate(uid).unwrap().belongs_to();
2016-08-19 18:10:18 +00:00
print!("uid={}({})", uid, entries::uid2usr(uid).unwrap());
print!(" gid={}({})", gid, entries::gid2grp(gid).unwrap());
2016-08-19 18:10:18 +00:00
let euid = geteuid();
if p_euid && (euid != uid) {
2016-08-19 18:10:18 +00:00
print!(" euid={}({})", euid, entries::uid2usr(euid).unwrap());
}
2016-08-19 18:10:18 +00:00
let egid = getegid();
2014-06-17 12:46:02 +00:00
if p_egid && (egid != gid) {
2016-08-19 18:10:18 +00:00
print!(" egid={}({})", euid, entries::gid2grp(egid).unwrap());
}
2014-06-17 12:45:10 +00:00
2016-08-19 18:10:18 +00:00
println!(" groups={}",
groups.iter()
.map(|&gr| format!("{}({})", gr, entries::gid2grp(gr).unwrap()))
.collect::<Vec<_>>()
.join(","));
}