If the user doesn't supply any arguments to the plugin in the OpenVPN configuration file, then it defaults to setting the second argument to the pam_start() function with the username that the other end of the vpn supplied. The pam libraries use this as the initial value for the PAM_USER pam 'item'.
If the administrator supplies one or more arguments to the auth-pam plugin, then this default behaviour is abandoned, and the user argument is set to NULL. The administrator must then supply a match for the message text content which the pam module will (hopefully) supply in order to try to discover the message (some pam modules will just give up at this stage, and fail the authentication e.g. Google Authenticator will fail if PAM_USER is set to NULL). The message text which the pam module supplies is intended to be read by a human, not parsed by other code (as is the current behaviour of the plugin), and as such may be subject to change (e.g. because of localisation changes etc.). This patch allows the user to supply a value for the second argument of pam_start, if they have supplied any arguments (by using the special value of 'PAM_USER' as the question message). This allows operation with inflexible pam modules, and also decreases the likelihood that system configuration changes (e.g. localisation changes, package updates etc.) will break the OpenVPN setup by causing existing matches to fail. Signed-off-by: Tim Small <t...@seoss.co.uk> --- src/plugins/auth-pam/auth-pam.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/plugins/auth-pam/auth-pam.c b/src/plugins/auth-pam/auth-pam.c index e0dc029..b14cf06 100644 --- a/src/plugins/auth-pam/auth-pam.c +++ b/src/plugins/auth-pam/auth-pam.c @@ -693,11 +693,21 @@ pam_auth (const char *service, const struct user_pass *up) int status = PAM_SUCCESS; int ret = 0; const int name_value_list_provided = (up->name_value_list && up->name_value_list->len > 0); - + char *pam_user = NULL; + if (name_value_list_provided) + { + ret = get_value_with_subst (up, "PAM_USER", &pam_user); + if (ret == PAM_SUCCESS) + fprintf (stderr, "Passing user '%s' in pam_start\n", pam_user); + else + fprintf (stderr, "User didn't specify value for user argument to pam_start()\n"); + } /* Initialize PAM */ conv.conv = my_conv; conv.appdata_ptr = (void *)up; - status = pam_start (service, name_value_list_provided ? NULL : up->username, &conv, &pamh); + status = pam_start (service, name_value_list_provided ? pam_user : up->username, &conv, &pamh); + if (pam_user) + free(pam_user); if (status == PAM_SUCCESS) { /* Call PAM to verify username/password */ -- 2.1.4