home *** CD-ROM | disk | FTP | other *** search
- /*
- * Copyright 1989, 1990, John F. Haugh II
- * All rights reserved.
- *
- * Use, duplication, and disclosure prohibited without
- * the express written permission of the author.
- */
-
- /*
- * pwunconv - restore old password file from shadow password file.
- *
- * Pwunconv copies the password file information from the shadow
- * password file, merging entries from an optional existing shadow
- * file.
- *
- * The new password file is left in npasswd. There is no new
- * shadow file. Password aging information is translated where
- * possible.
- */
-
- #include <sys/types.h>
- #include <stdio.h>
- #include <fcntl.h>
- #include <pwd.h>
- #include "config.h"
- #include "shadow.h"
-
- #ifndef lint
- static char _sccsid[] = "@(#)pwunconv.c 2.2 19:24:08 7/29/90";
- #endif
-
- char buf[BUFSIZ];
- char *l64a ();
-
- int main ()
- {
- struct passwd *pw;
- struct passwd *sgetpwent ();
- FILE *pwd;
- FILE *npwd;
- struct spwd *spwd;
- int fd;
-
- if (! (pwd = fopen (PWDFILE, "r"))) {
- perror (PWDFILE);
- return (1);
- }
- unlink ("npasswd");
- if ((fd = open ("npasswd", O_WRONLY|O_CREAT|O_EXCL, 0600)) < 0 ||
- ! (npwd = fdopen (fd, "w"))) {
- perror ("npasswd");
- return (1);
- }
- while (fgets (buf, BUFSIZ, pwd) == buf) {
- buf[strlen (buf) - 1] = '\0'; /* remove '\n' character */
-
- if (buf[0] == '#') { /* comment line */
- (void) fprintf (npwd, "%s\n", buf);
- continue;
- }
- if (! (pw = sgetpwent (buf))) { /* copy bad lines verbatim */
- (void) fprintf (npwd, "%s\n", buf);
- continue;
- }
- setspent (); /* rewind shadow file */
-
- if (! (spwd = getspnam (pw->pw_name))) {
- (void) fprintf (npwd, "%s\n", buf);
- continue;
- }
- pw->pw_passwd = spwd->sp_pwdp;
-
- /*
- * Password aging works differently in the two different systems.
- * With shadow password files you apparently must have some aging
- * information. The maxweeks or minweeks may not map exactly.
- * In pwconv we set max == 10000, which is about 30 years. Here
- * we have to undo that kludge. So, if maxdays == 10000, no aging
- * information is put into the new file. Otherwise, the days are
- * converted to weeks and so on.
- */
-
- if (spwd->sp_max > (63*7) && spwd->sp_max < 10000)
- spwd->sp_max = (63*7); /* 10000 is infinity this week */
-
- if (spwd->sp_min >= 0 && spwd->sp_min <= 63*7 &&
- spwd->sp_max >= 0 && spwd->sp_max <= 63*7) {
- spwd->sp_max /= 7; /* turn it into weeks */
- spwd->sp_min /= 7;
- spwd->sp_lstchg /= 7;
- pw->pw_age = l64a ((long) spwd->sp_lstchg * (64L*64L) +
- spwd->sp_min * (64L) +
- spwd->sp_max);
- } else
- pw->pw_age = (char *) 0;
-
- if (pw->pw_age)
- (void) fprintf (npwd, "%s:%s,%s:%d:%d:%s:%s:%s\n",
- pw->pw_name, pw->pw_passwd ? pw->pw_passwd:"",
- pw->pw_age, pw->pw_uid, pw->pw_gid,
- pw->pw_gecos, pw->pw_dir,
- pw->pw_shell ? pw->pw_shell:"");
- else
- (void) fprintf (npwd, "%s:%s:%d:%d:%s:%s:%s\n",
- pw->pw_name, pw->pw_passwd ? pw->pw_passwd:"",
- pw->pw_uid, pw->pw_gid,
- pw->pw_gecos, pw->pw_dir,
- pw->pw_shell ? pw->pw_shell:"");
- }
- endspent ();
-
- if (ferror (npwd)) {
- perror ("pwunconv");
- (void) unlink ("npasswd");
- }
- (void) fclose (npwd);
- (void) fclose (pwd);
- return (0);
- }
-