home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / unix / volume13 / autoadd < prev    next >
Text File  |  1988-01-31  |  26KB  |  987 lines

  1. Subject:  v13i043:  Program to add users to system
  2. Newsgroups: comp.sources.unix
  3. Sender: sources
  4. Approved: rsalz@uunet.UU.NET
  5.  
  6. Submitted-by: jim nelson <ecsgate!ecsvax!nelson>
  7. Posting-number: Volume 13, Issue 43
  8. Archive-name: autoadd
  9.  
  10. Autoadd reads lines from an input file, creates required lines in
  11. /etc/passwd, calls mkdir(1) to create required directories, creates
  12. .profile files, etc.  It's designed for educational environments.
  13.  
  14. # To unbundle, sh this file
  15. echo MANIFEST 1>&2
  16. sed -e 's/^X//' >MANIFEST <<'End'
  17. XMANIFEST
  18. XREADME 
  19. Xautoadd.8 
  20. XMakefile 
  21. Xautoadd.h 
  22. Xexample 
  23. Xausr
  24. Xkusr
  25. Xalready.c
  26. Xecpw.c
  27. Xexists.c
  28. Xinitfiles.c
  29. Xkindex.c
  30. Xmain.c
  31. Xparse.c
  32. Xquit.c
  33. Xtryagain.c
  34. End
  35. echo README 1>&2
  36. sed -e 's/^X//' >README <<'End'
  37. XAutoadd is yours for the taking.  If you like it, use it.
  38. XIf not, trash it.  I wrote it just for fun, and because I
  39. Xneeded it.  It's hereby put in the public domain; no
  40. Xcopyright, no send-me-money, no nothing.
  41. X
  42. XAutoadd is a batch adduser program.  It's in C, with one
  43. Xcall to the "system()" (to mkdir) (why reinvent TWO wheels?)
  44. X(Oh yeah, I think I also sytem("cp ....") just from sheer
  45. Xlaziness).
  46. X
  47. XI'd have to admit to a little hubris, though, in titling the
  48. Xman page with a ".8" suffix instead of ".1".  Feel free to
  49. Xmove it to ".1" if you see fit.
  50. X
  51. XI have included my own /etc/ausr and /etc/kusr (Bourne) shell
  52. Xscripts just for comparison with the autoadd.c program.  Throw
  53. Xthem away quickly if you have your own favorite (which most
  54. Xeverybody should, I guess.).
  55. X
  56. XNB: this is one of those "Oh, he wants me to run this as root?"
  57. Xprograms.  Well, the source is not very long; and it's intended
  58. Xto be totally readable to the most casual of observers, so
  59. Xuse if you like, but 
  60. X
  61. X#include <standard.disclaimer>
  62. X
  63. XSee mostly the autoadd.h comments and #defines, but also take
  64. Xa look at initfiles.c .
  65. X--- jhn
  66. X
  67. XOh yeah, all these sources should be looked at with tab stops
  68. Xset at four.  They were created using vi with autoindent and
  69. Xtabstops at four.  Stops of eight will make some of the lines run
  70. Xoff the screen.  Alternatively, run them thru sed and change 
  71. Xall \t to four blanks (which I did not do, in the interest of
  72. Xkeeping the byte count down).
  73. X--- jhn
  74. End
  75. echo autoadd.8 1>&2
  76. sed -e 's/^X//' >autoadd.8 <<'End'
  77. X.ig
  78. X    @(#)autoadd.8    
  79. X..
  80. X.TH AUTOADD 8
  81. X.UC 4
  82. X.SH NAME
  83. Xautoadd \- add class rosters to system
  84. X.SH SYNOPSIS
  85. X.B autoadd
  86. X[
  87. Xfilename
  88. X] 
  89. X.SH DESCRIPTION
  90. X.I Autoadd
  91. Xreads lines from an input file, creates required lines in
  92. X/etc/passwd, calls mkdir(1) to create required directories,
  93. Xcreates .profile files, etc.,
  94. Xto add a batch of users to the system.  Optionally, it will
  95. Xappend to the /etc/accesstab file for use with "access".
  96. XSupplied in source form.  See comments and tunable parameters
  97. Xin autoadd.h for more info.
  98. X.PP
  99. XNo command line parameters are provided; this program will
  100. Xbe used rarely (twice or thrice per semester, typically) and
  101. Xcan be configured by #defines in the source.
  102. X.PP
  103. XKeywords are:
  104. X.TP
  105. X.B    prof:    professor 
  106. X.TP
  107. X.B    group:    group
  108. X.TP
  109. X.B    alias:    for a mailrc
  110. X.TP
  111. X.B    disk:    partition 
  112. X.TP
  113. X.B    passwd:    password
  114. X.TP
  115. X.B    firstprog:    last line of profile
  116. X.PP
  117. XOther input lines are of the form:
  118. X.TP
  119. X.B    lastname i i
  120. X.PP
  121. XThe /etc/passwd file is read to determine the largest user number
  122. Xthere, and the new people are assigned user numbers from there up.
  123. X.SH FILES
  124. X.ta 2i
  125. X/etc/passwd    password file
  126. X.br
  127. X/etc/accesstab    (optional) for professor:student lines
  128. X.br
  129. X./mailrc    alias list for sending to professor
  130. X.SH AUTHOR
  131. XJim Nelson, UNC-Wilmington (nelson@ecsvax.uucp) 919-395-3300
  132. X.SH BUGS
  133. X Must be run as root.
  134. End
  135. echo Makefile 1>&2
  136. sed -e 's/^X//' >Makefile <<'End'
  137. XCFLAGS=
  138. XLDFLAGS=-s
  139. XLINTFLAGS=-hbx
  140. X
  141. XSOURCES= main.c parse.c kindex.c exists.c \
  142. X    ecpw.c quit.c initfiles.c already.c tryagain.c
  143. X
  144. XOBJS= main.o parse.o kindex.o exists.o \
  145. X    ecpw.o quit.o initfiles.o already.o tryagain.o
  146. X
  147. Xautoadd: $(OBJS) autoadd.h
  148. X    cc $(LDFLAGS) -o autoadd $(OBJS)
  149. X
  150. Xmain.o initfiles.o tryagain.o parse.o: autoadd.h
  151. X
  152. Xautoadd.shar: MANIFEST README autoadd.8 Makefile autoadd.h example \
  153. X        ausr kusr $(SOURCES)
  154. X    shar MANIFEST README autoadd.8 Makefile autoadd.h example \
  155. X        ausr kusr $(SOURCES) >autoadd.shar
  156. X
  157. Xlint: $(SOURCES) autoadd.h 
  158. X    lint $(LINTFLAGS) autoadd.h $(SOURCES)
  159. End
  160. echo autoadd.h 1>&2
  161. sed -e 's/^X//' >autoadd.h <<'End'
  162. X/*
  163. X"autoadd" -- a batch account-setter-upper.  for adding whole class
  164. Xrosters to unix machines.  
  165. Xby: j. nelson, univ. nc-wilmington, dept. math. sciences, 
  166. Xwilmington nc 28403,  919-395-3300.
  167. X
  168. XThe idea here is to allow a student assistant or other partially
  169. Xtrusted assistant to enter the class roster, and then in one 
  170. Xswell-foop, add all those folks to the system.  This can be either
  171. Xpermitted to the assistant or reserved to the sysop, but requires
  172. Xthat the program be run as root (at least it does on my machines).
  173. X
  174. XAn input file consists of a few "keyword" lines, followed by the
  175. Xclass roster in "lastname fi mi" form.
  176. X
  177. XKeywords :
  178. X"prof:ssss"        professor for "accesstab" file
  179. X                this is for that neat program that came down the
  180. X                wire a while back that allows someone to access
  181. X                another directory by effectively "becoming" them.
  182. X                If not using, comment out the following line: */
  183. X#define ACCESS
  184. X/*
  185. X"disk:/sssss"    parent directory, e.g. /usr3, /stoonts, etc.
  186. X"firstprog:ssss" this will be the last line of .profile
  187. X"shell:xxxxx"    shell; 0 means no entry */
  188. X#define PROFILE "/.profile" /*will have parentdir prepended*/
  189. X#define LOGIN "/.login"
  190. X#define STDPROFILE "/etc/stdprofile"
  191. X/*
  192. X"alias:sssss"    for manually moving into the prof's .mailrc file
  193. X"group:nnn"        group
  194. X"passwd:xxxxxx" password (will be same for all these users, but salt
  195. X                is randomly selected)
  196. X"password:xxxx" (same as passwd)
  197. X        special case: 1 means use username as password.
  198. X
  199. XAny line containing one of the keywords is processed for the keyword
  200. Xvalue.  Null lines, blank lines, and lines beginning with # are ignored.
  201. XOther lines are presumed to be name-lines of the form
  202. Xlastname f m
  203. Xthat is, lastname firstinitial middleinitial
  204. Xseparated by blanks.
  205. XThe lastname may be of any length, but will be truncated to ML (default
  206. Xis 7) chars before applying any of the algorithms.  fi and mi should 
  207. Xbe only single characters, but the parser will accept any number, 
  208. Xand will truncate them to single chars.
  209. XAlso accepts usernames of the form abc, where abc is the person's
  210. Xfi mi li, as some system admins like to use, e.g. I would be
  211. X"jhn" (James H Nelson), and "Joe Bob College" would be "jbc".  
  212. XThe program assumes that "jhn" is the lastname, and forces fi 
  213. Xand mi to be '1' for purposes of the algorithm.
  214. XThe algorithm first tries lastname, then filastname, then
  215. Xlastnamefi, then filastnamemi, etc., etc., finally resorting to
  216. Xprepending digits to usernames if all else fails (this is guaranteed
  217. Xto work unless you have a huge number of users (!)).  The exact
  218. Xalgorithm is clear from reading the code in tryagain().
  219. XSee alse the example file.
  220. X*/
  221. X
  222. X#include <stdio.h>
  223. X
  224. X
  225. X/* these next includes probably will not work everywhere */
  226. X/* they DO work on SysVr2 (3b2/300) and a BSD4.1-derived
  227. Xknockoff (lmc -- GENIX on a nsc16032) */
  228. X#include <string.h> /*maybe strings.h   ???*/
  229. X#include <sys/types.h> /*maybe don't need sys  ??? */
  230. X#include <sys/stat.h>  /* ditto */
  231. X#include <errno.h> /*only for ENOENT*/ /*if fails, forget it! */
  232. X
  233. X/* next three are individually tunable parameters */
  234. X#define MAXNU 1300 /*max number of entries in /etc/passwd */
  235. X#define ROOT 0 /* just in case your root is not uid==0 (?weird?) */
  236. X#define ML 7  /*maximum length of a login-name.*/
  237. X/* 7 is a nice length, 'cause tabs work better, but this can be
  238. X anything within reason */
  239. X
  240. X#define null '\0' /*just for ease of typing*/ /* not same as NULL */
  241. X
  242. Xextern void exit(); /* for lint */
  243. X
  244. X#ifdef MAIN /*so only see once; main.c will define MAIN,
  245. Xbut nobody else will*/
  246. X
  247. X/* some of the following might need to be lengthened if sysop
  248. Xallows ridiculously long login names */
  249. X
  250. Xint euid; 
  251. X/* euid = geteuid(); */ /*to see if we're dangerous */
  252. X/*this will be done very early in main() */
  253. X/* Autoadd does slightly different things depending on whether
  254. X user is root or not, e.g. /etc/passwd vs. ./passwd , etc.
  255. X Examine the code carefully before running at all, and then re-
  256. X examine it before running as root. This is not a disk-polisher or
  257. X one of those other nasties, (DO NOT take my word for it, look at
  258. X the code!) but it does have to run as root to be
  259. X effective (not necessarily setuid root, just "effective uid"
  260. X of root), 'cause it must append to /etc/passwd and create
  261. X directories in /"disk". (unless you let just anybody do those
  262. X things!)
  263. X*/
  264. X/* some defaults:*/
  265. X#define GROUP "100" /*why not?*/
  266. X#define DISK "/usr4" /*our current place to stash stoonts*/
  267. X#define SHELL "0" /* 0 means Bourne shell */
  268. X#define ALIAS "csc101" /*we don't have a csc101, so why not?*/
  269. X#define FIRSTPROG "0" /* default no startup program */
  270. X#define PROFESSOR "nelson"    /* make "0" (with quotes) for none*/
  271. X#define PASSWD "0" /*no default password*/
  272. X#define DISLIST "./mailrc" /*filename of where to put alias list*/
  273. X/*notice that several of the variables default if the first
  274. X(i.e. zeroth) character of a string is the character '0' , but the
  275. Xabove defines must be in double-qoutes, not single-quotes, becuz
  276. Xthey're used in strcpy() statements.
  277. XA couple of other things: GROUP must be a string, not an integer;
  278. Xthe leading / is optional on DISK (it'll be forced if omitted);
  279. XI don't have ksh, so the only way to make it the default is to
  280. Xhack on the source; be sure the look at ecpw.c closely if worried
  281. Xabout passwords.
  282. X*/
  283. X
  284. X/* Global variables: */
  285. Xchar *user[MAXNU],*malloc(); /* we have only about 120, but ...*/
  286. Xchar ecptex[20]; /* large enuff to hold an encrypted password*/
  287. Xchar infile[100]; /*the input filename ... 30 should be plenty*/
  288. Xchar line[142],lastname[50],fi[2],mi[2];
  289. Xchar profname[30],diskname[20],groupname[20],passwordname[20],
  290. X    username[40],aliasname[40],firstprog[40],parentdir[40];
  291. Xchar dislist[60],passwd[60],proffile[60] ;
  292. X#endif /*MAIN*/
  293. End
  294. echo example 1>&2
  295. sed -e 's/^X//' >example <<'End'
  296. X# fortran77
  297. Xgroup:195
  298. Xalias:csc111
  299. Xprof:herbst
  300. Xdisk:usr
  301. Xpassword:beginner
  302. X# force them into the menu-shell as the last line
  303. X# of their .profile
  304. Xfirstprog:/usr/uncw/msh
  305. X
  306. Xnelson brain dead
  307. Xmr
  308. Xmmr
  309. Xal-anon muhammad mustafa
  310. Xshell:/bin/csh
  311. Xpodgornowitz a a
  312. Xpodgornowitz a b
  313. X#next person should be only one who has password same as login
  314. Xpasswd:1
  315. Xpodgornowitz b a
  316. Xpasswd:0
  317. X
  318. X# intro comp sci II section 1
  319. Xprof:knuth
  320. Xdisk:/usr1
  321. X#i think this is the unit of albanian currency ?
  322. Xpasswd:zlotny
  323. Xgroup:177
  324. Xfirstprog:0
  325. Xalias:csc12201
  326. Xshell:0
  327. Xcampus big man on
  328. Xcretin a a
  329. Xcretin a b
  330. X# just to see if this works
  331. Xshell:/bin/ksh
  332. Xcretin b a
  333. Xshell:/bin/csh
  334. Xcretin b b
  335. X# go back to Bourne shell
  336. Xshell:0
  337. Xcretin b b
  338. Xjhn
  339. Xcollege suzy coed
  340. Xbch
  341. X#
  342. X# operating systems
  343. Xprof:ast
  344. Xalias:csc342
  345. Xpasswd:Wachtwoord
  346. Xgroup:178
  347. Xdisk:usr3
  348. Xfirstprog:0
  349. X
  350. Xcretin a a
  351. Xcretin a b
  352. Xcretin b a
  353. Xcollege jim bob
  354. Xcretin b b
  355. Xbch
  356. X
  357. X# programming languages
  358. Xprof:dmr
  359. Xpasswd:0
  360. Xalias:csc334
  361. Xdisk:/usr2
  362. Xgroup:179
  363. Xfirstprog:0
  364. X
  365. Xcretin a a
  366. Xfrn
  367. Xcretin a b
  368. Xcollege joe bob
  369. Xcretina b a
  370. Xcretinal b a
  371. Xcretinally terminal hazeltine
  372. Xcretin b b
  373. End
  374. echo ausr 1>&2
  375. sed -e 's/^X//' >ausr <<'End'
  376. XP#I'm not sure how to shar shell scripts, so I just arbitrarily
  377. XP#put a capital letter in column 1.  sed should snarf it fine.
  378. XP#!/bin/sh
  379. XP#adduser shell script ... bypasses most of the
  380. XP# agony the sysadm (SysVr2) route makes you go through
  381. XP#jhn 06jan87
  382. XPcase `uname` in
  383. XP    3b2b)
  384. XP        echo "puttem where? 2,3,or 4 [default is /usr] \c"
  385. XP        read blonk
  386. XP        case $blonk in
  387. XP            2) scrod=2;;
  388. XP            3) scrod=3;;
  389. XP            4) scrod=4;;
  390. XP            "") scrod="";;
  391. XP            *) echo "valid responses are <cr>, 2, 3, or 4.  Bye...";
  392. XP               exit;;
  393. XP        esac ;;
  394. XP    3b2a) scrod="";;
  395. XPesac #end case uname
  396. XPscrod=usr${scrod}
  397. XPecho "putting them in /$scrod
  398. XP    please wait ... looking for next avail userno" 
  399. XP
  400. XPgroup=100
  401. XPnextuser=`/usr/bin/awk -F: '$3+0>num+0 {num=$3+0}
  402. XPEND {print 1+num}' /etc/passwd `
  403. XP#nextuser=`expr $nextuser + 1`
  404. XPecho next available userno is $nextuser
  405. XP
  406. XPwhile : ; do
  407. XPecho "enter fullname \c"
  408. XPread fullname
  409. XPcase $fullname in
  410. XP    "") echo "null user fullname not allowed"; exit 1;;
  411. XPesac
  412. XP
  413. XPecho "enter loginname \c"
  414. XPread login
  415. XPcase $login in
  416. XP    "") echo "null user name not allowed"; exit 1;;
  417. XPesac
  418. XPecho "enter usernumber [$nextuser] \c"
  419. XPread user
  420. XPcase $user in
  421. XP    "") user=$nextuser;echo "using $user";;
  422. XPesac
  423. XPnextuser=`expr $user + 1`
  424. XPloop=true
  425. XPwhile :
  426. XPdo
  427. XP    echo "enter group (? for cat /etc/group) [$group] \c"
  428. XP    read xroup
  429. XP    case $xroup in
  430. XP        \?) cat /etc/group;;
  431. XP        "") break;;
  432. XP        *) group=$xroup;break;;
  433. XP    esac
  434. XPdone
  435. XPcase $group in
  436. XP    "") echo null group not allowed ... bye; exit 1;;
  437. XPesac
  438. XP
  439. XP/usr/bin/awk -F: '$1=='\"$login\"' || $3=='\"$user\"' {print}' /etc/passwd\
  440. XP    >/tmp/au$$
  441. XPalready=""
  442. XPif test -s /tmp/au$$
  443. XPthen
  444. XP    /bin/cat /tmp/au$$
  445. XP    echo "login=$login or user=$user in use ..."
  446. XP    rm -f /tmp/au$$
  447. XP    already=1
  448. XPfi
  449. XPif test -d /${scrod}/$login
  450. XPthen
  451. XP    echo "/${scrod}/$login already exists ... !"
  452. XP    rm -f /tmp/au$$
  453. XP    already=1
  454. XPfi
  455. XP
  456. XP
  457. XPcase $already in
  458. XP    "")
  459. XP    /bin/mkdir /${scrod}/$login
  460. XP    echo "$login::$user:$group:$fullname:/${scrod}/$login:"
  461. XP    echo "ok? [y] \c"
  462. XP    read doit
  463. XP    case $doit in
  464. XP        n) /bin/rmdir /${scrod}/$login; exit 1;;
  465. XP    esac
  466. XP    /bin/chmod u+w /etc/passwd
  467. XP    echo "$login::$user:$group:$fullname:/${scrod}/$login:">>/etc/passwd
  468. XP    sync
  469. XP    /bin/chmod u+w /etc/passwd
  470. XP    tail -2 /etc/passwd
  471. XP    /bin/chown $user /${scrod}/$login
  472. XP    /bin/chgrp $group /${scrod}/$login
  473. XP    /bin/chmod 755 /${scrod}/$login
  474. XP    /bin/cp /etc/stdprofile /${scrod}/$login/.profile
  475. XP    /bin/chown $user /${scrod}/$login/.profile
  476. XP    /bin/chgrp sys /${scrod}/$login/.profile
  477. XP    /bin/chmod gu+w /${scrod}/$login/.profile
  478. XP    case $umsk in
  479. XP        "") echo "enter umask [22]: \c"
  480. XP        read umsk
  481. XP                case $umsk in
  482. XP                "") umsk=22;;
  483. XP                esac
  484. XP        ;;
  485. XP    esac
  486. XP    echo "umask $umsk">>/${scrod}/$login/.profile
  487. XP    echo "menu-shell initially? [n]: \c"
  488. XP    read yesno
  489. XP    case $yesno in
  490. XP        y) echo "/usr/uncw/msh" >> /${scrod}/$login/.profile;;
  491. XP        *) echo "menu-shell not selected";;
  492. XP    esac
  493. XP    echo "give him a password? [y]: \c"
  494. XP    read yesno
  495. XP    case $yesno in
  496. XP        y|"") /bin/passwd $login;;
  497. XP        *) echo "no password set for $login";;
  498. XP    esac
  499. XP    rm -f /tmp/au$$
  500. XP    echo "put password aging in effect? [y]: \c"
  501. XP    read yesno
  502. XP    case $yesno in
  503. XP        y|"") /etc/agepw $login;;
  504. XP        n) echo password aging not set for $login;;
  505. XP    esac
  506. XP;;
  507. XPesac    #end of case $already==""
  508. XPcase $god in
  509. XP    "") echo "enter godname []: \c"
  510. XP    read god;;
  511. XP    *) ;;
  512. XPesac
  513. XPcase $god in
  514. XP    "") ;;
  515. XP    *) echo "$god:$login">>/etc/accesstab
  516. XP    ;;
  517. XPesac
  518. XPecho '***** done *****
  519. XP
  520. XP    want to add another user? [y] \c'
  521. XPread domore
  522. XPcase $domore in
  523. XP    n) exit;;
  524. XPesac
  525. XPdone
  526. XP
  527. End
  528. echo kusr 1>&2
  529. sed -e 's/^X//' >kusr <<'End'
  530. XPcase $1 in
  531. XP    "") echo "usage: /etc/kusr username"; exit 1;;
  532. XPesac
  533. XPx=`/usr/bin/awk -F: '$1=='\"$1\"' {print $6}' /etc/passwd `
  534. XPcase $x in
  535. XP/|/etc|/bin|/usr/bin|/usr/uncw|/lib|/usr/lib|/usr/spool ) \
  536. XP    echo "rm -r $x would be considered antisocial behavior";exit 1;;
  537. XP    "") echo no such user...bye; exit 1;;
  538. XP    /usr* ) ;;
  539. XP    *) echo "wtf?? x=$x"; exit 1;;
  540. XPesac
  541. XP
  542. XP#echo "about to rm -r $x ok [y] \c"
  543. XP#read ans
  544. XPans=y
  545. XPcase $ans in
  546. XP    "") rm -r $x;;
  547. XP    n) exit;;
  548. XP    y) rm -r $x;;
  549. XP    *) echo "invalid response ... $x not removed";exit;;
  550. XPesac
  551. XP#grep -v $1 /etc/passwd > /tmp/kusr$$
  552. XP/usr/bin/awk -F: '$1!='\"$1\"' {print }' /etc/passwd >/tmp/kusr$$
  553. XP#diff /etc/passwd /tmp/kusr$$
  554. XP#echo "ok? [y] \c"
  555. XP#read ans
  556. XPans=y
  557. XPcase $ans in
  558. XP    n) exit;;
  559. XP    ""|y) 
  560. XP        /bin/rm -f /usr/mail/$1;
  561. XP        cp /tmp/kusr$$ /etc/passwd ;
  562. XP        /bin/rm /tmp/kusr$$;;
  563. XP    *) echo "invalid response interpreted as \"no\" ";exit;;
  564. XPesac
  565. End
  566. echo already.c 1>&2
  567. sed -e 's/^X//' >already.c <<'End'
  568. X
  569. X#ifndef NULL
  570. X#include <stdio.h>
  571. X#endif
  572. Xalready(p)
  573. Xchar *p;
  574. X{
  575. X    int i;
  576. X    extern char *user[];
  577. X    i=0;
  578. X    /*printf("in already, looking for ...%s...",p);*/
  579. X    while(user[i]!=NULL){
  580. X        if(strcmp(p,user[i])==0){/*printf("found at %d...",i);*/
  581. X        return 1;}
  582. X        i++;
  583. X    }
  584. X    /*printf("not found, i=%d...",i);*/
  585. X    return 0;
  586. X}
  587. End
  588. echo ecpw.c 1>&2
  589. sed -e 's/^X//' >ecpw.c <<'End'
  590. X
  591. Xchar salts[63]= /*must be 63 to leave room for the null*/
  592. X"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
  593. X/*1234567890123456789012345678901234567890123456789012345678901*/
  594. X/*0000000001111111111222222222233333333334444444444555555555566*/
  595. X/* don't use / or . because one manual says one thing, and the other
  596. X  manual says another thing.  stick with letters and digits for salt.
  597. X*/
  598. X
  599. Xecpw(pwd)
  600. Xchar *pwd;
  601. X{
  602. X    /*side effect: modifies ecptex*/
  603. X    extern char ecptex[];
  604. X    void extern exit();
  605. X    char *result,*crypt();
  606. X    char salt[3];
  607. X    salt[0]=salts[rand()%62];
  608. X    salt[1]=salts[rand()%62];
  609. X    salt[2]='\0';
  610. X
  611. X    result=crypt(pwd,salt);
  612. X    (void) strcpy(ecptex,result);
  613. X}
  614. End
  615. echo exists.c 1>&2
  616. sed -e 's/^X//' >exists.c <<'End'
  617. X
  618. X#ifndef ENOENT
  619. X#include <sys/types.h>
  620. X#include <sys/stat.h>
  621. X#include <errno.h>
  622. X#endif
  623. Xexists(filename)
  624. Xchar *filename;
  625. X{
  626. X    extern int errno;
  627. X    struct stat buf;
  628. X    if(stat(filename,&buf)== -1 && errno==ENOENT)return 0;
  629. X    return 1;
  630. X}
  631. End
  632. echo initfiles.c 1>&2
  633. sed -e 's/^X//' >initfiles.c <<'End'
  634. X#include "autoadd.h"
  635. Xinitfiles()
  636. X{
  637. X    extern int euid;
  638. X    extern char passwd[], proffile[];
  639. X    if(euid==ROOT){
  640. X        strcpy(passwd,"/etc/passwd");
  641. X        strcpy(proffile,"/etc/accesstab");}
  642. X    else{
  643. X        strcpy(passwd,"passwd");
  644. X        strcpy(proffile,"accesstab");}
  645. X}
  646. End
  647. echo kindex.c 1>&2
  648. sed -e 's/^X//' >kindex.c <<'End'
  649. Xkindex(s,t) 
  650. Xchar s[],t[];
  651. X{
  652. X    extern void exit();
  653. X/* slightly beefed up version of "index" from the middle
  654. Xof p. 67 K&R */
  655. X    int c,i,j,k;
  656. X    c=s[0];
  657. X    if(c==0){i=puts("in kindex ... dummy, s[0] is zero");j=i;
  658. X        puts(t);
  659. X        if(i==j)exit(1);}
  660. X    c=t[0];
  661. X    if(c==0){i=puts("in kindex ... dummy, t[0] is zero");j=i;
  662. X        puts(s);
  663. X        if(j==i)exit(1);}
  664. X    for(i=0;s[i] !='\0'; i++){
  665. X        for(j=i,k=0;t[k] !='\0' && s[j]==t[k];j++,k++)
  666. X                ;
  667. X        if(t[k]=='\0')return (i);
  668. X    }
  669. X        return(-1);
  670. X} 
  671. X
  672. End
  673. echo main.c 1>&2
  674. sed -e 's/^X//' >main.c <<'End'
  675. X#define MAIN
  676. X#include "autoadd.h"
  677. X
  678. Xmain(argc,argv)
  679. Xint argc;
  680. Xchar *argv[];
  681. X{
  682. X    char systemline[100],profilename[100],directory[100],shellname[100];
  683. X    char answer[9];
  684. X    int i,j,k,how,nextu,unum,maxunum,groupnumber,firstalias,cshell;
  685. X    extern int geteuid();
  686. X    FILE *fp1,*fp2,*fp3,*fp4,*fopen();
  687. X    long time();
  688. X    void srand(); /*to make lint shut up*/
  689. X
  690. X/*some executable initializations:*/
  691. X    euid=geteuid(); /*should be first executable stmt*/
  692. X    initfiles(); /*executably set sensitive filenames*/
  693. X    strcpy(groupname,GROUP); /*100 our default group*/
  694. X    strcpy(diskname,DISK);   /* /usr our default disk*/
  695. X    strcpy(shellname,SHELL);
  696. X    strcpy(aliasname,ALIAS); 
  697. X    strcpy(firstprog,FIRSTPROG);
  698. X    strcpy(profname,PROFESSOR);
  699. X    strcpy(passwordname,PASSWD);
  700. X    strcpy(dislist,DISLIST);
  701. X    firstalias=cshell=0; 
  702. X    for(i=0;i<MAXNU;++i)user[i]=NULL;
  703. X    srand((unsigned int)time(0L));
  704. X
  705. X/*open the password file in read mode to see who's already there */
  706. X    fp1=fopen("/etc/passwd","r");
  707. X    if(fp1==NULL)quit("/etc/passwd");
  708. X    j=0;
  709. X    maxunum= -1;
  710. X    while(fgets(line,120,fp1)==line){
  711. X        i=kindex(line,":");
  712. X        line[i]='\0';
  713. X        k=i+1;
  714. X        while(line[k]!=':')k++;
  715. X        sscanf(&line[k+1],"%d",&unum);
  716. X        if(unum>maxunum)maxunum=unum;
  717. X        user[j]=malloc((unsigned)i+1);
  718. X        strcpy(user[j],line);
  719. X        j++;
  720. X    }
  721. X    nextu=j;
  722. X    if(fclose(fp1)<0)quit("/etc/passwd");
  723. X/* thru reading /etc/passwd */
  724. X    if(argc>=2)
  725. X        strcpy(infile,argv[1]);
  726. X    else{
  727. X        printf("input filename:");
  728. X        scanf("%s",infile);
  729. X    }
  730. X/* open the input file in read mode */
  731. X    fp1=fopen(infile,"r");
  732. X    if(fp1==NULL)quit(infile);
  733. X/* open /etc/passwd in append mode */
  734. X    fp2=fopen(passwd,"a");
  735. X    if(fp2==NULL)quit(passwd);
  736. X#ifdef ACCESS
  737. X/* open /etc/accesstab in append mode */
  738. X    fp3=fopen(proffile,"a");
  739. X    if(fp3==NULL)quit(proffile);
  740. X#endif
  741. X    profname[0]=null;
  742. X/* open mailrc in append mode */
  743. X    fp4=fopen(dislist,"a");
  744. X    if(fp4==NULL)quit(dislist);
  745. X/* process input file */
  746. X    while(fgets(line,120,fp1)==line){
  747. X        if(*line==' ' || *line=='#' || *line=='\n' || *line==null)
  748. X            continue;
  749. X        for(i=0;line[i];i++)if(line[i]<' '){
  750. X            line[i]='\0';
  751. X            break;
  752. X        }
  753. X#ifdef ACCESS
  754. X        if((i=kindex(line,"prof:"))>=0){
  755. X            strcpy(profname,&line[i+strlen("prof:")]);
  756. X        }
  757. X        else
  758. X#endif
  759. X
  760. X         if((i=kindex(line,"disk:"))>=0){
  761. X            strcpy(diskname,&line[i+strlen("disk:")]);
  762. X            if(diskname[0]!='/'){
  763. X                strcpy(diskname,"/");
  764. X                strcat(diskname,&line[i+strlen("disk:")]);}
  765. X            if(euid!=ROOT){
  766. X                strcpy(parentdir,".");
  767. X                strcat(parentdir,diskname);} 
  768. X            else 
  769. X                strcpy(parentdir,diskname);
  770. X            if(!exists(parentdir)){
  771. X                /*if not root, don't bother asking, just do it */
  772. X                if(euid==ROOT){
  773. X                    printf(
  774. X                    "%s doesn't seem to exist, shall I mkdir it?(y/n): "
  775. X                        ,parentdir);
  776. X                    scanf("%s",answer);
  777. X                    if(kindex(answer,"y")!=0)quit(parentdir);
  778. X                }
  779. X                /*else{*/
  780. X                    strcpy(systemline,"mkdir ");
  781. X                    strcat(systemline,parentdir);
  782. X                    system(systemline);
  783. X                    if(!exists(parentdir))quit(parentdir);
  784. X                /*}*/
  785. X            }
  786. X        }
  787. X
  788. X        else if((i=kindex(line,"firstprog:"))>=0){
  789. X            strcpy(firstprog,&line[i+strlen("firstprog:")]);
  790. X        }
  791. X        else if((i=kindex(line,"alias:"))>=0){
  792. X            strcpy(aliasname,&line[i+strlen("alias:")]);
  793. X            if(aliasname[0]!='0'){
  794. X                fprintf(fp4,
  795. X                    firstalias?"\nalias %s ":"alias %s ",aliasname);
  796. X                firstalias=1;
  797. X            }
  798. X        }
  799. X
  800. X
  801. X        else if((i=kindex(line,"group:"))>=0){
  802. X            strcpy(groupname,&line[i+strlen("group:")]);
  803. X            sscanf(groupname,"%d",&groupnumber);
  804. X        }
  805. X
  806. X        else if((i=kindex(line,"shell:"))>=0){
  807. X            strcpy(shellname,&line[i+strlen("shell:")]);
  808. X            if(kindex(shellname,"csh")>0)cshell=1;else cshell=0;
  809. X        }
  810. X
  811. X        else if((i=kindex(line,"passwd:"))>=0){
  812. X            strcpy(passwordname,&line[i+strlen("passwd:")]);
  813. X        }
  814. X
  815. X        else if((i=kindex(line,"password:"))>=0){
  816. X            strcpy(passwordname,&line[i+strlen("password:")]);
  817. X        }
  818. X        else{
  819. X            if(kindex(line,":")>=0){
  820. X                printf("IGNORED:%s\n",line);continue;}
  821. X            parse();
  822. X            strcpy(username,lastname);
  823. X            how=0;
  824. Xfor(;;){
  825. X            strcpy(directory,parentdir);
  826. X            strcat(directory,"/");
  827. X            strcat(directory,username);
  828. X            if(exists(directory) || already(username))
  829. X            {
  830. X                tryagain(how);
  831. X                username[ML]=null;
  832. X                how++;
  833. X            }
  834. X            else
  835. X                break;
  836. X}
  837. X                strcpy(systemline,"mkdir ");
  838. X                strcat(systemline,directory);
  839. X                system(systemline);
  840. X                if(!exists(directory))quit(directory);/*failed*/
  841. X            
  842. X            
  843. X            user[nextu]=malloc((unsigned)strlen(username)+1);
  844. X            strcpy(user[nextu],username);
  845. X            nextu++;
  846. X
  847. X            if(passwordname[0]=='0' || passwordname[0]==null)
  848. X                ecptex[0]=null;
  849. X            else if (passwordname[0] == '1')
  850. X                ecpw(username);
  851. X            else
  852. X                ecpw(passwordname); 
  853. X
  854. X            fprintf(fp2,"%s:%s:%d:%s:%s:%s/%s:%s\n"
  855. X                ,username,ecptex,++maxunum,groupname,line,
  856. X                diskname,username,shellname[0]!='0'?shellname:"");
  857. X            if(aliasname[0]!='0')
  858. X                fprintf(fp4,"\\\n%s ",username);/*for dislist*/
  859. X
  860. X            unum=maxunum;
  861. X#ifdef ACCESS
  862. X            if(*profname&&*profname!='0')
  863. X                fprintf(fp3,"%s:%s\n",profname,username);
  864. X#endif
  865. X
  866. X            strcpy(profilename,directory);
  867. X            strcat(profilename,cshell?LOGIN:PROFILE);
  868. X            if(!exists(profilename)){
  869. X            strcpy(systemline,"cp ");
  870. X            strcat(systemline,STDPROFILE /*"/etc/stdprofile "*/);
  871. X            strcat(systemline," "); /*just in case*/
  872. X            strcat(systemline,profilename);
  873. X            system(systemline);
  874. X                if(firstprog[0]!='0'){
  875. X                    strcpy(systemline,"echo ");
  876. X                    strcat(systemline,firstprog);
  877. X                    strcat(systemline," >> ");
  878. X                    strcat(systemline,profilename);
  879. X                    system(systemline);
  880. X                }
  881. X            }
  882. X            if(euid==ROOT){
  883. X            /*do the chowns only if running as root (effective uid)*/
  884. X                if(chown(directory,unum,groupnumber)<0)quit(directory);
  885. X                if(chown(profilename,unum,3 /*3=="sys"*/)<0)
  886. X                    quit(profilename);
  887. X            }
  888. X
  889. X
  890. X        }
  891. X    } /*end of file on input file */
  892. X    if(firstalias)
  893. X        fprintf(fp4,"\n");/*close out the last line of dislist*/
  894. X    return 0; /* lint */
  895. X}
  896. End
  897. echo parse.c 1>&2
  898. sed -e 's/^X//' >parse.c <<'End'
  899. X
  900. X
  901. X
  902. X#include "autoadd.h"
  903. Xparse()
  904. X{
  905. X    int i=0;
  906. X    int j;
  907. X    extern char lastname[],fi[],mi[],line[];
  908. X    lastname[0]=mi[0]=fi[0]='1';
  909. X    lastname[ML]=fi[1]=mi[1]=null;
  910. X    j=strlen(line);
  911. X    while(line[i]==' ' && i<j)i++;
  912. X    while(line[i] && line[i]!=' ' && i<ML && i<j)
  913. X        {lastname[i]=line[i];i++;}
  914. X    lastname[i]=lastname[ML]='\0';
  915. X    if(i>=j)return;
  916. X    while(line[i]!=' ' && i<j)i++;
  917. X    while(line[i]==' ' && i<j)i++;
  918. X    if(i>=j)return;
  919. X    fi[0]=line[i++];
  920. X    fi[1]='\0';
  921. X    if(i>=j)return;
  922. X    while(line[i]!=' ' && i<j)i++;
  923. X    while(line[i]==' ' && i<j)i++;
  924. X    if(line[i])mi[0]=line[i];
  925. X    mi[1]='\0';
  926. X}
  927. X
  928. End
  929. echo quit.c 1>&2
  930. sed -e 's/^X//' >quit.c <<'End'
  931. Xquit(p)
  932. Xchar *p;
  933. X{
  934. X    extern void exit();
  935. X    puts(
  936. X"******* something went wrong here that I can't figure out********"
  937. X    );
  938. X    puts(p);
  939. X    puts("I'm outta here...");
  940. X    exit(1);
  941. X}
  942. End
  943. echo tryagain.c 1>&2
  944. sed -e 's/^X//' >tryagain.c <<'End'
  945. X#include "autoadd.h"
  946. Xtryagain(how)
  947. X{
  948. X    extern char fi[],lastname[],mi[],username[];
  949. X    char temp[49];
  950. Xswitch(how){
  951. Xcase 0:
  952. X    strcpy(temp,fi);
  953. X    strcat(temp,lastname);
  954. X    break;
  955. Xcase 1:
  956. X    strncpy(temp,lastname,ML-1);
  957. X    temp[ML-1]='\0';
  958. X    strcat(temp,fi);
  959. X    break;
  960. Xcase 2:
  961. X    strncpy(temp,lastname,ML-2);
  962. X    temp[ML-2]='\0';
  963. X    strcat(temp,fi);
  964. X    strcat(temp,mi);
  965. X    break;
  966. Xcase 3:
  967. X    strcpy(temp,fi);
  968. X    strcat(temp,mi);
  969. X    strcat(temp,lastname);
  970. X    break;
  971. Xcase 4:
  972. X    strcpy(temp,fi);
  973. X    strncat(temp,lastname,ML-2);
  974. X    temp[ML-1]='\0';
  975. X    strcat(temp,mi);
  976. X    break;
  977. Xdefault:
  978. X    sprintf(temp,"%d%s",how>4?how-4+1:how /*this 4 is dangerous*/
  979. X    ,lastname);
  980. X    break;
  981. X}
  982. X/*    temp[ML]='\0';*/ /* let main do it!*/
  983. X    strcpy(username,temp);
  984. X}
  985. End
  986.  
  987.