1

Given the following users:

$ whoami
admin
$ groups
staff everyone admin groupA

and

$ whoami
user
$ groups
staff everyone groupB

I'm trying to understand what exactly the --preserve-groups option affects.

$ whoami
admin

$ sudo --preserve-groups -u user groups
staff everyone groupB

$ sudo --preserve-groups -u user -s groups
staff everyone groupB

$ sudo --preserve-groups -u user -i groups
staff everyone groupB

The way I read the option's documentation I expect the list of groups, as seen by the executed command, to be taken from the invoking user and not from the target user. But it appears to be not the case.

5
  • That’s what I referred as option’s documentation in my question.
    – Kentzo
    Commented Apr 13, 2022 at 0:43
  • I think that admin the group in this case is the primary group of the admin the user, and note that the manpage says "The real and effective group-IDs, however, are still set to match the target user", so you can't inherit the primary group. Maybe try sg everyone or sg staff before using sudo
    – muru
    Commented Apr 13, 2022 at 1:06
  • In reality there are other groups that are unique to admin and user respectively. The result is the same: group-vector of admin is not preserved as seen by the groups command. I suspect that it is preserved somewhere else, I just cannot come up with and example that’d demonstrate it.
    – Kentzo
    Commented Apr 13, 2022 at 2:07
  • Huh, weird, then. It works fine enough for me on macOS 12.3.1 (1.9.5p2) and Arch Linux (sudo 1.9.10) (e.g., by comparing the output of sudo -u daemon groups with sudo -u daemon --preserve-groups groups - on both I could see my groups in the output of the latter command)
    – muru
    Commented Apr 13, 2022 at 3:28
  • @muru On macOS 11.6.5 (1.9.5p2) I get the same output for both commands (i.e. with and without --preserve-groups): daemon everyone localaccounts com.apple.sharepoint.group.2 com.apple.sharepoint.group.1 com.apple.sharepoint.group.3 _lpoperator
    – Kentzo
    Commented Apr 13, 2022 at 5:14

1 Answer 1

2

Apparently it does work as I expected, it's just groups and CPython that retrieve groups in a way that is ignorant of sudo's work.

CPython (3.8.9) will return target user's groups regardless of --preserve-groups:

python3 -c "import os; print(os.getgroups())"

But the following Swift program will work as expected:

import Darwin

let count = Int(getgroups(0, nil))
var groups = [gid_t](repeating: 0, count: count)
getgroups(Int32(count), &groups)
print(groups.map({"\($0)"}).joined(separator: ", "))
3
  • This is decidedly weird. For me, groups works correctly, but Python works like you say it does. But that is documented: "If built with a deployment target greater than 10.5, getgroups() returns the current group access list for the user associated with the effective user id of the process; the group access list may change over the lifetime of the process, it is not affected by calls to setgroups(), and its length is not limited to 16."
    – muru
    Commented Apr 13, 2022 at 7:45
  • Oh, now I see. I had GNU utilities installed, and this was GNU coreutils' groups. /usr/bin/groups does work like you say it does.
    – muru
    Commented Apr 13, 2022 at 7:47
  • 1
    Apple's groups, per docs, is equivalent to id -Gn. The id tool uses getgrouplist which ignores the groups that sudo sets via setgroups when the --preserve-groups option is given.
    – Kentzo
    Commented Apr 13, 2022 at 8:32

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .