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