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
|
.Dt setruid 1
|
||||||
.Os
|
.Os
|
||||||
.Sh NAME
|
.Sh NAME
|
||||||
.Nm setruid
|
.Nm setruid
|
||||||
.Nd set the real UID for a command
|
.Nd set the real UID and GID for a command
|
||||||
.Sh SYNOPSIS
|
.Sh SYNOPSIS
|
||||||
.Nm
|
.Nm
|
||||||
|
.Ar username Ns Op : Ns Ar group
|
||||||
.Ar command
|
.Ar command
|
||||||
.Op Ar arguments
|
.Op Ar arguments
|
||||||
.Sh DESCRIPTION
|
.Sh DESCRIPTION
|
||||||
.Nm
|
.Nm
|
||||||
sets the real UID while keeping the effective UID the same. It is indended for
|
sets the real UID and GID while keeping the effective UID and GID the same. It
|
||||||
simple servers that need to bind on a low port and drop privileges by setting
|
is indended for simple servers that need to bind on a low port and drop
|
||||||
effective UID to real UID.
|
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
|
.Pp
|
||||||
.Nm
|
.Nm
|
||||||
executes the given command as the same process.
|
executes the given command as the same process.
|
||||||
|
|
43
setruid.c
43
setruid.c
|
@ -1,17 +1,34 @@
|
||||||
#define _BSD_SOURCE
|
#define _BSD_SOURCE
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
#include <grp.h>
|
||||||
#include <pwd.h>
|
#include <pwd.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
int main(int argc, char **argv) {
|
int main(int argc, char **argv) {
|
||||||
if(argc < 3) {
|
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;
|
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;
|
errno = 0;
|
||||||
struct passwd *passwd_entry = getpwnam(username);
|
struct passwd *passwd_entry = getpwnam(username);
|
||||||
if(passwd_entry == NULL) {
|
if(passwd_entry == NULL) {
|
||||||
|
@ -21,8 +38,28 @@ int main(int argc, char **argv) {
|
||||||
|
|
||||||
uid_t ruid = passwd_entry->pw_uid;
|
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) {
|
if(setreuid(ruid, -1) != 0) {
|
||||||
perror("getpwnam");
|
perror("setreuid");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if(setregid(rgid, -1) != 0) {
|
||||||
|
perror("setregid");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue