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

  1. Newsgroups: comp.sources.misc
  2. From: jfh@rpp386.cactus.org (John F. Haugh II)
  3. Subject: v38i121:  shadow - Shadow Password Suite, v3.3, Part02/14
  4. Message-ID: <1993Aug14.192322.9116@sparky.sterling.com>
  5. X-Md4-Signature: 19fb37d04a5a077914fc5a2ba9b410ea
  6. Sender: kent@sparky.sterling.com (Kent Landfield)
  7. Organization: Sterling Software
  8. Date: Sat, 14 Aug 1993 19:23:22 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 121
  13. Archive-name: shadow/part02
  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 groupmod.1 usermod.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 2 (of 14)."'
  26. if test -f 'Makefile' -a "${1}" != "-c" ; then 
  27.   echo shar: Will not clobber existing file \"'Makefile'\"
  28. else
  29.   echo shar: Extracting \"'Makefile'\" \(20253 characters\)
  30.   sed "s/^X//" >'Makefile' <<'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    3.25.1.18    09:57:59  - Shadow password system
  45. X#
  46. X#    @(#)Makefile    3.25.1.18    09:57:59    08 Aug 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.  It is now unsupported.
  54. X# The version with database-like file access is release 3.
  55. XRELEASE = 3
  56. XVERSION = ver3.3.0
  57. XGFLAGS = -n $(VERSION)
  58. XGET = get_file
  59. X
  60. X# Define the directory login is copied to.  BE VERY CAREFUL!!!  BSD old SunOS
  61. X# seems to use /bin, USG seems to use /etc, SunOS 4.1.1 seems to use /usr/bin.
  62. X# If you define SCOLOGIN, you MUST use /etc as LOGINDIR.
  63. X# LOGINDIR = /bin
  64. XLOGINDIR = /etc
  65. X# LOGINDIR = /usr/bin
  66. X
  67. X# Define any special libraries required to access the directory routines.
  68. X# Some systems require -lndir for the directory routines.  SCO Xenix uses
  69. X# -lx for that.  Your system might need nothing.
  70. X# NDIR = -lndir
  71. XNDIR = -lx
  72. X# NDIR =
  73. X
  74. X# Define some stuff for Cracklib.  This assumes that libcracklib.a is
  75. X# in a system directory.
  76. X# CRACKDEF='-DCRACKLIB_DICTPATH="$(DICTPATH)"'
  77. X# CRACKLIB=-lcrack
  78. X
  79. X# Pick your favorite C compiler and tags command
  80. XCC = cc
  81. XTAGS = ctags
  82. X
  83. X# OS.  Pick one of USG (AT&T, SYSV, SYS3), BSD, SUN (SunOS 2 and 3),
  84. X# SUN4 (SunOS 4.1.1.), or UNIXPC (AT&T PC/7300, 3B1)
  85. X# OS = -DUSG -DSYS3
  86. XOS = -DUSG
  87. X# OS = -DBSD
  88. X# OS = -DSUN
  89. X# OS = -DSUN4
  90. X# OS = -DUSG -DUNIXPC
  91. X
  92. X# Do you have to do ranlib (probably SUN, BSD and XENIX)?
  93. XRANLIB = ranlib
  94. X# RANLIB = echo
  95. X
  96. X# Enable the following if you are running SCO TCP/IP.  It is a /bin/login
  97. X# which understands the *ahem* novel way they do rlogin/telnet.
  98. X# SCOLOGIN = scologin
  99. X
  100. X# Configuration Flags
  101. X#
  102. X#    DEST_INCLUDE_DIR - local include files
  103. X#    LIBS - system libraries
  104. X#        -lsocket - needed for TCP/IP and possibly SYSLOG
  105. X#        -ldbm or -lndbm - needed for DBM support
  106. X#        -lcrypt - needed for SCO crypt() functions
  107. X#    CFLAGS - C compiler flags
  108. X#        -DLAI_TCP - needed for SCO Xenix Lachman TCP/IP
  109. X
  110. XDEST_INCLUDE_DIR = /usr/include
  111. X
  112. X# Flags for SCO Xenix/386
  113. XCFLAGS = -O -M3 -g $(OS) -I$(DEST_INCLUDE_DIR) $(CRACKDEF)
  114. XLIBS = -lcrypt -lndbm
  115. X# LIBS = -lcrypt -ldbm
  116. XLDFLAGS = -M3 -g
  117. XLTFLAGS = 
  118. X
  119. X# Flags for normal machines
  120. X# CFLAGS = -O -g $(OS) -I$(DEST_INCLUDE_DIR) $(CRACKDEF)
  121. X# LIBS =
  122. X# LDFLAGS = -g
  123. X
  124. X# Flags for SunOS 4.1.1
  125. X# CFLAGS = -O2 $(OS) -I$(DEST_INCLUDE_DIR) $(CRACKDEF)
  126. X# LIBS =
  127. X# LDFLAGS = 
  128. X
  129. X# This should be Slibsec.a for small model, or Llibsec.a for
  130. X# large model or whatever.  MUST AGREE WITH CFLAGS!!!  For non-Intel
  131. X# machines, just use libsec.a
  132. XLIBSEC = Slibsec.a
  133. X# LIBSEC = libsec.a
  134. X
  135. X# Names for root user and group, and bin user and group.  See your
  136. X# /etc/passwd and /etc/group files.  BSD and SUN use "wheel", most
  137. X# others use "root" for RGID.
  138. XRUID = root
  139. XRGID = root
  140. X# RGID = wheel
  141. XBUID = bin
  142. XBGID = bin
  143. X
  144. X# Where the login.defs file will be copied.  Must agree with config.h
  145. XDEST_LOGIN_DEFS = /etc/login.defs
  146. X
  147. X# Rules for .L (lint) files.
  148. X.SUFFIXES: .L
  149. XLINT = lint
  150. XLINTFLAGS = $(OS) -Dlint
  151. X
  152. X.c.L:
  153. X    $(LINT) -pxu $(LINTFLAGS) $*.c > $*.L
  154. X
  155. XLOBJS = lmain.o login.o env.o valid.o setup.o shell.o age.o \
  156. X    utmp.o sub.o mail.o motd.o log.o ttytype.o failure.o \
  157. X    tz.o console.o hushed.o
  158. X
  159. XLSRCS = lmain.c login.c env.c valid.c setup.c shell.c age.c \
  160. X    utmp.c sub.c mail.c motd.c log.c ttytype.c failure.c \
  161. X    tz.c console.c hushed.c
  162. X
  163. XSOBJS = smain.o env.o entry.o susetup.o shell.o \
  164. X    sub.o mail.o motd.o sulog.o age.o tz.o hushed.o
  165. X
  166. XSSRCS = smain.c env.c entry.c setup.c shell.c \
  167. X    pwent.c sub.c mail.c motd.c sulog.c shadow.c age.c pwpack.c rad64.c \
  168. X    tz.c hushed.c
  169. X
  170. XPOBJS = passwd.o obscure.o
  171. XPSRCS = passwd.c obscure.c
  172. X
  173. XGPSRCS = gpmain.c
  174. X
  175. XGPOBJS = gpmain.o
  176. X
  177. XPWOBJS = pwconv.o
  178. X
  179. XPWSRCS = pwconv.c pwent.c shadow.c pwpack.c rad64.c
  180. X
  181. XPWUNOBJS = pwunconv.o
  182. X
  183. XPWUNSRCS = pwunconv.c pwent.c shadow.c pwpack.c rad64.c
  184. X
  185. XSULOGOBJS = sulogin.o entry.o env.o age.o setup.o \
  186. X    valid.o shell.o tz.o
  187. X
  188. XSULOGSRCS = sulogin.c entry.c env.c age.c pwent.c setup.c \
  189. X    shadow.c shell.c valid.c pwpack.c tz.c
  190. X
  191. XMKPWDOBJS = mkpasswd.o
  192. X
  193. XMKPWDSRCS = mkpasswd.c
  194. X
  195. XNGSRCS = newgrp.c env.c shell.c
  196. X
  197. XNGOBJS = newgrp.o env.o shell.o
  198. X
  199. XCHFNSRCS = chfn.c fields.c
  200. XCHFNOBJS = chfn.o fields.o
  201. XCHSHSRCS = chsh.c fields.c
  202. XCHSHOBJS = chsh.o fields.o
  203. XCHAGEOBJS = chage.o fields.o
  204. XCHAGESRCS = chage.c fields.c
  205. XCHPASSOBJS = chpasswd.o
  206. XCHPASSSRCS = chpasswd.c
  207. XDPSRCS = dpmain.c
  208. XDPOBJS = dpmain.o
  209. X
  210. XALLSRCS = age.c dialchk.c dialup.c entry.c env.c lmain.c log.c login.c mail.c \
  211. X    motd.c obscure.c passwd.c pwconv.c pwent.c pwunconv.c getpass.c \
  212. X    setup.c shadow.c shell.c smain.c sub.c sulog.c sulogin.c ttytype.c \
  213. X    utmp.c valid.c port.c newgrp.c gpmain.c grent.c mkpasswd.c pwpack.c \
  214. X    chfn.c chsh.c chage.c rad64.c encrypt.c chpasswd.c shadowio.c pwio.c \
  215. X    newusers.c groupio.c fields.c pwdbm.c grpack.c grdbm.c sppack.c \
  216. X    spdbm.c dpmain.c gshadow.c gsdbm.c gspack.c sgroupio.c useradd.c \
  217. X    userdel.c patchlevel.h usermod.c copydir.c mkrmdir.c groupadd.c \
  218. X    groupdel.c groupmod.c tz.c console.c hushed.c getdef.c scologin.c \
  219. X    logoutd.c groups.c pwauth.c lockpw.c chowndir.c
  220. X
  221. XFILES1 = README patchlevel.h newgrp.c Makefile config.h pwunconv.c obscure.c \
  222. X    age.c id.c
  223. X
  224. XFILES2 = passwd.c port.c lmain.c sulogin.c pwpack.c dialup.c
  225. X
  226. XFILES3 = chfn.c chsh.c smain.c faillog.c pwconv.c shadow.c pwck.c
  227. X
  228. XFILES4 = gpmain.c chage.c pwent.c valid.c setup.c entry.c ttytype.c port.h
  229. X
  230. XFILES5 = pwio.c encrypt.c chpasswd.c newusers.c rad64.c dialchk.c faillog.h \
  231. X    pwdbm.c grdbm.c gshadow.c sppack.c grpck.c
  232. X
  233. XFILES6 = gspack.c spdbm.c lastlog.h shell.c login.c sub.c dpmain.c mail.c \
  234. X    env.c pwd.h.m4 grpack.c shadow.h log.c grent.c motd.c dialup.h \
  235. X    fields.c gsdbm.c utmp.c failure.c
  236. X
  237. XFILES7 = groupio.c shadowio.c sgroupio.c groups.c copydir.c mkrmdir.c \
  238. X    mkpasswd.c pwauth.c pwauth.h lastlog.c
  239. X
  240. XFILES8 = useradd.c usermod.c login.defs
  241. X
  242. XFILES9 = groupadd.c groupdel.c groupmod.c tz.c console.c hushed.c getdef.c \
  243. X    scologin.c logoutd.c sulog.c getpass.c userdel.c lockpw.c chowndir.c
  244. X
  245. XFILES_SUN4 = Makefile.sun4 README.sun4 config.h.sun4
  246. XFILES_SVR4 = Makefile.svr4 config.h.svr4
  247. X
  248. XMAN_1 = chage.1 chfn.1 chsh.1 id.1 login.1 newgrp.1 passwd.1 su.1 \
  249. X    useradd.1 userdel.1 usermod.1 groupadd.1 groupdel.1 groupmod.1 \
  250. X    groups.1 pwck.1 grpck.1
  251. XMAN_3 = shadow.3 pwauth.3
  252. XMAN_4 = faillog.4 passwd.4 porttime.4 shadow.4
  253. XMAN_5 = login.5
  254. XMAN_8 = chpasswd.8 dpasswd.8 faillog.8 newusers.8 pwconv.8 pwunconv.8 \
  255. X    sulogin.8 mkpasswd.8 logoutd.8 pwauth.8 lastlog.8
  256. X
  257. XDOCS1 = $(MAN_1) $(MAN_3) $(MAN_4)
  258. XDOCS2 = $(MAN_5) $(MAN_8)
  259. XDOCS = $(DOCS1) $(DOCS2)
  260. X
  261. XBINS = su login pwconv pwunconv passwd sulogin faillog newgrp sg gpasswd \
  262. X    mkpasswd chfn chsh chage chpasswd newusers dpasswd id useradd \
  263. X    userdel usermod groupadd groupdel groupmod $(SCOLOGIN) logoutd \
  264. X    groups pwck grpck lastlog
  265. X
  266. Xall:    $(BINS) $(DOCS)
  267. X
  268. X.PRECIOUS: libshadow.a
  269. X
  270. Xlibshadow.a: \
  271. X    libshadow.a(dialchk.o) \
  272. X    libshadow.a(dialup.o) \
  273. X    libshadow.a(encrypt.o) \
  274. X    libshadow.a(getdef.o) \
  275. X    libshadow.a(getpass.o) \
  276. X    libshadow.a(grdbm.o) \
  277. X    libshadow.a(grent.o) \
  278. X    libshadow.a(groupio.o) \
  279. X    libshadow.a(grpack.o) \
  280. X    libshadow.a(gshadow.o) \
  281. X    libshadow.a(gsdbm.o) \
  282. X    libshadow.a(gspack.o) \
  283. X    libshadow.a(sgroupio.o) \
  284. X    libshadow.a(port.o) \
  285. X    libshadow.a(pwdbm.o) \
  286. X    libshadow.a(pwent.o) \
  287. X    libshadow.a(pwio.o) \
  288. X    libshadow.a(pwpack.o) \
  289. X    libshadow.a(pwauth.o) \
  290. X    libshadow.a(rad64.o) \
  291. X    libshadow.a(spdbm.o) \
  292. X    libshadow.a(shadow.o) \
  293. X    libshadow.a(shadowio.o) \
  294. X    libshadow.a(sppack.o) \
  295. X    libshadow.a(lockpw.o)
  296. X    $(RANLIB) libshadow.a
  297. X
  298. Xlibsec: $(LIBSEC)(shadow.o)
  299. X    $(RANLIB) $(LIBSEC)
  300. X
  301. Xsave:
  302. X    [ ! -d save ] && mkdir save
  303. X    -cp $(LOGINDIR)/login save
  304. X    -cp /etc/mkpasswd /etc/pwconv /etc/pwunconv /etc/sulogin /etc/chpasswd \
  305. X        /etc/newusers /etc/useradd /etc/userdel /etc/usermod \
  306. X        /etc/groupadd /etc/groupdel /etc/groupmod /etc/logoutd \
  307. X        /etc/login.defs /etc/pwck /etc/grpck save
  308. X    -cp /bin/su /bin/passwd /bin/gpasswd /bin/dpasswd /bin/faillog \
  309. X        /bin/newgrp /bin/chfn /bin/chsh /bin/chage /bin/id \
  310. X        /bin/scologin save
  311. X    -cp $(DEST_INCLUDE_DIR)/dialup.h $(DEST_INCLUDE_DIR)/shadow.h \
  312. X        $(DEST_INCLUDE_DIR)/pwd.h save
  313. X
  314. Xrestore:
  315. X    [ -d save ]
  316. X    -(cd save ; cp login $(LOGINDIR) )
  317. X    -(cd save ; -cp mkpasswd pwconv pwunconv sulogin chpasswd \
  318. X        newusers useradd userdel usermod groupadd groupdel groupmod \
  319. X        logoutd login.defs pwck grpck /etc)
  320. X    -(cd save ; cp su passwd gpasswd dpasswd faillog newgrp chfn chsh \
  321. X        chage id scologin /bin)
  322. X    -(cd save ; cp dialup.h shadow.h pwd.h $(DEST_INCLUDE_DIR) )
  323. X
  324. Xinstall: all
  325. X    strip $(BINS)
  326. X    cp login $(LOGINDIR)/login
  327. X    cp mkpasswd pwconv pwunconv sulogin chpasswd newusers \
  328. X        useradd userdel usermod groupadd groupdel groupmod logoutd \
  329. X        pwck grpck /etc
  330. X    cp su passwd gpasswd dpasswd faillog newgrp chfn chsh chage id /bin
  331. X    rm -f /bin/sg
  332. X    ln /bin/newgrp /bin/sg
  333. X    cp dialup.h shadow.h pwd.h $(DEST_INCLUDE_DIR)
  334. X    chown $(RUID) $(LOGINDIR)/login /etc/pwconv /etc/pwunconv /etc/sulogin \
  335. X        /bin/su /bin/passwd /bin/gpasswd /bin/newgrp /etc/mkpasswd \
  336. X        /bin/dpasswd /bin/chsh /bin/chfn /bin/chage /etc/useradd \
  337. X        /etc/userdel /etc/usermod /etc/groupadd /etc/groupdel \
  338. X        /etc/groupmod /etc/logoutd /etc/pwck /etc/grpck
  339. X    chgrp $(RGID) $(LOGINDIR)/login /etc/pwconv /etc/pwunconv /etc/sulogin \
  340. X        /bin/su /bin/passwd /bin/gpasswd /bin/newgrp /etc/mkpasswd \
  341. X        /bin/dpasswd /bin/chsh /bin/chfn /bin/chage /etc/useradd \
  342. X        /etc/userdel /etc/usermod /etc/groupadd /etc/groupdel \
  343. X        /etc/groupmod /etc/logoutd /etc/pwck /etc/grpck
  344. X    chown $(BUID) /bin/faillog /bin/id $(DEST_INCLUDE_DIR)/shadow.h \
  345. X        $(DEST_INCLUDE_DIR)/dialup.h $(DEST_INCLUDE_DIR)/pwd.h
  346. X    chgrp $(BGID) /bin/faillog /bin/id $(DEST_INCLUDE_DIR)/shadow.h \
  347. X        $(DEST_INCLUDE_DIR)/dialup.h $(DEST_INCLUDE_DIR)/pwd.h
  348. X    chmod 700 /etc/pwconv /etc/pwunconv /etc/sulogin /etc/mkpasswd \
  349. X        /etc/chpasswd /etc/newusers /bin/dpasswd /etc/logoutd \
  350. X        /etc/useradd /etc/userdel /etc/usermod /etc/groupadd \
  351. X        /etc/groupdel /etc/groupmod /etc/pwck /etc/grpck
  352. X    chmod 4711 $(LOGINDIR)/login /bin/su /bin/passwd /bin/gpasswd \
  353. X        /bin/newgrp /bin/chfn /bin/chsh /bin/chage
  354. X    chmod 711 /bin/faillog /bin/id
  355. X    chmod 444 $(DEST_INCLUDE_DIR)/shadow.h $(DEST_INCLUDE_DIR)/dialup.h \
  356. X        $(DEST_INCLUDE_DIR)/pwd.h
  357. X    [ -f $(DEST_LOGIN_DEFS) ] || (cp login.defs $(DEST_LOGIN_DEFS) ; \
  358. X        chown $(RUID) $(DEST_LOGIN_DEFS) ; \
  359. X        chgrp $(RGID) $(DEST_LOGIN_DEFS) ; \
  360. X        chmod 600 $(DEST_LOGIN_DEFS) )
  361. X    [ -z "$(SCOLOGIN)" ] || (cp scologin /bin/login ; \
  362. X        chown $(RUID) /bin/login ; \
  363. X        chgrp $(RGID) /bin/login ; \
  364. X        chmod 755 /bin/login )
  365. X
  366. Xlint:    su.lint login.lint pwconv.lint pwunconv.lint passwd.lint sulogin.lint \
  367. X    faillog.lint newgrp.lint gpasswd.lint mkpasswd.lint chfn.lint \
  368. X    chsh.lint chage.lint dpasswd.lint id.lint useradd.lint userdel.lint \
  369. X    usermod.lint groupadd.lint groupdel.lint groupmod.lint logoutd.lint \
  370. X    pwck.lint grpck.lint \
  371. X    $(ALLSRCS:.c=.L)
  372. X
  373. Xtags:    $(ALLSRCS)
  374. X    $(TAGS) $(ALLSRCS)
  375. X
  376. XREADME:
  377. X    [ -f s.README ] && $(GET) $(GFLAGS) s.README
  378. X    
  379. X$(DOCS):
  380. X    [ -f s.$@ ] && $(GET) $(GFLAGS) s.$@
  381. X
  382. Xlogin.defs:
  383. X    [ -f s.login.defs ] && $(GET) $(GFLAGS) s.login.defs
  384. X
  385. XMakefile.sun4:
  386. X    [ -f s.Makefile.sun4 ] && $(GET) $(GFLAGS) s.Makefile.sun4
  387. X
  388. XMakefile.svr4:
  389. X    [ -f s.Makefile.svr4 ] && $(GET) $(GFLAGS) s.Makefile.svr4
  390. X
  391. XREADME.sun4:
  392. X    [ -f s.README.sun4 ] && $(GET) $(GFLAGS) s.README.sun4
  393. X
  394. Xconfig.h.sun4:
  395. X    [ -f s.config.h.sun4 ] && $(GET) $(GFLAGS) s.config.h.sun4
  396. X
  397. Xconfig.h.svr4:
  398. X    [ -f s.config.h.svr4 ] && $(GET) $(GFLAGS) s.config.h.svr4
  399. X
  400. Xlogin:    $(LOBJS) libshadow.a
  401. X    $(CC) -o login $(LDFLAGS) $(LOBJS) libshadow.a $(LIBS)
  402. X
  403. Xlogin.lint: $(LSRCS)
  404. X    $(LINT) $(LINTFLAGS) $(LSRCS) > login.lint
  405. X
  406. Xsu:    $(SOBJS) libshadow.a
  407. X    $(CC) -o su $(LDFLAGS) $(SOBJS) libshadow.a $(LIBS)
  408. X
  409. Xsu.lint:    $(SSRCS)
  410. X    $(LINT) $(LINTFLAGS) -DSU $(SSRCS) > su.lint
  411. X
  412. Xpasswd:    $(POBJS) libshadow.a
  413. X    $(CC) -o passwd $(LDFLAGS) $(POBJS) libshadow.a $(LIBS) $(CRACKLIB)
  414. X
  415. Xpasswd.lint: $(PSRCS)
  416. X    $(LINT) $(LINTFLAGS) -DPASSWD $(PSRCS) > passwd.lint
  417. X
  418. Xgpasswd: $(GPOBJS) libshadow.a
  419. X    $(CC) -o gpasswd $(LDFLAGS) $(GPOBJS) libshadow.a $(LIBS)
  420. X
  421. Xgpasswd.lint: $(GPSRCS)
  422. X    $(LINT) $(LINTFLAGS) $(GPSRCS) > gpasswd.lint
  423. X
  424. Xdpasswd: $(DPOBJS) libshadow.a
  425. X    $(CC) -o dpasswd $(LDFLAGS) $(DPOBJS) libshadow.a $(LIBS)
  426. X
  427. Xdpasswd.lint: $(DPSRCS)
  428. X    $(LINT) $(LINTFLAGS) $(DPSRCS) > dpasswd.lint
  429. X
  430. Xpwconv:    $(PWOBJS) libshadow.a config.h
  431. X    $(CC) -o pwconv $(LDFLAGS) $(PWOBJS) libshadow.a $(LIBS)
  432. X
  433. Xpwconv.lint: $(PWSRCS) config.h
  434. X    $(LINT) $(LINTFLAGS) -DPASSWD $(PWSRCS) > pwconv.lint
  435. X
  436. Xpwunconv: $(PWUNOBJS) libshadow.a config.h
  437. X    $(CC) -o pwunconv $(LDFLAGS) $(PWUNOBJS) libshadow.a $(LIBS)
  438. X
  439. Xpwunconv.lint: $(PWUNSRCS)
  440. X    $(LINT) $(LINTFLAGS) -DPASSWD $(PWUNSRCS) > pwunconv.lint
  441. X
  442. Xsulogin: $(SULOGOBJS) libshadow.a
  443. X    $(CC) -o sulogin $(LDFLAGS) $(SULOGOBJS) libshadow.a $(LIBS)
  444. X
  445. Xsulogin.lint: $(SULOGSRCS)
  446. X    $(LINT) $(LINTFLAGS) $(SULOGSRCS) > sulogin.lint
  447. X
  448. Xfaillog: faillog.o
  449. X    $(CC) -o faillog $(LDFLAGS) faillog.o $(LIBS)
  450. X
  451. Xfaillog.lint: faillog.c faillog.h config.h
  452. X    $(LINT) $(LINTFLAGS) faillog.c > faillog.lint
  453. X
  454. Xlastlog: lastlog.o
  455. X    $(CC) -o lastlog $(LDFLAGS) lastlog.o $(LIBS)
  456. X
  457. Xlastlog.lint: lastlog.c config.h lastlog.h
  458. X    $(LINT) $(LINTFLAGS) $(MKPWDSRCS) > lastlog.lint
  459. X
  460. Xmkpasswd: $(MKPWDOBJS) libshadow.a
  461. X    $(CC) -o mkpasswd $(LDFLAGS) $(MKPWDOBJS) libshadow.a $(LIBS)
  462. X
  463. Xmkpasswd.lint: $(MKPWDSRCS)
  464. X    $(LINT) $(LINTFLAGS) $(MKPWDSRCS) > mkpasswd.lint
  465. X
  466. Xnewgrp: $(NGOBJS) libshadow.a
  467. X    $(CC) -o newgrp $(LDFLAGS) $(NGOBJS) libshadow.a $(LIBS)
  468. X
  469. Xnewgrp.lint: $(NGSRCS)
  470. X    $(LINT) $(LINTFLAGS) $(NGSRCS) > newgrp.lint
  471. X
  472. Xsg:    newgrp
  473. X    rm -f sg
  474. X    ln newgrp sg
  475. X
  476. Xsg.lint: newgrp.lint
  477. X    ln newgrp.lint sg.lint
  478. X
  479. Xchfn:    $(CHFNOBJS) libshadow.a
  480. X    $(CC) -o chfn $(LDFLAGS) $(CHFNOBJS) libshadow.a $(LIBS)
  481. X
  482. Xchfn.lint:    $(CHFNSRCS)
  483. X    $(LINT) $(LINTFLAGS) $(CHFNSRCS) > chfn.lint
  484. X
  485. Xchsh:    $(CHSHOBJS) libshadow.a
  486. X    $(CC) -o chsh $(LDFLAGS) $(CHSHOBJS) libshadow.a $(LIBS)
  487. X
  488. Xchsh.lint: $(CHSHSRCS)
  489. X    $(LINT) $(LINTFLAGS) $(CHSHSRCS) > chsh.lint
  490. X
  491. Xchage:    $(CHAGEOBJS) libshadow.a
  492. X    $(CC) -o chage $(LDFLAGS) $(CHAGEOBJS) libshadow.a $(LIBS)
  493. X
  494. Xchage.lint: $(CHAGESRCS)
  495. X    $(LINT) $(LINTFLAGS) -DPASSWD $(CHAGESRCS) > chage.lint
  496. X
  497. Xchpasswd: $(CHPASSOBJS) libshadow.a
  498. X    $(CC) -o chpasswd $(LDFLAGS) $(CHPASSOBJS) libshadow.a $(LIBS)
  499. X
  500. Xchpasswd.lint: $(CHPASSSRCS)
  501. X    $(LINT) $(LINTFLAGS) $(CHPASSSRCS) > chpasswd.lint
  502. X
  503. Xnewusers: newusers.o libshadow.a
  504. X    $(CC) -o newusers $(LDFLAGS) newusers.o libshadow.a $(LIBS)
  505. X
  506. Xnewusers.lint: newusers.c
  507. X    $(LINT) $(LINTFLAGS) newusers.c > newusers.lint
  508. X    
  509. Xid: id.o libshadow.a
  510. X    $(CC) -o id $(LDFLAGS) id.o libshadow.a $(LIBS)
  511. X
  512. Xid.lint: id.c
  513. X    $(LINT) $(LINTFLAGS) id.c > id.lint
  514. X
  515. Xgroups: groups.o libshadow.a
  516. X    $(CC) -o groups $(LDFLAGS) groups.o libshadow.a $(LIBS)
  517. X
  518. Xgroups.lint: groups.c
  519. X    $(LINT) $(LINTFLAGS) groups.c > groups.lint
  520. X
  521. Xuseradd: useradd.o copydir.o mkrmdir.o libshadow.a
  522. X    $(CC) -o useradd $(LDFLAGS) useradd.o copydir.o mkrmdir.o \
  523. X        libshadow.a $(LIBS) $(NDIR)
  524. X
  525. Xuseradd.lint: useradd.c copydir.c mkrmdir.c
  526. X    $(LINT) $(LINTFLAGS) useradd.c copydir.c mkrmdir.c > useradd.lint
  527. X
  528. Xuserdel: userdel.o copydir.o mkrmdir.o libshadow.a
  529. X    $(CC) -o userdel $(LDFLAGS) userdel.o copydir.o mkrmdir.o \
  530. X        libshadow.a $(LIBS) $(NDIR)
  531. X
  532. Xuserdel.lint: userdel.c copydir.c mkrmdir.c
  533. X    $(LINT) $(LINTFLAGS) userdel.c copydir.c mkrmdir.c > userdel.lint
  534. X
  535. Xusermod: usermod.o copydir.o mkrmdir.o chowndir.o libshadow.a
  536. X    $(CC) -o usermod $(LDFLAGS) usermod.o copydir.o mkrmdir.o \
  537. X        chowndir.o libshadow.a $(LIBS) $(NDIR)
  538. X
  539. Xusermod.lint: usermod.c copydir.c mkrmdir.c chowndir.c
  540. X    $(LINT) $(LINTFLAGS) usermod.c copydir.c mkrmdir.c \
  541. X        chowndir.c > usermod.lint
  542. X
  543. Xgroupadd: groupadd.o libshadow.a
  544. X    $(CC) -o groupadd $(LDFLAGS) groupadd.o libshadow.a $(LIBS)
  545. X
  546. Xgroupadd.lint: groupadd.c
  547. X    $(LINT) $(LINTFLAGS) groupadd.c > groupadd.lint
  548. X
  549. Xgroupdel: groupdel.o libshadow.a
  550. X    $(CC) -o groupdel $(LDFLAGS) groupdel.o libshadow.a $(LIBS)
  551. X
  552. Xgroupdel.lint: groupdel.c
  553. X    $(LINT) $(LINTFLAGS) groupdel.c > groupdel.lint
  554. X
  555. Xgroupmod: groupmod.o libshadow.a
  556. X    $(CC) -o groupmod $(LDFLAGS) groupmod.o libshadow.a $(LIBS)
  557. X
  558. Xgroupmod.lint: groupmod.c
  559. X    $(LINT) $(LINTFLAGS) groupmod.c > groupmod.lint
  560. X
  561. Xpwd.h.m4:
  562. X    [ -f s.pwd.h.m4 ] && $(GET) $(GFLAGS) s.pwd.h.m4
  563. X
  564. Xpwd.h: pwd.h.m4
  565. X    m4 $(OS) < pwd.h.m4 > pwd.h
  566. X
  567. Xlogoutd: logoutd.o libshadow.a
  568. X    $(CC) -o logoutd $(LDFLAGS) logoutd.o libshadow.a
  569. X
  570. Xlogoutd.lint: logoutd.c
  571. X    $(LINT) $(LINTFLAGS) logoutd.c > logoutd.lint
  572. X
  573. Xpwck: pwck.o libshadow.a
  574. X    $(CC) -o pwck $(LDFLAGS) pwck.o libshadow.a $(LIBS)
  575. X
  576. Xpwck.lint: pwck.c
  577. X    $(LINT) $(LINTFLAGS) pwck.c > pwck.lint
  578. X
  579. Xgrpck: grpck.o libshadow.a
  580. X    $(CC) -o grpck $(LDFLAGS) grpck.o libshadow.a $(LIBS)
  581. X
  582. Xgrpck.lint: grpck.c
  583. X    $(LINT) $(LINTFLAGS) grpck.c > grpck.lint
  584. X
  585. Xsulog.o: config.h
  586. X
  587. Xsusetup.c: setup.c
  588. X    cp setup.c susetup.c
  589. X
  590. Xsusetup.o: config.h susetup.c pwd.h
  591. X    $(CC) -c $(CFLAGS) -DSU susetup.c
  592. X
  593. Xscologin: scologin.o
  594. X    $(CC) -o scologin $(LDFLAGS) scologin.o -lsocket
  595. X
  596. Xpasswd.o: config.h shadow.h pwd.h pwauth.h
  597. Xlmain.o: config.h lastlog.h faillog.h pwd.h pwauth.h
  598. Xsmain.o: config.h lastlog.h pwd.h shadow.h pwauth.h
  599. Xsub.o: pwd.h
  600. Xsetup.o: config.h pwd.h
  601. Xmkrmdir.o: config.h
  602. Xutmp.o: config.h
  603. Xmail.o: config.h
  604. Xmotd.o: config.h
  605. Xage.o: config.h pwd.h
  606. Xlog.o: config.h lastlog.h pwd.h
  607. Xshell.o: config.h
  608. Xentry.o: config.h shadow.h pwd.h
  609. Xhushed.o: config.h pwd.h
  610. Xvalid.o: config.h pwd.h
  611. Xfailure.o: faillog.h config.h
  612. Xfaillog.o: faillog.h config.h pwd.h
  613. Xnewgrp.o: config.h shadow.h pwd.h
  614. Xmkpasswd.o: config.h shadow.h pwd.h
  615. Xgpmain.o: config.h pwd.h
  616. Xchfn.o: config.h pwd.h
  617. Xchsh.o: config.h pwd.h
  618. Xchage.o: config.h shadow.h pwd.h
  619. Xpwconv.o: config.h shadow.h
  620. Xpwunconv.o: config.h shadow.h pwd.h
  621. Xchpasswd.o: config.h shadow.h pwd.h
  622. Xid.o: pwd.h
  623. Xnewusers.o: config.h shadow.h pwd.h
  624. Xdpmain.o: config.h dialup.h
  625. Xuseradd.o: config.h shadow.h pwd.h pwauth.h
  626. Xuserdel.o: config.h shadow.h pwd.h pwauth.h
  627. Xusermod.o: config.h shadow.h pwd.h pwauth.h
  628. Xgroupadd.o: config.h shadow.h
  629. Xgroupdel.o: config.h shadow.h
  630. Xgroupmod.o: config.h shadow.h
  631. Xlogoutd.o: config.h
  632. Xsulogin.o: config.h pwauth.h
  633. Xcopydir.o: config.h
  634. Xchowndir.o: config.h
  635. Xpwck.o: config.h shadow.h pwd.h
  636. Xgrpck.o: config.h shadow.h pwd.h
  637. X
  638. Xlibshadow.a(shadow.o): shadow.h config.h
  639. Xlibshadow.a(shadowio.o): shadow.h
  640. Xlibshadow.a(grent.o): config.h shadow.h
  641. Xlibshadow.a(sgroupio.o): shadow.h
  642. Xlibshadow.a(dialup.o): dialup.h
  643. Xlibshadow.a(dialchk.o): dialup.h config.h
  644. Xlibshadow.a(getdef.o): config.h
  645. Xlibshadow.a(pwdbm.o): config.h pwd.h
  646. Xlibshadow.a(spdbm.o): config.h shadow.h
  647. Xlibshadow.a(grdbm.o): config.h
  648. Xlibshadow.a(gshadow.o): config.h
  649. Xlibshadow.a(gsdbm.o): config.h shadow.h
  650. Xlibshadow.a(pwauth.o): config.h pwauth.h
  651. Xlibshadow.a(pwpack.o): config.h pwd.h
  652. Xlibshadow.a(pwent.o): config.h pwd.h
  653. Xlibshadow.a(pwio.o): pwd.h
  654. Xlibshadow.a(getpass.o): config.h
  655. Xlibshadow.a(encrypt.o): config.h
  656. Xlibshadow.a(port.o): port.h
  657. Xlibshadow.a(rad64.o): config.h
  658. Xlibshadow.a(lockpw.o):
  659. X
  660. Xclean:
  661. X    -rm -f susetup.c *.o a.out core npasswd nshadow *.pag *.dir pwd.h
  662. X
  663. Xclobber: clean
  664. X    -rm -f $(BINS) *.lint *.L libshadow.a
  665. X
  666. Xnuke:    clobber
  667. X    -for file in * ; do \
  668. X        if [ -f s.$$file -a ! -f p.$$file ] ; then \
  669. X            rm -f $$file ;\
  670. X        fi ;\
  671. X    done
  672. X
  673. Xshar:    login.sh.01 login.sh.02 login.sh.03 login.sh.04 login.sh.05 \
  674. X    login.sh.06 login.sh.07 login.sh.08 login.sh.09 login.sh.10 \
  675. X    login.sh.11 login.sh.12
  676. X
  677. Xlogin.sh.01: $(FILES1) Makefile
  678. X    shar -Dc $(FILES1) > login.sh.01
  679. X
  680. Xlogin.sh.02: $(FILES2) Makefile
  681. X    shar -Dc $(FILES2) > login.sh.02
  682. X
  683. Xlogin.sh.03: $(FILES3) Makefile
  684. X    shar -Dc $(FILES3) > login.sh.03
  685. X
  686. Xlogin.sh.04: $(FILES4) Makefile
  687. X    shar -Dc $(FILES4) > login.sh.04
  688. X
  689. Xlogin.sh.05: $(FILES5) Makefile
  690. X    shar -Dc $(FILES5) > login.sh.05
  691. X
  692. Xlogin.sh.06: $(FILES6) Makefile
  693. X    shar -Dc $(FILES6) > login.sh.06
  694. X
  695. Xlogin.sh.07: $(FILES7) Makefile
  696. X    shar -Dc $(FILES7) > login.sh.07
  697. X
  698. Xlogin.sh.08: $(FILES8) Makefile
  699. X    shar -Dc $(FILES8) > login.sh.08
  700. X
  701. Xlogin.sh.09: $(FILES9) Makefile
  702. X    shar -Dc $(FILES9) > login.sh.09
  703. X
  704. Xlogin.sh.10: $(DOCS1) Makefile
  705. X    shar -Dc $(DOCS1) > login.sh.10
  706. X
  707. Xlogin.sh.11: $(DOCS2) Makefile
  708. X    shar -Dc $(DOCS2) > login.sh.11
  709. X
  710. Xlogin.sh.12: $(FILES_SUN4) $(FILES_SVR4) Makefile
  711. X    shar -Dc $(FILES_SUN4) $(FILES_SVR4) > login.sh.12
  712. END_OF_FILE
  713.   if test 20253 -ne `wc -c <'Makefile'`; then
  714.     echo shar: \"'Makefile'\" unpacked with wrong size!
  715.   fi
  716.   # end of 'Makefile'
  717. fi
  718. if test -f 'groupmod.1' -a "${1}" != "-c" ; then 
  719.   echo shar: Will not clobber existing file \"'groupmod.1'\"
  720. else
  721.   echo shar: Extracting \"'groupmod.1'\" \(1387 characters\)
  722.   sed "s/^X//" >'groupmod.1' <<'END_OF_FILE'
  723. X.\" Copyright 1991, John F. Haugh II
  724. X.\" All rights reserved.
  725. X.\"
  726. X.\" Permission is granted to copy and create derivative works for any
  727. X.\" non-commercial purpose, provided this copyright notice is preserved
  728. X.\" in all copies of source code, or included in human readable form
  729. X.\" and conspicuously displayed on all copies of object code or
  730. X.\" distribution media.
  731. X.\"
  732. X.\"    @(#)groupmod.1    3.1    13:28:27    13 Jul 1991
  733. X.\"
  734. X.TH GROUPMOD 1M
  735. X.SH NAME
  736. Xgroupmod \- Modify a group
  737. X.SH SYNOPSIS
  738. X.B groupmod
  739. X[ \fB-g\fI gid \fR[ \fB-o\fR ] ]
  740. X[ \fB-n\fI group_name \fR ]
  741. X.I group
  742. X.SH DESCRIPTION
  743. XThe \fIgroupmod\fR command modifies the system account files to reflect
  744. Xthe changes that are specified on the command line.
  745. XThe options which apply to the \fIgroupmod\fR command are
  746. X.IP "\fB-g \fIgid\fR"
  747. XThe numerical value of the group's ID.
  748. XThis value must be unique, unless the \fI-o\fR option is used.
  749. XThe value must be non-negative.
  750. XValues between 0 and 99 are typically reserved for system groups.
  751. XAny files which the old group ID is the file group ID
  752. Xmust have the file group ID changed manually.
  753. X.IP "\fB-n \fIgroup_name\fR"
  754. XThe name of the group will be changed from \fIgroup\fR to
  755. X\fIgroup_name\fR.
  756. X.SH Files
  757. X/etc/group \- group information
  758. X.br
  759. X/etc/gshadow \- secure group information
  760. X.SH SEE ALSO
  761. X\fBchfn(1), chsh(1), useradd(1M), userdel(1M), usermod(1M),
  762. Xpasswd(1), groupadd(1M), groupdel(1M)
  763. END_OF_FILE
  764.   if test 1387 -ne `wc -c <'groupmod.1'`; then
  765.     echo shar: \"'groupmod.1'\" unpacked with wrong size!
  766.   fi
  767.   # end of 'groupmod.1'
  768. fi
  769. if test -f 'usermod.c' -a "${1}" != "-c" ; then 
  770.   echo shar: Will not clobber existing file \"'usermod.c'\"
  771. else
  772.   echo shar: Extracting \"'usermod.c'\" \(35799 characters\)
  773.   sed "s/^X//" >'usermod.c' <<'END_OF_FILE'
  774. X/*
  775. X * Copyright 1991, 1992, 1993, John F. Haugh II
  776. X * All rights reserved.
  777. X *
  778. X * Permission is granted to copy and create derivative works for any
  779. X * non-commercial purpose, provided this copyright notice is preserved
  780. X * in all copies of source code, or included in human readable form
  781. X * and conspicuously displayed on all copies of object code or
  782. X * distribution media.
  783. X *
  784. X * This software is provided on an AS-IS basis and the author makes
  785. X * no warrantee of any kind.
  786. X */
  787. X
  788. X#ifndef lint
  789. Xstatic    char    sccsid[] = "@(#)usermod.c    3.16    08:11:52    07 May 1993";
  790. X#endif
  791. X
  792. X#include <sys/types.h>
  793. X#include <sys/stat.h>
  794. X#include <stdio.h>
  795. X#include <errno.h>
  796. X#include "pwd.h"
  797. X#include <grp.h>
  798. X#include <ctype.h>
  799. X#include <fcntl.h>
  800. X#include <time.h>
  801. X
  802. X#ifdef    BSD
  803. X#include <strings.h>
  804. X#else
  805. X#include <string.h>
  806. X#endif
  807. X
  808. X#include "config.h"
  809. X#ifdef    SHADOWPWD
  810. X#include "shadow.h"
  811. X#endif
  812. X#include "faillog.h"
  813. X#include "lastlog.h"
  814. X#include "pwauth.h"
  815. X
  816. X#ifdef    USE_SYSLOG
  817. X#include <syslog.h>
  818. X
  819. X#ifndef    LOG_WARN
  820. X#define    LOG_WARN LOG_WARNING
  821. X#endif
  822. X#endif
  823. X
  824. X#ifndef    NGROUPS_MAX
  825. X#define    NGROUPS_MAX    64
  826. X#endif
  827. X
  828. X#if defined(DIR_XENIX) || defined(DIR_BSD) || defined(DIR_SYSV)
  829. X#define    DIR_ANY
  830. X#endif
  831. X
  832. X#if !defined(MDY_DATE) && !defined(DMY_DATE) && !defined(YMD_DATE)
  833. X#define    MDY_DATE    1
  834. X#endif
  835. X#if (defined (MDY_DATE) && (defined (DMY_DATE) || defined (YMD_DATE))) || \
  836. X    (defined (DMY_DATE) && (defined (MDY_DATE) || defined (YMD_DATE)))
  837. XError: You must only define one of MDY_DATE, DMY_DATE, or YMD_DATE
  838. X#endif
  839. X
  840. X#define    VALID(s)    (strcspn (s, ":\n") == strlen (s))
  841. X
  842. Xchar    user_name[BUFSIZ];
  843. Xchar    user_newname[BUFSIZ];
  844. Xchar    user_auth[BUFSIZ];
  845. Xchar    user_newauth[BUFSIZ];
  846. Xuid_t    user_id;
  847. Xuid_t    user_newid;
  848. Xgid_t    user_gid;
  849. Xgid_t    user_newgid;
  850. Xchar    user_comment[BUFSIZ];
  851. Xchar    user_home[BUFSIZ];
  852. Xchar    user_newhome[BUFSIZ];
  853. Xchar    user_shell[BUFSIZ];
  854. X#ifdef    SHADOWPWD
  855. Xlong    user_expire;
  856. Xlong    user_inactive;
  857. X#endif
  858. Xint    user_ngroups = -1;
  859. Xgid_t    user_groups[NGROUPS_MAX];
  860. Xstruct    passwd    user_pwd;
  861. X#ifdef    SHADOWPWD
  862. Xstruct    spwd    user_spwd;
  863. X#endif
  864. X
  865. Xchar    *Prog;
  866. Xchar    *auth_arg;
  867. X
  868. Xint    Aflg;    /* specify user defined authentication method                 */
  869. Xint    uflg;    /* specify user ID for new account                            */
  870. Xint    oflg;    /* permit non-unique user ID to be specified with -u          */
  871. Xint    gflg;    /* primary group ID  for new account                          */
  872. Xint    Gflg;    /* secondary group set for new account                        */
  873. Xint    dflg;    /* home directory for new account                             */
  874. Xint    sflg;    /* shell program for new account                              */
  875. Xint    cflg;    /* comment (GECOS) field for new account                      */
  876. Xint    mflg;    /* create user's home directory if it doesn't exist           */
  877. Xint    fflg;    /* days until account with expired password is locked         */
  878. Xint    eflg;    /* days after password changed before it becomes expired      */
  879. Xint    lflg;    /* new user name for user                                     */
  880. X
  881. X#ifdef    NDBM
  882. Xextern    int    pw_dbm_mode;
  883. X#ifdef    SHADOWPWD
  884. Xextern    int    sp_dbm_mode;
  885. X#endif
  886. Xextern    int    gr_dbm_mode;
  887. X#ifdef    SHADOWGRP
  888. Xextern    int    sg_dbm_mode;
  889. X#endif
  890. X#endif
  891. Xextern    FILE    *fopen();
  892. Xextern    int    fclose();
  893. Xextern    char    *malloc();
  894. Xextern    char    *mktemp();
  895. X
  896. Xextern    struct    group    *getgrnam();
  897. Xextern    struct    group    *getgrgid();
  898. Xextern    struct    group    *gr_next();
  899. Xextern    struct    group    *gr_locate();
  900. Xextern    int    gr_lock();
  901. Xextern    int    gr_unlock();
  902. Xextern    int    gr_rewind();
  903. Xextern    int    gr_open();
  904. X
  905. X#ifdef    SHADOWGRP
  906. Xextern    struct    sgrp    *sgr_next();
  907. Xextern    int    sgr_lock();
  908. Xextern    int    sgr_unlock();
  909. Xextern    int    sgr_rewind();
  910. Xextern    int    sgr_open();
  911. X#endif
  912. X
  913. Xextern    struct    passwd    *getpwnam();
  914. Xextern    struct    passwd    *pw_next();
  915. Xextern    struct    passwd    *pw_locate();
  916. Xextern    int    pw_lock();
  917. Xextern    int    pw_unlock();
  918. Xextern    int    pw_rewind();
  919. Xextern    int    pw_open();
  920. X
  921. X#ifdef    SHADOWPWD
  922. Xextern    int    spw_lock();
  923. Xextern    int    spw_unlock();
  924. Xextern    int    spw_open();
  925. Xextern    struct    spwd    *spw_locate();
  926. X#endif
  927. X
  928. X#define    DAY    (24L*3600L)
  929. X#define    WEEK    (7*DAY)
  930. X
  931. X#ifdef    ITI_AGING
  932. X#define    SCALE    (1)
  933. X#else
  934. X#define    SCALE    (DAY)
  935. X#endif
  936. X
  937. X/*
  938. X * days and juldays are used to compute the number of days in the
  939. X * current month, and the cummulative number of days in the preceding
  940. X * months.  they are declared so that january is 1, not 0.
  941. X */
  942. X
  943. Xstatic    short    days[13] = { 0,
  944. X    31,    28,    31,    30,    31,    30,    /* JAN - JUN */
  945. X    31,    31,    30,    31,    30,    31 };    /* JUL - DEC */
  946. X
  947. Xstatic    short    juldays[13] = { 0,
  948. X    0,    31,    59,    90,    120,    151,    /* JAN - JUN */
  949. X    181,    212,    243,    273,    304,    334 };    /* JUL - DEC */
  950. X
  951. X#ifdef    NEED_RENAME
  952. X/*
  953. X * rename - rename a file to another name
  954. X *
  955. X *    rename is provided for systems which do not include the rename()
  956. X *    system call.
  957. X */
  958. X
  959. Xint
  960. Xrename (begin, end)
  961. Xchar    *begin;
  962. Xchar    *end;
  963. X{
  964. X    struct    stat    s1, s2;
  965. X    extern    int    errno;
  966. X    int    orig_err = errno;
  967. X
  968. X    if (stat (begin, &s1))
  969. X        return -1;
  970. X
  971. X    if (stat (end, &s2)) {
  972. X        errno = orig_err;
  973. X    } else {
  974. X
  975. X        /*
  976. X         * See if this is a cross-device link.  We do this to
  977. X         * insure that the link below has a chance of working.
  978. X         */
  979. X
  980. X        if (s1.st_dev != s2.st_dev) {
  981. X            errno = EXDEV;
  982. X            return -1;
  983. X        }
  984. X
  985. X        /*
  986. X         * See if we can unlink the existing destination
  987. X         * file.  If the unlink works the directory is writable,
  988. X         * so there is no need here to figure that out.
  989. X         */
  990. X
  991. X        if (unlink (end))
  992. X            return -1;
  993. X    }
  994. X
  995. X    /*
  996. X     * Now just link the original name to the final name.  If there
  997. X     * was no file previously, this link will fail if the target
  998. X     * directory isn't writable.  The unlink will fail if the source
  999. X     * directory isn't writable, but life stinks ...
  1000. X     */
  1001. X
  1002. X    if (link (begin, end) || unlink (begin))
  1003. X        return -1;
  1004. X
  1005. X    return 0;
  1006. X}
  1007. X#endif
  1008. X
  1009. X/*
  1010. X * strtoday - compute the number of days since 1970.
  1011. X *
  1012. X * the total number of days prior to the current date is
  1013. X * computed.  january 1, 1970 is used as the origin with
  1014. X * it having a day number of 0.
  1015. X */
  1016. X
  1017. Xlong
  1018. Xstrtoday (str)
  1019. Xchar    *str;
  1020. X{
  1021. X    char    slop[2];
  1022. X    int    month;
  1023. X    int    day;
  1024. X    int    year;
  1025. X    long    total;
  1026. X
  1027. X    /*
  1028. X     * start by separating the month, day and year.  the order
  1029. X     * is compiled in ...
  1030. X     */
  1031. X
  1032. X#ifdef    MDY_DATE
  1033. X    if (sscanf (str, "%d/%d/%d%c", &month, &day, &year, slop) != 3)
  1034. X        return -1;
  1035. X#endif
  1036. X#ifdef    DMY_DATE
  1037. X    if (sscanf (str, "%d/%d/%d%c", &day, &month, &year, slop) != 3)
  1038. X        return -1;
  1039. X#endif
  1040. X#ifdef    YMD_DATE
  1041. X    if (sscanf (str, "%d/%d/%d%c", &year, &month, &day, slop) != 3)
  1042. X        return -1;
  1043. X#endif
  1044. X
  1045. X    /*
  1046. X     * the month, day of the month, and year are checked for
  1047. X     * correctness and the year adjusted so it falls between
  1048. X     * 1970 and 2069.
  1049. X     */
  1050. X
  1051. X    if (month < 1 || month > 12)
  1052. X        return -1;
  1053. X
  1054. X    if (day < 1)
  1055. X        return -1;
  1056. X
  1057. X    if ((month != 2 || (year % 4) != 0) && day > days[month])
  1058. X        return -1;
  1059. X    else if ((month == 2 && (year % 4) == 0) && day > 29)
  1060. X        return -1;
  1061. X
  1062. X    if (year < 0)
  1063. X        return -1;
  1064. X    else if (year < 69)
  1065. X        year += 2000;
  1066. X    else if (year < 99)
  1067. X        year += 1900;
  1068. X
  1069. X    if (year < 1970 || year > 2069)
  1070. X        return -1;
  1071. X
  1072. X    /*
  1073. X     * the total number of days is the total number of days in all
  1074. X     * the whole years, plus the number of leap days, plus the
  1075. X     * number of days in the whole months preceding, plus the number
  1076. X     * of days so far in the month.
  1077. X     */
  1078. X
  1079. X    total = (long) ((year - 1970) * 365L) + (((year + 1) - 1970) / 4);
  1080. X    total += (long) juldays[month] + (month > 2 && (year % 4) == 0 ? 1:0);
  1081. X    total += (long) day - 1;
  1082. X
  1083. X    return total;
  1084. X}
  1085. X
  1086. X/*
  1087. X * add_list - add a member to a list of group members
  1088. X *
  1089. X *    the array of member names is searched for the new member
  1090. X *    name, and if not present it is added to a freshly allocated
  1091. X *    list of users.
  1092. X */
  1093. X
  1094. Xchar **
  1095. Xadd_list (list, member)
  1096. Xchar    **list;
  1097. Xchar    *member;
  1098. X{
  1099. X    int    i;
  1100. X    char    **tmp;
  1101. X
  1102. X    /*
  1103. X     * Scan the list for the new name.  Return the original list
  1104. X     * pointer if it is present.
  1105. X     */
  1106. X
  1107. X    for (i = 0;list[i] != (char *) 0;i++)
  1108. X        if (strcmp (list[i], member) == 0)
  1109. X            return list;
  1110. X
  1111. X    /*
  1112. X     * Allocate a new list pointer large enough to hold all the
  1113. X     * old entries, and the new entries as well.
  1114. X     */
  1115. X
  1116. X    if (! (tmp = (char **) malloc ((i + 2) * sizeof member)))
  1117. X        return 0;
  1118. X
  1119. X    /*
  1120. X     * Copy the original list to the new list, then append the
  1121. X     * new member and NULL terminate the result.  This new list
  1122. X     * is returned to the invoker.
  1123. X     */
  1124. X
  1125. X    for (i = 0;list[i] != (char *) 0;i++)
  1126. X        tmp[i] = list[i];
  1127. X
  1128. X    tmp[i++] = strdup (member);
  1129. X    tmp[i] = (char *) 0;
  1130. X
  1131. X    return tmp;
  1132. X}
  1133. X
  1134. X/*
  1135. X * del_list - delete a member from a list of group members
  1136. X *
  1137. X *    the array of member names is searched for the old member
  1138. X *    name, and if present it is deleted from a freshly allocated
  1139. X *    list of users.
  1140. X */
  1141. X
  1142. Xchar **
  1143. Xdel_list (list, member)
  1144. Xchar    **list;
  1145. Xchar    *member;
  1146. X{
  1147. X    int    i, j;
  1148. X    char    **tmp;
  1149. X
  1150. X    /*
  1151. X     * Scan the list for the new name.  Return the original list
  1152. X     * pointer if it is present.
  1153. X     */
  1154. X
  1155. X    for (i = j = 0;list[i] != (char *) 0;i++)
  1156. X        if (strcmp (list[i], member))
  1157. X            j++;
  1158. X
  1159. X    if (j == i)
  1160. X        return list;
  1161. X
  1162. X    /*
  1163. X     * Allocate a new list pointer large enough to hold all the
  1164. X     * old entries, and the new entries as well.
  1165. X     */
  1166. X
  1167. X    if (! (tmp = (char **) malloc ((j + 2) * sizeof member)))
  1168. X        return 0;
  1169. X
  1170. X    /*
  1171. X     * Copy the original list to the new list, then append the
  1172. X     * new member and NULL terminate the result.  This new list
  1173. X     * is returned to the invoker.
  1174. X     */
  1175. X
  1176. X    for (i = j = 0;list[i] != (char *) 0;i++)
  1177. X        if (strcmp (list[i], member))
  1178. X            tmp[j++] = list[i];
  1179. X
  1180. X    tmp[j] = (char *) 0;
  1181. X
  1182. X    return tmp;
  1183. X}
  1184. X
  1185. X/*
  1186. X * get_groups - convert a list of group names to an array of group IDs
  1187. X *
  1188. X *    get_groups() takes a comma-separated list of group names and
  1189. X *    converts it to an array of group ID values.  Any unknown group
  1190. X *    names are reported as errors.
  1191. X */
  1192. X
  1193. Xint
  1194. Xget_groups (list)
  1195. Xchar    *list;
  1196. X{
  1197. X    char    *cp;
  1198. X    struct    group    *grp;
  1199. X    int    errors = 0;
  1200. X
  1201. X    /*
  1202. X     * Initialize the list to be empty
  1203. X     */
  1204. X
  1205. X    user_ngroups = 0;
  1206. X
  1207. X    if (! *list)
  1208. X        return 0;
  1209. X
  1210. X    /*
  1211. X     * So long as there is some data to be converted, strip off
  1212. X     * each name and look it up.  A mix of numerical and string
  1213. X     * values for group identifiers is permitted.
  1214. X     */
  1215. X
  1216. X    do {
  1217. X        /*
  1218. X         * Strip off a single name from the list
  1219. X         */
  1220. X
  1221. X        if (cp = strchr (list, ','))
  1222. X            *cp++ = '\0';
  1223. X
  1224. X        /*
  1225. X         * Names starting with digits are treated as numerical
  1226. X         * GID values, otherwise the string is looked up as is.
  1227. X         */
  1228. X
  1229. X        if (isdigit (*list))
  1230. X            grp = getgrgid (atoi (list));
  1231. X        else
  1232. X            grp = getgrnam (list);
  1233. X
  1234. X        /*
  1235. X         * There must be a match, either by GID value or by
  1236. X         * string name.
  1237. X         */
  1238. X
  1239. X        if (! grp) {
  1240. X            fprintf (stderr, "%s: unknown group %s\n", Prog, list);
  1241. X            errors++;
  1242. X        }
  1243. X
  1244. X        /*
  1245. X         * Add the GID value from the group file to the user's
  1246. X         * list of groups.
  1247. X         */
  1248. X
  1249. X        user_groups[user_ngroups++] = grp->gr_gid;
  1250. X
  1251. X        list = cp;
  1252. X    } while (list);
  1253. X
  1254. X    /*
  1255. X     * Any errors in finding group names are fatal
  1256. X     */
  1257. X
  1258. X    if (errors)
  1259. X        return -1;
  1260. X
  1261. X    return 0;
  1262. X}
  1263. X
  1264. X/*
  1265. X * usage - display usage message and exit
  1266. X */
  1267. X
  1268. Xusage ()
  1269. X{
  1270. X    fprintf (stderr,
  1271. X        "usage: %s [-u uid [-o]] [-g group] [-G group,...] \n", Prog);
  1272. X#ifdef    SHADOWPWD
  1273. X    fprintf (stderr,
  1274. X        "\t\t[-d home [-m]] [-s shell] [-c comment] [-l new_name]\n");
  1275. X#ifdef    MDY_DATE
  1276. X    fprintf (stderr,
  1277. X        "\t\t[-f inactive ] [-e expire mm/dd/yy ] name\n");
  1278. X#endif
  1279. X#ifdef    DMY_DATE
  1280. X    fprintf (stderr,
  1281. X        "\t\t[-f inactive ] [-e expire dd/mm/yy ] name\n");
  1282. X#endif
  1283. X#ifdef    YMD_DATE
  1284. X    fprintf (stderr,
  1285. X        "\t\t[-f inactive ] [-e expire yy/mm/dd ] name\n");
  1286. X#endif
  1287. X#else    /* !SHADOWPWD */
  1288. X    fprintf (stderr,
  1289. X        "\t\t[-d home [-m]] [-s shell] [-c comment] [-l new_name]\n");
  1290. X    fprintf (stderr,
  1291. X        "\t\t[ -A {DEFAULT|program},... ] name\n");
  1292. X#endif    /* SHADOWPWD */
  1293. X    exit (2);
  1294. X}
  1295. X
  1296. X/*
  1297. X * new_pwent - initialize the values in a password file entry
  1298. X *
  1299. X *    new_pwent() takes all of the values that have been entered and
  1300. X *    fills in a (struct passwd) with them.
  1301. X */
  1302. X
  1303. Xvoid
  1304. Xnew_pwent (pwent)
  1305. Xstruct    passwd    *pwent;
  1306. X{
  1307. X    if (lflg) {
  1308. X#ifdef    USE_SYSLOG
  1309. X        syslog (LOG_INFO, "change user name `%s' to `%s'\n",
  1310. X            pwent->pw_name, user_newname);
  1311. X#endif
  1312. X        pwent->pw_name = strdup (user_newname);
  1313. X    }
  1314. X    if (uflg) {
  1315. X#ifdef    USE_SYSLOG
  1316. X        syslog (LOG_INFO, "change user `%s' UID from `%d' to `%d'\n",
  1317. X            pwent->pw_name, pwent->pw_uid, user_newid);
  1318. X#endif
  1319. X        pwent->pw_uid = user_newid;
  1320. X    }
  1321. X    if (gflg) {
  1322. X#ifdef    USE_SYSLOG
  1323. X        syslog (LOG_INFO, "change user `%s' GID from `%d' to `%d'\n",
  1324. X            pwent->pw_name, pwent->pw_gid, user_newgid);
  1325. X#endif
  1326. X        pwent->pw_gid = user_newgid;
  1327. X    }
  1328. X    if (cflg)
  1329. X        pwent->pw_gecos = strdup (user_comment);
  1330. X
  1331. X    if (dflg) {
  1332. X#ifdef    USE_SYSLOG
  1333. X        syslog (LOG_INFO, "change user `%s' home from `%s' to `%s'\n",
  1334. X            pwent->pw_name, pwent->pw_dir, user_newhome);
  1335. X#endif
  1336. X        pwent->pw_dir = strdup (user_newhome);
  1337. X    }
  1338. X    if (sflg) {
  1339. X#ifdef    USE_SYSLOG
  1340. X        syslog (LOG_INFO, "change user `%s' shell from `%s' to `%s'\n",
  1341. X            pwent->pw_name, pwent->pw_shell, user_shell);
  1342. X#endif
  1343. X        pwent->pw_shell = strdup (user_shell);
  1344. X    }
  1345. X}
  1346. X
  1347. X#ifdef    SHADOWPWD
  1348. X/*
  1349. X * new_spent - initialize the values in a shadow password file entry
  1350. X *
  1351. X *    new_spent() takes all of the values that have been entered and
  1352. X *    fills in a (struct spwd) with them.
  1353. X */
  1354. X
  1355. Xvoid
  1356. Xnew_spent (spent)
  1357. Xstruct    spwd    *spent;
  1358. X{
  1359. X    if (lflg)
  1360. X        spent->sp_namp = strdup (user_newname);
  1361. X
  1362. X    if (fflg) {
  1363. X#ifdef    USE_SYSLOG
  1364. X        syslog (LOG_INFO, "change user `%s' inactive from `%d' to `%d'\n",
  1365. X            spent->sp_namp, spent->sp_inact, user_inactive);
  1366. X#endif
  1367. X        spent->sp_inact = user_inactive;
  1368. X    }
  1369. X    if (eflg) {
  1370. X#ifdef    USE_SYSLOG
  1371. X        syslog (LOG_INFO, "change user `%s' expiration from `%d' to `%d'\n",
  1372. X            spent->sp_namp, spent->sp_expire, user_expire);
  1373. X#endif
  1374. X        spent->sp_expire = user_expire;
  1375. X    }
  1376. X}
  1377. X#endif    /* SHADOWPWD */
  1378. X
  1379. X/*
  1380. X * grp_update - add user to secondary group set
  1381. X *
  1382. X *    grp_update() takes the secondary group set given in user_groups
  1383. X *    and adds the user to each group given by that set.
  1384. X */
  1385. X
  1386. Xvoid
  1387. Xgrp_update ()
  1388. X{
  1389. X    int    i;
  1390. X    int    is_member;
  1391. X    int    was_member;
  1392. X    struct    group    *grp;
  1393. X#ifdef    SHADOWGRP
  1394. X    int    was_admin;
  1395. X    struct    sgrp    *sgrp;
  1396. X#endif
  1397. X
  1398. X    /*
  1399. X     * Lock and open the group file.  This will load all of the group
  1400. X     * entries.
  1401. X     */
  1402. X
  1403. X    if (! gr_lock ()) {
  1404. X        fprintf (stderr, "%s: error locking group file\n", Prog);
  1405. X#ifdef    USE_SYSLOG
  1406. X        syslog (LOG_ERR, "error locking group file");
  1407. X#endif
  1408. X        exit (1);
  1409. X    }
  1410. X    if (! gr_open (O_RDWR)) {
  1411. X        fprintf (stderr, "%s: error opening group file\n", Prog);
  1412. X#ifdef    USE_SYSLOG
  1413. X        syslog (LOG_ERR, "error opening group file");
  1414. X#endif
  1415. X        fail_exit (1);
  1416. X    }
  1417. X#ifdef    SHADOWGRP
  1418. X    if (! sgr_lock ()) {
  1419. X        fprintf (stderr, "%s: error locking shadow group file\n", Prog);
  1420. X#ifdef    USE_SYSLOG
  1421. X        syslog (LOG_ERR, "error locking shadow group file");
  1422. X#endif
  1423. X        fail_exit (1);
  1424. X    }
  1425. X    if (! sgr_open (O_RDWR)) {
  1426. X        fprintf (stderr, "%s: error opening shadow group file\n", Prog);
  1427. X#ifdef    USE_SYSLOG
  1428. X        syslog (LOG_ERR, "error opening shadow group file");
  1429. X#endif
  1430. X        fail_exit (1);
  1431. X    }
  1432. X#endif    /* SHADOWGRP */
  1433. X
  1434. X    /*
  1435. X     * Scan through the entire group file looking for the groups that
  1436. X     * the user is a member of.
  1437. X     */
  1438. X
  1439. X    for (gr_rewind (), grp = gr_next ();grp;grp = gr_next ()) {
  1440. X
  1441. X        /*
  1442. X         * See if the user specified this group as one of their
  1443. X         * concurrent groups.
  1444. X         */
  1445. X
  1446. X        for (i = 0;i < user_ngroups;i++)
  1447. X            if (grp->gr_gid == user_groups[i])
  1448. X                break;
  1449. X
  1450. X        is_member = i == user_ngroups ? -1:i;
  1451. X
  1452. X        for (i = 0;grp->gr_mem[i];i++)
  1453. X            if (strcmp (user_name, grp->gr_mem[i]) == 0)
  1454. X                break;
  1455. X
  1456. X        was_member = grp->gr_mem[i] ? i:-1;
  1457. X
  1458. X        if (is_member == -1 && was_member == -1)
  1459. X            continue;
  1460. X
  1461. X        if (was_member >= 0 && (! Gflg || is_member >= 0)) {
  1462. X            if (lflg) {
  1463. X                grp->gr_mem = del_list (grp->gr_mem,
  1464. X                    user_name);
  1465. X                grp->gr_mem = add_list (grp->gr_mem,
  1466. X                    user_newname);
  1467. X#ifdef    USE_SYSLOG
  1468. X                syslog (LOG_INFO,
  1469. X                    "change `%s' to `%s' in group `%s'\n",
  1470. X                    user_name, user_newname, grp->gr_name);
  1471. X#endif
  1472. X            }
  1473. X        } else if (was_member >= 0 && Gflg && is_member < 0) {
  1474. X            grp->gr_mem = del_list (grp->gr_mem, user_name);
  1475. X#ifdef    USE_SYSLOG
  1476. X            syslog (LOG_INFO, "delete `%s' from group `%s'\n",
  1477. X                user_name, grp->gr_name);
  1478. X#endif
  1479. X        } else if (was_member < 0 && Gflg && is_member >= 0) {
  1480. X            grp->gr_mem = add_list (grp->gr_mem,
  1481. X                lflg ? user_newname:user_name);
  1482. X#ifdef    USE_SYSLOG
  1483. X            syslog (LOG_INFO, "add `%s' to group `%s'\n",
  1484. X                lflg ? user_newname:user_name, grp->gr_name);
  1485. X#endif
  1486. X        } else
  1487. X            continue;
  1488. X
  1489. X        if (! gr_update (grp)) {
  1490. X            fprintf (stderr, "%s: error adding new group entry\n",
  1491. X                Prog);
  1492. X#ifdef    USE_SYSLOG
  1493. X            syslog (LOG_ERR, "error adding group entry");
  1494. X#endif
  1495. X            fail_exit (1);
  1496. X        }
  1497. X#ifdef    NDBM
  1498. X        /*
  1499. X         * Update the DBM group file with the new entry as well.
  1500. X         */
  1501. X
  1502. X        if (! gr_dbm_update (grp)) {
  1503. X            fprintf (stderr, "%s: cannot add new dbm group entry\n",
  1504. X                Prog);
  1505. X#ifdef    USE_SYSLOG
  1506. X            syslog (LOG_ERR, "error adding dbm group entry");
  1507. X#endif
  1508. X            fail_exit (1);
  1509. X        }
  1510. X#endif    /* NDBM */
  1511. X    }
  1512. X#ifdef NDBM
  1513. X    endgrent ();
  1514. X#endif
  1515. X
  1516. X#ifdef    SHADOWGRP
  1517. X    /*
  1518. X     * Scan through the entire shadow group file looking for the groups
  1519. X     * that the user is a member of.
  1520. X     */
  1521. X
  1522. X    for (sgr_rewind (), sgrp = sgr_next ();sgrp;sgrp = sgr_next ()) {
  1523. X
  1524. X        /*
  1525. X         * See if the user was a member of this group
  1526. X         */
  1527. X
  1528. X        for (i = 0;sgrp->sg_mem[i];i++)
  1529. X            if (strcmp (sgrp->sg_mem[i], user_name) == 0)
  1530. X                break;
  1531. X
  1532. X        was_member = sgrp->sg_mem[i] ? i:-1;
  1533. X
  1534. X        /*
  1535. X         * See if the user was an administrator of this group
  1536. X         */
  1537. X
  1538. X        for (i = 0;sgrp->sg_adm[i];i++)
  1539. X            if (strcmp (sgrp->sg_adm[i], user_name) == 0)
  1540. X                break;
  1541. X
  1542. X        was_admin = sgrp->sg_adm[i] ? i:-1;
  1543. X
  1544. X        /*
  1545. X         * See if the user specified this group as one of their
  1546. X         * concurrent groups.
  1547. X         */
  1548. X
  1549. X        for (i = 0;i < user_ngroups;i++) {
  1550. X            if (! (grp = gr_locate (sgrp->sg_name)))
  1551. X                continue;
  1552. X
  1553. X            if (grp->gr_gid == user_groups[i])
  1554. X                break;
  1555. X        }
  1556. X        is_member = i == user_ngroups ? -1:i;
  1557. X
  1558. X        if (is_member == -1 && was_admin == -1 && was_member == -1)
  1559. X            continue;
  1560. X
  1561. X        if (was_admin >= 0 && lflg) {
  1562. X            sgrp->sg_adm = del_list (sgrp->sg_adm, user_name);
  1563. X            sgrp->sg_adm = add_list (sgrp->sg_adm, user_newname);
  1564. X#ifdef    USE_SYSLOG
  1565. X            syslog (LOG_INFO, "change admin `%s' to `%s' in shadow group `%s'\n",
  1566. X                user_name, user_newname, sgrp->sg_name);
  1567. X#endif
  1568. X        }
  1569. X        if (was_member >= 0 && (! Gflg || is_member >= 0)) {
  1570. X            if (lflg) {
  1571. X                sgrp->sg_mem = del_list (sgrp->sg_mem,
  1572. X                    user_name);
  1573. X                sgrp->sg_mem = add_list (sgrp->sg_mem,
  1574. X                    user_newname);
  1575. X#ifdef    USE_SYSLOG
  1576. X                syslog (LOG_INFO, "change `%s' to `%s' in shadow group `%s'\n",
  1577. X                    user_name, user_newname, sgrp->sg_name);
  1578. X#endif
  1579. X            }
  1580. X        } else if (was_member >= 0 && Gflg && is_member < 0) {
  1581. X            sgrp->sg_mem = del_list (sgrp->sg_mem, user_name);
  1582. X#ifdef    USE_SYSLOG
  1583. X            syslog (LOG_INFO,
  1584. X                "delete `%s' from shadow group `%s'\n",
  1585. X                user_name, sgrp->sg_name);
  1586. X#endif
  1587. X        } else if (was_member < 0 && Gflg && is_member >= 0) {
  1588. X            sgrp->sg_mem = add_list (sgrp->sg_mem,
  1589. X                lflg ? user_newname:user_name);
  1590. X#ifdef    USE_SYSLOG
  1591. X            syslog (LOG_INFO, "add `%s' to shadow group `%s'\n",
  1592. X                lflg ? user_newname:user_name, grp->gr_name);
  1593. X#endif
  1594. X        } else
  1595. X            continue;
  1596. X
  1597. X        /* 
  1598. X         * Update the group entry to reflect the changes.
  1599. X         */
  1600. X
  1601. X        if (! sgr_update (sgrp)) {
  1602. X            fprintf (stderr, "%s: error adding new group entry\n",
  1603. X                Prog);
  1604. X#ifdef    USE_SYSLOG
  1605. X            syslog (LOG_ERR, "error adding shadow group entry\n");
  1606. X#endif
  1607. X            fail_exit (1);
  1608. X        }
  1609. X#ifdef    NDBM
  1610. X        /*
  1611. X         * Update the DBM group file with the new entry as well.
  1612. X         */
  1613. X
  1614. X        if (! sg_dbm_update (sgrp)) {
  1615. X            fprintf (stderr, "%s: cannot add new dbm group entry\n",
  1616. X                Prog);
  1617. X#ifdef    USE_SYSLOG
  1618. X            syslog (LOG_ERR,
  1619. X                "error adding dbm shadow group entry\n");
  1620. X#endif
  1621. X            fail_exit (1);
  1622. X        }
  1623. X#endif    /* NDBM */
  1624. X    }
  1625. X#ifdef NDBM
  1626. X    endsgent ();
  1627. X#endif    /* NDBM */
  1628. X#endif    /* SHADOWGRP */
  1629. X}
  1630. X
  1631. X/*
  1632. X * check_new_id - verify the new UID for uniqueness
  1633. X *
  1634. X *    check_new_id() insures that the new UID does not exist already.
  1635. X *    It does this by checking that the UID has changed and that there
  1636. X *    is no current entry for this user ID.
  1637. X */
  1638. X
  1639. Xint
  1640. Xcheck_new_id ()
  1641. X{
  1642. X    /*
  1643. X     * First, the easy stuff.  If the ID can be duplicated, or if
  1644. X     * the ID didn't really change, just return.  If the ID didn't
  1645. X     * change, turn off those flags.  No sense doing needless work.
  1646. X     */
  1647. X
  1648. X    if (oflg)
  1649. X        return 0;
  1650. X
  1651. X    if (user_id == user_newid) {
  1652. X        uflg = lflg = 0;
  1653. X        return 0;
  1654. X    }
  1655. X    if (getpwuid (user_newid))
  1656. X        return -1;
  1657. X
  1658. X    return 0;
  1659. X}
  1660. X
  1661. X/*
  1662. X * get_password - locate encrypted password in authentication list
  1663. X */
  1664. X
  1665. Xchar *
  1666. Xget_password (list)
  1667. Xchar    *list;
  1668. X{
  1669. X    char    *cp, *end;
  1670. X    static    char    buf[257];
  1671. X
  1672. X    strcpy (buf, list);
  1673. X    for (cp = buf;cp;cp = end) {
  1674. X        if (end = strchr (cp, ';'))
  1675. X            *end++ = 0;
  1676. X
  1677. X        if (cp[0] == '@')
  1678. X            continue;
  1679. X
  1680. X        return cp;
  1681. X    }
  1682. X    return (char *) 0;
  1683. X}
  1684. X
  1685. X/*
  1686. X * split_auths - break up comma list into (char *) array
  1687. X */
  1688. X
  1689. Xsplit_auths (list, array)
  1690. Xchar    *list;
  1691. Xchar    **array;
  1692. X{
  1693. X    char    *cp, *end;
  1694. X    int    i = 0;
  1695. X
  1696. X    for (cp = list;cp;cp = end) {
  1697. X        if (end = strchr (cp, ';'))
  1698. X            *end++ = '\0';
  1699. X
  1700. X        array[i++] = cp;
  1701. X    }
  1702. X    array[i] = 0;
  1703. X}
  1704. X
  1705. X/*
  1706. X * update_auths - find list of methods to update
  1707. X */
  1708. X
  1709. Xupdate_auths (old, new, update)
  1710. Xchar    *old;
  1711. Xchar    *new;
  1712. Xchar    *update;
  1713. X{
  1714. X    char    oldbuf[257], newbuf[257];
  1715. X    char    *oldv[32], *newv[32], *updatev[32];
  1716. X    int    i, j, k;
  1717. X
  1718. X    strcpy (oldbuf, old);
  1719. X    split_auths (oldbuf, oldv);
  1720. X
  1721. X    strcpy (newbuf, new);
  1722. X    split_auths (newbuf, newv);
  1723. X
  1724. X    for (i = j = k = 0;oldv[i];i++) {
  1725. X        for (j = 0;newv[j];j++)
  1726. X            if (strcmp (oldv[i], newv[j]) != 0)
  1727. X                break;
  1728. X
  1729. X        if (newv[j] != (char *) 0)
  1730. X            updatev[k++] = oldv[i];
  1731. X    }
  1732. X    updatev[k] = 0;
  1733. X
  1734. X    update[0] = '\0';
  1735. X    for (i = 0;updatev[i];i++) {
  1736. X        if (i)
  1737. X            strcat (update, ";");
  1738. X
  1739. X        strcat (update, updatev[i]);
  1740. X    }
  1741. X}
  1742. X
  1743. X/*
  1744. X * add_auths - find list of methods to add
  1745. X */
  1746. X
  1747. Xadd_auths (old, new, add)
  1748. Xchar    *old;
  1749. Xchar    *new;
  1750. Xchar    *add;
  1751. X{
  1752. X    char    oldbuf[257], newbuf[257];
  1753. X    char    *oldv[32], *newv[32], *addv[32];
  1754. X    int    i, j, k;
  1755. X
  1756. X    strcpy (oldbuf, old);
  1757. X    split_auths (oldbuf, oldv);
  1758. X
  1759. X    strcpy (newbuf, new);
  1760. X    split_auths (newbuf, newv);
  1761. X
  1762. X    for (i = j = k = 0;newv[i];i++) {
  1763. X        for (j = 0;oldv[j];j++)
  1764. X            if (strcmp (oldv[i], newv[j]) == 0)
  1765. X                break;
  1766. X
  1767. X        if (oldv[j] == (char *) 0)
  1768. X            addv[k++] = newv[i];
  1769. X    }
  1770. X    addv[k] = 0;
  1771. X
  1772. X    add[0] = '\0';
  1773. X    for (i = 0;addv[i];i++) {
  1774. X        if (i)
  1775. X            strcat (add, ";");
  1776. X
  1777. X        strcat (add, addv[i]);
  1778. X    }
  1779. X}
  1780. X
  1781. X/*
  1782. X * delete_auths - find list of methods to delete
  1783. X */
  1784. X
  1785. Xdelete_auths (old, new, remove)
  1786. Xchar    *old;
  1787. Xchar    *new;
  1788. Xchar    *remove;
  1789. X{
  1790. X    char    oldbuf[257], newbuf[257];
  1791. X    char    *oldv[32], *newv[32], *removev[32];
  1792. X    int    i, j, k;
  1793. X
  1794. X    strcpy (oldbuf, old);
  1795. X    split_auths (oldbuf, oldv);
  1796. X
  1797. X    strcpy (newbuf, new);
  1798. X    split_auths (newbuf, newv);
  1799. X
  1800. X    for (i = j = k = 0;oldv[i];i++) {
  1801. X        for (j = 0;newv[j];j++)
  1802. X            if (strcmp (oldv[i], newv[j]) == 0)
  1803. X                break;
  1804. X
  1805. X        if (newv[j] == (char *) 0)
  1806. X            removev[k++] = oldv[i];
  1807. X    }
  1808. X    removev[k] = 0;
  1809. X
  1810. X    remove[0] = '\0';
  1811. X    for (i = 0;removev[i];i++) {
  1812. X        if (i)
  1813. X            strcat (remove, ";");
  1814. X
  1815. X        strcat (remove, removev[i]);
  1816. X    }
  1817. X}
  1818. X
  1819. X/*
  1820. X * convert_auth - convert the argument list to a authentication list
  1821. X */
  1822. X
  1823. Xconvert_auth (auths, oldauths, list)
  1824. Xchar    *auths;
  1825. Xchar    *oldauths;
  1826. Xchar    *list;
  1827. X{
  1828. X    char    *cp, *end;
  1829. X    char    *old;
  1830. X    char    buf[257];
  1831. X
  1832. X    /*
  1833. X     * Copy each method.  DEFAULT is replaced by an encrypted string
  1834. X     * if one can be found in the current authentication list.
  1835. X     */
  1836. X
  1837. X    strcpy (buf, list);
  1838. X    auths[0] = '\0';
  1839. X    for (cp = buf;cp;cp = end) {
  1840. X        if (auths[0])
  1841. X            strcat (auths, ";");
  1842. X
  1843. X        if (end = strchr (cp, ','))
  1844. X            *end++ = '\0';
  1845. X
  1846. X        if (strcmp (cp, "DEFAULT") == 0) {
  1847. X            if (old = get_password (oldauths))
  1848. X                strcat (auths, old);
  1849. X            else
  1850. X                strcat (auths, "!");
  1851. X        } else {
  1852. X            strcat (auths, "@");
  1853. X            strcat (auths, cp);
  1854. X        }
  1855. X    }
  1856. X}
  1857. X
  1858. X/*
  1859. X * valid_auth - check authentication list for validity
  1860. X */
  1861. X
  1862. Xvalid_auth (methods)
  1863. Xchar    *methods;
  1864. X{
  1865. X    char    *cp, *end;
  1866. X    char    buf[257];
  1867. X    int    default_cnt = 0;
  1868. X
  1869. X    /*
  1870. X     * Cursory checks, length and illegal characters
  1871. X     */
  1872. X
  1873. X    if (strlen (methods) > 256)
  1874. X        return 0;
  1875. X
  1876. X    if (! VALID (methods))
  1877. X        return 0;
  1878. X
  1879. X    /*
  1880. X     * Pick each method apart and check it.
  1881. X     */
  1882. X
  1883. X    strcpy (buf, methods);
  1884. X    for (cp = buf;cp;cp = end) {
  1885. X        if (end = strchr (cp, ','))
  1886. X            *end++ = '\0';
  1887. X
  1888. X        if (strcmp (cp, "DEFAULT") == 0) {
  1889. X            if (default_cnt++ > 0)
  1890. X                return 0;
  1891. X        } else if (cp[0] != '/')
  1892. X            return 0;
  1893. X    }
  1894. X    return 1;
  1895. X}
  1896. X
  1897. X/*
  1898. X * process_flags - perform command line argument setting
  1899. X *
  1900. X *    process_flags() interprets the command line arguments and sets
  1901. X *    the values that the user will be created with accordingly.  The
  1902. X *    values are checked for sanity.
  1903. X */
  1904. X
  1905. Xvoid
  1906. Xprocess_flags (argc, argv)
  1907. Xint    argc;
  1908. Xchar    **argv;
  1909. X{
  1910. X    extern    int    optind;
  1911. X    extern    char    *optarg;
  1912. X    struct    group    *grp;
  1913. X    struct    passwd    *pwd;
  1914. X    struct    spwd    *spwd;
  1915. X    long    l;
  1916. X    int    anyflag = 0;
  1917. X    int    arg;
  1918. X
  1919. X    if (argc == 1 || argv[argc - 1][0] == '-')
  1920. X        usage ();
  1921. X
  1922. X    if (! (pwd = getpwnam (argv[argc - 1]))) {
  1923. X        fprintf (stderr, "%s: user %s does not exist\n",
  1924. X            Prog, argv[argc - 1]);
  1925. X        exit (6);
  1926. X    }
  1927. X    strcpy (user_name, pwd->pw_name);
  1928. X    user_id = pwd->pw_uid;
  1929. X    user_gid = pwd->pw_gid;
  1930. X    strcpy (user_comment, pwd->pw_gecos);
  1931. X    strcpy (user_home, pwd->pw_dir);
  1932. X    strcpy (user_shell, pwd->pw_shell);
  1933. X
  1934. X#ifdef    SHADOWPWD
  1935. X    if (spwd = getspnam (user_name)) {
  1936. X        user_expire = spwd->sp_expire;
  1937. X        user_inactive = spwd->sp_inact;
  1938. X    }
  1939. X#endif
  1940. X#ifdef    SHADOWPWD
  1941. X    while ((arg = getopt (argc, argv, "A:u:og:G:d:s:c:mf:e:l:")) != EOF)
  1942. X#else
  1943. X    while ((arg = getopt (argc, argv, "A:u:og:G:d:s:c:ml:")) != EOF)
  1944. X#endif
  1945. X    {
  1946. X        switch (arg) {
  1947. X            case 'A':
  1948. X                if (! valid_auth (optarg)) {
  1949. X                    fprintf (stderr,
  1950. X                        "%s: invalid field `%s'\n",
  1951. X                        Prog, optarg);
  1952. X                    exit (3);
  1953. X                }
  1954. X                auth_arg = optarg;
  1955. X                Aflg++;
  1956. X                break;
  1957. X            case 'c':
  1958. X                if (! VALID (optarg)) {
  1959. X                    fprintf (stderr,
  1960. X                        "%s: invalid field `%s'\n",
  1961. X                        Prog, optarg);
  1962. X                    exit (3);
  1963. X                }
  1964. X                strncpy (user_comment, optarg, BUFSIZ);
  1965. X                cflg++;
  1966. X                break;
  1967. X            case 'd':
  1968. X                if (! VALID (optarg)) {
  1969. X                    fprintf (stderr,
  1970. X                        "%s: invalid field `%s'\n",
  1971. X                        Prog, optarg);
  1972. X                    exit (3);
  1973. X                }
  1974. X                dflg++;
  1975. X                strncpy (user_newhome, optarg, BUFSIZ);
  1976. X                break;
  1977. X#ifdef    SHADOWPWD
  1978. X            case 'e':
  1979. X                l = strtoday (optarg);
  1980. X#ifdef    ITI_AGING
  1981. X                l *= DAY;
  1982. X#endif
  1983. X                user_expire = l;
  1984. X                eflg++;
  1985. X                break;
  1986. X            case 'f':
  1987. X                user_inactive = atoi (optarg);
  1988. X                fflg++;
  1989. X                break;
  1990. X#endif    /* SHADOWPWD */
  1991. X            case 'g':
  1992. X                if (isdigit (optarg[0]))
  1993. X                    grp = getgrgid (atoi (optarg));
  1994. X                else
  1995. X                    grp = getgrnam (optarg);
  1996. X
  1997. X                if (! grp) {
  1998. X                    fprintf (stderr,
  1999. X                        "%s: unknown group %s\n",
  2000. X                        Prog, optarg);
  2001. X                    exit (1);
  2002. X                }
  2003. X                user_newgid = grp->gr_gid;
  2004. X                gflg++;
  2005. X                break;
  2006. X            case 'G':
  2007. X                Gflg++;
  2008. X                if (get_groups (optarg))
  2009. X                    exit (1);
  2010. X
  2011. X                break;
  2012. X            case 'l':
  2013. X                if (! VALID (optarg)) {
  2014. X                    fprintf (stderr,
  2015. X                        "%s: invalid field `%s'\n",
  2016. X                        Prog, optarg);
  2017. X                    exit (3);
  2018. X                }
  2019. X
  2020. X                /*
  2021. X                 * If the name does not really change, we
  2022. X                 * mustn't set the flag as this will cause
  2023. X                 * rather serious problems later!
  2024. X                 */
  2025. X
  2026. X                if (strcmp (user_newname, optarg)) {
  2027. X                    strcpy (user_newname, optarg);
  2028. X                    lflg++;
  2029. X                }
  2030. X                break;
  2031. X            case 'm':
  2032. X                if (! dflg)
  2033. X                    usage ();
  2034. X
  2035. X                mflg++;
  2036. X                break;
  2037. X            case 'o':
  2038. X                if (! uflg)
  2039. X                    usage ();
  2040. X
  2041. X                oflg++;
  2042. X                break;
  2043. X            case 's':
  2044. X                if (! VALID (optarg)) {
  2045. X                    fprintf (stderr,
  2046. X                        "%s: invalid field `%s'\n",
  2047. X                        Prog, optarg);
  2048. X                    exit (3);
  2049. X                }
  2050. X                strncpy (user_shell, optarg, BUFSIZ);
  2051. X                sflg++;
  2052. X                break;
  2053. X            case 'u':
  2054. X                uflg++;
  2055. X                user_newid = atoi (optarg);
  2056. X                break;
  2057. X            default:
  2058. X                usage ();
  2059. X        }
  2060. X        anyflag++;
  2061. X    }
  2062. X    if (anyflag == 0) {
  2063. X        fprintf (stderr, "%s: no flags given\n", Prog);
  2064. X        exit (1);
  2065. X    }
  2066. X    if (optind != argc - 1)
  2067. X        usage ();
  2068. X
  2069. X    if (dflg && strcmp (user_home, user_newhome) == 0)
  2070. X        dflg = mflg = 0;
  2071. X
  2072. X    if (uflg && user_id == user_newid)
  2073. X        uflg = oflg = 0;
  2074. X
  2075. X    if (lflg && getpwnam (user_newname)) {
  2076. X        fprintf (stderr, "%s: user %s exists\n", Prog, user_newname);
  2077. X        exit (9);
  2078. X    }
  2079. X}
  2080. X
  2081. X/*
  2082. X * close_files - close all of the files that were opened
  2083. X *
  2084. X *    close_files() closes all of the files that were opened for this
  2085. X *    new user.  This causes any modified entries to be written out.
  2086. X */
  2087. X
  2088. Xclose_files ()
  2089. X{
  2090. X    if (! pw_close ()) {
  2091. X        fprintf (stderr, "%s: cannot rewrite password file\n", Prog);
  2092. X        fail_exit (1);
  2093. X    }
  2094. X#ifdef    SHADOWPWD
  2095. X    if (! spw_close ()) {
  2096. X        fprintf (stderr, "%s: cannot rewrite shadow password file\n",    
  2097. X            Prog);
  2098. X        fail_exit (1);
  2099. X    }
  2100. X#endif
  2101. X    if (user_ngroups >= 0) {
  2102. X        if (! gr_close ()) {
  2103. X            fprintf (stderr, "%s: cannot rewrite group file\n",
  2104. X                Prog);
  2105. X            fail_exit (1);
  2106. X        }
  2107. X    }
  2108. X    (void) gr_unlock ();
  2109. X#ifdef    SHADOWGRP
  2110. X    if (user_ngroups >= 0) {
  2111. X        if (! sgr_close ()) {
  2112. X            fprintf (stderr, "%s: cannot rewrite shadow group file\n",
  2113. X                Prog);
  2114. X            fail_exit (1);
  2115. X        }
  2116. X    }
  2117. X    (void) sgr_unlock ();
  2118. X#endif
  2119. X    (void) spw_unlock ();
  2120. X    (void) pw_unlock ();
  2121. X
  2122. X    /*
  2123. X     * Close the DBM and/or flat files
  2124. X     */
  2125. X
  2126. X    endpwent ();
  2127. X#ifdef    SHADOWPWD
  2128. X    endspent ();
  2129. X#endif
  2130. X    endgrent ();
  2131. X#ifdef    SHADOWGRP
  2132. X    endsgent ();
  2133. X#endif
  2134. X}
  2135. X
  2136. X/*
  2137. X * open_files - lock and open the password files
  2138. X *
  2139. X *    open_files() opens the two password files.
  2140. X */
  2141. X
  2142. Xopen_files ()
  2143. X{
  2144. X    if (! pw_lock ()) {
  2145. X        fprintf (stderr, "%s: unable to lock password file\n", Prog);
  2146. X        exit (1);
  2147. X    }
  2148. X    if (! pw_open (O_RDWR)) {
  2149. X        fprintf (stderr, "%s: unable to open password file\n", Prog);
  2150. X        fail_exit (1);
  2151. X    }
  2152. X#ifdef    SHADOWPWD
  2153. X    if (! spw_lock ()) {
  2154. X        fprintf (stderr, "%s: cannot lock shadow password file\n",
  2155. X            Prog);
  2156. X        fail_exit (1);
  2157. X    }
  2158. X    if (! spw_open (O_RDWR)) {
  2159. X        fprintf (stderr, "%s: cannot open shadow password file\n",
  2160. X            Prog);
  2161. X        fail_exit (1);
  2162. X    }
  2163. X#endif
  2164. X}
  2165. X
  2166. X/*
  2167. X * usr_update - create the user entries
  2168. X *
  2169. X *    usr_update() creates the password file entries for this user
  2170. X *    and will update the group entries if required.
  2171. X */
  2172. X
  2173. Xusr_update ()
  2174. X{
  2175. X    struct    passwd    pwent;
  2176. X    struct    passwd    *pwd;
  2177. X#ifdef    SHADOWPWD
  2178. X    struct    spwd    spent;
  2179. X    struct    spwd    *spwd;
  2180. X#endif
  2181. X    char    old_auth[BUFSIZ];
  2182. X    char    auth_buf[BUFSIZ];
  2183. X
  2184. X    old_auth[0] = '\0';
  2185. X
  2186. X    /*
  2187. X     * Locate the entry in /etc/passwd, which MUST exist.
  2188. X     */
  2189. X
  2190. X    pwd = pw_locate (user_name);
  2191. X    pwent = *pwd;
  2192. X    new_pwent (&pwent);
  2193. X
  2194. X#ifdef    SHADOWPWD
  2195. X
  2196. X    /* 
  2197. X     * Locate the entry in /etc/shadow.  It doesn't have to
  2198. X     * exist, and won't be created if it doesn't.
  2199. X     */
  2200. X
  2201. X    if (spwd = spw_locate (user_name)) {
  2202. X        spent = *spwd;
  2203. X        new_spent (&spent);
  2204. X        strcpy (old_auth, spent.sp_pwdp);
  2205. X    } else {
  2206. X        strcpy (old_auth, pwent.pw_passwd);
  2207. X    }
  2208. X#else
  2209. X    strcpy (old_auth, pwent.pw_passwd);
  2210. X#endif
  2211. X    if (lflg || (Aflg && strcmp (old_auth, user_auth) != 0)) {
  2212. X        convert_auth (user_auth, old_auth, auth_arg);
  2213. X        delete_auths (old_auth, user_auth, auth_buf);
  2214. X        if (auth_buf[0] && pw_auth (auth_buf, user_name,
  2215. X                PW_DELETE, 0)) {
  2216. X            fprintf (stderr,
  2217. X                "%s: error deleting authentication method\n",
  2218. X                Prog);
  2219. X#ifdef    USE_SYSLOG
  2220. X            syslog (LOG_ERR, "error deleting auth for `%s'\n",
  2221. X                user_name);
  2222. X#endif
  2223. X            fail_exit (1);
  2224. X        }
  2225. X        add_auths (old_auth, user_auth, auth_buf);
  2226. X        if (auth_buf[0] == '@' && pw_auth (auth_buf,
  2227. X                lflg ? user_newname:user_name, PW_ADD, 0)) {
  2228. X            fprintf (stderr,
  2229. X                "%s: error adding authentication method\n",
  2230. X                Prog);
  2231. X#ifdef    USE_SYSLOG
  2232. X            syslog (LOG_ERR, "error adding auth for `%s'\n",
  2233. X                lflg ? user_newname:user_name);
  2234. X#endif
  2235. X            fail_exit (1);
  2236. X        }
  2237. X        update_auths (old_auth, user_auth, auth_buf);
  2238. X        if (lflg && auth_buf[0] == '@' && pw_auth (auth_buf,
  2239. X                user_newname, PW_CHANGE, user_name)) {
  2240. X            fprintf (stderr,
  2241. X                "%s: error changing authentication method\n",
  2242. X                Prog);
  2243. X#ifdef    USE_SYSLOG
  2244. X            syslog (LOG_ERR, "error changing auth for `%s'\n",
  2245. X                lflg ? user_newname:user_name);
  2246. X#endif
  2247. X            fail_exit (1);
  2248. X        }
  2249. X#ifdef    SHADOWPWD
  2250. X        spent.sp_pwdp = user_auth;
  2251. X#else
  2252. X        pwent.pw_passwd = user_auth;
  2253. X#endif
  2254. X    }
  2255. X    if (lflg || uflg || gflg || cflg || dflg || sflg || Aflg) {
  2256. X        if (! pw_update (&pwent)) {
  2257. X            fprintf (stderr, "%s: error changing password entry\n",
  2258. X                Prog);
  2259. X            fail_exit (1);
  2260. X        }
  2261. X        if (lflg && ! pw_remove (user_name)) {
  2262. X            fprintf (stderr, "%s: error removing password entry\n",
  2263. X                Prog);
  2264. X            fail_exit (1);
  2265. X        }
  2266. X#if defined(DBM) || defined(NDBM)
  2267. X        if (access ("/etc/passwd.pag", 0) == 0) {
  2268. X            if (! pw_dbm_update (&pwent)) {
  2269. X                fprintf (stderr,
  2270. X                    "%s: error adding password dbm entry\n",
  2271. X                    Prog);
  2272. X                fail_exit (1);
  2273. X            }
  2274. X            if (lflg && (pwd = getpwnam (user_name)) &&
  2275. X                    ! pw_dbm_remove (pwd)) {
  2276. X                fprintf (stderr,
  2277. X                    "%s: error removing passwd dbm entry\n",
  2278. X                    Prog);
  2279. X                fail_exit (1);
  2280. X            }
  2281. X        }
  2282. X#endif
  2283. X    }
  2284. X#ifdef    SHADOWPWD
  2285. X    if (spwd && (lflg || eflg || fflg || Aflg)) {
  2286. X        if (! spw_update (&spent)) {
  2287. X            fprintf (stderr,
  2288. X                "%s: error adding new shadow password entry\n",
  2289. X                Prog);
  2290. X            fail_exit (1);
  2291. X        }
  2292. X        if (lflg && ! spw_remove (user_name)) {
  2293. X            fprintf (stderr,
  2294. X                "%s: error removing shadow password entry\n",
  2295. X                Prog);
  2296. X            fail_exit (1);
  2297. X        }
  2298. X    }
  2299. X#ifdef    NDBM
  2300. X    if (spwd && access ("/etc/shadow.pag", 0) == 0) {
  2301. X        if (! sp_dbm_update (&spent)) {
  2302. X            fprintf (stderr,
  2303. X                "%s: error updating shadow passwd dbm entry\n",
  2304. X                Prog);
  2305. X            fail_exit (1);
  2306. X        }
  2307. X        if (lflg && ! sp_dbm_remove (user_name)) {
  2308. X            fprintf (stderr,
  2309. X                "%s: error removing shadow passwd db entry\n",
  2310. X                Prog);
  2311. X            fail_exit (1);
  2312. X        }
  2313. X    }
  2314. X#endif    /* NDBM */
  2315. X#endif    /* SHADOWPWD */
  2316. X    if (Gflg || lflg)
  2317. X        grp_update ();
  2318. X}
  2319. X
  2320. X/*
  2321. X * move_home - move the user's home directory
  2322. X *
  2323. X *    move_home() moves the user's home directory to a new location.
  2324. X *    The files will be copied if the directory cannot simply be
  2325. X *    renamed.
  2326. X */
  2327. X
  2328. Xmove_home ()
  2329. X{
  2330. X    struct    stat    sb;
  2331. X
  2332. X    if (mflg && stat (user_home, &sb) == 0) {
  2333. X        if (access (user_newhome, 0) == 0) {
  2334. X            fprintf (stderr, "%s: directory %s exists\n",
  2335. X                Prog, user_newhome);
  2336. X            fail_exit (12);
  2337. X        } else if (rename (user_home, user_newhome)) {
  2338. X            if (errno == EXDEV) {
  2339. X                if (mkdir (user_newhome, sb.st_mode & 0777)) {
  2340. X                    fprintf (stderr,
  2341. X                        "%s: can't create %s\n",
  2342. X                        Prog, user_newhome);
  2343. X                }
  2344. X                if (chown (user_newhome,
  2345. X                        sb.st_uid, sb.st_gid)) {
  2346. X                    fprintf (stderr, "%s: can't chown %s\n",
  2347. X                        Prog, user_newhome);
  2348. X                    rmdir (user_newhome);
  2349. X                    fail_exit (12);
  2350. X                }
  2351. X#ifdef    DIR_ANY
  2352. X                if (copy_tree (user_home, user_newhome,
  2353. X                        uflg ? user_newid:-1,
  2354. X                        gflg ? user_newgid:-1,
  2355. X                        user_id, user_gid) == 0 &&
  2356. X                    remove_tree (user_home) == 0 &&
  2357. X                        rmdir (user_home) == 0)
  2358. X                    return;
  2359. X
  2360. X                (void) remove_tree (user_newhome);
  2361. X                (void) rmdir (user_newhome);
  2362. X#else
  2363. X                return;
  2364. X#endif
  2365. X            }
  2366. X            fprintf (stderr,
  2367. X                "%s: cannot rename directory %s to %s\n",
  2368. X                Prog, user_home, user_newhome);
  2369. X            fail_exit (12);
  2370. X        }
  2371. X    }
  2372. X    if (uflg || gflg)
  2373. X        chown (dflg ? user_newhome:user_home,
  2374. X            uflg ? user_newid:user_id,
  2375. X            gflg ? user_newgid:user_gid);
  2376. X}
  2377. X
  2378. X/*
  2379. X * update_files - update the lastlog and faillog files
  2380. X */
  2381. X
  2382. Xvoid
  2383. Xupdate_files ()
  2384. X{
  2385. X    struct    lastlog    ll;
  2386. X    struct    faillog    fl;
  2387. X    int    fd;
  2388. X
  2389. X    /*
  2390. X     * Relocate the "lastlog" entries for the user.  The old entry
  2391. X     * is left alone in case the UID was shared.  It doesn't hurt
  2392. X     * anything to just leave it be.
  2393. X     */
  2394. X
  2395. X    if ((fd = open ("/usr/adm/lastlog", O_RDWR)) != -1) {
  2396. X        lseek (fd, (long) user_id * sizeof ll, 0);
  2397. X        if (read (fd, &ll, sizeof ll) == sizeof ll) {
  2398. X            lseek (fd, (long) user_newid * sizeof ll, 0);
  2399. X            write (fd, &ll, sizeof ll);
  2400. X        }
  2401. X        close (fd);
  2402. X    }
  2403. X
  2404. X    /*
  2405. X     * Relocate the "faillog" entries in the same manner.
  2406. X     */
  2407. X
  2408. X    if ((fd = open (FAILFILE, O_RDWR)) != -1) {
  2409. X        lseek (fd, (long) user_id * sizeof fl, 0);
  2410. X        if (read (fd, &fl, sizeof fl) == sizeof fl) {
  2411. X            lseek (fd, (long) user_newid * sizeof ll, 0);
  2412. X            write (fd, &fl, sizeof fl);
  2413. X        }
  2414. X        close (fd);
  2415. X    }
  2416. X}
  2417. X
  2418. X/*
  2419. X * fail_exit - exit with an error code after unlocking files
  2420. X */
  2421. X
  2422. Xfail_exit (code)
  2423. Xint    code;
  2424. X{
  2425. X    (void) gr_unlock ();
  2426. X#ifdef    SHADOWGRP
  2427. X    (void) sgr_unlock ();
  2428. X#endif
  2429. X#ifdef    SHADOWPWD
  2430. X    (void) spw_unlock ();
  2431. X#endif
  2432. X    (void) pw_unlock ();
  2433. X    exit (code);
  2434. X}
  2435. X
  2436. X/*
  2437. X * main - usermod command
  2438. X */
  2439. X
  2440. Xmain (argc, argv)
  2441. Xint    argc;
  2442. Xchar    **argv;
  2443. X{
  2444. X    /*
  2445. X     * Get my name so that I can use it to report errors.
  2446. X     */
  2447. X
  2448. X    if (Prog = strrchr (argv[0], '/'))
  2449. X        Prog++;
  2450. X    else
  2451. X        Prog = argv[0];
  2452. X
  2453. X#ifdef    USE_SYSLOG
  2454. X    openlog (Prog, LOG_PID|LOG_CONS|LOG_NOWAIT, LOG_AUTH);
  2455. X#endif
  2456. X
  2457. X    /*
  2458. X     * The open routines for the NDBM files don't use read-write
  2459. X     * as the mode, so we have to clue them in.
  2460. X     */
  2461. X
  2462. X#ifdef    NDBM
  2463. X    pw_dbm_mode = O_RDWR;
  2464. X#ifdef    SHADOWPWD
  2465. X    sp_dbm_mode = O_RDWR;
  2466. X#endif
  2467. X    gr_dbm_mode = O_RDWR;
  2468. X#ifdef    SHADOWGRP
  2469. X    sg_dbm_mode = O_RDWR;
  2470. X#endif
  2471. X#endif    /* NDBM */
  2472. X    process_flags (argc, argv);
  2473. X
  2474. X    /*
  2475. X     * Do the hard stuff - open the files, change the user entries,
  2476. X     * change the home directory, then close and update the files.
  2477. X     */
  2478. X
  2479. X    open_files ();
  2480. X
  2481. X    usr_update ();
  2482. X
  2483. X    close_files ();
  2484. X
  2485. X    if (mflg)
  2486. X        move_home ();
  2487. X
  2488. X    if (uflg) {
  2489. X        update_files ();
  2490. X
  2491. X        /*
  2492. X         * Change the UID on all of the files owned by `user_id'
  2493. X         * to `user_newid' in the user's home directory.
  2494. X         */
  2495. X
  2496. X        chown_tree (dflg ? user_newhome:user_home,
  2497. X            user_id, user_newid,
  2498. X            user_gid, gflg ? user_newgid:user_gid);
  2499. X    }
  2500. X    exit (0);
  2501. X    /*NOTREACHED*/
  2502. X}
  2503. END_OF_FILE
  2504.   if test 35799 -ne `wc -c <'usermod.c'`; then
  2505.     echo shar: \"'usermod.c'\" unpacked with wrong size!
  2506.   fi
  2507.   # end of 'usermod.c'
  2508. fi
  2509. echo shar: End of archive 2 \(of 14\).
  2510. cp /dev/null ark2isdone
  2511. MISSING=""
  2512. for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 ; do
  2513.     if test ! -f ark${I}isdone ; then
  2514.     MISSING="${MISSING} ${I}"
  2515.     fi
  2516. done
  2517. if test "${MISSING}" = "" ; then
  2518.     echo You have unpacked all 14 archives.
  2519.     rm -f ark[1-9]isdone ark[1-9][0-9]isdone
  2520. else
  2521.     echo You still must unpack the following archives:
  2522.     echo "        " ${MISSING}
  2523. fi
  2524. exit 0
  2525. exit 0 # Just in case...
  2526.