home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / misc / volume30 / shadow / patch05 next >
Encoding:
Text File  |  1992-07-06  |  41.6 KB  |  1,768 lines

  1. Newsgroups: comp.sources.misc
  2. From: jfh@rpp386.cactus.org (John F Haugh II)
  3. Subject:  v30i093:  shadow - Shadow Login/Password Suite, Patch05
  4. Message-ID: <1992Jun29.201256.24322@sparky.imd.sterling.com>
  5. X-Md4-Signature: 71e92577252e5edd5cfaaf4805d2f8bd
  6. Date: Mon, 29 Jun 1992 20:12:56 GMT
  7. Approved: kent@sparky.imd.sterling.com
  8.  
  9. Submitted-by: jfh@rpp386.cactus.org (John F Haugh II)
  10. Posting-number: Volume 30, Issue 93
  11. Archive-name: shadow/patch05
  12. Environment: UNIX
  13. Patch-To: shadow: Volume 26, Issue 54-64
  14.  
  15. Here is the latest patch for the Shadow Password Suite.  After applying
  16. this patch, your code will be at version 3.2.1.  This patch primarily
  17. adds a new command "sg", which functions similiarly to "su", except that
  18. it deals with groups.  It is intended to replace "newgrp", which is a 
  19. pain since it causes an exec of the command (being a shell builtin and
  20. so on ...).
  21.  
  22. You will have to have the code at 3.1.4 in order to apply this patch.  If
  23. you would prefer to stick with 3.1.4 and forego new features, please send
  24. me mail and I will see what can be arranged.  There will be bug-fix only
  25. patches for that level available on a very limited basis (read: they won't
  26. be posted to the net).
  27.  
  28. Changes -
  29.  
  30. Documented where crypt functions can be located.
  31. Fixed bug in sulogin for termios getting and setting.
  32. Added support for SYSLOG_SG_ENAB for sg command logging.
  33. Added code to actually perform sg command functionality.
  34. Added SYSLOG_SG_ENAB entry to login.defs.
  35. Fixed typo in groups manpage.
  36. Added documentation for sg command.
  37. Added Makefile rules for sg command.
  38. Fixed problem with open files.
  39. Fixed signal handling with dialup passwords.
  40. Fixed error message when changing dialup passwords.
  41. Added code to clean up lock files for dialup passwords.
  42. Added syslog support when changing user account information.
  43.  
  44. Future Directions -
  45.  
  46. I will be adding code to enable the administrator to select the
  47. authentication mechanism that will be used.  This will enable you to select
  48. one time pads, or retinal scanners, or some other system defined means of
  49. authenticating users.  I will also be adding code to set a limit on the
  50. total number of user, or the number of times an individual user is able to
  51. login.  Plus, the user{add,del,mod} commands will begin supporting the
  52. failure counting and login time features.
  53. -- 
  54. Prereq: "3.1.4"
  55. Index: patchlevel.h
  56. *** Standard Input    Wed Dec 31 18:00:00 1969
  57. --- patchlevel.h    Tue Jun  9 08:31:13 1992
  58. ***************
  59. *** 17,24 ****
  60.    *        Changes for SunOS 4.1.1
  61.    *    02/08/92    3.1.4    patchlevel 17
  62.    *        Changes for SVR4, plus bug fixes
  63.    */
  64.   
  65.   #define    RELEASE        3
  66. ! #define    PATCHLEVEL    17
  67. ! #define    VERSION        "3.1.4"
  68. --- 17,26 ----
  69.    *        Changes for SunOS 4.1.1
  70.    *    02/08/92    3.1.4    patchlevel 17
  71.    *        Changes for SVR4, plus bug fixes
  72. +  *    04/03/92    3.2.1    patchlevel 18
  73. +  *        Minor bug fixes, new baseline
  74.    */
  75.   
  76.   #define    RELEASE        3
  77. ! #define    PATCHLEVEL    18
  78. ! #define    VERSION        "3.2.1"
  79. Index: README
  80. *** Standard Input    Wed Dec 31 18:00:00 1969
  81. --- README    Tue Jun  9 08:31:33 1992
  82. ***************
  83. *** 1,7 ****
  84. ! [    @(#)README    3.8.1.1    20:36:10    3/7/92    ]
  85.   
  86.   This is the explanatory document for John F. Haugh II's login replacement,
  87. ! release 3.  This document was last updated 3/7/92.
  88.   
  89.   This software is copyright 1988, 1989, 1990, 1991, 1992, John F. Haugh II.
  90.   All rights reserved.  Use, duplication and disclosure is permitted according
  91. --- 1,7 ----
  92. ! [    @(#)README    3.8.1.2    14:48:13    4/28/92    ]
  93.   
  94.   This is the explanatory document for John F. Haugh II's login replacement,
  95. ! release 3.  This document was last updated 4/28/92.
  96.   
  97.   This software is copyright 1988, 1989, 1990, 1991, 1992, John F. Haugh II.
  98.   All rights reserved.  Use, duplication and disclosure is permitted according
  99. ***************
  100. *** 77,83 ****
  101.   fields or #define's until they match.  The same is true for "shadow.h",
  102.   if you system provides one.  You may want to replace large portions of
  103.   that file (or the entire file) with your system version.  It is provided
  104. ! for those systems which do NOT provide /usr/include/shadow.h.
  105.   
  106.   Login Defaults File -
  107.       This option selects the name of the file to read for the
  108. --- 77,87 ----
  109.   fields or #define's until they match.  The same is true for "shadow.h",
  110.   if you system provides one.  You may want to replace large portions of
  111.   that file (or the entire file) with your system version.  It is provided
  112. ! for those systems which do NOT provide /usr/include/shadow.h.  If you
  113. ! do not have a the crypt() function in your library (perhaps because you
  114. ! are located outside the United States), you may wish to look into the
  115. ! UFC-crypt package which was posted to comp.sources.misc in volume 23,
  116. ! issues 97 and 98.
  117.   
  118.   Login Defaults File -
  119.       This option selects the name of the file to read for the
  120. Index: sulogin.c
  121. *** Standard Input    Wed Dec 31 18:00:00 1969
  122. --- sulogin.c    Tue Jun  9 08:31:51 1992
  123. ***************
  124. *** 48,54 ****
  125.   #endif
  126.   
  127.   #ifndef    lint
  128. ! static    char    sccsid[] = "@(#)sulogin.c    3.10    23:56:58    3/7/92";
  129.   #endif
  130.   
  131.   char    name[BUFSIZ];
  132. --- 48,54 ----
  133.   #endif
  134.   
  135.   #ifndef    lint
  136. ! static    char    sccsid[] = "@(#)sulogin.c    3.11    14:49:03    4/28/92";
  137.   #endif
  138.   
  139.   char    name[BUFSIZ];
  140. ***************
  141. *** 116,122 ****
  142.       ioctl (0, TIOCSETN, &termio);
  143.   #endif
  144.   #ifdef    USE_TERMIO
  145. !     ioctl (0, TCSETA, &termio);
  146.       termio.c_iflag |= (ICRNL|IXON);
  147.       termio.c_oflag |= (OPOST|ONLCR);
  148.       termio.c_cflag |= (CREAD);
  149. --- 116,122 ----
  150.       ioctl (0, TIOCSETN, &termio);
  151.   #endif
  152.   #ifdef    USE_TERMIO
  153. !     ioctl (0, TCGETA, &termio);
  154.       termio.c_iflag |= (ICRNL|IXON);
  155.       termio.c_oflag |= (OPOST|ONLCR);
  156.       termio.c_cflag |= (CREAD);
  157. Index: getdef.c
  158. *** Standard Input    Wed Dec 31 18:00:00 1969
  159. --- getdef.c    Tue Jun  9 08:32:08 1992
  160. ***************
  161. *** 10,16 ****
  162.    */
  163.   
  164.   #ifndef lint
  165. ! static    char    sccsid[] = "@(#)getdef.c    3.5    21:21:14    3/7/92";
  166.   #endif
  167.   
  168.   #include <stdio.h>
  169. --- 10,16 ----
  170.    */
  171.   
  172.   #ifndef lint
  173. ! static    char    sccsid[] = "@(#)getdef.c    3.6    14:49:39    4/28/92";
  174.   #endif
  175.   
  176.   #include <stdio.h>
  177. ***************
  178. *** 74,79 ****
  179. --- 74,80 ----
  180.       { "QUOTAS_ENAB",        NULL },
  181.       { "SULOG_FILE",            NULL },
  182.       { "SU_NAME",            NULL },
  183. +     { "SYSLOG_SG_ENAB",        NULL },
  184.       { "SYSLOG_SU_ENAB",        NULL },
  185.       { "TTYGROUP",            NULL },
  186.       { "TTYPERM",            NULL },
  187. Index: newgrp.c
  188. *** Standard Input    Wed Dec 31 18:00:00 1969
  189. --- newgrp.c    Tue Jun  9 08:32:26 1992
  190. ***************
  191. *** 29,35 ****
  192.   #endif
  193.   
  194.   #ifndef    lint
  195. ! static    char    sccsid[] = "@(#)newgrp.c    3.9    20:37:26    3/7/92";
  196.   #endif
  197.   
  198.   #ifdef    NGROUPS
  199. --- 29,35 ----
  200.   #endif
  201.   
  202.   #ifndef    lint
  203. ! static    char    sccsid[] = "@(#)newgrp.c    3.10    14:50:28    4/28/92";
  204.   #endif
  205.   
  206.   #ifdef    NGROUPS
  207. ***************
  208. *** 53,58 ****
  209. --- 53,69 ----
  210.   struct    sgrp    *sgrp;
  211.   struct    sgrp    *getsgnam();
  212.   #endif
  213. + #ifdef    USE_SYSLOG
  214. + #include <syslog.h>
  215. + /*VARARGS*/ int syslog();
  216. + #ifndef    LOG_WARN
  217. + #define    LOG_WARN LOG_WARNING
  218. + #endif    /* !LOG_WARN */
  219. + #endif    /* USE_SYSLOG */
  220.   struct    group    *grp;
  221.   struct    group    *getgrgid();
  222.   struct    group    *getgrnam();
  223. ***************
  224. *** 67,72 ****
  225. --- 78,84 ----
  226.   char    *name;
  227.   char    *group;
  228.   int    gid;
  229. + int    cflag;
  230.   
  231.   char    *Prog;
  232.   char    prog[BUFSIZ];
  233. ***************
  234. *** 89,95 ****
  235.   
  236.   usage ()
  237.   {
  238. !     fprintf (stderr, "usage: newgrp [ - ] [ group ]\n");
  239.   }
  240.   
  241.   /*
  242. --- 101,110 ----
  243.   
  244.   usage ()
  245.   {
  246. !     if (strcmp (Prog, "sg") != 0)
  247. !         fprintf (stderr, "usage: newgrp [ - ] [ group ]\n");
  248. !     else
  249. !         fprintf (stderr, "usage: sg group [ command ]\n");
  250.   }
  251.   
  252.   /*
  253. ***************
  254. *** 105,110 ****
  255. --- 120,126 ----
  256.       int    needspasswd = 0;
  257.       int    i;
  258.       char    *cp;
  259. +     char    *command;
  260.   
  261.       /*
  262.        * save my name for error messages and save my real gid incase
  263. ***************
  264. *** 114,156 ****
  265.        * command line argument.
  266.        */
  267.   
  268. !     Prog = argv[0];
  269. !     gid = getgid ();
  270. !     argc--; argv++;
  271. !     /*
  272. !      * let me parse the command line first.  the only recognized
  273. !      * option is a "-", which indicates that the shell is to perform
  274. !      * the same initialization it does at login time.  the next
  275. !      * argument, if present, must be the new group name.  any
  276. !      * remaining arguments will be used to execute a command for
  277. !      * the user as the named group.  if the group name isn't present
  278. !      * i just use the login group id of this user.
  279. !      */
  280. !     if (argc > 0 && argv[0][0] == '-') {
  281. !         if (strcmp (argv[0], "-") == 0) {
  282. !             initflag = 1;
  283. !             argc--; argv++;
  284. !         } else {
  285. !             usage ();
  286. !             goto failure;
  287. !         }
  288. !     }
  289. ! #ifdef    NGROUPS
  290. !     /*
  291. !      * get the current users groupset.  the new group will be
  292. !      * added to the concurrent groupset if there is room, otherwise
  293. !      * you get a nasty message but at least your real and effective
  294. !      * group id's are set.
  295. !      */
  296.   
  297. !     ngroups = getgroups (groups);
  298.   #endif
  299.   
  300.       /*
  301. !      * now i get to determine my current name.  i do this to validate
  302.        * my access to the requested group.  the validation works like
  303.        * this -
  304.        *    1) get the name associated with my current user id
  305. --- 130,149 ----
  306.        * command line argument.
  307.        */
  308.   
  309. !     if (Prog = strrchr (argv[0], '/'))
  310. !         Prog++;
  311. !     else
  312. !         Prog = argv[0];
  313.   
  314. ! #ifdef    USE_SYSLOG
  315. !     openlog (Prog, LOG_PID|LOG_CONS|LOG_NOWAIT, LOG_AUTH);
  316.   #endif
  317.   
  318. +     gid = getgid ();
  319. +     argc--; argv++;
  320.       /*
  321. !      * here i get to determine my current name.  i do this to validate
  322.        * my access to the requested group.  the validation works like
  323.        * this -
  324.        *    1) get the name associated with my current user id
  325. ***************
  326. *** 159,165 ****
  327.        *    4) if they don't match, my name is the name in the
  328.        *       password file.
  329.        *
  330. !      * this isn't perfect, but it works more often then not.
  331.        */
  332.   
  333.       pwd = getpwuid (getuid ());
  334. --- 152,160 ----
  335.        *    4) if they don't match, my name is the name in the
  336.        *       password file.
  337.        *
  338. !      * this isn't perfect, but it works more often then not.  i have
  339. !      * to do this here so i can get the login name to find the
  340. !      * login group.
  341.        */
  342.   
  343.       pwd = getpwuid (getuid ());
  344. ***************
  345. *** 169,262 ****
  346.   
  347.       if (! (pwd = getpwnam (name))) {
  348.           fprintf (stderr, "unknown user: %s\n", name);
  349. !         exit (1);
  350. !     }
  351.       /*
  352. !      * now we determine the name of the new group which she wishes
  353. !      * to become a member of.  the password file entry for her
  354. !      * current user id has been gotten.  if there is no optional
  355. !      * group argument she will have her real and effective group id
  356. !      * set to the value from her password file entry.  otherwise
  357. !      * we validate her access to the specified group.
  358.        */
  359.   
  360. !     if (argv[0] != (char *) 0) {
  361.   
  362. !         /*
  363. !          * start by getting the entry for the requested group.
  364.            */
  365.   
  366. !         if (! (grp = getgrnam (group = argv[0]))) {
  367. !             fprintf (stderr, "unknown group: %s\n", group);
  368. !             goto failure;
  369. !         }
  370. !         argc--; argv++;
  371. ! #ifdef    SHADOWGRP
  372. !         sgrp = getsgnam (group);
  373.   #endif
  374.   
  375.           /*
  376. !          * see if she is a member of this group.
  377.            */
  378.   
  379. !         for (i = 0;grp->gr_mem[i];i++)
  380. !             if (strcmp (name, grp->gr_mem[i]) == 0)
  381. !                 break;
  382.   
  383. !         /*
  384. !          * if she isn't a member, she needs to provide the
  385. !          * group password.  if there is no group password, she
  386. !          * will be denied access anyway.
  387. !          */
  388.   
  389. !         if (grp->gr_mem[i] == (char *) 0)
  390. !             needspasswd = 1;
  391.   
  392.   #ifdef    SHADOWGRP
  393. !         if (sgrp) {
  394.   
  395. !             /*
  396. !              * Do the tests again with the shadow group entry.
  397. !              */
  398.   
  399. !             for (i = 0;sgrp->sg_mem[i];i++)
  400. !                 if (strcmp (name, sgrp->sg_mem[i]) == 0)
  401. !                     break;
  402.   
  403. !             needspasswd = sgrp->sg_mem[i] == 0;
  404. !         }
  405.   #endif
  406.   #ifdef    SHADOWPWD
  407.   
  408. !         /*
  409. !          * if she does not have either a shadowed password,
  410. !          * or a regular password, and the group has a password,
  411. !          * she needs to give the group password.
  412. !          */
  413.   
  414. !         if (spwd = getspnam (name)) {
  415. !             if (spwd->sp_pwdp[0] == '\0' && grp->gr_passwd[0])
  416. !                 needspasswd = 1;
  417. ! #ifdef    SHADOWGRP
  418. !             if (spwd->sp_pwdp[0] == '\0' && sgrp != 0)
  419. !                 needspasswd = sgrp->sg_passwd[0] != '\0';
  420. ! #endif
  421. !         } else {
  422. !             if (pwd->pw_passwd[0] == '\0' && grp->gr_passwd[0])
  423. !                 needspasswd = 1;
  424.   #ifdef    SHADOWGRP
  425. !             if (pwd->pw_passwd[0] == '\0' && sgrp != 0)
  426. !                 needspasswd = sgrp->sg_passwd[0] != '\0';
  427.   #endif
  428. !         }
  429. ! #else
  430. !         /*
  431. !          * if she does not have a regular password she will have
  432. !          * to give the group password, if one exists.
  433. !          */
  434.           if (pwd->pw_passwd[0] == '\0' && grp->gr_passwd[0])
  435.               needspasswd = 1;
  436.   #ifdef    SHADOWGRP
  437. --- 164,325 ----
  438.   
  439.       if (! (pwd = getpwnam (name))) {
  440.           fprintf (stderr, "unknown user: %s\n", name);
  441. ! #ifdef    USE_SYSLOG
  442. !         syslog (LOG_WARN, "unknown user `%s', uid `%d'\n",
  443. !             name, getuid ());
  444. !         closelog ();
  445. ! #endif
  446. !         goto failure;
  447. !     }
  448.       /*
  449. !      * Parse the command line.  There are two accepted flags.  The
  450. !      * first is "-", which for newgrp means to re-create the entire
  451. !      * environment as though a login had been performed, and "-c",
  452. !      * which for sg causes a command string to be executed.
  453. !      *
  454. !      * The next argument, if present, must be the new group name.
  455. !      * Any remaining remaining arguments will be used to execute a
  456. !      * command as the named group.  If the group name isn't present,
  457. !      * I just use the login group ID of the current user.
  458. !      *
  459. !      * The valid syntax are
  460. !      *    newgrp [ - ] [ groupid ]
  461. !      *    sg [ - ]
  462. !      *    sg [ - ] groupid [ command ]
  463.        */
  464.   
  465. !     if (argc > 0 && argv[0][0] == '-' && argv[0][1] == '\0') {
  466. !         argc--; argv++;
  467. !         initflag = 1;
  468. !     }
  469. !     if (strcmp (Prog, "newgrp") != 0) {
  470.   
  471. !         /* 
  472. !          * Do the command line for everything that is
  473. !          * not "newgrp".
  474.            */
  475.   
  476. !         if (argc > 0 && argv[0][0] != '-') {
  477. !             group = argv[0];
  478. !             argc--; argv++;
  479. !         } else {
  480. !             usage ();
  481. ! #ifdef    USE_SYSLOG
  482. !             closelog ();
  483.   #endif
  484. +             exit (1);
  485. +         }
  486. +         if (argc > 0) {
  487. +             command = argv[1];
  488. +             cflag++;
  489. +         }
  490. +     } else {
  491.   
  492.           /*
  493. !          * Do the command line for "newgrp".  It's just
  494. !          * making sure there aren't any flags and getting
  495. !          * the new group name.
  496.            */
  497.   
  498. !         if (argc > 0 && argv[0][0] == '-') {
  499. !             usage ();
  500. !             goto failure;
  501. !         } else if (argv[0] != (char *) 0) {
  502. !             group = argv[0];
  503. !         } else {
  504.   
  505. !             /*
  506. !              * get the group file entry for her login group id.
  507. !              * the entry must exist, simply to be annoying.
  508. !              */
  509.   
  510. !             if (! (grp = getgrgid (pwd->pw_gid))) {
  511. !                 fprintf (stderr, "unknown gid: %d\n",
  512. !                     pwd->pw_gid);
  513. ! #ifdef    USE_SYSLOG
  514. !                 syslog (LOG_CRIT, "unknown gid: %d\n",
  515. !                     pwd->pw_gid);
  516. ! #endif
  517. !                 goto failure;
  518. !             }
  519. !         }
  520. !     }
  521. ! #ifdef    NGROUPS
  522. !     /*
  523. !      * get the current users groupset.  the new group will be
  524. !      * added to the concurrent groupset if there is room, otherwise
  525. !      * you get a nasty message but at least your real and effective
  526. !      * group id's are set.
  527. !      */
  528. !     ngroups = getgroups (groups);
  529. ! #endif
  530. !     /*
  531. !      * now we put her in the new group.  the password file entry for
  532. !      * her current user id has been gotten.  if there was no optional
  533. !      * group argument she will have her real and effective group id
  534. !      * set to the value from her password file entry.  otherwise
  535. !      * we validate her access to the specified group.
  536. !      */
  537.   
  538. +     if (! (grp = getgrnam (group))) {
  539. +         fprintf (stderr, "unknown group: %s\n", group);
  540. +         goto failure;
  541. +     }
  542.   #ifdef    SHADOWGRP
  543. !     sgrp = getsgnam (group);
  544. ! #endif
  545. !     /*
  546. !      * see if she is a member of this group.
  547. !      */
  548.   
  549. !     for (i = 0;grp->gr_mem[i];i++)
  550. !         if (strcmp (name, grp->gr_mem[i]) == 0)
  551. !             break;
  552.   
  553. !     /*
  554. !      * if she isn't a member, she needs to provide the
  555. !      * group password.  if there is no group password, she
  556. !      * will be denied access anyway.
  557. !      */
  558.   
  559. !     if (grp->gr_mem[i] == (char *) 0)
  560. !         needspasswd = 1;
  561. ! #ifdef    SHADOWGRP
  562. !     if (sgrp) {
  563. !         /*
  564. !          * Do the tests again with the shadow group entry.
  565. !          */
  566. !         for (i = 0;sgrp->sg_mem[i];i++)
  567. !             if (strcmp (name, sgrp->sg_mem[i]) == 0)
  568. !                 break;
  569. !         needspasswd = sgrp->sg_mem[i] == (char *) 0;
  570. !     }
  571.   #endif
  572.   #ifdef    SHADOWPWD
  573.   
  574. !     /*
  575. !      * if she does not have either a shadowed password,
  576. !      * or a regular password, and the group has a password,
  577. !      * she needs to give the group password.
  578. !      */
  579.   
  580. !     if (spwd = getspnam (name)) {
  581. !         if (spwd->sp_pwdp[0] == '\0' && grp->gr_passwd[0])
  582. !             needspasswd = 1;
  583.   #ifdef    SHADOWGRP
  584. !         if (spwd->sp_pwdp[0] == '\0' && sgrp != 0)
  585. !             needspasswd = sgrp->sg_passwd[0] != '\0';
  586.   #endif
  587. !     } else {
  588.           if (pwd->pw_passwd[0] == '\0' && grp->gr_passwd[0])
  589.               needspasswd = 1;
  590.   #ifdef    SHADOWGRP
  591. ***************
  592. *** 263,281 ****
  593.           if (pwd->pw_passwd[0] == '\0' && sgrp != 0)
  594.               needspasswd = sgrp->sg_passwd[0] != '\0';
  595.   #endif
  596. ! #endif
  597. !     } else {
  598.   
  599. !         /*
  600. !          * get the group file entry for her login group id.
  601. !          * the entry must exist, simply to be annoying.
  602. !          */
  603.   
  604. !         if (! (grp = getgrgid (pwd->pw_gid))) {
  605. !             fprintf (stderr, "unknown gid: %d\n", pwd->pw_gid);
  606. !             goto failure;
  607. !         }
  608. !     }
  609.   
  610.       /*
  611.        * now i see about letting her into the group she requested.
  612. --- 326,346 ----
  613.           if (pwd->pw_passwd[0] == '\0' && sgrp != 0)
  614.               needspasswd = sgrp->sg_passwd[0] != '\0';
  615.   #endif
  616. !     }
  617. ! #else
  618.   
  619. !     /*
  620. !      * if she does not have a regular password she will have
  621. !      * to give the group password, if one exists.
  622. !      */
  623.   
  624. !     if (pwd->pw_passwd[0] == '\0' && grp->gr_passwd[0])
  625. !         needspasswd = 1;
  626. ! #ifdef    SHADOWGRP
  627. !     if (pwd->pw_passwd[0] == '\0' && sgrp != 0)
  628. !         needspasswd = sgrp->sg_passwd[0] != '\0';
  629. ! #endif
  630. ! #endif
  631.   
  632.       /*
  633.        * now i see about letting her into the group she requested.
  634. ***************
  635. *** 331,336 ****
  636. --- 396,405 ----
  637.   
  638.           if (strcmp (cpasswd, encrypted) != 0) {
  639.               fputs ("Sorry\n", stderr);
  640. + #ifdef    USE_SYSLOG
  641. +         syslog (LOG_INFO, "Invalid password for `%s' from `%s'\n",
  642. +             group, name);
  643. + #endif
  644.               goto failure;
  645.           }
  646.       }
  647. ***************
  648. *** 341,346 ****
  649. --- 410,419 ----
  650.        * groupset.
  651.        */
  652.   
  653. + #ifdef    USE_SYSLOG
  654. +     if (getdef_bool ("SYSLOG_SU_ENAB"))
  655. +         syslog (LOG_INFO, "user `%s' switched to group `%s'\n", name, group);
  656. + #endif
  657.       gid = grp->gr_gid;
  658.   #ifdef    NGROUPS
  659.   
  660. ***************
  661. *** 368,385 ****
  662.       }
  663.   #endif
  664.   
  665. !     /*
  666. !      * this is where all failures land.  the group id will not
  667. !      * have been set, so the setgid() below will set me to the
  668. !      * original group id i had when i was invoked.
  669. !      */
  670.   
  671. - failure:
  672.       /*
  673.        * i set her group id either to the value she requested, or
  674. !      * to the original value.  i have to go back to the original
  675. !      * because she no longer has a shell running.
  676.        */
  677.   
  678.       if (setgid (gid))
  679. --- 441,451 ----
  680.       }
  681.   #endif
  682.   
  683. ! okay:
  684.   
  685.       /*
  686.        * i set her group id either to the value she requested, or
  687. !      * to the original value if the newgrp failed.
  688.        */
  689.   
  690.       if (setgid (gid))
  691. ***************
  692. *** 389,397 ****
  693.           perror ("setuid");
  694.   
  695.       /*
  696. !      * i have to get the pathname of her login shell.  as a favor
  697.        * i'll try her environment for a $SHELL value first, and
  698. !      * then try the password file entry.
  699.        */
  700.   
  701.       if (! initflag && (cp = getenv ("SHELL")))
  702. --- 455,480 ----
  703.           perror ("setuid");
  704.   
  705.       /*
  706. !      * see if the "-c" flag was used.  if it was, i just create a
  707. !      * shell command for her using the argument that followed the
  708. !      * "-c" flag.
  709. !      */
  710. !     if (cflag) {
  711. !         execl ("/bin/sh", "sh", "-c", command, (char *) 0);
  712. !         perror ("/bin/sh");
  713. ! #ifdef    USE_SYSLOG
  714. !         closelog ();
  715. ! #endif
  716. !         exit (255);
  717. !     }
  718. !     /*
  719. !      * i have to get the pathname of her login shell.  as a favor,
  720.        * i'll try her environment for a $SHELL value first, and
  721. !      * then try the password file entry.  obviously this shouldn't
  722. !      * be in the restricted command directory since it could be
  723. !      * used to leave the restricted environment.
  724.        */
  725.   
  726.       if (! initflag && (cp = getenv ("SHELL")))
  727. ***************
  728. *** 440,446 ****
  729.           while (*envp) {
  730.               if (strncmp (*envp, "PATH=", 5) == 0 ||
  731.                       strncmp (*envp, "HOME=", 5) == 0 ||
  732. !                     strncmp (*envp, "SHELL=", 6) == 0)
  733.                   addenv (*envp);
  734.   
  735.               envp++;
  736. --- 523,530 ----
  737.           while (*envp) {
  738.               if (strncmp (*envp, "PATH=", 5) == 0 ||
  739.                       strncmp (*envp, "HOME=", 5) == 0 ||
  740. !                     strncmp (*envp, "SHELL=", 6) == 0 ||
  741. !                     strncmp (*envp, "TERM=", 5) == 0)
  742.                   addenv (*envp);
  743.   
  744.               envp++;
  745. ***************
  746. *** 458,461 ****
  747. --- 542,572 ----
  748.   
  749.       shell (prog, base);
  750.       /*NOTREACHED*/
  751. + failure:
  752. +     /*
  753. +      * this is where all failures land.  the group id will not
  754. +      * have been set, so the setgid() below will set me to the
  755. +      * original group id i had when i was invoked.
  756. +      */
  757. +     /*
  758. +      * only newgrp needs to re-exec the user's shell.  that is
  759. +      * because the shell doesn't recognize "sg", so it doesn't
  760. +      * "exec" this command.
  761. +      */
  762. +     if (strcmp (Prog, "newgrp") != 0) {
  763. + #ifdef    USE_SYSLOG
  764. +         closelog ();
  765. + #endif
  766. +         exit (1);
  767. +     }
  768. +     
  769. +     /*
  770. +      * The GID is still set to the old value, so now I can
  771. +      * give the user back her shell.
  772. +      */
  773. +     goto okay;
  774.   }
  775. Index: login.defs
  776. *** Standard Input    Wed Dec 31 18:00:00 1969
  777. --- login.defs    Tue Jun  9 08:32:52 1992
  778. ***************
  779. *** 1,7 ****
  780.   #
  781.   # /etc/login.defs - Configuration control definitions for the login package.
  782.   #
  783. ! #    @(#)login.defs    3.4    21:21:25    3/7/92
  784.   #
  785.   # Three items must be defined:  MAIL_DIR, ENV_SUPATH, and ENV_PATH.
  786.   # If unspecified, some arbitrary (and possibly incorrect) value will
  787. --- 1,7 ----
  788.   #
  789.   # /etc/login.defs - Configuration control definitions for the login package.
  790.   #
  791. ! #    @(#)login.defs    3.5    14:51:26    4/28/92
  792.   #
  793.   # Three items must be defined:  MAIL_DIR, ENV_SUPATH, and ENV_PATH.
  794.   # If unspecified, some arbitrary (and possibly incorrect) value will
  795. ***************
  796. *** 53,60 ****
  797. --- 53,62 ----
  798.   
  799.   #
  800.   # Enable "syslog" logging of su activity - in addition to sulog file logging.
  801. + # SYSLOG_SG_ENAB does the same for newgrp and sg.
  802.   #
  803.   SYSLOG_SU_ENAB        no
  804. + SYSLOG_SG_ENAB        no
  805.   
  806.   #
  807.   # If defined, either full pathname of a file containing device names or
  808. Index: groups.1
  809. *** Standard Input    Wed Dec 31 18:00:00 1969
  810. --- groups.1    Tue Jun  9 08:33:12 1992
  811. ***************
  812. *** 1,4 ****
  813. ! .\" Copyright 1991, John F. Haugh II
  814.   .\" All rights reserved.
  815.   .\"
  816.   .\" Permission is granted to copy and create derivative works for any
  817. --- 1,4 ----
  818. ! .\" Copyright 1991, 1992, John F. Haugh II
  819.   .\" All rights reserved.
  820.   .\"
  821.   .\" Permission is granted to copy and create derivative works for any
  822. ***************
  823. *** 7,15 ****
  824.   .\" and conspicuously displayed on all copies of object code or
  825.   .\" distribution media.
  826.   .\"
  827. ! .\"    @(#)groups.1    3.1    08:50:54    11/3/91
  828.   .\"
  829. ! .TH ID 1
  830.   .SH NAME
  831.   groups \- Display current group ID names
  832.   .SH SYNOPSIS
  833. --- 7,15 ----
  834.   .\" and conspicuously displayed on all copies of object code or
  835.   .\" distribution media.
  836.   .\"
  837. ! .\"    @(#)groups.1    3.2    14:52:10    4/28/92
  838.   .\"
  839. ! .TH GROUPS 1
  840.   .SH NAME
  841.   groups \- Display current group ID names
  842.   .SH SYNOPSIS
  843. ***************
  844. *** 28,35 ****
  845.   .SH Note
  846.   Systems which do not support concurrent group sets will have the information
  847.   from \fB/etc/group\fR reported.
  848. ! The user must use \fInewgrp\fR to change their current real and effective
  849. ! group ID.
  850.   .SH Files
  851.   /etc/group \- group information
  852.   .SH See Also
  853. --- 28,35 ----
  854.   .SH Note
  855.   Systems which do not support concurrent group sets will have the information
  856.   from \fB/etc/group\fR reported.
  857. ! The user must use \fInewgrp\fR or \fIsg\fR to change their current real and
  858. ! effective group ID.
  859.   .SH Files
  860.   /etc/group \- group information
  861.   .SH See Also
  862. Index: newgrp.1
  863. *** Standard Input    Wed Dec 31 18:00:00 1969
  864. --- newgrp.1    Tue Jun  9 08:33:29 1992
  865. ***************
  866. *** 7,20 ****
  867.   .\" and conspicuously displayed on all copies of object code or
  868.   .\" distribution media.
  869.   .\"
  870. ! .\"    @(#)newgrp.1    3.1    07:47:52    7/13/91
  871.   .\"
  872.   .TH NEWGRP 1
  873.   .SH NAME
  874.   newgrp \- Change group ID
  875.   .SH SYNOPSIS
  876.   .B newgrp
  877.   [ - ] [ \fIgroup\fR ]
  878.   .SH DESCRIPTION
  879.   .I newgrp
  880.   is used to change the current group ID during a login session.
  881. --- 7,25 ----
  882.   .\" and conspicuously displayed on all copies of object code or
  883.   .\" distribution media.
  884.   .\"
  885. ! .\"    @(#)newgrp.1    3.2    14:52:37    4/28/92
  886.   .\"
  887.   .TH NEWGRP 1
  888.   .SH NAME
  889.   newgrp \- Change group ID
  890. + .br
  891. + sg \- Execute command as different group ID
  892.   .SH SYNOPSIS
  893.   .B newgrp
  894.   [ - ] [ \fIgroup\fR ]
  895. + .br
  896. + .B sg
  897. + [ - ] [ \fIgroup\fR [ \fB-c\fR \fIcommand\fR ] ]
  898.   .SH DESCRIPTION
  899.   .I newgrp
  900.   is used to change the current group ID during a login session.
  901. ***************
  902. *** 32,37 ****
  903. --- 37,52 ----
  904.   member and the group has a password.
  905.   The user will be denied access if the group password is empty
  906.   and the user is not listed as a member.
  907. + .PP
  908. + The
  909. + .I sg
  910. + command works similiar to \fInewgrp\fR but does not replace the
  911. + user's shell, so upon exit from a \fIsg\fR command, you are
  912. + returned to your previous group ID.
  913. + .I sg
  914. + also accepts a command.
  915. + The command will be executed with the Bourne shell and must be
  916. + enclosed in quotes.
  917.   .SH CAVEATS
  918.   .PP
  919.   This version of \fInewgrp\fR has many compilation options,
  920. Index: Makefile
  921. *** Standard Input    Wed Dec 31 18:00:00 1969
  922. --- Makefile    Tue Jun  9 08:33:50 1992
  923. ***************
  924. *** 8,16 ****
  925.   # and conspicuously displayed on all copies of object code or
  926.   # distribution media.
  927.   #
  928. ! #    @(#)Makefile    3.25.1.9    10:18:08  - Shadow password system
  929.   #
  930. ! #    @(#)Makefile    3.25.1.9    10:18:08    3/27/92
  931.   #
  932.   SHELL = /bin/sh
  933.   
  934. --- 8,16 ----
  935.   # and conspicuously displayed on all copies of object code or
  936.   # distribution media.
  937.   #
  938. ! #    @(#)Makefile    3.25.1.10    14:47:00  - Shadow password system
  939.   #
  940. ! #    @(#)Makefile    3.25.1.10    14:47:00    4/28/92
  941.   #
  942.   SHELL = /bin/sh
  943.   
  944. ***************
  945. *** 218,224 ****
  946.   DOCS2 = $(MAN_5) $(MAN_8)
  947.   DOCS = $(DOCS1) $(DOCS2)
  948.   
  949. ! BINS = su login pwconv pwunconv passwd sulogin faillog newgrp gpasswd \
  950.       mkpasswd chfn chsh chage chpasswd newusers dpasswd id useradd \
  951.       userdel usermod groupadd groupdel groupmod $(SCOLOGIN) logoutd \
  952.       groups
  953. --- 218,224 ----
  954.   DOCS2 = $(MAN_5) $(MAN_8)
  955.   DOCS = $(DOCS1) $(DOCS2)
  956.   
  957. ! BINS = su login pwconv pwunconv passwd sulogin faillog newgrp sg gpasswd \
  958.       mkpasswd chfn chsh chage chpasswd newusers dpasswd id useradd \
  959.       userdel usermod groupadd groupdel groupmod $(SCOLOGIN) logoutd \
  960.       groups
  961. ***************
  962. *** 262,267 ****
  963. --- 262,269 ----
  964.       cp mkpasswd pwconv pwunconv sulogin chpasswd newusers \
  965.           useradd userdel usermod groupadd groupdel groupmod logoutd /etc
  966.       cp su passwd gpasswd dpasswd faillog newgrp chfn chsh chage id /bin
  967. +     rm -f /bin/sg
  968. +     ln /bin/newgrp /bin/sg
  969.       cp dialup.h shadow.h pwd.h $(DEST_INCLUDE_DIR)
  970.       chown $(RUID) $(LOGINDIR)/login /etc/pwconv /etc/pwunconv /etc/sulogin \
  971.           /bin/su /bin/passwd /bin/gpasswd /bin/newgrp /etc/mkpasswd \
  972. ***************
  973. *** 393,398 ****
  974. --- 395,406 ----
  975.   
  976.   newgrp.lint: $(NGSRCS)
  977.       $(LINT) $(LINTFLAGS) $(NGSRCS) > newgrp.lint
  978. + sg:    newgrp
  979. +     ln newgrp sg
  980. + sg.lint: newgrp.lint
  981. +     ln newgrp.lint sg.lint
  982.   
  983.   chfn:    $(CHFNOBJS) libshadow.a
  984.       $(CC) -o chfn $(LDFLAGS) $(CHFNOBJS) libshadow.a $(LIBS)
  985. Index: smain.c
  986. *** Standard Input    Wed Dec 31 18:00:00 1969
  987. --- smain.c    Tue Jun  9 08:34:11 1992
  988. ***************
  989. *** 13,19 ****
  990.   #include <stdio.h>
  991.   
  992.   #ifndef    lint
  993. ! static    char    sccsid[] = "@(#)smain.c    3.11    21:21:19    3/7/92";
  994.   #endif
  995.   
  996.   /*
  997. --- 13,19 ----
  998.   #include <stdio.h>
  999.   
  1000.   #ifndef    lint
  1001. ! static    char    sccsid[] = "@(#)smain.c    3.12    15:26:53    4/28/92";
  1002.   #endif
  1003.   
  1004.   /*
  1005. ***************
  1006. *** 411,416 ****
  1007. --- 411,418 ----
  1008.       }
  1009.   
  1010.       sulog (1);            /* save SU information */
  1011. +     endpwent ();
  1012. +     endspent ();
  1013.   #ifdef    USE_SYSLOG
  1014.       if ( getdef_bool("SYSLOG_SU_ENAB") )
  1015.           syslog (LOG_INFO, "+ %s %s-%s\n", tty ? tty:"???",
  1016. Index: dpmain.c
  1017. *** Standard Input    Wed Dec 31 18:00:00 1969
  1018. --- dpmain.c    Tue Jun  9 08:34:34 1992
  1019. ***************
  1020. *** 1,5 ****
  1021.   /*
  1022. !  * Copyright 1990, 1991 John F. Haugh II
  1023.    * All rights reserved.
  1024.    *
  1025.    * Permission is granted to copy and create derivative works for any
  1026. --- 1,5 ----
  1027.   /*
  1028. !  * Copyright 1990, 1991, 1992 John F. Haugh II
  1029.    * All rights reserved.
  1030.    *
  1031.    * Permission is granted to copy and create derivative works for any
  1032. ***************
  1033. *** 21,27 ****
  1034.   #include "dialup.h"
  1035.   
  1036.   #ifndef    lint
  1037. ! static    char    sccsid[] = "@(#)dpmain.c    3.4    17:31:55    8/4/91";
  1038.   #endif
  1039.   
  1040.   #ifdef    USG
  1041. --- 21,27 ----
  1042.   #include "dialup.h"
  1043.   
  1044.   #ifndef    lint
  1045. ! static    char    sccsid[] = "@(#)dpmain.c    3.6    07:49:11    4/29/92";
  1046.   #endif
  1047.   
  1048.   #ifdef    USG
  1049. ***************
  1050. *** 151,156 ****
  1051. --- 151,157 ----
  1052.       if (! (fp = fdopen (fd, "r+"))) {
  1053.           sprintf (pass, "%s: can't open %s", Prog, DTMP);
  1054.           perror (pass);
  1055. +         unlink (DTMP);
  1056.           exit (1);
  1057.       }
  1058.   
  1059. ***************
  1060. *** 176,183 ****
  1061.        */
  1062.   
  1063.       if (dflg && ! found) {
  1064. !         fprintf (stderr, NOMATCH, Prog, shell);
  1065. !         exit (1);
  1066.       }
  1067.       if (aflg)
  1068.           if (putduent (&dent, fp))
  1069. --- 177,184 ----
  1070.        */
  1071.   
  1072.       if (dflg && ! found) {
  1073. !         fprintf (stderr, NOFOUND, Prog, shell);
  1074. !         goto failure;
  1075.       }
  1076.       if (aflg)
  1077.           if (putduent (&dent, fp))
  1078. ***************
  1079. *** 207,212 ****
  1080. --- 208,218 ----
  1081.        * After this is done the new file will replace the old file.
  1082.        */
  1083.   
  1084. +     signal (SIGINT, SIG_IGN);
  1085. +     signal (SIGQUIT, SIG_IGN);
  1086. + #ifdef    SIGTSTP
  1087. +     signal (SIGTSTP, SIG_IGN);
  1088. + #endif
  1089.       if (! stat (DIALPWD, &sb)) {
  1090.           chown (DTMP, sb.st_uid, sb.st_gid);
  1091.           chmod (DTMP, sb.st_mode);
  1092. ***************
  1093. *** 215,222 ****
  1094.           chown (DTMP, 0, 0);
  1095.           chmod (DTMP, 0400);
  1096.       }
  1097. !     link (DTMP, DIALPWD);
  1098. !     unlink (DTMP);
  1099.   
  1100.       sync ();
  1101.       exit (0);
  1102. --- 221,228 ----
  1103.           chown (DTMP, 0, 0);
  1104.           chmod (DTMP, 0400);
  1105.       }
  1106. !     if (! link (DTMP, DIALPWD))
  1107. !         unlink (DTMP);
  1108.   
  1109.       sync ();
  1110.       exit (0);
  1111. Index: usermod.c
  1112. *** Standard Input    Wed Dec 31 18:00:00 1969
  1113. --- usermod.c    Tue Jun  9 08:34:55 1992
  1114. ***************
  1115. *** 10,16 ****
  1116.    */
  1117.   
  1118.   #ifndef lint
  1119. ! static    char    sccsid[] = "@(#)usermod.c    3.11    09:26:21    3/27/92";
  1120.   #endif
  1121.   
  1122.   #include <sys/types.h>
  1123. --- 10,16 ----
  1124.    */
  1125.   
  1126.   #ifndef lint
  1127. ! static    char    sccsid[] = "@(#)usermod.c    3.12    15:28:40    5/14/92";
  1128.   #endif
  1129.   
  1130.   #include <sys/types.h>
  1131. ***************
  1132. *** 30,36 ****
  1133. --- 30,38 ----
  1134.   #endif
  1135.   
  1136.   #include "config.h"
  1137. + #ifdef    SHADOWPWD
  1138.   #include "shadow.h"
  1139. + #endif
  1140.   #include "faillog.h"
  1141.   #include "lastlog.h"
  1142.   
  1143. ***************
  1144. *** 473,478 ****
  1145. --- 475,481 ----
  1146.   {
  1147.       fprintf (stderr,
  1148.           "usage: %s [-u uid [-o]] [-g group] [-G group,...] \n", Prog);
  1149. + #ifdef    SHADOWPWD
  1150.       fprintf (stderr,
  1151.           "\t\t[-d home [-m]] [-s shell] [-c comment] [-l new_name]\n");
  1152.   #ifdef    MDY_DATE
  1153. ***************
  1154. *** 487,492 ****
  1155. --- 490,499 ----
  1156.       fprintf (stderr,
  1157.           "\t\t[-f inactive ] [-e expire yy/mm/dd ] name\n");
  1158.   #endif
  1159. + #else    /* !SHADOWPWD */
  1160. +     fprintf (stderr,
  1161. +         "\t\t[-d home [-m]] [-s shell] [-c comment] [-l new_name] name\n");
  1162. + #endif    /* SHADOWPWD */
  1163.       exit (2);
  1164.   }
  1165.   
  1166. ***************
  1167. *** 541,546 ****
  1168. --- 548,554 ----
  1169.       }
  1170.   }
  1171.   
  1172. + #ifdef    SHADOWPWD
  1173.   /*
  1174.    * new_spent - initialize the values in a shadow password file entry
  1175.    *
  1176. ***************
  1177. *** 570,575 ****
  1178. --- 578,584 ----
  1179.           spent->sp_expire = user_expire;
  1180.       }
  1181.   }
  1182. + #endif    /* SHADOWPWD */
  1183.   
  1184.   /*
  1185.    * grp_update - add user to secondary group set
  1186. ***************
  1187. *** 597,618 ****
  1188.   
  1189.       if (! gr_lock ()) {
  1190.           fprintf (stderr, "%s: error locking group file\n", Prog);
  1191.           exit (1);
  1192.       }
  1193.       if (! gr_open (O_RDWR)) {
  1194.           fprintf (stderr, "%s: error opening group file\n", Prog);
  1195.           fail_exit (1);
  1196.       }
  1197.   #ifdef    SHADOWGRP
  1198.       if (! sgr_lock ()) {
  1199.           fprintf (stderr, "%s: error locking shadow group file\n", Prog);
  1200.           fail_exit (1);
  1201.       }
  1202.       if (! sgr_open (O_RDWR)) {
  1203.           fprintf (stderr, "%s: error opening shadow group file\n", Prog);
  1204.           fail_exit (1);
  1205.       }
  1206. ! #endif
  1207.   
  1208.       /*
  1209.        * Scan through the entire group file looking for the groups that
  1210. --- 606,639 ----
  1211.   
  1212.       if (! gr_lock ()) {
  1213.           fprintf (stderr, "%s: error locking group file\n", Prog);
  1214. + #ifdef    USE_SYSLOG
  1215. +         syslog (LOG_ERR, "error locking group file");
  1216. + #endif
  1217.           exit (1);
  1218.       }
  1219.       if (! gr_open (O_RDWR)) {
  1220.           fprintf (stderr, "%s: error opening group file\n", Prog);
  1221. + #ifdef    USE_SYSLOG
  1222. +         syslog (LOG_ERR, "error opening group file");
  1223. + #endif
  1224.           fail_exit (1);
  1225.       }
  1226.   #ifdef    SHADOWGRP
  1227.       if (! sgr_lock ()) {
  1228.           fprintf (stderr, "%s: error locking shadow group file\n", Prog);
  1229. + #ifdef    USE_SYSLOG
  1230. +         syslog (LOG_ERR, "error locking shadow group file");
  1231. + #endif
  1232.           fail_exit (1);
  1233.       }
  1234.       if (! sgr_open (O_RDWR)) {
  1235.           fprintf (stderr, "%s: error opening shadow group file\n", Prog);
  1236. + #ifdef    USE_SYSLOG
  1237. +         syslog (LOG_ERR, "error opening shadow group file");
  1238. + #endif
  1239.           fail_exit (1);
  1240.       }
  1241. ! #endif    /* SHADOWGRP */
  1242.   
  1243.       /*
  1244.        * Scan through the entire group file looking for the groups that
  1245. ***************
  1246. *** 672,677 ****
  1247. --- 693,701 ----
  1248.           if (! gr_update (grp)) {
  1249.               fprintf (stderr, "%s: error adding new group entry\n",
  1250.                   Prog);
  1251. + #ifdef    USE_SYSLOG
  1252. +             syslog (LOG_ERR, "error adding group entry");
  1253. + #endif
  1254.               fail_exit (1);
  1255.           }
  1256.   #ifdef    NDBM
  1257. ***************
  1258. *** 682,690 ****
  1259.           if (! gr_dbm_update (grp)) {
  1260.               fprintf (stderr, "%s: cannot add new dbm group entry\n",
  1261.                   Prog);
  1262.               fail_exit (1);
  1263.           }
  1264. ! #endif
  1265.       }
  1266.   #ifdef NDBM
  1267.       endgrent ();
  1268. --- 706,717 ----
  1269.           if (! gr_dbm_update (grp)) {
  1270.               fprintf (stderr, "%s: cannot add new dbm group entry\n",
  1271.                   Prog);
  1272. + #ifdef    USE_SYSLOG
  1273. +             syslog (LOG_ERR, "error adding dbm group entry");
  1274. + #endif
  1275.               fail_exit (1);
  1276.           }
  1277. ! #endif    /* NDBM */
  1278.       }
  1279.   #ifdef NDBM
  1280.       endgrent ();
  1281. ***************
  1282. *** 757,763 ****
  1283.           } else if (was_member >= 0 && Gflg && is_member < 0) {
  1284.               sgrp->sg_mem = del_list (sgrp->sg_mem, user_name);
  1285.   #ifdef    USE_SYSLOG
  1286. !             syslog (LOG_INFO, "delete `%s' from shadow group `%s'\n",
  1287.                   user_name, sgrp->sg_name);
  1288.   #endif
  1289.           } else if (was_member < 0 && Gflg && is_member >= 0) {
  1290. --- 784,791 ----
  1291.           } else if (was_member >= 0 && Gflg && is_member < 0) {
  1292.               sgrp->sg_mem = del_list (sgrp->sg_mem, user_name);
  1293.   #ifdef    USE_SYSLOG
  1294. !             syslog (LOG_INFO,
  1295. !                 "delete `%s' from shadow group `%s'\n",
  1296.                   user_name, sgrp->sg_name);
  1297.   #endif
  1298.           } else if (was_member < 0 && Gflg && is_member >= 0) {
  1299. ***************
  1300. *** 777,782 ****
  1301. --- 805,813 ----
  1302.           if (! sgr_update (sgrp)) {
  1303.               fprintf (stderr, "%s: error adding new group entry\n",
  1304.                   Prog);
  1305. + #ifdef    USE_SYSLOG
  1306. +             syslog (LOG_ERR, "error adding shadow group entry\n");
  1307. + #endif
  1308.               fail_exit (1);
  1309.           }
  1310.   #ifdef    NDBM
  1311. ***************
  1312. *** 787,800 ****
  1313.           if (! sgr_dbm_update (sgrp)) {
  1314.               fprintf (stderr, "%s: cannot add new dbm group entry\n",
  1315.                   Prog);
  1316.               fail_exit (1);
  1317.           }
  1318. ! #endif
  1319.       }
  1320.   #ifdef NDBM
  1321.       endsgent ();
  1322. ! #endif
  1323. ! #endif
  1324.   }
  1325.   
  1326.   /*
  1327. --- 818,835 ----
  1328.           if (! sgr_dbm_update (sgrp)) {
  1329.               fprintf (stderr, "%s: cannot add new dbm group entry\n",
  1330.                   Prog);
  1331. + #ifdef    USE_SYSLOG
  1332. +             syslog (LOG_ERR,
  1333. +                 "error adding dbm shadow group entry\n");
  1334. + #endif
  1335.               fail_exit (1);
  1336.           }
  1337. ! #endif    /* NDBM */
  1338.       }
  1339.   #ifdef NDBM
  1340.       endsgent ();
  1341. ! #endif    /* NDBM */
  1342. ! #endif    /* SHADOWGRP */
  1343.   }
  1344.   
  1345.   /*
  1346. ***************
  1347. *** 864,874 ****
  1348.       strcpy (user_home, pwd->pw_dir);
  1349.       strcpy (user_shell, pwd->pw_shell);
  1350.   
  1351.       if (spwd = getspnam (user_name)) {
  1352.           user_expire = spwd->sp_expire;
  1353.           user_inactive = spwd->sp_inact;
  1354.       }
  1355. !     while ((arg = getopt (argc, argv, "u:og:G:d:s:c:mf:e:l:")) != EOF) {
  1356.           switch (arg) {
  1357.               case 'c':
  1358.                   if (! VALID (optarg)) {
  1359. --- 899,916 ----
  1360.       strcpy (user_home, pwd->pw_dir);
  1361.       strcpy (user_shell, pwd->pw_shell);
  1362.   
  1363. + #ifdef    SHADOWPWD
  1364.       if (spwd = getspnam (user_name)) {
  1365.           user_expire = spwd->sp_expire;
  1366.           user_inactive = spwd->sp_inact;
  1367.       }
  1368. ! #endif
  1369. ! #ifdef    SHADOWPWD
  1370. !     while ((arg = getopt (argc, argv, "u:og:G:d:s:c:mf:e:l:")) != EOF)
  1371. ! #else
  1372. !     while ((arg = getopt (argc, argv, "u:og:G:d:s:c:ml:")) != EOF)
  1373. ! #endif
  1374. !     {
  1375.           switch (arg) {
  1376.               case 'c':
  1377.                   if (! VALID (optarg)) {
  1378. ***************
  1379. *** 877,886 ****
  1380.                           Prog, optarg);
  1381.                       exit (3);
  1382.                   }
  1383. !                 if (strcmp (optarg, user_comment)) {
  1384. !                     cflg++;
  1385. !                     strncpy (user_comment, optarg, BUFSIZ);
  1386. !                 }
  1387.                   break;
  1388.               case 'd':
  1389.                   if (! VALID (optarg)) {
  1390. --- 919,926 ----
  1391.                           Prog, optarg);
  1392.                       exit (3);
  1393.                   }
  1394. !                 strncpy (user_comment, optarg, BUFSIZ);
  1395. !                 cflg++;
  1396.                   break;
  1397.               case 'd':
  1398.                   if (! VALID (optarg)) {
  1399. ***************
  1400. *** 892,913 ****
  1401.                   dflg++;
  1402.                   strncpy (user_newhome, optarg, BUFSIZ);
  1403.                   break;
  1404.               case 'e':
  1405.                   l = strtoday (optarg);
  1406.   #ifdef    ITI_AGING
  1407.                   l *= DAY;
  1408.   #endif
  1409. !                 if (l != user_expire) {
  1410. !                     eflg++;
  1411. !                     user_expire = l;
  1412. !                 }
  1413.                   break;
  1414.               case 'f':
  1415. !                 if (user_inactive != atoi (optarg)) {
  1416. !                     fflg++;
  1417. !                     user_inactive = atoi (optarg);
  1418. !                 }
  1419.                   break;
  1420.               case 'g':
  1421.                   if (isdigit (optarg[0]))
  1422.                       grp = getgrgid (atoi (optarg));
  1423. --- 932,951 ----
  1424.                   dflg++;
  1425.                   strncpy (user_newhome, optarg, BUFSIZ);
  1426.                   break;
  1427. + #ifdef    SHADOWPWD
  1428.               case 'e':
  1429.                   l = strtoday (optarg);
  1430.   #ifdef    ITI_AGING
  1431.                   l *= DAY;
  1432.   #endif
  1433. !                 user_expire = l;
  1434. !                 eflg++;
  1435.                   break;
  1436.               case 'f':
  1437. !                 user_inactive = atoi (optarg);
  1438. !                 fflg++;
  1439.                   break;
  1440. + #endif    /* SHADOWPWD */
  1441.               case 'g':
  1442.                   if (isdigit (optarg[0]))
  1443.                       grp = getgrgid (atoi (optarg));
  1444. ***************
  1445. *** 920,929 ****
  1446.                           Prog, optarg);
  1447.                       exit (1);
  1448.                   }
  1449. !                 if (grp->gr_gid != user_gid) {
  1450. !                     gflg++;
  1451. !                     user_gid = grp->gr_gid;
  1452. !                 }
  1453.                   break;
  1454.               case 'G':
  1455.                   Gflg++;
  1456. --- 958,965 ----
  1457.                           Prog, optarg);
  1458.                       exit (1);
  1459.                   }
  1460. !                 user_gid = grp->gr_gid;
  1461. !                 gflg++;
  1462.                   break;
  1463.               case 'G':
  1464.                   Gflg++;
  1465. ***************
  1466. *** 938,946 ****
  1467.                           Prog, optarg);
  1468.                       exit (3);
  1469.                   }
  1470. !                 if (strcmp (user_name, optarg)) {
  1471. !                     lflg++;
  1472.                       strcpy (user_newname, optarg);
  1473.                   }
  1474.                   break;
  1475.               case 'm':
  1476. --- 974,989 ----
  1477.                           Prog, optarg);
  1478.                       exit (3);
  1479.                   }
  1480. !                 /*
  1481. !                  * If the name does not really change, we
  1482. !                  * mustn't set the flag as this will cause
  1483. !                  * rather serious problems later!
  1484. !                  */
  1485. !                 if (strcmp (user_newname, optarg)) {
  1486.                       strcpy (user_newname, optarg);
  1487. +                     lflg++;
  1488.                   }
  1489.                   break;
  1490.               case 'm':
  1491. ***************
  1492. *** 962,971 ****
  1493.                           Prog, optarg);
  1494.                       exit (3);
  1495.                   }
  1496. !                 if (strcmp (user_shell, optarg)) {
  1497. !                     strncpy (user_shell, optarg, BUFSIZ);
  1498. !                     sflg++;
  1499. !                 }
  1500.                   break;
  1501.               case 'u':
  1502.                   uflg++;
  1503. --- 1005,1012 ----
  1504.                           Prog, optarg);
  1505.                       exit (3);
  1506.                   }
  1507. !                 strncpy (user_shell, optarg, BUFSIZ);
  1508. !                 sflg++;
  1509.                   break;
  1510.               case 'u':
  1511.                   uflg++;
  1512. ***************
  1513. *** 1008,1018 ****
  1514. --- 1049,1061 ----
  1515.           fprintf (stderr, "%s: cannot rewrite password file\n", Prog);
  1516.           fail_exit (1);
  1517.       }
  1518. + #ifdef    SHADOWPWD
  1519.       if (! spw_close ()) {
  1520.           fprintf (stderr, "%s: cannot rewrite shadow password file\n",    
  1521.               Prog);
  1522.           fail_exit (1);
  1523.       }
  1524. + #endif
  1525.       if (user_ngroups >= 0) {
  1526.           if (! gr_close ()) {
  1527.               fprintf (stderr, "%s: cannot rewrite group file\n",
  1528. ***************
  1529. *** 1019,1036 ****
  1530.                   Prog);
  1531.               fail_exit (1);
  1532.           }
  1533. !         (void) gr_unlock ();
  1534.   #ifdef    SHADOWGRP
  1535.           if (! sgr_close ()) {
  1536.               fprintf (stderr, "%s: cannot rewrite shadow group file\n",
  1537.                   Prog);
  1538.               fail_exit (1);
  1539.           }
  1540. -         (void) sgr_unlock ();
  1541. - #endif
  1542.       }
  1543.       (void) spw_unlock ();
  1544.       (void) pw_unlock ();
  1545.   }
  1546.   
  1547.   /*
  1548. --- 1062,1094 ----
  1549.                   Prog);
  1550.               fail_exit (1);
  1551.           }
  1552. !     }
  1553. !     (void) gr_unlock ();
  1554.   #ifdef    SHADOWGRP
  1555. +     if (user_ngroups >= 0) {
  1556.           if (! sgr_close ()) {
  1557.               fprintf (stderr, "%s: cannot rewrite shadow group file\n",
  1558.                   Prog);
  1559.               fail_exit (1);
  1560.           }
  1561.       }
  1562. +     (void) sgr_unlock ();
  1563. + #endif
  1564.       (void) spw_unlock ();
  1565.       (void) pw_unlock ();
  1566. +     /*
  1567. +      * Close the DBM and/or flat files
  1568. +      */
  1569. +     endpwent ();
  1570. + #ifdef    SHADOWPWD
  1571. +     endspent ();
  1572. + #endif
  1573. +     endgrent ();
  1574. + #ifdef    SHADOWGRP
  1575. +     endsgent ();
  1576. + #endif
  1577.   }
  1578.   
  1579.   /*
  1580. ***************
  1581. *** 1049,1054 ****
  1582. --- 1107,1113 ----
  1583.           fprintf (stderr, "%s: unable to open password file\n", Prog);
  1584.           fail_exit (1);
  1585.       }
  1586. + #ifdef    SHADOWPWD
  1587.       if (! spw_lock ()) {
  1588.           fprintf (stderr, "%s: cannot lock shadow password file\n",
  1589.               Prog);
  1590. ***************
  1591. *** 1059,1064 ****
  1592. --- 1118,1124 ----
  1593.               Prog);
  1594.           fail_exit (1);
  1595.       }
  1596. + #endif
  1597.   }
  1598.   
  1599.   /*
  1600. ***************
  1601. *** 1071,1089 ****
  1602.   usr_update ()
  1603.   {
  1604.       struct    passwd    pwent;
  1605. -     struct    spwd    spent;
  1606.       struct    passwd    *pwd;
  1607.       struct    spwd    *spwd;
  1608.   
  1609.       pwd = pw_locate (user_name);
  1610.       pwent = *pwd;
  1611.   
  1612.       spwd = spw_locate (user_name);
  1613.       spent = *spwd;
  1614. -     new_pwent (&pwent);
  1615.       new_spent (&spent);
  1616.       if (lflg || uflg || gflg || cflg || dflg || sflg) {
  1617.           if (! pw_update (&pwent)) {
  1618.               fprintf (stderr, "%s: error changing password entry\n",
  1619. --- 1131,1151 ----
  1620.   usr_update ()
  1621.   {
  1622.       struct    passwd    pwent;
  1623.       struct    passwd    *pwd;
  1624. + #ifdef    SHADOWPWD
  1625. +     struct    spwd    spent;
  1626.       struct    spwd    *spwd;
  1627. + #endif
  1628.   
  1629.       pwd = pw_locate (user_name);
  1630.       pwent = *pwd;
  1631. +     new_pwent (&pwent);
  1632.   
  1633. + #ifdef    SHADOWPWD
  1634.       spwd = spw_locate (user_name);
  1635.       spent = *spwd;
  1636.       new_spent (&spent);
  1637. ! #endif
  1638.       if (lflg || uflg || gflg || cflg || dflg || sflg) {
  1639.           if (! pw_update (&pwent)) {
  1640.               fprintf (stderr, "%s: error changing password entry\n",
  1641. ***************
  1642. *** 1110,1119 ****
  1643.                       Prog);
  1644.                   fail_exit (1);
  1645.               }
  1646. -             endpwent ();
  1647.           }
  1648.   #endif
  1649.       }
  1650.       if (lflg || eflg || fflg) {
  1651.           if (! spw_update (&spent)) {
  1652.               fprintf (stderr,
  1653. --- 1172,1181 ----
  1654.                       Prog);
  1655.                   fail_exit (1);
  1656.               }
  1657.           }
  1658.   #endif
  1659.       }
  1660. + #ifdef    SHADOWPWD
  1661.       if (lflg || eflg || fflg) {
  1662.           if (! spw_update (&spent)) {
  1663.               fprintf (stderr,
  1664. ***************
  1665. *** 1142,1150 ****
  1666.                   Prog);
  1667.               fail_exit (1);
  1668.           }
  1669. -         endspent ();
  1670.       }
  1671. ! #endif
  1672.       if (Gflg || lflg)
  1673.           grp_update ();
  1674.   }
  1675. --- 1204,1212 ----
  1676.                   Prog);
  1677.               fail_exit (1);
  1678.           }
  1679.       }
  1680. ! #endif    /* NDBM */
  1681. ! #endif    /* SHADOWPWD */
  1682.       if (Gflg || lflg)
  1683.           grp_update ();
  1684.   }
  1685. ***************
  1686. *** 1243,1249 ****
  1687. --- 1305,1313 ----
  1688.   #ifdef    SHADOWGRP
  1689.       (void) sgr_unlock ();
  1690.   #endif
  1691. + #ifdef    SHADOWPWD
  1692.       (void) spw_unlock ();
  1693. + #endif
  1694.       (void) pw_unlock ();
  1695.       exit (code);
  1696.   }
  1697. ***************
  1698. *** 1276,1287 ****
  1699.   
  1700.   #ifdef    NDBM
  1701.       pw_dbm_mode = O_RDWR;
  1702.       sp_dbm_mode = O_RDWR;
  1703.       gr_dbm_mode = O_RDWR;
  1704.   #ifdef    SHADOWGRP
  1705.       sg_dbm_mode = O_RDWR;
  1706.   #endif
  1707. ! #endif
  1708.       process_flags (argc, argv);
  1709.   
  1710.       /*
  1711. --- 1340,1353 ----
  1712.   
  1713.   #ifdef    NDBM
  1714.       pw_dbm_mode = O_RDWR;
  1715. + #ifdef    SHADOWPWD
  1716.       sp_dbm_mode = O_RDWR;
  1717. + #endif
  1718.       gr_dbm_mode = O_RDWR;
  1719.   #ifdef    SHADOWGRP
  1720.       sg_dbm_mode = O_RDWR;
  1721.   #endif
  1722. ! #endif    /* NDBM */
  1723.       process_flags (argc, argv);
  1724.   
  1725.       /*
  1726. -- 
  1727. John F. Haugh II                   | Vida en La Republica de Tejas:
  1728. Ma Bell: (512) 251-2151            |  A Tejano woman, after spending the rent
  1729. UUCP: ...!cs.utexas.edu!rpp386!jfh |  money on the Tejas Lottery - "I can't go
  1730. Domain: jfh@rpp386.cactus.org      |  home, my husband will beat me up."
  1731.  
  1732. exit 0 # Just in case...
  1733.