home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1994 March / Source_Code_CD-ROM_Walnut_Creek_March_1994.iso / compsrcs / misc / volume38 / shadow / part05 < prev    next >
Encoding:
Text File  |  1993-08-14  |  60.6 KB  |  2,232 lines

  1. Newsgroups: comp.sources.misc
  2. From: jfh@rpp386.cactus.org (John F. Haugh II)
  3. Subject: v38i124:  shadow - Shadow Password Suite, v3.3, Part05/14
  4. Message-ID: <1993Aug14.192420.9351@sparky.sterling.com>
  5. X-Md4-Signature: 44a2f7469f44fb6b498e0d056f038ee8
  6. Sender: kent@sparky.sterling.com (Kent Landfield)
  7. Organization: Sterling Software
  8. Date: Sat, 14 Aug 1993 19:24:20 GMT
  9. Approved: kent@sparky.sterling.com
  10.  
  11. Submitted-by: jfh@rpp386.cactus.org (John F. Haugh II)
  12. Posting-number: Volume 38, Issue 124
  13. Archive-name: shadow/part05
  14. Environment: UNIX
  15. Supersedes: shadow: Volume 26, Issue 54-64
  16.  
  17. #! /bin/sh
  18. # This is a shell archive.  Remove anything before this line, then feed it
  19. # into a shell via "sh file" or similar.  To overwrite existing files,
  20. # type "sh file -c".
  21. # Contents:  Makefile.sun4 chsh.c login.5 newusers.c
  22. # Wrapped by kent@sparky on Sat Aug 14 14:11:39 1993
  23. PATH=/bin:/usr/bin:/usr/ucb:/usr/local/bin:/usr/lbin ; export PATH
  24. echo If this archive is complete, you will see the following message:
  25. echo '          "shar: End of archive 5 (of 14)."'
  26. if test -f 'Makefile.sun4' -a "${1}" != "-c" ; then 
  27.   echo shar: Will not clobber existing file \"'Makefile.sun4'\"
  28. else
  29.   echo shar: Extracting \"'Makefile.sun4'\" \(18789 characters\)
  30.   sed "s/^X//" >'Makefile.sun4' <<'END_OF_FILE'
  31. X#
  32. X# Copyright 1988,1989,1990,1991,1992,1993 John F. Haugh II
  33. X# All rights reserved.
  34. X#
  35. X# Permission is granted to copy and create derivative works for any
  36. X# non-commercial purpose, provided this copyright notice is preserved
  37. X# in all copies of source code, or included in human readable form
  38. X# and conspicuously displayed on all copies of object code or
  39. X# distribution media.
  40. X#
  41. X# This software is provided on an AS-IS basis and the author makes
  42. X# no warrantee of any kind.
  43. X#
  44. X#    @(#)Makefile.sun4    3.11    08:11:03  - Shadow password system (SunOS 4.1.1 version)
  45. X#
  46. X#    @(#)Makefile.sun4    3.11    08:11:03    19 Jul 1993
  47. X#
  48. XSHELL = /bin/sh
  49. X
  50. X#
  51. X# Set this flag to decide what level of code "get" returns.
  52. X# The base USENET release was release 1.  It is no longer supported.
  53. X# The version with the utilities added was release 2.
  54. X# The version with database-like file access is release 3.
  55. XRELEASE = 3
  56. XGFLAGS = -t -r$(RELEASE)
  57. X
  58. X# SunOS 4.1.1 uses /usr/bin
  59. XLOGINDIR = /usr/bin
  60. X
  61. X# SunOS 4.1.1 requires no extra libraries
  62. XNDIR = 
  63. X
  64. X# Define some stuff for Cracklib.  This assumes that libcracklib.a is
  65. X# in a system directory.
  66. X# CRACKDEF='-DCRACKLIB_DICTPATH="$(DICTPATH)"'
  67. X# CRACKLIB=-lcrack
  68. X
  69. X# Pick your favorite C compiler and tags command
  70. XCC = /bin/cc
  71. XTAGS = ctags
  72. X
  73. X# SunOS 4.1.1 is SUN4
  74. XOS = -DSUN4
  75. X
  76. X# SunOS 4.1.1 uses ranlib
  77. XRANLIB = ranlib
  78. X
  79. X# Configuration Flags
  80. X#
  81. X#    DEST_INCLUDE_DIR - local include files
  82. X#    LIBS - system libraries
  83. X#        -lsocket - needed for TCP/IP and possibly SYSLOG
  84. X#        -ldbm or -lndbm - needed for DBM support
  85. X#        -lcrypt - needed for SCO crypt() functions
  86. X#    CFLAGS - C compiler flags
  87. X#        -DLAI_TCP - needed for SCO Xenix Lachman TCP/IP
  88. X
  89. XDEST_INCLUDE_DIR = /usr/include
  90. X
  91. X# Flags for SunOS 4.1.1
  92. XCFLAGS = -O2 $(OS) $(DEST_INCLUDE_DIR) $(CRACKDEF)
  93. XLIBS =
  94. XLDFLAGS = 
  95. X
  96. X# Library for SunOS 4.1.1
  97. XLIBSEC = libsec.a
  98. X
  99. X# Names for root user and group, and bin user and group.  See your
  100. X# /etc/passwd and /etc/group files.  This is for SunOS 4.1.1
  101. XRUID = root
  102. XRGID = wheel
  103. XBUID = bin
  104. XBGID = bin
  105. X
  106. X# Where the login.defs file will be copied.  Must agree with config.h
  107. XDEST_LOGIN_DEFS = /etc/login.defs
  108. X
  109. X# Rules for .L (lint) files.
  110. X.SUFFIXES: .L
  111. XLINT = lint
  112. XLINTFLAGS = $(OS) -Dlint
  113. X
  114. X.c.L:
  115. X    $(LINT) -pxu $(LINTFLAGS) $*.c > $*.L
  116. X
  117. XLOBJS = lmain.o login.o env.o valid.o setup.o shell.o age.o \
  118. X    utmp.o sub.o mail.o motd.o log.o ttytype.o failure.o \
  119. X    tz.o console.o hushed.o
  120. X
  121. XLSRCS = lmain.c login.c env.c valid.c setup.c shell.c age.c \
  122. X    utmp.c sub.c mail.c motd.c log.c ttytype.c failure.c \
  123. X    tz.c console.c hushed.c
  124. X
  125. XSOBJS = smain.o env.o entry.o susetup.o shell.o \
  126. X    sub.o mail.o motd.o sulog.o age.o tz.o hushed.o
  127. X
  128. XSSRCS = smain.c env.c entry.c setup.c shell.c \
  129. X    pwent.c sub.c mail.c motd.c sulog.c shadow.c age.c pwpack.c rad64.c \
  130. X    tz.c hushed.c
  131. X
  132. XPOBJS = passwd.o obscure.o
  133. XPSRCS = passwd.c obscure.c
  134. X
  135. XGPSRCS = gpmain.c
  136. X
  137. XGPOBJS = gpmain.o
  138. X
  139. XPWOBJS = pwconv.o
  140. X
  141. XPWSRCS = pwconv.c pwent.c shadow.c pwpack.c rad64.c
  142. X
  143. XPWUNOBJS = pwunconv.o
  144. X
  145. XPWUNSRCS = pwunconv.c pwent.c shadow.c pwpack.c rad64.c
  146. X
  147. XSULOGOBJS = sulogin.o entry.o env.o age.o setup.o \
  148. X    valid.o shell.o tz.o
  149. X
  150. XSULOGSRCS = sulogin.c entry.c env.c age.c pwent.c setup.c \
  151. X    shadow.c shell.c valid.c pwpack.c tz.c
  152. X
  153. XMKPWDOBJS = mkpasswd.o
  154. X
  155. XMKPWDSRCS = mkpasswd.c
  156. X
  157. XNGSRCS = newgrp.c env.c shell.c
  158. X
  159. XNGOBJS = newgrp.o env.o shell.o
  160. X
  161. XCHFNSRCS = chfn.c fields.c
  162. XCHFNOBJS = chfn.o fields.o
  163. XCHSHSRCS = chsh.c fields.c
  164. XCHSHOBJS = chsh.o fields.o
  165. XCHAGEOBJS = chage.o fields.o
  166. XCHAGESRCS = chage.c fields.c
  167. XCHPASSOBJS = chpasswd.o
  168. XCHPASSSRCS = chpasswd.c
  169. XDPSRCS = dpmain.c
  170. XDPOBJS = dpmain.o
  171. X
  172. XALLSRCS = age.c dialchk.c dialup.c entry.c env.c lmain.c log.c login.c mail.c \
  173. X    motd.c obscure.c passwd.c pwconv.c pwent.c pwunconv.c getpass.c \
  174. X    setup.c shadow.c shell.c smain.c sub.c sulog.c sulogin.c ttytype.c \
  175. X    utmp.c valid.c port.c newgrp.c gpmain.c grent.c mkpasswd.c pwpack.c \
  176. X    chfn.c chsh.c chage.c rad64.c encrypt.c chpasswd.c shadowio.c pwio.c \
  177. X    newusers.c groupio.c fields.c pwdbm.c grpack.c grdbm.c sppack.c \
  178. X    spdbm.c dpmain.c gshadow.c gsdbm.c gspack.c sgroupio.c useradd.c \
  179. X    userdel.c patchlevel.h usermod.c copydir.c mkrmdir.c groupadd.c \
  180. X    groupdel.c groupmod.c tz.c console.c hushed.c getdef.c scologin.c \
  181. X    logoutd.c groups.c pwauth.c lockpw.c chowndir.c
  182. X
  183. XFILES1 = README patchlevel.h newgrp.c Makefile config.h pwunconv.c obscure.c \
  184. X    age.c id.c
  185. X
  186. XFILES2 = passwd.c port.c lmain.c sulogin.c pwpack.c dialup.c
  187. X
  188. XFILES3 = chfn.c chsh.c smain.c faillog.c pwconv.c shadow.c pwck.c
  189. X
  190. XFILES4 = gpmain.c chage.c pwent.c valid.c setup.c entry.c ttytype.c port.h
  191. X
  192. XFILES5 = pwio.c encrypt.c chpasswd.c newusers.c rad64.c dialchk.c faillog.h \
  193. X    pwdbm.c grdbm.c gshadow.c sppack.c grpck.c
  194. X
  195. XFILES6 = gspack.c spdbm.c lastlog.h shell.c login.c sub.c dpmain.c mail.c \
  196. X    env.c pwd.h.m4 grpack.c shadow.h log.c grent.c motd.c dialup.h \
  197. X    fields.c gsdbm.c utmp.c failure.c
  198. X
  199. XFILES7 = groupio.c shadowio.c sgroupio.c groups.c copydir.c mkrmdir.c \
  200. X    mkpasswd.c pwauth.c pwauth.h lastlog.c
  201. X
  202. XFILES8 = useradd.c usermod.c login.defs
  203. X
  204. XFILES9 = groupadd.c groupdel.c groupmod.c tz.c console.c hushed.c getdef.c \
  205. X    scologin.c logoutd.c sulog.c getpass.c userdel.c lockpw.c chowndir.c
  206. X
  207. XFILES_SUN4 = Makefile.sun4 README.sun4 config.h.sun4
  208. XFILES_SVR4 = Makefile.svr4 config.h.svr4
  209. X
  210. XMAN_1 = chage.1 chfn.1 chsh.1 id.1 login.1 newgrp.1 passwd.1 su.1 \
  211. X    useradd.1 userdel.1 usermod.1 groupadd.1 groupdel.1 groupmod.1 \
  212. X    groups.1 pwck.1 grpck.1
  213. XMAN_3 = shadow.3 pwauth.3
  214. XMAN_4 = faillog.4 passwd.4 porttime.4 shadow.4
  215. XMAN_5 = login.5
  216. XMAN_8 = chpasswd.8 dpasswd.8 faillog.8 newusers.8 pwconv.8 pwunconv.8 \
  217. X    sulogin.8 mkpasswd.8 logoutd.8 pwauth.8 lastlog.8
  218. X
  219. XDOCS1 = $(MAN_1) $(MAN_3) $(MAN_4)
  220. XDOCS2 = $(MAN_5) $(MAN_8)
  221. XDOCS = $(DOCS1) $(DOCS2)
  222. X
  223. XBINS = su login pwconv pwunconv passwd sulogin faillog newgrp gpasswd \
  224. X    mkpasswd chfn chsh chage chpasswd newusers dpasswd id useradd \
  225. X    userdel usermod groupadd groupdel groupmod logoutd groups \
  226. X    pwck grpck lastlog
  227. X
  228. Xall:    $(BINS) $(DOCS)
  229. X
  230. X.PRECIOUS: libshadow.a
  231. X
  232. Xlibshadow.a: \
  233. X    libshadow.a(dialchk.o) \
  234. X    libshadow.a(dialup.o) \
  235. X    libshadow.a(encrypt.o) \
  236. X    libshadow.a(getdef.o) \
  237. X    libshadow.a(getpass.o) \
  238. X    libshadow.a(grdbm.o) \
  239. X    libshadow.a(grent.o) \
  240. X    libshadow.a(groupio.o) \
  241. X    libshadow.a(grpack.o) \
  242. X    libshadow.a(gshadow.o) \
  243. X    libshadow.a(gsdbm.o) \
  244. X    libshadow.a(gspack.o) \
  245. X    libshadow.a(sgroupio.o) \
  246. X    libshadow.a(port.o) \
  247. X    libshadow.a(pwdbm.o) \
  248. X    libshadow.a(pwent.o) \
  249. X    libshadow.a(pwio.o) \
  250. X    libshadow.a(pwpack.o) \
  251. X    libshadow.a(pwauth.o) \
  252. X    libshadow.a(rad64.o) \
  253. X    libshadow.a(spdbm.o) \
  254. X    libshadow.a(shadow.o) \
  255. X    libshadow.a(shadowio.o) \
  256. X    libshadow.a(sppack.o) \
  257. X    libshadow.a(lockpw.o)
  258. X    $(RANLIB) libshadow.a
  259. X
  260. Xlibsec: $(LIBSEC)(shadow.o)
  261. X    $(RANLIB) $(LIBSEC)
  262. X
  263. Xsave:
  264. X    [ ! -d save ] && mkdir save
  265. X    -cp $(LOGINDIR)/login save
  266. X    -cp /etc/mkpasswd /etc/pwconv /etc/pwunconv /etc/sulogin /etc/chpasswd \
  267. X        /etc/newusers /etc/useradd /etc/userdel /etc/usermod \
  268. X        /etc/groupadd /etc/groupdel /etc/groupmod /etc/logoutd \
  269. X        /etc/login.defs /etc/pwck /etc/grpck save
  270. X    -cp /bin/su /bin/passwd /bin/gpasswd /bin/dpasswd /bin/faillog \
  271. X        /bin/newgrp /bin/chfn /bin/chsh /bin/chage /bin/id \
  272. X        /bin/scologin save
  273. X    -cp $(DEST_INCLUDE_DIR)/dialup.h $(DEST_INCLUDE_DIR)/shadow.h \
  274. X        $(DEST_INCLUDE_DIR)/pwd.h save
  275. X
  276. Xrestore:
  277. X    [ -d save ]
  278. X    -(cd save ; cp login $(LOGINDIR) )
  279. X    -(cd save ; -cp mkpasswd pwconv pwunconv sulogin chpasswd \
  280. X        newusers useradd userdel usermod groupadd groupdel groupmod \
  281. X        logoutd login.defs pwck grpck /etc)
  282. X    -(cd save ; cp su passwd gpasswd dpasswd faillog newgrp chfn chsh \
  283. X        chage id scologin /bin)
  284. X    -(cd save ; cp dialup.h shadow.h pwd.h $(DEST_INCLUDE_DIR) )
  285. X
  286. Xinstall: all
  287. X    strip $(BINS)
  288. X    cp login $(LOGINDIR)/login
  289. X    cp mkpasswd /etc 
  290. X    cp pwconv /etc 
  291. X    cp pwunconv /etc 
  292. X    cp sulogin /etc 
  293. X    cp chpasswd /etc 
  294. X    cp newusers /etc 
  295. X    cp useradd /etc 
  296. X    cp userdel /etc 
  297. X    cp usermod /etc 
  298. X    cp groupadd /etc 
  299. X    cp groupdel /etc 
  300. X    cp groupmod /etc 
  301. X    cp logoutd /etc
  302. X    cp pwck /etc
  303. X    cp grpck /etc
  304. X    cp su /bin
  305. X    cp passwd /bin
  306. X    cp gpasswd /bin
  307. X    cp dpasswd /bin
  308. X    cp faillog /bin
  309. X    cp newgrp /bin
  310. X    cp chfn /bin
  311. X    cp chsh /bin
  312. X    cp chage /bin
  313. X    cp id /bin
  314. X    cp dialup.h shadow.h pwd.h $(DEST_INCLUDE_DIR)
  315. X    chown $(RUID) $(LOGINDIR)/login /etc/pwconv /etc/pwunconv /etc/sulogin \
  316. X        /bin/su /bin/passwd /bin/gpasswd /bin/newgrp /etc/mkpasswd \
  317. X        /bin/dpasswd /bin/chsh /bin/chfn /bin/chage /etc/useradd \
  318. X        /etc/userdel /etc/usermod /etc/groupadd /etc/groupdel \
  319. X        /etc/groupmod /etc/logoutd /etc/pwck /etc/grpck
  320. X    chgrp $(RGID) $(LOGINDIR)/login /etc/pwconv /etc/pwunconv /etc/sulogin \
  321. X        /bin/su /bin/passwd /bin/gpasswd /bin/newgrp /etc/mkpasswd \
  322. X        /bin/dpasswd /bin/chsh /bin/chfn /bin/chage /etc/useradd \
  323. X        /etc/userdel /etc/usermod /etc/groupadd /etc/groupdel \
  324. X        /etc/groupmod /etc/logoutd /etc/pwck /etc/grpck
  325. X    chown $(BUID) /bin/faillog /bin/id $(DEST_INCLUDE_DIR)/shadow.h \
  326. X        $(DEST_INCLUDE_DIR)/dialup.h $(DEST_INCLUDE_DIR)/pwd.h
  327. X    chgrp $(BGID) /bin/faillog /bin/id $(DEST_INCLUDE_DIR)/shadow.h \
  328. X        $(DEST_INCLUDE_DIR)/dialup.h $(DEST_INCLUDE_DIR)/pwd.h
  329. X    chmod 700 /etc/pwconv /etc/pwunconv /etc/sulogin /etc/mkpasswd \
  330. X        /etc/chpasswd /etc/newusers /bin/dpasswd /bin/chage \
  331. X        /etc/useradd /etc/userdel /etc/usermod /etc/groupadd \
  332. X        /etc/groupdel /etc/groupmod /etc/logoutd /etc/pwck \
  333. X        /etc/grpck
  334. X    chmod 4711 $(LOGINDIR)/login /bin/su /bin/passwd /bin/gpasswd \
  335. X        /bin/newgrp /bin/chfn /bin/chsh
  336. X    chmod 711 /bin/faillog /bin/id
  337. X    chmod 444 $(DEST_INCLUDE_DIR)/shadow.h $(DEST_INCLUDE_DIR)/dialup.h \
  338. X        $(DEST_INCLUDE_DIR)/pwd.h
  339. X    [ -f $(DEST_LOGIN_DEFS) ] || (cp login.defs $(DEST_LOGIN_DEFS) ; \
  340. X        chown $(RUID) $(DEST_LOGIN_DEFS) ; \
  341. X        chgrp $(RGID) $(DEST_LOGIN_DEFS) ; \
  342. X        chmod 600 $(DEST_LOGIN_DEFS) )
  343. X
  344. Xlint:    su.lint login.lint pwconv.lint pwunconv.lint passwd.lint sulogin.lint \
  345. X    faillog.lint newgrp.lint gpasswd.lint mkpasswd.lint chfn.lint \
  346. X    chsh.lint chage.lint dpasswd.lint id.lint useradd.lint userdel.lint \
  347. X    usermod.lint groupadd.lint groupdel.lint groupmod.lint logoutd.lint \
  348. X    pwck.lint grpck.lint \
  349. X    $(ALLSRCS:.c=.L)
  350. X
  351. Xtags:    $(ALLSRCS)
  352. X    $(TAGS) $(ALLSRCS)
  353. X
  354. XREADME:
  355. X    [ -f s.README ] && get -t -r$(RELEASE) s.README
  356. X    
  357. X$(DOCS):
  358. X    [ -f s.$@ ] && get -t -r$(RELEASE) s.$@
  359. X
  360. Xlogin.defs:
  361. X    [ -f s.login.defs ] && get -t -r$(RELEASE) s.login.defs
  362. X
  363. XMakefile.sun4:
  364. X    [ -f s.Makefile.sun4 ] && get -t -r$(RELEASE) s.Makefile.sun4
  365. X
  366. XREADME.sun4:
  367. X    [ -f s.README.sun4 ] && get -t -r$(RELEASE) s.README.sun4
  368. X
  369. Xconfig.h.sun4:
  370. X    [ -f s.config.h.sun4 ] && get -t -r$(RELEASE) s.config.h.sun4
  371. X
  372. Xlogin:    $(LOBJS) libshadow.a
  373. X    $(CC) -o login $(LDFLAGS) $(LOBJS) libshadow.a $(LIBS)
  374. X
  375. Xlogin.lint: $(LSRCS)
  376. X    $(LINT) $(LINTFLAGS) $(LSRCS) > login.lint
  377. X
  378. Xsu:    $(SOBJS) libshadow.a
  379. X    $(CC) -o su $(LDFLAGS) $(SOBJS) libshadow.a $(LIBS)
  380. X
  381. Xsu.lint:    $(SSRCS)
  382. X    $(LINT) $(LINTFLAGS) -DSU $(SSRCS) > su.lint
  383. X
  384. Xpasswd:    $(POBJS) libshadow.a
  385. X    $(CC) -o passwd $(LDFLAGS) $(POBJS) libshadow.a $(LIBS) $(CRACKLIB)
  386. X
  387. Xpasswd.lint: $(PSRCS)
  388. X    $(LINT) $(LINTFLAGS) -DPASSWD $(PSRCS) > passwd.lint
  389. X
  390. Xgpasswd: $(GPOBJS) libshadow.a
  391. X    $(CC) -o gpasswd $(LDFLAGS) $(GPOBJS) libshadow.a $(LIBS)
  392. X
  393. Xgpasswd.lint: $(GPSRCS)
  394. X    $(LINT) $(LINTFLAGS) $(GPSRCS) > gpasswd.lint
  395. X
  396. Xdpasswd: $(DPOBJS) libshadow.a
  397. X    $(CC) -o dpasswd $(LDFLAGS) $(DPOBJS) libshadow.a $(LIBS)
  398. X
  399. Xdpasswd.lint: $(DPSRCS)
  400. X    $(LINT) $(LINTFLAGS) $(DPSRCS) > dpasswd.lint
  401. X
  402. Xpwconv:    $(PWOBJS) libshadow.a config.h
  403. X    $(CC) -o pwconv $(LDFLAGS) $(PWOBJS) libshadow.a $(LIBS)
  404. X
  405. Xpwconv.lint: $(PWSRCS) config.h
  406. X    $(LINT) $(LINTFLAGS) -DPASSWD $(PWSRCS) > pwconv.lint
  407. X
  408. Xpwunconv: $(PWUNOBJS) libshadow.a config.h
  409. X    $(CC) -o pwunconv $(LDFLAGS) $(PWUNOBJS) libshadow.a $(LIBS)
  410. X
  411. Xpwunconv.lint: $(PWUNSRCS)
  412. X    $(LINT) $(LINTFLAGS) -DPASSWD $(PWUNSRCS) > pwunconv.lint
  413. X
  414. Xsulogin: $(SULOGOBJS) libshadow.a
  415. X    $(CC) -o sulogin $(LDFLAGS) $(SULOGOBJS) libshadow.a $(LIBS)
  416. X
  417. Xsulogin.lint: $(SULOGSRCS)
  418. X    $(LINT) $(LINTFLAGS) $(SULOGSRCS) > sulogin.lint
  419. X
  420. Xfaillog: faillog.o
  421. X    $(CC) -o faillog $(LDFLAGS) faillog.o $(LIBS)
  422. X
  423. Xfaillog.lint: faillog.c faillog.h config.h
  424. X    $(LINT) $(LINTFLAGS) faillog.c > faillog.lint
  425. X
  426. Xlastlog: lastlog.o
  427. X    $(CC) -o lastlog $(LDFLAGS) lastlog.o $(LIBS)
  428. X
  429. Xlastlog.lint: lastlog.c config.h lastlog.h
  430. X    $(LINT) $(LINTFLAGS) $(MKPWDSRCS) > lastlog.lint
  431. X
  432. Xmkpasswd: $(MKPWDOBJS) libshadow.a
  433. X    $(CC) -o mkpasswd $(LDFLAGS) $(MKPWDOBJS) libshadow.a $(LIBS)
  434. X
  435. Xmkpasswd.lint: $(MKPWDSRCS)
  436. X    $(LINT) $(LINTFLAGS) $(MKPWDSRCS) > mkpasswd.lint
  437. X
  438. Xnewgrp: $(NGOBJS) libshadow.a
  439. X    $(CC) -o newgrp $(LDFLAGS) $(NGOBJS) libshadow.a $(LIBS)
  440. X
  441. Xnewgrp.lint: $(NGSRCS)
  442. X    $(LINT) $(LINTFLAGS) $(NGSRCS) > newgrp.lint
  443. X
  444. Xsg:    newgrp
  445. X    rm -f sg
  446. X    ln newgrp sg
  447. X
  448. Xchfn:    $(CHFNOBJS) libshadow.a
  449. X    $(CC) -o chfn $(LDFLAGS) $(CHFNOBJS) libshadow.a $(LIBS)
  450. X
  451. Xchfn.lint:    $(CHFNSRCS)
  452. X    $(LINT) $(LINTFLAGS) $(CHFNSRCS) > chfn.lint
  453. X
  454. Xchsh:    $(CHSHOBJS) libshadow.a
  455. X    $(CC) -o chsh $(LDFLAGS) $(CHSHOBJS) libshadow.a $(LIBS)
  456. X
  457. Xchsh.lint: $(CHSHSRCS)
  458. X    $(LINT) $(LINTFLAGS) $(CHSHSRCS) > chsh.lint
  459. X
  460. Xchage:    $(CHAGEOBJS) libshadow.a
  461. X    $(CC) -o chage $(LDFLAGS) $(CHAGEOBJS) libshadow.a $(LIBS)
  462. X
  463. Xchage.lint: $(CHAGESRCS)
  464. X    $(LINT) $(LINTFLAGS) -DPASSWD $(CHAGESRCS) > chage.lint
  465. X
  466. Xchpasswd: $(CHPASSOBJS) libshadow.a
  467. X    $(CC) -o chpasswd $(LDFLAGS) $(CHPASSOBJS) libshadow.a $(LIBS)
  468. X
  469. Xchpasswd.lint: $(CHPASSSRCS)
  470. X    $(LINT) $(LINTFLAGS) $(CHPASSSRCS) > chpasswd.lint
  471. X
  472. Xnewusers: newusers.o libshadow.a
  473. X    $(CC) -o newusers $(LDFLAGS) newusers.o libshadow.a $(LIBS)
  474. X
  475. Xnewusers.lint: newusers.c
  476. X    $(LINT) $(LINTFLAGS) newusers.c > newusers.lint
  477. X    
  478. Xid: id.o libshadow.a
  479. X    $(CC) -o id $(LDFLAGS) id.o libshadow.a $(LIBS)
  480. X
  481. Xid.lint: id.c
  482. X    $(LINT) $(LINTFLAGS) id.c > id.lint
  483. X
  484. Xgroups: groups.o libshadow.a
  485. X    $(CC) -o groups $(LDFLAGS) groups.o libshadow.a $(LIBS)
  486. X
  487. Xgroups.lint: groups.c
  488. X    $(LINT) $(LINTFLAGS) groups.c > groups.lint
  489. X
  490. Xuseradd: useradd.o copydir.o mkrmdir.o libshadow.a
  491. X    $(CC) -o useradd $(LDFLAGS) useradd.o copydir.o mkrmdir.o \
  492. X        libshadow.a $(LIBS) $(NDIR)
  493. X
  494. Xuseradd.lint: useradd.c copydir.c mkrmdir.c
  495. X    $(LINT) $(LINTFLAGS) useradd.c copydir.c mkrmdir.c > useradd.lint
  496. X
  497. Xuserdel: userdel.o copydir.o mkrmdir.o libshadow.a
  498. X    $(CC) -o userdel $(LDFLAGS) userdel.o copydir.o mkrmdir.o \
  499. X        libshadow.a $(LIBS) $(NDIR)
  500. X
  501. Xuserdel.lint: userdel.c copydir.c mkrmdir.c
  502. X    $(LINT) $(LINTFLAGS) userdel.c copydir.c mkrmdir.c > userdel.lint
  503. X
  504. Xusermod: usermod.o copydir.o mkrmdir.o chowndir.o libshadow.a
  505. X    $(CC) -o usermod $(LDFLAGS) usermod.o copydir.o mkrmdir.o \
  506. X        chowndir.o libshadow.a $(LIBS) $(NDIR)
  507. X
  508. Xusermod.lint: usermod.c copydir.c mkrmdir.c chowndir.c
  509. X    $(LINT) $(LINTFLAGS) usermod.c copydir.c mkrmdir.c \
  510. X        chowndir.c > usermod.lint
  511. X
  512. Xgroupadd: groupadd.o libshadow.a
  513. X    $(CC) -o groupadd $(LDFLAGS) groupadd.o libshadow.a $(LIBS)
  514. X
  515. Xgroupadd.lint: groupadd.c
  516. X    $(LINT) $(LINTFLAGS) groupadd.c > groupadd.lint
  517. X
  518. Xgroupdel: groupdel.o libshadow.a
  519. X    $(CC) -o groupdel $(LDFLAGS) groupdel.o libshadow.a $(LIBS)
  520. X
  521. Xgroupdel.lint: groupdel.c
  522. X    $(LINT) $(LINTFLAGS) groupdel.c > groupdel.lint
  523. X
  524. Xgroupmod: groupmod.o libshadow.a
  525. X    $(CC) -o groupmod $(LDFLAGS) groupmod.o libshadow.a $(LIBS)
  526. X
  527. Xgroupmod.lint: groupmod.c
  528. X    $(LINT) $(LINTFLAGS) groupmod.c > groupmod.lint
  529. X
  530. Xpwd.h.m4:
  531. X    [ -f s.pwd.h.m4 ] && get -t -r$(RELEASE) s.pwd.h.m4
  532. X
  533. Xpwd.h: pwd.h.m4
  534. X    /usr/5bin/m4 $(OS) < pwd.h.m4 > pwd.h
  535. X
  536. Xlogoutd: logoutd.o libshadow.a
  537. X    $(CC) -o logoutd $(LDFLAGS) logoutd.o libshadow.a
  538. X
  539. Xlogoutd.lint: logoutd.c
  540. X    $(LINT) $(LINTFLAGS) logoutd.c > logoutd.lint
  541. X
  542. Xpwck: pwck.o libshadow.a
  543. X    $(CC) -o pwck $(LDFLAGS) pwck.o libshadow.a $(LIBS)
  544. X
  545. Xpwck.lint: pwck.c
  546. X    $(LINT) $(LINTFLAGS) pwck.c > pwck.lint
  547. X
  548. Xgrpck: grpck.o libshadow.a
  549. X    $(CC) -o grpck $(LDFLAGS) grpck.o libshadow.a $(LIBS)
  550. X
  551. Xgrpck.lint: grpck.c
  552. X    $(LINT) $(LINTFLAGS) grpck.c > grpck.lint
  553. X
  554. Xsulog.o: config.h
  555. X
  556. Xsusetup.c: setup.c
  557. X    cp setup.c susetup.c
  558. X
  559. Xsusetup.o: config.h susetup.c pwd.h
  560. X    $(CC) -c $(CFLAGS) -DSU susetup.c
  561. X
  562. Xscologin: scologin.o
  563. X    $(CC) -o scologin $(LDFLAGS) scologin.o -lsocket
  564. X
  565. Xpasswd.o: config.h shadow.h pwd.h pwauth.h
  566. Xlmain.o: config.h lastlog.h faillog.h pwd.h pwauth.h
  567. Xsmain.o: config.h lastlog.h pwd.h shadow.h pwauth.h
  568. Xsub.o: pwd.h
  569. Xsetup.o: config.h pwd.h
  570. Xmkrmdir.o: config.h
  571. Xutmp.o: config.h
  572. Xmail.o: config.h
  573. Xmotd.o: config.h
  574. Xage.o: config.h pwd.h
  575. Xlog.o: config.h lastlog.h pwd.h
  576. Xshell.o: config.h
  577. Xentry.o: config.h shadow.h pwd.h
  578. Xhushed.o: config.h pwd.h
  579. Xvalid.o: config.h pwd.h
  580. Xfailure.o: faillog.h config.h
  581. Xfaillog.o: faillog.h config.h pwd.h
  582. Xnewgrp.o: config.h shadow.h pwd.h
  583. Xmkpasswd.o: config.h shadow.h pwd.h
  584. Xgpmain.o: config.h pwd.h
  585. Xchfn.o: config.h pwd.h
  586. Xchsh.o: config.h pwd.h
  587. Xchage.o: config.h shadow.h pwd.h
  588. Xpwconv.o: config.h shadow.h
  589. Xpwunconv.o: config.h shadow.h pwd.h
  590. Xchpasswd.o: config.h shadow.h pwd.h
  591. Xid.o: pwd.h
  592. Xnewusers.o: config.h shadow.h pwd.h
  593. Xdpmain.o: config.h dialup.h
  594. Xuseradd.o: config.h shadow.h pwd.h pwauth.h
  595. Xuserdel.o: config.h shadow.h pwd.h pwauth.h
  596. Xusermod.o: config.h shadow.h pwd.h pwauth.h
  597. Xgroupadd.o: config.h shadow.h
  598. Xgroupdel.o: config.h shadow.h
  599. Xgroupmod.o: config.h shadow.h
  600. Xlogoutd.o: config.h
  601. Xsulogin.o: config.h pwauth.h
  602. Xcopydir.o: config.h
  603. Xchowndir.o: config.h
  604. Xpwck.o: config.h shadow.h pwd.h
  605. Xgrpck.o: config.h shadow.h pwd.h
  606. X
  607. Xlibshadow.a(shadow.o): shadow.h config.h
  608. Xlibshadow.a(shadowio.o): shadow.h
  609. Xlibshadow.a(grent.o): config.h shadow.h
  610. Xlibshadow.a(sgroupio.o): shadow.h
  611. Xlibshadow.a(dialup.o): dialup.h
  612. Xlibshadow.a(dialchk.o): dialup.h config.h
  613. Xlibshadow.a(getdef.o): config.h
  614. Xlibshadow.a(pwdbm.o): config.h pwd.h
  615. Xlibshadow.a(spdbm.o): config.h shadow.h
  616. Xlibshadow.a(grdbm.o): config.h
  617. Xlibshadow.a(gshadow.o): config.h
  618. Xlibshadow.a(gsdbm.o): config.h shadow.h
  619. Xlibshadow.a(pwauth.o): config.h pwauth.h
  620. Xlibshadow.a(pwpack.o): config.h pwd.h
  621. Xlibshadow.a(pwent.o): config.h pwd.h
  622. Xlibshadow.a(pwio.o): pwd.h
  623. Xlibshadow.a(getpass.o): config.h
  624. Xlibshadow.a(encrypt.o): config.h
  625. Xlibshadow.a(port.o): port.h
  626. Xlibshadow.a(rad64.o): config.h
  627. Xlibshadow.a(lockpw.o):
  628. X
  629. Xclean:
  630. X    -rm -f susetup.c *.o a.out core npasswd nshadow *.pag *.dir pwd.h
  631. X
  632. Xclobber: clean
  633. X    -rm -f $(BINS) *.lint *.L libshadow.a
  634. X
  635. Xnuke:    clobber
  636. X    -for file in * ; do \
  637. X        if [ -f s.$$file -a ! -f p.$$file ] ; then \
  638. X            rm -f $$file ;\
  639. X        fi ;\
  640. X    done
  641. X
  642. Xshar:    login.sh.01 login.sh.02 login.sh.03 login.sh.04 login.sh.05 \
  643. X    login.sh.06 login.sh.07 login.sh.08 login.sh.09 login.sh.10 \
  644. X    login.sh.11 login.sh.12
  645. X
  646. Xlogin.sh.01: $(FILES1) Makefile
  647. X    shar -a $(FILES1) > login.sh.01
  648. X
  649. Xlogin.sh.02: $(FILES2) Makefile
  650. X    shar -a $(FILES2) > login.sh.02
  651. X
  652. Xlogin.sh.03: $(FILES3) Makefile
  653. X    shar -a $(FILES3) > login.sh.03
  654. X
  655. Xlogin.sh.04: $(FILES4) Makefile
  656. X    shar -a $(FILES4) > login.sh.04
  657. X
  658. Xlogin.sh.05: $(FILES5) Makefile
  659. X    shar -a $(FILES5) > login.sh.05
  660. X
  661. Xlogin.sh.06: $(FILES6) Makefile
  662. X    shar -a $(FILES6) > login.sh.06
  663. X
  664. Xlogin.sh.07: $(FILES7) Makefile
  665. X    shar -a $(FILES7) > login.sh.07
  666. X
  667. Xlogin.sh.08: $(FILES8) Makefile
  668. X    shar -a $(FILES8) > login.sh.08
  669. X
  670. Xlogin.sh.09: $(FILES9) Makefile
  671. X    shar -a $(FILES9) > login.sh.09
  672. X
  673. Xlogin.sh.10: $(DOCS1) Makefile
  674. X    shar -a $(DOCS1) > login.sh.10
  675. X
  676. Xlogin.sh.11: $(DOCS2) Makefile
  677. X    shar -a $(DOCS2) > login.sh.11
  678. X
  679. Xlogin.sh.12: $(FILES_SUN4) $(FILES_SVR4) Makefile
  680. X    shar -a $(FILES_SUN4) $(FILES_SVR4) > login.sh.12
  681. END_OF_FILE
  682.   if test 18789 -ne `wc -c <'Makefile.sun4'`; then
  683.     echo shar: \"'Makefile.sun4'\" unpacked with wrong size!
  684.   fi
  685.   # end of 'Makefile.sun4'
  686. fi
  687. if test -f 'chsh.c' -a "${1}" != "-c" ; then 
  688.   echo shar: Will not clobber existing file \"'chsh.c'\"
  689. else
  690.   echo shar: Extracting \"'chsh.c'\" \(10350 characters\)
  691.   sed "s/^X//" >'chsh.c' <<'END_OF_FILE'
  692. X/*
  693. X * Copyright 1989, 1990, 1991, 1992, 1993, John F. Haugh II
  694. X * All rights reserved.
  695. X *
  696. X * Permission is granted to copy and create derivative works for any
  697. X * non-commercial purpose, provided this copyright notice is preserved
  698. X * in all copies of source code, or included in human readable form
  699. X * and conspicuously displayed on all copies of object code or
  700. X * distribution media.
  701. X *
  702. X * This software is provided on an AS-IS basis and the author makes
  703. X * no warrantee of any kind.
  704. X */
  705. X
  706. X#include <sys/types.h>
  707. X#include <stdio.h>
  708. X#include <fcntl.h>
  709. X#include <signal.h>
  710. X
  711. X#ifndef    lint
  712. Xstatic    char    sccsid[] = "@(#)chsh.c    3.9    07:46:32    20 Apr 1993";
  713. X#endif
  714. X
  715. X/*
  716. X * Set up some BSD defines so that all the BSD ifdef's are
  717. X * kept right here 
  718. X */
  719. X
  720. X#ifndef    BSD
  721. X#include <string.h>
  722. X#include <memory.h>
  723. X#else
  724. X#include <strings.h>
  725. X#define    strchr    index
  726. X#define    strrchr    rindex
  727. X#endif
  728. X
  729. X#include "config.h"
  730. X#include "pwd.h"
  731. X
  732. X#ifdef    USE_SYSLOG
  733. X#include <syslog.h>
  734. X
  735. X#ifndef    LOG_WARN
  736. X#define    LOG_WARN LOG_WARNING
  737. X#endif
  738. X#endif
  739. X#ifdef    HAVE_RLIMIT
  740. X#include <sys/resource.h>
  741. X
  742. Xstruct    rlimit    rlimit_fsize = { RLIM_INFINITY, RLIM_INFINITY };
  743. X#endif
  744. X
  745. X/*
  746. X * Global variables.
  747. X */
  748. X
  749. Xchar    *Prog;            /* Program name */
  750. Xint    amroot;                /* Real UID is root */
  751. Xchar    loginsh[BUFSIZ];        /* Name of new login shell */
  752. X
  753. X/*
  754. X * External identifiers
  755. X */
  756. X
  757. Xextern    struct    passwd    *getpwuid ();
  758. Xextern    struct    passwd    *getpwnam ();
  759. Xextern    void    change_field ();
  760. Xextern    int    optind;
  761. Xextern    char    *optarg;
  762. Xextern    char    *getlogin ();
  763. X#ifdef    NDBM
  764. Xextern    int    pw_dbm_mode;
  765. X#endif
  766. X
  767. X/*
  768. X * #defines for messages.  This facilitates foreign language conversion
  769. X * since all messages are defined right here.
  770. X */
  771. X
  772. X#define    USAGE        "Usage: %s [ -s shell ] [ name ]\n"
  773. X#define    WHOAREYOU    "%s: Cannot determine your user name.\n"
  774. X#define    UNKUSER        "%s: Unknown user %s\n"
  775. X#define    NOPERM        "You may not change the shell for %s.\n"
  776. X#define    NOPERM2        "can't change shell for `%s'\n"
  777. X#define    NEWSHELLMSG    "Changing the login shell for %s\n"
  778. X#define    NEWSHELL    "Login Shell"
  779. X#define    NEWSHELLMSG2 \
  780. X    "Enter the new value, or press return for the default\n\n"
  781. X#define    BADSHELL    "%s is an invalid shell.\n"
  782. X#define    BADFIELD    "%s: Invalid entry: %s\n"
  783. X#define    PWDBUSY        "Cannot lock the password file; try again later.\n"
  784. X#define    PWDBUSY2    "can't lock /etc/passwd\n"
  785. X#define    OPNERROR    "Cannot open the password file.\n"
  786. X#define    OPNERROR2    "can't open /etc/passwd\n"
  787. X#define    UPDERROR    "Error updating the password entry.\n"
  788. X#define    UPDERROR2    "error updating passwd entry\n"
  789. X#define    DBMERROR    "Error updating the DBM password entry.\n"
  790. X#define    DBMERROR2    "error updating DBM passwd entry.\n"
  791. X#define    NOTROOT        "Cannot change ID to root.\n"
  792. X#define    NOTROOT2    "can't setuid(0).\n"
  793. X#define    CLSERROR    "Cannot commit password file changes.\n"
  794. X#define    CLSERROR2    "can't rewrite /etc/passwd.\n"
  795. X#define    UNLKERROR    "Cannot unlock the password file.\n"
  796. X#define    UNLKERROR2    "can't unlock /etc/passwd.\n"
  797. X#define    CHGSHELL    "changed user `%s' shell to `%s'\n"
  798. X
  799. X/*
  800. X * usage - print command line syntax and exit
  801. X */
  802. X
  803. Xvoid
  804. Xusage ()
  805. X{
  806. X    fprintf (stderr, USAGE, Prog);
  807. X    exit (1);
  808. X}
  809. X
  810. X/*
  811. X * new_fields - change the user's login shell information interactively
  812. X *
  813. X * prompt the user for the login shell and change it according to the
  814. X * response, or leave it alone if nothing was entered.
  815. X */
  816. X
  817. Xnew_fields ()
  818. X{
  819. X    printf (NEWSHELLMSG2);
  820. X    change_field (loginsh, NEWSHELL);
  821. X}
  822. X
  823. X/*
  824. X * check_shell - see if the user's login shell is listed in /etc/shells
  825. X *
  826. X * The /etc/shells file is read for valid names of login shells.  If the
  827. X * /etc/shells file does not exist the user cannot set any shell unless
  828. X * they are root.
  829. X */
  830. X
  831. Xcheck_shell (shell)
  832. Xchar    *shell;
  833. X{
  834. X    char    buf[BUFSIZ];
  835. X    char    *cp;
  836. X    int    found = 0;
  837. X    FILE    *fp;
  838. X
  839. X    if (amroot)
  840. X        return 1;
  841. X
  842. X    if ((fp = fopen ("/etc/shells", "r")) == (FILE *) 0)
  843. X        return 0;
  844. X
  845. X    while (fgets (buf, BUFSIZ, fp) && ! found) {
  846. X        if (cp = strrchr (buf, '\n'))
  847. X            *cp = '\0';
  848. X
  849. X        if (strcmp (buf, shell) == 0)
  850. X            found = 1;
  851. X    }
  852. X    fclose (fp);
  853. X
  854. X    return found;
  855. X}
  856. X
  857. X/*
  858. X * restricted_shell - return true if the named shell begins with 'r' or 'R'
  859. X *
  860. X * If the first letter of the filename is 'r' or 'R', the shell is
  861. X * considered to be restricted.
  862. X */
  863. X
  864. Xint
  865. Xrestricted_shell (shell)
  866. Xchar    *shell;
  867. X{
  868. X    char    *cp;
  869. X
  870. X    if (cp = strrchr (shell, '/'))
  871. X        cp++;
  872. X    else
  873. X        cp = shell;
  874. X
  875. X    return *cp == 'r' || *cp == 'R';
  876. X}
  877. X
  878. X/*
  879. X * chsh - this command controls changes to the user's shell
  880. X *
  881. X *    The only supported option is -s which permits the
  882. X *    the login shell to be set from the command line.
  883. X */
  884. X
  885. Xint
  886. Xmain (argc, argv)
  887. Xint    argc;
  888. Xchar    **argv;
  889. X{
  890. X    char    user[BUFSIZ];        /* User name                         */
  891. X    int    flag;            /* Current command line flag         */
  892. X    int    sflg = 0;        /* -s - set shell from command line  */
  893. X    int    i;            /* Loop control variable             */
  894. X    char    *cp;            /* Miscellaneous character pointer   */
  895. X    struct    passwd    *pw;        /* Password entry from /etc/passwd   */
  896. X    struct    passwd    pwent;        /* New password entry                */
  897. X
  898. X    /*
  899. X     * This command behaves different for root and non-root
  900. X     * users.
  901. X     */
  902. X
  903. X    amroot = getuid () == 0;
  904. X#ifdef    NDBM
  905. X    pw_dbm_mode = O_RDWR;
  906. X#endif
  907. X
  908. X    /*
  909. X     * Get the program name.  The program name is used as a
  910. X     * prefix to most error messages.  It is also used as input
  911. X     * to the openlog() function for error logging.
  912. X     */
  913. X
  914. X    if (Prog = strrchr (argv[0], '/'))
  915. X        Prog++;
  916. X    else
  917. X        Prog = argv[0];
  918. X
  919. X#ifdef    USE_SYSLOG
  920. X    openlog (Prog, LOG_PID, LOG_AUTH);
  921. X#endif
  922. X
  923. X    /*
  924. X     * There is only one option, but use getopt() anyway to
  925. X     * keep things consistent.
  926. X     */
  927. X
  928. X    while ((flag = getopt (argc, argv, "s:")) != EOF) {
  929. X        switch (flag) {
  930. X            case 's':
  931. X                sflg++;
  932. X                strcpy (loginsh, optarg);
  933. X                break;
  934. X            default:
  935. X                usage ();
  936. X        }
  937. X    }
  938. X
  939. X    /*
  940. X     * There should be only one remaining argument at most
  941. X     * and it should be the user's name.
  942. X     */
  943. X
  944. X    if (argc > optind + 1)
  945. X        usage ();
  946. X
  947. X    /*
  948. X     * Get the name of the user to check.  It is either
  949. X     * the command line name, or the name getlogin()
  950. X     * returns.
  951. X     */
  952. X
  953. X    if (optind < argc) {
  954. X        strncpy (user, argv[optind], sizeof user);
  955. X        pw = getpwnam (user);
  956. X    } else if (cp = getlogin ()) {
  957. X        strncpy (user, cp, sizeof user);
  958. X        pw = getpwnam (user);
  959. X    } else {
  960. X        fprintf (stderr, WHOAREYOU, Prog);
  961. X#ifdef    USE_SYSLOG
  962. X        closelog ();
  963. X#endif
  964. X        exit (1);
  965. X    }
  966. X
  967. X    /*
  968. X     * Make certain there was a password entry for the
  969. X     * user.
  970. X     */
  971. X
  972. X    if (! pw) {
  973. X        fprintf (stderr, UNKUSER, Prog, user);
  974. X#ifdef    USE_SYSLOG
  975. X        closelog ();
  976. X#endif
  977. X        exit (1);
  978. X    }
  979. X
  980. X    /*
  981. X     * Non-privileged users are only allowed to change the
  982. X     * shell if the UID of the user matches the current
  983. X     * real UID.
  984. X     */
  985. X
  986. X    if (! amroot && pw->pw_uid != getuid ()) {
  987. X        fprintf (stderr, NOPERM, user);
  988. X#ifdef    USE_SYSLOG
  989. X        syslog (LOG_WARN, NOPERM2, user);
  990. X        closelog ();
  991. X#endif
  992. X        exit (1);
  993. X    }
  994. X
  995. X    /*
  996. X     * Non-privileged users are only allowed to change the
  997. X     * shell if it is not a restricted one.
  998. X     */
  999. X
  1000. X    if (! amroot && restricted_shell (pw->pw_shell)) {
  1001. X        fprintf (stderr, NOPERM, user);
  1002. X#ifdef    USE_SYSLOG
  1003. X        syslog (LOG_WARN, NOPERM2, user);
  1004. X        closelog ();
  1005. X#endif
  1006. X        exit (1);
  1007. X    }
  1008. X
  1009. X    /*
  1010. X     * Make a copy of the user's password file entry so it
  1011. X     * can be modified without worrying about it be modified
  1012. X     * elsewhere.
  1013. X     */
  1014. X
  1015. X    pwent = *pw;
  1016. X    pwent.pw_name = strdup (pw->pw_name);
  1017. X    pwent.pw_passwd = strdup (pw->pw_passwd);
  1018. X#ifdef    ATT_AGE
  1019. X    pwent.pw_age = strdup (pw->pw_age);
  1020. X#endif
  1021. X#ifdef    ATT_COMMENT
  1022. X    pwent.pw_comment = strdup (pw->pw_comment);
  1023. X#endif
  1024. X    pwent.pw_dir = strdup (pw->pw_dir);
  1025. X    pwent.pw_gecos = strdup (pw->pw_gecos);
  1026. X
  1027. X    /*
  1028. X     * Now get the login shell.  Either get it from the password
  1029. X     * file, or use the value from the command line.
  1030. X     */
  1031. X
  1032. X    if (! sflg)
  1033. X        strcpy (loginsh, pw->pw_shell);
  1034. X
  1035. X    /*
  1036. X     * If the login shell was not set on the command line,
  1037. X     * let the user interactively change it.
  1038. X     */
  1039. X
  1040. X    if (! sflg) {
  1041. X        printf (NEWSHELLMSG, user);
  1042. X        new_fields ();
  1043. X    }
  1044. X
  1045. X    /*
  1046. X     * Check all of the fields for valid information.  The shell
  1047. X     * field may not contain any illegal characters.  Non-privileged
  1048. X     * users are restricted to using the shells in /etc/shells.
  1049. X     */
  1050. X
  1051. X    if (valid_field (loginsh, ":,=")) {
  1052. X        fprintf (stderr, BADFIELD, Prog, loginsh);
  1053. X#ifdef    USE_SYSLOG
  1054. X        closelog ();
  1055. X#endif
  1056. X        exit (1);
  1057. X    }
  1058. X    if (! check_shell (loginsh)) {
  1059. X        fprintf (stderr, BADSHELL, loginsh);
  1060. X#ifdef    USE_SYSLOG
  1061. X        closelog ();
  1062. X#endif
  1063. X        exit (1);
  1064. X    }
  1065. X    pwent.pw_shell = loginsh;
  1066. X    pw = &pwent;
  1067. X
  1068. X    /*
  1069. X     * Before going any further, raise the ulimit to prevent
  1070. X     * colliding into a lowered ulimit, and set the real UID
  1071. X     * to root to protect against unexpected signals.  Any
  1072. X     * keyboard signals are set to be ignored.
  1073. X     */
  1074. X
  1075. X#ifdef    HAVE_ULIMIT
  1076. X    ulimit (2, 30000);
  1077. X#endif
  1078. X#ifdef    HAVE_RLIMIT
  1079. X    setrlimit (RLIMIT_FSIZE, &rlimit_fsize);
  1080. X#endif
  1081. X    if (setuid (0)) {
  1082. X        fprintf (stderr, NOTROOT);
  1083. X#ifdef    USE_SYSLOG
  1084. X        syslog (LOG_ERR, NOTROOT2);
  1085. X        closelog ();
  1086. X#endif
  1087. X        exit (1);
  1088. X    }
  1089. X    signal (SIGHUP, SIG_IGN);
  1090. X    signal (SIGINT, SIG_IGN);
  1091. X    signal (SIGQUIT, SIG_IGN);
  1092. X#ifdef    SIGTSTP
  1093. X    signal (SIGTSTP, SIG_IGN);
  1094. X#endif
  1095. X
  1096. X    /*
  1097. X     * The passwd entry is now ready to be committed back to
  1098. X     * the password file.  Get a lock on the file and open it.
  1099. X     */
  1100. X
  1101. X    for (i = 0;i < 30;i++)
  1102. X        if (pw_lock ())
  1103. X            break;
  1104. X
  1105. X    if (i == 30) {
  1106. X        fprintf (stderr, PWDBUSY);
  1107. X#ifdef    USE_SYSLOG
  1108. X        syslog (LOG_WARN, PWDBUSY2);
  1109. X        closelog ();
  1110. X#endif
  1111. X        exit (1);
  1112. X    }
  1113. X    if (! pw_open (O_RDWR)) {
  1114. X        fprintf (stderr, OPNERROR);
  1115. X        (void) pw_unlock ();
  1116. X#ifdef    USE_SYSLOG
  1117. X        syslog (LOG_ERR, OPNERROR2);
  1118. X        closelog ();
  1119. X#endif
  1120. X        exit (1);
  1121. X    }
  1122. X
  1123. X    /*
  1124. X     * Update the passwd file entry.  If there is a DBM file,
  1125. X     * update that entry as well.
  1126. X     */
  1127. X
  1128. X    if (! pw_update (pw)) {
  1129. X        fprintf (stderr, UPDERROR);
  1130. X        (void) pw_unlock ();
  1131. X#ifdef    USE_SYSLOG
  1132. X        syslog (LOG_ERR, UPDERROR2);
  1133. X        closelog ();
  1134. X#endif
  1135. X        exit (1);
  1136. X    }
  1137. X#if defined(DBM) || defined(NDBM)
  1138. X    if (access ("/etc/passwd.pag", 0) == 0 && ! pw_dbm_update (pw)) {
  1139. X        fprintf (stderr, DBMERROR);
  1140. X        (void) pw_unlock ();
  1141. X#ifdef    USE_SYSLOG
  1142. X        syslog (LOG_ERR, DBMERROR2);
  1143. X        closelog ();
  1144. X#endif
  1145. X        exit (1);
  1146. X    }
  1147. X    endpwent ();
  1148. X#endif
  1149. X
  1150. X    /*
  1151. X     * Changes have all been made, so commit them and unlock the
  1152. X     * file.
  1153. X     */
  1154. X
  1155. X    if (! pw_close ()) {
  1156. X        fprintf (stderr, CLSERROR);
  1157. X        (void) pw_unlock ();
  1158. X#ifdef    USE_SYSLOG
  1159. X        syslog (LOG_ERR, CLSERROR2);
  1160. X        closelog ();
  1161. X#endif
  1162. X        exit (1);
  1163. X    }
  1164. X    if (! pw_unlock ()) {
  1165. X        fprintf (stderr, UNLKERROR);
  1166. X#ifdef    USE_SYSLOG
  1167. X        syslog (LOG_ERR, UNLKERROR2);
  1168. X        closelog ();
  1169. X#endif
  1170. X        exit (1);
  1171. X    }
  1172. X#ifdef    USE_SYSLOG
  1173. X    syslog (LOG_INFO, CHGSHELL, user, pwent.pw_shell);
  1174. X    closelog ();
  1175. X#endif
  1176. X    exit (0);
  1177. X}
  1178. END_OF_FILE
  1179.   if test 10350 -ne `wc -c <'chsh.c'`; then
  1180.     echo shar: \"'chsh.c'\" unpacked with wrong size!
  1181.   fi
  1182.   # end of 'chsh.c'
  1183. fi
  1184. if test -f 'login.5' -a "${1}" != "-c" ; then 
  1185.   echo shar: Will not clobber existing file \"'login.5'\"
  1186. else
  1187.   echo shar: Extracting \"'login.5'\" \(14568 characters\)
  1188.   sed "s/^X//" >'login.5' <<'END_OF_FILE'
  1189. X.\" Copyright 1991, 1992, 1993, John F. Haugh II and Chip Rosenthal
  1190. X.\" All rights reserved.
  1191. X.\"
  1192. X.\" Permission is granted to copy and create derivative works for any
  1193. X.\" non-commercial purpose, provided this copyright notice is preserved
  1194. X.\" in all copies of source code, or included in human readable form
  1195. X.\" and conspicuously displayed on all copies of object code or
  1196. X.\" distribution media.
  1197. X.\"
  1198. X.\" This software is provided on an AS-IS basis and the author makes
  1199. X.\" no warrantee of any kind.
  1200. X.\"
  1201. X.\"    @(#)login.5    3.6    09:30:17    30 Apr 1993
  1202. X.\"
  1203. X.TH LOGIN 5
  1204. X.SH NAME
  1205. X/etc/login.defs \- Login configuration
  1206. X.SH DESCRIPTION
  1207. XThe
  1208. X.I /etc/login.defs
  1209. Xfile defines the site-specific configuration for the shadow login
  1210. Xsuite.  This file is required.  Absence of this file will not prevent
  1211. Xsystem operation, but will probably result in undesirable operation.
  1212. X.PP
  1213. XThis file is a readable text file, each line of the file describing
  1214. Xone configuration parameter.  The lines consist of a configuration
  1215. Xname and value, seperated by whitespace.  Blank lines and comment
  1216. Xlines are ignored.  Comments are introduced with a `#' pound sign and
  1217. Xthe pound sign must be the first non-white character of the line.
  1218. X.PP
  1219. XParameter values may be of four types:  strings, booleans, numbers,
  1220. Xand long numbers.  A string is comprised of any printable characters.
  1221. XA boolean should be either the value ``yes'' or ``no''.  An undefined
  1222. Xboolean parameter or one with a value other than these will be given
  1223. Xa ``no'' value.  Numbers (both regular and long) may be either decimal
  1224. Xvalues, octal values (precede the value with ``0'') or hexadecimal
  1225. Xvalues (precede the value with ``0x'').  The maximum value of the
  1226. Xregular and long numeric parameters is machine-dependant.
  1227. X.PP
  1228. XThe following configuration items are provided:
  1229. X.\"
  1230. X.IP "CONSOLE (string)"
  1231. XIf specified, this definition provides for a restricted set of lines
  1232. Xon which root logins will be allowed.  An attempted root login which
  1233. Xdoes not meet the criteria established here will be rejected.  The
  1234. Xvalue of this field may be one of two forms, either a fully-rooted
  1235. Xpathname such as
  1236. X.sp
  1237. X.ft CW
  1238. X    CONSOLE /etc/consoles
  1239. X.ft P
  1240. X.sp
  1241. Xor a colon-delimited list of terminal lines such as:
  1242. X.sp
  1243. X.ft CW
  1244. X    CONSOLE console:tty01:tty02:tty03:tty04
  1245. X.ft P
  1246. X.sp
  1247. XIf a pathname is given, each line of the file should specify one
  1248. Xterminal line.  If this parameter is not defined or the specified file
  1249. Xdoes not exist, then root logins will be allowed from any terminal
  1250. Xline.  Because the removal of this file, or its truncation, could
  1251. Xresult in unauthorized root logins, this file must be protected.
  1252. XWhere security is critical, the colon-separated form should be used
  1253. Xto prevent this potential method of attack.
  1254. X.\"
  1255. X.IP "DIALUPS_CHECK_ENAB (boolean)"
  1256. XIf
  1257. X.I yes
  1258. Xand an
  1259. X.I /etc/dialups
  1260. Xfile exists, then secondary passwords are enabled upon the dialup
  1261. Xlines specified in this file.  This file should contain a list of
  1262. Xdialups, one per line, for example:
  1263. X.nf
  1264. X.sp
  1265. X.ft CW
  1266. X    ttyfm01
  1267. X    ttyfm02
  1268. X    \0\0.
  1269. X    \0\0.
  1270. X    \0\0.
  1271. X.ft P
  1272. X.sp
  1273. X.fi
  1274. X.\"
  1275. X.IP "ENV_HZ (string)"
  1276. XThis parameter specifies a value for an HZ environment parameter.
  1277. XExample usage is:
  1278. X.sp
  1279. X    \f(CWENV_HZ     HZ=50\fP
  1280. X.sp
  1281. XIf this parameter is not defined then no HZ value will be established.
  1282. X.\"
  1283. X.IP "ENV_PATH (string)"
  1284. XThis parameter must be defined as the search path for regular users.
  1285. XWhen a login with UID other than zero occurs, the PATH environment
  1286. Xparameter is initialized to this value.  This parameter is required;
  1287. Xif undefined a possibly incorrect default value will be provided.
  1288. X.\"
  1289. X.IP "ENV_SUPATH (string)"
  1290. XThis parameter must be defined as the search path for the superuser.
  1291. XWhen a login with UID zero occurs, the PATH environment parameter is
  1292. Xinitialized to this value.  This parameter is required; if undefined
  1293. Xa possibly incorrect default value will be provided.
  1294. X.\"
  1295. X.IP "ENV_TZ (string)"
  1296. XThis parameter specifies information for generating a TZ environment
  1297. Xparameter.  The value must either be the desired contents of TZ, or
  1298. Xthe full pathname of a file which contains this information.  Example
  1299. Xusage is:
  1300. X.sp
  1301. X    \f(CWENV_TZ\0\0\0\0TZ=CST6CDT\fP
  1302. X.sp
  1303. Xor
  1304. X.sp
  1305. X    \f(CWENV_TZ\0\0\0\0/etc/tzname\fP
  1306. X.sp
  1307. XIf a nonexistent file is named, then TZ will be initialized to some
  1308. Xdefault value.  If this parameter is not defined then no TZ value will
  1309. Xbe established.
  1310. X.\"
  1311. X.IP "ERASECHAR (number)"
  1312. XThe terminal
  1313. X.I erase
  1314. Xcharacter is initialized to this value.  This is supported only on
  1315. Xsystems with the
  1316. X.I termio
  1317. Xinterface, e.g. System V.  If not specified, the erase character will
  1318. Xbe initialized to a backspace.  See KILLCHAR for related information.
  1319. X.\"
  1320. X.IP "FAILLOG_ENAB (boolean)"
  1321. XIf
  1322. X.I yes
  1323. Xthen login failures will be accumulated in
  1324. X.I /usr/adm/faillog
  1325. Xin a
  1326. X.I faillog(8)
  1327. Xformat.
  1328. X.\"
  1329. X.IP "FTMP_FILE (string)"
  1330. XThis parameter specifies the full pathname to a file to which login
  1331. Xfailures are recorded.  When a login failure occurs, a
  1332. X.I utmp
  1333. Xformat record will be appended to this file.  Note that this differs
  1334. Xfrom the
  1335. X.I /usr/adm/faillog
  1336. Xfailure logging in that this facility logs every failure whereas the
  1337. X``faillog'' facility accumulates failure information per user.  If
  1338. Xthis parameter is not specified then logging will be inhibited.  See
  1339. XFAILLOG_ENAB and LOG_UNKFAIL_ENAB for related information.
  1340. X.\"
  1341. X.IP "HUSHLOGIN_FILE (string)"
  1342. XThis parameter is used to establish ``hushlogin'' conditions.  There
  1343. Xare two possible ways to establish these conditions.  First, if the
  1344. Xvalue of this parameter is a filename and that file exists in the
  1345. Xuser's home directory then ``hushlogin'' conditions will be in effect.
  1346. XThe contents of this file are ignored; its mere presence triggers
  1347. X``hushlogin'' conditions.  Second, if the value of this parameter is
  1348. Xa full pathname and either the user's login name or the user's shell
  1349. Xis found in this file, then ``hushlogin'' conditions will be in effect.
  1350. XIn this case, the file should be in a format similar to:
  1351. X.nf
  1352. X.sp
  1353. X.ft CW
  1354. X    demo
  1355. X    /usr/lib/uucp/uucico
  1356. X    \0\0.
  1357. X    \0\0.
  1358. X    \0\0.
  1359. X.ft P
  1360. X.sp
  1361. X.fi
  1362. XIf this parameter is not defined, then ``hushlogin'' conditions will
  1363. Xnever occur.  When ``hushlogin'' conditions are established, the
  1364. Xmessage of the day, last successful and unsuccessful login display,
  1365. Xmail status display, and password aging checks are suppressed.  Note
  1366. Xthat allowing hushlogin files in user home directories allows the user
  1367. Xto disable password aging checks.  See MOTD_FILE, FAILLOG_ENAB,
  1368. XLASTLOG_ENAB, and MAIL_CHECK_ENAB for related information.
  1369. X.\"
  1370. X.IP "KILLCHAR (number)"
  1371. XThe terminal
  1372. X.I kill
  1373. Xcharacter is initialized to this value.  This is supported only on
  1374. Xsystems with the
  1375. X.I termio
  1376. Xinterface, e.g. System V.  If not specified, the kill character will
  1377. Xbe initialized to a \s-2CTRL/U\s0.
  1378. XSee ERASECHAR for related information.
  1379. X.\"
  1380. X.IP "LASTLOG_ENAB (boolean)"
  1381. XIf
  1382. X.IR yes ,
  1383. Xand if the
  1384. X.I /usr/adm/lastlog
  1385. Xfile exists, then a successful user login will be recorded to this
  1386. Xfile.  Furthermore, if this option is enabled then the times of the
  1387. Xmost recent successful and unsuccessful logins will be displayed to
  1388. Xthe user upon login.  The unsuccessful login display will be suppressed
  1389. Xif FAILLOG_ENAB is not enabled.  If ``hushlogin'' conditions are in
  1390. Xeffect, then both the successful and unsuccessful login information
  1391. Xwill be suppressed.
  1392. X.\"
  1393. X.IP "LOG_UNKFAIL_ENAB (boolean)"
  1394. XIf
  1395. X.I yes
  1396. Xthen unknown usernames will be included when a login failure is
  1397. Xrecorded.  Note that this is a potential security risk; a common login
  1398. Xfailure mode is transposition of the user name and password, thus this
  1399. Xmode will often cause passwords to accumulate in the failure logs.
  1400. XIf this option is disabled then unknown usernames will be suppressed
  1401. Xin login failure messages.
  1402. X.\"
  1403. X.IP "MAIL_CHECK_ENAB (boolean)"
  1404. XIf
  1405. X.IR yes ,
  1406. Xthe user will be notified of his or her mailbox status upon login.
  1407. XSee MAIL_DIR for related information.
  1408. X.\"
  1409. X.IP "MAIL_DIR (string)"
  1410. XThis parameter specifies the full pathname to the directory which
  1411. Xcontains the user mailbox files.  The user's login name is appended
  1412. Xto this path to form the MAIL environment parameter \- the path to
  1413. Xthe user's mailbox.  This parameter must be defined; if undefined some
  1414. Xpossibly incorrect default value will be assumed.  See MAIL_CHECK_ENAB
  1415. Xfor related information.
  1416. X.\"
  1417. X.IP "MOTD_FILE (string)"
  1418. XThis parameter specifies a colon-delimited list of pathnames to ``message
  1419. Xof the day'' files.
  1420. XIf a specified file exists, then its contents are displayed to the user
  1421. Xupon login.
  1422. XIf this parameter is not defined or ``hushlogin'' login conditions are
  1423. Xin effect, this information will be suppressed.
  1424. X.\"
  1425. X.IP "NOLOGINS_FILE (string)"
  1426. XThis parameter specifies the full pathname to a file which inhibits
  1427. Xnon-root logins.  If this file exists and a user other than root
  1428. Xattempts to log in, the contents of the file will be displayed and
  1429. Xthe user will be disconnected.  If this parameter is not specified
  1430. Xthen this feature will be inhibited.
  1431. X.\"
  1432. X.IP "OBSCURE_CHECKS_ENAB (boolean)"
  1433. XIf
  1434. X.IR yes ,
  1435. Xthe
  1436. X.I passwd
  1437. Xprogram will perform additional checks before accepting a password change.
  1438. XThe checks performed are fairly simple, and their use is recommended.
  1439. XThese obscurity checks are bypassed if
  1440. X.I passwd
  1441. Xis run by
  1442. X.IR root .
  1443. XSee PASS_MIN_LEN for related information.
  1444. X.\"
  1445. X.IP "PASS_MIN_DAYS (number)"
  1446. XThe minimum number of days allowed between password changes.  Any password
  1447. Xchanges attempted sooner than this will be rejected.  If not specified, a
  1448. Xzero value will be assumed.
  1449. X.\"
  1450. X.IP "PASS_MIN_LEN (number)"
  1451. XThe minimum number of characters in an acceptable password.  An attempt to
  1452. Xassign a password with fewer characters will be rejected.  A zero value
  1453. Xsuppresses this check.  If not specified, a zero value will be assumed.
  1454. X.\"
  1455. X.IP "PASS_MAX_DAYS (number)"
  1456. XThe maximum number of days a password may be used.  If the password is
  1457. Xolder than this, then the account will be locked.  If not specified,
  1458. Xa large value will be assumed.
  1459. X.\"
  1460. X.IP "PASS_WARN_AGE (number)"
  1461. XThe number of days warning given before a password expires.  A zero means
  1462. Xwarning is given only upon the day of expiration, a negative value means
  1463. Xno warning is given.  If not specified, no warning will be provided.
  1464. X.IP "PORTTIME_CHECKS_ENAB (boolean)"
  1465. XIf
  1466. X.I yes
  1467. Xand an
  1468. X.I /etc/porttime
  1469. Xfile exists, that file will be consulted to ensure the user may login
  1470. Xat this time on the given line.
  1471. Xc.f. porttime(4)
  1472. X.\"
  1473. X.IP "QUOTAS_ENAB (boolean)"
  1474. XIf
  1475. X.I yes ,
  1476. Xthen the user's ``ulimit,'' ``umask,'' and ``niceness'' will be
  1477. Xinitialized to the values if specified in the
  1478. X.I gecos
  1479. Xfield of the
  1480. X.I passwd
  1481. Xfile.
  1482. Xc.f. passwd(4).
  1483. X.\"
  1484. X.IP "SU_NAME (string)"
  1485. XThis parameter assigns a command name when ``su -'' is run.  For
  1486. Xexample, if the parameter is defined as ``su'', then a
  1487. X.I ps(1)
  1488. Xlisting would show the command running as ``-su''.  If this parameter
  1489. Xis undefined, then a
  1490. X.I ps(1)
  1491. Xlisting would show the name of the actual shell being run, e.g.
  1492. Xsomething like ``-sh''.
  1493. X.\"
  1494. X.IP "SULOG_FILE (string)"
  1495. XThis parameter specifies a full pathname of a file in which
  1496. X.I su
  1497. Xactivity is logged.
  1498. XIf this parameter is not specified, the logging is suppressed.
  1499. XBecause the
  1500. X.I su
  1501. Xcommand may be used when attempting to authenticate a password,
  1502. Xeither this option, or
  1503. X.I syslog
  1504. Xshould be used to note
  1505. X.I su
  1506. Xactivity.  See the SYSLOG_SU_ENAB option for related information.
  1507. X.\"
  1508. X.IP "SYSLOG_SU_ENAB (boolean)"
  1509. XIf
  1510. X.I yes
  1511. Xand
  1512. X.I login
  1513. Xwas compiled with
  1514. X.I syslog
  1515. Xsupport, then all
  1516. X.I su
  1517. Xactivity will be noted through the
  1518. X.I syslog
  1519. Xfacility.
  1520. XSee SULOG_FILE for related information.
  1521. X.\"
  1522. X.IP "TTYGROUP (string or number)"
  1523. XThe group ownership of the terminal is initialized to this group
  1524. Xname or number.  One well-known security attack involves forcing terminal
  1525. Xcontrol sequences upon another user's terminal line.  This problem
  1526. Xcan be averted by disabling permissions which allow other users to
  1527. Xaccess the terminal line, but this unfortunately prevents programs
  1528. Xsuch as
  1529. X.I write
  1530. Xfrom operating.  Another solution is to use a version of the
  1531. X.I write
  1532. Xprogram which filters out potentially dangerous character sequences,
  1533. Xmake this program ``setgid'' to a special group, assign group ownership
  1534. Xof the terminal line to this special group, and assign permissions of
  1535. X\f(CW0620\fP to the terminal line.  The TTYGROUP definition has been
  1536. Xprovided for just this situation.  If this item is not defined, then
  1537. Xthe group ownership of the terminal is initialized to the user's group
  1538. Xnumber.  See TTYPERMS for related information.
  1539. X.\"
  1540. X.IP "TTYPERM (number)"
  1541. XThe login terminal permissions are initialized to this value.  Typical
  1542. Xvalues will be \f(CW0622\fP to permit others write access to the line
  1543. Xor \f(CW0600\fP to secure the line from other users.  If not specified,
  1544. Xthe terminal permissions will be initialized to \f(CW0622\fP.  See
  1545. XTTYGROUP for related information.
  1546. X.\"
  1547. X.IP "TTYTYPE_FILE (string)"
  1548. XThis parameter specifies the full pathname to a file which maps terminal
  1549. Xlines to terminal types.  Each line of the file contains a terminal
  1550. Xtype and a terminal line, seperated by whitespace, for example:
  1551. X.nf
  1552. X.sp
  1553. X.ft CW
  1554. X    vt100\0    tty01
  1555. X    wyse60    tty02
  1556. X    \0\0.\0\0\0    \0\0.
  1557. X    \0\0.\0\0\0    \0\0.
  1558. X    \0\0.\0\0\0    \0\0.
  1559. X.ft P
  1560. X.sp
  1561. X.fi
  1562. XThis information is used to initialize the TERM environment parameter.
  1563. XA line starting with a ``#'' pound sign will be treated as a comment.
  1564. XIf this paramter is not specified, the file does not exist, or the terminal
  1565. Xline is not found in the file, then the TERM environment parameter will not
  1566. Xbe set.
  1567. X.\"
  1568. X.IP "ULIMIT (long number)"
  1569. XThe file size limit is initialized to this value.  This is supported
  1570. Xonly on systems with a
  1571. X.IR ulimit ,
  1572. Xe.g. System V.  If not specified, the file size limit will be initialized
  1573. Xto some large value.
  1574. X.\"
  1575. X.IP "UMASK (number)"
  1576. XThe permission mask is initialized to this value.  If not specified,
  1577. Xthe permission mask will be initialized to zero.
  1578. X.\"
  1579. X.SH CROSS REFERENCE
  1580. XThe following cross reference shows which programs in the shadow login
  1581. Xsuite use which parameters.
  1582. X.na
  1583. X.IP login 12
  1584. XCONSOLE DIALUPS_CHECK_ENAB ENV_HZ ENV_SUPATH ENV_TZ ERASECHAR FAILLOG_ENAB
  1585. XFTMP_FILE HUSHLOGIN_FILE KILLCHAR LASTLOG_ENAB LOG_UNKFAIL_ENAB
  1586. XMAIL_CHECK_ENAB MAIL_DIR MOTD_FILE NOLOGINS_FILE PORTTIME_CHECKS_ENAB
  1587. XQUOTAS_ENAB TTYPERM TTYTYPE_FILE ULIMIT UMASK
  1588. X.IP newusers 12
  1589. XPASS_MAX_DAYS PASS_MIN_DAYS PASS_WARN_AGE UMASK
  1590. X.IP passwd 12
  1591. XOBSCURE_CHECKS_ENAB PASS_MIN_LEN
  1592. X.IP pwconv 12
  1593. XPASS_MAX_DAYS PASS_MIN_DAYS PASS_WARN_AGE
  1594. X.IP su 12
  1595. XENV_HZ ENV_SUPATH ENV_TZ HUSHLOGIN_FILE MAIL_CHECK_ENAB MAIL_DIR
  1596. XMOTD_FILE NOLOGIN_STR QUOTAS_ENAB SULOG_FILE SYSLOG_SU_ENAB
  1597. X.IP sulogin 12
  1598. XENV_HZ ENV_SUPATH ENV_TZ MAIL_DIR QUOTAS_ENAB TTYPERM
  1599. X.ad
  1600. X.SH SEE ALSO
  1601. Xlogin(1), passwd(4), faillog(4), porttime(4), faillog(8)
  1602. END_OF_FILE
  1603.   if test 14568 -ne `wc -c <'login.5'`; then
  1604.     echo shar: \"'login.5'\" unpacked with wrong size!
  1605.   fi
  1606.   # end of 'login.5'
  1607. fi
  1608. if test -f 'newusers.c' -a "${1}" != "-c" ; then 
  1609.   echo shar: Will not clobber existing file \"'newusers.c'\"
  1610. else
  1611.   echo shar: Extracting \"'newusers.c'\" \(13274 characters\)
  1612.   sed "s/^X//" >'newusers.c' <<'END_OF_FILE'
  1613. X/*
  1614. X * Copyright 1990, 1991, 1992, 1993, John F. Haugh II
  1615. X * All rights reserved.
  1616. X *
  1617. X * Permission is granted to copy and create derivative works for any
  1618. X * non-commercial purpose, provided this copyright notice is preserved
  1619. X * in all copies of source code, or included in human readable form
  1620. X * and conspicuously displayed on all copies of object code or
  1621. X * distribution media.
  1622. X *
  1623. X * This software is provided on an AS-IS basis and the author makes
  1624. X * no warrantee of any kind.
  1625. X *
  1626. X *    newusers - create users from a batch file
  1627. X *
  1628. X *    newusers creates a collection of entries in /etc/passwd
  1629. X *    and related files by reading a passwd-format file and
  1630. X *    adding entries in the related directories.
  1631. X */
  1632. X
  1633. X#include "config.h"
  1634. X#include <stdio.h>
  1635. X#include "pwd.h"
  1636. X#include <grp.h>
  1637. X#include <fcntl.h>
  1638. X#include <string.h>
  1639. X#ifdef    SHADOWPWD
  1640. X#include "shadow.h"
  1641. X#endif
  1642. X
  1643. X#ifndef    lint
  1644. Xstatic    char    sccsid[] = "@(#)newusers.c    3.9    09:19:18    04 Jun 1993";
  1645. X#endif
  1646. X
  1647. Xchar    *Prog;
  1648. X
  1649. Xextern    char    *pw_encrypt();
  1650. Xextern    char    *malloc();
  1651. X
  1652. Xint    pw_lock(), gr_lock();
  1653. Xint    pw_open(), gr_open();
  1654. Xstruct    passwd    *pw_locate(), *pw_next();
  1655. Xstruct    group    *gr_locate(), *gr_next();
  1656. Xint    pw_update(), gr_update();
  1657. Xint    pw_close(), gr_close();
  1658. Xint    pw_unlock(), gr_unlock();
  1659. Xextern    int    getdef_num();
  1660. X
  1661. X#ifdef    SHADOWPWD
  1662. Xint    spw_lock(), spw_open(), spw_update(), spw_close(), spw_unlock();
  1663. Xstruct    spwd    *spw_locate(), *spw_next();
  1664. X#endif
  1665. X
  1666. X#ifndef    MKDIR
  1667. X
  1668. X/*
  1669. X * mkdir - for those of us with no mkdir() system call.
  1670. X */
  1671. X
  1672. Xmkdir (dir, mode)
  1673. Xchar    *dir;
  1674. Xint    mode;
  1675. X{
  1676. X    int    mask;
  1677. X    int    status;
  1678. X    int    pid;
  1679. X    int    i;
  1680. X
  1681. X    mode = (~mode & 0777);
  1682. X    mask = umask (mode);
  1683. X    if ((pid = fork ()) == 0) {
  1684. X        execl ("/bin/mkdir", "mkdir", dir, (char *) 0);
  1685. X        perror ("/bin/mkdir");
  1686. X        _exit (1);
  1687. X    } else {
  1688. X        while ((i = wait (&status)) != pid && i != -1)
  1689. X            ;
  1690. X    }
  1691. X    umask (mask);
  1692. X    return status;
  1693. X}
  1694. X#endif
  1695. X
  1696. X/*
  1697. X * usage - display usage message and exit
  1698. X */
  1699. X
  1700. Xusage ()
  1701. X{
  1702. X    fprintf (stderr, "Usage: %s [ input ]\n", Prog);
  1703. X    exit (1);
  1704. X}
  1705. X
  1706. X/*
  1707. X * add_group - create a new group or add a user to an existing group
  1708. X */
  1709. X
  1710. Xint
  1711. Xadd_group (name, gid, ngid)
  1712. Xchar    *name;
  1713. Xchar    *gid;
  1714. XGID_T    *ngid;
  1715. X{
  1716. X    struct    passwd    *pwd;
  1717. X    struct    group    *grp;
  1718. X    struct    group    grent;
  1719. X    char    *members[2];
  1720. X    int    i;
  1721. X
  1722. X    /*
  1723. X     * Start by seeing if the named group already exists.  This
  1724. X     * will be very easy to deal with if it does.
  1725. X     */
  1726. X
  1727. X    if (grp = gr_locate (gid)) {
  1728. Xadd_member:
  1729. X        grent = *grp;
  1730. X        *ngid = grent.gr_gid;
  1731. X        for (i = 0;grent.gr_mem[i] != (char *) 0;i++)
  1732. X            if (strcmp (grent.gr_mem[i], name) == 0)
  1733. X                return 0;
  1734. X
  1735. X        if (! (grent.gr_mem = (char **)
  1736. X                malloc (sizeof (char *) * (i + 2)))) {
  1737. X            fprintf (stderr, "%s: Out of Memory\n", Prog);
  1738. X            return -1;
  1739. X        }
  1740. X        memcpy (grent.gr_mem, grp->gr_mem, sizeof (char *) * (i + 2));
  1741. X        grent.gr_mem[i] = strdup (name);
  1742. X        grent.gr_mem[i + 1] = (char *) 0;
  1743. X
  1744. X        return ! gr_update (&grent);
  1745. X    }
  1746. X
  1747. X    /*
  1748. X     * The group did not exist, so I try to figure out what the
  1749. X     * GID is going to be.  The gid parameter is probably "", meaning
  1750. X     * I figure out the GID from the password file.  I want the UID
  1751. X     * and GID to match, unless the GID is already used.
  1752. X     */
  1753. X
  1754. X    if (gid[0] == '\0') {
  1755. X        i = 100;
  1756. X        for (pw_rewind ();pwd = pw_next ();) {
  1757. X            if (pwd->pw_uid >= i)
  1758. X                i = pwd->pw_uid + 1;
  1759. X        }
  1760. X        for (gr_rewind ();grp = gr_next ();) {
  1761. X            if (grp->gr_gid == i) {
  1762. X                i = -1;
  1763. X                break;
  1764. X            }
  1765. X        }
  1766. X    } else if (gid[0] >= '0' && gid[0] <= '9') {
  1767. X
  1768. X    /*
  1769. X     * The GID is a number, which means either this is a brand new
  1770. X     * group, or an existing group.  For existing groups I just add
  1771. X     * myself as a member, just like I did earlier.
  1772. X     */
  1773. X
  1774. X        i = atoi (gid);
  1775. X        for (gr_rewind ();grp = gr_next ();)
  1776. X            if (grp->gr_gid == i)
  1777. X                goto add_member;
  1778. X    } else
  1779. X
  1780. X    /*
  1781. X     * The last alternative is that the GID is a name which is not
  1782. X     * already the name of an existing group, and I need to figure
  1783. X     * out what group ID that group name is going to have.
  1784. X     */
  1785. X
  1786. X        i = -1;
  1787. X
  1788. X    /*
  1789. X     * If I don't have a group ID by now, I'll go get the
  1790. X     * next one.
  1791. X     */
  1792. X
  1793. X    if (i == -1) {
  1794. X        for (i = 100, gr_rewind ();grp = gr_next ();)
  1795. X            if (grp->gr_gid >= i)
  1796. X                i = grp->gr_gid + 1;
  1797. X    }
  1798. X
  1799. X    /*
  1800. X     * Now I have all of the fields required to create the new
  1801. X     * group.
  1802. X     */
  1803. X
  1804. X    if (gid[0] && (gid[0] <= '0' || gid[0] >= '9'))
  1805. X        grent.gr_name = gid;
  1806. X    else
  1807. X        grent.gr_name = name;
  1808. X
  1809. X    grent.gr_passwd = "!";
  1810. X    grent.gr_gid = i;
  1811. X    members[0] = name;
  1812. X    members[1] = (char *) 0;
  1813. X    grent.gr_mem = members;
  1814. X
  1815. X    *ngid = grent.gr_gid;
  1816. X    return ! gr_update (&grent);
  1817. X}
  1818. X
  1819. X/*
  1820. X * add_user - create a new user ID
  1821. X */
  1822. X
  1823. Xadd_user (name, uid, nuid, gid)
  1824. Xchar    *name;
  1825. Xchar    *uid;
  1826. XUID_T    *nuid;
  1827. XGID_T    gid;
  1828. X{
  1829. X    struct    passwd    *pwd;
  1830. X    struct    passwd    pwent;
  1831. X    UID_T    i;
  1832. X
  1833. X    /*
  1834. X     * The first guess for the UID is either the numerical UID
  1835. X     * that the caller provided, or the next available UID.
  1836. X     */
  1837. X
  1838. X    if (uid[0] >= '0' && uid[0] <= '9') {
  1839. X        i = atoi (uid);
  1840. X    } else if (uid[0] && (pwd = pw_locate (uid))) {
  1841. X        i = pwd->pw_uid;
  1842. X    } else {
  1843. X        i = 100;
  1844. X        for (pw_rewind ();pwd = pw_next ();)
  1845. X            if (pwd->pw_uid >= i)
  1846. X                i = pwd->pw_uid + 1;
  1847. X    }
  1848. X
  1849. X    /*
  1850. X     * I don't want to fill in the entire password structure
  1851. X     * members JUST YET, since there is still more data to be
  1852. X     * added.  So, I fill in the parts that I have.
  1853. X     */
  1854. X
  1855. X    pwent.pw_name = name;
  1856. X    pwent.pw_passwd = "!";
  1857. X#ifdef    ATT_AGE
  1858. X    pwent.pw_age = "";
  1859. X#endif
  1860. X#ifdef    ATT_COMMENT
  1861. X    pwent.pw_comment = "";
  1862. X#endif
  1863. X#ifdef    BSD_QUOTAS
  1864. X    pwent.pw_quota = 0;
  1865. X#endif
  1866. X    pwent.pw_uid = i;
  1867. X    pwent.pw_gid = gid;
  1868. X    pwent.pw_gecos = "";
  1869. X    pwent.pw_dir = "";
  1870. X    pwent.pw_shell = "";
  1871. X
  1872. X    *nuid = i;
  1873. X    return ! pw_update (&pwent);
  1874. X}
  1875. X
  1876. X/*
  1877. X * add_passwd - add or update the encrypted password
  1878. X */
  1879. X
  1880. Xadd_passwd (pwd, passwd)
  1881. Xstruct    passwd    *pwd;
  1882. Xchar    *passwd;
  1883. X{
  1884. X#ifdef    SHADOWPWD
  1885. X    struct    spwd    *sp;
  1886. X    struct    spwd    spent;
  1887. X#endif
  1888. X    static    char    newage[5];
  1889. X    extern    char    *l64a();
  1890. X
  1891. X    /*
  1892. X     * In the case of regular password files, this is real
  1893. X     * easy - pwd points to the entry in the password file.
  1894. X     * Shadow files are harder since there are zillions of
  1895. X     * things to do ...
  1896. X     */
  1897. X
  1898. X#ifndef    SHADOWPWD
  1899. X    pwd->pw_passwd = pw_encrypt (passwd, (char *) 0);
  1900. X#ifdef    ATT_AGE
  1901. X    if (strlen (pwd->pw_age) == 4) {
  1902. X        strcpy (newage, pwd->pw_age);
  1903. X        strcpy (newage + 2,
  1904. X            l64a (time ((long *) 0) / (7L*24L*3600L)));
  1905. X        pwd->pw_age = newage;
  1906. X    }
  1907. X#endif    /* ATT_AGE */
  1908. X    return 0;
  1909. X#else
  1910. X
  1911. X    /*
  1912. X     * Do the first and easiest shadow file case.  The user
  1913. X     * already exists in the shadow password file.
  1914. X     */
  1915. X
  1916. X    if (sp = spw_locate (pwd->pw_name)) {
  1917. X        spent = *sp;
  1918. X        spent.sp_pwdp = pw_encrypt (passwd, (char *) 0);
  1919. X        return ! spw_update (&spent);
  1920. X    }
  1921. X
  1922. X    /*
  1923. X     * Pick the next easiest case - the user has an encrypted
  1924. X     * password which isn't equal to "!".  The password was set
  1925. X     * to "!" earlier when the entry was created, so this user
  1926. X     * would have to have had the password set someplace else.
  1927. X     */
  1928. X
  1929. X    if (strcmp (pwd->pw_passwd, "!") != 0) {
  1930. X        pwd->pw_passwd = pw_encrypt (passwd, (char *) 0);
  1931. X#ifdef    ATT_AGE
  1932. X        if (strlen (pwd->pw_age) == 4) {
  1933. X            strcpy (newage, pwd->pw_age);
  1934. X            strcpy (newage + 2,
  1935. X                l64a (time ((long *) 0) / (7L*24L*3600L)));
  1936. X            pwd->pw_age = newage;
  1937. X        }
  1938. X#endif    /* ATT_AGE */
  1939. X        return 0;
  1940. X    }
  1941. X
  1942. X    /*
  1943. X     * Now the really hard case - I need to create an entirely
  1944. X     * shadow password file entry.
  1945. X     */
  1946. X
  1947. X    spent.sp_namp = pwd->pw_name;
  1948. X    spent.sp_pwdp = pw_encrypt (passwd, (char *) 0);
  1949. X    spent.sp_lstchg = time ((long *) 0) / (24L*3600L);
  1950. X    spent.sp_min = getdef_num("PASS_MIN_DAYS", 0);
  1951. X                    /* 10000 is infinity this week */
  1952. X    spent.sp_max = getdef_num("PASS_MAX_DAYS", 10000);
  1953. X    spent.sp_warn = getdef_num("PASS_WARN_AGE", -1);
  1954. X    spent.sp_inact = -1;
  1955. X    spent.sp_expire = -1;
  1956. X    spent.sp_flag = -1;
  1957. X
  1958. X    return ! spw_update (&spent);
  1959. X#endif
  1960. X}
  1961. X
  1962. Xmain (argc, argv)
  1963. Xint    argc;
  1964. Xchar    **argv;
  1965. X{
  1966. X    char    buf[BUFSIZ];
  1967. X    char    *fields[8];
  1968. X    int    nfields;
  1969. X    char    *cp;
  1970. X#ifdef    SHADOWPWD
  1971. X    struct    spwd    *spw_locate();
  1972. X#endif
  1973. X    struct    passwd    *pw;
  1974. X    struct    passwd    newpw;
  1975. X    struct    passwd    *pw_locate();
  1976. X    int    errors = 0;
  1977. X    int    line = 0;
  1978. X    UID_T    uid;
  1979. X    GID_T    gid;
  1980. X    int    i;
  1981. X
  1982. X    if (Prog = strrchr (argv[0], '/'))
  1983. X        Prog++;
  1984. X    else
  1985. X        Prog = argv[0];
  1986. X
  1987. X    if (argc > 1 && argv[1][0] == '-')
  1988. X        usage ();
  1989. X
  1990. X    if (argc == 2) {
  1991. X        if (! freopen (argv[1], "r", stdin)) {
  1992. X            sprintf (buf, "%s: %s", Prog, argv[1]);
  1993. X            perror (buf);
  1994. X            exit (1);
  1995. X        }
  1996. X    }
  1997. X
  1998. X    /*
  1999. X     * Lock the password files and open them for update.  This will
  2000. X     * bring all of the entries into memory where they may be
  2001. X     * searched for an modified, or new entries added.  The password
  2002. X     * file is the key - if it gets locked, assume the others can
  2003. X     * be locked right away.
  2004. X     */
  2005. X
  2006. X    for (i = 0;i < 30;i++) {
  2007. X        if (pw_lock ())
  2008. X            break;
  2009. X    }
  2010. X    if (i == 30) {
  2011. X        fprintf (stderr, "%s: can't lock /etc/passwd.\n", Prog);
  2012. X        exit (1);
  2013. X    }
  2014. X#ifdef    SHADOWPWD
  2015. X    if (! spw_lock () || ! gr_lock ())
  2016. X#else
  2017. X    if (! gr_lock ())
  2018. X#endif
  2019. X    {
  2020. X        fprintf (stderr, "%s: can't lock files, try again later\n",
  2021. X            Prog);
  2022. X        (void) pw_unlock ();
  2023. X#ifdef    SHADOWPWD
  2024. X        (void) spw_unlock ();
  2025. X#endif
  2026. X        exit (1);
  2027. X    }
  2028. X#ifdef    SHADOWPWD
  2029. X    if (! pw_open (O_RDWR) || ! spw_open (O_RDWR) || ! gr_open (O_RDWR))
  2030. X#else
  2031. X    if (! pw_open (O_RDWR) || ! gr_open (O_RDWR))
  2032. X#endif
  2033. X    {
  2034. X        fprintf (stderr, "%s: can't open files\n", Prog);
  2035. X        (void) pw_unlock ();
  2036. X#ifdef    SHADOWPWD
  2037. X        (void) spw_unlock ();
  2038. X#endif
  2039. X        (void) gr_unlock ();
  2040. X        exit (1);
  2041. X    }
  2042. X
  2043. X    /*
  2044. X     * Read each line.  The line has the same format as a password
  2045. X     * file entry, except that certain fields are not contrained to
  2046. X     * be numerical values.  If a group ID is entered which does
  2047. X     * not already exist, an attempt is made to allocate the same
  2048. X     * group ID as the numerical user ID.  Should that fail, the
  2049. X     * next available group ID over 100 is allocated.  The pw_gid
  2050. X     * field will be updated with that value.
  2051. X     */
  2052. X
  2053. X    while (fgets (buf, sizeof buf, stdin) != (char *) 0) {
  2054. X        line++;
  2055. X        if (cp = strrchr (buf, '\n')) {
  2056. X            *cp = '\0';
  2057. X        } else {
  2058. X            fprintf (stderr, "%s: line %d: line too long\n",
  2059. X                Prog, line);
  2060. X            errors++;
  2061. X            continue;
  2062. X        }
  2063. X
  2064. X        /*
  2065. X         * Break the string into fields and screw around with
  2066. X         * them.  There MUST be 7 colon separated fields,
  2067. X         * although the values aren't that particular.
  2068. X         */
  2069. X
  2070. X        for (cp = buf, nfields = 0;nfields < 7;nfields++) {
  2071. X            fields[nfields] = cp;
  2072. X            if (cp = strchr (cp, ':'))
  2073. X                *cp++ = '\0';
  2074. X            else
  2075. X                break;
  2076. X        }
  2077. X        if (nfields != 6) {
  2078. X            fprintf (stderr, "%s: line %d: invalid line\n",
  2079. X                Prog, line);
  2080. X            continue;
  2081. X        }
  2082. X
  2083. X        /*
  2084. X         * Now the fields are processed one by one.  The first
  2085. X         * field to be processed is the group name.  A new
  2086. X         * group will be created if the group name is non-numeric
  2087. X         * and does not already exist.  The named user will be
  2088. X         * the only member.  If there is no named group to be a
  2089. X         * member of, the UID will be figured out and that value
  2090. X         * will be a candidate for a new group, if that group ID
  2091. X         * exists, a whole new group ID will be made up.
  2092. X         */
  2093. X        
  2094. X        if (! (pw = pw_locate (fields[0])) &&
  2095. X            add_group (fields[0], fields[3], &gid)) {
  2096. X            fprintf (stderr, "%s: %d: can't create GID\n",
  2097. X                Prog, line);
  2098. X            errors++;
  2099. X            continue;
  2100. X        }
  2101. X
  2102. X        /*
  2103. X         * Now we work on the user ID.  It has to be specified
  2104. X         * either as a numerical value, or left blank.  If it
  2105. X         * is a numerical value, that value will be used, otherwise
  2106. X         * the next available user ID is computed and used.  After
  2107. X         * this there will at least be a (struct passwd) for the
  2108. X         * user.
  2109. X         */
  2110. X
  2111. X        if (! pw && add_user (fields[0], fields[2], &uid, gid)) {
  2112. X            fprintf (stderr, "%s: line %d: can't create UID\n",
  2113. X                Prog, line);
  2114. X            errors++;
  2115. X            continue;
  2116. X        }
  2117. X
  2118. X        /*
  2119. X         * The password, gecos field, directory, and shell fields
  2120. X         * all come next.
  2121. X         */
  2122. X
  2123. X        if (! (pw = pw_locate (fields[0]))) {
  2124. X            fprintf (stderr, "%s: line %d: cannot find user %s\n",
  2125. X                Prog, line, fields[0]);
  2126. X            errors++;
  2127. X            continue;
  2128. X        }
  2129. X        newpw = *pw;
  2130. X
  2131. X        if (add_passwd (&newpw, fields[1])) {
  2132. X            fprintf (stderr, "%s: line %d: can't update password\n",
  2133. X                Prog, line);
  2134. X            errors++;
  2135. X            continue;
  2136. X        }
  2137. X        if (fields[4][0])
  2138. X            newpw.pw_gecos = fields[4];
  2139. X
  2140. X        if (fields[5][0])
  2141. X            newpw.pw_dir = fields[5];
  2142. X
  2143. X        if (fields[6][0])
  2144. X            newpw.pw_shell = fields[6];
  2145. X
  2146. X        if (newpw.pw_dir[0] && access (newpw.pw_dir, 0)) {
  2147. X            if (mkdir (newpw.pw_dir,
  2148. X                    0777 & ~getdef_num("UMASK", 0)))
  2149. X                fprintf (stderr, "%s: line %d: mkdir failed\n",
  2150. X                    Prog, line);
  2151. X            else if (chown (newpw.pw_dir,
  2152. X                    newpw.pw_uid, newpw.pw_gid))
  2153. X                fprintf (stderr, "%s: line %d: chown failed\n",
  2154. X                    Prog, line);
  2155. X        }
  2156. X
  2157. X        /*
  2158. X         * Update the password entry with the new changes made.
  2159. X         */
  2160. X
  2161. X        if (! pw_update (&newpw)) {
  2162. X            fprintf (stderr, "%s: line %d: can't update entry\n",
  2163. X                Prog, line);
  2164. X            errors++;
  2165. X            continue;
  2166. X        }
  2167. X    }
  2168. X
  2169. X    /*
  2170. X     * Any detected errors will cause the entire set of changes
  2171. X     * to be aborted.  Unlocking the password file will cause
  2172. X     * all of the changes to be ignored.  Otherwise the file is
  2173. X     * closed, causing the changes to be written out all at
  2174. X     * once, and then unlocked afterwards.
  2175. X     */
  2176. X
  2177. X    if (errors) {
  2178. X        fprintf (stderr, "%s: error detected, changes ignored\n", Prog);
  2179. X        (void) gr_unlock ();
  2180. X#ifdef    SHADOWPWD
  2181. X        (void) spw_unlock ();
  2182. X#endif
  2183. X        (void) pw_unlock ();
  2184. X        exit (1);
  2185. X    }
  2186. X#ifdef    SHADOWPWD
  2187. X    if (! pw_close () || ! spw_close () || ! gr_close ())
  2188. X#else
  2189. X    if (! pw_close () || ! gr_close ())
  2190. X#endif
  2191. X    {
  2192. X        fprintf (stderr, "%s: error updating files\n", Prog);
  2193. X        (void) gr_unlock ();
  2194. X#ifdef    SHADOWPWD
  2195. X        (void) spw_unlock ();
  2196. X#endif
  2197. X        (void) pw_unlock ();
  2198. X        exit (1);
  2199. X    }
  2200. X    (void) gr_unlock ();
  2201. X#ifdef    SHADOWPWD
  2202. X    (void) spw_unlock ();
  2203. X#endif
  2204. X    (void) pw_unlock ();
  2205. X
  2206. X    exit (0);
  2207. X    /*NOTREACHED*/
  2208. X}
  2209. END_OF_FILE
  2210.   if test 13274 -ne `wc -c <'newusers.c'`; then
  2211.     echo shar: \"'newusers.c'\" unpacked with wrong size!
  2212.   fi
  2213.   # end of 'newusers.c'
  2214. fi
  2215. echo shar: End of archive 5 \(of 14\).
  2216. cp /dev/null ark5isdone
  2217. MISSING=""
  2218. for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 ; do
  2219.     if test ! -f ark${I}isdone ; then
  2220.     MISSING="${MISSING} ${I}"
  2221.     fi
  2222. done
  2223. if test "${MISSING}" = "" ; then
  2224.     echo You have unpacked all 14 archives.
  2225.     rm -f ark[1-9]isdone ark[1-9][0-9]isdone
  2226. else
  2227.     echo You still must unpack the following archives:
  2228.     echo "        " ${MISSING}
  2229. fi
  2230. exit 0
  2231. exit 0 # Just in case...
  2232.