404 lines
9.3 KiB
C
404 lines
9.3 KiB
C
/*
|
|
* Copyright 1990 - 1994, Julianne Frances Haugh
|
|
* 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.
|
|
* 3. Neither the name of Julianne F. Haugh 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 JULIE HAUGH 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 JULIE HAUGH 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.
|
|
*/
|
|
|
|
#include <config.h>
|
|
|
|
#include "rcsid.h"
|
|
RCSID (PKG_VER "$Id: mkpasswd.c,v 1.9 2002/01/05 15:41:43 kloczek Exp $")
|
|
#include <sys/stat.h>
|
|
#include "prototypes.h"
|
|
#include "defines.h"
|
|
#include <stdio.h>
|
|
#if !defined(NDBM) /*{ */
|
|
int main (int argc, char **argv)
|
|
{
|
|
setlocale (LC_ALL, "");
|
|
bindtextdomain (PACKAGE, LOCALEDIR);
|
|
textdomain (PACKAGE);
|
|
|
|
fprintf (stderr,
|
|
_
|
|
("%s: no DBM database on system - no action performed\n"),
|
|
argv[0]);
|
|
return 0;
|
|
}
|
|
|
|
#else /*} defined(NDBM) { */
|
|
#include <fcntl.h>
|
|
#include <pwd.h>
|
|
#include <ndbm.h>
|
|
#include <grp.h>
|
|
extern DBM *pw_dbm;
|
|
extern DBM *gr_dbm;
|
|
|
|
#ifdef SHADOWPWD
|
|
extern DBM *sp_dbm;
|
|
#endif
|
|
#ifdef SHADOWGRP
|
|
extern DBM *sg_dbm;
|
|
#endif
|
|
char *fgetsx ();
|
|
|
|
char *Progname;
|
|
int vflg = 0;
|
|
int fflg = 0;
|
|
int gflg = 0;
|
|
int sflg = 0; /* -s flag -- leave in, makes code nicer */
|
|
int pflg = 0;
|
|
|
|
extern struct passwd *sgetpwent ();
|
|
extern int pw_dbm_update ();
|
|
|
|
extern struct group *sgetgrent ();
|
|
extern int gr_dbm_update ();
|
|
|
|
#ifdef SHADOWPWD
|
|
extern struct spwd *sgetspent ();
|
|
extern int sp_dbm_update ();
|
|
#endif
|
|
|
|
#ifdef SHADOWGRP
|
|
extern struct sgrp *sgetsgent ();
|
|
extern int sg_dbm_update ();
|
|
#endif
|
|
|
|
/* local function prototypes */
|
|
static void usage (void);
|
|
|
|
/*
|
|
* mkpasswd - create DBM files for /etc/passwd-like input file
|
|
*
|
|
* mkpasswd takes an an argument the name of a file in /etc/passwd format
|
|
* and creates a DBM file keyed by user ID and name. The output files have
|
|
* the same name as the input file, with .dir and .pag appended.
|
|
*
|
|
* this command will also create look-aside files for
|
|
* /etc/group, /etc/shadow, and /etc/gshadow.
|
|
*/
|
|
|
|
int main (int argc, char **argv)
|
|
{
|
|
extern int optind;
|
|
extern char *optarg;
|
|
FILE *fp; /* File pointer for input file */
|
|
char *file; /* Name of input file */
|
|
char *dir; /* Name of .dir file */
|
|
char *pag; /* Name of .pag file */
|
|
char *cp; /* Temporary character pointer */
|
|
int flag; /* Flag for command line option */
|
|
int cnt = 0; /* Number of entries in database */
|
|
int longest = 0; /* Longest entry in database */
|
|
int len; /* Length of input line */
|
|
int errors = 0; /* Count of errors processing file */
|
|
char buf[BUFSIZ * 8]; /* Input line from file */
|
|
struct passwd *passwd = NULL; /* Pointer to password file entry */
|
|
|
|
struct group *group = NULL; /* Pointer to group file entry */
|
|
|
|
#ifdef SHADOWPWD
|
|
struct spwd *shadow = NULL; /* Pointer to shadow passwd entry */
|
|
#endif
|
|
#ifdef SHADOWGRP
|
|
struct sgrp *gshadow = NULL; /* Pointer to shadow group entry */
|
|
#endif
|
|
DBM *dbm; /* Pointer to new NDBM files */
|
|
DBM *dbm_open (); /* Function to open NDBM files */
|
|
|
|
/*
|
|
* Figure out what my name is. I will use this later ...
|
|
*/
|
|
|
|
Progname = Basename (argv[0]);
|
|
|
|
/*
|
|
* Figure out what the flags might be ...
|
|
*/
|
|
|
|
while ((flag = getopt (argc, argv, "fvpgs")) != EOF) {
|
|
switch (flag) {
|
|
case 'v':
|
|
vflg++;
|
|
break;
|
|
case 'f':
|
|
fflg++;
|
|
break;
|
|
case 'g':
|
|
gflg++;
|
|
#ifndef SHADOWGRP
|
|
if (sflg)
|
|
usage ();
|
|
#endif
|
|
if (pflg)
|
|
usage ();
|
|
|
|
break;
|
|
#if defined(SHADOWPWD) || defined(SHADOWGRP)
|
|
case 's':
|
|
sflg++;
|
|
#ifndef SHADOWGRP
|
|
if (gflg)
|
|
usage ();
|
|
#endif
|
|
break;
|
|
#endif
|
|
case 'p':
|
|
pflg++;
|
|
if (gflg)
|
|
usage ();
|
|
|
|
break;
|
|
default:
|
|
usage ();
|
|
}
|
|
}
|
|
|
|
/*
|
|
* Backwards compatibility fix for -p flag ...
|
|
*/
|
|
|
|
#ifdef SHADOWPWD
|
|
if (!sflg && !gflg)
|
|
#else
|
|
if (!gflg)
|
|
#endif
|
|
pflg++;
|
|
|
|
/*
|
|
* The last and only remaining argument must be the file name
|
|
*/
|
|
|
|
if (argc - 1 != optind)
|
|
usage ();
|
|
|
|
file = argv[optind];
|
|
|
|
if (!(fp = fopen (file, "r"))) {
|
|
fprintf (stderr, _("%s: cannot open file %s\n"), Progname,
|
|
file);
|
|
exit (1);
|
|
}
|
|
|
|
/*
|
|
* Make the filenames for the two DBM files.
|
|
*/
|
|
|
|
dir = xmalloc (strlen (file) + 5); /* space for .dir file */
|
|
strcat (strcpy (dir, file), ".dir");
|
|
|
|
pag = xmalloc (strlen (file) + 5); /* space for .pag file */
|
|
strcat (strcpy (pag, file), ".pag");
|
|
|
|
/*
|
|
* Remove existing files if requested.
|
|
*/
|
|
|
|
if (fflg) {
|
|
(void) unlink (dir);
|
|
(void) unlink (pag);
|
|
}
|
|
|
|
/*
|
|
* Create the two DBM files - it is an error for these files
|
|
* to have existed already.
|
|
*/
|
|
|
|
if (access (dir, F_OK) == 0) {
|
|
fprintf (stderr, _("%s: cannot overwrite file %s\n"),
|
|
Progname, dir);
|
|
exit (1);
|
|
}
|
|
if (access (pag, F_OK) == 0) {
|
|
fprintf (stderr, _("%s: cannot overwrite file %s\n"),
|
|
Progname, pag);
|
|
exit (1);
|
|
}
|
|
|
|
if (sflg)
|
|
umask (077);
|
|
else
|
|
umask (022);
|
|
|
|
/*
|
|
* Now the DBM database gets initialized
|
|
*/
|
|
|
|
if (!(dbm = dbm_open (file, O_RDWR | O_CREAT, 0644))) {
|
|
fprintf (stderr, _("%s: cannot open DBM files for %s\n"),
|
|
Progname, file);
|
|
exit (1);
|
|
}
|
|
if (gflg) {
|
|
#ifdef SHADOWGRP
|
|
if (sflg)
|
|
sg_dbm = dbm;
|
|
else
|
|
#endif
|
|
gr_dbm = dbm;
|
|
} else {
|
|
#ifdef SHADOWPWD
|
|
if (sflg)
|
|
sp_dbm = dbm;
|
|
else
|
|
#endif
|
|
pw_dbm = dbm;
|
|
}
|
|
|
|
/*
|
|
* Read every line in the password file and convert it into a data
|
|
* structure to be put in the DBM database files.
|
|
*/
|
|
|
|
while (fgetsx (buf, BUFSIZ, fp) != NULL) {
|
|
|
|
/*
|
|
* Get the next line and strip off the trailing newline
|
|
* character.
|
|
*/
|
|
|
|
buf[sizeof buf - 1] = '\0';
|
|
if (!(cp = strchr (buf, '\n'))) {
|
|
fprintf (stderr,
|
|
_("%s: the beginning with " %
|
|
.16 s..." is too long\n"), Progname,
|
|
buf);
|
|
exit (1);
|
|
}
|
|
*cp = '\0';
|
|
len = strlen (buf);
|
|
|
|
#ifdef USE_NIS
|
|
/*
|
|
* Parse the password file line into a (struct passwd).
|
|
* Erroneous lines cause error messages, but that's all. YP
|
|
* lines are ignored completely.
|
|
*/
|
|
|
|
if (buf[0] == '-' || buf[0] == '+')
|
|
continue;
|
|
#endif
|
|
if (!(((!sflg && pflg) && (passwd = sgetpwent (buf)))
|
|
#ifdef SHADOWPWD
|
|
|| ((sflg && pflg) && (shadow = sgetspent (buf)))
|
|
#endif
|
|
|| ((!sflg && gflg) && (group = sgetgrent (buf)))
|
|
#ifdef SHADOWGRP
|
|
|| ((sflg && gflg) && (gshadow = sgetsgent (buf)))
|
|
#endif
|
|
)) {
|
|
fprintf (stderr,
|
|
_("%s: error parsing line \"%s\"\n"),
|
|
Progname, buf);
|
|
errors++;
|
|
continue;
|
|
}
|
|
if (vflg) {
|
|
if (!sflg && pflg)
|
|
printf (_
|
|
("adding record for name " %
|
|
s "\n"), passwd->pw_name);
|
|
#ifdef SHADOWPWD
|
|
if (sflg && pflg)
|
|
printf (_
|
|
("adding record for name " %
|
|
s "\n"), shadow->sp_namp);
|
|
#endif
|
|
if (!sflg && gflg)
|
|
printf (_
|
|
("adding record for name " %
|
|
s "\n"), group->gr_name);
|
|
#ifdef SHADOWGRP
|
|
if (sflg && gflg)
|
|
printf (_
|
|
("adding record for name " %
|
|
s "\n"), gshadow->sg_name);
|
|
#endif
|
|
}
|
|
if (!sflg && pflg && !pw_dbm_update (passwd))
|
|
fprintf (stderr,
|
|
_("%s: error adding record for " %
|
|
s "\n"), Progname, passwd->pw_name);
|
|
|
|
#ifdef SHADOWPWD
|
|
if (sflg && pflg && !sp_dbm_update (shadow))
|
|
fprintf (stderr,
|
|
_("%s: error adding record for " %
|
|
s "\n"), Progname, shadow->sp_namp);
|
|
#endif
|
|
if (!sflg && gflg && !gr_dbm_update (group))
|
|
fprintf (stderr,
|
|
_("%s: error adding record for " %
|
|
s "\n"), Progname, group->gr_name);
|
|
#ifdef SHADOWGRP
|
|
if (sflg && gflg && !sg_dbm_update (gshadow))
|
|
fprintf (stderr,
|
|
_("%s: error adding record for " %
|
|
s "\n"), Progname, gshadow->sg_name);
|
|
#endif /* SHADOWGRP */
|
|
|
|
/*
|
|
* Update the longest record and record count
|
|
*/
|
|
|
|
if (len > longest)
|
|
longest = len;
|
|
cnt++;
|
|
}
|
|
|
|
/*
|
|
* Tell the user how things went ...
|
|
*/
|
|
|
|
if (vflg)
|
|
printf (_("added %d entries, longest was %d\n"), cnt,
|
|
longest);
|
|
|
|
exit (errors);
|
|
/*NOTREACHED*/}
|
|
|
|
/*
|
|
* usage - print error message and exit
|
|
*/
|
|
|
|
static void usage (void)
|
|
{
|
|
#ifdef SHADOWPWD
|
|
#ifdef SHADOWGRP
|
|
fprintf (stderr, _("Usage: %s [-vf] [-p|g|sp|sg] file\n"),
|
|
Progname);
|
|
#else /* !SHADOWGRP */
|
|
fprintf (stderr, _("Usage: %s [-vf] [-p|g|sp] file\n"), Progname);
|
|
#endif /* SHADOWGRP */
|
|
#else /* !SHADOWPWD */
|
|
fprintf (stderr, _("Usage: %s [-vf] [-p|g] file\n"), Progname);
|
|
#endif /* SHADOWPWD */
|
|
|
|
exit (1);
|
|
/*NOTREACHED*/}
|
|
#endif /*} defined(NDBM) */
|