home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1992 March / Source_Code_CD-ROM_Walnut_Creek_March_1992.iso / usenet / altsrcs / 1 / 1501 < prev    next >
Encoding:
Internet Message Format  |  1990-12-28  |  21.1 KB

  1. From: jfh@rpp386.cactus.org (John F. Haugh II)
  2. Newsgroups: alt.security,alt.sources
  3. Subject: Group Password Command
  4. Message-ID: <18411@rpp386.cactus.org>
  5. Date: 22 Jun 90 14:50:49 GMT
  6.  
  7. I noticed Lenny Tropiano just posted his dialup password code.  I thought
  8. I'd get in on act with something slightly different.
  9.  
  10. This is a collection of code to implement group passwords.  It is based
  11. on the shadow password code I posted previously.  I know that group
  12. passwords are a bad idea, but then, why not at least support them ;-)
  13.  
  14. You will probably not want to mix this code with the older shadow code
  15. since the older code is backlevel for the Makefile and password.c files
  16. to probably be incompatible.  That will be fixed at some point in the
  17. future with a complete reposting of the entire shadow login system.
  18.  
  19. The command you will make is "gpasswd".  The current version of shadow
  20. passwd supports a "-g" flag which exec's gpasswd, but you'll have to
  21. wait until I get around to cleaning up that code prior to posting.
  22.  
  23. No man pages yet.  gpasswd is executed as "gpasswd [ -r ] group", where
  24. "-r" means to remove the password and replace it with "x".  Only root
  25. or the first group member can change or remove a group password.  If you
  26. find that your newgrp command doesn't support group passwords, let me
  27. know and I post the sources to my shadow newgrp command.
  28.  
  29. One final note - I have started working on a clone of AT&T's "private"
  30. password scheme.  I would appreciate any information [ PLEASE, NO AT&T
  31. SOURCE CODE AND NO MAN PAGES ] or descriptions you can provide.  In
  32. particular, there is a privates structure whose members I know nothing
  33. about ...
  34.  
  35. Shar and enjoy!
  36. --
  37. #! /bin/sh
  38. # This is a shell archive, meaning:
  39. # 1. Remove everything above the #! /bin/sh line.
  40. # 2. Save the resulting text in a file.
  41. # 3. Execute the file with /bin/sh (not csh) to create:
  42. #    Makefile
  43. #    gpmain.c
  44. #    grent.c
  45. #    password.c
  46. # This archive created: Fri Jun 22 09:40:27 1990
  47. # By:    John F. Haugh II (River Parishes Programming, Austin TX)
  48. export PATH; PATH=/bin:/usr/bin:$PATH
  49. echo shar: "extracting 'Makefile'" '(6678 characters)'
  50. if test -f 'Makefile'
  51. then
  52.     echo shar: "will not over-write existing file 'Makefile'"
  53. else
  54. sed 's/^X//' << \SHAR_EOF > 'Makefile'
  55. X#
  56. X# Copyright 1988,1989,1990, John F. Haugh II
  57. X# All rights reserved.
  58. X#
  59. X# Non-commercial distribution permitted.  You must provide this source
  60. X# code in any distribution.  This notice must remain intact.
  61. X#
  62. X#    @(#)Makefile    2.7    09:40:16  - Shadow password system
  63. X#
  64. X#    @(#)Makefile    2.7    09:40:16    6/22/90
  65. X#
  66. XSHELL = /bin/sh
  67. X
  68. X# Define the directory login is copied to.  BE VERY CAREFUL!!!
  69. X# LOGINDIR = /bin
  70. XLOGINDIR = /etc
  71. X
  72. X# Pick your favorite C compiler and tags command
  73. XCC = cc
  74. XTAGS = ctags
  75. X
  76. X# OS.  Currently only BSD and USG are defined.  If you don't use BSD,
  77. X# USG (System V) is assumed.
  78. X# OS = -DBSD
  79. X
  80. X# Do you have to do ranlib?  Sorry to hear that ...
  81. XRANLIB = ranlib
  82. X# RANLIB = echo
  83. X
  84. X# Flags for SCO Xenix/386
  85. XCFLAGS = -O -M3 -g $(PWDEF) $(AL64DEF) $(OS)
  86. XLIBS = -lcrypt
  87. XLDFLAGS = -M3 -g
  88. XLTFLAGS = 
  89. X# This should be Slibsec.a for small model, or Llibsec.a for
  90. X# large model or whatever.  MUST AGREE WITH CFLAGS!!!
  91. XLIBSEC = Slibsec.a
  92. X
  93. X# Flags for normal machines
  94. X# CFLAGS = -O -g $(PWDEF) $(AL64DEF) $(OS)
  95. X# LIBS =
  96. X# LDFLAGS = -g
  97. X# LIBSEC = libsec.a
  98. X
  99. XLOBJS = lmain.o login.o env.o password.o entry.o valid.o setup.o shell.o age.o \
  100. X    pwent.o utmp.o sub.o mail.o motd.o log.o shadow.o dialup.o dialchk.o \
  101. X    ttytype.o failure.o port.o
  102. X
  103. XLSRCS = lmain.c login.c env.c password.c entry.c valid.c setup.c shell.c age.c \
  104. X    pwent.c utmp.c sub.c mail.c motd.c log.c shadow.c dialup.c dialchk.c \
  105. X    ttytype.c failure.c port.c
  106. X
  107. XSOBJS = smain.o env.o password.o entry.o suvalid.o susetup.o sushell.o \
  108. X    pwent.o susub.o mail.o motd.o sulog.o shadow.o age.o
  109. X
  110. XSSRCS = smain.c env.c password.c entry.c valid.c setup.c shell.c \
  111. X    pwent.c sub.c mail.c motd.c sulog.c shadow.c age.c
  112. X
  113. XPOBJS = pmain.o password.o entry.o valid.o pwage.o pwent.o obscure.o shadow.o
  114. X
  115. XPSRCS = pmain.c password.c entry.c valid.c age.c pwent.c obscure.c shadow.c
  116. X
  117. XGPSRCS = gpmain.c password.c grent.c
  118. X
  119. XGPOBJS = gpmain.o password.o grent.o
  120. X
  121. XPWOBJS = pwconv.o pwent.o shadow.o pwage.o
  122. X
  123. XPWSRCS = pwconv.c pwent.c shadow.c age.c
  124. X
  125. XPWUNOBJS = pwunconv.o pwent.o shadow.o pwage.o
  126. X
  127. XPWUNSRCS = pwunconv.c pwent.c shadow.c age.c
  128. X
  129. XSULOGOBJS = sulogin.o entry.o env.o password.o pwage.o pwent.o setup.o \
  130. X    shadow.o shell.o valid.o
  131. X
  132. XSULOGSRCS = sulogin.c entry.c env.c password.c age.c pwent.c setup.c \
  133. X    shadow.c shell.c valid.c
  134. X
  135. XDBOBJS = mkpasswd.o pwent.o
  136. X
  137. XDBSRCS = mkpasswd.c pwent.c
  138. X
  139. XNGSRCS = newgrp.c shadow.c password.c
  140. X
  141. XNGOBJS = newgrp.o shadow.o password.o
  142. X
  143. XALLSRCS = age.c dialchk.c dialup.c entry.c env.c lmain.c log.c login.c mail.c \
  144. X    motd.c obscure.c password.c pmain.c pwconv.c pwent.c pwunconv.c \
  145. X    setup.c shadow.c shell.c smain.c sub.c sulog.c sulogin.c ttytype.c \
  146. X    utmp.c valid.c port.c newgrp.c gpmain.c grent.c
  147. X
  148. XFILES1 = README log.c mail.c shadow.h sulog.c Makefile entry.c obscure.c \
  149. X    setup.c sub.c config.h pmain.c sulogin.c dialup.h ttytype.c \
  150. X    port.c newgrp.c
  151. X
  152. XFILES2 = lastlog.h login.c motd.c password.c shell.c utmp.c age.c env.c \
  153. X    pwent.c shadow.c valid.c lmain.c smain.c pwconv.c dialup.c dialchk.c \
  154. X    pwunconv.c failure.c faillog.h faillog.c port.h gpmain.c grent.c
  155. X
  156. XDOCS = login.1 passwd.1 passwd.4 shadow.3 shadow.4 su.1 sulogin.8 pwconv.8 \
  157. X    pwunconv.8 faillog.8 faillog.4
  158. X
  159. XBINS = su login pwconv pwunconv passwd sulogin faillog newgrp gpasswd \
  160. X    mkpasswd
  161. X
  162. Xall:    $(BINS) $(DOCS)
  163. X
  164. Xlibsec: shadow.o
  165. X    ar rv $(LIBSEC) shadow.o
  166. X    $(RANLIB) $(LIBSEC)
  167. X
  168. Xinstall: all
  169. X    strip $(BINS)
  170. X    cp login $(LOGINDIR)/login
  171. X    cp mkpasswd pwconv pwunconv sulogin /etc
  172. X    cp su passwd gpasswd faillog newgrp /bin
  173. X    cp shadow.h /usr/include
  174. X    chown root $(LOGINDIR)/login /etc/pwconv /etc/pwunconv /etc/sulogin \
  175. X        /bin/su /bin/passwd /bin/gpasswd /bin/newgrp /etc/mkpasswd
  176. X    chgrp root $(LOGINDIR)/login /etc/pwconv /etc/pwunconv /etc/sulogin \
  177. X        /bin/su /bin/passwd /bin/gpasswd /bin/newgrp /etc/mkpasswd
  178. X    chown bin /bin/faillog /usr/include/shadow.h
  179. X    chgrp bin /bin/faillog /usr/include/shadow.h
  180. X    chmod 700 /etc/pwconv /etc/pwunconv /etc/sulogin /etc/mkpasswd
  181. X    chmod 4711 $(LOGINDIR)/login /bin/su /bin/passwd /bin/gpasswd \
  182. X        /bin/newgrp
  183. X    chmod 711 /bin/faillog
  184. X    chmod 444 /usr/include/shadow.h
  185. X
  186. Xlint:    su.L login.L pwconv.L pwunconv.L passwd.L sulogin.L faillog.L \
  187. X    newgrp.L gpasswd.L
  188. X
  189. Xtags:    $(ALLSRCS)
  190. X    $(TAGS) $(ALLSRCS)
  191. X
  192. XREADME:    s.README
  193. X    get s.README
  194. X    
  195. X$(DOCS):
  196. X    get s.$@
  197. X
  198. Xlogin:    $(LOBJS)
  199. X    $(CC) -o login $(LDFLAGS) $(LOBJS) $(LIBS)
  200. X
  201. Xlogin.L: $(LSRCS)
  202. X    lint $(LSRCS) > login.L
  203. X
  204. Xsu:    $(SOBJS)
  205. X    $(CC) -o su $(LDFLAGS) $(SOBJS) $(LIBS)
  206. X
  207. Xsu.L:    $(SSRCS)
  208. X    lint -DSU $(SSRCS) > su.L
  209. X
  210. Xpasswd:    $(POBJS)
  211. X    $(CC) -o passwd $(LDFLAGS) $(POBJS) $(LIBS)
  212. X
  213. Xpasswd.L: $(PSRCS)
  214. X    lint -DPASSWD $(PSRCS) > passwd.L
  215. X
  216. Xgpasswd: $(GPOBJS)
  217. X    $(CC) -o gpasswd $(LDFLAGS) $(GPOBJS) $(LIBS)
  218. X
  219. Xgpasswd.L: $(GPSRCS)
  220. X    lint $(GPSRCS) > gpasswd.L
  221. X
  222. Xpwconv:    $(PWOBJS)
  223. X    $(CC) -o pwconv $(LDFLAGS) $(PWOBJS) $(LIBS)
  224. X
  225. Xpwconv.L: $(PWSRCS)
  226. X    lint -DPASSWD $(PWSRCS) > pwconv.L
  227. X
  228. Xpwunconv: $(PWUNOBJS)
  229. X    $(CC) -o pwunconv $(LDFLAGS) $(PWUNOBJS) $(LIBS)
  230. X
  231. Xpwunconv.L: $(PWUNSRCS)
  232. X    lint -DPASSWD $(PWUNSRCS) > pwunconv.L
  233. X
  234. Xsulogin: $(SULOGOBJS)
  235. X    $(CC) -o sulogin $(LDFLAGS) $(SULOGOBJS) $(LIBS)
  236. X
  237. Xsulogin.L: $(SULOGSRCS)
  238. X    lint $(SULOGSRCS) > sulogin.L
  239. X
  240. Xfaillog: faillog.o
  241. X    $(CC) -o faillog $(LDFLAGS) faillog.o $(LIBS)
  242. X
  243. Xfaillog.L: faillog.c faillog.h config.h
  244. X    lint faillog.c > faillog.L
  245. X
  246. Xmkpasswd: $(DBOBJS)
  247. X    $(CC) -o mkpasswd $(LDFLAGS) $(DBOBJS) $(LIBS) -ldbm
  248. X
  249. Xmkpasswd.L: $(DBSRCS)
  250. X    lint $(DBSRCS) > mkpasswd.L
  251. X
  252. Xnewgrp: $(NGOBJS)
  253. X    $(CC) -o newgrp $(LDFLAGS) $(NGOBJS) $(LIBS)
  254. X
  255. Xnewgrp.L: $(NGSRCS)
  256. X    lint $(NGSRCS) > newgrp.L
  257. X
  258. Xsushell.o: config.h shell.c
  259. X    $(CC) -c $(CFLAGS) -DSU shell.c
  260. X    mv shell.o sushell.o
  261. X
  262. Xsusub.o: config.h sub.c
  263. X    cp sub.c susub.c
  264. X    $(CC) -c $(CFLAGS) -DSU susub.c
  265. X    rm susub.c
  266. X
  267. Xsulog.o: config.h
  268. X
  269. Xsusetup.o: config.h setup.c
  270. X    $(CC) -c $(CFLAGS) -DSU setup.c
  271. X    mv setup.o susetup.o
  272. X
  273. Xsuvalid.o: config.h valid.c
  274. X    cp valid.c suvalid.c
  275. X    $(CC) -c $(CFLAGS) -DSU suvalid.c
  276. X    rm suvalid.c
  277. X
  278. Xpmain.o: config.h lastlog.h shadow.h
  279. X
  280. Xpwage.o: age.c config.h
  281. X    cp age.c pwage.c
  282. X    $(CC) -c $(CFLAGS) -DPASSWD pwage.c
  283. X    rm pwage.c
  284. X
  285. Xlmain.o: config.h lastlog.h faillog.h
  286. X
  287. Xsmain.o: config.h lastlog.h
  288. X
  289. Xsetup.o: config.h
  290. X
  291. Xutmp.o: config.h
  292. X
  293. Xmail.o: config.h
  294. X
  295. Xmotd.o: config.h
  296. X
  297. Xage.o: config.h
  298. X
  299. Xlog.o: config.h lastlog.h
  300. X
  301. Xshell.o: config.h
  302. X
  303. Xentry.o: config.h shadow.h
  304. X
  305. Xshadow.o: shadow.h
  306. X
  307. Xdialup.o: dialup.h
  308. X
  309. Xdialchk.o: dialup.h config.h
  310. X
  311. Xvalid.o: config.h
  312. X
  313. Xfailure.o: faillog.h config.h
  314. X
  315. Xfaillog.o: faillog.h config.h
  316. X
  317. Xpwent.o: config.h
  318. X
  319. Xport.o: port.h
  320. X
  321. Xnewgrp.o: config.h shadow.h
  322. X
  323. Xclean:
  324. X    -rm -f *.o a.out core npasswd nshadow *.pag *.dir
  325. X
  326. Xclobber: clean
  327. X    -rm -f $(BINS) *.L
  328. X
  329. Xshar:    login.sh.1 login.sh.2 login.sh.3
  330. X
  331. Xlogin.sh.1: $(FILES1)
  332. X    shar -a $(FILES1) > login.sh.1
  333. X
  334. Xlogin.sh.2: $(FILES2)
  335. X    shar -a $(FILES2) > login.sh.2
  336. X
  337. Xlogin.sh.3: $(DOCS)
  338. X    shar -a $(DOCS) > login.sh.3
  339. SHAR_EOF
  340. if test 6678 -ne "`wc -c < 'Makefile'`"
  341. then
  342.     echo shar: "error transmitting 'Makefile'" '(should have been 6678 characters)'
  343. fi
  344. fi
  345. echo shar: "extracting 'gpmain.c'" '(7260 characters)'
  346. if test -f 'gpmain.c'
  347. then
  348.     echo shar: "will not over-write existing file 'gpmain.c'"
  349. else
  350. sed 's/^X//' << \SHAR_EOF > 'gpmain.c'
  351. X/*
  352. X * Copyright 1990, John F. Haugh II
  353. X * All rights reserved.
  354. X *
  355. X * Non-commercial distribution permitted.  You must provide this source
  356. X * code in any distribution.  This notice must remain intact.
  357. X */
  358. X
  359. X#include <sys/types.h>
  360. X#include <stdio.h>
  361. X#include <pwd.h>
  362. X#include <grp.h>
  363. X#include <fcntl.h>
  364. X#include <signal.h>
  365. X#include <errno.h>
  366. X#ifndef    BSD
  367. X#include <termio.h>
  368. X#ifdef SYS3
  369. X#include <sys/ioctl.h>
  370. X#endif
  371. X#include <string.h>
  372. X#ifndef    SYS3
  373. X#include <memory.h>
  374. X#endif
  375. X#else
  376. X#include <sgtty.h>
  377. X#include <strings.h>
  378. X#define    strchr    index
  379. X#define    strrchr    rindex
  380. X#endif
  381. X#include "config.h"
  382. X
  383. X#ifndef    PASSLENGTH
  384. X#define    PASSLENGTH    5
  385. X#endif
  386. X
  387. X#ifndef    lint
  388. Xstatic    char    _sccsid[] = "@(#)gpmain.c    1.2    09:24:15    6/22/90";
  389. X#endif
  390. X
  391. Xchar    name[BUFSIZ];
  392. Xchar    pass[BUFSIZ];
  393. Xchar    pass2[BUFSIZ];
  394. X
  395. Xstruct    group    grent;
  396. X
  397. Xchar    *myname;
  398. X
  399. X#ifndef    RETRIES
  400. X#define    RETRIES    3
  401. X#endif
  402. X
  403. Xchar    *l64a ();
  404. Xchar    *crypt ();
  405. Xextern    int    errno;
  406. Xlong    a64l ();
  407. Xvoid    entry ();
  408. Xtime_t    time ();
  409. X
  410. X/*
  411. X * usage - display usage message
  412. X */
  413. X
  414. Xvoid
  415. Xusage ()
  416. X{
  417. X    fprintf (stderr, "usage: %s [ -r ] group\n", myname);
  418. X    exit (1);
  419. X}
  420. X
  421. Xint
  422. Xmain (argc, argv)
  423. Xint    argc;
  424. Xchar    **argv;
  425. X{
  426. X    extern    int    optind;
  427. X    extern    char    *optarg;
  428. X    char    *group;
  429. X    int    flag;
  430. X    int    i;
  431. X    void    die ();
  432. X    char    *cp;
  433. X    char    *getlogin ();
  434. X    int    amroot;
  435. X    int    lockfd = -1;
  436. X    int    remove = 0;
  437. X    int    retries;
  438. X    int    ruid = getuid();
  439. X    int    suid = geteuid();
  440. X    long    salttime;
  441. X    struct    group    *gr;
  442. X    struct    group    *getgrnam ();
  443. X    struct    group    *sgetgrent ();
  444. X    struct    passwd    *pw;
  445. X    struct    passwd    *getpwuid ();
  446. X    struct    passwd    *getpwnam ();
  447. X    FILE    *ngrp;
  448. X    FILE    *ogrp;
  449. X    char    buf[BUFSIZ];
  450. X    char    tmp[BUFSIZ];
  451. X
  452. X    setuid (geteuid ());
  453. X    myname = argv[0];
  454. X
  455. X    if (! isatty (0) || ! isatty (1))
  456. X        exit (1);
  457. X
  458. X    die (0);            /* save tty modes */
  459. X
  460. X    signal (SIGHUP, die);
  461. X    signal (SIGINT, die);
  462. X    signal (SIGQUIT, die);
  463. X    signal (SIGTERM, die);
  464. X
  465. X    while ((flag = getopt (argc, argv, "gr")) != EOF) {
  466. X        switch (flag) {
  467. X            case 'g':    /* no-op from normal password */
  468. X                break;
  469. X            case 'r':    /* remove group password */
  470. X                remove = 1;
  471. X                break;
  472. X            default:
  473. X                usage ();
  474. X        }
  475. X    }
  476. X    if (cp = getlogin ())        /* need user name */
  477. X        (void) strcpy (name, cp);
  478. X    else if (pw = getpwuid (ruid)) /* get it from password file */
  479. X        strcpy (name, pw->pw_name);
  480. X    else {                /* can't find user name! */
  481. X        fprintf (stderr, "Who are you?\n");
  482. X        exit (1);
  483. X    }
  484. X    if (! (pw = getpwnam (name)))
  485. X        goto failure;        /* can't get my name ... */
  486. X        
  487. X    if (! (group = argv[optind]))
  488. X        usage ();
  489. X
  490. X    if (! (gr = getgrnam (group))) {
  491. X        fprintf (stderr, "unknown group: %s\n", group);
  492. X        exit (1);
  493. X    }
  494. X    if (! amroot) {
  495. X        if (gr->gr_mem[0] == (char *) 0)
  496. X            goto failure;
  497. X
  498. X        if (strcmp (gr->gr_mem[0], name) != 0)
  499. X            goto failure;
  500. X    }
  501. X    if (remove) {
  502. X        if (! amroot && (gr->gr_mem[0] &&
  503. X                strcmp (name, gr->gr_mem[0]) != 0))
  504. X            goto failure;
  505. X
  506. X        gr->gr_passwd = "";
  507. X        goto output;
  508. X    }
  509. X    printf ("Changing password for group %s\n", group);
  510. X
  511. X    printf ("Enter new password (minimum of %d characters)\n", PASSLENGTH);
  512. X    retries = RETRIES;
  513. Xretry:
  514. X    if (! password ("New Password:", pass))
  515. X        exit (1);
  516. X
  517. X    if (! password ("Re-enter new password:", pass2))
  518. X        exit (1);
  519. X
  520. X    if (strcmp (pass, pass2) != 0) {
  521. X        puts ("They don't match; try again");
  522. X
  523. X        if (retries-- > 0)
  524. X            goto retry;
  525. X        else
  526. X            goto toomany;
  527. X    }
  528. X    (void) time (&salttime);
  529. X    salttime = ((salttime & 07777) ^ ((salttime >> 12) & 07777)) & 07777;
  530. X    grent.gr_passwd = tmp;
  531. X    strcpy (grent.gr_passwd, crypt (pass, l64a (salttime)));
  532. X#ifdef    DOUBLESIZE
  533. X    if (strlen (pass) > 8) {
  534. X        strcpy (grent.gr_passwd + 13,
  535. X            crypt (pass + 8, l64a (salttime)) + 2);
  536. X    }
  537. X#endif
  538. Xoutput:
  539. X
  540. X    /*
  541. X     * Now we get to race the bad guy.  I don't think he can get us.
  542. X     *
  543. X     * Ignore most reasonable signals.
  544. X     *    Maybe we should ignore more?  He can't hurt us until the end.
  545. X     *
  546. X     * Get a lock file.
  547. X     *
  548. X     * Copy first part of password file to new file.
  549. X     *    Illegal lines are copied verbatim.
  550. X     *    File permissions are r--r--r--, owner root, group root.
  551. X     *
  552. X     * Output the new entry.
  553. X     *    Only fields in struct passwd are output.
  554. X     *
  555. X     * Copy the rest of the file verbatim.
  556. X     *
  557. X     * Rename (link, unlink) password file to backup.
  558. X     *    Kill me now and nothing changes or no one gets in.
  559. X     *
  560. X     * Rename (link, unlink) temporary file to password file.
  561. X     *    Kill me now and no one gets in or lock is left.
  562. X     *
  563. X     * Remove locking file.
  564. X     *
  565. X     * That's all folks ...
  566. X     */
  567. X
  568. X    signal (SIGHUP, SIG_IGN);
  569. X    signal (SIGINT, SIG_IGN);
  570. X    signal (SIGQUIT, SIG_IGN);
  571. X    signal (SIGTERM, SIG_IGN);
  572. X
  573. X    ulimit (30000);            /* prevent any funny business */
  574. X    umask (0);            /* get new files modes correct */
  575. X#ifndef    NDEBUG
  576. X    if ((lockfd = open (".grplock", O_RDONLY|O_CREAT|O_EXCL), 0444) == -1)
  577. X#else
  578. X    if ((lockfd = open (GRPLOCK, O_RDONLY|O_CREAT|O_EXCL), 0444) == -1)
  579. X#endif    /* NDEBUG */
  580. X    {
  581. X        puts ("Can't get lock");
  582. X        exit (1);
  583. X    }
  584. X    umask (077);            /* close security holes to come ... */
  585. X    if (access (NGRPFILE, 0) == 0 && unlink (NGRPFILE) == -1)
  586. X        goto failure;
  587. X
  588. X#ifndef    NDEBUG
  589. X    if ((ngrp = fopen ("ngroup", "w")) == (FILE *) 0)
  590. X#else
  591. X    umask (077);        /* no permissions for non-roots */
  592. X
  593. X    if ((ngrp = fopen (NGRPFILE, "w")) == (FILE *) 0)
  594. X#endif    /* NDEBUG */
  595. X        goto failure;
  596. X
  597. X#ifndef    NDEBUG
  598. X    chmod (NGRPFILE, 0444);        /* lets have some security here ... */
  599. X    chown (NGRPFILE, 0, 0);        /* ... and keep the bad guy away */
  600. X#endif    /* NDEBUG */
  601. X    if ((ogrp = fopen (GRPFILE, "r")) == (FILE *) 0)
  602. X        goto failure;
  603. X
  604. X    while (fgets (buf, sizeof buf, ogrp) != (char *) 0) {
  605. X        if (buf[0] == '#' || ! (gr = sgetgrent (buf))) {
  606. X            fputs (buf, ngrp);
  607. X        } else if (strcmp (gr->gr_name, group) != 0)
  608. X            fputs (buf, ngrp);
  609. X        else
  610. X            break;
  611. X    }
  612. X    if (gr) {
  613. X        (void) fprintf (ngrp, "%s:%s:%d%s",
  614. X            gr->gr_name,
  615. X                grent.gr_passwd ? grent.gr_passwd:"x",
  616. X                gr->gr_gid, strrchr (buf, ':'));
  617. X
  618. X        while (fgets (buf, BUFSIZ, ogrp) != (char *) 0)
  619. X            fputs (buf, ngrp);
  620. X    }
  621. X    if (ferror (ngrp)) {
  622. X        perror (NGRPFILE);
  623. X        if (unlink (NGRPFILE) || unlink (GRPLOCK))
  624. X            fputs ("Help!\n", stderr);
  625. X
  626. X        exit (1);
  627. X    }
  628. X    fflush (ngrp);
  629. X    fclose (ngrp);
  630. X#ifdef    NDEBUG
  631. X    chmod (NGRPFILE, 0644);
  632. X    if (unlink (OGRPFILE) == -1) {
  633. X        if (errno != ENOENT) {
  634. X            puts ("Can't unlink backup file");
  635. X            goto unlock;
  636. X        }
  637. X    }
  638. X    if (link (GRPFILE, OGRPFILE) || unlink (GRPFILE)) {
  639. X        puts ("Can't save backup file");
  640. X        goto unlock;
  641. X    }
  642. X#ifndef    BSD
  643. X    if (link (NGRPFILE, GRPFILE) || unlink (NGRPFILE))
  644. X#else
  645. X    if (rename (NGRPFILE, GRPFILE))
  646. X#endif
  647. X    {
  648. X        puts ("Can't rename new file");
  649. X        goto unlock;
  650. X    }
  651. X#endif    /* NDEBUG */
  652. X#ifndef    NDEBUG
  653. X    (void) unlink (".grplock");
  654. X#else
  655. X    (void) unlink (GRPLOCK);
  656. X#endif
  657. X    exit (0);
  658. X    /*NOTREACHED*/
  659. X
  660. Xfailure:
  661. X    puts ("Permission denied.");
  662. Xunlock:
  663. X    if (lockfd >= 0)
  664. X        (void) unlink (GRPLOCK);
  665. X
  666. X    (void) unlink (NGRPFILE);
  667. X    exit (1);
  668. X    /*NOTREACHED*/
  669. X
  670. Xtoomany:
  671. X    puts ("Too many tries; try again later.");
  672. X    exit (1);
  673. X    /*NOTREACHED*/
  674. X}
  675. X
  676. X/*
  677. X * die - set or reset termio modes.
  678. X *
  679. X *    die() is called before processing begins.  signal() is then
  680. X *    called with die() as the signal handler.  If signal later
  681. X *    calls die() with a signal number, the terminal modes are
  682. X *    then reset.
  683. X */
  684. X
  685. Xvoid    die (killed)
  686. Xint    killed;
  687. X{
  688. X#ifdef    BSD
  689. X    static    struct    sgtty    sgtty;
  690. X
  691. X    if (killed)
  692. X        stty (0, &sgtty);
  693. X    else
  694. X        gtty (0, &sgtty);
  695. X#else
  696. X    static    struct    termio    sgtty;
  697. X
  698. X    if (killed)
  699. X        ioctl (0, TCSETA, &sgtty);
  700. X    else
  701. X        ioctl (0, TCGETA, &sgtty);
  702. X#endif
  703. X    if (killed) {
  704. X        putchar ('\n');
  705. X        fflush (stdout);
  706. X        exit (killed);
  707. X    }
  708. X}
  709. SHAR_EOF
  710. if test 7260 -ne "`wc -c < 'gpmain.c'`"
  711. then
  712.     echo shar: "error transmitting 'gpmain.c'" '(should have been 7260 characters)'
  713. fi
  714. fi
  715. echo shar: "extracting 'grent.c'" '(1297 characters)'
  716. if test -f 'grent.c'
  717. then
  718.     echo shar: "will not over-write existing file 'grent.c'"
  719. else
  720. sed 's/^X//' << \SHAR_EOF > 'grent.c'
  721. X/*
  722. X * Copyright 1990, John F. Haugh II
  723. X * All rights reserved.
  724. X *
  725. X * Non-commercial distribution permitted.  You must provide this source
  726. X * code in any distribution.  This notice must remain intact.
  727. X */
  728. X
  729. X#include <stdio.h>
  730. X#include <grp.h>
  731. X#include <string.h>
  732. X#include "config.h"
  733. X#ifdef    DBM
  734. X#include <dbm.h>
  735. X#endif
  736. X
  737. X#ifndef    lint
  738. Xstatic    char    _sccsid[] = "@(#)grent.c    1.1    08:14:07    6/20/90";
  739. X#endif
  740. X
  741. X#define    NFIELDS    4
  742. X#define    MAXMEM    1024
  743. X
  744. Xstatic    char    grpbuf[4*BUFSIZ];
  745. Xstatic    char    *grpfields[NFIELDS];
  746. Xstatic    char    *members[MAXMEM+1];
  747. X
  748. Xstatic char **
  749. Xlist (s)
  750. Xchar    *s;
  751. X{
  752. X    int    nmembers = 0;
  753. X
  754. X    while (*s) {
  755. X        members[nmembers++] = s;
  756. X        if (s = strchr (s, ','))
  757. X            *s++ = '\0';
  758. X    }
  759. X    members[nmembers] = (char *) 0;
  760. X    return members;
  761. X}
  762. X
  763. Xstruct    group    *sgetgrent (buf)
  764. Xchar    *buf;
  765. X{
  766. X    int    i;
  767. X    char    *cp;
  768. X    static    struct    group    grent;
  769. X
  770. X    strncpy (grpbuf, buf, sizeof grpbuf);
  771. X    grpbuf[sizeof grpbuf - 1] = '\0';
  772. X    if (cp = strrchr (grpbuf, '\n'))
  773. X        *cp = '\0';
  774. X
  775. X    for (cp = grpbuf, i = 0;i < NFIELDS && cp;i++) {
  776. X        grpfields[i] = cp;
  777. X        if (cp = strchr (cp, ':'))
  778. X            *cp++ = 0;
  779. X    }
  780. X    if (i < (NFIELDS-1) || *grpfields[2] == '\0')
  781. X        return ((struct group *) 0);
  782. X
  783. X    grent.gr_name = grpfields[0];
  784. X    grent.gr_passwd = grpfields[1];
  785. X    grent.gr_gid = atoi (grpfields[2]);
  786. X    grent.gr_mem = list (grpfields[3]);
  787. X
  788. X    return (&grent);
  789. X}
  790. SHAR_EOF
  791. if test 1297 -ne "`wc -c < 'grent.c'`"
  792. then
  793.     echo shar: "error transmitting 'grent.c'" '(should have been 1297 characters)'
  794. fi
  795. fi
  796. echo shar: "extracting 'password.c'" '(1939 characters)'
  797. if test -f 'password.c'
  798. then
  799.     echo shar: "will not over-write existing file 'password.c'"
  800. else
  801. sed 's/^X//' << \SHAR_EOF > 'password.c'
  802. X/*
  803. X * Copyright 1988,1989,1990, John F. Haugh II
  804. X * All rights reserved.
  805. X *
  806. X * Non-commercial distribution permitted.  You must provide this source
  807. X * code in any distribution.  This notice must remain intact.
  808. X */
  809. X
  810. X#include <stdio.h>
  811. X#ifndef    BSD
  812. X#include <string.h>
  813. X#include <memory.h>
  814. X#else
  815. X#include <strings.h>
  816. X#define    strchr    index
  817. X#define    strrchr    rindex
  818. X#endif
  819. X#ifndef    BSD
  820. X#include <termio.h>
  821. X#else
  822. X#include <sgtty.h>
  823. X#endif
  824. X
  825. X#include <fcntl.h>
  826. X
  827. X/*
  828. X * password - prompt for password and return entry
  829. X *
  830. X *    Need to fake up getpass().  Returns TRUE if a password
  831. X *    was successfully input, and FALSE otherwise, including
  832. X *    EOF on input or ioctl() failure.  pass is not modified
  833. X *    on failure.  The input length limit may be set by
  834. X *    changing the value of PASSLIMIT.
  835. X */
  836. X
  837. X#ifndef    lint
  838. Xstatic    char    _sccsid[] = "@(#)password.c    2.2    09:38:59    6/22/90";
  839. X#endif
  840. X
  841. X#define    PASSLIMIT    20
  842. X
  843. Xint    password (prompt, pass)
  844. Xchar    *prompt;
  845. Xchar    *pass;
  846. X{
  847. X    char    buf[BUFSIZ];
  848. X    char    *cp;
  849. X    int    eof;
  850. X    int    ttyopened = 0;
  851. X#ifndef    BSD
  852. X    struct    termio    termio;
  853. X    struct    termio    save;
  854. X#else
  855. X    struct    sgttyb    termio ;
  856. X    struct    sgttyb    save ;
  857. X#endif
  858. X    FILE    *fp;
  859. X
  860. X    if ((fp = fopen ("/dev/tty", "r")) == (FILE *) 0)
  861. X        fp = stdin;
  862. X    else
  863. X        ttyopened = 1;
  864. X
  865. X#ifndef    BSD
  866. X    if (ioctl (fileno (fp), TCGETA, &termio))
  867. X        return (0);
  868. X#else
  869. X    if ( gtty( fileno(fp), &termio ) )
  870. X        return (0);
  871. X#endif
  872. X
  873. X    save = termio;
  874. X#ifndef    BSD
  875. X    termio.c_lflag &= ~(ECHO|ECHOE|ECHOK);
  876. X    ioctl (fileno (fp), TCSETAF, &termio);
  877. X#else
  878. X    termio.sg_flags &= ~ECHO ;
  879. X    stty( fileno( fp ), termio ) ;
  880. X#endif
  881. X
  882. X    fputs (prompt, stdout);
  883. X    eof = fgets (buf, BUFSIZ, fp) == (char *) 0 || feof (fp) || ferror (fp);
  884. X    putchar ('\n');
  885. X
  886. X#ifndef    BSD
  887. X    ioctl (fileno (fp), TCSETAF, &save);
  888. X#else
  889. X    stty( fileno( fp ), save ) ;
  890. X#endif
  891. X
  892. X    if (! eof) {
  893. X        buf[PASSLIMIT] = '\0';
  894. X        if ((cp = strchr (buf, '\n')) || (cp = strchr (buf, '\r')))
  895. X            *cp = '\0'; 
  896. X
  897. X        (void) strcpy (pass, buf);
  898. X    }
  899. X    if (ttyopened)
  900. X        fclose (fp);
  901. X
  902. X    return (! eof);
  903. X}
  904. SHAR_EOF
  905. if test 1939 -ne "`wc -c < 'password.c'`"
  906. then
  907.     echo shar: "error transmitting 'password.c'" '(should have been 1939 characters)'
  908. fi
  909. fi
  910. exit 0
  911. #    End of shell archive
  912. -- 
  913. John F. Haugh II                             UUCP: ...!cs.utexas.edu!rpp386!jfh
  914. Ma Bell: (512) 832-8832                           Domain: jfh@rpp386.cactus.org
  915.  
  916.                                             Proud Pilot of RS/6000 Serial #1472
  917.