cc9d98f2150325882772bc8ea2def49964471cc4
3 * $Id: name.c,v 1.9 2003/10/12 00:39:16 mdw Exp $
5 * Looking up of names in symbol tables
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.9 2003/10/12 00:39:16 mdw
33 * Light fixes for strange building.
35 * Revision 1.8 2003/10/12 00:14:55 mdw
36 * Major overhaul. Now uses DSA signatures rather than the bogus symmetric
37 * encrypt-and-hope thing. Integrated with mLib and Catacomb.
39 * Revision 1.7 1998/04/23 13:23:56 mdw
40 * Fix bugs involving empty classes.
42 * Revision 1.6 1998/01/12 16:46:14 mdw
45 * Revision 1.5 1997/09/17 10:26:11 mdw
46 * Use rewritten class handler. Support `none' class.
48 * Revision 1.4 1997/08/20 16:17:59 mdw
49 * Replace `name_reinit' by `name_end' for more sensible restart.
51 * Revision 1.3 1997/08/07 09:49:39 mdw
52 * Extensive modifications to handle netgroups. Also sanitise user and group
53 * names before adding them to the symbol table.
55 * Revision 1.2 1997/08/04 10:24:24 mdw
56 * Sources placed under CVS control.
58 * Revision 1.1 1997/07/21 13:47:46 mdw
63 /*----- Header files ------------------------------------------------------*/
65 /* --- ANSI headers --- */
72 /* --- Unix headers --- */
74 #include <sys/types.h>
75 #include <sys/socket.h>
77 #include <netinet/in.h>
79 #include <arpa/inet.h>
85 /* --- mLib headers --- */
87 #include <mLib/alloc.h>
90 /* --- Local headers --- */
100 /*----- Static variables --------------------------------------------------*/
102 static sym_table name__table
; /* Symbol table for everything */
104 /*----- Main code ---------------------------------------------------------*/
106 /* --- @name__get@ --- *
108 * Arguments: @const char *p@ = pointer to the name we want
109 * @unsigned type@ = type of class it should have
111 * Returns: A pointer to a name ready to use, or zero if there's a type
114 * Use: Creates a name of the appropriate type all ready to use.
117 static name
*name__get(const char *p
, unsigned type
)
120 name
*n
= sym_find(&name__table
, p
, -1, sizeof(*n
), &f
);
123 return ((n
->c
&& !(n
->c
->type
& type
)) ?
0 : n
);
126 /* --- @name__sanitise@ --- *
128 * Arguments: @const char *n@ = pointer to a name
129 * @char *buf@ = pointer to a buffer of space
130 * @size_t sz@ = size of the buffer
132 * Returns: A pointer to the transformed name in the buffer, or null
133 * if there wasn't enough space.
135 * Use: Transforms a name so that it only contains nice characters.
138 static char *name__sanitise(const char *n
, char *buf
, size_t sz
)
142 if (strlen(n
) + 1 > sz
)
146 if (isalnum((unsigned char)*n
))
156 /* --- @name__users@ --- *
162 * Use: Adds all of the users registered with the user database to
163 * the name table. Also adds the users' primary groups.
166 static void name__users(void)
172 userdb_iterateUsers();
173 while ((pw
= userdb_nextUser()) != 0) {
175 uid_t u
= pw
->pw_uid
;
177 /* --- First, add the user to the table --- */
179 if (name__sanitise(pw
->pw_name
, buf
, sizeof(buf
)) &&
180 (n
= name__get(buf
, clType_user
)) != 0)
181 n
->c
= class_addUser(n
->c
, u
);
183 /* --- Now handle the user's default group --- */
185 if ((gr
= userdb_groupById(pw
->pw_gid
)) != 0 &&
186 name__sanitise(gr
->gr_name
, buf
, sizeof(buf
)) &&
187 (n
= name__get(buf
, clType_user
)) != 0)
188 n
->c
= class_addUser(n
->c
, u
);
192 /* --- @name__groups@ --- *
198 * Use: Adds users into all of their supplementary groups.
201 static void name__groups(void)
208 userdb_iterateGroups();
209 while ((gr
= userdb_nextGroup()) != 0) {
212 if (name__sanitise(gr
->gr_name
, buf
, sizeof(buf
)) &&
213 (n
= name__get(buf
, clType_user
)) != 0) {
215 /* --- Now add all of the members --- */
217 for (p
= gr
->gr_mem
; *p
; p
++) {
218 if ((pw
= userdb_userByName(*p
)) != 0)
219 n
->c
= class_addUser(n
->c
, pw
->pw_uid
);
227 /* --- @name__scan@ --- *
229 * Arguments: @netg *n@ = the netgroup handle we're scanning
230 * @const char *host@ = the host name
231 * @const char *user@ = the user name
232 * @const char *domain@ = the (NIS?) domain name
233 * @void *ctx@ = some context pointer
235 * Returns: Zero to continue scanning.
237 * Use: Scans a netgroup, adding items to the name table.
240 /* --- A data type --- */
242 typedef struct name__scanctx
{
243 char *name
; /* Netgroup name prefixed with `?_'*/
244 unsigned f
; /* Various interesting flags */
245 name
*h
; /* Name entry for hosts */
246 name
*u
; /* Name entry for users */
249 enum { f_host
= 1, f_user
= 2 };
251 /* --- And now for the real code --- */
253 static int name__scan(netg
*n
, const char *host
, const char *user
,
254 const char *domain
, void *ctx
)
256 name__scanctx
*sc
= ctx
;
258 /* --- Add the host to the hosts class --- */
260 if (sc
->f
& f_host
&& host
) {
265 /* --- First ensure that I have a host class --- */
269 sc
->h
= name__get(sc
->name
, clType_host
);
276 /* --- Now that I've done that, try to add the host --- *
278 * I'll turn it into an IP address. There's less chance of confusion
282 if ((h
= gethostbyname(host
)) == 0)
284 memcpy(&in
, h
->h_addr
, sizeof(in
));
285 if ((a
= inet_ntoa(in
)) == 0)
287 sc
->h
->c
= class_addString(sc
->h
->c
, a
);
291 /* --- Add the user to the users class --- */
293 if (sc
->f
& f_user
&& user
) {
296 /* --- First ensure that I have a user class --- */
300 sc
->u
= name__get(sc
->name
, clType_user
);
307 /* --- Add the user to the list --- */
309 if ((pw
= userdb_userByName(user
)) == 0)
311 sc
->u
->c
= class_addUser(sc
->u
->c
, pw
->pw_uid
);
318 /* --- @name__netgroups@ --- *
324 * Use: Populates the name table with netgroup information.
327 void name__netgroups(void)
336 while ((n
= netg_next()) != 0) {
338 if (name__sanitise(p
, buf
+ 2, sizeof(buf
) - 2) == 0)
342 sc
.f
= f_host
| f_user
;
343 netg_scan(n
, name__scan
, &sc
);
347 /* --- @name_init@ --- *
353 * Use: Initialises the name table. Requires the user database to
354 * be populated (see @userdb_local@ and @userdb_yp@, and
360 /* --- Initialise the name table --- */
362 sym_create(&name__table
);
364 /* --- Add everyone into the table --- */
370 /* --- Finally add in the `all' and `none' classes --- *
372 * Do that now, to prevent them being overwritten by the above.
379 n
= sym_find(&name__table
, "all", -1, sizeof(name
), &f
);
384 n
= sym_find(&name__table
, "none", -1, sizeof(name
), &f
);
391 /* --- @name_end@ --- *
397 * Use: Closes down the name database, so that it can be
403 /* --- Empty the symbol table --- */
409 for (sym_mkiter(&i
, &name__table
); (n
= sym_next(&i
)) != 0; ) {
415 /* --- Destroy and recreate the table --- */
417 sym_destroy(&name__table
);
420 /* --- @name_find@ --- *
422 * Arguments: @const char *p@ = pointer to name to look up
423 * @unsigned create@ = whether to create the item
424 * @unsigned *f@ = whether the item was created
426 * Returns: Pointer to a @name@ block containing the symbol, or
427 * zero if it wasn't found and we didn't want to create a
430 * Use: Looks up a name in the symbol table and returns the
434 name
*name_find(const char *p
, unsigned create
, unsigned *f
)
436 /* --- This is a trivial veneer onto @sym_find@ --- */
438 return (sym_find(&name__table
, p
, -1, create ?
sizeof(name
) : 0, f
));
441 /* --- @name_dump@ --- *
447 * Use: Dumps a complete listing of the symbol table.
456 trace(TRACE_DEBUG
, "name: dumping names");
457 for (sym_mkiter(&i
, &name__table
); (n
= sym_next(&i
)) != 0; ) {
458 trace(TRACE_DEBUG
, "name: dumping `%s'", n
->base
.name
);
460 trace(TRACE_DEBUG
, "name: <empty>");
467 /*----- Test driver -------------------------------------------------------*/
474 trace_on(stdout
, TRACE_ALL
);
480 /* printf("loaded (%lu)\n", track_memused()); */
487 /* printf("cleared (%lu)\n", track_memused()); */
488 /* track_memlist(); */
494 /* printf("reloaded (%lu)\n", track_memused()); */