From ac676a111684706b7e97927f12d29b25c5205078 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dag-Erling=20Sm=C3=B8rgrav?= Date: Sat, 23 Feb 2002 01:23:20 +0000 Subject: [PATCH] Vendor import of OpenPAM Caliopsis --- contrib/openpam/HISTORY | 11 +++++++++++ contrib/openpam/RELNOTES | 16 ++++++++++++++-- contrib/openpam/include/security/pam_appl.h | 2 +- contrib/openpam/lib/openpam_dispatch.c | 17 +++++++++++++---- contrib/openpam/lib/openpam_load.c | 8 ++++---- contrib/openpam/lib/openpam_log.c | 12 +++++++++--- contrib/openpam/lib/pam_get_authtok.c | 2 +- contrib/openpam/lib/pam_get_data.c | 2 +- contrib/openpam/lib/pam_set_item.c | 16 ++++++++++------ contrib/openpam/lib/pam_start.c | 2 +- contrib/openpam/lib/pam_vprompt.c | 11 ++++++++--- 11 files changed, 73 insertions(+), 26 deletions(-) diff --git a/contrib/openpam/HISTORY b/contrib/openpam/HISTORY index 58ba3c8eddd0..b09caa17ca6f 100644 --- a/contrib/openpam/HISTORY +++ b/contrib/openpam/HISTORY @@ -1,4 +1,15 @@ ============================================================================ +OpenPAM Caliopsis 2002-02-13 + +Fixed a number of bugs in the previous release, including: + - a number of bugs in and related to pam_[gs]et_item(3) + - off-by-one bug in pam_start.c would trim last character off certain + configuration lines + - incorrect ordering of an array in openpam_load.c would cause service + module functions to get mixed up + - missing 'continue' in openpam_dispatch.c caused successes to be + counted as failures +============================================================================ OpenPAM Calamite 2002-02-09 First (beta) release. diff --git a/contrib/openpam/RELNOTES b/contrib/openpam/RELNOTES index 9309bc65fbbf..a1eebccc1ff4 100644 --- a/contrib/openpam/RELNOTES +++ b/contrib/openpam/RELNOTES @@ -1,6 +1,6 @@ - Release notes for OpenPAM Calamite - ================================== + Release notes for OpenPAM Caliopsis + =================================== This is a beta release. @@ -13,4 +13,16 @@ interested in testing OpenPAM on FreeBSD. It has not been tested on any other OS, though it should build and run with minimal tweaks on NetBSD and OpenBSD. +Known issues: + + - The pam_get_user() and pam_get_authtok() functions do not check + for commonly used options such as {use,try}_first_pass or + auth_as_self. In fact, pam_get_authtok() behaves as if + try_first_pass was always specified. + + - The provided conversation function, openpam_ttyconv(), should + block signals, and support some sort of timeout. + + - The documentation is far from complete. + $Id$ diff --git a/contrib/openpam/include/security/pam_appl.h b/contrib/openpam/include/security/pam_appl.h index f3e7e600ab09..7fcc068921dc 100644 --- a/contrib/openpam/include/security/pam_appl.h +++ b/contrib/openpam/include/security/pam_appl.h @@ -71,7 +71,7 @@ pam_end(pam_handle_t *_pamh, int pam_get_data(pam_handle_t *_pamh, const char *_module_data_name, - void **_data); + const void **_data); int pam_get_item(pam_handle_t *_pamh, diff --git a/contrib/openpam/lib/openpam_dispatch.c b/contrib/openpam/lib/openpam_dispatch.c index 9c7c2879cbb2..1582edb8ce09 100644 --- a/contrib/openpam/lib/openpam_dispatch.c +++ b/contrib/openpam/lib/openpam_dispatch.c @@ -89,6 +89,8 @@ openpam_dispatch(pam_handle_t *pamh, /* execute */ for (err = fail = 0; chain != NULL; chain = chain->next) { + openpam_log(PAM_LOG_DEBUG, "calling %s() in %s", + _pam_sm_func_name[primitive], chain->module->path); if (chain->module->func[primitive] == NULL) { openpam_log(PAM_LOG_ERROR, "%s: no %s()", chain->module->path, _pam_sm_func_name[primitive]); @@ -117,6 +119,7 @@ openpam_dispatch(pam_handle_t *pamh, if (chain->flag == PAM_SUFFICIENT && primitive != PAM_SM_SETCRED) break; + continue; } _openpam_check_error_code(primitive, r); @@ -129,6 +132,7 @@ openpam_dispatch(pam_handle_t *pamh, if (err == 0) err = r; if (chain->flag == PAM_REQUIRED && !fail) { + openpam_log(PAM_LOG_DEBUG, "required module failed"); fail = 1; err = r; } @@ -138,12 +142,16 @@ openpam_dispatch(pam_handle_t *pamh, * immediately. */ if (chain->flag == PAM_REQUISITE) { + openpam_log(PAM_LOG_DEBUG, "requisite module failed"); fail = 1; break; } } - return (fail ? err : PAM_SUCCESS); + if (!fail) + err = PAM_SUCCESS; + openpam_log(PAM_LOG_DEBUG, "returning: %s", pam_strerror(pamh, err)); + return (err); } #if !defined(OPENPAM_RELAX_CHECKS) @@ -151,11 +159,12 @@ static void _openpam_check_error_code(int primitive, int r) { /* common error codes */ - if (r == PAM_SERVICE_ERR || - r == PAM_BUF_ERR || + if (r == PAM_SUCCESS || + r == PAM_SERVICE_ERR || r == PAM_BUF_ERR || r == PAM_CONV_ERR || - r == PAM_PERM_DENIED) + r == PAM_PERM_DENIED || + r == PAM_ABORT) return; /* specific error codes */ diff --git a/contrib/openpam/lib/openpam_load.c b/contrib/openpam/lib/openpam_load.c index d93895989469..1a345ec272bc 100644 --- a/contrib/openpam/lib/openpam_load.c +++ b/contrib/openpam/lib/openpam_load.c @@ -47,12 +47,12 @@ SET_DECLARE(_openpam_modules, pam_module_t); #endif const char *_pam_sm_func_name[PAM_NUM_PRIMITIVES] = { - "pam_sm_acct_mgmt", "pam_sm_authenticate", - "pam_sm_chauthtok", - "pam_sm_close_session", + "pam_sm_setcred", + "pam_sm_acct_mgmt", "pam_sm_open_session", - "pam_sm_setcred" + "pam_sm_close_session", + "pam_sm_chauthtok" }; static pam_module_t *modules; diff --git a/contrib/openpam/lib/openpam_log.c b/contrib/openpam/lib/openpam_log.c index d733b690da7b..b15c6e35c728 100644 --- a/contrib/openpam/lib/openpam_log.c +++ b/contrib/openpam/lib/openpam_log.c @@ -34,6 +34,7 @@ * $Id$ */ +#include #include #include #include @@ -54,7 +55,7 @@ _openpam_log(int level, const char *func, const char *fmt, ...) { va_list ap; char *format; - int priority; + int len, priority; switch (level) { case PAM_LOG_DEBUG: @@ -71,9 +72,14 @@ _openpam_log(int level, const char *func, const char *fmt, ...) break; } va_start(ap, fmt); - if ((format = malloc(strlen(func) + strlen(fmt) + 8)) != NULL) { - sprintf(format, "in %s(): %s", func, fmt); + for (len = strlen(fmt); len > 0 && isspace(fmt[len]); len--) + /* nothing */; + if ((format = malloc(strlen(func) + len + 16)) != NULL) { + sprintf(format, "in %s(): %.*s\n", func, len, fmt); vsyslog(priority, format, ap); +#ifdef DEBUG + vfprintf(stderr, format, ap); +#endif free(format); } else { vsyslog(priority, fmt, ap); diff --git a/contrib/openpam/lib/pam_get_authtok.c b/contrib/openpam/lib/pam_get_authtok.c index 741b02d784ba..9776fffddfa1 100644 --- a/contrib/openpam/lib/pam_get_authtok.c +++ b/contrib/openpam/lib/pam_get_authtok.c @@ -59,7 +59,7 @@ pam_get_authtok(pam_handle_t *pamh, return (PAM_SYSTEM_ERR); r = pam_get_item(pamh, PAM_AUTHTOK, (const void **)authtok); - if (r == PAM_SUCCESS) + if (r == PAM_SUCCESS && *authtok != NULL) return (PAM_SUCCESS); if (prompt == NULL) { if (pam_get_item(pamh, PAM_AUTHTOK_PROMPT, diff --git a/contrib/openpam/lib/pam_get_data.c b/contrib/openpam/lib/pam_get_data.c index 8b2b09058b92..f258de8386cc 100644 --- a/contrib/openpam/lib/pam_get_data.c +++ b/contrib/openpam/lib/pam_get_data.c @@ -50,7 +50,7 @@ int pam_get_data(pam_handle_t *pamh, const char *module_data_name, - void **data) + const void **data) { pam_data_t *dp; diff --git a/contrib/openpam/lib/pam_set_item.c b/contrib/openpam/lib/pam_set_item.c index 1cebfd55aadd..5405a4e722cd 100644 --- a/contrib/openpam/lib/pam_set_item.c +++ b/contrib/openpam/lib/pam_set_item.c @@ -62,6 +62,7 @@ pam_set_item(pam_handle_t *pamh, return (PAM_SYSTEM_ERR); slot = &pamh->item[item_type]; + tmp = NULL; switch (item_type) { case PAM_SERVICE: case PAM_USER: @@ -72,20 +73,23 @@ pam_set_item(pam_handle_t *pamh, case PAM_RUSER: case PAM_USER_PROMPT: case PAM_AUTHTOK_PROMPT: - size = strlen(*slot) + 1; + if (*slot != NULL) + size = strlen(*slot) + 1; if (item != NULL) - tmp = strdup(item); + if ((tmp = strdup(item)) == NULL) + return (PAM_BUF_ERR); break; case PAM_CONV: size = sizeof(struct pam_conv); - if (item != NULL) - tmp = malloc(size); + if (item != NULL) { + if ((tmp = malloc(size)) == NULL) + return (PAM_BUF_ERR); + memcpy(tmp, item, sizeof(struct pam_conv)); + } break; default: return (PAM_SYSTEM_ERR); } - if (item != NULL && tmp == NULL) - return (PAM_BUF_ERR); if (*slot != NULL) { memset(*slot, 0xd0, size); free(*slot); diff --git a/contrib/openpam/lib/pam_start.c b/contrib/openpam/lib/pam_start.c index ff9cc32ec5a5..a059661595ab 100644 --- a/contrib/openpam/lib/pam_start.c +++ b/contrib/openpam/lib/pam_start.c @@ -132,7 +132,7 @@ _pam_read_policy_file(pam_handle_t *pamh, /* strip comments and trailing whitespace */ if ((p = strchr(buf, '#')) != NULL) len = p - buf ? p - buf - 1 : p - buf; - while (len > 0 && isspace(buf[len])) + while (len > 0 && isspace(buf[len - 1])) --len; if (len == 0) continue; diff --git a/contrib/openpam/lib/pam_vprompt.c b/contrib/openpam/lib/pam_vprompt.c index f090b23653fa..cea56c7c06f9 100644 --- a/contrib/openpam/lib/pam_vprompt.c +++ b/contrib/openpam/lib/pam_vprompt.c @@ -58,16 +58,21 @@ pam_vprompt(pam_handle_t *pamh, struct pam_message msg; const struct pam_message *msgp; struct pam_response *rsp; - struct pam_conv conv; + struct pam_conv *conv; int r; - if ((r = pam_get_item(pamh, PAM_CONV, (void *)&conv)) != PAM_SUCCESS) + r = pam_get_item(pamh, PAM_CONV, (const void **)&conv); + if (r != PAM_SUCCESS) return (r); + if (conv == NULL) { + openpam_log(PAM_LOG_ERROR, "no conversation function"); + return (PAM_SYSTEM_ERR); + } vsnprintf(msgbuf, PAM_MAX_MSG_SIZE, fmt, ap); msg.msg_style = style; msg.msg = msgbuf; msgp = &msg; - r = (conv.conv)(1, &msgp, &rsp, conv.appdata_ptr); + r = (conv->conv)(1, &msgp, &rsp, conv->appdata_ptr); *resp = rsp == NULL ? NULL : rsp->resp; free(rsp); return (r);