shell_rs/
id.rs

1// Copyright (c) 2021 Xu Shaohua <shaohua@biofan.org>. All rights reserved.
2// Use of this source is governed by Apache-2.0 License that can be found
3// in the LICENSE file.
4
5use crate::core::{grp, pwd};
6use crate::error::{Error, ErrorKind};
7
8#[derive(Debug, Clone)]
9pub struct Id {
10    name: String,
11    uid: nc::uid_t,
12
13    group_name: String,
14    gid: nc::gid_t,
15
16    groups: Vec<(String, nc::gid_t)>,
17}
18
19/// Get real and effective user nad group IDs.
20pub fn id(uid: nc::uid_t) -> Result<Id, Error> {
21    let passwd = pwd::getpwuid(uid)?;
22    match passwd {
23        None => Err(Error::from_string(
24            ErrorKind::PwdError,
25            format!("Invalid uid: {}", uid),
26        )),
27        Some(passwd) => {
28            let group_iter = grp::getgrent()?;
29            let mut groups = Vec::new();
30            let mut group_name = String::new();
31            for g in group_iter {
32                if g.mem.contains(&passwd.name) {
33                    groups.push((g.name, g.gid));
34                } else if g.gid == passwd.gid {
35                    groups.push((g.name.clone(), g.gid));
36                    group_name = g.name;
37                }
38            }
39            return Ok(Id {
40                name: passwd.name,
41                uid: passwd.uid,
42                group_name,
43                gid: passwd.gid,
44                groups,
45            });
46        }
47    }
48}
49
50#[cfg(test)]
51mod tests {
52    use super::*;
53
54    #[test]
55    fn test_id() {
56        let root_id = 0;
57        let ret = id(root_id);
58        assert!(ret.is_ok());
59        let id = ret.unwrap();
60        assert_eq!(id.uid, 0);
61        assert_eq!(id.gid, 0);
62    }
63}