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