1/* 2 * Copyright (c) 1988, 1993 3 * The Regents of the University of California. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 3. All advertising materials mentioning features or use of this software 14 * must display the following acknowledgement: 15 * This product includes software developed by the University of 16 * California, Berkeley and its contributors. 17 * 4. Neither the name of the University nor the names of its contributors 18 * may be used to endorse or promote products derived from this software 19 * without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 * SUCH DAMAGE. 32 */ 33 34#if defined(LIBC_SCCS) && !defined(lint)
|
35static char sccsid[] = "@(#)getpwent.c 8.1 (Berkeley) 6/4/93";
|
35static char sccsid[] = "@(#)getpwent.c 8.2 (Berkeley) 4/27/95"; |
36#endif /* LIBC_SCCS and not lint */ 37 38#include <stdio.h> 39#include <sys/param.h> 40#include <fcntl.h> 41#include <db.h> 42#include <syslog.h> 43#include <pwd.h> 44#include <utmp.h> 45#include <errno.h> 46#include <unistd.h> 47#include <stdlib.h> 48#include <string.h> 49#include <limits.h> 50#include <grp.h> 51 52extern void setnetgrent __P(( char * )); 53extern int getnetgrent __P(( char **, char **, char ** )); 54extern int innetgr __P(( const char *, const char *, const char *, const char * )); 55
|
56/* 57 * The lookup techniques and data extraction code here must be kept 58 * in sync with that in `pwd_mkdb'. 59 */ 60 |
61static struct passwd _pw_passwd; /* password structure */ 62static DB *_pw_db; /* password database */ 63static int _pw_keynum; /* key counter */ 64static int _pw_stayopen; /* keep fd's open */ 65#ifdef YP 66#include <rpc/rpc.h> 67#include <rpcsvc/yp_prot.h> 68#include <rpcsvc/ypclnt.h> 69 70static struct passwd _pw_copy; 71static DBT empty = { NULL, 0 }; 72static DB *_ypcache = (DB *)NULL; 73static int _yp_exclusions = 0; 74static int _yp_enabled; /* set true when yp enabled */ 75static int _pw_stepping_yp; /* set true when stepping thru map */ 76static char _ypnam[YPMAXRECORD]; 77#define YP_HAVE_MASTER 2 78#define YP_HAVE_ADJUNCT 1 79#define YP_HAVE_NONE 0 80static int _gotmaster; 81static char *_pw_yp_domain; 82static inline int unwind __P(( char * )); 83static inline void _ypinitdb __P(( void )); 84static int _havemaster __P((char *)); 85static int _getyppass __P((struct passwd *, const char *, const char * )); 86static int _nextyppass __P((struct passwd *)); 87#endif 88static int __hashpw(), __initdb(); 89 90struct passwd * 91getpwent() 92{ 93 DBT key; 94 char bf[sizeof(_pw_keynum) + 1]; 95 int rv; 96 97 if (!_pw_db && !__initdb()) 98 return((struct passwd *)NULL); 99 100#ifdef YP 101 if(_pw_stepping_yp) { 102 _pw_passwd = _pw_copy; 103 if (unwind((char *)&_ypnam)) 104 return(&_pw_passwd); 105 } 106#endif 107tryagain: 108 109 ++_pw_keynum; 110 bf[0] = _PW_KEYBYNUM; 111 bcopy((char *)&_pw_keynum, bf + 1, sizeof(_pw_keynum)); 112 key.data = (u_char *)bf; 113 key.size = sizeof(_pw_keynum) + 1; 114 rv = __hashpw(&key); 115 if(!rv) return (struct passwd *)NULL; 116#ifdef YP 117 if(_pw_passwd.pw_name[0] == '+' || _pw_passwd.pw_name[0] == '-') { 118 bzero((char *)&_ypnam, sizeof(_ypnam)); 119 bcopy(_pw_passwd.pw_name, _ypnam, 120 strlen(_pw_passwd.pw_name)); 121 _pw_copy = _pw_passwd; 122 if (unwind((char *)&_ypnam) == 0) 123 goto tryagain; 124 else 125 return(&_pw_passwd); 126 } 127#else 128 /* Ignore YP password file entries when YP is disabled. */ 129 if(_pw_passwd.pw_name[0] == '+' || _pw_passwd.pw_name[0] == '-') { 130 goto tryagain; 131 } 132#endif 133 return(&_pw_passwd); 134} 135 136struct passwd * 137getpwnam(name) 138 const char *name; 139{ 140 DBT key; 141 int len, rval; 142 char bf[UT_NAMESIZE + 2]; 143 144 if (!_pw_db && !__initdb()) 145 return((struct passwd *)NULL); 146 147 bf[0] = _PW_KEYBYNAME; 148 len = strlen(name); 149 bcopy(name, bf + 1, MIN(len, UT_NAMESIZE)); 150 key.data = (u_char *)bf; 151 key.size = len + 1; 152 rval = __hashpw(&key); 153 154#ifdef YP 155 if (!rval && _yp_enabled) 156 rval = _getyppass(&_pw_passwd, name, "passwd.byname"); 157#endif 158 /* 159 * Prevent login attempts when YP is not enabled but YP entries 160 * are in /etc/master.passwd. 161 */ 162 if (rval && (_pw_passwd.pw_name[0] == '+'|| 163 _pw_passwd.pw_name[0] == '-')) rval = 0; 164 165 endpwent(); 166 return(rval ? &_pw_passwd : (struct passwd *)NULL); 167} 168 169struct passwd *
|
165#ifdef __STDC__
166getpwuid(uid_t uid)
167#else
|
170getpwuid(uid)
|
169 int uid;
170#endif
|
171 uid_t uid; |
172{ 173 DBT key; 174 int keyuid, rval; 175 char bf[sizeof(keyuid) + 1]; 176 177 if (!_pw_db && !__initdb()) 178 return((struct passwd *)NULL); 179 180 bf[0] = _PW_KEYBYUID; 181 keyuid = uid; 182 bcopy(&keyuid, bf + 1, sizeof(keyuid)); 183 key.data = (u_char *)bf; 184 key.size = sizeof(keyuid) + 1; 185 rval = __hashpw(&key); 186 187#ifdef YP 188 if (!rval && _yp_enabled) { 189 char ypbuf[16]; /* big enough for 32-bit uids and then some */ 190 snprintf(ypbuf, sizeof ypbuf, "%u", (unsigned)uid); 191 rval = _getyppass(&_pw_passwd, ypbuf, "passwd.byuid"); 192 } 193#endif 194 /* 195 * Prevent login attempts when YP is not enabled but YP entries 196 * are in /etc/master.passwd. 197 */ 198 if (rval && (_pw_passwd.pw_name[0] == '+'|| 199 _pw_passwd.pw_name[0] == '-')) rval = 0; 200 201 endpwent(); 202 return(rval ? &_pw_passwd : (struct passwd *)NULL); 203} 204 205int 206setpassent(stayopen) 207 int stayopen; 208{ 209 _pw_keynum = 0; 210#ifdef YP 211 _pw_stepping_yp = 0; 212#endif 213 _pw_stayopen = stayopen; 214 return(1); 215} 216 217int 218setpwent() 219{ 220 _pw_keynum = 0; 221#ifdef YP 222 _pw_stepping_yp = 0; 223#endif 224 _pw_stayopen = 0; 225 return(1); 226} 227 228void 229endpwent() 230{ 231 _pw_keynum = 0; 232#ifdef YP 233 _pw_stepping_yp = 0; 234#endif 235 if (_pw_db) { 236 (void)(_pw_db->close)(_pw_db); 237 _pw_db = (DB *)NULL; 238 } 239#ifdef YP 240 if (_ypcache) { 241 (void)(_ypcache->close)(_ypcache); 242 _ypcache = (DB *)NULL; 243 _yp_exclusions = 0; 244 } 245#endif 246} 247 248static int 249__initdb() 250{ 251 static int warned; 252 char *p; 253 254 p = (geteuid()) ? _PATH_MP_DB : _PATH_SMP_DB; 255 _pw_db = dbopen(p, O_RDONLY, 0, DB_HASH, NULL); 256 if (_pw_db) { 257#ifdef YP 258 DBT key, data; 259 char buf[] = { _PW_KEYYPENABLED }; 260 key.data = buf; 261 key.size = 1; 262 if ((_pw_db->get)(_pw_db, &key, &data, 0)) { 263 _yp_enabled = 0; 264 } else { 265 _yp_enabled = (int)*((char *)data.data) - 2; 266 /* Don't even bother with this if we aren't root. */ 267 if (!geteuid()) { 268 if (!_pw_yp_domain) 269 if (yp_get_default_domain(&_pw_yp_domain)) 270 return(1); 271 _gotmaster = _havemaster(_pw_yp_domain); 272 } else _gotmaster = YP_HAVE_NONE; 273 if (!_ypcache) 274 _ypinitdb(); 275 } 276#endif 277 return(1); 278 } 279 if (!warned++) 280 syslog(LOG_ERR, "%s: %m", p); 281 return(0); 282} 283 284static int 285__hashpw(key) 286 DBT *key; 287{ 288 register char *p, *t; 289 static u_int max; 290 static char *line; 291 DBT data; 292 293 if ((_pw_db->get)(_pw_db, key, &data, 0)) 294 return(0); 295 p = (char *)data.data; 296 if (data.size > max && !(line = realloc(line, max += 1024))) 297 return(0); 298
|
299 /* THIS CODE MUST MATCH THAT IN pwd_mkdb. */ |
300 t = line; 301#define EXPAND(e) e = t; while ( (*t++ = *p++) );
|
302#define SCALAR(v) memmove(&(v), p, sizeof v); p += sizeof v |
303 EXPAND(_pw_passwd.pw_name); 304 EXPAND(_pw_passwd.pw_passwd);
|
302 bcopy(p, (char *)&_pw_passwd.pw_uid, sizeof(int));
303 p += sizeof(int);
304 bcopy(p, (char *)&_pw_passwd.pw_gid, sizeof(int));
305 p += sizeof(int);
306 bcopy(p, (char *)&_pw_passwd.pw_change, sizeof(time_t));
307 p += sizeof(time_t);
|
305 SCALAR(_pw_passwd.pw_uid); 306 SCALAR(_pw_passwd.pw_gid); 307 SCALAR(_pw_passwd.pw_change); |
308 EXPAND(_pw_passwd.pw_class); 309 EXPAND(_pw_passwd.pw_gecos); 310 EXPAND(_pw_passwd.pw_dir); 311 EXPAND(_pw_passwd.pw_shell);
|
312 bcopy(p, (char *)&_pw_passwd.pw_expire, sizeof(time_t));
313 p += sizeof(time_t);
|
312 SCALAR(_pw_passwd.pw_expire); |
313 bcopy(p, (char *)&_pw_passwd.pw_fields, sizeof _pw_passwd.pw_fields); 314 p += sizeof _pw_passwd.pw_fields; 315 return(1); 316} 317 318#ifdef YP 319 320/* 321 * Create a DB hash database in memory. Bet you didn't know you 322 * could do a dbopen() will a NULL filename, did you. 323 */ 324static inline void _ypinitdb() 325{ 326 if (_ypcache == (DB *)NULL) 327 _ypcache = dbopen(NULL, O_RDWR, 600, DB_HASH, NULL); 328 return; 329} 330 331/* 332 * See if a user is in the blackballed list. 333 */ 334static inline int lookup(name) 335 char *name; 336{ 337 DBT key; 338 339 if (!_yp_exclusions) 340 return(0); 341 342 key.data = name; 343 key.size = strlen(name); 344 345 if ((_ypcache->get)(_ypcache, &key, &empty, 0)) { 346 return(0); 347 } 348 349 return(1); 350} 351 352/* 353 * Store a blackballed user in an in-core hash database. 354 */ 355static inline void store(key) 356 char *key; 357{ 358 DBT lkey; 359/* 360 if (lookup(key)) 361 return; 362*/ 363 364 _yp_exclusions = 1; 365 366 lkey.data = key; 367 lkey.size = strlen(key); 368 369 (void)(_ypcache->put)(_ypcache, &lkey, &empty, R_NOOVERWRITE); 370} 371 372/* 373 * Parse the + entries in the password database and do appropriate 374 * NIS lookups. While ugly to look at, this is optimized to do only 375 * as many lookups as are absolutely necessary in any given case. 376 * Basically, the getpwent() function will feed us + and - lines 377 * as they appear in the database. For + lines, we do netgroup/group 378 * and user lookups to find all usernames that match the rule and 379 * extract them from the NIS passwd maps. For - lines, we save the 380 * matching names in a database and a) exlude them, and b) make sure 381 * we don't consider them when processing other + lines that appear 382 * later. 383 */ 384static inline int unwind(grp) 385 char *grp; 386{ 387 char *user, *host, *domain; 388 static int latch = 0; 389 static struct group *gr = NULL; 390 int rv = 0; 391 392 if (grp[0] == '+') { 393 if (strlen(grp) == 1) { 394 return(_nextyppass(&_pw_passwd)); 395 } 396 if (grp[1] == '@') { 397 _pw_stepping_yp = 1; 398grpagain: 399 if (gr != NULL) { 400 if (*gr->gr_mem != NULL) { 401 if (lookup(*gr->gr_mem)) { 402 gr->gr_mem++; 403 goto grpagain; 404 } 405 rv = _getyppass(&_pw_passwd, 406 *gr->gr_mem, 407 "passwd.byname"); 408 gr->gr_mem++; 409 return(rv); 410 } else { 411 endgrent(); 412 latch = 0; 413 gr = NULL; 414 return(0); 415 } 416 } 417 if (!latch) { 418 setnetgrent(grp+2); 419 latch++; 420 } 421again: 422 if (getnetgrent(&host, &user, &domain) == NULL) { 423 if ((gr = getgrnam(grp+2)) != NULL) 424 goto grpagain; 425 latch = 0; 426 _pw_stepping_yp = 0; 427 return(0); 428 } else { 429 if (lookup(user)) 430 goto again; 431 if (_getyppass(&_pw_passwd, user, 432 "passwd.byname")) 433 return(1); 434 else 435 goto again; 436 } 437 } else { 438 if (lookup(grp+1)) 439 return(0); 440 return(_getyppass(&_pw_passwd, grp+1, "passwd.byname")); 441 } 442 } else { 443 if (grp[1] == '@') { 444 setnetgrent(grp+2); 445 rv = 0; 446 while(getnetgrent(&host, &user, &domain) != NULL) { 447 store(user); 448 rv++; 449 } 450 if (!rv && (gr = getgrnam(grp+2)) != NULL) { 451 while(gr->gr_mem) { 452 store(gr->gr_mem); 453 gr->gr_mem++; 454 } 455 } 456 } else { 457 store(grp+1); 458 } 459 } 460 return(0); 461} 462 463/* 464 * See if a user is a member of a particular group. 465 */ 466static inline int ingr(grp, name) 467 char *grp; 468 char *name; 469{ 470 register struct group *gr; 471 472 if ((gr = getgrnam(grp)) == NULL) 473 return(0); 474 475 while(*gr->gr_mem) { 476 if (!strcmp(*gr->gr_mem, name)) { 477 endgrent(); 478 return(1); 479 } 480 gr->gr_mem++; 481 } 482 483 endgrent(); 484 return(0); 485} 486 487/* 488 * Check a user against the +@netgroup/-@netgroup lines listed in 489 * the local password database. Also checks +user/-user lines. 490 * If no netgroup exists that matches +@netgroup/-@netgroup, 491 * try searching regular groups with the same name. 492 */ 493static inline int verf(name) 494 char *name; 495{ 496 DBT key; 497 char bf[sizeof(_pw_keynum) + 1]; 498 int keynum = 0; 499 500again: 501 ++keynum; 502 bf[0] = _PW_KEYYPBYNUM; 503 bcopy((char *)&keynum, bf + 1, sizeof(keynum)); 504 key.data = (u_char *)bf; 505 key.size = sizeof(keynum) + 1; 506 if (!__hashpw(&key)) { 507 /* Try again using old format */ 508 bf[0] = _PW_KEYBYNUM; 509 bcopy((char *)&keynum, bf + 1, sizeof(keynum)); 510 key.data = (u_char *)bf; 511 if (!__hashpw(&key)) 512 return(0); 513 } 514 if (_pw_passwd.pw_name[0] != '+' && (_pw_passwd.pw_name[0] != '-')) 515 goto again; 516 if (_pw_passwd.pw_name[0] == '+') { 517 if (strlen(_pw_passwd.pw_name) == 1) /* Wildcard */ 518 return(1); 519 if (_pw_passwd.pw_name[1] == '@') { 520 if ((innetgr(_pw_passwd.pw_name+2, NULL, name, 521 _pw_yp_domain) || 522 ingr(_pw_passwd.pw_name+2, name)) && !lookup(name)) 523 return(1); 524 else 525 goto again; 526 } else { 527 if (!strcmp(name, _pw_passwd.pw_name+1) && 528 !lookup(name)) 529 return(1); 530 else 531 goto again; 532 } 533 } 534 if (_pw_passwd.pw_name[0] == '-') { 535 /* Note that a minus wildcard is a no-op. */ 536 if (_pw_passwd.pw_name[1] == '@') { 537 if (innetgr(_pw_passwd.pw_name+2, NULL, name, 538 _pw_yp_domain) || 539 ingr(_pw_passwd.pw_name+2, name)) { 540 store(name); 541 return(0); 542 } else 543 goto again; 544 } else { 545 if (!strcmp(name, _pw_passwd.pw_name+1)) { 546 store(name); 547 return(0); 548 } else 549 goto again; 550 } 551 552 } 553 return(0); 554} 555 556static char * _get_adjunct_pw(name) 557 char *name; 558{ 559 static char adjunctbuf[YPMAXRECORD+2]; 560 int rval; 561 char *result; 562 int resultlen; 563 char *map = "passwd.adjunct.byname"; 564 char *s; 565 566 if ((rval = yp_match(_pw_yp_domain, map, name, strlen(name), 567 &result, &resultlen))) 568 return(NULL); 569 570 strncpy(adjunctbuf, result, resultlen); 571 adjunctbuf[resultlen] = '\0'; 572 free(result); 573 result = (char *)&adjunctbuf; 574 575 /* Don't care about the name. */ 576 if ((s = strsep(&result, ":")) == NULL) 577 return (NULL); /* name */ 578 if ((s = strsep(&result, ":")) == NULL) 579 return (NULL); /* password */ 580 581 return(s); 582} 583 584static int 585_pw_breakout_yp(struct passwd *pw, char *res, int resultlen, int master) 586{ 587 char *s, *result; 588 static char resbuf[YPMAXRECORD+2]; 589 590 /* 591 * Be triple, ultra super-duper paranoid: reject entries 592 * that start with a + or -. yp_mkdb and /var/yp/Makefile 593 * are _both_ supposed to strip these out, but you never 594 * know. 595 */ 596 if (*res == '+' || *res == '-') 597 return 0; 598 599 /* 600 * The NIS protocol definition limits the size of an NIS 601 * record to YPMAXRECORD bytes. We need to do a copy to 602 * a static buffer here since the memory pointed to by 603 * res will be free()ed when this function returns. 604 */ 605 strncpy((char *)&resbuf, res, resultlen); 606 resbuf[resultlen] = '\0'; 607 result = (char *)&resbuf; 608 609 /* 610 * XXX Sanity check: make sure all fields are valid (no NULLs). 611 * If we find a badly formatted entry, we punt. 612 */ 613 if ((s = strsep(&result, ":")) == NULL) return 0; /* name */ 614 /* 615 * We don't care what pw_fields says: we _always_ want the 616 * username returned to us by NIS. 617 */ 618 pw->pw_name = s; 619 pw->pw_fields |= _PWF_NAME; 620 621 if ((s = strsep(&result, ":")) == NULL) return 0; /* password */ 622 if(!(pw->pw_fields & _PWF_PASSWD)) { 623 /* SunOS passwd.adjunct hack */ 624 if (master == YP_HAVE_ADJUNCT && strstr(s, "##") != NULL) { 625 char *realpw; 626 realpw = _get_adjunct_pw(pw->pw_name); 627 if (realpw == NULL) 628 pw->pw_passwd = s; 629 else 630 pw->pw_passwd = realpw; 631 } else { 632 pw->pw_passwd = s; 633 } 634 pw->pw_fields |= _PWF_PASSWD; 635 } 636 637 if ((s = strsep(&result, ":")) == NULL) return 0; /* uid */ 638 if(!(pw->pw_fields & _PWF_UID)) { 639 pw->pw_uid = atoi(s); 640 pw->pw_fields |= _PWF_UID; 641 } 642 643 if ((s = strsep(&result, ":")) == NULL) return 0; /* gid */ 644 if(!(pw->pw_fields & _PWF_GID)) { 645 pw->pw_gid = atoi(s); 646 pw->pw_fields |= _PWF_GID; 647 } 648 649 if (master == YP_HAVE_MASTER) { 650 if ((s = strsep(&result, ":")) == NULL) return 0; /* class */ 651 if(!(pw->pw_fields & _PWF_CLASS)) { 652 pw->pw_class = s; 653 pw->pw_fields |= _PWF_CLASS; 654 } 655 656 if ((s = strsep(&result, ":")) == NULL) return 0; /* change */ 657 if(!(pw->pw_fields & _PWF_CHANGE)) { 658 pw->pw_change = atol(s); 659 pw->pw_fields |= _PWF_CHANGE; 660 } 661 662 if ((s = strsep(&result, ":")) == NULL) return 0; /* expire */ 663 if(!(pw->pw_fields & _PWF_EXPIRE)) { 664 pw->pw_expire = atol(s); 665 pw->pw_fields |= _PWF_EXPIRE; 666 } 667 } 668 669 if ((s = strsep(&result, ":")) == NULL) return 0; /* gecos */ 670 if(!(pw->pw_fields & _PWF_GECOS)) { 671 pw->pw_gecos = s; 672 pw->pw_fields |= _PWF_GECOS; 673 } 674 675 if ((s = strsep(&result, ":")) == NULL) return 0; /* dir */ 676 if(!(pw->pw_fields & _PWF_DIR)) { 677 pw->pw_dir = s; 678 pw->pw_fields |= _PWF_DIR; 679 } 680 681 if ((s = strsep(&result, ":")) == NULL) return 0; /* shell */ 682 if(!(pw->pw_fields & _PWF_SHELL)) { 683 pw->pw_shell = s; 684 pw->pw_fields |= _PWF_SHELL; 685 } 686 687 /* Be consistent. */ 688 if ((s = strchr(pw->pw_shell, '\n'))) *s = '\0'; 689 690 return 1; 691} 692 693static int 694_havemaster(char *_pw_yp_domain) 695{ 696 int order; 697 int rval; 698 699 if (!(rval = yp_order(_pw_yp_domain, "master.passwd.byname", &order))) 700 return(YP_HAVE_MASTER); 701 702 /* 703 * NIS+ in YP compat mode doesn't support 704 * YPPROC_ORDER -- no point in continuing. 705 */ 706 if (rval == YPERR_YPERR) 707 return(YP_HAVE_NONE); 708 709 /* master.passwd doesn't exist -- try passwd.adjunct */ 710 if (rval == YPERR_MAP) { 711 rval = yp_order(_pw_yp_domain, "passwd.adjunct.byname", &order); 712 if (!rval) 713 return(YP_HAVE_ADJUNCT); 714 } 715 716 return (YP_HAVE_NONE); 717} 718 719static int 720_getyppass(struct passwd *pw, const char *name, const char *map) 721{ 722 char *result, *s; 723 int resultlen; 724 int rv; 725 char mastermap[YPMAXRECORD]; 726 727 if(!_pw_yp_domain) { 728 if(yp_get_default_domain(&_pw_yp_domain)) 729 return 0; 730 } 731 732 sprintf(mastermap,"%s",map); 733 734 if (_gotmaster == YP_HAVE_MASTER) 735 sprintf(mastermap,"master.%s", map); 736 737 if(yp_match(_pw_yp_domain, (char *)&mastermap, name, strlen(name), 738 &result, &resultlen)) 739 return 0; 740 741 if (!_pw_stepping_yp) { 742 s = strchr(result, ':'); 743 if (s) { 744 *s = '\0'; 745 } else { 746 /* Must be a malformed entry if no colons. */ 747 free(result); 748 return(0); 749 } 750 751 if (!verf(result)) { 752 *s = ':'; 753 free(result); 754 return(0); 755 } 756 757 *s = ':'; /* Put back the colon we previously replaced with a NUL. */ 758 } 759 760 rv = _pw_breakout_yp(pw, result, resultlen, _gotmaster); 761 free(result); 762 return(rv); 763} 764 765static int 766_nextyppass(struct passwd *pw) 767{ 768 static char *key; 769 static int keylen; 770 char *lastkey, *result, *s; 771 int resultlen; 772 int rv; 773 char *map = "passwd.byname"; 774 775 if(!_pw_yp_domain) { 776 if(yp_get_default_domain(&_pw_yp_domain)) 777 return 0; 778 } 779 780 if (_gotmaster == YP_HAVE_MASTER) 781 map = "master.passwd.byname"; 782 783 if(!_pw_stepping_yp) { 784 if(key) free(key); 785 rv = yp_first(_pw_yp_domain, map, 786 &key, &keylen, &result, &resultlen); 787 if(rv) { 788 return 0; 789 } 790 _pw_stepping_yp = 1; 791 goto unpack; 792 } else { 793tryagain: 794 lastkey = key; 795 rv = yp_next(_pw_yp_domain, map, key, keylen, 796 &key, &keylen, &result, &resultlen); 797 free(lastkey); 798unpack: 799 if(rv) { 800 _pw_stepping_yp = 0; 801 return 0; 802 } 803 804 s = strchr(result, ':'); 805 if (s) { 806 *s = '\0'; 807 } else { 808 /* Must be a malformed entry if no colons. */ 809 free(result); 810 goto tryagain; 811 } 812 813 if (lookup(result)) { 814 *s = ':'; 815 free(result); 816 goto tryagain; 817 } 818 819 *s = ':'; /* Put back the colon we previously replaced with a NUL. */ 820 if (_pw_breakout_yp(pw, result, resultlen, _gotmaster)) { 821 free(result); 822 return(1); 823 } else { 824 free(result); 825 goto tryagain; 826 } 827 } 828} 829 830#endif /* YP */
|