Hallo, dies ist ein Test.
PWD: /www/data-lst1/unixsoft/unixsoft/kaempfer/.public_html
Running in File Mode
Relative path: ./../.././../../../../sbin/kclient
Real path: /usr/sbin/kclient
Zurück
#!/bin/ksh93 -p # # Copyright (c) 2003, 2023, Oracle and/or its affiliates. # # This script is used to setup the Kerberos client by # supplying information about the Kerberos realm and kdc. # # The kerberos configuration file (/etc/krb5/krb5.conf) would # be generated and local host's keytab file setup. The script # can also optionally setup the system to do kerberized nfs and # bringover a master krb5.conf copy from a specified location. # TEXTDOMAIN=solaris_cmd_krb5 export TEXTDOMAIN function cleanup { kdestroy -q > $TMP_FILE 2>&1 rm -r $TMPDIR > /dev/null 2>&1 exit $1 } function exiting { printf "\n$(gettext "Exiting setup, nothing changed").\n\n" cleanup $1 } function error_message { printf -- "---------------------------------------------------\n" >&2 printf "$(gettext "Setup FAILED").\n\n" >&2 cleanup 1 } function check_bin { typeset bin=$1 if [[ ! -x $bin ]]; then printf "$(gettext "Could not access/execute %s").\n" $bin >&2 error_message fi } function cannot_create { typeset filename="$1" typeset stat="$2" if [[ $stat -ne 0 ]]; then printf "\n$(gettext "Can not create/edit %s, exiting").\n" $filename >&2 error_message fi } function update_pam_conf { typeset PAM_CONF PAM_D_CONF TPAM_D_CONF POLICY_CONF TPOLICY_CONF service typeset INC_FILE MOD PAM_CONF=/etc/pam.conf PAM_D_CONF=/etc/pam.d POLICY_CONF=/etc/security/policy.conf TPAM_D_CONF=$(mktemp -q -t kclient-pam.d-conf.XXXXXX) if [[ -z $TPAM_D_CONF ]]; then printf "\n$(gettext "Can not create temporary file, exiting").\n" >&2 error_message fi printf "$(gettext "Configuring PAM").\n\n" for service in $SVCs; do svc=${service%:*} auth_type=${service#*:} if [[ -n ${service/*:*/} ]]; then # Update PAM_POLICY with auth_type if grep "^[ ]*PAM_POLICY" $POLICY_CONF >/dev/null \ 2>&1; then printf "$(gettext "PAM_POLICY is already configured, please merge %s by \nhand with"):\n\n" \ $POLICY_CONF printf "PAM_POLICY=krb5_$auth_type\n\n" continue fi TPOLICY_CONF=$(mktemp -q -t kclient-policy-conf.XXXXXX) if [[ -z $TPOLICY_CONF ]]; then printf "\n$(gettext "Can not create temporary file, exiting: %s").\n" $TPOLICY_CONF >&2 error_message fi sed "s%^#PAM_POLICY=%PAM_POLICY=krb5_$auth_type%" \ $POLICY_CONF >$TPOLICY_CONF cp -f $TPOLICY_CONF $POLICY_CONF >/dev/null 2>&1 rm $TPOLICY_CONF > /dev/null 2>&1 continue fi # If cron has been selected for configuration then this is most # likely a S4U configuration else we configure the appropriate # pam_krb5 auth type. if [[ $svc == cron ]]; then MOD=pam_gss INC_FILE=${MOD}_s4u else MOD=pam_krb5 INC_FILE=${MOD}_${auth_type} fi if grep "^[ ]*$svc[ ]\{1,\}auth.*$MOD*" \ $PAM_CONF >/dev/null 2>&1; then printf "$(gettext "The %s service is already configured for %s, please merge the\nfollowing entry into %s by hand"):\n\n" \ $svc $MOD $PAM_CONF >&2 printf "$svc\tauth\tinclude\t\t$INC_FILE\n\n" continue fi if grep "^[ ]*$svc[ ]\{1,\}auth[ ]\{1,\}" \ $PAM_CONF >/dev/null 2>&1; then printf "$(gettext "The %s service is already configured for authentication in\n%s, please merge the following entry into %s by hand"):\n\n" $svc $PAM_CONF $PAM_CONF >&2 printf "$svc\tauth\tinclude\t\t$INC_FILE\n\n" continue else if grep "^[ ]*auth[ ]\{1,\}" \ $PAM_D_CONF/$svc >/dev/null 2>&1; then printf "$(gettext "The %s service is already configured for authentication in\n%s, please merge the following entry into\n%s by hand"):\n\n" $svc $PAM_D_CONF/$svc $PAM_D_CONF/$svc >&2 printf "auth\tinclude\t\t$INC_FILE\n\n" continue fi fi # update /etc/pam.d/$svc since this $svc isn't already # configured for authentication in /etc/pam.conf or # /etc/pam.d/$svc printf "$(gettext "Updating %s.\n")" "/etc/pam.d/$svc" cp -f $PAM_D_CONF/$svc $TPAM_D_CONF >/dev/null 2>&1 exec 3>>$TPAM_D_CONF printf "\nauth include\t\t$INC_FILE\n" 1>&3 cp -f $TPAM_D_CONF $PAM_D_CONF/$svc > /dev/null 2>&1 done rm $TPAM_D_CONF > /dev/null 2>&1 } function modify_nfssec_conf { typeset NFSSEC_FILE="/etc/nfssec.conf" if [[ -r $NFSSEC_FILE ]]; then cat $NFSSEC_FILE > $NFSSEC_FILE.sav cannot_create $NFSSEC_FILE.sav $? fi cat $NFSSEC_FILE > $TMP_FILE cannot_create $TMP_FILE $? if grep -s "#krb5" $NFSSEC_FILE > /dev/null 2>&1; then sed "s%^#krb5%krb5%" $TMP_FILE >$NFSSEC_FILE cannot_create $NFSSEC_FILE $? fi } function write_xml_profile { typeset output_file="$1" typeset cmd="" typeset KRB_INST_SVC="system/kerberos/install" typeset PROP=" -s instance-property=" # # Construct svcbundle command to create the configuration profile. # cmd=$cmd"svcbundle -o $output_file -s bundle-type=profile " cmd=$cmd" -s enabled=true -s model=transient -s instance-name=default " cmd=$cmd" -s service-name=$KRB_INST_SVC" cmd=$cmd$PROP"install:config_complete:boolean:false" cmd=$cmd$PROP"install:major_version:integer:0" cmd=$cmd$PROP"install:minor_version:integer:1" if [[ "$no_keytab" == 'yes' ]]; then cmd=$cmd$PROP"libdefaults:verify_ap_req_nofail:boolean:false" fi cmd=$cmd$PROP"libdefaults:default_realm:astring:$realm" if [[ $dns_lookup == yes ]]; then cmd=$cmd$PROP"libdefaults:$dnsarg:boolean:true" if [[ $dnsarg == dns_lookup_kdc ]]; then if [[ -n $domain_list ]]; then for dh in $domain_list; do cmd=$cmd$PROP"default_realm:domains:astring:$dh" done fi elif [[ $dnsarg = dns_lookup_realm ]]; then if [[ -n $slave_kdc_list ]]; then for kdc in $slave_kdc_list; do cmd=$cmd$PROP"default_realm:kdc:hostname:$kdc" done fi for kdc in $master_kdc_list; do cmd=$cmd$PROP"default_realm:kdc:hostname:$kdc" done for kdc in $master_kdc_list; do cmd=$cmd$PROP"default_realm:admin_server:hostname:$kdc" done if [[ $non_solaris == yes ]]; then cmd=$cmd$PROP"default_realm:kpasswd_protocol:" cmd=$cmd"astring:SET_CHANGE" fi fi else if [[ -n $slave_kdc_list ]]; then for kdc in $slave_kdc_list; do cmd=$cmd$PROP"default_realm:kdc:hostname:$kdc" done fi for kdc in $master_kdc_list; do cmd=$cmd$PROP"default_realm:kdc:hostname:$kdc" done for kdc in $master_kdc_list; do cmd=$cmd$PROP"default_realm:admin_server:hostname:$kdc" done if [[ $non_solaris == yes ]]; then cmd=$cmd$PROP"default_realm:kpasswd_protocol:astring:SET_CHANGE" fi if [[ -n $domain_list ]]; then for dh in $domain_list; do cmd=$cmd$PROP"default_realm:domains:astring:$dh" done fi fi cmd=$cmd$PROP"appdefaults-kinit:renewable:boolean:true" cmd=$cmd$PROP"appdefaults-kinit:forwardable:boolean:true" if [[ "$no_keytab" == 'yes' ]]; then cmd=$cmd$PROP"appdefaults-kinit:no_addresses:boolean:true" fi if [[ -n $b64_keytab ]]; then cmd=$cmd$PROP"autoreg:princ:astring:$ADMIN_PRINC" cmd=$cmd$PROP"autoreg:key:astring:$b64_keytab" if [[ -n $logical_hn ]]; then cmd=$cmd$PROP"autoreg:lhn:astring:$logical_hn" fi for fqdn in $fqdnlist; do cmd=$cmd$PROP"autoreg:fqdns:astring:$fqdn" done cmd=$cmd$PROP"autoreg:services:astring:host" if [[ $add_nfs == 'yes' ]]; then cmd=$cmd$PROP"autoreg:services:astring:nfs" fi cmd=$cmd$PROP"autoreg:kdctype:astring:$kdctype" fi # call the command and return its error code printf "\n$(gettext "Setting up %s").\n\n" $output_file exec $cmd } function xml_profile_prompts { # # Check to see if we will be a client of a MIT, Heimdal, Shishi, etc. # if [[ -z $options ]]; then query "$(gettext "Is this a client of a non-Solaris KDC") ?" non_solaris=$answer if [[ $non_solaris == yes ]]; then printf "$(gettext "Which type of KDC is the server"):\n" printf "\t$(gettext "ms_ad: Microsoft Active Directory")\n" printf "\t$(gettext "mit: MIT KDC server")\n" printf "\t$(gettext "heimdal: Heimdal KDC server")\n" printf "\t$(gettext "shishi: Shishi KDC server")\n" printf "$(gettext "Enter required KDC type"): " read kdctype if [[ $kdctype == ms_ad ]]; then msad=yes elif [[ $kdctype == mit || $kdctype == heimdal || \ $kdctype == shishi ]]; then no_keytab=yes else printf "\n$(gettext "Invalid KDC type option, valid types are ms_ad, mit, heimdal, or shishi, exiting").\n" >&2 error_message fi fi fi [[ -z $kdctype ]] && kdctype='solaris' # Auto-registration to MS AD domain if [[ $kdctype == 'ms_ad' ]]; then query "$(gettext "Should the client automatically join AD domain") ?" if [[ $answer == 'yes' ]]; then if [[ -z $realm ]]; then printf "$(gettext "Enter the Kerberos realm"): " read realm checkval="REALM"; check_value $realm fi if [[ -z $ADMIN_PRINC ]]; then printf "\n$(gettext "Enter the krb5 administrative principal to be used"): " read ADMIN_PRINC checkval="ADMIN_PRINC"; check_value $ADMIN_PRINC fi printf "\n$(gettext "Password for %s"): " $ADMIN_PRINC stty -echo read -s pw stty echo echo b64_keytab=$(create_b64_keytab $ADMIN_PRINC $pw $realm) return fi fi check_nss_conf || printf "$(gettext "/etc/nsswitch.conf does not make use of DNS for hosts and/or ipnodes").\n" if [[ -z $dnsarg && (-z $options || -z $filepath) ]]; then query "$(gettext "Do you want to use DNS for kerberos lookups") ?" if [[ $answer == yes ]]; then printf "\n$(gettext "Valid DNS lookup options are dns_lookup_kdc, dns_lookup_realm,\nand dns_fallback. Refer krb5.conf(5) for further details").\n" printf "\n$(gettext "Enter required DNS option"): " read dnsarg checkval="DNS_OPTIONS"; check_value $dnsarg set_dns_value $dnsarg fi fi [[ -z $dnsarg ]] && dnsarg=none set_dns_value $dnsarg if [[ -n $kdc_list ]]; then if [[ -z $master_kdc_list ]]; then # assign first kdc to master kdc list, rest to slave list print $kdc_list|read master_kdc_list slave_kdc_list else # masters were already specified so this is just slaves slave_kdc_list="$kdc_list" fi fi if [[ -z $realm ]]; then printf "$(gettext "Enter the Kerberos realm"): " read realm checkval="REALM"; check_value $realm fi if [[ $dnsarg == 'none' || $dnsarg == 'dns_lookup_realm' ]]; then if [[ -z $master_kdc_list ]]; then printf "$(gettext "Specify the master KDCs for the above realm using a comma-separated list"): " read master_kdc_list fi verify_kdcs $master_kdc_list 'no_ping_check' master_kdc_list=${master_kdc_list//,/ } if [[ -z $slave_kdc_list && -z $options ]]; then query "$(gettext "Do you have any slave KDC(s)") ?" if [[ $answer == yes ]]; then printf "$(gettext "Enter a comma-separated list of slave KDC host names"): " read slave_kdc_list fi fi [[ -n $slave_kdc_list ]] && verify_kdcs $slave_kdc_list 'no_ping_check' slave_kdc_list=${slave_kdc_list//,/ } found=false for kdc in $slave_kdc_list $master_kdc_list; do if ping $kdc 2 > /dev/null; then found=true break fi done ! $found && printf "\n$(gettext "Warning, no %s is reachable.").\n\n" "KDC" >&2 fi if [[ $dnsarg == 'none' || $dnsarg == 'dns_lookup_kdc' ]]; then if [[ -z $domain_list && (-z $options || -z $filepath) ]]; then query "$(gettext "Do you have multiple domains/hosts to map to realm %s" ) ?" $realm if [[ $answer == yes ]]; then printf "$(gettext "Enter a comma-separated list of domain/hosts to map to the default realm"): " read domain_list fi fi [[ -n $domain_list ]] && domain_list=${domain_list//,/ } fi # autoregistration not available for mit_kdc, shishi, heimdal. if [[ $kdctype != 'solaris' || $no_keytab = 'yes' ]]; then return fi query "$(gettext "Should the client automatically join the realm") ?" if [[ $answer == 'yes' ]]; then if [[ -z $ADMIN_PRINC ]]; then printf "\n$(gettext "Enter the krb5 administrative principal to be used"): " read ADMIN_PRINC checkval="ADMIN_PRINC"; check_value $ADMIN_PRINC fi printf "\n$(gettext "Password for %s"): " $ADMIN_PRINC stty -echo read -s pw stty echo echo b64_keytab=$(create_b64_keytab $ADMIN_PRINC $pw $realm) # Is this client going to use krb-nfs? if [[ -z $options ]]; then query "$(gettext "Do you plan on doing Kerberized nfs") ?" add_nfs=$answer fi # Cluster with logical hostname - different service principals if [[ -z $options ]]; then query "$(gettext "Is this client a member of a cluster that uses a logical host name") ?" if [[ $answer == yes ]]; then printf "$(gettext "Specify the logical hostname of the cluster"): " read logical_hn checkval="LOGICAL_HOSTNAME"; check_value $logical_hn fi fi # Create keys for service principals in multiple domains? if [[ -z $options ]]; then query "$(gettext "Do you have multiple DNS domains spanning the Kerberos realm") $realm ?" if [[ $answer == yes ]]; then printf "$(gettext "Enter a comma-separated list of DNS domain names"): " read fqdnlist fi fi [[ -n $fqdnlist ]] && fqdnlist=${fqdnlist//,/ } fi } # # Given principal name and password, creates a keytab # and prints it base64 encoded. # function create_b64_keytab { typeset princ=$1 typeset pass=$2 typeset realm=$3 typeset args rtrn # ksetpw requires some krb profile to work, any profile echo "[libdefaults]\ndefault_realm = $realm" > $KRB5_CONFIG args=" -n -s $princ -v2 -k $new_keytab " args=$args" -e aes256-cts-hmac-sha1-96 -e aes128-cts-hmac-sha1-96 " rm $new_keytab > /dev/null 2>&1 echo $pass | $KSETPW $args $princ@$realm >/dev/null 2>&1 if [[ $? -ne 0 ]]; then printf "\n$(gettext "Failed to create admin keytab.").\n" >&2 error_message fi rtrn=$(openssl base64 -in $new_keytab | tr -d '\n') if [[ $? -ne 0 ]]; then printf "\n$(gettext "Failed to encode admin keytab.").\n" >&2 error_message fi rm $new_keytab > /dev/null 2>&1 print -- $rtrn } function call_kadmin { typeset svc="$1" typeset bool1 bool2 bool3 bool4 typeset service_princ getprincsubcommand anksubcommand ktaddsubcommand typeset ktremsubcommand for listentry in $fqdnlist; do # Reset conditional vars to 1 bool1=1; bool2=1; bool3=1; bool4=1 service_princ=$(echo "${svc}/${listentry}") getprincsubcommand="getprinc $service_princ" anksubcommand="addprinc -randkey $service_princ" ktaddsubcommand="ktadd $service_princ" ktremsubcommand="ktrem $service_princ all" kadmin -c $KRB5CCNAME -q "$getprincsubcommand" 1>$TMP_FILE 2>&1 egrep -s "$(gettext "get_principal: Principal does not exist")" $TMP_FILE bool1=$? egrep -s "$(gettext "get_principal: Operation requires ``get")" $TMP_FILE bool2=$? if [[ $bool1 -eq 0 || $bool2 -eq 0 ]]; then kadmin -c $KRB5CCNAME -q "$anksubcommand" 1>$TMP_FILE 2>&1 egrep -s "$(printf $(gettext "add_principal: Principal or policy already exists while creating \"%s\".") "$service_princ@$realm")" $TMP_FILE bool3=$? egrep -s "$(printf $(gettext "Principal \"%s\" created.") "$service_princ@$realm")" $TMP_FILE bool4=$? if [[ $bool3 -eq 0 || $bool4 -eq 0 ]]; then printf "$(gettext "%s entry ADDED to KDC database").\n" $service_princ else cat $TMP_FILE; printf "\n$(gettext "kadmin: add_principal of %s failed, exiting").\n" $service_princ >&2 error_message fi else printf "$(gettext "%s entry already exists in KDC database").\n" $service_princ >&2 fi klist -k 1>$TMP_FILE 2>&1 egrep -s "$service_princ@$realm" $TMP_FILE if [[ $? -eq 0 ]]; then printf "$(gettext "%s entry already present in keytab").\n" $service_princ >&2 # Don't care is this succeeds or not, just need to replace old # entries as it is assummed that the client is reinitialized kadmin -c $KRB5CCNAME -q "$ktremsubcommand" 1>$TMP_FILE 2>&1 fi kadmin -c $KRB5CCNAME -q "$ktaddsubcommand" 1>$TMP_FILE 2>&1 # # Possible kadmin output on success: # added to keytab WRFILE:/etc/krb5/krb5.keytab # added to keytab FILE:/etc/krb5/krb5.keytab # egrep -s "$(gettext "added to keytab") (WR)?FILE:$KRB5_KEYTAB_FILE." $TMP_FILE if [[ $? -ne 0 ]]; then cat $TMP_FILE; printf "\n$(gettext "kadmin: ktadd of %s failed, exiting").\n" $service_princ >&2 error_message else printf "$(gettext "%s entry ADDED to keytab").\n" $service_princ fi done } function writeup_krb5_conf { typeset dh printf "\n$(gettext "Setting up %s").\n\n" $KRB5_CONFIG_FILE exec 3>$KRB5_CONFIG if [[ $? -ne 0 ]]; then printf "\n$(gettext "Can not write to %s, exiting").\n" $KRB5_CONFIG >&2 error_message fi printf "[libdefaults]\n" 1>&3 if [[ $no_keytab == yes ]]; then printf "\tverify_ap_req_nofail = false\n" 1>&3 fi if [[ $dns_lookup == yes ]]; then printf "\t$dnsarg = on\n" 1>&3 if [[ $dnsarg == dns_lookup_kdc ]]; then printf "\tdefault_realm = $realm\n" 1>&3 printf "\n[domain_realm]\n" 1>&3 printf "\t$client_machine = $realm\n" 1>&3 if [[ -z $short_fqdn ]]; then printf "\t.$domain = $realm\n\n" 1>&3 else printf "\t.$short_fqdn = $realm\n\n" 1>&3 fi if [[ -n $domain_list ]]; then for dh in $domain_list; do printf "\t$dh = $realm\n" 1>&3 done fi else if [[ $dnsarg = dns_lookup_realm ]]; then printf "\tdefault_realm = $realm\n" 1>&3 printf "\n[realms]\n" 1>&3 printf "\t$realm = {\n" 1>&3 if [[ -n $slave_kdc_list ]]; then for kdc in $slave_kdc_list; do printf "\t\tkdc = $kdc\n" 1>&3 done fi for kdc in $master_kdc_list; do printf "\t\tkdc = $kdc\n" 1>&3 done for kdc in $master_kdc_list; do printf "\t\tadmin_server = $kdc\n" 1>&3 done if [[ $non_solaris == yes ]]; then printf "\n\t\tkpasswd_protocol = SET_CHANGE\n" 1>&3 fi printf "\t}\n\n" 1>&3 else printf "\tdefault_realm = $realm\n\n" 1>&3 fi fi else printf "\tdefault_realm = $realm\n\n" 1>&3 printf "[realms]\n" 1>&3 printf "\t$realm = {\n" 1>&3 if [[ -n $slave_kdc_list ]]; then for kdc in $slave_kdc_list; do printf "\t\tkdc = $kdc\n" 1>&3 done fi for kdc in $master_kdc_list; do printf "\t\tkdc = $kdc\n" 1>&3 done for kdc in $master_kdc_list; do printf "\t\tadmin_server = $kdc\n" 1>&3 done if [[ $non_solaris == yes ]]; then printf "\n\t\tkpasswd_protocol = SET_CHANGE\n" 1>&3 fi printf "\t}\n\n" 1>&3 printf "[domain_realm]\n" 1>&3 printf "\t$client_machine = $realm\n" 1>&3 if [[ -z $short_fqdn ]]; then printf "\t.$domain = $realm\n\n" 1>&3 else printf "\t.$short_fqdn = $realm\n\n" 1>&3 fi if [[ -n $domain_list ]]; then for dh in $domain_list; do printf "\t$dh = $realm\n" 1>&3 done fi fi printf "[logging]\n" 1>&3 printf "\tdefault = FILE:/var/krb5/kdc.log\n" 1>&3 printf "\tkdc = FILE:/var/krb5/kdc.log\n" 1>&3 printf "\tkdc_rotate = {\n\t\tperiod = 1d\n\t\tversions = 10\n\t}\n\n" 1>&3 printf "[appdefaults]\n" 1>&3 printf "\tkinit = {\n\t\trenewable = true\n\t\tforwardable = true\n" 1>&3 if [[ $no_keytab == yes ]]; then printf "\t\tno_addresses = true\n" 1>&3 fi printf "\t}\n" 1>&3 } function ask { typeset question=$1 typeset default_answer=$2 if [[ -z $default_answer ]]; then printf "$question :" else printf "$question [$default_answer]: " fi read answer test -z "$answer" && answer="$default_answer" } function yesno { typeset question="$1" answer= yn=`printf "$(gettext "y/n")"` y=`printf "$(gettext "y")"` n=`printf "$(gettext "n")"` yes=`printf "$(gettext "yes")"` no=`printf "$(gettext "no")"` while [[ -z $answer ]]; do ask "$question" $yn case $answer in $y|$yes) answer=yes;; $n|$no) answer=no;; *) answer=;; esac done } function query { yesno "$*" if [[ $answer == no ]]; then printf "\t$(gettext "No action performed").\n" fi } function read_profile { typeset param value typeset file="$1" if [[ ! -d $file && -r $file ]]; then while read param value do case $param in REALM) if [[ -z $realm ]]; then realm="$value" checkval="REALM"; check_value $realm fi ;; MAS) if [[ -z $master_kdc_list ]]; then master_kdc_list="$value" fi ;; KDC) if [[ -z $kdc_list ]]; then kdc_list="$value" fi ;; ADMIN) if [[ -z $ADMIN_PRINC ]]; then ADMIN_PRINC="$value" checkval="ADMIN_PRINC" check_value $ADMIN_PRINC fi ;; FILEPATH) if [[ -z $filepath ]]; then filepath="$value" fi ;; NFS) if [[ -z $add_nfs ]]; then if [[ $value == 1 ]]; then add_nfs=yes else add_nfs=no fi fi ;; NOKEY) if [[ -z $no_keytab ]]; then if [[ $value == 1 ]]; then no_keytab=yes else no_keytab=no fi fi ;; NOSOL) if [[ -z $non_solaris ]]; then if [[ $value == 1 ]]; then non_solaris=yes no_keytab=yes else non_solaris=no fi fi ;; LHN) if [[ -z $logical_hn ]]; then logical_hn="$value" checkval="LOGICAL_HOSTNAME" check_value $logical_hn fi ;; DNSLOOKUP) if [[ -z $dnsarg ]]; then dnsarg="$value" checkval="DNS_OPTIONS" check_value $dnsarg fi ;; FQDN) if [[ -z $fqdnlist ]]; then fqdnlist="$value" checkval="FQDN" check_value $fqdnlist fi ;; MSAD) if [[ -z $msad ]]; then if [[ $value == 1 ]]; then msad=yes non_solaris=yes else msad=no fi fi ;; KDCVENDOR) if [[ -z $kdctype ]]; then kdctype="$value" fi if [[ $kdctype == ms_ad ]]; then msad=yes adddns=yes else non_solaris=yes no_keytab=yes fi ;; RMAP) if [[ -z $domain_list ]]; then domain_list="$value" fi ;; PAM) if [[ -z $svc_list ]]; then svc_list="$value" verify_pam_svc_list $svc_list SVCs=${svc_list//,/ } fi ;; esac done <$file else printf "\n$(gettext "The kclient profile \`%s' is not valid, exiting").\n" $file >&2 error_message fi } function ping_check { typeset machine="$1" typeset string="$2" if ping $machine 2 > /dev/null 2>&1; then : else printf "\n$(gettext "%s %s is unreachable, exiting").\n" $string $machine >&2 error_message fi # Output timesync warning if not using a profile, i.e. in # interactive mode. if [[ -z $profile && $string == KDC ]]; then # It's difficult to sync up time with KDC esp. if in a # zone so just print a warning about KDC time sync. printf "\n$(gettext "Note, this system and the KDC's time must be within 5 minutes of each other for Kerberos to function").\n" >&2 printf "$(gettext "Both systems should run some form of time synchronization system like Network Time Protocol (NTP)").\n" >&2 break fi } function check_value { typeset arg="$1" if [[ -z $arg ]]; then printf "\n$(gettext "No input obtained for %s, exiting").\n" $checkval >&2 error_message else echo "$arg" > $TMP_FILE if egrep -s '[*$^#!]+' $TMP_FILE; then printf "\n$(gettext "Invalid input obtained for %s, exiting").\n" $checkval >&2 error_message fi fi } function set_dns_value { typeset -l arg="$1" if [[ $arg == dns_lookup_kdc || $arg == dns_lookup_realm || $arg == dns_fallback ]]; then dns_lookup=yes else if [[ $arg == none ]]; then dns_lookup=no else printf "\n$(gettext "Invalid DNS lookup option, exiting").\n" >&2 error_message fi fi } function verify_pam_svc_list { svc_list=$1 if echo $1 | egrep -s '^([^:,]+:)?(first|only|optional)(,([^:,]+:)?(first|only|optional))*$'; then : else printf "\n$(gettext "Invalid PAM service list '%s', exiting").\n" $svc_list >&2 error_message fi } # Checks kdcs, returns a subset of resolvable kdcs function verify_kdcs { typeset k_list="${1//,/ }" typeset no_ping_test=$2 typeset -l kdc typeset kdc_up_list verified_kdc_list # If k_list is empty or only contains spaces error out if [[ -z $k_list || -z ${k_list// /} ]]; then printf "\n$(gettext "At least one %s should be listed").\n\n" "KDC" >&2 usage fi for kdc in $k_list; do # Try doing a A(ddress) record lookup fkdc=$($KLOOKUP $kdc) # If that doesn't work try CNAME [[ -z $fkdc ]] && fkdc=$($KLOOKUP $kdc C) if [[ -z $fkdc ]]; then printf "\n$(gettext "%s %s full host name not found, no action performed").\n" "KDC" $kdc >&2 else if [[ -z $no_ping_test ]]; then if ping $fkdc 2 > /dev/null; then kdc_up_list="$kdc_up_list $fkdc" else printf "\n$(gettext "Warning: %s %s is unreachable.").\n" "KDC" $fkdc >&2 fi fi verified_kdc_list="$verified_kdc_list $kdc" fi done if [[ -z $verified_kdc_list ]]; then printf "\n$(gettext "Unable to resolve the full host name of any %s.").\n\n" "KDC" >&2 [[ -z $no_ping_test ]] && usage fi [[ -z $no_ping_test ]] && print -n "$verified_kdc_list" } function parse_service { typeset service_list=$1 service_list=${service_list//,/ } for service in $service_list; do svc=${service%:} auth_type=${service#:} [[ -z $svc || -z $auth_type ]] && return print -- $svc $auth_type done } function verify_fqdnlist { typeset list="$1" typeset -l hostname typeset -i count=1 typeset eachfqdn tmpvar fullhost list=$(echo "$list" | tr -d " " | tr -d "\t") hostname=$(uname -n | cut -d"." -f1) fqdnlist=$client_machine eachfqdn=$(echo "$list" | cut -d"," -f$count) if [[ -z $eachfqdn ]]; then printf "\n$(gettext "If the -f option is used, at least one FQDN should be listed").\n\n" >&2 usage else while [[ ! -z $eachfqdn ]]; do tmpvar=$(echo "$eachfqdn" | cut -d"." -f1) if [[ -z $tmpvar ]]; then fullhost="$hostname$eachfqdn" else fullhost="$hostname.$eachfqdn" fi ping_check $fullhost $(gettext "System") if [[ $fullhost == $client_machine ]]; then : else fqdnlist="$fqdnlist $fullhost" fi if [[ $list == *,* ]]; then ((count = count + 1)) eachfqdn=$(echo "$list" | cut -d"," -f$count) else break fi done fi } function setup_keytab { typeset cname typeset instance # # 1. kinit with ADMIN_PRINC # if [[ -z $ADMIN_PRINC ]]; then printf "\n$(gettext "Enter the krb5 administrative principal to be used"): " read ADMIN_PRINC checkval="ADMIN_PRINC"; check_value $ADMIN_PRINC fi echo "$ADMIN_PRINC">$TMP_FILE [[ $msad == yes ]] && return if egrep -s '\/admin' $TMP_FILE; then # Already in "/admin" format, do nothing : else if egrep -s '\/' $TMP_FILE; then printf "\n$(gettext "Improper entry for krb5 admin principal, exiting").\n" >&2 error_message else ADMIN_PRINC=$(echo "$ADMIN_PRINC/admin") fi fi printf "$(gettext "Obtaining TGT for %s") ...\n" $ADMIN_PRINC cname=$(canon_resolve $KDC) if [[ -n $cname ]]; then kinit -S kadmin/$cname $ADMIN_PRINC instance=$cname else kinit -S kadmin/$FKDC $ADMIN_PRINC instance=$FKDC fi klist 1>$TMP_FILE 2>&1 if egrep -s "$(gettext "Valid starting")" $TMP_FILE && egrep -s "kadmin/$instance@$realm" $TMP_FILE; then : else printf "\n$(gettext "kinit of %s failed, exiting").\n" $ADMIN_PRINC >&2 error_message fi # # 2. Do we want to create and/or add service principal(s) for fqdn's # other than the one listed in resolv.conf(5) ? # if [[ -z $options ]]; then query "$(gettext "Do you have multiple DNS domains spanning the Kerberos realm") $realm ?" if [[ $answer == yes ]]; then printf "$(gettext "Enter a comma-separated list of DNS domain names"): " read fqdnlist verify_fqdnlist "$fqdnlist" else fqdnlist=$client_machine fi else if [[ -z $fqdnlist ]]; then fqdnlist=$client_machine fi fi if [[ $add_nfs == yes ]]; then echo; call_kadmin nfs fi # Add the host entry to the keytab echo; call_kadmin host } function setup_lhn { typeset -l lhn=$logical_hn echo "$lhn" > $TMP_FILE if egrep -s '[^.]\.[^.]+$' $TMP_FILE; then # do nothing, lhn is in fqdn format : else if egrep -s '\.+' $TMP_FILE; then printf "\n$(gettext "Improper format of logical hostname, exiting").\n" >&2 error_message else # Attach fqdn to logical_hn, to get the Fully Qualified # Host Name of the client requested lhn=$(echo "$lhn.$domain") fi fi client_machine=$lhn ping_check $client_machine $(gettext "System") } function usage { printf "\n$(gettext "Usage: kclient [ options ]")\n" >&2 printf "\t$(gettext "where options are any of the following")\n\n" >&2 printf "\t$(gettext "[ -D domain_list ] configure a client that has multiple mappings of domain and/or hosts to the default realm")\n" >&2 printf "\t$(gettext "[ -K ] configure a client that does not have host/service keys")\n" >&2 printf "\t$(gettext "[ -R realm ] specifies the realm to use")\n" >&2 printf "\t$(gettext "[ -T kdc_vendor ] specifies which KDC vendor is the server")\n" >&2 printf "\t$(gettext "[ -a adminuser ] specifies the Kerberos administrator")\n" >&2 printf "\t$(gettext "[ -c filepath ] specifies the krb5.conf path used to configure this client")\n" >&2 printf "\t$(gettext "[ -d dnsarg ] specifies which information should be looked up in DNS (dns_lookup_kdc, dns_lookup_realm, and dns_fallback)")\n" >&2 printf "\t$(gettext "[ -f fqdn_list ] specifies which domains to configure host keys for this client")\n" >&2 printf "\t$(gettext "[ -h logicalhostname ] configure the logical host name for a client that is in a cluster")\n" >&2 printf "\t$(gettext "[ -k kdc_list ] specify multiple KDCs, if -m is not used the first KDC in the list is assumed to be the master. KDC host names are used verbatim.")\n" >&2 printf "\t$(gettext "[ -m master_kdc_list ] list of master KDC server host names")\n" >&2 printf "\t$(gettext "[ -n ] configure client to be an NFS client")\n" >&2 printf "\t$(gettext "[ -p profile ] specifies which profile file to use to configure this client")\n" >&2 printf "\t$(gettext "[ -s pam_list ] update the service for Kerberos authentication")\n" >&2 printf "\t$(gettext "[ -x output_profile ] creates configuration profile for use with AI, doesn't configure current host ")\n" >&2 error_message } function discover_domain { typeset dom DOMs if [[ -z $realm ]]; then set -A DOMs -- `$KLOOKUP _ldap._tcp.dc._msdcs V` else set -A DOMs -- `$KLOOKUP _ldap._tcp.dc._msdcs.$realm V` fi [[ -z ${DOMs[0]} ]] && return 1 dom=${DOMs[0]} dom=${dom#_ldap._tcp.dc._msdcs.} print -- $dom } function check_nss_hosts_or_ipnodes_config { typeset backend for backend in $1 do [[ $backend == dns ]] && return 0 done return 1 } function check_nss_conf { typeset i j hosts_config for i in hosts ipnodes do grep "^${i}:" /etc/nsswitch.conf|read j hosts_config check_nss_hosts_or_ipnodes_config "$hosts_config" || return 1 done return 0 } function rev_resolve { typeset name ip ip=$(print -n `$KLOOKUP $1 I`) [[ -z $ip ]] && return for i in $ip do if ping $i 2 > /dev/null 2>&1; then break else i= fi done [[ -z $i ]] && return name=`$KLOOKUP $i P` [[ -z $name ]] && return print -- "$name" } function canon_resolve { typeset name ip name=`$KLOOKUP $1 C` [[ -z $name ]] && name=`$KLOOKUP $1 A` [[ -z $name ]] && return cname=$(rev_resolve $name) [[ -z $cname ]] && return print -- "$cname" } function doKRB5config { [[ -f $KRB5_CONFIG_FILE ]] && \ cp $KRB5_CONFIG_FILE ${KRB5_CONFIG_FILE}-pre-kclient [[ -f $KRB5_KEYTAB_FILE ]] && \ cp $KRB5_KEYTAB_FILE ${KRB5_KEYTAB_FILE}-pre-kclient [[ -s $KRB5_CONFIG ]] && cp $KRB5_CONFIG $KRB5_CONFIG_FILE [[ -s $KRB5_CONFIG_FILE ]] && chmod 0644 $KRB5_CONFIG_FILE [[ -s $new_keytab ]] && cp $new_keytab $KRB5_KEYTAB_FILE [[ -s $KRB5_KEYTAB_FILE ]] && chmod 0600 $KRB5_KEYTAB_FILE } function enable_warnd_srv { # # Start ktkt_warn service if it is disabled # typeset ktkt_srv_state="$(svcs -H -o STATE svc:/network/security/ktkt_warn:default)" case "$ktkt_srv_state" in 'online') ;; # nothing needs to be done 'disabled') svcadm enable -s svc:/network/security/ktkt_warn:default [[ $? -ne 0 ]] && printf "$(gettext "Warning: could not enable ktkt_warn service").\n";; *) printf "$(gettext "Warning: the ktkt_warn service is in %s state but should be enabled.").\n $ktkt_srv_state";; esac } function join_domain { echo "Will use 'smbadm join...' to join host to AD domain" SVCS='/usr/bin/svcs' SMBD='svc:/network/smb/server' CHECK_SMBD=$($SVCS -H -o state "$SMBD:default") SVCADM='/usr/sbin/svcadm' SMBADM='/usr/sbin/smbadm' DATE='/usr/bin/date +%m-%d-%Y' DISABLE_SMBD=0 if [[ "$CHECK_SMBD" == "disabled" ]] ; then DISABLE_SMBD=1; fi if [[ -z $ADMIN_PRINC ]]; then ADMIN=Administrator else ADMIN=$ADMIN_PRINC fi if [[ -n $key_b64 ]]; then tmp_keytab=$(mktemp -q -t kclient-adminkeytab.XXXXXX) $KT2PROF -d -p 'autoreg/key' -k $tmp_keytab DOMAIN=$realm $SMBADM join -u "$ADMIN" -k $tmp_keytab "$DOMAIN" EXIT_CODE=$? rm -f $tmp_keytab else if [[ -n $realm ]]; then DOMAIN=$realm else DOMAIN=$(discover_domain) fi echo "follow prompts from:" echo "\t$SMBADM join -u $ADMIN $DOMAIN" $SMBADM join -u "$ADMIN" "$DOMAIN" EXIT_CODE=$? fi if [[ $EXIT_CODE -eq 0 ]] ; then # # back up existing kerberos configuration # if test -f /etc/krb5/krb5.conf ; then SAVE=/etc/krb5/krb5.conf.$($DATE) echo "Saving existing /etc/krb5/krb5.conf to $SAVE" cp /etc/krb5/krb5.conf $SAVE if [[ $? -ne 0 ]] ; then "Unable to back up existing /etc/krb5/krb5.conf" exit 1 fi fi # # promote temporal krb5.conf to system-wide krb5.conf # cp $KRB5_CONFIG /etc/krb5/krb5.conf enable_warnd_srv fi if [[ $DISABLE_SMBD -eq 1 ]] ; then $SVCADM disable -s "$SMBD:default" fi exit $EXIT_CODE } ########################### # Main section # ########################### # # Set the Kerberos config file and some default strings/files # # ksh debuging # trace all functions #typeset -ft $(typeset -f) # trace commands in main #set -x KRB5_CONFIG_FILE=/etc/krb5/krb5.conf KRB5_KEYTAB_FILE=/etc/krb5/krb5.keytab DNS_CLIENT_FMRI=svc:/network/dns/client:default SVCS=/usr/bin/svcs; check_bin $SVCS KLOOKUP=/usr/lib/krb5/klookup; check_bin $KLOOKUP KSETPW=/usr/lib/krb5/ksetpw; check_bin $KSETPW KT2PROF=/usr/lib/krb5/kt2prof; check_bin $KT2PROF KCONF=/usr/lib/krb5/kconf; check_bin $KCONF unset MACHINE_THAT_GOES_PING dns_lookup=no adddns=no no_keytab=no checkval="" profile="" xml_profile="" typeset -u realm typeset -l hostname KDC export TMPDIR="/system/volatile/kclient" rm -rf $TMPDIR > /dev/null 2>&1 mkdir $TMPDIR > /dev/null 2>&1 if [[ $? -ne 0 ]]; then printf "\n$(gettext "Can not create directory: %s")\n\n" $TMPDIR >&2 exit 1 fi TMP_FILE=$(mktemp -q -t kclient-tmpfile.XXXXXX) export KRB5_CONFIG=$(mktemp -q -t kclient-krb5conf.XXXXXX) export KRB5CCNAME=$(mktemp -q -t kclient-krb5ccache.XXXXXX) new_keytab=$(mktemp -q -t kclient-krb5keytab.XXXXXX) if [[ -z $TMP_FILE || -z $KRB5_CONFIG || -z $KRB5CCNAME || -z $new_keytab ]] then printf "\n$(gettext "Can not create temporary files, exiting").\n\n" >&2 exit 1 fi # # If we are interrupted, cleanup after ourselves # trap "exiting 1" HUP INT QUIT TERM if [[ -d /usr/bin ]]; then if [[ -d /usr/sbin ]]; then if [[ -d /usr/lib/openldap/bin ]]; then PATH=/usr/lib/openldap/bin:/usr/bin:/usr/sbin:$PATH export PATH else printf "\n$(gettext "Directory /usr/lib/openldap/bin not found, exiting").\n" >&2 exit 1 fi else printf "\n$(gettext "Directory /usr/sbin not found, exiting").\n" >&2 exit 1 fi else printf "\n$(gettext "Directory /usr/bin not found, exiting").\n" >&2 exit 1 fi printf "\n$(gettext "Starting client setup")\n\n" printf -- "---------------------------------------------------\n" # # Check for uid 0, disallow otherwise # uid=$(id -u) if [[ $? -eq 0 ]]; then if [[ "$uid" != 0 ]]; then printf "\n$(gettext "Administrative privileges are required to run this script, exiting").\n" >&2 error_message fi else printf "\n$(gettext "uid check failed, exiting").\n" >&2 error_message fi uname=$(uname -n) hostname=${uname%%.*} # # Process the command-line arguments (if any) # OPTIND=1 while getopts nD:Kp:R:k:a:c:d:f:h:m:s:T:x:S OPTIONS do case $OPTIONS in D) options="$options -D" domain_list="$OPTARG" ;; K) options="$options -K" no_keytab=yes ;; R) options="$options -R" realm="$OPTARG" checkval="REALM"; check_value $realm ;; T) options="$options -T" kdctype="$OPTARG" if [[ $kdctype == ms_ad ]]; then msad=yes adddns=yes else non_solaris=yes no_keytab=yes fi ;; S) FMRI='system/kerberos/install:default' key_b64=$(svcprop -p autoreg/key $FMRI 2>/dev/null) if [[ $? -ne 0 || -z $key_b64 ]]; then usage; fi ;; a) options="$options -a" ADMIN_PRINC="$OPTARG" checkval="ADMIN_PRINC"; check_value $ADMIN_PRINC ;; c) options="$options -c" filepath="$OPTARG" ;; d) options="$options -d" dnsarg="$OPTARG" checkval="DNS_OPTIONS"; check_value $dnsarg ;; f) options="$options -f" fqdnlist="$OPTARG" ;; h) options="$options -h" logical_hn="$OPTARG" checkval="LOGICAL_HOSTNAME"; check_value $logical_hn ;; k) options="$options -k" kdc_list="${OPTARG//,/ }" # If kdc_list is empty or only contains spaces error out if [[ -z $kdc_list || -z ${kdc_list// /} ]]; then printf "\n$(gettext "At least one %s should be listed with -k").\n\n" "KDC" >&2 usage fi ;; m) options="$options -m" #KDC="$OPTARG" master_kdc_list="${OPTARG//,/ }" # If master_kdc_list is empty or only contains spaces error out if [[ -z $master_kdc_list || -z ${master_kdc_list// /} ]]; then printf "\n$(gettext "At least one %s should be listed with -k").\n\n" "KDC" >&2 usage fi ;; n) options="$options -n" add_nfs=yes ;; p) options="$options -p" profile="$OPTARG" read_profile $profile ;; s) options="$options -s" svc_list="$OPTARG" verify_pam_svc_list $svc_list SVCs=${svc_list//,/ } ;; x) xml_profile="$OPTARG" ;; \?) usage ;; *) usage ;; esac done #correct argument count after options shift `expr $OPTIND - 1` if [[ -z $options ]]; then : else if [[ $# -ne 0 ]]; then usage fi fi if [[ -n $xml_profile ]]; then xml_profile_prompts write_xml_profile $xml_profile # runs exec, never returns # unreachable fi # # Check to see if we will be a client of a MIT, Heimdal, Shishi, etc. # if [[ -z $options ]]; then query "$(gettext "Is this a client of a non-Solaris KDC") ?" non_solaris=$answer if [[ $non_solaris == yes ]]; then printf "$(gettext "Which type of KDC is the server"):\n" printf "\t$(gettext "ms_ad: Microsoft Active Directory")\n" printf "\t$(gettext "mit: MIT KDC server")\n" printf "\t$(gettext "heimdal: Heimdal KDC server")\n" printf "\t$(gettext "shishi: Shishi KDC server")\n" printf "$(gettext "Enter required KDC type"): " read kdctype if [[ $kdctype == ms_ad ]]; then msad=yes elif [[ $kdctype == mit || $kdctype == heimdal || \ $kdctype == shishi ]]; then no_keytab=yes else printf "\n$(gettext "Invalid KDC type option, valid types are ms_ad, mit, heimdal, or shishi, exiting").\n" >&2 error_message fi fi fi [[ $msad == yes ]] && join_domain # # Check for running DNS client service # dns_state=$($SVCS -H -o state $DNS_CLIENT_FMRI) if [[ $? -ne 0 ]]; then printf "\n$(gettext "Error while reading DNS client service state.")\n" >&2 dns_state="" fi if [[ "$dns_state" == @(online|degraded) ]]; then client_machine=`$KLOOKUP` if [[ $? -ne 0 ]]; then if [[ $adddns == no ]]; then printf "\n$(gettext "%s does not have a DNS record and is required for Kerberos setup")\n" $hostname >&2 error_message fi else # # If client entry already exists then do not recreate it # adddns=no hostname=${client_machine%%.*} domain=${client_machine#*.} fi short_fqdn=${domain#*.*} short_fqdn=$(echo $short_fqdn | grep "\.") else # # DNS client service not running, exit ... # if [[ -n "$dns_state" ]]; then printf "\n$(gettext "The DNS client service state is %s. It must be running (online or degraded) for Kerberos setup.")\n" "$dns_state" >&2 else printf "\n$(gettext "The DNS client service state is not known. It must be running (online or degraded) for Kerberos setup.")\n" >&2 fi printf "\n$(gettext "Check the DNS client service status with the command: %s -xv %s")\n" $SVCS $DNS_CLIENT_FMRI >&2 printf "$(gettext "Refer to resolv.conf(5), exiting").\n" >&2 error_message fi check_nss_conf || printf "$(gettext "/etc/nsswitch.conf does not make use of DNS for hosts and/or ipnodes").\n" [[ -n $fqdnlist ]] && verify_fqdnlist "$fqdnlist" if [[ -z $dnsarg && (-z $options || -z $filepath) ]]; then query "$(gettext "Do you want to use DNS for kerberos lookups") ?" if [[ $answer == yes ]]; then printf "\n$(gettext "Valid DNS lookup options are dns_lookup_kdc, dns_lookup_realm,\nand dns_fallback. Refer krb5.conf(5) for further details").\n" printf "\n$(gettext "Enter required DNS option"): " read dnsarg checkval="DNS_OPTIONS"; check_value $dnsarg set_dns_value $dnsarg fi else [[ -z $dnsarg ]] && dnsarg=none set_dns_value $dnsarg fi if [[ -n $kdc_list ]]; then if [[ -z $master_kdc_list ]]; then # assign first kdc to master kdc list, rest to slave list print $kdc_list|read master_kdc_list slave_kdc_list else # masters were already specified so this is just slaves slave_kdc_list="$kdc_list" fi fi if [[ -z $realm ]]; then printf "$(gettext "Enter the Kerberos realm"): " read realm checkval="REALM"; check_value $realm fi if [[ -z $master_kdc_list ]]; then printf "$(gettext "Specify the master KDCs for the above realm using a comma-separated list"): " read master_kdc_list fi if [[ -n $master_kdc_list ]]; then master_kdc_list=$(verify_kdcs "$master_kdc_list") # Much of this script wants to access one master kdc in the KDC variable # so KDC is the first in the list. print $master_kdc_list|read KDC junk else printf "\n$(gettext "At least one %s should be entered").\n\n" "KDC" >&2 error_message fi FKDC=$($KLOOKUP $KDC) if [[ -z $slave_kdc_list && (-z $options || -z $filepath) ]]; then query "$(gettext "Do you have any slave KDC(s)") ?" if [[ $answer == yes ]]; then printf "$(gettext "Enter a comma-separated list of slave KDC host names"): " read slave_kdc_list fi fi [[ -n $slave_kdc_list ]] && slave_kdc_list=$(verify_kdcs "$slave_kdc_list") found=false for kdc in $slave_kdc_list $master_kdc_list; do if ping $kdc 2 > /dev/null; then found=true break fi done ! $found && printf "\n$(gettext "Warning, no %s is reachable.").\n\n" "KDC" >&2 # # Check to see if we will have a dynamic presence in the realm # if [[ -z $options ]]; then query "$(gettext "Will this client need service keys") ?" if [[ $answer == no ]]; then no_keytab=yes fi fi # # Check to see if we are configuring the client to use a logical host name # of a cluster environment # if [[ -z $options ]]; then query "$(gettext "Is this client a member of a cluster that uses a logical host name") ?" if [[ $answer == yes ]]; then printf "$(gettext "Specify the logical hostname of the cluster"): " read logical_hn checkval="LOGICAL_HOSTNAME"; check_value $logical_hn fi fi if [[ -n $logical_hn ]]; then setup_lhn fi if [[ -z $domain_list && (-z $options || -z $filepath) ]]; then query "$(gettext "Do you have multiple domains/hosts to map to realm %s" ) ?" $realm if [[ $answer == yes ]]; then printf "$(gettext "Enter a comma-separated list of domain/hosts to map to the default realm"): " read domain_list fi fi [[ -n $domain_list ]] && domain_list=${domain_list//,/ } # # Start writing up the krb5.conf file, save the existing one # if already present # writeup_krb5_conf # # Is this client going to use krb-nfs? If so then we need to at least # uncomment the krb5* sec flavors in nfssec.conf. # if [[ -z $options ]]; then query "$(gettext "Do you plan on doing Kerberized nfs") ?" add_nfs=$answer fi if [[ $add_nfs == yes ]]; then modify_nfssec_conf # # We also want to enable gss as we now live in a SBD world # svcadm enable svc:/network/rpc/gss:default [[ $? -ne 0 ]] && printf "$(gettext "Warning: could not enable gss service").\n" fi if [[ -z $options ]]; then query "$(gettext "Do you want to update/add PAM per-service policy file(s)") ?" if [[ $answer == yes ]]; then printf "$(gettext "Enter a list of PAM service names in the following format: service:{first|only|optional}[,..]"): " read svc_list verify_pam_svc_list $svc_list SVCs=${svc_list//,/ } fi fi [[ -n $svc_list ]] && update_pam_conf # # Copy over krb5.conf master copy from filepath # if [[ -z $options || -z $filepath ]]; then query "$(gettext "Do you want to copy over the master krb5.conf file") ?" if [[ $answer == yes ]]; then printf "$(gettext "Enter the pathname of the file to be copied"): " read filepath fi fi if [[ -n $filepath && -r $filepath ]]; then cp $filepath $KRB5_CONFIG if [[ $? -eq 0 ]]; then printf "$(gettext "Copied %s to %s").\n" $filepath $KRB5_CONFIG else printf "$(gettext "Copy of %s failed, exiting").\n" $filepath >&2 error_message fi elif [[ -n $filepath ]]; then printf "\n$(gettext "%s not found, exiting").\n" $filepath >&2 error_message fi doKRB5config # # Populate any service keys needed for the client in the keytab file # if [[ $no_keytab != yes ]]; then setup_keytab else printf "\n$(gettext "Note: %s file not created, please refer to verify_ap_req_nofail in krb5.conf(5) for the implications").\n" $KRB5_KEYTAB_FILE printf "$(gettext "Client will also not be able to host services that use Kerberos").\n" fi # # Start ktkt_warn service if it is disabled # enable_warnd_srv printf -- "\n---------------------------------------------------\n" printf "$(gettext "Setup COMPLETE").\n\n" # # If we have configured the client in a cluster we need to remind the user # to propagate the keytab and configuration files to the other members. # if [[ -n $logical_hn ]]; then printf "\n$(gettext "Note, you will need to securely transfer the %s and %s files to all the other members of your cluster").\n" $KRB5_KEYTAB_FILE $KRB5_CONFIG fi # # Cleanup. # kdestroy -q 1>$TMP_FILE 2>&1 rm -f $TMP_FILE rm -rf $TMPDIR > /dev/null 2>&1 exit 0