radius.c revision 1.1.1.3
1/* $NetBSD: radius.c,v 1.1.1.3 2010/12/12 15:19:13 adam Exp $ */ 2 3/* OpenLDAP: pkg/ldap/contrib/slapd-modules/passwd/radius.c,v 1.2.2.7 2010/04/13 20:22:29 kurt Exp */ 4/* This work is part of OpenLDAP Software <http://www.openldap.org/>. 5 * 6 * Copyright 1998-2010 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 "portable.h" 19 20#include <stdio.h> 21 22#include <lber.h> 23#include <lber_pvt.h> /* BER_BVC definition */ 24#include "lutil.h" 25#include <ldap_pvt_thread.h> 26#include <ac/string.h> 27#include <ac/unistd.h> 28 29#include <radlib.h> 30 31static LUTIL_PASSWD_CHK_FUNC chk_radius; 32static const struct berval scheme = BER_BVC("{RADIUS}"); 33static char *config_filename; 34static ldap_pvt_thread_mutex_t libradius_mutex; 35 36static int 37chk_radius( 38 const struct berval *sc, 39 const struct berval *passwd, 40 const struct berval *cred, 41 const char **text ) 42{ 43 unsigned int i; 44 int rc = LUTIL_PASSWD_ERR; 45 46 struct rad_handle *h = NULL; 47 48 for ( i = 0; i < cred->bv_len; i++ ) { 49 if ( cred->bv_val[ i ] == '\0' ) { 50 return LUTIL_PASSWD_ERR; /* NUL character in cred */ 51 } 52 } 53 54 if ( cred->bv_val[ i ] != '\0' ) { 55 return LUTIL_PASSWD_ERR; /* cred must behave like a string */ 56 } 57 58 for ( i = 0; i < passwd->bv_len; i++ ) { 59 if ( passwd->bv_val[ i ] == '\0' ) { 60 return LUTIL_PASSWD_ERR; /* NUL character in password */ 61 } 62 } 63 64 if ( passwd->bv_val[ i ] != '\0' ) { 65 return LUTIL_PASSWD_ERR; /* passwd must behave like a string */ 66 } 67 68 ldap_pvt_thread_mutex_lock( &libradius_mutex ); 69 70 h = rad_auth_open(); 71 if ( h == NULL ) { 72 ldap_pvt_thread_mutex_unlock( &libradius_mutex ); 73 return LUTIL_PASSWD_ERR; 74 } 75 76 if ( rad_config( h, config_filename ) != 0 ) { 77 goto done; 78 } 79 80 if ( rad_create_request( h, RAD_ACCESS_REQUEST ) ) { 81 goto done; 82 } 83 84 if ( rad_put_string( h, RAD_USER_NAME, passwd->bv_val ) != 0 ) { 85 goto done; 86 } 87 88 if ( rad_put_string( h, RAD_USER_PASSWORD, cred->bv_val ) != 0 ) { 89 goto done; 90 } 91 92 switch ( rad_send_request( h ) ) { 93 case RAD_ACCESS_ACCEPT: 94 rc = LUTIL_PASSWD_OK; 95 break; 96 97 case RAD_ACCESS_REJECT: 98 rc = LUTIL_PASSWD_ERR; 99 break; 100 101 case RAD_ACCESS_CHALLENGE: 102 rc = LUTIL_PASSWD_ERR; 103 break; 104 105 case -1: 106 /* no valid response is received */ 107 break; 108 } 109 110done:; 111 rad_close( h ); 112 113 ldap_pvt_thread_mutex_unlock( &libradius_mutex ); 114 return rc; 115} 116 117int 118term_module() 119{ 120 return ldap_pvt_thread_mutex_destroy( &libradius_mutex ); 121} 122 123int 124init_module( int argc, char *argv[] ) 125{ 126 int i; 127 128 for ( i = 0; i < argc; i++ ) { 129 if ( strncasecmp( argv[ i ], "config=", STRLENOF( "config=" ) ) == 0 ) { 130 /* FIXME: what if multiple loads of same module? 131 * does it make sense (e.g. override an existing one)? */ 132 if ( config_filename == NULL ) { 133 config_filename = ber_strdup( &argv[ i ][ STRLENOF( "config=" ) ] ); 134 } 135 136 } else { 137 fprintf( stderr, "init_module(radius): unknown arg#%d=\"%s\".\n", 138 i, argv[ i ] ); 139 return 1; 140 } 141 } 142 143 ldap_pvt_thread_mutex_init( &libradius_mutex ); 144 145 return lutil_passwd_add( (struct berval *)&scheme, chk_radius, NULL ); 146} 147