Skip to content

Commit 33fd1c3

Browse files
authored
Add effective group as the first element in the call to set groups (#937)
2 parents d92bc5a + 291b179 commit 33fd1c3

File tree

3 files changed

+43
-4
lines changed

3 files changed

+43
-4
lines changed

src/su/context.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ impl SuContext {
112112

113113
// last argument is the primary group
114114
group = primary_group.clone();
115-
user.groups.push(primary_group.gid);
115+
user.groups.insert(0, primary_group.gid);
116116
}
117117

118118
// add additional group if current user is root

src/system/mod.rs

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -276,9 +276,16 @@ pub fn set_target_user(
276276
) {
277277
use std::os::unix::process::CommandExt;
278278

279-
// add target group to list of additional groups if not present
280-
if !target_user.groups.contains(&target_group.gid) {
281-
target_user.groups.push(target_group.gid);
279+
if let Some(index) = target_user
280+
.groups
281+
.iter()
282+
.position(|id| id == &target_group.gid)
283+
{
284+
// make sure the requested group id is the first in the list (necessary on FreeBSD)
285+
target_user.groups.swap(0, index)
286+
} else {
287+
// add target group to list of additional groups if not present
288+
target_user.groups.insert(0, target_group.gid);
282289
}
283290

284291
// we need to do this in a `pre_exec` call since the `groups` method in `process::Command` is unstable

test-framework/sudo-compliance-tests/src/sudo/flag_group.rs

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,38 @@ fn adds_group_to_groups_output() -> Result<()> {
7777
Ok(())
7878
}
7979

80+
#[test]
81+
fn supplementary_groups_can_be_made_primary() -> Result<()> {
82+
let extra_group = "rustaceans";
83+
let env = Env(SUDOERS_ALL_ALL_NOPASSWD)
84+
.user(User(USERNAME).secondary_group(extra_group))
85+
.group(Group(extra_group))
86+
.group("secondary-group")
87+
.build()?;
88+
89+
let stdout = Command::new("groups")
90+
.as_user(USERNAME)
91+
.output(&env)?
92+
.stdout()?;
93+
let mut groups_without_sudo = stdout.split_ascii_whitespace().collect::<Vec<_>>();
94+
95+
let stdout = Command::new("sudo")
96+
.args(["-g", extra_group, "groups"])
97+
.as_user(USERNAME)
98+
.output(&env)?
99+
.stdout()?;
100+
101+
let mut groups_with_sudo = stdout.split_ascii_whitespace().collect::<Vec<_>>();
102+
103+
assert_eq!(groups_with_sudo[0], extra_group);
104+
105+
groups_without_sudo.sort();
106+
groups_with_sudo.sort();
107+
assert_eq!(groups_with_sudo, groups_without_sudo);
108+
109+
Ok(())
110+
}
111+
80112
#[test]
81113
fn group_can_be_specified_by_id() -> Result<()> {
82114
let expected_gid = 1234;

0 commit comments

Comments
 (0)