16815Ssemery#!/bin/ksh93 -p 20Sstevel@tonic-gate# 36656Ssemery# CDDL HEADER START 46656Ssemery# 56656Ssemery# The contents of this file are subject to the terms of the 66656Ssemery# Common Development and Distribution License (the "License"). 76656Ssemery# You may not use this file except in compliance with the License. 86656Ssemery# 96656Ssemery# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 106656Ssemery# or http://www.opensolaris.org/os/licensing. 116656Ssemery# See the License for the specific language governing permissions 126656Ssemery# and limitations under the License. 136656Ssemery# 146656Ssemery# When distributing Covered Code, include this CDDL HEADER in each 156656Ssemery# file and include the License file at usr/src/OPENSOLARIS.LICENSE. 166656Ssemery# If applicable, add the following below this CDDL HEADER, with the 176656Ssemery# fields enclosed by brackets "[]" replaced with your own identifying 186656Ssemery# information: Portions Copyright [yyyy] [name of copyright owner] 196656Ssemery# 206656Ssemery# CDDL HEADER END 216656Ssemery# 22*12567SShawn.Emery@Sun.COM# Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. 230Sstevel@tonic-gate# 240Sstevel@tonic-gate# This script is used to setup the Kerberos client by 250Sstevel@tonic-gate# supplying information about the Kerberos realm and kdc. 260Sstevel@tonic-gate# 270Sstevel@tonic-gate# The kerberos configuration file (/etc/krb5/krb5.conf) would 280Sstevel@tonic-gate# be generated and local host's keytab file setup. The script 290Sstevel@tonic-gate# can also optionally setup the system to do kerberized nfs and 300Sstevel@tonic-gate# bringover a master krb5.conf copy from a specified location. 3111061SShawn.Emery@Sun.COM# 320Sstevel@tonic-gate 336656Ssemeryfunction cleanup { 346656Ssemery 359833SShawn.Emery@Sun.COM kdestroy -q > $TMP_FILE 2>&1 366656Ssemery rm -r $TMPDIR > /dev/null 2>&1 376656Ssemery 389833SShawn.Emery@Sun.COM exit $1 396656Ssemery} 406656Ssemeryfunction exiting { 416656Ssemery 426656Ssemery printf "\n$(gettext "Exiting setup, nothing changed").\n\n" 436656Ssemery 446656Ssemery cleanup $1 450Sstevel@tonic-gate} 460Sstevel@tonic-gate 476656Ssemeryfunction error_message { 486656Ssemery 499833SShawn.Emery@Sun.COM printf -- "---------------------------------------------------\n" >&2 509833SShawn.Emery@Sun.COM printf "$(gettext "Setup FAILED").\n\n" >&2 516656Ssemery 526656Ssemery cleanup 1 536656Ssemery} 546656Ssemery 556656Ssemeryfunction check_bin { 566656Ssemery 576656Ssemery typeset bin=$1 586656Ssemery 596656Ssemery if [[ ! -x $bin ]]; then 609833SShawn.Emery@Sun.COM printf "$(gettext "Could not access/execute %s").\n" $bin >&2 610Sstevel@tonic-gate error_message 620Sstevel@tonic-gate fi 630Sstevel@tonic-gate} 640Sstevel@tonic-gate 656656Ssemeryfunction cannot_create { 666656Ssemery typeset filename="$1" 676656Ssemery typeset stat="$2" 686656Ssemery 696656Ssemery if [[ $stat -ne 0 ]]; then 706656Ssemery printf "\n$(gettext "Can not create/edit %s, exiting").\n" $filename >&2 716656Ssemery error_message 726656Ssemery fi 736656Ssemery} 746656Ssemery 756656Ssemeryfunction update_pam_conf { 766656Ssemery typeset PAM TPAM service 776656Ssemery 786656Ssemery PAM=/etc/pam.conf 796656Ssemery 806656Ssemery TPAM=$(mktemp -q -t kclient-pamconf.XXXXXX) 816656Ssemery if [[ -z $TPAM ]]; then 826656Ssemery printf "\n$(gettext "Can not create temporary file, exiting").\n" >&2 836656Ssemery error_message 846656Ssemery fi 856656Ssemery 866656Ssemery cp $PAM $TPAM >/dev/null 2>&1 876656Ssemery 886656Ssemery printf "$(gettext "Configuring %s").\n\n" $PAM 896656Ssemery 906656Ssemery for service in $SVCs; do 916656Ssemery svc=${service%:*} 926656Ssemery auth_type=${service#*:} 936656Ssemery if egrep -s "^$svc[ ][ ]*auth.*pam_krb5*" $TPAM; then 946815Ssemery printf "$(gettext "The %s service is already configured for pam_krb5, please merge this service in %s").\n\n" $svc $PAM >&2 956656Ssemery continue 966656Ssemery else 976656Ssemery exec 3>>$TPAM 986815Ssemery printf "\n$svc\tauth include\t\tpam_krb5_$auth_type\n" 1>&3 996656Ssemery fi 1006656Ssemery done 1016656Ssemery 1026656Ssemery cp $TPAM $PAM > /dev/null 2>&1 1036656Ssemery 1046656Ssemery rm $TPAM > /dev/null 2>&1 1056656Ssemery} 1066656Ssemery 1076656Ssemeryfunction modify_nfssec_conf { 1086656Ssemery typeset NFSSEC_FILE="/etc/nfssec.conf" 1096656Ssemery 1106656Ssemery if [[ -r $NFSSEC_FILE ]]; then 1110Sstevel@tonic-gate cat $NFSSEC_FILE > $NFSSEC_FILE.sav 1120Sstevel@tonic-gate cannot_create $NFSSEC_FILE.sav $? 1130Sstevel@tonic-gate fi 1140Sstevel@tonic-gate 1150Sstevel@tonic-gate cat $NFSSEC_FILE > $TMP_FILE 1160Sstevel@tonic-gate cannot_create $TMP_FILE $? 1170Sstevel@tonic-gate 1180Sstevel@tonic-gate if grep -s "#krb5" $NFSSEC_FILE > /dev/null 2>&1; then 1190Sstevel@tonic-gate sed "s%^#krb5%krb5%" $TMP_FILE >$NFSSEC_FILE 1200Sstevel@tonic-gate cannot_create $NFSSEC_FILE $? 1210Sstevel@tonic-gate fi 1220Sstevel@tonic-gate} 1230Sstevel@tonic-gate 1246656Ssemeryfunction call_kadmin { 1250Sstevel@tonic-gate typeset svc="$1" 1260Sstevel@tonic-gate typeset bool1 bool2 bool3 bool4 1276656Ssemery typeset service_princ getprincsubcommand anksubcommand ktaddsubcommand 1286656Ssemery typeset ktremsubcommand 1290Sstevel@tonic-gate 1300Sstevel@tonic-gate for listentry in $fqdnlist; do 1310Sstevel@tonic-gate 1320Sstevel@tonic-gate # Reset conditional vars to 1 1330Sstevel@tonic-gate bool1=1; bool2=1; bool3=1; bool4=1 1340Sstevel@tonic-gate 1356656Ssemery service_princ=$(echo "${svc}/${listentry}") 1360Sstevel@tonic-gate getprincsubcommand="getprinc $service_princ" 1370Sstevel@tonic-gate anksubcommand="addprinc -randkey $service_princ" 1380Sstevel@tonic-gate ktaddsubcommand="ktadd $service_princ" 1396656Ssemery ktremsubcommand="ktrem $service_princ all" 1400Sstevel@tonic-gate 1416656Ssemery kadmin -c $KRB5CCNAME -q "$getprincsubcommand" 1>$TMP_FILE 2>&1 1420Sstevel@tonic-gate 1436815Ssemery egrep -s "$(gettext "get_principal: Principal does not exist")" $TMP_FILE 1440Sstevel@tonic-gate bool1=$? 1456815Ssemery egrep -s "$(gettext "get_principal: Operation requires ``get")" $TMP_FILE 1460Sstevel@tonic-gate bool2=$? 1470Sstevel@tonic-gate 1480Sstevel@tonic-gate if [[ $bool1 -eq 0 || $bool2 -eq 0 ]]; then 1496656Ssemery kadmin -c $KRB5CCNAME -q "$anksubcommand" 1>$TMP_FILE 2>&1 1500Sstevel@tonic-gate 1516815Ssemery egrep -s "$(gettext "add_principal: Principal or policy already exists while creating \"$service_princ@$realm\".")" $TMP_FILE 1520Sstevel@tonic-gate bool3=$? 1530Sstevel@tonic-gate 1546815Ssemery egrep -s "$(gettext "Principal \"$service_princ@$realm\" created.")" $TMP_FILE 1550Sstevel@tonic-gate bool4=$? 1560Sstevel@tonic-gate 1570Sstevel@tonic-gate if [[ $bool3 -eq 0 || $bool4 -eq 0 ]]; then 1580Sstevel@tonic-gate printf "$(gettext "%s entry ADDED to KDC database").\n" $service_princ 1590Sstevel@tonic-gate else 1600Sstevel@tonic-gate cat $TMP_FILE; 1616656Ssemery printf "\n$(gettext "kadmin: add_principal of %s failed, exiting").\n" $service_princ >&2 1620Sstevel@tonic-gate error_message 1630Sstevel@tonic-gate fi 1640Sstevel@tonic-gate else 1656656Ssemery printf "$(gettext "%s entry already exists in KDC database").\n" $service_princ >&2 1660Sstevel@tonic-gate fi 1670Sstevel@tonic-gate 1680Sstevel@tonic-gate klist -k 1>$TMP_FILE 2>&1 1696656Ssemery egrep -s "$service_princ@$realm" $TMP_FILE 1706656Ssemery if [[ $? -eq 0 ]]; then 1716656Ssemery printf "$(gettext "%s entry already present in keytab").\n" $service_princ >&2 1726656Ssemery # Don't care is this succeeds or not, just need to replace old 1736656Ssemery # entries as it is assummed that the client is reinitialized 1746656Ssemery kadmin -c $KRB5CCNAME -q "$ktremsubcommand" 1>$TMP_FILE 2>&1 1756656Ssemery fi 1766656Ssemery 1776656Ssemery kadmin -c $KRB5CCNAME -q "$ktaddsubcommand" 1>$TMP_FILE 2>&1 1786815Ssemery egrep -s "$(gettext "added to keytab WRFILE:$KRB5_KEYTAB_FILE.")" $TMP_FILE 1796656Ssemery if [[ $? -ne 0 ]]; then 1806656Ssemery cat $TMP_FILE; 1816656Ssemery printf "\n$(gettext "kadmin: ktadd of %s failed, exiting").\n" $service_princ >&2 1826656Ssemery error_message 1830Sstevel@tonic-gate else 1846656Ssemery printf "$(gettext "%s entry ADDED to keytab").\n" $service_princ 1850Sstevel@tonic-gate fi 1860Sstevel@tonic-gate 1870Sstevel@tonic-gate done 1880Sstevel@tonic-gate} 1890Sstevel@tonic-gate 1906656Ssemeryfunction writeup_krb5_conf { 1916656Ssemery typeset dh 1920Sstevel@tonic-gate 1936656Ssemery printf "\n$(gettext "Setting up %s").\n\n" $KRB5_CONFIG_FILE 1940Sstevel@tonic-gate 1956656Ssemery exec 3>$KRB5_CONFIG 1966656Ssemery if [[ $? -ne 0 ]]; then 1979833SShawn.Emery@Sun.COM printf "\n$(gettext "Can not write to %s, exiting").\n" $KRB5_CONFIG >&2 1980Sstevel@tonic-gate error_message 1990Sstevel@tonic-gate fi 2000Sstevel@tonic-gate 2016656Ssemery printf "[libdefaults]\n" 1>&3 2026656Ssemery if [[ $no_keytab == yes ]]; then 2036656Ssemery printf "\tverify_ap_req_nofail = false\n" 1>&3 2046656Ssemery fi 2056656Ssemery if [[ $dns_lookup == yes ]]; then 2066656Ssemery printf "\t$dnsarg = on\n" 1>&3 2076656Ssemery if [[ $dnsarg == dns_lookup_kdc ]]; then 2086656Ssemery printf "\tdefault_realm = $realm\n" 1>&3 2096656Ssemery printf "\n[domain_realm]\n" 1>&3 2106656Ssemery if [[ -n $fkdc_list ]]; then 2116656Ssemery for kdc in $fkdc_list; do 2126656Ssemery printf "\t$kdc = $realm\n" 1>&3 2136656Ssemery done 2146656Ssemery fi 2156656Ssemery printf "\t$FKDC = $realm\n" 1>&3 2166656Ssemery printf "\t$client_machine = $realm\n" 1>&3 2176656Ssemery if [[ -z $short_fqdn ]]; then 2186656Ssemery printf "\t.$domain = $realm\n\n" 1>&3 2196656Ssemery else 2206656Ssemery printf "\t.$short_fqdn = $realm\n\n" 1>&3 2216656Ssemery fi 2226656Ssemery if [[ -n $domain_list ]]; then 2236656Ssemery for dh in $domain_list; do 2246656Ssemery printf "\t$dh = $realm\n" 1>&3 2256656Ssemery done 2266656Ssemery fi 2270Sstevel@tonic-gate else 2286656Ssemery if [[ $dnsarg = dns_lookup_realm ]]; then 2296815Ssemery printf "\tdefault_realm = $realm\n" 1>&3 2306656Ssemery printf "\n[realms]\n" 1>&3 2316656Ssemery printf "\t$realm = {\n" 1>&3 2326656Ssemery if [[ -n $kdc_list ]]; then 2336656Ssemery for kdc in $kdc_list; do 2346656Ssemery printf "\t\tkdc = $kdc\n" 1>&3 2356656Ssemery done 2366656Ssemery else 2376656Ssemery printf "\t\tkdc = $KDC\n" 1>&3 2386656Ssemery fi 2396656Ssemery printf "\t\tadmin_server = $KDC\n" 1>&3 2406656Ssemery if [[ $non_solaris == yes ]]; then 2416656Ssemery printf "\n\t\tkpasswd_protocol = SET_CHANGE\n" 1>&3 2426656Ssemery fi 2436656Ssemery printf "\t}\n\n" 1>&3 2440Sstevel@tonic-gate else 2456815Ssemery printf "\tdefault_realm = $realm\n\n" 1>&3 2460Sstevel@tonic-gate fi 2470Sstevel@tonic-gate fi 2480Sstevel@tonic-gate else 2496656Ssemery printf "\tdefault_realm = $realm\n\n" 1>&3 2506656Ssemery 2516656Ssemery printf "[realms]\n" 1>&3 2526656Ssemery printf "\t$realm = {\n" 1>&3 2536656Ssemery if [[ -n $kdc_list ]]; then 2546656Ssemery for kdc in $kdc_list; do 2556656Ssemery printf "\t\tkdc = $kdc\n" 1>&3 2566656Ssemery done 2576656Ssemery else 2586656Ssemery printf "\t\tkdc = $KDC\n" 1>&3 2596656Ssemery fi 2606656Ssemery printf "\t\tadmin_server = $KDC\n" 1>&3 2616656Ssemery if [[ $non_solaris == yes ]]; then 2626656Ssemery printf "\n\t\tkpasswd_protocol = SET_CHANGE\n" 1>&3 2636656Ssemery fi 2646656Ssemery printf "\t}\n\n" 1>&3 2650Sstevel@tonic-gate 2666656Ssemery printf "[domain_realm]\n" 1>&3 2676656Ssemery if [[ -n $fkdc_list ]]; then 2686656Ssemery for kdc in $fkdc_list; do 2696656Ssemery printf "\t$kdc = $realm\n" 1>&3 2706656Ssemery done 2716656Ssemery fi 2726656Ssemery printf "\t$FKDC = $realm\n" 1>&3 2736656Ssemery printf "\t$client_machine = $realm\n" 1>&3 2746656Ssemery if [[ -z $short_fqdn ]]; then 2756656Ssemery printf "\t.$domain = $realm\n\n" 1>&3 2766656Ssemery else 2776656Ssemery printf "\t.$short_fqdn = $realm\n\n" 1>&3 2786656Ssemery fi 2796656Ssemery if [[ -n $domain_list ]]; then 2806656Ssemery for dh in $domain_list; do 2816656Ssemery printf "\t$dh = $realm\n" 1>&3 2826656Ssemery done 2836656Ssemery fi 2840Sstevel@tonic-gate fi 2850Sstevel@tonic-gate 2866656Ssemery printf "[logging]\n" 1>&3 2876656Ssemery printf "\tdefault = FILE:/var/krb5/kdc.log\n" 1>&3 2886656Ssemery printf "\tkdc = FILE:/var/krb5/kdc.log\n" 1>&3 2896656Ssemery printf "\tkdc_rotate = {\n\t\tperiod = 1d\n\t\tversions = 10\n\t}\n\n" 1>&3 2900Sstevel@tonic-gate 2916656Ssemery printf "[appdefaults]\n" 1>&3 2926656Ssemery printf "\tkinit = {\n\t\trenewable = true\n\t\tforwardable = true\n" 1>&3 2936656Ssemery if [[ $no_keytab == yes ]]; then 2946656Ssemery printf "\t\tno_addresses = true\n" 1>&3 2956656Ssemery fi 2966656Ssemery printf "\t}\n" 1>&3 2970Sstevel@tonic-gate} 2980Sstevel@tonic-gate 2996656Ssemeryfunction ask { 3006656Ssemery typeset question=$1 3016656Ssemery typeset default_answer=$2 3026656Ssemery 3036656Ssemery if [[ -z $default_answer ]]; then 3046656Ssemery printf "$question :" 3050Sstevel@tonic-gate else 3066656Ssemery printf "$question [$default_answer]: " 3070Sstevel@tonic-gate fi 3080Sstevel@tonic-gate read answer 3090Sstevel@tonic-gate test -z "$answer" && answer="$default_answer" 3100Sstevel@tonic-gate} 3110Sstevel@tonic-gate 3126656Ssemeryfunction yesno { 3130Sstevel@tonic-gate typeset question="$1" 3146656Ssemery 3156656Ssemery answer= 3166656Ssemery yn=`printf "$(gettext "y/n")"` 3176656Ssemery y=`printf "$(gettext "y")"` 3186656Ssemery n=`printf "$(gettext "n")"` 3196656Ssemery yes=`printf "$(gettext "yes")"` 3206656Ssemery no=`printf "$(gettext "no")"` 3216656Ssemery 3226656Ssemery while [[ -z $answer ]]; do 3236656Ssemery ask "$question" $yn 3246656Ssemery case $answer in 3256656Ssemery $y|$yes) answer=yes;; 3266656Ssemery $n|$no) answer=no;; 3276656Ssemery *) answer=;; 3280Sstevel@tonic-gate esac 3290Sstevel@tonic-gate done 3300Sstevel@tonic-gate} 3310Sstevel@tonic-gate 3326656Ssemeryfunction query { 3330Sstevel@tonic-gate yesno "$*" 3346656Ssemery 3356656Ssemery if [[ $answer == no ]]; then 3360Sstevel@tonic-gate printf "\t$(gettext "No action performed").\n" 3370Sstevel@tonic-gate fi 3380Sstevel@tonic-gate} 3390Sstevel@tonic-gate 3400Sstevel@tonic-gate 3416656Ssemeryfunction read_profile { 3420Sstevel@tonic-gate typeset param value 3430Sstevel@tonic-gate typeset file="$1" 3446656Ssemery 3450Sstevel@tonic-gate if [[ ! -d $file && -r $file ]]; then 3460Sstevel@tonic-gate while read param value 3470Sstevel@tonic-gate do 3486656Ssemery case $param in 3496656Ssemery REALM) if [[ -z $realm ]]; then 3506656Ssemery realm="$value" 3516656Ssemery checkval="REALM"; check_value $realm 3520Sstevel@tonic-gate fi 3530Sstevel@tonic-gate ;; 3546656Ssemery KDC) if [[ -z $KDC ]]; then 3550Sstevel@tonic-gate KDC="$value" 3560Sstevel@tonic-gate checkval="KDC"; check_value $KDC 3570Sstevel@tonic-gate fi 3580Sstevel@tonic-gate ;; 3596656Ssemery ADMIN) if [[ -z $ADMIN_PRINC ]]; then 3600Sstevel@tonic-gate ADMIN_PRINC="$value" 3610Sstevel@tonic-gate checkval="ADMIN_PRINC" 3620Sstevel@tonic-gate check_value $ADMIN_PRINC 3630Sstevel@tonic-gate fi 3640Sstevel@tonic-gate ;; 3656656Ssemery FILEPATH) if [[ -z $filepath ]]; then 3660Sstevel@tonic-gate filepath="$value" 3670Sstevel@tonic-gate fi 3680Sstevel@tonic-gate ;; 3696656Ssemery NFS) if [[ -z $add_nfs ]]; then 3706656Ssemery if [[ $value == 1 ]]; then 3710Sstevel@tonic-gate add_nfs=yes 3720Sstevel@tonic-gate else 3730Sstevel@tonic-gate add_nfs=no 3740Sstevel@tonic-gate fi 3750Sstevel@tonic-gate fi 3760Sstevel@tonic-gate ;; 3776656Ssemery NOKEY) if [[ -z $no_keytab ]]; then 3786656Ssemery if [[ $value == 1 ]]; then 3796656Ssemery no_keytab=yes 3806656Ssemery else 3816656Ssemery no_keytab=no 3826656Ssemery fi 3836656Ssemery fi 3846656Ssemery ;; 3856656Ssemery NOSOL) if [[ -z $non_solaris ]]; then 3866656Ssemery if [[ $value == 1 ]]; then 3876656Ssemery non_solaris=yes 3886656Ssemery no_keytab=yes 3896656Ssemery else 3906656Ssemery non_solaris=no 3916656Ssemery fi 3926656Ssemery fi 3936656Ssemery ;; 3946656Ssemery LHN) if [[ -z $logical_hn ]]; then 3956656Ssemery logical_hn="$value" 3966656Ssemery checkval="LOGICAL_HOSTNAME" 3976656Ssemery check_value $logical_hn 3986656Ssemery fi 3996656Ssemery ;; 4006656Ssemery DNSLOOKUP) if [[ -z $dnsarg ]]; then 4010Sstevel@tonic-gate dnsarg="$value" 4020Sstevel@tonic-gate checkval="DNS_OPTIONS" 4030Sstevel@tonic-gate check_value $dnsarg 4040Sstevel@tonic-gate fi 4050Sstevel@tonic-gate ;; 4066656Ssemery FQDN) if [[ -z $fqdnlist ]]; then 4070Sstevel@tonic-gate fqdnlist="$value" 4080Sstevel@tonic-gate checkval="FQDN" 4090Sstevel@tonic-gate check_value $fqdnlist 4100Sstevel@tonic-gate verify_fqdnlist "$fqdnlist" 4110Sstevel@tonic-gate fi 4120Sstevel@tonic-gate ;; 4136656Ssemery MSAD) if [[ -z $msad ]]; then 4146656Ssemery if [[ $value == 1 ]]; then 4156656Ssemery msad=yes 4166656Ssemery non_solaris=yes 4176656Ssemery else 4186656Ssemery msad=no 4196656Ssemery fi 4206656Ssemery fi 4216656Ssemery ;; 4220Sstevel@tonic-gate esac 4230Sstevel@tonic-gate done <$file 4240Sstevel@tonic-gate else 4256656Ssemery printf "\n$(gettext "The kclient profile \`%s' is not valid, exiting").\n" $file >&2 4260Sstevel@tonic-gate error_message 4270Sstevel@tonic-gate fi 4280Sstevel@tonic-gate} 4290Sstevel@tonic-gate 4306656Ssemeryfunction ping_check { 4310Sstevel@tonic-gate typeset machine="$1" 4320Sstevel@tonic-gate typeset string="$2" 4336656Ssemery 4346656Ssemery if ping $machine 2 > /dev/null 2>&1; then 4350Sstevel@tonic-gate : 4360Sstevel@tonic-gate else 4376656Ssemery printf "\n$(gettext "%s %s is unreachable, exiting").\n" $string $machine >&2 4380Sstevel@tonic-gate error_message 4390Sstevel@tonic-gate fi 4400Sstevel@tonic-gate 4410Sstevel@tonic-gate # Output timesync warning if not using a profile, i.e. in 4420Sstevel@tonic-gate # interactive mode. 4436656Ssemery if [[ -z $profile && $string == KDC ]]; then 4440Sstevel@tonic-gate # It's difficult to sync up time with KDC esp. if in a 4450Sstevel@tonic-gate # zone so just print a warning about KDC time sync. 4466815Ssemery 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 4476815Ssemery printf "$(gettext "Both systems should run some form of time synchronization system like Network Time Protocol (NTP)").\n" >&2 4486656Ssemerybreak 4490Sstevel@tonic-gate fi 4500Sstevel@tonic-gate} 4510Sstevel@tonic-gate 4526656Ssemeryfunction check_value { 4530Sstevel@tonic-gate typeset arg="$1" 4546656Ssemery 4556656Ssemery if [[ -z $arg ]]; then 4566656Ssemery printf "\n$(gettext "No input obtained for %s, exiting").\n" $checkval >&2 4570Sstevel@tonic-gate error_message 4580Sstevel@tonic-gate else 4596656Ssemery echo "$arg" > $TMP_FILE 4600Sstevel@tonic-gate if egrep -s '[*$^#!]+' $TMP_FILE; then 4616656Ssemery printf "\n$(gettext "Invalid input obtained for %s, exiting").\n" $checkval >&2 4626656Ssemery error_message 4636656Ssemery fi 4646656Ssemery fi 4656656Ssemery} 4666656Ssemery 4676656Ssemeryfunction set_dns_value { 4686656Ssemery typeset -l arg="$1" 4696656Ssemery 4706656Ssemery if [[ $arg == dns_lookup_kdc || $arg == dns_lookup_realm || $arg == dns_fallback ]]; then 4716656Ssemery dns_lookup=yes 4726656Ssemery else 4736656Ssemery if [[ $arg == none ]]; then 4746656Ssemery dns_lookup=no 4756656Ssemery else 4766656Ssemery printf "\n$(gettext "Invalid DNS lookup option, exiting").\n" >&2 4770Sstevel@tonic-gate error_message 4780Sstevel@tonic-gate fi 4790Sstevel@tonic-gate fi 4800Sstevel@tonic-gate} 4810Sstevel@tonic-gate 4826656Ssemeryfunction verify_kdcs { 4836656Ssemery typeset k_list="$1" 4846656Ssemery typeset -l kdc 4856656Ssemery typeset list fqhn f_list 4866656Ssemery 4876656Ssemery kdc_list=$(echo "$k_list" | sed 's/,/ /g') 4886656Ssemery 4896656Ssemery if [[ -z $k_list ]]; then 4906656Ssemery printf "\n$(gettext "At least one KDC should be listed").\n\n" >&2 4916656Ssemery usage 4926656Ssemery fi 4936656Ssemery 4946656Ssemery for kdc in $k_list; do 4956656Ssemery if [[ $kdc != $KDC ]]; then 4966656Ssemery list="$list $kdc" 4976656Ssemery fkdc=`$KLOOKUP $kdc` 4986656Ssemery if ping $fkdc 2 > /dev/null; then 4996656Ssemery : 5006656Ssemery else 5016656Ssemery printf "\n$(gettext "%s %s is unreachable, no action performed").\n" "KDC" $fkdc >&2 5026656Ssemery fi 5036656Ssemery f_list="$f_list $fkdc" 5040Sstevel@tonic-gate fi 5056656Ssemery done 5066656Ssemery 5076656Ssemery fkdc_list="$f_list" 5086656Ssemery kdc_list="$list" 5090Sstevel@tonic-gate} 5100Sstevel@tonic-gate 5116656Ssemeryfunction parse_service { 5126656Ssemery typeset service_list=$1 5130Sstevel@tonic-gate 5146656Ssemery service_list=${service_list//,/ } 5156656Ssemery for service in $service_list; do 5166656Ssemery svc=${service%:} 5176656Ssemery auth_type=${service#:} 5186656Ssemery [[ -z $svc || -z $auth_type ]] && return 5196656Ssemery print -- $svc $auth_type 5206656Ssemery done 5216656Ssemery} 5226656Ssemery 5236656Ssemeryfunction verify_fqdnlist { 5246656Ssemery typeset list="$1" 5256656Ssemery typeset -l hostname 5266656Ssemery typeset -i count=1 5276656Ssemery typeset fqdnlist eachfqdn tmpvar fullhost 5286656Ssemery 5296656Ssemery list=$(echo "$list" | tr -d " " | tr -d "\t") 5306656Ssemery hostname=$(uname -n | cut -d"." -f1) 5310Sstevel@tonic-gate fqdnlist=$client_machine 5320Sstevel@tonic-gate 5330Sstevel@tonic-gate eachfqdn=$(echo "$list" | cut -d"," -f$count) 5346656Ssemery if [[ -z $eachfqdn ]]; then 5356656Ssemery printf "\n$(gettext "If the -f option is used, at least one FQDN should be listed").\n\n" >&2 5360Sstevel@tonic-gate usage 5370Sstevel@tonic-gate else 5386656Ssemery while [[ ! -z $eachfqdn ]]; do 5390Sstevel@tonic-gate tmpvar=$(echo "$eachfqdn" | cut -d"." -f1) 5406656Ssemery if [[ -z $tmpvar ]]; then 5410Sstevel@tonic-gate fullhost="$hostname$eachfqdn" 5420Sstevel@tonic-gate else 5430Sstevel@tonic-gate fullhost="$hostname.$eachfqdn" 5440Sstevel@tonic-gate fi 5450Sstevel@tonic-gate 5466656Ssemery ping_check $fullhost $(gettext "System") 5476656Ssemery if [[ $fullhost == $client_machine ]]; then 5480Sstevel@tonic-gate : 5490Sstevel@tonic-gate else 5500Sstevel@tonic-gate fqdnlist="$fqdnlist $fullhost" 5510Sstevel@tonic-gate fi 5520Sstevel@tonic-gate 5536656Ssemery if [[ $list == *,* ]]; then 5540Sstevel@tonic-gate ((count = count + 1)) 5550Sstevel@tonic-gate eachfqdn=$(echo "$list" | cut -d"," -f$count) 5560Sstevel@tonic-gate else 5570Sstevel@tonic-gate break 5580Sstevel@tonic-gate fi 5590Sstevel@tonic-gate done 5600Sstevel@tonic-gate fi 5610Sstevel@tonic-gate} 5620Sstevel@tonic-gate 5636656Ssemeryfunction setup_keytab { 5646656Ssemery typeset cname ask_fqdns current_release 5656656Ssemery 5666656Ssemery # 5676656Ssemery # 1. kinit with ADMIN_PRINC 5686656Ssemery # 5696656Ssemery 5706656Ssemery if [[ -z $ADMIN_PRINC ]]; then 5716656Ssemery printf "\n$(gettext "Enter the krb5 administrative principal to be used"): " 5726656Ssemery read ADMIN_PRINC 5736656Ssemery checkval="ADMIN_PRINC"; check_value $ADMIN_PRINC 5746656Ssemery fi 5756656Ssemery 5766656Ssemery echo "$ADMIN_PRINC">$TMP_FILE 5776656Ssemery 5786656Ssemery [[ -n $msad ]] && return 5796656Ssemery if egrep -s '\/admin' $TMP_FILE; then 5806656Ssemery # Already in "/admin" format, do nothing 5816656Ssemery : 5826656Ssemery else 5836656Ssemery if egrep -s '\/' $TMP_FILE; then 5846656Ssemery printf "\n$(gettext "Improper entry for krb5 admin principal, exiting").\n" >&2 5856656Ssemery error_message 5866656Ssemery else 5876656Ssemery ADMIN_PRINC=$(echo "$ADMIN_PRINC/admin") 5886656Ssemery fi 5896656Ssemery fi 5906656Ssemery 5916656Ssemery printf "$(gettext "Obtaining TGT for %s") ...\n" $ADMIN_PRINC 5926656Ssemery 5936656Ssemery cname=$(canon_resolve $KDC) 5946656Ssemery if [[ -n $cname ]]; then 5956656Ssemery kinit -S kadmin/$cname $ADMIN_PRINC 5966656Ssemery else 5976656Ssemery kinit -S kadmin/$FKDC $ADMIN_PRINC 5986656Ssemery fi 5996656Ssemery klist 1>$TMP_FILE 2>&1 6006815Ssemery if egrep -s "$(gettext "Valid starting")" $TMP_FILE && egrep -s "kadmin/$FKDC@$realm" $TMP_FILE; then 6016656Ssemery : 6026656Ssemery else 6036656Ssemery printf "\n$(gettext "kinit of %s failed, exiting").\n" $ADMIN_PRINC >&2 6046656Ssemery error_message 6056656Ssemery fi 6066656Ssemery 6076656Ssemery # 6086656Ssemery # 2. Do we want to create and/or add service principal(s) for fqdn's 6096656Ssemery # other than the one listed in resolv.conf(4) ? 6106656Ssemery # 6116656Ssemery if [[ -z $options ]]; then 6126656Ssemery query "$(gettext "Do you have multiple DNS domains spanning the Kerberos realm") $realm ?" 6136656Ssemery ask_fqdns=$answer 6146656Ssemery if [[ $ask_fqdns == yes ]]; then 6156815Ssemery printf "$(gettext "Enter a comma-separated list of DNS domain names"): " 6166656Ssemery read fqdnlist 6176656Ssemery verify_fqdnlist "$fqdnlist" 6186656Ssemery else 6196656Ssemery fqdnlist=$client_machine 6206656Ssemery fi 6216656Ssemery else 6226656Ssemery if [[ -z $fqdnlist ]]; then 6236656Ssemery fqdnlist=$client_machine 6246656Ssemery fi 6256656Ssemery fi 6266656Ssemery 6276656Ssemery if [[ $add_nfs == yes ]]; then 6286656Ssemery echo; call_kadmin nfs 6296656Ssemery fi 6306656Ssemery 6316656Ssemery # Add the host entry to the keytab 6326656Ssemery echo; call_kadmin host 6336656Ssemery 6346656Ssemery} 6356656Ssemery 6366656Ssemeryfunction setup_lhn { 6376656Ssemery typeset -l logical_hn 6386656Ssemery 6396656Ssemery echo "$logical_hn" > $TMP_FILE 6406656Ssemery if egrep -s '[^.]\.[^.]+$' $TMP_FILE; then 6416656Ssemery # do nothing, logical_hn is in fqdn format 6426656Ssemery : 6436656Ssemery else 6446656Ssemery if egrep -s '\.+' $TMP_FILE; then 6456656Ssemery printf "\n$(gettext "Improper format of logical hostname, exiting").\n" >&2 6466656Ssemery error_message 6476656Ssemery else 6486656Ssemery # Attach fqdn to logical_hn, to get the Fully Qualified 6496656Ssemery # Host Name of the client requested 6506656Ssemery logical_hn=$(echo "$logical_hn.$fqdn") 6516656Ssemery fi 6526656Ssemery fi 6536656Ssemery 6546656Ssemery client_machine=$logical_hn 6556656Ssemery 6566656Ssemery ping_check $client_machine $(gettext "System") 6576656Ssemery} 6586656Ssemery 6596656Ssemeryfunction usage { 6606656Ssemery printf "\n$(gettext "Usage: kclient [ options ]")\n" >&2 6616656Ssemery printf "\t$(gettext "where options are any of the following")\n\n" >&2 6626656Ssemery printf "\t$(gettext "[ -D domain_list ] configure a client that has mul 6636656Ssemerytiple mappings of doamin and/or hosts to the default realm")\n" >&2 6646656Ssemery printf "\t$(gettext "[ -K ] configure a client that does not have host/service keys")\n" >&2 6656656Ssemery printf "\t$(gettext "[ -R realm ] specifies the realm to use")\n" >&2 6666656Ssemery printf "\t$(gettext "[ -T kdc_vendor ] specifies which KDC vendor is the server")\n" >&2 6676656Ssemery printf "\t$(gettext "[ -a adminuser ] specifies the Kerberos administrator")\n" >&2 6686656Ssemery printf "\t$(gettext "[ -c filepath ] specifies the krb5.conf path used to configure this client")\n" >&2 6696656Ssemery 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 6706656Ssemery printf "\t$(gettext "[ -f fqdn_list ] specifies which domains to configure host keys for this client")\n" >&2 6716656Ssemery printf "\t$(gettext "[ -h logicalhostname ] configure the logical host name for a client that is in a cluster")\n" >&2 6726656Ssemery 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 6736656Ssemery printf "\t$(gettext "[ -m master ] master KDC server host name")\n" >&2 6746656Ssemery printf "\t$(gettext "[ -n ] configure client to be an NFS client")\n" >&2 6756656Ssemery printf "\t$(gettext "[ -p profile ] specifies which profile file to use to configure this client")\n" >&2 6766656Ssemery printf "\t$(gettext "[ -s pam_list ] update the service for Kerberos authentication")\n" >&2 6770Sstevel@tonic-gate error_message 6780Sstevel@tonic-gate} 6790Sstevel@tonic-gate 6806656Ssemeryfunction discover_domain { 6816656Ssemery typeset dom DOMs 6826656Ssemery 6836656Ssemery if [[ -z $realm ]]; then 6846656Ssemery set -A DOMs -- `$KLOOKUP _ldap._tcp.dc._msdcs S` 6856656Ssemery else 6866656Ssemery set -A DOMs -- `$KLOOKUP _ldap._tcp.dc._msdcs.$realm S` 6876656Ssemery fi 6886656Ssemery 6896656Ssemery [[ -z ${DOMs[0]} ]] && return 1 6906656Ssemery 6916656Ssemery dom=${DOMs[0]} 6926656Ssemery 6936656Ssemery dom=${dom#*.} 6946656Ssemery dom=${dom% *} 6956656Ssemery 6966656Ssemery domain=$dom 6976656Ssemery 6986656Ssemery return 0 6996656Ssemery} 7006656Ssemery 7016656Ssemeryfunction check_nss_hosts_or_ipnodes_config { 7026656Ssemery typeset backend 7036656Ssemery 7046656Ssemery for backend in $1 7056656Ssemery do 7066656Ssemery [[ $backend == dns ]] && return 0 7076656Ssemery done 7086656Ssemery return 1 7096656Ssemery} 7106656Ssemery 7116656Ssemeryfunction check_nss_conf { 7126656Ssemery typeset i j hosts_config 7136656Ssemery 7146656Ssemery for i in hosts ipnodes 7156656Ssemery do 7166656Ssemery grep "^${i}:" /etc/nsswitch.conf|read j hosts_config 7176656Ssemery check_nss_hosts_or_ipnodes_config "$hosts_config" || return 1 7186656Ssemery done 7196656Ssemery 7206656Ssemery return 0 7216656Ssemery} 7226656Ssemery 7236656Ssemeryfunction canon_resolve { 7246656Ssemery typeset name ip 7256656Ssemery 7266656Ssemery name=`$KLOOKUP $1 C` 7276656Ssemery [[ -z $name ]] && name=`$KLOOKUP $1 A` 7286656Ssemery [[ -z $name ]] && return 7296656Ssemery 7306656Ssemery ip=`$KLOOKUP $name I` 7316656Ssemery [[ -z $ip ]] && return 7326815Ssemery for i in $ip 7336815Ssemery do 7346815Ssemery if ping $i 2 > /dev/null 2>&1; then 7356815Ssemery break 7366815Ssemery else 7376815Ssemery i= 7386815Ssemery fi 7396815Ssemery done 7406656Ssemery 7416656Ssemery cname=`$KLOOKUP $ip P` 7426656Ssemery [[ -z $cname ]] && return 7436656Ssemery 7446656Ssemery print -- "$cname" 7456656Ssemery} 7466656Ssemery 7476656Ssemeryfunction rev_resolve { 7486656Ssemery typeset name ip 7496656Ssemery 7506656Ssemery ip=`$KLOOKUP $1 I` 7516656Ssemery 7526656Ssemery [[ -z $ip ]] && return 7536656Ssemery name=`$KLOOKUP $ip P` 7546656Ssemery [[ -z $name ]] && return 7556656Ssemery 7566656Ssemery print -- $name 7576656Ssemery} 7586656Ssemery 7596656Ssemery# Convert an AD-style domain DN to a DNS domainname 7606656Ssemeryfunction dn2dns { 7616656Ssemery typeset OIFS dname dn comp components 7626656Ssemery 7636656Ssemery dn=$1 7646656Ssemery dname= 7656656Ssemery 7666656Ssemery OIFS="$IFS" 7676656Ssemery IFS=, 7686656Ssemery set -A components -- $1 7696656Ssemery IFS="$OIFS" 7706656Ssemery 7716656Ssemery for comp in "${components[@]}" 7726656Ssemery do 7736656Ssemery [[ "$comp" == [dD][cC]=* ]] || continue 7746656Ssemery dname="$dname.${comp#??=}" 7756656Ssemery done 7766656Ssemery 7776656Ssemery print ${dname#.} 7786656Ssemery} 7796656Ssemery 7806656Ssemery# Form a base DN from a DNS domainname and container 7816656Ssemeryfunction getBaseDN { 7826656Ssemery if [[ -n "$2" ]] 7836656Ssemery then 7846656Ssemery baseDN="CN=$1,$(dns2dn $2)" 7856656Ssemery else 7866656Ssemery baseDN="$(dns2dn $2)" 7876656Ssemery fi 7886656Ssemery} 7896656Ssemery 7906656Ssemery# Convert a DNS domainname to an AD-style DN for that domain 7916656Ssemeryfunction dns2dn { 7926656Ssemery typeset OIFS dn labels 7936656Ssemery 7946656Ssemery OIFS="$IFS" 7956656Ssemery IFS=. 7966656Ssemery set -A labels -- $1 7976656Ssemery IFS="$OIFS" 7986656Ssemery 7996656Ssemery dn= 8006656Ssemery for label in "${labels[@]}" 8016656Ssemery do 8026656Ssemery dn="${dn},DC=$label" 8036656Ssemery done 8046656Ssemery 8056656Ssemery print -- "${dn#,}" 8066656Ssemery} 8076656Ssemery 8086656Ssemeryfunction getSRVs { 8096656Ssemery typeset srv port 8106656Ssemery 8116656Ssemery $KLOOKUP $1 S | while read srv port 8126656Ssemery do 8136815Ssemery if ping $srv 2 > /dev/null 2>&1; then 8146815Ssemery print -- $srv $port 8156815Ssemery fi 8166656Ssemery done 8176656Ssemery} 8186656Ssemery 8196656Ssemeryfunction getKDC { 8206656Ssemery typeset j 8216656Ssemery 8226656Ssemery set -A KPWs -- $(getSRVs _kpasswd._tcp.$dom.) 8236656Ssemery kpasswd=${KPWs[0]} 8246656Ssemery 8256656Ssemery if [[ -n $siteName ]] 8266656Ssemery then 8276656Ssemery set -A KDCs -- $(getSRVs _kerberos._tcp.$siteName._sites.$dom.) 8286656Ssemery kdc=${KDCs[0]} 8296656Ssemery [[ -n $kdc ]] && return 8306656Ssemery fi 8316656Ssemery 8326656Ssemery # No site name 8336656Ssemery set -A KDCs -- $(getSRVs _kerberos._tcp.$dom.) 8346656Ssemery kdc=${KDCs[0]} 8356656Ssemery [[ -n $kdc ]] && return 8366656Ssemery 8376656Ssemery # Default 8386656Ssemery set -A KDCs -- $DomainDnsZones 88 8396656Ssemery kdc=$ForestDnsZones 8406656Ssemery} 8416656Ssemery 8426656Ssemeryfunction getDC { 8436656Ssemery typeset j 8446656Ssemery 8456656Ssemery if [[ -n $siteName ]] 8466656Ssemery then 8476656Ssemery set -A DCs -- $(getSRVs _ldap._tcp.$siteName._sites.dc._msdcs.$dom.) 8486656Ssemery dc=${DCs[0]} 8496656Ssemery [[ -n $dc ]] && return 8506656Ssemery fi 8516656Ssemery 8526656Ssemery # No site name 8536656Ssemery set -A DCs -- $(getSRVs _ldap._tcp.dc._msdcs.$dom.) 8546656Ssemery dc=${DCs[0]} 8556656Ssemery [[ -n $dc ]] && return 8566656Ssemery 8576656Ssemery # Default 8586656Ssemery set -A DCs -- $DomainDnsZones 389 8596656Ssemery dc=$DomainDnsZones 8606656Ssemery} 8616656Ssemery 8626656Ssemeryfunction write_ads_krb5conf { 863*12567SShawn.Emery@Sun.COM typeset kdcs 864*12567SShawn.Emery@Sun.COM 8656656Ssemery printf "\n$(gettext "Setting up %s").\n\n" $KRB5_CONFIG_FILE 8666656Ssemery 8676656Ssemery for i in ${KDCs[@]} 8686656Ssemery do 8696656Ssemery [[ $i == +([0-9]) ]] && continue 870*12567SShawn.Emery@Sun.COM if [[ -n $kdcs ]] 871*12567SShawn.Emery@Sun.COM then 872*12567SShawn.Emery@Sun.COM kdcs="$kdcs,$i" 873*12567SShawn.Emery@Sun.COM else 874*12567SShawn.Emery@Sun.COM kdcs=$i 875*12567SShawn.Emery@Sun.COM fi 8766656Ssemery done 877*12567SShawn.Emery@Sun.COM 878*12567SShawn.Emery@Sun.COM $KCONF -f $KRB5_CONFIG -r $realm -k $kdcs -m $KDC -p SET_CHANGE -d .$dom 879*12567SShawn.Emery@Sun.COM 880*12567SShawn.Emery@Sun.COM if [[ $? -ne 0 ]]; then 881*12567SShawn.Emery@Sun.COM printf "\n$(gettext "Can not update %s, exiting").\n" $KRB5_CONFIG >&2 882*12567SShawn.Emery@Sun.COM error_message 883*12567SShawn.Emery@Sun.COM fi 8846656Ssemery} 8856656Ssemery 8866656Ssemeryfunction getForestName { 8876656Ssemery ldapsearch -R -T -h $dc $ldap_args \ 8886656Ssemery -b "" -s base "" schemaNamingContext| \ 8896656Ssemery grep ^schemaNamingContext|read j schemaNamingContext 8906656Ssemery 8916656Ssemery if [[ $? -ne 0 ]]; then 8929833SShawn.Emery@Sun.COM printf "$(gettext "Can't find forest").\n" >&2 8936656Ssemery error_message 8946656Ssemery fi 8956656Ssemery schemaNamingContext=${schemaNamingContext#CN=Schema,CN=Configuration,} 8966656Ssemery 8976656Ssemery [[ -z $schemaNamingContext ]] && return 1 8986656Ssemery 8996656Ssemery forest= 9006656Ssemery while [[ -n $schemaNamingContext ]] 9016656Ssemery do 9026656Ssemery schemaNamingContext=${schemaNamingContext#DC=} 9036656Ssemery forest=${forest}.${schemaNamingContext%%,*} 9046656Ssemery [[ "$schemaNamingContext" = *,* ]] || break 9056656Ssemery schemaNamingContext=${schemaNamingContext#*,} 9066656Ssemery done 9076656Ssemery forest=${forest#.} 9086656Ssemery} 9096656Ssemery 9106656Ssemeryfunction getGC { 9116656Ssemery typeset j 9126656Ssemery 9136656Ssemery [[ -n $gc ]] && return 0 9146656Ssemery 9156656Ssemery if [[ -n $siteName ]] 9166656Ssemery then 9176656Ssemery set -A GCs -- $(getSRVs _ldap._tcp.$siteName._sites.gc._msdcs.$forest.) 9186656Ssemery gc=${GCs[0]} 9196656Ssemery [[ -n $gc ]] && return 9206656Ssemery fi 9216656Ssemery 9226656Ssemery # No site name 9236656Ssemery set -A GCs -- $(getSRVs _ldap._tcp.gc._msdcs.$forest.) 9246656Ssemery gc=${GCs[0]} 9256656Ssemery [[ -n $gc ]] && return 9266656Ssemery 9276656Ssemery # Default 9286656Ssemery set -A GCs -- $ForestDnsZones 3268 9296656Ssemery gc=$ForestDnsZones 9306656Ssemery} 9316656Ssemery 9329833SShawn.Emery@Sun.COM# 9339833SShawn.Emery@Sun.COM# The local variables used to calculate the IP address are of type unsigned 9349833SShawn.Emery@Sun.COM# integer (-ui), as this is required to restrict the integer to 32b. 9359833SShawn.Emery@Sun.COM# Starting in ksh88, Solaris has incorrectly assummed that -i represents 64b. 9369833SShawn.Emery@Sun.COM# 9376656Ssemeryfunction ipAddr2num { 9386656Ssemery typeset OIFS 9399833SShawn.Emery@Sun.COM typeset -ui16 num 9406656Ssemery 9416656Ssemery if [[ "$1" != +([0-9]).+([0-9]).+([0-9]).+([0-9]) ]] 9426656Ssemery then 9436656Ssemery print 0 9446656Ssemery return 0 9456656Ssemery fi 9466656Ssemery 9476656Ssemery OIFS="$IFS" 9486656Ssemery IFS=. 9496656Ssemery set -- $1 9506656Ssemery IFS="$OIFS" 9516656Ssemery 9526656Ssemery num=$((${1}<<24 | ${2}<<16 | ${3}<<8 | ${4})) 9536656Ssemery 9546656Ssemery print -- $num 9556656Ssemery} 9566656Ssemery 9579833SShawn.Emery@Sun.COM# 9589833SShawn.Emery@Sun.COM# The local variables used to calculate the IP address are of type unsigned 9599833SShawn.Emery@Sun.COM# integer (-ui), as this is required to restrict the integer to 32b. 9609833SShawn.Emery@Sun.COM# Starting in ksh88, Solaris has incorrectly assummed that -i represents 64b. 9619833SShawn.Emery@Sun.COM# 9626656Ssemeryfunction num2ipAddr { 9639833SShawn.Emery@Sun.COM typeset -ui16 num 9649833SShawn.Emery@Sun.COM typeset -ui10 a b c d 9656656Ssemery 9666656Ssemery num=$1 9676656Ssemery a=$((num>>24 )) 9686656Ssemery b=$((num>>16 & 16#ff)) 9696656Ssemery c=$((num>>8 & 16#ff)) 9706656Ssemery d=$((num & 16#ff)) 9716656Ssemery print -- $a.$b.$c.$d 9726656Ssemery} 9736656Ssemery 9749833SShawn.Emery@Sun.COM# 9759833SShawn.Emery@Sun.COM# The local variables used to calculate the IP address are of type unsigned 9769833SShawn.Emery@Sun.COM# integer (-ui), as this is required to restrict the integer to 32b. 9779833SShawn.Emery@Sun.COM# Starting in ksh88, Solaris has incorrectly assummed that -i represents 64b. 9789833SShawn.Emery@Sun.COM# 9796656Ssemeryfunction netmask2length { 9809833SShawn.Emery@Sun.COM typeset -ui16 netmask 9816656Ssemery typeset -i len 9826656Ssemery 9836656Ssemery netmask=$1 9846656Ssemery len=32 9856656Ssemery while [[ $((netmask % 2)) -eq 0 ]] 9866656Ssemery do 9876656Ssemery netmask=$((netmask>>1)) 9886656Ssemery len=$((len - 1)) 9896656Ssemery done 9906656Ssemery print $len 9916656Ssemery} 9926656Ssemery 9939833SShawn.Emery@Sun.COM# 9949833SShawn.Emery@Sun.COM# The local variables used to calculate the IP address are of type unsigned 9959833SShawn.Emery@Sun.COM# integer (-ui), as this is required to restrict the integer to 32b. 9969833SShawn.Emery@Sun.COM# Starting in ksh88, Solaris has incorrectly assummed that -i represents 64b. 9979833SShawn.Emery@Sun.COM# 9986656Ssemeryfunction getSubnets { 9999833SShawn.Emery@Sun.COM typeset -ui16 addr netmask 10009833SShawn.Emery@Sun.COM typeset -ui16 classa=16\#ff000000 10016656Ssemery 10026656Ssemery ifconfig -a|while read line 10036656Ssemery do 10046656Ssemery addr=0 10056656Ssemery netmask=0 10066656Ssemery set -- $line 10076656Ssemery [[ $1 == inet ]] || continue 10086656Ssemery while [[ $# -gt 0 ]] 10096656Ssemery do 10106656Ssemery case "$1" in 10116656Ssemery inet) addr=$(ipAddr2num $2); shift;; 10126656Ssemery netmask) eval netmask=16\#$2; shift;; 10136656Ssemery *) :; 10146656Ssemery esac 10156656Ssemery shift 10166656Ssemery done 10176656Ssemery 10186656Ssemery [[ $addr -eq 0 || $netmask -eq 0 ]] && continue 10196656Ssemery [[ $((addr & classa)) -eq 16\#7f000000 ]] && continue 10206656Ssemery 10216656Ssemery print $(num2ipAddr $((addr & netmask)))/$(netmask2length $netmask) 10226656Ssemery done 10236656Ssemery} 10246656Ssemery 10256656Ssemeryfunction getSite { 10266656Ssemery typeset subnet siteDN j ldapsrv subnet_dom 10276656Ssemery 10286656Ssemery eval "[[ -n \"\$siteName\" ]]" && return 10296656Ssemery for subnet in $(getSubnets) 10306656Ssemery do 10316656Ssemery ldapsearch -R -T -h $dc $ldap_args \ 10326656Ssemery -p 3268 -b "" -s sub cn=$subnet dn |grep ^dn|read j subnetDN 10336656Ssemery 10346656Ssemery [[ -z $subnetDN ]] && continue 10356656Ssemery subnet_dom=$(dn2dns $subnetDN) 10366656Ssemery ldapsrv=$(canon_resolve DomainDnsZones.$subnet_dom) 10376815Ssemery [[ -z $ldapsrv ]] && continue 10386656Ssemery ldapsearch -R -T -h $ldapsrv $ldap_args \ 10396656Ssemery -b "$subnetDN" -s base "" siteObject \ 10406656Ssemery |grep ^siteObject|read j siteDN 10416656Ssemery 10426656Ssemery [[ -z $siteDN ]] && continue 10436656Ssemery 10446656Ssemery eval siteName=${siteDN%%,*} 10456656Ssemery eval siteName=\${siteName#CN=} 10466656Ssemery return 10476656Ssemery done 10486656Ssemery} 10496656Ssemery 10506656Ssemeryfunction doKRB5config { 10516656Ssemery [[ -f $KRB5_CONFIG_FILE ]] && \ 10526656Ssemery cp $KRB5_CONFIG_FILE ${KRB5_CONFIG_FILE}-pre-kclient 10536656Ssemery 10546656Ssemery [[ -f $KRB5_KEYTAB_FILE ]] && \ 10556656Ssemery cp $KRB5_KEYTAB_FILE ${KRB5_KEYTAB_FILE}-pre-kclient 10566656Ssemery 10576815Ssemery [[ -s $KRB5_CONFIG ]] && cp $KRB5_CONFIG $KRB5_CONFIG_FILE 10586815Ssemery [[ -s $KRB5_CONFIG_FILE ]] && chmod 0644 $KRB5_CONFIG_FILE 10596815Ssemery [[ -s $new_keytab ]] && cp $new_keytab $KRB5_KEYTAB_FILE 10606815Ssemery [[ -s $KRB5_KEYTAB_FILE ]] && chmod 0600 $KRB5_KEYTAB_FILE 10616656Ssemery} 10626656Ssemery 10636656Ssemeryfunction addDNSRR { 10646656Ssemery smbFMRI=svc:/network/smb/server:default 10656656Ssemery ddnsProp=smbd/ddns_enable 10666656Ssemery enProp=general/enabled 10676656Ssemery 10686656Ssemery enabled=`svcprop -p $enProp $smbFMRI` 10696656Ssemery ddns_enable=`svcprop -p $ddnsProp $smbFMRI` 10706656Ssemery 10716656Ssemery if [[ $enabled == true && $ddns_enable != true ]]; then 10726656Ssemery printf "$(gettext "Warning: won't create DNS records for client").\n" 10736656Ssemery printf "$(gettext "%s property not set to 'true' for the %s FMRI").\n" $ddnsProp $smbFMRI 10746656Ssemery return 10756656Ssemery fi 10766656Ssemery 10776656Ssemery # Destroy any existing ccache as GSS_C_NO_CREDENTIAL will pick up any 10786656Ssemery # residual default credential in the cache. 10796656Ssemery kdestroy > /dev/null 2>&1 10806656Ssemery 10816656Ssemery $KDYNDNS -d $1 > /dev/null 2>&1 10826656Ssemery if [[ $? -ne 0 ]]; then 10836656Ssemery # 10846656Ssemery # Non-fatal, we should carry-on as clients may resolve to 10856656Ssemery # different servers and the client could already exist there. 10866656Ssemery # 10878334SJose.Borrego@Sun.COM printf "$(gettext "Warning: unable to create DNS records for client").\n" 10886656Ssemery printf "$(gettext "This could mean that '%s' is not included as a 'nameserver' in the /etc/resolv.conf file or some other type of error").\n" $dc 10896656Ssemery fi 10906656Ssemery} 10916656Ssemery 10926656Ssemeryfunction setSMB { 10936656Ssemery typeset domain=$1 10946656Ssemery typeset server=$2 10956656Ssemery smbFMRI=svc:/network/smb/server 10966656Ssemery 109711570SShawn.Emery@Sun.COM printf "%s" "$newpw" | $KSMB -d $domain -s $server 10986656Ssemery if [[ $? -ne 0 ]]; then 10998334SJose.Borrego@Sun.COM printf "$(gettext "Warning: unable to set %s domain, server and password information").\n" $smbFMRI 11006656Ssemery return 11016656Ssemery fi 11026656Ssemery 11038334SJose.Borrego@Sun.COM svcadm restart $smbFMRI > /dev/null 2>&1 11046656Ssemery if [[ $? -ne 0 ]]; then 11058334SJose.Borrego@Sun.COM printf "$(gettext "Warning: unable to restart %s").\n" $smbFMRI 11066656Ssemery fi 11076656Ssemery} 11086656Ssemery 11096656Ssemeryfunction compareDomains { 11106656Ssemery typeset oldDom hspn newDom=$1 11116656Ssemery 11126656Ssemery # If the client has been previously configured in a different 11136656Ssemery # realm/domain then we need to prompt the user to see if they wish to 11146656Ssemery # switch domains. 11156815Ssemery klist -k 2>&1 | grep @ | read j hspn 11166656Ssemery [[ -z $hspn ]] && return 11176656Ssemery 11186656Ssemery oldDom=${hspn#*@} 11196656Ssemery if [[ $oldDom != $newDom ]]; then 11206656Ssemery printf "$(gettext "The client is currently configured in a different domain").\n" 11216656Ssemery printf "$(gettext "Currently in the '%s' domain, trying to join the '%s' domain").\n" $oldDom $newDom 11226656Ssemery query "$(gettext "Do you want the client to join a new domain") ?" 11236656Ssemery printf "\n" 11246656Ssemery if [[ $answer != yes ]]; then 11259833SShawn.Emery@Sun.COM printf "$(gettext "Client will not be joined to the new domain").\n" >&2 11266656Ssemery error_message 11276656Ssemery fi 11286656Ssemery fi 11296656Ssemery} 11306656Ssemery 11316656Ssemeryfunction getKDCDC { 11326656Ssemery 11336656Ssemery getKDC 11346656Ssemery if [[ -n $kdc ]]; then 11356656Ssemery KDC=$kdc 11366656Ssemery dc=$kdc 11376656Ssemery else 11386656Ssemery getDC 11396656Ssemery if [[ -n $dc ]]; then 11406656Ssemery KDC=$dc 11416656Ssemery else 11429833SShawn.Emery@Sun.COM printf "$(gettext "Could not find domain controller server for '%s'. Exiting").\n" $realm >&2 11436656Ssemery error_message 11446656Ssemery fi 11456656Ssemery fi 11466656Ssemery} 11476656Ssemery 114811570SShawn.Emery@Sun.COMfunction gen_rand { 114911570SShawn.Emery@Sun.COM typeset -u hex 115011570SShawn.Emery@Sun.COM 115111570SShawn.Emery@Sun.COM dd if=/dev/random bs=1 count=1 2>/dev/null | od -A n -tx1 | read hex 115211570SShawn.Emery@Sun.COM 115311570SShawn.Emery@Sun.COM printf %s $((16#$hex)) 115411570SShawn.Emery@Sun.COM} 115511570SShawn.Emery@Sun.COM 11566656Ssemeryfunction join_domain { 11576656Ssemery typeset -u upcase_nodename 115811061SShawn.Emery@Sun.COM typeset -l locase_nodename 115911061SShawn.Emery@Sun.COM typeset -L15 string15 11606656Ssemery typeset netbios_nodename fqdn 11616656Ssemery 11626656Ssemery container=Computers 11636656Ssemery ldap_args="-o authzid= -o mech=gssapi" 11646656Ssemery userAccountControlBASE=4096 11656656Ssemery 11666656Ssemery if [[ -z $ADMIN_PRINC ]]; then 11676656Ssemery cprinc=Administrator 11686656Ssemery else 11696656Ssemery cprinc=$ADMIN_PRINC 11706656Ssemery fi 11716656Ssemery 11726656Ssemery if ! discover_domain; then 11739833SShawn.Emery@Sun.COM printf "$(gettext "Can not find realm") '%s'.\n" $realm >&2 11746656Ssemery error_message 11756656Ssemery fi 11766656Ssemery 11776656Ssemery dom=$domain 11786656Ssemery realm=$domain 117911061SShawn.Emery@Sun.COM 118011061SShawn.Emery@Sun.COM if [[ ${#hostname} -gt 15 ]]; then 118111061SShawn.Emery@Sun.COM string15=$hostname 118211061SShawn.Emery@Sun.COM upcase_nodename=$string15 118311061SShawn.Emery@Sun.COM locase_nodename=$string15 118411061SShawn.Emery@Sun.COM else 118511061SShawn.Emery@Sun.COM upcase_nodename=$hostname 118611061SShawn.Emery@Sun.COM locase_nodename=$hostname 118711061SShawn.Emery@Sun.COM fi 118811061SShawn.Emery@Sun.COM 11896656Ssemery netbios_nodename="${upcase_nodename}\$" 11906656Ssemery fqdn=$hostname.$domain 119110001SJoyce.McIntosh@Sun.COM upn=host/${fqdn}@${realm} 11926656Ssemery 11936656Ssemery grep=/usr/xpg4/bin/grep 11946656Ssemery 11956656Ssemery object=$(mktemp -q -t kclient-computer-object.XXXXXX) 11966656Ssemery if [[ -z $object ]]; then 11976656Ssemery printf "\n$(gettext "Can not create temporary file, exiting").\n 11986656Ssemery" >&2 11996656Ssemery error_message 12006656Ssemery fi 12016656Ssemery 12026656Ssemery grep=/usr/xpg4/bin/grep 12036656Ssemery 12046656Ssemery modify_existing=false 12056656Ssemery recreate=false 12066656Ssemery 12076656Ssemery DomainDnsZones=$(rev_resolve DomainDnsZones.$dom.) 12086656Ssemery ForestDnsZones=$(rev_resolve ForestDnsZones.$dom.) 12096656Ssemery 12106656Ssemery getBaseDN "$container" "$dom" 12116656Ssemery 12126656Ssemery if [[ -n $KDC ]]; then 12136656Ssemery dc=$KDC 12146656Ssemery else 12156656Ssemery getKDCDC 12166656Ssemery fi 12176656Ssemery 12186656Ssemery write_ads_krb5conf 12196656Ssemery 12206815Ssemery printf "$(gettext "Attempting to join '%s' to the '%s' domain").\n\n" $upcase_nodename $realm 12216656Ssemery 12226656Ssemery kinit $cprinc@$realm 12236656Ssemery if [[ $? -ne 0 ]]; then 12249833SShawn.Emery@Sun.COM printf "$(gettext "Could not authenticate %s. Exiting").\n" $cprinc@$realm >&2 12256656Ssemery error_message 12266656Ssemery fi 12276656Ssemery 12286656Ssemery if getForestName 12296656Ssemery then 12306656Ssemery printf "\n$(gettext "Forest name found: %s")\n\n" $forest 12316656Ssemery else 12326656Ssemery printf "\n$(gettext "Forest name not found, assuming forest is the domain name").\n" 12336656Ssemery fi 12346656Ssemery 12356656Ssemery getGC 12366656Ssemery getSite 12376656Ssemery 12386656Ssemery if [[ -z $siteName ]] 12396656Ssemery then 12406656Ssemery printf "$(gettext "Site name not found. Local DCs/GCs will not be discovered").\n\n" 12416656Ssemery else 12426656Ssemery printf "$(gettext "Looking for _local_ KDCs, DCs and global catalog servers (SRV RRs)").\n" 12436656Ssemery getKDCDC 12446656Ssemery getGC 12456656Ssemery 12466656Ssemery write_ads_krb5conf 12476656Ssemery fi 12486656Ssemery 12496656Ssemery if [[ ${#GCs} -eq 0 ]]; then 12509833SShawn.Emery@Sun.COM printf "$(gettext "Could not find global catalogs. Exiting").\n" >&2 12516656Ssemery error_message 12526656Ssemery fi 12536656Ssemery 12546656Ssemery # Check to see if the client is transitioning between domains. 12556656Ssemery compareDomains $realm 12566656Ssemery 12576656Ssemery # Here we check domainFunctionality to see which release: 12586656Ssemery # 0, 1, 2: Windows 2000, 2003 Interim, 2003 respecitively 12596656Ssemery # 3: Windows 2008 12606656Ssemery level=0 12616656Ssemery ldapsearch -R -T -h "$dc" $ldap_args -b "" -s base "" \ 12626656Ssemery domainControllerFunctionality| grep ^domainControllerFunctionality| \ 12636656Ssemery read j level 12646656Ssemery if [[ $? -ne 0 ]]; then 12659833SShawn.Emery@Sun.COM printf "$(gettext "Search for domain functionality failed, exiting").\n" >&2 12666656Ssemery error_message 12676656Ssemery fi 12686656Ssemery 12696656Ssemery if ldapsearch -R -T -h "$dc" $ldap_args -b "$baseDN" \ 12706656Ssemery -s sub sAMAccountName="$netbios_nodename" dn > /dev/null 2>&1 12716656Ssemery then 12726656Ssemery : 12736656Ssemery else 12749833SShawn.Emery@Sun.COM printf "$(gettext "Search for node failed, exiting").\n" >&2 12756656Ssemery error_message 12766656Ssemery fi 12776656Ssemery ldapsearch -R -T -h "$dc" $ldap_args -b "$baseDN" -s sub \ 12786656Ssemery sAMAccountName="$netbios_nodename" dn|grep "^dn:"|read j dn 12796656Ssemery 12806656Ssemery if [[ -z $dn ]]; then 12816656Ssemery : # modify_existing is already false, which is what we want. 12826656Ssemery else 12836656Ssemery printf "$(gettext "Computer account '%s' already exists in the '%s' domain").\n" $upcase_nodename $realm 12846656Ssemery query "$(gettext "Do you wish to recreate this computer account") ?" 12856656Ssemery printf "\n" 12866656Ssemery if [[ $answer == yes ]]; then 12876656Ssemery recreate=true 12886656Ssemery else 12896656Ssemery modify_existing=true 12906656Ssemery fi 12916656Ssemery fi 12926656Ssemery 12936656Ssemery if [[ $modify_existing == false && -n $dn ]]; then 12946656Ssemery query "$(gettext "Would you like to delete any sub-object found for this computer account") ?" 12956656Ssemery if [[ $answer == yes ]]; then 12966656Ssemery printf "$(gettext "Looking to see if the machine account contains other objects")...\n" 12976656Ssemery ldapsearch -R -T -h "$dc" $ldap_args -b "$dn" -s sub "" dn | while read j sub_dn 12986656Ssemery do 12996656Ssemery [[ $j != dn: || -z $sub_dn || $dn == $sub_dn ]] && continue 13006656Ssemery if $recreate; then 13016656Ssemery printf "$(gettext "Deleting the following object: %s")\n" ${sub_dn#$dn} 13026656Ssemery ldapdelete -h "$dc" $ldap_args "$sub_dn" > /dev/null 2>&1 13036656Ssemery if [[ $? -ne 0 ]]; then 13046656Ssemery printf "$(gettext "Error in deleting object: %s").\n" ${sub_dn#$dn} 13056656Ssemery fi 13066656Ssemery else 13076656Ssemery printf "$(gettext "The following object will not be deleted"): %s\n" ${sub_dn#$dn} 13086656Ssemery fi 13096656Ssemery done 13106656Ssemery fi 13116656Ssemery 13126656Ssemery if $recreate; then 13136656Ssemery ldapdelete -h "$dc" $ldap_args "$dn" > /dev/null 2>&1 13146656Ssemery if [[ $? -ne 0 ]]; then 13159833SShawn.Emery@Sun.COM printf "$(gettext "Error in deleting object: %s").\n" ${sub_dn#$dn} >&2 13166656Ssemery error_message 13176656Ssemery fi 13186656Ssemery elif $modify_existing; then 13196656Ssemery : # Nothing to delete 13206656Ssemery else 13219833SShawn.Emery@Sun.COM printf "$(gettext "A machine account already exists").\n" >&2 13226656Ssemery error_message 13236656Ssemery fi 13246656Ssemery fi 13256656Ssemery 132611061SShawn.Emery@Sun.COM [[ -z $dn ]] && dn="CN=${upcase_nodename},${baseDN}" 13276656Ssemery if $modify_existing; then 13286656Ssemery cat > "$object" <<EOF 132911061SShawn.Emery@Sun.COMdn: $dn 13306656Ssemerychangetype: modify 13316656Ssemeryreplace: userPrincipalName 13326656SsemeryuserPrincipalName: $upn 13336656Ssemery- 13346656Ssemeryreplace: servicePrincipalName 13356656SsemeryservicePrincipalName: host/${fqdn} 13366656Ssemery- 13376656Ssemeryreplace: userAccountControl 13386656SsemeryuserAccountControl: $((userAccountControlBASE + 32 + 2)) 13396656Ssemery- 13406656Ssemeryreplace: dNSHostname 13416656SsemerydNSHostname: ${fqdn} 13426656SsemeryEOF 13436656Ssemery 13446656Ssemery printf "$(gettext "A machine account already exists; updating it").\n" 13456815Ssemery ldapadd -h "$dc" $ldap_args -f "$object" > /dev/null 2>&1 13466656Ssemery if [[ $? -ne 0 ]]; then 134711061SShawn.Emery@Sun.COM printf "$(gettext "Failed to modify the AD object via LDAP").\n" >&2 13486656Ssemery error_message 13496656Ssemery fi 13506656Ssemery else 135111061SShawn.Emery@Sun.COM dn="CN=${upcase_nodename},${baseDN}" 13526656Ssemery cat > "$object" <<EOF 135311061SShawn.Emery@Sun.COMdn: $dn 13546656SsemeryobjectClass: computer 13556656Ssemerycn: $upcase_nodename 13566656SsemerysAMAccountName: ${netbios_nodename} 13576656SsemeryuserPrincipalName: $upn 13586656SsemeryservicePrincipalName: host/${fqdn} 13596656SsemeryuserAccountControl: $((userAccountControlBASE + 32 + 2)) 13606656SsemerydNSHostname: ${fqdn} 13616656SsemeryEOF 13626656Ssemery 13636656Ssemery printf "$(gettext "Creating the machine account in AD via LDAP").\n\n" 13646656Ssemery 13656656Ssemery ldapadd -h "$dc" $ldap_args -f "$object" > /dev/null 2>&1 13666656Ssemery if [[ $? -ne 0 ]]; then 13679833SShawn.Emery@Sun.COM printf "$(gettext "Failed to create the AD object via LDAP").\n" >&2 13686656Ssemery error_message 13696656Ssemery fi 13706656Ssemery fi 13716656Ssemery 13726656Ssemery # Generate a new password for the new account 137311570SShawn.Emery@Sun.COM MAX_PASS=120 13746656Ssemery i=0 13756656Ssemery 137611570SShawn.Emery@Sun.COM # first check to see if /dev/random exists to generate a new password 137711570SShawn.Emery@Sun.COM if [[ ! -h /dev/random ]]; then 137811570SShawn.Emery@Sun.COM printf "$(gettext "/dev/random does not exist").\n" >&2 137911570SShawn.Emery@Sun.COM error_message 138011570SShawn.Emery@Sun.COM fi 13816656Ssemery 138211570SShawn.Emery@Sun.COM while ((MAX_PASS > i)) 138311570SShawn.Emery@Sun.COM do 138411570SShawn.Emery@Sun.COM # [MS-DISO] A machine password is an ASCII string of randomly 138511570SShawn.Emery@Sun.COM # chosen characters. Each character's ASCII code is between 32 138611570SShawn.Emery@Sun.COM # and 122 inclusive. 138711570SShawn.Emery@Sun.COM c=$(printf "\\$(printf %o $(($(gen_rand) % 91 + 32)))\n") 138811570SShawn.Emery@Sun.COM p="$p$c" 138911570SShawn.Emery@Sun.COM ((i+=1)) 139011570SShawn.Emery@Sun.COM done 13916656Ssemery 13926656Ssemery newpw=$p 139311570SShawn.Emery@Sun.COM if [[ ${#newpw} -ne MAX_PASS ]]; then 139411570SShawn.Emery@Sun.COM printf "$(gettext "Password created was of incorrect length").\n" >&2 139511570SShawn.Emery@Sun.COM error_message 139611570SShawn.Emery@Sun.COM fi 13976656Ssemery 13986656Ssemery # Set the new password 139911570SShawn.Emery@Sun.COM printf "%s" "$newpw" | $KSETPW ${netbios_nodename}@${realm} > /dev/null 2>&1 14006656Ssemery if [[ $? -ne 0 ]] 14016656Ssemery then 14029833SShawn.Emery@Sun.COM printf "$(gettext "Failed to set account password").\n" >&2 14036656Ssemery error_message 14046656Ssemery fi 14056656Ssemery 14066656Ssemery # Lookup the new principal's kvno: 14076656Ssemery ldapsearch -R -T -h "$dc" $ldap_args -b "$baseDN" \ 14086656Ssemery -s sub cn=$upcase_nodename msDS-KeyVersionNumber| \ 14096656Ssemery grep "^msDS-KeyVersionNumber"|read j kvno 14106656Ssemery [[ -z $kvno ]] && kvno=1 14116656Ssemery 14126656Ssemery # Set supported enctypes. This only works for Longhorn/Vista, so we 14136656Ssemery # ignore errors here. 14146656Ssemery userAccountControl=$((userAccountControlBASE + 524288 + 65536)) 14156656Ssemery set -A enctypes -- 14166656Ssemery 14176656Ssemery # Do we have local support for AES? 14186656Ssemery encrypt -l|grep ^aes|read j minkeysize maxkeysize 14196656Ssemery val= 14206656Ssemery if [[ $maxkeysize -eq 256 ]]; then 14216656Ssemery val=16 14226656Ssemery enctypes[${#enctypes[@]}]=aes256-cts-hmac-sha1-96 14236656Ssemery fi 14246656Ssemery if [[ $minkeysize -eq 128 ]]; then 14256656Ssemery ((val=val+8)) 14266656Ssemery enctypes[${#enctypes[@]}]=aes128-cts-hmac-sha1-96 14276656Ssemery fi 14286656Ssemery 14296656Ssemery # RC4 comes next (whether it's better than 1DES or not -- AD prefers it) 14306656Ssemery if encrypt -l|$grep -q ^arcfour 14316656Ssemery then 14326656Ssemery ((val=val+4)) 14336656Ssemery enctypes[${#enctypes[@]}]=arcfour-hmac-md5 14346656Ssemery else 14356656Ssemery # Use 1DES ONLY if we don't have arcfour 14366656Ssemery userAccountControl=$((userAccountControl + 2097152)) 14376656Ssemery fi 14386656Ssemery if encrypt -l | $grep -q ^des 14396656Ssemery then 14409833SShawn.Emery@Sun.COM ((val=val+2)) 14416656Ssemery enctypes[${#enctypes[@]}]=des-cbc-md5 14426656Ssemery fi 14436656Ssemery 14446656Ssemery if [[ ${#enctypes[@]} -eq 0 ]] 14456656Ssemery then 14466656Ssemery printf "$(gettext "No enctypes are supported").\n" 14479833SShawn.Emery@Sun.COM printf "$(gettext "Please enable arcfour or 1DES, then re-join; see cryptoadm(1M)").\n" >&2 14486656Ssemery error_message 14496656Ssemery fi 14506656Ssemery 14516656Ssemery # If domain crontroller is Longhorn or above then set new supported 14526656Ssemery # encryption type attributes. 14536656Ssemery if [[ $level -gt 2 ]]; then 14546656Ssemery cat > "$object" <<EOF 145511061SShawn.Emery@Sun.COMdn: $dn 14566656Ssemerychangetype: modify 14576656Ssemeryreplace: msDS-SupportedEncryptionTypes 14586656SsemerymsDS-SupportedEncryptionTypes: $val 14596656SsemeryEOF 14606656Ssemery ldapmodify -h "$dc" $ldap_args -f "$object" >/dev/null 2>&1 14616656Ssemery if [[ $? -ne 0 ]]; then 14626656Ssemery printf "$(gettext "Warning: Could not set the supported encryption type for computer account").\n" 14636656Ssemery fi 14646656Ssemery fi 14656656Ssemery 14666656Ssemery # We should probably check whether arcfour is available, and if not, 14676656Ssemery # then set the 1DES only flag, but whatever, it's not likely NOT to be 14686656Ssemery # available on S10/Nevada! 14696656Ssemery 14706656Ssemery # Reset userAccountControl 14716656Ssemery # 14726656Ssemery # NORMAL_ACCOUNT (512) | DONT_EXPIRE_PASSWORD (65536) | 14736656Ssemery # TRUSTED_FOR_DELEGATION (524288) 14746656Ssemery # 14756656Ssemery # and possibly UseDesOnly (2097152) (see above) 14766656Ssemery # 14776656Ssemery cat > "$object" <<EOF 147811061SShawn.Emery@Sun.COMdn: $dn 14796656Ssemerychangetype: modify 14806656Ssemeryreplace: userAccountControl 14816656SsemeryuserAccountControl: $userAccountControl 14826656SsemeryEOF 14836656Ssemery ldapmodify -h "$dc" $ldap_args -f "$object" >/dev/null 2>&1 14846656Ssemery if [[ $? -ne 0 ]]; then 14859833SShawn.Emery@Sun.COM printf "$(gettext "ldapmodify failed to modify account attribute").\n" >&2 14866656Ssemery error_message 14876656Ssemery fi 14886656Ssemery 14896656Ssemery # Setup a keytab file 14906656Ssemery set -A args -- 14916656Ssemery for enctype in "${enctypes[@]}" 14926656Ssemery do 14936656Ssemery args[${#args[@]}]=-e 14946656Ssemery args[${#args[@]}]=$enctype 14956656Ssemery done 14966656Ssemery 14976656Ssemery rm $new_keytab > /dev/null 2>&1 14986656Ssemery 14996656Ssemery cat > "$object" <<EOF 150011061SShawn.Emery@Sun.COMdn: $dn 15016656Ssemerychangetype: modify 15026656Ssemeryadd: servicePrincipalName 15036656SsemeryservicePrincipalName: nfs/${fqdn} 15046656SsemeryservicePrincipalName: HTTP/${fqdn} 15056656SsemeryservicePrincipalName: root/${fqdn} 15069833SShawn.Emery@Sun.COMservicePrincipalName: cifs/${fqdn} 150711061SShawn.Emery@Sun.COMservicePrincipalName: host/${upcase_nodename} 15086656SsemeryEOF 15096656Ssemery ldapmodify -h "$dc" $ldap_args -f "$object" >/dev/null 2>&1 15106656Ssemery if [[ $? -ne 0 ]]; then 15119833SShawn.Emery@Sun.COM printf "$(gettext "ldapmodify failed to modify account attribute").\n" >&2 15126656Ssemery error_message 15136656Ssemery fi 15146656Ssemery 15159833SShawn.Emery@Sun.COM # 15169833SShawn.Emery@Sun.COM # In Windows, unlike MIT based implementations we salt the keys with 151711061SShawn.Emery@Sun.COM # the UPN, which is based on the host/string15@realm elements, not 151811061SShawn.Emery@Sun.COM # with the individual SPN strings. 15199833SShawn.Emery@Sun.COM # 152011061SShawn.Emery@Sun.COM salt=host/${locase_nodename}.${domain}@${realm} 15219833SShawn.Emery@Sun.COM 152212566SShawn.Emery@Sun.COM skeys=(host/${fqdn}@${realm} nfs/${fqdn}@${realm} HTTP/${fqdn}@${realm}) 152312566SShawn.Emery@Sun.COM skeys+=(root/${fqdn}@${realm} cifs/${fqdn}@${realm}) 152412566SShawn.Emery@Sun.COM skeys+=(${netbios_nodename}@${realm} host/${upcase_nodename}@${realm}) 152512566SShawn.Emery@Sun.COM skeys+=(cifs/${upcase_nodename}@${realm}) 15269833SShawn.Emery@Sun.COM 152712566SShawn.Emery@Sun.COM ks_args="-n -s $salt -v $kvno -k $new_keytab ${args[@]}" 15286656Ssemery 152912566SShawn.Emery@Sun.COM for skey in ${skeys[@]} 153012566SShawn.Emery@Sun.COM do 153112566SShawn.Emery@Sun.COM printf "%s" "$newpw" | $KSETPW $ks_args $skey > /dev/null 2>&1 153212566SShawn.Emery@Sun.COM if [[ $? -ne 0 ]] 153312566SShawn.Emery@Sun.COM then 153412566SShawn.Emery@Sun.COM printf "$(gettext "Failed to set password").\n" >&2 153512566SShawn.Emery@Sun.COM error_message 153612566SShawn.Emery@Sun.COM fi 153712566SShawn.Emery@Sun.COM done 153811061SShawn.Emery@Sun.COM 15396656Ssemery doKRB5config 15406656Ssemery 15416656Ssemery addDNSRR $dom 15426656Ssemery 15436656Ssemery setSMB $dom $dc 15446656Ssemery 154511061SShawn.Emery@Sun.COM printf -- "---------------------------------------------------\n" 15466656Ssemery printf "$(gettext "Setup COMPLETE").\n\n" 15476656Ssemery 15486656Ssemery kdestroy -q 1>$TMP_FILE 2>&1 15496656Ssemery rm -f $TMP_FILE 15506656Ssemery rm -rf $TMPDIR > /dev/null 2>&1 15516656Ssemery 15526656Ssemery exit 0 15536656Ssemery} 15546656Ssemery 15550Sstevel@tonic-gate########################### 15560Sstevel@tonic-gate# Main section # 15570Sstevel@tonic-gate########################### 15580Sstevel@tonic-gate# 15590Sstevel@tonic-gate# Set the Kerberos config file and some default strings/files 15600Sstevel@tonic-gate# 15616656SsemeryKRB5_CONFIG_FILE=/etc/krb5/krb5.conf 15626656SsemeryKRB5_KEYTAB_FILE=/etc/krb5/krb5.keytab 15636656SsemeryRESOLV_CONF_FILE=/etc/resolv.conf 15646656Ssemery 15656656SsemeryKLOOKUP=/usr/lib/krb5/klookup; check_bin $KLOOKUP 15666656SsemeryKSETPW=/usr/lib/krb5/ksetpw; check_bin $KSETPW 15676656SsemeryKSMB=/usr/lib/krb5/ksmb; check_bin $KSMB 15686656SsemeryKDYNDNS=/usr/lib/krb5/kdyndns; check_bin $KDYNDNS 1569*12567SShawn.Emery@Sun.COMKCONF=/usr/lib/krb5/kconf; check_bin $KCONF 15706656Ssemery 15716656Ssemerydns_lookup=no 15726656Ssemeryask_fqdns=no 15736656Ssemeryadddns=no 15746815Ssemeryno_keytab=no 15750Sstevel@tonic-gatecheckval="" 15760Sstevel@tonic-gateprofile="" 15776656Ssemerytypeset -u realm 15786656Ssemerytypeset -l hostname KDC 15790Sstevel@tonic-gate 15806656Ssemeryexport TMPDIR="/var/run/kclient" 15816656Ssemery 15826656Ssemerymkdir $TMPDIR > /dev/null 2>&1 15839833SShawn.Emery@Sun.COMif [[ $? -ne 0 ]]; then 15849833SShawn.Emery@Sun.COM printf "\n$(gettext "Can not create directory: %s")\n\n" $TMPDIR >&2 15859833SShawn.Emery@Sun.COM exit 1 15869833SShawn.Emery@Sun.COMfi 15870Sstevel@tonic-gate 15886656SsemeryTMP_FILE=$(mktemp -q -t kclient-tmpfile.XXXXXX) 15896656Ssemeryexport KRB5_CONFIG=$(mktemp -q -t kclient-krb5conf.XXXXXX) 15906815Ssemeryexport KRB5CCNAME=$(mktemp -q -t kclient-krb5ccache.XXXXXX) 15916656Ssemerynew_keytab=$(mktemp -q -t kclient-krb5keytab.XXXXXX) 15926656Ssemeryif [[ -z $TMP_FILE || -z $KRB5_CONFIG || -z $KRB5CCNAME || -z $new_keytab ]] 15936656Ssemerythen 15949833SShawn.Emery@Sun.COM printf "\n$(gettext "Can not create temporary files, exiting").\n\n" >&2 15959833SShawn.Emery@Sun.COM exit 1 15960Sstevel@tonic-gatefi 15970Sstevel@tonic-gate 15980Sstevel@tonic-gate# 15990Sstevel@tonic-gate# If we are interrupted, cleanup after ourselves 16000Sstevel@tonic-gate# 16016656Ssemerytrap "exiting 1" HUP INT QUIT TERM 16020Sstevel@tonic-gate 16036656Ssemeryif [[ -d /usr/bin ]]; then 16046656Ssemery if [[ -d /usr/sbin ]]; then 16050Sstevel@tonic-gate PATH=/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:$PATH 16060Sstevel@tonic-gate export PATH 16070Sstevel@tonic-gate else 16080Sstevel@tonic-gate printf "\n$(gettext "Directory /usr/sbin not found, exiting").\n" >&2 16090Sstevel@tonic-gate exit 1 16100Sstevel@tonic-gate fi 16110Sstevel@tonic-gateelse 16120Sstevel@tonic-gate printf "\n$(gettext "Directory /usr/bin not found, exiting").\n" >&2 16130Sstevel@tonic-gate exit 1 16140Sstevel@tonic-gatefi 16150Sstevel@tonic-gate 16160Sstevel@tonic-gateprintf "\n$(gettext "Starting client setup")\n\n" 16176656Ssemeryprintf -- "---------------------------------------------------\n" 16180Sstevel@tonic-gate 16190Sstevel@tonic-gate# 16200Sstevel@tonic-gate# Check for uid 0, disallow otherwise 16210Sstevel@tonic-gate# 16220Sstevel@tonic-gateid 1>$TMP_FILE 2>&1 16236656Ssemeryif [[ $? -eq 0 ]]; then 16240Sstevel@tonic-gate if egrep -s "uid=0\(root\)" $TMP_FILE; then 16250Sstevel@tonic-gate # uid is 0, go ahead ... 16260Sstevel@tonic-gate : 16270Sstevel@tonic-gate else 16286656Ssemery printf "\n$(gettext "Administrative privileges are required to run this script, exiting").\n" >&2 16290Sstevel@tonic-gate error_message 16300Sstevel@tonic-gate fi 16310Sstevel@tonic-gateelse 16320Sstevel@tonic-gate cat $TMP_FILE; 16336656Ssemery printf "\n$(gettext "uid check failed, exiting").\n" >&2 16340Sstevel@tonic-gate error_message 16350Sstevel@tonic-gatefi 16360Sstevel@tonic-gate 16376656Ssemeryuname=$(uname -n) 16386656Ssemeryhostname=${uname%%.*} 16390Sstevel@tonic-gate 16400Sstevel@tonic-gate# 16410Sstevel@tonic-gate# Process the command-line arguments (if any) 16420Sstevel@tonic-gate# 16430Sstevel@tonic-gateOPTIND=1 16446656Ssemerywhile getopts nD:Kp:R:k:a:c:d:f:h:m:s:T: OPTIONS 16450Sstevel@tonic-gatedo 16460Sstevel@tonic-gate case $OPTIONS in 16476656Ssemery D) options="$options -D" 16486656Ssemery domain_list="$OPTARG" 16496656Ssemery ;; 16506656Ssemery K) options="$options -K" 16516656Ssemery no_keytab=yes 16520Sstevel@tonic-gate ;; 16530Sstevel@tonic-gate R) options="$options -R" 16546656Ssemery realm="$OPTARG" 16556656Ssemery checkval="REALM"; check_value $realm 16560Sstevel@tonic-gate ;; 16576656Ssemery T) options="$options -T" 16586656Ssemery type="$OPTARG" 16596656Ssemery if [[ $type == ms_ad ]]; then 16606656Ssemery msad=yes 16616656Ssemery adddns=yes 16626656Ssemery else 16636656Ssemery non_solaris=yes 16646656Ssemery no_keytab=yes 16656656Ssemery fi 16660Sstevel@tonic-gate ;; 16670Sstevel@tonic-gate a) options="$options -a" 16680Sstevel@tonic-gate ADMIN_PRINC="$OPTARG" 16690Sstevel@tonic-gate checkval="ADMIN_PRINC"; check_value $ADMIN_PRINC 16700Sstevel@tonic-gate ;; 16710Sstevel@tonic-gate c) options="$options -c" 16720Sstevel@tonic-gate filepath="$OPTARG" 16730Sstevel@tonic-gate ;; 16740Sstevel@tonic-gate d) options="$options -d" 16750Sstevel@tonic-gate dnsarg="$OPTARG" 16760Sstevel@tonic-gate checkval="DNS_OPTIONS"; check_value $dnsarg 16770Sstevel@tonic-gate ;; 16780Sstevel@tonic-gate f) options="$options -f" 16790Sstevel@tonic-gate fqdnlist="$OPTARG" 16800Sstevel@tonic-gate ;; 16816656Ssemery h) options="$options -h" 16826656Ssemery logical_hn="$OPTARG" 16836656Ssemery checkval="LOGICAL_HOSTNAME"; check_value $logical_hn 16846656Ssemery ;; 16856656Ssemery k) options="$options -k" 16866656Ssemery kdc_list="$OPTARG" 16876656Ssemery ;; 16886656Ssemery m) options="$options -m" 16896656Ssemery KDC="$OPTARG" 16906656Ssemery checkval="KDC"; check_value $KDC 16916656Ssemery ;; 16920Sstevel@tonic-gate n) options="$options -n" 16930Sstevel@tonic-gate add_nfs=yes 16940Sstevel@tonic-gate ;; 16956656Ssemery p) options="$options -p" 16966656Ssemery profile="$OPTARG" 16976656Ssemery read_profile $profile 16986656Ssemery ;; 16996656Ssemery s) options="$options -s" 17006656Ssemery svc_list="$OPTARG" 17016656Ssemery SVCs=${svc_list//,/ } 17026656Ssemery ;; 17030Sstevel@tonic-gate \?) usage 17046656Ssemery ;; 17050Sstevel@tonic-gate *) usage 17060Sstevel@tonic-gate ;; 17070Sstevel@tonic-gate esac 17080Sstevel@tonic-gatedone 17090Sstevel@tonic-gate 17100Sstevel@tonic-gate#correct argument count after options 17110Sstevel@tonic-gateshift `expr $OPTIND - 1` 17120Sstevel@tonic-gate 17136656Ssemeryif [[ -z $options ]]; then 17140Sstevel@tonic-gate : 17150Sstevel@tonic-gateelse 17166656Ssemery if [[ $# -ne 0 ]]; then 17170Sstevel@tonic-gate usage 17180Sstevel@tonic-gate fi 17190Sstevel@tonic-gatefi 17200Sstevel@tonic-gate 17216656Ssemery# 17226815Ssemery# Check to see if we will be a client of a MIT, Heimdal, Shishi, etc. 17236815Ssemery# 17246815Ssemeryif [[ -z $options ]]; then 17256815Ssemery query "$(gettext "Is this a client of a non-Solaris KDC") ?" 17266815Ssemery non_solaris=$answer 17276815Ssemery if [[ $non_solaris == yes ]]; then 17286815Ssemery printf "$(gettext "Which type of KDC is the server"):\n" 17296815Ssemery printf "\t$(gettext "ms_ad: Microsoft Active Directory")\n" 17306815Ssemery printf "\t$(gettext "mit: MIT KDC server")\n" 17316815Ssemery printf "\t$(gettext "heimdal: Heimdal KDC server")\n" 17326815Ssemery printf "\t$(gettext "shishi: Shishi KDC server")\n" 17336815Ssemery printf "$(gettext "Enter required KDC type"): " 17346815Ssemery read kdctype 17356815Ssemery if [[ $kdctype == ms_ad ]]; then 17366815Ssemery msad=yes 17376815Ssemery elif [[ $kdctype == mit || $kdctype == heimdal || \ 17386815Ssemery $kdctype == shishi ]]; then 17396815Ssemery no_keytab=yes 17406815Ssemery else 17416815Ssemery printf "\n$(gettext "Invalid KDC type option, valid types are ms_ad, mit, heimdal, or shishi, exiting").\n" >&2 17426815Ssemery error_message 17436815Ssemery fi 17446815Ssemery fi 17456815Ssemeryfi 17466815Ssemery 17476815Ssemery[[ $msad == yes ]] && join_domain 17486815Ssemery 17496815Ssemery# 17506656Ssemery# Check for /etc/resolv.conf 17516656Ssemery# 17526656Ssemeryif [[ -r $RESOLV_CONF_FILE ]]; then 17536656Ssemery client_machine=`$KLOOKUP` 17546656Ssemery 17556656Ssemery if [[ $? -ne 0 ]]; then 17566656Ssemery if [[ $adddns == no ]]; then 17576656Ssemery printf "\n$(gettext "%s does not have a DNS record and is required for Kerberos setup")\n" $hostname >&2 17586656Ssemery error_message 17596656Ssemery fi 17606656Ssemery 17616656Ssemery else 17626656Ssemery # 17636656Ssemery # If client entry already exists then do not recreate it 17646656Ssemery # 17656656Ssemery adddns=no 17666656Ssemery 17676656Ssemery hostname=${client_machine%%.*} 17686656Ssemery domain=${client_machine#*.} 17696656Ssemery fi 17706656Ssemery 17716656Ssemery short_fqdn=${domain#*.*} 17726656Ssemery short_fqdn=$(echo $short_fqdn | grep "\.") 17736656Ssemeryelse 17746656Ssemery # 17756656Ssemery # /etc/resolv.conf not present, exit ... 17766656Ssemery # 17776656Ssemery printf "\n$(gettext "%s does not exist and is required for Kerberos setup")\n" $RESOLV_CONF_FILE >&2 17786656Ssemery printf "$(gettext "Refer to resolv.conf(4), exiting").\n" >&2 17796656Ssemery error_message 17806656Ssemeryfi 17816656Ssemery 17826815Ssemerycheck_nss_conf || printf "$(gettext "/etc/nsswitch.conf does not make use of DNS for hosts and/or ipnodes").\n" 17836656Ssemery 17846656Ssemery[[ -n $fqdnlist ]] && verify_fqdnlist "$fqdnlist" 17856656Ssemery 17866815Ssemeryif [[ -z $dnsarg && (-z $options || -z $filepath) ]]; then 17870Sstevel@tonic-gate query "$(gettext "Do you want to use DNS for kerberos lookups") ?" 17886656Ssemery if [[ $answer == yes ]]; then 17896656Ssemery printf "\n$(gettext "Valid DNS lookup options are dns_lookup_kdc, dns_lookup_realm,\nand dns_fallback. Refer krb5.conf(4) for further details").\n" 17906656Ssemery printf "\n$(gettext "Enter required DNS option"): " 17910Sstevel@tonic-gate read dnsarg 17920Sstevel@tonic-gate checkval="DNS_OPTIONS"; check_value $dnsarg 17930Sstevel@tonic-gate set_dns_value $dnsarg 17940Sstevel@tonic-gate fi 17950Sstevel@tonic-gateelse 17966815Ssemery [[ -z $dnsarg ]] && dnsarg=none 17970Sstevel@tonic-gate set_dns_value $dnsarg 17980Sstevel@tonic-gatefi 17990Sstevel@tonic-gate 18006656Ssemeryif [[ -n $kdc_list ]]; then 18016656Ssemery if [[ -z $KDC ]]; then 18026656Ssemery for kdc in $kdc_list; do 18036656Ssemery break 18046656Ssemery done 18056656Ssemery KDC="$kdc" 18066656Ssemery fi 18070Sstevel@tonic-gatefi 18086656Ssemery 18096815Ssemeryif [[ -z $realm ]]; then 18106656Ssemery printf "$(gettext "Enter the Kerberos realm"): " 18116656Ssemery read realm 18126656Ssemery checkval="REALM"; check_value $realm 18136656Ssemeryfi 18146815Ssemeryif [[ -z $KDC ]]; then 18156656Ssemery printf "$(gettext "Specify the master KDC hostname for the above realm"): " 18160Sstevel@tonic-gate read KDC 18170Sstevel@tonic-gate checkval="KDC"; check_value $KDC 18180Sstevel@tonic-gatefi 18190Sstevel@tonic-gate 18206656SsemeryFKDC=`$KLOOKUP $KDC` 18210Sstevel@tonic-gate 18220Sstevel@tonic-gate# 18230Sstevel@tonic-gate# Ping to see if the kdc is alive ! 18240Sstevel@tonic-gate# 18256656Ssemeryping_check $FKDC "KDC" 18266656Ssemery 18276815Ssemeryif [[ -z $kdc_list && (-z $options || -z $filepath) ]]; then 18286815Ssemery query "$(gettext "Do you have any slave KDC(s)") ?" 18296815Ssemery if [[ $answer == yes ]]; then 18306815Ssemery printf "$(gettext "Enter a comma-separated list of slave KDC host names"): " 18316815Ssemery read kdc_list 18326815Ssemery fi 18336815Ssemeryfi 18346815Ssemery 18356815Ssemery[[ -n $kdc_list ]] && verify_kdcs "$kdc_list" 18366815Ssemery 18376656Ssemery# 18386656Ssemery# Check to see if we will have a dynamic presence in the realm 18396656Ssemery# 18406656Ssemeryif [[ -z $options ]]; then 18416656Ssemery query "$(gettext "Will this client need service keys") ?" 18426656Ssemery if [[ $answer == no ]]; then 18436656Ssemery no_keytab=yes 18446656Ssemery fi 18456656Ssemeryfi 18460Sstevel@tonic-gate 18476656Ssemery# 18486656Ssemery# Check to see if we are configuring the client to use a logical host name 18496656Ssemery# of a cluster environment 18506656Ssemery# 18516656Ssemeryif [[ -z $options ]]; then 18526656Ssemery query "$(gettext "Is this client a member of a cluster that uses a logical host name") ?" 18536656Ssemery if [[ $answer == yes ]]; then 18546656Ssemery printf "$(gettext "Specify the logical hostname of the cluster"): " 18556656Ssemery read logical_hn 18566656Ssemery checkval="LOGICAL_HOSTNAME"; check_value $logical_hn 18576656Ssemery setup_lhn 18586656Ssemery fi 18596656Ssemeryfi 18606656Ssemery 18616815Ssemeryif [[ -n $domain_list && (-z $options || -z $filepath) ]]; then 18626656Ssemery query "$(gettext "Do you have multiple domains/hosts to map to realm %s" 18636656Ssemery) ?" $realm 18646656Ssemery if [[ $answer == yes ]]; then 18656815Ssemery printf "$(gettext "Enter a comma-separated list of domain/hosts 18666656Ssemeryto map to the default realm"): " 18676656Ssemery read domain_list 18686656Ssemery fi 18696656Ssemeryfi 18706656Ssemery[[ -n domain_list ]] && domain_list=${domain_list//,/ } 18710Sstevel@tonic-gate 18720Sstevel@tonic-gate# 18730Sstevel@tonic-gate# Start writing up the krb5.conf file, save the existing one 18740Sstevel@tonic-gate# if already present 18750Sstevel@tonic-gate# 18760Sstevel@tonic-gatewriteup_krb5_conf 18770Sstevel@tonic-gate 18786656Ssemery# 18796656Ssemery# Is this client going to use krb-nfs? If so then we need to at least 18806656Ssemery# uncomment the krb5* sec flavors in nfssec.conf. 18816656Ssemery# 18826656Ssemeryif [[ -z $options ]]; then 18836656Ssemery query "$(gettext "Do you plan on doing Kerberized nfs") ?" 18846656Ssemery add_nfs=$answer 18856656Ssemeryfi 18866656Ssemery 18876656Ssemeryif [[ $add_nfs == yes ]]; then 18886656Ssemery modify_nfssec_conf 18896656Ssemery 18906656Ssemery # 18916656Ssemery # We also want to enable gss as we now live in a SBD world 18926656Ssemery # 18936656Ssemery svcadm enable svc:/network/rpc/gss:default 18946656Ssemery [[ $? -ne 0 ]] && printf "$(gettext "Warning: could not enable gss service").\n" 18956656Ssemeryfi 18966656Ssemery 18976656Ssemeryif [[ -z $options ]]; then 18986656Ssemery query "$(gettext "Do you want to update /etc/pam.conf") ?" 18996656Ssemery if [[ $answer == yes ]]; then 19006656Ssemery printf "$(gettext "Enter a list of PAM service names in the following format: service:{first|only|optional}[,..]"): " 19016656Ssemery read svc_list 19026656Ssemery SVCs=${svc_list//,/ } 19036656Ssemery fi 19046656Ssemeryfi 19056656Ssemery[[ -n $svc_list ]] && update_pam_conf 19060Sstevel@tonic-gate 19070Sstevel@tonic-gate# 19086656Ssemery# Copy over krb5.conf master copy from filepath 19090Sstevel@tonic-gate# 19106656Ssemeryif [[ -z $options || -z $filepath ]]; then 19116656Ssemery query "$(gettext "Do you want to copy over the master krb5.conf file") ?" 19126656Ssemery if [[ $answer == yes ]]; then 19136656Ssemery printf "$(gettext "Enter the pathname of the file to be copied"): " 19146656Ssemery read filepath 19150Sstevel@tonic-gate fi 19160Sstevel@tonic-gatefi 19170Sstevel@tonic-gate 19186815Ssemeryif [[ -n $filepath && -r $filepath ]]; then 19196815Ssemery cp $filepath $KRB5_CONFIG 19206815Ssemery if [[ $? -eq 0 ]]; then 19216815Ssemery printf "$(gettext "Copied %s to %s").\n" $filepath $KRB5_CONFIG 19220Sstevel@tonic-gate else 19236815Ssemery printf "$(gettext "Copy of %s failed, exiting").\n" $filepath >&2 19246656Ssemery error_message 19250Sstevel@tonic-gate fi 19266815Ssemeryelif [[ -n $filepath ]]; then 19276815Ssemery printf "\n$(gettext "%s not found, exiting").\n" $filepath >&2 19286815Ssemery error_message 19290Sstevel@tonic-gatefi 19300Sstevel@tonic-gate 19316815SsemerydoKRB5config 19326815Ssemery 19330Sstevel@tonic-gate# 19346656Ssemery# Populate any service keys needed for the client in the keytab file 19350Sstevel@tonic-gate# 19366815Ssemeryif [[ $no_keytab != yes ]]; then 19376815Ssemery setup_keytab 19386815Ssemeryelse 19396815Ssemery printf "\n$(gettext "Note: %s file not created, please refer to verify_ap_req_nofail in krb5.conf(4) for the implications").\n" $KRB5_KEYTAB_FILE 19406815Ssemery printf "$(gettext "Client will also not be able to host services that use Kerberos").\n" 19416815Ssemeryfi 19420Sstevel@tonic-gate 19436656Ssemeryprintf -- "\n---------------------------------------------------\n" 19446656Ssemeryprintf "$(gettext "Setup COMPLETE").\n\n" 19450Sstevel@tonic-gate 19460Sstevel@tonic-gate# 19476656Ssemery# If we have configured the client in a cluster we need to remind the user 19486656Ssemery# to propagate the keytab and configuration files to the other members. 19490Sstevel@tonic-gate# 19506656Ssemeryif [[ -n $logical_hn ]]; then 19516656Ssemery printf "\n$(gettext "Note, you will need to securely transfer the /etc/krb5/krb5.keytab and /etc/krb5/krb5.conf files to all the other members of your cluster").\n" 19520Sstevel@tonic-gatefi 19530Sstevel@tonic-gate 19546656Ssemery# 19556656Ssemery# Cleanup. 19560Sstevel@tonic-gate# 19576656Ssemerykdestroy -q 1>$TMP_FILE 2>&1 19580Sstevel@tonic-gaterm -f $TMP_FILE 19596656Ssemeryrm -rf $TMPDIR > /dev/null 2>&1 19600Sstevel@tonic-gateexit 0 1961