home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1992 March / Source_Code_CD-ROM_Walnut_Creek_March_1992.iso / usenet / altsrcs / 3 / 3486 < prev    next >
Encoding:
Internet Message Format  |  1991-06-15  |  43.4 KB

  1. From: jfh@rpp386.cactus.org (John F Haugh II)
  2. Newsgroups: alt.sources
  3. Subject: Shadow Login Suite, patch 5
  4.      as well as support for rlogin on SCO Xenix
  5. Message-ID: <19383@rpp386.cactus.org>
  6. Date: 14 Jun 91 03:38:19 GMT
  7. Distribution: alt
  8. Organization: River Parishes Programming, Austin TX
  9. Lines: 2012
  10.  
  11. The three new commands that were added in patch 4 had a few problems, and
  12. this patch addresses them.  One important change is that the directory
  13. copy, move, and delete functions are better supported now.  It is now
  14. possible to rename someones home directory and have it copied to a completely
  15. different device.
  16.  
  17. The most significant changes are for the support of "rlogin" on SCO Xenix.
  18. These changes were made by Chip Rosenthal, as were many of the other
  19. changes in this particular set of patches.
  20.  
  21. In the "Things to Come" catagory, the groupadd, groupdel, and groupmod
  22. commands [ see your SVR4 documentation for more details ] have been
  23. finished and will be part of patch 6, due out in a week or two.  Also
  24. in "Things to Come" are changes to these 6 commands that will allow
  25. you to utilize the code without being forced to have all of the other
  26. strange modifications that I've made.  That is, you can stick with
  27. just plain old /etc/passwd and /etc/group and still use the 6 more
  28. recently added commands.  I think I went overboard making those commands
  29. only usable with the extensions that I've added ...
  30.  
  31. A gentleman from Down Under is currently working on SunOS patches, and
  32. swears to have it running on SunOS.  This is great news and I am
  33. anxiously waiting those results.
  34. --
  35. Prereq: 4
  36. *** rel3/patchlevel.h    Thu Jun 13 21:28:41 1991
  37. --- patchlevel.h    Thu Jun 13 10:06:38 1991
  38. ***************
  39. *** 10,13 ****
  40.    */
  41.   
  42.   #define    RELEASE        3
  43. ! #define    PATCHLEVEL    4
  44. --- 10,14 ----
  45.    */
  46.   
  47.   #define    RELEASE        3
  48. ! #define    PATCHLEVEL    5
  49. ! #define    VERSION        "3.0.5"
  50. *** rel3/Makefile    Thu Jun 13 21:28:42 1991
  51. --- Makefile    Thu Jun 13 21:16:50 1991
  52. ***************
  53. *** 8,16 ****
  54.   # and conspicuously displayed on all copies of object code or
  55.   # distribution media.
  56.   #
  57. ! #    @(#)Makefile    3.11    11:11:42  - Shadow password system
  58.   #
  59. ! #    @(#)Makefile    3.11    11:11:42    6/7/91
  60.   #
  61.   SHELL = /bin/sh
  62.   
  63. --- 8,16 ----
  64.   # and conspicuously displayed on all copies of object code or
  65.   # distribution media.
  66.   #
  67. ! #    @(#)Makefile    3.15    20:52:45  - Shadow password system
  68.   #
  69. ! #    @(#)Makefile    3.15    20:52:45    6/13/91
  70.   #
  71.   SHELL = /bin/sh
  72.   
  73. ***************
  74. *** 26,31 ****
  75. --- 26,35 ----
  76.   # LOGINDIR = /bin
  77.   LOGINDIR = /etc
  78.   
  79. + # Define any special libraries required to access the directory routines.
  80. + # NDIR = -lndir
  81. + NDIR = -lx
  82.   # Pick your favorite C compiler and tags command
  83.   CC = cc
  84.   TAGS = ctags
  85. ***************
  86. *** 39,44 ****
  87. --- 43,57 ----
  88.   RANLIB = ranlib
  89.   # RANLIB = echo
  90.   
  91. + # Configuration Flags
  92. + #
  93. + #    LIBS - system libraries
  94. + #        -lsocket - needed for TCP/IP and possibly SYSLOG
  95. + #        -ldbm or -lndbm - needed for DBM support
  96. + #        -lcrypt - needed for SCO crypt() functions
  97. + #    CFLAGS - C compiler flags
  98. + #        -DLAI_TCP - needed for SCO Xenix Lachman TCP/IP
  99.   # Flags for SCO Xenix/386
  100.   CFLAGS = -O -M3 -g $(OS)
  101.   LIBS = -lcrypt -lndbm
  102. ***************
  103. *** 128,134 ****
  104.       chfn.c chsh.c chage.c rad64.c encrypt.c chpasswd.c shadowio.c pwio.c \
  105.       newusers.c groupio.c fields.c pwdbm.c grpack.c grdbm.c sppack.c \
  106.       spdbm.c dpmain.c gshadow.c gsdbm.c gspack.c sgroupio.c useradd.c \
  107. !     userdel.c patchlevel.h usermod.c
  108.   
  109.   FILES1 = README newgrp.c Makefile config.h pwunconv.c obscure.c age.c id.c \
  110.       patchlevel.h
  111. --- 141,147 ----
  112.       chfn.c chsh.c chage.c rad64.c encrypt.c chpasswd.c shadowio.c pwio.c \
  113.       newusers.c groupio.c fields.c pwdbm.c grpack.c grdbm.c sppack.c \
  114.       spdbm.c dpmain.c gshadow.c gsdbm.c gspack.c sgroupio.c useradd.c \
  115. !     userdel.c patchlevel.h usermod.c copydir.c mkrmdir.c
  116.   
  117.   FILES1 = README newgrp.c Makefile config.h pwunconv.c obscure.c age.c id.c \
  118.       patchlevel.h
  119. ***************
  120. *** 149,155 ****
  121.   
  122.   FILES7 = groupio.c shadowio.c sgroupio.c
  123.   
  124. ! FILES8 = useradd.c userdel.c usermod.c
  125.   
  126.   MAN_1 = chage.1 chfn.1 chsh.1 login.1 passwd.1 su.1
  127.   MAN_3 = shadow.3
  128. --- 162,168 ----
  129.   
  130.   FILES7 = groupio.c shadowio.c sgroupio.c
  131.   
  132. ! FILES8 = useradd.c userdel.c usermod.c copydir.c mkrmdir.c
  133.   
  134.   MAN_1 = chage.1 chfn.1 chsh.1 login.1 passwd.1 su.1
  135.   MAN_3 = shadow.3
  136. ***************
  137. *** 333,355 ****
  138.   id.lint: id.c
  139.       $(LINT) $(LINTFLAGS) id.c > id.lint
  140.   
  141. ! useradd: useradd.o libshadow.a
  142. !     $(CC) -o useradd $(LDFLAGS) useradd.o libshadow.a $(LIBS)
  143.   
  144. ! useradd.lint: useradd.c
  145. !     $(LINT) $(LINTFLAGS) useradd.c > useradd.lint
  146. ! userdel: userdel.o libshadow.a
  147. !     $(CC) -o userdel $(LDFLAGS) userdel.o libshadow.a $(LIBS)
  148. ! userdel.lint: userdel.c
  149. !     $(LINT) $(LINTFLAGS) userdel.c > userdel.lint
  150. ! usermod: usermod.o libshadow.a
  151. !     $(CC) -o usermod $(LDFLAGS) usermod.o libshadow.a $(LIBS)
  152.   
  153. ! usermod.lint: usermod.c
  154. !     $(LINT) $(LINTFLAGS) usermod.c > usermod.lint
  155.   
  156.   sulog.o: config.h
  157.   
  158. --- 346,371 ----
  159.   id.lint: id.c
  160.       $(LINT) $(LINTFLAGS) id.c > id.lint
  161.   
  162. ! useradd: useradd.o copydir.o mkrmdir.o libshadow.a
  163. !     $(CC) -o useradd $(LDFLAGS) useradd.o copydir.o mkrmdir.o \
  164. !         libshadow.a $(LIBS) $(NDIR)
  165.   
  166. ! useradd.lint: useradd.c copydir.c mkrmdir.c
  167. !     $(LINT) $(LINTFLAGS) useradd.c copydir.c mkrmdir.c > useradd.lint
  168. ! userdel: userdel.o copydir.o mkrmdir.o libshadow.a
  169. !     $(CC) -o userdel $(LDFLAGS) userdel.o copydir.o mkrmdir.o \
  170. !         libshadow.a $(LIBS) $(NDIR)
  171. ! userdel.lint: userdel.c copydir.c mkrmdir.c
  172. !     $(LINT) $(LINTFLAGS) userdel.c copydir.c mkrmdir.c > userdel.lint
  173. ! usermod: usermod.o copydir.o mkrmdir.o libshadow.a
  174. !     $(CC) -o usermod $(LDFLAGS) usermod.o copydir.o mkrmdir.o \
  175. !         libshadow.a $(LIBS) $(NDIR)
  176.   
  177. ! usermod.lint: usermod.c copydir.c mkrmdir.c
  178. !     $(LINT) $(LINTFLAGS) usermod.c copydir.c mkrmdir.c > usermod.lint
  179.   
  180.   sulog.o: config.h
  181.   
  182. ***************
  183. *** 464,466 ****
  184. --- 480,483 ----
  185.   
  186.   login.sh.9: $(DOCS) Makefile
  187.       shar -a $(DOCS) > login.sh.9
  188. *** rel3/chpasswd.c    Thu Jun 13 21:27:57 1991
  189. --- chpasswd.c    Mon Jun 10 10:14:05 1991
  190. ***************
  191. *** 28,39 ****
  192.   #endif
  193.   
  194.   #ifndef    lint
  195. ! static    char    sccsid[] = "@(#)chpasswd.c    3.3    09:07:09    5/28/91";
  196.   #endif
  197.   
  198.   char    *Prog;
  199.   
  200.   extern    char    *pw_encrypt();
  201.   
  202.   /* 
  203.    * If it weren't for the different structures and differences in how
  204. --- 28,40 ----
  205.   #endif
  206.   
  207.   #ifndef    lint
  208. ! static    char    sccsid[] = "@(#)chpasswd.c    3.4    08:57:30    6/10/91";
  209.   #endif
  210.   
  211.   char    *Prog;
  212.   
  213.   extern    char    *pw_encrypt();
  214. + extern    char    *l64a();
  215.   
  216.   /* 
  217.    * If it weren't for the different structures and differences in how
  218. *** rel3/config.h    Thu Jun 13 21:28:42 1991
  219. --- config.h    Thu Jun 13 10:06:41 1991
  220. ***************
  221. *** 12,18 ****
  222.   /*
  223.    * Configuration file for login.
  224.    *
  225. !  *    @(#)config.h    3.8    11:11:17    6/7/91
  226.    */
  227.   
  228.   /*
  229. --- 12,18 ----
  230.   /*
  231.    * Configuration file for login.
  232.    *
  233. !  *    @(#)config.h    3.10    10:04:15    6/13/91
  234.    */
  235.   
  236.   /*
  237. ***************
  238. *** 223,228 ****
  239. --- 223,236 ----
  240.   #define    NDBM    /* */
  241.   
  242.   /*
  243. +  * Enable RLOGIN to support the "-r" and "-h" options.
  244. +  * If your /etc/utmp provides for a host name, enable UT_HOST.
  245. +  */
  246. + #define RLOGIN
  247. + #undef UT_HOST
  248. + /*
  249.    * Define file name for sulog.  If SULOG is not defined, there will be
  250.    * no logging.  This is NOT a good idea ...  We also define other file
  251.    * names.
  252. ***************
  253. *** 238,243 ****
  254. --- 246,253 ----
  255.   #define    GRPFILE    "/etc/group"
  256.   #define    OGRPFILE "/etc/group-"
  257.   #define    NGRPFILE "/etc/ngroup"
  258. + #define    OGSHADOW "/etc/gshadow-"
  259. + #define    NGSHADOW "/etc/ngshadow"
  260.   
  261.   /*
  262.    * Define PWDLOCK to be a locking semaphore for updating the password
  263. ***************
  264. *** 247,252 ****
  265. --- 257,263 ----
  266.   #define    PWDLOCK    "/etc/passwd.lock"
  267.   #define    GRPLOCK "/etc/group.lock"
  268.   #define    SPWLOCK "/etc/shadow.lock"
  269. + #define    SGRPLOCK "/etc/gshadow.lock"
  270.   
  271.   /*
  272.    * Define USE_SYSLOG if you want to have SYSLOG functions included
  273. ***************
  274. *** 256,261 ****
  275. --- 267,280 ----
  276.   
  277.   #define    USE_SYSLOG
  278.   #undef    SULOGONLY
  279. + /*
  280. +  * Select one of the following
  281. +  */
  282. + #define DIR_XENIX    /* include <sys/ndir.h>, use (struct direct)    */
  283. + /* #define DIR_BSD    /* include <ndir.h>, use (struct direct)    */
  284. + /* #define DIR_SYSV    /* include <dirent.h>, use (struct dirent)    */
  285.   
  286.   /*
  287.    * Wierd stuff follows ...
  288. *** /dev/null    Thu Jun 13 21:28:57 1991
  289. --- copydir.c    Thu Jun 13 10:09:40 1991
  290. ***************
  291. *** 0 ****
  292. --- 1,372 ----
  293. + /*
  294. +  * Copyright 1991, John F. Haugh II
  295. +  * An unpublished work.
  296. +  * All rights reserved.
  297. +  *
  298. +  * Permission is granted to copy and create derivative works for any
  299. +  * non-commercial purpose, provided this copyright notice is preserved
  300. +  * in all copies of source code, or included in human readable form
  301. +  * and conspicuously displayed on all copies of object code or
  302. +  * distribution media.
  303. +  */
  304. + #include <sys/types.h>
  305. + #include <sys/stat.h>
  306. + #include "config.h"
  307. + #ifdef DIR_XENIX
  308. + #include <sys/ndir.h>
  309. + #define DIRECT direct
  310. + #endif
  311. + #ifdef DIR_BSD
  312. + #include <ndir.h>
  313. + #define DIRECT direct
  314. + #endif
  315. + #ifdef DIR_SYSV
  316. + #include <dirent.h>
  317. + #define DIRECT dirent
  318. + #endif
  319. + #include <fcntl.h>
  320. + #include <stdio.h>
  321. + #ifndef lint
  322. + static    char    sccsid[] = "@(#)copydir.c    3.1    10:09:26    6/13/91";
  323. + #endif
  324. + #ifndef    S_ISDIR
  325. + #define    S_ISDIR(x)    (((x)&S_IFMT)==S_IFDIR)
  326. + #endif
  327. + #ifndef    S_ISREG
  328. + #define    S_ISREG(x)    (((x)&S_IFMT)==S_IFREG)
  329. + #endif
  330. + static    char    *src_orig;
  331. + static    char    *dst_orig;
  332. + struct    link_name {
  333. +     int    ln_dev;
  334. +     int    ln_ino;
  335. +     int    ln_count;
  336. +     char    *ln_name;
  337. +     struct    link_name *ln_next;
  338. + };
  339. + static    struct    link_name *links;
  340. + /*
  341. +  * remove_link - delete a link from the link list
  342. +  */
  343. + void
  344. + remove_link (link)
  345. + struct    link_name *link;
  346. + {
  347. +     struct link_name *lp;
  348. +     if (links == link) {
  349. +         links = link->ln_next;
  350. +         free (link->ln_name);
  351. +         free (link);
  352. +         return;
  353. +     }
  354. +     for (lp = links;lp;lp = lp->ln_next)
  355. +         if (lp->ln_next == link)
  356. +             break;
  357. +     if (! lp)
  358. +         return;
  359. +     lp->ln_next = lp->ln_next->ln_next;
  360. +     free (link->ln_name);
  361. +     free (link);
  362. + }
  363. + /*
  364. +  * check_link - see if a file is really a link
  365. +  */
  366. + struct link_name *
  367. + check_link (name, sb)
  368. + char    *name;
  369. + struct    stat    *sb;
  370. + {
  371. +     struct    link_name *lp;
  372. +     int    src_len;
  373. +     int    dst_len;
  374. +     int    name_len;
  375. +     char    *malloc ();
  376. +     for (lp = links;lp;lp = lp->ln_next)
  377. +         if (lp->ln_dev == sb->st_dev && lp->ln_ino == sb->st_ino)
  378. +             return lp;
  379. +     if (sb->st_nlink == 1)
  380. +         return 0;
  381. +     lp = (struct link_name *) malloc (sizeof *lp);
  382. +     src_len = strlen (src_orig);
  383. +     dst_len = strlen (dst_orig);
  384. +     name_len = strlen (name);
  385. +     lp->ln_dev = sb->st_dev;
  386. +     lp->ln_ino = sb->st_ino;
  387. +     lp->ln_count = sb->st_nlink;
  388. +     lp->ln_name = malloc (name_len - src_len + dst_len + 1);
  389. +     sprintf (lp->ln_name, "%s%s", dst_orig, name + src_len);
  390. +     lp->ln_next = links;
  391. +     links = lp;
  392. +     return 0;
  393. + }
  394. + /*
  395. +  * copy_tree - copy files in a directory tree
  396. +  *
  397. +  *    copy_tree() walks a directory tree and copies ordinary files
  398. +  *    as it goes.
  399. +  */
  400. + int
  401. + copy_tree (src_root, dst_root, uid, gid)
  402. + char    *src_root;
  403. + char    *dst_root;
  404. + int    uid;
  405. + int    gid;
  406. + {
  407. +     char    src_name[BUFSIZ];
  408. +     char    dst_name[BUFSIZ];
  409. +     char    buf[BUFSIZ];
  410. +     int    ifd;
  411. +     int    ofd;
  412. +     int    err = 0;
  413. +     int    cnt;
  414. +     int    set_orig = 0;
  415. +     struct    DIRECT    *ent;
  416. +     struct    stat    sb;
  417. +     struct    link_name *lp;
  418. +     DIR    *dir;
  419. +     /*
  420. +      * Make certain both directories exist.  This routine is called
  421. +      * after the home directory is created, or recursively after the
  422. +      * target is created.  It assumes the target directory exists.
  423. +      */
  424. +     if (access (src_root, 0) != 0 || access (dst_root, 0) != 0)
  425. +         return -1;
  426. +     /*
  427. +      * Open the source directory and read each entry.  Every file
  428. +      * entry in the directory is copied with the UID and GID set
  429. +      * to the provided values.  As an added security feature only
  430. +      * regular files (and directories ...) are copied, and no file
  431. +      * is made set-ID.
  432. +      */
  433. +     if (! (dir = opendir (src_root)))
  434. +         return -1;
  435. +     if (src_orig == 0) {
  436. +         src_orig = src_root;
  437. +         dst_orig = dst_root;
  438. +         set_orig++;
  439. +     }
  440. +     while (ent = readdir (dir)) {
  441. +         /*
  442. +          * Skip the "." and ".." entries
  443. +          */
  444. +         if (strcmp (ent->d_name, ".") == 0 ||
  445. +                 strcmp (ent->d_name, "..") == 0)
  446. +             continue;
  447. +         /*
  448. +          * Make the filename for both the source and the
  449. +          * destination files.
  450. +          */
  451. +         if (strlen (src_root) + strlen (ent->d_name) + 2 > BUFSIZ) {
  452. +             err++;
  453. +             break;
  454. +         }
  455. +         sprintf (src_name, "%s/%s", src_root, ent->d_name);
  456. +         if (strlen (dst_root) + strlen (ent->d_name) + 2 > BUFSIZ) {
  457. +             err++;
  458. +             break;
  459. +         }
  460. +         sprintf (dst_name, "%s/%s", dst_root, ent->d_name);
  461. +         if (stat (src_name, &sb) == -1)
  462. +             continue;
  463. +         if (S_ISDIR (sb.st_mode)) {
  464. +             /*
  465. +              * Create a new target directory, make it owned by
  466. +              * the user and then recursively copy that directory.
  467. +              */
  468. +             mkdir (dst_name, sb.st_mode & 0777);
  469. +             chown (dst_name, uid == -1 ? sb.st_uid:uid,
  470. +                 gid == -1 ? sb.st_gid:gid);
  471. +             if (copy_tree (src_name, dst_name, uid, gid)) {
  472. +                 err++;
  473. +                 break;
  474. +             }
  475. +             continue;
  476. +         }
  477. +         /*
  478. +          * See if this is a previously copied link
  479. +          */
  480. +         if (lp = check_link (src_name, &sb)) {
  481. +             if (link (lp->ln_name, dst_name)) {
  482. +                 err++;
  483. +                 break;
  484. +             }
  485. +             if (unlink (src_name)) {
  486. +                 err++;
  487. +                 break;
  488. +             }
  489. +             if (--lp->ln_count <= 0)
  490. +                 remove_link (lp);
  491. +             continue;
  492. +         }
  493. +         /*
  494. +          * Deal with FIFOs and special files.  The user really
  495. +          * shouldn't have any of these, but it seems like it
  496. +          * would be nice to copy everything ...
  497. +          */
  498. +         if (! S_ISREG (sb.st_mode)) {
  499. +             if (mknod (dst_name, sb.st_mode & ~07777, sb.st_rdev) ||
  500. +                 chown (dst_name, uid == -1 ? sb.st_uid:uid,
  501. +                     gid == -1 ? sb.st_gid:gid) ||
  502. +                     chmod (dst_name, sb.st_mode & 07777)) {
  503. +                 err++;
  504. +                 break;
  505. +             }
  506. +             continue;
  507. +         }
  508. +         /*
  509. +          * Create the new file and copy the contents.  The new
  510. +          * file will be owned by the provided UID and GID values.
  511. +          */
  512. +         if ((ifd = open (src_name, O_RDONLY)) < 0) {
  513. +             err++;
  514. +             break;
  515. +         }
  516. +         if ((ofd = open (dst_name, O_WRONLY|O_CREAT, 0)) < 0 ||
  517. +             chown (dst_name, uid == -1 ? sb.st_uid:uid,
  518. +                     gid == -1 ? sb.st_gid:gid) ||
  519. +                 chmod (dst_name, sb.st_mode & 07777)) {
  520. +             close (ifd);
  521. +             err++;
  522. +             break;
  523. +         }
  524. +         while ((cnt = read (ifd, buf, sizeof buf)) > 0) {
  525. +             if (write (ofd, buf, cnt) != cnt) {
  526. +                 cnt = -1;
  527. +                 break;
  528. +             }
  529. +         }
  530. +         close (ifd);
  531. +         close (ofd);
  532. +         if (cnt == -1) {
  533. +             err++;
  534. +             break;
  535. +         }
  536. +     }
  537. +     closedir (dir);
  538. +     if (set_orig) {
  539. +         src_orig = 0;
  540. +         dst_orig = 0;
  541. +     }
  542. +     return err ? -1:0;
  543. + }
  544. + /*
  545. +  * remove_tree - remove files in a directory tree
  546. +  *
  547. +  *    remove_tree() walks a directory tree and deletes all the files
  548. +  *    and directories.
  549. +  */
  550. + int
  551. + remove_tree (root)
  552. + char    *root;
  553. + {
  554. +     char    new_name[BUFSIZ];
  555. +     int    err = 0;
  556. +     struct    DIRECT    *ent;
  557. +     struct    stat    sb;
  558. +     DIR    *dir;
  559. +     /*
  560. +      * Make certain the directory exists.
  561. +      */
  562. +     if (access (root, 0) != 0)
  563. +         return -1;
  564. +     /*
  565. +      * Open the source directory and read each entry.  Every file
  566. +      * entry in the directory is copied with the UID and GID set
  567. +      * to the provided values.  As an added security feature only
  568. +      * regular files (and directories ...) are copied, and no file
  569. +      * is made set-ID.
  570. +      */
  571. +     dir = opendir (root);
  572. +     while (ent = readdir (dir)) {
  573. +         /*
  574. +          * Skip the "." and ".." entries
  575. +          */
  576. +         if (strcmp (ent->d_name, ".") == 0 ||
  577. +                 strcmp (ent->d_name, "..") == 0)
  578. +             continue;
  579. +         /*
  580. +          * Make the filename for the current entry.
  581. +          */
  582. +         if (strlen (root) + strlen (ent->d_name) + 2 > BUFSIZ) {
  583. +             err++;
  584. +             break;
  585. +         }
  586. +         sprintf (new_name, "%s/%s", root, ent->d_name);
  587. +         if (stat (new_name, &sb) == -1)
  588. +             continue;
  589. +         if (S_ISDIR (sb.st_mode)) {
  590. +             /*
  591. +              * Recursively delete this directory.
  592. +              */
  593. +             if (remove_tree (new_name)) {
  594. +                 err++;
  595. +                 break;
  596. +             }
  597. +             if (rmdir (new_name)) {
  598. +                 err++;
  599. +                 break;
  600. +             }
  601. +             continue;
  602. +         }
  603. +         unlink (new_name);
  604. +     }
  605. +     closedir (dir);
  606. +     return err ? -1:0;
  607. + }
  608. *** rel3/getpass.c    Thu Jun 13 21:27:59 1991
  609. --- getpass.c    Mon Jun 10 10:02:54 1991
  610. ***************
  611. *** 9,15 ****
  612.    * distribution media.
  613.    */
  614.   
  615. ! #include <sys/signal.h>
  616.   #include <stdio.h>
  617.   #include "config.h"
  618.   
  619. --- 9,15 ----
  620.    * distribution media.
  621.    */
  622.   
  623. ! #include <signal.h>
  624.   #include <stdio.h>
  625.   #include "config.h"
  626.   
  627. ***************
  628. *** 22,28 ****
  629.   #endif
  630.   
  631.   #ifndef    lint
  632. ! static    char    sccsid[] = "@(#)getpass.c    3.3    09:09:36    5/28/91";
  633.   #endif
  634.   
  635.   /*
  636. --- 22,28 ----
  637.   #endif
  638.   
  639.   #ifndef    lint
  640. ! static    char    sccsid[] = "@(#)getpass.c    3.4    08:59:38    6/10/91";
  641.   #endif
  642.   
  643.   /*
  644. *** rel3/lmain.c    Thu Jun 13 21:28:01 1991
  645. --- lmain.c    Thu Jun 13 10:06:44 1991
  646. ***************
  647. *** 44,52 ****
  648.   #endif
  649.   
  650.   #ifndef    lint
  651. ! static    char    sccsid[] = "@(#)lmain.c    3.5    09:07:32    5/28/91";
  652.   #endif
  653.   
  654.   #ifndef    ERASECHAR
  655.   #define    ERASECHAR    '\b'        /* backspace */
  656.   #endif
  657. --- 44,55 ----
  658.   #endif
  659.   
  660.   #ifndef    lint
  661. ! static    char    sccsid[] = "@(#)lmain.c    3.10    10:04:50    6/13/91";
  662.   #endif
  663.   
  664. +                     /* danger - side effects */
  665. + #define STRFCPY(A,B)    strncpy((A), (B), sizeof(A)), *((A)+sizeof(A)-1) = '\0'
  666.   #ifndef    ERASECHAR
  667.   #define    ERASECHAR    '\b'        /* backspace */
  668.   #endif
  669. ***************
  670. *** 55,62 ****
  671.   #define    KILLCHAR    '\025'        /* control U */
  672.   #endif
  673.   
  674. ! #ifdef    UT_HOST
  675. ! char    host[BUFSIZ];
  676.   #endif
  677.   #ifdef    HUSHLOGIN
  678.   int    hushed;
  679. --- 58,66 ----
  680.   #define    KILLCHAR    '\025'        /* control U */
  681.   #endif
  682.   
  683. ! #ifdef    RLOGIN
  684. ! char    host[128];
  685. ! char    term[128] = "TERM=";
  686.   #endif
  687.   #ifdef    HUSHLOGIN
  688.   int    hushed;
  689. ***************
  690. *** 69,74 ****
  691. --- 73,79 ----
  692.   int    rflg;
  693.   int    fflg;
  694.   int    hflg;
  695. + int    preauth_flag;
  696.   #ifndef    BSD
  697.   struct    termio    termio;
  698.   #endif
  699. ***************
  700. *** 114,120 ****
  701.   
  702.   #ifdef    TZ
  703.   FILE    *tzfile;
  704. ! char    tzbuf[32] = TZ;
  705.   #endif
  706.   
  707.   #ifndef    ALARM
  708. --- 119,125 ----
  709.   
  710.   #ifdef    TZ
  711.   FILE    *tzfile;
  712. ! char    tzbuf[BUFSIZ] = TZ;
  713.   #endif
  714.   
  715.   #ifndef    ALARM
  716. ***************
  717. *** 153,172 ****
  718.   
  719.   /*
  720.    * usage - print login command usage and exit
  721.    */
  722.   
  723.   usage ()
  724.   {
  725.       fprintf (stderr, "usage: login [ -p ] [ name ]\n");
  726. ! #ifdef    UT_HOST
  727. !     fprintf (stderr, "       login -r name\n");
  728. !     fprintf (stderr, "       login [ -p ] -f name [ -h host ]\n");
  729.   #else
  730.       fprintf (stderr, "       login [ -p ] -f name\n");
  731. ! #endif
  732.       exit (1);
  733.   }
  734.   
  735.   /*
  736.    * login - create a new login session for a user
  737.    *
  738. --- 158,224 ----
  739.   
  740.   /*
  741.    * usage - print login command usage and exit
  742. +  *
  743. +  * login [ name ]
  744. +  * login -r hostname    (for rlogind)
  745. +  * login -h hostname    (for telnetd, etc.)
  746. +  * login -f name    (for pre-authenticated login: datakit, xterm, etc.)
  747.    */
  748.   
  749.   usage ()
  750.   {
  751.       fprintf (stderr, "usage: login [ -p ] [ name ]\n");
  752. ! #ifdef    RLOGIN
  753. ! #ifdef    LAI_TCP
  754. !     fprintf (stderr, "       login -r rem_host rem_name name\n");
  755.   #else
  756. +     fprintf (stderr, "       login [ -p ] -r name\n");
  757. + #endif    /* LAI_TCP */
  758. +     fprintf (stderr, "       login [ -p ] [ -f name ] -h host\n");
  759. + #else
  760.       fprintf (stderr, "       login [ -p ] -f name\n");
  761. ! #endif    /* RLOGIN */
  762.       exit (1);
  763.   }
  764.   
  765. + #ifdef    RLOGIN
  766. + rlogin (host, name, namelen)
  767. + char    *host;
  768. + char    *name;
  769. + int    namelen;
  770. + {
  771. +     struct    passwd    *pwd;
  772. +     char    remote_name[32];
  773. +     char    *cp;
  774. +     get_remote_string (remote_name, sizeof remote_name);
  775. +     get_remote_string (name, namelen);
  776. +     get_remote_string (term + 5, sizeof term - 5);
  777. +     if (cp = strchr (term, '/'))
  778. +         *cp = '\0';
  779. +     if (! (pwd = getpwnam (name)))
  780. +         return 0;
  781. +     return ruserok (host, pwd->pw_uid == 0, remote_name, name);
  782. + }
  783. + get_remote_string (buf, size)
  784. + char    *buf;
  785. + int    size;
  786. + {
  787. +     for (;;) {
  788. +         if (read (0, buf, 1) != 1)
  789. +               exit (1);
  790. +         if (*buf == '\0')
  791. +             return;
  792. +         if (--size > 0)
  793. +             ++buf;
  794. +     }
  795. +     /*NOTREACHED*/
  796. + }
  797. + #endif
  798.   /*
  799.    * login - create a new login session for a user
  800.    *
  801. ***************
  802. *** 223,230 ****
  803.        */
  804.   
  805.       checkutmp (argc > 1 && argv[1][0] != '-');
  806. !     strncpy (tty, utent.ut_line, sizeof tty);
  807. !     tty[sizeof tty - 1] = '\0';
  808.   
  809.       if (Prog = strrchr (argv[0], '/'))
  810.           Prog++;
  811. --- 275,281 ----
  812.        */
  813.   
  814.       checkutmp (argc > 1 && argv[1][0] != '-');
  815. !     STRFCPY (tty, utent.ut_line);
  816.   
  817.       if (Prog = strrchr (argv[0], '/'))
  818.           Prog++;
  819. ***************
  820. *** 231,237 ****
  821.       else
  822.           Prog = argv[0];
  823.   
  824. ! #ifdef    UT_HOST
  825.       while ((flag = getopt (argc, argv, "pr:f:h:")) != EOF)
  826.   #else
  827.       while ((flag = getopt (argc, argv, "pf:")) != EOF)
  828. --- 282,310 ----
  829.       else
  830.           Prog = argv[0];
  831.   
  832. ! #ifdef LAI_TCP /*{*/
  833. !     /*
  834. !      * SCO/Lachman rlogind calls:
  835. !      *     /bin/login -r rem_host rem_name local_name"
  836. !      */
  837. !     if ( argc == 5 && strcmp(argv[1], "-r") == 0 ) {
  838. !         char rem_name[16];
  839. !         int root_user;
  840. !         STRFCPY(host, argv[2]);
  841. !         STRFCPY(rem_name, argv[3]);
  842. !         STRFCPY(name, argv[4]);
  843. !         root_user = ((pwd = getpwnam(name)) && pwd->pw_uid == 0);
  844. !         preauth_flag = ! ruserok(host, root_user, rem_name, name);
  845. !         pflg++;        /* in case SCO ever fixes rlogind */
  846. !         rflg++;
  847. !         argc = 1;
  848. !         argv[1] = NULL;
  849. !     }
  850. ! #endif /*}LAI_TCP*/
  851. ! #ifdef    RLOGIN
  852.       while ((flag = getopt (argc, argv, "pr:f:h:")) != EOF)
  853.   #else
  854.       while ((flag = getopt (argc, argv, "pf:")) != EOF)
  855. ***************
  856. *** 240,286 ****
  857.           switch (flag) {
  858.               case 'p': pflg++;
  859.                   break;
  860. !             case 'f': fflg++;
  861. !                 strncpy (name, optarg, sizeof name);
  862.                   break;
  863.   #ifdef    UT_HOST
  864. !             case 'r': rflg++;
  865. !                 strncpy (name, optarg, sizeof name);
  866.                   break;
  867. !             case 'h': hflg++;
  868. !                 strncpy (host, optarg, sizeof host);
  869. !                 strncpy (utmp.ut_host, host,
  870. !                             sizeof utmp.ut_host);
  871.                   break;
  872. ! #endif
  873.               default:
  874.                   usage ();
  875.           }
  876.       }
  877.   
  878.       /*
  879. !      * The -r option is not valid with any other flags
  880.        */
  881.   
  882. !     if (rflg && (hflg || fflg || pflg))
  883.           usage ();
  884. - #ifdef    USE_SYSLOG
  885. -     openlog (Prog, LOG_PID|LOG_CONS|LOG_NOWAIT, LOG_AUTH);
  886.   #endif
  887.   
  888.       /*
  889. !      * The -r and -f flags both require the real UID to be
  890. !      * zero.  No authentication may be required for these
  891. !      * flags, so the user must already be root.
  892.        */
  893.   
  894.       if ((rflg || fflg) && getuid () != 0) {
  895.   #ifdef    USE_SYSLOG
  896. !         closelog ();
  897.   #endif
  898. !         exit (1);        /* only root can use -r or -f */
  899. !     }
  900.       if (! isatty (0) || ! isatty (1) || ! isatty (2)) {
  901.   #ifdef    USE_SYSLOG
  902.           closelog ();
  903. --- 313,369 ----
  904.           switch (flag) {
  905.               case 'p': pflg++;
  906.                   break;
  907. !             case 'f':
  908. !                 fflg++;
  909. !                 preauth_flag++;
  910. !                 STRFCPY (name, optarg);
  911.                   break;
  912. + #ifdef    RLOGIN
  913. +             case 'r':
  914. +                 rflg++;
  915. +                 STRFCPY (host, optarg);
  916.   #ifdef    UT_HOST
  917. !                 STRFCPY (utent.ut_host, optarg);
  918. ! #endif    /*UT_HOST*/
  919. !                 if (rlogin (host, name, sizeof name))
  920. !                     preauth_flag++;
  921.                   break;
  922. !             case 'h':
  923. !                 hflg++;
  924. !                 STRFCPY (host, optarg);
  925. ! #ifdef    UT_HOST
  926. !                 STRFCPY (utent.ut_host, optarg);
  927. ! #endif    /*UT_HOST*/
  928.                   break;
  929. ! #endif    /*RLOGIN*/
  930.               default:
  931.                   usage ();
  932.           }
  933.       }
  934.   
  935. + #ifdef    RLOGIN
  936.       /*
  937. !      * Neither -h nor -f should be combined with -r.
  938.        */
  939.   
  940. !     if (rflg && (hflg || fflg))
  941.           usage ();
  942.   #endif
  943.   
  944.       /*
  945. !      * Allow authentication bypass only if real UID is zero.
  946.        */
  947.   
  948.       if ((rflg || fflg) && getuid () != 0) {
  949. +         fprintf(stderr, "%s: permission denied\n", Prog);
  950. +         exit (1);
  951. +     }
  952.   #ifdef    USE_SYSLOG
  953. !     openlog (Prog, LOG_PID|LOG_CONS|LOG_NOWAIT, LOG_AUTH);
  954.   #endif
  955.       if (! isatty (0) || ! isatty (1) || ! isatty (2)) {
  956.   #ifdef    USE_SYSLOG
  957.           closelog ();
  958. ***************
  959. *** 312,319 ****
  960.           while (*envp)        /* add inherited environment, */
  961.               addenv (*envp++); /* some variables change later */
  962.   
  963.   #ifdef    TZ
  964. !     if (! pflg) {
  965.           if (tzbuf[0] == '/') {
  966.               if ((tzfile = fopen (tzbuf, "r")) != (FILE *) 0) {
  967.                   if (fgets (tzbuf, sizeof tzbuf, tzfile)) {
  968. --- 395,406 ----
  969.           while (*envp)        /* add inherited environment, */
  970.               addenv (*envp++); /* some variables change later */
  971.   
  972. + #ifdef    RLOGIN
  973. +     if (term[5] != '\0')        /* see if anything after "TERM=" */
  974. +         addenv (term);
  975. + #endif
  976.   #ifdef    TZ
  977. !     if (! pflg || ! getenv("TZ")) {
  978.           if (tzbuf[0] == '/') {
  979.               if ((tzfile = fopen (tzbuf, "r")) != (FILE *) 0) {
  980.                   if (fgets (tzbuf, sizeof tzbuf, tzfile)) {
  981. ***************
  982. *** 328,342 ****
  983.       }
  984.   #endif    /* TZ */
  985.   #ifdef    HZ
  986. !     if (! pflg)
  987.           addenv (HZ);        /* set the default $HZ, if one */
  988.   #endif    /* HZ */
  989. -     if (optind < argc) {    /* now set command line variables */
  990. -         if (optind + 1 < argc)
  991. -             setenv (argc - optind - 1, &argv[optind + 1]);
  992.   
  993. !         (void) strncpy (name, argv[optind], sizeof name);
  994.       }
  995.   top:
  996.       (void) alarm (ALARM);        /* only allow ALARM sec. for login */
  997.   
  998. --- 415,434 ----
  999.       }
  1000.   #endif    /* TZ */
  1001.   #ifdef    HZ
  1002. !     if (! pflg || ! getenv("HZ"))
  1003.           addenv (HZ);        /* set the default $HZ, if one */
  1004.   #endif    /* HZ */
  1005.   
  1006. !     if (optind < argc) {        /* get the user name */
  1007. !         if (rflg || fflg)
  1008. !             usage ();
  1009. !         STRFCPY (name, argv[optind]);
  1010. !         ++optind;
  1011.       }
  1012. +     if (optind < argc)        /* now set command line variables */
  1013. +             setenv (argc - optind, &argv[optind]);
  1014.   top:
  1015.       (void) alarm (ALARM);        /* only allow ALARM sec. for login */
  1016.   
  1017. ***************
  1018. *** 351,357 ****
  1019.   #endif
  1020.                   exit (1);
  1021.               }
  1022. !             rflg = fflg = 0;
  1023.               login (name);
  1024.               continue;
  1025.           }
  1026. --- 443,451 ----
  1027.   #endif
  1028.                   exit (1);
  1029.               }
  1030. ! #ifdef    RLOGIN
  1031. !             preauth_flag = 0;
  1032. ! #endif
  1033.               login (name);
  1034.               continue;
  1035.           }
  1036. ***************
  1037. *** 373,385 ****
  1038.           } else
  1039.               failed = 1;    /* will never pass validation */
  1040.   
  1041.           /*
  1042.            * The -r and -f flags provide a name which has already
  1043.            * been authenticated by some server.
  1044.            */
  1045.   
  1046. !         if (pwent.pw_name && (rflg || fflg))
  1047.               goto have_name;
  1048.   
  1049.       /*
  1050.        * Get the user's password.  One will only be prompted for
  1051. --- 467,481 ----
  1052.           } else
  1053.               failed = 1;    /* will never pass validation */
  1054.   
  1055. + #ifdef    RLOGIN
  1056.           /*
  1057.            * The -r and -f flags provide a name which has already
  1058.            * been authenticated by some server.
  1059.            */
  1060.   
  1061. !         if (pwent.pw_name && preauth_flag)
  1062.               goto have_name;
  1063. + #endif    /*RLOGIN*/
  1064.   
  1065.       /*
  1066.        * Get the user's password.  One will only be prompted for
  1067. ***************
  1068. *** 393,399 ****
  1069.               continue;
  1070.   
  1071.           if (cp)
  1072. !             strncpy (pass, cp, sizeof pass);
  1073.   
  1074.           if (! valid (pass, &pwent)) { /* check encrypted passwords */
  1075.   #ifdef    USE_SYSLOG
  1076. --- 489,495 ----
  1077.               continue;
  1078.   
  1079.           if (cp)
  1080. !             STRFCPY (pass, cp);
  1081.   
  1082.           if (! valid (pass, &pwent)) { /* check encrypted passwords */
  1083.   #ifdef    USE_SYSLOG
  1084. ***************
  1085. *** 467,472 ****
  1086. --- 563,569 ----
  1087.               break;
  1088.   
  1089.           puts ("Login incorrect");
  1090. + #ifdef    RLOGIN
  1091.           if (rflg || fflg) {
  1092.   #ifdef    USE_SYSLOG
  1093.               closelog ();
  1094. ***************
  1095. *** 473,478 ****
  1096. --- 570,576 ----
  1097.   #endif
  1098.               exit (1);
  1099.           }
  1100. + #endif    /*RLOGIN*/
  1101.   #ifdef    FAILLOG
  1102.           if (pwent.pw_name)    /* don't log non-existent users */
  1103.               failure (pwent.pw_uid, tty, &faillog);
  1104. ***************
  1105. *** 481,493 ****
  1106.           failent = utent;
  1107.   
  1108.           if (pwent.pw_name)
  1109. !             strncpy (failent.ut_name,
  1110. !                 pwent.pw_name, sizeof failent.ut_name);
  1111.           else
  1112.   #ifdef    UNKNOWNS
  1113. !             strcpy (failent.ut_name, name);
  1114.   #else    /* !UNKNOWNS */
  1115. !             strcpy (failent.ut_name, "UNKNOWN");
  1116.   #endif    /* UNKNOWNS */
  1117.           time (&failent.ut_time);
  1118.           failent.ut_type = USER_PROCESS;
  1119. --- 579,590 ----
  1120.           failent = utent;
  1121.   
  1122.           if (pwent.pw_name)
  1123. !             STRFCPY (failent.ut_name, pwent.pw_name);
  1124.           else
  1125.   #ifdef    UNKNOWNS
  1126. !             STRFCPY (failent.ut_name, name);
  1127.   #else    /* !UNKNOWNS */
  1128. !             STRFCPY (failent.ut_name, "UNKNOWN");
  1129.   #endif    /* UNKNOWNS */
  1130.           time (&failent.ut_time);
  1131.           failent.ut_type = USER_PROCESS;
  1132. ***************
  1133. *** 575,581 ****
  1134. --- 672,680 ----
  1135.       hushed = access (hush, 0) == 0;
  1136.   #endif    /* HUSHLOGIN */
  1137.   #ifdef    MOTD
  1138. + #ifdef    HUSHLOGIN
  1139.       if (! hushed)
  1140. + #endif
  1141.           motd ();        /* print the message of the day */
  1142.   #endif
  1143.   #ifdef    FAILLOG
  1144. ***************
  1145. *** 583,603 ****
  1146.           failprint (pwent.pw_uid, &faillog);
  1147.   #endif    /* FAILLOG */
  1148.   #ifdef    LASTLOG
  1149. !     if (lastlog.ll_time != 0 && ! hushed)
  1150. !         printf ("Last login: %.19s on %s\n",
  1151. !             ctime (&lastlog.ll_time), lastlog.ll_line);
  1152.   #endif    /* LASTLOG */
  1153.   #ifdef    AGING
  1154.       if (! hushed)
  1155.           agecheck (&pwent, spwd);
  1156.   #endif    /* AGING */
  1157.   #ifdef    MAILCHECK
  1158.       if (! hushed)
  1159.           mailcheck ();        /* report on the status of mail */
  1160.   #endif    /* MAILCHECK */
  1161.   #ifdef    TTYTYPE
  1162. !     if (! pflg)
  1163. !         ttytype (tty);
  1164.   #endif    /* TTYTYPE */
  1165.       signal (SIGINT, SIG_DFL);    /* default interrupt signal */
  1166.       signal (SIGQUIT, SIG_DFL);    /* default quit signal */
  1167. --- 682,709 ----
  1168.           failprint (pwent.pw_uid, &faillog);
  1169.   #endif    /* FAILLOG */
  1170.   #ifdef    LASTLOG
  1171. ! #ifdef    HUSHLOGIN
  1172. !     if (! hushed)
  1173. ! #endif
  1174. !         if (lastlog.ll_time != 0)
  1175. !             printf ("Last login: %.19s on %s\n",
  1176. !                 ctime (&lastlog.ll_time), lastlog.ll_line);
  1177.   #endif    /* LASTLOG */
  1178.   #ifdef    AGING
  1179. + #ifdef    HUSHLOGIN
  1180.       if (! hushed)
  1181. + #endif
  1182.           agecheck (&pwent, spwd);
  1183.   #endif    /* AGING */
  1184.   #ifdef    MAILCHECK
  1185. + #ifdef    HUSHLOGIN
  1186.       if (! hushed)
  1187. + #endif
  1188.           mailcheck ();        /* report on the status of mail */
  1189.   #endif    /* MAILCHECK */
  1190.   #ifdef    TTYTYPE
  1191. !     if (! getenv("TERM"))
  1192. !           ttytype (tty);
  1193.   #endif    /* TTYTYPE */
  1194.       signal (SIGINT, SIG_DFL);    /* default interrupt signal */
  1195.       signal (SIGQUIT, SIG_DFL);    /* default quit signal */
  1196. *** /dev/null    Thu Jun 13 21:28:57 1991
  1197. --- mkrmdir.c    Thu Jun 13 10:09:40 1991
  1198. ***************
  1199. *** 0 ****
  1200. --- 1,76 ----
  1201. + /*
  1202. +  * Copyright 1991, John F. Haugh II
  1203. +  * An unpublished work.
  1204. +  * All rights reserved.
  1205. +  *
  1206. +  * Permission is granted to copy and create derivative works for any
  1207. +  * non-commercial purpose, provided this copyright notice is preserved
  1208. +  * in all copies of source code, or included in human readable form
  1209. +  * and conspicuously displayed on all copies of object code or
  1210. +  * distribution media.
  1211. +  */
  1212. + #include <fcntl.h>
  1213. + #include "config.h"
  1214. + #ifndef lint
  1215. + static    char    sccsid[] = "@(#)mkrmdir.c    3.1    10:09:21    6/13/91";
  1216. + #endif
  1217. + #ifdef    NEED_MKDIR
  1218. + /*
  1219. +  * mkdir - create a directory
  1220. +  *
  1221. +  *    mkdir is provided for systems which do not include the mkdir()
  1222. +  *    system call.
  1223. +  */
  1224. + int
  1225. + mkdir (dir, mode)
  1226. + char    *dir;
  1227. + int    mode;
  1228. + {
  1229. +     int    status;
  1230. +     if (fork ()) {
  1231. +         while (wait (&status) != -1)
  1232. +             ;
  1233. +         return status >> 8;
  1234. +     }
  1235. + #ifdef    USE_SYSLOG
  1236. +     closelog ();
  1237. + #endif
  1238. +     close (2);
  1239. +     open ("/dev/null", O_WRONLY);
  1240. +     umask (0777 & ~ mode);
  1241. +     execl ("/bin/mkdir", "mkdir", dir, 0);
  1242. +     _exit (128);
  1243. + }
  1244. + #endif
  1245. + #ifdef    NEED_RMDIR
  1246. + /*
  1247. +  * rmdir - remove a directory
  1248. +  *
  1249. +  *    rmdir is provided for systems which do not include the rmdir()
  1250. +  *    system call.
  1251. +  */
  1252. + int
  1253. + rmdir (dir)
  1254. + char    *dir;
  1255. + {
  1256. +     int    status;
  1257. +     if (fork ()) {
  1258. +         while (wait (&status) != -1)
  1259. +             ;
  1260. +         return status >> 8;
  1261. +     }
  1262. +     close (2);
  1263. +     open ("/dev/null", O_WRONLY);
  1264. +     execl ("/bin/rmdir", "rmdir", dir, 0);
  1265. +     _exit (128);
  1266. + }
  1267. + #endif
  1268. *** rel3/useradd.c    Thu Jun 13 21:28:44 1991
  1269. --- useradd.c    Thu Jun 13 10:06:45 1991
  1270. ***************
  1271. *** 10,16 ****
  1272.    */
  1273.   
  1274.   #ifndef lint
  1275. ! static    char    sccsid[] = "@(#)useradd.c    3.1    11:08:18    6/7/91";
  1276.   #endif
  1277.   
  1278.   #include <sys/types.h>
  1279. --- 10,16 ----
  1280.    */
  1281.   
  1282.   #ifndef lint
  1283. ! static    char    sccsid[] = "@(#)useradd.c    3.2    20:15:10    6/11/91";
  1284.   #endif
  1285.   
  1286.   #include <sys/types.h>
  1287. ***************
  1288. *** 43,48 ****
  1289. --- 43,49 ----
  1290.   gid_t    def_group;
  1291.   char    def_home[BUFSIZ];
  1292.   char    def_shell[BUFSIZ];
  1293. + char    def_template[BUFSIZ] = "/etc/skel";
  1294.   long    def_inactive;
  1295.   long    def_expire;
  1296.   char    def_file[] = "/etc/default/useradd";
  1297. ***************
  1298. *** 51,56 ****
  1299. --- 52,59 ----
  1300.   #define    NGROUPS_MAX    64
  1301.   #endif
  1302.   
  1303. + #define    VALID(s)    (strcspn (s, ":\n") == strlen (s))
  1304.   char    user_name[BUFSIZ];
  1305.   uid_t    user_id;
  1306.   gid_t    user_gid;
  1307. ***************
  1308. *** 141,177 ****
  1309.       0,    31,    59,    90,    120,    151,    /* JAN - JUN */
  1310.       181,    212,    243,    273,    304,    334 };    /* JUL - DEC */
  1311.   
  1312. - #ifdef    NEED_MKDIR
  1313. - /*
  1314. -  * mkdir - create a directory
  1315. -  *
  1316. -  *    mkdir is provided for systems which do not include the mkdir()
  1317. -  *    system call.
  1318. -  */
  1319. - int
  1320. - mkdir (dir, mode)
  1321. - char    *dir;
  1322. - int    mode;
  1323. - {
  1324. -     int    status;
  1325. -     if (fork ()) {
  1326. -         while (wait (&status) != -1)
  1327. -             ;
  1328. -         return status >> 8;
  1329. -     }
  1330. - #ifdef    USE_SYSLOG
  1331. -     closelog ();
  1332. - #endif
  1333. -     close (2);
  1334. -     open ("/dev/null", O_WRONLY);
  1335. -     umask (0777 & ~ mode);
  1336. -     execl ("/bin/mkdir", "mkdir", dir, 0);
  1337. -     _exit (128);
  1338. - }
  1339. - #endif
  1340.   #ifdef    NEED_RENAME
  1341.   /*
  1342.    * rename - rename a file to another name
  1343. --- 144,149 ----
  1344. ***************
  1345. *** 927,932 ****
  1346. --- 899,910 ----
  1347.       while ((arg = getopt (argc, argv, "Du:og:G:d:s:c:mk:f:e:b:")) != EOF) {
  1348.           switch (arg) {
  1349.               case 'b':
  1350. +                 if (! VALID (optarg)) {
  1351. +                     fprintf (stderr,
  1352. +                         "%s: invalid field `%s'\n",
  1353. +                         Prog, optarg);
  1354. +                     exit (3);
  1355. +                 }
  1356.                   bflg++;
  1357.                   if (! Dflg)
  1358.                       usage ();
  1359. ***************
  1360. *** 934,943 ****
  1361. --- 912,933 ----
  1362.                   strncpy (def_home, optarg, BUFSIZ);
  1363.                   break;
  1364.               case 'c':
  1365. +                 if (! VALID (optarg)) {
  1366. +                     fprintf (stderr,
  1367. +                         "%s: invalid field `%s'\n",
  1368. +                         Prog, optarg);
  1369. +                     exit (3);
  1370. +                 }
  1371.                   cflg++;
  1372.                   strncpy (user_comment, optarg, BUFSIZ);
  1373.                   break;
  1374.               case 'd':
  1375. +                 if (! VALID (optarg)) {
  1376. +                     fprintf (stderr,
  1377. +                         "%s: invalid field `%s'\n",
  1378. +                         Prog, optarg);
  1379. +                     exit (3);
  1380. +                 }
  1381.                   dflg++;
  1382.                   strncpy (user_home, optarg, BUFSIZ);
  1383.                   break;
  1384. ***************
  1385. *** 987,992 ****
  1386. --- 977,983 ----
  1387.                   if (! mflg)
  1388.                       usage ();
  1389.   
  1390. +                 strncpy (def_template, optarg, BUFSIZ);
  1391.                   kflg++;
  1392.                   break;
  1393.               case 'm':
  1394. ***************
  1395. *** 999,1004 ****
  1396. --- 990,1001 ----
  1397.                   oflg++;
  1398.                   break;
  1399.               case 's':
  1400. +                 if (! VALID (optarg)) {
  1401. +                     fprintf (stderr,
  1402. +                         "%s: invalid field `%s'\n",
  1403. +                         Prog, optarg);
  1404. +                     exit (3);
  1405. +                 }
  1406.                   sflg++;
  1407.                   strncpy (user_shell, optarg, BUFSIZ);
  1408.                   break;
  1409. ***************
  1410. *** 1086,1096 ****
  1411.           exit (1);
  1412.       }
  1413.       if (! spw_lock ()) {
  1414. !         fprintf ("%s: cannot lock shadow password file\n", Prog);
  1415.           exit (1);
  1416.       }
  1417.       if (! spw_open (O_RDWR)) {
  1418. !         fprintf ("%s: cannot open shadow password file\n", Prog);
  1419.           exit (1);
  1420.       }
  1421.   }
  1422. --- 1083,1093 ----
  1423.           exit (1);
  1424.       }
  1425.       if (! spw_lock ()) {
  1426. !         fprintf (stderr, "%s: cannot lock shadow password file\n", Prog);
  1427.           exit (1);
  1428.       }
  1429.       if (! spw_open (O_RDWR)) {
  1430. !         fprintf (stderr, "%s: cannot open shadow password file\n", Prog);
  1431.           exit (1);
  1432.       }
  1433.   }
  1434. ***************
  1435. *** 1236,1244 ****
  1436.   
  1437.       usr_update ();
  1438.   
  1439. !     if (mflg)
  1440.           create_home ();
  1441.       close_files ();
  1442.       exit (0);
  1443.       /*NOTREACHED*/
  1444. --- 1233,1242 ----
  1445.   
  1446.       usr_update ();
  1447.   
  1448. !     if (mflg) {
  1449.           create_home ();
  1450. !         copy_tree (def_template, user_home, user_id, user_gid);
  1451. !     }
  1452.       close_files ();
  1453.       exit (0);
  1454.       /*NOTREACHED*/
  1455. *** rel3/userdel.c    Thu Jun 13 21:28:45 1991
  1456. --- userdel.c    Thu Jun 13 21:16:54 1991
  1457. ***************
  1458. *** 10,16 ****
  1459.    */
  1460.   
  1461.   #ifndef lint
  1462. ! static    char    sccsid[] = "@(#)userdel.c    3.1    11:08:47    6/7/91";
  1463.   #endif
  1464.   
  1465.   #include <sys/types.h>
  1466. --- 10,16 ----
  1467.    */
  1468.   
  1469.   #ifndef lint
  1470. ! static    char    sccsid[] = "@(#)userdel.c    3.5    20:53:04    6/13/91";
  1471.   #endif
  1472.   
  1473.   #include <sys/types.h>
  1474. ***************
  1475. *** 90,123 ****
  1476.   
  1477.   extern    char    *malloc();
  1478.   
  1479. - #ifdef    NEED_RMDIR
  1480.   /*
  1481. -  * rmdir - remove a directory
  1482. -  *
  1483. -  *    rmdir is provided for systems which do not include the rmdir()
  1484. -  *    system call.
  1485. -  */
  1486. - int
  1487. - rmdir (dir)
  1488. - char    *dir;
  1489. - {
  1490. -     int    status;
  1491. -     if (fork ()) {
  1492. -         while (wait (&status) != -1)
  1493. -             ;
  1494. -         return status >> 8;
  1495. -     }
  1496. -     close (2);
  1497. -     open ("/dev/null", O_WRONLY);
  1498. -     execl ("/bin/rmdir", "rmdir", dir, 0);
  1499. -     _exit (128);
  1500. - }
  1501. - #endif
  1502. - /*
  1503.    * del_list - delete a member from a list of group members
  1504.    *
  1505.    *    the array of member names is searched for the old member
  1506. --- 90,96 ----
  1507. ***************
  1508. *** 175,181 ****
  1509.   usage ()
  1510.   {
  1511.       fprintf (stderr, "usage: userdel [-r] name\n");
  1512. !     exit (1);
  1513.   }
  1514.   
  1515.   /*
  1516. --- 148,154 ----
  1517.   usage ()
  1518.   {
  1519.       fprintf (stderr, "usage: userdel [-r] name\n");
  1520. !     exit (2);
  1521.   }
  1522.   
  1523.   /*
  1524. ***************
  1525. *** 224,239 ****
  1526.                   Prog);
  1527.               exit (1);
  1528.           }
  1529. - #ifdef    NDBM
  1530.           /*
  1531.            * Update the DBM group file with the new entry as well.
  1532.            */
  1533.   
  1534.           if (! gr_dbm_update (grp)) {
  1535.               fprintf (stderr, "%s: cannot update dbm group entry\n",
  1536.                   Prog);
  1537.               exit (1);
  1538.           }
  1539.   #endif
  1540.       }
  1541.   
  1542. --- 197,216 ----
  1543.                   Prog);
  1544.               exit (1);
  1545.           }
  1546.           /*
  1547.            * Update the DBM group file with the new entry as well.
  1548.            */
  1549.   
  1550. + #ifdef    NDBM
  1551.           if (! gr_dbm_update (grp)) {
  1552.               fprintf (stderr, "%s: cannot update dbm group entry\n",
  1553.                   Prog);
  1554.               exit (1);
  1555.           }
  1556. + #endif    /* NDBM */
  1557. + #ifdef    USE_SYSLOG
  1558. +         syslog (LOG_INFO, "delete `%s' from group `%s'\n",
  1559. +             user_name, grp->gr_name);
  1560.   #endif
  1561.       }
  1562.   
  1563. ***************
  1564. *** 287,292 ****
  1565. --- 264,273 ----
  1566.               exit (1);
  1567.           }
  1568.   #endif
  1569. + #ifdef    USE_SYSLOG
  1570. +         syslog (LOG_INFO, "delete `%s' from shadow group `%s'\n",
  1571. +             user_name, grp->gr_name);
  1572. + #endif
  1573.       }
  1574.   #endif
  1575.   }
  1576. ***************
  1577. *** 312,318 ****
  1578.       if (! gr_close ()) {
  1579.           fprintf (stderr, "%s: cannot rewrite group file\n",
  1580.               Prog);
  1581. !         exit (1);
  1582.       }
  1583.       (void) gr_unlock ();
  1584.   #ifdef    SHADOWGRP
  1585. --- 293,299 ----
  1586.       if (! gr_close ()) {
  1587.           fprintf (stderr, "%s: cannot rewrite group file\n",
  1588.               Prog);
  1589. !         exit (10);
  1590.       }
  1591.       (void) gr_unlock ();
  1592.   #ifdef    SHADOWGRP
  1593. ***************
  1594. *** 319,325 ****
  1595.       if (! sgr_close ()) {
  1596.           fprintf (stderr, "%s: cannot rewrite shadow group file\n",
  1597.               Prog);
  1598. !         exit (1);
  1599.       }
  1600.       (void) sgr_unlock ();
  1601.   #endif
  1602. --- 300,306 ----
  1603.       if (! sgr_close ()) {
  1604.           fprintf (stderr, "%s: cannot rewrite shadow group file\n",
  1605.               Prog);
  1606. !         exit (10);
  1607.       }
  1608.       (void) sgr_unlock ();
  1609.   #endif
  1610. ***************
  1611. *** 343,353 ****
  1612.           exit (1);
  1613.       }
  1614.       if (! spw_lock ()) {
  1615. !         fprintf ("%s: cannot lock shadow password file\n", Prog);
  1616.           exit (1);
  1617.       }
  1618.       if (! spw_open (O_RDWR)) {
  1619. !         fprintf ("%s: cannot open shadow password file\n", Prog);
  1620.           exit (1);
  1621.       }
  1622.       if (! gr_lock ()) {
  1623. --- 324,334 ----
  1624.           exit (1);
  1625.       }
  1626.       if (! spw_lock ()) {
  1627. !         fprintf (stderr, "%s: cannot lock shadow password file\n", Prog);
  1628.           exit (1);
  1629.       }
  1630.       if (! spw_open (O_RDWR)) {
  1631. !         fprintf (stderr, "%s: cannot open shadow password file\n", Prog);
  1632.           exit (1);
  1633.       }
  1634.       if (! gr_lock ()) {
  1635. ***************
  1636. *** 414,419 ****
  1637. --- 395,403 ----
  1638.           fprintf (stderr, "%s: error deleting shadow passwd dbm entry\n",
  1639.               Prog);
  1640.   #endif
  1641. + #ifdef    USE_SYSLOG
  1642. +     syslog (LOG_INFO, "delete user `%s'\n", user_name);
  1643. + #endif
  1644.   }
  1645.   
  1646.   /*
  1647. ***************
  1648. *** 426,431 ****
  1649. --- 410,416 ----
  1650.   {
  1651.       struct    passwd    *pwd;
  1652.       int    arg;
  1653. +     int    errors = 0;
  1654.       extern    int    optind;
  1655.       extern    char    *optarg;
  1656.   
  1657. ***************
  1658. *** 475,481 ****
  1659.       if (! (pwd = getpwnam (user_name))) {
  1660.           fprintf (stderr, "%s: user %s does not exist\n",
  1661.               Prog, user_name);
  1662. !         exit (1);
  1663.       }
  1664.       user_id = pwd->pw_uid;
  1665.       strcpy (user_home, pwd->pw_dir);
  1666. --- 460,466 ----
  1667.       if (! (pwd = getpwnam (user_name))) {
  1668.           fprintf (stderr, "%s: user %s does not exist\n",
  1669.               Prog, user_name);
  1670. !         exit (6);
  1671.       }
  1672.       user_id = pwd->pw_uid;
  1673.       strcpy (user_home, pwd->pw_dir);
  1674. ***************
  1675. *** 490,499 ****
  1676.       update_user ();
  1677.       update_groups ();
  1678.   
  1679. !     if (rflg)
  1680. !         rmdir (user_home);
  1681.       close_files ();
  1682. !     exit (0);
  1683.       /*NOTREACHED*/
  1684.   }
  1685. --- 475,485 ----
  1686.       update_user ();
  1687.       update_groups ();
  1688.   
  1689. !     if (rflg) {
  1690. !         if (remove_tree (user_home) || rmdir (user_home))
  1691. !             errors++;
  1692. !     }
  1693.       close_files ();
  1694. !     exit (errors ? 12:0);
  1695.       /*NOTREACHED*/
  1696.   }
  1697. *** rel3/usermod.c    Thu Jun 13 21:28:46 1991
  1698. --- usermod.c    Thu Jun 13 10:06:47 1991
  1699. ***************
  1700. *** 10,16 ****
  1701.    */
  1702.   
  1703.   #ifndef lint
  1704. ! static    char    sccsid[] = "@(#)usermod.c    3.1    11:08:35    6/7/91";
  1705.   #endif
  1706.   
  1707.   #include <sys/types.h>
  1708. --- 10,16 ----
  1709.    */
  1710.   
  1711.   #ifndef lint
  1712. ! static    char    sccsid[] = "@(#)usermod.c    3.2    20:26:57    6/11/91";
  1713.   #endif
  1714.   
  1715.   #include <sys/types.h>
  1716. ***************
  1717. *** 44,49 ****
  1718. --- 44,51 ----
  1719.   #define    NGROUPS_MAX    64
  1720.   #endif
  1721.   
  1722. + #define    VALID(s)    (strcspn (s, ":\n") == strlen (s))
  1723.   char    user_name[BUFSIZ];
  1724.   char    user_newname[BUFSIZ];
  1725.   uid_t    user_id;
  1726. ***************
  1727. *** 115,121 ****
  1728.   extern    int    spw_lock();
  1729.   extern    int    spw_unlock();
  1730.   extern    int    spw_open();
  1731. ! extern    int    spw_locate();
  1732.   
  1733.   #define    DAY    (24L*3600L)
  1734.   #define    WEEK    (7*DAY)
  1735. --- 117,123 ----
  1736.   extern    int    spw_lock();
  1737.   extern    int    spw_unlock();
  1738.   extern    int    spw_open();
  1739. ! extern    struct    spwd    *spw_locate();
  1740.   
  1741.   #define    DAY    (24L*3600L)
  1742.   #define    WEEK    (7*DAY)
  1743. ***************
  1744. *** 140,176 ****
  1745.       0,    31,    59,    90,    120,    151,    /* JAN - JUN */
  1746.       181,    212,    243,    273,    304,    334 };    /* JUL - DEC */
  1747.   
  1748. - #ifdef    NEED_MKDIR
  1749. - /*
  1750. -  * mkdir - create a directory
  1751. -  *
  1752. -  *    mkdir is provided for systems which do not include the mkdir()
  1753. -  *    system call.
  1754. -  */
  1755. - int
  1756. - mkdir (dir, mode)
  1757. - char    *dir;
  1758. - int    mode;
  1759. - {
  1760. -     int    status;
  1761. -     if (fork ()) {
  1762. -         while (wait (&status) != -1)
  1763. -             ;
  1764. -         return status >> 8;
  1765. -     }
  1766. - #ifdef    USE_SYSLOG
  1767. -     closelog ();
  1768. - #endif
  1769. -     close (2);
  1770. -     open ("/dev/null", O_WRONLY);
  1771. -     umask (0777 & ~ mode);
  1772. -     execl ("/bin/mkdir", "mkdir", dir, 0);
  1773. -     _exit (128);
  1774. - }
  1775. - #endif
  1776.   #ifdef    NEED_RENAME
  1777.   /*
  1778.    * rename - rename a file to another name
  1779. --- 142,147 ----
  1780. ***************
  1781. *** 831,836 ****
  1782. --- 802,813 ----
  1783.       while ((arg = getopt (argc, argv, "u:og:G:d:s:c:mf:e:l:")) != EOF) {
  1784.           switch (arg) {
  1785.               case 'c':
  1786. +                 if (! VALID (optarg)) {
  1787. +                     fprintf (stderr,
  1788. +                         "%s: invalid field `%s'\n",
  1789. +                         Prog, optarg);
  1790. +                     exit (3);
  1791. +                 }
  1792.                   if (strcmp (optarg, user_comment)) {
  1793.                       cflg++;
  1794.                       strncpy (user_comment, optarg, BUFSIZ);
  1795. ***************
  1796. *** 837,842 ****
  1797. --- 814,825 ----
  1798.                   }
  1799.                   break;
  1800.               case 'd':
  1801. +                 if (! VALID (optarg)) {
  1802. +                     fprintf (stderr,
  1803. +                         "%s: invalid field `%s'\n",
  1804. +                         Prog, optarg);
  1805. +                     exit (3);
  1806. +                 }
  1807.                   dflg++;
  1808.                   strncpy (user_newhome, optarg, BUFSIZ);
  1809.                   break;
  1810. ***************
  1811. *** 880,885 ****
  1812. --- 863,874 ----
  1813.   
  1814.                   break;
  1815.               case 'l':
  1816. +                 if (! VALID (optarg)) {
  1817. +                     fprintf (stderr,
  1818. +                         "%s: invalid field `%s'\n",
  1819. +                         Prog, optarg);
  1820. +                     exit (3);
  1821. +                 }
  1822.                   if (strcmp (user_name, optarg)) {
  1823.                       lflg++;
  1824.                       strcpy (user_newname, optarg);
  1825. ***************
  1826. *** 898,903 ****
  1827. --- 887,898 ----
  1828.                   oflg++;
  1829.                   break;
  1830.               case 's':
  1831. +                 if (! VALID (optarg)) {
  1832. +                     fprintf (stderr,
  1833. +                         "%s: invalid field `%s'\n",
  1834. +                         Prog, optarg);
  1835. +                     exit (3);
  1836. +                 }
  1837.                   if (strcmp (user_shell, optarg)) {
  1838.                       strncpy (user_shell, optarg, BUFSIZ);
  1839.                       sflg++;
  1840. ***************
  1841. *** 980,990 ****
  1842.           exit (1);
  1843.       }
  1844.       if (! spw_lock ()) {
  1845. !         fprintf ("%s: cannot lock shadow password file\n", Prog);
  1846.           exit (1);
  1847.       }
  1848.       if (! spw_open (O_RDWR)) {
  1849. !         fprintf ("%s: cannot open shadow password file\n", Prog);
  1850.           exit (1);
  1851.       }
  1852.   }
  1853. --- 975,985 ----
  1854.           exit (1);
  1855.       }
  1856.       if (! spw_lock ()) {
  1857. !         fprintf (stderr, "%s: cannot lock shadow password file\n", Prog);
  1858.           exit (1);
  1859.       }
  1860.       if (! spw_open (O_RDWR)) {
  1861. !         fprintf (stderr, "%s: cannot open shadow password file\n", Prog);
  1862.           exit (1);
  1863.       }
  1864.   }
  1865. ***************
  1866. *** 1076,1087 ****
  1867.   
  1868.   move_home ()
  1869.   {
  1870. !     if (mflg && access (user_home, 0) == 0) {
  1871.           if (access (user_newhome, 0) == 0) {
  1872.               fprintf (stderr, "%s: directory %s exists\n",
  1873.                   Prog, user_newhome);
  1874.               exit (12);
  1875.           } else if (rename (user_home, user_newhome)) {
  1876.               fprintf (stderr,
  1877.                   "%s: cannot rename directory %s to %s\n",
  1878.                   Prog, user_home, user_newhome);
  1879. --- 1071,1100 ----
  1880.   
  1881.   move_home ()
  1882.   {
  1883. !     struct    stat    sb;
  1884. !     if (mflg && stat (user_home, &sb) == 0) {
  1885.           if (access (user_newhome, 0) == 0) {
  1886.               fprintf (stderr, "%s: directory %s exists\n",
  1887.                   Prog, user_newhome);
  1888.               exit (12);
  1889.           } else if (rename (user_home, user_newhome)) {
  1890. +             if (errno == EXDEV) {
  1891. +                 if (mkdir (user_newhome, sb.st_mode & 0777)) {
  1892. +                     fprintf (stderr,
  1893. +                         "%s: can't create %s\n",
  1894. +                         Prog, user_newhome);
  1895. +                 }
  1896. +                 chown (user_newhome, sb.st_uid, sb.st_gid);
  1897. +                 if (copy_tree (user_home, user_newhome,
  1898. +                         -1, -1) == 0 &&
  1899. +                     remove_tree (user_home) == 0 &&
  1900. +                         rmdir (user_home) == 0)
  1901. +                     return;
  1902. +                 remove_tree (user_newhome);
  1903. +                 rmdir (user_newhome);
  1904. +             }
  1905.               fprintf (stderr,
  1906.                   "%s: cannot rename directory %s to %s\n",
  1907.                   Prog, user_home, user_newhome);
  1908. -- 
  1909. John F. Haugh II        | Distribution to  | UUCP: ...!cs.utexas.edu!rpp386!jfh
  1910. Ma Bell: (512) 255-8251 | GEnie PROHIBITED :-) |  Domain: jfh@rpp386.cactus.org
  1911. "I carry a lot of weight, and I carry it well."
  1912.         -- Rush Limbaugh
  1913.