2
* jabberd - Jabber Open Source Server
3
* Copyright (c) 2002-2003 Jeremie Miller, Thomas Muldowney,
4
* Ryan Eatmon, Robert Norris
6
* This program is free software; you can redistribute it and/or modify
7
* it under the terms of the GNU General Public License as published by
8
* the Free Software Foundation; either version 2 of the License, or
9
* (at your option) any later version.
11
* This program is distributed in the hope that it will be useful,
12
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the
14
* GNU General Public License for more details.
16
* You should have received a copy of the GNU General Public License
17
* along with this program; if not, write to the Free Software
18
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA02111-1307USA
21
/* this plugin uses PAM for authentication */
24
#include <security/pam_appl.h>
26
static int _ar_pam_user_exists(authreg_t ar, char *username, char *realm) {
27
/* we can't check if a user exists, so we just assume we have them all the time */
31
static int _ar_pam_conversation(int nmsg, const struct pam_message **msg, struct pam_response **res, void *arg) {
33
struct pam_response *reply;
38
reply = (struct pam_response *) calloc(1, sizeof(struct pam_response) * nmsg);
40
for(i = 0; i < nmsg; i++) {
41
if(msg[i]->msg_style == PAM_PROMPT_ECHO_OFF || msg[i]->msg_style == PAM_PROMPT_ECHO_ON) {
42
reply[i].resp = strdup((char *) arg);
43
reply[i].resp_retcode = 0;
53
static int _ar_pam_delay(int ret, unsigned int usec, void *arg) {
54
/* !!! hack the current byterate limit to throttle the connection */
59
static int _ar_pam_check_password(authreg_t ar, char *username, char *realm, char password[257]) {
62
int ret, user_len, realm_len;
65
conv.conv = _ar_pam_conversation;
66
conv.appdata_ptr = password;
69
realm_len = strlen(realm);
71
user_len = strlen(username);
72
user_realm = malloc(user_len + realm_len + 2);
73
strcpy(user_realm, username);
74
*(user_realm + user_len) = '@';
75
strcpy(user_realm + user_len + 1, realm);
79
ret = pam_start("jabberd", user_realm, &conv, &pam);
81
ret = pam_start("jabberd", username, &conv, &pam);
83
if (user_realm) free(user_realm);
84
if(ret != PAM_SUCCESS) {
85
log_write(ar->c2s->log, LOG_ERR, "pam: couldn't initialise PAM: %s", pam_strerror(NULL, ret));
90
ret = pam_set_item(pam, PAM_FAIL_DELAY, _ar_pam_delay);
91
if(ret != PAM_SUCCESS) {
92
log_write(ar->c2s->log, LOG_ERR, "pam: couldn't disable fail delay: %s", pam_strerror(NULL, ret));
97
ret = pam_authenticate(pam, 0);
98
if(ret == PAM_AUTHINFO_UNAVAIL || ret == PAM_USER_UNKNOWN) {
103
if(ret != PAM_SUCCESS) {
104
log_write(ar->c2s->log, LOG_ERR, "pam: couldn't authenticate: %s", pam_strerror(NULL, ret));
109
ret = pam_acct_mgmt(pam, 0);
110
if(ret != PAM_SUCCESS) {
111
log_write(ar->c2s->log, LOG_ERR, "pam: authentication succeeded, but can't use account: %s", pam_strerror(NULL, ret));
122
int ar_init(authreg_t ar) {
123
ar->user_exists = _ar_pam_user_exists;
124
ar->check_password = _ar_pam_check_password;