6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20 * Copyright 2000,2006 The FreeRADIUS server project
21 * Copyright 2000 your name <your address>
24 #include <freeradius-devel/ident.h>
27 #include <freeradius-devel/radiusd.h>
28 #include <freeradius-devel/modules.h>
31 static void cleanup(RADIUS_PACKET *packet)
34 if (packet->sockfd >= 0) close(packet->sockfd);
39 * Write accounting information to this modules database.
41 static int replicate_packet(void *instance, REQUEST *request)
43 int rcode = RLM_MODULE_NOOP;
44 VALUE_PAIR *vp, *last;
48 RADIUS_PACKET *packet = NULL;
50 instance = instance; /* -Wunused */
51 last = request->config_items;
54 * Send as many packets as necessary to different
58 vp = pairfind(last, PW_REPLICATE_TO_REALM, 0);
63 realm = realm_find2(vp->vp_strvalue);
65 RDEBUG2("ERROR: Cannot Replicate to unknown realm %s", realm);
70 * We shouldn't really do this on every loop.
72 switch (request->packet->code) {
74 RDEBUG2("ERROR: Cannot replicate unknown packet code %d",
75 request->packet->code);
77 return RLM_MODULE_FAIL;
79 case PW_AUTHENTICATION_REQUEST:
80 pool = realm->auth_pool;
83 #ifdef WITH_ACCOUNTING
85 case PW_ACCOUNTING_REQUEST:
86 pool = realm->acct_pool;
92 case PW_DISCONNECT_REQUEST:
93 pool = realm->acct_pool;
99 RDEBUG2(" WARNING: Cancelling replication to Realm %s, as the realm is local.", realm->name);
103 home = home_server_ldb(realm->name, pool, request);
105 RDEBUG2("ERROR: Failed to find live home server for realm %s",
111 packet = rad_alloc(1);
112 if (!packet) return RLM_MODULE_FAIL;
114 packet->code = request->packet->code;
115 packet->id = fr_rand() & 0xff;
117 packet->sockfd = fr_socket(&home->src_ipaddr, 0);
118 if (packet->sockfd < 0) {
119 RDEBUG("ERROR: Failed opening socket: %s", fr_strerror());
121 return RLM_MODULE_FAIL;
124 packet->vps = paircopy(request->packet->vps);
126 RDEBUG("ERROR: Out of memory!");
128 return RLM_MODULE_FAIL;
132 * For CHAP, create the CHAP-Challenge if
135 if ((request->packet->code == PW_AUTHENTICATION_REQUEST) &&
136 (pairfind(request->packet->vps, PW_CHAP_PASSWORD, 0) != NULL) &&
137 (pairfind(request->packet->vps, PW_CHAP_CHALLENGE, 0) == NULL)) {
138 vp = radius_paircreate(request, &packet->vps,
139 PW_CHAP_CHALLENGE, 0,
141 vp->length = AUTH_VECTOR_LEN;
142 memcpy(vp->vp_strvalue, request->packet->vector,
148 for (i = 0; i < sizeof(packet->vector); i++) {
149 packet->vector[i] = fr_rand() & 0xff;
155 packet->data_len = 0;
161 packet->dst_ipaddr = home->ipaddr;
162 packet->dst_port = home->port;
163 memset(&packet->src_ipaddr, 0, sizeof(packet->src_ipaddr));
164 packet->src_port = 0;
167 * Encode, sign and then send the packet.
169 RDEBUG("Replicating packet to Realm %s", realm->name);
170 if (rad_send(packet, NULL, home->secret) < 0) {
171 RDEBUG("ERROR: Failed replicating packet: %s",
174 return RLM_MODULE_FAIL;
178 * We've sent it to at least one destination.
180 rcode = RLM_MODULE_OK;
187 static int replicate_packet(void *instance, REQUEST *request)
189 RDEBUG("Replication is unsupported in this build.");
190 return RLM_MODULE_FAIL;
195 * The module name should be the only globally exported symbol.
196 * That is, everything else should be 'static'.
198 * If the module needs to temporarily modify it's instantiation
199 * data, the type should be changed to RLM_TYPE_THREAD_UNSAFE.
200 * The server will then take care of ensuring that the module
201 * is single-threaded.
203 module_t rlm_replicate = {
206 RLM_TYPE_THREAD_SAFE, /* type */
207 NULL, /* instantiation */
210 NULL, /* authentication */
211 replicate_packet, /* authorization */
212 NULL, /* preaccounting */
213 replicate_packet, /* accounting */
214 NULL, /* checksimul */
215 NULL, /* pre-proxy */
216 NULL, /* post-proxy */