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.1 (Berkeley) 06/04/93"; 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 static struct passwd _pw_passwd; /* password structure */ 25 static DB *_pw_db; /* password database */ 26 static int _pw_keynum; /* key counter */ 27 static int _pw_stayopen; /* keep fd's open */ 28 static int __hashpw(), __initdb(); 29 30 struct passwd * 31 getpwent() 32 { 33 DBT key; 34 char bf[sizeof(_pw_keynum) + 1]; 35 36 if (!_pw_db && !__initdb()) 37 return((struct passwd *)NULL); 38 39 ++_pw_keynum; 40 bf[0] = _PW_KEYBYNUM; 41 bcopy((char *)&_pw_keynum, bf + 1, sizeof(_pw_keynum)); 42 key.data = (u_char *)bf; 43 key.size = sizeof(_pw_keynum) + 1; 44 return(__hashpw(&key) ? &_pw_passwd : (struct passwd *)NULL); 45 } 46 47 struct passwd * 48 getpwnam(name) 49 const char *name; 50 { 51 DBT key; 52 int len, rval; 53 char bf[UT_NAMESIZE + 1]; 54 55 if (!_pw_db && !__initdb()) 56 return((struct passwd *)NULL); 57 58 bf[0] = _PW_KEYBYNAME; 59 len = strlen(name); 60 bcopy(name, bf + 1, MIN(len, UT_NAMESIZE)); 61 key.data = (u_char *)bf; 62 key.size = len + 1; 63 rval = __hashpw(&key); 64 65 if (!_pw_stayopen) { 66 (void)(_pw_db->close)(_pw_db); 67 _pw_db = (DB *)NULL; 68 } 69 return(rval ? &_pw_passwd : (struct passwd *)NULL); 70 } 71 72 struct passwd * 73 #ifdef __STDC__ 74 getpwuid(uid_t uid) 75 #else 76 getpwuid(uid) 77 int uid; 78 #endif 79 { 80 DBT key; 81 int keyuid, rval; 82 char bf[sizeof(keyuid) + 1]; 83 84 if (!_pw_db && !__initdb()) 85 return((struct passwd *)NULL); 86 87 bf[0] = _PW_KEYBYUID; 88 keyuid = uid; 89 bcopy(&keyuid, bf + 1, sizeof(keyuid)); 90 key.data = (u_char *)bf; 91 key.size = sizeof(keyuid) + 1; 92 rval = __hashpw(&key); 93 94 if (!_pw_stayopen) { 95 (void)(_pw_db->close)(_pw_db); 96 _pw_db = (DB *)NULL; 97 } 98 return(rval ? &_pw_passwd : (struct passwd *)NULL); 99 } 100 101 int 102 setpassent(stayopen) 103 int stayopen; 104 { 105 _pw_keynum = 0; 106 _pw_stayopen = stayopen; 107 return(1); 108 } 109 110 int 111 setpwent() 112 { 113 _pw_keynum = 0; 114 _pw_stayopen = 0; 115 return(1); 116 } 117 118 void 119 endpwent() 120 { 121 _pw_keynum = 0; 122 if (_pw_db) { 123 (void)(_pw_db->close)(_pw_db); 124 _pw_db = (DB *)NULL; 125 } 126 } 127 128 static 129 __initdb() 130 { 131 static int warned; 132 char *p; 133 134 p = (geteuid()) ? _PATH_MP_DB : _PATH_SMP_DB; 135 _pw_db = dbopen(p, O_RDONLY, 0, DB_HASH, NULL); 136 if (_pw_db) 137 return(1); 138 if (!warned) 139 syslog(LOG_ERR, "%s: %m", p); 140 return(0); 141 } 142 143 static 144 __hashpw(key) 145 DBT *key; 146 { 147 register char *p, *t; 148 static u_int max; 149 static char *line; 150 DBT data; 151 152 if ((_pw_db->get)(_pw_db, key, &data, 0)) 153 return(0); 154 p = (char *)data.data; 155 if (data.size > max && !(line = realloc(line, max += 1024))) 156 return(0); 157 158 t = line; 159 #define EXPAND(e) e = t; while (*t++ = *p++); 160 EXPAND(_pw_passwd.pw_name); 161 EXPAND(_pw_passwd.pw_passwd); 162 bcopy(p, (char *)&_pw_passwd.pw_uid, sizeof(int)); 163 p += sizeof(int); 164 bcopy(p, (char *)&_pw_passwd.pw_gid, sizeof(int)); 165 p += sizeof(int); 166 bcopy(p, (char *)&_pw_passwd.pw_change, sizeof(time_t)); 167 p += sizeof(time_t); 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 bcopy(p, (char *)&_pw_passwd.pw_expire, sizeof(time_t)); 173 p += sizeof(time_t); 174 return(1); 175 } 176