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); printf("%s\n", tmp);
return 0; return 0;
} else { } else {
if (getuid() != 0) { if (geteuid() != 0) {
fprintf(stderr,"Must be root to set hostname.\n"); fprintf(stderr,"Must be root to set hostname.\n");
return 1; return 1;
} else { } else {

View File

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

View File

@ -16,6 +16,7 @@
#include <signal.h> #include <signal.h>
#include <termios.h> #include <termios.h>
#include <errno.h> #include <errno.h>
#include <pwd.h>
#include <sys/wait.h> #include <sys/wait.h>
#include <sys/utsname.h> #include <sys/utsname.h>
#include <toaru/auth.h> #include <toaru/auth.h>
@ -36,12 +37,15 @@ int main(int argc, char ** argv) {
} }
while (1) { while (1) {
/* uid_t me = getuid();
* This is not very secure, but I'm lazy and just want this to exist. if (me == 0) goto _do_it;
* It's not like we have file system permissions or anything like
* that sitting around anyway... So, XXX: make this not dumb. struct passwd * p = getpwuid(me);
*/ if (!p) {
char * username = getenv("USER"); 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); char * password = malloc(sizeof(char) * 1024);
fprintf(stderr, "[%s] password for %s: ", argv[0], username); fprintf(stderr, "[%s] password for %s: ", argv[0], username);
@ -71,9 +75,41 @@ int main(int argc, char ** argv) {
continue; 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 */ /* Set username to root */
putenv("USER=root"); putenv("USER=root");
/* Actually become root, so real user id = 0 */
setuid(0);
if (!strcmp(argv[1], "-s")) { if (!strcmp(argv[1], "-s")) {
argv[1] = getenv("SHELL"); argv[1] = getenv("SHELL");
} }

View File

@ -13,7 +13,7 @@
#include <pwd.h> #include <pwd.h>
int main(int argc, char ** argv) { int main(int argc, char ** argv) {
struct passwd * p = getpwuid(getuid()); struct passwd * p = getpwuid(geteuid());
if (!p) return 0; if (!p) return 0;
fprintf(stdout, "%s\n", p->pw_name); 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 * name; /* Process Name */
char * description; /* Process description */ char * description; /* Process description */
user_t user; /* Effective user */ user_t user; /* Effective user */
user_t real_user; /* Real user ID */
int mask; /* Umask */ int mask; /* Umask */
char ** cmdline; char ** cmdline;

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -1,8 +1,10 @@
#include <unistd.h> #include <unistd.h>
#include <syscall.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(); 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 # 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/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 # Copy permissions and set ownership for user files
for user_details in [('local',1000)]: for user_details in [('local',1000)]: