summaryrefslogtreecommitdiff
path: root/modules/pam_echo
diff options
context:
space:
mode:
authorThorsten Kukuk <kukuk@thkukuk.de>2005-09-20 11:56:54 +0000
committerThorsten Kukuk <kukuk@thkukuk.de>2005-09-20 11:56:54 +0000
commit0c3724a3e14b7c95f47f2f083ebc5c00dd5c2afe (patch)
treeda7388b27ba270b7fbb63d8defcf3316d3366455 /modules/pam_echo
parentcff33b6413b03978d6289542f9aec790f0785783 (diff)
Relevant BUGIDs: none
Purpose of commit: new feature Commit summary: --------------- Add pam_echo module
Diffstat (limited to 'modules/pam_echo')
-rw-r--r--modules/pam_echo/.cvsignore2
-rw-r--r--modules/pam_echo/Makefile.am22
-rw-r--r--modules/pam_echo/pam_echo.852
-rw-r--r--modules/pam_echo/pam_echo.c263
4 files changed, 339 insertions, 0 deletions
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 <kukuk@suse.de>
+#
+
+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 <kukuk@suse.de>
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 <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>
+
+#define PAM_SM_ACCOUNT
+#define PAM_SM_AUTH
+#define PAM_SM_PASSWORD
+#define PAM_SM_SESSION
+
+#include <security/pam_modules.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;
+ 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