#!/bin/bash

USAGE="kinit-from-file <password-file> [all other kinit options]"

# STEP 1. Get the path to the password file.
# The first argument must be a valid filepath.
FILEPATH=$1
if [[ -z "$FILEPATH" ]]; then
   echo "${USAGE}"
   exit 10
fi

if [[ ! -e "$FILEPATH" ]]; then
   echo "cannot find password file '${FILEPATH}'"
   exit 11
fi

# Step 2. Get all the arguments EXCEPT for the first one.
REMAINING_ARGS="${@:2}"

# Step 3. Get the password from the password file
PASSWORD=$(head -n 1 $FILEPATH)

# Step 4. Do the kinit using expect. Make sure to
# wait for the exit code.
expect <<EOX
log_user 0
spawn sh -c {kinit $REMAINING_ARGS}
expect -re "Password.*:" {
  send -- "$PASSWORD\r"
}

expect eof { set results \$expect_out(buffer) }

if {[regexp {[^[:space:]]} \$results]} {
   puts stderr [string trim "\$results"]
}

lassign [wait] pid spawnid os_error_flag value

exit \$value
EOX

EXIT_VALUE=$?

# Step 5. Return the exit value
exit $EXIT_VALUE

########################################################################
########################################################################

# Documentation.  Use a hack to hide this from the shell.  Because of the
# above exit line, this should never be executed.
DOCS=<<__END_OF_DOCS__

=head1 NAME

kinit-from-file - Run a kinit but get password from a file

=head1 SYNOPSIS

B<kinit-from-file> /path/to/file <other options and arguments>

=head1 DESCRIPTION

This is a wrapper around B<kinit>. It takes the first line of the file specified by
the C</path/to/file> and uses that as the password. All other options
are passed through to B<kinit>.

=head1 Example

Here is an example:

    % echo 'secret' /root/mypassword
    % kinit-from-file /root/mypassword -c /tmp/kerbcache adamhl

The above runs the command C<kinit -c /tmp/kerbcache adamhl> but supplies the password
C<secret> to B<kinit> using Expect.

=head1 AUTHOR

Adam Lewenberg <adamhl@stanford.edu>

=head1 SEE ALSO

kadmin(1)

=cut

__END_OF_DOCS__
