~ubuntu-branches/ubuntu/oneiric/jabberd2/oneiric-security

« back to all changes in this revision

Viewing changes to storage/authreg_pam.c

  • Committer: Bazaar Package Importer
  • Author(s): Nicolai Spohrer
  • Date: 2008-08-12 16:13:43 UTC
  • mfrom: (1.1.3 upstream) (0.1.2 sid)
  • Revision ID: james.westby@ubuntu.com-20080812161343-6trz3r97dtevxd17
Tags: 2.2.1-1ubuntu1
* Merge with Debian unstable (LP: #257130), remaining changes:
  - debian/control:
    + Modify Maintainer field as per spec
    + Depend on libdb4.6-dev instead of libdb4.4-dev
    + Added Conflicts and Replaces: ..., jabber for jabberd2
  - debian/rules: Added libtoolize call (jabberd2 ships with
     an older ltmain.sh version that conflicts with the
     current libtool version)
  - debian/init: create /var/run/jabber directory with correct
     permissions
* Dropped changes:
  - Debian already depends on libpq-dev

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * jabberd - Jabber Open Source Server
 
3
 * Copyright (c) 2002-2003 Jeremie Miller, Thomas Muldowney,
 
4
 *                         Ryan Eatmon, Robert Norris
 
5
 *
 
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.
 
10
 *
 
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.
 
15
 *
 
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
 
19
 */
 
20
 
 
21
/* this plugin uses PAM for authentication */
 
22
 
 
23
#include "c2s.h"
 
24
#include <security/pam_appl.h>
 
25
 
 
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 */
 
28
    return 1;
 
29
}
 
30
 
 
31
static int _ar_pam_conversation(int nmsg, const struct pam_message **msg, struct pam_response **res, void *arg) {
 
32
    int i;
 
33
    struct pam_response *reply;
 
34
 
 
35
    if(nmsg <= 0)
 
36
        return PAM_CONV_ERR;
 
37
 
 
38
    reply = (struct pam_response *) calloc(1, sizeof(struct pam_response) * nmsg);
 
39
 
 
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;
 
44
        }
 
45
    }
 
46
 
 
47
    *res = reply;
 
48
 
 
49
    return PAM_SUCCESS;
 
50
}
 
51
 
 
52
#ifdef PAM_FAIL_DELAY
 
53
static int _ar_pam_delay(int ret, unsigned int usec, void *arg) {
 
54
    /* !!! hack the current byterate limit to throttle the connection */
 
55
    return PAM_SUCCESS;
 
56
}
 
57
#endif
 
58
 
 
59
static int _ar_pam_check_password(authreg_t ar, char *username, char *realm, char password[257]) {
 
60
    struct pam_conv conv;
 
61
    pam_handle_t *pam;
 
62
    int ret, user_len, realm_len;
 
63
    char *user_realm = 0;
 
64
 
 
65
    conv.conv = _ar_pam_conversation;
 
66
    conv.appdata_ptr = password;
 
67
 
 
68
    if (realm) {
 
69
        realm_len = strlen(realm);
 
70
        if (realm_len > 0) {
 
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);
 
76
        }
 
77
    }
 
78
    if (user_realm) {
 
79
        ret = pam_start("jabberd", user_realm, &conv, &pam);
 
80
    } else {
 
81
        ret = pam_start("jabberd", username, &conv, &pam);
 
82
    }
 
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));
 
86
        return 1;
 
87
    }
 
88
 
 
89
#ifdef PAM_FAIL_DELAY
 
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));
 
93
        return 1;
 
94
    }
 
95
#endif
 
96
 
 
97
    ret = pam_authenticate(pam, 0);
 
98
    if(ret == PAM_AUTHINFO_UNAVAIL || ret == PAM_USER_UNKNOWN) {
 
99
        pam_end(pam, ret);
 
100
        return 1;
 
101
    }
 
102
 
 
103
    if(ret != PAM_SUCCESS) {
 
104
        log_write(ar->c2s->log, LOG_ERR, "pam: couldn't authenticate: %s", pam_strerror(NULL, ret));
 
105
        pam_end(pam, ret);
 
106
        return 1;
 
107
    }
 
108
 
 
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));
 
112
        pam_end(pam, ret);
 
113
        return 1;
 
114
    }
 
115
 
 
116
    pam_end(pam, ret);
 
117
 
 
118
    return 0;
 
119
}
 
120
 
 
121
/** start me up */
 
122
int ar_init(authreg_t ar) {
 
123
    ar->user_exists = _ar_pam_user_exists;
 
124
    ar->check_password = _ar_pam_check_password;
 
125
 
 
126
    return 0;
 
127
}