Bring the PAM module up to date

This commit is contained in:
matt335672 2021-05-11 15:12:30 +01:00
parent 96052ba6e3
commit ce666a02fa

View File

@ -30,6 +30,7 @@
#include "arch.h"
#include "os_calls.h"
#include "log.h"
#include "string_calls.h"
#include <stdio.h>
@ -53,43 +54,117 @@ struct t_auth_info
pam_handle_t *ph;
};
/***************************************************************************//**
* Returns a string representing a pam_conv message style
*
* @param msg_style PAM msg_style (pam_conv(3))
* @param buff Buffer for conversion of unrecognised values
* @param bufflen Total length of above
*
* The buffer described by buff is only written to if required.
*/
static const char *
msg_style_to_str(int msg_style, char *buff, unsigned int bufflen)
{
const char *result;
switch (msg_style)
{
case PAM_PROMPT_ECHO_OFF:
result = "PAM_PROMPT_ECHO_OFF";
break;
case PAM_PROMPT_ECHO_ON:
result = "PAM_PROMPT_ECHO_ON";
break;
case PAM_ERROR_MSG:
result = "PAM_ERROR_MSG";
break;
case PAM_TEXT_INFO:
result = "PAM_TEXT_INFO";
break;
default:
snprintf(buff, bufflen, "UNKNOWN_0x%x", msg_style);
result = buff;
}
return result;
}
/******************************************************************************/
static int
verify_pam_conv(int num_msg, const struct pam_message **msg,
struct pam_response **resp, void *appdata_ptr)
{
int i;
struct pam_response *reply;
struct pam_response *reply = NULL;
struct t_user_pass *user_pass;
char sb[64];
int rv = PAM_SUCCESS;
reply = g_new0(struct pam_response, num_msg);
for (i = 0; i < num_msg; i++)
if (num_msg <= 0 || num_msg > PAM_MAX_NUM_MSG)
{
switch (msg[i]->msg_style)
rv = PAM_CONV_ERR;
}
else if ((reply = g_new0(struct pam_response, num_msg)) == NULL)
{
rv = PAM_BUF_ERR;
}
else
{
for (i = 0; i < num_msg && rv == PAM_SUCCESS; i++)
{
case PAM_PROMPT_ECHO_ON: /* username */
user_pass = (struct t_user_pass *) appdata_ptr;
reply[i].resp = g_strdup(user_pass->user);
reply[i].resp_retcode = PAM_SUCCESS;
break;
case PAM_PROMPT_ECHO_OFF: /* password */
user_pass = (struct t_user_pass *) appdata_ptr;
reply[i].resp = g_strdup(user_pass->pass);
reply[i].resp_retcode = PAM_SUCCESS;
break;
case PAM_TEXT_INFO:
g_memset(&reply[i], 0, sizeof(struct pam_response));
break;
default:
g_printf("unknown in verify_pam_conv\r\n");
g_free(reply);
return PAM_CONV_ERR;
LOG_DEVEL(LOG_LEVEL_INFO, "Handling struct pam_message"
" { style = %s, msg = \"%s\" }",
msg_style_to_str(msg[i]->msg_style, sb, sizeof (sb)),
msg[i]->msg == NULL ? "<null>" : msg[i]->msg);
switch (msg[i]->msg_style)
{
case PAM_PROMPT_ECHO_OFF: /* password */
user_pass = (struct t_user_pass *) appdata_ptr;
reply[i].resp = g_strdup(user_pass->pass);
break;
case PAM_ERROR_MSG:
LOG(LOG_LEVEL_ERROR, "PAM: %s", msg[i]->msg);
break;
case PAM_TEXT_INFO:
LOG(LOG_LEVEL_INFO, "PAM: %s", msg[i]->msg);
break;
default:
{
LOG(LOG_LEVEL_ERROR, "Unhandled message in verify_pam_conv"
" { style = %s, msg = \"%s\" }",
msg_style_to_str(msg[i]->msg_style, sb, sizeof (sb)),
msg[i]->msg == NULL ? "<null>" : msg[i]->msg);
rv = PAM_CONV_ERR;
}
}
}
}
*resp = reply;
return PAM_SUCCESS;
if (rv == PAM_SUCCESS)
{
*resp = reply;
}
else if (reply != NULL)
{
for (i = 0; i < num_msg; i++)
{
if (reply[i].resp != NULL)
{
g_free(reply[i].resp);
}
}
g_free(reply);
}
return rv;
}
/******************************************************************************/
@ -126,7 +201,7 @@ auth_userpass(const char *user, const char *pass, int *errorcode)
g_strncpy(auth_info->user_pass.pass, pass, MAX_BUF - 1);
auth_info->pamc.conv = &verify_pam_conv;
auth_info->pamc.appdata_ptr = &(auth_info->user_pass);
error = pam_start(service_name, 0, &(auth_info->pamc), &(auth_info->ph));
error = pam_start(service_name, user, &(auth_info->pamc), &(auth_info->ph));
if (error != PAM_SUCCESS)
{
@ -134,7 +209,8 @@ auth_userpass(const char *user, const char *pass, int *errorcode)
{
*errorcode = error;
}
g_printf("pam_start failed: %s\r\n", pam_strerror(auth_info->ph, error));
LOG(LOG_LEVEL_ERROR, "pam_start failed: %s",
pam_strerror(auth_info->ph, error));
pam_end(auth_info->ph, error);
g_free(auth_info);
return 0;
@ -143,8 +219,8 @@ auth_userpass(const char *user, const char *pass, int *errorcode)
error = pam_set_item(auth_info->ph, PAM_TTY, service_name);
if (error != PAM_SUCCESS)
{
g_printf("pam_set_item failed: %s\r\n",
pam_strerror(auth_info->ph, error));
LOG(LOG_LEVEL_ERROR, "pam_set_item failed: %s",
pam_strerror(auth_info->ph, error));
}
error = pam_authenticate(auth_info->ph, 0);
@ -155,8 +231,8 @@ auth_userpass(const char *user, const char *pass, int *errorcode)
{
*errorcode = error;
}
g_printf("pam_authenticate failed: %s\r\n",
pam_strerror(auth_info->ph, error));
LOG(LOG_LEVEL_ERROR, "pam_authenticate failed: %s",
pam_strerror(auth_info->ph, error));
pam_end(auth_info->ph, error);
g_free(auth_info);
return 0;
@ -175,8 +251,8 @@ auth_userpass(const char *user, const char *pass, int *errorcode)
{
*errorcode = error;
}
g_printf("pam_acct_mgmt failed: %s\r\n",
pam_strerror(auth_info->ph, error));
LOG(LOG_LEVEL_ERROR, "pam_acct_mgmt failed: %s",
pam_strerror(auth_info->ph, error));
pam_end(auth_info->ph, error);
g_free(auth_info);
return 0;
@ -200,7 +276,8 @@ auth_start_session(long in_val, int in_display)
if (error != PAM_SUCCESS)
{
g_printf("pam_set_item failed: %s\r\n", pam_strerror(auth_info->ph, error));
LOG(LOG_LEVEL_ERROR, "pam_set_item failed: %s",
pam_strerror(auth_info->ph, error));
return 1;
}
@ -208,7 +285,8 @@ auth_start_session(long in_val, int in_display)
if (error != PAM_SUCCESS)
{
g_printf("pam_setcred failed: %s\r\n", pam_strerror(auth_info->ph, error));
LOG(LOG_LEVEL_ERROR, "pam_setcred failed: %s",
pam_strerror(auth_info->ph, error));
return 1;
}
@ -217,8 +295,8 @@ auth_start_session(long in_val, int in_display)
if (error != PAM_SUCCESS)
{
g_printf("pam_open_session failed: %s\r\n",
pam_strerror(auth_info->ph, error));
LOG(LOG_LEVEL_ERROR, "pam_open_session failed: %s",
pam_strerror(auth_info->ph, error));
return 1;
}
@ -238,8 +316,8 @@ auth_stop_session(long in_val)
error = pam_close_session(auth_info->ph, 0);
if (error != PAM_SUCCESS)
{
g_printf("pam_close_session failed: %s\r\n",
pam_strerror(auth_info->ph, error));
LOG(LOG_LEVEL_ERROR, "pam_close_session failed: %s",
pam_strerror(auth_info->ph, error));
return 1;
}
auth_info->session_opened = 0;