Skip to content

Commit

Permalink
NSFS | add mac support for supplemental groups
Browse files Browse the repository at this point in the history
Signed-off-by: nadav mizrahi <[email protected]>
  • Loading branch information
nadavMiz committed Jan 22, 2025
1 parent 5762c13 commit 7c75fb9
Show file tree
Hide file tree
Showing 2 changed files with 61 additions and 2 deletions.
48 changes: 48 additions & 0 deletions src/native/util/os_darwin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,54 @@ const uid_t ThreadScope::orig_uid = getuid();
const gid_t ThreadScope::orig_gid = getgid();
const std::vector<gid_t> ThreadScope::orig_groups = get_process_groups();

static int
get_supplemental_groups_by_uid(uid_t uid, std::vector<gid_t>& groups)
{
// getpwuid will only indicate if an error happened by setting errno. set it to 0, so will know if there is a change
errno = 0;
struct passwd* pw = getpwuid(uid);
if (pw == NULL) {
if (errno == 0) {
LOG("get_supplemental_groups_by_uid: no record for uid " << uid);
} else {
LOG("WARNING: get_supplemental_groups_by_uid: getpwuid failed: " << strerror(errno));
}
return -1;
}
int ngroups = NGROUPS_MAX;
groups.resize(ngroups);
if (getgrouplist(pw->pw_name, pw->pw_gid, &groups[0], &ngroups) < 0) {
LOG("get_supplemental_groups_by_uid: getgrouplist failed: ngroups too small " << ngroups);
return -1;
}
groups.resize(ngroups);
return 0;
}

/**
* set supplemental groups of the thread according to the following:
* 1. if groups were defined in the account configuration, set the groups list to the one defined
* 2. try to get the list of groups corresponding to the user in the system recods, and set it to it
* 3. if supplemental groups were not defined for the account and getting it from system record failed (either because record doesn't exist ot because of an error)
* keep it as an empty set
*/
static void
set_supplemental_groups(uid_t uid, std::vector<gid_t>& groups) {
//first check if groups were defined in the account configuration
if (groups.empty()) {
if (get_supplemental_groups_by_uid(uid, groups) < 0) {
//aready unset by _mac_thread_setugid
return;
}
}
/*accourding to BSD Manual https://man.freebsd.org/cgi/man.cgi?query=setgroups
which darwin is occasionally compliant to setgroups changes the effective gid according to
the first element on the list. add the effective gid as the first element to prevent issues*/
_groups.push_back(_gid);
std::swap(_groups.front(), _groups.back());
MUST_SYS(setgroups(_groups.size(), &_groups[0]));
}


/**
* set the effective uid/gid/supplemental_groups of the current thread using pthread_getugid_np and setgroups
Expand Down
15 changes: 13 additions & 2 deletions src/test/system_tests/test_utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -343,7 +343,15 @@ async function delete_fs_user_by_platform(name) {
*/
async function create_fs_group_by_platform(group_name, gid, user_name) {
if (process.platform === 'darwin') {
//TODO not implemented
const create_group_cmd = `sudo dscl . create /Groups/${group_name} UserShell /bin/bash`;
const create_group_realname_cmd = `sudo dscl . create /Groups/${group_name} RealName ${group_name}`;
const create_group_gid_cmd = `sudo dscl . create /Groups/${group_name} gid ${gid}`;
const add_user_to_group_cmd = `sudo dscl . append /Groups/${group_name} GroupMembership ${user_name}`;
await os_utils.exec(create_group_cmd, { return_stdout: true });
await os_utils.exec(create_group_realname_cmd, { return_stdout: true });
await os_utils.exec(create_group_gid_cmd, { return_stdout: true });
await os_utils.exec(add_user_to_group_cmd, { return_stdout: true });

} else {
const create_group_cmd = `groupadd -g ${gid} ${group_name}`;
await os_utils.exec(create_group_cmd, { return_stdout: true });
Expand All @@ -361,7 +369,10 @@ async function create_fs_group_by_platform(group_name, gid, user_name) {
*/
async function delete_fs_group_by_platform(group_name, force = false) {
if (process.platform === 'darwin') {
//TODO not implemented
const delete_group_cmd = `sudo dscl . -delete /Groups/${group_name}`;
const delete_group_home_cmd = `sudo rm -rf /Groups/${group_name}`;
await os_utils.exec(delete_group_cmd, { return_stdout: true });
await os_utils.exec(delete_group_home_cmd, { return_stdout: true });
} else {
const flags = force ? '-f' : '';
const delete_group_cmd = `groupdel ${flags} ${group_name}`;
Expand Down

0 comments on commit 7c75fb9

Please sign in to comment.