summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog14
-rw-r--r--modules/pam_env/pam_env.c9
-rw-r--r--modules/pam_mail/pam_mail.c57
-rw-r--r--modules/pam_xauth/pam_xauth.c35
4 files changed, 76 insertions, 39 deletions
diff --git a/ChangeLog b/ChangeLog
index 86e3ae13..da8193dd 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,17 @@
+2010-08-12 Thorsten Kukuk <kukuk@thkukuk.de>
+
+ * modules/pam_mail/pam_mail.c: Check for mail only with user
+ privilegs.
+
+ * modules/pam_xauth/pam_xauth.c (run_coprocess): Check return
+ value of setgid, setgroups and setuid.
+
+ * modules/pam_xauth/pam_xauth.c (check_acl): Save errno for
+ later usage.
+
+ * modules/pam_env/pam_env.c (handle_env): Check if user exists,
+ read local user config only with user privilegs.`
+
2010-08-09 Thorsten Kukuk <kukuk@thkukuk.de>
* modules/pam_tally/pam_tally.8.xml: Document that pam_tally is
diff --git a/modules/pam_env/pam_env.c b/modules/pam_env/pam_env.c
index 84953104..4e5f6eb3 100644
--- a/modules/pam_env/pam_env.c
+++ b/modules/pam_env/pam_env.c
@@ -23,6 +23,7 @@
#include <string.h>
#include <syslog.h>
#include <sys/stat.h>
+#include <sys/fsuid.h>
#include <sys/types.h>
#include <unistd.h>
@@ -772,13 +773,14 @@ handle_env (pam_handle_t *pamh, int argc, const char **argv)
if(user_readenv && retval == PAM_SUCCESS) {
char *envpath = NULL;
- struct passwd *user_entry;
+ struct passwd *user_entry = NULL;
const char *username;
struct stat statbuf;
username = _pam_get_item_byname(pamh, "PAM_USER");
- user_entry = pam_modutil_getpwnam (pamh, username);
+ if (username)
+ user_entry = pam_modutil_getpwnam (pamh, username);
if (!user_entry) {
pam_syslog(pamh, LOG_ERR, "No such user!?");
}
@@ -789,7 +791,10 @@ handle_env (pam_handle_t *pamh, int argc, const char **argv)
return PAM_BUF_ERR;
}
if (stat(envpath, &statbuf) == 0) {
+ uid_t euid = geteuid();
+ setfsuid (user_entry->pw_uid);
retval = _parse_config_file(pamh, envpath);
+ setfsuid (euid);
if (retval == PAM_IGNORE)
retval = PAM_SUCCESS;
}
diff --git a/modules/pam_mail/pam_mail.c b/modules/pam_mail/pam_mail.c
index a5473605..089c398c 100644
--- a/modules/pam_mail/pam_mail.c
+++ b/modules/pam_mail/pam_mail.c
@@ -17,6 +17,7 @@
#include <syslog.h>
#include <sys/stat.h>
#include <sys/types.h>
+#include <sys/fsuid.h>
#include <unistd.h>
#include <dirent.h>
#include <errno.h>
@@ -124,29 +125,16 @@ _pam_parse (const pam_handle_t *pamh, int flags, int argc,
static int
get_folder(pam_handle_t *pamh, int ctrl,
- const char *path_mail, char **folder_p, size_t hashcount)
+ const char *path_mail, char **folder_p, size_t hashcount,
+ const struct passwd *pwd)
{
int retval;
- const char *user, *path;
+ const char *path;
char *folder = NULL;
- const struct passwd *pwd = NULL;
-
- retval = pam_get_user(pamh, &user, NULL);
- if (retval != PAM_SUCCESS || user == NULL) {
- pam_syslog(pamh, LOG_ERR, "cannot determine username");
- retval = PAM_USER_UNKNOWN;
- goto get_folder_cleanup;
- }
if (ctrl & PAM_NEW_MAIL_DIR) {
path = path_mail;
if (*path == '~') { /* support for $HOME delivery */
- pwd = pam_modutil_getpwnam(pamh, user);
- if (pwd == NULL) {
- pam_syslog(pamh, LOG_ERR, "user unknown");
- retval = PAM_USER_UNKNOWN;
- goto get_folder_cleanup;
- }
/*
* "~/xxx" and "~xxx" are treated as same
*/
@@ -168,18 +156,11 @@ get_folder(pam_handle_t *pamh, int ctrl,
/* put folder together */
- hashcount = hashcount < strlen(user) ? hashcount : strlen(user);
+ hashcount = hashcount < strlen(pwd->pw_name) ?
+ hashcount : strlen(pwd->pw_name);
retval = PAM_BUF_ERR;
if (ctrl & PAM_HOME_MAIL) {
- if (pwd == NULL) {
- pwd = pam_modutil_getpwnam(pamh, user);
- if (pwd == NULL) {
- pam_syslog(pamh, LOG_ERR, "user unknown");
- retval = PAM_USER_UNKNOWN;
- goto get_folder_cleanup;
- }
- }
if (asprintf(&folder, MAIL_FILE_FORMAT, pwd->pw_dir, "", path) < 0)
goto get_folder_cleanup;
} else {
@@ -192,11 +173,11 @@ get_folder(pam_handle_t *pamh, int ctrl,
for (i = 0; i < hashcount; i++) {
hash[2 * i] = '/';
- hash[2 * i + 1] = user[i];
+ hash[2 * i + 1] = pwd->pw_name[i];
}
hash[2 * i] = '\0';
- rc = asprintf(&folder, MAIL_FILE_FORMAT, path, hash, user);
+ rc = asprintf(&folder, MAIL_FILE_FORMAT, path, hash, pwd->pw_name);
_pam_overwrite(hash);
_pam_drop(hash);
if (rc < 0)
@@ -208,7 +189,6 @@ get_folder(pam_handle_t *pamh, int ctrl,
/* tidy up */
get_folder_cleanup:
- user = NULL;
path = NULL;
*folder_p = folder;
@@ -402,7 +382,9 @@ static int _do_mail(pam_handle_t *pamh, int flags, int argc,
int retval, ctrl, type;
size_t hashcount;
char *folder = NULL;
+ const char *user;
const char *path_mail = NULL;
+ const struct passwd *pwd = NULL;
/*
* this module (un)sets the MAIL environment variable, and checks if
@@ -411,9 +393,21 @@ static int _do_mail(pam_handle_t *pamh, int flags, int argc,
ctrl = _pam_parse(pamh, flags, argc, argv, &path_mail, &hashcount);
+ retval = pam_get_user(pamh, &user, NULL);
+ if (retval != PAM_SUCCESS || user == NULL) {
+ pam_syslog(pamh, LOG_ERR, "cannot determine username");
+ return PAM_USER_UNKNOWN;
+ }
+
+ pwd = pam_modutil_getpwnam (pamh, user);
+ if (pwd == NULL) {
+ pam_syslog(pamh, LOG_ERR, "user unknown");
+ return PAM_USER_UNKNOWN;
+ }
+
/* which folder? */
- retval = get_folder(pamh, ctrl, path_mail, &folder, hashcount);
+ retval = get_folder(pamh, ctrl, path_mail, &folder, hashcount, pwd);
if (retval != PAM_SUCCESS) {
D(("failed to find folder"));
return retval;
@@ -450,7 +444,12 @@ static int _do_mail(pam_handle_t *pamh, int flags, int argc,
if ((est && !(ctrl & PAM_NO_LOGIN))
|| (!est && (ctrl & PAM_LOGOUT_TOO))) {
+ uid_t euid = geteuid();
+
+ setfsuid (pwd->pw_uid);
type = get_mail_status(pamh, ctrl, folder);
+ setfsuid (euid);
+
if (type != 0) {
retval = report_mail(pamh, ctrl, type, folder);
type = 0;
diff --git a/modules/pam_xauth/pam_xauth.c b/modules/pam_xauth/pam_xauth.c
index 61bd5a91..07ece647 100644
--- a/modules/pam_xauth/pam_xauth.c
+++ b/modules/pam_xauth/pam_xauth.c
@@ -87,7 +87,7 @@ static const char * const xauthpaths[] = {
/* Run a given command (with a NULL-terminated argument list), feeding it the
* given input on stdin, and storing any output it generates. */
static int
-run_coprocess(const char *input, char **output,
+run_coprocess(pam_handle_t *pamh, const char *input, char **output,
uid_t uid, gid_t gid, const char *command, ...)
{
int ipipe[2], opipe[2], i;
@@ -126,9 +126,26 @@ run_coprocess(const char *input, char **output,
const char *tmp;
int maxopened;
/* Drop privileges. */
- setgid(gid);
- setgroups(0, NULL);
- setuid(uid);
+ if (setgid(gid) == -1)
+ {
+ int err = errno;
+ pam_syslog (pamh, LOG_ERR, "setgid(%lu) failed: %m",
+ (unsigned long) getegid ());
+ _exit (err);
+ }
+ if (setgroups(0, NULL) == -1)
+ {
+ int err = errno;
+ pam_syslog (pamh, LOG_ERR, "setgroups() failed: %m");
+ _exit (err);
+ }
+ if (setuid(uid) == -1)
+ {
+ int err = errno;
+ pam_syslog (pamh, LOG_ERR, "setuid(%lu) failed: %m",
+ (unsigned long) geteuid ());
+ _exit (err);
+ }
/* Initialize the argument list. */
memset(args, 0, sizeof(args));
/* Set the pipe descriptors up as stdin and stdout, and close
@@ -216,7 +233,7 @@ check_acl(pam_handle_t *pamh,
char path[PATH_MAX];
struct passwd *pwd;
FILE *fp;
- int i;
+ int i, save_errno;
uid_t euid;
/* Check this user's <sense> file. */
pwd = pam_modutil_getpwnam(pamh, this_user);
@@ -236,6 +253,7 @@ check_acl(pam_handle_t *pamh,
euid = geteuid();
setfsuid(pwd->pw_uid);
fp = fopen(path, "r");
+ save_errno = errno;
setfsuid(euid);
if (fp != NULL) {
char buf[LINE_MAX], *tmp;
@@ -268,6 +286,7 @@ check_acl(pam_handle_t *pamh,
return PAM_PERM_DENIED;
} else {
/* Default to okay if the file doesn't exist. */
+ errno = save_errno;
switch (errno) {
case ENOENT:
if (noent_code == PAM_SUCCESS) {
@@ -463,7 +482,7 @@ pam_sm_open_session (pam_handle_t *pamh, int flags UNUSED,
xauth, "-f", cookiefile, "nlist", display,
(unsigned long) getuid(), (unsigned long) getgid());
}
- if (run_coprocess(NULL, &cookie,
+ if (run_coprocess(pamh, NULL, &cookie,
getuid(), getgid(),
xauth, "-f", cookiefile, "nlist", display,
NULL) == 0) {
@@ -521,7 +540,7 @@ pam_sm_open_session (pam_handle_t *pamh, int flags UNUSED,
(unsigned long) getuid(),
(unsigned long) getgid());
}
- run_coprocess(NULL, &cookie,
+ run_coprocess(pamh, NULL, &cookie,
getuid(), getgid(),
xauth, "-f", cookiefile,
"nlist", t, NULL);
@@ -671,7 +690,7 @@ pam_sm_open_session (pam_handle_t *pamh, int flags UNUSED,
(unsigned long) tpwd->pw_uid,
(unsigned long) tpwd->pw_gid);
}
- run_coprocess(cookie, &tmp,
+ run_coprocess(pamh, cookie, &tmp,
tpwd->pw_uid, tpwd->pw_gid,
xauth, "-f", cookiefile, "nmerge", "-", NULL);