1 1.67 dholland /* $NetBSD: getgrent.c,v 1.67 2012/08/29 18:50:35 dholland Exp $ */ 2 1.49 lukem 3 1.49 lukem /*- 4 1.54 lukem * Copyright (c) 1999-2000, 2004-2005 The NetBSD Foundation, Inc. 5 1.49 lukem * All rights reserved. 6 1.49 lukem * 7 1.49 lukem * This code is derived from software contributed to The NetBSD Foundation 8 1.49 lukem * by Luke Mewburn. 9 1.49 lukem * 10 1.49 lukem * Redistribution and use in source and binary forms, with or without 11 1.49 lukem * modification, are permitted provided that the following conditions 12 1.49 lukem * are met: 13 1.49 lukem * 1. Redistributions of source code must retain the above copyright 14 1.49 lukem * notice, this list of conditions and the following disclaimer. 15 1.49 lukem * 2. Redistributions in binary form must reproduce the above copyright 16 1.49 lukem * notice, this list of conditions and the following disclaimer in the 17 1.49 lukem * documentation and/or other materials provided with the distribution. 18 1.49 lukem * 19 1.49 lukem * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 20 1.49 lukem * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21 1.49 lukem * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 1.49 lukem * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 23 1.49 lukem * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 1.49 lukem * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 1.49 lukem * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 1.49 lukem * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 1.49 lukem * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 1.49 lukem * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 1.49 lukem * POSSIBILITY OF SUCH DAMAGE. 30 1.49 lukem */ 31 1.11 cgd 32 1.1 cgd /* 33 1.11 cgd * Copyright (c) 1989, 1993 34 1.11 cgd * The Regents of the University of California. All rights reserved. 35 1.47 agc * 36 1.47 agc * Redistribution and use in source and binary forms, with or without 37 1.47 agc * modification, are permitted provided that the following conditions 38 1.47 agc * are met: 39 1.47 agc * 1. Redistributions of source code must retain the above copyright 40 1.47 agc * notice, this list of conditions and the following disclaimer. 41 1.47 agc * 2. Redistributions in binary form must reproduce the above copyright 42 1.47 agc * notice, this list of conditions and the following disclaimer in the 43 1.47 agc * documentation and/or other materials provided with the distribution. 44 1.47 agc * 3. Neither the name of the University nor the names of its contributors 45 1.47 agc * may be used to endorse or promote products derived from this software 46 1.47 agc * without specific prior written permission. 47 1.47 agc * 48 1.47 agc * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 49 1.47 agc * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 50 1.47 agc * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 51 1.47 agc * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 52 1.47 agc * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 53 1.47 agc * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 54 1.47 agc * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 55 1.47 agc * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 56 1.47 agc * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 57 1.47 agc * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 58 1.47 agc * SUCH DAMAGE. 59 1.47 agc */ 60 1.47 agc 61 1.47 agc /* 62 1.13 phil * Portions Copyright (c) 1994, Jason Downs. All Rights Reserved. 63 1.1 cgd * 64 1.1 cgd * Redistribution and use in source and binary forms, with or without 65 1.1 cgd * modification, are permitted provided that the following conditions 66 1.1 cgd * are met: 67 1.1 cgd * 1. Redistributions of source code must retain the above copyright 68 1.1 cgd * notice, this list of conditions and the following disclaimer. 69 1.1 cgd * 2. Redistributions in binary form must reproduce the above copyright 70 1.1 cgd * notice, this list of conditions and the following disclaimer in the 71 1.1 cgd * documentation and/or other materials provided with the distribution. 72 1.1 cgd * 73 1.48 agc * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS 74 1.48 agc * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 75 1.48 agc * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 76 1.48 agc * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, 77 1.48 agc * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 78 1.48 agc * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 79 1.48 agc * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 80 1.48 agc * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 81 1.1 cgd * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 82 1.1 cgd * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 83 1.1 cgd * SUCH DAMAGE. 84 1.1 cgd */ 85 1.1 cgd 86 1.20 christos #include <sys/cdefs.h> 87 1.1 cgd #if defined(LIBC_SCCS) && !defined(lint) 88 1.11 cgd #if 0 89 1.11 cgd static char sccsid[] = "@(#)getgrent.c 8.2 (Berkeley) 3/21/94"; 90 1.11 cgd #else 91 1.67 dholland __RCSID("$NetBSD: getgrent.c,v 1.67 2012/08/29 18:50:35 dholland Exp $"); 92 1.11 cgd #endif 93 1.1 cgd #endif /* LIBC_SCCS and not lint */ 94 1.1 cgd 95 1.21 jtc #include "namespace.h" 96 1.51 lukem #include "reentrant.h" 97 1.33 lukem 98 1.49 lukem #include <sys/param.h> 99 1.33 lukem 100 1.37 lukem #include <assert.h> 101 1.33 lukem #include <errno.h> 102 1.27 lukem #include <grp.h> 103 1.18 lukem #include <limits.h> 104 1.27 lukem #include <nsswitch.h> 105 1.50 lukem #include <stdarg.h> 106 1.1 cgd #include <stdio.h> 107 1.1 cgd #include <stdlib.h> 108 1.2 deraadt #include <string.h> 109 1.27 lukem #include <syslog.h> 110 1.33 lukem 111 1.27 lukem #ifdef HESIOD 112 1.27 lukem #include <hesiod.h> 113 1.27 lukem #endif 114 1.49 lukem 115 1.2 deraadt #ifdef YP 116 1.2 deraadt #include <rpc/rpc.h> 117 1.2 deraadt #include <rpcsvc/yp_prot.h> 118 1.2 deraadt #include <rpcsvc/ypclnt.h> 119 1.21 jtc #endif 120 1.21 jtc 121 1.54 lukem #include "gr_private.h" 122 1.34 lukem 123 1.21 jtc #ifdef __weak_alias 124 1.39 mycroft __weak_alias(endgrent,_endgrent) 125 1.39 mycroft __weak_alias(getgrent,_getgrent) 126 1.56 christos __weak_alias(getgrent_r,_getgrent_r) 127 1.39 mycroft __weak_alias(getgrgid,_getgrgid) 128 1.49 lukem __weak_alias(getgrgid_r,_getgrgid_r) 129 1.39 mycroft __weak_alias(getgrnam,_getgrnam) 130 1.49 lukem __weak_alias(getgrnam_r,_getgrnam_r) 131 1.39 mycroft __weak_alias(setgrent,_setgrent) 132 1.39 mycroft __weak_alias(setgroupent,_setgroupent) 133 1.2 deraadt #endif 134 1.54 lukem 135 1.50 lukem #ifdef _REENTRANT 136 1.54 lukem mutex_t __grmutex = MUTEX_INITIALIZER; 137 1.50 lukem #endif 138 1.1 cgd 139 1.49 lukem /* 140 1.49 lukem * _gr_memfrombuf 141 1.49 lukem * Obtain want bytes from buffer (of size buflen) and return a pointer 142 1.49 lukem * to the available memory after adjusting buffer/buflen. 143 1.49 lukem * Returns NULL if there is insufficient space. 144 1.49 lukem */ 145 1.49 lukem static char * 146 1.49 lukem _gr_memfrombuf(size_t want, char **buffer, size_t *buflen) 147 1.49 lukem { 148 1.49 lukem char *rv; 149 1.49 lukem 150 1.49 lukem if (want > *buflen) { 151 1.49 lukem errno = ERANGE; 152 1.49 lukem return NULL; 153 1.49 lukem } 154 1.49 lukem rv = *buffer; 155 1.49 lukem *buffer += want; 156 1.49 lukem *buflen -= want; 157 1.49 lukem return rv; 158 1.49 lukem } 159 1.27 lukem 160 1.49 lukem /* 161 1.49 lukem * _gr_parse 162 1.49 lukem * Parses entry as a line per group(5) (without the trailing \n) 163 1.49 lukem * and fills in grp with corresponding values; memory for strings 164 1.49 lukem * and arrays will be allocated from buf (of size buflen). 165 1.49 lukem * Returns 1 if parsed successfully, 0 on parse failure. 166 1.49 lukem */ 167 1.49 lukem static int 168 1.49 lukem _gr_parse(const char *entry, struct group *grp, char *buf, size_t buflen) 169 1.49 lukem { 170 1.49 lukem unsigned long id; 171 1.49 lukem const char *bp; 172 1.49 lukem char *ep; 173 1.49 lukem size_t count; 174 1.49 lukem int memc; 175 1.49 lukem 176 1.49 lukem _DIAGASSERT(entry != NULL); 177 1.49 lukem _DIAGASSERT(grp != NULL); 178 1.49 lukem _DIAGASSERT(buf != NULL); 179 1.49 lukem 180 1.49 lukem #define COPYTOBUF(to) \ 181 1.49 lukem do { \ 182 1.49 lukem (to) = _gr_memfrombuf(count+1, &buf, &buflen); \ 183 1.49 lukem if ((to) == NULL) \ 184 1.49 lukem return 0; \ 185 1.49 lukem memmove((to), entry, count); \ 186 1.49 lukem to[count] = '\0'; \ 187 1.49 lukem } while (0) /* LINTED */ 188 1.1 cgd 189 1.49 lukem #if 0 190 1.49 lukem if (*entry == '+') /* fail on compat `+' token */ 191 1.49 lukem return 0; 192 1.27 lukem #endif 193 1.27 lukem 194 1.49 lukem count = strcspn(entry, ":"); /* parse gr_name */ 195 1.49 lukem if (entry[count] == '\0') 196 1.49 lukem return 0; 197 1.49 lukem COPYTOBUF(grp->gr_name); 198 1.49 lukem entry += count + 1; 199 1.49 lukem 200 1.49 lukem count = strcspn(entry, ":"); /* parse gr_passwd */ 201 1.49 lukem if (entry[count] == '\0') 202 1.49 lukem return 0; 203 1.49 lukem COPYTOBUF(grp->gr_passwd); 204 1.49 lukem entry += count + 1; 205 1.49 lukem 206 1.49 lukem count = strcspn(entry, ":"); /* parse gr_gid */ 207 1.49 lukem if (entry[count] == '\0') 208 1.49 lukem return 0; 209 1.49 lukem id = strtoul(entry, &ep, 10); 210 1.49 lukem if (id > GID_MAX || *ep != ':') 211 1.49 lukem return 0; 212 1.49 lukem grp->gr_gid = (gid_t)id; 213 1.49 lukem entry += count + 1; 214 1.49 lukem 215 1.49 lukem memc = 1; /* for final NULL */ 216 1.49 lukem if (*entry != '\0') 217 1.49 lukem memc++; /* for first item */ 218 1.49 lukem for (bp = entry; *bp != '\0'; bp++) { 219 1.49 lukem if (*bp == ',') 220 1.49 lukem memc++; 221 1.49 lukem } 222 1.49 lukem /* grab ALIGNed char **gr_mem from buf */ 223 1.49 lukem ep = _gr_memfrombuf(memc * sizeof(char *) + ALIGNBYTES, &buf, &buflen); 224 1.67 dholland if (ep == NULL) 225 1.67 dholland return 0; 226 1.49 lukem grp->gr_mem = (char **)ALIGN(ep); 227 1.2 deraadt 228 1.49 lukem for (memc = 0; *entry != '\0'; memc++) { 229 1.49 lukem count = strcspn(entry, ","); /* parse member */ 230 1.49 lukem COPYTOBUF(grp->gr_mem[memc]); 231 1.49 lukem entry += count; 232 1.49 lukem if (*entry == ',') 233 1.49 lukem entry++; 234 1.49 lukem } 235 1.34 lukem 236 1.49 lukem #undef COPYTOBUF 237 1.41 lukem 238 1.49 lukem grp->gr_mem[memc] = NULL; 239 1.49 lukem return 1; 240 1.45 elric } 241 1.45 elric 242 1.45 elric /* 243 1.49 lukem * _gr_copy 244 1.49 lukem * Copy the contents of fromgrp to grp; memory for strings 245 1.49 lukem * and arrays will be allocated from buf (of size buflen). 246 1.49 lukem * Returns 1 if copied successfully, 0 on copy failure. 247 1.49 lukem * NOTE: fromgrp must not use buf for its own pointers. 248 1.45 elric */ 249 1.49 lukem static int 250 1.49 lukem _gr_copy(struct group *fromgrp, struct group *grp, char *buf, size_t buflen) 251 1.49 lukem { 252 1.49 lukem char *ep; 253 1.49 lukem int memc; 254 1.49 lukem 255 1.49 lukem _DIAGASSERT(fromgrp != NULL); 256 1.49 lukem _DIAGASSERT(grp != NULL); 257 1.49 lukem _DIAGASSERT(buf != NULL); 258 1.49 lukem 259 1.49 lukem #define COPYSTR(to, from) \ 260 1.49 lukem do { \ 261 1.49 lukem size_t count = strlen((from)); \ 262 1.49 lukem (to) = _gr_memfrombuf(count+1, &buf, &buflen); \ 263 1.49 lukem if ((to) == NULL) \ 264 1.49 lukem return 0; \ 265 1.49 lukem memmove((to), (from), count); \ 266 1.49 lukem to[count] = '\0'; \ 267 1.49 lukem } while (0) /* LINTED */ 268 1.49 lukem 269 1.49 lukem COPYSTR(grp->gr_name, fromgrp->gr_name); 270 1.49 lukem COPYSTR(grp->gr_passwd, fromgrp->gr_passwd); 271 1.49 lukem grp->gr_gid = fromgrp->gr_gid; 272 1.49 lukem 273 1.63 sjg if (fromgrp->gr_mem == NULL) 274 1.63 sjg return 0; 275 1.63 sjg 276 1.49 lukem for (memc = 0; fromgrp->gr_mem[memc]; memc++) 277 1.49 lukem continue; 278 1.49 lukem memc++; /* for final NULL */ 279 1.49 lukem 280 1.49 lukem /* grab ALIGNed char **gr_mem from buf */ 281 1.49 lukem ep = _gr_memfrombuf(memc * sizeof(char *) + ALIGNBYTES, &buf, &buflen); 282 1.49 lukem grp->gr_mem = (char **)ALIGN(ep); 283 1.49 lukem if (grp->gr_mem == NULL) 284 1.49 lukem return 0; 285 1.49 lukem 286 1.49 lukem for (memc = 0; fromgrp->gr_mem[memc]; memc++) { 287 1.49 lukem COPYSTR(grp->gr_mem[memc], fromgrp->gr_mem[memc]); 288 1.49 lukem } 289 1.49 lukem 290 1.49 lukem #undef COPYSTR 291 1.45 elric 292 1.49 lukem grp->gr_mem[memc] = NULL; 293 1.49 lukem return 1; 294 1.49 lukem } 295 1.49 lukem 296 1.49 lukem /* 297 1.49 lukem * files methods 298 1.49 lukem */ 299 1.49 lukem 300 1.54 lukem int 301 1.54 lukem __grstart_files(struct __grstate_files *state) 302 1.45 elric { 303 1.45 elric 304 1.49 lukem _DIAGASSERT(state != NULL); 305 1.49 lukem 306 1.49 lukem if (state->fp == NULL) { 307 1.64 christos state->fp = fopen(_PATH_GROUP, "re"); 308 1.49 lukem if (state->fp == NULL) 309 1.49 lukem return NS_UNAVAIL; 310 1.49 lukem } else { 311 1.49 lukem rewind(state->fp); 312 1.49 lukem } 313 1.49 lukem return NS_SUCCESS; 314 1.1 cgd } 315 1.1 cgd 316 1.54 lukem int 317 1.54 lukem __grend_files(struct __grstate_files *state) 318 1.1 cgd { 319 1.1 cgd 320 1.49 lukem _DIAGASSERT(state != NULL); 321 1.37 lukem 322 1.49 lukem if (state->fp) { 323 1.49 lukem (void) fclose(state->fp); 324 1.49 lukem state->fp = NULL; 325 1.49 lukem } 326 1.49 lukem return NS_SUCCESS; 327 1.1 cgd } 328 1.1 cgd 329 1.49 lukem /* 330 1.54 lukem * __grscan_files 331 1.49 lukem * Scan state->fp for the next desired entry. 332 1.49 lukem * If search is zero, return the next entry. 333 1.49 lukem * If search is non-zero, look for a specific name (if name != NULL), 334 1.49 lukem * or a specific gid (if name == NULL). 335 1.57 lukem * Sets *retval to the errno if the result is not NS_SUCCESS 336 1.57 lukem * or NS_NOTFOUND. 337 1.49 lukem */ 338 1.54 lukem int 339 1.54 lukem __grscan_files(int *retval, struct group *grp, char *buffer, size_t buflen, 340 1.54 lukem struct __grstate_files *state, int search, const char *name, gid_t gid) 341 1.1 cgd { 342 1.49 lukem int rv; 343 1.52 lukem char filebuf[_GETGR_R_SIZE_MAX], *ep; 344 1.49 lukem 345 1.49 lukem _DIAGASSERT(retval != NULL); 346 1.49 lukem _DIAGASSERT(grp != NULL); 347 1.49 lukem _DIAGASSERT(buffer != NULL); 348 1.49 lukem _DIAGASSERT(state != NULL); 349 1.49 lukem /* name is NULL to indicate searching for gid */ 350 1.49 lukem 351 1.49 lukem *retval = 0; 352 1.49 lukem 353 1.49 lukem if (state->fp == NULL) { /* only start if file not open yet */ 354 1.54 lukem rv = __grstart_files(state); 355 1.49 lukem if (rv != NS_SUCCESS) 356 1.49 lukem goto filesgrscan_out; 357 1.49 lukem } 358 1.49 lukem 359 1.49 lukem rv = NS_NOTFOUND; 360 1.49 lukem 361 1.49 lukem /* scan line by line */ 362 1.65 christos while (fgets(filebuf, (int)sizeof(filebuf), state->fp) != NULL) { 363 1.49 lukem ep = strchr(filebuf, '\n'); 364 1.58 lukem if (ep == NULL) { /* skip lines that are too big */ 365 1.49 lukem int ch; 366 1.49 lukem 367 1.49 lukem while ((ch = getc(state->fp)) != '\n' && ch != EOF) 368 1.49 lukem continue; 369 1.58 lukem continue; 370 1.49 lukem } 371 1.49 lukem *ep = '\0'; /* clear trailing \n */ 372 1.49 lukem 373 1.49 lukem if (filebuf[0] == '+') /* skip compat line */ 374 1.49 lukem continue; 375 1.49 lukem 376 1.49 lukem /* validate line */ 377 1.49 lukem if (! _gr_parse(filebuf, grp, buffer, buflen)) { 378 1.58 lukem continue; /* skip bad lines */ 379 1.49 lukem } 380 1.49 lukem if (! search) { /* just want this one */ 381 1.49 lukem rv = NS_SUCCESS; 382 1.49 lukem break; 383 1.49 lukem } 384 1.49 lukem /* want specific */ 385 1.49 lukem if ((name && strcmp(name, grp->gr_name) == 0) || 386 1.49 lukem (!name && gid == grp->gr_gid)) { 387 1.49 lukem rv = NS_SUCCESS; 388 1.49 lukem break; 389 1.49 lukem } 390 1.49 lukem } 391 1.1 cgd 392 1.49 lukem filesgrscan_out: 393 1.57 lukem if (rv != NS_SUCCESS && rv != NS_NOTFOUND) 394 1.49 lukem *retval = errno; 395 1.49 lukem return rv; 396 1.1 cgd } 397 1.1 cgd 398 1.54 lukem 399 1.54 lukem static struct __grstate_files _files_state; 400 1.54 lukem /* storage for non _r functions */ 401 1.54 lukem static struct group _files_group; 402 1.54 lukem static char _files_groupbuf[_GETGR_R_SIZE_MAX]; 403 1.54 lukem 404 1.49 lukem /*ARGSUSED*/ 405 1.49 lukem static int 406 1.49 lukem _files_setgrent(void *nsrv, void *nscb, va_list ap) 407 1.1 cgd { 408 1.41 lukem 409 1.49 lukem _files_state.stayopen = 0; 410 1.54 lukem return __grstart_files(&_files_state); 411 1.36 lukem } 412 1.36 lukem 413 1.49 lukem /*ARGSUSED*/ 414 1.36 lukem static int 415 1.49 lukem _files_setgroupent(void *nsrv, void *nscb, va_list ap) 416 1.36 lukem { 417 1.49 lukem int *retval = va_arg(ap, int *); 418 1.49 lukem int stayopen = va_arg(ap, int); 419 1.41 lukem 420 1.49 lukem int rv; 421 1.49 lukem 422 1.49 lukem _files_state.stayopen = stayopen; 423 1.54 lukem rv = __grstart_files(&_files_state); 424 1.49 lukem *retval = (rv == NS_SUCCESS); 425 1.49 lukem return rv; 426 1.1 cgd } 427 1.1 cgd 428 1.49 lukem /*ARGSUSED*/ 429 1.49 lukem static int 430 1.49 lukem _files_endgrent(void *nsrv, void *nscb, va_list ap) 431 1.1 cgd { 432 1.41 lukem 433 1.49 lukem _files_state.stayopen = 0; 434 1.54 lukem return __grend_files(&_files_state); 435 1.1 cgd } 436 1.1 cgd 437 1.49 lukem /*ARGSUSED*/ 438 1.49 lukem static int 439 1.49 lukem _files_getgrent(void *nsrv, void *nscb, va_list ap) 440 1.1 cgd { 441 1.49 lukem struct group **retval = va_arg(ap, struct group **); 442 1.49 lukem 443 1.49 lukem int rv, rerror; 444 1.49 lukem 445 1.49 lukem _DIAGASSERT(retval != NULL); 446 1.41 lukem 447 1.49 lukem *retval = NULL; 448 1.54 lukem rv = __grscan_files(&rerror, &_files_group, 449 1.49 lukem _files_groupbuf, sizeof(_files_groupbuf), 450 1.49 lukem &_files_state, 0, NULL, 0); 451 1.49 lukem if (rv == NS_SUCCESS) 452 1.49 lukem *retval = &_files_group; 453 1.49 lukem return rv; 454 1.1 cgd } 455 1.1 cgd 456 1.49 lukem /*ARGSUSED*/ 457 1.49 lukem static int 458 1.56 christos _files_getgrent_r(void *nsrv, void *nscb, va_list ap) 459 1.56 christos { 460 1.56 christos int *retval = va_arg(ap, int *); 461 1.56 christos struct group *grp = va_arg(ap, struct group *); 462 1.56 christos char *buffer = va_arg(ap, char *); 463 1.56 christos size_t buflen = va_arg(ap, size_t); 464 1.56 christos struct group **result = va_arg(ap, struct group **); 465 1.56 christos 466 1.56 christos int rv; 467 1.56 christos 468 1.56 christos _DIAGASSERT(retval != NULL); 469 1.56 christos _DIAGASSERT(grp != NULL); 470 1.56 christos _DIAGASSERT(buffer != NULL); 471 1.56 christos _DIAGASSERT(result != NULL); 472 1.56 christos 473 1.56 christos rv = __grscan_files(retval, grp, buffer, buflen, 474 1.56 christos &_files_state, 0, NULL, 0); 475 1.56 christos if (rv == NS_SUCCESS) 476 1.56 christos *result = grp; 477 1.56 christos else 478 1.56 christos *result = NULL; 479 1.56 christos return rv; 480 1.56 christos } 481 1.56 christos 482 1.56 christos /*ARGSUSED*/ 483 1.56 christos static int 484 1.49 lukem _files_getgrgid(void *nsrv, void *nscb, va_list ap) 485 1.1 cgd { 486 1.49 lukem struct group **retval = va_arg(ap, struct group **); 487 1.49 lukem gid_t gid = va_arg(ap, gid_t); 488 1.49 lukem 489 1.49 lukem int rv, rerror; 490 1.49 lukem 491 1.49 lukem _DIAGASSERT(retval != NULL); 492 1.41 lukem 493 1.49 lukem *retval = NULL; 494 1.54 lukem rv = __grstart_files(&_files_state); 495 1.49 lukem if (rv != NS_SUCCESS) 496 1.49 lukem return rv; 497 1.54 lukem rv = __grscan_files(&rerror, &_files_group, 498 1.49 lukem _files_groupbuf, sizeof(_files_groupbuf), 499 1.49 lukem &_files_state, 1, NULL, gid); 500 1.49 lukem if (!_files_state.stayopen) 501 1.54 lukem __grend_files(&_files_state); 502 1.49 lukem if (rv == NS_SUCCESS) 503 1.49 lukem *retval = &_files_group; 504 1.49 lukem return rv; 505 1.1 cgd } 506 1.1 cgd 507 1.49 lukem /*ARGSUSED*/ 508 1.49 lukem static int 509 1.49 lukem _files_getgrgid_r(void *nsrv, void *nscb, va_list ap) 510 1.49 lukem { 511 1.49 lukem int *retval = va_arg(ap, int *); 512 1.49 lukem gid_t gid = va_arg(ap, gid_t); 513 1.49 lukem struct group *grp = va_arg(ap, struct group *); 514 1.49 lukem char *buffer = va_arg(ap, char *); 515 1.49 lukem size_t buflen = va_arg(ap, size_t); 516 1.49 lukem struct group **result = va_arg(ap, struct group **); 517 1.49 lukem 518 1.54 lukem struct __grstate_files state; 519 1.49 lukem int rv; 520 1.49 lukem 521 1.49 lukem _DIAGASSERT(retval != NULL); 522 1.49 lukem _DIAGASSERT(grp != NULL); 523 1.49 lukem _DIAGASSERT(buffer != NULL); 524 1.49 lukem _DIAGASSERT(result != NULL); 525 1.49 lukem 526 1.49 lukem *result = NULL; 527 1.49 lukem memset(&state, 0, sizeof(state)); 528 1.54 lukem rv = __grscan_files(retval, grp, buffer, buflen, &state, 1, NULL, gid); 529 1.54 lukem __grend_files(&state); 530 1.49 lukem if (rv == NS_SUCCESS) 531 1.49 lukem *result = grp; 532 1.49 lukem return rv; 533 1.49 lukem } 534 1.27 lukem 535 1.29 christos /*ARGSUSED*/ 536 1.27 lukem static int 537 1.49 lukem _files_getgrnam(void *nsrv, void *nscb, va_list ap) 538 1.27 lukem { 539 1.49 lukem struct group **retval = va_arg(ap, struct group **); 540 1.49 lukem const char *name = va_arg(ap, const char *); 541 1.49 lukem 542 1.49 lukem int rv, rerror; 543 1.49 lukem 544 1.49 lukem _DIAGASSERT(retval != NULL); 545 1.27 lukem 546 1.49 lukem *retval = NULL; 547 1.54 lukem rv = __grstart_files(&_files_state); 548 1.49 lukem if (rv != NS_SUCCESS) 549 1.49 lukem return rv; 550 1.54 lukem rv = __grscan_files(&rerror, &_files_group, 551 1.49 lukem _files_groupbuf, sizeof(_files_groupbuf), 552 1.49 lukem &_files_state, 1, name, 0); 553 1.49 lukem if (!_files_state.stayopen) 554 1.54 lukem __grend_files(&_files_state); 555 1.49 lukem if (rv == NS_SUCCESS) 556 1.49 lukem *retval = &_files_group; 557 1.49 lukem return rv; 558 1.49 lukem } 559 1.27 lukem 560 1.49 lukem /*ARGSUSED*/ 561 1.49 lukem static int 562 1.49 lukem _files_getgrnam_r(void *nsrv, void *nscb, va_list ap) 563 1.49 lukem { 564 1.49 lukem int *retval = va_arg(ap, int *); 565 1.49 lukem const char *name = va_arg(ap, const char *); 566 1.49 lukem struct group *grp = va_arg(ap, struct group *); 567 1.49 lukem char *buffer = va_arg(ap, char *); 568 1.49 lukem size_t buflen = va_arg(ap, size_t); 569 1.49 lukem struct group **result = va_arg(ap, struct group **); 570 1.49 lukem 571 1.54 lukem struct __grstate_files state; 572 1.49 lukem int rv; 573 1.49 lukem 574 1.49 lukem _DIAGASSERT(retval != NULL); 575 1.49 lukem _DIAGASSERT(grp != NULL); 576 1.49 lukem _DIAGASSERT(buffer != NULL); 577 1.49 lukem _DIAGASSERT(result != NULL); 578 1.49 lukem 579 1.49 lukem *result = NULL; 580 1.49 lukem memset(&state, 0, sizeof(state)); 581 1.54 lukem rv = __grscan_files(retval, grp, buffer, buflen, &state, 1, name, 0); 582 1.54 lukem __grend_files(&state); 583 1.49 lukem if (rv == NS_SUCCESS) 584 1.49 lukem *result = grp; 585 1.49 lukem return rv; 586 1.27 lukem } 587 1.27 lukem 588 1.49 lukem 589 1.27 lukem #ifdef HESIOD 590 1.49 lukem /* 591 1.49 lukem * dns methods 592 1.49 lukem */ 593 1.49 lukem 594 1.54 lukem int 595 1.54 lukem __grstart_dns(struct __grstate_dns *state) 596 1.1 cgd { 597 1.1 cgd 598 1.49 lukem _DIAGASSERT(state != NULL); 599 1.27 lukem 600 1.49 lukem state->num = 0; 601 1.49 lukem if (state->context == NULL) { /* setup Hesiod */ 602 1.49 lukem if (hesiod_init(&state->context) == -1) 603 1.49 lukem return NS_UNAVAIL; 604 1.27 lukem } 605 1.49 lukem 606 1.49 lukem return NS_SUCCESS; 607 1.27 lukem } 608 1.45 elric 609 1.54 lukem int 610 1.54 lukem __grend_dns(struct __grstate_dns *state) 611 1.45 elric { 612 1.45 elric 613 1.49 lukem _DIAGASSERT(state != NULL); 614 1.45 elric 615 1.49 lukem state->num = 0; 616 1.49 lukem if (state->context) { 617 1.49 lukem hesiod_end(state->context); 618 1.49 lukem state->context = NULL; 619 1.49 lukem } 620 1.49 lukem return NS_SUCCESS; 621 1.49 lukem } 622 1.45 elric 623 1.49 lukem /* 624 1.54 lukem * __grscan_dns 625 1.54 lukem * Search Hesiod for the next desired entry. 626 1.54 lukem * If search is zero, return the next entry. 627 1.54 lukem * If search is non-zero, look for a specific name (if name != NULL), 628 1.54 lukem * or a specific gid (if name == NULL). 629 1.49 lukem */ 630 1.54 lukem int 631 1.54 lukem __grscan_dns(int *retval, struct group *grp, char *buffer, size_t buflen, 632 1.54 lukem struct __grstate_dns *state, int search, const char *name, gid_t gid) 633 1.49 lukem { 634 1.49 lukem const char **curzone; 635 1.49 lukem char **hp, *ep; 636 1.49 lukem int rv; 637 1.49 lukem 638 1.54 lukem static const char *zones_gid_group[] = { 639 1.54 lukem "gid", 640 1.54 lukem "group", 641 1.54 lukem NULL 642 1.54 lukem }; 643 1.54 lukem 644 1.54 lukem static const char *zones_group[] = { 645 1.54 lukem "group", 646 1.54 lukem NULL 647 1.54 lukem }; 648 1.54 lukem 649 1.49 lukem _DIAGASSERT(retval != NULL); 650 1.49 lukem _DIAGASSERT(grp != NULL); 651 1.49 lukem _DIAGASSERT(buffer != NULL); 652 1.49 lukem _DIAGASSERT(state != NULL); 653 1.54 lukem /* name is NULL to indicate searching for gid */ 654 1.49 lukem 655 1.49 lukem *retval = 0; 656 1.49 lukem 657 1.49 lukem if (state->context == NULL) { /* only start if Hesiod not setup */ 658 1.54 lukem rv = __grstart_dns(state); 659 1.49 lukem if (rv != NS_SUCCESS) 660 1.49 lukem return rv; 661 1.49 lukem } 662 1.45 elric 663 1.58 lukem next_dns_entry: 664 1.49 lukem hp = NULL; 665 1.49 lukem rv = NS_NOTFOUND; 666 1.45 elric 667 1.54 lukem if (! search) { /* find next entry */ 668 1.54 lukem if (state->num == -1) /* exhausted search */ 669 1.54 lukem return NS_NOTFOUND; 670 1.54 lukem /* find group-NNN */ 671 1.54 lukem snprintf(buffer, buflen, "group-%u", state->num); 672 1.54 lukem state->num++; 673 1.54 lukem curzone = zones_group; 674 1.54 lukem } else if (name) { /* find group name */ 675 1.54 lukem snprintf(buffer, buflen, "%s", name); 676 1.54 lukem curzone = zones_group; 677 1.54 lukem } else { /* find gid */ 678 1.54 lukem snprintf(buffer, buflen, "%u", (unsigned int)gid); 679 1.54 lukem curzone = zones_gid_group; 680 1.54 lukem } 681 1.54 lukem 682 1.54 lukem for (; *curzone; curzone++) { /* search zones */ 683 1.49 lukem hp = hesiod_resolve(state->context, buffer, *curzone); 684 1.49 lukem if (hp != NULL) 685 1.49 lukem break; 686 1.49 lukem if (errno != ENOENT) { 687 1.49 lukem rv = NS_UNAVAIL; 688 1.49 lukem goto dnsgrscan_out; 689 1.45 elric } 690 1.49 lukem } 691 1.54 lukem if (*curzone == NULL) { 692 1.54 lukem if (! search) 693 1.54 lukem state->num = -1; 694 1.49 lukem goto dnsgrscan_out; 695 1.54 lukem } 696 1.45 elric 697 1.49 lukem if ((ep = strchr(hp[0], '\n')) != NULL) 698 1.49 lukem *ep = '\0'; /* clear trailing \n */ 699 1.54 lukem if (_gr_parse(hp[0], grp, buffer, buflen)) { /* validate line */ 700 1.54 lukem if (! search) { /* just want this one */ 701 1.54 lukem rv = NS_SUCCESS; 702 1.54 lukem } else if ((name && strcmp(name, grp->gr_name) == 0) || 703 1.54 lukem (!name && gid == grp->gr_gid)) { /* want specific */ 704 1.54 lukem rv = NS_SUCCESS; 705 1.54 lukem } 706 1.58 lukem } else { /* dodgy entry */ 707 1.58 lukem if (!search) { /* try again if ! searching */ 708 1.58 lukem hesiod_free_list(state->context, hp); 709 1.58 lukem goto next_dns_entry; 710 1.58 lukem } 711 1.58 lukem } 712 1.49 lukem 713 1.49 lukem dnsgrscan_out: 714 1.57 lukem if (rv != NS_SUCCESS && rv != NS_NOTFOUND) 715 1.49 lukem *retval = errno; 716 1.49 lukem if (hp) 717 1.49 lukem hesiod_free_list(state->context, hp); 718 1.49 lukem return rv; 719 1.49 lukem } 720 1.45 elric 721 1.54 lukem static struct __grstate_dns _dns_state; 722 1.54 lukem /* storage for non _r functions */ 723 1.54 lukem static struct group _dns_group; 724 1.54 lukem static char _dns_groupbuf[_GETGR_R_SIZE_MAX]; 725 1.54 lukem 726 1.49 lukem /*ARGSUSED*/ 727 1.49 lukem static int 728 1.49 lukem _dns_setgrent(void *nsrv, void *nscb, va_list ap) 729 1.49 lukem { 730 1.45 elric 731 1.49 lukem _dns_state.stayopen = 0; 732 1.54 lukem return __grstart_dns(&_dns_state); 733 1.49 lukem } 734 1.45 elric 735 1.49 lukem /*ARGSUSED*/ 736 1.49 lukem static int 737 1.49 lukem _dns_setgroupent(void *nsrv, void *nscb, va_list ap) 738 1.49 lukem { 739 1.49 lukem int *retval = va_arg(ap, int *); 740 1.49 lukem int stayopen = va_arg(ap, int); 741 1.45 elric 742 1.49 lukem int rv; 743 1.45 elric 744 1.49 lukem _dns_state.stayopen = stayopen; 745 1.54 lukem rv = __grstart_dns(&_dns_state); 746 1.49 lukem *retval = (rv == NS_SUCCESS); 747 1.49 lukem return rv; 748 1.45 elric } 749 1.27 lukem 750 1.49 lukem /*ARGSUSED*/ 751 1.49 lukem static int 752 1.49 lukem _dns_endgrent(void *nsrv, void *nscb, va_list ap) 753 1.49 lukem { 754 1.49 lukem 755 1.49 lukem _dns_state.stayopen = 0; 756 1.54 lukem return __grend_dns(&_dns_state); 757 1.49 lukem } 758 1.27 lukem 759 1.29 christos /*ARGSUSED*/ 760 1.27 lukem static int 761 1.49 lukem _dns_getgrent(void *nsrv, void *nscb, va_list ap) 762 1.27 lukem { 763 1.49 lukem struct group **retval = va_arg(ap, struct group **); 764 1.49 lukem 765 1.54 lukem int rv, rerror; 766 1.49 lukem 767 1.49 lukem _DIAGASSERT(retval != NULL); 768 1.27 lukem 769 1.49 lukem *retval = NULL; 770 1.54 lukem rv = __grscan_dns(&rerror, &_dns_group, 771 1.54 lukem _dns_groupbuf, sizeof(_dns_groupbuf), &_dns_state, 0, NULL, 0); 772 1.49 lukem if (rv == NS_SUCCESS) 773 1.49 lukem *retval = &_dns_group; 774 1.49 lukem return rv; 775 1.27 lukem } 776 1.27 lukem 777 1.29 christos /*ARGSUSED*/ 778 1.27 lukem static int 779 1.56 christos _dns_getgrent_r(void *nsrv, void *nscb, va_list ap) 780 1.56 christos { 781 1.56 christos int *retval = va_arg(ap, int *); 782 1.56 christos struct group *grp = va_arg(ap, struct group *); 783 1.56 christos char *buffer = va_arg(ap, char *); 784 1.56 christos size_t buflen = va_arg(ap, size_t); 785 1.56 christos struct group **result = va_arg(ap, struct group **); 786 1.56 christos 787 1.56 christos int rv; 788 1.56 christos 789 1.56 christos _DIAGASSERT(retval != NULL); 790 1.56 christos _DIAGASSERT(grp != NULL); 791 1.56 christos _DIAGASSERT(buffer != NULL); 792 1.56 christos _DIAGASSERT(result != NULL); 793 1.56 christos 794 1.56 christos rv = __grscan_dns(retval, grp, buffer, buflen, 795 1.56 christos &_dns_state, 0, NULL, 0); 796 1.56 christos if (rv == NS_SUCCESS) 797 1.56 christos *result = grp; 798 1.56 christos else 799 1.56 christos *result = NULL; 800 1.56 christos return rv; 801 1.56 christos } 802 1.56 christos /*ARGSUSED*/ 803 1.56 christos static int 804 1.49 lukem _dns_getgrgid(void *nsrv, void *nscb, va_list ap) 805 1.27 lukem { 806 1.49 lukem struct group **retval = va_arg(ap, struct group **); 807 1.49 lukem gid_t gid = va_arg(ap, gid_t); 808 1.49 lukem 809 1.49 lukem int rv, rerror; 810 1.27 lukem 811 1.49 lukem _DIAGASSERT(retval != NULL); 812 1.37 lukem 813 1.49 lukem *retval = NULL; 814 1.54 lukem rv = __grstart_dns(&_dns_state); 815 1.49 lukem if (rv != NS_SUCCESS) 816 1.49 lukem return rv; 817 1.54 lukem rv = __grscan_dns(&rerror, &_dns_group, 818 1.54 lukem _dns_groupbuf, sizeof(_dns_groupbuf), &_dns_state, 1, NULL, gid); 819 1.49 lukem if (!_dns_state.stayopen) 820 1.54 lukem __grend_dns(&_dns_state); 821 1.54 lukem if (rv == NS_SUCCESS) 822 1.49 lukem *retval = &_dns_group; 823 1.49 lukem return rv; 824 1.27 lukem } 825 1.27 lukem 826 1.49 lukem /*ARGSUSED*/ 827 1.49 lukem static int 828 1.49 lukem _dns_getgrgid_r(void *nsrv, void *nscb, va_list ap) 829 1.49 lukem { 830 1.49 lukem int *retval = va_arg(ap, int *); 831 1.49 lukem gid_t gid = va_arg(ap, gid_t); 832 1.49 lukem struct group *grp = va_arg(ap, struct group *); 833 1.49 lukem char *buffer = va_arg(ap, char *); 834 1.49 lukem size_t buflen = va_arg(ap, size_t); 835 1.49 lukem struct group **result = va_arg(ap, struct group **); 836 1.49 lukem 837 1.54 lukem struct __grstate_dns state; 838 1.49 lukem int rv; 839 1.49 lukem 840 1.49 lukem _DIAGASSERT(retval != NULL); 841 1.49 lukem _DIAGASSERT(grp != NULL); 842 1.49 lukem _DIAGASSERT(buffer != NULL); 843 1.49 lukem _DIAGASSERT(result != NULL); 844 1.49 lukem 845 1.49 lukem *result = NULL; 846 1.49 lukem memset(&state, 0, sizeof(state)); 847 1.54 lukem rv = __grscan_dns(retval, grp, buffer, buflen, &state, 1, NULL, gid); 848 1.54 lukem __grend_dns(&state); 849 1.54 lukem if (rv == NS_SUCCESS) 850 1.49 lukem *result = grp; 851 1.54 lukem return rv; 852 1.49 lukem } 853 1.27 lukem 854 1.49 lukem /*ARGSUSED*/ 855 1.27 lukem static int 856 1.49 lukem _dns_getgrnam(void *nsrv, void *nscb, va_list ap) 857 1.27 lukem { 858 1.49 lukem struct group **retval = va_arg(ap, struct group **); 859 1.49 lukem const char *name = va_arg(ap, const char *); 860 1.49 lukem 861 1.49 lukem int rv, rerror; 862 1.27 lukem 863 1.49 lukem _DIAGASSERT(retval != NULL); 864 1.37 lukem 865 1.49 lukem *retval = NULL; 866 1.54 lukem rv = __grstart_dns(&_dns_state); 867 1.49 lukem if (rv != NS_SUCCESS) 868 1.49 lukem return rv; 869 1.54 lukem rv = __grscan_dns(&rerror, &_dns_group, 870 1.54 lukem _dns_groupbuf, sizeof(_dns_groupbuf), &_dns_state, 1, name, 0); 871 1.49 lukem if (!_dns_state.stayopen) 872 1.54 lukem __grend_dns(&_dns_state); 873 1.54 lukem if (rv == NS_SUCCESS) 874 1.49 lukem *retval = &_dns_group; 875 1.49 lukem return rv; 876 1.27 lukem } 877 1.27 lukem 878 1.29 christos /*ARGSUSED*/ 879 1.27 lukem static int 880 1.49 lukem _dns_getgrnam_r(void *nsrv, void *nscb, va_list ap) 881 1.27 lukem { 882 1.49 lukem int *retval = va_arg(ap, int *); 883 1.49 lukem const char *name = va_arg(ap, const char *); 884 1.49 lukem struct group *grp = va_arg(ap, struct group *); 885 1.49 lukem char *buffer = va_arg(ap, char *); 886 1.49 lukem size_t buflen = va_arg(ap, size_t); 887 1.49 lukem struct group **result = va_arg(ap, struct group **); 888 1.49 lukem 889 1.54 lukem struct __grstate_dns state; 890 1.49 lukem int rv; 891 1.49 lukem 892 1.49 lukem _DIAGASSERT(retval != NULL); 893 1.49 lukem _DIAGASSERT(grp != NULL); 894 1.49 lukem _DIAGASSERT(buffer != NULL); 895 1.49 lukem _DIAGASSERT(result != NULL); 896 1.49 lukem 897 1.49 lukem *result = NULL; 898 1.49 lukem memset(&state, 0, sizeof(state)); 899 1.54 lukem rv = __grscan_dns(retval, grp, buffer, buflen, &state, 1, name, 0); 900 1.54 lukem __grend_dns(&state); 901 1.54 lukem if (rv == NS_SUCCESS) 902 1.49 lukem *result = grp; 903 1.54 lukem return rv; 904 1.49 lukem } 905 1.49 lukem 906 1.49 lukem #endif /* HESIOD */ 907 1.49 lukem 908 1.49 lukem 909 1.49 lukem #ifdef YP 910 1.49 lukem /* 911 1.49 lukem * nis methods 912 1.49 lukem */ 913 1.49 lukem 914 1.54 lukem int 915 1.54 lukem __grstart_nis(struct __grstate_nis *state) 916 1.49 lukem { 917 1.49 lukem 918 1.49 lukem _DIAGASSERT(state != NULL); 919 1.49 lukem 920 1.49 lukem state->done = 0; 921 1.49 lukem if (state->current) { 922 1.49 lukem free(state->current); 923 1.49 lukem state->current = NULL; 924 1.49 lukem } 925 1.49 lukem if (state->domain == NULL) { /* setup NIS */ 926 1.49 lukem switch (yp_get_default_domain(&state->domain)) { 927 1.49 lukem case 0: 928 1.49 lukem break; 929 1.49 lukem case YPERR_RESRC: 930 1.49 lukem return NS_TRYAGAIN; 931 1.49 lukem default: 932 1.49 lukem return NS_UNAVAIL; 933 1.49 lukem } 934 1.49 lukem } 935 1.49 lukem return NS_SUCCESS; 936 1.49 lukem } 937 1.49 lukem 938 1.54 lukem int 939 1.54 lukem __grend_nis(struct __grstate_nis *state) 940 1.49 lukem { 941 1.49 lukem 942 1.49 lukem _DIAGASSERT(state != NULL); 943 1.49 lukem 944 1.49 lukem if (state->domain) { 945 1.49 lukem state->domain = NULL; 946 1.49 lukem } 947 1.49 lukem state->done = 0; 948 1.49 lukem if (state->current) { 949 1.49 lukem free(state->current); 950 1.49 lukem state->current = NULL; 951 1.49 lukem } 952 1.49 lukem return NS_SUCCESS; 953 1.49 lukem } 954 1.49 lukem 955 1.49 lukem /* 956 1.54 lukem * __grscan_nis 957 1.54 lukem * Search NIS for the next desired entry. 958 1.54 lukem * If search is zero, return the next entry. 959 1.54 lukem * If search is non-zero, look for a specific name (if name != NULL), 960 1.54 lukem * or a specific gid (if name == NULL). 961 1.49 lukem */ 962 1.54 lukem int 963 1.54 lukem __grscan_nis(int *retval, struct group *grp, char *buffer, size_t buflen, 964 1.54 lukem struct __grstate_nis *state, int search, const char *name, gid_t gid) 965 1.49 lukem { 966 1.54 lukem const char *map; 967 1.54 lukem char *key, *data; 968 1.54 lukem int nisr, rv, keylen, datalen; 969 1.49 lukem 970 1.49 lukem _DIAGASSERT(retval != NULL); 971 1.49 lukem _DIAGASSERT(grp != NULL); 972 1.49 lukem _DIAGASSERT(buffer != NULL); 973 1.49 lukem _DIAGASSERT(state != NULL); 974 1.54 lukem /* name is NULL to indicate searching for gid */ 975 1.49 lukem 976 1.49 lukem *retval = 0; 977 1.49 lukem 978 1.49 lukem if (state->domain == NULL) { /* only start if NIS not setup */ 979 1.54 lukem rv = __grstart_nis(state); 980 1.49 lukem if (rv != NS_SUCCESS) 981 1.49 lukem return rv; 982 1.49 lukem } 983 1.49 lukem 984 1.58 lukem next_nis_entry: 985 1.54 lukem key = NULL; 986 1.49 lukem data = NULL; 987 1.54 lukem rv = NS_SUCCESS; 988 1.49 lukem 989 1.54 lukem if (! search) { /* find next entry */ 990 1.54 lukem if (state->done) /* exhausted search */ 991 1.54 lukem return NS_NOTFOUND; 992 1.54 lukem map = "group.byname"; 993 1.54 lukem if (state->current) { /* already searching */ 994 1.54 lukem nisr = yp_next(state->domain, map, 995 1.54 lukem state->current, state->currentlen, 996 1.54 lukem &key, &keylen, &data, &datalen); 997 1.54 lukem free(state->current); 998 1.54 lukem state->current = NULL; 999 1.54 lukem switch (nisr) { 1000 1.54 lukem case 0: 1001 1.54 lukem state->current = key; 1002 1.54 lukem state->currentlen = keylen; 1003 1.54 lukem key = NULL; 1004 1.54 lukem break; 1005 1.54 lukem case YPERR_NOMORE: 1006 1.54 lukem rv = NS_NOTFOUND; 1007 1.54 lukem state->done = 1; 1008 1.54 lukem break; 1009 1.54 lukem default: 1010 1.54 lukem rv = NS_UNAVAIL; 1011 1.54 lukem break; 1012 1.54 lukem } 1013 1.54 lukem } else { /* new search */ 1014 1.54 lukem if (yp_first(state->domain, map, 1015 1.54 lukem &state->current, &state->currentlen, 1016 1.54 lukem &data, &datalen)) { 1017 1.54 lukem rv = NS_UNAVAIL; 1018 1.54 lukem } 1019 1.54 lukem } 1020 1.54 lukem } else { /* search for specific item */ 1021 1.54 lukem if (name) { /* find group name */ 1022 1.54 lukem snprintf(buffer, buflen, "%s", name); 1023 1.54 lukem map = "group.byname"; 1024 1.54 lukem } else { /* find gid */ 1025 1.54 lukem snprintf(buffer, buflen, "%u", (unsigned int)gid); 1026 1.54 lukem map = "group.bygid"; 1027 1.54 lukem } 1028 1.54 lukem nisr = yp_match(state->domain, map, buffer, (int)strlen(buffer), 1029 1.54 lukem &data, &datalen); 1030 1.54 lukem switch (nisr) { 1031 1.54 lukem case 0: 1032 1.54 lukem break; 1033 1.54 lukem case YPERR_KEY: 1034 1.54 lukem rv = NS_NOTFOUND; 1035 1.54 lukem break; 1036 1.54 lukem default: 1037 1.54 lukem rv = NS_UNAVAIL; 1038 1.54 lukem break; 1039 1.54 lukem } 1040 1.54 lukem } 1041 1.54 lukem if (rv == NS_SUCCESS) { /* validate data */ 1042 1.49 lukem data[datalen] = '\0'; /* clear trailing \n */ 1043 1.54 lukem if (_gr_parse(data, grp, buffer, buflen)) { 1044 1.54 lukem if (! search) { /* just want this one */ 1045 1.54 lukem rv = NS_SUCCESS; 1046 1.54 lukem } else if ((name && strcmp(name, grp->gr_name) == 0) || 1047 1.54 lukem (!name && gid == grp->gr_gid)) { 1048 1.54 lukem /* want specific */ 1049 1.54 lukem rv = NS_SUCCESS; 1050 1.54 lukem } 1051 1.58 lukem } else { /* dodgy entry */ 1052 1.58 lukem if (!search) { /* try again if ! searching */ 1053 1.58 lukem free(data); 1054 1.58 lukem goto next_nis_entry; 1055 1.58 lukem } 1056 1.58 lukem } 1057 1.49 lukem } 1058 1.49 lukem 1059 1.57 lukem if (rv != NS_SUCCESS && rv != NS_NOTFOUND) 1060 1.49 lukem *retval = errno; 1061 1.54 lukem if (key) 1062 1.54 lukem free(key); 1063 1.49 lukem if (data) 1064 1.49 lukem free(data); 1065 1.49 lukem return rv; 1066 1.49 lukem } 1067 1.49 lukem 1068 1.54 lukem static struct __grstate_nis _nis_state; 1069 1.54 lukem /* storage for non _r functions */ 1070 1.54 lukem static struct group _nis_group; 1071 1.54 lukem static char _nis_groupbuf[_GETGR_R_SIZE_MAX]; 1072 1.54 lukem 1073 1.49 lukem /*ARGSUSED*/ 1074 1.49 lukem static int 1075 1.49 lukem _nis_setgrent(void *nsrv, void *nscb, va_list ap) 1076 1.49 lukem { 1077 1.49 lukem 1078 1.49 lukem _nis_state.stayopen = 0; 1079 1.54 lukem return __grstart_nis(&_nis_state); 1080 1.49 lukem } 1081 1.49 lukem 1082 1.49 lukem /*ARGSUSED*/ 1083 1.49 lukem static int 1084 1.49 lukem _nis_setgroupent(void *nsrv, void *nscb, va_list ap) 1085 1.49 lukem { 1086 1.49 lukem int *retval = va_arg(ap, int *); 1087 1.49 lukem int stayopen = va_arg(ap, int); 1088 1.49 lukem 1089 1.49 lukem int rv; 1090 1.49 lukem 1091 1.49 lukem _nis_state.stayopen = stayopen; 1092 1.54 lukem rv = __grstart_nis(&_nis_state); 1093 1.49 lukem *retval = (rv == NS_SUCCESS); 1094 1.49 lukem return rv; 1095 1.49 lukem } 1096 1.49 lukem 1097 1.49 lukem /*ARGSUSED*/ 1098 1.49 lukem static int 1099 1.49 lukem _nis_endgrent(void *nsrv, void *nscb, va_list ap) 1100 1.49 lukem { 1101 1.49 lukem 1102 1.54 lukem return __grend_nis(&_nis_state); 1103 1.49 lukem } 1104 1.49 lukem 1105 1.49 lukem /*ARGSUSED*/ 1106 1.49 lukem static int 1107 1.49 lukem _nis_getgrent(void *nsrv, void *nscb, va_list ap) 1108 1.49 lukem { 1109 1.49 lukem struct group **retval = va_arg(ap, struct group **); 1110 1.49 lukem 1111 1.54 lukem int rv, rerror; 1112 1.49 lukem 1113 1.49 lukem _DIAGASSERT(retval != NULL); 1114 1.49 lukem 1115 1.49 lukem *retval = NULL; 1116 1.54 lukem rv = __grscan_nis(&rerror, &_nis_group, 1117 1.54 lukem _nis_groupbuf, sizeof(_nis_groupbuf), &_nis_state, 0, NULL, 0); 1118 1.49 lukem if (rv == NS_SUCCESS) 1119 1.49 lukem *retval = &_nis_group; 1120 1.49 lukem return rv; 1121 1.49 lukem } 1122 1.49 lukem 1123 1.49 lukem /*ARGSUSED*/ 1124 1.49 lukem static int 1125 1.56 christos _nis_getgrent_r(void *nsrv, void *nscb, va_list ap) 1126 1.56 christos { 1127 1.56 christos int *retval = va_arg(ap, int *); 1128 1.56 christos struct group *grp = va_arg(ap, struct group *); 1129 1.56 christos char *buffer = va_arg(ap, char *); 1130 1.56 christos size_t buflen = va_arg(ap, size_t); 1131 1.56 christos struct group **result = va_arg(ap, struct group **); 1132 1.56 christos 1133 1.56 christos int rv; 1134 1.56 christos 1135 1.56 christos _DIAGASSERT(retval != NULL); 1136 1.56 christos _DIAGASSERT(grp != NULL); 1137 1.56 christos _DIAGASSERT(buffer != NULL); 1138 1.56 christos _DIAGASSERT(result != NULL); 1139 1.56 christos 1140 1.56 christos rv = __grscan_nis(retval, grp, buffer, buflen, 1141 1.56 christos &_nis_state, 0, NULL, 0); 1142 1.56 christos if (rv == NS_SUCCESS) 1143 1.56 christos *result = grp; 1144 1.56 christos else 1145 1.56 christos *result = NULL; 1146 1.56 christos return rv; 1147 1.56 christos } 1148 1.56 christos 1149 1.56 christos /*ARGSUSED*/ 1150 1.56 christos static int 1151 1.49 lukem _nis_getgrgid(void *nsrv, void *nscb, va_list ap) 1152 1.49 lukem { 1153 1.49 lukem struct group **retval = va_arg(ap, struct group **); 1154 1.49 lukem gid_t gid = va_arg(ap, gid_t); 1155 1.49 lukem 1156 1.49 lukem int rv, rerror; 1157 1.49 lukem 1158 1.49 lukem _DIAGASSERT(retval != NULL); 1159 1.49 lukem 1160 1.49 lukem *retval = NULL; 1161 1.54 lukem rv = __grstart_nis(&_nis_state); 1162 1.49 lukem if (rv != NS_SUCCESS) 1163 1.49 lukem return rv; 1164 1.54 lukem rv = __grscan_nis(&rerror, &_nis_group, 1165 1.54 lukem _nis_groupbuf, sizeof(_nis_groupbuf), &_nis_state, 1, NULL, gid); 1166 1.49 lukem if (!_nis_state.stayopen) 1167 1.54 lukem __grend_nis(&_nis_state); 1168 1.54 lukem if (rv == NS_SUCCESS) 1169 1.49 lukem *retval = &_nis_group; 1170 1.49 lukem return rv; 1171 1.49 lukem } 1172 1.49 lukem 1173 1.49 lukem /*ARGSUSED*/ 1174 1.49 lukem static int 1175 1.49 lukem _nis_getgrgid_r(void *nsrv, void *nscb, va_list ap) 1176 1.49 lukem { 1177 1.49 lukem int *retval = va_arg(ap, int *); 1178 1.49 lukem gid_t gid = va_arg(ap, gid_t); 1179 1.49 lukem struct group *grp = va_arg(ap, struct group *); 1180 1.49 lukem char *buffer = va_arg(ap, char *); 1181 1.49 lukem size_t buflen = va_arg(ap, size_t); 1182 1.49 lukem struct group **result = va_arg(ap, struct group **); 1183 1.49 lukem 1184 1.54 lukem struct __grstate_nis state; 1185 1.49 lukem int rv; 1186 1.49 lukem 1187 1.49 lukem _DIAGASSERT(retval != NULL); 1188 1.49 lukem _DIAGASSERT(grp != NULL); 1189 1.49 lukem _DIAGASSERT(buffer != NULL); 1190 1.49 lukem _DIAGASSERT(result != NULL); 1191 1.49 lukem 1192 1.49 lukem *result = NULL; 1193 1.66 christos /* remark: we run under a global mutex inside of this module ... */ 1194 1.66 christos if (_nis_state.stayopen) 1195 1.66 christos { /* use global state only if stayopen is set - otherwiese we would blow up getgrent_r() ... */ 1196 1.66 christos rv = __grscan_nis(retval, grp, buffer, buflen, &_nis_state, 1, NULL, gid); 1197 1.66 christos } 1198 1.66 christos else 1199 1.66 christos { 1200 1.66 christos memset(&state, 0, sizeof(state)); 1201 1.66 christos rv = __grscan_nis(retval, grp, buffer, buflen, &state, 1, NULL, gid); 1202 1.66 christos __grend_nis(&state); 1203 1.66 christos } 1204 1.54 lukem if (rv == NS_SUCCESS) 1205 1.49 lukem *result = grp; 1206 1.54 lukem return rv; 1207 1.49 lukem } 1208 1.49 lukem 1209 1.49 lukem /*ARGSUSED*/ 1210 1.49 lukem static int 1211 1.49 lukem _nis_getgrnam(void *nsrv, void *nscb, va_list ap) 1212 1.49 lukem { 1213 1.49 lukem struct group **retval = va_arg(ap, struct group **); 1214 1.49 lukem const char *name = va_arg(ap, const char *); 1215 1.49 lukem 1216 1.49 lukem int rv, rerror; 1217 1.49 lukem 1218 1.49 lukem _DIAGASSERT(retval != NULL); 1219 1.49 lukem 1220 1.49 lukem *retval = NULL; 1221 1.54 lukem rv = __grstart_nis(&_nis_state); 1222 1.49 lukem if (rv != NS_SUCCESS) 1223 1.49 lukem return rv; 1224 1.54 lukem rv = __grscan_nis(&rerror, &_nis_group, 1225 1.54 lukem _nis_groupbuf, sizeof(_nis_groupbuf), &_nis_state, 1, name, 0); 1226 1.49 lukem if (!_nis_state.stayopen) 1227 1.54 lukem __grend_nis(&_nis_state); 1228 1.54 lukem if (rv == NS_SUCCESS) 1229 1.49 lukem *retval = &_nis_group; 1230 1.49 lukem return rv; 1231 1.49 lukem } 1232 1.49 lukem 1233 1.49 lukem /*ARGSUSED*/ 1234 1.49 lukem static int 1235 1.49 lukem _nis_getgrnam_r(void *nsrv, void *nscb, va_list ap) 1236 1.49 lukem { 1237 1.49 lukem int *retval = va_arg(ap, int *); 1238 1.49 lukem const char *name = va_arg(ap, const char *); 1239 1.49 lukem struct group *grp = va_arg(ap, struct group *); 1240 1.49 lukem char *buffer = va_arg(ap, char *); 1241 1.49 lukem size_t buflen = va_arg(ap, size_t); 1242 1.49 lukem struct group **result = va_arg(ap, struct group **); 1243 1.49 lukem 1244 1.54 lukem struct __grstate_nis state; 1245 1.49 lukem int rv; 1246 1.49 lukem 1247 1.49 lukem _DIAGASSERT(retval != NULL); 1248 1.49 lukem _DIAGASSERT(grp != NULL); 1249 1.49 lukem _DIAGASSERT(buffer != NULL); 1250 1.49 lukem _DIAGASSERT(result != NULL); 1251 1.49 lukem 1252 1.49 lukem *result = NULL; 1253 1.66 christos /* remark: we run under a global mutex inside of this module ... */ 1254 1.66 christos if (_nis_state.stayopen) 1255 1.66 christos { /* use global state only if stayopen is set - otherwiese we would blow up getgrent_r() ... */ 1256 1.66 christos rv = __grscan_nis(retval, grp, buffer, buflen, &_nis_state, 1, name, 0); 1257 1.66 christos } 1258 1.66 christos else 1259 1.66 christos { 1260 1.66 christos memset(&state, 0, sizeof(state)); 1261 1.66 christos rv = __grscan_nis(retval, grp, buffer, buflen, &state, 1, name, 0); 1262 1.66 christos __grend_nis(&state); 1263 1.66 christos } 1264 1.54 lukem if (rv == NS_SUCCESS) 1265 1.49 lukem *result = grp; 1266 1.54 lukem return rv; 1267 1.49 lukem } 1268 1.49 lukem 1269 1.49 lukem #endif /* YP */ 1270 1.49 lukem 1271 1.27 lukem 1272 1.34 lukem #ifdef _GROUP_COMPAT 1273 1.49 lukem /* 1274 1.49 lukem * compat methods 1275 1.49 lukem */ 1276 1.49 lukem 1277 1.54 lukem int 1278 1.54 lukem __grstart_compat(struct __grstate_compat *state) 1279 1.49 lukem { 1280 1.49 lukem 1281 1.49 lukem _DIAGASSERT(state != NULL); 1282 1.49 lukem 1283 1.49 lukem if (state->fp == NULL) { 1284 1.64 christos state->fp = fopen(_PATH_GROUP, "re"); 1285 1.49 lukem if (state->fp == NULL) 1286 1.49 lukem return NS_UNAVAIL; 1287 1.49 lukem } else { 1288 1.49 lukem rewind(state->fp); 1289 1.49 lukem } 1290 1.49 lukem return NS_SUCCESS; 1291 1.49 lukem } 1292 1.49 lukem 1293 1.54 lukem int 1294 1.54 lukem __grend_compat(struct __grstate_compat *state) 1295 1.49 lukem { 1296 1.49 lukem 1297 1.49 lukem _DIAGASSERT(state != NULL); 1298 1.49 lukem 1299 1.49 lukem if (state->name) { 1300 1.49 lukem free(state->name); 1301 1.49 lukem state->name = NULL; 1302 1.49 lukem } 1303 1.49 lukem if (state->fp) { 1304 1.49 lukem (void) fclose(state->fp); 1305 1.49 lukem state->fp = NULL; 1306 1.49 lukem } 1307 1.49 lukem return NS_SUCCESS; 1308 1.49 lukem } 1309 1.49 lukem 1310 1.49 lukem 1311 1.49 lukem /* 1312 1.54 lukem * __grbad_compat 1313 1.49 lukem * log an error if "files" or "compat" is specified in 1314 1.49 lukem * group_compat database 1315 1.49 lukem */ 1316 1.49 lukem /*ARGSUSED*/ 1317 1.54 lukem int 1318 1.54 lukem __grbad_compat(void *nsrv, void *nscb, va_list ap) 1319 1.49 lukem { 1320 1.49 lukem static int warned; 1321 1.49 lukem 1322 1.61 christos _DIAGASSERT(nsrv != NULL); 1323 1.61 christos _DIAGASSERT(nscb != NULL); 1324 1.49 lukem 1325 1.49 lukem if (!warned) { 1326 1.49 lukem syslog(LOG_ERR, 1327 1.49 lukem "nsswitch.conf group_compat database can't use '%s'", 1328 1.54 lukem (const char *)nscb); 1329 1.49 lukem } 1330 1.49 lukem warned = 1; 1331 1.49 lukem return NS_UNAVAIL; 1332 1.49 lukem } 1333 1.49 lukem 1334 1.49 lukem /* 1335 1.54 lukem * __grscan_compat 1336 1.49 lukem * Scan state->fp for the next desired entry. 1337 1.49 lukem * If search is zero, return the next entry. 1338 1.49 lukem * If search is non-zero, look for a specific name (if name != NULL), 1339 1.49 lukem * or a specific gid (if name == NULL). 1340 1.57 lukem * Sets *retval to the errno if the result is not NS_SUCCESS or 1341 1.57 lukem * NS_NOTFOUND. 1342 1.54 lukem * 1343 1.54 lukem * searchfunc is invoked when a compat "+" lookup is required; 1344 1.54 lukem * searchcookie is passed as the first argument to searchfunc, 1345 1.54 lukem * the second argument is the group result. 1346 1.54 lukem * This should return NS_NOTFOUND when "no more groups" from compat src. 1347 1.54 lukem * If searchfunc is NULL then nsdispatch of getgrent is used. 1348 1.54 lukem * This is primarily intended for getgroupmembership(3)'s compat backend. 1349 1.49 lukem */ 1350 1.54 lukem int 1351 1.54 lukem __grscan_compat(int *retval, struct group *grp, char *buffer, size_t buflen, 1352 1.54 lukem struct __grstate_compat *state, int search, const char *name, gid_t gid, 1353 1.54 lukem int (*searchfunc)(void *, struct group **), void *searchcookie) 1354 1.49 lukem { 1355 1.49 lukem int rv; 1356 1.52 lukem char filebuf[_GETGR_R_SIZE_MAX], *ep; 1357 1.49 lukem 1358 1.49 lukem static const ns_dtab compatentdtab[] = { 1359 1.54 lukem NS_FILES_CB(__grbad_compat, "files") 1360 1.56 christos NS_DNS_CB(_dns_getgrent_r, NULL) 1361 1.56 christos NS_NIS_CB(_nis_getgrent_r, NULL) 1362 1.54 lukem NS_COMPAT_CB(__grbad_compat, "compat") 1363 1.60 christos NS_NULL_CB 1364 1.49 lukem }; 1365 1.49 lukem static const ns_dtab compatgiddtab[] = { 1366 1.54 lukem NS_FILES_CB(__grbad_compat, "files") 1367 1.49 lukem NS_DNS_CB(_dns_getgrgid_r, NULL) 1368 1.49 lukem NS_NIS_CB(_nis_getgrgid_r, NULL) 1369 1.54 lukem NS_COMPAT_CB(__grbad_compat, "compat") 1370 1.60 christos NS_NULL_CB 1371 1.49 lukem }; 1372 1.49 lukem static const ns_dtab compatnamdtab[] = { 1373 1.54 lukem NS_FILES_CB(__grbad_compat, "files") 1374 1.49 lukem NS_DNS_CB(_dns_getgrnam_r, NULL) 1375 1.49 lukem NS_NIS_CB(_nis_getgrnam_r, NULL) 1376 1.54 lukem NS_COMPAT_CB(__grbad_compat, "compat") 1377 1.60 christos NS_NULL_CB 1378 1.49 lukem }; 1379 1.27 lukem 1380 1.49 lukem _DIAGASSERT(retval != NULL); 1381 1.49 lukem _DIAGASSERT(grp != NULL); 1382 1.49 lukem _DIAGASSERT(buffer != NULL); 1383 1.49 lukem _DIAGASSERT(state != NULL); 1384 1.49 lukem /* name is NULL to indicate searching for gid */ 1385 1.49 lukem 1386 1.49 lukem *retval = 0; 1387 1.49 lukem 1388 1.49 lukem if (state->fp == NULL) { /* only start if file not open yet */ 1389 1.54 lukem rv = __grstart_compat(state); 1390 1.49 lukem if (rv != NS_SUCCESS) 1391 1.49 lukem goto compatgrscan_out; 1392 1.49 lukem } 1393 1.49 lukem rv = NS_NOTFOUND; 1394 1.27 lukem 1395 1.49 lukem for (;;) { /* loop through file */ 1396 1.49 lukem if (state->name != NULL) { 1397 1.49 lukem /* processing compat entry */ 1398 1.49 lukem int crv, cretval; 1399 1.49 lukem struct group cgrp, *cgrpres; 1400 1.49 lukem 1401 1.49 lukem if (state->name[0]) { /* specific +group: */ 1402 1.49 lukem crv = nsdispatch(NULL, compatnamdtab, 1403 1.53 lukem NSDB_GROUP_COMPAT, "getgrnam_r", 1404 1.53 lukem __nsdefaultnis, 1405 1.49 lukem &cretval, state->name, 1406 1.49 lukem &cgrp, filebuf, sizeof(filebuf), &cgrpres); 1407 1.49 lukem free(state->name); /* (only check 1 grp) */ 1408 1.49 lukem state->name = NULL; 1409 1.49 lukem } else if (!search) { /* any group */ 1410 1.54 lukem if (searchfunc) { 1411 1.54 lukem crv = searchfunc(searchcookie, 1412 1.54 lukem &cgrpres); 1413 1.54 lukem } else { 1414 1.54 lukem crv = nsdispatch(NULL, compatentdtab, 1415 1.56 christos NSDB_GROUP_COMPAT, "getgrent_r", 1416 1.54 lukem __nsdefaultnis, 1417 1.56 christos &cretval, &cgrp, filebuf, 1418 1.56 christos sizeof(filebuf), &cgrpres); 1419 1.54 lukem } 1420 1.49 lukem } else if (name) { /* specific group */ 1421 1.49 lukem crv = nsdispatch(NULL, compatnamdtab, 1422 1.53 lukem NSDB_GROUP_COMPAT, "getgrnam_r", 1423 1.53 lukem __nsdefaultnis, 1424 1.49 lukem &cretval, name, 1425 1.49 lukem &cgrp, filebuf, sizeof(filebuf), &cgrpres); 1426 1.49 lukem } else { /* specific gid */ 1427 1.49 lukem crv = nsdispatch(NULL, compatgiddtab, 1428 1.53 lukem NSDB_GROUP_COMPAT, "getgrgid_r", 1429 1.53 lukem __nsdefaultnis, 1430 1.49 lukem &cretval, gid, 1431 1.49 lukem &cgrp, filebuf, sizeof(filebuf), &cgrpres); 1432 1.49 lukem } 1433 1.49 lukem if (crv != NS_SUCCESS) { /* not found */ 1434 1.49 lukem free(state->name); 1435 1.49 lukem state->name = NULL; 1436 1.49 lukem continue; /* try next line */ 1437 1.49 lukem } 1438 1.49 lukem if (!_gr_copy(cgrpres, grp, buffer, buflen)) { 1439 1.49 lukem rv = NS_UNAVAIL; 1440 1.20 christos break; 1441 1.2 deraadt } 1442 1.49 lukem goto compatgrscan_cmpgrp; /* skip to grp test */ 1443 1.2 deraadt } 1444 1.27 lukem 1445 1.49 lukem /* get next file line */ 1446 1.65 christos if (fgets(filebuf, (int)sizeof(filebuf), state->fp) == NULL) 1447 1.49 lukem break; 1448 1.49 lukem 1449 1.49 lukem ep = strchr(filebuf, '\n'); 1450 1.58 lukem if (ep == NULL) { /* skip lines that are too big */ 1451 1.1 cgd int ch; 1452 1.1 cgd 1453 1.49 lukem while ((ch = getc(state->fp)) != '\n' && ch != EOF) 1454 1.49 lukem continue; 1455 1.58 lukem continue; 1456 1.1 cgd } 1457 1.49 lukem *ep = '\0'; /* clear trailing \n */ 1458 1.27 lukem 1459 1.49 lukem if (filebuf[0] == '+') { /* parse compat line */ 1460 1.49 lukem if (state->name) 1461 1.49 lukem free(state->name); 1462 1.49 lukem state->name = NULL; 1463 1.49 lukem switch(filebuf[1]) { 1464 1.13 phil case ':': 1465 1.13 phil case '\0': 1466 1.49 lukem state->name = strdup(""); 1467 1.13 phil break; 1468 1.13 phil default: 1469 1.49 lukem ep = strchr(filebuf + 1, ':'); 1470 1.49 lukem if (ep == NULL) 1471 1.49 lukem break; 1472 1.49 lukem *ep = '\0'; 1473 1.49 lukem state->name = strdup(filebuf + 1); 1474 1.49 lukem break; 1475 1.49 lukem } 1476 1.49 lukem if (state->name == NULL) { 1477 1.49 lukem rv = NS_UNAVAIL; 1478 1.13 phil break; 1479 1.2 deraadt } 1480 1.9 deraadt continue; 1481 1.1 cgd } 1482 1.49 lukem 1483 1.49 lukem /* validate line */ 1484 1.49 lukem if (! _gr_parse(filebuf, grp, buffer, buflen)) { 1485 1.58 lukem continue; /* skip bad lines */ 1486 1.49 lukem } 1487 1.49 lukem 1488 1.49 lukem compatgrscan_cmpgrp: 1489 1.49 lukem if (! search) { /* just want this one */ 1490 1.49 lukem rv = NS_SUCCESS; 1491 1.49 lukem break; 1492 1.49 lukem } 1493 1.49 lukem /* want specific */ 1494 1.49 lukem if ((name && strcmp(name, grp->gr_name) == 0) || 1495 1.49 lukem (!name && gid == grp->gr_gid)) { 1496 1.49 lukem rv = NS_SUCCESS; 1497 1.49 lukem break; 1498 1.49 lukem } 1499 1.49 lukem 1500 1.1 cgd } 1501 1.49 lukem 1502 1.49 lukem compatgrscan_out: 1503 1.57 lukem if (rv != NS_SUCCESS && rv != NS_NOTFOUND) 1504 1.49 lukem *retval = errno; 1505 1.49 lukem return rv; 1506 1.27 lukem } 1507 1.27 lukem 1508 1.54 lukem static struct __grstate_compat _compat_state; 1509 1.54 lukem /* storage for non _r functions */ 1510 1.54 lukem static struct group _compat_group; 1511 1.54 lukem static char _compat_groupbuf[_GETGR_R_SIZE_MAX]; 1512 1.54 lukem 1513 1.49 lukem /*ARGSUSED*/ 1514 1.27 lukem static int 1515 1.49 lukem _compat_setgrent(void *nsrv, void *nscb, va_list ap) 1516 1.27 lukem { 1517 1.31 lukem static const ns_dtab dtab[] = { 1518 1.54 lukem NS_FILES_CB(__grbad_compat, "files") 1519 1.49 lukem NS_DNS_CB(_dns_setgrent, NULL) 1520 1.49 lukem NS_NIS_CB(_nis_setgrent, NULL) 1521 1.54 lukem NS_COMPAT_CB(__grbad_compat, "compat") 1522 1.60 christos NS_NULL_CB 1523 1.27 lukem }; 1524 1.49 lukem 1525 1.49 lukem /* force group_compat setgrent() */ 1526 1.49 lukem (void) nsdispatch(NULL, dtab, NSDB_GROUP_COMPAT, "setgrent", 1527 1.53 lukem __nsdefaultnis_forceall); 1528 1.49 lukem 1529 1.49 lukem /* reset state, keep fp open */ 1530 1.49 lukem _compat_state.stayopen = 0; 1531 1.54 lukem return __grstart_compat(&_compat_state); 1532 1.49 lukem } 1533 1.49 lukem 1534 1.49 lukem /*ARGSUSED*/ 1535 1.49 lukem static int 1536 1.49 lukem _compat_setgroupent(void *nsrv, void *nscb, va_list ap) 1537 1.49 lukem { 1538 1.49 lukem int *retval = va_arg(ap, int *); 1539 1.49 lukem int stayopen = va_arg(ap, int); 1540 1.49 lukem 1541 1.49 lukem int rv; 1542 1.49 lukem 1543 1.49 lukem static const ns_dtab dtab[] = { 1544 1.54 lukem NS_FILES_CB(__grbad_compat, "files") 1545 1.49 lukem NS_DNS_CB(_dns_setgroupent, NULL) 1546 1.49 lukem NS_NIS_CB(_nis_setgroupent, NULL) 1547 1.54 lukem NS_COMPAT_CB(__grbad_compat, "compat") 1548 1.60 christos NS_NULL_CB 1549 1.32 lukem }; 1550 1.27 lukem 1551 1.49 lukem /* force group_compat setgroupent() */ 1552 1.49 lukem (void) nsdispatch(NULL, dtab, NSDB_GROUP_COMPAT, "setgroupent", 1553 1.53 lukem __nsdefaultnis_forceall, &rv, stayopen); 1554 1.49 lukem 1555 1.49 lukem _compat_state.stayopen = stayopen; 1556 1.54 lukem rv = __grstart_compat(&_compat_state); 1557 1.49 lukem *retval = (rv == NS_SUCCESS); 1558 1.49 lukem return rv; 1559 1.49 lukem } 1560 1.37 lukem 1561 1.49 lukem /*ARGSUSED*/ 1562 1.49 lukem static int 1563 1.49 lukem _compat_endgrent(void *nsrv, void *nscb, va_list ap) 1564 1.49 lukem { 1565 1.49 lukem static const ns_dtab dtab[] = { 1566 1.54 lukem NS_FILES_CB(__grbad_compat, "files") 1567 1.49 lukem NS_DNS_CB(_dns_endgrent, NULL) 1568 1.49 lukem NS_NIS_CB(_nis_endgrent, NULL) 1569 1.54 lukem NS_COMPAT_CB(__grbad_compat, "compat") 1570 1.60 christos NS_NULL_CB 1571 1.49 lukem }; 1572 1.49 lukem 1573 1.49 lukem /* force group_compat endgrent() */ 1574 1.49 lukem (void) nsdispatch(NULL, dtab, NSDB_GROUP_COMPAT, "endgrent", 1575 1.53 lukem __nsdefaultnis_forceall); 1576 1.49 lukem 1577 1.49 lukem /* reset state, close fp */ 1578 1.49 lukem _compat_state.stayopen = 0; 1579 1.54 lukem return __grend_compat(&_compat_state); 1580 1.27 lukem } 1581 1.27 lukem 1582 1.49 lukem /*ARGSUSED*/ 1583 1.49 lukem static int 1584 1.49 lukem _compat_getgrent(void *nsrv, void *nscb, va_list ap) 1585 1.49 lukem { 1586 1.49 lukem struct group **retval = va_arg(ap, struct group **); 1587 1.49 lukem 1588 1.49 lukem int rv, rerror; 1589 1.49 lukem 1590 1.49 lukem _DIAGASSERT(retval != NULL); 1591 1.49 lukem 1592 1.49 lukem *retval = NULL; 1593 1.54 lukem rv = __grscan_compat(&rerror, &_compat_group, 1594 1.49 lukem _compat_groupbuf, sizeof(_compat_groupbuf), 1595 1.54 lukem &_compat_state, 0, NULL, 0, NULL, NULL); 1596 1.49 lukem if (rv == NS_SUCCESS) 1597 1.49 lukem *retval = &_compat_group; 1598 1.49 lukem return rv; 1599 1.49 lukem } 1600 1.49 lukem 1601 1.49 lukem /*ARGSUSED*/ 1602 1.27 lukem static int 1603 1.56 christos _compat_getgrent_r(void *nsrv, void *nscb, va_list ap) 1604 1.56 christos { 1605 1.56 christos int *retval = va_arg(ap, int *); 1606 1.56 christos struct group *grp = va_arg(ap, struct group *); 1607 1.56 christos char *buffer = va_arg(ap, char *); 1608 1.56 christos size_t buflen = va_arg(ap, size_t); 1609 1.56 christos struct group **result = va_arg(ap, struct group **); 1610 1.56 christos 1611 1.56 christos int rv; 1612 1.56 christos 1613 1.56 christos _DIAGASSERT(retval != NULL); 1614 1.56 christos _DIAGASSERT(grp != NULL); 1615 1.56 christos _DIAGASSERT(buffer != NULL); 1616 1.56 christos _DIAGASSERT(result != NULL); 1617 1.56 christos 1618 1.56 christos rv = __grscan_compat(retval, grp, buffer, buflen, 1619 1.56 christos &_compat_state, 0, NULL, 0, NULL, NULL); 1620 1.56 christos if (rv == NS_SUCCESS) 1621 1.56 christos *result = grp; 1622 1.56 christos else 1623 1.56 christos *result = NULL; 1624 1.56 christos return rv; 1625 1.56 christos } 1626 1.56 christos 1627 1.56 christos /*ARGSUSED*/ 1628 1.56 christos static int 1629 1.49 lukem _compat_getgrgid(void *nsrv, void *nscb, va_list ap) 1630 1.49 lukem { 1631 1.49 lukem struct group **retval = va_arg(ap, struct group **); 1632 1.49 lukem gid_t gid = va_arg(ap, gid_t); 1633 1.49 lukem 1634 1.49 lukem int rv, rerror; 1635 1.49 lukem 1636 1.49 lukem _DIAGASSERT(retval != NULL); 1637 1.49 lukem 1638 1.49 lukem *retval = NULL; 1639 1.54 lukem rv = __grstart_compat(&_compat_state); 1640 1.49 lukem if (rv != NS_SUCCESS) 1641 1.49 lukem return rv; 1642 1.54 lukem rv = __grscan_compat(&rerror, &_compat_group, 1643 1.49 lukem _compat_groupbuf, sizeof(_compat_groupbuf), 1644 1.54 lukem &_compat_state, 1, NULL, gid, NULL, NULL); 1645 1.49 lukem if (!_compat_state.stayopen) 1646 1.54 lukem __grend_compat(&_compat_state); 1647 1.49 lukem if (rv == NS_SUCCESS) 1648 1.49 lukem *retval = &_compat_group; 1649 1.49 lukem return rv; 1650 1.49 lukem } 1651 1.49 lukem 1652 1.49 lukem /*ARGSUSED*/ 1653 1.49 lukem static int 1654 1.49 lukem _compat_getgrgid_r(void *nsrv, void *nscb, va_list ap) 1655 1.49 lukem { 1656 1.49 lukem int *retval = va_arg(ap, int *); 1657 1.49 lukem gid_t gid = va_arg(ap, gid_t); 1658 1.49 lukem struct group *grp = va_arg(ap, struct group *); 1659 1.49 lukem char *buffer = va_arg(ap, char *); 1660 1.49 lukem size_t buflen = va_arg(ap, size_t); 1661 1.49 lukem struct group **result = va_arg(ap, struct group **); 1662 1.49 lukem 1663 1.54 lukem struct __grstate_compat state; 1664 1.49 lukem int rv; 1665 1.49 lukem 1666 1.49 lukem _DIAGASSERT(retval != NULL); 1667 1.49 lukem _DIAGASSERT(grp != NULL); 1668 1.49 lukem _DIAGASSERT(buffer != NULL); 1669 1.49 lukem _DIAGASSERT(result != NULL); 1670 1.49 lukem 1671 1.49 lukem *result = NULL; 1672 1.49 lukem memset(&state, 0, sizeof(state)); 1673 1.54 lukem rv = __grscan_compat(retval, grp, buffer, buflen, &state, 1674 1.54 lukem 1, NULL, gid, NULL, NULL); 1675 1.54 lukem __grend_compat(&state); 1676 1.49 lukem if (rv == NS_SUCCESS) 1677 1.49 lukem *result = grp; 1678 1.49 lukem return rv; 1679 1.49 lukem } 1680 1.49 lukem 1681 1.49 lukem /*ARGSUSED*/ 1682 1.49 lukem static int 1683 1.49 lukem _compat_getgrnam(void *nsrv, void *nscb, va_list ap) 1684 1.49 lukem { 1685 1.49 lukem struct group **retval = va_arg(ap, struct group **); 1686 1.49 lukem const char *name = va_arg(ap, const char *); 1687 1.49 lukem 1688 1.49 lukem int rv, rerror; 1689 1.49 lukem 1690 1.49 lukem _DIAGASSERT(retval != NULL); 1691 1.49 lukem 1692 1.49 lukem *retval = NULL; 1693 1.54 lukem rv = __grstart_compat(&_compat_state); 1694 1.49 lukem if (rv != NS_SUCCESS) 1695 1.49 lukem return rv; 1696 1.54 lukem rv = __grscan_compat(&rerror, &_compat_group, 1697 1.49 lukem _compat_groupbuf, sizeof(_compat_groupbuf), 1698 1.54 lukem &_compat_state, 1, name, 0, NULL, NULL); 1699 1.49 lukem if (!_compat_state.stayopen) 1700 1.54 lukem __grend_compat(&_compat_state); 1701 1.49 lukem if (rv == NS_SUCCESS) 1702 1.49 lukem *retval = &_compat_group; 1703 1.49 lukem return rv; 1704 1.49 lukem } 1705 1.49 lukem 1706 1.49 lukem /*ARGSUSED*/ 1707 1.49 lukem static int 1708 1.49 lukem _compat_getgrnam_r(void *nsrv, void *nscb, va_list ap) 1709 1.49 lukem { 1710 1.49 lukem int *retval = va_arg(ap, int *); 1711 1.49 lukem const char *name = va_arg(ap, const char *); 1712 1.49 lukem struct group *grp = va_arg(ap, struct group *); 1713 1.49 lukem char *buffer = va_arg(ap, char *); 1714 1.49 lukem size_t buflen = va_arg(ap, size_t); 1715 1.49 lukem struct group **result = va_arg(ap, struct group **); 1716 1.49 lukem 1717 1.54 lukem struct __grstate_compat state; 1718 1.49 lukem int rv; 1719 1.49 lukem 1720 1.49 lukem _DIAGASSERT(retval != NULL); 1721 1.49 lukem _DIAGASSERT(grp != NULL); 1722 1.49 lukem _DIAGASSERT(buffer != NULL); 1723 1.49 lukem _DIAGASSERT(result != NULL); 1724 1.49 lukem 1725 1.49 lukem *result = NULL; 1726 1.49 lukem memset(&state, 0, sizeof(state)); 1727 1.54 lukem rv = __grscan_compat(retval, grp, buffer, buflen, &state, 1728 1.54 lukem 1, name, 0, NULL, NULL); 1729 1.54 lukem __grend_compat(&state); 1730 1.49 lukem if (rv == NS_SUCCESS) 1731 1.49 lukem *result = grp; 1732 1.49 lukem return rv; 1733 1.49 lukem } 1734 1.49 lukem 1735 1.49 lukem #endif /* _GROUP_COMPAT */ 1736 1.49 lukem 1737 1.49 lukem 1738 1.49 lukem /* 1739 1.49 lukem * public functions 1740 1.49 lukem */ 1741 1.49 lukem 1742 1.49 lukem struct group * 1743 1.49 lukem getgrent(void) 1744 1.27 lukem { 1745 1.49 lukem int rv; 1746 1.49 lukem struct group *retval; 1747 1.49 lukem 1748 1.49 lukem static const ns_dtab dtab[] = { 1749 1.49 lukem NS_FILES_CB(_files_getgrent, NULL) 1750 1.49 lukem NS_DNS_CB(_dns_getgrent, NULL) 1751 1.49 lukem NS_NIS_CB(_nis_getgrent, NULL) 1752 1.49 lukem NS_COMPAT_CB(_compat_getgrent, NULL) 1753 1.60 christos NS_NULL_CB 1754 1.49 lukem }; 1755 1.49 lukem 1756 1.54 lukem mutex_lock(&__grmutex); 1757 1.53 lukem rv = nsdispatch(NULL, dtab, NSDB_GROUP, "getgrent", __nsdefaultcompat, 1758 1.49 lukem &retval); 1759 1.54 lukem mutex_unlock(&__grmutex); 1760 1.57 lukem return (rv == NS_SUCCESS) ? retval : NULL; 1761 1.56 christos } 1762 1.56 christos 1763 1.56 christos int 1764 1.56 christos getgrent_r(struct group *grp, char *buffer, size_t buflen, 1765 1.56 christos struct group **result) 1766 1.56 christos { 1767 1.56 christos int rv, retval; 1768 1.56 christos 1769 1.56 christos static const ns_dtab dtab[] = { 1770 1.56 christos NS_FILES_CB(_files_getgrent_r, NULL) 1771 1.56 christos NS_DNS_CB(_dns_getgrent_r, NULL) 1772 1.56 christos NS_NIS_CB(_nis_getgrent_r, NULL) 1773 1.56 christos NS_COMPAT_CB(_compat_getgrent_r, NULL) 1774 1.60 christos NS_NULL_CB 1775 1.56 christos }; 1776 1.56 christos 1777 1.56 christos mutex_lock(&__grmutex); 1778 1.56 christos rv = nsdispatch(NULL, dtab, NSDB_GROUP, "getgrent_r", __nsdefaultcompat, 1779 1.56 christos &retval, grp, buffer, buflen, result); 1780 1.56 christos mutex_unlock(&__grmutex); 1781 1.57 lukem switch (rv) { 1782 1.57 lukem case NS_SUCCESS: 1783 1.57 lukem case NS_NOTFOUND: 1784 1.57 lukem return 0; 1785 1.57 lukem default: 1786 1.57 lukem return retval; 1787 1.57 lukem } 1788 1.49 lukem } 1789 1.49 lukem 1790 1.56 christos 1791 1.49 lukem struct group * 1792 1.49 lukem getgrgid(gid_t gid) 1793 1.49 lukem { 1794 1.49 lukem int rv; 1795 1.49 lukem struct group *retval; 1796 1.49 lukem 1797 1.49 lukem static const ns_dtab dtab[] = { 1798 1.49 lukem NS_FILES_CB(_files_getgrgid, NULL) 1799 1.49 lukem NS_DNS_CB(_dns_getgrgid, NULL) 1800 1.49 lukem NS_NIS_CB(_nis_getgrgid, NULL) 1801 1.49 lukem NS_COMPAT_CB(_compat_getgrgid, NULL) 1802 1.60 christos NS_NULL_CB 1803 1.49 lukem }; 1804 1.49 lukem 1805 1.54 lukem mutex_lock(&__grmutex); 1806 1.53 lukem rv = nsdispatch(NULL, dtab, NSDB_GROUP, "getgrgid", __nsdefaultcompat, 1807 1.49 lukem &retval, gid); 1808 1.54 lukem mutex_unlock(&__grmutex); 1809 1.49 lukem return (rv == NS_SUCCESS) ? retval : NULL; 1810 1.49 lukem } 1811 1.49 lukem 1812 1.49 lukem int 1813 1.49 lukem getgrgid_r(gid_t gid, struct group *grp, char *buffer, size_t buflen, 1814 1.49 lukem struct group **result) 1815 1.49 lukem { 1816 1.49 lukem int rv, retval; 1817 1.49 lukem 1818 1.49 lukem static const ns_dtab dtab[] = { 1819 1.49 lukem NS_FILES_CB(_files_getgrgid_r, NULL) 1820 1.49 lukem NS_DNS_CB(_dns_getgrgid_r, NULL) 1821 1.49 lukem NS_NIS_CB(_nis_getgrgid_r, NULL) 1822 1.49 lukem NS_COMPAT_CB(_compat_getgrgid_r, NULL) 1823 1.60 christos NS_NULL_CB 1824 1.49 lukem }; 1825 1.49 lukem 1826 1.49 lukem _DIAGASSERT(grp != NULL); 1827 1.49 lukem _DIAGASSERT(buffer != NULL); 1828 1.49 lukem _DIAGASSERT(result != NULL); 1829 1.49 lukem 1830 1.49 lukem *result = NULL; 1831 1.49 lukem retval = 0; 1832 1.54 lukem mutex_lock(&__grmutex); 1833 1.53 lukem rv = nsdispatch(NULL, dtab, NSDB_GROUP, "getgrgid_r", __nsdefaultcompat, 1834 1.49 lukem &retval, gid, grp, buffer, buflen, result); 1835 1.54 lukem mutex_unlock(&__grmutex); 1836 1.57 lukem switch (rv) { 1837 1.57 lukem case NS_SUCCESS: 1838 1.57 lukem case NS_NOTFOUND: 1839 1.57 lukem return 0; 1840 1.57 lukem default: 1841 1.57 lukem return retval; 1842 1.57 lukem } 1843 1.49 lukem } 1844 1.49 lukem 1845 1.49 lukem struct group * 1846 1.49 lukem getgrnam(const char *name) 1847 1.49 lukem { 1848 1.49 lukem int rv; 1849 1.49 lukem struct group *retval; 1850 1.49 lukem 1851 1.49 lukem static const ns_dtab dtab[] = { 1852 1.49 lukem NS_FILES_CB(_files_getgrnam, NULL) 1853 1.49 lukem NS_DNS_CB(_dns_getgrnam, NULL) 1854 1.49 lukem NS_NIS_CB(_nis_getgrnam, NULL) 1855 1.49 lukem NS_COMPAT_CB(_compat_getgrnam, NULL) 1856 1.60 christos NS_NULL_CB 1857 1.49 lukem }; 1858 1.49 lukem 1859 1.54 lukem mutex_lock(&__grmutex); 1860 1.53 lukem rv = nsdispatch(NULL, dtab, NSDB_GROUP, "getgrnam", __nsdefaultcompat, 1861 1.49 lukem &retval, name); 1862 1.54 lukem mutex_unlock(&__grmutex); 1863 1.49 lukem return (rv == NS_SUCCESS) ? retval : NULL; 1864 1.49 lukem } 1865 1.49 lukem 1866 1.49 lukem int 1867 1.49 lukem getgrnam_r(const char *name, struct group *grp, char *buffer, size_t buflen, 1868 1.49 lukem struct group **result) 1869 1.49 lukem { 1870 1.49 lukem int rv, retval; 1871 1.49 lukem 1872 1.49 lukem static const ns_dtab dtab[] = { 1873 1.49 lukem NS_FILES_CB(_files_getgrnam_r, NULL) 1874 1.49 lukem NS_DNS_CB(_dns_getgrnam_r, NULL) 1875 1.49 lukem NS_NIS_CB(_nis_getgrnam_r, NULL) 1876 1.49 lukem NS_COMPAT_CB(_compat_getgrnam_r, NULL) 1877 1.60 christos NS_NULL_CB 1878 1.49 lukem }; 1879 1.49 lukem 1880 1.49 lukem _DIAGASSERT(name != NULL); 1881 1.49 lukem _DIAGASSERT(grp != NULL); 1882 1.49 lukem _DIAGASSERT(buffer != NULL); 1883 1.49 lukem _DIAGASSERT(result != NULL); 1884 1.49 lukem 1885 1.49 lukem *result = NULL; 1886 1.49 lukem retval = 0; 1887 1.54 lukem mutex_lock(&__grmutex); 1888 1.53 lukem rv = nsdispatch(NULL, dtab, NSDB_GROUP, "getgrnam_r", __nsdefaultcompat, 1889 1.49 lukem &retval, name, grp, buffer, buflen, result); 1890 1.54 lukem mutex_unlock(&__grmutex); 1891 1.57 lukem switch (rv) { 1892 1.57 lukem case NS_SUCCESS: 1893 1.57 lukem case NS_NOTFOUND: 1894 1.57 lukem return 0; 1895 1.57 lukem default: 1896 1.57 lukem return retval; 1897 1.57 lukem } 1898 1.49 lukem } 1899 1.49 lukem 1900 1.49 lukem void 1901 1.49 lukem endgrent(void) 1902 1.49 lukem { 1903 1.49 lukem static const ns_dtab dtab[] = { 1904 1.49 lukem NS_FILES_CB(_files_endgrent, NULL) 1905 1.49 lukem NS_DNS_CB(_dns_endgrent, NULL) 1906 1.49 lukem NS_NIS_CB(_nis_endgrent, NULL) 1907 1.49 lukem NS_COMPAT_CB(_compat_endgrent, NULL) 1908 1.60 christos NS_NULL_CB 1909 1.49 lukem }; 1910 1.49 lukem 1911 1.54 lukem mutex_lock(&__grmutex); 1912 1.49 lukem /* force all endgrent() methods */ 1913 1.49 lukem (void) nsdispatch(NULL, dtab, NSDB_GROUP, "endgrent", 1914 1.53 lukem __nsdefaultcompat_forceall); 1915 1.54 lukem mutex_unlock(&__grmutex); 1916 1.49 lukem } 1917 1.49 lukem 1918 1.49 lukem int 1919 1.49 lukem setgroupent(int stayopen) 1920 1.49 lukem { 1921 1.49 lukem static const ns_dtab dtab[] = { 1922 1.49 lukem NS_FILES_CB(_files_setgroupent, NULL) 1923 1.49 lukem NS_DNS_CB(_dns_setgroupent, NULL) 1924 1.49 lukem NS_NIS_CB(_nis_setgroupent, NULL) 1925 1.49 lukem NS_COMPAT_CB(_compat_setgroupent, NULL) 1926 1.60 christos NS_NULL_CB 1927 1.49 lukem }; 1928 1.49 lukem int rv, retval; 1929 1.49 lukem 1930 1.54 lukem mutex_lock(&__grmutex); 1931 1.49 lukem /* force all setgroupent() methods */ 1932 1.49 lukem rv = nsdispatch(NULL, dtab, NSDB_GROUP, "setgroupent", 1933 1.53 lukem __nsdefaultcompat_forceall, &retval, stayopen); 1934 1.54 lukem mutex_unlock(&__grmutex); 1935 1.49 lukem return (rv == NS_SUCCESS) ? retval : 0; 1936 1.49 lukem } 1937 1.37 lukem 1938 1.49 lukem void 1939 1.49 lukem setgrent(void) 1940 1.49 lukem { 1941 1.49 lukem static const ns_dtab dtab[] = { 1942 1.49 lukem NS_FILES_CB(_files_setgrent, NULL) 1943 1.49 lukem NS_DNS_CB(_dns_setgrent, NULL) 1944 1.49 lukem NS_NIS_CB(_nis_setgrent, NULL) 1945 1.49 lukem NS_COMPAT_CB(_compat_setgrent, NULL) 1946 1.60 christos NS_NULL_CB 1947 1.49 lukem }; 1948 1.27 lukem 1949 1.54 lukem mutex_lock(&__grmutex); 1950 1.49 lukem /* force all setgrent() methods */ 1951 1.49 lukem (void) nsdispatch(NULL, dtab, NSDB_GROUP, "setgrent", 1952 1.53 lukem __nsdefaultcompat_forceall); 1953 1.54 lukem mutex_unlock(&__grmutex); 1954 1.1 cgd } 1955