diff options
Diffstat (limited to 'modules/pam_shells')
-rw-r--r-- | modules/pam_shells/Makefile.am | 8 | ||||
-rw-r--r-- | modules/pam_shells/Makefile.in | 23 | ||||
-rw-r--r-- | modules/pam_shells/README | 6 | ||||
-rw-r--r-- | modules/pam_shells/README.xml | 32 | ||||
-rw-r--r-- | modules/pam_shells/pam_shells.8 | 13 | ||||
-rw-r--r-- | modules/pam_shells/pam_shells.8.xml | 41 | ||||
-rw-r--r-- | modules/pam_shells/pam_shells.c | 73 |
7 files changed, 130 insertions, 66 deletions
diff --git a/modules/pam_shells/Makefile.am b/modules/pam_shells/Makefile.am index b91bada5..e44915f2 100644 --- a/modules/pam_shells/Makefile.am +++ b/modules/pam_shells/Makefile.am @@ -15,17 +15,21 @@ dist_check_SCRIPTS = tst-pam_shells TESTS = $(dist_check_SCRIPTS) securelibdir = $(SECUREDIR) +if HAVE_VENDORDIR +secureconfdir = $(VENDOR_SCONFIGDIR) +else secureconfdir = $(SCONFIGDIR) +endif AM_CFLAGS = -I$(top_srcdir)/libpam/include -I$(top_srcdir)/libpamc/include \ - $(WARN_CFLAGS) + $(WARN_CFLAGS) $(ECONF_CFLAGS) AM_LDFLAGS = -no-undefined -avoid-version -module if HAVE_VERSIONING AM_LDFLAGS += -Wl,--version-script=$(srcdir)/../modules.map endif securelib_LTLIBRARIES = pam_shells.la -pam_shells_la_LIBADD = $(top_builddir)/libpam/libpam.la +pam_shells_la_LIBADD = $(top_builddir)/libpam/libpam.la $(ECONF_LIBS) if ENABLE_REGENERATE_MAN dist_noinst_DATA = README diff --git a/modules/pam_shells/Makefile.in b/modules/pam_shells/Makefile.in index c92648bc..3c236b33 100644 --- a/modules/pam_shells/Makefile.in +++ b/modules/pam_shells/Makefile.in @@ -148,7 +148,9 @@ am__uninstall_files_from_dir = { \ } am__installdirs = "$(DESTDIR)$(securelibdir)" "$(DESTDIR)$(man8dir)" LTLIBRARIES = $(securelib_LTLIBRARIES) -pam_shells_la_DEPENDENCIES = $(top_builddir)/libpam/libpam.la +am__DEPENDENCIES_1 = +pam_shells_la_DEPENDENCIES = $(top_builddir)/libpam/libpam.la \ + $(am__DEPENDENCIES_1) pam_shells_la_SOURCES = pam_shells.c pam_shells_la_OBJECTS = pam_shells.lo AM_V_lt = $(am__v_lt_@AM_V@) @@ -428,6 +430,7 @@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ +DOCBOOK_RNG = @DOCBOOK_RNG@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ @@ -440,11 +443,13 @@ EXEEXT = @EXEEXT@ EXE_CFLAGS = @EXE_CFLAGS@ EXE_LDFLAGS = @EXE_LDFLAGS@ FGREP = @FGREP@ +FILECMD = @FILECMD@ FO2PDF = @FO2PDF@ GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@ GMSGFMT = @GMSGFMT@ GMSGFMT_015 = @GMSGFMT_015@ GREP = @GREP@ +HTML_STYLESHEET = @HTML_STYLESHEET@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ @@ -476,12 +481,14 @@ LIBSELINUX = @LIBSELINUX@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ +LOGIND_CFLAGS = @LOGIND_CFLAGS@ LTLIBICONV = @LTLIBICONV@ LTLIBINTL = @LTLIBINTL@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ +MAN_STYLESHEET = @MAN_STYLESHEET@ MKDIR_P = @MKDIR_P@ MSGFMT = @MSGFMT@ MSGFMT_015 = @MSGFMT_015@ @@ -504,6 +511,7 @@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ +PDF_STYLESHEET = @PDF_STYLESHEET@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ @@ -514,12 +522,16 @@ SECUREDIR = @SECUREDIR@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ -STRINGPARAM_HMAC = @STRINGPARAM_HMAC@ +STRINGPARAM_PROFILECONDITIONS = @STRINGPARAM_PROFILECONDITIONS@ STRINGPARAM_VENDORDIR = @STRINGPARAM_VENDORDIR@ STRIP = @STRIP@ +SYSTEMD_CFLAGS = @SYSTEMD_CFLAGS@ +SYSTEMD_LIBS = @SYSTEMD_LIBS@ TIRPC_CFLAGS = @TIRPC_CFLAGS@ TIRPC_LIBS = @TIRPC_LIBS@ +TXT_STYLESHEET = @TXT_STYLESHEET@ USE_NLS = @USE_NLS@ +VENDOR_SCONFIGDIR = @VENDOR_SCONFIGDIR@ VERSION = @VERSION@ WARN_CFLAGS = @WARN_CFLAGS@ XGETTEXT = @XGETTEXT@ @@ -593,13 +605,14 @@ XMLS = README.xml pam_shells.8.xml dist_check_SCRIPTS = tst-pam_shells TESTS = $(dist_check_SCRIPTS) securelibdir = $(SECUREDIR) -secureconfdir = $(SCONFIGDIR) +@HAVE_VENDORDIR_FALSE@secureconfdir = $(SCONFIGDIR) +@HAVE_VENDORDIR_TRUE@secureconfdir = $(VENDOR_SCONFIGDIR) AM_CFLAGS = -I$(top_srcdir)/libpam/include -I$(top_srcdir)/libpamc/include \ - $(WARN_CFLAGS) + $(WARN_CFLAGS) $(ECONF_CFLAGS) AM_LDFLAGS = -no-undefined -avoid-version -module $(am__append_1) securelib_LTLIBRARIES = pam_shells.la -pam_shells_la_LIBADD = $(top_builddir)/libpam/libpam.la +pam_shells_la_LIBADD = $(top_builddir)/libpam/libpam.la $(ECONF_LIBS) @ENABLE_REGENERATE_MAN_TRUE@dist_noinst_DATA = README all: all-am diff --git a/modules/pam_shells/README b/modules/pam_shells/README index e09dd205..bde6667c 100644 --- a/modules/pam_shells/README +++ b/modules/pam_shells/README @@ -7,7 +7,11 @@ DESCRIPTION pam_shells is a PAM module that only allows access to the system if the user's shell is listed in /etc/shells. -It also checks if /etc/shells is a plain file and not world writable. +If this file does not exist, entries are taken from files %vendordir%/shells, +%vendordir%/shells.d/* and /etc/shells.d/* in that order. + +It also checks if needed files (e.g. /etc/shells) are plain files and not world +writable. OPTIONS diff --git a/modules/pam_shells/README.xml b/modules/pam_shells/README.xml index 154b97b5..c4da1a06 100644 --- a/modules/pam_shells/README.xml +++ b/modules/pam_shells/README.xml @@ -1,41 +1,27 @@ -<?xml version="1.0" encoding='UTF-8'?> -<!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN" -"http://www.docbook.org/xml/4.3/docbookx.dtd" -[ -<!-- -<!ENTITY pamaccess SYSTEM "pam_shells.8.xml"> ---> -]> +<article xmlns="http://docbook.org/ns/docbook" version="5.0"> -<article> - - <articleinfo> + <info> <title> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" - href="pam_shells.8.xml" xpointer='xpointer(//refnamediv[@id = "pam_shells-name"]/*)'/> + <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="pam_shells.8.xml" xpointer='xpointer(id("pam_shells-name")/*)'/> </title> - </articleinfo> + </info> <section> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" - href="pam_shells.8.xml" xpointer='xpointer(//refsect1[@id = "pam_shells-description"]/*)'/> + <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="pam_shells.8.xml" xpointer='xpointer(id("pam_shells-description")/*)'/> </section> <section> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" - href="pam_shells.8.xml" xpointer='xpointer(//refsect1[@id = "pam_shells-options"]/*)'/> + <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="pam_shells.8.xml" xpointer='xpointer(id("pam_shells-options")/*)'/> </section> <section> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" - href="pam_shells.8.xml" xpointer='xpointer(//refsect1[@id = "pam_shells-examples"]/*)'/> + <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="pam_shells.8.xml" xpointer='xpointer(id("pam_shells-examples")/*)'/> </section> <section> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" - href="pam_shells.8.xml" xpointer='xpointer(//refsect1[@id = "pam_shells-author"]/*)'/> + <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="pam_shells.8.xml" xpointer='xpointer(id("pam_shells-author")/*)'/> </section> -</article> +</article>
\ No newline at end of file diff --git a/modules/pam_shells/pam_shells.8 b/modules/pam_shells/pam_shells.8 index 4e519d17..af3dc668 100644 --- a/modules/pam_shells/pam_shells.8 +++ b/modules/pam_shells/pam_shells.8 @@ -1,13 +1,13 @@ '\" t .\" Title: pam_shells .\" Author: [see the "AUTHOR" section] -.\" Generator: DocBook XSL Stylesheets v1.79.1 <http://docbook.sf.net/> -.\" Date: 09/03/2021 +.\" Generator: DocBook XSL Stylesheets v1.79.2 <http://docbook.sf.net/> +.\" Date: 05/07/2023 .\" Manual: Linux-PAM Manual -.\" Source: Linux-PAM Manual +.\" Source: Linux-PAM .\" Language: English .\" -.TH "PAM_SHELLS" "8" "09/03/2021" "Linux-PAM Manual" "Linux\-PAM Manual" +.TH "PAM_SHELLS" "8" "05/07/2023" "Linux\-PAM" "Linux\-PAM Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- @@ -37,9 +37,8 @@ pam_shells \- PAM module to check for valid login shell pam_shells is a PAM module that only allows access to the system if the user\*(Aqs shell is listed in /etc/shells\&. .PP -It also checks if -/etc/shells -is a plain file and not world writable\&. +It also checks if needed files (e\&.g\&. +/etc/shells) are plain files and not world writable\&. .SH "OPTIONS" .PP This module does not recognise any options\&. diff --git a/modules/pam_shells/pam_shells.8.xml b/modules/pam_shells/pam_shells.8.xml index 15f47671..b9f90e94 100644 --- a/modules/pam_shells/pam_shells.8.xml +++ b/modules/pam_shells/pam_shells.8.xml @@ -1,27 +1,24 @@ -<?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_shells"> +<refentry xmlns="http://docbook.org/ns/docbook" version="5.0" xml:id="pam_shells"> <refmeta> <refentrytitle>pam_shells</refentrytitle> <manvolnum>8</manvolnum> - <refmiscinfo class="sectdesc">Linux-PAM Manual</refmiscinfo> + <refmiscinfo class="source">Linux-PAM</refmiscinfo> + <refmiscinfo class="manual">Linux-PAM Manual</refmiscinfo> </refmeta> - <refnamediv id="pam_shells-name"> + <refnamediv xml:id="pam_shells-name"> <refname>pam_shells</refname> <refpurpose>PAM module to check for valid login shell</refpurpose> </refnamediv> <refsynopsisdiv> - <cmdsynopsis id="pam_shells-cmdsynopsis"> + <cmdsynopsis xml:id="pam_shells-cmdsynopsis" sepchar=" "> <command>pam_shells.so</command> </cmdsynopsis> </refsynopsisdiv> - <refsect1 id="pam_shells-description"> + <refsect1 xml:id="pam_shells-description"> <title>DESCRIPTION</title> @@ -29,19 +26,27 @@ pam_shells is a PAM module that only allows access to the system if the user's shell is listed in <filename>/etc/shells</filename>. </para> + + <para condition="with_vendordir_and_with_econf"> + If this file does not exist, entries are taken from files + <filename>%vendordir%/shells</filename>, + <filename>%vendordir%/shells.d/*</filename> and + <filename>/etc/shells.d/*</filename> in that order. + </para> + <para> - It also checks if <filename>/etc/shells</filename> is a plain - file and not world writable. + It also checks if needed files (e.g. <filename>/etc/shells</filename>) are plain + files and not world writable. </para> </refsect1> - <refsect1 id="pam_shells-options"> + <refsect1 xml:id="pam_shells-options"> <title>OPTIONS</title> <para> This module does not recognise any options.</para> </refsect1> - <refsect1 id="pam_shells-types"> + <refsect1 xml:id="pam_shells-types"> <title>MODULE TYPES PROVIDED</title> <para> The <option>auth</option> and <option>account</option> @@ -49,7 +54,7 @@ </para> </refsect1> - <refsect1 id='pam_shells-return_values'> + <refsect1 xml:id="pam_shells-return_values"> <title>RETURN VALUES</title> <variablelist> <varlistentry> @@ -80,7 +85,7 @@ </variablelist> </refsect1> - <refsect1 id='pam_shells-examples'> + <refsect1 xml:id="pam_shells-examples"> <title>EXAMPLES</title> <para> <programlisting> @@ -89,7 +94,7 @@ auth required pam_shells.so </para> </refsect1> - <refsect1 id='pam_shells-see_also'> + <refsect1 xml:id="pam_shells-see_also"> <title>SEE ALSO</title> <para> <citerefentry> @@ -107,11 +112,11 @@ auth required pam_shells.so </para> </refsect1> - <refsect1 id='pam_shells-author'> + <refsect1 xml:id="pam_shells-author"> <title>AUTHOR</title> <para> pam_shells was written by Erik Troan <ewt@redhat.com>. </para> </refsect1> -</refentry> +</refentry>
\ No newline at end of file diff --git a/modules/pam_shells/pam_shells.c b/modules/pam_shells/pam_shells.c index dc8f4878..abebdd0c 100644 --- a/modules/pam_shells/pam_shells.c +++ b/modules/pam_shells/pam_shells.c @@ -13,27 +13,47 @@ #include <string.h> #include <stdio.h> #include <stdlib.h> +#include <stdbool.h> #include <sys/stat.h> #include <syslog.h> #include <unistd.h> +#if defined (USE_ECONF) && defined (VENDORDIR) +#include <libeconf.h> +#endif #include <security/pam_modules.h> #include <security/pam_modutil.h> #include <security/pam_ext.h> #define SHELL_FILE "/etc/shells" - +#define SHELLS "shells" +#define ETCDIR "/etc" #define DEFAULT_SHELL "/bin/sh" +static bool check_file(const char *filename, const void *pamh) +{ + struct stat sb; + + if (stat(filename, &sb)) { + pam_syslog(pamh, LOG_ERR, "Cannot stat %s: %m", filename); + return false; /* must have /etc/shells */ + } + + if ((sb.st_mode & S_IWOTH) || !S_ISREG(sb.st_mode)) { + pam_syslog(pamh, LOG_ERR, + "%s is either world writable or not a normal file", + filename); + return false; + } + return true; +} + static int perform_check(pam_handle_t *pamh) { int retval = PAM_AUTH_ERR; const char *userName; const char *userShell; - char shellFileLine[256]; - struct stat sb; struct passwd * pw; - FILE * shellFile; retval = pam_get_user(pamh, &userName, NULL); if (retval != PAM_SUCCESS) { @@ -48,18 +68,50 @@ static int perform_check(pam_handle_t *pamh) if (userShell[0] == '\0') userShell = DEFAULT_SHELL; - if (stat(SHELL_FILE,&sb)) { - pam_syslog(pamh, LOG_ERR, "Cannot stat %s: %m", SHELL_FILE); - return PAM_AUTH_ERR; /* must have /etc/shells */ +#if defined (USE_ECONF) && defined (VENDORDIR) + size_t size = 0; + econf_err error; + char **keys; + econf_file *key_file; + + error = econf_readDirsWithCallback(&key_file, + VENDORDIR, + ETCDIR, + SHELLS, + NULL, + "", /* key only */ + "#", /* comment */ + check_file, pamh); + if (error) { + pam_syslog(pamh, LOG_ERR, + "Cannot parse shell files: %s", + econf_errString(error)); + return PAM_AUTH_ERR; } - if ((sb.st_mode & S_IWOTH) || !S_ISREG(sb.st_mode)) { + error = econf_getKeys(key_file, NULL, &size, &keys); + if (error) { pam_syslog(pamh, LOG_ERR, - "%s is either world writable or not a normal file", - SHELL_FILE); + "Cannot evaluate entries in shell files: %s", + econf_errString(error)); + econf_free (key_file); return PAM_AUTH_ERR; } + retval = 1; + for (size_t i = 0; i < size; i++) { + retval = strcmp(keys[i], userShell); + if (!retval) + break; + } + econf_free (key_file); +#else + char shellFileLine[256]; + FILE * shellFile; + + if (!check_file(SHELL_FILE, pamh)) + return PAM_AUTH_ERR; + shellFile = fopen(SHELL_FILE,"r"); if (shellFile == NULL) { /* Check that we opened it successfully */ pam_syslog(pamh, LOG_ERR, "Error opening %s: %m", SHELL_FILE); @@ -75,6 +127,7 @@ static int perform_check(pam_handle_t *pamh) } fclose(shellFile); + #endif if (retval) { return PAM_AUTH_ERR; |