chiark / gitweb /
Added. No idea why this wasn't done before.
[become] / src / name.c
1 /* -*-c-*-
2  *
3  * $Id: name.c,v 1.2 1997/08/04 10:24:24 mdw Exp $
4  *
5  * Looking up of names in symbol tables
6  *
7  * (c) 1997 EBI
8  */
9
10 /*----- Licensing notice --------------------------------------------------*
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
25  * along with `become'; if not, write to the Free Software Foundation,
26  * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
27  */
28
29 /*----- Revision history --------------------------------------------------*
30  *
31  * $Log: name.c,v $
32  * Revision 1.2  1997/08/04 10:24:24  mdw
33  * Sources placed under CVS control.
34  *
35  * Revision 1.1  1997/07/21  13:47:46  mdw
36  * Initial revision
37  *
38  */
39
40 /*----- Header files ------------------------------------------------------*/
41
42 /* --- ANSI headers --- */
43
44 #include <stdio.h>
45 #include <stdlib.h>
46 #include <string.h>
47
48 /* --- Unix headers --- */
49
50 #include "config.h"
51
52 #ifdef HAVE_YP
53 #  include <rpcsvc/ypclnt.h>
54 #  include <rpcsvc/yp_prot.h>
55 #endif
56
57 #include <grp.h>
58 #include <pwd.h>
59
60 /* --- Local headers --- */
61
62 #include "become.h"
63 #include "class.h"
64 #include "name.h"
65 #include "sym.h"
66 #include "userdb.h"
67 #include "utils.h"
68
69 /*----- Static variables --------------------------------------------------*/
70
71 static sym_table name__table;           /* Symbol table for everything */
72
73 /*----- Main code ---------------------------------------------------------*/
74
75 /* --- @name__users@ --- *
76  *
77  * Arguments:   ---
78  *
79  * Returns:     ---
80  *
81  * Use:         Adds all of the users registered with the user database to
82  *              the name table.  Also adds the users' primary groups.
83  */
84
85 static void name__users(void)
86 {
87   struct passwd *pw;
88   struct group *gr;
89
90   userdb_iterateUsers();
91   while ((pw = userdb_nextUser()) != 0) {
92     unsigned f;
93     name *n;
94     int u;
95
96     /* --- First, add the user to the table --- */
97
98     n = sym_find(&name__table, pw->pw_name, -1, sizeof(name), &f);
99     if (!f) {
100       sym_table *t = xmalloc(sizeof(*t));
101       sym_createTable(t);
102       n->c = class_create(clType_user, t);
103     }
104     u = pw->pw_uid;
105     sym_find(n->c->t, (char *)&u, sizeof(u), sizeof(sym_base), 0);
106
107     /* --- Now handle the user's default group --- */
108
109     if ((gr = userdb_groupById(pw->pw_gid)) != 0) {
110       n = sym_find(&name__table, gr->gr_name, -1, sizeof(name), &f);
111       if (!f) {
112         sym_table *t = xmalloc(sizeof(*t));
113         sym_createTable(t);
114         n->c = class_create(clType_user, t);
115       }
116       sym_find(n->c->t, (char *)&u, sizeof(u), sizeof(sym_base), 0);
117     }
118   }
119 }
120
121 /* --- @name__groups@ --- *
122  *
123  * Arguments:   ---
124  *
125  * Returns:     ---
126  *
127  * Use:         Adds users into all of their supplementary groups.
128  */
129
130 static void name__groups(void)
131 {
132   struct group *gr;
133   struct passwd *pw;
134   char **p;
135
136   userdb_iterateGroups();
137   while ((gr = userdb_nextGroup()) != 0) {
138     unsigned f;
139     name *n;
140     int u;
141
142     /* --- Add the group name to the table --- */
143
144     n = sym_find(&name__table, gr->gr_name, -1, sizeof(name), &f);
145     if (!f) {
146       sym_table *t = xmalloc(sizeof(*t));
147       sym_createTable(t);
148       n->c = class_create(clType_user, t);
149     }
150
151     /* --- Now add all of the members --- */
152
153     for (p = gr->gr_mem; *p; p++) {
154       if ((pw = userdb_userByName(*p)) != 0) {
155         u = pw->pw_uid;
156         sym_find(n->c->t, (char *)&u, sizeof(u), sizeof(sym_base), 0);
157       }
158     }
159   }
160 }
161
162 /* --- @name_init@ --- *
163  *
164  * Arguments:   ---
165  *
166  * Returns:     ---
167  *
168  * Use:         Initialises the name table.  Requires the user database to
169  *              be populated (see @userdb_local@ and @userdb_yp@).
170  */
171
172 void name_init(void)
173 {
174   /* --- Initialise the name table --- */
175
176   sym_createTable(&name__table);
177
178   /* --- Add everyone into the table --- */
179
180   name__users();
181   name__groups();
182
183   /* --- Finally add in the `all' class --- *
184    *
185    * Do that now, to prevent it being overwritten by the above.
186    */
187
188   {
189     name *n;
190     unsigned f;
191
192     n = sym_find(&name__table, "all", -1, sizeof(name), &f);
193     if (f)
194       class_dec(n->c);
195     n->c = class_all;
196   }
197 }
198
199 /* --- @name_reinit@ --- *
200  *
201  * Arguments:   ---
202  *
203  * Returns:     ---
204  *
205  * Use:         Reinitialises the names table.  It's cleared and then
206  *              initialised with the current user and group ids as for
207  *              @name_init@ above.
208  */
209
210 void name_reinit(void)
211 {
212   /* --- Empty the symbol table --- */
213
214   {
215     sym_iter i;
216     name *n;
217
218     for (sym_createIter(&i, &name__table); (n = sym_next(&i)) != 0; ) {
219       if (n->c)
220         class_dec(n->c);
221     }
222   }
223
224   /* --- Destroy and recreate the table --- */
225
226   sym_destroyTable(&name__table);
227   name_init();
228 }
229
230 /* --- @name_find@ --- *
231  *
232  * Arguments:   @const char *p@ = pointer to name to look up
233  *              @unsigned create@ = whether to create the item
234  *              @unsigned *f@ = whether the item was created
235  *
236  * Returns:     Pointer to a @name@ block containing the symbol, or
237  *              zero if it wasn't found and we didn't want to create a
238  *              new one.
239  *
240  * Use:         Looks up a name in the symbol table and returns the
241  *              item so located.
242  */
243
244 name *name_find(const char *p, unsigned create, unsigned *f)
245 {
246   /* --- This is a trivial veneer onto @sym_find@ --- */
247
248   return (sym_find(&name__table, p, -1, create ? sizeof(name) : 0, f));
249 }
250
251 /* --- @name_dump@ --- *
252  *
253  * Arguments:   ---
254  *
255  * Returns:     ---
256  *
257  * Use:         Dumps a complete listing of the symbol table.
258  */
259
260 void name_dump(void)
261 {
262   sym_iter i;
263   name *n;
264
265   trace(TRACE_DEBUG, "name: dumping names");
266   for (sym_createIter(&i, &name__table); (n = sym_next(&i)) != 0; ) {
267     trace(TRACE_DEBUG, "name: dumping `%s'", n->base.name);
268     class_dump(n->c);
269   }
270 }  
271
272 /*----- Test driver -------------------------------------------------------*/
273
274 #ifdef TEST_RIG
275
276 int main(void)
277 {
278   userdb_init();
279   userdb_local();
280   userdb_yp();
281   ego("name-test");
282   traceon(stdout, TRACE_DEBUG);
283   name_init();
284   name_dump();
285   return (0);
286 }
287
288 #endif