1 /* 2 * Copyright (c) 1988 The Regents of the University of California. 3 * All rights reserved. 4 * 5 * %sccs.include.redist.c% 6 */ 7 8 #if defined(LIBC_SCCS) && !defined(lint) 9 static char sccsid[] = "@(#)getpwent.c 5.16 (Berkeley) 02/24/91"; 10 #endif /* LIBC_SCCS and not lint */ 11 12 #include <sys/param.h> 13 #include <fcntl.h> 14 #include <pwd.h> 15 #include <ndbm.h> 16 #include <utmp.h> 17 #include <errno.h> 18 #include <unistd.h> 19 #include <stdlib.h> 20 #include <string.h> 21 #include <limits.h> 22 23 static struct passwd _pw_passwd; /* password structure */ 24 static DBM *_pw_db; /* password database */ 25 static int _pw_keynum; /* key counter */ 26 static int _pw_stayopen; /* keep fd's open */ 27 static int _pw_euid; 28 static int __hashpw(), __initdb(); 29 30 struct passwd * 31 getpwent() 32 { 33 datum key; 34 int rval; 35 char bf[sizeof(_pw_keynum) + 1]; 36 37 if (!_pw_db && !__initdb()) 38 return((struct passwd *)NULL); 39 40 ++_pw_keynum; 41 bf[0] = _PW_KEYBYNUM; 42 bcopy((char *)&_pw_keynum, bf + 1, sizeof(_pw_keynum)); 43 key.dptr = bf; 44 key.dsize = sizeof(_pw_keynum) + 1; 45 rval = __hashpw(key); 46 47 /* Can't leave secure database open. */ 48 if (!_pw_euid) { 49 (void)dbm_close(_pw_db); 50 _pw_db = (DBM *)NULL; 51 } 52 return(rval ? &_pw_passwd : (struct passwd *)NULL); 53 } 54 55 struct passwd * 56 getpwnam(name) 57 const char *name; 58 { 59 datum key; 60 int len, rval; 61 char bf[UT_NAMESIZE + 1]; 62 63 if (!_pw_db && !__initdb()) 64 return((struct passwd *)NULL); 65 66 bf[0] = _PW_KEYBYNAME; 67 len = strlen(name); 68 bcopy(name, bf + 1, MIN(len, UT_NAMESIZE)); 69 key.dptr = bf; 70 key.dsize = len + 1; 71 rval = __hashpw(key); 72 73 /* Can't leave secure database open. */ 74 if (!_pw_stayopen || !_pw_euid) { 75 (void)dbm_close(_pw_db); 76 _pw_db = (DBM *)NULL; 77 } 78 return(rval ? &_pw_passwd : (struct passwd *)NULL); 79 } 80 81 struct passwd * 82 #ifdef __STDC__ 83 getpwuid(uid_t uid) 84 #else 85 getpwuid(uid) 86 int uid; 87 #endif 88 { 89 datum key; 90 int rval; 91 char bf[sizeof(uid) + 1]; 92 93 if (!_pw_db && !__initdb()) 94 return((struct passwd *)NULL); 95 96 bf[0] = _PW_KEYBYUID; 97 bcopy(&uid, bf + 1, sizeof(uid)); 98 key.dptr = bf; 99 key.dsize = sizeof(uid) + 1; 100 rval = __hashpw(key); 101 102 /* Can't leave secure database open. */ 103 if (!_pw_stayopen || !_pw_euid) { 104 (void)dbm_close(_pw_db); 105 _pw_db = (DBM *)NULL; 106 } 107 return(rval ? &_pw_passwd : (struct passwd *)NULL); 108 } 109 110 int 111 setpassent(stayopen) 112 int stayopen; 113 { 114 _pw_keynum = 0; 115 _pw_stayopen = stayopen; 116 return(1); 117 } 118 119 int 120 setpwent() 121 { 122 _pw_keynum = 0; 123 _pw_stayopen = 0; 124 return(1); 125 } 126 127 void 128 endpwent() 129 { 130 _pw_keynum = 0; 131 if (_pw_db) { 132 (void)dbm_close(_pw_db); 133 _pw_db = (DBM *)NULL; 134 } 135 } 136 137 static 138 __initdb() 139 { 140 static int warned; 141 char *p; 142 143 p = (_pw_euid = geteuid()) ? _PATH_MP_DB : _PATH_SMP_DB; 144 if (_pw_db = dbm_open(p, O_RDONLY, 0)) 145 return(1); 146 if (!warned) { 147 (void)write(STDERR_FILENO, "getpwent: ", 10); 148 (void)write(STDERR_FILENO, p, strlen(p)); 149 (void)write(STDERR_FILENO, ": ", 2); 150 p = strerror(errno); 151 (void)write(STDERR_FILENO, p, strlen(p)); 152 (void)write(STDERR_FILENO, "\n", 1); 153 warned = 1; 154 } 155 return(0); 156 } 157 158 static 159 __hashpw(key) 160 datum key; 161 { 162 register char *p, *t; 163 static u_int max; 164 static char *line; 165 datum dp; 166 167 dp = dbm_fetch(_pw_db, key); 168 if (!(p = dp.dptr)) 169 return(0); 170 if (dp.dsize > max && !(line = (char *)realloc(line, max += 1024))) 171 return(0); 172 173 t = line; 174 #define EXPAND(e) e = t; while (*t++ = *p++); 175 EXPAND(_pw_passwd.pw_name); 176 EXPAND(_pw_passwd.pw_passwd); 177 bcopy(p, (char *)&_pw_passwd.pw_uid, sizeof(int)); 178 p += sizeof(int); 179 bcopy(p, (char *)&_pw_passwd.pw_gid, sizeof(int)); 180 p += sizeof(int); 181 bcopy(p, (char *)&_pw_passwd.pw_change, sizeof(time_t)); 182 p += sizeof(time_t); 183 EXPAND(_pw_passwd.pw_class); 184 EXPAND(_pw_passwd.pw_gecos); 185 EXPAND(_pw_passwd.pw_dir); 186 EXPAND(_pw_passwd.pw_shell); 187 bcopy(p, (char *)&_pw_passwd.pw_expire, sizeof(time_t)); 188 p += sizeof(time_t); 189 return(1); 190 } 191