2019-09-27 13:47:45 +00:00
|
|
|
|
2019-09-09 09:17:41 +00:00
|
|
|
/*
|
|
|
|
* Odyssey.
|
|
|
|
*
|
|
|
|
* Scalable PostgreSQL connection pooler.
|
2020-04-02 11:00:56 +00:00
|
|
|
*/
|
2019-09-09 09:17:41 +00:00
|
|
|
|
2019-09-27 13:47:45 +00:00
|
|
|
#include <stdlib.h>
|
|
|
|
#include <string.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
|
|
|
|
2020-06-16 05:27:33 +00:00
|
|
|
struct sss
|
|
|
|
{
|
|
|
|
char *psswd;
|
|
|
|
char *res;
|
|
|
|
};
|
|
|
|
|
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)
|
|
|
|
{
|
2020-06-16 05:27:33 +00:00
|
|
|
od_pam_auth_data_t *auth_data = authdata;
|
|
|
|
if (msgc < 1 || msgv == 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
|
|
|
|
2020-04-02 11:00:56 +00:00
|
|
|
int rc = PAM_SUCCESS;
|
2019-09-27 13:47:45 +00:00
|
|
|
int counter = 0;
|
2020-04-02 11:00:56 +00:00
|
|
|
for (; counter < msgc; counter++) {
|
2020-06-16 05:27:33 +00:00
|
|
|
od_list_t *i;
|
|
|
|
od_list_foreach(&auth_data->link, i)
|
|
|
|
{
|
|
|
|
od_pam_auth_data_t *param;
|
|
|
|
param = od_container_of(i, od_pam_auth_data_t, link);
|
|
|
|
if (param->msg_style == msgv[counter]->msg_style) {
|
|
|
|
(*rspv)[counter].resp = strdup(param->value);
|
2019-09-27 13:47:45 +00:00
|
|
|
break;
|
2019-09-09 09:17:41 +00:00
|
|
|
}
|
|
|
|
}
|
2020-06-16 05:27:33 +00:00
|
|
|
if ((*rspv)[counter].resp == NULL) {
|
|
|
|
rc = PAM_CONV_ERR;
|
|
|
|
break;
|
|
|
|
}
|
2019-09-09 09:17:41 +00:00
|
|
|
}
|
2020-04-02 11:00:56 +00:00
|
|
|
|
2019-09-27 13:47:45 +00:00
|
|
|
if (rc != PAM_SUCCESS) {
|
|
|
|
for (; counter >= 0; counter--) {
|
2020-06-16 05:27:33 +00:00
|
|
|
od_list_t *i;
|
|
|
|
od_list_foreach(&auth_data->link, i)
|
|
|
|
{
|
|
|
|
od_pam_auth_data_t *param;
|
|
|
|
param = od_container_of(i, od_pam_auth_data_t, link);
|
|
|
|
if (param->msg_style == msgv[counter]->msg_style) {
|
|
|
|
free((*rspv)[counter].resp);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2019-09-27 13:47:45 +00:00
|
|
|
}
|
2019-09-09 09:17:41 +00:00
|
|
|
free(*rspv);
|
2019-09-28 14:27:34 +00:00
|
|
|
*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
|
2020-06-04 17:35:44 +00:00
|
|
|
od_pam_auth(char *od_pam_service,
|
2020-06-16 05:27:33 +00:00
|
|
|
char *usrname,
|
2020-06-09 09:19:11 +00:00
|
|
|
od_pam_auth_data_t *auth_data,
|
2020-06-04 17:35:44 +00:00
|
|
|
machine_io_t *io)
|
2019-09-27 13:47:45 +00:00
|
|
|
{
|
2020-04-02 11:00:56 +00:00
|
|
|
struct pam_conv conv = {
|
2019-09-27 13:47:45 +00:00
|
|
|
od_pam_conversation,
|
2020-06-16 05:27:33 +00:00
|
|
|
.appdata_ptr = auth_data,
|
2019-09-09 09:17:41 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
pam_handle_t *pamh = NULL;
|
2019-09-27 13:47:45 +00:00
|
|
|
int rc;
|
2020-06-09 09:19:11 +00:00
|
|
|
rc = pam_start(od_pam_service, usrname, &conv, &pamh);
|
2019-09-27 13:47:45 +00:00
|
|
|
if (rc != PAM_SUCCESS)
|
|
|
|
goto error;
|
2020-04-02 11:00:56 +00:00
|
|
|
|
2020-06-04 17:35:44 +00:00
|
|
|
char peer[128];
|
|
|
|
od_getpeername(io, peer, sizeof(peer), 1, 0);
|
|
|
|
rc = pam_set_item(pamh, PAM_RHOST, peer);
|
|
|
|
if (rc != PAM_SUCCESS) {
|
|
|
|
goto error;
|
|
|
|
}
|
2020-04-07 08:58:13 +00:00
|
|
|
|
2020-06-16 05:27:33 +00:00
|
|
|
rc = pam_authenticate(pamh, PAM_SILENT);
|
2019-09-27 13:47:45 +00:00
|
|
|
if (rc != PAM_SUCCESS)
|
|
|
|
goto error;
|
2020-04-02 11:00:56 +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
|
|
|
}
|
2020-06-09 09:19:11 +00:00
|
|
|
|
|
|
|
void
|
2020-06-16 05:27:33 +00:00
|
|
|
od_pam_convert_passwd(od_pam_auth_data_t *d, char *passwd)
|
2020-06-09 09:19:11 +00:00
|
|
|
{
|
2020-06-16 05:27:33 +00:00
|
|
|
od_pam_auth_data_t *passwd_data = malloc(sizeof(od_pam_auth_data_t));
|
|
|
|
passwd_data->msg_style = PAM_PROMPT_ECHO_OFF;
|
|
|
|
passwd_data->value = strdup(passwd);
|
2020-06-09 09:19:11 +00:00
|
|
|
|
2020-06-16 05:27:33 +00:00
|
|
|
od_list_append(&d->link, &passwd_data->link);
|
2020-06-09 09:19:11 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
od_pam_auth_data_t *
|
2020-06-14 07:23:04 +00:00
|
|
|
od_pam_auth_data_create(void)
|
2020-06-09 09:19:11 +00:00
|
|
|
{
|
|
|
|
od_pam_auth_data_t *d;
|
|
|
|
d = (od_pam_auth_data_t *)malloc(sizeof(*d));
|
|
|
|
if (d == NULL)
|
|
|
|
return NULL;
|
|
|
|
od_list_init(&d->link);
|
|
|
|
return d;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
od_pam_auth_data_free(od_pam_auth_data_t *d)
|
|
|
|
{
|
2020-06-16 05:27:33 +00:00
|
|
|
od_list_t *i;
|
|
|
|
od_list_foreach(&d->link, i)
|
|
|
|
{
|
|
|
|
od_pam_auth_data_t *current =
|
|
|
|
od_container_of(i, od_pam_auth_data_t, link);
|
|
|
|
free(current->value);
|
|
|
|
}
|
2020-06-09 09:19:11 +00:00
|
|
|
od_list_unlink(&d->link);
|
|
|
|
free(d);
|
2020-06-16 05:27:33 +00:00
|
|
|
}
|