Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
cgwalters committed Jan 30, 2019
1 parent 8029b2e commit f25e1b6
Showing 1 changed file with 27 additions and 15 deletions.
42 changes: 27 additions & 15 deletions rust/src/sysusers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ static SYSUSERS_DIR: &str = "usr/lib/sysusers.d";
static SYSUSERS_AUTO_NAME: &str = "rpmostree-auto.conf";
static SYSUSERS_OVERRIDES_NAME: &str = "rpmostree-overrides.conf";

#[derive(PartialEq, Eq, Debug, Hash)]
#[derive(PartialEq, Eq, Debug, Hash, Clone)]
enum IdSpecification {
Unspecified,
Specified(u32),
Expand Down Expand Up @@ -60,7 +60,7 @@ impl IdSpecification {
}

/// A generic name ↔ id pair used for both users and groups
#[derive(PartialEq, Eq, Debug, Hash)]
#[derive(PartialEq, Eq, Debug, Hash, Clone)]
struct PartialEntryValue {
raw: String,
name: String,
Expand All @@ -72,15 +72,15 @@ struct PartialEntryValue {
// etc. See extract-word.c in the systemd source. All we need is the
// user/group → {u,g}id mapping to ensure we're not creating duplicate entries.
// Group members we just pass through
#[derive(PartialEq, Eq, Debug, Hash)]
#[derive(PartialEq, Eq, Debug, Hash, Clone)]
enum PartialSysuserEntry {
User(PartialEntryValue),
Group(PartialEntryValue),
GroupMember(String)
}

/// The full version that we get from `useradd`.
#[derive(PartialEq, Eq, Debug, Hash)]
#[derive(PartialEq, Eq, Debug, Hash, Clone)]
enum SysuserEntry {
User {
name: String,
Expand Down Expand Up @@ -295,14 +295,15 @@ fn process_useradd_invocation(rootfs: openat::Dir, mut argf: fs::File) -> Fallib
let mut lines = argf.lines();
let sysusers_dir = path::Path::new(SYSUSERS_DIR);
let autopath = sysusers_dir.join(SYSUSERS_AUTO_NAME);
let mut sysusers_autof = None;
loop {
let mode = match (&mut lines).next() {
Some(mode) => mode?,
None => return Ok(()),
None => break,
};
let mode = mode.as_str();
if mode == "" {
return Ok(())
break
}
let mut args = vec![mode.to_string()];
for line in &mut lines {
Expand All @@ -314,13 +315,17 @@ fn process_useradd_invocation(rootfs: openat::Dir, mut argf: fs::File) -> Fallib
args.push(line);
};
let args : Vec<&str> = args.iter().map(|v| v.as_str()).collect();
let mut sysusers_autof = rootfs.append_file(&autopath, 0644)?;
sysusers_autof = Some(rootfs.append_file(&autopath, 0644)?);
match mode {
"useradd" => useradd_main(&mut sysusers_autof, &args)?,
"groupadd" => groupadd_main(&mut sysusers_autof, &args)?,
"useradd" => useradd_main(&mut sysusers_autof.as_mut().unwrap(), &args)?,
"groupadd" => groupadd_main(&mut sysusers_autof.as_mut().unwrap(), &args)?,
x => bail!("Unknown command: {}", x),
};
}
if let Some(ref mut autof) = sysusers_autof {
autof.flush()?;
}
Ok(())
}

#[derive(Default)]
Expand Down Expand Up @@ -366,7 +371,8 @@ fn parse_sysusers_indexed<I: io::BufRead>(f: I, indexed: &mut IndexedSysusers) -
let mut entries = parse_sysusers_stream(f)?;
for entry in entries.drain(..) {
match entry {
PartialSysuserEntry::User(u) => {indexed.users.insert(u.name.clone(), u);},
PartialSysuserEntry::User(u) => {indexed.users.insert(u.name.clone(), u.clone());
indexed.groups.insert(u.name.clone(), u);},
PartialSysuserEntry::Group(g) => {indexed.groups.insert(g.name.clone(), g);},
PartialSysuserEntry::GroupMember(raw) => {indexed.members.insert(raw);},
}
Expand Down Expand Up @@ -418,7 +424,7 @@ fn find_nonstatic_ownership(root: &openat::Dir, users: &IndexedSysusers) -> Fall
}

/// Iterate over any sysusers files from RPMs (not created by us).
fn load_other_sysusers(sysusers_dir: &openat::Dir) -> Fallible<IndexedSysusers> {
fn index_sysusers(sysusers_dir: &openat::Dir, skip_self: bool) -> Fallible<IndexedSysusers> {
let mut other_indexed = IndexedSysusers::new();
// Load and index our *other* sysusers.d entries
for child in sysusers_dir.list_dir(".")? {
Expand All @@ -427,7 +433,7 @@ fn load_other_sysusers(sysusers_dir: &openat::Dir) -> Fallible<IndexedSysusers>
if sysusers_dir.get_file_type(&child)? != openat::SimpleType::File {
continue;
};
if name == SYSUSERS_AUTO_NAME || name == SYSUSERS_OVERRIDES_NAME {
if skip_self && (name == SYSUSERS_AUTO_NAME || name == SYSUSERS_OVERRIDES_NAME) {
continue;
}
let f = sysusers_dir.open_file(name)?;
Expand Down Expand Up @@ -573,7 +579,7 @@ pub fn postprocess(rootfs: &openat::Dir, tf: &Treefile) -> Fallible<()> {
let sysusers_dirpath = path::Path::new(SYSUSERS_DIR);
let sysusers_dir = rootfs.sub_dir(sysusers_dirpath)?;

let mut other_indexed = load_other_sysusers(&sysusers_dir)?;
let mut other_indexed = index_sysusers(&sysusers_dir, true)?;

// Load our auto-generated sysusers.d entries
let mut my_entries =
Expand All @@ -595,14 +601,17 @@ pub fn postprocess(rootfs: &openat::Dir, tf: &Treefile) -> Fallible<()> {
if !other_indexed.users.contains_key(&v.name) {
f.write(v.raw.as_bytes())?;
f.write(b"\n")?;
other_indexed.users.insert(v.name.clone(), v);
} else {
eprintln!("dropping u {}", v.name);
}
},
PartialSysuserEntry::Group(v) => {
if !other_indexed.groups.contains_key(&v.name) {
f.write(v.raw.as_bytes())?;
f.write(b"\n")?;
other_indexed.groups.insert(v.name.clone(), v);
} else {
eprintln!("dropping g {}", v.name);
}
},
PartialSysuserEntry::GroupMember(g) => {
Expand All @@ -621,7 +630,10 @@ pub fn postprocess(rootfs: &openat::Dir, tf: &Treefile) -> Fallible<()> {
rewrite_sysusers_with_overrides(&sysusers_dir, user_overrides, group_overrides)?;
}

find_nonstatic_ownership(&rootfs, &other_indexed).map_err(|e| format_err!("Analyzing non-root ownership: {}", e))?;
let _ = other_indexed;
let final_indexed = index_sysusers(&sysusers_dir, false)?;

find_nonstatic_ownership(&rootfs, &final_indexed).map_err(|e| format_err!("Analyzing non-root ownership: {}", e))?;

return Ok(())
}
Expand Down

0 comments on commit f25e1b6

Please sign in to comment.