121151Sdist /*
233137Sbostic * Copyright (c) 1980, 1983 Regents of the University of California.
333137Sbostic * All rights reserved.
433137Sbostic *
542815Sbostic * %sccs.include.redist.c%
621151Sdist */
721151Sdist
815664Sralph #ifndef lint
921151Sdist char copyright[] =
1033137Sbostic "@(#) Copyright (c) 1980, 1983 Regents of the University of California.\n\
1121151Sdist All rights reserved.\n";
1233137Sbostic #endif /* not lint */
1315664Sralph
1421151Sdist #ifndef lint
15*55329Sbostic static char sccsid[] = "@(#)mkpasswd.c 5.7 (Berkeley) 07/17/92";
1633137Sbostic #endif /* not lint */
1721151Sdist
1836859Sbostic #include <sys/param.h>
1915664Sralph #include <sys/file.h>
2036859Sbostic #include <ndbm.h>
2136859Sbostic #include <pwd.h>
2215664Sralph #include <stdio.h>
2315664Sralph
2436859Sbostic static FILE *_pw_fp;
2536859Sbostic static struct passwd _pw_passwd;
2636859Sbostic static off_t offset;
2736859Sbostic
2836859Sbostic #define MAXLINELENGTH 1024
2936859Sbostic static char line[MAXLINELENGTH];
3036859Sbostic
3136859Sbostic /*
3236859Sbostic * Mkpasswd does two things -- use the ``arg'' file to create ``arg''.{pag,dir}
3336859Sbostic * for ndbm, and, if the -p flag is on, create a password file in the original
3436859Sbostic * format. It doesn't use the getpwent(3) routines because it has to figure
3536859Sbostic * out offsets for the encrypted passwords to put in the dbm files. One other
3636859Sbostic * problem is that, since the addition of shadow passwords, getpwent(3) has to
3736859Sbostic * use the dbm databases rather than simply scanning the actual file. This
3836859Sbostic * required the addition of a flag field to the dbm database to distinguish
3936859Sbostic * between a record keyed by name, and one keyed by uid.
4036859Sbostic */
4136859Sbostic
main(argc,argv)4215664Sralph main(argc, argv)
4333137Sbostic int argc;
4436859Sbostic char **argv;
4515664Sralph {
4636859Sbostic extern int errno, optind;
4736859Sbostic register char *flag, *p, *t;
4836859Sbostic register int makeold;
4936859Sbostic FILE *oldfp;
5015664Sralph DBM *dp;
5115664Sralph datum key, content;
5236859Sbostic int ch;
5336859Sbostic char buf[8192], nbuf[50], *strerror();
54*55329Sbostic static int scanpw();
5515664Sralph
5636859Sbostic makeold = 0;
5736859Sbostic while ((ch = getopt(argc, argv, "pv")) != EOF)
5836859Sbostic switch(ch) {
5936859Sbostic case 'p': /* create ``password.orig'' */
6036859Sbostic makeold = 1;
6136859Sbostic /* FALLTHROUGH */
6236859Sbostic case 'v': /* backward compatible */
6336859Sbostic break;
6436859Sbostic case '?':
6536859Sbostic default:
6636859Sbostic usage();
6736859Sbostic }
6836859Sbostic argc -= optind;
6936859Sbostic argv += optind;
7036859Sbostic
7136859Sbostic if (argc != 1)
7236859Sbostic usage();
7336859Sbostic
7436859Sbostic if (!(_pw_fp = fopen(*argv, "r"))) {
7536859Sbostic (void)fprintf(stderr,
7636859Sbostic "mkpasswd: %s: can't open for reading.\n", *argv);
7715664Sralph exit(1);
7815664Sralph }
7936859Sbostic
8036859Sbostic rmall(*argv);
8133137Sbostic (void)umask(0);
8236859Sbostic
8336859Sbostic /* open old password format file, dbm files */
8436859Sbostic if (makeold) {
8536859Sbostic int oldfd;
8636859Sbostic
8736859Sbostic (void)sprintf(buf, "%s.orig", *argv);
8836859Sbostic if ((oldfd = open(buf, O_WRONLY|O_CREAT|O_EXCL, 0644)) < 0) {
8936859Sbostic (void)fprintf(stderr, "mkpasswd: %s: %s\n", buf,
9036859Sbostic strerror(errno));
9117308Sralph exit(1);
9217308Sralph }
9336859Sbostic if (!(oldfp = fdopen(oldfd, "w"))) {
9436859Sbostic (void)fprintf(stderr, "mkpasswd: %s: fdopen failed.\n",
9536859Sbostic buf);
9617308Sralph exit(1);
9717308Sralph }
9815664Sralph }
9936859Sbostic if (!(dp = dbm_open(*argv, O_WRONLY|O_CREAT|O_EXCL, 0644))) {
10036859Sbostic (void)fprintf(stderr, "mkpasswd: %s: %s\n", *argv,
10136859Sbostic strerror(errno));
10236859Sbostic exit(1);
10336859Sbostic }
10436859Sbostic
10536859Sbostic content.dptr = buf;
10636859Sbostic while (scanpw()) {
10736859Sbostic /* create dbm entry */
10836859Sbostic p = buf;
10936859Sbostic #define COMPACT(e) t = e; while (*p++ = *t++);
11036859Sbostic COMPACT(_pw_passwd.pw_name);
11136859Sbostic (void)sprintf(nbuf, "%ld", offset);
11236859Sbostic COMPACT(nbuf);
11336859Sbostic bcopy((char *)&_pw_passwd.pw_uid, p, sizeof(int));
11436859Sbostic p += sizeof(int);
11536859Sbostic bcopy((char *)&_pw_passwd.pw_gid, p, sizeof(int));
11636859Sbostic p += sizeof(int);
11736859Sbostic bcopy((char *)&_pw_passwd.pw_change, p, sizeof(time_t));
11836859Sbostic p += sizeof(time_t);
11936859Sbostic COMPACT(_pw_passwd.pw_class);
12036859Sbostic COMPACT(_pw_passwd.pw_gecos);
12136859Sbostic COMPACT(_pw_passwd.pw_dir);
12236859Sbostic COMPACT(_pw_passwd.pw_shell);
12336859Sbostic bcopy((char *)&_pw_passwd.pw_expire, p, sizeof(time_t));
12436859Sbostic p += sizeof(time_t);
12536859Sbostic flag = p;
12636859Sbostic *p++ = _PW_KEYBYNAME;
12736859Sbostic content.dsize = p - buf;
12836859Sbostic #ifdef debug
12936859Sbostic (void)printf("store %s, uid %d\n", _pw_passwd.pw_name,
13036859Sbostic _pw_passwd.pw_uid);
13136859Sbostic #endif
13236859Sbostic key.dptr = _pw_passwd.pw_name;
13336859Sbostic key.dsize = strlen(_pw_passwd.pw_name);
13436859Sbostic if (dbm_store(dp, key, content, DBM_INSERT) < 0)
13536859Sbostic goto bad;
13636859Sbostic key.dptr = (char *)&_pw_passwd.pw_uid;
13736859Sbostic key.dsize = sizeof(int);
13836859Sbostic *flag = _PW_KEYBYUID;
13936859Sbostic if (dbm_store(dp, key, content, DBM_INSERT) < 0)
14036859Sbostic goto bad;
14136859Sbostic
14236859Sbostic /* create original format password file entry */
14336859Sbostic if (!makeold)
14436859Sbostic continue;
14536859Sbostic fprintf(oldfp, "%s:*:%d:%d:%s:%s:%s\n", _pw_passwd.pw_name,
14636859Sbostic _pw_passwd.pw_uid, _pw_passwd.pw_gid, _pw_passwd.pw_gecos,
14736859Sbostic _pw_passwd.pw_dir, _pw_passwd.pw_shell);
14836859Sbostic }
14917308Sralph dbm_close(dp);
15015664Sralph exit(0);
15136859Sbostic
15236859Sbostic bad: (void)fprintf(stderr, "mkpasswd: dbm_store failed.\n");
15336859Sbostic rmall(*argv);
15436859Sbostic exit(1);
15515664Sralph }
15636859Sbostic
rmall(fname)15736859Sbostic rmall(fname)
15836859Sbostic char *fname;
15936859Sbostic {
16036859Sbostic register char *p;
16136859Sbostic char buf[MAXPATHLEN], *strcpy();
16236859Sbostic
16336859Sbostic for (p = strcpy(buf, fname); *p; ++p);
16436859Sbostic bcopy(".pag", p, 5);
16536859Sbostic (void)unlink(buf);
16636859Sbostic bcopy(".dir", p, 5);
16736859Sbostic (void)unlink(buf);
16836859Sbostic bcopy(".orig", p, 6);
16936859Sbostic (void)unlink(buf);
17036859Sbostic }
17136859Sbostic
usage()17236859Sbostic usage()
17336859Sbostic {
17436859Sbostic (void)fprintf(stderr, "usage: mkpasswd [-p] passwd_file\n");
17536859Sbostic exit(1);
17636859Sbostic }
17736859Sbostic
17836859Sbostic /* from libc/gen/getpwent.c */
17936859Sbostic
18036859Sbostic static
scanpw()18136859Sbostic scanpw()
18236859Sbostic {
18336859Sbostic register char *cp;
18436859Sbostic long atol(), ftell();
18541567Smarc char *bp;
18636859Sbostic char *fgets(), *strsep(), *index();
18736859Sbostic
18836859Sbostic for (;;) {
18936859Sbostic offset = ftell(_pw_fp);
19036859Sbostic if (!(fgets(line, sizeof(line), _pw_fp)))
19136859Sbostic return(0);
19236859Sbostic /* skip lines that are too big */
19336859Sbostic if (!index(line, '\n')) {
19436859Sbostic int ch;
19536859Sbostic
19636859Sbostic while ((ch = getc(_pw_fp)) != '\n' && ch != EOF)
19736859Sbostic ;
19836859Sbostic continue;
19936859Sbostic }
20041567Smarc bp = line;
20141567Smarc _pw_passwd.pw_name = strsep(&bp, ":\n");
20241567Smarc _pw_passwd.pw_passwd = strsep(&bp, ":\n");
20336859Sbostic offset += _pw_passwd.pw_passwd - line;
20441567Smarc if (!(cp = strsep(&bp, ":\n")))
20536859Sbostic continue;
20636859Sbostic _pw_passwd.pw_uid = atoi(cp);
20741567Smarc if (!(cp = strsep(&bp, ":\n")))
20836859Sbostic continue;
20936859Sbostic _pw_passwd.pw_gid = atoi(cp);
21041567Smarc _pw_passwd.pw_class = strsep(&bp, ":\n");
21141567Smarc if (!(cp = strsep(&bp, ":\n")))
21236859Sbostic continue;
21336859Sbostic _pw_passwd.pw_change = atol(cp);
21441567Smarc if (!(cp = strsep(&bp, ":\n")))
21536859Sbostic continue;
21636859Sbostic _pw_passwd.pw_expire = atol(cp);
21741567Smarc _pw_passwd.pw_gecos = strsep(&bp, ":\n");
21841567Smarc _pw_passwd.pw_dir = strsep(&bp, ":\n");
21941567Smarc _pw_passwd.pw_shell = strsep(&bp, ":\n");
22036859Sbostic return(1);
22136859Sbostic }
22236859Sbostic /* NOTREACHED */
22336859Sbostic }
224