diff --git a/pam-0.99.8.1-tty-audit.patch b/pam-0.99.8.1-tty-audit.patch new file mode 100644 index 0000000..ead4837 --- /dev/null +++ b/pam-0.99.8.1-tty-audit.patch @@ -0,0 +1,590 @@ +Written-by: Miloslav Trmac +Reviewed-by: Tomas Mraz +diff -urN Linux-PAM/configure.in Linux-PAM-0.99.8.1/configure.in +--- Linux-PAM/configure.in 2007-11-28 13:41:14.000000000 +0100 ++++ Linux-PAM-0.99.8.1/configure.in 2007-11-28 14:35:30.000000000 +0100 +@@ -331,7 +331,11 @@ + WITH_LIBAUDIT=$enableval, WITH_LIBAUDIT=yes) + if test x"$WITH_LIBAUDIT" != xno ; then + AC_CHECK_HEADER([libaudit.h], +- [AC_CHECK_LIB(audit, audit_log_acct_message, LIBAUDIT=-laudit, LIBAUDIT="")] ++ [AC_CHECK_LIB(audit, audit_log_acct_message, LIBAUDIT=-laudit, LIBAUDIT="") ++ AC_CHECK_TYPE([struct audit_tty_status], ++ [HAVE_AUDIT_TTY_STATUS=yes], ++ [HAVE_AUDIT_TTY_STATUS=""], ++ [#include ])] + ) + if test ! -z "$LIBAUDIT" -a "ac_cv_header_libaudit_h" != "no" ; then + AC_DEFINE([HAVE_LIBAUDIT], 1, [Defined if audit support should be compiled in]) +@@ -340,6 +344,8 @@ + LIBAUDIT="" + fi + AC_SUBST(LIBAUDIT) ++AM_CONDITIONAL([HAVE_AUDIT_TTY_STATUS], ++ [test "x$HAVE_AUDIT_TTY_STATUS" = xyes]) + + BACKUP_LIBS=$LIBS + AC_SEARCH_LIBS([crypt],[xcrypt crypt], LIBCRYPT="-l$ac_lib", LIBCRYPT="") +@@ -517,7 +523,8 @@ + modules/pam_securetty/Makefile modules/pam_selinux/Makefile \ + modules/pam_shells/Makefile modules/pam_stress/Makefile \ + modules/pam_succeed_if/Makefile modules/pam_tally/Makefile \ +- modules/pam_time/Makefile modules/pam_umask/Makefile \ ++ modules/pam_time/Makefile modules/pam_tty_audit/Makefile \ ++ modules/pam_umask/Makefile \ + modules/pam_unix/Makefile modules/pam_userdb/Makefile \ + modules/pam_warn/Makefile modules/pam_wheel/Makefile \ + modules/pam_xauth/Makefile doc/Makefile doc/specs/Makefile \ +diff -urN Linux-PAM/modules/Makefile.am Linux-PAM-0.99.8.1/modules/Makefile.am +--- Linux-PAM/modules/Makefile.am 2007-11-28 13:41:13.000000000 +0100 ++++ Linux-PAM-0.99.8.1/modules/Makefile.am 2007-11-28 14:02:48.000000000 +0100 +@@ -9,8 +9,8 @@ + 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_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_loginuid \ ++ 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 = *~ +diff -urN Linux-PAM/modules/pam_tty_audit/Makefile.am Linux-PAM-0.99.8.1/modules/pam_tty_audit/Makefile.am +--- Linux-PAM/modules/pam_tty_audit/Makefile.am 1970-01-01 01:00:00.000000000 +0100 ++++ Linux-PAM-0.99.8.1/modules/pam_tty_audit/Makefile.am 2007-11-28 16:05:00.000000000 +0100 +@@ -0,0 +1,30 @@ ++# ++# Copyright (c) 2005, 2006 Thorsten Kukuk ++# ++ ++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 \ ++ -L$(top_builddir)/libpam -lpam ++if HAVE_VERSIONING ++ AM_LDFLAGS += -Wl,--version-script=$(srcdir)/../modules.map ++endif ++ ++if HAVE_AUDIT_TTY_STATUS ++ 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 -urN Linux-PAM/modules/pam_tty_audit/pam_tty_audit.c Linux-PAM-0.99.8.1/modules/pam_tty_audit/pam_tty_audit.c +--- Linux-PAM/modules/pam_tty_audit/pam_tty_audit.c 1970-01-01 01:00:00.000000000 +0100 ++++ Linux-PAM-0.99.8.1/modules/pam_tty_audit/pam_tty_audit.c 2007-11-28 16:10:43.000000000 +0100 +@@ -0,0 +1,332 @@ ++/* Copyright © 2007 Red Hat, Inc. All rights reserved. ++ Red Hat author: Miloslav Trmač ++ ++ 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 ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++#include ++ ++#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; ++ uid_t user_uid; ++ struct passwd *pwd; ++ int i, fd; ++ ++ (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; ++ } ++ pwd = pam_modutil_getpwnam (pamh, user); ++ if (pwd == NULL) ++ { ++ pam_syslog (pamh, LOG_ERR, "error determining target user's UID: %m"); ++ return PAM_SESSION_ERR; ++ } ++ user_uid = pwd->pw_uid; ++ ++ command = CMD_NONE; ++ 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)) ++ { ++ pwd = pam_modutil_getpwnam (pamh, tok); ++ if (pwd == NULL) ++ { ++ pam_syslog (pamh, LOG_WARNING, "unknown user %s", tok); ++ continue; ++ } ++ if (pwd->pw_uid == user_uid) ++ { ++ command = this_command; ++ break; ++ } ++ } ++ free (copy); ++ } ++ } ++ 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; ++ } ++ ++ if (old_status->enabled == (command == CMD_ENABLE ? 1 : 0)) ++ { ++ free (old_status); ++ goto ok_fd; ++ } ++ ++ if (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; ++ } ++ ++ new_status.enabled = (command == CMD_ENABLE ? 1 : 0); ++ 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); ++ 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); ++ 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; ++} +diff -urN Linux-PAM/modules/pam_tty_audit/pam_tty_audit.8.xml Linux-PAM-0.99.8.1/modules/pam_tty_audit/pam_tty_audit.8.xml +--- Linux-PAM/modules/pam_tty_audit/pam_tty_audit.8.xml 1970-01-01 01:00:00.000000000 +0100 ++++ Linux-PAM-0.99.8.1/modules/pam_tty_audit/pam_tty_audit.8.xml 2007-11-28 15:50:22.000000000 +0100 +@@ -0,0 +1,125 @@ ++ ++ ++ ++ ++ ++ ++ pam_tty_audit ++ 8 ++ Linux-PAM Manual ++ ++ ++ ++ pam_tty_audit ++ Enable or disable TTY auditing for specified users ++ ++ ++ ++ ++ pam_tty_audit.so ++ ++ disable=usernames ++ ++ ++ enable=usernames ++ ++ ++ ++ ++ ++ DESCRIPTION ++ ++ 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. ++ ++ ++ ++ ++ OPTIONS ++ ++ ++ ++ ++ ++ ++ ++ For each user matching one of comma-separated ++ , disable ++ TTY auditing. This overrides any older ++ option for the same user name. ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ For each user matching one of comma-separated ++ , enable ++ TTY auditing. This overrides any older ++ option for the same user name. ++ ++ ++ ++ ++ ++ ++ ++ MODULE SERVICES PROVIDED ++ ++ Only the session service is supported. ++ ++ ++ ++ ++ RETURN VALUES ++ ++ ++ PAM_SESSION_ERR ++ ++ ++ Error reading or modifying the TTY audit flag. See the system log ++ for more details. ++ ++ ++ ++ ++ ++ PAM_SUCCESS ++ ++ ++ Success. ++ ++ ++ ++ ++ ++ ++ ++ ++ EXAMPLES ++ ++ Audit all administrative actions. ++ ++login root required pam_tty_audit.so enable=root ++su root required pam_tty_audit.so enable=root ++su-l root required pam_tty_audit.so enable=root ++sudo root required pam_tty_audit.so enable=root ++sudo-l root required pam_tty_audit.so enable=root ++sshd root required pam_tty_audit.so enable=root ++ ++ ++ ++ ++ ++ AUTHOR ++ ++ pam_tty_audit was written by Miloslav Trmač ++ <mitr@redhat.com>. ++ ++ ++ ++ +diff -urN Linux-PAM/modules/pam_tty_audit/README.xml Linux-PAM-0.99.8.1/modules/pam_tty_audit/README.xml +--- Linux-PAM/modules/pam_tty_audit/README.xml 1970-01-01 01:00:00.000000000 +0100 ++++ Linux-PAM-0.99.8.1/modules/pam_tty_audit/README.xml 2007-11-28 15:52:50.000000000 +0100 +@@ -0,0 +1,36 @@ ++ ++ ++ ++
++ ++ ++ ++ ++ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" ++ href="pam_tty_audit.8.xml" xpointer='xpointer(//refnamediv[@id = "pam_tty_audit-name"]/*)'/> ++ ++ ++ ++ ++
++ ++
++ ++
++ ++
++ ++
++ ++
++ ++
++ ++
++ ++
diff --git a/pam.spec b/pam.spec index cd2d790..1cfb032 100644 --- a/pam.spec +++ b/pam.spec @@ -11,7 +11,7 @@ Summary: A security tool which provides authentication for applications Name: pam Version: 0.99.8.1 -Release: 11%{?dist} +Release: 12%{?dist} # The library is BSD licensed with option to relicense as GPLv2+ - this option is redundant # as the BSD license allows that anyway. pam_timestamp and pam_console modules are GPLv2+, # pam_rhosts_auth module is BSD with advertising @@ -45,6 +45,7 @@ Patch45: pam-0.99.8.1-selinux-permit.patch Patch46: pam-0.99.8.1-succif-in-operator.patch Patch47: pam-0.99.8.1-xauth-no-free.patch Patch48: pam-0.99.8.1-substack.patch +Patch49: pam-0.99.8.1-tty-audit.patch BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) Requires: cracklib, cracklib-dicts >= 2.8 @@ -117,6 +118,7 @@ popd %patch46 -p1 -b .in-operator %patch47 -p1 -b .no-free %patch48 -p0 -b .substack +%patch49 -p1 -b .tty-audit autoreconf @@ -365,6 +367,7 @@ fi /%{_lib}/security/pam_tally2.so /%{_lib}/security/pam_time.so /%{_lib}/security/pam_timestamp.so +/%{_lib}/security/pam_tty_audit.so /%{_lib}/security/pam_umask.so /%{_lib}/security/pam_unix.so /%{_lib}/security/pam_unix_acct.so @@ -409,6 +412,9 @@ fi %doc doc/adg/*.txt doc/adg/html %changelog +* Thu Nov 29 2007 Tomas Mraz 0.99.8.1-12 +- add pam_tty_audit module (#244352) - written by Miloslav Trmač + * Wed Nov 7 2007 Tomas Mraz 0.99.8.1-11 - add substack support