Thu Jun 18 21:59:24 2009 UTC ()
remove duplicated code by merging the insecure and secure database handling.
add warning flag.


(christos)
diff -r1.24 -r1.25 src/usr.sbin/pwd_mkdb/pwd_mkdb.8
diff -r1.41 -r1.42 src/usr.sbin/pwd_mkdb/pwd_mkdb.c

cvs diff -r1.24 -r1.25 src/usr.sbin/pwd_mkdb/pwd_mkdb.8 (expand / switch to unified diff)

--- src/usr.sbin/pwd_mkdb/pwd_mkdb.8 2009/06/18 17:46:24 1.24
+++ src/usr.sbin/pwd_mkdb/pwd_mkdb.8 2009/06/18 21:59:24 1.25
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1.\" $NetBSD: pwd_mkdb.8,v 1.24 2009/06/18 17:46:24 christos Exp $ 1.\" $NetBSD: pwd_mkdb.8,v 1.25 2009/06/18 21:59:24 christos Exp $
2.\" 2.\"
3.\" Copyright (c) 1991, 1993 3.\" Copyright (c) 1991, 1993
4.\" The Regents of the University of California. All rights reserved. 4.\" The Regents of the University of California. All rights reserved.
5.\" 5.\"
6.\" Redistribution and use in source and binary forms, with or without 6.\" Redistribution and use in source and binary forms, with or without
7.\" modification, are permitted provided that the following conditions 7.\" modification, are permitted provided that the following conditions
8.\" are met: 8.\" are met:
9.\" 1. Redistributions of source code must retain the above copyright 9.\" 1. Redistributions of source code must retain the above copyright
10.\" notice, this list of conditions and the following disclaimer. 10.\" notice, this list of conditions and the following disclaimer.
11.\" 2. Redistributions in binary form must reproduce the above copyright 11.\" 2. Redistributions in binary form must reproduce the above copyright
12.\" notice, this list of conditions and the following disclaimer in the 12.\" notice, this list of conditions and the following disclaimer in the
13.\" documentation and/or other materials provided with the distribution. 13.\" documentation and/or other materials provided with the distribution.
14.\" 3. Neither the name of the University nor the names of its contributors 14.\" 3. Neither the name of the University nor the names of its contributors
@@ -27,27 +27,27 @@ @@ -27,27 +27,27 @@
27.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28.\" SUCH DAMAGE. 28.\" SUCH DAMAGE.
29.\" 29.\"
30.\" from: @(#)pwd_mkdb.8 8.2 (Berkeley) 4/27/95 30.\" from: @(#)pwd_mkdb.8 8.2 (Berkeley) 4/27/95
31.\" 31.\"
32.Dd June 18, 2009 32.Dd June 18, 2009
33.Dt PWD_MKDB 8 33.Dt PWD_MKDB 8
34.Os 34.Os
35.Sh NAME 35.Sh NAME
36.Nm pwd_mkdb 36.Nm pwd_mkdb
37.Nd generate the password databases 37.Nd generate the password databases
38.Sh SYNOPSIS 38.Sh SYNOPSIS
39.Nm 39.Nm
40.Op Fl BLpsv 40.Op Fl BLpsvw
41.Op Fl c Ar cachesize 41.Op Fl c Ar cachesize
42.Op Fl d Ar directory 42.Op Fl d Ar directory
43.Op Fl u Ar username 43.Op Fl u Ar username
44.Op Fl V Ar version 44.Op Fl V Ar version
45.Ar file 45.Ar file
46.Sh DESCRIPTION 46.Sh DESCRIPTION
47.Nm 47.Nm
48creates 48creates
49.Xr db 3 49.Xr db 3
50style secure and insecure databases for the specified file. 50style secure and insecure databases for the specified file.
51These databases are then installed into 51These databases are then installed into
52.Dq Pa /etc/spwd.db 52.Dq Pa /etc/spwd.db
53and 53and
@@ -113,26 +113,28 @@ cannot read version @@ -113,26 +113,28 @@ cannot read version
113.Dv 1 113.Dv 1
114databases. 114databases.
115All versions above 115All versions above
116.Nx 5.0 116.Nx 5.0
117can read and write both version 117can read and write both version
118.Dv 0 118.Dv 0
119and version 119and version
120.Dv 1 120.Dv 1
121databases. 121databases.
122By default the databases stay in the version they were before the command 122By default the databases stay in the version they were before the command
123was run. 123was run.
124.It Fl v 124.It Fl v
125Mention when a version change occurs. 125Mention when a version change occurs.
 126.It Fl w
 127Print a warning if the system is using old style databases.
126.El 128.El
127.Pp 129.Pp
128The two databases differ in that the secure version contains the user's 130The two databases differ in that the secure version contains the user's
129encrypted password and the insecure version has an asterisk 131encrypted password and the insecure version has an asterisk
130.Pq Dq * . 132.Pq Dq * .
131.Pp 133.Pp
132The databases are used by the C library password routines (see 134The databases are used by the C library password routines (see
133.Xr getpwent 3 ) . 135.Xr getpwent 3 ) .
134.Sh EXIT STATUS 136.Sh EXIT STATUS
135.Nm 137.Nm
136exits zero on success, non-zero on failure. 138exits zero on success, non-zero on failure.
137.Sh FILES 139.Sh FILES
138.Bl -tag -width Pa -compact 140.Bl -tag -width Pa -compact

cvs diff -r1.41 -r1.42 src/usr.sbin/pwd_mkdb/pwd_mkdb.c (expand / switch to unified diff)

