sudo: support euids with setuid binaries
This commit is contained in:
parent
ba40bb5cc6
commit
b42c185421
@ -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 {
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
48
apps/sudo.c
48
apps/sudo.c
@ -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");
|
||||||
}
|
}
|
||||||
|
@ -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
1
base/etc/sudoers
Normal file
@ -0,0 +1 @@
|
|||||||
|
local
|
@ -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;
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
@ -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 */
|
||||||
|
@ -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,
|
||||||
|
@ -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();
|
||||||
}
|
}
|
||||||
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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)]:
|
||||||
|
Loading…
Reference in New Issue
Block a user