]> 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 <pppd/pppd.h>
25
26 #include "radiusclient.h"
27
28 char pppd_version[] = PPPD_VERSION;
29
30 char radrealms_config[MAXPATHLEN] = "/etc/radiusclient/realms";
31
32 static option_t Options[] = {
33     { "realms-config-file", o_string, &radrealms_config,
34       "Configuration file for RADIUS realms", OPT_STATIC, NULL, MAXPATHLEN },
35     { NULL }
36 };
37
38 extern void (*radius_pre_auth_hook)(char const *user,
39                                     SERVER **authserver,
40                                     SERVER **acctserver);
41
42 static void
43 lookup_realm(char const *user,
44              SERVER **authserver,
45              SERVER **acctserver)
46 {
47     char *realm;
48     FILE *fd;
49     SERVER *accts, *auths, *s;
50     char buffer[512], *p;
51     int line = 0;
52     
53     auths = (SERVER *) malloc(sizeof(SERVER));
54     auths->max = 0;
55     accts = (SERVER *) malloc(sizeof(SERVER));
56     accts->max = 0;
57     
58     realm = strrchr(user, '@');
59     
60     if (realm) {
61         info("Looking up servers for realm '%s'", realm);
62     } else {
63         info("Looking up servers for DEFAULT realm");
64     }
65     if (realm) {
66         if (*(++realm) == '\0') {
67             realm = NULL;
68         }
69     }
70     
71     if ((fd = fopen(radrealms_config, "r")) == NULL) {
72         option_error("cannot open %s", radrealms_config);
73         free(auths);
74         free(accts);
75         return;
76     }
77     info("Reading %s", radrealms_config);
78
79     while ((fgets(buffer, sizeof(buffer), fd) != NULL)) {
80         line++;
81
82         if ((*buffer == '\n') || (*buffer == '#') || (*buffer == '\0'))
83             continue;
84
85         buffer[strlen(buffer)-1] = '\0';
86
87         p = strtok(buffer, "\t ");
88
89         if (p == NULL || (strcmp(p, "authserver") !=0
90             && strcmp(p, "acctserver"))) {
91             fclose(fd);
92             option_error("%s: invalid line %d: %s", radrealms_config,
93                          line, buffer);
94             free(auths);
95             free(accts);
96             return;
97         }
98         info("Parsing '%s' entry:", p);
99         s = auths;
100         if (p[1] == 'c') {
101             s = accts;
102         }
103         if (s->max >= SERVER_MAX)
104             continue;
105
106         if ((p = strtok(NULL, "\t ")) == NULL) {
107             fclose(fd);
108             option_error("%s: realm name missing on line %d: %s",
109                          radrealms_config, line, buffer);
110             free(auths);
111             free(accts);
112             return;
113         }
114
115         if ((realm != NULL && strcmp(p, realm) == 0) ||
116             (realm == NULL && strcmp(p, "DEFAULT") == 0) ) {
117             info(" - Matched realm %s", p);
118             if ((p = strtok(NULL, ":")) == NULL) {
119                 fclose(fd);
120                 option_error("%s: server address missing on line %d: %s",
121                              radrealms_config, line, buffer);
122                 free(auths);
123                 free(accts);
124                 return;
125             }
126             s->name[s->max] = strdup(p);
127             info(" - Address is '%s'",p);
128             if ((p = strtok(NULL, "\t ")) == NULL) {
129                 fclose(fd);
130                 option_error("%s: server port missing on line %d:  %s",
131                              radrealms_config, line, buffer);
132                 free(auths);
133                 free(accts);
134                 return;
135             }
136             s->port[s->max] = atoi(p);
137             info(" - Port is '%d'", s->port[s->max]);
138             s->max++;
139         } else 
140             info(" - Skipping realm '%s'", p);
141     }
142     fclose(fd);
143
144     if (accts->max)
145         *acctserver = accts;
146
147     if (auths->max)
148         *authserver = auths;
149
150     return;
151 }
152
153 void
154 plugin_init(void)
155 {
156     radius_pre_auth_hook = lookup_realm;
157
158     add_options(Options);
159     info("RADIUS Realms plugin initialized.");
160 }