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