Switch to using the ypstuff interface to YP server.
[become] / src / userdb.c
CommitLineData
c4f2d992 1/* -*-c-*-
2 *
a340752b 3 * $Id: userdb.c,v 1.7 1998/04/23 13:27:46 mdw Exp $
c4f2d992 4 *
5 * User database management
6 *
c758e654 7 * (c) 1998 EBI
c4f2d992 8 */
9
03f996bd 10/*----- Licensing notice --------------------------------------------------*
c4f2d992 11 *
12 * This file is part of `become'
13 *
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.
18 *
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.
23 *
24 * You should have received a copy of the GNU General Public License
03f996bd 25 * along with `become'; if not, write to the Free Software Foundation,
26 * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
c4f2d992 27 */
28
29/*----- Revision history --------------------------------------------------*
30 *
31 * $Log: userdb.c,v $
a340752b 32 * Revision 1.7 1998/04/23 13:27:46 mdw
33 * Switch to using the ypstuff interface to YP server.
34 *
c758e654 35 * Revision 1.6 1998/01/12 16:46:33 mdw
36 * Fix copyright date.
37 *
38 * Revision 1.5 1997/09/17 10:24:08 mdw
d8cd61fe 39 * Use `uid_t' instead of `int' for uids and gids. Not quite sure why I
40 * didn't do this before.
41 *
42 * Revision 1.4 1997/08/20 16:24:58 mdw
46cc26eb 43 * Patch memory leak. Rename `userdb_reinit' to `userdb_end' for more
44 * sensible restart.
45 *
e893b83f 46 * Revision 1.3 1997/08/07 09:44:29 mdw
47 * Read NIS-based passwords from the YP server directly, rather than using
48 * `popen(ypcat)', which is probably both slower and less secure.
49 *
03f996bd 50 * Revision 1.2 1997/08/04 10:24:26 mdw
51 * Sources placed under CVS control.
52 *
53 * Revision 1.1 1997/07/21 13:47:43 mdw
c4f2d992 54 * Initial revision
55 *
56 */
57
58/*----- Header files ------------------------------------------------------*/
59
60/* --- ANSI headers --- */
61
62#include <ctype.h>
63#include <errno.h>
64#include <stdio.h>
65#include <stdlib.h>
66#include <string.h>
67
68/* --- Unix headers --- */
69
03f996bd 70#include "config.h"
71
c4f2d992 72#include <sys/types.h>
73
74#include <grp.h>
75#include <pwd.h>
76#include <unistd.h>
77
78/* --- Local headers --- */
79
e893b83f 80#include "become.h"
c4f2d992 81#include "sym.h"
82#include "userdb.h"
83#include "utils.h"
a340752b 84#include "ypstuff.h"
c4f2d992 85
86/*----- Type definitions --------------------------------------------------*/
87
88/* --- A map link --- */
89
90typedef struct userdb__node {
91 struct userdb__node *next;
92 void *rec;
93} userdb__node;
94
95/* --- A reference to a real record --- */
96
97typedef struct userdb__sym {
98 sym_base _base;
99 void *rec;
100} userdb__sym;
101
102/* --- A name- and number-mapping --- */
103
104typedef struct userdb__map {
105 sym_table nmap;
106 sym_table idmap;
107 userdb__node *list;
108} userdb__map;
109
110/*----- Static variables --------------------------------------------------*/
111
112static userdb__map userdb__users; /* Map of user info blocks */
113static sym_iter userdb__useri; /* Iterator for users */
114static userdb__map userdb__groups; /* Map of group info blocks */
115static sym_iter userdb__groupi; /* Iterator for groups */
116
117/*----- Map management functions ------------------------------------------*/
118
119/* --- @userdb__createMap@ --- *
120 *
121 * Arguments: @userdb__map *m@ = pointer to a map block
122 *
123 * Returns: ---
124 *
125 * Use: Initialises a map table.
126 */
127
128static void userdb__createMap(userdb__map *m)
129{
130 sym_createTable(&m->nmap);
131 sym_createTable(&m->idmap);
132 m->list = 0;
133}
134
135/* --- @userdb__addToMap@ --- *
136 *
137 * Arguments: @userdb__map *m@ = pointer to the map block
138 * @const char *name@ = pointer to the item's name
d8cd61fe 139 * @uid_t id@ = the item's id number
c4f2d992 140 * @void *rec@ = pointer to the actual record
141 *
142 * Returns: ---
143 *
144 * Use: Adds an item to the given map.
145 */
146
147static void userdb__addToMap(userdb__map *m,
148 const char *name,
d8cd61fe 149 uid_t id, void *rec)
c4f2d992 150{
151 unsigned f;
152 userdb__sym *s;
153 userdb__node *n;
154
155 s = sym_find(&m->nmap, name, -1, sizeof(*s), &f);
156 if (!f)
157 s->rec = rec;
158
159 s = sym_find(&m->idmap, (char *)&id, sizeof(id), sizeof(*s), &f);
160 if (!f)
161 s->rec = rec;
162
163 n = xmalloc(sizeof(*n));
164 n->rec = rec;
165 n->next = m->list;
166 m->list = n;
167}
168
169/* --- @userdb__byName@ --- *
170 *
171 * Arguments: @userdb__map *m@ = pointer to a map block
172 * @const char *name@ = name to look up
173 *
174 * Returns: A pointer to the appropriate block, or zero if not found.
175 *
176 * Use: Looks up a name in a mapping and returns the result.
177 */
178
179static void *userdb__byName(userdb__map *m, const char *name)
180{
181 userdb__sym *s = sym_find(&m->nmap, name, -1, 0, 0);
182 return (s ? s->rec : 0);
183}
184
185/* --- @userdb__byId@ --- *
186 *
187 * Arguments: @userdb__map *m@ = pointer to a map block
d8cd61fe 188 * @uid_t id@ = id number to find
c4f2d992 189 *
190 * Returns: A pointer to the appropriate block, or zero if not found.
191 *
192 * Use: Looks up an ID in a mapping, and returns the result.
193 */
194
d8cd61fe 195static void *userdb__byId(userdb__map *m, uid_t id)
c4f2d992 196{
197 userdb__sym *s = sym_find(&m->idmap, (char *)&id, sizeof(id), 0, 0);
198 return (s ? s->rec : 0);
199}
200
201/* --- @userdb__clearMap@ --- *
202 *
203 * Arguments: @userdb__map *m@ = pointer to a map block
204 * @void (*freerec)(void *rec)@ = pointer to a free-record proc
205 *
206 * Returns: ---
207 *
208 * Use: Clears a map, emptying it and releasing the memory it
209 * occupied.
210 */
211
212static void userdb__clearMap(userdb__map *m, void (*freerec)(void *rec))
213{
214 userdb__node *n, *t;
215
216 sym_destroyTable(&m->nmap);
217 sym_destroyTable(&m->idmap);
218
219 for (n = m->list; n; n = t) {
220 t = n->next;
221 freerec(n->rec);
222 free(n);
223 }
224}
225
226/*----- User and group block management -----------------------------------*/
227
228/* --- @userdb__dumpUser@ --- *
229 *
230 * Arguments: @const struct passwd *pw@ = pointer to a user block
c4f2d992 231 *
232 * Returns: ---
233 *
234 * Use: Writes a user's informationt to a stream.
235 */
236
e893b83f 237#ifdef TRACING
c4f2d992 238
e893b83f 239static void userdb__dumpUser(const struct passwd *pw)
c4f2d992 240{
e893b83f 241 trace(TRACE_DEBUG,
242 "debug: name `%s' passwd `%s' uid %i gid %i",
243 pw->pw_name, pw->pw_passwd, (int)pw->pw_uid, (int)pw->pw_gid);
244 trace(TRACE_DEBUG,
245 "debug: ... gecos `%s' home `%s' shell `%s'",
246 pw->pw_gecos, pw->pw_dir, pw->pw_shell);
c4f2d992 247}
248
c4f2d992 249#endif
250
251/* --- @userdb_copyUser@ --- *
252 *
253 * Arguments: @struct passwd *pw@ = pointer to block to copy
254 *
255 * Returns: Pointer to the copy.
256 *
257 * Use: Copies a user block. The copy is `deep' so all the strings
258 * are copied too. Free the copy with @userdb_freeUser@ when
259 * you don't want it any more.
260 */
261
262struct passwd *userdb_copyUser(struct passwd *pw)
263{
264 struct passwd *npw;
265
266 if (!pw)
267 return (0);
268
269 npw = xmalloc(sizeof(*npw));
270
271 npw->pw_name = xstrdup(pw->pw_name);
272 npw->pw_passwd = xstrdup(pw->pw_passwd);
273 npw->pw_uid = pw->pw_uid;
274 npw->pw_gid = pw->pw_gid;
275 npw->pw_gecos = xstrdup(pw->pw_gecos);
276 npw->pw_dir = xstrdup(pw->pw_dir);
277 npw->pw_shell = xstrdup(pw->pw_shell);
278
279 return (npw);
280}
281
282/* --- @userdb__buildUser@ --- *
283 *
284 * Arguments: @char *s@ = pointer to user string
285 *
286 * Returns: Pointer to a user block.
287 *
288 * Use: Converts a line from a user file into a password entry.
289 * Note that the string is corrupted by @strtok@ while it gets
290 * parsed.
291 */
292
293static struct passwd *userdb__buildUser(char *s)
294{
295 struct passwd *pw = xmalloc(sizeof(*pw));
296
297 s = strtok(s, ":"); if (!s) goto tidy_0; pw->pw_name = xstrdup(s);
298 s = strtok(0, ":"); if (!s) goto tidy_1; pw->pw_passwd = xstrdup(s);
d8cd61fe 299 s = strtok(0, ":"); if (!s) goto tidy_2; pw->pw_uid = (uid_t)atol(s);
300 s = strtok(0, ":"); if (!s) goto tidy_2; pw->pw_gid = (gid_t)atol(s);
c4f2d992 301 s = strtok(0, ":"); if (!s) goto tidy_2; pw->pw_gecos = xstrdup(s);
302 s = strtok(0, ":"); if (!s) goto tidy_3; pw->pw_dir = xstrdup(s);
303 s = strtok(0, ":"); if (!s) goto tidy_4; pw->pw_shell = xstrdup(s);
304 return (pw);
305
306 /* --- Error handling --- */
307
308tidy_4:
309 free(pw->pw_dir);
310tidy_3:
311 free(pw->pw_gecos);
312tidy_2:
313 free(pw->pw_passwd);
314tidy_1:
315 free(pw->pw_name);
316tidy_0:
317 free(pw);
318
319 return (0);
320}
321
322/* --- @userdb_freeUser@ --- *
323 *
324 * Arguments: @void *rec@ = pointer to a user record
325 *
326 * Returns: ---
327 *
328 * Use: Frees a user record.
329 */
330
331void userdb_freeUser(void *rec)
332{
333 struct passwd *pw;
334
335 if (!rec)
336 return;
337
338 pw = rec;
339 free(pw->pw_name);
340 free(pw->pw_passwd);
341 free(pw->pw_gecos);
342 free(pw->pw_dir);
343 free(pw->pw_shell);
344 free(pw);
345}
346
347/* --- @userdb__dumpGroup@ --- *
348 *
349 * Arguments: @const struct group *gr@ = pointer to a group block
350 * @FILE *fp@ = pointer to stream to write on
351 *
352 * Returns: ---
353 *
354 * Use: Writes a group's information to a stream.
355 */
356
e893b83f 357#ifdef TRACING
c4f2d992 358
e893b83f 359static void userdb__dumpGroup(const struct group *gr)
c4f2d992 360{
361 char *const *p;
362
e893b83f 363 trace(TRACE_DEBUG,
364 "debug: name `%s' passwd `%s' gid %i",
c4f2d992 365 gr->gr_name, gr->gr_passwd, (int)gr->gr_gid);
366 for (p = gr->gr_mem; *p; p++)
e893b83f 367 trace(TRACE_DEBUG,"debug: ... `%s'", *p);
c4f2d992 368}
369
c4f2d992 370#endif
371
372/* --- @userdb_copyGroup@ --- *
373 *
374 * Arguments: @struct group *gr@ = pointer to group block
375 *
376 * Returns: Pointer to copied block
377 *
378 * Use: Copies a group block. The copy is `deep' so all the strings
379 * are copied too. Free the copy with @userdb_freeGroup@ when
380 * you don't want it any more.
381 */
382
383struct group *userdb_copyGroup(struct group *gr)
384{
385 struct group *ngr;
386 int i, max;
387
388 if (!gr)
389 return (0);
390
391 ngr = xmalloc(sizeof(*ngr));
392
393 ngr->gr_name = xstrdup(gr->gr_name);
394 ngr->gr_passwd = xstrdup(gr->gr_passwd);
395 ngr->gr_gid = gr->gr_gid;
396
397 for (max = 0; gr->gr_mem[max]; max++)
398 ;
399 ngr->gr_mem = xmalloc((max + 1) * sizeof(char *));
400 for (i = 0; i < max; i++)
401 ngr->gr_mem[i] = xstrdup(gr->gr_mem[i]);
402 ngr->gr_mem[max] = 0;
403
404 return (ngr);
405}
406
407/* --- @userdb__buildGroup@ --- *
408 *
409 * Arguments: @char *s@ = pointer to group line string
410 *
411 * Returns: Pointer to a group block
412 *
413 * Use: Parses an entry in the groups file. The string is garbled
414 * by @strtok@ as we go.
415 */
416
417static struct group *userdb__buildGroup(char *s)
418{
419 struct group *gr = xmalloc(sizeof(*gr));
420 char *p;
421 int i;
422
423 /* --- Do the easy bits --- */
424
425 s = strtok(s, ":"); if (!s) goto tidy_0; gr->gr_name = xstrdup(s);
426 s = strtok(0, ":"); if (!s) goto tidy_1; gr->gr_passwd = xstrdup(s);
d8cd61fe 427 s = strtok(0, ":"); if (!s) goto tidy_2; gr->gr_gid = (gid_t)atol(s);
c4f2d992 428
429 /* --- Find the start of the member list --- */
430
431 s = strtok(0, "");
432 if (!s)
433 goto tidy_2;
434
435 /* --- Count the number of members --- */
436
437 p = s;
438 i = 0;
439 for (;;) {
440 i++;
441 if ((p = strpbrk(p, ",")) == 0)
442 break;
443 p++;
444 }
445
446 /* --- Allocate the block and fill it --- */
447
448 gr->gr_mem = xmalloc((i + 1) * sizeof(char *));
449 i = 0;
450 s = strtok(s, ",");
451 do {
452 gr->gr_mem[i++] = xstrdup(s);
453 s = strtok(0, ",");
454 } while (s);
455 gr->gr_mem[i] = 0;
456
457 return (gr);
458
459 /* --- Various tidying-up things --- */
460
461tidy_2:
462 free(gr->gr_passwd);
463tidy_1:
464 free(gr->gr_name);
465tidy_0:
466 free(gr);
467
468 return (0);
469}
470
471/* --- @userdb_freeGroup@ --- *
472 *
473 * Arguments: @void *rec@ = pointer to a group record
474 *
475 * Returns: ---
476 *
477 * Use: Frees a group record.
478 */
479
480void userdb_freeGroup(void *rec)
481{
482 struct group *gr;
483 char **p;
484
485 if (!rec)
486 return;
487
488 gr = rec;
489 free(gr->gr_name);
490 free(gr->gr_passwd);
491 for (p = gr->gr_mem; *p; p++)
492 free(*p);
493 free(gr->gr_mem);
494 free(gr);
495}
496
03f996bd 497/*----- Answering queries -------------------------------------------------*/
c4f2d992 498
499/* --- @userdb_userByName@, @userdb_userById@ --- *
500 *
501 * Arguments: @const char *name@ = pointer to user's name
502 * @uid_t id@ = user id to find
503 *
504 * Returns: Pointer to user block, or zero if not found.
505 *
506 * Use: Looks up a user by name or id.
507 */
508
509struct passwd *userdb_userByName(const char *name)
510{ return (userdb__byName(&userdb__users, name)); }
511
512struct passwd *userdb_userById(uid_t id)
513{ return (userdb__byId(&userdb__users, id)); }
514
515/* --- @userdb_iterateUsers@, @userdb_iterateUsers_r@ --- *
516 *
517 * Arguments: @userdb_iter *i@ = pointer to a symbol table iterator object
518 *
519 * Returns: ---
520 *
521 * Use: Initialises an iteration for the user database.
522 */
523
524void userdb_iterateUsers(void)
525{ userdb_iterateUsers_r(&userdb__useri); }
526
527void userdb_iterateUsers_r(userdb_iter *i)
528{ sym_createIter(i, &userdb__users.nmap); }
529
530/* --- @userdb_nextUser@, @userdb_nextUser_r@ --- *
531 *
532 * Arguments: @userdb_iter *i@ = pointer to a symbol table iterator oject
533 *
534 * Returns: Pointer to the next user block, or null.
535 *
536 * Use: Returns another user block.
537 */
538
539struct passwd *userdb_nextUser(void)
540{ return (userdb_nextUser_r(&userdb__useri)); }
541
542struct passwd *userdb_nextUser_r(userdb_iter *i)
543{
544 userdb__sym *s = sym_next(i);
545 return (s ? s->rec : 0);
546}
547
548/* --- @userdb_groupByName@, @userdb_groupById@ --- *
549 *
550 * Arguments: @const char *name@ = pointer to group's name
551 * @gid_t id@ = group id to find
552 *
553 * Returns: Pointer to group block, or zero if not found.
554 *
555 * Use: Looks up a group by name or id.
556 */
557
558struct group *userdb_groupByName(const char *name)
559{ return (userdb__byName(&userdb__groups, name)); }
560
561struct group *userdb_groupById(gid_t id)
562{ return (userdb__byId(&userdb__groups, id)); }
563
564/* --- @userdb_iterateGroups@, @userdb_iterateGroups_r@ --- *
565 *
566 * Arguments: @userdb_iter *i@ = pointer to a symbol table iterator object
567 *
568 * Returns: ---
569 *
570 * Use: Initialises an iteration for the group database.
571 */
572
573void userdb_iterateGroups(void)
574{ userdb_iterateGroups_r(&userdb__groupi); }
575
576void userdb_iterateGroups_r(userdb_iter *i)
577{ sym_createIter(i, &userdb__groups.nmap); }
578
579/* --- @userdb_nextGroup@, @userdb_nextGroup_r@ --- *
580 *
581 * Arguments: @userdb_iter *i@ = pointer to a symbol table iterator oject
582 *
583 * Returns: Pointer to the next group block, or null.
584 *
585 * Use: Returns another group block.
586 */
587
588struct group *userdb_nextGroup(void)
589{ return (userdb_nextGroup_r(&userdb__groupi)); }
590
591struct group *userdb_nextGroup_r(userdb_iter *i)
592{
593 userdb__sym *s = sym_next(i);
594 return (s ? s->rec : 0);
595}
596
03f996bd 597/*----- Yellow pages support ----------------------------------------------*/
598
599#ifdef HAVE_YP
600
601/* --- @userdb__foreachUser@ --- *
602 *
603 * Arguments: @int st@ = YP protocol-level status code
604 * @char *k@ = address of the key for this record
605 * @int ksz@ = size of the key
606 * @char *v@ = address of the value for this record
607 * @int vsz@ = size of the value
608 * @char *data@ = pointer to some data passed to me
609 *
610 * Returns: Zero to be called again, nonzero to end the enumeration.
611 *
612 * Use: Handles an incoming user record.
613 */
614
615static int userdb__foreachUser(int st, char *k, int ksz,
616 char *v, int vsz, char *data)
617{
618 char *cv;
619 struct passwd *pw;
620
621 if (st != YP_TRUE)
622 return (-1);
623 cv = xmalloc(vsz + 1);
624 memcpy(cv, v, vsz);
625 cv[vsz] = 0;
e893b83f 626 T( trace(TRACE_DEBUG, "debug: nis string: `%s'", cv); )
03f996bd 627 pw = userdb__buildUser(cv);
e893b83f 628 if (pw && !userdb__byName(&userdb__users, pw->pw_name)) {
629 IF_TRACING(TRACE_DEBUG, userdb__dumpUser(pw); )
03f996bd 630 userdb__addToMap(&userdb__users, pw->pw_name, pw->pw_uid, pw);
46cc26eb 631 } else
632 userdb_freeUser(pw);
03f996bd 633 free(cv);
634 return (0);
635}
636
637/* --- @userdb__foreachGroup@ --- *
638 *
639 * Arguments: @int st@ = YP protocol-level status code
640 * @char *k@ = address of the key for this record
641 * @int ksz@ = size of the key
642 * @char *v@ = address of the value for this record
643 * @int vsz@ = size of the value
644 * @char *data@ = pointer to some data passed to me
645 *
646 * Returns: Zero to be called again, nonzero to end the enumeration.
647 *
648 * Use: Handles an incoming user record.
649 */
650
651static int userdb__foreachGroup(int st, char *k, int ksz,
652 char *v, int vsz, char *data)
653{
654 char *cv;
655 struct group *gr;
656
657 if (st != YP_TRUE)
658 return (-1);
659 cv = xmalloc(vsz + 1);
660 memcpy(cv, v, vsz);
661 cv[vsz] = 0;
e893b83f 662 T( trace(TRACE_DEBUG, "debug: nis string: `%s'", cv); )
03f996bd 663 gr = userdb__buildGroup(cv);
e893b83f 664 if (gr && !userdb__byName(&userdb__groups, gr->gr_name)) {
665 IF_TRACING(TRACE_DEBUG, userdb__dumpGroup(gr); )
03f996bd 666 userdb__addToMap(&userdb__groups, gr->gr_name, gr->gr_gid, gr);
46cc26eb 667 } else
668 userdb_freeGroup(gr);
03f996bd 669 free(cv);
670 return (0);
671}
672
673/* --- @userdb_yp@ --- *
674 *
675 * Arguments: ---
676 *
677 * Returns: ---
678 *
679 * Use: Fetches the YP database of users.
680 */
681
682void userdb_yp(void)
683{
03f996bd 684 /* --- Bind to a server --- */
685
a340752b 686 ypstuff_bind();
687 if (!yp_domain)
03f996bd 688 return;
689
e893b83f 690 T( trace(TRACE_DEBUG, "debug: adding NIS users"); )
691
03f996bd 692 /* --- Fetch the users map --- */
693
694 {
695 static struct ypall_callback ucb = { userdb__foreachUser, 0 };
a340752b 696 yp_all(yp_domain, "passwd.byuid", &ucb);
03f996bd 697 }
698
699 /* --- Fetch the groups map --- */
700
701 {
702 static struct ypall_callback gcb = { userdb__foreachGroup, 0 };
a340752b 703 yp_all(yp_domain, "group.bygid", &gcb);
03f996bd 704 }
03f996bd 705}
706
707#else
708
709void userdb_yp(void) { ; }
710
711#endif
712
713/*----- Building the databases --------------------------------------------*/
714
715/* --- @userdb_local@ --- *
716 *
717 * Arguments: ---
718 *
719 * Returns: ---
720 *
721 * Use: Reads the local list of users into the maps.
722 */
723
724void userdb_local(void)
725{
e893b83f 726 T( trace(TRACE_DEBUG, "debug: adding local users"); )
03f996bd 727
728 /* --- Fetch users first --- */
729
730 {
731 struct passwd *pw;
732
733 setpwent();
734 while ((pw = getpwent()) != 0) {
e893b83f 735 IF_TRACING(TRACE_DEBUG, userdb__dumpUser(pw); )
03f996bd 736 if (!userdb__byName(&userdb__users, pw->pw_name))
737 userdb__addToMap(&userdb__users, pw->pw_name, pw->pw_uid,
738 userdb_copyUser(pw));
739 }
740 endpwent();
741 }
742
743 /* --- Then fetch groups --- */
744
745 {
746 struct group *gr;
747
748 setgrent();
749 while ((gr = getgrent()) != 0) {
e893b83f 750 IF_TRACING(TRACE_DEBUG, userdb__dumpGroup(gr); )
03f996bd 751 if (!userdb__byName(&userdb__groups, gr->gr_name))
752 userdb__addToMap(&userdb__groups, gr->gr_name, gr->gr_gid,
753 userdb_copyGroup(gr));
754 }
755 endgrent();
756 }
757}
758
c4f2d992 759/* --- @userdb_init@ --- *
760 *
761 * Arguments: ---
762 *
763 * Returns: ---
764 *
765 * Use: Initialises the user database.
766 */
767
768void userdb_init(void)
769{
770 userdb__createMap(&userdb__users);
771 userdb__createMap(&userdb__groups);
772}
773
46cc26eb 774/* --- @userdb_end@ --- *
c4f2d992 775 *
776 * Arguments: ---
777 *
778 * Returns: ---
779 *
46cc26eb 780 * Use: Closes down the user database.
c4f2d992 781 */
782
46cc26eb 783void userdb_end(void)
c4f2d992 784{
785 userdb__clearMap(&userdb__users, userdb_freeUser);
786 userdb__clearMap(&userdb__groups, userdb_freeGroup);
c4f2d992 787}
788
789/*----- Test rig ----------------------------------------------------------*/
790
791#ifdef TEST_RIG
792
793void dumpit(const char *msg)
794{
e893b83f 795 trace(TRACE_DEBUG, "debug: %s", msg);
c4f2d992 796
797 {
798 struct passwd *pw;
799 for (userdb_iterateUsers(); (pw = userdb_nextUser()) != 0; )
e893b83f 800 userdb__dumpUser(pw);
c4f2d992 801 }
802
803 {
804 struct group *gr;
805 for (userdb_iterateGroups(); (gr = userdb_nextGroup()) != 0; )
e893b83f 806 userdb__dumpGroup(gr);
c4f2d992 807 }
808}
809
810int main(void)
811{
e893b83f 812 ego("userdb-test");
a340752b 813 traceon(stdout, TRACE_ALL);
c4f2d992 814 userdb_init();
e893b83f 815 userdb_local();
46cc26eb 816 userdb_yp();
a340752b 817 dumpit("spong");
818/* printf("loaded (%lu)\n", track_memused()); */
46cc26eb 819 getchar();
820 for (;;) {
821 userdb_end();
a340752b 822/* printf("cleared (%lu)\n", track_memused()); */
46cc26eb 823/* track_memlist(); */
824 userdb_init();
825 userdb_local();
826 userdb_yp();
a340752b 827/* printf("reloaded (%lu)\n", track_memused()); */
46cc26eb 828 getchar();
829 }
c4f2d992 830 return (0);
831}
832
833#endif
834
835/*----- That's all, folks -------------------------------------------------*/