From 0c3724a3e14b7c95f47f2f083ebc5c00dd5c2afe Mon Sep 17 00:00:00 2001 From: Thorsten Kukuk Date: Tue, 20 Sep 2005 11:56:54 +0000 Subject: [PATCH] Relevant BUGIDs: none Purpose of commit: new feature Commit summary: --------------- Add pam_echo module --- configure.in | 4 +- modules/Makefile.am | 8 +- modules/pam_echo/.cvsignore | 2 + modules/pam_echo/Makefile.am | 22 +++ modules/pam_echo/pam_echo.8 | 52 +++++++ modules/pam_echo/pam_echo.c | 263 +++++++++++++++++++++++++++++++++++ 6 files changed, 345 insertions(+), 6 deletions(-) create mode 100644 modules/pam_echo/.cvsignore create mode 100644 modules/pam_echo/Makefile.am create mode 100644 modules/pam_echo/pam_echo.8 create mode 100644 modules/pam_echo/pam_echo.c diff --git a/configure.in b/configure.in index acd2951f..f3480b5d 100644 --- a/configure.in +++ b/configure.in @@ -380,8 +380,8 @@ AC_OUTPUT(Makefile libpam/Makefile libpamc/Makefile libpamc/test/Makefile \ modules/Makefile modules/pammodutil/Makefile \ modules/pam_access/Makefile modules/pam_cracklib/Makefile \ modules/pam_debug/Makefile modules/pam_deny/Makefile \ - modules/pam_env/Makefile modules/pam_filter/Makefile \ - modules/pam_filter/upperLOWER/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_lastlog/Makefile \ modules/pam_limits/Makefile modules/pam_listfile/Makefile \ diff --git a/modules/Makefile.am b/modules/Makefile.am index f9a04570..afa3e621 100644 --- a/modules/Makefile.am +++ b/modules/Makefile.am @@ -2,10 +2,10 @@ # Copyright (c) 2005 Thorsten Kukuk # -SUBDIRS = pammodutil pam_access pam_cracklib pam_debug pam_deny pam_env \ - pam_filter pam_ftp pam_group pam_issue pam_lastlog pam_limits \ - pam_listfile pam_localuser pam_mail pam_mkhomedir pam_motd \ - pam_nologin pam_permit pam_pwdb pam_rhosts pam_rootok \ +SUBDIRS = pammodutil pam_access pam_cracklib pam_debug pam_deny pam_echo \ + pam_env pam_filter pam_ftp pam_group pam_issue pam_lastlog \ + pam_limits pam_listfile pam_localuser pam_mail pam_mkhomedir \ + pam_motd pam_nologin pam_permit pam_pwdb 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 diff --git a/modules/pam_echo/.cvsignore b/modules/pam_echo/.cvsignore new file mode 100644 index 00000000..282522db --- /dev/null +++ b/modules/pam_echo/.cvsignore @@ -0,0 +1,2 @@ +Makefile +Makefile.in diff --git a/modules/pam_echo/Makefile.am b/modules/pam_echo/Makefile.am new file mode 100644 index 00000000..663e7ab9 --- /dev/null +++ b/modules/pam_echo/Makefile.am @@ -0,0 +1,22 @@ +# +# Copyright (c) 2005 Thorsten Kukuk +# + +CLEANFILES = *~ + +EXTRA_DIST = $(MANS) + +man_MANS = pam_echo.8 + +securelibdir = $(SECUREDIR) +secureconfdir = $(SCONFIGDIR) + +AM_CFLAGS = -I$(top_srcdir)/libpam/include -I$(top_srcdir)/libpamc/include \ + -I$(top_srcdir)/modules/pammodutil/include/ +AM_LDFLAGS = -no-undefined -avoid-version -module \ + -L$(top_builddir)/libpam -lpam +if HAVE_VERSIONING + AM_LDFLAGS += -Wl,--version-script=../modules.map +endif + +securelib_LTLIBRARIES = pam_echo.la diff --git a/modules/pam_echo/pam_echo.8 b/modules/pam_echo/pam_echo.8 new file mode 100644 index 00000000..6834ae01 --- /dev/null +++ b/modules/pam_echo/pam_echo.8 @@ -0,0 +1,52 @@ +.\" -*- nroff -*- +.\" Copyright (c) 2005 Thorsten Kukuk kukuk@suse.de +.\" +.TH pam_echo 8 "September 2005" "pam_echo" "Reference Manual" +.SH NAME +pam_echo - PAM module for printing text messages +.SH DESCRIPTION +The +.B pam_echo +PAM module is for printing text messages to inform user about +special things. Sequences starting with the +.B % +character are interpreted in the following way: +.TP +.B %H +The name of the remote host (PAM_RHOST). +.TP +.B %h +The name of the local host. +.TP +.B %s +The service name (PAM_SERVICE). +.TP +.B %t +The name of the controlling terminal (PAM_TTY). +.TP +.B %U +The remote user name (PAM_RUSER). +.TP +.B %u +The local user name (PAM_USER). +.PP +All other sequences beginning with +.B % +expands to the characters following the +.B % +character. +.SH OPTIONS +The following options may be passed to all types of management +groups: +.TP +.BR "file=" "message" +.B pam_echo +will print the content of the file +.B message +with the PAM conversion function as PAM_TEXT_INFO. +.SH "SEE ALSO" +.BR pam.conf (8), +.BR pam.d (8), +.BR pam (8) +.SH AUTHOR +Thorsten Kukuk diff --git a/modules/pam_echo/pam_echo.c b/modules/pam_echo/pam_echo.c new file mode 100644 index 00000000..e13b8f94 --- /dev/null +++ b/modules/pam_echo/pam_echo.c @@ -0,0 +1,263 @@ +/* + * Copyright (c) 2005 Thorsten Kukuk + * + * 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define PAM_SM_ACCOUNT +#define PAM_SM_AUTH +#define PAM_SM_PASSWORD +#define PAM_SM_SESSION + +#include +#include +#include + +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; + 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_IGNORE; + } + + 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; + + 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'; + + 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_IGNORE; + + if (read (fd, mtmp, st.st_size) == -1) + { + pam_syslog (pamh, LOG_ERR, "Error while reading %s: %s", + file, strerror (errno)); + 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); + replace_and_print (pamh, mtmp); + free (mtmp); + } + else + pam_syslog (pamh, LOG_ERR, "Cannot open %s: %s", + file, strerror (errno)); + + return PAM_IGNORE; +} + +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 -- 2.40.0