AC_CHECK_LIB([econf],[econf_readDirs],[LIBECONF="-leconf"],[LIBECONF=""])
if test -n "$LIBECONF"; then
+ AC_DEFINE_UNQUOTED([VENDORDIR], ["$enable_vendordir"],
+ [Directory for distribution provided configuration files])
ECONF_CPPFLAGS="-DUSE_ECONF=1"
AC_ARG_ENABLE([vendordir],
AS_HELP_STRING([--enable-vendordir=DIR], [Directory for distribution provided configuration files]),,[])
AC_SUBST(ECONF_CPPFLAGS)
AC_SUBST(LIBECONF)
AC_SUBST([VENDORDIR], [$enable_vendordir])
+if test "x$enable_vendordir" != x; then
+ AC_DEFINE(HAVE_VENDORDIR, 1, [Define to support vendor settings.])
+fi
AM_CONDITIONAL([HAVE_VENDORDIR], [test "x$enable_vendordir" != x])
if test "$enable_shadowgrp" = "yes"; then
echo " subordinate IDs support: $enable_subids"
echo " use file caps: $with_fcaps"
echo " install su: $with_su"
+echo " enabled vendor dir: $enable_vendordir"
echo
<refsect1 id='note'>
<title>NOTE</title>
- <para>
+ <para condition="without_vendordir">
The only restriction placed on the login shell is that the command
name must be listed in <filename>/etc/shells</filename>, unless the
invoker is the superuser, and then any value may be added. An
changing to a restricted shell would prevent the user from ever
changing her login shell back to its original value.
</para>
+ <para condition="with_vendordir">
+ The only restriction placed on the login shell is that the command
+ name must be listed in <filename>/etc/shells</filename>.
+ If this file does not exist, the definitions are taken from the files
+ <filename>%vendordir%/shells</filename>,
+ <filename>%vendordir%/shells.d/*</filename> and
+ <filename>/etc/shells.d/*</filename> in that order.
+ If <filename>/etc/shells.d/@filename@</filename> exists, then
+ <filename>%vendordir%/shells.d/@filename@</filename> will not be used.
+ If the invoker is the superuser any value may be added regardless what is
+ defined in the configuration files.
+ An account with a restricted login shell may not change her login shell.
+ </para>
+ <para>
+ For this reason, placing <filename>/bin/rsh</filename> in
+ <filename>/etc/shells</filename> is discouraged since accidentally
+ changing to a restricted shell would prevent the user from ever
+ changing her login shell back to its original value.
+ </para>
</refsect1>
<refsect1 id='configuration' condition="no_pam">
</varlistentry>
<varlistentry>
<term><filename>/etc/shells</filename></term>
- <listitem>
+ <listitem condition="without_vendordir">
<para>List of valid login shells.</para>
</listitem>
+ <listitem condition="with_vendordir">
+ <para>User defined list of valid login shells.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry condition="with_vendordir">
+ <term><filename>%vendordir%/shells</filename></term>
+ <listitem>
+ <para>Default configuration file if
+ <filename>/etc/shells</filename> does not exist.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry condition="with_vendordir">
+ <term><filename>%vendordir%/shells.d</filename></term>
+ <listitem>
+ <para>Directory for additional vendor specific configuration files.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry condition="with_vendordir">
+ <term><filename>/etc/shells.d</filename></term>
+ <listitem>
+ <para>Directory for additional user defined configuration files.</para>
+ </listitem>
</varlistentry>
<varlistentry>
<term><filename>/etc/login.defs</filename></term>
+if HAVE_VENDORDIR
+VENDORDIR_COND=with_vendordir
+else
+VENDORDIR_COND=without_vendordir
+endif
if USE_PAM
PAM_COND=pam
else
fi
man1/% man3/% man5/% man8/%: %.xml-config Makefile config.xml
- $(XSLTPROC) --stringparam profile.condition "$(PAM_COND);$(SHADOWGRP_COND);$(TCB_COND);$(SHA_CRYPT_COND);$(SUBIDS_COND)" \
+ $(XSLTPROC) --stringparam profile.condition "$(PAM_COND);$(SHADOWGRP_COND);$(TCB_COND);$(SHA_CRYPT_COND);$(SUBIDS_COND);$(VENDORDIR_COND)" \
--param "man.authors.section.enabled" "0" \
--stringparam "man.output.base.dir" "" \
+ --stringparam vendordir "$(VENDORDIR)" \
--param "man.output.in.separate.dir" "1" \
- -nonet http://docbook.sourceforge.net/release/xsl/current/manpages/profile-docbook.xsl $<
+ -nonet $(top_builddir)/man/shadow-man.xsl $<
clean-local:
rm -rf man1 man3 man5 man8
--- /dev/null
+<?xml version='1.0'?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:ss="http://docbook.sf.net/xmlns/string.subst/1.0" version="1.0">
+ <xsl:import href="http://docbook.sourceforge.net/release/xsl/current/manpages/profile-docbook.xsl"/>
+ <xsl:param name="vendordir"/>
+
+ <xsl:param name="man.string.subst.map.local.pre">
+ <ss:substitution oldstring="%vendordir%" newstring="{$vendordir}" />
+ </xsl:param>
+</xsl:stylesheet>
-I${top_srcdir}/lib \
-I$(top_srcdir)/libmisc \
-I$(top_srcdir) \
- -DLOCALEDIR=\"$(datadir)/locale\"
+ -DLOCALEDIR=\"$(datadir)/locale\" \
+ $(ECONF_CPPFLAGS)
AM_CFLAGS = $(LIBBSD_CFLAGS)
#ifndef SHELLS_FILE
#define SHELLS_FILE "/etc/shells"
#endif
+
+#ifdef HAVE_VENDORDIR
+#include <libeconf.h>
+#define SHELLS "shells"
+#define ETCDIR "/etc"
+#endif
+
/*
* Global variables
*/
* If getusershell() is available (Linux, *BSD, possibly others), use it
* instead of re-implementing it.
*/
+
+#ifdef HAVE_VENDORDIR
static bool shell_is_listed (const char *sh)
{
- char *cp;
bool found = false;
-#ifndef HAVE_GETUSERSHELL
- char buf[BUFSIZ];
- FILE *fp;
-#endif
+ size_t size = 0;
+ econf_err error;
+ char **keys;
+ econf_file *key_file;
+
+ error = econf_readDirs(&key_file,
+ VENDORDIR,
+ ETCDIR,
+ SHELLS,
+ NULL,
+ "", /* key only */
+ "#" /* comment */);
+ if (error) {
+ fprintf (stderr,
+ _("Cannot parse shell files: %s"),
+ econf_errString(error));
+ fail_exit (1);
+ }
+
+ error = econf_getKeys(key_file, NULL, &size, &keys);
+ if (error) {
+ fprintf (stderr,
+ _("Cannot evaluate entries in shell files: %s"),
+ econf_errString(error));
+ econf_free (key_file);
+ fail_exit (1);
+ }
+
+ for (size_t i = 0; i < size; i++) {
+ if (strcmp (keys[i], sh) == 0) {
+ found = true;
+ break;
+ }
+ }
+ econf_free (key_file);
+
+ return found;
+}
+
+#else /* without HAVE_VENDORDIR */
+
+static bool shell_is_listed (const char *sh)
+{
+ bool found = false;
#ifdef HAVE_GETUSERSHELL
+ char *cp;
setusershell ();
while ((cp = getusershell ())) {
if (strcmp (cp, sh) == 0) {
}
endusershell ();
#else
+ char buf[BUFSIZ];
+ FILE *fp;
+
fp = fopen (SHELLS_FILE, "r");
if (NULL == fp) {
return false;
#endif
return found;
}
+#endif /* with HAVE_VENDORDIR */
/*
* process_flags - parse the command line options