11 static const char rcsid[] = "$Id$";
13 #define REALM_FORMAT_PREFIX 0
14 #define REALM_FORMAT_SUFFIX 1
16 typedef struct realm_config_t {
22 static realm_config_t config;
24 static CONF_PARSER module_config[] = {
25 { "format", PW_TYPE_STRING_PTR, &config.formatstring, "suffix" },
26 { "delimiter", PW_TYPE_STRING_PTR, &config.delim, "@" },
27 { NULL, -1, NULL, NULL } /* end the list */
31 * Internal function to cut down on duplicated code.
33 * Returns NULL on don't proxy, realm otherwise.
35 static REALM *check_for_realm(void *instance, REQUEST *request)
37 char namebuf[MAX_STRING_LEN];
39 char *realmname = (char *)NULL;
44 struct realm_config_t *inst = instance;
50 * If the request has a proxy entry, then it's a proxy
51 * reply, and we're walking through the module list again.
53 * In that case, don't bother trying to proxy the request
56 * Also, if there's no User-Name attribute, we can't
59 if ((request->proxy != NULL) ||
60 (request->username == NULL)) {
64 strncpy(namebuf, request->username->strvalue, MAX_STRING_LEN-1);
69 case REALM_FORMAT_SUFFIX:
71 /* DEBUG2(" rlm_realm: Checking for suffix after \"%c\"", inst->delim[0]); */
73 realmname = strchr(username, inst->delim[0]);
80 case REALM_FORMAT_PREFIX:
82 /* DEBUG2(" rlm_realm: Checking for prefix before \"%c\"", inst->delim[0]); */
84 ptr = strchr(username, inst->delim[0]);
101 realm = realm_find(realmname);
106 /* make sure it's proxyable realm */
107 if (realm->notrealm) {
111 DEBUG2(" rlm_realm: Proxying request from user %s to realm %s",
112 username, realm->realm);
115 * If we've been told to strip the realm off, then do so.
117 if (realm->striprealm) {
119 * Create the Stripped-User-Name attribute, if it
123 vp = pairfind(request->packet->vps, PW_STRIPPED_USER_NAME);
125 vp = paircreate(PW_STRIPPED_USER_NAME, PW_TYPE_STRING);
127 radlog(L_ERR|L_CONS, "no memory");
130 strcpy(vp->strvalue, username);
131 vp->length = strlen((char *)vp->strvalue);
132 pairadd(&request->packet->vps, vp);
133 request->username = vp;
138 * Don't add a 'Realm' attribute, proxy.c does
143 * Perhaps accounting proxying was turned off.
145 if ((request->packet->code == PW_ACCOUNTING_REQUEST) &&
146 (realm->acct_port == 0)) {
147 /* log a warning that the packet isn't getting proxied ??? */
148 DEBUG2("rlm_realm: acct_port is not set. proxy cancelled");
153 * Perhaps authentication proxying was turned off.
155 if ((request->packet->code == PW_AUTHENTICATION_REQUEST) &&
156 (realm->auth_port == 0)) {
157 /* log a warning that the packet isn't getting proxied ??? */
158 DEBUG2("rlm_realm: auth_port is not set. proxy cancelled");
167 * Maybe add a "Proxy-To-Realm" attribute to the request.
169 * If it's a LOCAL realm, then don't bother.
171 static void add_proxy_to_realm(VALUE_PAIR **vps, REALM *realm)
176 * If it's the LOCAL realm, we do NOT proxy it, but
177 * we DO strip the User-Name, if told to do so.
179 if (strcmp(realm->server, "LOCAL") == 0) {
184 * Tell the server to proxy this request to another
187 vp = pairmake("Proxy-To-Realm", realm->realm, T_OP_EQ);
189 radlog(L_ERR|L_CONS, "no memory");
194 * Add it, even if it's already present.
200 * Perform the realm module instantiation. Configuration info is
201 * stored in *instance for later use.
204 static int realm_instantiate(CONF_SECTION *conf, void **instance)
206 struct realm_config_t *inst;
208 /* setup a storage area for instance data */
209 inst = malloc(sizeof(struct realm_config_t));
211 radlog(L_ERR|L_CONS, "Out of memory\n");
215 if(cf_section_parse(conf, module_config) < 0) {
220 /* copy the configuration info into the instance data */
222 if(strcasecmp(config.formatstring, "suffix") == 0) {
223 inst->format = REALM_FORMAT_SUFFIX;
224 } else if(strcasecmp(config.formatstring, "prefix") == 0) {
225 inst->format = REALM_FORMAT_PREFIX;
227 radlog(L_ERR, "Bad value \"%s\" for realm format value", config.formatstring);
231 if(strlen(config.delim) != 1) {
232 radlog(L_ERR, "Bad value \"%s\" for realm delimiter value", config.delim);
236 inst->delim = config.delim;
238 /* set these to NULL to prevent other instances from reusing the data */
240 config.formatstring = NULL;
253 * Examine a request for a username with an realm, and if it
254 * corresponds to something in the realms file, set that realm as
257 * This should very nearly duplicate the old proxy_send() code
259 static int realm_authorize(void *instance, REQUEST *request)
264 * Check if we've got to proxy the request.
265 * If not, return without adding a Proxy-To-Realm
268 realm = check_for_realm(instance, request);
270 return RLM_MODULE_OK;
274 * Maybe add a Proxy-To-Realm attribute to the request.
276 add_proxy_to_realm(&request->config_items, realm);
278 return RLM_MODULE_UPDATED; /* try the next module */
282 * This does the exact same thing as the realm_authorize, it's just called
285 static int realm_preacct(void *instance, REQUEST *request)
287 const char *name = (char *)request->username->strvalue;
291 return RLM_MODULE_OK;
295 * Check if we've got to proxy the request.
296 * If not, return without adding a Proxy-To-Realm
299 realm = check_for_realm(instance, request);
301 return RLM_MODULE_OK;
306 * Maybe add a Proxy-To-Realm attribute to the request.
308 add_proxy_to_realm(&request->config_items, realm);
310 return RLM_MODULE_OK; /* try the next module */
313 /* globally exported name */
314 module_t rlm_realm = {
316 0, /* type: reserved */
317 NULL, /* initialization */
318 realm_instantiate, /* instantiation */
319 realm_authorize, /* authorization */
320 NULL, /* authentication */
321 realm_preacct, /* preaccounting */
322 NULL, /* accounting */
323 NULL, /* checksimul */