2 * $Id: radius.c,v 1.2 2002/04/02 14:09:35 dfs Exp $
4 * Copyright (C) 1996 Lars Fenneberg
6 * See the file COPYRIGHT for the respective terms and conditions.
7 * If the file is missing contact me at lf@elemental.net
8 * and I'll send you a copy.
14 #include <radiusclient.h>
20 LFUNC auth_radius(UINT4 client_port, char *username, char *passwd)
23 VALUE_PAIR *send, *received, *vp, *service_vp;
24 UINT4 service, ftype, ctype;
25 char msg[4096], *p, username_realm[256];
26 char name[2048], value[2048]; /* more than enough */
28 char *default_realm, *service_str, *ftype_str;
31 send = received = NULL;
34 * Determine and fill in Service-Type
38 /* determine based on the username what kind of service is requested.
39 this allows you to use one password for all accounts, but the
40 Merit radiusd supplies you just with the right information you
41 need for the specified service type -lf, 03/15/96 */
54 ctype = PW_VAN_JACOBSON_TCP_IP;
75 if (rc_avpair_add(&send, PW_SERVICE_TYPE, &service, 0, VENDOR_NONE) == NULL)
78 /* Fill in Framed-Protocol, if neccessary */
82 if (rc_avpair_add(&send, PW_FRAMED_PROTOCOL, &ftype, 0, VENDOR_NONE) == NULL)
86 /* Fill in Framed-Compression, if neccessary */
90 if (rc_avpair_add(&send, PW_FRAMED_COMPRESSION, &ctype, 0, VENDOR_NONE) == NULL)
98 strncpy(username_realm, username, sizeof(username_realm));
100 /* Append default realm */
101 default_realm = rc_conf_str("default_realm");
103 if ((strchr(username_realm, '@') == NULL) && default_realm &&
104 ((*default_realm) != '\0'))
106 strncat(username_realm, "@", sizeof(username_realm));
107 strncat(username_realm, default_realm, sizeof(username_realm));
110 if (rc_avpair_add(&send, PW_USER_NAME, username_realm, 0, VENDOR_NONE) == NULL)
114 * Fill in User-Password
117 if (rc_avpair_add(&send, PW_USER_PASSWORD, passwd, 0, VENDOR_NONE) == NULL)
120 result = rc_auth(client_port, send, &received, msg, NULL);
124 /* Set up a running count of attributes saved. */
125 int acount[256], attr;
127 memset(acount, 0, sizeof(acount));
129 rc_add_env(env, "RADIUS_USER_NAME", username);
133 /* map-- keep track of the attributes so that we know
134 when to add the delimiters. Note that we can only
135 handle attributes < 256, which is the standard anyway. */
139 strcpy(name, "RADIUS_");
140 if (rc_avpair_tostr(vp, name+7, sizeof(name)-7, value, sizeof(value)) < 0) {
141 rc_avpair_free(send);
142 rc_avpair_free(received);
146 /* Translate "-" => "_" and uppercase*/
147 for(p = name; *p; p++) {
149 if (*p == '-') *p = '_';
152 /* Add to the attribute count and append the var
154 if ((attr = vp->attribute) < 256)
157 if ((count = acount[attr]++) > 0) {
159 sprintf(buf, "_%d", count);
164 if (rc_add_env(env, name, value) < 0)
166 rc_avpair_free(send);
167 rc_avpair_free(received);
174 service_str = "(unknown)";
177 if ((service_vp = rc_avpair_get(received, PW_SERVICE_TYPE)) != NULL)
178 if ((dval = rc_dict_getval(service_vp->lvalue, service_vp->name)) != NULL) {
179 service_str = dval->name;
182 if (service_vp && (service_vp->lvalue == PW_FRAMED) &&
183 ((vp = rc_avpair_get(received, PW_FRAMED_PROTOCOL)) != NULL))
184 if ((dval = rc_dict_getval(vp->lvalue, vp->name)) != NULL) {
185 ftype_str = dval->name;
188 rc_log(LOG_NOTICE, "authentication OK, username %s, service %s%s%s",
189 username, service_str,(ftype_str)?"/":"", (ftype_str)?ftype_str:"");
191 if (msg && (*msg != '\0'))
192 printf(SC_SERVER_REPLY, msg);
194 printf(SC_RADIUS_OK);
196 rc_avpair_free(send);
197 rc_avpair_free(received);
203 rc_log(LOG_NOTICE, "authentication FAILED, type RADIUS, username %s",
205 if (msg && (*msg != '\0'))
206 printf(SC_SERVER_REPLY, msg);
208 printf(SC_RADIUS_FAILED);
211 rc_avpair_free(send);
213 rc_avpair_free(received);
219 radius_login(char *username)
221 char *login_radius = rc_conf_str("login_radius");
223 execle(login_radius, login_radius, NULL, env->env);
225 rc_log(LOG_ERR, "couldn't execute %s: %s", login_radius, strerror(errno));
226 fprintf(stderr, "couldn't execute %s: %s", login_radius, strerror(errno));
228 sleep(1); /* give the user time to read */