6cb771045b4f50f69e513c17303dcc85b974394f
[freeradius.git] / src / modules / rlm_dynamic_clients / rlm_dynamic_clients.c
1 /*
2  * rlm_dynamic_clients.c
3  *
4  * Version:     $Id$
5  *
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.
10  *
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.
15  *
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
19  *
20  * Copyright 2008  The FreeRADIUS server project
21  * Copyright 2008  Alan DeKok <aland@deployingradius.com>
22  */
23
24 #include <freeradius-devel/ident.h>
25 RCSID("$Id$")
26
27 #include <freeradius-devel/radiusd.h>
28 #include <freeradius-devel/modules.h>
29
30 /*
31  *      Find the client definition.
32  */
33 static int dynamic_client_authorize(UNUSED void *instance, REQUEST *request)
34 {
35         size_t length;
36         const char *value;
37         CONF_PAIR *cp;
38         RADCLIENT *c;
39         char buffer[2048];
40
41         /*
42          *      Ensure we're only being called from the main thread,
43          *      with fake packets.
44          */
45         if ((request->packet->src_port != 0) || (request->packet->vps != NULL) ||
46             (request->parent != NULL)) {
47                 RDEBUG("Improper configuration");
48                 return RLM_MODULE_NOOP;
49         }
50
51         if (!request->client || !request->client->cs) {
52                 RDEBUG("Unknown client definition");
53                 return RLM_MODULE_NOOP;
54         }
55
56         cp = cf_pair_find(request->client->cs, "directory");
57         if (!cp) {
58                 RDEBUG("No directory configuration in the client");
59                 return RLM_MODULE_NOOP;
60         }
61
62         value = cf_pair_value(cp);
63         if (!value) {
64                 RDEBUG("No value given for the directory entry in the client.");
65                 return RLM_MODULE_NOOP;
66         }
67
68         length = strlen(value);
69         if (length > (sizeof(buffer) - 256)) {
70                 RDEBUG("Directory name too long");
71                 return RLM_MODULE_NOOP;
72         }
73
74         memcpy(buffer, value, length + 1);
75         ip_ntoh(&request->packet->src_ipaddr,
76                 buffer + length, sizeof(buffer) - length - 1);
77
78         /*
79          *      Read the buffer and generate the client.
80          */
81         c = client_read(buffer, (request->client->server != NULL), TRUE);
82         if (!c) return RLM_MODULE_FAIL;
83
84         /*
85          *      Replace the client.  This is more than a bit of a
86          *      hack.
87          */
88         request->client = c;
89
90         return RLM_MODULE_OK;
91 }
92
93 /*
94  *      The module name should be the only globally exported symbol.
95  *      That is, everything else should be 'static'.
96  *
97  *      If the module needs to temporarily modify it's instantiation
98  *      data, the type should be changed to RLM_TYPE_THREAD_UNSAFE.
99  *      The server will then take care of ensuring that the module
100  *      is single-threaded.
101  */
102 module_t rlm_dynamic_client = {
103         RLM_MODULE_INIT,
104         "example",
105         RLM_TYPE_THREAD_SAFE,           /* type */
106         NULL,                           /* instantiation */
107         NULL,                           /* detach */
108         {
109                 NULL,                   /* authentication */
110                 dynamic_client_authorize,       /* authorization */
111                 NULL,                   /* preaccounting */
112                 NULL,                   /* accounting */
113                 NULL,                   /* checksimul */
114                 NULL,                   /* pre-proxy */
115                 NULL,                   /* post-proxy */
116                 NULL                    /* post-auth */
117         },
118 };