ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid/src/conf/access.c
Revision: 768
Committed: Mon Aug 21 16:59:42 2006 UTC (19 years, 11 months ago) by adx
Content type: text/x-csrc
File size: 9248 byte(s)
Log Message:
+ added a missing callback initialization

File Contents

# User Rev Content
1 adx 724 /*
2     * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd).
3     * access.c: Common code for user@host access control blocks.
4     *
5     * Copyright (C) 2006 by the Hybrid Development Team.
6     *
7     * This program is free software; you can redistribute it and/or modify
8     * it under the terms of the GNU General Public License as published by
9     * the Free Software Foundation; either version 2 of the License, or
10     * (at your option) any later version.
11     *
12     * This program is distributed in the hope that it will be useful,
13     * but WITHOUT ANY WARRANTY; without even the implied warranty of
14     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15     * GNU General Public License for more details.
16     *
17     * You should have received a copy of the GNU General Public License
18     * along with this program; if not, write to the Free Software
19     * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
20     * USA
21     *
22     * $Id$
23     */
24    
25     #include "stdinc.h"
26     #include "conf/conf.h"
27 adx 730 #include "client.h"
28     #include "send.h"
29 adx 724
30 adx 744 struct Callback *is_client_banned = NULL;
31 adx 724 struct AccessConf *atable[ATABLE_SIZE] = {0};
32 adx 743 struct Callback *expire_confs = NULL;
33 adx 730 uint64_t curprec = ~0;
34 adx 724
35     static dlink_node *hreset;
36 adx 730 static struct
37     {
38     const char *name;
39     ACB_FREE_HANDLER *free;
40     } acb_types[MAX_ACB_TYPES] = {{0}};
41 adx 724
42     /*
43     * hash_hostmask()
44     *
45     * Calculates the hash value for a given hostmask.
46     *
47     * inputs:
48     * p - the hostname to hash
49     * addr - where to store mask info
50     * output: hash value
51     */
52     static unsigned int
53     hash_hostmask(const char *p, struct irc_ssaddr *addr)
54     {
55     int bits;
56     unsigned int hv;
57     const char *seg;
58    
59 adx 762 if (parse_netmask(p, addr, &bits) != HM_HOST)
60     hv = hash_ip(addr, bits - bits % 8, ATABLE_SIZE);
61     else
62 adx 724 {
63 adx 762 //
64     // Choose the longest domain substring which contains no wildcards.
65     // This way hash value will be as precise as possible.
66     //
67     for (seg = p; *p; p++)
68     if (*p == '.' && !seg)
69     seg = p + 1;
70     else if (IsMWildChar(*p))
71     seg = NULL;
72 adx 724
73 adx 762 hv = seg ? hash_text(seg, ATABLE_SIZE) : 0;
74 adx 724 }
75    
76     addr->ss_port = (in_port_t) bits;
77     return hv;
78     }
79    
80     /*
81     * add_access_conf()
82     *
83     * Adds an AccessConf entry to the hash table.
84     *
85     * inputs: pointer to AccessConf struct
86     * output: none
87     */
88     void
89     add_access_conf(struct AccessConf *conf)
90     {
91     unsigned int hv = hash_hostmask(conf->host, &conf->ip);
92    
93     conf->precedence = curprec--;
94     conf->hnext = atable[hv];
95     atable[hv] = conf;
96     }
97    
98     /*
99     * destroy_access_conf()
100     *
101     * Deletes an AccessConf entry from the hash table and frees its memory.
102     *
103     * inputs: pointer to AccessConf struct
104     * output: none
105     */
106     void
107     destroy_access_conf(struct AccessConf *conf)
108     {
109     struct irc_ssaddr addr;
110     unsigned int hv = hash_hostmask(conf->host, &addr);
111     struct AccessConf *prev;
112    
113     if (conf == atable[hv])
114     atable[hv] = conf->hnext;
115     else
116     {
117     for (prev = atable[hv]; prev->hnext != conf; prev = prev->hnext)
118 adx 730 assert(prev->type >= 0); // let it core if not found
119 adx 724 prev->hnext = conf->hnext;
120     }
121    
122 adx 730 acb_types[conf->type].free(conf);
123 adx 724 }
124    
125     /*
126     * acb_generic_free()
127     *
128     * Generic free procedure for ACB's.
129     *
130     * inputs: pointer to AccessConf struct
131     * output: none
132     */
133     void
134     acb_generic_free(struct AccessConf *conf)
135     {
136     MyFree(conf->user);
137     MyFree(conf->host);
138     MyFree(conf);
139     }
140    
141     /*
142 adx 729 * enum_access_confs()
143 adx 724 *
144     * Enumerates all AccessConfs. Calls the supplied routine on each one,
145     * if 1 is returned then this one is deleted and freed.
146     * Any number of AccessConfs can be deleted by this function.
147     *
148     * inputs: pointer to checking routine
149     * output: none
150     */
151     void
152 adx 729 enum_access_confs(ACB_EXAMINE_HANDLER *examine, void *param)
153 adx 724 {
154     unsigned int hv;
155     struct AccessConf *prev, *conf;
156    
157     for (hv = 0; hv < ATABLE_SIZE; hv++)
158     for (prev = NULL, conf = atable[hv]; conf != NULL;
159     conf = (prev ? prev->hnext : atable[hv]))
160     {
161 adx 730 assert(conf->type >= 0);
162 adx 729 if (examine(conf, param))
163 adx 724 {
164     if (prev != NULL)
165     prev->hnext = conf->hnext;
166     else
167     atable[hv] = conf->hnext;
168    
169 adx 730 acb_types[conf->type].free(conf);
170 adx 724 }
171     else
172     prev = conf;
173     }
174     }
175    
176 adx 729 static int is_acb_permanent(struct AccessConf *conf, void *unused)
177 adx 724 {
178     return !conf->expires;
179     }
180    
181 adx 729 static int is_acb_expired(struct AccessConf *conf, void *unused)
182 adx 724 {
183 adx 730 if (conf->expires && conf->expires <= CurrentTime)
184     {
185     sendto_realops_flags(UMODE_ALL, L_ALL,
186     "Temporary %s for [%s@%s] expired",
187     acb_types[conf->type].name, conf->user, conf->host);
188     return YES;
189     }
190    
191     return NO;
192 adx 724 }
193    
194 adx 729 static int is_acb_orphaned(struct AccessConf *conf, void *unused)
195 adx 724 {
196 adx 730 return !acb_types[conf->type].name;
197 adx 724 }
198    
199     /*
200     * register_acb_type()
201     *
202     * Allocates a unique value for AccessConf.type field to be used by modules.
203     *
204     * inputs: pointer to routine which frees a conf entry of this type
205     * output: requested value
206     */
207     int
208 adx 730 register_acb_type(const char *name, void *fh)
209 adx 724 {
210     int i;
211    
212 adx 730 assert(name != NULL);
213     assert(fh != NULL);
214    
215 adx 724 for (i = 0; i < MAX_ACB_TYPES; i++)
216 adx 730 if (acb_types[i].name == NULL)
217 adx 724 {
218 adx 730 acb_types[i].name = name;
219     acb_types[i].free = (ACB_FREE_HANDLER *) fh;
220 adx 724 return i;
221     }
222    
223     return -1;
224     }
225    
226     /*
227     * unregister_acb_type()
228     *
229     * Deallocates an AccessConf.type specifier.
230     *
231     * inputs: type value
232     * output: none
233     */
234     void
235     unregister_acb_type(int id)
236     {
237 adx 730 acb_types[id].name = NULL;
238     acb_types[id].free = NULL;
239 adx 729 enum_access_confs(is_acb_orphaned, NULL);
240 adx 724 }
241    
242     /*
243     * reset_access()
244     *
245     * Deletes all non-expiring ACB's before a rehash.
246     *
247     * inputs: none
248     * output: none
249     */
250     static void *
251     reset_access(va_list args)
252     {
253 adx 729 enum_access_confs(is_acb_permanent, NULL);
254 adx 724 return pass_callback(hreset);
255     }
256    
257     /*
258 adx 728 * find_access_conf()
259     *
260     * Looks for an access conf matching given criteria.
261     *
262     * inputs:
263     * type - only check confs of this type
264     * user - if non-NULL, limit to confs matching given username
265     * host - limit to confs matching given hostname...
266     * ip - ...or IP address (either host or ip must be non-NULL)
267     * func - function which verifies additional criteria, can be NULL
268     * output: pointer to struct AccessConf or NULL if not found
269     */
270     struct AccessConf *
271     find_access_conf(int type, const char *user, const char *host,
272 adx 729 const struct irc_ssaddr *ip, ACB_EXAMINE_HANDLER *func,
273     void *param)
274 adx 728 {
275     struct AccessConf *conf, *best = NULL;
276     int bits;
277    
278     if (ip != NULL)
279     if (ip->ss.sin_family == AF_INET)
280     for (bits = 32; bits >= 0; bits -= 8)
281 adx 762 for (conf = atable[hash_ip(ip, bits, ATABLE_SIZE)]; conf;
282     conf = conf->hnext)
283 adx 728 if ((best == NULL || conf->precedence > best->precedence) &&
284 adx 749 conf->type == type && conf->ip.ss.sin_family == AF_INET &&
285     match_ipv4(ip, &conf->ip, conf->ip.ss_port) &&
286     (EmptyString(user) || match(conf->user, user)) &&
287 adx 729 (!func || func(conf, param)))
288 adx 728 best = conf;
289     #ifdef IPV6
290     else if (ip->ss.sin_family == AF_INET6)
291     for (bits = 128; bits >= 0; bits -= 16)
292 adx 762 for (conf = atable[hash_ip(ip, bits, ATABLE_SIZE)]; conf;
293     conf = conf->hnext)
294 adx 728 if ((best == NULL || conf->precedence > best->precedence) &&
295 adx 749 conf->type == type && conf->ip.ss.sin_family == AF_INET6 &&
296     match_ipv6(ip, &conf->ip, conf->ip.ss_port) &&
297     (EmptyString(user) || match(conf->user, user)) &&
298 adx 729 (!func || func(conf, param)))
299 adx 728 best = conf;
300     #endif
301    
302     if (host != NULL)
303     while (1)
304     {
305 adx 734 for (conf = atable[hash_text(host, ATABLE_SIZE)]; conf; conf = conf->hnext)
306 adx 728 if ((best == NULL || conf->precedence > best->precedence) &&
307     conf->type == type && match(conf->host, host) &&
308     (EmptyString(user) || match(conf->user, user)) &&
309 adx 729 (!func || func(conf, param)))
310 adx 728 best = conf;
311    
312     if (*host)
313     do {
314     if (*host++ == '.')
315     break;
316     }
317     while (*host);
318     else
319     break;
320     }
321    
322     return best;
323     }
324    
325 adx 749 struct AccessConf *
326     find_exact_access_conf(int type, const char *user, const char *host)
327     {
328     /* kludge, irc_ssaddr contains bytes which we not always use
329     * (for example they might be reserved for IPv6); here we assume
330     * they are zeros, and they actually are zeroed by MyMalloc()
331     * before calling add_access_conf. --adx
332     */
333     struct irc_ssaddr ip = {{{0}}};
334     struct AccessConf *conf;
335    
336     for (conf = atable[hash_hostmask(host, &ip)]; conf; conf = conf->hnext)
337     if (conf->ip.ss.sin_family == ip.ss.sin_family &&
338     !(ip.ss.sin_family == AF_UNSPEC ? irccmp(conf->host, host) :
339     memcmp(&conf->ip, &ip, sizeof(ip))))
340     return conf;
341    
342     return NULL;
343     }
344    
345 adx 728 /*
346 adx 724 * expire_confs()
347     *
348     * Called periodically to remove expired conf entries.
349     *
350     * inputs: none
351     * output: none
352     */
353     static void
354 adx 743 do_expire_confs(void *unused)
355 adx 724 {
356 adx 729 enum_access_confs(is_acb_expired, NULL);
357 adx 743 execute_callback(expire_confs);
358 adx 724 }
359    
360     /*
361     * init_access()
362     *
363     * Initializes ACB's support.
364     *
365     * inputs: none
366     * output: none
367     */
368     void
369     init_access(void)
370     {
371 adx 768 is_client_banned = register_callback("is_client_banned", NULL);
372    
373 adx 724 hreset = install_hook(reset_conf, reset_access);
374    
375 adx 743 expire_confs = register_callback("expire_confs", NULL);
376     eventAddIsh("expire_confs", do_expire_confs, NULL, EXPIRE_FREQUENCY);
377 adx 724 }

Properties

Name Value
svn:eol-style native
svn:keywords "Id Revision"