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

  1. Newsgroups: comp.sources.misc
  2. From: jfh@rpp386.cactus.org (John F. Haugh II)
  3. Subject: v38i123:  shadow - Shadow Password Suite, v3.3, Part04/14
  4. Message-ID: <1993Aug14.192400.9275@sparky.sterling.com>
  5. X-Md4-Signature: ff921a960dee618d06ddddbacb15f8ea
  6. Sender: kent@sparky.sterling.com (Kent Landfield)
  7. Organization: Sterling Software
  8. Date: Sat, 14 Aug 1993 19:24:00 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 123
  13. Archive-name: shadow/part04
  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.svr4 gpmain.c lmain.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 4 (of 14)."'
  26. if test -f 'Makefile.svr4' -a "${1}" != "-c" ; then 
  27.   echo shar: Will not clobber existing file \"'Makefile.svr4'\"
  28. else
  29.   echo shar: Extracting \"'Makefile.svr4'\" \(18940 characters\)
  30.   sed "s/^X//" >'Makefile.svr4' <<'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.svr4    3.11    08:11:05  - Shadow password system (SVR4)
  45. X#
  46. X#    @(#)Makefile.svr4    3.11    08:11:05    19 Jul 1993
  47. X#
  48. XSHELL = /sbin/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# Define the directory login is copied to.  SVr4 uses /usr/bin.
  59. XLOGINDIR = /usr/bin
  60. XSBIN=/usr/sbin
  61. X# system (admin) commands
  62. XUBIN=/usr/bin
  63. X# user commands
  64. X
  65. X# SVr4 doesn't need extra libraries
  66. XNDIR =
  67. X
  68. X# Define some stuff for Cracklib.  This assumes that libcracklib.a is
  69. X# in a system directory.
  70. X# CRACKDEF='-DCRACKLIB_DICTPATH="$(DICTPATH)"'
  71. X# CRACKLIB=-lcrack
  72. X
  73. X# Pick your favorite C compiler and tags command
  74. XCC = cc
  75. XTAGS = ctags
  76. X
  77. X# OS.  This is SVr4
  78. XOS = -DUSG -DSVR4
  79. X
  80. X# SVr4 doesn't use ranlib
  81. XRANLIB = echo
  82. X
  83. X# Configuration Flags
  84. X#
  85. X#    DEST_INCLUDE_DIR - local include files
  86. X#    LIBS - system libraries
  87. X#        -lsocket - needed for TCP/IP and possibly SYSLOG
  88. X#        -ldbm or -lndbm - needed for DBM support
  89. X#        -lcrypt - needed for SCO crypt() functions
  90. X#        -lucb if -ldbm is defined
  91. X#        -lsocket and -lnsl if RLOGIN is defined
  92. X#    CFLAGS - C compiler flags
  93. X#        -DLAI_TCP - needed for SCO Xenix Lachman TCP/IP
  94. X
  95. XDEST_INCLUDE_DIR = /usr/include
  96. X
  97. X# Flags for SVr4
  98. XCFLAGS = -O -g $(OS) -I$(DEST_INCLUDE_DIR) $(CRACKDEF)
  99. XLIBS =
  100. XLDFLAGS = -g
  101. X
  102. X# Library is libsec.a
  103. XLIBSEC = libsec.a
  104. X
  105. X# Names for root user and group, and bin user and group.
  106. XRUID = root
  107. XRGID = root
  108. XBUID = bin
  109. XBGID = bin
  110. X
  111. X# Where the login.defs file will be copied.  Must agree with config.h
  112. XDEST_LOGIN_DEFS = /etc/login.defs
  113. X
  114. X# Rules for .L (lint) files.
  115. X.SUFFIXES: .L
  116. XLINT = lint
  117. XLINTFLAGS = $(OS) -Dlint
  118. X
  119. X.c.L:
  120. X    $(LINT) -pxu $(LINTFLAGS) $*.c > $*.L
  121. X
  122. XLOBJS = lmain.o login.o env.o valid.o setup.o shell.o age.o \
  123. X    utmp.o sub.o mail.o motd.o log.o ttytype.o failure.o \
  124. X    tz.o console.o hushed.o
  125. X
  126. XLSRCS = lmain.c login.c env.c valid.c setup.c shell.c age.c \
  127. X    utmp.c sub.c mail.c motd.c log.c ttytype.c failure.c \
  128. X    tz.c console.c hushed.c
  129. X
  130. XSOBJS = smain.o env.o entry.o susetup.o shell.o \
  131. X    sub.o mail.o motd.o sulog.o age.o tz.o hushed.o
  132. X
  133. XSSRCS = smain.c env.c entry.c setup.c shell.c \
  134. X    pwent.c sub.c mail.c motd.c sulog.c shadow.c age.c pwpack.c rad64.c \
  135. X    tz.c hushed.c
  136. X
  137. XPOBJS = passwd.o obscure.o
  138. XPSRCS = passwd.c obscure.c
  139. X
  140. XGPSRCS = gpmain.c
  141. X
  142. XGPOBJS = gpmain.o
  143. X
  144. XPWOBJS = pwconv.o
  145. X
  146. XPWSRCS = pwconv.c pwent.c shadow.c pwpack.c rad64.c
  147. X
  148. XPWUNOBJS = pwunconv.o
  149. X
  150. XPWUNSRCS = pwunconv.c pwent.c shadow.c pwpack.c rad64.c
  151. X
  152. XSULOGOBJS = sulogin.o entry.o env.o age.o setup.o \
  153. X    valid.o shell.o tz.o
  154. X
  155. XSULOGSRCS = sulogin.c entry.c env.c age.c pwent.c setup.c \
  156. X    shadow.c shell.c valid.c pwpack.c tz.c
  157. X
  158. XMKPWDOBJS = mkpasswd.o
  159. X
  160. XMKPWDSRCS = mkpasswd.c
  161. X
  162. XNGSRCS = newgrp.c env.c shell.c
  163. X
  164. XNGOBJS = newgrp.o env.o shell.o
  165. X
  166. XCHFNSRCS = chfn.c fields.c
  167. XCHFNOBJS = chfn.o fields.o
  168. XCHSHSRCS = chsh.c fields.c
  169. XCHSHOBJS = chsh.o fields.o
  170. XCHAGEOBJS = chage.o fields.o
  171. XCHAGESRCS = chage.c fields.c
  172. XCHPASSOBJS = chpasswd.o
  173. XCHPASSSRCS = chpasswd.c
  174. XDPSRCS = dpmain.c
  175. XDPOBJS = dpmain.o
  176. X
  177. XALLSRCS = age.c dialchk.c dialup.c entry.c env.c lmain.c log.c login.c mail.c \
  178. X    motd.c obscure.c passwd.c pwconv.c pwent.c pwunconv.c getpass.c \
  179. X    setup.c shadow.c shell.c smain.c sub.c sulog.c sulogin.c ttytype.c \
  180. X    utmp.c valid.c port.c newgrp.c gpmain.c grent.c mkpasswd.c pwpack.c \
  181. X    chfn.c chsh.c chage.c rad64.c encrypt.c chpasswd.c shadowio.c pwio.c \
  182. X    newusers.c groupio.c fields.c pwdbm.c grpack.c grdbm.c sppack.c \
  183. X    spdbm.c dpmain.c gshadow.c gsdbm.c gspack.c sgroupio.c useradd.c \
  184. X    userdel.c patchlevel.h usermod.c copydir.c mkrmdir.c groupadd.c \
  185. X    groupdel.c groupmod.c tz.c console.c hushed.c getdef.c \
  186. X    logoutd.c groups.c pwauth.c lockpw.c chowndir.c
  187. X
  188. XFILES1 = README patchlevel.h newgrp.c Makefile config.h pwunconv.c obscure.c \
  189. X    age.c id.c
  190. X
  191. XFILES2 = passwd.c port.c lmain.c sulogin.c pwpack.c dialup.c
  192. X
  193. XFILES3 = chfn.c chsh.c smain.c faillog.c pwconv.c shadow.c pwck.c
  194. X
  195. XFILES4 = gpmain.c chage.c pwent.c valid.c setup.c entry.c ttytype.c port.h
  196. X
  197. XFILES5 = pwio.c encrypt.c chpasswd.c newusers.c rad64.c dialchk.c faillog.h \
  198. X    pwdbm.c grdbm.c gshadow.c sppack.c grpck.c
  199. X
  200. XFILES6 = gspack.c spdbm.c lastlog.h shell.c login.c sub.c dpmain.c mail.c \
  201. X    env.c pwd.h.m4 grpack.c shadow.h log.c grent.c motd.c dialup.h \
  202. X    fields.c gsdbm.c utmp.c failure.c
  203. X
  204. XFILES7 = groupio.c shadowio.c sgroupio.c groups.c copydir.c mkrmdir.c \
  205. X    mkpasswd.c pwauth.c pwauth.h lastlog.c
  206. X
  207. XFILES8 = useradd.c usermod.c login.defs
  208. X
  209. XFILES9 = groupadd.c groupdel.c groupmod.c tz.c console.c hushed.c getdef.c \
  210. X    scologin.c logoutd.c sulog.c getpass.c userdel.c lockpw.c chowndir.c
  211. X
  212. XFILES_SUN4 = Makefile.sun4 README.sun4 config.h.sun4
  213. XFILES_SVR4 = Makefile.svr4 config.h.svr4
  214. X
  215. XMAN_1 = chage.1 chfn.1 chsh.1 id.1 login.1 newgrp.1 passwd.1 su.1 \
  216. X    useradd.1 userdel.1 usermod.1 groupadd.1 groupdel.1 groupmod.1 \
  217. X    groups.1 pwck.1 grpck.1
  218. XMAN_3 = shadow.3 pwauth.3
  219. XMAN_4 = faillog.4 passwd.4 porttime.4 shadow.4
  220. XMAN_5 = login.5
  221. XMAN_8 = chpasswd.8 dpasswd.8 faillog.8 newusers.8 pwconv.8 pwunconv.8 \
  222. X    sulogin.8 mkpasswd.8 logoutd.8 pwauth.8 lastlog.8
  223. X
  224. XDOCS1 = $(MAN_1) $(MAN_3) $(MAN_4)
  225. XDOCS2 = $(MAN_5) $(MAN_8)
  226. XDOCS = $(DOCS1) $(DOCS2)
  227. X
  228. XBINS = su login pwconv pwunconv passwd sulogin faillog newgrp sg gpasswd \
  229. X    mkpasswd chfn chsh chage chpasswd newusers dpasswd id useradd \
  230. X    userdel usermod groupadd groupdel groupmod $(SCOLOGIN) logoutd \
  231. X    groups pwck grpck lastlog
  232. X
  233. Xall:    $(BINS) $(DOCS)
  234. X
  235. X.PRECIOUS: libshadow.a
  236. X
  237. Xlibshadow.a: \
  238. X    libshadow.a(dialchk.o) \
  239. X    libshadow.a(dialup.o) \
  240. X    libshadow.a(encrypt.o) \
  241. X    libshadow.a(getdef.o) \
  242. X    libshadow.a(getpass.o) \
  243. X    libshadow.a(grdbm.o) \
  244. X    libshadow.a(grent.o) \
  245. X    libshadow.a(groupio.o) \
  246. X    libshadow.a(grpack.o) \
  247. X    libshadow.a(gshadow.o) \
  248. X    libshadow.a(gsdbm.o) \
  249. X    libshadow.a(gspack.o) \
  250. X    libshadow.a(sgroupio.o) \
  251. X    libshadow.a(port.o) \
  252. X    libshadow.a(pwdbm.o) \
  253. X    libshadow.a(pwent.o) \
  254. X    libshadow.a(pwio.o) \
  255. X    libshadow.a(pwpack.o) \
  256. X    libshadow.a(pwauth.o) \
  257. X    libshadow.a(rad64.o) \
  258. X    libshadow.a(spdbm.o) \
  259. X    libshadow.a(shadow.o) \
  260. X    libshadow.a(shadowio.o) \
  261. X    libshadow.a(sppack.o) \
  262. X    libshadow.a(lockpw.o)
  263. X    $(RANLIB) libshadow.a
  264. X
  265. Xlibsec: $(LIBSEC)(shadow.o)
  266. X    $(RANLIB) $(LIBSEC)
  267. X
  268. Xsave:
  269. X    [ ! -d save ] && mkdir save
  270. X    -cp $(LOGINDIR)/login save
  271. X    -cp $(SBIN)/mkpasswd $(SBIN)/pwconv $(SBIN)/pwunconv $(SBIN)/sulogin \
  272. X        $(SBIN)/chpasswd $(SBIN)/newusers $(SBIN)/useradd \
  273. X        $(SBIN)/userdel $(SBIN)/usermod $(SBIN)/groupadd \
  274. X        $(SBIN)/groupdel $(SBIN)/groupmod $(SBIN)/logoutd \
  275. X        $(SBIN)/login.defs $(SBIN)/pwck $(SBIN)/grpck save
  276. X    -cp $(UBIN)/su $(UBIN)/passwd $(UBIN)/gpasswd $(UBIN)/dpasswd \
  277. X        $(UBIN)/faillog $(UBIN)/newgrp $(UBIN)/chfn \
  278. X        $(UBIN)/chsh $(UBIN)/chage $(UBIN)/id save
  279. X    -cp $(DEST_INCLUDE_DIR)/dialup.h $(DEST_INCLUDE_DIR)/shadow.h \
  280. X        $(DEST_INCLUDE_DIR)/pwd.h save
  281. X
  282. Xrestore:
  283. X    [ -d save ]
  284. X    -(cd save ; cp login $(LOGINDIR) )
  285. X    -(cd save ; -cp mkpasswd pwconv pwunconv sulogin chpasswd \
  286. X        newusers useradd userdel usermod groupadd groupdel groupmod \
  287. X        logoutd login.defs pwck grpck $(SBIN) )
  288. X    -(cd save ; cp su passwd gpasswd dpasswd faillog newgrp chfn chsh \
  289. X        chage id $(UBIN) )
  290. X    -(cd save ; cp dialup.h shadow.h pwd.h $(DEST_INCLUDE_DIR) )
  291. X
  292. Xinstall: all
  293. X    strip $(BINS)
  294. X    mcs -da '@(#)shadow 3.2.3' $(BINS)
  295. X    cp login $(LOGINDIR)/login
  296. X    cp mkpasswd pwconv pwunconv sulogin chpasswd newusers \
  297. X        useradd userdel usermod groupadd groupdel groupmod logoutd \
  298. X        pwck grpck lastlog $(SBIN)
  299. X    cp su passwd gpasswd dpasswd faillog newgrp chfn chsh chage id $(UBIN)
  300. X    cp dialup.h shadow.h pwd.h /usr/include
  301. X    chown $(RUID) $(LOGINDIR)/login $(SBIN)/pwconv $(SBIN)/pwunconv \
  302. X        $(SBIN)/sulogin $(UBIN)/su $(UBIN)/passwd $(UBIN)/gpasswd \
  303. X        $(UBIN)/newgrp $(SBIN)/mkpasswd $(UBIN)/dpasswd $(UBIN)/chsh \
  304. X        $(UBIN)/chfn $(UBIN)/chage $(SBIN)/useradd $(SBIN)/userdel \
  305. X        $(SBIN)/usermod $(SBIN)/groupadd $(SBIN)/groupdel \
  306. X        $(SBIN)/groupmod $(SBIN)/logoutd $(SBIN)/pwck $(SBIN)/grpck
  307. X    chgrp $(RGID) $(LOGINDIR)/login $(SBIN)/pwconv $(SBIN)/pwunconv \
  308. X        $(SBIN)/sulogin $(UBIN)/su $(UBIN)/passwd $(UBIN)/gpasswd \
  309. X        $(UBIN)/newgrp $(SBIN)/mkpasswd $(UBIN)/dpasswd $(UBIN)/chsh \
  310. X        $(UBIN)/chfn $(UBIN)/chage $(SBIN)/useradd $(SBIN)/userdel \
  311. X        $(SBIN)/usermod $(SBIN)/groupadd $(SBIN)/groupdel \
  312. X        $(SBIN)/groupmod $(SBIN)/logoutd $(SBIN)/pwck $(SBIN)/grpck
  313. X    chown $(BUID) $(UBIN)/faillog $(UBIN)/id /usr/include/shadow.h \
  314. X        /usr/include/dialup.h /usr/include/pwd.h
  315. X    chgrp $(BGID) $(UBIN)/faillog $(UBIN)/id /usr/include/shadow.h \
  316. X        /usr/include/dialup.h /usr/include/pwd.h
  317. X    chmod 700 $(SBIN)/pwconv $(SBIN)/pwunconv $(SBIN)/sulogin \
  318. X        $(SBIN)/mkpasswd $(SBIN)/chpasswd $(SBIN)/newusers \
  319. X        $(UBIN)/dpasswd $(UBIN)/chage $(SBIN)/useradd $(SBIN)/userdel \
  320. X        $(SBIN)/usermod $(SBIN)/groupadd $(SBIN)/groupdel \
  321. X        $(SBIN)/groupmod $(SBIN)/logoutd $(SBIN)/pwck $(SBIN)/grpck
  322. X    chmod 4711 $(LOGINDIR)/login $(UBIN)/su $(UBIN)/passwd $(UBIN)/gpasswd \
  323. X        $(UBIN)/newgrp $(UBIN)/chfn $(UBIN)/chsh
  324. X    chmod 711 $(UBIN)/faillog $(UBIN)/id
  325. X    chmod 444 /usr/include/shadow.h /usr/include/dialup.h \
  326. X        /usr/include/pwd.h
  327. X    rm -f $(UBIN)/sg
  328. X    ln $(UBIN)/newgrp $(UBIN)/sg
  329. X    [ -f /etc/login.defs ] || (cp login.defs /etc ; \
  330. X        chown $(RUID) /etc/login.defs ; \
  331. X        chgrp $(RGID) /etc/login.defs ; \
  332. X        chmod 600 /etc/login.defs )
  333. X
  334. Xlint:    su.lint login.lint pwconv.lint pwunconv.lint passwd.lint sulogin.lint \
  335. X    faillog.lint newgrp.lint gpasswd.lint mkpasswd.lint chfn.lint \
  336. X    chsh.lint chage.lint dpasswd.lint id.lint useradd.lint userdel.lint \
  337. X    usermod.lint groupadd.lint groupdel.lint groupmod.lint logoutd.lint \
  338. X    pwck.lint grpck.lint \
  339. X    $(ALLSRCS:.c=.L)
  340. X
  341. Xtags:    $(ALLSRCS)
  342. X    $(TAGS) $(ALLSRCS)
  343. X
  344. XREADME:
  345. X    [ -f s.README ] && get -t -r$(RELEASE) s.README
  346. X    
  347. X$(DOCS):
  348. X    [ -f s.$@ ] && get -t -r$(RELEASE) s.$@
  349. X
  350. Xlogin.defs:
  351. X    [ -f s.login.defs ] && get -t -r$(RELEASE) s.login.defs
  352. X
  353. XMakefile.sun4:
  354. X    [ -f s.Makefile.sun4 ] && get -t -r$(RELEASE) s.Makefile.sun4
  355. X
  356. XMakefile.svr4:
  357. X    [ -f s.Makefile.svr4 ] && get -t -r$(RELEASE) s.Makefile.svr4
  358. X
  359. XREADME.sun4:
  360. X    [ -f s.README.sun4 ] && get -t -r$(RELEASE) s.README.sun4
  361. X
  362. Xconfig.h.sun4:
  363. X    [ -f s.config.h.sun4 ] && get -t -r$(RELEASE) s.config.h.sun4
  364. X
  365. Xconfig.h.svr4:
  366. X    [ -f s.config.h.svr4 ] && get -t -r$(RELEASE) s.config.h.svr4
  367. X
  368. Xlogin:    $(LOBJS) libshadow.a
  369. X    $(CC) -o login $(LDFLAGS) $(LOBJS) libshadow.a $(LIBS)
  370. X
  371. Xlogin.lint: $(LSRCS)
  372. X    $(LINT) $(LINTFLAGS) $(LSRCS) > login.lint
  373. X
  374. Xsu:    $(SOBJS) libshadow.a
  375. X    $(CC) -o su $(LDFLAGS) $(SOBJS) libshadow.a $(LIBS)
  376. X
  377. Xsu.lint:    $(SSRCS)
  378. X    $(LINT) $(LINTFLAGS) -DSU $(SSRCS) > su.lint
  379. X
  380. Xpasswd:    $(POBJS) libshadow.a
  381. X    $(CC) -o passwd $(LDFLAGS) $(POBJS) libshadow.a $(LIBS) $(CRACKLIB)
  382. X
  383. Xpasswd.lint: $(PSRCS)
  384. X    $(LINT) $(LINTFLAGS) -DPASSWD $(PSRCS) > passwd.lint
  385. X
  386. Xgpasswd: $(GPOBJS) libshadow.a
  387. X    $(CC) -o gpasswd $(LDFLAGS) $(GPOBJS) libshadow.a $(LIBS)
  388. X
  389. Xgpasswd.lint: $(GPSRCS)
  390. X    $(LINT) $(LINTFLAGS) $(GPSRCS) > gpasswd.lint
  391. X
  392. Xdpasswd: $(DPOBJS) libshadow.a
  393. X    $(CC) -o dpasswd $(LDFLAGS) $(DPOBJS) libshadow.a $(LIBS)
  394. X
  395. Xdpasswd.lint: $(DPSRCS)
  396. X    $(LINT) $(LINTFLAGS) $(DPSRCS) > dpasswd.lint
  397. X
  398. Xpwconv:    $(PWOBJS) libshadow.a config.h
  399. X    $(CC) -o pwconv $(LDFLAGS) $(PWOBJS) libshadow.a $(LIBS)
  400. X
  401. Xpwconv.lint: $(PWSRCS) config.h
  402. X    $(LINT) $(LINTFLAGS) -DPASSWD $(PWSRCS) > pwconv.lint
  403. X
  404. Xpwunconv: $(PWUNOBJS) libshadow.a config.h
  405. X    $(CC) -o pwunconv $(LDFLAGS) $(PWUNOBJS) libshadow.a $(LIBS)
  406. X
  407. Xpwunconv.lint: $(PWUNSRCS)
  408. X    $(LINT) $(LINTFLAGS) -DPASSWD $(PWUNSRCS) > pwunconv.lint
  409. X
  410. Xsulogin: $(SULOGOBJS) libshadow.a
  411. X    $(CC) -o sulogin $(LDFLAGS) $(SULOGOBJS) libshadow.a $(LIBS)
  412. X
  413. Xsulogin.lint: $(SULOGSRCS)
  414. X    $(LINT) $(LINTFLAGS) $(SULOGSRCS) > sulogin.lint
  415. X
  416. Xfaillog: faillog.o
  417. X    $(CC) -o faillog $(LDFLAGS) faillog.o $(LIBS)
  418. X
  419. Xfaillog.lint: faillog.c faillog.h config.h
  420. X    $(LINT) $(LINTFLAGS) faillog.c > faillog.lint
  421. X
  422. Xlastlog: lastlog.o
  423. X    $(CC) -o lastlog $(LDFLAGS) lastlog.o $(LIBS)
  424. X
  425. Xlastlog.lint: lastlog.c config.h lastlog.h
  426. X    $(LINT) $(LINTFLAGS) $(MKPWDSRCS) > lastlog.lint
  427. X
  428. Xmkpasswd: $(MKPWDOBJS) libshadow.a
  429. X    $(CC) -o mkpasswd $(LDFLAGS) $(MKPWDOBJS) libshadow.a $(LIBS)
  430. X
  431. Xmkpasswd.lint: $(MKPWDSRCS)
  432. X    $(LINT) $(LINTFLAGS) $(MKPWDSRCS) > mkpasswd.lint
  433. X
  434. Xnewgrp: $(NGOBJS) libshadow.a
  435. X    $(CC) -o newgrp $(LDFLAGS) $(NGOBJS) libshadow.a $(LIBS)
  436. X
  437. Xnewgrp.lint: $(NGSRCS)
  438. X    $(LINT) $(LINTFLAGS) $(NGSRCS) > newgrp.lint
  439. X
  440. Xsg:    newgrp
  441. X    /bin/rm -f sg
  442. X    ln newgrp sg
  443. X
  444. Xsg.lint: newgrp.lint
  445. X    ln newgrp.lint sg.lint
  446. X
  447. Xchfn:    $(CHFNOBJS) libshadow.a
  448. X    $(CC) -o chfn $(LDFLAGS) $(CHFNOBJS) libshadow.a $(LIBS)
  449. X
  450. Xchfn.lint:    $(CHFNSRCS)
  451. X    $(LINT) $(LINTFLAGS) $(CHFNSRCS) > chfn.lint
  452. X
  453. Xchsh:    $(CHSHOBJS) libshadow.a
  454. X    $(CC) -o chsh $(LDFLAGS) $(CHSHOBJS) libshadow.a $(LIBS)
  455. X
  456. Xchsh.lint: $(CHSHSRCS)
  457. X    $(LINT) $(LINTFLAGS) $(CHSHSRCS) > chsh.lint
  458. X
  459. Xchage:    $(CHAGEOBJS) libshadow.a
  460. X    $(CC) -o chage $(LDFLAGS) $(CHAGEOBJS) libshadow.a $(LIBS)
  461. X
  462. Xchage.lint: $(CHAGESRCS)
  463. X    $(LINT) $(LINTFLAGS) -DPASSWD $(CHAGESRCS) > chage.lint
  464. X
  465. Xchpasswd: $(CHPASSOBJS) libshadow.a
  466. X    $(CC) -o chpasswd $(LDFLAGS) $(CHPASSOBJS) libshadow.a $(LIBS)
  467. X
  468. Xchpasswd.lint: $(CHPASSSRCS)
  469. X    $(LINT) $(LINTFLAGS) $(CHPASSSRCS) > chpasswd.lint
  470. X
  471. Xnewusers: newusers.o libshadow.a
  472. X    $(CC) -o newusers $(LDFLAGS) newusers.o libshadow.a $(LIBS)
  473. X
  474. Xnewusers.lint: newusers.c
  475. X    $(LINT) $(LINTFLAGS) newusers.c > newusers.lint
  476. X    
  477. Xid: id.o libshadow.a
  478. X    $(CC) -o id $(LDFLAGS) id.o libshadow.a $(LIBS)
  479. X
  480. Xid.lint: id.c
  481. X    $(LINT) $(LINTFLAGS) id.c > id.lint
  482. X
  483. Xgroups: groups.o libshadow.a
  484. X    $(CC) -o groups $(LDFLAGS) groups.o libshadow.a $(LIBS)
  485. X
  486. Xgroups.lint: groups.c
  487. X    $(LINT) $(LINTFLAGS) groups.c > groups.lint
  488. X
  489. Xuseradd: useradd.o copydir.o mkrmdir.o libshadow.a
  490. X    $(CC) -o useradd $(LDFLAGS) useradd.o copydir.o mkrmdir.o \
  491. X        libshadow.a $(LIBS) $(NDIR)
  492. X
  493. Xuseradd.lint: useradd.c copydir.c mkrmdir.c
  494. X    $(LINT) $(LINTFLAGS) useradd.c copydir.c mkrmdir.c > useradd.lint
  495. X
  496. Xuserdel: userdel.o copydir.o mkrmdir.o libshadow.a
  497. X    $(CC) -o userdel $(LDFLAGS) userdel.o copydir.o mkrmdir.o \
  498. X        libshadow.a $(LIBS) $(NDIR)
  499. X
  500. Xuserdel.lint: userdel.c copydir.c mkrmdir.c
  501. X    $(LINT) $(LINTFLAGS) userdel.c copydir.c mkrmdir.c > userdel.lint
  502. X
  503. Xusermod: usermod.o copydir.o mkrmdir.o chowndir.o libshadow.a
  504. X    $(CC) -o usermod $(LDFLAGS) usermod.o copydir.o mkrmdir.o \
  505. X        chowndir.o libshadow.a $(LIBS) $(NDIR)
  506. X
  507. Xusermod.lint: usermod.c copydir.c mkrmdir.c chowndir.c
  508. X    $(LINT) $(LINTFLAGS) usermod.c copydir.c mkrmdir.c \
  509. X        chowndir.c > usermod.lint
  510. X
  511. Xgroupadd: groupadd.o libshadow.a
  512. X    $(CC) -o groupadd $(LDFLAGS) groupadd.o libshadow.a $(LIBS)
  513. X
  514. Xgroupadd.lint: groupadd.c
  515. X    $(LINT) $(LINTFLAGS) groupadd.c > groupadd.lint
  516. X
  517. Xgroupdel: groupdel.o libshadow.a
  518. X    $(CC) -o groupdel $(LDFLAGS) groupdel.o libshadow.a $(LIBS)
  519. X
  520. Xgroupdel.lint: groupdel.c
  521. X    $(LINT) $(LINTFLAGS) groupdel.c > groupdel.lint
  522. X
  523. Xgroupmod: groupmod.o libshadow.a
  524. X    $(CC) -o groupmod $(LDFLAGS) groupmod.o libshadow.a $(LIBS)
  525. X
  526. Xgroupmod.lint: groupmod.c
  527. X    $(LINT) $(LINTFLAGS) groupmod.c > groupmod.lint
  528. X
  529. Xpwd.h.m4:
  530. X    [ -f s.pwd.h.m4 ] && get -t -r$(RELEASE) s.pwd.h.m4
  531. X
  532. Xpwd.h: pwd.h.m4
  533. X    m4 $(OS) < pwd.h.m4 > pwd.h
  534. X
  535. Xlogoutd: logoutd.o libshadow.a
  536. X    $(CC) -o logoutd $(LDFLAGS) logoutd.o libshadow.a
  537. X
  538. Xlogoutd.lint: logoutd.c
  539. X    $(LINT) $(LINTFLAGS) logoutd.c > logoutd.lint
  540. X
  541. Xpwck: pwck.o libshadow.a
  542. X    $(CC) -o pwck $(LDFLAGS) pwck.o libshadow.a $(LIBS)
  543. X
  544. Xpwck.lint: pwck.c
  545. X    $(LINT) $(LINTFLAGS) pwck.c > pwck.lint
  546. X
  547. Xgrpck: grpck.o libshadow.a
  548. X    $(CC) -o grpck $(LDFLAGS) grpck.o libshadow.a $(LIBS)
  549. X
  550. Xgrpck.lint: grpck.c
  551. X    $(LINT) $(LINTFLAGS) grpck.c > grpck.lint
  552. X
  553. Xsulog.o: config.h
  554. X
  555. Xsusetup.c: setup.c
  556. X    cp setup.c susetup.c
  557. X
  558. Xsusetup.o: config.h susetup.c pwd.h
  559. X    $(CC) -c $(CFLAGS) -DSU susetup.c
  560. X
  561. Xpasswd.o: config.h shadow.h pwd.h
  562. Xlmain.o: config.h lastlog.h faillog.h pwd.h
  563. Xsmain.o: config.h lastlog.h pwd.h shadow.h
  564. Xsub.o: pwd.h
  565. Xsetup.o: config.h pwd.h
  566. Xmkrmdir.o: config.h
  567. Xutmp.o: config.h
  568. Xmail.o: config.h
  569. Xmotd.o: config.h
  570. Xage.o: config.h pwd.h
  571. Xlog.o: config.h lastlog.h pwd.h
  572. Xshell.o: config.h
  573. Xentry.o: config.h shadow.h pwd.h
  574. Xhushed.o: config.h pwd.h
  575. Xvalid.o: config.h pwd.h
  576. Xfailure.o: faillog.h config.h
  577. Xfaillog.o: faillog.h config.h pwd.h
  578. Xnewgrp.o: config.h shadow.h pwd.h
  579. Xmkpasswd.o: config.h shadow.h pwd.h
  580. Xgpmain.o: config.h pwd.h
  581. Xchfn.o: config.h pwd.h
  582. Xchsh.o: config.h pwd.h
  583. Xchage.o: config.h shadow.h pwd.h
  584. Xpwconv.o: config.h shadow.h
  585. Xpwunconv.o: config.h shadow.h pwd.h
  586. Xchpasswd.o: config.h shadow.h pwd.h
  587. Xid.o: pwd.h
  588. Xnewusers.o: config.h shadow.h pwd.h
  589. Xdpmain.o: config.h dialup.h
  590. Xuseradd.o: config.h shadow.h pwd.h
  591. Xuserdel.o: config.h shadow.h pwd.h
  592. Xusermod.o: config.h shadow.h pwd.h
  593. Xgroupadd.o: config.h shadow.h
  594. Xgroupdel.o: config.h shadow.h
  595. Xgroupmod.o: config.h shadow.h
  596. Xlogoutd.o: config.h
  597. Xsulogin.o: config.h
  598. Xcopydir.o: config.h
  599. Xchowndir.o: config.h
  600. Xpwck.o: config.h shadow.h pwd.h
  601. Xgrpck.o: config.h shadow.h pwd.h
  602. X
  603. Xlibshadow.a(shadow.o): shadow.h config.h
  604. Xlibshadow.a(shadowio.o): shadow.h
  605. Xlibshadow.a(grent.o): config.h shadow.h
  606. Xlibshadow.a(sgroupio.o): shadow.h
  607. Xlibshadow.a(dialup.o): dialup.h
  608. Xlibshadow.a(dialchk.o): dialup.h config.h
  609. Xlibshadow.a(getdef.o): config.h
  610. Xlibshadow.a(pwdbm.o): config.h pwd.h
  611. Xlibshadow.a(spdbm.o): config.h shadow.h
  612. Xlibshadow.a(grdbm.o): config.h
  613. Xlibshadow.a(gsdbm.o): config.h shadow.h
  614. Xlibshadow.a(pwpack.o): config.h pwd.h
  615. Xlibshadow.a(pwent.o): config.h pwd.h
  616. Xlibshadow.a(pwio.o): pwd.h
  617. Xlibshadow.a(getpass.o): config.h
  618. Xlibshadow.a(encrypt.o): config.h
  619. Xlibshadow.a(port.o): port.h
  620. Xlibshadow.a(rad64.o): config.h
  621. Xlibshadow.a(lockpw.o):
  622. X
  623. Xclean:
  624. X    -rm -f susetup.c *.o a.out core npasswd nshadow *.pag *.dir pwd.h
  625. X
  626. Xclobber: clean
  627. X    -rm -f $(BINS) *.lint *.L libshadow.a
  628. X
  629. Xnuke:    clobber
  630. X    -for file in * ; do \
  631. X        if [ -f s.$$file -a ! -f p.$$file ] ; then \
  632. X            rm -f $$file ;\
  633. X        fi ;\
  634. X    done
  635. X
  636. Xshar:    login.sh.01 login.sh.02 login.sh.03 login.sh.04 login.sh.05 \
  637. X    login.sh.06 login.sh.07 login.sh.08 login.sh.09 login.sh.10 \
  638. X    login.sh.11 login.sh.12
  639. X
  640. Xlogin.sh.01: $(FILES1) Makefile
  641. X    shar -a $(FILES1) > login.sh.01
  642. X
  643. Xlogin.sh.02: $(FILES2) Makefile
  644. X    shar -a $(FILES2) > login.sh.02
  645. X
  646. Xlogin.sh.03: $(FILES3) Makefile
  647. X    shar -a $(FILES3) > login.sh.03
  648. X
  649. Xlogin.sh.04: $(FILES4) Makefile
  650. X    shar -a $(FILES4) > login.sh.04
  651. X
  652. Xlogin.sh.05: $(FILES5) Makefile
  653. X    shar -a $(FILES5) > login.sh.05
  654. X
  655. Xlogin.sh.06: $(FILES6) Makefile
  656. X    shar -a $(FILES6) > login.sh.06
  657. X
  658. Xlogin.sh.07: $(FILES7) Makefile
  659. X    shar -a $(FILES7) > login.sh.07
  660. X
  661. Xlogin.sh.08: $(FILES8) Makefile
  662. X    shar -a $(FILES8) > login.sh.08
  663. X
  664. Xlogin.sh.09: $(FILES9) Makefile
  665. X    shar -a $(FILES9) > login.sh.09
  666. X
  667. Xlogin.sh.10: $(DOCS1) Makefile
  668. X    shar -a $(DOCS1) > login.sh.10
  669. X
  670. Xlogin.sh.11: $(DOCS2) Makefile
  671. X    shar -a $(DOCS2) > login.sh.11
  672. X
  673. Xlogin.sh.12: $(FILES_SUN4) $(FILES_SVR4) Makefile
  674. X    shar -a $(FILES_SUN4) $(FILES_SVR4) > login.sh.12
  675. END_OF_FILE
  676.   if test 18940 -ne `wc -c <'Makefile.svr4'`; then
  677.     echo shar: \"'Makefile.svr4'\" unpacked with wrong size!
  678.   fi
  679.   # end of 'Makefile.svr4'
  680. fi
  681. if test -f 'gpmain.c' -a "${1}" != "-c" ; then 
  682.   echo shar: Will not clobber existing file \"'gpmain.c'\"
  683. else
  684.   echo shar: Extracting \"'gpmain.c'\" \(18788 characters\)
  685.   sed "s/^X//" >'gpmain.c' <<'END_OF_FILE'
  686. X/*
  687. X * Copyright 1990, 1991, 1992, 1993, John F. Haugh II
  688. X * All rights reserved.
  689. X *
  690. X * Permission is granted to copy and create derivative works for any
  691. X * non-commercial purpose, provided this copyright notice is preserved
  692. X * in all copies of source code, or included in human readable form
  693. X * and conspicuously displayed on all copies of object code or
  694. X * distribution media.
  695. X *
  696. X * This software is provided on an AS-IS basis and the author makes
  697. X * no warrantee of any kind.
  698. X */
  699. X
  700. X#include <sys/types.h>
  701. X#include <stdio.h>
  702. X#include "pwd.h"
  703. X#include "shadow.h"
  704. X#include <grp.h>
  705. X#include <fcntl.h>
  706. X#include <signal.h>
  707. X#include <errno.h>
  708. X#if defined(USG) || defined(SUN4)
  709. X#include <termio.h>
  710. X#ifdef SYS3
  711. X# include <sys/ioctl.h>
  712. X#endif    /* SYS3 */
  713. X#include <string.h>
  714. X#ifndef    SYS3
  715. X# include <memory.h>
  716. X#endif /* !SYS3 */
  717. X#else /* SUN || BSD */
  718. X#include <sgtty.h>
  719. X#include <strings.h>
  720. X#define    strchr    index
  721. X#define    strrchr    rindex
  722. X#endif /* !SUN && !BSD */
  723. X#include "config.h"
  724. X
  725. X#ifdef    USE_SYSLOG
  726. X#include <syslog.h>
  727. X
  728. X#ifndef    LOG_WARN
  729. X#define    LOG_WARN    LOG_WARNING
  730. X#endif
  731. X#endif
  732. X
  733. X#ifdef    USG
  734. X#define    bzero(p,l) memset(p, 0, l)
  735. X#endif
  736. X
  737. X#ifndef    lint
  738. Xstatic    char    _sccsid[] = "@(#)gpmain.c    3.14    08:16:38    07 May 1993";
  739. X#endif
  740. X
  741. Xchar    name[BUFSIZ];
  742. Xchar    pass[BUFSIZ];
  743. Xchar    pass2[BUFSIZ];
  744. X
  745. Xstruct    group    grent;
  746. X
  747. Xchar    *Prog;
  748. Xchar    *user;
  749. Xchar    *group;
  750. Xchar    *admins;
  751. Xchar    *members;
  752. X
  753. Xint    aflg;
  754. Xint    Aflg;
  755. Xint    dflg;
  756. Xint    Mflg;
  757. Xint    rflg;
  758. Xint    Rflg;
  759. X
  760. X#ifndef    RETRIES
  761. X#define    RETRIES    3
  762. X#endif
  763. X
  764. Xextern    char    *l64a ();
  765. Xextern    char    *crypt ();
  766. Xextern    char    *pw_encrypt ();
  767. Xextern    int    errno;
  768. Xextern    long    a64l ();
  769. Xextern    void    entry ();
  770. Xextern    time_t    time ();
  771. Xextern    char    *malloc ();
  772. Xextern    char    *getpass ();
  773. X#ifdef    NDBM
  774. Xextern    int    sg_dbm_mode;
  775. Xextern    int    gr_dbm_mode;
  776. X#endif
  777. X
  778. X/*
  779. X * usage - display usage message
  780. X */
  781. X
  782. Xvoid
  783. Xusage ()
  784. X{
  785. X    fprintf (stderr, "usage: %s [ -r|R ] group\n", Prog);
  786. X    fprintf (stderr, "       %s [ -a user ] group\n", Prog);
  787. X    fprintf (stderr, "       %s [ -d user ] group\n", Prog);
  788. X#ifdef    SHADOWGRP
  789. X    fprintf (stderr, "       %s [ -A user[,user] ][ -M user[,user] group\n",
  790. X        Prog);
  791. X#else
  792. X    fprintf (stderr, "       %s [ -M user[,user] group\n", Prog);
  793. X#endif
  794. X    exit (1);
  795. X}
  796. X
  797. X/*
  798. X * add_list - add a member to a list of group members
  799. X *
  800. X *    the array of member names is searched for the new member
  801. X *    name, and if not present it is added to a freshly allocated
  802. X *    list of users.
  803. X */
  804. X
  805. Xchar **
  806. Xadd_list (list, member)
  807. Xchar    **list;
  808. Xchar    *member;
  809. X{
  810. X    int    i;
  811. X    char    **tmp;
  812. X
  813. X    for (i = 0;list[i] != (char *) 0;i++)
  814. X        if (strcmp (list[i], member) == 0)
  815. X            return list;
  816. X
  817. X    if (! (tmp = (char **) malloc ((i + 2) * sizeof member)))
  818. X        return 0;
  819. X
  820. X    for (i = 0;list[i] != (char *) 0;i++)
  821. X        tmp[i] = list[i];
  822. X
  823. X    tmp[i++] = strdup (member);
  824. X    tmp[i] = (char *) 0;
  825. X
  826. X    return tmp;
  827. X}
  828. X
  829. X/*
  830. X * del_list - delete a group member from a list of members
  831. X *
  832. X *    del_list searches a list of group members, copying the
  833. X *    members which do not match "member" to a newly allocated
  834. X *    list.
  835. X */
  836. X
  837. Xchar **
  838. Xdel_list (list, member)
  839. Xchar    **list;
  840. Xchar    *member;
  841. X{
  842. X    int    i, j;
  843. X    char    **tmp;
  844. X
  845. X    for (j = i = 0;list[i] != (char *) 0;i++)
  846. X        if (strcmp (list[i], member))
  847. X            j++;
  848. X
  849. X    tmp = (char **) malloc ((j + 1) * sizeof member);
  850. X
  851. X    for (j = i = 0;list[i] != (char *) 0;i++)
  852. X        if (strcmp (list[i], member) != 0)
  853. X            tmp[j++] = list[i];
  854. X
  855. X    tmp[j] = (char *) 0;
  856. X
  857. X    return tmp;
  858. X}
  859. X
  860. X/*
  861. X * comma_to_list - convert comma-separated list to (char *) array
  862. X */
  863. X
  864. Xchar **
  865. Xcomma_to_list (comma)
  866. Xchar    *comma;
  867. X{
  868. X    char    *members;
  869. X    char    **array;
  870. X    int    i;
  871. X    char    *cp, *cp2;
  872. X
  873. X    /*
  874. X     * Make a copy since we are going to be modifying the list
  875. X     */
  876. X
  877. X    if (! (members = strdup (comma))) {
  878. X        perror ("malloc");
  879. X        exit (1);
  880. X    }
  881. X
  882. X    /*
  883. X     * Count the number of commas in the list
  884. X     */
  885. X
  886. X    for (cp = members, i = 0;;i++)
  887. X        if (cp2 = strchr (cp, ','))
  888. X            cp = cp2 + 1;
  889. X        else
  890. X            break;
  891. X
  892. X    /*
  893. X     * Add 2 - one for the ending NULL, the other for the last item
  894. X     */
  895. X
  896. X    i += 2;
  897. X
  898. X    /*
  899. X     * Allocate the array we're going to store the pointers into.
  900. X     */
  901. X
  902. X    if (! (array = (char **) malloc (sizeof (char *) * i))) {
  903. X
  904. X        /*
  905. X         * Can't happen ...
  906. X         */
  907. X
  908. X        perror ("malloc");
  909. X        exit (1);
  910. X    }
  911. X
  912. X    /*
  913. X     * Now go walk that list all over again, this time building the
  914. X     * array of pointers.
  915. X     */
  916. X
  917. X    for (cp = members, i = 0;;i++) {
  918. X        array[i] = cp;
  919. X        if (cp2 = strchr (cp, ',')) {
  920. X            *cp2++ = '\0';
  921. X            cp = cp2;
  922. X        } else {
  923. X            array[i + 1] = (char *) 0;
  924. X            break;
  925. X        }
  926. X    }
  927. X
  928. X    /*
  929. X     * Return the new array of pointers
  930. X     */
  931. X
  932. X    return array;
  933. X}
  934. X
  935. X/*
  936. X * check_list - check a comma-separated list of user names for validity
  937. X *
  938. X *    check_list scans a comma-separated list of user names and checks
  939. X *    that each listed name exists.
  940. X */
  941. X
  942. Xint
  943. Xcheck_list (users)
  944. Xchar    *users;
  945. X{
  946. X    char    *cp;
  947. X    char    *end;
  948. X    char    *start;
  949. X    char    user[16];
  950. X    int    errors = 0;
  951. X    int    len;
  952. X
  953. X    for (start = users;start && *start;start = end) {
  954. X        if (end = strchr (start, ',')) {
  955. X            if ((len = end - start) > 15)
  956. X                len = 15;
  957. X
  958. X            strncpy (user, start, len);
  959. X            user[len] = 0;
  960. X            end++;
  961. X        } else {
  962. X            if ((len = strlen (start)) > 15)
  963. X                len = 15;
  964. X
  965. X            strncpy (user, start, len);
  966. X            user[len] = 0;
  967. X        }
  968. X
  969. X        /*
  970. X         * This user must exist.
  971. X         */
  972. X
  973. X        if (! getpwnam (user)) {
  974. X            fprintf (stderr, "%s: unknown user %s\n", Prog, user);
  975. X            errors++;
  976. X        }
  977. X    }
  978. X    return errors;
  979. X}
  980. X
  981. X/*
  982. X * gpasswd - administer the /etc/group file
  983. X *
  984. X *    -a user        add user to the named group
  985. X *    -d user        remove user from the named group
  986. X *    -r        remove password from the named group
  987. X *    -R        restrict access to the named group
  988. X *    -A user,...    make list of users the administrative users
  989. X *    -M user,...    make list of users the group members
  990. X */
  991. X
  992. Xint
  993. Xmain (argc, argv)
  994. Xint    argc;
  995. Xchar    **argv;
  996. X{
  997. X    extern    int    optind;
  998. X    extern    char    *optarg;
  999. X    int    flag;
  1000. X    int    i;
  1001. X    void    die ();
  1002. X    char    *cp;
  1003. X    char    *getlogin ();
  1004. X    char    *getpass ();
  1005. X    int    amroot;
  1006. X    int    retries;
  1007. X    int    ruid = getuid();
  1008. X    struct    group    *gr = 0;
  1009. X    struct    group    *getgrnam ();
  1010. X    struct    group    *sgetgrent ();
  1011. X#ifdef    SHADOWGRP
  1012. X    struct    sgrp    *sg = 0;
  1013. X    struct    sgrp    sgent;
  1014. X    struct    sgrp    *getsgnam ();
  1015. X#endif
  1016. X    struct    passwd    *pw = 0;
  1017. X    struct    passwd    *getpwuid ();
  1018. X    struct    passwd    *getpwnam ();
  1019. X
  1020. X    /*
  1021. X     * Make a note of whether or not this command was invoked
  1022. X     * by root.  This will be used to bypass certain checks
  1023. X     * later on.  Also, set the real user ID to match the
  1024. X     * effective user ID.  This will prevent the invoker from
  1025. X     * issuing signals which would interfer with this command.
  1026. X     */
  1027. X
  1028. X    amroot = getuid () == 0;
  1029. X#ifdef    NDBM
  1030. X    sg_dbm_mode = O_RDWR;
  1031. X    gr_dbm_mode = O_RDWR;
  1032. X#endif
  1033. X    setuid (geteuid ());
  1034. X
  1035. X    if (Prog = strrchr (argv[0], '/'))
  1036. X        Prog++;
  1037. X    else
  1038. X        Prog = argv[0];
  1039. X
  1040. X#ifdef    USE_SYSLOG
  1041. X    openlog (Prog, LOG_PID|LOG_CONS|LOG_NOWAIT, LOG_AUTH);
  1042. X#endif
  1043. X    setbuf (stdout, (char *) 0);
  1044. X    setbuf (stderr, (char *) 0);
  1045. X
  1046. X    while ((flag = getopt (argc, argv, "a:d:grRA:M:")) != EOF) {
  1047. X        switch (flag) {
  1048. X            case 'a':    /* add a user */
  1049. X                aflg++;
  1050. X                user = optarg;
  1051. X                break;
  1052. X            case 'A':
  1053. X                Aflg++;
  1054. X                admins = optarg;
  1055. X                break;
  1056. X            case 'd':    /* delete a user */
  1057. X                dflg++;
  1058. X                user = optarg;
  1059. X                break;
  1060. X            case 'g':    /* no-op from normal password */
  1061. X                break;
  1062. X            case 'M':
  1063. X                Mflg++;
  1064. X                members = optarg;
  1065. X                break;
  1066. X            case 'r':    /* remove group password */
  1067. X                rflg++;
  1068. X                break;
  1069. X            case 'R':    /* restrict group password */
  1070. X                Rflg++;
  1071. X                break;
  1072. X            default:
  1073. X                usage ();
  1074. X        }
  1075. X    }
  1076. X
  1077. X    /*
  1078. X     * Make sure exclusive flags are exclusive
  1079. X     */
  1080. X
  1081. X    if (aflg + dflg + rflg + Rflg + (Aflg || Mflg) > 1)
  1082. X        usage ();
  1083. X
  1084. X    /*
  1085. X     * If the password is being changed, the input and output must
  1086. X     * both be a tty.  The typical keyboard signals are caught
  1087. X     * so the termio modes can be restored.
  1088. X     */
  1089. X
  1090. X    if (! aflg && ! dflg && ! rflg && ! Rflg && ! Aflg && ! Mflg) {
  1091. X        if (! isatty (0) || ! isatty (1))
  1092. X            exit (1);
  1093. X
  1094. X        die (0);            /* save tty modes */
  1095. X
  1096. X        signal (SIGHUP, die);
  1097. X        signal (SIGINT, die);
  1098. X        signal (SIGQUIT, die);
  1099. X        signal (SIGTERM, die);
  1100. X#ifdef    SIGTSTP
  1101. X        signal (SIGTSTP, die);
  1102. X#endif
  1103. X    }
  1104. X
  1105. X    /*
  1106. X     * Determine the name of the user that invoked this command.
  1107. X     * This is really hit or miss because there are so many ways
  1108. X     * that command can be executed and so many ways to trip up
  1109. X     * the routines that report the user name.
  1110. X     */
  1111. X
  1112. X    if ((cp = getlogin ()) && (pw = getpwnam (cp)) && pw->pw_uid == ruid) {
  1113. X                    /* need user name */
  1114. X        (void) strcpy (name, cp);
  1115. X    } else if (pw = getpwuid (ruid)) /* get it from password file */
  1116. X        strcpy (name, pw->pw_name);
  1117. X    else {                /* can't find user name! */
  1118. X        fprintf (stderr, "Who are you?\n");
  1119. X        exit (1);
  1120. X    }
  1121. X    if (! (pw = getpwnam (name)))
  1122. X        goto failure;        /* can't get my name ... */
  1123. X        
  1124. X    /*
  1125. X     * Get the name of the group that is being affected.  The group
  1126. X     * entry will be completely replicated so it may be modified
  1127. X     * later on.
  1128. X     */
  1129. X
  1130. X    if (! (group = argv[optind]))
  1131. X        usage ();
  1132. X
  1133. X    if (! (gr = getgrnam (group))) {
  1134. X        fprintf (stderr, "unknown group: %s\n", group);
  1135. X        exit (1);
  1136. X    }
  1137. X    grent = *gr;
  1138. X    grent.gr_name = strdup (gr->gr_name);
  1139. X    grent.gr_passwd = strdup (gr->gr_passwd);
  1140. X
  1141. X    for (i = 0;gr->gr_mem[i];i++)
  1142. X        ;
  1143. X    grent.gr_mem = (char **) malloc ((i + 1) * sizeof (char *));
  1144. X    for (i = 0;gr->gr_mem[i];i++)
  1145. X        grent.gr_mem[i] = strdup (gr->gr_mem[i]);
  1146. X    grent.gr_mem[i] = (char *) 0;
  1147. X#ifdef    SHADOWGRP
  1148. X    if (sg = getsgnam (group)) {
  1149. X        sgent = *sg;
  1150. X        sgent.sg_name = strdup (sg->sg_name);
  1151. X        sgent.sg_passwd = strdup (sg->sg_passwd);
  1152. X
  1153. X        for (i = 0;sg->sg_mem[i];i++)
  1154. X            ;
  1155. X        sgent.sg_mem = (char **) malloc (sizeof (char *) * (i + 1));
  1156. X        for (i = 0;sg->sg_mem[i];i++)
  1157. X            sgent.sg_mem[i] = strdup (sg->sg_mem[i]);
  1158. X        sgent.sg_mem[i] = 0;
  1159. X
  1160. X        for (i = 0;sg->sg_adm[i];i++)
  1161. X            ;
  1162. X        sgent.sg_adm = (char **) malloc (sizeof (char *) * (i + 1));
  1163. X        for (i = 0;sg->sg_adm[i];i++)
  1164. X            sgent.sg_adm[i] = strdup (sg->sg_adm[i]);
  1165. X        sgent.sg_adm[i] = 0;
  1166. X    } else {
  1167. X        sgent.sg_name = strdup (group);
  1168. X        sgent.sg_passwd = grent.gr_passwd;
  1169. X        grent.gr_passwd = "!";
  1170. X
  1171. X        for (i = 0;grent.gr_mem[i];i++)
  1172. X            ;
  1173. X        sgent.sg_mem = (char **) malloc (sizeof (char *) * (i + 1));
  1174. X        for (i = 0;grent.gr_mem[i];i++)
  1175. X            sgent.sg_mem[i] = strdup (grent.gr_mem[i]);
  1176. X        sgent.sg_mem[i] = 0;
  1177. X
  1178. X        sgent.sg_adm = (char **) malloc (sizeof (char *) * 2);
  1179. X        if (sgent.sg_mem[0]) {
  1180. X            sgent.sg_adm[0] = strdup (sgent.sg_mem[0]);
  1181. X            sgent.sg_adm[1] = 0;
  1182. X        } else
  1183. X            sgent.sg_adm[0] = 0;
  1184. X
  1185. X        sg = &sgent;
  1186. X    }
  1187. X#endif
  1188. X
  1189. X#ifdef    SHADOWGRP
  1190. X
  1191. X    /*
  1192. X     * The policy here for changing a group is that 1) you must be
  1193. X     * root or 2). you must be listed as an administrative member.
  1194. X     * Administrative members can do anything to a group that the
  1195. X     * root user can.
  1196. X     */
  1197. X
  1198. X    if (! amroot) {
  1199. X        for (i = 0;sgent.sg_adm[i];i++)
  1200. X            if (strcmp (sgent.sg_adm[i], name) == 0)
  1201. X                break;
  1202. X
  1203. X        if (sgent.sg_adm[i] == (char *) 0)
  1204. X            goto failure;
  1205. X    }
  1206. X#else
  1207. X
  1208. X    /*
  1209. X     * The policy here for changing a group is that 1) you must bes
  1210. X     * root or 2) you must be the first listed member of the group.
  1211. X     * The first listed member of a group can do anything to that
  1212. X     * group that the root user can.  The rationale for this hack is
  1213. X     * that the FIRST user is probably the most important user in
  1214. X     * this entire group.
  1215. X     */
  1216. X
  1217. X    if (! amroot) {
  1218. X        if (grent.gr_mem[0] == (char *) 0)
  1219. X            goto failure;
  1220. X
  1221. X        if (strcmp (grent.gr_mem[0], name) != 0)
  1222. X            goto failure;
  1223. X    }
  1224. X
  1225. X#endif    /* SHADOWGRP */
  1226. X
  1227. X    /*
  1228. X     * Removing a password is straight forward.  Just set the
  1229. X     * password field to a "".
  1230. X     */
  1231. X
  1232. X    if (rflg) {
  1233. X        grent.gr_passwd = "";
  1234. X#ifdef    SHADOWGRP
  1235. X        sgent.sg_passwd = "";
  1236. X#endif
  1237. X#ifdef    USE_SYSLOG
  1238. X        syslog (LOG_INFO, "remove password from group %s\n", group);
  1239. X#endif
  1240. X        goto output;
  1241. X    } else if (Rflg) {
  1242. X
  1243. X    /*
  1244. X     * Same thing for restricting the group.  Set the password
  1245. X     * field to "!".
  1246. X     */
  1247. X
  1248. X        grent.gr_passwd = "!";
  1249. X#ifdef    SHADOWGRP
  1250. X        sgent.sg_passwd = "!";
  1251. X#endif
  1252. X#ifdef    USE_SYSLOG
  1253. X        syslog (LOG_INFO, "restrict access to group %s\n", group);
  1254. X#endif
  1255. X        goto output;
  1256. X    }
  1257. X
  1258. X    /*
  1259. X     * Adding a member to a member list is pretty straightforward
  1260. X     * as well.  Call the appropriate routine and split.
  1261. X     */
  1262. X
  1263. X    if (aflg) {
  1264. X        if (getpwnam (user) == (struct passwd *) 0) {
  1265. X            fprintf (stderr, "%s: unknown user %s\n", Prog, user);
  1266. X            exit (1);
  1267. X        }
  1268. X        printf ("Adding user %s to group %s\n", user, group);
  1269. X        grent.gr_mem = add_list (grent.gr_mem, user);
  1270. X#ifdef    SHADOWGRP
  1271. X        sgent.sg_mem = add_list (sgent.sg_mem, user);
  1272. X#endif
  1273. X#ifdef    USE_SYSLOG
  1274. X        syslog (LOG_INFO, "add member %s to group %s\n", user, group);
  1275. X#endif
  1276. X        goto output;
  1277. X    }
  1278. X
  1279. X    /*
  1280. X     * Removing a member from the member list is the same deal
  1281. X     * as adding one, except the routine is different.
  1282. X     */
  1283. X
  1284. X    if (dflg) {
  1285. X        int    removed = 0;
  1286. X
  1287. X        for (i = 0;grent.gr_mem[i];i++)
  1288. X            if (strcmp (user, grent.gr_mem[i]) == 0)
  1289. X                break;
  1290. X
  1291. X        printf ("Removing user %s from group %s\n", user, group);
  1292. X
  1293. X        if (grent.gr_mem[i] != (char *) 0) {
  1294. X            removed = 1;
  1295. X            grent.gr_mem = del_list (grent.gr_mem, user);
  1296. X        }
  1297. X#ifdef    SHADOWGRP
  1298. X        for (i = 0;sgent.sg_mem[i];i++)
  1299. X            if (strcmp (user, sgent.sg_mem[i]) == 0)
  1300. X                break;
  1301. X
  1302. X        if (sgent.sg_mem[i] != (char *) 0) {
  1303. X            removed = 1;
  1304. X            sgent.sg_mem = del_list (sgent.sg_mem, user);
  1305. X        }
  1306. X#endif
  1307. X        if (! removed) {
  1308. X            fprintf (stderr, "%s: unknown member %s\n", Prog, user);
  1309. X            exit (1);
  1310. X        }
  1311. X#ifdef    USE_SYSLOG
  1312. X        syslog (LOG_INFO, "remove member %s from group %s\n",
  1313. X                user, group);
  1314. X#endif
  1315. X        goto output;
  1316. X    }
  1317. X
  1318. X    /*
  1319. X     * Replacing the entire list of members is simple.  Check the list
  1320. X     * to make sure everyone is a real user.  Then slap the new list
  1321. X     * in place.
  1322. X     */
  1323. X
  1324. X    if (Mflg) {
  1325. X
  1326. X        /*
  1327. X         * Only root can replace the entire list.
  1328. X         */
  1329. X
  1330. X        if (! amroot)
  1331. X            goto failure;
  1332. X
  1333. X        /*
  1334. X         * Check the list for validity, then put it in.
  1335. X         */
  1336. X
  1337. X        if (check_list (members))
  1338. X            exit (1);
  1339. X
  1340. X#ifdef    USE_SYSLOG
  1341. X        syslog (LOG_INFO, "set members of %s to %s\n", group, members);
  1342. X#endif
  1343. X#ifdef    SHADOWGRP
  1344. X        sgent.sg_mem = comma_to_list (members);
  1345. X        grent.gr_mem = comma_to_list (members);
  1346. X
  1347. X        if (! Aflg)
  1348. X            goto output;
  1349. X#else
  1350. X        grent.gr_mem = comma_to_list (members);
  1351. X
  1352. X        goto output;
  1353. X#endif
  1354. X    }
  1355. X
  1356. X#ifdef    SHADOWGRP
  1357. X
  1358. X    /*
  1359. X     * Replacing the entire list of administators is simple.  Check the
  1360. X     * list to make sure everyone is a real user.  Then slap the new
  1361. X     * list in place.
  1362. X     */
  1363. X
  1364. X    if (Aflg) {
  1365. X
  1366. X        /*
  1367. X         * Only root can replace the entire list.
  1368. X         */
  1369. X
  1370. X        if (! amroot)
  1371. X            goto failure;
  1372. X
  1373. X        /*
  1374. X         * Check the list for validity, then put it in.
  1375. X         */
  1376. X
  1377. X        if (check_list (admins))
  1378. X            exit (1);
  1379. X
  1380. X#ifdef    USE_SYSLOG
  1381. X        syslog (LOG_INFO, "set administrators of %s to %s\n",
  1382. X                group, members);
  1383. X#endif
  1384. X        sgent.sg_adm = comma_to_list (admins);
  1385. X
  1386. X        goto output;
  1387. X    }
  1388. X#endif
  1389. X
  1390. X    /*
  1391. X     * A new password is to be entered and it must be encrypted,
  1392. X     * etc.  The password will be prompted for twice, and both
  1393. X     * entries must be identical.  There is no need to validate
  1394. X     * the old password since the invoker is either the group
  1395. X     * owner, or root.
  1396. X     */
  1397. X
  1398. X    printf ("Changing the password for group %s\n", group);
  1399. X
  1400. X    for (retries = 0;retries < RETRIES;retries++) {
  1401. X        if (! (cp = getpass ("New Password:")))
  1402. X            exit (1);
  1403. X        else {
  1404. X            strcpy (pass, cp);
  1405. X            bzero (cp, strlen (cp));
  1406. X        }
  1407. X        if (! (cp = getpass ("Re-enter new password:")))
  1408. X            exit (1);
  1409. X        else {
  1410. X            strcpy (pass2, cp);
  1411. X            bzero (cp, strlen (cp));
  1412. X        }
  1413. X        if (strcmp (pass, pass2) == 0)
  1414. X            break;
  1415. X
  1416. X        bzero (pass, sizeof pass);
  1417. X        bzero (pass2, sizeof pass2);
  1418. X
  1419. X        if (retries + 1 < RETRIES)
  1420. X            puts ("They don't match; try again");
  1421. X    }
  1422. X    bzero (pass2, sizeof pass2);
  1423. X
  1424. X    if (retries == RETRIES) {
  1425. X        fprintf (stderr, "%s: Try again later\n", Prog);
  1426. X        exit (1);
  1427. X    }
  1428. X#ifdef    SHADOWGRP
  1429. X    sgent.sg_passwd = pw_encrypt (pass, (char *) 0);
  1430. X#else
  1431. X    grent.gr_passwd = pw_encrypt (pass, (char *) 0);
  1432. X#endif
  1433. X    bzero (pass, sizeof pass);
  1434. X#ifdef    USE_SYSLOG
  1435. X    syslog (LOG_INFO, "change the password for group %s\n", group);
  1436. X#endif
  1437. X
  1438. X    /*
  1439. X     * This is the common arrival point to output the new group
  1440. X     * file.  The freshly crafted entry is in allocated space.
  1441. X     * The group file will be locked and opened for writing.  The
  1442. X     * new entry will be output, etc.
  1443. X     */
  1444. X
  1445. Xoutput:
  1446. X    signal (SIGHUP, SIG_IGN);
  1447. X    signal (SIGINT, SIG_IGN);
  1448. X    signal (SIGQUIT, SIG_IGN);
  1449. X#ifdef    SIGTSTP
  1450. X    signal (SIGTSTP, SIG_IGN);
  1451. X#endif
  1452. X
  1453. X    if (! gr_lock ()) {
  1454. X        fprintf (stderr, "%s: can't get lock\n", Prog);
  1455. X#ifdef    USE_SYSLOG
  1456. X        syslog (LOG_WARN, "failed to get lock for /etc/group\n");
  1457. X#endif
  1458. X        exit (1);
  1459. X    }
  1460. X#ifdef    SHADOWGRP
  1461. X    if (! sgr_lock ()) {
  1462. X        fprintf (stderr, "%s: can't get shadow lock\n", Prog);
  1463. X#ifdef    USE_SYSLOG
  1464. X        syslog (LOG_WARN, "failed to get lock for /etc/gshadow\n");
  1465. X#endif
  1466. X        exit (1);
  1467. X    }
  1468. X#endif
  1469. X    if (! gr_open (O_RDWR)) {
  1470. X        fprintf (stderr, "%s: can't open file\n", Prog);
  1471. X#ifdef    USE_SYSLOG
  1472. X        syslog (LOG_WARN, "cannot open /etc/group\n");
  1473. X#endif
  1474. X        exit (1);
  1475. X    }
  1476. X#ifdef    SHADOWGRP
  1477. X    if (! sgr_open (O_RDWR)) {
  1478. X        fprintf (stderr, "%s: can't open shadow file\n", Prog);
  1479. X#ifdef    USE_SYSLOG
  1480. X        syslog (LOG_WARN, "cannot open /etc/gshadow\n");
  1481. X#endif
  1482. X        exit (1);
  1483. X    }
  1484. X#endif
  1485. X    if (! gr_update (&grent)) {
  1486. X        fprintf (stderr, "%s: can't update entry\n", Prog);
  1487. X#ifdef    USE_SYSLOG
  1488. X        syslog (LOG_WARN, "cannot update /etc/group\n");
  1489. X#endif
  1490. X        exit (1);
  1491. X    }
  1492. X#ifdef    SHADOWGRP
  1493. X    if (! sgr_update (&sgent)) {
  1494. X        fprintf (stderr, "%s: can't update shadow entry\n", Prog);
  1495. X#ifdef    USE_SYSLOG
  1496. X        syslog (LOG_WARN, "cannot update /etc/gshadow\n");
  1497. X#endif
  1498. X        exit (1);
  1499. X    }
  1500. X#endif
  1501. X    if (! gr_close ()) {
  1502. X        fprintf (stderr, "%s: can't re-write file\n", Prog);
  1503. X#ifdef    USE_SYSLOG
  1504. X        syslog (LOG_WARN, "cannot re-write /etc/group\n");
  1505. X#endif
  1506. X        exit (1);
  1507. X    }
  1508. X#ifdef    SHADOWGRP
  1509. X    if (! sgr_close ()) {
  1510. X        fprintf (stderr, "%s: can't re-write shadow file\n", Prog);
  1511. X#ifdef    USE_SYSLOG
  1512. X        syslog (LOG_WARN, "cannot re-write /etc/gshadow\n");
  1513. X#endif
  1514. X        exit (1);
  1515. X    }
  1516. X    (void) sgr_unlock ();
  1517. X#endif
  1518. X    if (! gr_unlock ()) {
  1519. X        fprintf (stderr, "%s: can't unlock file\n", Prog);
  1520. X        exit (1);
  1521. X    }
  1522. X#ifdef    NDBM
  1523. X    if (access ("/etc/group.pag", 0) == 0 && ! gr_dbm_update (&grent)) {
  1524. X        fprintf (stderr, "%s: can't update DBM files\n", Prog);
  1525. X#ifdef    USE_SYSLOG
  1526. X        syslog (LOG_WARN, "cannot update /etc/group DBM files\n");
  1527. X#endif
  1528. X        exit (1);
  1529. X    }
  1530. X    endgrent ();
  1531. X#ifdef    SHADOWGRP
  1532. X    if (access ("/etc/gshadow.pag", 0) == 0 && ! sg_dbm_update (&sgent)) {
  1533. X        fprintf (stderr, "%s: can't update DBM shadow files\n", Prog);
  1534. X#ifdef    USE_SYSLOG
  1535. X        syslog (LOG_WARN, "cannot update /etc/gshadow DBM files\n");
  1536. X#endif
  1537. X        exit (1);
  1538. X    }
  1539. X    endsgent ();
  1540. X#endif
  1541. X#endif
  1542. X    exit (0);
  1543. X    /*NOTREACHED*/
  1544. X
  1545. Xfailure:
  1546. X    fprintf (stderr, "Permission denied.\n");
  1547. X    exit (1);
  1548. X    /*NOTREACHED*/
  1549. X}
  1550. X
  1551. X/*
  1552. X * die - set or reset termio modes.
  1553. X *
  1554. X *    die() is called before processing begins.  signal() is then
  1555. X *    called with die() as the signal handler.  If signal later
  1556. X *    calls die() with a signal number, the terminal modes are
  1557. X *    then reset.
  1558. X */
  1559. X
  1560. Xvoid
  1561. Xdie (killed)
  1562. Xint    killed;
  1563. X{
  1564. X#if defined(BSD) || defined(SUN)
  1565. X    static    struct    sgtty    sgtty;
  1566. X
  1567. X    if (killed)
  1568. X        stty (0, &sgtty);
  1569. X    else
  1570. X        gtty (0, &sgtty);
  1571. X#else
  1572. X#if defined(SVR4) || defined (SUN4)
  1573. X    static    struct    termios    sgtty;
  1574. X
  1575. X    if (killed)
  1576. X        tcsetattr (0, TCSANOW, &sgtty);
  1577. X    else
  1578. X        tcgetattr (0, &sgtty);
  1579. X#else    /* !SVR4 */
  1580. X    static    struct    termio    sgtty;
  1581. X
  1582. X    if (killed)
  1583. X        ioctl (0, TCSETA, &sgtty);
  1584. X    else
  1585. X        ioctl (0, TCGETA, &sgtty);
  1586. X#endif    /* SVR4 */
  1587. X#endif    /* BSD || SUN */
  1588. X    if (killed) {
  1589. X        putchar ('\n');
  1590. X        fflush (stdout);
  1591. X        exit (killed);
  1592. X    }
  1593. X}
  1594. END_OF_FILE
  1595.   if test 18788 -ne `wc -c <'gpmain.c'`; then
  1596.     echo shar: \"'gpmain.c'\" unpacked with wrong size!
  1597.   fi
  1598.   # end of 'gpmain.c'
  1599. fi
  1600. if test -f 'lmain.c' -a "${1}" != "-c" ; then 
  1601.   echo shar: Will not clobber existing file \"'lmain.c'\"
  1602. else
  1603.   echo shar: Extracting \"'lmain.c'\" \(19435 characters\)
  1604.   sed "s/^X//" >'lmain.c' <<'END_OF_FILE'
  1605. X/*
  1606. X * Copyright 1989, 1990, 1991, 1992, 1993, John F. Haugh II
  1607. X * All rights reserved.
  1608. X *
  1609. X * Permission is granted to copy and create derivative works for any
  1610. X * non-commercial purpose, provided this copyright notice is preserved
  1611. X * in all copies of source code, or included in human readable form
  1612. X * and conspicuously displayed on all copies of object code or
  1613. X * distribution media.
  1614. X *
  1615. X * This software is provided on an AS-IS basis and the author makes
  1616. X * no warrantee of any kind.
  1617. X */
  1618. X
  1619. X#include "config.h"
  1620. X#include <sys/types.h>
  1621. X#include <sys/stat.h>
  1622. X#include <stdio.h>
  1623. X#include "pwd.h"
  1624. X#ifdef SVR4
  1625. X#include <utmpx.h>
  1626. X#else
  1627. X#include <utmp.h>
  1628. X#endif
  1629. X#include <time.h>
  1630. X#include <signal.h>
  1631. X#ifndef    BSD
  1632. X#include <string.h>
  1633. X#include <memory.h>
  1634. X#else
  1635. X#include <strings.h>
  1636. X#define    strchr    index
  1637. X#define    strrchr    rindex
  1638. X#endif
  1639. X#ifndef    BSD
  1640. X#ifdef    SVR4
  1641. X#include <termios.h>
  1642. X#else    /* !SVR4 */
  1643. X#include <termio.h>
  1644. X#endif    /* SVR4 */
  1645. X#else
  1646. X#include <sgtty.h>
  1647. X#endif
  1648. X#ifdef    STDLIB_H
  1649. X#include <stdlib.h>
  1650. X#endif
  1651. X#ifdef    UNISTD_H
  1652. X#include <unistd.h>
  1653. X#endif
  1654. X
  1655. X#include "lastlog.h"
  1656. X#include "faillog.h"
  1657. X#ifdef    SHADOWPWD
  1658. X#include "shadow.h"
  1659. X#endif
  1660. X#include "pwauth.h"
  1661. X
  1662. X#ifdef SVR4_SI86_EUA
  1663. X#include <sys/proc.h>
  1664. X#include <sys/sysi86.h>
  1665. X#endif
  1666. X
  1667. X#if !defined(BSD) && !defined(SUN)
  1668. X#define    bzero(a,n)    memset(a, 0, n);
  1669. X#endif
  1670. X
  1671. X#ifdef    USE_SYSLOG
  1672. X#include <syslog.h>
  1673. X
  1674. X#ifndef    LOG_WARN
  1675. X#define    LOG_WARN    LOG_WARNING
  1676. X#endif
  1677. X#endif
  1678. X
  1679. X#ifndef    lint
  1680. Xstatic    char    sccsid[] = "@(#)lmain.c    3.24    08:07:08    19 Jul 1993";
  1681. X#endif
  1682. X
  1683. X                    /* danger - side effects */
  1684. X#define STRFCPY(A,B)    strncpy((A), (B), sizeof(A)), *((A)+sizeof(A)-1) = '\0'
  1685. X
  1686. X#if defined(RLOGIN) || defined(UT_HOST) || defined(SVR4)
  1687. Xchar    host[BUFSIZ];
  1688. Xchar    term[128] = "TERM=";
  1689. Xint    remote_speed = 9600;
  1690. X#endif
  1691. X
  1692. Xstruct    passwd    pwent;
  1693. X#ifdef SVR4
  1694. Xstruct    utmpx    utxent, failent;
  1695. Xstruct    utmp    utent;
  1696. X#else    /*!SVR4 */
  1697. Xstruct    utmp    utent, failent;
  1698. X#endif    /* SVR4 */
  1699. Xstruct    lastlog    lastlog;
  1700. Xint    pflg;
  1701. Xint    rflg;
  1702. Xint    fflg;
  1703. X#ifdef    RLOGIN
  1704. Xint    hflg;
  1705. X#endif
  1706. Xint    preauth_flag;
  1707. X
  1708. X#if defined(SVR4) || defined(SUN4)
  1709. X#define    STTY(fd,termio) tcsetattr (fd, TCSANOW, termio)
  1710. X#define    GTTY(fd,termio) tcgetattr (fd, termio)
  1711. X#define    TERMIO    struct    termios
  1712. X#else
  1713. X#define    STTY(fd,termio) ioctl(fd, TCSETA, termio)
  1714. X#define    GTTY(fd,termio) ioctl(fd, TCGETA, termio)
  1715. X#define    TERMIO    struct    termio
  1716. X#endif    /* SVR4 || SUN4 */
  1717. XTERMIO    termio;
  1718. X
  1719. X#ifndef    MAXENV
  1720. X#define    MAXENV    64
  1721. X#endif
  1722. X
  1723. X/*
  1724. X * Global variables.
  1725. X */
  1726. X
  1727. Xchar    *newenvp[MAXENV];
  1728. Xchar    *Prog;
  1729. Xint    newenvc = 0;
  1730. Xint    maxenv = MAXENV;
  1731. X
  1732. X/*
  1733. X * External identifiers.
  1734. X */
  1735. X
  1736. Xextern    char    *getenv ();
  1737. Xextern    char    *getpass ();
  1738. Xextern    char    *tz ();
  1739. Xextern    void    checkutmp ();
  1740. Xextern    void    addenv ();
  1741. Xextern    void    setenv ();
  1742. Xextern    unsigned alarm ();
  1743. Xextern    void    login ();
  1744. Xextern    void    setutmp ();
  1745. Xextern    void    subsystem ();
  1746. Xextern    void    log ();
  1747. Xextern    void    setup ();
  1748. Xextern    int    expire ();
  1749. Xextern    void    motd ();
  1750. Xextern    void    mailcheck ();
  1751. Xextern    void    shell ();
  1752. Xextern    long    a64l ();
  1753. Xextern    int    c64i ();
  1754. Xextern    char    *getdef_str();
  1755. Xextern    int    getdef_bool();
  1756. Xextern    int    getdef_num();
  1757. Xextern    long    getdef_long();
  1758. Xextern    int    optind;
  1759. Xextern    char    *optarg;
  1760. Xextern    char    **environ;
  1761. Xextern    int    pw_auth();
  1762. X
  1763. X#ifdef HAVE_ULIMIT
  1764. Xextern    long    ulimit();
  1765. X#endif
  1766. X
  1767. X#ifndef    ALARM
  1768. X#define    ALARM    60
  1769. X#endif
  1770. X
  1771. X#ifndef    RETRIES
  1772. X#define    RETRIES    3
  1773. X#endif
  1774. X
  1775. Xstruct    faillog    faillog;
  1776. X
  1777. X#define    NO_SHADOW    "no shadow password for `%s' on `%s'\n"
  1778. X#define    BAD_PASSWD_HOST    "invalid password for `%s' on `%s' from `%s'\n"
  1779. X#define    BAD_PASSWD    "invalid password for `%s' on `%s'\n"
  1780. X#define    BAD_DIALUP    "invalid dialup password for `%s' on `%s'\n"
  1781. X#define    BAD_TIME_HOST    "invalid login time for `%s' on `%s' from `%s'\n"
  1782. X#define    BAD_TIME    "invalid login time for `%s' on `%s'\n"
  1783. X#define    BAD_ROOT_LOGIN    "ILLEGAL ROOT LOGIN ON TTY `%s'\n"
  1784. X#define    ROOT_LOGIN    "ROOT LOGIN ON TTY `%s'\n"
  1785. X#define    FAILURE_CNT    "exceeded failure limit for `%s' on `%s'\n"
  1786. X#define    NOT_A_TTY    "not a tty\n"
  1787. X#define    NOT_ROOT    "-r or -f flag and not ROOT on `%s'\n"
  1788. X#define AUTHFAIL    "authentication failed for user `%s'\n"
  1789. X
  1790. X/*
  1791. X * usage - print login command usage and exit
  1792. X *
  1793. X * login [ name ]
  1794. X * login -r hostname    (for rlogind)
  1795. X * login -h hostname    (for telnetd, etc.)
  1796. X * login -f name    (for pre-authenticated login: datakit, xterm, etc.)
  1797. X */
  1798. X
  1799. Xvoid
  1800. Xusage ()
  1801. X{
  1802. X    fprintf (stderr, "usage: login [ -p ] [ name ]\n");
  1803. X#ifdef    RLOGIN
  1804. X    fprintf (stderr, "       login [ -p ] -r name\n");
  1805. X    fprintf (stderr, "       login [ -p ] [ -f name ] -h host\n");
  1806. X#else
  1807. X    fprintf (stderr, "       login [ -p ] -f name\n");
  1808. X#endif    /* RLOGIN */
  1809. X    exit (1);
  1810. X}
  1811. X
  1812. X#ifdef    RLOGIN
  1813. Xstruct    {
  1814. X    int    spd_name;
  1815. X    int    spd_baud;
  1816. X} speed_table [] = {
  1817. X#ifdef    B50
  1818. X    B50, 50,
  1819. X#endif
  1820. X#ifdef    B75
  1821. X    B75, 75,
  1822. X#endif
  1823. X#ifdef    B110
  1824. X    B110, 110,
  1825. X#endif
  1826. X#ifdef    B134
  1827. X    B134, 134,
  1828. X#endif
  1829. X#ifdef    B150
  1830. X    B150, 150,
  1831. X#endif
  1832. X#ifdef    B200
  1833. X    B200, 200,
  1834. X#endif
  1835. X#ifdef    B300
  1836. X    B300, 300,
  1837. X#endif
  1838. X#ifdef    B600
  1839. X    B600, 600,
  1840. X#endif
  1841. X#ifdef    B1200
  1842. X    B1200, 1200,
  1843. X#endif
  1844. X#ifdef    B1800
  1845. X    B1800, 1800,
  1846. X#endif
  1847. X#ifdef    B2400
  1848. X    B2400, 2400,
  1849. X#endif
  1850. X#ifdef    B4800
  1851. X    B4800, 4800,
  1852. X#endif
  1853. X#ifdef    B9600
  1854. X    B9600, 9600,
  1855. X#endif
  1856. X#ifdef    B19200
  1857. X    B19200, 19200,
  1858. X#endif
  1859. X#ifdef    B38400
  1860. X    B38400, 38400,
  1861. X#endif
  1862. X    -1,    -1
  1863. X};
  1864. X
  1865. Xrlogin (remote_host, name, namelen)
  1866. Xchar    *remote_host;
  1867. Xchar    *name;
  1868. Xint    namelen;
  1869. X{
  1870. X    struct    passwd    *pwd;
  1871. X    char    remote_name[32];
  1872. X    char    *cp;
  1873. X    int    remote_speed = 9600;
  1874. X    int    speed_name = B9600;
  1875. X    int    i;
  1876. X
  1877. X    get_remote_string (remote_name, sizeof remote_name);
  1878. X    get_remote_string (name, namelen);
  1879. X    get_remote_string (term + 5, sizeof term - 5);
  1880. X
  1881. X    if (cp = strchr (term, '/')) {
  1882. X        *cp++ = '\0';
  1883. X
  1884. X        if (! (remote_speed = atoi (cp)))
  1885. X            remote_speed = 9600;
  1886. X    }
  1887. X    for (i = 0;speed_table[i].spd_baud != remote_speed &&
  1888. X                speed_table[i].spd_name != -1;i++)
  1889. X        ;
  1890. X
  1891. X    if (speed_table[i].spd_name != -1)
  1892. X        speed_name = speed_table[i].spd_name;
  1893. X
  1894. X    GTTY (0, &termio);
  1895. X#ifndef    BSD
  1896. X    termio.c_iflag |= ICRNL|IXON;
  1897. X    termio.c_oflag |= OPOST|ONLCR;
  1898. X    termio.c_lflag |= ICANON|ECHO|ECHOE;
  1899. X    termio.c_cflag = (termio.c_cflag & ~CBAUD) | speed_name;
  1900. X#endif
  1901. X    STTY (0, &termio);
  1902. X
  1903. X    if (! (pwd = getpwnam (name)))
  1904. X        return 0;
  1905. X
  1906. X    /*
  1907. X     * ruserok() returns 0 for success on modern systems, and 1 on
  1908. X     * older ones.  If you are having trouble with people logging
  1909. X     * in without giving a required password, THIS is the culprit -
  1910. X     * go fix the #define in config.h.
  1911. X     */
  1912. X
  1913. X#ifndef    RUSEROK
  1914. X    return 0;
  1915. X#else
  1916. X    return ruserok (remote_host, pwd->pw_uid == 0,
  1917. X                remote_name, name) == RUSEROK;
  1918. X#endif
  1919. X}
  1920. X
  1921. Xget_remote_string (buf, size)
  1922. Xchar    *buf;
  1923. Xint    size;
  1924. X{
  1925. X    for (;;) {
  1926. X        if (read (0, buf, 1) != 1)
  1927. X              exit (1);
  1928. X        if (*buf == '\0')
  1929. X            return;
  1930. X        if (--size > 0)
  1931. X            ++buf;
  1932. X    }
  1933. X    /*NOTREACHED*/
  1934. X}
  1935. X#endif
  1936. X
  1937. X/*
  1938. X * login - create a new login session for a user
  1939. X *
  1940. X *    login is typically called by getty as the second step of a
  1941. X *    new user session.  getty is responsible for setting the line
  1942. X *    characteristics to a reasonable set of values and getting
  1943. X *    the name of the user to be logged in.  login may also be
  1944. X *    called to create a new user session on a pty for a variety
  1945. X *    of reasons, such as X servers or network logins.
  1946. X *
  1947. X *    the flags which login supports are
  1948. X *    
  1949. X *    -p - preserve the environment
  1950. X *    -r - perform autologin protocol for rlogin
  1951. X *    -f - do not perform authentication, user is preauthenticated
  1952. X *    -h - the name of the remote host
  1953. X */
  1954. X
  1955. Xint
  1956. Xmain (argc, argv, envp)
  1957. Xint    argc;
  1958. Xchar    **argv;
  1959. Xchar    **envp;
  1960. X{
  1961. X    char    name[32];
  1962. X    char    pass[32];
  1963. X    char    tty[BUFSIZ];
  1964. X    int    reason = PW_LOGIN;
  1965. X    int    retries;
  1966. X    int    failed;
  1967. X    int    flag;
  1968. X    int    subroot = 0;
  1969. X    char    *fname;
  1970. X    char    *cp;
  1971. X    char    *tmp;
  1972. X    char    buff[128];
  1973. X    struct    passwd    *pwd;
  1974. X#ifdef    SHADOWPWD
  1975. X    struct    spwd    *spwd;
  1976. X    struct    spwd    *getspnam();
  1977. X#endif
  1978. X
  1979. X    /*
  1980. X     * Some quick initialization.
  1981. X     */
  1982. X
  1983. X    name[0] = '\0';
  1984. X
  1985. X    /*
  1986. X     * Get the utmp file entry and get the tty name from it.  The
  1987. X     * current process ID must match the process ID in the utmp
  1988. X     * file if there are no additional flags on the command line.
  1989. X     */
  1990. X
  1991. X    checkutmp (argc == 1 || argv[1][0] != '-');
  1992. X    STRFCPY (tty, utent.ut_line);
  1993. X
  1994. X    if (Prog = strrchr (argv[0], '/'))
  1995. X        Prog++;
  1996. X    else
  1997. X        Prog = argv[0];
  1998. X
  1999. X#ifdef    RLOGIN
  2000. X    while ((flag = getopt (argc, argv, "pr:f:h:")) != EOF)
  2001. X#else
  2002. X    while ((flag = getopt (argc, argv, "pf:")) != EOF)
  2003. X#endif
  2004. X    {
  2005. X        switch (flag) {
  2006. X            case 'p': pflg++;
  2007. X                break;
  2008. X            case 'f':
  2009. X                fflg++;
  2010. X                preauth_flag++;
  2011. X                STRFCPY (name, optarg);
  2012. X                break;
  2013. X#ifdef    RLOGIN
  2014. X            case 'r':
  2015. X                rflg++;
  2016. X                reason = PW_RLOGIN;
  2017. X                STRFCPY (host, optarg);
  2018. X#ifdef    UT_HOST
  2019. X                STRFCPY (utent.ut_host, optarg);
  2020. X#endif    /*UT_HOST*/
  2021. X#ifdef    SVR4
  2022. X                STRFCPY (utxent.ut_host, optarg);
  2023. X#endif    /* SVR4 */
  2024. X                if (rlogin (host, name, sizeof name))
  2025. X                    preauth_flag++;
  2026. X
  2027. X                break;
  2028. X            case 'h':
  2029. X                hflg++;
  2030. X                reason = PW_TELNET;
  2031. X                STRFCPY (host, optarg);
  2032. X#ifdef    UT_HOST
  2033. X                STRFCPY (utent.ut_host, optarg);
  2034. X#endif    /*UT_HOST*/
  2035. X#ifdef    SVR4
  2036. X                STRFCPY (utxent.ut_host, optarg);
  2037. X#endif    /* SVR4 */
  2038. X                break;
  2039. X#endif    /*RLOGIN*/
  2040. X            default:
  2041. X                usage ();
  2042. X        }
  2043. X    }
  2044. X
  2045. X#ifdef    RLOGIN
  2046. X    /*
  2047. X     * Neither -h nor -f should be combined with -r.
  2048. X     */
  2049. X
  2050. X    if (rflg && (hflg || fflg))
  2051. X        usage ();
  2052. X#endif
  2053. X
  2054. X    /*
  2055. X     * Allow authentication bypass only if real UID is zero.
  2056. X     */
  2057. X
  2058. X    if ((rflg || fflg) && getuid () != 0) {
  2059. X        fprintf(stderr, "%s: permission denied\n", Prog);
  2060. X        exit (1);
  2061. X    }
  2062. X
  2063. X    if (! isatty (0) || ! isatty (1) || ! isatty (2))
  2064. X        exit (1);        /* must be a terminal */
  2065. X
  2066. X#ifdef    USE_SYSLOG
  2067. X    openlog (Prog, LOG_PID|LOG_CONS|LOG_NOWAIT, LOG_AUTH);
  2068. X#endif
  2069. X
  2070. X#ifndef    BSD
  2071. X    GTTY (0, &termio);        /* get terminal characteristics */
  2072. X
  2073. X    /*
  2074. X     * Add your favorite terminal modes here ...
  2075. X     */
  2076. X
  2077. X    termio.c_lflag |= ISIG;
  2078. X
  2079. X    termio.c_cc[VERASE] = getdef_num("ERASECHAR", '\b');
  2080. X    termio.c_cc[VKILL] = getdef_num("KILLCHAR", '\025');
  2081. X
  2082. X    /*
  2083. X     * ttymon invocation prefers this, but these settings won't come into
  2084. X     * effect after the first username login 
  2085. X     */
  2086. X
  2087. X    STTY (0, &termio);
  2088. X#endif    /* !BSD */
  2089. X    umask (getdef_num("UMASK", 0));
  2090. X#ifdef HAVE_ULIMIT
  2091. X    {
  2092. X        /* 
  2093. X         * Use the ULIMIT in the login.defs file, and if
  2094. X         * there isn't one, use the default value.  The
  2095. X         * user may have one for themselves, but otherwise,
  2096. X         * just take what you get.
  2097. X         */
  2098. X
  2099. X        long limit = getdef_long("ULIMIT", -1L);
  2100. X
  2101. X        if (limit != -1)
  2102. X            ulimit (2, limit);
  2103. X    }
  2104. X#endif
  2105. X
  2106. X    /*
  2107. X     * The entire environment will be preserved if the -p flag
  2108. X     * is used.
  2109. X     */
  2110. X
  2111. X    if (pflg)
  2112. X        while (*envp)        /* add inherited environment, */
  2113. X            addenv (*envp++); /* some variables change later */
  2114. X
  2115. X#ifdef    RLOGIN
  2116. X    if (term[5] != '\0')        /* see if anything after "TERM=" */
  2117. X        addenv (term);
  2118. X#endif
  2119. X    /*
  2120. X     * Add the timezone environmental variable so that time functions
  2121. X     * work correctly.
  2122. X     */
  2123. X
  2124. X    if (tmp = getenv ("TZ")) {
  2125. X        strcat (strcpy (buff, "TZ="), tmp);
  2126. X        addenv (buff);
  2127. X    } else if (cp = getdef_str ("ENV_TZ"))
  2128. X        addenv (*cp == '/' ? tz (cp):cp);
  2129. X
  2130. X    /* 
  2131. X     * Add the clock frequency so that profiling commands work
  2132. X     * correctly.
  2133. X     */
  2134. X
  2135. X    if (tmp = getenv("HZ")) {
  2136. X        strcat (strcpy (buff, "HZ="), tmp);
  2137. X        addenv (buff);
  2138. X    } else if (cp = getdef_str("ENV_HZ"))
  2139. X        addenv (cp);
  2140. X
  2141. X    if (optind < argc) {        /* get the user name */
  2142. X        if (rflg || fflg)
  2143. X            usage ();
  2144. X
  2145. X#ifdef SVR4
  2146. X        /*
  2147. X         * The "-h" option can't be used with a command-line username,
  2148. X         * because telnetd invokes us as: login -h host TERM=...
  2149. X         */
  2150. X
  2151. X        if (! hflg) {
  2152. X            STRFCPY (name, argv[optind]);
  2153. X            ++optind;
  2154. X        }
  2155. X#else
  2156. X        STRFCPY (name, argv[optind]);
  2157. X        ++optind;
  2158. X#endif
  2159. X    }
  2160. X#ifdef SVR4
  2161. X    /*
  2162. X     * check whether ttymon has done the prompt for us already
  2163. X     */
  2164. X
  2165. X    {
  2166. X        char *ttymon_prompt;
  2167. X
  2168. X        if ((ttymon_prompt = getenv("TTYPROMPT")) != NULL &&
  2169. X            (*ttymon_prompt != 0)) {
  2170. X        login(name, 0);    /* read name, without prompt */
  2171. X        }
  2172. X    }
  2173. X#endif /* SVR4 */
  2174. X    if (optind < argc)        /* now set command line variables */
  2175. X            setenv (argc - optind, &argv[optind]);
  2176. X
  2177. Xtop:
  2178. X    (void) alarm (ALARM);        /* only allow ALARM sec. for login */
  2179. X
  2180. X    environ = newenvp;        /* make new environment active */
  2181. X    retries = RETRIES;
  2182. X    while (1) {    /* repeatedly get login/password pairs */
  2183. X        failed = 0;        /* haven't failed authentication yet */
  2184. X        pass[0] = '\0';
  2185. X
  2186. X        if (! name[0]) {    /* need to get a login id */
  2187. X            if (subroot) {
  2188. X#ifdef    USE_SYSLOG
  2189. X                closelog ();
  2190. X#endif
  2191. X                exit (1);
  2192. X            }
  2193. X#ifdef    RLOGIN
  2194. X            preauth_flag = 0;
  2195. X#endif
  2196. X            login (name, "login: ");
  2197. X            continue;
  2198. X        }
  2199. X        if (! (pwd = getpwnam (name))) {
  2200. X            pwent.pw_name = name;
  2201. X            pwent.pw_passwd = "!";
  2202. X            pwent.pw_shell = "/bin/sh";
  2203. X
  2204. X            preauth_flag = 0;
  2205. X            failed = 1;
  2206. X        } else {
  2207. X            pwent = *pwd;
  2208. X        }
  2209. X#ifdef    SHADOWPWD
  2210. X        if (pwd) {
  2211. X            if (! (spwd = getspnam (name)))
  2212. X#ifdef    USE_SYSLOG
  2213. X                syslog (LOG_WARN, NO_SHADOW, name, tty);
  2214. X#else
  2215. X                ;
  2216. X#endif
  2217. X            else
  2218. X                pwent.pw_passwd = spwd->sp_pwdp;
  2219. X        }
  2220. X#endif    /* SHADOWPWD */
  2221. X#ifdef    RLOGIN
  2222. X        /*
  2223. X         * If the encrypted password begins with a "!", the account
  2224. X         * is locked and the user cannot login, even if they have
  2225. X         * been "pre-authenticated."
  2226. X         */
  2227. X
  2228. X        if (pwent.pw_passwd[0] == '!' || pwent.pw_passwd[0] == '*')
  2229. X            failed = 1;
  2230. X
  2231. X        /*
  2232. X         * The -r and -f flags provide a name which has already
  2233. X         * been authenticated by some server.
  2234. X         */
  2235. X
  2236. X        if (preauth_flag)
  2237. X            goto have_name;
  2238. X#endif    /*RLOGIN*/
  2239. X
  2240. X        if (pw_auth (pwent.pw_passwd, name, reason, (char *) 0)) {
  2241. X#ifdef    USE_SYSLOG
  2242. X#ifdef UT_HOST
  2243. X            if (*(utent.ut_host))
  2244. X                syslog (LOG_WARN, BAD_PASSWD_HOST,
  2245. X                    name, tty, utent.ut_host);
  2246. X            else
  2247. X#endif /* UT_HOST */
  2248. X#ifdef SVR4
  2249. X            if (*(utxent.ut_host))
  2250. X                syslog (LOG_WARN, BAD_PASSWD_HOST,
  2251. X                    name, tty, utxent.ut_host);
  2252. X            else
  2253. X#endif /* SVR4 */
  2254. X                syslog (LOG_WARN, BAD_PASSWD,
  2255. X                    name, tty);
  2256. X#endif /* USE_SYSLOG */
  2257. X            failed = 1;
  2258. X        }
  2259. X        goto auth_done;
  2260. X
  2261. X        /*
  2262. X         * This is the point where all authenticated users
  2263. X         * wind up.  If you reach this far, your password has
  2264. X         * been authenticated and so on.
  2265. X         */
  2266. X
  2267. Xauth_done:
  2268. X#ifdef    RLOGIN
  2269. Xhave_name:
  2270. X#endif
  2271. X        if (getdef_bool("DIALUPS_CHECK_ENAB")) {
  2272. X            alarm (30);
  2273. X
  2274. X            if (! dialcheck (tty, pwent.pw_shell[0] ?
  2275. X                    pwent.pw_shell:"/bin/sh")) {
  2276. X#ifdef    USE_SYSLOG
  2277. X                syslog (LOG_WARN, BAD_DIALUP, name, tty);
  2278. X#endif
  2279. X                failed = 1;
  2280. X            }
  2281. X        }
  2282. X        if (getdef_bool("PORTTIME_CHECKS_ENAB") &&
  2283. X            ! isttytime (pwent.pw_name, tty, time ((time_t *) 0))
  2284. X        ) {
  2285. X#ifdef    USE_SYSLOG
  2286. X#ifdef UT_HOST
  2287. X            if (*(utent.ut_host))
  2288. X                syslog (LOG_WARN, BAD_TIME_HOST, name, tty,
  2289. X                    utent.ut_host);
  2290. X            else
  2291. X#endif    /* UT_HOST */
  2292. X#ifdef SVR4
  2293. X            if (*(utxent.ut_host))
  2294. X                syslog (LOG_WARN, BAD_TIME_HOST, name, tty,
  2295. X                    utxent.ut_host);
  2296. X            else
  2297. X#endif    /* SVR4 */
  2298. X                syslog (LOG_WARN, BAD_TIME, name, tty);
  2299. X#endif    /* USE_SYSLOG */
  2300. X                failed = 1;
  2301. X        }
  2302. X        if (! failed && pwent.pw_name && pwent.pw_uid == 0 &&
  2303. X                ! console (tty)) {
  2304. X#ifdef    USE_SYSLOG
  2305. X            syslog (LOG_CRIT, BAD_ROOT_LOGIN, tty);
  2306. X#endif
  2307. X            failed = 1;
  2308. X        }
  2309. X        if (pwd && getdef_bool("FAILLOG_ENAB") && 
  2310. X                ! failcheck (pwent.pw_uid, &faillog, failed)) {
  2311. X#ifdef    USE_SYSLOG
  2312. X            syslog (LOG_CRIT, FAILURE_CNT, name, tty);
  2313. X#endif
  2314. X            failed = 1;
  2315. X        }
  2316. X        if (! failed)
  2317. X            break;
  2318. X
  2319. X        puts ("Login incorrect");
  2320. X#ifdef    RLOGIN
  2321. X        if (rflg || fflg) {
  2322. X#ifdef    USE_SYSLOG
  2323. X            closelog ();
  2324. X#endif
  2325. X            exit (1);
  2326. X        }
  2327. X#endif    /*RLOGIN*/
  2328. X
  2329. X        /* don't log non-existent users */
  2330. X        if (pwd && getdef_bool("FAILLOG_ENAB"))
  2331. X            failure (pwent.pw_uid, tty, &faillog);
  2332. X        if (getdef_str("FTMP_FILE") != NULL) {
  2333. X#ifdef    SVR4
  2334. X            failent = utxent;
  2335. X#else
  2336. X            failent = utent;
  2337. X#endif
  2338. X
  2339. X            if (pwd)
  2340. X                STRFCPY (failent.ut_name, pwent.pw_name);
  2341. X            else
  2342. X                if (getdef_bool("LOG_UNKFAIL_ENAB"))
  2343. X                    STRFCPY (failent.ut_name, name);
  2344. X                else
  2345. X                    STRFCPY (failent.ut_name, "UNKNOWN");
  2346. X#ifdef    SVR4
  2347. X            gettimeofday (&(failent.ut_tv));
  2348. X#else
  2349. X            time (&failent.ut_time);
  2350. X#endif
  2351. X#ifdef    USG_UTMP
  2352. X            failent.ut_type = USER_PROCESS;
  2353. X#endif
  2354. X            failtmp (&failent);
  2355. X        }
  2356. X
  2357. X        if (--retries <= 0) {    /* only allow so many failures */
  2358. X#ifdef    USE_SYSLOG
  2359. X            closelog ();
  2360. X#endif
  2361. X            exit (1);
  2362. X        }
  2363. Xagain:
  2364. X        bzero (name, sizeof name);
  2365. X        bzero (pass, sizeof pass);
  2366. X
  2367. X        /*
  2368. X         * Wait a while (a la SVR4 /usr/bin/login) before attempting
  2369. X         * to login the user again.  If the earlier alarm occurs
  2370. X         * before the sleep() below completes, login will exit.
  2371. X         */
  2372. X
  2373. X        if (getdef_num ("FAIL_DELAY", 0))
  2374. X            sleep (getdef_num ("FAIL_DELAY", 0));
  2375. X    }
  2376. X    (void) alarm (0);        /* turn off alarm clock */
  2377. X
  2378. X    /*
  2379. X     * Check to see if system is turned off for non-root users.
  2380. X     * This would be useful to prevent users from logging in
  2381. X     * during system maintenance.  We make sure the message comes
  2382. X     * out for root so she knows to remove the file if she's
  2383. X     * forgotten about it ...
  2384. X     */
  2385. X
  2386. X    fname = getdef_str("NOLOGINS_FILE");
  2387. X    if (fname != NULL && access (fname, 0) == 0) {
  2388. X        FILE    *nlfp;
  2389. X        int    c;
  2390. X
  2391. X        /*
  2392. X         * Cat the file if it can be opened, otherwise just
  2393. X         * print a default message
  2394. X         */
  2395. X
  2396. X        if (nlfp = fopen (fname, "r")) {
  2397. X            while ((c = getc (nlfp)) != EOF) {
  2398. X                if (c == '\n')
  2399. X                    putchar ('\r');
  2400. X
  2401. X                putchar (c);
  2402. X            }
  2403. X            fflush (stdout);
  2404. X            fclose (nlfp);
  2405. X        } else
  2406. X            printf ("\r\nSystem closed for routine maintenance\r\n");
  2407. X        /*
  2408. X         * Non-root users must exit.  Root gets the message, but
  2409. X         * gets to login.
  2410. X         */
  2411. X
  2412. X        if (pwent.pw_uid != 0) {
  2413. X  
  2414. X#ifdef    USE_SYSLOG
  2415. X            closelog ();
  2416. X#endif
  2417. X            exit (0);
  2418. X        }
  2419. X        printf ("\r\n[Disconnect bypassed -- root login allowed.]\r\n");
  2420. X    }
  2421. X    if (getenv ("IFS"))        /* don't export user IFS ... */
  2422. X        addenv ("IFS= \t\n");    /* ... instead, set a safe IFS */
  2423. X
  2424. X    setutmp (name, tty);        /* make entry in utmp & wtmp files */
  2425. X    if (pwent.pw_shell[0] == '*') {    /* subsystem root */
  2426. X        subsystem (&pwent);    /* figure out what to execute */
  2427. X        subroot++;        /* say i was here again */
  2428. X        endpwent ();        /* close all of the file which were */
  2429. X        endgrent ();        /* open in the original rooted file */
  2430. X#ifdef    SHADOWPWD
  2431. X        endspent ();        /* system.  they will be re-opened */
  2432. X#endif
  2433. X#ifdef    SHADOWGRP
  2434. X        endsgent ();        /* in the new rooted file system */
  2435. X#endif
  2436. X        goto top;        /* go do all this all over again */
  2437. X    }
  2438. X    if (getdef_bool("LASTLOG_ENAB"))
  2439. X        log ();            /* give last login and log this one */
  2440. X
  2441. X#ifdef SVR4_SI86_EUA
  2442. X    sysi86(SI86LIMUSER, EUA_ADD_USER);    /* how do we test for fail? */
  2443. X#endif
  2444. X
  2445. X    setup (&pwent);            /* set UID, GID, HOME, etc ... */
  2446. X#ifdef    AGING
  2447. X#ifdef    SHADOWPWD
  2448. X    if (spwd) {            /* check for age of password */
  2449. X        if (expire (&pwent, spwd)) {
  2450. X            spwd = getspnam (name);
  2451. X            pwd = getpwnam (name);
  2452. X            pwent = *pwd;
  2453. X        }
  2454. X    }
  2455. X#endif
  2456. X#ifdef    ATT_AGE
  2457. X#ifdef    SHADOWPWD
  2458. X    else
  2459. X#endif
  2460. X    if (pwent.pw_age && pwent.pw_age[0]) {
  2461. X        if (expire (&pwent, (void *) 0)) {
  2462. X            pwd = getpwnam (name);
  2463. X            pwent = *pwd;
  2464. X        }
  2465. X    }
  2466. X#endif    /* ATT_AGE */
  2467. X#endif    /* AGING */
  2468. X    if (! hushed (&pwent)) {
  2469. X        motd ();        /* print the message of the day */
  2470. X        if (getdef_bool ("FAILLOG_ENAB") && faillog.fail_cnt != 0)
  2471. X            failprint (&faillog);
  2472. X        if (getdef_bool ("LASTLOG_ENAB") && lastlog.ll_time != 0) {
  2473. X            printf ("Last login: %.19s on %s",
  2474. X                ctime (&lastlog.ll_time), lastlog.ll_line);
  2475. X#ifdef    SVR4
  2476. X            if (lastlog.ll_host[0])
  2477. X                printf(" from %.16s", lastlog.ll_host);
  2478. X#endif
  2479. X            printf("\n");
  2480. X        }
  2481. X#ifdef    AGING
  2482. X#ifdef    SHADOWPWD
  2483. X        agecheck (&pwent, spwd);
  2484. X#else
  2485. X        agecheck (&pwent, (void *) 0);
  2486. X#endif
  2487. X#endif    /* AGING */
  2488. X        mailcheck ();    /* report on the status of mail */
  2489. X    }
  2490. X    if (getdef_str("TTYTYPE_FILE") != NULL && getenv("TERM") == NULL)
  2491. X          ttytype (tty);
  2492. X
  2493. X    signal (SIGINT, SIG_DFL);    /* default interrupt signal */
  2494. X    signal (SIGQUIT, SIG_DFL);    /* default quit signal */
  2495. X    signal (SIGTERM, SIG_DFL);    /* default terminate signal */
  2496. X    signal (SIGALRM, SIG_DFL);    /* default alarm signal */
  2497. X
  2498. X    endpwent ();            /* stop access to password file */
  2499. X    endgrent ();            /* stop access to group file */
  2500. X#ifdef    SHADOWPWD
  2501. X    endspent ();            /* stop access to shadow passwd file */
  2502. X#endif
  2503. X#ifdef    SHADOWGRP
  2504. X    endsgent ();            /* stop access to shadow group file */
  2505. X#endif
  2506. X#ifdef    USE_SYSLOG
  2507. X    if (pwent.pw_uid == 0)
  2508. X        syslog (LOG_NOTICE, ROOT_LOGIN, tty);
  2509. X
  2510. X    closelog ();
  2511. X#endif
  2512. X    shell (pwent.pw_shell, (char *) 0); /* exec the shell finally. */
  2513. X    /*NOTREACHED*/
  2514. X}
  2515. END_OF_FILE
  2516.   if test 19435 -ne `wc -c <'lmain.c'`; then
  2517.     echo shar: \"'lmain.c'\" unpacked with wrong size!
  2518.   fi
  2519.   # end of 'lmain.c'
  2520. fi
  2521. echo shar: End of archive 4 \(of 14\).
  2522. cp /dev/null ark4isdone
  2523. MISSING=""
  2524. for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 ; do
  2525.     if test ! -f ark${I}isdone ; then
  2526.     MISSING="${MISSING} ${I}"
  2527.     fi
  2528. done
  2529. if test "${MISSING}" = "" ; then
  2530.     echo You have unpacked all 14 archives.
  2531.     rm -f ark[1-9]isdone ark[1-9][0-9]isdone
  2532. else
  2533.     echo You still must unpack the following archives:
  2534.     echo "        " ${MISSING}
  2535. fi
  2536. exit 0
  2537. exit 0 # Just in case...
  2538.