From f35a55398a3bc209f3d84b73bc5c978765b003fd Mon Sep 17 00:00:00 2001 From: Pierangelo Masarati Date: Fri, 12 May 2006 12:03:05 +0000 Subject: [PATCH] add (basic) support for {RADIUS} scheme; userPassword attributes prefixed with {RADIUS} are interpreted as RADIUS userids and authentication occurs contacting the configured RADIUS servers with that userid and the provided password (experimental; please report) --- contrib/slapd-modules/passwd/README | 18 +++- contrib/slapd-modules/passwd/radius.c | 115 ++++++++++++++++++++++++++ 2 files changed, 132 insertions(+), 1 deletion(-) create mode 100644 contrib/slapd-modules/passwd/radius.c diff --git a/contrib/slapd-modules/passwd/README b/contrib/slapd-modules/passwd/README index f6594cb440..ee288431bf 100644 --- a/contrib/slapd-modules/passwd/README +++ b/contrib/slapd-modules/passwd/README @@ -6,7 +6,7 @@ Public License. This directory contains native slapd plugins for password mechanisms that are not actively supported by the project. Currently this includes the -Kerberos and Netscape MTA-MD5 password mechanisms. +Kerberos, Netscape MTA-MD5 and RADIUS password mechanisms. To use the Kerberos plugin, add: @@ -20,6 +20,15 @@ moduleload pw-netscape.so to your slapd configuration file. +To use the RADIUS plugin, add: + +moduleload pw-radius.so + +to your slapd configuration file; optionally, the path to a configuration +file can be appended in the form + +moduleload pw-radius.so config="/etc/radius.conf" + No Makefile is provided. Use a command line similar to: gcc -shared -I../../../include -Wall -g -DHAVE_KRB5 -o pw-kerberos.so kerberos.c @@ -32,3 +41,10 @@ The corresponding command for the Netscape plugin would be: gcc -shared -I../../../include -Wall -g -o pw-netscape.so netscape.c +The corresponding command for the RADIUS plugin would be: + +gcc -shared -I../../../include -Wall -g -o pw-radius.so radius.c -lradius + +(Actually, you might want to statically link the RADIUS client library +libradius.a into the module). + diff --git a/contrib/slapd-modules/passwd/radius.c b/contrib/slapd-modules/passwd/radius.c new file mode 100644 index 0000000000..3e0c73d7d1 --- /dev/null +++ b/contrib/slapd-modules/passwd/radius.c @@ -0,0 +1,115 @@ +/* $OpenLDAP$ */ +/* + * Copyright 1998-2006 The OpenLDAP Foundation. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted only as authorized by the OpenLDAP + * Public License. + * + * A copy of this license is available in the file LICENSE in the + * top-level directory of the distribution or, alternatively, at + * . + */ + +#include + +#include +#include /* BER_BVC definition */ +#include "lutil.h" +#include +#include + +#include + +static LUTIL_PASSWD_CHK_FUNC chk_radius; +static const struct berval scheme = BER_BVC("{RADIUS}"); +static char *config_filename; + +static int +chk_radius( + const struct berval *sc, + const struct berval *passwd, + const struct berval *cred, + const char **text ) +{ + unsigned int i; + int rc = LUTIL_PASSWD_ERR; + + struct rad_handle *h = NULL; + + for ( i = 0; i < cred->bv_len; i++ ) { + if ( cred->bv_val[ i ] == '\0' ) { + return LUTIL_PASSWD_ERR; /* NUL character in cred */ + } + } + + if ( cred->bv_val[ i ] != '\0' ) { + return LUTIL_PASSWD_ERR; /* cred must behave like a string */ + } + + for ( i = 0; i < passwd->bv_len; i++ ) { + if ( passwd->bv_val[ i ] == '\0' ) { + return LUTIL_PASSWD_ERR; /* NUL character in password */ + } + } + + if ( passwd->bv_val[ i ] != '\0' ) { + return LUTIL_PASSWD_ERR; /* passwd must behave like a string */ + } + + h = rad_auth_open(); + if ( h == NULL ) { + return LUTIL_PASSWD_ERR; + } + + if ( config_filename ) { + if ( rad_config( h, config_filename ) != 0 ) { + goto done; + } + } + + if ( rad_create_request( h, RAD_ACCESS_REQUEST ) ) { + goto done; + } + + if ( rad_put_string( h, RAD_USER_NAME, passwd->bv_val ) != 0 ) { + goto done; + } + + if ( rad_put_string( h, RAD_USER_PASSWORD, cred->bv_val ) != 0 ) { + goto done; + } + + if ( rad_send_request( h ) == RAD_ACCESS_ACCEPT ) { + rc = LUTIL_PASSWD_OK; + } + +done:; + rad_close( h ); + + return rc; +} + +int +init_module( int argc, char *argv[] ) +{ + int i; + + for ( i = 0; i < argc; i++ ) { + if ( strncasecmp( argv[ i ], "config=", STRLENOF( "config=" ) ) == 0 ) { + /* FIXME: what if multiple loads of same module? + * does it make sense (e.g. override an existing one)? */ + if ( config_filename == NULL ) { + config_filename = ber_strdup( &argv[ i ][ STRLENOF( "config=" ) ] ); + } + + } else { + fprintf( stderr, "init_module(radius): unknown arg#%d=\"%s\".\n", + i, argv[ i ] ); + return 1; + } + } + + return lutil_passwd_add( (struct berval *)&scheme, chk_radius, NULL ); +} -- 2.39.5