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