diff options
Diffstat (limited to 'modules')
300 files changed, 0 insertions, 38625 deletions
diff --git a/modules/.cvsignore b/modules/.cvsignore deleted file mode 100644 index 0615b487..00000000 --- a/modules/.cvsignore +++ /dev/null @@ -1,3 +0,0 @@ -*~ -Makefile -Makefile.in diff --git a/modules/Makefile.am b/modules/Makefile.am deleted file mode 100644 index c79f5957..00000000 --- a/modules/Makefile.am +++ /dev/null @@ -1,16 +0,0 @@ -# -# Copyright (c) 2005, 2006 Thorsten Kukuk <kukuk@thkukuk.de> -# - -SUBDIRS = pam_access pam_cracklib pam_debug pam_deny pam_echo \ - 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 \ - pam_securetty pam_selinux pam_sepermit pam_shells pam_stress \ - pam_succeed_if pam_tally pam_time pam_tty_audit pam_umask \ - pam_unix pam_userdb pam_warn pam_wheel pam_xauth pam_exec \ - pam_namespace pam_loginuid pam_faildelay - -CLEANFILES = *~ - -EXTRA_DIST = modules.map diff --git a/modules/modules.map b/modules/modules.map deleted file mode 100644 index 2234aa40..00000000 --- a/modules/modules.map +++ /dev/null @@ -1,11 +0,0 @@ -{ - global: - pam_sm_acct_mgmt; - pam_sm_authenticate; - pam_sm_chauthtok; - pam_sm_close_session; - pam_sm_open_session; - pam_sm_setcred; - local: *; -}; - diff --git a/modules/pam_access/.cvsignore b/modules/pam_access/.cvsignore deleted file mode 100644 index 6e648372..00000000 --- a/modules/pam_access/.cvsignore +++ /dev/null @@ -1,9 +0,0 @@ -*.la -*.lo -.deps -.libs -Makefile -Makefile.in -README -access.conf.5 -pam_access.8 diff --git a/modules/pam_access/Makefile.am b/modules/pam_access/Makefile.am deleted file mode 100644 index 9b58e81e..00000000 --- a/modules/pam_access/Makefile.am +++ /dev/null @@ -1,37 +0,0 @@ -# -# Copyright (c) 2005, 2006 Thorsten Kukuk <kukuk@thkukuk.de> -# - -CLEANFILES = *~ - -EXTRA_DIST = README access.conf $(MANS) $(XMLS) tst-pam_access - -man_MANS = access.conf.5 pam_access.8 - -XMLS = README.xml access.conf.5.xml pam_access.8.xml - -securelibdir = $(SECUREDIR) -secureconfdir = $(SCONFIGDIR) - -AM_CFLAGS = -I$(top_srcdir)/libpam/include -I$(top_srcdir)/libpamc/include \ - -DPAM_ACCESS_CONFIG=\"$(SCONFIGDIR)/access.conf\" -AM_LDFLAGS = -no-undefined -avoid-version -module -if HAVE_VERSIONING - AM_LDFLAGS += -Wl,--version-script=$(srcdir)/../modules.map -endif - -securelib_LTLIBRARIES = pam_access.la -pam_access_la_LIBADD = -L$(top_builddir)/libpam -lpam @LIBNSL@ - -secureconf_DATA = access.conf - -if ENABLE_REGENERATE_MAN - -noinst_DATA = README - -README: pam_access.8.xml access.conf.5.xml - --include $(top_srcdir)/Make.xml.rules -endif - -TESTS = tst-pam_access diff --git a/modules/pam_access/README.xml b/modules/pam_access/README.xml deleted file mode 100644 index 8c7d078b..00000000 --- a/modules/pam_access/README.xml +++ /dev/null @@ -1,39 +0,0 @@ -<?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_access.8.xml"> ---> -<!-- -<!ENTITY accessconf SYSTEM "access.conf.5.xml"> ---> -]> - -<article> - - <articleinfo> - - <title> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" - href="pam_access.8.xml" xpointer='xpointer(//refnamediv[@id = "pam_access-name"]/*)'/> - </title> - - </articleinfo> - - <section> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" - href="pam_access.8.xml" xpointer='xpointer(//refsect1[@id = "pam_access-description"]/*)'/> - </section> - - <section> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" - href="pam_access.8.xml" xpointer='xpointer(//refsect1[@id = "pam_access-options"]/*)'/> - </section> - - <section> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" - href="access.conf.5.xml" xpointer='xpointer(//refsect1[@id = "access.conf-examples"]/*)'/> - </section> - -</article> diff --git a/modules/pam_access/access.conf b/modules/pam_access/access.conf deleted file mode 100644 index 74c5fbe8..00000000 --- a/modules/pam_access/access.conf +++ /dev/null @@ -1,122 +0,0 @@ -# Login access control table. -# -# Comment line must start with "#", no space at front. -# Order of lines is important. -# -# When someone logs in, the table is scanned for the first entry that -# matches the (user, host) combination, or, in case of non-networked -# logins, the first entry that matches the (user, tty) combination. The -# permissions field of that table entry determines whether the login will -# be accepted or refused. -# -# Format of the login access control table is three fields separated by a -# ":" character: -# -# [Note, if you supply a 'fieldsep=|' argument to the pam_access.so -# module, you can change the field separation character to be -# '|'. This is useful for configurations where you are trying to use -# pam_access with X applications that provide PAM_TTY values that are -# the display variable like "host:0".] -# -# permission : users : origins -# -# The first field should be a "+" (access granted) or "-" (access denied) -# character. -# -# The second field should be a list of one or more login names, group -# names, or ALL (always matches). A pattern of the form user@host is -# matched when the login name matches the "user" part, and when the -# "host" part matches the local machine name. -# -# The third field should be a list of one or more tty names (for -# non-networked logins), host names, domain names (begin with "."), host -# addresses, internet network numbers (end with "."), ALL (always -# matches), NONE (matches no tty on non-networked logins) or -# LOCAL (matches any string that does not contain a "." character). -# -# You can use @netgroupname in host or user patterns; this even works -# for @usergroup@@hostgroup patterns. -# -# The EXCEPT operator makes it possible to write very compact rules. -# -# The group file is searched only when a name does not match that of the -# logged-in user. Both the user's primary group is matched, as well as -# groups in which users are explicitly listed. -# To avoid problems with accounts, which have the same name as a group, -# you can use brackets around group names '(group)' to differentiate. -# In this case, you should also set the "nodefgroup" option. -# -# TTY NAMES: Must be in the form returned by ttyname(3) less the initial -# "/dev" (e.g. tty1 or vc/1) -# -############################################################################## -# -# Disallow non-root logins on tty1 -# -#-:ALL EXCEPT root:tty1 -# -# Disallow console logins to all but a few accounts. -# -#-:ALL EXCEPT wheel shutdown sync:LOCAL -# -# Same, but make sure that really the group wheel and not the user -# wheel is used (use nodefgroup argument, too): -# -#-:ALL EXCEPT (wheel) shutdown sync:LOCAL -# -# Disallow non-local logins to privileged accounts (group wheel). -# -#-:wheel:ALL EXCEPT LOCAL .win.tue.nl -# -# Some accounts are not allowed to login from anywhere: -# -#-:wsbscaro wsbsecr wsbspac wsbsym wscosor wstaiwde:ALL -# -# All other accounts are allowed to login from anywhere. -# -############################################################################## -# All lines from here up to the end are building a more complex example. -############################################################################## -# -# User "root" should be allowed to get access via cron .. tty5 tty6. -#+ : root : cron crond :0 tty1 tty2 tty3 tty4 tty5 tty6 -# -# User "root" should be allowed to get access from hosts with ip addresses. -#+ : root : 192.168.200.1 192.168.200.4 192.168.200.9 -#+ : root : 127.0.0.1 -# -# User "root" should get access from network 192.168.201. -# This term will be evaluated by string matching. -# comment: It might be better to use network/netmask instead. -# The same is 192.168.201.0/24 or 192.168.201.0/255.255.255.0 -#+ : root : 192.168.201. -# -# User "root" should be able to have access from domain. -# Uses string matching also. -#+ : root : .foo.bar.org -# -# User "root" should be denied to get access from all other sources. -#- : root : ALL -# -# User "foo" and members of netgroup "nis_group" should be -# allowed to get access from all sources. -# This will only work if netgroup service is available. -#+ : @nis_group foo : ALL -# -# User "john" should get access from ipv4 net/mask -#+ : john : 127.0.0.0/24 -# -# User "john" should get access from ipv4 as ipv6 net/mask -#+ : john : ::ffff:127.0.0.0/127 -# -# User "john" should get access from ipv6 host address -#+ : john : 2001:4ca0:0:101::1 -# -# User "john" should get access from ipv6 host address (same as above) -#+ : john : 2001:4ca0:0:101:0:0:0:1 -# -# User "john" should get access from ipv6 net/mask -#+ : john : 2001:4ca0:0:101::/64 -# -# All other users should be denied to get access from all sources. -#- : ALL : ALL diff --git a/modules/pam_access/access.conf.5.xml b/modules/pam_access/access.conf.5.xml deleted file mode 100644 index f8eb7a4e..00000000 --- a/modules/pam_access/access.conf.5.xml +++ /dev/null @@ -1,203 +0,0 @@ -<?xml version="1.0" encoding='UTF-8'?> -<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.4//EN" - "http://www.oasis-open.org/docbook/xml/4.4/docbookx.dtd"> - -<refentry id="access.conf"> - - <refmeta> - <refentrytitle>access.conf</refentrytitle> - <manvolnum>5</manvolnum> - <refmiscinfo class="sectdesc">Linux-PAM Manual</refmiscinfo> - </refmeta> - - <refnamediv> - <refname>access.conf</refname> - <refpurpose>the login access control table file</refpurpose> - </refnamediv> - - - <refsect1 id='access.conf-description'> - <title>DESCRIPTION</title> - <para> - The <filename>/etc/security/access.conf</filename> file specifies - (<replaceable>user/group</replaceable>, <replaceable>host</replaceable>), - (<replaceable>user/group</replaceable>, <replaceable>network/netmask</replaceable>) or - (<replaceable>user/group</replaceable>, <replaceable>tty</replaceable>) - combinations for which a login will be either accepted or refused. - </para> - <para> - When someone logs in, the file <filename>access.conf</filename> is - scanned for the first entry that matches the - (<replaceable>user/group</replaceable>, <replaceable>host</replaceable>) or - (<replaceable>user/group</replaceable>, <replaceable>network/netmask</replaceable>) - combination, or, in case of non-networked logins, the first entry - that matches the - (<replaceable>user/group</replaceable>, <replaceable>tty</replaceable>) - combination. The permissions field of that table entry determines - whether the login will be accepted or refused. - </para> - - <para> - Each line of the login access control table has three fields separated - by a ":" character (colon): - </para> - - <para> - <replaceable>permission</replaceable>:<replaceable>users/groups</replaceable>:<replaceable>origins</replaceable> - </para> - - - <para> - The first field, the <replaceable>permission</replaceable> field, can be either a - "<emphasis>+</emphasis>" character (plus) for access granted or a - "<emphasis>-</emphasis>" character (minus) for access denied. - </para> - - <para> - The second field, the - <replaceable>users</replaceable>/<replaceable>group</replaceable> - field, should be a list of one or more login names, group names, or - <emphasis>ALL</emphasis> (which always matches). To differentiate - user entries from group entries, group entries should be written - with brackets, e.g. <emphasis>(group)</emphasis>. - </para> - - <para> - The third field, the <replaceable>origins</replaceable> - field, should be a list of one or more tty names (for non-networked - logins), host names, domain names (begin with "."), host addresses, - internet network numbers (end with "."), internet network addresses - with network mask (where network mask can be a decimal number or an - internet address also), <emphasis>ALL</emphasis> (which always matches) - or <emphasis>LOCAL</emphasis> (which matches any string that does not - contain a "." character). If supported by the system you can use - <emphasis>@netgroupname</emphasis> in host or user patterns. - </para> - - <para> - The <replaceable>EXCEPT</replaceable> operator makes it possible to - write very compact rules. - </para> - - <para> - If the <option>nodefgroup</option> is not set, the group file - is searched when a name does not match that of the logged-in - user. Only groups are matched in which users are explicitly listed. - However the PAM module does not look at the primary group id of a user. - </para> - - - <para> - The "<emphasis>#</emphasis>" character at start of line (no space - at front) can be used to mark this line as a comment line. - </para> - - </refsect1> - - <refsect1 id="access.conf-examples"> - <title>EXAMPLES</title> - <para> - These are some example lines which might be specified in - <filename>/etc/security/access.conf</filename>. - </para> - - <para> - User <emphasis>root</emphasis> should be allowed to get access via - <emphasis>cron</emphasis>, X11 terminal <emphasis remap='I'>:0</emphasis>, - <emphasis>tty1</emphasis>, ..., <emphasis>tty5</emphasis>, - <emphasis>tty6</emphasis>. - </para> - <para>+ : root : crond :0 tty1 tty2 tty3 tty4 tty5 tty6</para> - - <para> - User <emphasis>root</emphasis> should be allowed to get access from - hosts which own the IPv4 addresses. This does not mean that the - connection have to be a IPv4 one, a IPv6 connection from a host with - one of this IPv4 addresses does work, too. - </para> - <para>+ : root : 192.168.200.1 192.168.200.4 192.168.200.9</para> - <para>+ : root : 127.0.0.1</para> - - <para> - User <emphasis>root</emphasis> should get access from network - <literal>192.168.201.</literal> where the term will be evaluated by - string matching. But it might be better to use network/netmask instead. - The same meaning of <literal>192.168.201.</literal> is - <emphasis>192.168.201.0/24</emphasis> or - <emphasis>192.168.201.0/255.255.255.0</emphasis>. - </para> - <para>+ : root : 192.168.201.</para> - - <para> - User <emphasis>root</emphasis> should be able to have access from hosts - <emphasis>foo1.bar.org</emphasis> and <emphasis>foo2.bar.org</emphasis> - (uses string matching also). - </para> - <para>+ : root : foo1.bar.org foo2.bar.org</para> - - <para> - User <emphasis>root</emphasis> should be able to have access from - domain <emphasis>foo.bar.org</emphasis> (uses string matching also). - </para> - <para>+ : root : .foo.bar.org</para> - - <para> - User <emphasis>root</emphasis> should be denied to get access - from all other sources. - </para> - <para>- : root : ALL</para> - - <para> - User <emphasis>foo</emphasis> and members of netgroup - <emphasis>admins</emphasis> should be allowed to get access - from all sources. This will only work if netgroup service is available. - </para> - <para>+ : @admins foo : ALL</para> - - <para> - User <emphasis>john</emphasis> and <emphasis>foo</emphasis> - should get access from IPv6 host address. - </para> - <para>+ : john foo : 2001:4ca0:0:101::1</para> - - <para> - User <emphasis>john</emphasis> should get access from IPv6 net/mask. - </para> - <para>+ : john : 2001:4ca0:0:101::/64</para> - - <para> - Disallow console logins to all but the shutdown, sync and all - other accounts, which are a member of the wheel group. - </para> - <para>-:ALL EXCEPT (wheel) shutdown sync:LOCAL</para> - - <para> - All other users should be denied to get access from all sources. - </para> - <para>- : ALL : ALL</para> - - </refsect1> - - <refsect1 id="access.conf-see_also"> - <title>SEE ALSO</title> - <para> - <citerefentry><refentrytitle>pam_access</refentrytitle><manvolnum>8</manvolnum></citerefentry>, - <citerefentry><refentrytitle>pam.d</refentrytitle><manvolnum>5</manvolnum></citerefentry>, - <citerefentry><refentrytitle>pam</refentrytitle><manvolnum>8</manvolnum></citerefentry> - </para> - </refsect1> - - <refsect1 id="access.conf-author"> - <title>AUTHORS</title> - <para> - Original <citerefentry><refentrytitle>login.access</refentrytitle><manvolnum>5</manvolnum></citerefentry> - manual was provided by Guido van Rooij which was renamed to - <citerefentry><refentrytitle>access.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry> - to reflect relation to default config file. - </para> - <para> - Network address / netmask description and example text was - introduced by Mike Becher <mike.becher@lrz-muenchen.de>. - </para> - </refsect1> -</refentry> diff --git a/modules/pam_access/pam_access.8.xml b/modules/pam_access/pam_access.8.xml deleted file mode 100644 index 21970d49..00000000 --- a/modules/pam_access/pam_access.8.xml +++ /dev/null @@ -1,253 +0,0 @@ -<?xml version="1.0" encoding="ISO-8859-1"?> -<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN" - "http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd"> - -<refentry id='pam_access'> - - <refmeta> - <refentrytitle>pam_access</refentrytitle> - <manvolnum>8</manvolnum> - <refmiscinfo class='setdesc'>Linux-PAM Manual</refmiscinfo> - </refmeta> - - <refnamediv id='pam_access-name'> - <refname>pam_access</refname> - <refpurpose> - PAM module for logdaemon style login access control - </refpurpose> - </refnamediv> - -<!-- body begins here --> - - <refsynopsisdiv> - <cmdsynopsis id="pam_access-cmdsynopsis"> - <command>pam_access.so</command> - <arg choice="opt"> - debug - </arg> - <arg choice="opt"> - nodefgroup - </arg> - <arg choice="opt"> - noaudit - </arg> - <arg choice="opt"> - accessfile=<replaceable>file</replaceable> - </arg> - <arg choice="opt"> - fieldsep=<replaceable>sep</replaceable> - </arg> - <arg choice="opt"> - listsep=<replaceable>sep</replaceable> - </arg> - </cmdsynopsis> - </refsynopsisdiv> - - - <refsect1 id="pam_access-description"> - <title>DESCRIPTION</title> - <para> - The pam_access PAM module is mainly for access management. - It provides logdaemon style login access control based on login - names, host or domain names, internet addresses or network numbers, - or on terminal line names in case of non-networked logins. - </para> - <para> - By default rules for access management are taken from config file - <filename>/etc/security/access.conf</filename> if you don't specify - another file. - </para> - <para> - If Linux PAM is compiled with audit support the module will report - when it denies access based on origin (host or tty). - </para> - </refsect1> - - <refsect1 id="pam_access-options"> - <title>OPTIONS</title> - <variablelist> - - <varlistentry> - <term> - <option>accessfile=<replaceable>/path/to/access.conf</replaceable></option> - </term> - <listitem> - <para> - Indicate an alternative <filename>access.conf</filename> - style configuration file to override the default. This can - be useful when different services need different access lists. - </para> - </listitem> - </varlistentry> - - <varlistentry> - <term> - <option>debug</option> - </term> - <listitem> - <para> - A lot of debug informations are printed with - <citerefentry><refentrytitle>syslog</refentrytitle><manvolnum>3</manvolnum></citerefentry>. - </para> - </listitem> - </varlistentry> - - <varlistentry> - <term> - <option>noaudit</option> - </term> - <listitem> - <para> - Do not report logins from disallowed hosts and ttys to the audit subsystem. - </para> - </listitem> - </varlistentry> - - <varlistentry> - <term> - <option>fieldsep=<replaceable>separators</replaceable></option> - </term> - <listitem> - <para> - This option modifies the field separator character that - pam_access will recognize when parsing the access - configuration file. For example: - <emphasis remap='B'>fieldsep=|</emphasis> will cause the - default `:' character to be treated as part of a field value - and `|' becomes the field separator. Doing this may be - useful in conjuction with a system that wants to use - pam_access with X based applications, since the - <emphasis remap='B'>PAM_TTY</emphasis> item is likely to be - of the form "hostname:0" which includes a `:' character in - its value. But you should not need this. - </para> - </listitem> - </varlistentry> - - <varlistentry> - <term> - <option>listsep=<replaceable>separators</replaceable></option> - </term> - <listitem> - <para> - This option modifies the list separator character that - pam_access will recognize when parsing the access - configuration file. For example: - <emphasis remap='B'>listsep=,</emphasis> will cause the - default ` ' (space) and `\t' (tab) characters to be treated - as part of a list element value and `,' becomes the only - list element separator. Doing this may be useful on a system - with group information obtained from a Windows domain, - where the default built-in groups "Domain Users", - "Domain Admins" contain a space. - </para> - </listitem> - </varlistentry> - - <varlistentry> - <term> - <option>nodefgroup</option> - </term> - <listitem> - <para> - The group database will not be used for tokens not - identified as account name. - </para> - </listitem> - </varlistentry> - - </variablelist> - </refsect1> - - <refsect1 id="pam_access-services"> - <title>MODULE SERVICES PROVIDED</title> - <para> - All services are supported. - </para> - </refsect1> - - <refsect1 id="pam_access-return_values"> - <title>RETURN VALUES</title> - <variablelist> - <varlistentry> - <term>PAM_SUCCESS</term> - <listitem> - <para> - Access was granted. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term>PAM_PERM_DENIED</term> - <listitem> - <para> - Access was not granted. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term>PAM_IGNORE</term> - <listitem> - <para> - <function>pam_setcred</function> was called which does nothing. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term>PAM_ABORT</term> - <listitem> - <para> - Not all relevant data or options could be gotten. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term>PAM_USER_UNKNOWN</term> - <listitem> - <para> - The user is not known to the system. - </para> - </listitem> - </varlistentry> - </variablelist> - </refsect1> - - <refsect1 id="pam_access-files"> - <title>FILES</title> - <variablelist> - <varlistentry> - <term><filename>/etc/security/access.conf</filename></term> - <listitem> - <para>Default configuration file</para> - </listitem> - </varlistentry> - </variablelist> - </refsect1> - - <refsect1 id="pam_access-see_also"> - <title>SEE ALSO</title> - <para> - <citerefentry> - <refentrytitle>access.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_access-authors"> - <title>AUTHORS</title> - <para> - The logdaemon style login access control scheme was designed and implemented by - Wietse Venema. - The pam_access PAM module was developed by - Alexei Nogin <alexei@nogin.dnttm.ru>. - The IPv6 support and the network(address) / netmask feature - was developed and provided by Mike Becher <mike.becher@lrz-muenchen.de>. - </para> - </refsect1> -</refentry> diff --git a/modules/pam_access/pam_access.c b/modules/pam_access/pam_access.c deleted file mode 100644 index edb8fb0a..00000000 --- a/modules/pam_access/pam_access.c +++ /dev/null @@ -1,922 +0,0 @@ -/* pam_access module */ - -/* - * Written by Alexei Nogin <alexei@nogin.dnttm.ru> 1997/06/15 - * (I took login_access from logdaemon-5.6 and converted it to PAM - * using parts of pam_time code.) - * - ************************************************************************ - * Copyright message from logdaemon-5.6 (original file name DISCLAIMER) - ************************************************************************ - * Copyright 1995 by Wietse Venema. All rights reserved. Individual files - * may be covered by other copyrights (as noted in the file itself.) - * - * This material was originally written and compiled by Wietse Venema at - * Eindhoven University of Technology, The Netherlands, in 1990, 1991, - * 1992, 1993, 1994 and 1995. - * - * Redistribution and use in source and binary forms are permitted - * provided that this entire copyright notice is duplicated in all such - * copies. - * - * This software is provided "as is" and without any expressed or implied - * warranties, including, without limitation, the implied warranties of - * merchantibility and fitness for any particular purpose. - ************************************************************************* - */ - -#include "config.h" - -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> - -#include <stdarg.h> -#include <syslog.h> -#include <string.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <pwd.h> -#include <grp.h> -#include <errno.h> -#include <ctype.h> -#include <sys/utsname.h> -#include <rpcsvc/ypclnt.h> -#include <arpa/inet.h> -#include <netdb.h> -#include <sys/socket.h> - -#ifdef HAVE_LIBAUDIT -#include <libaudit.h> -#endif - -/* - * here, we make definitions for the externally accessible functions - * in this file (these definitions are required for static modules - * but strongly encouraged generally) they are used to instruct the - * modules include file to define their prototypes. - */ - -#define PAM_SM_AUTH -#define PAM_SM_ACCOUNT -#define PAM_SM_SESSION -#define PAM_SM_PASSWORD - -#include <security/_pam_macros.h> -#include <security/pam_modules.h> -#include <security/pam_modutil.h> -#include <security/pam_ext.h> - -/* login_access.c from logdaemon-5.6 with several changes by A.Nogin: */ - - /* - * This module implements a simple but effective form of login access - * control based on login names and on host (or domain) names, internet - * addresses (or network numbers), or on terminal line names in case of - * non-networked logins. Diagnostics are reported through syslog(3). - * - * Author: Wietse Venema, Eindhoven University of Technology, The Netherlands. - */ - -#if !defined(MAXHOSTNAMELEN) || (MAXHOSTNAMELEN < 64) -#undef MAXHOSTNAMELEN -#define MAXHOSTNAMELEN 256 -#endif - - /* Delimiters for fields and for lists of users, ttys or hosts. */ - - -#define ALL 2 -#define YES 1 -#define NO 0 - - /* - * A structure to bundle up all login-related information to keep the - * functional interfaces as generic as possible. - */ -struct login_info { - const struct passwd *user; - const char *from; - const char *config_file; - int debug; /* Print debugging messages. */ - int only_new_group_syntax; /* Only allow group entries of the form "(xyz)" */ - int noaudit; /* Do not audit denials */ - const char *fs; /* field separator */ - const char *sep; /* list-element separator */ -}; - -/* Parse module config arguments */ - -static int -parse_args(pam_handle_t *pamh, struct login_info *loginfo, - int argc, const char **argv) -{ - int i; - - loginfo->noaudit = NO; - loginfo->debug = NO; - loginfo->only_new_group_syntax = NO; - loginfo->fs = ":"; - loginfo->sep = ", \t"; - for (i=0; i<argc; ++i) { - if (!strncmp("fieldsep=", argv[i], 9)) { - - /* the admin wants to override the default field separators */ - loginfo->fs = argv[i]+9; - - } else if (!strncmp("listsep=", argv[i], 8)) { - - /* the admin wants to override the default list separators */ - loginfo->sep = argv[i]+8; - - } else if (!strncmp("accessfile=", argv[i], 11)) { - FILE *fp = fopen(11 + argv[i], "r"); - - if (fp) { - loginfo->config_file = 11 + argv[i]; - fclose(fp); - } else { - pam_syslog(pamh, LOG_ERR, - "failed to open accessfile=[%s]: %m", 11 + argv[i]); - return 0; - } - - } else if (strcmp (argv[i], "debug") == 0) { - loginfo->debug = YES; - } else if (strcmp (argv[i], "nodefgroup") == 0) { - loginfo->only_new_group_syntax = YES; - } else if (strcmp (argv[i], "noaudit") == 0) { - loginfo->noaudit = YES; - } else { - pam_syslog(pamh, LOG_ERR, "unrecognized option [%s]", argv[i]); - } - } - - return 1; /* OK */ -} - -/* --- static functions for checking whether the user should be let in --- */ - -typedef int match_func (pam_handle_t *, char *, struct login_info *); - -static int list_match (pam_handle_t *, char *, char *, struct login_info *, - match_func *); -static int user_match (pam_handle_t *, char *, struct login_info *); -static int group_match (pam_handle_t *, const char *, const char *, int); -static int from_match (pam_handle_t *, char *, struct login_info *); -static int string_match (pam_handle_t *, const char *, const char *, int); -static int network_netmask_match (pam_handle_t *, const char *, const char *, int); - - -/* isipaddr - find out if string provided is an IP address or not */ - -static int -isipaddr (const char *string, int *addr_type, - struct sockaddr_storage *addr) -{ - struct sockaddr_storage local_addr; - int is_ip; - - /* We use struct sockaddr_storage addr because - * struct in_addr/in6_addr is an integral part - * of struct sockaddr and we doesn't want to - * use its value. - */ - - if (addr == NULL) - addr = &local_addr; - - memset(addr, 0, sizeof(struct sockaddr_storage)); - - /* first ipv4 */ - if (inet_pton(AF_INET, string, addr) > 0) - { - if (addr_type != NULL) - *addr_type = AF_INET; - - is_ip = YES; - } - else if (inet_pton(AF_INET6, string, addr) > 0) - { /* then ipv6 */ - if (addr_type != NULL) { - *addr_type = AF_INET6; - } - is_ip = YES; - } - else - is_ip = NO; - - return is_ip; -} - - -/* are_addresses_equal - translate IP address strings to real IP - * addresses and compare them to find out if they are equal. - * If netmask was provided it will be used to focus comparation to - * relevant bits. - */ -static int -are_addresses_equal (const char *ipaddr0, const char *ipaddr1, - const char *netmask) -{ - struct sockaddr_storage addr0; - struct sockaddr_storage addr1; - int addr_type0 = 0; - int addr_type1 = 0; - - if (isipaddr (ipaddr0, &addr_type0, &addr0) == NO) - return NO; - - if (isipaddr (ipaddr1, &addr_type1, &addr1) == NO) - return NO; - - if (addr_type0 != addr_type1) - /* different address types */ - return NO; - - if (netmask != NULL) { - /* Got a netmask, so normalize addresses? */ - struct sockaddr_storage nmask; - unsigned char *byte_a, *byte_nm; - - memset(&nmask, 0, sizeof(struct sockaddr_storage)); - if (inet_pton(addr_type0, netmask, (void *)&nmask) > 0) { - unsigned int i; - byte_a = (unsigned char *)(&addr0); - byte_nm = (unsigned char *)(&nmask); - for (i=0; i<sizeof(struct sockaddr_storage); i++) { - byte_a[i] = byte_a[i] & byte_nm[i]; - } - - byte_a = (unsigned char *)(&addr1); - byte_nm = (unsigned char *)(&nmask); - for (i=0; i<sizeof(struct sockaddr_storage); i++) { - byte_a[i] = byte_a[i] & byte_nm[i]; - } - } - } - - - /* Are the two addresses equal? */ - if (memcmp((void *)&addr0, (void *)&addr1, - sizeof(struct sockaddr_storage)) == 0) { - return(YES); - } - - return(NO); -} - -static char * -number_to_netmask (long netmask, int addr_type, - char *ipaddr_buf, size_t ipaddr_buf_len) -{ - /* We use struct sockaddr_storage addr because - * struct in_addr/in6_addr is an integral part - * of struct sockaddr and we doesn't want to - * use its value. - */ - struct sockaddr_storage nmask; - unsigned char *byte_nm; - const char *ipaddr_dst = NULL; - int i, ip_bytes; - - if (netmask == 0) { - /* mask 0 is the same like no mask */ - return(NULL); - } - - memset(&nmask, 0, sizeof(struct sockaddr_storage)); - if (addr_type == AF_INET6) { - /* ipv6 address mask */ - ip_bytes = 16; - } else { - /* default might be an ipv4 address mask */ - addr_type = AF_INET; - ip_bytes = 4; - } - - byte_nm = (unsigned char *)(&nmask); - /* translate number to mask */ - for (i=0; i<ip_bytes; i++) { - if (netmask >= 8) { - byte_nm[i] = 0xff; - netmask -= 8; - } else - if (netmask > 0) { - byte_nm[i] = 0xff << (8 - netmask); - break; - } else - if (netmask <= 0) { - break; - } - } - - /* now generate netmask address string */ - ipaddr_dst = inet_ntop(addr_type, &nmask, ipaddr_buf, ipaddr_buf_len); - if (ipaddr_dst == ipaddr_buf) { - return (ipaddr_buf); - } - - return (NULL); -} - -/* login_access - match username/group and host/tty with access control file */ - -static int -login_access (pam_handle_t *pamh, struct login_info *item) -{ - FILE *fp; - char line[BUFSIZ]; - char *perm; /* becomes permission field */ - char *users; /* becomes list of login names */ - char *froms; /* becomes list of terminals or hosts */ - int match = NO; - int nonall_match = NO; - int end; - int lineno = 0; /* for diagnostics */ - char *sptr; - - if (item->debug) - pam_syslog (pamh, LOG_DEBUG, - "login_access: user=%s, from=%s, file=%s", - item->user->pw_name, - item->from, item->config_file); - - /* - * Process the table one line at a time and stop at the first match. - * Blank lines and lines that begin with a '#' character are ignored. - * Non-comment lines are broken at the ':' character. All fields are - * mandatory. The first field should be a "+" or "-" character. A - * non-existing table means no access control. - */ - - if ((fp = fopen(item->config_file, "r"))!=NULL) { - while (!match && fgets(line, sizeof(line), fp)) { - lineno++; - if (line[end = strlen(line) - 1] != '\n') { - pam_syslog(pamh, LOG_ERR, - "%s: line %d: missing newline or line too long", - item->config_file, lineno); - continue; - } - if (line[0] == '#') - continue; /* comment line */ - while (end > 0 && isspace(line[end - 1])) - end--; - line[end] = 0; /* strip trailing whitespace */ - if (line[0] == 0) /* skip blank lines */ - continue; - - /* Allow field seperator in last field of froms */ - if (!(perm = strtok_r(line, item->fs, &sptr)) - || !(users = strtok_r(NULL, item->fs, &sptr)) - || !(froms = strtok_r(NULL, "\n", &sptr))) { - pam_syslog(pamh, LOG_ERR, "%s: line %d: bad field count", - item->config_file, lineno); - continue; - } - if (perm[0] != '+' && perm[0] != '-') { - pam_syslog(pamh, LOG_ERR, "%s: line %d: bad first field", - item->config_file, lineno); - continue; - } - if (item->debug) - pam_syslog (pamh, LOG_DEBUG, - "line %d: %s : %s : %s", lineno, perm, users, froms); - match = list_match(pamh, users, NULL, item, user_match); - if (item->debug) - pam_syslog (pamh, LOG_DEBUG, "user_match=%d, \"%s\"", - match, item->user->pw_name); - if (match) { - match = list_match(pamh, froms, NULL, item, from_match); - if (!match && perm[0] == '+') { - nonall_match = YES; - } - if (item->debug) - pam_syslog (pamh, LOG_DEBUG, - "from_match=%d, \"%s\"", match, item->from); - } - } - (void) fclose(fp); - } else if (errno == ENOENT) { - /* This is no error. */ - pam_syslog(pamh, LOG_WARNING, "warning: cannot open %s: %m", - item->config_file); - } else { - pam_syslog(pamh, LOG_ERR, "cannot open %s: %m", item->config_file); - return NO; - } -#ifdef HAVE_LIBAUDIT - if (!item->noaudit && line[0] == '-' && (match == YES || (match == ALL && - nonall_match == YES))) { - pam_modutil_audit_write(pamh, AUDIT_ANOM_LOGIN_LOCATION, - "pam_access", 0); - } -#endif - return (match == NO || (line[0] == '+')); -} - - -/* list_match - match an item against a list of tokens with exceptions */ - -static int -list_match(pam_handle_t *pamh, char *list, char *sptr, - struct login_info *item, match_func *match_fn) -{ - char *tok; - int match = NO; - - if (item->debug && list != NULL) - pam_syslog (pamh, LOG_DEBUG, - "list_match: list=%s, item=%s", list, item->user->pw_name); - - /* - * Process tokens one at a time. We have exhausted all possible matches - * when we reach an "EXCEPT" token or the end of the list. If we do find - * a match, look for an "EXCEPT" list and recurse to determine whether - * the match is affected by any exceptions. - */ - - for (tok = strtok_r(list, item->sep, &sptr); tok != 0; - tok = strtok_r(NULL, item->sep, &sptr)) { - if (strcasecmp(tok, "EXCEPT") == 0) /* EXCEPT: give up */ - break; - if ((match = (*match_fn) (pamh, tok, item))) /* YES */ - break; - } - /* Process exceptions to matches. */ - - if (match != NO) { - while ((tok = strtok_r(NULL, item->sep, &sptr)) && strcasecmp(tok, "EXCEPT")) - /* VOID */ ; - if (tok == 0) - return match; - if (list_match(pamh, NULL, sptr, item, match_fn) == NO) - return YES; /* drop special meaning of ALL */ - } - return (NO); -} - -/* myhostname - figure out local machine name */ - -static char *myhostname(void) -{ - static char name[MAXHOSTNAMELEN + 1]; - - if (gethostname(name, MAXHOSTNAMELEN) == 0) { - name[MAXHOSTNAMELEN] = 0; - return (name); - } - return NULL; -} - -/* netgroup_match - match group against machine or user */ - -static int -netgroup_match (pam_handle_t *pamh, const char *netgroup, - const char *machine, const char *user, int debug) -{ - char *mydomain = NULL; - int retval; - - yp_get_default_domain(&mydomain); - - - retval = innetgr (netgroup, machine, user, mydomain); - if (debug == YES) - pam_syslog (pamh, LOG_DEBUG, - "netgroup_match: %d (netgroup=%s, machine=%s, user=%s, domain=%s)", - retval, netgroup ? netgroup : "NULL", - machine ? machine : "NULL", - user ? user : "NULL", mydomain ? mydomain : "NULL"); - return retval; - -} - -/* user_match - match a username against one token */ - -static int -user_match (pam_handle_t *pamh, char *tok, struct login_info *item) -{ - char *string = item->user->pw_name; - struct login_info fake_item; - char *at; - int rv; - - if (item->debug) - pam_syslog (pamh, LOG_DEBUG, - "user_match: tok=%s, item=%s", tok, string); - - /* - * If a token has the magic value "ALL" the match always succeeds. - * Otherwise, return YES if the token fully matches the username, if the - * token is a group that contains the username, or if the token is the - * name of the user's primary group. - */ - - if ((at = strchr(tok + 1, '@')) != 0) { /* split user@host pattern */ - *at = 0; - fake_item.from = myhostname(); - if (fake_item.from == NULL) - return NO; - return (user_match (pamh, tok, item) && - from_match (pamh, at + 1, &fake_item)); - } else if (tok[0] == '@') /* netgroup */ - return (netgroup_match (pamh, tok + 1, (char *) 0, string, item->debug)); - else if (tok[0] == '(' && tok[strlen(tok) - 1] == ')') - return (group_match (pamh, tok, string, item->debug)); - else if ((rv=string_match (pamh, tok, string, item->debug)) != NO) /* ALL or exact match */ - return rv; - else if (item->only_new_group_syntax == NO && - pam_modutil_user_in_group_nam_nam (pamh, - item->user->pw_name, tok)) - /* try group membership */ - return YES; - - return NO; -} - - -/* group_match - match a username against token named group */ - -static int -group_match (pam_handle_t *pamh, const char *tok, const char* usr, - int debug) -{ - char grptok[BUFSIZ]; - - if (debug) - pam_syslog (pamh, LOG_DEBUG, - "group_match: grp=%s, user=%s", grptok, usr); - - if (strlen(tok) < 3) - return NO; - - /* token is recieved under the format '(...)' */ - memset(grptok, 0, BUFSIZ); - strncpy(grptok, tok + 1, strlen(tok) - 2); - - if (pam_modutil_user_in_group_nam_nam(pamh, usr, grptok)) - return YES; - - return NO; -} - - -/* from_match - match a host or tty against a list of tokens */ - -static int -from_match (pam_handle_t *pamh UNUSED, char *tok, struct login_info *item) -{ - const char *string = item->from; - int tok_len; - int str_len; - int rv; - - if (item->debug) - pam_syslog (pamh, LOG_DEBUG, - "from_match: tok=%s, item=%s", tok, string); - - /* - * If a token has the magic value "ALL" the match always succeeds. Return - * YES if the token fully matches the string. If the token is a domain - * name, return YES if it matches the last fields of the string. If the - * token has the magic value "LOCAL", return YES if the string does not - * contain a "." character. If the token is a network number, return YES - * if it matches the head of the string. - */ - - if (string == NULL) { - return NO; - } else if (tok[0] == '@') { /* netgroup */ - return (netgroup_match (pamh, tok + 1, string, (char *) 0, item->debug)); - } else if ((rv = string_match(pamh, tok, string, item->debug)) != NO) { - /* ALL or exact match */ - return rv; - } else if (tok[0] == '.') { /* domain: match last fields */ - if ((str_len = strlen(string)) > (tok_len = strlen(tok)) - && strcasecmp(tok, string + str_len - tok_len) == 0) - return (YES); - } else if (strcasecmp(tok, "LOCAL") == 0) { /* local: no dots */ - if (strchr(string, '.') == 0) - return (YES); - } else if (tok[(tok_len = strlen(tok)) - 1] == '.') { - struct addrinfo *res; - struct addrinfo hint; - - memset (&hint, '\0', sizeof (hint)); - hint.ai_flags = AI_CANONNAME; - hint.ai_family = AF_INET; - - if (getaddrinfo (string, NULL, &hint, &res) != 0) - return NO; - else - { - struct addrinfo *runp = res; - - while (runp != NULL) - { - char buf[INET_ADDRSTRLEN+2]; - - if (runp->ai_family == AF_INET) - { - inet_ntop (runp->ai_family, - &((struct sockaddr_in *) runp->ai_addr)->sin_addr, - buf, sizeof (buf)); - - strcat (buf, "."); - - if (strncmp(tok, buf, tok_len) == 0) - { - freeaddrinfo (res); - return YES; - } - } - runp = runp->ai_next; - } - freeaddrinfo (res); - } - } else if (isipaddr(string, NULL, NULL) == YES) { - /* Assume network/netmask with a IP of a host. */ - if (network_netmask_match(pamh, tok, string, item->debug)) - return YES; - } else { - /* Assume network/netmask with a name of a host. */ - struct addrinfo *res; - struct addrinfo hint; - - memset (&hint, '\0', sizeof (hint)); - hint.ai_flags = AI_CANONNAME; - hint.ai_family = AF_UNSPEC; - - if (getaddrinfo (string, NULL, &hint, &res) != 0) - return NO; - else - { - struct addrinfo *runp = res; - - while (runp != NULL) - { - char buf[INET6_ADDRSTRLEN]; - - inet_ntop (runp->ai_family, - runp->ai_family == AF_INET - ? (void *) &((struct sockaddr_in *) runp->ai_addr)->sin_addr - : (void *) &((struct sockaddr_in6 *) runp->ai_addr)->sin6_addr, - buf, sizeof (buf)); - - if (network_netmask_match(pamh, tok, buf, item->debug)) - { - freeaddrinfo (res); - return YES; - } - runp = runp->ai_next; - } - freeaddrinfo (res); - } - } - - return NO; -} - -/* string_match - match a string against one token */ - -static int -string_match (pam_handle_t *pamh, const char *tok, const char *string, - int debug) -{ - - if (debug) - pam_syslog (pamh, LOG_DEBUG, - "string_match: tok=%s, item=%s", tok, string); - - /* - * If the token has the magic value "ALL" the match always succeeds. - * Otherwise, return YES if the token fully matches the string. - * "NONE" token matches NULL string. - */ - - if (strcasecmp(tok, "ALL") == 0) { /* all: always matches */ - return (ALL); - } else if (string != NULL) { - if (strcasecmp(tok, string) == 0) { /* try exact match */ - return (YES); - } - } else if (strcasecmp(tok, "NONE") == 0) { - return (YES); - } - return (NO); -} - - -/* network_netmask_match - match a string against one token - * where string is an ip (v4,v6) address and tok represents - * whether a single ip (v4,v6) address or a network/netmask - */ -static int -network_netmask_match (pam_handle_t *pamh, - const char *tok, const char *string, int debug) -{ - if (debug) - pam_syslog (pamh, LOG_DEBUG, - "network_netmask_match: tok=%s, item=%s", tok, string); - - if (isipaddr(string, NULL, NULL) == YES) - { - char *netmask_ptr = NULL; - static char netmask_string[MAXHOSTNAMELEN + 1] = ""; - int addr_type; - - /* OK, check if tok is of type addr/mask */ - if ((netmask_ptr = strchr(tok, '/')) != NULL) - { - long netmask = 0; - - /* YES */ - *netmask_ptr = 0; - netmask_ptr++; - - if (isipaddr(tok, &addr_type, NULL) == NO) - { /* no netaddr */ - return(NO); - } - - /* check netmask */ - if (isipaddr(netmask_ptr, NULL, NULL) == NO) - { /* netmask as integre value */ - char *endptr = NULL; - netmask = strtol(netmask_ptr, &endptr, 0); - if ((endptr == NULL) || (*endptr != '\0')) - { /* invalid netmask value */ - return(NO); - } - if ((netmask < 0) || (netmask >= 128)) - { /* netmask value out of range */ - return(NO); - } - - netmask_ptr = number_to_netmask(netmask, addr_type, - netmask_string, MAXHOSTNAMELEN); - } - - /* Netmask is now an ipv4/ipv6 address. - * This works also if netmask_ptr is NULL. - */ - return (are_addresses_equal(string, tok, netmask_ptr)); - } - else - /* NO, then check if it is only an addr */ - if (isipaddr(tok, NULL, NULL) == YES) - { /* check if they are the same, no netmask */ - return(are_addresses_equal(string, tok, NULL)); - } - } - - return (NO); -} - - -/* --- public PAM management functions --- */ - -PAM_EXTERN int -pam_sm_authenticate (pam_handle_t *pamh, int flags UNUSED, - int argc, const char **argv) -{ - struct login_info loginfo; - const char *user=NULL; - const void *void_from=NULL; - const char *from; - struct passwd *user_pw; - - /* set username */ - - 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 ((user_pw=pam_modutil_getpwnam(pamh, user))==NULL) - return (PAM_USER_UNKNOWN); - - /* - * Bundle up the arguments to avoid unnecessary clumsiness later on. - */ - loginfo.user = user_pw; - loginfo.config_file = PAM_ACCESS_CONFIG; - - /* parse the argument list */ - - if (!parse_args(pamh, &loginfo, argc, argv)) { - pam_syslog(pamh, LOG_ERR, "failed to parse the module arguments"); - return PAM_ABORT; - } - - /* remote host name */ - - if (pam_get_item(pamh, PAM_RHOST, &void_from) - != PAM_SUCCESS) { - pam_syslog(pamh, LOG_ERR, "cannot find the remote host name"); - return PAM_ABORT; - } - from = void_from; - - if ((from==NULL) || (*from=='\0')) { - - /* local login, set tty name */ - - if (pam_get_item(pamh, PAM_TTY, &void_from) != PAM_SUCCESS - || void_from == NULL) { - D(("PAM_TTY not set, probing stdin")); - from = ttyname(STDIN_FILENO); - if (from != NULL) { - if (pam_set_item(pamh, PAM_TTY, from) != PAM_SUCCESS) - pam_syslog(pamh, LOG_WARNING, "couldn't set tty name"); - } else { - if (pam_get_item(pamh, PAM_SERVICE, &void_from) != PAM_SUCCESS - || void_from == NULL) { - pam_syslog (pamh, LOG_ERR, - "cannot determine remote host, tty or service name"); - return PAM_ABORT; - } - from = void_from; - if (loginfo.debug) - pam_syslog (pamh, LOG_DEBUG, - "cannot determine tty or remote hostname, using service %s", - from); - } - } - else - from = void_from; - - if (from[0] == '/') { /* full path, remove device path. */ - const char *f; - from++; - if ((f = strchr(from, '/')) != NULL) { - from = f + 1; - } - } - } - - loginfo.from = from; - - if (login_access(pamh, &loginfo)) { - return (PAM_SUCCESS); - } else { - pam_syslog(pamh, LOG_ERR, - "access denied for user `%s' from `%s'",user,from); - return (PAM_PERM_DENIED); - } -} - -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); -} - -PAM_EXTERN int -pam_sm_open_session(pam_handle_t *pamh, int flags, - int argc, const char **argv) -{ - return pam_sm_authenticate(pamh, flags, argc, argv); -} - -PAM_EXTERN int -pam_sm_close_session(pam_handle_t *pamh, int flags, - int argc, const char **argv) -{ - return pam_sm_authenticate(pamh, flags, argc, argv); -} - -PAM_EXTERN int -pam_sm_chauthtok(pam_handle_t *pamh, int flags, - int argc, const char **argv) -{ - return pam_sm_authenticate(pamh, flags, argc, argv); -} - -/* end of module definition */ - -#ifdef PAM_STATIC - -/* static module data */ - -struct pam_module _pam_access_modstruct = { - "pam_access", - pam_sm_authenticate, - pam_sm_setcred, - pam_sm_acct_mgmt, - pam_sm_open_session, - pam_sm_close_session, - pam_sm_chauthtok -}; -#endif diff --git a/modules/pam_access/tst-pam_access b/modules/pam_access/tst-pam_access deleted file mode 100755 index 271e69fe..00000000 --- a/modules/pam_access/tst-pam_access +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/sh -../../tests/tst-dlopen .libs/pam_access.so diff --git a/modules/pam_cracklib/.cvsignore b/modules/pam_cracklib/.cvsignore deleted file mode 100644 index db3b3295..00000000 --- a/modules/pam_cracklib/.cvsignore +++ /dev/null @@ -1,8 +0,0 @@ -*.la -*.lo -.deps -.libs -Makefile -Makefile.in -README -pam_cracklib.8 diff --git a/modules/pam_cracklib/Makefile.am b/modules/pam_cracklib/Makefile.am deleted file mode 100644 index 619ffc93..00000000 --- a/modules/pam_cracklib/Makefile.am +++ /dev/null @@ -1,38 +0,0 @@ -# -# Copyright (c) 2005, 2006 Thorsten Kukuk <kukuk@suse.de> -# - -CLEANFILES = *~ - -EXTRA_DIST = README $(MANS) $(XMLS) tst-pam_cracklib - -man_MANS = pam_cracklib.8 - -XMLS = README.xml pam_cracklib.8.xml - -securelibdir = $(SECUREDIR) -secureconfdir = $(SCONFIGDIR) - -AM_CFLAGS = -I$(top_srcdir)/libpam/include -I$(top_srcdir)/libpamc/include -AM_LDFLAGS = -no-undefined -avoid-version -module -if HAVE_VERSIONING - AM_LDFLAGS += -Wl,--version-script=$(srcdir)/../modules.map -endif - -if HAVE_LIBCRACK -securelib_LTLIBRARIES = pam_cracklib.la - -TESTS = tst-pam_cracklib -endif - -pam_cracklib_la_LIBADD = -L$(top_builddir)/libpam -lpam \ - @LIBCRACK@ @LIBCRYPT@ - -if ENABLE_REGENERATE_MAN - -noinst_DATA = README - -README: pam_cracklib.8.xml - --include $(top_srcdir)/Make.xml.rules -endif diff --git a/modules/pam_cracklib/README.xml b/modules/pam_cracklib/README.xml deleted file mode 100644 index c4a7b54c..00000000 --- a/modules/pam_cracklib/README.xml +++ /dev/null @@ -1,41 +0,0 @@ -<?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_cracklib.8.xml"> ---> -]> - -<article> - - <articleinfo> - - <title> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" - href="pam_cracklib.8.xml" xpointer='xpointer(//refnamediv[@id = "pam_cracklib-name"]/*)'/> - </title> - - </articleinfo> - - <section> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" - href="pam_cracklib.8.xml" xpointer='xpointer(//refsect1[@id = "pam_cracklib-description"]/*)'/> - </section> - - <section> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" - href="pam_cracklib.8.xml" xpointer='xpointer(//refsect1[@id = "pam_cracklib-options"]/*)'/> - </section> - - <section> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" - href="pam_cracklib.8.xml" xpointer='xpointer(//refsect1[@id = "pam_cracklib-examples"]/*)'/> - </section> - - <section> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" - href="pam_cracklib.8.xml" xpointer='xpointer(//refsect1[@id = "pam_cracklib-author"]/*)'/> - </section> - -</article> diff --git a/modules/pam_cracklib/pam_cracklib.8.xml b/modules/pam_cracklib/pam_cracklib.8.xml deleted file mode 100644 index 589e7b44..00000000 --- a/modules/pam_cracklib/pam_cracklib.8.xml +++ /dev/null @@ -1,513 +0,0 @@ -<?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_cracklib"> - - <refmeta> - <refentrytitle>pam_cracklib</refentrytitle> - <manvolnum>8</manvolnum> - <refmiscinfo class="sectdesc">Linux-PAM Manual</refmiscinfo> - </refmeta> - - <refnamediv id="pam_cracklib-name"> - <refname>pam_cracklib</refname> - <refpurpose>PAM module to check the password against dictionary words</refpurpose> - </refnamediv> - - <refsynopsisdiv> - <cmdsynopsis id="pam_cracklib-cmdsynopsis"> - <command>pam_cracklib.so</command> - <arg choice="opt"> - <replaceable>...</replaceable> - </arg> - </cmdsynopsis> - </refsynopsisdiv> - - <refsect1 id="pam_cracklib-description"> - - <title>DESCRIPTION</title> - - <para> - This module can be plugged into the <emphasis>password</emphasis> stack of - a given application to provide some plug-in strength-checking for passwords. - </para> - - <para> - The action of this module is to prompt the user for a password and - check its strength against a system dictionary and a set of rules for - identifying poor choices. - </para> - - <para> - The first action is to prompt for a single password, check its - strength and then, if it is considered strong, prompt for the password - a second time (to verify that it was typed correctly on the first - occasion). All being well, the password is passed on to subsequent - modules to be installed as the new authentication token. - </para> - - <para> - The strength checks works in the following manner: at first the - <function>Cracklib</function> routine is called to check if the password - is part of a dictionary; if this is not the case an additional set of - strength checks is done. These checks are: - </para> - - <variablelist> - <varlistentry> - <term>Palindrome</term> - <listitem> - <para> - Is the new password a palindrome of the old one? - </para> - </listitem> - </varlistentry> - <varlistentry> - <term>Case Change Only</term> - <listitem> - <para> - Is the new password the the old one with only a change of case? - </para> - </listitem> - </varlistentry> - <varlistentry> - <term>Similar</term> - <listitem> - <para> - Is the new password too much like the old one? - This is primarily controlled by one argument, - <option>difok</option> which is a number of characters - that if different between the old and new are enough to accept - the new password, this defaults to 10 or 1/2 the size of the - new password whichever is smaller. - </para> - <para> - To avoid the lockup associated with trying to change a long and - complicated password, <option>difignore</option> is available. - This argument can be used to specify the minimum length a new - password needs to be before the <option>difok</option> value is - ignored. The default value for <option>difignore</option> is 23. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term>Simple</term> - <listitem> - <para> - Is the new password too small? - This is controlled by 5 arguments <option>minlen</option>, - <option>dcredit</option>, <option>ucredit</option>, - <option>lcredit</option>, and <option>ocredit</option>. See the section - on the arguments for the details of how these work and there defaults. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term>Rotated</term> - <listitem> - <para> - Is the new password a rotated version of the old password? - </para> - </listitem> - </varlistentry> - <varlistentry> - <term>Already used</term> - <listitem> - <para> - Was the password used in the past? Previously used passwords - are to be found in <filename>/etc/security/opasswd</filename>. - </para> - </listitem> - </varlistentry> - </variablelist> - <para> - This module with no arguments will work well for standard unix - password encryption. With md5 encryption, passwords can be longer - than 8 characters and the default settings for this module can make it - hard for the user to choose a satisfactory new password. Notably, the - requirement that the new password contain no more than 1/2 of the - characters in the old password becomes a non-trivial constraint. For - example, an old password of the form "the quick brown fox jumped over - the lazy dogs" would be difficult to change... In addition, the - default action is to allow passwords as small as 5 characters in - length. For a md5 systems it can be a good idea to increase the - required minimum size of a password. One can then allow more credit - for different kinds of characters but accept that the new password may - share most of these characters with the old password. - </para> - - </refsect1> - - <refsect1 id="pam_cracklib-options"> - - <title>OPTIONS</title> - <para> - <variablelist> - - <varlistentry> - <term> - <option>debug</option> - </term> - <listitem> - <para> - This option makes the module write information to - <citerefentry> - <refentrytitle>syslog</refentrytitle><manvolnum>3</manvolnum> - </citerefentry> - indicating the behavior of the module (this option does - not write password information to the log file). - </para> - </listitem> - </varlistentry> - - <varlistentry> - <term> - <option>type=<replaceable>XXX</replaceable></option> - </term> - <listitem> - <para> - The default action is for the module to use the - following prompts when requesting passwords: - "New UNIX password: " and "Retype UNIX password: ". - The default word <emphasis>UNIX</emphasis> can - be replaced with this option. - </para> - </listitem> - </varlistentry> - - <varlistentry> - <term> - <option>retry=<replaceable>N</replaceable></option> - </term> - <listitem> - <para> - Prompt user at most <replaceable>N</replaceable> times - before returning with error. The default is - <emphasis>1</emphasis> - </para> - </listitem> - </varlistentry> - - <varlistentry> - <term> - <option>difok=<replaceable>N</replaceable></option> - </term> - <listitem> - <para> - This argument will change the default of - <emphasis>5</emphasis> for the number of characters in - the new password that must not be present in the old - password. In addition, if 1/2 of the characters in the - new password are different then the new password will - be accepted anyway. - </para> - </listitem> - </varlistentry> - - <varlistentry> - <term> - <option>difignore=<replaceable>N</replaceable></option> - </term> - <listitem> - <para> - How many characters should the password have before - difok will be ignored. The default is - <emphasis>23</emphasis>. - </para> - </listitem> - </varlistentry> - - <varlistentry> - <term> - <option>minlen=<replaceable>N</replaceable></option> - </term> - <listitem> - <para> - The minimum acceptable size for the new password (plus - one if credits are not disabled which is the default). - In addition to the number of characters in the new password, - credit (of +1 in length) is given for each different kind - of character (<emphasis>other</emphasis>, - <emphasis>upper</emphasis>, <emphasis>lower</emphasis> and - <emphasis>digit</emphasis>). The default for this parameter - is <emphasis>9</emphasis> which is good for a old style UNIX - password all of the same type of character but may be too low - to exploit the added security of a md5 system. Note that - there is a pair of length limits in - <emphasis>Cracklib</emphasis> itself, a "way too short" limit - of 4 which is hard coded in and a defined limit (6) that will - be checked without reference to <option>minlen</option>. - If you want to allow passwords as short as 5 characters you - should not use this module. - </para> - </listitem> - </varlistentry> - - <varlistentry> - <term> - <option>dcredit=<replaceable>N</replaceable></option> - </term> - <listitem> - <para> - (N >= 0) This is the maximum credit for having digits in - the new password. If you have less than or - <replaceable>N</replaceable> - digits, each digit will count +1 towards meeting the current - <option>minlen</option> value. The default for - <option>dcredit</option> is 1 which is the recommended - value for <option>minlen</option> less than 10. - </para> - <para> - (N < 0) This is the minimum number of digits that must - be met for a new password. - </para> - </listitem> - </varlistentry> - - <varlistentry> - <term> - <option>ucredit=<replaceable>N</replaceable></option> - </term> - <listitem> - <para> - (N >= 0) This is the maximum credit for having upper - case letters in the new password. If you have less than - or <replaceable>N</replaceable> upper case letters each - letter will count +1 towards meeting the current - <option>minlen</option> value. The default for - <option>ucredit</option> is <emphasis>1</emphasis> which - is the recommended value for <option>minlen</option> less - than 10. - </para> - <para> - (N > 0) This is the minimum number of upper - case letters that must be met for a new password. - </para> - </listitem> - </varlistentry> - - <varlistentry> - <term> - <option>lcredit=<replaceable>N</replaceable></option> - </term> - <listitem> - <para> - (N >= 0) This is the maximum credit for having - lower case letters in the new password. If you have - less than or <replaceable>N</replaceable> lower case - letters, each letter will count +1 towards meeting the - current <option>minlen</option> value. The default for - <option>lcredit</option> is 1 which is the recommended - value for <option>minlen</option> less than 10. - </para> - <para> - (N < 0) This is the minimum number of lower - case letters that must be met for a new password. - </para> - </listitem> - </varlistentry> - - <varlistentry> - <term> - <option>ocredit=<replaceable>N</replaceable></option> - </term> - <listitem> - <para> - (N >= 0) This is the maximum credit for having other - characters in the new password. If you have less than or - <replaceable>N</replaceable> other characters, each - character will count +1 towards meeting the current - <option>minlen</option> value. The default for - <option>ocredit</option> is 1 which is the recommended - value for <option>minlen</option> less than 10. - </para> - <para> - (N < 0) This is the minimum number of other - characters that must be met for a new password. - </para> - </listitem> - </varlistentry> - - <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>use_authtok</option> - </term> - <listitem> - <para> - This argument is used to <emphasis>force</emphasis> the - module to not prompt the user for a new password but use - the one provided by the previously stacked - <emphasis>password</emphasis> module. - </para> - </listitem> - </varlistentry> - - <varlistentry> - <term> - <option>dictpath=<replaceable>/path/to/dict</replaceable></option> - </term> - <listitem> - <para> - Path to the cracklib dictionaries. - </para> - </listitem> - </varlistentry> - - </variablelist> - </para> - </refsect1> - - <refsect1 id="pam_cracklib-services"> - <title>MODULE SERVICES PROVIDED</title> - <para> - Only he <option>password</option> service is supported. - </para> - </refsect1> - - <refsect1 id='pam_cracklib-return_values'> - <title>RETURN VALUES</title> - <para> - <variablelist> - - <varlistentry> - <term>PAM_SUCCESS</term> - <listitem> - <para> - The new password passes all checks. - </para> - </listitem> - </varlistentry> - - <varlistentry> - <term>PAM_AUTHTOK_ERR</term> - <listitem> - <para> - No new password was entered, - the username could not be determined or the new - password fails the strength checks. - </para> - </listitem> - </varlistentry> - - <varlistentry> - <term>PAM_AUTHTOK_RECOVERY_ERR</term> - <listitem> - <para> - The old password was not supplied by a previous stacked - module or got not requested from the user. - The first error can happen if <option>use_authtok</option> - is specified. - </para> - </listitem> - </varlistentry> - - <varlistentry> - <term>PAM_SERVICE_ERR</term> - <listitem> - <para> - A internal error occured. - </para> - </listitem> - </varlistentry> - - </variablelist> - </para> - </refsect1> - - <refsect1 id='pam_cracklib-examples'> - <title>EXAMPLES</title> - <para> - For an example of the use of this module, we show how it may be - stacked with the password component of - <citerefentry> - <refentrytitle>pam_unix</refentrytitle><manvolnum>8</manvolnum> - </citerefentry> - <programlisting> -# -# These lines stack two password type modules. In this example the -# user is given 3 opportunities to enter a strong password. The -# "use_authtok" argument ensures that the pam_unix module does not -# prompt for a password, but instead uses the one provided by -# pam_cracklib. -# -passwd password required pam_cracklib.so retry=3 -passwd password required pam_unix.so use_authtok - </programlisting> - </para> - - <para> - Another example (in the <filename>/etc/pam.d/passwd</filename> format) - is for the case that you want to use md5 password encryption: - <programlisting> -#%PAM-1.0 -# -# These lines allow a md5 systems to support passwords of at least 14 -# bytes with extra credit of 2 for digits and 2 for others the new -# password must have at least three bytes that are not present in the -# old password -# -password required pam_cracklib.so \ - difok=3 minlen=15 dcredit= 2 ocredit=2 -password required pam_unix.so use_authtok nullok md5 - </programlisting> - </para> - - <para> - And here is another example in case you don't want to use credits: - <programlisting> -#%PAM-1.0 -# -# These lines require the user to select a password with a minimum -# length of 8 and with at least 1 digit number, 1 upper case letter, -# and 1 other character -# -password required pam_cracklib.so \ - dcredit=-1 ucredit=-1 ocredit=-1 lcredit=0 minlen=8 -password required pam_unix.so use_authtok nullok md5 - </programlisting> - </para> - - </refsect1> - - <refsect1 id='pam_cracklib-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_cracklib-author'> - <title>AUTHOR</title> - <para> - pam_cracklib was written by Cristian Gafton <gafton@redhat.com> - </para> - </refsect1> - -</refentry> diff --git a/modules/pam_cracklib/pam_cracklib.c b/modules/pam_cracklib/pam_cracklib.c deleted file mode 100644 index 532a72b2..00000000 --- a/modules/pam_cracklib/pam_cracklib.c +++ /dev/null @@ -1,850 +0,0 @@ -/* - * pam_cracklib module - */ - -/* - * 0.9. switch to using a distance algorithm in similar() - * 0.86. added support for setting minimum numbers of digits, uppers, - * lowers, and others - * 0.85. added six new options to use this with long passwords. - * 0.8. tidied output and improved D(()) usage for debugging. - * 0.7. added support for more obscure checks for new passwd. - * 0.6. root can reset user passwd to any values (it's only warned) - * 0.5. supports retries - 'retry=N' argument - * 0.4. added argument 'type=XXX' for 'New XXX password' prompt - * 0.3. Added argument 'debug' - * 0.2. new password is feeded to cracklib for verify after typed once - * 0.1. First release - */ - -/* - * Written by Cristian Gafton <gafton@redhat.com> 1996/09/10 - * Long password support by Philip W. Dalrymple <pwd@mdtsoft.com> 1997/07/18 - * See the end of the file for Copyright Information - * - * Modification for long password systems (>8 chars). The original - * module had problems when used in a md5 password system in that it - * allowed too short passwords but required that at least half of the - * bytes in the new password did not appear in the old one. this - * action is still the default and the changes should not break any - * current user. This modification adds 6 new options, one to set the - * number of bytes in the new password that are not in the old one, - * the other five to control the length checking, these are all - * documented (or will be before anyone else sees this code) in the PAM - * S.A.G. in the section on the cracklib module. - */ - -#include "config.h" - -#include <stdio.h> -#ifdef HAVE_CRYPT_H -# include <crypt.h> -#endif -#include <unistd.h> -#include <stdlib.h> -#include <string.h> -#include <syslog.h> -#include <stdarg.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <ctype.h> -#include <limits.h> - -#ifdef HAVE_CRACK_H -#include <crack.h> -#else -extern char *FascistCheck(char *pw, const char *dictpath); -#endif - -#ifndef CRACKLIB_DICTS -#define CRACKLIB_DICTS NULL -#endif - -/* For Translators: "%s%s" could be replaced with "<service> " or "". */ -#define PROMPT1 _("New %s%spassword: ") -/* For Translators: "%s%s" could be replaced with "<service> " or "". */ -#define PROMPT2 _("Retype new %s%spassword: ") -#define MISTYPED_PASS _("Sorry, passwords do not match.") - -#ifdef MIN -#undef MIN -#endif -#define MIN(_a, _b) (((_a) < (_b)) ? (_a) : (_b)) - -/* - * here, we make a definition for the externally accessible function - * in this file (this definition is required for static a module - * but strongly encouraged generally) it is used to instruct the - * modules include file to define the function prototypes. - */ - -#define PAM_SM_PASSWORD - -#include <security/pam_modules.h> -#include <security/_pam_macros.h> -#include <security/pam_ext.h> - -/* argument parsing */ -#define PAM_DEBUG_ARG 0x0001 - -struct cracklib_options { - int retry_times; - int diff_ok; - int diff_ignore; - int min_length; - int dig_credit; - int up_credit; - int low_credit; - int oth_credit; - int min_class; - int use_authtok; - char prompt_type[BUFSIZ]; - const char *cracklib_dictpath; -}; - -#define CO_RETRY_TIMES 1 -#define CO_DIFF_OK 5 -#define CO_DIFF_IGNORE 23 -#define CO_MIN_LENGTH 9 -# define CO_MIN_LENGTH_BASE 5 -#define CO_DIG_CREDIT 1 -#define CO_UP_CREDIT 1 -#define CO_LOW_CREDIT 1 -#define CO_OTH_CREDIT 1 -#define CO_USE_AUTHTOK 0 - -static int -_pam_parse (pam_handle_t *pamh, struct cracklib_options *opt, - int argc, const char **argv) -{ - int ctrl=0; - - /* step through arguments */ - for (ctrl=0; argc-- > 0; ++argv) { - char *ep = NULL; - - /* generic options */ - - if (!strcmp(*argv,"debug")) - ctrl |= PAM_DEBUG_ARG; - else if (!strncmp(*argv,"type=",5)) - strncpy(opt->prompt_type, *argv+5, sizeof(opt->prompt_type) - 1); - else if (!strncmp(*argv,"retry=",6)) { - opt->retry_times = strtol(*argv+6,&ep,10); - if (!ep || (opt->retry_times < 1)) - opt->retry_times = CO_RETRY_TIMES; - } else if (!strncmp(*argv,"difok=",6)) { - opt->diff_ok = strtol(*argv+6,&ep,10); - if (!ep || (opt->diff_ok < 0)) - opt->diff_ok = CO_DIFF_OK; - } else if (!strncmp(*argv,"difignore=",10)) { - opt->diff_ignore = strtol(*argv+10,&ep,10); - if (!ep || (opt->diff_ignore < 0)) - opt->diff_ignore = CO_DIFF_IGNORE; - } else if (!strncmp(*argv,"minlen=",7)) { - opt->min_length = strtol(*argv+7,&ep,10); - if (!ep || (opt->min_length < CO_MIN_LENGTH_BASE)) - opt->min_length = CO_MIN_LENGTH_BASE; - } else if (!strncmp(*argv,"dcredit=",8)) { - opt->dig_credit = strtol(*argv+8,&ep,10); - if (!ep) - opt->dig_credit = 0; - } else if (!strncmp(*argv,"ucredit=",8)) { - opt->up_credit = strtol(*argv+8,&ep,10); - if (!ep) - opt->up_credit = 0; - } else if (!strncmp(*argv,"lcredit=",8)) { - opt->low_credit = strtol(*argv+8,&ep,10); - if (!ep) - opt->low_credit = 0; - } else if (!strncmp(*argv,"ocredit=",8)) { - opt->oth_credit = strtol(*argv+8,&ep,10); - if (!ep) - opt->oth_credit = 0; - } else if (!strncmp(*argv,"minclass=",9)) { - opt->min_class = strtol(*argv+9,&ep,10); - if (!ep) - opt->min_class = 0; - if (opt->min_class > 4) - opt->min_class = 4 ; - } else if (!strncmp(*argv,"use_authtok",11)) { - opt->use_authtok = 1; - } else if (!strncmp(*argv,"dictpath=",9)) { - opt->cracklib_dictpath = *argv+9; - if (!*(opt->cracklib_dictpath)) { - opt->cracklib_dictpath = CRACKLIB_DICTS; - } - } else { - pam_syslog(pamh,LOG_ERR,"pam_parse: unknown option; %s",*argv); - } - } - opt->prompt_type[sizeof(opt->prompt_type) - 1] = '\0'; - - return ctrl; -} - -/* Helper functions */ - -/* use this to free strings. ESPECIALLY password strings */ -static char *_pam_delete(register char *xx) -{ - _pam_overwrite(xx); - free(xx); - return NULL; -} - -/* - * can't be a palindrome - like `R A D A R' or `M A D A M' - */ -static int palindrome(const char *new) -{ - int i, j; - - i = strlen (new); - - for (j = 0;j < i;j++) - if (new[i - j - 1] != new[j]) - return 0; - - return 1; -} - -/* - * Calculate how different two strings are in terms of the number of - * character removals, additions, and changes needed to go from one to - * the other - */ - -static int distdifferent(const char *old, const char *new, - size_t i, size_t j) -{ - char c, d; - - if ((i == 0) || (strlen(old) < i)) { - c = 0; - } else { - c = old[i - 1]; - } - if ((j == 0) || (strlen(new) < j)) { - d = 0; - } else { - d = new[j - 1]; - } - return (c != d); -} - -static int distcalculate(int **distances, const char *old, const char *new, - size_t i, size_t j) -{ - int tmp = 0; - - if (distances[i][j] != -1) { - return distances[i][j]; - } - - tmp = distcalculate(distances, old, new, i - 1, j - 1); - tmp = MIN(tmp, distcalculate(distances, old, new, i, j - 1)); - tmp = MIN(tmp, distcalculate(distances, old, new, i - 1, j)); - tmp += distdifferent(old, new, i, j); - - distances[i][j] = tmp; - - return tmp; -} - -static int distance(const char *old, const char *new) -{ - int **distances = NULL; - size_t m, n, i, j, r; - - m = strlen(old); - n = strlen(new); - distances = malloc(sizeof(int*) * (m + 1)); - - for (i = 0; i <= m; i++) { - distances[i] = malloc(sizeof(int) * (n + 1)); - for(j = 0; j <= n; j++) { - distances[i][j] = -1; - } - } - for (i = 0; i <= m; i++) { - distances[i][0] = i; - } - for (j = 0; j <= n; j++) { - distances[0][j] = j; - } - distances[0][0] = 0; - - r = distcalculate(distances, old, new, m, n); - - for (i = 0; i <= m; i++) { - memset(distances[i], 0, sizeof(int) * (n + 1)); - free(distances[i]); - } - free(distances); - - return r; -} - -static int similar(struct cracklib_options *opt, - const char *old, const char *new) -{ - if (distance(old, new) >= opt->diff_ok) { - return 0; - } - - if (strlen(new) >= (strlen(old) * 2)) { - return 0; - } - - /* passwords are too similar */ - return 1; -} - -/* - * enough classes of charecters - */ - -static int minclass (struct cracklib_options *opt, - const char *new) -{ - int digits = 0; - int uppers = 0; - int lowers = 0; - int others = 0; - int total_class; - int i; - int retval; - - D(( "called" )); - for (i = 0; new[i]; i++) - { - if (isdigit (new[i])) - digits = 1; - else if (isupper (new[i])) - uppers = 1; - else if (islower (new[i])) - lowers = 1; - else - others = 1; - } - - total_class = digits + uppers + lowers + others; - - D (("total class: %d\tmin_class: %d", total_class, opt->min_class)); - - if (total_class >= opt->min_class) - retval = 0; - else - retval = 1; - - return retval; -} - - -/* - * a nice mix of characters. - */ -static int simple(struct cracklib_options *opt, const char *new) -{ - int digits = 0; - int uppers = 0; - int lowers = 0; - int others = 0; - int size; - int i; - - for (i = 0;new[i];i++) { - if (isdigit (new[i])) - digits++; - else if (isupper (new[i])) - uppers++; - else if (islower (new[i])) - lowers++; - else - others++; - } - - /* - * The scam was this - a password of only one character type - * must be 8 letters long. Two types, 7, and so on. - * This is now changed, the base size and the credits or defaults - * see the docs on the module for info on these parameters, the - * defaults cause the effect to be the same as before the change - */ - - if ((opt->dig_credit >= 0) && (digits > opt->dig_credit)) - digits = opt->dig_credit; - - if ((opt->up_credit >= 0) && (uppers > opt->up_credit)) - uppers = opt->up_credit; - - if ((opt->low_credit >= 0) && (lowers > opt->low_credit)) - lowers = opt->low_credit; - - if ((opt->oth_credit >= 0) && (others > opt->oth_credit)) - others = opt->oth_credit; - - size = opt->min_length; - - if (opt->dig_credit >= 0) - size -= digits; - else if (digits < opt->dig_credit * -1) - return 1; - - if (opt->up_credit >= 0) - size -= uppers; - else if (uppers < opt->up_credit * -1) - return 1; - - if (opt->low_credit >= 0) - size -= lowers; - else if (lowers < opt->low_credit * -1) - return 1; - - if (opt->oth_credit >= 0) - size -= others; - else if (others < opt->oth_credit * -1) - return 1; - - if (size <= i) - return 0; - - return 1; -} - -static char * str_lower(char *string) -{ - char *cp; - - for (cp = string; *cp; cp++) - *cp = tolower(*cp); - return string; -} - -static const char *password_check(struct cracklib_options *opt, - const char *old, const char *new) -{ - const char *msg = NULL; - char *oldmono = NULL, *newmono, *wrapped = NULL; - - if (old && strcmp(new, old) == 0) { - msg = _("is the same as the old one"); - return msg; - } - - newmono = str_lower(x_strdup(new)); - if (old) { - oldmono = str_lower(x_strdup(old)); - wrapped = malloc(strlen(oldmono) * 2 + 1); - strcpy (wrapped, oldmono); - strcat (wrapped, oldmono); - } - - if (palindrome(newmono)) - msg = _("is a palindrome"); - - if (!msg && oldmono && strcmp(oldmono, newmono) == 0) - msg = _("case changes only"); - - if (!msg && oldmono && similar(opt, oldmono, newmono)) - msg = _("is too similar to the old one"); - - if (!msg && simple(opt, new)) - msg = _("is too simple"); - - if (!msg && wrapped && strstr(wrapped, newmono)) - msg = _("is rotated"); - - if (!msg && minclass (opt, new)) - msg = _("not enough character classes"); - - memset(newmono, 0, strlen(newmono)); - free(newmono); - if (old) { - memset(oldmono, 0, strlen(oldmono)); - memset(wrapped, 0, strlen(wrapped)); - free(oldmono); - free(wrapped); - } - - return msg; -} - - -#define OLD_PASSWORDS_FILE "/etc/security/opasswd" - -static const char * check_old_password(const char *forwho, const char *newpass) -{ - static char buf[16384]; - char *s_luser, *s_uid, *s_npas, *s_pas; - const char *msg = NULL; - FILE *opwfile; - - opwfile = fopen(OLD_PASSWORDS_FILE, "r"); - if (opwfile == NULL) - return NULL; - - while (fgets(buf, 16380, opwfile)) { - if (!strncmp(buf, forwho, strlen(forwho))) { - char *sptr; - buf[strlen(buf)-1] = '\0'; - s_luser = strtok_r(buf, ":,", &sptr); - s_uid = strtok_r(NULL, ":,", &sptr); - s_npas = strtok_r(NULL, ":,", &sptr); - s_pas = strtok_r(NULL, ":,", &sptr); - while (s_pas != NULL) { - if (!strcmp(crypt(newpass, s_pas), s_pas)) { - msg = _("has been already used"); - break; - } - s_pas = strtok_r(NULL, ":,", &sptr); - } - break; - } - } - fclose(opwfile); - - return msg; -} - - -static int _pam_unix_approve_pass(pam_handle_t *pamh, - unsigned int ctrl, - struct cracklib_options *opt, - const char *pass_old, - const char *pass_new) -{ - const char *msg = NULL; - const void *user; - int retval; - - if (pass_new == NULL || (pass_old && !strcmp(pass_old,pass_new))) { - if (ctrl & PAM_DEBUG_ARG) - pam_syslog(pamh, LOG_DEBUG, "bad authentication token"); - pam_error(pamh, "%s", pass_new == NULL ? - _("No password supplied"):_("Password unchanged")); - 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); - 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); - } - - if (msg) { - if (ctrl & PAM_DEBUG_ARG) - pam_syslog(pamh, LOG_NOTICE, - "new passwd fails strength check: %s", msg); - pam_error(pamh, _("BAD PASSWORD: %s"), msg); - return PAM_AUTHTOK_ERR; - }; - return PAM_SUCCESS; - -} - -/* The Main Thing (by Cristian Gafton, CEO at this module :-) - * (stolen from http://home.netscape.com) - */ -PAM_EXTERN int pam_sm_chauthtok(pam_handle_t *pamh, int flags, - int argc, const char **argv) -{ - unsigned int ctrl; - struct cracklib_options options; - - D(("called.")); - - memset(&options, 0, sizeof(options)); - options.retry_times = CO_RETRY_TIMES; - options.diff_ok = CO_DIFF_OK; - options.diff_ignore = CO_DIFF_IGNORE; - options.min_length = CO_MIN_LENGTH; - options.dig_credit = CO_DIG_CREDIT; - options.up_credit = CO_UP_CREDIT; - options.low_credit = CO_LOW_CREDIT; - options.oth_credit = CO_OTH_CREDIT; - options.use_authtok = CO_USE_AUTHTOK; - memset(options.prompt_type, 0, BUFSIZ); - strcpy(options.prompt_type,"UNIX"); - options.cracklib_dictpath = CRACKLIB_DICTS; - - ctrl = _pam_parse(pamh, &options, argc, argv); - - if (flags & PAM_PRELIM_CHECK) { - /* Check for passwd dictionary */ - /* We cannot do that, since the original path is compiled - into the cracklib library and we don't know it. */ - return PAM_SUCCESS; - } else if (flags & PAM_UPDATE_AUTHTOK) { - int retval; - char *token1, *token2, *resp; - const void *oldtoken; - - D(("do update")); - retval = pam_get_item(pamh, PAM_OLDAUTHTOK, &oldtoken); - if (retval != PAM_SUCCESS) { - if (ctrl & PAM_DEBUG_ARG) - pam_syslog(pamh,LOG_ERR,"Can not get old passwd"); - oldtoken=NULL; - retval = PAM_SUCCESS; - } - - do { - /* - * make sure nothing inappropriate gets returned - */ - token1 = token2 = NULL; - - if (!options.retry_times) { - D(("returning %s because maxtries reached", - pam_strerror(pamh, retval))); - return retval; - } - - /* Planned modus operandi: - * Get a passwd. - * Verify it against cracklib. - * If okay get it a second time. - * Check to be the same with the first one. - * set PAM_AUTHTOK and return - */ - - if (options.use_authtok == 1) { - const void *item = NULL; - - retval = pam_get_item(pamh, PAM_AUTHTOK, &item); - if (retval != PAM_SUCCESS) { - /* very strange. */ - pam_syslog(pamh, LOG_ALERT, - "pam_get_item returned error to pam_cracklib"); - } else if (item != NULL) { /* we have a password! */ - token1 = x_strdup(item); - item = NULL; - } else { - retval = PAM_AUTHTOK_RECOVERY_ERR; /* didn't work */ - } - - } else { - /* Prepare to ask the user for the first time */ - resp = NULL; - retval = pam_prompt (pamh, PAM_PROMPT_ECHO_OFF, &resp, - PROMPT1, options.prompt_type, - options.prompt_type[0]?" ":""); - - if (retval == PAM_SUCCESS) { /* a good conversation */ - token1 = x_strdup(resp); - if (token1 == NULL) { - pam_syslog(pamh, LOG_NOTICE, - "could not recover authentication token 1"); - retval = PAM_AUTHTOK_RECOVERY_ERR; - } - /* - * tidy up the conversation (resp_retcode) is ignored - */ - _pam_drop(resp); - } else { - retval = (retval == PAM_SUCCESS) ? - PAM_AUTHTOK_RECOVERY_ERR:retval ; - } - } - - if (retval != PAM_SUCCESS) { - if (ctrl & PAM_DEBUG_ARG) - pam_syslog(pamh,LOG_DEBUG,"unable to obtain a password"); - continue; - } - - D(("testing password, retval = %s", pam_strerror(pamh, retval))); - /* now test this passwd against cracklib */ - { - const char *crack_msg; - - D(("against cracklib")); - if ((crack_msg = FascistCheck(token1,options.cracklib_dictpath))) { - if (ctrl & PAM_DEBUG_ARG) - pam_syslog(pamh,LOG_DEBUG,"bad password: %s",crack_msg); - pam_error(pamh, _("BAD PASSWORD: %s"), crack_msg); - if (getuid() || (flags & PAM_CHANGE_EXPIRED_AUTHTOK)) - retval = PAM_AUTHTOK_ERR; - else - retval = PAM_SUCCESS; - } else { - /* check it for strength too... */ - D(("for strength")); - retval = _pam_unix_approve_pass (pamh, ctrl, &options, - oldtoken, token1); - if (retval != PAM_SUCCESS) { - if (getuid() || (flags & PAM_CHANGE_EXPIRED_AUTHTOK)) - retval = PAM_AUTHTOK_ERR; - else - retval = PAM_SUCCESS; - } - } - } - - D(("after testing: retval = %s", pam_strerror(pamh, retval))); - /* if cracklib/strength check said it is a bad passwd... */ - if ((retval != PAM_SUCCESS) && (retval != PAM_IGNORE)) { - int temp_unused; - - temp_unused = pam_set_item(pamh, PAM_AUTHTOK, NULL); - token1 = _pam_delete(token1); - continue; - } - - /* Now we have a good passwd. Ask for it once again */ - - if (options.use_authtok == 0) { - resp = NULL; - retval = pam_prompt (pamh, PAM_PROMPT_ECHO_OFF, &resp, - PROMPT2, options.prompt_type, - options.prompt_type[0]?" ":""); - if (retval == PAM_SUCCESS) { /* a good conversation */ - token2 = x_strdup(resp); - if (token2 == NULL) { - pam_syslog(pamh,LOG_NOTICE, - "could not recover authentication token 2"); - retval = PAM_AUTHTOK_RECOVERY_ERR; - } - /* - * tidy up the conversation (resp_retcode) is ignored - */ - _pam_drop(resp); - } - - /* No else, the a retval == PAM_SUCCESS path can change retval - to a failure code. */ - if (retval != PAM_SUCCESS) { - if (ctrl & PAM_DEBUG_ARG) - pam_syslog(pamh,LOG_DEBUG,"unable to obtain retyped password"); - continue; - } - - /* Hopefully now token1 and token2 the same password ... */ - if (strcmp(token1,token2) != 0) { - /* tell the user */ - pam_error(pamh, "%s", MISTYPED_PASS); - token1 = _pam_delete(token1); - token2 = _pam_delete(token2); - pam_set_item(pamh, PAM_AUTHTOK, NULL); - if (ctrl & PAM_DEBUG_ARG) - pam_syslog(pamh,LOG_NOTICE,"Password mistyped"); - retval = PAM_AUTHTOK_RECOVERY_ERR; - continue; - } - - /* Yes, the password was typed correct twice - * we store this password as an item - */ - - { - const void *item = NULL; - - retval = pam_set_item(pamh, PAM_AUTHTOK, token1); - - /* clean up */ - token1 = _pam_delete(token1); - token2 = _pam_delete(token2); - - if ( (retval != PAM_SUCCESS) || - ((retval = pam_get_item(pamh, PAM_AUTHTOK, &item) - ) != PAM_SUCCESS) ) { - pam_syslog(pamh, LOG_CRIT, "error manipulating password"); - continue; - } - item = NULL; /* break link to password */ - return PAM_SUCCESS; - } - } - - } while (options.retry_times--); - - } else { - if (ctrl & PAM_DEBUG_ARG) - pam_syslog(pamh, LOG_NOTICE, "UNKNOWN flags setting %02X",flags); - return PAM_SERVICE_ERR; - } - - /* Not reached */ - return PAM_SERVICE_ERR; -} - - - -#ifdef PAM_STATIC -/* static module data */ -struct pam_module _pam_cracklib_modstruct = { - "pam_cracklib", - NULL, - NULL, - NULL, - NULL, - NULL, - pam_sm_chauthtok -}; -#endif - -/* - * Copyright (c) Cristian Gafton <gafton@redhat.com>, 1996. - * All rights reserved - * - * 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. - * - * The following copyright was appended for the long password support - * added with the libpam 0.58 release: - * - * Modificaton Copyright (c) Philip W. Dalrymple III <pwd@mdtsoft.com> - * 1997. All rights reserved - * - * THE MODIFICATION THAT PROVIDES SUPPORT FOR LONG PASSWORD TYPE CHECKING TO - * 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. - */ diff --git a/modules/pam_cracklib/tst-pam_cracklib b/modules/pam_cracklib/tst-pam_cracklib deleted file mode 100755 index 46a7060d..00000000 --- a/modules/pam_cracklib/tst-pam_cracklib +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/sh -../../tests/tst-dlopen .libs/pam_cracklib.so diff --git a/modules/pam_debug/.cvsignore b/modules/pam_debug/.cvsignore deleted file mode 100644 index af38ef08..00000000 --- a/modules/pam_debug/.cvsignore +++ /dev/null @@ -1,8 +0,0 @@ -*.la -*.lo -.deps -.libs -Makefile -Makefile.in -README -pam_debug.8 diff --git a/modules/pam_debug/Makefile.am b/modules/pam_debug/Makefile.am deleted file mode 100644 index 0b798516..00000000 --- a/modules/pam_debug/Makefile.am +++ /dev/null @@ -1,31 +0,0 @@ -# -# Copyright (c) 2005, 2006 Thorsten Kukuk <kukuk@thkukuk.de> -# - -CLEANFILES = *~ - -EXTRA_DIST = README $(MANS) $(XMLS) tst-pam_debug - -man_MANS = pam_debug.8 -XMLS = README.xml pam_debug.8.xml - -securelibdir = $(SECUREDIR) -secureconfdir = $(SCONFIGDIR) - -AM_CFLAGS = -I$(top_srcdir)/libpam/include -I$(top_srcdir)/libpamc/include -AM_LDFLAGS = -no-undefined -avoid-version -module -if HAVE_VERSIONING - AM_LDFLAGS += -Wl,--version-script=$(srcdir)/../modules.map -endif - -securelib_LTLIBRARIES = pam_debug.la -pam_debug_la_LIBADD = -L$(top_builddir)/libpam -lpam - -TESTS = tst-pam_debug - -if ENABLE_REGENERATE_MAN -noinst_DATA = README -README: pam_debug.8.xml --include $(top_srcdir)/Make.xml.rules -endif - diff --git a/modules/pam_debug/README.xml b/modules/pam_debug/README.xml deleted file mode 100644 index ef41911b..00000000 --- a/modules/pam_debug/README.xml +++ /dev/null @@ -1,41 +0,0 @@ -<?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_debug.8.xml"> ---> -]> - -<article> - - <articleinfo> - - <title> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" - href="pam_debug.8.xml" xpointer='xpointer(//refnamediv[@id = "pam_debug-name"]/*)'/> - </title> - - </articleinfo> - - <section> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" - href="pam_debug.8.xml" xpointer='xpointer(//refsect1[@id = "pam_debug-description"]/*)'/> - </section> - - <section> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" - href="pam_debug.8.xml" xpointer='xpointer(//refsect1[@id = "pam_debug-options"]/*)'/> - </section> - - <section> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" - href="pam_debug.8.xml" xpointer='xpointer(//refsect1[@id = "pam_debug-examples"]/*)'/> - </section> - - <section> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" - href="pam_debug.8.xml" xpointer='xpointer(//refsect1[@id = "pam_debug-author"]/*)'/> - </section> - -</article> diff --git a/modules/pam_debug/pam_debug.8.xml b/modules/pam_debug/pam_debug.8.xml deleted file mode 100644 index 65519852..00000000 --- a/modules/pam_debug/pam_debug.8.xml +++ /dev/null @@ -1,231 +0,0 @@ -<?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_debug"> - - <refmeta> - <refentrytitle>pam_debug</refentrytitle> - <manvolnum>8</manvolnum> - <refmiscinfo class="sectdesc">Linux-PAM Manual</refmiscinfo> - </refmeta> - - <refnamediv id="pam_debug-name"> - <refname>pam_debug</refname> - <refpurpose>PAM module to debug the PAM stack</refpurpose> - </refnamediv> - - <refsynopsisdiv> - <cmdsynopsis id="pam_debug-cmdsynopsis"> - <command>pam_debug.so</command> - <arg choice="opt"> - auth=<replaceable>value</replaceable> - </arg> - <arg choice="opt"> - cred=<replaceable>value</replaceable> - </arg> - <arg choice="opt"> - acct=<replaceable>value</replaceable> - </arg> - <arg choice="opt"> - prechauthtok=<replaceable>value</replaceable> - </arg> - <arg choice="opt"> - chauthtok=<replaceable>value</replaceable> - </arg> - <arg choice="opt"> - auth=<replaceable>value</replaceable> - </arg> - <arg choice="opt"> - open_session=<replaceable>value</replaceable> - </arg> - <arg choice="opt"> - close_session=<replaceable>value</replaceable> - </arg> - </cmdsynopsis> - </refsynopsisdiv> - - <refsect1 id="pam_debug-description"> - <title>DESCRIPTION</title> - <para> - The pam_debug PAM module is intended as a debugging aide for - determining how the PAM stack is operating. This module returns - what its module arguments tell it to return. - </para> - </refsect1> - - <refsect1 id="pam_debug-options"> - <title>OPTIONS</title> - <variablelist> - <varlistentry> - <term> - <option>auth=<replaceable>value</replaceable></option> - </term> - <listitem> - <para> - The - <citerefentry> - <refentrytitle>pam_sm_authenticate</refentrytitle><manvolnum>3</manvolnum> - </citerefentry> function will return - <replaceable>value</replaceable>. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <option>cred=<replaceable>value</replaceable></option> - </term> - <listitem> - <para> - The - <citerefentry> - <refentrytitle>pam_sm_setcred</refentrytitle><manvolnum>3</manvolnum> - </citerefentry> function will return - <replaceable>value</replaceable>. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <option>acct=<replaceable>value</replaceable></option> - </term> - <listitem> - <para> - The - <citerefentry> - <refentrytitle>pam_sm_acct_mgmt</refentrytitle><manvolnum>3</manvolnum> - </citerefentry> function will return - <replaceable>value</replaceable>. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <option>prechauthtok=<replaceable>value</replaceable></option> - </term> - <listitem> - <para> - The - <citerefentry> - <refentrytitle>pam_sm_chauthtok</refentrytitle><manvolnum>3</manvolnum> - </citerefentry> function will return - <replaceable>value</replaceable> if the - <emphasis>PAM_PRELIM_CHECK</emphasis> flag is set. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <option>chauthtok=<replaceable>value</replaceable></option> - </term> - <listitem> - <para> - The - <citerefentry> - <refentrytitle>pam_sm_chauthtok</refentrytitle><manvolnum>3</manvolnum> - </citerefentry> function will return - <replaceable>value</replaceable> if the - <emphasis>PAM_PRELIM_CHECK</emphasis> flag is - <emphasis remap='B'>not</emphasis> set. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <option>open_session=<replaceable>value</replaceable></option> - </term> - <listitem> - <para> - The - <citerefentry> - <refentrytitle>pam_sm_open_session</refentrytitle><manvolnum>3</manvolnum> - </citerefentry> function will return - <replaceable>value</replaceable>. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <option>close_session=<replaceable>value</replaceable></option> - </term> - <listitem> - <para> - The - <citerefentry> - <refentrytitle>pam_sm_close_session</refentrytitle><manvolnum>3</manvolnum> - </citerefentry> function will return - <replaceable>value</replaceable>. - </para> - </listitem> - </varlistentry> - </variablelist> - <para> - Where <replaceable>value</replaceable> can be one of: success, - open_err, symbol_err, service_err, system_err, buf_err, perm_denied, - auth_err, cred_insufficient, authinfo_unavail, user_unknown, - maxtries, new_authtok_reqd, acct_expired, session_err, cred_unavail, - cred_expired, cred_err, no_module_data, conv_err, authtok_err, - authtok_recover_err, authtok_lock_busy, authtok_disable_aging, - try_again, ignore, abort, authtok_expired, module_unknown, - bad_item, conv_again, incomplete. - </para> - </refsect1> - - <refsect1 id="pam_debug-services"> - <title>MODULE SERVICES PROVIDED</title> - <para> - The services <option>auth</option>, <option>account</option>, - <option>password</option> and <option>session</option> are supported. - </para> - </refsect1> - - <refsect1 id='pam_debug-return_values'> - <title>RETURN VALUES</title> - <variablelist> - <varlistentry> - <term>PAM_SUCCESS</term> - <listitem> - <para> - Default return code if no other value was specified, - else specified return value. - </para> - </listitem> - </varlistentry> - </variablelist> - </refsect1> - - <refsect1 id='pam_debug-examples'> - <title>EXAMPLES</title> - <programlisting> -auth requisite pam_permit.so -auth [success=2 default=ok] pam_debug.so auth=perm_denied cred=success -auth [default=reset] pam_debug.so auth=success cred=perm_denied -auth [success=done default=die] pam_debug.so -auth optional pam_debug.so auth=perm_denied cred=perm_denied -auth sufficient pam_debug.so auth=success cred=success - </programlisting> - </refsect1> - - <refsect1 id='pam_debug-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_debug-author'> - <title>AUTHOR</title> - <para> - pam_debug was written by Andrew G. Morgan <morgan@kernel.org>. - </para> - </refsect1> - -</refentry> diff --git a/modules/pam_debug/pam_debug.c b/modules/pam_debug/pam_debug.c deleted file mode 100644 index a65d1bf2..00000000 --- a/modules/pam_debug/pam_debug.c +++ /dev/null @@ -1,167 +0,0 @@ -/* pam_permit module */ - -/* - * $Id$ - * - * Written by Andrew Morgan <morgan@kernel.org> 2001/02/04 - * - */ - -#define DEFAULT_USER "nobody" - -#include "config.h" - -#include <stdio.h> - -/* - * This module is intended as a debugging aide for determining how - * the PAM stack is operating. - * - * here, we make definitions for the externally accessible functions - * in this file (these definitions are required for static modules - * but strongly encouraged generally) they are used to instruct the - * modules include file to define their prototypes. - */ - -#define PAM_SM_AUTH -#define PAM_SM_ACCOUNT -#define PAM_SM_SESSION -#define PAM_SM_PASSWORD - -#include <security/pam_modules.h> -#include <security/_pam_macros.h> -#include <security/pam_ext.h> - -#define _PAM_ACTION_UNDEF (-10) -#include "../../libpam/pam_tokens.h" - -/* --- authentication management functions --- */ - -static int state(pam_handle_t *pamh, const char *text) -{ - int retval; - - retval = pam_info (pamh, "%s", text); - - if (retval != PAM_SUCCESS) { - D(("pam_info failed")); - } - - return retval; -} - -static int parse_args(int retval, const char *event, - pam_handle_t *pamh, int argc, const char **argv) -{ - int i; - - for (i=0; i<argc; ++i) { - int length = strlen(event); - if (!strncmp(event, argv[i], length) && (argv[i][length] == '=')) { - int j; - const char *return_string = argv[i] + (length+1); - - for (j=0; j<_PAM_RETURN_VALUES; ++j) { - if (!strcmp(return_string, _pam_token_returns[j])) { - retval = j; - state(pamh, argv[i]); - break; - } - } - break; - } - } - - return retval; -} - -PAM_EXTERN -int pam_sm_authenticate(pam_handle_t *pamh, int flags UNUSED, - int argc, const char **argv) -{ - int retval; - const char *user=NULL; - - /* - * authentication requires we know who the user wants to be - */ - retval = pam_get_user(pamh, &user, NULL); - if (retval != PAM_SUCCESS) { - D(("get user returned error: %s", pam_strerror(pamh,retval))); - return retval; - } - if (user == NULL || *user == '\0') { - D(("username not known")); - retval = pam_set_item(pamh, PAM_USER, (const void *) DEFAULT_USER); - if (retval != PAM_SUCCESS) - return retval; - } - user = NULL; /* clean up */ - - retval = parse_args(PAM_SUCCESS, "auth", pamh, argc, argv); - - return retval; -} - -PAM_EXTERN -int pam_sm_setcred(pam_handle_t *pamh, int flags UNUSED, - int argc, const char **argv) -{ - return parse_args(PAM_SUCCESS, "cred", pamh, argc, argv); -} - -/* --- account management functions --- */ - -PAM_EXTERN -int pam_sm_acct_mgmt(pam_handle_t *pamh, int flags UNUSED, - int argc, const char **argv) -{ - return parse_args(PAM_SUCCESS, "acct", pamh, argc, argv); -} - -/* --- password management --- */ - -PAM_EXTERN -int pam_sm_chauthtok(pam_handle_t *pamh, int flags UNUSED, - int argc, const char **argv) -{ - if (flags & PAM_PRELIM_CHECK) { - return parse_args(PAM_SUCCESS, "prechauthtok", pamh, argc, argv); - } else { - return parse_args(PAM_SUCCESS, "chauthtok", pamh, argc, argv); - } -} - -/* --- session management --- */ - -PAM_EXTERN -int pam_sm_open_session(pam_handle_t *pamh, int flags UNUSED, - int argc, const char **argv) -{ - return parse_args(PAM_SUCCESS, "open_session", pamh, argc, argv); -} - -PAM_EXTERN -int pam_sm_close_session(pam_handle_t *pamh, int flags UNUSED, - int argc, const char **argv) -{ - return parse_args(PAM_SUCCESS, "close_session", pamh, argc, argv); -} - -/* end of module definition */ - -#ifdef PAM_STATIC - -/* static module data */ - -struct pam_module _pam_debug_modstruct = { - "pam_debug", - pam_sm_authenticate, - pam_sm_setcred, - pam_sm_acct_mgmt, - pam_sm_open_session, - pam_sm_close_session, - pam_sm_chauthtok -}; - -#endif diff --git a/modules/pam_debug/tst-pam_debug b/modules/pam_debug/tst-pam_debug deleted file mode 100755 index f07ff640..00000000 --- a/modules/pam_debug/tst-pam_debug +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/sh -../../tests/tst-dlopen .libs/pam_debug.so diff --git a/modules/pam_deny/.cvsignore b/modules/pam_deny/.cvsignore deleted file mode 100644 index 180c6155..00000000 --- a/modules/pam_deny/.cvsignore +++ /dev/null @@ -1,8 +0,0 @@ -*.la -*.lo -.deps -.libs -Makefile -Makefile.in -README -pam_deny.8 diff --git a/modules/pam_deny/Makefile.am b/modules/pam_deny/Makefile.am deleted file mode 100644 index 94b5f0f6..00000000 --- a/modules/pam_deny/Makefile.am +++ /dev/null @@ -1,34 +0,0 @@ -# -# Copyright (c) 2005 Thorsten Kukuk <kukuk@suse.de> -# - -CLEANFILES = *~ - -EXTRA_DIST = README $(MANS) $(XMLS) tst-pam_deny - -man_MANS = pam_deny.8 - -XMLS = README.xml pam_deny.8.xml - -securelibdir = $(SECUREDIR) -secureconfdir = $(SCONFIGDIR) - -AM_CFLAGS = -I$(top_srcdir)/libpam/include -I$(top_srcdir)/libpamc/include -AM_LDFLAGS = -no-undefined -avoid-version -module -if HAVE_VERSIONING - AM_LDFLAGS += -Wl,--version-script=$(srcdir)/../modules.map -endif - -securelib_LTLIBRARIES = pam_deny.la -pam_deny_la_LIBADD = -L$(top_builddir)/libpam -lpam - -if ENABLE_REGENERATE_MAN - -noinst_DATA = README - -README: pam_deny.8.xml - --include $(top_srcdir)/Make.xml.rules -endif - -TESTS = tst-pam_deny diff --git a/modules/pam_deny/README.xml b/modules/pam_deny/README.xml deleted file mode 100644 index ff2e82b0..00000000 --- a/modules/pam_deny/README.xml +++ /dev/null @@ -1,36 +0,0 @@ -<?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_deny.8.xml"> ---> -]> - -<article> - - <articleinfo> - - <title> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" - href="pam_deny.8.xml" xpointer='xpointer(//refnamediv[@id = "pam_deny-name"]/*)'/> - </title> - - </articleinfo> - - <section> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" - href="pam_deny.8.xml" xpointer='xpointer(//refsect1[@id = "pam_deny-description"]/*)'/> - </section> - - <section> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" - href="pam_deny.8.xml" xpointer='xpointer(//refsect1[@id = "pam_deny-examples"]/*)'/> - </section> - - <section> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" - href="pam_deny.8.xml" xpointer='xpointer(//refsect1[@id = "pam_deny-author"]/*)'/> - </section> - -</article> diff --git a/modules/pam_deny/pam_deny.8.xml b/modules/pam_deny/pam_deny.8.xml deleted file mode 100644 index e50beb2d..00000000 --- a/modules/pam_deny/pam_deny.8.xml +++ /dev/null @@ -1,135 +0,0 @@ -<?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_deny"> - - <refmeta> - <refentrytitle>pam_deny</refentrytitle> - <manvolnum>8</manvolnum> - <refmiscinfo class="sectdesc">Linux-PAM Manual</refmiscinfo> - </refmeta> - - <refnamediv id="pam_deny-name"> - <refname>pam_deny</refname> - <refpurpose>The locking-out PAM module</refpurpose> - </refnamediv> - - <refsynopsisdiv> - <cmdsynopsis id="pam_deny-cmdsynopsis"> - <command>pam_deny.so</command> - </cmdsynopsis> - </refsynopsisdiv> - - <refsect1 id="pam_deny-description"> - - <title>DESCRIPTION</title> - - <para> - This module can be used to deny access. It always indicates a failure - to the application through the PAM framework. It might be suitable - for using for default (the <emphasis>OTHER</emphasis>) entries. - </para> - - </refsect1> - - <refsect1 id="pam_deny-options"> - <title>OPTIONS</title> - <para>This module does not recognise any options.</para> - </refsect1> - - <refsect1 id="pam_deny-services"> - <title>MODULE SERVICES PROVIDED</title> - <para> - All services (<option>account</option>, <option>auth</option>, - <option>password</option> and <option>session</option>) are supported. - </para> - </refsect1> - - <refsect1 id='pam_deny-return_values'> - <title>RETURN VALUES</title> - <para> - <variablelist> - - <varlistentry> - <term>PAM_AUTH_ERR</term> - <listitem> - <para> - This is returned by the account and auth services. - </para> - </listitem> - </varlistentry> - - <varlistentry> - <term>PAM_CRED_ERR</term> - <listitem> - <para> - This is returned by the setcred function. - </para> - </listitem> - </varlistentry> - - <varlistentry> - <term>PAM_AUTHTOK_ERR</term> - <listitem> - <para> - This is returned by the password service. - </para> - </listitem> - </varlistentry> - - <varlistentry> - <term>PAM_SESSION_ERR</term> - <listitem> - <para> - This is returned by the session service. - </para> - </listitem> - </varlistentry> - - </variablelist> - </para> - </refsect1> - - <refsect1 id='pam_deny-examples'> - <title>EXAMPLES</title> - <programlisting> -#%PAM-1.0 -# -# If we don't have config entries for a service, the -# OTHER entries are used. To be secure, warn and deny -# access to everything. -other auth required pam_warn.so -other auth required pam_deny.so -other account required pam_warn.so -other account required pam_deny.so -other password required pam_warn.so -other password required pam_deny.so -other session required pam_warn.so -other session required pam_deny.so - </programlisting> - </refsect1> - - <refsect1 id='pam_deny-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_deny-author'> - <title>AUTHOR</title> - <para> - pam_deny was written by Andrew G. Morgan <morgan@kernel.org> - </para> - </refsect1> - -</refentry> diff --git a/modules/pam_deny/pam_deny.c b/modules/pam_deny/pam_deny.c deleted file mode 100644 index 544c5bdb..00000000 --- a/modules/pam_deny/pam_deny.c +++ /dev/null @@ -1,89 +0,0 @@ -/* pam_deny module */ - -/* - * $Id$ - * - * Written by Andrew Morgan <morgan@parc.power.net> 1996/3/11 - * - */ - -/* - * here, we make definitions for the externally accessible functions - * in this file (these definitions are required for static modules - * but strongly encouraged generally) they are used to instruct the - * modules include file to define their prototypes. - */ - -#include "config.h" - -#define PAM_SM_AUTH -#define PAM_SM_ACCOUNT -#define PAM_SM_SESSION -#define PAM_SM_PASSWORD - -#include <security/pam_modules.h> - -/* --- authentication management functions --- */ - -PAM_EXTERN int -pam_sm_authenticate(pam_handle_t *pamh UNUSED, int flags UNUSED, - int argc UNUSED, const char **argv UNUSED) -{ - return PAM_AUTH_ERR; -} - -PAM_EXTERN int -pam_sm_setcred(pam_handle_t *pamh UNUSED, int flags UNUSED, - int argc UNUSED, const char **argv UNUSED) -{ - return PAM_CRED_ERR; -} - -/* --- account management functions --- */ - -PAM_EXTERN int -pam_sm_acct_mgmt(pam_handle_t *pamh UNUSED, int flags UNUSED, - int argc UNUSED, const char **argv UNUSED) -{ - return PAM_AUTH_ERR; -} - -/* --- password management --- */ - -PAM_EXTERN int -pam_sm_chauthtok(pam_handle_t *pamh UNUSED, int flags UNUSED, - int argc UNUSED, const char **argv UNUSED) -{ - return PAM_AUTHTOK_ERR; -} - -/* --- session management --- */ - -PAM_EXTERN int -pam_sm_open_session(pam_handle_t *pamh UNUSED, int flags UNUSED, - int argc UNUSED, const char **argv UNUSED) -{ - return PAM_SESSION_ERR; -} - -PAM_EXTERN int -pam_sm_close_session(pam_handle_t *pamh UNUSED, int flags UNUSED, - int argc UNUSED, const char **argv UNUSED) -{ - return PAM_SESSION_ERR; -} - -/* end of module definition */ - -/* static module data */ -#ifdef PAM_STATIC -struct pam_module _pam_deny_modstruct = { - "pam_deny", - pam_sm_authenticate, - pam_sm_setcred, - pam_sm_acct_mgmt, - pam_sm_open_session, - pam_sm_close_session, - pam_sm_chauthtok -}; -#endif diff --git a/modules/pam_deny/tst-pam_deny b/modules/pam_deny/tst-pam_deny deleted file mode 100755 index 7d9d6bad..00000000 --- a/modules/pam_deny/tst-pam_deny +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/sh -../../tests/tst-dlopen .libs/pam_deny.so diff --git a/modules/pam_echo/.cvsignore b/modules/pam_echo/.cvsignore deleted file mode 100644 index 2d5569ad..00000000 --- a/modules/pam_echo/.cvsignore +++ /dev/null @@ -1,8 +0,0 @@ -*.la -*.lo -.deps -.libs -Makefile -Makefile.in -README -pam_echo.8 diff --git a/modules/pam_echo/Makefile.am b/modules/pam_echo/Makefile.am deleted file mode 100644 index d004e8f4..00000000 --- a/modules/pam_echo/Makefile.am +++ /dev/null @@ -1,31 +0,0 @@ -# -# Copyright (c) 2005, 2006 Thorsten Kukuk <kukuk@thkukuk.de> -# - -CLEANFILES = *~ - -EXTRA_DIST = README $(MANS) $(XMLS) tst-pam_echo - -man_MANS = pam_echo.8 - -XMLS = README.xml pam_echo.8.xml - -securelibdir = $(SECUREDIR) -secureconfdir = $(SCONFIGDIR) - -AM_CFLAGS = -I$(top_srcdir)/libpam/include -I$(top_srcdir)/libpamc/include -AM_LDFLAGS = -no-undefined -avoid-version -module -if HAVE_VERSIONING - AM_LDFLAGS += -Wl,--version-script=$(srcdir)/../modules.map -endif - -securelib_LTLIBRARIES = pam_echo.la -pam_echo_la_LIBADD = -L$(top_builddir)/libpam -lpam - -if ENABLE_REGENERATE_MAN -noinst_DATA = README -README: pam_echo.8.xml --include $(top_srcdir)/Make.xml.rules -endif - -TESTS = tst-pam_echo diff --git a/modules/pam_echo/README.xml b/modules/pam_echo/README.xml deleted file mode 100644 index b1556e38..00000000 --- a/modules/pam_echo/README.xml +++ /dev/null @@ -1,36 +0,0 @@ -<?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_echo.8.xml"> ---> -]> - -<article> - - <articleinfo> - - <title> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" - href="pam_echo.8.xml" xpointer='xpointer(//refnamediv[@id = "pam_echo-name"]/*)'/> - </title> - - </articleinfo> - - <section> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" - href="pam_echo.8.xml" xpointer='xpointer(//refsect1[@id = "pam_echo-description"]/*)'/> - </section> - - <section> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" - href="pam_echo.8.xml" xpointer='xpointer(//refsect1[@id = "pam_echo-examples"]/*)'/> - </section> - - <section> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" - href="pam_echo.8.xml" xpointer='xpointer(//refsect1[@id = "pam_echo-author"]/*)'/> - </section> - -</article> diff --git a/modules/pam_echo/pam_echo.8.xml b/modules/pam_echo/pam_echo.8.xml deleted file mode 100644 index 4a495195..00000000 --- a/modules/pam_echo/pam_echo.8.xml +++ /dev/null @@ -1,168 +0,0 @@ -<?xml version="1.0" encoding="ISO-8859-1"?> -<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN" - "http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd"> - -<refentry id='pam_echo'> - <refmeta> - <refentrytitle>pam_echo</refentrytitle> - <manvolnum>8</manvolnum> - <refmiscinfo class='setdesc'>Linux-PAM Manual</refmiscinfo> - </refmeta> - - <refnamediv id='pam_echo-name'> - <refname>pam_echo</refname> - <refpurpose>PAM module for printing text messages</refpurpose> - </refnamediv> - -<!-- body begins here --> - - <refsynopsisdiv> - <cmdsynopsis id="pam_echo-cmdsynopsis"> - <command>pam_echo.so</command> - <arg choice="opt"> - file=<replaceable>/path/message</replaceable> - </arg> - </cmdsynopsis> - </refsynopsisdiv> - - <refsect1 id='pam_echo-description'> - <title>DESCRIPTION</title> - <para> - The <emphasis>pam_echo</emphasis> PAM module is for printing - text messages to inform user about special things. Sequences - starting with the <emphasis>%</emphasis> character are - interpreted in the following way: - </para> - <variablelist> - <varlistentry> - <term><emphasis>%H</emphasis></term> - <listitem> - <para>The name of the remote host (PAM_RHOST).</para> - </listitem> - </varlistentry> - <varlistentry> - <term><emphasis remap='B'>%h</emphasis></term> - <listitem> - <para>The name of the local host.</para> - </listitem> - </varlistentry> - <varlistentry> - <term><emphasis>%s</emphasis></term> - <listitem> - <para>The service name (PAM_SERVICE).</para> - </listitem> - </varlistentry> - <varlistentry> - <term><emphasis>%t</emphasis></term> - <listitem> - <para>The name of the controlling terminal (PAM_TTY).</para> - </listitem> - </varlistentry> - <varlistentry> - <term><emphasis>%U</emphasis></term> - <listitem> - <para>The remote user name (PAM_RUSER).</para> - </listitem> - </varlistentry> - <varlistentry> - <term><emphasis>%u</emphasis></term> - <listitem> - <para>The local user name (PAM_USER).</para> - </listitem> - </varlistentry> - </variablelist> - - <para> - All other sequences beginning with <emphasis>%</emphasis> - expands to the characters following the <emphasis>%</emphasis> - character. - </para> - </refsect1> - - <refsect1 id='pam_echo-options'> - <title>OPTIONS</title> - <variablelist> - <varlistentry> - <term> - <option>file=<replaceable>/path/message</replaceable></option> - </term> - <listitem> - <para> - The content of the file <filename>/path/message</filename> - will be printed with the PAM conversion function as PAM_TEXT_INFO. - </para> - </listitem> - </varlistentry> - </variablelist> - </refsect1> - - <refsect1 id="pam_echo-services"> - <title>MODULE SERVICES PROVIDED</title> - <para> - All services are supported. - </para> - </refsect1> - - - <refsect1 id="pam_echo-return_values"> - <title>RETURN VALUES</title> - <variablelist> - <varlistentry> - <term>PAM_BUF_ERR</term> - <listitem> - <para> - Memory buffer error. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term>PAM_SUCCESS</term> - <listitem> - <para> - Message was successful printed. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term>PAM_IGNORE</term> - <listitem> - <para> - PAM_SILENT flag was given or message file does not - exist, no message printed. - </para> - </listitem> - </varlistentry> - </variablelist> - </refsect1> - - <refsect1 id='pam_echo-examples'> - <title>EXAMPLES</title> - <para> - For an example of the use of this module, we show how it may be - used to print informations about good passwords: - <programlisting> -password optional pam_echo.so file=/usr/share/doc/good-password.txt -password required pam_unix.so - </programlisting> - </para> - </refsect1> - - - <refsect1 id='pam_echo-see_also'><title>SEE ALSO</title> - <para> - <citerefentry> - <refentrytitle>pam.conf</refentrytitle><manvolnum>8</manvolnum> - </citerefentry>, - <citerefentry> - <refentrytitle>pam.d</refentrytitle><manvolnum>8</manvolnum> - </citerefentry>, - <citerefentry> - <refentrytitle>pam</refentrytitle><manvolnum>8</manvolnum> - </citerefentry></para> - </refsect1> - - <refsect1 id='pam_echo-author'> - <title>AUTHOR</title> - <para>Thorsten Kukuk <kukuk@thkukuk.de></para> - </refsect1> -</refentry> diff --git a/modules/pam_echo/pam_echo.c b/modules/pam_echo/pam_echo.c deleted file mode 100644 index 31ebca22..00000000 --- a/modules/pam_echo/pam_echo.c +++ /dev/null @@ -1,269 +0,0 @@ -/* - * Copyright (c) 2005, 2006 Thorsten Kukuk <kukuk@suse.de> - * - * 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. - */ - -#if defined(HAVE_CONFIG_H) -#include "config.h" -#endif - -#include <errno.h> -#include <stdio.h> -#include <fcntl.h> -#include <string.h> -#include <stdlib.h> -#include <unistd.h> -#include <limits.h> -#include <syslog.h> -#include <sys/types.h> -#include <sys/stat.h> - -#ifndef HOST_NAME_MAX -#define HOST_NAME_MAX 255 -#endif - -#define PAM_SM_ACCOUNT -#define PAM_SM_AUTH -#define PAM_SM_PASSWORD -#define PAM_SM_SESSION - -#include <security/pam_modules.h> -#include <security/pam_modutil.h> -#include <security/_pam_macros.h> -#include <security/pam_ext.h> - -static int -replace_and_print (pam_handle_t *pamh, const char *mesg) -{ - char *output; - size_t length = strlen (mesg) + PAM_MAX_MSG_SIZE; - char myhostname[HOST_NAME_MAX+1]; - const void *str = NULL; - const char *p, *q; - int item; - size_t len; - - output = malloc (length); - if (output == NULL) - { - pam_syslog (pamh, LOG_ERR, "running out of memory"); - return PAM_BUF_ERR; - } - - for (p = mesg, len = 0; *p != '\0' && len < length - 1; ++p) - { - if (*p != '%' || p[1] == '\0') - { - output[len++] = *p; - continue; - } - switch (*++p) - { - case 'H': - item = PAM_RHOST; - break; - case 'h': - item = -2; /* aka PAM_LOCALHOST */ - break; - case 's': - item = PAM_SERVICE; - break; - case 't': - item = PAM_TTY; - break; - case 'U': - item = PAM_RUSER; - break; - case 'u': - item = PAM_USER; - break; - default: - output[len++] = *p; - continue; - } - if (item == -2) - { - if (gethostname (myhostname, sizeof (myhostname)) == -1) - str = NULL; - else - str = &myhostname; - } - else - pam_get_item (pamh, item, &str); - if (str == NULL) - str = "(null)"; - for (q = str; *q != '\0' && len < length - 1; ++q) - output[len++] = *q; - } - output[len] = '\0'; - - pam_info (pamh, "%s", output); - free (output); - - return PAM_SUCCESS; -} - -static int -pam_echo (pam_handle_t *pamh, int flags, int argc, const char **argv) -{ - int fd; - int orig_argc = argc; - const char **orig_argv = argv; - const char *file = NULL; - int retval; - - if (flags & PAM_SILENT) - return PAM_IGNORE; - - for (; argc-- > 0; ++argv) - { - if (!strncmp (*argv, "file=", 5)) - file = (5 + *argv); - } - - /* No file= option, use argument for output. */ - if (file == NULL || file[0] == '\0') - { - char msg[PAM_MAX_MSG_SIZE]; - const char *p; - int i; - size_t len; - - for (i = 0, len = 0; i < orig_argc && len < sizeof (msg) - 1; ++i) - { - if (i > 0) - msg[len++] = ' '; - for (p = orig_argv[i]; *p != '\0' && len < sizeof(msg) - 1; ++p) - msg[len++] = *p; - } - msg[len] = '\0'; - - retval = replace_and_print (pamh, msg); - } - else if ((fd = open (file, O_RDONLY, 0)) >= 0) - { - char *mtmp = NULL; - struct stat st; - - /* load file into message buffer. */ - if ((fstat (fd, &st) < 0) || !st.st_size) - return PAM_IGNORE; - - mtmp = malloc (st.st_size + 1); - if (!mtmp) - return PAM_BUF_ERR; - - if (pam_modutil_read (fd, mtmp, st.st_size) == -1) - { - pam_syslog (pamh, LOG_ERR, "Error while reading %s: %m", file); - free (mtmp); - return PAM_IGNORE; - } - - if (mtmp[st.st_size - 1] == '\n') - mtmp[st.st_size - 1] = '\0'; - else - mtmp[st.st_size] = '\0'; - - close (fd); - retval = replace_and_print (pamh, mtmp); - free (mtmp); - } - else - { - pam_syslog (pamh, LOG_ERR, "Cannot open %s: %m", file); - retval = PAM_IGNORE; - } - return retval; -} - -int -pam_sm_authenticate (pam_handle_t *pamh, int flags, int argc, - const char **argv) -{ - return pam_echo (pamh, flags, argc, argv); -} - -int -pam_sm_setcred (pam_handle_t *pamh UNUSED, int flags UNUSED, - int argc UNUSED, const char **argv UNUSED) -{ - return PAM_IGNORE; -} - -int -pam_sm_acct_mgmt (pam_handle_t *pamh, int flags, int argc, - const char **argv) -{ - return pam_echo (pamh, flags, argc, argv); -} - -int -pam_sm_open_session (pam_handle_t *pamh, int flags, int argc, - const char **argv) -{ - return pam_echo (pamh, flags, argc, argv); -} - -int -pam_sm_close_session (pam_handle_t *pamh UNUSED, int flags UNUSED, - int argc UNUSED, const char **argv UNUSED) -{ - return PAM_IGNORE; -} - -int -pam_sm_chauthtok (pam_handle_t *pamh, int flags, int argc, - const char **argv) -{ - if (flags & PAM_PRELIM_CHECK) - return pam_echo (pamh, flags, argc, argv); - else - return PAM_IGNORE; -} - -#ifdef PAM_STATIC - -/* static module data */ - -struct pam_module _pam_echo_modstruct = { - "pam_echo", - pam_sm_authenticate, - pam_sm_setcred, - pam_sm_acct_mgmt, - pam_sm_open_session, - pam_sm_close_session, - pam_sm_chauthtok, -}; - -#endif diff --git a/modules/pam_echo/tst-pam_echo b/modules/pam_echo/tst-pam_echo deleted file mode 100755 index 483a2c23..00000000 --- a/modules/pam_echo/tst-pam_echo +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/sh -../../tests/tst-dlopen .libs/pam_echo.so diff --git a/modules/pam_env/.cvsignore b/modules/pam_env/.cvsignore deleted file mode 100644 index e35f869e..00000000 --- a/modules/pam_env/.cvsignore +++ /dev/null @@ -1,9 +0,0 @@ -*.la -*.lo -.deps -.libs -Makefile -Makefile.in -README -pam_env.8 -pam_env.conf.5 diff --git a/modules/pam_env/Makefile.am b/modules/pam_env/Makefile.am deleted file mode 100644 index 87813688..00000000 --- a/modules/pam_env/Makefile.am +++ /dev/null @@ -1,35 +0,0 @@ -# -# Copyright (c) 2005 Thorsten Kukuk <kukuk@suse.de> -# - -CLEANFILES = *~ - -EXTRA_DIST = README pam_env.conf $(MANS) $(XMLS) tst-pam_env environment - -man_MANS = pam_env.conf.5 pam_env.8 - -XMLS = README.xml pam_env.conf.5.xml pam_env.8.xml - -securelibdir = $(SECUREDIR) -secureconfdir = $(SCONFIGDIR) - -AM_CFLAGS = -I$(top_srcdir)/libpam/include -I$(top_srcdir)/libpamc/include \ - -DDEFAULT_CONF_FILE=\"$(SCONFIGDIR)/pam_env.conf\" -AM_LDFLAGS = -no-undefined -avoid-version -module -if HAVE_VERSIONING - AM_LDFLAGS += -Wl,--version-script=$(srcdir)/../modules.map -endif - -securelib_LTLIBRARIES = pam_env.la -pam_env_la_LIBADD = -L$(top_builddir)/libpam -lpam - -secureconf_DATA = pam_env.conf -sysconf_DATA = environment - -if ENABLE_REGENERATE_MAN -noinst_DATA = README -README: pam_env.8.xml pam_env.conf.5.xml --include $(top_srcdir)/Make.xml.rules -endif - -TESTS = tst-pam_env diff --git a/modules/pam_env/README.xml b/modules/pam_env/README.xml deleted file mode 100644 index 21a9b855..00000000 --- a/modules/pam_env/README.xml +++ /dev/null @@ -1,39 +0,0 @@ -<?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_env.8.xml"> ---> -<!-- -<!ENTITY accessconf SYSTEM "pam_env.conf.5.xml"> ---> -]> - -<article> - - <articleinfo> - - <title> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" - href="pam_env.8.xml" xpointer='xpointer(//refnamediv[@id = "pam_env-name"]/*)'/> - </title> - - </articleinfo> - - <section> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" - href="pam_env.8.xml" xpointer='xpointer(//refsect1[@id = "pam_env-description"]/*)'/> - </section> - - <section> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" - href="pam_env.8.xml" xpointer='xpointer(//refsect1[@id = "pam_env-options"]/*)'/> - </section> - - <section> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" - href="pam_env.conf.5.xml" xpointer='xpointer(//refsect1[@id = "pam_env.conf-examples"]/*)'/> - </section> - -</article> diff --git a/modules/pam_env/environment b/modules/pam_env/environment deleted file mode 100644 index f46b8d94..00000000 --- a/modules/pam_env/environment +++ /dev/null @@ -1,5 +0,0 @@ -# -# This file is parsed by pam_env module -# -# Syntax: simple "KEY=VAL" pairs on seperate lines -# diff --git a/modules/pam_env/pam_env.8.xml b/modules/pam_env/pam_env.8.xml deleted file mode 100644 index 731c20b2..00000000 --- a/modules/pam_env/pam_env.8.xml +++ /dev/null @@ -1,206 +0,0 @@ -<?xml version="1.0" encoding="ISO-8859-1"?> -<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN" - "http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd"> - -<refentry id='pam_env'> - - <refmeta> - <refentrytitle>pam_env</refentrytitle> - <manvolnum>8</manvolnum> - <refmiscinfo class='setdesc'>Linux-PAM Manual</refmiscinfo> - </refmeta> - - <refnamediv id='pam_env-name'> - <refname>pam_env</refname> - <refpurpose> - PAM module to set/unset environment variables - </refpurpose> - </refnamediv> - -<!-- body begins here --> - - <refsynopsisdiv> - <cmdsynopsis id="pam_env-cmdsynopsis"> - <command>pam_env.so</command> - <arg choice="opt"> - debug - </arg> - <arg choice="opt"> - conffile=<replaceable>conf-file</replaceable> - </arg> - <arg choice="opt"> - envfile=<replaceable>env-file</replaceable> - </arg> - <arg choice="opt"> - readenv=<replaceable>0|1</replaceable> - </arg> - </cmdsynopsis> - </refsynopsisdiv> - - - <refsect1 id="pam_env-description"> - <title>DESCRIPTION</title> - <para> - The pam_env PAM module allows the (un)setting of environment - variables. Supported is the use of previously set environment - variables as well as <emphasis>PAM_ITEM</emphasis>s such as - <emphasis>PAM_RHOST</emphasis>. - </para> - <para> - By default rules for (un)setting of variables is taken from the - config file <filename>/etc/security/pam_env.conf</filename> if - no other file is specified. - </para> - <para> - This module can also parse a file with simple - <emphasis>KEY=VAL</emphasis> pairs on seperate lines - (<filename>/etc/environment</filename> by default). You can - change the default file to parse, with the <emphasis>envfile</emphasis> - flag and turn it on or off by setting the <emphasis>readenv</emphasis> - flag to 1 or 0 respectively. - </para> - </refsect1> - - <refsect1 id="pam_env-options"> - <title>OPTIONS</title> - <variablelist> - - <varlistentry> - <term> - <option>conffile=<replaceable>/path/to/pam_env.conf</replaceable></option> - </term> - <listitem> - <para> - Indicate an alternative <filename>pam_env.conf</filename> - style configuration file to override the default. This can - be useful when different services need different environments. - </para> - </listitem> - </varlistentry> - - <varlistentry> - <term> - <option>debug</option> - </term> - <listitem> - <para> - A lot of debug informations are printed with - <citerefentry><refentrytitle>syslog</refentrytitle><manvolnum>3</manvolnum></citerefentry>. - </para> - </listitem> - </varlistentry> - - <varlistentry> - <term> - <option>envfile=<replaceable>/path/to/environment</replaceable></option> - </term> - <listitem> - <para> - Indicate an alternative <filename>environment</filename> - file to override the default. This can be useful when different - services need different environments. - </para> - </listitem> - </varlistentry> - - <varlistentry> - <term> - <option>readenv=<replaceable>0|1</replaceable></option> - </term> - <listitem> - <para> - Turns on or off the reading of the file specified by envfile - (0 is off, 1 is on). By default this option is on. - </para> - </listitem> - </varlistentry> - - </variablelist> - </refsect1> - - <refsect1 id="pam_env-services"> - <title>MODULE SERVICES PROVIDED</title> - <para> - The <option>auth</option> and <option>session</option> services - are supported. - </para> - </refsect1> - - <refsect1 id="pam_env-return_values"> - <title>RETURN VALUES</title> - <variablelist> - <varlistentry> - <term>PAM_ABORT</term> - <listitem> - <para> - Not all relevant data or options could be gotten. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term>PAM_BUF_ERR</term> - <listitem> - <para> - Memory buffer error. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term>PAM_IGNORE</term> - <listitem> - <para> - No pam_env.conf and environment file was found. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term>PAM_SUCCESS</term> - <listitem> - <para> - Environment variables were set. - </para> - </listitem> - </varlistentry> - </variablelist> - </refsect1> - - <refsect1 id="pam_env-files"> - <title>FILES</title> - <variablelist> - <varlistentry> - <term><filename>/etc/security/pam_env.conf</filename></term> - <listitem> - <para>Default configuration file</para> - </listitem> - </varlistentry> - <varlistentry> - <term><filename>/etc/environment</filename></term> - <listitem> - <para>Default environment file</para> - </listitem> - </varlistentry> - </variablelist> - </refsect1> - - <refsect1 id="pam_env-see_also"> - <title>SEE ALSO</title> - <para> - <citerefentry> - <refentrytitle>pam_env.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_env-authors"> - <title>AUTHOR</title> - <para> - pam_env was written by Dave Kinchlea <kinch@kinch.ark.com>. - </para> - </refsect1> -</refentry> diff --git a/modules/pam_env/pam_env.c b/modules/pam_env/pam_env.c deleted file mode 100644 index bcbb1881..00000000 --- a/modules/pam_env/pam_env.c +++ /dev/null @@ -1,832 +0,0 @@ -/* pam_env module */ - -/* - * $Id$ - * - * Written by Dave Kinchlea <kinch@kinch.ark.com> 1997/01/31 - * Inspired by Andrew Morgan <morgan@kernel.org>, who also supplied the - * template for this file (via pam_mail) - */ - -#define DEFAULT_ETC_ENVFILE "/etc/environment" -#define DEFAULT_READ_ENVFILE 1 - -#include "config.h" - -#include <ctype.h> -#include <errno.h> -#include <pwd.h> -#include <stdarg.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <syslog.h> -#include <sys/stat.h> -#include <sys/types.h> -#include <unistd.h> - -/* - * here, we make a definition for the externally accessible function - * in this file (this definition is required for static a module - * but strongly encouraged generally) it is used to instruct the - * modules include file to define the function prototypes. - */ - -#define PAM_SM_AUTH /* This is primarily a AUTH_SETCRED module */ -#define PAM_SM_SESSION /* But I like to be friendly */ -#define PAM_SM_PASSWORD /* "" */ -#define PAM_SM_ACCOUNT /* "" */ - -#include <security/pam_modules.h> -#include <security/_pam_macros.h> -#include <security/pam_ext.h> - -/* This little structure makes it easier to keep variables together */ - -typedef struct var { - char *name; - char *value; - char *defval; - char *override; -} VAR; - -#define BUF_SIZE 1024 -#define MAX_ENV 8192 - -#define GOOD_LINE 0 -#define BAD_LINE 100 /* This must be > the largest PAM_* error code */ - -#define DEFINE_VAR 101 -#define UNDEFINE_VAR 102 -#define ILLEGAL_VAR 103 - -static int _assemble_line(FILE *, char *, int); -static int _parse_line(const pam_handle_t *, char *, VAR *); -static int _check_var(pam_handle_t *, VAR *); /* This is the real meat */ -static void _clean_var(VAR *); -static int _expand_arg(pam_handle_t *, char **); -static const char * _pam_get_item_byname(pam_handle_t *, const char *); -static int _define_var(pam_handle_t *, VAR *); -static int _undefine_var(pam_handle_t *, VAR *); - -/* This is a flag used to designate an empty string */ -static char quote='Z'; - -/* argument parsing */ - -#define PAM_DEBUG_ARG 0x01 -#define PAM_NEW_CONF_FILE 0x02 -#define PAM_ENV_SILENT 0x04 -#define PAM_NEW_ENV_FILE 0x10 - -static int -_pam_parse (const pam_handle_t *pamh, int argc, const char **argv, - const char **conffile, const char **envfile, int *readenv) -{ - int ctrl=0; - - - /* step through arguments */ - for (; argc-- > 0; ++argv) { - - /* generic options */ - - if (!strcmp(*argv,"debug")) - ctrl |= PAM_DEBUG_ARG; - else if (!strncmp(*argv,"conffile=",9)) { - *conffile = 9 + *argv; - if (**conffile != '\0') { - D(("new Configuration File: %s", *conffile)); - ctrl |= PAM_NEW_CONF_FILE; - } else { - pam_syslog(pamh, LOG_ERR, - "conffile= specification missing argument - ignored"); - } - } else if (!strncmp(*argv,"envfile=",8)) { - *envfile = 8 + *argv; - if (**envfile != '\0') { - D(("new Env File: %s", *envfile)); - ctrl |= PAM_NEW_ENV_FILE; - } else { - pam_syslog (pamh, LOG_ERR, - "envfile= specification missing argument - ignored"); - } - } else if (!strncmp(*argv,"readenv=",8)) - *readenv = atoi(8+*argv); - else - pam_syslog(pamh, LOG_ERR, "unknown option: %s", *argv); - } - - return ctrl; -} - -static int -_parse_config_file(pam_handle_t *pamh, int ctrl, const char *conffile) -{ - int retval; - const char *file; - char buffer[BUF_SIZE]; - FILE *conf; - VAR Var, *var=&Var; - - var->name=NULL; var->defval=NULL; var->override=NULL; - D(("Called.")); - - if (ctrl & PAM_NEW_CONF_FILE) { - file = conffile; - } else { - file = DEFAULT_CONF_FILE; - } - - D(("Config file name is: %s", file)); - - /* - * Lets try to open the config file, parse it and process - * any variables found. - */ - - if ((conf = fopen(file,"r")) == NULL) { - pam_syslog(pamh, LOG_ERR, "Unable to open config file: %s: %m", file); - return PAM_IGNORE; - } - - /* _pam_assemble_line will provide a complete line from the config file, - * with all comments removed and any escaped newlines fixed up - */ - - while (( retval = _assemble_line(conf, buffer, BUF_SIZE)) > 0) { - D(("Read line: %s", buffer)); - - if ((retval = _parse_line(pamh, buffer, var)) == GOOD_LINE) { - retval = _check_var(pamh, var); - - if (DEFINE_VAR == retval) { - retval = _define_var(pamh, var); - - } else if (UNDEFINE_VAR == retval) { - retval = _undefine_var(pamh, var); - } - } - if (PAM_SUCCESS != retval && ILLEGAL_VAR != retval - && BAD_LINE != retval && PAM_BAD_ITEM != retval) break; - - _clean_var(var); - - } /* while */ - - (void) fclose(conf); - - /* tidy up */ - _clean_var(var); /* We could have got here prematurely, - * this is safe though */ - D(("Exit.")); - return (retval != 0 ? PAM_ABORT : PAM_SUCCESS); -} - -static int -_parse_env_file(pam_handle_t *pamh, int ctrl, const char *env_file) -{ - int retval=PAM_SUCCESS, i, t; - const char *file; - char buffer[BUF_SIZE], *key, *mark; - FILE *conf; - - if (ctrl & PAM_NEW_ENV_FILE) - file = env_file; - else - file = DEFAULT_ETC_ENVFILE; - - D(("Env file name is: %s", file)); - - if ((conf = fopen(file,"r")) == NULL) { - pam_syslog(pamh, LOG_ERR, "Unable to open env file: %s: %m", file); - return PAM_IGNORE; - } - - while (_assemble_line(conf, buffer, BUF_SIZE) > 0) { - D(("Read line: %s", buffer)); - key = buffer; - - /* skip leading white space */ - key += strspn(key, " \n\t"); - - /* skip blanks lines and comments */ - if (!key || key[0] == '#') - continue; - - /* skip over "export " if present so we can be compat with - bash type declarations */ - if (strncmp(key, "export ", (size_t) 7) == 0) - key += 7; - - /* now find the end of value */ - mark = key; - while(mark[0] != '\n' && mark[0] != '#' && mark[0] != '\0') - mark++; - if (mark[0] != '\0') - mark[0] = '\0'; - - /* - * sanity check, the key must be alpha-numeric - */ - - for ( i = 0 ; key[i] != '=' && key[i] != '\0' ; i++ ) - if (!isalnum(key[i]) && key[i] != '_') { - D(("key is not alpha numeric - '%s', ignoring", key)); - continue; - } - - /* now we try to be smart about quotes around the value, - but not too smart, we can't get all fancy with escaped - values like bash */ - if (key[i] == '=' && (key[++i] == '\"' || key[i] == '\'')) { - for ( t = i+1 ; key[t] != '\0' ; t++) - if (key[t] != '\"' && key[t] != '\'') - key[i++] = key[t]; - else if (key[t+1] != '\0') - key[i++] = key[t]; - key[i] = '\0'; - } - - /* set the env var, if it fails, we break out of the loop */ - retval = pam_putenv(pamh, key); - if (retval != PAM_SUCCESS) { - D(("error setting env \"%s\"", key)); - break; - } - } - - (void) fclose(conf); - - /* tidy up */ - D(("Exit.")); - return retval; -} - -/* - * This is where we read a line of the PAM config file. The line may be - * preceeded by lines of comments and also extended with "\\\n" - */ - -static int _assemble_line(FILE *f, char *buffer, int buf_len) -{ - char *p = buffer; - char *s, *os; - int used = 0; - - /* loop broken with a 'break' when a non-'\\n' ended line is read */ - - D(("called.")); - for (;;) { - if (used >= buf_len) { - /* Overflow */ - D(("_assemble_line: overflow")); - return -1; - } - if (fgets(p, buf_len - used, f) == NULL) { - if (used) { - /* Incomplete read */ - return -1; - } else { - /* EOF */ - return 0; - } - } - - /* skip leading spaces --- line may be blank */ - - s = p + strspn(p, " \n\t"); - if (*s && (*s != '#')) { - os = s; - - /* - * we are only interested in characters before the first '#' - * character - */ - - while (*s && *s != '#') - ++s; - if (*s == '#') { - *s = '\0'; - used += strlen(os); - break; /* the line has been read */ - } - - s = os; - - /* - * Check for backslash by scanning back from the end of - * the entered line, the '\n' has been included since - * normally a line is terminated with this - * character. fgets() should only return one though! - */ - - s += strlen(s); - while (s > os && ((*--s == ' ') || (*s == '\t') - || (*s == '\n'))); - - /* check if it ends with a backslash */ - if (*s == '\\') { - *s = '\0'; /* truncate the line here */ - used += strlen(os); - p = s; /* there is more ... */ - } else { - /* End of the line! */ - used += strlen(os); - break; /* this is the complete line */ - } - - } else { - /* Nothing in this line */ - /* Don't move p */ - } - } - - return used; -} - -static int -_parse_line (const pam_handle_t *pamh, char *buffer, VAR *var) -{ - /* - * parse buffer into var, legal syntax is - * VARIABLE [DEFAULT=[[string]] [OVERRIDE=[value]] - * - * Any other options defined make this a bad line, - * error logged and no var set - */ - - int length, quoteflg=0; - char *ptr, **valptr, *tmpptr; - - D(("Called buffer = <%s>", buffer)); - - length = strcspn(buffer," \t\n"); - - if ((var->name = malloc(length + 1)) == NULL) { - pam_syslog(pamh, LOG_ERR, "Couldn't malloc %d bytes", length+1); - return PAM_BUF_ERR; - } - - /* - * The first thing on the line HAS to be the variable name, - * it may be the only thing though. - */ - strncpy(var->name, buffer, length); - var->name[length] = '\0'; - D(("var->name = <%s>, length = %d", var->name, length)); - - /* - * Now we check for arguments, we only support two kinds and ('cause I am lazy) - * each one can actually be listed any number of times - */ - - ptr = buffer+length; - while ((length = strspn(ptr, " \t")) > 0) { - ptr += length; /* remove leading whitespace */ - D((ptr)); - if (strncmp(ptr,"DEFAULT=",8) == 0) { - ptr+=8; - D(("Default arg found: <%s>", ptr)); - valptr=&(var->defval); - } else if (strncmp(ptr, "OVERRIDE=", 9) == 0) { - ptr+=9; - D(("Override arg found: <%s>", ptr)); - valptr=&(var->override); - } else { - D(("Unrecognized options: <%s> - ignoring line", ptr)); - pam_syslog(pamh, LOG_ERR, "Unrecognized Option: %s - ignoring line", ptr); - return BAD_LINE; - } - - if ('"' != *ptr) { /* Escaped quotes not supported */ - length = strcspn(ptr, " \t\n"); - tmpptr = ptr+length; - } else { - tmpptr = strchr(++ptr, '"'); - if (!tmpptr) { - D(("Unterminated quoted string: %s", ptr-1)); - pam_syslog(pamh, LOG_ERR, "Unterminated quoted string: %s", ptr-1); - return BAD_LINE; - } - length = tmpptr - ptr; - if (*++tmpptr && ' ' != *tmpptr && '\t' != *tmpptr && '\n' != *tmpptr) { - D(("Quotes must cover the entire string: <%s>", ptr)); - pam_syslog(pamh, LOG_ERR, "Quotes must cover the entire string: <%s>", ptr); - return BAD_LINE; - } - quoteflg++; - } - if (length) { - if ((*valptr = malloc(length + 1)) == NULL) { - D(("Couldn't malloc %d bytes", length+1)); - pam_syslog(pamh, LOG_ERR, "Couldn't malloc %d bytes", length+1); - return PAM_BUF_ERR; - } - (void)strncpy(*valptr,ptr,length); - (*valptr)[length]='\0'; - } else if (quoteflg--) { - *valptr = "e; /* a quick hack to handle the empty string */ - } - ptr = tmpptr; /* Start the search where we stopped */ - } /* while */ - - /* - * The line is parsed, all is well. - */ - - D(("Exit.")); - ptr = NULL; tmpptr = NULL; valptr = NULL; - return GOOD_LINE; -} - -static int _check_var(pam_handle_t *pamh, VAR *var) -{ - /* - * Examine the variable and determine what action to take. - * Returns DEFINE_VAR, UNDEFINE_VAR depending on action to take - * or a PAM_* error code if passed back from other routines - * - * if no DEFAULT provided, the empty string is assumed - * if no OVERRIDE provided, the empty string is assumed - * if DEFAULT= and OVERRIDE evaluates to the empty string, - * this variable should be undefined - * if DEFAULT="" and OVERRIDE evaluates to the empty string, - * this variable should be defined with no value - * if OVERRIDE=value and value turns into the empty string, DEFAULT is used - * - * If DEFINE_VAR is to be returned, the correct value to define will - * be pointed to by var->value - */ - - int retval; - - D(("Called.")); - - /* - * First thing to do is to expand any arguments, but only - * if they are not the special quote values (cause expand_arg - * changes memory). - */ - - if (var->defval && ("e != var->defval) && - ((retval = _expand_arg(pamh, &(var->defval))) != PAM_SUCCESS)) { - return retval; - } - if (var->override && ("e != var->override) && - ((retval = _expand_arg(pamh, &(var->override))) != PAM_SUCCESS)) { - return retval; - } - - /* Now its easy */ - - if (var->override && *(var->override) && "e != var->override) { - /* if there is a non-empty string in var->override, we use it */ - D(("OVERRIDE variable <%s> being used: <%s>", var->name, var->override)); - var->value = var->override; - retval = DEFINE_VAR; - } else { - - var->value = var->defval; - if ("e == var->defval) { - /* - * This means that the empty string was given for defval value - * which indicates that a variable should be defined with no value - */ - *var->defval = '\0'; - D(("An empty variable: <%s>", var->name)); - retval = DEFINE_VAR; - } else if (var->defval) { - D(("DEFAULT variable <%s> being used: <%s>", var->name, var->defval)); - retval = DEFINE_VAR; - } else { - D(("UNDEFINE variable <%s>", var->name)); - retval = UNDEFINE_VAR; - } - } - - D(("Exit.")); - return retval; -} - -static int _expand_arg(pam_handle_t *pamh, char **value) -{ - const char *orig=*value, *tmpptr=NULL; - char *ptr; /* - * Sure would be nice to use tmpptr but it needs to be - * a constant so that the compiler will shut up when I - * call pam_getenv and _pam_get_item_byname -- sigh - */ - - /* No unexpanded variable can be bigger than BUF_SIZE */ - char type, tmpval[BUF_SIZE]; - - /* I know this shouldn't be hard-coded but it's so much easier this way */ - char tmp[MAX_ENV]; - - D(("Remember to initialize tmp!")); - memset(tmp, 0, MAX_ENV); - - /* - * (possibly non-existent) environment variables can be used as values - * by prepending a "$" and wrapping in {} (ie: ${HOST}), can escape with "\" - * (possibly non-existent) PAM items can be used as values - * by prepending a "@" and wrapping in {} (ie: @{PAM_RHOST}, can escape - * - */ - D(("Expanding <%s>",orig)); - while (*orig) { /* while there is some input to deal with */ - if ('\\' == *orig) { - ++orig; - if ('$' != *orig && '@' != *orig) { - D(("Unrecognized escaped character: <%c> - ignoring", *orig)); - pam_syslog(pamh, LOG_ERR, - "Unrecognized escaped character: <%c> - ignoring", - *orig); - } else if ((strlen(tmp) + 1) < MAX_ENV) { - tmp[strlen(tmp)] = *orig++; /* Note the increment */ - } else { - /* is it really a good idea to try to log this? */ - D(("Variable buffer overflow: <%s> + <%s>", tmp, tmpptr)); - pam_syslog (pamh, LOG_ERR, "Variable buffer overflow: <%s> + <%s>", - tmp, tmpptr); - } - continue; - } - if ('$' == *orig || '@' == *orig) { - if ('{' != *(orig+1)) { - D(("Expandable variables must be wrapped in {}" - " <%s> - ignoring", orig)); - pam_syslog(pamh, LOG_ERR, "Expandable variables must be wrapped in {}" - " <%s> - ignoring", orig); - if ((strlen(tmp) + 1) < MAX_ENV) { - tmp[strlen(tmp)] = *orig++; /* Note the increment */ - } - continue; - } else { - D(("Expandable argument: <%s>", orig)); - type = *orig; - orig+=2; /* skip the ${ or @{ characters */ - ptr = strchr(orig, '}'); - if (ptr) { - *ptr++ = '\0'; - } else { - D(("Unterminated expandable variable: <%s>", orig-2)); - pam_syslog(pamh, LOG_ERR, - "Unterminated expandable variable: <%s>", orig-2); - return PAM_ABORT; - } - strncpy(tmpval, orig, sizeof(tmpval)); - tmpval[sizeof(tmpval)-1] = '\0'; - orig=ptr; - /* - * so, we know we need to expand tmpval, it is either - * an environment variable or a PAM_ITEM. type will tell us which - */ - switch (type) { - - case '$': - D(("Expanding env var: <%s>",tmpval)); - tmpptr = pam_getenv(pamh, tmpval); - D(("Expanded to <%s>", tmpptr)); - break; - - case '@': - D(("Expanding pam item: <%s>",tmpval)); - tmpptr = _pam_get_item_byname(pamh, tmpval); - D(("Expanded to <%s>", tmpptr)); - break; - - default: - D(("Impossible error, type == <%c>", type)); - pam_syslog(pamh, LOG_CRIT, "Impossible error, type == <%c>", type); - return PAM_ABORT; - } /* switch */ - - if (tmpptr) { - if ((strlen(tmp) + strlen(tmpptr)) < MAX_ENV) { - strcat(tmp, tmpptr); - } else { - /* is it really a good idea to try to log this? */ - D(("Variable buffer overflow: <%s> + <%s>", tmp, tmpptr)); - pam_syslog (pamh, LOG_ERR, - "Variable buffer overflow: <%s> + <%s>", tmp, tmpptr); - } - } - } /* if ('{' != *orig++) */ - } else { /* if ( '$' == *orig || '@' == *orig) */ - if ((strlen(tmp) + 1) < MAX_ENV) { - tmp[strlen(tmp)] = *orig++; /* Note the increment */ - } else { - /* is it really a good idea to try to log this? */ - D(("Variable buffer overflow: <%s> + <%s>", tmp, tmpptr)); - pam_syslog(pamh, LOG_ERR, - "Variable buffer overflow: <%s> + <%s>", tmp, tmpptr); - } - } - } /* for (;*orig;) */ - - if (strlen(tmp) > strlen(*value)) { - free(*value); - if ((*value = malloc(strlen(tmp) +1)) == NULL) { - D(("Couldn't malloc %d bytes for expanded var", strlen(tmp)+1)); - pam_syslog (pamh, LOG_ERR, "Couldn't malloc %lu bytes for expanded var", - (unsigned long)strlen(tmp)+1); - return PAM_BUF_ERR; - } - } - strcpy(*value, tmp); - memset(tmp,'\0',sizeof(tmp)); - D(("Exit.")); - - return PAM_SUCCESS; -} - -static const char * _pam_get_item_byname(pam_handle_t *pamh, const char *name) -{ - /* - * This function just allows me to use names as given in the config - * file and translate them into the appropriate PAM_ITEM macro - */ - - int item; - const void *itemval; - - D(("Called.")); - if (strcmp(name, "PAM_USER") == 0) { - item = PAM_USER; - } else if (strcmp(name, "PAM_USER_PROMPT") == 0) { - item = PAM_USER_PROMPT; - } else if (strcmp(name, "PAM_TTY") == 0) { - item = PAM_TTY; - } else if (strcmp(name, "PAM_RUSER") == 0) { - item = PAM_RUSER; - } else if (strcmp(name, "PAM_RHOST") == 0) { - item = PAM_RHOST; - } else { - D(("Unknown PAM_ITEM: <%s>", name)); - pam_syslog (pamh, LOG_ERR, "Unknown PAM_ITEM: <%s>", name); - return NULL; - } - - if (pam_get_item(pamh, item, &itemval) != PAM_SUCCESS) { - D(("pam_get_item failed")); - return NULL; /* let pam_get_item() log the error */ - } - D(("Exit.")); - return itemval; -} - -static int _define_var(pam_handle_t *pamh, VAR *var) -{ - /* We have a variable to define, this is a simple function */ - - char *envvar; - int retval = PAM_SUCCESS; - - D(("Called.")); - if (asprintf(&envvar, "%s=%s", var->name, var->value) < 0) { - pam_syslog(pamh, LOG_ERR, "out of memory"); - return PAM_BUF_ERR; - } - - retval = pam_putenv(pamh, envvar); - _pam_drop(envvar); - D(("Exit.")); - return retval; -} - -static int _undefine_var(pam_handle_t *pamh, VAR *var) -{ - /* We have a variable to undefine, this is a simple function */ - - D(("Called and exit.")); - return pam_putenv(pamh, var->name); -} - -static void _clean_var(VAR *var) -{ - if (var->name) { - free(var->name); - } - if (var->defval && ("e != var->defval)) { - free(var->defval); - } - if (var->override && ("e != var->override)) { - free(var->override); - } - var->name = NULL; - var->value = NULL; /* never has memory specific to it */ - var->defval = NULL; - var->override = NULL; - return; -} - - - -/* --- authentication management functions (only) --- */ - -PAM_EXTERN int -pam_sm_authenticate (pam_handle_t *pamh UNUSED, int flags UNUSED, - int argc UNUSED, const char **argv UNUSED) -{ - return PAM_IGNORE; -} - -PAM_EXTERN int -pam_sm_setcred (pam_handle_t *pamh, int flags UNUSED, - int argc, const char **argv) -{ - int retval, ctrl, readenv=DEFAULT_READ_ENVFILE; - const char *conf_file = NULL, *env_file = NULL; - - /* - * this module sets environment variables read in from a file - */ - - D(("Called.")); - ctrl = _pam_parse(pamh, argc, argv, &conf_file, &env_file, &readenv); - - retval = _parse_config_file(pamh, ctrl, conf_file); - - if(readenv && retval == PAM_SUCCESS) { - retval = _parse_env_file(pamh, ctrl, env_file); - if (retval == PAM_IGNORE) - retval = PAM_SUCCESS; - } - - /* indicate success or failure */ - - D(("Exit.")); - return retval; -} - -PAM_EXTERN int -pam_sm_acct_mgmt (pam_handle_t *pamh UNUSED, int flags UNUSED, - int argc UNUSED, const char **argv UNUSED) -{ - pam_syslog (pamh, LOG_NOTICE, "pam_sm_acct_mgmt called inappropriately"); - return PAM_SERVICE_ERR; -} - -PAM_EXTERN int -pam_sm_open_session (pam_handle_t *pamh, int flags UNUSED, - int argc, const char **argv) -{ - int retval, ctrl, readenv=DEFAULT_READ_ENVFILE; - const char *conf_file = NULL, *env_file = NULL; - - /* - * this module sets environment variables read in from a file - */ - - D(("Called.")); - ctrl = _pam_parse(pamh, argc, argv, &conf_file, &env_file, &readenv); - - retval = _parse_config_file(pamh, ctrl, conf_file); - - if(readenv && retval == PAM_SUCCESS) { - retval = _parse_env_file(pamh, ctrl, env_file); - if (retval == PAM_IGNORE) - retval = PAM_SUCCESS; - } - - /* indicate success or failure */ - - D(("Exit.")); - return retval; -} - -PAM_EXTERN int -pam_sm_close_session (pam_handle_t *pamh UNUSED, int flags UNUSED, - int argc UNUSED, const char **argv UNUSED) -{ - D(("Called and Exit")); - return PAM_SUCCESS; -} - -PAM_EXTERN int -pam_sm_chauthtok (pam_handle_t *pamh UNUSED, int flags UNUSED, - int argc UNUSED, const char **argv UNUSED) -{ - pam_syslog (pamh, LOG_NOTICE, "pam_sm_chauthtok called inappropriately"); - return PAM_SERVICE_ERR; -} - -#ifdef PAM_STATIC - -/* static module data */ - -struct pam_module _pam_env_modstruct = { - "pam_env", - pam_sm_authenticate, - pam_sm_setcred, - pam_sm_acct_mgmt, - pam_sm_open_session, - pam_sm_close_session, - pam_sm_chauthtok, -}; - -#endif - -/* end of module definition */ diff --git a/modules/pam_env/pam_env.conf b/modules/pam_env/pam_env.conf deleted file mode 100644 index d0ba35c2..00000000 --- a/modules/pam_env/pam_env.conf +++ /dev/null @@ -1,73 +0,0 @@ -# -# This is the configuration file for pam_env, a PAM module to load in -# a configurable list of environment variables for a -# -# The original idea for this came from Andrew G. Morgan ... -#<quote> -# Mmm. Perhaps you might like to write a pam_env module that reads a -# default environment from a file? I can see that as REALLY -# useful... Note it would be an "auth" module that returns PAM_IGNORE -# for the auth part and sets the environment returning PAM_SUCCESS in -# the setcred function... -#</quote> -# -# What I wanted was the REMOTEHOST variable set, purely for selfish -# reasons, and AGM didn't want it added to the SimpleApps login -# program (which is where I added the patch). So, my first concern is -# that variable, from there there are numerous others that might/would -# be useful to be set: NNTPSERVER, LESS, PATH, PAGER, MANPAGER ..... -# -# Of course, these are a different kind of variable than REMOTEHOST in -# that they are things that are likely to be configured by -# administrators rather than set by logging in, how to treat them both -# in the same config file? -# -# Here is my idea: -# -# Each line starts with the variable name, there are then two possible -# options for each variable DEFAULT and OVERRIDE. -# DEFAULT allows and administrator to set the value of the -# variable to some default value, if none is supplied then the empty -# string is assumed. The OVERRIDE option tells pam_env that it should -# enter in its value (overriding the default value) if there is one -# to use. OVERRIDE is not used, "" is assumed and no override will be -# done. -# -# VARIABLE [DEFAULT=[value]] [OVERRIDE=[value]] -# -# (Possibly non-existent) environment variables may be used in values -# using the ${string} syntax and (possibly non-existent) PAM_ITEMs may -# be used in values using the @{string} syntax. Both the $ and @ -# characters can be backslash escaped to be used as literal values -# values can be delimited with "", escaped " not supported. -# Note that many environment variables that you would like to use -# may not be set by the time the module is called. -# For example, HOME is used below several times, but -# many PAM applications don't make it available by the time you need it. -# -# -# First, some special variables -# -# Set the REMOTEHOST variable for any hosts that are remote, default -# to "localhost" rather than not being set at all -#REMOTEHOST DEFAULT=localhost OVERRIDE=@{PAM_RHOST} -# -# Set the DISPLAY variable if it seems reasonable -#DISPLAY DEFAULT=${REMOTEHOST}:0.0 OVERRIDE=${DISPLAY} -# -# -# Now some simple variables -# -#PAGER DEFAULT=less -#MANPAGER DEFAULT=less -#LESS DEFAULT="M q e h15 z23 b80" -#NNTPSERVER DEFAULT=localhost -#PATH DEFAULT=${HOME}/bin:/usr/local/bin:/bin\ -#:/usr/bin:/usr/local/bin/X11:/usr/bin/X11 -# -# silly examples of escaped variables, just to show how they work. -# -#DOLLAR DEFAULT=\$ -#DOLLARDOLLAR DEFAULT= OVERRIDE=\$${DOLLAR} -#DOLLARPLUS DEFAULT=\${REMOTEHOST}${REMOTEHOST} -#ATSIGN DEFAULT="" OVERRIDE=\@ diff --git a/modules/pam_env/pam_env.conf.5.xml b/modules/pam_env/pam_env.conf.5.xml deleted file mode 100644 index 090e0e75..00000000 --- a/modules/pam_env/pam_env.conf.5.xml +++ /dev/null @@ -1,123 +0,0 @@ -<?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_env.conf"> - - <refmeta> - <refentrytitle>pam_env.conf</refentrytitle> - <manvolnum>5</manvolnum> - <refmiscinfo class="sectdesc">Linux-PAM Manual</refmiscinfo> - </refmeta> - - <refnamediv> - <refname>pam_env.conf</refname> - <refpurpose>the environment variables config file</refpurpose> - </refnamediv> - - - <refsect1 id='pam_env.conf-description'> - <title>DESCRIPTION</title> - - <para> - The <filename>/etc/security/pam_env.conf</filename> file specifies - the environment variables to be set, unset or modified by - <citerefentry><refentrytitle>pam_env</refentrytitle><manvolnum>8</manvolnum></citerefentry>. - When someone logs in, this file is read and the environment - variables are set according. - </para> - <para> - Each line starts with the variable name, there are then two possible - options for each variable DEFAULT and OVERRIDE. DEFAULT allows and - administrator to set the value of the variable to some default - value, if none is supplied then the empty string is assumed. The - OVERRIDE option tells pam_env that it should enter in its value - (overriding the default value) if there is one to use. OVERRIDE is - not used, "" is assumed and no override will be done. - </para> - <para> - <replaceable>VARIABLE</replaceable> - [<replaceable>DEFAULT=[value]</replaceable>] - [<replaceable>OVERRIDE=[value]</replaceable>] - </para> - - <para> - (Possibly non-existent) environment variables may be used in values - using the ${string} syntax and (possibly non-existent) PAM_ITEMs may - be used in values using the @{string} syntax. Both the $ and @ - characters can be backslash escaped to be used as literal values - values can be delimited with "", escaped " not supported. - Note that many environment variables that you would like to use - may not be set by the time the module is called. - For example, HOME is used below several times, but - many PAM applications don't make it available by the time you need it. - </para> - - <para> - The "<emphasis>#</emphasis>" character at start of line (no space - at front) can be used to mark this line as a comment line. - </para> - - </refsect1> - - <refsect1 id="pam_env.conf-examples"> - <title>EXAMPLES</title> - <para> - These are some example lines which might be specified in - <filename>/etc/security/pam_env.conf</filename>. - </para> - - <para> - Set the REMOTEHOST variable for any hosts that are remote, default - to "localhost" rather than not being set at all - </para> - <programlisting> - REMOTEHOST DEFAULT=localhost OVERRIDE=@{PAM_RHOST} - </programlisting> - - <para> - Set the DISPLAY variable if it seems reasonable - </para> - <programlisting> - DISPLAY DEFAULT=${REMOTEHOST}:0.0 OVERRIDE=${DISPLAY} - </programlisting> - - <para> - Now some simple variables - </para> - <programlisting> - PAGER DEFAULT=less - MANPAGER DEFAULT=less - LESS DEFAULT="M q e h15 z23 b80" - NNTPSERVER DEFAULT=localhost - PATH DEFAULT=${HOME}/bin:/usr/local/bin:/bin\ - :/usr/bin:/usr/local/bin/X11:/usr/bin/X11 - </programlisting> - - <para> - Silly examples of escaped variables, just to show how they work. - </para> - <programlisting> - DOLLAR DEFAULT=\$ - DOLLARDOLLAR DEFAULT= OVERRIDE=\$${DOLLAR} - DOLLARPLUS DEFAULT=\${REMOTEHOST}${REMOTEHOST} - ATSIGN DEFAULT="" OVERRIDE=\@ - </programlisting> - </refsect1> - - <refsect1 id="pam_env.conf-see_also"> - <title>SEE ALSO</title> - <para> - <citerefentry><refentrytitle>pam_env</refentrytitle><manvolnum>8</manvolnum></citerefentry>, - <citerefentry><refentrytitle>pam.d</refentrytitle><manvolnum>5</manvolnum></citerefentry>, - <citerefentry><refentrytitle>pam</refentrytitle><manvolnum>8</manvolnum></citerefentry> - </para> - </refsect1> - - <refsect1 id="pam_env.conf-author"> - <title>AUTHOR</title> - <para> - pam_env was written by Dave Kinchlea <kinch@kinch.ark.com>. - </para> - </refsect1> -</refentry> diff --git a/modules/pam_env/tst-pam_env b/modules/pam_env/tst-pam_env deleted file mode 100755 index c40e70a8..00000000 --- a/modules/pam_env/tst-pam_env +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/sh -../../tests/tst-dlopen .libs/pam_env.so diff --git a/modules/pam_exec/.cvsignore b/modules/pam_exec/.cvsignore deleted file mode 100644 index 47c8610e..00000000 --- a/modules/pam_exec/.cvsignore +++ /dev/null @@ -1,8 +0,0 @@ -*.la -*.lo -.deps -.libs -Makefile -Makefile.in -README -pam_exec.8 diff --git a/modules/pam_exec/Makefile.am b/modules/pam_exec/Makefile.am deleted file mode 100644 index 55fe9297..00000000 --- a/modules/pam_exec/Makefile.am +++ /dev/null @@ -1,34 +0,0 @@ -# -# Copyright (c) 2006 Thorsten Kukuk <kukuk@suse.de> -# - -CLEANFILES = *~ - -EXTRA_DIST = README $(MANS) $(XMLS) tst-pam_exec - -man_MANS = pam_exec.8 - -XMLS = README.xml pam_exec.8.xml - -securelibdir = $(SECUREDIR) -secureconfdir = $(SCONFIGDIR) - -AM_CFLAGS = -I$(top_srcdir)/libpam/include -I$(top_srcdir)/libpamc/include -AM_LDFLAGS = -no-undefined -avoid-version -module -if HAVE_VERSIONING - AM_LDFLAGS += -Wl,--version-script=$(srcdir)/../modules.map -endif - -securelib_LTLIBRARIES = pam_exec.la -pam_exec_la_LIBADD = -L$(top_builddir)/libpam -lpam - -if ENABLE_REGENERATE_MAN - -noinst_DATA = README - -README: pam_exec.8.xml - --include $(top_srcdir)/Make.xml.rules -endif - -TESTS = tst-pam_exec diff --git a/modules/pam_exec/README.xml b/modules/pam_exec/README.xml deleted file mode 100644 index 5e76cab3..00000000 --- a/modules/pam_exec/README.xml +++ /dev/null @@ -1,41 +0,0 @@ -<?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_exec.8.xml"> ---> -]> - -<article> - - <articleinfo> - - <title> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" - href="pam_exec.8.xml" xpointer='xpointer(//refnamediv[@id = "pam_exec-name"]/*)'/> - </title> - - </articleinfo> - - <section> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" - href="pam_exec.8.xml" xpointer='xpointer(//refsect1[@id = "pam_exec-description"]/*)'/> - </section> - - <section> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" - href="pam_exec.8.xml" xpointer='xpointer(//refsect1[@id = "pam_exec-options"]/*)'/> - </section> - - <section> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" - href="pam_exec.8.xml" xpointer='xpointer(//refsect1[@id = "pam_exec-examples"]/*)'/> - </section> - - <section> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" - href="pam_exec.8.xml" xpointer='xpointer(//refsect1[@id = "pam_exec-author"]/*)'/> - </section> - -</article> diff --git a/modules/pam_exec/pam_exec.8.xml b/modules/pam_exec/pam_exec.8.xml deleted file mode 100644 index f4dc1e15..00000000 --- a/modules/pam_exec/pam_exec.8.xml +++ /dev/null @@ -1,217 +0,0 @@ -<?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_exec"> - - <refmeta> - <refentrytitle>pam_exec</refentrytitle> - <manvolnum>8</manvolnum> - <refmiscinfo class="sectdesc">Linux-PAM Manual</refmiscinfo> - </refmeta> - - <refnamediv id="pam_exec-name"> - <refname>pam_exec</refname> - <refpurpose>PAM module which calls an external command</refpurpose> - </refnamediv> - - <refsynopsisdiv> - <cmdsynopsis id="pam_exec-cmdsynopsis"> - <command>pam_exec.so</command> - <arg choice="opt"> - debug - </arg> - <arg choice="opt"> - seteuid - </arg> - <arg choice="opt"> - quiet - </arg> - <arg choice="opt"> - log=<replaceable>file</replaceable> - </arg> - <arg choice="plain"> - <replaceable>command</replaceable> - </arg> - <arg choice="opt"> - <replaceable>...</replaceable> - </arg> - </cmdsynopsis> - </refsynopsisdiv> - - <refsect1 id="pam_exec-description"> - - <title>DESCRIPTION</title> - - <para> - pam_exec is a PAM module that can be used to run - an external command. - </para> - - <para> - The child's environment is set to the current PAM environment list, as - returned by - <citerefentry> - <refentrytitle>pam_getenvlist</refentrytitle><manvolnum>3</manvolnum> - </citerefentry> - In addition, the following PAM items are - exported as environment variables: <emphasis>PAM_RHOST</emphasis>, - <emphasis>PAM_RUSER</emphasis>, <emphasis>PAM_SERVICE</emphasis>, - <emphasis>PAM_TTY</emphasis>, and <emphasis>PAM_USER</emphasis>. - </para> - - </refsect1> - - <refsect1 id="pam_exec-options"> - - <title>OPTIONS</title> - <para> - <variablelist> - - <varlistentry> - <term> - <option>debug</option> - </term> - <listitem> - <para> - Print debug information. - </para> - </listitem> - </varlistentry> - - <varlistentry> - <term> - <option>log=<replaceable>file</replaceable></option> - </term> - <listitem> - <para> - The output of the command is appended to - <filename>file</filename> - </para> - </listitem> - </varlistentry> - - <varlistentry> - <term> - <option>quiet</option> - </term> - <listitem> - <para> - Per default pam_exec.so will echo the exit status of the - external command if it fails. - Specifying this option will suppress the message. - </para> - </listitem> - </varlistentry> - - <varlistentry> - <term> - <option>seteuid</option> - </term> - <listitem> - <para> - Per default pam_exec.so will execute the external command - with the real user ID of the calling process. - Specifying this option means the command is run - with the effective user ID. - </para> - </listitem> - </varlistentry> - - </variablelist> - - </para> - </refsect1> - - <refsect1 id="pam_exec-services"> - <title>MODULE SERVICES PROVIDED</title> - <para> - The services <option>auth</option>, <option>account</option>, - <option>password</option> and <option>session</option> are supported. - </para> - </refsect1> - - <refsect1 id='pam_exec-return_values'> - <title>RETURN VALUES</title> - <para> - <variablelist> - - <varlistentry> - <term>PAM_SUCCESS</term> - <listitem> - <para> - The external command runs successfull. - </para> - </listitem> - </varlistentry> - - <varlistentry> - <term>PAM_SERVICE_ERR</term> - <listitem> - <para> - No argument or a wrong number of arguments were given. - </para> - </listitem> - </varlistentry> - - <varlistentry> - <term>PAM_SYSTEM_ERR</term> - <listitem> - <para> - A system error occured or the command to execute failed. - </para> - </listitem> - </varlistentry> - - <varlistentry> - <term>PAM_IGNORE</term> - <listitem> - <para> - <function>pam_setcred</function> was called, which - does not execute the command. - </para> - </listitem> - </varlistentry> - - </variablelist> - </para> - </refsect1> - - <refsect1 id='pam_exec-examples'> - <title>EXAMPLES</title> - <para> - Add the following line to <filename>/etc/pam.d/passwd</filename> to - rebuild the NIS database after each local password change: - <programlisting> - passwd optional pam_exec.so seteuid make -C /var/yp - </programlisting> - - This will execute the command - <programlisting>make -C /var/yp</programlisting> - with effective user ID. - </para> - </refsect1> - - <refsect1 id='pam_exec-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_exec-author'> - <title>AUTHOR</title> - <para> - pam_exec was written by Thorsten Kukuk <kukuk@thkukuk.de>. - </para> - </refsect1> - -</refentry> diff --git a/modules/pam_exec/pam_exec.c b/modules/pam_exec/pam_exec.c deleted file mode 100644 index 766c0a06..00000000 --- a/modules/pam_exec/pam_exec.c +++ /dev/null @@ -1,342 +0,0 @@ -/* - * Copyright (c) 2006 Thorsten Kukuk <kukuk@thkukuk.de> - * - * 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. - */ - -#if defined(HAVE_CONFIG_H) -#include "config.h" -#endif - -#include <time.h> -#include <errno.h> -#include <fcntl.h> -#include <stdio.h> -#include <string.h> -#include <syslog.h> -#include <unistd.h> -#include <stdlib.h> -#include <sys/wait.h> -#include <sys/stat.h> -#include <sys/types.h> - - -#define PAM_SM_AUTH -#define PAM_SM_ACCOUNT -#define PAM_SM_SESSION -#define PAM_SM_PASSWORD - -#include <security/pam_modules.h> -#include <security/pam_modutil.h> -#include <security/pam_ext.h> - -#define ENV_ITEM(n) { (n), #n } -static struct { - int item; - const char *name; -} env_items[] = { - ENV_ITEM(PAM_SERVICE), - ENV_ITEM(PAM_USER), - ENV_ITEM(PAM_TTY), - ENV_ITEM(PAM_RHOST), - ENV_ITEM(PAM_RUSER), -}; - -static int -call_exec (pam_handle_t *pamh, int argc, const char **argv) -{ - int debug = 0; - int call_setuid = 0; - int quiet = 0; - int optargc; - const char *logfile = NULL; - pid_t pid; - - if (argc < 1) { - pam_syslog (pamh, LOG_ERR, - "This module needs at least one argument"); - return PAM_SERVICE_ERR; - } - - for (optargc = 0; optargc < argc; optargc++) - { - if (argv[optargc][0] == '/') /* paths starts with / */ - break; - - if (strcasecmp (argv[optargc], "debug") == 0) - debug = 1; - else if (strncasecmp (argv[optargc], "log=", 4) == 0) - logfile = &argv[optargc][4]; - else if (strcasecmp (argv[optargc], "seteuid") == 0) - call_setuid = 1; - else if (strcasecmp (argv[optargc], "quiet") == 0) - quiet = 1; - else - break; /* Unknown option, assume program to execute. */ - } - - - if (optargc >= argc) { - pam_syslog (pamh, LOG_ERR, "No path given as argument"); - return PAM_SERVICE_ERR; - } - - pid = fork(); - if (pid == -1) - return PAM_SYSTEM_ERR; - if (pid > 0) /* parent */ - { - int status = 0; - pid_t retval; - while ((retval = waitpid (pid, &status, 0)) == -1 && - errno == EINTR); - if (retval == (pid_t)-1) - { - pam_syslog (pamh, LOG_ERR, "waitpid returns with -1: %m"); - return PAM_SYSTEM_ERR; - } - else if (status != 0) - { - if (WIFEXITED(status)) - { - pam_syslog (pamh, LOG_ERR, "%s failed: exit code %d", - argv[optargc], WEXITSTATUS(status)); - if (!quiet) - pam_error (pamh, _("%s failed: exit code %d"), - argv[optargc], WEXITSTATUS(status)); - } - else if (WIFSIGNALED(status)) - { - pam_syslog (pamh, LOG_ERR, "%s failed: caught signal %d%s", - argv[optargc], WTERMSIG(status), - WCOREDUMP(status) ? " (core dumped)" : ""); - if (!quiet) - pam_error (pamh, _("%s failed: caught signal %d%s"), - argv[optargc], WTERMSIG(status), - WCOREDUMP(status) ? " (core dumped)" : ""); - } - else - { - pam_syslog (pamh, LOG_ERR, "%s failed: unknown status 0x%x", - argv[optargc], status); - if (!quiet) - pam_error (pamh, _("%s failed: unknown status 0x%x"), - argv[optargc], status); - } - return PAM_SYSTEM_ERR; - } - return PAM_SUCCESS; - } - else /* child */ - { - char **arggv; - int i; - - for (i = 0; i < sysconf (_SC_OPEN_MAX); i++) - close (i); - - /* New stdin. */ - if ((i = open ("/dev/null", O_RDWR)) < 0) - { - int err = errno; - pam_syslog (pamh, LOG_ERR, "open of /dev/null failed: %m"); - exit (err); - } - /* New stdout and stderr. */ - if (logfile) - { - time_t tm = time (NULL); - char *buffer = NULL; - - if ((i = open (logfile, O_CREAT|O_APPEND|O_WRONLY, - S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH)) == -1) - { - int err = errno; - pam_syslog (pamh, LOG_ERR, "open of %s failed: %m", - logfile); - exit (err); - } - if (asprintf (&buffer, "*** %s", ctime (&tm)) > 0) - { - pam_modutil_write (i, buffer, strlen (buffer)); - free (buffer); - } - } - else - if (dup (i) == -1) - { - int err = errno; - pam_syslog (pamh, LOG_ERR, "dup failed: %m"); - exit (err); - } - if (dup (i) == -1) - { - int err = errno; - pam_syslog (pamh, LOG_ERR, "dup failed: %m"); - exit (err); - } - - if (call_setuid) - if (setuid (geteuid ()) == -1) - { - int err = errno; - pam_syslog (pamh, LOG_ERR, "setuid(%lu) failed: %m", - (unsigned long) geteuid ()); - exit (err); - } - - if (setsid () == -1) - { - int err = errno; - pam_syslog (pamh, LOG_ERR, "setsid failed: %m"); - exit (err); - } - - arggv = calloc (argc + 4, sizeof (char *)); - if (arggv == NULL) - exit (ENOMEM); - - for (i = 0; i < (argc - optargc); i++) - arggv[i] = strdup(argv[i+optargc]); - arggv[i] = NULL; - - char **envlist, **tmp; - int envlen, nitems; - - /* - * Set up the child's environment list. It consists of the PAM - * environment, plus a few hand-picked PAM items. - */ - envlist = pam_getenvlist(pamh); - for (envlen = 0; envlist[envlen] != NULL; ++envlen) - /* nothing */ ; - nitems = sizeof(env_items) / sizeof(*env_items); - tmp = realloc(envlist, (envlen + nitems + 1) * sizeof(*envlist)); - if (tmp == NULL) - { - free(envlist); - pam_syslog (pamh, LOG_ERR, "realloc environment failed : %m"); - exit (ENOMEM); - } - envlist = tmp; - for (i = 0; i < nitems; ++i) - { - const void *item; - char *envstr; - - if (pam_get_item(pamh, env_items[i].item, &item) != PAM_SUCCESS || item == NULL) - continue; - asprintf(&envstr, "%s=%s", env_items[i].name, (const char *)item); - if (envstr == NULL) - { - free(envlist); - pam_syslog (pamh, LOG_ERR, "prepare environment failed : %m"); - exit (ENOMEM); - } - envlist[envlen++] = envstr; - envlist[envlen] = NULL; - } - - if (debug) - pam_syslog (pamh, LOG_DEBUG, "Calling %s ...", arggv[0]); - - if (execve (arggv[0], arggv, envlist) == -1) - { - int err = errno; - pam_syslog (pamh, LOG_ERR, "execve(%s,...) failed: %m", - arggv[0]); - free(envlist); - exit (err); - } - free(envlist); - exit (1); /* should never be reached. */ - } - return PAM_SYSTEM_ERR; /* will never be reached. */ -} - -PAM_EXTERN int -pam_sm_authenticate (pam_handle_t *pamh, int flags UNUSED, - int argc, const char **argv) -{ - return call_exec (pamh, argc, argv); -} - -PAM_EXTERN int -pam_sm_setcred (pam_handle_t *pamh UNUSED, int flags UNUSED, - int argc UNUSED, const char **argv UNUSED) -{ - return PAM_IGNORE; -} - -/* password updating functions */ - -PAM_EXTERN int -pam_sm_chauthtok(pam_handle_t *pamh, int flags, - int argc, const char **argv) -{ - if (flags & PAM_PRELIM_CHECK) - return PAM_SUCCESS; - return call_exec (pamh, argc, argv); -} - -PAM_EXTERN int -pam_sm_acct_mgmt(pam_handle_t *pamh, int flags UNUSED, - int argc, const char **argv) -{ - return call_exec (pamh, argc, argv); -} - -PAM_EXTERN int -pam_sm_open_session(pam_handle_t *pamh, int flags UNUSED, - int argc, const char **argv) -{ - return call_exec (pamh, argc, argv); -} - -PAM_EXTERN int -pam_sm_close_session(pam_handle_t *pamh, int flags UNUSED, - int argc, const char **argv) -{ - return call_exec (pamh, argc, argv); -} - -#ifdef PAM_STATIC -struct pam_module _pam_exec_modstruct = { - "pam_exec", - pam_sm_authenticate, - pam_sm_setcred, - pam_sm_acct_mgmt, - pam_sm_open_session, - pam_sm_close_session, - pam_sm_chauthtok, -}; -#endif diff --git a/modules/pam_exec/tst-pam_exec b/modules/pam_exec/tst-pam_exec deleted file mode 100755 index a0b00393..00000000 --- a/modules/pam_exec/tst-pam_exec +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/sh -../../tests/tst-dlopen .libs/pam_exec.so diff --git a/modules/pam_faildelay/.cvsignore b/modules/pam_faildelay/.cvsignore deleted file mode 100644 index cc931c87..00000000 --- a/modules/pam_faildelay/.cvsignore +++ /dev/null @@ -1,8 +0,0 @@ -*.la -*.lo -.deps -.libs -Makefile -Makefile.in -README -pam_faildelay.8 diff --git a/modules/pam_faildelay/Makefile.am b/modules/pam_faildelay/Makefile.am deleted file mode 100644 index 2796018c..00000000 --- a/modules/pam_faildelay/Makefile.am +++ /dev/null @@ -1,31 +0,0 @@ -# -# Copyright (c) 2006 Thorsten Kukuk <kukuk@suse.de> -# - -CLEANFILES = *~ - -EXTRA_DIST = README $(MANS) $(XMLS) tst-pam_faildelay - -man_MANS = pam_faildelay.8 -XMLS = README.xml pam_faildelay.8.xml - -TESTS = tst-pam_faildelay - -securelibdir = $(SECUREDIR) -secureconfdir = $(SCONFIGDIR) - -AM_CFLAGS = -I$(top_srcdir)/libpam/include -I$(top_srcdir)/libpamc/include -AM_LDFLAGS = -no-undefined -avoid-version -module -if HAVE_VERSIONING - AM_LDFLAGS += -Wl,--version-script=$(srcdir)/../modules.map -endif - -securelib_LTLIBRARIES = pam_faildelay.la -pam_faildelay_la_LIBADD = -L$(top_builddir)/libpam -lpam - -if ENABLE_REGENERATE_MAN -noinst_DATA = README -README: pam_faildelay.8.xml --include $(top_srcdir)/Make.xml.rules -endif - diff --git a/modules/pam_faildelay/README.xml b/modules/pam_faildelay/README.xml deleted file mode 100644 index 64d4accc..00000000 --- a/modules/pam_faildelay/README.xml +++ /dev/null @@ -1,41 +0,0 @@ -<?xml version="1.0" encoding='UTF-8'?> -<!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook XML V4.4//EN" -"http://www.docbook.org/xml/4.4/docbookx.dtd" -[ -<!-- -<!ENTITY pamaccess SYSTEM "pam_faildelay.8.xml"> ---> -]> - -<article> - - <articleinfo> - - <title> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" - href="pam_faildelay.8.xml" xpointer='xpointer(//refnamediv[@id = "pam_faildelay-name"]/*)'/> - </title> - - </articleinfo> - - <section> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" - href="pam_faildelay.8.xml" xpointer='xpointer(//refsect1[@id = "pam_faildelay-description"]/*)'/> - </section> - - <section> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" - href="pam_faildelay.8.xml" xpointer='xpointer(//refsect1[@id = "pam_faildelay-options"]/*)'/> - </section> - - <section> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" - href="pam_faildelay.8.xml" xpointer='xpointer(//refsect1[@id = "pam_faildelay-examples"]/*)'/> - </section> - - <section> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" - href="pam_faildelay.8.xml" xpointer='xpointer(//refsect1[@id = "pam_faildelay-author"]/*)'/> - </section> - -</article> diff --git a/modules/pam_faildelay/pam_faildelay.8.xml b/modules/pam_faildelay/pam_faildelay.8.xml deleted file mode 100644 index d2dfd266..00000000 --- a/modules/pam_faildelay/pam_faildelay.8.xml +++ /dev/null @@ -1,136 +0,0 @@ -<?xml version="1.0" encoding='UTF-8'?> -<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.4//EN" - "http://www.oasis-open.org/docbook/xml/4.4/docbookx.dtd"> - -<refentry id="pam_faildelay"> - - <refmeta> - <refentrytitle>pam_faildelay</refentrytitle> - <manvolnum>8</manvolnum> - <refmiscinfo class="sectdesc">Linux-PAM Manual</refmiscinfo> - </refmeta> - - <refnamediv id="pam_faildelay-name"> - <refname>pam_faildelay</refname> - <refpurpose>Change the delay on failure per-application</refpurpose> - </refnamediv> - - <refsynopsisdiv> - <cmdsynopsis id="pam_faildelay-cmdsynopsis"> - <command>pam_faildelay.so</command> - <arg choice="opt"> - debug - </arg> - <arg choice="opt"> - delay=<replaceable>microseconds</replaceable> - </arg> - </cmdsynopsis> - </refsynopsisdiv> - - <refsect1 id="pam_faildelay-description"> - - <title>DESCRIPTION</title> - - <para> - pam_faildelay is a PAM module that can be used to set - the delay on failure per-application. - </para> - <para> - If no <option>delay</option> is given, pam_faildelay will - use the value of FAIL_DELAY from <filename>/etc/login.defs</filename>. - </para> - </refsect1> - - <refsect1 id="pam_faildelay-options"> - - <title>OPTIONS</title> - <variablelist> - <varlistentry> - <term> - <option>debug</option> - </term> - <listitem> - <para> - Turns on debugging messages sent to syslog. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <option>delay=<replaceable>N</replaceable></option> - </term> - <listitem> - <para> - Set the delay on failure to N microseconds. - </para> - </listitem> - </varlistentry> - </variablelist> - </refsect1> - - <refsect1 id="pam_faildelay-services"> - <title>MODULE SERVICES PROVIDED</title> - <para> - Only the <option>auth</option> service is supported. - </para> - </refsect1> - - <refsect1 id='pam_faildelay-return_values'> - <title>RETURN VALUES</title> - <variablelist> - <varlistentry> - <term>PAM_IGNORE</term> - <listitem> - <para> - Delay was successful adjusted. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term>PAM_SYSTEM_ERR</term> - <listitem> - <para> - The specified delay was not valid. - </para> - </listitem> - </varlistentry> - </variablelist> - </refsect1> - - <refsect1 id='pam_faildelay-examples'> - <title>EXAMPLES</title> - <para> - The following example will set the delay on failure to - 10 seconds: - <programlisting> -auth optional pam_faildelay.so delay=10000000 - </programlisting> - </para> - </refsect1> - - <refsect1 id='pam_faildelay-see_also'> - <title>SEE ALSO</title> - <para> - <citerefentry> - <refentrytitle>pam_fail_delay</refentrytitle><manvolnum>3</manvolnum> - </citerefentry>, - <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_faildelay-author'> - <title>AUTHOR</title> - <para> - pam_faildelay was written by Darren Tucker <dtucker@zip.com.au>. - </para> - </refsect1> - -</refentry> diff --git a/modules/pam_faildelay/pam_faildelay.c b/modules/pam_faildelay/pam_faildelay.c deleted file mode 100644 index 072b7dd3..00000000 --- a/modules/pam_faildelay/pam_faildelay.c +++ /dev/null @@ -1,231 +0,0 @@ -/* pam_faildelay module */ - -/* - * Allows an admin to set the delay on failure per-application. - * Provides "auth" interface only. - * - * Use by putting something like this in the relevant pam config: - * auth required pam_faildelay.so delay=[microseconds] - * - * eg: - * auth required pam_faildelay.so delay=10000000 - * will set the delay on failure to 10 seconds. - * - * If no delay option was given, pam_faildelay.so will use the - * FAIL_DELAY value of /etc/login.defs. - * - * Based on pam_rootok and parts of pam_unix both by Andrew Morgan - * <morgan@linux.kernel.org> - * - * Copyright (c) 2006 Thorsten Kukuk <kukuk@thkukuk.de> - * - Rewrite to use extended PAM functions - * - Add /etc/login.defs support - * - * Portions Copyright (c) 2005 Darren Tucker <dtucker at zip com au>. - * - * Redistribution and use in source and binary forms of, with - * or without modification, are permitted provided that the following - * conditions are met: - * - * 1. Redistributions of source code must retain any existing copyright - * notice, and this entire permission notice in its entirety, - * including the disclaimer of warranties. - * - * 2. Redistributions in binary form must reproduce all prior and current - * copyright notices, this list of conditions, and the following - * disclaimer in the documentation and/or other materials provided - * with the distribution. - * - * 3. The name of any author may not be used to endorse or promote - * products derived from this software without their specific prior - * written permission. - * - * ALTERNATIVELY, this product may be distributed under the terms of the - * GNU General Public License, in which case the provisions of the GNU - * GPL are required INSTEAD OF the above restrictions. (This clause is - * necessary due to a potential conflict between the GNU 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(S) 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 <ctype.h> -#include <stdio.h> -#include <limits.h> -#include <unistd.h> -#include <syslog.h> -#include <string.h> -#include <stdlib.h> - - -#define PAM_SM_AUTH - -#include <security/pam_modules.h> -#include <security/pam_ext.h> - - -#define BUF_SIZE 8192 -#define LOGIN_DEFS "/etc/login.defs" - -static char * -search_key (const char *filename) -{ - FILE *fp; - char *buf = NULL; - size_t buflen = 0; - char *retval = NULL; - - fp = fopen (filename, "r"); - if (NULL == fp) - return NULL; - - while (!feof (fp)) - { - char *tmp, *cp; -#if defined(HAVE_GETLINE) - ssize_t n = getline (&buf, &buflen, fp); -#elif defined (HAVE_GETDELIM) - ssize_t n = getdelim (&buf, &buflen, '\n', fp); -#else - ssize_t n; - - if (buf == NULL) - { - buflen = BUF_SIZE; - buf = malloc (buflen); - } - buf[0] = '\0'; - if (fgets (buf, buflen - 1, fp) == NULL) - break; - else if (buf != NULL) - n = strlen (buf); - else - n = 0; -#endif /* HAVE_GETLINE / HAVE_GETDELIM */ - cp = buf; - - if (n < 1) - break; - - tmp = strchr (cp, '#'); /* remove comments */ - if (tmp) - *tmp = '\0'; - while (isspace ((int)*cp)) /* remove spaces and tabs */ - ++cp; - if (*cp == '\0') /* ignore empty lines */ - continue; - - if (cp[strlen (cp) - 1] == '\n') - cp[strlen (cp) - 1] = '\0'; - - tmp = strsep (&cp, " \t="); - if (cp != NULL) - while (isspace ((int)*cp) || *cp == '=') - ++cp; - - if (strcasecmp (tmp, "FAIL_DELAY") == 0) - { - retval = strdup (cp); - break; - } - } - fclose (fp); - - free (buf); - - return retval; -} - - -/* --- authentication management functions (only) --- */ - -PAM_EXTERN -int pam_sm_authenticate(pam_handle_t *pamh, int flags UNUSED, - int argc, const char **argv) -{ - int i, debug_flag = 0; - long int delay = -1; - - /* step through arguments */ - for (i = 0; i < argc; i++) { - if (sscanf(argv[i], "delay=%ld", &delay) == 1) { - /* sscanf did already everything necessary */ - } else if (strcmp (argv[i], "debug") == 0) - debug_flag = 1; - else - pam_syslog (pamh, LOG_ERR, "unknown option; %s", argv[i]); - } - - if (delay == -1) - { - char *endptr; - char *val = search_key (LOGIN_DEFS); - const char *val_orig = val; - - if (val == NULL) - return PAM_IGNORE; - - errno = 0; - delay = strtol (val, &endptr, 10) & 0777; - if (((delay == 0) && (val_orig == endptr)) || - ((delay == LONG_MIN || delay == LONG_MAX) && (errno == ERANGE))) - { - pam_syslog (pamh, LOG_ERR, "FAIL_DELAY=%s in %s not valid", - val, LOGIN_DEFS); - free (val); - return PAM_IGNORE; - } - - free (val); - /* delay is in seconds, convert to microseconds. */ - delay *= 1000000; - } - - if (debug_flag) - pam_syslog (pamh, LOG_DEBUG, "setting fail delay to %ld", delay); - - i = pam_fail_delay(pamh, delay); - if (i == PAM_SUCCESS) - return PAM_IGNORE; - else - return i; -} - -PAM_EXTERN -int pam_sm_setcred(pam_handle_t *pamh UNUSED, int flags UNUSED, - int argc UNUSED, const char **argv UNUSED) -{ - return PAM_IGNORE; -} - - -#ifdef PAM_STATIC - -/* static module data */ - -struct pam_module _pam_faildelay_modstruct = { - "pam_faildelay", - pam_sm_authenticate, - pam_sm_setcred, - NULL, - NULL, - NULL, - NULL, -}; - -#endif - -/* end of module definition */ diff --git a/modules/pam_faildelay/tst-pam_faildelay b/modules/pam_faildelay/tst-pam_faildelay deleted file mode 100755 index 87f7fd44..00000000 --- a/modules/pam_faildelay/tst-pam_faildelay +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/sh -../../tests/tst-dlopen .libs/pam_faildelay.so diff --git a/modules/pam_filter/.cvsignore b/modules/pam_filter/.cvsignore deleted file mode 100644 index dc6908c2..00000000 --- a/modules/pam_filter/.cvsignore +++ /dev/null @@ -1,9 +0,0 @@ -*.la -*.lo -.deps -.libs -Makefile -Makefile.in -security -README -pam_filter.8 diff --git a/modules/pam_filter/Makefile.am b/modules/pam_filter/Makefile.am deleted file mode 100644 index ab2ceee9..00000000 --- a/modules/pam_filter/Makefile.am +++ /dev/null @@ -1,34 +0,0 @@ -# -# Copyright (c) 2005, 2006, 2007 Thorsten Kukuk <kukuk@thkukuk.de> -# - -SUBDIRS = upperLOWER - -CLEANFILES = *~ - -EXTRA_DIST = README $(MANS) $(XMLS) tst-pam_filter - -man_MANS = pam_filter.8 -XMLS = README.xml pam_filter.8.xml - -securelibdir = $(SECUREDIR) -secureconfdir = $(SCONFIGDIR) - -AM_CFLAGS = -I$(top_srcdir)/libpam/include -I$(top_srcdir)/libpamc/include -AM_LDFLAGS = -no-undefined -avoid-version -module -if HAVE_VERSIONING - AM_LDFLAGS += -Wl,--version-script=$(srcdir)/../modules.map -endif - -include_HEADERS=pam_filter.h -pam_filter_la_LIBADD = -L$(top_builddir)/libpam -lpam - -securelib_LTLIBRARIES = pam_filter.la -TESTS = tst-pam_filter - -if ENABLE_REGENERATE_MAN -noinst_DATA = README -README: pam_filter.8.xml --include $(top_srcdir)/Make.xml.rules -endif - diff --git a/modules/pam_filter/README.xml b/modules/pam_filter/README.xml deleted file mode 100644 index b76cb743..00000000 --- a/modules/pam_filter/README.xml +++ /dev/null @@ -1,41 +0,0 @@ -<?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_filter.8.xml"> ---> -]> - -<article> - - <articleinfo> - - <title> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" - href="pam_filter.8.xml" xpointer='xpointer(//refnamediv[@id = "pam_filter-name"]/*)'/> - </title> - - </articleinfo> - - <section> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" - href="pam_filter.8.xml" xpointer='xpointer(//refsect1[@id = "pam_filter-description"]/*)'/> - </section> - - <section> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" - href="pam_filter.8.xml" xpointer='xpointer(//refsect1[@id = "pam_filter-options"]/*)'/> - </section> - - <section> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" - href="pam_filter.8.xml" xpointer='xpointer(//refsect1[@id = "pam_filter-examples"]/*)'/> - </section> - - <section> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" - href="pam_filter.8.xml" xpointer='xpointer(//refsect1[@id = "pam_filter-author"]/*)'/> - </section> - -</article> diff --git a/modules/pam_filter/pam_filter.8.xml b/modules/pam_filter/pam_filter.8.xml deleted file mode 100644 index d15d7e97..00000000 --- a/modules/pam_filter/pam_filter.8.xml +++ /dev/null @@ -1,261 +0,0 @@ -<?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_filter"> - - <refmeta> - <refentrytitle>pam_filter</refentrytitle> - <manvolnum>8</manvolnum> - <refmiscinfo class="sectdesc">Linux-PAM Manual</refmiscinfo> - </refmeta> - - <refnamediv id="pam_filter-name"> - <refname>pam_filter</refname> - <refpurpose>PAM filter module</refpurpose> - </refnamediv> - - <refsynopsisdiv> - <cmdsynopsis id="pam_filter-cmdsynopsis"> - <command>pam_filter.so</command> - <arg choice="opt"> - debug - </arg> - <arg choice="opt"> - new_term - </arg> - <arg choice="opt"> - non_term - </arg> - <arg choice="plain"> - run1|run2 - </arg> - <arg choice="plain"> - <replaceable>filter</replaceable> - </arg> - <arg choice="opt"> - <replaceable>...</replaceable> - </arg> - </cmdsynopsis> - </refsynopsisdiv> - - <refsect1 id="pam_filter-description"> - - <title>DESCRIPTION</title> - - <para> - This module is intended to be a platform for providing access to all - of the input/output that passes between the user and the application. - It is only suitable for tty-based and (stdin/stdout) applications. - </para> - <para> - To function this module requires <emphasis>filters</emphasis> to be - installed on the system. - The single filter provided with the module simply transposes upper and - lower case letters in the input and output streams. (This can be very - annoying and is not kind to termcap based editors). - </para> - <para> - Each component of the module has the potential to invoke the - desired filter. The filter is always - <citerefentry> - <refentrytitle>execv</refentrytitle><manvolnum>2</manvolnum> - </citerefentry> with the privilege of the calling application - and <emphasis>not</emphasis> that of the user. For this reason it - cannot usually be killed by the user without closing their session. - </para> - </refsect1> - - <refsect1 id="pam_filter-options"> - - <title>OPTIONS</title> - <para> - <variablelist> - - <varlistentry> - <term> - <option>debug</option> - </term> - <listitem> - <para> - Print debug information. - </para> - </listitem> - </varlistentry> - - <varlistentry> - <term> - <option>new_term</option> - </term> - <listitem> - <para> - The default action of the filter is to set the - <emphasis>PAM_TTY</emphasis> item to indicate the - terminal that the user is using to connect to the - application. This argument indicates that the filter - should set <emphasis>PAM_TTY</emphasis> to the filtered - pseudo-terminal. - </para> - </listitem> - </varlistentry> - - <varlistentry> - <term> - <option>non_term</option> - </term> - <listitem> - <para> - don't try to set the <emphasis>PAM_TTY</emphasis> item. - </para> - </listitem> - </varlistentry> - - <varlistentry> - <term> - <option>runX</option> - </term> - <listitem> - <para> - In order that the module can invoke a filter it should - know when to invoke it. This argument is required to tell - the filter when to do this. - </para> - <para> - Permitted values for <emphasis>X</emphasis> are - <emphasis>1</emphasis> and <emphasis>2</emphasis>. These - indicate the precise time that the filter is to be run. - To understand this concept it will be useful to have read - the <citerefentry> - <refentrytitle>pam</refentrytitle><manvolnum>3</manvolnum> - </citerefentry> manual page. - Basically, for each management group there are up to two ways - of calling the module's functions. - In the case of the <emphasis>authentication</emphasis> and - <emphasis>session</emphasis> components there are actually - two separate functions. For the case of authentication, these - functions are - <citerefentry> - <refentrytitle>pam_authenticate</refentrytitle><manvolnum>3</manvolnum> - </citerefentry> and - <citerefentry> - <refentrytitle>pam_setcred</refentrytitle><manvolnum>3</manvolnum> - </citerefentry>, here <option>run1</option> means run the - filter from the <function>pam_authenticate</function> function - and <option>run2</option> means run the filter from - <function>pam_setcred</function>. In the case of the - session modules, <emphasis>run1</emphasis> implies - that the filter is invoked at the - <citerefentry> - <refentrytitle>pam_open_session</refentrytitle><manvolnum>3</manvolnum> - </citerefentry> stage, and <emphasis>run2</emphasis> for - <citerefentry> - <refentrytitle>pam_close_session</refentrytitle><manvolnum>3</manvolnum> - </citerefentry>. - </para> - <para> - For the case of the account component. Either - <emphasis>run1</emphasis> or <emphasis>run2</emphasis> - may be used. - </para> - <para> - For the case of the password component, <emphasis>run1</emphasis> - is used to indicate that the filter is run on the first - occasion of - <citerefentry> - <refentrytitle>pam_chauthtok</refentrytitle><manvolnum>3</manvolnum> - </citerefentry> (the <emphasis>PAM_PRELIM_CHECK</emphasis> - phase) and <emphasis>run2</emphasis> is used to indicate - that the filter is run on the second occasion (the - <emphasis>PAM_UPDATE_AUTHTOK</emphasis> phase). - - </para> - </listitem> - </varlistentry> - - <varlistentry> - <term> - <option>filter</option> - </term> - <listitem> - <para> - The full pathname of the filter to be run and any command line - arguments that the filter might expect. - </para> - </listitem> - </varlistentry> - </variablelist> - - </para> - </refsect1> - - <refsect1 id="pam_filter-services"> - <title>MODULE SERVICES PROVIDED</title> - <para> - The services <option>auth</option>, <option>account</option>, - <option>password</option> and <option>session</option> are supported. - </para> - </refsect1> - - <refsect1 id='pam_filter-return_values'> - <title>RETURN VALUES</title> - <para> - <variablelist> - - <varlistentry> - <term>PAM_SUCCESS</term> - <listitem> - <para> - The new filter was set successfull. - </para> - </listitem> - </varlistentry> - - <varlistentry> - <term>PAM_ABORT</term> - <listitem> - <para> - Critical error, immediate abort. - </para> - </listitem> - </varlistentry> - - </variablelist> - </para> - </refsect1> - - <refsect1 id='pam_filter-examples'> - <title>EXAMPLES</title> - <para> - Add the following line to <filename>/etc/pam.d/login</filename> to - see how to configure login to transpose upper and lower case letters - once the user has logged in: - - <programlisting> - session required pam_filter.so run1 /lib/security/pam_filter/upperLOWER - </programlisting> - </para> - </refsect1> - - <refsect1 id='pam_filter-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_filter-author'> - <title>AUTHOR</title> - <para> - pam_filter was written by Andrew G. Morgan <morgan@kernel.org>. - </para> - </refsect1> - -</refentry> diff --git a/modules/pam_filter/pam_filter.c b/modules/pam_filter/pam_filter.c deleted file mode 100644 index 86bc172b..00000000 --- a/modules/pam_filter/pam_filter.c +++ /dev/null @@ -1,744 +0,0 @@ -/* - * $Id$ - * - * written by Andrew Morgan <morgan@transmeta.com> with much help from - * Richard Stevens' UNIX Network Programming book. - */ - -#include "config.h" - -#include <stdlib.h> -#include <syslog.h> -#include <unistd.h> -#include <fcntl.h> -#include <string.h> - -#include <stdio.h> -#include <sys/types.h> -#include <sys/wait.h> -#include <sys/time.h> -#include <sys/file.h> -#include <sys/stat.h> -#include <sys/socket.h> -#include <sys/ioctl.h> -#include <termios.h> - -#include <signal.h> - -#define PAM_SM_AUTH -#define PAM_SM_ACCOUNT -#define PAM_SM_SESSION -#define PAM_SM_PASSWORD - -#include <security/pam_modules.h> -#include <security/pam_ext.h> -#include "pam_filter.h" - -/* ------ some tokens used for convenience throughout this file ------- */ - -#define FILTER_DEBUG 01 -#define FILTER_RUN1 02 -#define FILTER_RUN2 04 -#define NEW_TERM 010 -#define NON_TERM 020 - -/* -------------------------------------------------------------------- */ - -/* log errors */ - -#include <stdarg.h> - -#define TERMINAL_LEN 12 - -static int -master (const pam_handle_t *pamh, char *terminal) -/* - * try to open all of the terminals in sequence return first free one, - * or -1 - */ -{ - const char ptys[] = "pqrs", *pty = ptys; - const char hexs[] = "0123456789abcdef", *hex; - struct stat tstat; - int fd; - - strcpy(terminal, "/dev/pty??"); - - while (*pty) { /* step through four types */ - terminal[8] = *pty++; - terminal[9] = '0'; - if (stat(terminal,&tstat) < 0) { - pam_syslog(pamh, LOG_WARNING, - "unknown pseudo terminal: %s", terminal); - break; - } - for (hex = hexs; *hex; ) { /* step through 16 of these */ - terminal[9] = *hex++; - if ((fd = open(terminal, O_RDWR)) >= 0) { - return fd; - } - } - } - - /* no terminal found */ - - return -1; -} - -static int process_args(pam_handle_t *pamh - , int argc, const char **argv, const char *type - , char ***evp, const char **filtername) -{ - int ctrl=0; - - while (argc-- > 0) { - if (strcmp("debug",*argv) == 0) { - ctrl |= FILTER_DEBUG; - } else if (strcmp("new_term",*argv) == 0) { - ctrl |= NEW_TERM; - } else if (strcmp("non_term",*argv) == 0) { - ctrl |= NON_TERM; - } else if (strcmp("run1",*argv) == 0) { - ctrl |= FILTER_RUN1; - if (argc <= 0) { - pam_syslog(pamh, LOG_ALERT, "no run filter supplied"); - } else - break; - } else if (strcmp("run2",*argv) == 0) { - ctrl |= FILTER_RUN2; - if (argc <= 0) { - pam_syslog(pamh, LOG_ALERT, "no run filter supplied"); - } else - break; - } else { - pam_syslog(pamh, LOG_ERR, "unrecognized option: %s", *argv); - } - ++argv; /* step along list */ - } - - if (argc < 0) { - /* there was no reference to a filter */ - *filtername = NULL; - *evp = NULL; - } else { - char **levp; - const char *user = NULL; - const void *tmp; - int i,size, retval; - - *filtername = *++argv; - if (ctrl & FILTER_DEBUG) { - pam_syslog(pamh, LOG_DEBUG, "will run filter %s", *filtername); - } - - levp = (char **) malloc(5*sizeof(char *)); - if (levp == NULL) { - pam_syslog(pamh, LOG_CRIT, "no memory for environment of filter"); - return -1; - } - - for (size=i=0; i<argc; ++i) { - size += strlen(argv[i])+1; - } - - /* the "ARGS" variable */ - -#define ARGS_OFFSET 5 /* strlen('ARGS='); */ -#define ARGS_NAME "ARGS=" - - size += ARGS_OFFSET; - - levp[0] = (char *) malloc(size); - if (levp[0] == NULL) { - pam_syslog(pamh, LOG_CRIT, "no memory for filter arguments"); - if (levp) { - free(levp); - } - return -1; - } - - strncpy(levp[0],ARGS_NAME,ARGS_OFFSET); - for (i=0,size=ARGS_OFFSET; i<argc; ++i) { - strcpy(levp[0]+size, argv[i]); - size += strlen(argv[i]); - levp[0][size++] = ' '; - } - levp[0][--size] = '\0'; /* <NUL> terminate */ - - /* the "SERVICE" variable */ - -#define SERVICE_OFFSET 8 /* strlen('SERVICE='); */ -#define SERVICE_NAME "SERVICE=" - - retval = pam_get_item(pamh, PAM_SERVICE, &tmp); - if (retval != PAM_SUCCESS || tmp == NULL) { - pam_syslog(pamh, LOG_CRIT, "service name not found"); - if (levp) { - free(levp[0]); - free(levp); - } - return -1; - } - size = SERVICE_OFFSET+strlen(tmp); - - levp[1] = (char *) malloc(size+1); - if (levp[1] == NULL) { - pam_syslog(pamh, LOG_CRIT, "no memory for service name"); - if (levp) { - free(levp[0]); - free(levp); - } - return -1; - } - - strncpy(levp[1],SERVICE_NAME,SERVICE_OFFSET); - strcpy(levp[1]+SERVICE_OFFSET, tmp); - levp[1][size] = '\0'; /* <NUL> terminate */ - - /* the "USER" variable */ - -#define USER_OFFSET 5 /* strlen('USER='); */ -#define USER_NAME "USER=" - - pam_get_user(pamh, &user, NULL); - if (user == NULL) { - user = "<unknown>"; - } - size = USER_OFFSET+strlen(user); - - levp[2] = (char *) malloc(size+1); - if (levp[2] == NULL) { - pam_syslog(pamh, LOG_CRIT, "no memory for user's name"); - if (levp) { - free(levp[1]); - free(levp[0]); - free(levp); - } - return -1; - } - - strncpy(levp[2],USER_NAME,USER_OFFSET); - strcpy(levp[2]+USER_OFFSET, user); - levp[2][size] = '\0'; /* <NUL> terminate */ - - /* the "USER" variable */ - -#define TYPE_OFFSET 5 /* strlen('TYPE='); */ -#define TYPE_NAME "TYPE=" - - size = TYPE_OFFSET+strlen(type); - - levp[3] = (char *) malloc(size+1); - if (levp[3] == NULL) { - pam_syslog(pamh, LOG_CRIT, "no memory for type"); - if (levp) { - free(levp[2]); - free(levp[1]); - free(levp[0]); - free(levp); - } - return -1; - } - - strncpy(levp[3],TYPE_NAME,TYPE_OFFSET); - strcpy(levp[3]+TYPE_OFFSET, type); - levp[3][size] = '\0'; /* <NUL> terminate */ - - levp[4] = NULL; /* end list */ - - *evp = levp; - } - - if ((ctrl & FILTER_DEBUG) && *filtername) { - char **e; - - pam_syslog(pamh, LOG_DEBUG, "filter[%s]: %s", type, *filtername); - pam_syslog(pamh, LOG_DEBUG, "environment:"); - for (e=*evp; e && *e; ++e) { - pam_syslog(pamh, LOG_DEBUG, " %s", *e); - } - } - - return ctrl; -} - -static void free_evp(char *evp[]) -{ - int i; - - if (evp) - for (i=0; i<4; ++i) { - if (evp[i]) - free(evp[i]); - } - free(evp); -} - -static int -set_filter (pam_handle_t *pamh, int flags UNUSED, int ctrl, - const char **evp, const char *filtername) -{ - int status=-1; - char terminal[TERMINAL_LEN]; - struct termios stored_mode; /* initial terminal mode settings */ - int fd[2], child=0, child2=0, aterminal; - - if (filtername == NULL || *filtername != '/') { - pam_syslog(pamh, LOG_ALERT, - "filtername not permitted; full pathname required"); - return PAM_ABORT; - } - - if (!isatty(STDIN_FILENO) || !isatty(STDOUT_FILENO)) { - aterminal = 0; - } else { - aterminal = 1; - } - - if (aterminal) { - - /* open the master pseudo terminal */ - - fd[0] = master(pamh,terminal); - if (fd[0] < 0) { - pam_syslog(pamh, LOG_CRIT, "no master terminal"); - return PAM_AUTH_ERR; - } - - /* set terminal into raw mode.. remember old mode so that we can - revert to it after the child has quit. */ - - /* this is termios terminal handling... */ - - if ( tcgetattr(STDIN_FILENO, &stored_mode) < 0 ) { - pam_syslog(pamh, LOG_CRIT, "couldn't copy terminal mode: %m"); - /* in trouble, so close down */ - close(fd[0]); - return PAM_ABORT; - } else { - struct termios t_mode = stored_mode; - - t_mode.c_iflag = 0; /* no input control */ - t_mode.c_oflag &= ~OPOST; /* no ouput post processing */ - - /* no signals, canonical input, echoing, upper/lower output */ -#ifdef XCASE - t_mode.c_lflag &= ~(XCASE); -#endif - t_mode.c_lflag &= ~(ISIG|ICANON|ECHO); - t_mode.c_cflag &= ~(CSIZE|PARENB); /* no parity */ - t_mode.c_cflag |= CS8; /* 8 bit chars */ - - t_mode.c_cc[VMIN] = 1; /* number of chars to satisfy a read */ - t_mode.c_cc[VTIME] = 0; /* 0/10th second for chars */ - - if ( tcsetattr(STDIN_FILENO, TCSAFLUSH, &t_mode) < 0 ) { - pam_syslog(pamh, LOG_WARNING, - "couldn't put terminal in RAW mode: %m"); - close(fd[0]); - return PAM_ABORT; - } - - /* - * NOTE: Unlike the stream socket case here the child - * opens the slave terminal as fd[1] *after* the fork... - */ - } - } else { - - /* - * not a terminal line so just open a stream socket fd[0-1] - * both set... - */ - - if ( socketpair(AF_UNIX, SOCK_STREAM, 0, fd) < 0 ) { - pam_syslog(pamh, LOG_CRIT, "couldn't open a stream pipe: %m"); - return PAM_ABORT; - } - } - - /* start child process */ - - if ( (child = fork()) < 0 ) { - - pam_syslog(pamh, LOG_WARNING, "first fork failed: %m"); - if (aterminal) { - (void) tcsetattr(STDIN_FILENO, TCSAFLUSH, &stored_mode); - } - - return PAM_AUTH_ERR; - } - - if ( child == 0 ) { /* child process *is* application */ - - if (aterminal) { - - /* close the controlling tty */ - -#if defined(__hpux) && defined(O_NOCTTY) - int t = open("/dev/tty", O_RDWR|O_NOCTTY); -#else - int t = open("/dev/tty",O_RDWR); - if (t > 0) { - (void) ioctl(t, TIOCNOTTY, NULL); - close(t); - } -#endif /* defined(__hpux) && defined(O_NOCTTY) */ - - /* make this process it's own process leader */ - if (setsid() == -1) { - pam_syslog(pamh, LOG_WARNING, - "child cannot become new session: %m"); - return PAM_ABORT; - } - - /* find slave's name */ - terminal[5] = 't'; /* want to open slave terminal */ - fd[1] = open(terminal, O_RDWR); - close(fd[0]); /* process is the child -- uses line fd[1] */ - - if (fd[1] < 0) { - pam_syslog(pamh, LOG_WARNING, - "cannot open slave terminal: %s: %m", terminal); - return PAM_ABORT; - } - - /* initialize the child's terminal to be the way the - parent's was before we set it into RAW mode */ - - if ( tcsetattr(fd[1], TCSANOW, &stored_mode) < 0 ) { - pam_syslog(pamh, LOG_WARNING, - "cannot set slave terminal mode: %s: %m", terminal); - close(fd[1]); - return PAM_ABORT; - } - - } else { - - /* nothing to do for a simple stream socket */ - - } - - /* re-assign the stdin/out to fd[1] <- (talks to filter). */ - - if ( dup2(fd[1],STDIN_FILENO) != STDIN_FILENO || - dup2(fd[1],STDOUT_FILENO) != STDOUT_FILENO || - dup2(fd[1],STDERR_FILENO) != STDERR_FILENO ) { - pam_syslog(pamh, LOG_WARNING, - "unable to re-assign STDIN/OUT/ERR: %m"); - close(fd[1]); - return PAM_ABORT; - } - - /* make sure that file descriptors survive 'exec's */ - - if ( fcntl(STDIN_FILENO, F_SETFD, 0) || - fcntl(STDOUT_FILENO,F_SETFD, 0) || - fcntl(STDERR_FILENO,F_SETFD, 0) ) { - pam_syslog(pamh, LOG_WARNING, - "unable to re-assign STDIN/OUT/ERR: %m"); - return PAM_ABORT; - } - - /* now the user input is read from the parent/filter: forget fd */ - - close(fd[1]); - - /* the current process is now aparently working with filtered - stdio/stdout/stderr --- success! */ - - return PAM_SUCCESS; - } - - /* - * process is the parent here. So we can close the application's - * input/output - */ - - close(fd[1]); - - /* Clear out passwords... there is a security problem here in - * that this process never executes pam_end. Consequently, any - * other sensitive data in this process is *not* explicitly - * overwritten, before the process terminates */ - - (void) pam_set_item(pamh, PAM_AUTHTOK, NULL); - (void) pam_set_item(pamh, PAM_OLDAUTHTOK, NULL); - - /* fork a copy of process to run the actual filter executable */ - - if ( (child2 = fork()) < 0 ) { - - pam_syslog(pamh, LOG_WARNING, "filter fork failed: %m"); - child2 = 0; - - } else if ( child2 == 0 ) { /* exec the child filter */ - - if ( dup2(fd[0],APPIN_FILENO) != APPIN_FILENO || - dup2(fd[0],APPOUT_FILENO) != APPOUT_FILENO || - dup2(fd[0],APPERR_FILENO) != APPERR_FILENO ) { - pam_syslog(pamh, LOG_WARNING, - "unable to re-assign APPIN/OUT/ERR: %m"); - close(fd[0]); - exit(1); - } - - /* make sure that file descriptors survive 'exec's */ - - if ( fcntl(APPIN_FILENO, F_SETFD, 0) == -1 || - fcntl(APPOUT_FILENO,F_SETFD, 0) == -1 || - fcntl(APPERR_FILENO,F_SETFD, 0) == -1 ) { - pam_syslog(pamh, LOG_WARNING, - "unable to retain APPIN/OUT/ERR: %m"); - close(APPIN_FILENO); - close(APPOUT_FILENO); - close(APPERR_FILENO); - exit(1); - } - - /* now the user input is read from the parent through filter */ - - execle(filtername, "<pam_filter>", NULL, evp); - - /* getting to here is an error */ - - pam_syslog(pamh, LOG_ALERT, "filter: %s: %m", filtername); - - } else { /* wait for either of the two children to exit */ - - while (child && child2) { /* loop if there are two children */ - int lstatus=0; - int chid; - - chid = wait(&lstatus); - if (chid == child) { - - if (WIFEXITED(lstatus)) { /* exited ? */ - status = WEXITSTATUS(lstatus); - } else if (WIFSIGNALED(lstatus)) { /* killed ? */ - status = -1; - } else - continue; /* just stopped etc.. */ - child = 0; /* the child has exited */ - - } else if (chid == child2) { - /* - * if the filter has exited. Let the child die - * naturally below - */ - if (WIFEXITED(lstatus) || WIFSIGNALED(lstatus)) - child2 = 0; - } else { - - pam_syslog(pamh, LOG_ALERT, - "programming error <chid=%d,lstatus=%x> " - "in file %s at line %d", - chid, lstatus, __FILE__, __LINE__); - child = child2 = 0; - status = -1; - - } - } - } - - close(fd[0]); - - /* if there is something running, wait for it to exit */ - - while (child || child2) { - int lstatus=0; - int chid; - - chid = wait(&lstatus); - - if (child && chid == child) { - - if (WIFEXITED(lstatus)) { /* exited ? */ - status = WEXITSTATUS(lstatus); - } else if (WIFSIGNALED(lstatus)) { /* killed ? */ - status = -1; - } else - continue; /* just stopped etc.. */ - child = 0; /* the child has exited */ - - } else if (child2 && chid == child2) { - - if (WIFEXITED(lstatus) || WIFSIGNALED(lstatus)) - child2 = 0; - - } else { - - pam_syslog(pamh, LOG_ALERT, - "programming error <chid=%d,lstatus=%x> " - "in file %s at line %d", - chid, lstatus, __FILE__, __LINE__); - child = child2 = 0; - status = -1; - - } - } - - if (aterminal) { - /* reset to initial terminal mode */ - (void) tcsetattr(STDIN_FILENO, TCSANOW, &stored_mode); - } - - if (ctrl & FILTER_DEBUG) { - pam_syslog(pamh, LOG_DEBUG, "parent process exited"); /* clock off */ - } - - /* quit the parent process, returning the child's exit status */ - - exit(status); - return status; /* never reached, to make gcc happy */ -} - -static int set_the_terminal(pam_handle_t *pamh) -{ - const void *tty; - - if (pam_get_item(pamh, PAM_TTY, &tty) != PAM_SUCCESS - || tty == NULL) { - tty = ttyname(STDIN_FILENO); - if (tty == NULL) { - pam_syslog(pamh, LOG_ERR, "couldn't get the tty name"); - return PAM_ABORT; - } - if (pam_set_item(pamh, PAM_TTY, tty) != PAM_SUCCESS) { - pam_syslog(pamh, LOG_ERR, "couldn't set tty name"); - return PAM_ABORT; - } - } - return PAM_SUCCESS; -} - -static int need_a_filter(pam_handle_t *pamh - , int flags, int argc, const char **argv - , const char *name, int which_run) -{ - int ctrl; - char **evp; - const char *filterfile; - int retval; - - ctrl = process_args(pamh, argc, argv, name, &evp, &filterfile); - if (ctrl == -1) { - return PAM_AUTHINFO_UNAVAIL; - } - - /* set the tty to the old or the new one? */ - - if (!(ctrl & NON_TERM) && !(ctrl & NEW_TERM)) { - retval = set_the_terminal(pamh); - if (retval != PAM_SUCCESS) { - pam_syslog(pamh, LOG_ERR, "tried and failed to set PAM_TTY"); - } - } else { - retval = PAM_SUCCESS; /* nothing to do which is always a success */ - } - - if (retval == PAM_SUCCESS && (ctrl & which_run)) { - retval = set_filter(pamh, flags, ctrl - , (const char **)evp, filterfile); - } - - if (retval == PAM_SUCCESS - && !(ctrl & NON_TERM) && (ctrl & NEW_TERM)) { - retval = set_the_terminal(pamh); - if (retval != PAM_SUCCESS) { - pam_syslog(pamh, LOG_ERR, - "tried and failed to set new terminal as PAM_TTY"); - } - } - - free_evp(evp); - - if (ctrl & FILTER_DEBUG) { - pam_syslog(pamh, LOG_DEBUG, "filter/%s, returning %d", name, retval); - pam_syslog(pamh, LOG_DEBUG, "[%s]", pam_strerror(pamh, retval)); - } - - return retval; -} - -/* ----------------- public functions ---------------- */ - -/* - * here are the advertised access points ... - */ - -/* ------------------ authentication ----------------- */ - -PAM_EXTERN int pam_sm_authenticate(pam_handle_t *pamh - , int flags, int argc, const char **argv) -{ - return need_a_filter(pamh, flags, argc, argv - , "authenticate", FILTER_RUN1); -} - -PAM_EXTERN int pam_sm_setcred(pam_handle_t *pamh, int flags - , int argc, const char **argv) -{ - return need_a_filter(pamh, flags, argc, argv, "setcred", FILTER_RUN2); -} - -/* --------------- account management ---------------- */ - -PAM_EXTERN int pam_sm_acct_mgmt(pam_handle_t *pamh, int flags, int argc, - const char **argv) -{ - return need_a_filter(pamh, flags, argc, argv - , "setcred", FILTER_RUN1|FILTER_RUN2 ); -} - -/* --------------- session management ---------------- */ - -PAM_EXTERN int pam_sm_open_session(pam_handle_t *pamh, int flags - , int argc, const char **argv) -{ - return need_a_filter(pamh, flags, argc, argv - , "open_session", FILTER_RUN1); -} - -PAM_EXTERN int pam_sm_close_session(pam_handle_t *pamh, int flags - , int argc, const char **argv) -{ - return need_a_filter(pamh, flags, argc, argv - , "close_session", FILTER_RUN2); -} - -/* --------- updating authentication tokens --------- */ - - -PAM_EXTERN int pam_sm_chauthtok(pam_handle_t *pamh, int flags - , int argc, const char **argv) -{ - int runN; - - if (flags & PAM_PRELIM_CHECK) - runN = FILTER_RUN1; - else if (flags & PAM_UPDATE_AUTHTOK) - runN = FILTER_RUN2; - else { - pam_syslog(pamh, LOG_ERR, "unknown flags for chauthtok (0x%X)", flags); - return PAM_TRY_AGAIN; - } - - return need_a_filter(pamh, flags, argc, argv, "chauthtok", runN); -} - -#ifdef PAM_STATIC - -/* ------------ stuff for static modules ------------ */ - -struct pam_module _pam_filter_modstruct = { - "pam_filter", - pam_sm_authenticate, - pam_sm_setcred, - pam_sm_acct_mgmt, - pam_sm_open_session, - pam_sm_close_session, - pam_sm_chauthtok, -}; - -#endif diff --git a/modules/pam_filter/pam_filter.h b/modules/pam_filter/pam_filter.h deleted file mode 100644 index 630198ee..00000000 --- a/modules/pam_filter/pam_filter.h +++ /dev/null @@ -1,32 +0,0 @@ -/* - * $Id$ - * - * this file is associated with the Linux-PAM filter module. - * it was written by Andrew G. Morgan <morgan@linux.kernel.org> - * - */ - -#ifndef PAM_FILTER_H -#define PAM_FILTER_H - -#include <sys/file.h> - -/* - * this will fail if there is some problem with these file descriptors - * being allocated by the pam_filter Linux-PAM module. The numbers - * here are thought safe, but the filter developer should use the - * macros, as these numbers are subject to change. - * - * The APPXXX_FILENO file descriptors are the STDIN/OUT/ERR_FILENO of the - * application. The filter uses the STDIN/OUT/ERR_FILENO's to converse - * with the user, passes (modified) user input to the application via - * APPIN_FILENO, and receives application output from APPOUT_FILENO/ERR. - */ - -#define APPIN_FILENO 3 /* write here to give application input */ -#define APPOUT_FILENO 4 /* read here to get application output */ -#define APPERR_FILENO 5 /* read here to get application errors */ - -#define APPTOP_FILE 6 /* used by select */ - -#endif diff --git a/modules/pam_filter/tst-pam_filter b/modules/pam_filter/tst-pam_filter deleted file mode 100755 index 56a5d083..00000000 --- a/modules/pam_filter/tst-pam_filter +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/sh -../../tests/tst-dlopen .libs/pam_filter.so diff --git a/modules/pam_filter/upperLOWER/.cvsignore b/modules/pam_filter/upperLOWER/.cvsignore deleted file mode 100644 index ceceb1b9..00000000 --- a/modules/pam_filter/upperLOWER/.cvsignore +++ /dev/null @@ -1,5 +0,0 @@ -.deps -.libs -upperLOWER -Makefile -Makefile.in diff --git a/modules/pam_filter/upperLOWER/Makefile.am b/modules/pam_filter/upperLOWER/Makefile.am deleted file mode 100644 index 93d24ff5..00000000 --- a/modules/pam_filter/upperLOWER/Makefile.am +++ /dev/null @@ -1,15 +0,0 @@ -# -# Copyright (c) 2005 Thorsten Kukuk <kukuk@suse.de> -# - -CLEANFILES = *~ - -securelibfilterdir = $(SECUREDIR)/pam_filter - - -AM_CFLAGS = -I$(top_srcdir)/libpam/include -I$(top_srcdir)/libpamc/include \ - -I$(srcdir)/.. @PIE_CFLAGS@ -AM_LDFLAGS = @PIE_LDFLAGS@ -LDADD = -L$(top_builddir)/libpam -lpam - -securelibfilter_PROGRAMS = upperLOWER diff --git a/modules/pam_filter/upperLOWER/upperLOWER.c b/modules/pam_filter/upperLOWER/upperLOWER.c deleted file mode 100644 index 0ede4a0d..00000000 --- a/modules/pam_filter/upperLOWER/upperLOWER.c +++ /dev/null @@ -1,141 +0,0 @@ -/* - * This is a sample filter program, for use with pam_filter (a module - * provided with Linux-PAM). This filter simply transposes upper and - * lower case letters, it is intended for demonstration purposes and - * it serves no purpose other than to annoy the user... - */ - -#include "config.h" - -#include <ctype.h> -#include <stdio.h> -#include <stdlib.h> -#include <syslog.h> -#include <sys/time.h> -#include <sys/types.h> -#include <unistd.h> - -#include "pam_filter.h" -#include <security/pam_modutil.h> - -/* ---------------------------------------------------------------- */ - -static void do_transpose(char *buffer,int len) -{ - int i; - for (i=0; i<len; ++i) { - if (islower(buffer[i])) { - buffer[i] = toupper(buffer[i]); - } else { - buffer[i] = tolower(buffer[i]); - } - } -} - -extern char **environ; - -int main(int argc, char **argv UNUSED) -{ - char buffer[BUFSIZ]; - fd_set readers; - void (*before_user)(char *,int); - void (*before_app)(char *,int); - - openlog("upperLOWER", LOG_CONS|LOG_PID, LOG_AUTHPRIV); - -#ifdef DEBUG - { - int i; - - fprintf(stderr,"environment :[\r\n"); - for (i=0; environ[i]; ++i) { - fprintf(stderr,"-> %s\r\n",environ[i]); - } - fprintf(stderr,"]: end\r\n"); - } -#endif - - if (argc != 1) { -#ifdef DEBUG - fprintf(stderr,"filter invoked as conventional executable\n"); -#else - syslog(LOG_ERR, "filter invoked as conventional executable"); -#endif - exit(1); - } - - before_user = before_app = do_transpose; /* assign filter functions */ - - /* enter a loop that deals with the input and output of the - user.. passing it to and from the application */ - - FD_ZERO(&readers); /* initialize reading mask */ - - for (;;) { - - FD_SET(APPOUT_FILENO, &readers); /* wake for output */ - FD_SET(APPERR_FILENO, &readers); /* wake for error */ - FD_SET(STDIN_FILENO, &readers); /* wake for input */ - - if ( select(APPTOP_FILE,&readers,NULL,NULL,NULL) < 0 ) { -#ifdef DEBUG - fprintf(stderr,"select failed\n"); -#else - syslog(LOG_WARNING,"select failed"); -#endif - break; - } - - /* application errors */ - - if ( FD_ISSET(APPERR_FILENO,&readers) ) { - int got = pam_modutil_read(APPERR_FILENO, buffer, BUFSIZ); - if (got <= 0) { - break; - } else { - /* translate to give to real terminal */ - if (before_user != NULL) - before_user(buffer, got); - if (pam_modutil_write(STDERR_FILENO, buffer, got) != got ) { - syslog(LOG_WARNING,"couldn't write %d bytes?!",got); - break; - } - } - } else if ( FD_ISSET(APPOUT_FILENO,&readers) ) { /* app output */ - int got = pam_modutil_read(APPOUT_FILENO, buffer, BUFSIZ); - if (got <= 0) { - break; - } else { - /* translate to give to real terminal */ - if (before_user != NULL) - before_user(buffer, got); - if (pam_modutil_write(STDOUT_FILENO, buffer, got) != got ) { - syslog(LOG_WARNING,"couldn't write %d bytes!?",got); - break; - } - } - } - - if ( FD_ISSET(STDIN_FILENO, &readers) ) { /* user input */ - int got = pam_modutil_read(STDIN_FILENO, buffer, BUFSIZ); - if (got < 0) { - syslog(LOG_WARNING,"user input junked"); - break; - } else if (got) { - /* translate to give to application */ - if (before_app != NULL) - before_app(buffer, got); - if (pam_modutil_write(APPIN_FILENO, buffer, got) != got ) { - syslog(LOG_WARNING,"couldn't pass %d bytes!?",got); - break; - } - } else { - /* nothing received -- an error? */ - syslog(LOG_WARNING,"user input null?"); - break; - } - } - } - - exit(0); -} diff --git a/modules/pam_ftp/.cvsignore b/modules/pam_ftp/.cvsignore deleted file mode 100644 index 02e0ab6b..00000000 --- a/modules/pam_ftp/.cvsignore +++ /dev/null @@ -1,8 +0,0 @@ -*.la -*.lo -.deps -.libs -Makefile -Makefile.in -README -pam_ftp.8 diff --git a/modules/pam_ftp/Makefile.am b/modules/pam_ftp/Makefile.am deleted file mode 100644 index a4ce03df..00000000 --- a/modules/pam_ftp/Makefile.am +++ /dev/null @@ -1,31 +0,0 @@ -# -# Copyright (c) 2005, 2006 Thorsten Kukuk <kukuk@suse.de> -# - -CLEANFILES = *~ - -EXTRA_DIST = README $(MANS) $(XMLS) tst-pam_ftp - -man_MANS = pam_ftp.8 -XMLS = README.xml pam_ftp.8.xml - -securelibdir = $(SECUREDIR) -secureconfdir = $(SCONFIGDIR) - -AM_CFLAGS = -I$(top_srcdir)/libpam/include -I$(top_srcdir)/libpamc/include -AM_LDFLAGS = -no-undefined -avoid-version -module -if HAVE_VERSIONING - AM_LDFLAGS += -Wl,--version-script=$(srcdir)/../modules.map -endif - -securelib_LTLIBRARIES = pam_ftp.la -pam_ftp_la_LIBADD = -L$(top_builddir)/libpam -lpam - -TESTS = tst-pam_ftp - -if ENABLE_REGENERATE_MAN -noinst_DATA = README -README: pam_ftp.8.xml --include $(top_srcdir)/Make.xml.rules -endif - diff --git a/modules/pam_ftp/README.xml b/modules/pam_ftp/README.xml deleted file mode 100644 index 65de28e3..00000000 --- a/modules/pam_ftp/README.xml +++ /dev/null @@ -1,41 +0,0 @@ -<?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_ftp.8.xml"> ---> -]> - -<article> - - <articleinfo> - - <title> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" - href="pam_ftp.8.xml" xpointer='xpointer(//refnamediv[@id = "pam_ftp-name"]/*)'/> - </title> - - </articleinfo> - - <section> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" - href="pam_ftp.8.xml" xpointer='xpointer(//refsect1[@id = "pam_ftp-description"]/*)'/> - </section> - - <section> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" - href="pam_ftp.8.xml" xpointer='xpointer(//refsect1[@id = "pam_ftp-options"]/*)'/> - </section> - - <section> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" - href="pam_ftp.8.xml" xpointer='xpointer(//refsect1[@id = "pam_ftp-examples"]/*)'/> - </section> - - <section> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" - href="pam_ftp.8.xml" xpointer='xpointer(//refsect1[@id = "pam_ftp-author"]/*)'/> - </section> - -</article> diff --git a/modules/pam_ftp/pam_ftp.8.xml b/modules/pam_ftp/pam_ftp.8.xml deleted file mode 100644 index aca21694..00000000 --- a/modules/pam_ftp/pam_ftp.8.xml +++ /dev/null @@ -1,183 +0,0 @@ -<?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_ftp"> - - <refmeta> - <refentrytitle>pam_ftp</refentrytitle> - <manvolnum>8</manvolnum> - <refmiscinfo class="sectdesc">Linux-PAM Manual</refmiscinfo> - </refmeta> - - <refnamediv id="pam_ftp-name"> - <refname>pam_ftp</refname> - <refpurpose>PAM module for anonymous access module</refpurpose> - </refnamediv> - - <refsynopsisdiv> - <cmdsynopsis id="pam_ftp-cmdsynopsis"> - <command>pam_ftp.so</command> - <arg choice="opt"> - debug - </arg> - <arg choice="opt"> - ignore - </arg> - <arg choice="opt" rep='repeat'> - users=<replaceable>XXX,YYY,</replaceable> - </arg> - </cmdsynopsis> - </refsynopsisdiv> - - <refsect1 id="pam_ftp-description"> - - <title>DESCRIPTION</title> - - <para> - pam_ftp is a PAM module which provides a pluggable - anonymous ftp mode of access. - </para> - <para> - This module intercepts the user's name and password. If the name is - <emphasis>ftp</emphasis> or <emphasis>anonymous</emphasis>, the - user's password is broken up at the <emphasis>@</emphasis> delimiter - into a <emphasis>PAM_RUSER</emphasis> and a - <emphasis>PAM_RHOST</emphasis> part; these pam-items being set - accordingly. The username (<emphasis>PAM_USER</emphasis>) is set - to <emphasis>ftp</emphasis>. In this case the module succeeds. - Alternatively, the module sets the <emphasis>PAM_AUTHTOK</emphasis> - item with the entered password and fails. - </para> - <para> - This module is not safe and easily spoofable. - </para> - </refsect1> - - <refsect1 id="pam_ftp-options"> - - <title>OPTIONS</title> - <para> - <variablelist> - - <varlistentry> - <term> - <option>debug</option> - </term> - <listitem> - <para> - Print debug information. - </para> - </listitem> - </varlistentry> - - <varlistentry> - <term> - <option>ignore</option> - </term> - <listitem> - <para> - Pay no attention to the email address of the user - (if supplied). - </para> - </listitem> - </varlistentry> - - <varlistentry> - <term> - <option>ftp=<replaceable>XXX,YYY,...</replaceable></option> - </term> - <listitem> - <para> - Instead of <emphasis>ftp</emphasis> or - <emphasis>anonymous</emphasis>, provide anonymous login - to the comma separated list of users: - <option><replaceable>XXX,YYY,...</replaceable></option>. - Should the applicant enter - one of these usernames the returned username is set to - the first in the list: <emphasis>XXX</emphasis>. - </para> - </listitem> - </varlistentry> - - </variablelist> - - </para> - </refsect1> - - <refsect1 id="pam_ftp-services"> - <title>MODULE SERVICES PROVIDED</title> - <para> - Only the <option>auth</option> service is supported. - </para> - </refsect1> - - <refsect1 id='pam_ftp-return_values'> - <title>RETURN VALUES</title> - <para> - <variablelist> - - <varlistentry> - <term>PAM_SUCCESS</term> - <listitem> - <para> - The authentication was successfull. - </para> - </listitem> - </varlistentry> - - <varlistentry> - <term>PAM_USER_UNKNOWN</term> - <listitem> - <para> - User not known. - </para> - </listitem> - </varlistentry> - - </variablelist> - </para> - </refsect1> - - <refsect1 id='pam_ftp-examples'> - <title>EXAMPLES</title> - <para> - Add the following line to <filename>/etc/pam.d/ftpd</filename> to - handle ftp style anonymous login: - <programlisting> -# -# ftpd; add ftp-specifics. These lines enable anonymous ftp over -# standard UN*X access (the listfile entry blocks access to -# users listed in /etc/ftpusers) -# -auth sufficient pam_ftp.so -auth required pam_unix.so use_first_pass -auth required pam_listfile.so \ - onerr=succeed item=user sense=deny file=/etc/ftpusers - </programlisting> - </para> - </refsect1> - - <refsect1 id='pam_ftp-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_ftp-author'> - <title>AUTHOR</title> - <para> - pam_ftp was written by Andrew G. Morgan <morgan@kernel.org>. - </para> - </refsect1> - -</refentry> diff --git a/modules/pam_ftp/pam_ftp.c b/modules/pam_ftp/pam_ftp.c deleted file mode 100644 index 11cdf590..00000000 --- a/modules/pam_ftp/pam_ftp.c +++ /dev/null @@ -1,235 +0,0 @@ -/* pam_ftp module */ - -/* - * $Id$ - * - * Written by Andrew Morgan <morgan@linux.kernel.org> 1996/3/11 - * - */ - -#define PLEASE_ENTER_PASSWORD "Password required for %s." -#define GUEST_LOGIN_PROMPT "Guest login ok, " \ -"send your complete e-mail address as password." - -/* the following is a password that "can't be correct" */ -#define BLOCK_PASSWORD "\177BAD PASSWPRD\177" - -#include "config.h" - -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <syslog.h> -#include <stdarg.h> -#include <string.h> - -/* - * here, we make a definition for the externally accessible function - * in this file (this definition is required for static a module - * but strongly encouraged generally) it is used to instruct the - * modules include file to define the function prototypes. - */ - -#define PAM_SM_AUTH - -#include <security/pam_modules.h> -#include <security/_pam_macros.h> -#include <security/pam_ext.h> - -/* argument parsing */ - -#define PAM_DEBUG_ARG 01 -#define PAM_IGNORE_EMAIL 02 -#define PAM_NO_ANON 04 - -static int -_pam_parse(pam_handle_t *pamh, int argc, const char **argv, const char **users) -{ - int ctrl=0; - - /* step through arguments */ - for (ctrl=0; argc-- > 0; ++argv) { - - /* generic options */ - - if (!strcmp(*argv,"debug")) - ctrl |= PAM_DEBUG_ARG; - else if (!strncmp(*argv,"users=",6)) { - *users = 6 + *argv; - } else if (!strcmp(*argv,"ignore")) { - ctrl |= PAM_IGNORE_EMAIL; - } else { - pam_syslog(pamh, LOG_ERR, "unknown option: %s", *argv); - } - } - - return ctrl; -} - -/* - * check if name is in list or default list. place users name in *_user - * return 1 if listed 0 if not. - */ - -static int lookup(const char *name, const char *list, const char **_user) -{ - int anon = 0; - - *_user = name; /* this is the default */ - if (list && *list) { - const char *l; - char *list_copy, *x; - char *sptr; - - list_copy = x_strdup(list); - x = list_copy; - while (list_copy && (l = strtok_r(x, ",", &sptr))) { - x = NULL; - if (!strcmp(name, l)) { - *_user = list; - anon = 1; - } - } - _pam_overwrite(list_copy); - _pam_drop(list_copy); - } else { -#define MAX_L 2 - static const char *l[MAX_L] = { "ftp", "anonymous" }; - int i; - - for (i=0; i<MAX_L; ++i) { - if (!strcmp(l[i], name)) { - *_user = l[0]; - anon = 1; - break; - } - } - } - - return anon; -} - -/* --- authentication management functions (only) --- */ - -PAM_EXTERN int -pam_sm_authenticate (pam_handle_t *pamh, int flags UNUSED, - int argc, const char **argv) -{ - int retval, anon=0, ctrl; - const char *user; - const char *users = NULL; - - /* - * this module checks if the user name is ftp or annonymous. If - * this is the case, it can set the PAM_RUSER to the entered email - * address and SUCCEEDS, otherwise it FAILS. - */ - - ctrl = _pam_parse(pamh, argc, argv, &users); - - retval = pam_get_user(pamh, &user, NULL); - if (retval != PAM_SUCCESS || user == NULL) { - pam_syslog(pamh, LOG_ERR, "no user specified"); - return PAM_USER_UNKNOWN; - } - - if (!(ctrl & PAM_NO_ANON)) { - anon = lookup(user, users, &user); - } - - if (anon) { - retval = pam_set_item(pamh, PAM_USER, (const void *)user); - if (retval != PAM_SUCCESS || user == NULL) { - pam_syslog(pamh, LOG_ERR, "user resetting failed"); - return PAM_USER_UNKNOWN; - } - } - - /* - * OK. we require an email address for user or the user's password. - * - build conversation and get their input. - */ - - { - char *resp = NULL; - const char *token; - - if (!anon) - retval = pam_prompt (pamh, PAM_PROMPT_ECHO_OFF, &resp, - PLEASE_ENTER_PASSWORD, user); - else - retval = pam_prompt (pamh, PAM_PROMPT_ECHO_OFF, &resp, - GUEST_LOGIN_PROMPT); - - if (retval != PAM_SUCCESS) { - _pam_drop (resp); - return ((retval == PAM_CONV_AGAIN) - ? PAM_INCOMPLETE:PAM_AUTHINFO_UNAVAIL); - } - - if (anon) { - /* XXX: Some effort should be made to verify this email address! */ - - if (!(ctrl & PAM_IGNORE_EMAIL)) { - char *sptr; - token = strtok_r(resp, "@", &sptr); - retval = pam_set_item(pamh, PAM_RUSER, token); - - if ((token) && (retval == PAM_SUCCESS)) { - token = strtok_r(NULL, "@", &sptr); - retval = pam_set_item(pamh, PAM_RHOST, token); - } - } - - /* we are happy to grant annonymous access to the user */ - retval = PAM_SUCCESS; - - } else { - /* - * we have a password so set AUTHTOK - */ - - pam_set_item(pamh, PAM_AUTHTOK, resp); - - /* - * this module failed, but the next one might succeed with - * this password. - */ - - retval = PAM_AUTH_ERR; - } - - /* clean up */ - _pam_drop(resp); - - /* success or failure */ - - return retval; - } -} - -PAM_EXTERN int -pam_sm_setcred (pam_handle_t *pamh UNUSED, int flags UNUSED, - int argc UNUSED, const char **argv UNUSED) -{ - return PAM_IGNORE; -} - - -#ifdef PAM_STATIC - -/* static module data */ - -struct pam_module _pam_ftp_modstruct = { - "pam_ftp", - pam_sm_authenticate, - pam_sm_setcred, - NULL, - NULL, - NULL, - NULL, -}; - -#endif - -/* end of module definition */ diff --git a/modules/pam_ftp/tst-pam_ftp b/modules/pam_ftp/tst-pam_ftp deleted file mode 100755 index 1a4f67c7..00000000 --- a/modules/pam_ftp/tst-pam_ftp +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/sh -../../tests/tst-dlopen .libs/pam_ftp.so diff --git a/modules/pam_group/.cvsignore b/modules/pam_group/.cvsignore deleted file mode 100644 index 49b88179..00000000 --- a/modules/pam_group/.cvsignore +++ /dev/null @@ -1,9 +0,0 @@ -*.la -*.lo -.deps -.libs -Makefile -Makefile.in -README -group.conf.5 -pam_group.8 diff --git a/modules/pam_group/Makefile.am b/modules/pam_group/Makefile.am deleted file mode 100644 index 22dc831b..00000000 --- a/modules/pam_group/Makefile.am +++ /dev/null @@ -1,34 +0,0 @@ -# -# Copyright (c) 2005, 2006 Thorsten Kukuk <kukuk@suse.de> -# - -CLEANFILES = *~ - -EXTRA_DIST = README group.conf $(MANS) $(XMLS) tst-pam_group - -man_MANS = group.conf.5 pam_group.8 -XMLS = README.xml group.conf.5.xml pam_group.8.xml - -securelibdir = $(SECUREDIR) -secureconfdir = $(SCONFIGDIR) - -AM_CFLAGS = -I$(top_srcdir)/libpam/include -I$(top_srcdir)/libpamc/include \ - -DPAM_GROUP_CONF=\"$(SCONFIGDIR)/group.conf\" -AM_LDFLAGS = -no-undefined -avoid-version -module -if HAVE_VERSIONING - AM_LDFLAGS += -Wl,--version-script=$(srcdir)/../modules.map -endif - -securelib_LTLIBRARIES = pam_group.la -pam_group_la_LIBADD = -L$(top_builddir)/libpam -lpam - -secureconf_DATA = group.conf - -TESTS = tst-pam_group - -if ENABLE_REGENERATE_MAN -noinst_DATA = README -README: pam_group.8.xml group.conf.5.xml --include $(top_srcdir)/Make.xml.rules -endif - diff --git a/modules/pam_group/README.xml b/modules/pam_group/README.xml deleted file mode 100644 index 387d6987..00000000 --- a/modules/pam_group/README.xml +++ /dev/null @@ -1,34 +0,0 @@ -<?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 pamgroup SYSTEM "pam_group.8.xml"> ---> -<!-- -<!ENTITY groupconf SYSTEM "group.conf.5.xml"> ---> -]> - -<article> - - <articleinfo> - - <title> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" - href="pam_group.8.xml" xpointer='xpointer(//refnamediv[@id = "pam_group-name"]/*)'/> - </title> - - </articleinfo> - - <section> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" - href="pam_group.8.xml" xpointer='xpointer(//refsect1[@id = "pam_group-description"]/*)'/> - </section> - - <section> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" - href="group.conf.5.xml" xpointer='xpointer(//refsect1[@id = "group.conf-examples"]/*)'/> - </section> - -</article> diff --git a/modules/pam_group/group.conf b/modules/pam_group/group.conf deleted file mode 100644 index b766becb..00000000 --- a/modules/pam_group/group.conf +++ /dev/null @@ -1,99 +0,0 @@ -# -# This is the configuration file for the pam_group module. -# - -# -# *** Please note that giving group membership on a session basis is -# *** NOT inherently secure. If a user can create an executable that -# *** is setgid a group that they are infrequently given membership -# *** of, they can basically obtain group membership any time they -# *** like. Example: games are allowed between the hours of 6pm and 6am -# *** user joe logs in at 7pm writes a small C-program toplay.c that -# *** invokes their favorite shell, compiles it and does -# *** "chgrp play toplay; chmod g+s toplay". They are basically able -# *** to play games any time... You have been warned. AGM -# - -# -# The syntax of the lines is as follows: -# -# services;ttys;users;times;groups -# -# white space is ignored and lines maybe extended with '\\n' (escaped -# newlines). From reading these comments, it is clear that -# text following a '#' is ignored to the end of the line. -# -# the combination of individual users/terminals etc is a logic list -# namely individual tokens that are optionally prefixed with '!' (logical -# not) and separated with '&' (logical and) and '|' (logical or). -# -# services -# is a logic list of PAM service names that the rule applies to. -# -# ttys -# is a logic list of terminal names that this rule applies to. -# -# users -# is a logic list of users or a netgroup of users to whom this -# rule applies. -# -# NB. For these items the simple wildcard '*' may be used only once. -# With netgroups no wildcards or logic operators are allowed. -# -# times -# It is used to indicate "when" these groups are to be given to the -# user. The format here is a logic list of day/time-range -# entries the days are specified by a sequence of two character -# entries, MoTuSa for example is Monday Tuesday and Saturday. Note -# that repeated days are unset MoMo = no day, and MoWk = all weekdays -# bar Monday. The two character combinations accepted are -# -# Mo Tu We Th Fr Sa Su Wk Wd Al -# -# the last two being week-end days and all 7 days of the week -# respectively. As a final example, AlFr means all days except Friday. -# -# Each day/time-range can be prefixed with a '!' to indicate "anything -# but" -# -# The time-range part is two 24-hour times HHMM separated by a hyphen -# indicating the start and finish time (if the finish time is smaller -# than the start time it is deemed to apply on the following day). -# -# groups -# The (comma or space separated) list of groups that the user -# inherits membership of. These groups are added if the previous -# fields are satisfied by the user's request -# -# For a rule to be active, ALL of service+ttys+users must be satisfied -# by the applying process. -# - -# -# Note, to get this to work as it is currently typed you need -# -# 1. to run an application as root -# 2. add the following groups to the /etc/group file: -# floppy, play, sound -# - -# -# Here is a simple example: running 'xsh' on tty* (any ttyXXX device), -# the user 'us' is given access to the floppy (through membership of -# the floppy group) -# - -#xsh;tty*&!ttyp*;us;Al0000-2400;floppy - -# -# another example: running 'xsh' on tty* (any ttyXXX device), -# the user 'sword' is given access to games (through membership of -# the sound and play group) after work hours. -# - -#xsh; tty* ;sword;!Wk0900-1800;sound, play -#xsh; tty* ;*;Al0900-1800;floppy - -# -# End of group.conf file -# diff --git a/modules/pam_group/group.conf.5.xml b/modules/pam_group/group.conf.5.xml deleted file mode 100644 index 9c008eb0..00000000 --- a/modules/pam_group/group.conf.5.xml +++ /dev/null @@ -1,131 +0,0 @@ -<?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="group.conf"> - - <refmeta> - <refentrytitle>group.conf</refentrytitle> - <manvolnum>5</manvolnum> - <refmiscinfo class="sectdesc">Linux-PAM Manual</refmiscinfo> - </refmeta> - - <refnamediv> - <refname>group.conf</refname> - <refpurpose>configuration file for the pam_group module</refpurpose> - </refnamediv> - - <refsect1 id='group.conf-description'> - <title>DESCRIPTION</title> - - <para> - The pam_group PAM module does not authenticate the user, but instead - it grants group memberships (in the credential setting phase of the - authentication module) to the user. Such memberships are based on the - service they are applying for. - </para> - <para> - For this module to function correctly there must be a correctly - formatted <filename>/etc/security/group.conf</filename> file present. - White spaces are ignored and lines maybe extended with '\' (escaped - newlines). Text following a '#' is ignored to the end of the line. - </para> - - <para> - The syntax of the lines is as follows: - </para> - - <para> - <replaceable>services</replaceable>;<replaceable>ttys</replaceable>;<replaceable>users</replaceable>;<replaceable>times</replaceable>;<replaceable>groups</replaceable> - </para> - - - <para> - The first field, the <replaceable>services</replaceable> field, is a logic list - of PAM service names that the rule applies to. - </para> - - <para> - The second field, the <replaceable>tty</replaceable> - field, is a logic list of terminal names that this rule applies to. - </para> - - <para> - The third field, the <replaceable>users</replaceable> - field, is a logic list of users or a netgroup of users to whom this - rule applies. - </para> - - <para> - For these items the simple wildcard '*' may be used only once. - With netgroups no wildcards or logic operators are allowed. - </para> - - <para> - The <replaceable>times</replaceable> field is used to indicate "when" - these groups are to be given to the user. The format here is a logic - list of day/time-range entries. The days are specified by a sequence of - two character entries, MoTuSa for example is Monday Tuesday and Saturday. - Note that repeated days are unset MoMo = no day, and MoWk = all weekdays - bar Monday. The two character combinations accepted are Mo Tu We Th Fr Sa - Su Wk Wd Al, the last two being week-end days and all 7 days of the week - respectively. As a final example, AlFr means all days except Friday. - </para> - <para> - Each day/time-range can be prefixed with a '!' to indicate "anything but". - The time-range part is two 24-hour times HHMM, separated by a hyphen, - indicating the start and finish time (if the finish time is smaller - than the start time it is deemed to apply on the following day). - </para> - - <para> - The <replaceable>groups</replaceable> field is a comma or space - separated list of groups that the user inherits membership of. These - groups are added if the previous fields are satisfied by the user's request. - </para> - - <para> - For a rule to be active, ALL of service+ttys+users must be satisfied - by the applying process. - </para> - </refsect1> - - <refsect1 id="group.conf-examples"> - <title>EXAMPLES</title> - <para> - These are some example lines which might be specified in - <filename>/etc/security/group.conf</filename>. - </para> - - <para> - Running 'xsh' on tty* (any ttyXXX device), the user 'us' is given access - to the floppy (through membership of the floppy group) - </para> - <programlisting>xsh;tty*&!ttyp*;us;Al0000-2400;floppy</programlisting> - - <para> - Running 'xsh' on tty* (any ttyXXX device), the user 'sword' is given access - to games (through membership of the floppy group) after work hours. - </para> - <programlisting> -xsh; tty* ;sword;!Wk0900-1800;games, sound -xsh; tty* ;*;Al0900-1800;floppy - </programlisting> - </refsect1> - - <refsect1 id="group.conf-see_also"> - <title>SEE ALSO</title> - <para> - <citerefentry><refentrytitle>pam_group</refentrytitle><manvolnum>8</manvolnum></citerefentry>, - <citerefentry><refentrytitle>pam.d</refentrytitle><manvolnum>5</manvolnum></citerefentry>, - <citerefentry><refentrytitle>pam</refentrytitle><manvolnum>8</manvolnum></citerefentry> - </para> - </refsect1> - - <refsect1 id="group.conf-author"> - <title>AUTHOR</title> - <para> - pam_group was written by Andrew G. Morgan <morgan@kernel.org>. - </para> - </refsect1> -</refentry> diff --git a/modules/pam_group/pam_group.8.xml b/modules/pam_group/pam_group.8.xml deleted file mode 100644 index f7488fb3..00000000 --- a/modules/pam_group/pam_group.8.xml +++ /dev/null @@ -1,162 +0,0 @@ -<?xml version="1.0" encoding="ISO-8859-1"?> -<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN" - "http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd"> - -<refentry id='pam_group'> - - <refmeta> - <refentrytitle>pam_group</refentrytitle> - <manvolnum>8</manvolnum> - <refmiscinfo class='setdesc'>Linux-PAM Manual</refmiscinfo> - </refmeta> - - <refnamediv id='pam_group-name'> - <refname>pam_group</refname> - <refpurpose> - PAM module for group access - </refpurpose> - </refnamediv> - -<!-- body begins here --> - - <refsynopsisdiv> - <cmdsynopsis id="pam_group-cmdsynopsis"> - <command>pam_group.so</command> - </cmdsynopsis> - </refsynopsisdiv> - - - <refsect1 id="pam_group-description"> - <title>DESCRIPTION</title> - <para> - The pam_group PAM module does not authenticate the user, but instead - it grants group memberships (in the credential setting phase of the - authentication module) to the user. Such memberships are based on the - service they are applying for. - </para> - <para> - By default rules for group memberships are taken from config file - <filename>/etc/security/group.conf</filename>. - </para> - <para> - This module's usefulness relies on the file-systems - accessible to the user. The point being that once granted the - membership of a group, the user may attempt to create a - <function>setgid</function> binary with a restricted group ownership. - Later, when the user is not given membership to this group, they can - recover group membership with the precompiled binary. The reason that - the file-systems that the user has access to are so significant, is the - fact that when a system is mounted <emphasis>nosuid</emphasis> the user - is unable to create or execute such a binary file. For this module to - provide any level of security, all file-systems that the user has write - access to should be mounted <emphasis>nosuid</emphasis>. - </para> - <para> - The pam_group module fuctions in parallel with the - <filename>/etc/group</filename> file. If the user is granted any groups - based on the behavior of this module, they are granted - <emphasis>in addition</emphasis> to those entries - <filename>/etc/group</filename> (or equivalent). - </para> - </refsect1> - - <refsect1 id="pam_group-options"> - <title>OPTIONS</title> - <para>This module does not recognise any options.</para> - </refsect1> - - <refsect1 id="pam_group-services"> - <title>MODULE SERVICES PROVIDED</title> - <para> - Only the <option>auth</option> service is supported. - </para> - </refsect1> - - <refsect1 id="pam_group-return_values"> - <title>RETURN VALUES</title> - <variablelist> - <varlistentry> - <term>PAM_SUCCESS</term> - <listitem> - <para> - group membership was granted. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term>PAM_ABORT</term> - <listitem> - <para> - Not all relevant data could be gotten. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term>PAM_BUF_ERR</term> - <listitem> - <para> - Memory buffer error. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term>PAM_CRED_ERR</term> - <listitem> - <para> - Group membership was not granted. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term>PAM_IGNORE</term> - <listitem> - <para> - <function>pam_sm_authenticate</function> was called which does nothing. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term>PAM_USER_UNKNOWN</term> - <listitem> - <para> - The user is not known to the system. - </para> - </listitem> - </varlistentry> - </variablelist> - </refsect1> - - <refsect1 id="pam_group-files"> - <title>FILES</title> - <variablelist> - <varlistentry> - <term><filename>/etc/security/group.conf</filename></term> - <listitem> - <para>Default configuration file</para> - </listitem> - </varlistentry> - </variablelist> - </refsect1> - - <refsect1 id="pam_group-see_also"> - <title>SEE ALSO</title> - <para> - <citerefentry> - <refentrytitle>group.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_group-authors"> - <title>AUTHORS</title> - <para> - pam_group was written by Andrew G. Morgan <morgan@kernel.org>. - </para> - </refsect1> -</refentry> diff --git a/modules/pam_group/pam_group.c b/modules/pam_group/pam_group.c deleted file mode 100644 index 4a54da14..00000000 --- a/modules/pam_group/pam_group.c +++ /dev/null @@ -1,842 +0,0 @@ -/* pam_group module */ - -/* - * Written by Andrew Morgan <morgan@linux.kernel.org> 1996/7/6 - */ - -#include "config.h" - -#include <sys/file.h> -#include <stdio.h> -#include <stdlib.h> -#include <ctype.h> -#include <unistd.h> -#include <stdarg.h> -#include <time.h> -#include <syslog.h> -#include <string.h> - -#include <grp.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <fcntl.h> -#include <netdb.h> - -#define PAM_GROUP_BUFLEN 1000 -#define FIELD_SEPARATOR ';' /* this is new as of .02 */ - -#ifndef TRUE -# define TRUE 1 -#endif -#ifndef FALSE -# define FALSE 0 -#endif - -typedef enum { AND, OR } operator; - -/* - * here, we make definitions for the externally accessible functions - * in this file (these definitions are required for static modules - * but strongly encouraged generally) they are used to instruct the - * modules include file to define their prototypes. - */ - -#define PAM_SM_AUTH - -#include <security/pam_modules.h> -#include <security/_pam_macros.h> -#include <security/pam_modutil.h> -#include <security/pam_ext.h> - -/* --- static functions for checking whether the user should be let in --- */ - -static void shift_bytes(char *mem, int from, int by) -{ - while (by-- > 0) { - *mem = mem[from]; - ++mem; - } -} - -/* This function should initially be called with buf = NULL. If - * an error occurs, the file descriptor is closed. Subsequent - * calls with a closed descriptor will cause buf to be deallocated. - * Therefore, always check buf after calling this to see if an error - * occurred. - */ -static int -read_field (const pam_handle_t *pamh, int fd, char **buf, int *from, int *to) -{ - /* is buf set ? */ - - if (! *buf) { - *buf = (char *) malloc(PAM_GROUP_BUFLEN); - if (! *buf) { - pam_syslog(pamh, LOG_ERR, "out of memory"); - return -1; - } - *from = *to = 0; - fd = open(PAM_GROUP_CONF, O_RDONLY); - } - - /* do we have a file open ? return error */ - - if (fd < 0 && *to <= 0) { - pam_syslog(pamh, LOG_ERR, "%s not opened", PAM_GROUP_CONF); - memset(*buf, 0, PAM_GROUP_BUFLEN); - _pam_drop(*buf); - return -1; - } - - /* check if there was a newline last time */ - - if ((*to > *from) && (*to > 0) - && ((*buf)[*from] == '\0')) { /* previous line ended */ - (*from)++; - (*buf)[0] = '\0'; - return fd; - } - - /* ready for more data: first shift the buffer's remaining data */ - - *to -= *from; - shift_bytes(*buf, *from, *to); - *from = 0; - (*buf)[*to] = '\0'; - - while (fd >= 0 && *to < PAM_GROUP_BUFLEN) { - int i; - - /* now try to fill the remainder of the buffer */ - - i = read(fd, *to + *buf, PAM_GROUP_BUFLEN - *to); - if (i < 0) { - pam_syslog(pamh, LOG_ERR, "error reading %s: %m", PAM_GROUP_CONF); - close(fd); - return -1; - } else if (!i) { - close(fd); - fd = -1; /* end of file reached */ - } else - *to += i; - - /* - * contract the buffer. Delete any comments, and replace all - * multiple spaces with single commas - */ - - i = 0; -#ifdef DEBUG_DUMP - D(("buffer=<%s>",*buf)); -#endif - while (i < *to) { - if ((*buf)[i] == ',') { - int j; - - for (j=++i; j<*to && (*buf)[j] == ','; ++j); - if (j!=i) { - shift_bytes(i + (*buf), j-i, (*to) - j); - *to -= j-i; - } - } - switch ((*buf)[i]) { - int j, c; - case '#': - c = 0; - for (j=i; j < *to && (c = (*buf)[j]) != '\n'; ++j); - if (j >= *to) { - (*buf)[*to = ++i] = '\0'; - } else if (c == '\n') { - shift_bytes(i + (*buf), j-i, (*to) - j); - *to -= j-i; - ++i; - } else { - pam_syslog(pamh, LOG_CRIT, - "internal error in file %s at line %d", - __FILE__, __LINE__); - close(fd); - return -1; - } - break; - case '\\': - if ((*buf)[i+1] == '\n') { - shift_bytes(i + *buf, 2, *to - (i+2)); - *to -= 2; - } else { - ++i; /* we don't escape non-newline characters */ - } - break; - case '!': - case ' ': - case '\t': - if ((*buf)[i] != '!') - (*buf)[i] = ','; - /* delete any trailing spaces */ - for (j=++i; j < *to && ( (c = (*buf)[j]) == ' ' - || c == '\t' ); ++j); - shift_bytes(i + *buf, j-i, (*to)-j ); - *to -= j-i; - break; - default: - ++i; - } - } - } - - (*buf)[*to] = '\0'; - - /* now return the next field (set the from/to markers) */ - { - int i; - - for (i=0; i<*to; ++i) { - switch ((*buf)[i]) { - case '#': - case '\n': /* end of the line/file */ - (*buf)[i] = '\0'; - *from = i; - return fd; - case FIELD_SEPARATOR: /* end of the field */ - (*buf)[i] = '\0'; - *from = ++i; - return fd; - } - } - *from = i; - (*buf)[*from] = '\0'; - } - - if (*to <= 0) { - D(("[end of text]")); - *buf = NULL; - } - return fd; -} - -/* read a member from a field */ - -static int logic_member(const char *string, int *at) -{ - int c,to; - int done=0; - int token=0; - - to=*at; - do { - c = string[to++]; - - switch (c) { - - case '\0': - --to; - done = 1; - break; - - case '&': - case '|': - case '!': - if (token) { - --to; - } - done = 1; - break; - - default: - if (isalpha(c) || c == '*' || isdigit(c) || c == '_' - || c == '-' || c == '.' || c == '/' || c == ':') { - token = 1; - } else if (token) { - --to; - done = 1; - } else { - ++*at; - } - } - } while (!done); - - return to - *at; -} - -typedef enum { VAL, OP } expect; - -static int -logic_field (const pam_handle_t *pamh, const void *me, - const char *x, int rule, - int (*agrees)(const pam_handle_t *pamh, const void *, - const char *, int, int)) -{ - int left=FALSE, right, not=FALSE; - operator oper=OR; - int at=0, l; - expect next=VAL; - - while ((l = logic_member(x,&at))) { - int c = x[at]; - - if (next == VAL) { - if (c == '!') - not = !not; - else if (isalpha(c) || c == '*' || isdigit(c) || c == '_' - || c == '-' || c == '.' || c == '/' || c == ':') { - right = not ^ agrees(pamh, me, x+at, l, rule); - if (oper == AND) - left &= right; - else - left |= right; - next = OP; - } else { - pam_syslog(pamh, LOG_ERR, - "garbled syntax; expected name (rule #%d)", - rule); - return FALSE; - } - } else { /* OP */ - switch (c) { - case '&': - oper = AND; - break; - case '|': - oper = OR; - break; - default: - pam_syslog(pamh, LOG_ERR, - "garbled syntax; expected & or | (rule #%d)", - rule); - D(("%c at %d",c,at)); - return FALSE; - } - next = VAL; - } - at += l; - } - - return left; -} - -static int -is_same (const pam_handle_t *pamh UNUSED, - const void *A, const char *b, int len, int rule UNUSED) -{ - int i; - const char *a; - - a = A; - for (i=0; len > 0; ++i, --len) { - if (b[i] != a[i]) { - if (b[i++] == '*') { - return (!--len || !strncmp(b+i,a+strlen(a)-len,len)); - } else - return FALSE; - } - } - - /* Ok, we know that b is a substring from A and does not contain - wildcards, but now the length of both strings must be the same, - too. */ - if (strlen (a) != strlen(b)) - return FALSE; - - return ( !len ); -} - -typedef struct { - int day; /* array of 7 bits, one set for today */ - int minute; /* integer, hour*100+minute for now */ -} TIME; - -static struct day { - const char *d; - int bit; -} const days[11] = { - { "su", 01 }, - { "mo", 02 }, - { "tu", 04 }, - { "we", 010 }, - { "th", 020 }, - { "fr", 040 }, - { "sa", 0100 }, - { "wk", 076 }, - { "wd", 0101 }, - { "al", 0177 }, - { NULL, 0 } -}; - -static TIME time_now(void) -{ - struct tm *local; - time_t the_time; - TIME this; - - the_time = time((time_t *)0); /* get the current time */ - local = localtime(&the_time); - this.day = days[local->tm_wday].bit; - this.minute = local->tm_hour*100 + local->tm_min; - - D(("day: 0%o, time: %.4d", this.day, this.minute)); - return this; -} - -/* take the current date and see if the range "date" passes it */ -static int -check_time (const pam_handle_t *pamh, const void *AT, - const char *times, int len, int rule) -{ - int not,pass; - int marked_day, time_start, time_end; - const TIME *at; - int i,j=0; - - at = AT; - D(("checking: 0%o/%.4d vs. %s", at->day, at->minute, times)); - - if (times == NULL) { - /* this should not happen */ - pam_syslog(pamh, LOG_CRIT, "internal error in file %s at line %d", - __FILE__, __LINE__); - return FALSE; - } - - if (times[j] == '!') { - ++j; - not = TRUE; - } else { - not = FALSE; - } - - for (marked_day = 0; len > 0 && isalpha(times[j]); --len) { - int this_day=-1; - - D(("%c%c ?", times[j], times[j+1])); - for (i=0; days[i].d != NULL; ++i) { - if (tolower(times[j]) == days[i].d[0] - && tolower(times[j+1]) == days[i].d[1] ) { - this_day = days[i].bit; - break; - } - } - j += 2; - if (this_day == -1) { - pam_syslog(pamh, LOG_ERR, "bad day specified (rule #%d)", rule); - return FALSE; - } - marked_day ^= this_day; - } - if (marked_day == 0) { - pam_syslog(pamh, LOG_ERR, "no day specified"); - return FALSE; - } - D(("day range = 0%o", marked_day)); - - time_start = 0; - for (i=0; len > 0 && i < 4 && isdigit(times[i+j]); ++i, --len) { - time_start *= 10; - time_start += times[i+j]-'0'; /* is this portable? */ - } - j += i; - - if (times[j] == '-') { - time_end = 0; - for (i=1; len > 0 && i < 5 && isdigit(times[i+j]); ++i, --len) { - time_end *= 10; - time_end += times[i+j]-'0'; /* is this portable? */ - } - j += i; - } else - time_end = -1; - - D(("i=%d, time_end=%d, times[j]='%c'", i, time_end, times[j])); - if (i != 5 || time_end == -1) { - pam_syslog(pamh, LOG_ERR, "no/bad times specified (rule #%d)", rule); - return TRUE; - } - D(("times(%d to %d)", time_start,time_end)); - D(("marked_day = 0%o", marked_day)); - - /* compare with the actual time now */ - - pass = FALSE; - if (time_start < time_end) { /* start < end ? --> same day */ - if ((at->day & marked_day) && (at->minute >= time_start) - && (at->minute < time_end)) { - D(("time is listed")); - pass = TRUE; - } - } else { /* spans two days */ - if ((at->day & marked_day) && (at->minute >= time_start)) { - D(("caught on first day")); - pass = TRUE; - } else { - marked_day <<= 1; - marked_day |= (marked_day & 0200) ? 1:0; - D(("next day = 0%o", marked_day)); - if ((at->day & marked_day) && (at->minute <= time_end)) { - D(("caught on second day")); - pass = TRUE; - } - } - } - - return (not ^ pass); -} - -static int find_member(const char *string, int *at) -{ - int c,to; - int done=0; - int token=0; - - to=*at; - do { - c = string[to++]; - - switch (c) { - - case '\0': - --to; - done = 1; - break; - - case '&': - case '|': - case '!': - if (token) { - --to; - } - done = 1; - break; - - default: - if (isalpha(c) || isdigit(c) || c == '_' || c == '*' - || c == '-') { - token = 1; - } else if (token) { - --to; - done = 1; - } else { - ++*at; - } - } - } while (!done); - - return to - *at; -} - -#define GROUP_BLK 10 -#define blk_size(len) (((len-1 + GROUP_BLK)/GROUP_BLK)*GROUP_BLK) - -static int mkgrplist(pam_handle_t *pamh, char *buf, gid_t **list, int len) -{ - int l,at=0; - int blks; - - blks = blk_size(len); - D(("cf. blks=%d and len=%d", blks,len)); - - while ((l = find_member(buf,&at))) { - int edge; - - if (len >= blks) { - gid_t *tmp; - - D(("allocating new block")); - tmp = (gid_t *) realloc((*list) - , sizeof(gid_t) * (blks += GROUP_BLK)); - if (tmp != NULL) { - (*list) = tmp; - } else { - pam_syslog(pamh, LOG_ERR, "out of memory for group list"); - free(*list); - (*list) = NULL; - return -1; - } - } - - /* '\0' terminate the entry */ - - edge = (buf[at+l]) ? 1:0; - buf[at+l] = '\0'; - D(("found group: %s",buf+at)); - - /* this is where we convert a group name to a gid_t */ - { - const struct group *grp; - - grp = pam_modutil_getgrnam(pamh, buf+at); - if (grp == NULL) { - pam_syslog(pamh, LOG_ERR, "bad group: %s", buf+at); - } else { - D(("group %s exists", buf+at)); - (*list)[len++] = grp->gr_gid; - } - } - - /* next entry along */ - - at += l + edge; - } - D(("returning with [%p/len=%d]->%p",list,len,*list)); - return len; -} - - -static int check_account(pam_handle_t *pamh, const char *service, - const char *tty, const char *user) -{ - int from=0,to=0,fd=-1; - char *buffer=NULL; - int count=0; - TIME here_and_now; - int retval=PAM_SUCCESS; - gid_t *grps; - int no_grps; - - /* - * first we get the current list of groups - the application - * will have previously done an initgroups(), or equivalent. - */ - - D(("counting supplementary groups")); - no_grps = getgroups(0, NULL); /* find the current number of groups */ - if (no_grps > 0) { - grps = calloc( blk_size(no_grps) , sizeof(gid_t) ); - D(("copying current list into grps [%d big]",blk_size(no_grps))); - if (getgroups(no_grps, grps) < 0) { - D(("getgroups call failed")); - no_grps = 0; - grps = NULL; - } -#ifdef DEBUG - { - int z; - for (z=0; z<no_grps; ++z) { - D(("gid[%d]=%d", z, grps[z])); - } - } -#endif - } else { - D(("no supplementary groups known")); - no_grps = 0; - grps = NULL; - } - - here_and_now = time_now(); /* find current time */ - - /* parse the rules in the configuration file */ - do { - int good=TRUE; - - /* here we get the service name field */ - - fd = read_field(pamh,fd,&buffer,&from,&to); - if (!buffer || !buffer[0]) { - /* empty line .. ? */ - continue; - } - ++count; - D(("working on rule #%d",count)); - - good = logic_field(pamh,service, buffer, count, is_same); - D(("with service: %s", good ? "passes":"fails" )); - - /* here we get the terminal name field */ - - fd = read_field(pamh,fd,&buffer,&from,&to); - if (!buffer || !buffer[0]) { - pam_syslog(pamh, LOG_ERR, - "%s: no tty entry #%d", PAM_GROUP_CONF, count); - continue; - } - good &= logic_field(pamh,tty, buffer, count, is_same); - D(("with tty: %s", good ? "passes":"fails" )); - - /* here we get the username field */ - - fd = read_field(pamh,fd,&buffer,&from,&to); - if (!buffer || !buffer[0]) { - pam_syslog(pamh, LOG_ERR, - "%s: no user entry #%d", PAM_GROUP_CONF, count); - continue; - } - /* If buffer starts with @, we are using netgroups */ - if (buffer[0] == '@') - good &= innetgr (&buffer[1], NULL, user, NULL); - else - good &= logic_field(pamh,user, buffer, count, is_same); - D(("with user: %s", good ? "passes":"fails" )); - - /* here we get the time field */ - - fd = read_field(pamh,fd,&buffer,&from,&to); - if (!buffer || !buffer[0]) { - pam_syslog(pamh, LOG_ERR, - "%s: no time entry #%d", PAM_GROUP_CONF, count); - continue; - } - - good &= logic_field(pamh,&here_and_now, buffer, count, check_time); - D(("with time: %s", good ? "passes":"fails" )); - - fd = read_field(pamh,fd,&buffer,&from,&to); - if (!buffer || !buffer[0]) { - pam_syslog(pamh, LOG_ERR, - "%s: no listed groups for rule #%d", PAM_GROUP_CONF, count); - continue; - } - - /* - * so we have a list of groups, we need to turn it into - * something to send to setgroups(2) - */ - - if (good) { - D(("adding %s to gid list", buffer)); - good = mkgrplist(pamh, buffer, &grps, no_grps); - if (good < 0) { - no_grps = 0; - } else { - no_grps = good; - } - } - - /* check the line is terminated correctly */ - - fd = read_field(pamh,fd,&buffer,&from,&to); - if (buffer && buffer[0]) { - pam_syslog(pamh, LOG_ERR, - "%s: poorly terminated rule #%d", PAM_GROUP_CONF, count); - } - - if (good > 0) { - D(("rule #%d passed, added %d groups", count, good)); - } else if (good < 0) { - retval = PAM_BUF_ERR; - } else { - D(("rule #%d failed", count)); - } - - } while (buffer); - - /* now set the groups for the user */ - - if (no_grps > 0) { -#ifdef DEBUG - int err; -#endif - D(("trying to set %d groups", no_grps)); -#ifdef DEBUG - for (err=0; err<no_grps; ++err) { - D(("gid[%d]=%d", err, grps[err])); - } -#endif - if (setgroups(no_grps, grps) != 0) { - D(("but couldn't set groups %m")); - pam_syslog(pamh, LOG_ERR, - "unable to set the group membership for user: %m"); - retval = PAM_CRED_ERR; - } - } - - if (grps) { /* tidy up */ - memset(grps, 0, sizeof(gid_t) * blk_size(no_grps)); - _pam_drop(grps); - no_grps = 0; - } - - return retval; -} - -/* --- public authentication management functions --- */ - -PAM_EXTERN int -pam_sm_authenticate (pam_handle_t *pamh UNUSED, int flags UNUSED, - int argc UNUSED, const char **argv UNUSED) -{ - return PAM_IGNORE; -} - -PAM_EXTERN int -pam_sm_setcred (pam_handle_t *pamh, int flags, - int argc UNUSED, const char **argv UNUSED) -{ - const void *service=NULL, *void_tty=NULL; - const char *user=NULL; - const char *tty; - int retval; - unsigned setting; - - /* only interested in establishing credentials */ - - setting = flags; - if (!(setting & (PAM_ESTABLISH_CRED | PAM_REINITIALIZE_CRED))) { - D(("ignoring call - not for establishing credentials")); - return PAM_SUCCESS; /* don't fail because of this */ - } - - /* set service name */ - - if (pam_get_item(pamh, PAM_SERVICE, &service) - != PAM_SUCCESS || service == NULL) { - pam_syslog(pamh, LOG_ERR, "cannot find the current service name"); - return PAM_ABORT; - } - - /* set username */ - - 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; - } - - /* set tty name */ - - if (pam_get_item(pamh, PAM_TTY, &void_tty) != PAM_SUCCESS - || void_tty == NULL) { - D(("PAM_TTY not set, probing stdin")); - tty = ttyname(STDIN_FILENO); - if (tty == NULL) { - tty = ""; - } - if (pam_set_item(pamh, PAM_TTY, tty) != PAM_SUCCESS) { - pam_syslog(pamh, LOG_ERR, "couldn't set tty name"); - return PAM_ABORT; - } - } - else - tty = (const char *) void_tty; - - if (tty[0] == '/') { /* full path */ - const char *t; - tty++; - if ((t = strchr(tty, '/')) != NULL) { - tty = t + 1; - } - } - - /* good, now we have the service name, the user and the terminal name */ - - D(("service=%s", service)); - D(("user=%s", user)); - D(("tty=%s", tty)); - - retval = check_account(pamh,service,tty,user); /* get groups */ - - return retval; -} - -/* end of module definition */ - -#ifdef PAM_STATIC - -/* static module data */ - -struct pam_module _pam_group_modstruct = { - "pam_group", - pam_sm_authenticate, - pam_sm_setcred, - NULL, - NULL, - NULL, - NULL -}; -#endif diff --git a/modules/pam_group/tst-pam_group b/modules/pam_group/tst-pam_group deleted file mode 100755 index 29f7ba06..00000000 --- a/modules/pam_group/tst-pam_group +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/sh -../../tests/tst-dlopen .libs/pam_group.so diff --git a/modules/pam_issue/.cvsignore b/modules/pam_issue/.cvsignore deleted file mode 100644 index 8754cdf0..00000000 --- a/modules/pam_issue/.cvsignore +++ /dev/null @@ -1,8 +0,0 @@ -*.la -*.lo -.deps -.libs -Makefile -Makefile.in -README -pam_issue.8 diff --git a/modules/pam_issue/Makefile.am b/modules/pam_issue/Makefile.am deleted file mode 100644 index 8161fd81..00000000 --- a/modules/pam_issue/Makefile.am +++ /dev/null @@ -1,31 +0,0 @@ -# -# Copyright (c) 2005, 2006 Thorsten Kukuk <kukuk@suse.de> -# - -CLEANFILES = *~ - -EXTRA_DIST = README $(MANS) $(XMLS) tst-pam_issue - -man_MANS = pam_issue.8 -XMLS = README.xml pam_issue.8.xml - -TESTS = tst-pam_issue - -securelibdir = $(SECUREDIR) -secureconfdir = $(SCONFIGDIR) - -AM_CFLAGS = -I$(top_srcdir)/libpam/include -I$(top_srcdir)/libpamc/include -AM_LDFLAGS = -no-undefined -avoid-version -module -if HAVE_VERSIONING - AM_LDFLAGS += -Wl,--version-script=$(srcdir)/../modules.map -endif - -securelib_LTLIBRARIES = pam_issue.la -pam_issue_la_LIBADD = -L$(top_builddir)/libpam -lpam - -if ENABLE_REGENERATE_MAN -noinst_DATA = README -README: pam_issue.8.xml --include $(top_srcdir)/Make.xml.rules -endif - diff --git a/modules/pam_issue/README.xml b/modules/pam_issue/README.xml deleted file mode 100644 index b5b61c3a..00000000 --- a/modules/pam_issue/README.xml +++ /dev/null @@ -1,41 +0,0 @@ -<?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_issue.8.xml"> ---> -]> - -<article> - - <articleinfo> - - <title> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" - href="pam_issue.8.xml" xpointer='xpointer(//refnamediv[@id = "pam_issue-name"]/*)'/> - </title> - - </articleinfo> - - <section> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" - href="pam_issue.8.xml" xpointer='xpointer(//refsect1[@id = "pam_issue-description"]/*)'/> - </section> - - <section> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" - href="pam_issue.8.xml" xpointer='xpointer(//refsect1[@id = "pam_issue-options"]/*)'/> - </section> - - <section> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" - href="pam_issue.8.xml" xpointer='xpointer(//refsect1[@id = "pam_issue-examples"]/*)'/> - </section> - - <section> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" - href="pam_issue.8.xml" xpointer='xpointer(//refsect1[@id = "pam_issue-author"]/*)'/> - </section> - -</article> diff --git a/modules/pam_issue/pam_issue.8.xml b/modules/pam_issue/pam_issue.8.xml deleted file mode 100644 index fd0d06ae..00000000 --- a/modules/pam_issue/pam_issue.8.xml +++ /dev/null @@ -1,234 +0,0 @@ -<?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_issue"> - - <refmeta> - <refentrytitle>pam_issue</refentrytitle> - <manvolnum>8</manvolnum> - <refmiscinfo class="sectdesc">Linux-PAM Manual</refmiscinfo> - </refmeta> - - <refnamediv id="pam_issue-name"> - <refname>pam_issue</refname> - <refpurpose>PAM module to add issue file to user prompt</refpurpose> - </refnamediv> - - <refsynopsisdiv> - <cmdsynopsis id="pam_issue-cmdsynopsis"> - <command>pam_issue.so</command> - <arg choice="opt"> - noesc - </arg> - <arg choice="opt"> - issue=<replaceable>issue-file-name</replaceable> - </arg> - </cmdsynopsis> - </refsynopsisdiv> - - <refsect1 id="pam_issue-description"> - - <title>DESCRIPTION</title> - - <para> - pam_issue is a PAM module to prepend an issue file to the username - prompt. It also by default parses escape codes in the issue file - similar to some common getty's (using \x format). - </para> - <para> - Recognized escapes: - </para> - <variablelist> - <varlistentry> - <term><emphasis remap='B'>\d</emphasis></term> - <listitem> - <para>current day</para> - </listitem> - </varlistentry> - <varlistentry> - <term><emphasis remap='B'>\l</emphasis></term> - <listitem> - <para>name of this tty</para> - </listitem> - </varlistentry> - <varlistentry> - <term><emphasis remap='B'>\m</emphasis></term> - <listitem> - <para>machine architecture (uname -m)</para> - </listitem> - </varlistentry> - <varlistentry> - <term><emphasis remap='B'>\n</emphasis></term> - <listitem> - <para>machine's network node hostname (uname -n)</para> - </listitem> - </varlistentry> - <varlistentry> - <term><emphasis remap='B'>\o</emphasis></term> - <listitem> - <para>domain name of this system</para> - </listitem> - </varlistentry> - <varlistentry> - <term><emphasis remap='B'>\r</emphasis></term> - <listitem> - <para>release number of operating system (uname -r)</para> - </listitem> - </varlistentry> - <varlistentry> - <term><emphasis remap='B'>\t</emphasis></term> - <listitem> - <para>current time</para> - </listitem> - </varlistentry> - <varlistentry> - <term><emphasis remap='B'>\s</emphasis></term> - <listitem> - <para>operating system name (uname -s)</para> - </listitem> - </varlistentry> - <varlistentry> - <term><emphasis remap='B'>\u</emphasis></term> - <listitem> - <para>number of users currently logged in</para> - </listitem> - </varlistentry> - <varlistentry> - <term><emphasis remap='B'>\U</emphasis></term> - <listitem> - <para> - same as \u except it is suffixed with "user" or - "users" (eg. "1 user" or "10 users") - </para> - </listitem> - </varlistentry> - <varlistentry> - <term><emphasis remap='B'>\v</emphasis></term> - <listitem> - <para>operating system version and build date (uname -v)</para> - </listitem> - </varlistentry> - </variablelist> - - </refsect1> - - <refsect1 id="pam_issue-options"> - - <title>OPTIONS</title> - <para> - <variablelist> - - <varlistentry> - <term> - <option>noesc</option> - </term> - <listitem> - <para> - Turns off escape code parsing. - </para> - </listitem> - </varlistentry> - - <varlistentry> - <term> - <option>issue=<replaceable>issue-file-name</replaceable></option> - </term> - <listitem> - <para> - The file to output if not using the default. - </para> - </listitem> - </varlistentry> - - </variablelist> - - </para> - </refsect1> - - <refsect1 id="pam_issue-services"> - <title>MODULE SERVICES PROVIDED</title> - <para> - Only the <option>auth</option> service is supported. - </para> - </refsect1> - - <refsect1 id='pam_issue-return_values'> - <title>RETURN VALUES</title> - <para> - <variablelist> - - <varlistentry> - <term>PAM_BUF_ERR</term> - <listitem> - <para> - Memory buffer error. - </para> - </listitem> - </varlistentry> - - <varlistentry> - <term>PAM_IGNORE</term> - <listitem> - <para> - The prompt was already changed. - </para> - </listitem> - </varlistentry> - - <varlistentry> - <term>PAM_SERVICE_ERR</term> - <listitem> - <para> - A service module error occured. - </para> - </listitem> - </varlistentry> - - <varlistentry> - <term>PAM_SUCCESS</term> - <listitem> - <para> - The new prompt was set successfull. - </para> - </listitem> - </varlistentry> - - </variablelist> - </para> - </refsect1> - - <refsect1 id='pam_issue-examples'> - <title>EXAMPLES</title> - <para> - Add the following line to <filename>/etc/pam.d/login</filename> to - set the user specific issue at login: - <programlisting> - auth optional pam_issue.so issue=/etc/issue - </programlisting> - </para> - </refsect1> - - <refsect1 id='pam_issue-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_issue-author'> - <title>AUTHOR</title> - <para> - pam_issue was written by Ben Collins <bcollins@debian.org>. - </para> - </refsect1> - -</refentry> diff --git a/modules/pam_issue/pam_issue.c b/modules/pam_issue/pam_issue.c deleted file mode 100644 index 7a8a24d5..00000000 --- a/modules/pam_issue/pam_issue.c +++ /dev/null @@ -1,310 +0,0 @@ -/* pam_issue module - a simple /etc/issue parser to set PAM_USER_PROMPT - * - * Copyright 1999 by Ben Collins <bcollins@debian.org> - * - * Needs to be called before any other auth modules so we can setup the - * user prompt before it's first used. Allows one argument option, which - * is the full path to a file to be used for issue (uses /etc/issue as a - * default) such as "issue=/etc/issue.telnet". - * - * We can also parse escapes within the the issue file (enabled by - * default, but can be disabled with the "noesc" option). It's the exact - * same parsing as util-linux's agetty program performs. - * - * Released under the GNU LGPL version 2 or later - */ - -#include "config.h" - -#include <string.h> -#include <stdio.h> -#include <stdlib.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <fcntl.h> -#include <string.h> -#include <unistd.h> -#include <sys/utsname.h> -#include <utmp.h> -#include <time.h> -#include <syslog.h> - -#define PAM_SM_AUTH - -#include <security/_pam_macros.h> -#include <security/pam_modules.h> -#include <security/pam_ext.h> - -static int _user_prompt_set = 0; - -static int read_issue_raw(pam_handle_t *pamh, FILE *fp, char **prompt); -static int read_issue_quoted(pam_handle_t *pamh, FILE *fp, char **prompt); - -/* --- authentication management functions (only) --- */ - -PAM_EXTERN int -pam_sm_authenticate (pam_handle_t *pamh, int flags UNUSED, - int argc, const char **argv) -{ - int retval = PAM_SERVICE_ERR; - FILE *fp; - const char *issue_file = NULL; - int parse_esc = 1; - const void *item = NULL; - const char *cur_prompt; - char *issue_prompt = NULL; - - /* If we've already set the prompt, don't set it again */ - if(_user_prompt_set) - return PAM_IGNORE; - - /* We set this here so if we fail below, we wont get further - than this next time around (only one real failure) */ - _user_prompt_set = 1; - - for ( ; argc-- > 0 ; ++argv ) { - if (!strncmp(*argv,"issue=",6)) { - issue_file = 6 + *argv; - D(("set issue_file to: %s", issue_file)); - } else if (!strcmp(*argv,"noesc")) { - parse_esc = 0; - D(("turning off escape parsing by request")); - } else - D(("unknown option passed: %s", *argv)); - } - - if (issue_file == NULL) - issue_file = "/etc/issue"; - - if ((fp = fopen(issue_file, "r")) == NULL) { - pam_syslog(pamh, LOG_ERR, "error opening %s: %m", issue_file); - return PAM_SERVICE_ERR; - } - - if ((retval = pam_get_item(pamh, PAM_USER_PROMPT, &item)) != PAM_SUCCESS) { - fclose(fp); - return retval; - } - - cur_prompt = item; - if (cur_prompt == NULL) - cur_prompt = ""; - - if (parse_esc) - retval = read_issue_quoted(pamh, fp, &issue_prompt); - else - retval = read_issue_raw(pamh, fp, &issue_prompt); - - fclose(fp); - - if (retval != PAM_SUCCESS) - goto out; - - { - size_t size = strlen(issue_prompt) + strlen(cur_prompt) + 1; - char *new_prompt = realloc(issue_prompt, size); - - if (new_prompt == NULL) { - pam_syslog(pamh, LOG_ERR, "out of memory"); - retval = PAM_BUF_ERR; - goto out; - } - issue_prompt = new_prompt; - } - - strcat(issue_prompt, cur_prompt); - retval = pam_set_item(pamh, PAM_USER_PROMPT, - (const void *) issue_prompt); - out: - _pam_drop(issue_prompt); - return (retval == PAM_SUCCESS) ? PAM_IGNORE : retval; -} - -PAM_EXTERN int -pam_sm_setcred (pam_handle_t *pamh UNUSED, int flags UNUSED, - int argc UNUSED, const char **argv UNUSED) -{ - return PAM_IGNORE; -} - -static int -read_issue_raw(pam_handle_t *pamh, FILE *fp, char **prompt) -{ - char *issue; - struct stat st; - - *prompt = NULL; - - if (fstat(fileno(fp), &st) < 0) { - pam_syslog(pamh, LOG_ERR, "stat error: %m"); - return PAM_SERVICE_ERR; - } - - if ((issue = malloc(st.st_size + 1)) == NULL) { - pam_syslog(pamh, LOG_ERR, "out of memory"); - return PAM_BUF_ERR; - } - - if (fread(issue, 1, st.st_size, fp) != st.st_size) { - pam_syslog(pamh, LOG_ERR, "read error: %m"); - _pam_drop(issue); - return PAM_SERVICE_ERR; - } - - issue[st.st_size] = '\0'; - *prompt = issue; - return PAM_SUCCESS; -} - -static int -read_issue_quoted(pam_handle_t *pamh, FILE *fp, char **prompt) -{ - int c; - size_t size = 1024; - char *issue; - struct utsname uts; - - *prompt = NULL; - - if ((issue = malloc(size)) == NULL) { - pam_syslog(pamh, LOG_ERR, "out of memory"); - return PAM_BUF_ERR; - } - - issue[0] = '\0'; - (void) uname(&uts); - - while ((c = getc(fp)) != EOF) { - char buf[1024]; - - buf[0] = '\0'; - if (c == '\\') { - if ((c = getc(fp)) == EOF) - break; - switch (c) { - case 's': - strncat(buf, uts.sysname, sizeof(buf) - 1); - break; - case 'n': - strncat(buf, uts.nodename, sizeof(buf) - 1); - break; - case 'r': - strncat(buf, uts.release, sizeof(buf) - 1); - break; - case 'v': - strncat(buf, uts.version, sizeof(buf) - 1); - break; - case 'm': - strncat(buf, uts.machine, sizeof(buf) - 1); - break; - case 'o': - { - char domainname[256]; - - if (getdomainname(domainname, sizeof(domainname)) >= 0) { - domainname[sizeof(domainname)-1] = '\0'; - strncat(buf, domainname, sizeof(buf) - 1); - } - } - break; - case 'd': - case 't': - { - const char *weekday[] = { - "Sun", "Mon", "Tue", "Wed", "Thu", - "Fri", "Sat" }; - const char *month[] = { - "Jan", "Feb", "Mar", "Apr", "May", - "Jun", "Jul", "Aug", "Sep", "Oct", - "Nov", "Dec" }; - time_t now; - struct tm *tm; - - (void) time (&now); - tm = localtime(&now); - - if (c == 'd') - snprintf (buf, sizeof buf, "%s %s %d %d", - weekday[tm->tm_wday], month[tm->tm_mon], - tm->tm_mday, tm->tm_year + 1900); - else - snprintf (buf, sizeof buf, "%02d:%02d:%02d", - tm->tm_hour, tm->tm_min, tm->tm_sec); - } - break; - case 'l': - { - char *ttyn = ttyname(1); - if (ttyn) { - if (!strncmp(ttyn, "/dev/", 5)) - ttyn += 5; - strncat(buf, ttyn, sizeof(buf) - 1); - } - } - break; - case 'u': - case 'U': - { - unsigned int users = 0; - struct utmp *ut; - setutent(); - while ((ut = getutent())) { - if (ut->ut_type == USER_PROCESS) - ++users; - } - endutent(); - if (c == 'U') - snprintf (buf, sizeof buf, "%u %s", users, - (users == 1) ? "user" : "users"); - else - snprintf (buf, sizeof buf, "%u", users); - break; - } - default: - buf[0] = c; buf[1] = '\0'; - } - } else { - buf[0] = c; buf[1] = '\0'; - } - - if ((strlen(issue) + strlen(buf)) + 1 > size) { - char *new_issue; - - size += strlen(buf) + 1; - new_issue = (char *) realloc (issue, size); - if (new_issue == NULL) { - _pam_drop(issue); - return PAM_BUF_ERR; - } - issue = new_issue; - strcat(issue, buf); - } - } - - if (ferror(fp)) { - pam_syslog(pamh, LOG_ERR, "read error: %m"); - _pam_drop(issue); - return PAM_SERVICE_ERR; - } - - *prompt = issue; - return PAM_SUCCESS; -} - -#ifdef PAM_STATIC - -/* static module data */ - -struct pam_module _pam_issue_modstruct = { - "pam_issue", - pam_sm_authenticate, - pam_sm_setcred, - NULL, - NULL, - NULL, - NULL, -}; - -#endif - -/* end of module definition */ diff --git a/modules/pam_issue/tst-pam_issue b/modules/pam_issue/tst-pam_issue deleted file mode 100755 index 0fe4f763..00000000 --- a/modules/pam_issue/tst-pam_issue +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/sh -../../tests/tst-dlopen .libs/pam_issue.so diff --git a/modules/pam_keyinit/.cvsignore b/modules/pam_keyinit/.cvsignore deleted file mode 100644 index a2072fc9..00000000 --- a/modules/pam_keyinit/.cvsignore +++ /dev/null @@ -1,8 +0,0 @@ -*.la -*.lo -.deps -.libs -Makefile -Makefile.in -README -pam_keyinit.8 diff --git a/modules/pam_keyinit/Makefile.am b/modules/pam_keyinit/Makefile.am deleted file mode 100644 index 5039705a..00000000 --- a/modules/pam_keyinit/Makefile.am +++ /dev/null @@ -1,33 +0,0 @@ -# -# Copyright (c) 2006 David Howells <dhowells@redhat.com> -# - -CLEANFILES = *~ - -EXTRA_DIST = README $(XMLS) pam_keyinit.8 tst-pam_keyinit -XMLS = README.xml pam_keyinit.8.xml - -if HAVE_KEY_MANAGEMENT - man_MANS = pam_keyinit.8 - TESTS = tst-pam_keyinit -endif - -if ENABLE_REGENERATE_MAN -noinst_DATA = README -README: pam_keyinit.8.xml --include $(top_srcdir)/Make.xml.rules -endif - -securelibdir = $(SECUREDIR) -secureconfdir = $(SCONFIGDIR) - -AM_CFLAGS = -I$(top_srcdir)/libpam/include -I$(top_srcdir)/libpamc/include -AM_LDFLAGS = -no-undefined -avoid-version -module -if HAVE_VERSIONING - AM_LDFLAGS += -Wl,--version-script=$(srcdir)/../modules.map -endif - -if HAVE_KEY_MANAGEMENT - securelib_LTLIBRARIES = pam_keyinit.la -endif -pam_keyinit_la_LIBADD = -L$(top_builddir)/libpam -lpam diff --git a/modules/pam_keyinit/README.xml b/modules/pam_keyinit/README.xml deleted file mode 100644 index 47659e89..00000000 --- a/modules/pam_keyinit/README.xml +++ /dev/null @@ -1,41 +0,0 @@ -<?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_keyinit.8.xml"> ---> -]> - -<article> - - <articleinfo> - - <title> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" - href="pam_keyinit.8.xml" xpointer='xpointer(//refnamediv[@id = "pam_keyinit-name"]/*)'/> - </title> - - </articleinfo> - - <section> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" - href="pam_keyinit.8.xml" xpointer='xpointer(//refsect1[@id = "pam_keyinit-description"]/*)'/> - </section> - - <section> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" - href="pam_keyinit.8.xml" xpointer='xpointer(//refsect1[@id = "pam_keyinit-options"]/*)'/> - </section> - - <section> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" - href="pam_keyinit.8.xml" xpointer='xpointer(//refsect1[@id = "pam_keyinit-examples"]/*)'/> - </section> - - <section> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" - href="pam_keyinit.8.xml" xpointer='xpointer(//refsect1[@id = "pam_keyinit-author"]/*)'/> - </section> - -</article> diff --git a/modules/pam_keyinit/pam_keyinit.8.xml b/modules/pam_keyinit/pam_keyinit.8.xml deleted file mode 100644 index c7dddf54..00000000 --- a/modules/pam_keyinit/pam_keyinit.8.xml +++ /dev/null @@ -1,241 +0,0 @@ -<?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_keyinit"> - - <refmeta> - <refentrytitle>pam_keyinit</refentrytitle> - <manvolnum>8</manvolnum> - <refmiscinfo class="sectdesc">Linux-PAM Manual</refmiscinfo> - </refmeta> - - <refnamediv id="pam_keyinit-name"> - <refname>pam_keyinit</refname> - <refpurpose>Kernel session keyring initialiser module</refpurpose> - </refnamediv> - - <refsynopsisdiv> - <cmdsynopsis id="pam_keyinit-cmdsynopsis"> - <command>pam_keyinit.so</command> - <arg choice="opt"> - debug - </arg> - <arg choice="opt"> - force - </arg> - <arg choice="opt"> - revoke - </arg> - </cmdsynopsis> - </refsynopsisdiv> - - <refsect1 id="pam_keyinit-description"> - <title>DESCRIPTION</title> - <para> - The pam_keyinit PAM module ensures that the invoking process has a - session keyring other than the user default session keyring. - </para> - <para> - The session component of the module checks to see if the process's - session keyring is the user default, and, if it is, creates a new - anonymous session keyring with which to replace it. - </para> - <para> - If a new session keyring is created, it will install a link to the user - common keyring in the session keyring so that keys common to the user - will be automatically accessible through it. - </para> - <para> - The session keyring of the invoking process will thenceforth be inherited - by all its children unless they override it. - </para> - <para> - This module is intended primarily for use by login processes. Be aware - that after the session keyring has been replaced, the old session keyring - and the keys it contains will no longer be accessible. - </para> - <para> - This module should not, generally, be invoked by programs like - <emphasis remap='B'>su</emphasis>, since it is usually desirable for the - key set to percolate through to the alternate context. The keys have - their own permissions system to manage this. - </para> - <para> - This module should be included as early as possible in a PAM - configuration, so that other PAM modules can attach tokens to the - keyring. - </para> - <para> - The keyutils package is used to manipulate keys more directly. This - can be obtained from: - </para> - <para> - <ulink url="http://people.redhat.com/~dhowells/keyutils/"> - Keyutils - </ulink> - </para> - </refsect1> - - <refsect1 id="pam_keyinit-options"> - <title>OPTIONS</title> - <variablelist> - <varlistentry> - <term> - <option>debug</option> - </term> - <listitem> - <para> - Log debug information with <citerefentry> - <refentrytitle>syslog</refentrytitle><manvolnum>3</manvolnum> - </citerefentry>. - </para> - </listitem> - </varlistentry> - - <varlistentry> - <term> - <option>force</option> - </term> - <listitem> - <para> - Causes the session keyring of the invoking process to be replaced - unconditionally. - </para> - </listitem> - </varlistentry> - - <varlistentry> - <term> - <option>revoke</option> - </term> - <listitem> - <para> - Causes the session keyring of the invoking process to be revoked - when the invoking process exits if the session keyring was created - for this process in the first place. - </para> - </listitem> - </varlistentry> - - </variablelist> - </refsect1> - - <refsect1 id="pam_keyinit-services"> - <title>MODULE SERVICES PROVIDED</title> - <para> - Only the <emphasis remap='B'>session</emphasis> service is supported. - </para> - </refsect1> - - <refsect1 id='pam_keyinit-return_values'> - <title>RETURN VALUES</title> - <variablelist> - <varlistentry> - <term>PAM_SUCCESS</term> - <listitem> - <para> - This module will usually return this value - </para> - </listitem> - </varlistentry> - - <varlistentry> - <term>PAM_AUTH_ERR</term> - <listitem> - <para> - Authentication failure. - </para> - </listitem> - </varlistentry> - - <varlistentry> - <term>PAM_BUF_ERR</term> - <listitem> - <para> - Memory buffer error. - </para> - </listitem> - </varlistentry> - - <varlistentry> - <term>PAM_IGNORE</term> - <listitem> - <para> - The return value should be ignored by PAM dispatch. - </para> - </listitem> - </varlistentry> - - <varlistentry> - <term>PAM_SERVICE_ERR</term> - <listitem> - <para> - Cannot determine the user name. - </para> - </listitem> - </varlistentry> - - <varlistentry> - <term>PAM_SESSION_ERR</term> - <listitem> - <para> - This module will return this value if its arguments are invalid or - if a system error such as ENOMEM occurs. - </para> - </listitem> - </varlistentry> - - <varlistentry> - <term>PAM_USER_UNKNOWN</term> - <listitem> - <para> - User not known. - </para> - </listitem> - </varlistentry> - - </variablelist> - </refsect1> - - <refsect1 id='pam_keyinit-examples'> - <title>EXAMPLES</title> - <para> - Add this line to your login entries to start each login session with its - own session keyring: - <programlisting> -session required pam_keyinit.so - </programlisting> - </para> - <para> - This will prevent keys from one session leaking into another session for - the same user. - </para> - </refsect1> - - <refsect1 id='pam_keyinit-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> - <citerefentry> - <refentrytitle>keyctl</refentrytitle><manvolnum>1</manvolnum> - </citerefentry> - </para> - </refsect1> - - <refsect1 id='pam_keyinit-author'> - <title>AUTHOR</title> - <para> - pam_keyinit was written by David Howells, <dhowells@redhat.com>. - </para> - </refsect1> - -</refentry> diff --git a/modules/pam_keyinit/pam_keyinit.c b/modules/pam_keyinit/pam_keyinit.c deleted file mode 100644 index 378a7723..00000000 --- a/modules/pam_keyinit/pam_keyinit.c +++ /dev/null @@ -1,269 +0,0 @@ -/* pam_keyinit.c: Initialise the session keyring on login through a PAM module - * - * Copyright (C) 2006 Red Hat, Inc. All Rights Reserved. - * Written by David Howells (dhowells@redhat.com) - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - */ - -#include "config.h" -#include <stdarg.h> -#include <string.h> -#include <syslog.h> -#include <pwd.h> -#include <unistd.h> -#include <errno.h> -#include <security/pam_modules.h> -#include <security/pam_modutil.h> -#include <security/pam_ext.h> -#include <sys/syscall.h> - -#define KEY_SPEC_SESSION_KEYRING -3 /* ID for session keyring */ -#define KEY_SPEC_USER_KEYRING -4 /* ID for UID-specific keyring */ -#define KEY_SPEC_USER_SESSION_KEYRING -5 /* - key ID for UID-session keyring */ - -#define KEYCTL_GET_KEYRING_ID 0 /* ask for a keyring's ID */ -#define KEYCTL_JOIN_SESSION_KEYRING 1 /* start named session keyring */ -#define KEYCTL_REVOKE 3 /* revoke a key */ -#define KEYCTL_LINK 8 /* link a key into a keyring */ - -static int my_session_keyring; -static int session_counter; -static int do_revoke; -static int revoke_as_uid; -static int revoke_as_gid; -static int xdebug = 0; - -static void debug(pam_handle_t *pamh, const char *fmt, ...) - __attribute__((format(printf, 2, 3))); - -static void debug(pam_handle_t *pamh, const char *fmt, ...) -{ - va_list va; - - if (xdebug) { - va_start(va, fmt); - pam_vsyslog(pamh, LOG_DEBUG, fmt, va); - va_end(va); - } -} - -static int error(pam_handle_t *pamh, const char *fmt, ...) - __attribute__((format(printf, 2, 3))); - -static int error(pam_handle_t *pamh, const char *fmt, ...) -{ - va_list va; - - va_start(va, fmt); - pam_vsyslog(pamh, LOG_ERR, fmt, va); - va_end(va); - - return PAM_SESSION_ERR; -} - -/* - * initialise the session keyring for this process - */ -static int init_keyrings(pam_handle_t *pamh, int force) -{ - int session, usession, ret; - - if (!force) { - /* get the IDs of the session keyring and the user session - * keyring */ - session = syscall(__NR_keyctl, - KEYCTL_GET_KEYRING_ID, - KEY_SPEC_SESSION_KEYRING, - 0); - debug(pamh, "GET SESSION = %d", session); - if (session < 0) { - /* don't worry about keyrings if facility not - * installed */ - if (errno == ENOSYS) - return PAM_SUCCESS; - return PAM_SESSION_ERR; - } - - usession = syscall(__NR_keyctl, - KEYCTL_GET_KEYRING_ID, - KEY_SPEC_USER_SESSION_KEYRING, - 0); - debug(pamh, "GET SESSION = %d", usession); - if (usession < 0) - return PAM_SESSION_ERR; - - /* if the user session keyring is our keyring, then we don't - * need to do anything if we're not forcing */ - if (session != usession) - return PAM_SUCCESS; - } - - /* create a session keyring, discarding the old one */ - ret = syscall(__NR_keyctl, - KEYCTL_JOIN_SESSION_KEYRING, - NULL); - debug(pamh, "JOIN = %d", ret); - if (ret < 0) - return PAM_SESSION_ERR; - - my_session_keyring = ret; - - /* make a link from the session keyring to the user keyring */ - ret = syscall(__NR_keyctl, - KEYCTL_LINK, - KEY_SPEC_USER_KEYRING, - KEY_SPEC_SESSION_KEYRING); - - return ret < 0 ? PAM_SESSION_ERR : PAM_SUCCESS; -} - -/* - * revoke the session keyring for this process - */ -static void kill_keyrings(pam_handle_t *pamh) -{ - int old_uid, old_gid; - - /* revoke the session keyring we created earlier */ - if (my_session_keyring > 0) { - debug(pamh, "REVOKE %d", my_session_keyring); - - old_uid = geteuid(); - old_gid = getegid(); - debug(pamh, "UID:%d [%d] GID:%d [%d]", - revoke_as_uid, old_uid, revoke_as_gid, old_gid); - - /* switch to the real UID and GID so that we have permission to - * revoke the key */ - if (revoke_as_gid != old_gid && setregid(-1, revoke_as_gid) < 0) - error(pamh, "Unable to change GID to %d temporarily\n", - revoke_as_gid); - - if (revoke_as_uid != old_uid && setreuid(-1, revoke_as_uid) < 0) - error(pamh, "Unable to change UID to %d temporarily\n", - revoke_as_uid); - - syscall(__NR_keyctl, - KEYCTL_REVOKE, - my_session_keyring); - - /* return to the orignal UID and GID (probably root) */ - if (revoke_as_uid != old_uid && setreuid(-1, old_uid) < 0) - error(pamh, "Unable to change UID back to %d\n", old_uid); - - if (revoke_as_gid != old_gid && setregid(-1, old_gid) < 0) - error(pamh, "Unable to change GID back to %d\n", old_gid); - - my_session_keyring = 0; - } -} - -/* - * open a PAM session by making sure there's a session keyring - */ -PAM_EXTERN -int pam_sm_open_session(pam_handle_t *pamh, int flags UNUSED, - int argc, const char **argv) -{ - struct passwd *pw; - const char *username; - int ret, old_uid, uid, old_gid, gid, loop, force = 0; - - for (loop = 0; loop < argc; loop++) { - if (strcmp(argv[loop], "force") == 0) - force = 1; - else if (strcmp(argv[loop], "debug") == 0) - xdebug = 1; - else if (strcmp(argv[loop], "revoke") == 0) - do_revoke = 1; - } - - /* don't do anything if already created a keyring (will be called - * multiple times if mentioned more than once in a pam script) - */ - session_counter++; - - debug(pamh, "OPEN %d", session_counter); - - if (my_session_keyring > 0) - return PAM_SUCCESS; - - /* look up the target UID */ - ret = pam_get_user(pamh, &username, "key user"); - if (ret != PAM_SUCCESS) - return ret; - - pw = pam_modutil_getpwnam(pamh, username); - if (!pw) { - error(pamh, "Unable to look up user \"%s\"\n", username); - return PAM_USER_UNKNOWN; - } - - revoke_as_uid = uid = pw->pw_uid; - old_uid = getuid(); - revoke_as_gid = gid = pw->pw_gid; - old_gid = getgid(); - debug(pamh, "UID:%d [%d] GID:%d [%d]", uid, old_uid, gid, old_gid); - - /* switch to the real UID and GID so that the keyring ends up owned by - * the right user */ - if (gid != old_gid && setregid(gid, -1) < 0) { - error(pamh, "Unable to change GID to %d temporarily\n", gid); - return PAM_SESSION_ERR; - } - - if (uid != old_uid && setreuid(uid, -1) < 0) { - error(pamh, "Unable to change UID to %d temporarily\n", uid); - setregid(old_gid, -1); - return PAM_SESSION_ERR; - } - - ret = init_keyrings(pamh, force); - - /* return to the orignal UID and GID (probably root) */ - if (uid != old_uid && setreuid(old_uid, -1) < 0) - ret = error(pamh, "Unable to change UID back to %d\n", old_uid); - - if (gid != old_gid && setregid(old_gid, -1) < 0) - ret = error(pamh, "Unable to change GID back to %d\n", old_gid); - - return ret; -} - -/* - * close a PAM session by revoking the session keyring if requested - */ -PAM_EXTERN -int pam_sm_close_session(pam_handle_t *pamh, int flags UNUSED, - int argc UNUSED, const char **argv UNUSED) -{ - debug(pamh, "CLOSE %d,%d,%d", - session_counter, my_session_keyring, do_revoke); - - session_counter--; - - if (session_counter == 0 && my_session_keyring > 0 && do_revoke) - kill_keyrings(pamh); - - return PAM_SUCCESS; -} - -#ifdef PAM_STATIC - -/* static module data */ - -struct pam_module _pam_keyinit_modstruct = { - "pam_keyinit", - NULL, - NULL, - NULL, - pam_sm_open_session, - pam_sm_close_session, - NULL -}; -#endif - diff --git a/modules/pam_keyinit/tst-pam_keyinit b/modules/pam_keyinit/tst-pam_keyinit deleted file mode 100755 index f0a7b9bc..00000000 --- a/modules/pam_keyinit/tst-pam_keyinit +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/sh -../../tests/tst-dlopen .libs/pam_keyinit.so diff --git a/modules/pam_lastlog/.cvsignore b/modules/pam_lastlog/.cvsignore deleted file mode 100644 index 9b0768f7..00000000 --- a/modules/pam_lastlog/.cvsignore +++ /dev/null @@ -1,8 +0,0 @@ -*.la -*.lo -.deps -.libs -Makefile -Makefile.in -README -pam_lastlog.8 diff --git a/modules/pam_lastlog/Makefile.am b/modules/pam_lastlog/Makefile.am deleted file mode 100644 index 899bda7b..00000000 --- a/modules/pam_lastlog/Makefile.am +++ /dev/null @@ -1,31 +0,0 @@ -# -# Copyright (c) 2005, 2006 Thorsten Kukuk <kukuk@suse.de> -# - -CLEANFILES = *~ - -securelibdir = $(SECUREDIR) -secureconfdir = $(SCONFIGDIR) - -EXTRA_DIST = README $(MANS) $(XMLS) tst-pam_lastlog - -man_MANS = pam_lastlog.8 -XMLS = README.xml pam_lastlog.8.xml - -TESTS = tst-pam_lastlog - -AM_CFLAGS = -I$(top_srcdir)/libpam/include -I$(top_srcdir)/libpamc/include -AM_LDFLAGS = -no-undefined -avoid-version -module -if HAVE_VERSIONING - AM_LDFLAGS += -Wl,--version-script=$(srcdir)/../modules.map -endif - -securelib_LTLIBRARIES = pam_lastlog.la -pam_lastlog_la_LIBADD = -L$(top_builddir)/libpam -lpam -lutil - -if ENABLE_REGENERATE_MAN -noinst_DATA = README -README: pam_lastlog.8.xml --include $(top_srcdir)/Make.xml.rules -endif - diff --git a/modules/pam_lastlog/README.xml b/modules/pam_lastlog/README.xml deleted file mode 100644 index 7fe70339..00000000 --- a/modules/pam_lastlog/README.xml +++ /dev/null @@ -1,41 +0,0 @@ -<?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_lastlog.8.xml"> ---> -]> - -<article> - - <articleinfo> - - <title> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" - href="pam_lastlog.8.xml" xpointer='xpointer(//refnamediv[@id = "pam_lastlog-name"]/*)'/> - </title> - - </articleinfo> - - <section> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" - href="pam_lastlog.8.xml" xpointer='xpointer(//refsect1[@id = "pam_lastlog-description"]/*)'/> - </section> - - <section> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" - href="pam_lastlog.8.xml" xpointer='xpointer(//refsect1[@id = "pam_lastlog-options"]/*)'/> - </section> - - <section> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" - href="pam_lastlog.8.xml" xpointer='xpointer(//refsect1[@id = "pam_lastlog-examples"]/*)'/> - </section> - - <section> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" - href="pam_lastlog.8.xml" xpointer='xpointer(//refsect1[@id = "pam_lastlog-author"]/*)'/> - </section> - -</article> diff --git a/modules/pam_lastlog/pam_lastlog.8.xml b/modules/pam_lastlog/pam_lastlog.8.xml deleted file mode 100644 index 066eff58..00000000 --- a/modules/pam_lastlog/pam_lastlog.8.xml +++ /dev/null @@ -1,231 +0,0 @@ -<?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_lastlog"> - - <refmeta> - <refentrytitle>pam_lastlog</refentrytitle> - <manvolnum>8</manvolnum> - <refmiscinfo class="sectdesc">Linux-PAM Manual</refmiscinfo> - </refmeta> - - <refnamediv id="pam_lastlog-name"> - <refname>pam_lastlog</refname> - <refpurpose>PAM module to display date of last login</refpurpose> - </refnamediv> - - <refsynopsisdiv> - <cmdsynopsis id="pam_lastlog-cmdsynopsis"> - <command>pam_lastlog.so</command> - <arg choice="opt"> - debug - </arg> - <arg choice="opt"> - silent - </arg> - <arg choice="opt"> - never - </arg> - <arg choice="opt"> - nodate - </arg> - <arg choice="opt"> - nohost - </arg> - <arg choice="opt"> - noterm - </arg> - <arg choice="opt"> - nowtmp - </arg> - </cmdsynopsis> - </refsynopsisdiv> - - <refsect1 id="pam_lastlog-description"> - - <title>DESCRIPTION</title> - - <para> - pam_lastlog is a PAM module to display a line of information - about the last login of the user. In addition, the module maintains - the <filename>/var/log/lastlog</filename> file. - </para> - <para> - Some applications may perform this function themselves. In such - cases, this module is not necessary. - </para> - </refsect1> - - <refsect1 id="pam_lastlog-options"> - - <title>OPTIONS</title> - <variablelist> - <varlistentry> - <term> - <option>debug</option> - </term> - <listitem> - <para> - Print debug information. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <option>silent</option> - </term> - <listitem> - <para> - Don't inform the user about any previous login, - just upate the <filename>/var/log/lastlog</filename> file. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <option>never</option> - </term> - <listitem> - <para> - If the <filename>/var/log/lastlog</filename> file does - not contain any old entries for the user, indicate that - the user has never previously logged in with a welcome - message. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <option>nodate</option> - </term> - <listitem> - <para> - Don't display the date of the last login. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <option>noterm</option> - </term> - <listitem> - <para> - Don't display the terminal name on which the - last login was attempted. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <option>nohost</option> - </term> - <listitem> - <para> - Don't indicate from which host the last login was - attempted. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <option>nowtmp</option> - </term> - <listitem> - <para> - Don't update the wtmp entry. - </para> - </listitem> - </varlistentry> - </variablelist> - </refsect1> - - <refsect1 id="pam_lastlog-services"> - <title>MODULE SERVICES PROVIDED</title> - <para> - Only the <option>session</option> service is supported. - </para> - </refsect1> - - <refsect1 id='pam_lastlog-return_values'> - <title>RETURN VALUES</title> - <para> - <variablelist> - - <varlistentry> - <term>PAM_SUCCESS</term> - <listitem> - <para> - Everything was successfull. - </para> - </listitem> - </varlistentry> - - <varlistentry> - <term>PAM_SERVICE_ERR</term> - <listitem> - <para> - Internal service module error. - </para> - </listitem> - </varlistentry> - - <varlistentry> - <term>PAM_USER_UNKNOWN</term> - <listitem> - <para> - User not known. - </para> - </listitem> - </varlistentry> - - </variablelist> - </para> - </refsect1> - - <refsect1 id='pam_lastlog-examples'> - <title>EXAMPLES</title> - <para> - Add the following line to <filename>/etc/pam.d/login</filename> to - display the last login time of an user: - </para> - <programlisting> - session required pam_lastlog.so nowtmp - </programlisting> - </refsect1> - - <refsect1 id="pam_lastlog-files"> - <title>FILES</title> - <variablelist> - <varlistentry> - <term><filename>/var/log/lastlog</filename></term> - <listitem> - <para>Lastlog logging file</para> - </listitem> - </varlistentry> - </variablelist> - </refsect1> - - <refsect1 id='pam_lastlog-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_lastlog-author'> - <title>AUTHOR</title> - <para> - pam_lastlog was written by Andrew G. Morgan <morgan@kernel.org>. - </para> - </refsect1> - -</refentry> diff --git a/modules/pam_lastlog/pam_lastlog.c b/modules/pam_lastlog/pam_lastlog.c deleted file mode 100644 index a75e1ce7..00000000 --- a/modules/pam_lastlog/pam_lastlog.c +++ /dev/null @@ -1,452 +0,0 @@ -/* pam_lastlog module */ - -/* - * Written by Andrew Morgan <morgan@linux.kernel.org> 1996/3/11 - * - * This module does the necessary work to display the last login - * time+date for this user, it then updates this entry for the - * present (login) service. - */ - -#include "config.h" - -#include <fcntl.h> -#include <time.h> -#include <errno.h> -#ifdef HAVE_UTMP_H -# include <utmp.h> -#else -# include <lastlog.h> -#endif -#include <pwd.h> -#include <stdlib.h> -#include <stdarg.h> -#include <stdio.h> -#include <string.h> -#include <sys/types.h> -#include <syslog.h> -#include <unistd.h> - -#if defined(hpux) || defined(sunos) || defined(solaris) -# ifndef _PATH_LASTLOG -# define _PATH_LASTLOG "/usr/adm/lastlog" -# endif /* _PATH_LASTLOG */ -# ifndef UT_HOSTSIZE -# define UT_HOSTSIZE 16 -# endif /* UT_HOSTSIZE */ -# ifndef UT_LINESIZE -# define UT_LINESIZE 12 -# endif /* UT_LINESIZE */ -#endif -#if defined(hpux) -struct lastlog { - time_t ll_time; - char ll_line[UT_LINESIZE]; - char ll_host[UT_HOSTSIZE]; /* same as in utmp */ -}; -#endif /* hpux */ - -/* XXX - time before ignoring lock. Is 1 sec enough? */ -#define LASTLOG_IGNORE_LOCK_TIME 1 - -#define DEFAULT_HOST "" /* "[no.where]" */ -#define DEFAULT_TERM "" /* "tt???" */ - -/* - * here, we make a definition for the externally accessible function - * in this file (this definition is required for static a module - * but strongly encouraged generally) it is used to instruct the - * modules include file to define the function prototypes. - */ - -#define PAM_SM_SESSION - -#include <security/pam_modules.h> -#include <security/_pam_macros.h> -#include <security/pam_modutil.h> -#include <security/pam_ext.h> - -/* argument parsing */ - -#define LASTLOG_DATE 01 /* display the date of the last login */ -#define LASTLOG_HOST 02 /* display the last host used (if set) */ -#define LASTLOG_LINE 04 /* display the last terminal used */ -#define LASTLOG_NEVER 010 /* display a welcome message for first login */ -#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 */ - -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); - - /* does the appliction require quiet? */ - if (flags & PAM_SILENT) { - ctrl |= LASTLOG_QUIET; - } - - /* step through arguments */ - for (; argc-- > 0; ++argv) { - - /* generic options */ - - if (!strcmp(*argv,"debug")) { - ctrl |= LASTLOG_DEBUG; - } else if (!strcmp(*argv,"nodate")) { - ctrl &= ~LASTLOG_DATE; - } else if (!strcmp(*argv,"noterm")) { - ctrl &= ~LASTLOG_LINE; - } else if (!strcmp(*argv,"nohost")) { - ctrl &= ~LASTLOG_HOST; - } else if (!strcmp(*argv,"silent")) { - ctrl |= LASTLOG_QUIET; - } else if (!strcmp(*argv,"never")) { - ctrl |= LASTLOG_NEVER; - } else if (!strcmp(*argv,"nowtmp")) { - ctrl &= ~LASTLOG_WTMP; - } else { - pam_syslog(pamh, LOG_ERR, "unknown option: %s", *argv); - } - } - - D(("ctrl = %o", ctrl)); - return ctrl; -} - -static const char * -get_tty(pam_handle_t *pamh) -{ - const void *void_terminal_line = NULL; - const char *terminal_line; - - if (pam_get_item(pamh, PAM_TTY, &void_terminal_line) != PAM_SUCCESS - || void_terminal_line == NULL) { - terminal_line = DEFAULT_TERM; - } else { - terminal_line = void_terminal_line; - } - if (!strncmp("/dev/", terminal_line, 5)) { - /* strip leading "/dev/" from tty. */ - terminal_line += 5; - } - D(("terminal = %s", terminal_line)); - return terminal_line; -} - -static int -last_login_read(pam_handle_t *pamh, int announce, int last_fd, uid_t uid) -{ - struct flock last_lock; - struct lastlog last_login; - int retval = PAM_SUCCESS; - char the_time[256]; - char *date = NULL; - char *host = NULL; - char *line = NULL; - - memset(&last_lock, 0, sizeof(last_lock)); - last_lock.l_type = F_RDLCK; - last_lock.l_whence = SEEK_SET; - last_lock.l_start = sizeof(last_login) * (off_t) uid; - last_lock.l_len = sizeof(last_login); - - if (fcntl(last_fd, F_SETLK, &last_lock) < 0) { - D(("locking %s failed..(waiting a little)", _PATH_LASTLOG)); - pam_syslog(pamh, LOG_WARNING, - "file %s is locked/read", _PATH_LASTLOG); - sleep(LASTLOG_IGNORE_LOCK_TIME); - } - - if (pam_modutil_read(last_fd, (char *) &last_login, - sizeof(last_login)) != sizeof(last_login)) { - memset(&last_login, 0, sizeof(last_login)); - } - - last_lock.l_type = F_UNLCK; - (void) fcntl(last_fd, F_SETLK, &last_lock); /* unlock */ - - if (!last_login.ll_time) { - if (announce & LASTLOG_DEBUG) { - pam_syslog(pamh, LOG_DEBUG, - "first login for user with uid %lu", - (unsigned long int)uid); - } - } - - if (!(announce & LASTLOG_QUIET)) { - - if (last_login.ll_time) { - - /* we want the date? */ - if (announce & LASTLOG_DATE) { - struct tm *tm, tm_buf; - time_t ll_time; - - ll_time = last_login.ll_time; - tm = localtime_r (&ll_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) - && (last_login.ll_host[0] != '\0')) { - /* TRANSLATORS: " from <host>" */ - if (asprintf(&host, _(" from %.*s"), UT_HOSTSIZE, - last_login.ll_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) - && (last_login.ll_line[0] != '\0')) { - /* TRANSLATORS: " on <terminal>" */ - if (asprintf(&line, _(" on %.*s"), UT_LINESIZE, - last_login.ll_line) < 0) { - pam_syslog(pamh, LOG_ERR, "out of memory"); - retval = PAM_BUF_ERR; - goto cleanup; - } - } - - /* TRANSLATORS: "Last login: <date> from <host> on <terminal>" */ - retval = pam_info(pamh, _("Last login:%s%s%s"), - date ? date : "", - host ? host : "", - line ? line : ""); - } else if (announce & LASTLOG_NEVER) { - D(("this is the first time this user has logged in")); - retval = pam_info(pamh, "%s", _("Welcome to your new account!")); - } - } - - /* cleanup */ - cleanup: - memset(&last_login, 0, sizeof(last_login)); - _pam_overwrite(date); - _pam_overwrite(host); - _pam_drop(host); - _pam_overwrite(line); - _pam_drop(line); - - return retval; -} - -static int -last_login_write(pam_handle_t *pamh, int announce, int last_fd, - uid_t uid, const char *user) -{ - struct flock last_lock; - struct lastlog last_login; - time_t ll_time; - const void *void_remote_host = NULL; - const char *remote_host; - const char *terminal_line; - int retval = PAM_SUCCESS; - - /* rewind */ - if (lseek(last_fd, sizeof(last_login) * (off_t) uid, SEEK_SET) < 0) { - pam_syslog(pamh, LOG_ERR, "failed to lseek %s: %m", _PATH_LASTLOG); - return PAM_SERVICE_ERR; - } - - /* set this login date */ - D(("set the most recent login time")); - (void) time(&ll_time); /* set the time */ - last_login.ll_time = ll_time; - - /* set the remote host */ - if (pam_get_item(pamh, PAM_RHOST, &void_remote_host) != PAM_SUCCESS - || void_remote_host == NULL) { - remote_host = DEFAULT_HOST; - } else { - remote_host = void_remote_host; - } - - /* copy to last_login */ - last_login.ll_host[0] = '\0'; - strncat(last_login.ll_host, remote_host, sizeof(last_login.ll_host)-1); - - /* set the terminal line */ - terminal_line = get_tty(pamh); - - /* copy to last_login */ - last_login.ll_line[0] = '\0'; - strncat(last_login.ll_line, terminal_line, sizeof(last_login.ll_line)-1); - terminal_line = NULL; - - D(("locking lastlog file")); - - /* now we try to lock this file-record exclusively; non-blocking */ - memset(&last_lock, 0, sizeof(last_lock)); - last_lock.l_type = F_WRLCK; - last_lock.l_whence = SEEK_SET; - last_lock.l_start = sizeof(last_login) * (off_t) uid; - last_lock.l_len = sizeof(last_login); - - if (fcntl(last_fd, F_SETLK, &last_lock) < 0) { - D(("locking %s failed..(waiting a little)", _PATH_LASTLOG)); - pam_syslog(pamh, LOG_WARNING, "file %s is locked/write", _PATH_LASTLOG); - sleep(LASTLOG_IGNORE_LOCK_TIME); - } - - D(("writing to the lastlog file")); - if (pam_modutil_write (last_fd, (char *) &last_login, - sizeof (last_login)) != sizeof(last_login)) { - pam_syslog(pamh, LOG_ERR, "failed to write %s: %m", _PATH_LASTLOG); - retval = PAM_SERVICE_ERR; - } - - last_lock.l_type = F_UNLCK; - (void) fcntl(last_fd, F_SETLK, &last_lock); /* unlock */ - D(("unlocked")); - - if (announce & LASTLOG_WTMP) { - /* write wtmp entry for user */ - logwtmp(last_login.ll_line, user, remote_host); - } - - /* cleanup */ - memset(&last_login, 0, sizeof(last_login)); - - return retval; -} - -static int -last_login_date(pam_handle_t *pamh, int announce, uid_t uid, const char *user) -{ - int retval; - int last_fd; - - /* obtain the last login date and all the relevant info */ - last_fd = open(_PATH_LASTLOG, O_RDWR); - if (last_fd < 0) { - if (errno == ENOENT) { - last_fd = open(_PATH_LASTLOG, O_RDWR|O_CREAT, - S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH); - if (last_fd < 0) { - pam_syslog(pamh, LOG_ERR, - "unable to create %s: %m", _PATH_LASTLOG); - D(("unable to create %s file", _PATH_LASTLOG)); - return PAM_SERVICE_ERR; - } - pam_syslog(pamh, LOG_WARNING, - "file %s created", _PATH_LASTLOG); - D(("file %s created", _PATH_LASTLOG)); - } else { - pam_syslog(pamh, LOG_ERR, "unable to open %s: %m", _PATH_LASTLOG); - D(("unable to open %s file", _PATH_LASTLOG)); - return PAM_SERVICE_ERR; - } - } - - if (lseek(last_fd, sizeof(struct lastlog) * (off_t) uid, SEEK_SET) < 0) { - pam_syslog(pamh, LOG_ERR, "failed to lseek %s: %m", _PATH_LASTLOG); - D(("unable to lseek %s file", _PATH_LASTLOG)); - return PAM_SERVICE_ERR; - } - - retval = last_login_read(pamh, announce, last_fd, uid); - if (retval != PAM_SUCCESS) - { - close(last_fd); - D(("error while reading lastlog file")); - return retval; - } - - retval = last_login_write(pamh, announce, last_fd, uid, user); - - close(last_fd); - D(("all done with last login")); - - return retval; -} - -/* --- authentication management functions (only) --- */ - -PAM_EXTERN int -pam_sm_open_session(pam_handle_t *pamh, int flags, - int argc, const char **argv) -{ - int retval, ctrl; - const void *user; - const struct passwd *pwd; - uid_t uid; - - /* - * this module gets the uid of the PAM_USER. Uses it to display - * last login info and then updates the lastlog for that user. - */ - - ctrl = _pam_parse(pamh, flags, argc, argv); - - /* which user? */ - - retval = pam_get_item(pamh, PAM_USER, &user); - if (retval != PAM_SUCCESS || user == NULL || *(const char *)user == '\0') { - pam_syslog(pamh, LOG_NOTICE, "user unknown"); - return PAM_USER_UNKNOWN; - } - - /* what uid? */ - - pwd = pam_modutil_getpwnam (pamh, user); - if (pwd == NULL) { - D(("couldn't identify user %s", user)); - return PAM_USER_UNKNOWN; - } - uid = pwd->pw_uid; - pwd = NULL; /* tidy up */ - - /* process the current login attempt (indicate last) */ - - retval = last_login_date(pamh, ctrl, uid, user); - - /* indicate success or failure */ - - uid = -1; /* forget this */ - - return retval; -} - -PAM_EXTERN int -pam_sm_close_session (pam_handle_t *pamh, int flags, - int argc, const char **argv) -{ - const char *terminal_line; - - if (!(_pam_parse(pamh, flags, argc, argv) & LASTLOG_WTMP)) - return PAM_SUCCESS; - - terminal_line = get_tty(pamh); - - /* Wipe out utmp logout entry */ - logwtmp(terminal_line, "", ""); - - return PAM_SUCCESS; -} - -#ifdef PAM_STATIC - -/* static module data */ - -struct pam_module _pam_lastlog_modstruct = { - "pam_lastlog", - NULL, - NULL, - NULL, - pam_sm_open_session, - pam_sm_close_session, - NULL, -}; - -#endif - -/* end of module definition */ diff --git a/modules/pam_lastlog/tst-pam_lastlog b/modules/pam_lastlog/tst-pam_lastlog deleted file mode 100755 index ea9a5eb0..00000000 --- a/modules/pam_lastlog/tst-pam_lastlog +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/sh -../../tests/tst-dlopen .libs/pam_lastlog.so diff --git a/modules/pam_limits/.cvsignore b/modules/pam_limits/.cvsignore deleted file mode 100644 index b2519a1c..00000000 --- a/modules/pam_limits/.cvsignore +++ /dev/null @@ -1,9 +0,0 @@ -*.la -*.lo -.deps -.libs -Makefile -Makefile.in -README -limits.conf.5 -pam_limits.8 diff --git a/modules/pam_limits/Makefile.am b/modules/pam_limits/Makefile.am deleted file mode 100644 index 13232ea6..00000000 --- a/modules/pam_limits/Makefile.am +++ /dev/null @@ -1,38 +0,0 @@ -# -# Copyright (c) 2005, 2006 Thorsten Kukuk <kukuk@suse.de> -# - -CLEANFILES = *~ - -EXTRA_DIST = README $(MANS) $(XMLS) limits.conf tst-pam_limits - -man_MANS = limits.conf.5 pam_limits.8 -XMLS = README.xml limits.conf.5.xml pam_limits.8.xml - -TESTS = tst-pam_limits - -securelibdir = $(SECUREDIR) -secureconfdir = $(SCONFIGDIR) -limits_conf_dir = $(SCONFIGDIR)/limits.d - -AM_CFLAGS = -I$(top_srcdir)/libpam/include -I$(top_srcdir)/libpamc/include \ - -DLIMITS_FILE_DIR=\"$(limits_conf_dir)/*.conf\" \ - -DLIMITS_FILE=\"$(SCONFIGDIR)/limits.conf\" -AM_LDFLAGS = -no-undefined -avoid-version -module -if HAVE_VERSIONING - AM_LDFLAGS += -Wl,--version-script=$(srcdir)/../modules.map -endif - -securelib_LTLIBRARIES = pam_limits.la -pam_limits_la_LIBADD = -L$(top_builddir)/libpam -lpam - -secureconf_DATA = limits.conf - -if ENABLE_REGENERATE_MAN -noinst_DATA = README -README: pam_limits.8.xml limits.conf.5.xml --include $(top_srcdir)/Make.xml.rules -endif - -install-data-local: - mkdir -p $(DESTDIR)$(limits_conf_dir) diff --git a/modules/pam_limits/README.xml b/modules/pam_limits/README.xml deleted file mode 100644 index 964a5a21..00000000 --- a/modules/pam_limits/README.xml +++ /dev/null @@ -1,39 +0,0 @@ -<?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 pamlimits SYSTEM "pam_limits.8.xml"> ---> -<!-- -<!ENTITY limitsconf SYSTEM "limits.conf.5.xml"> ---> -]> - -<article> - - <articleinfo> - - <title> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" - href="pam_limits.8.xml" xpointer='xpointer(//refnamediv[@id = "pam_limits-name"]/*)'/> - </title> - - </articleinfo> - - <section> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" - href="pam_limits.8.xml" xpointer='xpointer(//refsect1[@id = "pam_limits-description"]/*)'/> - </section> - - <section> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" - href="pam_limits.8.xml" xpointer='xpointer(//refsect1[@id = "pam_limits-options"]/*)'/> - </section> - - <section> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" - href="limits.conf.5.xml" xpointer='xpointer(//refsect1[@id = "limits.conf-examples"]/*)'/> - </section> - -</article> diff --git a/modules/pam_limits/limits.conf b/modules/pam_limits/limits.conf deleted file mode 100644 index 5d5c3f70..00000000 --- a/modules/pam_limits/limits.conf +++ /dev/null @@ -1,50 +0,0 @@ -# /etc/security/limits.conf -# -#Each line describes a limit for a user in the form: -# -#<domain> <type> <item> <value> -# -#Where: -#<domain> can be: -# - an user name -# - a group name, with @group syntax -# - the wildcard *, for default entry -# - the wildcard %, can be also used with %group syntax, -# for maxlogin limit -# -#<type> can have the two values: -# - "soft" for enforcing the soft limits -# - "hard" for enforcing hard limits -# -#<item> can be one of the following: -# - core - limits the core file size (KB) -# - data - max data size (KB) -# - fsize - maximum filesize (KB) -# - memlock - max locked-in-memory address space (KB) -# - nofile - max number of open files -# - rss - max resident set size (KB) -# - stack - max stack size (KB) -# - cpu - max CPU time (MIN) -# - nproc - max number of processes -# - as - address space limit (KB) -# - maxlogins - max number of logins for this user -# - maxsyslogins - max number of logins on the system -# - priority - the priority to run user process with -# - locks - max number of file locks the user can hold -# - sigpending - max number of pending signals -# - msgqueue - max memory used by POSIX message queues (bytes) -# - nice - max nice priority allowed to raise to values: [-20, 19] -# - rtprio - max realtime priority -# -#<domain> <type> <item> <value> -# - -#* soft core 0 -#* hard rss 10000 -#@student hard nproc 20 -#@faculty soft nproc 20 -#@faculty hard nproc 50 -#ftp hard nproc 0 -#@student - maxlogins 4 - -# End of file diff --git a/modules/pam_limits/limits.conf.5.xml b/modules/pam_limits/limits.conf.5.xml deleted file mode 100644 index fb1fad27..00000000 --- a/modules/pam_limits/limits.conf.5.xml +++ /dev/null @@ -1,287 +0,0 @@ -<?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="limits.conf"> - - <refmeta> - <refentrytitle>limits.conf</refentrytitle> - <manvolnum>5</manvolnum> - <refmiscinfo class="sectdesc">Linux-PAM Manual</refmiscinfo> - </refmeta> - - <refnamediv> - <refname>limits.conf</refname> - <refpurpose>configuration file for the pam_limits module</refpurpose> - </refnamediv> - - <refsect1 id='limits.conf-description'> - <title>DESCRIPTION</title> - <para> - The syntax of the lines is as follows: - </para> - <para> - <replaceable><domain></replaceable> <replaceable><type></replaceable> - <replaceable><item></replaceable> <replaceable><value></replaceable> - </para> - <para> - The fields listed above should be filled as follows: - </para> - <variablelist> - <varlistentry> - <term> - <option><domain></option> - </term> - <listitem> - <itemizedlist> - <listitem> - <para> - a username - </para> - </listitem> - <listitem> - <para> - a groupname, with <emphasis remap='B'>@group</emphasis> syntax. - This should not be confused with netgroups. - </para> - </listitem> - <listitem> - <para> - the wildcard <emphasis remap='B'>*</emphasis>, for default entry. - </para> - </listitem> - <listitem> - <para> - the wildcard <emphasis remap='B'>%</emphasis>, for maxlogins limit only, - can also be used with <emphasis remap='b'>%group</emphasis> syntax. - </para> - </listitem> - </itemizedlist> - </listitem> - </varlistentry> - - <varlistentry> - <term> - <option><type></option> - </term> - <listitem> - <variablelist> - <varlistentry> - <term><option>hard</option></term> - <listitem> - <para> - for enforcing <emphasis remap='B'>hard</emphasis> resource limits. - These limits are set by the superuser and enforced by the Kernel. - The user cannot raise his requirement of system resources above such values. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term><option>soft</option></term> - <listitem> - <para> - for enforcing <emphasis remap='B'>soft</emphasis> resource limits. - These limits are ones that the user can move up or down within the - permitted range by any pre-existing <emphasis remap='B'>hard</emphasis> - limits. The values specified with this token can be thought of as - <emphasis>default</emphasis> values, for normal system usage. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term><option>-</option></term> - <listitem> - <para> - for enforcing both <emphasis remap='B'>soft</emphasis> and - <emphasis remap='B'>hard</emphasis> resource limits together. - </para> - <para> - Note, if you specify a type of '-' but neglect to supply the - item and value fields then the module will never enforce any - limits on the specified user/group etc. . - </para> - </listitem> - </varlistentry> - </variablelist> - </listitem> - </varlistentry> - - <varlistentry> - <term> - <option><item></option> - </term> - <listitem> - <variablelist> - <varlistentry> - <term><option>core</option></term> - <listitem> - <para>limits the core file size (KB)</para> - </listitem> - </varlistentry> - <varlistentry> - <term><option>data</option></term> - <listitem> - <para>maximum data size (KB)</para> - </listitem> - </varlistentry> - <varlistentry> - <term><option>fsize</option></term> - <listitem> - <para>maximum filesize (KB)</para> - </listitem> - </varlistentry> - <varlistentry> - <term><option>memlock</option></term> - <listitem> - <para>maximum locked-in-memory address space (KB)</para> - </listitem> - </varlistentry> - <varlistentry> - <term><option>nofile</option></term> - <listitem> - <para>maximum number of open files</para> - </listitem> - </varlistentry> - <varlistentry> - <term><option>rss</option></term> - <listitem> - <para>maximum resident set size (KB)</para> - </listitem> - </varlistentry> - <varlistentry> - <term><option>stack</option></term> - <listitem> - <para>maximum stack size (KB)</para> - </listitem> - </varlistentry> - <varlistentry> - <term><option>cpu</option></term> - <listitem> - <para>maximum CPU time (minutes)</para> - </listitem> - </varlistentry> - <varlistentry> - <term><option>nproc</option></term> - <listitem> - <para>maximum number of processes</para> - </listitem> - </varlistentry> - <varlistentry> - <term><option>as</option></term> - <listitem> - <para>address space limit (KB)</para> - </listitem> - </varlistentry> - <varlistentry> - <term><option>maxlogins</option></term> - <listitem> - <para>maximum number of logins for this user except - for this with <emphasis>uid=0</emphasis></para> - </listitem> - </varlistentry> - <varlistentry> - <term><option>maxsyslogins</option></term> - <listitem> - <para>maximum number of logins on system</para> - </listitem> - </varlistentry> - <varlistentry> - <term><option>priority</option></term> - <listitem> - <para>the priority to run user process with (negative - values boost process priority)</para> - </listitem> - </varlistentry> - <varlistentry> - <term><option>locks</option></term> - <listitem> - <para>maximum locked files (Linux 2.4 and higher)</para> - </listitem> - </varlistentry> - <varlistentry> - <term><option>sigpending</option></term> - <listitem> - <para>maximum number of pending signals (Linux 2.6 and higher)</para> - </listitem> - </varlistentry> - <varlistentry> - <term><option>msqqueue</option></term> - <listitem> - <para>maximum memory used by POSIX message queues (bytes) - (Linux 2.6 and higher)</para> - </listitem> - </varlistentry> - <varlistentry> - <term><option>nice</option></term> - <listitem> - <para>maximum nice priority allowed to raise to (Linux 2.6.12 and higher) values: [-20,19]</para> - </listitem> - </varlistentry> - <varlistentry> - <term><option>rtprio</option></term> - <listitem> - <para>maximum realtime priority allowed for non-privileged processes - (Linux 2.6.12 and higher)</para> - </listitem> - </varlistentry> - </variablelist> - </listitem> - </varlistentry> - - </variablelist> - <para> - In general, individual limits have priority over group limits, so if - you impose no limits for <emphasis>admin</emphasis> group, but one of - the members in this group have a limits line, the user will have its - limits set according to this line. - </para> - <para> - Also, please note that all limit settings are set - <emphasis>per login</emphasis>. They are not global, nor are they - permanent; existing only for the duration of the session. - </para> - <para> - In the <emphasis>limits</emphasis> configuration file, the - '<emphasis remap='B'>#</emphasis>' character introduces a comment - - after which the rest of the line is ignored. - </para> - <para> - The pam_limits module does its best to report configuration problems - found in its configuration file via <citerefentry> - <refentrytitle>syslog</refentrytitle><manvolnum>3</manvolnum></citerefentry>. - </para> - </refsect1> - - <refsect1 id="limits.conf-examples"> - <title>EXAMPLES</title> - <para> - These are some example lines which might be specified in - <filename>/etc/security/limits.conf</filename>. - </para> - <programlisting> -* soft core 0 -* hard rss 10000 -@student hard nproc 20 -@faculty soft nproc 20 -@faculty hard nproc 50 -ftp hard nproc 0 -@student - maxlogins 4 - </programlisting> - </refsect1> - - <refsect1 id="limits.conf-see_also"> - <title>SEE ALSO</title> - <para> - <citerefentry><refentrytitle>pam_limits</refentrytitle><manvolnum>8</manvolnum></citerefentry>, - <citerefentry><refentrytitle>pam.d</refentrytitle><manvolnum>5</manvolnum></citerefentry>, - <citerefentry><refentrytitle>pam</refentrytitle><manvolnum>8</manvolnum></citerefentry> - </para> - </refsect1> - - <refsect1 id="limits.conf-author"> - <title>AUTHOR</title> - <para> - pam_limits was initially written by Cristian Gafton <gafton@redhat.com> - </para> - </refsect1> -</refentry> diff --git a/modules/pam_limits/pam_limits.8.xml b/modules/pam_limits/pam_limits.8.xml deleted file mode 100644 index 98afdcd4..00000000 --- a/modules/pam_limits/pam_limits.8.xml +++ /dev/null @@ -1,256 +0,0 @@ -<?xml version="1.0" encoding="ISO-8859-1"?> -<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN" - "http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd"> - -<refentry id='pam_limits'> - - <refmeta> - <refentrytitle>pam_limits</refentrytitle> - <manvolnum>8</manvolnum> - <refmiscinfo class='setdesc'>Linux-PAM Manual</refmiscinfo> - </refmeta> - - <refnamediv id='pam_limits-name'> - <refname>pam_limits</refname> - <refpurpose> - PAM module to limit resources - </refpurpose> - </refnamediv> - -<!-- body begins here --> - - <refsynopsisdiv> - <cmdsynopsis id="pam_limits-cmdsynopsis"> - <command>pam_limits.so</command> - <arg choice="opt"> - change_uid - </arg> - <arg choice="opt"> - conf=<replaceable>/path/to/limits.conf</replaceable> - </arg> - <arg choice="opt"> - debug - </arg> - <arg choice="opt"> - utmp_early - </arg> - <arg choice="opt"> - noaudit - </arg> - </cmdsynopsis> - </refsynopsisdiv> - - - <refsect1 id="pam_limits-description"> - <title>DESCRIPTION</title> - <para> - The pam_limits PAM module sets limits on the system resources that can be - obtained in a user-session. Users of <emphasis>uid=0</emphasis> are affected - by this limits, too. - </para> - <para> - By default limits are taken from the <filename>/etc/security/limits.conf</filename> - config file. Then individual files from the <filename>/etc/security/limits.d/</filename> - directory are read. The files are parsed one after another in the order of "C" locale. - The effect of the individual files is the same as if all the files were - concatenated together in the order of parsing. - If a config file is explicitely specified with a module option then the - files in the above directory are not parsed. - </para> - <para> - The module must not be called by a multithreaded application. - </para> - <para> - If Linux PAM is compiled with audit support the module will report - when it denies access based on limit of maximum number of concurrent - login sessions. - </para> - </refsect1> - - <refsect1 id="pam_limits-options"> - <title>OPTIONS</title> - <variablelist> - <varlistentry> - <term> - <option>change_uid</option> - </term> - <listitem> - <para> - Change real uid to the user for who the limits are set up. Use this - option if you have problems like login not forking a shell for user - who has no processes. Be warned that something else may break when - you do this. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <option>conf=<replaceable>/path/to/limits.conf</replaceable></option> - </term> - <listitem> - <para> - Indicate an alternative limits.conf style configuration file to - override the default. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <option>debug</option> - </term> - <listitem> - <para> - Print debug information. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <option>utmp_early</option> - </term> - <listitem> - <para> - Some broken applications actually allocate a utmp entry for - the user before the user is admitted to the system. If some - of the services you are configuring PAM for do this, you can - selectively use this module argument to compensate for this - behavior and at the same time maintain system-wide consistency - with a single limits.conf file. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <option>noaudit</option> - </term> - <listitem> - <para> - Do not report exceeded maximum logins count to the audit subsystem. - </para> - </listitem> - </varlistentry> - </variablelist> - </refsect1> - - <refsect1 id="pam_limits-services"> - <title>MODULE SERVICES PROVIDED</title> - <para> - Only the <option>session</option> service is supported. - </para> - </refsect1> - - <refsect1 id="pam_limits-return_values"> - <title>RETURN VALUES</title> - <variablelist> - <varlistentry> - <term>PAM_ABORT</term> - <listitem> - <para> - Cannot get current limits. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term>PAM_IGNORE</term> - <listitem> - <para> - No limits found for this user. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term>PAM_PERM_DENIED</term> - <listitem> - <para> - New limits could not be set. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term>PAM_SERVICE_ERR</term> - <listitem> - <para> - Cannot read config file. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term>PAM_SESSEION_ERR</term> - <listitem> - <para> - Error recovering account name. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term>PAM_SUCCESS</term> - <listitem> - <para> - Limits were changed. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term>PAM_USER_UNKNOWN</term> - <listitem> - <para> - The user is not known to the system. - </para> - </listitem> - </varlistentry> - </variablelist> - </refsect1> - - <refsect1 id="pam_limits-files"> - <title>FILES</title> - <variablelist> - <varlistentry> - <term><filename>/etc/security/limits.conf</filename></term> - <listitem> - <para>Default configuration file</para> - </listitem> - </varlistentry> - </variablelist> - </refsect1> - - <refsect1 id='pam_limits-examples'> - <title>EXAMPLES</title> - <para> - For the services you need resources limits (login for example) put a - the following line in <filename>/etc/pam.d/login</filename> as the last - line for that service (usually after the pam_unix session line): - </para> - <programlisting> -#%PAM-1.0 -# -# Resource limits imposed on login sessions via pam_limits -# -session required pam_limits.so - </programlisting> - <para> - Replace "login" for each service you are using this module. - </para> - </refsect1> - - <refsect1 id="pam_limits-see_also"> - <title>SEE ALSO</title> - <para> - <citerefentry> - <refentrytitle>limits.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_limits-authors"> - <title>AUTHORS</title> - <para> - pam_limits was initially written by Cristian Gafton <gafton@redhat.com> - </para> - </refsect1> -</refentry> diff --git a/modules/pam_limits/pam_limits.c b/modules/pam_limits/pam_limits.c deleted file mode 100644 index f1e29b85..00000000 --- a/modules/pam_limits/pam_limits.c +++ /dev/null @@ -1,777 +0,0 @@ -/* - * pam_limits - impose resource limits when opening a user session - * - * 1.6 - modified for PLD (added process priority settings) - * by Marcin Korzonek <mkorz@shadow.eu.org> - * 1.5 - Elliot Lee's "max system logins patch" - * 1.4 - addressed bug in configuration file parser - * 1.3 - modified the configuration file format - * 1.2 - added 'debug' and 'conf=' arguments - * 1.1 - added @group support - * 1.0 - initial release - Linux ONLY - * - * See end for Copyright information - */ - -#if !defined(linux) && !defined(__linux) -#warning THIS CODE IS KNOWN TO WORK ONLY ON LINUX !!! -#endif - -#include "config.h" - -#include <stdio.h> -#include <unistd.h> -#include <string.h> -#include <ctype.h> -#include <stdlib.h> -#include <errno.h> -#include <syslog.h> -#include <stdarg.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <sys/resource.h> -#include <limits.h> -#include <glob.h> -#include <utmp.h> -#ifndef UT_USER /* some systems have ut_name instead of ut_user */ -#define UT_USER ut_user -#endif - -#include <grp.h> -#include <pwd.h> -#include <locale.h> - -#ifdef HAVE_LIBAUDIT -#include <libaudit.h> -#endif - -/* Module defines */ -#define LINE_LENGTH 1024 - -#define LIMITS_DEF_USER 0 /* limit was set by an user entry */ -#define LIMITS_DEF_GROUP 1 /* limit was set by a group entry */ -#define LIMITS_DEF_ALLGROUP 2 /* limit was set by a group entry */ -#define LIMITS_DEF_ALL 3 /* limit was set by an default entry */ -#define LIMITS_DEF_DEFAULT 4 /* limit was set by an default entry */ -#define LIMITS_DEF_NONE 5 /* this limit was not set yet */ - -static const char *limits_def_names[] = { - "USER", - "GROUP", - "ALLGROUP", - "ALL", - "DEFAULT", - "NONE", - NULL -}; - -struct user_limits_struct { - int supported; - int src_soft; - int src_hard; - struct rlimit limit; -}; - -/* internal data */ -struct pam_limit_s { - int login_limit; /* the max logins limit */ - int login_limit_def; /* which entry set the login limit */ - int flag_numsyslogins; /* whether to limit logins only for a - specific user or to count all logins */ - int priority; /* the priority to run user process with */ - struct user_limits_struct limits[RLIM_NLIMITS]; - const char *conf_file; - int utmp_after_pam_call; - char login_group[LINE_LENGTH]; -}; - -#define LIMIT_LOGIN RLIM_NLIMITS+1 -#define LIMIT_NUMSYSLOGINS RLIM_NLIMITS+2 - -#define LIMIT_PRI RLIM_NLIMITS+3 - -#define LIMIT_SOFT 1 -#define LIMIT_HARD 2 - -#define PAM_SM_SESSION - -#include <security/pam_modules.h> -#include <security/_pam_macros.h> -#include <security/pam_modutil.h> -#include <security/pam_ext.h> - -/* argument parsing */ - -#define PAM_DEBUG_ARG 0x0001 -#define PAM_DO_SETREUID 0x0002 -#define PAM_UTMP_EARLY 0x0004 -#define PAM_NO_AUDIT 0x0008 - -/* Limits from globbed files. */ -#define LIMITS_CONF_GLOB LIMITS_FILE_DIR - -#define CONF_FILE (pl->conf_file != NULL)?pl->conf_file:LIMITS_FILE - -static int -_pam_parse (const pam_handle_t *pamh, int argc, const char **argv, - struct pam_limit_s *pl) -{ - int ctrl=0; - - /* step through arguments */ - for (ctrl=0; argc-- > 0; ++argv) { - - /* generic options */ - - if (!strcmp(*argv,"debug")) { - ctrl |= PAM_DEBUG_ARG; - } else if (!strncmp(*argv,"conf=",5)) { - pl->conf_file = *argv+5; - } else if (!strncmp(*argv,"change_uid",10)) { - ctrl |= PAM_DO_SETREUID; - } else if (!strcmp(*argv,"utmp_early")) { - ctrl |= PAM_UTMP_EARLY; - } else if (!strcmp(*argv,"noaudit")) { - ctrl |= PAM_NO_AUDIT; - } else { - pam_syslog(pamh, LOG_ERR, "unknown option: %s", *argv); - } - } - - return ctrl; -} - - -#define LIMITED_OK 0 /* limit setting appeared to work */ -#define LIMIT_ERR 1 /* error setting a limit */ -#define LOGIN_ERR 2 /* too many logins err */ - -/* Counts the number of user logins and check against the limit*/ -static int -check_logins (pam_handle_t *pamh, const char *name, int limit, int ctrl, - struct pam_limit_s *pl) -{ - struct utmp *ut; - int count; - - if (ctrl & PAM_DEBUG_ARG) { - pam_syslog(pamh, LOG_DEBUG, - "checking logins for '%s' (maximum of %d)", name, limit); - } - - if (limit < 0) - return 0; /* no limits imposed */ - if (limit == 0) /* maximum 0 logins ? */ { - pam_syslog(pamh, LOG_WARNING, "No logins allowed for '%s'", name); - return LOGIN_ERR; - } - - setutent(); - - /* Because there is no definition about when an application - actually adds a utmp entry, some applications bizarrely do the - utmp call before the have PAM authenticate them to the system: - you're logged it, sort of...? Anyway, you can use the - "utmp_early" module argument in your PAM config file to make - allowances for this sort of problem. (There should be a PAM - standard for this, since if a module wants to actually map a - username then any early utmp entry will be for the unmapped - name = broken.) */ - - if (ctrl & PAM_UTMP_EARLY) { - count = 0; - } else { - count = 1; - } - - while((ut = getutent())) { -#ifdef USER_PROCESS - if (ut->ut_type != USER_PROCESS) { - continue; - } -#endif - if (ut->UT_USER[0] == '\0') { - continue; - } - if (!pl->flag_numsyslogins) { - if (((pl->login_limit_def == LIMITS_DEF_USER) - || (pl->login_limit_def == LIMITS_DEF_GROUP) - || (pl->login_limit_def == LIMITS_DEF_DEFAULT)) - && strncmp(name, ut->UT_USER, sizeof(ut->UT_USER)) != 0) { - continue; - } - if ((pl->login_limit_def == LIMITS_DEF_ALLGROUP) - && !pam_modutil_user_in_group_nam_nam(pamh, ut->UT_USER, pl->login_group)) { - continue; - } - } - if (++count > limit) { - break; - } - } - endutent(); - if (count > limit) { - if (name) { - pam_syslog(pamh, LOG_WARNING, - "Too many logins (max %d) for %s", limit, name); - } else { - pam_syslog(pamh, LOG_WARNING, "Too many system logins (max %d)", limit); - } - return LOGIN_ERR; - } - return 0; -} - -static int init_limits(struct pam_limit_s *pl) -{ - int i; - int retval = PAM_SUCCESS; - - D(("called.")); - - for(i = 0; i < RLIM_NLIMITS; i++) { - int r = getrlimit(i, &pl->limits[i].limit); - if (r == -1) { - pl->limits[i].supported = 0; - if (errno != EINVAL) { - retval = !PAM_SUCCESS; - } - } else { - pl->limits[i].supported = 1; - pl->limits[i].src_soft = LIMITS_DEF_NONE; - pl->limits[i].src_hard = LIMITS_DEF_NONE; - } - } - - errno = 0; - pl->priority = getpriority (PRIO_PROCESS, 0); - if (pl->priority == -1 && errno != 0) - retval = !PAM_SUCCESS; - pl->login_limit = -2; - pl->login_limit_def = LIMITS_DEF_NONE; - - return retval; -} - -static void -process_limit (const pam_handle_t *pamh, int source, const char *lim_type, - const char *lim_item, const char *lim_value, - int ctrl, struct pam_limit_s *pl) -{ - int limit_item; - int limit_type = 0; - int int_value = 0; - rlim_t rlimit_value = 0; - char *endptr; - const char *value_orig = lim_value; - - if (ctrl & PAM_DEBUG_ARG) - pam_syslog(pamh, LOG_DEBUG, "%s: processing %s %s %s for %s", - __FUNCTION__, lim_type, lim_item, lim_value, - limits_def_names[source]); - - if (strcmp(lim_item, "cpu") == 0) - limit_item = RLIMIT_CPU; - else if (strcmp(lim_item, "fsize") == 0) - limit_item = RLIMIT_FSIZE; - else if (strcmp(lim_item, "data") == 0) - limit_item = RLIMIT_DATA; - else if (strcmp(lim_item, "stack") == 0) - limit_item = RLIMIT_STACK; - else if (strcmp(lim_item, "core") == 0) - limit_item = RLIMIT_CORE; - else if (strcmp(lim_item, "rss") == 0) - limit_item = RLIMIT_RSS; - else if (strcmp(lim_item, "nproc") == 0) - limit_item = RLIMIT_NPROC; - else if (strcmp(lim_item, "nofile") == 0) - limit_item = RLIMIT_NOFILE; - else if (strcmp(lim_item, "memlock") == 0) - limit_item = RLIMIT_MEMLOCK; -#ifdef RLIMIT_AS - else if (strcmp(lim_item, "as") == 0) - limit_item = RLIMIT_AS; -#endif /*RLIMIT_AS*/ -#ifdef RLIMIT_LOCKS - else if (strcmp(lim_item, "locks") == 0) - limit_item = RLIMIT_LOCKS; -#endif -#ifdef RLIMIT_SIGPENDING - else if (strcmp(lim_item, "sigpending") == 0) - limit_item = RLIMIT_SIGPENDING; -#endif -#ifdef RLIMIT_MSGQUEUE - else if (strcmp(lim_item, "msgqueue") == 0) - limit_item = RLIMIT_MSGQUEUE; -#endif -#ifdef RLIMIT_NICE - else if (strcmp(lim_item, "nice") == 0) - limit_item = RLIMIT_NICE; -#endif -#ifdef RLIMIT_RTPRIO - else if (strcmp(lim_item, "rtprio") == 0) - limit_item = RLIMIT_RTPRIO; -#endif - else if (strcmp(lim_item, "maxlogins") == 0) { - limit_item = LIMIT_LOGIN; - pl->flag_numsyslogins = 0; - } else if (strcmp(lim_item, "maxsyslogins") == 0) { - limit_item = LIMIT_NUMSYSLOGINS; - pl->flag_numsyslogins = 1; - } else if (strcmp(lim_item, "priority") == 0) { - limit_item = LIMIT_PRI; - } else { - pam_syslog(pamh, LOG_DEBUG, "unknown limit item '%s'", lim_item); - return; - } - - if (strcmp(lim_type,"soft")==0) - limit_type=LIMIT_SOFT; - else if (strcmp(lim_type, "hard")==0) - limit_type=LIMIT_HARD; - else if (strcmp(lim_type,"-")==0) - limit_type=LIMIT_SOFT | LIMIT_HARD; - else if (limit_item != LIMIT_LOGIN && limit_item != LIMIT_NUMSYSLOGINS) { - pam_syslog(pamh, LOG_DEBUG, "unknown limit type '%s'", lim_type); - return; - } - if (limit_item != LIMIT_PRI -#ifdef RLIMIT_NICE - && limit_item != RLIMIT_NICE -#endif - && (strcmp(lim_value, "-1") == 0 - || strcmp(lim_value, "-") == 0 || strcmp(lim_value, "unlimited") == 0 - || strcmp(lim_value, "infinity") == 0)) { - int_value = -1; - rlimit_value = RLIM_INFINITY; - } else if (limit_item == LIMIT_PRI || limit_item == LIMIT_LOGIN || -#ifdef RLIMIT_NICE - limit_item == RLIMIT_NICE || -#endif - limit_item == LIMIT_NUMSYSLOGINS) { - long temp; - temp = strtol (lim_value, &endptr, 10); - temp = temp < INT_MAX ? temp : INT_MAX; - int_value = temp > INT_MIN ? temp : INT_MIN; - if (int_value == 0 && value_orig == endptr) { - pam_syslog(pamh, LOG_DEBUG, - "wrong limit value '%s' for limit type '%s'", - lim_value, lim_type); - return; - } - } else { -#ifdef __USE_FILE_OFFSET64 - rlimit_value = strtoull (lim_value, &endptr, 10); -#else - rlimit_value = strtoul (lim_value, &endptr, 10); -#endif - if (rlimit_value == 0 && value_orig == endptr) { - pam_syslog(pamh, LOG_DEBUG, - "wrong limit value '%s' for limit type '%s'", - lim_value, lim_type); - return; - } - } - - /* one more special case when limiting logins */ - if ((source == LIMITS_DEF_ALL || source == LIMITS_DEF_ALLGROUP) - && (limit_item != LIMIT_LOGIN)) { - if (ctrl & PAM_DEBUG_ARG) - pam_syslog(pamh, LOG_DEBUG, - "'%%' domain valid for maxlogins type only"); - return; - } - - switch(limit_item) { - case RLIMIT_CPU: - if (rlimit_value != RLIM_INFINITY) - { - if (rlimit_value >= RLIM_INFINITY/60) - rlimit_value = RLIM_INFINITY; - else - rlimit_value *= 60; - } - break; - case RLIMIT_FSIZE: - case RLIMIT_DATA: - case RLIMIT_STACK: - case RLIMIT_CORE: - case RLIMIT_RSS: - case RLIMIT_MEMLOCK: -#ifdef RLIMIT_AS - case RLIMIT_AS: -#endif - if (rlimit_value != RLIM_INFINITY) - { - if (rlimit_value >= RLIM_INFINITY/1024) - rlimit_value = RLIM_INFINITY; - else - rlimit_value *= 1024; - } - break; -#ifdef RLIMIT_NICE - case RLIMIT_NICE: - if (int_value > 19) - int_value = 19; - if (int_value < -20) - int_value = -20; - rlimit_value = 20 - int_value; -#endif - break; - } - - if ( (limit_item != LIMIT_LOGIN) - && (limit_item != LIMIT_NUMSYSLOGINS) - && (limit_item != LIMIT_PRI) ) { - if (limit_type & LIMIT_SOFT) { - if (pl->limits[limit_item].src_soft < source) { - return; - } else { - pl->limits[limit_item].limit.rlim_cur = rlimit_value; - pl->limits[limit_item].src_soft = source; - } - } - if (limit_type & LIMIT_HARD) { - if (pl->limits[limit_item].src_hard < source) { - return; - } else { - pl->limits[limit_item].limit.rlim_max = rlimit_value; - pl->limits[limit_item].src_hard = source; - } - } - } else { - /* recent kernels support negative priority limits (=raise priority) */ - - if (limit_item == LIMIT_PRI) { - pl->priority = int_value; - } else { - if (pl->login_limit_def < source) { - return; - } else { - pl->login_limit = int_value; - pl->login_limit_def = source; - } - } - } - return; -} - -static int parse_config_file(pam_handle_t *pamh, const char *uname, int ctrl, - struct pam_limit_s *pl) -{ - FILE *fil; - char buf[LINE_LENGTH]; - - /* check for the LIMITS_FILE */ - if (ctrl & PAM_DEBUG_ARG) - pam_syslog(pamh, LOG_DEBUG, "reading settings from '%s'", CONF_FILE); - fil = fopen(CONF_FILE, "r"); - if (fil == NULL) { - pam_syslog (pamh, LOG_WARNING, - "cannot read settings from %s: %m", CONF_FILE); - return PAM_SERVICE_ERR; - } - - /* start the show */ - while (fgets(buf, LINE_LENGTH, fil) != NULL) { - char domain[LINE_LENGTH]; - char ltype[LINE_LENGTH]; - char item[LINE_LENGTH]; - char value[LINE_LENGTH]; - int i; - size_t j; - char *tptr,*line; - - line = buf; - /* skip the leading white space */ - while (*line && isspace(*line)) - line++; - - /* Rip off the comments */ - tptr = strchr(line,'#'); - if (tptr) - *tptr = '\0'; - /* Rip off the newline char */ - tptr = strchr(line,'\n'); - if (tptr) - *tptr = '\0'; - /* Anything left ? */ - if (!strlen(line)) - continue; - - domain[0] = ltype[0] = item[0] = value[0] = '\0'; - - i = sscanf(line,"%s%s%s%s", domain, ltype, item, value); - D(("scanned line[%d]: domain[%s], ltype[%s], item[%s], value[%s]", - i, domain, ltype, item, value)); - - for(j=0; j < strlen(ltype); j++) - ltype[j]=tolower(ltype[j]); - - if (i == 4) { /* a complete line */ - for(j=0; j < strlen(item); j++) - item[j]=tolower(item[j]); - for(j=0; j < strlen(value); j++) - value[j]=tolower(value[j]); - - if (strcmp(uname, domain) == 0) /* this user have a limit */ - process_limit(pamh, LIMITS_DEF_USER, ltype, item, value, ctrl, pl); - else if (domain[0]=='@') { - if (ctrl & PAM_DEBUG_ARG) { - pam_syslog(pamh, LOG_DEBUG, - "checking if %s is in group %s", - uname, domain + 1); - } - if (pam_modutil_user_in_group_nam_nam(pamh, uname, domain+1)) - process_limit(pamh, LIMITS_DEF_GROUP, ltype, item, value, ctrl, - pl); - } else if (domain[0]=='%') { - if (ctrl & PAM_DEBUG_ARG) { - pam_syslog(pamh, LOG_DEBUG, - "checking if %s is in group %s", - uname, domain + 1); - } - if (strcmp(domain,"%") == 0) - process_limit(pamh, LIMITS_DEF_ALL, ltype, item, value, ctrl, - pl); - else if (pam_modutil_user_in_group_nam_nam(pamh, uname, domain+1)) { - strcpy(pl->login_group, domain+1); - process_limit(pamh, LIMITS_DEF_ALLGROUP, ltype, item, value, ctrl, - pl); - } - } else if (strcmp(domain, "*") == 0) - process_limit(pamh, LIMITS_DEF_DEFAULT, ltype, item, value, ctrl, - pl); - } else if (i == 2 && ltype[0] == '-') { /* Probably a no-limit line */ - if (strcmp(uname, domain) == 0) { - if (ctrl & PAM_DEBUG_ARG) { - pam_syslog(pamh, LOG_DEBUG, "no limits for '%s'", uname); - } - fclose(fil); - return PAM_IGNORE; - } else if (domain[0] == '@' && pam_modutil_user_in_group_nam_nam(pamh, uname, domain+1)) { - if (ctrl & PAM_DEBUG_ARG) { - pam_syslog(pamh, LOG_DEBUG, - "no limits for '%s' in group '%s'", - uname, domain+1); - } - fclose(fil); - return PAM_IGNORE; - } - } else { - pam_syslog(pamh, LOG_WARNING, "invalid line '%s' - skipped", line); - } - } - fclose(fil); - return PAM_SUCCESS; -} - -static int setup_limits(pam_handle_t *pamh, - const char *uname, uid_t uid, int ctrl, - struct pam_limit_s *pl) -{ - int i; - int status; - int retval = LIMITED_OK; - - for (i=0, status=LIMITED_OK; i<RLIM_NLIMITS; i++) { - if (!pl->limits[i].supported) { - /* skip it if its not known to the system */ - continue; - } - if (pl->limits[i].src_soft == LIMITS_DEF_NONE && - pl->limits[i].src_hard == LIMITS_DEF_NONE) { - /* skip it if its not initialized */ - continue; - } - if (pl->limits[i].limit.rlim_cur > pl->limits[i].limit.rlim_max) - pl->limits[i].limit.rlim_cur = pl->limits[i].limit.rlim_max; - status |= setrlimit(i, &pl->limits[i].limit); - } - - if (status) { - retval = LIMIT_ERR; - } - - status = setpriority(PRIO_PROCESS, 0, pl->priority); - if (status != 0) { - retval = LIMIT_ERR; - } - - if (uid == 0) { - D(("skip login limit check for uid=0")); - } else if (pl->login_limit > 0) { - if (check_logins(pamh, uname, pl->login_limit, ctrl, pl) == LOGIN_ERR) { -#ifdef HAVE_LIBAUDIT - if (!(ctrl & PAM_NO_AUDIT)) { - pam_modutil_audit_write(pamh, AUDIT_ANOM_LOGIN_SESSIONS, - "pam_limits", PAM_PERM_DENIED); - /* ignore return value as we fail anyway */ - } -#endif - retval |= LOGIN_ERR; - } - } else if (pl->login_limit == 0) { - retval |= LOGIN_ERR; - } - - return retval; -} - -/* now the session stuff */ -PAM_EXTERN int -pam_sm_open_session (pam_handle_t *pamh, int flags UNUSED, - int argc, const char **argv) -{ - int retval; - int i; - int glob_rc; - char *user_name; - struct passwd *pwd; - int ctrl; - struct pam_limit_s plstruct; - struct pam_limit_s *pl = &plstruct; - glob_t globbuf; - const char *oldlocale; - - D(("called.")); - - memset(pl, 0, sizeof(*pl)); - memset(&globbuf, 0, sizeof(globbuf)); - - ctrl = _pam_parse(pamh, argc, argv, pl); - retval = pam_get_item( pamh, PAM_USER, (void*) &user_name ); - if ( user_name == NULL || retval != PAM_SUCCESS ) { - pam_syslog(pamh, LOG_CRIT, "open_session - error recovering username"); - return PAM_SESSION_ERR; - } - - pwd = pam_modutil_getpwnam(pamh, user_name); - if (!pwd) { - if (ctrl & PAM_DEBUG_ARG) - pam_syslog(pamh, LOG_WARNING, - "open_session username '%s' does not exist", user_name); - return PAM_USER_UNKNOWN; - } - - retval = init_limits(pl); - if (retval != PAM_SUCCESS) { - pam_syslog(pamh, LOG_WARNING, "cannot initialize"); - return PAM_ABORT; - } - - retval = parse_config_file(pamh, pwd->pw_name, ctrl, pl); - if (retval == PAM_IGNORE) { - D(("the configuration file ('%s') has an applicable '<domain> -' entry", CONF_FILE)); - return PAM_SUCCESS; - } - if (retval != PAM_SUCCESS || pl->conf_file != NULL) - /* skip reading limits.d if config file explicitely specified */ - goto out; - - /* Read subsequent *.conf files, if they exist. */ - - /* set the LC_COLLATE so the sorting order doesn't depend - on system locale */ - - oldlocale = setlocale(LC_COLLATE, "C"); - glob_rc = glob(LIMITS_CONF_GLOB, GLOB_ERR, NULL, &globbuf); - - if (oldlocale != NULL) - setlocale (LC_COLLATE, oldlocale); - - if (!glob_rc) { - /* Parse the *.conf files. */ - for (i = 0; globbuf.gl_pathv[i] != NULL; i++) { - pl->conf_file = globbuf.gl_pathv[i]; - retval = parse_config_file(pamh, pwd->pw_name, ctrl, pl); - if (retval == PAM_IGNORE) { - D(("the configuration file ('%s') has an applicable '<domain> -' entry", pl->conf_file)); - globfree(&globbuf); - return PAM_SUCCESS; - } - if (retval != PAM_SUCCESS) - goto out; - } - } - -out: - globfree(&globbuf); - if (retval != PAM_SUCCESS) - { - pam_syslog(pamh, LOG_WARNING, "error parsing the configuration file: '%s' ",CONF_FILE); - return retval; - } - - if (ctrl & PAM_DO_SETREUID) { - setreuid(pwd->pw_uid, -1); - } - - retval = setup_limits(pamh, pwd->pw_name, pwd->pw_uid, ctrl, pl); - if (retval & LOGIN_ERR) - pam_error(pamh, _("Too many logins for '%s'."), pwd->pw_name); - if (retval != LIMITED_OK) { - return PAM_PERM_DENIED; - } - - return PAM_SUCCESS; -} - -PAM_EXTERN int -pam_sm_close_session (pam_handle_t *pamh UNUSED, int flags UNUSED, - int argc UNUSED, const char **argv UNUSED) -{ - /* nothing to do */ - return PAM_SUCCESS; -} - -#ifdef PAM_STATIC - -/* static module data */ - -struct pam_module _pam_limits_modstruct = { - "pam_limits", - NULL, - NULL, - NULL, - pam_sm_open_session, - pam_sm_close_session, - NULL -}; -#endif - -/* - * Copyright (c) Cristian Gafton, 1996-1997, <gafton@redhat.com> - * All rights reserved. - * - * 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. - */ diff --git a/modules/pam_limits/tst-pam_limits b/modules/pam_limits/tst-pam_limits deleted file mode 100755 index f563beb7..00000000 --- a/modules/pam_limits/tst-pam_limits +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/sh -../../tests/tst-dlopen .libs/pam_limits.so diff --git a/modules/pam_listfile/.cvsignore b/modules/pam_listfile/.cvsignore deleted file mode 100644 index f54f6f27..00000000 --- a/modules/pam_listfile/.cvsignore +++ /dev/null @@ -1,8 +0,0 @@ -*.la -*.lo -.deps -.libs -Makefile -Makefile.in -README -pam_listfile.8 diff --git a/modules/pam_listfile/Makefile.am b/modules/pam_listfile/Makefile.am deleted file mode 100644 index 2f211320..00000000 --- a/modules/pam_listfile/Makefile.am +++ /dev/null @@ -1,31 +0,0 @@ -# -# Copyright (c) 2005, 2006 Thorsten Kukuk <kukuk@suse.de> -# - -CLEANFILES = *~ - -EXTRA_DIST = README $(MANS) $(XMLS) tst-pam_listfile - -man_MANS = pam_listfile.8 -XMLS = README.xml pam_listfile.8.xml - -TESTS = tst-pam_listfile - -securelibdir = $(SECUREDIR) -secureconfdir = $(SCONFIGDIR) - -AM_CFLAGS = -I$(top_srcdir)/libpam/include -I$(top_srcdir)/libpamc/include -AM_LDFLAGS = -no-undefined -avoid-version -module -if HAVE_VERSIONING - AM_LDFLAGS += -Wl,--version-script=$(srcdir)/../modules.map -endif - -securelib_LTLIBRARIES = pam_listfile.la -pam_listfile_la_LIBADD = -L$(top_builddir)/libpam -lpam - -if ENABLE_REGENERATE_MAN -noinst_DATA = README -README: pam_listfile.8.xml --include $(top_srcdir)/Make.xml.rules -endif - diff --git a/modules/pam_listfile/README.xml b/modules/pam_listfile/README.xml deleted file mode 100644 index d851aef3..00000000 --- a/modules/pam_listfile/README.xml +++ /dev/null @@ -1,41 +0,0 @@ -<?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_listfile.8.xml"> ---> -]> - -<article> - - <articleinfo> - - <title> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" - href="pam_listfile.8.xml" xpointer='xpointer(//refnamediv[@id = "pam_listfile-name"]/*)'/> - </title> - - </articleinfo> - - <section> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" - href="pam_listfile.8.xml" xpointer='xpointer(//refsect1[@id = "pam_listfile-description"]/*)'/> - </section> - - <section> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" - href="pam_listfile.8.xml" xpointer='xpointer(//refsect1[@id = "pam_listfile-options"]/*)'/> - </section> - - <section> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" - href="pam_listfile.8.xml" xpointer='xpointer(//refsect1[@id = "pam_listfile-examples"]/*)'/> - </section> - - <section> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" - href="pam_listfile.8.xml" xpointer='xpointer(//refsect1[@id = "pam_listfile-author"]/*)'/> - </section> - -</article> diff --git a/modules/pam_listfile/pam_listfile.8.xml b/modules/pam_listfile/pam_listfile.8.xml deleted file mode 100644 index e54e80a4..00000000 --- a/modules/pam_listfile/pam_listfile.8.xml +++ /dev/null @@ -1,297 +0,0 @@ -<?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_listfile"> - - <refmeta> - <refentrytitle>pam_listfile</refentrytitle> - <manvolnum>8</manvolnum> - <refmiscinfo class="sectdesc">Linux-PAM Manual</refmiscinfo> - </refmeta> - - <refnamediv id="pam_listfile-name"> - <refname>pam_listfile</refname> - <refpurpose>deny or allow services based on an arbitrary file</refpurpose> - </refnamediv> - - <refsynopsisdiv> - <cmdsynopsis id="pam_listfile-cmdsynopsis"> - <command>pam_listfile.so</command> - <arg choice="plain"> - item=[tty|user|rhost|ruser|group|shell] - </arg> - <arg choice="plain"> - sense=[allow|deny] - </arg> - <arg choice="plain"> - file=<replaceable>/path/filename</replaceable> - </arg> - <arg choice="plain"> - onerr=[succeed|fail] - </arg> - <arg choice="opt"> - apply=[<replaceable>user</replaceable>|<replaceable>@group</replaceable>] - </arg> - <arg choice="opt"> - quiet - </arg> - </cmdsynopsis> - </refsynopsisdiv> - - <refsect1 id="pam_listfile-description"> - - <title>DESCRIPTION</title> - - <para> - pam_listfile is a PAM module which provides a way to deny or - allow services based on an arbitrary file. - </para> - <para> - The module gets the <option>item</option> of the type specified -- - <emphasis>user</emphasis> specifies the username, - <emphasis>PAM_USER</emphasis>; tty specifies the name of the terminal - over which the request has been made, <emphasis>PAM_TTY</emphasis>; - rhost specifies the name of the remote host (if any) from which the - request was made, <emphasis>PAM_RHOST</emphasis>; and ruser specifies - the name of the remote user (if available) who made the request, - <emphasis>PAM_RUSER</emphasis> -- and looks for an instance of that - item in the <option>file=<replaceable>filename</replaceable></option>. - <filename>filename</filename> contains one line per item listed. If - the item is found, then if - <option>sense=<replaceable>allow</replaceable></option>, - <emphasis>PAM_SUCCESS</emphasis> is returned, causing the authorization - request to succeed; else if - <option>sense=<replaceable>deny</replaceable></option>, - <emphasis>PAM_AUTH_ERR</emphasis> is returned, causing the authorization - request to fail. - </para> - <para> - If an error is encountered (for instance, if - <filename>filename</filename> does not exist, or a poorly-constructed - argument is encountered), then if <emphasis>onerr=succeed</emphasis>, - <emphasis>PAM_SUCCESS</emphasis> is returned, otherwise if - <emphasis>onerr=fail</emphasis>, <emphasis>PAM_AUTH_ERR</emphasis> or - <emphasis>PAM_SERVICE_ERR</emphasis> (as appropriate) will be returned. - </para> - <para> - An additional argument, <option>apply=</option>, can be used - to restrict the application of the above to a specific user - (<option>apply=<replaceable>username</replaceable></option>) - or a given group - (<option>apply=<replaceable>@groupname</replaceable></option>). - This added restriction is only meaningful when used with the - <emphasis>tty</emphasis>, <emphasis>rhost</emphasis> and - <emphasis>shell</emphasis> items. - </para> - <para> - Besides this last one, all arguments should be specified; do not - count on any default behavior. - </para> - <para> - No credentials are awarded by this module. - </para> - </refsect1> - - <refsect1 id="pam_listfile-options"> - - <title>OPTIONS</title> - <para> - <variablelist> - - <varlistentry> - <term> - <option>item=[tty|user|rhost|ruser|group|shell]</option> - </term> - <listitem> - <para> - What is listed in the file and should be checked for. - </para> - </listitem> - </varlistentry> - - <varlistentry> - <term> - <option>sense=[allow|deny]</option> - </term> - <listitem> - <para> - Action to take if found in file, if the item is NOT found in - the file, then the opposite action is requested. - </para> - </listitem> - </varlistentry> - - <varlistentry> - <term> - <option>file=<replaceable>/path/filename</replaceable></option> - </term> - <listitem> - <para> - File containing one item per line. The file needs to be a plain - file and not world writeable. - </para> - </listitem> - </varlistentry> - - <varlistentry> - <term> - <option>onerr=[succeed|fail]</option> - </term> - <listitem> - <para> - What to do if something weird happens like being unable to open - the file. - </para> - </listitem> - </varlistentry> - - <varlistentry> - <term> - <option>apply=[<replaceable>user</replaceable>|<replaceable>@group</replaceable>]</option> - </term> - <listitem> - <para> - Restrict the user class for which the restriction apply. Note that - with <option>item=[user|ruser|group]</option> this does not make sense, - but for <option>item=[tty|rhost|shell]</option> it have a meaning. - </para> - </listitem> - </varlistentry> - - <varlistentry> - <term> - <option>quiet</option> - </term> - <listitem> - <para> - Do not treat service refusals or missing list files as - errors that need to be logged. - </para> - </listitem> - </varlistentry> - </variablelist> - - </para> - </refsect1> - - <refsect1 id="pam_listfile-services"> - <title>MODULE SERVICES PROVIDED</title> - <para> - The services <option>auth</option>, <option>account</option>, - <option>password</option> and <option>session</option> are supported. - </para> - </refsect1> - - <refsect1 id='pam_listfile-return_values'> - <title>RETURN VALUES</title> - <para> - <variablelist> - - <varlistentry> - <term>PAM_AUTH_ERR</term> - <listitem> - <para>Authentication failure.</para> - </listitem> - </varlistentry> - - <varlistentry> - <term>PAM_BUF_ERR</term> - <listitem> - <para> - Memory buffer error. - </para> - </listitem> - </varlistentry> - - <varlistentry> - <term>PAM_IGNORE</term> - <listitem> - <para> - The rule does not apply to the <option>apply</option> option. - </para> - </listitem> - </varlistentry> - - <varlistentry> - <term>PAM_SERVICE_ERR</term> - <listitem> - <para> - Error in service module. - </para> - </listitem> - </varlistentry> - - <varlistentry> - <term>PAM_SUCCESS</term> - <listitem> - <para> - Success. - </para> - </listitem> - </varlistentry> - - </variablelist> - </para> - </refsect1> - - <refsect1 id='pam_listfile-examples'> - <title>EXAMPLES</title> - <para> - Classic 'ftpusers' authentication can be implemented with this entry - in <filename>/etc/pam.d/ftpd</filename>: - <programlisting> -# -# deny ftp-access to users listed in the /etc/ftpusers file -# -auth required pam_listfile.so \ - onerr=succeed item=user sense=deny file=/etc/ftpusers - </programlisting> - Note, users listed in <filename>/etc/ftpusers</filename> file are - (counterintuitively) <emphasis>not</emphasis> allowed access to - the ftp service. - </para> - <para> - To allow login access only for certain users, you can use a - <filename>/etc/pam.d/login</filename> entry like this: - <programlisting> -# -# permit login to users listed in /etc/loginusers -# -auth required pam_listfile.so \ - onerr=fail item=user sense=allow file=/etc/loginusers - </programlisting> - For this example to work, all users who are allowed to use the - login service should be listed in the file - <filename>/etc/loginusers</filename>. Unless you are explicitly - trying to lock out root, make sure that when you do this, you leave - a way for root to log in, either by listing root in - <filename>/etc/loginusers</filename>, or by listing a user who is - able to <emphasis>su</emphasis> to the root account. - </para> - </refsect1> - - <refsect1 id='pam_listfile-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_listfile-author'> - <title>AUTHOR</title> - <para> - pam_listfile was written by Michael K. Johnson <johnsonm@redhat.com> - and Elliot Lee <sopwith@cuc.edu>. - </para> - </refsect1> - -</refentry> diff --git a/modules/pam_listfile/pam_listfile.c b/modules/pam_listfile/pam_listfile.c deleted file mode 100644 index f276e5b8..00000000 --- a/modules/pam_listfile/pam_listfile.c +++ /dev/null @@ -1,462 +0,0 @@ -/* - * by Elliot Lee <sopwith@redhat.com>, Red Hat Software. July 25, 1996. - * log refused access error christopher mccrory <chrismcc@netus.com> 1998/7/11 - * - * This code began life as the pam_rootok module. - */ - -#include "config.h" - -#include <stdio.h> -#include <stdlib.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <unistd.h> -#include <syslog.h> -#include <stdarg.h> -#include <string.h> -#include <pwd.h> -#include <grp.h> - -#ifdef DEBUG -#include <assert.h> -#endif - -/* - * here, we make a definition for the externally accessible function - * in this file (this definition is required for static a module - * but strongly encouraged generally) it is used to instruct the - * modules include file to define the function prototypes. - */ - -#define PAM_SM_AUTH -#define PAM_SM_ACCOUNT -#define PAM_SM_PASSWORD -#define PAM_SM_SESSION - -#include <security/pam_modules.h> -#include <security/_pam_macros.h> -#include <security/pam_modutil.h> -#include <security/pam_ext.h> - -/* checks if a user is on a list of members */ -static int is_on_list(char * const *list, const char *member) -{ - while (*list) { - if (strcmp(*list, member) == 0) - return 1; - list++; - } - return 0; -} - -/* --- authentication management functions (only) --- */ - -/* Extended Items that are not directly available via pam_get_item() */ -#define EI_GROUP (1 << 0) -#define EI_SHELL (1 << 1) - -/* Constants for apply= parameter */ -#define APPLY_TYPE_NULL 0 -#define APPLY_TYPE_NONE 1 -#define APPLY_TYPE_USER 2 -#define APPLY_TYPE_GROUP 3 - -#define LESSER(a, b) ((a) < (b) ? (a) : (b)) - -PAM_EXTERN int -pam_sm_authenticate (pam_handle_t *pamh, int flags UNUSED, - int argc, const char **argv) -{ - int retval, i, citem=0, extitem=0, onerr=PAM_SERVICE_ERR, sense=2, quiet=0; - const void *void_citemp; - const char *citemp; - char *ifname=NULL; - char aline[256]; - char mybuf[256],myval[256]; - struct stat fileinfo; - FILE *inf; - char apply_val[256]; - int apply_type; - - /* Stuff for "extended" items */ - struct passwd *userinfo; - struct group *grpinfo; - char *itemlist[256]; /* Maximum of 256 items */ - - apply_type=APPLY_TYPE_NULL; - memset(apply_val,0,sizeof(apply_val)); - - for(i=0; i < argc; i++) { - { - const char *junk; - - memset(mybuf,'\0',sizeof(mybuf)); - memset(myval,'\0',sizeof(mybuf)); - junk = strchr(argv[i], '='); - if((junk == NULL) || (junk - argv[i]) >= (int) sizeof(mybuf)) { - pam_syslog(pamh,LOG_ERR, "Bad option: \"%s\"", - argv[i]); - continue; - } - strncpy(mybuf, argv[i], - LESSER(junk - argv[i], (int)sizeof(mybuf) - 1)); - strncpy(myval, junk + 1, sizeof(myval) - 1); - } - if(!strcmp(mybuf,"onerr")) - if(!strcmp(myval,"succeed")) - onerr = PAM_SUCCESS; - else if(!strcmp(myval,"fail")) - onerr = PAM_SERVICE_ERR; - else { - if (ifname) free (ifname); - return PAM_SERVICE_ERR; - } - else if(!strcmp(mybuf,"sense")) - if(!strcmp(myval,"allow")) - sense=0; - else if(!strcmp(myval,"deny")) - sense=1; - else { - if (ifname) free (ifname); - return onerr; - } - else if(!strcmp(mybuf,"file")) { - if (ifname) free (ifname); - ifname = (char *)malloc(strlen(myval)+1); - if (!ifname) - return PAM_BUF_ERR; - strcpy(ifname,myval); - } else if(!strcmp(mybuf,"item")) - if(!strcmp(myval,"user")) - citem = PAM_USER; - else if(!strcmp(myval,"tty")) - citem = PAM_TTY; - else if(!strcmp(myval,"rhost")) - citem = PAM_RHOST; - else if(!strcmp(myval,"ruser")) - citem = PAM_RUSER; - else { /* These items are related to the user, but are not - directly gettable with pam_get_item */ - citem = PAM_USER; - if(!strcmp(myval,"group")) - extitem = EI_GROUP; - else if(!strcmp(myval,"shell")) - extitem = EI_SHELL; - else - citem = 0; - } else if(!strcmp(mybuf,"apply")) { - apply_type=APPLY_TYPE_NONE; - memset(apply_val,'\0',sizeof(apply_val)); - if (myval[0]=='@') { - apply_type=APPLY_TYPE_GROUP; - strncpy(apply_val,myval+1,sizeof(apply_val)-1); - } else { - apply_type=APPLY_TYPE_USER; - strncpy(apply_val,myval,sizeof(apply_val)-1); - } - } else if (!strcmp(mybuf,"quiet")) { - quiet = 1; - } else { - free(ifname); - pam_syslog(pamh,LOG_ERR, "Unknown option: %s",mybuf); - return onerr; - } - } - - if(!citem) { - pam_syslog(pamh,LOG_ERR, - "Unknown item or item not specified"); - free(ifname); - return onerr; - } else if(!ifname) { - pam_syslog(pamh,LOG_ERR, "List filename not specified"); - return onerr; - } else if(sense == 2) { - pam_syslog(pamh,LOG_ERR, - "Unknown sense or sense not specified"); - free(ifname); - return onerr; - } else if( - (apply_type==APPLY_TYPE_NONE) || - ((apply_type!=APPLY_TYPE_NULL) && (*apply_val=='\0')) - ) { - pam_syslog(pamh,LOG_ERR, - "Invalid usage for apply= parameter"); - free (ifname); - return onerr; - } - - /* Check if it makes sense to use the apply= parameter */ - if (apply_type != APPLY_TYPE_NULL) { - if((citem==PAM_USER) || (citem==PAM_RUSER)) { - pam_syslog(pamh,LOG_WARNING, - "Non-sense use for apply= parameter"); - apply_type=APPLY_TYPE_NULL; - } - if(extitem && (extitem==EI_GROUP)) { - pam_syslog(pamh,LOG_WARNING, - "Non-sense use for apply= parameter"); - apply_type=APPLY_TYPE_NULL; - } - } - - /* Short-circuit - test if this session apply for this user */ - { - const char *user_name; - int rval; - - rval=pam_get_user(pamh,&user_name,NULL); - if((rval==PAM_SUCCESS) && user_name && user_name[0]) { - /* Got it ? Valid ? */ - if(apply_type==APPLY_TYPE_USER) { - if(strcmp(user_name, apply_val)) { - /* Does not apply to this user */ -#ifdef DEBUG - pam_syslog(pamh,LOG_DEBUG, - "don't apply: apply=%s, user=%s", - apply_val,user_name); -#endif /* DEBUG */ - free(ifname); - return PAM_IGNORE; - } - } else if(apply_type==APPLY_TYPE_GROUP) { - if(!pam_modutil_user_in_group_nam_nam(pamh,user_name,apply_val)) { - /* Not a member of apply= group */ -#ifdef DEBUG - pam_syslog(pamh,LOG_DEBUG, - - "don't apply: %s not a member of group %s", - user_name,apply_val); -#endif /* DEBUG */ - free(ifname); - return PAM_IGNORE; - } - } - } - } - - retval = pam_get_item(pamh,citem,&void_citemp); - citemp = void_citemp; - if(retval != PAM_SUCCESS) { - return onerr; - } - if((citem == PAM_USER) && !citemp) { - retval = pam_get_user(pamh,&citemp,NULL); - if (retval != PAM_SUCCESS || !citemp) { - free(ifname); - return PAM_SERVICE_ERR; - } - } - if((citem == PAM_TTY) && citemp) { - /* Normalize the TTY name. */ - if(strncmp(citemp, "/dev/", 5) == 0) { - citemp += 5; - } - } - - if(!citemp || (strlen(citemp) == 0)) { - free(ifname); - /* The item was NULL - we are sure not to match */ - return sense?PAM_SUCCESS:PAM_AUTH_ERR; - } - - if(extitem) { - switch(extitem) { - case EI_GROUP: - userinfo = pam_modutil_getpwnam(pamh, citemp); - if (userinfo == NULL) { - pam_syslog(pamh,LOG_ERR, "getpwnam(%s) failed", - citemp); - free(ifname); - return onerr; - } - grpinfo = pam_modutil_getgrgid(pamh, userinfo->pw_gid); - if (grpinfo == NULL) { - pam_syslog(pamh,LOG_ERR, "getgrgid(%d) failed", - (int)userinfo->pw_gid); - free(ifname); - return onerr; - } - itemlist[0] = x_strdup(grpinfo->gr_name); - setgrent(); - for (i=1; (i < (int)(sizeof(itemlist)/sizeof(itemlist[0])-1)) && - (grpinfo = getgrent()); ) { - if (is_on_list(grpinfo->gr_mem,citemp)) { - itemlist[i++] = x_strdup(grpinfo->gr_name); - } - } - endgrent(); - itemlist[i] = NULL; - break; - case EI_SHELL: - /* Assume that we have already gotten PAM_USER in - pam_get_item() - a valid assumption since citem - gets set to PAM_USER in the extitem switch */ - userinfo = pam_modutil_getpwnam(pamh, citemp); - if (userinfo == NULL) { - pam_syslog(pamh,LOG_ERR, "getpwnam(%s) failed", - citemp); - free(ifname); - return onerr; - } - citemp = userinfo->pw_shell; - break; - default: - pam_syslog(pamh,LOG_ERR, - - "Internal weirdness, unknown extended item %d", - extitem); - free(ifname); - return onerr; - } - } -#ifdef DEBUG - pam_syslog(pamh,LOG_INFO, - - "Got file = %s, item = %d, value = %s, sense = %d", - ifname, citem, citemp, sense); -#endif - if(lstat(ifname,&fileinfo)) { - pam_syslog(pamh,LOG_ERR, "Couldn't open %s",ifname); - free(ifname); - return onerr; - } - - if((fileinfo.st_mode & S_IWOTH) - || !S_ISREG(fileinfo.st_mode)) { - /* If the file is world writable or is not a - normal file, return error */ - pam_syslog(pamh,LOG_ERR, - "%s is either world writable or not a normal file", - ifname); - free(ifname); - return PAM_AUTH_ERR; - } - - inf = fopen(ifname,"r"); - if(inf == NULL) { /* Check that we opened it successfully */ - if (onerr == PAM_SERVICE_ERR) { - /* Only report if it's an error... */ - pam_syslog(pamh,LOG_ERR, "Error opening %s", ifname); - } - free(ifname); - return onerr; - } - /* There should be no more errors from here on */ - retval=PAM_AUTH_ERR; - /* This loop assumes that PAM_SUCCESS == 0 - and PAM_AUTH_ERR != 0 */ -#ifdef DEBUG - assert(PAM_SUCCESS == 0); - assert(PAM_AUTH_ERR != 0); -#endif - if(extitem == EI_GROUP) { - while((fgets(aline,sizeof(aline),inf) != NULL) - && retval) { - if(strlen(aline) == 0) - continue; - if(aline[strlen(aline) - 1] == '\n') - aline[strlen(aline) - 1] = '\0'; - for(i=0;itemlist[i];) - /* If any of the items match, strcmp() == 0, and we get out - of this loop */ - retval = (strcmp(aline,itemlist[i++]) && retval); - } - for(i=0;itemlist[i];) - free(itemlist[i++]); - } else { - while((fgets(aline,sizeof(aline),inf) != NULL) - && retval) { - char *a = aline; - if(strlen(aline) == 0) - continue; - if(aline[strlen(aline) - 1] == '\n') - aline[strlen(aline) - 1] = '\0'; - if(strlen(aline) == 0) - continue; - if(aline[strlen(aline) - 1] == '\r') - aline[strlen(aline) - 1] = '\0'; - if(citem == PAM_TTY) - if(strncmp(a, "/dev/", 5) == 0) - a += 5; - retval = strcmp(a,citemp); - } - } - fclose(inf); - free(ifname); - if ((sense && retval) || (!sense && !retval)) { -#ifdef DEBUG - pam_syslog(pamh,LOG_INFO, - "Returning PAM_SUCCESS, retval = %d", retval); -#endif - return PAM_SUCCESS; - } - else { - const void *service; - const char *user_name; -#ifdef DEBUG - pam_syslog(pamh,LOG_INFO, - "Returning PAM_AUTH_ERR, retval = %d", retval); -#endif - (void) pam_get_item(pamh, PAM_SERVICE, &service); - (void) pam_get_user(pamh, &user_name, NULL); - if (!quiet) - pam_syslog (pamh, LOG_ALERT, "Refused user %s for service %s", - user_name, (const char *)service); - return PAM_AUTH_ERR; - } -} - -PAM_EXTERN int -pam_sm_setcred (pam_handle_t *pamh UNUSED, int flags UNUSED, - int argc UNUSED, const char **argv UNUSED) -{ - return PAM_SUCCESS; -} - -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); -} - -PAM_EXTERN int -pam_sm_open_session (pam_handle_t *pamh, int flags, - int argc, const char **argv) -{ - return pam_sm_authenticate(pamh, flags, argc, argv); -} - -PAM_EXTERN int -pam_sm_close_session (pam_handle_t *pamh, int flags, - int argc, const char **argv) -{ - return pam_sm_authenticate(pamh, flags, argc, argv); -} - -PAM_EXTERN int -pam_sm_chauthtok (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_listfile_modstruct = { - "pam_listfile", - pam_sm_authenticate, - pam_sm_setcred, - pam_sm_acct_mgmt, - pam_sm_open_session, - pam_sm_close_session, - pam_sm_chauthtok, -}; - -#endif /* PAM_STATIC */ - -/* end of module definition */ diff --git a/modules/pam_listfile/tst-pam_listfile b/modules/pam_listfile/tst-pam_listfile deleted file mode 100755 index f555a9f5..00000000 --- a/modules/pam_listfile/tst-pam_listfile +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/sh -../../tests/tst-dlopen .libs/pam_listfile.so diff --git a/modules/pam_localuser/.cvsignore b/modules/pam_localuser/.cvsignore deleted file mode 100644 index ae7dab97..00000000 --- a/modules/pam_localuser/.cvsignore +++ /dev/null @@ -1,10 +0,0 @@ -*.la -*.lo -*.so -*~ -.deps -.libs -Makefile -Makefile.in -README -pam_localuser.8 diff --git a/modules/pam_localuser/Makefile.am b/modules/pam_localuser/Makefile.am deleted file mode 100644 index d4e47937..00000000 --- a/modules/pam_localuser/Makefile.am +++ /dev/null @@ -1,31 +0,0 @@ -# -# Copyright (c) 2005, 2006 Thorsten Kukuk <kukuk@suse.de> -# - -CLEANFILES = *~ - -EXTRA_DIST = README ${MANS} $(XMLS) tst-pam_localuser - -TESTS = tst-pam_localuser - -man_MANS = pam_localuser.8 -XMLS = README.xml pam_localuser.8.xml - -securelibdir = $(SECUREDIR) -secureconfdir = $(SCONFIGDIR) - -AM_CFLAGS = -I$(top_srcdir)/libpam/include -I$(top_srcdir)/libpamc/include -AM_LDFLAGS = -no-undefined -avoid-version -module -if HAVE_VERSIONING - AM_LDFLAGS += -Wl,--version-script=$(srcdir)/../modules.map -endif - -securelib_LTLIBRARIES = pam_localuser.la -pam_localuser_la_LIBADD = -L$(top_builddir)/libpam -lpam - -if ENABLE_REGENERATE_MAN -noinst_DATA = README -README: pam_localuser.8.xml --include $(top_srcdir)/Make.xml.rules -endif - diff --git a/modules/pam_localuser/README.xml b/modules/pam_localuser/README.xml deleted file mode 100644 index 4ab56d9d..00000000 --- a/modules/pam_localuser/README.xml +++ /dev/null @@ -1,41 +0,0 @@ -<?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_localuser.8.xml"> ---> -]> - -<article> - - <articleinfo> - - <title> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" - href="pam_localuser.8.xml" xpointer='xpointer(//refnamediv[@id = "pam_localuser-name"]/*)'/> - </title> - - </articleinfo> - - <section> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" - href="pam_localuser.8.xml" xpointer='xpointer(//refsect1[@id = "pam_localuser-description"]/*)'/> - </section> - - <section> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" - href="pam_localuser.8.xml" xpointer='xpointer(//refsect1[@id = "pam_localuser-options"]/*)'/> - </section> - - <section> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" - href="pam_localuser.8.xml" xpointer='xpointer(//refsect1[@id = "pam_localuser-examples"]/*)'/> - </section> - - <section> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" - href="pam_localuser.8.xml" xpointer='xpointer(//refsect1[@id = "pam_localuser-author"]/*)'/> - </section> - -</article> diff --git a/modules/pam_localuser/pam_localuser.8.xml b/modules/pam_localuser/pam_localuser.8.xml deleted file mode 100644 index ac00ce99..00000000 --- a/modules/pam_localuser/pam_localuser.8.xml +++ /dev/null @@ -1,173 +0,0 @@ -<?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_localuser"> - - <refmeta> - <refentrytitle>pam_localuser</refentrytitle> - <manvolnum>8</manvolnum> - <refmiscinfo class="sectdesc">Linux-PAM Manual</refmiscinfo> - </refmeta> - - <refnamediv id="pam_localuser-name"> - <refname>pam_localuser</refname> - <refpurpose>require users to be listed in /etc/passwd</refpurpose> - </refnamediv> - - <refsynopsisdiv> - <cmdsynopsis id="pam_localuser-cmdsynopsis"> - <command>pam_localuser.so</command> - <arg choice="opt"> - debug - </arg> - <arg choice="opt"> - file=<replaceable>/path/passwd</replaceable> - </arg> - </cmdsynopsis> - </refsynopsisdiv> - - <refsect1 id="pam_localuser-description"> - - <title>DESCRIPTION</title> - - <para> - pam_localuser is a PAM module to help implementing site-wide login - policies, where they typically include a subset of the network's - users and a few accounts that are local to a particular workstation. - Using pam_localuser and pam_wheel or pam_listfile is an effective - way to restrict access to either local users and/or a subset of the - network's users. - </para> - <para> - This could also be implemented using pam_listfile.so and a very - short awk script invoked by cron, but it's common enough to have - been separated out. - </para> - - </refsect1> - - <refsect1 id="pam_localuser-options"> - - <title>OPTIONS</title> - <para> - <variablelist> - - <varlistentry> - <term> - <option>debug</option> - </term> - <listitem> - <para> - Print debug information. - </para> - </listitem> - </varlistentry> - - <varlistentry> - <term> - <option>file=<replaceable>/path/passwd</replaceable></option> - </term> - <listitem> - <para> - Use a file other than <filename>/etc/passwd</filename>. - </para> - </listitem> - </varlistentry> - - </variablelist> - - </para> - </refsect1> - - <refsect1 id="pam_localuser-services"> - <title>MODULE SERVICES PROVIDED</title> - <para> - All services (<option>account</option>, <option>auth</option>, - <option>password</option> and <option>session</option>) are supported. - </para> - </refsect1> - - <refsect1 id='pam_localuser-return_values'> - <title>RETURN VALUES</title> - <para> - <variablelist> - - <varlistentry> - <term>PAM_SUCCESS</term> - <listitem> - <para> - The new localuser was set successfull. - </para> - </listitem> - </varlistentry> - - <varlistentry> - <term>PAM_SERVICE_ERR</term> - <listitem> - <para> - No username was given. - </para> - </listitem> - </varlistentry> - - <varlistentry> - <term>PAM_USER_UNKNOWN</term> - <listitem> - <para> - User not known. - </para> - </listitem> - </varlistentry> - - </variablelist> - </para> - </refsect1> - - <refsect1 id='pam_localuser-examples'> - <title>EXAMPLES</title> - <para> - Add the following line to <filename>/etc/pam.d/su</filename> to - allow only local users in group wheel to use su. - <programlisting> -account sufficient pam_localuser.so -account required pam_wheel.so - </programlisting> - </para> - </refsect1> - - <refsect1 id="pam_localuser-files"> - <title>FILES</title> - <variablelist> - <varlistentry> - <term><filename>/etc/passwd</filename></term> - <listitem> - <para>Local user account information.</para> - </listitem> - </varlistentry> - </variablelist> - </refsect1> - - <refsect1 id='pam_localuser-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_localuser-author'> - <title>AUTHOR</title> - <para> - pam_localuser was written by Nalin Dahyabhai <nalin@redhat.com>. - </para> - </refsect1> - -</refentry> diff --git a/modules/pam_localuser/pam_localuser.c b/modules/pam_localuser/pam_localuser.c deleted file mode 100644 index aa43bc4c..00000000 --- a/modules/pam_localuser/pam_localuser.c +++ /dev/null @@ -1,174 +0,0 @@ -/* - * Copyright 2001, 2004 Red Hat, Inc. - * - * 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 <limits.h> -#include <stdlib.h> -#include <string.h> -#include <syslog.h> -#include <stdio.h> -#include <stdarg.h> -#include <time.h> -#include <unistd.h> -#include <sys/stat.h> -#include <sys/types.h> - -#define PAM_SM_AUTH -#define PAM_SM_ACCOUNT -#include <security/pam_modules.h> -#include <security/_pam_macros.h> -#include <security/pam_ext.h> - -#define MODULE_NAME "pam_localuser" - -PAM_EXTERN int -pam_sm_authenticate (pam_handle_t *pamh, int flags UNUSED, - int argc, const char **argv) -{ - int i, ret = PAM_SUCCESS; - FILE *fp; - int debug = 0; - const char *filename = "/etc/passwd"; - char line[LINE_MAX], name[LINE_MAX]; - const char* user; - - /* process arguments */ - for(i = 0; i < argc; i++) { - if(strcmp("debug", argv[i]) == 0) { - debug = 1; - } - } - for(i = 0; i < argc; i++) { - if(strncmp("file=", argv[i], 5) == 0) { - filename = argv[i] + 5; - if(debug) { - pam_syslog (pamh, LOG_DEBUG, - "set filename to \"%s\"", - filename); - } - } - } - - /* open the file */ - fp = fopen(filename, "r"); - if(fp == NULL) { - pam_syslog (pamh, LOG_ERR, "error opening \"%s\": %m", - filename); - return PAM_SYSTEM_ERR; - } - - if(pam_get_user(pamh, &user, NULL) != PAM_SUCCESS) { - pam_syslog (pamh, LOG_ERR, "user name not specified yet"); - fclose(fp); - return PAM_SYSTEM_ERR; - } - - if ((user == NULL) || (strlen(user) == 0)) { - pam_syslog (pamh, LOG_ERR, "user name not valid"); - fclose(fp); - return PAM_SYSTEM_ERR; - } - - /* scan the file, using fgets() instead of fgetpwent() because i - * don't want to mess with applications which call fgetpwent() */ - ret = PAM_PERM_DENIED; - snprintf(name, sizeof(name), "%s:", user); - i = strlen(name); - while(fgets(line, sizeof(line), fp) != NULL) { - if(debug) { - pam_syslog (pamh, LOG_DEBUG, "checking \"%s\"", line); - } - if(strncmp(name, line, i) == 0) { - ret = PAM_SUCCESS; - break; - } - } - - /* okay, we're done */ - fclose(fp); - return ret; -} - -PAM_EXTERN int -pam_sm_setcred (pam_handle_t *pamh UNUSED, int flags UNUSED, - int argc UNUSED, const char **argv UNUSED) -{ - return PAM_SUCCESS; -} - -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); -} - -PAM_EXTERN int -pam_sm_open_session (pam_handle_t *pamh, int flags, - int argc, const char **argv) -{ - return pam_sm_authenticate(pamh, flags, argc, argv); -} - -PAM_EXTERN int -pam_sm_close_session (pam_handle_t *pamh, int flags, - int argc, const char **argv) -{ - return pam_sm_authenticate(pamh, flags, argc, argv); -} - -PAM_EXTERN int -pam_sm_chauthtok (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_localuser_modstruct = { - "pam_localuser", - pam_sm_authenticate, - pam_sm_setcred, - pam_sm_acct_mgmt, - pam_sm_open_session, - pam_sm_close_session, - pam_sm_chauthtok -}; - -#endif diff --git a/modules/pam_localuser/tst-pam_localuser b/modules/pam_localuser/tst-pam_localuser deleted file mode 100755 index 2bcdf6b9..00000000 --- a/modules/pam_localuser/tst-pam_localuser +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/sh -../../tests/tst-dlopen .libs/pam_localuser.so diff --git a/modules/pam_loginuid/.cvsignore b/modules/pam_loginuid/.cvsignore deleted file mode 100644 index cb4cb6de..00000000 --- a/modules/pam_loginuid/.cvsignore +++ /dev/null @@ -1,9 +0,0 @@ -*.la -*.lo -.deps -.libs -Makefile -Makefile.in -pam_loginuid -README -pam_loginuid.8 diff --git a/modules/pam_loginuid/Makefile.am b/modules/pam_loginuid/Makefile.am deleted file mode 100644 index 636db963..00000000 --- a/modules/pam_loginuid/Makefile.am +++ /dev/null @@ -1,34 +0,0 @@ -# -# Copyright (c) 2006 Thorsten Kukuk <kukuk@thkukuk.de> -# - -CLEANFILES = *~ - -EXTRA_DIST = README $(MANS) $(XMLS) tst-pam_loginuid - -man_MANS = pam_loginuid.8 - -XMLS = README.xml pam_loginuid.8.xml - -securelibdir = $(SECUREDIR) -secureconfdir = $(SCONFIGDIR) - -AM_CFLAGS = -I$(top_srcdir)/libpam/include -I$(top_srcdir)/libpamc/include -AM_LDFLAGS = -no-undefined -avoid-version -module -if HAVE_VERSIONING - AM_LDFLAGS += -Wl,--version-script=$(srcdir)/../modules.map -endif - -securelib_LTLIBRARIES = pam_loginuid.la -pam_loginuid_la_LIBADD = -L$(top_builddir)/libpam -lpam @LIBAUDIT@ - -if ENABLE_REGENERATE_MAN - -noinst_DATA = README - -README: pam_loginuid.8.xml - --include $(top_srcdir)/Make.xml.rules -endif - -TESTS = tst-pam_loginuid diff --git a/modules/pam_loginuid/README.xml b/modules/pam_loginuid/README.xml deleted file mode 100644 index 3bcd38ab..00000000 --- a/modules/pam_loginuid/README.xml +++ /dev/null @@ -1,36 +0,0 @@ -<?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_loginuid.8.xml"> ---> -]> - -<article> - - <articleinfo> - - <title> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" - href="pam_loginuid.8.xml" xpointer='xpointer(//refnamediv[@id = "pam_loginuid-name"]/*)'/> - </title> - - </articleinfo> - - <section> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" - href="pam_loginuid.8.xml" xpointer='xpointer(//refsect1[@id = "pam_loginuid-description"]/*)'/> - </section> - - <section> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" - href="pam_loginuid.8.xml" xpointer='xpointer(//refsect1[@id = "pam_loginuid-examples"]/*)'/> - </section> - - <section> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" - href="pam_loginuid.8.xml" xpointer='xpointer(//refsect1[@id = "pam_loginuid-author"]/*)'/> - </section> - -</article> diff --git a/modules/pam_loginuid/pam_loginuid.8.xml b/modules/pam_loginuid/pam_loginuid.8.xml deleted file mode 100644 index f50336d0..00000000 --- a/modules/pam_loginuid/pam_loginuid.8.xml +++ /dev/null @@ -1,125 +0,0 @@ -<?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_loginuid"> - - <refmeta> - <refentrytitle>pam_loginuid</refentrytitle> - <manvolnum>8</manvolnum> - <refmiscinfo class="sectdesc">Linux-PAM Manual</refmiscinfo> - </refmeta> - - <refnamediv id="pam_loginuid-name"> - <refname>pam_loginuid</refname> - <refpurpose>Record user's login uid to the process attribute</refpurpose> - </refnamediv> - - <refsynopsisdiv> - <cmdsynopsis id="pam_loginuid-cmdsynopsis"> - <command>pam_loginuid.so</command> - <arg choice="opt"> - require_auditd - </arg> - </cmdsynopsis> - </refsynopsisdiv> - - <refsect1 id="pam_loginuid-description"> - - <title>DESCRIPTION</title> - - <para> - The pam_loginuid module sets the loginuid process attribute for the - process that was authenticated. This is necessary for applications - to be correctly audited. This PAM module should only be used for entry - point applications like: login, sshd, gdm, vsftpd, crond and atd. - There are probably other entry point applications besides these. - You should not use it for applications like sudo or su as that - defeats the purpose by changing the loginuid to the account they just - switched to. - </para> - </refsect1> - - <refsect1 id="pam_loginuid-options"> - <title>OPTIONS</title> - <variablelist> - <varlistentry> - <term> - <option>require_auditd</option> - </term> - <listitem> - <para> - This option, when given, will cause this module to query - the audit daemon status and deny logins if it is not running. - </para> - </listitem> - </varlistentry> - </variablelist> - </refsect1> - - <refsect1 id="pam_loginuid-services"> - <title>MODULE SERVICES PROVIDED</title> - <para> - The <option>session</option> service is supported. - </para> - </refsect1> - - <refsect1 id='pam_loginuid-return_values'> - <title>RETURN VALUES</title> - <para> - <variablelist> - <varlistentry> - <term>PAM_SESSION_ERR</term> - <listitem> - <para> - An error occured during session management. - </para> - </listitem> - </varlistentry> - - </variablelist> - </para> - </refsect1> - - <refsect1 id='pam_loginuid-examples'> - <title>EXAMPLES</title> - <programlisting> -#%PAM-1.0 -auth required pam_unix.so -auth required pam_nologin.so -account required pam_unix.so -password required pam_unix.so -session required pam_unix.so -session required pam_loginuid.so - </programlisting> - </refsect1> - - <refsect1 id='pam_loginuid-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>, - <citerefentry> - <refentrytitle>auditctl</refentrytitle><manvolnum>8</manvolnum> - </citerefentry>, - <citerefentry> - <refentrytitle>auditd</refentrytitle><manvolnum>8</manvolnum> - </citerefentry> - </para> - </refsect1> - - <refsect1 id='pam_loginuid-author'> - <title>AUTHOR</title> - <para> - pam_loginuid was written by Steve Grubb <sgrubb@redhat.com> - </para> - </refsect1> - -</refentry> diff --git a/modules/pam_loginuid/pam_loginuid.c b/modules/pam_loginuid/pam_loginuid.c deleted file mode 100644 index 13509e7e..00000000 --- a/modules/pam_loginuid/pam_loginuid.c +++ /dev/null @@ -1,239 +0,0 @@ -/* pam_loginuid.c -- - * Copyright 2005 Red Hat Inc., Durham, North Carolina. - * All Rights Reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - * Authors: - * Steve Grubb <sgrubb@redhat.com> - * - * PAM module that sets the login uid introduced in kernel 2.6.11 - */ - -#include "config.h" -#include <stdio.h> -#include <stdarg.h> -#include <syslog.h> -#include <string.h> -#include <pwd.h> -#include <unistd.h> -#include <limits.h> -#include <errno.h> - -#include <security/pam_modules.h> -#include <security/pam_ext.h> -#include <security/pam_modutil.h> - -#include <fcntl.h> - -#ifdef HAVE_LIBAUDIT -#include <libaudit.h> -#include <sys/select.h> -#include <errno.h> -#endif - -/* - * This function writes the loginuid to the /proc system. It returns - * 0 on success and 1 on failure. - */ -static int set_loginuid(pam_handle_t *pamh, uid_t uid) -{ - int fd, count, rc = 0; - char loginuid[24]; - - count = snprintf(loginuid, sizeof(loginuid), "%d", uid); - fd = open("/proc/self/loginuid", O_NOFOLLOW|O_WRONLY|O_TRUNC); - if (fd < 0) { - if (errno != ENOENT) { - rc = 1; - pam_syslog(pamh, LOG_ERR, - "Cannot open /proc/self/loginuid: %m"); - } - return rc; - } - if (pam_modutil_write(fd, loginuid, count) != count) - rc = 1; - close(fd); - return rc; -} - -#ifdef HAVE_LIBAUDIT -/* - * This function is called only if "require_auditd" option is passed. It is - * called after loginuid has been set. The purpose is to disallow logins - * should the audit daemon not be running or crashed. It returns PAM_SUCCESS - * if the audit daemon is running and PAM_SESSION_ERR otherwise. - */ -static int check_auditd(void) -{ - int fd, retval; - - fd = audit_open(); - if (fd < 0) { - /* This is here to let people that build their own kernel - and disable the audit system get in. 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; - return PAM_SESSION_ERR; - } - retval = audit_request_status(fd); - if (retval > 0) { - struct audit_reply rep; - int i; - int timeout = 30; /* tenths of seconds */ - fd_set read_mask; - - FD_ZERO(&read_mask); - FD_SET(fd, &read_mask); - - for (i = 0; i < timeout; i++) { - struct timeval t; - int rc; - - t.tv_sec = 0; - t.tv_usec = 100000; - do { - rc = select(fd+1, &read_mask, NULL, NULL, &t); - } while (rc < 0 && errno == EINTR); - - rc = audit_get_reply(fd, &rep, GET_REPLY_NONBLOCKING,0); - if (rc > 0) { - /* If we get done or error, break out */ - if (rep.type == NLMSG_DONE || - rep.type == NLMSG_ERROR) - break; - - /* If its not status, keep looping */ - if (rep.type != AUDIT_GET) - continue; - - /* Found it... */ - close(fd); - if (rep.status->pid == 0) - return PAM_SESSION_ERR; - else - return PAM_SUCCESS; - } - } - } - close(fd); - if (retval == -ECONNREFUSED) { - /* This is here to let people that build their own kernel - and disable the audit system get in. ECONNREFUSED is - issued by the kernel when there is "no on listening". */ - return PAM_SUCCESS; - } else if (retval == -EPERM && getuid() != 0) { - /* If we get this, then the kernel supports auditing - * but we don't have enough privilege to write to the - * socket. Therefore, we have already been authenticated - * and we are a common user. Just act as though auditing - * is not enabled. Any other error we take seriously. */ - return PAM_SUCCESS; - } - - return PAM_SESSION_ERR; -} -#endif - -/* - * Initialize audit session for user - */ -static int -_pam_loginuid(pam_handle_t *pamh, int flags UNUSED, -#ifdef HAVE_LIBAUDIT - int argc, const char **argv -#else - int argc UNUSED, const char **argv UNUSED -#endif -) -{ - const char *user = NULL; - struct passwd *pwd; -#ifdef HAVE_LIBAUDIT - int require_auditd = 0; -#endif - - /* get user name */ - if (pam_get_user(pamh, &user, NULL) != PAM_SUCCESS) - { - pam_syslog(pamh, LOG_ERR, "error recovering login user-name"); - return PAM_SESSION_ERR; - } - - /* get user info */ - if ((pwd = pam_modutil_getpwnam(pamh, user)) == NULL) { - pam_syslog(pamh, LOG_ERR, - "error: login user-name '%s' does not exist", user); - return PAM_SESSION_ERR; - } - - if (set_loginuid(pamh, pwd->pw_uid)) { - pam_syslog(pamh, LOG_ERR, "set_loginuid failed\n"); - return PAM_SESSION_ERR; - } - -#ifdef HAVE_LIBAUDIT - while (argc-- > 0) { - if (strcmp(*argv, "require_auditd") == 0) - require_auditd = 1; - argv++; - } - - if (require_auditd) - return check_auditd(); - else -#endif - return PAM_SUCCESS; -} - -/* - * PAM routines - * - * This is here for vsftpd which doesn't seem to run the session stack - */ -PAM_EXTERN int -pam_sm_acct_mgmt(pam_handle_t *pamh, int flags, int argc, const char **argv) -{ - return _pam_loginuid(pamh, flags, argc, argv); -} - -PAM_EXTERN int -pam_sm_open_session(pam_handle_t *pamh, int flags, int argc, const char **argv) -{ - return _pam_loginuid(pamh, flags, argc, argv); -} - -PAM_EXTERN int -pam_sm_close_session(pam_handle_t *pamh UNUSED, int flags UNUSED, - int argc UNUSED, const char **argv UNUSED) -{ - return PAM_SUCCESS; -} - -/* static module data */ -#ifdef PAM_STATIC -struct pam_module _pam_loginuid_modstruct = { - "pam_loginuid", - NULL, - NULL, - pam_sm_acct_mgmt, - pam_sm_open_session, - pam_sm_close_session, - NULL -}; -#endif diff --git a/modules/pam_loginuid/tst-pam_loginuid b/modules/pam_loginuid/tst-pam_loginuid deleted file mode 100755 index bd1e83b7..00000000 --- a/modules/pam_loginuid/tst-pam_loginuid +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/sh -../../tests/tst-dlopen .libs/pam_loginuid.so diff --git a/modules/pam_mail/.cvsignore b/modules/pam_mail/.cvsignore deleted file mode 100644 index e34886b5..00000000 --- a/modules/pam_mail/.cvsignore +++ /dev/null @@ -1,8 +0,0 @@ -*.la -*.lo -.deps -.libs -Makefile -Makefile.in -README -pam_mail.8 diff --git a/modules/pam_mail/Makefile.am b/modules/pam_mail/Makefile.am deleted file mode 100644 index 0b5d2d70..00000000 --- a/modules/pam_mail/Makefile.am +++ /dev/null @@ -1,31 +0,0 @@ -# -# Copyright (c) 2005, 2006 Thorsten Kukuk <kukuk@suse.de> -# - -CLEANFILES = *~ - -EXTRA_DIST = README $(MANS) $(XMLS) tst-pam_mail - -man_MANS = pam_mail.8 -XMLS = README.xml pam_mail.8.xml - -TESTS = tst-pam_mail - -securelibdir = $(SECUREDIR) -secureconfdir = $(SCONFIGDIR) - -AM_CFLAGS = -I$(top_srcdir)/libpam/include -I$(top_srcdir)/libpamc/include -AM_LDFLAGS = -no-undefined -avoid-version -module -if HAVE_VERSIONING - AM_LDFLAGS += -Wl,--version-script=$(srcdir)/../modules.map -endif - -securelib_LTLIBRARIES = pam_mail.la -pam_mail_la_LIBADD = -L$(top_builddir)/libpam -lpam - -if ENABLE_REGENERATE_MAN -noinst_DATA = README -README: pam_mail.8.xml --include $(top_srcdir)/Make.xml.rules -endif - diff --git a/modules/pam_mail/README.xml b/modules/pam_mail/README.xml deleted file mode 100644 index 4165d857..00000000 --- a/modules/pam_mail/README.xml +++ /dev/null @@ -1,41 +0,0 @@ -<?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_mail.8.xml"> ---> -]> - -<article> - - <articleinfo> - - <title> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" - href="pam_mail.8.xml" xpointer='xpointer(//refnamediv[@id = "pam_mail-name"]/*)'/> - </title> - - </articleinfo> - - <section> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" - href="pam_mail.8.xml" xpointer='xpointer(//refsect1[@id = "pam_mail-description"]/*)'/> - </section> - - <section> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" - href="pam_mail.8.xml" xpointer='xpointer(//refsect1[@id = "pam_mail-options"]/*)'/> - </section> - - <section> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" - href="pam_mail.8.xml" xpointer='xpointer(//refsect1[@id = "pam_mail-examples"]/*)'/> - </section> - - <section> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" - href="pam_mail.8.xml" xpointer='xpointer(//refsect1[@id = "pam_mail-author"]/*)'/> - </section> - -</article> diff --git a/modules/pam_mail/pam_mail.8.xml b/modules/pam_mail/pam_mail.8.xml deleted file mode 100644 index d3c481a5..00000000 --- a/modules/pam_mail/pam_mail.8.xml +++ /dev/null @@ -1,279 +0,0 @@ -<?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_mail"> - - <refmeta> - <refentrytitle>pam_mail</refentrytitle> - <manvolnum>8</manvolnum> - <refmiscinfo class="sectdesc">Linux-PAM Manual</refmiscinfo> - </refmeta> - - <refnamediv id="pam_mail-name"> - <refname>pam_mail</refname> - <refpurpose>Inform about available mail</refpurpose> - </refnamediv> - - <refsynopsisdiv> - <cmdsynopsis id="pam_mail-cmdsynopsis"> - <command>pam_mail.so</command> - <arg choice="opt"> - close - </arg> - <arg choice="opt"> - debug - </arg> - <arg choice="opt"> - dir=<replaceable>maildir</replaceable> - </arg> - <arg choice="opt"> - empty - </arg> - <arg choice="opt"> - hash=<replaceable>count</replaceable> - </arg> - <arg choice="opt"> - noenv - </arg> - <arg choice="opt"> - nopen - </arg> - <arg choice="opt"> - quit - </arg> - <arg choice="opt"> - standard - </arg> - </cmdsynopsis> - </refsynopsisdiv> - - <refsect1 id="pam_mail-description"> - - <title>DESCRIPTION</title> - - <para> - The pam_mail PAM module provides the "you have new mail" - service to the user. It can be plugged into any application - that has credential or session hooks. It gives a single message - indicating the <emphasis>newness</emphasis> of any mail it finds - in the user's mail folder. This module also sets the PAM - environment variable, <emphasis remap='B'>MAIL</emphasis>, to the - user's mail directory. - </para> - <para> - If the mail spool file (be it <filename>/var/mail/$USER</filename> - or a pathname given with the <option>dir=</option> parameter) is - a directory then pam_mail assumes it is in the - <emphasis remap='I'>Maildir</emphasis> format. - </para> - </refsect1> - - <refsect1 id="pam_mail-options"> - - <title>OPTIONS</title> - <para> - <variablelist> - - <varlistentry> - <term> - <option>close</option> - </term> - <listitem> - <para> - Indicate if the user has any mail also on logout. - </para> - </listitem> - </varlistentry> - - <varlistentry> - <term> - <option>debug</option> - </term> - <listitem> - <para> - Print debug information. - </para> - </listitem> - </varlistentry> - - <varlistentry> - <term> - <option>dir=<replaceable>maildir</replaceable></option> - </term> - <listitem> - <para> - Look for the users' mail in an alternative location defined by - <filename>maildir/<login></filename>. The default - location for mail is <filename>/var/mail/<login></filename>. - Note, if the supplied - <filename>maildir</filename> is prefixed by a '~', the - directory is interpreted as indicating a file in the user's - home directory. - </para> - </listitem> - </varlistentry> - - <varlistentry> - <term> - <option>empty</option> - </term> - <listitem> - <para> - Also print message if user has no mail. - </para> - </listitem> - </varlistentry> - - <varlistentry> - <term> - <option>hash=<replaceable>count</replaceable></option> - </term> - <listitem> - <para> - Mail directory hash depth. For example, a - <emphasis>hashcount</emphasis> of 2 would - make the mail file be - <filename>/var/spool/mail/u/s/user</filename>. - </para> - </listitem> - </varlistentry> - - <varlistentry> - <term> - <option>noenv</option> - </term> - <listitem> - <para> - Do not set the <emphasis remap='B'>MAIL</emphasis> - environment variable. - </para> - </listitem> - </varlistentry> - - <varlistentry> - <term> - <option>nopen</option> - </term> - <listitem> - <para> - Don't print any mail information on login. This flag is - useful to get the <emphasis remap='B'>MAIL</emphasis> - environment variable set, but to not display any information - about it. - </para> - </listitem> - </varlistentry> - - <varlistentry> - <term> - <option>quiet</option> - </term> - <listitem> - <para> - Only report when there is new mail. - </para> - </listitem> - </varlistentry> - - <varlistentry> - <term> - <option>standard</option> - </term> - <listitem> - <para> - Old style "You have..." format which doesn't show the - mail spool being used. This also implies "empty". - </para> - </listitem> - </varlistentry> - - </variablelist> - - </para> - </refsect1> - - <refsect1 id="pam_mail-services"> - <title>MODULE SERVICES PROVIDED</title> - <para> - The <emphasis remap='B'>auth</emphasis> and - <emphasis remap='B'>account</emphasis> services are supported. - </para> - </refsect1> - - <refsect1 id='pam_mail-return_values'> - <title>RETURN VALUES</title> - <variablelist> - <varlistentry> - <term>PAM_BUF_ERR</term> - <listitem> - <para> - Memory buffer error. - </para> - </listitem> - </varlistentry> - - <varlistentry> - <term>PAM_SERVICE_ERR</term> - <listitem> - <para> - Badly formed arguments. - </para> - </listitem> - </varlistentry> - - <varlistentry> - <term>PAM_SUCCESS</term> - <listitem> - <para> - Success. - </para> - </listitem> - </varlistentry> - - <varlistentry> - <term>PAM_USER_UNKNOWN</term> - <listitem> - <para> - User not known. - </para> - </listitem> - </varlistentry> - - </variablelist> - </refsect1> - - <refsect1 id='pam_mail-examples'> - <title>EXAMPLES</title> - <para> - Add the following line to <filename>/etc/pam.d/login</filename> to - indicate that the user has new mail when they login to the system. - <programlisting> -session optional pam_mail.so standard - </programlisting> - </para> - </refsect1> - - <refsect1 id='pam_mail-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_mail-author'> - <title>AUTHOR</title> - <para> - pam_mail was written by Andrew G. Morgan <morgan@kernel.org>. - </para> - </refsect1> - -</refentry> diff --git a/modules/pam_mail/pam_mail.c b/modules/pam_mail/pam_mail.c deleted file mode 100644 index 46395b53..00000000 --- a/modules/pam_mail/pam_mail.c +++ /dev/null @@ -1,489 +0,0 @@ -/* pam_mail module */ - -/* - * Written by Andrew Morgan <morgan@linux.kernel.org> 1996/3/11 - * $HOME additions by David Kinchlea <kinch@kinch.ark.com> 1997/1/7 - * mailhash additions by Chris Adams <cadams@ro.com> 1998/7/11 - */ - -#include "config.h" - -#include <ctype.h> -#include <pwd.h> -#include <stdarg.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <syslog.h> -#include <sys/stat.h> -#include <sys/types.h> -#include <unistd.h> -#include <dirent.h> -#include <errno.h> - -#ifdef HAVE_PATHS_H -#include <paths.h> -#endif - -#define DEFAULT_MAIL_DIRECTORY PAM_PATH_MAILDIR -#define MAIL_FILE_FORMAT "%s%s/%s" -#define MAIL_ENV_NAME "MAIL" -#define MAIL_ENV_FORMAT MAIL_ENV_NAME "=%s" - -/* - * here, we make a definition for the externally accessible function - * in this file (this definition is required for static a module - * but strongly encouraged generally) it is used to instruct the - * modules include file to define the function prototypes. - */ - -#define PAM_SM_SESSION -#define PAM_SM_AUTH - -#include <security/pam_modules.h> -#include <security/_pam_macros.h> -#include <security/pam_modutil.h> -#include <security/pam_ext.h> - -/* argument parsing */ - -#define PAM_DEBUG_ARG 0x0001 -#define PAM_NO_LOGIN 0x0002 -#define PAM_LOGOUT_TOO 0x0004 -#define PAM_NEW_MAIL_DIR 0x0010 -#define PAM_MAIL_SILENT 0x0020 -#define PAM_NO_ENV 0x0040 -#define PAM_HOME_MAIL 0x0100 -#define PAM_EMPTY_TOO 0x0200 -#define PAM_STANDARD_MAIL 0x0400 -#define PAM_QUIET_MAIL 0x1000 - -#define HAVE_NEW_MAIL 0x1 -#define HAVE_OLD_MAIL 0x2 -#define HAVE_NO_MAIL 0x3 -#define HAVE_MAIL 0x4 - -static int -_pam_parse (const pam_handle_t *pamh, int flags, int argc, - const char **argv, const char **maildir, size_t *hashcount) -{ - int ctrl=0; - - if (flags & PAM_SILENT) { - ctrl |= PAM_MAIL_SILENT; - } - - *hashcount = 0; - - /* step through arguments */ - for (; argc-- > 0; ++argv) { - - /* generic options */ - - if (!strcmp(*argv,"debug")) - ctrl |= PAM_DEBUG_ARG; - else if (!strcmp(*argv,"quiet")) - ctrl |= PAM_QUIET_MAIL; - else if (!strcmp(*argv,"standard")) - ctrl |= PAM_STANDARD_MAIL | PAM_EMPTY_TOO; - else if (!strncmp(*argv,"dir=",4)) { - *maildir = 4 + *argv; - if (**maildir != '\0') { - D(("new mail directory: %s", *maildir)); - ctrl |= PAM_NEW_MAIL_DIR; - } else { - pam_syslog(pamh, LOG_ERR, - "dir= specification missing argument - ignored"); - } - } else if (!strncmp(*argv,"hash=",5)) { - char *ep = NULL; - *hashcount = strtoul(*argv+5,&ep,10); - if (!ep) { - *hashcount = 0; - } - } else if (!strcmp(*argv,"close")) { - ctrl |= PAM_LOGOUT_TOO; - } else if (!strcmp(*argv,"nopen")) { - ctrl |= PAM_NO_LOGIN; - } else if (!strcmp(*argv,"noenv")) { - ctrl |= PAM_NO_ENV; - } else if (!strcmp(*argv,"empty")) { - ctrl |= PAM_EMPTY_TOO; - } else { - pam_syslog(pamh, LOG_ERR, "unknown option: %s", *argv); - } - } - - if ((*hashcount != 0) && !(ctrl & PAM_NEW_MAIL_DIR)) { - *maildir = DEFAULT_MAIL_DIRECTORY; - ctrl |= PAM_NEW_MAIL_DIR; - } - - return ctrl; -} - -static int -get_folder(pam_handle_t *pamh, int ctrl, - const char *path_mail, char **folder_p, size_t hashcount) -{ - int retval; - const char *user, *path; - char *folder = NULL; - const struct passwd *pwd = NULL; - - retval = pam_get_user(pamh, &user, NULL); - if (retval != PAM_SUCCESS || user == NULL) { - pam_syslog(pamh, LOG_ERR, "cannot determine username"); - retval = PAM_USER_UNKNOWN; - goto get_folder_cleanup; - } - - if (ctrl & PAM_NEW_MAIL_DIR) { - path = path_mail; - if (*path == '~') { /* support for $HOME delivery */ - pwd = pam_modutil_getpwnam(pamh, user); - if (pwd == NULL) { - pam_syslog(pamh, LOG_ERR, "user unknown"); - retval = PAM_USER_UNKNOWN; - goto get_folder_cleanup; - } - /* - * "~/xxx" and "~xxx" are treated as same - */ - if (!*++path || (*path == '/' && !*++path)) { - pam_syslog(pamh, LOG_ERR, - "badly formed mail path [%s]", path_mail); - retval = PAM_SERVICE_ERR; - goto get_folder_cleanup; - } - ctrl |= PAM_HOME_MAIL; - if (hashcount != 0) { - pam_syslog(pamh, LOG_ERR, - "cannot do hash= and home directory mail"); - } - } - } else { - path = DEFAULT_MAIL_DIRECTORY; - } - - /* put folder together */ - - hashcount = hashcount < strlen(user) ? hashcount : strlen(user); - - retval = PAM_BUF_ERR; - if (ctrl & PAM_HOME_MAIL) { - if (pwd == NULL) { - pwd = pam_modutil_getpwnam(pamh, user); - if (pwd == NULL) { - pam_syslog(pamh, LOG_ERR, "user unknown"); - retval = PAM_USER_UNKNOWN; - goto get_folder_cleanup; - } - } - if (asprintf(&folder, MAIL_FILE_FORMAT, pwd->pw_dir, "", path) < 0) - goto get_folder_cleanup; - } else { - int rc; - size_t i; - char *hash; - - if ((hash = malloc(2 * hashcount + 1)) == NULL) - goto get_folder_cleanup; - - for (i = 0; i < hashcount; i++) { - hash[2 * i] = '/'; - hash[2 * i + 1] = user[i]; - } - hash[2 * i] = '\0'; - - rc = asprintf(&folder, MAIL_FILE_FORMAT, path, hash, user); - _pam_overwrite(hash); - _pam_drop(hash); - if (rc < 0) - goto get_folder_cleanup; - } - D(("folder=[%s]", folder)); - retval = PAM_SUCCESS; - - /* tidy up */ - - get_folder_cleanup: - user = NULL; - path = NULL; - - *folder_p = folder; - folder = NULL; - - if (retval == PAM_BUF_ERR) - pam_syslog(pamh, LOG_CRIT, "out of memory for mail folder"); - - return retval; -} - -static int -get_mail_status(pam_handle_t *pamh, int ctrl, const char *folder) -{ - int type = 0; - struct stat mail_st; - - if (stat(folder, &mail_st) < 0) - return 0; - - if (S_ISDIR(mail_st.st_mode)) { /* Assume Maildir format */ - int i, save_errno; - char *dir; - struct dirent **namelist; - - if (asprintf(&dir, "%s/new", folder) < 0) { - pam_syslog(pamh, LOG_CRIT, "out of memory"); - goto get_mail_status_cleanup; - } - i = scandir(dir, &namelist, 0, alphasort); - save_errno = errno; - _pam_overwrite(dir); - _pam_drop(dir); - if (i < 0) { - type = 0; - namelist = NULL; - if (save_errno == ENOMEM) { - pam_syslog(pamh, LOG_CRIT, "out of memory"); - goto get_mail_status_cleanup; - } - } - type = (i > 2) ? HAVE_NEW_MAIL : 0; - while (--i >= 0) - _pam_drop(namelist[i]); - _pam_drop(namelist); - if (type == 0) { - if (asprintf(&dir, "%s/cur", folder) < 0) { - pam_syslog(pamh, LOG_CRIT, "out of memory"); - goto get_mail_status_cleanup; - } - i = scandir(dir, &namelist, 0, alphasort); - save_errno = errno; - _pam_overwrite(dir); - _pam_drop(dir); - if (i < 0) { - type = 0; - namelist = NULL; - if (save_errno == ENOMEM) { - pam_syslog(pamh, LOG_CRIT, "out of memory"); - goto get_mail_status_cleanup; - } - } - if (i > 2) - type = HAVE_OLD_MAIL; - else - type = (ctrl & PAM_EMPTY_TOO) ? HAVE_NO_MAIL : 0; - while (--i >= 0) - _pam_drop(namelist[i]); - _pam_drop(namelist); - } - } else { - if (mail_st.st_size > 0) { - if (mail_st.st_atime < mail_st.st_mtime) /* new */ - type = HAVE_NEW_MAIL; - else /* old */ - type = (ctrl & PAM_STANDARD_MAIL) ? HAVE_MAIL : HAVE_OLD_MAIL; - } else if (ctrl & PAM_EMPTY_TOO) { - type = HAVE_NO_MAIL; - } else { - type = 0; - } - } - - get_mail_status_cleanup: - memset(&mail_st, 0, sizeof(mail_st)); - D(("user has %d mail in %s folder", type, folder)); - return type; -} - -static int -report_mail(pam_handle_t *pamh, int ctrl, int type, const char *folder) -{ - int retval; - - if (!(ctrl & PAM_MAIL_SILENT) || - ((ctrl & PAM_QUIET_MAIL) && type == HAVE_NEW_MAIL)) - { - if (ctrl & PAM_STANDARD_MAIL) - switch (type) - { - case HAVE_NO_MAIL: - retval = pam_info (pamh, "%s", _("No mail.")); - break; - case HAVE_NEW_MAIL: - retval = pam_info (pamh, "%s", _("You have new mail.")); - break; - case HAVE_OLD_MAIL: - retval = pam_info (pamh, "%s", _("You have old mail.")); - break; - case HAVE_MAIL: - default: - retval = pam_info (pamh, "%s", _("You have mail.")); - break; - } - else - switch (type) - { - case HAVE_NO_MAIL: - retval = pam_info (pamh, _("You have no mail in folder %s."), - folder); - break; - case HAVE_NEW_MAIL: - retval = pam_info (pamh, _("You have new mail in folder %s."), - folder); - break; - case HAVE_OLD_MAIL: - retval = pam_info (pamh, _("You have old mail in folder %s."), - folder); - break; - case HAVE_MAIL: - default: - retval = pam_info (pamh, _("You have mail in folder %s."), - folder); - break; - } - } - else - { - D(("keeping quiet")); - retval = PAM_SUCCESS; - } - - D(("returning %s", pam_strerror(pamh, retval))); - return retval; -} - -static int _do_mail(pam_handle_t *, int, int, const char **, int); - -/* --- authentication functions --- */ - -PAM_EXTERN int -pam_sm_authenticate (pam_handle_t *pamh UNUSED, int flags UNUSED, - int argc UNUSED, const char **argv UNUSED) -{ - return PAM_IGNORE; -} - -/* Checking mail as part of authentication */ -PAM_EXTERN -int pam_sm_setcred(pam_handle_t *pamh, int flags, int argc, - const char **argv) -{ - if (!(flags & (PAM_ESTABLISH_CRED|PAM_DELETE_CRED))) - return PAM_IGNORE; - return _do_mail(pamh,flags,argc,argv,(flags & PAM_ESTABLISH_CRED)); -} - -/* --- session management functions --- */ - -PAM_EXTERN -int pam_sm_close_session(pam_handle_t *pamh,int flags,int argc - ,const char **argv) -{ - return _do_mail(pamh,flags,argc,argv,0); -} - -/* Checking mail as part of the session management */ -PAM_EXTERN -int pam_sm_open_session(pam_handle_t *pamh, int flags, int argc, - const char **argv) -{ - return _do_mail(pamh,flags,argc,argv,1); -} - - -/* --- The Beaf (Tm) --- */ - -static int _do_mail(pam_handle_t *pamh, int flags, int argc, - const char **argv, int est) -{ - int retval, ctrl, type; - size_t hashcount; - char *folder = NULL; - const char *path_mail = NULL; - - /* - * this module (un)sets the MAIL environment variable, and checks if - * the user has any new mail. - */ - - ctrl = _pam_parse(pamh, flags, argc, argv, &path_mail, &hashcount); - - /* which folder? */ - - retval = get_folder(pamh, ctrl, path_mail, &folder, hashcount); - if (retval != PAM_SUCCESS) { - D(("failed to find folder")); - return retval; - } - - /* set the MAIL variable? */ - - if (!(ctrl & PAM_NO_ENV) && est) { - char *tmp; - - if (asprintf(&tmp, MAIL_ENV_FORMAT, folder) < 0) { - pam_syslog(pamh, LOG_CRIT, - "no memory for " MAIL_ENV_NAME " variable"); - retval = PAM_BUF_ERR; - goto do_mail_cleanup; - } - D(("setting env: %s", tmp)); - retval = pam_putenv(pamh, tmp); - _pam_overwrite(tmp); - _pam_drop(tmp); - if (retval != PAM_SUCCESS) { - pam_syslog(pamh, LOG_CRIT, - "unable to set " MAIL_ENV_NAME " variable"); - retval = PAM_BUF_ERR; - goto do_mail_cleanup; - } - } else { - D(("not setting " MAIL_ENV_NAME " variable")); - } - - /* - * OK. we've got the mail folder... what about its status? - */ - - if ((est && !(ctrl & PAM_NO_LOGIN)) - || (!est && (ctrl & PAM_LOGOUT_TOO))) { - type = get_mail_status(pamh, ctrl, folder); - if (type != 0) { - retval = report_mail(pamh, ctrl, type, folder); - type = 0; - } - } - - /* Delete environment variable? */ - if ( ! est && ! (ctrl & PAM_NO_ENV) ) - (void) pam_putenv(pamh, MAIL_ENV_NAME); - - do_mail_cleanup: - _pam_overwrite(folder); - _pam_drop(folder); - - /* indicate success or failure */ - - return retval; -} - -#ifdef PAM_STATIC - -/* static module data */ - -struct pam_module _pam_mail_modstruct = { - "pam_mail", - pam_sm_authenticate, - pam_sm_setcred, - NULL, - pam_sm_open_session, - pam_sm_close_session, - NULL, -}; - -#endif - -/* end of module definition */ diff --git a/modules/pam_mail/tst-pam_mail b/modules/pam_mail/tst-pam_mail deleted file mode 100755 index 99fb7ed0..00000000 --- a/modules/pam_mail/tst-pam_mail +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/sh -../../tests/tst-dlopen .libs/pam_mail.so diff --git a/modules/pam_mkhomedir/.cvsignore b/modules/pam_mkhomedir/.cvsignore deleted file mode 100644 index bd6faa7e..00000000 --- a/modules/pam_mkhomedir/.cvsignore +++ /dev/null @@ -1,8 +0,0 @@ -*.la -*.lo -.deps -.libs -Makefile -Makefile.in -README -pam_mkhomedir.8 diff --git a/modules/pam_mkhomedir/Makefile.am b/modules/pam_mkhomedir/Makefile.am deleted file mode 100644 index 7ed3a9f0..00000000 --- a/modules/pam_mkhomedir/Makefile.am +++ /dev/null @@ -1,33 +0,0 @@ -# -# Copyright (c) 2005, 2006 Thorsten Kukuk <kukuk@suse.de> -# - -CLEANFILES = *~ - -EXTRA_DIST = README $(MANS) $(XMLS) tst-pam_mkhomedir - -man_MANS = pam_mkhomedir.8 - -XMLS = README.xml pam_mkhomedir.8.xml - -TESTS = tst-pam_mkhomedir - -securelibdir = $(SECUREDIR) -secureconfdir = $(SCONFIGDIR) - -AM_CFLAGS = -I$(top_srcdir)/libpam/include -I$(top_srcdir)/libpamc/include -AM_LDFLAGS = -no-undefined -avoid-version -module -if HAVE_VERSIONING - AM_LDFLAGS += -Wl,--version-script=$(srcdir)/../modules.map -endif - -securelib_LTLIBRARIES = pam_mkhomedir.la -pam_mkhomedir_la_SOURCES = pam_mkhomedir.c -pam_mkhomedir_la_LIBADD = -L$(top_builddir)/libpam -lpam - -if ENABLE_REGENERATE_MAN -noinst_DATA = README -README: pam_mkhomedir.8.xml --include $(top_srcdir)/Make.xml.rules -endif - diff --git a/modules/pam_mkhomedir/README.xml b/modules/pam_mkhomedir/README.xml deleted file mode 100644 index 978cbe77..00000000 --- a/modules/pam_mkhomedir/README.xml +++ /dev/null @@ -1,36 +0,0 @@ -<?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_mkhomedir.8.xml"> ---> -]> - -<article> - - <articleinfo> - - <title> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" - href="pam_mkhomedir.8.xml" xpointer='xpointer(//refnamediv[@id = "pam_mkhomedir-name"]/*)'/> - </title> - - </articleinfo> - - <section> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" - href="pam_mkhomedir.8.xml" xpointer='xpointer(//refsect1[@id = "pam_mkhomedir-description"]/*)'/> - </section> - - <section> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" - href="pam_mkhomedir.8.xml" xpointer='xpointer(//refsect1[@id = "pam_mkhomedir-examples"]/*)'/> - </section> - - <section> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" - href="pam_mkhomedir.8.xml" xpointer='xpointer(//refsect1[@id = "pam_mkhomedir-author"]/*)'/> - </section> - -</article> diff --git a/modules/pam_mkhomedir/pam_mkhomedir.8.xml b/modules/pam_mkhomedir/pam_mkhomedir.8.xml deleted file mode 100644 index 3c40de15..00000000 --- a/modules/pam_mkhomedir/pam_mkhomedir.8.xml +++ /dev/null @@ -1,203 +0,0 @@ -<?xml version="1.0" encoding="ISO-8859-1"?> -<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN" - "http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd"> - -<refentry id='pam_mkhomedir'> - - <refmeta> - <refentrytitle>pam_mkhomedir</refentrytitle> - <manvolnum>8</manvolnum> - <refmiscinfo class='setdesc'>Linux-PAM Manual</refmiscinfo> - </refmeta> - - <refnamediv id='pam_mkhomedir-name'> - <refname>pam_mkhomedir</refname> - <refpurpose> - PAM module to create users home directory - </refpurpose> - </refnamediv> - -<!-- body begins here --> - - <refsynopsisdiv> - <cmdsynopsis id="pam_mkhomedir-cmdsynopsis"> - <command>pam_mkhomedir.so</command> - <arg choice="opt"> - silent - </arg> - <arg choice="opt"> - umask=<replaceable>mode</replaceable> - </arg> - <arg choice="opt"> - skel=<replaceable>skeldir</replaceable> - </arg> - </cmdsynopsis> - </refsynopsisdiv> - - - <refsect1 id="pam_mkhomedir-description"> - <title>DESCRIPTION</title> - <para> - The pam_mkhomedir PAM module will create a users home directory - if it does not exist when the session begins. This allows users - to be present in central database (such as NIS, kerberos or LDAP) - without using a distributed file system or pre-creating a large - number of directories. The skeleton directory (usually - <filename>/etc/skel/</filename>) is used to copy default files - and also set's a umask for the creation. - </para> - <para> - The new users home directory will not be removed after logout - of the user. - </para> - </refsect1> - - <refsect1 id="pam_mkhomedir-options"> - <title>OPTIONS</title> - <variablelist> - - <varlistentry> - <term> - <option>silent</option> - </term> - <listitem> - <para> - Don't print informative messages. - </para> - </listitem> - </varlistentry> - - <varlistentry> - <term> - <option>umask=<replaceable>mask</replaceable></option> - </term> - <listitem> - <para> - The user file-creation mask is set to - <replaceable>mask</replaceable>. The default value of mask is - 0022. - </para> - </listitem> - </varlistentry> - - <varlistentry> - <term> - <option>skel=<replaceable>/path/to/skel/directory</replaceable></option> - </term> - <listitem> - <para> - Indicate an alternative <filename>skel</filename> directory - to override the default <filename>/etc/skel</filename>. - </para> - </listitem> - </varlistentry> - - </variablelist> - </refsect1> - - <refsect1 id="pam_mkhomedir-services"> - <title>MODULE SERVICES PROVIDED</title> - <para> - Only the <option>session</option> service is supported. - </para> - </refsect1> - - <refsect1 id="pam_mkhomedir-return_values"> - <title>RETURN VALUES</title> - <variablelist> - <varlistentry> - <term>PAM_BUF_ERR</term> - <listitem> - <para> - Memory buffer error. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term>PAM_CRED_INSUFFICIENT</term> - <listitem> - <para> - Insufficient credentials to access authentication data. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term>PAM_PERM_DENIED</term> - <listitem> - <para> - Not enough permissions to create the new directory - or read the skel directory. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term>PAM_USER_UNKNOWN</term> - <listitem> - <para> - User not known to the underlying authentication module. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term>PAM_SUCCESS</term> - <listitem> - <para> - Environment variables were set. - </para> - </listitem> - </varlistentry> - </variablelist> - </refsect1> - - <refsect1 id="pam_mkhomedir-files"> - <title>FILES</title> - <variablelist> - <varlistentry> - <term><filename>/etc/skel</filename></term> - <listitem> - <para>Default skel directory</para> - </listitem> - </varlistentry> - </variablelist> - </refsect1> - - <refsect1 id='pam_mkhomedir-examples'> - <title>EXAMPLES</title> - <para> - A sample /etc/pam.d/login file: - <programlisting> - auth requisite pam_securetty.so - auth sufficient pam_ldap.so - auth required pam_unix.so - auth required pam_nologin.so - account sufficient pam_ldap.so - account required pam_unix.so - password required pam_unix.so - session required pam_mkhomedir.so skel=/etc/skel/ umask=0022 - session required pam_unix.so - session optional pam_lastlog.so - session optional pam_mail.so standard - </programlisting> - </para> - </refsect1> - - - <refsect1 id="pam_mkhomedir-see_also"> - <title>SEE ALSO</title> - <para> - <citerefentry> - <refentrytitle>pam.d</refentrytitle><manvolnum>8</manvolnum> - </citerefentry>, - <citerefentry> - <refentrytitle>pam</refentrytitle><manvolnum>8</manvolnum> - </citerefentry>. - </para> - </refsect1> - - <refsect1 id="pam_mkhomedir-author"> - <title>AUTHOR</title> - <para> - pam_mkhomedir was written by Jason Gunthorpe <jgg@debian.org>. - </para> - </refsect1> -</refentry> diff --git a/modules/pam_mkhomedir/pam_mkhomedir.c b/modules/pam_mkhomedir/pam_mkhomedir.c deleted file mode 100644 index 44b092c1..00000000 --- a/modules/pam_mkhomedir/pam_mkhomedir.c +++ /dev/null @@ -1,511 +0,0 @@ -/* PAM Make Home Dir module - - This module will create a users home directory if it does not exist - when the session begins. This allows users to be present in central - database (such as nis, kerb or ldap) without using a distributed - file system or pre-creating a large number of directories. - - Here is a sample /etc/pam.d/login file for Debian GNU/Linux - 2.1: - - auth requisite pam_securetty.so - auth sufficient pam_ldap.so - auth required pam_unix.so - auth optional pam_group.so - auth optional pam_mail.so - account requisite pam_time.so - account sufficient pam_ldap.so - account required pam_unix.so - session required pam_mkhomedir.so skel=/etc/skel/ umask=0022 - session required pam_unix.so - session optional pam_lastlog.so - password required pam_unix.so - - Released under the GNU LGPL version 2 or later - Originally written by Jason Gunthorpe <jgg@debian.org> Feb 1999 - Structure taken from pam_lastlogin by Andrew Morgan - <morgan@parc.power.net> 1996 - */ - -#include "config.h" - -#include <stdarg.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <fcntl.h> -#include <unistd.h> -#include <pwd.h> -#include <errno.h> -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <dirent.h> -#include <syslog.h> - -/* - * here, we make a definition for the externally accessible function - * in this file (this definition is required for static a module - * but strongly encouraged generally) it is used to instruct the - * modules include file to define the function prototypes. - */ - -#define PAM_SM_SESSION - -#include <security/pam_modules.h> -#include <security/_pam_macros.h> -#include <security/pam_modutil.h> -#include <security/pam_ext.h> - - -/* argument parsing */ -#define MKHOMEDIR_DEBUG 020 /* be verbose about things */ -#define MKHOMEDIR_QUIET 040 /* keep quiet about things */ - -static unsigned int UMask = 0022; -static char SkelDir[BUFSIZ] = "/etc/skel"; /* THIS MODULE IS NOT THREAD SAFE */ - -static int -_pam_parse (const pam_handle_t *pamh, int flags, int argc, const char **argv) -{ - int ctrl = 0; - - /* does the appliction require quiet? */ - if ((flags & PAM_SILENT) == PAM_SILENT) - ctrl |= MKHOMEDIR_QUIET; - - /* step through arguments */ - for (; argc-- > 0; ++argv) - { - if (!strcmp(*argv, "silent")) { - ctrl |= MKHOMEDIR_QUIET; - } else if (!strcmp(*argv, "debug")) { - ctrl |= MKHOMEDIR_DEBUG; - } else if (!strncmp(*argv,"umask=",6)) { - UMask = strtol(*argv+6,0,0); - } else if (!strncmp(*argv,"skel=",5)) { - strncpy(SkelDir,*argv+5,sizeof(SkelDir)); - SkelDir[sizeof(SkelDir)-1] = '\0'; - } else { - pam_syslog(pamh, LOG_ERR, "unknown option: %s", *argv); - } - } - - D(("ctrl = %o", ctrl)); - return ctrl; -} - -static int -rec_mkdir (const char *dir, mode_t mode) -{ - char *cp; - char *parent = strdup (dir); - - if (parent == NULL) - return 1; - - cp = strrchr (parent, '/'); - - if (cp != NULL && cp != parent) - { - struct stat st; - - *cp++ = '\0'; - if (stat (parent, &st) == -1 && errno == ENOENT) - if (rec_mkdir (parent, mode) != 0) - { - free (parent); - return 1; - } - } - - free (parent); - - if (mkdir (dir, mode) != 0 && errno != EEXIST) - return 1; - - return 0; -} - -/* Do the actual work of creating a home dir */ -static int -create_homedir (pam_handle_t * pamh, int ctrl, - const struct passwd *pwd, - const char *source, const char *dest) -{ - char remark[BUFSIZ]; - DIR *D; - struct dirent *Dir; - int retval = PAM_AUTH_ERR; - - /* Mention what is happening, if the notification fails that is OK */ - if ((ctrl & MKHOMEDIR_QUIET) != MKHOMEDIR_QUIET) - pam_info(pamh, _("Creating directory '%s'."), dest); - - /* Create the new directory */ - if (rec_mkdir (dest,0755) != 0) - { - pam_error(pamh, _("Unable to create directory %s: %m"), dest); - pam_syslog(pamh, LOG_ERR, "unable to create directory %s: %m", dest); - return PAM_PERM_DENIED; - } - - /* See if we need to copy the skel dir over. */ - if ((source == NULL) || (strlen(source) == 0)) - { - retval = PAM_SUCCESS; - goto go_out; - } - - /* Scan the directory */ - D = opendir (source); - if (D == 0) - { - pam_syslog(pamh, LOG_DEBUG, "unable to read directory %s: %m", source); - retval = PAM_PERM_DENIED; - goto go_out; - } - - for (Dir = readdir(D); Dir != 0; Dir = readdir(D)) - { - int SrcFd; - int DestFd; - int Res; - struct stat St; -#ifndef PATH_MAX - char *newsource = NULL, *newdest = NULL; - /* track length of buffers */ - int nslen = 0, ndlen = 0; - int slen = strlen(source), dlen = strlen(dest); -#else - char newsource[PATH_MAX], newdest[PATH_MAX]; -#endif - - /* Skip some files.. */ - if (strcmp(Dir->d_name,".") == 0 || - strcmp(Dir->d_name,"..") == 0) - continue; - - /* Determine what kind of file it is. */ -#ifndef PATH_MAX - nslen = slen + strlen(Dir->d_name) + 2; - - if (nslen <= 0) - { - retval = PAM_BUF_ERR; - goto go_out; - } - - if ((newsource = malloc (nslen)) == NULL) - { - retval = PAM_BUF_ERR; - goto go_out; - } - - sprintf(newsource, "%s/%s", source, Dir->d_name); -#else - snprintf(newsource,sizeof(newsource),"%s/%s",source,Dir->d_name); -#endif - - if (lstat(newsource,&St) != 0) -#ifndef PATH_MAX - { - free(newsource); - newsource = NULL; - continue; - } -#else - continue; -#endif - - - /* We'll need the new file's name. */ -#ifndef PATH_MAX - ndlen = dlen + strlen(Dir->d_name)+2; - - if (ndlen <= 0) - { - retval = PAM_BUF_ERR; - goto go_out; - } - - if ((newdest = malloc(ndlen)) == NULL) - { - free (newsource); - retval = PAM_BUF_ERR; - goto go_out; - } - - sprintf (newdest, "%s/%s", dest, Dir->d_name); -#else - snprintf (newdest,sizeof (newdest),"%s/%s",dest,Dir->d_name); -#endif - - /* If it's a directory, recurse. */ - if (S_ISDIR(St.st_mode)) - { - retval = create_homedir (pamh, ctrl, pwd, newsource, newdest); - -#ifndef PATH_MAX - free(newsource); newsource = NULL; - free(newdest); newdest = NULL; -#endif - - if (retval != PAM_SUCCESS) - { - closedir(D); - goto go_out; - } - continue; - } - - /* If it's a symlink, create a new link. */ - if (S_ISLNK(St.st_mode)) - { - int pointedlen = 0; -#ifndef PATH_MAX - char *pointed = NULL; - { - int size = 100; - - while (1) { - pointed = (char *) malloc(size); - if ( ! pointed ) { - free(newsource); - free(newdest); - return PAM_BUF_ERR; - } - pointedlen = readlink (newsource, pointed, size); - if ( pointedlen < 0 ) break; - if ( pointedlen < size ) break; - free (pointed); - size *= 2; - } - } - if ( pointedlen < 0 ) - free(pointed); - else - pointed[pointedlen] = 0; -#else - char pointed[PATH_MAX]; - memset(pointed, 0, sizeof(pointed)); - - pointedlen = readlink(newsource, pointed, sizeof(pointed) - 1); -#endif - - if ( pointedlen >= 0 ) { - if(symlink(pointed, newdest) == 0) - { - if (lchown(newdest,pwd->pw_uid,pwd->pw_gid) != 0) - { - pam_syslog(pamh, LOG_DEBUG, - "unable to change perms on link %s: %m", newdest); - closedir(D); -#ifndef PATH_MAX - free(pointed); - free(newsource); - free(newdest); -#endif - return PAM_PERM_DENIED; - } - } -#ifndef PATH_MAX - free(pointed); -#endif - } -#ifndef PATH_MAX - free(newsource); newsource = NULL; - free(newdest); newdest = NULL; -#endif - continue; - } - - /* If it's not a regular file, it's probably not a good idea to create - * the new device node, FIFO, or whatever it is. */ - if (!S_ISREG(St.st_mode)) - { -#ifndef PATH_MAX - free(newsource); newsource = NULL; - free(newdest); newdest = NULL; -#endif - continue; - } - - /* Open the source file */ - if ((SrcFd = open(newsource,O_RDONLY)) < 0 || fstat(SrcFd,&St) != 0) - { - pam_syslog(pamh, LOG_DEBUG, - "unable to open src file %s: %m", newsource); - closedir(D); - -#ifndef PATH_MAX - free(newsource); newsource = NULL; - free(newdest); newdest = NULL; -#endif - - return PAM_PERM_DENIED; - } - if (stat(newsource,&St) != 0) - { - pam_syslog(pamh, LOG_DEBUG, "unable to stat src file %s: %m", - newsource); - close(SrcFd); - closedir(D); - -#ifndef PATH_MAX - free(newsource); newsource = NULL; - free(newdest); newdest = NULL; -#endif - - return PAM_PERM_DENIED; - } - - /* Open the dest file */ - if ((DestFd = open(newdest,O_WRONLY | O_TRUNC | O_CREAT,0600)) < 0) - { - pam_syslog(pamh, LOG_DEBUG, - "unable to open dest file %s: %m", newdest); - close(SrcFd); - closedir(D); - -#ifndef PATH_MAX - free(newsource); newsource = NULL; - free(newdest); newdest = NULL; -#endif - return PAM_PERM_DENIED; - } - - /* Set the proper ownership and permissions for the module. We make - the file a+w and then mask it with the set mask. This preseves - execute bits */ - if (fchmod(DestFd,(St.st_mode | 0222) & (~UMask)) != 0 || - fchown(DestFd,pwd->pw_uid,pwd->pw_gid) != 0) - { - pam_syslog(pamh, LOG_DEBUG, - "unable to change perms on copy %s: %m", newdest); - close(SrcFd); - close(DestFd); - closedir(D); - -#ifndef PATH_MAX - free(newsource); newsource = NULL; - free(newdest); newdest = NULL; -#endif - - return PAM_PERM_DENIED; - } - - /* Copy the file */ - do - { - Res = pam_modutil_read(SrcFd,remark,sizeof(remark)); - - if (Res == 0) - continue; - - if (Res > 0) { - if (pam_modutil_write(DestFd,remark,Res) == Res) - continue; - } - - /* If we get here, pam_modutil_read returned a -1 or - pam_modutil_write returned something unexpected. */ - pam_syslog(pamh, LOG_DEBUG, "unable to perform IO: %m"); - close(SrcFd); - close(DestFd); - closedir(D); - -#ifndef PATH_MAX - free(newsource); newsource = NULL; - free(newdest); newdest = NULL; -#endif - - return PAM_PERM_DENIED; - } - while (Res != 0); - close(SrcFd); - close(DestFd); - -#ifndef PATH_MAX - free(newsource); newsource = NULL; - free(newdest); newdest = NULL; -#endif - - } - closedir(D); - - retval = PAM_SUCCESS; - - go_out: - - if (chmod(dest,0777 & (~UMask)) != 0 || - chown(dest,pwd->pw_uid,pwd->pw_gid) != 0) - { - pam_syslog(pamh, LOG_DEBUG, - "unable to change perms on directory %s: %m", dest); - return PAM_PERM_DENIED; - } - - return retval; -} - -/* --- authentication management functions (only) --- */ - -PAM_EXTERN int -pam_sm_open_session (pam_handle_t *pamh, int flags, int argc, - const char **argv) -{ - int retval, ctrl; - const void *user; - const struct passwd *pwd; - struct stat St; - - /* Parse the flag values */ - ctrl = _pam_parse(pamh, flags, argc, argv); - - /* Determine the user name so we can get the home directory */ - retval = pam_get_item(pamh, PAM_USER, &user); - if (retval != PAM_SUCCESS || user == NULL || *(const char *)user == '\0') - { - pam_syslog(pamh, LOG_NOTICE, "user unknown"); - return PAM_USER_UNKNOWN; - } - - /* Get the password entry */ - pwd = pam_modutil_getpwnam (pamh, user); - if (pwd == NULL) - { - D(("couldn't identify user %s", user)); - return PAM_CRED_INSUFFICIENT; - } - - /* Stat the home directory, if something exists then we assume it is - correct and return a success*/ - if (stat(pwd->pw_dir,&St) == 0) - return PAM_SUCCESS; - - return create_homedir(pamh,ctrl,pwd,SkelDir,pwd->pw_dir); -} - -/* Ignore */ -PAM_EXTERN -int pam_sm_close_session (pam_handle_t * pamh UNUSED, int flags UNUSED, - int argc UNUSED, const char **argv UNUSED) -{ - return PAM_SUCCESS; -} - -#ifdef PAM_STATIC - -/* static module data */ -struct pam_module _pam_mkhomedir_modstruct = -{ - "pam_mkhomedir", - NULL, - NULL, - NULL, - pam_sm_open_session, - pam_sm_close_session, - NULL, -}; - -#endif diff --git a/modules/pam_mkhomedir/tst-pam_mkhomedir b/modules/pam_mkhomedir/tst-pam_mkhomedir deleted file mode 100755 index 5447883f..00000000 --- a/modules/pam_mkhomedir/tst-pam_mkhomedir +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/sh -../../tests/tst-dlopen .libs/pam_mkhomedir.so diff --git a/modules/pam_motd/.cvsignore b/modules/pam_motd/.cvsignore deleted file mode 100644 index f36d06fa..00000000 --- a/modules/pam_motd/.cvsignore +++ /dev/null @@ -1,8 +0,0 @@ -*.la -*.lo -.deps -.libs -Makefile -Makefile.in -README -pam_motd.8 diff --git a/modules/pam_motd/Makefile.am b/modules/pam_motd/Makefile.am deleted file mode 100644 index 872e5d37..00000000 --- a/modules/pam_motd/Makefile.am +++ /dev/null @@ -1,31 +0,0 @@ -# -# Copyright (c) 2005, 2006 Thorsten Kukuk <kukuk@suse.de> -# - -CLEANFILES = *~ - -EXTRA_DIST = README $(MANS) $(XMLS) tst-pam_motd - -man_MANS = pam_motd.8 -XMLS = README.xml pam_motd.8.xml - -TESTS = tst-pam_motd - -securelibdir = $(SECUREDIR) -secureconfdir = $(SCONFIGDIR) - -AM_CFLAGS = -I$(top_srcdir)/libpam/include -I$(top_srcdir)/libpamc/include -AM_LDFLAGS = -no-undefined -avoid-version -module -if HAVE_VERSIONING - AM_LDFLAGS += -Wl,--version-script=$(srcdir)/../modules.map -endif - -securelib_LTLIBRARIES = pam_motd.la -pam_motd_la_LIBADD = -L$(top_builddir)/libpam -lpam - -if ENABLE_REGENERATE_MAN -noinst_DATA = README -README: pam_motd.8.xml --include $(top_srcdir)/Make.xml.rules -endif - diff --git a/modules/pam_motd/README.xml b/modules/pam_motd/README.xml deleted file mode 100644 index 779e4d17..00000000 --- a/modules/pam_motd/README.xml +++ /dev/null @@ -1,41 +0,0 @@ -<?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_motd.8.xml"> ---> -]> - -<article> - - <articleinfo> - - <title> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" - href="pam_motd.8.xml" xpointer='xpointer(//refnamediv[@id = "pam_motd-name"]/*)'/> - </title> - - </articleinfo> - - <section> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" - href="pam_motd.8.xml" xpointer='xpointer(//refsect1[@id = "pam_motd-description"]/*)'/> - </section> - - <section> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" - href="pam_motd.8.xml" xpointer='xpointer(//refsect1[@id = "pam_motd-options"]/*)'/> - </section> - - <section> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" - href="pam_motd.8.xml" xpointer='xpointer(//refsect1[@id = "pam_motd-examples"]/*)'/> - </section> - - <section> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" - href="pam_motd.8.xml" xpointer='xpointer(//refsect1[@id = "pam_motd-author"]/*)'/> - </section> - -</article> diff --git a/modules/pam_motd/pam_motd.8.xml b/modules/pam_motd/pam_motd.8.xml deleted file mode 100644 index 7bd6798c..00000000 --- a/modules/pam_motd/pam_motd.8.xml +++ /dev/null @@ -1,114 +0,0 @@ -<?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_motd"> - - <refmeta> - <refentrytitle>pam_motd</refentrytitle> - <manvolnum>8</manvolnum> - <refmiscinfo class="sectdesc">Linux-PAM Manual</refmiscinfo> - </refmeta> - - <refnamediv id="pam_motd-name"> - <refname>pam_motd</refname> - <refpurpose>Display the motd file</refpurpose> - </refnamediv> - - <refsynopsisdiv> - <cmdsynopsis id="pam_motd-cmdsynopsis"> - <command>pam_motd.so</command> - <arg choice="opt"> - motd=<replaceable>/path/filename</replaceable> - </arg> - </cmdsynopsis> - </refsynopsisdiv> - - <refsect1 id="pam_motd-description"> - - <title>DESCRIPTION</title> - - <para> - pam_motd is a PAM module that can be used to display - arbitrary motd (message of the day) files after a succesful - login. By default the <filename>/etc/motd</filename> file is - shown. The message size is limited to 64KB. - </para> - - </refsect1> - - <refsect1 id="pam_motd-options"> - - <title>OPTIONS</title> - <variablelist> - <varlistentry> - <term> - <option>motd=<replaceable>/path/filename</replaceable></option> - </term> - <listitem> - <para> - The <filename>/path/filename</filename> file is displayed - as message of the day. - </para> - </listitem> - </varlistentry> - </variablelist> - </refsect1> - - <refsect1 id="pam_motd-services"> - <title>MODULE SERVICES PROVIDED</title> - <para> - Only the <option>session</option> service is supported. - </para> - </refsect1> - - <refsect1 id='pam_motd-return_values'> - <title>RETURN VALUES</title> - <variablelist> - <varlistentry> - <term>PAM_IGNORE</term> - <listitem> - <para> - This is the only return value of this module. - </para> - </listitem> - </varlistentry> - </variablelist> - </refsect1> - - <refsect1 id='pam_motd-examples'> - <title>EXAMPLES</title> - <para> - The suggested usage for <filename>/etc/pam.d/login</filename> is: - <programlisting> -session optional pam_motd.so motd=/etc/motd - </programlisting> - </para> - </refsect1> - - <refsect1 id='pam_motd-see_also'> - <title>SEE ALSO</title> - <para> - <citerefentry> - <refentrytitle>motd</refentrytitle><manvolnum>5</manvolnum> - </citerefentry>, - <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_motd-author'> - <title>AUTHOR</title> - <para> - pam_motd was written by Ben Collins <bcollins@debian.org>. - </para> - </refsect1> - -</refentry> diff --git a/modules/pam_motd/pam_motd.c b/modules/pam_motd/pam_motd.c deleted file mode 100644 index ff9b1690..00000000 --- a/modules/pam_motd/pam_motd.c +++ /dev/null @@ -1,130 +0,0 @@ -/* pam_motd module */ - -/* - * Modified for pam_motd by Ben Collins <bcollins@debian.org> - * - * Based off of: - * $Id$ - * - * Written by Michael K. Johnson <johnsonm@redhat.com> 1996/10/24 - * - */ - -#include "config.h" - -#include <stdio.h> -#include <string.h> -#include <stdlib.h> -#include <unistd.h> -#include <fcntl.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <pwd.h> -#include <syslog.h> - -#include <security/_pam_macros.h> -#include <security/pam_ext.h> -/* - * here, we make a definition for the externally accessible function - * in this file (this definition is required for static a module - * but strongly encouraged generally) it is used to instruct the - * modules include file to define the function prototypes. - */ - -#define PAM_SM_SESSION -#define DEFAULT_MOTD "/etc/motd" - -#include <security/pam_modules.h> -#include <security/pam_modutil.h> - -/* --- session management functions (only) --- */ - -PAM_EXTERN int -pam_sm_close_session (pam_handle_t *pamh UNUSED, int flags UNUSED, - int argc UNUSED, const char **argv UNUSED) -{ - return PAM_IGNORE; -} - -static char default_motd[] = DEFAULT_MOTD; - -PAM_EXTERN -int pam_sm_open_session(pam_handle_t *pamh, int flags, - int argc, const char **argv) -{ - int retval = PAM_IGNORE; - int fd; - const char *motd_path = NULL; - char *mtmp = NULL; - - if (flags & PAM_SILENT) { - return retval; - } - - for (; argc-- > 0; ++argv) { - if (!strncmp(*argv,"motd=",5)) { - - motd_path = 5 + *argv; - if (*motd_path != '\0') { - D(("set motd path: %s", motd_path)); - } else { - motd_path = NULL; - pam_syslog(pamh, LOG_ERR, - "motd= specification missing argument - ignored"); - } - } - else - pam_syslog(pamh, LOG_ERR, "unknown option: %s", *argv); - } - - if (motd_path == NULL) - motd_path = default_motd; - - while ((fd = open(motd_path, O_RDONLY, 0)) >= 0) { - struct stat st; - - /* fill in message buffer with contents of motd */ - if ((fstat(fd, &st) < 0) || !st.st_size || st.st_size > 0x10000) - break; - - if (!(mtmp = malloc(st.st_size+1))) - break; - - if (pam_modutil_read(fd, mtmp, st.st_size) != st.st_size) - break; - - if (mtmp[st.st_size-1] == '\n') - mtmp[st.st_size-1] = '\0'; - else - mtmp[st.st_size] = '\0'; - - pam_info (pamh, "%s", mtmp); - break; - } - - _pam_drop (mtmp); - - if (fd >= 0) - close(fd); - - return retval; -} - - -#ifdef PAM_STATIC - -/* static module data */ - -struct pam_module _pam_motd_modstruct = { - "pam_motd", - NULL, - NULL, - NULL, - pam_sm_open_session, - pam_sm_close_session, - NULL, -}; - -#endif - -/* end of module definition */ diff --git a/modules/pam_motd/tst-pam_motd b/modules/pam_motd/tst-pam_motd deleted file mode 100755 index 155e2304..00000000 --- a/modules/pam_motd/tst-pam_motd +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/sh -../../tests/tst-dlopen .libs/pam_motd.so diff --git a/modules/pam_namespace/.cvsignore b/modules/pam_namespace/.cvsignore deleted file mode 100644 index 59a9578c..00000000 --- a/modules/pam_namespace/.cvsignore +++ /dev/null @@ -1,9 +0,0 @@ -*.la -*.lo -.deps -.libs -Makefile -Makefile.in -README -namespace.conf.5 -pam_namespace.8 diff --git a/modules/pam_namespace/Makefile.am b/modules/pam_namespace/Makefile.am deleted file mode 100644 index 05d47cf3..00000000 --- a/modules/pam_namespace/Makefile.am +++ /dev/null @@ -1,42 +0,0 @@ -# -# Copyright (c) 2006 Red Hat, Inc. -# - -CLEANFILES = *~ -MAN5 = namespace.conf.5 -MAN8 = pam_namespace.8 - -XMLS = README.xml namespace.conf.5.xml pam_namespace.8.xml - -if ENABLE_REGENERATE_MAN -noinst_DATA = README --include $(top_srcdir)/Make.xml.rules -endif - -EXTRA_DIST = README namespace.conf namespace.init $(MAN5) $(MAN8) $(XMLS) tst-pam_namespace - -noinst_HEADERS = md5.h pam_namespace.h argv_parse.h - -securelibdir = $(SECUREDIR) -secureconfdir = $(SCONFIGDIR) -namespaceddir = $(SCONFIGDIR)/namespace.d - -AM_CFLAGS = -I$(top_srcdir)/libpam/include -I$(top_srcdir)/libpamc/include \ - -DSECURECONF_DIR=\"$(SCONFIGDIR)/\" -AM_LDFLAGS = -no-undefined -avoid-version -module -if HAVE_VERSIONING - AM_LDFLAGS += -Wl,--version-script=$(srcdir)/../modules.map -endif - -if HAVE_UNSHARE -securelib_LTLIBRARIES = pam_namespace.la -pam_namespace_la_SOURCES = pam_namespace.c md5.c argv_parse.c -pam_namespace_la_LIBADD = -L$(top_builddir)/libpam -lpam @LIBSELINUX@ - -secureconf_DATA = namespace.conf -secureconf_SCRIPTS = namespace.init -namespaced_DATA = - -TESTS = tst-pam_namespace -man_MANS = $(MAN5) $(MAN8) -endif diff --git a/modules/pam_namespace/README.xml b/modules/pam_namespace/README.xml deleted file mode 100644 index 4ef99c9f..00000000 --- a/modules/pam_namespace/README.xml +++ /dev/null @@ -1,44 +0,0 @@ -<?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 pamns SYSTEM "pam_namespace.8.xml"> ---> -<!-- -<!ENTITY nsconf SYSTEM "namespace.conf.5.xml"> ---> -]> - -<article> - - <articleinfo> - - <title> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" - href="pam_namespace.8.xml" xpointer='xpointer(//refnamediv[@id = "pam_namespace-name"]/*)'/> - </title> - - </articleinfo> - - <section> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" - href="pam_namespace.8.xml" xpointer='xpointer(//refsect1[@id = "pam_namespace-description"]/*)'/> - </section> - - <section> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" - href="pam_namespace.8.xml" xpointer='xpointer(//refsect1[@id = "pam_namespace-options"]/*)'/> - </section> - - <section> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" - href="namespace.conf.5.xml" xpointer='xpointer(//refsect1[@id = "namespace.conf-description"]/*)'/> - </section> - - <section> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" - href="namespace.conf.5.xml" xpointer='xpointer(//refsect1[@id = "namespace.conf-examples"]/*)'/> - </section> - -</article> diff --git a/modules/pam_namespace/argv_parse.c b/modules/pam_namespace/argv_parse.c deleted file mode 100644 index acc76d74..00000000 --- a/modules/pam_namespace/argv_parse.c +++ /dev/null @@ -1,165 +0,0 @@ -/* - * argv_parse.c --- utility function for parsing a string into a - * argc, argv array. - * - * This file defines a function argv_parse() which parsing a - * passed-in string, handling double quotes and backslashes, and - * creates an allocated argv vector which can be freed using the - * argv_free() function. - * - * See argv_parse.h for the formal definition of the functions. - * - * Copyright 1999 by Theodore Ts'o. - * - * Permission to use, copy, modify, and distribute this software for - * any purpose with or without fee is hereby granted, provided that - * the above copyright notice and this permission notice appear in all - * copies. THE SOFTWARE IS PROVIDED "AS IS" AND THEODORE TS'O (THE - * AUTHOR) DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, - * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, - * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER - * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR - * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. (Isn't - * it sick that the U.S. culture of lawsuit-happy lawyers requires - * this kind of disclaimer?) - * - * Version 1.1, modified 2/27/1999 - */ - -#include <stdlib.h> -#include <ctype.h> -#include <string.h> -#include "argv_parse.h" - -#define STATE_WHITESPACE 1 -#define STATE_TOKEN 2 -#define STATE_QUOTED 3 - -/* - * Returns 0 on success, -1 on failure. - */ -int argv_parse(const char *in_buf, int *ret_argc, char ***ret_argv) -{ - int argc = 0, max_argc = 0; - char **argv, **new_argv, *buf, ch; - const char *cp = 0; - char *outcp = 0; - int state = STATE_WHITESPACE; - - buf = malloc(strlen(in_buf)+1); - if (!buf) - return -1; - - max_argc = 0; argc = 0; argv = 0; - outcp = buf; - for (cp = in_buf; (ch = *cp); cp++) { - if (state == STATE_WHITESPACE) { - if (isspace((int) ch)) - continue; - /* Not whitespace, so start a new token */ - state = STATE_TOKEN; - if (argc >= max_argc) { - max_argc += 3; - new_argv = realloc(argv, - (max_argc+1)*sizeof(char *)); - if (!new_argv) { - if (argv) free(argv); - free(buf); - return -1; - } - argv = new_argv; - } - argv[argc++] = outcp; - } - if (state == STATE_QUOTED) { - if (ch == '"') - state = STATE_TOKEN; - else - *outcp++ = ch; - continue; - } - /* Must be processing characters in a word */ - if (isspace((int) ch)) { - /* - * Terminate the current word and start - * looking for the beginning of the next word. - */ - *outcp++ = 0; - state = STATE_WHITESPACE; - continue; - } - if (ch == '"') { - state = STATE_QUOTED; - continue; - } - if (ch == '\\') { - ch = *++cp; - switch (ch) { - case '\0': - ch = '\\'; cp--; break; - case 'n': - ch = '\n'; break; - case 't': - ch = '\t'; break; - case 'b': - ch = '\b'; break; - } - } - *outcp++ = ch; - } - if (state != STATE_WHITESPACE) - *outcp++ = '\0'; - if (argv == 0) { - argv = malloc(sizeof(char *)); - free(buf); - } - argv[argc] = 0; - if (ret_argc) - *ret_argc = argc; - if (ret_argv) - *ret_argv = argv; - return 0; -} - -void argv_free(char **argv) -{ - if (*argv) - free(*argv); - free(argv); -} - -#ifdef DEBUG_ARGV_PARSE -/* - * For debugging - */ - -#include <stdio.h> - -int main(int argc, char **argv) -{ - int ac, ret; - char **av, **cpp; - char buf[256]; - - while (!feof(stdin)) { - if (fgets(buf, sizeof(buf), stdin) == NULL) - break; - ret = argv_parse(buf, &ac, &av); - if (ret != 0) { - printf("Argv_parse returned %d!\n", ret); - continue; - } - printf("Argv_parse returned %d arguments...\n", ac); - for (cpp = av; *cpp; cpp++) { - if (cpp != av) - printf(", "); - printf("'%s'", *cpp); - } - printf("\n"); - argv_free(av); - } - exit(0); -} -#endif diff --git a/modules/pam_namespace/argv_parse.h b/modules/pam_namespace/argv_parse.h deleted file mode 100644 index c7878fc1..00000000 --- a/modules/pam_namespace/argv_parse.h +++ /dev/null @@ -1,43 +0,0 @@ -/* - * argv_parse.h --- header file for the argv parser. - * - * This file defines the interface for the functions argv_parse() and - * argv_free(). - * - *********************************************************************** - * int argv_parse(char *in_buf, int *ret_argc, char ***ret_argv) - * - * This function takes as its first argument a string which it will - * parse into an argv argument vector, with each white-space separated - * word placed into its own slot in the argv. This function handles - * double quotes and backslashes so that the parsed words can contain - * special characters. The count of the number words found in the - * parsed string, as well as the argument vector, are returned into - * ret_argc and ret_argv, respectively. - *********************************************************************** - * extern void argv_free(char **argv); - * - * This function frees the argument vector created by argv_parse(). - *********************************************************************** - * - * Copyright 1999 by Theodore Ts'o. - * - * Permission to use, copy, modify, and distribute this software for - * any purpose with or without fee is hereby granted, provided that - * the above copyright notice and this permission notice appear in all - * copies. THE SOFTWARE IS PROVIDED "AS IS" AND THEODORE TS'O (THE - * AUTHOR) DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, - * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, - * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER - * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR - * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. (Isn't - * it sick that the U.S. culture of lawsuit-happy lawyers requires - * this kind of disclaimer?) - * - * Version 1.1, modified 2/27/1999 - */ - -extern int argv_parse(const char *in_buf, int *ret_argc, char ***ret_argv); -extern void argv_free(char **argv); diff --git a/modules/pam_namespace/md5.c b/modules/pam_namespace/md5.c deleted file mode 100644 index 3094a130..00000000 --- a/modules/pam_namespace/md5.c +++ /dev/null @@ -1,260 +0,0 @@ -/* - * $Id$ - * - * This code implements the MD5 message-digest algorithm. - * The algorithm is due to Ron Rivest. This code was - * written by Colin Plumb in 1993, no copyright is claimed. - * This code is in the public domain; do with it what you wish. - * - * Equivalent code is available from RSA Data Security, Inc. - * This code has been tested against that, and is equivalent, - * except that you don't need to include two pages of legalese - * with every copy. - * - * To compute the message digest of a chunk of bytes, declare an - * MD5Context structure, pass it to MD5Init, call MD5Update as - * needed on buffers full of bytes, and then call MD5Final, which - * will fill a supplied 16-byte array with the digest. - * - */ - -#include <string.h> -#include "md5.h" - -#define MD5Name(x) x - -#if defined(__i386) || defined(__i386__) || defined(__x86_64) || defined(__x86_64__) -#define byteReverse(buf, len) /* Nothing */ -#else -static void byteReverse(unsigned char *buf, unsigned longs); - -/* - * Note: this code is harmless on little-endian machines. - */ -static void byteReverse(unsigned char *buf, unsigned longs) -{ - uint32 t; - do { - t = (uint32) ((unsigned) buf[3] << 8 | buf[2]) << 16 | - ((unsigned) buf[1] << 8 | buf[0]); - *(uint32 *) buf = t; - buf += 4; - } while (--longs); -} -#endif - -/* - * Start MD5 accumulation. Set bit count to 0 and buffer to mysterious - * initialization constants. - */ -void MD5Name(MD5Init)(struct MD5Context *ctx) -{ - ctx->buf[0] = 0x67452301U; - ctx->buf[1] = 0xefcdab89U; - ctx->buf[2] = 0x98badcfeU; - ctx->buf[3] = 0x10325476U; - - ctx->bits[0] = 0; - ctx->bits[1] = 0; -} - -/* - * Update context to reflect the concatenation of another buffer full - * of bytes. - */ -void MD5Name(MD5Update)(struct MD5Context *ctx, unsigned const char *buf, unsigned len) -{ - uint32 t; - - /* Update bitcount */ - - t = ctx->bits[0]; - if ((ctx->bits[0] = t + ((uint32) len << 3)) < t) - ctx->bits[1]++; /* Carry from low to high */ - ctx->bits[1] += len >> 29; - - t = (t >> 3) & 0x3f; /* Bytes already in shsInfo->data */ - - /* Handle any leading odd-sized chunks */ - - if (t) { - unsigned char *p = (unsigned char *) ctx->in + t; - - t = 64 - t; - if (len < t) { - memcpy(p, buf, len); - return; - } - memcpy(p, buf, t); - byteReverse(ctx->in, 16); - MD5Name(MD5Transform)(ctx->buf, (uint32 *) ctx->in); - buf += t; - len -= t; - } - /* Process data in 64-byte chunks */ - - while (len >= 64) { - memcpy(ctx->in, buf, 64); - byteReverse(ctx->in, 16); - MD5Name(MD5Transform)(ctx->buf, (uint32 *) ctx->in); - buf += 64; - len -= 64; - } - - /* Handle any remaining bytes of data. */ - - memcpy(ctx->in, buf, len); -} - -/* - * Final wrapup - pad to 64-byte boundary with the bit pattern - * 1 0* (64-bit count of bits processed, MSB-first) - */ -void MD5Name(MD5Final)(unsigned char digest[16], struct MD5Context *ctx) -{ - unsigned count; - unsigned char *p; - - /* Compute number of bytes mod 64 */ - count = (ctx->bits[0] >> 3) & 0x3F; - - /* Set the first char of padding to 0x80. This is safe since there is - always at least one byte free */ - p = ctx->in + count; - *p++ = 0x80; - - /* Bytes of padding needed to make 64 bytes */ - count = 64 - 1 - count; - - /* Pad out to 56 mod 64 */ - if (count < 8) { - /* Two lots of padding: Pad the first block to 64 bytes */ - memset(p, 0, count); - byteReverse(ctx->in, 16); - MD5Name(MD5Transform)(ctx->buf, (uint32 *) ctx->in); - - /* Now fill the next block with 56 bytes */ - memset(ctx->in, 0, 56); - } else { - /* Pad block to 56 bytes */ - memset(p, 0, count - 8); - } - byteReverse(ctx->in, 14); - - /* Append length in bits and transform */ - ((uint32 *) ctx->in)[14] = ctx->bits[0]; - ((uint32 *) ctx->in)[15] = ctx->bits[1]; - - MD5Name(MD5Transform)(ctx->buf, (uint32 *) ctx->in); - byteReverse((unsigned char *) ctx->buf, 4); - memcpy(digest, ctx->buf, 16); - memset(ctx, 0, sizeof(ctx)); /* In case it's sensitive */ -} - -/* The four core functions - F1 is optimized somewhat */ - -/* #define F1(x, y, z) (x & y | ~x & z) */ -#define F1(x, y, z) (z ^ (x & (y ^ z))) -#define F2(x, y, z) F1(z, x, y) -#define F3(x, y, z) (x ^ y ^ z) -#define F4(x, y, z) (y ^ (x | ~z)) - -/* This is the central step in the MD5 algorithm. */ -#define MD5STEP(f, w, x, y, z, data, s) \ - ( w += f(x, y, z) + data, w = w<<s | w>>(32-s), w += x ) - -/* - * The core of the MD5 algorithm, this alters an existing MD5 hash to - * reflect the addition of 16 longwords of new data. MD5Update blocks - * the data and converts bytes into longwords for this routine. - */ -void MD5Name(MD5Transform)(uint32 buf[4], uint32 const in[16]) -{ - register uint32 a, b, c, d; - - a = buf[0]; - b = buf[1]; - c = buf[2]; - d = buf[3]; - - MD5STEP(F1, a, b, c, d, in[0] + 0xd76aa478U, 7); - MD5STEP(F1, d, a, b, c, in[1] + 0xe8c7b756U, 12); - MD5STEP(F1, c, d, a, b, in[2] + 0x242070dbU, 17); - MD5STEP(F1, b, c, d, a, in[3] + 0xc1bdceeeU, 22); - MD5STEP(F1, a, b, c, d, in[4] + 0xf57c0fafU, 7); - MD5STEP(F1, d, a, b, c, in[5] + 0x4787c62aU, 12); - MD5STEP(F1, c, d, a, b, in[6] + 0xa8304613U, 17); - MD5STEP(F1, b, c, d, a, in[7] + 0xfd469501U, 22); - MD5STEP(F1, a, b, c, d, in[8] + 0x698098d8U, 7); - MD5STEP(F1, d, a, b, c, in[9] + 0x8b44f7afU, 12); - MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1U, 17); - MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7beU, 22); - MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122U, 7); - MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193U, 12); - MD5STEP(F1, c, d, a, b, in[14] + 0xa679438eU, 17); - MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821U, 22); - - MD5STEP(F2, a, b, c, d, in[1] + 0xf61e2562U, 5); - MD5STEP(F2, d, a, b, c, in[6] + 0xc040b340U, 9); - MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51U, 14); - MD5STEP(F2, b, c, d, a, in[0] + 0xe9b6c7aaU, 20); - MD5STEP(F2, a, b, c, d, in[5] + 0xd62f105dU, 5); - MD5STEP(F2, d, a, b, c, in[10] + 0x02441453U, 9); - MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681U, 14); - MD5STEP(F2, b, c, d, a, in[4] + 0xe7d3fbc8U, 20); - MD5STEP(F2, a, b, c, d, in[9] + 0x21e1cde6U, 5); - MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6U, 9); - MD5STEP(F2, c, d, a, b, in[3] + 0xf4d50d87U, 14); - MD5STEP(F2, b, c, d, a, in[8] + 0x455a14edU, 20); - MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905U, 5); - MD5STEP(F2, d, a, b, c, in[2] + 0xfcefa3f8U, 9); - MD5STEP(F2, c, d, a, b, in[7] + 0x676f02d9U, 14); - MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8aU, 20); - - MD5STEP(F3, a, b, c, d, in[5] + 0xfffa3942U, 4); - MD5STEP(F3, d, a, b, c, in[8] + 0x8771f681U, 11); - MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122U, 16); - MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380cU, 23); - MD5STEP(F3, a, b, c, d, in[1] + 0xa4beea44U, 4); - MD5STEP(F3, d, a, b, c, in[4] + 0x4bdecfa9U, 11); - MD5STEP(F3, c, d, a, b, in[7] + 0xf6bb4b60U, 16); - MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70U, 23); - MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6U, 4); - MD5STEP(F3, d, a, b, c, in[0] + 0xeaa127faU, 11); - MD5STEP(F3, c, d, a, b, in[3] + 0xd4ef3085U, 16); - MD5STEP(F3, b, c, d, a, in[6] + 0x04881d05U, 23); - MD5STEP(F3, a, b, c, d, in[9] + 0xd9d4d039U, 4); - MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5U, 11); - MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8U, 16); - MD5STEP(F3, b, c, d, a, in[2] + 0xc4ac5665U, 23); - - MD5STEP(F4, a, b, c, d, in[0] + 0xf4292244U, 6); - MD5STEP(F4, d, a, b, c, in[7] + 0x432aff97U, 10); - MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7U, 15); - MD5STEP(F4, b, c, d, a, in[5] + 0xfc93a039U, 21); - MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3U, 6); - MD5STEP(F4, d, a, b, c, in[3] + 0x8f0ccc92U, 10); - MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47dU, 15); - MD5STEP(F4, b, c, d, a, in[1] + 0x85845dd1U, 21); - MD5STEP(F4, a, b, c, d, in[8] + 0x6fa87e4fU, 6); - MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0U, 10); - MD5STEP(F4, c, d, a, b, in[6] + 0xa3014314U, 15); - MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1U, 21); - MD5STEP(F4, a, b, c, d, in[4] + 0xf7537e82U, 6); - MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235U, 10); - MD5STEP(F4, c, d, a, b, in[2] + 0x2ad7d2bbU, 15); - MD5STEP(F4, b, c, d, a, in[9] + 0xeb86d391U, 21); - - buf[0] += a; - buf[1] += b; - buf[2] += c; - buf[3] += d; -} - -void MD5Name(MD5)(unsigned const char *buf, unsigned len, unsigned char digest[16]) -{ - struct MD5Context ctx; - MD5Name(MD5Init)(&ctx); - MD5Name(MD5Update)(&ctx, buf, len); - MD5Name(MD5Final)(digest, &ctx); -} diff --git a/modules/pam_namespace/md5.h b/modules/pam_namespace/md5.h deleted file mode 100644 index 73f85833..00000000 --- a/modules/pam_namespace/md5.h +++ /dev/null @@ -1,28 +0,0 @@ - -#ifndef MD5_H -#define MD5_H - -typedef unsigned int uint32; - -struct MD5Context { - uint32 buf[4]; - uint32 bits[2]; - unsigned char in[64]; -}; - -#define MD5_DIGEST_LENGTH 16 - -void MD5Init(struct MD5Context *); -void MD5Update(struct MD5Context *, unsigned const char *, unsigned); -void MD5Final(unsigned char digest[MD5_DIGEST_LENGTH], struct MD5Context *); -void MD5Transform(uint32 buf[4], uint32 const in[MD5_DIGEST_LENGTH]); -void MD5(unsigned const char *, unsigned, unsigned char digest[MD5_DIGEST_LENGTH]); - - -/* - * This is needed to make RSAREF happy on some MS-DOS compilers. - */ - -typedef struct MD5Context MD5_CTX; - -#endif /* MD5_H */ diff --git a/modules/pam_namespace/namespace.conf b/modules/pam_namespace/namespace.conf deleted file mode 100644 index f973225f..00000000 --- a/modules/pam_namespace/namespace.conf +++ /dev/null @@ -1,28 +0,0 @@ -# /etc/security/namespace.conf -# -# See /usr/share/doc/pam-*/txts/README.pam_namespace for more information. -# -# Uncommenting the following three lines will polyinstantiate -# /tmp, /var/tmp and user's home directories. /tmp and /var/tmp will -# be polyinstantiated based on the MLS level part of the security context as well as user -# name, Polyinstantion will not be performed for user root and adm for directories -# /tmp and /var/tmp, whereas home directories will be polyinstantiated for all users. -# The user name and context is appended to the instance prefix. -# -# Note that instance directories do not have to reside inside the -# polyinstantiated directory. In the examples below, instances of /tmp -# will be created in /tmp-inst directory, where as instances of /var/tmp -# and users home directories will reside within the directories that -# are being polyinstantiated. -# -# Instance parent directories must exist for the polyinstantiation -# mechanism to work. By default, they should be created with the mode -# of 000. pam_namespace module will enforce this mode unless it -# is explicitly called with an argument to ignore the mode of the -# instance parent. System administrators should use this argument with -# caution, as it will reduce security and isolation achieved by -# polyinstantiation. -# -#/tmp /tmp-inst/ level root,adm -#/var/tmp /var/tmp/tmp-inst/ level root,adm -#$HOME $HOME/$USER.inst/ level diff --git a/modules/pam_namespace/namespace.conf.5.xml b/modules/pam_namespace/namespace.conf.5.xml deleted file mode 100644 index a1769600..00000000 --- a/modules/pam_namespace/namespace.conf.5.xml +++ /dev/null @@ -1,210 +0,0 @@ -<?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="namespace.conf"> - - <refmeta> - <refentrytitle>namespace.conf</refentrytitle> - <manvolnum>5</manvolnum> - <refmiscinfo class="sectdesc">Linux-PAM Manual</refmiscinfo> - </refmeta> - - <refnamediv> - <refname>namespace.conf</refname> - <refpurpose>the namespace configuration file</refpurpose> - </refnamediv> - - - <refsect1 id='namespace.conf-description'> - <title>DESCRIPTION</title> - - <para> - The <emphasis>pam_namespace.so</emphasis> module allows setup of - private namespaces with polyinstantiated directories. - 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 - directory path and the instance directory path as its arguments. - </para> - - <para> - The <filename>/etc/security/namespace.conf</filename> file specifies - which directories are polyinstantiated, how they are polyinstantiated, - how instance directories would be named, and any users for whom - polyinstantiation would not be performed. - </para> - - <para> - When someone logs in, the file <filename>namespace.conf</filename> is - scanned. Comments are marked by <emphasis>#</emphasis> characters. - Each non comment line represents one polyinstantiated - directory. The fields are separated by spaces but can be quoted by - <emphasis>"</emphasis> characters also escape - sequences <emphasis>\b</emphasis>, <emphasis>\n</emphasis>, and - <emphasis>\t</emphasis> are recognized. The fields are as follows: - </para> - - <para><replaceable>polydir</replaceable> <replaceable>instance_prefix</replaceable> <replaceable>method</replaceable> <replaceable>list_of_uids</replaceable> - </para> - - <para> - The first field, <replaceable>polydir</replaceable>, is the absolute - pathname of the directory to polyinstantiate. The special string - <emphasis>$HOME</emphasis> is replaced with the user's home directory, - and <emphasis>$USER</emphasis> with the username. This field cannot - be blank. - </para> - - <para> - The second field, <replaceable>instance_prefix</replaceable> is - the string prefix used to build the pathname for the instantiation - of <polydir>. Depending on the polyinstantiation - <replaceable>method</replaceable> it is then appended with - "instance differentiation string" to generate the final - instance directory path. This directory is created if it did not exist - already, and is then bind mounted on the <polydir> to provide an - instance of <polydir> based on the <method> column. - The special string <emphasis>$HOME</emphasis> is replaced with the - user's home directory, and <emphasis>$USER</emphasis> with the username. - This field cannot be blank. - </para> - - <para> - The third field, <replaceable>method</replaceable>, is the method - used for polyinstantiation. It can take these values; "user" - for polyinstantiation based on user name, "level" for - polyinstantiation based on process MLS level and user name, "context" for - polyinstantiation based on process security context and user name, - "tmpfs" for mounting tmpfs filesystem as an instance dir, and - "tmpdir" for creating temporary directory as an instance dir which is - removed when the user's session is closed. - Methods "context" and "level" are only available with SELinux. This - field cannot be blank. - </para> - - <para> - The fourth field, <replaceable>list_of_uids</replaceable>, is - a comma separated list of user names for whom the polyinstantiation - is not performed. If left blank, polyinstantiation will be performed - for all users. If the list is preceded with a single "~" character, - polyinstantiation is performed only for users in the list. - </para> - - <para> - The <replaceable>method</replaceable> field can contain also following - optional flags separated by <emphasis>:</emphasis> characters. - </para> - - <para><emphasis>create</emphasis>=<replaceable>mode</replaceable>,<replaceable>owner</replaceable>,<replaceable>group</replaceable> - - create the polyinstantiated directory. The mode, owner and group parameters - are optional. The default for mode is determined by umask, the default - owner is the user whose session is opened, the default group is the - primary group of the user. - </para> - - <para><emphasis>iscript</emphasis>=<replaceable>path</replaceable> - - path to the instance directory init script. The base directory for relative - paths is <filename>/etc/security/namespace.d</filename>. - </para> - - <para><emphasis>noinit</emphasis> - - instance directory init script will not be executed. - </para> - - <para><emphasis>shared</emphasis> - - the instance directories for "context" and "level" methods will not - contain the user name and will be shared among all users. - </para> - - <para> - The directory where polyinstantiated instances are to be - created, must exist and must have, by default, the mode of 0000. The - requirement that the instance parent be of mode 0000 can be overridden - with the command line option <emphasis>ignore_instance_parent_mode</emphasis> - </para> - - <para> - In case of context or level polyinstantiation the SELinux context - which is used for polyinstantiation is the context used for executing - a new process as obtained by getexeccon. This context must be set - by the calling application or <filename>pam_selinux.so</filename> - module. If this context is not set the polyinstatiation will be - based just on user name. - </para> - - <para> - The "instance differentiation string" is <user name> for "user" - method and <user name>_<raw directory context> for "context" - and "level" methods. If the whole string is too long the end of it is - replaced with md5sum of itself. Also when command line option - <emphasis>gen_hash</emphasis> is used the whole string is replaced - with md5sum of itself. - </para> - - </refsect1> - - <refsect1 id="namespace.conf-examples"> - <title>EXAMPLES</title> - <para> - These are some example lines which might be specified in - <filename>/etc/security/namespace.conf</filename>. - </para> - - <literallayout> - # The following three lines will polyinstantiate /tmp, - # /var/tmp and user's home directories. /tmp and /var/tmp - # will be polyinstantiated based on the security level - # as well as user name, whereas home directory will be - # polyinstantiated based on the full security context and user name. - # Polyinstantiation will not be performed for user root - # and adm for directories /tmp and /var/tmp, whereas home - # directories will be polyinstantiated for all users. - # - # Note that instance directories do not have to reside inside - # the polyinstantiated directory. In the examples below, - # instances of /tmp will be created in /tmp-inst directory, - # where as instances of /var/tmp and users home directories - # will reside within the directories that are being - # polyinstantiated. - # - /tmp /tmp-inst/ level root,adm - /var/tmp /var/tmp/tmp-inst/ level root,adm - $HOME $HOME/$USER.inst/inst- context - </literallayout> - - <para> - For the <service>s you need polyinstantiation (login for example) - put the following line in /etc/pam.d/<service> as the last line for - session group: - </para> - - <para> - session required pam_namespace.so [arguments] - </para> - - <para> - This module also depends on pam_selinux.so setting the context. - </para> - - </refsect1> - - <refsect1 id="namespace.conf-see_also"> - <title>SEE ALSO</title> - <para> - <citerefentry><refentrytitle>pam_namespace</refentrytitle><manvolnum>8</manvolnum></citerefentry>, - <citerefentry><refentrytitle>pam.d</refentrytitle><manvolnum>5</manvolnum></citerefentry>, - <citerefentry><refentrytitle>pam</refentrytitle><manvolnum>8</manvolnum></citerefentry> - </para> - </refsect1> - - <refsect1 id="namespace.conf-author"> - <title>AUTHORS</title> - <para> - The namespace.conf manual page was written by Janak Desai <janak@us.ibm.com>. - More features added by Tomas Mraz <tmraz@redhat.com>. - </para> - </refsect1> -</refentry> diff --git a/modules/pam_namespace/namespace.init b/modules/pam_namespace/namespace.init deleted file mode 100755 index 424c6d0c..00000000 --- a/modules/pam_namespace/namespace.init +++ /dev/null @@ -1,24 +0,0 @@ -#!/bin/sh -p -# It receives polydir path as $1, the instance path as $2, -# a flag whether the instance dir was newly created (0 - no, 1 - yes) in $3, -# and user name in $4. -# -# The following section will copy the contents of /etc/skel if this is a -# newly created home directory. -if [ "$3" = 1 ]; then - # This line will fix the labeling on all newly created directories - [ -x /sbin/restorecon ] && /sbin/restorecon "$1" - user="$4" - passwd=$(getent passwd "$user") - homedir=$(echo "$passwd" | cut -f6 -d":") - if [ "$1" = "$homedir" ]; then - gid=$(echo "$passwd" | cut -f4 -d":") - cp -rT /etc/skel "$homedir" - chown -R "$user":"$gid" "$homedir" - mode=$(awk '/^UMASK/{gsub("#.*$", "", $2); printf "%o", and(0777,compl(strtonum("0" $2))); exit}' /etc/login.defs) - chmod ${mode:-700} "$homedir" - [ -x /sbin/restorecon ] && /sbin/restorecon -R "$homedir" - fi -fi - -exit 0 diff --git a/modules/pam_namespace/pam_namespace.8.xml b/modules/pam_namespace/pam_namespace.8.xml deleted file mode 100644 index 32c5359d..00000000 --- a/modules/pam_namespace/pam_namespace.8.xml +++ /dev/null @@ -1,390 +0,0 @@ -<?xml version="1.0" encoding="ISO-8859-1"?> -<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN" - "http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd"> - -<refentry id='pam_namespace'> - - <refmeta> - <refentrytitle>pam_namespace</refentrytitle> - <manvolnum>8</manvolnum> - <refmiscinfo class='setdesc'>Linux-PAM Manual</refmiscinfo> - </refmeta> - - <refnamediv id='pam_namespace-name'> - <refname>pam_namespace</refname> - <refpurpose> - PAM module for configuring namespace for a session - </refpurpose> - </refnamediv> - -<!-- body begins here --> - - <refsynopsisdiv> - <cmdsynopsis id="pam_namespace-cmdsynopsis"> - <command>pam_namespace.so</command> - <arg choice="opt"> - debug - </arg> - <arg choice="opt"> - unmnt_remnt - </arg> - <arg choice="opt"> - unmnt_only - </arg> - <arg choice="opt"> - require_selinux - </arg> - <arg choice="opt"> - gen_hash - </arg> - <arg choice="opt"> - ignore_config_error - </arg> - <arg choice="opt"> - ignore_instance_parent_mode - </arg> - <arg choice="opt"> - no_unmount_on_close - </arg> - <arg choice="opt"> - use_current_context - </arg> - <arg choice="opt"> - use_default_context - </arg> - </cmdsynopsis> - </refsynopsisdiv> - - - <refsect1 id="pam_namespace-description"> - <title>DESCRIPTION</title> - <para> - The pam_namespace PAM module sets up a private namespace for a session - with polyinstantiated directories. A polyinstantiated directory - 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. - </para> - - <para> - The pam_namespace module disassociates the session namespace from - the parent namespace. Any mounts/unmounts performed in the parent - namespace, such as mounting of devices, are not reflected in the - session namespace. To propagate selected mount/unmount events from - the parent namespace into the disassociated session namespace, an - administrator may use the special shared-subtree feature. For - additional information on shared-subtree feature, please refer to - the mount(8) man page and the shared-subtree description at - http://lwn.net/Articles/159077 and http://lwn.net/Articles/159092. - </para> - - </refsect1> - - <refsect1 id="pam_namespace-options"> - <title>OPTIONS</title> - <variablelist> - - <varlistentry> - <term> - <option>debug</option> - </term> - <listitem> - <para> - A lot of debug information is logged using syslog - </para> - </listitem> - </varlistentry> - - <varlistentry> - <term> - <option>unmnt_remnt</option> - </term> - <listitem> - <para> - For programs such as su and newrole, the login - session has already setup a polyinstantiated - namespace. For these programs, polyinstantiation - is performed based on new user id or security - context, however the command first needs to - undo the polyinstantiation performed by login. - This argument instructs the command to - first undo previous polyinstantiation before - proceeding with new polyinstantiation based on - new id/context - </para> - </listitem> - </varlistentry> - - <varlistentry> - <term> - <option>unmnt_only</option> - </term> - <listitem> - <para> - For trusted programs that want to undo any - existing bind mounts and process instance - directories on their own, this argument allows - them to unmount currently mounted instance - directories - </para> - </listitem> - </varlistentry> - - <varlistentry> - <term> - <option>require_selinux</option> - </term> - <listitem> - <para> - If selinux is not enabled, return failure - </para> - </listitem> - </varlistentry> - - <varlistentry> - <term> - <option>gen_hash</option> - </term> - <listitem> - <para> - Instead of using the security context string - for the instance name, generate and use its - md5 hash. - </para> - </listitem> - </varlistentry> - - <varlistentry> - <term> - <option>ignore_config_error</option> - </term> - <listitem> - <para> - If a line in the configuration file corresponding - to a polyinstantiated directory contains format - error, skip that line process the next line. - Without this option, pam will return an error - to the calling program resulting in termination - of the session. - </para> - </listitem> - </varlistentry> - - <varlistentry> - <term> - <option>ignore_instance_parent_mode</option> - </term> - <listitem> - <para> - Instance parent directories by default are expected to have - the restrictive mode of 000. Using this option, an administrator - can choose to ignore the mode of the instance parent. This option - should be used with caution as it will reduce security and - isolation goals of the polyinstantiation mechanism. - </para> - </listitem> - </varlistentry> - - <varlistentry> - <term> - <option>no_unmount_on_close</option> - </term> - <listitem> - <para> - For certain trusted programs such as newrole, open session - is called from a child process while the parent perfoms - close session and pam end functions. For these commands - use this option to instruct pam_close_session to not - unmount the bind mounted polyinstantiated directory in the - parent. - </para> - </listitem> - </varlistentry> - - <varlistentry> - <term> - <option>use_current_context</option> - </term> - <listitem> - <para> - Useful for services which do not change the SELinux context - with setexeccon call. The module will use the current SELinux - context of the calling process for the level and context - polyinstantiation. - </para> - </listitem> - </varlistentry> - - <varlistentry> - <term> - <option>use_default_context</option> - </term> - <listitem> - <para> - Useful for services which do not use pam_selinux for changing - the SELinux context with setexeccon call. The module will use - the default SELinux context of the user for the level and context - polyinstantiation. - </para> - </listitem> - </varlistentry> - - </variablelist> - </refsect1> - - <refsect1 id="pam_namespace-services"> - <title>MODULE SERVICES PROVIDED</title> - <para> - The <option>session</option> service is supported. The module must not - be called from multithreaded processes. - </para> - </refsect1> - - <refsect1 id="pam_namespace-return_values"> - <title>RETURN VALUES</title> - <variablelist> - <varlistentry> - <term>PAM_SUCCESS</term> - <listitem> - <para> - Namespace setup was successful. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term>PAM_SERVICE_ERR</term> - <listitem> - <para> - Unexpected system error occurred while setting up namespace. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term>PAM_SESSION_ERR</term> - <listitem> - <para> - Unexpected namespace configuration error occurred. - </para> - </listitem> - </varlistentry> - </variablelist> - </refsect1> - - <refsect1 id="pam_namespace-files"> - <title>FILES</title> - <variablelist> - <varlistentry> - <term><filename>/etc/security/namespace.conf</filename></term> - <listitem> - <para>Main configuration file</para> - </listitem> - </varlistentry> - - <varlistentry> - <term><filename>/etc/security/namespace.d</filename></term> - <listitem> - <para>Directory for additional configuration files</para> - </listitem> - </varlistentry> - - <varlistentry> - <term><filename>/etc/security/namespace.init</filename></term> - <listitem> - <para>Init script for instance directories</para> - </listitem> - </varlistentry> - </variablelist> - </refsect1> - - <refsect1 id="pam_namespace-examples"> - <title>EXAMPLES</title> - - <para> - For the <service>s you need polyinstantiation (login for example) - put the following line in /etc/pam.d/<service> as the last line for - session group: - </para> - - <para> - session required pam_namespace.so [arguments] - </para> - - <para> - To use polyinstantiation with graphical display manager gdm, insert the - following line, before exit 0, in /etc/gdm/PostSession/Default: - </para> - - <para> - /usr/sbin/gdm-safe-restart - </para> - - <para> - This allows gdm to restart after each session and appropriately adjust - namespaces of display manager and the X server. If polyinstantiation - of /tmp is desired along with the graphical environment, then additional - configuration changes are needed to address the interaction of X server - and font server namespaces with their use of /tmp to create - communication sockets. Please use the initialization script - <filename>/etc/security/namespace.init</filename> to ensure that - the X server and its clients can appropriately access the - communication socket X0. Please refer to the sample instructions - provided in the comment section of the instance initialization script - <filename>/etc/security/namespace.init</filename>. In addition, - perform the following changes to use graphical environment with - polyinstantiation of /tmp: - </para> - - <para> - <literallayout> - 1. Disable the use of font server by commenting out "FontPath" - line in /etc/X11/xorg.conf. If you do want to use the font server - then you will have to augment the instance initialization - script to appropriately provide /tmp/.font-unix from the - polyinstantiated /tmp. - 2. Ensure that the gdm service is setup to use pam_namespace, - as described above, by modifying /etc/pam.d/gdm. - 3. Ensure that the display manager is configured to restart X server - with each new session. This default setup can be verified by - making sure that /usr/share/gdm/defaults.conf contains - "AlwaysRestartServer=true", and it is not overridden by - /etc/gdm/custom.conf. - </literallayout> - </para> - - </refsect1> - - <refsect1 id="pam_namespace-see_also"> - <title>SEE ALSO</title> - <para> - <citerefentry> - <refentrytitle>namespace.conf</refentrytitle><manvolnum>5</manvolnum> - </citerefentry>, - <citerefentry> - <refentrytitle>pam.d</refentrytitle><manvolnum>8</manvolnum> - </citerefentry>, - <citerefentry> - <refentrytitle>mount</refentrytitle><manvolnum>8</manvolnum> - </citerefentry>, - <citerefentry> - <refentrytitle>pam</refentrytitle><manvolnum>8</manvolnum> - </citerefentry>. - </para> - </refsect1> - - <refsect1 id="pam_namespace-authors"> - <title>AUTHORS</title> - <para> - The namespace setup scheme was designed by Stephen Smalley, Janak Desai - and Chad Sellers. - The pam_namespace PAM module was developed by Janak Desai <janak@us.ibm.com>, - Chad Sellers <csellers@tresys.com> and Steve Grubb <sgrubb@redhat.com>. - Additional improvements by Xavier Toth <txtoth@gmail.com> and Tomas Mraz - <tmraz@redhat.com>. - </para> - </refsect1> -</refentry> diff --git a/modules/pam_namespace/pam_namespace.c b/modules/pam_namespace/pam_namespace.c deleted file mode 100644 index d0741fd2..00000000 --- a/modules/pam_namespace/pam_namespace.c +++ /dev/null @@ -1,1907 +0,0 @@ -/****************************************************************************** - * A module for Linux-PAM that will set the default namespace after - * establishing a session via PAM. - * - * (C) Copyright IBM Corporation 2005 - * (C) Copyright Red Hat, Inc. 2006, 2008 - * All Rights Reserved. - * - * Written by: Janak Desai <janak@us.ibm.com> - * With Revisions by: Steve Grubb <sgrubb@redhat.com> - * Contributions by: Xavier Toth <txtoth@gmail.com>, - * Tomas Mraz <tmraz@redhat.com> - * Derived from a namespace setup patch by Chad Sellers <cdselle@tycho.nsa.gov> - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * on the rights to use, copy, modify, merge, publish, distribute, sub - * license, and/or sell copies of the Software, and to permit persons to whom - * the Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL - * IBM AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -#include "pam_namespace.h" -#include "argv_parse.h" - -/* - * Adds an entry for a polyinstantiated directory to the linked list of - * polyinstantiated directories. It is called from process_line() while - * parsing the namespace configuration file. - */ -static void add_polydir_entry(struct instance_data *idata, - struct polydir_s *ent) -{ - /* Now attach to linked list */ - ent->next = NULL; - if (idata->polydirs_ptr == NULL) - idata->polydirs_ptr = ent; - else { - struct polydir_s *tail; - - tail = idata->polydirs_ptr; - while (tail->next) - tail = tail->next; - tail->next = ent; - } -} - -static void del_polydir(struct polydir_s *poly) -{ - free(poly->uid); - free(poly->init_script); - free(poly); -} - -/* - * Deletes all the entries in the linked list. - */ -static void del_polydir_list(struct polydir_s *polydirs_ptr) -{ - struct polydir_s *dptr = polydirs_ptr; - - while (dptr) { - struct polydir_s *tptr = dptr; - dptr = dptr->next; - del_polydir(tptr); - } -} - -static void cleanup_data(pam_handle_t *pamh UNUSED , void *data, int err UNUSED) -{ - del_polydir_list(data); -} - -static char *expand_variables(const char *orig, const char *var_names[], const char *var_values[]) -{ - const char *src = orig; - char *dst; - char *expanded; - char c; - size_t dstlen = 0; - while (*src) { - if (*src == '$') { - int i; - for (i = 0; var_names[i]; i++) { - int namelen = strlen(var_names[i]); - if (strncmp(var_names[i], src+1, namelen) == 0) { - dstlen += strlen(var_values[i]) - 1; /* $ */ - src += namelen; - break; - } - } - } - ++dstlen; - ++src; - } - if ((dst=expanded=malloc(dstlen + 1)) == NULL) - return NULL; - src = orig; - while ((c=*src) != '\0') { - if (c == '$') { - int i; - for (i = 0; var_names[i]; i++) { - int namelen = strlen(var_names[i]); - if (strncmp(var_names[i], src+1, namelen) == 0) { - dst = stpcpy(dst, var_values[i]); - --dst; - c = *dst; /* replace $ */ - src += namelen; - break; - } - } - } - *dst = c; - ++dst; - ++src; - } - *dst = '\0'; - return expanded; -} - -static int parse_create_params(char *params, struct polydir_s *poly) -{ - char *sptr; - struct passwd *pwd; - struct group *grp; - - poly->mode = (mode_t)ULONG_MAX; - poly->owner = (uid_t)ULONG_MAX; - poly->group = (gid_t)ULONG_MAX; - - if (*params != '=') - return 0; - params++; - - params = strtok_r(params, ",", &sptr); - if (params == NULL) - return 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); - if (params == NULL) - return 0; - - 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; - return 0; - } - grp = getgrnam(params); - if (grp == NULL) - return -1; - poly->group = grp->gr_gid; - - return 0; -} - -static int parse_iscript_params(char *params, struct polydir_s *poly) -{ - if (*params != '=') - return 0; - params++; - - if (*params != '\0') { - if (*params != '/') { /* path is relative to NAMESPACE_D_DIR */ - if (asprintf(&poly->init_script, "%s%s", NAMESPACE_D_DIR, params) == -1) - return -1; - } else { - poly->init_script = strdup(params); - } - if (poly->init_script == NULL) - return -1; - } - return 0; -} - -static int parse_method(char *method, struct polydir_s *poly, - struct instance_data *idata) -{ - enum polymethod pm; - char *sptr; - static const char *method_names[] = { "user", "context", "level", "tmpdir", - "tmpfs", NULL }; - static const char *flag_names[] = { "create", "noinit", "iscript", - "shared", NULL }; - static const unsigned int flag_values[] = { POLYDIR_CREATE, POLYDIR_NOINIT, - POLYDIR_ISCRIPT, POLYDIR_SHARED }; - int i; - char *flag; - - method = strtok_r(method, ":", &sptr); - pm = NONE; - - for (i = 0; method_names[i]; i++) { - if (strcmp(method, method_names[i]) == 0) { - pm = i + 1; /* 0 = NONE */ - } - } - - if (pm == NONE) { - pam_syslog(idata->pamh, LOG_NOTICE, "Unknown method"); - return -1; - } - - poly->method = pm; - - while ((flag=strtok_r(NULL, ":", &sptr)) != NULL) { - for (i = 0; flag_names[i]; i++) { - int namelen = strlen(flag_names[i]); - - if (strncmp(flag, flag_names[i], namelen) == 0) { - poly->flags |= flag_values[i]; - switch (flag_values[i]) { - case POLYDIR_CREATE: - if (parse_create_params(flag+namelen, poly) != 0) { - pam_syslog(idata->pamh, LOG_CRIT, "Invalid create parameters"); - return -1; - } - break; - - case POLYDIR_ISCRIPT: - if (parse_iscript_params(flag+namelen, poly) != 0) { - pam_syslog(idata->pamh, LOG_CRIT, "Memory allocation error"); - return -1; - }; - break; - } - } - } - } - - return 0; -} - -/* - * Called from parse_config_file, this function processes a single line - * of the namespace configuration file. It skips over comments and incomplete - * or malformed lines. It processes a valid line with information on - * polyinstantiating a directory by populating appropriate fields of a - * polyinstatiated directory structure and then calling add_polydir_entry to - * add that entry to the linked list of polyinstantiated directories. - */ -static int process_line(char *line, const char *home, const char *rhome, - struct instance_data *idata) -{ - char *dir = NULL, *instance_prefix = NULL, *rdir = NULL; - char *method, *uids; - char *tptr; - struct polydir_s *poly; - int retval = 0; - char **config_options = NULL; - static const char *var_names[] = {"HOME", "USER", NULL}; - const char *var_values[] = {home, idata->user}; - const char *rvar_values[] = {rhome, idata->ruser}; - int len; - - poly = calloc(1, sizeof(*poly)); - if (poly == NULL) - goto erralloc; - - /* - * skip the leading white space - */ - while (*line && isspace(*line)) - line++; - - /* - * Rip off the comments - */ - tptr = strchr(line,'#'); - if (tptr) - *tptr = '\0'; - - /* - * Rip off the newline char - */ - tptr = strchr(line,'\n'); - if (tptr) - *tptr = '\0'; - - /* - * Anything left ? - */ - if (line[0] == 0) - return 0; - - /* - * Initialize and scan the five strings from the line from the - * namespace configuration file. - */ - retval = argv_parse(line, NULL, &config_options); - if (retval != 0) { - goto erralloc; - } - - dir = config_options[0]; - if (dir == NULL) { - pam_syslog(idata->pamh, LOG_NOTICE, "Invalid line missing polydir"); - goto skipping; - } - instance_prefix = config_options[1]; - if (instance_prefix == NULL) { - pam_syslog(idata->pamh, LOG_NOTICE, "Invalid line missing instance_prefix"); - instance_prefix = NULL; - goto skipping; - } - method = config_options[2]; - if (method == NULL) { - pam_syslog(idata->pamh, LOG_NOTICE, "Invalid line missing method"); - instance_prefix = NULL; - dir = NULL; - goto skipping; - } - - /* - * Only the uids field is allowed to be blank, to indicate no - * override users for polyinstantiation of that directory. If - * any of the other fields are blank, the line is incomplete so - * skip it. - */ - uids = config_options[3]; - - /* - * Expand $HOME and $USER in poly dir and instance dir prefix - */ - if ((rdir=expand_variables(dir, var_names, rvar_values)) == NULL) { - instance_prefix = NULL; - dir = NULL; - goto erralloc; - } - - if ((dir=expand_variables(dir, var_names, var_values)) == NULL) { - instance_prefix = NULL; - goto erralloc; - } - - if ((instance_prefix=expand_variables(instance_prefix, var_names, var_values)) - == NULL) { - goto erralloc; - } - - if (idata->flags & PAMNS_DEBUG) { - pam_syslog(idata->pamh, LOG_DEBUG, "Expanded polydir: '%s'", dir); - pam_syslog(idata->pamh, LOG_DEBUG, "Expanded ruser polydir: '%s'", rdir); - pam_syslog(idata->pamh, LOG_DEBUG, "Expanded instance prefix: '%s'", instance_prefix); - } - - len = strlen(dir); - if (len > 0 && dir[len-1] == '/') { - dir[len-1] = '\0'; - } - - len = strlen(rdir); - if (len > 0 && rdir[len-1] == '/') { - rdir[len-1] = '\0'; - } - - if (dir[0] == '\0' || rdir[0] == '\0') { - pam_syslog(idata->pamh, LOG_NOTICE, "Invalid polydir"); - goto skipping; - } - - /* - * Populate polyinstantiated directory structure with appropriate - * pathnames and the method with which to polyinstantiate. - */ - if (strlen(dir) >= sizeof(poly->dir) - || strlen(rdir) >= sizeof(poly->rdir) - || strlen(instance_prefix) >= sizeof(poly->instance_prefix)) { - pam_syslog(idata->pamh, LOG_NOTICE, "Pathnames too long"); - goto skipping; - } - strcpy(poly->dir, dir); - strcpy(poly->rdir, rdir); - strcpy(poly->instance_prefix, instance_prefix); - - if (parse_method(method, poly, idata) != 0) { - goto skipping; - } - - if (poly->method == TMPDIR) { - if (sizeof(poly->instance_prefix) - strlen(poly->instance_prefix) < 7) { - pam_syslog(idata->pamh, LOG_NOTICE, "Pathnames too long"); - goto skipping; - } - strcat(poly->instance_prefix, "XXXXXX"); - } - - /* - * Ensure that all pathnames are absolute path names. - */ - if ((poly->dir[0] != '/') || (poly->method != TMPFS && poly->instance_prefix[0] != '/')) { - pam_syslog(idata->pamh, LOG_NOTICE, "Pathnames must start with '/'"); - goto skipping; - } - if (strstr(dir, "..") || strstr(poly->instance_prefix, "..")) { - pam_syslog(idata->pamh, LOG_NOTICE, "Pathnames must not contain '..'"); - goto skipping; - } - - /* - * If the line in namespace.conf for a directory to polyinstantiate - * contains a list of override users (users for whom polyinstantiation - * is not performed), read the user ids, convert names into uids, and - * add to polyinstantiated directory structure. - */ - if (uids) { - uid_t *uidptr; - const char *ustr, *sstr; - int count, i; - - if (*uids == '~') { - poly->flags |= POLYDIR_EXCLUSIVE; - uids++; - } - for (count = 0, ustr = sstr = uids; sstr; ustr = sstr + 1, count++) - sstr = strchr(ustr, ','); - - poly->num_uids = count; - poly->uid = (uid_t *) malloc(count * sizeof (uid_t)); - uidptr = poly->uid; - if (uidptr == NULL) { - goto erralloc; - } - - ustr = uids; - for (i = 0; i < count; i++) { - struct passwd *pwd; - - tptr = strchr(ustr, ','); - if (tptr) - *tptr = '\0'; - - pwd = pam_modutil_getpwnam(idata->pamh, ustr); - if (pwd == NULL) { - pam_syslog(idata->pamh, LOG_ERR, "Unknown user %s in configuration", ustr); - poly->num_uids--; - } else { - *uidptr = pwd->pw_uid; - uidptr++; - } - ustr = tptr + 1; - } - } - - /* - * Add polyinstantiated directory structure to the linked list - * of all polyinstantiated directory structures. - */ - add_polydir_entry(idata, poly); - - goto out; - -erralloc: - pam_syslog(idata->pamh, LOG_CRIT, "Memory allocation error"); - -skipping: - if (idata->flags & PAMNS_IGN_CONFIG_ERR) - retval = 0; - else - retval = PAM_SERVICE_ERR; - del_polydir(poly); -out: - free(rdir); - free(dir); - free(instance_prefix); - argv_free(config_options); - return retval; -} - - -/* - * Parses /etc/security/namespace.conf file to build a linked list of - * polyinstantiated directory structures of type polydir_s. Each entry - * in the linked list contains information needed to polyinstantiate - * one directory. - */ -static int parse_config_file(struct instance_data *idata) -{ - FILE *fil; - char *home, *rhome; - const char *confname; - struct passwd *cpwd; - char *line; - int retval; - size_t len = 0; - glob_t globbuf; - const char *oldlocale; - size_t n; - - /* - * Extract the user's home directory to resolve $HOME entries - * in the namespace configuration file. - */ - cpwd = pam_modutil_getpwnam(idata->pamh, idata->user); - if (!cpwd) { - pam_syslog(idata->pamh, LOG_ERR, - "Error getting home dir for '%s'", idata->user); - return PAM_SESSION_ERR; - } - if ((home=strdup(cpwd->pw_dir)) == NULL) { - pam_syslog(idata->pamh, LOG_CRIT, - "Memory allocation error"); - return PAM_SESSION_ERR; - } - - cpwd = pam_modutil_getpwnam(idata->pamh, idata->ruser); - if (!cpwd) { - pam_syslog(idata->pamh, LOG_ERR, - "Error getting home dir for '%s'", idata->ruser); - free(home); - return PAM_SESSION_ERR; - } - - if ((rhome=strdup(cpwd->pw_dir)) == NULL) { - pam_syslog(idata->pamh, LOG_CRIT, - "Memory allocation error"); - free(home); - return PAM_SESSION_ERR; - } - - /* - * Open configuration file, read one line at a time and call - * process_line to process each line. - */ - - memset(&globbuf, '\0', sizeof(globbuf)); - oldlocale = setlocale(LC_COLLATE, "C"); - glob(NAMESPACE_D_GLOB, 0, NULL, &globbuf); - if (oldlocale != NULL) - setlocale(LC_COLLATE, oldlocale); - - confname = PAM_NAMESPACE_CONFIG; - n = 0; - for (;;) { - if (idata->flags & PAMNS_DEBUG) - pam_syslog(idata->pamh, LOG_DEBUG, "Parsing config file %s", - confname); - fil = fopen(confname, "r"); - if (fil == NULL) { - pam_syslog(idata->pamh, LOG_ERR, "Error opening config file %s", - confname); - globfree(&globbuf); - free(rhome); - free(home); - return PAM_SERVICE_ERR; - } - - /* Use unlocked IO */ - __fsetlocking(fil, FSETLOCKING_BYCALLER); - - line = NULL; - /* loop reading the file */ - while (getline(&line, &len, fil) > 0) { - retval = process_line(line, home, rhome, idata); - if (retval) { - pam_syslog(idata->pamh, LOG_ERR, - "Error processing conf file %s line %s", confname, line); - fclose(fil); - free(line); - globfree(&globbuf); - free(rhome); - free(home); - return PAM_SERVICE_ERR; - } - } - fclose(fil); - free(line); - - if (n >= globbuf.gl_pathc) - break; - - confname = globbuf.gl_pathv[n]; - n++; - } - - globfree(&globbuf); - free(rhome); - free(home); - - /* All done...just some debug stuff */ - if (idata->flags & PAMNS_DEBUG) { - struct polydir_s *dptr = idata->polydirs_ptr; - uid_t *iptr; - uid_t i; - - pam_syslog(idata->pamh, LOG_DEBUG, - dptr?"Configured poly dirs:":"No configured poly dirs"); - while (dptr) { - pam_syslog(idata->pamh, LOG_DEBUG, "dir='%s' iprefix='%s' meth=%d", - dptr->dir, dptr->instance_prefix, dptr->method); - for (i = 0, iptr = dptr->uid; i < dptr->num_uids; i++, iptr++) - pam_syslog(idata->pamh, LOG_DEBUG, "override user %d ", *iptr); - dptr = dptr->next; - } - } - - return PAM_SUCCESS; -} - - -/* - * This funtion returns true if a given uid is present in the polyinstantiated - * directory's list of override uids. If the uid is one of the override - * uids for the polyinstantiated directory, polyinstantiation is not - * performed for that user for that directory. - * If exclusive is set the returned values are opposite. - */ -static int ns_override(struct polydir_s *polyptr, struct instance_data *idata, - uid_t uid) -{ - unsigned int i; - - if (idata->flags & PAMNS_DEBUG) - pam_syslog(idata->pamh, LOG_DEBUG, - "Checking for ns override in dir %s for uid %d", - polyptr->dir, uid); - - for (i = 0; i < polyptr->num_uids; i++) { - if (uid == polyptr->uid[i]) { - return !(polyptr->flags & POLYDIR_EXCLUSIVE); - } - } - - return !!(polyptr->flags & POLYDIR_EXCLUSIVE); -} - -/* - * md5hash generates a hash of the passed in instance directory name. - */ -static char *md5hash(const char *instname, struct instance_data *idata) -{ - int i; - char *md5inst = NULL; - char *to; - unsigned char inst_digest[MD5_DIGEST_LENGTH]; - - /* - * Create MD5 hashes for instance pathname. - */ - - MD5((const unsigned char *)instname, strlen(instname), inst_digest); - - if ((md5inst = malloc(MD5_DIGEST_LENGTH * 2 + 1)) == NULL) { - pam_syslog(idata->pamh, LOG_ERR, "Unable to allocate buffer"); - return NULL; - } - - to = md5inst; - for (i = 0; i < MD5_DIGEST_LENGTH; i++) { - snprintf(to, 3, "%02x", (unsigned int)inst_digest[i]); - to += 2; - } - - return md5inst; -} - -#ifdef WITH_SELINUX -static int form_context(const struct polydir_s *polyptr, - security_context_t *i_context, security_context_t *origcon, - struct instance_data *idata) -{ - int rc = PAM_SUCCESS; - security_context_t scon = NULL; - security_class_t tclass; - - /* - * Get the security context of the directory to polyinstantiate. - */ - rc = getfilecon(polyptr->dir, origcon); - if (rc < 0 || *origcon == NULL) { - pam_syslog(idata->pamh, LOG_ERR, - "Error getting poly dir context, %m"); - return PAM_SESSION_ERR; - } - - if (polyptr->method == USER) return PAM_SUCCESS; - - if (idata->flags & PAMNS_USE_CURRENT_CONTEXT) { - rc = getcon(&scon); - } else if (idata->flags & PAMNS_USE_DEFAULT_CONTEXT) { - char *seuser = NULL, *level = NULL; - - if ((rc=getseuserbyname(idata->user, &seuser, &level)) == 0) { - rc = get_default_context_with_level(seuser, level, NULL, &scon); - free(seuser); - free(level); - } - } else { - rc = getexeccon(&scon); - } - if (rc < 0 || scon == NULL) { - pam_syslog(idata->pamh, LOG_ERR, - "Error getting exec context, %m"); - return PAM_SESSION_ERR; - } - - /* - * If polyinstantiating based on security context, get current - * process security context, get security class for directories, - * and ask the policy to provide security context of the - * polyinstantiated instance directory. - */ - - if (polyptr->method == CONTEXT) { - tclass = string_to_security_class("dir"); - - if (security_compute_member(scon, *origcon, tclass, - i_context) < 0) { - pam_syslog(idata->pamh, LOG_ERR, - "Error computing poly dir member context"); - freecon(scon); - return PAM_SESSION_ERR; - } else if (idata->flags & PAMNS_DEBUG) - pam_syslog(idata->pamh, LOG_DEBUG, - "member context returned by policy %s", *i_context); - freecon(scon); - return PAM_SUCCESS; - } - - /* - * If polyinstantiating based on security level, get current - * process security context, get security class for directories, - * and change the directories MLS Level to match process. - */ - - if (polyptr->method == LEVEL) { - context_t scontext = NULL; - context_t fcontext = NULL; - rc = PAM_SESSION_ERR; - - scontext = context_new(scon); - if (! scontext) { - pam_syslog(idata->pamh, LOG_ERR, "out of memory"); - goto fail; - } - fcontext = context_new(*origcon); - if (! fcontext) { - pam_syslog(idata->pamh, LOG_ERR, "out of memory"); - goto fail; - } - if (context_range_set(fcontext, context_range_get(scontext)) != 0) { - pam_syslog(idata->pamh, LOG_ERR, "Unable to set MLS Componant of context"); - goto fail; - } - *i_context=strdup(context_str(fcontext)); - if (! *i_context) { - pam_syslog(idata->pamh, LOG_ERR, "out of memory"); - goto fail; - } - - rc = PAM_SUCCESS; - fail: - context_free(scontext); - context_free(fcontext); - freecon(scon); - return rc; - } - /* Should never get here */ - return PAM_SUCCESS; -} -#endif - -/* - * poly_name returns the name of the polyinstantiated instance directory - * based on the method used for polyinstantiation (user, context or level) - * In addition, the function also returns the security contexts of the - * original directory to polyinstantiate and the polyinstantiated instance - * directory. - */ -#ifdef WITH_SELINUX -static int poly_name(const struct polydir_s *polyptr, char **i_name, - security_context_t *i_context, security_context_t *origcon, - struct instance_data *idata) -#else -static int poly_name(const struct polydir_s *polyptr, char **i_name, - struct instance_data *idata) -#endif -{ - int rc; - char *hash = NULL; - enum polymethod pm; -#ifdef WITH_SELINUX - security_context_t rawcon = NULL; -#endif - - *i_name = NULL; -#ifdef WITH_SELINUX - *i_context = NULL; - *origcon = NULL; - if ((idata->flags & PAMNS_SELINUX_ENABLED) && - (rc=form_context(polyptr, i_context, origcon, idata)) != PAM_SUCCESS) { - return rc; - } -#endif - - rc = PAM_SESSION_ERR; - /* - * Set the name of the polyinstantiated instance dir based on the - * polyinstantiation method. - */ - - pm = polyptr->method; - if (pm == LEVEL || pm == USER) { -#ifdef WITH_SELINUX - if (!(idata->flags & PAMNS_CTXT_BASED_INST)) -#else - pam_syslog(idata->pamh, LOG_NOTICE, - "Context and level methods not available, using user method"); -#endif - if (polyptr->flags & POLYDIR_SHARED) { - rc = PAM_IGNORE; - goto fail; - } - pm = USER; - } - - switch (pm) { - case USER: - if (asprintf(i_name, "%s", idata->user) < 0) { - *i_name = NULL; - goto fail; - } - break; - -#ifdef WITH_SELINUX - case LEVEL: - case CONTEXT: - if (selinux_trans_to_raw_context(*i_context, &rawcon) < 0) { - pam_syslog(idata->pamh, LOG_ERR, "Error translating directory context"); - goto fail; - } - if (polyptr->flags & POLYDIR_SHARED) { - if (asprintf(i_name, "%s", rawcon) < 0) { - *i_name = NULL; - goto fail; - } - } else { - if (asprintf(i_name, "%s_%s", rawcon, idata->user) < 0) { - *i_name = NULL; - goto fail; - } - } - break; - -#endif /* WITH_SELINUX */ - - case TMPDIR: - case TMPFS: - if ((*i_name=strdup("")) == NULL) - goto fail; - return PAM_SUCCESS; - - default: - if (idata->flags & PAMNS_DEBUG) - pam_syslog(idata->pamh, LOG_ERR, "Unknown method"); - goto fail; - } - - if (idata->flags & PAMNS_DEBUG) - pam_syslog(idata->pamh, LOG_DEBUG, "poly_name %s", *i_name); - - if ((idata->flags & PAMNS_GEN_HASH) || strlen(*i_name) > NAMESPACE_MAX_DIR_LEN) { - hash = md5hash(*i_name, idata); - if (hash == NULL) { - goto fail; - } - if (idata->flags & PAMNS_GEN_HASH) { - free(*i_name); - *i_name = hash; - hash = NULL; - } else { - char *newname; - if (asprintf(&newname, "%.*s_%s", NAMESPACE_MAX_DIR_LEN-1-(int)strlen(hash), - *i_name, hash) < 0) { - goto fail; - } - free(*i_name); - *i_name = newname; - } - } - rc = PAM_SUCCESS; - -fail: - free(hash); -#ifdef WITH_SELINUX - freecon(rawcon); -#endif - if (rc != PAM_SUCCESS) { -#ifdef WITH_SELINUX - freecon(*i_context); - *i_context = NULL; - freecon(*origcon); - *origcon = NULL; -#endif - free(*i_name); - *i_name = NULL; - } - return rc; -} - -static int check_inst_parent(char *ipath, struct instance_data *idata) -{ - struct stat instpbuf; - char *inst_parent, *trailing_slash; - /* - * stat the instance parent path to make sure it exists - * and is a directory. Check that its mode is 000 (unless the - * admin explicitly instructs to ignore the instance parent - * mode by the "ignore_instance_parent_mode" argument). - */ - inst_parent = (char *) malloc(strlen(ipath)+1); - if (!inst_parent) { - pam_syslog(idata->pamh, LOG_ERR, "Error allocating pathname string"); - return PAM_SESSION_ERR; - } - - strcpy(inst_parent, ipath); - trailing_slash = strrchr(inst_parent, '/'); - 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; - } - - /* - * 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); - 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", - inst_parent); - free(inst_parent); - return PAM_SESSION_ERR; - } - } - free(inst_parent); - return PAM_SUCCESS; -} - -/* -* 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. -*/ -static int inst_init(const struct polydir_s *polyptr, const char *ipath, - struct instance_data *idata, int newdir) -{ - pid_t rc, pid; - sighandler_t osighand = NULL; - int status; - const char *init_script = NAMESPACE_INIT_SCRIPT; - - osighand = signal(SIGCHLD, SIG_DFL); - if (osighand == SIG_ERR) { - pam_syslog(idata->pamh, LOG_ERR, "Cannot set signal value"); - rc = PAM_SESSION_ERR; - goto out; - } - - if ((polyptr->flags & POLYDIR_ISCRIPT) && polyptr->init_script) - init_script = polyptr->init_script; - - if (access(init_script, F_OK) == 0) { - if (access(init_script, X_OK) < 0) { - if (idata->flags & PAMNS_DEBUG) - pam_syslog(idata->pamh, LOG_ERR, - "Namespace init script not executable"); - rc = PAM_SESSION_ERR; - goto out; - } else { - pid = fork(); - if (pid == 0) { -#ifdef WITH_SELINUX - if (idata->flags & PAMNS_SELINUX_ENABLED) { - if (setexeccon(NULL) < 0) - exit(1); - } -#endif - if (execl(init_script, init_script, - polyptr->dir, ipath, newdir?"1":"0", idata->user, (char *)NULL) < 0) - exit(1); - } else if (pid > 0) { - while (((rc = waitpid(pid, &status, 0)) == (pid_t)-1) && - (errno == EINTR)); - if (rc == (pid_t)-1) { - pam_syslog(idata->pamh, LOG_ERR, "waitpid failed- %m"); - rc = PAM_SESSION_ERR; - goto out; - } - if (!WIFEXITED(status) || WIFSIGNALED(status) > 0) { - pam_syslog(idata->pamh, LOG_ERR, - "Error initializing instance"); - rc = PAM_SESSION_ERR; - goto out; - } - } else if (pid < 0) { - pam_syslog(idata->pamh, LOG_ERR, - "Cannot fork to run namespace init script, %m"); - rc = PAM_SESSION_ERR; - goto out; - } - } - } - rc = PAM_SUCCESS; -out: - (void) signal(SIGCHLD, osighand); - - return rc; -} - -static int create_polydir(struct polydir_s *polyptr, - struct instance_data *idata) -{ - mode_t mode; - int rc; -#ifdef WITH_SELINUX - security_context_t dircon, oldcon = NULL; -#endif - const char *dir = polyptr->dir; - - if (polyptr->mode != (mode_t)ULONG_MAX) - mode = polyptr->mode; - else - mode = 0777; - -#ifdef WITH_SELINUX - if (idata->flags & PAMNS_SELINUX_ENABLED) { - getfscreatecon(&oldcon); - rc = matchpathcon(dir, S_IFDIR, &dircon); - if (rc) { - pam_syslog(idata->pamh, LOG_NOTICE, - "Unable to get default context for directory %s, check your policy: %m", dir); - } else { - if (idata->flags & PAMNS_DEBUG) - pam_syslog(idata->pamh, LOG_DEBUG, - "Polydir %s context: %s", dir, (char *)dircon); - if (setfscreatecon(dircon) != 0) - pam_syslog(idata->pamh, LOG_NOTICE, - "Error setting context for directory %s: %m", dir); - freecon(dircon); - } - matchpathcon_fini(); - } -#endif - - rc = mkdir(dir, mode); - if (rc != 0) { - pam_syslog(idata->pamh, LOG_ERR, - "Error creating directory %s: %m", dir); - return PAM_SESSION_ERR; - } - -#ifdef WITH_SELINUX - if (idata->flags & PAMNS_SELINUX_ENABLED) { - if (setfscreatecon(oldcon) != 0) - pam_syslog(idata->pamh, LOG_NOTICE, - "Error resetting fs create context: %m"); - freecon(oldcon); - } -#endif - - if (idata->flags & PAMNS_DEBUG) - pam_syslog(idata->pamh, LOG_DEBUG, "Created polydir %s", dir); - - if (polyptr->mode != (mode_t)ULONG_MAX) { - /* explicit mode requested */ - if (chmod(dir, mode) != 0) { - pam_syslog(idata->pamh, LOG_ERR, - "Error changing mode of directory %s: %m", dir); - 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); - } - - return PAM_SUCCESS; -} - -/* - * Create polyinstantiated instance directory (ipath). - */ -#ifdef WITH_SELINUX -static int create_dirs(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, - struct instance_data *idata) -#endif -{ - struct stat newstatbuf; - int fd; - int newdir = 0; - - /* - * Check to make sure instance parent is valid. - */ - if (check_inst_parent(ipath, idata)) - return PAM_SESSION_ERR; - - /* - * Create instance directory and set its security context to the context - * returned by the security policy. Set its mode and ownership - * attributes to match that of the original directory that is being - * polyinstantiated. - */ - - if (polyptr->method == TMPDIR) { - if (mkdtemp(polyptr->instance_prefix) == NULL) { - pam_syslog(idata->pamh, LOG_ERR, "Error creating temporary instance %s, %m", - polyptr->instance_prefix); - polyptr->method = NONE; /* do not clean up! */ - return PAM_SESSION_ERR; - } - /* copy the actual directory name to ipath */ - strcpy(ipath, polyptr->instance_prefix); - } else if (mkdir(ipath, S_IRUSR) < 0) { - if (errno == EEXIST) - goto inst_init; - else { - pam_syslog(idata->pamh, LOG_ERR, "Error creating %s, %m", - ipath); - return PAM_SESSION_ERR; - } - } - - newdir = 1; - /* Open a descriptor to it to prevent races */ - fd = open(ipath, O_DIRECTORY | O_RDONLY); - if (fd < 0) { - pam_syslog(idata->pamh, LOG_ERR, "Error opening %s, %m", ipath); - rmdir(ipath); - return PAM_SESSION_ERR; - } -#ifdef WITH_SELINUX - /* If SE Linux is disabled, no need to label it */ - if (idata->flags & PAMNS_SELINUX_ENABLED) { - /* If method is USER, icontext is NULL */ - if (icontext) { - if (fsetfilecon(fd, icontext) < 0) { - pam_syslog(idata->pamh, LOG_ERR, - "Error setting context of %s to %s", ipath, icontext); - close(fd); - rmdir(ipath); - return PAM_SESSION_ERR; - } - } else { - if (fsetfilecon(fd, ocontext) < 0) { - pam_syslog(idata->pamh, LOG_ERR, - "Error setting context of %s to %s", ipath, ocontext); - close(fd); - rmdir(ipath); - return PAM_SESSION_ERR; - } - } - } -#endif - if (fstat(fd, &newstatbuf) < 0) { - pam_syslog(idata->pamh, LOG_ERR, "Error stating %s, %m", - ipath); - rmdir(ipath); - return PAM_SESSION_ERR; - } - if (newstatbuf.st_uid != statbuf->st_uid || - newstatbuf.st_gid != statbuf->st_gid) { - if (fchown(fd, statbuf->st_uid, statbuf->st_gid) < 0) { - pam_syslog(idata->pamh, LOG_ERR, - "Error changing owner for %s, %m", - ipath); - close(fd); - rmdir(ipath); - return PAM_SESSION_ERR; - } - } - if (fchmod(fd, statbuf->st_mode & 07777) < 0) { - pam_syslog(idata->pamh, LOG_ERR, "Error changing mode for %s, %m", - ipath); - close(fd); - rmdir(ipath); - 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); -} - - -/* - * 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 - * 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; - char *inst_dir = NULL; - char *instname = NULL; - struct stat statbuf; -#ifdef WITH_SELINUX - security_context_t instcontext = NULL, origcontext = NULL; -#endif - - if (idata->flags & PAMNS_DEBUG) - 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 */ - } - } - - /* - * 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", - polyptr->dir); - return PAM_SESSION_ERR; - } - - 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 */ - return inst_init(polyptr, "tmpfs", idata, 1); - } - - /* - * Obtain the name of instance pathname based on the - * polyinstantiation method and instance context returned by - * security policy. - */ -#ifdef WITH_SELINUX - retval = poly_name(polyptr, &instname, &instcontext, - &origcontext, idata); -#else - retval = poly_name(polyptr, &instname, idata); -#endif - - if (retval != PAM_SUCCESS) { - if (retval != PAM_IGNORE) - pam_syslog(idata->pamh, LOG_ERR, "Error getting instance name"); - goto cleanup; - } else { -#ifdef WITH_SELINUX - if ((idata->flags & PAMNS_DEBUG) && - (idata->flags & PAMNS_SELINUX_ENABLED)) - pam_syslog(idata->pamh, LOG_DEBUG, "Inst ctxt %s Orig ctxt %s", - instcontext, origcontext); -#endif - } - - if (asprintf(&inst_dir, "%s%s", polyptr->instance_prefix, instname) < 0) - goto error_out; - - if (idata->flags & PAMNS_DEBUG) - pam_syslog(idata->pamh, LOG_DEBUG, "instance_dir %s", - inst_dir); - - /* - * Create instance directory with appropriate security - * contexts, owner, group and mode bits. - */ -#ifdef WITH_SELINUX - retval = create_dirs(polyptr, inst_dir, &statbuf, instcontext, - origcontext, idata); -#else - retval = create_dirs(polyptr, inst_dir, &statbuf, idata); -#endif - - if (retval < 0) { - pam_syslog(idata->pamh, LOG_ERR, "Error creating instance dir"); - goto error_out; - } - - /* - * Bind mount instance directory on top of the polyinstantiated - * directory to provide an instance of polyinstantiated directory - * based on polyinstantiated method. - */ - if (mount(inst_dir, polyptr->dir, NULL, MS_BIND, NULL) < 0) { - pam_syslog(idata->pamh, LOG_ERR, "Error mounting %s on %s, %m", - inst_dir, polyptr->dir); - goto error_out; - } - - goto cleanup; - - /* - * various error exit points. Free allocated memory and set return - * value to indicate a pam session error. - */ -error_out: - retval = PAM_SESSION_ERR; - -cleanup: - free(inst_dir); - free(instname); -#ifdef WITH_SELINUX - freecon(instcontext); - freecon(origcontext); -#endif - return retval; -} - - -/* - * This function checks to see if the current working directory is - * inside the directory passed in as the first argument. - */ -static int cwd_in(char *dir, struct instance_data *idata) -{ - int retval = 0; - char cwd[PATH_MAX]; - - if (getcwd(cwd, PATH_MAX) == NULL) { - pam_syslog(idata->pamh, LOG_ERR, "Can't get current dir, %m"); - return -1; - } - - if (strncmp(cwd, dir, strlen(dir)) == 0) { - if (idata->flags & PAMNS_DEBUG) - pam_syslog(idata->pamh, LOG_DEBUG, "cwd is inside %s", dir); - retval = 1; - } else { - if (idata->flags & PAMNS_DEBUG) - pam_syslog(idata->pamh, LOG_DEBUG, "cwd is outside %s", dir); - } - - return retval; -} - -static int cleanup_tmpdirs(struct instance_data *idata) -{ - struct polydir_s *pptr; - pid_t rc, pid; - sighandler_t osighand = NULL; - int status; - - osighand = signal(SIGCHLD, SIG_DFL); - if (osighand == SIG_ERR) { - pam_syslog(idata->pamh, LOG_ERR, "Cannot set signal value"); - rc = PAM_SESSION_ERR; - goto out; - } - - for (pptr = idata->polydirs_ptr; pptr; pptr = pptr->next) { - if (pptr->method == TMPDIR && access(pptr->instance_prefix, F_OK) == 0) { - pid = fork(); - if (pid == 0) { -#ifdef WITH_SELINUX - if (idata->flags & PAMNS_SELINUX_ENABLED) { - if (setexeccon(NULL) < 0) - exit(1); - } -#endif - if (execl("/bin/rm", "/bin/rm", "-rf", pptr->instance_prefix, (char *)NULL) < 0) - exit(1); - } else if (pid > 0) { - while (((rc = waitpid(pid, &status, 0)) == (pid_t)-1) && - (errno == EINTR)); - if (rc == (pid_t)-1) { - pam_syslog(idata->pamh, LOG_ERR, "waitpid failed- %m"); - rc = PAM_SESSION_ERR; - goto out; - } - if (!WIFEXITED(status) || WIFSIGNALED(status) > 0) { - pam_syslog(idata->pamh, LOG_ERR, - "Error removing %s", pptr->instance_prefix); - } - } else if (pid < 0) { - pam_syslog(idata->pamh, LOG_ERR, - "Cannot fork to run namespace init script, %m"); - rc = PAM_SESSION_ERR; - goto out; - } - } - } - - rc = PAM_SUCCESS; -out: - signal(SIGCHLD, osighand); - return rc; -} - -/* - * This function checks to see if polyinstantiation is needed for any - * of the directories listed in the configuration file. If needed, - * cycles through all polyinstantiated directory entries and calls - * ns_setup to setup polyinstantiation for each one of them. - */ -static int setup_namespace(struct instance_data *idata, enum unmnt_op unmnt) -{ - int retval = 0, need_poly = 0, changing_dir = 0; - char *cptr, *fptr, poly_parent[PATH_MAX]; - struct polydir_s *pptr; - - if (idata->flags & PAMNS_DEBUG) - pam_syslog(idata->pamh, LOG_DEBUG, "Set up namespace for pid %d", - getpid()); - - /* - * Cycle through all polyinstantiated directory entries to see if - * polyinstantiation is needed at all. - */ - for (pptr = idata->polydirs_ptr; pptr; pptr = pptr->next) { - if (ns_override(pptr, idata, idata->uid)) { - if (unmnt == NO_UNMNT || ns_override(pptr, idata, idata->ruid)) { - if (idata->flags & PAMNS_DEBUG) - pam_syslog(idata->pamh, LOG_DEBUG, - "Overriding poly for user %d for dir %s", - idata->uid, pptr->dir); - } else { - if (idata->flags & PAMNS_DEBUG) - pam_syslog(idata->pamh, LOG_DEBUG, - "Need unmount ns for user %d for dir %s", - idata->ruid, pptr->dir); - need_poly = 1; - break; - } - continue; - } else { - if (idata->flags & PAMNS_DEBUG) - pam_syslog(idata->pamh, LOG_DEBUG, - "Need poly ns for user %d for dir %s", - idata->uid, pptr->dir); - need_poly = 1; - break; - } - } - - /* - * If polyinstantiation is needed, call the unshare system call to - * disassociate from the parent namespace. - */ - if (need_poly) { - if (unshare(CLONE_NEWNS) < 0) { - pam_syslog(idata->pamh, LOG_ERR, - "Unable to unshare from parent namespace, %m"); - return PAM_SESSION_ERR; - } - } else { - del_polydir_list(idata->polydirs_ptr); - return PAM_SUCCESS; - } - - /* - * Again cycle through all polyinstantiated directories, this time, - * call ns_setup to setup polyinstantiation for a particular entry. - */ - for (pptr = idata->polydirs_ptr; pptr; pptr = pptr->next) { - enum unmnt_op dir_unmnt = unmnt; - if (ns_override(pptr, idata, idata->uid)) { - if (unmnt == NO_UNMNT || ns_override(pptr, idata, idata->ruid)) { - continue; - } else { - dir_unmnt = UNMNT_ONLY; - } - } - if (idata->flags & PAMNS_DEBUG) - pam_syslog(idata->pamh, LOG_DEBUG, - "Setting poly ns for user %d for dir %s", - idata->uid, pptr->dir); - - if ((dir_unmnt == UNMNT_REMNT) || (dir_unmnt == UNMNT_ONLY)) { - /* - * Check to see if process current directory is in the - * bind mounted instance_parent directory that we are trying to - * umount - */ - if ((changing_dir = cwd_in(pptr->rdir, idata)) < 0) { - retval = PAM_SESSION_ERR; - goto out; - } else if (changing_dir) { - if (idata->flags & PAMNS_DEBUG) - pam_syslog(idata->pamh, LOG_DEBUG, "changing cwd"); - - /* - * Change current working directory to the parent of - * the mount point, that is parent of the orig - * directory where original contents of the polydir - * are available from - */ - strcpy(poly_parent, pptr->rdir); - fptr = strchr(poly_parent, '/'); - cptr = strrchr(poly_parent, '/'); - if (fptr && cptr && (fptr == cptr)) - strcpy(poly_parent, "/"); - else if (cptr) - *cptr = '\0'; - if (chdir(poly_parent) < 0) { - pam_syslog(idata->pamh, LOG_ERR, - "Can't chdir to %s, %m", poly_parent); - } - } - - if (umount(pptr->rdir) < 0) { - int saved_errno = errno; - pam_syslog(idata->pamh, LOG_ERR, "Unmount of %s failed, %m", - pptr->rdir); - if (saved_errno != EINVAL) { - retval = PAM_SESSION_ERR; - goto out; - } - } else if (idata->flags & PAMNS_DEBUG) - pam_syslog(idata->pamh, LOG_DEBUG, "Umount succeeded %s", - pptr->rdir); - } - - if (dir_unmnt != UNMNT_ONLY) { - retval = ns_setup(pptr, idata); - if (retval == PAM_IGNORE) - retval = PAM_SUCCESS; - if (retval != PAM_SUCCESS) - break; - } - } -out: - if (retval != PAM_SUCCESS) - 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"); - cleanup_tmpdirs(idata); - return PAM_SYSTEM_ERR; - } - return retval; -} - - -/* - * Orig namespace. This function is called from when closing a pam - * session. If authorized, it unmounts instance directory. - */ -static int orig_namespace(struct instance_data *idata) -{ - struct polydir_s *pptr; - - if (idata->flags & PAMNS_DEBUG) - pam_syslog(idata->pamh, LOG_DEBUG, "orig namespace for pid %d", - getpid()); - - /* - * Cycle through all polyinstantiated directories from the namespace - * configuration file to see if polyinstantiation was performed for - * this user for each of the entry. If it was, try and unmount - * appropriate polyinstantiated instance directories. - */ - for (pptr = idata->polydirs_ptr; pptr; pptr = pptr->next) { - if (ns_override(pptr, idata, idata->uid)) - continue; - else { - if (idata->flags & PAMNS_DEBUG) - pam_syslog(idata->pamh, LOG_DEBUG, - "Unmounting instance dir for user %d & dir %s", - idata->uid, pptr->dir); - - if (umount(pptr->dir) < 0) { - pam_syslog(idata->pamh, LOG_ERR, "Unmount of %s failed, %m", - pptr->dir); - return PAM_SESSION_ERR; - } else if (idata->flags & PAMNS_DEBUG) - pam_syslog(idata->pamh, LOG_DEBUG, "Unmount of %s succeeded", - pptr->dir); - } - } - - cleanup_tmpdirs(idata); - return 0; -} - - -#ifdef WITH_SELINUX -/* - * This function checks if the calling program has requested context - * change by calling setexeccon(). If context change is not requested - * then it does not make sense to polyinstantiate based on context. - * The return value from this function is used when selecting the - * polyinstantiation method. If context change is not requested then - * the polyinstantiation method is set to USER, even if the configuration - * file lists the method as "context" or "level". - */ -static int ctxt_based_inst_needed(void) -{ - security_context_t scon = NULL; - int rc = 0; - - rc = getexeccon(&scon); - if (rc < 0 || scon == NULL) - return 0; - else { - freecon(scon); - return 1; - } -} -#endif - - -static int get_user_data(struct instance_data *idata) -{ - int retval; - char *user_name; - struct passwd *pwd; - /* - * Lookup user and fill struct items - */ - retval = pam_get_item(idata->pamh, PAM_USER, (void*) &user_name ); - if ( user_name == NULL || retval != PAM_SUCCESS ) { - pam_syslog(idata->pamh, LOG_ERR, "Error recovering pam user name"); - return PAM_SESSION_ERR; - } - - pwd = pam_modutil_getpwnam(idata->pamh, user_name); - if (!pwd) { - pam_syslog(idata->pamh, LOG_ERR, "user unknown '%s'", user_name); - return PAM_USER_UNKNOWN; - } - - /* - * Add the user info to the instance data so we can refer to them later. - */ - idata->user[0] = 0; - strncat(idata->user, user_name, sizeof(idata->user) - 1); - idata->uid = pwd->pw_uid; - idata->gid = pwd->pw_gid; - - /* Fill in RUSER too */ - retval = pam_get_item(idata->pamh, PAM_RUSER, (void*) &user_name ); - if ( user_name != NULL && retval == PAM_SUCCESS && user_name[0] != '\0' ) { - strncat(idata->ruser, user_name, sizeof(idata->ruser) - 1); - pwd = pam_modutil_getpwnam(idata->pamh, user_name); - } else { - pwd = pam_modutil_getpwuid(idata->pamh, getuid()); - } - if (!pwd) { - pam_syslog(idata->pamh, LOG_ERR, "user unknown '%s'", user_name); - return PAM_USER_UNKNOWN; - } - user_name = pwd->pw_name; - - idata->ruser[0] = 0; - strncat(idata->ruser, user_name, sizeof(idata->ruser) - 1); - idata->ruid = pwd->pw_uid; - - return PAM_SUCCESS; -} - -/* - * Entry point from pam_open_session call. - */ -PAM_EXTERN int pam_sm_open_session(pam_handle_t *pamh, int flags UNUSED, - int argc, const char **argv) -{ - int i, retval; - struct instance_data idata; - enum unmnt_op unmnt = NO_UNMNT; - - /* init instance data */ - idata.flags = 0; - idata.polydirs_ptr = NULL; - idata.pamh = pamh; -#ifdef WITH_SELINUX - if (is_selinux_enabled()) - idata.flags |= PAMNS_SELINUX_ENABLED; - if (ctxt_based_inst_needed()) - idata.flags |= PAMNS_CTXT_BASED_INST; -#endif - - /* Parse arguments. */ - for (i = 0; i < argc; i++) { - if (strcmp(argv[i], "debug") == 0) - idata.flags |= PAMNS_DEBUG; - if (strcmp(argv[i], "gen_hash") == 0) - idata.flags |= PAMNS_GEN_HASH; - if (strcmp(argv[i], "ignore_config_error") == 0) - idata.flags |= PAMNS_IGN_CONFIG_ERR; - if (strcmp(argv[i], "ignore_instance_parent_mode") == 0) - idata.flags |= PAMNS_IGN_INST_PARENT_MODE; - if (strcmp(argv[i], "use_current_context") == 0) { - idata.flags |= PAMNS_USE_CURRENT_CONTEXT; - idata.flags |= PAMNS_CTXT_BASED_INST; - } - if (strcmp(argv[i], "use_default_context") == 0) { - idata.flags |= PAMNS_USE_DEFAULT_CONTEXT; - idata.flags |= PAMNS_CTXT_BASED_INST; - } - if (strcmp(argv[i], "unmnt_remnt") == 0) - unmnt = UNMNT_REMNT; - if (strcmp(argv[i], "unmnt_only") == 0) - unmnt = UNMNT_ONLY; - if (strcmp(argv[i], "require_selinux") == 0) { - if (~(idata.flags & PAMNS_SELINUX_ENABLED)) { - pam_syslog(idata.pamh, LOG_ERR, - "selinux_required option given and selinux is disabled"); - return PAM_SESSION_ERR; - } - } - } - if (idata.flags & PAMNS_DEBUG) - pam_syslog(idata.pamh, LOG_DEBUG, "open_session - start"); - - retval = get_user_data(&idata); - if (retval != PAM_SUCCESS) - return retval; - - /* - * Parse namespace configuration file which lists directories to - * polyinstantiate, directory where instance directories are to - * be created and the method used for polyinstantiation. - */ - retval = parse_config_file(&idata); - if (retval != PAM_SUCCESS) { - del_polydir_list(idata.polydirs_ptr); - return PAM_SESSION_ERR; - } - - if (idata.polydirs_ptr) { - retval = setup_namespace(&idata, unmnt); - if (idata.flags & PAMNS_DEBUG) { - if (retval) - pam_syslog(idata.pamh, LOG_DEBUG, - "namespace setup failed for pid %d", getpid()); - else - pam_syslog(idata.pamh, LOG_DEBUG, - "namespace setup ok for pid %d", getpid()); - } - } else if (idata.flags & PAMNS_DEBUG) - pam_syslog(idata.pamh, LOG_DEBUG, "Nothing to polyinstantiate"); - - if (retval != PAM_SUCCESS) - del_polydir_list(idata.polydirs_ptr); - return retval; -} - - -/* - * Entry point from pam_close_session call. - */ -PAM_EXTERN int pam_sm_close_session(pam_handle_t *pamh, int flags UNUSED, - int argc, const char **argv) -{ - int i, retval; - struct instance_data idata; - void *polyptr; - - /* init instance data */ - idata.flags = 0; - idata.polydirs_ptr = NULL; - idata.pamh = pamh; -#ifdef WITH_SELINUX - if (is_selinux_enabled()) - idata.flags |= PAMNS_SELINUX_ENABLED; - if (ctxt_based_inst_needed()) - idata.flags |= PAMNS_CTXT_BASED_INST; -#endif - - /* Parse arguments. */ - for (i = 0; i < argc; i++) { - if (strcmp(argv[i], "debug") == 0) - idata.flags |= PAMNS_DEBUG; - if (strcmp(argv[i], "ignore_config_error") == 0) - idata.flags |= PAMNS_IGN_CONFIG_ERR; - if (strcmp(argv[i], "no_unmount_on_close") == 0) - idata.flags |= PAMNS_NO_UNMOUNT_ON_CLOSE; - } - - if (idata.flags & PAMNS_DEBUG) - pam_syslog(idata.pamh, LOG_DEBUG, "close_session - start"); - - /* - * For certain trusted programs such as newrole, open session - * is called from a child process while the parent perfoms - * close session and pam end functions. For these commands - * pam_close_session should not perform the unmount of the - * polyinstantiatied directory because it will result in - * undoing of parents polyinstantiatiaion. These commands - * will invoke pam_namespace with the "no_unmount_on_close" - * argument. - */ - if (idata.flags & PAMNS_NO_UNMOUNT_ON_CLOSE) { - if (idata.flags & PAMNS_DEBUG) - pam_syslog(idata.pamh, LOG_DEBUG, "close_session - sucessful"); - return PAM_SUCCESS; - } - - retval = get_user_data(&idata); - if (retval != PAM_SUCCESS) - return retval; - - retval = pam_get_data(idata.pamh, NAMESPACE_POLYDIR_DATA, (const void **)&polyptr); - if (retval != PAM_SUCCESS || polyptr == NULL) - /* nothing to reset */ - return PAM_SUCCESS; - - idata.polydirs_ptr = polyptr; - - if (idata.flags & PAMNS_DEBUG) - pam_syslog(idata.pamh, LOG_DEBUG, "Resetting namespace for pid %d", - getpid()); - - retval = orig_namespace(&idata); - if (idata.flags & PAMNS_DEBUG) { - if (retval) - pam_syslog(idata.pamh, LOG_DEBUG, - "resetting namespace failed for pid %d", getpid()); - else - pam_syslog(idata.pamh, LOG_DEBUG, - "resetting namespace ok for pid %d", getpid()); - } - - pam_set_data(idata.pamh, NAMESPACE_POLYDIR_DATA, NULL, NULL); - - return PAM_SUCCESS; -} - -#ifdef PAM_STATIC - -/* static module data */ - -struct pam_module _pam_namespace_modstruct = { - "pam_namespace", - NULL, - NULL, - NULL, - pam_sm_open_session, - pam_sm_close_session, - NULL -}; -#endif diff --git a/modules/pam_namespace/pam_namespace.h b/modules/pam_namespace/pam_namespace.h deleted file mode 100644 index bfc0da17..00000000 --- a/modules/pam_namespace/pam_namespace.h +++ /dev/null @@ -1,168 +0,0 @@ -/****************************************************************************** - * A module for Linux-PAM that will set the default namespace after - * establishing a session via PAM. - * - * (C) Copyright IBM Corporation 2005 - * (C) Copyright Red Hat 2006 - * All Rights Reserved. - * - * Written by: Janak Desai <janak@us.ibm.com> - * With Revisions by: Steve Grubb <sgrubb@redhat.com> - * Derived from a namespace setup patch by Chad Sellers <cdselle@tycho.nsa.gov> - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * on the rights to use, copy, modify, merge, publish, distribute, sub - * license, and/or sell copies of the Software, and to permit persons to whom - * the Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL - * IBM AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -#if !(defined(linux)) -#error THIS CODE IS KNOWN TO WORK ONLY ON LINUX !!! -#endif - -#include "config.h" - -#include <stdio.h> -#include <stdio_ext.h> -#include <unistd.h> -#include <string.h> -#include <ctype.h> -#include <stdlib.h> -#include <errno.h> -#include <syslog.h> -#include <dlfcn.h> -#include <stdarg.h> -#include <pwd.h> -#include <grp.h> -#include <limits.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <sys/resource.h> -#include <sys/mount.h> -#include <sys/wait.h> -#include <libgen.h> -#include <fcntl.h> -#include <sched.h> -#include <glob.h> -#include <locale.h> -#include "security/pam_modules.h" -#include "security/pam_modutil.h" -#include "security/pam_ext.h" -#include "md5.h" - -#ifdef WITH_SELINUX -#include <selinux/selinux.h> -#include <selinux/get_context_list.h> -#include <selinux/context.h> -#endif - -#ifndef CLONE_NEWNS -#define CLONE_NEWNS 0x00020000 /* Flag to create new namespace */ -#endif - -/* - * Module defines - */ -#ifndef SECURECONF_DIR -#define SECURECONF_DIR "/etc/security/" -#endif - -#define PAM_NAMESPACE_CONFIG (SECURECONF_DIR "namespace.conf") -#define NAMESPACE_INIT_SCRIPT (SECURECONF_DIR "namespace.init") -#define NAMESPACE_D_DIR (SECURECONF_DIR "namespace.d/") -#define NAMESPACE_D_GLOB (SECURECONF_DIR "namespace.d/*.conf") - -/* module flags */ -#define PAMNS_DEBUG 0x00000100 /* Running in debug mode */ -#define PAMNS_SELINUX_ENABLED 0x00000400 /* SELinux is enabled */ -#define PAMNS_CTXT_BASED_INST 0x00000800 /* Context based instance needed */ -#define PAMNS_GEN_HASH 0x00002000 /* Generate md5 hash for inst names */ -#define PAMNS_IGN_CONFIG_ERR 0x00004000 /* Ignore format error in conf file */ -#define PAMNS_IGN_INST_PARENT_MODE 0x00008000 /* Ignore instance parent mode */ -#define PAMNS_NO_UNMOUNT_ON_CLOSE 0x00010000 /* no unmount at session close */ -#define PAMNS_USE_CURRENT_CONTEXT 0x00020000 /* use getcon instead of getexeccon */ -#define PAMNS_USE_DEFAULT_CONTEXT 0x00040000 /* use get_default_context instead of getexeccon */ - -/* polydir flags */ -#define POLYDIR_EXCLUSIVE 0x00000001 /* polyinstatiate exclusively for override uids */ -#define POLYDIR_CREATE 0x00000002 /* create the polydir */ -#define POLYDIR_NOINIT 0x00000004 /* no init script */ -#define POLYDIR_SHARED 0x00000008 /* share context/level instances among users */ -#define POLYDIR_ISCRIPT 0x00000010 /* non default init script */ - - -#define NAMESPACE_MAX_DIR_LEN 80 -#define NAMESPACE_POLYDIR_DATA "pam_namespace:polydir_data" - -/* - * Polyinstantiation method options, based on user, security context - * or both - */ -enum polymethod { - NONE, - USER, - CONTEXT, - LEVEL, - TMPDIR, - TMPFS -}; - -/* - * Depending on the application using this namespace module, we - * may need to unmount priviously bind mounted instance directory. - * Applications such as login and sshd, that establish a new - * session unmount of instance directory is not needed. For applications - * such as su and newrole, that switch the identity, this module - * has to unmount previous instance directory first and re-mount - * based on the new indentity. For other trusted applications that - * just want to undo polyinstantiation, only unmount of previous - * instance directory is needed. - */ -enum unmnt_op { - NO_UNMNT, - UNMNT_REMNT, - UNMNT_ONLY, -}; - -/* - * Structure that holds information about a directory to polyinstantiate - */ -struct polydir_s { - char dir[PATH_MAX]; /* directory to polyinstantiate */ - char rdir[PATH_MAX]; /* directory to unmount (based on RUSER) */ - char instance_prefix[PATH_MAX]; /* prefix for instance dir path name */ - enum polymethod method; /* method used to polyinstantiate */ - unsigned int num_uids; /* number of override uids */ - uid_t *uid; /* list of override uids */ - unsigned int flags; /* polydir flags */ - char *init_script; /* path to init script */ - uid_t owner; /* user which should own the polydir */ - gid_t group; /* group which should own the polydir */ - mode_t mode; /* mode of the polydir */ - struct polydir_s *next; /* pointer to the next polydir entry */ -}; - -struct instance_data { - pam_handle_t *pamh; /* The pam handle for this instance */ - struct polydir_s *polydirs_ptr; /* The linked list pointer */ - char user[LOGIN_NAME_MAX]; /* User name */ - char ruser[LOGIN_NAME_MAX]; /* Requesting user name */ - uid_t uid; /* The uid of the user */ - gid_t gid; /* The gid of the user's primary group */ - uid_t ruid; /* The uid of the requesting user */ - unsigned long flags; /* Flags for debug, selinux etc */ -}; diff --git a/modules/pam_namespace/tst-pam_namespace b/modules/pam_namespace/tst-pam_namespace deleted file mode 100755 index c929dfcf..00000000 --- a/modules/pam_namespace/tst-pam_namespace +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/sh -../../tests/tst-dlopen .libs/pam_namespace.so diff --git a/modules/pam_nologin/.cvsignore b/modules/pam_nologin/.cvsignore deleted file mode 100644 index f9fb15b5..00000000 --- a/modules/pam_nologin/.cvsignore +++ /dev/null @@ -1,8 +0,0 @@ -*.la -*.lo -.deps -.libs -Makefile -Makefile.in -README -pam_nologin.8 diff --git a/modules/pam_nologin/Makefile.am b/modules/pam_nologin/Makefile.am deleted file mode 100644 index 02840dde..00000000 --- a/modules/pam_nologin/Makefile.am +++ /dev/null @@ -1,31 +0,0 @@ -# -# Copyright (c) 2005, 2006 Thorsten Kukuk <kukuk@suse.de> -# - -CLEANFILES = *~ - -EXTRA_DIST = README $(MANS) $(XMLS) tst-pam_nologin - -TESTS = tst-pam_nologin - -man_MANS = pam_nologin.8 -XMLS = README.xml pam_nologin.8.xml - -securelibdir = $(SECUREDIR) -secureconfdir = $(SCONFIGDIR) - -AM_CFLAGS = -I$(top_srcdir)/libpam/include -I$(top_srcdir)/libpamc/include -AM_LDFLAGS = -no-undefined -avoid-version -module -if HAVE_VERSIONING - AM_LDFLAGS += -Wl,--version-script=$(srcdir)/../modules.map -endif - -securelib_LTLIBRARIES = pam_nologin.la -pam_nologin_la_LIBADD = -L$(top_builddir)/libpam -lpam - -if ENABLE_REGENERATE_MAN -noinst_DATA = README -README: pam_nologin.8.xml --include $(top_srcdir)/Make.xml.rules -endif - diff --git a/modules/pam_nologin/README.xml b/modules/pam_nologin/README.xml deleted file mode 100644 index bc0808e7..00000000 --- a/modules/pam_nologin/README.xml +++ /dev/null @@ -1,46 +0,0 @@ -<?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_nologin.8.xml"> ---> -]> - -<article> - - <articleinfo> - - <title> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" - href="pam_nologin.8.xml" xpointer='xpointer(//refnamediv[@id = "pam_nologin-name"]/*)'/> - </title> - - </articleinfo> - - <section> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" - href="pam_nologin.8.xml" xpointer='xpointer(//refsect1[@id = "pam_nologin-description"]/*)'/> - </section> - - <section> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" - href="pam_nologin.8.xml" xpointer='xpointer(//refsect1[@id = "pam_nologin-options"]/*)'/> - </section> - - <section> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" - href="pam_nologin.8.xml" xpointer='xpointer(//refsect1[@id = "pam_nologin-examples"]/*)'/> - </section> - - <section> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" - href="pam_nologin.8.xml" xpointer='xpointer(//refsect1[@id = "pam_nologin-note"]/*)'/> - </section> - - <section> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" - href="pam_nologin.8.xml" xpointer='xpointer(//refsect1[@id = "pam_nologin-author"]/*)'/> - </section> - -</article> diff --git a/modules/pam_nologin/pam_nologin.8.xml b/modules/pam_nologin/pam_nologin.8.xml deleted file mode 100644 index 9710df9d..00000000 --- a/modules/pam_nologin/pam_nologin.8.xml +++ /dev/null @@ -1,174 +0,0 @@ -<?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_nologin"> - - <refmeta> - <refentrytitle>pam_nologin</refentrytitle> - <manvolnum>8</manvolnum> - <refmiscinfo class="sectdesc">Linux-PAM Manual</refmiscinfo> - </refmeta> - - <refnamediv id="pam_nologin-name"> - <refname>pam_nologin</refname> - <refpurpose>Prevent non-root users from login</refpurpose> - </refnamediv> - - <refsynopsisdiv> - <cmdsynopsis id="pam_nologin-cmdsynopsis"> - <command>pam_nologin.so</command> - <arg choice="opt"> - file=<replaceable>/path/nologin</replaceable> - </arg> - <arg choice="opt"> - successok - </arg> - </cmdsynopsis> - </refsynopsisdiv> - - <refsect1 id="pam_nologin-description"> - - <title>DESCRIPTION</title> - - <para> - pam_nologin is a PAM module that prevents users from logging into - the system when <filename>/etc/nologin</filename> exists. The contents - of the <filename>/etc/nologin</filename> file are displayed to the - user. The pam_nologin module has no effect on the root user's ability - to log in. - </para> - </refsect1> - - <refsect1 id="pam_nologin-options"> - - <title>OPTIONS</title> - <variablelist> - <varlistentry> - <term> - <option>file=<replaceable>/path/nologin</replaceable></option> - </term> - <listitem> - <para> - Use this file instead the default - <filename>/etc/nologin</filename>. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <option>successok</option> - </term> - <listitem> - <para> - Return PAM_SUCCESS if no file exists, the default is PAM_IGNORE. - </para> - </listitem> - </varlistentry> - </variablelist> - </refsect1> - - <refsect1 id="pam_nologin-services"> - <title>MODULE SERVICES PROVIDED</title> - <para> - The <option>auth</option> and <option>acct</option> services are - supported. - </para> - </refsect1> - - <refsect1 id='pam_nologin-return_values'> - <title>RETURN VALUES</title> - <variablelist> - <varlistentry> - <term>PAM_AUTH_ERR</term> - <listitem> - <para> - The user is not root and <filename>/etc/nologin</filename> - exists, so the user is not permitted to log in. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term>PAM_BUF_ERR</term> - <listitem> - <para>Memory buffer error.</para> - </listitem> - </varlistentry> - <varlistentry> - <term>PAM_IGNORE</term> - <listitem> - <para> - This is the default return value. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term>PAM_SUCCESS</term> - <listitem> - <para> - Success: either the user is root or the - <filename>/etc/nologin</filename> file does not exist. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term>PAM_USER_UNKNOWN</term> - <listitem> - <para> - User not known to the underlying authentication module. - </para> - </listitem> - </varlistentry> - </variablelist> - </refsect1> - - <refsect1 id='pam_nologin-examples'> - <title>EXAMPLES</title> - <para> - The suggested usage for <filename>/etc/pam.d/login</filename> is: - <programlisting> -auth required pam_nologin.so - </programlisting> - </para> - </refsect1> - <refsect1 id='pam_nologin-note'> - <title>NOTES</title> - <para> - In order to make this module effective, all login methods should be - secured by it. It should be used as a <emphasis>required</emphasis> - method listed before any <emphasis>sufficient</emphasis> methods in - order to get standard Unix nologin semantics. Note, the use of - <option>successok</option> module argument causes the module to - return <emphasis>PAM_SUCCESS</emphasis> and as such would break - such a configuration - failing <emphasis>sufficient</emphasis> modules - would lead to a successful login because the nologin module - <emphasis>succeeded</emphasis>. - </para> - </refsect1> - - <refsect1 id='pam_nologin-see_also'> - <title>SEE ALSO</title> - <para> - <citerefentry> - <refentrytitle>nologin</refentrytitle><manvolnum>5</manvolnum> - </citerefentry>, - <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_nologin-author'> - <title>AUTHOR</title> - <para> - pam_nologin was written by Michael K. Johnson <johnsonm@redhat.com>. - </para> - </refsect1> - -</refentry> diff --git a/modules/pam_nologin/pam_nologin.c b/modules/pam_nologin/pam_nologin.c deleted file mode 100644 index 54ecc82b..00000000 --- a/modules/pam_nologin/pam_nologin.c +++ /dev/null @@ -1,180 +0,0 @@ -/* pam_nologin module */ - -/* - * $Id$ - * - * Written by Michael K. Johnson <johnsonm@redhat.com> 1996/10/24 - * - */ - -#include "config.h" - -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <fcntl.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <syslog.h> -#include <pwd.h> - -#include <security/_pam_macros.h> -/* - * here, we make a definition for the externally accessible function - * in this file (this definition is required for static a module - * but strongly encouraged generally) it is used to instruct the - * modules include file to define the function prototypes. - */ - -#define PAM_SM_AUTH -#define PAM_SM_ACCOUNT - -#include <security/pam_modules.h> -#include <security/pam_modutil.h> -#include <security/pam_ext.h> - -/* - * parse some command line options - */ -struct opt_s { - int retval_when_nofile; - const char *nologin_file; -}; - -static void -parse_args(pam_handle_t *pamh, int argc, const char **argv, struct opt_s *opts) -{ - int i; - - memset(opts, 0, sizeof(*opts)); - - opts->retval_when_nofile = PAM_IGNORE; - opts->nologin_file = "/etc/nologin"; - - for (i=0; i<argc; ++i) { - if (!strcmp("successok", argv[i])) { - opts->retval_when_nofile = PAM_SUCCESS; - } else if (!strncmp("file=", argv[i], 5)) { - opts->nologin_file = argv[i] + 5; - } else { - pam_syslog(pamh, LOG_ERR, "unknown option: %s", argv[i]); - } - } -} - -/* - * do the meat of the work for this module - */ - -static int perform_check(pam_handle_t *pamh, struct opt_s *opts) -{ - const char *username; - int retval = opts->retval_when_nofile; - int fd; - - if ((pam_get_user(pamh, &username, NULL) != PAM_SUCCESS) || !username) { - pam_syslog(pamh, LOG_WARNING, "cannot determine username"); - return PAM_USER_UNKNOWN; - } - - if ((fd = open(opts->nologin_file, O_RDONLY, 0)) >= 0) { - - char *mtmp=NULL; - int msg_style = PAM_TEXT_INFO; - struct passwd *user_pwd; - struct stat st; - - user_pwd = pam_modutil_getpwnam(pamh, username); - if (user_pwd == NULL) { - retval = PAM_USER_UNKNOWN; - msg_style = PAM_ERROR_MSG; - } else if (user_pwd->pw_uid) { - retval = PAM_AUTH_ERR; - msg_style = PAM_ERROR_MSG; - } - - /* fill in message buffer with contents of /etc/nologin */ - if (fstat(fd, &st) < 0) { - /* give up trying to display message */ - goto clean_up_fd; - } - - mtmp = malloc(st.st_size+1); - if (!mtmp) { - pam_syslog(pamh, LOG_ERR, "out of memory"); - retval = PAM_BUF_ERR; - goto clean_up_fd; - } - - if (pam_modutil_read(fd, mtmp, st.st_size) == st.st_size) { - mtmp[st.st_size] = '\0'; - (void) pam_prompt (pamh, msg_style, NULL, "%s", mtmp); - } - else - retval = PAM_SYSTEM_ERR; - - free(mtmp); - - clean_up_fd: - - close(fd); - } - - return retval; -} - -/* --- authentication management functions --- */ - -PAM_EXTERN int -pam_sm_authenticate (pam_handle_t *pamh, int flags UNUSED, - int argc, const char **argv) -{ - struct opt_s opts; - - parse_args(pamh, argc, argv, &opts); - - return perform_check(pamh, &opts); -} - -PAM_EXTERN int -pam_sm_setcred (pam_handle_t *pamh UNUSED, int flags UNUSED, - int argc, const char **argv) -{ - struct opt_s opts; - - parse_args(pamh, argc, argv, &opts); - - return opts.retval_when_nofile; -} - -/* --- account management function --- */ - -PAM_EXTERN int -pam_sm_acct_mgmt(pam_handle_t *pamh, int flags UNUSED, - int argc, const char **argv) -{ - struct opt_s opts; - - parse_args(pamh, argc, argv, &opts); - - return perform_check(pamh, &opts); -} - - -#ifdef PAM_STATIC - -/* static module data */ - -struct pam_module _pam_nologin_modstruct = { - "pam_nologin", - pam_sm_authenticate, - pam_sm_setcred, - pam_sm_acct_mgmt, - NULL, - NULL, - NULL, -}; - -#endif /* PAM_STATIC */ - -/* end of module definition */ diff --git a/modules/pam_nologin/tst-pam_nologin b/modules/pam_nologin/tst-pam_nologin deleted file mode 100755 index caa91b67..00000000 --- a/modules/pam_nologin/tst-pam_nologin +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/sh -../../tests/tst-dlopen .libs/pam_nologin.so diff --git a/modules/pam_permit/.cvsignore b/modules/pam_permit/.cvsignore deleted file mode 100644 index 5406ac33..00000000 --- a/modules/pam_permit/.cvsignore +++ /dev/null @@ -1,8 +0,0 @@ -*.la -*.lo -.deps -.libs -Makefile -Makefile.in -README -pam_permit.8 diff --git a/modules/pam_permit/Makefile.am b/modules/pam_permit/Makefile.am deleted file mode 100644 index aa6db7a1..00000000 --- a/modules/pam_permit/Makefile.am +++ /dev/null @@ -1,31 +0,0 @@ -# -# Copyright (c) 2005, 2006 Thorsten Kukuk <kukuk@suse.de> -# - -CLEANFILES = *~ - -EXTRA_DIST = README $(MANS) $(XMLS) tst-pam_permit - -man_MANS = pam_permit.8 -XMLS = README.xml pam_permit.8.xml - -TESTS = tst-pam_permit - -securelibdir = $(SECUREDIR) -secureconfdir = $(SCONFIGDIR) - -AM_CFLAGS = -I$(top_srcdir)/libpam/include -I$(top_srcdir)/libpamc/include -AM_LDFLAGS = -no-undefined -avoid-version -module -if HAVE_VERSIONING - AM_LDFLAGS += -Wl,--version-script=$(srcdir)/../modules.map -endif - -securelib_LTLIBRARIES = pam_permit.la -pam_permit_la_LIBADD = -L$(top_builddir)/libpam -lpam - -if ENABLE_REGENERATE_MAN -noinst_DATA = README -README: pam_permit.8.xml --include $(top_srcdir)/Make.xml.rules -endif - diff --git a/modules/pam_permit/README.xml b/modules/pam_permit/README.xml deleted file mode 100644 index acb38b51..00000000 --- a/modules/pam_permit/README.xml +++ /dev/null @@ -1,41 +0,0 @@ -<?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_permit.8.xml"> ---> -]> - -<article> - - <articleinfo> - - <title> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" - href="pam_permit.8.xml" xpointer='xpointer(//refnamediv[@id = "pam_permit-name"]/*)'/> - </title> - - </articleinfo> - - <section> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" - href="pam_permit.8.xml" xpointer='xpointer(//refsect1[@id = "pam_permit-description"]/*)'/> - </section> - - <section> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" - href="pam_permit.8.xml" xpointer='xpointer(//refsect1[@id = "pam_permit-options"]/*)'/> - </section> - - <section> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" - href="pam_permit.8.xml" xpointer='xpointer(//refsect1[@id = "pam_permit-examples"]/*)'/> - </section> - - <section> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" - href="pam_permit.8.xml" xpointer='xpointer(//refsect1[@id = "pam_permit-author"]/*)'/> - </section> - -</article> diff --git a/modules/pam_permit/pam_permit.8.xml b/modules/pam_permit/pam_permit.8.xml deleted file mode 100644 index 4db7a963..00000000 --- a/modules/pam_permit/pam_permit.8.xml +++ /dev/null @@ -1,105 +0,0 @@ -<?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_permit"> - - <refmeta> - <refentrytitle>pam_permit</refentrytitle> - <manvolnum>8</manvolnum> - <refmiscinfo class="sectdesc">Linux-PAM Manual</refmiscinfo> - </refmeta> - - <refnamediv id="pam_permit-name"> - <refname>pam_permit</refname> - <refpurpose>The promiscuous module</refpurpose> - </refnamediv> - - <refsynopsisdiv> - <cmdsynopsis id="pam_permit-cmdsynopsis"> - <command>pam_permit.so</command> - </cmdsynopsis> - </refsynopsisdiv> - - <refsect1 id="pam_permit-description"> - - <title>DESCRIPTION</title> - - <para> - pam_permit is a PAM module that always permit access. It does - nothing else. - </para> - <para> - In the case of authentication, the user's name will be set to - <emphasis>nobody</emphasis> if the application didn't set one. - Many applications and PAM modules become confused if this name - is unknown. - </para> - <para> - This module is very dangerous. It should be used with extreme - caution. - </para> - </refsect1> - - <refsect1 id="pam_permit-options"> - - <title>OPTIONS</title> - <para> This module does not recognise any options.</para> - </refsect1> - - <refsect1 id="pam_permit-services"> - <title>MODULE SERVICES PROVIDED</title> - <para> - The services <option>auth</option>, <option>account</option>, - <option>password</option> and <option>session</option> are supported. - </para> - </refsect1> - - <refsect1 id='pam_permit-return_values'> - <title>RETURN VALUES</title> - <variablelist> - <varlistentry> - <term>PAM_SUCCESS</term> - <listitem> - <para> - This module always returns this value. - </para> - </listitem> - </varlistentry> - </variablelist> - </refsect1> - - <refsect1 id='pam_permit-examples'> - <title>EXAMPLES</title> - <para> - Add this line to your other login entries to disable account - management, but continue to permit users to log in. - <programlisting> -account required pam_permit.so - </programlisting> - </para> - </refsect1> - - <refsect1 id='pam_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_permit-author'> - <title>AUTHOR</title> - <para> - pam_permit was written by Andrew G. Morgan, <morgan@kernel.org>. - </para> - </refsect1> - -</refentry> diff --git a/modules/pam_permit/pam_permit.c b/modules/pam_permit/pam_permit.c deleted file mode 100644 index e4539b03..00000000 --- a/modules/pam_permit/pam_permit.c +++ /dev/null @@ -1,116 +0,0 @@ -/* pam_permit module */ - -/* - * $Id$ - * - * Written by Andrew Morgan <morgan@parc.power.net> 1996/3/11 - * - */ - -#include "config.h" - -#define DEFAULT_USER "nobody" - -#include <stdio.h> - -/* - * here, we make definitions for the externally accessible functions - * in this file (these definitions are required for static modules - * but strongly encouraged generally) they are used to instruct the - * modules include file to define their prototypes. - */ - -#define PAM_SM_AUTH -#define PAM_SM_ACCOUNT -#define PAM_SM_SESSION -#define PAM_SM_PASSWORD - -#include <security/pam_modules.h> -#include <security/_pam_macros.h> - -/* --- authentication management functions --- */ - -PAM_EXTERN int -pam_sm_authenticate(pam_handle_t *pamh, int flags UNUSED, - int argc UNUSED, const char **argv UNUSED) -{ - int retval; - const char *user=NULL; - - /* - * authentication requires we know who the user wants to be - */ - retval = pam_get_user(pamh, &user, NULL); - if (retval != PAM_SUCCESS) { - D(("get user returned error: %s", pam_strerror(pamh,retval))); - return retval; - } - if (user == NULL || *user == '\0') { - D(("username not known")); - retval = pam_set_item(pamh, PAM_USER, (const void *) DEFAULT_USER); - if (retval != PAM_SUCCESS) - return PAM_USER_UNKNOWN; - } - user = NULL; /* clean up */ - - return PAM_SUCCESS; -} - -PAM_EXTERN int -pam_sm_setcred(pam_handle_t *pamh UNUSED, int flags UNUSED, - int argc UNUSED, const char **argv UNUSED) -{ - return PAM_SUCCESS; -} - -/* --- account management functions --- */ - -PAM_EXTERN int -pam_sm_acct_mgmt(pam_handle_t *pamh UNUSED, int flags UNUSED, - int argc UNUSED, const char **argv UNUSED) -{ - return PAM_SUCCESS; -} - -/* --- password management --- */ - -PAM_EXTERN int -pam_sm_chauthtok(pam_handle_t *pamh UNUSED, int flags UNUSED, - int argc UNUSED, const char **argv UNUSED) -{ - return PAM_SUCCESS; -} - -/* --- session management --- */ - -PAM_EXTERN int -pam_sm_open_session(pam_handle_t *pamh UNUSED, int flags UNUSED, - int argc UNUSED, const char **argv UNUSED) -{ - return PAM_SUCCESS; -} - -PAM_EXTERN int -pam_sm_close_session(pam_handle_t *pamh UNUSED, int flags UNUSED, - int argc UNUSED, const char **argv UNUSED) -{ - return PAM_SUCCESS; -} - -/* end of module definition */ - -#ifdef PAM_STATIC - -/* static module data */ - -struct pam_module _pam_permit_modstruct = { - "pam_permit", - pam_sm_authenticate, - pam_sm_setcred, - pam_sm_acct_mgmt, - pam_sm_open_session, - pam_sm_close_session, - pam_sm_chauthtok -}; - -#endif diff --git a/modules/pam_permit/tst-pam_permit b/modules/pam_permit/tst-pam_permit deleted file mode 100755 index 8adb427f..00000000 --- a/modules/pam_permit/tst-pam_permit +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/sh -../../tests/tst-dlopen .libs/pam_permit.so diff --git a/modules/pam_rhosts/.cvsignore b/modules/pam_rhosts/.cvsignore deleted file mode 100644 index 8f807d67..00000000 --- a/modules/pam_rhosts/.cvsignore +++ /dev/null @@ -1,8 +0,0 @@ -*.la -*.lo -.deps -.libs -Makefile -Makefile.in -README -pam_rhosts.8 diff --git a/modules/pam_rhosts/Makefile.am b/modules/pam_rhosts/Makefile.am deleted file mode 100644 index 547ad621..00000000 --- a/modules/pam_rhosts/Makefile.am +++ /dev/null @@ -1,32 +0,0 @@ -# -# Copyright (c) 2005, 2006, 2008 Thorsten Kukuk <kukuk@suse.de> -# - -CLEANFILES = *~ - -EXTRA_DIST = README $(MANS) $(XMLS) tst-pam_rhosts - -TESTS = tst-pam_rhosts - -man_MANS = pam_rhosts.8 - -XMLS = README.xml pam_rhosts.8.xml - -securelibdir = $(SECUREDIR) -secureconfdir = $(SCONFIGDIR) - -AM_CFLAGS = -I$(top_srcdir)/libpam/include -I$(top_srcdir)/libpamc/include -AM_LDFLAGS = -no-undefined -avoid-version -module -if HAVE_VERSIONING - AM_LDFLAGS += -Wl,--version-script=$(srcdir)/../modules.map -endif - -securelib_LTLIBRARIES = pam_rhosts.la -pam_rhosts_la_LIBADD = -L$(top_builddir)/libpam -lpam - -if ENABLE_REGENERATE_MAN -noinst_DATA = README -README: pam_rhosts.8.xml --include $(top_srcdir)/Make.xml.rules -endif - diff --git a/modules/pam_rhosts/README.xml b/modules/pam_rhosts/README.xml deleted file mode 100644 index 5d3307e7..00000000 --- a/modules/pam_rhosts/README.xml +++ /dev/null @@ -1,41 +0,0 @@ -<?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_rhosts.8.xml"> ---> -]> - -<article> - - <articleinfo> - - <title> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" - href="pam_rhosts.8.xml" xpointer='xpointer(//refnamediv[@id = "pam_rhosts-name"]/*)'/> - </title> - - </articleinfo> - - <section> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" - href="pam_rhosts.8.xml" xpointer='xpointer(//refsect1[@id = "pam_rhosts-description"]/*)'/> - </section> - - <section> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" - href="pam_rhosts.8.xml" xpointer='xpointer(//refsect1[@id = "pam_rhosts-options"]/*)'/> - </section> - - <section> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" - href="pam_rhosts.8.xml" xpointer='xpointer(//refsect1[@id = "pam_rhosts-examples"]/*)'/> - </section> - - <section> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" - href="pam_rhosts.8.xml" xpointer='xpointer(//refsect1[@id = "pam_rhosts-author"]/*)'/> - </section> - -</article> diff --git a/modules/pam_rhosts/pam_rhosts.8.xml b/modules/pam_rhosts/pam_rhosts.8.xml deleted file mode 100644 index e559f315..00000000 --- a/modules/pam_rhosts/pam_rhosts.8.xml +++ /dev/null @@ -1,171 +0,0 @@ -<?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_rhosts"> - - <refmeta> - <refentrytitle>pam_rhosts</refentrytitle> - <manvolnum>8</manvolnum> - <refmiscinfo class="sectdesc">Linux-PAM Manual</refmiscinfo> - </refmeta> - - <refnamediv id="pam_rhosts-name"> - <refname>pam_rhosts</refname> - <refpurpose>The rhosts PAM module</refpurpose> - </refnamediv> - - <refsynopsisdiv> - <cmdsynopsis id="pam_rhosts-cmdsynopsis"> - <command>pam_rhosts.so</command> - </cmdsynopsis> - </refsynopsisdiv> - - <refsect1 id="pam_rhosts-description"> - - <title>DESCRIPTION</title> - - <para> - This module performs the standard network authentication for services, - as used by traditional implementations of <command>rlogin</command> - and <command>rsh</command> etc. - </para> - <para> - The authentication mechanism of this module is based on the contents - of two files; <filename>/etc/hosts.equiv</filename> (or - and <filename>~/.rhosts</filename>. Firstly, hosts listed in the - former file are treated as equivalent to the localhost. Secondly, - entries in the user's own copy of the latter file is used to map - "<emphasis>remote-host remote-user</emphasis>" pairs to that user's - account on the current host. Access is granted to the user if their - host is present in <filename>/etc/hosts.equiv</filename> and their - remote account is identical to their local one, or if their remote - account has an entry in their personal configuration file. - </para> - <para> - The module authenticates a remote user (internally specified by the - item <parameter>PAM_RUSER</parameter> connecting from the remote - host (internally specified by the item <command>PAM_RHOST</command>). - Accordingly, for applications to be compatible this authentication - module they must set these items prior to calling - <function>pam_authenticate()</function>. The module is not capable - of independently probing the network connection for such information. - </para> - </refsect1> - - <refsect1 id="pam_rhosts-options"> - <title>OPTIONS</title> - <variablelist> - <varlistentry> - <term> - <option>debug</option> - </term> - <listitem> - <para> - Print debug information. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <option>silent</option> - </term> - <listitem> - <para> - Don't print informative messages. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <option>superuser=<replaceable>account</replaceable></option> - </term> - <listitem> - <para> - Handle <replaceable>account</replaceable> as root. - </para> - </listitem> - </varlistentry> - </variablelist> - </refsect1> - - <refsect1 id="pam_rhosts-services"> - <title>MODULE SERVICES PROVIDED</title> - <para> - Only the <option>auth</option> service is supported. - </para> - </refsect1> - - <refsect1 id='pam_rhosts-return_values'> - <title>RETURN VALUES</title> - <variablelist> - <varlistentry> - <term>PAM_AUTH_ERR</term> - <listitem> - <para> - The remote host, remote user name or the local user name - couldn't be determined or access was denied by - <filename>.rhosts</filename> file. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term>PAM_USER_UNKNOWN</term> - <listitem> - <para> - User is not known to system. - </para> - </listitem> - </varlistentry> - </variablelist> - </refsect1> - - <refsect1 id='pam_rhosts-examples'> - <title>EXAMPLES</title> - <para> - To grant a remote user access by <filename>/etc/hosts.equiv</filename> - or <filename>.rhosts</filename> for <command>rsh</command> add the - following lines to <filename>/etc/pam.d/rsh</filename>: - <programlisting> -#%PAM-1.0 -# -auth required pam_rhosts.so -auth required pam_nologin.so -auth required pam_env.so -auth required pam_unix.so - </programlisting> - </para> - </refsect1> - - <refsect1 id='pam_rhosts-see_also'> - <title>SEE ALSO</title> - <para> - <citerefentry> - <refentrytitle>rootok</refentrytitle><manvolnum>3</manvolnum> - </citerefentry>, - <citerefentry> - <refentrytitle>hosts.equiv</refentrytitle><manvolnum>5</manvolnum> - </citerefentry>, - <citerefentry> - <refentrytitle>rhosts</refentrytitle><manvolnum>5</manvolnum> - </citerefentry>, - <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_rhosts-author'> - <title>AUTHOR</title> - <para> - pam_rhosts was written by Thorsten Kukuk <kukuk@thkukuk.de> - </para> - </refsect1> - -</refentry> diff --git a/modules/pam_rhosts/pam_rhosts.c b/modules/pam_rhosts/pam_rhosts.c deleted file mode 100644 index 8e120614..00000000 --- a/modules/pam_rhosts/pam_rhosts.c +++ /dev/null @@ -1,155 +0,0 @@ -/* - * 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 <pwd.h> -#include <netdb.h> -#include <string.h> -#include <syslog.h> - -#define PAM_SM_AUTH /* only defines this management group */ - -#include <security/pam_modules.h> -#include <security/pam_modutil.h> -#include <security/pam_ext.h> - -PAM_EXTERN -int pam_sm_authenticate (pam_handle_t *pamh, int flags, int argc, - const char **argv) -{ - const char *luser = NULL; - const char *ruser = NULL, *rhost = NULL; - const char *opt_superuser = NULL; - const void *c_void; - int opt_debug = 0; - int opt_silent; - int as_root; - int retval; - - opt_silent = flags & PAM_SILENT; - - while (argc-- > 0) { - if (strcmp(*argv, "debug") == 0) - opt_debug = 1; - else if (strcmp (*argv, "silent") == 0 || strcmp(*argv, "suppress") == 0) - opt_silent = 1; - else if (strncmp(*argv, "superuser=", sizeof("superuser=")-1) == 0) - opt_superuser = *argv+sizeof("superuser=")-1; - else - pam_syslog(pamh, LOG_WARNING, "unrecognized option '%s'", *argv); - - ++argv; - } - - retval = pam_get_item (pamh, PAM_RHOST, &c_void); - if (retval != PAM_SUCCESS) { - pam_syslog(pamh, LOG_ERR, "could not get the remote host name"); - return retval; - } - rhost = c_void; - - retval = pam_get_item(pamh, PAM_RUSER, &c_void); - ruser = c_void; - if (retval != PAM_SUCCESS) { - pam_syslog(pamh, LOG_ERR, "could not get the remote username"); - return retval; - } - - retval = pam_get_user(pamh, &luser, NULL); - if (retval != PAM_SUCCESS) { - pam_syslog(pamh, LOG_ERR, "could not determine name of local user"); - return retval; - } - - if (rhost == NULL || ruser == NULL || luser == NULL) - return PAM_AUTH_ERR; - - if (opt_superuser && strcmp(opt_superuser, luser) == 0) - as_root = 1; - else { - struct passwd *lpwd; - - lpwd = pam_modutil_getpwnam(pamh, luser); - if (lpwd == NULL) { - if (opt_debug) - /* don't print by default, could be the users password */ - pam_syslog(pamh, LOG_DEBUG, - "user '%s' unknown to this system", luser); - return PAM_USER_UNKNOWN; - - } - as_root = (lpwd->pw_uid == 0); - } - -#ifdef HAVE_RUSEROK_AF - retval = ruserok_af (rhost, as_root, ruser, luser, PF_UNSPEC); -#else - retval = ruserok (rhost, as_root, ruser, luser); -#endif - if (retval != 0) { - if (!opt_silent || opt_debug) - pam_syslog(pamh, LOG_WARNING, "denied access to %s@%s as %s", - ruser, rhost, luser); - return PAM_AUTH_ERR; - } else { - if (!opt_silent || opt_debug) - pam_syslog(pamh, LOG_NOTICE, "allowed access to %s@%s as %s", - ruser, rhost, luser); - return PAM_SUCCESS; - } -} - - -PAM_EXTERN int -pam_sm_setcred (pam_handle_t *pamh UNUSED, int flags UNUSED, - int argc UNUSED, const char **argv UNUSED) -{ - return PAM_SUCCESS; -} - - -#ifdef PAM_STATIC - -/* static module data */ - -struct pam_module _pam_rhosts_modstruct = { - "pam_rhosts", - pam_sm_authenticate, - pam_sm_setcred, - NULL, - NULL, - NULL, - NULL, -}; - -#endif diff --git a/modules/pam_rhosts/tst-pam_rhosts b/modules/pam_rhosts/tst-pam_rhosts deleted file mode 100755 index 65e85a98..00000000 --- a/modules/pam_rhosts/tst-pam_rhosts +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/sh -../../tests/tst-dlopen .libs/pam_rhosts.so diff --git a/modules/pam_rootok/.cvsignore b/modules/pam_rootok/.cvsignore deleted file mode 100644 index 70776789..00000000 --- a/modules/pam_rootok/.cvsignore +++ /dev/null @@ -1,8 +0,0 @@ -*.la -*.lo -.deps -.libs -Makefile -Makefile.in -README -pam_rootok.8 diff --git a/modules/pam_rootok/Makefile.am b/modules/pam_rootok/Makefile.am deleted file mode 100644 index 54fe2720..00000000 --- a/modules/pam_rootok/Makefile.am +++ /dev/null @@ -1,33 +0,0 @@ -# -# Copyright (c) 2005, 2006 Thorsten Kukuk <kukuk@suse.de> -# - -CLEANFILES = *~ - -EXTRA_DIST = README $(MANS) $(XMLS) tst-pam_rootok - -man_MANS = pam_rootok.8 -XMLS = README.xml pam_rootok.8.xml - -TESTS = tst-pam_rootok - -securelibdir = $(SECUREDIR) -secureconfdir = $(SCONFIGDIR) - -AM_CFLAGS = -I$(top_srcdir)/libpam/include -I$(top_srcdir)/libpamc/include -if HAVE_LIBSELINUX -AM_CFLAGS += -DWITH_SELINUX -endif -AM_LDFLAGS = -no-undefined -avoid-version -module -if HAVE_VERSIONING - AM_LDFLAGS += -Wl,--version-script=$(srcdir)/../modules.map -endif - -securelib_LTLIBRARIES = pam_rootok.la -pam_rootok_la_LIBADD = -L$(top_builddir)/libpam -lpam @LIBSELINUX@ - -if ENABLE_REGENERATE_MAN -noinst_DATA = README -README: pam_rootok.8.xml --include $(top_srcdir)/Make.xml.rules -endif diff --git a/modules/pam_rootok/README.xml b/modules/pam_rootok/README.xml deleted file mode 100644 index 6fb58cd0..00000000 --- a/modules/pam_rootok/README.xml +++ /dev/null @@ -1,41 +0,0 @@ -<?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_rootok.8.xml"> ---> -]> - -<article> - - <articleinfo> - - <title> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" - href="pam_rootok.8.xml" xpointer='xpointer(//refnamediv[@id = "pam_rootok-name"]/*)'/> - </title> - - </articleinfo> - - <section> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" - href="pam_rootok.8.xml" xpointer='xpointer(//refsect1[@id = "pam_rootok-description"]/*)'/> - </section> - - <section> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" - href="pam_rootok.8.xml" xpointer='xpointer(//refsect1[@id = "pam_rootok-options"]/*)'/> - </section> - - <section> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" - href="pam_rootok.8.xml" xpointer='xpointer(//refsect1[@id = "pam_rootok-examples"]/*)'/> - </section> - - <section> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" - href="pam_rootok.8.xml" xpointer='xpointer(//refsect1[@id = "pam_rootok-author"]/*)'/> - </section> - -</article> diff --git a/modules/pam_rootok/pam_rootok.8.xml b/modules/pam_rootok/pam_rootok.8.xml deleted file mode 100644 index ec8dee43..00000000 --- a/modules/pam_rootok/pam_rootok.8.xml +++ /dev/null @@ -1,130 +0,0 @@ -<?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_rootok"> - - <refmeta> - <refentrytitle>pam_rootok</refentrytitle> - <manvolnum>8</manvolnum> - <refmiscinfo class="sectdesc">Linux-PAM Manual</refmiscinfo> - </refmeta> - - <refnamediv id="pam_rootok-name"> - <refname>pam_rootok</refname> - <refpurpose>Gain only root access</refpurpose> - </refnamediv> - - <refsynopsisdiv> - <cmdsynopsis id="pam_rootok-cmdsynopsis"> - <command>pam_rootok.so</command> - <arg choice="opt"> - debug - </arg> - </cmdsynopsis> - </refsynopsisdiv> - - <refsect1 id="pam_rootok-description"> - - <title>DESCRIPTION</title> - - <para> - pam_rootok is a PAM module that authenticates the user if their - <emphasis>UID</emphasis> is <emphasis>0</emphasis>. - Applications that are created setuid-root generally retain the - <emphasis>UID</emphasis> of the user but run with the authority - of an enhanced effective-UID. It is the real <emphasis>UID</emphasis> - that is checked. - </para> - </refsect1> - - <refsect1 id="pam_rootok-options"> - <title>OPTIONS</title> - <variablelist> - <varlistentry> - <term> - <option>debug</option> - </term> - <listitem> - <para> - Print debug information. - </para> - </listitem> - </varlistentry> - </variablelist> - </refsect1> - - <refsect1 id="pam_rootok-services"> - <title>MODULE SERVICES PROVIDED</title> - <para> - Only the <option>auth</option> service is supported. - </para> - </refsect1> - - <refsect1 id='pam_rootok-return_values'> - <title>RETURN VALUES</title> - <variablelist> - <varlistentry> - <term>PAM_SUCCESS</term> - <listitem> - <para> - The <emphasis>UID</emphasis> is <emphasis>0</emphasis>. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term>PAM_AUTH_ERR</term> - <listitem> - <para> - The <emphasis>UID</emphasis> is <emphasis remap='B'>not</emphasis> - <emphasis>0</emphasis>. - </para> - </listitem> - </varlistentry> - </variablelist> - </refsect1> - - <refsect1 id='pam_rootok-examples'> - <title>EXAMPLES</title> - <para> - In the case of the <citerefentry> - <refentrytitle>su</refentrytitle><manvolnum>1</manvolnum> - </citerefentry> application the historical usage is to - permit the superuser to adopt the identity of a lesser user - without the use of a password. To obtain this behavior with PAM - the following pair of lines are needed for the corresponding entry - in the <filename>/etc/pam.d/su</filename> configuration file: - <programlisting> -# su authentication. Root is granted access by default. -auth sufficient pam_rootok.so -auth required pam_unix.so - </programlisting> - </para> - </refsect1> - - <refsect1 id='pam_rootok-see_also'> - <title>SEE ALSO</title> - <para> - <citerefentry> - <refentrytitle>su</refentrytitle><manvolnum>1</manvolnum> - </citerefentry>, - <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_rootok-author'> - <title>AUTHOR</title> - <para> - pam_rootok was written by Andrew G. Morgan, <morgan@kernel.org>. - </para> - </refsect1> - -</refentry> diff --git a/modules/pam_rootok/pam_rootok.c b/modules/pam_rootok/pam_rootok.c deleted file mode 100644 index c5f6bb55..00000000 --- a/modules/pam_rootok/pam_rootok.c +++ /dev/null @@ -1,106 +0,0 @@ -/* pam_rootok module */ - -/* - * $Id$ - * - * Written by Andrew Morgan <morgan@linux.kernel.org> 1996/3/11 - */ - -#include "config.h" - -#include <stdio.h> -#include <unistd.h> -#include <syslog.h> -#include <stdarg.h> -#include <string.h> - -/* - * here, we make a definition for the externally accessible function - * in this file (this definition is required for static a module - * but strongly encouraged generally) it is used to instruct the - * modules include file to define the function prototypes. - */ - -#define PAM_SM_AUTH - -#include <security/pam_modules.h> -#include <security/pam_ext.h> - -#ifdef WITH_SELINUX -#include <selinux/selinux.h> -#include <selinux/av_permissions.h> -#endif - -/* argument parsing */ - -#define PAM_DEBUG_ARG 01 - -static int -_pam_parse (const pam_handle_t *pamh, int argc, const char **argv) -{ - int ctrl=0; - - /* step through arguments */ - for (ctrl=0; argc-- > 0; ++argv) { - - /* generic options */ - - if (!strcmp(*argv,"debug")) - ctrl |= PAM_DEBUG_ARG; - else { - pam_syslog(pamh, LOG_ERR, "unknown option: %s", *argv); - } - } - - return ctrl; -} - -/* --- authentication management functions (only) --- */ - -PAM_EXTERN int -pam_sm_authenticate (pam_handle_t *pamh, int flags UNUSED, - int argc, const char **argv) -{ - int ctrl; - int retval = PAM_AUTH_ERR; - - ctrl = _pam_parse(pamh, argc, argv); - if (getuid() == 0) -#ifdef WITH_SELINUX - if (is_selinux_enabled()<1 || checkPasswdAccess(PASSWD__ROOTOK)==0) -#endif - retval = PAM_SUCCESS; - - if (ctrl & PAM_DEBUG_ARG) { - pam_syslog(pamh, LOG_DEBUG, "authentication %s", - (retval==PAM_SUCCESS) ? "succeeded" : "failed"); - } - - return retval; -} - -PAM_EXTERN int -pam_sm_setcred (pam_handle_t *pamh UNUSED, int flags UNUSED, - int argc UNUSED, const char **argv UNUSED) -{ - return PAM_SUCCESS; -} - - -#ifdef PAM_STATIC - -/* static module data */ - -struct pam_module _pam_rootok_modstruct = { - "pam_rootok", - pam_sm_authenticate, - pam_sm_setcred, - NULL, - NULL, - NULL, - NULL, -}; - -#endif - -/* end of module definition */ diff --git a/modules/pam_rootok/tst-pam_rootok b/modules/pam_rootok/tst-pam_rootok deleted file mode 100755 index 385ef760..00000000 --- a/modules/pam_rootok/tst-pam_rootok +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/sh -../../tests/tst-dlopen .libs/pam_rootok.so diff --git a/modules/pam_securetty/.cvsignore b/modules/pam_securetty/.cvsignore deleted file mode 100644 index 1e9b0b2d..00000000 --- a/modules/pam_securetty/.cvsignore +++ /dev/null @@ -1,8 +0,0 @@ -*.la -*.lo -.deps -.libs -Makefile -Makefile.in -README -pam_securetty.8 diff --git a/modules/pam_securetty/Makefile.am b/modules/pam_securetty/Makefile.am deleted file mode 100644 index dd8d9473..00000000 --- a/modules/pam_securetty/Makefile.am +++ /dev/null @@ -1,30 +0,0 @@ -# -# Copyright (c) 2005, 2006 Thorsten Kukuk <kukuk@suse.de> -# - -CLEANFILES = *~ - -EXTRA_DIST = README $(MANS) $(XMLS) tst-pam_securetty - -TESTS = tst-pam_securetty - -man_MANS = pam_securetty.8 -XMLS = README.xml pam_securetty.8.xml - -securelibdir = $(SECUREDIR) -secureconfdir = $(SCONFIGDIR) - -AM_CFLAGS = -I$(top_srcdir)/libpam/include -I$(top_srcdir)/libpamc/include -AM_LDFLAGS = -no-undefined -avoid-version -module -if HAVE_VERSIONING - AM_LDFLAGS += -Wl,--version-script=$(srcdir)/../modules.map -endif - -securelib_LTLIBRARIES = pam_securetty.la -pam_securetty_la_LIBADD = -L$(top_builddir)/libpam -lpam - -if ENABLE_REGENERATE_MAN -noinst_DATA = README -README: pam_securetty.8.xml --include $(top_srcdir)/Make.xml.rules -endif diff --git a/modules/pam_securetty/README.xml b/modules/pam_securetty/README.xml deleted file mode 100644 index a8c098a0..00000000 --- a/modules/pam_securetty/README.xml +++ /dev/null @@ -1,41 +0,0 @@ -<?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_securetty.8.xml"> ---> -]> - -<article> - - <articleinfo> - - <title> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" - href="pam_securetty.8.xml" xpointer='xpointer(//refnamediv[@id = "pam_securetty-name"]/*)'/> - </title> - - </articleinfo> - - <section> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" - href="pam_securetty.8.xml" xpointer='xpointer(//refsect1[@id = "pam_securetty-description"]/*)'/> - </section> - - <section> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" - href="pam_securetty.8.xml" xpointer='xpointer(//refsect1[@id = "pam_securetty-options"]/*)'/> - </section> - - <section> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" - href="pam_securetty.8.xml" xpointer='xpointer(//refsect1[@id = "pam_securetty-examples"]/*)'/> - </section> - - <section> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" - href="pam_securetty.8.xml" xpointer='xpointer(//refsect1[@id = "pam_securetty-author"]/*)'/> - </section> - -</article> diff --git a/modules/pam_securetty/pam_securetty.8.xml b/modules/pam_securetty/pam_securetty.8.xml deleted file mode 100644 index 56348d78..00000000 --- a/modules/pam_securetty/pam_securetty.8.xml +++ /dev/null @@ -1,167 +0,0 @@ -<?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_securetty"> - - <refmeta> - <refentrytitle>pam_securetty</refentrytitle> - <manvolnum>8</manvolnum> - <refmiscinfo class="sectdesc">Linux-PAM Manual</refmiscinfo> - </refmeta> - - <refnamediv id="pam_securetty-name"> - <refname>pam_securetty</refname> - <refpurpose>Limit root login to special devices</refpurpose> - </refnamediv> - - <refsynopsisdiv> - <cmdsynopsis id="pam_securetty-cmdsynopsis"> - <command>pam_securetty.so</command> - <arg choice="opt"> - debug - </arg> - </cmdsynopsis> - </refsynopsisdiv> - - <refsect1 id="pam_securetty-description"> - - <title>DESCRIPTION</title> - - <para> - pam_securetty is a PAM module that allows root logins only if the - user is logging in on a "secure" tty, as defined by the listing - in <filename>/etc/securetty</filename>. pam_securetty also checks - to make sure that <filename>/etc/securetty</filename> is a plain - file and not world writable. - </para> - <para> - This module has no effect on non-root users and requires that the - application fills in the <emphasis remap='B'>PAM_TTY</emphasis> - item correctly. - </para> - <para> - For canonical usage, should be listed as a - <emphasis remap='B'>required</emphasis> authentication method - before any <emphasis remap='B'>sufficient</emphasis> - authentication methods. - </para> - </refsect1> - - <refsect1 id="pam_securetty-options"> - <title>OPTIONS</title> - <variablelist> - <varlistentry> - <term> - <option>debug</option> - </term> - <listitem> - <para> - Print debug information. - </para> - </listitem> - </varlistentry> - </variablelist> - </refsect1> - - <refsect1 id="pam_securetty-services"> - <title>MODULE SERVICES PROVIDED</title> - <para> - Only the <option>auth</option> service is supported. - </para> - </refsect1> - - <refsect1 id='pam_securetty-return_values'> - <title>RETURN VALUES</title> - <variablelist> - <varlistentry> - <term>PAM_SUCCESS</term> - <listitem> - <para> - The user is allowed to continue authentication. - Either the user is not root, or the root user is - trying to log in on an acceptable device. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term>PAM_AUTH_ERR</term> - <listitem> - <para> - Authentication is rejected. Either root is attempting to - log in via an unacceptable device, or the - <filename>/etc/securetty</filename> file is world writable or - not a normal file. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term>PAM_INCOMPLETE</term> - <listitem> - <para> - An application error occurred. pam_securetty was not able - to get information it required from the application that - called it. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term>PAM_SERVICE_ERR</term> - <listitem> - <para> - An error occurred while the module was determining the - user's name or tty, or the module could not open - <filename>/etc/securetty</filename>. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term>PAM_IGNORE</term> - <listitem> - <para> - The module could not find the user name in the - <filename>/etc/passwd</filename> file to verify whether - the user had a UID of 0. Therefore, the results of running - this module are ignored. - </para> - </listitem> - </varlistentry> - </variablelist> - </refsect1> - - <refsect1 id='pam_securetty-examples'> - <title>EXAMPLES</title> - <para> - <programlisting> -auth required pam_securetty.so -auth required pam_unix.so - </programlisting> - </para> - </refsect1> - - <refsect1 id='pam_securetty-see_also'> - <title>SEE ALSO</title> - <para> - <citerefentry> - <refentrytitle>securetty</refentrytitle><manvolnum>5</manvolnum> - </citerefentry>, - <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_securetty-author'> - <title>AUTHOR</title> - <para> - pam_securetty was written by Elliot Lee <sopwith@cuc.edu>. - </para> - </refsect1> - -</refentry> diff --git a/modules/pam_securetty/pam_securetty.c b/modules/pam_securetty/pam_securetty.c deleted file mode 100644 index 9dbe9bc4..00000000 --- a/modules/pam_securetty/pam_securetty.c +++ /dev/null @@ -1,219 +0,0 @@ -/* pam_securetty module */ - -#define SECURETTY_FILE "/etc/securetty" -#define TTY_PREFIX "/dev/" - -/* - * by Elliot Lee <sopwith@redhat.com>, Red Hat Software. - * July 25, 1996. - * This code shamelessly ripped from the pam_rootok module. - * Slight modifications AGM. 1996/12/3 - */ - -#include "config.h" - -#include <stdio.h> -#include <stdlib.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <unistd.h> -#include <syslog.h> -#include <stdarg.h> -#include <pwd.h> -#include <string.h> -#include <ctype.h> - -/* - * here, we make a definition for the externally accessible function - * in this file (this definition is required for static a module - * but strongly encouraged generally) it is used to instruct the - * modules include file to define the function prototypes. - */ - -#define PAM_SM_AUTH -#define PAM_SM_ACCOUNT - -#include <security/pam_modules.h> -#include <security/pam_modutil.h> -#include <security/pam_ext.h> - -#define PAM_DEBUG_ARG 0x0001 - -static int -_pam_parse (const pam_handle_t *pamh, int argc, const char **argv) -{ - int ctrl=0; - - /* step through arguments */ - for (ctrl=0; argc-- > 0; ++argv) { - - /* generic options */ - - if (!strcmp(*argv,"debug")) - ctrl |= PAM_DEBUG_ARG; - else { - pam_syslog(pamh, LOG_ERR, "unknown option: %s", *argv); - } - } - - return ctrl; -} - -static int -securetty_perform_check (pam_handle_t *pamh, int ctrl, - const char *function_name) -{ - int retval = PAM_AUTH_ERR; - const char *username; - const char *uttyname; - const void *void_uttyname; - char ttyfileline[256]; - char ptname[256]; - struct stat ttyfileinfo; - struct passwd *user_pwd; - FILE *ttyfile; - - /* log a trail for debugging */ - if (ctrl & PAM_DEBUG_ARG) { - pam_syslog(pamh, LOG_DEBUG, "pam_securetty called via %s function", - function_name); - } - - retval = pam_get_user(pamh, &username, NULL); - if (retval != PAM_SUCCESS || username == NULL) { - pam_syslog(pamh, LOG_WARNING, "cannot determine username"); - return (retval == PAM_CONV_AGAIN ? PAM_INCOMPLETE:PAM_SERVICE_ERR); - } - - user_pwd = pam_modutil_getpwnam(pamh, username); - if (user_pwd == NULL) { - return PAM_USER_UNKNOWN; - } else if (user_pwd->pw_uid != 0) { /* If the user is not root, - securetty's does not apply - to them */ - return PAM_SUCCESS; - } - - retval = pam_get_item(pamh, PAM_TTY, &void_uttyname); - uttyname = void_uttyname; - if (retval != PAM_SUCCESS || uttyname == NULL) { - pam_syslog (pamh, LOG_WARNING, "cannot determine user's tty"); - return PAM_SERVICE_ERR; - } - - /* The PAM_TTY item may be prefixed with "/dev/" - skip that */ - if (strncmp(TTY_PREFIX, uttyname, sizeof(TTY_PREFIX)-1) == 0) { - uttyname += sizeof(TTY_PREFIX)-1; - } - - if (stat(SECURETTY_FILE, &ttyfileinfo)) { - pam_syslog(pamh, LOG_NOTICE, "Couldn't open %s: %m", SECURETTY_FILE); - return PAM_SUCCESS; /* for compatibility with old securetty handling, - this needs to succeed. But we still log the - error. */ - } - - if ((ttyfileinfo.st_mode & S_IWOTH) || !S_ISREG(ttyfileinfo.st_mode)) { - /* If the file is world writable or is not a - normal file, return error */ - pam_syslog(pamh, LOG_ERR, - "%s is either world writable or not a normal file", - SECURETTY_FILE); - return PAM_AUTH_ERR; - } - - ttyfile = fopen(SECURETTY_FILE,"r"); - if (ttyfile == NULL) { /* Check that we opened it successfully */ - pam_syslog(pamh, LOG_ERR, "Error opening %s: %m", SECURETTY_FILE); - return PAM_SERVICE_ERR; - } - - if (isdigit(uttyname[0])) { - snprintf(ptname, sizeof(ptname), "pts/%s", uttyname); - } else { - ptname[0] = '\0'; - } - - retval = 1; - - while ((fgets(ttyfileline, sizeof(ttyfileline)-1, ttyfile) != NULL) - && retval) { - if (ttyfileline[strlen(ttyfileline) - 1] == '\n') - ttyfileline[strlen(ttyfileline) - 1] = '\0'; - - retval = ( strcmp(ttyfileline, uttyname) - && (!ptname[0] || strcmp(ptname, uttyname)) ); - } - fclose(ttyfile); - - if (retval) { - pam_syslog(pamh, LOG_WARNING, "access denied: tty '%s' is not secure !", - uttyname); - - retval = PAM_AUTH_ERR; - } else { - if ((retval == PAM_SUCCESS) && (ctrl & PAM_DEBUG_ARG)) { - pam_syslog(pamh, LOG_DEBUG, "access allowed for '%s' on '%s'", - username, uttyname); - } - retval = PAM_SUCCESS; - - } - - return retval; -} - -/* --- authentication management functions --- */ - -PAM_EXTERN -int pam_sm_authenticate(pam_handle_t *pamh, int flags UNUSED, int argc, - const char **argv) -{ - int ctrl; - - /* parse the arguments */ - ctrl = _pam_parse (pamh, argc, argv); - - return securetty_perform_check(pamh, ctrl, __FUNCTION__); -} - -PAM_EXTERN int -pam_sm_setcred (pam_handle_t *pamh UNUSED, int flags UNUSED, - int argc UNUSED, const char **argv UNUSED) -{ - return PAM_SUCCESS; -} - -/* --- account management functions --- */ - -PAM_EXTERN int -pam_sm_acct_mgmt (pam_handle_t *pamh, int flags UNUSED, - int argc, const char **argv) -{ - int ctrl; - - /* parse the arguments */ - ctrl = _pam_parse (pamh, argc, argv); - - /* take the easy route */ - return securetty_perform_check(pamh, ctrl, __FUNCTION__); -} - - -#ifdef PAM_STATIC - -/* static module data */ - -struct pam_module _pam_securetty_modstruct = { - "pam_securetty", - pam_sm_authenticate, - pam_sm_setcred, - pam_sm_acct_mgmt, - NULL, - NULL, - NULL, -}; - -#endif /* PAM_STATIC */ - -/* end of module definition */ diff --git a/modules/pam_securetty/tst-pam_securetty b/modules/pam_securetty/tst-pam_securetty deleted file mode 100755 index 1252f798..00000000 --- a/modules/pam_securetty/tst-pam_securetty +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/sh -../../tests/tst-dlopen .libs/pam_securetty.so diff --git a/modules/pam_selinux/.cvsignore b/modules/pam_selinux/.cvsignore deleted file mode 100644 index 08754fd5..00000000 --- a/modules/pam_selinux/.cvsignore +++ /dev/null @@ -1,11 +0,0 @@ -*.la -*.lo -*.so -*~ -.deps -.libs -Makefile -Makefile.in -pam_selinux_check -README -pam_selinux.8 diff --git a/modules/pam_selinux/Makefile.am b/modules/pam_selinux/Makefile.am deleted file mode 100644 index baf782a8..00000000 --- a/modules/pam_selinux/Makefile.am +++ /dev/null @@ -1,43 +0,0 @@ -# -# Copyright (c) 2005, 2006, 2007 Thorsten Kukuk <kukuk@thkukuk.de> -# - -CLEANFILES = *~ -MAINTAINERCLEANFILES = $(MANS) README - -EXTRA_DIST = README $(XMLS) pam_selinux.8 pam_selinux_check.8 \ - tst-pam_selinux - -if HAVE_LIBSELINUX - TESTS = tst-pam_selinux - man_MANS = pam_selinux.8 -endif - -XMLS = README.xml pam_selinux.8.xml - -securelibdir = $(SECUREDIR) -secureconfdir = $(SCONFIGDIR) - -AM_CFLAGS = -I$(top_srcdir)/libpam/include -I$(top_srcdir)/libpamc/include \ - -I$(top_srcdir)/libpam_misc/include - -pam_selinux_check_LDFLAGS = $(AM_LDFLAGS) \ - -L$(top_builddir)/libpam -lpam \ - -L$(top_builddir)/libpam_misc -lpam_misc - -pam_selinux_la_LIBADD = -L$(top_builddir)/libpam -lpam @LIBSELINUX@ -pam_selinux_la_LDFLAGS = -no-undefined -avoid-version -module -if HAVE_VERSIONING - pam_selinux_la_LDFLAGS += -Wl,--version-script=$(srcdir)/../modules.map -endif - -if HAVE_LIBSELINUX - securelib_LTLIBRARIES = pam_selinux.la - noinst_PROGRAMS = pam_selinux_check -endif -if ENABLE_REGENERATE_MAN -noinst_DATA = README pam_selinux.8 -README: pam_selinux.8.xml --include $(top_srcdir)/Make.xml.rules -endif - diff --git a/modules/pam_selinux/README.xml b/modules/pam_selinux/README.xml deleted file mode 100644 index 7e1baf55..00000000 --- a/modules/pam_selinux/README.xml +++ /dev/null @@ -1,41 +0,0 @@ -<?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_selinux.8.xml"> ---> -]> - -<article> - - <articleinfo> - - <title> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" - href="pam_selinux.8.xml" xpointer='xpointer(//refnamediv[@id = "pam_selinux-name"]/*)'/> - </title> - - </articleinfo> - - <section> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" - href="pam_selinux.8.xml" xpointer='xpointer(//refsect1[@id = "pam_selinux-description"]/*)'/> - </section> - - <section> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" - href="pam_selinux.8.xml" xpointer='xpointer(//refsect1[@id = "pam_selinux-options"]/*)'/> - </section> - - <section> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" - href="pam_selinux.8.xml" xpointer='xpointer(//refsect1[@id = "pam_selinux-examples"]/*)'/> - </section> - - <section> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" - href="pam_selinux.8.xml" xpointer='xpointer(//refsect1[@id = "pam_selinux-author"]/*)'/> - </section> - -</article> diff --git a/modules/pam_selinux/pam_selinux.8.xml b/modules/pam_selinux/pam_selinux.8.xml deleted file mode 100644 index 3acd1322..00000000 --- a/modules/pam_selinux/pam_selinux.8.xml +++ /dev/null @@ -1,220 +0,0 @@ -<?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"> - - <refmeta> - <refentrytitle>pam_selinux</refentrytitle> - <manvolnum>8</manvolnum> - <refmiscinfo class="sectdesc">Linux-PAM Manual</refmiscinfo> - </refmeta> - - <refnamediv id="pam_selinux-name"> - <refname>pam_selinux</refname> - <refpurpose>PAM module to set the default security context</refpurpose> - </refnamediv> - - <refsynopsisdiv> - <cmdsynopsis id="pam_selinux-cmdsynopsis"> - <command>pam_selinux.so</command> - <arg choice="opt"> - close - </arg> - <arg choice="opt"> - debug - </arg> - <arg choice="opt"> - open - </arg> - <arg choice="opt"> - nottys - </arg> - <arg choice="opt"> - verbose - </arg> - <arg choice="opt"> - select_context - </arg> - <arg choice="opt"> - use_current_range - </arg> - </cmdsynopsis> - </refsynopsisdiv> - - <refsect1 id="pam_selinux-description"> - <title>DESCRIPTION</title> - <para> - In a nutshell, pam_selinux sets up the default security context for the - next execed shell. - </para> - <para> - When an application opens a session using pam_selinux, the shell that - gets executed will be run in the default security context, or if the - user chooses and the pam file allows the selected security context. - Also the controlling tty will have it's security context modified to - match the users. - </para> - <para> - Adding pam_selinux into a pam file could cause other pam modules to - change their behavior if the exec another application. The close and - open option help mitigate this problem. close option will only cause - the close portion of the pam_selinux to execute, and open will only - cause the open portion to run. You can add pam_selinux to the config - file twice. Add the pam_selinux close as the executes the open pass - through the modules, pam_selinux open_session will happen last. - When PAM executes the close pass through the modules pam_selinux - close_session will happen first. - </para> - </refsect1> - - <refsect1 id="pam_selinux-options"> - <title>OPTIONS</title> - <variablelist> - <varlistentry> - <term> - <option>close</option> - </term> - <listitem> - <para> - Only execute the close_session portion of the module. - </para> - </listitem> - </varlistentry> - <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>open</option> - </term> - <listitem> - <para> - Only execute the open_session portion of the module. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <option>nottys</option> - </term> - <listitem> - <para> - Do not try to setup the ttys security context. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <option>verbose</option> - </term> - <listitem> - <para> - attempt to inform the user when security context is set. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <option>select_context</option> - </term> - <listitem> - <para> - Attempt to ask the user for a custom security context role. - If MLS is on ask also for sensitivity level. - </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. - </para> - </listitem> - </varlistentry> - </variablelist> - </refsect1> - - <refsect1 id="pam_selinux-services"> - <title>MODULE SERVICES PROVIDED</title> - <para> - Only the <option>session</option> service is supported. - </para> - </refsect1> - - <refsect1 id='pam_selinux-return_values'> - <title>RETURN VALUES</title> - <variablelist> - <varlistentry> - <term>PAM_AUTH_ERR</term> - <listitem> - <para> - Unable to get or set a valid context. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term>PAM_SUCCESS</term> - <listitem> - <para> - The security context was set successfull. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term>PAM_USER_UNKNOWN</term> - <listitem> - <para> - The user is not known to the system. - </para> - </listitem> - </varlistentry> - </variablelist> - </refsect1> - - <refsect1 id='pam_selinux-examples'> - <title>EXAMPLES</title> - <programlisting> -auth required pam_unix.so -session required pam_permit.so -session optional pam_selinux.so - </programlisting> - </refsect1> - - <refsect1 id='pam_selinux-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-author'> - <title>AUTHOR</title> - <para> - pam_selinux was written by Dan Walsh <dwalsh@redhat.com>. - </para> - </refsect1> - -</refentry> diff --git a/modules/pam_selinux/pam_selinux.c b/modules/pam_selinux/pam_selinux.c deleted file mode 100644 index f0935896..00000000 --- a/modules/pam_selinux/pam_selinux.c +++ /dev/null @@ -1,720 +0,0 @@ -/****************************************************************************** - * A module for Linux-PAM that will set the default security context after login - * via PAM. - * - * Copyright (c) 2003 Red Hat, Inc. - * Written by Dan Walsh <dwalsh@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 <limits.h> -#include <pwd.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <fcntl.h> -#include <syslog.h> - -#define PAM_SM_AUTH -#define PAM_SM_SESSION - -#include <security/pam_modules.h> -#include <security/_pam_macros.h> -#include <security/pam_modutil.h> -#include <security/pam_ext.h> - -#include <selinux/selinux.h> -#include <selinux/get_context_list.h> -#include <selinux/flask.h> -#include <selinux/av_permissions.h> -#include <selinux/selinux.h> -#include <selinux/context.h> -#include <selinux/get_default_type.h> - -#ifdef HAVE_LIBAUDIT -#include <libaudit.h> -#include <sys/select.h> -#include <errno.h> -#endif - -/* Send audit message */ -static - -int send_audit_message(pam_handle_t *pamh, int success, security_context_t default_context, - security_context_t selected_context) -{ - int rc=0; -#ifdef HAVE_LIBAUDIT - char *msg = NULL; - int audit_fd = audit_open(); - security_context_t default_raw=NULL; - security_context_t selected_raw=NULL; - rc = -1; - if (audit_fd < 0) { - if (errno == EINVAL || errno == EPROTONOSUPPORT || - errno == EAFNOSUPPORT) - return 0; /* No audit support in kernel */ - pam_syslog(pamh, LOG_ERR, _("Error connecting to audit system.")); - return rc; - } - if (selinux_trans_to_raw_context(default_context, &default_raw) < 0) { - pam_syslog(pamh, LOG_ERR, _("Error translating default context.")); - default_raw = NULL; - } - if (selinux_trans_to_raw_context(selected_context, &selected_raw) < 0) { - pam_syslog(pamh, LOG_ERR, _("Error translating selected context.")); - selected_raw = NULL; - } - if (asprintf(&msg, "pam: default-context=%s selected-context=%s", - default_raw ? default_raw : (default_context ? default_context : "?"), - selected_raw ? selected_raw : (selected_context ? selected_context : "?")) < 0) { - pam_syslog(pamh, LOG_ERR, ("Error allocating memory.")); - goto out; - } - if (audit_log_user_message(audit_fd, AUDIT_USER_ROLE_CHANGE, - msg, NULL, NULL, NULL, success) <= 0) { - pam_syslog(pamh, LOG_ERR, _("Error sending audit message.")); - goto out; - } - rc = 0; - out: - free(msg); - freecon(default_raw); - freecon(selected_raw); - close(audit_fd); -#else - pam_syslog(pamh, LOG_NOTICE, "pam: default-context=%s selected-context=%s success %d", default_context, selected_context, success); -#endif - return rc; -} -static int -send_text (pam_handle_t *pamh, const char *text, int debug) -{ - if (debug) - pam_syslog(pamh, LOG_NOTICE, "%s", text); - return pam_info (pamh, "%s", text); -} - -/* - * This function sends a message to the user and gets the response. The caller - * is responsible for freeing the responses. - */ -static int -query_response (pam_handle_t *pamh, const char *text, const char *def, - char **responses, int debug) -{ - int rc; - if (def) - rc = pam_prompt (pamh, PAM_PROMPT_ECHO_ON, responses, "%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]); - return rc; -} - -static security_context_t -manual_context (pam_handle_t *pamh, const char *user, int debug) -{ - security_context_t newcon=NULL; - context_t new_context; - int mls_enabled = is_selinux_mls_enabled(); - char *type=NULL; - char *responses=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 (mls_enabled) - new_context = context_new ("user:role:type:level"); - else - new_context = context_new ("user:role:type"); - - if (!new_context) - goto fail_set; - - if (context_user_set (new_context, user)) - goto fail_set; - - _pam_drop(responses); - /* 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)) - goto fail_set; - if (get_default_type(responses, &type)) - goto fail_set; - if (context_type_set (new_context, type)) - goto fail_set; - } - _pam_drop(responses); - if (mls_enabled) - { - query_response(pamh,_("level:"), NULL, &responses,debug); - if (responses[0] != '\0') { - if (context_range_set (new_context, responses)) - goto fail_set; - } - } - /* 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); - return newcon; - } - else - send_text(pamh,_("Not a valid security context"),debug); - context_free (new_context); - } - else { - _pam_drop(responses); - return NULL; - } - } /* end while */ - fail_set: - free(type); - _pam_drop(responses); - context_free (new_context); - return NULL; -} - -static int mls_range_allowed(pam_handle_t *pamh, security_context_t src, security_context_t dst, int debug) -{ - struct av_decision avd; - int retval; - unsigned int bit = CONTEXT__CONTAINS; - context_t src_context = context_new (src); - context_t dst_context = context_new (dst); - context_range_set(dst_context, context_range_get(src_context)); - if (debug) - pam_syslog(pamh, LOG_NOTICE, "Checking if %s mls range valid for %s", dst, context_str(dst_context)); - - retval = security_compute_av(context_str(dst_context), dst, SECCLASS_CONTEXT, bit, &avd); - context_free(src_context); - context_free(dst_context); - if (retval || ((bit & avd.allowed) != bit)) - return 0; - - return 1; -} - -static security_context_t -config_context (pam_handle_t *pamh, security_context_t puser_context, int debug) -{ - security_context_t newcon=NULL; - context_t new_context; - int mls_enabled = is_selinux_mls_enabled(); - char *responses=NULL; - char *type=NULL; - char resp_val = 0; - - pam_prompt (pamh, PAM_TEXT_INFO, NULL, _("Default Security Context %s\n"), puser_context); - - while (1) { - query_response(pamh, - _("Would you like to enter a different role or level?"), "n", - &responses,debug); - - resp_val = responses[0]; - _pam_drop(responses); - if ((resp_val == 'y') || (resp_val == 'Y')) - { - new_context = context_new(puser_context); - - /* 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); - continue; - } else { - if (context_role_set(new_context, responses)) - goto fail_set; - if (context_type_set (new_context, type)) - goto fail_set; - } - } - _pam_drop(responses); - 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; - } - _pam_drop(responses); - } - 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); - - /* 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); - - send_audit_message(pamh, 0, puser_context, newcon); - - free(newcon); - goto fail_range; - } - return newcon; - } - else { - send_audit_message(pamh, 0, puser_context, 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); - } /* end while */ - - return NULL; - - fail_set: - free(type); - _pam_drop(responses); - context_free (new_context); - send_audit_message(pamh, 0, puser_context, NULL); - fail_range: - return NULL; -} - -static void -security_restorelabel_tty(const pam_handle_t *pamh, - const char *tty, security_context_t context) -{ - char ttybuf[PATH_MAX]; - const char *ptr; - - if (context==NULL) - return; - - if(strncmp("/dev/", tty, 5)) { - snprintf(ttybuf,sizeof(ttybuf),"/dev/%s",tty); - ptr = ttybuf; - } - else - ptr = tty; - - if (setfilecon(ptr, context) && errno != ENOENT) - { - pam_syslog(pamh, LOG_NOTICE, - "Warning! Could not relabel %s with %s, not relabeling: %m", - ptr, context); - } -} - -static security_context_t -security_label_tty(pam_handle_t *pamh, char *tty, - security_context_t usercon) -{ - char ttybuf[PATH_MAX]; - int status=0; - security_context_t newdev_context=NULL; /* The new context of a device */ - security_context_t prev_context=NULL; /* The new context of a device */ - const char *ptr; - - if(strncmp("/dev/", tty, 5)) - { - snprintf(ttybuf,sizeof(ttybuf),"/dev/%s",tty); - ptr = ttybuf; - } - else - ptr = tty; - - if (getfilecon(ptr, &prev_context) < 0) - { - if(errno != ENOENT) - pam_syslog(pamh, LOG_NOTICE, - "Warning! Could not get current context for %s, not relabeling: %m", - ptr); - return NULL; - } - if( security_compute_relabel(usercon,prev_context,SECCLASS_CHR_FILE, - &newdev_context)!=0) - { - pam_syslog(pamh, LOG_NOTICE, - "Warning! Could not get new context for %s, not relabeling: %m", - ptr); - pam_syslog(pamh, LOG_NOTICE, - "usercon=%s, prev_context=%s", usercon, prev_context); - freecon(prev_context); - return NULL; - } - status=setfilecon(ptr,newdev_context); - if (status) - { - pam_syslog(pamh, LOG_NOTICE, - "Warning! Could not relabel %s with %s, not relabeling: %m", - ptr,newdev_context); - freecon(prev_context); - prev_context=NULL; - } - freecon(newdev_context); - return prev_context; -} - -static security_context_t user_context=NULL; -static security_context_t prev_user_context=NULL; -static security_context_t ttyn_context=NULL; /* The current context of ttyn device */ -static int selinux_enabled=0; -static char *ttyn=NULL; - -/* Tell the user that access has been granted. */ -static void -verbose_message(pam_handle_t *pamh, char *msg, int debug) -{ - if (debug) - pam_syslog(pamh, LOG_NOTICE, msg); - - pam_info (pamh, "%s", msg); -} - -PAM_EXTERN int -pam_sm_authenticate(pam_handle_t *pamh UNUSED, int flags UNUSED, - int argc UNUSED, const char **argv UNUSED) -{ - /* Fail by default. */ - return PAM_AUTH_ERR; -} - -PAM_EXTERN int -pam_sm_setcred(pam_handle_t *pamh UNUSED, int flags UNUSED, - int argc UNUSED, const char **argv UNUSED) -{ - return PAM_SUCCESS; -} - -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 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; - const char *username = NULL; - const void *tty = NULL; - char *seuser=NULL; - char *level=NULL; - security_context_t default_user_context=NULL; - - /* Parse arguments. */ - for (i = 0; i < argc; i++) { - if (strcmp(argv[i], "debug") == 0) { - debug = 1; - } - if (strcmp(argv[i], "nottys") == 0) { - ttys = 0; - } - if (strcmp(argv[i], "verbose") == 0) { - verbose = 1; - } - if (strcmp(argv[i], "close") == 0) { - close_session = 1; - } - if (strcmp(argv[i], "select_context") == 0) { - select_context = 1; - } - if (strcmp(argv[i], "use_current_range") == 0) { - use_current_range = 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"); - select_context = 0; - } - - /* this module is only supposed to execute close_session */ - if (close_session) - return PAM_SUCCESS; - - if (!(selinux_enabled = is_selinux_enabled()>0) ) - return PAM_SUCCESS; - - if (pam_get_item(pamh, PAM_USER, (void *) &username) != PAM_SUCCESS || - username == NULL) { - return PAM_USER_UNKNOWN; - } - - if (getseuserbyname(username, &seuser, &level)==0) { - num_contexts = get_ordered_context_list_with_level(seuser, - level, - NULL, - &contextlist); - if (debug) - pam_syslog(pamh, LOG_DEBUG, "Username= %s SELinux User = %s Level= %s", - username, seuser, level); - free(seuser); - free(level); - } - if (num_contexts > 0) { - default_user_context=strdup(contextlist[0]); - freeconary(contextlist); - if (default_user_context == NULL) { - pam_syslog(pamh, LOG_ERR, _("Out of memory")); - return PAM_AUTH_ERR; - } - user_context = default_user_context; - if (select_context && has_tty) { - user_context = config_context(pamh, default_user_context, debug); - if (user_context == NULL) { - freecon(default_user_context); - pam_syslog(pamh, LOG_ERR, _("Unable to get valid context for %s"), - username); - pam_prompt (pamh, PAM_ERROR_MSG, NULL, _("Unable to get valid context for %s"), username); - if (security_getenforce() == 1) - 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", - username); - if (security_getenforce() == 1) - return PAM_AUTH_ERR; - 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) { - prev_user_context=NULL; - } - if (ttys) { - /* Get the name of the terminal. */ - if (pam_get_item(pamh, PAM_TTY, &tty) != PAM_SUCCESS) { - tty = NULL; - } - - if ((tty == NULL) || (strlen(tty) == 0) || - strcmp(tty, "ssh") == 0 || strncmp(tty, "NODEV", 5) == 0) { - tty = ttyname(STDIN_FILENO); - if ((tty == NULL) || (strlen(tty) == 0)) { - tty = ttyname(STDOUT_FILENO); - } - if ((tty == NULL) || (strlen(tty) == 0)) { - tty = ttyname(STDERR_FILENO); - } - } - } - if(ttys && tty ) { - ttyn=strdup(tty); - ttyn_context=security_label_tty(pamh,ttyn,user_context); - } - send_audit_message(pamh, 1, default_user_context, user_context); - if (default_user_context != user_context) { - freecon(default_user_context); - } - ret = setexeccon(user_context); - if (ret==0 && verbose) { - char msg[PATH_MAX]; - snprintf(msg, sizeof(msg), - _("Security Context %s Assigned"), user_context); - verbose_message(pamh, msg, debug); - } - if (ret) { - pam_syslog(pamh, LOG_ERR, - "Error! Unable to set %s executable context %s.", - username, user_context); - if (security_getenforce() == 1) { - freecon(user_context); - return PAM_AUTH_ERR; - } - } else { - if (debug) - pam_syslog(pamh, LOG_NOTICE, "set %s security context to %s", - username, user_context); - } -#ifdef HAVE_SETKEYCREATECON - ret = setkeycreatecon(user_context); - if (ret==0 && verbose) { - char msg[PATH_MAX]; - snprintf(msg, sizeof(msg), - _("Key Creation Context %s Assigned"), user_context); - verbose_message(pamh, msg, debug); - } - if (ret) { - pam_syslog(pamh, LOG_ERR, - "Error! Unable to set %s key creation context %s.", - username, user_context); - if (security_getenforce() == 1) { - freecon(user_context); - return PAM_AUTH_ERR; - } - } else { - if (debug) - pam_syslog(pamh, LOG_NOTICE, "set %s key creation context to %s", - username, user_context); - } -#endif - freecon(user_context); - - return PAM_SUCCESS; -} - -PAM_EXTERN int -pam_sm_close_session(pam_handle_t *pamh, int flags UNUSED, - int argc, const char **argv) -{ - int i, debug = 0,status=0, open_session=0; - if (! (selinux_enabled )) - return PAM_SUCCESS; - - /* Parse arguments. */ - for (i = 0; i < argc; i++) { - if (strcmp(argv[i], "debug") == 0) { - debug = 1; - } - if (strcmp(argv[i], "open") == 0) { - open_session = 1; - } - } - - if (debug) - pam_syslog(pamh, LOG_NOTICE, "Close Session"); - - if (open_session) - return PAM_SUCCESS; - - if (ttyn) { - if (debug) - pam_syslog(pamh, LOG_NOTICE, "Restore tty %s -> %s", - ttyn,ttyn_context); - - security_restorelabel_tty(pamh,ttyn,ttyn_context); - freecon(ttyn_context); - free(ttyn); - ttyn=NULL; - } - status=setexeccon(prev_user_context); - freecon(prev_user_context); - if (status) { - pam_syslog(pamh, LOG_ERR, "Error! Unable to set executable context %s.", - prev_user_context); - if (security_getenforce() == 1) - return PAM_AUTH_ERR; - else - return PAM_SUCCESS; - } - - if (debug) - pam_syslog(pamh, LOG_NOTICE, "setcontext back to orginal"); - - return PAM_SUCCESS; -} diff --git a/modules/pam_selinux/pam_selinux_check.8 b/modules/pam_selinux/pam_selinux_check.8 deleted file mode 100644 index d6fcdff1..00000000 --- a/modules/pam_selinux/pam_selinux_check.8 +++ /dev/null @@ -1,35 +0,0 @@ -.TH pam_selinux_check 8 2002/05/23 "Red Hat Linux" "System Administrator's Manual" -.SH NAME -pam_selinux_check \- login program to test pam_selinux.so -.SH SYNOPSIS -.B pam_selinux_check [user] -.br - -.SH DESCRIPTION -With no arguments, -.B pam_selinux_check -will prompt for user - -.SH OPTIONS -.IP target_user -The user to login as. - -.SH DIAGNOSTICS -You must setup a /etc/pam.d/pam_selinux_check file, in order for the check to work. - -When checking if a selinux is valid, -.B pam_selinux_check -returns an exit code of 0 for success and > 0 on error: - -.nf -1: Authentication failure -.fi - -.SH SEE ALSO -pam_selinux(8) - -.SH BUGS -Let's hope not, but if you find any, please email the author. - -.SH AUTHOR -Dan Walsh <dwalsh@redhat.com> diff --git a/modules/pam_selinux/pam_selinux_check.c b/modules/pam_selinux/pam_selinux_check.c deleted file mode 100644 index 30526d37..00000000 --- a/modules/pam_selinux/pam_selinux_check.c +++ /dev/null @@ -1,161 +0,0 @@ -/****************************************************************************** - * A module for Linux-PAM that will set the default security context after login - * via PAM. - * - * Copyright (c) 2003 Red Hat, Inc. - * Written by Dan Walsh <dwalsh@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. - * - */ - -/************************************************************************ - * - * All PAM code goes in this section. - * - ************************************************************************/ - -#include "config.h" - -#include <errno.h> -#include <syslog.h> -#include <unistd.h> /* for getuid(), exit(), getopt() */ -#include <signal.h> -#include <sys/wait.h> /* for wait() */ - -#include <security/pam_appl.h> /* for PAM functions */ -#include <security/pam_misc.h> /* for misc_conv PAM utility function */ - -#define SERVICE_NAME "pam_selinux_check" /* the name of this program for PAM */ - /* The file containing the context to run - * the scripts under. */ -int authenticate_via_pam( const char *user , pam_handle_t **pamh); - -/* authenticate_via_pam() - * - * in: user - * out: nothing - * return: value condition - * ----- --------- - * 1 pam thinks that the user authenticated themselves properly - * 0 otherwise - * - * this function uses pam to authenticate the user running this - * program. this is the only function in this program that makes pam - * calls. - * - */ - -int authenticate_via_pam( const char *user , pam_handle_t **pamh) { - - struct pam_conv *conv; - int result = 0; /* our result, set to 0 (not authenticated) by default */ - - /* this is a jump table of functions for pam to use when it wants to * - * communicate with the user. we'll be using misc_conv(), which is * - * provided for us via pam_misc.h. */ - struct pam_conv pam_conversation = { - misc_conv, - NULL - }; - conv = &pam_conversation; - - - /* make `p_pam_handle' a valid pam handle so we can use it when * - * calling pam functions. */ - if( PAM_SUCCESS != pam_start( SERVICE_NAME, - user, - conv, - pamh ) ) { - fprintf( stderr, _("failed to initialize PAM\n") ); - exit( -1 ); - } - - if( PAM_SUCCESS != pam_set_item(*pamh, PAM_RUSER, user)) - { - fprintf( stderr, _("failed to pam_set_item()\n") ); - exit( -1 ); - } - - /* Ask PAM to authenticate the user running this program */ - if( PAM_SUCCESS == pam_authenticate(*pamh,0) ) { - if ( PAM_SUCCESS == pam_open_session(*pamh, 0) ) - result = 1; /* user authenticated OK! */ - } - return( result ); - -} /* authenticate_via_pam() */ - -int -main (int argc, char **argv) -{ - pam_handle_t *pamh; - int childPid; - - if (argc < 1) - exit (-1); - - if (!authenticate_via_pam(argv[1],&pamh)) - exit(-1); - - childPid = fork(); - if (childPid < 0) { - /* error in fork() */ - fprintf(stderr, _("login: failure forking: %m")); - pam_close_session(pamh, 0); - /* We're done with PAM. Free `pam_handle'. */ - pam_end( pamh, PAM_SUCCESS ); - exit(0); - } - if (childPid) { - close(0); close(1); close(2); - struct sigaction sa; - memset(&sa,0,sizeof(sa)); - sa.sa_handler = SIG_IGN; - sigaction(SIGQUIT, &sa, NULL); - sigaction(SIGINT, &sa, NULL); - while(wait(NULL) == -1 && errno == EINTR) /**/ ; - openlog("login", LOG_ODELAY, LOG_AUTHPRIV); - pam_close_session(pamh, 0); - /* We're done with PAM. Free `pam_handle'. */ - pam_end( pamh, PAM_SUCCESS ); - exit(0); - } - argv[0]=strdup ("/bin/sh"); - argv[1]=NULL; - - /* NOTE: The environment has not been sanitized. LD_PRELOAD and other fun - * things could be set. */ - execv("/bin/sh",argv); - fprintf(stderr,"Failure\n"); - return 0; -} diff --git a/modules/pam_selinux/tst-pam_selinux b/modules/pam_selinux/tst-pam_selinux deleted file mode 100755 index 14c3d82f..00000000 --- a/modules/pam_selinux/tst-pam_selinux +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/sh -../../tests/tst-dlopen .libs/pam_selinux.so diff --git a/modules/pam_sepermit/.cvsignore b/modules/pam_sepermit/.cvsignore deleted file mode 100644 index 258e7207..00000000 --- a/modules/pam_sepermit/.cvsignore +++ /dev/null @@ -1,10 +0,0 @@ -*.la -*.lo -*.so -*~ -.deps -.libs -Makefile -Makefile.in -README -pam_sepermit.8 diff --git a/modules/pam_sepermit/Makefile.am b/modules/pam_sepermit/Makefile.am deleted file mode 100644 index 579e142f..00000000 --- a/modules/pam_sepermit/Makefile.am +++ /dev/null @@ -1,43 +0,0 @@ -# -# Copyright (c) 2005, 2006, 2007 Thorsten Kukuk <kukuk@thkukuk.de> -# Copyright (c) 2008 Red Hat, Inc. -# - -CLEANFILES = *~ -MAINTAINERCLEANFILES = $(MANS) README - -EXTRA_DIST = README $(XMLS) pam_sepermit.8 sepermit.conf tst-pam_sepermit - -if HAVE_LIBSELINUX - TESTS = tst-pam_sepermit - man_MANS = pam_sepermit.8 -endif - -XMLS = README.xml pam_sepermit.8.xml - -securelibdir = $(SECUREDIR) -secureconfdir = $(SCONFIGDIR) -sepermitlockdir = ${localstatedir}/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_LOCKDIR=\"$(sepermitlockdir)\" - -pam_sepermit_la_LIBADD = -L$(top_builddir)/libpam -lpam @LIBSELINUX@ -pam_sepermit_la_LDFLAGS = -no-undefined -avoid-version -module -if HAVE_VERSIONING - pam_sepermit_la_LDFLAGS += -Wl,--version-script=$(srcdir)/../modules.map -endif - -if HAVE_LIBSELINUX - secureconf_DATA = sepermit.conf - sepermitlock_DATA = - - securelib_LTLIBRARIES = pam_sepermit.la -endif -if ENABLE_REGENERATE_MAN -noinst_DATA = README pam_sepermit.8 -README: pam_sepermit.8.xml --include $(top_srcdir)/Make.xml.rules -endif diff --git a/modules/pam_sepermit/README.xml b/modules/pam_sepermit/README.xml deleted file mode 100644 index bb65951c..00000000 --- a/modules/pam_sepermit/README.xml +++ /dev/null @@ -1,41 +0,0 @@ -<?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_sepermit.8.xml"> ---> -]> - -<article> - - <articleinfo> - - <title> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" - href="pam_sepermit.8.xml" xpointer='xpointer(//refnamediv[@id = "pam_sepermit-name"]/*)'/> - </title> - - </articleinfo> - - <section> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" - href="pam_sepermit.8.xml" xpointer='xpointer(//refsect1[@id = "pam_sepermit-description"]/*)'/> - </section> - - <section> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" - href="pam_sepermit.8.xml" xpointer='xpointer(//refsect1[@id = "pam_sepermit-options"]/*)'/> - </section> - - <section> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" - href="pam_sepermit.8.xml" xpointer='xpointer(//refsect1[@id = "pam_sepermit-examples"]/*)'/> - </section> - - <section> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" - href="pam_sepermit.8.xml" xpointer='xpointer(//refsect1[@id = "pam_sepermit-author"]/*)'/> - </section> - -</article> diff --git a/modules/pam_sepermit/pam_sepermit.8.xml b/modules/pam_sepermit/pam_sepermit.8.xml deleted file mode 100644 index c2546b62..00000000 --- a/modules/pam_sepermit/pam_sepermit.8.xml +++ /dev/null @@ -1,189 +0,0 @@ -<?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_sepermit"> - - <refmeta> - <refentrytitle>pam_sepermit</refentrytitle> - <manvolnum>8</manvolnum> - <refmiscinfo class="sectdesc">Linux-PAM Manual</refmiscinfo> - </refmeta> - - <refnamediv id="pam_sepermit-name"> - <refname>pam_sepermit</refname> - <refpurpose>PAM module to allow/deny login depending on SELinux enforcement state</refpurpose> - </refnamediv> - - <refsynopsisdiv> - <cmdsynopsis id="pam_sepermit-cmdsynopsis"> - <command>pam_sepermit.so</command> - <arg choice="opt"> - debug - </arg> - <arg choice="opt"> - conf=<replaceable>/path/to/config/file</replaceable> - </arg> - </cmdsynopsis> - </refsynopsisdiv> - - <refsect1 id="pam_sepermit-description"> - <title>DESCRIPTION</title> - <para> - The pam_sepermit 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_sepermit 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 <emphasis>@</emphasis> character it means that all - users in the group <replaceable>name</replaceable> match. If it is prefixed - 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_sepermit - 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_sepermit 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_sepermit-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_sepermit-services"> - <title>MODULE SERVICES PROVIDED</title> - <para> - Only the <option>auth</option> and <option>account</option> - services are supported. - </para> - </refsect1> - - <refsect1 id='pam_sepermit-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_sepermit-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_sepermit-examples'> - <title>EXAMPLES</title> - <programlisting> -auth [success=done ignore=ignore default=bad] pam_sepermit.so -auth required pam_unix.so -account required pam_unix.so -session required pam_permit.so - </programlisting> - </refsect1> - - <refsect1 id='pam_sepermit-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_sepermit-author'> - <title>AUTHOR</title> - <para> - pam_sepermit was written by Tomas Mraz <tmraz@redhat.com>. - </para> - </refsect1> - -</refentry> diff --git a/modules/pam_sepermit/pam_sepermit.c b/modules/pam_sepermit/pam_sepermit.c deleted file mode 100644 index 47f95030..00000000 --- a/modules/pam_sepermit/pam_sepermit.c +++ /dev/null @@ -1,405 +0,0 @@ -/****************************************************************************** - * A module for Linux-PAM that allows/denies acces based on SELinux state. - * - * Copyright (c) 2007, 2008 Red Hat, Inc. - * Originally written by Tomas Mraz <tmraz@redhat.com> - * Contributions by Dan Walsh <dwalsh@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> -#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 - -#include <security/pam_modules.h> -#include <security/_pam_macros.h> -#include <security/pam_modutil.h> -#include <security/pam_ext.h> - -#include <selinux/selinux.h> - -#define MODULE "pam_sepermit" -#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, MODULE, 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, - const char *seuser, int debug) -{ - FILE *f; - char *line = NULL; - char *start; - size_t len = 0; - int matched = 0; - int exclusive = 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; - char *sptr; - char *opt; - - 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'; - start = strtok_r(start, OPT_DELIM, &sptr); - - 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; - } - } - 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); - if (matched) - return exclusive ? sepermit_lock(pamh, user, debug) : 0; - else - return -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_sepermit_modstruct = { - "pam_sepermit", - pam_sm_authenticate, - pam_sm_setcred, - pam_sm_acct_mgmt, - NULL, - NULL, - NULL -}; -#endif - diff --git a/modules/pam_sepermit/sepermit.conf b/modules/pam_sepermit/sepermit.conf deleted file mode 100644 index 951f3dfe..00000000 --- a/modules/pam_sepermit/sepermit.conf +++ /dev/null @@ -1,11 +0,0 @@ -# /etc/security/sepermit.conf -# -# Each line contains either: -# - 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 diff --git a/modules/pam_sepermit/tst-pam_sepermit b/modules/pam_sepermit/tst-pam_sepermit deleted file mode 100755 index 6e6d2363..00000000 --- a/modules/pam_sepermit/tst-pam_sepermit +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/sh -../../tests/tst-dlopen .libs/pam_sepermit.so diff --git a/modules/pam_shells/.cvsignore b/modules/pam_shells/.cvsignore deleted file mode 100644 index f86c33b1..00000000 --- a/modules/pam_shells/.cvsignore +++ /dev/null @@ -1,8 +0,0 @@ -*.la -*.lo -.deps -.libs -Makefile -Makefile.in -README -pam_shells.8 diff --git a/modules/pam_shells/Makefile.am b/modules/pam_shells/Makefile.am deleted file mode 100644 index 543e01b4..00000000 --- a/modules/pam_shells/Makefile.am +++ /dev/null @@ -1,31 +0,0 @@ -# -# Copyright (c) 2005, 2006 Thorsten Kukuk <kukuk@suse.de> -# - -CLEANFILES = *~ - -EXTRA_DIST = README $(MANS) $(XMLS) tst-pam_shells - -man_MANS = pam_shells.8 -XMLS = README.xml pam_shells.8.xml - -TESTS = tst-pam_shells - -securelibdir = $(SECUREDIR) -secureconfdir = $(SCONFIGDIR) - -AM_CFLAGS = -I$(top_srcdir)/libpam/include -I$(top_srcdir)/libpamc/include -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 = -L$(top_builddir)/libpam -lpam - -if ENABLE_REGENERATE_MAN -noinst_DATA = README -README: pam_shells.8.xml --include $(top_srcdir)/Make.xml.rules -endif - diff --git a/modules/pam_shells/README.xml b/modules/pam_shells/README.xml deleted file mode 100644 index 154b97b5..00000000 --- a/modules/pam_shells/README.xml +++ /dev/null @@ -1,41 +0,0 @@ -<?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> - - <articleinfo> - - <title> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" - href="pam_shells.8.xml" xpointer='xpointer(//refnamediv[@id = "pam_shells-name"]/*)'/> - </title> - - </articleinfo> - - <section> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" - href="pam_shells.8.xml" xpointer='xpointer(//refsect1[@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"]/*)'/> - </section> - - <section> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" - href="pam_shells.8.xml" xpointer='xpointer(//refsect1[@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"]/*)'/> - </section> - -</article> diff --git a/modules/pam_shells/pam_shells.8.xml b/modules/pam_shells/pam_shells.8.xml deleted file mode 100644 index abbd5cbd..00000000 --- a/modules/pam_shells/pam_shells.8.xml +++ /dev/null @@ -1,117 +0,0 @@ -<?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"> - - <refmeta> - <refentrytitle>pam_shells</refentrytitle> - <manvolnum>8</manvolnum> - <refmiscinfo class="sectdesc">Linux-PAM Manual</refmiscinfo> - </refmeta> - - <refnamediv 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"> - <command>pam_shells.so</command> - </cmdsynopsis> - </refsynopsisdiv> - - <refsect1 id="pam_shells-description"> - - <title>DESCRIPTION</title> - - <para> - pam_shells is a PAM module that only allows access to the - system if the users shell is listed in <filename>/etc/shells</filename>. - </para> - <para> - It also checks if <filename>/etc/shells</filename> is a plain - file and not world writable. - </para> - </refsect1> - - <refsect1 id="pam_shells-options"> - - <title>OPTIONS</title> - <para> This module does not recognise any options.</para> - </refsect1> - - <refsect1 id="pam_shells-services"> - <title>MODULE SERVICES PROVIDED</title> - <para> - The services <option>auth</option> and <option>account</option> - are supported. - </para> - </refsect1> - - <refsect1 id='pam_shells-return_values'> - <title>RETURN VALUES</title> - <variablelist> - <varlistentry> - <term>PAM_AUTH_ERR</term> - <listitem> - <para> - Access to the system was denied. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term>PAM_SUCCESS</term> - <listitem> - <para> - The users login shell was listed as valid shell in - <filename>/etc/shells</filename>. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term>PAM_SERVICE_ERR</term> - <listitem> - <para> - The module was not able to get the name of the user. - </para> - </listitem> - </varlistentry> - </variablelist> - </refsect1> - - <refsect1 id='pam_shells-examples'> - <title>EXAMPLES</title> - <para> - <programlisting> -auth required pam_shells.so - </programlisting> - </para> - </refsect1> - - <refsect1 id='pam_shells-see_also'> - <title>SEE ALSO</title> - <para> - <citerefentry> - <refentrytitle>shells</refentrytitle><manvolnum>5</manvolnum> - </citerefentry>, - <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_shells-author'> - <title>AUTHOR</title> - <para> - pam_shells was written by Erik Troan <ewt@redhat.com>. - </para> - </refsect1> - -</refentry> diff --git a/modules/pam_shells/pam_shells.c b/modules/pam_shells/pam_shells.c deleted file mode 100644 index 89fc297e..00000000 --- a/modules/pam_shells/pam_shells.c +++ /dev/null @@ -1,146 +0,0 @@ -/* pam_shells module */ - -#define SHELL_FILE "/etc/shells" - -/* - * by Erik Troan <ewt@redhat.com>, Red Hat Software. - * August 5, 1996. - * This code shamelessly ripped from the pam_securetty module. - */ - -#include "config.h" - -#include <pwd.h> -#include <stdarg.h> -#include <string.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <sys/stat.h> -#include <syslog.h> -#include <unistd.h> - -/* - * here, we make a definition for the externally accessible function - * in this file (this definition is required for static a module - * but strongly encouraged generally) it is used to instruct the - * modules include file to define the function prototypes. - */ - -#define PAM_SM_AUTH -#define PAM_SM_ACCOUNT - -#include <security/pam_modules.h> -#include <security/pam_modutil.h> -#include <security/pam_ext.h> - -static int perform_check(pam_handle_t *pamh) -{ - int retval = PAM_AUTH_ERR; - const char *userName; - char *userShell; - char shellFileLine[256]; - struct stat sb; - struct passwd * pw; - FILE * shellFile; - - retval = pam_get_user(pamh, &userName, NULL); - if (retval != PAM_SUCCESS) { - return PAM_SERVICE_ERR; - } - - if (!userName || (userName[0] == '\0')) { - - /* Don't let them use a NULL username... */ - retval = pam_get_user(pamh,&userName,NULL); - if (retval != PAM_SUCCESS) - return PAM_SERVICE_ERR; - - /* It could still be NULL the second time. */ - if (!userName || (userName[0] == '\0')) - return PAM_SERVICE_ERR; - } - - pw = pam_modutil_getpwnam(pamh, userName); - if (!pw) { - return PAM_AUTH_ERR; /* user doesn't exist */ - } - userShell = pw->pw_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 ((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", - SHELL_FILE); - 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); - return PAM_SERVICE_ERR; - } - - retval = 1; - - while(retval && (fgets(shellFileLine, 255, shellFile) != NULL)) { - if (shellFileLine[strlen(shellFileLine) - 1] == '\n') - shellFileLine[strlen(shellFileLine) - 1] = '\0'; - retval = strcmp(shellFileLine, userShell); - } - - fclose(shellFile); - - if (retval) { - return PAM_AUTH_ERR; - } else { - return PAM_SUCCESS; - } -} - -/* --- authentication management functions (only) --- */ - -PAM_EXTERN -int pam_sm_authenticate(pam_handle_t *pamh, int flags UNUSED, - int argc UNUSED, const char **argv UNUSED) -{ - return perform_check(pamh); -} - -PAM_EXTERN -int pam_sm_setcred(pam_handle_t *pamh UNUSED, int flags UNUSED, - int argc UNUSED, const char **argv UNUSED) -{ - return PAM_SUCCESS; -} - -/* --- account management functions (only) --- */ - -PAM_EXTERN -int pam_sm_acct_mgmt(pam_handle_t *pamh, int flags UNUSED, - int argc UNUSED, const char **argv UNUSED) -{ - return perform_check(pamh); -} - -#ifdef PAM_STATIC - -/* static module data */ - -struct pam_module _pam_shells_modstruct = { - "pam_shells", - pam_sm_authenticate, - pam_sm_setcred, - pam_sm_acct_mgmt, - NULL, - NULL, - NULL, -}; - -#endif /* PAM_STATIC */ - -/* end of module definition */ diff --git a/modules/pam_shells/tst-pam_shells b/modules/pam_shells/tst-pam_shells deleted file mode 100755 index dccc33d0..00000000 --- a/modules/pam_shells/tst-pam_shells +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/sh -../../tests/tst-dlopen .libs/pam_shells.so diff --git a/modules/pam_stress/.cvsignore b/modules/pam_stress/.cvsignore deleted file mode 100644 index 9fb98574..00000000 --- a/modules/pam_stress/.cvsignore +++ /dev/null @@ -1,6 +0,0 @@ -*.la -*.lo -.deps -.libs -Makefile -Makefile.in diff --git a/modules/pam_stress/Makefile.am b/modules/pam_stress/Makefile.am deleted file mode 100644 index b5f80938..00000000 --- a/modules/pam_stress/Makefile.am +++ /dev/null @@ -1,20 +0,0 @@ -# -# Copyright (c) 2005, 2006 Thorsten Kukuk <kukuk@suse.de> -# - -CLEANFILES = *~ - -EXTRA_DIST = README tst-pam_stress - -TESTS = tst-pam_stress - -securelibdir = $(SECUREDIR) -secureconfdir = $(SCONFIGDIR) - -AM_CFLAGS = -I$(top_srcdir)/libpam/include -I$(top_srcdir)/libpamc/include -AM_LDFLAGS = -no-undefined -avoid-version -module -if HAVE_VERSIONING - AM_LDFLAGS += -Wl,--version-script=$(srcdir)/../modules.map -endif -securelib_LTLIBRARIES = pam_stress.la -pam_stress_la_LIBADD = -L$(top_builddir)/libpam -lpam diff --git a/modules/pam_stress/README b/modules/pam_stress/README deleted file mode 100644 index e64bf2d3..00000000 --- a/modules/pam_stress/README +++ /dev/null @@ -1,64 +0,0 @@ -# -# This describes the behavior of this module with respect to the -# /etc/pam.conf file. -# -# writen by Andrew Morgan <morgan@parc.power.net> -# - -This module recognizes the following arguments. - -debug put lots of information in syslog. - *NOTE* this option writes passwords to syslog, so - don't use anything sensitive when testing. - -no_warn don't give warnings about things (otherwise warnings are issued - via the conversation function) - -use_first_pass don't prompt for a password, for pam_sm_authentication - function just use item PAM_AUTHTOK. - -try_first_pass don't prompt for a password unless there has been no - previous authentication token (item PAM_AUTHTOK is NULL) - -rootok This is intended for the pam_sm_chauthtok function and - it instructs this function to permit root to change - the user's password without entering the old password. - -The following arguments are acted on by the module. They are intended -to make the module give the impression of failing as a fully -functioning module might. - -expired an argument intended for the account and chauthtok module - parts. It instructs the module to act as if the user's - password has expired - -fail_1 this instructs the module to make its first function fail. - -fail_2 this instructs the module to make its second function (if there - is one) fail. - - The function break up is indicated in the Module - Developers' Guide. Listed here it is: - - service function 1 function 2 - ------- ---------- ---------- - auth pam_sm_authenticate pam_sm_setcred - password pam_sm_chauthtok - session pam_sm_open_session pam_sm_close_session - account pam_sm_acct_mgmt - -prelim for pam_sm_chauthtok, means fail on PAM_PRELIM_CHECK. - -required for pam_sm_chauthtok, means fail if the user hasn't already - been authenticated by this module. (See stress_new_pwd data - item below.) - -# -# data strings that this module uses are the following: -# - -data name value(s) Comments ---------- -------- -------- -stress_new_pwd yes tells pam_sm_chauthtok that - pam_sm_acct_mgmt says we need a new - password diff --git a/modules/pam_stress/pam_stress.c b/modules/pam_stress/pam_stress.c deleted file mode 100644 index c254868f..00000000 --- a/modules/pam_stress/pam_stress.c +++ /dev/null @@ -1,570 +0,0 @@ -/* - * pam_stress module - * - * created by Andrew Morgan <morgan@linux.kernel.org> 1996/3/12 - */ - -#include "config.h" - -#include <stdlib.h> -#include <stdio.h> - -#include <syslog.h> - -#include <stdarg.h> -#include <string.h> -#include <unistd.h> - -/* - * here, we make definitions for the externally accessible functions - * in this file (these definitions are required for static modules - * but strongly encouraged generally) they are used to instruct the - * modules include file to define their prototypes. - */ - -#define PAM_SM_AUTH -#define PAM_SM_ACCOUNT -#define PAM_SM_SESSION -#define PAM_SM_PASSWORD - -#include <security/pam_modules.h> -#include <security/_pam_macros.h> -#include <security/pam_ext.h> - -/* ---------- */ - -/* an internal function to turn all possible test arguments into bits - of a ctrl number */ - -/* generic options */ - -#define PAM_ST_DEBUG 01 -#define PAM_ST_NO_WARN 02 -#define PAM_ST_USE_PASS1 04 -#define PAM_ST_TRY_PASS1 010 -#define PAM_ST_ROOTOK 020 - -/* simulation options */ - -#define PAM_ST_EXPIRED 040 -#define PAM_ST_FAIL_1 0100 -#define PAM_ST_FAIL_2 0200 -#define PAM_ST_PRELIM 0400 -#define PAM_ST_REQUIRE_PWD 01000 - -/* some syslogging */ - -static void -_pam_report (const pam_handle_t *pamh, int ctrl, const char *name, - int flags, int argc, const char **argv) -{ - if (ctrl & PAM_ST_DEBUG) { - pam_syslog(pamh, LOG_DEBUG, "CALLED: %s", name); - pam_syslog(pamh, LOG_DEBUG, "FLAGS : 0%o%s", - flags, (flags & PAM_SILENT) ? " (silent)":""); - pam_syslog(pamh, LOG_DEBUG, "CTRL = 0%o", ctrl); - pam_syslog(pamh, LOG_DEBUG, "ARGV :"); - while (argc--) { - pam_syslog(pamh, LOG_DEBUG, " \"%s\"", *argv++); - } - } -} - -static int -_pam_parse (const pam_handle_t *pamh, int argc, const char **argv) -{ - int ctrl=0; - - /* step through arguments */ - for (ctrl=0; argc-- > 0; ++argv) { - - /* generic options */ - - if (!strcmp(*argv,"debug")) - ctrl |= PAM_ST_DEBUG; - else if (!strcmp(*argv,"no_warn")) - ctrl |= PAM_ST_NO_WARN; - else if (!strcmp(*argv,"use_first_pass")) - ctrl |= PAM_ST_USE_PASS1; - else if (!strcmp(*argv,"try_first_pass")) - ctrl |= PAM_ST_TRY_PASS1; - else if (!strcmp(*argv,"rootok")) - ctrl |= PAM_ST_ROOTOK; - - /* simulation options */ - - else if (!strcmp(*argv,"expired")) /* signal password needs - renewal */ - ctrl |= PAM_ST_EXPIRED; - else if (!strcmp(*argv,"fail_1")) /* instruct fn 1 to fail */ - ctrl |= PAM_ST_FAIL_1; - else if (!strcmp(*argv,"fail_2")) /* instruct fn 2 to fail */ - ctrl |= PAM_ST_FAIL_2; - else if (!strcmp(*argv,"prelim")) /* instruct pam_sm_setcred - to fail on first call */ - ctrl |= PAM_ST_PRELIM; - else if (!strcmp(*argv,"required")) /* module is fussy about the - user being authenticated */ - ctrl |= PAM_ST_REQUIRE_PWD; - - else { - pam_syslog(pamh, LOG_ERR, "unknown option: %s", *argv); - } - } - - return ctrl; -} - -static int converse(pam_handle_t *pamh, int nargs - , struct pam_message **message - , struct pam_response **response) -{ - int retval; - const void *void_conv; - const struct pam_conv *conv; - - retval = pam_get_item(pamh,PAM_CONV,&void_conv); - conv = void_conv; - if (retval == PAM_SUCCESS && conv) { - retval = conv->conv(nargs, (const struct pam_message **) message - , response, conv->appdata_ptr); - if (retval != PAM_SUCCESS) { - pam_syslog(pamh, LOG_ERR, "converse returned %d: %s", - retval, pam_strerror(pamh, retval)); - } - } else { - pam_syslog(pamh, LOG_ERR, "converse failed to get pam_conv"); - if (retval == PAM_SUCCESS) - retval = PAM_BAD_ITEM; /* conv was null */ - } - - return retval; -} - -/* authentication management functions */ - -static int stress_get_password(pam_handle_t *pamh, int flags - , int ctrl, char **password) -{ - const void *pam_pass; - char *pass; - - if ( (ctrl & (PAM_ST_TRY_PASS1|PAM_ST_USE_PASS1)) - && (pam_get_item(pamh,PAM_AUTHTOK,&pam_pass) - == PAM_SUCCESS) - && (pam_pass != NULL) ) { - if ((pass = strdup(pam_pass)) == NULL) - return PAM_BUF_ERR; - } else if ((ctrl & PAM_ST_USE_PASS1)) { - pam_syslog(pamh, LOG_WARNING, "no forwarded password"); - return PAM_PERM_DENIED; - } else { /* we will have to get one */ - struct pam_message msg[1],*pmsg[1]; - struct pam_response *resp; - int retval; - - /* set up conversation call */ - - pmsg[0] = &msg[0]; - msg[0].msg_style = PAM_PROMPT_ECHO_OFF; - msg[0].msg = "STRESS Password: "; - resp = NULL; - - if ((retval = converse(pamh,1,pmsg,&resp)) != PAM_SUCCESS) { - return retval; - } - - if (resp) { - if ((resp[0].resp == NULL) && (ctrl & PAM_ST_DEBUG)) { - pam_syslog(pamh, LOG_DEBUG, - "pam_sm_authenticate: NULL authtok given"); - } - if ((flags & PAM_DISALLOW_NULL_AUTHTOK) - && resp[0].resp == NULL) { - free(resp); - return PAM_AUTH_ERR; - } - - pass = resp[0].resp; /* remember this! */ - - resp[0].resp = NULL; - } else { - if (ctrl & PAM_ST_DEBUG) { - pam_syslog(pamh, LOG_DEBUG, - "pam_sm_authenticate: no error reported"); - pam_syslog(pamh, LOG_DEBUG, - "getting password, but NULL returned!?"); - } - return PAM_CONV_ERR; - } - if (resp) - free(resp); - } - - *password = pass; /* this *MUST* be free()'d by this module */ - - return PAM_SUCCESS; -} - -/* function to clean up data items */ - -static void -wipe_up (pam_handle_t *pamh UNUSED, void *data, int error UNUSED) -{ - free(data); -} - -PAM_EXTERN -int pam_sm_authenticate(pam_handle_t *pamh, int flags, - int argc, const char **argv) -{ - const char *username; - int retval=PAM_SUCCESS; - char *pass; - int ctrl; - - D(("called.")); - - ctrl = _pam_parse(pamh, argc, argv); - _pam_report(pamh, ctrl, "pam_sm_authenticate", flags, argc, argv); - - /* try to get the username */ - - retval = pam_get_user(pamh, &username, "username: "); - if (retval != PAM_SUCCESS || !username) { - pam_syslog(pamh, LOG_WARNING, - "pam_sm_authenticate: failed to get username"); - if (retval == PAM_SUCCESS) - retval = PAM_USER_UNKNOWN; /* username was null */ - return retval; - } - else if ((ctrl & PAM_ST_DEBUG) && (retval == PAM_SUCCESS)) { - pam_syslog(pamh, LOG_DEBUG, - "pam_sm_authenticate: username = %s", username); - } - - /* now get the password */ - - retval = stress_get_password(pamh,flags,ctrl,&pass); - if (retval != PAM_SUCCESS) { - pam_syslog(pamh, LOG_WARNING, - "pam_sm_authenticate: failed to get a password"); - return retval; - } - - /* try to set password item */ - - retval = pam_set_item(pamh,PAM_AUTHTOK,pass); - _pam_overwrite(pass); /* clean up local copy of password */ - free(pass); - pass = NULL; - if (retval != PAM_SUCCESS) { - pam_syslog(pamh, LOG_WARNING, - "pam_sm_authenticate: failed to store new password"); - return retval; - } - - /* if we are debugging then we print the password */ - - if (ctrl & PAM_ST_DEBUG) { - const void *pam_pass; - (void) pam_get_item(pamh,PAM_AUTHTOK,&pam_pass); - pam_syslog(pamh, LOG_DEBUG, - "pam_st_authenticate: password entered is: [%s]", - (const char *)pam_pass); - } - - /* if we signal a fail for this function then fail */ - - if ((ctrl & PAM_ST_FAIL_1) && retval == PAM_SUCCESS) - return PAM_PERM_DENIED; - - return retval; -} - -PAM_EXTERN -int pam_sm_setcred(pam_handle_t *pamh, int flags, - int argc, const char **argv) -{ - int ctrl = _pam_parse(pamh, argc, argv); - - D(("called. [post parsing]")); - - _pam_report(pamh, ctrl, "pam_sm_setcred", flags, argc, argv); - - if (ctrl & PAM_ST_FAIL_2) - return PAM_CRED_ERR; - - return PAM_SUCCESS; -} - -/* account management functions */ - -PAM_EXTERN -int pam_sm_acct_mgmt(pam_handle_t *pamh, int flags, - int argc, const char **argv) -{ - int ctrl = _pam_parse(pamh, argc, argv); - - D(("called. [post parsing]")); - - _pam_report(pamh, ctrl,"pam_sm_acct_mgmt", flags, argc, argv); - - if (ctrl & PAM_ST_FAIL_1) - return PAM_PERM_DENIED; - else if (ctrl & PAM_ST_EXPIRED) { - int retval; - void *text = strdup("yes"); - if (!text) - return PAM_BUF_ERR; - retval = pam_set_data(pamh,"stress_new_pwd",text,wipe_up); - if (retval != PAM_SUCCESS) { - pam_syslog(pamh, LOG_DEBUG, - "pam_sm_acct_mgmt: failed setting stress_new_pwd"); - free(text); - return retval; - } - - if (ctrl & PAM_ST_DEBUG) { - pam_syslog(pamh, LOG_DEBUG, - "pam_sm_acct_mgmt: need a new password"); - } - return PAM_NEW_AUTHTOK_REQD; - } - - return PAM_SUCCESS; -} - -PAM_EXTERN -int pam_sm_open_session(pam_handle_t *pamh, int flags, - int argc, const char **argv) -{ - const void *username, *service; - int ctrl = _pam_parse(pamh, argc, argv); - - D(("called. [post parsing]")); - - _pam_report(pamh, ctrl,"pam_sm_open_session", flags, argc, argv); - - if ((pam_get_item(pamh, PAM_USER, &username) - != PAM_SUCCESS || !username) - || (pam_get_item(pamh, PAM_SERVICE, &service) - != PAM_SUCCESS || !service)) { - pam_syslog(pamh, LOG_WARNING, "pam_sm_open_session: for whom?"); - return PAM_SESSION_ERR; - } - - pam_syslog(pamh, LOG_NOTICE, "opened [%s] session for user [%s]", - (const char *)service, (const char *)username); - - if (ctrl & PAM_ST_FAIL_1) - return PAM_SESSION_ERR; - - return PAM_SUCCESS; -} - -PAM_EXTERN -int pam_sm_close_session(pam_handle_t *pamh, int flags, - int argc, const char **argv) -{ - const void *username, *service; - int ctrl = _pam_parse(pamh, argc, argv); - - D(("called. [post parsing]")); - - _pam_report(pamh, ctrl,"pam_sm_close_session", flags, argc, argv); - - if ((pam_get_item(pamh, PAM_USER, &username) - != PAM_SUCCESS || !username) - || (pam_get_item(pamh, PAM_SERVICE, &service) - != PAM_SUCCESS || !service)) { - pam_syslog(pamh, LOG_WARNING, "pam_sm_close_session: for whom?"); - return PAM_SESSION_ERR; - } - - pam_syslog(pamh, LOG_NOTICE, "closed [%s] session for user [%s]", - (const char *)service, (const char *)username); - - if (ctrl & PAM_ST_FAIL_2) - return PAM_SESSION_ERR; - - return PAM_SUCCESS; -} - -PAM_EXTERN -int pam_sm_chauthtok(pam_handle_t *pamh, int flags, - int argc, const char **argv) -{ - int retval; - int ctrl = _pam_parse(pamh, argc, argv); - - D(("called. [post parsing]")); - - _pam_report(pamh, ctrl,"pam_sm_chauthtok", flags, argc, argv); - - /* this function should be called twice by the Linux-PAM library */ - - if (flags & PAM_PRELIM_CHECK) { /* first call */ - if (ctrl & PAM_ST_DEBUG) { - pam_syslog(pamh, LOG_DEBUG, "pam_sm_chauthtok: prelim check"); - } - if (ctrl & PAM_ST_PRELIM) - return PAM_TRY_AGAIN; - - return PAM_SUCCESS; - } else if (flags & PAM_UPDATE_AUTHTOK) { /* second call */ - struct pam_message msg[3],*pmsg[3]; - struct pam_response *resp; - const void *text; - char *txt=NULL; - int i; - - if (ctrl & PAM_ST_DEBUG) { - pam_syslog(pamh, LOG_DEBUG, "pam_sm_chauthtok: alter password"); - } - - if (ctrl & PAM_ST_FAIL_1) - return PAM_AUTHTOK_LOCK_BUSY; - - if ( !(ctrl && PAM_ST_EXPIRED) - && (flags & PAM_CHANGE_EXPIRED_AUTHTOK) - && (pam_get_data(pamh,"stress_new_pwd", &text) - != PAM_SUCCESS || strcmp(text,"yes"))) { - return PAM_SUCCESS; /* the token has not expired */ - } - - /* the password should be changed */ - - if ((ctrl & PAM_ST_REQUIRE_PWD) - && !(getuid() == 0 && (ctrl & PAM_ST_ROOTOK)) - ) { /* first get old one? */ - char *pass; - - if (ctrl & PAM_ST_DEBUG) { - pam_syslog(pamh, LOG_DEBUG, - "pam_sm_chauthtok: getting old password"); - } - retval = stress_get_password(pamh,flags,ctrl,&pass); - if (retval != PAM_SUCCESS) { - pam_syslog(pamh, LOG_DEBUG, - "pam_sm_chauthtok: no password obtained"); - return retval; - } - retval = pam_set_item(pamh, PAM_OLDAUTHTOK, pass); - _pam_overwrite(pass); - free(pass); - pass = NULL; - if (retval != PAM_SUCCESS) { - pam_syslog(pamh, LOG_DEBUG, - "pam_sm_chauthtok: could not set OLDAUTHTOK"); - return retval; - } - } - - /* set up for conversation */ - - if (!(flags & PAM_SILENT)) { - const void *username; - - if ( pam_get_item(pamh, PAM_USER, &username) - || username == NULL ) { - pam_syslog(pamh, LOG_ERR, "no username set"); - return PAM_USER_UNKNOWN; - } - pmsg[0] = &msg[0]; - msg[0].msg_style = PAM_TEXT_INFO; - if (asprintf(&txt, _("Changing STRESS password for %s."), - (const char *)username) < 0) { - pam_syslog(pamh, LOG_CRIT, "out of memory"); - return PAM_BUF_ERR; - } - - msg[0].msg = txt; - i = 1; - } else { - i = 0; - } - - pmsg[i] = &msg[i]; - msg[i].msg_style = PAM_PROMPT_ECHO_OFF; - msg[i++].msg = _("Enter new STRESS password: "); - pmsg[i] = &msg[i]; - msg[i].msg_style = PAM_PROMPT_ECHO_OFF; - msg[i++].msg = _("Retype new STRESS password: "); - resp = NULL; - - retval = converse(pamh,i,pmsg,&resp); - if (txt) { - free(txt); - txt = NULL; /* clean up */ - } - if (retval != PAM_SUCCESS) { - return retval; - } - - if (resp == NULL) { - pam_syslog(pamh, LOG_ERR, - "pam_sm_chauthtok: no response from conv"); - return PAM_CONV_ERR; - } - - /* store the password */ - - if (resp[i-2].resp && resp[i-1].resp) { - if (strcmp(resp[i-2].resp,resp[i-1].resp)) { - /* passwords are not the same; forget and return error */ - - _pam_drop_reply(resp, i); - - if (!(flags & PAM_SILENT) && !(ctrl & PAM_ST_NO_WARN)) { - pmsg[0] = &msg[0]; - msg[0].msg_style = PAM_ERROR_MSG; - msg[0].msg = _("Verification mis-typed; " - "password unchanged"); - resp = NULL; - (void) converse(pamh,1,pmsg,&resp); - if (resp) { - _pam_drop_reply(resp, 1); - } - } - return PAM_AUTHTOK_ERR; - } - - if (pam_get_item(pamh,PAM_AUTHTOK,&text) - == PAM_SUCCESS) { - (void) pam_set_item(pamh,PAM_OLDAUTHTOK,text); - text = NULL; - } - (void) pam_set_item(pamh,PAM_AUTHTOK,resp[0].resp); - } else { - pam_syslog(pamh, LOG_DEBUG, - "pam_sm_chauthtok: problem with resp"); - retval = PAM_SYSTEM_ERR; - } - - _pam_drop_reply(resp, i); /* clean up the passwords */ - } else { - pam_syslog(pamh, LOG_ERR, - "pam_sm_chauthtok: this must be a Linux-PAM error"); - return PAM_SYSTEM_ERR; - } - - return retval; -} - - -#ifdef PAM_STATIC - -/* static module data */ - -struct pam_module _pam_stress_modstruct = { - "pam_stress", - pam_sm_authenticate, - pam_sm_setcred, - pam_sm_acct_mgmt, - pam_sm_open_session, - pam_sm_close_session, - pam_sm_chauthtok -}; - -#endif diff --git a/modules/pam_stress/tst-pam_stress b/modules/pam_stress/tst-pam_stress deleted file mode 100755 index 24be7560..00000000 --- a/modules/pam_stress/tst-pam_stress +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/sh -../../tests/tst-dlopen .libs/pam_stress.so diff --git a/modules/pam_succeed_if/.cvsignore b/modules/pam_succeed_if/.cvsignore deleted file mode 100644 index 6218e822..00000000 --- a/modules/pam_succeed_if/.cvsignore +++ /dev/null @@ -1,10 +0,0 @@ -*.la -*.lo -*.so -*~ -.deps -.libs -Makefile -Makefile.in -README -pam_succeed_if.8 diff --git a/modules/pam_succeed_if/Makefile.am b/modules/pam_succeed_if/Makefile.am deleted file mode 100644 index 0394f42d..00000000 --- a/modules/pam_succeed_if/Makefile.am +++ /dev/null @@ -1,31 +0,0 @@ -# -# Copyright (c) 2005, 2006 Thorsten Kukuk <kukuk@suse.de> -# - -CLEANFILES = *~ - -EXTRA_DIST = README ${MANS} ${XMLS} tst-pam_succeed_if - -TESTS = tst-pam_succeed_if - -man_MANS = pam_succeed_if.8 - -XMLS = README.xml pam_succeed_if.8.xml - -securelibdir = $(SECUREDIR) -secureconfdir = $(SCONFIGDIR) - -AM_CFLAGS = -I$(top_srcdir)/libpam/include -I$(top_srcdir)/libpamc/include -AM_LDFLAGS = -no-undefined -avoid-version -module -if HAVE_VERSIONING - AM_LDFLAGS += -Wl,--version-script=$(srcdir)/../modules.map -endif - -securelib_LTLIBRARIES = pam_succeed_if.la -pam_succeed_if_la_LIBADD = -L$(top_builddir)/libpam -lpam - -if ENABLE_REGENERATE_MAN -noinst_DATA = README -README: pam_succeed_if.8.xml --include $(top_srcdir)/Make.xml.rules -endif diff --git a/modules/pam_succeed_if/README.xml b/modules/pam_succeed_if/README.xml deleted file mode 100644 index c52f00a0..00000000 --- a/modules/pam_succeed_if/README.xml +++ /dev/null @@ -1,41 +0,0 @@ -<?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_succeed_if.8.xml"> ---> -]> - -<article> - - <articleinfo> - - <title> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" - href="pam_succeed_if.8.xml" xpointer='xpointer(//refnamediv[@id = "pam_succeed_if-name"]/*)'/> - </title> - - </articleinfo> - - <section> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" - href="pam_succeed_if.8.xml" xpointer='xpointer(//refsect1[@id = "pam_succeed_if-description"]/*)'/> - </section> - - <section> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" - href="pam_succeed_if.8.xml" xpointer='xpointer(//refsect1[@id = "pam_succeed_if-options"]/*)'/> - </section> - - <section> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" - href="pam_succeed_if.8.xml" xpointer='xpointer(//refsect1[@id = "pam_succeed_if-examples"]/*)'/> - </section> - - <section> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" - href="pam_succeed_if.8.xml" xpointer='xpointer(//refsect1[@id = "pam_succeed_if-author"]/*)'/> - </section> - -</article> diff --git a/modules/pam_succeed_if/pam_succeed_if.8.xml b/modules/pam_succeed_if/pam_succeed_if.8.xml deleted file mode 100644 index d064e03b..00000000 --- a/modules/pam_succeed_if/pam_succeed_if.8.xml +++ /dev/null @@ -1,297 +0,0 @@ -<?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_succeed_if'> -<!-- Copyright 2003, 2004 Red Hat, Inc. --> -<!-- Written by Nalin Dahyabhai <nalin@redhat.com> --> - - <refmeta> - <refentrytitle>pam_succeed_if</refentrytitle> - <manvolnum>8</manvolnum> - <refmiscinfo class='sectdesc'>Linux-PAM</refmiscinfo> - </refmeta> - - <refnamediv id='pam_succeed_if-name'> - <refname>pam_succeed_if</refname> - <refpurpose>test account characteristics</refpurpose> - </refnamediv> - - - <refsynopsisdiv> - <cmdsynopsis id='pam_succeed_if-cmdsynopsis'> - <command>pam_succeed_if.so</command> - <arg choice='opt' rep='repeat'><replaceable>flag</replaceable></arg> - <arg choice='opt' rep='repeat'><replaceable>condition</replaceable></arg> - </cmdsynopsis> - </refsynopsisdiv> - - - <refsect1 id='pam_succeed_if-description'> - <title>DESCRIPTION</title> - <para> - pam_succeed_if.so is designed to succeed or fail authentication - based on characteristics of the account belonging to the user being - authenticated. One use is to select whether to load other modules based - on this test. - </para> - - <para> - The module should be given one or more conditions as module arguments, - and authentication will succeed only if all of the conditions are met. - </para> - </refsect1> - - <refsect1 id="pam_succeed_if-options"> - <title>OPTIONS</title> - <para> - The following <emphasis>flag</emphasis>s are supported: - </para> - - <variablelist> - <varlistentry> - <term><option>debug</option></term> - <listitem> - <para>Turns on debugging messages sent to syslog.</para> - </listitem> - </varlistentry> - <varlistentry> - <term><option>use_uid</option></term> - <listitem> - <para> - Evaluate conditions using the account of the user whose UID - the application is running under instead of the user being - authenticated. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term><option>quiet</option></term> - <listitem> - <para>Don't log failure or success to the system log.</para> - </listitem> - </varlistentry> - <varlistentry> - <term><option>quiet_fail</option></term> - <listitem> - <para> - Don't log failure to the system log. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term><option>quiet_success</option></term> - <listitem> - <para> - Don't log success to the system log. - </para> - </listitem> - </varlistentry> - </variablelist> - - <para> - <emphasis>Condition</emphasis>s are three words: a field, a test, - and a value to test for. - </para> - <para> - Available fields are <emphasis>user</emphasis>, - <emphasis>uid</emphasis>, <emphasis>gid</emphasis>, - <emphasis>shell</emphasis>, <emphasis>home</emphasis> - and <emphasis>service</emphasis>: - </para> - - <variablelist> - <varlistentry> - <term><option>field < number</option></term> - <listitem> - <para>Field has a value numerically less than number.</para> - </listitem> - </varlistentry> - <varlistentry> - <term><option>field <= number</option></term> - <listitem> - <para> - Field has a value numerically less than or equal to number. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term><option>field eq number</option></term> - <listitem> - <para> - Field has a value numerically equal to number. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term><option>field >= number</option></term> - <listitem> - <para> - Field has a value numerically greater than or equal to number. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term><option>field > number</option></term> - <listitem> - <para> - Field has a value numerically greater than number. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term><option>field ne number</option></term> - <listitem> - <para> - Field has a value numerically different from number. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term><option>field = string</option></term> - <listitem> - <para> - Field exactly matches the given string. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term><option>field != string</option></term> - <listitem> - <para> - Field does not match the given string. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term><option>field =~ glob</option></term> - <listitem> - <para>Field matches the given glob.</para> - </listitem> - </varlistentry> - <varlistentry> - <term><option>field !~ glob</option></term> - <listitem> - <para>Field does not match the given glob.</para> - </listitem> - </varlistentry> - <varlistentry> - <term><option>field in item:item:...</option></term> - <listitem> - <para>Field is contained in the list of items separated by colons.</para> - </listitem> - </varlistentry> - <varlistentry> - <term><option>field notin item:item:...</option></term> - <listitem> - <para>Field is not contained in the list of items separated by colons.</para> - </listitem> - </varlistentry> - <varlistentry> - <term><option>user ingroup group</option></term> - <listitem> - <para>User is in given group.</para> - </listitem> - </varlistentry> - <varlistentry> - <term><option>user notingroup group</option></term> - <listitem> - <para>User is not in given group.</para> - </listitem> - </varlistentry> - <varlistentry> - <term><option>user innetgr netgroup</option></term> - <listitem> - <para>(user,host) is in given netgroup.</para> - </listitem> - </varlistentry> - <varlistentry> - <term><option>user notinnetgr group</option></term> - <listitem> - <para>(user,host) is not in given netgroup.</para> - </listitem> - </varlistentry> - </variablelist> - </refsect1> - - <refsect1 id="pam_succeed_if-services"> - <title>MODULE SERVICES PROVIDED</title> - <para> - All services are supported. - </para> - </refsect1> - - <refsect1 id='pam_succeed_if-return_values'> - <title>RETURN VALUES</title> - <variablelist> - - <varlistentry> - <term>PAM_SUCCESS</term> - <listitem> - <para> - The condition was true. - </para> - </listitem> - </varlistentry> - - <varlistentry> - <term>PAM_AUTH_ERR</term> - <listitem> - <para> - The condition was false. - </para> - </listitem> - </varlistentry> - - <varlistentry> - <term>PAM_SERVICE_ERR</term> - <listitem> - <para> - A service error occured or the arguments can't be - parsed as numbers. - </para> - </listitem> - </varlistentry> - </variablelist> - </refsect1> - - - <refsect1 id='pam_succeed_if-examples'> - <title>EXAMPLES</title> - <para> - To emulate the behaviour of <emphasis>pam_wheel</emphasis>, except - there is no fallback to group 0: - </para> - <programlisting> -auth required pam_succeed_if.so quiet user ingroup wheel - </programlisting> - - <para> - Given that the type matches, only loads the othermodule rule if - the UID is over 500. Adjust the number after default to skip - several rules. - </para> - <programlisting> -type [default=1 success=ignore] pam_succeed_if.so quiet uid > 500 -type required othermodule.so arguments... - </programlisting> - </refsect1> - - <refsect1 id='pam_succeed_if-see_also'> - <title>SEE ALSO</title> - <para> - <citerefentry> - <refentrytitle>glob</refentrytitle><manvolnum>7</manvolnum> - </citerefentry>, - <citerefentry> - <refentrytitle>pam</refentrytitle><manvolnum>8</manvolnum> - </citerefentry> - </para> - </refsect1> - - <refsect1 id='pam_succeed_if-author'> - <title>AUTHOR</title> - <para>Nalin Dahyabhai <nalin@redhat.com></para> - </refsect1> -</refentry> diff --git a/modules/pam_succeed_if/pam_succeed_if.c b/modules/pam_succeed_if/pam_succeed_if.c deleted file mode 100644 index 06cb5d6a..00000000 --- a/modules/pam_succeed_if/pam_succeed_if.c +++ /dev/null @@ -1,552 +0,0 @@ -/****************************************************************************** - * A simple user-attribute based module for PAM. - * - * Copyright (c) 2003 Red Hat, Inc. - * Written by Nalin Dahyabhai <nalin@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 <sys/types.h> -#include <errno.h> -#include <fcntl.h> -#include <fnmatch.h> -#include <limits.h> -#include <stdarg.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <syslog.h> -#include <unistd.h> -#include <pwd.h> -#include <grp.h> -#include <netdb.h> - -#define PAM_SM_AUTH -#define PAM_SM_ACCOUNT -#define PAM_SM_SESSION -#define PAM_SM_PASSWORD - -#include <security/pam_modules.h> -#include <security/pam_modutil.h> -#include <security/pam_ext.h> - -/* Basically, run cmp(atol(left), atol(right)), returning PAM_SUCCESS if - * the function returns non-zero, PAM_AUTH_ERR if it returns zero, and - * PAM_SERVICE_ERR if the arguments can't be parsed as numbers. */ -static int -evaluate_num(const pam_handle_t *pamh, const char *left, - const char *right, int (*cmp)(int, int)) -{ - long l, r; - char *p; - int ret = PAM_SUCCESS; - - errno = 0; - l = strtol(left, &p, 0); - if ((p == NULL) || (*p != '\0') || errno) { - pam_syslog(pamh, LOG_INFO, "\"%s\" is not a number", left); - ret = PAM_SERVICE_ERR; - } - - r = strtol(right, &p, 0); - if ((p == NULL) || (*p != '\0') || errno) { - pam_syslog(pamh, LOG_INFO, "\"%s\" is not a number", right); - ret = PAM_SERVICE_ERR; - } - - if (ret != PAM_SUCCESS) { - return ret; - } - - return cmp(l, r) ? PAM_SUCCESS : PAM_AUTH_ERR; -} - -/* Simple numeric comparison callbacks. */ -static int -eq(int i, int j) -{ - return i == j; -} -static int -ne(int i, int j) -{ - return i != j; -} -static int -lt(int i, int j) -{ - return i < j; -} -static int -le(int i, int j) -{ - return lt(i, j) || eq(i, j); -} -static int -gt(int i, int j) -{ - return i > j; -} -static int -ge(int i, int j) -{ - return gt(i, j) || eq(i, j); -} - -/* Test for numeric equality. */ -static int -evaluate_eqn(const pam_handle_t *pamh, const char *left, const char *right) -{ - return evaluate_num(pamh, left, right, eq); -} -/* Test for string equality. */ -static int -evaluate_eqs(const char *left, const char *right) -{ - return (strcmp(left, right) == 0) ? PAM_SUCCESS : PAM_AUTH_ERR; -} -/* Test for numeric inequality. */ -static int -evaluate_nen(const pam_handle_t *pamh, const char *left, const char *right) -{ - return evaluate_num(pamh, left, right, ne); -} -/* Test for string inequality. */ -static int -evaluate_nes(const char *left, const char *right) -{ - return (strcmp(left, right) != 0) ? PAM_SUCCESS : PAM_AUTH_ERR; -} -/* Test for numeric less-than-ness(?) */ -static int -evaluate_lt(const pam_handle_t *pamh, const char *left, const char *right) -{ - return evaluate_num(pamh, left, right, lt); -} -/* Test for numeric less-than-or-equal-ness(?) */ -static int -evaluate_le(const pam_handle_t *pamh, const char *left, const char *right) -{ - return evaluate_num(pamh, left, right, le); -} -/* Test for numeric greater-than-ness(?) */ -static int -evaluate_gt(const pam_handle_t *pamh, const char *left, const char *right) -{ - return evaluate_num(pamh, left, right, gt); -} -/* Test for numeric greater-than-or-equal-ness(?) */ -static int -evaluate_ge(const pam_handle_t *pamh, const char *left, const char *right) -{ - return evaluate_num(pamh, left, right, ge); -} -/* Check for file glob match. */ -static int -evaluate_glob(const char *left, const char *right) -{ - return (fnmatch(right, left, 0) == 0) ? PAM_SUCCESS : PAM_AUTH_ERR; -} -/* Check for file glob mismatch. */ -static int -evaluate_noglob(const char *left, const char *right) -{ - return (fnmatch(right, left, 0) != 0) ? PAM_SUCCESS : PAM_AUTH_ERR; -} -/* Check for list match. */ -static int -evaluate_inlist(const char *left, const char *right) -{ - char *p; - /* Don't care about left containing ':'. */ - while ((p=strstr(right, left)) != NULL) { - if (p == right || *(p-1) == ':') { /* ':' is a list separator */ - p += strlen(left); - if (*p == '\0' || *p == ':') { - return PAM_SUCCESS; - } - } - right = strchr(p, ':'); - if (right == NULL) - break; - else - ++right; - } - return PAM_AUTH_ERR; -} -/* Check for list mismatch. */ -static int -evaluate_notinlist(const char *left, const char *right) -{ - return evaluate_inlist(left, right) != PAM_SUCCESS ? PAM_SUCCESS : PAM_AUTH_ERR; -} -/* Return PAM_SUCCESS if the user is in the group. */ -static int -evaluate_ingroup(pam_handle_t *pamh, const char *user, const char *group) -{ - if (pam_modutil_user_in_group_nam_nam(pamh, user, group) == 1) - return PAM_SUCCESS; - return PAM_AUTH_ERR; -} -/* Return PAM_SUCCESS if the user is NOT in the group. */ -static int -evaluate_notingroup(pam_handle_t *pamh, const char *user, const char *group) -{ - if (pam_modutil_user_in_group_nam_nam(pamh, user, group) == 0) - return PAM_SUCCESS; - return PAM_AUTH_ERR; -} -/* Return PAM_SUCCESS if the (host,user) is in the netgroup. */ -static int -evaluate_innetgr(const char *host, const char *user, const char *group) -{ - if (innetgr(group, host, user, NULL) == 1) - return PAM_SUCCESS; - return PAM_AUTH_ERR; -} -/* Return PAM_SUCCESS if the (host,user) is NOT in the netgroup. */ -static int -evaluate_notinnetgr(const char *host, const char *user, const char *group) -{ - if (innetgr(group, host, user, NULL) == 0) - return PAM_SUCCESS; - return PAM_AUTH_ERR; -} - -/* Match a triple. */ -static int -evaluate(pam_handle_t *pamh, int debug, - const char *left, const char *qual, const char *right, - struct passwd *pwd) -{ - char buf[LINE_MAX] = ""; - const char *attribute = left; - /* Figure out what we're evaluating here, and convert it to a string.*/ - if ((strcasecmp(left, "login") == 0) || - (strcasecmp(left, "name") == 0) || - (strcasecmp(left, "user") == 0)) { - snprintf(buf, sizeof(buf), "%s", pwd->pw_name); - left = buf; - } - if (strcasecmp(left, "uid") == 0) { - snprintf(buf, sizeof(buf), "%lu", (unsigned long) pwd->pw_uid); - left = buf; - } - if (strcasecmp(left, "gid") == 0) { - snprintf(buf, sizeof(buf), "%lu", (unsigned long) pwd->pw_gid); - left = buf; - } - if (strcasecmp(left, "shell") == 0) { - snprintf(buf, sizeof(buf), "%s", pwd->pw_shell); - left = buf; - } - if ((strcasecmp(left, "home") == 0) || - (strcasecmp(left, "dir") == 0) || - (strcasecmp(left, "homedir") == 0)) { - snprintf(buf, sizeof(buf), "%s", pwd->pw_dir); - left = buf; - } - if (strcasecmp(left, "service") == 0) { - const void *svc; - if (pam_get_item(pamh, PAM_SERVICE, &svc) != PAM_SUCCESS) - svc = ""; - snprintf(buf, sizeof(buf), "%s", (const char *)svc); - left = buf; - } - /* If we have no idea what's going on, return an error. */ - if (left != buf) { - pam_syslog(pamh, LOG_CRIT, "unknown attribute \"%s\"", left); - return PAM_SERVICE_ERR; - } - if (debug) { - pam_syslog(pamh, LOG_DEBUG, "'%s' resolves to '%s'", - attribute, left); - } - - /* Attribute value < some threshold. */ - if ((strcasecmp(qual, "<") == 0) || - (strcasecmp(qual, "lt") == 0)) { - return evaluate_lt(pamh, left, right); - } - /* Attribute value <= some threshold. */ - if ((strcasecmp(qual, "<=") == 0) || - (strcasecmp(qual, "le") == 0)) { - return evaluate_le(pamh, left, right); - } - /* Attribute value > some threshold. */ - if ((strcasecmp(qual, ">") == 0) || - (strcasecmp(qual, "gt") == 0)) { - return evaluate_gt(pamh, left, right); - } - /* Attribute value >= some threshold. */ - if ((strcasecmp(qual, ">=") == 0) || - (strcasecmp(qual, "ge") == 0)) { - return evaluate_ge(pamh, left, right); - } - /* Attribute value == some threshold. */ - if (strcasecmp(qual, "eq") == 0) { - return evaluate_eqn(pamh, left, right); - } - /* Attribute value = some string. */ - if (strcasecmp(qual, "=") == 0) { - return evaluate_eqs(left, right); - } - /* Attribute value != some threshold. */ - if (strcasecmp(qual, "ne") == 0) { - return evaluate_nen(pamh, left, right); - } - /* Attribute value != some string. */ - if (strcasecmp(qual, "!=") == 0) { - return evaluate_nes(left, right); - } - /* Attribute value matches some pattern. */ - if ((strcasecmp(qual, "=~") == 0) || - (strcasecmp(qual, "glob") == 0)) { - return evaluate_glob(left, right); - } - if ((strcasecmp(qual, "!~") == 0) || - (strcasecmp(qual, "noglob") == 0)) { - return evaluate_noglob(left, right); - } - /* Attribute value matches item in list. */ - if (strcasecmp(qual, "in") == 0) { - return evaluate_inlist(left, right); - } - if (strcasecmp(qual, "notin") == 0) { - return evaluate_notinlist(left, right); - } - /* User is in this group. */ - if (strcasecmp(qual, "ingroup") == 0) { - return evaluate_ingroup(pamh, pwd->pw_name, right); - } - /* User is not in this group. */ - if (strcasecmp(qual, "notingroup") == 0) { - return evaluate_notingroup(pamh, pwd->pw_name, right); - } - /* (Rhost, user) is in this netgroup. */ - if (strcasecmp(qual, "innetgr") == 0) { - const void *rhost; - if (pam_get_item(pamh, PAM_RHOST, &rhost) != PAM_SUCCESS) - rhost = NULL; - return evaluate_innetgr(rhost, pwd->pw_name, right); - } - /* (Rhost, user) is not in this group. */ - if (strcasecmp(qual, "notinnetgr") == 0) { - const void *rhost; - if (pam_get_item(pamh, PAM_RHOST, &rhost) != PAM_SUCCESS) - rhost = NULL; - return evaluate_notinnetgr(rhost, pwd->pw_name, right); - } - /* Fail closed. */ - return PAM_SERVICE_ERR; -} - -PAM_EXTERN int -pam_sm_authenticate (pam_handle_t *pamh, int flags UNUSED, - int argc, const char **argv) -{ - const void *prompt; - const char *user; - struct passwd *pwd; - int ret, i, count, use_uid, debug; - const char *left, *right, *qual; - int quiet_fail, quiet_succ; - - /* Get the user prompt. */ - ret = pam_get_item(pamh, PAM_USER_PROMPT, &prompt); - if ((ret != PAM_SUCCESS) || (prompt == NULL) || (strlen(prompt) == 0)) { - prompt = "login: "; - } - - quiet_fail = 0; - quiet_succ = 0; - for (use_uid = 0, debug = 0, i = 0; i < argc; i++) { - if (strcmp(argv[i], "debug") == 0) { - debug++; - } - if (strcmp(argv[i], "use_uid") == 0) { - use_uid++; - } - if (strcmp(argv[i], "quiet") == 0) { - quiet_fail++; - quiet_succ++; - } - if (strcmp(argv[i], "quiet_fail") == 0) { - quiet_fail++; - } - if (strcmp(argv[i], "quiet_success") == 0) { - quiet_succ++; - } - } - - if (use_uid) { - /* Get information about the user. */ - pwd = pam_modutil_getpwuid(pamh, getuid()); - if (pwd == NULL) { - pam_syslog(pamh, LOG_CRIT, - "error retrieving information about user %lu", - (unsigned long)getuid()); - return PAM_USER_UNKNOWN; - } - user = pwd->pw_name; - } else { - /* Get the user's name. */ - ret = pam_get_user(pamh, &user, prompt); - if ((ret != PAM_SUCCESS) || (user == NULL)) { - pam_syslog(pamh, LOG_CRIT, - "error retrieving user name: %s", - pam_strerror(pamh, ret)); - return ret; - } - - /* Get information about the user. */ - pwd = pam_modutil_getpwnam(pamh, user); - if (pwd == NULL) { - pam_syslog(pamh, LOG_CRIT, - "error retrieving information about user %s", - user); - return PAM_USER_UNKNOWN; - } - } - - /* Walk the argument list. */ - i = count = 0; - left = qual = right = NULL; - while (i <= argc) { - if ((left != NULL) && (qual != NULL) && (right != NULL)) { - ret = evaluate(pamh, debug, - left, qual, right, - pwd); - if (ret != PAM_SUCCESS) { - if(!quiet_fail) - pam_syslog(pamh, LOG_INFO, - "requirement \"%s %s %s\" " - "not met by user \"%s\"", - left, qual, right, user); - break; - } - else - if(!quiet_succ) - pam_syslog(pamh, LOG_INFO, - "requirement \"%s %s %s\" " - "was met by user \"%s\"", - left, qual, right, user); - left = qual = right = NULL; - } - if ((i < argc) && (strcmp(argv[i], "debug") == 0)) { - i++; - continue; - } - if ((i < argc) && (strcmp(argv[i], "use_uid") == 0)) { - i++; - continue; - } - if ((i < argc) && (strcmp(argv[i], "quiet") == 0)) { - i++; - continue; - } - if ((i < argc) && (strcmp(argv[i], "quiet_fail") == 0)) { - i++; - continue; - } - if ((i < argc) && (strcmp(argv[i], "quiet_success") == 0)) { - i++; - continue; - } - if ((i < argc) && (left == NULL)) { - left = argv[i++]; - count++; - continue; - } - if ((i < argc) && (qual == NULL)) { - qual = argv[i++]; - count++; - continue; - } - if ((i < argc) && (right == NULL)) { - right = argv[i++]; - count++; - continue; - } - i++; - } - - return ret; -} - -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); -} - -PAM_EXTERN int -pam_sm_open_session(pam_handle_t *pamh, int flags, int argc, const char **argv) -{ - return pam_sm_authenticate(pamh, flags, argc, argv); -} - -PAM_EXTERN int -pam_sm_close_session(pam_handle_t *pamh, int flags, int argc, const char **argv) -{ - return pam_sm_authenticate(pamh, flags, argc, argv); -} - -PAM_EXTERN int -pam_sm_chauthtok(pam_handle_t *pamh, int flags, int argc, const char **argv) -{ - return pam_sm_authenticate(pamh, flags, argc, argv); -} - -/* static module data */ -#ifdef PAM_STATIC -struct pam_module _pam_succeed_if_modstruct = { - "pam_succeed_if", - pam_sm_authenticate, - pam_sm_setcred, - pam_sm_acct_mgmt, - pam_sm_open_session, - pam_sm_close_session, - pam_sm_chauthtok -}; -#endif diff --git a/modules/pam_succeed_if/tst-pam_succeed_if b/modules/pam_succeed_if/tst-pam_succeed_if deleted file mode 100755 index f2b6dd3f..00000000 --- a/modules/pam_succeed_if/tst-pam_succeed_if +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/sh -../../tests/tst-dlopen .libs/pam_succeed_if.so diff --git a/modules/pam_tally/.cvsignore b/modules/pam_tally/.cvsignore deleted file mode 100644 index 0286d635..00000000 --- a/modules/pam_tally/.cvsignore +++ /dev/null @@ -1,9 +0,0 @@ -*.la -*.lo -.deps -.libs -Makefile -Makefile.in -pam_tally -README -pam_tally.8 diff --git a/modules/pam_tally/Makefile.am b/modules/pam_tally/Makefile.am deleted file mode 100644 index c4c181a9..00000000 --- a/modules/pam_tally/Makefile.am +++ /dev/null @@ -1,36 +0,0 @@ -# -# Copyright (c) 2005, 2006, 2007 Thorsten Kukuk <kukuk@thkukuk.de> -# - -CLEANFILES = *~ - -EXTRA_DIST = README $(MANS) $(XMLS) tst-pam_tally - -man_MANS = pam_tally.8 -XMLS = README.xml pam_tally.8.xml - -TESTS = tst-pam_tally - -securelibdir = $(SECUREDIR) -secureconfdir = $(SCONFIGDIR) - -noinst_HEADERS = faillog.h - -AM_CFLAGS = -I$(top_srcdir)/libpam/include -I$(top_srcdir)/libpamc/include - -pam_tally_la_LDFLAGS = -no-undefined -avoid-version -module -pam_tally_la_LIBADD = -L$(top_builddir)/libpam -lpam -if HAVE_VERSIONING - pam_tally_la_LDFLAGS += -Wl,--version-script=$(srcdir)/../modules.map -endif - -securelib_LTLIBRARIES = pam_tally.la -sbin_PROGRAMS = pam_tally - -pam_tally_SOURCES = pam_tally_app.c - -if ENABLE_REGENERATE_MAN -noinst_DATA = README -README: pam_tally.8.xml --include $(top_srcdir)/Make.xml.rules -endif diff --git a/modules/pam_tally/README.xml b/modules/pam_tally/README.xml deleted file mode 100644 index 3c6de50e..00000000 --- a/modules/pam_tally/README.xml +++ /dev/null @@ -1,41 +0,0 @@ -<?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_tally.8.xml"> ---> -]> - -<article> - - <articleinfo> - - <title> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" - href="pam_tally.8.xml" xpointer='xpointer(//refnamediv[@id = "pam_tally-name"]/*)'/> - </title> - - </articleinfo> - - <section> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" - href="pam_tally.8.xml" xpointer='xpointer(//refsect1[@id = "pam_tally-description"]/*)'/> - </section> - - <section> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" - href="pam_tally.8.xml" xpointer='xpointer(//refsect1[@id = "pam_tally-options"]/*)'/> - </section> - - <section> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" - href="pam_tally.8.xml" xpointer='xpointer(//refsect1[@id = "pam_tally-examples"]/*)'/> - </section> - - <section> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" - href="pam_tally.8.xml" xpointer='xpointer(//refsect1[@id = "pam_tally-author"]/*)'/> - </section> - -</article> diff --git a/modules/pam_tally/faillog.h b/modules/pam_tally/faillog.h deleted file mode 100644 index 7f704713..00000000 --- a/modules/pam_tally/faillog.h +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright 1989 - 1994, Julianne Frances Haugh - * All rights reserved. - * - * 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, this list of conditions and the following disclaimer. - * 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. Neither the name of Julianne F. Haugh nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``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 JULIE HAUGH OR CONTRIBUTORS 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. - */ - -/* - * faillog.h - login failure logging file format - * - * $Id$ - * - * The login failure file is maintained by login(1) and faillog(8) - * Each record in the file represents a separate UID and the file - * is indexed in that fashion. - */ - -#ifndef _FAILLOG_H -#define _FAILLOG_H - -struct faillog { - short fail_cnt; /* failures since last success */ - short fail_max; /* failures before turning account off */ - char fail_line[12]; /* last failure occured here */ - time_t fail_time; /* last failure occured then */ - /* - * If nonzero, the account will be re-enabled if there are no - * failures for fail_locktime seconds since last failure. - */ - long fail_locktime; -}; - -#endif diff --git a/modules/pam_tally/pam_tally.8.xml b/modules/pam_tally/pam_tally.8.xml deleted file mode 100644 index 4f89269e..00000000 --- a/modules/pam_tally/pam_tally.8.xml +++ /dev/null @@ -1,427 +0,0 @@ -<?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_tally"> - - <refmeta> - <refentrytitle>pam_tally</refentrytitle> - <manvolnum>8</manvolnum> - <refmiscinfo class="sectdesc">Linux-PAM Manual</refmiscinfo> - </refmeta> - - <refnamediv id="pam_tally-name"> - <refname>pam_tally</refname> - <refpurpose>The login counter (tallying) module</refpurpose> - </refnamediv> - - <refsynopsisdiv> - <cmdsynopsis id="pam_tally-cmdsynopsis1"> - <command>pam_tally.so</command> - <arg choice="opt"> - file=<replaceable>/path/to/counter</replaceable> - </arg> - <arg choice="opt"> - onerr=[<replaceable>fail</replaceable>|<replaceable>succeed</replaceable>] - </arg> - <arg choice="opt"> - magic_root - </arg> - <arg choice="opt"> - even_deny_root_account - </arg> - <arg choice="opt"> - deny=<replaceable>n</replaceable> - </arg> - <arg choice="opt"> - lock_time=<replaceable>n</replaceable> - </arg> - <arg choice="opt"> - unlock_time=<replaceable>n</replaceable> - </arg> - <arg choice="opt"> - per_user - </arg> - <arg choice="opt"> - no_lock_time - </arg> - <arg choice="opt"> - no_reset - </arg> - <arg choice="opt"> - audit - </arg> - </cmdsynopsis> - <cmdsynopsis id="pam_tally-cmdsynopsis2"> - <command>pam_tally</command> - <arg choice="opt"> - --file <replaceable>/path/to/counter</replaceable> - </arg> - <arg choice="opt"> - --user <replaceable>username</replaceable> - </arg> - <arg choice="opt"> - --reset[=<replaceable>n</replaceable>] - </arg> - <arg choice="opt"> - --quiet - </arg> - </cmdsynopsis> - </refsynopsisdiv> - - <refsect1 id="pam_tally-description"> - - <title>DESCRIPTION</title> - - <para> - This module maintains a count of attempted accesses, can - reset count on success, can deny access if too many attempts fail. - </para> - <para> - pam_tally comes in two parts: - <emphasis remap='B'>pam_tally.so</emphasis> and - <command>pam_tally</command>. The former is the PAM module and - the latter, a stand-alone program. <command>pam_tally</command> - is an (optional) application which can be used to interrogate and - manipulate the counter file. It can display users' counts, set - individual counts, or clear all counts. Setting artificially high - counts may be useful for blocking users without changing their - passwords. For example, one might find it useful to clear all counts - every midnight from a cron job. The - <citerefentry> - <refentrytitle>faillog</refentrytitle><manvolnum>8</manvolnum> - </citerefentry> command can be used instead of pam_tally to to - maintain the counter file. - </para> - <para> - Normally, failed attempts to access <emphasis>root</emphasis> will - <emphasis remap='B'>not</emphasis> cause the root account to become - blocked, to prevent denial-of-service: if your users aren't given - shell accounts and root may only login via <command>su</command> or - at the machine console (not telnet/rsh, etc), this is safe. - </para> - </refsect1> - - <refsect1 id="pam_tally-options"> - - <title>OPTIONS</title> - <variablelist> - <varlistentry> - <term> - GLOBAL OPTIONS - </term> - <listitem> - <para> - This can be used for <emphasis>auth</emphasis> and - <emphasis>account</emphasis> services. - </para> - <variablelist> - <varlistentry> - <term> - <option>onerr=[<replaceable>fail</replaceable>|<replaceable>succeed</replaceable>]</option> - </term> - <listitem> - <para> - If something weird happens (like unable to open the file), - return with <errorcode>PAM_SUCESS</errorcode> if - <option>onerr=<replaceable>succeed</replaceable></option> - is given, else with the corresponding PAM error code. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <option>file=<replaceable>/path/to/counter</replaceable></option> - </term> - <listitem> - <para> - File where to keep counts. Default is - <filename>/var/log/faillog</filename>. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <option>audit</option> - </term> - <listitem> - <para> - Will log the user name into the system log if the user is not found. - </para> - </listitem> - </varlistentry> - </variablelist> - </listitem> - </varlistentry> - - <varlistentry> - <term> - AUTH OPTIONS - </term> - <listitem> - <para> - Authentication phase first checks if user should be denied - access and if not it increments attempted login counter. Then - on call to <citerefentry> - <refentrytitle>pam_setcred</refentrytitle><manvolnum>3</manvolnum> - </citerefentry> it resets the attempts counter. - </para> - <variablelist> - <varlistentry> - <term> - <option>deny=<replaceable>n</replaceable></option> - </term> - <listitem> - <para> - Deny access if tally for this user exceeds - <replaceable>n</replaceable>. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <option>lock_time=<replaceable>n</replaceable></option> - </term> - <listitem> - <para> - Always deny for <replaceable>n</replaceable> seconds - after failed attempt. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <option>unlock_time=<replaceable>n</replaceable></option> - </term> - <listitem> - <para> - Allow access after <replaceable>n</replaceable> seconds - after failed attempt. If this option is used the user will - be locked out for the specified amount of time after he - exceeded his maximum allowed attempts. Otherwise the - account is locked until the lock is removed by a manual - intervention of the system administrator. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <option>magic_root</option> - </term> - <listitem> - <para> - If the module is invoked by a user with uid=0 the - counter is not incremented. The sys-admin should use this - for user launched services, like <command>su</command>, - otherwise this argument should be omitted. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <option>no_lock_time</option> - </term> - <listitem> - <para> - Do not use the .fail_locktime field in - <filename>/var/log/faillog</filename> for this user. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <option>no_reset</option> - </term> - <listitem> - <para> - Don't reset count on successful entry, only decrement. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <option>even_deny_root_account</option> - </term> - <listitem> - <para> - Root account can become unavailable. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <option>per_user</option> - </term> - <listitem> - <para> - If <filename>/var/log/faillog</filename> contains a non-zero - .fail_max/.fail_locktime field for this user then use it - instead of <option>deny=<replaceable>n</replaceable></option>/ - <option>lock_time=<replaceable>n</replaceable></option> parameter. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <option>no_lock_time</option> - </term> - <listitem> - <para> - Don't use .fail_locktime filed in - <filename>/var/log/faillog</filename> for this user. - </para> - </listitem> - </varlistentry> - - </variablelist> - </listitem> - </varlistentry> - - - <varlistentry> - <term> - ACCOUNT OPTIONS - </term> - <listitem> - <para> - Account phase resets attempts counter if the user is - <emphasis remap='B'>not</emphasis> magic root. - This phase can be used optionaly for services which don't call - <citerefentry> - <refentrytitle>pam_setcred</refentrytitle><manvolnum>3</manvolnum> - </citerefentry> correctly or if the reset should be done regardless - of the failure of the account phase of other modules. - </para> - <variablelist> - <varlistentry> - <term> - <option>magic_root</option> - </term> - <listitem> - <para> - If the module is invoked by a user with uid=0 the - counter is not incremented. The sys-admin should use this - for user launched services, like <command>su</command>, - otherwise this argument should be omitted. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <option>no_reset</option> - </term> - <listitem> - <para> - Don't reset count on successful entry, only decrement. - </para> - </listitem> - </varlistentry> - </variablelist> - </listitem> - </varlistentry> - </variablelist> - </refsect1> - - <refsect1 id="pam_tally-services"> - <title>MODULE SERVICES PROVIDED</title> - <para> - The <option>auth</option> and <option>account</option> - services are supported. - </para> - </refsect1> - - <refsect1 id='pam_tally-return_values'> - <title>RETURN VALUES</title> - <variablelist> - <varlistentry> - <term>PAM_AUTH_ERR</term> - <listitem> - <para> - A invalid option was given, the module was not able - to retrive the user name, no valid counter file - was found, or too many failed logins. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term>PAM_SUCCESS</term> - <listitem> - <para> - Everything was successfull. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term>PAM_USER_UNKNOWN</term> - <listitem> - <para> - User not known. - </para> - </listitem> - </varlistentry> - </variablelist> - </refsect1> - - <refsect1 id='pam_tally-examples'> - <title>EXAMPLES</title> - <para> - Add the following line to <filename>/etc/pam.d/login</filename> to - lock the account after too many failed logins. The number of - allowed fails is specified by <filename>/var/log/faillog</filename> - and needs to be set with pam_tally or <citerefentry> - <refentrytitle>faillog</refentrytitle><manvolnum>8</manvolnum> - </citerefentry> before. - </para> - <programlisting> -auth required pam_securetty.so -auth required pam_tally.so per_user -auth required pam_env.so -auth required pam_unix.so -auth required pam_nologin.so -account required pam_unix.so -password required pam_unix.so -session required pam_limits.so -session required pam_unix.so -session required pam_lastlog.so nowtmp -session optional pam_mail.so standard - </programlisting> - </refsect1> - - <refsect1 id="pam_tally-files"> - <title>FILES</title> - <variablelist> - <varlistentry> - <term><filename>/var/log/faillog</filename></term> - <listitem> - <para>failure logging file</para> - </listitem> - </varlistentry> - </variablelist> - </refsect1> - - <refsect1 id='pam_tally-see_also'> - <title>SEE ALSO</title> - <para> - <citerefentry> - <refentrytitle>faillog</refentrytitle><manvolnum>8</manvolnum> - </citerefentry>, - <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_tally-author'> - <title>AUTHOR</title> - <para> - pam_tally was written by Tim Baverstock and Tomas Mraz. - </para> - </refsect1> - -</refentry> diff --git a/modules/pam_tally/pam_tally.c b/modules/pam_tally/pam_tally.c deleted file mode 100644 index 8814659a..00000000 --- a/modules/pam_tally/pam_tally.c +++ /dev/null @@ -1,867 +0,0 @@ -/* - * pam_tally.c - * - */ - - -/* By Tim Baverstock <warwick@mmm.co.uk>, Multi Media Machine Ltd. - * 5 March 1997 - * - * Stuff stolen from pam_rootok and pam_listfile - * - * Changes by Tomas Mraz <tmraz@redhat.com> 5 January 2005 - * Audit option added for Tomas patch by - * Sebastien Tricaud <toady@gscore.org> 13 January 2005 - */ - -#include "config.h" - -#include <stdio.h> -#include <string.h> -#include <unistd.h> -#include <stdarg.h> -#include <stdlib.h> -#include <syslog.h> -#include <pwd.h> -#include <time.h> - -#include <sys/types.h> -#include <sys/stat.h> -#include <sys/param.h> -#include "faillog.h" - -/* - * here, we make a definition for the externally accessible function - * in this file (this definition is required for static a module - * but strongly encouraged generally) it is used to instruct the - * modules include file to define the function prototypes. - */ - -#ifndef MAIN -#define PAM_SM_AUTH -#define PAM_SM_ACCOUNT -/* #define PAM_SM_SESSION */ -/* #define PAM_SM_PASSWORD */ - -#include <security/pam_modutil.h> -#include <security/pam_ext.h> -#endif -#include <security/pam_modules.h> - -#ifndef TRUE -#define TRUE 1L -#define FALSE 0L -#endif - -#ifndef HAVE_FSEEKO -#define fseeko fseek -#endif - -/*---------------------------------------------------------------------*/ - -#define DEFAULT_LOGFILE "/var/log/faillog" -#define MODULE_NAME "pam_tally" - -#define tally_t unsigned short int -#define TALLY_FMT "%hu" -#define TALLY_HI ((tally_t)~0L) - -#ifndef FILENAME_MAX -# define FILENAME_MAX MAXPATHLEN -#endif - -struct fail_s { - struct faillog fs_faillog; -#ifndef MAIN - time_t fs_fail_time; -#endif /* ndef MAIN */ -}; - -struct tally_options { - const char *filename; - tally_t deny; - long lock_time; - long unlock_time; - unsigned int ctrl; -}; - -#define PHASE_UNKNOWN 0 -#define PHASE_AUTH 1 -#define PHASE_ACCOUNT 2 -#define PHASE_SESSION 3 - -#define OPT_MAGIC_ROOT 01 -#define OPT_FAIL_ON_ERROR 02 -#define OPT_DENY_ROOT 04 -#define OPT_PER_USER 010 -#define OPT_NO_LOCK_TIME 020 -#define OPT_NO_RESET 040 -#define OPT_AUDIT 0100 - - -/*---------------------------------------------------------------------*/ - -/* some syslogging */ - -#ifdef MAIN -#define pam_syslog tally_log -static void -tally_log (const pam_handle_t *pamh UNUSED, int priority UNUSED, - const char *fmt, ...) -{ - va_list args; - - va_start(args, fmt); - fprintf(stderr, "%s: ", MODULE_NAME); - vfprintf(stderr, fmt, args); - fprintf(stderr,"\n"); - va_end(args); -} - -#define pam_modutil_getpwnam(pamh,user) getpwnam(user) - -#endif - -/*---------------------------------------------------------------------*/ - -/* --- Support function: parse arguments --- */ - -#ifndef MAIN - -static void -log_phase_no_auth(pam_handle_t *pamh, int phase, const char *argv) -{ - if ( phase != PHASE_AUTH ) { - pam_syslog(pamh, LOG_ERR, - "option %s allowed in auth phase only", argv); - } -} - -static int -tally_parse_args(pam_handle_t *pamh, struct tally_options *opts, - int phase, int argc, const char **argv) -{ - memset(opts, 0, sizeof(*opts)); - opts->filename = DEFAULT_LOGFILE; - - for ( ; argc-- > 0; ++argv ) { - - if ( ! strncmp( *argv, "file=", 5 ) ) { - const char *from = *argv + 5; - if ( *from!='/' || strlen(from)>FILENAME_MAX-1 ) { - pam_syslog(pamh, LOG_ERR, - "filename not /rooted or too long; %s", *argv); - return PAM_AUTH_ERR; - } - opts->filename = from; - } - else if ( ! strcmp( *argv, "onerr=fail" ) ) { - opts->ctrl |= OPT_FAIL_ON_ERROR; - } - else if ( ! strcmp( *argv, "onerr=succeed" ) ) { - opts->ctrl &= ~OPT_FAIL_ON_ERROR; - } - else if ( ! strcmp( *argv, "magic_root" ) ) { - opts->ctrl |= OPT_MAGIC_ROOT; - } - else if ( ! strcmp( *argv, "even_deny_root_account" ) ) { - log_phase_no_auth(pamh, phase, *argv); - opts->ctrl |= OPT_DENY_ROOT; - } - else if ( ! strncmp( *argv, "deny=", 5 ) ) { - log_phase_no_auth(pamh, phase, *argv); - if ( sscanf((*argv)+5,TALLY_FMT,&opts->deny) != 1 ) { - pam_syslog(pamh, LOG_ERR, "bad number supplied: %s", *argv); - return PAM_AUTH_ERR; - } - } - else if ( ! strncmp( *argv, "lock_time=", 10 ) ) { - log_phase_no_auth(pamh, phase, *argv); - if ( sscanf((*argv)+10,"%ld",&opts->lock_time) != 1 ) { - pam_syslog(pamh, LOG_ERR, "bad number supplied: %s", *argv); - return PAM_AUTH_ERR; - } - } - else if ( ! strncmp( *argv, "unlock_time=", 12 ) ) { - log_phase_no_auth(pamh, phase, *argv); - if ( sscanf((*argv)+12,"%ld",&opts->unlock_time) != 1 ) { - pam_syslog(pamh, LOG_ERR, "bad number supplied: %s", *argv); - return PAM_AUTH_ERR; - } - } - else if ( ! strcmp( *argv, "per_user" ) ) - { - log_phase_no_auth(pamh, phase, *argv); - opts->ctrl |= OPT_PER_USER; - } - else if ( ! strcmp( *argv, "no_lock_time") ) - { - log_phase_no_auth(pamh, phase, *argv); - opts->ctrl |= OPT_NO_LOCK_TIME; - } - else if ( ! strcmp( *argv, "no_reset" ) ) { - opts->ctrl |= OPT_NO_RESET; - } - else if ( ! strcmp ( *argv, "audit") ) { - opts->ctrl |= OPT_AUDIT; - } - else { - pam_syslog(pamh, LOG_ERR, "unknown option: %s", *argv); - } - } - - return PAM_SUCCESS; -} - -#endif /* #ifndef MAIN */ - -/*---------------------------------------------------------------------*/ - -/* --- Support function: get uid (and optionally username) from PAM or - cline_user --- */ - -#ifdef MAIN -static char *cline_user=0; /* cline_user is used in the administration prog */ -#endif - -static int -pam_get_uid(pam_handle_t *pamh, uid_t *uid, const char **userp, struct tally_options *opts) -{ - const char *user = NULL; - struct passwd *pw; - -#ifdef MAIN - user = cline_user; -#else - if ((pam_get_user( pamh, &user, NULL )) != PAM_SUCCESS) { - pam_syslog(pamh, LOG_ERR, "pam_get_user; user?"); - return PAM_AUTH_ERR; - } -#endif - - if ( !user || !*user ) { - pam_syslog(pamh, LOG_ERR, "pam_get_uid; user?"); - return PAM_AUTH_ERR; - } - - if ( ! ( pw = pam_modutil_getpwnam( pamh, user ) ) ) { - opts->ctrl & OPT_AUDIT ? - pam_syslog(pamh, LOG_ERR, "pam_get_uid; no such user %s", user) : - pam_syslog(pamh, LOG_ERR, "pam_get_uid; no such user"); - return PAM_USER_UNKNOWN; - } - - if ( uid ) *uid = pw->pw_uid; - if ( userp ) *userp = user; - return PAM_SUCCESS; -} - -/*---------------------------------------------------------------------*/ - -/* --- Support functions: set/get tally data --- */ - -#ifndef MAIN - -static void -_cleanup(pam_handle_t *pamh UNUSED, void *data, int error_status UNUSED) -{ - free(data); -} - - -static void -tally_set_data( pam_handle_t *pamh, time_t oldtime ) -{ - time_t *data; - - if ( (data=malloc(sizeof(time_t))) != NULL ) { - *data = oldtime; - pam_set_data(pamh, MODULE_NAME, (void *)data, _cleanup); - } -} - -static int -tally_get_data( pam_handle_t *pamh, time_t *oldtime ) -{ - int rv; - const void *data; - - rv = pam_get_data(pamh, MODULE_NAME, &data); - if ( rv == PAM_SUCCESS && data != NULL && oldtime != NULL ) { - *oldtime = *(const time_t *)data; - pam_set_data(pamh, MODULE_NAME, NULL, NULL); - } - else { - rv = -1; - if (oldtime) - *oldtime = 0; - } - return rv; -} -#endif /* #ifndef MAIN */ - -/*---------------------------------------------------------------------*/ - -/* --- Support function: open/create tallyfile and return tally for uid --- */ - -/* If on entry *tally==TALLY_HI, tallyfile is opened READONLY */ -/* Otherwise, if on entry tallyfile doesn't exist, creation is attempted. */ - -static int -get_tally(pam_handle_t *pamh, tally_t *tally, uid_t uid, - const char *filename, FILE **TALLY, struct fail_s *fsp) -{ - struct stat fileinfo; - int lstat_ret = lstat(filename,&fileinfo); - - if ( lstat_ret && *tally!=TALLY_HI ) { - int oldmask = umask(077); - *TALLY=fopen(filename, "a"); - /* Create file, or append-open in pathological case. */ - umask(oldmask); - if ( !*TALLY ) { - pam_syslog(pamh, LOG_ALERT, "Couldn't create %s", filename); - return PAM_AUTH_ERR; - } - lstat_ret = fstat(fileno(*TALLY),&fileinfo); - fclose(*TALLY); - } - - if ( lstat_ret ) { - pam_syslog(pamh, LOG_ALERT, "Couldn't stat %s", filename); - return PAM_AUTH_ERR; - } - - if((fileinfo.st_mode & S_IWOTH) || !S_ISREG(fileinfo.st_mode)) { - /* If the file is world writable or is not a - normal file, return error */ - pam_syslog(pamh, LOG_ALERT, - "%s is either world writable or not a normal file", - filename); - return PAM_AUTH_ERR; - } - - if ( ! ( *TALLY = fopen(filename,(*tally!=TALLY_HI)?"r+":"r") ) ) { - pam_syslog(pamh, LOG_ALERT, "Error opening %s for update", filename); - -/* Discovering why account service fails: e/uid are target user. - * - * perror(MODULE_NAME); - * fprintf(stderr,"uid %d euid %d\n",getuid(), geteuid()); - */ - return PAM_AUTH_ERR; - } - - if ( fseeko( *TALLY, (off_t) uid * sizeof(struct faillog), SEEK_SET ) ) { - pam_syslog(pamh, LOG_ALERT, "fseek failed for %s", filename); - fclose(*TALLY); - return PAM_AUTH_ERR; - } - - if ( (size_t)fileinfo.st_size <= uid * sizeof(struct faillog) ) { - - memset(fsp, 0, sizeof(struct faillog)); - *tally=0; - fsp->fs_faillog.fail_time = time(NULL); - - } else if (( fread((char *) &fsp->fs_faillog, - sizeof(struct faillog), 1, *TALLY) )==0 ) { - - *tally=0; /* Assuming a gappy filesystem */ - - } else { - - *tally = fsp->fs_faillog.fail_cnt; - - } - - return PAM_SUCCESS; -} - -/*---------------------------------------------------------------------*/ - -/* --- Support function: update and close tallyfile with tally!=TALLY_HI --- */ - -static int -set_tally(pam_handle_t *pamh, tally_t tally, uid_t uid, - const char *filename, FILE **TALLY, struct fail_s *fsp) -{ - int retval = PAM_SUCCESS; - - if ( tally!=TALLY_HI ) { - if ( fseeko( *TALLY, (off_t) uid * sizeof(struct faillog), SEEK_SET ) ) { - pam_syslog(pamh, LOG_ALERT, "fseek failed for %s", filename); - retval = PAM_AUTH_ERR; - } else { - fsp->fs_faillog.fail_cnt = tally; - if (fwrite((char *) &fsp->fs_faillog, - sizeof(struct faillog), 1, *TALLY)==0 ) { - pam_syslog(pamh, LOG_ALERT, "update (fwrite) failed for %s", filename); - retval = PAM_AUTH_ERR; - } - } - } - - if ( fclose(*TALLY) ) { - pam_syslog(pamh, LOG_ALERT, "update (fclose) failed for %s", filename); - return PAM_AUTH_ERR; - } - *TALLY=NULL; - return retval; -} - -/*---------------------------------------------------------------------*/ - -/* --- PAM bits --- */ - -#ifndef MAIN - -#define RETURN_ERROR(i) return ((opts->ctrl & OPT_FAIL_ON_ERROR)?(i):(PAM_SUCCESS)) - -/*---------------------------------------------------------------------*/ - -/* --- tally bump function: bump tally for uid by (signed) inc --- */ - -static int -tally_bump (int inc, time_t *oldtime, pam_handle_t *pamh, - uid_t uid, const char *user, struct tally_options *opts) -{ - tally_t - tally = 0; /* !TALLY_HI --> Log opened for update */ - - FILE - *TALLY = NULL; - const void - *remote_host = NULL, - *cur_tty = NULL; - struct fail_s fs, *fsp = &fs; - int i; - - i=get_tally(pamh, &tally, uid, opts->filename, &TALLY, fsp); - if ( i != PAM_SUCCESS ) { RETURN_ERROR( i ); } - - /* to remember old fail time (for locktime) */ - fsp->fs_fail_time = fsp->fs_faillog.fail_time; - if ( inc > 0 ) { - if ( oldtime ) { - *oldtime = fsp->fs_faillog.fail_time; - } - fsp->fs_faillog.fail_time = time(NULL); - } else { - if ( oldtime ) { - fsp->fs_faillog.fail_time = *oldtime; - } - } - (void) pam_get_item(pamh, PAM_RHOST, &remote_host); - if (!remote_host) { - - (void) pam_get_item(pamh, PAM_TTY, &cur_tty); - if (!cur_tty) { - strncpy(fsp->fs_faillog.fail_line, "unknown", - sizeof(fsp->fs_faillog.fail_line) - 1); - fsp->fs_faillog.fail_line[sizeof(fsp->fs_faillog.fail_line)-1] = 0; - } else { - strncpy(fsp->fs_faillog.fail_line, cur_tty, - sizeof(fsp->fs_faillog.fail_line)-1); - fsp->fs_faillog.fail_line[sizeof(fsp->fs_faillog.fail_line)-1] = 0; - } - - } else { - strncpy(fsp->fs_faillog.fail_line, remote_host, - (size_t)sizeof(fsp->fs_faillog.fail_line)); - fsp->fs_faillog.fail_line[sizeof(fsp->fs_faillog.fail_line)-1] = 0; - } - - if ( !(opts->ctrl & OPT_MAGIC_ROOT) || getuid() ) { /* magic_root doesn't change tally */ - - tally+=inc; - - if ( tally==TALLY_HI ) { /* Overflow *and* underflow. :) */ - tally-=inc; - pam_syslog(pamh, LOG_ALERT, "Tally %sflowed for user %s", - (inc<0)?"under":"over",user); - } - } - - i=set_tally(pamh, tally, uid, opts->filename, &TALLY, fsp ); - if ( i != PAM_SUCCESS ) { RETURN_ERROR( i ); } - - return PAM_SUCCESS; -} - -static int -tally_check (time_t oldtime, pam_handle_t *pamh, uid_t uid, - const char *user, struct tally_options *opts) -{ - tally_t - deny = opts->deny; - tally_t - tally = 0; /* !TALLY_HI --> Log opened for update */ - long - lock_time = opts->lock_time; - - struct fail_s fs, *fsp = &fs; - FILE *TALLY=0; - int i; - - i=get_tally(pamh, &tally, uid, opts->filename, &TALLY, fsp); - if ( i != PAM_SUCCESS ) { RETURN_ERROR( i ); } - - if ( !(opts->ctrl & OPT_MAGIC_ROOT) || getuid() ) { /* magic_root skips tally check */ - - /* To deny or not to deny; that is the question */ - - /* if there's .fail_max entry and per_user=TRUE then deny=.fail_max */ - - if ( (fsp->fs_faillog.fail_max) && (opts->ctrl & OPT_PER_USER) ) { - deny = fsp->fs_faillog.fail_max; - } - if ( (fsp->fs_faillog.fail_locktime) && (opts->ctrl & OPT_PER_USER) ) { - lock_time = fsp->fs_faillog.fail_locktime; - } - if (lock_time && oldtime - && !(opts->ctrl & OPT_NO_LOCK_TIME) ) - { - if ( lock_time + oldtime > time(NULL) ) - { - pam_syslog(pamh, LOG_NOTICE, - "user %s (%lu) has time limit [%lds left]" - " since last failure.", - user, (unsigned long int) uid, - oldtime+lock_time - -time(NULL)); - return PAM_AUTH_ERR; - } - } - if (opts->unlock_time && oldtime) - { - if ( opts->unlock_time + oldtime <= time(NULL) ) - { /* ignore deny check after unlock_time elapsed */ - return PAM_SUCCESS; - } - } - if ( - ( deny != 0 ) && /* deny==0 means no deny */ - ( tally > deny ) && /* tally>deny means exceeded */ - ( ((opts->ctrl & OPT_DENY_ROOT) || uid) ) /* even_deny stops uid check */ - ) { - pam_syslog(pamh, LOG_NOTICE, - "user %s (%lu) tally "TALLY_FMT", deny "TALLY_FMT, - user, (unsigned long int) uid, tally, deny); - return PAM_AUTH_ERR; /* Only unconditional failure */ - } - } - - return PAM_SUCCESS; -} - -static int -tally_reset (pam_handle_t *pamh, uid_t uid, struct tally_options *opts) -{ - tally_t - tally = 0; /* !TALLY_HI --> Log opened for update */ - - struct fail_s fs, *fsp = &fs; - FILE *TALLY=0; - int i; - - i=get_tally(pamh, &tally, uid, opts->filename, &TALLY, fsp); - if ( i != PAM_SUCCESS ) { RETURN_ERROR( i ); } - - /* resets if not magic root - */ - - if ( (!(opts->ctrl & OPT_MAGIC_ROOT) || getuid()) - && !(opts->ctrl & OPT_NO_RESET) ) - { tally=0; } - - if (tally == 0) - { - fsp->fs_faillog.fail_time = (time_t) 0; - strcpy(fsp->fs_faillog.fail_line, ""); - } - - i=set_tally(pamh, tally, uid, opts->filename, &TALLY, fsp); - if ( i != PAM_SUCCESS ) { RETURN_ERROR( i ); } - - return PAM_SUCCESS; -} - -/*---------------------------------------------------------------------*/ - -/* --- authentication management functions (only) --- */ - -#ifdef PAM_SM_AUTH - -PAM_EXTERN int -pam_sm_authenticate(pam_handle_t *pamh, int flags UNUSED, - int argc, const char **argv) -{ - int - rvcheck, rvbump; - time_t - oldtime = 0; - struct tally_options - options, *opts = &options; - uid_t - uid; - const char - *user; - - rvcheck = tally_parse_args(pamh, opts, PHASE_AUTH, argc, argv); - if ( rvcheck != PAM_SUCCESS ) - RETURN_ERROR( rvcheck ); - - rvcheck = pam_get_uid(pamh, &uid, &user, opts); - if ( rvcheck != PAM_SUCCESS ) - RETURN_ERROR( rvcheck ); - - rvbump = tally_bump(1, &oldtime, pamh, uid, user, opts); - rvcheck = tally_check(oldtime, pamh, uid, user, opts); - - tally_set_data(pamh, oldtime); - - return rvcheck != PAM_SUCCESS ? rvcheck : rvbump; -} - -PAM_EXTERN int -pam_sm_setcred(pam_handle_t *pamh, int flags UNUSED, - int argc, const char **argv) -{ - int - rv; - time_t - oldtime = 0; - struct tally_options - options, *opts = &options; - uid_t - uid; - const char - *user; - - rv = tally_parse_args(pamh, opts, PHASE_AUTH, argc, argv); - if ( rv != PAM_SUCCESS ) - RETURN_ERROR( rv ); - - rv = pam_get_uid(pamh, &uid, &user, opts); - if ( rv != PAM_SUCCESS ) - RETURN_ERROR( rv ); - - if ( tally_get_data(pamh, &oldtime) != 0 ) - /* no data found */ - return PAM_SUCCESS; - - if ( (rv=tally_bump(-1, &oldtime, pamh, uid, user, opts)) != PAM_SUCCESS ) - return rv; - return tally_reset(pamh, uid, opts); -} - -#endif - -/*---------------------------------------------------------------------*/ - -/* --- authentication management functions (only) --- */ - -#ifdef PAM_SM_ACCOUNT - -/* To reset failcount of user on successfull login */ - -PAM_EXTERN int -pam_sm_acct_mgmt(pam_handle_t *pamh, int flags UNUSED, - int argc, const char **argv) -{ - int - rv; - time_t - oldtime = 0; - struct tally_options - options, *opts = &options; - uid_t - uid; - const char - *user; - - rv = tally_parse_args(pamh, opts, PHASE_ACCOUNT, argc, argv); - if ( rv != PAM_SUCCESS ) - RETURN_ERROR( rv ); - - rv = pam_get_uid(pamh, &uid, &user, opts); - if ( rv != PAM_SUCCESS ) - RETURN_ERROR( rv ); - - if ( tally_get_data(pamh, &oldtime) != 0 ) - /* no data found */ - return PAM_SUCCESS; - - if ( (rv=tally_bump(-1, &oldtime, pamh, uid, user, opts)) != PAM_SUCCESS ) - return rv; - return tally_reset(pamh, uid, opts); -} - -#endif /* #ifdef PAM_SM_ACCOUNT */ - -/*-----------------------------------------------------------------------*/ - -#ifdef PAM_STATIC - -/* static module data */ - -struct pam_module _pam_tally_modstruct = { - MODULE_NAME, -#ifdef PAM_SM_AUTH - pam_sm_authenticate, - pam_sm_setcred, -#else - NULL, - NULL, -#endif -#ifdef PAM_SM_ACCOUNT - pam_sm_acct_mgmt, -#else - NULL, -#endif - NULL, - NULL, - NULL, -}; - -#endif /* #ifdef PAM_STATIC */ - -/*-----------------------------------------------------------------------*/ - -#else /* #ifndef MAIN */ - -static const char *cline_filename = DEFAULT_LOGFILE; -static tally_t cline_reset = TALLY_HI; /* Default is `interrogate only' */ -static int cline_quiet = 0; - -/* - * Not going to link with pamlib just for these.. :) - */ - -static const char * -pam_errors( int i ) -{ - switch (i) { - case PAM_AUTH_ERR: return _("Authentication error"); - case PAM_SERVICE_ERR: return _("Service error"); - case PAM_USER_UNKNOWN: return _("Unknown user"); - default: return _("Unknown error"); - } -} - -static int -getopts( char **argv ) -{ - const char *pname = *argv; - for ( ; *argv ; (void)(*argv && ++argv) ) { - if ( !strcmp (*argv,"--file") ) cline_filename=*++argv; - else if ( !strncmp(*argv,"--file=",7) ) cline_filename=*argv+7; - else if ( !strcmp (*argv,"--user") ) cline_user=*++argv; - else if ( !strncmp(*argv,"--user=",7) ) cline_user=*argv+7; - else if ( !strcmp (*argv,"--reset") ) cline_reset=0; - else if ( !strncmp(*argv,"--reset=",8)) { - if ( sscanf(*argv+8,TALLY_FMT,&cline_reset) != 1 ) - fprintf(stderr,_("%s: Bad number given to --reset=\n"),pname), exit(0); - } - else if ( !strcmp (*argv,"--quiet") ) cline_quiet=1; - else { - fprintf(stderr,_("%s: Unrecognised option %s\n"),pname,*argv); - return FALSE; - } - } - return TRUE; -} - -int main ( int argc UNUSED, char **argv ) -{ - struct fail_s fs, *fsp = &fs; - - if ( ! getopts( argv+1 ) ) { - printf(_("%s: [--file rooted-filename] [--user username] " - "[--reset[=n]] [--quiet]\n"), - *argv); - exit(0); - } - - umask(077); - - /* - * Major difference between individual user and all users: - * --user just handles one user, just like PAM. - * --user=* handles all users, sniffing cline_filename for nonzeros - */ - - if ( cline_user ) { - uid_t uid; - tally_t tally=cline_reset; - FILE *TALLY=0; - struct tally_options opts; - int i; - - memset(&opts, 0, sizeof(opts)); - opts.ctrl = OPT_AUDIT; - i=pam_get_uid(NULL, &uid, NULL, &opts); - if ( i != PAM_SUCCESS ) { - fprintf(stderr,"%s: %s\n",*argv,pam_errors(i)); - exit(0); - } - - i=get_tally(NULL, &tally, uid, cline_filename, &TALLY, fsp); - if ( i != PAM_SUCCESS ) { - fprintf(stderr,"%s: %s\n",*argv,pam_errors(i)); - exit(0); - } - - if ( !cline_quiet ) - printf("User %s\t(%lu)\t%s "TALLY_FMT"\n",cline_user, - (unsigned long int) uid, - (cline_reset!=TALLY_HI)?"had":"has",tally); - - i=set_tally(NULL, cline_reset, uid, cline_filename, &TALLY, fsp); - if ( i != PAM_SUCCESS ) { - fprintf(stderr,"%s: %s\n",*argv,pam_errors(i)); - exit(0); - } - } - else /* !cline_user (ie, operate on all users) */ { - FILE *TALLY=fopen(cline_filename, "r"); - uid_t uid=0; - if ( !TALLY ) perror(*argv), exit(0); - - for ( ; !feof(TALLY); uid++ ) { - tally_t tally; - struct passwd *pw; - if ( ! fread((char *) &fsp->fs_faillog, - sizeof (struct faillog), 1, TALLY) - || ! fsp->fs_faillog.fail_cnt ) { - continue; - } - tally = fsp->fs_faillog.fail_cnt; - - if ( ( pw=getpwuid(uid) ) ) { - printf("User %s\t(%lu)\t%s "TALLY_FMT"\n",pw->pw_name, - (unsigned long int) uid, - (cline_reset!=TALLY_HI)?"had":"has",tally); - } - else { - printf("User [NONAME]\t(%lu)\t%s "TALLY_FMT"\n", - (unsigned long int) uid, - (cline_reset!=TALLY_HI)?"had":"has",tally); - } - } - fclose(TALLY); - if ( cline_reset!=0 && cline_reset!=TALLY_HI ) { - fprintf(stderr,_("%s: Can't reset all users to non-zero\n"),*argv); - } - else if ( !cline_reset ) { - TALLY=fopen(cline_filename, "w"); - if ( !TALLY ) perror(*argv), exit(0); - fclose(TALLY); - } - } - return 0; -} - - -#endif /* #ifndef MAIN */ diff --git a/modules/pam_tally/pam_tally_app.c b/modules/pam_tally/pam_tally_app.c deleted file mode 100644 index 9e6e1faf..00000000 --- a/modules/pam_tally/pam_tally_app.c +++ /dev/null @@ -1,7 +0,0 @@ -/* - # This seemed like such a good idea at the time. :) - */ - -#define MAIN -#include "pam_tally.c" - diff --git a/modules/pam_tally/tst-pam_tally b/modules/pam_tally/tst-pam_tally deleted file mode 100755 index 15291af6..00000000 --- a/modules/pam_tally/tst-pam_tally +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/sh -../../tests/tst-dlopen .libs/pam_tally.so diff --git a/modules/pam_time/.cvsignore b/modules/pam_time/.cvsignore deleted file mode 100644 index cac9cca3..00000000 --- a/modules/pam_time/.cvsignore +++ /dev/null @@ -1,9 +0,0 @@ -*.la -*.lo -.deps -.libs -Makefile -Makefile.in -README -pam_time.8 -time.conf.5 diff --git a/modules/pam_time/Makefile.am b/modules/pam_time/Makefile.am deleted file mode 100644 index 9c63ee5e..00000000 --- a/modules/pam_time/Makefile.am +++ /dev/null @@ -1,32 +0,0 @@ -# -# Copyright (c) 2005, 2006 Thorsten Kukuk <kukuk@suse.de> -# - -CLEANFILES = *~ - -EXTRA_DIST = README $(MANS) $(XMLS) time.conf tst-pam_time - -man_MANS = time.conf.5 pam_time.8 -XMLS = README.xml time.conf.5.xml pam_time.8.xml - -TESTS = tst-pam_time - -securelibdir = $(SECUREDIR) -secureconfdir = $(SCONFIGDIR) - -AM_CFLAGS = -I$(top_srcdir)/libpam/include -I$(top_srcdir)/libpamc/include \ - -DPAM_TIME_CONF=\"$(SCONFIGDIR)/time.conf\" -AM_LDFLAGS = -no-undefined -avoid-version -module -if HAVE_VERSIONING - AM_LDFLAGS += -Wl,--version-script=$(srcdir)/../modules.map -endif -pam_time_la_LIBADD = -L$(top_builddir)/libpam -lpam - -securelib_LTLIBRARIES = pam_time.la -secureconf_DATA = time.conf - -if ENABLE_REGENERATE_MAN -noinst_DATA = README -README: pam_time.8.xml time.conf.5.xml --include $(top_srcdir)/Make.xml.rules -endif diff --git a/modules/pam_time/README.xml b/modules/pam_time/README.xml deleted file mode 100644 index 6c11eec1..00000000 --- a/modules/pam_time/README.xml +++ /dev/null @@ -1,34 +0,0 @@ -<?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 pamtime SYSTEM "pam_time.8.xml"> ---> -<!-- -<!ENTITY timeconf SYSTEM "time.conf.5.xml"> ---> -]> - -<article> - - <articleinfo> - - <title> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" - href="pam_time.8.xml" xpointer='xpointer(//refnamediv[@id = "pam_time-name"]/*)'/> - </title> - - </articleinfo> - - <section> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" - href="pam_time.8.xml" xpointer='xpointer(//refsect1[@id = "pam_time-description"]/*)'/> - </section> - - <section> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" - href="time.conf.5.xml" xpointer='xpointer(//refsect1[@id = "time.conf-examples"]/*)'/> - </section> - -</article> diff --git a/modules/pam_time/pam_time.8.xml b/modules/pam_time/pam_time.8.xml deleted file mode 100644 index e0b149a7..00000000 --- a/modules/pam_time/pam_time.8.xml +++ /dev/null @@ -1,183 +0,0 @@ -<?xml version="1.0" encoding="ISO-8859-1"?> -<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN" - "http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd"> - -<refentry id='pam_time'> - - <refmeta> - <refentrytitle>pam_time</refentrytitle> - <manvolnum>8</manvolnum> - <refmiscinfo class='setdesc'>Linux-PAM Manual</refmiscinfo> - </refmeta> - - <refnamediv id='pam_time-name'> - <refname>pam_time</refname> - <refpurpose> - PAM module for time control access - </refpurpose> - </refnamediv> - -<!-- body begins here --> - - <refsynopsisdiv> - <cmdsynopsis id="pam_time-cmdsynopsis"> - <command>pam_time.so</command> - <arg choice="opt"> - debug - </arg> - <arg choice="opt"> - noaudit - </arg> - </cmdsynopsis> - </refsynopsisdiv> - - - <refsect1 id="pam_time-description"> - <title>DESCRIPTION</title> - <para> - The pam_time PAM module does not authenticate the user, but instead - it restricts access to a system and or specific applications at - various times of the day and on specific days or over various - terminal lines. This module can be configured to deny access to - (individual) users based on their name, the time of day, the day of - week, the service they are applying for and their terminal from which - they are making their request. - </para> - <para> - By default rules for time/port access are taken from config file - <filename>/etc/security/time.conf</filename>. - </para> - <para> - If Linux PAM is compiled with audit support the module will report - when it denies access. - </para> - </refsect1> - - <refsect1 id="pam_time-options"> - <title>OPTIONS</title> - <variablelist> - - <varlistentry> - <term> - <option>debug</option> - </term> - <listitem> - <para> - Some debug informations are printed with - <citerefentry><refentrytitle>syslog</refentrytitle><manvolnum>3</manvolnum></citerefentry>. - </para> - </listitem> - </varlistentry> - - <varlistentry> - <term> - <option>noaudit</option> - </term> - <listitem> - <para> - Do not report logins at disallowed time to the audit subsystem. - </para> - </listitem> - </varlistentry> - - </variablelist> - </refsect1> - - <refsect1 id="pam_time-services"> - <title>MODULE SERVICES PROVIDED</title> - <para> - Only the <option>account</option> service is supported. - </para> - </refsect1> - - <refsect1 id="pam_time-return_values"> - <title>RETURN VALUES</title> - <variablelist> - <varlistentry> - <term>PAM_SUCCESS</term> - <listitem> - <para> - Access was granted. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term>PAM_ABORT</term> - <listitem> - <para> - Not all relevant data could be gotten. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term>PAM_BUF_ERR</term> - <listitem> - <para> - Memory buffer error. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term>PAM_PERM_DENIED</term> - <listitem> - <para> - Access was not granted. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term>PAM_USER_UNKNOWN</term> - <listitem> - <para> - The user is not known to the system. - </para> - </listitem> - </varlistentry> - </variablelist> - </refsect1> - - <refsect1 id="pam_time-files"> - <title>FILES</title> - <variablelist> - <varlistentry> - <term><filename>/etc/security/time.conf</filename></term> - <listitem> - <para>Default configuration file</para> - </listitem> - </varlistentry> - </variablelist> - </refsect1> - - <refsect1 id='pam_time-examples'> - <title>EXAMPLES</title> - <programlisting> -#%PAM-1.0 -# -# apply pam_time accounting to login requests -# -login account required pam_time.so - </programlisting> - </refsect1> - - <refsect1 id="pam_time-see_also"> - <title>SEE ALSO</title> - <para> - <citerefentry> - <refentrytitle>time.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_time-authors"> - <title>AUTHOR</title> - <para> - pam_time was written by Andrew G. Morgan <morgan@kernel.org>. - </para> - </refsect1> -</refentry> diff --git a/modules/pam_time/pam_time.c b/modules/pam_time/pam_time.c deleted file mode 100644 index 8e3b2486..00000000 --- a/modules/pam_time/pam_time.c +++ /dev/null @@ -1,687 +0,0 @@ -/* pam_time module */ - -/* - * Written by Andrew Morgan <morgan@linux.kernel.org> 1996/6/22 - * (File syntax and much other inspiration from the shadow package - * shadow-960129) - */ - -#include "config.h" - -#include <sys/file.h> -#include <stdio.h> -#include <stdlib.h> -#include <ctype.h> -#include <unistd.h> -#include <stdarg.h> -#include <time.h> -#include <syslog.h> -#include <string.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <fcntl.h> -#include <netdb.h> - -#ifdef HAVE_LIBAUDIT -#include <libaudit.h> -#endif - -#define PAM_TIME_BUFLEN 1000 -#define FIELD_SEPARATOR ';' /* this is new as of .02 */ - -#define PAM_DEBUG_ARG 0x0001 -#define PAM_NO_AUDIT 0x0002 - -#ifndef TRUE -# define TRUE 1 -#endif -#ifndef FALSE -# define FALSE 0 -#endif - -typedef enum { AND, OR } operator; - -/* - * here, we make definitions for the externally accessible functions - * in this file (these definitions are required for static modules - * but strongly encouraged generally) they are used to instruct the - * modules include file to define their prototypes. - */ - -#define PAM_SM_ACCOUNT - -#include <security/_pam_macros.h> -#include <security/pam_modules.h> -#include <security/pam_ext.h> -#include <security/pam_modutil.h> - -static int -_pam_parse (const pam_handle_t *pamh, int argc, const char **argv) -{ - int ctrl = 0; - - /* step through arguments */ - for (; argc-- > 0; ++argv) { - - /* generic options */ - - if (!strcmp(*argv, "debug")) { - ctrl |= PAM_DEBUG_ARG; - } else if (!strcmp(*argv, "noaudit")) { - ctrl |= PAM_NO_AUDIT; - } else { - pam_syslog(pamh, LOG_ERR, "unknown option: %s", *argv); - } - } - - return ctrl; -} - -/* --- static functions for checking whether the user should be let in --- */ - -static void -shift_bytes(char *mem, int from, int by) -{ - while (by-- > 0) { - *mem = mem[from]; - ++mem; - } -} - -static int -read_field(const pam_handle_t *pamh, int fd, char **buf, int *from, int *to) -{ - /* is buf set ? */ - - if (! *buf) { - *buf = (char *) malloc(PAM_TIME_BUFLEN); - if (! *buf) { - pam_syslog(pamh, LOG_ERR, "out of memory"); - D(("no memory")); - return -1; - } - *from = *to = 0; - fd = open(PAM_TIME_CONF, O_RDONLY); - } - - /* do we have a file open ? return error */ - - if (fd < 0 && *to <= 0) { - pam_syslog(pamh, LOG_ERR, "error opening %s: %m", PAM_TIME_CONF); - memset(*buf, 0, PAM_TIME_BUFLEN); - _pam_drop(*buf); - return -1; - } - - /* check if there was a newline last time */ - - if ((*to > *from) && (*to > 0) - && ((*buf)[*from] == '\0')) { /* previous line ended */ - (*from)++; - (*buf)[0] = '\0'; - return fd; - } - - /* ready for more data: first shift the buffer's remaining data */ - - *to -= *from; - shift_bytes(*buf, *from, *to); - *from = 0; - (*buf)[*to] = '\0'; - - while (fd >= 0 && *to < PAM_TIME_BUFLEN) { - int i; - - /* now try to fill the remainder of the buffer */ - - i = read(fd, *to + *buf, PAM_TIME_BUFLEN - *to); - if (i < 0) { - pam_syslog(pamh, LOG_ERR, "error reading %s: %m", PAM_TIME_CONF); - close(fd); - return -1; - } else if (!i) { - close(fd); - fd = -1; /* end of file reached */ - } else - *to += i; - - /* - * contract the buffer. Delete any comments, and replace all - * multiple spaces with single commas - */ - - i = 0; -#ifdef DEBUG_DUMP - D(("buffer=<%s>",*buf)); -#endif - while (i < *to) { - if ((*buf)[i] == ',') { - int j; - - for (j=++i; j<*to && (*buf)[j] == ','; ++j); - if (j!=i) { - shift_bytes(i + (*buf), j-i, (*to) - j); - *to -= j-i; - } - } - switch ((*buf)[i]) { - int j,c; - case '#': - c = 0; - for (j=i; j < *to && (c = (*buf)[j]) != '\n'; ++j); - if (j >= *to) { - (*buf)[*to = ++i] = '\0'; - } else if (c == '\n') { - shift_bytes(i + (*buf), j-i, (*to) - j); - *to -= j-i; - ++i; - } else { - pam_syslog(pamh, LOG_CRIT, - "internal error in file %s at line %d", - __FILE__, __LINE__); - close(fd); - return -1; - } - break; - case '\\': - if ((*buf)[i+1] == '\n') { - shift_bytes(i + *buf, 2, *to - (i+2)); - *to -= 2; - } else { - ++i; /* we don't escape non-newline characters */ - } - break; - case '!': - case ' ': - case '\t': - if ((*buf)[i] != '!') - (*buf)[i] = ','; - /* delete any trailing spaces */ - for (j=++i; j < *to && ( (c = (*buf)[j]) == ' ' - || c == '\t' ); ++j); - shift_bytes(i + *buf, j-i, (*to)-j ); - *to -= j-i; - break; - default: - ++i; - } - } - } - - (*buf)[*to] = '\0'; - - /* now return the next field (set the from/to markers) */ - { - int i; - - for (i=0; i<*to; ++i) { - switch ((*buf)[i]) { - case '#': - case '\n': /* end of the line/file */ - (*buf)[i] = '\0'; - *from = i; - return fd; - case FIELD_SEPARATOR: /* end of the field */ - (*buf)[i] = '\0'; - *from = ++i; - return fd; - } - } - *from = i; - (*buf)[*from] = '\0'; - } - - if (*to <= 0) { - D(("[end of text]")); - *buf = NULL; - } - - return fd; -} - -/* read a member from a field */ - -static int -logic_member(const char *string, int *at) -{ - int c,to; - int done=0; - int token=0; - - to=*at; - do { - c = string[to++]; - - switch (c) { - - case '\0': - --to; - done = 1; - break; - - case '&': - case '|': - case '!': - if (token) { - --to; - } - done = 1; - break; - - default: - if (isalpha(c) || c == '*' || isdigit(c) || c == '_' - || c == '-' || c == '.' || c == '/' || c == ':') { - token = 1; - } else if (token) { - --to; - done = 1; - } else { - ++*at; - } - } - } while (!done); - - return to - *at; -} - -typedef enum { VAL, OP } expect; - -static int -logic_field(pam_handle_t *pamh, const void *me, const char *x, int rule, - int (*agrees)(pam_handle_t *pamh, - const void *, const char *, int, int)) -{ - int left=FALSE, right, not=FALSE; - operator oper=OR; - int at=0, l; - expect next=VAL; - - while ((l = logic_member(x,&at))) { - int c = x[at]; - - if (next == VAL) { - if (c == '!') - not = !not; - else if (isalpha(c) || c == '*' || isdigit(c) || c == '_' - || c == '-' || c == '.' || c == '/' || c == ':') { - right = not ^ agrees(pamh, me, x+at, l, rule); - if (oper == AND) - left &= right; - else - left |= right; - next = OP; - } else { - pam_syslog(pamh, LOG_ERR, - "garbled syntax; expected name (rule #%d)", - rule); - return FALSE; - } - } else { /* OP */ - switch (c) { - case '&': - oper = AND; - break; - case '|': - oper = OR; - break; - default: - pam_syslog(pamh, LOG_ERR, - "garbled syntax; expected & or | (rule #%d)", - rule); - D(("%c at %d",c,at)); - return FALSE; - } - next = VAL; - } - at += l; - } - - return left; -} - -static int -is_same(pam_handle_t *pamh UNUSED, const void *A, const char *b, - int len, int rule UNUSED) -{ - int i; - const char *a; - - a = A; - for (i=0; len > 0; ++i, --len) { - if (b[i] != a[i]) { - if (b[i++] == '*') { - return (!--len || !strncmp(b+i,a+strlen(a)-len,len)); - } else - return FALSE; - } - } - - /* Ok, we know that b is a substring from A and does not contain - wildcards, but now the length of both strings must be the same, - too. */ - if (strlen (a) != strlen(b)) - return FALSE; - - return ( !len ); -} - -typedef struct { - int day; /* array of 7 bits, one set for today */ - int minute; /* integer, hour*100+minute for now */ -} TIME; - -static struct day { - const char *d; - int bit; -} const days[11] = { - { "su", 01 }, - { "mo", 02 }, - { "tu", 04 }, - { "we", 010 }, - { "th", 020 }, - { "fr", 040 }, - { "sa", 0100 }, - { "wk", 076 }, - { "wd", 0101 }, - { "al", 0177 }, - { NULL, 0 } -}; - -static TIME -time_now(void) -{ - struct tm *local; - time_t the_time; - TIME this; - - the_time = time((time_t *)0); /* get the current time */ - local = localtime(&the_time); - this.day = days[local->tm_wday].bit; - this.minute = local->tm_hour*100 + local->tm_min; - - D(("day: 0%o, time: %.4d", this.day, this.minute)); - return this; -} - -/* take the current date and see if the range "date" passes it */ -static int -check_time(pam_handle_t *pamh, const void *AT, const char *times, - int len, int rule) -{ - int not,pass; - int marked_day, time_start, time_end; - const TIME *at; - int i,j=0; - - at = AT; - D(("chcking: 0%o/%.4d vs. %s", at->day, at->minute, times)); - - if (times == NULL) { - /* this should not happen */ - pam_syslog(pamh, LOG_CRIT, - "internal error in file %s at line %d", - __FILE__, __LINE__); - return FALSE; - } - - if (times[j] == '!') { - ++j; - not = TRUE; - } else { - not = FALSE; - } - - for (marked_day = 0; len > 0 && isalpha(times[j]); --len) { - int this_day=-1; - - D(("%c%c ?", times[j], times[j+1])); - for (i=0; days[i].d != NULL; ++i) { - if (tolower(times[j]) == days[i].d[0] - && tolower(times[j+1]) == days[i].d[1] ) { - this_day = days[i].bit; - break; - } - } - j += 2; - if (this_day == -1) { - pam_syslog(pamh, LOG_ERR, "bad day specified (rule #%d)", rule); - return FALSE; - } - marked_day ^= this_day; - } - if (marked_day == 0) { - pam_syslog(pamh, LOG_ERR, "no day specified"); - return FALSE; - } - D(("day range = 0%o", marked_day)); - - time_start = 0; - for (i=0; len > 0 && i < 4 && isdigit(times[i+j]); ++i, --len) { - time_start *= 10; - time_start += times[i+j]-'0'; /* is this portable? */ - } - j += i; - - if (times[j] == '-') { - time_end = 0; - for (i=1; len > 0 && i < 5 && isdigit(times[i+j]); ++i, --len) { - time_end *= 10; - time_end += times[i+j]-'0'; /* is this portable */ - } - j += i; - } else - time_end = -1; - - D(("i=%d, time_end=%d, times[j]='%c'", i, time_end, times[j])); - if (i != 5 || time_end == -1) { - pam_syslog(pamh, LOG_ERR, "no/bad times specified (rule #%d)", rule); - return TRUE; - } - D(("times(%d to %d)", time_start,time_end)); - D(("marked_day = 0%o", marked_day)); - - /* compare with the actual time now */ - - pass = FALSE; - if (time_start < time_end) { /* start < end ? --> same day */ - if ((at->day & marked_day) && (at->minute >= time_start) - && (at->minute < time_end)) { - D(("time is listed")); - pass = TRUE; - } - } else { /* spans two days */ - if ((at->day & marked_day) && (at->minute >= time_start)) { - D(("caught on first day")); - pass = TRUE; - } else { - marked_day <<= 1; - marked_day |= (marked_day & 0200) ? 1:0; - D(("next day = 0%o", marked_day)); - if ((at->day & marked_day) && (at->minute <= time_end)) { - D(("caught on second day")); - pass = TRUE; - } - } - } - - return (not ^ pass); -} - -static int -check_account(pam_handle_t *pamh, const char *service, - const char *tty, const char *user) -{ - int from=0,to=0,fd=-1; - char *buffer=NULL; - int count=0; - TIME here_and_now; - int retval=PAM_SUCCESS; - - here_and_now = time_now(); /* find current time */ - do { - int good=TRUE,intime; - - /* here we get the service name field */ - - fd = read_field(pamh, fd, &buffer, &from, &to); - - if (!buffer || !buffer[0]) { - /* empty line .. ? */ - continue; - } - ++count; - - good = logic_field(pamh, service, buffer, count, is_same); - D(("with service: %s", good ? "passes":"fails" )); - - /* here we get the terminal name field */ - - fd = read_field(pamh, fd, &buffer, &from, &to); - if (!buffer || !buffer[0]) { - pam_syslog(pamh, LOG_ERR, - "%s: no tty entry #%d", PAM_TIME_CONF, count); - continue; - } - good &= logic_field(pamh, tty, buffer, count, is_same); - D(("with tty: %s", good ? "passes":"fails" )); - - /* here we get the username field */ - - fd = read_field(pamh, fd, &buffer, &from, &to); - if (!buffer || !buffer[0]) { - pam_syslog(pamh, LOG_ERR, - "%s: no user entry #%d", PAM_TIME_CONF, count); - continue; - } - /* If buffer starts with @, we are using netgroups */ - if (buffer[0] == '@') - good &= innetgr (&buffer[1], NULL, user, NULL); - else - good &= logic_field(pamh, user, buffer, count, is_same); - D(("with user: %s", good ? "passes":"fails" )); - - /* here we get the time field */ - - fd = read_field(pamh, fd, &buffer, &from, &to); - if (!buffer || !buffer[0]) { - pam_syslog(pamh, LOG_ERR, - "%s: no time entry #%d", PAM_TIME_CONF, count); - continue; - } - - intime = logic_field(pamh, &here_and_now, buffer, count, check_time); - D(("with time: %s", intime ? "passes":"fails" )); - - fd = read_field(pamh, fd, &buffer, &from, &to); - if (buffer && buffer[0]) { - pam_syslog(pamh, LOG_ERR, - "%s: poorly terminated rule #%d", PAM_TIME_CONF, count); - continue; - } - - if (good && !intime) { - /* - * for security parse whole file.. also need to ensure - * that the buffer is free()'d and the file is closed. - */ - retval = PAM_PERM_DENIED; - } else { - D(("rule passed")); - } - } while (buffer); - - return retval; -} - -/* --- public account management functions --- */ - -PAM_EXTERN int -pam_sm_acct_mgmt(pam_handle_t *pamh, int flags UNUSED, - int argc, const char **argv) -{ - const void *service=NULL, *void_tty=NULL; - const char *tty; - const char *user=NULL; - int ctrl; - int rv; - - ctrl = _pam_parse(pamh, argc, argv); - - /* set service name */ - - if (pam_get_item(pamh, PAM_SERVICE, &service) - != PAM_SUCCESS || service == NULL) { - pam_syslog(pamh, LOG_ERR, "cannot find the current service name"); - return PAM_ABORT; - } - - /* set username */ - - if (pam_get_user(pamh, &user, NULL) != PAM_SUCCESS || user == NULL - || *user == '\0') { - pam_syslog(pamh, LOG_ERR, "can not get the username"); - return PAM_USER_UNKNOWN; - } - - /* set tty name */ - - if (pam_get_item(pamh, PAM_TTY, &void_tty) != PAM_SUCCESS - || void_tty == NULL) { - D(("PAM_TTY not set, probing stdin")); - tty = ttyname(STDIN_FILENO); - if (tty == NULL) { - tty = ""; - } - if (pam_set_item(pamh, PAM_TTY, tty) != PAM_SUCCESS) { - pam_syslog(pamh, LOG_ERR, "couldn't set tty name"); - return PAM_ABORT; - } - } - else - tty = void_tty; - - if (tty[0] == '/') { /* full path */ - const char *t; - tty++; - if ((t = strchr(tty, '/')) != NULL) { - tty = t + 1; - } - } - - /* good, now we have the service name, the user and the terminal name */ - - D(("service=%s", service)); - D(("user=%s", user)); - D(("tty=%s", tty)); - - rv = check_account(pamh, service, tty, user); - if (rv != PAM_SUCCESS) { -#ifdef HAVE_LIBAUDIT - if (!(ctrl & PAM_NO_AUDIT)) { - pam_modutil_audit_write(pamh, AUDIT_ANOM_LOGIN_TIME, - "pam_time", rv); /* ignore return value as we fail anyway */ - } -#endif - if (ctrl & PAM_DEBUG_ARG) { - pam_syslog(pamh, LOG_DEBUG, "user %s rejected", user); - } - } - return rv; -} - -/* end of module definition */ - -#ifdef PAM_STATIC - -/* static module data */ - -struct pam_module _pam_time_modstruct = { - "pam_time", - NULL, - NULL, - pam_sm_acct_mgmt, - NULL, - NULL, - NULL -}; -#endif diff --git a/modules/pam_time/time.conf b/modules/pam_time/time.conf deleted file mode 100644 index c7b7989c..00000000 --- a/modules/pam_time/time.conf +++ /dev/null @@ -1,65 +0,0 @@ -# this is an example configuration file for the pam_time module. Its syntax -# was initially based heavily on that of the shadow package (shadow-960129). -# -# the syntax of the lines is as follows: -# -# services;ttys;users;times -# -# white space is ignored and lines maybe extended with '\\n' (escaped -# newlines). As should be clear from reading these comments, -# text following a '#' is ignored to the end of the line. -# -# the combination of individual users/terminals etc is a logic list -# namely individual tokens that are optionally prefixed with '!' (logical -# not) and separated with '&' (logical and) and '|' (logical or). -# -# services -# is a logic list of PAM service names that the rule applies to. -# -# ttys -# is a logic list of terminal names that this rule applies to. -# -# users -# is a logic list of users or a netgroup of users to whom this -# rule applies. -# -# NB. For these items the simple wildcard '*' may be used only once. -# -# times -# the format here is a logic list of day/time-range -# entries the days are specified by a sequence of two character -# entries, MoTuSa for example is Monday Tuesday and Saturday. Note -# that repeated days are unset MoMo = no day, and MoWk = all weekdays -# bar Monday. The two character combinations accepted are -# -# Mo Tu We Th Fr Sa Su Wk Wd Al -# -# the last two being week-end days and all 7 days of the week -# respectively. As a final example, AlFr means all days except Friday. -# -# each day/time-range can be prefixed with a '!' to indicate "anything -# but" -# -# The time-range part is two 24-hour times HHMM separated by a hyphen -# indicating the start and finish time (if the finish time is smaller -# than the start time it is deemed to apply on the following day). -# -# for a rule to be active, ALL of service+ttys+users must be satisfied -# by the applying process. -# - -# -# Here is a simple example: running blank on tty* (any ttyXXX device), -# the users 'you' and 'me' are denied service all of the time -# - -#blank;tty* & !ttyp*;you|me;!Al0000-2400 - -# Another silly example, user 'root' is denied xsh access -# from pseudo terminals at the weekend and on mondays. - -#xsh;ttyp*;root;!WdMo0000-2400 - -# -# End of example file. -# diff --git a/modules/pam_time/time.conf.5.xml b/modules/pam_time/time.conf.5.xml deleted file mode 100644 index 224fda34..00000000 --- a/modules/pam_time/time.conf.5.xml +++ /dev/null @@ -1,143 +0,0 @@ -<?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="time.conf"> - - <refmeta> - <refentrytitle>time.conf</refentrytitle> - <manvolnum>5</manvolnum> - <refmiscinfo class="sectdesc">Linux-PAM Manual</refmiscinfo> - </refmeta> - - <refnamediv> - <refname>time.conf</refname> - <refpurpose>configuration file for the pam_time module</refpurpose> - </refnamediv> - - <refsect1 id='time.conf-description'> - <title>DESCRIPTION</title> - - <para> - The pam_time PAM module does not authenticate the user, but instead - it restricts access to a system and or specific applications at - various times of the day and on specific days or over various - terminal lines. This module can be configured to deny access to - (individual) users based on their name, the time of day, the day of - week, the service they are applying for and their terminal from which - they are making their request. - </para> - <para> - For this module to function correctly there must be a correctly - formatted <filename>/etc/security/time.conf</filename> file present. - White spaces are ignored and lines maybe extended with '\' (escaped - newlines). Text following a '#' is ignored to the end of the line. - </para> - - <para> - The syntax of the lines is as follows: - </para> - - <para> - <replaceable>services</replaceable>;<replaceable>ttys</replaceable>;<replaceable>users</replaceable>;<replaceable>times</replaceable> - </para> - <para> - In words, each rule occupies a line, terminated with a newline - or the beginning of a comment; a '<emphasis remap='B'>#</emphasis>'. - It contains four fields separated with semicolons, - '<emphasis remap='B'>;</emphasis>'. - </para> - - <para> - The first field, the <replaceable>services</replaceable> field, - is a logic list of PAM service names that the rule applies to. - </para> - - <para> - The second field, the <replaceable>tty</replaceable> - field, is a logic list of terminal names that this rule applies to. - </para> - - <para> - The third field, the <replaceable>users</replaceable> - field, is a logic list of users or a netgroup of users to whom this - rule applies. - </para> - - <para> - For these items the simple wildcard '*' may be used only once. - With netgroups no wildcards or logic operators are allowed. - </para> - - <para> - The <replaceable>times</replaceable> field is used to indicate the times - at which this rule applies. The format here is a logic - list of day/time-range entries. The days are specified by a sequence of - two character entries, MoTuSa for example is Monday Tuesday and Saturday. - Note that repeated days are unset MoMo = no day, and MoWk = all weekdays - bar Monday. The two character combinations accepted are Mo Tu We Th Fr Sa - Su Wk Wd Al, the last two being week-end days and all 7 days of the week - respectively. As a final example, AlFr means all days except Friday. - </para> - <para> - Each day/time-range can be prefixed with a '!' to indicate - "anything but". - The time-range part is two 24-hour times HHMM, separated by a hyphen, - indicating the start and finish time (if the finish time is smaller - than the start time it is deemed to apply on the following day). - </para> - - <para> - For a rule to be active, ALL of service+ttys+users must be satisfied - by the applying process. - </para> - <para> - Note, currently there is no daemon enforcing the end of a session. - This needs to be remedied. - </para> - <para> - Poorly formatted rules are logged as errors using - <citerefentry><refentrytitle>syslog</refentrytitle><manvolnum>3</manvolnum></citerefentry>. - </para> - </refsect1> - - <refsect1 id="time.conf-examples"> - <title>EXAMPLES</title> - <para> - These are some example lines which might be specified in - <filename>/etc/security/time.conf</filename>. - </para> - <para> - All users except for <emphasis>root</emphasis> are denied access - to console-login at all times: - <programlisting> -login ; tty* & !ttyp* ; !root ; !Al0000-2400 - </programlisting> - </para> - - <para> - Games (configured to use PAM) are only to be accessed out of - working hours. This rule does not apply to the user - <emphasis>waster</emphasis>: - <programlisting> -games ; * ; !waster ; Wd0000-2400 | Wk1800-0800 - </programlisting> - </para> - </refsect1> - - <refsect1 id="time.conf-see_also"> - <title>SEE ALSO</title> - <para> - <citerefentry><refentrytitle>pam_time</refentrytitle><manvolnum>8</manvolnum></citerefentry>, - <citerefentry><refentrytitle>pam.d</refentrytitle><manvolnum>5</manvolnum></citerefentry>, - <citerefentry><refentrytitle>pam</refentrytitle><manvolnum>8</manvolnum></citerefentry> - </para> - </refsect1> - - <refsect1 id="time.conf-author"> - <title>AUTHOR</title> - <para> - pam_time was written by Andrew G. Morgan <morgan@kernel.org>. - </para> - </refsect1> -</refentry> diff --git a/modules/pam_time/tst-pam_time b/modules/pam_time/tst-pam_time deleted file mode 100755 index 030717bb..00000000 --- a/modules/pam_time/tst-pam_time +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/sh -../../tests/tst-dlopen .libs/pam_time.so diff --git a/modules/pam_tty_audit/.cvsignore b/modules/pam_tty_audit/.cvsignore deleted file mode 100644 index aefb9d6f..00000000 --- a/modules/pam_tty_audit/.cvsignore +++ /dev/null @@ -1,8 +0,0 @@ -*.la -*.lo -.deps -.libs -Makefile -Makefile.in -README -pam_tty_audit.8 diff --git a/modules/pam_tty_audit/Makefile.am b/modules/pam_tty_audit/Makefile.am deleted file mode 100644 index 5bb64585..00000000 --- a/modules/pam_tty_audit/Makefile.am +++ /dev/null @@ -1,30 +0,0 @@ -# -# Copyright (c) 2005, 2006 Thorsten Kukuk <kukuk@suse.de> -# - -CLEANFILES = *~ - -EXTRA_DIST = README $(MANS) $(XMLS) - -man_MANS = pam_tty_audit.8 -XMLS = README.xml pam_tty_audit.8.xml - -securelibdir = $(SECUREDIR) - -AM_CFLAGS = -I$(top_srcdir)/libpam/include -I$(top_srcdir)/libpamc/include -AM_LDFLAGS = -no-undefined -avoid-version -module -if HAVE_VERSIONING - AM_LDFLAGS += -Wl,--version-script=$(srcdir)/../modules.map -endif - -if HAVE_AUDIT_TTY_STATUS - pam_tty_audit_la_LIBADD = -L$(top_builddir)/libpam -lpam - securelib_LTLIBRARIES = pam_tty_audit.la -endif - -if ENABLE_REGENERATE_MAN -noinst_DATA = README -README: pam_tty_audit.8.xml --include $(top_srcdir)/Make.xml.rules -endif - diff --git a/modules/pam_tty_audit/README.xml b/modules/pam_tty_audit/README.xml deleted file mode 100644 index 4dad6bbe..00000000 --- a/modules/pam_tty_audit/README.xml +++ /dev/null @@ -1,41 +0,0 @@ -<?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"> - -<article> - - <articleinfo> - - <title> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" - href="pam_tty_audit.8.xml" xpointer='xpointer(//refnamediv[@id = "pam_tty_audit-name"]/*)'/> - </title> - - </articleinfo> - - <section> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" - href="pam_tty_audit.8.xml" xpointer='xpointer(//refsect1[@id = "pam_tty_audit-description"]/*)'/> - </section> - - <section> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" - href="pam_tty_audit.8.xml" xpointer='xpointer(//refsect1[@id = "pam_tty_audit-options"]/*)'/> - </section> - - <section> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" - href="pam_tty_audit.8.xml" xpointer='xpointer(//refsect1[@id = "pam_tty_audit-notes"]/*)'/> - </section> - - <section> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" - href="pam_tty_audit.8.xml" xpointer='xpointer(//refsect1[@id = "pam_tty_audit-examples"]/*)'/> - </section> - - <section> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" - href="pam_tty_audit.8.xml" xpointer='xpointer(//refsect1[@id = "pam_tty_audit-author"]/*)'/> - </section> - -</article> diff --git a/modules/pam_tty_audit/pam_tty_audit.8.xml b/modules/pam_tty_audit/pam_tty_audit.8.xml deleted file mode 100644 index f6f0602f..00000000 --- a/modules/pam_tty_audit/pam_tty_audit.8.xml +++ /dev/null @@ -1,145 +0,0 @@ -<?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_tty_audit"> - - <refmeta> - <refentrytitle>pam_tty_audit</refentrytitle> - <manvolnum>8</manvolnum> - <refmiscinfo class="sectdesc">Linux-PAM Manual</refmiscinfo> - </refmeta> - - <refnamediv id="pam_tty_audit-name"> - <refname>pam_tty_audit</refname> - <refpurpose>Enable or disable TTY auditing for specified users</refpurpose> - </refnamediv> - - <refsynopsisdiv> - <cmdsynopsis id="pam_tty_audit-cmdsynopsis"> - <command>pam_tty_audit.so</command> - <arg choice="opt"> - disable=<replaceable>patterns</replaceable> - </arg> - <arg choice="opt"> - enable=<replaceable>patterns</replaceable> - </arg> - </cmdsynopsis> - </refsynopsisdiv> - - <refsect1 id="pam_tty_audit-description"> - <title>DESCRIPTION</title> - <para> - The pam_tty_audit PAM module is used to enable or disable TTY auditing. - By default, the kernel does not audit input on any TTY. - </para> - </refsect1> - - <refsect1 id="pam_tty_audit-options"> - <title>OPTIONS</title> - <variablelist> - <varlistentry> - <term> - <option>disable=<replaceable>patterns</replaceable></option> - </term> - <listitem> - <para> - For each user matching one of comma-separated glob - <option><replaceable>patterns</replaceable></option>, disable - TTY auditing. This overrides any previous <option>enable</option> - option matchin the same user name on the command line. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <option>enable=<replaceable>patterns</replaceable></option> - </term> - <listitem> - <para> - For each user matching one of comma-separated glob - <option><replaceable>patterns</replaceable></option>, enable - TTY auditing. This overrides any previous <option>disable</option> - option matching the same user name on the command line. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <option>open_only</option> - </term> - <listitem> - <para> - Set the TTY audit flag when opening the session, but do not restore - it when closing the session. Using this option is necessary for - some services that don't <function>fork()</function> to run the - authenticated session, such as <command>sudo</command>. - </para> - </listitem> - </varlistentry> - </variablelist> - </refsect1> - - <refsect1 id="pam_tty_audit-services"> - <title>MODULE SERVICES PROVIDED</title> - <para> - Only the <emphasis remap='B'>session</emphasis> service is supported. - </para> - </refsect1> - - <refsect1 id='pam_tty_audit-return_values'> - <title>RETURN VALUES</title> - <variablelist> - <varlistentry> - <term>PAM_SESSION_ERR</term> - <listitem> - <para> - Error reading or modifying the TTY audit flag. See the system log - for more details. - </para> - </listitem> - </varlistentry> - - <varlistentry> - <term>PAM_SUCCESS</term> - <listitem> - <para> - Success. - </para> - </listitem> - </varlistentry> - - </variablelist> - </refsect1> - - <refsect1 id='pam_tty_audit-notes'> - <title>NOTES</title> - <para> - When TTY auditing is enabled, it is inherited by all processes started by - that user. In particular, daemons restarted by an user will still have - TTY auditing enabled, and audit TTY input even by other users unless - auditing for these users is explicitly disabled. Therefore, it is - recommended to use <option>disable=*</option> as the first option for - most daemons using PAM. - </para> - </refsect1> - - <refsect1 id='pam_tty_audit-examples'> - <title>EXAMPLES</title> - <para> - Audit all administrative actions. - <programlisting> -session required pam_tty_audit.so disable=* enable=root - </programlisting> - </para> - </refsect1> - - <refsect1 id='pam_tty_audit-author'> - <title>AUTHOR</title> - <para> - pam_tty_audit was written by Miloslav Trmač - <mitr@redhat.com>. - </para> - </refsect1> - -</refentry> diff --git a/modules/pam_tty_audit/pam_tty_audit.c b/modules/pam_tty_audit/pam_tty_audit.c deleted file mode 100644 index d57dbbe3..00000000 --- a/modules/pam_tty_audit/pam_tty_audit.c +++ /dev/null @@ -1,346 +0,0 @@ -/* Copyright © 2007, 2008 Red Hat, Inc. All rights reserved. - Red Hat author: Miloslav TrmaÄ <mitr@redhat.com> - - Redistribution and use in source and binary forms of Linux-PAM, with - or without modification, are permitted provided that the following - conditions are met: - - 1. Redistributions of source code must retain any existing copyright - notice, and this entire permission notice in its entirety, - including the disclaimer of warranties. - - 2. Redistributions in binary form must reproduce all prior and current - copyright notices, this list of conditions, and the following - disclaimer in the documentation and/or other materials provided - with the distribution. - - 3. The name of any author may not be used to endorse or promote - products derived from this software without their specific prior - written permission. - - ALTERNATIVELY, this product may be distributed under the terms of the - GNU General Public License, in which case the provisions of the GNU - GPL are required INSTEAD OF the above restrictions. (This clause is - necessary due to a potential conflict between the GNU 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(S) 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 <errno.h> -#include <fnmatch.h> -#include <stdlib.h> -#include <string.h> -#include <syslog.h> -#include <sys/socket.h> -#include <unistd.h> - -#include <libaudit.h> -#include <linux/netlink.h> - -#define PAM_SM_SESSION - -#include <security/pam_ext.h> -#include <security/pam_modules.h> -#include <security/pam_modutil.h> - -#define DATANAME "pam_tty_audit_last_state" - -/* Open an audit netlink socket */ -static int -nl_open (void) -{ - return socket (AF_NETLINK, SOCK_RAW, NETLINK_AUDIT); -} - -static int -nl_send (int fd, unsigned type, unsigned flags, const void *data, size_t size) -{ - struct sockaddr_nl addr; - struct msghdr msg; - struct nlmsghdr nlm; - struct iovec iov[2]; - ssize_t res; - - nlm.nlmsg_len = NLMSG_LENGTH (size); - nlm.nlmsg_type = type; - nlm.nlmsg_flags = NLM_F_REQUEST | flags; - nlm.nlmsg_seq = 0; - nlm.nlmsg_pid = 0; - iov[0].iov_base = &nlm; - iov[0].iov_len = sizeof (nlm); - iov[1].iov_base = (void *)data; - iov[1].iov_len = size; - addr.nl_family = AF_NETLINK; - addr.nl_pid = 0; - addr.nl_groups = 0; - msg.msg_name = &addr; - msg.msg_namelen = sizeof (addr); - msg.msg_iov = iov; - msg.msg_iovlen = 2; - msg.msg_control = NULL; - msg.msg_controllen = 0; - msg.msg_flags = 0; - res = sendmsg (fd, &msg, 0); - if (res == -1) - return -1; - if ((size_t)res != nlm.nlmsg_len) - { - errno = EIO; - return -1; - } - return 0; -} - -static int -nl_recv (int fd, unsigned type, void *buf, size_t size) -{ - struct sockaddr_nl addr; - struct msghdr msg; - struct nlmsghdr nlm; - struct iovec iov[2]; - ssize_t res; - - again: - iov[0].iov_base = &nlm; - iov[0].iov_len = sizeof (nlm); - msg.msg_name = &addr; - msg.msg_namelen = sizeof (addr); - msg.msg_iov = iov; - msg.msg_iovlen = 1; - msg.msg_control = NULL; - msg.msg_controllen = 0; - if (type != NLMSG_ERROR) - { - res = recvmsg (fd, &msg, MSG_PEEK); - if (res == -1) - return -1; - if (res != NLMSG_LENGTH (0)) - { - errno = EIO; - return -1; - } - if (nlm.nlmsg_type == NLMSG_ERROR) - { - struct nlmsgerr err; - - iov[1].iov_base = &err; - iov[1].iov_len = sizeof (err); - msg.msg_iovlen = 2; - res = recvmsg (fd, &msg, 0); - if (res == -1) - return -1; - if ((size_t)res != NLMSG_LENGTH (sizeof (err)) - || nlm.nlmsg_type != NLMSG_ERROR) - { - errno = EIO; - return -1; - } - if (err.error == 0) - goto again; - errno = -err.error; - return -1; - } - } - if (size != 0) - { - iov[1].iov_base = buf; - iov[1].iov_len = size; - msg.msg_iovlen = 2; - } - res = recvmsg (fd, &msg, 0); - if (res == -1) - return -1; - if ((size_t)res != NLMSG_LENGTH (size) - || nlm.nlmsg_type != type) - { - errno = EIO; - return -1; - } - return 0; -} - -static int -nl_recv_ack (int fd) -{ - struct nlmsgerr err; - - if (nl_recv (fd, NLMSG_ERROR, &err, sizeof (err)) != 0) - return -1; - if (err.error != 0) - { - errno = -err.error; - return -1; - } - return 0; -} - -static void -cleanup_old_status (pam_handle_t *pamh, void *data, int error_status) -{ - (void)pamh; - (void)error_status; - free (data); -} - -int -pam_sm_open_session (pam_handle_t *pamh, int flags, int argc, const char **argv) -{ - enum command { CMD_NONE, CMD_ENABLE, CMD_DISABLE }; - - enum command command; - struct audit_tty_status *old_status, new_status; - const char *user; - int i, fd, open_only; - - (void)flags; - - if (pam_get_user (pamh, &user, NULL) != PAM_SUCCESS) - { - pam_syslog (pamh, LOG_ERR, "error determining target user's name"); - return PAM_SESSION_ERR; - } - - command = CMD_NONE; - open_only = 0; - for (i = 0; i < argc; i++) - { - if (strncmp (argv[i], "enable=", 7) == 0 - || strncmp (argv[i], "disable=", 8) == 0) - { - enum command this_command; - char *copy, *tok_data, *tok; - - this_command = *argv[i] == 'e' ? CMD_ENABLE : CMD_DISABLE; - copy = strdup (strchr (argv[i], '=') + 1); - if (copy == NULL) - return PAM_SESSION_ERR; - for (tok = strtok_r (copy, ",", &tok_data); tok != NULL; - tok = strtok_r (NULL, ",", &tok_data)) - { - if (fnmatch (tok, user, 0) == 0) - { - command = this_command; - break; - } - } - free (copy); - } - else if (strcmp (argv[i], "open_only") == 0) - open_only = 1; - else - { - pam_syslog (pamh, LOG_ERR, "unknown option `%s'", argv[i]); - return PAM_SESSION_ERR; - } - } - if (command == CMD_NONE) - return PAM_SUCCESS; - - old_status = malloc (sizeof (*old_status)); - if (old_status == NULL) - return PAM_SESSION_ERR; - - fd = nl_open (); - if (fd == -1 - || nl_send (fd, AUDIT_TTY_GET, 0, NULL, 0) != 0 - || nl_recv (fd, AUDIT_TTY_GET, old_status, sizeof (*old_status)) != 0) - { - pam_syslog (pamh, LOG_ERR, "error reading current audit status: %m"); - if (fd != -1) - close (fd); - free (old_status); - return PAM_SESSION_ERR; - } - - new_status.enabled = (command == CMD_ENABLE ? 1 : 0); - if (old_status->enabled == new_status.enabled) - { - free (old_status); - goto ok_fd; - } - - if (open_only == 0 - && pam_set_data (pamh, DATANAME, old_status, cleanup_old_status) - != PAM_SUCCESS) - { - pam_syslog (pamh, LOG_ERR, "error saving old audit status"); - close (fd); - free (old_status); - return PAM_SESSION_ERR; - } - - if (nl_send (fd, AUDIT_TTY_SET, NLM_F_ACK, &new_status, - sizeof (new_status)) != 0 - || nl_recv_ack (fd) != 0) - { - pam_syslog (pamh, LOG_ERR, "error setting current audit status: %m"); - close (fd); - if (open_only != 0) - free (old_status); - return PAM_SESSION_ERR; - } - /* Fall through */ - ok_fd: - close (fd); - pam_syslog (pamh, LOG_DEBUG, "changed status from %d to %d", - old_status->enabled, new_status.enabled); - if (open_only != 0) - free (old_status); - return PAM_SUCCESS; -} - -int -pam_sm_close_session (pam_handle_t *pamh, int flags, int argc, - const char **argv) -{ - const void *status_; - - (void)flags; - (void)argc; - (void)argv; - if (pam_get_data (pamh, DATANAME, &status_) == PAM_SUCCESS) - { - const struct audit_tty_status *status; - int fd; - - status = status_; - - fd = nl_open (); - if (fd == -1 - || nl_send (fd, AUDIT_TTY_SET, NLM_F_ACK, status, - sizeof (*status)) != 0 - || nl_recv_ack (fd) != 0) - { - pam_syslog (pamh, LOG_ERR, "error restoring audit status: %m"); - if (fd != -1) - close (fd); - return PAM_SESSION_ERR; - } - close (fd); - pam_syslog (pamh, LOG_ERR, "restored status to %d", status->enabled); - } - return PAM_SUCCESS; -} - -/* static module data */ -#ifdef PAM_STATIC -struct pam_module _pam_tty_audit_modstruct = { - "pam_tty_audit", - NULL, - NULL, - NULL, - pam_sm_open_session, - pam_sm_close_session, - NULL -}; -#endif diff --git a/modules/pam_umask/.cvsignore b/modules/pam_umask/.cvsignore deleted file mode 100644 index d53ba152..00000000 --- a/modules/pam_umask/.cvsignore +++ /dev/null @@ -1,10 +0,0 @@ -*.la -*.lo -*.so -*~ -.deps -.libs -Makefile -Makefile.in -README -pam_umask.8 diff --git a/modules/pam_umask/Makefile.am b/modules/pam_umask/Makefile.am deleted file mode 100644 index 53a666aa..00000000 --- a/modules/pam_umask/Makefile.am +++ /dev/null @@ -1,32 +0,0 @@ -# -# Copyright (c) 2005, 2006 Thorsten Kukuk <kukuk@suse.de> -# - -CLEANFILES = *~ - -EXTRA_DIST = README $(MANS) $(XMLS) tst-pam_umask - -man_MANS = pam_umask.8 - -XMLS = README.xml pam_umask.8.xml - -TESTS = tst-pam_umask - -securelibdir = $(SECUREDIR) -secureconfdir = $(SCONFIGDIR) - -AM_CFLAGS = -I$(top_srcdir)/libpam/include -I$(top_srcdir)/libpamc/include -AM_LDFLAGS = -no-undefined -avoid-version -module -if HAVE_VERSIONING - AM_LDFLAGS += -Wl,--version-script=$(srcdir)/../modules.map -endif - -securelib_LTLIBRARIES = pam_umask.la -pam_umask_la_LIBADD = -L$(top_builddir)/libpam -lpam - -if ENABLE_REGENERATE_MAN -noinst_DATA = README -README: pam_umask.8.xml --include $(top_srcdir)/Make.xml.rules -endif - diff --git a/modules/pam_umask/README.xml b/modules/pam_umask/README.xml deleted file mode 100644 index 9afbe543..00000000 --- a/modules/pam_umask/README.xml +++ /dev/null @@ -1,41 +0,0 @@ -<?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_umask.8.xml"> ---> -]> - -<article> - - <articleinfo> - - <title> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" - href="pam_umask.8.xml" xpointer='xpointer(//refnamediv[@id = "pam_umask-name"]/*)'/> - </title> - - </articleinfo> - - <section> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" - href="pam_umask.8.xml" xpointer='xpointer(//refsect1[@id = "pam_umask-description"]/*)'/> - </section> - - <section> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" - href="pam_umask.8.xml" xpointer='xpointer(//refsect1[@id = "pam_umask-options"]/*)'/> - </section> - - <section> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" - href="pam_umask.8.xml" xpointer='xpointer(//refsect1[@id = "pam_umask-examples"]/*)'/> - </section> - - <section> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" - href="pam_umask.8.xml" xpointer='xpointer(//refsect1[@id = "pam_umask-author"]/*)'/> - </section> - -</article> diff --git a/modules/pam_umask/pam_umask.8.xml b/modules/pam_umask/pam_umask.8.xml deleted file mode 100644 index d65e6660..00000000 --- a/modules/pam_umask/pam_umask.8.xml +++ /dev/null @@ -1,220 +0,0 @@ -<?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_umask"> - - <refmeta> - <refentrytitle>pam_umask</refentrytitle> - <manvolnum>8</manvolnum> - <refmiscinfo class="sectdesc">Linux-PAM Manual</refmiscinfo> - </refmeta> - - <refnamediv id="pam_umask-name"> - <refname>pam_umask</refname> - <refpurpose>PAM module to set the file mode creation mask</refpurpose> - </refnamediv> - - <refsynopsisdiv> - <cmdsynopsis id="pam_umask-cmdsynopsis"> - <command>pam_umask.so</command> - <arg choice="opt"> - debug - </arg> - <arg choice="opt"> - silent - </arg> - <arg choice="opt"> - usergroups - </arg> - <arg choice="opt"> - umask=<replaceable>mask</replaceable> - </arg> - </cmdsynopsis> - </refsynopsisdiv> - - <refsect1 id="pam_umask-description"> - - <title>DESCRIPTION</title> - - <para> - pam_umask is a PAM module to set the file mode creation mask - of the current environment. The umask affects the default - permissions assigned to newly created files. - </para> - <para> - The PAM module tries to get the umask value from the - following places in the following order: - <itemizedlist> - <listitem> - <para> - umask= argument - </para> - </listitem> - <listitem> - <para> - umask= entry of the users GECOS field - </para> - </listitem> - <listitem> - <para> - pri= entry of the users GECOS field - </para> - </listitem> - <listitem> - <para> - ulimit= entry of the users GECOS field - </para> - </listitem> - <listitem> - <para> - UMASK= entry from /etc/default/login - </para> - </listitem> - <listitem> - <para> - UMASK entry from /etc/login.defs - </para> - </listitem> - </itemizedlist> - </para> - - </refsect1> - - <refsect1 id="pam_umask-options"> - - <title>OPTIONS</title> - <para> - <variablelist> - - <varlistentry> - <term> - <option>debug</option> - </term> - <listitem> - <para> - Print debug information. - </para> - </listitem> - </varlistentry> - - <varlistentry> - <term> - <option>silent</option> - </term> - <listitem> - <para> - Don't print informative messages. - </para> - </listitem> - </varlistentry> - - <varlistentry> - <term> - <option>usergroups</option> - </term> - <listitem> - <para> - If the user is not root, and the user ID is equal to the - group ID, and the username is the same as primary group name, - the umask group bits are set to be the same as - owner bits (examples: 022 -> 002, 077 -> 007). - </para> - </listitem> - </varlistentry> - - <varlistentry> - <term> - <option>umask=<replaceable>mask</replaceable></option> - </term> - <listitem> - <para> - Sets the calling process's file mode creation mask (umask) - to <option>mask</option> & 0777. The value is interpreted - as Octal. - </para> - </listitem> - </varlistentry> - - </variablelist> - - </para> - </refsect1> - - <refsect1 id="pam_umask-services"> - <title>MODULE SERVICES PROVIDED</title> - <para> - Only the <option>session</option> service is supported. - </para> - </refsect1> - - <refsect1 id='pam_umask-return_values'> - <title>RETURN VALUES</title> - <para> - <variablelist> - - <varlistentry> - <term>PAM_SUCCESS</term> - <listitem> - <para> - The new umask was set successfull. - </para> - </listitem> - </varlistentry> - - <varlistentry> - <term>PAM_SERVICE_ERR</term> - <listitem> - <para> - No username was given. - </para> - </listitem> - </varlistentry> - - <varlistentry> - <term>PAM_USER_UNKNOWN</term> - <listitem> - <para> - User not known. - </para> - </listitem> - </varlistentry> - - </variablelist> - </para> - </refsect1> - - <refsect1 id='pam_umask-examples'> - <title>EXAMPLES</title> - <para> - Add the following line to <filename>/etc/pam.d/login</filename> to - set the user specific umask at login: - <programlisting> - session optional pam_umask.so umask=0022 - </programlisting> - </para> - </refsect1> - - <refsect1 id='pam_umask-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_umask-author'> - <title>AUTHOR</title> - <para> - pam_umask was written by Thorsten Kukuk <kukuk@thkukuk.de>. - </para> - </refsect1> - -</refentry> diff --git a/modules/pam_umask/pam_umask.c b/modules/pam_umask/pam_umask.c deleted file mode 100644 index eb88c1ac..00000000 --- a/modules/pam_umask/pam_umask.c +++ /dev/null @@ -1,319 +0,0 @@ -/* - * Copyright (c) 2005, 2006, 2007 Thorsten Kukuk <kukuk@thkukuk.de> - * - * 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 V2, 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 <pwd.h> -#include <grp.h> -#include <stdio.h> -#include <ctype.h> -#include <errno.h> -#include <limits.h> -#include <string.h> -#include <stdarg.h> -#include <unistd.h> -#include <stdlib.h> -#include <sys/stat.h> -#include <sys/types.h> -#include <sys/resource.h> -#include <syslog.h> - -#define PAM_SM_SESSION - -#include <security/pam_modules.h> -#include <security/pam_modutil.h> -#include <security/pam_ext.h> - -#define BUF_SIZE 4096 -#define LOGIN_DEFS "/etc/login.defs" -#define LOGIN_CONF "/etc/default/login" - -struct options_t { - int debug; - int usergroups; - int silent; - char *umask; -}; -typedef struct options_t options_t; - -static void -parse_option (const pam_handle_t *pamh, const char *argv, options_t *options) -{ - if (argv == NULL || argv[0] == '\0') - return; - - if (strcasecmp (argv, "debug") == 0) - options->debug = 1; - else if (strncasecmp (argv, "umask=", 6) == 0) - options->umask = strdup (&argv[6]); - else if (strcasecmp (argv, "usergroups") == 0) - options->usergroups = 1; - else if (strcasecmp (argv, "silent") == 0) - options->silent = 1; - else - pam_syslog (pamh, LOG_ERR, "Unknown option: `%s'", argv); -} - -static char * -search_key (const char *filename) -{ - FILE *fp; - char *buf = NULL; - size_t buflen = 0; - char *retval = NULL; - - fp = fopen (filename, "r"); - if (NULL == fp) - return NULL; - - while (!feof (fp)) - { - char *tmp, *cp; -#if defined(HAVE_GETLINE) - ssize_t n = getline (&buf, &buflen, fp); -#elif defined (HAVE_GETDELIM) - ssize_t n = getdelim (&buf, &buflen, '\n', fp); -#else - ssize_t n; - - if (buf == NULL) - { - buflen = BUF_SIZE; - buf = malloc (buflen); - } - buf[0] = '\0'; - if (fgets (buf, buflen - 1, fp) == NULL) - break; - else if (buf != NULL) - n = strlen (buf); - else - n = 0; -#endif /* HAVE_GETLINE / HAVE_GETDELIM */ - cp = buf; - - if (n < 1) - break; - - tmp = strchr (cp, '#'); /* remove comments */ - if (tmp) - *tmp = '\0'; - while (isspace ((int)*cp)) /* remove spaces and tabs */ - ++cp; - if (*cp == '\0') /* ignore empty lines */ - continue; - - if (cp[strlen (cp) - 1] == '\n') - cp[strlen (cp) - 1] = '\0'; - - tmp = strsep (&cp, " \t="); - if (cp != NULL) - while (isspace ((int)*cp) || *cp == '=') - ++cp; - - if (strcasecmp (tmp, "UMASK") == 0) - { - retval = strdup (cp); - break; - } - } - fclose (fp); - - free (buf); - - return retval; -} - -static int -get_options (const pam_handle_t *pamh, options_t *options, - int argc, const char **argv) -{ - memset (options, 0, sizeof (options_t)); - /* Parse parameters for module */ - for ( ; argc-- > 0; argv++) - parse_option (pamh, *argv, options); - - if (options->umask == NULL) - options->umask = search_key (LOGIN_DEFS); - if (options->umask == NULL) - options->umask = search_key (LOGIN_CONF); - - return 0; -} - -static void -set_umask (const char *value) -{ - const char *value_orig = value; - mode_t mask; - char *endptr; - - mask = strtoul (value, &endptr, 8) & 0777; - if (((mask == 0) && (value_orig == endptr)) || - ((mask == UINT_MAX) && (errno == ERANGE))) - return; - umask (mask); - return; -} - -/* Set the process nice, ulimit, and umask from the - password file entry. */ -static void -setup_limits_from_gecos (pam_handle_t *pamh, options_t *options, - struct passwd *pw) -{ - char *cp; - - if (options->usergroups) - { - /* if not root, and UID == GID, and username is the same as - primary group name, set umask group bits to be the same as - owner bits (examples: 022 -> 002, 077 -> 007). */ - if (pw->pw_uid != 0 && pw->pw_uid == pw->pw_gid) - { - struct group *grp = pam_modutil_getgrgid (pamh, pw->pw_gid); - if (grp && (strcmp (pw->pw_name, grp->gr_name) == 0)) - { - mode_t oldmask = umask (0777); - umask ((oldmask & ~070) | ((oldmask >> 3) & 070)); - } - } - } - - /* See if the GECOS field contains values for NICE, UMASK or ULIMIT. */ - for (cp = pw->pw_gecos; cp != NULL; cp = strchr (cp, ',')) - { - if (*cp == ',') - cp++; - - if (strncasecmp (cp, "umask=", 6) == 0) - umask (strtol (cp + 6, NULL, 8) & 0777); - else if (strncasecmp (cp, "pri=", 4) == 0) - { - errno = 0; - if (nice (strtol (cp + 4, NULL, 10)) == -1 && errno != 0) - { - if (!options->silent || options->debug) - pam_error (pamh, "nice failed: %m\n"); - pam_syslog (pamh, LOG_ERR, "nice failed: %m"); - } - } - else if (strncasecmp (cp, "ulimit=", 7) == 0) - { - struct rlimit rlimit_fsize; - rlimit_fsize.rlim_cur = 512L * strtol (cp + 7, NULL, 10); - rlimit_fsize.rlim_max = rlimit_fsize.rlim_cur; - if (setrlimit (RLIMIT_FSIZE, &rlimit_fsize) == -1) - { - if (!options->silent || options->debug) - pam_error (pamh, "setrlimit failed: %m\n"); - pam_syslog (pamh, LOG_ERR, "setrlimit failed: %m"); - } - } - } -} - - -PAM_EXTERN int -pam_sm_open_session (pam_handle_t *pamh, int flags UNUSED, - int argc, const char **argv) -{ - struct passwd *pw; - options_t options; - const char *name; - int retval = PAM_SUCCESS; - - get_options (pamh, &options, argc, argv); - if (flags & PAM_SILENT) - options.silent = 1; - - /* get the user name. */ - if ((retval = pam_get_user (pamh, &name, NULL)) != PAM_SUCCESS) - { - pam_syslog (pamh, LOG_ERR, "pam_get_user failed: return %d", retval); - return (retval == PAM_CONV_AGAIN ? PAM_INCOMPLETE:retval); - } - - if (name == NULL || name[0] == '\0') - { - if (name) - { - pam_syslog (pamh, LOG_ERR, "bad username [%s]", name); - return PAM_USER_UNKNOWN; - } - return PAM_SERVICE_ERR; - } - - pw = pam_modutil_getpwnam (pamh, name); - if (pw == NULL) - { - pam_syslog (pamh, LOG_ERR, "account for %s not found", name); - return PAM_USER_UNKNOWN; - } - - if (options.umask != NULL) - { - set_umask (options.umask); - free (options.umask); - } - - setup_limits_from_gecos (pamh, &options, pw); - - return retval; -} - -PAM_EXTERN int -pam_sm_close_session (pam_handle_t *pamh UNUSED, int flags UNUSED, - int argc UNUSED, const char **argv UNUSED) -{ - return PAM_SUCCESS; -} - -#ifdef PAM_STATIC - -/* static module data */ - -struct pam_module _pam_umask_modstruct = { - "pam_umask", - NULL, - NULL, - NULL, - pam_sm_open_session, - pam_sm_close_session, - NULL -}; - -#endif - -/* end of module definition */ diff --git a/modules/pam_umask/tst-pam_umask b/modules/pam_umask/tst-pam_umask deleted file mode 100755 index 3608a9de..00000000 --- a/modules/pam_umask/tst-pam_umask +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/sh -../../tests/tst-dlopen .libs/pam_umask.so diff --git a/modules/pam_unix/.cvsignore b/modules/pam_unix/.cvsignore deleted file mode 100644 index 01819c28..00000000 --- a/modules/pam_unix/.cvsignore +++ /dev/null @@ -1,14 +0,0 @@ -*.la -*.lo -*.so -.deps -.libs -Makefile -Makefile.in -bigcrypt -unix_chkpwd -unix_update -README -pam_unix.8 -unix_chkpwd.8 -unix_update.8 diff --git a/modules/pam_unix/CHANGELOG b/modules/pam_unix/CHANGELOG deleted file mode 100644 index 1476b579..00000000 --- a/modules/pam_unix/CHANGELOG +++ /dev/null @@ -1,55 +0,0 @@ -$Id$ - -* Mon Aug 16 1999 Jan Rêkorajski <baggins@pld.org.pl> -- fixed reentrancy problems - -* Sun Jul 4 21:03:42 PDT 1999 - -- temporarily removed the crypt16 stuff. I'm really paranoid about - crypto stuff and exporting it, and there are a few too many 's-box' - references in the code for my liking.. - -* Wed Jun 30 1999 Steve Langasek <vorlon@netexpress.net> -- further NIS+ fixes - -* Sun Jun 27 1999 Steve Langasek <vorlon@netexpress.net> -- fix to uid-handling code for NIS+ - -* Sat Jun 26 1999 Jan Rêkorajski <baggins@mimuw.edu.pl> -- merged MD5 fix and early failure syslog - by Andrey Vladimirovich Savochkin <saw@msu.ru> -- minor fixes -- added signal handler to unix_chkpwd - -* Fri Jun 25 1999 Stephen Langasek <vorlon@netexpress.net> -- reorganized the code to let it build as separate C files - -* Sun Jun 20 1999 Jan Rêkorajski <baggins@mimuw.edu.pl> -- fixes in pam_unix_auth, it incorrectly saved and restored return - value when likeauth option was used - -* Tue Jun 15 1999 Jan Rêkorajski <baggins@mimuw.edu.pl> -- added NIS+ support - -* Mon Jun 14 1999 Jan Rêkorajski <baggins@mimuw.edu.pl> -- total rewrite based on pam_pwdb module, now there is ONE pam_unix.so - module, it accepts the same options as pam_pwdb - all of them correctly ;) - (pam_pwdb dosn't understand what DISALLOW_NULL_AUTHTOK means) - -* Tue Apr 20 1999 Jan Rêkorajski <baggins@mimuw.edu.pl> -- Arghhh, pam_unix_passwd was not updating /etc/shadow when used with - pam_cracklib. - -* Mon Apr 19 1999 Jan Rêkorajski <baggins@mimuw.edu.pl> -- added "remember=XXX" option that means 'remember XXX old passwords' - Old passwords are stored in /etc/security/opasswd, there can be - maximum of 400 passwords per user. - -* Sat Mar 27 1999 Jan Rêkorajski <baggins@mimuw.edu.pl> -- added crypt16 to pam_unix_auth and pam_unix_passwd (check only, this algorithm - is too lame to use it in real life) - -* Sun Mar 21 1999 Jan Rêkorajski <baggins@mimuw.edu.pl> -- pam_unix_auth now correctly behave when user has NULL AUTHTOK -- pam_unix_auth returns PAM_PERM_DENIED when seteuid fails - diff --git a/modules/pam_unix/Makefile.am b/modules/pam_unix/Makefile.am deleted file mode 100644 index 4d2c58b8..00000000 --- a/modules/pam_unix/Makefile.am +++ /dev/null @@ -1,69 +0,0 @@ -# -# Copyright (c) 2005, 2006 Thorsten Kukuk <kukuk@suse.de> -# - -CLEANFILES = *~ - -EXTRA_DIST = README md5.c md5_crypt.c lckpwdf.-c $(MANS) CHANGELOG \ - tst-pam_unix $(XMLS) - -man_MANS = pam_unix.8 unix_chkpwd.8 unix_update.8 -XMLS = README.xml pam_unix.8.xml unix_chkpwd.8.xml unix_update.8.xml - -TESTS = tst-pam_unix - -securelibdir = $(SECUREDIR) -secureconfdir = $(SCONFIGDIR) - -AM_CFLAGS = -I$(top_srcdir)/libpam/include -I$(top_srcdir)/libpamc/include \ - -DCHKPWD_HELPER=\"$(sbindir)/unix_chkpwd\" \ - -DUPDATE_HELPER=\"$(sbindir)/unix_update\" - -if HAVE_LIBSELINUX - AM_CFLAGS += -D"WITH_SELINUX" -endif -if HAVE_LIBCRACK - AM_CFLAGS += -D"USE_CRACKLIB" -endif - -pam_unix_la_LDFLAGS = -no-undefined -avoid-version -module -if HAVE_VERSIONING - pam_unix_la_LDFLAGS += -Wl,--version-script=$(srcdir)/../modules.map -endif -pam_unix_la_LIBADD = @LIBCRACK@ @LIBNSL@ -L$(top_builddir)/libpam -lpam \ - @LIBCRYPT@ @LIBSELINUX@ - -securelib_LTLIBRARIES = pam_unix.la - -noinst_HEADERS = md5.h support.h yppasswd.h bigcrypt.h passverify.h - -sbin_PROGRAMS = unix_chkpwd unix_update - -noinst_PROGRAMS = bigcrypt - -pam_unix_la_SOURCES = bigcrypt.c pam_unix_acct.c \ - pam_unix_auth.c pam_unix_passwd.c pam_unix_sess.c support.c \ - passverify.c yppasswd_xdr.c md5_good.c md5_broken.c - -bigcrypt_SOURCES = bigcrypt.c bigcrypt_main.c -bigcrypt_CFLAGS = $(AM_CFLAGS) -bigcrypt_LDADD = @LIBCRYPT@ - -unix_chkpwd_SOURCES = unix_chkpwd.c md5_good.c md5_broken.c bigcrypt.c \ - passverify.c -unix_chkpwd_CFLAGS = $(AM_CFLAGS) @PIE_CFLAGS@ -DHELPER_COMPILE=\"unix_chkpwd\" -unix_chkpwd_LDFLAGS = @PIE_LDFLAGS@ -unix_chkpwd_LDADD = @LIBCRYPT@ @LIBSELINUX@ - -unix_update_SOURCES = unix_update.c md5_good.c md5_broken.c bigcrypt.c \ - passverify.c -unix_update_CFLAGS = $(AM_CFLAGS) @PIE_CFLAGS@ -DHELPER_COMPILE=\"unix_update\" -unix_update_LDFLAGS = @PIE_LDFLAGS@ -unix_update_LDADD = @LIBCRYPT@ @LIBSELINUX@ - -if ENABLE_REGENERATE_MAN -noinst_DATA = README -README: pam_unix.8.xml --include $(top_srcdir)/Make.xml.rules -endif - diff --git a/modules/pam_unix/README.xml b/modules/pam_unix/README.xml deleted file mode 100644 index 7fd340b3..00000000 --- a/modules/pam_unix/README.xml +++ /dev/null @@ -1,41 +0,0 @@ -<?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_unix.8.xml"> ---> -]> - -<article> - - <articleinfo> - - <title> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" - href="pam_unix.8.xml" xpointer='xpointer(//refnamediv[@id = "pam_unix-name"]/*)'/> - </title> - - </articleinfo> - - <section> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" - href="pam_unix.8.xml" xpointer='xpointer(//refsect1[@id = "pam_unix-description"]/*)'/> - </section> - - <section> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" - href="pam_unix.8.xml" xpointer='xpointer(//refsect1[@id = "pam_unix-options"]/*)'/> - </section> - - <section> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" - href="pam_unix.8.xml" xpointer='xpointer(//refsect1[@id = "pam_unix-examples"]/*)'/> - </section> - - <section> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" - href="pam_unix.8.xml" xpointer='xpointer(//refsect1[@id = "pam_unix-author"]/*)'/> - </section> - -</article> diff --git a/modules/pam_unix/bigcrypt.c b/modules/pam_unix/bigcrypt.c deleted file mode 100644 index 9cd55384..00000000 --- a/modules/pam_unix/bigcrypt.c +++ /dev/null @@ -1,148 +0,0 @@ -/* - * This function implements the "bigcrypt" algorithm specifically for - * Linux-PAM. - * - * This algorithm is algorithm 0 (default) shipped with the C2 secure - * implementation of Digital UNIX. - * - * Disclaimer: This work is not based on the source code to Digital - * UNIX, nor am I connected to Digital Equipment Corp, in any way - * other than as a customer. This code is based on published - * interfaces and reasonable guesswork. - * - * Description: The cleartext is divided into blocks of SEGMENT_SIZE=8 - * characters or less. Each block is encrypted using the standard UNIX - * libc crypt function. The result of the encryption for one block - * provides the salt for the suceeding block. - * - * Restrictions: The buffer used to hold the encrypted result is - * statically allocated. (see MAX_PASS_LEN below). This is necessary, - * as the returned pointer points to "static data that are overwritten - * by each call", (XPG3: XSI System Interface + Headers pg 109), and - * this is a drop in replacement for crypt(); - * - * Andy Phillips <atp@mssl.ucl.ac.uk> - */ - -#include "config.h" - -#include <string.h> -#include <stdlib.h> -#include <security/_pam_macros.h> -#ifdef HAVE_CRYPT_H -#include <crypt.h> -#endif - -#include "bigcrypt.h" - -/* - * Max cleartext password length in segments of 8 characters this - * function can deal with (16 segments of 8 chars= max 128 character - * password). - */ - -#define MAX_PASS_LEN 16 -#define SEGMENT_SIZE 8 -#define SALT_SIZE 2 -#define KEYBUF_SIZE ((MAX_PASS_LEN*SEGMENT_SIZE)+SALT_SIZE) -#define ESEGMENT_SIZE 11 -#define CBUF_SIZE ((MAX_PASS_LEN*ESEGMENT_SIZE)+SALT_SIZE+1) - -char *bigcrypt(const char *key, const char *salt) -{ - char *dec_c2_cryptbuf; -#ifdef HAVE_CRYPT_R - struct crypt_data *cdata; -#endif - unsigned long int keylen, n_seg, j; - char *cipher_ptr, *plaintext_ptr, *tmp_ptr, *salt_ptr; - char keybuf[KEYBUF_SIZE + 1]; - - D(("called with key='%s', salt='%s'.", key, salt)); - - /* reset arrays */ - dec_c2_cryptbuf = malloc(CBUF_SIZE); - if (!dec_c2_cryptbuf) { - return NULL; - } -#ifdef HAVE_CRYPT_R - cdata = malloc(sizeof(*cdata)); - if(!cdata) { - free(dec_c2_cryptbuf); - return NULL; - } - cdata->initialized = 0; -#endif - memset(keybuf, 0, KEYBUF_SIZE + 1); - memset(dec_c2_cryptbuf, 0, CBUF_SIZE); - - /* fill KEYBUF_SIZE with key */ - strncpy(keybuf, key, KEYBUF_SIZE); - - /* deal with case that we are doing a password check for a - conventially encrypted password: the salt will be - SALT_SIZE+ESEGMENT_SIZE long. */ - if (strlen(salt) == (SALT_SIZE + ESEGMENT_SIZE)) - keybuf[SEGMENT_SIZE] = '\0'; /* terminate password early(?) */ - - keylen = strlen(keybuf); - - if (!keylen) { - n_seg = 1; - } else { - /* work out how many segments */ - n_seg = 1 + ((keylen - 1) / SEGMENT_SIZE); - } - - if (n_seg > MAX_PASS_LEN) - n_seg = MAX_PASS_LEN; /* truncate at max length */ - - /* set up some pointers */ - cipher_ptr = dec_c2_cryptbuf; - plaintext_ptr = keybuf; - - /* do the first block with supplied salt */ -#ifdef HAVE_CRYPT_R - tmp_ptr = crypt_r(plaintext_ptr, salt, cdata); /* libc crypt_r() */ -#else - tmp_ptr = crypt(plaintext_ptr, salt); /* libc crypt() */ -#endif - /* and place in the static area */ - strncpy(cipher_ptr, tmp_ptr, 13); - cipher_ptr += ESEGMENT_SIZE + SALT_SIZE; - plaintext_ptr += SEGMENT_SIZE; /* first block of SEGMENT_SIZE */ - - /* change the salt (1st 2 chars of previous block) - this was found - by dowsing */ - - salt_ptr = cipher_ptr - ESEGMENT_SIZE; - - /* so far this is identical to "return crypt(key, salt);", if - there is more than one block encrypt them... */ - - if (n_seg > 1) { - for (j = 2; j <= n_seg; j++) { - -#ifdef HAVE_CRYPT_R - tmp_ptr = crypt_r(plaintext_ptr, salt_ptr, cdata); -#else - tmp_ptr = crypt(plaintext_ptr, salt_ptr); -#endif - - /* skip the salt for seg!=0 */ - strncpy(cipher_ptr, (tmp_ptr + SALT_SIZE), ESEGMENT_SIZE); - - cipher_ptr += ESEGMENT_SIZE; - plaintext_ptr += SEGMENT_SIZE; - salt_ptr = cipher_ptr - ESEGMENT_SIZE; - } - } - D(("key=|%s|, salt=|%s|\nbuf=|%s|\n", key, salt, dec_c2_cryptbuf)); - -#ifdef HAVE_CRYPT_R - free(cdata); -#endif - - /* this is the <NUL> terminated encrypted password */ - return dec_c2_cryptbuf; -} diff --git a/modules/pam_unix/bigcrypt.h b/modules/pam_unix/bigcrypt.h deleted file mode 100644 index a66a96e6..00000000 --- a/modules/pam_unix/bigcrypt.h +++ /dev/null @@ -1 +0,0 @@ -extern char *bigcrypt(const char *key, const char *salt); diff --git a/modules/pam_unix/bigcrypt_main.c b/modules/pam_unix/bigcrypt_main.c deleted file mode 100644 index fab212d9..00000000 --- a/modules/pam_unix/bigcrypt_main.c +++ /dev/null @@ -1,18 +0,0 @@ -#include <stdio.h> -#include <string.h> - -#include "bigcrypt.h" - -int -main(int argc, char **argv) -{ - if (argc < 3) { - fprintf(stderr, "Usage: %s password salt\n", - strchr(argv[0], '/') ? - (strchr(argv[0], '/') + 1) : - argv[0]); - return 0; - } - fprintf(stdout, "%s\n", bigcrypt(argv[1], argv[2])); - return 0; -} diff --git a/modules/pam_unix/lckpwdf.-c b/modules/pam_unix/lckpwdf.-c deleted file mode 100644 index 7145617e..00000000 --- a/modules/pam_unix/lckpwdf.-c +++ /dev/null @@ -1,142 +0,0 @@ -/* - * This is a hack, but until libc and glibc both include this function - * by default (libc only includes it if nys is not being used, at the - * moment, and glibc doesn't appear to have it at all) we need to have - * it here, too. :-( - * - * This should not become an official part of PAM. - * - * BEGIN_HACK - */ - -/* - * lckpwdf.c -- prevent simultaneous updates of password files - * - * Before modifying any of the password files, call lckpwdf(). It may block - * for up to 15 seconds trying to get the lock. Return value is 0 on success - * or -1 on failure. When you are done, call ulckpwdf() to release the lock. - * The lock is also released automatically when the process exits. Only one - * process at a time may hold the lock. - * - * These functions are supposed to be conformant with AT&T SVID Issue 3. - * - * Written by Marek Michalkiewicz <marekm@i17linuxb.ists.pwr.wroc.pl>, - * public domain. - */ - -#include <fcntl.h> -#include <signal.h> -#ifdef WITH_SELINUX -#include <selinux/selinux.h> -#endif - -#define LOCKFILE "/etc/.pwd.lock" -#define TIMEOUT 15 - -static int lockfd = -1; - -static int set_close_on_exec(int fd) -{ - int flags = fcntl(fd, F_GETFD, 0); - if (flags == -1) - return -1; - flags |= FD_CLOEXEC; - return fcntl(fd, F_SETFD, flags); -} - -static int do_lock(int fd) -{ - struct flock fl; - - memset(&fl, 0, sizeof fl); - fl.l_type = F_WRLCK; - fl.l_whence = SEEK_SET; - return fcntl(fd, F_SETLKW, &fl); -} - -static void alarm_catch(int sig) -{ -/* does nothing, but fcntl F_SETLKW will fail with EINTR */ -} - -static int lckpwdf(void) -{ - struct sigaction act, oldact; - sigset_t set, oldset; - - if (lockfd != -1) - return -1; - -#ifdef WITH_SELINUX - if(is_selinux_enabled()>0) - { - lockfd = open(LOCKFILE, O_WRONLY); - if(lockfd == -1 && errno == ENOENT) - { - security_context_t create_context; - int rc; - - if(getfilecon("/etc/passwd", &create_context)) - return -1; - rc = setfscreatecon(create_context); - freecon(create_context); - if(rc) - return -1; - lockfd = open(LOCKFILE, O_CREAT | O_WRONLY, 0600); - if(setfscreatecon(NULL)) - return -1; - } - } - else -#endif - lockfd = open(LOCKFILE, O_CREAT | O_WRONLY, 0600); - if (lockfd == -1) - return -1; - if (set_close_on_exec(lockfd) == -1) - goto cleanup_fd; - - memset(&act, 0, sizeof act); - act.sa_handler = alarm_catch; - act.sa_flags = 0; - sigfillset(&act.sa_mask); - if (sigaction(SIGALRM, &act, &oldact) == -1) - goto cleanup_fd; - - sigemptyset(&set); - sigaddset(&set, SIGALRM); - if (sigprocmask(SIG_UNBLOCK, &set, &oldset) == -1) - goto cleanup_sig; - - alarm(TIMEOUT); - if (do_lock(lockfd) == -1) - goto cleanup_alarm; - alarm(0); - sigprocmask(SIG_SETMASK, &oldset, NULL); - sigaction(SIGALRM, &oldact, NULL); - return 0; - - cleanup_alarm: - alarm(0); - sigprocmask(SIG_SETMASK, &oldset, NULL); - cleanup_sig: - sigaction(SIGALRM, &oldact, NULL); - cleanup_fd: - close(lockfd); - lockfd = -1; - return -1; -} - -static int ulckpwdf(void) -{ - unlink(LOCKFILE); - if (lockfd == -1) - return -1; - - if (close(lockfd) == -1) { - lockfd = -1; - return -1; - } - lockfd = -1; - return 0; -} -/* END_HACK */ diff --git a/modules/pam_unix/md5.c b/modules/pam_unix/md5.c deleted file mode 100644 index d88d6810..00000000 --- a/modules/pam_unix/md5.c +++ /dev/null @@ -1,256 +0,0 @@ -/* - * $Id$ - * - * This code implements the MD5 message-digest algorithm. - * The algorithm is due to Ron Rivest. This code was - * written by Colin Plumb in 1993, no copyright is claimed. - * This code is in the public domain; do with it what you wish. - * - * Equivalent code is available from RSA Data Security, Inc. - * This code has been tested against that, and is equivalent, - * except that you don't need to include two pages of legalese - * with every copy. - * - * To compute the message digest of a chunk of bytes, declare an - * MD5Context structure, pass it to MD5Init, call MD5Update as - * needed on buffers full of bytes, and then call MD5Final, which - * will fill a supplied 16-byte array with the digest. - * - */ - -#include <string.h> -#include "md5.h" - -#ifndef HIGHFIRST -#define byteReverse(buf, len) /* Nothing */ -#else -static void byteReverse(unsigned char *buf, unsigned longs); - -#ifndef ASM_MD5 -/* - * Note: this code is harmless on little-endian machines. - */ -static void byteReverse(unsigned char *buf, unsigned longs) -{ - uint32 t; - do { - t = (uint32) ((unsigned) buf[3] << 8 | buf[2]) << 16 | - ((unsigned) buf[1] << 8 | buf[0]); - *(uint32 *) buf = t; - buf += 4; - } while (--longs); -} -#endif -#endif - -/* - * Start MD5 accumulation. Set bit count to 0 and buffer to mysterious - * initialization constants. - */ -void MD5Name(MD5Init)(struct MD5Context *ctx) -{ - ctx->buf[0] = 0x67452301U; - ctx->buf[1] = 0xefcdab89U; - ctx->buf[2] = 0x98badcfeU; - ctx->buf[3] = 0x10325476U; - - ctx->bits[0] = 0; - ctx->bits[1] = 0; -} - -/* - * Update context to reflect the concatenation of another buffer full - * of bytes. - */ -void MD5Name(MD5Update)(struct MD5Context *ctx, unsigned const char *buf, unsigned len) -{ - uint32 t; - - /* Update bitcount */ - - t = ctx->bits[0]; - if ((ctx->bits[0] = t + ((uint32) len << 3)) < t) - ctx->bits[1]++; /* Carry from low to high */ - ctx->bits[1] += len >> 29; - - t = (t >> 3) & 0x3f; /* Bytes already in shsInfo->data */ - - /* Handle any leading odd-sized chunks */ - - if (t) { - unsigned char *p = (unsigned char *) ctx->in + t; - - t = 64 - t; - if (len < t) { - memcpy(p, buf, len); - return; - } - memcpy(p, buf, t); - byteReverse(ctx->in, 16); - MD5Name(MD5Transform)(ctx->buf, (uint32 *) ctx->in); - buf += t; - len -= t; - } - /* Process data in 64-byte chunks */ - - while (len >= 64) { - memcpy(ctx->in, buf, 64); - byteReverse(ctx->in, 16); - MD5Name(MD5Transform)(ctx->buf, (uint32 *) ctx->in); - buf += 64; - len -= 64; - } - - /* Handle any remaining bytes of data. */ - - memcpy(ctx->in, buf, len); -} - -/* - * Final wrapup - pad to 64-byte boundary with the bit pattern - * 1 0* (64-bit count of bits processed, MSB-first) - */ -void MD5Name(MD5Final)(unsigned char digest[16], struct MD5Context *ctx) -{ - unsigned count; - unsigned char *p; - - /* Compute number of bytes mod 64 */ - count = (ctx->bits[0] >> 3) & 0x3F; - - /* Set the first char of padding to 0x80. This is safe since there is - always at least one byte free */ - p = ctx->in + count; - *p++ = 0x80; - - /* Bytes of padding needed to make 64 bytes */ - count = 64 - 1 - count; - - /* Pad out to 56 mod 64 */ - if (count < 8) { - /* Two lots of padding: Pad the first block to 64 bytes */ - memset(p, 0, count); - byteReverse(ctx->in, 16); - MD5Name(MD5Transform)(ctx->buf, (uint32 *) ctx->in); - - /* Now fill the next block with 56 bytes */ - memset(ctx->in, 0, 56); - } else { - /* Pad block to 56 bytes */ - memset(p, 0, count - 8); - } - byteReverse(ctx->in, 14); - - /* Append length in bits and transform */ - ((uint32 *) ctx->in)[14] = ctx->bits[0]; - ((uint32 *) ctx->in)[15] = ctx->bits[1]; - - MD5Name(MD5Transform)(ctx->buf, (uint32 *) ctx->in); - byteReverse((unsigned char *) ctx->buf, 4); - memcpy(digest, ctx->buf, 16); - memset(ctx, 0, sizeof(ctx)); /* In case it's sensitive */ -} - -#ifndef ASM_MD5 - -/* The four core functions - F1 is optimized somewhat */ - -/* #define F1(x, y, z) (x & y | ~x & z) */ -#define F1(x, y, z) (z ^ (x & (y ^ z))) -#define F2(x, y, z) F1(z, x, y) -#define F3(x, y, z) (x ^ y ^ z) -#define F4(x, y, z) (y ^ (x | ~z)) - -/* This is the central step in the MD5 algorithm. */ -#define MD5STEP(f, w, x, y, z, data, s) \ - ( w += f(x, y, z) + data, w = w<<s | w>>(32-s), w += x ) - -/* - * The core of the MD5 algorithm, this alters an existing MD5 hash to - * reflect the addition of 16 longwords of new data. MD5Update blocks - * the data and converts bytes into longwords for this routine. - */ -void MD5Name(MD5Transform)(uint32 buf[4], uint32 const in[16]) -{ - register uint32 a, b, c, d; - - a = buf[0]; - b = buf[1]; - c = buf[2]; - d = buf[3]; - - MD5STEP(F1, a, b, c, d, in[0] + 0xd76aa478U, 7); - MD5STEP(F1, d, a, b, c, in[1] + 0xe8c7b756U, 12); - MD5STEP(F1, c, d, a, b, in[2] + 0x242070dbU, 17); - MD5STEP(F1, b, c, d, a, in[3] + 0xc1bdceeeU, 22); - MD5STEP(F1, a, b, c, d, in[4] + 0xf57c0fafU, 7); - MD5STEP(F1, d, a, b, c, in[5] + 0x4787c62aU, 12); - MD5STEP(F1, c, d, a, b, in[6] + 0xa8304613U, 17); - MD5STEP(F1, b, c, d, a, in[7] + 0xfd469501U, 22); - MD5STEP(F1, a, b, c, d, in[8] + 0x698098d8U, 7); - MD5STEP(F1, d, a, b, c, in[9] + 0x8b44f7afU, 12); - MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1U, 17); - MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7beU, 22); - MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122U, 7); - MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193U, 12); - MD5STEP(F1, c, d, a, b, in[14] + 0xa679438eU, 17); - MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821U, 22); - - MD5STEP(F2, a, b, c, d, in[1] + 0xf61e2562U, 5); - MD5STEP(F2, d, a, b, c, in[6] + 0xc040b340U, 9); - MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51U, 14); - MD5STEP(F2, b, c, d, a, in[0] + 0xe9b6c7aaU, 20); - MD5STEP(F2, a, b, c, d, in[5] + 0xd62f105dU, 5); - MD5STEP(F2, d, a, b, c, in[10] + 0x02441453U, 9); - MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681U, 14); - MD5STEP(F2, b, c, d, a, in[4] + 0xe7d3fbc8U, 20); - MD5STEP(F2, a, b, c, d, in[9] + 0x21e1cde6U, 5); - MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6U, 9); - MD5STEP(F2, c, d, a, b, in[3] + 0xf4d50d87U, 14); - MD5STEP(F2, b, c, d, a, in[8] + 0x455a14edU, 20); - MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905U, 5); - MD5STEP(F2, d, a, b, c, in[2] + 0xfcefa3f8U, 9); - MD5STEP(F2, c, d, a, b, in[7] + 0x676f02d9U, 14); - MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8aU, 20); - - MD5STEP(F3, a, b, c, d, in[5] + 0xfffa3942U, 4); - MD5STEP(F3, d, a, b, c, in[8] + 0x8771f681U, 11); - MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122U, 16); - MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380cU, 23); - MD5STEP(F3, a, b, c, d, in[1] + 0xa4beea44U, 4); - MD5STEP(F3, d, a, b, c, in[4] + 0x4bdecfa9U, 11); - MD5STEP(F3, c, d, a, b, in[7] + 0xf6bb4b60U, 16); - MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70U, 23); - MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6U, 4); - MD5STEP(F3, d, a, b, c, in[0] + 0xeaa127faU, 11); - MD5STEP(F3, c, d, a, b, in[3] + 0xd4ef3085U, 16); - MD5STEP(F3, b, c, d, a, in[6] + 0x04881d05U, 23); - MD5STEP(F3, a, b, c, d, in[9] + 0xd9d4d039U, 4); - MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5U, 11); - MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8U, 16); - MD5STEP(F3, b, c, d, a, in[2] + 0xc4ac5665U, 23); - - MD5STEP(F4, a, b, c, d, in[0] + 0xf4292244U, 6); - MD5STEP(F4, d, a, b, c, in[7] + 0x432aff97U, 10); - MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7U, 15); - MD5STEP(F4, b, c, d, a, in[5] + 0xfc93a039U, 21); - MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3U, 6); - MD5STEP(F4, d, a, b, c, in[3] + 0x8f0ccc92U, 10); - MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47dU, 15); - MD5STEP(F4, b, c, d, a, in[1] + 0x85845dd1U, 21); - MD5STEP(F4, a, b, c, d, in[8] + 0x6fa87e4fU, 6); - MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0U, 10); - MD5STEP(F4, c, d, a, b, in[6] + 0xa3014314U, 15); - MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1U, 21); - MD5STEP(F4, a, b, c, d, in[4] + 0xf7537e82U, 6); - MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235U, 10); - MD5STEP(F4, c, d, a, b, in[2] + 0x2ad7d2bbU, 15); - MD5STEP(F4, b, c, d, a, in[9] + 0xeb86d391U, 21); - - buf[0] += a; - buf[1] += b; - buf[2] += c; - buf[3] += d; -} - -#endif diff --git a/modules/pam_unix/md5.h b/modules/pam_unix/md5.h deleted file mode 100644 index 103f168a..00000000 --- a/modules/pam_unix/md5.h +++ /dev/null @@ -1,31 +0,0 @@ - -#ifndef MD5_H -#define MD5_H - -typedef unsigned int uint32; - -struct MD5Context { - uint32 buf[4]; - uint32 bits[2]; - unsigned char in[64]; -}; - -void GoodMD5Init(struct MD5Context *); -void GoodMD5Update(struct MD5Context *, unsigned const char *, unsigned); -void GoodMD5Final(unsigned char digest[16], struct MD5Context *); -void GoodMD5Transform(uint32 buf[4], uint32 const in[16]); -void BrokenMD5Init(struct MD5Context *); -void BrokenMD5Update(struct MD5Context *, unsigned const char *, unsigned); -void BrokenMD5Final(unsigned char digest[16], struct MD5Context *); -void BrokenMD5Transform(uint32 buf[4], uint32 const in[16]); - -char *Goodcrypt_md5(const char *pw, const char *salt); -char *Brokencrypt_md5(const char *pw, const char *salt); - -/* - * This is needed to make RSAREF happy on some MS-DOS compilers. - */ - -typedef struct MD5Context MD5_CTX; - -#endif /* MD5_H */ diff --git a/modules/pam_unix/md5_broken.c b/modules/pam_unix/md5_broken.c deleted file mode 100644 index 193daebb..00000000 --- a/modules/pam_unix/md5_broken.c +++ /dev/null @@ -1,4 +0,0 @@ -#define MD5Name(x) Broken##x - -#include "md5.c" -#include "md5_crypt.c" diff --git a/modules/pam_unix/md5_crypt.c b/modules/pam_unix/md5_crypt.c deleted file mode 100644 index 53972fcc..00000000 --- a/modules/pam_unix/md5_crypt.c +++ /dev/null @@ -1,154 +0,0 @@ -/* - * $Id$ - * - * ---------------------------------------------------------------------------- - * "THE BEER-WARE LICENSE" (Revision 42): - * <phk@login.dknet.dk> wrote this file. As long as you retain this notice you - * can do whatever you want with this stuff. If we meet some day, and you think - * this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp - * ---------------------------------------------------------------------------- - * - * Origin: Id: crypt.c,v 1.3 1995/05/30 05:42:22 rgrimes Exp - * - */ - -#include <string.h> -#include <stdlib.h> -#include "md5.h" - -static unsigned char itoa64[] = /* 0 ... 63 => ascii - 64 */ -"./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; - -static void to64(char *s, unsigned long v, int n) -{ - while (--n >= 0) { - *s++ = itoa64[v & 0x3f]; - v >>= 6; - } -} - -/* - * UNIX password - * - * Use MD5 for what it is best at... - */ - -char *MD5Name(crypt_md5)(const char *pw, const char *salt) -{ - const char *magic = "$1$"; - /* This string is magic for this algorithm. Having - * it this way, we can get get better later on */ - char *passwd, *p; - const char *sp, *ep; - unsigned char final[16]; - int sl, pl, i, j; - MD5_CTX ctx, ctx1; - unsigned long l; - - /* Refine the Salt first */ - sp = salt; - - /* TODO: now that we're using malloc'ed memory, get rid of the - strange constant buffer size. */ - passwd = malloc(120); - - /* If it starts with the magic string, then skip that */ - if (!strncmp(sp, magic, strlen(magic))) - sp += strlen(magic); - - /* It stops at the first '$', max 8 chars */ - for (ep = sp; *ep && *ep != '$' && ep < (sp + 8); ep++) - continue; - - /* get the length of the true salt */ - sl = ep - sp; - - MD5Name(MD5Init)(&ctx); - - /* The password first, since that is what is most unknown */ - MD5Name(MD5Update)(&ctx,(unsigned const char *)pw,strlen(pw)); - - /* Then our magic string */ - MD5Name(MD5Update)(&ctx,(unsigned const char *)magic,strlen(magic)); - - /* Then the raw salt */ - MD5Name(MD5Update)(&ctx,(unsigned const char *)sp,sl); - - /* Then just as many characters of the MD5(pw,salt,pw) */ - MD5Name(MD5Init)(&ctx1); - MD5Name(MD5Update)(&ctx1,(unsigned const char *)pw,strlen(pw)); - MD5Name(MD5Update)(&ctx1,(unsigned const char *)sp,sl); - MD5Name(MD5Update)(&ctx1,(unsigned const char *)pw,strlen(pw)); - MD5Name(MD5Final)(final,&ctx1); - for (pl = strlen(pw); pl > 0; pl -= 16) - MD5Name(MD5Update)(&ctx,(unsigned const char *)final,pl>16 ? 16 : pl); - - /* Don't leave anything around in vm they could use. */ - memset(final, 0, sizeof final); - - /* Then something really weird... */ - for (j = 0, i = strlen(pw); i; i >>= 1) - if (i & 1) - MD5Name(MD5Update)(&ctx, (unsigned const char *)final+j, 1); - else - MD5Name(MD5Update)(&ctx, (unsigned const char *)pw+j, 1); - - /* Now make the output string */ - strcpy(passwd, magic); - strncat(passwd, sp, sl); - strcat(passwd, "$"); - - MD5Name(MD5Final)(final,&ctx); - - /* - * and now, just to make sure things don't run too fast - * On a 60 Mhz Pentium this takes 34 msec, so you would - * need 30 seconds to build a 1000 entry dictionary... - */ - for (i = 0; i < 1000; i++) { - MD5Name(MD5Init)(&ctx1); - if (i & 1) - MD5Name(MD5Update)(&ctx1,(unsigned const char *)pw,strlen(pw)); - else - MD5Name(MD5Update)(&ctx1,(unsigned const char *)final,16); - - if (i % 3) - MD5Name(MD5Update)(&ctx1,(unsigned const char *)sp,sl); - - if (i % 7) - MD5Name(MD5Update)(&ctx1,(unsigned const char *)pw,strlen(pw)); - - if (i & 1) - MD5Name(MD5Update)(&ctx1,(unsigned const char *)final,16); - else - MD5Name(MD5Update)(&ctx1,(unsigned const char *)pw,strlen(pw)); - MD5Name(MD5Final)(final,&ctx1); - } - - p = passwd + strlen(passwd); - - l = (final[0] << 16) | (final[6] << 8) | final[12]; - to64(p, l, 4); - p += 4; - l = (final[1] << 16) | (final[7] << 8) | final[13]; - to64(p, l, 4); - p += 4; - l = (final[2] << 16) | (final[8] << 8) | final[14]; - to64(p, l, 4); - p += 4; - l = (final[3] << 16) | (final[9] << 8) | final[15]; - to64(p, l, 4); - p += 4; - l = (final[4] << 16) | (final[10] << 8) | final[5]; - to64(p, l, 4); - p += 4; - l = final[11]; - to64(p, l, 2); - p += 2; - *p = '\0'; - - /* Don't leave anything around in vm they could use. */ - memset(final, 0, sizeof final); - - return passwd; -} diff --git a/modules/pam_unix/md5_good.c b/modules/pam_unix/md5_good.c deleted file mode 100644 index 131e4516..00000000 --- a/modules/pam_unix/md5_good.c +++ /dev/null @@ -1,5 +0,0 @@ -#define HIGHFIRST -#define MD5Name(x) Good##x - -#include "md5.c" -#include "md5_crypt.c" diff --git a/modules/pam_unix/pam_unix.8.xml b/modules/pam_unix/pam_unix.8.xml deleted file mode 100644 index 290cb2b9..00000000 --- a/modules/pam_unix/pam_unix.8.xml +++ /dev/null @@ -1,379 +0,0 @@ -<?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_unix"> - - <refmeta> - <refentrytitle>pam_unix</refentrytitle> - <manvolnum>8</manvolnum> - <refmiscinfo class="sectdesc">Linux-PAM Manual</refmiscinfo> - </refmeta> - - <refnamediv id="pam_unix-name"> - <refname>pam_unix</refname> - <refpurpose>Module for traditional password authentication</refpurpose> - </refnamediv> - - <refsynopsisdiv> - <cmdsynopsis id="pam_unix-cmdsynopsis"> - <command>pam_unix.so</command> - <arg choice="opt"> - ... - </arg> - </cmdsynopsis> - </refsynopsisdiv> - - <refsect1 id="pam_unix-description"> - - <title>DESCRIPTION</title> - - <para> - This is the standard Unix authentication module. It uses standard - calls from the system's libraries to retrieve and set account - information as well as authentication. Usually this is obtained - from the /etc/passwd and the /etc/shadow file as well if shadow is - enabled. - </para> - - <para> - The account component performs the task of establishing the status - of the user's account and password based on the following - <emphasis>shadow</emphasis> elements: expire, last_change, max_change, - min_change, warn_change. In the case of the latter, it may offer advice - to the user on changing their password or, through the - <emphasis remap='B'>PAM_AUTHTOKEN_REQD</emphasis> return, delay - giving service to the user until they have established a new password. - The entries listed above are documented in the <citerefentry> - <refentrytitle>shadow</refentrytitle><manvolnum>5</manvolnum> - </citerefentry> manual page. Should the user's record not contain - one or more of these entries, the corresponding - <emphasis>shadow</emphasis> check is not performed. - </para> - - <para> - The authentication component performs the task of checking the - users credentials (password). The default action of this module - is to not permit the user access to a service if their official - password is blank. - </para> - - <para> - A helper binary, <citerefentry> - <refentrytitle>unix_chkpwd</refentrytitle><manvolnum>8</manvolnum> - </citerefentry>, is provided - to check the user's password when it is stored in a read - protected database. This binary is very simple and will only - check the password of the user invoking it. It is called - transparently on behalf of the user by the authenticating - component of this module. In this way it is possible - for applications like <citerefentry> - <refentrytitle>xlock</refentrytitle><manvolnum>1</manvolnum> - </citerefentry> to work without - being setuid-root. The module, by default, will temporarily turn - off SIGCHLD handling for the duration of execution of the helper - binary. This is generally the right thing to do, as many applications - are not prepared to handle this signal from a child they didn't know - was <function>fork()</function>d. The <option>noreap</option> module - argument can be used to suppress this temporary shielding and may be - needed for use with certain applications. - </para> - - <para> - The password component of this module performs the task of updating - the user's password. - </para> - - <para> - The session component of this module logs when a user logins - or leave the system. - </para> - - <para> - Remaining arguments, supported by others functions of this - module, are silently ignored. Other arguments are logged as - errors through <citerefentry> - <refentrytitle>syslog</refentrytitle><manvolnum>3</manvolnum> - </citerefentry>. - </para> - </refsect1> - - <refsect1 id="pam_unix-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>audit</option> - </term> - <listitem> - <para> - A little more extreme than debug. - </para> - </listitem> - </varlistentry> - - <varlistentry> - <term> - <option>nullok</option> - </term> - <listitem> - <para> - The default action of this module is to not permit the - user access to a service if their official password is blank. - The <option>nullok</option> argument overrides this default. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <option>try_first_pass</option> - </term> - <listitem> - <para> - Before prompting the user for their password, the module first - tries the previous stacked module's password in case that - satisfies this module as well. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <option>use_first_pass</option> - </term> - <listitem> - <para> - The argument <option>use_first_pass</option> forces the module - to use a previous stacked modules password and will never prompt - the user - if no password is available or the password is not - appropriate, the user will be denied access. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <option>nodelay</option> - </term> - <listitem> - <para> - This argument can be used to discourage the authentication - component from requesting a delay should the authentication - as a whole fail. The default action is for the module to - request a delay-on-failure of the order of two second. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <option>use_authtok</option> - </term> - <listitem> - <para> - When password changing enforce the module to set the new - password to the one provided by a previously stacked - <option>password</option> module (this is used in the - example of the stacking of the <command>pam_cracklib</command> - module documented above). - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <option>not_set_pass</option> - </term> - <listitem> - <para> - This argument is used to inform the module that it is not to - pay attention to/make available the old or new passwords from/to - other (stacked) password modules. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <option>nis</option> - </term> - <listitem> - <para> - NIS RPC is used for setting new passwords. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <option>remember=<replaceable>n</replaceable></option> - </term> - <listitem> - <para> - The last <replaceable>n</replaceable> passwords for each - user are saved in <filename>/etc/security/opasswd</filename> - in order to force password change history and keep the user - from alternating between the same password too frequently. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <option>shadow</option> - </term> - <listitem> - <para> - Try to maintain a shadow based system. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <option>md5</option> - </term> - <listitem> - <para> - When a user changes their password next, encrypt - it with the MD5 algorithm. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <option>bigcrypt</option> - </term> - <listitem> - <para> - When a user changes their password next, - encrypt it with the DEC C2 algorithm. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <option>sha256</option> - </term> - <listitem> - <para> - When a user changes their password next, - encrypt it with the SHA256 algorithm. If the - SHA256 algorithm is not known to the libcrypt, - fall back to MD5. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <option>sha512</option> - </term> - <listitem> - <para> - When a user changes their password next, - encrypt it with the SHA512 algorithm. If the - SHA512 algorithm is not known to the libcrypt, - fall back to MD5. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <option>rounds=<replaceable>n</replaceable></option> - </term> - <listitem> - <para> - Set the optional number of rounds of the SHA256 and SHA512 - password hashing algorithms to <replaceable>n</replaceable>. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <option>broken_shadow</option> - </term> - <listitem> - <para> - Ignore errors reading shadow inforation for - users in the account management module. - </para> - </listitem> - </varlistentry> - </variablelist> - <para> - Invalid arguments are logged with <citerefentry> - <refentrytitle>syslog</refentrytitle><manvolnum>3</manvolnum> - </citerefentry>. - </para> - </refsect1> - - <refsect1 id="pam_unix-services"> - <title>MODULE SERVICES PROVIDED</title> - <para> - All service are supported. - </para> - </refsect1> - - <refsect1 id='pam_unix-return_values'> - <title>RETURN VALUES</title> - <variablelist> - <varlistentry> - <term>PAM_IGNORE</term> - <listitem> - <para> - Ignore this module. - </para> - </listitem> - </varlistentry> - </variablelist> - </refsect1> - - <refsect1 id='pam_unix-examples'> - <title>EXAMPLES</title> - <para> - An example usage for <filename>/etc/pam.d/login</filename> - would be: - <programlisting> -# Authenticate the user -auth required pam_unix.so -# Ensure users account and password are still active -account required pam_unix.so -# Change the users password, but at first check the strength -# with pam_cracklib(8) -password required pam_cracklib.so retry=3 minlen=6 difok=3 -password required pam_unix.so use_authtok nullok md5 -session required pam_unix.so - </programlisting> - </para> - </refsect1> - - <refsect1 id='pam_unix-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_unix-author'> - <title>AUTHOR</title> - <para> - pam_unix was written by various people. - </para> - </refsect1> - -</refentry> diff --git a/modules/pam_unix/pam_unix_acct.c b/modules/pam_unix/pam_unix_acct.c deleted file mode 100644 index c09bc175..00000000 --- a/modules/pam_unix/pam_unix_acct.c +++ /dev/null @@ -1,297 +0,0 @@ -/* - * Copyright Elliot Lee, 1996. All rights reserved. - * Copyright Jan Rêkorajski, 1999. All rights reserved. - * - * 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 <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <unistd.h> -#include <sys/types.h> -#include <syslog.h> -#include <pwd.h> -#include <shadow.h> -#include <time.h> /* for time() */ -#include <errno.h> -#include <sys/wait.h> - -#include <security/_pam_macros.h> - -/* indicate that the following groups are defined */ - -#define PAM_SM_ACCOUNT - -#include <security/pam_modules.h> -#include <security/pam_ext.h> -#include <security/pam_modutil.h> - -#include "support.h" -#include "passverify.h" - -int _unix_run_verify_binary(pam_handle_t *pamh, unsigned int ctrl, - const char *user, int *daysleft) -{ - int retval=0, child, fds[2]; - void (*sighandler)(int) = NULL; - D(("running verify_binary")); - - /* create a pipe for the messages */ - if (pipe(fds) != 0) { - D(("could not make pipe")); - pam_syslog(pamh, LOG_ERR, "Could not make pipe: %m"); - return PAM_AUTH_ERR; - } - D(("called.")); - - if (off(UNIX_NOREAP, ctrl)) { - /* - * This code arranges that the demise of the child does not cause - * the application to receive a signal it is not expecting - which - * may kill the application or worse. - * - * The "noreap" module argument is provided so that the admin can - * override this behavior. - */ - sighandler = signal(SIGCHLD, SIG_DFL); - } - - /* fork */ - child = fork(); - if (child == 0) { - size_t i=0; - struct rlimit rlim; - static char *envp[] = { NULL }; - char *args[] = { NULL, NULL, NULL, NULL }; - - close(0); close(1); - /* reopen stdin as pipe */ - close(fds[0]); - dup2(fds[1], STDOUT_FILENO); - - /* XXX - should really tidy up PAM here too */ - - if (getrlimit(RLIMIT_NOFILE,&rlim)==0) { - for (i=2; i < rlim.rlim_max; i++) { - if ((unsigned int)fds[1] != i) { - close(i); - } - } - } - - if (geteuid() == 0) { - /* must set the real uid to 0 so the helper will not error - out if pam is called from setuid binary (su, sudo...) */ - setuid(0); - } - - /* exec binary helper */ - args[0] = x_strdup(CHKPWD_HELPER); - args[1] = x_strdup(user); - args[2] = x_strdup("chkexpiry"); - - execve(CHKPWD_HELPER, args, envp); - - pam_syslog(pamh, LOG_ERR, "helper binary execve failed: %m"); - /* should not get here: exit with error */ - close (fds[1]); - D(("helper binary is not available")); - printf("-1\n"); - exit(PAM_AUTHINFO_UNAVAIL); - } else { - close(fds[1]); - if (child > 0) { - char buf[32]; - int rc=0; - rc=waitpid(child, &retval, 0); /* wait for helper to complete */ - if (rc<0) { - pam_syslog(pamh, LOG_ERR, "unix_chkpwd waitpid returned %d: %m", rc); - retval = PAM_AUTH_ERR; - } else { - retval = WEXITSTATUS(retval); - rc = pam_modutil_read(fds[0], buf, sizeof(buf) - 1); - if(rc > 0) { - buf[rc] = '\0'; - if (sscanf(buf,"%d", daysleft) != 1 ) - retval = PAM_AUTH_ERR; - } - else { - pam_syslog(pamh, LOG_ERR, "read unix_chkpwd output error %d: %m", rc); - retval = PAM_AUTH_ERR; - } - } - } else { - pam_syslog(pamh, LOG_ERR, "Fork failed: %m"); - D(("fork failed")); - retval = PAM_AUTH_ERR; - } - close(fds[0]); - } - if (sighandler != SIG_ERR) { - (void) signal(SIGCHLD, sighandler); /* restore old signal handler */ - } - D(("Returning %d",retval)); - return retval; -} - -/* - * PAM framework looks for this entry-point to pass control to the - * account management module. - */ - -PAM_EXTERN int pam_sm_acct_mgmt(pam_handle_t * pamh, int flags, - int argc, const char **argv) -{ - unsigned int ctrl; - const void *void_uname; - const char *uname; - int retval, daysleft; - struct spwd *spent; - struct passwd *pwent; - char buf[256]; - - D(("called.")); - - ctrl = _set_ctrl(pamh, flags, NULL, NULL, argc, argv); - - retval = pam_get_item(pamh, PAM_USER, &void_uname); - uname = void_uname; - D(("user = `%s'", uname)); - if (retval != PAM_SUCCESS || uname == NULL) { - pam_syslog(pamh, LOG_ALERT, - "could not identify user (from uid=%lu)", - (unsigned long int)getuid()); - return PAM_USER_UNKNOWN; - } - - retval = get_account_info(pamh, uname, &pwent, &spent); - if (retval == PAM_USER_UNKNOWN) { - pam_syslog(pamh, LOG_ALERT, - "could not identify user (from getpwnam(%s))", - uname); - return retval; - } - - if (retval == PAM_SUCCESS && spent == NULL) - return PAM_SUCCESS; - - if (retval == PAM_UNIX_RUN_HELPER) { - retval = _unix_run_verify_binary(pamh, ctrl, uname, &daysleft); - if (retval == PAM_AUTHINFO_UNAVAIL && - on(UNIX_BROKEN_SHADOW, ctrl)) - return PAM_SUCCESS; - } else if (retval != PAM_SUCCESS) { - if (on(UNIX_BROKEN_SHADOW,ctrl)) - return PAM_SUCCESS; - else - return retval; - } else - retval = check_shadow_expiry(pamh, spent, &daysleft); - - switch (retval) { - case PAM_ACCT_EXPIRED: - pam_syslog(pamh, LOG_NOTICE, - "account %s has expired (account expired)", - uname); - _make_remark(pamh, ctrl, PAM_ERROR_MSG, - _("Your account has expired; please contact your system administrator")); - break; - case PAM_NEW_AUTHTOK_REQD: - if (daysleft == 0) { - pam_syslog(pamh, LOG_NOTICE, - "expired password for user %s (root enforced)", - uname); - _make_remark(pamh, ctrl, PAM_ERROR_MSG, - _("You are required to change your password immediately (root enforced)")); - } else { - pam_syslog(pamh, LOG_DEBUG, - "expired password for user %s (password aged)", - uname); - _make_remark(pamh, ctrl, PAM_ERROR_MSG, - _("You are required to change your password immediately (password aged)")); - } - break; - case PAM_AUTHTOK_EXPIRED: - pam_syslog(pamh, LOG_NOTICE, - "account %s has expired (failed to change password)", - uname); - _make_remark(pamh, ctrl, PAM_ERROR_MSG, - _("Your account has expired; please contact your system administrator")); - break; - case PAM_SUCCESS: - if (daysleft >= 0) { - pam_syslog(pamh, LOG_DEBUG, - "password for user %s will expire in %d days", - uname, daysleft); -#if defined HAVE_DNGETTEXT && defined ENABLE_NLS - snprintf (buf, sizeof (buf), - dngettext(PACKAGE, - "Warning: your password will expire in %d day", - "Warning: your password will expire in %d days", - daysleft), - daysleft); -#else - if (daysleft == 1) - snprintf(buf, sizeof (buf), - _("Warning: your password will expire in %d day"), - daysleft); - else - snprintf(buf, sizeof (buf), - /* TRANSLATORS: only used if dngettext is not supported */ - _("Warning: your password will expire in %d days"), - daysleft); -#endif - _make_remark(pamh, ctrl, PAM_TEXT_INFO, buf); - } - } - - D(("all done")); - - return retval; -} - - -/* static module data */ -#ifdef PAM_STATIC -struct pam_module _pam_unix_acct_modstruct = { - "pam_unix_acct", - NULL, - NULL, - pam_sm_acct_mgmt, - NULL, - NULL, - NULL, -}; -#endif diff --git a/modules/pam_unix/pam_unix_auth.c b/modules/pam_unix/pam_unix_auth.c deleted file mode 100644 index dfedd608..00000000 --- a/modules/pam_unix/pam_unix_auth.c +++ /dev/null @@ -1,229 +0,0 @@ -/* - * Copyright Alexander O. Yuriev, 1996. All rights reserved. - * NIS+ support by Thorsten Kukuk <kukuk@weber.uni-paderborn.de> - * Copyright Jan Rêkorajski, 1999. All rights reserved. - * - * 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. - */ - -/* #define DEBUG */ - -#include "config.h" - -#include <stdio.h> -#include <stdlib.h> -#include <stdarg.h> -#include <string.h> -#include <unistd.h> -#include <fcntl.h> -#include <ctype.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <syslog.h> - -/* indicate the following groups are defined */ - -#define PAM_SM_AUTH - -#define _PAM_EXTERN_FUNCTIONS -#include <security/_pam_macros.h> -#include <security/pam_modules.h> -#include <security/pam_ext.h> - -#include "support.h" - -/* - * PAM framework looks for these entry-points to pass control to the - * authentication module. - */ - -/* Fun starts here :) - - * pam_sm_authenticate() performs UNIX/shadow authentication - * - * First, if shadow support is available, attempt to perform - * authentication using shadow passwords. If shadow is not - * available, or user does not have a shadow password, fallback - * onto a normal UNIX authentication - */ - -#define _UNIX_AUTHTOK "-UN*X-PASS" - -#define AUTH_RETURN \ -do { \ - if (on(UNIX_LIKE_AUTH, ctrl) && ret_data) { \ - D(("recording return code for next time [%d]", \ - retval)); \ - *ret_data = retval; \ - pam_set_data(pamh, "unix_setcred_return", \ - (void *) ret_data, setcred_free); \ - } else if (ret_data) \ - free (ret_data); \ - D(("done. [%s]", pam_strerror(pamh, retval))); \ - return retval; \ -} while (0) - - -static void -setcred_free (pam_handle_t *pamh UNUSED, void *ptr, int err UNUSED) -{ - if (ptr) - free (ptr); -} - - -PAM_EXTERN int pam_sm_authenticate(pam_handle_t * pamh, int flags - ,int argc, const char **argv) -{ - unsigned int ctrl; - int retval, *ret_data = NULL; - const char *name; - const void *p; - - D(("called.")); - - ctrl = _set_ctrl(pamh, flags, NULL, NULL, argc, argv); - - /* Get a few bytes so we can pass our return value to - pam_sm_setcred(). */ - if (on(UNIX_LIKE_AUTH, ctrl)) - ret_data = malloc(sizeof(int)); - - /* get the user'name' */ - - retval = pam_get_user(pamh, &name, NULL); - if (retval == PAM_SUCCESS) { - /* - * Various libraries at various times have had bugs related to - * '+' or '-' as the first character of a user name. Don't - * allow this characters here. - */ - if (name == NULL || name[0] == '-' || name[0] == '+') { - pam_syslog(pamh, LOG_ERR, "bad username [%s]", name); - retval = PAM_USER_UNKNOWN; - AUTH_RETURN; - } - if (retval == PAM_SUCCESS && on(UNIX_DEBUG, ctrl)) - D(("username [%s] obtained", name)); - } else { - D(("trouble reading username")); - if (retval == PAM_CONV_AGAIN) { - D(("pam_get_user/conv() function is not ready yet")); - /* it is safe to resume this function so we translate this - * retval to the value that indicates we're happy to resume. - */ - retval = PAM_INCOMPLETE; - } - AUTH_RETURN; - } - - /* if this user does not have a password... */ - - if (_unix_blankpasswd(pamh, ctrl, name)) { - D(("user '%s' has blank passwd", name)); - name = NULL; - retval = PAM_SUCCESS; - AUTH_RETURN; - } - /* get this user's authentication token */ - - retval = _unix_read_password(pamh, ctrl, NULL, _("Password: "), NULL - ,_UNIX_AUTHTOK, &p); - if (retval != PAM_SUCCESS) { - if (retval != PAM_CONV_AGAIN) { - pam_syslog(pamh, LOG_CRIT, - "auth could not identify password for [%s]", name); - } else { - D(("conversation function is not ready yet")); - /* - * it is safe to resume this function so we translate this - * retval to the value that indicates we're happy to resume. - */ - retval = PAM_INCOMPLETE; - } - name = NULL; - AUTH_RETURN; - } - D(("user=%s, password=[%s]", name, p)); - - /* verify the password of this user */ - retval = _unix_verify_password(pamh, name, p, ctrl); - name = p = NULL; - - AUTH_RETURN; -} - - -/* - * The only thing _pam_set_credentials_unix() does is initialization of - * UNIX group IDs. - * - * Well, everybody but me on linux-pam is convinced that it should not - * initialize group IDs, so I am not doing it but don't say that I haven't - * warned you. -- AOY - */ - -PAM_EXTERN int -pam_sm_setcred (pam_handle_t *pamh, int flags UNUSED, - int argc UNUSED, const char **argv UNUSED) -{ - int retval; - const void *pretval = NULL; - - D(("called.")); - - retval = PAM_SUCCESS; - - D(("recovering return code from auth call")); - /* We will only find something here if UNIX_LIKE_AUTH is set -- - don't worry about an explicit check of argv. */ - if (pam_get_data(pamh, "unix_setcred_return", &pretval) == PAM_SUCCESS - && pretval) { - retval = *(const int *)pretval; - pam_set_data(pamh, "unix_setcred_return", NULL, NULL); - D(("recovered data indicates that old retval was %d", retval)); - } - - return retval; -} - -#ifdef PAM_STATIC -struct pam_module _pam_unix_auth_modstruct = { - "pam_unix_auth", - pam_sm_authenticate, - pam_sm_setcred, - NULL, - NULL, - NULL, - NULL, -}; -#endif diff --git a/modules/pam_unix/pam_unix_passwd.c b/modules/pam_unix/pam_unix_passwd.c deleted file mode 100644 index 432f687f..00000000 --- a/modules/pam_unix/pam_unix_passwd.c +++ /dev/null @@ -1,802 +0,0 @@ -/* - * Main coding by Elliot Lee <sopwith@redhat.com>, Red Hat Software. - * Copyright (C) 1996. - * Copyright (c) Jan Rêkorajski, 1999. - * Copyright (c) Red Hat, Inc., 2007, 2008. - * - * 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 <stdio.h> -#include <stdlib.h> -#include <stdarg.h> -#include <string.h> -#include <malloc.h> -#include <unistd.h> -#include <errno.h> -#include <sys/types.h> -#include <pwd.h> -#include <syslog.h> -#include <shadow.h> -#include <time.h> /* for time() */ -#include <fcntl.h> -#include <ctype.h> -#include <sys/time.h> -#include <sys/stat.h> -#include <rpc/rpc.h> -#include <rpcsvc/yp_prot.h> -#include <rpcsvc/ypclnt.h> - -#include <signal.h> -#include <errno.h> -#include <sys/wait.h> -#ifdef WITH_SELINUX -static int selinux_enabled=-1; -#include <selinux/selinux.h> -#define SELINUX_ENABLED (selinux_enabled!=-1 ? selinux_enabled : (selinux_enabled=is_selinux_enabled()>0)) -#endif - -#ifdef USE_CRACKLIB -#include <crack.h> -#endif - -#include <security/_pam_macros.h> - -/* indicate the following groups are defined */ - -#define PAM_SM_PASSWORD - -#include <security/pam_modules.h> -#include <security/pam_ext.h> -#include <security/pam_modutil.h> - -#include "yppasswd.h" -#include "md5.h" -#include "support.h" -#include "passverify.h" -#include "bigcrypt.h" - -#if !((__GLIBC__ == 2) && (__GLIBC_MINOR__ >= 1)) -extern int getrpcport(const char *host, unsigned long prognum, - unsigned long versnum, unsigned int proto); -#endif /* GNU libc 2.1 */ - -/* - How it works: - Gets in username (has to be done) from the calling program - Does authentication of user (only if we are not running as root) - Gets new password/checks for sanity - Sets it. - */ - -/* data tokens */ - -#define _UNIX_OLD_AUTHTOK "-UN*X-OLD-PASS" -#define _UNIX_NEW_AUTHTOK "-UN*X-NEW-PASS" - -#define MAX_PASSWD_TRIES 3 -#ifndef CRACKLIB_DICTS -#define CRACKLIB_DICTS NULL -#endif - -static char *getNISserver(pam_handle_t *pamh) -{ - char *master; - char *domainname; - int port, err; - - if ((err = yp_get_default_domain(&domainname)) != 0) { - pam_syslog(pamh, LOG_WARNING, "can't get local yp domain: %s", - yperr_string(err)); - return NULL; - } - if ((err = yp_master(domainname, "passwd.byname", &master)) != 0) { - pam_syslog(pamh, LOG_WARNING, "can't find the master ypserver: %s", - yperr_string(err)); - return NULL; - } - port = getrpcport(master, YPPASSWDPROG, YPPASSWDPROC_UPDATE, IPPROTO_UDP); - if (port == 0) { - pam_syslog(pamh, LOG_WARNING, - "yppasswdd not running on NIS master host"); - return NULL; - } - if (port >= IPPORT_RESERVED) { - pam_syslog(pamh, LOG_WARNING, - "yppasswd daemon running on illegal port"); - return NULL; - } - return master; -} - -#ifdef WITH_SELINUX - -static int _unix_run_update_binary(pam_handle_t *pamh, unsigned int ctrl, const char *user, - const char *fromwhat, const char *towhat, int remember) -{ - int retval, child, fds[2]; - void (*sighandler)(int) = NULL; - - D(("called.")); - /* create a pipe for the password */ - if (pipe(fds) != 0) { - D(("could not make pipe")); - return PAM_AUTH_ERR; - } - - if (off(UNIX_NOREAP, ctrl)) { - /* - * This code arranges that the demise of the child does not cause - * the application to receive a signal it is not expecting - which - * may kill the application or worse. - * - * The "noreap" module argument is provided so that the admin can - * override this behavior. - */ - sighandler = signal(SIGCHLD, SIG_DFL); - } - - /* fork */ - child = fork(); - if (child == 0) { - size_t i=0; - struct rlimit rlim; - static char *envp[] = { NULL }; - char *args[] = { NULL, NULL, NULL, NULL, NULL, NULL }; - char buffer[16]; - - /* XXX - should really tidy up PAM here too */ - - close(0); close(1); - /* reopen stdin as pipe */ - close(fds[1]); - dup2(fds[0], STDIN_FILENO); - - if (getrlimit(RLIMIT_NOFILE,&rlim)==0) { - for (i=2; i < rlim.rlim_max; i++) { - if ((unsigned int)fds[0] != i) - close(i); - } - } - - if (SELINUX_ENABLED && geteuid() == 0) { - /* must set the real uid to 0 so the helper will not error - out if pam is called from setuid binary (su, sudo...) */ - setuid(0); - } - - /* exec binary helper */ - args[0] = x_strdup(UPDATE_HELPER); - args[1] = x_strdup(user); - args[2] = x_strdup("update"); - if (on(UNIX_SHADOW, ctrl)) - args[3] = x_strdup("1"); - else - args[3] = x_strdup("0"); - - snprintf(buffer, sizeof(buffer), "%d", remember); - args[4] = x_strdup(buffer); - - execve(UPDATE_HELPER, args, envp); - - /* should not get here: exit with error */ - D(("helper binary is not available")); - exit(PAM_AUTHINFO_UNAVAIL); - } else if (child > 0) { - /* wait for child */ - /* if the stored password is NULL */ - int rc=0; - if (fromwhat) - pam_modutil_write(fds[1], fromwhat, strlen(fromwhat)+1); - else - pam_modutil_write(fds[1], "", 1); - if (towhat) { - pam_modutil_write(fds[1], towhat, strlen(towhat)+1); - } - else - pam_modutil_write(fds[1], "", 1); - - close(fds[0]); /* close here to avoid possible SIGPIPE above */ - close(fds[1]); - rc=waitpid(child, &retval, 0); /* wait for helper to complete */ - if (rc<0) { - pam_syslog(pamh, LOG_ERR, "unix_update waitpid failed: %m"); - retval = PAM_AUTH_ERR; - } else { - retval = WEXITSTATUS(retval); - } - } else { - D(("fork failed")); - close(fds[0]); - close(fds[1]); - retval = PAM_AUTH_ERR; - } - - if (sighandler != SIG_ERR) { - (void) signal(SIGCHLD, sighandler); /* restore old signal handler */ - } - - return retval; -} -#endif - -static int check_old_password(const char *forwho, const char *newpass) -{ - static char buf[16384]; - char *s_luser, *s_uid, *s_npas, *s_pas; - int retval = PAM_SUCCESS; - FILE *opwfile; - - opwfile = fopen(OLD_PASSWORDS_FILE, "r"); - if (opwfile == NULL) - return PAM_ABORT; - - while (fgets(buf, 16380, opwfile)) { - if (!strncmp(buf, forwho, strlen(forwho))) { - char *sptr; - buf[strlen(buf) - 1] = '\0'; - s_luser = strtok_r(buf, ":,", &sptr); - s_uid = strtok_r(NULL, ":,", &sptr); - s_npas = strtok_r(NULL, ":,", &sptr); - s_pas = strtok_r(NULL, ":,", &sptr); - while (s_pas != NULL) { - char *md5pass = Goodcrypt_md5(newpass, s_pas); - if (!strcmp(md5pass, s_pas)) { - _pam_delete(md5pass); - retval = PAM_AUTHTOK_ERR; - break; - } - s_pas = strtok_r(NULL, ":,", &sptr); - _pam_delete(md5pass); - } - break; - } - } - fclose(opwfile); - - return retval; -} - -static int _do_setpass(pam_handle_t* pamh, const char *forwho, - const char *fromwhat, - char *towhat, unsigned int ctrl, int remember) -{ - struct passwd *pwd = NULL; - int retval = 0; - int unlocked = 0; - char *master = NULL; - - D(("called")); - - pwd = getpwnam(forwho); - - if (pwd == NULL) { - retval = PAM_AUTHTOK_ERR; - goto done; - } - - if (on(UNIX_NIS, ctrl) && _unix_comesfromsource(pamh, forwho, 0, 1)) { - if ((master=getNISserver(pamh)) != NULL) { - struct timeval timeout; - struct yppasswd yppwd; - CLIENT *clnt; - int status; - enum clnt_stat err; - - /* Unlock passwd file to avoid deadlock */ - unlock_pwdf(); - unlocked = 1; - - /* Initialize password information */ - yppwd.newpw.pw_passwd = pwd->pw_passwd; - yppwd.newpw.pw_name = pwd->pw_name; - yppwd.newpw.pw_uid = pwd->pw_uid; - yppwd.newpw.pw_gid = pwd->pw_gid; - yppwd.newpw.pw_gecos = pwd->pw_gecos; - yppwd.newpw.pw_dir = pwd->pw_dir; - yppwd.newpw.pw_shell = pwd->pw_shell; - yppwd.oldpass = fromwhat ? strdup (fromwhat) : strdup (""); - yppwd.newpw.pw_passwd = towhat; - - D(("Set password %s for %s", yppwd.newpw.pw_passwd, forwho)); - - /* The yppasswd.x file said `unix authentication required', - * so I added it. This is the only reason it is in here. - * My yppasswdd doesn't use it, but maybe some others out there - * do. --okir - */ - clnt = clnt_create(master, YPPASSWDPROG, YPPASSWDVERS, "udp"); - clnt->cl_auth = authunix_create_default(); - memset((char *) &status, '\0', sizeof(status)); - timeout.tv_sec = 25; - timeout.tv_usec = 0; - err = clnt_call(clnt, YPPASSWDPROC_UPDATE, - (xdrproc_t) xdr_yppasswd, (char *) &yppwd, - (xdrproc_t) xdr_int, (char *) &status, - timeout); - - free (yppwd.oldpass); - - if (err) { - _make_remark(pamh, ctrl, PAM_TEXT_INFO, - clnt_sperrno(err)); - } else if (status) { - D(("Error while changing NIS password.\n")); - } - D(("The password has%s been changed on %s.", - (err || status) ? " not" : "", master)); - pam_syslog(pamh, LOG_NOTICE, "password%s changed for %s on %s", - (err || status) ? " not" : "", pwd->pw_name, master); - - auth_destroy(clnt->cl_auth); - clnt_destroy(clnt); - if (err || status) { - _make_remark(pamh, ctrl, PAM_TEXT_INFO, - _("NIS password could not be changed.")); - retval = PAM_TRY_AGAIN; - } -#ifdef DEBUG - sleep(5); -#endif - } else { - retval = PAM_TRY_AGAIN; - } - } - - if (_unix_comesfromsource(pamh, forwho, 1, 0)) { - if(unlocked) { - if (lock_pwdf() != PAM_SUCCESS) { - return PAM_AUTHTOK_LOCK_BUSY; - } - } -#ifdef WITH_SELINUX - if (unix_selinux_confined()) - return _unix_run_update_binary(pamh, ctrl, forwho, fromwhat, towhat, remember); -#endif - /* first, save old password */ - if (save_old_password(forwho, fromwhat, remember)) { - retval = PAM_AUTHTOK_ERR; - goto done; - } - if (on(UNIX_SHADOW, ctrl) || is_pwd_shadowed(pwd)) { - retval = unix_update_shadow(pamh, forwho, towhat); - if (retval == PAM_SUCCESS) - if (!is_pwd_shadowed(pwd)) - retval = unix_update_passwd(pamh, forwho, "x"); - } else { - retval = unix_update_passwd(pamh, forwho, towhat); - } - } - - -done: - unlock_pwdf(); - - return retval; -} - -static int _unix_verify_shadow(pam_handle_t *pamh, const char *user, unsigned int ctrl) -{ - struct passwd *pwent = NULL; /* Password and shadow password */ - struct spwd *spent = NULL; /* file entries for the user */ - int daysleft; - int retval; - - retval = get_account_info(pamh, user, &pwent, &spent); - if (retval == PAM_USER_UNKNOWN) { - return retval; - } - - if (retval == PAM_SUCCESS && spent == NULL) - return PAM_SUCCESS; - - if (retval == PAM_UNIX_RUN_HELPER) { - retval = _unix_run_verify_binary(pamh, ctrl, user, &daysleft); - if (retval == PAM_AUTH_ERR || retval == PAM_USER_UNKNOWN) - return retval; - } - else if (retval == PAM_SUCCESS) - retval = check_shadow_expiry(pamh, spent, &daysleft); - - if (on(UNIX__IAMROOT, ctrl) || retval == PAM_NEW_AUTHTOK_REQD) - return PAM_SUCCESS; - - return retval; -} - -static int _pam_unix_approve_pass(pam_handle_t * pamh - ,unsigned int ctrl - ,const char *pass_old - ,const char *pass_new) -{ - const void *user; - const char *remark = NULL; - int retval = PAM_SUCCESS; - - D(("&new=%p, &old=%p", pass_old, pass_new)); - D(("new=[%s]", pass_new)); - D(("old=[%s]", pass_old)); - - if (pass_new == NULL || (pass_old && !strcmp(pass_old, pass_new))) { - if (on(UNIX_DEBUG, ctrl)) { - pam_syslog(pamh, LOG_DEBUG, "bad authentication token"); - } - _make_remark(pamh, ctrl, PAM_ERROR_MSG, pass_new == NULL ? - _("No password supplied") : _("Password unchanged")); - return PAM_AUTHTOK_ERR; - } - /* - * if one wanted to hardwire authentication token strength - * checking this would be the place - AGM - */ - - retval = pam_get_item(pamh, PAM_USER, &user); - if (retval != PAM_SUCCESS) { - if (on(UNIX_DEBUG, ctrl)) { - pam_syslog(pamh, LOG_ERR, "Can not get username"); - return PAM_AUTHTOK_ERR; - } - } - if (off(UNIX__IAMROOT, ctrl)) { -#ifdef USE_CRACKLIB - remark = FascistCheck (pass_new, CRACKLIB_DICTS); - D(("called cracklib [%s]", remark)); -#else - if (strlen(pass_new) < 6) - remark = _("You must choose a longer password"); - D(("length check [%s]", remark)); -#endif - if (on(UNIX_REMEMBER_PASSWD, ctrl)) { - if ((retval = check_old_password(user, pass_new)) == PAM_AUTHTOK_ERR) - remark = _("Password has been already used. Choose another."); - if (retval == PAM_ABORT) { - pam_syslog(pamh, LOG_ERR, "can't open %s file to check old passwords", - OLD_PASSWORDS_FILE); - return retval; - } - } - } - if (remark) { - _make_remark(pamh, ctrl, PAM_ERROR_MSG, remark); - retval = PAM_AUTHTOK_ERR; - } - return retval; -} - - -PAM_EXTERN int pam_sm_chauthtok(pam_handle_t * pamh, int flags, - int argc, const char **argv) -{ - unsigned int ctrl, lctrl; - int retval; - int remember = -1; - int rounds = -1; - - /* <DO NOT free() THESE> */ - const char *user; - const void *pass_old, *pass_new; - /* </DO NOT free() THESE> */ - - D(("called.")); - - ctrl = _set_ctrl(pamh, flags, &remember, &rounds, argc, argv); - - /* - * First get the name of a user - */ - retval = pam_get_user(pamh, &user, NULL); - if (retval == PAM_SUCCESS) { - /* - * Various libraries at various times have had bugs related to - * '+' or '-' as the first character of a user name. Don't - * allow them. - */ - if (user == NULL || user[0] == '-' || user[0] == '+') { - pam_syslog(pamh, LOG_ERR, "bad username [%s]", user); - return PAM_USER_UNKNOWN; - } - if (retval == PAM_SUCCESS && on(UNIX_DEBUG, ctrl)) - pam_syslog(pamh, LOG_DEBUG, "username [%s] obtained", - user); - } else { - if (on(UNIX_DEBUG, ctrl)) - pam_syslog(pamh, LOG_DEBUG, - "password - could not identify user"); - return retval; - } - - D(("Got username of %s", user)); - - /* - * Before we do anything else, check to make sure that the user's - * info is in one of the databases we can modify from this module, - * which currently is 'files' and 'nis'. We have to do this because - * getpwnam() doesn't tell you *where* the information it gives you - * came from, nor should it. That's our job. - */ - if (_unix_comesfromsource(pamh, user, 1, on(UNIX_NIS, ctrl)) == 0) { - pam_syslog(pamh, LOG_DEBUG, - "user \"%s\" does not exist in /etc/passwd%s", - user, on(UNIX_NIS, ctrl) ? " or NIS" : ""); - return PAM_USER_UNKNOWN; - } else { - struct passwd *pwd; - _unix_getpwnam(pamh, user, 1, 1, &pwd); - if (pwd == NULL) { - pam_syslog(pamh, LOG_DEBUG, - "user \"%s\" has corrupted passwd entry", - user); - return PAM_USER_UNKNOWN; - } - } - - /* - * This is not an AUTH module! - */ - if (on(UNIX__NONULL, ctrl)) - set(UNIX__NULLOK, ctrl); - - if (on(UNIX__PRELIM, ctrl)) { - /* - * obtain and verify the current password (OLDAUTHTOK) for - * the user. - */ - char *Announce; - - D(("prelim check")); - - if (_unix_blankpasswd(pamh, ctrl, user)) { - return PAM_SUCCESS; - } else if (off(UNIX__IAMROOT, ctrl)) { - /* instruct user what is happening */ - if (asprintf(&Announce, _("Changing password for %s."), - user) < 0) { - pam_syslog(pamh, LOG_CRIT, - "password - out of memory"); - return PAM_BUF_ERR; - } - - lctrl = ctrl; - set(UNIX__OLD_PASSWD, lctrl); - retval = _unix_read_password(pamh, lctrl - ,Announce - ,_("(current) UNIX password: ") - ,NULL - ,_UNIX_OLD_AUTHTOK - ,&pass_old); - free(Announce); - - if (retval != PAM_SUCCESS) { - pam_syslog(pamh, LOG_NOTICE, - "password - (old) token not obtained"); - return retval; - } - /* verify that this is the password for this user */ - - retval = _unix_verify_password(pamh, user, pass_old, ctrl); - } else { - D(("process run by root so do nothing this time around")); - pass_old = NULL; - retval = PAM_SUCCESS; /* root doesn't have too */ - } - - if (retval != PAM_SUCCESS) { - D(("Authentication failed")); - pass_old = NULL; - return retval; - } - retval = pam_set_item(pamh, PAM_OLDAUTHTOK, (const void *) pass_old); - pass_old = NULL; - if (retval != PAM_SUCCESS) { - pam_syslog(pamh, LOG_CRIT, - "failed to set PAM_OLDAUTHTOK"); - } - retval = _unix_verify_shadow(pamh,user, ctrl); - if (retval == PAM_AUTHTOK_ERR) { - if (off(UNIX__IAMROOT, ctrl)) - _make_remark(pamh, ctrl, PAM_ERROR_MSG, - _("You must wait longer to change your password")); - else - retval = PAM_SUCCESS; - } - } else if (on(UNIX__UPDATE, ctrl)) { - /* - * tpass is used below to store the _pam_md() return; it - * should be _pam_delete()'d. - */ - - char *tpass = NULL; - int retry = 0; - - /* - * obtain the proposed password - */ - - D(("do update")); - - /* - * get the old token back. NULL was ok only if root [at this - * point we assume that this has already been enforced on a - * previous call to this function]. - */ - - if (off(UNIX_NOT_SET_PASS, ctrl)) { - retval = pam_get_item(pamh, PAM_OLDAUTHTOK - ,&pass_old); - } else { - retval = pam_get_data(pamh, _UNIX_OLD_AUTHTOK - ,&pass_old); - if (retval == PAM_NO_MODULE_DATA) { - retval = PAM_SUCCESS; - pass_old = NULL; - } - } - D(("pass_old [%s]", pass_old)); - - if (retval != PAM_SUCCESS) { - pam_syslog(pamh, LOG_NOTICE, "user not authenticated"); - return retval; - } - - D(("get new password now")); - - lctrl = ctrl; - - if (on(UNIX_USE_AUTHTOK, lctrl)) { - set(UNIX_USE_FIRST_PASS, lctrl); - } - retry = 0; - retval = PAM_AUTHTOK_ERR; - while ((retval != PAM_SUCCESS) && (retry++ < MAX_PASSWD_TRIES)) { - /* - * use_authtok is to force the use of a previously entered - * password -- needed for pluggable password strength checking - */ - - retval = _unix_read_password(pamh, lctrl - ,NULL - ,_("Enter new UNIX password: ") - ,_("Retype new UNIX password: ") - ,_UNIX_NEW_AUTHTOK - ,&pass_new); - - if (retval != PAM_SUCCESS) { - if (on(UNIX_DEBUG, ctrl)) { - pam_syslog(pamh, LOG_ALERT, - "password - new password not obtained"); - } - pass_old = NULL; /* tidy up */ - return retval; - } - D(("returned to _unix_chauthtok")); - - /* - * At this point we know who the user is and what they - * propose as their new password. Verify that the new - * password is acceptable. - */ - - if (*(const char *)pass_new == '\0') { /* "\0" password = NULL */ - pass_new = NULL; - } - retval = _pam_unix_approve_pass(pamh, ctrl, pass_old, pass_new); - } - - if (retval != PAM_SUCCESS) { - pam_syslog(pamh, LOG_NOTICE, - "new password not acceptable"); - pass_new = pass_old = NULL; /* tidy up */ - return retval; - } - if (lock_pwdf() != PAM_SUCCESS) { - return PAM_AUTHTOK_LOCK_BUSY; - } - - if (pass_old) { - retval = _unix_verify_password(pamh, user, pass_old, ctrl); - if (retval != PAM_SUCCESS) { - pam_syslog(pamh, LOG_NOTICE, "user password changed by another process"); - unlock_pwdf(); - return retval; - } - } - - retval = _unix_verify_shadow(pamh, user, ctrl); - if (retval != PAM_SUCCESS) { - pam_syslog(pamh, LOG_NOTICE, "user shadow entry expired"); - unlock_pwdf(); - return retval; - } - - retval = _pam_unix_approve_pass(pamh, ctrl, pass_old, pass_new); - if (retval != PAM_SUCCESS) { - pam_syslog(pamh, LOG_NOTICE, - "new password not acceptable 2"); - pass_new = pass_old = NULL; /* tidy up */ - unlock_pwdf(); - return retval; - } - - /* - * By reaching here we have approved the passwords and must now - * rebuild the password database file. - */ - - /* - * First we encrypt the new password. - */ - - tpass = create_password_hash(pass_new, ctrl, rounds); - if (tpass == NULL) { - pam_syslog(pamh, LOG_CRIT, - "out of memory for password"); - pass_new = pass_old = NULL; /* tidy up */ - unlock_pwdf(); - return PAM_BUF_ERR; - } - - D(("password processed")); - - /* update the password database(s) -- race conditions..? */ - - retval = _do_setpass(pamh, user, pass_old, tpass, ctrl, - remember); - /* _do_setpass has called unlock_pwdf for us */ - - _pam_delete(tpass); - pass_old = pass_new = NULL; - } else { /* something has broken with the module */ - pam_syslog(pamh, LOG_ALERT, - "password received unknown request"); - retval = PAM_ABORT; - } - - D(("retval was %d", retval)); - - return retval; -} - - -/* static module data */ -#ifdef PAM_STATIC -struct pam_module _pam_unix_passwd_modstruct = { - "pam_unix_passwd", - NULL, - NULL, - NULL, - NULL, - NULL, - pam_sm_chauthtok, -}; -#endif diff --git a/modules/pam_unix/pam_unix_sess.c b/modules/pam_unix/pam_unix_sess.c deleted file mode 100644 index e984578c..00000000 --- a/modules/pam_unix/pam_unix_sess.c +++ /dev/null @@ -1,143 +0,0 @@ -/* - * $Id$ - * - * Copyright Alexander O. Yuriev, 1996. All rights reserved. - * Copyright Jan Rêkorajski, 1999. All rights reserved. - * - * 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 <stdio.h> -#include <stdlib.h> -#include <stdarg.h> -#include <unistd.h> -#include <syslog.h> -#include <fcntl.h> -#include <sys/types.h> -#include <sys/stat.h> - -/* indicate the following groups are defined */ - -#define PAM_SM_SESSION - -#include <security/_pam_macros.h> -#include <security/pam_modules.h> -#include <security/pam_ext.h> -#include <security/pam_modutil.h> - -#include "support.h" - -/* - * PAM framework looks for these entry-points to pass control to the - * session module. - */ - -PAM_EXTERN int pam_sm_open_session(pam_handle_t * pamh, int flags, - int argc, const char **argv) -{ - char *user_name, *service; - unsigned int ctrl; - int retval; - const char *login_name; - - D(("called.")); - - ctrl = _set_ctrl(pamh, flags, NULL, NULL, argc, argv); - - retval = pam_get_item(pamh, PAM_USER, (void *) &user_name); - if (user_name == NULL || *user_name == '\0' || retval != PAM_SUCCESS) { - pam_syslog(pamh, LOG_CRIT, - "open_session - error recovering username"); - return PAM_SESSION_ERR; /* How did we get authenticated with - no username?! */ - } - retval = pam_get_item(pamh, PAM_SERVICE, (void *) &service); - if (service == NULL || *service == '\0' || retval != PAM_SUCCESS) { - pam_syslog(pamh, LOG_CRIT, - "open_session - error recovering service"); - return PAM_SESSION_ERR; - } - login_name = pam_modutil_getlogin(pamh); - if (login_name == NULL) { - login_name = ""; - } - pam_syslog(pamh, LOG_INFO, "session opened for user %s by %s(uid=%lu)", - user_name, login_name, (unsigned long)getuid()); - - return PAM_SUCCESS; -} - -PAM_EXTERN int pam_sm_close_session(pam_handle_t * pamh, int flags, - int argc, const char **argv) -{ - char *user_name, *service; - unsigned int ctrl; - int retval; - - D(("called.")); - - ctrl = _set_ctrl(pamh, flags, NULL, NULL, argc, argv); - - retval = pam_get_item(pamh, PAM_USER, (void *) &user_name); - if (user_name == NULL || *user_name == '\0' || retval != PAM_SUCCESS) { - pam_syslog(pamh, LOG_CRIT, - "close_session - error recovering username"); - return PAM_SESSION_ERR; /* How did we get authenticated with - no username?! */ - } - retval = pam_get_item(pamh, PAM_SERVICE, (void *) &service); - if (service == NULL || *service == '\0' || retval != PAM_SUCCESS) { - pam_syslog(pamh, LOG_CRIT, - "close_session - error recovering service"); - return PAM_SESSION_ERR; - } - pam_syslog(pamh, LOG_INFO, "session closed for user %s", - user_name); - - return PAM_SUCCESS; -} - -/* static module data */ -#ifdef PAM_STATIC -struct pam_module _pam_unix_session_modstruct = { - "pam_unix_session", - NULL, - NULL, - NULL, - pam_sm_open_session, - pam_sm_close_session, - NULL, -}; -#endif - diff --git a/modules/pam_unix/passverify.c b/modules/pam_unix/passverify.c deleted file mode 100644 index 6d588e63..00000000 --- a/modules/pam_unix/passverify.c +++ /dev/null @@ -1,1129 +0,0 @@ -/* - * Copyright information at end of file. - */ -#include "config.h" -#include <security/_pam_macros.h> -#include <security/pam_modules.h> -#include "support.h" -#include <stdio.h> -#include <string.h> -#include <sys/types.h> -#include <unistd.h> -#include <pwd.h> -#include <shadow.h> -#include <syslog.h> -#include <stdarg.h> -#include <signal.h> -#include <errno.h> -#include <time.h> -#include <sys/time.h> -#include <sys/stat.h> -#include <fcntl.h> -#ifdef HAVE_CRYPT_H -#include <crypt.h> -#endif - -#include "md5.h" -#include "bigcrypt.h" -#include "passverify.h" - -#ifdef WITH_SELINUX -#include <selinux/selinux.h> -#define SELINUX_ENABLED is_selinux_enabled()>0 -#else -#define SELINUX_ENABLED 0 -#endif - -#ifdef HELPER_COMPILE -#define pam_modutil_getpwnam(h,n) getpwnam(n) -#define pam_modutil_getspnam(h,n) getspnam(n) -#define pam_syslog(h,a,b,c) helper_log_err(a,b,c) -#else -#include <security/pam_modutil.h> -#include <security/pam_ext.h> -#endif - -#if defined(USE_LCKPWDF) && !defined(HAVE_LCKPWDF) -# include "./lckpwdf.-c" -#endif - -static void -strip_hpux_aging(char *hash) -{ - static const char valid[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" - "abcdefghijklmnopqrstuvwxyz" - "0123456789./"; - if ((*hash != '$') && (strlen(hash) > 13)) { - for (hash += 13; *hash != '\0'; hash++) { - if (strchr(valid, *hash) == NULL) { - *hash = '\0'; - break; - } - } - } -} - -int -verify_pwd_hash(const char *p, char *hash, unsigned int nullok) -{ - size_t hash_len; - char *pp = NULL; - int retval; - D(("called")); - - strip_hpux_aging(hash); - hash_len = strlen(hash); - if (!hash_len) { - /* the stored password is NULL */ - if (nullok) { /* this means we've succeeded */ - D(("user has empty password - access granted")); - retval = PAM_SUCCESS; - } else { - D(("user has empty password - access denied")); - retval = PAM_AUTH_ERR; - } - } else if (!p || *hash == '*' || *hash == '!') { - retval = PAM_AUTH_ERR; - } else { - if (!strncmp(hash, "$1$", 3)) { - pp = Goodcrypt_md5(p, hash); - if (pp && strcmp(pp, hash) != 0) { - _pam_delete(pp); - pp = Brokencrypt_md5(p, hash); - } - } else if (*hash != '$' && hash_len >= 13) { - pp = bigcrypt(p, hash); - if (pp && hash_len == 13 && strlen(pp) > hash_len) { - _pam_overwrite(pp + hash_len); - } - } else { - /* - * Ok, we don't know the crypt algorithm, but maybe - * libcrypt knows about it? We should try it. - */ -#ifdef HAVE_CRYPT_R - struct crypt_data *cdata; - cdata = malloc(sizeof(*cdata)); - if (cdata != NULL) { - cdata->initialized = 0; - pp = x_strdup(crypt_r(p, hash, cdata)); - memset(cdata, '\0', sizeof(*cdata)); - free(cdata); - } -#else - pp = x_strdup(crypt(p, hash)); -#endif - } - p = NULL; /* no longer needed here */ - - /* the moment of truth -- do we agree with the password? */ - D(("comparing state of pp[%s] and salt[%s]", pp, salt)); - - if (pp && strcmp(pp, hash) == 0) { - retval = PAM_SUCCESS; - } else { - retval = PAM_AUTH_ERR; - } - } - - if (pp) - _pam_delete(pp); - D(("done [%d].", retval)); - - return retval; -} - -int -is_pwd_shadowed(const struct passwd *pwd) -{ - if (pwd != NULL) { - if (strcmp(pwd->pw_passwd, "x") == 0) { - return 1; - } - if ((pwd->pw_passwd[0] == '#') && - (pwd->pw_passwd[1] == '#') && - (strcmp(pwd->pw_name, pwd->pw_passwd + 2) == 0)) { - return 1; - } - } - return 0; -} - -#ifdef HELPER_COMPILE -int -get_account_info(const char *name, - struct passwd **pwd, struct spwd **spwdent) -#else -int -get_account_info(pam_handle_t *pamh, const char *name, - struct passwd **pwd, struct spwd **spwdent) -#endif -{ - /* UNIX passwords area */ - *pwd = pam_modutil_getpwnam(pamh, name); /* Get password file entry... */ - *spwdent = NULL; - - if (*pwd != NULL) { - if (strcmp((*pwd)->pw_passwd, "*NP*") == 0) - { /* NIS+ */ -#ifdef HELPER_COMPILE - uid_t save_euid, save_uid; - - save_euid = geteuid(); - save_uid = getuid(); - if (save_uid == (*pwd)->pw_uid) - setreuid(save_euid, save_uid); - else { - setreuid(0, -1); - if (setreuid(-1, (*pwd)->pw_uid) == -1) { - setreuid(-1, 0); - setreuid(0, -1); - if(setreuid(-1, (*pwd)->pw_uid) == -1) - return PAM_CRED_INSUFFICIENT; - } - } - - *spwdent = pam_modutil_getspnam(pamh, name); - if (save_uid == (*pwd)->pw_uid) - setreuid(save_uid, save_euid); - else { - setreuid(-1, 0); - setreuid(save_uid, -1); - setreuid(-1, save_euid); - } - - if (*spwdent == NULL || (*spwdent)->sp_pwdp == NULL) - return PAM_AUTHINFO_UNAVAIL; -#else - /* we must run helper for NIS+ passwords */ - return PAM_UNIX_RUN_HELPER; -#endif - } else if (is_pwd_shadowed(*pwd)) { - /* - * ...and shadow password file entry for this user, - * if shadowing is enabled - */ -#ifndef HELPER_COMPILE - if (geteuid() || SELINUX_ENABLED) - return PAM_UNIX_RUN_HELPER; -#endif - *spwdent = pam_modutil_getspnam(pamh, name); - if (*spwdent == NULL || (*spwdent)->sp_pwdp == NULL) - return PAM_AUTHINFO_UNAVAIL; - } - } else { - return PAM_USER_UNKNOWN; - } - return PAM_SUCCESS; -} - -#ifdef HELPER_COMPILE -int -get_pwd_hash(const char *name, - struct passwd **pwd, char **hash) -#else -int -get_pwd_hash(pam_handle_t *pamh, const char *name, - struct passwd **pwd, char **hash) -#endif -{ - int retval; - struct spwd *spwdent = NULL; - -#ifdef HELPER_COMPILE - retval = get_account_info(name, pwd, &spwdent); -#else - retval = get_account_info(pamh, name, pwd, &spwdent); -#endif - if (retval != PAM_SUCCESS) { - return retval; - } - - if (spwdent) - *hash = x_strdup(spwdent->sp_pwdp); - else - *hash = x_strdup((*pwd)->pw_passwd); - if (*hash == NULL) - return PAM_BUF_ERR; - - return PAM_SUCCESS; -} - -#ifdef HELPER_COMPILE -int -check_shadow_expiry(struct spwd *spent, int *daysleft) -#else -int -check_shadow_expiry(pam_handle_t *pamh, struct spwd *spent, int *daysleft) -#endif -{ - long int curdays; - *daysleft = -1; - curdays = (long int)(time(NULL) / (60 * 60 * 24)); - D(("today is %d, last change %d", curdays, spent->sp_lstchg)); - if ((curdays > spent->sp_expire) && (spent->sp_expire != -1)) { - D(("account expired")); - return PAM_ACCT_EXPIRED; - } - if (spent->sp_lstchg == 0) { - D(("need a new password")); - *daysleft = 0; - return PAM_NEW_AUTHTOK_REQD; - } - if (curdays < spent->sp_lstchg) { - pam_syslog(pamh, LOG_DEBUG, - "account %s has password changed in future", - spent->sp_namp); - return PAM_SUCCESS; - } - if ((curdays - spent->sp_lstchg > spent->sp_max) - && (curdays - spent->sp_lstchg > spent->sp_inact) - && (curdays - spent->sp_lstchg > spent->sp_max + spent->sp_inact) - && (spent->sp_max != -1) && (spent->sp_inact != -1)) { - *daysleft = (int)((spent->sp_lstchg + spent->sp_max) - curdays); - D(("authtok expired")); - return PAM_AUTHTOK_EXPIRED; - } - if ((curdays - spent->sp_lstchg > spent->sp_max) && (spent->sp_max != -1)) { - D(("need a new password 2")); - return PAM_NEW_AUTHTOK_REQD; - } - if ((curdays - spent->sp_lstchg > spent->sp_max - spent->sp_warn) - && (spent->sp_max != -1) && (spent->sp_warn != -1)) { - *daysleft = (int)((spent->sp_lstchg + spent->sp_max) - curdays); - D(("warn before expiry")); - } - return PAM_SUCCESS; - -} - -/* passwd/salt conversion macros */ - -#define PW_TMPFILE "/etc/npasswd" -#define SH_TMPFILE "/etc/nshadow" -#define OPW_TMPFILE "/etc/security/nopasswd" - -/* - * i64c - convert an integer to a radix 64 character - */ -static int -i64c(int i) -{ - if (i < 0) - return ('.'); - else if (i > 63) - return ('z'); - if (i == 0) - return ('.'); - if (i == 1) - return ('/'); - if (i >= 2 && i <= 11) - return ('0' - 2 + i); - if (i >= 12 && i <= 37) - return ('A' - 12 + i); - if (i >= 38 && i <= 63) - return ('a' - 38 + i); - return ('\0'); -} - -/* <where> must point to a buffer of at least <length>+1 length */ -static void -crypt_make_salt(char *where, int length) -{ - struct timeval tv; - MD5_CTX ctx; - unsigned char tmp[16]; - unsigned char *src = (unsigned char *)where; - int i; -#ifdef PAM_PATH_RANDOMDEV - int fd; - int rv; - - if ((rv = fd = open(PAM_PATH_RANDOMDEV, O_RDONLY)) != -1) { - while ((rv = read(fd, where, length)) != length && errno == EINTR); - close (fd); - } - if (rv != length) { -#endif - /* - * Code lifted from Marek Michalkiewicz's shadow suite. (CG) - * removed use of static variables (AGM) - * - * will work correctly only for length <= 16 */ - src = tmp; - GoodMD5Init(&ctx); - gettimeofday(&tv, (struct timezone *) 0); - GoodMD5Update(&ctx, (void *) &tv, sizeof tv); - i = getpid(); - GoodMD5Update(&ctx, (void *) &i, sizeof i); - i = clock(); - GoodMD5Update(&ctx, (void *) &i, sizeof i); - GoodMD5Update(&ctx, src, length); - GoodMD5Final(tmp, &ctx); -#ifdef PAM_PATH_RANDOMDEV - } -#endif - for (i = 0; i < length; i++) - *where++ = i64c(src[i] & 077); - *where = '\0'; -} - -char * -crypt_md5_wrapper(const char *pass_new) -{ - unsigned char result[16]; - char *cp = (char *) result; - - cp = stpcpy(cp, "$1$"); /* magic for the MD5 */ - crypt_make_salt(cp, 8); - - /* no longer need cleartext */ - cp = Goodcrypt_md5(pass_new, (const char *) result); - pass_new = NULL; - - return cp; -} - -char * -create_password_hash(const char *password, unsigned int ctrl, int rounds) -{ - const char *algoid; - char salt[64]; /* contains rounds number + max 16 bytes of salt + algo id */ - char *sp; - - if (on(UNIX_MD5_PASS, ctrl)) { - return crypt_md5_wrapper(password); - } - if (on(UNIX_SHA256_PASS, ctrl)) { - algoid = "$5$"; - } else if (on(UNIX_SHA512_PASS, ctrl)) { - algoid = "$6$"; - } else { /* must be crypt/bigcrypt */ - char tmppass[9]; - char *crypted; - - crypt_make_salt(salt, 2); - if (off(UNIX_BIGCRYPT, ctrl) && strlen(password) > 8) { - strncpy(tmppass, password, sizeof(tmppass)-1); - tmppass[sizeof(tmppass)-1] = '\0'; - password = tmppass; - } - crypted = bigcrypt(password, salt); - memset(tmppass, '\0', sizeof(tmppass)); - password = NULL; - return crypted; - } - - sp = stpcpy(salt, algoid); - if (on(UNIX_ALGO_ROUNDS, ctrl)) { - sp += snprintf(sp, sizeof(salt) - 3, "rounds=%u$", rounds); - } - crypt_make_salt(sp, 8); - /* For now be conservative so the resulting hashes - * are not too long. 8 bytes of salt prevents dictionary - * attacks well enough. */ - sp = crypt(password, salt); - if (strncmp(algoid, sp, strlen(algoid)) != 0) { - /* libc doesn't know the algorithm, use MD5 */ - memset(sp, '\0', strlen(sp)); - return crypt_md5_wrapper(password); - } - - return x_strdup(sp); -} - -#ifdef WITH_SELINUX -int -unix_selinux_confined(void) -{ - static int confined = -1; - int fd; - char tempfile[]="/etc/.pwdXXXXXX"; - - if (confined != -1) - return confined; - - /* cannot be confined without SELinux enabled */ - if (!SELINUX_ENABLED){ - confined = 0; - return confined; - } - - /* let's try opening shadow read only */ - if ((fd=open("/etc/shadow", O_RDONLY)) != -1) { - close(fd); - confined = 0; - return confined; - } - - if (errno == EACCES) { - confined = 1; - return confined; - } - - /* shadow opening failed because of other reasons let's try - creating a file in /etc */ - if ((fd=mkstemp(tempfile)) != -1) { - unlink(tempfile); - close(fd); - confined = 0; - return confined; - } - - confined = 1; - return confined; -} - -#else -int -unix_selinux_confined(void) -{ - return 0; -} -#endif - -#ifdef USE_LCKPWDF -int -lock_pwdf(void) -{ - int i; - int retval; - -#ifndef HELPER_COMPILE - if (unix_selinux_confined()) { - return PAM_SUCCESS; - } -#endif - /* These values for the number of attempts and the sleep time - are, of course, completely arbitrary. - My reading of the PAM docs is that, once pam_chauthtok() has been - called with PAM_UPDATE_AUTHTOK, we are obliged to take any - reasonable steps to make sure the token is updated; so retrying - for 1/10 sec. isn't overdoing it. */ - i=0; - while((retval = lckpwdf()) != 0 && i < 100) { - usleep(1000); - i++; - } - if(retval != 0) { - return PAM_AUTHTOK_LOCK_BUSY; - } - return PAM_SUCCESS; -} - -void -unlock_pwdf(void) -{ -#ifndef HELPER_COMPILE - if (unix_selinux_confined()) { - return; - } -#endif - ulckpwdf(); -} -#else -int -lock_pwdf(void) -{ - return PAM_SUCCESS; -} - -void -unlock_pwdf(void) -{ - return; -} -#endif - -int -save_old_password(const char *forwho, const char *oldpass, - int howmany) -{ - static char buf[16384]; - static char nbuf[16384]; - char *s_luser, *s_uid, *s_npas, *s_pas, *pass; - int npas; - FILE *pwfile, *opwfile; - int err = 0; - int oldmask; - int found = 0; - struct passwd *pwd = NULL; - struct stat st; -#ifdef WITH_SELINUX - security_context_t prev_context=NULL; -#endif - - if (howmany < 0) { - return PAM_SUCCESS; - } - - if (oldpass == NULL) { - return PAM_SUCCESS; - } - - oldmask = umask(077); - -#ifdef WITH_SELINUX - if (SELINUX_ENABLED) { - security_context_t passwd_context=NULL; - if (getfilecon("/etc/passwd",&passwd_context)<0) { - return PAM_AUTHTOK_ERR; - }; - if (getfscreatecon(&prev_context)<0) { - freecon(passwd_context); - return PAM_AUTHTOK_ERR; - } - if (setfscreatecon(passwd_context)) { - freecon(passwd_context); - freecon(prev_context); - return PAM_AUTHTOK_ERR; - } - freecon(passwd_context); - } -#endif - pwfile = fopen(OPW_TMPFILE, "w"); - umask(oldmask); - if (pwfile == NULL) { - err = 1; - goto done; - } - - opwfile = fopen(OLD_PASSWORDS_FILE, "r"); - if (opwfile == NULL) { - fclose(pwfile); - err = 1; - goto done; - } - - if (fstat(fileno(opwfile), &st) == -1) { - fclose(opwfile); - fclose(pwfile); - err = 1; - goto done; - } - - if (fchown(fileno(pwfile), st.st_uid, st.st_gid) == -1) { - fclose(opwfile); - fclose(pwfile); - err = 1; - goto done; - } - if (fchmod(fileno(pwfile), st.st_mode) == -1) { - fclose(opwfile); - fclose(pwfile); - err = 1; - goto done; - } - - while (fgets(buf, 16380, opwfile)) { - if (!strncmp(buf, forwho, strlen(forwho))) { - char *sptr = NULL; - found = 1; - if (howmany == 0) - continue; - buf[strlen(buf) - 1] = '\0'; - s_luser = strtok_r(buf, ":", &sptr); - s_uid = strtok_r(NULL, ":", &sptr); - s_npas = strtok_r(NULL, ":", &sptr); - s_pas = strtok_r(NULL, ":", &sptr); - npas = strtol(s_npas, NULL, 10) + 1; - while (npas > howmany) { - s_pas = strpbrk(s_pas, ","); - if (s_pas != NULL) - s_pas++; - npas--; - } - pass = crypt_md5_wrapper(oldpass); - if (s_pas == NULL) - snprintf(nbuf, sizeof(nbuf), "%s:%s:%d:%s\n", - s_luser, s_uid, npas, pass); - else - snprintf(nbuf, sizeof(nbuf),"%s:%s:%d:%s,%s\n", - s_luser, s_uid, npas, s_pas, pass); - _pam_delete(pass); - if (fputs(nbuf, pwfile) < 0) { - err = 1; - break; - } - } else if (fputs(buf, pwfile) < 0) { - err = 1; - break; - } - } - fclose(opwfile); - - if (!found) { - pwd = getpwnam(forwho); - if (pwd == NULL) { - err = 1; - } else { - pass = crypt_md5_wrapper(oldpass); - snprintf(nbuf, sizeof(nbuf), "%s:%lu:1:%s\n", - forwho, (unsigned long)pwd->pw_uid, pass); - _pam_delete(pass); - if (fputs(nbuf, pwfile) < 0) { - err = 1; - } - } - } - - if (fclose(pwfile)) { - D(("error writing entries to old passwords file: %m")); - err = 1; - } - -done: - if (!err) { - if (rename(OPW_TMPFILE, OLD_PASSWORDS_FILE)) - err = 1; - } -#ifdef WITH_SELINUX - if (SELINUX_ENABLED) { - if (setfscreatecon(prev_context)) { - err = 1; - } - if (prev_context) - freecon(prev_context); - prev_context=NULL; - } -#endif - if (!err) { - return PAM_SUCCESS; - } else { - unlink(OPW_TMPFILE); - return PAM_AUTHTOK_ERR; - } -} - -#ifdef HELPER_COMPILE -int -unix_update_passwd(const char *forwho, const char *towhat) -#else -int -unix_update_passwd(pam_handle_t *pamh, const char *forwho, const char *towhat) -#endif -{ - struct passwd *tmpent = NULL; - struct stat st; - FILE *pwfile, *opwfile; - int err = 1; - int oldmask; -#ifdef WITH_SELINUX - security_context_t prev_context=NULL; -#endif - - oldmask = umask(077); -#ifdef WITH_SELINUX - if (SELINUX_ENABLED) { - security_context_t passwd_context=NULL; - if (getfilecon("/etc/passwd",&passwd_context)<0) { - return PAM_AUTHTOK_ERR; - }; - if (getfscreatecon(&prev_context)<0) { - freecon(passwd_context); - return PAM_AUTHTOK_ERR; - } - if (setfscreatecon(passwd_context)) { - freecon(passwd_context); - freecon(prev_context); - return PAM_AUTHTOK_ERR; - } - freecon(passwd_context); - } -#endif - pwfile = fopen(PW_TMPFILE, "w"); - umask(oldmask); - if (pwfile == NULL) { - err = 1; - goto done; - } - - opwfile = fopen("/etc/passwd", "r"); - if (opwfile == NULL) { - fclose(pwfile); - err = 1; - goto done; - } - - if (fstat(fileno(opwfile), &st) == -1) { - fclose(opwfile); - fclose(pwfile); - err = 1; - goto done; - } - - if (fchown(fileno(pwfile), st.st_uid, st.st_gid) == -1) { - fclose(opwfile); - fclose(pwfile); - err = 1; - goto done; - } - if (fchmod(fileno(pwfile), st.st_mode) == -1) { - fclose(opwfile); - fclose(pwfile); - err = 1; - goto done; - } - - tmpent = fgetpwent(opwfile); - while (tmpent) { - if (!strcmp(tmpent->pw_name, forwho)) { - /* To shut gcc up */ - union { - const char *const_charp; - char *charp; - } assigned_passwd; - assigned_passwd.const_charp = towhat; - - tmpent->pw_passwd = assigned_passwd.charp; - err = 0; - } - if (putpwent(tmpent, pwfile)) { - D(("error writing entry to password file: %m")); - err = 1; - break; - } - tmpent = fgetpwent(opwfile); - } - fclose(opwfile); - - if (fclose(pwfile)) { - D(("error writing entries to password file: %m")); - err = 1; - } - -done: - if (!err) { - if (!rename(PW_TMPFILE, "/etc/passwd")) -#ifdef HELPER_COMPILE - helper_log_err( -#else - pam_syslog(pamh, -#endif - LOG_NOTICE, "password changed for %s", forwho); - else - err = 1; - } -#ifdef WITH_SELINUX - if (SELINUX_ENABLED) { - if (setfscreatecon(prev_context)) { - err = 1; - } - if (prev_context) - freecon(prev_context); - prev_context=NULL; - } -#endif - if (!err) { - return PAM_SUCCESS; - } else { - unlink(PW_TMPFILE); - return PAM_AUTHTOK_ERR; - } -} - -#ifdef HELPER_COMPILE -int -unix_update_shadow(const char *forwho, char *towhat) -#else -int -unix_update_shadow(pam_handle_t *pamh, const char *forwho, char *towhat) -#endif -{ - struct spwd *spwdent = NULL, *stmpent = NULL; - struct stat st; - FILE *pwfile, *opwfile; - int err = 1; - int oldmask; -#ifdef WITH_SELINUX - security_context_t prev_context=NULL; -#endif - - spwdent = getspnam(forwho); - if (spwdent == NULL) { - return PAM_USER_UNKNOWN; - } - oldmask = umask(077); - -#ifdef WITH_SELINUX - if (SELINUX_ENABLED) { - security_context_t shadow_context=NULL; - if (getfilecon("/etc/shadow",&shadow_context)<0) { - return PAM_AUTHTOK_ERR; - }; - if (getfscreatecon(&prev_context)<0) { - freecon(shadow_context); - return PAM_AUTHTOK_ERR; - } - if (setfscreatecon(shadow_context)) { - freecon(shadow_context); - freecon(prev_context); - return PAM_AUTHTOK_ERR; - } - freecon(shadow_context); - } -#endif - pwfile = fopen(SH_TMPFILE, "w"); - umask(oldmask); - if (pwfile == NULL) { - err = 1; - goto done; - } - - opwfile = fopen("/etc/shadow", "r"); - if (opwfile == NULL) { - fclose(pwfile); - err = 1; - goto done; - } - - if (fstat(fileno(opwfile), &st) == -1) { - fclose(opwfile); - fclose(pwfile); - err = 1; - goto done; - } - - if (fchown(fileno(pwfile), st.st_uid, st.st_gid) == -1) { - fclose(opwfile); - fclose(pwfile); - err = 1; - goto done; - } - if (fchmod(fileno(pwfile), st.st_mode) == -1) { - fclose(opwfile); - fclose(pwfile); - err = 1; - goto done; - } - - stmpent = fgetspent(opwfile); - while (stmpent) { - - if (!strcmp(stmpent->sp_namp, forwho)) { - stmpent->sp_pwdp = towhat; - stmpent->sp_lstchg = time(NULL) / (60 * 60 * 24); - err = 0; - D(("Set password %s for %s", stmpent->sp_pwdp, forwho)); - } - - if (putspent(stmpent, pwfile)) { - D(("error writing entry to shadow file: %m")); - err = 1; - break; - } - - stmpent = fgetspent(opwfile); - } - fclose(opwfile); - - if (fclose(pwfile)) { - D(("error writing entries to shadow file: %m")); - err = 1; - } - - done: - if (!err) { - if (!rename(SH_TMPFILE, "/etc/shadow")) -#ifdef HELPER_COMPILE - helper_log_err( -#else - pam_syslog(pamh, -#endif - LOG_NOTICE, "password changed for %s", forwho); - else - err = 1; - } - -#ifdef WITH_SELINUX - if (SELINUX_ENABLED) { - if (setfscreatecon(prev_context)) { - err = 1; - } - if (prev_context) - freecon(prev_context); - prev_context=NULL; - } -#endif - - if (!err) { - return PAM_SUCCESS; - } else { - unlink(SH_TMPFILE); - return PAM_AUTHTOK_ERR; - } -} - -#ifdef HELPER_COMPILE - -int -helper_verify_password(const char *name, const char *p, int nullok) -{ - struct passwd *pwd = NULL; - char *salt = NULL; - int retval; - - retval = get_pwd_hash(name, &pwd, &salt); - - if (pwd == NULL || salt == NULL) { - helper_log_err(LOG_WARNING, "check pass; user unknown"); - retval = PAM_USER_UNKNOWN; - } else { - retval = verify_pwd_hash(p, salt, nullok); - } - - if (salt) { - _pam_overwrite(salt); - _pam_drop(salt); - } - - p = NULL; /* no longer needed here */ - - return retval; -} - -void -helper_log_err(int err, const char *format, ...) -{ - va_list args; - - va_start(args, format); - openlog(HELPER_COMPILE, LOG_CONS | LOG_PID, LOG_AUTHPRIV); - vsyslog(err, format, args); - va_end(args); - closelog(); -} - -static void -su_sighandler(int sig) -{ -#ifndef SA_RESETHAND - /* emulate the behaviour of the SA_RESETHAND flag */ - if ( sig == SIGILL || sig == SIGTRAP || sig == SIGBUS || sig = SIGSERV ) - signal(sig, SIG_DFL); -#endif - if (sig > 0) { - _exit(sig); - } -} - -void -setup_signals(void) -{ - struct sigaction action; /* posix signal structure */ - - /* - * Setup signal handlers - */ - (void) memset((void *) &action, 0, sizeof(action)); - action.sa_handler = su_sighandler; -#ifdef SA_RESETHAND - action.sa_flags = SA_RESETHAND; -#endif - (void) sigaction(SIGILL, &action, NULL); - (void) sigaction(SIGTRAP, &action, NULL); - (void) sigaction(SIGBUS, &action, NULL); - (void) sigaction(SIGSEGV, &action, NULL); - action.sa_handler = SIG_IGN; - action.sa_flags = 0; - (void) sigaction(SIGTERM, &action, NULL); - (void) sigaction(SIGHUP, &action, NULL); - (void) sigaction(SIGINT, &action, NULL); - (void) sigaction(SIGQUIT, &action, NULL); -} - -char * -getuidname(uid_t uid) -{ - struct passwd *pw; - static char username[256]; - - pw = getpwuid(uid); - if (pw == NULL) - return NULL; - - strncpy(username, pw->pw_name, sizeof(username)); - username[sizeof(username) - 1] = '\0'; - - return username; -} - -int -read_passwords(int fd, int npass, char **passwords) -{ - int rbytes = 0; - int offset = 0; - int i = 0; - char *pptr; - while (npass > 0) { - rbytes = read(fd, passwords[i]+offset, MAXPASS-offset); - - if (rbytes < 0) { - if (errno == EINTR) continue; - break; - } - if (rbytes == 0) - break; - - while (npass > 0 && (pptr=memchr(passwords[i]+offset, '\0', rbytes)) - != NULL) { - rbytes -= pptr - (passwords[i]+offset) + 1; - i++; - offset = 0; - npass--; - if (rbytes > 0) { - if (npass > 0) - memcpy(passwords[i], pptr+1, rbytes); - memset(pptr+1, '\0', rbytes); - } - } - offset += rbytes; - } - - /* clear up */ - if (offset > 0 && npass > 0) { - memset(passwords[i], '\0', offset); - } - - return i; -} - -#endif -/* ****************************************************************** * - * Copyright (c) Jan Rêkorajski 1999. - * Copyright (c) Andrew G. Morgan 1996-8. - * Copyright (c) Alex O. Yuriev, 1996. - * Copyright (c) Cristian Gafton 1996. - * Copyright (c) Red Hat, Inc. 1996, 2007, 2008. - * - * 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. - */ diff --git a/modules/pam_unix/passverify.h b/modules/pam_unix/passverify.h deleted file mode 100644 index e8e112d0..00000000 --- a/modules/pam_unix/passverify.h +++ /dev/null @@ -1,124 +0,0 @@ -/* - * Copyright information at end of file. - */ - -#include <sys/types.h> -#include <pwd.h> -#include <security/pam_modules.h> - -#define PAM_UNIX_RUN_HELPER PAM_CRED_INSUFFICIENT - -#define MAXPASS 200 /* the maximum length of a password */ - -#define OLD_PASSWORDS_FILE "/etc/security/opasswd" - -int -verify_pwd_hash(const char *p, char *hash, unsigned int nullok); - -int -is_pwd_shadowed(const struct passwd *pwd); - -char * -crypt_md5_wrapper(const char *pass_new); - -char * -create_password_hash(const char *password, unsigned int ctrl, int rounds); - -int -unix_selinux_confined(void); - -int -lock_pwdf(void); - -void -unlock_pwdf(void); - -int -save_old_password(const char *forwho, const char *oldpass, - int howmany); - -#ifdef HELPER_COMPILE -void -helper_log_err(int err, const char *format,...); - -int -helper_verify_password(const char *name, const char *p, int nullok); - -void -setup_signals(void); - -char * -getuidname(uid_t uid); - -int -read_passwords(int fd, int npass, char **passwords); - -int -get_account_info(const char *name, - struct passwd **pwd, struct spwd **spwdent); - -int -get_pwd_hash(const char *name, - struct passwd **pwd, char **hash); - -int -check_shadow_expiry(struct spwd *spent, int *daysleft); - -int -unix_update_passwd(const char *forwho, const char *towhat); - -int -unix_update_shadow(const char *forwho, char *towhat); -#else -int -get_account_info(pam_handle_t *pamh, const char *name, - struct passwd **pwd, struct spwd **spwdent); - -int -get_pwd_hash(pam_handle_t *pamh, const char *name, - struct passwd **pwd, char **hash); - -int -check_shadow_expiry(pam_handle_t *pamh, struct spwd *spent, int *daysleft); - -int -unix_update_passwd(pam_handle_t *pamh, const char *forwho, const char *towhat); - -int -unix_update_shadow(pam_handle_t *pamh, const char *forwho, char *towhat); -#endif - -/* ****************************************************************** * - * Copyright (c) Red Hat, Inc. 2007. - * - * 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. - */ diff --git a/modules/pam_unix/support.c b/modules/pam_unix/support.c deleted file mode 100644 index b82cad26..00000000 --- a/modules/pam_unix/support.c +++ /dev/null @@ -1,893 +0,0 @@ -/* - * Copyright information at end of file. - */ - -#include "config.h" - -#include <stdlib.h> -#include <unistd.h> -#include <stdarg.h> -#include <stdio.h> -#include <string.h> -#include <malloc.h> -#include <pwd.h> -#include <shadow.h> -#include <limits.h> -#include <utmp.h> -#include <errno.h> -#include <signal.h> -#include <ctype.h> -#include <syslog.h> -#include <sys/resource.h> -#include <rpcsvc/ypclnt.h> - -#include <security/_pam_macros.h> -#include <security/pam_modules.h> -#include <security/pam_ext.h> -#include <security/pam_modutil.h> - -#include "support.h" -#include "passverify.h" -#ifdef WITH_SELINUX -#include <selinux/selinux.h> -#define SELINUX_ENABLED is_selinux_enabled()>0 -#else -#define SELINUX_ENABLED 0 -#endif - -/* this is a front-end for module-application conversations */ - -int _make_remark(pam_handle_t * pamh, unsigned int ctrl, - int type, const char *text) -{ - int retval = PAM_SUCCESS; - - if (off(UNIX__QUIET, ctrl)) { - retval = pam_prompt(pamh, type, NULL, "%s", text); - } - return retval; -} - -/* - * set the control flags for the UNIX module. - */ - -int _set_ctrl(pam_handle_t *pamh, int flags, int *remember, int *rounds, - int argc, const char **argv) -{ - unsigned int ctrl; - - D(("called.")); - - ctrl = UNIX_DEFAULTS; /* the default selection of options */ - - /* set some flags manually */ - - if (getuid() == 0 && !(flags & PAM_CHANGE_EXPIRED_AUTHTOK)) { - D(("IAMROOT")); - set(UNIX__IAMROOT, ctrl); - } - if (flags & PAM_UPDATE_AUTHTOK) { - D(("UPDATE_AUTHTOK")); - set(UNIX__UPDATE, ctrl); - } - if (flags & PAM_PRELIM_CHECK) { - D(("PRELIM_CHECK")); - set(UNIX__PRELIM, ctrl); - } - if (flags & PAM_SILENT) { - D(("SILENT")); - set(UNIX__QUIET, ctrl); - } - /* now parse the arguments to this module */ - - while (argc-- > 0) { - int j; - - D(("pam_unix arg: %s", *argv)); - - for (j = 0; j < UNIX_CTRLS_; ++j) { - if (unix_args[j].token - && !strncmp(*argv, unix_args[j].token, strlen(unix_args[j].token))) { - break; - } - } - - if (j >= UNIX_CTRLS_) { - pam_syslog(pamh, LOG_ERR, - "unrecognized option [%s]", *argv); - } else { - ctrl &= unix_args[j].mask; /* for turning things off */ - ctrl |= unix_args[j].flag; /* for turning things on */ - - if (remember != NULL) { - if (j == UNIX_REMEMBER_PASSWD) { - *remember = strtol(*argv + 9, NULL, 10); - if ((*remember == INT_MIN) || (*remember == INT_MAX)) - *remember = -1; - if (*remember > 400) - *remember = 400; - } - } - if (rounds != NULL) { - if (j == UNIX_ALGO_ROUNDS) { - *rounds = strtol(*argv + 7, NULL, 10); - if ((*rounds < 1000) || (*rounds == INT_MAX)) - /* don't care about bogus values */ - unset(UNIX_ALGO_ROUNDS, ctrl); - if (*rounds >= 10000000) - *rounds = 9999999; - } - } - } - - ++argv; /* step to next argument */ - } - - if (flags & PAM_DISALLOW_NULL_AUTHTOK) { - D(("DISALLOW_NULL_AUTHTOK")); - set(UNIX__NONULL, ctrl); - } - - /* auditing is a more sensitive version of debug */ - - if (on(UNIX_AUDIT, ctrl)) { - set(UNIX_DEBUG, ctrl); - } - /* return the set of flags */ - - D(("done.")); - return ctrl; -} - -static void _cleanup(pam_handle_t * pamh UNUSED, void *x, int error_status UNUSED) -{ - _pam_delete(x); -} - -/* ************************************************************** * - * Useful non-trivial functions * - * ************************************************************** */ - - /* - * the following is used to keep track of the number of times a user fails - * to authenticate themself. - */ - -#define FAIL_PREFIX "-UN*X-FAIL-" -#define UNIX_MAX_RETRIES 3 - -struct _pam_failed_auth { - char *user; /* user that's failed to be authenticated */ - char *name; /* attempt from user with name */ - int uid; /* uid of calling user */ - int euid; /* euid of calling process */ - int count; /* number of failures so far */ -}; - -#ifndef PAM_DATA_REPLACE -#error "Need to get an updated libpam 0.52 or better" -#endif - -static void _cleanup_failures(pam_handle_t * pamh, void *fl, int err) -{ - int quiet; - const void *service = NULL; - const void *ruser = NULL; - const void *rhost = NULL; - const void *tty = NULL; - struct _pam_failed_auth *failure; - - D(("called")); - - quiet = err & PAM_DATA_SILENT; /* should we log something? */ - err &= PAM_DATA_REPLACE; /* are we just replacing data? */ - failure = (struct _pam_failed_auth *) fl; - - if (failure != NULL) { - - if (!quiet && !err) { /* under advisement from Sun,may go away */ - - /* log the number of authentication failures */ - if (failure->count > 1) { - (void) pam_get_item(pamh, PAM_SERVICE, - &service); - (void) pam_get_item(pamh, PAM_RUSER, - &ruser); - (void) pam_get_item(pamh, PAM_RHOST, - &rhost); - (void) pam_get_item(pamh, PAM_TTY, - &tty); - pam_syslog(pamh, LOG_NOTICE, - "%d more authentication failure%s; " - "logname=%s uid=%d euid=%d " - "tty=%s ruser=%s rhost=%s " - "%s%s", - failure->count - 1, failure->count == 2 ? "" : "s", - failure->name, failure->uid, failure->euid, - tty ? (const char *)tty : "", ruser ? (const char *)ruser : "", - rhost ? (const char *)rhost : "", - (failure->user && failure->user[0] != '\0') - ? " user=" : "", failure->user - ); - - if (failure->count > UNIX_MAX_RETRIES) { - pam_syslog(pamh, LOG_ALERT, - "service(%s) ignoring max retries; %d > %d", - service == NULL ? "**unknown**" : (const char *)service, - failure->count, - UNIX_MAX_RETRIES); - } - } - } - _pam_delete(failure->user); /* tidy up */ - _pam_delete(failure->name); /* tidy up */ - free(failure); - } -} - -/* - * _unix_getpwnam() searches only /etc/passwd and NIS to find user information - */ -static void _unix_cleanup(pam_handle_t *pamh UNUSED, void *data, int error_status UNUSED) -{ - free(data); -} - -int _unix_getpwnam(pam_handle_t *pamh, const char *name, - int files, int nis, struct passwd **ret) -{ - FILE *passwd; - char buf[16384]; - int matched = 0, buflen; - char *slogin, *spasswd, *suid, *sgid, *sgecos, *shome, *sshell, *p; - - memset(buf, 0, sizeof(buf)); - - if (!matched && files) { - int userlen = strlen(name); - passwd = fopen("/etc/passwd", "r"); - if (passwd != NULL) { - while (fgets(buf, sizeof(buf), passwd) != NULL) { - if ((buf[userlen] == ':') && - (strncmp(name, buf, userlen) == 0)) { - p = buf + strlen(buf) - 1; - while (isspace(*p) && (p >= buf)) { - *p-- = '\0'; - } - matched = 1; - break; - } - } - fclose(passwd); - } - } - - if (!matched && nis) { - char *userinfo = NULL, *domain = NULL; - int len = 0, i; - len = yp_get_default_domain(&domain); - if (len == YPERR_SUCCESS) { - len = yp_bind(domain); - } - if (len == YPERR_SUCCESS) { - i = yp_match(domain, "passwd.byname", name, - strlen(name), &userinfo, &len); - yp_unbind(domain); - if ((i == YPERR_SUCCESS) && ((size_t)len < sizeof(buf))) { - strncpy(buf, userinfo, sizeof(buf) - 1); - buf[sizeof(buf) - 1] = '\0'; - matched = 1; - } - } - } - - if (matched && (ret != NULL)) { - *ret = NULL; - - slogin = buf; - - spasswd = strchr(slogin, ':'); - if (spasswd == NULL) { - return matched; - } - *spasswd++ = '\0'; - - suid = strchr(spasswd, ':'); - if (suid == NULL) { - return matched; - } - *suid++ = '\0'; - - sgid = strchr(suid, ':'); - if (sgid == NULL) { - return matched; - } - *sgid++ = '\0'; - - sgecos = strchr(sgid, ':'); - if (sgecos == NULL) { - return matched; - } - *sgecos++ = '\0'; - - shome = strchr(sgecos, ':'); - if (shome == NULL) { - return matched; - } - *shome++ = '\0'; - - sshell = strchr(shome, ':'); - if (sshell == NULL) { - return matched; - } - *sshell++ = '\0'; - - buflen = sizeof(struct passwd) + - strlen(slogin) + 1 + - strlen(spasswd) + 1 + - strlen(suid) + 1 + - strlen(sgid) + 1 + - strlen(sgecos) + 1 + - strlen(shome) + 1 + - strlen(sshell) + 1; - *ret = malloc(buflen); - if (*ret == NULL) { - return matched; - } - memset(*ret, '\0', buflen); - - (*ret)->pw_uid = strtol(suid, &p, 10); - if ((strlen(suid) == 0) || (*p != '\0')) { - free(*ret); - *ret = NULL; - return matched; - } - - (*ret)->pw_gid = strtol(sgid, &p, 10); - if ((strlen(sgid) == 0) || (*p != '\0')) { - free(*ret); - *ret = NULL; - return matched; - } - - p = ((char*)(*ret)) + sizeof(struct passwd); - (*ret)->pw_name = strcpy(p, slogin); - p += strlen(p) + 1; - (*ret)->pw_passwd = strcpy(p, spasswd); - p += strlen(p) + 1; - (*ret)->pw_gecos = strcpy(p, sgecos); - p += strlen(p) + 1; - (*ret)->pw_dir = strcpy(p, shome); - p += strlen(p) + 1; - (*ret)->pw_shell = strcpy(p, sshell); - - snprintf(buf, sizeof(buf), "_pam_unix_getpwnam_%s", name); - - if (pam_set_data(pamh, buf, - *ret, _unix_cleanup) != PAM_SUCCESS) { - free(*ret); - *ret = NULL; - } - } - - return matched; -} - -/* - * _unix_comsefromsource() is a quick check to see if information about a given - * user comes from a particular source (just files and nis for now) - * - */ -int _unix_comesfromsource(pam_handle_t *pamh, - const char *name, int files, int nis) -{ - return _unix_getpwnam(pamh, name, files, nis, NULL); -} - -/* - * verify the password of a user - */ - -#include <sys/types.h> -#include <sys/wait.h> - -static int _unix_run_helper_binary(pam_handle_t *pamh, const char *passwd, - unsigned int ctrl, const char *user) -{ - int retval, child, fds[2]; - void (*sighandler)(int) = NULL; - - D(("called.")); - /* create a pipe for the password */ - if (pipe(fds) != 0) { - D(("could not make pipe")); - return PAM_AUTH_ERR; - } - - if (off(UNIX_NOREAP, ctrl)) { - /* - * This code arranges that the demise of the child does not cause - * the application to receive a signal it is not expecting - which - * may kill the application or worse. - * - * The "noreap" module argument is provided so that the admin can - * override this behavior. - */ - sighandler = signal(SIGCHLD, SIG_DFL); - } - - /* fork */ - child = fork(); - if (child == 0) { - int i=0; - struct rlimit rlim; - static char *envp[] = { NULL }; - char *args[] = { NULL, NULL, NULL, NULL }; - - /* XXX - should really tidy up PAM here too */ - - close(0); close(1); - /* reopen stdin as pipe */ - close(fds[1]); - dup2(fds[0], STDIN_FILENO); - - if (getrlimit(RLIMIT_NOFILE,&rlim)==0) { - for (i=2; i < (int)rlim.rlim_max; i++) { - if (fds[0] != i) - close(i); - } - } - - if (geteuid() == 0) { - /* must set the real uid to 0 so the helper will not error - out if pam is called from setuid binary (su, sudo...) */ - setuid(0); - } - - /* exec binary helper */ - args[0] = strdup(CHKPWD_HELPER); - args[1] = x_strdup(user); - if (off(UNIX__NONULL, ctrl)) { /* this means we've succeeded */ - args[2]=strdup("nullok"); - } else { - args[2]=strdup("nonull"); - } - - execve(CHKPWD_HELPER, args, envp); - - /* should not get here: exit with error */ - D(("helper binary is not available")); - exit(PAM_AUTHINFO_UNAVAIL); - } else if (child > 0) { - /* wait for child */ - /* if the stored password is NULL */ - int rc=0; - if (passwd != NULL) { /* send the password to the child */ - write(fds[1], passwd, strlen(passwd)+1); - passwd = NULL; - } else { - write(fds[1], "", 1); /* blank password */ - } - close(fds[0]); /* close here to avoid possible SIGPIPE above */ - close(fds[1]); - rc=waitpid(child, &retval, 0); /* wait for helper to complete */ - if (rc<0) { - pam_syslog(pamh, LOG_ERR, "unix_chkpwd waitpid returned %d: %m", rc); - retval = PAM_AUTH_ERR; - } else { - retval = WEXITSTATUS(retval); - } - } else { - D(("fork failed")); - close(fds[0]); - close(fds[1]); - retval = PAM_AUTH_ERR; - } - - if (sighandler != SIG_ERR) { - (void) signal(SIGCHLD, sighandler); /* restore old signal handler */ - } - - D(("returning %d", retval)); - return retval; -} - -/* - * _unix_blankpasswd() is a quick check for a blank password - * - * returns TRUE if user does not have a password - * - to avoid prompting for one in such cases (CG) - */ - -int -_unix_blankpasswd (pam_handle_t *pamh, unsigned int ctrl, const char *name) -{ - struct passwd *pwd = NULL; - char *salt = NULL; - int retval; - - D(("called")); - - /* - * This function does not have to be too smart if something goes - * wrong, return FALSE and let this case to be treated somewhere - * else (CG) - */ - - if (on(UNIX__NONULL, ctrl)) - return 0; /* will fail but don't let on yet */ - - /* UNIX passwords area */ - - retval = get_pwd_hash(pamh, name, &pwd, &salt); - - if (retval == PAM_UNIX_RUN_HELPER) { - /* salt will not be set here so we can return immediately */ - if (_unix_run_helper_binary(pamh, NULL, ctrl, name) == PAM_SUCCESS) - return 1; - else - return 0; - } - - /* Does this user have a password? */ - if (salt == NULL) { - retval = 0; - } else { - if (strlen(salt) == 0) - retval = 1; - else - retval = 0; - } - - /* tidy up */ - - if (salt) - _pam_delete(salt); - - return retval; -} - -int _unix_verify_password(pam_handle_t * pamh, const char *name - ,const char *p, unsigned int ctrl) -{ - struct passwd *pwd = NULL; - char *salt = NULL; - char *data_name; - int retval; - - - D(("called")); - -#ifdef HAVE_PAM_FAIL_DELAY - if (off(UNIX_NODELAY, ctrl)) { - D(("setting delay")); - (void) pam_fail_delay(pamh, 2000000); /* 2 sec delay for on failure */ - } -#endif - - /* locate the entry for this user */ - - D(("locating user's record")); - - retval = get_pwd_hash(pamh, name, &pwd, &salt); - - data_name = (char *) malloc(sizeof(FAIL_PREFIX) + strlen(name)); - if (data_name == NULL) { - pam_syslog(pamh, LOG_CRIT, "no memory for data-name"); - } else { - strcpy(data_name, FAIL_PREFIX); - strcpy(data_name + sizeof(FAIL_PREFIX) - 1, name); - } - - if (retval != PAM_SUCCESS) { - if (retval == PAM_UNIX_RUN_HELPER) { - D(("running helper binary")); - retval = _unix_run_helper_binary(pamh, p, ctrl, name); - } else { - D(("user's record unavailable")); - p = NULL; - if (on(UNIX_AUDIT, ctrl)) { - /* this might be a typo and the user has given a password - instead of a username. Careful with this. */ - pam_syslog(pamh, LOG_WARNING, - "check pass; user (%s) unknown", name); - } else { - name = NULL; - if (on(UNIX_DEBUG, ctrl) || pwd == NULL) { - pam_syslog(pamh, LOG_WARNING, - "check pass; user unknown"); - } else { - /* don't log failure as another pam module can succeed */ - goto cleanup; - } - } - } - } else { - retval = verify_pwd_hash(p, salt, off(UNIX__NONULL, ctrl)); - } - - if (retval == PAM_SUCCESS) { - if (data_name) /* reset failures */ - pam_set_data(pamh, data_name, NULL, _cleanup_failures); - } else { - if (data_name != NULL) { - struct _pam_failed_auth *new = NULL; - const struct _pam_failed_auth *old = NULL; - - /* get a failure recorder */ - - new = (struct _pam_failed_auth *) - malloc(sizeof(struct _pam_failed_auth)); - - if (new != NULL) { - - const char *login_name; - const void *void_old; - - - login_name = pam_modutil_getlogin(pamh); - if (login_name == NULL) { - login_name = ""; - } - - new->user = x_strdup(name ? name : ""); - new->uid = getuid(); - new->euid = geteuid(); - new->name = x_strdup(login_name); - - /* any previous failures for this user ? */ - if (pam_get_data(pamh, data_name, &void_old) - == PAM_SUCCESS) - old = void_old; - else - old = NULL; - - if (old != NULL) { - new->count = old->count + 1; - if (new->count >= UNIX_MAX_RETRIES) { - retval = PAM_MAXTRIES; - } - } else { - const void *service=NULL; - const void *ruser=NULL; - const void *rhost=NULL; - const void *tty=NULL; - - (void) pam_get_item(pamh, PAM_SERVICE, - &service); - (void) pam_get_item(pamh, PAM_RUSER, - &ruser); - (void) pam_get_item(pamh, PAM_RHOST, - &rhost); - (void) pam_get_item(pamh, PAM_TTY, - &tty); - - pam_syslog(pamh, LOG_NOTICE, - "authentication failure; " - "logname=%s uid=%d euid=%d " - "tty=%s ruser=%s rhost=%s " - "%s%s", - new->name, new->uid, new->euid, - tty ? (const char *)tty : "", - ruser ? (const char *)ruser : "", - rhost ? (const char *)rhost : "", - (new->user && new->user[0] != '\0') - ? " user=" : "", - new->user - ); - new->count = 1; - } - - pam_set_data(pamh, data_name, new, _cleanup_failures); - - } else { - pam_syslog(pamh, LOG_CRIT, - "no memory for failure recorder"); - } - } - } - -cleanup: - if (data_name) - _pam_delete(data_name); - if (salt) - _pam_delete(salt); - - D(("done [%d].", retval)); - - return retval; -} - -/* - * obtain a password from the user - */ - -int _unix_read_password(pam_handle_t * pamh - ,unsigned int ctrl - ,const char *comment - ,const char *prompt1 - ,const char *prompt2 - ,const char *data_name - ,const void **pass) -{ - int authtok_flag; - int retval = PAM_SUCCESS; - char *token; - - D(("called")); - - /* - * make sure nothing inappropriate gets returned - */ - - *pass = token = NULL; - - /* - * which authentication token are we getting? - */ - - authtok_flag = on(UNIX__OLD_PASSWD, ctrl) ? PAM_OLDAUTHTOK : PAM_AUTHTOK; - - /* - * should we obtain the password from a PAM item ? - */ - - if (on(UNIX_TRY_FIRST_PASS, ctrl) || on(UNIX_USE_FIRST_PASS, ctrl)) { - retval = pam_get_item(pamh, authtok_flag, pass); - if (retval != PAM_SUCCESS) { - /* very strange. */ - pam_syslog(pamh, LOG_ALERT, - "pam_get_item returned error to unix-read-password" - ); - 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; - } - } - /* - * getting here implies we will have to get the password from the - * user directly. - */ - - { - int replies=1; - char *resp[2] = { NULL, NULL }; - - if (comment != NULL && off(UNIX__QUIET, ctrl)) { - retval = pam_info(pamh, "%s", comment); - } - - if (retval == PAM_SUCCESS) { - retval = pam_prompt(pamh, PAM_PROMPT_ECHO_OFF, - &resp[0], "%s", prompt1); - - if (retval == PAM_SUCCESS && prompt2 != NULL) { - retval = pam_prompt(pamh, PAM_PROMPT_ECHO_OFF, - &resp[1], "%s", prompt2); - ++replies; - } - } - - if (resp[0] != NULL && resp[replies-1] != NULL) { - /* interpret the response */ - - if (retval == PAM_SUCCESS) { /* a good conversation */ - - token = resp[0]; - if (token != NULL) { - if (replies == 2) { - /* verify that password entered correctly */ - if (strcmp(token, resp[replies - 1])) { - /* mistyped */ - retval = PAM_AUTHTOK_RECOVERY_ERR; - _make_remark(pamh, ctrl, - PAM_ERROR_MSG, MISTYPED_PASS); - } - } - } else { - pam_syslog(pamh, LOG_NOTICE, - "could not recover authentication token"); - } - - } - - } else { - retval = (retval == PAM_SUCCESS) - ? PAM_AUTHTOK_RECOVERY_ERR : retval; - } - - resp[0] = NULL; - if (replies > 1) - _pam_delete(resp[1]); - } - - if (retval != PAM_SUCCESS) { - _pam_delete(token); - - if (on(UNIX_DEBUG, ctrl)) - pam_syslog(pamh, LOG_DEBUG, - "unable to obtain a password"); - return retval; - } - /* 'token' is the entered password */ - - if (off(UNIX_NOT_SET_PASS, ctrl)) { - - /* we store this password as an item */ - - retval = pam_set_item(pamh, authtok_flag, token); - _pam_delete(token); /* clean it up */ - if (retval != PAM_SUCCESS - || (retval = pam_get_item(pamh, authtok_flag, pass)) - != PAM_SUCCESS) { - - *pass = NULL; - pam_syslog(pamh, LOG_CRIT, "error manipulating password"); - return retval; - - } - } else { - /* - * then store it as data specific to this module. pam_end() - * will arrange to clean it up. - */ - - retval = pam_set_data(pamh, data_name, (void *) token, _cleanup); - if (retval != PAM_SUCCESS) { - pam_syslog(pamh, LOG_CRIT, - "error manipulating password data [%s]", - pam_strerror(pamh, retval)); - _pam_delete(token); - return retval; - } - *pass = token; - token = NULL; /* break link to password */ - } - - return PAM_SUCCESS; -} - -/* ****************************************************************** * - * Copyright (c) Jan Rêkorajski 1999. - * Copyright (c) Andrew G. Morgan 1996-8. - * Copyright (c) Alex O. Yuriev, 1996. - * Copyright (c) Cristian Gafton 1996. - * Copyright (c) Red Hat, Inc. 2007. - * - * 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. - */ diff --git a/modules/pam_unix/support.h b/modules/pam_unix/support.h deleted file mode 100644 index 9d4f8b85..00000000 --- a/modules/pam_unix/support.h +++ /dev/null @@ -1,162 +0,0 @@ -/* - * $Id$ - */ - -#ifndef _PAM_UNIX_SUPPORT_H -#define _PAM_UNIX_SUPPORT_H - -#include <pwd.h> - -/* - * here is the string to inform the user that the new passwords they - * typed were not the same. - */ - -#define MISTYPED_PASS "Sorry, passwords do not match" - -/* type definition for the control options */ - -typedef struct { - const char *token; - unsigned int mask; /* shall assume 32 bits of flags */ - unsigned int flag; -} UNIX_Ctrls; - -/* - * macro to determine if a given flag is on - */ - -#define on(x,ctrl) (unix_args[x].flag & ctrl) - -/* - * macro to determine that a given flag is NOT on - */ - -#define off(x,ctrl) (!on(x,ctrl)) - -/* - * macro to turn on/off a ctrl flag manually - */ - -#define set(x,ctrl) (ctrl = ((ctrl)&unix_args[x].mask)|unix_args[x].flag) -#define unset(x,ctrl) (ctrl &= ~(unix_args[x].flag)) - -/* the generic mask */ - -#define _ALL_ON_ (~0U) - -/* end of macro definitions definitions for the control flags */ - -/* ****************************************************************** * - * ctrl flags proper.. - */ - -/* - * here are the various options recognized by the unix module. They - * are enumerated here and then defined below. Internal arguments are - * given NULL tokens. - */ - -#define UNIX__OLD_PASSWD 0 /* internal */ -#define UNIX__VERIFY_PASSWD 1 /* internal */ -#define UNIX__IAMROOT 2 /* internal */ - -#define UNIX_AUDIT 3 /* print more things than debug.. - some information may be sensitive */ -#define UNIX_USE_FIRST_PASS 4 -#define UNIX_TRY_FIRST_PASS 5 -#define UNIX_NOT_SET_PASS 6 /* don't set the AUTHTOK items */ - -#define UNIX__PRELIM 7 /* internal */ -#define UNIX__UPDATE 8 /* internal */ -#define UNIX__NONULL 9 /* internal */ -#define UNIX__QUIET 10 /* internal */ -#define UNIX_USE_AUTHTOK 11 /* insist on reading PAM_AUTHTOK */ -#define UNIX_SHADOW 12 /* signal shadow on */ -#define UNIX_MD5_PASS 13 /* force the use of MD5 passwords */ -#define UNIX__NULLOK 14 /* Null token ok */ -#define UNIX_DEBUG 15 /* send more info to syslog(3) */ -#define UNIX_NODELAY 16 /* admin does not want a fail-delay */ -#define UNIX_NIS 17 /* wish to use NIS for pwd */ -#define UNIX_BIGCRYPT 18 /* use DEC-C2 crypt()^x function */ -#define UNIX_LIKE_AUTH 19 /* need to auth for setcred to work */ -#define UNIX_REMEMBER_PASSWD 20 /* Remember N previous passwords */ -#define UNIX_NOREAP 21 /* don't reap child process */ -#define UNIX_BROKEN_SHADOW 22 /* ignore errors reading password aging - * information during acct management */ -#define UNIX_SHA256_PASS 23 /* new password hashes will use SHA256 */ -#define UNIX_SHA512_PASS 24 /* new password hashes will use SHA512 */ -#define UNIX_ALGO_ROUNDS 25 /* optional number of rounds for new - password hash algorithms */ -/* -------------- */ -#define UNIX_CTRLS_ 26 /* number of ctrl arguments defined */ - - -static const UNIX_Ctrls unix_args[UNIX_CTRLS_] = -{ -/* symbol token name ctrl mask ctrl * - * ----------------------- ------------------- --------------------- -------- */ - -/* UNIX__OLD_PASSWD */ {NULL, _ALL_ON_, 01}, -/* UNIX__VERIFY_PASSWD */ {NULL, _ALL_ON_, 02}, -/* UNIX__IAMROOT */ {NULL, _ALL_ON_, 04}, -/* UNIX_AUDIT */ {"audit", _ALL_ON_, 010}, -/* UNIX_USE_FIRST_PASS */ {"use_first_pass", _ALL_ON_^(060), 020}, -/* UNIX_TRY_FIRST_PASS */ {"try_first_pass", _ALL_ON_^(060), 040}, -/* UNIX_NOT_SET_PASS */ {"not_set_pass", _ALL_ON_, 0100}, -/* UNIX__PRELIM */ {NULL, _ALL_ON_^(0600), 0200}, -/* UNIX__UPDATE */ {NULL, _ALL_ON_^(0600), 0400}, -/* UNIX__NONULL */ {NULL, _ALL_ON_, 01000}, -/* UNIX__QUIET */ {NULL, _ALL_ON_, 02000}, -/* UNIX_USE_AUTHTOK */ {"use_authtok", _ALL_ON_, 04000}, -/* UNIX_SHADOW */ {"shadow", _ALL_ON_, 010000}, -/* UNIX_MD5_PASS */ {"md5", _ALL_ON_^(0400000), 020000}, -/* UNIX__NULLOK */ {"nullok", _ALL_ON_^(01000), 0}, -/* UNIX_DEBUG */ {"debug", _ALL_ON_, 040000}, -/* UNIX_NODELAY */ {"nodelay", _ALL_ON_, 0100000}, -/* UNIX_NIS */ {"nis", _ALL_ON_, 0200000}, -/* UNIX_BIGCRYPT */ {"bigcrypt", _ALL_ON_^(020000), 0400000}, -/* UNIX_LIKE_AUTH */ {"likeauth", _ALL_ON_, 01000000}, -/* UNIX_REMEMBER_PASSWD */ {"remember=", _ALL_ON_, 02000000}, -/* UNIX_NOREAP */ {"noreap", _ALL_ON_, 04000000}, -/* UNIX_BROKEN_SHADOW */ {"broken_shadow", _ALL_ON_, 010000000}, -/* UNIX_SHA256_PASS */ {"sha256", _ALL_ON_^(040420000), 020000000}, -/* UNIX_SHA512_PASS */ {"sha512", _ALL_ON_^(020420000), 040000000}, -/* UNIX_ALGO_ROUNDS */ {"rounds=", _ALL_ON_, 0100000000}, -}; - -#define UNIX_DEFAULTS (unix_args[UNIX__NONULL].flag) - - -/* use this to free strings. ESPECIALLY password strings */ - -#define _pam_delete(xx) \ -{ \ - _pam_overwrite(xx); \ - _pam_drop(xx); \ -} - -extern int _make_remark(pam_handle_t * pamh, unsigned int ctrl - ,int type, const char *text); -extern int _set_ctrl(pam_handle_t * pamh, int flags, int *remember, int *rounds, - int argc, const char **argv); -extern int _unix_getpwnam (pam_handle_t *pamh, - const char *name, int files, int nis, - struct passwd **ret); -extern int _unix_comesfromsource (pam_handle_t *pamh, - const char *name, int files, int nis); -extern int _unix_blankpasswd(pam_handle_t *pamh,unsigned int ctrl, - const char *name); -extern int _unix_verify_password(pam_handle_t * pamh, const char *name - ,const char *p, unsigned int ctrl); -extern int _unix_read_password(pam_handle_t * pamh - ,unsigned int ctrl - ,const char *comment - ,const char *prompt1 - ,const char *prompt2 - ,const char *data_name - ,const void **pass); - -extern int _unix_run_verify_binary(pam_handle_t *pamh, - unsigned int ctrl, const char *user, int *daysleft); -#endif /* _PAM_UNIX_SUPPORT_H */ diff --git a/modules/pam_unix/tst-pam_unix b/modules/pam_unix/tst-pam_unix deleted file mode 100755 index 22922800..00000000 --- a/modules/pam_unix/tst-pam_unix +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/sh -../../tests/tst-dlopen .libs/pam_unix.so diff --git a/modules/pam_unix/unix_chkpwd.8.xml b/modules/pam_unix/unix_chkpwd.8.xml deleted file mode 100644 index a10dbe33..00000000 --- a/modules/pam_unix/unix_chkpwd.8.xml +++ /dev/null @@ -1,67 +0,0 @@ -<?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="unix_chkpwd"> - - <refmeta> - <refentrytitle>unix_chkpwd</refentrytitle> - <manvolnum>8</manvolnum> - <refmiscinfo class="sectdesc">Linux-PAM Manual</refmiscinfo> - </refmeta> - - <refnamediv id="unix_chkpwd-name"> - <refname>unix_chkpwd</refname> - <refpurpose>Helper binary that verifies the password of the current user</refpurpose> - </refnamediv> - - <refsynopsisdiv> - <cmdsynopsis id="unix_chkpwd-cmdsynopsis"> - <command>unix_chkpwd</command> - <arg choice="opt"> - ... - </arg> - </cmdsynopsis> - </refsynopsisdiv> - - <refsect1 id="unix_chkpwd-description"> - - <title>DESCRIPTION</title> - - <para> - <emphasis>unix_chkpwd</emphasis> is a helper program for the - <emphasis>pam_unix</emphasis> module that verifies the - password of the current user. It also checks password and account - expiration dates in <emphasis>shadow</emphasis>. It is not intended to - be run directly from the command line and logs a security violation if - done so. - </para> - - <para> - It is typically installed setuid root or setgid shadow. - </para> - - <para> - The interface of the helper - command line options, and input/output - data format are internal to the <emphasis>pam_unix</emphasis> - module and it should not be called directly from applications. - </para> - </refsect1> - - <refsect1 id='unix_chkpwd-see_also'> - <title>SEE ALSO</title> - <para> - <citerefentry> - <refentrytitle>pam_unix</refentrytitle><manvolnum>8</manvolnum> - </citerefentry> - </para> - </refsect1> - - <refsect1 id='unix_chkpwd-author'> - <title>AUTHOR</title> - <para> - Written by Andrew Morgan and other various people. - </para> - </refsect1> - -</refentry> diff --git a/modules/pam_unix/unix_chkpwd.c b/modules/pam_unix/unix_chkpwd.c deleted file mode 100644 index 11ac3aac..00000000 --- a/modules/pam_unix/unix_chkpwd.c +++ /dev/null @@ -1,184 +0,0 @@ -/* - * This program is designed to run setuid(root) or with sufficient - * privilege to read all of the unix password databases. It is designed - * to provide a mechanism for the current user (defined by this - * process' uid) to verify their own password. - * - * The password is read from the standard input. The exit status of - * this program indicates whether the user is authenticated or not. - * - * Copyright information is located at the end of the file. - * - */ - -#include "config.h" - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <syslog.h> -#include <unistd.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <pwd.h> -#include <shadow.h> -#include <signal.h> -#include <time.h> - -#include <security/_pam_types.h> -#include <security/_pam_macros.h> - -#include "passverify.h" - -static int _check_expiry(const char *uname) -{ - struct spwd *spent; - struct passwd *pwent; - int retval; - int daysleft; - - retval = get_account_info(uname, &pwent, &spent); - if (retval != PAM_SUCCESS) { - helper_log_err(LOG_ALERT, "could not obtain user info (%s)", uname); - printf("-1\n"); - return retval; - } - - if (spent == NULL) { - printf("-1\n"); - return retval; - } - - retval = check_shadow_expiry(spent, &daysleft); - printf("%d\n", daysleft); - return retval; -} - -int main(int argc, char *argv[]) -{ - char pass[MAXPASS + 1]; - char *option; - int npass, nullok; - int blankpass = 0; - int retval = PAM_AUTH_ERR; - char *user; - char *passwords[] = { pass }; - - /* - * Catch or ignore as many signal as possible. - */ - setup_signals(); - - /* - * we establish that this program is running with non-tty stdin. - * this is to discourage casual use. It does *NOT* prevent an - * intruder from repeatadly running this program to determine the - * password of the current user (brute force attack, but one for - * which the attacker must already have gained access to the user's - * account). - */ - - if (isatty(STDIN_FILENO) || argc != 3 ) { - helper_log_err(LOG_NOTICE - ,"inappropriate use of Unix helper binary [UID=%d]" - ,getuid()); - fprintf(stderr - ,"This binary is not designed for running in this way\n" - "-- the system administrator has been informed\n"); - sleep(10); /* this should discourage/annoy the user */ - return PAM_SYSTEM_ERR; - } - - /* - * Determine what the current user's name is. - * We must thus skip the check if the real uid is 0. - */ - if (getuid() == 0) { - user=argv[1]; - } - else { - user = getuidname(getuid()); - /* if the caller specifies the username, verify that user - matches it */ - if (strcmp(user, argv[1])) { - return PAM_AUTH_ERR; - } - } - - option=argv[2]; - - if (strcmp(option, "chkexpiry") == 0) - /* Check account information from the shadow file */ - return _check_expiry(argv[1]); - /* read the nullok/nonull option */ - else if (strcmp(option, "nullok") == 0) - nullok = 1; - else if (strcmp(option, "nonull") == 0) - nullok = 0; - else - return PAM_SYSTEM_ERR; - - /* read the password from stdin (a pipe from the pam_unix module) */ - - npass = read_passwords(STDIN_FILENO, 1, passwords); - - if (npass != 1) { /* is it a valid password? */ - helper_log_err(LOG_DEBUG, "no password supplied"); - *pass = '\0'; - } - - if (*pass == '\0') { - blankpass = 1; - } - - retval = helper_verify_password(user, pass, nullok); - - memset(pass, '\0', MAXPASS); /* clear memory of the password */ - - /* return pass or fail */ - - if (retval != PAM_SUCCESS) { - if (!nullok || !blankpass) - /* no need to log blank pass test */ - helper_log_err(LOG_NOTICE, "password check failed for user (%s)", user); - return PAM_AUTH_ERR; - } else { - return PAM_SUCCESS; - } -} - -/* - * Copyright (c) Andrew G. Morgan, 1996. All rights reserved - * Copyright (c) Red Hat, Inc., 2007,2008. All rights reserved - * - * 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. - */ diff --git a/modules/pam_unix/unix_update.8.xml b/modules/pam_unix/unix_update.8.xml deleted file mode 100644 index 07695951..00000000 --- a/modules/pam_unix/unix_update.8.xml +++ /dev/null @@ -1,67 +0,0 @@ -<?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="unix_update"> - - <refmeta> - <refentrytitle>unix_update</refentrytitle> - <manvolnum>8</manvolnum> - <refmiscinfo class="sectdesc">Linux-PAM Manual</refmiscinfo> - </refmeta> - - <refnamediv id="unix_update-name"> - <refname>unix_update</refname> - <refpurpose>Helper binary that updates the password of a given user</refpurpose> - </refnamediv> - - <refsynopsisdiv> - <cmdsynopsis id="unix_update-cmdsynopsis"> - <command>unix_update</command> - <arg choice="opt"> - ... - </arg> - </cmdsynopsis> - </refsynopsisdiv> - - <refsect1 id="unix_update-description"> - - <title>DESCRIPTION</title> - - <para> - <emphasis>unix_update</emphasis> is a helper program for the - <emphasis>pam_unix</emphasis> module that updates the - password of a given user. It is not intended to be run directly - from the command line and logs a security violation if done so. - </para> - - <para> - The purpose of the helper is to enable tighter confinement of - login and password changing services. The helper is thus called only - when SELinux is enabled and in the enforcing mode on the system. - </para> - - <para> - The interface of the helper - command line options, and input/output - data format are internal to the <emphasis>pam_unix</emphasis> - module and it should not be called directly from applications. - </para> - </refsect1> - - <refsect1 id='unix_update-see_also'> - <title>SEE ALSO</title> - <para> - <citerefentry> - <refentrytitle>pam_unix</refentrytitle><manvolnum>8</manvolnum> - </citerefentry> - </para> - </refsect1> - - <refsect1 id='unix_update-author'> - <title>AUTHOR</title> - <para> - Written by Tomas Mraz and other various people. - </para> - </refsect1> - -</refentry> diff --git a/modules/pam_unix/unix_update.c b/modules/pam_unix/unix_update.c deleted file mode 100644 index 595b7f8b..00000000 --- a/modules/pam_unix/unix_update.c +++ /dev/null @@ -1,187 +0,0 @@ -/* - * This program is designed to run setuid(root) or with sufficient - * privilege to read all of the unix password databases. It is designed - * to provide a mechanism for the current user (defined by this - * process' uid) to verify their own password. - * - * The password is read from the standard input. The exit status of - * this program indicates whether the user is authenticated or not. - * - * Copyright information is located at the end of the file. - * - */ - -#include "config.h" - -#include <stdarg.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <syslog.h> -#include <unistd.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <pwd.h> -#include <shadow.h> -#include <signal.h> -#include <time.h> -#include <sys/time.h> - -#include <security/_pam_types.h> -#include <security/_pam_macros.h> - -#include "passverify.h" - -static int -set_password(const char *forwho, const char *shadow, const char *remember) -{ - struct passwd *pwd = NULL; - int retval; - char pass[MAXPASS + 1]; - char towhat[MAXPASS + 1]; - int npass = 0; - /* we don't care about number format errors because the helper - should be called internally only */ - int doshadow = atoi(shadow); - int nremember = atoi(remember); - char *passwords[] = { pass, towhat }; - - /* read the password from stdin (a pipe from the pam_unix module) */ - - npass = read_passwords(STDIN_FILENO, 2, passwords); - - if (npass != 2) { /* is it a valid password? */ - if (npass == 1) { - helper_log_err(LOG_DEBUG, "no new password supplied"); - memset(pass, '\0', MAXPASS); - } else { - helper_log_err(LOG_DEBUG, "no valid passwords supplied"); - } - return PAM_AUTHTOK_ERR; - } - - if (lock_pwdf() != PAM_SUCCESS) - return PAM_AUTHTOK_LOCK_BUSY; - - pwd = getpwnam(forwho); - - if (pwd == NULL) { - retval = PAM_USER_UNKNOWN; - goto done; - } - - /* does pass agree with the official one? - we always allow change from null pass */ - retval = helper_verify_password(forwho, pass, 1); - if (retval != PAM_SUCCESS) { - goto done; - } - - /* first, save old password */ - if (save_old_password(forwho, pass, nremember)) { - retval = PAM_AUTHTOK_ERR; - goto done; - } - - if (doshadow || is_pwd_shadowed(pwd)) { - retval = unix_update_shadow(forwho, towhat); - if (retval == PAM_SUCCESS) - if (!is_pwd_shadowed(pwd)) - retval = unix_update_passwd(forwho, "x"); - } else { - retval = unix_update_passwd(forwho, towhat); - } - -done: - memset(pass, '\0', MAXPASS); - memset(towhat, '\0', MAXPASS); - - unlock_pwdf(); - - if (retval == PAM_SUCCESS) { - return PAM_SUCCESS; - } else { - return PAM_AUTHTOK_ERR; - } -} - -int main(int argc, char *argv[]) -{ - char *option; - - /* - * Catch or ignore as many signal as possible. - */ - setup_signals(); - - /* - * we establish that this program is running with non-tty stdin. - * this is to discourage casual use. It does *NOT* prevent an - * intruder from repeatadly running this program to determine the - * password of the current user (brute force attack, but one for - * which the attacker must already have gained access to the user's - * account). - */ - - if (isatty(STDIN_FILENO) || argc != 5 ) { - helper_log_err(LOG_NOTICE - ,"inappropriate use of Unix helper binary [UID=%d]" - ,getuid()); - fprintf(stderr - ,"This binary is not designed for running in this way\n" - "-- the system administrator has been informed\n"); - sleep(10); /* this should discourage/annoy the user */ - return PAM_SYSTEM_ERR; - } - - /* We must be root to read/update shadow. - */ - if (geteuid() != 0) { - return PAM_CRED_INSUFFICIENT; - } - - option = argv[2]; - - if (strcmp(option, "update") == 0) { - /* Attempting to change the password */ - return set_password(argv[1], argv[3], argv[4]); - } - - return PAM_SYSTEM_ERR; -} - -/* - * Copyright (c) Andrew G. Morgan, 1996. All rights reserved - * Copyright (c) Red Hat, Inc., 2007, 2008. All rights reserved - * - * 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. - */ diff --git a/modules/pam_unix/yppasswd.h b/modules/pam_unix/yppasswd.h deleted file mode 100644 index 6b414be0..00000000 --- a/modules/pam_unix/yppasswd.h +++ /dev/null @@ -1,51 +0,0 @@ -/* - * yppasswdd - * Copyright 1994, 1995, 1996 Olaf Kirch, <okir@monad.swb.de> - * - * This program is covered by the GNU General Public License, version 2. - * It is provided in the hope that it is useful. However, the author - * disclaims ALL WARRANTIES, expressed or implied. See the GPL for details. - * - * This file was generated automatically by rpcgen from yppasswd.x, and - * editied manually. - */ - -#ifndef _YPPASSWD_H_ -#define _YPPASSWD_H_ - -#define YPPASSWDPROG ((u_long)100009) -#define YPPASSWDVERS ((u_long)1) -#define YPPASSWDPROC_UPDATE ((u_long)1) - -/* - * The password struct passed by the update call. I renamed it to - * xpasswd to avoid a type clash with the one defined in <pwd.h>. - */ -#ifndef __sgi -typedef struct xpasswd { - char *pw_name; - char *pw_passwd; - int pw_uid; - int pw_gid; - char *pw_gecos; - char *pw_dir; - char *pw_shell; -} xpasswd; - -#else -#include <pwd.h> -typedef struct xpasswd xpasswd; -#endif - -/* The updated password information, plus the old password. - */ -typedef struct yppasswd { - char *oldpass; - xpasswd newpw; -} yppasswd; - -/* XDR encoding/decoding routines */ -bool_t xdr_xpasswd(XDR * xdrs, xpasswd * objp); -bool_t xdr_yppasswd(XDR * xdrs, yppasswd * objp); - -#endif /* _YPPASSWD_H_ */ diff --git a/modules/pam_unix/yppasswd_xdr.c b/modules/pam_unix/yppasswd_xdr.c deleted file mode 100644 index bf3f2fc6..00000000 --- a/modules/pam_unix/yppasswd_xdr.c +++ /dev/null @@ -1,38 +0,0 @@ -/* - * yppasswdd - * Copyright 1994, 1995, 1996 Olaf Kirch, <okir@monad.swb.de> - * - * This program is covered by the GNU General Public License, version 2. - * It is provided in the hope that it is useful. However, the author - * disclaims ALL WARRANTIES, expressed or implied. See the GPL for details. - * - * This file was generated automatically by rpcgen from yppasswd.x, and - * editied manually. - */ - -#include "config.h" - -#include <rpc/rpc.h> -#include <rpcsvc/yp_prot.h> -#include <rpcsvc/ypclnt.h> -#include "yppasswd.h" - -bool_t -xdr_xpasswd(XDR * xdrs, xpasswd * objp) -{ - return xdr_string(xdrs, &objp->pw_name, ~0) - && xdr_string(xdrs, &objp->pw_passwd, ~0) - && xdr_int(xdrs, &objp->pw_uid) - && xdr_int(xdrs, &objp->pw_gid) - && xdr_string(xdrs, &objp->pw_gecos, ~0) - && xdr_string(xdrs, &objp->pw_dir, ~0) - && xdr_string(xdrs, &objp->pw_shell, ~0); -} - - -bool_t -xdr_yppasswd(XDR * xdrs, yppasswd * objp) -{ - return xdr_string(xdrs, &objp->oldpass, ~0) - && xdr_xpasswd(xdrs, &objp->newpw); -} diff --git a/modules/pam_userdb/.cvsignore b/modules/pam_userdb/.cvsignore deleted file mode 100644 index ca9670ba..00000000 --- a/modules/pam_userdb/.cvsignore +++ /dev/null @@ -1,8 +0,0 @@ -*.la -*.lo -.deps -.libs -Makefile -Makefile.in -README -pam_userdb.8 diff --git a/modules/pam_userdb/Makefile.am b/modules/pam_userdb/Makefile.am deleted file mode 100644 index a442ef83..00000000 --- a/modules/pam_userdb/Makefile.am +++ /dev/null @@ -1,34 +0,0 @@ -# -# Copyright (c) 2005, 2006 Thorsten Kukuk <kukuk@suse.de> -# - -CLEANFILES = *~ - -EXTRA_DIST = README $(MANS) $(XMLS) create.pl tst-pam_userdb - -man_MANS = pam_userdb.8 -XMLS = README.xml pam_userdb.8.xml - -securelibdir = $(SECUREDIR) -secureconfdir = $(SCONFIGDIR) - -AM_CFLAGS = -I$(top_srcdir)/libpam/include -I$(top_srcdir)/libpamc/include -AM_LDFLAGS = -no-undefined -avoid-version -module \ - -L$(top_builddir)/libpam -lpam @LIBDB@ @LIBCRYPT@ -if HAVE_VERSIONING - AM_LDFLAGS += -Wl,--version-script=$(srcdir)/../modules.map -endif - -if HAVE_LIBDB - securelib_LTLIBRARIES = pam_userdb.la - TESTS = tst-pam_userdb -endif - -noinst_HEADERS = pam_userdb.h - -if ENABLE_REGENERATE_MAN -noinst_DATA = README -README: pam_userdb.8.xml --include $(top_srcdir)/Make.xml.rules -endif - diff --git a/modules/pam_userdb/README.xml b/modules/pam_userdb/README.xml deleted file mode 100644 index b22c09e7..00000000 --- a/modules/pam_userdb/README.xml +++ /dev/null @@ -1,41 +0,0 @@ -<?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_userdb.8.xml"> ---> -]> - -<article> - - <articleinfo> - - <title> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" - href="pam_userdb.8.xml" xpointer='xpointer(//refnamediv[@id = "pam_userdb-name"]/*)'/> - </title> - - </articleinfo> - - <section> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" - href="pam_userdb.8.xml" xpointer='xpointer(//refsect1[@id = "pam_userdb-description"]/*)'/> - </section> - - <section> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" - href="pam_userdb.8.xml" xpointer='xpointer(//refsect1[@id = "pam_userdb-options"]/*)'/> - </section> - - <section> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" - href="pam_userdb.8.xml" xpointer='xpointer(//refsect1[@id = "pam_userdb-examples"]/*)'/> - </section> - - <section> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" - href="pam_userdb.8.xml" xpointer='xpointer(//refsect1[@id = "pam_userdb-author"]/*)'/> - </section> - -</article> diff --git a/modules/pam_userdb/create.pl b/modules/pam_userdb/create.pl deleted file mode 100644 index 224204b7..00000000 --- a/modules/pam_userdb/create.pl +++ /dev/null @@ -1,23 +0,0 @@ -#!/usr/bin/perl -# this program creates a database in ARGV[1] from pairs given on -# stdandard input -# -# $Id$ - -use DB_File; - -my $database = $ARGV[0]; -die "Use: create.pl <database>\n" unless ($database); -print "Using database: $database\n"; - -my %lusers = (); - -tie %lusers, 'DB_File', $database, O_RDWR|O_CREAT, 0644, $DB_HASH ; -while (<STDIN>) { - my ($user, $pass) = split; - - $lusers{$user} = $pass; -} -untie %lusers; - - diff --git a/modules/pam_userdb/pam_userdb.8.xml b/modules/pam_userdb/pam_userdb.8.xml deleted file mode 100644 index 70b416b3..00000000 --- a/modules/pam_userdb/pam_userdb.8.xml +++ /dev/null @@ -1,292 +0,0 @@ -<?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_userdb"> - - <refmeta> - <refentrytitle>pam_userdb</refentrytitle> - <manvolnum>8</manvolnum> - <refmiscinfo class="sectdesc">Linux-PAM Manual</refmiscinfo> - </refmeta> - - <refnamediv id="pam_userdb-name"> - <refname>pam_userdb</refname> - <refpurpose>PAM module to authenticate against a db database</refpurpose> - </refnamediv> - - <refsynopsisdiv> - <cmdsynopsis id="pam_userdb-cmdsynopsis"> - <command>pam_userdb.so</command> - <arg choice="plain"> - db=<replaceable>/path/database</replaceable> - </arg> - <arg choice="opt"> - debug - </arg> - <arg choice="opt"> - crypt=[crypt|none] - </arg> - <arg choice="opt"> - icase - </arg> - <arg choice="opt"> - dump - </arg> - <arg choice="opt"> - try_first_pass - </arg> - <arg choice="opt"> - use_first_pass - </arg> - <arg choice="opt"> - unknown_ok - </arg> - <arg choice="opt"> - key_only - </arg> - </cmdsynopsis> - </refsynopsisdiv> - - <refsect1 id="pam_userdb-description"> - - <title>DESCRIPTION</title> - - <para> - The pam_userdb module is used to verify a username/password pair - against values stored in a Berkeley DB database. The database is - indexed by the username, and the data fields corresponding to the - username keys are the passwords. - </para> - </refsect1> - - <refsect1 id="pam_userdb-options"> - - <title>OPTIONS</title> - <variablelist> - <varlistentry> - <term> - <option>crypt=[crypt|none]</option> - </term> - <listitem> - <para> - Indicates whether encrypted or plaintext passwords are stored - in the database. If it is <option>crypt</option>, passwords - should be stored in the database in - <citerefentry> - <refentrytitle>crypt</refentrytitle><manvolnum>3</manvolnum> - </citerefentry> form. If <option>none</option> is selected, - passwords should be stored in the database as plaintext. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <option>db=<replaceable>/path/database</replaceable></option> - </term> - <listitem> - <para> - Use the <filename>/path/database</filename> database for - performing lookup. There is no default; the module will - return <emphasis remap='B'>PAM_IGNORE</emphasis> if no - database is provided. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <option>debug</option> - </term> - <listitem> - <para> - Print debug information. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <option>dump</option> - </term> - <listitem> - <para> - Dump all the entries in the database to the log. - Don't do this by default! - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <option>icase</option> - </term> - <listitem> - <para> - Make the password verification to be case insensitive - (ie when working with registration numbers and such). - Only works with plaintext password storage. - </para> - </listitem> - </varlistentry> - - <varlistentry> - <term> - <option>try_first_pass</option> - </term> - <listitem> - <para> - Use the authentication token previously obtained by - another module that did the conversation with the - application. If this token can not be obtained then - the module will try to converse. This option can - be used for stacking different modules that need to - deal with the authentication tokens. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <option>use_first_pass</option> - </term> - <listitem> - <para> - Use the authentication token previously obtained by - another module that did the conversation with the - application. If this token can not be obtained then - the module will fail. This option can be used for - stacking different modules that need to deal with - the authentication tokens. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <option>unknown_ok</option> - </term> - <listitem> - <para> - Do not return error when checking for a user that is - not in the database. This can be used to stack more - than one pam_userdb module that will check a - username/password pair in more than a database. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <option>key_only</option> - </term> - <listitem> - <para> - The username and password are concatenated together - in the database hash as 'username-password' with a - random value. if the concatenation of the username and - password with a dash in the middle returns any result, - the user is valid. this is useful in cases where - the username may not be unique but the username and - password pair are. - </para> - </listitem> - </varlistentry> - </variablelist> - </refsect1> - - <refsect1 id="pam_userdb-services"> - <title>MODULE SERVICES PROVIDED</title> - <para> - The services <option>auth</option> and <option>account</option> - are supported. - </para> - </refsect1> - - <refsect1 id='pam_userdb-return_values'> - <title>RETURN VALUES</title> - <variablelist> - <varlistentry> - <term>PAM_AUTH_ERR</term> - <listitem> - <para>Authentication failure.</para> - </listitem> - </varlistentry> - <varlistentry> - <term>PAM_AUTHTOK_RECOVERY_ERR</term> - <listitem> - <para> - Authentication information cannot be recovered. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term>PAM_BUF_ERR</term> - <listitem> - <para> - Memory buffer error. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term>PAM_CONV_ERR</term> - <listitem> - <para> - Conversation failure. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term>PAM_SERVICE_ERR</term> - <listitem> - <para> - Error in service module. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term>PAM_SUCCESS</term> - <listitem> - <para> - Success. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term>PAM_USER_UNKNOWN</term> - <listitem> - <para> - User not known to the underlying authentication module. - </para> - </listitem> - </varlistentry> - </variablelist> - </refsect1> - - <refsect1 id='pam_userdb-examples'> - <title>EXAMPLES</title> - <programlisting> -auth sufficient pam_userdb.so icase db=/etc/dbtest.db - </programlisting> - </refsect1> - - <refsect1 id='pam_userdb-see_also'> - <title>SEE ALSO</title> - <para> - <citerefentry> - <refentrytitle>crypt</refentrytitle><manvolnum>3</manvolnum> - </citerefentry>, - <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_userdb-author'> - <title>AUTHOR</title> - <para> - pam_userdb was written by Cristian Gafton >gafton@redhat.com<. - </para> - </refsect1> - -</refentry> diff --git a/modules/pam_userdb/pam_userdb.c b/modules/pam_userdb/pam_userdb.c deleted file mode 100644 index a796b15e..00000000 --- a/modules/pam_userdb/pam_userdb.c +++ /dev/null @@ -1,517 +0,0 @@ -/* pam_userdb module */ - -/* - * Written by Cristian Gafton <gafton@redhat.com> 1996/09/10 - * See the end of the file for Copyright Information - */ - -#include "config.h" - -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <string.h> -#include <syslog.h> -#include <stdarg.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <fcntl.h> -#include <errno.h> -#ifdef HAVE_CRYPT_H -#include <crypt.h> -#endif - -#include "pam_userdb.h" - -#ifdef HAVE_NDBM_H -# include <ndbm.h> -#else -# ifdef HAVE_DB_H -# define DB_DBM_HSEARCH 1 /* use the dbm interface */ -# include <db.h> -# else -# error "failed to find a libdb or equivalent" -# endif -#endif - -/* - * here, we make a definition for the externally accessible function - * in this file (this definition is required for static a module - * but strongly encouraged generally) it is used to instruct the - * modules include file to define the function prototypes. - */ - -#define PAM_SM_AUTH -#define PAM_SM_ACCOUNT - -#include <security/pam_modules.h> -#include <security/pam_ext.h> -#include <security/_pam_macros.h> - -/* - * Conversation function to obtain the user's password - */ -static int -obtain_authtok(pam_handle_t *pamh) -{ - char *resp; - const void *item; - int retval; - - retval = pam_prompt(pamh, PAM_PROMPT_ECHO_OFF, &resp, _("Password: ")); - - if (retval != PAM_SUCCESS) - return retval; - - if (resp == NULL) - return PAM_CONV_ERR; - - /* set the auth token */ - retval = pam_set_item(pamh, PAM_AUTHTOK, resp); - - /* clean it up */ - _pam_overwrite(resp); - _pam_drop(resp); - - if ( (retval != PAM_SUCCESS) || - (retval = pam_get_item(pamh, PAM_AUTHTOK, &item)) - != PAM_SUCCESS ) { - return retval; - } - - return retval; -} - -static int -_pam_parse (pam_handle_t *pamh, int argc, const char **argv, - const char **database, const char **cryptmode) -{ - int ctrl; - - *database = NULL; - *cryptmode = NULL; - - /* step through arguments */ - for (ctrl = 0; argc-- > 0; ++argv) - { - /* generic options */ - - if (!strcmp(*argv,"debug")) - ctrl |= PAM_DEBUG_ARG; - else if (!strcasecmp(*argv, "icase")) - ctrl |= PAM_ICASE_ARG; - else if (!strcasecmp(*argv, "dump")) - ctrl |= PAM_DUMP_ARG; - else if (!strcasecmp(*argv, "unknown_ok")) - ctrl |= PAM_UNKNOWN_OK_ARG; - else if (!strcasecmp(*argv, "key_only")) - ctrl |= PAM_KEY_ONLY_ARG; - else if (!strcasecmp(*argv, "use_first_pass")) - ctrl |= PAM_USE_FPASS_ARG; - else if (!strcasecmp(*argv, "try_first_pass")) - ctrl |= PAM_TRY_FPASS_ARG; - else if (!strncasecmp(*argv,"db=", 3)) - { - *database = (*argv) + 3; - if (**database == '\0') { - *database = NULL; - pam_syslog(pamh, LOG_ERR, - "db= specification missing argument - ignored"); - } - } - else if (!strncasecmp(*argv,"crypt=", 6)) - { - *cryptmode = (*argv) + 6; - if (**cryptmode == '\0') - pam_syslog(pamh, LOG_ERR, - "crypt= specification missing argument - ignored"); - } - else - { - pam_syslog(pamh, LOG_ERR, "unknown option: %s", *argv); - } - } - - return ctrl; -} - - -/* - * Looks up an user name in a database and checks the password - * - * return values: - * 1 = User not found - * 0 = OK - * -1 = Password incorrect - * -2 = System error - */ -static int -user_lookup (pam_handle_t *pamh, const char *database, const char *cryptmode, - const char *user, const char *pass, int ctrl) -{ - DBM *dbm; - datum key, data; - - /* Open the DB file. */ - dbm = dbm_open(database, O_RDONLY, 0644); - if (dbm == NULL) { - pam_syslog(pamh, LOG_ERR, - "user_lookup: could not open database `%s': %m", database); - return -2; - } - - /* dump out the database contents for debugging */ - if (ctrl & PAM_DUMP_ARG) { - pam_syslog(pamh, LOG_INFO, "Database dump:"); - for (key = dbm_firstkey(dbm); key.dptr != NULL; - key = dbm_nextkey(dbm)) { - data = dbm_fetch(dbm, key); - pam_syslog(pamh, LOG_INFO, - "key[len=%d] = `%s', data[len=%d] = `%s'", - key.dsize, key.dptr, data.dsize, data.dptr); - } - } - - /* do some more init work */ - memset(&key, 0, sizeof(key)); - memset(&data, 0, sizeof(data)); - if (ctrl & PAM_KEY_ONLY_ARG) { - if (asprintf(&key.dptr, "%s-%s", user, pass) < 0) - key.dptr = NULL; - else - key.dsize = strlen(key.dptr); - } else { - key.dptr = x_strdup(user); - key.dsize = strlen(user); - } - - if (key.dptr) { - data = dbm_fetch(dbm, key); - memset(key.dptr, 0, key.dsize); - free(key.dptr); - } - - if (ctrl & PAM_DEBUG_ARG) { - pam_syslog(pamh, LOG_INFO, - "password in database is [%p]`%.*s', len is %d", - data.dptr, data.dsize, (char *) data.dptr, data.dsize); - } - - if (data.dptr != NULL) { - int compare = 0; - - if (ctrl & PAM_KEY_ONLY_ARG) - { - dbm_close (dbm); - return 0; /* found it, data contents don't matter */ - } - - if (cryptmode && strncasecmp(cryptmode, "crypt", 5) == 0) { - - /* crypt(3) password storage */ - - char *cryptpw; - char salt[2]; - - if (data.dsize != 13) { - compare = -2; - } else if (ctrl & PAM_ICASE_ARG) { - compare = -2; - } else { - salt[0] = *data.dptr; - salt[1] = *(data.dptr + 1); - - cryptpw = crypt (pass, salt); - - if (cryptpw) { - compare = strncasecmp (data.dptr, cryptpw, data.dsize); - } else { - compare = -2; - if (ctrl & PAM_DEBUG_ARG) { - pam_syslog(pamh, LOG_INFO, "crypt() returned NULL"); - } - }; - - }; - - } else { - - /* Unknown password encryption method - - * default to plaintext password storage - */ - - if (strlen(pass) != (size_t)data.dsize) { - compare = 1; /* wrong password len -> wrong password */ - } else if (ctrl & PAM_ICASE_ARG) { - compare = strncasecmp(data.dptr, pass, data.dsize); - } else { - compare = strncmp(data.dptr, pass, data.dsize); - } - - if (cryptmode && strncasecmp(cryptmode, "none", 4) - && (ctrl & PAM_DEBUG_ARG)) { - pam_syslog(pamh, LOG_INFO, "invalid value for crypt parameter: %s", - cryptmode); - pam_syslog(pamh, LOG_INFO, "defaulting to plaintext password mode"); - } - - } - - dbm_close(dbm); - if (compare == 0) - return 0; /* match */ - else - return -1; /* wrong */ - } else { - int saw_user = 0; - - if (ctrl & PAM_DEBUG_ARG) { - pam_syslog(pamh, LOG_INFO, "error returned by dbm_fetch: %m"); - } - - /* probably we should check dbm_error() here */ - - if ((ctrl & PAM_KEY_ONLY_ARG) == 0) { - dbm_close(dbm); - return 1; /* not key_only, so no entry => no entry for the user */ - } - - /* now handle the key_only case */ - for (key = dbm_firstkey(dbm); - key.dptr != NULL; - key = dbm_nextkey(dbm)) { - int compare; - /* first compare the user portion (case sensitive) */ - compare = strncmp(key.dptr, user, strlen(user)); - if (compare == 0) { - /* assume failure */ - compare = -1; - /* if we have the divider where we expect it to be... */ - if (key.dptr[strlen(user)] == '-') { - saw_user = 1; - if ((size_t)key.dsize == strlen(user) + 1 + strlen(pass)) { - if (ctrl & PAM_ICASE_ARG) { - /* compare the password portion (case insensitive)*/ - compare = strncasecmp(key.dptr + strlen(user) + 1, - pass, - strlen(pass)); - } else { - /* compare the password portion (case sensitive) */ - compare = strncmp(key.dptr + strlen(user) + 1, - pass, - strlen(pass)); - } - } - } - if (compare == 0) { - dbm_close(dbm); - return 0; /* match */ - } - } - } - dbm_close(dbm); - if (saw_user) - return -1; /* saw the user, but password mismatch */ - else - return 1; /* not found */ - } - - /* NOT REACHED */ - return -2; -} - -/* --- authentication management functions (only) --- */ - -PAM_EXTERN int -pam_sm_authenticate(pam_handle_t *pamh, int flags UNUSED, - int argc, const char **argv) -{ - const char *username; - const void *password; - const char *database = NULL; - const char *cryptmode = NULL; - int retval = PAM_AUTH_ERR, ctrl; - - /* parse arguments */ - ctrl = _pam_parse(pamh, argc, argv, &database, &cryptmode); - if (database == NULL) { - pam_syslog(pamh, LOG_ERR, "can not get the database name"); - return PAM_SERVICE_ERR; - } - - /* Get the username */ - retval = pam_get_user(pamh, &username, NULL); - if ((retval != PAM_SUCCESS) || (!username)) { - pam_syslog(pamh, LOG_ERR, "can not get the username"); - return PAM_SERVICE_ERR; - } - - if ((ctrl & PAM_USE_FPASS_ARG) == 0 && (ctrl & PAM_TRY_FPASS_ARG) == 0) { - /* Converse to obtain a password */ - retval = obtain_authtok(pamh); - if (retval != PAM_SUCCESS) { - pam_syslog(pamh, LOG_ERR, "can not obtain password from user"); - return retval; - } - } - - /* Check if we got a password */ - retval = pam_get_item(pamh, PAM_AUTHTOK, &password); - if (retval != PAM_SUCCESS || password == NULL) { - if ((ctrl & PAM_TRY_FPASS_ARG) != 0) { - /* Converse to obtain a password */ - retval = obtain_authtok(pamh); - if (retval != PAM_SUCCESS) { - pam_syslog(pamh, LOG_ERR, "can not obtain password from user"); - return retval; - } - retval = pam_get_item(pamh, PAM_AUTHTOK, &password); - } - if (retval != PAM_SUCCESS || password == NULL) { - pam_syslog(pamh, LOG_ERR, "can not recover user password"); - return PAM_AUTHTOK_RECOVERY_ERR; - } - } - - if (ctrl & PAM_DEBUG_ARG) - pam_syslog(pamh, LOG_INFO, "Verify user `%s' with a password", - username); - - /* Now use the username to look up password in the database file */ - retval = user_lookup(pamh, database, cryptmode, username, password, ctrl); - switch (retval) { - case -2: - /* some sort of system error. The log was already printed */ - return PAM_SERVICE_ERR; - case -1: - /* incorrect password */ - pam_syslog(pamh, LOG_WARNING, - "user `%s' denied access (incorrect password)", - username); - return PAM_AUTH_ERR; - case 1: - /* the user does not exist in the database */ - if (ctrl & PAM_DEBUG_ARG) - pam_syslog(pamh, LOG_NOTICE, - "user `%s' not found in the database", username); - return PAM_USER_UNKNOWN; - case 0: - /* Otherwise, the authentication looked good */ - pam_syslog(pamh, LOG_NOTICE, "user '%s' granted access", username); - return PAM_SUCCESS; - default: - /* we don't know anything about this return value */ - pam_syslog(pamh, LOG_ERR, - "internal module error (retval = %d, user = `%s'", - retval, username); - return PAM_SERVICE_ERR; - } - - /* should not be reached */ - return PAM_IGNORE; -} - -PAM_EXTERN int -pam_sm_setcred(pam_handle_t *pamh UNUSED, int flags UNUSED, - int argc UNUSED, const char **argv UNUSED) -{ - return PAM_SUCCESS; -} - -PAM_EXTERN int -pam_sm_acct_mgmt(pam_handle_t *pamh, int flags UNUSED, - int argc, const char **argv) -{ - const char *username; - const char *database = NULL; - const char *cryptmode = NULL; - int retval = PAM_AUTH_ERR, ctrl; - - /* parse arguments */ - ctrl = _pam_parse(pamh, argc, argv, &database, &cryptmode); - - /* Get the username */ - retval = pam_get_user(pamh, &username, NULL); - if ((retval != PAM_SUCCESS) || (!username)) { - pam_syslog(pamh, LOG_ERR,"can not get the username"); - return PAM_SERVICE_ERR; - } - - /* Now use the username to look up password in the database file */ - retval = user_lookup(pamh, database, cryptmode, username, "", ctrl); - switch (retval) { - case -2: - /* some sort of system error. The log was already printed */ - return PAM_SERVICE_ERR; - case -1: - /* incorrect password, but we don't care */ - /* FALL THROUGH */ - case 0: - /* authentication succeeded. dumbest password ever. */ - return PAM_SUCCESS; - case 1: - /* the user does not exist in the database */ - return PAM_USER_UNKNOWN; - default: - /* we don't know anything about this return value */ - pam_syslog(pamh, LOG_ERR, - "internal module error (retval = %d, user = `%s'", - retval, username); - return PAM_SERVICE_ERR; - } - - return PAM_SUCCESS; -} - - -#ifdef PAM_STATIC - -/* static module data */ - -struct pam_module _pam_userdb_modstruct = { - "pam_userdb", - pam_sm_authenticate, - pam_sm_setcred, - pam_sm_acct_mgmt, - NULL, - NULL, - NULL, -}; - -#endif - -/* - * Copyright (c) Cristian Gafton <gafton@redhat.com>, 1999 - * All rights reserved - * - * 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. - */ diff --git a/modules/pam_userdb/pam_userdb.h b/modules/pam_userdb/pam_userdb.h deleted file mode 100644 index 4cd81baf..00000000 --- a/modules/pam_userdb/pam_userdb.h +++ /dev/null @@ -1,62 +0,0 @@ - -#ifndef _PAM_USERSDB_H -#define _PAM_USERSDB_H -/* $Id$ */ - -/* Header files */ -#include <security/pam_appl.h> - -/* argument parsing */ -#define PAM_DEBUG_ARG 0x0001 -#define PAM_ICASE_ARG 0x0002 -#define PAM_DUMP_ARG 0x0004 -#define PAM_UNKNOWN_OK_ARG 0x0010 -#define PAM_KEY_ONLY_ARG 0x0020 -#define PAM_USE_FPASS_ARG 0x0040 -#define PAM_TRY_FPASS_ARG 0x0080 - -/* Useful macros */ -#define x_strdup(s) ( (s) ? strdup(s):NULL ) - -/* The name of the module we are compiling */ -#ifndef MODULE_NAME -#define MODULE_NAME "pam_userdb" -#endif /* MODULE_NAME */ - -#endif /* _PAM_USERSDB_H */ - -/* - * Copyright (c) Cristian Gafton <gafton@redhat.com>, 1999 - * All rights reserved - * - * 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. - */ diff --git a/modules/pam_userdb/tst-pam_userdb b/modules/pam_userdb/tst-pam_userdb deleted file mode 100755 index 5d5eb195..00000000 --- a/modules/pam_userdb/tst-pam_userdb +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/sh -../../tests/tst-dlopen .libs/pam_userdb.so diff --git a/modules/pam_warn/.cvsignore b/modules/pam_warn/.cvsignore deleted file mode 100644 index 7737bcc0..00000000 --- a/modules/pam_warn/.cvsignore +++ /dev/null @@ -1,8 +0,0 @@ -*.la -*.lo -.deps -.libs -Makefile -Makefile.in -README -pam_warn.8 diff --git a/modules/pam_warn/Makefile.am b/modules/pam_warn/Makefile.am deleted file mode 100644 index 6ecc1362..00000000 --- a/modules/pam_warn/Makefile.am +++ /dev/null @@ -1,31 +0,0 @@ -# -# Copyright (c) 2005, 2006 Thorsten Kukuk <kukuk@suse.de> -# - -CLEANFILES = *~ - -EXTRA_DIST = README $(MANS) $(XMLS) tst-pam_warn - -man_MANS = pam_warn.8 -XMLS = README.xml pam_warn.8.xml - -TESTS = tst-pam_warn - -securelibdir = $(SECUREDIR) -secureconfdir = $(SCONFIGDIR) - -AM_CFLAGS = -I$(top_srcdir)/libpam/include -I$(top_srcdir)/libpamc/include -AM_LDFLAGS = -no-undefined -avoid-version -module \ - -L$(top_builddir)/libpam -lpam -if HAVE_VERSIONING - AM_LDFLAGS += -Wl,--version-script=$(srcdir)/../modules.map -endif - -securelib_LTLIBRARIES = pam_warn.la - -if ENABLE_REGENERATE_MAN -noinst_DATA = README -README: pam_warn.8.xml --include $(top_srcdir)/Make.xml.rules -endif - diff --git a/modules/pam_warn/README.xml b/modules/pam_warn/README.xml deleted file mode 100644 index 4367c28f..00000000 --- a/modules/pam_warn/README.xml +++ /dev/null @@ -1,41 +0,0 @@ -<?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_warn.8.xml"> ---> -]> - -<article> - - <articleinfo> - - <title> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" - href="pam_warn.8.xml" xpointer='xpointer(//refnamediv[@id = "pam_warn-name"]/*)'/> - </title> - - </articleinfo> - - <section> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" - href="pam_warn.8.xml" xpointer='xpointer(//refsect1[@id = "pam_warn-description"]/*)'/> - </section> - - <section> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" - href="pam_warn.8.xml" xpointer='xpointer(//refsect1[@id = "pam_warn-options"]/*)'/> - </section> - - <section> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" - href="pam_warn.8.xml" xpointer='xpointer(//refsect1[@id = "pam_warn-examples"]/*)'/> - </section> - - <section> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" - href="pam_warn.8.xml" xpointer='xpointer(//refsect1[@id = "pam_warn-author"]/*)'/> - </section> - -</article> diff --git a/modules/pam_warn/pam_warn.8.xml b/modules/pam_warn/pam_warn.8.xml deleted file mode 100644 index b3261b86..00000000 --- a/modules/pam_warn/pam_warn.8.xml +++ /dev/null @@ -1,104 +0,0 @@ -<?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_warn"> - - <refmeta> - <refentrytitle>pam_warn</refentrytitle> - <manvolnum>8</manvolnum> - <refmiscinfo class="sectdesc">Linux-PAM Manual</refmiscinfo> - </refmeta> - <refnamediv id="pam_warn-name"> - <refname>pam_warn</refname> - <refpurpose>PAM module which logs all PAM items if called</refpurpose> - </refnamediv> - <refsynopsisdiv> - <cmdsynopsis id="pam_warn-cmdsynopsis"> - <command>pam_warn.so</command> - </cmdsynopsis> - </refsynopsisdiv> - - <refsect1 id="pam_warn-description"> - <title>DESCRIPTION</title> - <para> - pam_warn is a PAM module that logs the service, terminal, user, - remote user and remote host to - <citerefentry> - <refentrytitle>syslog</refentrytitle><manvolnum>3</manvolnum> - </citerefentry>. The items are not probed for, but instead obtained - from the standard PAM items. The module always returns - <emphasis remap='B'>PAM_IGNORE</emphasis>, indicating that it - does not want to affect the authentication process. - </para> - </refsect1> - - <refsect1 id="pam_warn-options"> - <title>OPTIONS</title> - <para>This module does not recognise any options.</para> - </refsect1> - - <refsect1 id="pam_warn-services"> - <title>MODULE SERVICES PROVIDED</title> - <para> - The services <option>auth</option>, <option>account</option>, - <option>password</option> and <option>session</option> are supported. - </para> - </refsect1> - - <refsect1 id='pam_warn-return_values'> - <title>RETURN VALUES</title> - <variablelist> - <varlistentry> - <term>PAM_IGNORE</term> - <listitem> - <para> - This module always returns PAM_IGNORE. - </para> - </listitem> - </varlistentry> - </variablelist> - </refsect1> - - <refsect1 id='pam_warn-examples'> - <title>EXAMPLES</title> - <programlisting> -#%PAM-1.0 -# -# If we don't have config entries for a service, the -# OTHER entries are used. To be secure, warn and deny -# access to everything. -other auth required pam_warn.so -other auth required pam_deny.so -other account required pam_warn.so -other account required pam_deny.so -other password required pam_warn.so -other password required pam_deny.so -other session required pam_warn.so -other session required pam_deny.so - </programlisting> - </refsect1> - - <refsect1 id='pam_warn-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_warn-author'> - <title>AUTHOR</title> - <para> - pam_warn was written by Andrew G. Morgan <morgan@kernel.org>. - </para> - </refsect1> - -</refentry> diff --git a/modules/pam_warn/pam_warn.c b/modules/pam_warn/pam_warn.c deleted file mode 100644 index 268e2289..00000000 --- a/modules/pam_warn/pam_warn.c +++ /dev/null @@ -1,123 +0,0 @@ -/* pam_warn module */ - -/* - * $Id$ - * - * Written by Andrew Morgan <morgan@linux.kernel.org> 1996/3/11 - */ - -#include "config.h" - -#include <stdio.h> -#include <unistd.h> -#include <syslog.h> -#include <stdarg.h> - -/* - * here, we make a definition for the externally accessible function - * in this file (this definition is required for static a module - * but strongly encouraged generally) it is used to instruct the - * modules include file to define the function prototypes. - */ - -#define PAM_SM_AUTH -#define PAM_SM_PASSWORD - -#include <security/pam_modules.h> -#include <security/pam_ext.h> - -/* some syslogging */ - -#define OBTAIN(item, value, default_value) do { \ - (void) pam_get_item(pamh, item, &value); \ - value = value ? value : default_value ; \ -} while (0) - -static void log_items(pam_handle_t *pamh, const char *function) -{ - const void *service=NULL, *user=NULL, *terminal=NULL, - *rhost=NULL, *ruser=NULL; - - OBTAIN(PAM_SERVICE, service, "<unknown>"); - OBTAIN(PAM_TTY, terminal, "<unknown>"); - OBTAIN(PAM_USER, user, "<unknown>"); - OBTAIN(PAM_RUSER, ruser, "<unknown>"); - OBTAIN(PAM_RHOST, rhost, "<unknown>"); - - pam_syslog(pamh, LOG_NOTICE, - "function=[%s] service=[%s] terminal=[%s] user=[%s]" - " ruser=[%s] rhost=[%s]\n", function, - (const char *) service, (const char *) terminal, - (const char *) user, (const char *) ruser, - (const char *) rhost); -} - -/* --- authentication management functions (only) --- */ - -PAM_EXTERN -int pam_sm_authenticate(pam_handle_t *pamh, int flags UNUSED, - int argc UNUSED, const char **argv UNUSED) -{ - log_items(pamh, __FUNCTION__); - return PAM_IGNORE; -} - -PAM_EXTERN -int pam_sm_setcred(pam_handle_t *pamh, int flags UNUSED, - int argc UNUSED, const char **argv UNUSED) -{ - log_items(pamh, __FUNCTION__); - return PAM_IGNORE; -} - -/* password updating functions */ - -PAM_EXTERN -int pam_sm_chauthtok(pam_handle_t *pamh, int flags UNUSED, - int argc UNUSED, const char **argv UNUSED) -{ - log_items(pamh, __FUNCTION__); - return PAM_IGNORE; -} - -PAM_EXTERN int -pam_sm_acct_mgmt(pam_handle_t *pamh, int flags UNUSED, - int argc UNUSED, const char **argv UNUSED) -{ - log_items(pamh, __FUNCTION__); - return PAM_IGNORE; -} - -PAM_EXTERN int -pam_sm_open_session(pam_handle_t *pamh, int flags UNUSED, - int argc UNUSED, const char **argv UNUSED) -{ - log_items(pamh, __FUNCTION__); - return PAM_IGNORE; -} - -PAM_EXTERN int -pam_sm_close_session(pam_handle_t *pamh, int flags UNUSED, - int argc UNUSED, const char **argv UNUSED) -{ - log_items(pamh, __FUNCTION__); - return PAM_IGNORE; -} - -#ifdef PAM_STATIC - -/* static module data */ - -struct pam_module _pam_warn_modstruct = { - "pam_warn", - pam_sm_authenticate, - pam_sm_setcred, - pam_sm_acct_mgmt, - pam_sm_open_session, - pam_sm_close_session, - pam_sm_chauthtok, -}; - -#endif - -/* end of module definition */ diff --git a/modules/pam_warn/tst-pam_warn b/modules/pam_warn/tst-pam_warn deleted file mode 100755 index 0b48365a..00000000 --- a/modules/pam_warn/tst-pam_warn +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/sh -../../tests/tst-dlopen .libs/pam_warn.so diff --git a/modules/pam_wheel/.cvsignore b/modules/pam_wheel/.cvsignore deleted file mode 100644 index e63f2a9c..00000000 --- a/modules/pam_wheel/.cvsignore +++ /dev/null @@ -1,8 +0,0 @@ -*.la -*.lo -.deps -.libs -Makefile -Makefile.in -README -pam_wheel.8 diff --git a/modules/pam_wheel/Makefile.am b/modules/pam_wheel/Makefile.am deleted file mode 100644 index 82a98305..00000000 --- a/modules/pam_wheel/Makefile.am +++ /dev/null @@ -1,31 +0,0 @@ -# -# Copyright (c) 2005, 2006 Thorsten Kukuk <kukuk@suse.de> -# - -CLEANFILES = *~ - -EXTRA_DIST = README ${MANS} $(XMLS) tst-pam_wheel - -man_MANS = pam_wheel.8 -XMLS = README.xml pam_wheel.8.xml - -TESTS = tst-pam_wheel - -securelibdir = $(SECUREDIR) -secureconfdir = $(SCONFIGDIR) - -AM_CFLAGS = -I$(top_srcdir)/libpam/include -I$(top_srcdir)/libpamc/include -AM_LDFLAGS = -no-undefined -avoid-version -module \ - -L$(top_builddir)/libpam -lpam -if HAVE_VERSIONING - AM_LDFLAGS += -Wl,--version-script=$(srcdir)/../modules.map -endif - -securelib_LTLIBRARIES = pam_wheel.la - -if ENABLE_REGENERATE_MAN -noinst_DATA = README -README: pam_wheel.8.xml --include $(top_srcdir)/Make.xml.rules -endif - diff --git a/modules/pam_wheel/README.xml b/modules/pam_wheel/README.xml deleted file mode 100644 index 9e33d7ff..00000000 --- a/modules/pam_wheel/README.xml +++ /dev/null @@ -1,41 +0,0 @@ -<?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_wheel.8.xml"> ---> -]> - -<article> - - <articleinfo> - - <title> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" - href="pam_wheel.8.xml" xpointer='xpointer(//refnamediv[@id = "pam_wheel-name"]/*)'/> - </title> - - </articleinfo> - - <section> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" - href="pam_wheel.8.xml" xpointer='xpointer(//refsect1[@id = "pam_wheel-description"]/*)'/> - </section> - - <section> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" - href="pam_wheel.8.xml" xpointer='xpointer(//refsect1[@id = "pam_wheel-options"]/*)'/> - </section> - - <section> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" - href="pam_wheel.8.xml" xpointer='xpointer(//refsect1[@id = "pam_wheel-examples"]/*)'/> - </section> - - <section> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" - href="pam_wheel.8.xml" xpointer='xpointer(//refsect1[@id = "pam_wheel-author"]/*)'/> - </section> - -</article> diff --git a/modules/pam_wheel/pam_wheel.8.xml b/modules/pam_wheel/pam_wheel.8.xml deleted file mode 100644 index bf8b7349..00000000 --- a/modules/pam_wheel/pam_wheel.8.xml +++ /dev/null @@ -1,242 +0,0 @@ -<?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_wheel"> - - <refmeta> - <refentrytitle>pam_wheel</refentrytitle> - <manvolnum>8</manvolnum> - <refmiscinfo class="sectdesc">Linux-PAM Manual</refmiscinfo> - </refmeta> - - <refnamediv id="pam_wheel-name"> - <refname>pam_wheel</refname> - <refpurpose>Only permit root access to members of group wheel</refpurpose> - </refnamediv> - - <refsynopsisdiv> - <cmdsynopsis id="pam_wheel-cmdsynopsis"> - <command>pam_wheel.so</command> - <arg choice="opt"> - debug - </arg> - <arg choice="opt"> - deny - </arg> - <arg choice="opt"> - group=<replaceable>name</replaceable> - </arg> - <arg choice="opt"> - root_only - </arg> - <arg choice="opt"> - trust - </arg> - <arg choice="opt"> - use_uid - </arg> - </cmdsynopsis> - </refsynopsisdiv> - - <refsect1 id="pam_wheel-description"> - <title>DESCRIPTION</title> - <para> - The pam_wheel PAM module is used to enforce the so-called - <emphasis>wheel</emphasis> group. By default it permits root - access to the system if the applicant user is a member of the - <emphasis>wheel</emphasis> group. If no group with this name exist, - the module is using the group with the group-ID - <emphasis remap='B'>0</emphasis>. - </para> - </refsect1> - - <refsect1 id="pam_wheel-options"> - <title>OPTIONS</title> - <variablelist> - <varlistentry> - <term> - <option>debug</option> - </term> - <listitem> - <para> - Print debug information. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <option>deny</option> - </term> - <listitem> - <para> - Reverse the sense of the auth operation: if the user - is trying to get UID 0 access and is a member of the - wheel group (or the group of the <option>group</option> option), - deny access. Conversely, if the user is not in the group, return - PAM_IGNORE (unless <option>trust</option> was also specified, - in which case we return PAM_SUCCESS). - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <option>group=<replaceable>name</replaceable></option> - </term> - <listitem> - <para> - Instead of checking the wheel or GID 0 groups, use - the <option><replaceable>name</replaceable></option> group - to perform the authentication. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <option>root_only</option> - </term> - <listitem> - <para> - The check for wheel membership is done only. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <option>trust</option> - </term> - <listitem> - <para> - The pam_wheel module will return PAM_SUCCESS instead - of PAM_IGNORE if the user is a member of the wheel group - (thus with a little play stacking the modules the wheel - members may be able to su to root without being prompted - for a passwd). - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <option>use_uid</option> - </term> - <listitem> - <para> - The check for wheel membership will be done against - the current uid instead of the original one (useful when - jumping with su from one account to another for example). - </para> - </listitem> - </varlistentry> - </variablelist> - </refsect1> - - <refsect1 id="pam_wheel-services"> - <title>MODULE SERVICES PROVIDED</title> - <para> - The <emphasis remap='B'>auth</emphasis> and - <emphasis remap='B'>account</emphasis> services are supported. - </para> - </refsect1> - - <refsect1 id='pam_wheel-return_values'> - <title>RETURN VALUES</title> - <variablelist> - <varlistentry> - <term>PAM_AUTH_ERR</term> - <listitem> - <para> - Authentication failure. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term>PAM_BUF_ERR</term> - <listitem> - <para> - Memory buffer error. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term>PAM_IGNORE</term> - <listitem> - <para> - The return value should be ignored by PAM dispatch. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term>PAM_PERM_DENY</term> - <listitem> - <para> - Permission denied. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term>PAM_SERVICE_ERR</term> - <listitem> - <para> - Cannot determine the user name. - </para> - </listitem> - </varlistentry> - - <varlistentry> - <term>PAM_SUCCESS</term> - <listitem> - <para> - Success. - </para> - </listitem> - </varlistentry> - - <varlistentry> - <term>PAM_USER_UNKNOWN</term> - <listitem> - <para> - User not known. - </para> - </listitem> - </varlistentry> - - </variablelist> - </refsect1> - - <refsect1 id='pam_wheel-examples'> - <title>EXAMPLES</title> - <para> - The root account gains access by default (rootok), only wheel - members can become root (wheel) but Unix authenticate non-root - applicants. - <programlisting> -su auth sufficient pam_rootok.so -su auth required pam_wheel.so -su auth required pam_unix.so - </programlisting> - </para> - </refsect1> - - <refsect1 id='pam_wheel-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_wheel-author'> - <title>AUTHOR</title> - <para> - pam_wheel was written by Cristian Gafton <gafton@redhat.com>. - </para> - </refsect1> - -</refentry> diff --git a/modules/pam_wheel/pam_wheel.c b/modules/pam_wheel/pam_wheel.c deleted file mode 100644 index d7d8096e..00000000 --- a/modules/pam_wheel/pam_wheel.c +++ /dev/null @@ -1,316 +0,0 @@ -/* pam_wheel module */ - -/* - * Written by Cristian Gafton <gafton@redhat.com> 1996/09/10 - * See the end of the file for Copyright Information - * - * - * 1.2 - added 'deny' and 'group=' options - * 1.1 - added 'trust' option - * 1.0 - the code is working for at least another person, so... :-) - * 0.1 - use vsyslog instead of vfprintf/syslog in _pam_log - * - return PAM_IGNORE on success (take care of sloppy sysadmins..) - * - use pam_get_user instead of pam_get_item(...,PAM_USER,...) - * - a new arg use_uid to auth the current uid instead of the - * initial (logged in) one. - * 0.0 - first release - * - * TODO: - * - try to use make_remark from pam_unix/support.c - * - consider returning on failure PAM_FAIL_NOW if the user is not - * a wheel member. - */ - -#include "config.h" - -#include <stdio.h> -#include <unistd.h> -#include <string.h> -#include <syslog.h> -#include <stdarg.h> -#include <sys/types.h> -#include <pwd.h> -#include <grp.h> - -/* - * here, we make a definition for the externally accessible function - * in this file (this definition is required for static a module - * but strongly encouraged generally) it is used to instruct the - * modules include file to define the function prototypes. - */ - -#define PAM_SM_AUTH -#define PAM_SM_ACCOUNT - -#include <security/pam_modules.h> -#include <security/pam_modutil.h> -#include <security/pam_ext.h> - -/* checks if a user is on a list of members of the GID 0 group */ -static int is_on_list(char * const *list, const char *member) -{ - while (list && *list) { - if (strcmp(*list, member) == 0) - return 1; - list++; - } - return 0; -} - -/* argument parsing */ - -#define PAM_DEBUG_ARG 0x0001 -#define PAM_USE_UID_ARG 0x0002 -#define PAM_TRUST_ARG 0x0004 -#define PAM_DENY_ARG 0x0010 -#define PAM_ROOT_ONLY_ARG 0x0020 - -static int -_pam_parse (const pam_handle_t *pamh, int argc, const char **argv, - char *use_group, size_t group_length) -{ - int ctrl=0; - - memset(use_group, '\0', group_length); - - /* step through arguments */ - for (ctrl=0; argc-- > 0; ++argv) { - - /* generic options */ - - if (!strcmp(*argv,"debug")) - ctrl |= PAM_DEBUG_ARG; - else if (!strcmp(*argv,"use_uid")) - ctrl |= PAM_USE_UID_ARG; - else if (!strcmp(*argv,"trust")) - ctrl |= PAM_TRUST_ARG; - else if (!strcmp(*argv,"deny")) - ctrl |= PAM_DENY_ARG; - else if (!strcmp(*argv,"root_only")) - ctrl |= PAM_ROOT_ONLY_ARG; - else if (!strncmp(*argv,"group=",6)) - strncpy(use_group,*argv+6,group_length-1); - else { - pam_syslog(pamh, LOG_ERR, "unknown option: %s", *argv); - } - } - - return ctrl; -} - -static int -perform_check (pam_handle_t *pamh, int ctrl, const char *use_group) -{ - const char *username = NULL; - const char *fromsu; - struct passwd *pwd, *tpwd = NULL; - struct group *grp; - int retval = PAM_AUTH_ERR; - - retval = pam_get_user(pamh, &username, NULL); - if ((retval != PAM_SUCCESS) || (!username)) { - if (ctrl & PAM_DEBUG_ARG) { - pam_syslog(pamh, LOG_DEBUG, "can not get the username"); - } - return PAM_SERVICE_ERR; - } - - pwd = pam_modutil_getpwnam (pamh, username); - if (!pwd) { - if (ctrl & PAM_DEBUG_ARG) { - pam_syslog(pamh, LOG_NOTICE, "unknown user %s", username); - } - return PAM_USER_UNKNOWN; - } - if (ctrl & PAM_ROOT_ONLY_ARG) { - /* su to a non uid 0 account ? */ - if (pwd->pw_uid != 0) { - return PAM_IGNORE; - } - } - - if (ctrl & PAM_USE_UID_ARG) { - tpwd = pam_modutil_getpwuid (pamh, getuid()); - if (!tpwd) { - if (ctrl & PAM_DEBUG_ARG) { - pam_syslog(pamh, LOG_NOTICE, "who is running me ?!"); - } - return PAM_SERVICE_ERR; - } - fromsu = tpwd->pw_name; - } else { - fromsu = pam_modutil_getlogin(pamh); - if (fromsu) { - tpwd = pam_modutil_getpwnam (pamh, fromsu); - } - if (!fromsu || !tpwd) { - if (ctrl & PAM_DEBUG_ARG) { - pam_syslog(pamh, LOG_NOTICE, "who is running me ?!"); - } - return PAM_SERVICE_ERR; - } - } - - /* - * At this point fromsu = username-of-invoker; tpwd = pwd ptr for fromsu - */ - - if (!use_group[0]) { - if ((grp = pam_modutil_getgrnam (pamh, "wheel")) == NULL) { - grp = pam_modutil_getgrgid (pamh, 0); - } - } else { - grp = pam_modutil_getgrnam (pamh, use_group); - } - - if (!grp || (!grp->gr_mem && (tpwd->pw_gid != grp->gr_gid))) { - if (ctrl & PAM_DEBUG_ARG) { - if (!use_group[0]) { - pam_syslog(pamh, LOG_NOTICE, "no members in a GID 0 group"); - } else { - pam_syslog(pamh, LOG_NOTICE, - "no members in '%s' group", use_group); - } - } - if (ctrl & PAM_DENY_ARG) { - /* if this was meant to deny access to the members - * of this group and the group does not exist, allow - * access - */ - return PAM_IGNORE; - } else { - return PAM_AUTH_ERR; - } - } - - /* - * test if the user is a member of the group, or if the - * user has the "wheel" (sic) group as its primary group. - */ - - if (is_on_list(grp->gr_mem, fromsu) || (tpwd->pw_gid == grp->gr_gid)) { - - if (ctrl & PAM_DENY_ARG) { - retval = PAM_PERM_DENIED; - - } else if (ctrl & PAM_TRUST_ARG) { - retval = PAM_SUCCESS; /* this can be a sufficient check */ - - } else { - retval = PAM_IGNORE; - } - - } else { - - if (ctrl & PAM_DENY_ARG) { - - if (ctrl & PAM_TRUST_ARG) { - retval = PAM_SUCCESS; /* this can be a sufficient check */ - } else { - retval = PAM_IGNORE; - } - - } else { - retval = PAM_PERM_DENIED; - } - } - - if (ctrl & PAM_DEBUG_ARG) { - if (retval == PAM_IGNORE) { - pam_syslog(pamh, LOG_NOTICE, - "Ignoring access request '%s' for '%s'", - fromsu, username); - } else { - pam_syslog(pamh, LOG_NOTICE, "Access %s to '%s' for '%s'", - (retval != PAM_SUCCESS) ? "denied":"granted", - fromsu, username); - } - } - - return retval; -} - -/* --- authentication management functions --- */ - -PAM_EXTERN int -pam_sm_authenticate (pam_handle_t *pamh, int flags UNUSED, - int argc, const char **argv) -{ - char use_group[BUFSIZ]; - int ctrl; - - ctrl = _pam_parse(pamh, argc, argv, use_group, sizeof(use_group)); - - return perform_check(pamh, ctrl, use_group); -} - -PAM_EXTERN int -pam_sm_setcred (pam_handle_t *pamh UNUSED, int flags UNUSED, - int argc UNUSED, const char **argv UNUSED) -{ - return PAM_SUCCESS; -} - -PAM_EXTERN int -pam_sm_acct_mgmt (pam_handle_t *pamh, int flags UNUSED, - int argc, const char **argv) -{ - char use_group[BUFSIZ]; - int ctrl; - - ctrl = _pam_parse(pamh, argc, argv, use_group, sizeof(use_group)); - - return perform_check(pamh, ctrl, use_group); -} - -#ifdef PAM_STATIC - -/* static module data */ - -struct pam_module _pam_wheel_modstruct = { - "pam_wheel", - pam_sm_authenticate, - pam_sm_setcred, - pam_sm_acct_mgmt, - NULL, - NULL, - NULL -}; - -#endif /* PAM_STATIC */ - -/* - * Copyright (c) Cristian Gafton <gafton@redhat.com>, 1996, 1997 - * All rights reserved - * - * 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. - */ diff --git a/modules/pam_wheel/tst-pam_wheel b/modules/pam_wheel/tst-pam_wheel deleted file mode 100755 index 4bf5d6a6..00000000 --- a/modules/pam_wheel/tst-pam_wheel +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/sh -../../tests/tst-dlopen .libs/pam_wheel.so diff --git a/modules/pam_xauth/.cvsignore b/modules/pam_xauth/.cvsignore deleted file mode 100644 index 1611e414..00000000 --- a/modules/pam_xauth/.cvsignore +++ /dev/null @@ -1,10 +0,0 @@ -*.la -*.lo -*.so -*~ -.deps -.libs -Makefile -Makefile.in -README -pam_xauth.8 diff --git a/modules/pam_xauth/Makefile.am b/modules/pam_xauth/Makefile.am deleted file mode 100644 index 8f1d56b0..00000000 --- a/modules/pam_xauth/Makefile.am +++ /dev/null @@ -1,31 +0,0 @@ -# -# Copyright (c) 2005, 2006 Thorsten Kukuk <kukuk@suse.de> -# - -CLEANFILES = *~ - -EXTRA_DIST = README ${MANS} $(XMLS) tst-pam_xauth - -man_MANS = pam_xauth.8 -XMLS = README.xml pam_xauth.8.xml - -TESTS = tst-pam_xauth - -securelibdir = $(SECUREDIR) -secureconfdir = $(SCONFIGDIR) - -AM_CFLAGS = -I$(top_srcdir)/libpam/include -I$(top_srcdir)/libpamc/include -AM_LDFLAGS = -no-undefined -avoid-version -module \ - -L$(top_builddir)/libpam -lpam -if HAVE_VERSIONING - AM_LDFLAGS += -Wl,--version-script=$(srcdir)/../modules.map -endif - -securelib_LTLIBRARIES = pam_xauth.la - -if ENABLE_REGENERATE_MAN -noinst_DATA = README -README: pam_xauth.8.xml --include $(top_srcdir)/Make.xml.rules -endif - diff --git a/modules/pam_xauth/README.xml b/modules/pam_xauth/README.xml deleted file mode 100644 index adefbd98..00000000 --- a/modules/pam_xauth/README.xml +++ /dev/null @@ -1,46 +0,0 @@ -<?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_xauth.8.xml"> ---> -]> - -<article> - - <articleinfo> - - <title> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" - href="pam_xauth.8.xml" xpointer='xpointer(//refnamediv[@id = "pam_xauth-name"]/*)'/> - </title> - - </articleinfo> - - <section> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" - href="pam_xauth.8.xml" xpointer='xpointer(//refsect1[@id = "pam_xauth-description"]/*)'/> - </section> - - <section> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" - href="pam_xauth.8.xml" xpointer='xpointer(//refsect1[@id = "pam_xauth-options"]/*)'/> - </section> - - <section> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" - href="pam_xauth.8.xml" xpointer='xpointer(//refsect1[@id = "pam_xauth-examples"]/*)'/> - </section> - - <section> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" - href="pam_xauth.8.xml" xpointer='xpointer(//refsect1[@id = "pam_xauth-implementation"]/*)'/> - </section> - - <section> - <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" - href="pam_xauth.8.xml" xpointer='xpointer(//refsect1[@id = "pam_xauth-author"]/*)'/> - </section> - -</article> diff --git a/modules/pam_xauth/pam_xauth.8.xml b/modules/pam_xauth/pam_xauth.8.xml deleted file mode 100644 index f6323f26..00000000 --- a/modules/pam_xauth/pam_xauth.8.xml +++ /dev/null @@ -1,293 +0,0 @@ -<?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_xauth"> - - <refmeta> - <refentrytitle>pam_xauth</refentrytitle> - <manvolnum>8</manvolnum> - <refmiscinfo class="sectdesc">Linux-PAM Manual</refmiscinfo> - </refmeta> - - <refnamediv id="pam_xauth-name"> - <refname>pam_xauth</refname> - <refpurpose>PAM module to forward xauth keys between users</refpurpose> - </refnamediv> - - <refsynopsisdiv> - <cmdsynopsis id="pam_xauth-cmdsynopsis"> - <command>pam_xauth.so</command> - <arg choice="opt"> - debug - </arg> - <arg choice="opt"> - xauthpath=<replaceable>/path/to/xauth</replaceable> - </arg> - <arg choice="opt"> - systemuser=<replaceable>UID</replaceable> - </arg> - <arg choice="opt"> - targetuser=<replaceable>UID</replaceable> - </arg> - </cmdsynopsis> - </refsynopsisdiv> - - <refsect1 id="pam_xauth-description"> - <title>DESCRIPTION</title> - <para> - The pam_xauth PAM module is designed to forward xauth keys - (sometimes referred to as "cookies") between users. - </para> - <para> - Without pam_xauth, when xauth is enabled and a user uses the - <citerefentry> - <refentrytitle>su</refentrytitle><manvolnum>1</manvolnum> - </citerefentry> command to assume another user's priviledges, - that user is no longer able to access the original user's X display - because the new user does not have the key needed to access the - display. pam_xauth solves the problem by forwarding the key from - the user running su (the source user) to the user whose identity the - source user is assuming (the target user) when the session is created, - and destroying the key when the session is torn down. - </para> - <para> - This means, for example, that when you run - <citerefentry> - <refentrytitle>su</refentrytitle><manvolnum>1</manvolnum> - </citerefentry> from an xterm sesssion, you will be able to run - X programs without explicitly dealing with the - <citerefentry> - <refentrytitle>xauth</refentrytitle><manvolnum>1</manvolnum> - </citerefentry> xauth command or ~/.Xauthority files. - </para> - <para> - pam_xauth will only forward keys if xauth can list a key connected - to the $DISPLAY environment variable. - </para> - <para> - Primitive access control is provided by - <filename>~/.xauth/export</filename> in the invoking user's home - directory and <filename>~/.xauth/import</filename> in the target - user's home directory. - </para> - <para> - If a user has a <filename>~/.xauth/import</filename> file, the user - will only receive cookies from users listed in the file. If there is - no <filename>~/.xauth/import</filename> file, the user will accept - cookies from any other user. - </para> - <para> - If a user has a <filename>.xauth/export</filename> file, the user will - only forward cookies to users listed in the file. If there is no - <filename>~/.xauth/export</filename> file, and the invoking user is - not <emphasis remap='B'>root</emphasis>, the user will forward cookies - to any other user. If there is no <filename>~/.xauth/export</filename> - file, and the invoking user is <emphasis remap='B'>root</emphasis>, - the user will <emphasis remap='I'>not</emphasis> forward cookies to - other users. - </para> - <para> - Both the import and export files support wildcards (such as - <emphasis remap='I'>*</emphasis>). Both the import and export files - can be empty, signifying that no users are allowed. - </para> - </refsect1> - - <refsect1 id="pam_xauth-options"> - <title>OPTIONS</title> - <variablelist> - <varlistentry> - <term> - <option>debug</option> - </term> - <listitem> - <para> - Print debug information. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <option>xauthpath=<replaceable>/path/to/xauth</replaceable></option> - </term> - <listitem> - <para> - Specify the path the xauth program (it is expected in - <filename>/usr/X11R6/bin/xauth</filename>, - <filename>/usr/bin/xauth</filename>, or - <filename>/usr/bin/X11/xauth</filename> by default). - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <option>systemuser=<replaceable>UID</replaceable></option> - </term> - <listitem> - <para> - Specify the highest UID which will be assumed to belong to a - "system" user. pam_xauth will refuse to forward credentials to - users with UID less than or equal to this number, except for - root and the "targetuser", if specified. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> - <option>targetuser=<replaceable>UID</replaceable></option> - </term> - <listitem> - <para> - Specify a single target UID which is exempt from the - systemuser check. - </para> - </listitem> - </varlistentry> - </variablelist> - </refsect1> - - <refsect1 id="pam_xauth-services"> - <title>MODULE SERVICES PROVIDED</title> - <para> - Only the <emphasis remap='B'>session</emphasis> service is supported. - </para> - </refsect1> - - <refsect1 id='pam_xauth-return_values'> - <title>RETURN VALUES</title> - <variablelist> - <varlistentry> - <term>PAM_BUF_ERR</term> - <listitem> - <para> - Memory buffer error. - </para> - </listitem> - </varlistentry> - - <varlistentry> - <term>PAM_PERM_DENIED</term> - <listitem> - <para> - Permission denied by import/export file. - </para> - </listitem> - </varlistentry> - - <varlistentry> - <term>PAM_SESSION_ERR</term> - <listitem> - <para> - Cannot determine user name, UID or access users home directory. - </para> - </listitem> - </varlistentry> - - <varlistentry> - <term>PAM_SUCCESS</term> - <listitem> - <para> - Success. - </para> - </listitem> - </varlistentry> - - <varlistentry> - <term>PAM_USER_UNKNOWN</term> - <listitem> - <para> - User not known. - </para> - </listitem> - </varlistentry> - - </variablelist> - </refsect1> - - <refsect1 id='pam_xauth-examples'> - <title>EXAMPLES</title> - <para> - Add the following line to <filename>/etc/pam.d/su</filename> to - forward xauth keys between users when calling su: - <programlisting> -session optional pam_xauth.so - </programlisting> - </para> - </refsect1> - - <refsect1 id="pam_xauth-implementation"> - <title>IMPLEMENTATION DETAILS</title> - <para> - pam_xauth will work <emphasis remap='I'>only</emphasis> if it is - used from a setuid application in which the - <function>getuid</function>() call returns the id of the user - running the application, and for which PAM can supply the name - of the account that the user is attempting to assume. The typical - application of this type is - <citerefentry> - <refentrytitle>su</refentrytitle><manvolnum>1</manvolnum> - </citerefentry>. - The application must call both <function>pam_open_session</function>() - and <function>pam_close_session</function>() with the ruid set to the - uid of the calling user and the euid set to root, and must have - provided as the PAM_USER item the name of the target user. - </para> - <para> - pam_xauth calls - <citerefentry> - <refentrytitle>xauth</refentrytitle><manvolnum>1</manvolnum> - </citerefentry> as the source user to extract the key for $DISPLAY, - then calls xauth as the target user to merge the key into the a - temporary database and later remove the database. - </para> - <para> - pam_xauth cannot be told to not remove the keys when the session - is closed. - </para> - </refsect1> - - <refsect1 id="pam_lastlog-files"> - <title>FILES</title> - <variablelist> - <varlistentry> - <term><filename>~/.xauth/import</filename></term> - <listitem> - <para>XXX</para> - </listitem> - </varlistentry> - <varlistentry> - <term><filename>~/.xauth/export</filename></term> - <listitem> - <para>XXX</para> - </listitem> - </varlistentry> - </variablelist> - </refsect1> - - - <refsect1 id='pam_xauth-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_xauth-author'> - <title>AUTHOR</title> - <para> - pam_xauth was written by Nalin Dahyabhai <nalin@redhat.com>, - based on original version by - Michael K. Johnson <johnsonm@redhat.com>. - </para> - </refsect1> - -</refentry> diff --git a/modules/pam_xauth/pam_xauth.c b/modules/pam_xauth/pam_xauth.c deleted file mode 100644 index 1135d4b7..00000000 --- a/modules/pam_xauth/pam_xauth.c +++ /dev/null @@ -1,686 +0,0 @@ -/* - * Copyright 2001-2003 Red Hat, Inc. - * - * 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 <sys/types.h> -#include <sys/fsuid.h> -#include <sys/wait.h> -#include <errno.h> -#include <fnmatch.h> -#include <grp.h> -#include <limits.h> -#include <netdb.h> -#include <pwd.h> -#include <stdarg.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <syslog.h> -#include <unistd.h> - -#define PAM_SM_SESSION - -#include <security/pam_modules.h> -#include <security/_pam_macros.h> -#include <security/pam_modutil.h> -#include <security/pam_ext.h> - -#define DATANAME "pam_xauth_cookie_file" -#define XAUTHENV "XAUTHORITY" -#define HOMEENV "HOME" -#define XAUTHDEF ".Xauthority" -#define XAUTHTMP ".xauthXXXXXX" - -/* Hurd compatibility */ -#ifndef PATH_MAX -#define PATH_MAX 4096 -#endif - -/* Possible paths to xauth executable */ -static const char * const xauthpaths[] = { -#ifdef PAM_PATH_XAUTH - PAM_PATH_XAUTH, -#endif - "/usr/X11R6/bin/xauth", - "/usr/bin/xauth", - "/usr/bin/X11/xauth" -}; - -/* Run a given command (with a NULL-terminated argument list), feeding it the - * given input on stdin, and storing any output it generates. */ -static int -run_coprocess(const char *input, char **output, - uid_t uid, gid_t gid, const char *command, ...) -{ - int ipipe[2], opipe[2], i; - char buf[LINE_MAX]; - pid_t child; - char *buffer = NULL; - size_t buffer_size = 0; - va_list ap; - - *output = NULL; - - /* Create stdio pipery. */ - if (pipe(ipipe) == -1) { - return -1; - } - if (pipe(opipe) == -1) { - close(ipipe[0]); - close(ipipe[1]); - return -1; - } - - /* Fork off a child. */ - child = fork(); - if (child == -1) { - close(ipipe[0]); - close(ipipe[1]); - close(opipe[0]); - close(opipe[1]); - return -1; - } - - if (child == 0) { - /* We're the child. */ - size_t j; - char *args[10]; - const char *tmp; - /* Drop privileges. */ - setgid(gid); - setgroups(0, NULL); - setuid(uid); - /* Initialize the argument list. */ - memset(args, 0, sizeof(args)); - /* Set the pipe descriptors up as stdin and stdout, and close - * everything else, including the original values for the - * descriptors. */ - dup2(ipipe[0], STDIN_FILENO); - dup2(opipe[1], STDOUT_FILENO); - for (i = 0; i < sysconf(_SC_OPEN_MAX); i++) { - if ((i != STDIN_FILENO) && (i != STDOUT_FILENO)) { - close(i); - } - } - /* Convert the varargs list into a regular array of strings. */ - va_start(ap, command); - args[0] = strdup(command); - for (j = 1; j < ((sizeof(args) / sizeof(args[0])) - 1); j++) { - tmp = va_arg(ap, const char*); - if (tmp == NULL) { - break; - } - args[j] = strdup(tmp); - } - /* Run the command. */ - execv(command, args); - /* Never reached. */ - exit(1); - } - - /* We're the parent, so close the other ends of the pipes. */ - close(ipipe[0]); - close(opipe[1]); - /* Send input to the process (if we have any), then send an EOF. */ - if (input) { - (void)pam_modutil_write(ipipe[1], input, strlen(input)); - } - close(ipipe[1]); - - /* Read data output until we run out of stuff to read. */ - i = pam_modutil_read(opipe[0], buf, sizeof(buf)); - while ((i != 0) && (i != -1)) { - char *tmp; - /* Resize the buffer to hold the data. */ - tmp = realloc(buffer, buffer_size + i + 1); - if (tmp == NULL) { - /* Uh-oh, bail. */ - if (buffer != NULL) { - free(buffer); - } - close(opipe[0]); - waitpid(child, NULL, 0); - return -1; - } - /* Save the new buffer location, copy the newly-read data into - * the buffer, and make sure the result will be - * nul-terminated. */ - buffer = tmp; - memcpy(buffer + buffer_size, buf, i); - buffer[buffer_size + i] = '\0'; - buffer_size += i; - /* Try to read again. */ - i = pam_modutil_read(opipe[0], buf, sizeof(buf)); - } - /* No more data. Clean up and return data. */ - close(opipe[0]); - *output = buffer; - waitpid(child, NULL, 0); - return 0; -} - -/* Free a data item. */ -static void -cleanup (pam_handle_t *pamh UNUSED, void *data, int err UNUSED) -{ - free (data); -} - -/* Check if we want to allow export to the other user, or import from the - * other user. */ -static int -check_acl(pam_handle_t *pamh, - const char *sense, const char *this_user, const char *other_user, - int noent_code, int debug) -{ - char path[PATH_MAX]; - struct passwd *pwd; - FILE *fp; - int i; - uid_t euid; - /* Check this user's <sense> file. */ - pwd = pam_modutil_getpwnam(pamh, this_user); - if (pwd == NULL) { - pam_syslog(pamh, LOG_ERR, - "error determining home directory for '%s'", - this_user); - return PAM_SESSION_ERR; - } - /* Figure out what that file is really named. */ - i = snprintf(path, sizeof(path), "%s/.xauth/%s", pwd->pw_dir, sense); - if ((i >= (int)sizeof(path)) || (i < 0)) { - pam_syslog(pamh, LOG_ERR, - "name of user's home directory is too long"); - return PAM_SESSION_ERR; - } - euid = geteuid(); - setfsuid(pwd->pw_uid); - fp = fopen(path, "r"); - setfsuid(euid); - if (fp != NULL) { - char buf[LINE_MAX], *tmp; - /* Scan the file for a list of specs of users to "trust". */ - while (fgets(buf, sizeof(buf), fp) != NULL) { - tmp = memchr(buf, '\r', sizeof(buf)); - if (tmp != NULL) { - *tmp = '\0'; - } - tmp = memchr(buf, '\n', sizeof(buf)); - if (tmp != NULL) { - *tmp = '\0'; - } - if (fnmatch(buf, other_user, 0) == 0) { - if (debug) { - pam_syslog(pamh, LOG_DEBUG, - "%s %s allowed by %s", - other_user, sense, path); - } - fclose(fp); - return PAM_SUCCESS; - } - } - /* If there's no match in the file, we fail. */ - if (debug) { - pam_syslog(pamh, LOG_DEBUG, "%s not listed in %s", - other_user, path); - } - fclose(fp); - return PAM_PERM_DENIED; - } else { - /* Default to okay if the file doesn't exist. */ - switch (errno) { - case ENOENT: - if (noent_code == PAM_SUCCESS) { - if (debug) { - pam_syslog(pamh, LOG_DEBUG, - "%s does not exist, ignoring", - path); - } - } else { - if (debug) { - pam_syslog(pamh, LOG_DEBUG, - "%s does not exist, failing", - path); - } - } - return noent_code; - default: - if (debug) { - pam_syslog(pamh, LOG_ERR, - "error opening %s: %m", path); - } - return PAM_PERM_DENIED; - } - } -} - -int -pam_sm_open_session (pam_handle_t *pamh, int flags UNUSED, - int argc, const char **argv) -{ - char *cookiefile = NULL, *xauthority = NULL, - *cookie = NULL, *display = NULL, *tmp = NULL; - const char *user, *xauth = NULL; - struct passwd *tpwd, *rpwd; - int fd, i, debug = 0; - int retval = PAM_SUCCESS; - uid_t systemuser = 499, targetuser = 0, euid; - - /* Parse arguments. We don't understand many, so no sense in breaking - * this into a separate function. */ - for (i = 0; i < argc; i++) { - if (strcmp(argv[i], "debug") == 0) { - debug = 1; - continue; - } - if (strncmp(argv[i], "xauthpath=", 10) == 0) { - xauth = argv[i] + 10; - continue; - } - if (strncmp(argv[i], "targetuser=", 11) == 0) { - long l = strtol(argv[i] + 11, &tmp, 10); - if ((strlen(argv[i] + 11) > 0) && (*tmp == '\0')) { - targetuser = l; - } else { - pam_syslog(pamh, LOG_WARNING, - "invalid value for targetuser (`%s')", - argv[i] + 11); - } - continue; - } - if (strncmp(argv[i], "systemuser=", 11) == 0) { - long l = strtol(argv[i] + 11, &tmp, 10); - if ((strlen(argv[i] + 11) > 0) && (*tmp == '\0')) { - systemuser = l; - } else { - pam_syslog(pamh, LOG_WARNING, - "invalid value for systemuser (`%s')", - argv[i] + 11); - } - continue; - } - pam_syslog(pamh, LOG_WARNING, "unrecognized option `%s'", - argv[i]); - } - - if (xauth == NULL) { - size_t j; - for (j = 0; j < sizeof(xauthpaths)/sizeof(xauthpaths[0]); j++) { - if (access(xauthpaths[j], X_OK) == 0) { - xauth = xauthpaths[j]; - break; - } - } - if (xauth == NULL) { - /* xauth executable not found - nothing to do */ - return PAM_SUCCESS; - } - } - - /* If DISPLAY isn't set, we don't really care, now do we? */ - if ((display = getenv("DISPLAY")) == NULL) { - if (debug) { - pam_syslog(pamh, LOG_DEBUG, - "user has no DISPLAY, doing nothing"); - } - return PAM_SUCCESS; - } - - /* Read the target user's name. */ - if (pam_get_user(pamh, &user, NULL) != PAM_SUCCESS) { - pam_syslog(pamh, LOG_ERR, - "error determining target user's name"); - retval = PAM_SESSION_ERR; - goto cleanup; - } - rpwd = pam_modutil_getpwuid(pamh, getuid()); - if (rpwd == NULL) { - pam_syslog(pamh, LOG_ERR, - "error determining invoking user's name"); - retval = PAM_SESSION_ERR; - goto cleanup; - } - - /* Get the target user's UID and primary GID, which we'll need to set - * on the xauthority file we create later on. */ - tpwd = pam_modutil_getpwnam(pamh, user); - if (tpwd == NULL) { - pam_syslog(pamh, LOG_ERR, - "error determining target user's UID"); - retval = PAM_SESSION_ERR; - goto cleanup; - } - - if (debug) { - pam_syslog(pamh, LOG_DEBUG, - "requesting user %lu/%lu, target user %lu/%lu", - (unsigned long) rpwd->pw_uid, - (unsigned long) rpwd->pw_gid, - (unsigned long) tpwd->pw_uid, - (unsigned long) tpwd->pw_gid); - } - - /* If the UID is a system account (and not the superuser), forget - * about forwarding keys. */ - if ((tpwd->pw_uid != 0) && - (tpwd->pw_uid != targetuser) && - (tpwd->pw_uid <= systemuser)) { - if (debug) { - pam_syslog(pamh, LOG_DEBUG, - "not forwarding cookies to user ID %lu", - (unsigned long) tpwd->pw_uid); - } - retval = PAM_SESSION_ERR; - goto cleanup; - } - - /* Check that both users are amenable to this. By default, this - * boils down to this policy: - * export(ruser=root): only if <user> is listed in .xauth/export - * export(ruser=*) if <user> is listed in .xauth/export, or - * if .xauth/export does not exist - * import(user=*): if <ruser> is listed in .xauth/import, or - * if .xauth/import does not exist */ - i = (getuid() != 0 || tpwd->pw_uid == 0) ? PAM_SUCCESS : PAM_PERM_DENIED; - i = check_acl(pamh, "export", rpwd->pw_name, user, i, debug); - if (i != PAM_SUCCESS) { - retval = PAM_SESSION_ERR; - goto cleanup; - } - i = PAM_SUCCESS; - i = check_acl(pamh, "import", user, rpwd->pw_name, i, debug); - if (i != PAM_SUCCESS) { - retval = PAM_SESSION_ERR; - goto cleanup; - } - - /* Figure out where the source user's .Xauthority file is. */ - if (getenv(XAUTHENV) != NULL) { - cookiefile = strdup(getenv(XAUTHENV)); - } else { - cookiefile = malloc(strlen(rpwd->pw_dir) + 1 + - strlen(XAUTHDEF) + 1); - if (cookiefile == NULL) { - retval = PAM_SESSION_ERR; - goto cleanup; - } - strcpy(cookiefile, rpwd->pw_dir); - strcat(cookiefile, "/"); - strcat(cookiefile, XAUTHDEF); - } - if (debug) { - pam_syslog(pamh, LOG_DEBUG, "reading keys from `%s'", - cookiefile); - } - - /* Read the user's .Xauthority file. Because the current UID is - * the original user's UID, this will only fail if something has - * gone wrong, or we have no cookies. */ - if (debug) { - pam_syslog(pamh, LOG_DEBUG, - "running \"%s %s %s %s %s\" as %lu/%lu", - xauth, "-f", cookiefile, "nlist", display, - (unsigned long) getuid(), (unsigned long) getgid()); - } - if (run_coprocess(NULL, &cookie, - getuid(), getgid(), - xauth, "-f", cookiefile, "nlist", display, - NULL) == 0) { - /* Check that we got a cookie. If not, we get creative. */ - if (((cookie == NULL) || (strlen(cookie) == 0)) && - ((strncmp(display, "localhost:", 10) == 0) || - (strncmp(display, "localhost/unix:", 15) == 0))) { - char *t, *screen; - size_t tlen, slen; - /* Free the useless cookie string. */ - if (cookie != NULL) { - free(cookie); - cookie = NULL; - } - /* Allocate enough space to hold an adjusted name. */ - tlen = strlen(display) + LINE_MAX + 1; - t = malloc(tlen); - if (t != NULL) { - memset(t, 0, tlen); - if (gethostname(t, tlen - 1) != -1) { - /* Append the protocol and then the - * screen number. */ - if (strlen(t) < tlen - 6) { - strcat(t, "/unix:"); - } - screen = strchr(display, ':'); - if (screen != NULL) { - screen++; - slen = strlen(screen); - if (strlen(t) + slen < tlen) { - strcat(t, screen); - } - } - if (debug) { - pam_syslog(pamh, LOG_DEBUG, - "no key for `%s', " - "trying `%s'", - display, t); - } - /* Read the cookie for this display. */ - if (debug) { - pam_syslog(pamh, LOG_DEBUG, - "running " - "\"%s %s %s %s %s\" as " - "%lu/%lu", - xauth, - "-f", - cookiefile, - "nlist", - t, - (unsigned long) getuid(), - (unsigned long) getgid()); - } - run_coprocess(NULL, &cookie, - getuid(), getgid(), - xauth, "-f", cookiefile, - "nlist", t, NULL); - } - free(t); - t = NULL; - } - } - - /* Check that we got a cookie, this time for real. */ - if ((cookie == NULL) || (strlen(cookie) == 0)) { - if (debug) { - pam_syslog(pamh, LOG_DEBUG, "no key"); - } - retval = PAM_SESSION_ERR; - goto cleanup; - } - - /* Generate the environment variable - * "XAUTHORITY=<homedir>/filename". */ - if (asprintf(&xauthority, "%s=%s/%s", - XAUTHENV, tpwd->pw_dir, XAUTHTMP) < 0) { - xauthority = NULL; - if (debug) { - pam_syslog(pamh, LOG_DEBUG, "out of memory"); - } - retval = PAM_SESSION_ERR; - goto cleanup; - } - - /* Generate a new file to hold the data. */ - euid = geteuid(); - setfsuid(tpwd->pw_uid); - fd = mkstemp(xauthority + strlen(XAUTHENV) + 1); - setfsuid(euid); - if (fd == -1) { - pam_syslog(pamh, LOG_ERR, - "error creating temporary file `%s': %m", - xauthority + strlen(XAUTHENV) + 1); - retval = PAM_SESSION_ERR; - goto cleanup; - } - /* Set permissions on the new file and dispose of the - * descriptor. */ - if (fchown(fd, tpwd->pw_uid, tpwd->pw_gid) < 0) - pam_syslog (pamh, LOG_ERR, "fchown: %m"); - close(fd); - - /* Get a copy of the filename to save as a data item for - * removal at session-close time. */ - free(cookiefile); - cookiefile = strdup(xauthority + strlen(XAUTHENV) + 1); - - /* Save the filename. */ - if (pam_set_data(pamh, DATANAME, cookiefile, cleanup) != PAM_SUCCESS) { - pam_syslog(pamh, LOG_ERR, - "error saving name of temporary file `%s'", - cookiefile); - unlink(cookiefile); - retval = PAM_SESSION_ERR; - goto cleanup; - } - - /* Set the new variable in the environment. */ - if (pam_putenv (pamh, xauthority) != PAM_SUCCESS) - pam_syslog(pamh, LOG_ERR, - "can't set environment variable '%s'", - xauthority); - putenv (xauthority); /* The environment owns this string now. */ - xauthority = NULL; /* Don't free environment variables. */ - - /* set $DISPLAY in pam handle to make su - work */ - { - char *d; - - if (asprintf(&d, "DISPLAY=%s", display) < 0) - { - pam_syslog(pamh, LOG_DEBUG, "out of memory"); - cookiefile = NULL; - retval = PAM_SESSION_ERR; - goto cleanup; - } - - if (pam_putenv (pamh, d) != PAM_SUCCESS) - pam_syslog (pamh, LOG_DEBUG, - "can't set environment variable '%s'", d); - free (d); - } - - /* Merge the cookie we read before into the new file. */ - if (debug) { - pam_syslog(pamh, LOG_DEBUG, - "writing key `%s' to temporary file `%s'", - cookie, cookiefile); - } - if (debug) { - pam_syslog(pamh, LOG_DEBUG, - "running \"%s %s %s %s %s\" as %lu/%lu", - xauth, "-f", cookiefile, "nmerge", "-", - (unsigned long) tpwd->pw_uid, - (unsigned long) tpwd->pw_gid); - } - run_coprocess(cookie, &tmp, - tpwd->pw_uid, tpwd->pw_gid, - xauth, "-f", cookiefile, "nmerge", "-", NULL); - - /* We don't need to keep a copy of these around any more. */ - cookiefile = NULL; - free(tmp); - } -cleanup: - /* Unset any old XAUTHORITY variable in the environment. */ - if (retval != PAM_SUCCESS && getenv (XAUTHENV)) - unsetenv (XAUTHENV); - free(cookiefile); - free(cookie); - free(xauthority); - return retval; -} - -int -pam_sm_close_session (pam_handle_t *pamh, int flags UNUSED, - int argc, const char **argv) -{ - void *cookiefile; - int i, debug = 0; - - /* Parse arguments. We don't understand many, so no sense in breaking - * this into a separate function. */ - for (i = 0; i < argc; i++) { - if (strcmp(argv[i], "debug") == 0) { - debug = 1; - continue; - } - if (strncmp(argv[i], "xauthpath=", 10) == 0) { - continue; - } - if (strncmp(argv[i], "systemuser=", 11) == 0) { - continue; - } - if (strncmp(argv[i], "targetuser=", 11) == 0) { - continue; - } - pam_syslog(pamh, LOG_WARNING, "unrecognized option `%s'", - argv[i]); - } - - /* Try to retrieve the name of a file we created when the session was - * opened. */ - if (pam_get_data(pamh, DATANAME, (const void**) &cookiefile) == PAM_SUCCESS) { - /* We'll only try to remove the file once. */ - if (strlen((char*)cookiefile) > 0) { - if (debug) { - pam_syslog(pamh, LOG_DEBUG, "removing `%s'", - (char*)cookiefile); - } - unlink((char*)cookiefile); - *((char*)cookiefile) = '\0'; - } - } - return PAM_SUCCESS; -} - -/* static module data */ -#ifdef PAM_STATIC -struct pam_module _pam_xauth_modstruct = { - "pam_xauth", - NULL, - NULL, - NULL, - pam_sm_open_session, - pam_sm_close_session, - NULL -}; -#endif diff --git a/modules/pam_xauth/tst-pam_xauth b/modules/pam_xauth/tst-pam_xauth deleted file mode 100755 index 32948963..00000000 --- a/modules/pam_xauth/tst-pam_xauth +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/sh -../../tests/tst-dlopen .libs/pam_xauth.so |