Skip to content

Instantly share code, notes, and snippets.

@jgarzik
Created April 17, 2024 03:18
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jgarzik/abb57e48a7f6c824a2182049d10a853f to your computer and use it in GitHub Desktop.
Save jgarzik/abb57e48a7f6c824a2182049d10a853f to your computer and use it in GitHub Desktop.
Enumerate groups, try 3 (working)
extern crate libc;
use libc::{endgrent, getgrent, setgrent, group};
use std::ffi::CStr;
use std::ptr;
struct Group {
name: String,
passwd: String,
gid: libc::gid_t,
members: Vec<String>,
}
fn load_group_db() -> Vec<Group> {
let mut groups = Vec::new();
unsafe {
setgrent(); // Initialize the group entry stream
let mut groupent = getgrent(); // Get the first group entry
while !groupent.is_null() {
let group = &*groupent;
let name = CStr::from_ptr(group.gr_name).to_string_lossy().to_string();
let passwd = CStr::from_ptr(group.gr_passwd).to_string_lossy().to_string();
let gid = group.gr_gid;
let mut members = Vec::new();
if !group.gr_mem.is_null() {
let mut member_ptr_arr = group.gr_mem;
while !ptr::read_unaligned(member_ptr_arr).is_null() {
let member_ptr = ptr::read_unaligned(member_ptr_arr);
let member = CStr::from_ptr(member_ptr).to_string_lossy().to_string();
members.push(member);
member_ptr_arr = member_ptr_arr.add(1);
}
}
groups.push(Group {
name,
passwd,
gid,
members,
});
groupent = getgrent(); // Move to the next group entry
}
endgrent(); // Close the group entry stream
}
groups
}
fn main() {
let groups = load_group_db();
for group in groups {
println!("{}({})", group.gid, group.name);
for member in &group.members {
println!("\t{}", member);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment