diff options
author | Tobias Stoeckmann <tobias@stoeckmann.org> | 2023-11-11 23:34:28 +0100 |
---|---|---|
committer | Dmitry V. Levin <github.dl@altlinux.org> | 2023-11-13 10:38:36 +0000 |
commit | f800c5a8533003be7df56e6253821cf145f1a725 (patch) | |
tree | 1590545d2d4976cf958c843d0bcfa7236fe0bad8 /modules/pam_shells | |
parent | 32e4039784ba32a54406688b5bb71d3069381648 (diff) | |
download | pam-f800c5a8533003be7df56e6253821cf145f1a725.tar.gz pam-f800c5a8533003be7df56e6253821cf145f1a725.tar.bz2 pam-f800c5a8533003be7df56e6253821cf145f1a725.zip |
pam_shells: limit shells to absolute paths
Only allow shells with absolute paths. Also handle line truncations
which could occur with fgets by prefering getline/getdelim.
Signed-off-by: Tobias Stoeckmann <tobias@stoeckmann.org>
Diffstat (limited to 'modules/pam_shells')
-rw-r--r-- | modules/pam_shells/pam_shells.c | 48 |
1 files changed, 41 insertions, 7 deletions
diff --git a/modules/pam_shells/pam_shells.c b/modules/pam_shells/pam_shells.c index 276a56dd..54875704 100644 --- a/modules/pam_shells/pam_shells.c +++ b/modules/pam_shells/pam_shells.c @@ -8,6 +8,7 @@ #include "config.h" +#include <limits.h> #include <pwd.h> #include <stdarg.h> #include <string.h> @@ -115,8 +116,8 @@ static int perform_check(pam_handle_t *pamh) econf_free (keys); econf_free (key_file); #else - char shellFileLine[256]; - FILE * shellFile; + FILE *shellFile; + char *p = NULL; if (!check_file(SHELL_FILE, pamh)) return PAM_AUTH_ERR; @@ -129,14 +130,47 @@ static int perform_check(pam_handle_t *pamh) retval = 1; - while(retval && (fgets(shellFileLine, 255, shellFile) != NULL)) { - if (shellFileLine[strlen(shellFileLine) - 1] == '\n') - shellFileLine[strlen(shellFileLine) - 1] = '\0'; - retval = strcmp(shellFileLine, userShell); +#if defined(HAVE_GETLINE) || defined (HAVE_GETDELIM) + size_t n = 0; + + while (retval && +#if defined(HAVE_GETLINE) + getline(&p, &n, shellFile) +#elif defined (HAVE_GETDELIM) + getdelim(&p, &n, '\n', shellFile) +#endif + != -1) { + + if (p[0] != '/') { + continue; + } + retval = strcmp(p, userShell); + } + + free(p); +#else + char buf[PATH_MAX + 2]; + int ignore = 0; + + while (retval && fgets(buf, sizeof(buf), shellFile) != NULL) { + p = strchr(buf, '\n'); + if (p == NULL) { + ignore = 1; + continue; + } else if (ignore) { + ignore = 0; + continue; + } + + if (buf[0] != '/') { + continue; + } + retval = strcmp(buf, userShell); } +#endif fclose(shellFile); - #endif +#endif if (retval) { return PAM_AUTH_ERR; |