xref: /csrg-svn/old/mkpasswd/mkpasswd.c (revision 55329)
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