xref: /netbsd-src/external/bsd/openldap/dist/contrib/slapd-modules/passwd/radius.c (revision 1b9578b8c2c1f848eeb16dabbfd7d1f0d9fdefbd)
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 
31 static LUTIL_PASSWD_CHK_FUNC chk_radius;
32 static const struct berval scheme = BER_BVC("{RADIUS}");
33 static char *config_filename;
34 static ldap_pvt_thread_mutex_t libradius_mutex;
35 
36 static int
37 chk_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 
110 done:;
111 	rad_close( h );
112 
113 	ldap_pvt_thread_mutex_unlock( &libradius_mutex );
114 	return rc;
115 }
116 
117 int
118 term_module()
119 {
120 	return ldap_pvt_thread_mutex_destroy( &libradius_mutex );
121 }
122 
123 int
124 init_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