--- src/usr.sbin/pwd_mkdb/pwd_mkdb.c 2009/06/18 17:46:24 1.41
+++ src/usr.sbin/pwd_mkdb/pwd_mkdb.c 2009/06/18 21:59:24 1.42
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: pwd_mkdb.c,v 1.41 2009/06/18 17:46:24 christos Exp $ */ 1/* $NetBSD: pwd_mkdb.c,v 1.42 2009/06/18 21:59:24 christos Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 2000, 2009 The NetBSD Foundation, Inc. 4 * Copyright (c) 2000, 2009 The NetBSD Foundation, Inc.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * Redistribution and use in source and binary forms, with or without 7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions 8 * modification, are permitted provided that the following conditions
9 * are met: 9 * are met:
10 * 1. Redistributions of source code must retain the above copyright 10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer. 11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright 12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the 13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution. 14 * documentation and/or other materials provided with the distribution.
@@ -81,27 +81,27 @@ @@ -81,27 +81,27 @@
81 */ 81 */
82 82
83#if HAVE_NBTOOL_CONFIG_H 83#if HAVE_NBTOOL_CONFIG_H
84#include "nbtool_config.h" 84#include "nbtool_config.h"
85#endif 85#endif
86 86
87#include <sys/cdefs.h> 87#include <sys/cdefs.h>
88#if !defined(lint) 88#if !defined(lint)
89__COPYRIGHT("@(#) Copyright (c) 2000, 2009\ 89__COPYRIGHT("@(#) Copyright (c) 2000, 2009\
90 The NetBSD Foundation, Inc. All rights reserved.\ 90 The NetBSD Foundation, Inc. All rights reserved.\
91 Copyright (c) 1991, 1993, 1994\ 91 Copyright (c) 1991, 1993, 1994\
92 The Regents of the University of California. All rights reserved."); 92 The Regents of the University of California. All rights reserved.");
93__SCCSID("from: @(#)pwd_mkdb.c 8.5 (Berkeley) 4/20/94"); 93__SCCSID("from: @(#)pwd_mkdb.c 8.5 (Berkeley) 4/20/94");
94__RCSID("$NetBSD: pwd_mkdb.c,v 1.41 2009/06/18 17:46:24 christos Exp $"); 94__RCSID("$NetBSD: pwd_mkdb.c,v 1.42 2009/06/18 21:59:24 christos Exp $");
95#endif /* not lint */ 95#endif /* not lint */
96 96
97#if HAVE_NBTOOL_CONFIG_H 97#if HAVE_NBTOOL_CONFIG_H
98#include "compat_pwd.h" 98#include "compat_pwd.h"
99#else 99#else
100#include <pwd.h> 100#include <pwd.h>
101#endif 101#endif
102 102
103#include <sys/param.h> 103#include <sys/param.h>
104#include <sys/stat.h> 104#include <sys/stat.h>
105#include <sys/types.h> 105#include <sys/types.h>
106 106
107#ifndef HAVE_NBTOOL_CONFIG_H 107#ifndef HAVE_NBTOOL_CONFIG_H
@@ -136,118 +136,184 @@ extern const char __yp_token[]; @@ -136,118 +136,184 @@ extern const char __yp_token[];
136static HASHINFO openinfo = { 136static HASHINFO openinfo = {
137 4096, /* bsize */ 137 4096, /* bsize */
138 32, /* ffactor */ 138 32, /* ffactor */
139 256, /* nelem */ 139 256, /* nelem */
140 0, /* cachesize */ 140 0, /* cachesize */
141 NULL, /* hash() */ 141 NULL, /* hash() */
142 0 /* lorder */ 142 0 /* lorder */
143}; 143};
144 144
145#define FILE_INSECURE 0x01 145#define FILE_INSECURE 0x01
146#define FILE_SECURE 0x02 146#define FILE_SECURE 0x02
147#define FILE_ORIG 0x04 147#define FILE_ORIG 0x04
148 148
 149
 150struct pwddb {
 151 DB *db;
 152 char dbname[MAX(MAXPATHLEN, LINE_MAX * 2)];
 153 const char *fname;
 154 uint32_t rversion;
 155 uint32_t wversion;
 156};
 157
149static char *pname; /* password file name */ 158static char *pname; /* password file name */
150static char prefix[MAXPATHLEN]; 159static char prefix[MAXPATHLEN];
151static char oldpwdfile[MAX(MAXPATHLEN, LINE_MAX * 2)]; 160static char oldpwdfile[MAX(MAXPATHLEN, LINE_MAX * 2)];
152static char pwd_db_tmp[MAX(MAXPATHLEN, LINE_MAX * 2)]; 
153static char pwd_Sdb_tmp[MAX(MAXPATHLEN, LINE_MAX * 2)]; 
154static int lorder = BYTE_ORDER; 161static int lorder = BYTE_ORDER;
155static int clean; 162static int clean;
 163static int verbose;
 164static int warning;
 165static struct pwddb sdb, idb;
 166
156 167
157void bailout(void) __attribute__((__noreturn__)); 168void bailout(void) __attribute__((__noreturn__));
158void cp(const char *, const char *, mode_t); 169void cp(const char *, const char *, mode_t);
159int deldbent(DB *, const char *, int, void *); 170int deldbent(struct pwddb *, int, void *);
160void error(const char *); 171void error(const char *);
161int getdbent(DB *, const char *, int, void *, struct passwd **, uint32_t); 172int getdbent(struct pwddb *, int, void *, struct passwd **);
162void inconsistancy(void); 173void inconsistancy(void);
163void install(const char *, const char *); 174void install(const char *, const char *);
164int main(int, char **); 175int main(int, char **);
165void putdbents(DB *, struct passwd *, const char *, int, const char *, int, 176void putdbents(struct pwddb *, struct passwd *, const char *, int, int, int,
166 int, int, uint32_t); 177 int);
167void putyptoken(DB *, const char *); 178void putyptoken(struct pwddb *);
168void rm(const char *); 179void rm(const char *);
169int scan(FILE *, struct passwd *, int *, int *); 180int scan(FILE *, struct passwd *, int *, int *);
170void usage(void) __attribute__((__noreturn__)); 181void usage(void) __attribute__((__noreturn__));
171void wr_error(const char *); 182void wr_error(const char *);
172void checkversion(uint32_t, uint32_t); 183void checkversion(struct pwddb *);
173uint32_t getversion(const char *); 184uint32_t getversion(const char *);
174void setversion(DB *, uint32_t); 185void setversion(struct pwddb *);
175 186
176#define SWAP(sw) \ 187#define SWAP(sw) \
177 ((sizeof(sw) == 2 ? (typeof(sw))bswap16((uint16_t)sw) : \ 188 ((sizeof(sw) == 2 ? (typeof(sw))bswap16((uint16_t)sw) : \
178 (sizeof(sw) == 4 ? (typeof(sw))bswap32((uint32_t)sw) : \ 189 (sizeof(sw) == 4 ? (typeof(sw))bswap32((uint32_t)sw) : \
179 (sizeof(sw) == 8 ? (typeof(sw))bswap64((uint64_t)sw) : (abort(), 0))))) 190 (sizeof(sw) == 8 ? (typeof(sw))bswap64((uint64_t)sw) : (abort(), 0)))))
180 191
 192static void
 193closedb(struct pwddb *db)
 194{
 195 if ((*db->db->close)(db->db) < 0)
 196 wr_error(db->dbname);
 197}
 198
 199static void
 200opendb(struct pwddb *db, const char *dbname, const char *username,
 201 uint32_t req_version, int flags, int perm)
 202{
 203 char buf[MAXPATHLEN];
 204
 205 (void)snprintf(db->dbname, sizeof(db->dbname), "%s%s.tmp", prefix,
 206 dbname);
 207
 208 if (username != NULL) {
 209 snprintf(buf, sizeof(buf), "%s%s", prefix, dbname);
 210 cp(buf, db->dbname, perm);
 211 }
 212
 213 db->db = dbopen(db->dbname, flags, perm, DB_HASH, &openinfo);
 214 if (db->db == NULL)
 215 error(db->dbname);
 216
 217 db->fname = dbname;
 218 db->rversion = getversion(dbname);
 219 if (req_version == ~0U)
 220 db->wversion = db->rversion;
 221 else
 222 db->wversion = req_version;
 223
 224 if (warning && db->rversion == 0 && db->wversion == 0) {
 225 warnx("Database %s is a version %u database.",
 226 db->fname, db->rversion);
 227 warnx("Use %s -V 1 to upgrade once you've recompiled "
 228 "all your binaries.", getprogname());
 229 }
 230 if (verbose)
 231 fprintf(stderr, "%s: %s version %u requested %u\n",
 232 getprogname(), db->fname, db->rversion, db->wversion);
 233
 234 if (db->wversion != db->rversion) {
 235 if (username != NULL)
 236 checkversion(db);
 237 else if (verbose) {
 238 fprintf(stderr, "%s: changing %s from version "
 239 "%u to version %u\n",
 240 getprogname(), db->fname,
 241 db->rversion, db->wversion);
 242 }
 243 }
 244 setversion(db);
 245}
 246
181int 247int
182main(int argc, char *argv[]) 248main(int argc, char *argv[])
183{ 249{
184 int ch, makeold, tfd, lineno, found, rv, hasyp, secureonly, verbose; 250 int ch, makeold, tfd, lineno, found, rv, hasyp, secureonly;
185 struct passwd pwd, *tpwd; 251 struct passwd pwd, *tpwd;
186 char *username; 252 char *username;
187 DB *dp, *edp; 
188 FILE *fp, *oldfp; 253 FILE *fp, *oldfp;
189 sigset_t set; 254 sigset_t set;
190 int dbflg, uid_dbflg, newuser, olduid, flags; 255 int dbflg, uid_dbflg, newuser, olduid, flags;
191 char buf[MAXPATHLEN]; 
192 struct stat st; 256 struct stat st;
193 u_int cachesize; 257 u_int cachesize;
194 uint32_t version, req_version; 258 uint32_t req_version;
195 uint32_t sversion, req_sversion; 
196 259
197 prefix[0] = '\0'; 260 prefix[0] = '\0';
198 makeold = 0; 261 makeold = 0;
199 oldfp = NULL; 262 oldfp = NULL;
200 username = NULL; 263 username = NULL;
201 hasyp = 0; 264 hasyp = 0;
202 secureonly = 0; 265 secureonly = 0;
203 found = 0; 266 found = 0;
204 newuser = 0; 267 newuser = 0;
205 dp = NULL; 
206 cachesize = 0; 268 cachesize = 0;
207 verbose = 0; 269 verbose = 0;
208 req_version = req_sversion = ~0U; 270 warning = 0;
 271 req_version = ~0U;
209 272
210 while ((ch = getopt(argc, argv, "BLc:d:psu:V:v")) != -1) 273 while ((ch = getopt(argc, argv, "BLc:d:psu:V:vw")) != -1)
211 switch (ch) { 274 switch (ch) {
212 case 'B': /* big-endian output */ 275 case 'B': /* big-endian output */
213 lorder = BIG_ENDIAN; 276 lorder = BIG_ENDIAN;
214 break; 277 break;
215 case 'L': /* little-endian output */ 278 case 'L': /* little-endian output */
216 lorder = LITTLE_ENDIAN; 279 lorder = LITTLE_ENDIAN;
217 break; 280 break;
218 case 'c': 281 case 'c':
219 cachesize = atoi(optarg) * 1024 * 1024; 282 cachesize = atoi(optarg) * 1024 * 1024;
220 break; 283 break;
221 case 'd': /* set prefix */ 284 case 'd': /* set prefix */
222 strlcpy(prefix, optarg, sizeof(prefix)); 285 strlcpy(prefix, optarg, sizeof(prefix));
223 break; 286 break;
224 case 'p': /* create V7 "file.orig" */ 287 case 'p': /* create V7 "file.orig" */
225 makeold = 1; 288 makeold = 1;
226 break; 289 break;
227 case 's': /* modify secure db only */ 290 case 's': /* modify secure db only */
228 secureonly = 1; 291 secureonly = 1;
229 break; 292 break;
230 case 'u': /* modify one user only */ 293 case 'u': /* modify one user only */
231 username = optarg; 294 username = optarg;
232 break; 295 break;
233 case 'V': 296 case 'V':
234 req_sversion = req_version = (uint32_t)atoi(optarg); 297 req_version = (uint32_t)atoi(optarg);
235 if (req_version > 1) 298 if (req_version > 1)
236 err(1, "Unknown version %u\n", req_version); 299 err(1, "Unknown version %u\n", req_version);
237 break; 300 break;
238 case 'v': 301 case 'v':
239 verbose++; 302 verbose++;
240 break; 303 break;
 304 case 'w':
 305 warning++;
 306 break;
241 case '?': 307 case '?':
242 default: 308 default:
243 usage(); 309 usage();
244 } 310 }
245 argc -= optind; 311 argc -= optind;
246 argv += optind; 312 argv += optind;
247 313
248 if (argc != 1) 314 if (argc != 1)
249 usage(); 315 usage();
250 if (username != NULL) 316 if (username != NULL)
251 if (username[0] == '+' || username[0] == '-') 317 if (username[0] == '+' || username[0] == '-')
252 usage(); 318 usage();
253 if (secureonly) 319 if (secureonly)
@@ -287,110 +353,62 @@ main(int argc, char *argv[]) @@ -287,110 +353,62 @@ main(int argc, char *argv[])
287 openinfo.cachesize = cachesize; 353 openinfo.cachesize = cachesize;
288 } else { 354 } else {
289 /* Tweak openinfo values for large passwd files. */ 355 /* Tweak openinfo values for large passwd files. */
290 cachesize = st.st_size * 20; 356 cachesize = st.st_size * 20;
291 if (cachesize > MAX_CACHESIZE) 357 if (cachesize > MAX_CACHESIZE)
292 cachesize = MAX_CACHESIZE; 358 cachesize = MAX_CACHESIZE;
293 else if (cachesize < MIN_CACHESIZE) 359 else if (cachesize < MIN_CACHESIZE)
294 cachesize = MIN_CACHESIZE; 360 cachesize = MIN_CACHESIZE;
295 openinfo.cachesize = cachesize; 361 openinfo.cachesize = cachesize;
296 } 362 }
297 363
298 /* Open the temporary insecure password database. */ 364 /* Open the temporary insecure password database. */
299 if (!secureonly) { 365 if (!secureonly) {
300 (void)snprintf(pwd_db_tmp, sizeof(pwd_db_tmp), "%s%s.tmp", 366 opendb(&idb, _PATH_MP_DB, username, req_version,
301 prefix, _PATH_MP_DB); 367 flags, PERM_INSECURE);
302 if (username != NULL) { 
303 snprintf(buf, sizeof(buf), "%s" _PATH_MP_DB, prefix); 
304 cp(buf, pwd_db_tmp, PERM_INSECURE); 
305 } 
306 dp = dbopen(pwd_db_tmp, flags, PERM_INSECURE, DB_HASH, 
307 &openinfo); 
308 if (dp == NULL) 
309 error(pwd_db_tmp); 
310 clean |= FILE_INSECURE; 368 clean |= FILE_INSECURE;
311 version = getversion(_PATH_MP_DB); 
312 if (req_version == ~0U) 
313 req_version = version; 
314 if (verbose) 
315 fprintf(stderr, "%s: " _PATH_MP_DB 
316 " version %u requested %u\n", 
317 getprogname(), version, req_version); 
318 if (username != NULL && req_version != version) 
319 checkversion(req_version, version); 
320 else if (req_version != version) { 
321 if (verbose) 
322 fprintf(stderr, "%s: changing " _PATH_MP_DB 
323 " from version %u to version %u\n", 
324 getprogname(), version, req_version); 
325 setversion(dp, req_version); 
326 } 
327 } 369 }
 370
328 371
329 /* Open the temporary encrypted password database. */ 372 /* Open the temporary encrypted password database. */
330 (void)snprintf(pwd_Sdb_tmp, sizeof(pwd_Sdb_tmp), "%s%s.tmp", prefix, 373 opendb(&sdb, _PATH_SMP_DB, username, req_version, flags, PERM_SECURE);
331 _PATH_SMP_DB); 
332 if (username != NULL) { 
333 snprintf(buf, sizeof(buf), "%s" _PATH_SMP_DB, prefix); 
334 cp(buf, pwd_Sdb_tmp, PERM_SECURE); 
335 } 
336 edp = dbopen(pwd_Sdb_tmp, flags, PERM_SECURE, DB_HASH, &openinfo); 
337 if (!edp) 
338 error(pwd_Sdb_tmp); 
339 clean |= FILE_SECURE; 374 clean |= FILE_SECURE;
340 sversion = getversion(_PATH_SMP_DB); 
341 if (verbose) 
342 fprintf(stderr, "%s: " _PATH_SMP_DB 
343 " version %u requested %u\n", 
344 getprogname(), sversion, req_version); 
345 if (req_sversion == ~0U) 
346 req_sversion = sversion; 
347 if (username != NULL) 
348 checkversion(req_sversion, sversion); 
349 else if (req_sversion != sversion) { 
350 if (verbose) 
351 fprintf(stderr, "%s: changing " _PATH_SMP_DB 
352 " from version %u to version %u\n", 
353 getprogname(), sversion, req_sversion); 
354 setversion(edp, req_sversion); 
355 } 
356 375
357 /* 376 /*
358 * Open file for old password file. Minor trickiness -- don't want to 377 * Open file for old password file. Minor trickiness -- don't want to
359 * chance the file already existing, since someone (stupidly) might 378 * chance the file already existing, since someone (stupidly) might
360 * still be using this for permission checking. So, open it first and 379 * still be using this for permission checking. So, open it first and
361 * fdopen the resulting fd. The resulting file should be readable by 380 * fdopen the resulting fd. The resulting file should be readable by
362 * everyone. 381 * everyone.
363 */ 382 */
364 if (makeold) { 383 if (makeold) {
365 (void)snprintf(oldpwdfile, sizeof(oldpwdfile), "%s.orig", 384 (void)snprintf(oldpwdfile, sizeof(oldpwdfile), "%s.orig",
366 pname); 385 pname);
367 if ((tfd = open(oldpwdfile, O_WRONLY | O_CREAT | O_EXCL, 386 if ((tfd = open(oldpwdfile, O_WRONLY | O_CREAT | O_EXCL,
368 PERM_INSECURE)) < 0) 387 PERM_INSECURE)) < 0)
369 error(oldpwdfile); 388 error(oldpwdfile);
370 clean |= FILE_ORIG; 389 clean |= FILE_ORIG;
371 if ((oldfp = fdopen(tfd, "w")) == NULL) 390 if ((oldfp = fdopen(tfd, "w")) == NULL)
372 error(oldpwdfile); 391 error(oldpwdfile);
373 } 392 }
374 393
375 if (username != NULL) { 394 if (username != NULL) {
376 uid_dbflg = 0; 395 uid_dbflg = 0;
377 dbflg = 0; 396 dbflg = 0;
378 397
379 /* 398 /*
380 * Determine if this is a new entry. 399 * Determine if this is a new entry.
381 */ 400 */
382 if (getdbent(edp, pwd_Sdb_tmp, _PW_KEYBYNAME, username, &tpwd, 401 if (getdbent(&sdb, _PW_KEYBYNAME, username, &tpwd))
383 sversion)) 
384 newuser = 1; 402 newuser = 1;
385 else { 403 else {
386 newuser = 0; 404 newuser = 0;
387 olduid = tpwd->pw_uid; 405 olduid = tpwd->pw_uid;
388 } 406 }
389 407
390 } else { 408 } else {
391 uid_dbflg = R_NOOVERWRITE; 409 uid_dbflg = R_NOOVERWRITE;
392 dbflg = R_NOOVERWRITE; 410 dbflg = R_NOOVERWRITE;
393 } 411 }
394 412
395 /* 413 /*
396 * If we see something go by that looks like YP, we save a special 414 * If we see something go by that looks like YP, we save a special
@@ -418,127 +436,121 @@ main(int argc, char *argv[]) @@ -418,127 +436,121 @@ main(int argc, char *argv[])
418 if (pwd.pw_name[0] == '+') { 436 if (pwd.pw_name[0] == '+') {
419 if ((flags & _PASSWORD_NOUID) == 0 && 437 if ((flags & _PASSWORD_NOUID) == 0 &&
420 pwd.pw_uid == 0) 438 pwd.pw_uid == 0)
421 warnx("line %d: superuser override " 439 warnx("line %d: superuser override "
422 "in YP inclusion", lineno); 440 "in YP inclusion", lineno);
423 if ((flags & _PASSWORD_NOGID) == 0 && 441 if ((flags & _PASSWORD_NOGID) == 0 &&
424 pwd.pw_gid == 0) 442 pwd.pw_gid == 0)
425 warnx("line %d: wheel override " 443 warnx("line %d: wheel override "
426 "in YP inclusion", lineno); 444 "in YP inclusion", lineno);
427 } 445 }
428 446
429 /* Write the database entry out. */ 447 /* Write the database entry out. */
430 if (!secureonly) 448 if (!secureonly)
431 putdbents(dp, &pwd, "*", flags, pwd_db_tmp, 449 putdbents(&idb, &pwd, "*", flags, lineno, dbflg,
432 lineno, dbflg, uid_dbflg, req_version); 450 uid_dbflg);
433 continue; 451 continue;
434 } else if (strcmp(username, pwd.pw_name) != 0) 452 } else if (strcmp(username, pwd.pw_name) != 0)
435 continue; 453 continue;
436 454
437 if (found) { 455 if (found) {
438 warnx("user `%s' listed twice in password file", 456 warnx("user `%s' listed twice in password file",
439 username); 457 username);
440 bailout(); 458 bailout();
441 } 459 }
442 460
443 /* 461 /*
444 * Ensure that the text file and database agree on 462 * Ensure that the text file and database agree on
445 * which line the record is from. 463 * which line the record is from.
446 */ 464 */
447 rv = getdbent(edp, pwd_Sdb_tmp, _PW_KEYBYNUM, &lineno, &tpwd, 465 rv = getdbent(&sdb, _PW_KEYBYNUM, &lineno, &tpwd);
448 sversion); 
449 if (newuser) { 466 if (newuser) {
450 if (rv == 0) 467 if (rv == 0)
451 inconsistancy(); 468 inconsistancy();
452 } else if (rv == -1 || 469 } else if (rv == -1 ||
453 strcmp(username, tpwd->pw_name) != 0) 470 strcmp(username, tpwd->pw_name) != 0)
454 inconsistancy(); 471 inconsistancy();
455 else if ((uid_t)olduid != pwd.pw_uid) { 472 else if ((uid_t)olduid != pwd.pw_uid) {
456 /* 473 /*
457 * If we're changing UID, remove the BYUID 474 * If we're changing UID, remove the BYUID
458 * record for the old UID only if it has the 475 * record for the old UID only if it has the
459 * same username. 476 * same username.
460 */ 477 */
461 if (!getdbent(edp, pwd_Sdb_tmp, _PW_KEYBYUID, &olduid, 478 if (!getdbent(&sdb, _PW_KEYBYUID, &olduid, &tpwd)) {
462 &tpwd, sversion)) { 
463 if (strcmp(username, tpwd->pw_name) == 0) { 479 if (strcmp(username, tpwd->pw_name) == 0) {
464 if (!secureonly) 480 if (!secureonly)
465 deldbent(dp, pwd_db_tmp, 481 deldbent(&idb, _PW_KEYBYUID,
466 _PW_KEYBYUID, &olduid); 482 &olduid);
467 deldbent(edp, pwd_Sdb_tmp, 483 deldbent(&sdb, _PW_KEYBYUID, &olduid);
468 _PW_KEYBYUID, &olduid); 
469 } 484 }
470 } else 485 } else
471 inconsistancy(); 486 inconsistancy();
472 } 487 }
473 488
474 /* 489 /*
475 * If there's an existing BYUID record for the new UID and 490 * If there's an existing BYUID record for the new UID and
476 * the username doesn't match then be sure not to overwrite 491 * the username doesn't match then be sure not to overwrite
477 * it. 492 * it.
478 */ 493 */
479 if (!getdbent(edp, pwd_Sdb_tmp, _PW_KEYBYUID, &pwd.pw_uid, 494 if (!getdbent(&sdb, _PW_KEYBYUID, &pwd.pw_uid, &tpwd))
480 &tpwd, sversion)) 
481 if (strcmp(username, tpwd->pw_name) != 0) 495 if (strcmp(username, tpwd->pw_name) != 0)
482 uid_dbflg = R_NOOVERWRITE; 496 uid_dbflg = R_NOOVERWRITE;
483 497
484 /* Write the database entries out */ 498 /* Write the database entries out */
485 if (!secureonly) 499 if (!secureonly)
486 putdbents(dp, &pwd, "*", flags, pwd_db_tmp, lineno, 500 putdbents(&idb, &pwd, "*", flags, lineno, dbflg,
487 dbflg, uid_dbflg, req_version); 501 uid_dbflg);
488 putdbents(edp, &pwd, pwd.pw_passwd, flags, pwd_Sdb_tmp, 502 putdbents(&sdb, &pwd, pwd.pw_passwd, flags, lineno, dbflg,
489 lineno, dbflg, uid_dbflg, req_sversion); 503 uid_dbflg);
490 504
491 found = 1; 505 found = 1;
492 if (!makeold) 506 if (!makeold)
493 break; 507 break;
494 } 508 }
495 509
496 if (!secureonly) { 510 if (!secureonly) {
497 /* Store YP token if needed. */ 511 /* Store YP token if needed. */
498 if (hasyp) 512 if (hasyp)
499 putyptoken(dp, pwd_db_tmp); 513 putyptoken(&idb);
500 514
501 /* Close the insecure database. */ 515 /* Close the insecure database. */
502 if ((*dp->close)(dp) < 0) 516 closedb(&idb);
503 wr_error(pwd_db_tmp); 
504 } 517 }
505 518
506 /* 519 /*
507 * If rebuilding the databases, we re-parse the text file and write 520 * If rebuilding the databases, we re-parse the text file and write
508 * the secure entries out in a separate pass. 521 * the secure entries out in a separate pass.
509 */ 522 */
510 if (username == NULL) { 523 if (username == NULL) {
511 rewind(fp); 524 rewind(fp);
512 for (lineno = 0; scan(fp, &pwd, &flags, &lineno);) 525 for (lineno = 0; scan(fp, &pwd, &flags, &lineno);)
513 putdbents(edp, &pwd, pwd.pw_passwd, flags, pwd_Sdb_tmp, 526 putdbents(&sdb, &pwd, pwd.pw_passwd, flags,
514 lineno, dbflg, uid_dbflg, req_sversion); 527 lineno, dbflg, uid_dbflg);
515 528
516 /* Store YP token if needed. */ 529 /* Store YP token if needed. */
517 if (hasyp) 530 if (hasyp)
518 putyptoken(edp, pwd_Sdb_tmp); 531 putyptoken(&sdb);
519 } else if (!found) { 532 } else if (!found) {
520 warnx("user `%s' not found in password file", username); 533 warnx("user `%s' not found in password file", username);
521 bailout(); 534 bailout();
522 } 535 }
523 536
524 /* Close the secure database. */ 537 /* Close the secure database. */
525 if ((*edp->close)(edp) < 0) 538 closedb(&sdb);
526 wr_error(pwd_Sdb_tmp); 
527 539
528 /* Install as the real password files. */ 540 /* Install as the real password files. */
529 if (!secureonly) 541 if (!secureonly)
530 install(pwd_db_tmp, _PATH_MP_DB); 542 install(idb.dbname, idb.fname);
531 install(pwd_Sdb_tmp, _PATH_SMP_DB); 543 install(sdb.dbname, sdb.fname);
532 544
533 /* Install the V7 password file. */ 545 /* Install the V7 password file. */
534 if (makeold) { 546 if (makeold) {
535 if (fflush(oldfp) == EOF) 547 if (fflush(oldfp) == EOF)
536 wr_error(oldpwdfile); 548 wr_error(oldpwdfile);
537 if (fclose(oldfp) == EOF) 549 if (fclose(oldfp) == EOF)
538 wr_error(oldpwdfile); 550 wr_error(oldpwdfile);
539 install(oldpwdfile, _PATH_PASSWD); 551 install(oldpwdfile, _PATH_PASSWD);
540 } 552 }
541 553
542 /* Set master.passwd permissions, in case caller forgot. */ 554 /* Set master.passwd permissions, in case caller forgot. */
543 (void)fchmod(fileno(fp), S_IRUSR|S_IWUSR); 555 (void)fchmod(fileno(fp), S_IRUSR|S_IWUSR);
544 if (fclose(fp) == EOF) 556 if (fclose(fp) == EOF)
@@ -672,140 +684,144 @@ inconsistancy(void) @@ -672,140 +684,144 @@ inconsistancy(void)
672 684
673 warnx("text files and databases are inconsistent"); 685 warnx("text files and databases are inconsistent");
674 warnx("re-build the databases without -u"); 686 warnx("re-build the databases without -u");
675 bailout(); 687 bailout();
676} 688}
677 689
678void 690void
679bailout(void) 691bailout(void)
680{ 692{
681 693
682 if ((clean & FILE_ORIG) != 0) 694 if ((clean & FILE_ORIG) != 0)
683 rm(oldpwdfile); 695 rm(oldpwdfile);
684 if ((clean & FILE_SECURE) != 0) 696 if ((clean & FILE_SECURE) != 0)
685 rm(pwd_Sdb_tmp); 697 rm(sdb.dbname);
686 if ((clean & FILE_INSECURE) != 0) 698 if ((clean & FILE_INSECURE) != 0)
687 rm(pwd_db_tmp); 699 rm(idb.dbname);
688 700
689 exit(EXIT_FAILURE); 701 exit(EXIT_FAILURE);
690} 702}
691 703
692uint32_t 704uint32_t
693getversion(const char *fname) 705getversion(const char *fname)
694{ 706{
695 DBT data, key; 707 DBT data, key;
696 int ret; 708 int ret;
697 uint32_t version = 0; 709 uint32_t version = 0;
698 DB *dp; 710 DB *db;
699 711
700 dp = dbopen(fname, O_RDONLY, PERM_INSECURE, DB_HASH, NULL); 712 db = dbopen(fname, O_RDONLY, PERM_INSECURE, DB_HASH, NULL);
701 if (dp == NULL) { 713 if (db == NULL) {
702 warn("Cannot open database %s", fname); 714 warn("Cannot open database %s", fname);
703 bailout(); 715 bailout();
704 } 716 }
705 key.data = __UNCONST("VERSION"); 717 key.data = __UNCONST("VERSION");
706 key.size = strlen((const char *)key.data) + 1; 718 key.size = strlen((const char *)key.data) + 1;
707 719
708 switch (ret = (*dp->get)(dp, &key, &data, 0)) { 720 switch (ret = (*db->get)(db, &key, &data, 0)) {
709 case -1: /* Error */ 721 case -1: /* Error */
710 warn("Cannot get VERSION record from database"); 722 warn("Cannot get VERSION record from database");
711 goto out; 723 goto out;
712 case 0: 724 case 0:
713 if (data.size != sizeof(version)) { 725 if (data.size != sizeof(version)) {
714 warnx("Bad VERSION record in database"); 726 warnx("Bad VERSION record in database");
715 goto out; 727 goto out;
716 } 728 }
717 memcpy(&version, data.data, sizeof(version)); 729 memcpy(&version, data.data, sizeof(version));
718 /*FALLTHROUGH*/ 730 /*FALLTHROUGH*/
719 case 1: 731 case 1:
720 (*dp->close)(dp); 732 if (ret == 1)
 733 warnx("Database %s has no version info", fname);
 734 (*db->close)(db);
721 return version; 735 return version;
722 default: 736 default:
723 warnx("internal error db->get returns %d", ret); 737 warnx("internal error db->get returns %d", ret);
724 goto out; 738 goto out;
725 } 739 }
726out: 740out:
727 (*dp->close)(dp); 741 (*db->close)(db);
728 bailout(); 742 bailout();
729} 743}
730 744
731void 745void
732setversion(DB *dp, uint32_t version) 746setversion(struct pwddb *db)
733{ 747{
734 DBT data, key; 748 DBT data, key;
735 key.data = __UNCONST("VERSION"); 749 key.data = __UNCONST("VERSION");
736 key.size = strlen((const char *)key.data) + 1; 750 key.size = strlen((const char *)key.data) + 1;
737 751
738 data.data = &version; 752 data.data = &db->wversion;
739 data.size = sizeof(uint32_t); 753 data.size = sizeof(uint32_t);
740 754
741 if ((*dp->put)(dp, &key, &data, R_NOOVERWRITE) == -1) 755 if ((*db->db->put)(db->db, &key, &data, R_NOOVERWRITE) != 0) {
742 wr_error("setversion"); 756 warn("Can't write VERSION record to %s", db->dbname);
 757 bailout();
 758 }
743} 759}
744 760
745void 761void
746checkversion(uint32_t req_version, uint32_t version) 762checkversion(struct pwddb *db)
747{ 763{
748 (void)fprintf(stderr, "%s: you cannot change a single " 764 (void)fprintf(stderr, "%s: you cannot change a single "
749 "record from version %u to version %u\n", getprogname(), 765 "record from version %u to version %u\n", getprogname(),
750 version, req_version); 766 db->rversion, db->wversion);
751 bailout(); 767 bailout();
752} 768}
753 769
754/* 770/*
755 * Write entries to a database for a single user.  771 * Write entries to a database for a single user.
756 * 772 *
757 * The databases actually contain three copies of the original data. Each 773 * The databases actually contain three copies of the original data. Each
758 * password file entry is converted into a rough approximation of a ``struct 774 * password file entry is converted into a rough approximation of a ``struct
759 * passwd'', with the strings placed inline. This object is then stored as 775 * passwd'', with the strings placed inline. This object is then stored as
760 * the data for three separate keys. The first key * is the pw_name field 776 * the data for three separate keys. The first key * is the pw_name field
761 * prepended by the _PW_KEYBYNAME character. The second key is the pw_uid 777 * prepended by the _PW_KEYBYNAME character. The second key is the pw_uid
762 * field prepended by the _PW_KEYBYUID character. The third key is the line 778 * field prepended by the _PW_KEYBYUID character. The third key is the line
763 * number in the original file prepended by the _PW_KEYBYNUM character.  779 * number in the original file prepended by the _PW_KEYBYNUM character.
764 * (The special characters are prepended to ensure that the keys do not 780 * (The special characters are prepended to ensure that the keys do not
765 * collide.) 781 * collide.)
766 */ 782 */
767#define COMPACT(e) for (t = e; (*p++ = *t++) != '\0';) 783#define COMPACT(e) for (t = e; (*p++ = *t++) != '\0';)
768 784
769void 785void
770putdbents(DB *dp, struct passwd *pw, const char *passwd, int flags, 786putdbents(struct pwddb *db, struct passwd *pw, const char *passwd, int flags,
771 const char *fn, int lineno, int dbflg, int uid_dbflg, uint32_t version) 787 int lineno, int dbflg, int uid_dbflg)
772{ 788{
773 struct passwd pwd; 789 struct passwd pwd;
774 char buf[MAX(MAXPATHLEN, LINE_MAX * 2)], tbuf[1024], *p; 790 char buf[MAX(MAXPATHLEN, LINE_MAX * 2)], tbuf[1024], *p;
775 DBT data, key; 791 DBT data, key;
776 const char *t; 792 const char *t;
777 u_int32_t x; 793 u_int32_t x;
778 int len; 794 int len;
779 795
780 memcpy(&pwd, pw, sizeof(pwd)); 796 memcpy(&pwd, pw, sizeof(pwd));
781 data.data = (u_char *)buf; 797 data.data = (u_char *)buf;
782 key.data = (u_char *)tbuf; 798 key.data = (u_char *)tbuf;
783 799
784 if (lorder != BYTE_ORDER) { 800 if (lorder != BYTE_ORDER) {
785 pwd.pw_uid = SWAP(pwd.pw_uid); 801 pwd.pw_uid = SWAP(pwd.pw_uid);
786 pwd.pw_gid = SWAP(pwd.pw_gid); 802 pwd.pw_gid = SWAP(pwd.pw_gid);
787 } 803 }
788 804
789#define WRITEPWTIMEVAR(pwvar) \ 805#define WRITEPWTIMEVAR(pwvar) \
790 do { \ 806 do { \
791 if (version == 0 && \ 807 if (db->wversion == 0 && \
792 sizeof(pwvar) == sizeof(uint64_t)) { \ 808 sizeof(pwvar) == sizeof(uint64_t)) { \
793 uint32_t tmp = (uint32_t)pwvar; \ 809 uint32_t tmp = (uint32_t)pwvar; \
794 if (lorder != BYTE_ORDER) \ 810 if (lorder != BYTE_ORDER) \
795 tmp = SWAP(tmp); \ 811 tmp = SWAP(tmp); \
796 memmove(p, &tmp, sizeof(tmp)); \ 812 memmove(p, &tmp, sizeof(tmp)); \
797 p += sizeof(tmp); \ 813 p += sizeof(tmp); \
798 } else if (version == 1 && \ 814 } else if (db->wversion == 1 && \
799 sizeof(pwvar) == sizeof(uint32_t)) { \ 815 sizeof(pwvar) == sizeof(uint32_t)) { \
800 uint64_t tmp = pwvar; \ 816 uint64_t tmp = pwvar; \
801 if (lorder != BYTE_ORDER) \ 817 if (lorder != BYTE_ORDER) \
802 tmp = SWAP(tmp); \ 818 tmp = SWAP(tmp); \
803 memmove(p, &tmp, sizeof(tmp)); \ 819 memmove(p, &tmp, sizeof(tmp)); \
804 p += sizeof(tmp); \ 820 p += sizeof(tmp); \
805 } else { \ 821 } else { \
806 if (lorder != BYTE_ORDER) \ 822 if (lorder != BYTE_ORDER) \
807 pwvar = SWAP(pwvar); \ 823 pwvar = SWAP(pwvar); \
808 memmove(p, &pwvar, sizeof(pwvar)); \ 824 memmove(p, &pwvar, sizeof(pwvar)); \
809 p += sizeof(pwvar); \ 825 p += sizeof(pwvar); \
810 } \ 826 } \
811 } while (/*CONSTCOND*/0) 827 } while (/*CONSTCOND*/0)
@@ -826,82 +842,81 @@ putdbents(DB *dp, struct passwd *pw, con @@ -826,82 +842,81 @@ putdbents(DB *dp, struct passwd *pw, con
826 WRITEPWTIMEVAR(pwd.pw_expire); 842 WRITEPWTIMEVAR(pwd.pw_expire);
827 x = flags; 843 x = flags;
828 if (lorder != BYTE_ORDER) 844 if (lorder != BYTE_ORDER)
829 x = SWAP(x); 845 x = SWAP(x);
830 memmove(p, &x, sizeof(x)); 846 memmove(p, &x, sizeof(x));
831 p += sizeof(flags); 847 p += sizeof(flags);
832 data.size = p - buf; 848 data.size = p - buf;
833 849
834 /* Store insecure by name. */ 850 /* Store insecure by name. */
835 tbuf[0] = _PW_KEYBYNAME; 851 tbuf[0] = _PW_KEYBYNAME;
836 len = strlen(pwd.pw_name); 852 len = strlen(pwd.pw_name);
837 memmove(tbuf + 1, pwd.pw_name, len); 853 memmove(tbuf + 1, pwd.pw_name, len);
838 key.size = len + 1; 854 key.size = len + 1;
839 if ((*dp->put)(dp, &key, &data, dbflg) == -1) 855 if ((*db->db->put)(db->db, &key, &data, dbflg) == -1)
840 wr_error(fn); 856 wr_error(db->dbname);
841 857
842 /* Store insecure by number. */ 858 /* Store insecure by number. */
843 tbuf[0] = _PW_KEYBYNUM; 859 tbuf[0] = _PW_KEYBYNUM;
844 x = lineno; 860 x = lineno;
845 if (lorder != BYTE_ORDER) 861 if (lorder != BYTE_ORDER)
846 x = SWAP(x); 862 x = SWAP(x);
847 memmove(tbuf + 1, &x, sizeof(x)); 863 memmove(tbuf + 1, &x, sizeof(x));
848 key.size = sizeof(x) + 1; 864 key.size = sizeof(x) + 1;
849 if ((*dp->put)(dp, &key, &data, dbflg) == -1) 865 if ((*db->db->put)(db->db, &key, &data, dbflg) == -1)
850 wr_error(fn); 866 wr_error(db->dbname);
851 867
852 /* Store insecure by uid. */ 868 /* Store insecure by uid. */
853 tbuf[0] = _PW_KEYBYUID; 869 tbuf[0] = _PW_KEYBYUID;
854 memmove(tbuf + 1, &pwd.pw_uid, sizeof(pwd.pw_uid)); 870 memmove(tbuf + 1, &pwd.pw_uid, sizeof(pwd.pw_uid));
855 key.size = sizeof(pwd.pw_uid) + 1; 871 key.size = sizeof(pwd.pw_uid) + 1;
856 if ((*dp->put)(dp, &key, &data, uid_dbflg) == -1) 872 if ((*db->db->put)(db->db, &key, &data, uid_dbflg) == -1)
857 wr_error(fn); 873 wr_error(db->dbname);
858} 874}
859 875
860int 876int
861deldbent(DB *dp, const char *fn, int type, void *keyp) 877deldbent(struct pwddb *db, int type, void *keyp)
862{ 878{
863 char tbuf[1024]; 879 char tbuf[1024];
864 DBT key; 880 DBT key;
865 u_int32_t x; 881 u_int32_t x;
866 int len, rv; 882 int len, rv;
867 883
868 key.data = (u_char *)tbuf; 884 key.data = (u_char *)tbuf;
869 885
870 switch (tbuf[0] = type) { 886 switch (tbuf[0] = type) {
871 case _PW_KEYBYNAME: 887 case _PW_KEYBYNAME:
872 len = strlen((char *)keyp); 888 len = strlen((char *)keyp);
873 memcpy(tbuf + 1, keyp, len); 889 memcpy(tbuf + 1, keyp, len);
874 key.size = len + 1; 890 key.size = len + 1;
875 break; 891 break;
876 892
877 case _PW_KEYBYNUM: 893 case _PW_KEYBYNUM:
878 case _PW_KEYBYUID: 894 case _PW_KEYBYUID:
879 x = *(int *)keyp; 895 x = *(int *)keyp;
880 if (lorder != BYTE_ORDER) 896 if (lorder != BYTE_ORDER)
881 x = SWAP(x); 897 x = SWAP(x);
882 memmove(tbuf + 1, &x, sizeof(x)); 898 memmove(tbuf + 1, &x, sizeof(x));
883 key.size = sizeof(x) + 1; 899 key.size = sizeof(x) + 1;
884 break; 900 break;
885 } 901 }
886 902
887 if ((rv = (*dp->del)(dp, &key, 0)) == -1) 903 if ((rv = (*db->db->del)(db->db, &key, 0)) == -1)
888 wr_error(fn); 904 wr_error(db->dbname);
889 return (rv); 905 return (rv);
890} 906}
891 907
892int 908int
893getdbent(DB *dp, const char *fn, int type, void *keyp, struct passwd **tpwd, 909getdbent(struct pwddb *db, int type, void *keyp, struct passwd **tpwd)
894 uint32_t version) 
895{ 910{
896 static char buf[MAX(MAXPATHLEN, LINE_MAX * 2)]; 911 static char buf[MAX(MAXPATHLEN, LINE_MAX * 2)];
897 static struct passwd pwd; 912 static struct passwd pwd;
898 char tbuf[1024], *p; 913 char tbuf[1024], *p;
899 DBT key, data; 914 DBT key, data;
900 u_int32_t x; 915 u_int32_t x;
901 int len, rv; 916 int len, rv;
902 917
903 data.data = (u_char *)buf; 918 data.data = (u_char *)buf;
904 data.size = sizeof(buf); 919 data.size = sizeof(buf);
905 key.data = (u_char *)tbuf; 920 key.data = (u_char *)tbuf;
906 921
907 switch (tbuf[0] = type) { 922 switch (tbuf[0] = type) {
@@ -911,57 +926,57 @@ getdbent(DB *dp, const char *fn, int typ @@ -911,57 +926,57 @@ getdbent(DB *dp, const char *fn, int typ
911 key.size = len + 1; 926 key.size = len + 1;
912 break; 927 break;
913 928
914 case _PW_KEYBYNUM: 929 case _PW_KEYBYNUM:
915 case _PW_KEYBYUID: 930 case _PW_KEYBYUID:
916 x = *(int *)keyp; 931 x = *(int *)keyp;
917 if (lorder != BYTE_ORDER) 932 if (lorder != BYTE_ORDER)
918 x = SWAP(x); 933 x = SWAP(x);
919 memmove(tbuf + 1, &x, sizeof(x)); 934 memmove(tbuf + 1, &x, sizeof(x));
920 key.size = sizeof(x) + 1; 935 key.size = sizeof(x) + 1;
921 break; 936 break;
922 } 937 }
923 938
924 if ((rv = (*dp->get)(dp, &key, &data, 0)) == 1) 939 if ((rv = (*db->db->get)(db->db, &key, &data, 0)) == 1)
925 return (rv); 940 return (rv);
926 if (rv == -1) 941 if (rv == -1)
927 error(pwd_Sdb_tmp); 942 error(db->dbname);
928 943
929 p = (char *)data.data; 944 p = (char *)data.data;
930 945
931 pwd.pw_name = p; 946 pwd.pw_name = p;
932 while (*p++ != '\0') 947 while (*p++ != '\0')
933 continue; 948 continue;
934 pwd.pw_passwd = p; 949 pwd.pw_passwd = p;
935 while (*p++ != '\0') 950 while (*p++ != '\0')
936 continue; 951 continue;
937 952
938 memcpy(&pwd.pw_uid, p, sizeof(pwd.pw_uid)); 953 memcpy(&pwd.pw_uid, p, sizeof(pwd.pw_uid));
939 p += sizeof(pwd.pw_uid); 954 p += sizeof(pwd.pw_uid);
940 memcpy(&pwd.pw_gid, p, sizeof(pwd.pw_gid)); 955 memcpy(&pwd.pw_gid, p, sizeof(pwd.pw_gid));
941 p += sizeof(pwd.pw_gid); 956 p += sizeof(pwd.pw_gid);
942 957
943#define READPWTIMEVAR(pwvar) \ 958#define READPWTIMEVAR(pwvar) \
944 do { \ 959 do { \
945 if (version == 0 && \ 960 if (db->rversion == 0 && \
946 sizeof(pwvar) == sizeof(uint64_t)) { \ 961 sizeof(pwvar) == sizeof(uint64_t)) { \
947 uint32_t tmp; \ 962 uint32_t tmp; \
948 memcpy(&tmp, p, sizeof(tmp)); \ 963 memcpy(&tmp, p, sizeof(tmp)); \
949 p += sizeof(tmp); \ 964 p += sizeof(tmp); \
950 if (lorder != BYTE_ORDER) \ 965 if (lorder != BYTE_ORDER) \
951 pwvar = SWAP(tmp); \ 966 pwvar = SWAP(tmp); \
952 else \ 967 else \
953 pwvar = tmp; \ 968 pwvar = tmp; \
954 } else if (version == 1 && \ 969 } else if (db->rversion == 1 && \
955 sizeof(pwvar) == sizeof(uint32_t)) { \ 970 sizeof(pwvar) == sizeof(uint32_t)) { \
956 uint64_t tmp; \ 971 uint64_t tmp; \
957 memcpy(&tmp, p, sizeof(tmp)); \ 972 memcpy(&tmp, p, sizeof(tmp)); \
958 p += sizeof(tmp); \ 973 p += sizeof(tmp); \
959 if (lorder != BYTE_ORDER) \ 974 if (lorder != BYTE_ORDER) \
960 pwvar = (uint32_t)SWAP(tmp); \ 975 pwvar = (uint32_t)SWAP(tmp); \
961 else \ 976 else \
962 pwvar = (uint32_t)tmp; \ 977 pwvar = (uint32_t)tmp; \
963 } else { \ 978 } else { \
964 memcpy(&pwvar, p, sizeof(pwvar)); \ 979 memcpy(&pwvar, p, sizeof(pwvar)); \
965 p += sizeof(pwvar); \ 980 p += sizeof(pwvar); \
966 if (lorder != BYTE_ORDER) \ 981 if (lorder != BYTE_ORDER) \
967 pwvar = SWAP(pwvar); \ 982 pwvar = SWAP(pwvar); \
@@ -985,36 +1000,36 @@ getdbent(DB *dp, const char *fn, int typ @@ -985,36 +1000,36 @@ getdbent(DB *dp, const char *fn, int typ
985 1000
986 READPWTIMEVAR(pwd.pw_expire); 1001 READPWTIMEVAR(pwd.pw_expire);
987 1002
988 if (lorder != BYTE_ORDER) { 1003 if (lorder != BYTE_ORDER) {
989 pwd.pw_uid = SWAP(pwd.pw_uid); 1004 pwd.pw_uid = SWAP(pwd.pw_uid);
990 pwd.pw_gid = SWAP(pwd.pw_gid); 1005 pwd.pw_gid = SWAP(pwd.pw_gid);
991 } 1006 }
992 1007
993 *tpwd = &pwd; 1008 *tpwd = &pwd;
994 return (0); 1009 return (0);
995} 1010}
996 1011
997void 1012void
998putyptoken(DB *dp, const char *fn) 1013putyptoken(struct pwddb *db)
999{ 1014{
1000 DBT data, key; 1015 DBT data, key;
1001 1016
1002 key.data = __UNCONST(__yp_token); 1017 key.data = __UNCONST(__yp_token);
1003 key.size = strlen(__yp_token); 1018 key.size = strlen(__yp_token);
1004 data.data = (u_char *)NULL; 1019 data.data = (u_char *)NULL;
1005 data.size = 0; 1020 data.size = 0;
1006 1021
1007 if ((*dp->put)(dp, &key, &data, R_NOOVERWRITE) == -1) 1022 if ((*db->db->put)(db->db, &key, &data, R_NOOVERWRITE) == -1)
1008 wr_error(fn); 1023 wr_error(db->dbname);
1009} 1024}
1010 1025
1011void 1026void
1012usage(void) 1027usage(void)
1013{ 1028{
1014 1029
1015 (void)fprintf(stderr, 1030 (void)fprintf(stderr,
1016 "Usage: %s [-BLpsv] [-c cachesize] [-d directory] [-u user] " 1031 "Usage: %s [-BLpsvw] [-c cachesize] [-d directory] [-u user] "
1017 "[-V version] file\n", 1032 "[-V version] file\n",
1018 getprogname()); 1033 getprogname());
1019 exit(EXIT_FAILURE); 1034 exit(EXIT_FAILURE);
1020} 1035}