mirror of
https://github.com/RGBCube/serenity
synced 2025-05-31 15:48:12 +00:00
su: Use setgroups() to switch over to the target user's extra GIDs
Before this, su would leave the process's extra GIDs untouched, simply inheriting them from whoever spawned su. Now we grab the target user's groups from /etc/group and setgroups().
This commit is contained in:
parent
5abc30e057
commit
c663b1034a
1 changed files with 27 additions and 2 deletions
|
@ -1,3 +1,4 @@
|
|||
#include <AK/Vector.h>
|
||||
#include <alloca.h>
|
||||
#include <grp.h>
|
||||
#include <pwd.h>
|
||||
|
@ -10,8 +11,9 @@ int main(int argc, char** argv)
|
|||
{
|
||||
uid_t uid = 0;
|
||||
gid_t gid = 0;
|
||||
struct passwd* pwd = nullptr;
|
||||
if (argc > 1) {
|
||||
auto* pwd = getpwnam(argv[1]);
|
||||
pwd = getpwnam(argv[1]);
|
||||
if (!pwd) {
|
||||
fprintf(stderr, "No such user: %s\n", argv[1]);
|
||||
return 1;
|
||||
|
@ -19,7 +21,30 @@ int main(int argc, char** argv)
|
|||
uid = pwd->pw_uid;
|
||||
gid = pwd->pw_gid;
|
||||
}
|
||||
int rc = setgid(uid);
|
||||
|
||||
if (!pwd)
|
||||
pwd = getpwuid(0);
|
||||
|
||||
if (!pwd) {
|
||||
fprintf(stderr, "No passwd entry.\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
Vector<gid_t> extra_gids;
|
||||
for (auto* group = getgrent(); group; group = getgrent()) {
|
||||
for (size_t i = 0; group->gr_mem[i]; ++i) {
|
||||
if (!strcmp(pwd->pw_name, group->gr_mem[i]))
|
||||
extra_gids.append(group->gr_gid);
|
||||
}
|
||||
}
|
||||
endgrent();
|
||||
|
||||
int rc = setgroups(extra_gids.size(), extra_gids.data());
|
||||
if (rc < 0) {
|
||||
perror("setgroups");
|
||||
return 1;
|
||||
}
|
||||
rc = setgid(uid);
|
||||
if (rc < 0) {
|
||||
perror("setgid");
|
||||
return 1;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue