]> git.ozlabs.org Git - ppp.git/blob - pppd/plugins/radius/radrealms.c
Makefile.am: Add explicit openssl directory to pppd include path
[ppp.git] / pppd / plugins / radius / radrealms.c
1 /*
2 *
3 * radrealms.c
4 *
5 * A pppd plugin which is stacked on top of radius.so.  This plugin
6 * allows selection of alternate set of servers based on the user's realm.
7 *
8 * Author: Ben McKeegan  ben@netservers.co.uk
9 *
10 * Copyright (C) 2002 Netservers
11 *
12 * This plugin may be distributed according to the terms of the GNU
13 * General Public License, version 2 or (at your option) any later version.
14 *
15 */
16
17 static char const RCSID[] =
18     "$Id: radrealms.c,v 1.2 2004/11/14 07:26:26 paulus Exp $";
19
20 #include <stdio.h>
21 #include <string.h>
22 #include <stdlib.h>
23 #include <sys/param.h>
24 #include <stdbool.h>
25 #include <stdint.h>
26 #include <stdarg.h>
27 #include <sys/types.h>
28
29 #include <pppd/pppd.h>
30
31 #include "radiusclient.h"
32
33 char pppd_version[] = PPPD_VERSION;
34
35 char radrealms_config[MAXPATHLEN] = "/etc/radiusclient/realms";
36
37 static option_t Options[] = {
38     { "realms-config-file", o_string, &radrealms_config,
39       "Configuration file for RADIUS realms", OPT_STATIC, NULL, MAXPATHLEN },
40     { NULL }
41 };
42
43 extern void (*radius_pre_auth_hook)(char const *user,
44                                     SERVER **authserver,
45                                     SERVER **acctserver);
46
47 static void
48 lookup_realm(char const *user,
49              SERVER **authserver,
50              SERVER **acctserver)
51 {
52     char *realm;
53     FILE *fd;
54     SERVER *accts, *auths, *s;
55     char buffer[512], *p;
56     int line = 0;
57     
58     auths = (SERVER *) malloc(sizeof(SERVER));
59     auths->max = 0;
60     accts = (SERVER *) malloc(sizeof(SERVER));
61     accts->max = 0;
62     
63     realm = strrchr(user, '@');
64     
65     if (realm) {
66         info("Looking up servers for realm '%s'", realm);
67     } else {
68         info("Looking up servers for DEFAULT realm");
69     }
70     if (realm) {
71         if (*(++realm) == '\0') {
72             realm = NULL;
73         }
74     }
75     
76     if ((fd = fopen(radrealms_config, "r")) == NULL) {
77         ppp_option_error("cannot open %s", radrealms_config);
78         free(auths);
79         free(accts);
80         return;
81     }
82     info("Reading %s", radrealms_config);
83
84     while ((fgets(buffer, sizeof(buffer), fd) != NULL)) {
85         line++;
86
87         if ((*buffer == '\n') || (*buffer == '#') || (*buffer == '\0'))
88             continue;
89
90         buffer[strlen(buffer)-1] = '\0';
91
92         p = strtok(buffer, "\t ");
93
94         if (p == NULL || (strcmp(p, "authserver") !=0
95             && strcmp(p, "acctserver"))) {
96             fclose(fd);
97             ppp_option_error("%s: invalid line %d: %s", radrealms_config,
98                          line, buffer);
99             free(auths);
100             free(accts);
101             return;
102         }
103         info("Parsing '%s' entry:", p);
104         s = auths;
105         if (p[1] == 'c') {
106             s = accts;
107         }
108         if (s->max >= SERVER_MAX)
109             continue;
110
111         if ((p = strtok(NULL, "\t ")) == NULL) {
112             fclose(fd);
113             ppp_option_error("%s: realm name missing on line %d: %s",
114                          radrealms_config, line, buffer);
115             free(auths);
116             free(accts);
117             return;
118         }
119
120         if ((realm != NULL && strcmp(p, realm) == 0) ||
121             (realm == NULL && strcmp(p, "DEFAULT") == 0) ) {
122             info(" - Matched realm %s", p);
123             if ((p = strtok(NULL, ":")) == NULL) {
124                 fclose(fd);
125                 ppp_option_error("%s: server address missing on line %d: %s",
126                              radrealms_config, line, buffer);
127                 free(auths);
128                 free(accts);
129                 return;
130             }
131             s->name[s->max] = strdup(p);
132             info(" - Address is '%s'",p);
133             if ((p = strtok(NULL, "\t ")) == NULL) {
134                 fclose(fd);
135                 ppp_option_error("%s: server port missing on line %d:  %s",
136                              radrealms_config, line, buffer);
137                 free(auths);
138                 free(accts);
139                 return;
140             }
141             s->port[s->max] = atoi(p);
142             info(" - Port is '%d'", s->port[s->max]);
143             s->max++;
144         } else 
145             info(" - Skipping realm '%s'", p);
146     }
147     fclose(fd);
148
149     if (accts->max)
150         *acctserver = accts;
151     else
152         free(accts);
153
154     if (auths->max)
155         *authserver = auths;
156     else
157         free(auths);
158
159     return;
160 }
161
162 void
163 plugin_init(void)
164 {
165     radius_pre_auth_hook = lookup_realm;
166
167     ppp_add_options(Options);
168     info("RADIUS Realms plugin initialized.");
169 }