Implement PAM authentication in auth.c and adapt Makefile to link against libpam.

This commit is contained in:
Jan Christoph Terasa
2019-02-18 19:38:34 +01:00
parent 0e3fca6835
commit c21421dbec
2 changed files with 92 additions and 0 deletions
+10
View File
@@ -31,6 +31,9 @@ USE_KRB5 = 0
# flag for LDAP support, please turn on if you need LDAP
USE_LDAP = 0
# flag for PAM support, please turn on if you need PAM
USE_PAM = 0
#############################################################
# Default compilation flags unless stated otherwise.
@@ -107,6 +110,13 @@ LIBS += -lldap
endif
endif
ifdef USE_PAM
ifneq ($(USE_PAM),0)
CFLAGS += -DHAVE_PAM
LIBS += -lpam
endif
endif
ifdef NEED_STRLCPY
OBJS += strlcpy.o
endif
+82
View File
@@ -42,6 +42,10 @@ char ldap_userbase[256];
char ldap_bindDN[512];
#endif /* HAVE_LDAP */
#ifdef HAVE_PAM
#include <security/pam_appl.h>
#endif HAVE_PAM /* HAVE_PAM */
extern LOGBOOK *lb_list;
/*==================================================================*/
@@ -421,6 +425,77 @@ int ldap_clear ()
#endif /* LDAP */
/* PAM authentication routines */
#ifdef HAVE_PAM
/* we need a custom PAM conversation function to handle acquiring the auth
* token (password) from the web formular, and hand it to PAM */
int elog_conv(int num_msg, const struct pam_message **mess, struct pam_response **resp, void *my_data)
{
char *resptok;
/* no PAM message received, this is an error */
if(num_msg <= 0 || num_msg >= PAM_MAX_NUM_MSG) {
*resp = NULL;
return (PAM_CONV_ERR);
}
/* if we do not have enough space to allocate the response, we have an error
* */
if((*resp = calloc(num_msg, sizeof(struct pam_response))) == NULL)
return (PAM_BUF_ERR);
/* this is the password we got through the UI, copy it to the heap, since
* pam_authenticate will free() the response, give error if calloc fails */
if((resptok = calloc(strlen(my_data)+1, sizeof(char))) == NULL)
return (PAM_BUF_ERR);
memcpy(resptok, my_data, strlen(my_data)+1);
/* set the response to our auth token (password) */
(*resp)->resp = resptok;
return (PAM_SUCCESS);
}
int auth_verify_password_pam(LOGBOOK *lbs, const char *user, const char *password, char *error_str, int error_size)
{
pam_handle_t *pamh;
int retval;
int verified = 0;
/* use our custom conversation function */
static struct pam_conv elog_pam_conv = {
elog_conv,
NULL
};
/* set conversation application data to our password */
elog_pam_conv.appdata_ptr = password;
/* start PAM auth procedure */
retval = pam_start("elogd", user, &elog_pam_conv, &pamh);
/* if we can use PAM, try to authenticate using our conversation method */
if(retval == PAM_SUCCESS) {
retval = pam_authenticate(pamh, 0);
}
/* if the user authenticated, see if the acc is valid */
if(retval == PAM_SUCCESS) {
retval = pam_acct_mgmt(pamh, 0);
}
verified = (retval == PAM_SUCCESS);
if(pam_end(pamh, retval) != PAM_SUCCESS) {
pamh = NULL;
strlcpy(error_str, "PAM: Error releasing authenticator", error_size);
}
return verified;
}
#endif /* PAM */
/*---- local password file routines --------------------------------*/
int auth_verify_password_file(LOGBOOK * lbs, const char *user, const char *password, char *error_str,
@@ -505,6 +580,13 @@ int auth_verify_password(LOGBOOK * lbs, const char *user, const char *password,
return TRUE;
#endif
#ifdef HAVE_PAM
if(stristr(str, "PAM"))
verified = auth_verify_password_pam(lbs, user, password, error_str, error_size);
if(verified)
return TRUE;
#endif
if (str[0] == 0 || stristr(str, "File"))
verified = auth_verify_password_file(lbs, user, password, error_str, error_size);