So something I find that I need to do quite often is to log in as a specific user, and I don’t always want to reset their password.
While AFP has a really useful function where you can allow admins of an AFP server to masquerade as a specific user by using the admin password, no other services really offer that same kind of functionality.
What I tend to do in these situations is to swap the Authentication Authority around. I keep a test user account around that I know the password to, and I swap its Authentication Authority with the user I need to login as.
As the Authentication Authority describes which Password Server slot contains the password for a given user, by swapping them around you are effectively swapping the passwords. If you’re in a nice Kerberized environment (and if you’re not, you should be…) then you’ll notice that this doesn’t actually swap the Kerberos passwords around. This is because in a standard Open Directory setup, there are actually two password stores, one for Password Server and one for Kerberos. Apple have done some nifty stuff behind the scenes to keep the two in sync when users change their passwords, but by swapping Authentication Authorities around, you’re not modifying the Kerberos passwords at all.
Anyway, here’s the script I use to swap authentication authorities around. I tend to save it as something like “swap_auth_authorities.sh”, and then you’d use it like:
./swap_auth_authorities.sh -n /LDAPv3/my.od.domain -a diradmin -p diradminpass testone testtwo
which would swap the Authentication Authorities for the users “testone” and “testtwo”.
As always, don’t blame me if you blow up your server, and you should definitely try this on test accounts first…. You can use the command “/usr/libexec/chkpasswd testone” to test the passwords for each user. If you get “Sorry” back, the password is wrong, if you get nothing back, the password is correct.
Love that famed Apple user friendliness :)
Script follows, or you can download it here:
#!/bin/bash
#
directorynode="/LDAPv3/127.0.0.1"
adminusername="diradmin"
export PATH="/usr/bin"
show_usage() {
echo "This script will swap the authentication authorities of two users in a directory node."
echo usage: swap_auth_authorities [-h] [-n directorynode] [-a adminusername] [-p adminpassword] username1 username2 ...
echo
echo "-h help (this output)"
echo "-n directory node name (default: /LDAPv3/127.0.0.1)"
echo "-a directory admin username (default: diradmin)"
echo "-p directory admin password"
echo "username1 and username2 are the users you wish to swap authentication authorities for"
echo
echo "Note: If the admin password is not specified, you will be prompted for it a number of times."
}
show_password_prompt() {
if [ ${#adminpassword} -eq 0 ]; then
echo "Enter the password for $adminusername"
fi
}
while getopts "hn:a:p:" flag; do
# echo "$flag" $OPTIND $OPTARG
case "$flag" in
h) show_usage; exit ;;
n) directorynode="$OPTARG" ;;
a) adminusername="$OPTARG" ;;
p) adminpassword="$OPTARG" ;;
?) echo >&2 "Illegal option '$OPTARG'"; exit 1 ;;
esac
done
shift $(($OPTIND -1 ))
if [ $# -ne 2 ]; then
echo >&2 "Error: You should only pass two additional parameters, the usernames whose authentication authorities are to be swapped"
echo
show_usage
exit 1
fi
if [ ${#adminpassword} -eq 0 ]; then
authstring="-u $adminusername -p"
echo "You will now be prompted several times for the password for $adminusername"
else
authstring="-u $adminusername -P $adminpassword"
fi
show_password_prompt
authority1=$(dscl $authstring $directorynode -read /Users/$1 AuthenticationAuthority | sed 's|^AuthenticationAuthority: ||g')
# check to see if users exist or permission denied.
if [ $? -ne 0 ]; then
case $? in
71 ) echo "User $1 not found in $directorynode"; exit 1 ;;
esac
fi
# dscl really should return an error code in these cases...
if [ $(echo $authority1 | grep -c "Data source ($directorynode) is not valid.") -gt 0 ]; then
echo "There is a problem with either your admin username/password combination, or the specified directory node"
exit 1;
fi
show_password_prompt
authority2=$(dscl $authstring $directorynode -read /Users/$2 AuthenticationAuthority | sed 's|^AuthenticationAuthority: ||g')
# check to see if users exist or permission denied.
if [ $? -ne 0 ]; then
case $? in
71 ) echo "User $2 not found in $directorynode"; exit 1 ;;
esac
fi
show_password_prompt
dscl $authstring $directorynode -create /Users/$1 AuthenticationAuthority "$authority2"
show_password_prompt
dscl $authstring $directorynode -create /Users/$2 AuthenticationAuthority "$authority1"
echo "The authentication authorities for $1 and $2 have been swapped."
echo "Note that Kerberos authentication will continue to use the old passwords."
echo "If you re-run this command, the authentication authorities will be swapped back again."
Testing comments…
This is a test of the emergency broadcast system.
This is only a test.
This concludes the test of the emergency broadcast system.
Yeah – this is one of my favorites! I do somthing very similar…although, I haven’t gotten around to scripting it (I’ve sadly been using WGM and editing the LDAP record directly). Leaves people’s jaw agape when they see it in action, though…two factor authentication can’t become truly mainstream quickly enough.
–
erm
Neat-O! Thanks!
-systemsboy
I don’t even understand the effect you are trying to produce.
Perfect! This comes in handy when I have to set up a vacation reply or forward for a (incapable) user with Avelsieve in Squirrelmail, and I don’t want to know or change their password.