radius.c revision 1.1.1.5
1/* $NetBSD: radius.c,v 1.1.1.5 2017/02/09 01:46:42 christos Exp $ */ 2 3/* $OpenLDAP$ */ 4/* This work is part of OpenLDAP Software <http://www.openldap.org/>. 5 * 6 * Copyright 1998-2016 The OpenLDAP Foundation. 7 * All rights reserved. 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted only as authorized by the OpenLDAP 11 * Public License. 12 * 13 * A copy of this license is available in the file LICENSE in the 14 * top-level directory of the distribution or, alternatively, at 15 * <http://www.OpenLDAP.org/license.html>. 16 */ 17 18#include <sys/cdefs.h> 19__RCSID("$NetBSD: radius.c,v 1.1.1.5 2017/02/09 01:46:42 christos Exp $"); 20 21#include "portable.h" 22 23#include <stdio.h> 24 25#include <lber.h> 26#include <lber_pvt.h> /* BER_BVC definition */ 27#include "lutil.h" 28#include <ldap_pvt_thread.h> 29#include <ac/string.h> 30#include <ac/unistd.h> 31 32#include <radlib.h> 33 34extern char *global_host; /* from slapd */ 35static LUTIL_PASSWD_CHK_FUNC chk_radius; 36static const struct berval scheme = BER_BVC("{RADIUS}"); 37static char *config_filename; 38static ldap_pvt_thread_mutex_t libradius_mutex; 39 40static int 41chk_radius( 42 const struct berval *sc, 43 const struct berval *passwd, 44 const struct berval *cred, 45 const char **text ) 46{ 47 unsigned int i; 48 int rc = LUTIL_PASSWD_ERR; 49 50 struct rad_handle *h = NULL; 51 52 for ( i = 0; i < cred->bv_len; i++ ) { 53 if ( cred->bv_val[ i ] == '\0' ) { 54 return LUTIL_PASSWD_ERR; /* NUL character in cred */ 55 } 56 } 57 58 if ( cred->bv_val[ i ] != '\0' ) { 59 return LUTIL_PASSWD_ERR; /* cred must behave like a string */ 60 } 61 62 for ( i = 0; i < passwd->bv_len; i++ ) { 63 if ( passwd->bv_val[ i ] == '\0' ) { 64 return LUTIL_PASSWD_ERR; /* NUL character in password */ 65 } 66 } 67 68 if ( passwd->bv_val[ i ] != '\0' ) { 69 return LUTIL_PASSWD_ERR; /* passwd must behave like a string */ 70 } 71 72 ldap_pvt_thread_mutex_lock( &libradius_mutex ); 73 74 h = rad_auth_open(); 75 if ( h == NULL ) { 76 ldap_pvt_thread_mutex_unlock( &libradius_mutex ); 77 return LUTIL_PASSWD_ERR; 78 } 79 80 if ( rad_config( h, config_filename ) != 0 ) { 81 goto done; 82 } 83 84 if ( rad_create_request( h, RAD_ACCESS_REQUEST ) ) { 85 goto done; 86 } 87 88 if ( rad_put_string( h, RAD_USER_NAME, passwd->bv_val ) != 0 ) { 89 goto done; 90 } 91 92 if ( rad_put_string( h, RAD_USER_PASSWORD, cred->bv_val ) != 0 ) { 93 goto done; 94 } 95 96 if ( rad_put_string( h, RAD_NAS_IDENTIFIER, global_host ) != 0 ) { 97 goto done; 98 } 99 100 switch ( rad_send_request( h ) ) { 101 case RAD_ACCESS_ACCEPT: 102 rc = LUTIL_PASSWD_OK; 103 break; 104 105 case RAD_ACCESS_REJECT: 106 rc = LUTIL_PASSWD_ERR; 107 break; 108 109 case RAD_ACCESS_CHALLENGE: 110 rc = LUTIL_PASSWD_ERR; 111 break; 112 113 case -1: 114 /* no valid response is received */ 115 break; 116 } 117 118done:; 119 rad_close( h ); 120 121 ldap_pvt_thread_mutex_unlock( &libradius_mutex ); 122 return rc; 123} 124 125int 126term_module() 127{ 128 return ldap_pvt_thread_mutex_destroy( &libradius_mutex ); 129} 130 131int 132init_module( int argc, char *argv[] ) 133{ 134 int i; 135 136 for ( i = 0; i < argc; i++ ) { 137 if ( strncasecmp( argv[ i ], "config=", STRLENOF( "config=" ) ) == 0 ) { 138 /* FIXME: what if multiple loads of same module? 139 * does it make sense (e.g. override an existing one)? */ 140 if ( config_filename == NULL ) { 141 config_filename = ber_strdup( &argv[ i ][ STRLENOF( "config=" ) ] ); 142 } 143 144 } else { 145 fprintf( stderr, "init_module(radius): unknown arg#%d=\"%s\".\n", 146 i, argv[ i ] ); 147 return 1; 148 } 149 } 150 151 ldap_pvt_thread_mutex_init( &libradius_mutex ); 152 153 return lutil_passwd_add( (struct berval *)&scheme, chk_radius, NULL ); 154} 155