pwcache.c revision 1.12 1 1.12 mycroft /* $NetBSD: pwcache.c,v 1.12 1999/01/19 08:32:34 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.12 mycroft __RCSID("$NetBSD: pwcache.c,v 1.12 1999/01/19 08:32:34 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.11 mycroft * user_from_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.12 mycroft *pptr = ptr = (UIDC *)malloc(sizeof(UIDC));
265 1.10 mycroft
266 1.10 mycroft if ((pw = getpwuid(uid)) == NULL) {
267 1.10 mycroft /*
268 1.10 mycroft * no match for this uid in the local password file
269 1.10 mycroft * a string that is the uid in numberic format
270 1.10 mycroft */
271 1.10 mycroft if (ptr == NULL)
272 1.10 mycroft return (NULL);
273 1.10 mycroft ptr->uid = uid;
274 1.10 mycroft # ifdef NET2_STAT
275 1.10 mycroft (void)snprintf(ptr->name, UNMLEN, "%u", uid);
276 1.10 mycroft # else
277 1.10 mycroft (void)snprintf(ptr->name, UNMLEN, "%lu", (long) uid);
278 1.10 mycroft # endif
279 1.10 mycroft ptr->valid = INVALID;
280 1.10 mycroft if (noname)
281 1.10 mycroft return (NULL);
282 1.10 mycroft } else {
283 1.10 mycroft /*
284 1.10 mycroft * there is an entry for this uid in the password file
285 1.10 mycroft */
286 1.10 mycroft if (ptr == NULL)
287 1.10 mycroft return (pw->pw_name);
288 1.10 mycroft ptr->uid = uid;
289 1.10 mycroft (void)strncpy(ptr->name, pw->pw_name, UNMLEN);
290 1.10 mycroft ptr->name[UNMLEN-1] = '\0';
291 1.10 mycroft ptr->valid = VALID;
292 1.10 mycroft }
293 1.10 mycroft return (ptr->name);
294 1.1 cgd }
295 1.1 cgd
296 1.10 mycroft /*
297 1.10 mycroft * group_from_gid()
298 1.10 mycroft * caches the name (if any) for the gid. If noname clear, we always return the
299 1.10 mycroft * the stored name (if valid or invalid match). We use a simple hash table.
300 1.10 mycroft * Return
301 1.10 mycroft * Pointer to stored name (or a empty string)
302 1.10 mycroft */
303 1.10 mycroft
304 1.10 mycroft #if __STDC__
305 1.10 mycroft const char *
306 1.10 mycroft group_from_gid(gid_t gid, int noname)
307 1.10 mycroft #else
308 1.10 mycroft const char *
309 1.10 mycroft group_from_gid(gid, noname)
310 1.1 cgd gid_t gid;
311 1.10 mycroft int noname;
312 1.10 mycroft #endif
313 1.10 mycroft {
314 1.10 mycroft struct group *gr;
315 1.10 mycroft GIDC *ptr, **pptr;
316 1.10 mycroft
317 1.10 mycroft if ((gidtb == NULL) && (gidtb_start() < 0))
318 1.10 mycroft return (NULL);
319 1.10 mycroft
320 1.10 mycroft /*
321 1.10 mycroft * see if we have this gid cached
322 1.10 mycroft */
323 1.10 mycroft pptr = gidtb + (gid % GID_SZ);
324 1.10 mycroft ptr = *pptr;
325 1.10 mycroft
326 1.10 mycroft if ((ptr != NULL) && (ptr->valid > 0) && (ptr->gid == gid)) {
327 1.10 mycroft /*
328 1.10 mycroft * have an entry for this gid
329 1.10 mycroft */
330 1.10 mycroft if (!noname || (ptr->valid == VALID))
331 1.10 mycroft return (ptr->name);
332 1.10 mycroft return (NULL);
333 1.10 mycroft }
334 1.10 mycroft
335 1.10 mycroft /*
336 1.10 mycroft * No entry for this gid, we will add it
337 1.10 mycroft */
338 1.10 mycroft if (!gropn) {
339 1.10 mycroft setgroupent(1);
340 1.10 mycroft ++gropn;
341 1.10 mycroft }
342 1.10 mycroft
343 1.10 mycroft if (ptr == NULL)
344 1.12 mycroft *pptr = ptr = (GIDC *)malloc(sizeof(GIDC));
345 1.10 mycroft
346 1.10 mycroft if ((gr = getgrgid(gid)) == NULL) {
347 1.10 mycroft /*
348 1.10 mycroft * no match for this gid in the local group file, put in
349 1.10 mycroft * a string that is the gid in numberic format
350 1.10 mycroft */
351 1.10 mycroft if (ptr == NULL)
352 1.10 mycroft return (NULL);
353 1.10 mycroft ptr->gid = gid;
354 1.10 mycroft # ifdef NET2_STAT
355 1.10 mycroft (void)snprintf(ptr->name, GNMLEN, "%u", gid);
356 1.10 mycroft # else
357 1.10 mycroft (void)snprintf(ptr->name, GNMLEN, "%lu", (long) gid);
358 1.10 mycroft # endif
359 1.10 mycroft ptr->valid = INVALID;
360 1.10 mycroft if (noname)
361 1.10 mycroft return (NULL);
362 1.10 mycroft } else {
363 1.10 mycroft /*
364 1.10 mycroft * there is an entry for this group in the group file
365 1.10 mycroft */
366 1.10 mycroft if (ptr == NULL)
367 1.10 mycroft return (gr->gr_name);
368 1.10 mycroft ptr->gid = gid;
369 1.10 mycroft (void)strncpy(ptr->name, gr->gr_name, GNMLEN);
370 1.10 mycroft ptr->name[GNMLEN-1] = '\0';
371 1.10 mycroft ptr->valid = VALID;
372 1.10 mycroft }
373 1.10 mycroft return (ptr->name);
374 1.10 mycroft }
375 1.10 mycroft
376 1.10 mycroft /*
377 1.10 mycroft * uid_from_user()
378 1.10 mycroft * caches the uid for a given user name. We use a simple hash table.
379 1.10 mycroft * Return
380 1.10 mycroft * the uid (if any) for a user name, or a -1 if no match can be found
381 1.10 mycroft */
382 1.10 mycroft
383 1.10 mycroft #if __STDC__
384 1.10 mycroft int
385 1.10 mycroft uid_from_user(const char *name, uid_t *uid)
386 1.10 mycroft #else
387 1.10 mycroft int
388 1.10 mycroft uid_from_user(name, uid)
389 1.10 mycroft const char *name;
390 1.10 mycroft uid_t *uid;
391 1.10 mycroft #endif
392 1.10 mycroft {
393 1.10 mycroft struct passwd *pw;
394 1.10 mycroft UIDC *ptr, **pptr;
395 1.10 mycroft size_t namelen;
396 1.10 mycroft
397 1.10 mycroft /*
398 1.10 mycroft * return -1 for mangled names
399 1.10 mycroft */
400 1.10 mycroft if (((namelen = strlen(name)) == 0) || (name[0] == '\0'))
401 1.10 mycroft return (-1);
402 1.10 mycroft if ((usrtb == NULL) && (usrtb_start() < 0))
403 1.10 mycroft return (-1);
404 1.10 mycroft
405 1.10 mycroft /*
406 1.10 mycroft * look up in hash table, if found and valid return the uid,
407 1.10 mycroft * if found and invalid, return a -1
408 1.10 mycroft */
409 1.10 mycroft pptr = usrtb + st_hash(name, namelen, UNM_SZ);
410 1.10 mycroft ptr = *pptr;
411 1.10 mycroft
412 1.10 mycroft if ((ptr != NULL) && (ptr->valid > 0) && !strcmp(name, ptr->name)) {
413 1.10 mycroft if (ptr->valid == INVALID)
414 1.10 mycroft return (-1);
415 1.10 mycroft *uid = ptr->uid;
416 1.10 mycroft return (0);
417 1.10 mycroft }
418 1.10 mycroft
419 1.10 mycroft if (!pwopn) {
420 1.10 mycroft setpassent(1);
421 1.10 mycroft ++pwopn;
422 1.10 mycroft }
423 1.10 mycroft
424 1.10 mycroft if (ptr == NULL)
425 1.12 mycroft *pptr = ptr = (UIDC *)malloc(sizeof(UIDC));
426 1.10 mycroft
427 1.10 mycroft /*
428 1.10 mycroft * no match, look it up, if no match store it as an invalid entry,
429 1.10 mycroft * or store the matching uid
430 1.10 mycroft */
431 1.10 mycroft if (ptr == NULL) {
432 1.10 mycroft if ((pw = getpwnam(name)) == NULL)
433 1.10 mycroft return (-1);
434 1.10 mycroft *uid = pw->pw_uid;
435 1.10 mycroft return (0);
436 1.10 mycroft }
437 1.10 mycroft (void)strncpy(ptr->name, name, UNMLEN);
438 1.10 mycroft ptr->name[UNMLEN-1] = '\0';
439 1.10 mycroft if ((pw = getpwnam(name)) == NULL) {
440 1.10 mycroft ptr->valid = INVALID;
441 1.10 mycroft return (-1);
442 1.10 mycroft }
443 1.10 mycroft ptr->valid = VALID;
444 1.10 mycroft *uid = ptr->uid = pw->pw_uid;
445 1.10 mycroft return (0);
446 1.10 mycroft }
447 1.10 mycroft
448 1.10 mycroft /*
449 1.10 mycroft * gid_from_group()
450 1.10 mycroft * caches the gid for a given group name. We use a simple hash table.
451 1.10 mycroft * Return
452 1.10 mycroft * the gid (if any) for a group name, or a -1 if no match can be found
453 1.10 mycroft */
454 1.10 mycroft
455 1.10 mycroft #if __STDC__
456 1.10 mycroft int
457 1.10 mycroft gid_from_group(const char *name, gid_t *gid)
458 1.10 mycroft #else
459 1.10 mycroft int
460 1.10 mycroft gid_from_group(name, gid)
461 1.10 mycroft const char *name;
462 1.10 mycroft gid_t *gid;
463 1.10 mycroft #endif
464 1.1 cgd {
465 1.4 cgd struct group *gr;
466 1.10 mycroft GIDC *ptr, **pptr;
467 1.10 mycroft size_t namelen;
468 1.10 mycroft
469 1.10 mycroft /*
470 1.10 mycroft * return -1 for mangled names
471 1.10 mycroft */
472 1.10 mycroft if (((namelen = strlen(name)) == 0) || (name[0] == '\0'))
473 1.10 mycroft return (-1);
474 1.10 mycroft if ((grptb == NULL) && (grptb_start() < 0))
475 1.10 mycroft return (-1);
476 1.10 mycroft
477 1.10 mycroft /*
478 1.10 mycroft * look up in hash table, if found and valid return the uid,
479 1.10 mycroft * if found and invalid, return a -1
480 1.10 mycroft */
481 1.10 mycroft pptr = grptb + st_hash(name, namelen, GID_SZ);
482 1.10 mycroft ptr = *pptr;
483 1.10 mycroft
484 1.10 mycroft if ((ptr != NULL) && (ptr->valid > 0) && !strcmp(name, ptr->name)) {
485 1.10 mycroft if (ptr->valid == INVALID)
486 1.10 mycroft return (-1);
487 1.10 mycroft *gid = ptr->gid;
488 1.10 mycroft return (0);
489 1.10 mycroft }
490 1.10 mycroft
491 1.10 mycroft if (!gropn) {
492 1.10 mycroft setgroupent(1);
493 1.10 mycroft ++gropn;
494 1.10 mycroft }
495 1.10 mycroft
496 1.10 mycroft if (ptr == NULL)
497 1.12 mycroft *pptr = ptr = (GIDC *)malloc(sizeof(GIDC));
498 1.10 mycroft
499 1.10 mycroft /*
500 1.10 mycroft * no match, look it up, if no match store it as an invalid entry,
501 1.10 mycroft * or store the matching gid
502 1.10 mycroft */
503 1.10 mycroft if (ptr == NULL) {
504 1.10 mycroft if ((gr = getgrnam(name)) == NULL)
505 1.10 mycroft return (-1);
506 1.10 mycroft *gid = gr->gr_gid;
507 1.10 mycroft return (0);
508 1.10 mycroft }
509 1.1 cgd
510 1.10 mycroft (void)strncpy(ptr->name, name, GNMLEN);
511 1.10 mycroft ptr->name[GNMLEN-1] = '\0';
512 1.10 mycroft if ((gr = getgrnam(name)) == NULL) {
513 1.10 mycroft ptr->valid = INVALID;
514 1.10 mycroft return (-1);
515 1.1 cgd }
516 1.10 mycroft ptr->valid = VALID;
517 1.10 mycroft *gid = ptr->gid = gr->gr_gid;
518 1.10 mycroft return (0);
519 1.1 cgd }
520