Handle groups in setruid(1) as well
This commit is contained in:
parent
4ce7746cb5
commit
568bddef26
14
setruid.1
14
setruid.1
|
@ -1,18 +1,22 @@
|
|||
.Dd Jul 11, 2018
|
||||
.Dd Jul 16, 2018
|
||||
.Dt setruid 1
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm setruid
|
||||
.Nd set the real UID for a command
|
||||
.Nd set the real UID and GID for a command
|
||||
.Sh SYNOPSIS
|
||||
.Nm
|
||||
.Ar username Ns Op : Ns Ar group
|
||||
.Ar command
|
||||
.Op Ar arguments
|
||||
.Sh DESCRIPTION
|
||||
.Nm
|
||||
sets the real UID while keeping the effective UID the same. It is indended for
|
||||
simple servers that need to bind on a low port and drop privileges by setting
|
||||
effective UID to real UID.
|
||||
sets the real UID and GID while keeping the effective UID and GID the same. It
|
||||
is indended for simple servers that need to bind on a low port and drop
|
||||
privileges by setting effective UID to real UID.
|
||||
.Pp
|
||||
By default the real GID of the process is set to the default group of the given
|
||||
user, but this can be overridden by passing the group argument.
|
||||
.Pp
|
||||
.Nm
|
||||
executes the given command as the same process.
|
||||
|
|
43
setruid.c
43
setruid.c
|
@ -1,17 +1,34 @@
|
|||
#define _BSD_SOURCE
|
||||
#include <errno.h>
|
||||
#include <grp.h>
|
||||
#include <pwd.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
if(argc < 3) {
|
||||
fprintf(stderr, "Usage: %s username command [arguments]\n", argv[0]);
|
||||
fprintf(stderr, "Usage: %s username[:group] command [arguments]\n", argv[0]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
const char *username = argv[1];
|
||||
char *username_group = strdup(argv[1]);
|
||||
if(username_group == NULL) {
|
||||
perror("strdup");
|
||||
return 1;
|
||||
}
|
||||
char *colon_position, *username, *group;
|
||||
if((colon_position = strchr(username_group, ':')) != NULL) {
|
||||
*colon_position = 0;
|
||||
username = username_group;
|
||||
group = colon_position + 1;
|
||||
} else {
|
||||
username = username_group;
|
||||
group = NULL;
|
||||
}
|
||||
|
||||
errno = 0;
|
||||
struct passwd *passwd_entry = getpwnam(username);
|
||||
if(passwd_entry == NULL) {
|
||||
|
@ -21,8 +38,28 @@ int main(int argc, char **argv) {
|
|||
|
||||
uid_t ruid = passwd_entry->pw_uid;
|
||||
|
||||
uid_t rgid;
|
||||
|
||||
if(group != NULL) {
|
||||
errno = 0;
|
||||
struct group *group_entry = getgrnam(group);
|
||||
if(group_entry == NULL) {
|
||||
perror("getgrnam");
|
||||
return 1;
|
||||
}
|
||||
rgid = group_entry->gr_gid;
|
||||
} else {
|
||||
rgid = passwd_entry->pw_gid;
|
||||
}
|
||||
|
||||
free(username_group);
|
||||
|
||||
if(setreuid(ruid, -1) != 0) {
|
||||
perror("getpwnam");
|
||||
perror("setreuid");
|
||||
return 1;
|
||||
}
|
||||
if(setregid(rgid, -1) != 0) {
|
||||
perror("setregid");
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue