#!/bin/bash
# net/k5 - Kerberos 5 helper

set -e

source "/home/zwelch/src/mcf/mcsh/install/share/mcsh/mcsh.sh"


######
# Native dependencies

k5_client_packages=(
		krb5-user
		sasl2-bin
		libsasl2-2
		libsasl2-modules
		libsasl2-modules-gssapi-mit
	)


######
# Configuration

k5_config_init() {
	script_setting_vars kdc_host kdc_server admin_host admin_server

	script_setting_vars -ro KADMIN KTUTIL KRB5_CONF KRB5_KEYTAB KEYTAB_DIR

	KADMIN="kadmin.local"
	KTUTIL="ktutil"

	KRB5_CONF="/etc/krb5.conf"
	KRB5_KEYTAB="/etc/krb5.keytab"
	KEYTAB_DIR="/etc/krb5.keytab.d"
}

k5_config_check() {
	kdc_server=$(server_name "$kdc_host")
	admin_server=$(server_name "$admin_host")
}


######
# Kerberos 5 utility wrappers

run_ktutil() { run $KTUTIL -p "$USER"; }
run_kadmin() { run_sudo $KADMIN -p "$K5_USER" -q "$*"; }


######
# service management

k5_srv_usage() {
	cat <<EOF
<cmd> ...
Service Commands:
	add <name>
EOF
}
k5_srv_add() {
	has_args 1 "$@"
	run_kadmin addprinc -randkey $1;
}

k5_srv() { cmd_dispatch "$@"; }


######
# principle management

k5_pr_usage() {
	cat <<EOF
<cmd> [...]
Principle Commands:
	add <name>
	delete|rm <name>
	list|ls
EOF
}

k5_pr_add() {
	has_args 1 "$@"
	run_kadmin addprinc $1
}

k5_pr_delete() {
	has_args 1 "$@"
	run_kadmin delprinc $1
}
k5_pr_rm() { k5_pr_delete "$@"; }

k5_pr_list() {
	has_args 0 "$@"
	run_kadmin listprincs
}
k5_pr_ls() { k5_pr_list "$@"; }

k5_pr() { cmd_dispatch "$@"; }


######
# keytab management

k5_kt_usage() {
	cat <<EOF
<cmd> [...]
Key Table File Commands:
	add <keytab> <name>+
	del <keytab> <name>+
	list|ls [<keytab>+]
	keys
	gen <keytab> < <keylist>
	hosts [...]
EOF
}

kt_host_keys() { echo $KEYTAB_DIR/$1.keys; }
kt_host_keytab() { echo $KEYTAB_DIR/$1.keytab; }

k5_kt_new() {
	has_args 2 "$@"
	run_kadmin ktadd -k $1 $2
}
k5_kt_add() { file_test -f "$1"; k5_kt_new "$@"; }
k5_kt_del() {
	has_args 2 "$@"
	file_test -f "$1"
	run_kadmin ktremove -k $1 $2
}

k5_kt_ls() {
	local -a files
	if [ "$*" ]; then
		files=( "$@" )
	else
		files=( "/etc/krb5.keytab" )
	fi
	file_test -f "${files[@]}"
	for f in "${files[@]}"; do
		info "$f:"
		run_ktutil <<EOF
rkt $f
l
q
EOF
	done | egrep -v 'ktutil:  [ql]' |sed -e 's,^ktutil:  rkt ,\n,'
}

