790525d4ab
- don't free/malloc when unnecessary
474 lines
14 KiB
Diff
474 lines
14 KiB
Diff
Written-by: Tomas Mraz <tmraz@redhat.com>
|
|
Reviewed-by: Karel Zak <kzak@redhat.com>
|
|
|
|
diff -up /dev/null Linux-PAM-0.99.8.1/modules/pam_selinux/pam_selinux_permit.8.xml
|
|
--- /dev/null 2007-09-17 08:57:19.474470099 +0200
|
|
+++ Linux-PAM-0.99.8.1/modules/pam_selinux/pam_selinux_permit.8.xml 2007-09-19 19:37:26.000000000 +0200
|
|
@@ -0,0 +1,182 @@
|
|
+<?xml version="1.0" encoding='UTF-8'?>
|
|
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
|
|
+ "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd">
|
|
+
|
|
+<refentry id="pam_selinux_permit">
|
|
+
|
|
+ <refmeta>
|
|
+ <refentrytitle>pam_selinux_permit</refentrytitle>
|
|
+ <manvolnum>8</manvolnum>
|
|
+ <refmiscinfo class="sectdesc">Linux-PAM Manual</refmiscinfo>
|
|
+ </refmeta>
|
|
+
|
|
+ <refnamediv id="pam_selinux_permit-name">
|
|
+ <refname>pam_selinux_permit</refname>
|
|
+ <refpurpose>PAM module to allow/deny login depending on SELinux enforcement state</refpurpose>
|
|
+ </refnamediv>
|
|
+
|
|
+ <refsynopsisdiv>
|
|
+ <cmdsynopsis id="pam_selinux_permit-cmdsynopsis">
|
|
+ <command>pam_selinux_permit.so</command>
|
|
+ <arg choice="opt">
|
|
+ debug
|
|
+ </arg>
|
|
+ <arg choice="opt">
|
|
+ conf=<replaceable>/path/to/config/file</replaceable>
|
|
+ </arg>
|
|
+ </cmdsynopsis>
|
|
+ </refsynopsisdiv>
|
|
+
|
|
+ <refsect1 id="pam_selinux_permit-description">
|
|
+ <title>DESCRIPTION</title>
|
|
+ <para>
|
|
+ The pam_selinux 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
|
|
+ he is allowed access only when the SELinux is in enforcing mode. Otherwise
|
|
+ he is denied access. For users not matching any entry in the config file
|
|
+ the pam_selinux_permit module returns PAM_IGNORE return value.
|
|
+ </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
|
|
+ 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>
|
|
+ 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>
|
|
+ </refsect1>
|
|
+
|
|
+ <refsect1 id="pam_selinux_permit-options">
|
|
+ <title>OPTIONS</title>
|
|
+ <variablelist>
|
|
+ <varlistentry>
|
|
+ <term>
|
|
+ <option>debug</option>
|
|
+ </term>
|
|
+ <listitem>
|
|
+ <para>
|
|
+ Turns on debugging via
|
|
+ <citerefentry>
|
|
+ <refentrytitle>syslog</refentrytitle><manvolnum>3</manvolnum>
|
|
+ </citerefentry>.
|
|
+ </para>
|
|
+ </listitem>
|
|
+ </varlistentry>
|
|
+ <varlistentry>
|
|
+ <term>
|
|
+ <option>conf=<replaceable>/path/to/config/file</replaceable></option>
|
|
+ </term>
|
|
+ <listitem>
|
|
+ <para>
|
|
+ Path to alternative config file overriding the default.
|
|
+ </para>
|
|
+ </listitem>
|
|
+ </varlistentry>
|
|
+ </variablelist>
|
|
+ </refsect1>
|
|
+
|
|
+ <refsect1 id="pam_selinux_permit-services">
|
|
+ <title>MODULE SERVICES PROVIDED</title>
|
|
+ <para>
|
|
+ Only the <option>auth</option> and <option>account</option>
|
|
+ services are supported.
|
|
+ </para>
|
|
+ </refsect1>
|
|
+
|
|
+ <refsect1 id='pam_selinux_permit-return_values'>
|
|
+ <title>RETURN VALUES</title>
|
|
+ <variablelist>
|
|
+ <varlistentry>
|
|
+ <term>PAM_AUTH_ERR</term>
|
|
+ <listitem>
|
|
+ <para>
|
|
+ SELinux is disabled or in the permissive mode and the user
|
|
+ matches.
|
|
+ </para>
|
|
+ </listitem>
|
|
+ </varlistentry>
|
|
+ <varlistentry>
|
|
+ <term>PAM_SUCCESS</term>
|
|
+ <listitem>
|
|
+ <para>
|
|
+ SELinux is in the enforcing mode and the user matches.
|
|
+ </para>
|
|
+ </listitem>
|
|
+ </varlistentry>
|
|
+ <varlistentry>
|
|
+ <term>PAM_IGNORE</term>
|
|
+ <listitem>
|
|
+ <para>
|
|
+ The user does not match any entry in the config file.
|
|
+ </para>
|
|
+ </listitem>
|
|
+ </varlistentry>
|
|
+ <varlistentry>
|
|
+ <term>PAM_USER_UNKNOWN</term>
|
|
+ <listitem>
|
|
+ <para>
|
|
+ The module was unable to determine the user's name.
|
|
+ </para>
|
|
+ </listitem>
|
|
+ </varlistentry>
|
|
+ <varlistentry>
|
|
+ <term>PAM_SERVICE_ERR</term>
|
|
+ <listitem>
|
|
+ <para>
|
|
+ Error during reading or parsing the config file.
|
|
+ </para>
|
|
+ </listitem>
|
|
+ </varlistentry>
|
|
+ </variablelist>
|
|
+ </refsect1>
|
|
+
|
|
+ <refsect1 id="pam_selinux_permit-files">
|
|
+ <title>FILES</title>
|
|
+ <variablelist>
|
|
+ <varlistentry>
|
|
+ <term><filename>/etc/security/sepermit.conf</filename></term>
|
|
+ <listitem>
|
|
+ <para>Default configuration file</para>
|
|
+ </listitem>
|
|
+ </varlistentry>
|
|
+ </variablelist>
|
|
+ </refsect1>
|
|
+
|
|
+ <refsect1 id='pam_selinux_permit-examples'>
|
|
+ <title>EXAMPLES</title>
|
|
+ <programlisting>
|
|
+auth [success=done ignore=ignore default=bad] pam_selinux_permit.so
|
|
+auth required pam_unix.so
|
|
+account required pam_unix.so
|
|
+session required pam_permit.so
|
|
+ </programlisting>
|
|
+ </refsect1>
|
|
+
|
|
+ <refsect1 id='pam_selinux_permit-see_also'>
|
|
+ <title>SEE ALSO</title>
|
|
+ <para>
|
|
+ <citerefentry>
|
|
+ <refentrytitle>pam.conf</refentrytitle><manvolnum>5</manvolnum>
|
|
+ </citerefentry>,
|
|
+ <citerefentry>
|
|
+ <refentrytitle>pam.d</refentrytitle><manvolnum>8</manvolnum>
|
|
+ </citerefentry>,
|
|
+ <citerefentry>
|
|
+ <refentrytitle>pam</refentrytitle><manvolnum>8</manvolnum>
|
|
+ </citerefentry>
|
|
+ </para>
|
|
+ </refsect1>
|
|
+
|
|
+ <refsect1 id='pam_selinux_permit-author'>
|
|
+ <title>AUTHOR</title>
|
|
+ <para>
|
|
+ pam_selinux_permit was written by Tomas Mraz <tmraz@redhat.com>.
|
|
+ </para>
|
|
+ </refsect1>
|
|
+
|
|
+</refentry>
|
|
diff -up /dev/null Linux-PAM-0.99.8.1/modules/pam_selinux/pam_selinux_permit.c
|
|
--- /dev/null 2007-09-17 08:57:19.474470099 +0200
|
|
+++ Linux-PAM-0.99.8.1/modules/pam_selinux/pam_selinux_permit.c 2007-09-19 20:29:47.000000000 +0200
|
|
@@ -0,0 +1,222 @@
|
|
+/******************************************************************************
|
|
+ * A module for Linux-PAM that allows/denies acces based on SELinux state.
|
|
+ *
|
|
+ * Copyright (c) 2007 Red Hat, Inc.
|
|
+ * Written 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
|
|
+ * are met:
|
|
+ * 1. Redistributions of source code must retain the above copyright
|
|
+ * notice, and the entire permission notice in its entirety,
|
|
+ * including the disclaimer of warranties.
|
|
+ * 2. Redistributions in binary form must reproduce the above copyright
|
|
+ * notice, this list of conditions and the following disclaimer in the
|
|
+ * documentation and/or other materials provided with the distribution.
|
|
+ * 3. The name of the author may not be used to endorse or promote
|
|
+ * products derived from this software without specific prior
|
|
+ * written permission.
|
|
+ *
|
|
+ * ALTERNATIVELY, this product may be distributed under the terms of
|
|
+ * the GNU Public License, in which case the provisions of the GPL are
|
|
+ * required INSTEAD OF the above restrictions. (This clause is
|
|
+ * necessary due to a potential bad interaction between the GPL and
|
|
+ * the restrictions contained in a BSD-style copyright.)
|
|
+ *
|
|
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
|
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
|
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
+ * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
|
|
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
|
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
|
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
|
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
|
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
+ *
|
|
+ */
|
|
+
|
|
+#include "config.h"
|
|
+
|
|
+#include <errno.h>
|
|
+#include <pwd.h>
|
|
+#include <stdio.h>
|
|
+#include <stdlib.h>
|
|
+#include <string.h>
|
|
+#include <syslog.h>
|
|
+#include <ctype.h>
|
|
+
|
|
+#define PAM_SM_AUTH
|
|
+#define PAM_SM_ACCOUNT
|
|
+
|
|
+#include <security/pam_modules.h>
|
|
+#include <security/_pam_macros.h>
|
|
+#include <security/pam_modutil.h>
|
|
+#include <security/pam_ext.h>
|
|
+
|
|
+#include <selinux/selinux.h>
|
|
+
|
|
+/* return 0 when matched, -1 when unmatched, pam error otherwise */
|
|
+static int
|
|
+sepermit_match(pam_handle_t *pamh, const char *cfgfile, const char *user,
|
|
+ const char *seuser, int debug)
|
|
+{
|
|
+ FILE *f;
|
|
+ char *line = NULL;
|
|
+ char *start;
|
|
+ size_t len = 0;
|
|
+ int matched = 0;
|
|
+
|
|
+ f = fopen(cfgfile, "r");
|
|
+
|
|
+ if (!f) {
|
|
+ pam_syslog(pamh, LOG_ERR, "Failed to open config file %s: %m", cfgfile);
|
|
+ return PAM_SERVICE_ERR;
|
|
+ }
|
|
+
|
|
+ while (!matched && getline(&line, &len, f) != -1) {
|
|
+ size_t n;
|
|
+
|
|
+ if (line[0] == '#')
|
|
+ continue;
|
|
+
|
|
+ start = line;
|
|
+ while (isspace(*start))
|
|
+ ++start;
|
|
+ n = strlen(start);
|
|
+ while (n > 0 && isspace(start[n-1])) {
|
|
+ --n;
|
|
+ }
|
|
+ if (n == 0)
|
|
+ continue;
|
|
+
|
|
+ start[n] = '\0';
|
|
+
|
|
+ switch (start[0]) {
|
|
+ case '@':
|
|
+ ++start;
|
|
+ if (debug)
|
|
+ pam_syslog(pamh, LOG_NOTICE, "Matching user %s against group %s", user, start);
|
|
+ if (pam_modutil_user_in_group_nam_nam(pamh, user, start)) {
|
|
+ matched = 1;
|
|
+ }
|
|
+ break;
|
|
+ case '%':
|
|
+ ++start;
|
|
+ if (debug)
|
|
+ pam_syslog(pamh, LOG_NOTICE, "Matching seuser %s against seuser %s", seuser, start);
|
|
+ if (strcmp(seuser, start) == 0) {
|
|
+ matched = 1;
|
|
+ }
|
|
+ break;
|
|
+ default:
|
|
+ if (debug)
|
|
+ pam_syslog(pamh, LOG_NOTICE, "Matching user %s against user %s", user, start);
|
|
+ if (strcmp(user, start) == 0) {
|
|
+ matched = 1;
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+
|
|
+ free(line);
|
|
+ fclose(f);
|
|
+ return matched ? 0 : -1;
|
|
+}
|
|
+
|
|
+PAM_EXTERN int
|
|
+pam_sm_authenticate(pam_handle_t *pamh, int flags UNUSED,
|
|
+ int argc, const char **argv)
|
|
+{
|
|
+ int i;
|
|
+ int rv;
|
|
+ int debug = 0;
|
|
+ int sense = PAM_AUTH_ERR;
|
|
+ const char *user = NULL;
|
|
+ char *seuser = NULL;
|
|
+ char *level = NULL;
|
|
+ const char *cfgfile = SEPERMIT_CONF_FILE;
|
|
+
|
|
+ /* Parse arguments. */
|
|
+ for (i = 0; i < argc; i++) {
|
|
+ if (strcmp(argv[i], "debug") == 0) {
|
|
+ debug = 1;
|
|
+ }
|
|
+ if (strcmp(argv[i], "conf=") == 0) {
|
|
+ cfgfile = argv[i] + 5;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ if (debug)
|
|
+ pam_syslog(pamh, LOG_NOTICE, "Parsing config file: %s", cfgfile);
|
|
+
|
|
+ if (pam_get_user(pamh, &user, NULL) != PAM_SUCCESS || user == NULL
|
|
+ || *user == '\0') {
|
|
+ pam_syslog(pamh, LOG_ERR, "Cannot determine the user's name");
|
|
+ return PAM_USER_UNKNOWN;
|
|
+ }
|
|
+
|
|
+ if (is_selinux_enabled() > 0) {
|
|
+ if (security_getenforce() == 1) {
|
|
+ if (debug)
|
|
+ pam_syslog(pamh, LOG_NOTICE, "Enforcing mode, access will be allowed on match");
|
|
+ sense = PAM_SUCCESS;
|
|
+ }
|
|
+
|
|
+ if (getseuserbyname(user, &seuser, &level) != 0) {
|
|
+ seuser = NULL;
|
|
+ level = NULL;
|
|
+ pam_syslog(pamh, LOG_ERR, "getseuserbyname failed: %m");
|
|
+ }
|
|
+ }
|
|
+
|
|
+ if (debug && sense != PAM_SUCCESS)
|
|
+ pam_syslog(pamh, LOG_NOTICE, "Access will not be allowed on match");
|
|
+
|
|
+ rv = sepermit_match(pamh, cfgfile, user, seuser, debug);
|
|
+
|
|
+ if (debug)
|
|
+ pam_syslog(pamh, LOG_NOTICE, "sepermit_match returned: %d", rv);
|
|
+
|
|
+ free(seuser);
|
|
+ free(level);
|
|
+
|
|
+ switch (rv) {
|
|
+ case -1:
|
|
+ return PAM_IGNORE;
|
|
+ case 0:
|
|
+ return sense;
|
|
+ }
|
|
+
|
|
+ return rv;
|
|
+}
|
|
+
|
|
+PAM_EXTERN int
|
|
+pam_sm_setcred (pam_handle_t *pamh UNUSED, int flags UNUSED,
|
|
+ int argc UNUSED, const char **argv UNUSED)
|
|
+{
|
|
+ return PAM_IGNORE;
|
|
+}
|
|
+
|
|
+PAM_EXTERN int
|
|
+pam_sm_acct_mgmt(pam_handle_t *pamh, int flags,
|
|
+ int argc, const char **argv)
|
|
+{
|
|
+ return pam_sm_authenticate(pamh, flags, argc, argv);
|
|
+}
|
|
+
|
|
+#ifdef PAM_STATIC
|
|
+
|
|
+/* static module data */
|
|
+
|
|
+struct pam_module _pam_access_modstruct = {
|
|
+ "pam_access",
|
|
+ pam_sm_authenticate,
|
|
+ pam_sm_setcred,
|
|
+ pam_sm_acct_mgmt,
|
|
+ NULL,
|
|
+ NULL,
|
|
+ NULL
|
|
+};
|
|
+#endif
|
|
+
|
|
diff -up /dev/null Linux-PAM-0.99.8.1/modules/pam_selinux/sepermit.conf
|
|
--- /dev/null 2007-09-17 08:57:19.474470099 +0200
|
|
+++ Linux-PAM-0.99.8.1/modules/pam_selinux/sepermit.conf 2007-09-19 19:37:26.000000000 +0200
|
|
@@ -0,0 +1,6 @@
|
|
+# /etc/security/sepermit.conf
|
|
+#
|
|
+# Each line contains either:
|
|
+# - an user name
|
|
+# - a group name, with @group syntax
|
|
+# - a SELinux user name, with %seuser syntax
|
|
diff -up Linux-PAM-0.99.8.1/modules/pam_selinux/Makefile.am.permit Linux-PAM-0.99.8.1/modules/pam_selinux/Makefile.am
|
|
--- Linux-PAM-0.99.8.1/modules/pam_selinux/Makefile.am.permit 2007-01-23 11:09:25.000000000 +0100
|
|
+++ Linux-PAM-0.99.8.1/modules/pam_selinux/Makefile.am 2007-09-19 19:37:26.000000000 +0200
|
|
@@ -5,20 +5,21 @@
|
|
CLEANFILES = *~
|
|
|
|
EXTRA_DIST = README $(XMLS) pam_selinux.8 pam_selinux_check.8 \
|
|
- tst-pam_selinux
|
|
+ pam_seliux_permit.8 sepermit.conf tst-pam_selinux
|
|
|
|
if HAVE_LIBSELINUX
|
|
TESTS = tst-pam_selinux
|
|
- man_MANS = pam_selinux.8
|
|
+ man_MANS = pam_selinux.8 pam_selinux_permit.8
|
|
endif
|
|
|
|
-XMLS = README.xml pam_selinux.8.xml
|
|
+XMLS = README.xml pam_selinux.8.xml pam_selinux_permit.8.xml
|
|
|
|
securelibdir = $(SECUREDIR)
|
|
secureconfdir = $(SCONFIGDIR)
|
|
|
|
AM_CFLAGS = -I$(top_srcdir)/libpam/include -I$(top_srcdir)/libpamc/include \
|
|
- -I$(top_srcdir)/libpam_misc/include
|
|
+ -I$(top_srcdir)/libpam_misc/include \
|
|
+ -D SEPERMIT_CONF_FILE=\"$(SCONFIGDIR)/sepermit.conf\"
|
|
AM_LDFLAGS = -no-undefined \
|
|
-L$(top_builddir)/libpam -lpam @LIBSELINUX@
|
|
|
|
@@ -30,12 +31,16 @@ if HAVE_VERSIONING
|
|
-Wl,--version-script=$(srcdir)/../modules.map
|
|
endif
|
|
|
|
+pam_selinux_permit_la_LDFLAGS= $(pam_selinux_la_LDFLAGS)
|
|
+
|
|
+secureconf_DATA = sepermit.conf
|
|
+
|
|
if HAVE_LIBSELINUX
|
|
- securelib_LTLIBRARIES = pam_selinux.la
|
|
+ securelib_LTLIBRARIES = pam_selinux.la pam_selinux_permit.la
|
|
noinst_PROGRAMS = pam_selinux_check
|
|
endif
|
|
if ENABLE_REGENERATE_MAN
|
|
-noinst_DATA = README pam_selinux.8
|
|
+noinst_DATA = README pam_selinux.8 pam_selinux_permit.8
|
|
README: pam_selinux.8.xml
|
|
-include $(top_srcdir)/Make.xml.rules
|
|
endif
|