]> granicus.if.org Git - linux-pam/commitdiff
Relevant BUGIDs:
authorThorsten Kukuk <kukuk@thkukuk.de>
Tue, 29 Aug 2006 16:21:31 +0000 (16:21 +0000)
committerThorsten Kukuk <kukuk@thkukuk.de>
Tue, 29 Aug 2006 16:21:31 +0000 (16:21 +0000)
Purpose of commit: new feature

Commit summary:
---------------

As discussed with Tomas I'm adding the pam_loginuid module from RH
to make the SELinux/Audit stack complete:

2006-08-29  Thorsten Kukuk  <kukuk@thkukuk.de>

        * doc/sag/pam_loginuid.xml: New.
        * doc/sag/Linux-PAM_SAG.xml: Include pam_loginuid.xml.

        * configure.in: Add modules/pam_loginuid/Makefile.
        * modules/Makefile.am: Add pam_loginuid sub directory.

        * libpam/pam_static_modules.h: Add pam_loginuid.

        * modules/pam_loginuid/Makefile.am: New.
        * modules/pam_loginuid/tst-pam_loginuid: New.
        * modules/pam_loginuid/pam_loginuid.8.xml: New.
        * modules/pam_loginuid/pam_loginuid.8: New, generated from XML source.
        * modules/pam_loginuid/pam_loginuid.c: New.
        * modules/pam_loginuid/README.xml: New.
        * modules/pam_loginuid/README: New, generated from XML source.

15 files changed:
ChangeLog
NEWS
configure.in
doc/sag/Linux-PAM_SAG.xml
doc/sag/pam_loginuid.xml [new file with mode: 0644]
libpam/pam_static_modules.h
modules/Makefile.am
modules/pam_loginuid/.cvsignore [new file with mode: 0644]
modules/pam_loginuid/Makefile.am [new file with mode: 0644]
modules/pam_loginuid/README [new file with mode: 0644]
modules/pam_loginuid/README.xml [new file with mode: 0644]
modules/pam_loginuid/pam_loginuid.8 [new file with mode: 0644]
modules/pam_loginuid/pam_loginuid.8.xml [new file with mode: 0644]
modules/pam_loginuid/pam_loginuid.c [new file with mode: 0644]
modules/pam_loginuid/tst-pam_loginuid [new file with mode: 0755]

index bef9c28a9e42f2d94d15c7acfed6b2d38aec8f21..93b5cf899739c8603da57c87faa0f3e52ba1b9fc 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,21 @@
+2006-08-29  Thorsten Kukuk  <kukuk@thkukuk.de>
+
+       * doc/sag/pam_loginuid.xml: New.
+       * doc/sag/Linux-PAM_SAG.xml: Include pam_loginuid.xml.
+
+       * configure.in: Add modules/pam_loginuid/Makefile.
+       * modules/Makefile.am: Add pam_loginuid sub directory.
+
+       * libpam/pam_static_modules.h: Add pam_loginuid.
+
+       * modules/pam_loginuid/Makefile.am: New.
+       * modules/pam_loginuid/tst-pam_loginuid: New.
+       * modules/pam_loginuid/pam_loginuid.8.xml: New.
+       * modules/pam_loginuid/pam_loginuid.8: New, generated from XML source.
+       * modules/pam_loginuid/pam_loginuid.c: New.
+       * modules/pam_loginuid/README.xml: New.
+       * modules/pam_loginuid/README: New, generated from XML source.
+
 2006-08-29  Dmitry V. Levin  <ldv@altlinux.org>
 
        * modules/pam_exec/pam_exec.c (call_exec): Add required third
diff --git a/NEWS b/NEWS
index 780b545ca9d7ac72ca92b7790afb6a5e025ae2c8..e9292068500b0fc7a65615d9118d344741549cfc 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -1,6 +1,11 @@
 Linux-PAM NEWS -- history of user-visible changes.
 
 
+Release 0.99.6.3
+
+* pam_loginuid: New PAM module.
+
+
 Release 0.99.6.2
 
 * pam_lastlog: Don't refuse login if lastlog file got lost.
