diff options
author | Mattias Andrée <maandree@operamail.com> | 2013-11-19 00:23:59 +0100 |
---|---|---|
committer | Mattias Andrée <maandree@operamail.com> | 2013-11-19 00:23:59 +0100 |
commit | 11b8c55bc9c9ac3639cda50e5f3e15d6eb4443a3 (patch) | |
tree | 6d0cdb5a627020c64d77207fbc2594ff6cf9b89e /src/cerberus.c | |
parent | m (diff) | |
download | libpassphrase-11b8c55bc9c9ac3639cda50e5f3e15d6eb4443a3.tar.gz libpassphrase-11b8c55bc9c9ac3639cda50e5f3e15d6eb4443a3.tar.bz2 libpassphrase-11b8c55bc9c9ac3639cda50e5f3e15d6eb4443a3.tar.xz |
m + spawn shell
Signed-off-by: Mattias Andrée <maandree@operamail.com>
Diffstat (limited to 'src/cerberus.c')
-rw-r--r-- | src/cerberus.c | 85 |
1 files changed, 78 insertions, 7 deletions
diff --git a/src/cerberus.c b/src/cerberus.c index f60f64c..3a5dd5d 100644 --- a/src/cerberus.c +++ b/src/cerberus.c @@ -36,7 +36,7 @@ int main(int argc, char** argv) char preserve_env = 0; char skip_auth = 0; #ifdef USE_TTY_GROUP - gid_t tty_group = 0; + static gid_t tty_group = 0; struct group* group; #endif struct passwd* entry; @@ -179,17 +179,88 @@ int main(int argc, char** argv) reenable_echo(); - /* Login */ + /* Partial login */ /* TODO verify that user is enabled */ - set_user(entry); - /* TODO set supplemental groups */ + chown_tty(entry->pw_uid, tty_group, 0); chdir_home(entry); ensure_shell(entry); set_environ(entry, preserve_env); - - /* Reset terminal ownership and mode */ - chown_tty(0, tty_group, 0); + { + pid_t pid = fork(); + /* vfork cannot be used as the child changes the user, + the parent would not be able to chown the TTY */ + + if (pid == -1) + { + perror("fork"); + return 1; + } + else if (pid == 0) + { + int child_argc = 0; + char** child_argv = malloc(5 * sizeof(char*)); + int n = 0; + char* sh = entry->pw_shell; + char* login_sh; + + /* Partial login */ + /* TODO set supplemental groups */ + set_user(entry); + + while (*(sh + n++)) + ; + + login_sh = malloc((n + (strchr(sh, ' ') ? 5 : 1)) * sizeof(char)); + if (login_sh == NULL) + { + perror("malloc"); + sleep(ERROR_SLEEP); + _exit(1); + } + + if (strchr(sh, ' ')) + { + login_sh += 5; + strcpy(login_sh, "exec "); + *(login_sh + n) = 0; + + *(child_argv + child_argc++) = DEFAULT_SHELL; + *(child_argv + child_argc++) = "-" DEFAULT_SH; + *(child_argv + child_argc++) = "-c"; + *(child_argv + child_argc++) = login_sh - 5; + } + else + { + int i; + for (i = n - 1; i >= 0; i--) + if (*(sh + i) == '/') + { + i++; + break; + } + + login_sh = malloc((n + 1) * sizeof(char)); + *login_sh++ = '-'; + strcpy(login_sh, sh + i); + *(login_sh + n) = 0; + + *(child_argv + child_argc++) = sh; + *(child_argv + child_argc++) = login_sh - 1; + } + + *(child_argv + child_argc) = NULL; + execvp(*child_argv, child_argv + 1); + } + else + { + int _status; + waitpid(pid, &_status, 0); + + /* Reset terminal ownership and mode */ + chown_tty(0, tty_group, 0); + } + } return 0; } |