1 /* 2 * Copyright (c) 1988, 1993 3 * The Regents of the University of California. All rights reserved. 4 * 5 * %sccs.include.redist.c% 6 */ 7 8 #if defined(LIBC_SCCS) && !defined(lint) 9 static char sccsid[] = "@(#)getpwent.c 8.2 (Berkeley) 04/27/95"; 10 #endif /* LIBC_SCCS and not lint */ 11 12 #include <sys/param.h> 13 #include <fcntl.h> 14 #include <db.h> 15 #include <syslog.h> 16 #include <pwd.h> 17 #include <utmp.h> 18 #include <errno.h> 19 #include <unistd.h> 20 #include <stdlib.h> 21 #include <string.h> 22 #include <limits.h> 23 24 /* 25 * The lookup techniques and data extraction code here must be kept 26 * in sync with that in `pwd_mkdb'. 27 */ 28 29 static struct passwd _pw_passwd; /* password structure */ 30 static DB *_pw_db; /* password database */ 31 static int _pw_keynum; /* key counter */ 32 static int _pw_stayopen; /* keep fd's open */ 33 static int __hashpw(), __initdb(); 34 35 struct passwd * 36 getpwent() 37 { 38 DBT key; 39 char bf[sizeof(_pw_keynum) + 1]; 40 41 if (!_pw_db && !__initdb()) 42 return((struct passwd *)NULL); 43 44 ++_pw_keynum; 45 bf[0] = _PW_KEYBYNUM; 46 bcopy((char *)&_pw_keynum, bf + 1, sizeof(_pw_keynum)); 47 key.data = (u_char *)bf; 48 key.size = sizeof(_pw_keynum) + 1; 49 return(__hashpw(&key) ? &_pw_passwd : (struct passwd *)NULL); 50 } 51 52 struct passwd * 53 getpwnam(name) 54 const char *name; 55 { 56 DBT key; 57 int len, rval; 58 char bf[UT_NAMESIZE + 1]; 59 60 if (!_pw_db && !__initdb()) 61 return((struct passwd *)NULL); 62 63 bf[0] = _PW_KEYBYNAME; 64 len = strlen(name); 65 bcopy(name, bf + 1, MIN(len, UT_NAMESIZE)); 66 key.data = (u_char *)bf; 67 key.size = len + 1; 68 rval = __hashpw(&key); 69 70 if (!_pw_stayopen) { 71 (void)(_pw_db->close)(_pw_db); 72 _pw_db = (DB *)NULL; 73 } 74 return(rval ? &_pw_passwd : (struct passwd *)NULL); 75 } 76 77 struct passwd * 78 getpwuid(uid) 79 uid_t uid; 80 { 81 DBT key; 82 int keyuid, rval; 83 char bf[sizeof(keyuid) + 1]; 84 85 if (!_pw_db && !__initdb()) 86 return((struct passwd *)NULL); 87 88 bf[0] = _PW_KEYBYUID; 89 keyuid = uid; 90 bcopy(&keyuid, bf + 1, sizeof(keyuid)); 91 key.data = (u_char *)bf; 92 key.size = sizeof(keyuid) + 1; 93 rval = __hashpw(&key); 94 95 if (!_pw_stayopen) { 96 (void)(_pw_db->close)(_pw_db); 97 _pw_db = (DB *)NULL; 98 } 99 return(rval ? &_pw_passwd : (struct passwd *)NULL); 100 } 101 102 int 103 setpassent(stayopen) 104 int stayopen; 105 { 106 _pw_keynum = 0; 107 _pw_stayopen = stayopen; 108 return(1); 109 } 110 111 int 112 setpwent() 113 { 114 _pw_keynum = 0; 115 _pw_stayopen = 0; 116 return(1); 117 } 118 119 void 120 endpwent() 121 { 122 _pw_keynum = 0; 123 if (_pw_db) { 124 (void)(_pw_db->close)(_pw_db); 125 _pw_db = (DB *)NULL; 126 } 127 } 128 129 static 130 __initdb() 131 { 132 static int warned; 133 char *p; 134 135 p = (geteuid()) ? _PATH_MP_DB : _PATH_SMP_DB; 136 _pw_db = dbopen(p, O_RDONLY, 0, DB_HASH, NULL); 137 if (_pw_db) 138 return(1); 139 if (!warned) 140 syslog(LOG_ERR, "%s: %m", p); 141 return(0); 142 } 143 144 static 145 __hashpw(key) 146 DBT *key; 147 { 148 register char *p, *t; 149 static u_int max; 150 static char *line; 151 DBT data; 152 153 if ((_pw_db->get)(_pw_db, key, &data, 0)) 154 return(0); 155 p = (char *)data.data; 156 if (data.size > max && !(line = realloc(line, max += 1024))) 157 return(0); 158 159 /* THIS CODE MUST MATCH THAT IN pwd_mkdb. */ 160 t = line; 161 #define EXPAND(e) e = t; while (*t++ = *p++); 162 #define SCALAR(v) memmove(&(v), p, sizeof v); p += sizeof v 163 EXPAND(_pw_passwd.pw_name); 164 EXPAND(_pw_passwd.pw_passwd); 165 SCALAR(_pw_passwd.pw_uid); 166 SCALAR(_pw_passwd.pw_gid); 167 SCALAR(_pw_passwd.pw_change); 168 EXPAND(_pw_passwd.pw_class); 169 EXPAND(_pw_passwd.pw_gecos); 170 EXPAND(_pw_passwd.pw_dir); 171 EXPAND(_pw_passwd.pw_shell); 172 SCALAR(_pw_passwd.pw_expire); 173 return(1); 174 } 175