parent
e30408c5d9
commit
d4ff57cf6f
@ -1,4 +1,4 @@
|
|||||||
*.src.rpm
|
*.src.rpm
|
||||||
*.tar.bz2
|
*.tar.bz2
|
||||||
pam-redhat-0.99.9-1.tar.bz2
|
pam-redhat-0.99.10-1.tar.bz2
|
||||||
Linux-PAM-1.0.2.tar.bz2
|
Linux-PAM-1.0.90.tar.bz2
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
Version: GnuPG v1.4.9 (GNU/Linux)
|
Version: GnuPG v1.4.9 (GNU/Linux)
|
||||||
Comment: See http://www.kernel.org/signature.html for info
|
Comment: See http://www.kernel.org/signature.html for info
|
||||||
|
|
||||||
iD8DBQBIt8Q3yGugalF9Dw4RAnJQAJ9hxQ8qCSTFxs0hKZnT1iuPIld0VwCfV4pa
|
iD8DBQBJQnT1yGugalF9Dw4RAmSGAKCOEjM9X5nFa21Ang/N5B9LdQ7f7wCfRPbd
|
||||||
mxTaEK08wwAQ2bYjsDhh01s=
|
a5H9INJU6W0Ymb4pOq9OFBM=
|
||||||
=rPNX
|
=V27P
|
||||||
-----END PGP SIGNATURE-----
|
-----END PGP SIGNATURE-----
|
@ -1,103 +0,0 @@
|
|||||||
diff -up Linux-PAM-0.99.10.0/modules/pam_unix/Makefile.am.audit-failed Linux-PAM-0.99.10.0/modules/pam_unix/Makefile.am
|
|
||||||
--- Linux-PAM-0.99.10.0/modules/pam_unix/Makefile.am.audit-failed 2008-02-06 15:21:34.000000000 +0100
|
|
||||||
+++ Linux-PAM-0.99.10.0/modules/pam_unix/Makefile.am 2008-02-22 16:11:02.000000000 +0100
|
|
||||||
@@ -53,7 +53,7 @@ unix_chkpwd_SOURCES = unix_chkpwd.c md5_
|
|
||||||
passverify.c
|
|
||||||
unix_chkpwd_CFLAGS = $(AM_CFLAGS) @PIE_CFLAGS@ -DHELPER_COMPILE=\"unix_chkpwd\"
|
|
||||||
unix_chkpwd_LDFLAGS = @PIE_LDFLAGS@
|
|
||||||
-unix_chkpwd_LDADD = @LIBCRYPT@ @LIBSELINUX@
|
|
||||||
+unix_chkpwd_LDADD = @LIBCRYPT@ @LIBSELINUX@ @LIBAUDIT@
|
|
||||||
|
|
||||||
unix_update_SOURCES = unix_update.c md5_good.c md5_broken.c bigcrypt.c \
|
|
||||||
passverify.c
|
|
||||||
diff -up Linux-PAM-0.99.10.0/modules/pam_unix/unix_chkpwd.c.audit-failed Linux-PAM-0.99.10.0/modules/pam_unix/unix_chkpwd.c
|
|
||||||
--- Linux-PAM-0.99.10.0/modules/pam_unix/unix_chkpwd.c.audit-failed 2008-02-22 15:39:03.000000000 +0100
|
|
||||||
+++ Linux-PAM-0.99.10.0/modules/pam_unix/unix_chkpwd.c 2008-02-22 16:34:29.000000000 +0100
|
|
||||||
@@ -24,6 +24,10 @@
|
|
||||||
#include <shadow.h>
|
|
||||||
#include <signal.h>
|
|
||||||
#include <time.h>
|
|
||||||
+#include <errno.h>
|
|
||||||
+#ifdef HAVE_LIBAUDIT
|
|
||||||
+#include <libaudit.h>
|
|
||||||
+#endif
|
|
||||||
|
|
||||||
#include <security/_pam_types.h>
|
|
||||||
#include <security/_pam_macros.h>
|
|
||||||
@@ -54,6 +58,37 @@ static int _check_expiry(const char *una
|
|
||||||
return retval;
|
|
||||||
}
|
|
||||||
|
|
||||||
+static int _audit_log(int type, const char *uname, int rc)
|
|
||||||
+{
|
|
||||||
+#ifdef HAVE_LIBAUDIT
|
|
||||||
+ int audit_fd;
|
|
||||||
+
|
|
||||||
+ audit_fd = audit_open();
|
|
||||||
+ if (audit_fd < 0) {
|
|
||||||
+ /* You get these error codes only when the kernel doesn't have
|
|
||||||
+ * audit compiled in. */
|
|
||||||
+ if (errno == EINVAL || errno == EPROTONOSUPPORT ||
|
|
||||||
+ errno == EAFNOSUPPORT)
|
|
||||||
+ return PAM_SUCCESS;
|
|
||||||
+
|
|
||||||
+ helper_log_err(LOG_CRIT, "audit_open() failed: %m");
|
|
||||||
+ return PAM_AUTH_ERR;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ rc = audit_log_acct_message(audit_fd, type, NULL, "PAM:unix_chkpwd",
|
|
||||||
+ uname, -1, NULL, NULL, NULL, rc == PAM_SUCCESS);
|
|
||||||
+ if (rc == -EPERM && geteuid() != 0) {
|
|
||||||
+ rc = 0;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ audit_close(audit_fd);
|
|
||||||
+
|
|
||||||
+ return rc < 0 ? PAM_AUTH_ERR : PAM_SUCCESS;
|
|
||||||
+#else
|
|
||||||
+ return PAM_SUCCESS;
|
|
||||||
+#endif
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
int main(int argc, char *argv[])
|
|
||||||
{
|
|
||||||
char pass[MAXPASS + 1];
|
|
||||||
@@ -82,6 +117,7 @@ int main(int argc, char *argv[])
|
|
||||||
helper_log_err(LOG_NOTICE
|
|
||||||
,"inappropriate use of Unix helper binary [UID=%d]"
|
|
||||||
,getuid());
|
|
||||||
+ _audit_log(AUDIT_ANOM_EXEC, getuidname(getuid()), PAM_SYSTEM_ERR);
|
|
||||||
fprintf(stderr
|
|
||||||
,"This binary is not designed for running in this way\n"
|
|
||||||
"-- the system administrator has been informed\n");
|
|
||||||
@@ -118,9 +154,10 @@ int main(int argc, char *argv[])
|
|
||||||
nullok = 1;
|
|
||||||
else if (strcmp(option, "nonull") == 0)
|
|
||||||
nullok = 0;
|
|
||||||
- else
|
|
||||||
+ else {
|
|
||||||
+ _audit_log(AUDIT_ANOM_EXEC, getuidname(getuid()), PAM_SYSTEM_ERR);
|
|
||||||
return PAM_SYSTEM_ERR;
|
|
||||||
-
|
|
||||||
+ }
|
|
||||||
/* read the password from stdin (a pipe from the pam_unix module) */
|
|
||||||
|
|
||||||
npass = read_passwords(STDIN_FILENO, 1, passwords);
|
|
||||||
@@ -141,11 +178,16 @@ int main(int argc, char *argv[])
|
|
||||||
/* return pass or fail */
|
|
||||||
|
|
||||||
if (retval != PAM_SUCCESS) {
|
|
||||||
- if (!nullok || !blankpass)
|
|
||||||
+ if (!nullok || !blankpass) {
|
|
||||||
/* no need to log blank pass test */
|
|
||||||
+ if (getuid() != 0)
|
|
||||||
+ _audit_log(AUDIT_USER_AUTH, user, PAM_AUTH_ERR);
|
|
||||||
helper_log_err(LOG_NOTICE, "password check failed for user (%s)", user);
|
|
||||||
+ }
|
|
||||||
return PAM_AUTH_ERR;
|
|
||||||
} else {
|
|
||||||
+ if (getuid() != 0)
|
|
||||||
+ return _audit_log(AUDIT_USER_AUTH, user, PAM_SUCCESS);
|
|
||||||
return PAM_SUCCESS;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,285 +0,0 @@
|
|||||||
diff -up Linux-PAM-0.99.6.2/modules/pam_lastlog/pam_lastlog.c.failed Linux-PAM-0.99.6.2/modules/pam_lastlog/pam_lastlog.c
|
|
||||||
--- Linux-PAM-0.99.6.2/modules/pam_lastlog/pam_lastlog.c.failed 2006-08-24 20:03:44.000000000 +0200
|
|
||||||
+++ Linux-PAM-0.99.6.2/modules/pam_lastlog/pam_lastlog.c 2008-09-12 21:21:42.000000000 +0200
|
|
||||||
@@ -46,6 +46,10 @@ struct lastlog {
|
|
||||||
};
|
|
||||||
#endif /* hpux */
|
|
||||||
|
|
||||||
+#ifndef _PATH_BTMP
|
|
||||||
+# define _PATH_BTMP "/var/log/btmp"
|
|
||||||
+#endif
|
|
||||||
+
|
|
||||||
/* XXX - time before ignoring lock. Is 1 sec enough? */
|
|
||||||
#define LASTLOG_IGNORE_LOCK_TIME 1
|
|
||||||
|
|
||||||
@@ -75,11 +79,13 @@ struct lastlog {
|
|
||||||
#define LASTLOG_DEBUG 020 /* send info to syslog(3) */
|
|
||||||
#define LASTLOG_QUIET 040 /* keep quiet about things */
|
|
||||||
#define LASTLOG_WTMP 0100 /* log to wtmp as well as lastlog */
|
|
||||||
+#define LASTLOG_BTMP 0200 /* display failed login info from btmp */
|
|
||||||
+#define LASTLOG_UPDATE 0400 /* update the lastlog and wtmp files (default) */
|
|
||||||
|
|
||||||
static int
|
|
||||||
_pam_parse(pam_handle_t *pamh, int flags, int argc, const char **argv)
|
|
||||||
{
|
|
||||||
- int ctrl=(LASTLOG_DATE|LASTLOG_HOST|LASTLOG_LINE|LASTLOG_WTMP);
|
|
||||||
+ int ctrl=(LASTLOG_DATE|LASTLOG_HOST|LASTLOG_LINE|LASTLOG_WTMP|LASTLOG_UPDATE);
|
|
||||||
|
|
||||||
/* does the appliction require quiet? */
|
|
||||||
if (flags & PAM_SILENT) {
|
|
||||||
@@ -105,6 +111,10 @@ _pam_parse(pam_handle_t *pamh, int flags
|
|
||||||
ctrl |= LASTLOG_NEVER;
|
|
||||||
} else if (!strcmp(*argv,"nowtmp")) {
|
|
||||||
ctrl &= ~LASTLOG_WTMP;
|
|
||||||
+ } else if (!strcmp(*argv,"noupdate")) {
|
|
||||||
+ ctrl &= ~(LASTLOG_WTMP|LASTLOG_UPDATE);
|
|
||||||
+ } else if (!strcmp(*argv,"showfailed")) {
|
|
||||||
+ ctrl |= LASTLOG_BTMP;
|
|
||||||
} else {
|
|
||||||
pam_syslog(pamh, LOG_ERR, "unknown option: %s", *argv);
|
|
||||||
}
|
|
||||||
@@ -135,7 +145,7 @@ get_tty(pam_handle_t *pamh)
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
-last_login_read(pam_handle_t *pamh, int announce, int last_fd, uid_t uid)
|
|
||||||
+last_login_read(pam_handle_t *pamh, int announce, int last_fd, uid_t uid, time_t *lltime)
|
|
||||||
{
|
|
||||||
struct flock last_lock;
|
|
||||||
struct lastlog last_login;
|
|
||||||
@@ -166,6 +176,7 @@ last_login_read(pam_handle_t *pamh, int
|
|
||||||
last_lock.l_type = F_UNLCK;
|
|
||||||
(void) fcntl(last_fd, F_SETLK, &last_lock); /* unlock */
|
|
||||||
|
|
||||||
+ *lltime = last_login.ll_time;
|
|
||||||
if (!last_login.ll_time) {
|
|
||||||
if (announce & LASTLOG_DEBUG) {
|
|
||||||
pam_syslog(pamh, LOG_DEBUG,
|
|
||||||
@@ -320,13 +331,13 @@ last_login_write(pam_handle_t *pamh, int
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
-last_login_date(pam_handle_t *pamh, int announce, uid_t uid, const char *user)
|
|
||||||
+last_login_date(pam_handle_t *pamh, int announce, uid_t uid, const char *user, time_t *lltime)
|
|
||||||
{
|
|
||||||
int retval;
|
|
||||||
int last_fd;
|
|
||||||
|
|
||||||
/* obtain the last login date and all the relevant info */
|
|
||||||
- last_fd = open(_PATH_LASTLOG, O_RDWR);
|
|
||||||
+ last_fd = open(_PATH_LASTLOG, announce&LASTLOG_UPDATE ? O_RDWR : O_RDONLY);
|
|
||||||
if (last_fd < 0) {
|
|
||||||
if (errno == ENOENT) {
|
|
||||||
last_fd = open(_PATH_LASTLOG, O_RDWR|O_CREAT,
|
|
||||||
@@ -353,7 +364,7 @@ last_login_date(pam_handle_t *pamh, int
|
|
||||||
return PAM_SERVICE_ERR;
|
|
||||||
}
|
|
||||||
|
|
||||||
- retval = last_login_read(pamh, announce, last_fd, uid);
|
|
||||||
+ retval = last_login_read(pamh, announce, last_fd, uid, lltime);
|
|
||||||
if (retval != PAM_SUCCESS)
|
|
||||||
{
|
|
||||||
close(last_fd);
|
|
||||||
@@ -361,7 +372,9 @@ last_login_date(pam_handle_t *pamh, int
|
|
||||||
return retval;
|
|
||||||
}
|
|
||||||
|
|
||||||
- retval = last_login_write(pamh, announce, last_fd, uid, user);
|
|
||||||
+ if (announce & LASTLOG_UPDATE) {
|
|
||||||
+ retval = last_login_write(pamh, announce, last_fd, uid, user);
|
|
||||||
+ }
|
|
||||||
|
|
||||||
close(last_fd);
|
|
||||||
D(("all done with last login"));
|
|
||||||
@@ -369,6 +382,116 @@ last_login_date(pam_handle_t *pamh, int
|
|
||||||
return retval;
|
|
||||||
}
|
|
||||||
|
|
||||||
+static int
|
|
||||||
+last_login_failed(pam_handle_t *pamh, int announce, const char *user, time_t lltime)
|
|
||||||
+{
|
|
||||||
+ int retval;
|
|
||||||
+ int fd;
|
|
||||||
+ struct utmp ut;
|
|
||||||
+ struct utmp utuser;
|
|
||||||
+ int failed = 0;
|
|
||||||
+ char the_time[256];
|
|
||||||
+ char *date = NULL;
|
|
||||||
+ char *host = NULL;
|
|
||||||
+ char *line = NULL;
|
|
||||||
+
|
|
||||||
+ if (strlen(user) > UT_NAMESIZE) {
|
|
||||||
+ pam_syslog(pamh, LOG_WARNING, "username too long, output might be inaccurate");
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ /* obtain the failed login attempt records from btmp */
|
|
||||||
+ fd = open(_PATH_BTMP, O_RDONLY);
|
|
||||||
+ if (fd < 0) {
|
|
||||||
+ pam_syslog(pamh, LOG_ERR, "unable to open %s: %m", _PATH_BTMP);
|
|
||||||
+ D(("unable to open %s file", _PATH_BTMP));
|
|
||||||
+ return PAM_SERVICE_ERR;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ while ((retval=pam_modutil_read(fd, (void *)&ut,
|
|
||||||
+ sizeof(ut))) == sizeof(ut)) {
|
|
||||||
+ if (ut.ut_tv.tv_sec >= lltime && strncmp(ut.ut_user, user, UT_NAMESIZE) == 0) {
|
|
||||||
+ memcpy(&utuser, &ut, sizeof(utuser));
|
|
||||||
+ failed++;
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ if (failed) {
|
|
||||||
+ /* we want the date? */
|
|
||||||
+ if (announce & LASTLOG_DATE) {
|
|
||||||
+ struct tm *tm, tm_buf;
|
|
||||||
+ time_t lf_time;
|
|
||||||
+
|
|
||||||
+ lf_time = utuser.ut_tv.tv_sec;
|
|
||||||
+ tm = localtime_r (&lf_time, &tm_buf);
|
|
||||||
+ strftime (the_time, sizeof (the_time),
|
|
||||||
+ /* TRANSLATORS: "strftime options for date of last login" */
|
|
||||||
+ _(" %a %b %e %H:%M:%S %Z %Y"), tm);
|
|
||||||
+
|
|
||||||
+ date = the_time;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ /* we want & have the host? */
|
|
||||||
+ if ((announce & LASTLOG_HOST)
|
|
||||||
+ && (utuser.ut_host[0] != '\0')) {
|
|
||||||
+ /* TRANSLATORS: " from <host>" */
|
|
||||||
+ if (asprintf(&host, _(" from %.*s"), UT_HOSTSIZE,
|
|
||||||
+ utuser.ut_host) < 0) {
|
|
||||||
+ pam_syslog(pamh, LOG_ERR, "out of memory");
|
|
||||||
+ retval = PAM_BUF_ERR;
|
|
||||||
+ goto cleanup;
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ /* we want and have the terminal? */
|
|
||||||
+ if ((announce & LASTLOG_LINE)
|
|
||||||
+ && (utuser.ut_line[0] != '\0')) {
|
|
||||||
+ /* TRANSLATORS: " on <terminal>" */
|
|
||||||
+ if (asprintf(&line, _(" on %.*s"), UT_LINESIZE,
|
|
||||||
+ utuser.ut_line) < 0) {
|
|
||||||
+ pam_syslog(pamh, LOG_ERR, "out of memory");
|
|
||||||
+ retval = PAM_BUF_ERR;
|
|
||||||
+ goto cleanup;
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ if (announce & (LASTLOG_LINE|LASTLOG_DATE|LASTLOG_HOST)) {
|
|
||||||
+ /* TRANSLATORS: "Last failed login: <date> from <host> on <terminal>" */
|
|
||||||
+ pam_info(pamh, _("Last failed login:%s%s%s"),
|
|
||||||
+ date ? date : "",
|
|
||||||
+ host ? host : "",
|
|
||||||
+ line ? line : "");
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ _pam_drop(line);
|
|
||||||
+#if defined HAVE_DNGETTEXT && defined ENABLE_NLS
|
|
||||||
+ asprintf (&line, dngettext(PACKAGE,
|
|
||||||
+ "There was %d failed login attempt since the last successful login.",
|
|
||||||
+ "There were %d failed login attempts since the last successful login.",
|
|
||||||
+ failed),
|
|
||||||
+ failed);
|
|
||||||
+#else
|
|
||||||
+ if (daysleft == 1)
|
|
||||||
+ asprintf(&line,
|
|
||||||
+ _("There was %d failed login attempt since the last successful login."),
|
|
||||||
+ failed);
|
|
||||||
+ else
|
|
||||||
+ asprintf(&line,
|
|
||||||
+ /* TRANSLATORS: only used if dngettext is not supported */
|
|
||||||
+ _("There were %d failed login attempts since the last successful login."),
|
|
||||||
+ failed);
|
|
||||||
+#endif
|
|
||||||
+ retval = pam_info(pamh, "%s", line);
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+cleanup:
|
|
||||||
+ free(host);
|
|
||||||
+ free(line);
|
|
||||||
+ close(fd);
|
|
||||||
+ D(("all done with btmp"));
|
|
||||||
+
|
|
||||||
+ return retval;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
/* --- authentication management functions (only) --- */
|
|
||||||
|
|
||||||
PAM_EXTERN int
|
|
||||||
@@ -379,6 +502,7 @@ pam_sm_open_session(pam_handle_t *pamh,
|
|
||||||
const void *user;
|
|
||||||
const struct passwd *pwd;
|
|
||||||
uid_t uid;
|
|
||||||
+ time_t lltime = 0;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* this module gets the uid of the PAM_USER. Uses it to display
|
|
||||||
@@ -407,7 +531,11 @@ pam_sm_open_session(pam_handle_t *pamh,
|
|
||||||
|
|
||||||
/* process the current login attempt (indicate last) */
|
|
||||||
|
|
||||||
- retval = last_login_date(pamh, ctrl, uid, user);
|
|
||||||
+ retval = last_login_date(pamh, ctrl, uid, user, &lltime);
|
|
||||||
+
|
|
||||||
+ if ((ctrl & LASTLOG_BTMP) && retval == PAM_SUCCESS) {
|
|
||||||
+ retval = last_login_failed(pamh, ctrl, user, lltime);
|
|
||||||
+ }
|
|
||||||
|
|
||||||
/* indicate success or failure */
|
|
||||||
|
|
||||||
diff -up Linux-PAM-0.99.6.2/modules/pam_lastlog/pam_lastlog.8.xml.failed Linux-PAM-0.99.6.2/modules/pam_lastlog/pam_lastlog.8.xml
|
|
||||||
--- Linux-PAM-0.99.6.2/modules/pam_lastlog/pam_lastlog.8.xml.failed 2006-06-09 18:44:07.000000000 +0200
|
|
||||||
+++ Linux-PAM-0.99.6.2/modules/pam_lastlog/pam_lastlog.8.xml 2008-09-12 21:12:35.000000000 +0200
|
|
||||||
@@ -39,6 +39,12 @@
|
|
||||||
<arg choice="opt">
|
|
||||||
nowtmp
|
|
||||||
</arg>
|
|
||||||
+ <arg choice="opt">
|
|
||||||
+ noupdate
|
|
||||||
+ </arg>
|
|
||||||
+ <arg choice="opt">
|
|
||||||
+ showfailed
|
|
||||||
+ </arg>
|
|
||||||
</cmdsynopsis>
|
|
||||||
</refsynopsisdiv>
|
|
||||||
|
|
||||||
@@ -137,6 +143,28 @@
|
|
||||||
</para>
|
|
||||||
</listitem>
|
|
||||||
</varlistentry>
|
|
||||||
+ <varlistentry>
|
|
||||||
+ <term>
|
|
||||||
+ <option>noupdate</option>
|
|
||||||
+ </term>
|
|
||||||
+ <listitem>
|
|
||||||
+ <para>
|
|
||||||
+ Don't update any file.
|
|
||||||
+ </para>
|
|
||||||
+ </listitem>
|
|
||||||
+ </varlistentry>
|
|
||||||
+ <varlistentry>
|
|
||||||
+ <term>
|
|
||||||
+ <option>showfailed</option>
|
|
||||||
+ </term>
|
|
||||||
+ <listitem>
|
|
||||||
+ <para>
|
|
||||||
+ Display number of failed login attempts and the date of the
|
|
||||||
+ last failed attempt from btmp. The date is not displayed
|
|
||||||
+ when <option>nodate</option> is specified.
|
|
||||||
+ </para>
|
|
||||||
+ </listitem>
|
|
||||||
+ </varlistentry>
|
|
||||||
</variablelist>
|
|
||||||
</refsect1>
|
|
||||||
|
|
||||||
@@ -213,7 +241,7 @@
|
|
||||||
<refentrytitle>pam.conf</refentrytitle><manvolnum>5</manvolnum>
|
|
||||||
</citerefentry>,
|
|
||||||
<citerefentry>
|
|
||||||
- <refentrytitle>pam.d</refentrytitle><manvolnum>8</manvolnum>
|
|
||||||
+ <refentrytitle>pam.d</refentrytitle><manvolnum>5</manvolnum>
|
|
||||||
</citerefentry>,
|
|
||||||
<citerefentry>
|
|
||||||
<refentrytitle>pam</refentrytitle><manvolnum>8</manvolnum>
|
|
@ -1,23 +0,0 @@
|
|||||||
--- Linux-PAM-0.99.5.0/configure.in.redhat-modules 2006-06-28 09:25:02.000000000 +0200
|
|
||||||
+++ Linux-PAM-0.99.5.0/configure.in 2006-06-30 10:24:35.000000000 +0200
|
|
||||||
@@ -492,6 +492,9 @@
|
|
||||||
libpam_misc/Makefile conf/Makefile conf/pam_conv1/Makefile \
|
|
||||||
po/Makefile.in \
|
|
||||||
modules/Makefile \
|
|
||||||
+ modules/pam_chroot/Makefile modules/pam_console/Makefile \
|
|
||||||
+ modules/pam_postgresok/Makefile \
|
|
||||||
+ modules/pam_timestamp/Makefile modules/pam_tally2/Makefile \
|
|
||||||
modules/pam_access/Makefile modules/pam_cracklib/Makefile \
|
|
||||||
modules/pam_debug/Makefile modules/pam_deny/Makefile \
|
|
||||||
modules/pam_echo/Makefile modules/pam_env/Makefile \
|
|
||||||
--- Linux-PAM-0.99.5.0/modules/Makefile.am.redhat-modules 2006-06-27 16:21:08.000000000 +0200
|
|
||||||
+++ Linux-PAM-0.99.5.0/modules/Makefile.am 2006-06-30 10:27:02.000000000 +0200
|
|
||||||
@@ -3,6 +3,8 @@
|
|
||||||
#
|
|
||||||
|
|
||||||
SUBDIRS = pam_access pam_cracklib pam_debug pam_deny pam_echo \
|
|
||||||
+ pam_chroot pam_console pam_postgresok \
|
|
||||||
+ pam_timestamp pam_tally2 \
|
|
||||||
pam_env pam_filter pam_ftp pam_group pam_issue pam_keyinit \
|
|
||||||
pam_lastlog pam_limits pam_listfile pam_localuser pam_mail \
|
|
||||||
pam_mkhomedir pam_motd pam_nologin pam_permit pam_rhosts pam_rootok \
|
|
@ -1,561 +0,0 @@
|
|||||||
Index: modules/pam_selinux/pam_selinux.8.xml
|
|
||||||
===================================================================
|
|
||||||
RCS file: /cvsroot/pam/Linux-PAM/modules/pam_selinux/pam_selinux.8.xml,v
|
|
||||||
retrieving revision 1.2
|
|
||||||
diff -u -p -r1.2 pam_selinux.8.xml
|
|
||||||
--- modules/pam_selinux/pam_selinux.8.xml 15 Jun 2007 10:17:22 -0000 1.2
|
|
||||||
+++ modules/pam_selinux/pam_selinux.8.xml 19 May 2008 15:44:08 -0000
|
|
||||||
@@ -37,6 +37,9 @@
|
|
||||||
select_context
|
|
||||||
</arg>
|
|
||||||
<arg choice="opt">
|
|
||||||
+ env_params
|
|
||||||
+ </arg>
|
|
||||||
+ <arg choice="opt">
|
|
||||||
use_current_range
|
|
||||||
</arg>
|
|
||||||
</cmdsynopsis>
|
|
||||||
@@ -137,12 +140,30 @@
|
|
||||||
</varlistentry>
|
|
||||||
<varlistentry>
|
|
||||||
<term>
|
|
||||||
+ <option>env_params</option>
|
|
||||||
+ </term>
|
|
||||||
+ <listitem>
|
|
||||||
+ <para>
|
|
||||||
+ Attempt to obtain a custom security context role from PAM environment.
|
|
||||||
+ If MLS is on obtain also sensitivity level. This option and the
|
|
||||||
+ select_context option are mutually exclusive. The respective PAM
|
|
||||||
+ environment variables are <emphasis>SELINUX_ROLE_REQUESTED</emphasis>,
|
|
||||||
+ <emphasis>SELINUX_LEVEL_REQUESTED</emphasis>, and
|
|
||||||
+ <emphasis>SELINUX_USE_CURRENT_RANGE</emphasis>. The first two variables
|
|
||||||
+ are self describing and the last one if set to 1 makes the PAM module behave as
|
|
||||||
+ if the use_current_range was specified on the command line of the module.
|
|
||||||
+ </para>
|
|
||||||
+ </listitem>
|
|
||||||
+ </varlistentry>
|
|
||||||
+ <varlistentry>
|
|
||||||
+ <term>
|
|
||||||
<option>use_current_range</option>
|
|
||||||
</term>
|
|
||||||
<listitem>
|
|
||||||
<para>
|
|
||||||
- Use the sensitivity range of the process for the user context.
|
|
||||||
- This option and the select_context option are mutually exclusive.
|
|
||||||
+ Use the sensitivity level of the current process for the user context
|
|
||||||
+ instead of the default level. Also supresses asking of the
|
|
||||||
+ sensitivity level from the user or obtaining it from PAM environment.
|
|
||||||
</para>
|
|
||||||
</listitem>
|
|
||||||
</varlistentry>
|
|
||||||
Index: modules/pam_selinux/pam_selinux.c
|
|
||||||
===================================================================
|
|
||||||
RCS file: /cvsroot/pam/Linux-PAM/modules/pam_selinux/pam_selinux.c,v
|
|
||||||
retrieving revision 1.16
|
|
||||||
diff -u -p -r1.16 pam_selinux.c
|
|
||||||
--- modules/pam_selinux/pam_selinux.c 22 Apr 2008 19:21:37 -0000 1.16
|
|
||||||
+++ modules/pam_selinux/pam_selinux.c 19 May 2008 15:44:08 -0000
|
|
||||||
@@ -2,8 +2,9 @@
|
|
||||||
* A module for Linux-PAM that will set the default security context after login
|
|
||||||
* via PAM.
|
|
||||||
*
|
|
||||||
- * Copyright (c) 2003 Red Hat, Inc.
|
|
||||||
+ * Copyright (c) 2003-2008 Red Hat, Inc.
|
|
||||||
* Written by Dan Walsh <dwalsh@redhat.com>
|
|
||||||
+ * Additional improvements by Tomas Mraz <tmraz@redhat.com>
|
|
||||||
*
|
|
||||||
* Redistribution and use in source and binary forms, with or without
|
|
||||||
* modification, are permitted provided that the following conditions
|
|
||||||
@@ -138,15 +139,22 @@ send_text (pam_handle_t *pamh, const cha
|
|
||||||
*/
|
|
||||||
static int
|
|
||||||
query_response (pam_handle_t *pamh, const char *text, const char *def,
|
|
||||||
- char **responses, int debug)
|
|
||||||
+ char **response, int debug)
|
|
||||||
{
|
|
||||||
int rc;
|
|
||||||
if (def)
|
|
||||||
- rc = pam_prompt (pamh, PAM_PROMPT_ECHO_ON, responses, "%s [%s] ", text, def);
|
|
||||||
+ rc = pam_prompt (pamh, PAM_PROMPT_ECHO_ON, response, "%s [%s] ", text, def);
|
|
||||||
else
|
|
||||||
- rc = pam_prompt (pamh, PAM_PROMPT_ECHO_ON, responses, "%s ", text);
|
|
||||||
- if (debug)
|
|
||||||
- pam_syslog(pamh, LOG_NOTICE, "%s %s", text, responses[0]);
|
|
||||||
+ rc = pam_prompt (pamh, PAM_PROMPT_ECHO_ON, response, "%s ", text);
|
|
||||||
+
|
|
||||||
+ if (*response == NULL) {
|
|
||||||
+ rc = PAM_CONV_ERR;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ if (rc != PAM_SUCCESS) {
|
|
||||||
+ pam_syslog(pamh, LOG_WARNING, "No response to query: %s", text);
|
|
||||||
+ } else if (debug)
|
|
||||||
+ pam_syslog(pamh, LOG_NOTICE, "%s %s", text, *response);
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -157,13 +165,15 @@ manual_context (pam_handle_t *pamh, cons
|
|
||||||
context_t new_context;
|
|
||||||
int mls_enabled = is_selinux_mls_enabled();
|
|
||||||
char *type=NULL;
|
|
||||||
- char *responses=NULL;
|
|
||||||
+ char *response=NULL;
|
|
||||||
|
|
||||||
while (1) {
|
|
||||||
- query_response(pamh,
|
|
||||||
- _("Would you like to enter a security context? [N] "), NULL,
|
|
||||||
- &responses,debug);
|
|
||||||
- if ((responses[0] == 'y') || (responses[0] == 'Y'))
|
|
||||||
+ if (query_response(pamh,
|
|
||||||
+ _("Would you like to enter a security context? [N] "), NULL,
|
|
||||||
+ &response, debug) != PAM_SUCCESS)
|
|
||||||
+ return NULL;
|
|
||||||
+
|
|
||||||
+ if ((response[0] == 'y') || (response[0] == 'Y'))
|
|
||||||
{
|
|
||||||
if (mls_enabled)
|
|
||||||
new_context = context_new ("user:role:type:level");
|
|
||||||
@@ -176,26 +186,29 @@ manual_context (pam_handle_t *pamh, cons
|
|
||||||
if (context_user_set (new_context, user))
|
|
||||||
goto fail_set;
|
|
||||||
|
|
||||||
- _pam_drop(responses);
|
|
||||||
+ _pam_drop(response);
|
|
||||||
/* Allow the user to enter each field of the context individually */
|
|
||||||
- query_response(pamh,_("role:"), NULL, &responses,debug);
|
|
||||||
- if (responses[0] != '\0') {
|
|
||||||
- if (context_role_set (new_context, responses))
|
|
||||||
+ if (query_response(pamh, _("role:"), NULL, &response, debug) == PAM_SUCCESS &&
|
|
||||||
+ response[0] != '\0') {
|
|
||||||
+ if (context_role_set (new_context, response))
|
|
||||||
goto fail_set;
|
|
||||||
- if (get_default_type(responses, &type))
|
|
||||||
+ if (get_default_type(response, &type))
|
|
||||||
goto fail_set;
|
|
||||||
if (context_type_set (new_context, type))
|
|
||||||
goto fail_set;
|
|
||||||
}
|
|
||||||
- _pam_drop(responses);
|
|
||||||
+ _pam_drop(response);
|
|
||||||
+
|
|
||||||
if (mls_enabled)
|
|
||||||
{
|
|
||||||
- query_response(pamh,_("level:"), NULL, &responses,debug);
|
|
||||||
- if (responses[0] != '\0') {
|
|
||||||
- if (context_range_set (new_context, responses))
|
|
||||||
+ if (query_response(pamh, _("level:"), NULL, &response, debug) == PAM_SUCCESS &&
|
|
||||||
+ response[0] != '\0') {
|
|
||||||
+ if (context_range_set (new_context, response))
|
|
||||||
goto fail_set;
|
|
||||||
}
|
|
||||||
+ _pam_drop(response);
|
|
||||||
}
|
|
||||||
+
|
|
||||||
/* Get the string value of the context and see if it is valid. */
|
|
||||||
if (!security_check_context(context_str(new_context))) {
|
|
||||||
newcon = strdup(context_str(new_context));
|
|
||||||
@@ -204,16 +217,17 @@ manual_context (pam_handle_t *pamh, cons
|
|
||||||
}
|
|
||||||
else
|
|
||||||
send_text(pamh,_("Not a valid security context"),debug);
|
|
||||||
- context_free (new_context);
|
|
||||||
+
|
|
||||||
+ context_free (new_context);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
- _pam_drop(responses);
|
|
||||||
+ _pam_drop(response);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
} /* end while */
|
|
||||||
fail_set:
|
|
||||||
free(type);
|
|
||||||
- _pam_drop(responses);
|
|
||||||
+ _pam_drop(response);
|
|
||||||
context_free (new_context);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
@@ -239,69 +253,91 @@ static int mls_range_allowed(pam_handle_
|
|
||||||
}
|
|
||||||
|
|
||||||
static security_context_t
|
|
||||||
-config_context (pam_handle_t *pamh, security_context_t puser_context, int debug)
|
|
||||||
+config_context (pam_handle_t *pamh, security_context_t defaultcon, int use_current_range, int debug)
|
|
||||||
{
|
|
||||||
security_context_t newcon=NULL;
|
|
||||||
context_t new_context;
|
|
||||||
int mls_enabled = is_selinux_mls_enabled();
|
|
||||||
- char *responses=NULL;
|
|
||||||
+ char *response=NULL;
|
|
||||||
char *type=NULL;
|
|
||||||
char resp_val = 0;
|
|
||||||
|
|
||||||
- pam_prompt (pamh, PAM_TEXT_INFO, NULL, _("Default Security Context %s\n"), puser_context);
|
|
||||||
+ pam_prompt (pamh, PAM_TEXT_INFO, NULL, _("Default Security Context %s\n"), defaultcon);
|
|
||||||
|
|
||||||
while (1) {
|
|
||||||
- query_response(pamh,
|
|
||||||
+ if (query_response(pamh,
|
|
||||||
_("Would you like to enter a different role or level?"), "n",
|
|
||||||
- &responses,debug);
|
|
||||||
-
|
|
||||||
- resp_val = responses[0];
|
|
||||||
- _pam_drop(responses);
|
|
||||||
+ &response, debug) == PAM_SUCCESS) {
|
|
||||||
+ resp_val = response[0];
|
|
||||||
+ _pam_drop(response);
|
|
||||||
+ } else {
|
|
||||||
+ resp_val = 'N';
|
|
||||||
+ }
|
|
||||||
if ((resp_val == 'y') || (resp_val == 'Y'))
|
|
||||||
{
|
|
||||||
- new_context = context_new(puser_context);
|
|
||||||
-
|
|
||||||
+ if ((new_context = context_new(defaultcon)) == NULL)
|
|
||||||
+ goto fail_set;
|
|
||||||
+
|
|
||||||
/* Allow the user to enter role and level individually */
|
|
||||||
- query_response(pamh,_("role:"), context_role_get(new_context),
|
|
||||||
- &responses, debug);
|
|
||||||
- if (responses[0]) {
|
|
||||||
- if (get_default_type(responses, &type)) {
|
|
||||||
- pam_prompt (pamh, PAM_ERROR_MSG, NULL, _("No default type for role %s\n"), responses);
|
|
||||||
- _pam_drop(responses);
|
|
||||||
+ if (query_response(pamh, _("role:"), context_role_get(new_context),
|
|
||||||
+ &response, debug) == PAM_SUCCESS && response[0]) {
|
|
||||||
+ if (get_default_type(response, &type)) {
|
|
||||||
+ pam_prompt (pamh, PAM_ERROR_MSG, NULL, _("No default type for role %s\n"), response);
|
|
||||||
+ _pam_drop(response);
|
|
||||||
continue;
|
|
||||||
} else {
|
|
||||||
- if (context_role_set(new_context, responses))
|
|
||||||
+ if (context_role_set(new_context, response))
|
|
||||||
goto fail_set;
|
|
||||||
if (context_type_set (new_context, type))
|
|
||||||
goto fail_set;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
- _pam_drop(responses);
|
|
||||||
+ _pam_drop(response);
|
|
||||||
+
|
|
||||||
if (mls_enabled)
|
|
||||||
{
|
|
||||||
- query_response(pamh,_("level:"), context_range_get(new_context),
|
|
||||||
- &responses, debug);
|
|
||||||
- if (responses[0]) {
|
|
||||||
- if (context_range_set(new_context, responses))
|
|
||||||
- goto fail_set;
|
|
||||||
+ if (use_current_range) {
|
|
||||||
+ security_context_t mycon = NULL;
|
|
||||||
+ context_t my_context;
|
|
||||||
+
|
|
||||||
+ if (getcon(&mycon) != 0)
|
|
||||||
+ goto fail_set;
|
|
||||||
+ my_context = context_new(mycon);
|
|
||||||
+ if (my_context == NULL) {
|
|
||||||
+ freecon(mycon);
|
|
||||||
+ goto fail_set;
|
|
||||||
+ }
|
|
||||||
+ freecon(mycon);
|
|
||||||
+ if (context_range_set(new_context, context_range_get(my_context))) {
|
|
||||||
+ context_free(my_context);
|
|
||||||
+ goto fail_set;
|
|
||||||
+ }
|
|
||||||
+ context_free(my_context);
|
|
||||||
+ } else if (query_response(pamh, _("level:"), context_range_get(new_context),
|
|
||||||
+ &response, debug) == PAM_SUCCESS && response[0]) {
|
|
||||||
+ if (context_range_set(new_context, response))
|
|
||||||
+ goto fail_set;
|
|
||||||
}
|
|
||||||
- _pam_drop(responses);
|
|
||||||
+ _pam_drop(response);
|
|
||||||
}
|
|
||||||
+
|
|
||||||
if (debug)
|
|
||||||
pam_syslog(pamh, LOG_NOTICE, "Selected Security Context %s", context_str(new_context));
|
|
||||||
|
|
||||||
/* Get the string value of the context and see if it is valid. */
|
|
||||||
if (!security_check_context(context_str(new_context))) {
|
|
||||||
newcon = strdup(context_str(new_context));
|
|
||||||
- context_free (new_context);
|
|
||||||
+ if (newcon == NULL)
|
|
||||||
+ goto fail_set;
|
|
||||||
+ context_free(new_context);
|
|
||||||
|
|
||||||
/* we have to check that this user is allowed to go into the
|
|
||||||
range they have specified ... role is tied to an seuser, so that'll
|
|
||||||
be checked at setexeccon time */
|
|
||||||
- if (mls_enabled && !mls_range_allowed(pamh, puser_context, newcon, debug)) {
|
|
||||||
- pam_syslog(pamh, LOG_NOTICE, "Security context %s is not allowed for %s", puser_context, newcon);
|
|
||||||
+ if (mls_enabled && !mls_range_allowed(pamh, defaultcon, newcon, debug)) {
|
|
||||||
+ pam_syslog(pamh, LOG_NOTICE, "Security context %s is not allowed for %s", defaultcon, newcon);
|
|
||||||
|
|
||||||
- send_audit_message(pamh, 0, puser_context, newcon);
|
|
||||||
+ send_audit_message(pamh, 0, defaultcon, newcon);
|
|
||||||
|
|
||||||
free(newcon);
|
|
||||||
goto fail_range;
|
|
||||||
@@ -309,26 +345,120 @@ config_context (pam_handle_t *pamh, secu
|
|
||||||
return newcon;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
- send_audit_message(pamh, 0, puser_context, context_str(new_context));
|
|
||||||
+ send_audit_message(pamh, 0, defaultcon, context_str(new_context));
|
|
||||||
send_text(pamh,_("Not a valid security context"),debug);
|
|
||||||
}
|
|
||||||
context_free(new_context); /* next time around allocates another */
|
|
||||||
}
|
|
||||||
else
|
|
||||||
- return strdup(puser_context);
|
|
||||||
+ return strdup(defaultcon);
|
|
||||||
} /* end while */
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
fail_set:
|
|
||||||
free(type);
|
|
||||||
- _pam_drop(responses);
|
|
||||||
+ _pam_drop(response);
|
|
||||||
context_free (new_context);
|
|
||||||
- send_audit_message(pamh, 0, puser_context, NULL);
|
|
||||||
+ send_audit_message(pamh, 0, defaultcon, NULL);
|
|
||||||
fail_range:
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
+static security_context_t
|
|
||||||
+context_from_env (pam_handle_t *pamh, security_context_t defaultcon, int env_params, int use_current_range, int debug)
|
|
||||||
+{
|
|
||||||
+ security_context_t newcon = NULL;
|
|
||||||
+ context_t new_context;
|
|
||||||
+ context_t my_context = NULL;
|
|
||||||
+ int mls_enabled = is_selinux_mls_enabled();
|
|
||||||
+ const char *env = NULL;
|
|
||||||
+ char *type = NULL;
|
|
||||||
+
|
|
||||||
+ if ((new_context = context_new(defaultcon)) == NULL)
|
|
||||||
+ goto fail_set;
|
|
||||||
+
|
|
||||||
+ if (env_params && (env = pam_getenv(pamh, "SELINUX_ROLE_REQUESTED")) != NULL && env[0] != '\0') {
|
|
||||||
+ if (debug)
|
|
||||||
+ pam_syslog(pamh, LOG_NOTICE, "Requested role: %s", env);
|
|
||||||
+
|
|
||||||
+ if (get_default_type(env, &type)) {
|
|
||||||
+ pam_syslog(pamh, LOG_NOTICE, "No default type for role %s", env);
|
|
||||||
+ goto fail_set;
|
|
||||||
+ } else {
|
|
||||||
+ if (context_role_set(new_context, env))
|
|
||||||
+ goto fail_set;
|
|
||||||
+ if (context_type_set(new_context, type))
|
|
||||||
+ goto fail_set;
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ if (mls_enabled) {
|
|
||||||
+ if ((env = pam_getenv(pamh, "SELINUX_USE_CURRENT_RANGE")) != NULL && env[0] == '1') {
|
|
||||||
+ if (debug)
|
|
||||||
+ pam_syslog(pamh, LOG_NOTICE, "SELINUX_USE_CURRENT_RANGE is set");
|
|
||||||
+ use_current_range = 1;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ if (use_current_range) {
|
|
||||||
+ security_context_t mycon = NULL;
|
|
||||||
+
|
|
||||||
+ if (getcon(&mycon) != 0)
|
|
||||||
+ goto fail_set;
|
|
||||||
+ my_context = context_new(mycon);
|
|
||||||
+ if (my_context == NULL) {
|
|
||||||
+ freecon(mycon);
|
|
||||||
+ goto fail_set;
|
|
||||||
+ }
|
|
||||||
+ freecon(mycon);
|
|
||||||
+ env = context_range_get(my_context);
|
|
||||||
+ } else {
|
|
||||||
+ env = pam_getenv(pamh, "SELINUX_LEVEL_REQUESTED");
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ if (env != NULL && env[0] != '\0') {
|
|
||||||
+ if (debug)
|
|
||||||
+ pam_syslog(pamh, LOG_NOTICE, "Requested level: %s", env);
|
|
||||||
+ if (context_range_set(new_context, env))
|
|
||||||
+ goto fail_set;
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ newcon = strdup(context_str(new_context));
|
|
||||||
+ if (newcon == NULL)
|
|
||||||
+ goto fail_set;
|
|
||||||
+
|
|
||||||
+ if (debug)
|
|
||||||
+ pam_syslog(pamh, LOG_NOTICE, "Selected Security Context %s", newcon);
|
|
||||||
+
|
|
||||||
+ /* Get the string value of the context and see if it is valid. */
|
|
||||||
+ if (security_check_context(newcon)) {
|
|
||||||
+ pam_syslog(pamh, LOG_NOTICE, "Not a valid security context %s", newcon);
|
|
||||||
+ send_audit_message(pamh, 0, defaultcon, newcon);
|
|
||||||
+ freecon(newcon);
|
|
||||||
+ newcon = NULL;
|
|
||||||
+
|
|
||||||
+ goto fail_set;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ /* we have to check that this user is allowed to go into the
|
|
||||||
+ range they have specified ... role is tied to an seuser, so that'll
|
|
||||||
+ be checked at setexeccon time */
|
|
||||||
+ if (mls_enabled && !mls_range_allowed(pamh, defaultcon, newcon, debug)) {
|
|
||||||
+ pam_syslog(pamh, LOG_NOTICE, "Security context %s is not allowed for %s", defaultcon, newcon);
|
|
||||||
+ send_audit_message(pamh, 0, defaultcon, newcon);
|
|
||||||
+ freecon(newcon);
|
|
||||||
+ newcon = NULL;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ fail_set:
|
|
||||||
+ free(type);
|
|
||||||
+ context_free(my_context);
|
|
||||||
+ context_free(new_context);
|
|
||||||
+ send_audit_message(pamh, 0, defaultcon, NULL);
|
|
||||||
+ return newcon;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
static void
|
|
||||||
security_restorelabel_tty(const pam_handle_t *pamh,
|
|
||||||
const char *tty, security_context_t context)
|
|
||||||
@@ -439,13 +569,14 @@ PAM_EXTERN int
|
|
||||||
pam_sm_open_session(pam_handle_t *pamh, int flags UNUSED,
|
|
||||||
int argc, const char **argv)
|
|
||||||
{
|
|
||||||
- int i, debug = 0, ttys=1, has_tty=isatty(0);
|
|
||||||
+ int i, debug = 0, ttys=1;
|
|
||||||
int verbose=0, close_session=0;
|
|
||||||
int select_context = 0;
|
|
||||||
int use_current_range = 0;
|
|
||||||
int ret = 0;
|
|
||||||
security_context_t* contextlist = NULL;
|
|
||||||
int num_contexts = 0;
|
|
||||||
+ int env_params = 0;
|
|
||||||
const char *username = NULL;
|
|
||||||
const void *tty = NULL;
|
|
||||||
char *seuser=NULL;
|
|
||||||
@@ -472,13 +603,16 @@ pam_sm_open_session(pam_handle_t *pamh,
|
|
||||||
if (strcmp(argv[i], "use_current_range") == 0) {
|
|
||||||
use_current_range = 1;
|
|
||||||
}
|
|
||||||
+ if (strcmp(argv[i], "env_params") == 0) {
|
|
||||||
+ env_params = 1;
|
|
||||||
+ }
|
|
||||||
}
|
|
||||||
|
|
||||||
if (debug)
|
|
||||||
pam_syslog(pamh, LOG_NOTICE, "Open Session");
|
|
||||||
|
|
||||||
- if (select_context && use_current_range) {
|
|
||||||
- pam_syslog(pamh, LOG_ERR, "select_context cannot be used with use_current_range");
|
|
||||||
+ if (select_context && env_params) {
|
|
||||||
+ pam_syslog(pamh, LOG_ERR, "select_context cannot be used with env_params");
|
|
||||||
select_context = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -510,12 +644,17 @@ pam_sm_open_session(pam_handle_t *pamh,
|
|
||||||
freeconary(contextlist);
|
|
||||||
if (default_user_context == NULL) {
|
|
||||||
pam_syslog(pamh, LOG_ERR, "Out of memory");
|
|
||||||
- return PAM_AUTH_ERR;
|
|
||||||
+ return PAM_BUF_ERR;
|
|
||||||
}
|
|
||||||
+
|
|
||||||
user_context = default_user_context;
|
|
||||||
- if (select_context && has_tty) {
|
|
||||||
- user_context = config_context(pamh, default_user_context, debug);
|
|
||||||
- if (user_context == NULL) {
|
|
||||||
+ if (select_context) {
|
|
||||||
+ user_context = config_context(pamh, default_user_context, use_current_range, debug);
|
|
||||||
+ } else if (env_params || use_current_range) {
|
|
||||||
+ user_context = context_from_env(pamh, default_user_context, env_params, use_current_range, debug);
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ if (user_context == NULL) {
|
|
||||||
freecon(default_user_context);
|
|
||||||
pam_syslog(pamh, LOG_ERR, "Unable to get valid context for %s",
|
|
||||||
username);
|
|
||||||
@@ -524,11 +663,9 @@ pam_sm_open_session(pam_handle_t *pamh,
|
|
||||||
return PAM_AUTH_ERR;
|
|
||||||
else
|
|
||||||
return PAM_SUCCESS;
|
|
||||||
- }
|
|
||||||
- }
|
|
||||||
+ }
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
- if (has_tty) {
|
|
||||||
user_context = manual_context(pamh,seuser,debug);
|
|
||||||
if (user_context == NULL) {
|
|
||||||
pam_syslog (pamh, LOG_ERR, "Unable to get valid context for %s",
|
|
||||||
@@ -538,59 +675,6 @@ pam_sm_open_session(pam_handle_t *pamh,
|
|
||||||
else
|
|
||||||
return PAM_SUCCESS;
|
|
||||||
}
|
|
||||||
- } else {
|
|
||||||
- pam_syslog (pamh, LOG_ERR,
|
|
||||||
- "Unable to get valid context for %s, No valid tty",
|
|
||||||
- username);
|
|
||||||
- if (security_getenforce() == 1)
|
|
||||||
- return PAM_AUTH_ERR;
|
|
||||||
- else
|
|
||||||
- return PAM_SUCCESS;
|
|
||||||
- }
|
|
||||||
- }
|
|
||||||
-
|
|
||||||
- if (use_current_range && is_selinux_mls_enabled()) {
|
|
||||||
- security_context_t process_context=NULL;
|
|
||||||
- if (getcon(&process_context) == 0) {
|
|
||||||
- context_t pcon, ucon;
|
|
||||||
- char *process_level=NULL;
|
|
||||||
- security_context_t orig_context;
|
|
||||||
-
|
|
||||||
- if (user_context)
|
|
||||||
- orig_context = user_context;
|
|
||||||
- else
|
|
||||||
- orig_context = default_user_context;
|
|
||||||
-
|
|
||||||
- pcon = context_new(process_context);
|
|
||||||
- freecon(process_context);
|
|
||||||
- process_level = strdup(context_range_get(pcon));
|
|
||||||
- context_free(pcon);
|
|
||||||
-
|
|
||||||
- if (debug)
|
|
||||||
- pam_syslog (pamh, LOG_DEBUG, "process level=%s", process_level);
|
|
||||||
-
|
|
||||||
- ucon = context_new(orig_context);
|
|
||||||
-
|
|
||||||
- context_range_set(ucon, process_level);
|
|
||||||
- free(process_level);
|
|
||||||
-
|
|
||||||
- if (!mls_range_allowed(pamh, orig_context, context_str(ucon), debug)) {
|
|
||||||
- send_text(pamh, _("Requested MLS level not in permitted range"), debug);
|
|
||||||
- /* even if default_user_context is NULL audit that anyway */
|
|
||||||
- send_audit_message(pamh, 0, default_user_context, context_str(ucon));
|
|
||||||
- context_free(ucon);
|
|
||||||
- return PAM_AUTH_ERR;
|
|
||||||
- }
|
|
||||||
-
|
|
||||||
- if (debug)
|
|
||||||
- pam_syslog (pamh, LOG_DEBUG, "adjusted context=%s", context_str(ucon));
|
|
||||||
-
|
|
||||||
- /* replace the user context with the level adjusted one */
|
|
||||||
- freecon(user_context);
|
|
||||||
- user_context = strdup(context_str(ucon));
|
|
||||||
-
|
|
||||||
- context_free(ucon);
|
|
||||||
- }
|
|
||||||
}
|
|
||||||
|
|
||||||
if (getexeccon(&prev_user_context)<0) {
|
|
||||||
@@ -613,7 +697,7 @@ pam_sm_open_session(pam_handle_t *pamh,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
- if(ttys && tty ) {
|
|
||||||
+ if (ttys && tty) {
|
|
||||||
ttyn=strdup(tty);
|
|
||||||
ttyn_context=security_label_tty(pamh,ttyn,user_context);
|
|
||||||
}
|
|
@ -1,16 +0,0 @@
|
|||||||
Index: pam_sepermit.c
|
|
||||||
===================================================================
|
|
||||||
RCS file: /cvsroot/pam/Linux-PAM/modules/pam_sepermit/pam_sepermit.c,v
|
|
||||||
retrieving revision 1.3
|
|
||||||
diff -u -p -r1.3 pam_sepermit.c
|
|
||||||
--- Linux-PAM/modules/pam_sepermit/pam_sepermit.c.orig 31 Mar 2008 10:31:50 -0000 1.3
|
|
||||||
+++ Linux-PAM/modules/pam_sepermit/pam_sepermit.c 15 Apr 2008 16:30:38 -0000
|
|
||||||
@@ -305,7 +305,7 @@ sepermit_match(pam_handle_t *pamh, const
|
|
||||||
free(line);
|
|
||||||
fclose(f);
|
|
||||||
if (matched)
|
|
||||||
- return exclusive ? sepermit_lock(pamh, user, debug) : 0;
|
|
||||||
+ return (geteuid() == 0 && exclusive) ? sepermit_lock(pamh, user, debug) : 0;
|
|
||||||
else
|
|
||||||
return -1;
|
|
||||||
}
|
|
@ -1,22 +0,0 @@
|
|||||||
diff -up Linux-PAM-1.0.1/configure.in.autoreconf Linux-PAM-1.0.1/configure.in
|
|
||||||
--- Linux-PAM-1.0.1/configure.in.autoreconf 2008-05-19 17:45:00.000000000 +0200
|
|
||||||
+++ Linux-PAM-1.0.1/configure.in 2008-05-20 15:24:54.000000000 +0200
|
|
||||||
@@ -72,7 +72,7 @@ fi
|
|
||||||
AM_CONDITIONAL([STATIC_MODULES], [test "$STATIC_MODULES" != "no"])
|
|
||||||
|
|
||||||
dnl Checks for programs.
|
|
||||||
-AC_GNU_SOURCE
|
|
||||||
+AC_USE_SYSTEM_EXTENSIONS
|
|
||||||
AC_PROG_CC
|
|
||||||
AC_PROG_YACC
|
|
||||||
AM_PROG_LEX
|
|
||||||
@@ -491,8 +491,7 @@ AM_GNU_GETTEXT_VERSION
|
|
||||||
AM_GNU_GETTEXT([external])
|
|
||||||
AC_CHECK_FUNCS(dngettext)
|
|
||||||
|
|
||||||
-AH_VERBATIM([_ZZENABLE_NLS],
|
|
||||||
-[#ifdef ENABLE_NLS
|
|
||||||
+AH_BOTTOM([#ifdef ENABLE_NLS
|
|
||||||
#include <libintl.h>
|
|
||||||
#define _(msgid) dgettext(PACKAGE, msgid)
|
|
||||||
#define N_(msgid) msgid
|
|
@ -1,47 +0,0 @@
|
|||||||
diff -up Linux-PAM-1.0.1/modules/pam_cracklib/pam_cracklib.c.try-first-pass Linux-PAM-1.0.1/modules/pam_cracklib/pam_cracklib.c
|
|
||||||
--- Linux-PAM-1.0.1/modules/pam_cracklib/pam_cracklib.c.try-first-pass 2008-03-05 21:21:38.000000000 +0100
|
|
||||||
+++ Linux-PAM-1.0.1/modules/pam_cracklib/pam_cracklib.c 2008-09-05 21:35:18.000000000 +0200
|
|
||||||
@@ -98,6 +98,7 @@ struct cracklib_options {
|
|
||||||
int oth_credit;
|
|
||||||
int min_class;
|
|
||||||
int use_authtok;
|
|
||||||
+ int try_first_pass;
|
|
||||||
char prompt_type[BUFSIZ];
|
|
||||||
const char *cracklib_dictpath;
|
|
||||||
};
|
|
||||||
@@ -169,6 +170,10 @@ _pam_parse (pam_handle_t *pamh, struct c
|
|
||||||
opt->min_class = 4 ;
|
|
||||||
} else if (!strncmp(*argv,"use_authtok",11)) {
|
|
||||||
opt->use_authtok = 1;
|
|
||||||
+ } else if (!strncmp(*argv,"use_first_pass",14)) {
|
|
||||||
+ opt->use_authtok = 1;
|
|
||||||
+ } else if (!strncmp(*argv,"try_first_pass",14)) {
|
|
||||||
+ opt->try_first_pass = 1;
|
|
||||||
} else if (!strncmp(*argv,"dictpath=",9)) {
|
|
||||||
opt->cracklib_dictpath = *argv+9;
|
|
||||||
if (!*(opt->cracklib_dictpath)) {
|
|
||||||
@@ -619,7 +624,7 @@ PAM_EXTERN int pam_sm_chauthtok(pam_hand
|
|
||||||
* set PAM_AUTHTOK and return
|
|
||||||
*/
|
|
||||||
|
|
||||||
- if (options.use_authtok == 1) {
|
|
||||||
+ if (options.use_authtok == 1 || options.try_first_pass == 1) {
|
|
||||||
const void *item = NULL;
|
|
||||||
|
|
||||||
retval = pam_get_item(pamh, PAM_AUTHTOK, &item);
|
|
||||||
@@ -630,11 +635,13 @@ PAM_EXTERN int pam_sm_chauthtok(pam_hand
|
|
||||||
} else if (item != NULL) { /* we have a password! */
|
|
||||||
token1 = x_strdup(item);
|
|
||||||
item = NULL;
|
|
||||||
+ options.use_authtok = 1; /* don't ask for the password again */
|
|
||||||
} else {
|
|
||||||
retval = PAM_AUTHTOK_RECOVERY_ERR; /* didn't work */
|
|
||||||
}
|
|
||||||
-
|
|
||||||
- } else {
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ if (options.use_authtok != 1) {
|
|
||||||
/* Prepare to ask the user for the first time */
|
|
||||||
resp = NULL;
|
|
||||||
retval = pam_prompt (pamh, PAM_PROMPT_ECHO_OFF, &resp,
|
|
@ -1,679 +0,0 @@
|
|||||||
diff -up Linux-PAM-1.0.1/modules/pam_namespace/pam_namespace.c.create Linux-PAM-1.0.1/modules/pam_namespace/pam_namespace.c
|
|
||||||
--- Linux-PAM-1.0.1/modules/pam_namespace/pam_namespace.c.create 2008-03-20 18:06:32.000000000 +0100
|
|
||||||
+++ Linux-PAM-1.0.1/modules/pam_namespace/pam_namespace.c 2008-04-03 17:32:28.000000000 +0200
|
|
||||||
@@ -32,6 +32,8 @@
|
|
||||||
* DEALINGS IN THE SOFTWARE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
+#define _ATFILE_SOURCE
|
|
||||||
+
|
|
||||||
#include "pam_namespace.h"
|
|
||||||
#include "argv_parse.h"
|
|
||||||
|
|
||||||
@@ -78,11 +80,29 @@ static void del_polydir_list(struct poly
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
-static void cleanup_data(pam_handle_t *pamh UNUSED , void *data, int err UNUSED)
|
|
||||||
+static void unprotect_dirs(struct protect_dir_s *dir)
|
|
||||||
+{
|
|
||||||
+ struct protect_dir_s *next;
|
|
||||||
+
|
|
||||||
+ while (dir != NULL) {
|
|
||||||
+ umount(dir->dir);
|
|
||||||
+ free(dir->dir);
|
|
||||||
+ next = dir->next;
|
|
||||||
+ free(dir);
|
|
||||||
+ dir = next;
|
|
||||||
+ }
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static void cleanup_polydir_data(pam_handle_t *pamh UNUSED , void *data, int err UNUSED)
|
|
||||||
{
|
|
||||||
del_polydir_list(data);
|
|
||||||
}
|
|
||||||
|
|
||||||
+static void cleanup_protect_data(pam_handle_t *pamh UNUSED , void *data, int err UNUSED)
|
|
||||||
+{
|
|
||||||
+ unprotect_dirs(data);
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
static char *expand_variables(const char *orig, const char *var_names[], const char *var_values[])
|
|
||||||
{
|
|
||||||
const char *src = orig;
|
|
||||||
@@ -132,8 +152,8 @@ static char *expand_variables(const char
|
|
||||||
|
|
||||||
static int parse_create_params(char *params, struct polydir_s *poly)
|
|
||||||
{
|
|
||||||
- char *sptr;
|
|
||||||
- struct passwd *pwd;
|
|
||||||
+ char *next;
|
|
||||||
+ struct passwd *pwd = NULL;
|
|
||||||
struct group *grp;
|
|
||||||
|
|
||||||
poly->mode = (mode_t)ULONG_MAX;
|
|
||||||
@@ -144,28 +164,40 @@ static int parse_create_params(char *par
|
|
||||||
return 0;
|
|
||||||
params++;
|
|
||||||
|
|
||||||
- params = strtok_r(params, ",", &sptr);
|
|
||||||
- if (params == NULL)
|
|
||||||
- return 0;
|
|
||||||
+ next = strchr(params, ',');
|
|
||||||
+ if (next != NULL) {
|
|
||||||
+ *next = '\0';
|
|
||||||
+ next++;
|
|
||||||
+ }
|
|
||||||
|
|
||||||
- errno = 0;
|
|
||||||
- poly->mode = (mode_t)strtoul(params, NULL, 0);
|
|
||||||
- if (errno != 0) {
|
|
||||||
- poly->mode = (mode_t)ULONG_MAX;
|
|
||||||
+ if (*params != '\0') {
|
|
||||||
+ errno = 0;
|
|
||||||
+ poly->mode = (mode_t)strtoul(params, NULL, 0);
|
|
||||||
+ if (errno != 0) {
|
|
||||||
+ poly->mode = (mode_t)ULONG_MAX;
|
|
||||||
+ }
|
|
||||||
}
|
|
||||||
|
|
||||||
- params = strtok_r(NULL, ",", &sptr);
|
|
||||||
+ params = next;
|
|
||||||
if (params == NULL)
|
|
||||||
return 0;
|
|
||||||
+ next = strchr(params, ',');
|
|
||||||
+ if (next != NULL) {
|
|
||||||
+ *next = '\0';
|
|
||||||
+ next++;
|
|
||||||
+ }
|
|
||||||
|
|
||||||
- pwd = getpwnam(params); /* session modules are not reentrant */
|
|
||||||
- if (pwd == NULL)
|
|
||||||
- return -1;
|
|
||||||
- poly->owner = pwd->pw_uid;
|
|
||||||
-
|
|
||||||
- params = strtok_r(NULL, ",", &sptr);
|
|
||||||
- if (params == NULL) {
|
|
||||||
- poly->group = pwd->pw_gid;
|
|
||||||
+ if (*params != '\0') {
|
|
||||||
+ pwd = getpwnam(params); /* session modules are not reentrant */
|
|
||||||
+ if (pwd == NULL)
|
|
||||||
+ return -1;
|
|
||||||
+ poly->owner = pwd->pw_uid;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ params = next;
|
|
||||||
+ if (params == NULL || *params == '\0') {
|
|
||||||
+ if (pwd != NULL)
|
|
||||||
+ poly->group = pwd->pw_gid;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
grp = getgrnam(params);
|
|
||||||
@@ -199,7 +231,7 @@ static int parse_method(char *method, st
|
|
||||||
struct instance_data *idata)
|
|
||||||
{
|
|
||||||
enum polymethod pm;
|
|
||||||
- char *sptr;
|
|
||||||
+ char *sptr = NULL;
|
|
||||||
static const char *method_names[] = { "user", "context", "level", "tmpdir",
|
|
||||||
"tmpfs", NULL };
|
|
||||||
static const char *flag_names[] = { "create", "noinit", "iscript",
|
|
||||||
@@ -921,10 +953,158 @@ fail:
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
|
|
||||||
+static int protect_mount(int dfd, const char *path, struct instance_data *idata)
|
|
||||||
+{
|
|
||||||
+ struct protect_dir_s *dir = idata->protect_dirs;
|
|
||||||
+ char tmpbuf[64];
|
|
||||||
+
|
|
||||||
+ while (dir != NULL) {
|
|
||||||
+ if (strcmp(path, dir->dir) == 0) {
|
|
||||||
+ return 0;
|
|
||||||
+ }
|
|
||||||
+ dir = dir->next;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ dir = calloc(1, sizeof(*dir));
|
|
||||||
+
|
|
||||||
+ if (dir == NULL) {
|
|
||||||
+ return -1;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ dir->dir = strdup(path);
|
|
||||||
+
|
|
||||||
+ if (dir->dir == NULL) {
|
|
||||||
+ free(dir);
|
|
||||||
+ return -1;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ snprintf(tmpbuf, sizeof(tmpbuf), "/proc/self/fd/%d", dfd);
|
|
||||||
+
|
|
||||||
+ if (idata->flags & PAMNS_DEBUG) {
|
|
||||||
+ pam_syslog(idata->pamh, LOG_INFO,
|
|
||||||
+ "Protect mount of %s over itself", path);
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ if (mount(tmpbuf, tmpbuf, NULL, MS_BIND, NULL) != 0) {
|
|
||||||
+ int save_errno = errno;
|
|
||||||
+ pam_syslog(idata->pamh, LOG_ERR,
|
|
||||||
+ "Protect mount of %s failed: %m", tmpbuf);
|
|
||||||
+ free(dir->dir);
|
|
||||||
+ free(dir);
|
|
||||||
+ errno = save_errno;
|
|
||||||
+ return -1;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ dir->next = idata->protect_dirs;
|
|
||||||
+ idata->protect_dirs = dir;
|
|
||||||
+
|
|
||||||
+ return 0;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static int protect_dir(const char *path, mode_t mode, int do_mkdir,
|
|
||||||
+ struct instance_data *idata)
|
|
||||||
+{
|
|
||||||
+ char *p = strdup(path);
|
|
||||||
+ char *d;
|
|
||||||
+ char *dir = p;
|
|
||||||
+ int dfd = AT_FDCWD;
|
|
||||||
+ int dfd_next;
|
|
||||||
+ int save_errno;
|
|
||||||
+ int flags = O_RDONLY;
|
|
||||||
+ int rv = -1;
|
|
||||||
+ struct stat st;
|
|
||||||
+
|
|
||||||
+ if (p == NULL) {
|
|
||||||
+ goto error;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ if (*dir == '/') {
|
|
||||||
+ dfd = open("/", flags);
|
|
||||||
+ if (dfd == -1) {
|
|
||||||
+ goto error;
|
|
||||||
+ }
|
|
||||||
+ dir++; /* assume / is safe */
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ while ((d=strchr(dir, '/')) != NULL) {
|
|
||||||
+ *d = '\0';
|
|
||||||
+ dfd_next = openat(dfd, dir, flags);
|
|
||||||
+ if (dfd_next == -1) {
|
|
||||||
+ goto error;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ if (dfd != AT_FDCWD)
|
|
||||||
+ close(dfd);
|
|
||||||
+ dfd = dfd_next;
|
|
||||||
+
|
|
||||||
+ if (fstat(dfd, &st) != 0) {
|
|
||||||
+ goto error;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ if (flags & O_NOFOLLOW) {
|
|
||||||
+ /* we are inside user-owned dir - protect */
|
|
||||||
+ if (protect_mount(dfd, p, idata) == -1)
|
|
||||||
+ goto error;
|
|
||||||
+ } else if (st.st_uid != 0 || st.st_gid != 0 ||
|
|
||||||
+ (st.st_mode & S_IWOTH)) {
|
|
||||||
+ /* do not follow symlinks on subdirectories */
|
|
||||||
+ flags |= O_NOFOLLOW;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ *d = '/';
|
|
||||||
+ dir = d + 1;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ rv = openat(dfd, dir, flags);
|
|
||||||
+
|
|
||||||
+ if (rv == -1) {
|
|
||||||
+ if (!do_mkdir || mkdirat(dfd, dir, mode) != 0) {
|
|
||||||
+ goto error;
|
|
||||||
+ }
|
|
||||||
+ rv = openat(dfd, dir, flags);
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ if (rv != -1) {
|
|
||||||
+ if (fstat(rv, &st) != 0) {
|
|
||||||
+ save_errno = errno;
|
|
||||||
+ close(rv);
|
|
||||||
+ rv = -1;
|
|
||||||
+ errno = save_errno;
|
|
||||||
+ goto error;
|
|
||||||
+ }
|
|
||||||
+ if (!S_ISDIR(st.st_mode)) {
|
|
||||||
+ close(rv);
|
|
||||||
+ errno = ENOTDIR;
|
|
||||||
+ rv = -1;
|
|
||||||
+ goto error;
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ if (flags & O_NOFOLLOW) {
|
|
||||||
+ /* we are inside user-owned dir - protect */
|
|
||||||
+ if (protect_mount(rv, p, idata) == -1) {
|
|
||||||
+ save_errno = errno;
|
|
||||||
+ close(rv);
|
|
||||||
+ rv = -1;
|
|
||||||
+ errno = save_errno;
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+error:
|
|
||||||
+ save_errno = errno;
|
|
||||||
+ free(p);
|
|
||||||
+ if (dfd != AT_FDCWD)
|
|
||||||
+ close(dfd);
|
|
||||||
+ errno = save_errno;
|
|
||||||
+
|
|
||||||
+ return rv;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
static int check_inst_parent(char *ipath, struct instance_data *idata)
|
|
||||||
{
|
|
||||||
struct stat instpbuf;
|
|
||||||
char *inst_parent, *trailing_slash;
|
|
||||||
+ int dfd;
|
|
||||||
/*
|
|
||||||
* stat the instance parent path to make sure it exists
|
|
||||||
* and is a directory. Check that its mode is 000 (unless the
|
|
||||||
@@ -942,30 +1122,27 @@ static int check_inst_parent(char *ipath
|
|
||||||
if (trailing_slash)
|
|
||||||
*trailing_slash = '\0';
|
|
||||||
|
|
||||||
- if (stat(inst_parent, &instpbuf) < 0) {
|
|
||||||
- pam_syslog(idata->pamh, LOG_ERR, "Error stating %s, %m", inst_parent);
|
|
||||||
- free(inst_parent);
|
|
||||||
- return PAM_SESSION_ERR;
|
|
||||||
- }
|
|
||||||
+ dfd = protect_dir(inst_parent, 0, 1, idata);
|
|
||||||
|
|
||||||
- /*
|
|
||||||
- * Make sure we are dealing with a directory
|
|
||||||
- */
|
|
||||||
- if (!S_ISDIR(instpbuf.st_mode)) {
|
|
||||||
- pam_syslog(idata->pamh, LOG_ERR, "Instance parent %s is not a dir",
|
|
||||||
- inst_parent);
|
|
||||||
+ if (dfd == -1 || fstat(dfd, &instpbuf) < 0) {
|
|
||||||
+ pam_syslog(idata->pamh, LOG_ERR,
|
|
||||||
+ "Error creating or accessing instance parent %s, %m", inst_parent);
|
|
||||||
+ if (dfd != -1)
|
|
||||||
+ close(dfd);
|
|
||||||
free(inst_parent);
|
|
||||||
return PAM_SESSION_ERR;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((idata->flags & PAMNS_IGN_INST_PARENT_MODE) == 0) {
|
|
||||||
- if (instpbuf.st_mode & (S_IRWXU|S_IRWXG|S_IRWXO)) {
|
|
||||||
- pam_syslog(idata->pamh, LOG_ERR, "Mode of inst parent %s not 000",
|
|
||||||
+ if ((instpbuf.st_mode & (S_IRWXU|S_IRWXG|S_IRWXO)) || instpbuf.st_uid != 0) {
|
|
||||||
+ pam_syslog(idata->pamh, LOG_ERR, "Mode of inst parent %s not 000 or owner not root",
|
|
||||||
inst_parent);
|
|
||||||
+ close(dfd);
|
|
||||||
free(inst_parent);
|
|
||||||
return PAM_SESSION_ERR;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+ close(dfd);
|
|
||||||
free(inst_parent);
|
|
||||||
return PAM_SUCCESS;
|
|
||||||
}
|
|
||||||
@@ -1051,6 +1228,8 @@ static int create_polydir(struct polydir
|
|
||||||
security_context_t dircon, oldcon = NULL;
|
|
||||||
#endif
|
|
||||||
const char *dir = polyptr->dir;
|
|
||||||
+ uid_t uid;
|
|
||||||
+ gid_t gid;
|
|
||||||
|
|
||||||
if (polyptr->mode != (mode_t)ULONG_MAX)
|
|
||||||
mode = polyptr->mode;
|
|
||||||
@@ -1077,8 +1256,8 @@ static int create_polydir(struct polydir
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
- rc = mkdir(dir, mode);
|
|
||||||
- if (rc != 0) {
|
|
||||||
+ rc = protect_dir(dir, mode, 1, idata);
|
|
||||||
+ if (rc == -1) {
|
|
||||||
pam_syslog(idata->pamh, LOG_ERR,
|
|
||||||
"Error creating directory %s: %m", dir);
|
|
||||||
return PAM_SESSION_ERR;
|
|
||||||
@@ -1098,36 +1277,41 @@ static int create_polydir(struct polydir
|
|
||||||
|
|
||||||
if (polyptr->mode != (mode_t)ULONG_MAX) {
|
|
||||||
/* explicit mode requested */
|
|
||||||
- if (chmod(dir, mode) != 0) {
|
|
||||||
+ if (fchmod(rc, mode) != 0) {
|
|
||||||
pam_syslog(idata->pamh, LOG_ERR,
|
|
||||||
"Error changing mode of directory %s: %m", dir);
|
|
||||||
+ close(rc);
|
|
||||||
+ umount(dir); /* undo the eventual protection bind mount */
|
|
||||||
rmdir(dir);
|
|
||||||
return PAM_SESSION_ERR;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
- if (polyptr->owner != (uid_t)ULONG_MAX) {
|
|
||||||
- if (chown(dir, polyptr->owner, polyptr->group) != 0) {
|
|
||||||
- pam_syslog(idata->pamh, LOG_ERR,
|
|
||||||
- "Unable to change owner on directory %s: %m", dir);
|
|
||||||
- rmdir(dir);
|
|
||||||
- return PAM_SESSION_ERR;
|
|
||||||
- }
|
|
||||||
- if (idata->flags & PAMNS_DEBUG)
|
|
||||||
- pam_syslog(idata->pamh, LOG_DEBUG,
|
|
||||||
- "Polydir owner %u group %u from configuration", polyptr->owner, polyptr->group);
|
|
||||||
- } else {
|
|
||||||
- if (chown(dir, idata->uid, idata->gid) != 0) {
|
|
||||||
- pam_syslog(idata->pamh, LOG_ERR,
|
|
||||||
- "Unable to change owner on directory %s: %m", dir);
|
|
||||||
- rmdir(dir);
|
|
||||||
- return PAM_SESSION_ERR;
|
|
||||||
- }
|
|
||||||
- if (idata->flags & PAMNS_DEBUG)
|
|
||||||
- pam_syslog(idata->pamh, LOG_DEBUG,
|
|
||||||
- "Polydir owner %u group %u", idata->uid, idata->gid);
|
|
||||||
+ if (polyptr->owner != (uid_t)ULONG_MAX)
|
|
||||||
+ uid = polyptr->owner;
|
|
||||||
+ else
|
|
||||||
+ uid = idata->uid;
|
|
||||||
+
|
|
||||||
+ if (polyptr->group != (gid_t)ULONG_MAX)
|
|
||||||
+ gid = polyptr->group;
|
|
||||||
+ else
|
|
||||||
+ gid = idata->gid;
|
|
||||||
+
|
|
||||||
+ if (fchown(rc, uid, gid) != 0) {
|
|
||||||
+ pam_syslog(idata->pamh, LOG_ERR,
|
|
||||||
+ "Unable to change owner on directory %s: %m", dir);
|
|
||||||
+ close(rc);
|
|
||||||
+ umount(dir); /* undo the eventual protection bind mount */
|
|
||||||
+ rmdir(dir);
|
|
||||||
+ return PAM_SESSION_ERR;
|
|
||||||
}
|
|
||||||
|
|
||||||
+ close(rc);
|
|
||||||
+
|
|
||||||
+ if (idata->flags & PAMNS_DEBUG)
|
|
||||||
+ pam_syslog(idata->pamh, LOG_DEBUG,
|
|
||||||
+ "Polydir owner %u group %u", uid, gid);
|
|
||||||
+
|
|
||||||
return PAM_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -1135,17 +1319,16 @@ static int create_polydir(struct polydir
|
|
||||||
* Create polyinstantiated instance directory (ipath).
|
|
||||||
*/
|
|
||||||
#ifdef WITH_SELINUX
|
|
||||||
-static int create_dirs(struct polydir_s *polyptr, char *ipath, struct stat *statbuf,
|
|
||||||
+static int create_instance(struct polydir_s *polyptr, char *ipath, struct stat *statbuf,
|
|
||||||
security_context_t icontext, security_context_t ocontext,
|
|
||||||
struct instance_data *idata)
|
|
||||||
#else
|
|
||||||
-static int create_dirs(struct polydir_s *polyptr, char *ipath, struct stat *statbuf,
|
|
||||||
+static int create_instance(struct polydir_s *polyptr, char *ipath, struct stat *statbuf,
|
|
||||||
struct instance_data *idata)
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
struct stat newstatbuf;
|
|
||||||
int fd;
|
|
||||||
- int newdir = 0;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Check to make sure instance parent is valid.
|
|
||||||
@@ -1171,7 +1354,7 @@ static int create_dirs(struct polydir_s
|
|
||||||
strcpy(ipath, polyptr->instance_prefix);
|
|
||||||
} else if (mkdir(ipath, S_IRUSR) < 0) {
|
|
||||||
if (errno == EEXIST)
|
|
||||||
- goto inst_init;
|
|
||||||
+ return PAM_IGNORE;
|
|
||||||
else {
|
|
||||||
pam_syslog(idata->pamh, LOG_ERR, "Error creating %s, %m",
|
|
||||||
ipath);
|
|
||||||
@@ -1179,7 +1362,6 @@ static int create_dirs(struct polydir_s
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
- newdir = 1;
|
|
||||||
/* Open a descriptor to it to prevent races */
|
|
||||||
fd = open(ipath, O_DIRECTORY | O_RDONLY);
|
|
||||||
if (fd < 0) {
|
|
||||||
@@ -1235,33 +1417,22 @@ static int create_dirs(struct polydir_s
|
|
||||||
return PAM_SESSION_ERR;
|
|
||||||
}
|
|
||||||
close(fd);
|
|
||||||
-
|
|
||||||
- /*
|
|
||||||
- * Check to see if there is a namespace initialization script in
|
|
||||||
- * the /etc/security directory. If such a script exists
|
|
||||||
- * execute it and pass directory to polyinstantiate and instance
|
|
||||||
- * directory as arguments.
|
|
||||||
- */
|
|
||||||
-
|
|
||||||
-inst_init:
|
|
||||||
- if (polyptr->flags & POLYDIR_NOINIT)
|
|
||||||
- return PAM_SUCCESS;
|
|
||||||
-
|
|
||||||
- return inst_init(polyptr, ipath, idata, newdir);
|
|
||||||
+ return PAM_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* This function performs the namespace setup for a particular directory
|
|
||||||
- * that is being polyinstantiated. It creates an MD5 hash of instance
|
|
||||||
- * directory, calls create_dirs to create it with appropriate
|
|
||||||
+ * that is being polyinstantiated. It calls poly_name to create name of instance
|
|
||||||
+ * directory, calls create_instance to mkdir it with appropriate
|
|
||||||
* security attributes, and performs bind mount to setup the process
|
|
||||||
* namespace.
|
|
||||||
*/
|
|
||||||
static int ns_setup(struct polydir_s *polyptr,
|
|
||||||
struct instance_data *idata)
|
|
||||||
{
|
|
||||||
- int retval = 0;
|
|
||||||
+ int retval;
|
|
||||||
+ int newdir = 1;
|
|
||||||
char *inst_dir = NULL;
|
|
||||||
char *instname = NULL;
|
|
||||||
struct stat statbuf;
|
|
||||||
@@ -1273,37 +1444,40 @@ static int ns_setup(struct polydir_s *po
|
|
||||||
pam_syslog(idata->pamh, LOG_DEBUG,
|
|
||||||
"Set namespace for directory %s", polyptr->dir);
|
|
||||||
|
|
||||||
- while (stat(polyptr->dir, &statbuf) < 0) {
|
|
||||||
- if (retval || !(polyptr->flags & POLYDIR_CREATE)) {
|
|
||||||
- pam_syslog(idata->pamh, LOG_ERR, "Error stating %s, %m",
|
|
||||||
- polyptr->dir);
|
|
||||||
- return PAM_SESSION_ERR;
|
|
||||||
- } else {
|
|
||||||
- if (create_polydir(polyptr, idata) != PAM_SUCCESS)
|
|
||||||
- return PAM_SESSION_ERR;
|
|
||||||
- retval = PAM_SESSION_ERR; /* bail out on next failed stat */
|
|
||||||
- }
|
|
||||||
- }
|
|
||||||
+ retval = protect_dir(polyptr->dir, 0, 0, idata);
|
|
||||||
|
|
||||||
- /*
|
|
||||||
- * Make sure we are dealing with a directory
|
|
||||||
- */
|
|
||||||
- if (!S_ISDIR(statbuf.st_mode)) {
|
|
||||||
- pam_syslog(idata->pamh, LOG_ERR, "Polydir %s is not a dir",
|
|
||||||
+ if (retval < 0 && errno != ENOENT) {
|
|
||||||
+ pam_syslog(idata->pamh, LOG_ERR, "Polydir %s access error: %m",
|
|
||||||
polyptr->dir);
|
|
||||||
- return PAM_SESSION_ERR;
|
|
||||||
+ return PAM_SESSION_ERR;
|
|
||||||
}
|
|
||||||
|
|
||||||
+ if (retval < 0 && (polyptr->flags & POLYDIR_CREATE)) {
|
|
||||||
+ if (create_polydir(polyptr, idata) != PAM_SUCCESS)
|
|
||||||
+ return PAM_SESSION_ERR;
|
|
||||||
+ } else {
|
|
||||||
+ close(retval);
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
if (polyptr->method == TMPFS) {
|
|
||||||
if (mount("tmpfs", polyptr->dir, "tmpfs", 0, NULL) < 0) {
|
|
||||||
pam_syslog(idata->pamh, LOG_ERR, "Error mounting tmpfs on %s, %m",
|
|
||||||
polyptr->dir);
|
|
||||||
return PAM_SESSION_ERR;
|
|
||||||
}
|
|
||||||
- /* we must call inst_init after the mount in this case */
|
|
||||||
+
|
|
||||||
+ if (polyptr->flags & POLYDIR_NOINIT)
|
|
||||||
+ return PAM_SUCCESS;
|
|
||||||
+
|
|
||||||
return inst_init(polyptr, "tmpfs", idata, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
+ if (stat(polyptr->dir, &statbuf) < 0) {
|
|
||||||
+ pam_syslog(idata->pamh, LOG_ERR, "Error stating %s: %m",
|
|
||||||
+ polyptr->dir);
|
|
||||||
+ return PAM_SESSION_ERR;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
/*
|
|
||||||
* Obtain the name of instance pathname based on the
|
|
||||||
* polyinstantiation method and instance context returned by
|
|
||||||
@@ -1341,14 +1515,18 @@ static int ns_setup(struct polydir_s *po
|
|
||||||
* contexts, owner, group and mode bits.
|
|
||||||
*/
|
|
||||||
#ifdef WITH_SELINUX
|
|
||||||
- retval = create_dirs(polyptr, inst_dir, &statbuf, instcontext,
|
|
||||||
+ retval = create_instance(polyptr, inst_dir, &statbuf, instcontext,
|
|
||||||
origcontext, idata);
|
|
||||||
#else
|
|
||||||
- retval = create_dirs(polyptr, inst_dir, &statbuf, idata);
|
|
||||||
+ retval = create_instance(polyptr, inst_dir, &statbuf, idata);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
- if (retval < 0) {
|
|
||||||
- pam_syslog(idata->pamh, LOG_ERR, "Error creating instance dir");
|
|
||||||
+ if (retval == PAM_IGNORE) {
|
|
||||||
+ newdir = 0;
|
|
||||||
+ retval = PAM_SUCCESS;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ if (retval != PAM_SUCCESS) {
|
|
||||||
goto error_out;
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -1363,6 +1541,9 @@ static int ns_setup(struct polydir_s *po
|
|
||||||
goto error_out;
|
|
||||||
}
|
|
||||||
|
|
||||||
+ if (!(polyptr->flags & POLYDIR_NOINIT))
|
|
||||||
+ retval = inst_init(polyptr, inst_dir, idata, newdir);
|
|
||||||
+
|
|
||||||
goto cleanup;
|
|
||||||
|
|
||||||
/*
|
|
||||||
@@ -1600,12 +1781,21 @@ static int setup_namespace(struct instan
|
|
||||||
}
|
|
||||||
}
|
|
||||||
out:
|
|
||||||
- if (retval != PAM_SUCCESS)
|
|
||||||
+ if (retval != PAM_SUCCESS) {
|
|
||||||
+ cleanup_tmpdirs(idata);
|
|
||||||
+ unprotect_dirs(idata->protect_dirs);
|
|
||||||
+ } else if (pam_set_data(idata->pamh, NAMESPACE_PROTECT_DATA, idata->protect_dirs,
|
|
||||||
+ cleanup_protect_data) != PAM_SUCCESS) {
|
|
||||||
+ pam_syslog(idata->pamh, LOG_ERR, "Unable to set namespace protect data");
|
|
||||||
cleanup_tmpdirs(idata);
|
|
||||||
- else if (pam_set_data(idata->pamh, NAMESPACE_POLYDIR_DATA, idata->polydirs_ptr,
|
|
||||||
- cleanup_data) != PAM_SUCCESS) {
|
|
||||||
- pam_syslog(idata->pamh, LOG_ERR, "Unable to set namespace data");
|
|
||||||
+ unprotect_dirs(idata->protect_dirs);
|
|
||||||
+ return PAM_SYSTEM_ERR;
|
|
||||||
+ } else if (pam_set_data(idata->pamh, NAMESPACE_POLYDIR_DATA, idata->polydirs_ptr,
|
|
||||||
+ cleanup_polydir_data) != PAM_SUCCESS) {
|
|
||||||
+ pam_syslog(idata->pamh, LOG_ERR, "Unable to set namespace polydir data");
|
|
||||||
cleanup_tmpdirs(idata);
|
|
||||||
+ pam_set_data(idata->pamh, NAMESPACE_PROTECT_DATA, NULL, NULL);
|
|
||||||
+ idata->protect_dirs = NULL;
|
|
||||||
return PAM_SYSTEM_ERR;
|
|
||||||
}
|
|
||||||
return retval;
|
|
||||||
@@ -1742,6 +1932,7 @@ PAM_EXTERN int pam_sm_open_session(pam_h
|
|
||||||
/* init instance data */
|
|
||||||
idata.flags = 0;
|
|
||||||
idata.polydirs_ptr = NULL;
|
|
||||||
+ idata.protect_dirs = NULL;
|
|
||||||
idata.pamh = pamh;
|
|
||||||
#ifdef WITH_SELINUX
|
|
||||||
if (is_selinux_enabled())
|
|
||||||
@@ -1893,6 +2084,7 @@ PAM_EXTERN int pam_sm_close_session(pam_
|
|
||||||
}
|
|
||||||
|
|
||||||
pam_set_data(idata.pamh, NAMESPACE_POLYDIR_DATA, NULL, NULL);
|
|
||||||
+ pam_set_data(idata.pamh, NAMESPACE_PROTECT_DATA, NULL, NULL);
|
|
||||||
|
|
||||||
return PAM_SUCCESS;
|
|
||||||
}
|
|
||||||
diff -up Linux-PAM-1.0.1/modules/pam_namespace/pam_namespace.h.create Linux-PAM-1.0.1/modules/pam_namespace/pam_namespace.h
|
|
||||||
--- Linux-PAM-1.0.1/modules/pam_namespace/pam_namespace.h.create 2008-02-13 13:49:44.000000000 +0100
|
|
||||||
+++ Linux-PAM-1.0.1/modules/pam_namespace/pam_namespace.h 2008-03-20 18:07:29.000000000 +0100
|
|
||||||
@@ -107,6 +107,7 @@
|
|
||||||
|
|
||||||
#define NAMESPACE_MAX_DIR_LEN 80
|
|
||||||
#define NAMESPACE_POLYDIR_DATA "pam_namespace:polydir_data"
|
|
||||||
+#define NAMESPACE_PROTECT_DATA "pam_namespace:protect_data"
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Polyinstantiation method options, based on user, security context
|
|
||||||
@@ -156,9 +157,15 @@ struct polydir_s {
|
|
||||||
struct polydir_s *next; /* pointer to the next polydir entry */
|
|
||||||
};
|
|
||||||
|
|
||||||
+struct protect_dir_s {
|
|
||||||
+ char *dir; /* protected directory */
|
|
||||||
+ struct protect_dir_s *next; /* next entry */
|
|
||||||
+};
|
|
||||||
+
|
|
||||||
struct instance_data {
|
|
||||||
pam_handle_t *pamh; /* The pam handle for this instance */
|
|
||||||
struct polydir_s *polydirs_ptr; /* The linked list pointer */
|
|
||||||
+ struct protect_dir_s *protect_dirs; /* The pointer to stack of mount-protected dirs */
|
|
||||||
char user[LOGIN_NAME_MAX]; /* User name */
|
|
||||||
char ruser[LOGIN_NAME_MAX]; /* Requesting user name */
|
|
||||||
uid_t uid; /* The uid of the user */
|
|
||||||
@@ -166,3 +173,4 @@ struct instance_data {
|
|
||||||
uid_t ruid; /* The uid of the requesting user */
|
|
||||||
unsigned long flags; /* Flags for debug, selinux etc */
|
|
||||||
};
|
|
||||||
+
|
|
||||||
diff -up Linux-PAM-1.0.1/modules/pam_namespace/namespace.conf.5.xml.create Linux-PAM-1.0.1/modules/pam_namespace/namespace.conf.5.xml
|
|
||||||
--- Linux-PAM-1.0.1/modules/pam_namespace/namespace.conf.5.xml.create 2008-02-13 13:49:44.000000000 +0100
|
|
||||||
+++ Linux-PAM-1.0.1/modules/pam_namespace/namespace.conf.5.xml 2008-04-18 14:38:57.000000000 +0200
|
|
||||||
@@ -25,8 +25,8 @@
|
|
||||||
Directories can be polyinstantiated based on user name
|
|
||||||
or, in the case of SELinux, user name, sensitivity level or complete security context. If an
|
|
||||||
executable script <filename>/etc/security/namespace.init</filename>
|
|
||||||
- exists, it is used to initialize the namespace every time a new instance
|
|
||||||
- directory is setup. The script receives the polyinstantiated
|
|
||||||
+ exists, it is used to initialize the namespace every time an instance
|
|
||||||
+ directory is set up and mounted. The script receives the polyinstantiated
|
|
||||||
directory path and the instance directory path as its arguments.
|
|
||||||
</para>
|
|
||||||
|
|
||||||
diff -up Linux-PAM-1.0.1/modules/pam_namespace/pam_namespace.8.xml.create Linux-PAM-1.0.1/modules/pam_namespace/pam_namespace.8.xml
|
|
||||||
--- Linux-PAM-1.0.1/modules/pam_namespace/pam_namespace.8.xml.create 2008-02-13 13:49:44.000000000 +0100
|
|
||||||
+++ Linux-PAM-1.0.1/modules/pam_namespace/pam_namespace.8.xml 2008-04-18 14:40:54.000000000 +0200
|
|
||||||
@@ -64,11 +64,11 @@
|
|
||||||
provides a different instance of itself based on user name, or when
|
|
||||||
using SELinux, user name, security context or both. If an executable
|
|
||||||
script <filename>/etc/security/namespace.init</filename> exists, it
|
|
||||||
- is used to initialize the namespace every time a new instance
|
|
||||||
- directory is setup. The script receives the polyinstantiated
|
|
||||||
- directory path, the instance directory path, flag whether the instance
|
|
||||||
- directory was newly created (0 for no, 1 for yes), and the user name
|
|
||||||
- as its arguments.
|
|
||||||
+ is used to initialize the instance directory after it is set up
|
|
||||||
+ and mounted on the polyinstantiated direcory. The script receives the
|
|
||||||
+ polyinstantiated directory path, the instance directory path, flag
|
|
||||||
+ whether the instance directory was newly created (0 for no, 1 for yes),
|
|
||||||
+ and the user name as its arguments.
|
|
||||||
</para>
|
|
||||||
|
|
||||||
<para>
|
|
@ -1,27 +0,0 @@
|
|||||||
diff -up Linux-PAM-1.0.1/modules/pam_tally/pam_tally.c.fail-close Linux-PAM-1.0.1/modules/pam_tally/pam_tally.c
|
|
||||||
--- Linux-PAM-1.0.1/modules/pam_tally/pam_tally.c.fail-close 2007-11-20 11:58:11.000000000 +0100
|
|
||||||
+++ Linux-PAM-1.0.1/modules/pam_tally/pam_tally.c 2008-09-05 21:54:31.000000000 +0200
|
|
||||||
@@ -325,6 +325,7 @@ get_tally(pam_handle_t *pamh, tally_t *t
|
|
||||||
}
|
|
||||||
lstat_ret = fstat(fileno(*TALLY),&fileinfo);
|
|
||||||
fclose(*TALLY);
|
|
||||||
+ *TALLY = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( lstat_ret ) {
|
|
||||||
@@ -355,6 +356,7 @@ get_tally(pam_handle_t *pamh, tally_t *t
|
|
||||||
if ( fseeko( *TALLY, (off_t) uid * sizeof(struct faillog), SEEK_SET ) ) {
|
|
||||||
pam_syslog(pamh, LOG_ALERT, "fseek failed for %s", filename);
|
|
||||||
fclose(*TALLY);
|
|
||||||
+ *TALLY = NULL;
|
|
||||||
return PAM_AUTH_ERR;
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -403,6 +405,7 @@ set_tally(pam_handle_t *pamh, tally_t ta
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( fclose(*TALLY) ) {
|
|
||||||
+ *TALLY = NULL;
|
|
||||||
pam_syslog(pamh, LOG_ALERT, "update (fclose) failed for %s", filename);
|
|
||||||
return PAM_AUTH_ERR;
|
|
||||||
}
|
|
@ -1,31 +0,0 @@
|
|||||||
diff -up Linux-PAM-1.0.1/modules/pam_unix/pam_unix_passwd.c.prompts Linux-PAM-1.0.1/modules/pam_unix/pam_unix_passwd.c
|
|
||||||
--- Linux-PAM-1.0.1/modules/pam_unix/pam_unix_passwd.c.prompts 2008-02-29 16:22:03.000000000 +0100
|
|
||||||
+++ Linux-PAM-1.0.1/modules/pam_unix/pam_unix_passwd.c 2008-04-24 13:27:29.000000000 +0200
|
|
||||||
@@ -699,6 +699,10 @@ PAM_EXTERN int pam_sm_chauthtok(pam_hand
|
|
||||||
pass_new = NULL;
|
|
||||||
}
|
|
||||||
retval = _pam_unix_approve_pass(pamh, ctrl, pass_old, pass_new);
|
|
||||||
+
|
|
||||||
+ if (retval != PAM_SUCCESS && off(UNIX_NOT_SET_PASS, ctrl)) {
|
|
||||||
+ pam_set_item(pamh, PAM_AUTHTOK, NULL);
|
|
||||||
+ }
|
|
||||||
}
|
|
||||||
|
|
||||||
if (retval != PAM_SUCCESS) {
|
|
||||||
diff -up Linux-PAM-1.0.1/modules/pam_unix/support.c.prompts Linux-PAM-1.0.1/modules/pam_unix/support.c
|
|
||||||
--- Linux-PAM-1.0.1/modules/pam_unix/support.c.prompts 2008-01-23 16:35:13.000000000 +0100
|
|
||||||
+++ Linux-PAM-1.0.1/modules/pam_unix/support.c 2008-04-24 14:49:21.000000000 +0200
|
|
||||||
@@ -743,11 +743,11 @@ int _unix_read_password(pam_handle_t * p
|
|
||||||
return retval;
|
|
||||||
} else if (*pass != NULL) { /* we have a password! */
|
|
||||||
return PAM_SUCCESS;
|
|
||||||
- } else if (on(UNIX_USE_FIRST_PASS, ctrl)) {
|
|
||||||
- return PAM_AUTHTOK_RECOVERY_ERR; /* didn't work */
|
|
||||||
} else if (on(UNIX_USE_AUTHTOK, ctrl)
|
|
||||||
&& off(UNIX__OLD_PASSWD, ctrl)) {
|
|
||||||
return PAM_AUTHTOK_ERR;
|
|
||||||
+ } else if (on(UNIX_USE_FIRST_PASS, ctrl)) {
|
|
||||||
+ return PAM_AUTHTOK_RECOVERY_ERR; /* didn't work */
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/*
|
|
@ -1,257 +0,0 @@
|
|||||||
diff -up Linux-PAM-1.0.2/modules/pam_cracklib/pam_cracklib.8.xml.pwquality Linux-PAM-1.0.2/modules/pam_cracklib/pam_cracklib.8.xml
|
|
||||||
--- Linux-PAM-1.0.2/modules/pam_cracklib/pam_cracklib.8.xml.pwquality 2007-11-06 15:58:54.000000000 +0100
|
|
||||||
+++ Linux-PAM-1.0.2/modules/pam_cracklib/pam_cracklib.8.xml 2008-09-23 15:06:40.000000000 +0200
|
|
||||||
@@ -59,7 +59,7 @@
|
|
||||||
<term>Palindrome</term>
|
|
||||||
<listitem>
|
|
||||||
<para>
|
|
||||||
- Is the new password a palindrome of the old one?
|
|
||||||
+ Is the new password a palindrome?
|
|
||||||
</para>
|
|
||||||
</listitem>
|
|
||||||
</varlistentry>
|
|
||||||
@@ -120,6 +120,23 @@
|
|
||||||
</para>
|
|
||||||
</listitem>
|
|
||||||
</varlistentry>
|
|
||||||
+ <varlistentry>
|
|
||||||
+ <term>Same consecutive characters</term>
|
|
||||||
+ <listitem>
|
|
||||||
+ <para>
|
|
||||||
+ Optional check for same consecutive characters.
|
|
||||||
+ </para>
|
|
||||||
+ </listitem>
|
|
||||||
+ </varlistentry>
|
|
||||||
+ <varlistentry>
|
|
||||||
+ <term>Contains user name</term>
|
|
||||||
+ <listitem>
|
|
||||||
+ <para>
|
|
||||||
+ Optional check whether the password contains the user's name
|
|
||||||
+ in some form.
|
|
||||||
+ </para>
|
|
||||||
+ </listitem>
|
|
||||||
+ </varlistentry>
|
|
||||||
</variablelist>
|
|
||||||
<para>
|
|
||||||
This module with no arguments will work well for standard unix
|
|
||||||
@@ -281,7 +298,7 @@
|
|
||||||
than 10.
|
|
||||||
</para>
|
|
||||||
<para>
|
|
||||||
- (N > 0) This is the minimum number of upper
|
|
||||||
+ (N < 0) This is the minimum number of upper
|
|
||||||
case letters that must be met for a new password.
|
|
||||||
</para>
|
|
||||||
</listitem>
|
|
||||||
@@ -349,6 +366,50 @@
|
|
||||||
|
|
||||||
<varlistentry>
|
|
||||||
<term>
|
|
||||||
+ <option>minclass=<replaceable>N</replaceable></option>
|
|
||||||
+ </term>
|
|
||||||
+ <listitem>
|
|
||||||
+ <para>
|
|
||||||
+ The minimum number of required classes of characters for
|
|
||||||
+ the new password. The default number is zero. The four
|
|
||||||
+ classes are digits, upper and lower letters and other
|
|
||||||
+ characters.
|
|
||||||
+ The difference to the <option>credit</option> check is
|
|
||||||
+ that a specific class if of characters is not required.
|
|
||||||
+ Instead <replaceable>N</replaceable> out of four of the
|
|
||||||
+ classes are required.
|
|
||||||
+ </para>
|
|
||||||
+ </listitem>
|
|
||||||
+ </varlistentry>
|
|
||||||
+
|
|
||||||
+ <varlistentry>
|
|
||||||
+ <term>
|
|
||||||
+ <option>maxrepeat=<replaceable>N</replaceable></option>
|
|
||||||
+ </term>
|
|
||||||
+ <listitem>
|
|
||||||
+ <para>
|
|
||||||
+ Reject passwords which contain more than N same consecutive
|
|
||||||
+ characters. The default is 0 which means that this check
|
|
||||||
+ is disabled.
|
|
||||||
+ </para>
|
|
||||||
+ </listitem>
|
|
||||||
+ </varlistentry>
|
|
||||||
+
|
|
||||||
+ <varlistentry>
|
|
||||||
+ <term>
|
|
||||||
+ <option>reject_username</option>
|
|
||||||
+ </term>
|
|
||||||
+ <listitem>
|
|
||||||
+ <para>
|
|
||||||
+ Check whether the name of the user in straight or reversed
|
|
||||||
+ form is contained in the new password. If it is found the
|
|
||||||
+ new password is rejected.
|
|
||||||
+ </para>
|
|
||||||
+ </listitem>
|
|
||||||
+ </varlistentry>
|
|
||||||
+
|
|
||||||
+ <varlistentry>
|
|
||||||
+ <term>
|
|
||||||
<option>use_authtok</option>
|
|
||||||
</term>
|
|
||||||
<listitem>
|
|
||||||
@@ -495,7 +556,7 @@ password required pam_unix.so use_autht
|
|
||||||
<refentrytitle>pam.conf</refentrytitle><manvolnum>5</manvolnum>
|
|
||||||
</citerefentry>,
|
|
||||||
<citerefentry>
|
|
||||||
- <refentrytitle>pam.d</refentrytitle><manvolnum>8</manvolnum>
|
|
||||||
+ <refentrytitle>pam.d</refentrytitle><manvolnum>5</manvolnum>
|
|
||||||
</citerefentry>,
|
|
||||||
<citerefentry>
|
|
||||||
<refentrytitle>pam</refentrytitle><manvolnum>8</manvolnum>
|
|
||||||
diff -up Linux-PAM-1.0.2/modules/pam_cracklib/pam_cracklib.c.pwquality Linux-PAM-1.0.2/modules/pam_cracklib/pam_cracklib.c
|
|
||||||
--- Linux-PAM-1.0.2/modules/pam_cracklib/pam_cracklib.c.pwquality 2008-09-23 15:06:40.000000000 +0200
|
|
||||||
+++ Linux-PAM-1.0.2/modules/pam_cracklib/pam_cracklib.c 2008-09-23 15:10:14.000000000 +0200
|
|
||||||
@@ -99,6 +99,8 @@ struct cracklib_options {
|
|
||||||
int min_class;
|
|
||||||
int use_authtok;
|
|
||||||
int try_first_pass;
|
|
||||||
+ int max_repeat;
|
|
||||||
+ int reject_user;
|
|
||||||
char prompt_type[BUFSIZ];
|
|
||||||
const char *cracklib_dictpath;
|
|
||||||
};
|
|
||||||
@@ -166,8 +168,14 @@ _pam_parse (pam_handle_t *pamh, struct c
|
|
||||||
opt->min_class = strtol(*argv+9,&ep,10);
|
|
||||||
if (!ep)
|
|
||||||
opt->min_class = 0;
|
|
||||||
- if (opt->min_class > 4)
|
|
||||||
- opt->min_class = 4 ;
|
|
||||||
+ if (opt->min_class > 4)
|
|
||||||
+ opt->min_class = 4;
|
|
||||||
+ } else if (!strncmp(*argv,"maxrepeat=",10)) {
|
|
||||||
+ opt->max_repeat = strtol(*argv+10,&ep,10);
|
|
||||||
+ if (!ep)
|
|
||||||
+ opt->max_repeat = 0;
|
|
||||||
+ } else if (!strncmp(*argv,"reject_username",15)) {
|
|
||||||
+ opt->reject_user = 1;
|
|
||||||
} else if (!strncmp(*argv,"use_authtok",11)) {
|
|
||||||
opt->use_authtok = 1;
|
|
||||||
} else if (!strncmp(*argv,"use_first_pass",14)) {
|
|
||||||
@@ -418,6 +426,58 @@ static int simple(struct cracklib_option
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
+static int consecutive(struct cracklib_options *opt, const char *new)
|
|
||||||
+{
|
|
||||||
+ char c;
|
|
||||||
+ int i;
|
|
||||||
+ int same;
|
|
||||||
+
|
|
||||||
+ if (opt->max_repeat == 0)
|
|
||||||
+ return 0;
|
|
||||||
+
|
|
||||||
+ for (i = 0; new[i]; i++) {
|
|
||||||
+ if (i > 0 && new[i] == c) {
|
|
||||||
+ ++same;
|
|
||||||
+ if (same > opt->max_repeat)
|
|
||||||
+ return 1;
|
|
||||||
+ } else {
|
|
||||||
+ c = new[i];
|
|
||||||
+ same = 1;
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+ return 0;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static int usercheck(struct cracklib_options *opt, const char *new,
|
|
||||||
+ char *user)
|
|
||||||
+{
|
|
||||||
+ char *f, *b;
|
|
||||||
+
|
|
||||||
+ if (!opt->reject_user)
|
|
||||||
+ return 0;
|
|
||||||
+
|
|
||||||
+ if (strstr(new, user) != NULL)
|
|
||||||
+ return 1;
|
|
||||||
+
|
|
||||||
+ /* now reverse the username, we can do that in place
|
|
||||||
+ as it is strdup-ed */
|
|
||||||
+ f = user;
|
|
||||||
+ b = user+strlen(user)-1;
|
|
||||||
+ while (f < b) {
|
|
||||||
+ char c;
|
|
||||||
+
|
|
||||||
+ c = *f;
|
|
||||||
+ *f = *b;
|
|
||||||
+ *b = c;
|
|
||||||
+ --b;
|
|
||||||
+ ++f;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ if (strstr(new, user) != NULL)
|
|
||||||
+ return 1;
|
|
||||||
+ return 0;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
static char * str_lower(char *string)
|
|
||||||
{
|
|
||||||
char *cp;
|
|
||||||
@@ -428,10 +488,12 @@ static char * str_lower(char *string)
|
|
||||||
}
|
|
||||||
|
|
||||||
static const char *password_check(struct cracklib_options *opt,
|
|
||||||
- const char *old, const char *new)
|
|
||||||
+ const char *old, const char *new,
|
|
||||||
+ const char *user)
|
|
||||||
{
|
|
||||||
const char *msg = NULL;
|
|
||||||
char *oldmono = NULL, *newmono, *wrapped = NULL;
|
|
||||||
+ char *usermono = NULL;
|
|
||||||
|
|
||||||
if (old && strcmp(new, old) == 0) {
|
|
||||||
msg = _("is the same as the old one");
|
|
||||||
@@ -439,6 +501,7 @@ static const char *password_check(struct
|
|
||||||
}
|
|
||||||
|
|
||||||
newmono = str_lower(x_strdup(new));
|
|
||||||
+ usermono = str_lower(x_strdup(user));
|
|
||||||
if (old) {
|
|
||||||
oldmono = str_lower(x_strdup(old));
|
|
||||||
wrapped = malloc(strlen(oldmono) * 2 + 1);
|
|
||||||
@@ -464,8 +527,15 @@ static const char *password_check(struct
|
|
||||||
if (!msg && minclass (opt, new))
|
|
||||||
msg = _("not enough character classes");
|
|
||||||
|
|
||||||
+ if (!msg && consecutive(opt, new))
|
|
||||||
+ msg = _("contains too many same characters consecutively");
|
|
||||||
+
|
|
||||||
+ if (!msg && usercheck(opt, newmono, usermono))
|
|
||||||
+ msg = _("contains the user name in some form");
|
|
||||||
+
|
|
||||||
memset(newmono, 0, strlen(newmono));
|
|
||||||
free(newmono);
|
|
||||||
+ free(usermono);
|
|
||||||
if (old) {
|
|
||||||
memset(oldmono, 0, strlen(oldmono));
|
|
||||||
memset(wrapped, 0, strlen(wrapped));
|
|
||||||
@@ -532,18 +602,18 @@ static int _pam_unix_approve_pass(pam_ha
|
|
||||||
return PAM_AUTHTOK_ERR;
|
|
||||||
}
|
|
||||||
|
|
||||||
+ retval = pam_get_item(pamh, PAM_USER, &user);
|
|
||||||
+ if (retval != PAM_SUCCESS || user == NULL) {
|
|
||||||
+ if (ctrl & PAM_DEBUG_ARG)
|
|
||||||
+ pam_syslog(pamh,LOG_ERR,"Can not get username");
|
|
||||||
+ return PAM_AUTHTOK_ERR;
|
|
||||||
+ }
|
|
||||||
/*
|
|
||||||
* if one wanted to hardwire authentication token strength
|
|
||||||
* checking this would be the place
|
|
||||||
*/
|
|
||||||
- msg = password_check(opt, pass_old, pass_new);
|
|
||||||
+ msg = password_check(opt, pass_old, pass_new, user);
|
|
||||||
if (!msg) {
|
|
||||||
- retval = pam_get_item(pamh, PAM_USER, &user);
|
|
||||||
- if (retval != PAM_SUCCESS || user == NULL) {
|
|
||||||
- if (ctrl & PAM_DEBUG_ARG)
|
|
||||||
- pam_syslog(pamh,LOG_ERR,"Can not get username");
|
|
||||||
- return PAM_AUTHTOK_ERR;
|
|
||||||
- }
|
|
||||||
msg = check_old_password(user, pass_new);
|
|
||||||
}
|
|
||||||
|
|
@ -1,75 +0,0 @@
|
|||||||
diff -up Linux-PAM-1.0.2/libpam/pam_modutil_getpwnam.c.many-groups Linux-PAM-1.0.2/libpam/pam_modutil_getpwnam.c
|
|
||||||
--- Linux-PAM-1.0.2/libpam/pam_modutil_getpwnam.c.many-groups 2007-08-30 06:00:39.000000000 +0200
|
|
||||||
+++ Linux-PAM-1.0.2/libpam/pam_modutil_getpwnam.c 2008-09-23 15:59:46.000000000 +0200
|
|
||||||
@@ -104,7 +104,7 @@ pam_modutil_getpwnam(pam_handle_t *pamh,
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
- length <<= 2;
|
|
||||||
+ length <<= PWD_LENGTH_SHIFT;
|
|
||||||
|
|
||||||
} while (length < PWD_ABSURD_PWD_LENGTH);
|
|
||||||
|
|
||||||
diff -up Linux-PAM-1.0.2/libpam/pam_modutil_getpwuid.c.many-groups Linux-PAM-1.0.2/libpam/pam_modutil_getpwuid.c
|
|
||||||
--- Linux-PAM-1.0.2/libpam/pam_modutil_getpwuid.c.many-groups 2007-08-30 06:00:39.000000000 +0200
|
|
||||||
+++ Linux-PAM-1.0.2/libpam/pam_modutil_getpwuid.c 2008-09-23 15:59:59.000000000 +0200
|
|
||||||
@@ -115,7 +115,7 @@ pam_modutil_getpwuid(pam_handle_t *pamh,
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
- length <<= 2;
|
|
||||||
+ length <<= PWD_LENGTH_SHIFT;
|
|
||||||
|
|
||||||
} while (length < PWD_ABSURD_PWD_LENGTH);
|
|
||||||
|
|
||||||
diff -up Linux-PAM-1.0.2/libpam/pam_modutil_getgrnam.c.many-groups Linux-PAM-1.0.2/libpam/pam_modutil_getgrnam.c
|
|
||||||
--- Linux-PAM-1.0.2/libpam/pam_modutil_getgrnam.c.many-groups 2007-08-30 06:00:39.000000000 +0200
|
|
||||||
+++ Linux-PAM-1.0.2/libpam/pam_modutil_getgrnam.c 2008-09-23 15:59:29.000000000 +0200
|
|
||||||
@@ -104,7 +104,7 @@ pam_modutil_getgrnam(pam_handle_t *pamh,
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
- length <<= 2;
|
|
||||||
+ length <<= PWD_LENGTH_SHIFT;
|
|
||||||
|
|
||||||
} while (length < PWD_ABSURD_PWD_LENGTH);
|
|
||||||
|
|
||||||
diff -up Linux-PAM-1.0.2/libpam/pam_modutil_getspnam.c.many-groups Linux-PAM-1.0.2/libpam/pam_modutil_getspnam.c
|
|
||||||
--- Linux-PAM-1.0.2/libpam/pam_modutil_getspnam.c.many-groups 2007-08-30 06:00:39.000000000 +0200
|
|
||||||
+++ Linux-PAM-1.0.2/libpam/pam_modutil_getspnam.c 2008-09-23 16:00:11.000000000 +0200
|
|
||||||
@@ -104,7 +104,7 @@ pam_modutil_getspnam(pam_handle_t *pamh,
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
- length <<= 2;
|
|
||||||
+ length <<= PWD_LENGTH_SHIFT;
|
|
||||||
|
|
||||||
} while (length < PWD_ABSURD_PWD_LENGTH);
|
|
||||||
|
|
||||||
diff -up Linux-PAM-1.0.2/libpam/pam_modutil_getgrgid.c.many-groups Linux-PAM-1.0.2/libpam/pam_modutil_getgrgid.c
|
|
||||||
--- Linux-PAM-1.0.2/libpam/pam_modutil_getgrgid.c.many-groups 2007-08-30 06:00:39.000000000 +0200
|
|
||||||
+++ Linux-PAM-1.0.2/libpam/pam_modutil_getgrgid.c 2008-09-23 15:59:07.000000000 +0200
|
|
||||||
@@ -115,7 +115,7 @@ pam_modutil_getgrgid(pam_handle_t *pamh,
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
- length <<= 2;
|
|
||||||
+ length <<= PWD_LENGTH_SHIFT;
|
|
||||||
|
|
||||||
} while (length < PWD_ABSURD_PWD_LENGTH);
|
|
||||||
|
|
||||||
diff -up Linux-PAM-1.0.2/libpam/pam_modutil_private.h.many-groups Linux-PAM-1.0.2/libpam/pam_modutil_private.h
|
|
||||||
--- Linux-PAM-1.0.2/libpam/pam_modutil_private.h.many-groups 2005-09-21 12:00:58.000000000 +0200
|
|
||||||
+++ Linux-PAM-1.0.2/libpam/pam_modutil_private.h 2008-09-23 16:00:30.000000000 +0200
|
|
||||||
@@ -13,8 +13,9 @@
|
|
||||||
#include <security/pam_modules.h>
|
|
||||||
#include <security/pam_modutil.h>
|
|
||||||
|
|
||||||
-#define PWD_INITIAL_LENGTH 0x100
|
|
||||||
-#define PWD_ABSURD_PWD_LENGTH 0x8000
|
|
||||||
+#define PWD_INITIAL_LENGTH 0x400
|
|
||||||
+#define PWD_ABSURD_PWD_LENGTH 0x40001
|
|
||||||
+#define PWD_LENGTH_SHIFT 4 /* 2^4 == 16 */
|
|
||||||
|
|
||||||
extern void
|
|
||||||
pam_modutil_cleanup(pam_handle_t *pamh, void *data,
|
|
@ -1,36 +0,0 @@
|
|||||||
Index: pam_tally.c
|
|
||||||
===================================================================
|
|
||||||
RCS file: /cvsroot/pam/Linux-PAM/modules/pam_tally/pam_tally.c,v
|
|
||||||
retrieving revision 1.30
|
|
||||||
diff -u -p -r1.30 pam_tally.c
|
|
||||||
--- pam/modules/pam_tally/pam_tally.c 9 Jul 2008 12:23:23 -0000 1.30
|
|
||||||
+++ pam/modules/pam_tally/pam_tally.c 19 Sep 2008 12:29:21 -0000
|
|
||||||
@@ -350,7 +350,7 @@ get_tally(pam_handle_t *pamh, tally_t *t
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( ! ( *TALLY = fopen(filename,(*tally!=TALLY_HI)?"r+":"r") ) ) {
|
|
||||||
- pam_syslog(pamh, LOG_ALERT, "Error opening %s for update", filename);
|
|
||||||
+ pam_syslog(pamh, LOG_ALERT, "Error opening %s for %s", filename, *tally!=TALLY_HI?"update":"read");
|
|
||||||
|
|
||||||
/* Discovering why account service fails: e/uid are target user.
|
|
||||||
*
|
|
||||||
@@ -504,7 +504,7 @@ tally_check (time_t oldtime, pam_handle_
|
|
||||||
tally_t
|
|
||||||
deny = opts->deny;
|
|
||||||
tally_t
|
|
||||||
- tally = 0; /* !TALLY_HI --> Log opened for update */
|
|
||||||
+ tally = TALLY_HI;
|
|
||||||
long
|
|
||||||
lock_time = opts->lock_time;
|
|
||||||
|
|
||||||
@@ -515,6 +515,10 @@ tally_check (time_t oldtime, pam_handle_
|
|
||||||
i=get_tally(pamh, &tally, uid, opts->filename, &TALLY, fsp);
|
|
||||||
if ( i != PAM_SUCCESS ) { RETURN_ERROR( i ); }
|
|
||||||
|
|
||||||
+ if ( TALLY != NULL ) {
|
|
||||||
+ fclose(TALLY);
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
if ( !(opts->ctrl & OPT_MAGIC_ROOT) || getuid() ) { /* magic_root skips tally check */
|
|
||||||
|
|
||||||
/* To deny or not to deny; that is the question */
|
|
23
pam-1.0.90-redhat-modules.patch
Normal file
23
pam-1.0.90-redhat-modules.patch
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
diff -up Linux-PAM-1.0.90/modules/Makefile.am.redhat-modules Linux-PAM-1.0.90/modules/Makefile.am
|
||||||
|
--- Linux-PAM-1.0.90/modules/Makefile.am.redhat-modules 2008-11-29 08:27:35.000000000 +0100
|
||||||
|
+++ Linux-PAM-1.0.90/modules/Makefile.am 2008-12-16 13:40:16.000000000 +0100
|
||||||
|
@@ -3,6 +3,7 @@
|
||||||
|
#
|
||||||
|
|
||||||
|
SUBDIRS = pam_access pam_cracklib pam_debug pam_deny pam_echo \
|
||||||
|
+ pam_chroot pam_console pam_postgresok \
|
||||||
|
pam_env pam_exec pam_faildelay pam_filter pam_ftp \
|
||||||
|
pam_group pam_issue pam_keyinit pam_lastlog pam_limits \
|
||||||
|
pam_listfile pam_localuser pam_loginuid pam_mail \
|
||||||
|
diff -up Linux-PAM-1.0.90/configure.in.redhat-modules Linux-PAM-1.0.90/configure.in
|
||||||
|
--- Linux-PAM-1.0.90/configure.in.redhat-modules 2008-12-02 16:25:01.000000000 +0100
|
||||||
|
+++ Linux-PAM-1.0.90/configure.in 2008-12-16 13:39:11.000000000 +0100
|
||||||
|
@@ -531,6 +531,8 @@ AC_CONFIG_FILES([Makefile libpam/Makefil
|
||||||
|
libpam_misc/Makefile conf/Makefile conf/pam_conv1/Makefile \
|
||||||
|
po/Makefile.in \
|
||||||
|
modules/Makefile \
|
||||||
|
+ modules/pam_chroot/Makefile modules/pam_console/Makefile \
|
||||||
|
+ modules/pam_postgresok/Makefile \
|
||||||
|
modules/pam_access/Makefile modules/pam_cracklib/Makefile \
|
||||||
|
modules/pam_debug/Makefile modules/pam_deny/Makefile \
|
||||||
|
modules/pam_echo/Makefile modules/pam_env/Makefile \
|
44
pam.spec
44
pam.spec
@ -1,16 +1,16 @@
|
|||||||
%define pam_redhat_version 0.99.9-1
|
%define pam_redhat_version 0.99.10-1
|
||||||
|
|
||||||
Summary: A security tool which provides authentication for applications
|
Summary: An extensible library which provides authentication for applications
|
||||||
Name: pam
|
Name: pam
|
||||||
Version: 1.0.2
|
Version: 1.0.90
|
||||||
Release: 2%{?dist}
|
Release: 1%{?dist}
|
||||||
# The library is BSD licensed with option to relicense as GPLv2+ - this option is redundant
|
# The library is BSD licensed with option to relicense as GPLv2+ - this option is redundant
|
||||||
# as the BSD license allows that anyway. pam_timestamp and pam_console modules are GPLv2+,
|
# as the BSD license allows that anyway. pam_timestamp and pam_console modules are GPLv2+,
|
||||||
# pam_rhosts_auth module is BSD with advertising
|
# pam_rhosts_auth module is BSD with advertising
|
||||||
License: BSD and GPLv2+ and BSD with advertising
|
License: BSD and GPLv2+ and BSD with advertising
|
||||||
Group: System Environment/Base
|
Group: System Environment/Base
|
||||||
Source0: http://ftp.us.kernel.org/pub/linux/libs/pam/library/Linux-PAM-%{version}.tar.bz2
|
Source0: http://ftp.us.kernel.org/pub/linux/libs/pam/beta/Linux-PAM-%{version}.tar.bz2
|
||||||
Source1: http://ftp.us.kernel.org/pub/linux/libs/pam/library/Linux-PAM-%{version}.tar.bz2.sign
|
Source1: http://ftp.us.kernel.org/pub/linux/libs/pam/beta/Linux-PAM-%{version}.tar.bz2.sign
|
||||||
Source2: https://fedorahosted.org/releases/p/a/pam-redhat/pam-redhat-%{pam_redhat_version}.tar.bz2
|
Source2: https://fedorahosted.org/releases/p/a/pam-redhat/pam-redhat-%{pam_redhat_version}.tar.bz2
|
||||||
Source5: other.pamd
|
Source5: other.pamd
|
||||||
Source6: system-auth.pamd
|
Source6: system-auth.pamd
|
||||||
@ -19,19 +19,7 @@ Source8: dlopen.sh
|
|||||||
Source9: system-auth.5
|
Source9: system-auth.5
|
||||||
Source10: config-util.5
|
Source10: config-util.5
|
||||||
Source11: 90-nproc.conf
|
Source11: 90-nproc.conf
|
||||||
Patch1: pam-0.99.7.0-redhat-modules.patch
|
Patch1: pam-1.0.90-redhat-modules.patch
|
||||||
Patch5: pam-1.0.1-autoreconf.patch
|
|
||||||
Patch10: pam-1.0.0-sepermit-screensaver.patch
|
|
||||||
Patch12: pam-1.0.0-selinux-env-params.patch
|
|
||||||
Patch21: pam-0.99.10.0-unix-audit-failed.patch
|
|
||||||
Patch22: pam-1.0.1-unix-prompts.patch
|
|
||||||
Patch31: pam-1.0.1-cracklib-try-first-pass.patch
|
|
||||||
Patch32: pam-1.0.1-tally-fail-close.patch
|
|
||||||
Patch33: pam-1.0.2-tally-fdleak.patch
|
|
||||||
Patch41: pam-1.0.1-namespace-create.patch
|
|
||||||
Patch42: pam-1.0.2-cracklib-pwquality.patch
|
|
||||||
Patch43: pam-0.99.6.2-lastlog-failed.patch
|
|
||||||
Patch44: pam-1.0.2-many-groups.patch
|
|
||||||
|
|
||||||
%define _sbindir /sbin
|
%define _sbindir /sbin
|
||||||
%define _moduledir /%{_lib}/security
|
%define _moduledir /%{_lib}/security
|
||||||
@ -94,18 +82,6 @@ PAM-aware applications and modules for use with PAM.
|
|||||||
mv pam-redhat-%{pam_redhat_version}/* modules
|
mv pam-redhat-%{pam_redhat_version}/* modules
|
||||||
|
|
||||||
%patch1 -p1 -b .redhat-modules
|
%patch1 -p1 -b .redhat-modules
|
||||||
%patch5 -p1 -b .autoreconf
|
|
||||||
%patch10 -p1 -b .screensaver
|
|
||||||
%patch12 -p0 -b .env-params
|
|
||||||
%patch21 -p1 -b .audit-failed
|
|
||||||
%patch22 -p1 -b .prompts
|
|
||||||
%patch31 -p1 -b .try-first-pass
|
|
||||||
%patch32 -p1 -b .fail-close
|
|
||||||
%patch33 -p1 -b .fdleak
|
|
||||||
%patch41 -p1 -b .create
|
|
||||||
%patch42 -p1 -b .pwquality
|
|
||||||
%patch43 -p1 -b .failed
|
|
||||||
%patch44 -p1 -b .many-groups
|
|
||||||
|
|
||||||
autoreconf
|
autoreconf
|
||||||
|
|
||||||
@ -113,6 +89,7 @@ autoreconf
|
|||||||
%configure \
|
%configure \
|
||||||
--libdir=/%{_lib} \
|
--libdir=/%{_lib} \
|
||||||
--includedir=%{_includedir}/security \
|
--includedir=%{_includedir}/security \
|
||||||
|
--disable-prelude \
|
||||||
%if ! %{WITH_SELINUX}
|
%if ! %{WITH_SELINUX}
|
||||||
--disable-selinux \
|
--disable-selinux \
|
||||||
%endif
|
%endif
|
||||||
@ -271,6 +248,7 @@ fi
|
|||||||
%{_moduledir}/pam_nologin.so
|
%{_moduledir}/pam_nologin.so
|
||||||
%{_moduledir}/pam_permit.so
|
%{_moduledir}/pam_permit.so
|
||||||
%{_moduledir}/pam_postgresok.so
|
%{_moduledir}/pam_postgresok.so
|
||||||
|
%{_moduledir}/pam_pwhistory.so
|
||||||
%{_moduledir}/pam_rhosts.so
|
%{_moduledir}/pam_rhosts.so
|
||||||
%{_moduledir}/pam_rootok.so
|
%{_moduledir}/pam_rootok.so
|
||||||
%if %{WITH_SELINUX}
|
%if %{WITH_SELINUX}
|
||||||
@ -335,6 +313,10 @@ fi
|
|||||||
%doc doc/adg/*.txt doc/adg/html
|
%doc doc/adg/*.txt doc/adg/html
|
||||||
|
|
||||||
%changelog
|
%changelog
|
||||||
|
* Tue Dec 16 2008 Tomas Mraz <tmraz@redhat.com> 1.0.90-1
|
||||||
|
- upgrade to new upstream release
|
||||||
|
- add --disable-prelude (#466242)
|
||||||
|
|
||||||
* Tue Sep 23 2008 Tomas Mraz <tmraz@redhat.com> 1.0.2-2
|
* Tue Sep 23 2008 Tomas Mraz <tmraz@redhat.com> 1.0.2-2
|
||||||
- new password quality checks in pam_cracklib
|
- new password quality checks in pam_cracklib
|
||||||
- report failed logins from btmp in pam_lastlog
|
- report failed logins from btmp in pam_lastlog
|
||||||
|
Loading…
Reference in New Issue
Block a user