index 0d59a1769d237c6d154296e6ee649f3add558528..e714814e1e867a037b442e87d2a6ac793e445b63 100644 (file)
@@ -477,10 +477,10 @@ AC_OUTPUT(Makefile libpam/Makefile libpamc/Makefile libpamc/test/Makefile \
        modules/pam_echo/Makefile modules/pam_env/Makefile \
        modules/pam_filter/Makefile modules/pam_filter/upperLOWER/Makefile \
        modules/pam_ftp/Makefile modules/pam_group/Makefile \
-       modules/pam_issue/Makefile \
-       modules/pam_keyinit/Makefile modules/pam_lastlog/Makefile \
-       modules/pam_limits/Makefile modules/pam_listfile/Makefile \
-       modules/pam_localuser/Makefile modules/pam_mail/Makefile \
+       modules/pam_issue/Makefile modules/pam_keyinit/Makefile \
+       modules/pam_lastlog/Makefile modules/pam_limits/Makefile \
+       modules/pam_listfile/Makefile modules/pam_localuser/Makefile \
+       modules/pam_loginuid/Makefile modules/pam_mail/Makefile \
        modules/pam_mkhomedir/Makefile modules/pam_motd/Makefile \
        modules/pam_namespace/Makefile \
        modules/pam_nologin/Makefile modules/pam_permit/Makefile \
index 1be4c338525b2eaa1d677040e1b0d867238615d5..605516c04618f8671b5ff07a5351b6c867e33a83 100644 (file)
@@ -426,6 +426,8 @@ session   required   pam_warn.so
      href="pam_listfile.xml"/>
     <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
      href="pam_localuser.xml"/>
+    <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+     href="pam_loginuid.xml"/>
     <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
      href="pam_mail.xml"/>
     <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
diff --git a/doc/sag/pam_loginuid.xml b/doc/sag/pam_loginuid.xml
new file mode 100644 (file)
index 0000000..6166d99
--- /dev/null
@@ -0,0 +1,34 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!DOCTYPE section PUBLIC "-//OASIS//DTD DocBook XML V4.4//EN"
+        "http://www.oasis-open.org/docbook/xml/4.4/docbookx.dtd">
+<section id='sag-pam_loginuid'>
+  <title>pam_loginuid - record user's login uid to the process attribute</title>
+  <cmdsynopsis>
+    <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+     href="../../modules/pam_loginuid/pam_loginuid.8.xml" xpointer='xpointer(//cmdsynopsis[@id = "pam_loginuid-cmdsynopsis"]/*)'/>
+  </cmdsynopsis>
+  <section id='sag-pam_loginuid-description'>
+    <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+     href="../../modules/pam_loginuid/pam_loginuid.8.xml" xpointer='xpointer(//refsect1[@id = "pam_loginuid-description"]/*)'/>
+  </section>
+  <section id='sag-pam_loginuid-options'>
+    <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+     href="../../modules/pam_loginuid/pam_loginuid.8.xml" xpointer='xpointer(//refsect1[@id = "pam_loginuid-options"]/*)'/>
+  </section>
+  <section id='sag-pam_loginuid-services'>
+    <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+     href="../../modules/pam_loginuid/pam_loginuid.8.xml" xpointer='xpointer(//refsect1[@id = "pam_loginuid-services"]/*)'/>
+  </section>
+  <section id='sag-pam_loginuid-return_values'>
+    <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+     href="../../modules/pam_loginuid/pam_loginuid.8.xml" xpointer='xpointer(//refsect1[@id = "pam_loginuid-return_values"]/*)'/>
+  </section>
+  <section id='sag-pam_loginuid-examples'>
+    <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+     href="../../modules/pam_loginuid/pam_loginuid.8.xml" xpointer='xpointer(//refsect1[@id = "pam_loginuid-examples"]/*)'/>
+  </section>
+  <section id='sag-pam_loginuid-author'>
+    <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+     href="../../modules/pam_loginuid/pam_loginuid.8.xml" xpointer='xpointer(//refsect1[@id = "pam_loginuid-author"]/*)'/>
+  </section>
+</section>
index 92a367ac0c2c7c4f6502f619394dfc3760fa7f98..b7f5cf88340f7d444b82a7cfc597ba762fdfcc51 100644 (file)
@@ -49,6 +49,7 @@ extern struct pam_module _pam_lastlog_modstruct;
 extern struct pam_module _pam_limits_modstruct;
 extern struct pam_module _pam_listfile_modstruct;
 extern struct pam_module _pam_localuser_modstruct;
+extern struct pam_module _pam_loginuid_modstruct;
 extern struct pam_module _pam_mail_modstruct;
 extern struct pam_module _pam_mkhomedir_modstruct;
 extern struct pam_module _pam_motd_modstruct;
@@ -99,6 +100,7 @@ static struct pam_module *static_modules[] = {
   &_pam_limits_modstruct,
   &_pam_listfile_modstruct,
   &_pam_localuser_modstruct,
+  &_pam_loginuid_modstruct,
   &_pam_mail_modstruct,
   &_pam_mkhomedir_modstruct,
   &_pam_motd_modstruct,
index 300f1955c5936a6ba5e4315e69eca7e5d9e6046e..9afee1d599538c5ed8e1f5cb70722b8a540ddc1a 100644 (file)
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2005 Thorsten Kukuk <kukuk@suse.de>
+# Copyright (c) 2005, 2006 Thorsten Kukuk <kukuk@thkukuk.de>
 #
 
 SUBDIRS = pam_access pam_cracklib pam_debug pam_deny pam_echo \
@@ -8,7 +8,7 @@ SUBDIRS = pam_access pam_cracklib pam_debug pam_deny pam_echo \
        pam_mkhomedir pam_motd pam_nologin pam_permit pam_rhosts pam_rootok \
        pam_securetty pam_selinux pam_shells pam_stress pam_succeed_if \
        pam_tally pam_time pam_umask pam_unix pam_userdb pam_warn \
-       pam_wheel pam_xauth pam_exec pam_namespace
+       pam_wheel pam_xauth pam_exec pam_namespace pam_loginuid
 
 CLEANFILES = *~
 
diff --git a/modules/pam_loginuid/.cvsignore b/modules/pam_loginuid/.cvsignore
new file mode 100644 (file)
index 0000000..2a3d8d2
--- /dev/null
@@ -0,0 +1,7 @@
+*.la
+*.lo
+.deps
+.libs
+Makefile
+Makefile.in
+pam_loginuid
diff --git a/modules/pam_loginuid/Makefile.am b/modules/pam_loginuid/Makefile.am
new file mode 100644 (file)
index 0000000..d4fd326
--- /dev/null
@@ -0,0 +1,34 @@
+#
+# 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 \
+       -L$(top_builddir)/libpam -lpam
+if HAVE_VERSIONING
+  AM_LDFLAGS += -Wl,--version-script=$(srcdir)/../modules.map
+endif
+
+securelib_LTLIBRARIES = pam_loginuid.la
+
+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 b/modules/pam_loginuid/README
new file mode 100644 (file)
index 0000000..c8b0eb0
--- /dev/null
@@ -0,0 +1,29 @@
+pam_loginuid — Record user's login uid to the process attribute
+
+━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+
+DESCRIPTION
+
+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, at, and remote. 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.
+
+EXAMPLES
+
+#%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
+
+
+AUTHOR
+
+pam_loginuid was written by Steve Grubb <sgrubb@redhat.com>
+
diff --git a/modules/pam_loginuid/README.xml b/modules/pam_loginuid/README.xml
new file mode 100644 (file)
index 0000000..3bcd38a
--- /dev/null
@@ -0,0 +1,36 @@
+<?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 b/modules/pam_loginuid/pam_loginuid.8
new file mode 100644 (file)
index 0000000..55485e9
--- /dev/null
@@ -0,0 +1,59 @@
+.\"     Title: pam_loginuid
+.\"    Author: 
+.\" Generator: DocBook XSL Stylesheets vsnapshot_2006\-08\-24_0226 <http://docbook.sf.net/>
+.\"      Date: 08/29/2006
+.\"    Manual: Linux\-PAM Manual
+.\"    Source: Linux\-PAM Manual
+.\"
+.TH "PAM_LOGINUID" "8" "08/29/2006" "Linux\-PAM Manual" "Linux\-PAM Manual"
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.SH "NAME"
+pam_loginuid \- Record user's login uid to the process attribute
+.SH "SYNOPSIS"
+.HP 16
+\fBpam_loginuid.so\fR [require_auditd]
+.SH "DESCRIPTION"
+.PP
+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, at, and remote. 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.
+.SH "OPTIONS"
+.TP 3n
+\fBrequire_auditd\fR
+This option, when given, will cause this module to query the audit daemon status and deny logins if it is not running.
+.SH "MODULE SERVICES PROVIDED"
+.PP
+The
+\fBsession\fR
+service is supported.
+.SH "RETURN VALUES"
+.PP
+.TP 3n
+PAM_SESSION_ERR
+An error occured during session management.
+.SH "EXAMPLES"
+.sp
+.RS 3n
+.nf
+#%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
+    
+.fi
+.RE
+.SH "SEE ALSO"
+.PP
+
+\fBpam.conf\fR(5),
+\fBpam.d\fR(8),
+\fBpam\fR(8),
+\fBauditctl\fR(8),
+\fBauditd\fR(8)
+.SH "AUTHOR"
+.PP
+pam_loginuid was written by Steve Grubb <sgrubb@redhat.com>
diff --git a/modules/pam_loginuid/pam_loginuid.8.xml b/modules/pam_loginuid/pam_loginuid.8.xml
new file mode 100644 (file)
index 0000000..7022d9a
--- /dev/null
@@ -0,0 +1,125 @@
+<?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, at, and
+      remote. 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 &lt;sgrubb@redhat.com&gt;
+      </para>
+  </refsect1>
+
+</refentry>
diff --git a/modules/pam_loginuid/pam_loginuid.c b/modules/pam_loginuid/pam_loginuid.c
new file mode 100644 (file)
index 0000000..13d915e
--- /dev/null
@@ -0,0 +1,240 @@
+/* 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) {
+               int loglevel = LOG_DEBUG;
+               if (errno != ENOENT) {
+                       rc = 1;
+                       loglevel = LOG_ERR;
+               }
+               pam_syslog(pamh, loglevel, "set_loginuid failed opening loginuid");
+               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
new file mode 100755 (executable)
index 0000000..bd1e83b
--- /dev/null
@@ -0,0 +1,2 @@
+#!/bin/sh
+../../tests/tst-dlopen .libs/pam_loginuid.so