diff -ruN checkpassword-0.81-old/Makefile checkpassword-0.81/Makefile --- checkpassword-0.81-old/Makefile Sat Nov 21 21:29:52 1998 +++ checkpassword-0.81/Makefile Mon Jan 18 13:34:03 1999 @@ -33,9 +33,10 @@ ./instcheck checkpassword: \ -load checkpassword.o prot.o shadow.lib crypt.lib s.lib +load log_pam.h haspam.h log_pam.o checkpassword.o prot.o shadow.lib \ +crypt.lib pam.lib s.lib ./load checkpassword prot.o `cat shadow.lib` `cat \ - crypt.lib` `cat s.lib` + crypt.lib` `cat pam.lib` `cat s.lib` checkpassword.0: \ checkpassword.8 @@ -67,6 +68,13 @@ && echo -lcrypt || exit 0 ) > crypt.lib rm -f trycrypt.o trycrypt +pam.lib: \ +trypam.c compile load + ( ( ./compile trypam.c && \ + ./load trypam -lcrypt -lpam -ldl ) >/dev/null 2>&1 \ + && echo log_pam.o -ldl -lpam || exit 0 ) > pam.lib + rm -f trypam.o trypam + error.a: \ makelib error.o error_str.o ./makelib error.a error.o error_str.o @@ -79,6 +87,13 @@ compile error_str.c error.h ./compile error_str.c +haspam.h: \ +trypam.c compile load + ( ( ./compile trypam.c && \ + ./load trypam -lcrypt -lpam -ldl ) >/dev/null 2>&1 \ + && echo \#define HAS_PAM || exit 0 ) > haspam.h + rm -f trypam.o trypam + hasshsgr.h: \ chkshsgr warn-shsgr tryshsgr.c compile load ./chkshsgr || ( cat warn-shsgr; exit 1 ) @@ -137,6 +152,10 @@ '-o "$$main" "$$main".o $${1+"$$@"}' \ ) > load chmod 755 load + +log_pam.o: \ +compile log_pam.c haspam.h + ./compile log_pam.c makelib: \ warn-auto.sh systype diff -ruN checkpassword-0.81-old/SYSDEPS checkpassword-0.81/SYSDEPS --- checkpassword-0.81-old/SYSDEPS Sat Nov 21 21:29:52 1998 +++ checkpassword-0.81/SYSDEPS Mon Jan 18 13:33:13 1999 @@ -6,3 +6,4 @@ hasspnam.h hasuserpw.h hasshsgr.h +haspam.h diff -ruN checkpassword-0.81-old/TARGETS checkpassword-0.81/TARGETS --- checkpassword-0.81-old/TARGETS Sat Nov 21 21:29:52 1998 +++ checkpassword-0.81/TARGETS Mon Jan 18 15:51:10 1999 @@ -12,10 +12,12 @@ prot.o shadow.lib crypt.lib +pam.lib checkpassword prog install.o hier.o +log_pam.o auto-str.o systype makelib diff -ruN checkpassword-0.81-old/checkpassword.c checkpassword-0.81/checkpassword.c --- checkpassword-0.81-old/checkpassword.c Sat Nov 21 21:29:52 1998 +++ checkpassword-0.81/checkpassword.c Mon Jan 18 15:54:36 1999 @@ -16,6 +16,11 @@ static struct passwd *pw; static char *stored; +#include "haspam.h" +#ifdef HAS_PAM +#include "log_pam.h" +#else + #include "hasspnam.h" #ifdef HASGETSPNAM #include @@ -28,6 +33,8 @@ static struct userpw *upw; #endif +#endif + void doit(login) char *login; { @@ -105,13 +112,22 @@ while (up[i++]) if (i == uplen) _exit(2); doit(login); - +#ifndef HAS_PAM encrypted = crypt(password,stored); for (i = 0;i < sizeof(up);++i) up[i] = 0; +#endif +#ifdef HAS_PAM + if (!pam_pop3_check(login,password)) { + for (i = 0;i < sizeof(up);++i) up[i] = 0; + _exit(1); + } + for (i = 0;i < sizeof(up);++i) up[i] = 0; +#else if (!*stored || strcmp(encrypted,stored)) _exit(1); +#endif if (prot_gid((int) pw->pw_gid) == -1) _exit(1); if (prot_uid((int) pw->pw_uid) == -1) _exit(1); if (chdir(pw->pw_dir) == -1) _exit(111); diff -ruN checkpassword-0.81-old/hier.c checkpassword-0.81/hier.c --- checkpassword-0.81-old/hier.c Sat Nov 21 21:29:52 1998 +++ checkpassword-0.81/hier.c Mon Jan 18 15:50:21 1999 @@ -3,4 +3,6 @@ void hier() { c(auto_home,"bin","checkpassword",-1,-1,0700); + d(auto_home,"etc/pam.d",-1,-1,0755); + c(auto_home,"etc/pam.d","qmail-pop3",-1,-1,0644); } diff -ruN checkpassword-0.81-old/log_pam.c checkpassword-0.81/log_pam.c --- checkpassword-0.81-old/log_pam.c Thu Jan 1 01:00:00 1970 +++ checkpassword-0.81/log_pam.c Mon Jan 18 13:33:13 1999 @@ -0,0 +1,129 @@ +/* + * Program: Pluggable Authentication Modules login services + * + * Author: Michael K. Johnson + * Red Hat Software + * Internet: johnsonm@redhat.com + * + * + */ +/* + * This majority of this code was lifted from the src.rpm for imap + * in the RedHat-4.2 updates directory + * by Kelley Lingerfelt redhat@cococo.net + */ + +#include "haspam.h" +#ifdef HAS_PAM +#include +#include +#include +#include +#include +#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; +static int PAM_error = 0; + +/* for compability with older pam stuff, before the stupid transposition */ +#ifndef PAM_CRED_ESTABLISH +#define PAM_CRED_ESTABLISH 0x0002U +#endif + +/* PAM conversation function + * Here we assume (for now, at least) that echo on means login name, and + * echo off means password. + */ +static int PAM_conv (int num_msg, + const struct pam_message **msg, + struct pam_response **resp, + void *appdata_ptr) { + int count = 0, replies = 0; + struct pam_response *reply = NULL; + int size = sizeof(struct pam_response); + + #define GET_MEM if (reply) realloc(reply, size); else reply = malloc(size); \ + if (!reply) return PAM_CONV_ERR; \ + size += sizeof(struct pam_response) + #define COPY_STRING(s) (s) ? strdup(s) : (char *)NULL + + for (count = 0; count < num_msg; count++) { + switch (msg[count]->msg_style) { + case PAM_PROMPT_ECHO_ON: + GET_MEM; + reply[replies].resp_retcode = PAM_SUCCESS; + reply[replies++].resp = COPY_STRING(PAM_username); + /* PAM frees resp */ + break; + case PAM_PROMPT_ECHO_OFF: + GET_MEM; + reply[replies].resp_retcode = PAM_SUCCESS; + reply[replies++].resp = COPY_STRING(PAM_password); + /* PAM frees resp */ + break; + case PAM_TEXT_INFO: + /* ignore it... */ + break; + case PAM_ERROR_MSG: + default: + /* Must be an error of some sort... */ + free (reply); + PAM_error = 1; + return PAM_CONV_ERR; + } + } + if (reply) *resp = reply; + return PAM_SUCCESS; +} +static struct pam_conv PAM_conversation = { + &PAM_conv, + NULL +}; + +/* Server log in + * Accepts: user name string + * password string + * Returns: T if password validated, NIL otherwise + */ +int pam_pop3_check (char *user, char *pass) +{ + pam_handle_t *pamh; + int pam_error; +/* char tmp[MAILTMPLEN]; */ + struct passwd *pw = getpwnam (user); + + /* Now use PAM to do authentication. For now, we won't worry about + * session logging, only authentication. Bail out if there are any + * errors. Since this is a limited protocol, and an even more limited + * function within a server speaking this protocol, we can't be as + * verbose as would otherwise make sense. It would be nice if we + * could return a string for the server to pass the the client and/or + * log, but that doesn't exist right now. If it is ever added, PAM + * could make good use of it. + * Query: should we be using PAM_SILENT to shut PAM up? + */ + #define PAM_BAIL if (PAM_error || (pam_error != PAM_SUCCESS)) { \ + pam_end(pamh, 0); return 0; \ + } + PAM_password = pass; + PAM_username = user; + pam_error = pam_start("qmail-pop3", user, &PAM_conversation, &pamh); + PAM_BAIL; + pam_error = pam_authenticate(pamh, 0); + PAM_BAIL; + pam_error = pam_acct_mgmt(pamh, 0); + PAM_BAIL; + pam_error = pam_setcred(pamh, PAM_CRED_ESTABLISH); + PAM_BAIL; + + pam_end(pamh, PAM_SUCCESS); + /* If this point is reached, the user has been authenticated. */ + return 1; +} +#endif diff -ruN checkpassword-0.81-old/log_pam.h checkpassword-0.81/log_pam.h --- checkpassword-0.81-old/log_pam.h Thu Jan 1 01:00:00 1970 +++ checkpassword-0.81/log_pam.h Mon Jan 18 13:33:13 1999 @@ -0,0 +1 @@ +int pam_pop3_check (char *, char *); diff -ruN checkpassword-0.81-old/qmail-pop3 checkpassword-0.81/qmail-pop3 --- checkpassword-0.81-old/qmail-pop3 Thu Jan 1 01:00:00 1970 +++ checkpassword-0.81/qmail-pop3 Mon Jan 18 13:33:13 1999 @@ -0,0 +1,4 @@ +#%PAM-1.0 +auth required /lib/security/pam_listfile.so onerr=fail item=user sense=deny file=/etc/no_mail +auth required /lib/security/pam_pwdb.so shadow nullok +account required /lib/security/pam_pwdb.so diff -ruN checkpassword-0.81-old/trypam.c checkpassword-0.81/trypam.c --- checkpassword-0.81-old/trypam.c Thu Jan 1 01:00:00 1970 +++ checkpassword-0.81/trypam.c Mon Jan 18 13:33:13 1999 @@ -0,0 +1,4 @@ +main() +{ + ; +}