[BACK]Return to pam.c CVS log [TXT][DIR] Up to [local] / ircnowd / src / ngircd

Annotation of ircnowd/src/ngircd/pam.c, Revision 1.1.1.1

1.1       tomglok     1: /*
                      2:  * ngIRCd -- The Next Generation IRC Daemon
                      3:  * Copyright (c)2001-2014 Alexander Barton (alex@barton.de) and Contributors.
                      4:  *
                      5:  * This program is free software; you can redistribute it and/or modify
                      6:  * it under the terms of the GNU General Public License as published by
                      7:  * the Free Software Foundation; either version 2 of the License, or
                      8:  * (at your option) any later version.
                      9:  * Please read the file COPYING, README and AUTHORS for more information.
                     10:  */
                     11:
                     12: #include "portab.h"
                     13:
                     14: #ifdef PAM
                     15:
                     16: /**
                     17:  * @file
                     18:  * PAM User Authentication
                     19:  */
                     20:
                     21: #include <assert.h>
                     22: #include <stdlib.h>
                     23: #include <string.h>
                     24: #ifdef HAVE_SECURITY_PAM_APPL_H
                     25: # include <security/pam_appl.h>
                     26: #endif
                     27: #ifdef HAVE_PAM_PAM_APPL_H
                     28: # include <pam/pam_appl.h>
                     29: #endif
                     30:
                     31: #include "defines.h"
                     32: #include "log.h"
                     33: #include "conn.h"
                     34: #include "client.h"
                     35: #include "conf.h"
                     36:
                     37: #include "pam.h"
                     38:
                     39: static char *password;
                     40:
                     41: /**
                     42:  * PAM "conversation function".
                     43:  * This is a callback function used by the PAM library to get the password.
                     44:  * Please see the PAM documentation for details :-)
                     45:  */
                     46: static int
                     47: password_conversation(int num_msg, const struct pam_message **msg,
                     48:                      struct pam_response **resp, void *appdata_ptr) {
                     49:        LogDebug("PAM: conv(%d, %d, '%s', '%s')",
                     50:                 num_msg, msg[0]->msg_style, msg[0]->msg, appdata_ptr);
                     51:
                     52:        /* Can we deal with this request? */
                     53:        if (num_msg != 1 || msg[0]->msg_style != PAM_PROMPT_ECHO_OFF) {
                     54:                Log(LOG_ERR, "PAM: Unexpected PAM conversation '%d:%s'!",
                     55:                    msg[0]->msg_style, msg[0]->msg);
                     56:                return PAM_CONV_ERR;
                     57:        }
                     58:
                     59:        if (!appdata_ptr) {
                     60:                /* Sometimes appdata_ptr gets lost!? */
                     61:                appdata_ptr = password;
                     62:        }
                     63:
                     64:        /* Duplicate password ("application data") for the PAM library */
                     65:        *resp = calloc(num_msg, sizeof(struct pam_response));
                     66:        if (!*resp) {
                     67:                Log(LOG_ERR, "PAM: Out of memory!");
                     68:                return PAM_CONV_ERR;
                     69:        }
                     70:
                     71:        (*resp)[0].resp = strdup((char *)appdata_ptr);
                     72:        (*resp)[0].resp_retcode = 0;
                     73:
                     74:        return ((*resp)[0].resp ? PAM_SUCCESS : PAM_CONV_ERR);
                     75: }
                     76:
                     77: /**
                     78:  * PAM "conversation" structure.
                     79:  */
                     80: static struct pam_conv conv = {
                     81:        &password_conversation,
                     82:        NULL
                     83: };
                     84:
                     85: /**
                     86:  * Authenticate a connecting client using PAM.
                     87:  * @param Client The client to authenticate.
                     88:  * @return true when authentication succeeded, false otherwise.
                     89:  */
                     90: GLOBAL bool
                     91: PAM_Authenticate(CLIENT *Client) {
                     92:        pam_handle_t *pam;
                     93:        int retval = PAM_SUCCESS;
                     94:
                     95:        LogDebug("PAM: Authenticate \"%s\" (%s) ...",
                     96:                 Client_OrigUser(Client), Client_Mask(Client));
                     97:
                     98:        /* Set supplied client password */
                     99:        if (password)
                    100:                free(password);
                    101:        password = strdup(Conn_Password(Client_Conn(Client)));
                    102:        conv.appdata_ptr = Conn_Password(Client_Conn(Client));
                    103:
                    104:        /* Initialize PAM */
                    105:        retval = pam_start(Conf_PAMServiceName, Client_OrigUser(Client), &conv, &pam);
                    106:        if (retval != PAM_SUCCESS) {
                    107:                Log(LOG_ERR, "PAM: Failed to create authenticator! (%d)", retval);
                    108:                return false;
                    109:        }
                    110:
                    111:        pam_set_item(pam, PAM_RUSER, Client_User(Client));
                    112:        pam_set_item(pam, PAM_RHOST, Client_Hostname(Client));
                    113: #if defined(HAVE_PAM_FAIL_DELAY) && !defined(NO_PAM_FAIL_DELAY)
                    114:        pam_fail_delay(pam, 0);
                    115: #endif
                    116:
                    117:        /* PAM authentication ... */
                    118:        retval = pam_authenticate(pam, 0);
                    119:
                    120:        /* Success? */
                    121:        if (retval == PAM_SUCCESS)
                    122:                Log(LOG_INFO, "PAM: Authenticated \"%s\" (%s).",
                    123:                    Client_OrigUser(Client), Client_Mask(Client));
                    124:        else
                    125:                Log(LOG_ERR, "PAM: Error on \"%s\" (%s): %s",
                    126:                    Client_OrigUser(Client), Client_Mask(Client),
                    127:                    pam_strerror(pam, retval));
                    128:
                    129:        /* Free PAM structures */
                    130:        if (pam_end(pam, retval) != PAM_SUCCESS)
                    131:                Log(LOG_ERR, "PAM: Failed to release authenticator!");
                    132:
                    133:        return (retval == PAM_SUCCESS);
                    134: }
                    135:
                    136: #endif /* PAM */
                    137:
                    138: /* -eof- */

CVSweb