1 /* $Cambridge: exim/src/src/auths/call_radius.c,v 1.4 2005/08/22 10:49:04 ph10 Exp $ */
3 /*************************************************
4 * Exim - an Internet mail transport agent *
5 *************************************************/
7 /* Copyright (c) University of Cambridge 1995 - 2005 */
8 /* See the file NOTICE for conditions of use and distribution. */
10 /* This file was originally supplied by Ian Kirk. The libradius support came
15 /* This module contains functions that call the Radius authentication
18 We can't just compile this code and allow the library mechanism to omit the
19 functions if they are not wanted, because we need to have the Radius headers
20 available for compiling. Therefore, compile these functions only if
21 RADIUS_CONFIG_FILE is defined. However, some compilers don't like compiling
22 empty modules, so keep them happy with a dummy when skipping the rest. Make it
23 reference itself to stop picky compilers complaining that it is unused, and put
24 in a dummy argument to stop even pickier compilers complaining about infinite
27 #ifndef RADIUS_CONFIG_FILE
28 static void dummy(int x) { dummy(x-1); }
29 #else /* RADIUS_CONFIG_FILE */
32 /* Two different Radius libraries are supported. The default is radiusclient,
33 using its original API. At release 0.4.0 the API changed. */
35 #ifdef RADIUS_LIB_RADLIB
38 #if !defined(RADIUS_LIB_RADIUSCLIENT) && !defined(RADIUS_LIB_RADIUSCLIENTNEW)
39 #define RADIUS_LIB_RADIUSCLIENT
41 #include <radiusclient.h>
46 /*************************************************
47 * Perform RADIUS authentication *
48 *************************************************/
50 /* This function calls the Radius authentication mechanism, passing over one or
54 s a colon-separated list of strings
55 errptr where to point an error message
57 Returns: OK if authentication succeeded
58 FAIL if authentication failed
59 ERROR some other error condition
63 auth_call_radius(uschar *s, uschar **errptr)
66 uschar *radius_args = s;
70 #ifdef RADIUS_LIB_RADLIB
73 #ifdef RADIUS_LIB_RADIUSCLIENTNEW
76 VALUE_PAIR *send = NULL;
78 unsigned int service = PW_AUTHENTICATE_ONLY;
83 user = string_nextinlist(&radius_args, &sep, big_buffer, big_buffer_size);
84 if (user == NULL) user = US"";
86 DEBUG(D_auth) debug_printf("Running RADIUS authentication for user \"%s\" "
87 "and \"%s\"\n", user, radius_args);
92 /* Authenticate using the radiusclient library */
94 #ifndef RADIUS_LIB_RADLIB
98 #ifdef RADIUS_LIB_RADIUSCLIENT
99 if (rc_read_config(RADIUS_CONFIG_FILE) != 0)
100 *errptr = string_sprintf("RADIUS: can't open %s", RADIUS_CONFIG_FILE);
102 else if (rc_read_dictionary(rc_conf_str("dictionary")) != 0)
103 *errptr = string_sprintf("RADIUS: can't read dictionary");
105 else if (rc_avpair_add(&send, PW_USER_NAME, user, 0) == NULL)
106 *errptr = string_sprintf("RADIUS: add user name failed\n");
108 else if (rc_avpair_add(&send, PW_USER_PASSWORD, CS radius_args, 0) == NULL)
109 *errptr = string_sprintf("RADIUS: add password failed\n");
111 else if (rc_avpair_add(&send, PW_SERVICE_TYPE, &service, 0) == NULL)
112 *errptr = string_sprintf("RADIUS: add service type failed\n");
114 #else /* RADIUS_LIB_RADIUSCLIENT unset => RADIUS_LIB_RADIUSCLIENT2 */
116 if ((h = rc_read_config(RADIUS_CONFIG_FILE)) == NULL)
117 *errptr = string_sprintf("RADIUS: can't open %s", RADIUS_CONFIG_FILE);
119 else if (rc_read_dictionary(h, rc_conf_str(h, "dictionary")) != 0)
120 *errptr = string_sprintf("RADIUS: can't read dictionary");
122 else if (rc_avpair_add(h, &send, PW_USER_NAME, user, Ustrlen(user), 0) == NULL)
123 *errptr = string_sprintf("RADIUS: add user name failed\n");
125 else if (rc_avpair_add(h, &send, PW_USER_PASSWORD, CS radius_args,
126 Ustrlen(radius_args), 0) == NULL)
127 *errptr = string_sprintf("RADIUS: add password failed\n");
129 else if (rc_avpair_add(h, &send, PW_SERVICE_TYPE, &service, 0, 0) == NULL)
130 *errptr = string_sprintf("RADIUS: add service type failed\n");
132 #endif /* RADIUS_LIB_RADIUSCLIENT */
136 DEBUG(D_auth) debug_printf("%s\n", *errptr);
140 #ifdef RADIUS_LIB_RADIUSCLIENT
141 result = rc_auth(0, send, &received, msg);
143 result = rc_auth(h, 0, send, &received, msg);
146 DEBUG(D_auth) debug_printf("RADIUS code returned %d\n", result);
157 *errptr = US"RADIUS: timed out";
162 *errptr = string_sprintf("RADIUS: unexpected response (%d)", result);
166 #else /* RADIUS_LIB_RADLIB is set */
168 /* Authenticate using the libradius library */
173 *errptr = string_sprintf("RADIUS: can't initialise libradius");
176 if (rad_config(h, RADIUS_CONFIG_FILE) != 0 ||
177 rad_create_request(h, RAD_ACCESS_REQUEST) != 0 ||
178 rad_put_string(h, RAD_USER_NAME, CS user) != 0 ||
179 rad_put_string(h, RAD_USER_PASSWORD, CS radius_args) != 0 ||
180 rad_put_int(h, RAD_SERVICE_TYPE, RAD_AUTHENTICATE_ONLY) != 0)
182 *errptr = string_sprintf("RADIUS: %s", rad_strerror(h));
187 result = rad_send_request(h);
191 case RAD_ACCESS_ACCEPT:
195 case RAD_ACCESS_REJECT:
200 *errptr = string_sprintf("RADIUS: %s", rad_strerror(h));
205 *errptr = string_sprintf("RADIUS: unexpected response (%d)", result);
211 if (*errptr != NULL) DEBUG(D_auth) debug_printf("%s\n", *errptr);
215 #endif /* RADIUS_LIB_RADLIB */
218 #endif /* RADIUS_CONFIG_FILE */
220 /* End of call_radius.c */