k5_kt_keys() {
	has_args 0 "$@"
	for f in $KEYTAB_DIR/*.keys; do
		echo "$f:"
		cat $f
	done
}

k5_kt_gen() {
	has_args 1 "$@"
	local out=$1
	run rm -vf "$out"
	while read p; do
		run k5_kt_new "$out" "$p"
	done
}

######
# Host keytab generation

kt_hosts_make() {
	has_args 1 "$@"
	run_sudo test -f $KEYTAB_DIR/Makefile || k5_kt_hosts_init
	run_sudo make --silent -C $KEYTAB_DIR $1;
}


k5_kt_hosts() { cmd_dispatch "$@"; }
k5_kt_hosts_usage() {
	cat <<EOF
<cmd> ...
Keytab Generation Commands:
	init				Initialize the keytab directory
	keys				Prints the host key file names
	build				Builds keytabs from key lists
	print				Print contents of keytabs
	clean				Removes the generated keytabs
EOF
}

k5_kt_hosts_all()     { has_args 0 "$@"; kt_hosts_make all; }
k5_kt_hosts_keys()    { has_args 0 "$@"; kt_hosts_make keys; }
k5_kt_hosts_print()   { has_args 0 "$@"; kt_hosts_make print; }
k5_kt_hosts_clean()   { has_args 0 "$@"; kt_hosts_make clean; }

k5_kt_hosts_init() {
	local makefile
	makefile=$(cmd_tempfile)
	cat >$makefile <<'EOF'
KEYS := $(wildcard *.keys)
KEYTABS = $(patsubst %.keys,%.keytab,$(KEYS))

all: $(KEYTABS)

keys:
	echo $(KEYS)

print: $(KEYTABS)
	k5 kt ls "$*"

clean:
	rm -f $(KEYTABS)
	rm Makefile

%.keytab: %.keys
	k5 kt gen "$@" < "$<"
EOF
	run_sudo mkdir -p $KEYTAB_DIR
	run_sudo mv $makefile $KEYTAB_DIR/Makefile
	run_sudo chown root:root $KEYTAB_DIR/Makefile
	run_sudo chmod 0600 $KEYTAB_DIR/Makefile
}


k5_kt() { cmd_dispatch "$@"; }

######
# Host management

is_admin_host() {
	has_args 1 "$@"
	[ "$1" = "$admin_host" -o "$1" = "$admin_server" ]
}

require_admin_host() {
	is_admin_host "$host" || error "must be run on admin host"
}

k5_host_new() {
	has_args 1 "$@"
	local fqdn=$1
	local host=${fqdn%%.*}
	local name="host/$fqdn"
	local keys
	keys=$(kt_host_keys $host)

	run k5_srv_add "$name"
	if [ ! -f "$keys" ]; then
		info "creating $keys..."
		echo $name | sudo_pipe_to_file "$keys"
	fi
}
k5_host_delete() {
	has_args 1 "$@"
	local fqdn=$1
	local host=${fqdn%%.*}
	local name="host/$fqdn"
	local keys
	keys=$(kt_host_keys $host)

	sudo rm -if $keys
	k5_pr_delete "host/$1"
}
k5_host_rm() { host_delete "$@"; }

k5_host_config() {
	has_args 1 "$@"
	remote_deploy_file $1 $KRB5_CONF $KRB5_CONF
}
k5_host_keytab() {
	has_args 1 "$@"
	remote_deploy_file $1 $(kt_host_keytab $1) $KRB5_KEYTAB
}

k5_host_list() {
	run_sudo sh -c "ls $(kt_host_keys "*")" | xargs -n1 basename -s .keys
}
k5_host_ls() { k5_host_list "$@"; }

k5_host_init() {
	require_admin_host
	has_args 1 "$@"
	local host=$1
	if [ "$host" = "all" ]; then
		for h in $(host_list); do
			k5_host_init $h
		done
		return
	fi

	remote_pkg_install $host "${k5_client_packages[@]}"

	if [ -z "$(ssh_host_for_host $host)" ]; then
		info "$host: skipped"
		return
	fi

	info "$host: updating..."
	k5_host_config $host
	k5_host_keytab $host
	info "$host: ... done"
}

k5_host_keys() {
	has_args 1 "$@"
	local keys
	keys=$(kt_host_keys $1)
	run_sudo cat $keys
}

k5_host_edit() {
	has_args 1 "$@"
	local host=$1
	local keys
	keys=$(kt_host_keys $host)
	run_editor $keys
}

k5_host() { cmd_dispatch "$@"; }
k5_host_usage() {
	cat <<EOF
<cmd> [...]
General Host Commands:
	list			Print the list of krb5 hosts.
	new <hostname>		Create a new krb5 host.
	init [<hostname>]	Copy remote krb5 configuration to host(s).

Host Key Lists:
	keys <hostname>		Print the list of host keys
	edit <hostname>		Edit the list of host keys.
EOF
}


######
# admin commands

k5_admin_init() {
	require_admin_host
	has_args 0 "$@"

	# generate host keytabs
	k5_kt_hosts_gen
	# setup a link to this host's keytab
	run rm -f $KRB5_KEYTAB

	local host_keytab
	host_keytab=$(kt_host_keytab $host)
	run ln -s $host_keytab $KRB5_KEYTAB

	# initialize hosts
	for h in "$@"; do
		k5_host_init "$host"
	done
}

k5_admin_run() {
	run_kadmin "$@"
}


######
# Check

k5_check() {
	if $intense; then
		k5_pr_list
		k5_kt_hosts
		k5_host_list
	else
		app_help
	fi
}


######
# Main

k5_desc() {
	echo "Kerberos 5 management tool"
}

k5_usage() {
	cat <<USAGE
<cmd> [...]
Main Commands:
	pr <cmd> [...]		- Manage principles.
	srv <cmd> [...]		- Manage services.
	kt <cmd> [...]		- Manage key table files.
	host <cmd> [...]	- Manage remote hosts.
	admin <cmd> [...]	- Manage admin server.
USAGE
}

k5_help() {
	cat<<HELP
The $script_name tool automates Kerberos 5 server management, including
installation, configuration, creation and updates, and host setup.
HELP
}

app_run "$@"

View the Script Reference Index


Generated on Tue Apr 25 21:19:43 PDT 2017 by mcsh i7 v0.18.0.