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 | |
| 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 '')
| -rw-r--r-- | src/cerberus.c | 85 | ||||
| -rw-r--r-- | src/cerberus.h | 2 | 
2 files changed, 80 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;  } diff --git a/src/cerberus.h b/src/cerberus.h index a4ba19a..b5501a4 100644 --- a/src/cerberus.h +++ b/src/cerberus.h @@ -24,8 +24,10 @@  #include <stdlib.h>  #include <unistd.h>  #include <signal.h> +#include <string.h>  #include <pwd.h>  #include <errno.h> +#include <sys/wait.h>  #ifdef USE_TTY_GROUP  #include <grp.h>  #endif | 
