shell_rs/
groups.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/// Get the groups a user is in.
9pub fn groups(uid: nc::uid_t) -> Result<Vec<String>, Error> {
10    let passwd = pwd::getpwuid(uid)?;
11    match passwd {
12        None => Err(Error::from_string(
13            ErrorKind::PwdError,
14            format!("Invalid uid: {}", uid),
15        )),
16        Some(passwd) => {
17            let group_iter = grp::getgrent()?;
18            let mut result = Vec::new();
19            for g in group_iter {
20                if g.mem.contains(&passwd.name) || g.gid == passwd.gid {
21                    result.push(g.name);
22                }
23            }
24            return Ok(result);
25        }
26    }
27}
28
29/// Get the groups a user is in, by username.
30pub fn groups_by_name(name: &str) -> Result<Vec<String>, Error> {
31    let passwd = pwd::getpwname(name)?;
32    match passwd {
33        None => Err(Error::from_string(
34            ErrorKind::PwdError,
35            format!("Invalid user name: {}", name),
36        )),
37        Some(passwd) => {
38            let group_iter = grp::getgrent()?;
39            let mut result = Vec::new();
40            for g in group_iter {
41                if g.mem.contains(&passwd.name) || g.gid == passwd.gid {
42                    result.push(g.name);
43                }
44            }
45            return Ok(result);
46        }
47    }
48}
49
50#[cfg(test)]
51mod tests {
52    use super::*;
53
54    #[test]
55    fn test_groups() {
56        let root_uid = 0;
57        let root_group = "root".to_string();
58        let ret = groups(root_uid);
59        assert!(ret.is_ok());
60        let ret = ret.unwrap();
61        assert!(ret.contains(&root_group));
62    }
63
64    #[test]
65    fn test_groups_by_name() {
66        let root_name = "root";
67        let root_group = "root".to_string();
68        let ret = groups_by_name(root_name);
69        assert!(ret.is_ok());
70        let ret = ret.unwrap();
71        assert!(ret.contains(&root_group));
72    }
73}