Work around an ambiguity in the PAM spec with respect to the conversation

function.  It is not clear whether the "struct pam_message **msg" is an
array of pointers or a pointer to an array.  Linux-PAM and OpenPAM use
an array of pointers while Solaris/HP-UX/AIX uses a pointer to an array.
Bug #726.
This commit is contained in:
Todd C. Miller
2016-03-09 09:39:46 -07:00
parent 9353672608
commit 48dff84081
5 changed files with 52 additions and 13 deletions

3
NEWS
View File

@@ -63,6 +63,9 @@ What's new in Sudo 1.8.16
* Fixed a bug in the LDAP and SSSD backends that could allow an
unauthorized user to list another user's privileges. Bug #738.
* The PAM conversation function now works around an ambiguity in the
PAM spec with respect to multiple messages. Bug #726.
What's new in Sudo 1.8.15
* Fixed a bug that prevented sudo from building outside the source tree

View File

@@ -963,6 +963,10 @@
/* Define to the version of this package. */
#undef PACKAGE_VERSION
/* Define to 1 if your system uses a Solaris-derived PAM and not Linux-PAM or
OpenPAM. */
#undef PAM_SUN_CODEBASE
/* The default password prompt. */
#undef PASSPROMPT

13
configure vendored
View File

@@ -14729,6 +14729,9 @@ esac
shadow_funcs="getpwanam issecure"
;;
*-*-solaris2*)
$as_echo "#define PAM_SUN_CODEBASE 1" >>confdefs.h
# LD_PRELOAD is space-delimited
RTLD_PRELOAD_DELIM=" "
@@ -14756,6 +14759,9 @@ done
;;
*-*-aix*)
$as_echo "#define PAM_SUN_CODEBASE 1" >>confdefs.h
# To get all prototypes (so we pass -Wall)
$as_echo "#define _LINUX_SOURCE_COMPAT 1" >>confdefs.h
@@ -14872,6 +14878,9 @@ _ACEOF
;;
*-*-hiuxmpp*)
$as_echo "#define PAM_SUN_CODEBASE 1" >>confdefs.h
: ${mansectsu='1m'}
: ${mansectform='4'}
@@ -14897,6 +14906,9 @@ done
;;
*-*-hpux*)
$as_echo "#define PAM_SUN_CODEBASE 1" >>confdefs.h
# AFS support needs -lBSD
if test "$with_AFS" = "yes"; then
AFS_LIBS="-lc -lBSD"
@@ -26577,5 +26589,6 @@ fi

View File

