diff options
| author | Mattias Andrée <maandree@operamail.com> | 2013-11-19 01:08:57 +0100 | 
|---|---|---|
| committer | Mattias Andrée <maandree@operamail.com> | 2013-11-19 01:08:57 +0100 | 
| commit | db52f5cb409b9df43f9d231f78339f7787d9c7a4 (patch) | |
| tree | 0096c258ea06cb2693846bae1a904a93a1a9b36f | |
| parent | m + redisable echo when the tty has been reopened (diff) | |
| download | libpassphrase-db52f5cb409b9df43f9d231f78339f7787d9c7a4.tar.gz libpassphrase-db52f5cb409b9df43f9d231f78339f7787d9c7a4.tar.bz2 libpassphrase-db52f5cb409b9df43f9d231f78339f7787d9c7a4.tar.xz  | |
move exec instructions into login.c
Signed-off-by: Mattias Andrée <maandree@operamail.com>
Diffstat (limited to '')
| -rw-r--r-- | src/cerberus.c | 60 | ||||
| -rw-r--r-- | src/cerberus.h | 1 | ||||
| -rw-r--r-- | src/login.c | 60 | ||||
| -rw-r--r-- | src/login.h | 7 | 
4 files changed, 73 insertions, 55 deletions
diff --git a/src/cerberus.c b/src/cerberus.c index ce60846..a4fa33d 100644 --- a/src/cerberus.c +++ b/src/cerberus.c @@ -40,6 +40,7 @@ int main(int argc, char** argv)    struct group* group;    #endif    struct passwd* entry; +  pid_t child_pid;    /* Disable echoing */ @@ -190,75 +191,26 @@ int main(int argc, char** argv)    set_environ(entry, preserve_env);    { -    pid_t pid = fork(); +    child_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) +    if (child_pid == -1)        {  	perror("fork");  	return 1;        } -    else if (pid == 0) +    else if (child_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); +	exec_shell(entry);        }      else        {  	int _status; -	waitpid(pid, &_status, 0); +	waitpid(child_pid, &_status, 0);  	/* Reset terminal ownership and mode */  	chown_tty(0, tty_group, 0); diff --git a/src/cerberus.h b/src/cerberus.h index b5501a4..e195245 100644 --- a/src/cerberus.h +++ b/src/cerberus.h @@ -24,7 +24,6 @@  #include <stdlib.h>  #include <unistd.h>  #include <signal.h> -#include <string.h>  #include <pwd.h>  #include <errno.h>  #include <sys/wait.h> diff --git a/src/login.c b/src/login.c index 46bf4e2..3ad1204 100644 --- a/src/login.c +++ b/src/login.c @@ -20,6 +20,7 @@  #include <stdlib.h>  #include <stdio.h>  #include <unistd.h> +#include <string.h>  #include "config.h" @@ -135,3 +136,62 @@ void set_environ(struct passwd* entry, char preserve_env)      free(term);  } + +/** + * Replace the current image with the user's login shell + *  + * @param  entry  The user entry in the password file + */ +void exec_shell(struct passwd* entry) +{ +  int child_argc = 0; +  char** child_argv = malloc(5 * sizeof(char*)); +  long n = 0; +  char* sh = entry->pw_shell; +  char* login_sh; +   +  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); +} + diff --git a/src/login.h b/src/login.h index 14014f2..e335e7c 100644 --- a/src/login.h +++ b/src/login.h @@ -51,6 +51,13 @@ void ensure_shell(struct passwd* entry);   */  void set_environ(struct passwd* entry, char preserve_env); +/** + * Replace the current image with the user's login shell + *  + * @param  entry  The user entry in the password file + */ +void exec_shell(struct passwd* entry); +  #endif  | 
