pwcache.c revision 1.10 1 1.10 mycroft /* $NetBSD: pwcache.c,v 1.10 1998/07/28 16:58:36 mycroft Exp $ */
2 1.4 cgd
3 1.10 mycroft /*-
4 1.10 mycroft * Copyright (c) 1992 Keith Muller.
5 1.10 mycroft * Copyright (c) 1992, 1993
6 1.4 cgd * The Regents of the University of California. All rights reserved.
7 1.1 cgd *
8 1.10 mycroft * This code is derived from software contributed to Berkeley by
9 1.10 mycroft * Keith Muller of the University of California, San Diego.
10 1.10 mycroft *
11 1.1 cgd * Redistribution and use in source and binary forms, with or without
12 1.1 cgd * modification, are permitted provided that the following conditions
13 1.1 cgd * are met:
14 1.1 cgd * 1. Redistributions of source code must retain the above copyright
15 1.1 cgd * notice, this list of conditions and the following disclaimer.
16 1.1 cgd * 2. Redistributions in binary form must reproduce the above copyright
17 1.1 cgd * notice, this list of conditions and the following disclaimer in the
18 1.1 cgd * documentation and/or other materials provided with the distribution.
19 1.1 cgd * 3. All advertising materials mentioning features or use of this software
20 1.1 cgd * must display the following acknowledgement:
21 1.1 cgd * This product includes software developed by the University of
22 1.1 cgd * California, Berkeley and its contributors.
23 1.1 cgd * 4. Neither the name of the University nor the names of its contributors
24 1.1 cgd * may be used to endorse or promote products derived from this software
25 1.1 cgd * without specific prior written permission.
26 1.1 cgd *
27 1.1 cgd * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
28 1.1 cgd * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
29 1.1 cgd * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
30 1.1 cgd * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
31 1.1 cgd * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
32 1.1 cgd * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
33 1.1 cgd * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
34 1.1 cgd * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
35 1.1 cgd * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
36 1.1 cgd * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
37 1.1 cgd * SUCH DAMAGE.
38 1.1 cgd */
39 1.1 cgd
40 1.7 christos #include <sys/cdefs.h>
41 1.10 mycroft #ifndef lint
42 1.4 cgd #if 0
43 1.10 mycroft static char sccsid[] = "@(#)cache.c 8.1 (Berkeley) 5/31/93";
44 1.4 cgd #else
45 1.10 mycroft __RCSID("$NetBSD: pwcache.c,v 1.10 1998/07/28 16:58:36 mycroft Exp $");
46 1.4 cgd #endif
47 1.10 mycroft #endif /* not lint */
48 1.1 cgd
49 1.8 jtc #include "namespace.h"
50 1.10 mycroft
51 1.1 cgd #include <sys/types.h>
52 1.6 sommerfe #include <sys/param.h>
53 1.4 cgd
54 1.4 cgd #include <grp.h>
55 1.1 cgd #include <pwd.h>
56 1.1 cgd #include <stdio.h>
57 1.10 mycroft #include <stdlib.h>
58 1.5 jtc #include <string.h>
59 1.10 mycroft #include <unistd.h>
60 1.10 mycroft
61 1.10 mycroft #include "pwcache.h"
62 1.8 jtc
63 1.8 jtc #ifdef __weak_alias
64 1.8 jtc __weak_alias(user_from_uid,_user_from_uid);
65 1.8 jtc __weak_alias(group_from_gid,_group_from_gid);
66 1.8 jtc #endif
67 1.1 cgd
68 1.10 mycroft /*
69 1.10 mycroft * routines that control user, group, uid and gid caches (for the archive
70 1.10 mycroft * member print routine).
71 1.10 mycroft * IMPORTANT:
72 1.10 mycroft * these routines cache BOTH hits and misses, a major performance improvement
73 1.10 mycroft */
74 1.10 mycroft
75 1.10 mycroft static int pwopn = 0; /* is password file open */
76 1.10 mycroft static int gropn = 0; /* is group file open */
77 1.10 mycroft static UIDC **uidtb = NULL; /* uid to name cache */
78 1.10 mycroft static GIDC **gidtb = NULL; /* gid to name cache */
79 1.10 mycroft static UIDC **usrtb = NULL; /* user name to uid cache */
80 1.10 mycroft static GIDC **grptb = NULL; /* group name to gid cache */
81 1.10 mycroft
82 1.10 mycroft static u_int st_hash __P((const char *, size_t, int));
83 1.10 mycroft static int uidtb_start __P((void));
84 1.10 mycroft static int gidtb_start __P((void));
85 1.10 mycroft static int usrtb_start __P((void));
86 1.10 mycroft static int grptb_start __P((void));
87 1.10 mycroft
88 1.10 mycroft static u_int
89 1.10 mycroft st_hash(name, len, tabsz)
90 1.10 mycroft const char *name;
91 1.10 mycroft size_t len;
92 1.10 mycroft int tabsz;
93 1.10 mycroft {
94 1.10 mycroft u_int key = 0;
95 1.10 mycroft
96 1.10 mycroft while (len--) {
97 1.10 mycroft key += *name++;
98 1.10 mycroft key = (key << 8) | (key >> 24);
99 1.10 mycroft }
100 1.10 mycroft
101 1.10 mycroft return (key % tabsz);
102 1.10 mycroft }
103 1.10 mycroft
104 1.10 mycroft /*
105 1.10 mycroft * uidtb_start
106 1.10 mycroft * creates an an empty uidtb
107 1.10 mycroft * Return:
108 1.10 mycroft * 0 if ok, -1 otherwise
109 1.10 mycroft */
110 1.10 mycroft
111 1.10 mycroft #if __STDC__
112 1.10 mycroft static int
113 1.10 mycroft uidtb_start(void)
114 1.10 mycroft #else
115 1.10 mycroft static int
116 1.10 mycroft uidtb_start()
117 1.10 mycroft #endif
118 1.10 mycroft {
119 1.10 mycroft static int fail = 0;
120 1.10 mycroft
121 1.10 mycroft if (uidtb != NULL)
122 1.10 mycroft return (0);
123 1.10 mycroft if (fail)
124 1.10 mycroft return (-1);
125 1.10 mycroft if ((uidtb = (UIDC **)calloc(UID_SZ, sizeof(UIDC *))) == NULL) {
126 1.10 mycroft ++fail;
127 1.10 mycroft return (-1);
128 1.10 mycroft }
129 1.10 mycroft return (0);
130 1.10 mycroft }
131 1.10 mycroft
132 1.10 mycroft /*
133 1.10 mycroft * gidtb_start
134 1.10 mycroft * creates an an empty gidtb
135 1.10 mycroft * Return:
136 1.10 mycroft * 0 if ok, -1 otherwise
137 1.10 mycroft */
138 1.1 cgd
139 1.10 mycroft #if __STDC__
140 1.10 mycroft int
141 1.10 mycroft gidtb_start(void)
142 1.10 mycroft #else
143 1.10 mycroft int
144 1.10 mycroft gidtb_start()
145 1.10 mycroft #endif
146 1.10 mycroft {
147 1.10 mycroft static int fail = 0;
148 1.10 mycroft
149 1.10 mycroft if (gidtb != NULL)
150 1.10 mycroft return (0);
151 1.10 mycroft if (fail)
152 1.10 mycroft return (-1);
153 1.10 mycroft if ((gidtb = (GIDC **)calloc(GID_SZ, sizeof(GIDC *))) == NULL) {
154 1.10 mycroft ++fail;
155 1.10 mycroft return (-1);
156 1.10 mycroft }
157 1.10 mycroft return (0);
158 1.10 mycroft }
159 1.10 mycroft
160 1.10 mycroft /*
161 1.10 mycroft * usrtb_start
162 1.10 mycroft * creates an an empty usrtb
163 1.10 mycroft * Return:
164 1.10 mycroft * 0 if ok, -1 otherwise
165 1.10 mycroft */
166 1.10 mycroft
167 1.10 mycroft #if __STDC__
168 1.10 mycroft int
169 1.10 mycroft usrtb_start(void)
170 1.10 mycroft #else
171 1.10 mycroft int
172 1.10 mycroft usrtb_start()
173 1.10 mycroft #endif
174 1.10 mycroft {
175 1.10 mycroft static int fail = 0;
176 1.10 mycroft
177 1.10 mycroft if (usrtb != NULL)
178 1.10 mycroft return (0);
179 1.10 mycroft if (fail)
180 1.10 mycroft return (-1);
181 1.10 mycroft if ((usrtb = (UIDC **)calloc(UNM_SZ, sizeof(UIDC *))) == NULL) {
182 1.10 mycroft ++fail;
183 1.10 mycroft return (-1);
184 1.10 mycroft }
185 1.10 mycroft return (0);
186 1.10 mycroft }
187 1.10 mycroft
188 1.10 mycroft /*
189 1.10 mycroft * grptb_start
190 1.10 mycroft * creates an an empty grptb
191 1.10 mycroft * Return:
192 1.10 mycroft * 0 if ok, -1 otherwise
193 1.10 mycroft */
194 1.10 mycroft
195 1.10 mycroft #if __STDC__
196 1.10 mycroft int
197 1.10 mycroft grptb_start(void)
198 1.10 mycroft #else
199 1.10 mycroft int
200 1.10 mycroft grptb_start()
201 1.10 mycroft #endif
202 1.10 mycroft {
203 1.10 mycroft static int fail = 0;
204 1.10 mycroft
205 1.10 mycroft if (grptb != NULL)
206 1.10 mycroft return (0);
207 1.10 mycroft if (fail)
208 1.10 mycroft return (-1);
209 1.10 mycroft if ((grptb = (GIDC **)calloc(GNM_SZ, sizeof(GIDC *))) == NULL) {
210 1.10 mycroft ++fail;
211 1.10 mycroft return (-1);
212 1.10 mycroft }
213 1.10 mycroft return (0);
214 1.10 mycroft }
215 1.10 mycroft
216 1.10 mycroft /*
217 1.10 mycroft * name_uid()
218 1.10 mycroft * caches the name (if any) for the uid. If noname clear, we always return the
219 1.10 mycroft * the stored name (if valid or invalid match). We use a simple hash table.
220 1.10 mycroft * Return
221 1.10 mycroft * Pointer to stored name (or a empty string)
222 1.10 mycroft */
223 1.10 mycroft
224 1.10 mycroft #if __STDC__
225 1.10 mycroft const char *
226 1.10 mycroft user_from_uid(uid_t uid, int noname)
227 1.10 mycroft #else
228 1.10 mycroft const char *
229 1.10 mycroft user_from_uid(uid, noname)
230 1.1 cgd uid_t uid;
231 1.10 mycroft int noname;
232 1.10 mycroft #endif
233 1.1 cgd {
234 1.9 perry struct passwd *pw;
235 1.10 mycroft UIDC *ptr, **pptr;
236 1.1 cgd
237 1.10 mycroft if ((uidtb == NULL) && (uidtb_start() < 0))
238 1.10 mycroft return (NULL);
239 1.10 mycroft
240 1.10 mycroft /*
241 1.10 mycroft * see if we have this uid cached
242 1.10 mycroft */
243 1.10 mycroft pptr = uidtb + (uid % UID_SZ);
244 1.10 mycroft ptr = *pptr;
245 1.10 mycroft
246 1.10 mycroft if ((ptr != NULL) && (ptr->valid > 0) && (ptr->uid == uid)) {
247 1.10 mycroft /*
248 1.10 mycroft * have an entry for this uid
249 1.10 mycroft */
250 1.10 mycroft if (!noname || (ptr->valid == VALID))
251 1.10 mycroft return (ptr->name);
252 1.10 mycroft return (NULL);
253 1.10 mycroft }
254 1.10 mycroft
255 1.10 mycroft /*
256 1.10 mycroft * No entry for this uid, we will add it
257 1.10 mycroft */
258 1.10 mycroft if (!pwopn) {
259 1.10 mycroft setpassent(1);
260 1.10 mycroft ++pwopn;
261 1.1 cgd }
262 1.10 mycroft
263 1.10 mycroft if (ptr == NULL)
264 1.10 mycroft ptr = (UIDC *)malloc(sizeof(UIDC));
265 1.10 mycroft *pptr = ptr;
266 1.10 mycroft
267 1.10 mycroft if ((pw = getpwuid(uid)) == NULL) {
268 1.10 mycroft /*
269 1.10 mycroft * no match for this uid in the local password file
270 1.10 mycroft * a string that is the uid in numberic format
271 1.10 mycroft */
272 1.10 mycroft if (ptr == NULL)
273 1.10 mycroft return (NULL);
274 1.10 mycroft ptr->uid = uid;
275 1.10 mycroft # ifdef NET2_STAT
276 1.10 mycroft (void)snprintf(ptr->name, UNMLEN, "%u", uid);
277 1.10 mycroft # else
278 1.10 mycroft (void)snprintf(ptr->name, UNMLEN, "%lu", (long) uid);
279 1.10 mycroft # endif
280 1.10 mycroft ptr->valid = INVALID;
281 1.10 mycroft if (noname)
282 1.10 mycroft return (NULL);
283 1.10 mycroft } else {
284 1.10 mycroft /*
285 1.10 mycroft * there is an entry for this uid in the password file
286 1.10 mycroft */
287 1.10 mycroft if (ptr == NULL)
288 1.10 mycroft return (pw->pw_name);
289 1.10 mycroft ptr->uid = uid;
290 1.10 mycroft (void)strncpy(ptr->name, pw->pw_name, UNMLEN);
291 1.10 mycroft ptr->name[UNMLEN-1] = '\0';
292 1.10 mycroft ptr->valid = VALID;
293 1.10 mycroft }
294 1.10 mycroft return (ptr->name);
295 1.1 cgd }
296 1.1 cgd
297 1.10 mycroft /*
298 1.10 mycroft * group_from_gid()
299 1.10 mycroft * caches the name (if any) for the gid. If noname clear, we always return the
300 1.10 mycroft * the stored name (if valid or invalid match). We use a simple hash table.
301 1.10 mycroft * Return
302 1.10 mycroft * Pointer to stored name (or a empty string)
303 1.10 mycroft */
304 1.10 mycroft
305 1.10 mycroft #if __STDC__
306 1.10 mycroft const char *
307 1.10 mycroft group_from_gid(gid_t gid, int noname)
308 1.10 mycroft #else
309 1.10 mycroft const char *
310 1.10 mycroft group_from_gid(gid, noname)
311 1.1 cgd gid_t gid;
312 1.10 mycroft int noname;
313 1.10 mycroft #endif
314 1.10 mycroft {
315 1.10 mycroft struct group *gr;
316 1.10 mycroft GIDC *ptr, **pptr;
317 1.10 mycroft
318 1.10 mycroft if ((gidtb == NULL) && (gidtb_start() < 0))
319 1.10 mycroft return (NULL);
320 1.10 mycroft
321 1.10 mycroft /*
322 1.10 mycroft * see if we have this gid cached
323 1.10 mycroft */
324 1.10 mycroft pptr = gidtb + (gid % GID_SZ);
325 1.10 mycroft ptr = *pptr;
326 1.10 mycroft
327 1.10 mycroft if ((ptr != NULL) && (ptr->valid > 0) && (ptr->gid == gid)) {
328 1.10 mycroft /*
329 1.10 mycroft * have an entry for this gid
330 1.10 mycroft */
331 1.10 mycroft if (!noname || (ptr->valid == VALID))
332 1.10 mycroft return (ptr->name);
333 1.10 mycroft return (NULL);
334 1.10 mycroft }
335 1.10 mycroft
336 1.10 mycroft /*
337 1.10 mycroft * No entry for this gid, we will add it
338 1.10 mycroft */
339 1.10 mycroft if (!gropn) {
340 1.10 mycroft setgroupent(1);
341 1.10 mycroft ++gropn;
342 1.10 mycroft }
343 1.10 mycroft
344 1.10 mycroft if (ptr == NULL)
345 1.10 mycroft ptr = (GIDC *)malloc(sizeof(GIDC));
346 1.10 mycroft *pptr = ptr;
347 1.10 mycroft
348 1.10 mycroft if ((gr = getgrgid(gid)) == NULL) {
349 1.10 mycroft /*
350 1.10 mycroft * no match for this gid in the local group file, put in
351 1.10 mycroft * a string that is the gid in numberic format
352 1.10 mycroft */
353 1.10 mycroft if (ptr == NULL)
354 1.10 mycroft return (NULL);
355 1.10 mycroft ptr->gid = gid;
356 1.10 mycroft # ifdef NET2_STAT
357 1.10 mycroft (void)snprintf(ptr->name, GNMLEN, "%u", gid);
358 1.10 mycroft # else
359 1.10 mycroft (void)snprintf(ptr->name, GNMLEN, "%lu", (long) gid);
360 1.10 mycroft # endif
361 1.10 mycroft ptr->valid = INVALID;
362 1.10 mycroft if (noname)
363 1.10 mycroft return (NULL);
364 1.10 mycroft } else {
365 1.10 mycroft /*
366 1.10 mycroft * there is an entry for this group in the group file
367 1.10 mycroft */
368 1.10 mycroft if (ptr == NULL)
369 1.10 mycroft return (gr->gr_name);
370 1.10 mycroft ptr->gid = gid;
371 1.10 mycroft (void)strncpy(ptr->name, gr->gr_name, GNMLEN);
372 1.10 mycroft ptr->name[GNMLEN-1] = '\0';
373 1.10 mycroft ptr->valid = VALID;
374 1.10 mycroft }
375 1.10 mycroft return (ptr->name);
376 1.10 mycroft }
377 1.10 mycroft
378 1.10 mycroft /*
379 1.10 mycroft * uid_from_user()
380 1.10 mycroft * caches the uid for a given user name. We use a simple hash table.
381 1.10 mycroft * Return
382 1.10 mycroft * the uid (if any) for a user name, or a -1 if no match can be found
383 1.10 mycroft */
384 1.10 mycroft
385 1.10 mycroft #if __STDC__
386 1.10 mycroft int
387 1.10 mycroft uid_from_user(const char *name, uid_t *uid)
388 1.10 mycroft #else
389 1.10 mycroft int
390 1.10 mycroft uid_from_user(name, uid)
391 1.10 mycroft const char *name;
392 1.10 mycroft uid_t *uid;
393 1.10 mycroft #endif
394 1.10 mycroft {
395 1.10 mycroft struct passwd *pw;
396 1.10 mycroft UIDC *ptr, **pptr;
397 1.10 mycroft size_t namelen;
398 1.10 mycroft
399 1.10 mycroft /*
400 1.10 mycroft * return -1 for mangled names
401 1.10 mycroft */
402 1.10 mycroft if (((namelen = strlen(name)) == 0) || (name[0] == '\0'))
403 1.10 mycroft return (-1);
404 1.10 mycroft if ((usrtb == NULL) && (usrtb_start() < 0))
405 1.10 mycroft return (-1);
406 1.10 mycroft
407 1.10 mycroft /*
408 1.10 mycroft * look up in hash table, if found and valid return the uid,
409 1.10 mycroft * if found and invalid, return a -1
410 1.10 mycroft */
411 1.10 mycroft pptr = usrtb + st_hash(name, namelen, UNM_SZ);
412 1.10 mycroft ptr = *pptr;
413 1.10 mycroft
414 1.10 mycroft if ((ptr != NULL) && (ptr->valid > 0) && !strcmp(name, ptr->name)) {
415 1.10 mycroft if (ptr->valid == INVALID)
416 1.10 mycroft return (-1);
417 1.10 mycroft *uid = ptr->uid;
418 1.10 mycroft return (0);
419 1.10 mycroft }
420 1.10 mycroft
421 1.10 mycroft if (!pwopn) {
422 1.10 mycroft setpassent(1);
423 1.10 mycroft ++pwopn;
424 1.10 mycroft }
425 1.10 mycroft
426 1.10 mycroft if (ptr == NULL)
427 1.10 mycroft ptr = (UIDC *)malloc(sizeof(UIDC));
428 1.10 mycroft *pptr = ptr;
429 1.10 mycroft
430 1.10 mycroft /*
431 1.10 mycroft * no match, look it up, if no match store it as an invalid entry,
432 1.10 mycroft * or store the matching uid
433 1.10 mycroft */
434 1.10 mycroft if (ptr == NULL) {
435 1.10 mycroft if ((pw = getpwnam(name)) == NULL)
436 1.10 mycroft return (-1);
437 1.10 mycroft *uid = pw->pw_uid;
438 1.10 mycroft return (0);
439 1.10 mycroft }
440 1.10 mycroft (void)strncpy(ptr->name, name, UNMLEN);
441 1.10 mycroft ptr->name[UNMLEN-1] = '\0';
442 1.10 mycroft if ((pw = getpwnam(name)) == NULL) {
443 1.10 mycroft ptr->valid = INVALID;
444 1.10 mycroft return (-1);
445 1.10 mycroft }
446 1.10 mycroft ptr->valid = VALID;
447 1.10 mycroft *uid = ptr->uid = pw->pw_uid;
448 1.10 mycroft return (0);
449 1.10 mycroft }
450 1.10 mycroft
451 1.10 mycroft /*
452 1.10 mycroft * gid_from_group()
453 1.10 mycroft * caches the gid for a given group name. We use a simple hash table.
454 1.10 mycroft * Return
455 1.10 mycroft * the gid (if any) for a group name, or a -1 if no match can be found
456 1.10 mycroft */
457 1.10 mycroft
458 1.10 mycroft #if __STDC__
459 1.10 mycroft int
460 1.10 mycroft gid_from_group(const char *name, gid_t *gid)
461 1.10 mycroft #else
462 1.10 mycroft int
463 1.10 mycroft gid_from_group(name, gid)
464 1.10 mycroft const char *name;
465 1.10 mycroft gid_t *gid;
466 1.10 mycroft #endif
467 1.1 cgd {
468 1.4 cgd struct group *gr;
469 1.10 mycroft GIDC *ptr, **pptr;
470 1.10 mycroft size_t namelen;
471 1.10 mycroft
472 1.10 mycroft /*
473 1.10 mycroft * return -1 for mangled names
474 1.10 mycroft */
475 1.10 mycroft if (((namelen = strlen(name)) == 0) || (name[0] == '\0'))
476 1.10 mycroft return (-1);
477 1.10 mycroft if ((grptb == NULL) && (grptb_start() < 0))
478 1.10 mycroft return (-1);
479 1.10 mycroft
480 1.10 mycroft /*
481 1.10 mycroft * look up in hash table, if found and valid return the uid,
482 1.10 mycroft * if found and invalid, return a -1
483 1.10 mycroft */
484 1.10 mycroft pptr = grptb + st_hash(name, namelen, GID_SZ);
485 1.10 mycroft ptr = *pptr;
486 1.10 mycroft
487 1.10 mycroft if ((ptr != NULL) && (ptr->valid > 0) && !strcmp(name, ptr->name)) {
488 1.10 mycroft if (ptr->valid == INVALID)
489 1.10 mycroft return (-1);
490 1.10 mycroft *gid = ptr->gid;
491 1.10 mycroft return (0);
492 1.10 mycroft }
493 1.10 mycroft
494 1.10 mycroft if (!gropn) {
495 1.10 mycroft setgroupent(1);
496 1.10 mycroft ++gropn;
497 1.10 mycroft }
498 1.10 mycroft
499 1.10 mycroft if (ptr == NULL)
500 1.10 mycroft ptr = (GIDC *)malloc(sizeof(GIDC));
501 1.10 mycroft *pptr = ptr;
502 1.10 mycroft
503 1.10 mycroft /*
504 1.10 mycroft * no match, look it up, if no match store it as an invalid entry,
505 1.10 mycroft * or store the matching gid
506 1.10 mycroft */
507 1.10 mycroft if (ptr == NULL) {
508 1.10 mycroft if ((gr = getgrnam(name)) == NULL)
509 1.10 mycroft return (-1);
510 1.10 mycroft *gid = gr->gr_gid;
511 1.10 mycroft return (0);
512 1.10 mycroft }
513 1.1 cgd
514 1.10 mycroft (void)strncpy(ptr->name, name, GNMLEN);
515 1.10 mycroft ptr->name[GNMLEN-1] = '\0';
516 1.10 mycroft if ((gr = getgrnam(name)) == NULL) {
517 1.10 mycroft ptr->valid = INVALID;
518 1.10 mycroft return (-1);
519 1.1 cgd }
520 1.10 mycroft ptr->valid = VALID;
521 1.10 mycroft *gid = ptr->gid = gr->gr_gid;
522 1.10 mycroft return (0);
523 1.1 cgd }
524