xref: /illumos-gate/usr/src/lib/libc/port/gen/getgrnam.c (revision eb00b1c8a31c2253a353644606388dff5b0e0275)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  */
21 
22 /*
23  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
24  * Use is subject to license terms.
25  */
26 
27 /*	Copyright (c) 1988 AT&T	*/
28 /*	  All Rights Reserved  	*/
29 
30 #pragma ident	"%Z%%M%	%I%	%E% SMI"
31 
32 #pragma weak _getgrnam	= getgrnam
33 #pragma weak _getgrgid	= getgrgid
34 
35 #include "lint.h"
36 #include <sys/types.h>
37 #include <grp.h>
38 #include <nss_dbdefs.h>
39 #include <stdio.h>
40 #include "tsd.h"
41 
42 #ifdef	NSS_INCLUDE_UNSAFE
43 
44 extern size_t _nss_get_bufsizes(int arg);
45 
46 /*
47  * Ye olde non-reentrant interface (MT-unsafe, caveat utor)
48  */
49 
50 static void
51 free_grbuf(void *arg)
52 {
53 	nss_XbyY_buf_t **buffer = arg;
54 
55 	NSS_XbyY_FREE(buffer);
56 }
57 
58 static nss_XbyY_buf_t *
59 get_grbuf(int max_buf)
60 {
61 	nss_XbyY_buf_t **buffer =
62 	    tsdalloc(_T_GRBUF, sizeof (nss_XbyY_buf_t *), free_grbuf);
63 	nss_XbyY_buf_t *b;
64 	size_t	blen;
65 
66 	if (buffer == NULL)
67 		return (NULL);
68 	if (max_buf == 0)
69 		blen = _nss_get_bufsizes(0);		/* default size */
70 	else
71 		blen = sysconf(_SC_GETGR_R_SIZE_MAX);	/* max size */
72 	if (*buffer) {
73 		if ((*buffer)->buflen >= blen)	/* existing size fits */
74 			return (*buffer);
75 		NSS_XbyY_FREE(buffer);		/* existing is too small */
76 	}
77 	b = NSS_XbyY_ALLOC(buffer, sizeof (struct group), blen);
78 	return (b);
79 }
80 
81 struct group *
82 getgrgid(gid_t gid)
83 {
84 	nss_XbyY_buf_t	*b = get_grbuf(0);
85 	struct group *ret;
86 
87 	if (b == NULL)
88 		return (NULL);
89 
90 	ret = getgrgid_r(gid, b->result, b->buffer, b->buflen);
91 	if (ret == NULL && errno == ERANGE) {
92 		b = get_grbuf(1);
93 		if (b == NULL)
94 			return (NULL);
95 		ret = getgrgid_r(gid, b->result, b->buffer, b->buflen);
96 	}
97 	return (ret);
98 }
99 
100 struct group *
101 getgrnam(const char *nam)
102 {
103 	nss_XbyY_buf_t	*b = get_grbuf(0);
104 	struct group *ret;
105 
106 	if (b == NULL)
107 		return (NULL);
108 
109 	ret = getgrnam_r(nam, b->result, b->buffer, b->buflen);
110 	if (ret == NULL && errno == ERANGE && nam != NULL) {
111 		b = get_grbuf(1);
112 		if (b == NULL)
113 			return (NULL);
114 		ret = getgrnam_r(nam, b->result, b->buffer, b->buflen);
115 	}
116 	return (ret);
117 }
118 
119 struct group *
120 getgrent(void)
121 {
122 	nss_XbyY_buf_t	*b = get_grbuf(1);
123 
124 	return (b == NULL ? NULL :
125 	    getgrent_r(b->result, b->buffer, b->buflen));
126 }
127 
128 struct group *
129 fgetgrent(FILE *f)
130 {
131 	nss_XbyY_buf_t	*b = get_grbuf(1);
132 
133 	return (b == NULL ? NULL :
134 	    fgetgrent_r(f, b->result, b->buffer, b->buflen));
135 }
136 
137 #endif	/* NSS_INCLUDE_UNSAFE */
138