#!/bin/sh # # Copyright (c) AT&T 1998. All rights reserved. # @(#)setservername.sh 1.5 3/20/98 # textdomaindir=/opt/lanman/lib/locale textdomain='setservername' # # Function to run gettext with TEXTDOMAINDIR set. # TEXTDOMAINDIR is not set in the exported environment so subprocesses # do not inadvertently use it. # pgettext () { gttext=gettext #Trick to fool shgettext TEXTDOMAINDIR=${textdomaindir} ${gttext} ${textdomain} "$1" } # # These variables may be used immediately # FATAL_EXIT_CODE=1 # Used in messages Progname=`basename $0` # initialze the common shell variables LMPATHS="`/bin/dirname $0`/../lib/lmpaths" if [ -f ${LMPATHS} ] then . ${LMPATHS} else . lmpaths fi # # if not root then exit # id | grep root > $DEV_NULL_PATH 2>&1 if [ $? != 0 ] then eval echo "\"`pgettext 'You must be root to run ${Progname}.\n'`\"" exit ${FATAL_EXIT_CODE} fi #---------------------------------------------------------------------------- # Routines #---------------------------------------------------------------------------- # # Ask the user a question, return true(YES) if yes, false(NO) if no # NO=255 YES=0 NO_DEFAULT=2 yorn () { def=$1 shift while [ 1 ] do if [ $def = $NO ] then echo "$* [y/n]? n\b\c" elif [ $def = $YES ] then echo "$* [y/n]? y\b\c" else echo "$* [y/n]? \c" fi case `line` in y|Y|[yY][eE][sS]) return $YES ;; n|N|[nN][oO]) return $NO ;; '') if [ $def != $NO_DEFAULT ] then return $def fi pgettext "\tPlease respond with y(es) or n(o)\n" ;; *) pgettext "\tPlease respond with y(es) or n(o)\n" ;; esac done } #---------------------------------------------------------------------------- # # If the password is ok, return 0. # checkpw () { n=`echo "$1" | wc -c` if [ $n -gt 15 -o $n -lt 0 ] then pgettext "Password must be shorter than 15 characters.\n" return 1 else return 0 fi } #---------------------------------------------------------------------------- # # Get the password. # Globals: modifies AdminPW # getpw() { while [ 1 ] do echo "\n$1" stty -echo read pw checkpw $pw if [ $? -ne 0 ] then continue fi pgettext "\nRe-enter password: " read ANS2 stty echo if [ "$pw" != "$ANS2" ] then pgettext "\nPassword mismatch!\n" continue fi echo break done AdminPW=$pw } #---------------------------------------------------------------------------- # # usage - display more info for bdc than pdc # usage () { if [ "$Role" = "primary" ] then eval echo "\"`pgettext 'Usage: ${Progname} [ -n newname -a admin_account -p password ][ -s ]\n'`\"" pgettext " where:\n"\ " newname - the new name of this server\n"\ " admin_account - the name of the administrative account\n"\ " password - the password for the administrative account\n"\ " -s - the server is not started when this argument is set\n" else eval echo "\"`pgettext 'Usage: ${Progname} [ -n newname -a admin_account -p password -d pdc_name ][ -s ] '`\""\ pgettext "where: \n"\ " newname - the new name of this server\n"\ " admin_account - the name of the administrative account on the primary\n"\ " password - the password for the administrative account\n"\ " pdc_name - the name of the primary domain controller\n"\ " -s - the server is not started when this argument is set\n" fi exit 1 } #---------------------------------------------------------------------------- # # Check for a legal name. Return 0 if ok, 1 otherwise # usage: check_name name_to_check # check_name () { name=$1 if [ "$name" = "" ] then pgettext "You must select a server name.\n" return 1 fi # if no allowing uname as server name, can't be uname if [ "$ALLOW_UNAME_SERVER" != yes -a "$name" = "`uname -n`" ] then pgettext "The server name cannot be the system name.\n" pgettext "You must select a unique name.\n" return 1 fi # check name length namelen=`echo $name | wc -c` namelen=`expr $namelen - 1` if [ $namelen -gt 15 ] then pgettext "Server names must be 15 characters or less.\n" return 1 fi # check for valid character set len=`expr "$name" : "[$VALIDCH]*"` if [ "$len" -ne "$namelen" ] then pgettext "The server name contains invalid characters.\n" eval echo "\"`pgettext 'The valid characters are: ${VALIDCH}'`\"" return 1 fi # server name may not be the same as the domain name # test must be case insensitive. use sort since it honors locale locale="`$SRVCONFIG_PATH -g lmxserver,lang`" domain="`$SRVCONFIG_PATH -g workstation,domain`" count=`echo "$name\n$domain" | LC_CTYPE="$locale" sort -fu | wc -l` if [ "$count" -eq 1 ] then pgettext "The server name cannot be the same as the domain name.\n" return 1 fi return 0 } #---------------------------------------------------------------------------- # # Check the command line options. # Return 0 if no options (interactive mode), or 1 for non-interactive. # If invalid options or arguments, call usage(a). # # usage: check_commandline arg1 arg2 arg3 [arg4] # These args are those specified on the commandline. All args have values and # are of the form arg:val. # check_commandline () { # are there any commandline arguments? if [ "$1" = "" ] then return 0 else while getopts 'n:p:d:a:s?' c do case $c in n) Servername=$OPTARG;; p) AdminPW=$OPTARG;; d) Primary=$OPTARG;; a) Administrator=$OPTARG;; s) Autostart_flag=no;; \?) usage;; esac done check_name $Servername if [ $? -eq 1 ] then usage fi if [ -n "$Primary" ] then check_name $Primary if [ $? -eq 1 ] then usage fi fi checkpw $AdminPW if [ $? -eq 1 ] then usage fi # were all args specified? if [ "$Servername" = "" -o "$AdminPW" = "" \ -o "$Administrator" = "" ] then usage fi # PDC name is a required option when changing the BDC name if [ $Role = backup -a "$Primary" = "" ] then usage fi return 1 fi } #---------------------------------------------------------------------------- # # Initialize variables, perform startup checks. # Sets Role, Original_listenname, Original_servername, Administrator. # initialize () { # set global variables # The product name COMMENT="SunLink Server" # Valid characters for server name VALIDCH="--.a-zA-Z0-9~!#$%^&()_{}" # The variables needed to set the name Primary="" Servername="" AdminPW="" Administrator="administrator" ListenNameCheck=`$SRVCONFIG_PATH -g "lmxserver,listennamechk"` ListenExtension=`$SRVCONFIG_PATH -g "lmxserver,listenextension" | \ tr '[A-Z]' '[a-z]'` if [ -z "$ListenExtension" ] then ListenExtension=".serve" fi len=`echo $ListenExtension | wc -c` len=`expr 16 - $len` UnameDotServe="`uname -n | cut -c1-${len}`${ListenExtension}" # The current server name Original_listenname=`$SRVCONFIG_PATH -g "server,listenname"` if [ "$Original_listenname" = "" ] then # no entry was entered, name must be uname.serve Original_servername=$UnameDotServe else Original_servername=$Original_listenname fi # Role is used to issue role-specific messages, command-line args, etc. Role=`${GETROLE_PATH} -r | tr -d "\012"` # The accounts database may be VERY large; # Never run out of ulimit space ulimit 1000000 # is server running? ps -e | grep $LMXCTRL_NAME > $DEV_NULL_PATH 2>&1 if [ $? = 0 ] then Serverup=yes else Serverup=no fi # This flag set to no if command line arg (-s) is specified. # The server will be started if the flag is yes in non-interactive mode. Autostart_flag=yes # save the database rm -rf $SAMDIR_PATH/.tmp > $DEV_NULL_PATH 2>&1 mkdir $SAMDIR_PATH/.tmp > $DEV_NULL_PATH 2>&1 cp -r $SAMDIR_PATH/* $SAMDIR_PATH/.tmp> $DEV_NULL_PATH 2>&1 return } #---------------------------------------------------------------------------- # # Get the pdc name. # Globals: references and modifies Primary # getpdcname () { while [ 1 ] do if [ "$Primary" != "" ] then eval echo "\"`pgettext 'Enter the name of the primary domain controller\n or press Enter to select ${Primary}: '`\c\"" read x if [ "$x" != "" ] then Primary=$x break fi else pgettext "\nEnter the name of the primary domain controller: " read Primary if [ "$Primary" != "" ] then break else pgettext "\nYou must enter the name of the primary domain controller\n" fi fi done } #---------------------------------------------------------------------------- # # Get the name of the administrator account on the pdc # Globals: modifies Administrator # usage: getadminacct # getadminacct () { name=$1 while [ 1 ] do eval echo "\"`pgettext 'Enter the name of an administrator account on ${name}\n or press Enter to select ${Administrator}: '`\c\"" read x if [ "$x" != "" ] then Administrator=$x fi break done } #---------------------------------------------------------------------------- # # Get the server name # Globals: referenced: Original_servername # modified: Servername # getserver_name () { Servername=$Original_servername eval echo "\"`pgettext 'The current name of this server is (${Servername}).'`\"" eval yorn $YES "\"`pgettext 'Would you like to change this name now'`\"" if [ $? = $NO ] then eval echo "\"`pgettext '\nThis server's name (${Servername}) will not be changed.'`\"" exit ${FATAL_EXIT_CODE} fi while [ 1 ] do newservername="" pgettext "\nEnter the new servername (15 characters or less):" read newservername # Make sure server name is OK check_name "$newservername" if [ $? -eq 1 ] then continue fi break done Servername=$newservername return } #---------------------------------------------------------------------------- # # Restore Original_servername, replace accounts database file, start the server # if it had been running. # Exits with FATAL_EXIT_CODE # restorestate() { trap 2 3 15 pgettext "\nRestoring server to its previous state ... \n" stty echo if [ "$Original_listenname" != "" ] then $SRVCONFIG_PATH -s "server,listenname=$Original_listenname" \ > $DEV_NULL_PATH 2>&1 else # remove listenname if it exists sed '/^listenname=/d' < $LANMAN_INI_PATH > $LANMAN_INI_PATH.t mv $LANMAN_INI_PATH.t $LANMAN_INI_PATH fi cp -r $SAMDIR_PATH/.tmp/* $SAMDIR_PATH > $DEV_NULL_PATH 2>&1 rm -f $SAMDIR_PATH/.tmp/* > $DEV_NULL_PATH 2>&1 rmdir $SAMDIR_PATH/.tmp > $DEV_NULL_PATH 2>&1 pgettext "Success\n" if [ $Serverup = yes ] then eval echo "\"`pgettext 'Restarting the ${COMMENT} ... '`\c\"" $NET_PATH start server > $DEV_NULL_PATH 2>&1 if [ $? -ne 0 ] then pgettext "\n\tFailed to start\n" else pgettext "\n\tStarted successfully\n" fi fi exit ${FATAL_EXIT_CODE} } #---------------------------------------------------------------------------- # # This routine does the work. It is called after all the required information # has been specified and checked. # setname () { # update the listenname only if a servername is entered, it is # not uname.serve, and the user has changed it # makemach reads the name from lanman.ini (using getlmxname() ) if [ "$Servername" != "" -a "$Servername" != "$Original_servername" ] then # update listenname. # set if no unix listener or new name is not uname.serve. # remove if unix listener and new name is uname.serve. if [ "$ListenNameCheck" = no -o \ "$Servername" != $UnameDotServe ] then $SRVCONFIG_PATH -s "server,listenname=$Servername" else sed '/^listenname=/d' < $LANMAN_INI_PATH > $LANMAN_INI_PATH.t mv $LANMAN_INI_PATH.t $LANMAN_INI_PATH fi fi if [ $Role = backup ] then eval echo "\"`pgettext 'Contacting the server ${Primary} ... '`\c\"" serverarg=${Primary} else pgettext "\nUpdating the accounts database ... \n" serverarg=${Servername} fi $MAKEMACH_PATH -d $Original_servername -a $Administrator \ -p "$AdminPW" -s $serverarg > $DEV_NULL_PATH 2>&1 if [ $? != 0 ] then if [ $Role = backup ] then eval echo "\"`pgettext 'Unable to contact the PDC ${Primary}.'`\"" else pgettext "\nUnable to update the accounts database.\n" fi if [ $Interactive = yes ] then eval yorn $YES "\"`pgettext 'Do you want to retry with new information'`\"" if [ $? = $YES ] then # have the previously created SAM stuff trashed return 1 fi fi restorestate else pgettext "Database updated successfully\n" fi # If the servername is 'uname'.serve, update UNIX listener database # Tell nlsadmin to install the Client Vc handoff program # Do it for every network protocol loaded. if [ "$ListenNameCheck" = yes -a "$Servername" = $UnameDotServe ] then for x in `$NLSADMIN_PATH -x | cut -f1` do $NLSADMIN_PATH -q -z 2 $x > $DEV_NULL_PATH 2>&1 if [ $? -eq 0 ] then eval echo "\"`pgettext 'Removing old entry for the server on protocol stack: ${x}'`\"" $NLSADMIN_PATH -r 2 $x > $DEV_NULL_PATH 2>&1 fi eval echo "\"`pgettext 'Adding the server to protocol stack:${x}'`\"" eval $NLSADMIN_PATH -m -a 2 -c "$PASSCLI_PATH" -y \ "\"`pgettext 'Used by ${COMMENT}'`\"" -w root $x done fi return 0 } #---------------------------------------------------------------------------- # # This routine does most of the work # changename () { # # Interactive = no, command line has been used, just do it! # if [ $Interactive = no ] then setname return fi # # Interactive mode # while [ 1 ] do getserver_name if [ "$Role" = "backup" ] then # # Update the machine account at the PDC # pgettext "\n"\ "This command will notify the primary domain controller of the change\n in server name. You will be prompted to enter the name of the PDC,\n and an adminstrative account name on the primary along with its password.\n In order for the server name change to complete successfully, the PDC\n must be running and connected to the network.\n" getpdcname getadminacct $Primary else getadminacct $Servername fi eval getpw "\"`pgettext 'Enter the password for ${Administrator}:'`\c\"" # We have the answers. Give one last chance to change them # eval echo "\"`pgettext 'Confirm choices: New servername : ${Servername}'`\"" eval echo "\"`pgettext ' Administrator account : ${Administrator}'`\"" if [ $Role = backup ] then eval echo "\"`pgettext ' Primary domain controller : ${Primary}\n'`\"" fi eval yorn $YES "\"`pgettext 'Is this correct'`\"" if [ $? = $NO ] then # get the info again continue fi setname if [ $? -ne 0 ] then continue fi break done return } #---------------------------------------------------------------------------- # # Prompt to stop the server # Globals: references Serverup, Interactive # stop_the_server () { # See if the server is running and then stop it. if [ $Serverup = yes ] then if [ $Interactive = yes ] then pgettext "\nThe server is running.\n" pgettext "The server name cannot be changed while the server is running.\n" eval yorn $YES "\"`pgettext 'Do you want to stop the server and continue'`\"" if [ $? != $YES ] then exit ${FATAL_EXIT_CODE} fi fi pgettext "\nStopping the server ... \n" $NET_PATH stop server /y > $DEV_NULL_PATH 2>&1 if [ $? = 0 ] then pgettext "Success\n" else pgettext "\nError: Unable to stop the server.\n" exit ${FATAL_EXIT_CODE} fi fi } #---------------------------------------------------------------------------- # # Start_the_server - determine whether to automatically start, prompt to start, # or not start the server. # Globals: references Serverup, Interactive # start_the_server () { # # If the server was not up AND we are running interactively, # then prompt to restart; # else do not start if the flag is set to not start; # all other times automatically restart # if [ $Serverup = no -a $Interactive = yes ] then eval yorn $YES "\"`pgettext 'Do you want to start the server now'`\"" startserver=$? elif [ $Autostart_flag = no ] then startserver=$NO else startserver=$YES fi if [ $startserver = $YES ] then eval echo "\"`pgettext 'Starting the ${COMMENT} ... '`\c\"" $NET_PATH start server > $DEV_NULL_PATH 2>&1 if [ $? -ne 0 ] then pgettext "Unable to start the server.\n" # restorestate else pgettext "Server started successfully\n\n"\ "Note: If the replicator service is running on this server, it may have to be\n"\ " reconfigured. Use the Properties function of Server Manager to check\n"\ " the replication configuration.\n" fi else pgettext "The name change will not take effect until the server has been started.\n\n" fi } #---------------------------------------------------------------------------- #---------------------------------------------------------------------------- # # Beginning of main function of setservername # # # perform initialization, startup checks # initialize # is there are command line? should we run interactively? check_commandline $* if [ $? -eq 0 ] then Interactive=yes else Interactive=no fi if [ $Interactive = yes ] then eval echo "\"`pgettext 'This ${COMMENT} utility (${Progname})\n allows you to change the server name on either the primary domain controller (PDC) or backup domain controller (BDC). This utility creates an account for the new server name\n and deletes the account with the old server name.\n When this utility is run on a BDC, the PDC is contacted and \n the new account is added to the domain, then the old account is removed from the domain. \n The server will be stopped each time you run ${Progname}.'`\"" eval yorn $NO "\"`pgettext 'Do you want to continue'`\"" if [ $? = $NO ] then exit ${FATAL_EXIT_CODE} fi fi stop_the_server trap 'restorestate' 2 3 15 # # perform the name change # changename start_the_server trap 2 3 15 rm -f $SAMDIR_PATH/.tmp/* > $DEV_NULL_PATH 2>&1 rmdir $SAMDIR_PATH/.tmp > $DEV_NULL_PATH 2>&1