|
|
|
@ -47,6 +47,8 @@ |
|
|
|
|
|
|
|
|
|
#define MAX_HASH 1024 |
|
|
|
|
|
|
|
|
|
static void *emalloc(size_t); |
|
|
|
|
static char *estrdup(const char *); |
|
|
|
|
static void usage(void); |
|
|
|
|
static void die(const char *, ...); |
|
|
|
|
static int perm_set(struct passwd *, struct group *); |
|
|
|
@ -102,9 +104,11 @@ int main(int argc, char *argv[]) |
|
|
|
|
fprintf(stderr, "getpwid: %s\n", strerror(errno)); |
|
|
|
|
return errno; |
|
|
|
|
} |
|
|
|
|
char *my_name = strdup(my_pw->pw_name); |
|
|
|
|
if (!my_name) |
|
|
|
|
die("strdup:"); |
|
|
|
|
char *my_name = estrdup(my_pw->pw_name); |
|
|
|
|
|
|
|
|
|
/* From now on most actions require root */ |
|
|
|
|
if (setuid(0) == -1) |
|
|
|
|
die("setuid:"); |
|
|
|
|
|
|
|
|
|
/* Authenticate, we will be root from now on */ |
|
|
|
|
if (authenticate(my_pw->pw_uid, 0)) |
|
|
|
@ -128,22 +132,13 @@ int main(int argc, char *argv[]) |
|
|
|
|
int c_argc = argc - optind; |
|
|
|
|
char **c_argv; |
|
|
|
|
if (c_argc) { |
|
|
|
|
c_argv = malloc(sizeof(char *) * (c_argc + 1)); |
|
|
|
|
if (!c_argv) |
|
|
|
|
die("malloc:"); |
|
|
|
|
for (int i = 0; optind < argc; optind++, i++) { |
|
|
|
|
c_argv[i] = strdup(argv[optind]); |
|
|
|
|
if (!c_argv[i]) |
|
|
|
|
die("strdup:"); |
|
|
|
|
} |
|
|
|
|
c_argv = emalloc(sizeof(char *) * (c_argc + 1)); |
|
|
|
|
for (int i = 0; optind < argc; optind++, i++) |
|
|
|
|
c_argv[i] = estrdup(argv[optind]); |
|
|
|
|
} else { |
|
|
|
|
c_argc = 1; |
|
|
|
|
c_argv = malloc(sizeof(char *) * (c_argc + 1)); |
|
|
|
|
if (!c_argv) |
|
|
|
|
die("malloc:"); |
|
|
|
|
c_argv[0] = strdup(shell); |
|
|
|
|
if (!c_argv[0]) |
|
|
|
|
die("strdup:"); |
|
|
|
|
c_argv = emalloc(sizeof(char *) * (c_argc + 1)); |
|
|
|
|
c_argv[0] = estrdup(shell); |
|
|
|
|
} |
|
|
|
|
c_argv[c_argc] = NULL; |
|
|
|
|
|
|
|
|
@ -171,11 +166,8 @@ int main(int argc, char *argv[]) |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
if (envflag) { /* clear env */ |
|
|
|
|
for (int i = 0; env_keep[i].name; i++) { |
|
|
|
|
env_keep[i].value = strdup(getenv(env_keep[i].name)); |
|
|
|
|
if (!env_keep[i].value) |
|
|
|
|
die("strdup:"); |
|
|
|
|
} |
|
|
|
|
for (int i = 0; env_keep[i].name; i++) |
|
|
|
|
env_keep[i].value = estrdup(getenv(env_keep[i].name)); |
|
|
|
|
environ = NULL; // in place of clearenv
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -285,9 +277,6 @@ static int authenticate(uid_t uid, char ask) |
|
|
|
|
char *p = pw->pw_passwd; |
|
|
|
|
int tty_fd = STDOUT_FILENO; |
|
|
|
|
|
|
|
|
|
// but we have to be root
|
|
|
|
|
if (setuid(0) == -1) |
|
|
|
|
die("setreuid:"); |
|
|
|
|
if (!strcmp(p, "x") || *p == '*' || *p == '!') { |
|
|
|
|
#if defined(__linux__) |
|
|
|
|
// get exclusive access to shadow
|
|
|
|
@ -300,8 +289,6 @@ static int authenticate(uid_t uid, char ask) |
|
|
|
|
hash_p = sp->sp_pwdp; |
|
|
|
|
endspent(); |
|
|
|
|
ulckpwdf(); |
|
|
|
|
// if (setuid(uid) == -1)
|
|
|
|
|
// die("setreuid:");
|
|
|
|
|
#elif defined(__OpenBSD__) |
|
|
|
|
// TODO: openbsd has getpwuid_passwd
|
|
|
|
|
struct passwd *op = getpwuid_shadow(uid); |
|
|
|
@ -469,3 +456,22 @@ void die(const char *fmt, ...) |
|
|
|
|
exit(errno ? errno : EXIT_FAILURE); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void *emalloc(size_t s) |
|
|
|
|
{ |
|
|
|
|
if (!s || s == (size_t)-1) |
|
|
|
|
die("bad malloc: invalid size"); |
|
|
|
|
void *p = malloc(s); |
|
|
|
|
if (!p) |
|
|
|
|
die("bad malloc:"); |
|
|
|
|
return p; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
char *estrdup(const char *s) |
|
|
|
|
{ |
|
|
|
|
if (!s) |
|
|
|
|
die("bad strdup: cannot duplicate NULL pointer"); |
|
|
|
|
char *r = strdup(s); |
|
|
|
|
if (!r) |
|
|
|
|
die("bad strdup:"); |
|
|
|
|
return r; |
|
|
|
|
} |
|
|
|
|