home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / misc / volume6 / shadow-2.pt3 / pwunconv.c < prev    next >
C/C++ Source or Header  |  1989-02-03  |  3KB  |  109 lines

  1. /*
  2.  * pwunconv - restore old password file from shadow password file.
  3.  *
  4.  *    Pwunconv copies the password file information from the shadow
  5.  *    password file, merging entries from an optional existing shadow
  6.  *    file.
  7.  *
  8.  *    The new password file is left in npasswd.  There is no new
  9.  *    shadow file.  Password aging information is translated where
  10.  *    possible.
  11.  */
  12.  
  13. #include <sys/types.h>
  14. #include <stdio.h>
  15. #include <fcntl.h>
  16. #include <pwd.h>
  17. #include "config.h"
  18. #include "lastlog.h"
  19. #include "shadow.h"
  20.  
  21. char    buf[BUFSIZ];
  22. char    *l64a ();
  23.  
  24. int    main ()
  25. {
  26.     struct    passwd    *pw;
  27.     struct    passwd    *sgetpwent ();
  28.     FILE    *pwd;
  29.     FILE    *npwd;
  30.     struct    spwd    *spwd;
  31.     int    fd;
  32.  
  33.     if (! (pwd = fopen (PWDFILE, "r"))) {
  34.         perror (PWDFILE);
  35.         return (1);
  36.     }
  37.     unlink ("npasswd");
  38.     if ((fd = open ("npasswd", O_WRONLY|O_CREAT|O_EXCL, 0600)) < 0 ||
  39.             ! (npwd = fdopen (fd, "w"))) {
  40.         perror ("npasswd");
  41.         return (1);
  42.     }
  43.     while (fgets (buf, BUFSIZ, pwd) == buf) {
  44.         buf[strlen (buf) - 1] = '\0'; /* remove '\n' character */
  45.  
  46.         if (buf[0] == '#') {    /* comment line */
  47.             (void) fprintf (npwd, "%s\n", buf);
  48.             continue;
  49.         }
  50.         if (! (pw = sgetpwent (buf))) { /* copy bad lines verbatim */
  51.             (void) fprintf (npwd, "%s\n", buf);
  52.             continue;
  53.         }
  54.         setspent ();        /* rewind shadow file */
  55.  
  56.         if (! (spwd = getspnam (pw->pw_name))) {
  57.             (void) fprintf (npwd, "%s\n", buf);
  58.             continue;
  59.         }
  60.         pw->pw_passwd = spwd->sp_pwdp;
  61.  
  62.     /*
  63.      * Password aging works differently in the two different systems.
  64.      * With shadow password files you apparently must have some aging
  65.      * information.  The maxweeks or minweeks may not map exactly.
  66.      * In pwconv we set max == 10000, which is about 30 years.  Here
  67.      * we have to undo that kludge.  So, if maxdays == 10000, no aging
  68.      * information is put into the new file.  Otherwise, the days are
  69.      * converted to weeks and so on.
  70.      */
  71.  
  72.         if (spwd->sp_max > (63*7) && spwd->sp_max < 10000)
  73.             spwd->sp_max = (63*7); /* 10000 is infinity this week */
  74.  
  75.         if (spwd->sp_min >= 0 && spwd->sp_min <= 63*7 &&
  76.                 spwd->sp_max >= 0 && spwd->sp_max <= 63*7) {
  77.             spwd->sp_max /= 7;    /* turn it into weeks */
  78.             spwd->sp_min /= 7;
  79.             spwd->sp_lstchg /= 7;
  80.             pw->pw_age = l64a ((long) spwd->sp_lstchg * (64L*64L) +
  81.                           spwd->sp_min * (64L) +
  82.                           spwd->sp_max);
  83.         } else
  84.             pw->pw_age = (char *) 0;
  85.  
  86.         if (pw->pw_age)
  87.             (void) fprintf (npwd, "%s:%s,%s:%d:%d:%s:%s:%s\n",
  88.                 pw->pw_name, pw->pw_passwd ? pw->pw_passwd:"",
  89.                 pw->pw_age, pw->pw_uid, pw->pw_gid,
  90.                 pw->pw_gecos, pw->pw_dir,
  91.                 pw->pw_shell ? pw->pw_shell:"");
  92.         else
  93.             (void) fprintf (npwd, "%s:%s:%d:%d:%s:%s:%s\n",
  94.                 pw->pw_name, pw->pw_passwd ? pw->pw_passwd:"",
  95.                 pw->pw_uid, pw->pw_gid,
  96.                 pw->pw_gecos, pw->pw_dir,
  97.                 pw->pw_shell ? pw->pw_shell:"");
  98.     }
  99.     endspent ();
  100.  
  101.     if (ferror (npwd)) {
  102.         perror ("pwunconv");
  103.         (void) unlink ("npasswd");
  104.     }
  105.     (void) fclose (npwd);
  106.     (void) fclose (pwd);
  107.     return (0);
  108. }
  109.