Take the 2-minute tour ×
Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, no registration required.

Per the following, I'm trying to obfuscate a password within a script

Hide/encrypt password in bash file to stop accidentally seeing it

However, because this password has non-alpha numeric characters in it, I don't think the variable "$MYPASS" echoing out properly in the second to last line of the script

My script:

#!/bin/bash
PATH=/bin:/usr/bin:/sbin:/usr/sbin export PATH
MYENCPASS='IURv34bmNocv98RnZXQhCg=='
MYPASS=`echo "$MYENCPASS" | base64 --decode`

echo
echo Enter username you\'d like to change password for:
read USERNAME
dscl /LDAPv3/127.0.0.1 -read /Users/$USERNAME >/dev/null 2>&1

if [ "$?" != "0" ]; then

echo
echo -e "\033[31m Username $USERNAME does not exist! Exiting..."
echo -e "\033[0m"
exit 1
fi

echo
echo Enter New Password for "$USERNAME"
read PASSWORD
dscl -u diradmin -P "$MYPASS" /LDAPv3/127.0.0.1 passwd /Users/$USERNAME $PASSWORD
echo Password successfully changed for $USERNAME to $PASSWORD at `date` | tee -a /var/log/odpasswd.log

Your ideas/suggestions are most appreciated!

Thanks, Dan

share|improve this question
add comment

1 Answer

up vote 3 down vote accepted

First, you need to quote your parameter to echo to avoid string-splitting and glob expansion:

echo "Password successfully changed for $USERNAME to $PASSWORD at `date`"

Second, if you want to emit the password in a machine-parsable form, use printf %q:

printf 'Password successfully changed for %s to %q at %s\n' \
  "$USERNAME" "$PASSWORD" "$(date)"

As an aside -- it's bad practice to use all-uppercase names for local variables (as it risks namespace conflicts with built-in and environment variables).


A complete version of your script, making a stronger attempt to follow best practices around scripting (but still failing horribly to follow any kind of good practices around security), would look something like this:

#!/bin/bash

# you probably don't need to export PATH -- if something is already exported,
# it stays exported on updates.
PATH=/bin:/usr/bin:/sbin:/usr/sbin

## this is really, _really_ horrible "security".
myencpass='IURv34bmNocv98RnZXQhCg=='
mypass=$(base64 --decode <<<"$myencpass")

echo
echo "Enter username you'd like to change password for:"
read -r username
if ! dscl /LDAPv3/127.0.0.1 -read "/Users/$username" &>/dev/null; then
  # This is bad practice -- assuming that the only error that can happen is
  # the nonexistent-user case, and hiding any other error messages, means that
  # the user can't diagnose the _actual_ cause of any other error.
  printf '\n\033[31m Username %s does not exist! Exiting...\033[0m\n' "$username"
  exit 1
fi

printf '\nEnter New Password for %s\n' "$username"
read -r password
if dscl -u diradmin -P "$mypass" /LDAPv3/127.0.0.1 passwd "/Users/$username" "$password"; then
  # previously, there was no conditional here, so we logged that this was
  # successful even if it failed.
  # And, of course, storing users' plaintext passwords in a log makes you evil.
  printf "Password successfully changed for %s to %q at %s\n" \
    "$username" "$password" "$(date)" \
    | tee -a /var/log/odpasswd.log
fi

If you wanted to actually do this The Right Way, instead of trying this kind of obfuscation technique you'd authenticate to LDAP with, say, a cached Kerberos ticket (I'm assuming this is MacOS's Open Directory -- it can do that), readable only by the user the script runs as, and use sudo to allow temporary privilege escalation to the user who can read the ticket only when running this script.

share|improve this answer
    
Hi Charles, I appreciate the comments and suggestions -- as well as the solution -- but this script is for one administrative person and no one else, so yes it's not the Right Way, but it'll work just fine, especially behind a firewall. I'd love to know how to do the Kerberized method, too, if you feel inspired! Cheers, Dan –  Dan Jul 13 '13 at 19:28
    
Charles, alas your script works perfectly except that it does not echo the date/time from the %s. Ideas how to fix that? –  Dan Jul 13 '13 at 19:34
    
@Doug Oops -- left out the date call. Edited to add that. As for the Kerberized approach -- it's been long enough since I've done that that it would take some research to dig it back up. Perhaps you might ask about it as a separate question? (Even if you don't, it would do some good to put the obfuscated password in a file with limited permissions, and require users of this script to jump through sudo to read it; if you control the permissions sudo grants, you can let them run the script but not let them see the file it reads). –  Charles Duffy Jul 13 '13 at 19:39
    
Charles, thanks for the date fix and excellent suggestion about using a separate password file, I know how to tackle that. Much appreciated! –  Dan Jul 13 '13 at 19:53
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.