diff options
author | William Jon McCann <mccann@jhu.edu> | 2007-03-01 14:24:27 -0500 |
---|---|---|
committer | William Jon McCann <mccann@jhu.edu> | 2007-03-01 14:24:27 -0500 |
commit | 1d1b98cd17764be77b1aee79efae8e89ce7faa04 (patch) | |
tree | a7cb12bfcbf9061b26c9d274781d00361f4667fd | |
parent | e37a78dfc5abcb3b02cb5debaa24122fa9b949c4 (diff) |
add a test program for the PAM module
Basically this is a mini login. It authenticates, opens a session,
sleeps 20 seconds, and then closes the session.
-rw-r--r-- | configure.ac | 4 | ||||
-rw-r--r-- | pam-ck-connector/Makefile.am | 38 | ||||
-rw-r--r-- | pam-ck-connector/pam-ck-connector.c | 2 | ||||
-rw-r--r-- | pam-ck-connector/test-pam.c | 135 |
4 files changed, 174 insertions, 5 deletions
diff --git a/configure.ac b/configure.ac index 1e2c1aa..4b8f8ba 100644 --- a/configure.ac +++ b/configure.ac @@ -206,7 +206,11 @@ fi have_pam=no AC_CHECK_LIB(pam, pam_getenv, have_pam=yes) AM_CONDITIONAL(HAVE_PAM, test x$have_pam = xyes) +if test "x$have_pam" = "xyes"; then + PAM_LIBS="${PAM_LIBS} -lpam" +fi AC_SUBST(HAVE_PAM) +AC_SUBST(PAM_LIBS) # # Check if we should build the PAM module diff --git a/pam-ck-connector/Makefile.am b/pam-ck-connector/Makefile.am index e03923b..3819f5e 100644 --- a/pam-ck-connector/Makefile.am +++ b/pam-ck-connector/Makefile.am @@ -1,17 +1,47 @@ +NULL = if ENABLE_PAM_MODULE -INCLUDES = $(LIBDBUS_CFLAGS) -I$(top_builddir)/libck-connector +INCLUDES = \ + $(LIBDBUS_CFLAGS) \ + -I$(top_builddir)/libck-connector \ + $(NULL) + +pamlibdir = /lib/security + +pamlib_LTLIBRARIES = \ + pam_ck_connector.la \ + $(NULL) -pamlib_LTLIBRARIES=pam_ck_connector.la -pamlibdir=/lib/security pam_ck_connector_la_SOURCES = pam-ck-connector.c pam_ck_connector_la_LDFLAGS = -no-undefined -module -avoid-version -pam_ck_connector_la_LIBADD = -lpam $(LIBDBUS_LIBS) $(top_builddir)/libck-connector/libck-connector.la +pam_ck_connector_la_LIBADD = \ + $(PAM_LIBS) \ + $(LIBDBUS_LIBS) \ + $(top_builddir)/libck-connector/libck-connector.la \ + $(NULL) man_MANS = pam_ck_connector.8 +noinst_PROGRAMS = \ + test-pam \ + $(NULL) + +test_pam_SOURCES = \ + test-pam.c \ + $(NULL) + +test_pam_LDADD = \ + $(PAM_LIBS) \ + -lpam_misc \ + $(NULL) + endif +MAINTAINERCLEANFILES = \ + *~ \ + Makefile.in \ + $(NULL) + clean-local : rm -f *~ diff --git a/pam-ck-connector/pam-ck-connector.c b/pam-ck-connector/pam-ck-connector.c index 42d0d2b..67135f7 100644 --- a/pam-ck-connector/pam-ck-connector.c +++ b/pam-ck-connector/pam-ck-connector.c @@ -60,7 +60,7 @@ _parse_pam_args (const pam_handle_t *pamh, opt_debug = FALSE; for (i = 0; i < argc && argv[i] != NULL; i++) { - if (strcmp (argv[i] ,"debug") == 0) { + if (strcmp (argv[i] , "debug") == 0) { opt_debug = TRUE; } else { pam_syslog (pamh, LOG_ERR, "unknown option: %s", argv[i]); diff --git a/pam-ck-connector/test-pam.c b/pam-ck-connector/test-pam.c new file mode 100644 index 0000000..b5619b9 --- /dev/null +++ b/pam-ck-connector/test-pam.c @@ -0,0 +1,135 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- + * + * Copyright (c) 2007 William Jon McCann <mccann@jhu.edu> + * + * 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 the rights to use, + * copy, modify, merge, publish, distribute, sublicense, 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 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 + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS 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 <stdio.h> +#include <stdlib.h> +#include <unistd.h> + +#include <security/pam_appl.h> +#include <security/pam_misc.h> + +#define PAM_MAX_LOGIN_TRIES 3 +#define PAM_FAIL_CHECK if (retcode != PAM_SUCCESS) { \ + fprintf (stderr, "\n%s\n", pam_strerror (pamh, retcode)); \ + pam_end (pamh, retcode); exit (1); \ + } +#define PAM_END { \ + pam_setcred (pamh, PAM_DELETE_CRED); \ + retcode = pam_close_session (pamh, 0); \ + pam_end (pamh, retcode); \ +} + +int +main (int argc, char *argv[]) +{ + int retcode; + int ret; + pam_handle_t *pamh; + char *username; + char *hostname; + char *tty_name; + char *ttyn; + struct pam_conv conv = { misc_conv, NULL }; + int failcount; + + ret = 1; + username = NULL; + hostname = NULL; + tty_name = NULL; + + retcode = pam_start ("login", username, &conv, &pamh); + if (retcode != PAM_SUCCESS) { + fprintf (stderr, "login: PAM Failure, aborting: %s\n", + pam_strerror (pamh, retcode)); + exit (99); + } + + ttyn = ttyname (0); + + if (strncmp(ttyn, "/dev/", 5) == 0) { + tty_name = ttyn + 5; + } else { + tty_name = ttyn; + } + + retcode = pam_set_item (pamh, PAM_RHOST, hostname); + PAM_FAIL_CHECK; + retcode = pam_set_item (pamh, PAM_TTY, tty_name); + PAM_FAIL_CHECK; + pam_set_item (pamh, PAM_USER, NULL); + + retcode = pam_set_item (pamh, PAM_USER_PROMPT, "Username: "); + PAM_FAIL_CHECK; + + failcount = 0; + retcode = pam_authenticate (pamh, 0); + while ((failcount++ < PAM_MAX_LOGIN_TRIES) && + ((retcode == PAM_AUTH_ERR) || + (retcode == PAM_USER_UNKNOWN) || + (retcode == PAM_CRED_INSUFFICIENT) || + (retcode == PAM_AUTHINFO_UNAVAIL))) { + pam_get_item (pamh, PAM_USER, (const void **) &username); + + fprintf (stderr, "Login incorrect\n\n"); + pam_set_item (pamh, PAM_USER, NULL); + retcode = pam_authenticate (pamh, 0); + } + + if (retcode != PAM_SUCCESS) { + fprintf (stderr, "\nLogin incorrect\n"); + pam_end (pamh, retcode); + exit (0); + } + + retcode = pam_acct_mgmt (pamh, 0); + if (retcode == PAM_NEW_AUTHTOK_REQD) { + retcode = pam_chauthtok (pamh, PAM_CHANGE_EXPIRED_AUTHTOK); + } + + PAM_FAIL_CHECK; + + pam_putenv (pamh, "CKCON_TTY=/dev/tty55"); + pam_putenv (pamh, "CKCON_X11_DISPLAY=:50"); + + retcode = pam_open_session (pamh, 0); + PAM_FAIL_CHECK; + + retcode = pam_setcred (pamh, PAM_ESTABLISH_CRED); + PAM_FAIL_CHECK; + + pam_get_item (pamh, PAM_USER, (const void **) &username); + + printf ("Session opened for %s\n", username); + + printf ("sleeping for 20 seconds..."); + sleep (20); + + PAM_END; + + printf ("\nSession closed\n"); + + return ret; +} |