xref: /illumos-gate/usr/src/lib/libc/port/gen/getgrnam.c (revision 1d9df23bbf4124f12ca7832d6eaaa600e0aa8eda)
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  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
23  * Use is subject to license terms.
24  */
25 
26 #pragma ident	"%Z%%M%	%I%	%E% SMI"
27 
28 /*	Copyright (c) 1988 AT&T	*/
29 /*	  All Rights Reserved  	*/
30 
31 
32 /*	3.0 SID #	1.2	*/
33 
34 #pragma weak getgrnam	= _getgrnam
35 #pragma weak getgrgid	= _getgrgid
36 #pragma weak getgrent	= _getgrent
37 #pragma weak fgetgrent	= _fgetgrent
38 
39 #include "synonyms.h"
40 #include <sys/types.h>
41 #include <grp.h>
42 #include <nss_dbdefs.h>
43 #include <stdio.h>
44 #include "tsd.h"
45 
46 #ifdef	NSS_INCLUDE_UNSAFE
47 
48 extern size_t _nss_get_bufsizes(int arg);
49 
50 /*
51  * Ye olde non-reentrant interface (MT-unsafe, caveat utor)
52  */
53 
54 static void
55 free_grbuf(void *arg)
56 {
57 	nss_XbyY_buf_t **buffer = arg;
58 
59 	NSS_XbyY_FREE(buffer);
60 }
61 
62 static nss_XbyY_buf_t *
63 get_grbuf(int max_buf)
64 {
65 	nss_XbyY_buf_t **buffer =
66 	    tsdalloc(_T_GRBUF, sizeof (nss_XbyY_buf_t *), free_grbuf);
67 	nss_XbyY_buf_t *b;
68 	size_t	blen;
69 
70 	if (buffer == NULL)
71 		return (NULL);
72 	if (max_buf == 0)
73 		blen = _nss_get_bufsizes(0);		/* default size */
74 	else
75 		blen = sysconf(_SC_GETGR_R_SIZE_MAX);	/* max size */
76 	if (*buffer) {
77 		if ((*buffer)->buflen >= blen)	/* existing size fits */
78 			return (*buffer);
79 		NSS_XbyY_FREE(buffer);		/* existing is too small */
80 	}
81 	b = NSS_XbyY_ALLOC(buffer, sizeof (struct group), blen);
82 	return (b);
83 }
84 
85 struct group *
86 getgrgid(gid_t gid)
87 {
88 	nss_XbyY_buf_t	*b = get_grbuf(0);
89 	struct group *ret;
90 
91 	if (b == NULL)
92 		return (NULL);
93 
94 	ret = getgrgid_r(gid, b->result, b->buffer, b->buflen);
95 	if (ret == NULL && errno == ERANGE) {
96 		b = get_grbuf(1);
97 		if (b == NULL)
98 			return (NULL);
99 		ret = getgrgid_r(gid, b->result, b->buffer, b->buflen);
100 	}
101 	return (ret);
102 }
103 
104 struct group *
105 getgrnam(const char *nam)
106 {
107 	nss_XbyY_buf_t	*b = get_grbuf(0);
108 	struct group *ret;
109 
110 	if (b == NULL)
111 		return (NULL);
112 
113 	ret = getgrnam_r(nam, b->result, b->buffer, b->buflen);
114 	if (ret == NULL && errno == ERANGE && nam != NULL) {
115 		b = get_grbuf(1);
116 		if (b == NULL)
117 			return (NULL);
118 		ret = getgrnam_r(nam, b->result, b->buffer, b->buflen);
119 	}
120 	return (ret);
121 }
122 
123 struct group *
124 getgrent(void)
125 {
126 	nss_XbyY_buf_t	*b = get_grbuf(1);
127 
128 	return (b == NULL ? NULL :
129 	    getgrent_r(b->result, b->buffer, b->buflen));
130 }
131 
132 struct group *
133 fgetgrent(FILE *f)
134 {
135 	nss_XbyY_buf_t	*b = get_grbuf(1);
136 
137 	return (b == NULL ? NULL :
138 	    fgetgrent_r(f, b->result, b->buffer, b->buflen));
139 }
140 
141 #endif	/* NSS_INCLUDE_UNSAFE */
142