11fceb383Ssemery#!/usr/bin/ksh
21fceb383Ssemery#
32707a226Ssemery# CDDL HEADER START
42707a226Ssemery#
52707a226Ssemery# The contents of this file are subject to the terms of the
62707a226Ssemery# Common Development and Distribution License (the "License").
72707a226Ssemery# You may not use this file except in compliance with the License.
82707a226Ssemery#
92707a226Ssemery# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
102707a226Ssemery# or http://www.opensolaris.org/os/licensing.
112707a226Ssemery# See the License for the specific language governing permissions
122707a226Ssemery# and limitations under the License.
132707a226Ssemery#
142707a226Ssemery# When distributing Covered Code, include this CDDL HEADER in each
152707a226Ssemery# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
162707a226Ssemery# If applicable, add the following below this CDDL HEADER, with the
172707a226Ssemery# fields enclosed by brackets "[]" replaced with your own identifying
182707a226Ssemery# information: Portions Copyright [yyyy] [name of copyright owner]
192707a226Ssemery#
201fceb383Ssemery# CDDL HEADER END
211fceb383Ssemery#
22*b793cf1fSShawn Emery# Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
231fceb383Ssemery# Use is subject to license terms.
241fceb383Ssemery#
251fceb383Ssemery
261fceb383Ssemery#
271fceb383Ssemery# This command provides an simple interface to configure, destroy, and to obtain
281fceb383Ssemery# the status of a master or slave Kerberos KDC server.
291fceb383Ssemery#
301fceb383Ssemery
311fceb383Ssemeryfunction usage {
321fceb383Ssemery
331fceb383Ssemery	app=`basename $0`
341fceb383Ssemery
351fceb383Ssemery	printf "\n$(gettext "Usage: %s [ -a admprincipal ] [ -e enctype ] [ -h ]")\n" $app
361fceb383Ssemery	printf "\t$(gettext "[ -p pwfile ] [ -r realm ] subcommand")\n\n"
371fceb383Ssemery
381fceb383Ssemery	printf "\t$(gettext "-a: Create non-default admin principal.")\n"
391fceb383Ssemery	printf "\t$(gettext "-e: Encryption type used to encrypt the master key")\n"
401fceb383Ssemery	printf "\t$(gettext "-h: This help message.")\n"
411fceb383Ssemery	printf "\t$(gettext "-p: File that contains the admin principal and master key password.")\n"
421fceb383Ssemery	printf "\t$(gettext "-r: Set the default realm for this server.")\n\n"
431fceb383Ssemery
441fceb383Ssemery	printf "\t$(gettext "where 'subcommand' is one of the following:")\n\n"
451fceb383Ssemery
461fceb383Ssemery	printf "\t$(gettext "create [ master ]")\n"
471fceb383Ssemery	printf "\t$(gettext "create [ -m masterkdc ] slave")\n"
481fceb383Ssemery	printf "\t$(gettext "destroy")\n"
491fceb383Ssemery	printf "\t$(gettext "status")\n\n"
501fceb383Ssemery
5167c90040Ssemery	cleanup 1
521fceb383Ssemery}
531fceb383Ssemery
541fceb383Ssemeryfunction ask {
551fceb383Ssemery
561fceb383Ssemery	# ask question, set global answer
571fceb383Ssemery	typeset question=$1 default_answer=$2
581fceb383Ssemery	if [[ -z $default_answer ]]; then
591fceb383Ssemery		print "$question \c"
601fceb383Ssemery	else
611fceb383Ssemery		print "$question [$default_answer]: \c"
621fceb383Ssemery	fi
631fceb383Ssemery	read answer
641fceb383Ssemery	[ -z "$answer" ] && answer="$default_answer"
651fceb383Ssemery}
661fceb383Ssemery
671fceb383Ssemeryfunction yesno {
681fceb383Ssemery
691fceb383Ssemery	typeset question="$1"
701fceb383Ssemery	# answer is a global set by ask
711fceb383Ssemery	answer=
721fceb383Ssemery	yn=`printf "$(gettext "y/n")"`
731fceb383Ssemery	y=`printf "$(gettext "y")"`
741fceb383Ssemery	n=`printf "$(gettext "n")"`
751fceb383Ssemery	yes=`printf "$(gettext "yes")"`
761fceb383Ssemery	no=`printf "$(gettext "no")"`
771fceb383Ssemery
781fceb383Ssemery	while [[ -z $answer ]]; do
791fceb383Ssemery		ask "$question" $yn
801fceb383Ssemery		case $answer in
811fceb383Ssemery			$y|$yes)	answer=yes;;
821fceb383Ssemery			$n|$no)		answer=no;;
831fceb383Ssemery			*)		answer=;;
841fceb383Ssemery		esac
851fceb383Ssemery	done
861fceb383Ssemery}
871fceb383Ssemery
881fceb383Ssemeryfunction query {
891fceb383Ssemery
901fceb383Ssemery	yesno "$*"
911fceb383Ssemery	if [[ $answer = no ]]; then
921fceb383Ssemery		printf "\t$(gettext "No action performed").\n"
931fceb383Ssemery	fi
941fceb383Ssemery}
951fceb383Ssemery
961fceb383Ssemeryfunction cleanup {
971fceb383Ssemery
9867c90040Ssemery	integer ret=$1
9967c90040Ssemery
1001fceb383Ssemery	kdestroy -q -c $TMP_CCACHE 1>$TMP_FILE 2>&1
1011fceb383Ssemery        rm -f $TMP_FILE
10267c90040Ssemery
10367c90040Ssemery        exit $ret
1041fceb383Ssemery}
1051fceb383Ssemery
1061fceb383Ssemeryfunction error_message {
1071fceb383Ssemery
1081fceb383Ssemery        printf "---------------------------------------------------\n"
1091fceb383Ssemery        printf "$(gettext "Setup FAILED").\n\n"
1101fceb383Ssemery
11167c90040Ssemery	cleanup 1
1121fceb383Ssemery}
1131fceb383Ssemery
1141fceb383Ssemeryfunction check_bin {
1151fceb383Ssemery
1161fceb383Ssemery	bin=$1
1171fceb383Ssemery
1181fceb383Ssemery	if [[ ! -x $bin ]]; then
1191fceb383Ssemery		printf "$(gettext "Could not access/execute %s").\n" $bin
1201fceb383Ssemery		error_message
1211fceb383Ssemery	fi
1221fceb383Ssemery}
1231fceb383Ssemery
1241fceb383Ssemeryfunction check_ret {
1251fceb383Ssemery
1261fceb383Ssemery	integer ret=$1
1271fceb383Ssemery	prog=$2
1281fceb383Ssemery
1291fceb383Ssemery	if [[ $ret -ne 0 ]]; then
1301fceb383Ssemery		printf "\n$(gettext "%s failed with return value %d, exiting").\n\n" $prog $ret
1311fceb383Ssemery		error_message
1321fceb383Ssemery	fi
1331fceb383Ssemery}
1341fceb383Ssemery
1351fceb383Ssemery
1361fceb383Ssemeryfunction ok_to_proceed {
1371fceb383Ssemery
1381fceb383Ssemery	yesno "$@"
1391fceb383Ssemery
1401fceb383Ssemery	if [[ $answer = no ]]; then
1411fceb383Ssemery		printf "\n$(gettext "Exiting, no action performed")\n\n"
14267c90040Ssemery		cleanup 0
1431fceb383Ssemery	fi
1441fceb383Ssemery}
1451fceb383Ssemery
1461fceb383Ssemeryfunction check_value {
1471fceb383Ssemery
1481fceb383Ssemery	typeset arg="$1"
1491fceb383Ssemery
1501fceb383Ssemery	if [[ -z $arg ]]; then
1511fceb383Ssemery		printf "\n$(gettext "No input obtained for %s, exiting").\n" $checkval
1521fceb383Ssemery		error_message
1531fceb383Ssemery	else
1541fceb383Ssemery		echo "$arg">$TMP_FILE
1551fceb383Ssemery		if egrep -s '[*$^#!]+' $TMP_FILE; then
1561fceb383Ssemery			printf "\n$(gettext "Invalid input obtained for %s, exiting").\n" $checkval
1571fceb383Ssemery			error_message
1581fceb383Ssemery		fi
1591fceb383Ssemery	fi
1601fceb383Ssemery}
1611fceb383Ssemery
1621fceb383Ssemeryfunction setup_kdc_conf {
1631fceb383Ssemery
1641fceb383Ssemery	printf "\n$(gettext "Setting up %s").\n" $KRB5_KDC_CONF
1651fceb383Ssemery
1661fceb383Ssemery	if [[ -r $KRB5_KDC_CONF ]]; then
1671fceb383Ssemery		cat $KRB5_KDC_CONF > $KRB5_KDC_CONF.sav
1681fceb383Ssemery		cannot_create $KRB5_KDC_CONF.sav $?
1691fceb383Ssemery	fi
1701fceb383Ssemery
1711fceb383Ssemery	exec 3>$KRB5_KDC_CONF
1721fceb383Ssemery	if [[ $? -ne 0 ]]; then
1731fceb383Ssemery		printf "\n$(gettext "Cannot write to %s, exiting").\n" $KRB5_KDC_CONF
1741fceb383Ssemery		error_message
1751fceb383Ssemery	fi
1761fceb383Ssemery
1771fceb383Ssemery	printf "\n[kdcdefaults]\n\tkdc_ports = 88,750\n\n" 1>&3
1781fceb383Ssemery	printf "[realms]\n\t$REALM = {\n" 1>&3
1791fceb383Ssemery	printf "\t\tprofile = $KRB5_KRB_CONF\n" 1>&3
1801fceb383Ssemery	printf "\t\tdatabase_name = $PRINCDB\n" 1>&3
1811fceb383Ssemery	printf "\t\tmaster_key_type = $ENCTYPE\n" 1>&3
1821fceb383Ssemery	printf "\t\tacl_file = $KADM5ACL\n" 1>&3
1831fceb383Ssemery	printf "\t\tkadmind_port = 749\n" 1>&3
1841fceb383Ssemery	printf "\t\tmax_life = 8h 0m 0s\n" 1>&3
1851fceb383Ssemery	printf "\t\tmax_renewable_life = 7d 0h 0m 0s\n" 1>&3
1861fceb383Ssemery	printf "\t\tdefault_principal_flags = +preauth\n" 1>&3
1871fceb383Ssemery
1881fceb383Ssemery	printf "\t\tsunw_dbprop_enable = true\n" 1>&3
1891fceb383Ssemery	if [[ $master = yes ]]; then
1901fceb383Ssemery		printf "\t\tsunw_dbprop_master_ulogsize = 1000\n" 1>&3
1911fceb383Ssemery	fi
1921fceb383Ssemery	if [[ $slave = yes ]]; then
1931fceb383Ssemery		printf "\t\tsunw_dbprop_slave_poll = 2m\n" 1>&3
1941fceb383Ssemery	fi
1951fceb383Ssemery
1961fceb383Ssemery	printf "\t}\n" 1>&3
1971fceb383Ssemery}
1981fceb383Ssemery
1991fceb383Ssemeryfunction setup_krb_conf {
2001fceb383Ssemery
2011fceb383Ssemery	printf "\n$(gettext "Setting up %s").\n" $KRB5_KRB_CONF
2021fceb383Ssemery
2031fceb383Ssemery	if [[ -r $KRB5_KRB_CONF ]]; then
2041fceb383Ssemery		cat $KRB5_KRB_CONF > $KRB5_KRB_CONF.sav
2051fceb383Ssemery		cannot_create $KRB5_KRB_CONF.sav $?
2061fceb383Ssemery	fi
2071fceb383Ssemery
2081fceb383Ssemery	exec 3>$KRB5_KRB_CONF
2091fceb383Ssemery	if [[ $? -ne 0 ]]; then
2101fceb383Ssemery		printf "\n$(gettext "Cannot write to %s, exiting").\n" $KRB5_KRB_CONF
2111fceb383Ssemery		error_message
2121fceb383Ssemery	fi
2131fceb383Ssemery
2141fceb383Ssemery	printf "[libdefaults]\n" 1>&3
2151fceb383Ssemery	printf "\tdefault_realm = $REALM\n\n" 1>&3
2161fceb383Ssemery
2171fceb383Ssemery	printf "[realms]\n" 1>&3
2181fceb383Ssemery	printf "\t$REALM = {\n" 1>&3
2191fceb383Ssemery	if [[ $slave = yes ]]; then
2201fceb383Ssemery		printf "\t\tkdc = $master_hn\n" 1>&3
2211fceb383Ssemery	fi
2221fceb383Ssemery	printf "\t\tkdc = $fqhn\n" 1>&3
2231fceb383Ssemery	if [[ $master = yes ]]; then
2241fceb383Ssemery		printf "\t\tadmin_server = $fqhn\n" 1>&3
2251fceb383Ssemery	else
2261fceb383Ssemery		printf "\t\tadmin_server = $master_hn\n" 1>&3
2271fceb383Ssemery	fi
2281fceb383Ssemery	printf "\t}\n\n" 1>&3
2291fceb383Ssemery
2301fceb383Ssemery	printf "[domain_realm]\n" 1>&3
2311fceb383Ssemery	printf "\t.$domain = $REALM\n\n" 1>&3
2321fceb383Ssemery
2331fceb383Ssemery	printf "[logging]\n" 1>&3
2341fceb383Ssemery	printf "\tdefault = FILE:/var/krb5/kdc.log\n" 1>&3
2351fceb383Ssemery	printf "\tkdc = FILE:/var/krb5/kdc.log\n" 1>&3
2361fceb383Ssemery	printf "\tkdc_rotate = {\n\t\tperiod = 1d\n\t\tversions = 10\n\t}\n\n" 1>&3
2371fceb383Ssemery
2381fceb383Ssemery	printf "[appdefaults]\n" 1>&3
2391fceb383Ssemery	printf "\tkinit = {\n\t\trenewable = true\n\t\tforwardable = true\n" 1>&3
2401fceb383Ssemery	printf "\t}\n" 1>&3
2411fceb383Ssemery}
2421fceb383Ssemery
2431fceb383Ssemeryfunction cannot_create {
2441fceb383Ssemery
2451fceb383Ssemery	typeset filename="$1"
2461fceb383Ssemery	typeset stat="$2"
2471fceb383Ssemery	if [[ $stat -ne 0 ]]; then
2481fceb383Ssemery		printf "\n$(gettext "Cannot create/edit %s, exiting").\n" $filename
2491fceb383Ssemery		error_message
2501fceb383Ssemery	fi
2511fceb383Ssemery}
2521fceb383Ssemery
2531fceb383Ssemeryfunction check_admin {
2541fceb383Ssemery
2551fceb383Ssemery	message=$1
2561fceb383Ssemery
2571fceb383Ssemery	if [[ -z $ADMIN_PRINC ]]; then
2581fceb383Ssemery		printf "$message"
2591fceb383Ssemery		read ADMIN_PRINC
2601fceb383Ssemery		checkval="ADMIN_PRINC"; check_value $ADMIN_PRINC
2611fceb383Ssemery	fi
2621fceb383Ssemery
2631fceb383Ssemery	echo "$ADMIN_PRINC">$TMP_FILE
2641fceb383Ssemery
2651fceb383Ssemery	if egrep -s '\/admin' $TMP_FILE; then
2661fceb383Ssemery		# Already in "/admin" format, do nothing
2671fceb383Ssemery		:
2681fceb383Ssemery	else
2691fceb383Ssemery		if egrep -s '\/' $TMP_FILE; then
2701fceb383Ssemery			printf "\n$(gettext "Improper entry for krb5 admin principal, exiting").\n"
2711fceb383Ssemery			error_message
2721fceb383Ssemery		else
2731fceb383Ssemery			ADMIN_PRINC=$(echo "$ADMIN_PRINC/admin")
2741fceb383Ssemery		fi
2751fceb383Ssemery	fi
2761fceb383Ssemery
2771fceb383Ssemery}
2781fceb383Ssemery
2791fceb383Ssemeryfunction ping_check {
2801fceb383Ssemery
2811fceb383Ssemery	typeset machine="$1"
2821fceb383Ssemery
2831fceb383Ssemery	if $PING $machine > /dev/null 2>&1; then
2841fceb383Ssemery		:
2851fceb383Ssemery	else
2861fceb383Ssemery		printf "\n$(gettext "%s %s is unreachable, exiting").\n" $string $machine
2871fceb383Ssemery		error_message
2881fceb383Ssemery	fi
2891fceb383Ssemery}
2901fceb383Ssemery
2911fceb383Ssemeryfunction check_host {
2921fceb383Ssemery
2931fceb383Ssemery	echo "$host">$TMP_FILE
2941fceb383Ssemery	if egrep -s '[^.]\.[^.]+$' $TMP_FILE; then
2951fceb383Ssemery		# do nothing, host is in fqhn format
2961fceb383Ssemery		:
2971fceb383Ssemery	else
2981fceb383Ssemery		if egrep -s '\.+' $TMP_FILE; then
2991fceb383Ssemery			printf "\n$(gettext "Improper format of host name: '%s'").\n"
3001fceb383Ssemery			printf "$(gettext "Expecting the following format: 'somehost.example.com' or 'somehost', exiting").\n"
3011fceb383Ssemery			error_message
3021fceb383Ssemery		else
3031fceb383Ssemery			# Attach fqdn to host, to get the Fully Qualified Domain
3041fceb383Ssemery			# Name of the host requested
3051fceb383Ssemery			host=$(echo "$host.$domain")
3061fceb383Ssemery		fi
3071fceb383Ssemery	fi
3081fceb383Ssemery
3091fceb383Ssemery	#
3101fceb383Ssemery	# Ping to see if the host is alive!
3111fceb383Ssemery	#
3121fceb383Ssemery	ping_check $host
3131fceb383Ssemery}
3141fceb383Ssemery
3151fceb383Ssemeryfunction kill_daemons {
3161fceb383Ssemery
3171fceb383Ssemery	# Kill daemons so they won't go into maintenance mode
3181fceb383Ssemery	$SVCADM disable -s krb5kdc
3191fceb383Ssemery	if [[ $? -ne 0 ]]; then
3201fceb383Ssemery		printf "\n$(gettext "Error in disabling krb5kdc, exiting").\n"
3211fceb383Ssemery		error_message
3221fceb383Ssemery	fi
3231fceb383Ssemery	$SVCADM disable -s kadmin
3241fceb383Ssemery	if [[ $? -ne 0 ]]; then
3251fceb383Ssemery		printf "\n$(gettext "Error in disabling kadmind, exiting").\n"
3261fceb383Ssemery		error_message
3271fceb383Ssemery	fi
3281fceb383Ssemery	$SVCADM disable -s krb5_prop
3291fceb383Ssemery	if [[ $? -ne 0 ]]; then
3301fceb383Ssemery		printf "\n$(gettext "Error in disabling kpropd, exiting").\n"
3311fceb383Ssemery		error_message
3321fceb383Ssemery	fi
3331fceb383Ssemery
3341fceb383Ssemery	# Make sure that none of the daemons outside of SMF are running either
3351fceb383Ssemery	pkill kadmind
3361fceb383Ssemery	if [[ $? -gt 1 ]]; then
3371fceb383Ssemery		printf "\n$(gettext "Error in killing kadmind, exiting").\n"
3381fceb383Ssemery		error_message
3391fceb383Ssemery	fi
3401fceb383Ssemery	pkill krb5kdc
3411fceb383Ssemery	if [[ $? -gt 1 ]]; then
3421fceb383Ssemery		printf "\n$(gettext "Error in killing krb5kdc, exiting").\n"
3431fceb383Ssemery		error_message
3441fceb383Ssemery	fi
3451fceb383Ssemery	pkill kpropd
3461fceb383Ssemery	if [[ $? -gt 1 ]]; then
3471fceb383Ssemery		printf "\n$(gettext "Error in killing kpropd, exiting").\n"
3481fceb383Ssemery		error_message
3491fceb383Ssemery	fi
3501fceb383Ssemery}
3511fceb383Ssemery
3521fceb383Ssemeryfunction setup_mkeytab {
3531fceb383Ssemery
3541fceb383Ssemery	check_admin "\n$(gettext "Enter the krb5 administrative principal to be created"): \c"
3551fceb383Ssemery
3561fceb383Ssemery	if [[ -z $PWFILE ]]; then
3571fceb383Ssemery		echo
3581fceb383Ssemery		$KADMINL -q "ank $ADMIN_PRINC"
3591fceb383Ssemery		check_ret $? $KADMINL
3601fceb383Ssemery	else
3611fceb383Ssemery		cat $PWFILE $PWFILE | $KADMINL -q "ank $ADMIN_PRINC" > /dev/null 2>&1
3621fceb383Ssemery		check_ret $? $KADMINL
3631fceb383Ssemery	fi
3641fceb383Ssemery
3651fceb383Ssemery	$KADMINL -q "ank -randkey host/$fqhn" 1>$TMP_FILE 2>&1
3661fceb383Ssemery	check_ret $? $KADMINL
3671fceb383Ssemery	$KADMINL -q "ktadd host/$fqhn" 1>$TMP_FILE 2>&1
3681fceb383Ssemery	check_ret $? $KADMINL
3691fceb383Ssemery}
3701fceb383Ssemery
3711fceb383Ssemeryfunction setup_skeytab {
3721fceb383Ssemery
3731fceb383Ssemery	check_admin "\n$(gettext "Enter the krb5 administrative principal to be used"): \c"
3741fceb383Ssemery
3751fceb383Ssemery	printf "$(gettext "Obtaining TGT for %s") ...\n" $ADMIN_PRINC
3761fceb383Ssemery
3771fceb383Ssemery	if [[ -z $PWFILE ]]; then
3781fceb383Ssemery		kinit -c $TMP_CCACHE -S kadmin/$master_hn $ADMIN_PRINC
3791fceb383Ssemery		check_ret $? kinit
3801fceb383Ssemery	else
3811fceb383Ssemery		cat $PWFILE | kinit -c $TMP_CCACHE -S kadmin/$master_hn \
3821fceb383Ssemery			$ADMIN_PRINC > /dev/null 2>&1
3831fceb383Ssemery	fi
3841fceb383Ssemery	klist -c $TMP_CCACHE 1>$TMP_FILE 2>&1
3851fceb383Ssemery	if egrep -s "$(gettext "Valid starting")" $TMP_FILE && \
3861fceb383Ssemery	   egrep -s "kadmin/$master_hn@$REALM" $TMP_FILE; then
3871fceb383Ssemery		:
3881fceb383Ssemery	else
3891fceb383Ssemery		printf "\n$(gettext "kinit of %s failed, exiting").\n" $ADMIN_PRINC
3901fceb383Ssemery		error_message
3911fceb383Ssemery	fi
3921fceb383Ssemery
3931fceb383Ssemery	$KADMIN -c $TMP_CCACHE -q "ank -randkey kiprop/$fqhn" 1>$TMP_FILE 2>&1
3941fceb383Ssemery	check_ret $? $KADMIN
3951fceb383Ssemery	$KADMIN -c $TMP_CCACHE -q "ktadd kiprop/$fqhn" 1>$TMP_FILE 2>&1
3961fceb383Ssemery	check_ret $? $KADMIN
3971fceb383Ssemery
3981fceb383Ssemery	$KADMIN -c $TMP_CCACHE -q "ank -randkey host/$fqhn" 1>$TMP_FILE 2>&1
3991fceb383Ssemery	check_ret $? $KADMIN
4001fceb383Ssemery	$KADMIN -c $TMP_CCACHE -q "ktadd host/$fqhn" 1>$TMP_FILE 2>&1
4011fceb383Ssemery	check_ret $? $KADMIN
4021fceb383Ssemery
4031fceb383Ssemery	kdestroy -q -c $TMP_CCACHE 1>$TMP_FILE 2>&1
4041fceb383Ssemery	check_ret $? $kdestroy
4051fceb383Ssemery}
4061fceb383Ssemery
4071fceb383Ssemeryfunction setup_kadm5acl {
4081fceb383Ssemery
4091fceb383Ssemery	printf "\n$(gettext "Setting up %s").\n" $KADM5ACL
4101fceb383Ssemery
4111fceb383Ssemery	if [[ -r $KADM5ACL ]]; then
4121fceb383Ssemery		cat $KADM5ACL > $KADM5ACL.sav
4131fceb383Ssemery		cannot_create $KADM5ACL.sav $?
4141fceb383Ssemery	fi
4151fceb383Ssemery
4161fceb383Ssemery	exec 3>$KADM5ACL
4171fceb383Ssemery	if [[ $? -ne 0 ]]; then
4181fceb383Ssemery		printf "\n$(gettext "Cannot write to %s, exiting").\n" $KADM5ACL
4191fceb383Ssemery		error_message
4201fceb383Ssemery	fi
4211fceb383Ssemery
4221fceb383Ssemery	if [[ $master = yes ]]; then
4231fceb383Ssemery		printf "\n$ADMIN_PRINC@$REALM\t\tacmil\n" 1>&3
4241fceb383Ssemery		printf "\nkiprop/*@$REALM\t\tp\n" 1>&3
4251fceb383Ssemery	else
4261fceb383Ssemery		printf "\n*/admin@___default_realm___\t\t*\n" 1>&3
4271fceb383Ssemery	fi
4281fceb383Ssemery}
4291fceb383Ssemery
4301fceb383Ssemeryfunction setup_kpropdacl {
4311fceb383Ssemery
4321fceb383Ssemery	printf "\n$(gettext "Setting up %s").\n\n" $KPROPACL
4331fceb383Ssemery
4341fceb383Ssemery	if [[ -r $KPROPACL ]]; then
4351fceb383Ssemery		cat $KPROPACL > $KPROPACL.sav
4361fceb383Ssemery		cannot_create $KPROPACL.sav $?
4371fceb383Ssemery	fi
4381fceb383Ssemery
4391fceb383Ssemery	exec 3>$KPROPACL
4401fceb383Ssemery	if [[ $? -ne 0 ]]; then
4411fceb383Ssemery		printf "\n$(gettext "Cannot write to %s, exiting").\n" $KPROPACL
4421fceb383Ssemery		error_message
4431fceb383Ssemery	fi
4441fceb383Ssemery	printf "\nhost/$master_hn@$REALM\n" 1>&3
4451fceb383Ssemery}
4461fceb383Ssemery
4471fceb383Ssemeryfunction setup_master {
4481fceb383Ssemery
4491fceb383Ssemery	# create principal DB (KDB)
4501fceb383Ssemery	if [[ -z $PWFILE ]]; then
4511fceb383Ssemery		echo
4521fceb383Ssemery		kdb5_util create
4531fceb383Ssemery		check_ret $? kdb5_util
4541fceb383Ssemery	else
4551fceb383Ssemery		cat $PWFILE $PWFILE | kdb5_util create > /dev/null
4561fceb383Ssemery		check_ret $? kdb5_util
4571fceb383Ssemery	fi
4581fceb383Ssemery
4591fceb383Ssemery	setup_mkeytab
4601fceb383Ssemery	setup_kadm5acl
4611fceb383Ssemery
4621fceb383Ssemery	$SVCADM enable -r -s krb5kdc
4631fceb383Ssemery	$SVCADM enable -r -s kadmin
4641fceb383Ssemery}
4651fceb383Ssemery
4661fceb383Ssemeryfunction setup_slave {
4671fceb383Ssemery
4681fceb383Ssemery	integer count=1
4691fceb383Ssemery
4701fceb383Ssemery	setup_skeytab
4711fceb383Ssemery
4721fceb383Ssemery	# Clear the kadm5acl, since the start methods look at this file
4731fceb383Ssemery	# to see if the server has been configured as a master server
4741fceb383Ssemery	setup_kadm5acl
4751fceb383Ssemery
4761fceb383Ssemery	setup_kpropdacl
4771fceb383Ssemery
4781fceb383Ssemery	$SVCADM enable -r -s krb5_prop
4791fceb383Ssemery
4801fceb383Ssemery	# Wait for full propagation of the database, in some environments
4811fceb383Ssemery	# this could take a few seconds
4821fceb383Ssemery	while [[ ! -f /var/krb5/principal ]]; do
4831fceb383Ssemery		if [[ count -gt $LOOPCNT ]]; then
4841fceb383Ssemery			printf "\n$(gettext "Could not receive updates from the master").\n"
4851fceb383Ssemery                        error_message
4861fceb383Ssemery			((count = count + 1))
4871fceb383Ssemery		fi
4881fceb383Ssemery		printf "$(gettext "Waiting for database from master")...\n"
4891fceb383Ssemery		sleep $SLEEPTIME
4901fceb383Ssemery	done
4911fceb383Ssemery
4921fceb383Ssemery	# The database is propagated now we need to create the stash file
4931fceb383Ssemery	if [[ -z $PWFILE ]]; then
4941fceb383Ssemery		kdb5_util stash
4951fceb383Ssemery		check_ret $? kdb5_util
4961fceb383Ssemery	else
4971fceb383Ssemery		cat $PWFILE | kdb5_util stash > /dev/null 2>&1
4981fceb383Ssemery		check_ret $? kdb5_util
4991fceb383Ssemery	fi
5001fceb383Ssemery
5011fceb383Ssemery	$SVCADM enable -r -s krb5kdc
5021fceb383Ssemery}
5031fceb383Ssemery
504*b793cf1fSShawn Emeryfunction kdb5_destroy {
505*b793cf1fSShawn Emery	typeset status=0
506*b793cf1fSShawn Emery	typeset arg=
507*b793cf1fSShawn Emery
508*b793cf1fSShawn Emery	[[ -n $REALM ]] && arg="-r $REALM"
509*b793cf1fSShawn Emery	printf "$(gettext "yes")\n" | kdb5_util $arg destroy > /dev/null 2>&1
510*b793cf1fSShawn Emery
511*b793cf1fSShawn Emery	status=$?
512*b793cf1fSShawn Emery	[[ $status -eq 0 ]] && return $status
513*b793cf1fSShawn Emery
514*b793cf1fSShawn Emery	# Could mean that the admin could have already removed part of the
515*b793cf1fSShawn Emery	# configuration.  Better to check to see if anything else should be
516*b793cf1fSShawn Emery	# destroyed.  We check by looking at any other stash files in /var/krb5
517*b793cf1fSShawn Emery	stashfiles=`ls $STASH`
518*b793cf1fSShawn Emery	for stash in $stashfiles
519*b793cf1fSShawn Emery	do
520*b793cf1fSShawn Emery		realm=${stash#*.k5.}
521*b793cf1fSShawn Emery		[[ -z $realm ]] && continue
522*b793cf1fSShawn Emery
523*b793cf1fSShawn Emery		printf "$(gettext "Found non-default realm: %s")\n" $realm
524*b793cf1fSShawn Emery		query "$(gettext "Do you wish to destroy realm"): $realm ?"
525*b793cf1fSShawn Emery		if [[ $answer == yes ]]; then
526*b793cf1fSShawn Emery			printf "$(gettext "yes")\n" | kdb5_util -r $realm destroy > /dev/null 2>&1
527*b793cf1fSShawn Emery			status=$?
528*b793cf1fSShawn Emery			if [[ $status -ne 0 ]]; then
529*b793cf1fSShawn Emery				printf "$(gettext "Could not destroy realm: %s")\n" $realm
530*b793cf1fSShawn Emery				return $status
531*b793cf1fSShawn Emery			fi
532*b793cf1fSShawn Emery		else
533*b793cf1fSShawn Emery			printf "$(gettext "%s will not be destroyed").\n" $realm
534*b793cf1fSShawn Emery			status=0
535*b793cf1fSShawn Emery		fi
536*b793cf1fSShawn Emery	done
537*b793cf1fSShawn Emery
538*b793cf1fSShawn Emery	return $status
539*b793cf1fSShawn Emery}
540*b793cf1fSShawn Emery
5411fceb383Ssemeryfunction destroy_kdc {
542*b793cf1fSShawn Emery	typeset status
5431fceb383Ssemery
5441fceb383Ssemery	# Check first to see if this is an existing KDC or server
545159d09a2SMark Phalan	if [[ -f $KRB5KT || -f $PRINCDB || -f $OLDPRINCDB ]]
5461fceb383Ssemery	then
5471fceb383Ssemery		if [[ -z $PWFILE ]]; then
5481fceb383Ssemery			printf "\n$(gettext "Some of the following files are present on this system"):\n"
549159d09a2SMark Phalan			echo "\t$KRB5KT\n\t$PRINCDB\n\t$OLDPRINCDB\n\t$STASH\n"
5501fceb383Ssemery			if [[ -z $d_option ]]; then
5511fceb383Ssemery				printf "$(gettext "You must first run 'kdcmgr destroy' to remove all of these files before creating a KDC server").\n\n"
55267c90040Ssemery				cleanup 1
5531fceb383Ssemery			else
5541fceb383Ssemery				ok_to_proceed "$(gettext "All of these files will be removed, okay to proceed?")"
5551fceb383Ssemery			fi
5561fceb383Ssemery		fi
5571fceb383Ssemery	else
5581fceb383Ssemery		if [[ -n $d_option ]]; then
5591fceb383Ssemery			printf "\n$(gettext "No KDC related files exist, exiting").\n\n"
56067c90040Ssemery			cleanup 0
5611fceb383Ssemery		fi
5621fceb383Ssemery		return
5631fceb383Ssemery	fi
5641fceb383Ssemery
565*b793cf1fSShawn Emery	kdb5_destroy
566*b793cf1fSShawn Emery	status=$?
567*b793cf1fSShawn Emery
568159d09a2SMark Phalan	rm -f $KRB5KT
569*b793cf1fSShawn Emery
570*b793cf1fSShawn Emery	[[ $status -ne 0 ]] && cleanup 1
5711fceb383Ssemery}
5721fceb383Ssemery
5731fceb383Ssemeryfunction kadm5_acl_configed {
5741fceb383Ssemery
5751fceb383Ssemery	if [[ -s $KADM5ACL ]]; then
5761fceb383Ssemery		grep -v '^[    ]*#' $KADM5ACL | \
5771fceb383Ssemery			egrep '_default_realm_' > /dev/null 2>&1
5781fceb383Ssemery		if [[ $? -gt 0 ]]; then
5791fceb383Ssemery			return 0
5801fceb383Ssemery		fi
5811fceb383Ssemery	fi
5821fceb383Ssemery
5831fceb383Ssemery	return 1
5841fceb383Ssemery}
5851fceb383Ssemery
5861fceb383Ssemeryfunction status_kdc {
5871fceb383Ssemery
5881fceb383Ssemery	integer is_master=0
5891fceb383Ssemery
5901fceb383Ssemery	printf "\n$(gettext "KDC Status Information")\n"
5911fceb383Ssemery	echo "--------------------------------------------"
5921fceb383Ssemery	svcs -xv svc:/network/security/krb5kdc:default
5931fceb383Ssemery
5941fceb383Ssemery	if kadm5_acl_configed; then
5951fceb383Ssemery		is_master=1
5961fceb383Ssemery		printf "\n$(gettext "KDC Master Status Information")\n"
5971fceb383Ssemery		echo "--------------------------------------------"
5981fceb383Ssemery		svcs -xv svc:/network/security/kadmin:default
5991fceb383Ssemery	else
6001fceb383Ssemery		printf "\n$(gettext "KDC Slave Status Information")\n"
6011fceb383Ssemery		echo "--------------------------------------------"
6021fceb383Ssemery		svcs -xv svc:/network/security/krb5_prop:default
6031fceb383Ssemery	fi
6041fceb383Ssemery
6051fceb383Ssemery	printf "\n$(gettext "Transaction Log Information")\n"
6061fceb383Ssemery	echo "--------------------------------------------"
6071fceb383Ssemery	/usr/sbin/kproplog -h
6081fceb383Ssemery
6091fceb383Ssemery	printf "$(gettext "Kerberos Related File Information")\n"
6101fceb383Ssemery	echo "--------------------------------------------"
6111fceb383Ssemery	printf "$(gettext "(will display any missing files below)")\n"
6121fceb383Ssemery	FILELIST="$KRB5_KDC_CONF $KRB5_KRB_CONF $KADM5ACL $KRB5KT $PRINCDB "
6131fceb383Ssemery	for file in $FILELIST; do
6141fceb383Ssemery		if [[ ! -s $file ]]; then
6151fceb383Ssemery			printf "$(gettext "%s not found").\n" $file
6161fceb383Ssemery		fi
6171fceb383Ssemery	done
6181fceb383Ssemery	if [[ $is_master -eq 0 && ! -s $KPROPACL ]]; then
6191fceb383Ssemery		printf "$(gettext "%s not found").\n" $KPROPACL
6201fceb383Ssemery	fi
621159d09a2SMark Phalan
6221fceb383Ssemery	test ! -s $STASH &&
6231fceb383Ssemery	    printf "$(gettext "Stash file not found") (/var/krb5/.k5.*).\n"
6241fceb383Ssemery	echo
6251fceb383Ssemery
62667c90040Ssemery	cleanup 0
6271fceb383Ssemery}
6281fceb383Ssemery
6291fceb383Ssemery# Start of Main script
6301fceb383Ssemery
631*b793cf1fSShawn Emerytypeset -u REALM
632*b793cf1fSShawn Emerytypeset -l host
633*b793cf1fSShawn Emerytypeset -l fqhn
634*b793cf1fSShawn Emery
6351fceb383Ssemery# Defaults
6361fceb383SsemeryKRB5_KDC_CONF=/etc/krb5/kdc.conf
6371fceb383SsemeryKRB5_KRB_CONF=/etc/krb5/krb5.conf
6381fceb383SsemeryKADM5ACL=/etc/krb5/kadm5.acl
6391fceb383SsemeryKPROPACL=/etc/krb5/kpropd.acl
6401fceb383Ssemery
6411fceb383SsemeryKRB5KT=/etc/krb5/krb5.keytab
6421fceb383SsemeryPRINCDB=/var/krb5/principal
6431fceb383SsemeryOLDPRINCDB=/var/krb5/principal.old
6441fceb383SsemerySTASH=/var/krb5/.k5.*
6451fceb383Ssemery
6461fceb383SsemeryKADMINL=/usr/sbin/kadmin.local;	check_bin $KADMINL
6471fceb383SsemeryKADMIN=/usr/sbin/kadmin;	check_bin $KADMIN
6481fceb383SsemeryKDCRES=/usr/lib/krb5/klookup;	check_bin $KDCRES
6491fceb383SsemerySVCADM=/usr/sbin/svcadm;	check_bin $SVCADM
6501fceb383SsemeryPING=/usr/sbin/ping;		check_bin $PING
6511fceb383Ssemery
6521fceb383SsemeryENCTYPE=aes128-cts-hmac-sha1-96
6531fceb383SsemeryLOOPCNT=10
6541fceb383SsemerySLEEPTIME=5
6551fceb383Ssemery
6561fceb383Ssemeryif [[ -x /usr/bin/mktemp ]]; then
6571fceb383Ssemery	TMP_FILE=$(/usr/bin/mktemp /etc/krb5/krb5tmpfile.XXXXXX)
6581fceb383Ssemery	TMP_CCACHE=$(/usr/bin/mktemp /etc/krb5/krb5tmpccache.XXXXXX)
6591fceb383Ssemeryelse
6601fceb383Ssemery	TMP_FILE="/etc/krb5/krb5tmpfile.$$"
6611fceb383Ssemery	TMP_CCACHE="/etc/krb5/krb5tmpccache.$$"
6621fceb383Ssemeryfi
6631fceb383Ssemery
6641fceb383Ssemeryif [[ ! -f /etc/resolv.conf ]]; then
6651fceb383Ssemery	printf "$(gettext "Error: need to configure /etc/resolv.conf").\n"
6661fceb383Ssemery
66767c90040Ssemery	cleanup 1
6681fceb383Ssemeryfi
6691fceb383Ssemery
6701fceb383Ssemeryfqhn=`$KDCRES`
6711fceb383Ssemeryif [[ -n "$fqhn" ]]; then
6721fceb383Ssemery	:
6731fceb383Ssemeryelif [[ -n $(hostname) && -n $(domainname) ]]; then
674*b793cf1fSShawn Emery	fqhn=$(hostname|cut -f1 -d'.').$(domainname|cut -f2- -d'.')
6751fceb383Ssemeryelse
6761fceb383Ssemery	printf "$(gettext "Error: can not determine full hostname (FQHN).  Aborting")\n"
6771fceb383Ssemery	printf "$(gettext "Note, trying to use hostname and domainname to get FQHN").\n"
67867c90040Ssemery
67967c90040Ssemery	cleanup 1
6801fceb383Ssemeryfi
6811fceb383Ssemery
6821fceb383Ssemeryping_check $fqhn
6831fceb383Ssemery
6841fceb383Ssemerydomain=${fqhn#*.} # remove host part
6851fceb383Ssemery
6861fceb383Ssemeryexitmsg=`printf "$(gettext "Exiting...")"`
6871fceb383Ssemery
6881fceb383Ssemerytrap "echo $exitmsg; rm -f $TMP_FILE $TMP_CCACHE; exit 1" HUP INT QUIT TERM
6891fceb383Ssemery
6901fceb383Ssemerywhile getopts :a:e:hp:r:s flag
6911fceb383Ssemerydo
6921fceb383Ssemery	case "$flag" in
6931fceb383Ssemery		a)	ADMIN_PRINC=$OPTARG;;
6941fceb383Ssemery		e)	ENCTYPE=$OPTARG;;
6951fceb383Ssemery		h)	usage;;
6961fceb383Ssemery		p)	PWFILE=$OPTARG
6971fceb383Ssemery			if [[ ! -r $PWFILE ]]; then
6981fceb383Ssemery				printf "\n$(gettext "Password file %s does not exist, exiting").\n\n" $PWFILE
69967c90040Ssemery				cleanup 1
7001fceb383Ssemery			fi
7011fceb383Ssemery			;;
7021fceb383Ssemery		r)	REALM=$OPTARG;;
7031fceb383Ssemery		*)	usage;;
7041fceb383Ssemery	esac
7051fceb383Ssemerydone
7061fceb383Ssemeryshift $(($OPTIND - 1))
7071fceb383Ssemery
7081fceb383Ssemerycase "$*" in
7091fceb383Ssemery	create)			master=yes;;
7101fceb383Ssemery	"create master")	master=yes;;
7111fceb383Ssemery	"create -m "*)		host=$3
7121fceb383Ssemery				checkval="MASTER"; check_value $host
7131fceb383Ssemery				check_host
7141fceb383Ssemery				master_hn=$host
7151fceb383Ssemery				if [[ $4 != slave ]]; then
7161fceb383Ssemery					usage
7171fceb383Ssemery				fi;&
7181fceb383Ssemery	"create slave")		slave=yes;;
7191fceb383Ssemery	destroy)		d_option=yes
7201fceb383Ssemery				kill_daemons
72147fc6f3cSsemery				destroy_kdc
72247fc6f3cSsemery				cleanup 0;;
7231fceb383Ssemery	status)			status_kdc;;
7241fceb383Ssemery	*)			usage;;
7251fceb383Ssemeryesac
7261fceb383Ssemery
7271fceb383Ssemerykill_daemons
7281fceb383Ssemery
7291fceb383Ssemeryprintf "\n$(gettext "Starting server setup")\n"
7301fceb383Ssemeryprintf "---------------------------------------------------\n"
7311fceb383Ssemery
7321fceb383Ssemery# Checks for existing kdb and destroys if desired
7331fceb383Ssemerydestroy_kdc
7341fceb383Ssemery
7351fceb383Ssemeryif [[ -z $REALM ]]; then
7361fceb383Ssemery	printf "$(gettext "Enter the Kerberos realm"): \c"
7371fceb383Ssemery	read REALM
7381fceb383Ssemery	checkval="REALM"; check_value $REALM
7391fceb383Ssemeryfi
7401fceb383Ssemery
7411fceb383Ssemeryif [[ -z $master && -z $slave ]]; then
7421fceb383Ssemery	query "$(gettext "Is this machine to be configured as a master?"): \c"
7431fceb383Ssemery	master=$answer
7441fceb383Ssemery
7451fceb383Ssemery	if [[ $answer = no ]]; then
7461fceb383Ssemery		query "$(gettext "Is this machine to be configured as a slave?"): \c"
7471fceb383Ssemery		slave=$answer
7481fceb383Ssemery		if [[ $answer = no ]]; then
7491fceb383Ssemery			printf "\n$(gettext "Machine must either be a master or a slave KDC server").\n"
7501fceb383Ssemery			error_message
7511fceb383Ssemery		fi
7521fceb383Ssemery	fi
7531fceb383Ssemeryfi
7541fceb383Ssemery
7551fceb383Ssemeryif [[ $slave = yes && -z $master_hn ]]; then
7561fceb383Ssemery	printf "$(gettext "What is the master KDC's host name?"): \c"
7571fceb383Ssemery	read host
7581fceb383Ssemery	checkval="MASTER"; check_value $host
7591fceb383Ssemery	check_host
7601fceb383Ssemery	master_hn=$host
7611fceb383Ssemeryfi
7621fceb383Ssemery
7631fceb383Ssemerysetup_kdc_conf
7641fceb383Ssemery
7651fceb383Ssemerysetup_krb_conf
7661fceb383Ssemery
7671fceb383Ssemeryif [[ $master = yes ]]; then
7681fceb383Ssemery	setup_master
7691fceb383Ssemeryelse
7701fceb383Ssemery	setup_slave
7711fceb383Ssemeryfi
7721fceb383Ssemery
7731fceb383Ssemeryprintf "\n---------------------------------------------------\n"
7741fceb383Ssemeryprintf "$(gettext "Setup COMPLETE").\n\n"
7751fceb383Ssemery
77667c90040Ssemerycleanup 0
777