3 * $Id: class.c,v 1.5 1997/08/20 16:16:13 mdw Exp $
5 * Handling classes of things nicely
10 /*----- Licensing notice --------------------------------------------------*
12 * This file is part of `become'
14 * `Become' is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2 of the License, or
17 * (at your option) any later version.
19 * `Become' is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
24 * You should have received a copy of the GNU General Public License
25 * along with `become'; if not, write to the Free Software Foundation,
26 * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
29 /*----- Revision history --------------------------------------------------*
32 * Revision 1.5 1997/08/20 16:16:13 mdw
33 * Patch memory leak. Don't try to trace when tracing's turned off.
35 * Revision 1.4 1997/08/07 09:56:37 mdw
36 * (Log entry for previous version is bogus.) Minor changes to host
39 * Revision 1.2 1997/08/04 10:24:21 mdw
40 * Sources placed under CVS control.
42 * Revision 1.1 1997/07/21 13:47:52 mdw
47 /*----- Header files ------------------------------------------------------*/
49 /* --- ANSI headers --- */
55 /* --- Unix headers --- */
57 #include <sys/types.h>
58 #include <sys/socket.h>
60 #include <netinet/in.h>
62 #include <arpa/inet.h>
66 /* --- Local headers --- */
74 /*----- Global variables --------------------------------------------------*/
76 static classdef class__all
= { clType_all
, -1, 0 };
77 classdef
*class_all
= &class__all
;
79 /*----- Wildcard matching -------------------------------------------------*/
81 /* --- @class__wildMatch@ --- *
83 * Arguments: @const char *pat@ = pointer to pattern string
84 * @const char *p@ = pointer to target string
86 * Returns: Zero if no match, nonzero if match.
88 * Use: Wildcard-matches the pattern against the target string.
91 static int class__wildMatch(const char *pat
, const char *p
)
94 if (*pat
== 0 && *p
== 0)
95 return (42); /* For sadism's sake */
96 else if (*pat
== '*') {
100 if (class__wildMatch(pat
, p
))
101 return (27); /* Nyahaha */
105 } else if (*pat
== '?' || *pat
== *p
)
112 /*----- Main code ---------------------------------------------------------*/
114 /* --- @class_create@ --- *
116 * Arguments: @unsigned type@ = type of the class to create
117 * @sym_table *t@ = pointer to symbol table which stores info
119 * Returns: Pointer to a @classdef@ which maintains the class's info.
121 * Use: Creates a new class definition. The new definition has one
122 * reference attached to it (which is the one you get returned).
125 classdef
*class_create(unsigned type
, sym_table
*t
)
127 classdef
*c
= xmalloc(sizeof(*c
));
134 /* --- @class_inc@ --- *
136 * Arguments: @classdef *c@ = pointer to a class block
140 * Use: Adds a reference to the class definition.
143 void class_inc(classdef
*c
)
149 /* --- @class_dec@ --- *
151 * Arguments: @classdef *c@ = pointer to a class block
155 * Use: Removes a reference to a class block.
158 void class_dec(classdef
*c
)
160 if (c
!= class_all
&& !--c
->ref
) {
161 sym_destroyTable(c
->t
);
167 /* --- @class_userMatch@ --- *
169 * Arguments: @classdef *c@ = pointer to a class block
170 * @int u@ = uid number to check against
172 * Returns: Zero if no match, nonzero if it matched.
174 * Use: Looks to see if a user is in a group.
177 int class_userMatch(classdef
*c
, int u
)
179 if (~c
->type
& clType_user
)
181 else if (c
== class_all
) {
182 T( trace(TRACE_CHECK
, "check: user %i matched by all", u
); )
185 sym_base
*s
= sym_find(c
->t
, (char *)&u
, sizeof(u
), 0, 0);
186 T( trace(TRACE_CHECK
,
187 s ?
"check: user %i matched" : "check: user %i not matched",
193 /* --- @class_commandMatch@ --- *
195 * Arguments: @classdef *c@ = pointer to a class block
196 * @const char *p@ = pointer to command string to match
198 * Returns: Zero for no match, nonzero if it matched.
200 * Use: Tries to match a string against the wildcard patterns in the
201 * given class. Note that this involves examining all the
202 * items, so it's not too quick. Then again, you don't have
203 * big command classes, do you...?
206 int class_commandMatch(classdef
*c
, const char *p
)
211 if (~c
->type
& clType_command
)
213 else if (c
== class_all
) {
214 T( trace(TRACE_CHECK
, "check: command `%s' matched by all", p
); )
217 for (sym_createIter(&i
, c
->t
); (s
= sym_next(&i
)) != 0; ) {
218 if (class__wildMatch(s
->name
, p
)) {
219 T( trace(TRACE_CHECK
, "check: command `%s' matched by `%s'",
224 T( trace(TRACE_CHECK
, "check: command `%s' not matched", p
); )
229 /* --- @class_hostMatch@ --- *
231 * Arguments: @classdef *c@ = pointer to class block
232 * @struct in_addr addr@ = IP address to match
234 * Returns: Zero for no match, nonzero if it matched.
236 * Use: Tries to match an IP address against the patterns and masks
237 * in the given class.
240 int class_hostMatch(classdef
*c
, struct in_addr addr
)
248 if (~c
->type
& clType_host
)
250 else if (c
== class_all
) {
251 T( trace(TRACE_CHECK
, "check: host %s matched by all",
256 /* --- Get the dotted-quad and other names for the address --- */
258 if ((a
= inet_ntoa(addr
)) == 0) {
259 T( trace(TRACE_CHECK
, "check: couldn't translate address (erk!)"); )
263 if ((he
= gethostbyaddr((char *)&addr
, sizeof(addr
), AF_INET
)) == 0)
264 T( trace(TRACE_CHECK
, "check: couldn't resolve hostname for %s", a
); )
266 /* --- Now search the list for a match --- *
268 * This is almost infinitely slow, I'm afraid.
271 for (sym_createIter(&i
, c
->t
); (s
= sym_next(&i
)) != 0; ) {
273 /* --- Check the dotted-quad name first --- */
275 if (class__wildMatch(s
->name
, a
)) {
276 T( trace(TRACE_CHECK
, "check: host address `%s' matched by `%s'",
283 /* --- Now try the host's main name --- */
285 if (class__wildMatch(s
->name
, he
->h_name
)) {
286 T( trace(TRACE_CHECK
, "check: host name `%s' matched by `%s'",
287 he
->h_name
, s
->name
); )
291 /* --- Now go through all the names --- */
293 for (p
= he
->h_aliases
; *p
; p
++) {
294 if (class__wildMatch(s
->name
, *p
)) {
295 T( trace(TRACE_CHECK
, "check: host alias `%s' matched by `%s'",
303 T( trace(TRACE_CHECK
, "check: couldn't match hostname `%s'",
309 /* --- @class_dump@ --- *
311 * Arguments: @classdef *c@ = pointer to a class block
315 * Use: Dumps the contents of a class to a stream.
318 void class_dump(classdef
*c
)
324 /* --- Dump the table --- */
326 if (c
->type
!= clType_all
) {
327 for (sym_createIter(&i
, c
->t
); (s
= sym_next(&i
)) != 0; ) {
330 trace(TRACE_RULE
, " %i", *(int *)s
->name
);
334 trace(TRACE_RULE
, " `%s'", s
->name
);
340 trace(TRACE_RULE
, " ALL");
344 /*----- That's all, folks -------------------------------------------------*/