121151Sdist /* 233137Sbostic * Copyright (c) 1980, 1983 Regents of the University of California. 333137Sbostic * All rights reserved. 433137Sbostic * 533137Sbostic * Redistribution and use in source and binary forms are permitted 634778Sbostic * provided that the above copyright notice and this paragraph are 734778Sbostic * duplicated in all such forms and that any documentation, 834778Sbostic * advertising materials, and other materials related to such 934778Sbostic * distribution and use acknowledge that the software was developed 1034778Sbostic * by the University of California, Berkeley. The name of the 1134778Sbostic * University may not be used to endorse or promote products derived 1234778Sbostic * from this software without specific prior written permission. 1334778Sbostic * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 1434778Sbostic * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 1534778Sbostic * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. 1621151Sdist */ 1721151Sdist 1815664Sralph #ifndef lint 1921151Sdist char copyright[] = 2033137Sbostic "@(#) Copyright (c) 1980, 1983 Regents of the University of California.\n\ 2121151Sdist All rights reserved.\n"; 2233137Sbostic #endif /* not lint */ 2315664Sralph 2421151Sdist #ifndef lint 25*41567Smarc static char sccsid[] = "@(#)mkpasswd.c 5.5 (Berkeley) 05/10/90"; 2633137Sbostic #endif /* not lint */ 2721151Sdist 2836859Sbostic #include <sys/param.h> 2915664Sralph #include <sys/file.h> 3036859Sbostic #include <ndbm.h> 3136859Sbostic #include <pwd.h> 3215664Sralph #include <stdio.h> 3315664Sralph 3436859Sbostic static FILE *_pw_fp; 3536859Sbostic static struct passwd _pw_passwd; 3636859Sbostic static off_t offset; 3736859Sbostic 3836859Sbostic #define MAXLINELENGTH 1024 3936859Sbostic static char line[MAXLINELENGTH]; 4036859Sbostic 4136859Sbostic /* 4236859Sbostic * Mkpasswd does two things -- use the ``arg'' file to create ``arg''.{pag,dir} 4336859Sbostic * for ndbm, and, if the -p flag is on, create a password file in the original 4436859Sbostic * format. It doesn't use the getpwent(3) routines because it has to figure 4536859Sbostic * out offsets for the encrypted passwords to put in the dbm files. One other 4636859Sbostic * problem is that, since the addition of shadow passwords, getpwent(3) has to 4736859Sbostic * use the dbm databases rather than simply scanning the actual file. This 4836859Sbostic * required the addition of a flag field to the dbm database to distinguish 4936859Sbostic * between a record keyed by name, and one keyed by uid. 5036859Sbostic */ 5136859Sbostic 5215664Sralph main(argc, argv) 5333137Sbostic int argc; 5436859Sbostic char **argv; 5515664Sralph { 5636859Sbostic extern int errno, optind; 5736859Sbostic register char *flag, *p, *t; 5836859Sbostic register int makeold; 5936859Sbostic FILE *oldfp; 6015664Sralph DBM *dp; 6115664Sralph datum key, content; 6236859Sbostic int ch; 6336859Sbostic char buf[8192], nbuf[50], *strerror(); 6415664Sralph 6536859Sbostic makeold = 0; 6636859Sbostic while ((ch = getopt(argc, argv, "pv")) != EOF) 6736859Sbostic switch(ch) { 6836859Sbostic case 'p': /* create ``password.orig'' */ 6936859Sbostic makeold = 1; 7036859Sbostic /* FALLTHROUGH */ 7136859Sbostic case 'v': /* backward compatible */ 7236859Sbostic break; 7336859Sbostic case '?': 7436859Sbostic default: 7536859Sbostic usage(); 7636859Sbostic } 7736859Sbostic argc -= optind; 7836859Sbostic argv += optind; 7936859Sbostic 8036859Sbostic if (argc != 1) 8136859Sbostic usage(); 8236859Sbostic 8336859Sbostic if (!(_pw_fp = fopen(*argv, "r"))) { 8436859Sbostic (void)fprintf(stderr, 8536859Sbostic "mkpasswd: %s: can't open for reading.\n", *argv); 8615664Sralph exit(1); 8715664Sralph } 8836859Sbostic 8936859Sbostic rmall(*argv); 9033137Sbostic (void)umask(0); 9136859Sbostic 9236859Sbostic /* open old password format file, dbm files */ 9336859Sbostic if (makeold) { 9436859Sbostic int oldfd; 9536859Sbostic 9636859Sbostic (void)sprintf(buf, "%s.orig", *argv); 9736859Sbostic if ((oldfd = open(buf, O_WRONLY|O_CREAT|O_EXCL, 0644)) < 0) { 9836859Sbostic (void)fprintf(stderr, "mkpasswd: %s: %s\n", buf, 9936859Sbostic strerror(errno)); 10017308Sralph exit(1); 10117308Sralph } 10236859Sbostic if (!(oldfp = fdopen(oldfd, "w"))) { 10336859Sbostic (void)fprintf(stderr, "mkpasswd: %s: fdopen failed.\n", 10436859Sbostic buf); 10517308Sralph exit(1); 10617308Sralph } 10715664Sralph } 10836859Sbostic if (!(dp = dbm_open(*argv, O_WRONLY|O_CREAT|O_EXCL, 0644))) { 10936859Sbostic (void)fprintf(stderr, "mkpasswd: %s: %s\n", *argv, 11036859Sbostic strerror(errno)); 11136859Sbostic exit(1); 11236859Sbostic } 11336859Sbostic 11436859Sbostic content.dptr = buf; 11536859Sbostic while (scanpw()) { 11636859Sbostic /* create dbm entry */ 11736859Sbostic p = buf; 11836859Sbostic #define COMPACT(e) t = e; while (*p++ = *t++); 11936859Sbostic COMPACT(_pw_passwd.pw_name); 12036859Sbostic (void)sprintf(nbuf, "%ld", offset); 12136859Sbostic COMPACT(nbuf); 12236859Sbostic bcopy((char *)&_pw_passwd.pw_uid, p, sizeof(int)); 12336859Sbostic p += sizeof(int); 12436859Sbostic bcopy((char *)&_pw_passwd.pw_gid, p, sizeof(int)); 12536859Sbostic p += sizeof(int); 12636859Sbostic bcopy((char *)&_pw_passwd.pw_change, p, sizeof(time_t)); 12736859Sbostic p += sizeof(time_t); 12836859Sbostic COMPACT(_pw_passwd.pw_class); 12936859Sbostic COMPACT(_pw_passwd.pw_gecos); 13036859Sbostic COMPACT(_pw_passwd.pw_dir); 13136859Sbostic COMPACT(_pw_passwd.pw_shell); 13236859Sbostic bcopy((char *)&_pw_passwd.pw_expire, p, sizeof(time_t)); 13336859Sbostic p += sizeof(time_t); 13436859Sbostic flag = p; 13536859Sbostic *p++ = _PW_KEYBYNAME; 13636859Sbostic content.dsize = p - buf; 13736859Sbostic #ifdef debug 13836859Sbostic (void)printf("store %s, uid %d\n", _pw_passwd.pw_name, 13936859Sbostic _pw_passwd.pw_uid); 14036859Sbostic #endif 14136859Sbostic key.dptr = _pw_passwd.pw_name; 14236859Sbostic key.dsize = strlen(_pw_passwd.pw_name); 14336859Sbostic if (dbm_store(dp, key, content, DBM_INSERT) < 0) 14436859Sbostic goto bad; 14536859Sbostic key.dptr = (char *)&_pw_passwd.pw_uid; 14636859Sbostic key.dsize = sizeof(int); 14736859Sbostic *flag = _PW_KEYBYUID; 14836859Sbostic if (dbm_store(dp, key, content, DBM_INSERT) < 0) 14936859Sbostic goto bad; 15036859Sbostic 15136859Sbostic /* create original format password file entry */ 15236859Sbostic if (!makeold) 15336859Sbostic continue; 15436859Sbostic fprintf(oldfp, "%s:*:%d:%d:%s:%s:%s\n", _pw_passwd.pw_name, 15536859Sbostic _pw_passwd.pw_uid, _pw_passwd.pw_gid, _pw_passwd.pw_gecos, 15636859Sbostic _pw_passwd.pw_dir, _pw_passwd.pw_shell); 15736859Sbostic } 15817308Sralph dbm_close(dp); 15915664Sralph exit(0); 16036859Sbostic 16136859Sbostic bad: (void)fprintf(stderr, "mkpasswd: dbm_store failed.\n"); 16236859Sbostic rmall(*argv); 16336859Sbostic exit(1); 16415664Sralph } 16536859Sbostic 16636859Sbostic rmall(fname) 16736859Sbostic char *fname; 16836859Sbostic { 16936859Sbostic register char *p; 17036859Sbostic char buf[MAXPATHLEN], *strcpy(); 17136859Sbostic 17236859Sbostic for (p = strcpy(buf, fname); *p; ++p); 17336859Sbostic bcopy(".pag", p, 5); 17436859Sbostic (void)unlink(buf); 17536859Sbostic bcopy(".dir", p, 5); 17636859Sbostic (void)unlink(buf); 17736859Sbostic bcopy(".orig", p, 6); 17836859Sbostic (void)unlink(buf); 17936859Sbostic } 18036859Sbostic 18136859Sbostic usage() 18236859Sbostic { 18336859Sbostic (void)fprintf(stderr, "usage: mkpasswd [-p] passwd_file\n"); 18436859Sbostic exit(1); 18536859Sbostic } 18636859Sbostic 18736859Sbostic /* from libc/gen/getpwent.c */ 18836859Sbostic 18936859Sbostic static 19036859Sbostic scanpw() 19136859Sbostic { 19236859Sbostic register char *cp; 19336859Sbostic long atol(), ftell(); 194*41567Smarc char *bp; 19536859Sbostic char *fgets(), *strsep(), *index(); 19636859Sbostic 19736859Sbostic for (;;) { 19836859Sbostic offset = ftell(_pw_fp); 19936859Sbostic if (!(fgets(line, sizeof(line), _pw_fp))) 20036859Sbostic return(0); 20136859Sbostic /* skip lines that are too big */ 20236859Sbostic if (!index(line, '\n')) { 20336859Sbostic int ch; 20436859Sbostic 20536859Sbostic while ((ch = getc(_pw_fp)) != '\n' && ch != EOF) 20636859Sbostic ; 20736859Sbostic continue; 20836859Sbostic } 209*41567Smarc bp = line; 210*41567Smarc _pw_passwd.pw_name = strsep(&bp, ":\n"); 211*41567Smarc _pw_passwd.pw_passwd = strsep(&bp, ":\n"); 21236859Sbostic offset += _pw_passwd.pw_passwd - line; 213*41567Smarc if (!(cp = strsep(&bp, ":\n"))) 21436859Sbostic continue; 21536859Sbostic _pw_passwd.pw_uid = atoi(cp); 216*41567Smarc if (!(cp = strsep(&bp, ":\n"))) 21736859Sbostic continue; 21836859Sbostic _pw_passwd.pw_gid = atoi(cp); 219*41567Smarc _pw_passwd.pw_class = strsep(&bp, ":\n"); 220*41567Smarc if (!(cp = strsep(&bp, ":\n"))) 22136859Sbostic continue; 22236859Sbostic _pw_passwd.pw_change = atol(cp); 223*41567Smarc if (!(cp = strsep(&bp, ":\n"))) 22436859Sbostic continue; 22536859Sbostic _pw_passwd.pw_expire = atol(cp); 226*41567Smarc _pw_passwd.pw_gecos = strsep(&bp, ":\n"); 227*41567Smarc _pw_passwd.pw_dir = strsep(&bp, ":\n"); 228*41567Smarc _pw_passwd.pw_shell = strsep(&bp, ":\n"); 22936859Sbostic return(1); 23036859Sbostic } 23136859Sbostic /* NOTREACHED */ 23236859Sbostic } 233