forked from bitlbee/bitlbee
-
Notifications
You must be signed in to change notification settings - Fork 0
/
auth_pam.c
62 lines (54 loc) · 1.47 KB
/
auth_pam.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
#define BITLBEE_CORE
#include "bitlbee.h"
#include <security/pam_appl.h>
#define PAM_CHECK(x) do { \
ret = (x); \
if(ret != PAM_SUCCESS) { \
pam_func = #x; \
goto pam_error; \
} \
} while(0)
/* This function fills in the password when PAM asks for it */
int pamconv(int num_msg, const struct pam_message **msg, struct pam_response **resp, void *appdata_ptr) {
int i;
struct pam_response *rsp = g_new0(struct pam_response, num_msg);
for (i = 0; i < num_msg; i++) {
rsp[i].resp = NULL;
rsp[i].resp_retcode = 0;
if (msg[i]->msg_style == PAM_PROMPT_ECHO_OFF) {
rsp[i].resp = g_strdup((char *)appdata_ptr);
}
}
*resp = rsp;
return PAM_SUCCESS;
}
static storage_status_t pam_check_pass(const char *nick, const char *password)
{
int ret;
const struct pam_conv pamc = { pamconv, (void*) password };
pam_handle_t *pamh = NULL;
char *pam_func;
PAM_CHECK(pam_start("bitlbee", nick, &pamc, &pamh));
PAM_CHECK(pam_authenticate(pamh, PAM_DISALLOW_NULL_AUTHTOK));
PAM_CHECK(pam_acct_mgmt(pamh, 0));
pam_end(pamh, ret);
return STORAGE_OK;
pam_error:
switch (ret) {
case PAM_AUTH_ERR:
pam_end(pamh, ret);
return STORAGE_INVALID_PASSWORD;
case PAM_USER_UNKNOWN:
case PAM_PERM_DENIED:
pam_end(pamh, ret);
return STORAGE_NO_SUCH_USER;
default:
log_message(LOGLVL_WARNING, "%s failed: %s", pam_func, pam_strerror(pamh, ret));
pam_end(pamh, ret);
return STORAGE_OTHER_ERROR;
}
}
auth_backend_t auth_pam = {
.name = "pam",
.check_pass = pam_check_pass,
};