home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / misc / volume32 / shadow / patch06b < prev    next >
Text File  |  1992-10-15  |  57KB  |  2,518 lines

  1. Newsgroups: comp.sources.misc
  2. From: jfh@rpp386.cactus.org (John F Haugh II)
  3. Subject:  v32i099:  shadow - Shadow Login/Password Suite, Patch06b/3
  4. Message-ID: <1992Oct12.152327.11902@sparky.imd.sterling.com>
  5. X-Md4-Signature: 4b2a40adc1d28b0497b221fd7a0a6b72
  6. Date: Mon, 12 Oct 1992 15:23:27 GMT
  7. Approved: kent@sparky.imd.sterling.com
  8.  
  9. Submitted-by: jfh@rpp386.cactus.org (John F Haugh II)
  10. Posting-number: Volume 32, Issue 99
  11. Archive-name: shadow/patch06b
  12. Environment: UNIX
  13. Patch-To: shadow: Volume 26, Issue 54-64
  14.  
  15. This is the second part of a three part patch.
  16. --
  17. Index: passwd.c
  18. *** passwd.c.old    Sat Oct 10 11:17:03 1992
  19. --- passwd.c    Sat Oct 10 11:17:02 1992
  20. ***************
  21. *** 7,12 ****
  22. --- 7,15 ----
  23.    * in all copies of source code, or included in human readable form
  24.    * and conspicuously displayed on all copies of object code or
  25.    * distribution media.
  26. +  *
  27. +  * This software is provided on an AS-IS basis and the author makes
  28. +  * no warrantee of any kind.
  29.    */
  30.   
  31.   #include "config.h"
  32. ***************
  33. *** 17,23 ****
  34.   #include <signal.h>
  35.   
  36.   #ifndef    lint
  37. ! static    char    sccsid[] = "@(#)passwd.c    3.8    20:37:37    3/7/92";
  38.   #endif
  39.   
  40.   /*
  41. --- 20,26 ----
  42.   #include <signal.h>
  43.   
  44.   #ifndef    lint
  45. ! static    char    sccsid[] = "@(#)passwd.c    3.9    13:03:56    7/27/92";
  46.   #endif
  47.   
  48.   /*
  49. ***************
  50. *** 51,57 ****
  51. --- 54,63 ----
  52.   
  53.   #include "pwd.h"
  54.   #include "lastlog.h"
  55. + #ifdef    SHADOWPWD
  56.   #include "shadow.h"
  57. + #endif
  58. + #include "pwauth.h"
  59.   
  60.   #ifdef    USE_SYSLOG
  61.   #include <syslog.h>
  62. ***************
  63. *** 60,66 ****
  64.   #define    LOG_WARN    LOG_WARNING
  65.   #endif
  66.   #endif
  67. ! #ifdef    USE_RLIMIT
  68.   #include <sys/resource.h>
  69.   
  70.   struct    rlimit    rlimit_fsize = { RLIM_INFINITY, RLIM_INFINIT };
  71. --- 66,72 ----
  72.   #define    LOG_WARN    LOG_WARNING
  73.   #endif
  74.   #endif
  75. ! #ifdef    HAVE_RLIMIT
  76.   #include <sys/resource.h>
  77.   
  78.   struct    rlimit    rlimit_fsize = { RLIM_INFINITY, RLIM_INFINIT };
  79. ***************
  80. *** 99,105 ****
  81. --- 105,113 ----
  82.   
  83.   extern    char    *getpass();
  84.   extern    char    *pw_encrypt();
  85. + extern    int    pw_auth();
  86.   extern    char    *getlogin();
  87. + extern    char    l64a();
  88.   extern    int    optind;        /* Index into argv[] for current option */
  89.   extern    char    *optarg;    /* Pointer to current option value */
  90.   #ifdef    NDBM
  91. ***************
  92. *** 138,143 ****
  93. --- 146,152 ----
  94.   #define    NOPERM        "You may not change the password for %s.\n"
  95.   #define    NOPERM2        "can't change pwd for `%s'\n"
  96.   #define    UNCHANGED    "The password for %s is unchanged.\n"
  97. + #ifdef    SHADOWPWD
  98.   #define    SPWDBUSY    "Cannot lock the password file; try again later.\n"
  99.   #define    SPWDBUSY2    "can't lock /etc/shadow\n"
  100.   #define    OPNERROR    "Cannot open the password file.\n"
  101. ***************
  102. *** 146,159 ****
  103.   #define    UPDERROR2    "error updating shadow entry\n"
  104.   #define    DBMERROR    "Error updating the DBM password entry.\n"
  105.   #define    DBMERROR2    "error updating DBM shadow entry.\n"
  106. - #define    NOTROOT        "Cannot change ID to root.\n"
  107. - #define    NOTROOT2    "can't setuid(0).\n"
  108.   #define    CLSERROR    "Cannot commit shadow file changes.\n"
  109.   #define    CLSERROR2    "can't rewrite /etc/shadow.\n"
  110.   #define    UNLKERROR    "Cannot unlock the shadow file.\n"
  111.   #define    UNLKERROR2    "can't unlock /etc/shadow.\n"
  112.   #define    TRYAGAIN    "Try again.\n"
  113.   #define    CHGPASSWD    "changed password for `%s'\n"
  114.   
  115.   /*
  116.    * usage - print command usage and exit
  117. --- 155,183 ----
  118.   #define    UPDERROR2    "error updating shadow entry\n"
  119.   #define    DBMERROR    "Error updating the DBM password entry.\n"
  120.   #define    DBMERROR2    "error updating DBM shadow entry.\n"
  121.   #define    CLSERROR    "Cannot commit shadow file changes.\n"
  122.   #define    CLSERROR2    "can't rewrite /etc/shadow.\n"
  123.   #define    UNLKERROR    "Cannot unlock the shadow file.\n"
  124.   #define    UNLKERROR2    "can't unlock /etc/shadow.\n"
  125. + #else
  126. + #define    PWDBUSY        "Cannot lock the password file; try again later.\n"
  127. + #define    PWDBUSY2    "can't lock /etc/passwd\n"
  128. + #define    OPNERROR    "Cannot open the password file.\n"
  129. + #define    OPNERROR2    "can't open /etc/passwd\n"
  130. + #define    UPDERROR    "Error updating the password entry.\n"
  131. + #define    UPDERROR2    "error updating password entry\n"
  132. + #define    DBMERROR    "Error updating the DBM password entry.\n"
  133. + #define    DBMERROR2    "error updating DBM password entry.\n"
  134. + #define    CLSERROR    "Cannot commit password file changes.\n"
  135. + #define    CLSERROR2    "can't rewrite /etc/passwd.\n"
  136. + #define    UNLKERROR    "Cannot unlock the password file.\n"
  137. + #define    UNLKERROR2    "can't unlock /etc/passwd.\n"
  138. + #endif
  139. + #define    NOTROOT        "Cannot change ID to root.\n"
  140. + #define    NOTROOT2    "can't setuid(0).\n"
  141.   #define    TRYAGAIN    "Try again.\n"
  142.   #define    CHGPASSWD    "changed password for `%s'\n"
  143. + #define    NOCHGPASSWD    "did not change password for `%s'\n"
  144.   
  145.   /*
  146.    * usage - print command usage and exit
  147. ***************
  148. *** 170,175 ****
  149. --- 194,228 ----
  150.       exit (1);
  151.   }
  152.   
  153. + void
  154. + #ifdef    SHADOWPWD
  155. + update_age (sp)
  156. + struct    spwd    *sp;
  157. + {
  158. +     sp->sp_lstchg = time ((time_t *) 0) / SCALE;
  159. + }
  160. + #else
  161. + update_age (pw)
  162. + struct    passwd    *pw;
  163. + {
  164. + #ifdef    ATT_AGE
  165. +     long    week;        /* at the office ... */
  166. +     static    char    age[5];    /* Password age string */
  167. +     week = time ((time_t *) 0) / WEEK;
  168. +     if (pw->pw_age[0]) {
  169. +         cp = l64a (week);
  170. +         age[0] = pw->pw_age[0];
  171. +         age[1] = pw->pw_age[1];
  172. +         age[2] = cp[0];
  173. +         age[3] = cp[1];
  174. +         age[4] = '\0';
  175. +         pw->pw_age = age;
  176. +     }
  177. + #endif    /* ATT_AGE */
  178. + }
  179. + #endif
  180.   /*
  181.    * new_password - validate old password and replace with new
  182.    */
  183. ***************
  184. *** 176,191 ****
  185. --- 229,251 ----
  186.   
  187.   /*ARGSUSED*/
  188.   int
  189. + #ifdef    SHADOWPWD
  190.   new_password (pw, sp)
  191.   struct    passwd    *pw;
  192.   struct    spwd    *sp;
  193. + #else
  194. + new_password (pw)
  195. + struct    passwd    *pw;
  196. + #endif
  197.   {
  198.       char    *clear;        /* Pointer to clear text */
  199.       char    *cipher;    /* Pointer to cipher text */
  200.       char    *cp;        /* Pointer to getpass() response */
  201. +     char    *old;        /* Pointer to old cipher text */
  202.       char    orig[BUFSIZ];    /* Original password */
  203.       char    pass[BUFSIZ];    /* New password */
  204.       int    i;        /* Counter for retries */
  205. +     long    week;        /* This week in history ... */
  206.   
  207.       /*
  208.        * Authenticate the user.  The user will be prompted for their
  209. ***************
  210. *** 192,209 ****
  211.        * own password.
  212.        */
  213.   
  214. !     if (! amroot && sp->sp_pwdp[0]) {
  215.           bzero (orig, sizeof orig);
  216.   
  217.           if (! (clear = getpass (OLDPASS)))
  218.               return -1;
  219.   
  220. !         cipher = pw_encrypt (clear, sp->sp_pwdp);
  221. !         if (strcmp (cipher, sp->sp_pwdp) != 0) {
  222.               sleep (1);
  223. !             fprintf (stderr, WRONGPWD, sp->sp_namp);
  224.   #ifdef    USE_SYSLOG
  225. !             syslog (LOG_WARN, WRONGPWD2, sp->sp_namp);
  226.   #endif
  227.               return -1;
  228.           }
  229. --- 252,274 ----
  230.        * own password.
  231.        */
  232.   
  233. ! #ifdef    SHADOWPWD
  234. !     old = sp->sp_pwdp;
  235. ! #else
  236. !     old = pw->pw_passwd;
  237. ! #endif
  238. !     if (! amroot && old[0]) {
  239.           bzero (orig, sizeof orig);
  240.   
  241.           if (! (clear = getpass (OLDPASS)))
  242.               return -1;
  243.   
  244. !         cipher = pw_encrypt (clear, old);
  245. !         if (strcmp (cipher, old) != 0) {
  246.               sleep (1);
  247. !             fprintf (stderr, WRONGPWD, pw->pw_name);
  248.   #ifdef    USE_SYSLOG
  249. !             syslog (LOG_WARN, WRONGPWD2, pw->pw_name);
  250.   #endif
  251.               return -1;
  252.           }
  253. ***************
  254. *** 254,261 ****
  255.        * the shadow password structure updated to reflect the change.
  256.        */
  257.   
  258.       sp->sp_pwdp = pw_encrypt (pass, (char *) 0);
  259. !     sp->sp_lstchg = time ((time_t *) 0) / SCALE;
  260.       bzero (pass, sizeof pass);
  261.   
  262.       return 0;
  263. --- 319,331 ----
  264.        * the shadow password structure updated to reflect the change.
  265.        */
  266.   
  267. + #ifdef    SHADOWPWD
  268.       sp->sp_pwdp = pw_encrypt (pass, (char *) 0);
  269. !     update_age (sp);
  270. ! #else
  271. !     pw->pw_passwd = pw_encrypt (pass, (char *) 0);
  272. !     update_age (pw);
  273. ! #endif    /* SHADOWPWD */
  274.       bzero (pass, sizeof pass);
  275.   
  276.       return 0;
  277. ***************
  278. *** 270,280 ****
  279. --- 340,359 ----
  280.   
  281.   /*ARGSUSED*/
  282.   void
  283. + #ifdef    SHADOWPWD
  284.   check_password (pw, sp)
  285.   struct    passwd    *pw;
  286.   struct    spwd    *sp;
  287. + #else
  288. + check_password (pw)
  289. + struct    passwd    *pw;
  290. + #endif
  291.   {
  292.       time_t    now = time ((time_t *) 0) / SCALE;
  293. + #ifndef    SHADOWPWD
  294. +     time_t    last;
  295. +     time_t    ok;
  296. + #endif
  297.   
  298.       /*
  299.        * Root can change any password any time.
  300. ***************
  301. *** 290,295 ****
  302. --- 369,375 ----
  303.        * been inactive too long cannot be changed.
  304.        */
  305.   
  306. + #ifdef    SHADOWPWD
  307.       if ((sp->sp_expire > 0 && now >= sp->sp_expire) ||
  308.           (sp->sp_inact >= 0 && sp->sp_max >= 0 &&
  309.           now >= (sp->sp_lstchg + sp->sp_inact + sp->sp_max)) ||
  310. ***************
  311. *** 302,312 ****
  312. --- 382,394 ----
  313.   #endif
  314.           exit (1);
  315.       }
  316. + #endif
  317.   
  318.       /*
  319.        * Passwords may only be changed after sp_min time is up.
  320.        */
  321.   
  322. + #ifdef    SHADOWPWD
  323.       if (sp->sp_min >= 0 && now < (sp->sp_lstchg + sp->sp_min)) {
  324.           fprintf (stderr, TOOSOON, sp->sp_namp);
  325.   #ifdef    USE_SYSLOG
  326. ***************
  327. *** 315,322 ****
  328. --- 397,426 ----
  329.   #endif
  330.           exit (1);
  331.       }
  332. + #else    /* !SHADOWPWD */
  333. +     /*
  334. +      * Can always be changed if there is no age info
  335. +      */
  336. +     if (! pw->pw_age[0])
  337. +         return;
  338. +     last = a64l (pw->pw_age + 2) * WEEK;
  339. +     ok = last + c64i (pw->pw_age[1]) * WEEK;
  340. +     if (now < ok) {
  341. +         fprintf (stderr, TOOSOON, pw->pw_name);
  342. + #ifdef    USE_SYSLOG
  343. +         syslog (LOG_WARN, TOOSOON2, pw->pw_name);
  344. +         closelog ();
  345. + #endif
  346. +         exit (1);
  347. +     }
  348. + #endif    /* SHADOWPWD */
  349.   }
  350.   
  351. + #ifdef    SHADOWPWD
  352.   /*
  353.    * pwd_to_spwd - create entries for new spwd structure
  354.    *
  355. ***************
  356. *** 389,394 ****
  357. --- 493,500 ----
  358.       sp->sp_flag = -1;
  359.   }
  360.   
  361. + #endif    /* SHADOWPWD */
  362.   /*
  363.    * print_status - print current password status
  364.    */
  365. ***************
  366. *** 395,407 ****
  367. --- 501,519 ----
  368.   
  369.   /*ARGSUSED*/
  370.   void
  371. + #ifdef    SHADOWPWD
  372.   print_status (pw, sp)
  373.   struct    passwd    *pw;
  374.   struct    spwd    *sp;
  375. + #else
  376. + print_status (pw)
  377. + struct    passwd    *pw;
  378. + #endif
  379.   {
  380.       struct    tm    *tm;
  381.       time_t    last_time;
  382.   
  383. + #ifdef    SHADOWPWD
  384.       last_time = sp->sp_lstchg * SCALE;
  385.       tm = gmtime (&last_time);
  386.   
  387. ***************
  388. *** 413,418 ****
  389. --- 525,546 ----
  390.       printf ("%d %d %d %d\n",
  391.           (sp->sp_min * SCALE) / DAY, (sp->sp_max * SCALE) / DAY,
  392.           (sp->sp_warn * SCALE) / DAY, (sp->sp_inact * SCALE) / DAY);
  393. + #else
  394. +     if (pw->pw_age[0])
  395. +         last_time = a64l (pw->pw_age + 2);
  396. +     else
  397. +         last_time = 0L;
  398. +     tm = gmtime (&last_time);
  399. +     printf ("%s ", pw->pw_name);
  400. +     printf ("%s ",
  401. +         pw->pw_passwd[0] ? (pw->pw_passwd[0] == '!' ? "L":"P"):"NP");
  402. +     printf ("%02.2d/%02.2d/%02.2d ",
  403. +         tm->tm_mon + 1, tm->tm_mday, tm->tm_year % 100);
  404. +     printf ("%d %d\n",
  405. +         pw->pw_age[0] ? c64i (pw->pw_age[1]) * 7:10000,
  406. +         pw->pw_age[0] ? c64i (pw->pw_age[0]) * 7:0);
  407. + #endif    /* SHADOWPWD */
  408.   }
  409.   
  410.   /*
  411. ***************
  412. *** 464,471 ****
  413. --- 592,603 ----
  414.       int    iflg = 0;        /* -i - set inactive days             */
  415.       int    Sflg = 0;        /* -S - show password status          */
  416.       struct    passwd    *pw;        /* Password file entry for user       */
  417. + #ifdef    SHADOWPWD
  418.       struct    spwd    *sp;        /* Shadow file entry for user         */
  419.       struct    spwd    tspwd;        /* New shadow file entry if none      */
  420. + #else
  421. +     char    age[5];            /* New password age entry             */
  422. + #endif
  423.   
  424.       /*
  425.        * The program behaves differently when executed by root
  426. ***************
  427. *** 474,480 ****
  428. --- 606,614 ----
  429.   
  430.       amroot = getuid () == 0;
  431.   #ifdef    NDBM
  432. + #ifdef    SHADOWPWD
  433.       sp_dbm_mode = O_RDWR;
  434. + #endif
  435.       pw_dbm_mode = O_RDWR;
  436.   #endif
  437.   
  438. ***************
  439. *** 535,544 ****
  440.        * which are restricted to root only.
  441.        */
  442.   
  443. !     while ((flag = getopt (argc, argv, "ludx:n:w:i:S")) != EOF) {
  444.           switch (flag) {
  445.               case 'x':
  446.                   max = strtol (optarg, &cp, 10);
  447.                   if (*cp || getuid ())
  448.                       usage ();
  449.   
  450. --- 669,686 ----
  451.        * which are restricted to root only.
  452.        */
  453.   
  454. ! #ifdef    SHADOWPWD
  455. !     while ((flag = getopt (argc, argv, "ludx:n:w:i:S")) != EOF)
  456. ! #else
  457. !     while ((flag = getopt (argc, argv, "ludx:n:S")) != EOF)
  458. ! #endif
  459. !     {
  460.           switch (flag) {
  461.               case 'x':
  462.                   max = strtol (optarg, &cp, 10);
  463. + #ifndef    SHADOWPWD
  464. +                 max /= 7;
  465. + #endif
  466.                   if (*cp || getuid ())
  467.                       usage ();
  468.   
  469. ***************
  470. *** 546,556 ****
  471. --- 688,702 ----
  472.                   break;
  473.               case 'n':
  474.                   min = strtol (optarg, &cp, 10);
  475. + #ifndef    SHADOWPWD
  476. +                 min /= 7;
  477. + #endif
  478.                   if (*cp || getuid ())
  479.                       usage ();
  480.   
  481.                   nflg++;
  482.                   break;
  483. + #ifdef    SHADOWPWD
  484.               case 'w':
  485.                   warn = strtol (optarg, &cp, 10);
  486.                   if (*cp || getuid ())
  487. ***************
  488. *** 565,570 ****
  489. --- 711,717 ----
  490.   
  491.                   iflg++;
  492.                   break;
  493. + #endif    /* SHADOWPWD */
  494.               case 'S':
  495.                   if (getuid ())
  496.                       usage ();
  497. ***************
  498. *** 598,608 ****
  499. --- 745,763 ----
  500.        * -i may appear with each other.  -d, -l and -S must appear alone.
  501.        */
  502.   
  503. + #ifdef    SHADOWPWD
  504.       if ((dflg || lflg || xflg || nflg ||
  505.                   wflg || iflg || Sflg) && optind >= argc)
  506. + #else
  507. +     if ((dflg || lflg || xflg || nflg || Sflg) && optind >= argc)
  508. + #endif
  509.           usage ();
  510.   
  511. + #ifdef    SHADOWPWD
  512.       if ((dflg + lflg + uflg + (xflg || nflg || wflg || iflg) + Sflg) > 1)
  513. + #else
  514. +     if ((dflg + lflg + uflg + (xflg || nflg) + Sflg) > 1)
  515. + #endif
  516.           usage ();
  517.   
  518.       /*
  519. ***************
  520. *** 655,660 ****
  521. --- 810,816 ----
  522.       if (! Sflg)
  523.           printf (CHANGING, name);
  524.   
  525. + #ifdef    SHADOWPWD
  526.       /*
  527.        * The user name is valid, so let's get the shadow file
  528.        * entry.
  529. ***************
  530. *** 674,682 ****
  531. --- 830,843 ----
  532.       }
  533.       tspwd.sp_namp = strdup (sp->sp_namp);
  534.       tspwd.sp_pwdp = strdup (sp->sp_pwdp);
  535. + #endif    /* SHADOWPWD */
  536.   
  537.       if (Sflg) {
  538. + #ifdef    SHADOWPWD
  539.           print_status (pw, sp);
  540. + #else
  541. +         print_status (pw);
  542. + #endif
  543.   #ifdef    USE_SYSLOG
  544.           closelog ();
  545.   #endif
  546. ***************
  547. *** 687,693 ****
  548.        * If there are no other flags, just change the password.
  549.        */
  550.   
  551. !     if (! (dflg || lflg || uflg || xflg || nflg || wflg || iflg)) {
  552.   
  553.           /*
  554.            * See if the user is permitted to change the password.
  555. --- 848,886 ----
  556.        * If there are no other flags, just change the password.
  557.        */
  558.   
  559. ! #ifdef    SHADOWPWD
  560. !     if (! (dflg || lflg || uflg || xflg || nflg || wflg || iflg))
  561. ! #else
  562. !     if (! (dflg || lflg || uflg || xflg || nflg))
  563. ! #endif
  564. !     {
  565. ! #ifdef    SHADOWPWD
  566. !         if (sp->sp_pwdp[0] == '@') {
  567. !             if (pw_auth (sp->sp_pwdp + 1, name, PW_CHANGE)) {
  568. ! #ifdef    USE_SYSLOG
  569. !                 syslog (LOG_INFO, NOCHGPASSWD, name);
  570. !                 closelog ();
  571. ! #endif
  572. !                 exit (1);
  573. !             } else {
  574. !                 update_age (sp);
  575. !                 goto done;
  576. !             }
  577. !         }
  578. ! #else    /* !SHADOWPWD */
  579. !         if (pw->pw_passwd[0] == '@') {
  580. !             if (pw_auth (pw->pw_passwd + 1, name, PW_CHANGE)) {
  581. ! #ifdef    USE_SYSLOG
  582. !                 syslog (LOG_INFO, CHGPASSWD, name);
  583. !                 closelog ();
  584. ! #endif
  585. !                 exit (0);
  586. !             } else {
  587. !                 update_age (pw);
  588. !                 goto done;
  589. !             }
  590. !         }
  591. ! #endif    /* SHADOWPWD */
  592.   
  593.           /*
  594.            * See if the user is permitted to change the password.
  595. ***************
  596. *** 694,702 ****
  597.            * Otherwise, go ahead and set a new password.
  598.            */
  599.   
  600.           check_password (pw, sp);
  601. !         if (new_password (pw, sp)) {
  602.               fprintf (stderr, UNCHANGED, name);
  603.   #ifdef    USE_SYSLOG
  604.               closelog ();
  605. --- 887,900 ----
  606.            * Otherwise, go ahead and set a new password.
  607.            */
  608.   
  609. + #ifdef    SHADOWPWD
  610.           check_password (pw, sp);
  611. !         if (new_password (pw, sp))
  612. ! #else
  613. !         check_password (pw);
  614. !         if (new_password (pw))
  615. ! #endif
  616. !         {
  617.               fprintf (stderr, UNCHANGED, name);
  618.   #ifdef    USE_SYSLOG
  619.               closelog ();
  620. ***************
  621. *** 711,743 ****
  622.        */
  623.   
  624.       if (dflg)            /* Set password to blank */
  625.           sp->sp_pwdp = "";
  626.       if (lflg) {            /* Set password to "locked" value */
  627.           if (sp->sp_pwdp && sp->sp_pwdp[0] != '!') {
  628.               strcpy (new_passwd, "!");
  629.               strcat (new_passwd, sp->sp_pwdp);
  630.               sp->sp_pwdp = new_passwd;
  631.           }
  632.       }
  633.       if (uflg) {            /* Undo password "locked" value */
  634.           if (sp->sp_pwdp && sp->sp_pwdp[0] == '!') {
  635.               strcpy (new_passwd, sp->sp_pwdp + 1);
  636.               sp->sp_pwdp = new_passwd;
  637.           }
  638. !     }
  639. !     if (xflg)
  640.           sp->sp_max = (max * DAY) / SCALE;
  641. !     if (nflg)
  642.           sp->sp_min = (min * DAY) / SCALE;
  643.   
  644.       if (wflg)
  645.           sp->sp_warn = (warn * DAY) / SCALE;
  646.   
  647.       if (iflg)
  648.           sp->sp_inact = (inact * DAY) / SCALE;
  649.   
  650.       /*
  651.        * Before going any further, raise the ulimit to prevent
  652.        * colliding into a lowered ulimit, and set the real UID
  653. --- 909,980 ----
  654.        */
  655.   
  656.       if (dflg)            /* Set password to blank */
  657. + #ifdef    SHADOWPWD
  658.           sp->sp_pwdp = "";
  659. ! #else
  660. !         pw->pw_passwd = "";
  661. ! #endif
  662.       if (lflg) {            /* Set password to "locked" value */
  663. + #ifdef    SHADOWPWD
  664.           if (sp->sp_pwdp && sp->sp_pwdp[0] != '!') {
  665.               strcpy (new_passwd, "!");
  666.               strcat (new_passwd, sp->sp_pwdp);
  667.               sp->sp_pwdp = new_passwd;
  668.           }
  669. + #else
  670. +         if (pw->pw_passwd & pw->pw_passwd[0] != '!') {
  671. +             strcpy (new_passwd, "!");
  672. +             strcat (new_passwd, pw->pw_passwd);
  673. +             pw->pw_passwd = new_passwd;
  674. +         }
  675. + #endif
  676.       }
  677.       if (uflg) {            /* Undo password "locked" value */
  678. + #ifdef    SHADOWPWD
  679.           if (sp->sp_pwdp && sp->sp_pwdp[0] == '!') {
  680.               strcpy (new_passwd, sp->sp_pwdp + 1);
  681.               sp->sp_pwdp = new_passwd;
  682.           }
  683. ! #else
  684. !         if (pw->pw_passwd && pw->pw_passwd[0] == '!') {
  685. !             strcpy (new_passwd, pw->pw_passwd + 1);
  686. !             pw->pw_passwd = new_passwd;
  687. !         }
  688. ! #endif
  689. !     }
  690. ! #if !defined(SHADOWPWD) && defined(ATT_AGE)
  691. !     bzero (age, sizeof age);
  692. !     strcpy (age, pw->pw_age);
  693. ! #endif
  694. !     if (xflg) {
  695. ! #ifdef    SHADOWPWD
  696.           sp->sp_max = (max * DAY) / SCALE;
  697. ! #else
  698. !         age[0] = i64c (max);
  699. ! #endif
  700. !     }
  701. !     if (nflg) {
  702. ! #ifdef    SHADOWPWD
  703.           sp->sp_min = (min * DAY) / SCALE;
  704. + #else
  705. +         if (age[0] == '\0')
  706. +             age[0] = '/';
  707.   
  708. +         age[1] = i64c (min);
  709. + #endif
  710. +     }
  711. + #ifdef    SHADOWPWD
  712.       if (wflg)
  713.           sp->sp_warn = (warn * DAY) / SCALE;
  714.   
  715.       if (iflg)
  716.           sp->sp_inact = (inact * DAY) / SCALE;
  717. + #endif
  718. + #if !defined(SHADOWPWD) && defined(ATT_AGE)
  719. +     pw->pw_age = age;
  720. + #endif
  721.   
  722. + done:
  723.       /*
  724.        * Before going any further, raise the ulimit to prevent
  725.        * colliding into a lowered ulimit, and set the real UID
  726. ***************
  727. *** 772,795 ****
  728.        */
  729.   
  730.       for (i = 0;i < 30;i++)
  731.           if (spw_lock ())
  732.               break;
  733.   
  734.       if (i == 30) {
  735.           fprintf (stderr, SPWDBUSY);
  736.   #ifdef    USE_SYSLOG
  737.           syslog (LOG_WARN, SPWDBUSY2);
  738.           closelog ();
  739.   #endif
  740.           exit (1);
  741.       }
  742. !     if (! spw_open (O_RDWR)) {
  743.           fprintf (stderr, OPNERROR);
  744.   #ifdef    USE_SYSLOG
  745.           syslog (LOG_ERR, OPNERROR2);
  746.           closelog ();
  747.   #endif
  748.           (void) spw_unlock ();
  749.           exit (1);
  750.       }
  751.   
  752. --- 1009,1053 ----
  753.        */
  754.   
  755.       for (i = 0;i < 30;i++)
  756. + #ifdef    SHADOWPWD
  757.           if (spw_lock ())
  758. + #else
  759. +         if (pw_lock ())
  760. + #endif
  761.               break;
  762.   
  763.       if (i == 30) {
  764. + #ifdef    SHADOWPWD
  765.           fprintf (stderr, SPWDBUSY);
  766. + #else
  767. +         fprintf (stderr, PWDBUSY);
  768. + #endif
  769.   #ifdef    USE_SYSLOG
  770. + #ifdef    SHADOWPWD
  771.           syslog (LOG_WARN, SPWDBUSY2);
  772. + #else
  773. +         syslog (LOG_WARN, PWDBUSY2);
  774. + #endif
  775.           closelog ();
  776.   #endif
  777.           exit (1);
  778.       }
  779. ! #ifdef    SHADOWPWD
  780. !     if (! spw_open (O_RDWR))
  781. ! #else
  782. !     if (! pw_open (O_RDWR))
  783. ! #endif
  784. !     {
  785.           fprintf (stderr, OPNERROR);
  786.   #ifdef    USE_SYSLOG
  787.           syslog (LOG_ERR, OPNERROR2);
  788.           closelog ();
  789.   #endif
  790. + #ifdef    SHADOWPWD
  791.           (void) spw_unlock ();
  792. + #else
  793. +         (void) pw_unlock ();
  794. + #endif
  795.           exit (1);
  796.       }
  797.   
  798. ***************
  799. *** 798,824 ****
  800.        * update that entry as well.
  801.        */
  802.   
  803. !     if (! spw_update (sp)) {
  804.           fprintf (stderr, UPDERROR);
  805.   #ifdef    USE_SYSLOG
  806.           syslog (LOG_ERR, UPDERROR2);
  807.           closelog ();
  808.   #endif
  809.           (void) spw_unlock ();
  810.           exit (1);
  811.       }
  812.   #ifdef    NDBM
  813. !     if (access ("/etc/shadow.pag", 0) == 0 && ! sp_dbm_update (sp)) {
  814.           fprintf (stderr, DBMERROR);
  815.   #ifdef    USE_SYSLOG
  816.           syslog (LOG_ERR, DBMERROR2);
  817.           closelog ();
  818.   #endif
  819.           (void) spw_unlock ();
  820.           exit (1);
  821.       }
  822.       endspent ();
  823.   #endif
  824.   
  825.       /*
  826.        * Changes have all been made, so commit them and unlock the
  827. --- 1056,1103 ----
  828.        * update that entry as well.
  829.        */
  830.   
  831. ! #ifdef    SHADOWPWD
  832. !     if (! spw_update (sp))
  833. ! #else
  834. !     if (! pw_update (pw))
  835. ! #endif
  836. !     {
  837.           fprintf (stderr, UPDERROR);
  838.   #ifdef    USE_SYSLOG
  839.           syslog (LOG_ERR, UPDERROR2);
  840.           closelog ();
  841.   #endif
  842. + #ifdef    SHADOWPWD
  843.           (void) spw_unlock ();
  844. + #else
  845. +         (void) pw_unlock ();
  846. + #endif
  847.           exit (1);
  848.       }
  849.   #ifdef    NDBM
  850. ! #ifdef    SHADOWPWD
  851. !     if (access ("/etc/shadow.pag", 0) == 0 && ! sp_dbm_update (sp))
  852. ! #else
  853. !     if (access ("/etc/passwd.pag", 0) == 0 && ! pw_dbm_update (pw))
  854. ! #endif
  855. !     {
  856.           fprintf (stderr, DBMERROR);
  857.   #ifdef    USE_SYSLOG
  858.           syslog (LOG_ERR, DBMERROR2);
  859.           closelog ();
  860.   #endif
  861. + #ifdef    SHADOWPWD
  862.           (void) spw_unlock ();
  863. + #else
  864. +         (void) pw_unlock ();
  865. + #endif
  866.           exit (1);
  867.       }
  868. + #ifdef    SHADOWPWD
  869.       endspent ();
  870.   #endif
  871. +     endpwent ();
  872. + #endif    /* NDBM */
  873.   
  874.       /*
  875.        * Changes have all been made, so commit them and unlock the
  876. ***************
  877. *** 825,840 ****
  878.        * file.
  879.        */
  880.   
  881. !     if (! spw_close ()) {
  882.           fprintf (stderr, CLSERROR);
  883.   #ifdef    USE_SYSLOG
  884.           syslog (LOG_ERR, CLSERROR2);
  885.           closelog ();
  886.   #endif
  887.           (void) spw_unlock ();
  888.           exit (1);
  889.       }
  890. !     if (! spw_unlock ()) {
  891.           fprintf (stderr, UNLKERROR);
  892.   #ifdef    USE_SYSLOG
  893.           syslog (LOG_ERR, UNLKERROR2);
  894. --- 1104,1133 ----
  895.        * file.
  896.        */
  897.   
  898. ! #ifdef    SHADOWPWD
  899. !     if (! spw_close ())
  900. ! #else
  901. !     if (! pw_close ())
  902. ! #endif
  903. !     {
  904.           fprintf (stderr, CLSERROR);
  905.   #ifdef    USE_SYSLOG
  906.           syslog (LOG_ERR, CLSERROR2);
  907.           closelog ();
  908.   #endif
  909. + #ifdef    SHADOWPWD
  910.           (void) spw_unlock ();
  911. + #else
  912. +         (void) pw_unlock ();
  913. + #endif
  914.           exit (1);
  915.       }
  916. ! #ifdef    SHADOWPWD
  917. !     if (! spw_unlock ())
  918. ! #else
  919. !     if (! pw_unlock ())
  920. ! #endif
  921. !     {
  922.           fprintf (stderr, UNLKERROR);
  923.   #ifdef    USE_SYSLOG
  924.           syslog (LOG_ERR, UNLKERROR2);
  925. Index: pwd.h.m4
  926. *** pwd.h.m4.old    Sat Oct 10 11:17:23 1992
  927. --- pwd.h.m4    Sat Oct 10 11:17:22 1992
  928. ***************
  929. *** 7,12 ****
  930. --- 7,15 ----
  931.    * in all copies of source code, or included in human readable form
  932.    * and conspicuously displayed on all copies of object code or
  933.    * distribution media.
  934. +  *
  935. +  * This software is provided on an AS-IS basis and the author makes
  936. +  * no warrantee of any kind.
  937.    */
  938.   
  939.   /*
  940. ***************
  941. *** 17,23 ****
  942.    * is simply replaced by the standard system supplied /usr/include/pwd.h
  943.    * file.
  944.    *
  945. !  *    @(#)pwd.h.m4    3.4    13:22:36    3/9/92
  946.    */
  947.   
  948.   #ifndef    PWD_H
  949. --- 20,26 ----
  950.    * is simply replaced by the standard system supplied /usr/include/pwd.h
  951.    * file.
  952.    *
  953. !  *    @(#)pwd.h.m4    3.4.1.1    13:02:40    7/27/92
  954.    */
  955.   
  956.   #ifndef    PWD_H
  957. ***************
  958. *** 34,42 ****
  959.   
  960.   #ifdef    SVR4
  961.   #include <sys/types.h>
  962.   #include <limits.h>
  963.   #define NGROUPS NGROUPS_MAX
  964. ! #endif
  965.   
  966.   ifdef(`SUN4', `#define    ATT_AGE')
  967.   ifdef(`SUN4', `#define  ATT_COMMENT')
  968. --- 37,50 ----
  969.   
  970.   #ifdef    SVR4
  971.   #include <sys/types.h>
  972. + #ifndef    _POSIX_SOURCE
  973. + #define    _POSIX_SOURCE
  974. + #include <limits.h>
  975. + #else
  976.   #include <limits.h>
  977. + #endif    /* _POSIX_SOURCE */
  978.   #define NGROUPS NGROUPS_MAX
  979. ! #endif    /* SVR4 */
  980.   
  981.   ifdef(`SUN4', `#define    ATT_AGE')
  982.   ifdef(`SUN4', `#define  ATT_COMMENT')
  983. Index: pwent.c
  984. *** pwent.c.old    Sat Oct 10 11:17:40 1992
  985. --- pwent.c    Sat Oct 10 11:17:39 1992
  986. ***************
  987. *** 7,12 ****
  988. --- 7,15 ----
  989.    * in all copies of source code, or included in human readable form
  990.    * and conspicuously displayed on all copies of object code or
  991.    * distribution media.
  992. +  *
  993. +  * This software is provided on an AS-IS basis and the author makes
  994. +  * no warrantee of any kind.
  995.    */
  996.   
  997.   #include "config.h"
  998. ***************
  999. *** 60,66 ****
  1000.   #endif
  1001.   
  1002.   #ifndef    lint
  1003. ! static    char    sccsid[] = "@(#)pwent.c    3.8    20:37:54    3/7/92";
  1004.   #endif
  1005.   
  1006.   #define    SBUFSIZ    64
  1007. --- 63,69 ----
  1008.   #endif
  1009.   
  1010.   #ifndef    lint
  1011. ! static    char    sccsid[] = "@(#)pwent.c    3.9    13:02:42    7/27/92";
  1012.   #endif
  1013.   
  1014.   #define    SBUFSIZ    64
  1015. ***************
  1016. *** 272,278 ****
  1017.   
  1018.   struct passwd *
  1019.   getpwuid (uid)
  1020. ! int    uid;
  1021.   {
  1022.       struct    passwd    *pwd;
  1023.   #if defined(DBM) || defined(NDBM)
  1024. --- 275,281 ----
  1025.   
  1026.   struct passwd *
  1027.   getpwuid (uid)
  1028. ! uid_t    uid;
  1029.   {
  1030.       struct    passwd    *pwd;
  1031.   #if defined(DBM) || defined(NDBM)
  1032. Index: setup.c
  1033. *** setup.c.old    Sat Oct 10 11:17:58 1992
  1034. --- setup.c    Sat Oct 10 11:17:57 1992
  1035. ***************
  1036. *** 7,17 ****
  1037.    * in all copies of source code, or included in human readable form
  1038.    * and conspicuously displayed on all copies of object code or
  1039.    * distribution media.
  1040.    */
  1041.   
  1042.   #include <sys/types.h>
  1043. - #include <stdio.h>
  1044.   #include <utmp.h>
  1045.   #include <grp.h>
  1046.   
  1047.   #ifdef    BSD
  1048. --- 7,25 ----
  1049.    * in all copies of source code, or included in human readable form
  1050.    * and conspicuously displayed on all copies of object code or
  1051.    * distribution media.
  1052. +  *
  1053. +  * This software is provided on an AS-IS basis and the author makes
  1054. +  * no warrantee of any kind.
  1055.    */
  1056.   
  1057. + #ifdef    SVR4
  1058. + #include <utmpx.h>
  1059. + #else
  1060.   #include <sys/types.h>
  1061.   #include <utmp.h>
  1062. + #endif    /* SVR4 */
  1063. + #include <stdio.h>
  1064.   #include <grp.h>
  1065.   
  1066.   #ifdef    BSD
  1067. ***************
  1068. *** 34,45 ****
  1069.   #endif
  1070.   
  1071.   #ifndef    lint
  1072. ! static    char    sccsid[] = "@(#)setup.c    3.11    12:21:39    3/8/92";
  1073.   #endif
  1074.   
  1075.   #ifndef    SU
  1076.   extern    struct    utmp    utent;
  1077. ! #endif
  1078.   
  1079.   long    strtol ();
  1080.   #ifdef    HAVE_ULIMIT
  1081. --- 42,57 ----
  1082.   #endif
  1083.   
  1084.   #ifndef    lint
  1085. ! static    char    sccsid[] = "@(#)setup.c    3.12    13:02:46    7/27/92";
  1086.   #endif
  1087.   
  1088.   #ifndef    SU
  1089. + #ifdef    SVR4
  1090. + extern    struct    utmpx    utent;
  1091. + #else
  1092.   extern    struct    utmp    utent;
  1093. ! #endif    /* SVR4 */
  1094. ! #endif    /* !SU */
  1095.   
  1096.   long    strtol ();
  1097.   #ifdef    HAVE_ULIMIT
  1098. ***************
  1099. *** 83,89 ****
  1100.       long    l;
  1101.   
  1102.   #ifndef    SU
  1103. !     (void) strcat (strcpy (tty, "/dev/"), utent.ut_line);
  1104.   
  1105.       if (! (group = getdef_str ("TTYGROUP")))
  1106.           i = info->pw_gid;
  1107. --- 95,104 ----
  1108.       long    l;
  1109.   
  1110.   #ifndef    SU
  1111. !     if (utent.ut_line[0] != '/')
  1112. !         (void) strcat (strcpy (tty, "/dev/"), utent.ut_line);
  1113. !     else
  1114. !         (void) strcpy (tty, utent.ut_line);
  1115.   
  1116.       if (! (group = getdef_str ("TTYGROUP")))
  1117.           i = info->pw_gid;
  1118. Index: smain.c
  1119. *** smain.c.old    Sat Oct 10 11:18:16 1992
  1120. --- smain.c    Sat Oct 10 11:18:15 1992
  1121. ***************
  1122. *** 1,5 ****
  1123.   /*
  1124. !  * Copyright 1989, 1990, 1991, John F. Haugh II
  1125.    * All rights reserved.
  1126.    *
  1127.    * Permission is granted to copy and create derivative works for any
  1128. --- 1,5 ----
  1129.   /*
  1130. !  * Copyright 1989, 1990, 1991, 1992, John F. Haugh II
  1131.    * All rights reserved.
  1132.    *
  1133.    * Permission is granted to copy and create derivative works for any
  1134. ***************
  1135. *** 7,12 ****
  1136. --- 7,15 ----
  1137.    * in all copies of source code, or included in human readable form
  1138.    * and conspicuously displayed on all copies of object code or
  1139.    * distribution media.
  1140. +  *
  1141. +  * This software is provided on an AS-IS basis and the author makes
  1142. +  * no warrantee of any kind.
  1143.    */
  1144.   
  1145.   #include <sys/types.h>
  1146. ***************
  1147. *** 13,19 ****
  1148.   #include <stdio.h>
  1149.   
  1150.   #ifndef    lint
  1151. ! static    char    sccsid[] = "@(#)smain.c    3.12    15:26:53    4/28/92";
  1152.   #endif
  1153.   
  1154.   /*
  1155. --- 16,22 ----
  1156.   #include <stdio.h>
  1157.   
  1158.   #ifndef    lint
  1159. ! static    char    sccsid[] = "@(#)smain.c    3.13    13:04:04    7/27/92";
  1160.   #endif
  1161.   
  1162.   /*
  1163. ***************
  1164. *** 37,43 ****
  1165. --- 40,49 ----
  1166.   #include <signal.h>
  1167.   #include "lastlog.h"
  1168.   #include "pwd.h"
  1169. + #ifdef    SHADOWPWD
  1170.   #include "shadow.h"
  1171. + #endif
  1172. + #include "pwauth.h"
  1173.   
  1174.   #ifdef    USE_SYSLOG
  1175.   #include <syslog.h>
  1176. ***************
  1177. *** 108,113 ****
  1178. --- 114,120 ----
  1179.   extern    char    *getpass ();
  1180.   extern    char    *tz ();
  1181.   extern    char    *pw_encrypt();
  1182. + extern    int    pw_auth();
  1183.   extern    struct    passwd    *getpwuid ();
  1184.   extern    struct    passwd    *getpwnam ();
  1185.   extern    struct    spwd    *getspnam ();
  1186. ***************
  1187. *** 177,183 ****
  1188. --- 184,192 ----
  1189.       int    fakelogin = 0;
  1190.       int    amroot = 0;
  1191.       struct    passwd    *pw = 0;
  1192. + #ifdef    SHADOWPWD
  1193.       struct    spwd    *spwd = 0;
  1194. + #endif
  1195.   
  1196.       /*
  1197.        * Get the program name.  The program name is used as a
  1198. ***************
  1199. *** 289,295 ****
  1200.        * or if the user is to be logged into a subsystem root.
  1201.        *
  1202.        * The password file entries for the user is gotten and the
  1203. !      * accont validated.
  1204.        */
  1205.   
  1206.       if (pw = getpwnam (name)) {
  1207. --- 298,304 ----
  1208.        * or if the user is to be logged into a subsystem root.
  1209.        *
  1210.        * The password file entries for the user is gotten and the
  1211. !      * account validated.
  1212.        */
  1213.   
  1214.       if (pw = getpwnam (name)) {
  1215. ***************
  1216. *** 316,322 ****
  1217.        * Set the default shell.
  1218.        */
  1219.   
  1220. !     if (pwent.pw_shell == 0 || pwent.pw_shell[0] == '\0')
  1221.           pwent.pw_shell = "/bin/sh";
  1222.   
  1223.       /*
  1224. --- 325,331 ----
  1225.        * Set the default shell.
  1226.        */
  1227.   
  1228. !     if (pwent.pw_shell[0] == '\0')
  1229.           pwent.pw_shell = "/bin/sh";
  1230.   
  1231.       /*
  1232. ***************
  1233. *** 330,336 ****
  1234.        * Get the password from the invoker
  1235.        */
  1236.   
  1237. !     if (! amroot && pwent.pw_passwd[0]) {
  1238.           if (! (cp = getpass ("Password:"))) {
  1239.   #ifdef    USE_SYSLOG
  1240.               syslog (pwent.pw_uid ? LOG_WARN:LOG_CRIT,
  1241. --- 339,345 ----
  1242.        * Get the password from the invoker
  1243.        */
  1244.   
  1245. !     if (! amroot && pwent.pw_passwd[0] && pwent.pw_passwd[0] != '@') {
  1246.           if (! (cp = getpass ("Password:"))) {
  1247.   #ifdef    USE_SYSLOG
  1248.               syslog (pwent.pw_uid ? LOG_WARN:LOG_CRIT,
  1249. ***************
  1250. *** 337,364 ****
  1251.                   "Unable to get password for %s\n", name);
  1252.   #endif
  1253.               goto failure;
  1254. !         } else
  1255.               (void) strncpy (pass, cp, sizeof pass);
  1256.       } else
  1257.           bzero (pass, sizeof pass);
  1258.   
  1259.       /*
  1260. !      * check encrypted passwords ...
  1261.        */
  1262.   
  1263. !     if (! amroot && ((pass[0] != '\0' || pwent.pw_passwd[0] != '\0') &&
  1264.               strcmp (pwent.pw_passwd,
  1265.                   pw_encrypt (pass, pwent.pw_passwd)) != 0)) {
  1266.   #ifdef    USE_SYSLOG
  1267.           syslog (pwent.pw_uid ? LOG_WARN:LOG_CRIT,
  1268.               "Invalid password for %s\n", name);
  1269.   #endif
  1270. ! failure:    sulog (0);        /* log failed attempt */
  1271.           puts ("Sorry.");
  1272.   #ifdef    USE_SYSLOG
  1273.           if ( getdef_bool("SYSLOG_SU_ENAB") )
  1274.               syslog (pwent.pw_uid ? LOG_INFO:LOG_CRIT,
  1275. !                 "- %s %s-%s\n", tty ? tty:"???",
  1276.                   oldname[0] ? oldname:"???",
  1277.                   name[0] ? name:"???");
  1278.           closelog ();
  1279. --- 346,390 ----
  1280.                   "Unable to get password for %s\n", name);
  1281.   #endif
  1282.               goto failure;
  1283. !         } else {
  1284.               (void) strncpy (pass, cp, sizeof pass);
  1285. +             bzero (cp, strlen (pass));
  1286. +         }
  1287.       } else
  1288.           bzero (pass, sizeof pass);
  1289.   
  1290.       /*
  1291. !      * See if the system defined authentication method is being used.
  1292. !      * The first character of an administrator defined method is an
  1293. !      * '@' character.
  1294.        */
  1295.   
  1296. !     if (pwent.pw_passwd[0] == '@') {
  1297. !         if (pw_auth (pwent.pw_passwd + 1, name, PW_SU)) {
  1298. ! #ifdef    USE_SYSLOG
  1299. !             syslog (pwent.pw_uid ? LOG_WARN:LOG_CRIT,
  1300. !                 "Authentication failed for %s\n", name);
  1301. ! #endif
  1302. !             goto failure;
  1303. !         }
  1304. !     } else if (! amroot && ((pass[0] || pwent.pw_passwd[0]) &&
  1305.               strcmp (pwent.pw_passwd,
  1306.                   pw_encrypt (pass, pwent.pw_passwd)) != 0)) {
  1307. +         /*
  1308. +          * check encrypted passwords like before ...
  1309. +          */
  1310.   #ifdef    USE_SYSLOG
  1311.           syslog (pwent.pw_uid ? LOG_WARN:LOG_CRIT,
  1312.               "Invalid password for %s\n", name);
  1313.   #endif
  1314. ! failure:    sulog (tty, 0);        /* log failed attempt */
  1315.           puts ("Sorry.");
  1316.   #ifdef    USE_SYSLOG
  1317.           if ( getdef_bool("SYSLOG_SU_ENAB") )
  1318.               syslog (pwent.pw_uid ? LOG_INFO:LOG_CRIT,
  1319. !                 "- %s %s-%s\n", tty,
  1320.                   oldname[0] ? oldname:"???",
  1321.                   name[0] ? name:"???");
  1322.           closelog ();
  1323. ***************
  1324. *** 410,421 ****
  1325.           goto top;
  1326.       }
  1327.   
  1328. !     sulog (1);            /* save SU information */
  1329.       endpwent ();
  1330.       endspent ();
  1331.   #ifdef    USE_SYSLOG
  1332.       if ( getdef_bool("SYSLOG_SU_ENAB") )
  1333. !         syslog (LOG_INFO, "+ %s %s-%s\n", tty ? tty:"???",
  1334.               oldname[0] ? oldname:"???", name[0] ? name:"???");
  1335.   #endif
  1336.       if (fakelogin)
  1337. --- 436,447 ----
  1338.           goto top;
  1339.       }
  1340.   
  1341. !     sulog (tty, 1);            /* save SU information */
  1342.       endpwent ();
  1343.       endspent ();
  1344.   #ifdef    USE_SYSLOG
  1345.       if ( getdef_bool("SYSLOG_SU_ENAB") )
  1346. !         syslog (LOG_INFO, "+ %s %s-%s\n", tty,
  1347.               oldname[0] ? oldname:"???", name[0] ? name:"???");
  1348.   #endif
  1349.       if (fakelogin)
  1350. Index: sulog.c
  1351. *** sulog.c.old    Sat Oct 10 11:18:36 1992
  1352. --- sulog.c    Sat Oct 10 11:18:36 1992
  1353. ***************
  1354. *** 1,5 ****
  1355.   /*
  1356. !  * Copyright 1989, 1990, 1991, John F. Haugh II
  1357.    * All rights reserved.
  1358.    *
  1359.    * Permission is granted to copy and create derivative works for any
  1360. --- 1,5 ----
  1361.   /*
  1362. !  * Copyright 1989, 1990, 1991, 1992, John F. Haugh II
  1363.    * All rights reserved.
  1364.    *
  1365.    * Permission is granted to copy and create derivative works for any
  1366. ***************
  1367. *** 7,12 ****
  1368. --- 7,15 ----
  1369.    * in all copies of source code, or included in human readable form
  1370.    * and conspicuously displayed on all copies of object code or
  1371.    * distribution media.
  1372. +  *
  1373. +  * This software is provided on an AS-IS basis and the author makes
  1374. +  * no warrantee of any kind.
  1375.    */
  1376.   
  1377.   #include <sys/types.h>
  1378. ***************
  1379. *** 23,29 ****
  1380.   #include "config.h"
  1381.   
  1382.   #ifndef    lint
  1383. ! static    char    sccsid[] = "@(#)sulog.c    3.2    07:43:31    9/17/91";
  1384.   #endif
  1385.   
  1386.   extern    char    name[];
  1387. --- 26,32 ----
  1388.   #include "config.h"
  1389.   
  1390.   #ifndef    lint
  1391. ! static    char    sccsid[] = "@(#)sulog.c    3.3    13:02:53    7/27/92";
  1392.   #endif
  1393.   
  1394.   extern    char    name[];
  1395. ***************
  1396. *** 32,44 ****
  1397.   time_t    time ();
  1398.   extern    char    *getdef_str();
  1399.   
  1400. ! void    sulog (success)
  1401. ! int    success;
  1402.   {
  1403.       char    *sulog;
  1404. -     char    *tty;
  1405.       char    *cp;
  1406. -     char    *ttyname ();
  1407.       time_t    clock;
  1408.       struct    tm    *tm;
  1409.       struct    tm    *localtime ();
  1410. --- 35,51 ----
  1411.   time_t    time ();
  1412.   extern    char    *getdef_str();
  1413.   
  1414. ! /*
  1415. !  * sulog - log a SU command execution result
  1416. !  */
  1417. ! void
  1418. ! sulog (tty, success)
  1419. ! char    *tty;        /* Name of terminal SU was executed from */
  1420. ! int    success;    /* Success (1) or failure (0) of command */
  1421.   {
  1422.       char    *sulog;
  1423.       char    *cp;
  1424.       time_t    clock;
  1425.       struct    tm    *tm;
  1426.       struct    tm    *localtime ();
  1427. ***************
  1428. *** 52,65 ****
  1429.   
  1430.       (void) time (&clock);
  1431.       tm = localtime (&clock);
  1432. -     if (isatty (0) && (cp = ttyname (0))) {
  1433. -         if (tty = strrchr (cp, '/'))
  1434. -             tty++;
  1435. -         else
  1436. -             tty = cp;
  1437. -     } else
  1438. -         tty = "???";
  1439.   
  1440.       (void) fprintf (fp, "SU %.02d/%0.2d %.02d:%.02d %c %.6s %s-%s\n",
  1441.           tm->tm_mon + 1, tm->tm_mday, tm->tm_hour, tm->tm_min,
  1442. --- 59,64 ----
  1443. Index: sulogin.c
  1444. *** sulogin.c.old    Sat Oct 10 11:19:00 1992
  1445. --- sulogin.c    Sat Oct 10 11:18:59 1992
  1446. ***************
  1447. *** 7,19 ****
  1448.    * in all copies of source code, or included in human readable form
  1449.    * and conspicuously displayed on all copies of object code or
  1450.    * distribution media.
  1451.    */
  1452.   
  1453.   #include <sys/types.h>
  1454.   #include <signal.h>
  1455.   #include <stdio.h>
  1456.   #include "pwd.h"
  1457. - #include <utmp.h>
  1458.   #include <fcntl.h>
  1459.   #ifdef    BSD
  1460.   #include <strings.h>
  1461. --- 7,26 ----
  1462.    * in all copies of source code, or included in human readable form
  1463.    * and conspicuously displayed on all copies of object code or
  1464.    * distribution media.
  1465. +  *
  1466. +  * This software is provided on an AS-IS basis and the author makes
  1467. +  * no warrantee of any kind.
  1468.    */
  1469.   
  1470. + #ifdef SVR4
  1471. + #include <utmpx.h>
  1472. + #else
  1473.   #include <sys/types.h>
  1474. + #include <utmp.h>
  1475. + #endif
  1476.   #include <signal.h>
  1477.   #include <stdio.h>
  1478.   #include "pwd.h"
  1479.   #include <fcntl.h>
  1480.   #ifdef    BSD
  1481.   #include <strings.h>
  1482. ***************
  1483. *** 24,29 ****
  1484. --- 31,37 ----
  1485.   #include <memory.h>
  1486.   #endif
  1487.   #include "config.h"
  1488. + #include "pwauth.h"
  1489.   
  1490.   #if defined(BSD) || defined(SUN)
  1491.   #include <sgtty.h>
  1492. ***************
  1493. *** 48,54 ****
  1494.   #endif
  1495.   
  1496.   #ifndef    lint
  1497. ! static    char    sccsid[] = "@(#)sulogin.c    3.11    14:49:03    4/28/92";
  1498.   #endif
  1499.   
  1500.   char    name[BUFSIZ];
  1501. --- 56,62 ----
  1502.   #endif
  1503.   
  1504.   #ifndef    lint
  1505. ! static    char    sccsid[] = "@(#)sulogin.c    3.12    13:04:09    7/27/92";
  1506.   #endif
  1507.   
  1508.   char    name[BUFSIZ];
  1509. ***************
  1510. *** 58,64 ****
  1511. --- 66,76 ----
  1512.   char    mail[BUFSIZ];
  1513.   
  1514.   struct    passwd    pwent;
  1515. + #ifdef SVR4
  1516. + struct    utmpx    utent;
  1517. + #else
  1518.   struct    utmp    utent;
  1519. + #endif
  1520.   
  1521.   #ifdef    USE_SGTTY
  1522.   struct    sgttyb    termio;
  1523. ***************
  1524. *** 144,149 ****
  1525. --- 156,162 ----
  1526.           } else {
  1527.   #ifdef    USE_SYSLOG
  1528.               syslog (LOG_WARN, "cannot open %s\n", argv[1]);
  1529. +             closelog ();
  1530.   #endif
  1531.               exit (1);
  1532.           }
  1533. ***************
  1534. *** 152,157 ****
  1535. --- 165,171 ----
  1536.           printf ("No password file\n");
  1537.   #ifdef    USE_SYSLOG
  1538.           syslog (LOG_WARN, "No password file\n");
  1539. +         closelog ();
  1540.   #endif
  1541.           exit (1);
  1542.       }
  1543. ***************
  1544. *** 159,171 ****
  1545.       if (getppid () != 1) {        /* parent must be INIT */
  1546.   #ifdef    USE_SYSLOG
  1547.           syslog (LOG_WARN, "Pid == %d, not 1\n", getppid ());
  1548.   #endif
  1549.           exit (1);
  1550.       }
  1551.   #endif
  1552. !     if (! isatty (0) || ! isatty (1) || ! isatty (2))
  1553.           exit (1);        /* must be a terminal */
  1554.       while (*envp)            /* add inherited environment, */
  1555.           addenv (*envp++);    /* some variables change later */
  1556.   
  1557. --- 173,189 ----
  1558.       if (getppid () != 1) {        /* parent must be INIT */
  1559.   #ifdef    USE_SYSLOG
  1560.           syslog (LOG_WARN, "Pid == %d, not 1\n", getppid ());
  1561. +         closelog ();
  1562.   #endif
  1563.           exit (1);
  1564.       }
  1565.   #endif
  1566. !     if (! isatty (0) || ! isatty (1) || ! isatty (2)) {
  1567. ! #ifdef    USE_SYSLOG
  1568. !         closelog ();
  1569. ! #endif
  1570.           exit (1);        /* must be a terminal */
  1571. !     }
  1572.       while (*envp)            /* add inherited environment, */
  1573.           addenv (*envp++);    /* some variables change later */
  1574.   
  1575. ***************
  1576. *** 181,189 ****
  1577. --- 199,213 ----
  1578.       while (1) {        /* repeatedly get login/password pairs */
  1579.           entry (name, &pwent);    /* get entry from password file */
  1580.           if (pwent.pw_name == (char *) 0) {
  1581. +             /*
  1582. +              * Fail secure
  1583. +              */
  1584.               printf ("No password entry for 'root'\n");
  1585.   #ifdef    USE_SYSLOG
  1586.               syslog (LOG_WARN, "No password entry for 'root'\n");
  1587. +             closelog ();
  1588.   #endif
  1589.               exit (1);
  1590.           }
  1591. ***************
  1592. *** 198,203 ****
  1593. --- 222,228 ----
  1594.   (or give root password for system maintenance):"))) {
  1595.   #ifdef    USE_SYSLOG
  1596.               syslog (LOG_INFO, "Normal startup\n");
  1597. +             closelog ();
  1598.   #endif
  1599.   #ifdef    TELINIT
  1600.               execl ("/etc/telinit", "telinit", RUNLEVEL, (char *) 0);
  1601. ***************
  1602. *** 206,211 ****
  1603. --- 231,246 ----
  1604.           } else
  1605.               strcpy (pass, cp);
  1606.   
  1607. +         if (pwent.pw_name && pwent.pw_passwd[0] == '@') {
  1608. +             if (pw_auth (pwent.pw_passwd + 1, name, PW_LOGIN)) {
  1609. + #ifdef    USE_SYSLOG
  1610. +                 syslog (LOG_WARN,
  1611. +                     "Incorrect root authentication");
  1612. + #endif
  1613. +                 continue;
  1614. +             }
  1615. +             goto auth_done;
  1616. +         }
  1617.           if (valid (pass, &pwent)) /* check encrypted passwords ... */
  1618.               break;        /* ... encrypted passwords matched */
  1619.   
  1620. ***************
  1621. *** 214,219 ****
  1622. --- 249,255 ----
  1623.           syslog (LOG_WARN, "Incorrect root password\n");
  1624.   #endif
  1625.       }
  1626. + auth_done:
  1627.       alarm (0);
  1628.       signal (SIGALRM, SIG_DFL);
  1629.       environ = newenvp;        /* make new environment active */
  1630. ***************
  1631. *** 242,247 ****
  1632. --- 278,286 ----
  1633.   
  1634.       setup (&pwent);            /* set UID, GID, HOME, etc ... */
  1635.   
  1636. + #ifdef    USE_SYSLOG
  1637. +     closelog ();
  1638. + #endif
  1639.       shell (pwent.pw_shell, (char *) 0); /* exec the shell finally. */
  1640.       /*NOTREACHED*/
  1641.   }
  1642. Index: useradd.1
  1643. *** useradd.1.old    Sat Oct 10 11:19:19 1992
  1644. --- useradd.1    Sat Oct 10 11:19:18 1992
  1645. ***************
  1646. *** 7,19 ****
  1647.   .\" and conspicuously displayed on all copies of object code or
  1648.   .\" distribution media.
  1649.   .\"
  1650. ! .\"    @(#)useradd.1    3.2    20:38:24    3/7/92
  1651.   .\"
  1652.   .TH USERADD 1M
  1653.   .SH NAME
  1654.   useradd \- Create a new user or update default new user information
  1655.   .SH SYNOPSIS
  1656.   .B useradd
  1657.   [ \fB-c\fI comment\fR ]
  1658.   [ \fB-d\fI home_dir\fR ]
  1659.   [ \fB-e\fI expire_date\fR ]
  1660. --- 7,23 ----
  1661.   .\" and conspicuously displayed on all copies of object code or
  1662.   .\" distribution media.
  1663.   .\"
  1664. ! .\" This software is provided on an AS-IS basis and the author makes
  1665. ! .\" no warrantee of any kind.
  1666.   .\"
  1667. + .\"    @(#)useradd.1    3.3    13:04:12    7/27/92
  1668. + .\"
  1669.   .TH USERADD 1M
  1670.   .SH NAME
  1671.   useradd \- Create a new user or update default new user information
  1672.   .SH SYNOPSIS
  1673.   .B useradd
  1674. + [ \fB-A\fI method|DEFAULT ]
  1675.   [ \fB-c\fI comment\fR ]
  1676.   [ \fB-d\fI home_dir\fR ]
  1677.   [ \fB-e\fI expire_date\fR ]
  1678. ***************
  1679. *** 40,45 ****
  1680. --- 44,55 ----
  1681.   the home directory will be created, and initial files copied, depending
  1682.   on the command line options.
  1683.   The options which apply to the \fIuseradd\fR command are
  1684. + .IP "\fB-A \fImethod\fR|\fBDEFAULT\fR"
  1685. + The value of the user's authentication method.
  1686. + The authentication method is the name of a program which is responsible
  1687. + for validating the user's identity.
  1688. + The string \fBDEFAULT\fR may be used to change the user's authentication
  1689. + method to the standard system password method.
  1690.   .IP "\fB-d \fIhome_dir\fR"
  1691.   The new user will be created using \fIhome_dir\fR as the value for
  1692.   the user's login directory.
  1693. Index: useradd.c
  1694. *** useradd.c.old    Sat Oct 10 11:19:42 1992
  1695. --- useradd.c    Sat Oct 10 11:19:40 1992
  1696. ***************
  1697. *** 7,16 ****
  1698.    * in all copies of source code, or included in human readable form
  1699.    * and conspicuously displayed on all copies of object code or
  1700.    * distribution media.
  1701.    */
  1702.   
  1703.   #ifndef lint
  1704. ! static    char    sccsid[] = "@(#)useradd.c    3.9    09:41:30    3/19/92";
  1705.   #endif
  1706.   
  1707.   #include "config.h"
  1708. --- 7,19 ----
  1709.    * in all copies of source code, or included in human readable form
  1710.    * and conspicuously displayed on all copies of object code or
  1711.    * distribution media.
  1712. +  *
  1713. +  * This software is provided on an AS-IS basis and the author makes
  1714. +  * no warrantee of any kind.
  1715.    */
  1716.   
  1717.   #ifndef lint
  1718. ! static    char    sccsid[] = "@(#)useradd.c    3.12    10:52:16    10/10/92";
  1719.   #endif
  1720.   
  1721.   #include "config.h"
  1722. ***************
  1723. *** 30,36 ****
  1724. --- 33,42 ----
  1725.   #include <string.h>
  1726.   #endif
  1727.   
  1728. + #ifdef    SHADOWPWD
  1729.   #include "shadow.h"
  1730. + #endif
  1731. + #include "pwauth.h"
  1732.   
  1733.   #ifdef    USE_SYSLOG
  1734.   #include <syslog.h>
  1735. ***************
  1736. *** 44,50 ****
  1737. --- 50,58 ----
  1738.   char    def_home[BUFSIZ];
  1739.   char    def_shell[BUFSIZ];
  1740.   char    def_template[BUFSIZ] = "/etc/skel";
  1741. + #ifdef    SHADOWPWD
  1742.   long    def_inactive;
  1743. + #endif
  1744.   long    def_expire;
  1745.   char    def_file[] = "/etc/default/useradd";
  1746.   
  1747. ***************
  1748. *** 68,76 ****
  1749. --- 76,87 ----
  1750.   char    user_comment[BUFSIZ];
  1751.   char    user_home[BUFSIZ];
  1752.   char    user_shell[BUFSIZ];
  1753. + #ifdef    SHADOWPWD
  1754.   long    user_expire;
  1755. + #endif
  1756.   int    user_ngroups;
  1757.   gid_t    user_groups[NGROUPS_MAX];
  1758. + char    user_auth[BUFSIZ];
  1759.   
  1760.   char    *Prog;
  1761.   
  1762. ***************
  1763. *** 87,101 ****
  1764. --- 98,128 ----
  1765.   int    fflg;    /* days until account with expired password is locked         */
  1766.   int    eflg;    /* days after password changed before it becomes expired      */
  1767.   int    Dflg;    /* set/show new user default values                           */
  1768. + int    Aflg;    /* specify authentication method for user                     */
  1769.   
  1770.   #ifdef NDBM
  1771.   extern    int    pw_dbm_mode;
  1772. + #ifdef    SHADOWPWD
  1773.   extern    int    sp_dbm_mode;
  1774. + #endif
  1775.   extern    int    gr_dbm_mode;
  1776.   #ifdef    SHADOWGRP
  1777.   extern    int    sg_dbm_mode;
  1778.   #endif
  1779.   #endif
  1780. + int    home_added;
  1781. + int    pw_dbm_added;
  1782. + #ifdef    NDBM
  1783. + int    gr_dbm_added;
  1784. + #ifdef    SHADOWPWD
  1785. + int    sp_dbm_added;
  1786. + #endif
  1787. + #ifdef    SHADOWGRP
  1788. + int    sg_dbm_added;
  1789. + #endif
  1790. + #endif    /* NDBM */
  1791.   extern    FILE    *fopen();
  1792.   extern    int    fclose();
  1793.   extern    char    *malloc();
  1794. ***************
  1795. *** 125,133 ****
  1796. --- 152,162 ----
  1797.   extern    int    pw_rewind();
  1798.   extern    int    pw_open();
  1799.   
  1800. + #ifdef    SHADOWPWD
  1801.   extern    int    spw_lock();
  1802.   extern    int    spw_unlock();
  1803.   extern    int    spw_open();
  1804. + #endif
  1805.   
  1806.   #define    DAY    (24L*3600L)
  1807.   #define    WEEK    (7*DAY)
  1808. ***************
  1809. *** 364,370 ****
  1810. --- 393,401 ----
  1811.   
  1812.           def_group = 1;
  1813.           strcpy (def_home, "/home");
  1814. + #ifdef    SHADOWPWD
  1815.           def_inactive = 0;
  1816. + #endif
  1817.           def_expire = 0;
  1818.           return;
  1819.       }
  1820. ***************
  1821. *** 409,414 ****
  1822. --- 440,446 ----
  1823.               strncpy (def_shell, buf + 6, BUFSIZ);
  1824.           }
  1825.   
  1826. + #ifdef    SHADOWPWD
  1827.           /*
  1828.            * Default Password Inactive value
  1829.            */
  1830. ***************
  1831. *** 416,421 ****
  1832. --- 448,454 ----
  1833.           else if (strncmp ("INACTIVE=", buf, 9) == 0) {
  1834.               def_inactive = atoi (buf + 9);
  1835.           }
  1836. + #endif
  1837.           
  1838.           /*
  1839.            * Default Password Expiration value
  1840. ***************
  1841. *** 439,445 ****
  1842. --- 472,480 ----
  1843.   {
  1844.       printf ("GROUP=%d\n", def_group);
  1845.       printf ("HOME=%s\n", def_home);
  1846. + #ifdef    SHADOWPWD
  1847.       printf ("INACTIVE=%d\n", def_inactive);
  1848. + #endif
  1849.       printf ("EXPIRE=%d\n", def_expire);
  1850.   }
  1851.   
  1852. ***************
  1853. *** 495,500 ****
  1854. --- 530,536 ----
  1855.                       fprintf (ofp, "HOME=%s\n", def_home);
  1856.   
  1857.                   out_home++;
  1858. + #ifdef    SHADOWPWD
  1859.               } else if (strncmp ("INACTIVE=", buf, 9) == 0) {
  1860.                   if (! out_inactive)
  1861.                       fprintf (ofp, "INACTIVE=%d\n",
  1862. ***************
  1863. *** 501,506 ****
  1864. --- 537,543 ----
  1865.                           def_inactive);
  1866.   
  1867.                   out_inactive++;
  1868. + #endif
  1869.               } else if (strncmp ("EXPIRE=", buf, 7) == 0) {
  1870.                   if (! out_expire)
  1871.                       fprintf (ofp, "EXPIRE=%d\n",
  1872. ***************
  1873. *** 524,533 ****
  1874.   
  1875.       if (! out_home)
  1876.           fprintf (ofp, "HOME=%s\n", def_home);
  1877.       if (! out_inactive)
  1878.           fprintf (ofp, "INACTIVE=%d\n", def_inactive);
  1879.       if (! out_expire)
  1880.           fprintf (ofp, "EXPIRE=%d\n", def_expire);
  1881.   
  1882. --- 561,570 ----
  1883.   
  1884.       if (! out_home)
  1885.           fprintf (ofp, "HOME=%s\n", def_home);
  1886. ! #ifdef    SHADOWPWD
  1887.       if (! out_inactive)
  1888.           fprintf (ofp, "INACTIVE=%d\n", def_inactive);
  1889. ! #endif
  1890.       if (! out_expire)
  1891.           fprintf (ofp, "EXPIRE=%d\n", def_expire);
  1892.   
  1893. ***************
  1894. *** 564,572 ****
  1895. --- 601,615 ----
  1896.           return -1;
  1897.       }
  1898.   #ifdef    USE_SYSLOG
  1899. + #ifdef    SHADOWPWD
  1900.       syslog (LOG_INFO,
  1901.           "defaults: group=%d, home=%s, inactive=%d, expire=%d\n",
  1902.           def_group, def_home, def_inactive, def_expire);
  1903. + #else
  1904. +     syslog (LOG_INFO,
  1905. +         "defaults: group=%d, home=%s, expire=%d\n",
  1906. +         def_group, def_home, def_expire);
  1907. + #endif
  1908.   #endif
  1909.       return 0;
  1910.   }
  1911. ***************
  1912. *** 662,679 ****
  1913.           "\t\t[-d home] [-s shell] [-c comment] [-m [-k template]]\n");
  1914.   #ifdef    MDY_DATE
  1915.       fprintf (stderr,
  1916. !         "\t\t[-f inactive ] [-e expire mm/dd/yy ] name\n");
  1917.   #endif
  1918.   #ifdef    DMY_DATE
  1919.       fprintf (stderr,
  1920. !         "\t\t[-f inactive ] [-e expire dd/mm/yy ] name\n");
  1921.   #endif
  1922.   #ifdef    YMD_DATE
  1923.       fprintf (stderr,
  1924. !         "\t\t[-f inactive ] [-e expire yy/mm/dd ] name\n");
  1925.   #endif
  1926.       fprintf (stderr,
  1927.           "\t%s -D [-g group] [-b base] [-f inactive] [-e expire]\n",
  1928.               Prog);
  1929.   
  1930.       exit (1);
  1931. --- 705,741 ----
  1932.           "\t\t[-d home] [-s shell] [-c comment] [-m [-k template]]\n");
  1933.   #ifdef    MDY_DATE
  1934.       fprintf (stderr,
  1935. ! #ifdef    SHADOWPWD
  1936. !         "\t\t[-f inactive ] [-e expire mm/dd/yy ] [ -A program ] name\n"
  1937. ! #else
  1938. !         "\t\t[ -A program ] name\n"
  1939.   #endif
  1940. +         );
  1941. + #endif
  1942.   #ifdef    DMY_DATE
  1943.       fprintf (stderr,
  1944. ! #ifdef    SHADOWPWD
  1945. !         "\t\t[-f inactive ] [-e expire dd/mm/yy ] [ -A program ] name\n"
  1946. ! #else
  1947. !         "\t\t[ -A program ] name\n"
  1948. ! #endif
  1949. !         );
  1950.   #endif
  1951.   #ifdef    YMD_DATE
  1952.       fprintf (stderr,
  1953. ! #ifdef    SHADOWPWD
  1954. !         "\t\t[-f inactive ] [-e expire yy/mm/dd ] [ -A program ] name\n"
  1955. ! #else
  1956. !         "\t\t[ -A program ] name\n"
  1957. ! #endif
  1958. !         );
  1959.   #endif
  1960.       fprintf (stderr,
  1961. + #ifdef    SHADOWPWD
  1962.           "\t%s -D [-g group] [-b base] [-f inactive] [-e expire]\n",
  1963. + #else
  1964. +         "\t%s -D [-g group] [-b base] [-e expire]\n",
  1965. + #endif
  1966.               Prog);
  1967.   
  1968.       exit (1);
  1969. ***************
  1970. *** 690,699 ****
  1971. --- 752,777 ----
  1972.   new_pwent (pwent)
  1973.   struct    passwd    *pwent;
  1974.   {
  1975. + #ifndef    SHADOWPWD
  1976. +     static    char    age[3];
  1977. + #endif
  1978.       memset (pwent, 0, sizeof *pwent);
  1979.       pwent->pw_name = user_name;
  1980. + #ifdef    SHADOWPWD
  1981.       pwent->pw_passwd = "*";
  1982.       pwent->pw_age = "";
  1983. + #else
  1984. +     if (Aflg)
  1985. +         pwent->pw_passwd = user_auth;
  1986. +     else
  1987. +         pwent->pw_passwd = "!";
  1988. +     pwent->pw_age = age;
  1989. +     age[0] = i64c (def_expire + 6 / 7);
  1990. +     age[1] = i64c (0);
  1991. +     age[2] = '\0';
  1992. + #endif
  1993.       pwent->pw_uid = user_id;
  1994.       pwent->pw_gid = user_gid;
  1995.       pwent->pw_gecos = user_comment;
  1996. ***************
  1997. *** 702,707 ****
  1998. --- 780,786 ----
  1999.       pwent->pw_shell = user_shell;
  2000.   }
  2001.   
  2002. + #ifdef    SHADOWPWD
  2003.   /*
  2004.    * new_spent - initialize the values in a shadow password file entry
  2005.    *
  2006. ***************
  2007. *** 715,721 ****
  2008.   {
  2009.       memset (spent, 0, sizeof *spent);
  2010.       spent->sp_namp = user_name;
  2011. !     spent->sp_pwdp = "!";
  2012.       spent->sp_lstchg = 0;
  2013.       spent->sp_min = 0;
  2014.       spent->sp_max = def_expire;
  2015. --- 794,805 ----
  2016.   {
  2017.       memset (spent, 0, sizeof *spent);
  2018.       spent->sp_namp = user_name;
  2019. !     if (Aflg)
  2020. !         spent->sp_pwdp = user_auth;
  2021. !     else
  2022. !         spent->sp_pwdp = "!";
  2023.       spent->sp_lstchg = 0;
  2024.       spent->sp_min = 0;
  2025.       spent->sp_max = def_expire;
  2026. ***************
  2027. *** 723,728 ****
  2028. --- 807,813 ----
  2029.       spent->sp_inact = def_inactive;
  2030.       spent->sp_expire = user_expire;
  2031.   }
  2032. + #endif
  2033.   
  2034.   /*
  2035.    * grp_update - add user to secondary group set
  2036. ***************
  2037. *** 792,798 ****
  2038.           if (! gr_update (grp)) {
  2039.               fprintf (stderr, "%s: error adding new group entry\n",
  2040.                   Prog);
  2041. !             exit (1);
  2042.           }
  2043.   #ifdef    NDBM
  2044.           /*
  2045. --- 877,883 ----
  2046.           if (! gr_update (grp)) {
  2047.               fprintf (stderr, "%s: error adding new group entry\n",
  2048.                   Prog);
  2049. !             fail (1);
  2050.           }
  2051.   #ifdef    NDBM
  2052.           /*
  2053. ***************
  2054. *** 802,809 ****
  2055.           if (! gr_dbm_update (grp)) {
  2056.               fprintf (stderr, "%s: cannot add new dbm group entry\n",
  2057.                   Prog);
  2058. !             exit (1);
  2059. !         }
  2060.   #endif
  2061.   #ifdef    USE_SYSLOG
  2062.           syslog (LOG_INFO, "add `%s' to group `%s'\n",
  2063. --- 887,895 ----
  2064.           if (! gr_dbm_update (grp)) {
  2065.               fprintf (stderr, "%s: cannot add new dbm group entry\n",
  2066.                   Prog);
  2067. !             fail (1);
  2068. !         } else
  2069. !             gr_dbm_added++;
  2070.   #endif
  2071.   #ifdef    USE_SYSLOG
  2072.           syslog (LOG_INFO, "add `%s' to group `%s'\n",
  2073. ***************
  2074. *** 847,853 ****
  2075.           if (! sgr_update (sgrp)) {
  2076.               fprintf (stderr, "%s: error adding new group entry\n",
  2077.                   Prog);
  2078. !             exit (1);
  2079.           }
  2080.   #ifdef    NDBM
  2081.           /*
  2082. --- 933,939 ----
  2083.           if (! sgr_update (sgrp)) {
  2084.               fprintf (stderr, "%s: error adding new group entry\n",
  2085.                   Prog);
  2086. !             fail (1);
  2087.           }
  2088.   #ifdef    NDBM
  2089.           /*
  2090. ***************
  2091. *** 854,874 ****
  2092.            * Update the DBM group file with the new entry as well.
  2093.            */
  2094.   
  2095. !         if (! sgr_dbm_update (sgrp)) {
  2096.               fprintf (stderr, "%s: cannot add new dbm group entry\n",
  2097.                   Prog);
  2098. !             exit (1);
  2099. !         }
  2100. ! #endif
  2101.   #ifdef    USE_SYSLOG
  2102.           syslog (LOG_INFO, "add `%s' to shadow group `%s'\n",
  2103.               user_name, sgrp->sg_name);
  2104. ! #endif
  2105.       }
  2106.   #ifdef NDBM
  2107.       endsgent ();
  2108. ! #endif
  2109. ! #endif
  2110.   }
  2111.   
  2112.   /*
  2113. --- 940,961 ----
  2114.            * Update the DBM group file with the new entry as well.
  2115.            */
  2116.   
  2117. !         if (! sg_dbm_update (sgrp)) {
  2118.               fprintf (stderr, "%s: cannot add new dbm group entry\n",
  2119.                   Prog);
  2120. !             fail (1);
  2121. !         } else
  2122. !             sg_dbm_added++;
  2123. ! #endif    /* NDBM */
  2124.   #ifdef    USE_SYSLOG
  2125.           syslog (LOG_INFO, "add `%s' to shadow group `%s'\n",
  2126.               user_name, sgrp->sg_name);
  2127. ! #endif    /* USE_SYSLOG */
  2128.       }
  2129.   #ifdef NDBM
  2130.       endsgent ();
  2131. ! #endif    /* NDBM */
  2132. ! #endif    /* SHADOWGRP */
  2133.   }
  2134.   
  2135.   /*
  2136. ***************
  2137. *** 933,940 ****
  2138.       int    anyflag = 0;
  2139.       int    arg;
  2140.   
  2141. !     while ((arg = getopt (argc, argv, "Du:og:G:d:s:c:mk:f:e:b:")) != EOF) {
  2142.           switch (arg) {
  2143.               case 'b':
  2144.                   if (! VALID (optarg)) {
  2145.                       fprintf (stderr,
  2146. --- 1020,1048 ----
  2147.       int    anyflag = 0;
  2148.       int    arg;
  2149.   
  2150. !     while ((arg = getopt (argc, argv,
  2151. ! #ifdef    SHADOWPWD
  2152. !         "A:Du:og:G:d:s:c:mk:f:e:b:"
  2153. ! #else
  2154. !         "A:Du:og:G:d:s:c:mk:e:b:"
  2155. ! #endif
  2156. !                     )) != EOF) {
  2157.           switch (arg) {
  2158. +             case 'A':
  2159. +                 if (! VALID (optarg) || (optarg[0] != '/' &&
  2160. +                     strcmp (optarg, "DEFAULT") != 0) ||
  2161. +                         strlen (optarg) > 256) {
  2162. +                     fprintf (stderr,
  2163. +                         "%s: invalid field `%s'\n",
  2164. +                         Prog, optarg);
  2165. +                     exit (3);
  2166. +                 }
  2167. +                 if (strcmp (optarg, "DEFAULT") != 0) {
  2168. +                     strcpy (user_auth, "@");
  2169. +                     strcat (user_auth, optarg);
  2170. +                     Aflg++;
  2171. +                 }
  2172. +                 break;
  2173.               case 'b':
  2174.                   if (! VALID (optarg)) {
  2175.                       fprintf (stderr,
  2176. ***************
  2177. *** 979,994 ****
  2178. --- 1087,1108 ----
  2179.                   if (Dflg)
  2180.                       def_expire = atoi (optarg);
  2181.                   else {
  2182. + #ifdef    SHADOWPWD
  2183.                       user_expire = strtoday (optarg);
  2184.   #ifdef    ITI_AGING
  2185.                       user_expire *= DAY;
  2186.   #endif
  2187. + #else
  2188. +                     usage ();
  2189. + #endif
  2190.                   }
  2191.                   break;
  2192. + #ifdef    SHADOWPWD
  2193.               case 'f':
  2194.                   fflg++;
  2195.                   def_inactive = atoi (optarg);
  2196.                   break;
  2197. + #endif
  2198.               case 'g':
  2199.                   gflg++;
  2200.                   if (isdigit (optarg[0]))
  2201. ***************
  2202. *** 1081,1098 ****
  2203.   {
  2204.       if (! pw_close ()) {
  2205.           fprintf (stderr, "%s: cannot rewrite password file\n", Prog);
  2206. !         exit (1);
  2207.       }
  2208.       if (! spw_close ()) {
  2209.           fprintf (stderr, "%s: cannot rewrite shadow password file\n",    
  2210.               Prog);
  2211. !         exit (1);
  2212.       }
  2213.       if (user_ngroups > 0) {
  2214.           if (! gr_close ()) {
  2215.               fprintf (stderr, "%s: cannot rewrite group file\n",
  2216.                   Prog);
  2217. !             exit (1);
  2218.           }
  2219.           (void) gr_unlock ();
  2220.   #ifdef    SHADOWGRP
  2221. --- 1195,1214 ----
  2222.   {
  2223.       if (! pw_close ()) {
  2224.           fprintf (stderr, "%s: cannot rewrite password file\n", Prog);
  2225. !         fail (1);
  2226.       }
  2227. + #ifdef    SHADOWPWD
  2228.       if (! spw_close ()) {
  2229.           fprintf (stderr, "%s: cannot rewrite shadow password file\n",    
  2230.               Prog);
  2231. !         fail (1);
  2232.       }
  2233. + #endif
  2234.       if (user_ngroups > 0) {
  2235.           if (! gr_close ()) {
  2236.               fprintf (stderr, "%s: cannot rewrite group file\n",
  2237.                   Prog);
  2238. !             fail (1);
  2239.           }
  2240.           (void) gr_unlock ();
  2241.   #ifdef    SHADOWGRP
  2242. ***************
  2243. *** 1099,1110 ****
  2244.           if (! sgr_close ()) {
  2245.               fprintf (stderr, "%s: cannot rewrite shadow group file\n",
  2246.                   Prog);
  2247. !             exit (1);
  2248.           }
  2249.           (void) sgr_unlock ();
  2250.   #endif
  2251.       }
  2252.       (void) spw_unlock ();
  2253.       (void) pw_unlock ();
  2254.   }
  2255.   
  2256. --- 1215,1228 ----
  2257.           if (! sgr_close ()) {
  2258.               fprintf (stderr, "%s: cannot rewrite shadow group file\n",
  2259.                   Prog);
  2260. !             fail (1);
  2261.           }
  2262.           (void) sgr_unlock ();
  2263.   #endif
  2264.       }
  2265. + #ifdef    SHADOWPWD
  2266.       (void) spw_unlock ();
  2267. + #endif
  2268.       (void) pw_unlock ();
  2269.   }
  2270.   
  2271. ***************
  2272. *** 1124,1129 ****
  2273. --- 1242,1248 ----
  2274.           fprintf (stderr, "%s: unable to open password file\n", Prog);
  2275.           exit (1);
  2276.       }
  2277. + #ifdef    SHADOWPWD
  2278.       if (! spw_lock ()) {
  2279.           fprintf (stderr, "%s: cannot lock shadow password file\n", Prog);
  2280.           exit (1);
  2281. ***************
  2282. *** 1132,1137 ****
  2283. --- 1251,1257 ----
  2284.           fprintf (stderr, "%s: cannot open shadow password file\n", Prog);
  2285.           exit (1);
  2286.       }
  2287. + #endif
  2288.   }
  2289.   
  2290.   /*
  2291. ***************
  2292. *** 1144,1150 ****
  2293. --- 1264,1272 ----
  2294.   usr_update ()
  2295.   {
  2296.       struct    passwd    pwent;
  2297. + #ifdef    SHADOWPWD
  2298.       struct    spwd    spent;
  2299. + #endif
  2300.   
  2301.       if (! oflg)
  2302.           find_new_uid ();
  2303. ***************
  2304. *** 1154,1159 ****
  2305. --- 1276,1282 ----
  2306.           fprintf (stderr, "%s: error adding new password entry\n", Prog);
  2307.           exit (1);
  2308.       }
  2309. + #ifdef    SHADOWPWD
  2310.       new_spent (&spent);
  2311.       if (! spw_update (&spent)) {
  2312.           fprintf (stderr, "%s: error adding new shadow password entry\n",
  2313. ***************
  2314. *** 1160,1186 ****
  2315.               Prog);
  2316.           exit (1);
  2317.       }
  2318.   #if defined(DBM) || defined(NDBM)
  2319. !     if (access ("/etc/passwd.pag", 0) == 0 && ! pw_dbm_update (&pwent)) {
  2320. !         fprintf (stderr, "%s: error updating password dbm entry\n",
  2321. !             Prog);
  2322. !         exit (1);
  2323.       }
  2324.       endpwent ();
  2325.   #endif
  2326. ! #ifdef    NDBM
  2327. !     if (access ("/etc/shadow.pag", 0) == 0 && ! sp_dbm_update (&spent)) {
  2328. !         fprintf (stderr, "%s: error updating shadow passwd dbm entry\n",
  2329. !             Prog);
  2330. !         exit (1);
  2331.       }
  2332.       endspent ();
  2333.   #endif
  2334.   #ifdef    USE_SYSLOG
  2335.       syslog (LOG_INFO,
  2336. !         "new user: name=%s, uid=%d, gid=%d, home=%s, shell=%s\n",
  2337. !         user_name, user_id, user_gid, user_home, user_shell);
  2338.   #endif
  2339.       if (user_ngroups > 0)
  2340.           grp_update ();
  2341.   }
  2342. --- 1283,1324 ----
  2343.               Prog);
  2344.           exit (1);
  2345.       }
  2346. + #endif
  2347.   #if defined(DBM) || defined(NDBM)
  2348. !     if (access ("/etc/passwd.pag", 0) == 0) {
  2349. !         if (! pw_dbm_update (&pwent)) {
  2350. !             fprintf (stderr,
  2351. !                 "%s: error updating password dbm entry\n",
  2352. !                 Prog);
  2353. !             exit (1);
  2354. !         } else
  2355. !             pw_dbm_added = 1;
  2356.       }
  2357.       endpwent ();
  2358.   #endif
  2359. ! #if defined(SHADOWPWD) && defined(NDBM)
  2360. !     if (access ("/etc/shadow.pag", 0) == 0) {
  2361. !         if (! sp_dbm_update (&spent)) {
  2362. !             fprintf (stderr,
  2363. !                 "%s: error updating shadow passwd dbm entry\n",
  2364. !                 Prog);
  2365. !             fail (1);
  2366. !         } else
  2367. !             sp_dbm_added++;
  2368.       }
  2369.       endspent ();
  2370.   #endif
  2371.   #ifdef    USE_SYSLOG
  2372.       syslog (LOG_INFO,
  2373. !         "new user: name=%s, uid=%d, gid=%d, home=%s, shell=%s, auth=%s\n",
  2374. !         user_name, user_id, user_gid, user_home, user_shell,
  2375. !             Aflg ? user_auth + 1:"password");
  2376.   #endif
  2377. +     if (Aflg && pw_auth (user_auth + 1, pwent.pw_name, PW_ADD)) {
  2378. +         fprintf (stderr, "%s: error adding authentication method\n",
  2379. +             Prog);
  2380. +         fail (1);
  2381. +     }
  2382.       if (user_ngroups > 0)
  2383.           grp_update ();
  2384.   }
  2385. ***************
  2386. *** 1196,1209 ****
  2387.   create_home ()
  2388.   {
  2389.       if (access (user_home, 0)) {
  2390. !         if (mkdir (user_home, 0755)) {
  2391.               fprintf (stderr, "%s: cannot create directory %s\n",
  2392.                   Prog, user_home);
  2393. !             exit (1);
  2394.           }
  2395.           chown (user_home, user_id, user_gid);
  2396.           chmod (user_home, 0755);
  2397.       }
  2398.   }
  2399.   
  2400.   /*
  2401. --- 1334,1386 ----
  2402.   create_home ()
  2403.   {
  2404.       if (access (user_home, 0)) {
  2405. !         if (mkdir (user_home, 0)) {
  2406.               fprintf (stderr, "%s: cannot create directory %s\n",
  2407.                   Prog, user_home);
  2408. !             fail (1);
  2409.           }
  2410.           chown (user_home, user_id, user_gid);
  2411.           chmod (user_home, 0755);
  2412. +         home_added++;
  2413. +     }
  2414. + }
  2415. + /*
  2416. +  * fail - undo as much as possible
  2417. +  */
  2418. + fail (code)
  2419. + int    code;
  2420. + {
  2421. +     struct    passwd    pwent;
  2422. + #if defined(DBM) || defined(NDBM)
  2423. +     if (pw_dbm_added) {
  2424. +         pwent.pw_name = user_name;
  2425. +         pwent.pw_uid = user_id;
  2426. +         (void) pw_dbm_remove (&pwent);
  2427.       }
  2428. + #endif
  2429. + #ifdef    NDBM
  2430. +     if (gr_dbm_added)
  2431. +         fprintf (stderr, "%s: rebuild the group database\n", Prog);
  2432. + #ifdef    SHADOWPWD
  2433. +     if (sp_dbm_added)
  2434. +         (void) sp_dbm_remove (user_name);
  2435. + #endif
  2436. + #ifdef    SHADOWGRP
  2437. +     if (sg_dbm_added)
  2438. +         fprintf (stderr, "%s: rebuild the shadow group database\n",
  2439. +             Prog);
  2440. + #endif
  2441. + #endif    /* NDBM */
  2442. +     if (home_added)
  2443. +         rmdir (user_home);
  2444. + #ifdef    USE_SYSLOG
  2445. +     syslog (LOG_INFO, "failed adding user `%s', data deleted\n", user_name);
  2446. + #endif
  2447. +     exit (code);
  2448.   }
  2449.   
  2450.   /*
  2451. ***************
  2452. *** 1234,1240 ****
  2453. --- 1411,1419 ----
  2454.   
  2455.   #ifdef    NDBM
  2456.       pw_dbm_mode = O_RDWR;
  2457. + #ifdef    SHADOWPWD
  2458.       sp_dbm_mode = O_RDWR;
  2459. + #endif
  2460.       gr_dbm_mode = O_RDWR;
  2461.   #ifdef    SHADOWGRP
  2462.       sg_dbm_mode = O_RDWR;
  2463. ***************
  2464. *** 1277,1283 ****
  2465.   
  2466.       if (mflg) {
  2467.           create_home ();
  2468. !         copy_tree (def_template, user_home, user_id, user_gid);
  2469.       }
  2470.       close_files ();
  2471.       exit (0);
  2472. --- 1456,1464 ----
  2473.   
  2474.       if (mflg) {
  2475.           create_home ();
  2476. ! #if defined(DIR_XENIX) || defined(DIR_BSD) || defined(DIR_SYSV)
  2477. !         copy_tree (def_template, user_home, user_id, user_gid, -1, -1);
  2478. ! #endif
  2479.       }
  2480.       close_files ();
  2481.       exit (0);
  2482. -- 
  2483. John F. Haugh II                  [  TSAKC  ] !'s: ...!cs.utexas.edu!rpp386!jfh
  2484. Ma Bell: (512) 251-2151           [ DoF #17 ]        @'s: jfh@rpp386.cactus.org
  2485.  
  2486. exit 0 # Just in case...
  2487.