@@ -1685,6 +1685,8 @@ case "$host" in
shadow_funcs="getpwanam issecure"
;;
*-*-solaris2*)
AC_DEFINE([PAM_SUN_CODEBASE])
# LD_PRELOAD is space-delimited
RTLD_PRELOAD_DELIM=" "
@@ -1702,6 +1704,8 @@ case "$host" in
AC_CHECK_FUNCS([priv_set], [PSMAN=1])
;;
*-*-aix*)
AC_DEFINE([PAM_SUN_CODEBASE])
# To get all prototypes (so we pass -Wall)
AC_DEFINE([_LINUX_SOURCE_COMPAT])
SUDOERS_LDFLAGS="${SUDOERS_LDFLAGS} -Wl,-bI:\$(srcdir)/aixcrypt.exp"
@@ -1756,6 +1760,8 @@ case "$host" in
])
;;
*-*-hiuxmpp*)
AC_DEFINE([PAM_SUN_CODEBASE])
: ${mansectsu='1m'}
: ${mansectform='4'}
@@ -1771,6 +1777,8 @@ case "$host" in
AC_CHECK_FUNCS([pstat_getproc])
;;
*-*-hpux*)
AC_DEFINE([PAM_SUN_CODEBASE])
# AFS support needs -lBSD
if test "$with_AFS" = "yes"; then
AFS_LIBS="-lc -lBSD"
@@ -4352,6 +4360,7 @@ AH_TEMPLATE(HAVE__NSS_XBYY_BUF_ALLOC, [Define to 1 if you have the `_nss_XbyY_bu
AH_TEMPLATE(HAVE___NSS_XBYY_BUF_ALLOC, [Define to 1 if you have the `__nss_XbyY_buf_alloc' function.])
AH_TEMPLATE(NEED_RESOLV_H, [Define to 1 if resolv.h must be included to get the `inet_ntop' or `inet_pton' function prototypes.])
AH_TEMPLATE(HAVE_STRNLEN, [Define to 1 if you have the `strnlen' function.])
AH_TEMPLATE(PAM_SUN_CODEBASE, [Define to 1 if your system uses a Solaris-derived PAM and not Linux-PAM or OpenPAM.])
dnl
dnl Bits to copy verbatim into config.h.in

View File

@@ -58,11 +58,17 @@
#include "sudo_auth.h"
/* Only OpenPAM and Linux PAM use const qualifiers. */
#if defined(_OPENPAM) || defined(OPENPAM_VERSION) || \
defined(__LIBPAM_VERSION) || defined(__LINUX_PAM__)
# define PAM_CONST const
#else
#ifdef PAM_SUN_CODEBASE
# define PAM_CONST
#else
# define PAM_CONST const
#endif
/* Ambiguity in spec: is it an array of pointers or a pointer to an array? */
#ifdef PAM_SUN_CODEBASE
# define PAM_MSG_GET(msg, n) (*(msg) + (n))
#else
# define PAM_MSG_GET(msg, n) ((msg)[(n)])
#endif
#ifndef PAM_DATA_SILENT
@@ -376,11 +382,10 @@ sudo_pam_end_session(struct passwd *pw, sudo_auth *auth)
*/
static int
converse(int num_msg, PAM_CONST struct pam_message **msg,
struct pam_response **response, void *vcallback)
struct pam_response **reply_out, void *vcallback)
{
struct pam_response *pr;
struct sudo_conv_callback *callback = NULL;
PAM_CONST struct pam_message *pm;
struct pam_response *reply;
const char *prompt;
char *pass;
int n, type;
@@ -395,15 +400,18 @@ converse(int num_msg, PAM_CONST struct pam_message **msg,
sudo_debug_printf(SUDO_DEBUG_DEBUG|SUDO_DEBUG_LINENO,
"number of PAM messages: %d", num_msg);
if ((*response = calloc(num_msg, sizeof(struct pam_response))) == NULL) {
if ((reply = calloc(num_msg, sizeof(struct pam_response))) == NULL) {
sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
debug_return_int(PAM_BUF_ERR);
}
*reply_out = reply;
if (vcallback != NULL)
callback = *((struct sudo_conv_callback **)vcallback);
for (pr = *response, pm = *msg, n = num_msg; n--; pr++, pm++) {
for (n = 0; n < num_msg; n++) {
PAM_CONST struct pam_message *pm = PAM_MSG_GET(msg, n);
type = SUDO_CONV_PROMPT_ECHO_OFF;
switch (pm->msg_style) {
case PAM_PROMPT_ECHO_ON:
@@ -447,7 +455,7 @@ converse(int num_msg, PAM_CONST struct pam_message **msg,
memset_s(pass, SUDO_CONV_REPL_MAX, 0, strlen(pass));
goto done;
}
pr->resp = pass; /* auth_getpass() malloc's a copy */
reply[n].resp = pass; /* auth_getpass() malloc's a copy */
break;
case PAM_TEXT_INFO:
if (pm->msg)
@@ -470,15 +478,17 @@ converse(int num_msg, PAM_CONST struct pam_message **msg,
done:
if (ret != PAM_SUCCESS) {
/* Zero and free allocated memory and return an error. */
for (pr = *response, n = num_msg; n--; pr++) {
for (n = 0; n < num_msg; n++) {
struct pam_response *pr = &reply[n];
if (pr->resp != NULL) {
memset_s(pr->resp, SUDO_CONV_REPL_MAX, 0, strlen(pr->resp));
free(pr->resp);
pr->resp = NULL;
}
}
free(*response);
*response = NULL;
free(reply);
*reply_out = NULL;
}
debug_return_int(ret);
}