pwcache.c revision 1.15 1 1.15 msaitoh /* $NetBSD: pwcache.c,v 1.15 2000/09/13 22:32:28 msaitoh 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.15 msaitoh #if defined(LIBC_SCCS) && !defined(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.15 msaitoh __RCSID("$NetBSD: pwcache.c,v 1.15 2000/09/13 22:32:28 msaitoh Exp $");
46 1.4 cgd #endif
47 1.15 msaitoh #endif /* LIBC_SCCS and 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.13 lukem #include <assert.h>
55 1.4 cgd #include <grp.h>
56 1.1 cgd #include <pwd.h>
57 1.1 cgd #include <stdio.h>
58 1.10 mycroft #include <stdlib.h>
59 1.5 jtc #include <string.h>
60 1.10 mycroft #include <unistd.h>
61 1.10 mycroft
62 1.10 mycroft #include "pwcache.h"
63 1.8 jtc
64 1.8 jtc #ifdef __weak_alias
65 1.14 mycroft __weak_alias(user_from_uid,_user_from_uid)
66 1.14 mycroft __weak_alias(group_from_gid,_group_from_gid)
67 1.8 jtc #endif
68 1.1 cgd
69 1.10 mycroft /*
70 1.10 mycroft * routines that control user, group, uid and gid caches (for the archive
71 1.10 mycroft * member print routine).
72 1.10 mycroft * IMPORTANT:
73 1.10 mycroft * these routines cache BOTH hits and misses, a major performance improvement
74 1.10 mycroft */
75 1.10 mycroft
76 1.10 mycroft static int pwopn = 0; /* is password file open */
77 1.10 mycroft static int gropn = 0; /* is group file open */
78 1.10 mycroft static UIDC **uidtb = NULL; /* uid to name cache */
79 1.10 mycroft static GIDC **gidtb = NULL; /* gid to name cache */
80 1.10 mycroft static UIDC **usrtb = NULL; /* user name to uid cache */
81 1.10 mycroft static GIDC **grptb = NULL; /* group name to gid cache */
82 1.10 mycroft
83 1.10 mycroft static u_int st_hash __P((const char *, size_t, int));
84 1.10 mycroft static int uidtb_start __P((void));
85 1.10 mycroft static int gidtb_start __P((void));
86 1.10 mycroft static int usrtb_start __P((void));
87 1.10 mycroft static int grptb_start __P((void));
88 1.10 mycroft
89 1.10 mycroft static u_int
90 1.10 mycroft st_hash(name, len, tabsz)
91 1.10 mycroft const char *name;
92 1.10 mycroft size_t len;
93 1.10 mycroft int tabsz;
94 1.10 mycroft {
95 1.10 mycroft u_int key = 0;
96 1.10 mycroft
97 1.13 lukem _DIAGASSERT(name != NULL);
98 1.13 lukem
99 1.10 mycroft while (len--) {
100 1.10 mycroft key += *name++;
101 1.10 mycroft key = (key << 8) | (key >> 24);
102 1.10 mycroft }
103 1.10 mycroft
104 1.10 mycroft return (key % tabsz);
105 1.10 mycroft }
106 1.10 mycroft
107 1.10 mycroft /*
108 1.10 mycroft * uidtb_start
109 1.10 mycroft * creates an an empty uidtb
110 1.10 mycroft * Return:
111 1.10 mycroft * 0 if ok, -1 otherwise
112 1.10 mycroft */
113 1.10 mycroft
114 1.10 mycroft #if __STDC__
115 1.10 mycroft static int
116 1.10 mycroft uidtb_start(void)
117 1.10 mycroft #else
118 1.10 mycroft static int
119 1.10 mycroft uidtb_start()
120 1.10 mycroft #endif
121 1.10 mycroft {
122 1.10 mycroft static int fail = 0;
123 1.10 mycroft
124 1.10 mycroft if (uidtb != NULL)
125 1.10 mycroft return (0);
126 1.10 mycroft if (fail)
127 1.10 mycroft return (-1);
128 1.10 mycroft if ((uidtb = (UIDC **)calloc(UID_SZ, sizeof(UIDC *))) == NULL) {
129 1.10 mycroft ++fail;
130 1.10 mycroft return (-1);
131 1.10 mycroft }
132 1.10 mycroft return (0);
133 1.10 mycroft }
134 1.10 mycroft
135 1.10 mycroft /*
136 1.10 mycroft * gidtb_start
137 1.10 mycroft * creates an an empty gidtb
138 1.10 mycroft * Return:
139 1.10 mycroft * 0 if ok, -1 otherwise
140 1.10 mycroft */
141 1.1 cgd
142 1.10 mycroft #if __STDC__
143 1.10 mycroft int
144 1.10 mycroft gidtb_start(void)
145 1.10 mycroft #else
146 1.10 mycroft int
147 1.10 mycroft gidtb_start()
148 1.10 mycroft #endif
149 1.10 mycroft {
150 1.10 mycroft static int fail = 0;
151 1.10 mycroft
152 1.10 mycroft if (gidtb != NULL)
153 1.10 mycroft return (0);
154 1.10 mycroft if (fail)
155 1.10 mycroft return (-1);
156 1.10 mycroft if ((gidtb = (GIDC **)calloc(GID_SZ, sizeof(GIDC *))) == NULL) {
157 1.10 mycroft ++fail;
158 1.10 mycroft return (-1);
159 1.10 mycroft }
160 1.10 mycroft return (0);
161 1.10 mycroft }
162 1.10 mycroft
163 1.10 mycroft /*
164 1.10 mycroft * usrtb_start
165 1.10 mycroft * creates an an empty usrtb
166 1.10 mycroft * Return:
167 1.10 mycroft * 0 if ok, -1 otherwise
168 1.10 mycroft */
169 1.10 mycroft
170 1.10 mycroft #if __STDC__
171 1.10 mycroft int
172 1.10 mycroft usrtb_start(void)
173 1.10 mycroft #else
174 1.10 mycroft int
175 1.10 mycroft usrtb_start()
176 1.10 mycroft #endif
177 1.10 mycroft {
178 1.10 mycroft static int fail = 0;
179 1.10 mycroft
180 1.10 mycroft if (usrtb != NULL)
181 1.10 mycroft return (0);
182 1.10 mycroft if (fail)
183 1.10 mycroft return (-1);
184 1.10 mycroft if ((usrtb = (UIDC **)calloc(UNM_SZ, sizeof(UIDC *))) == NULL) {
185 1.10 mycroft ++fail;
186 1.10 mycroft return (-1);
187 1.10 mycroft }
188 1.10 mycroft return (0);
189 1.10 mycroft }
190 1.10 mycroft
191 1.10 mycroft /*
192 1.10 mycroft * grptb_start
193 1.10 mycroft * creates an an empty grptb
194 1.10 mycroft * Return:
195 1.10 mycroft * 0 if ok, -1 otherwise
196 1.10 mycroft */
197 1.10 mycroft
198 1.10 mycroft #if __STDC__
199 1.10 mycroft int
200 1.10 mycroft grptb_start(void)
201 1.10 mycroft #else
202 1.10 mycroft int
203 1.10 mycroft grptb_start()
204 1.10 mycroft #endif
205 1.10 mycroft {
206 1.10 mycroft static int fail = 0;
207 1.10 mycroft
208 1.10 mycroft if (grptb != NULL)
209 1.10 mycroft return (0);
210 1.10 mycroft if (fail)
211 1.10 mycroft return (-1);
212 1.10 mycroft if ((grptb = (GIDC **)calloc(GNM_SZ, sizeof(GIDC *))) == NULL) {
213 1.10 mycroft ++fail;
214 1.10 mycroft return (-1);
215 1.10 mycroft }
216 1.10 mycroft return (0);
217 1.10 mycroft }
218 1.10 mycroft
219 1.10 mycroft /*
220 1.11 mycroft * user_from_uid()
221 1.10 mycroft * caches the name (if any) for the uid. If noname clear, we always return the
222 1.10 mycroft * the stored name (if valid or invalid match). We use a simple hash table.
223 1.10 mycroft * Return
224 1.10 mycroft * Pointer to stored name (or a empty string)
225 1.10 mycroft */
226 1.10 mycroft
227 1.10 mycroft #if __STDC__
228 1.10 mycroft const char *
229 1.10 mycroft user_from_uid(uid_t uid, int noname)
230 1.10 mycroft #else
231 1.10 mycroft const char *
232 1.10 mycroft user_from_uid(uid, noname)
233 1.1 cgd uid_t uid;
234 1.10 mycroft int noname;
235 1.10 mycroft #endif
236 1.1 cgd {
237 1.9 perry struct passwd *pw;
238 1.10 mycroft UIDC *ptr, **pptr;
239 1.1 cgd
240 1.10 mycroft if ((uidtb == NULL) && (uidtb_start() < 0))
241 1.10 mycroft return (NULL);
242 1.10 mycroft
243 1.10 mycroft /*
244 1.10 mycroft * see if we have this uid cached
245 1.10 mycroft */
246 1.10 mycroft pptr = uidtb + (uid % UID_SZ);
247 1.10 mycroft ptr = *pptr;
248 1.10 mycroft
249 1.10 mycroft if ((ptr != NULL) && (ptr->valid > 0) && (ptr->uid == uid)) {
250 1.10 mycroft /*
251 1.10 mycroft * have an entry for this uid
252 1.10 mycroft */
253 1.10 mycroft if (!noname || (ptr->valid == VALID))
254 1.10 mycroft return (ptr->name);
255 1.10 mycroft return (NULL);
256 1.10 mycroft }
257 1.10 mycroft
258 1.10 mycroft /*
259 1.10 mycroft * No entry for this uid, we will add it
260 1.10 mycroft */
261 1.10 mycroft if (!pwopn) {
262 1.10 mycroft setpassent(1);
263 1.10 mycroft ++pwopn;
264 1.1 cgd }
265 1.10 mycroft
266 1.10 mycroft if (ptr == NULL)
267 1.12 mycroft *pptr = ptr = (UIDC *)malloc(sizeof(UIDC));
268 1.10 mycroft
269 1.10 mycroft if ((pw = getpwuid(uid)) == NULL) {
270 1.10 mycroft /*
271 1.10 mycroft * no match for this uid in the local password file
272 1.10 mycroft * a string that is the uid in numberic format
273 1.10 mycroft */
274 1.10 mycroft if (ptr == NULL)
275 1.10 mycroft return (NULL);
276 1.10 mycroft ptr->uid = uid;
277 1.10 mycroft # ifdef NET2_STAT
278 1.10 mycroft (void)snprintf(ptr->name, UNMLEN, "%u", uid);
279 1.10 mycroft # else
280 1.10 mycroft (void)snprintf(ptr->name, UNMLEN, "%lu", (long) uid);
281 1.10 mycroft # endif
282 1.10 mycroft ptr->valid = INVALID;
283 1.10 mycroft if (noname)
284 1.10 mycroft return (NULL);
285 1.10 mycroft } else {
286 1.10 mycroft /*
287 1.10 mycroft * there is an entry for this uid in the password file
288 1.10 mycroft */
289 1.10 mycroft if (ptr == NULL)
290 1.10 mycroft return (pw->pw_name);
291 1.10 mycroft ptr->uid = uid;
292 1.10 mycroft (void)strncpy(ptr->name, pw->pw_name, UNMLEN);
293 1.10 mycroft ptr->name[UNMLEN-1] = '\0';
294 1.10 mycroft ptr->valid = VALID;
295 1.10 mycroft }
296 1.10 mycroft return (ptr->name);
297 1.1 cgd }
298 1.1 cgd
299 1.10 mycroft /*
300 1.10 mycroft * group_from_gid()
301 1.10 mycroft * caches the name (if any) for the gid. If noname clear, we always return the
302 1.10 mycroft * the stored name (if valid or invalid match). We use a simple hash table.
303 1.10 mycroft * Return
304 1.10 mycroft * Pointer to stored name (or a empty string)
305 1.10 mycroft */
306 1.10 mycroft
307 1.10 mycroft #if __STDC__
308 1.10 mycroft const char *
309 1.10 mycroft group_from_gid(gid_t gid, int noname)
310 1.10 mycroft #else
311 1.10 mycroft const char *
312 1.10 mycroft group_from_gid(gid, noname)
313 1.1 cgd gid_t gid;
314 1.10 mycroft int noname;
315 1.10 mycroft #endif
316 1.10 mycroft {
317 1.10 mycroft struct group *gr;
318 1.10 mycroft GIDC *ptr, **pptr;
319 1.10 mycroft
320 1.10 mycroft if ((gidtb == NULL) && (gidtb_start() < 0))
321 1.10 mycroft return (NULL);
322 1.10 mycroft
323 1.10 mycroft /*
324 1.10 mycroft * see if we have this gid cached
325 1.10 mycroft */
326 1.10 mycroft pptr = gidtb + (gid % GID_SZ);
327 1.10 mycroft ptr = *pptr;
328 1.10 mycroft
329 1.10 mycroft if ((ptr != NULL) && (ptr->valid > 0) && (ptr->gid == gid)) {
330 1.10 mycroft /*
331 1.10 mycroft * have an entry for this gid
332 1.10 mycroft */
333 1.10 mycroft if (!noname || (ptr->valid == VALID))
334 1.10 mycroft return (ptr->name);
335 1.10 mycroft return (NULL);
336 1.10 mycroft }
337 1.10 mycroft
338 1.10 mycroft /*
339 1.10 mycroft * No entry for this gid, we will add it
340 1.10 mycroft */
341 1.10 mycroft if (!gropn) {
342 1.10 mycroft setgroupent(1);
343 1.10 mycroft ++gropn;
344 1.10 mycroft }
345 1.10 mycroft
346 1.10 mycroft if (ptr == NULL)
347 1.12 mycroft *pptr = ptr = (GIDC *)malloc(sizeof(GIDC));
348 1.10 mycroft
349 1.10 mycroft if ((gr = getgrgid(gid)) == NULL) {
350 1.10 mycroft /*
351 1.10 mycroft * no match for this gid in the local group file, put in
352 1.10 mycroft * a string that is the gid in numberic format
353 1.10 mycroft */
354 1.10 mycroft if (ptr == NULL)
355 1.10 mycroft return (NULL);
356 1.10 mycroft ptr->gid = gid;
357 1.10 mycroft # ifdef NET2_STAT
358 1.10 mycroft (void)snprintf(ptr->name, GNMLEN, "%u", gid);
359 1.10 mycroft # else
360 1.10 mycroft (void)snprintf(ptr->name, GNMLEN, "%lu", (long) gid);
361 1.10 mycroft # endif
362 1.10 mycroft ptr->valid = INVALID;
363 1.10 mycroft if (noname)
364 1.10 mycroft return (NULL);
365 1.10 mycroft } else {
366 1.10 mycroft /*
367 1.10 mycroft * there is an entry for this group in the group file
368 1.10 mycroft */
369 1.10 mycroft if (ptr == NULL)
370 1.10 mycroft return (gr->gr_name);
371 1.10 mycroft ptr->gid = gid;
372 1.10 mycroft (void)strncpy(ptr->name, gr->gr_name, GNMLEN);
373 1.10 mycroft ptr->name[GNMLEN-1] = '\0';
374 1.10 mycroft ptr->valid = VALID;
375 1.10 mycroft }
376 1.10 mycroft return (ptr->name);
377 1.10 mycroft }
378 1.10 mycroft
379 1.10 mycroft /*
380 1.10 mycroft * uid_from_user()
381 1.10 mycroft * caches the uid for a given user name. We use a simple hash table.
382 1.10 mycroft * Return
383 1.10 mycroft * the uid (if any) for a user name, or a -1 if no match can be found
384 1.10 mycroft */
385 1.10 mycroft
386 1.10 mycroft #if __STDC__
387 1.10 mycroft int
388 1.10 mycroft uid_from_user(const char *name, uid_t *uid)
389 1.10 mycroft #else
390 1.10 mycroft int
391 1.10 mycroft uid_from_user(name, uid)
392 1.10 mycroft const char *name;
393 1.10 mycroft uid_t *uid;
394 1.10 mycroft #endif
395 1.10 mycroft {
396 1.10 mycroft struct passwd *pw;
397 1.10 mycroft UIDC *ptr, **pptr;
398 1.10 mycroft size_t namelen;
399 1.10 mycroft
400 1.10 mycroft /*
401 1.10 mycroft * return -1 for mangled names
402 1.10 mycroft */
403 1.13 lukem if (name == NULL || ((namelen = strlen(name)) == 0))
404 1.10 mycroft return (-1);
405 1.10 mycroft if ((usrtb == NULL) && (usrtb_start() < 0))
406 1.10 mycroft return (-1);
407 1.10 mycroft
408 1.10 mycroft /*
409 1.10 mycroft * look up in hash table, if found and valid return the uid,
410 1.10 mycroft * if found and invalid, return a -1
411 1.10 mycroft */
412 1.10 mycroft pptr = usrtb + st_hash(name, namelen, UNM_SZ);
413 1.10 mycroft ptr = *pptr;
414 1.10 mycroft
415 1.10 mycroft if ((ptr != NULL) && (ptr->valid > 0) && !strcmp(name, ptr->name)) {
416 1.10 mycroft if (ptr->valid == INVALID)
417 1.10 mycroft return (-1);
418 1.10 mycroft *uid = ptr->uid;
419 1.10 mycroft return (0);
420 1.10 mycroft }
421 1.10 mycroft
422 1.10 mycroft if (!pwopn) {
423 1.10 mycroft setpassent(1);
424 1.10 mycroft ++pwopn;
425 1.10 mycroft }
426 1.10 mycroft
427 1.10 mycroft if (ptr == NULL)
428 1.12 mycroft *pptr = ptr = (UIDC *)malloc(sizeof(UIDC));
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.13 lukem if (name == NULL || ((namelen = strlen(name)) == 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.12 mycroft *pptr = ptr = (GIDC *)malloc(sizeof(GIDC));
501 1.10 mycroft
502 1.10 mycroft /*
503 1.10 mycroft * no match, look it up, if no match store it as an invalid entry,
504 1.10 mycroft * or store the matching gid
505 1.10 mycroft */
506 1.10 mycroft if (ptr == NULL) {
507 1.10 mycroft if ((gr = getgrnam(name)) == NULL)
508 1.10 mycroft return (-1);
509 1.10 mycroft *gid = gr->gr_gid;
510 1.10 mycroft return (0);
511 1.10 mycroft }
512 1.1 cgd
513 1.10 mycroft (void)strncpy(ptr->name, name, GNMLEN);
514 1.10 mycroft ptr->name[GNMLEN-1] = '\0';
515 1.10 mycroft if ((gr = getgrnam(name)) == NULL) {
516 1.10 mycroft ptr->valid = INVALID;
517 1.10 mycroft return (-1);
518 1.1 cgd }
519 1.10 mycroft ptr->valid = VALID;
520 1.10 mycroft *gid = ptr->gid = gr->gr_gid;
521 1.10 mycroft return (0);
522 1.1 cgd }
523