Во-первых, вам необходимо указать ваш параметр эхо, чтобы избежать строковое расщепление и расширение Глоб:
echo "Password successfully changed for $USERNAME to $PASSWORD at `date`"
Во-вторых, если вы хотите, чтобы испустить пароль в машино- интерпретируемая форма, используйте printf %q
:
printf 'Password successfully changed for %s to %q at %s\n' \
"$USERNAME" "$PASSWORD" "$(date)"
Как и в стороне - это плохая практика, чтобы использовать все прописные имена для локальных переменных (как рисков конфликта имен со встроенным d переменные среды).
Полная версия вашего сценария, делая более сильную попытку следовать передовой практике вокруг сценариев (но еще не удается ужасно следовать какому-либо передовая практика вокруг безопасности), будет выглядеть примерно так:
#!/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
Если вы хотите, чтобы на самом деле сделать это правильный путь, вместо того, чтобы пытаться этот вид техники запутывания вы бы проверить подлинность LDAP, скажем, в кэше билет Kerberos (я предполагаю, что это Open Directory Macos в - он может сделать это t), читаемый только пользователем, выполняемым сценарием, и использует sudo, чтобы разрешить временную эскалацию привилегий для пользователя, который может читать билет только при запуске этого скрипта.
Привет, Чарлз, я ценю комментарии и предложения, а также решение, но этот сценарий предназначен для одного административного человека и никого другого, так что да, это не правильный путь, но он будет работать нормально , особенно за брандмауэром. Мне также хотелось бы знать, как сделать метод Kerberized, если вы чувствуете вдохновение! Cheers, Dan – Dan
Charles, увы, ваш скрипт отлично работает, за исключением того, что он не повторяет дату/время из% s. Идеи, как это исправить? – Dan
@Doug Упс - исключен вызов даты. Отредактировано, чтобы добавить это. Что касается подхода Kerberized - это было достаточно долго, так как я сделал это, чтобы потребовалось некоторое исследование, чтобы выкопать его обратно. Возможно, вы можете спросить об этом как отдельный вопрос? (Даже если вы этого не сделаете, было бы неплохо поместить запутанный пароль в файл с ограниченными разрешениями и потребовать от пользователей этого скрипта перескакивать через sudo, чтобы прочитать его, если вы контролируете разрешения sudo s permo, вы можете позволить они запускают скрипт, но не позволяют им видеть файл, который он читает). –