home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / misc / volume38 / shadow / part11 / pwconv.c < prev    next >
C/C++ Source or Header  |  1993-08-14  |  4KB  |  180 lines

  1. /*
  2.  * Copyright 1989, 1990, 1991, John F. Haugh II
  3.  * All rights reserved.
  4.  *
  5.  * Permission is granted to copy and create derivative works for any
  6.  * non-commercial purpose, provided this copyright notice is preserved
  7.  * in all copies of source code, or included in human readable form
  8.  * and conspicuously displayed on all copies of object code or
  9.  * distribution media.
  10.  *
  11.  * pwconv - convert and update shadow password files
  12.  *
  13.  *    Pwconv copies the old password file information to a new shadow
  14.  *    password file, merging entries from an optional existing shadow
  15.  *    file.
  16.  *
  17.  *    The new password file is left in npasswd, the new shadow file is
  18.  *    left in nshadow.  Existing shadow entries are copied as is.
  19.  *    New entries are created with passwords which expire in MAXDAYS days,
  20.  *    with a last changed date of today, unless password aging
  21.  *    information was already present.  Likewise, the minimum number of
  22.  *    days before which the password may be changed is controlled by
  23.  *    MINDAYS.  The number of warning days is set to WARNAGE if that
  24.  *    macro exists.  Entries with blank passwordsare not copied to the
  25.  *    shadow file at all.
  26.  */
  27.  
  28. #include <sys/types.h>
  29. #include <stdio.h>
  30. #include <fcntl.h>
  31. #include "pwd.h"
  32. #ifndef    BSD
  33. #include <string.h>
  34. #else
  35. #define    strchr    index
  36. #define    strrchr    rindex
  37. #include <strings.h>
  38. #endif
  39. #include "config.h"
  40. #include "shadow.h"
  41.  
  42. #ifndef    lint
  43. static    char    _sccsid[] = "@(#)pwconv.c    3.4    07:43:52    17 Sep 1991";
  44. #endif
  45.  
  46. char    buf[BUFSIZ];
  47.  
  48. long    time ();
  49. long    a64l ();
  50. extern    int    getdef_num();
  51.  
  52. int    main ()
  53. {
  54.     long    today;
  55.     struct    passwd    *pw;
  56.     struct    passwd    *sgetpwent ();
  57.     FILE    *pwd;
  58.     FILE    *npwd;
  59.     FILE    *shadow;
  60.     struct    spwd    *spwd;
  61.     struct    spwd    tspwd;
  62.     int    fd;
  63.     char    *cp;
  64.  
  65.     if (! (pwd = fopen (PWDFILE, "r"))) {
  66.         perror (PWDFILE);
  67.         exit (1);
  68.     }
  69.     unlink ("npasswd");
  70.     if ((fd = open ("npasswd", O_WRONLY|O_CREAT|O_EXCL, 0644)) < 0 ||
  71.             ! (npwd = fdopen (fd, "w"))) {
  72.         perror ("npasswd");
  73.         exit (1);
  74.     }
  75.     unlink  ("nshadow");
  76.     if ((fd = open ("nshadow", O_WRONLY|O_CREAT|O_EXCL, 0600)) < 0 ||
  77.             ! (shadow = fdopen (fd, "w"))) {
  78.         perror ("nshadow");
  79.         (void) unlink ("npasswd");
  80.         (void) unlink ("nshadow");
  81.         exit (1);
  82.     }
  83.  
  84.     (void) time (&today);
  85.     today /= (24L * 60L * 60L);
  86.  
  87.     while (fgets (buf, BUFSIZ, pwd) == buf) {
  88.         if (cp = strrchr (buf, '\n'))
  89.             *cp = '\0';
  90.  
  91.         if (buf[0] == '#') {    /* comment line */
  92.             (void) fprintf (npwd, "%s\n", buf);
  93.             continue;
  94.         }
  95.         if (! (pw = sgetpwent (buf))) { /* copy bad lines verbatim */
  96.             (void) fprintf (npwd, "%s\n", buf);
  97.             continue;
  98.         }
  99.         if (pw->pw_passwd[0] == '\0') { /* no password, skip */
  100.             (void) fprintf (npwd, "%s\n", buf);
  101.             continue;
  102.         }
  103.         setspent ();        /* rewind old shadow file */
  104.  
  105.         if (spwd = getspnam (pw->pw_name)) {
  106.             if (putspent (spwd, shadow)) { /* copy old entry */
  107.                 perror ("nshadow");
  108.                 goto error;
  109.             }
  110.         } else {        /* need a new entry. */
  111.             tspwd.sp_namp = pw->pw_name;
  112.             tspwd.sp_pwdp = pw->pw_passwd;
  113.             pw->pw_passwd = "x";
  114. #ifdef    ATT_AGE
  115.             if (pw->pw_age) { /* copy old password age stuff */
  116.                 if (strlen (pw->pw_age) >= 2) {
  117.                     tspwd.sp_min = c64i (pw->pw_age[1]);
  118.                     tspwd.sp_max = c64i (pw->pw_age[0]);
  119.                 } else {
  120.                     tspwd.sp_min = tspwd.sp_max = -1;
  121.                 }
  122.                 if (strlen (pw->pw_age) == 4)
  123.                     tspwd.sp_lstchg = a64l (&pw->pw_age[2]);
  124.                 else
  125.                     tspwd.sp_lstchg = -1;
  126.  
  127.                 /*
  128.                  * Convert weeks to days
  129.                  */
  130.  
  131.                 if (tspwd.sp_min != -1)
  132.                     tspwd.sp_min *= 7;
  133.  
  134.                 if (tspwd.sp_max != -1)
  135.                     tspwd.sp_max *= 7;
  136.  
  137.                 if (tspwd.sp_lstchg != -1)
  138.                     tspwd.sp_lstchg *= 7;
  139.             } else
  140. #endif    /* ATT_AGE */
  141.             {    /* fake up new password age stuff */
  142.                 tspwd.sp_max =
  143.                     getdef_num("PASS_MAX_DAYS", 10000);
  144.                 tspwd.sp_min = getdef_num("PASS_MIN_DAYS", 0);
  145.                 tspwd.sp_lstchg = today;
  146.             }
  147.             tspwd.sp_warn = getdef_num("PASS_WARN_AGE", -1);
  148.             tspwd.sp_inact = tspwd.sp_expire = tspwd.sp_flag = -1;
  149.             if (putspent (&tspwd, shadow)) { /* output entry */
  150.                 perror ("nshadow");
  151.                 goto error;
  152.             }
  153.         }
  154.         (void) fprintf (npwd, "%s:%s:%d:%d:%s:%s:",
  155.                 pw->pw_name, pw->pw_passwd,
  156.                 pw->pw_uid, pw->pw_gid,
  157.                 pw->pw_gecos, pw->pw_dir);
  158.  
  159.         if (fprintf (npwd, "%s\n",
  160.                 pw->pw_shell ? pw->pw_shell:"") == EOF) {
  161.             perror ("npasswd");
  162.             goto error;
  163.         }
  164.     }
  165.     endspent ();
  166.  
  167.     if (ferror (npwd) || ferror (shadow)) {
  168.         perror ("pwconv");
  169. error:
  170.         (void) unlink ("npasswd");
  171.         (void) unlink ("nshadow");
  172.         exit (1);
  173.     }
  174.     (void) fclose (pwd);
  175.     (void) fclose (npwd);
  176.     (void) fclose (shadow);
  177.  
  178.     exit (0);
  179. }
  180.