Files
shadow/src/mkpasswd.c
T

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) */