2 * paircmp.c Valuepair functions for various attributes
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 Alan DeKok <aland@ox.org>
24 #include <freeradius-devel/ident.h>
27 #include <freeradius-devel/radiusd.h>
30 * Compare a Connect-Info and a Connect-Rate
32 static int connectcmp(void *instance,
36 VALUE_PAIR *check_pairs,
37 VALUE_PAIR **reply_pairs)
42 check_pairs = check_pairs; /* shut the compiler up */
43 reply_pairs = reply_pairs;
45 rate = atoi((char *)request->vp_strvalue);
46 return rate - check->vp_integer;
51 * Compare a portno with a range.
53 static int portcmp(void *instance,
54 REQUEST *req UNUSED, VALUE_PAIR *request, VALUE_PAIR *check,
55 VALUE_PAIR *check_pairs, VALUE_PAIR **reply_pairs)
57 char buf[MAX_STRING_LEN];
60 uint32_t port = request->vp_integer;
63 check_pairs = check_pairs; /* shut the compiler up */
64 reply_pairs = reply_pairs;
66 if ((strchr((char *)check->vp_strvalue, ',') == NULL) &&
67 (strchr((char *)check->vp_strvalue, '-') == NULL)) {
68 return (request->vp_integer - check->vp_integer);
72 strcpy(buf, (char *)check->vp_strvalue);
76 if ((p = strchr(s, '-')) != NULL)
80 lo = strtoul(s, NULL, 10);
81 hi = strtoul(p, NULL, 10);
82 if (lo <= port && port <= hi) {
85 s = strtok(NULL, ",");
92 * Compare prefix/suffix.
95 * - if PW_STRIP_USER_NAME is present in check_pairs,
96 * strip the username of prefix/suffix.
97 * - if PW_STRIP_USER_NAME is not present in check_pairs,
98 * add a PW_STRIPPED_USER_NAME to the request.
100 static int presufcmp(void *instance,
102 VALUE_PAIR *request, VALUE_PAIR *check,
103 VALUE_PAIR *check_pairs, VALUE_PAIR **reply_pairs)
106 char *name = (char *)request->vp_strvalue;
107 char rest[MAX_STRING_LEN];
112 reply_pairs = reply_pairs; /* shut the compiler up */
115 printf("Comparing %s and %s, check->attr is %d\n",
116 name, check->vp_strvalue, check->attribute);
119 len = strlen((char *)check->vp_strvalue);
120 switch (check->attribute) {
122 ret = strncmp(name, (char *)check->vp_strvalue, len);
123 if (ret == 0 && rest)
124 strcpy(rest, name + len);
127 namelen = strlen(name);
130 ret = strcmp(name + namelen - len,
131 (char *)check->vp_strvalue);
132 if (ret == 0 && rest) {
133 strlcpy(rest, name, namelen - len + 1);
141 * If Strip-User-Name == No, then don't do any more.
143 vp = pairfind(check_pairs, PW_STRIP_USER_NAME);
144 if (vp && !vp->vp_integer) return ret;
147 * See where to put the stripped user name.
149 vp = pairfind(check_pairs, PW_STRIPPED_USER_NAME);
152 * If "request" is NULL, then the memory will be
155 vp = radius_paircreate(req, &request,
156 PW_STRIPPED_USER_NAME, PW_TYPE_STRING);
159 strlcpy((char *)vp->vp_strvalue, rest, sizeof(vp->vp_strvalue));
160 vp->length = strlen(vp->vp_strvalue);
167 * Compare the request packet type.
169 static int packetcmp(void *instance UNUSED, REQUEST *req,
170 VALUE_PAIR *request UNUSED,
172 VALUE_PAIR *check_pairs UNUSED,
173 VALUE_PAIR **reply_pairs UNUSED)
175 if (req->packet->code == check->vp_integer) {
183 * Compare the response packet type.
185 static int responsecmp(void *instance UNUSED,
187 VALUE_PAIR *request UNUSED,
189 VALUE_PAIR *check_pairs UNUSED,
190 VALUE_PAIR **reply_pairs UNUSED)
192 if (req->reply->code == check->vp_integer) {
200 * Generic comparisons, via xlat.
202 static int genericcmp(void *instance UNUSED,
204 VALUE_PAIR *request UNUSED,
206 VALUE_PAIR *check_pairs UNUSED,
207 VALUE_PAIR **reply_pairs UNUSED)
209 if ((check->operator != T_OP_REG_EQ) &&
210 (check->operator != T_OP_REG_EQ)) {
216 snprintf(name, sizeof(name), "%%{%s}", check->name);
218 rcode = radius_xlat(value, sizeof(value), name, req, NULL);
219 vp = pairmake(check->name, value, T_OP_EQ);
221 rcode = radius_compare_vps(req, check, vp);
228 * Will do the xlat for us
230 return radius_compare_vps(req, check, NULL);
233 static int generic_attrs[] = {
234 PW_CLIENT_IP_ADDRESS,
235 PW_PACKET_SRC_IP_ADDRESS,
236 PW_PACKET_DST_IP_ADDRESS,
239 PW_REQUEST_PROCESSING_STAGE,
240 PW_PACKET_SRC_IPV6_ADDRESS,
241 PW_PACKET_DST_IPV6_ADDRESS,
247 * Register server-builtin special attributes.
249 void pair_builtincompare_init(void)
253 paircompare_register(PW_NAS_PORT, PW_NAS_PORT, portcmp, NULL);
254 paircompare_register(PW_PREFIX, PW_USER_NAME, presufcmp, NULL);
255 paircompare_register(PW_SUFFIX, PW_USER_NAME, presufcmp, NULL);
256 paircompare_register(PW_CONNECT_RATE, PW_CONNECT_INFO, connectcmp, NULL);
257 paircompare_register(PW_PACKET_TYPE, 0, packetcmp, NULL);
258 paircompare_register(PW_RESPONSE_PACKET_TYPE, 0, responsecmp, NULL);
260 for (i = 0; generic_attrs[i] != 0; i++) {
261 paircompare_register(generic_attrs[i], -1, genericcmp, NULL);
265 void pair_builtincompare_detach(void)
269 paircompare_unregister(PW_NAS_PORT, portcmp);
270 paircompare_unregister(PW_PREFIX, presufcmp);
271 paircompare_unregister(PW_SUFFIX, presufcmp);
272 paircompare_unregister(PW_CONNECT_RATE, connectcmp);
273 paircompare_unregister(PW_PACKET_TYPE, packetcmp);
274 paircompare_unregister(PW_RESPONSE_PACKET_TYPE, responsecmp);
276 for (i = 0; generic_attrs[i] != 0; i++) {
277 paircompare_unregister(generic_attrs[i], genericcmp);