Skip to content

Instantly share code, notes, and snippets.

@acidprime
Created January 9, 2012 00:53
Show Gist options
  • Save acidprime/1580325 to your computer and use it in GitHub Desktop.
Save acidprime/1580325 to your computer and use it in GitHub Desktop.
Password Modification of Auto Server Setup files
#!/bin/bash
#set -xv
# Required commands
declare -x awk="/usr/bin/awk"
declare -x ls="/bin/ls"
declare -x basename="/usr/bin/basename"
declare -x du="/usr/bin/du"
declare -x defaults="/usr/bin/defaults"
declare -x plistbuddy="/usr/libexec/PlistBuddy"
declare -x serialnumber="/System/Library/ServerSetup/SerialNumber"
declare -x ifconfig="/sbin/ifconfig"
declare -x ipconfig="ipconfig"
declare -x tr="/usr/bin/tr"
declare -x hostname="/bin/hostname"
# Runtime variables
declare -ix ENX_NUM="1" # Highest interface to check en0,en1,en2 etc.
declare -x HOST_NAME="$($hostname)" # Not using $HOSTNAME for safety
# -- Runtime varibles
declare -x REQCMDS="$awk $dscl $deaults $ntpdate $perl $scutil"
declare -x SCRIPT="${0##*/}" ; SCRIPTNAME="${SCRIPT%%\.*}"
declare -x SCRIPTPATH="$0" RUNDIRECTORY="${0%/*}"
declare -x SYSTEMVERSION="/System/Library/CoreServices/SystemVersion.plist"
declare -x OSVER="$("$defaults" read "${SYSTEMVERSION%.plist}" ProductVersion )"
#declare -x CONFIGFILE="${RUNDIRECTORY:?}/${SCRIPTNAME}.conf"
declare -x BUILDVERSION="2009051"
# -- Start the script log
# Set to "VERBOSE" for more logging prior to using -v
declare -x LOGLEVEL="NORMAL" SCRIPTLOG="/Library/Logs/${SCRIPT%%\.*}.log"
declare -i CURRENT_LOG_SIZE="$("$du" -hm "${SCRIPTLOG:?}" |
"$awk" '/^[0-9]/{print $1;exit}')"
if [ ${CURRENT_LOG_SIZE:=0} -gt 50 ] ; then
"$rm" "$SCRIPTLOG"
statusMessage "LOGSIZE:$CURRENT_LOG_SIZE, too large removing"
fi
exec 2>>"${SCRIPTLOG:?}" # Redirect standard error to log file
# Strip any extention from scriptname and log stderr to script log
# Removed log file path notification
statusMessage() { # Status message function with type and now color!
# Requires SCRIPTLOG STATUS_TYPE=1 STATUS_MESSAGE=2
declare date="${date:="/bin/date"}"
declare DATE="$("$date" -u "+%Y-%m-%d")"
declare STATUS_TYPE="$1" STATUS_MESSAGE="$2"
if [ "$ENABLECOLOR" = "YES" ] ; then
# Background Color
declare REDBG="41" WHITEBG="47" BLACKBG="40"
declare YELLOWBG="43" BLUEBG="44" GREENBG="42"
# Foreground Color
declare BLACKFG="30" WHITEFG="37" YELLOWFG="33"
declare BLUEFG="36" REDFG="31"
declare BOLD="1" NOTBOLD="0"
declare format='\033[%s;%s;%sm%s\033[0m\n'
# "Bold" "Background" "Forground" "Status message"
printf '\033[0m' # Clean up any previous color in the prompt
else
declare format='%s\n'
fi
# Function only seems to work on intel and higher.
showUIDialog(){
statusMessage header "FUNCTION: # $FUNCNAME" ; unset EXITVALUE TRY
"$killall" -HUP "System Events" 2>/dev/null
declare -x UIMESSAGE="$1"
"$osascript" <<EOF
try
with timeout of 0.1 seconds
tell application "System Events"
set UIMESSAGE to (system attribute "UIMESSAGE") as string
activate
display dialog UIMESSAGE with icon 2 giving up after "3600" buttons "Dismiss" default button "Dismiss"
end tell
end timeout
end try
EOF
return 0
} # END showUIDialog()
case "${STATUS_TYPE:?"Error status message with null type"}" in
progress) \
[ -n "$LOGLEVEL" ] &&
printf $format $NOTBOLD $WHITEBG $BLACKFG "PROGRESS:$STATUS_MESSAGE" ;
printf "%s\n" "$DATE:PROGRESS: $STATUS_MESSAGE" >> "${SCRIPTLOG:?}" ;;
# Used for general progress messages, always viewable
notice) \
printf "%s\n" "$DATE:NOTICE:$STATUS_MESSAGE" >> "${SCRIPTLOG:?}" ;
[ -n "$LOGLEVEL" ] &&
printf $format $NOTBOLD $YELLOWBG $BLACKFG "NOTICE :$STATUS_MESSAGE" ;;
# Notifications of non-fatal errors , always viewable
error) \
printf "%s\n\a" "$DATE:ERROR:$STATUS_MESSAGE" >> "${SCRIPTLOG:?}" ;
[ -n "$LOGLEVEL" ] &&
printf $format $NOTBOLD $REDBG $YELLOWFG "ERROR :$STATUS_MESSAGE" ;;
# Errors , always viewable
verbose) \
printf "%s\n" "$DATE:VERBOSE: $STATUS_MESSAGE" >> "${SCRIPTLOG:?}" ;
[ "$LOGLEVEL" = "VERBOSE" ] &&
printf $format $NOTBOLD $WHITEBG $BLACKFG "VERBOSE :$STATUS_MESSAGE" ;;
# All verbose output
header) \
[ "$LOGLEVEL" = "VERBOSE" ] &&
printf $format $NOTBOLD $BLUEBG $BLUEFG "VERBOSE :$STATUS_MESSAGE" ;
printf "%s\n" "$DATE:PROGRESS: $STATUS_MESSAGE" >> "${SCRIPTLOG:?}" ;;
# Function and section headers for the script
passed) \
[ "$LOGLEVEL" = "VERBOSE" ] &&
printf $format $NOTBOLD $GREENBG $BLACKFG "PASSED :$STATUS_MESSAGE" ;
printf "%s\n" "$DATE:PASSED: $STATUS_MESSAGE" >> "${SCRIPTLOG:?}" ;;
# Sanity checks and "good" information
graphical) \
[ "$GUI" = "ENABLED" ] &&
showUIDialog "$STATUS_MESSAGE" ;;
esac
return 0
} # END statusMessage()
die() { # die Function
statusMessage header "FUNCTION: # $FUNCNAME" ; unset EXITVALUE
declare LASTDIETYPE="$1" LAST_MESSAGE="$2" LASTEXIT="$3"
declare LASTDIETYPE="${LASTDIETYPE:="UNTYPED"}"
if [ ${LASTEXIT:="192"} -gt 0 ] ; then
statusMessage error "$LASTDIETYPE :$LAST_MESSAGE:EXIT:$LASTEXIT"
# Print specific error message in red
else
statusMessage verbose "$LASTDIETYPE :$LAST_MESSAGE:EXIT:$LASTEXIT"
# Print specific error message in white
fi
statusMessage verbose "COMPLETED:$SCRIPT IN $SECONDS SECONDS"
"$killall" "System Events"
exit "${LASTEXIT}" # Exit with last status or 192 if none.
return 1 # Should never get here
} # END die()
cleanUp() { # -- Clean up of our inportant sessions variables and functions.
statusMessage header "FUNCTION: # $FUNCNAME" ; unset EXITVALUE
statusMessage verbose "TIME: $SCRIPT ran in $SECONDS seconds"
unset -f ${!check*}
[ "${ENABLECOLOR:-"ENABLECOLOR"}" = "YES" ] && printf '\033[0m' # Clear Color
if [ "$PPID" == 1 ] ; then # LaunchD is always PID 1 in 10.4+
: # Future LaunchD code
fi
exec 2>&- # Reset the error redirects
return 0
} # END cleanUp()
showUsage(){
statusMessage header "FUNCTION: # $FUNCNAME" ; unset EXITVALUE
printf "%s\n\t" "USAGE:"
printf "%s\n\t" "Discription: $SCRIPT_NAME a script for finding and setting Auto Server Setup passwords "
printf "%s\n\t"
printf "%s\n\t" " TASKS:"
printf "%s\n\t" " -r | # Return this machines admin password from Auto Server Setup"
printf "%s\n\t" " -s | # Set Password for all files in Auto Server Setup directory"
printf "%s\n\t" " -P \'password\' | # Password to set"
printf "%s\n\t" " OUTPUT:"
printf "%s\n\t" " -v | # Turn on verbose output"
printf "\033[%s;%s;%sm%s\033[0m\n\t" "1" "44" "37" " -C | # Turn on colorized output"
printf "\033[0m"
printf "%s\n\t" " -u | # Turn on graphical display box support"
printf "%s\n\t" " -D | # Turn on debug (all function's name will be displayed at runtime)."
printf "%s\n\t" " OTHER TASKS:"
printf "%s\n\t" " -f | </path/to/$SCRIPT_NAME.conf> # Read configuration from a conf file."
# printf "%s\n\t" " -w | </path/to/$0.conf> # Write configuration to a conf file."
printf "%s\n\t" " -d | </path/to/Auto Server Setup> # Auto Server Setup"
printf "%s\n\t" " -h | # Print this usage message and quit"
printf "%s\n\t"
printf "%s\n\t" " EXAMPLE SYNTAX:"
printf "%s\n\t" " sudo \"$0\" -Cv -f ServerList.csv -d \"/Auto Server Setup\" -P \'d0gc4t\'"
printf "%s\n\t" " sudo \"$0\" -r"
printf "%s\n\t" " \$ d0gc4t"
printf "%s\n"
return 0
}
# Check script options
statusMessage header "GETOPTS: Processing script $# options:$@"
# ABOVE: Check to see if we are running as a postflight script,the installer creates $SCRIPT_NAME
if [ $# = 0 ] ; then
statusMessage verbose "No options given"
showUsage && exit 1
fi
while getopts rsvCud:f:P: SWITCH ; do
case $SWITCH in
v ) export LOGLEVEL="VERBOSE" ;;
C ) export ENABLECOLOR="YES" ;;
u ) export GUI="ENABLED" ;;
d ) export SAVE_DIRECTORY="$OPTARG" ;;
r ) export RETURN_PASSWORD="true" ;;
s ) export SET_PASSWORD="true" ;;
P ) export PASSWORD_TO_SET="$OPTARG" ;;
esac
done # END getopts
getAdminPassword(){
declare FILE="$1"
export DIRADMIN_PASS="$($plistbuddy -c "Print :AdminUser:password" "$FILE")"
if [ ${#DIRADMIN_PASS} -gt 1 ] ; then
return 0
else
return 1
fi
}
setAdminPassword(){
if [ -w "${FILE:?}" ] ; then
declare PASSWORD_TO_SET="$1" FILE="$2"
$plistbuddy -c "Set :AdminUser:password ${PASSWORD_TO_SET:?}" "${FILE:?}"
else
statusMessage error "$FILE is not writable by current user ($EUID)"
fi
}
setPassword(){
OLDIFS="$IFS"
IFS=$'\n' # Reset field seperator to newline for spaces in the paths
# First Alphanumeric File that is found wins, not sure how Apple does this as its not documented (AFAIK)
for FILE in `$ls /Volumes/*/Auto\ Server\ Setup/*.plist` ; do
declare FILE_NAME="$($basename "$FILE" | $tr [:upper:] [:lower:])"
statusMessage progress "FOUND: Setting password in file $FILE_NAME"
setAdminPassword "${PASSWORD_TO_SET:?}" "${FILE:?}" &&
statusMessage passed "SET: Password successfully set in file: $FILE_NAME"
done
}
returnPassword(){
OLDIFS="$IFS"
IFS=$'\n' # Reset field seperator to newline for spaces in the paths
# First Alphanumeric File that is found wins, not sure how Apple does this as its not documented (AFAIK)
for FILE in `$ls /Volumes/*/Auto\ Server\ Setup/*.plist` ; do
declare FILE_NAME="$($basename "$FILE" | $tr [:upper:] [:lower:])"
# Find file name from path (Should be converted to awk)
declare -i IS_IP_OR_HOSTNAME="$(printf "%s" "$FILE_NAME" | $awk 'BEGIN{FS=""}/\./{seen++}END{print seen}')"
if [ $IS_IP_OR_HOSTNAME -ge 1 ] ; then
if [ "$HOST_NAME" = "${FILE_NAME%%.plist}" ] ; then
getAdminPassword "$FILE" && export FOUND="true"
echo "$DIRADMIN_PASS"
exit 0
else # If its not out HOSTNAME, how about our IP(s)?
for (( N = 0 ; N <=$ENX_NUM; N++ )) ; do
for IPS in `$ipconfig getifaddr "en$N" 2>/dev/null` ; do
if [ "$IPS" = "${FILE_NAME%%.plist}" ] ; then
getAdminPassword "$FILE" && export FOUND="true"
echo "$DIRADMIN_PASS" # This is exported from the function
exit 0
fi
done
done
fi
fi # END IP check
declare -i FILE_NAME_LEN="$(printf "%s" "$FILE_NAME" | $awk 'BEGIN{FS=""}{print NF}')"
# Check for Serial Number file bases on file length (hostnames and IPs caught before this )
if [ $FILE_NAME_LEN -le 8 ] ; then
if [ "${FILE_NAME%%.plist}" = "$($serialnumber)" ] ; then
getAdminPassword "$FILE" && export FOUND="true"
echo "$DIRADMIN_PASS" # This is exported from the function
exit 0
else
continue
fi
# Larger then or equal to 19 with no "." then its probobly a MAC
elif [ $FILE_NAME_LEN -ge 10 ] ; then
for ETHER in `$ifconfig | $awk '/^.*ether/{gsub(":","",$NF);print tolower($NF)}'` ; do
if [ "${FILE_NAME%%.plist}" = "${ETHER}" ] ; then
getAdminPassword "$FILE" && export FOUND="true"
echo "$DIRADMIN_PASS" # This is exported from the function
exit 0
else
continue
fi
done
fi
done
OLDIFS="$IFS" # Reset Field Seperator
}
if [ "$SET_PASSWORD" = "true" ] ; then
setPassword "${PASSWORD_TO_SET:?"Please specify a password"}"
elif [ "$RETURN_PASSWORD" = "true" ] ; then
returnPassword
fi
if [ "${FOUND:-"false"}" = "true" ] ; then
exit 0
else
exit 1
fi
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment