logo

skeud

Simple and portable utilities to deal with user accounts (su, login)
commit: 285c64f0fdcb2f69022291aceb74b5ea9b822725
parent 7ea8455aaa574504026dc6d1dcea50fc29a9f6d3
Author: Haelwenn (lanodan) Monnier <contact@hacktivis.me>
Date:   Sun, 10 Sep 2023 15:50:33 +0200

su: Fail if pwent is NULL, drop reading $SHELL

Diffstat:

Msu.c77+++++++++++++++++++++++++++++++++++++++--------------------------------------
1 file changed, 39 insertions(+), 38 deletions(-)

diff --git a/su.c b/su.c @@ -116,17 +116,38 @@ main(int argc, char *argv[]) errno = 0; pwent = getpwnam(username); - if(errno != 0) + if(pwent == NULL) { - perror("su: getpwnam"); + if(errno != 0) + { + perror("su: getpwnam"); + } + else + { + fprintf(stderr, "su: getpwnam: No entry found for user %s\n", username); + } + return 1; } + if(shell == NULL) + { + if(pwent->pw_shell) + { + shell = pwent->pw_shell; + } + else + { + fprintf(stderr, "su: No shell entry for user %s\n", username); + } + } + fprintf(stderr, "su: Authenticating as %s\n", username); + if(getuid() != 0) { char *pw_hash = NULL; - if(pwent && pwent->pw_passwd) + if(pwent->pw_passwd) { pw_hash = pwent->pw_passwd; } @@ -141,8 +162,7 @@ main(int argc, char *argv[]) } else { - - if(pw_hash && strcmp(pw_hash, "x") == 0) + if(pw_hash && pw_hash[0] == 'x' && pw_hash[1] == 0) { pw_hash = swent->sp_pwdp; } @@ -183,47 +203,28 @@ main(int argc, char *argv[]) } } - if(pwent != NULL) + if(setgid(pwent->pw_gid) < 0) { - if(setgid(pwent->pw_gid) < 0) - { - perror("su: setgid"); - } - if(setuid(pwent->pw_uid) < 0) - { - perror("su: setuid"); - } - - if(pwent->pw_shell != NULL) - { - shell = pwent->pw_shell; - } - - if(pwent->pw_dir != NULL) - { - setenv("HOME", pwent->pw_dir, 1); - - if(opt_l) - { - if(chdir(pwent->pw_dir) != 0) perror("su: chdir"); - } - } - - explicit_bzero(pwent, sizeof(pwent)); - pwent = NULL; + perror("su: setgid"); } - - if(shell == NULL) + if(setuid(pwent->pw_uid) < 0) { - /* flawfinder: CWE-807, CWE-20 */ - shell = getenv("SHELL"); + perror("su: setuid"); } - if(shell == NULL) + if(pwent->pw_dir != NULL) { - shell = "/bin/sh"; + setenv("HOME", pwent->pw_dir, 1); + + if(opt_l) + { + if(chdir(pwent->pw_dir) != 0) perror("su: chdir"); + } } + explicit_bzero(pwent, sizeof(pwent)); + pwent = NULL; + setenv("USER", username, 1); setenv("LOGNAME", username, 1); setenv("SHELL", shell, 1);