diff options
author | Dmitry V. Levin <ldv@altlinux.org> | 2010-09-28 17:11:36 +0000 |
---|---|---|
committer | Dmitry V. Levin <ldv@altlinux.org> | 2010-09-28 17:11:36 +0000 |
commit | cad7f9be856ff813848f0048db056cf076d1b7af (patch) | |
tree | 6f8c0aa6a77c79bf2aaa0b0d0b3ad6d080bd264b /modules/pam_xauth/pam_xauth.c | |
parent | e2f2489b397720eaf176aaa16c7188ee92050dd8 (diff) | |
download | pam-cad7f9be856ff813848f0048db056cf076d1b7af.tar.gz pam-cad7f9be856ff813848f0048db056cf076d1b7af.tar.bz2 pam-cad7f9be856ff813848f0048db056cf076d1b7af.zip |
Relevant BUGIDs:
Purpose of commit: bugfix
Commit summary:
---------------
2010-09-27 Dmitry V. Levin <ldv@altlinux.org>
* modules/pam_xauth/pam_xauth.c (check_acl): Check that the given
access control file is a regular file.
Diffstat (limited to 'modules/pam_xauth/pam_xauth.c')
-rw-r--r-- | modules/pam_xauth/pam_xauth.c | 29 |
1 files changed, 25 insertions, 4 deletions
diff --git a/modules/pam_xauth/pam_xauth.c b/modules/pam_xauth/pam_xauth.c index 05ed6ee9..591dc85d 100644 --- a/modules/pam_xauth/pam_xauth.c +++ b/modules/pam_xauth/pam_xauth.c @@ -37,6 +37,9 @@ #include <sys/types.h> #include <sys/fsuid.h> #include <sys/wait.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <unistd.h> #include <errno.h> #include <fnmatch.h> #include <grp.h> @@ -232,9 +235,10 @@ check_acl(pam_handle_t *pamh, { char path[PATH_MAX]; struct passwd *pwd; - FILE *fp; - int i, save_errno; + FILE *fp = NULL; + int i, fd = -1, save_errno; uid_t fsuid; + struct stat st; /* Check this user's <sense> file. */ pwd = pam_modutil_getpwnam(pamh, this_user); if (pwd == NULL) { @@ -251,10 +255,27 @@ check_acl(pam_handle_t *pamh, return PAM_SESSION_ERR; } fsuid = setfsuid(pwd->pw_uid); - fp = fopen(path, "r"); + if (!stat(path, &st)) { + if (!S_ISREG(st.st_mode)) + errno = EINVAL; + else + fd = open(path, O_RDONLY | O_NOCTTY); + } save_errno = errno; setfsuid(fsuid); - if (fp != NULL) { + if (fd >= 0) { + if (!fstat(fd, &st)) { + if (!S_ISREG(st.st_mode)) + errno = EINVAL; + else + fp = fdopen(fd, "r"); + } + if (!fp) { + save_errno = errno; + close(fd); + } + } + if (fp) { char buf[LINE_MAX], *tmp; /* Scan the file for a list of specs of users to "trust". */ while (fgets(buf, sizeof(buf), fp) != NULL) { |