1: /*
   2:  * Copyright (c) 1980, 1983 Regents of the University of California.
   3:  * All rights reserved.
   4:  *
   5:  * Redistribution and use in source and binary forms are permitted
   6:  * provided that the above copyright notice and this paragraph are
   7:  * duplicated in all such forms and that any documentation,
   8:  * advertising materials, and other materials related to such
   9:  * distribution and use acknowledge that the software was developed
  10:  * by the University of California, Berkeley.  The name of the
  11:  * University may not be used to endorse or promote products derived
  12:  * from this software without specific prior written permission.
  13:  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
  14:  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  15:  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  16:  */
  17: 
  18: #if !defined(lint) && defined(DOSCCS)
  19: char copyright[] =
  20: "@(#) Copyright (c) 1980, 1983 Regents of the University of California.\n\
  21:  All rights reserved.\n";
  22: 
  23: static char sccsid[] = "@(#)mkpasswd.c	5.4.1 (2.11BSD) 1996/1/12";
  24: #endif /* not lint */
  25: 
  26: #include <sys/param.h>
  27: #include <sys/file.h>
  28: #include <ndbm.h>
  29: #include <pwd.h>
  30: #include <stdio.h>
  31: #include <strings.h>
  32: #include <stdlib.h>
  33: 
  34: static FILE *_pw_fp;
  35: static struct passwd _pw_passwd;
  36: static off_t offset;
  37: 
  38: #define MAXLINELENGTH   256
  39: static char line[MAXLINELENGTH];
  40: 
  41: /*
  42:  * Mkpasswd does two things -- use the ``arg'' file to create ``arg''.{pag,dir}
  43:  * for ndbm, and, if the -p flag is on, create a password file in the original
  44:  * format.  It doesn't use the getpwent(3) routines because it has to figure
  45:  * out offsets for the encrypted passwords to put in the dbm files.  One other
  46:  * problem is that, since the addition of shadow passwords, getpwent(3) has to
  47:  * use the dbm databases rather than simply scanning the actual file.  This
  48:  * required the addition of a flag field to the dbm database to distinguish
  49:  * between a record keyed by name, and one keyed by uid.
  50:  */
  51: 
  52: main(argc, argv)
  53:     int argc;
  54:     char **argv;
  55: {
  56:     extern int errno, optind;
  57:     register char *flag, *p, *t;
  58:     register int makeold;
  59:     FILE *oldfp;
  60:     DBM *dp;
  61:     datum key, content;
  62:     int ch;
  63:     char buf[256], nbuf[50];
  64: 
  65:     makeold = 0;
  66:     while ((ch = getopt(argc, argv, "pv")) != EOF)
  67:         switch(ch) {
  68:         case 'p':           /* create ``password.orig'' */
  69:             makeold = 1;
  70:             /* FALLTHROUGH */
  71:         case 'v':           /* backward compatible */
  72:             break;
  73:         case '?':
  74:         default:
  75:             usage();
  76:         }
  77:     argc -= optind;
  78:     argv += optind;
  79: 
  80:     if (argc != 1)
  81:         usage();
  82: 
  83:     if (!(_pw_fp = fopen(*argv, "r"))) {
  84:         (void)fprintf(stderr,
  85:             "mkpasswd: %s: can't open for reading.\n", *argv);
  86:         exit(1);
  87:     }
  88: 
  89:     rmall(*argv);
  90:     (void)umask(0);
  91: 
  92:     /* open old password format file, dbm files */
  93:     if (makeold) {
  94:         int oldfd;
  95: 
  96:         (void)sprintf(buf, "%s.orig", *argv);
  97:         if ((oldfd = open(buf, O_WRONLY|O_CREAT|O_EXCL, 0644)) < 0) {
  98:             (void)fprintf(stderr, "mkpasswd: %s: %s\n", buf,
  99:                 strerror(errno));
 100:             exit(1);
 101:         }
 102:         if (!(oldfp = fdopen(oldfd, "w"))) {
 103:             (void)fprintf(stderr, "mkpasswd: %s: fdopen failed.\n",
 104:                 buf);
 105:             exit(1);
 106:         }
 107:     }
 108:     if (!(dp = dbm_open(*argv, O_WRONLY|O_CREAT|O_EXCL, 0644))) {
 109:         (void)fprintf(stderr, "mkpasswd: %s: %s\n", *argv,
 110:             strerror(errno));
 111:         exit(1);
 112:     }
 113: 
 114:     content.dptr = buf;
 115:     while (scanpw()) {
 116:         /* create dbm entry */
 117:         p = buf;
 118: #define COMPACT(e)  t = e; while (*p++ = *t++);
 119:         COMPACT(_pw_passwd.pw_name);
 120:         (void)sprintf(nbuf, "%ld", offset);
 121:         COMPACT(nbuf);
 122:         bcopy((char *)&_pw_passwd.pw_uid, p, sizeof(int));
 123:         p += sizeof(int);
 124:         bcopy((char *)&_pw_passwd.pw_gid, p, sizeof(int));
 125:         p += sizeof(int);
 126:         bcopy((char *)&_pw_passwd.pw_change, p, sizeof(time_t));
 127:         p += sizeof(time_t);
 128:         COMPACT(_pw_passwd.pw_class);
 129:         COMPACT(_pw_passwd.pw_gecos);
 130:         COMPACT(_pw_passwd.pw_dir);
 131:         COMPACT(_pw_passwd.pw_shell);
 132:         bcopy((char *)&_pw_passwd.pw_expire, p, sizeof(time_t));
 133:         p += sizeof(time_t);
 134:         flag = p;
 135:         *p++ = _PW_KEYBYNAME;
 136:         content.dsize = p - buf;
 137: #ifdef debug
 138:         (void)printf("store %s, uid %d\n", _pw_passwd.pw_name,
 139:             _pw_passwd.pw_uid);
 140: #endif
 141:         key.dptr = _pw_passwd.pw_name;
 142:         key.dsize = strlen(_pw_passwd.pw_name);
 143:         if (dbm_store(dp, key, content, DBM_INSERT) < 0)
 144:             goto bad;
 145:         key.dptr = (char *)&_pw_passwd.pw_uid;
 146:         key.dsize = sizeof(int);
 147:         *flag = _PW_KEYBYUID;
 148:         if (dbm_store(dp, key, content, DBM_INSERT) < 0)
 149:             goto bad;
 150: 
 151:         /* create original format password file entry */
 152:         if (!makeold)
 153:             continue;
 154:         fprintf(oldfp, "%s:*:%d:%d:%s:%s:%s\n", _pw_passwd.pw_name,
 155:             _pw_passwd.pw_uid, _pw_passwd.pw_gid, _pw_passwd.pw_gecos,
 156:             _pw_passwd.pw_dir, _pw_passwd.pw_shell);
 157:     }
 158:     dbm_close(dp);
 159:     exit(0);
 160: 
 161: bad:    (void)fprintf(stderr, "mkpasswd: dbm_store failed.\n");
 162:     rmall(*argv);
 163:     exit(1);
 164: }
 165: 
 166: rmall(fname)
 167:     char *fname;
 168: {
 169:     register char *p;
 170:     char buf[MAXPATHLEN];
 171: 
 172:     for (p = strcpy(buf, fname); *p; ++p);
 173:     bcopy(".pag", p, 5);
 174:     (void)unlink(buf);
 175:     bcopy(".dir", p, 5);
 176:     (void)unlink(buf);
 177:     bcopy(".orig", p, 6);
 178:     (void)unlink(buf);
 179: }
 180: 
 181: usage()
 182: {
 183:     (void)fprintf(stderr, "usage: mkpasswd [-p] passwd_file\n");
 184:     exit(1);
 185: }
 186: 
 187: /* from libc/gen/getpwent.c */
 188: 
 189: static
 190: scanpw()
 191: {
 192:     register char *cp;
 193:     char    *bp;
 194: 
 195:     for (;;) {
 196:         offset = ftell(_pw_fp);
 197:         if (!(fgets(line, sizeof(line), _pw_fp)))
 198:             return(0);
 199:         bp = line;
 200:         /* skip lines that are too big */
 201:         if (!(cp = index(line, '\n'))) {
 202:             int ch;
 203: 
 204:             while ((ch = getc(_pw_fp)) != '\n' && ch != EOF)
 205:                 ;
 206:             continue;
 207:         }
 208:         *cp = '\0';
 209:         _pw_passwd.pw_name = strsep(&bp, ":");
 210:         _pw_passwd.pw_passwd = strsep(&bp, ":");
 211:         offset += _pw_passwd.pw_passwd - line;
 212:         if (!(cp = strsep(&bp, ":")))
 213:             continue;
 214:         _pw_passwd.pw_uid = atoi(cp);
 215:         if (!(cp = strsep(&bp, ":")))
 216:             continue;
 217:         _pw_passwd.pw_gid = atoi(cp);
 218:         _pw_passwd.pw_class = strsep(&bp, ":");
 219:         if (!(cp = strsep(&bp, ":")))
 220:             continue;
 221:         _pw_passwd.pw_change = atol(cp);
 222:         if (!(cp = strsep(&bp, ":")))
 223:             continue;
 224:         _pw_passwd.pw_expire = atol(cp);
 225:         _pw_passwd.pw_gecos = strsep(&bp, ":");
 226:         _pw_passwd.pw_dir = strsep(&bp, ":");
 227:         _pw_passwd.pw_shell = strsep(&bp, ":");
 228:         return(1);
 229:     }
 230:     /* NOTREACHED */
 231: }

Defined functions

main defined in line 52; never used
rmall defined in line 166; used 2 times
scanpw defined in line 189; used 1 times
usage defined in line 181; used 2 times

Defined variables

_pw_passwd defined in line 35; used 31 times
copyright defined in line 19; never used
line defined in line 39; used 5 times
offset defined in line 36; used 3 times
sccsid defined in line 23; never used

Defined macros

COMPACT defined in line 118; used 6 times
MAXLINELENGTH defined in line 38; used 1 times
  • in line 39
Last modified: 1996-01-13
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 3916
Valid CSS Valid XHTML 1.0 Strict