#================================================================================================== # Release 2.6.7: Fix for macOS-specific build issue, due to missing 'pam_modutil.h', etc. # Merged into upstream master, and will be included in next release. # # Issue: https://gitlab.com/oath-toolkit/oath-toolkit/-/issues/26 # MR: https://gitlab.com/oath-toolkit/oath-toolkit/-/merge_requests/19 #================================================================================================== # From ff7f814c5f4fce00917cf60bafea0e9591fab3ed Mon Sep 17 00:00:00 2001 # From: Nick Gaya # Date: Thu, 17 Jun 2021 10:21:42 -0700 # Subject: [PATCH] pam_oath: Provide fallback pam_modutil_getpwnam implementation # # Closes #26 # --- # pam_oath/Makefile.am | 2 +- # pam_oath/configure.ac | 3 +- # pam_oath/pam_modutil.c | 82 ++++++++++++++++++++++++++++++++++++++++++ # pam_oath/pam_modutil.h | 17 +++++++++ # pam_oath/pam_oath.c | 4 +-- # 5 files changed, 102 insertions(+), 6 deletions(-) # create mode 100644 pam_oath/pam_modutil.c # create mode 100644 pam_oath/pam_modutil.h #================================================================================================== diff --git a/pam_oath/Makefile.am b/pam_oath/Makefile.am index 53a4cf7..16bd790 100644 --- a/pam_oath/Makefile.am +++ b/pam_oath/Makefile.am @@ -24,7 +24,7 @@ EXTRA_DIST = README pammoddir = $(PAMDIR) pammod_LTLIBRARIES = pam_oath.la -pam_oath_la_SOURCES = pam_oath.c +pam_oath_la_SOURCES = pam_oath.c pam_modutil.c pam_modutil.h # XXX add -Wl,-x too? PAM documentation suggests it. pam_oath_la_LIBADD = ../liboath/liboath.la pam_oath_la_LDFLAGS = -module -avoid-version diff --git a/pam_oath/configure.ac b/pam_oath/configure.ac index b3c198c..50c0c74 100644 --- a/pam_oath/configure.ac +++ b/pam_oath/configure.ac @@ -29,8 +29,7 @@ LT_INIT([disable-static]) AC_CHECK_HEADERS([security/pam_appl.h], [], [AC_MSG_ERROR([[PAM header files not found, install libpam-dev.]])]) -AC_CHECK_HEADERS([security/pam_modutil.h], [], - [AC_MSG_ERROR([[PAM header files not found, install libpam-dev.]])]) +AC_CHECK_HEADERS([security/pam_modutil.h], [], []) AC_CHECK_HEADERS([security/pam_modules.h security/_pam_macros.h], [], [], [#include ]) diff --git a/pam_oath/pam_modutil.c b/pam_oath/pam_modutil.c new file mode 100644 index 0000000..6bc2949 --- /dev/null +++ b/pam_oath/pam_modutil.c @@ -0,0 +1,82 @@ +#include + +#ifndef HAVE_SECURITY_PAM_MODUTIL_H + +#include "pam_modutil.h" + +#ifdef HAVE_SECURITY_PAM_APPL_H +#include +#endif +#ifdef HAVE_SECURITY_PAM_MODULES_H +#include +#endif + +#include +#include +#include +#include +#include + +#define PWD_INITIAL_LENGTH 0x400 +#define PWD_ABSURD_PWD_LENGTH 0x4000 + +void _pam_modutil_cleanup(pam_handle_t *pamh, void *data, int error_status) { + if (data) { + (void) free(data); + } +} + +struct passwd *pam_modutil_getpwnam(pam_handle_t *pamh, const char *user) { + void *buffer = NULL; + size_t length = PWD_INITIAL_LENGTH; + long sc_init_length = sysconf(_SC_GETPW_R_SIZE_MAX); + + if (sc_init_length != -1 && sc_init_length < PWD_ABSURD_PWD_LENGTH) { + length = (size_t) sc_init_length; + } + + do { + int status; + void *new_buffer; + struct passwd *result = NULL; + + new_buffer = realloc(buffer, sizeof(struct passwd) + length); + if (new_buffer == NULL) { + // out of memory + if (buffer) { + free(buffer); + } + return NULL; + } + buffer = new_buffer; + + status = getpwnam_r(user, buffer, + sizeof(struct passwd) + (char *) buffer, + length, &result); + if (!status && result) { + status = pam_set_data(pamh, "_pammodutil_getpwnam", result, + _pam_modutil_cleanup); + if (status == PAM_SUCCESS) { + return result; + } + // unable to set data item + free(buffer); + return NULL; + } + if (status != ERANGE) { + // no matching record found (if status == 0) + // or getpwnam_r encountered an error + free(buffer); + return NULL; + } + + length <<= 1; + } while (length < PWD_ABSURD_PWD_LENGTH); + + // exceeded maximum buffer size + free(buffer); + return NULL; +} +#else +typedef int make_iso_compilers_happy; +#endif /* HAVE_SECURITY_PAM_MODUTIL_H */ diff --git a/pam_oath/pam_modutil.h b/pam_oath/pam_modutil.h new file mode 100644 index 0000000..c5d5647 --- /dev/null +++ b/pam_oath/pam_modutil.h @@ -0,0 +1,17 @@ +#ifndef PAM_MODUTIL_H +#define PAM_MODUTIL_H + +#ifdef HAVE_SECURITY_PAM_MODUTIL_H +#include +#else + +#ifdef HAVE_SECURITY_PAM_MODULES_H +#include +#endif + +#include + +struct passwd *pam_modutil_getpwnam(pam_handle_t *pamh, const char *user); + +#endif +#endif diff --git a/pam_oath/pam_oath.c b/pam_oath/pam_oath.c index 3e72edc..79bc912 100644 --- a/pam_oath/pam_oath.c +++ b/pam_oath/pam_oath.c @@ -21,6 +21,7 @@ #include #include "oath.h" +#include "pam_modutil.h" #include #include @@ -43,9 +44,6 @@ #ifdef HAVE_SECURITY_PAM_APPL_H #include #endif -#ifdef HAVE_SECURITY_PAM_MODUTIL_H -#include -#endif #ifdef HAVE_SECURITY_PAM_MODULES_H #include #endif -- GitLab