Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

take supplementary groups into account #168

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open

Conversation

r5r3
Copy link

@r5r3 r5r3 commented May 26, 2020

Fix for issue #167.
The changes certainly needs to be properly reviewed.

@googlebot
Copy link

Thanks for your pull request. It looks like this may be your first contribution to a Google open source project (if not, look below for help). Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA).

📝 Please visit https://cla.developers.google.com/ to sign.

Once you've signed (or fixed any issues), please reply here with @googlebot I signed it! and we'll verify it.


What to do if you already signed the CLA

Individual signers
Corporate signers

ℹ️ Googlers: Go here for more info.

@r5r3
Copy link
Author

r5r3 commented May 26, 2020

@googlebot I signed it!

@googlebot
Copy link

CLAs look good, thanks!

ℹ️ Googlers: Go here for more info.

Copy link
Collaborator

@ThomasHabets ThomasHabets left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice work.

// get number of groups for the user
GroupList user_groups;
user_groups.n_groups = 0;
int err = getgrouplist(username, gid, NULL, &user_groups.n_groups);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also check for the error.

}

// store the old list of groups of this process
old_groups->n_groups = getgroups(0, NULL);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

check for error (-1 return value)

@@ -385,6 +392,38 @@ static int drop_privileges(pam_handle_t *pamh, const char *username, int uid,
gid_t gid = pw->pw_gid;
free(buf);

// to access the secret file, we may have to be member of the same groups as the
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Break out all this grouplist fetching into its own function, so that it's easy to follow the failure path, that should presumably be to degrade to the current behaviour of no extra groups.

Bonus points for hiding this behind a HAVE_SETGROUPLIST since it's apparently nonstandard.


// store the old list of groups of this process
old_groups->n_groups = getgroups(0, NULL);
old_groups->gids = malloc(sizeof(gid_t)*old_groups->n_groups);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

check for malloc fail.

Also above.

// store the old list of groups of this process
old_groups->n_groups = getgroups(0, NULL);
old_groups->gids = malloc(sizeof(gid_t)*old_groups->n_groups);
err = getgroups(old_groups->n_groups, old_groups->gids);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

From the manpage:

       It is unspecified whether the effective group ID of the calling process
       is included in the returned list.  (Thus, an  application  should  also
       call getegid(2) and add or remove the resulting value.)

Are we already capturing this using old_gid, so no need?

}
// cleanup user group list
free(user_groups.gids);
user_groups.n_groups = -1;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why not 0?

Well, if this is in its own function then this auto variable will go out of scope anyway.

@@ -2132,6 +2174,13 @@ static int google_authenticator(pam_handle_t *pamh,
"but can't switch back", old_uid, uid);
}
}
// restore old supplementary groups for process
if (old_groups.n_groups > 0) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the list is empty we still want to call setgroups(), no? That is, we want to drop whatever groups we added before.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think when we make sure that the effective group is taken into account, then the list can never be empty. Except for platforms where not all functions are available. I will make sure that this case is also handled correctly.

@ThomasHabets
Copy link
Collaborator

And you've confirmed that this fixes the issue for you?

@r5r3
Copy link
Author

r5r3 commented May 28, 2020

Thank you for your comments! I will move my changes into a separate function and hide it behind HAVE_SETGROUPLIST.

I can also confirm that the issue #167 is solved when supplementary groups are taken into account.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants