odyssey/sources/pam.c

95 lines
1.8 KiB
C
Raw Normal View History

2019-09-27 13:47:45 +00:00
2019-09-09 09:17:41 +00:00
/*
* Odyssey.
*
* Scalable PostgreSQL connection pooler.
*/
2019-09-27 13:47:45 +00:00
#include <stdlib.h>
#include <stdarg.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <inttypes.h>
#include <assert.h>
2019-09-09 09:17:41 +00:00
#include <security/pam_appl.h>
2019-09-27 13:47:45 +00:00
2019-09-09 09:17:41 +00:00
#include <kiwi.h>
2019-09-27 13:47:45 +00:00
#include <odyssey.h>
2019-09-09 09:17:41 +00:00
static int
2019-09-27 13:47:45 +00:00
od_pam_conversation(int msgc,
const struct pam_message **msgv,
struct pam_response **rspv,
void *authdata)
{
char *password = (char *)authdata;
if (msgc < 1 || msgv == NULL || password == NULL)
2019-09-09 09:17:41 +00:00
return PAM_CONV_ERR;
2019-09-27 13:47:45 +00:00
2019-09-09 09:17:41 +00:00
*rspv = malloc(msgc * sizeof(struct pam_response));
2019-09-27 13:47:45 +00:00
if (*rspv == NULL)
2019-09-09 09:17:41 +00:00
return PAM_CONV_ERR;
memset(*rspv, 0, msgc * sizeof(struct pam_response));
2019-09-27 13:47:45 +00:00
int rc = PAM_SUCCESS;
int counter = 0;
for (; counter < msgc; counter++)
{
2019-09-09 09:17:41 +00:00
if (msgv[counter]->msg_style == PAM_PROMPT_ECHO_OFF) {
(*rspv)[counter].resp = strdup(password);
if ((*rspv)[counter].resp == NULL) {
2019-09-27 13:47:45 +00:00
rc = PAM_CONV_ERR;
break;
2019-09-09 09:17:41 +00:00
}
}
}
2019-09-27 13:47:45 +00:00
if (rc != PAM_SUCCESS) {
for (; counter >= 0; counter--) {
if (msgv[counter]->msg_style == PAM_PROMPT_ECHO_OFF)
free((*rspv)[counter].resp);
}
2019-09-09 09:17:41 +00:00
free(*rspv);
*rspv = NULL;
2019-09-09 09:17:41 +00:00
}
2019-09-27 13:47:45 +00:00
return rc;
2019-09-09 09:17:41 +00:00
}
int
2019-09-27 13:47:45 +00:00
od_pam_auth(char *od_pam_service, kiwi_var_t *user, kiwi_password_t *password)
{
struct pam_conv conv =
{
od_pam_conversation,
2019-09-09 09:17:41 +00:00
.appdata_ptr = (void *)password->password,
};
pam_handle_t *pamh = NULL;
2019-09-27 13:47:45 +00:00
int rc;
rc = pam_start(od_pam_service, user->value, &conv, &pamh);
if (rc != PAM_SUCCESS)
goto error;
2019-09-09 09:17:41 +00:00
2019-09-27 13:47:45 +00:00
rc = pam_authenticate(pamh, 0);
if (rc != PAM_SUCCESS)
goto error;
2019-09-09 09:17:41 +00:00
2019-09-27 13:47:45 +00:00
rc = pam_acct_mgmt(pamh, PAM_SILENT);
if (rc != PAM_SUCCESS)
goto error;
rc = pam_end(pamh, rc);
if (rc != PAM_SUCCESS)
2019-09-09 09:17:41 +00:00
return -1;
2019-09-27 13:47:45 +00:00
return 0;
error:
pam_end(pamh, rc);
return -1;
2019-09-09 09:17:41 +00:00
}