Skip to content

Commit 5961d29

Browse files
committed
sysusers: Parse more truncated entries
This isn't mentioned in the docs, but the tooling will happily accept missing GECOS or even the uid field for users. xref #1331 Signed-off-by: Colin Walters <[email protected]>
1 parent bd317c3 commit 5961d29

File tree

1 file changed

+38
-3
lines changed

1 file changed

+38
-3
lines changed

sysusers/src/lib.rs

Lines changed: 38 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -168,7 +168,7 @@ impl SysusersEntry {
168168
let r = match ftype {
169169
"u" | "u!" => {
170170
let (name, s) = Self::next_token_owned(s).ok_or_else(err.clone())?;
171-
let (id, s) = Self::next_optional_token(s).ok_or_else(err.clone())?;
171+
let (id, s) = Self::next_optional_token(s).unwrap_or_default();
172172
let (uid, pgid) = id
173173
.and_then(|v| v.split_once(':'))
174174
.or_else(|| id.map(|id| (id, id)))
@@ -180,7 +180,8 @@ impl SysusersEntry {
180180
.transpose()
181181
.map_err(|_| err())?;
182182
let pgid = pgid.map(|id| id.parse()).transpose().map_err(|_| err())?;
183-
let (gecos, s) = Self::next_token_owned(s).ok_or_else(err.clone())?;
183+
let (gecos, s) = Self::next_token(s).unwrap_or_default();
184+
let gecos = gecos.to_owned();
184185
let (home, s) = Self::next_optional_token_owned(s).unwrap_or_default();
185186
let (shell, _) = Self::next_optional_token_owned(s).unwrap_or_default();
186187
SysusersEntry::User {
@@ -194,7 +195,7 @@ impl SysusersEntry {
194195
}
195196
"g" => {
196197
let (name, s) = Self::next_token_owned(s).ok_or_else(err.clone())?;
197-
let (id, _) = Self::next_optional_token(s).ok_or_else(err.clone())?;
198+
let (id, _) = Self::next_optional_token(s).unwrap_or_default();
198199
let id = id.map(|id| id.parse()).transpose().map_err(|_| err())?;
199200
SysusersEntry::Group { name, id }
200201
}
@@ -434,6 +435,11 @@ mod tests {
434435
const OTHER_SYSUSERS_EXAMPLES: &str = indoc! { r#"
435436
u user_name /file/owned/by/user "User Description" /home/dir /path/to/shell
436437
g group_name /file/owned/by/group
438+
# Note no GECOS field
439+
u otheruser -
440+
# And finally, no numeric specification at all
441+
u justusername
442+
g justgroupname
437443
"#};
438444

439445
const OTHER_SYSUSERS_UNHANDLED: &str = indoc! { r#"
@@ -541,6 +547,35 @@ mod tests {
541547
id: Some(IdSource::Path("/file/owned/by/group".into()))
542548
}
543549
);
550+
assert_eq!(
551+
entries.next().unwrap(),
552+
SysusersEntry::User {
553+
name: "otheruser".into(),
554+
uid: None,
555+
pgid: None,
556+
gecos: "".into(),
557+
home: None,
558+
shell: None
559+
}
560+
);
561+
assert_eq!(
562+
entries.next().unwrap(),
563+
SysusersEntry::User {
564+
name: "justusername".into(),
565+
uid: None,
566+
pgid: None,
567+
gecos: "".into(),
568+
home: None,
569+
shell: None
570+
}
571+
);
572+
assert_eq!(
573+
entries.next().unwrap(),
574+
SysusersEntry::Group {
575+
name: "justgroupname".into(),
576+
id: None
577+
}
578+
);
544579
assert_eq!(entries.count(), 0);
545580

546581
let n = OTHER_SYSUSERS_UNHANDLED

0 commit comments

Comments
 (0)