# -*- mode: sh -*- # kdo is a shell function for interacting with multiple Kerberos # credential caches. # # To use kdo, add this snippet to your .bashrc or .bashrc.mine file. # # To run a command with a different set of credentials from your # default, run # # kdo # # e.g., # # kdo broder/root aklog # # If you lack credentials for the specified principal, you'll be # prompted for the password. # # If kdo needs to acquire tickets, it will pass the value of # ${kdo_args[@]} to kinit. I use this to get tickets that last for 15 # minutes, that are renewable for 60 minutes, and aren't forwardable. # # To add kdo support for a new platform, you need to provide an # interface to multiple credential caches by defining two functions: # # - kcaches:: # Print one line per current credential cache of the form " " # - knewcache:: # Without changing the current credentials cache, get credentials # for the principal in $1, passing the remaining arguments to # kinit. # knewcache should set the variable cache with the KRB5CCNAME # value for the newly created credential cache # # Also included is krootssh, a wrapper around ssh for using your # root-instance tickets with ssh. It ensures that your tickets don't # get accidentally forwarded, on the off chance that you have # forwardable tickets. # CONFIGURATION kdo_args=(-l15m -r60m -F) # CC interface for OS X or modern MIT krb5 if type kswitch &>/dev/null; then kcaches () { klist -A | perl -ne '$cache = $1 if /^(?:Kerberos 5 ticket|Ticket|Credentials) cache: '\''?(.*)'\''?/; print "$1 $cache\n" if /^(?:Default p|P)rincipal: (.*)$/' } knewcache () { princ="$1"; shift local oldcache="$(klist | perl -ne 'print $1 if /^(?:Kerberos 5 ticket|Ticket|Credentials) cache: '\''?(.*)'\''?/')" # " # <-- emacs thinks there's an unbalanced " on the previous line. kinit "$@" "$princ" || return 1 cache="$(kfindcache "$princ")" # On OS X, kinit will switch your default credential cache to # that of the newly acquired tickets, so switch back if we can if [ -z "$oldcache" ]; then echo "W: Tickets for $princ are now in your default credential cache" >&2 else kswitch -c "$oldcache" fi } fi # If kcaches and knewcache have been defined for this platform, then # setup kdo. Otherwise, add a helpful error. if type kcaches &>/dev/null && type knewcache &>/dev/null; then kfindcache () { kcaches | fgrep "$1" | cut -d' ' -f2- } kdo () { local princ="$1"; shift local cache="$(kfindcache "$princ")" # If the cache that we want to use has expired tickets, then # destroy that cache so we don't try to use it again and clear # $cache so that we'll revert to acquiring a new set of # tickets if [ -n "$cache" ] && ! (KRB5CCNAME="$cache" klist -s); then KRB5CCNAME="$cache" kdestroy cache="" fi if [ -z "$cache" ]; then knewcache "$princ" "${kdo_args[@]}" || return 1 fi echo "I: Running $1 with cache $cache (for principal $princ)" >&2 KRB5CCNAME="$cache" "$@" } _kdo () { local cur COMPREPLY=() cur="${COMP_WORDS[COMP_CWORD]}" opts="$(kcaches | awk '{ print $1 }')" case $COMP_CWORD in 1) COMPREPLY=($(compgen -W "${opts}" -- "${cur}")) ;; 2) COMPREPLY=($(compgen -c -- "${cur}")) esac } if type complete &>/dev/null; then complete -o bashdefault -F _kdo kdo fi else kdo () { echo "kdo has not been ported to this platform yet." >&2 return 1 } fi krootssh () { kdo ${ATHENA_USER:-$USER}/root@ATHENA.MIT.EDU ssh -o GSSAPIDelegateCredentials=no "$@" } krootscp () { kdo ${ATHENA_USER:-$USER}/root@ATHENA.MIT.EDU scp -o GSSAPIDelegateCredentials=no "$@" }