sudo: support euids with setuid binaries

This commit is contained in:
K. Lange 2018-10-31 10:28:41 +09:00
parent ba40bb5cc6
commit b42c185421
13 changed files with 68 additions and 13 deletions

View File

@ -18,7 +18,7 @@ int main(int argc, char * argv[]) {
printf("%s\n", tmp);
return 0;
} else {
if (getuid() != 0) {
if (geteuid() != 0) {
fprintf(stderr,"Must be root to set hostname.\n");
return 1;
} else {

View File

@ -22,7 +22,7 @@
int main(int argc, char * argv[]) {
int pid;
if (getuid() != 0) {
if (geteuid() != 0) {
return 1;
}

View File

@ -16,6 +16,7 @@
#include <signal.h>
#include <termios.h>
#include <errno.h>
#include <pwd.h>
#include <sys/wait.h>
#include <sys/utsname.h>
#include <toaru/auth.h>
@ -36,12 +37,15 @@ int main(int argc, char ** argv) {
}
while (1) {
/*
* This is not very secure, but I'm lazy and just want this to exist.
* It's not like we have file system permissions or anything like
* that sitting around anyway... So, XXX: make this not dumb.
*/
char * username = getenv("USER");
uid_t me = getuid();
if (me == 0) goto _do_it;
struct passwd * p = getpwuid(me);
if (!p) {
fprintf(stderr, "%s: unable to obtain username for real uid=%d\n", argv[0], getuid());
return 1;
}
char * username = p->pw_name;
char * password = malloc(sizeof(char) * 1024);
fprintf(stderr, "[%s] password for %s: ", argv[0], username);
@ -71,9 +75,41 @@ int main(int argc, char ** argv) {
continue;
}
/* Determine if this user is in the sudoers file */
FILE * sudoers = fopen("/etc/sudoers","r");
if (!sudoers) {
fprintf(stderr, "%s: /etc/sudoers is not available\n", argv[0]);
return 1;
}
/* Read each line */
int in_sudoers = 0;
while (!feof(sudoers)) {
char line[1024];
fgets(line, 1024, sudoers);
char * nl = strchr(line, '\n');
if (nl) {
*nl = '\0';
}
if (!strncmp(line,username,1024)) {
in_sudoers = 1;
break;
}
}
fclose(sudoers);
if (!in_sudoers) {
fprintf(stderr, "%s is not in sudoers file.\n", username);
return 1;
}
_do_it:
/* Set username to root */
putenv("USER=root");
/* Actually become root, so real user id = 0 */
setuid(0);
if (!strcmp(argv[1], "-s")) {
argv[1] = getenv("SHELL");
}

View File

@ -13,7 +13,7 @@
#include <pwd.h>
int main(int argc, char ** argv) {
struct passwd * p = getpwuid(getuid());
struct passwd * p = getpwuid(geteuid());
if (!p) return 0;
fprintf(stdout, "%s\n", p->pw_name);

1
base/etc/sudoers Normal file
View File

@ -0,0 +1 @@
local

View File

@ -74,6 +74,7 @@ typedef struct process {
char * name; /* Process Name */
char * description; /* Process description */
user_t user; /* Effective user */
user_t real_user; /* Real user ID */
int mask; /* Umask */
char ** cmdline;

View File

@ -120,6 +120,7 @@ DECL_SYSCALL3(readlink, char *, char *, int);
DECL_SYSCALL0(setsid);
DECL_SYSCALL2(setpgid,int,int);
DECL_SYSCALL1(getpgid,int);
DECL_SYSCALL0(geteuid);
_End_C_Header

View File

@ -1,6 +1,7 @@
#pragma once
#define SYS_EXT 0
#define SYS_GETEUID 1
#define SYS_OPEN 2
#define SYS_READ 3
#define SYS_WRITE 4

View File

@ -271,6 +271,7 @@ process_t * spawn_init(void) {
init->name = strdup("init"); /* Um, duh. */
init->cmdline = NULL;
init->user = 0; /* UID 0 */
init->real_user = 0;
init->mask = 022; /* umask */
init->status = 0; /* Run status */
init->fds = malloc(sizeof(fd_table_t));
@ -389,6 +390,7 @@ process_t * spawn_process(volatile process_t * parent, int reuse_fds) {
/* Copy permissions */
proc->user = parent->user;
proc->real_user = parent->real_user;
proc->mask = parent->mask;
/* Until specified otherwise */

View File

@ -411,12 +411,17 @@ static int sys_dup2(int old, int new) {
}
static int sys_getuid(void) {
return current_process->real_user;
}
static int sys_geteuid(void) {
return current_process->user;
}
static int sys_setuid(user_t new_uid) {
if (current_process->user == USER_ROOT_UID) {
current_process->user = new_uid;
current_process->real_user = new_uid;
return 0;
}
return -EPERM;
@ -1008,6 +1013,7 @@ static int sys_getpgid(pid_t pid) {
static int (*syscalls[])() = {
/* System Call Table */
[SYS_EXT] = sys_exit,
[SYS_GETEUID] = sys_geteuid,
[SYS_OPEN] = sys_open,
[SYS_READ] = sys_read,
[SYS_WRITE] = sys_write,

View File

@ -1,5 +1,9 @@
#include <unistd.h>
#include <syscall.h>
#include <syscall_nums.h>
int geteuid() {
return getuid();
DEFN_SYSCALL0(geteuid, SYS_GETEUID);
uid_t geteuid(void) {
return syscall_geteuid();
}

View File

@ -1,8 +1,10 @@
#include <unistd.h>
#include <syscall.h>
#include <syscall_nums.h>
DEFN_SYSCALL0(getuid, 23);
DEFN_SYSCALL0(getuid, SYS_GETUID);
int getuid() {
uid_t getuid(void) {
return syscall_getuid();
}

View File

@ -19,6 +19,7 @@ with open('util/devtable','w') as devtable:
# Set master.passwd to not be visible except by root
devtable.write('/etc/master.passwd f 600 0 0 - - - - -\n') # /etc/master.passwd should be restricted
devtable.write('/etc/sudoers f 600 0 0 - - - - -\n')
# Copy permissions and set ownership for user files
for user_details in [('local',1000)]: