|
|
@ -39,14 +39,55 @@ static struct pam_conv conv = {misc_conv, NULL}; |
|
|
|
|
|
|
|
|
|
|
|
int main (int argc, char *argv[]) |
|
|
|
int main (int argc, char *argv[]) |
|
|
|
{ |
|
|
|
{ |
|
|
|
|
|
|
|
// TODO: Add arguments
|
|
|
|
// FIXME: change the default program to execute SHELL
|
|
|
|
// FIXME: change the default program to execute SHELL
|
|
|
|
if (argc < 2) { |
|
|
|
char *t_usr = NULL, *t_grp = NULL; |
|
|
|
|
|
|
|
int opt; |
|
|
|
|
|
|
|
while ((opt = getopt(argc, argv, "A:u:g:C:")) != -1) { |
|
|
|
|
|
|
|
switch (opt) { |
|
|
|
|
|
|
|
case 'A': |
|
|
|
|
|
|
|
printf("-A is not yet implemented\n"); |
|
|
|
|
|
|
|
exit(EXIT_FAILURE); |
|
|
|
|
|
|
|
break; |
|
|
|
|
|
|
|
case 'u': |
|
|
|
|
|
|
|
t_usr = optarg; |
|
|
|
|
|
|
|
break; |
|
|
|
|
|
|
|
case 'g': |
|
|
|
|
|
|
|
t_grp = optarg; |
|
|
|
|
|
|
|
break; |
|
|
|
|
|
|
|
case 'C': |
|
|
|
|
|
|
|
printf("-C is not yet implemented\n"); |
|
|
|
|
|
|
|
exit(EXIT_FAILURE); |
|
|
|
|
|
|
|
break; |
|
|
|
|
|
|
|
case '?': |
|
|
|
|
|
|
|
usage(); |
|
|
|
|
|
|
|
exit(EINVAL); |
|
|
|
|
|
|
|
break; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Copy argv and argc
|
|
|
|
|
|
|
|
int c_argc = argc - optind; |
|
|
|
|
|
|
|
char **c_argv = malloc((c_argc + 1) * sizeof(char *)); |
|
|
|
|
|
|
|
if (!c_argv) { |
|
|
|
|
|
|
|
fprintf(stderr, "malloc: %s\n", strerror(errno)); |
|
|
|
|
|
|
|
goto fail_end; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
for (int i = 0; optind < argc; i++, optind++) { |
|
|
|
|
|
|
|
c_argv[i] = strdup(argv[optind]); |
|
|
|
|
|
|
|
if (!c_argv[i]) { |
|
|
|
|
|
|
|
fprintf(stderr, "getpwid: %s\n", strerror(errno)); |
|
|
|
|
|
|
|
exit(errno); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
c_argc[c_argv] = NULL; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (c_argc == 0) { |
|
|
|
usage(); |
|
|
|
usage(); |
|
|
|
exit(1); |
|
|
|
exit(EINVAL); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
uid_t ruid = getuid(); |
|
|
|
uid_t ruid = getuid(); |
|
|
|
// gid_t rgid = getgid();
|
|
|
|
|
|
|
|
struct passwd *pw = getpwuid(ruid); |
|
|
|
struct passwd *pw = getpwuid(ruid); |
|
|
|
if (!pw) { |
|
|
|
if (!pw) { |
|
|
|
fprintf(stderr, "getpwid: %s\n", strerror(errno)); |
|
|
|
fprintf(stderr, "getpwid: %s\n", strerror(errno)); |
|
|
@ -56,10 +97,6 @@ int main (int argc, char *argv[]) |
|
|
|
|
|
|
|
|
|
|
|
pam_handle_t *pamh; |
|
|
|
pam_handle_t *pamh; |
|
|
|
int pam_err, count = 0; |
|
|
|
int pam_err, count = 0; |
|
|
|
|
|
|
|
|
|
|
|
// TODO: Add arguments
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// TODO: add PAM authentication
|
|
|
|
|
|
|
|
pam_err = pam_start("User Switcher", uname, &conv, &pamh); |
|
|
|
pam_err = pam_start("User Switcher", uname, &conv, &pamh); |
|
|
|
if (pam_err != PAM_SUCCESS) { |
|
|
|
if (pam_err != PAM_SUCCESS) { |
|
|
|
fprintf(stderr, "pam_start: %s\n", pam_strerror(pamh, pam_err)); |
|
|
|
fprintf(stderr, "pam_start: %s\n", pam_strerror(pamh, pam_err)); |
|
|
@ -85,20 +122,9 @@ int main (int argc, char *argv[]) |
|
|
|
pam_end(pamh, pam_err); |
|
|
|
pam_end(pamh, pam_err); |
|
|
|
// TODO: clean up env
|
|
|
|
// TODO: clean up env
|
|
|
|
|
|
|
|
|
|
|
|
// Copy argv and argc
|
|
|
|
|
|
|
|
int c_argc = argc - 1; |
|
|
|
|
|
|
|
char **c_argv = malloc((c_argc + 1) * sizeof(char *)); |
|
|
|
|
|
|
|
if (!c_argv) { |
|
|
|
|
|
|
|
fprintf(stderr, "malloc: %s\n", strerror(errno)); |
|
|
|
|
|
|
|
goto fail_end; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
for (int i = 0; i < c_argc; i++) |
|
|
|
|
|
|
|
c_argv[i] = strdup(argv[i+1]); |
|
|
|
|
|
|
|
c_argc[c_argv] = NULL; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
errno = 0; |
|
|
|
errno = 0; |
|
|
|
/* Set permissions */ |
|
|
|
/* Set permissions */ |
|
|
|
if (perm_set(NULL, NULL) == -1) { // 0 = root
|
|
|
|
if (perm_set(t_usr, t_grp) == -1) { // 0 = root
|
|
|
|
fprintf(stderr, "perm_set: %s\n", strerror(errno)); |
|
|
|
fprintf(stderr, "perm_set: %s\n", strerror(errno)); |
|
|
|
goto fail_end; |
|
|
|
goto fail_end; |
|
|
|
} |
|
|
|
} |
|
|
@ -107,17 +133,8 @@ int main (int argc, char *argv[]) |
|
|
|
if (execvp(*c_argv, c_argv) == -1) // execvp searches in path
|
|
|
|
if (execvp(*c_argv, c_argv) == -1) // execvp searches in path
|
|
|
|
fprintf(stderr, "execv: %s\n", strerror(errno)); |
|
|
|
fprintf(stderr, "execv: %s\n", strerror(errno)); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* We may no longer have permission to reset the permissions
|
|
|
|
|
|
|
|
// If exec fails reset the permissions
|
|
|
|
|
|
|
|
if (perm_set(pw->pw_name, NULL) == -1) { // 0 = root
|
|
|
|
|
|
|
|
fprintf(stderr, "perm_set: %s\n", strerror(errno)); |
|
|
|
|
|
|
|
goto fail_end; |
|
|
|
|
|
|
|
} */ |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Cleanup and return */ |
|
|
|
/* Cleanup and return */ |
|
|
|
fail_end: |
|
|
|
fail_end: |
|
|
|
|
|
|
|
|
|
|
|
/* Free up the copied argv */ |
|
|
|
/* Free up the copied argv */ |
|
|
|
for (int i = 0; i < c_argc; i++) |
|
|
|
for (int i = 0; i < c_argc; i++) |
|
|
|
free(c_argv[i]); |
|
|
|
free(c_argv[i]); |
|
|
@ -135,7 +152,7 @@ static inline void usage (void) |
|
|
|
// -c [file]: manually select config file
|
|
|
|
// -c [file]: manually select config file
|
|
|
|
// something about environment
|
|
|
|
// something about environment
|
|
|
|
// something about non interactiveness
|
|
|
|
// something about non interactiveness
|
|
|
|
printf("usage: us [command]\n"); |
|
|
|
printf("usage: us [-u user] [-g group] command [args]\n"); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
static int perm_set (const char *user, const char *group) |
|
|
|
static int perm_set (const char *user, const char *group) |
|
|
|