Guest User

Untitled

a guest
Mar 12th, 2018
259
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 23.51 KB | None | 0 0
  1. #!/bin/sh
  2. #
  3. # Copyright (c) 2002-2004 Michael Telahun Makonnen. All rights reserved.
  4. #
  5. # Redistribution and use in source and binary forms, with or without
  6. # modification, are permitted provided that the following conditions
  7. # are met:
  8. # 1. Redistributions of source code must retain the above copyright
  9. # notice, this list of conditions and the following disclaimer.
  10. # 2. Redistributions in binary form must reproduce the above copyright
  11. # notice, this list of conditions and the following disclaimer in the
  12. # documentation and/or other materials provided with the distribution.
  13. #
  14. # THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  15. # IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  16. # OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  17. # IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
  18. # INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  19. # NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  20. # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  21. # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  22. # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  23. # THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  24. #
  25. # Email: Mike Makonnen <mtm@FreeBSD.Org>
  26. #
  27. # $FreeBSD: src/usr.sbin/adduser/adduser.sh,v 1.30.2.2.4.1 2009/04/15 03:14:26 kensmith Exp $
  28. #
  29.  
  30. # err msg
  31. # Display $msg on stderr, unless we're being quiet.
  32. #
  33. err() {
  34. if [ -z "$quietflag" ]; then
  35. echo 1>&2 ${THISCMD}: ERROR: $*
  36. fi
  37. }
  38.  
  39. # info msg
  40. # Display $msg on stdout, unless we're being quiet.
  41. #
  42. info() {
  43. if [ -z "$quietflag" ]; then
  44. echo ${THISCMD}: INFO: $*
  45. fi
  46. }
  47.  
  48. # get_nextuid
  49. # Output the value of $_uid if it is available for use. If it
  50. # is not, output the value of the next higher uid that is available.
  51. # If a uid is not specified, output the first available uid, as indicated
  52. # by pw(8).
  53. #
  54. get_nextuid () {
  55. _uid=$1
  56. _nextuid=
  57.  
  58. if [ -z "$_uid" ]; then
  59. _nextuid="`${PWCMD} usernext | cut -f1 -d:`"
  60. else
  61. while : ; do
  62. ${PWCMD} usershow $_uid > /dev/null 2>&1
  63. if [ ! "$?" -eq 0 ]; then
  64. _nextuid=$_uid
  65. break
  66. fi
  67. _uid=$(($_uid + 1))
  68. done
  69. fi
  70. echo $_nextuid
  71. }
  72.  
  73. # show_usage
  74. # Display usage information for this utility.
  75. #
  76. show_usage() {
  77. echo "usage: ${THISCMD} [options]"
  78. echo " options may include:"
  79. echo " -C save to the configuration file only"
  80. echo " -D do not attempt to create the home directory"
  81. echo " -E disable this account after creation"
  82. echo " -G additional groups to add accounts to"
  83. echo " -L login class of the user"
  84. echo " -M file permission for home directory"
  85. echo " -N do not read configuration file"
  86. echo " -S a nonexistent shell is not an error"
  87. echo " -d home directory"
  88. echo " -f file from which input will be received"
  89. echo " -g default login group"
  90. echo " -h display this usage message"
  91. echo " -k path to skeleton home directory"
  92. echo " -m user welcome message file"
  93. echo " -q absolute minimal user feedback"
  94. echo " -s shell"
  95. echo " -u uid to start at"
  96. echo " -w password type: no, none, yes or random"
  97. }
  98.  
  99. # valid_shells
  100. # Outputs a list of valid shells from /etc/shells. Only the
  101. # basename of the shell is output.
  102. #
  103. valid_shells() {
  104. _prefix=
  105. cat ${ETCSHELLS} |
  106. while read _path _junk ; do
  107. case $_path in
  108. \#*|'')
  109. ;;
  110. *)
  111. /bin/echo -n "${_prefix}`basename $_path`"
  112. _prefix=' '
  113. ;;
  114. esac
  115. done
  116.  
  117. # /sbin/nologin is a special case
  118. [ -x "${NOLOGIN_PATH}" ] && /bin/echo -n " ${NOLOGIN}"
  119. }
  120.  
  121. # fullpath_from_shell shell
  122. # Given $shell, which is either the full path to a shell or
  123. # the basename component of a valid shell, get the
  124. # full path to the shell from the /etc/shells file.
  125. #
  126. fullpath_from_shell() {
  127. _shell=$1
  128. [ -z "$_shell" ] && return 1
  129.  
  130. # /sbin/nologin is a special case; it needs to be handled
  131. # before the cat | while loop, since a 'return' from within
  132. # a subshell will not terminate the function's execution, and
  133. # the path to the nologin shell might be printed out twice.
  134. #
  135. if [ "$_shell" = "${NOLOGIN}" -o \
  136. "$_shell" = "${NOLOGIN_PATH}" ]; then
  137. echo ${NOLOGIN_PATH}
  138. return 0;
  139. fi
  140.  
  141. cat ${ETCSHELLS} |
  142. while read _path _junk ; do
  143. case "$_path" in
  144. \#*|'')
  145. ;;
  146. *)
  147. if [ "$_path" = "$_shell" -o \
  148. "`basename $_path`" = "$_shell" ]; then
  149. echo $_path
  150. return 0
  151. fi
  152. ;;
  153. esac
  154. done
  155.  
  156. return 1
  157. }
  158.  
  159. # shell_exists shell
  160. # If the given shell is listed in ${ETCSHELLS} or it is
  161. # the nologin shell this function will return 0.
  162. # Otherwise, it will return 1. If shell is valid but
  163. # the path is invalid or it is not executable it
  164. # will emit an informational message saying so.
  165. #
  166. shell_exists()
  167. {
  168. _sh="$1"
  169. _shellchk="${GREPCMD} '^$_sh$' ${ETCSHELLS} > /dev/null 2>&1"
  170.  
  171. if ! eval $_shellchk; then
  172. # The nologin shell is not listed in /etc/shells.
  173. if [ "$_sh" != "${NOLOGIN_PATH}" ]; then
  174. err "Invalid shell ($_sh) for user $username."
  175. return 1
  176. fi
  177. fi
  178. ! [ -x "$_sh" ] &&
  179. info "The shell ($_sh) does not exist or is not executable."
  180.  
  181. return 0
  182. }
  183.  
  184. # save_config
  185. # Save some variables to a configuration file.
  186. # Note: not all script variables are saved, only those that
  187. # it makes sense to save.
  188. #
  189. save_config() {
  190. echo "# Configuration file for adduser(8)." > ${ADDUSERCONF}
  191. echo "# NOTE: only *some* variables are saved." >> ${ADDUSERCONF}
  192. echo "# Last Modified on `${DATECMD}`." >> ${ADDUSERCONF}
  193. echo '' >> ${ADDUSERCONF}
  194. echo "defaultHomePerm=$uhomeperm" >> ${ADDUSERCONF}
  195. echo "defaultLgroup=$ulogingroup" >> ${ADDUSERCONF}
  196. echo "defaultclass=$uclass" >> ${ADDUSERCONF}
  197. echo "defaultgroups=$ugroups" >> ${ADDUSERCONF}
  198. echo "passwdtype=$passwdtype" >> ${ADDUSERCONF}
  199. echo "homeprefix=$homeprefix" >> ${ADDUSERCONF}
  200. echo "defaultshell=$ushell" >> ${ADDUSERCONF}
  201. echo "udotdir=$udotdir" >> ${ADDUSERCONF}
  202. echo "msgfile=$msgfile" >> ${ADDUSERCONF}
  203. echo "disableflag=$disableflag" >> ${ADDUSERCONF}
  204. echo "uidstart=$uidstart" >> ${ADDUSERCONF}
  205. }
  206.  
  207. # add_user
  208. # Add a user to the user database. If the user chose to send a welcome
  209. # message or lock the account, do so.
  210. #
  211. add_user() {
  212.  
  213. # Is this a configuration run? If so, don't modify user database.
  214. #
  215. if [ -n "$configflag" ]; then
  216. save_config
  217. return
  218. fi
  219.  
  220. _uid=
  221. _name=
  222. _comment=
  223. _gecos=
  224. _home=
  225. _group=
  226. _grouplist=
  227. _shell=
  228. _class=
  229. _dotdir=
  230. _expire=
  231. _pwexpire=
  232. _passwd=
  233. _upasswd=
  234. _passwdmethod=
  235.  
  236. _name="-n '$username'"
  237. [ -n "$uuid" ] && _uid='-u "$uuid"'
  238. [ -n "$ulogingroup" ] && _group='-g "$ulogingroup"'
  239. [ -n "$ugroups" ] && _grouplist='-G "$ugroups"'
  240. [ -n "$ushell" ] && _shell='-s "$ushell"'
  241. [ -n "$uclass" ] && _class='-L "$uclass"'
  242. [ -n "$ugecos" ] && _comment='-c "$ugecos"'
  243. [ -n "$udotdir" ] && _dotdir='-k "$udotdir"'
  244. [ -n "$uexpire" ] && _expire='-e "$uexpire"'
  245. [ -n "$upwexpire" ] && _pwexpire='-p "$upwexpire"'
  246. if [ -z "$Dflag" -a -n "$uhome" ]; then
  247. # The /nonexistent home directory is special. It
  248. # means the user has no home directory.
  249. if [ "$uhome" = "$NOHOME" ]; then
  250. _home='-d "$uhome"'
  251. else
  252. # Use home directory permissions if specified
  253. if [ -n "$uhomeperm" ]; then
  254. _home='-m -d "$uhome" -M "$uhomeperm"'
  255. else
  256. _home='-m -d "$uhome"'
  257. fi
  258. fi
  259. elif [ -n "$Dflag" -a -n "$uhome" ]; then
  260. _home='-d "$uhome"'
  261. fi
  262. case $passwdtype in
  263. no)
  264. _passwdmethod="-w no"
  265. _passwd="-h -"
  266. ;;
  267. yes)
  268. # Note on processing the password: The outer double quotes
  269. # make literal everything except ` and \ and $.
  270. # The outer single quotes make literal ` and $.
  271. # We can ensure the \ isn't treated specially by specifying
  272. # the -r switch to the read command used to obtain the input.
  273. #
  274. _passwdmethod="-w yes"
  275. _passwd="-h 0"
  276. _upasswd='echo "$upass" |'
  277. ;;
  278. none)
  279. _passwdmethod="-w none"
  280. ;;
  281. random)
  282. _passwdmethod="-w random"
  283. ;;
  284. esac
  285.  
  286. _pwcmd="$_upasswd ${PWCMD} useradd $_uid $_name $_group $_grouplist $_comment"
  287. _pwcmd="$_pwcmd $_shell $_class $_home $_dotdir $_passwdmethod $_passwd"
  288. _pwcmd="$_pwcmd $_expire $_pwexpire"
  289.  
  290. if ! _output=`eval $_pwcmd` ; then
  291. err "There was an error adding user ($username)."
  292. return 1
  293. else
  294. info "Successfully added ($username) to the user database."
  295. if [ "random" = "$passwdtype" ]; then
  296. randompass="$_output"
  297. info "Password for ($username) is: $randompass"
  298. fi
  299. fi
  300.  
  301. if [ -n "$disableflag" ]; then
  302. if ${PWCMD} lock $username ; then
  303. info "Account ($username) is locked."
  304. else
  305. info "Account ($username) could NOT be locked."
  306. fi
  307. fi
  308.  
  309. _line=
  310. _owner=
  311. _perms=
  312. if [ -n "$msgflag" ]; then
  313. [ -r "$msgfile" ] && {
  314. # We're evaluating the contents of an external file.
  315. # Let's not open ourselves up for attack. _perms will
  316. # be empty if it's writeable only by the owner. _owner
  317. # will *NOT* be empty if the file is owned by root.
  318. #
  319. _dir="`dirname $msgfile`"
  320. _file="`basename $msgfile`"
  321. _perms=`/usr/bin/find $_dir -name $_file -perm +07022 -prune`
  322. _owner=`/usr/bin/find $_dir -name $_file -user 0 -prune`
  323. if [ -z "$_owner" -o -n "$_perms" ]; then
  324. err "The message file ($msgfile) may be writeable only by root."
  325. return 1
  326. fi
  327. cat "$msgfile" |
  328. while read _line ; do
  329. eval echo "$_line"
  330. done | ${MAILCMD} -s"Welcome" ${username}
  331. info "Sent welcome message to ($username)."
  332. }
  333. fi
  334. }
  335.  
  336. # get_user
  337. # Reads username of the account from standard input or from a global
  338. # variable containing an account line from a file. The username is
  339. # required. If this is an interactive session it will prompt in
  340. # a loop until a username is entered. If it is batch processing from
  341. # a file it will output an error message and return to the caller.
  342. #
  343. get_user() {
  344. _input=
  345.  
  346. # No need to take down user names if this is a configuration saving run.
  347. [ -n "$configflag" ] && return
  348.  
  349. while : ; do
  350. if [ -z "$fflag" ]; then
  351. /bin/echo -n "Username: "
  352. read _input
  353. else
  354. _input="`echo "$fileline" | cut -f1 -d:`"
  355. fi
  356.  
  357. # There *must* be a username, and it must not exist. If
  358. # this is an interactive session give the user an
  359. # opportunity to retry.
  360. #
  361. if [ -z "$_input" ]; then
  362. err "You must enter a username!"
  363. [ -z "$fflag" ] && continue
  364. fi
  365. ${PWCMD} usershow $_input > /dev/null 2>&1
  366. if [ "$?" -eq 0 ]; then
  367. err "User exists!"
  368. [ -z "$fflag" ] && continue
  369. fi
  370. break
  371. done
  372. username="$_input"
  373. }
  374.  
  375. # get_gecos
  376. # Reads extra information about the user. Can be used both in interactive
  377. # and batch (from file) mode.
  378. #
  379. get_gecos() {
  380. _input=
  381.  
  382. # No need to take down additional user information for a configuration run.
  383. [ -n "$configflag" ] && return
  384.  
  385. if [ -z "$fflag" ]; then
  386. /bin/echo -n "Full name: "
  387. read _input
  388. else
  389. _input="`echo "$fileline" | cut -f7 -d:`"
  390. fi
  391. ugecos="$_input"
  392. }
  393.  
  394. # get_shell
  395. # Get the account's shell. Works in interactive and batch mode. It
  396. # accepts either the base name of the shell or the full path.
  397. # If an invalid shell is entered it will simply use the default shell.
  398. #
  399. get_shell() {
  400. _input=
  401. _fullpath=
  402. ushell="$defaultshell"
  403.  
  404. # Make sure the current value of the shell is a valid one
  405. if [ -z "$Sflag" ]; then
  406. if ! shell_exists $ushell ; then
  407. info "Using default shell ${defaultshell}."
  408. ushell="$defaultshell"
  409. fi
  410. fi
  411.  
  412. if [ -z "$fflag" ]; then
  413. /bin/echo -n "Shell ($shells) [`basename $ushell`]: "
  414. read _input
  415. else
  416. _input="`echo "$fileline" | cut -f9 -d:`"
  417. fi
  418. if [ -n "$_input" ]; then
  419. if [ -n "$Sflag" ]; then
  420. ushell="$_input"
  421. else
  422. _fullpath=`fullpath_from_shell $_input`
  423. if [ -n "$_fullpath" ]; then
  424. ushell="$_fullpath"
  425. else
  426. err "Invalid shell ($_input) for user $username."
  427. info "Using default shell ${defaultshell}."
  428. ushell="$defaultshell"
  429. fi
  430. fi
  431. fi
  432. }
  433.  
  434. # get_homedir
  435. # Reads the account's home directory. Used both with interactive input
  436. # and batch input.
  437. #
  438. get_homedir() {
  439. _input=
  440. if [ -z "$fflag" ]; then
  441. /bin/echo -n "Home directory [${homeprefix}/${username}]: "
  442. read _input
  443. else
  444. _input="`echo "$fileline" | cut -f8 -d:`"
  445. fi
  446.  
  447. if [ -n "$_input" ]; then
  448. uhome="$_input"
  449. # if this is a configuration run, then user input is the home
  450. # directory prefix. Otherwise it is understood to
  451. # be $prefix/$user
  452. #
  453. [ -z "$configflag" ] && homeprefix="`dirname $uhome`" || homeprefix="$uhome"
  454. else
  455. uhome="${homeprefix}/${username}"
  456. fi
  457. }
  458.  
  459. # get_homeperm
  460. # Reads the account's home directory permissions.
  461. #
  462. get_homeperm() {
  463. uhomeperm=$defaultHomePerm
  464. _input=
  465. _prompt=
  466.  
  467. if [ -n "$uhomeperm" ]; then
  468. _prompt="Home directory permissions [${uhomeperm}]: "
  469. else
  470. _prompt="Home directory permissions (Leave empty for default): "
  471. fi
  472. if [ -z "$fflag" ]; then
  473. /bin/echo -n "$_prompt"
  474. read _input
  475. fi
  476.  
  477. if [ -n "$_input" ]; then
  478. uhomeperm="$_input"
  479. fi
  480. }
  481.  
  482. # get_uid
  483. # Reads a numeric userid in an interactive or batch session. Automatically
  484. # allocates one if it is not specified.
  485. #
  486. get_uid() {
  487. uuid=${uidstart}
  488. _input=
  489. _prompt=
  490.  
  491. if [ -n "$uuid" ]; then
  492. _prompt="Uid [$uuid]: "
  493. else
  494. _prompt="Uid (Leave empty for default): "
  495. fi
  496. if [ -z "$fflag" ]; then
  497. /bin/echo -n "$_prompt"
  498. read _input
  499. else
  500. _input="`echo "$fileline" | cut -f2 -d:`"
  501. fi
  502.  
  503. [ -n "$_input" ] && uuid=$_input
  504. uuid=`get_nextuid $uuid`
  505. uidstart=$uuid
  506. }
  507.  
  508. # get_class
  509. # Reads login class of account. Can be used in interactive or batch mode.
  510. #
  511. get_class() {
  512. uclass="$defaultclass"
  513. _input=
  514. _class=${uclass:-"default"}
  515.  
  516. if [ -z "$fflag" ]; then
  517. /bin/echo -n "Login class [$_class]: "
  518. read _input
  519. else
  520. _input="`echo "$fileline" | cut -f4 -d:`"
  521. fi
  522.  
  523. [ -n "$_input" ] && uclass="$_input"
  524. }
  525.  
  526. # get_logingroup
  527. # Reads user's login group. Can be used in both interactive and batch
  528. # modes. The specified value can be a group name or its numeric id.
  529. # This routine leaves the field blank if nothing is provided and
  530. # a default login group has not been set. The pw(8) command
  531. # will then provide a login group with the same name as the username.
  532. #
  533. get_logingroup() {
  534. ulogingroup="$defaultLgroup"
  535. _input=
  536.  
  537. if [ -z "$fflag" ]; then
  538. /bin/echo -n "Login group [${ulogingroup:-$username}]: "
  539. read _input
  540. else
  541. _input="`echo "$fileline" | cut -f3 -d:`"
  542. fi
  543.  
  544. # Pw(8) will use the username as login group if it's left empty
  545. [ -n "$_input" ] && ulogingroup="$_input"
  546. }
  547.  
  548. # get_groups
  549. # Read additional groups for the user. It can be used in both interactive
  550. # and batch modes.
  551. #
  552. get_groups() {
  553. ugroups="$defaultgroups"
  554. _input=
  555. _group=${ulogingroup:-"${username}"}
  556.  
  557. if [ -z "$configflag" ]; then
  558. [ -z "$fflag" ] && /bin/echo -n "Login group is $_group. Invite $username"
  559. [ -z "$fflag" ] && /bin/echo -n " into other groups? [$ugroups]: "
  560. else
  561. [ -z "$fflag" ] && /bin/echo -n "Enter additional groups [$ugroups]: "
  562. fi
  563. read _input
  564.  
  565. [ -n "$_input" ] && ugroups="$_input"
  566. }
  567.  
  568. # get_expire_dates
  569. # Read expiry information for the account and also for the password. This
  570. # routine is used only from batch processing mode.
  571. #
  572. get_expire_dates() {
  573. upwexpire="`echo "$fileline" | cut -f5 -d:`"
  574. uexpire="`echo "$fileline" | cut -f6 -d:`"
  575. }
  576.  
  577. # get_password
  578. # Read the password in batch processing mode. The password field matters
  579. # only when the password type is "yes" or "random". If the field is empty and the
  580. # password type is "yes", then it assumes the account has an empty passsword
  581. # and changes the password type accordingly. If the password type is "random"
  582. # and the password field is NOT empty, then it assumes the account will NOT
  583. # have a random password and set passwdtype to "yes."
  584. #
  585. get_password() {
  586. # We may temporarily change a password type. Make sure it's changed
  587. # back to whatever it was before we process the next account.
  588. #
  589. [ -n "$savedpwtype" ] && {
  590. passwdtype=$savedpwtype
  591. savedpwtype=
  592. }
  593.  
  594. # There may be a ':' in the password
  595. upass=${fileline#*:*:*:*:*:*:*:*:*:}
  596.  
  597. if [ -z "$upass" ]; then
  598. case $passwdtype in
  599. yes)
  600. # if it's empty, assume an empty password
  601. passwdtype=none
  602. savedpwtype=yes
  603. ;;
  604. esac
  605. else
  606. case $passwdtype in
  607. random)
  608. passwdtype=yes
  609. savedpwtype=random
  610. ;;
  611. esac
  612. fi
  613. }
  614.  
  615. # input_from_file
  616. # Reads a line of account information from standard input and
  617. # adds it to the user database.
  618. #
  619. input_from_file() {
  620. _field=
  621.  
  622. while read -r fileline ; do
  623. case "$fileline" in
  624. \#*|'')
  625. ;;
  626. *)
  627. get_user || continue
  628. get_gecos
  629. get_uid
  630. get_logingroup
  631. get_class
  632. get_shell
  633. get_homedir
  634. get_homeperm
  635. get_password
  636. get_expire_dates
  637. ugroups="$defaultgroups"
  638.  
  639. add_user
  640. ;;
  641. esac
  642. done
  643. }
  644.  
  645. # input_interactive
  646. # Prompts for user information interactively, and commits to
  647. # the user database.
  648. #
  649. input_interactive() {
  650.  
  651. _disable=
  652. _pass=
  653. _passconfirm=
  654. _random="no"
  655. _emptypass="no"
  656. _usepass="yes"
  657. _logingroup_ok="no"
  658. _groups_ok="no"
  659. case $passwdtype in
  660. none)
  661. _emptypass="yes"
  662. _usepass="yes"
  663. ;;
  664. no)
  665. _usepass="no"
  666. ;;
  667. random)
  668. _random="yes"
  669. ;;
  670. esac
  671.  
  672. get_user
  673. get_gecos
  674. get_uid
  675.  
  676. # The case where group = user is handled elsewhere, so
  677. # validate any other groups the user is invited to.
  678. until [ "$_logingroup_ok" = yes ]; do
  679. get_logingroup
  680. _logingroup_ok=yes
  681. if [ -n "$ulogingroup" -a "$username" != "$ulogingroup" ]; then
  682. if ! ${PWCMD} show group $ulogingroup > /dev/null 2>&1; then
  683. echo "Group $ulogingroup does not exist!"
  684. _logingroup_ok=no
  685. fi
  686. fi
  687. done
  688. until [ "$_groups_ok" = yes ]; do
  689. get_groups
  690. _groups_ok=yes
  691. for i in $ugroups; do
  692. if [ "$username" != "$i" ]; then
  693. if ! ${PWCMD} show group $i > /dev/null 2>&1; then
  694. echo "Group $i does not exist!"
  695. _groups_ok=no
  696. fi
  697. fi
  698. done
  699. done
  700.  
  701. get_class
  702. get_shell
  703. get_homedir
  704. get_homeperm
  705.  
  706. while : ; do
  707. /bin/echo -n "Use password-based authentication? [$_usepass]: "
  708. read _input
  709. [ -z "$_input" ] && _input=$_usepass
  710. case $_input in
  711. [Nn][Oo]|[Nn])
  712. passwdtype="no"
  713. ;;
  714. [Yy][Ee][Ss]|[Yy][Ee]|[Yy])
  715. while : ; do
  716. /bin/echo -n "Use an empty password? (yes/no) [$_emptypass]: "
  717. read _input
  718. [ -n "$_input" ] && _emptypass=$_input
  719. case $_emptypass in
  720. [Nn][Oo]|[Nn])
  721. /bin/echo -n "Use a random password? (yes/no) [$_random]: "
  722. read _input
  723. [ -n "$_input" ] && _random="$_input"
  724. case $_random in
  725. [Yy][Ee][Ss]|[Yy][Ee]|[Yy])
  726. passwdtype="random"
  727. break
  728. ;;
  729. esac
  730. passwdtype="yes"
  731. [ -n "$configflag" ] && break
  732. trap 'stty echo; exit' 0 1 2 3 15
  733. stty -echo
  734. /bin/echo -n "Enter password: "
  735. read -r upass
  736. echo''
  737. /bin/echo -n "Enter password again: "
  738. read -r _passconfirm
  739. echo ''
  740. stty echo
  741. # if user entered a blank password
  742. # explicitly ask again.
  743. [ -z "$upass" -a -z "$_passconfirm" ] \
  744. && continue
  745. ;;
  746. [Yy][Ee][Ss]|[Yy][Ee]|[Yy])
  747. passwdtype="none"
  748. break;
  749. ;;
  750. *)
  751. # invalid answer; repeat the loop
  752. continue
  753. ;;
  754. esac
  755. if [ "$upass" != "$_passconfirm" ]; then
  756. echo "Passwords did not match!"
  757. continue
  758. fi
  759. break
  760. done
  761. ;;
  762. *)
  763. # invalid answer; repeat loop
  764. continue
  765. ;;
  766. esac
  767. break;
  768. done
  769. _disable=${disableflag:-"no"}
  770. while : ; do
  771. /bin/echo -n "Lock out the account after creation? [$_disable]: "
  772. read _input
  773. [ -z "$_input" ] && _input=$_disable
  774. case $_input in
  775. [Nn][Oo]|[Nn])
  776. disableflag=
  777. ;;
  778. [Yy][Ee][Ss]|[Yy][Ee]|[Yy])
  779. disableflag=yes
  780. ;;
  781. *)
  782. # invalid answer; repeat loop
  783. continue
  784. ;;
  785. esac
  786. break
  787. done
  788.  
  789. # Display the information we have so far and prompt to
  790. # commit it.
  791. #
  792. _disable=${disableflag:-"no"}
  793. [ -z "$configflag" ] && printf "%-10s : %s\n" Username $username
  794. case $passwdtype in
  795. yes)
  796. _pass='*****'
  797. ;;
  798. no)
  799. _pass='<disabled>'
  800. ;;
  801. none)
  802. _pass='<blank>'
  803. ;;
  804. random)
  805. _pass='<random>'
  806. ;;
  807. esac
  808. [ -z "$configflag" ] && printf "%-10s : %s\n" "Password" "$_pass"
  809. [ -n "$configflag" ] && printf "%-10s : %s\n" "Pass Type" "$passwdtype"
  810. [ -z "$configflag" ] && printf "%-10s : %s\n" "Full Name" "$ugecos"
  811. [ -z "$configflag" ] && printf "%-10s : %s\n" "Uid" "$uuid"
  812. printf "%-10s : %s\n" "Class" "$uclass"
  813. printf "%-10s : %s %s\n" "Groups" "${ulogingroup:-$username}" "$ugroups"
  814. printf "%-10s : %s\n" "Home" "$uhome"
  815. printf "%-10s : %s\n" "Home Mode" "$uhomeperm"
  816. printf "%-10s : %s\n" "Shell" "$ushell"
  817. printf "%-10s : %s\n" "Locked" "$_disable"
  818. while : ; do
  819. /bin/echo -n "OK? (yes/no): "
  820. read _input
  821. case $_input in
  822. [Nn][Oo]|[Nn])
  823. return 1
  824. ;;
  825. [Yy][Ee][Ss]|[Yy][Ee]|[Yy])
  826. add_user
  827. ;;
  828. *)
  829. continue
  830. ;;
  831. esac
  832. break
  833. done
  834. return 0
  835. }
  836.  
  837. #### END SUBROUTINE DEFINITION ####
  838.  
  839. THISCMD=`/usr/bin/basename $0`
  840. DEFAULTSHELL=/bin/sh
  841. ADDUSERCONF="${ADDUSERCONF:-/etc/adduser.conf}"
  842. PWCMD="${PWCMD:-/usr/sbin/pw}"
  843. MAILCMD="${MAILCMD:-mail}"
  844. ETCSHELLS="${ETCSHELLS:-/etc/shells}"
  845. NOHOME="/nonexistent"
  846. NOLOGIN="nologin"
  847. NOLOGIN_PATH="/sbin/nologin"
  848. GREPCMD="/usr/bin/grep"
  849. DATECMD="/bin/date"
  850.  
  851. # Set default values
  852. #
  853. username=
  854. uuid=
  855. uidstart=
  856. ugecos=
  857. ulogingroup=
  858. uclass=
  859. uhome=
  860. uhomeperm=
  861. upass=
  862. ushell=
  863. udotdir=/usr/share/skel
  864. ugroups=
  865. uexpire=
  866. upwexpire=
  867. shells="`valid_shells`"
  868. passwdtype="yes"
  869. msgfile=/etc/adduser.msg
  870. msgflag=
  871. quietflag=
  872. configflag=
  873. fflag=
  874. infile=
  875. disableflag=
  876. Dflag=
  877. Sflag=
  878. readconfig="yes"
  879. homeprefix="/Users"
  880. randompass=
  881. fileline=
  882. savedpwtype=
  883. defaultclass=
  884. defaultLgroup=
  885. defaultgroups=
  886. defaultshell="${DEFAULTSHELL}"
  887. defaultHomePerm=
  888.  
  889. # Make sure the user running this program is root. This isn't a security
  890. # measure as much as it is a usefull method of reminding the user to
  891. # 'su -' before he/she wastes time entering data that won't be saved.
  892. #
  893. procowner=${procowner:-`/usr/bin/id -u`}
  894. if [ "$procowner" != "0" ]; then
  895. err 'you must be the super-user (uid 0) to use this utility.'
  896. exit 1
  897. fi
  898.  
  899. # Overide from our conf file
  900. # Quickly go through the commandline line to see if we should read
  901. # from our configuration file. The actual parsing of the commandline
  902. # arguments happens after we read in our configuration file (commandline
  903. # should override configuration file).
  904. #
  905. for _i in $* ; do
  906. if [ "$_i" = "-N" ]; then
  907. readconfig=
  908. break;
  909. fi
  910. done
  911. if [ -n "$readconfig" ]; then
  912. # On a long-lived system, the first time this script is run it
  913. # will barf upon reading the configuration file for its perl predecessor.
  914. if ( . ${ADDUSERCONF} > /dev/null 2>&1 ); then
  915. [ -r ${ADDUSERCONF} ] && . ${ADDUSERCONF} > /dev/null 2>&1
  916. fi
  917. fi
  918.  
  919. # Proccess command-line options
  920. #
  921. for _switch ; do
  922. case $_switch in
  923. -L)
  924. defaultclass="$2"
  925. shift; shift
  926. ;;
  927. -C)
  928. configflag=yes
  929. shift
  930. ;;
  931. -D)
  932. Dflag=yes
  933. shift
  934. ;;
  935. -E)
  936. disableflag=yes
  937. shift
  938. ;;
  939. -k)
  940. udotdir="$2"
  941. shift; shift
  942. ;;
  943. -f)
  944. [ "$2" != "-" ] && infile="$2"
  945. fflag=yes
  946. shift; shift
  947. ;;
  948. -g)
  949. defaultLgroup="$2"
  950. shift; shift
  951. ;;
  952. -G)
  953. defaultgroups="$2"
  954. shift; shift
  955. ;;
  956. -h)
  957. show_usage
  958. exit 0
  959. ;;
  960. -d)
  961. homeprefix="$2"
  962. shift; shift
  963. ;;
  964. -m)
  965. case "$2" in
  966. [Nn][Oo])
  967. msgflag=
  968. ;;
  969. *)
  970. msgflag=yes
  971. msgfile="$2"
  972. ;;
  973. esac
  974. shift; shift
  975. ;;
  976. -M)
  977. defaultHomePerm=$2
  978. shift; shift
  979. ;;
  980. -N)
  981. readconfig=
  982. shift
  983. ;;
  984. -w)
  985. case "$2" in
  986. no|none|random|yes)
  987. passwdtype=$2
  988. ;;
  989. *)
  990. show_usage
  991. exit 1
  992. ;;
  993. esac
  994. shift; shift
  995. ;;
  996. -q)
  997. quietflag=yes
  998. shift
  999. ;;
  1000. -s)
  1001. defaultshell="`fullpath_from_shell $2`"
  1002. shift; shift
  1003. ;;
  1004. -S)
  1005. Sflag=yes
  1006. shift
  1007. ;;
  1008. -u)
  1009. uidstart=$2
  1010. shift; shift
  1011. ;;
  1012. esac
  1013. done
  1014.  
  1015. # If the -f switch was used, get input from a file. Otherwise,
  1016. # this is an interactive session.
  1017. #
  1018. if [ -n "$fflag" ]; then
  1019. if [ -z "$infile" ]; then
  1020. input_from_file
  1021. elif [ -n "$infile" ]; then
  1022. if [ -r "$infile" ]; then
  1023. input_from_file < $infile
  1024. else
  1025. err "File ($infile) is unreadable or does not exist."
  1026. fi
  1027. fi
  1028. else
  1029. input_interactive
  1030. while : ; do
  1031. if [ -z "$configflag" ]; then
  1032. /bin/echo -n "Add another user? (yes/no): "
  1033. else
  1034. /bin/echo -n "Re-edit the default configuration? (yes/no): "
  1035. fi
  1036. read _input
  1037. case $_input in
  1038. [Yy][Ee][Ss]|[Yy][Ee]|[Yy])
  1039. uidstart=`get_nextuid $uidstart`
  1040. input_interactive
  1041. continue
  1042. ;;
  1043. [Nn][Oo]|[Nn])
  1044. echo "Goodbye!"
  1045. ;;
  1046. *)
  1047. continue
  1048. ;;
  1049. esac
  1050. break
  1051. done
  1052. fi
Add Comment
Please, Sign In to add comment