Annotation of ircnowd/src/ngircd/pam.c, Revision 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