--- Makefile 2001/05/21 20:30:49 1.24 +++ Makefile 2001/07/18 18:00:12 @@ -113,6 +113,11 @@ pre-configure: @(cd ${WRKSRC} && ${AUTOHEADER}) +post-configure: +.if defined(PWCHECK_USE_PAM) + cd ${WRKSRC} && ${PATCH} < ${FILESDIR}/special-pwcheck-ptch +.endif + # Create Cyrus user and group pre-install: @${SH} ${PKGINSTALL} ${PKGNAME} PRE-INSTALL --- /dev/null Wed Jul 18 10:59:10 2001 +++ files/special-pwcheck-ptch Wed Jul 18 10:55:57 2001 @@ -0,0 +1,137 @@ +--- pwcheck/Makefile.orig Wed Jul 18 10:52:38 2001 ++++ pwcheck/Makefile Wed Jul 18 10:53:53 2001 +@@ -113,7 +113,7 @@ + PLAIN_LIBS = -lcrypt -lpam + PURECOV = + PURIFY = +-PWCHECKMETH = getpwnam ++PWCHECKMETH = pam + RANLIB = ranlib + SASL_DB_BACKEND = db_ndbm.lo + SASL_DB_LIB = +@@ -131,9 +131,9 @@ + sbin_PROGRAMS = pwcheck + + pwcheck_SOURCES = pwcheck.c +-EXTRA_pwcheck_SOURCES = pwcheck_getpwnam.c pwcheck_getspnam.c +-pwcheck_DEPENDECIES = pwcheck_getpwnam.lo +-pwcheck_LDADD = pwcheck_getpwnam.lo -lcrypt ++EXTRA_pwcheck_SOURCES = pwcheck_getpwnam.c pwcheck_getspnam.c pwcheck_pam.c ++pwcheck_DEPENDECIES = pwcheck_pam.lo ++pwcheck_LDADD = pwcheck_pam.lo -lpam + mkinstalldirs = $(SHELL) $(top_srcdir)/config/mkinstalldirs + CONFIG_HEADER = ../config.h + CONFIG_CLEAN_FILES = +@@ -145,7 +145,7 @@ + LDFLAGS = -L/usr/local/lib -R/usr/local/lib -L/usr/lib -R/usr/lib + LIBS = + pwcheck_OBJECTS = pwcheck.o +-pwcheck_DEPENDENCIES = pwcheck_getpwnam.lo ++pwcheck_DEPENDENCIES = pwcheck_pam.lo + pwcheck_LDFLAGS = + CFLAGS = -Wall -W -O -pipe + COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +--- /dev/null Wed Jul 18 10:54:31 2001 ++++ pwcheck/pwcheck_pam.c Wed Jul 18 10:39:15 2001 +@@ -0,0 +1,101 @@ ++ ++#include ++#include ++#include ++#include ++ ++/* Static variables used to communicate between the conversation function ++ * and the server_login function ++ */ ++static char *PAM_username; ++static char *PAM_password; ++ ++/* PAM conversation function ++ */ ++static int PAM_conv (int num_msg, ++ const struct pam_message **msg, ++ struct pam_response **resp, ++ void *appdata_ptr) { ++ int replies = 0; ++ struct pam_response *reply = NULL; ++ ++ #define COPY_STRING(s) (s) ? strdup(s) : NULL ++ ++ reply = malloc(sizeof(struct pam_response) * num_msg); ++ if (!reply) return PAM_CONV_ERR; ++ ++ for (replies = 0; replies < num_msg; replies++) { ++ switch (msg[replies]->msg_style) { ++ case PAM_PROMPT_ECHO_ON: ++ reply[replies].resp_retcode = PAM_SUCCESS; ++ reply[replies].resp = COPY_STRING(PAM_username); ++ /* PAM frees resp */ ++ break; ++ case PAM_PROMPT_ECHO_OFF: ++ reply[replies].resp_retcode = PAM_SUCCESS; ++ reply[replies].resp = COPY_STRING(PAM_password); ++ /* PAM frees resp */ ++ break; ++ case PAM_TEXT_INFO: ++ /* fall through */ ++ case PAM_ERROR_MSG: ++ /* ignore it, but pam still wants a NULL response... */ ++ reply[replies].resp_retcode = PAM_SUCCESS; ++ reply[replies].resp = NULL; ++ break; ++ default: ++ /* Must be an error of some sort... */ ++ free (reply); ++ return PAM_CONV_ERR; ++ } ++ } ++ *resp = reply; ++ return PAM_SUCCESS; ++} ++ ++static struct pam_conv PAM_conversation = { ++ PAM_conv, ++ NULL ++}; ++ ++/* Server log in ++ * Accepts: user name string ++ * password string ++ * Returns: "OK" if password validated, error message otherwise ++ */ ++ ++char *pwcheck(char *username, char *password) ++{ ++ pam_handle_t *pamh; ++ int pam_error; ++ ++ /* PAM only handles authentication, not user information. */ ++ if ( !(username && password && strlen(username) && strlen(password)) ) ++ return "Incorrect username"; ++ ++ /* validate password */ ++ ++ PAM_password = password; ++ PAM_username = username; ++ fprintf(stderr, "checking %s\n", username); ++ pam_error = pam_start("cyrus", username, &PAM_conversation, &pamh); ++ if (pam_error == PAM_SUCCESS) ++ pam_error = pam_authenticate(pamh, 0); ++ ++ if (pam_error == PAM_SUCCESS) ++ pam_error = pam_acct_mgmt(pamh, 0); ++ ++ if ( pam_error == PAM_SUCCESS) ++ fprintf(stderr, "\tauthenticated %s\n", username); ++ else ++ fprintf(stderr, "\tfailed to authenticate %s\n", username); ++ ++ if(pam_end(pamh, pam_error) != PAM_SUCCESS) { ++ pamh = NULL; ++ fprintf(stderr, "pwcheck: failed to release authenticator\n"); ++ exit(1); ++ } ++ return ( pam_error == PAM_SUCCESS ? "OK" : "Incorrect passwd" ); ++} ++ ++