Back to index

openldap  2.4.31
radius.c
Go to the documentation of this file.
00001 /* $OpenLDAP$ */
00002 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
00003  *
00004  * Copyright 1998-2012 The OpenLDAP Foundation.
00005  * All rights reserved.
00006  *
00007  * Redistribution and use in source and binary forms, with or without
00008  * modification, are permitted only as authorized by the OpenLDAP
00009  * Public License.
00010  *
00011  * A copy of this license is available in the file LICENSE in the
00012  * top-level directory of the distribution or, alternatively, at
00013  * <http://www.OpenLDAP.org/license.html>.
00014  */
00015 
00016 #include "portable.h"
00017 
00018 #include <stdio.h>
00019 
00020 #include <lber.h>
00021 #include <lber_pvt.h>       /* BER_BVC definition */
00022 #include "lutil.h"
00023 #include <ldap_pvt_thread.h>
00024 #include <ac/string.h>
00025 #include <ac/unistd.h>
00026 
00027 #include <radlib.h>
00028 
00029 static LUTIL_PASSWD_CHK_FUNC chk_radius;
00030 static const struct berval scheme = BER_BVC("{RADIUS}");
00031 static char *config_filename;
00032 static ldap_pvt_thread_mutex_t libradius_mutex;
00033 
00034 static int
00035 chk_radius(
00036        const struct berval  *sc,
00037        const struct berval  *passwd,
00038        const struct berval  *cred,
00039        const char           **text )
00040 {
00041        unsigned int         i;
00042        int                  rc = LUTIL_PASSWD_ERR;
00043 
00044        struct rad_handle    *h = NULL;
00045 
00046        for ( i = 0; i < cred->bv_len; i++ ) {
00047               if ( cred->bv_val[ i ] == '\0' ) {
00048                      return LUTIL_PASSWD_ERR;    /* NUL character in cred */
00049               }
00050        }
00051 
00052        if ( cred->bv_val[ i ] != '\0' ) {
00053               return LUTIL_PASSWD_ERR;    /* cred must behave like a string */
00054        }
00055 
00056        for ( i = 0; i < passwd->bv_len; i++ ) {
00057               if ( passwd->bv_val[ i ] == '\0' ) {
00058                      return LUTIL_PASSWD_ERR;    /* NUL character in password */
00059               }
00060        }
00061 
00062        if ( passwd->bv_val[ i ] != '\0' ) {
00063               return LUTIL_PASSWD_ERR;    /* passwd must behave like a string */
00064        }
00065 
00066        ldap_pvt_thread_mutex_lock( &libradius_mutex );
00067 
00068        h = rad_auth_open();
00069        if ( h == NULL ) {
00070               ldap_pvt_thread_mutex_unlock( &libradius_mutex );
00071               return LUTIL_PASSWD_ERR;
00072        }
00073 
00074        if ( rad_config( h, config_filename ) != 0 ) {
00075               goto done;
00076        }
00077 
00078        if ( rad_create_request( h, RAD_ACCESS_REQUEST ) ) {
00079               goto done;
00080        }
00081 
00082        if ( rad_put_string( h, RAD_USER_NAME, passwd->bv_val ) != 0 ) {
00083               goto done;
00084        }
00085 
00086        if ( rad_put_string( h, RAD_USER_PASSWORD, cred->bv_val ) != 0 ) {
00087               goto done;
00088        }
00089 
00090        switch ( rad_send_request( h ) ) {
00091        case RAD_ACCESS_ACCEPT:
00092               rc = LUTIL_PASSWD_OK;
00093               break;
00094 
00095        case RAD_ACCESS_REJECT:
00096               rc = LUTIL_PASSWD_ERR;
00097               break;
00098 
00099        case RAD_ACCESS_CHALLENGE:
00100               rc = LUTIL_PASSWD_ERR;
00101               break;
00102 
00103        case -1:
00104               /* no valid response is received */
00105               break;
00106        }
00107 
00108 done:;
00109        rad_close( h );
00110 
00111        ldap_pvt_thread_mutex_unlock( &libradius_mutex );
00112        return rc;
00113 }
00114 
00115 int
00116 term_module()
00117 {
00118        return ldap_pvt_thread_mutex_destroy( &libradius_mutex );
00119 }
00120 
00121 int
00122 init_module( int argc, char *argv[] )
00123 {
00124        int    i;
00125 
00126        for ( i = 0; i < argc; i++ ) {
00127               if ( strncasecmp( argv[ i ], "config=", STRLENOF( "config=" ) ) == 0 ) {
00128                      /* FIXME: what if multiple loads of same module?
00129                       * does it make sense (e.g. override an existing one)? */
00130                      if ( config_filename == NULL ) {
00131                             config_filename = ber_strdup( &argv[ i ][ STRLENOF( "config=" ) ] );
00132                      }
00133 
00134               } else {
00135                      fprintf( stderr, "init_module(radius): unknown arg#%d=\"%s\".\n",
00136                             i, argv[ i ] );
00137                      return 1;
00138               }
00139        }
00140 
00141        ldap_pvt_thread_mutex_init( &libradius_mutex );
00142 
00143        return lutil_passwd_add( (struct berval *)&scheme, chk_radius, NULL );
00144 }