- test for setkeycreatecon correctly
- add exclusive login mode of operation to pam_selinux_permit (original patch by Dan Walsh)
This commit is contained in:
parent
de90b38383
commit
b6b1e29706
318
pam-0.99.8.1-sepermit-kill-user.patch
Normal file
318
pam-0.99.8.1-sepermit-kill-user.patch
Normal file
@ -0,0 +1,318 @@
|
||||
diff -up Linux-PAM-0.99.8.1/modules/pam_selinux/pam_selinux_permit.c.kill-user Linux-PAM-0.99.8.1/modules/pam_selinux/pam_selinux_permit.c
|
||||
--- Linux-PAM-0.99.8.1/modules/pam_selinux/pam_selinux_permit.c.kill-user 2008-01-28 18:34:18.000000000 +0100
|
||||
+++ Linux-PAM-0.99.8.1/modules/pam_selinux/pam_selinux_permit.c 2008-01-28 18:34:18.000000000 +0100
|
||||
@@ -1,7 +1,7 @@
|
||||
/******************************************************************************
|
||||
* A module for Linux-PAM that allows/denies acces based on SELinux state.
|
||||
*
|
||||
- * Copyright (c) 2007 Red Hat, Inc.
|
||||
+ * Copyright (c) 2007, 2008 Red Hat, Inc.
|
||||
* Written by Tomas Mraz <tmraz@redhat.com>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@@ -46,6 +46,14 @@
|
||||
#include <string.h>
|
||||
#include <syslog.h>
|
||||
#include <ctype.h>
|
||||
+#include <signal.h>
|
||||
+#include <limits.h>
|
||||
+#include <sys/types.h>
|
||||
+#include <sys/stat.h>
|
||||
+#include <fcntl.h>
|
||||
+#include <unistd.h>
|
||||
+#include <pwd.h>
|
||||
+#include <dirent.h>
|
||||
|
||||
#define PAM_SM_AUTH
|
||||
#define PAM_SM_ACCOUNT
|
||||
@@ -57,6 +65,165 @@
|
||||
|
||||
#include <selinux/selinux.h>
|
||||
|
||||
+#define MODULE "pam_selinux_permit"
|
||||
+#define OPT_DELIM ":"
|
||||
+
|
||||
+struct lockfd {
|
||||
+ uid_t uid;
|
||||
+ int fd;
|
||||
+ int debug;
|
||||
+};
|
||||
+
|
||||
+#define PROC_BASE "/proc"
|
||||
+#define MAX_NAMES (int)(sizeof(unsigned long)*8)
|
||||
+
|
||||
+static int
|
||||
+match_process_uid(pid_t pid, uid_t uid)
|
||||
+{
|
||||
+ char buf[128];
|
||||
+ uid_t puid;
|
||||
+ FILE *f;
|
||||
+ int re = 0;
|
||||
+
|
||||
+ snprintf (buf, sizeof buf, PROC_BASE "/%d/status", pid);
|
||||
+ if (!(f = fopen (buf, "r")))
|
||||
+ return 0;
|
||||
+
|
||||
+ while (fgets(buf, sizeof buf, f)) {
|
||||
+ if (sscanf (buf, "Uid:\t%d", &puid)) {
|
||||
+ re = uid == puid;
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+ fclose(f);
|
||||
+ return re;
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+check_running (pam_handle_t *pamh, uid_t uid, int killall, int debug)
|
||||
+{
|
||||
+ DIR *dir;
|
||||
+ struct dirent *de;
|
||||
+ pid_t *pid_table, pid, self;
|
||||
+ int i;
|
||||
+ int pids, max_pids;
|
||||
+ int running = 0;
|
||||
+ self = getpid();
|
||||
+ if (!(dir = opendir(PROC_BASE))) {
|
||||
+ pam_syslog(pamh, LOG_ERR, "Failed to open proc directory file %s:", PROC_BASE);
|
||||
+ return -1;
|
||||
+ }
|
||||
+ max_pids = 256;
|
||||
+ pid_table = malloc(max_pids * sizeof (pid_t));
|
||||
+ if (!pid_table) {
|
||||
+ pam_syslog(pamh, LOG_CRIT, "Memory allocation error");
|
||||
+ return -1;
|
||||
+ }
|
||||
+ pids = 0;
|
||||
+ while ((de = readdir (dir)) != NULL) {
|
||||
+ if (!(pid = (pid_t)atoi(de->d_name)) || pid == self)
|
||||
+ continue;
|
||||
+
|
||||
+ if (pids == max_pids) {
|
||||
+ if (!(pid_table = realloc(pid_table, 2*pids*sizeof(pid_t)))) {
|
||||
+ pam_syslog(pamh, LOG_CRIT, "Memory allocation error");
|
||||
+ return -1;
|
||||
+ }
|
||||
+ max_pids *= 2;
|
||||
+ }
|
||||
+ pid_table[pids++] = pid;
|
||||
+ }
|
||||
+
|
||||
+ (void)closedir(dir);
|
||||
+
|
||||
+ for (i = 0; i < pids; i++) {
|
||||
+ pid_t id;
|
||||
+
|
||||
+ if (match_process_uid(pid_table[i], uid) == 0)
|
||||
+ continue;
|
||||
+ id = pid_table[i];
|
||||
+
|
||||
+ if (killall) {
|
||||
+ if (debug)
|
||||
+ pam_syslog(pamh, LOG_NOTICE, "Attempting to kill %d", id);
|
||||
+ kill(id, SIGKILL);
|
||||
+ }
|
||||
+ running++;
|
||||
+ }
|
||||
+
|
||||
+ free(pid_table);
|
||||
+ return running;
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+sepermit_unlock(pam_handle_t *pamh, void *plockfd, int error_status UNUSED)
|
||||
+{
|
||||
+ struct lockfd *lockfd = plockfd;
|
||||
+ struct flock fl;
|
||||
+
|
||||
+ memset(&fl, 0, sizeof(fl));
|
||||
+ fl.l_type = F_UNLCK;
|
||||
+ fl.l_whence = SEEK_SET;
|
||||
+
|
||||
+ if (lockfd->debug)
|
||||
+ pam_syslog(pamh, LOG_ERR, "Unlocking fd: %d uid: %d", lockfd->fd, lockfd->uid);
|
||||
+
|
||||
+ /* Don't kill uid==0 */
|
||||
+ if (lockfd->uid)
|
||||
+ /* This is a DOS but it prevents an app from forking to prevent killing */
|
||||
+ while(check_running(pamh, lockfd->uid, 1, lockfd->debug) > 0)
|
||||
+ continue;
|
||||
+
|
||||
+ fcntl(lockfd->fd, F_SETLK, &fl);
|
||||
+ close(lockfd->fd);
|
||||
+ free(lockfd);
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+sepermit_lock(pam_handle_t *pamh, const char *user, int debug)
|
||||
+{
|
||||
+ char buf[PATH_MAX];
|
||||
+ struct flock fl;
|
||||
+
|
||||
+ memset(&fl, 0, sizeof(fl));
|
||||
+ fl.l_type = F_WRLCK;
|
||||
+ fl.l_whence = SEEK_SET;
|
||||
+
|
||||
+ struct passwd *pw = pam_modutil_getpwnam( pamh, user );
|
||||
+ if (!pw) {
|
||||
+ pam_syslog(pamh, LOG_ERR, "Unable to find uid for user %s", user);
|
||||
+ return -1;
|
||||
+ }
|
||||
+ if (check_running(pamh, pw->pw_uid, 0, debug) > 0) {
|
||||
+ pam_syslog(pamh, LOG_ERR, "User %s processes are running. Exclusive login not allowed", user);
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ snprintf(buf, sizeof(buf), "%s/%d.lock", SEPERMIT_LOCKDIR, pw->pw_uid);
|
||||
+ int fd = open(buf, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR);
|
||||
+ if (fd < 0) {
|
||||
+ pam_syslog(pamh, LOG_ERR, "Unable to open lock file %s/%d.lock", SEPERMIT_LOCKDIR, pw->pw_uid);
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ if (fcntl(fd, F_SETLK, &fl) == -1) {
|
||||
+ pam_syslog(pamh, LOG_ERR, "User %s with exclusive login already logged in", user);
|
||||
+ close(fd);
|
||||
+ return -1;
|
||||
+ }
|
||||
+ struct lockfd *lockfd=calloc(1, sizeof(struct lockfd));
|
||||
+ if (!lockfd) {
|
||||
+ close(fd);
|
||||
+ pam_syslog(pamh, LOG_CRIT, "Memory allocation error");
|
||||
+ return -1;
|
||||
+ }
|
||||
+ lockfd->uid = pw->pw_uid;
|
||||
+ lockfd->debug = debug;
|
||||
+ lockfd->fd=fd;
|
||||
+ pam_set_data(pamh, "pam_selinux_permit", lockfd, sepermit_unlock);
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
/* return 0 when matched, -1 when unmatched, pam error otherwise */
|
||||
static int
|
||||
sepermit_match(pam_handle_t *pamh, const char *cfgfile, const char *user,
|
||||
@@ -67,6 +234,7 @@ sepermit_match(pam_handle_t *pamh, const
|
||||
char *start;
|
||||
size_t len = 0;
|
||||
int matched = 0;
|
||||
+ int exclusive = 0;
|
||||
|
||||
f = fopen(cfgfile, "r");
|
||||
|
||||
@@ -77,6 +245,8 @@ sepermit_match(pam_handle_t *pamh, const
|
||||
|
||||
while (!matched && getline(&line, &len, f) != -1) {
|
||||
size_t n;
|
||||
+ char *sptr;
|
||||
+ char *opt;
|
||||
|
||||
if (line[0] == '#')
|
||||
continue;
|
||||
@@ -92,6 +262,7 @@ sepermit_match(pam_handle_t *pamh, const
|
||||
continue;
|
||||
|
||||
start[n] = '\0';
|
||||
+ start = strtok_r(start, OPT_DELIM, &sptr);
|
||||
|
||||
switch (start[0]) {
|
||||
case '@':
|
||||
@@ -117,11 +288,22 @@ sepermit_match(pam_handle_t *pamh, const
|
||||
matched = 1;
|
||||
}
|
||||
}
|
||||
+ if (matched)
|
||||
+ while ((opt=strtok_r(NULL, OPT_DELIM, &sptr)) != NULL) {
|
||||
+ if (strcmp(opt, "exclusive") == 0)
|
||||
+ exclusive = 1;
|
||||
+ else if (debug) {
|
||||
+ pam_syslog(pamh, LOG_NOTICE, "Unknown user option: %s", opt);
|
||||
+ }
|
||||
+ }
|
||||
}
|
||||
|
||||
free(line);
|
||||
fclose(f);
|
||||
- return matched ? 0 : -1;
|
||||
+ if (matched)
|
||||
+ return exclusive ? sepermit_lock(pamh, user, debug) : 0;
|
||||
+ else
|
||||
+ return -1;
|
||||
}
|
||||
|
||||
PAM_EXTERN int
|
||||
diff -up Linux-PAM-0.99.8.1/modules/pam_selinux/pam_selinux_permit.8.xml.kill-user Linux-PAM-0.99.8.1/modules/pam_selinux/pam_selinux_permit.8.xml
|
||||
--- Linux-PAM-0.99.8.1/modules/pam_selinux/pam_selinux_permit.8.xml.kill-user 2008-01-28 18:34:18.000000000 +0100
|
||||
+++ Linux-PAM-0.99.8.1/modules/pam_selinux/pam_selinux_permit.8.xml 2008-01-28 18:34:18.000000000 +0100
|
||||
@@ -30,8 +30,8 @@
|
||||
<refsect1 id="pam_selinux_permit-description">
|
||||
<title>DESCRIPTION</title>
|
||||
<para>
|
||||
- The pam_selinux module allows or denies login depending on SELinux enforcement
|
||||
- state.
|
||||
+ The pam_selinux_permit module allows or denies login depending on SELinux
|
||||
+ enforcement state.
|
||||
</para>
|
||||
<para>
|
||||
When the user which is logging in matches an entry in the config file
|
||||
@@ -41,14 +41,21 @@
|
||||
</para>
|
||||
<para>
|
||||
The config file contains a simple list of user names one per line. If the
|
||||
- <replaceable>name</replaceable> is prefixed with @ character it means that all
|
||||
+ <replaceable>name</replaceable> is prefixed with <emphasis>@</emphasis> character it means that all
|
||||
users in the group <replaceable>name</replaceable> match. If it is prefixed
|
||||
- with a % character the SELinux user is used to match against the <replaceable>name</replaceable>
|
||||
+ with a <emphasis>%</emphasis> character the SELinux user is used to match against the <replaceable>name</replaceable>
|
||||
instead of the account name. Note that when SELinux is disabled the
|
||||
SELinux user assigned to the account cannot be determined. This means that
|
||||
such entries are never matched when SELinux is disabled and pam_selinux_permit
|
||||
will return PAM_IGNORE.
|
||||
</para>
|
||||
+ <para>
|
||||
+ Each user name in the configuration file can have optional arguments separated
|
||||
+ by <emphasis>:</emphasis> character. The only currently recognized argument is <emphasis>exclusive</emphasis>.
|
||||
+ The pam_selinux_permit module will allow only single concurrent user session for
|
||||
+ the user with this argument specified and it will attempt to kill all processes
|
||||
+ of the user after logout.
|
||||
+ </para>
|
||||
</refsect1>
|
||||
|
||||
<refsect1 id="pam_selinux_permit-options">
|
||||
diff -up Linux-PAM-0.99.8.1/modules/pam_selinux/Makefile.am.kill-user Linux-PAM-0.99.8.1/modules/pam_selinux/Makefile.am
|
||||
--- Linux-PAM-0.99.8.1/modules/pam_selinux/Makefile.am.kill-user 2008-01-28 18:34:18.000000000 +0100
|
||||
+++ Linux-PAM-0.99.8.1/modules/pam_selinux/Makefile.am 2008-01-28 18:35:01.000000000 +0100
|
||||
@@ -16,10 +16,13 @@ XMLS = README.xml pam_selinux.8.xml pam_
|
||||
|
||||
securelibdir = $(SECUREDIR)
|
||||
secureconfdir = $(SCONFIGDIR)
|
||||
+sepermitlockdir = /var/run/sepermit
|
||||
|
||||
AM_CFLAGS = -I$(top_srcdir)/libpam/include -I$(top_srcdir)/libpamc/include \
|
||||
-I$(top_srcdir)/libpam_misc/include \
|
||||
- -D SEPERMIT_CONF_FILE=\"$(SCONFIGDIR)/sepermit.conf\"
|
||||
+ -D SEPERMIT_CONF_FILE=\"$(SCONFIGDIR)/sepermit.conf\" \
|
||||
+ -D SEPERMIT_LOCKDIR=\"$(sepermitlockdir)\"
|
||||
+
|
||||
AM_LDFLAGS = -no-undefined \
|
||||
-L$(top_builddir)/libpam -lpam @LIBSELINUX@
|
||||
|
||||
@@ -34,6 +37,7 @@ endif
|
||||
pam_selinux_permit_la_LDFLAGS= $(pam_selinux_la_LDFLAGS)
|
||||
|
||||
secureconf_DATA = sepermit.conf
|
||||
+sepermitlock_DATA =
|
||||
|
||||
if HAVE_LIBSELINUX
|
||||
securelib_LTLIBRARIES = pam_selinux.la pam_selinux_permit.la
|
||||
diff -up Linux-PAM-0.99.8.1/modules/pam_selinux/sepermit.conf.kill-user Linux-PAM-0.99.8.1/modules/pam_selinux/sepermit.conf
|
||||
--- Linux-PAM-0.99.8.1/modules/pam_selinux/sepermit.conf.kill-user 2008-01-28 18:34:18.000000000 +0100
|
||||
+++ Linux-PAM-0.99.8.1/modules/pam_selinux/sepermit.conf 2008-01-28 18:34:18.000000000 +0100
|
||||
@@ -4,3 +4,8 @@
|
||||
# - an user name
|
||||
# - a group name, with @group syntax
|
||||
# - a SELinux user name, with %seuser syntax
|
||||
+# Each line can contain optional arguments separated by :
|
||||
+# The possible arguments are:
|
||||
+# - exclusive - only single login session will
|
||||
+# be allowed for the user and the user's processes
|
||||
+# will be killed on logout
|
31
pam-0.99.8.1-setkeycreatecon.patch
Normal file
31
pam-0.99.8.1-setkeycreatecon.patch
Normal file
@ -0,0 +1,31 @@
|
||||
diff -up Linux-PAM-0.99.8.1/configure.in.setkeycreatecon Linux-PAM-0.99.8.1/configure.in
|
||||
--- Linux-PAM-0.99.8.1/configure.in.setkeycreatecon 2008-01-28 17:22:40.000000000 +0100
|
||||
+++ Linux-PAM-0.99.8.1/configure.in 2008-01-28 17:26:25.000000000 +0100
|
||||
@@ -379,6 +379,7 @@ AC_SUBST(LIBDB)
|
||||
AM_CONDITIONAL([HAVE_LIBDB], [test ! -z "$LIBDB"])
|
||||
|
||||
AC_CHECK_LIB([nsl],[yp_get_default_domain], LIBNSL="-lnsl", LIBNSL="")
|
||||
+BACKUP_LIBS=$LIBS
|
||||
LIBS="$LIBS $LIBNSL"
|
||||
AC_CHECK_FUNCS(yp_get_default_domain)
|
||||
LIBS=$BACKUP_LIBS
|
||||
@@ -396,6 +397,10 @@ AC_SUBST(LIBSELINUX)
|
||||
AM_CONDITIONAL([HAVE_LIBSELINUX], [test ! -z "$LIBSELINUX"])
|
||||
if test ! -z "$LIBSELINUX" ; then
|
||||
AC_DEFINE([WITH_SELINUX], 1, [Defined if SE Linux support is compiled in])
|
||||
+ BACKUP_LIBS=$LIBS
|
||||
+ LIBS="$LIBS $LIBSELINUX"
|
||||
+ AC_CHECK_FUNCS(setkeycreatecon)
|
||||
+ LIBS=$BACKUP_LIBS
|
||||
fi
|
||||
|
||||
dnl Checks for header files.
|
||||
@@ -428,7 +433,7 @@ AC_CHECK_FUNCS(fseeko gethostname gettim
|
||||
AC_CHECK_FUNCS(strcspn strdup strspn strstr strtol uname)
|
||||
AC_CHECK_FUNCS(getpwnam_r getpwuid_r getgrnam_r getgrgid_r getspnam_r)
|
||||
AC_CHECK_FUNCS(getgrouplist getline getdelim)
|
||||
-AC_CHECK_FUNCS(inet_ntop inet_pton ruserok_af setkeycreatecon)
|
||||
+AC_CHECK_FUNCS(inet_ntop inet_pton ruserok_af)
|
||||
|
||||
AC_CHECK_FUNCS(unshare, [UNSHARE=yes], [UNSHARE=no])
|
||||
AM_CONDITIONAL([HAVE_UNSHARE], [test "$UNSHARE" = yes])
|
12
pam.spec
12
pam.spec
@ -11,7 +11,7 @@
|
||||
Summary: A security tool which provides authentication for applications
|
||||
Name: pam
|
||||
Version: 0.99.8.1
|
||||
Release: 16%{?dist}
|
||||
Release: 17%{?dist}
|
||||
# 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+,
|
||||
# pam_rhosts_auth module is BSD with advertising
|
||||
@ -47,6 +47,8 @@ Patch48: pam-0.99.8.1-substack.patch
|
||||
Patch49: pam-0.99.8.1-tty-audit.patch
|
||||
Patch50: pam-0.99.8.1-tty-audit2.patch
|
||||
Patch51: pam-0.99.8.1-audit-failed.patch
|
||||
Patch52: pam-0.99.8.1-setkeycreatecon.patch
|
||||
Patch53: pam-0.99.8.1-sepermit-kill-user.patch
|
||||
|
||||
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
|
||||
Requires: cracklib, cracklib-dicts >= 2.8
|
||||
@ -119,6 +121,8 @@ popd
|
||||
%patch49 -p1 -b .tty-audit
|
||||
%patch50 -p1 -b .tty-audit2
|
||||
%patch51 -p1 -b .audit-failed
|
||||
%patch52 -p1 -b .setkeycreatecon
|
||||
%patch53 -p1 -b .kill-user
|
||||
|
||||
autoreconf
|
||||
|
||||
@ -352,6 +356,7 @@ fi
|
||||
%dir %{_sysconfdir}/security/console.perms.d
|
||||
%config %{_sysconfdir}/security/console.perms.d/50-default.perms
|
||||
%dir /var/run/console
|
||||
%dir /var/run/sepermit
|
||||
%ghost %verify(not md5 size mtime) /var/log/faillog
|
||||
%ghost %verify(not md5 size mtime) /var/log/tallylog
|
||||
%{_mandir}/man5/*
|
||||
@ -368,6 +373,11 @@ fi
|
||||
%doc doc/adg/*.txt doc/adg/html
|
||||
|
||||
%changelog
|
||||
* Mon Jan 28 2008 Tomas Mraz <tmraz@redhat.com> 0.99.8.1-17
|
||||
- test for setkeycreatecon correctly
|
||||
- add exclusive login mode of operation to pam_selinux_permit (original
|
||||
patch by Dan Walsh)
|
||||
|
||||
* Tue Jan 22 2008 Tomas Mraz <tmraz@redhat.com> 0.99.8.1-16
|
||||
- add auditing to pam_access, pam_limits, and pam_time
|
||||
- moved sanity testing code to check script
|
||||
|
Loading…
Reference in New Issue
Block a user