Replace local swap16, swap32, and swap64 inline functions with the
NetBSD conventional bswap16, bswap32, and bswap64 functions or macros.
In a non-tools build, include <sys/types.h> and <machine/bswap.h> to
get definitions of these functions. In a tools build, rely on the
functions or macros being provided by nbtool_config.h, but don't incluce
<machine/bswap.h> (which might not exist in a cross build).
This should address a problem building on OpenBSD, which has swap16,
swap32, and swap64 macros that conflicted with the local definitions.
The problem was reported by Alexander Bluhm, but this patch is quite
different from the one he suggested.
2009-03-06 22:05:11 +03:00
|
|
|
/* $NetBSD: pwd_mkdb.c,v 1.39 2009/03/06 19:05:11 apb Exp $ */
|
2009-01-16 13:42:36 +03:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Copyright (c) 2000, 2009 The NetBSD Foundation, Inc.
|
|
|
|
* All rights reserved.
|
|
|
|
*
|
|
|
|
* Redistribution and use in source and binary forms, with or without
|
|
|
|
* modification, are permitted provided that the following conditions
|
|
|
|
* are met:
|
|
|
|
* 1. Redistributions of source code must retain the above copyright
|
|
|
|
* notice, this list of conditions and the following disclaimer.
|
|
|
|
* 2. Redistributions in binary form must reproduce the above copyright
|
|
|
|
* notice, this list of conditions and the following disclaimer in the
|
|
|
|
* documentation and/or other materials provided with the distribution.
|
|
|
|
*
|
|
|
|
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
|
|
|
|
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
|
|
|
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
|
|
|
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
|
|
|
|
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
|
|
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
|
|
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|
|
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
|
|
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
|
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
|
|
* POSSIBILITY OF SUCH DAMAGE.
|
|
|
|
*/
|
2000-08-07 17:19:27 +04:00
|
|
|
|
1998-04-14 03:12:45 +04:00
|
|
|
/*
|
1994-08-29 03:32:47 +04:00
|
|
|
* Copyright (c) 1991, 1993, 1994
|
|
|
|
* The Regents of the University of California. All rights reserved.
|
2003-08-07 15:25:11 +04:00
|
|
|
*
|
|
|
|
* Redistribution and use in source and binary forms, with or without
|
|
|
|
* modification, are permitted provided that the following conditions
|
|
|
|
* are met:
|
|
|
|
* 1. Redistributions of source code must retain the above copyright
|
|
|
|
* notice, this list of conditions and the following disclaimer.
|
|
|
|
* 2. Redistributions in binary form must reproduce the above copyright
|
|
|
|
* notice, this list of conditions and the following disclaimer in the
|
|
|
|
* documentation and/or other materials provided with the distribution.
|
|
|
|
* 3. Neither the name of the University nor the names of its contributors
|
|
|
|
* may be used to endorse or promote products derived from this software
|
|
|
|
* without specific prior written permission.
|
|
|
|
*
|
|
|
|
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
|
|
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
|
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
|
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
|
|
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
|
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
|
|
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
|
|
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
|
|
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
|
|
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
|
|
|
* SUCH DAMAGE.
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*
|
1995-07-28 11:13:04 +04:00
|
|
|
* Portions Copyright(C) 1994, Jason Downs. All rights reserved.
|
1993-03-21 12:45:37 +03:00
|
|
|
*
|
|
|
|
* Redistribution and use in source and binary forms, with or without
|
|
|
|
* modification, are permitted provided that the following conditions
|
|
|
|
* are met:
|
|
|
|
* 1. Redistributions of source code must retain the above copyright
|
|
|
|
* notice, this list of conditions and the following disclaimer.
|
|
|
|
* 2. Redistributions in binary form must reproduce the above copyright
|
|
|
|
* notice, this list of conditions and the following disclaimer in the
|
|
|
|
* documentation and/or other materials provided with the distribution.
|
|
|
|
*
|
2003-10-13 19:36:33 +04:00
|
|
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS
|
|
|
|
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
|
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
|
|
* DISCLAIMED. IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT,
|
|
|
|
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
|
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
|
|
|
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
|
|
|
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
1993-03-21 12:45:37 +03:00
|
|
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
|
|
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
|
|
|
* SUCH DAMAGE.
|
|
|
|
*/
|
|
|
|
|
2003-10-27 03:12:41 +03:00
|
|
|
#if HAVE_NBTOOL_CONFIG_H
|
|
|
|
#include "nbtool_config.h"
|
2002-01-29 13:20:28 +03:00
|
|
|
#endif
|
|
|
|
|
1997-10-17 16:18:16 +04:00
|
|
|
#include <sys/cdefs.h>
|
2003-10-27 03:12:41 +03:00
|
|
|
#if !defined(lint)
|
2009-01-16 13:42:36 +03:00
|
|
|
__COPYRIGHT("@(#) Copyright (c) 2000, 2009\
|
2008-07-21 17:36:57 +04:00
|
|
|
The NetBSD Foundation, Inc. All rights reserved.\
|
|
|
|
Copyright (c) 1991, 1993, 1994\
|
|
|
|
The Regents of the University of California. All rights reserved.");
|
2000-01-23 22:59:32 +03:00
|
|
|
__SCCSID("from: @(#)pwd_mkdb.c 8.5 (Berkeley) 4/20/94");
|
Replace local swap16, swap32, and swap64 inline functions with the
NetBSD conventional bswap16, bswap32, and bswap64 functions or macros.
In a non-tools build, include <sys/types.h> and <machine/bswap.h> to
get definitions of these functions. In a tools build, rely on the
functions or macros being provided by nbtool_config.h, but don't incluce
<machine/bswap.h> (which might not exist in a cross build).
This should address a problem building on OpenBSD, which has swap16,
swap32, and swap64 macros that conflicted with the local definitions.
The problem was reported by Alexander Bluhm, but this patch is quite
different from the one he suggested.
2009-03-06 22:05:11 +03:00
|
|
|
__RCSID("$NetBSD: pwd_mkdb.c,v 1.39 2009/03/06 19:05:11 apb Exp $");
|
1993-03-21 12:45:37 +03:00
|
|
|
#endif /* not lint */
|
|
|
|
|
2004-06-21 02:20:14 +04:00
|
|
|
#if HAVE_NBTOOL_CONFIG_H
|
|
|
|
#include "compat_pwd.h"
|
|
|
|
#else
|
|
|
|
#include <pwd.h>
|
|
|
|
#endif
|
|
|
|
|
1993-03-21 12:45:37 +03:00
|
|
|
#include <sys/param.h>
|
|
|
|
#include <sys/stat.h>
|
Replace local swap16, swap32, and swap64 inline functions with the
NetBSD conventional bswap16, bswap32, and bswap64 functions or macros.
In a non-tools build, include <sys/types.h> and <machine/bswap.h> to
get definitions of these functions. In a tools build, rely on the
functions or macros being provided by nbtool_config.h, but don't incluce
<machine/bswap.h> (which might not exist in a cross build).
This should address a problem building on OpenBSD, which has swap16,
swap32, and swap64 macros that conflicted with the local definitions.
The problem was reported by Alexander Bluhm, but this patch is quite
different from the one he suggested.
2009-03-06 22:05:11 +03:00
|
|
|
#include <sys/types.h>
|
|
|
|
|
|
|
|
#ifndef HAVE_NBTOOL_CONFIG_H
|
|
|
|
#include <machine/bswap.h>
|
|
|
|
#endif
|
1994-08-29 03:32:47 +04:00
|
|
|
|
1993-03-21 12:45:37 +03:00
|
|
|
#include <db.h>
|
2002-02-01 01:43:33 +03:00
|
|
|
#include <err.h>
|
1993-03-21 12:45:37 +03:00
|
|
|
#include <errno.h>
|
1994-08-29 03:32:47 +04:00
|
|
|
#include <fcntl.h>
|
1993-03-21 12:45:37 +03:00
|
|
|
#include <limits.h>
|
1994-08-29 03:32:47 +04:00
|
|
|
#include <signal.h>
|
1993-03-21 12:45:37 +03:00
|
|
|
#include <stdio.h>
|
1994-08-29 03:32:47 +04:00
|
|
|
#include <stdlib.h>
|
1993-03-21 12:45:37 +03:00
|
|
|
#include <string.h>
|
1994-08-29 03:32:47 +04:00
|
|
|
#include <unistd.h>
|
2002-02-01 01:43:33 +03:00
|
|
|
#include <util.h>
|
2002-01-29 13:20:28 +03:00
|
|
|
|
2001-08-18 23:29:31 +04:00
|
|
|
#define MAX_CACHESIZE 8*1024*1024
|
|
|
|
#define MIN_CACHESIZE 2*1024*1024
|
|
|
|
|
2000-08-07 17:19:27 +04:00
|
|
|
#define PERM_INSECURE (S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)
|
|
|
|
#define PERM_SECURE (S_IRUSR | S_IWUSR)
|
1993-03-21 12:45:37 +03:00
|
|
|
|
2003-10-27 03:12:41 +03:00
|
|
|
#if HAVE_NBTOOL_CONFIG_H
|
2002-01-29 13:20:28 +03:00
|
|
|
static const char __yp_token[] = "__YP!";
|
|
|
|
#else
|
2001-08-18 23:29:31 +04:00
|
|
|
/* Pull this out of the C library. */
|
1995-07-28 11:13:04 +04:00
|
|
|
extern const char __yp_token[];
|
2002-01-29 13:20:28 +03:00
|
|
|
#endif
|
1995-07-28 11:13:04 +04:00
|
|
|
|
1994-08-29 03:32:47 +04:00
|
|
|
HASHINFO openinfo = {
|
|
|
|
4096, /* bsize */
|
|
|
|
32, /* ffactor */
|
|
|
|
256, /* nelem */
|
2001-08-18 23:29:31 +04:00
|
|
|
0, /* cachesize */
|
1994-08-29 03:32:47 +04:00
|
|
|
NULL, /* hash() */
|
|
|
|
0 /* lorder */
|
|
|
|
};
|
1993-03-21 12:45:37 +03:00
|
|
|
|
2001-08-18 23:29:31 +04:00
|
|
|
#define FILE_INSECURE 0x01
|
|
|
|
#define FILE_SECURE 0x02
|
|
|
|
#define FILE_ORIG 0x04
|
|
|
|
|
|
|
|
static char *pname; /* password file name */
|
|
|
|
static char prefix[MAXPATHLEN];
|
|
|
|
static char oldpwdfile[MAX(MAXPATHLEN, LINE_MAX * 2)];
|
|
|
|
static char pwd_db_tmp[MAX(MAXPATHLEN, LINE_MAX * 2)];
|
|
|
|
static char pwd_Sdb_tmp[MAX(MAXPATHLEN, LINE_MAX * 2)];
|
|
|
|
static int lorder = BYTE_ORDER;
|
|
|
|
static int clean;
|
|
|
|
|
|
|
|
void bailout(void);
|
|
|
|
void cp(const char *, const char *, mode_t);
|
|
|
|
int deldbent(DB *, const char *, int, void *);
|
2000-08-07 17:19:27 +04:00
|
|
|
void error(const char *);
|
2001-08-18 23:29:31 +04:00
|
|
|
int getdbent(DB *, const char *, int, void *, struct passwd **);
|
|
|
|
void inconsistancy(void);
|
2000-08-07 17:19:27 +04:00
|
|
|
void install(const char *, const char *);
|
2001-08-18 23:29:31 +04:00
|
|
|
int main(int, char **);
|
|
|
|
void putdbents(DB *, struct passwd *, const char *, int, const char *, int,
|
|
|
|
int, int);
|
|
|
|
void putyptoken(DB *, const char *);
|
2000-08-07 17:19:27 +04:00
|
|
|
void rm(const char *);
|
|
|
|
int scan(FILE *, struct passwd *, int *, int *);
|
|
|
|
void usage(void);
|
2001-08-18 23:29:31 +04:00
|
|
|
void wr_error(const char *);
|
2009-01-16 13:42:36 +03:00
|
|
|
void checkversion(DB *);
|
|
|
|
uint32_t getversion(void);
|
2009-01-15 02:18:57 +03:00
|
|
|
void setversion(DB *);
|
|
|
|
|
|
|
|
#define SWAP(sw) \
|
Replace local swap16, swap32, and swap64 inline functions with the
NetBSD conventional bswap16, bswap32, and bswap64 functions or macros.
In a non-tools build, include <sys/types.h> and <machine/bswap.h> to
get definitions of these functions. In a tools build, rely on the
functions or macros being provided by nbtool_config.h, but don't incluce
<machine/bswap.h> (which might not exist in a cross build).
This should address a problem building on OpenBSD, which has swap16,
swap32, and swap64 macros that conflicted with the local definitions.
The problem was reported by Alexander Bluhm, but this patch is quite
different from the one he suggested.
2009-03-06 22:05:11 +03:00
|
|
|
((sizeof(sw) == 2 ? (typeof(sw))bswap16((uint16_t)sw) : \
|
|
|
|
(sizeof(sw) == 4 ? (typeof(sw))bswap32((uint32_t)sw) : \
|
|
|
|
(sizeof(sw) == 8 ? (typeof(sw))bswap64((uint64_t)sw) : (abort(), 0)))))
|
1994-08-29 03:32:47 +04:00
|
|
|
|
|
|
|
int
|
2000-08-07 17:19:27 +04:00
|
|
|
main(int argc, char *argv[])
|
1993-03-21 12:45:37 +03:00
|
|
|
{
|
2001-08-18 23:29:31 +04:00
|
|
|
int ch, makeold, tfd, lineno, found, rv, hasyp, secureonly;
|
|
|
|
struct passwd pwd, *tpwd;
|
|
|
|
char *username;
|
1993-03-21 12:45:37 +03:00
|
|
|
DB *dp, *edp;
|
1994-08-29 03:32:47 +04:00
|
|
|
FILE *fp, *oldfp;
|
|
|
|
sigset_t set;
|
2001-08-18 23:29:31 +04:00
|
|
|
int dbflg, uid_dbflg, newuser, olduid, flags;
|
|
|
|
char buf[MAXPATHLEN];
|
|
|
|
struct stat st;
|
|
|
|
u_int cachesize;
|
1993-03-21 12:45:37 +03:00
|
|
|
|
2000-11-20 17:09:36 +03:00
|
|
|
prefix[0] = '\0';
|
1993-03-21 12:45:37 +03:00
|
|
|
makeold = 0;
|
2001-08-18 23:29:31 +04:00
|
|
|
oldfp = NULL;
|
|
|
|
username = NULL;
|
|
|
|
hasyp = 0;
|
|
|
|
secureonly = 0;
|
2005-06-02 13:18:14 +04:00
|
|
|
found = 0;
|
|
|
|
newuser = 0;
|
|
|
|
dp = NULL;
|
2006-09-23 21:17:04 +04:00
|
|
|
cachesize = 0;
|
2001-08-18 23:29:31 +04:00
|
|
|
|
2006-09-23 21:17:04 +04:00
|
|
|
while ((ch = getopt(argc, argv, "BLc:d:psu:v")) != -1)
|
2001-08-18 23:29:31 +04:00
|
|
|
switch (ch) {
|
|
|
|
case 'B': /* big-endian output */
|
|
|
|
lorder = BIG_ENDIAN;
|
|
|
|
break;
|
|
|
|
case 'L': /* little-endian output */
|
|
|
|
lorder = LITTLE_ENDIAN;
|
|
|
|
break;
|
2006-09-23 21:17:04 +04:00
|
|
|
case 'c':
|
|
|
|
cachesize = atoi(optarg) * 1024 * 1024;
|
|
|
|
break;
|
2000-08-07 17:19:27 +04:00
|
|
|
case 'd': /* set prefix */
|
2003-05-17 23:18:59 +04:00
|
|
|
strlcpy(prefix, optarg, sizeof(prefix));
|
1996-11-22 08:37:29 +03:00
|
|
|
break;
|
1993-03-21 12:45:37 +03:00
|
|
|
case 'p': /* create V7 "file.orig" */
|
|
|
|
makeold = 1;
|
|
|
|
break;
|
2001-08-18 23:29:31 +04:00
|
|
|
case 's': /* modify secure db only */
|
|
|
|
secureonly = 1;
|
1993-03-21 12:45:37 +03:00
|
|
|
break;
|
2001-08-18 23:29:31 +04:00
|
|
|
case 'u': /* modify one user only */
|
|
|
|
username = optarg;
|
2000-01-23 22:59:32 +03:00
|
|
|
break;
|
2001-08-18 23:29:31 +04:00
|
|
|
case 'v': /* backward compatible */
|
2000-01-23 22:59:32 +03:00
|
|
|
break;
|
1993-03-21 12:45:37 +03:00
|
|
|
case '?':
|
|
|
|
default:
|
|
|
|
usage();
|
|
|
|
}
|
|
|
|
argc -= optind;
|
|
|
|
argv += optind;
|
|
|
|
|
|
|
|
if (argc != 1)
|
|
|
|
usage();
|
2001-08-18 23:29:31 +04:00
|
|
|
if (username != NULL)
|
|
|
|
if (username[0] == '+' || username[0] == '-')
|
|
|
|
usage();
|
|
|
|
if (secureonly)
|
|
|
|
makeold = 0;
|
1993-03-21 12:45:37 +03:00
|
|
|
|
|
|
|
/*
|
1994-08-29 03:32:47 +04:00
|
|
|
* This could be changed to allow the user to interrupt.
|
|
|
|
* Probably not worth the effort.
|
1993-03-21 12:45:37 +03:00
|
|
|
*/
|
|
|
|
sigemptyset(&set);
|
|
|
|
sigaddset(&set, SIGTSTP);
|
|
|
|
sigaddset(&set, SIGHUP);
|
|
|
|
sigaddset(&set, SIGINT);
|
|
|
|
sigaddset(&set, SIGQUIT);
|
|
|
|
sigaddset(&set, SIGTERM);
|
|
|
|
(void)sigprocmask(SIG_BLOCK, &set, (sigset_t *)NULL);
|
|
|
|
|
1994-08-29 03:32:47 +04:00
|
|
|
/* We don't care what the user wants. */
|
|
|
|
(void)umask(0);
|
|
|
|
|
2001-08-18 23:29:31 +04:00
|
|
|
if (username == NULL)
|
|
|
|
flags = O_RDWR | O_CREAT | O_EXCL;
|
|
|
|
else
|
|
|
|
flags = O_RDWR;
|
|
|
|
|
1993-03-21 12:45:37 +03:00
|
|
|
pname = *argv;
|
|
|
|
/* Open the original password file */
|
2000-08-07 17:19:27 +04:00
|
|
|
if ((fp = fopen(pname, "r")) == NULL)
|
1993-03-21 12:45:37 +03:00
|
|
|
error(pname);
|
|
|
|
|
2000-01-23 22:59:32 +03:00
|
|
|
openinfo.lorder = lorder;
|
|
|
|
|
2001-08-18 23:29:31 +04:00
|
|
|
if (fstat(fileno(fp), &st) == -1)
|
|
|
|
error(pname);
|
|
|
|
|
2006-09-23 21:17:04 +04:00
|
|
|
if (cachesize) {
|
|
|
|
openinfo.cachesize = cachesize;
|
|
|
|
} else {
|
|
|
|
/* Tweak openinfo values for large passwd files. */
|
|
|
|
cachesize = st.st_size * 20;
|
|
|
|
if (cachesize > MAX_CACHESIZE)
|
|
|
|
cachesize = MAX_CACHESIZE;
|
|
|
|
else if (cachesize < MIN_CACHESIZE)
|
|
|
|
cachesize = MIN_CACHESIZE;
|
|
|
|
openinfo.cachesize = cachesize;
|
|
|
|
}
|
2001-08-18 23:29:31 +04:00
|
|
|
|
1993-03-21 12:45:37 +03:00
|
|
|
/* Open the temporary insecure password database. */
|
2001-08-18 23:29:31 +04:00
|
|
|
if (!secureonly) {
|
|
|
|
(void)snprintf(pwd_db_tmp, sizeof(pwd_db_tmp), "%s%s.tmp",
|
|
|
|
prefix, _PATH_MP_DB);
|
|
|
|
if (username != NULL) {
|
|
|
|
snprintf(buf, sizeof(buf), "%s" _PATH_MP_DB, prefix);
|
|
|
|
cp(buf, pwd_db_tmp, PERM_INSECURE);
|
|
|
|
}
|
|
|
|
dp = dbopen(pwd_db_tmp, flags, PERM_INSECURE, DB_HASH,
|
|
|
|
&openinfo);
|
|
|
|
if (dp == NULL)
|
|
|
|
error(pwd_db_tmp);
|
|
|
|
clean |= FILE_INSECURE;
|
2009-01-16 13:42:36 +03:00
|
|
|
if (username != NULL)
|
|
|
|
checkversion(dp);
|
|
|
|
else
|
|
|
|
setversion(dp);
|
2001-08-18 23:29:31 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Open the temporary encrypted password database. */
|
|
|
|
(void)snprintf(pwd_Sdb_tmp, sizeof(pwd_Sdb_tmp), "%s%s.tmp", prefix,
|
|
|
|
_PATH_SMP_DB);
|
|
|
|
if (username != NULL) {
|
|
|
|
snprintf(buf, sizeof(buf), "%s" _PATH_SMP_DB, prefix);
|
|
|
|
cp(buf, pwd_Sdb_tmp, PERM_SECURE);
|
|
|
|
}
|
|
|
|
edp = dbopen(pwd_Sdb_tmp, flags, PERM_SECURE, DB_HASH, &openinfo);
|
|
|
|
if (!edp)
|
|
|
|
error(pwd_Sdb_tmp);
|
|
|
|
clean |= FILE_SECURE;
|
2009-01-16 13:42:36 +03:00
|
|
|
if (username != NULL)
|
|
|
|
checkversion(edp);
|
|
|
|
else
|
|
|
|
setversion(edp);
|
1993-03-21 12:45:37 +03:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Open file for old password file. Minor trickiness -- don't want to
|
|
|
|
* chance the file already existing, since someone (stupidly) might
|
|
|
|
* still be using this for permission checking. So, open it first and
|
1994-08-29 03:32:47 +04:00
|
|
|
* fdopen the resulting fd. The resulting file should be readable by
|
|
|
|
* everyone.
|
1993-03-21 12:45:37 +03:00
|
|
|
*/
|
|
|
|
if (makeold) {
|
1998-04-14 03:12:45 +04:00
|
|
|
(void)snprintf(oldpwdfile, sizeof(oldpwdfile), "%s.orig",
|
2000-08-07 17:19:27 +04:00
|
|
|
pname);
|
|
|
|
if ((tfd = open(oldpwdfile, O_WRONLY | O_CREAT | O_EXCL,
|
|
|
|
PERM_INSECURE)) < 0)
|
1998-04-14 03:12:45 +04:00
|
|
|
error(oldpwdfile);
|
2001-08-18 23:29:31 +04:00
|
|
|
clean |= FILE_ORIG;
|
1994-08-29 03:32:47 +04:00
|
|
|
if ((oldfp = fdopen(tfd, "w")) == NULL)
|
1998-04-14 03:12:45 +04:00
|
|
|
error(oldpwdfile);
|
2001-08-18 23:29:31 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
if (username != NULL) {
|
|
|
|
uid_dbflg = 0;
|
|
|
|
dbflg = 0;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Determine if this is a new entry.
|
|
|
|
*/
|
|
|
|
if (getdbent(edp, pwd_Sdb_tmp, _PW_KEYBYNAME, username, &tpwd))
|
|
|
|
newuser = 1;
|
|
|
|
else {
|
|
|
|
newuser = 0;
|
|
|
|
olduid = tpwd->pw_uid;
|
|
|
|
}
|
|
|
|
|
|
|
|
} else {
|
|
|
|
uid_dbflg = R_NOOVERWRITE;
|
|
|
|
dbflg = R_NOOVERWRITE;
|
1993-03-21 12:45:37 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
1995-07-28 11:13:04 +04:00
|
|
|
* If we see something go by that looks like YP, we save a special
|
|
|
|
* pointer record, which if YP is enabled in the C lib, will speed
|
|
|
|
* things up.
|
1993-03-21 12:45:37 +03:00
|
|
|
*/
|
2000-08-07 17:19:27 +04:00
|
|
|
for (lineno = 0; scan(fp, &pwd, &flags, &lineno);) {
|
1996-11-25 00:13:27 +03:00
|
|
|
/*
|
2001-08-18 23:29:31 +04:00
|
|
|
* Create original format password file entry.
|
1996-11-25 00:13:27 +03:00
|
|
|
*/
|
1998-04-14 03:12:45 +04:00
|
|
|
if (makeold) {
|
1994-08-29 03:32:47 +04:00
|
|
|
(void)fprintf(oldfp, "%s:*:%d:%d:%s:%s:%s\n",
|
|
|
|
pwd.pw_name, pwd.pw_uid, pwd.pw_gid, pwd.pw_gecos,
|
|
|
|
pwd.pw_dir, pwd.pw_shell);
|
2000-08-07 17:19:27 +04:00
|
|
|
if (ferror(oldfp))
|
1998-04-14 03:12:45 +04:00
|
|
|
wr_error(oldpwdfile);
|
|
|
|
}
|
2001-08-18 23:29:31 +04:00
|
|
|
|
|
|
|
if (username == NULL) {
|
|
|
|
/* Look like YP? */
|
|
|
|
if (pwd.pw_name[0] == '+' || pwd.pw_name[0] == '-')
|
|
|
|
hasyp++;
|
|
|
|
|
|
|
|
/* Warn about potentially unsafe uid/gid overrides. */
|
|
|
|
if (pwd.pw_name[0] == '+') {
|
|
|
|
if ((flags & _PASSWORD_NOUID) == 0 &&
|
|
|
|
pwd.pw_uid == 0)
|
|
|
|
warnx("line %d: superuser override "
|
|
|
|
"in YP inclusion", lineno);
|
|
|
|
if ((flags & _PASSWORD_NOGID) == 0 &&
|
|
|
|
pwd.pw_gid == 0)
|
|
|
|
warnx("line %d: wheel override "
|
|
|
|
"in YP inclusion", lineno);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Write the database entry out. */
|
|
|
|
if (!secureonly)
|
|
|
|
putdbents(dp, &pwd, "*", flags, pwd_db_tmp,
|
|
|
|
lineno, dbflg, uid_dbflg);
|
|
|
|
continue;
|
|
|
|
} else if (strcmp(username, pwd.pw_name) != 0)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
if (found) {
|
|
|
|
warnx("user `%s' listed twice in password file",
|
|
|
|
username);
|
|
|
|
bailout();
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Ensure that the text file and database agree on
|
|
|
|
* which line the record is from.
|
|
|
|
*/
|
|
|
|
rv = getdbent(edp, pwd_Sdb_tmp, _PW_KEYBYNUM, &lineno, &tpwd);
|
|
|
|
if (newuser) {
|
|
|
|
if (rv == 0)
|
|
|
|
inconsistancy();
|
|
|
|
} else if (rv == -1 ||
|
|
|
|
strcmp(username, tpwd->pw_name) != 0)
|
|
|
|
inconsistancy();
|
|
|
|
else if (olduid != pwd.pw_uid) {
|
|
|
|
/*
|
|
|
|
* If we're changing UID, remove the BYUID
|
|
|
|
* record for the old UID only if it has the
|
|
|
|
* same username.
|
|
|
|
*/
|
|
|
|
if (!getdbent(edp, pwd_Sdb_tmp, _PW_KEYBYUID, &olduid,
|
|
|
|
&tpwd)) {
|
|
|
|
if (strcmp(username, tpwd->pw_name) == 0) {
|
|
|
|
if (!secureonly)
|
|
|
|
deldbent(dp, pwd_db_tmp,
|
|
|
|
_PW_KEYBYUID, &olduid);
|
|
|
|
deldbent(edp, pwd_Sdb_tmp,
|
|
|
|
_PW_KEYBYUID, &olduid);
|
|
|
|
}
|
|
|
|
} else
|
|
|
|
inconsistancy();
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* If there's an existing BYUID record for the new UID and
|
|
|
|
* the username doesn't match then be sure not to overwrite
|
|
|
|
* it.
|
|
|
|
*/
|
|
|
|
if (!getdbent(edp, pwd_Sdb_tmp, _PW_KEYBYUID, &pwd.pw_uid,
|
|
|
|
&tpwd))
|
|
|
|
if (strcmp(username, tpwd->pw_name) != 0)
|
|
|
|
uid_dbflg = R_NOOVERWRITE;
|
|
|
|
|
|
|
|
/* Write the database entries out */
|
|
|
|
if (!secureonly)
|
|
|
|
putdbents(dp, &pwd, "*", flags, pwd_db_tmp, lineno,
|
|
|
|
dbflg, uid_dbflg);
|
|
|
|
putdbents(edp, &pwd, pwd.pw_passwd, flags, pwd_Sdb_tmp,
|
|
|
|
lineno, dbflg, uid_dbflg);
|
|
|
|
|
|
|
|
found = 1;
|
|
|
|
if (!makeold)
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!secureonly) {
|
|
|
|
/* Store YP token if needed. */
|
|
|
|
if (hasyp)
|
|
|
|
putyptoken(dp, pwd_db_tmp);
|
|
|
|
|
|
|
|
/* Close the insecure database. */
|
|
|
|
if ((*dp->close)(dp) < 0)
|
|
|
|
wr_error(pwd_db_tmp);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* If rebuilding the databases, we re-parse the text file and write
|
|
|
|
* the secure entries out in a separate pass.
|
|
|
|
*/
|
|
|
|
if (username == NULL) {
|
|
|
|
rewind(fp);
|
|
|
|
for (lineno = 0; scan(fp, &pwd, &flags, &lineno);)
|
|
|
|
putdbents(edp, &pwd, pwd.pw_passwd, flags, pwd_Sdb_tmp,
|
|
|
|
lineno, dbflg, uid_dbflg);
|
|
|
|
|
|
|
|
/* Store YP token if needed. */
|
|
|
|
if (hasyp)
|
|
|
|
putyptoken(edp, pwd_Sdb_tmp);
|
|
|
|
} else if (!found) {
|
|
|
|
warnx("user `%s' not found in password file", username);
|
|
|
|
bailout();
|
1994-08-29 03:32:47 +04:00
|
|
|
}
|
1995-07-28 11:13:04 +04:00
|
|
|
|
2001-08-18 23:29:31 +04:00
|
|
|
/* Close the secure database. */
|
|
|
|
if ((*edp->close)(edp) < 0)
|
|
|
|
wr_error(pwd_Sdb_tmp);
|
|
|
|
|
|
|
|
/* Install as the real password files. */
|
|
|
|
if (!secureonly)
|
|
|
|
install(pwd_db_tmp, _PATH_MP_DB);
|
|
|
|
install(pwd_Sdb_tmp, _PATH_SMP_DB);
|
1995-07-28 11:13:04 +04:00
|
|
|
|
2001-08-18 23:29:31 +04:00
|
|
|
/* Install the V7 password file. */
|
1994-08-29 03:32:47 +04:00
|
|
|
if (makeold) {
|
2000-08-07 17:19:27 +04:00
|
|
|
if (fflush(oldfp) == EOF)
|
1998-04-14 03:12:45 +04:00
|
|
|
wr_error(oldpwdfile);
|
2000-08-07 17:19:27 +04:00
|
|
|
if (fclose(oldfp) == EOF)
|
1998-04-14 03:12:45 +04:00
|
|
|
wr_error(oldpwdfile);
|
2001-08-18 23:29:31 +04:00
|
|
|
install(oldpwdfile, _PATH_PASSWD);
|
1994-08-29 03:32:47 +04:00
|
|
|
}
|
|
|
|
|
1993-03-21 12:45:37 +03:00
|
|
|
/* Set master.passwd permissions, in case caller forgot. */
|
|
|
|
(void)fchmod(fileno(fp), S_IRUSR|S_IWUSR);
|
2000-08-07 17:19:27 +04:00
|
|
|
if (fclose(fp) == EOF)
|
1998-04-14 03:12:45 +04:00
|
|
|
wr_error(pname);
|
1993-03-21 12:45:37 +03:00
|
|
|
|
2000-08-07 17:19:27 +04:00
|
|
|
/*
|
2001-08-18 23:29:31 +04:00
|
|
|
* Move the temporary master password file LAST -- chpass(1),
|
2006-11-25 01:52:16 +03:00
|
|
|
* passwd(1), vipw(8) and friends all use its existence to block
|
2001-08-18 23:29:31 +04:00
|
|
|
* other incarnations of themselves. The rename means that
|
|
|
|
* everything is unlocked, as the original file can no longer be
|
|
|
|
* accessed.
|
2000-08-07 17:19:27 +04:00
|
|
|
*/
|
|
|
|
install(pname, _PATH_MASTERPASSWD);
|
|
|
|
exit(EXIT_SUCCESS);
|
|
|
|
/* NOTREACHED */
|
1993-03-21 12:45:37 +03:00
|
|
|
}
|
|
|
|
|
1994-08-29 03:32:47 +04:00
|
|
|
int
|
2000-08-07 17:19:27 +04:00
|
|
|
scan(FILE *fp, struct passwd *pw, int *flags, int *lineno)
|
1993-03-21 12:45:37 +03:00
|
|
|
{
|
|
|
|
static char line[LINE_MAX];
|
|
|
|
char *p;
|
2000-01-23 22:59:32 +03:00
|
|
|
int oflags;
|
1993-03-21 12:45:37 +03:00
|
|
|
|
2000-08-07 17:19:27 +04:00
|
|
|
if (fgets(line, sizeof(line), fp) == NULL)
|
1994-08-29 03:32:47 +04:00
|
|
|
return (0);
|
2000-08-07 17:19:27 +04:00
|
|
|
(*lineno)++;
|
|
|
|
|
1993-03-21 12:45:37 +03:00
|
|
|
/*
|
|
|
|
* ``... if I swallow anything evil, put your fingers down my
|
|
|
|
* throat...''
|
|
|
|
* -- The Who
|
|
|
|
*/
|
2000-08-07 17:19:27 +04:00
|
|
|
if ((p = strchr(line, '\n')) == NULL) {
|
1994-08-29 03:32:47 +04:00
|
|
|
warnx("line too long");
|
2000-08-07 17:19:27 +04:00
|
|
|
errno = EFTYPE; /* XXX */
|
|
|
|
error(pname);
|
1993-03-21 12:45:37 +03:00
|
|
|
}
|
|
|
|
*p = '\0';
|
1998-06-08 07:23:07 +04:00
|
|
|
if (strcmp(line, "+") == 0)
|
|
|
|
strcpy(line, "+:::::::::"); /* pw_scan() can't handle "+" */
|
2000-01-23 22:59:32 +03:00
|
|
|
oflags = 0;
|
|
|
|
if (!pw_scan(line, pw, &oflags)) {
|
2000-08-07 17:19:27 +04:00
|
|
|
warnx("at line #%d", *lineno);
|
|
|
|
errno = EFTYPE; /* XXX */
|
1993-03-21 12:45:37 +03:00
|
|
|
error(pname);
|
|
|
|
}
|
2000-01-23 22:59:32 +03:00
|
|
|
*flags = oflags;
|
1994-08-29 03:32:47 +04:00
|
|
|
|
|
|
|
return (1);
|
1993-03-21 12:45:37 +03:00
|
|
|
}
|
|
|
|
|
1994-08-29 03:32:47 +04:00
|
|
|
void
|
2000-08-07 17:19:27 +04:00
|
|
|
install(const char *from, const char *to)
|
1993-03-21 12:45:37 +03:00
|
|
|
{
|
|
|
|
char buf[MAXPATHLEN];
|
2006-09-23 21:38:42 +04:00
|
|
|
char errbuf[BUFSIZ];
|
2000-08-07 17:19:27 +04:00
|
|
|
int sverrno;
|
1993-03-21 12:45:37 +03:00
|
|
|
|
2000-08-07 17:19:27 +04:00
|
|
|
snprintf(buf, sizeof(buf), "%s%s", prefix, to);
|
|
|
|
if (rename(from, buf)) {
|
|
|
|
sverrno = errno;
|
2006-09-23 21:38:42 +04:00
|
|
|
(void)snprintf(errbuf, sizeof(errbuf), "%s to %s", from, buf);
|
1993-03-21 12:45:37 +03:00
|
|
|
errno = sverrno;
|
2006-09-23 21:38:42 +04:00
|
|
|
error(errbuf);
|
1993-03-21 12:45:37 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2001-08-18 23:29:31 +04:00
|
|
|
void
|
|
|
|
rm(const char *victim)
|
|
|
|
{
|
|
|
|
|
|
|
|
if (unlink(victim) < 0)
|
|
|
|
warn("unlink(%s)", victim);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
cp(const char *from, const char *to, mode_t mode)
|
|
|
|
{
|
|
|
|
static char buf[MAXBSIZE];
|
|
|
|
int from_fd, rcount, to_fd, wcount, sverrno;
|
|
|
|
|
|
|
|
if ((from_fd = open(from, O_RDONLY, 0)) < 0)
|
|
|
|
error(from);
|
|
|
|
if ((to_fd = open(to, O_WRONLY | O_CREAT | O_EXCL, mode)) < 0)
|
|
|
|
error(to);
|
|
|
|
while ((rcount = read(from_fd, buf, MAXBSIZE)) > 0) {
|
|
|
|
wcount = write(to_fd, buf, rcount);
|
|
|
|
if (rcount != wcount || wcount == -1) {
|
|
|
|
sverrno = errno;
|
|
|
|
(void)snprintf(buf, sizeof(buf), "%s to %s", from, to);
|
|
|
|
errno = sverrno;
|
|
|
|
error(buf);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (rcount < 0) {
|
|
|
|
sverrno = errno;
|
|
|
|
(void)snprintf(buf, sizeof(buf), "%s to %s", from, to);
|
|
|
|
errno = sverrno;
|
|
|
|
error(buf);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
1998-04-14 03:12:45 +04:00
|
|
|
void
|
2000-08-07 17:19:27 +04:00
|
|
|
wr_error(const char *str)
|
1998-04-14 03:12:45 +04:00
|
|
|
{
|
2000-08-07 17:19:27 +04:00
|
|
|
char errbuf[BUFSIZ];
|
|
|
|
int sverrno;
|
|
|
|
|
|
|
|
sverrno = errno;
|
1998-04-14 03:12:45 +04:00
|
|
|
|
|
|
|
(void)snprintf(errbuf, sizeof(errbuf),
|
2000-08-07 17:19:27 +04:00
|
|
|
"attempt to write %s failed", str);
|
1998-04-14 03:12:45 +04:00
|
|
|
|
|
|
|
errno = sverrno;
|
|
|
|
error(errbuf);
|
|
|
|
}
|
|
|
|
|
1994-08-29 03:32:47 +04:00
|
|
|
void
|
2000-08-07 17:19:27 +04:00
|
|
|
error(const char *str)
|
1993-03-21 12:45:37 +03:00
|
|
|
{
|
1994-08-29 03:32:47 +04:00
|
|
|
|
2000-08-07 17:19:27 +04:00
|
|
|
warn("%s", str);
|
2001-08-18 23:29:31 +04:00
|
|
|
bailout();
|
1993-03-21 12:45:37 +03:00
|
|
|
}
|
|
|
|
|
1998-04-14 03:12:45 +04:00
|
|
|
void
|
2001-08-18 23:29:31 +04:00
|
|
|
inconsistancy(void)
|
1998-04-14 03:12:45 +04:00
|
|
|
{
|
2000-08-07 17:19:27 +04:00
|
|
|
|
2001-08-18 23:29:31 +04:00
|
|
|
warnx("text files and databases are inconsistent");
|
|
|
|
warnx("re-build the databases without -u");
|
|
|
|
bailout();
|
1998-04-14 03:12:45 +04:00
|
|
|
}
|
|
|
|
|
1994-08-29 03:32:47 +04:00
|
|
|
void
|
2001-08-18 23:29:31 +04:00
|
|
|
bailout(void)
|
1993-03-21 12:45:37 +03:00
|
|
|
{
|
2000-08-07 17:19:27 +04:00
|
|
|
|
2001-08-18 23:29:31 +04:00
|
|
|
if ((clean & FILE_ORIG) != 0)
|
1998-04-14 03:12:45 +04:00
|
|
|
rm(oldpwdfile);
|
2001-08-18 23:29:31 +04:00
|
|
|
if ((clean & FILE_SECURE) != 0)
|
1998-04-14 03:12:45 +04:00
|
|
|
rm(pwd_Sdb_tmp);
|
2001-08-18 23:29:31 +04:00
|
|
|
if ((clean & FILE_INSECURE) != 0)
|
1998-04-14 03:12:45 +04:00
|
|
|
rm(pwd_db_tmp);
|
2001-08-18 23:29:31 +04:00
|
|
|
|
|
|
|
exit(EXIT_FAILURE);
|
1993-03-21 12:45:37 +03:00
|
|
|
}
|
|
|
|
|
2009-01-16 13:42:36 +03:00
|
|
|
/*
|
|
|
|
* Ensures that an existing database is up to date.
|
|
|
|
*
|
|
|
|
* Makes sure that the version number of an existing database matches the
|
|
|
|
* version number setversion() writes. If it does not, this function aborts
|
|
|
|
* execution because updating the database without fully regenerating it will
|
|
|
|
* leave it inconsistent.
|
|
|
|
*/
|
2009-01-15 02:18:57 +03:00
|
|
|
void
|
2009-01-16 13:42:36 +03:00
|
|
|
checkversion(DB *dp)
|
2009-01-15 02:18:57 +03:00
|
|
|
{
|
|
|
|
DBT data, key;
|
2009-01-16 13:42:36 +03:00
|
|
|
int ret;
|
2009-01-15 02:18:57 +03:00
|
|
|
|
|
|
|
key.data = __UNCONST("VERSION");
|
|
|
|
key.size = strlen((const char *)key.data) + 1;
|
|
|
|
|
2009-01-16 13:42:36 +03:00
|
|
|
ret = (*dp->get)(dp, &key, &data, 0);
|
|
|
|
if (ret == -1) {
|
|
|
|
warnx("cannot get VERSION record from database");
|
|
|
|
bailout();
|
|
|
|
}
|
|
|
|
|
|
|
|
if (ret == 1 || *(int *)data.data != getversion()) {
|
|
|
|
warnx("databases are laid out according to an old version");
|
|
|
|
warnx("re-build the databases without -u");
|
|
|
|
bailout();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Returns the version number we write to and expect from databases.
|
|
|
|
*/
|
|
|
|
uint32_t
|
|
|
|
getversion(void)
|
|
|
|
{
|
2009-02-02 07:24:18 +03:00
|
|
|
uint32_t version = sizeof(((struct passwd *)NULL)->pw_change) != sizeof(int32_t);
|
2009-01-15 02:18:57 +03:00
|
|
|
if (lorder != BYTE_ORDER)
|
|
|
|
version = SWAP(version);
|
2009-01-16 13:42:36 +03:00
|
|
|
return version;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
setversion(DB *dp)
|
|
|
|
{
|
|
|
|
DBT data, key;
|
|
|
|
uint32_t version = getversion();
|
|
|
|
|
|
|
|
key.data = __UNCONST("VERSION");
|
|
|
|
key.size = strlen((const char *)key.data) + 1;
|
|
|
|
|
2009-01-15 02:18:57 +03:00
|
|
|
data.data = &version;
|
|
|
|
data.size = sizeof(uint32_t);
|
|
|
|
|
|
|
|
if ((*dp->put)(dp, &key, &data, R_NOOVERWRITE) == -1)
|
|
|
|
wr_error("setversion");
|
|
|
|
}
|
|
|
|
|
2000-08-07 17:19:27 +04:00
|
|
|
/*
|
|
|
|
* Write entries to a database for a single user.
|
|
|
|
*
|
|
|
|
* The databases actually contain three copies of the original data. Each
|
|
|
|
* password file entry is converted into a rough approximation of a ``struct
|
|
|
|
* passwd'', with the strings placed inline. This object is then stored as
|
|
|
|
* the data for three separate keys. The first key * is the pw_name field
|
|
|
|
* prepended by the _PW_KEYBYNAME character. The second key is the pw_uid
|
|
|
|
* field prepended by the _PW_KEYBYUID character. The third key is the line
|
|
|
|
* number in the original file prepended by the _PW_KEYBYNUM character.
|
|
|
|
* (The special characters are prepended to ensure that the keys do not
|
|
|
|
* collide.)
|
|
|
|
*/
|
|
|
|
#define COMPACT(e) for (t = e; (*p++ = *t++) != '\0';)
|
|
|
|
|
|
|
|
void
|
2001-08-18 23:29:31 +04:00
|
|
|
putdbents(DB *dp, struct passwd *pw, const char *passwd, int flags,
|
|
|
|
const char *fn, int lineno, int dbflg, int uid_dbflg)
|
2000-08-07 17:19:27 +04:00
|
|
|
{
|
|
|
|
struct passwd pwd;
|
|
|
|
char buf[MAX(MAXPATHLEN, LINE_MAX * 2)], tbuf[1024], *p;
|
|
|
|
DBT data, key;
|
|
|
|
const char *t;
|
|
|
|
u_int32_t x;
|
|
|
|
int len;
|
|
|
|
|
|
|
|
memcpy(&pwd, pw, sizeof(pwd));
|
|
|
|
data.data = (u_char *)buf;
|
|
|
|
key.data = (u_char *)tbuf;
|
|
|
|
|
|
|
|
if (lorder != BYTE_ORDER) {
|
2009-01-15 02:18:57 +03:00
|
|
|
pwd.pw_uid = SWAP(pwd.pw_uid);
|
|
|
|
pwd.pw_gid = SWAP(pwd.pw_gid);
|
|
|
|
pwd.pw_change = SWAP(pwd.pw_change);
|
|
|
|
pwd.pw_expire = SWAP(pwd.pw_expire);
|
2000-08-07 17:19:27 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Create insecure data. */
|
|
|
|
p = buf;
|
|
|
|
COMPACT(pwd.pw_name);
|
|
|
|
COMPACT(passwd);
|
|
|
|
memmove(p, &pwd.pw_uid, sizeof(pwd.pw_uid));
|
|
|
|
p += sizeof(pwd.pw_uid);
|
|
|
|
memmove(p, &pwd.pw_gid, sizeof(pwd.pw_gid));
|
|
|
|
p += sizeof(pwd.pw_gid);
|
|
|
|
memmove(p, &pwd.pw_change, sizeof(pwd.pw_change));
|
|
|
|
p += sizeof(pwd.pw_change);
|
|
|
|
COMPACT(pwd.pw_class);
|
|
|
|
COMPACT(pwd.pw_gecos);
|
|
|
|
COMPACT(pwd.pw_dir);
|
|
|
|
COMPACT(pwd.pw_shell);
|
|
|
|
memmove(p, &pwd.pw_expire, sizeof(pwd.pw_expire));
|
|
|
|
p += sizeof(pwd.pw_expire);
|
|
|
|
x = flags;
|
|
|
|
if (lorder != BYTE_ORDER)
|
2009-01-15 02:18:57 +03:00
|
|
|
x = SWAP(x);
|
2000-08-07 17:19:27 +04:00
|
|
|
memmove(p, &x, sizeof(x));
|
|
|
|
p += sizeof(flags);
|
|
|
|
data.size = p - buf;
|
|
|
|
|
|
|
|
/* Store insecure by name. */
|
|
|
|
tbuf[0] = _PW_KEYBYNAME;
|
|
|
|
len = strlen(pwd.pw_name);
|
|
|
|
memmove(tbuf + 1, pwd.pw_name, len);
|
|
|
|
key.size = len + 1;
|
2001-08-18 23:29:31 +04:00
|
|
|
if ((*dp->put)(dp, &key, &data, dbflg) == -1)
|
2000-08-07 17:19:27 +04:00
|
|
|
wr_error(fn);
|
2001-08-18 23:29:31 +04:00
|
|
|
|
2000-08-07 17:19:27 +04:00
|
|
|
/* Store insecure by number. */
|
|
|
|
tbuf[0] = _PW_KEYBYNUM;
|
|
|
|
x = lineno;
|
|
|
|
if (lorder != BYTE_ORDER)
|
2009-01-15 02:18:57 +03:00
|
|
|
x = SWAP(x);
|
2000-08-07 17:19:27 +04:00
|
|
|
memmove(tbuf + 1, &x, sizeof(x));
|
|
|
|
key.size = sizeof(x) + 1;
|
2001-08-18 23:29:31 +04:00
|
|
|
if ((*dp->put)(dp, &key, &data, dbflg) == -1)
|
2000-08-07 17:19:27 +04:00
|
|
|
wr_error(fn);
|
|
|
|
|
|
|
|
/* Store insecure by uid. */
|
|
|
|
tbuf[0] = _PW_KEYBYUID;
|
|
|
|
memmove(tbuf + 1, &pwd.pw_uid, sizeof(pwd.pw_uid));
|
|
|
|
key.size = sizeof(pwd.pw_uid) + 1;
|
2001-08-18 23:29:31 +04:00
|
|
|
if ((*dp->put)(dp, &key, &data, uid_dbflg) == -1)
|
|
|
|
wr_error(fn);
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
deldbent(DB *dp, const char *fn, int type, void *keyp)
|
|
|
|
{
|
|
|
|
char tbuf[1024];
|
|
|
|
DBT key;
|
|
|
|
u_int32_t x;
|
|
|
|
int len, rv;
|
|
|
|
|
|
|
|
key.data = (u_char *)tbuf;
|
|
|
|
|
|
|
|
switch (tbuf[0] = type) {
|
|
|
|
case _PW_KEYBYNAME:
|
|
|
|
len = strlen((char *)keyp);
|
|
|
|
memcpy(tbuf + 1, keyp, len);
|
|
|
|
key.size = len + 1;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case _PW_KEYBYNUM:
|
|
|
|
case _PW_KEYBYUID:
|
|
|
|
x = *(int *)keyp;
|
|
|
|
if (lorder != BYTE_ORDER)
|
2009-01-15 02:18:57 +03:00
|
|
|
x = SWAP(x);
|
2001-08-18 23:29:31 +04:00
|
|
|
memmove(tbuf + 1, &x, sizeof(x));
|
|
|
|
key.size = sizeof(x) + 1;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((rv = (*dp->del)(dp, &key, 0)) == -1)
|
2000-08-07 17:19:27 +04:00
|
|
|
wr_error(fn);
|
2001-08-18 23:29:31 +04:00
|
|
|
return (rv);
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
getdbent(DB *dp, const char *fn, int type, void *keyp, struct passwd **tpwd)
|
|
|
|
{
|
|
|
|
static char buf[MAX(MAXPATHLEN, LINE_MAX * 2)];
|
|
|
|
static struct passwd pwd;
|
|
|
|
char tbuf[1024], *p;
|
|
|
|
DBT key, data;
|
|
|
|
u_int32_t x;
|
|
|
|
int len, rv;
|
|
|
|
|
|
|
|
data.data = (u_char *)buf;
|
|
|
|
data.size = sizeof(buf);
|
|
|
|
key.data = (u_char *)tbuf;
|
|
|
|
|
|
|
|
switch (tbuf[0] = type) {
|
|
|
|
case _PW_KEYBYNAME:
|
|
|
|
len = strlen((char *)keyp);
|
|
|
|
memcpy(tbuf + 1, keyp, len);
|
|
|
|
key.size = len + 1;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case _PW_KEYBYNUM:
|
|
|
|
case _PW_KEYBYUID:
|
|
|
|
x = *(int *)keyp;
|
|
|
|
if (lorder != BYTE_ORDER)
|
2009-01-15 02:18:57 +03:00
|
|
|
x = SWAP(x);
|
2001-08-18 23:29:31 +04:00
|
|
|
memmove(tbuf + 1, &x, sizeof(x));
|
|
|
|
key.size = sizeof(x) + 1;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((rv = (*dp->get)(dp, &key, &data, 0)) == 1)
|
|
|
|
return (rv);
|
|
|
|
if (rv == -1)
|
|
|
|
error(pwd_Sdb_tmp);
|
|
|
|
|
|
|
|
p = (char *)data.data;
|
|
|
|
|
|
|
|
pwd.pw_name = p;
|
|
|
|
while (*p++ != '\0')
|
|
|
|
;
|
|
|
|
pwd.pw_passwd = p;
|
|
|
|
while (*p++ != '\0')
|
|
|
|
;
|
|
|
|
|
|
|
|
memcpy(&pwd.pw_uid, p, sizeof(pwd.pw_uid));
|
|
|
|
p += sizeof(pwd.pw_uid);
|
|
|
|
memcpy(&pwd.pw_gid, p, sizeof(pwd.pw_gid));
|
|
|
|
p += sizeof(pwd.pw_gid);
|
|
|
|
memcpy(&pwd.pw_change, p, sizeof(pwd.pw_change));
|
|
|
|
p += sizeof(pwd.pw_change);
|
|
|
|
|
|
|
|
pwd.pw_class = p;
|
|
|
|
while (*p++ != '\0')
|
|
|
|
;
|
|
|
|
pwd.pw_gecos = p;
|
|
|
|
while (*p++ != '\0')
|
|
|
|
;
|
|
|
|
pwd.pw_dir = p;
|
|
|
|
while (*p++ != '\0')
|
|
|
|
;
|
|
|
|
pwd.pw_shell = p;
|
|
|
|
while (*p++ != '\0')
|
|
|
|
;
|
|
|
|
|
|
|
|
memcpy(&pwd.pw_expire, p, sizeof(pwd.pw_expire));
|
|
|
|
p += sizeof(pwd.pw_expire);
|
|
|
|
|
|
|
|
if (lorder != BYTE_ORDER) {
|
2009-01-15 02:18:57 +03:00
|
|
|
pwd.pw_uid = SWAP(pwd.pw_uid);
|
|
|
|
pwd.pw_gid = SWAP(pwd.pw_gid);
|
|
|
|
pwd.pw_change = SWAP(pwd.pw_change);
|
|
|
|
pwd.pw_expire = SWAP(pwd.pw_expire);
|
2001-08-18 23:29:31 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
*tpwd = &pwd;
|
|
|
|
return (0);
|
2000-08-07 17:19:27 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
putyptoken(DB *dp, const char *fn)
|
|
|
|
{
|
|
|
|
DBT data, key;
|
|
|
|
|
|
|
|
key.data = (u_char *)__yp_token;
|
|
|
|
key.size = strlen(__yp_token);
|
|
|
|
data.data = (u_char *)NULL;
|
|
|
|
data.size = 0;
|
|
|
|
|
2001-08-18 23:29:31 +04:00
|
|
|
if ((*dp->put)(dp, &key, &data, R_NOOVERWRITE) == -1)
|
2000-08-07 17:19:27 +04:00
|
|
|
wr_error(fn);
|
|
|
|
}
|
|
|
|
|
1994-08-29 03:32:47 +04:00
|
|
|
void
|
2000-08-07 17:19:27 +04:00
|
|
|
usage(void)
|
1993-03-21 12:45:37 +03:00
|
|
|
{
|
1994-08-29 03:32:47 +04:00
|
|
|
|
2001-08-18 23:29:31 +04:00
|
|
|
(void)fprintf(stderr,
|
2006-09-23 21:17:04 +04:00
|
|
|
"usage: pwd_mkdb [-BLps] [-c cachesize] [-d directory] [-u user] file\n");
|
2000-08-07 17:19:27 +04:00
|
|
|
exit(EXIT_FAILURE);
|
1993-03-21 12:45:37 +03:00
|
|
|
}
|