Running a large network of macs in a secure environment leads to regular password changes on the local administrator account. Doing this in a 10.3 environment is quite a simple endeavor, but for those with some older 10.2.x machines around, it can be quite frustrating. Read on for an expect script for running on 10.3.x and a bash script to be used on 10.2.x machines.First, the expect script:
The reason I went about doing this, is while passwd would suit my needs, I really wanted to use a non-user interactive script that could be pushed out to all machines at the same time.
First put your password you want used into a temporary text file (made readable only by root, and deleted immediately after the script was run). This was done as some characters will present an error “tcsh: sudo: No match” when you just try to put the new password after the command. To run on the client machine, see the following:
sudo cpasswd.tcl
cat password_file
This is the contents of my cpasswd.tcl script, note that in the second line I’ve used the username of admin, change this to whatever the short name of the user on your machine is.
#!/usr/bin/expect
spawn passwd admin
expect "ssword:"
send [lindex $argv 0]r
expect "ssword:"
send [lindex $argv 0]r
expect eof
And that’s it for a 10.3.x machine, very simple.
The 10.2.x machines required a bit more thought as they do not have expect or tcl/tk installed by default. The full bash script is shown below, there’s a couple things to note before just running the script however. You will have to change one machine manually first, this will be your “known good machine”. Note the second comment in the script, and perform the nidump as instructed on your known good machine.
This script should not overwrite any custom user account passwords on the machine as long as you create your nidump file from a machine that only has the one local account that you want to change on the rest of your machines. Again, I’ve used admin as the account to look out for in this script, change it to whatever suits your environment. And of course, before pushing this out to all your machines, make sure to test this thoroughly to make sure it suits your needs.
#!/bin/bash
Script for changing the password on Mac OS 10.2.x machines using nidump from a machine that
has had it's admin password changed to affect changes on all other machines.
BEFORE RUNNING THIS SCRIPT run the following on your known good machine:
nidump passwd . > /shared/network/drive/accessible/by/all/machines/nidumpfile
(Ed. Note if you are cutting and pasting the above line is all in the comment. Stupid html…)
# Check to see if root
amiroot=whoami
if [ $amiroot != root ];then
echo ""
echo "ERROR: You must be root to use this script"
echo ""
exit
fi
Check to see if nidump has been run on the known good system before proceeding
if [ ! -e '/shared/network/drive/accessible/by/all/machines/nidumpfile' ]
then
echo ""
echo "You have not run nidump on your known good machine - do this first and then run this script again"
echo ""
exit
fi
Create a temporary directory at the root of Netinfo
nicl . -create /temp
Move the current admin entry into the newly created temp directoy
nicl . -move /users/admin /temp
Load the nidump passwords from your known good machine into the Netinfo database
niload passwd .
Clean up by deleting the temporary directory that was housing the old admin details
nicl . -delete /temp
Use kickstart to let the ARD agent recognize there's a new admin password
/System/Library/CoreServices/ARD Agent.app/Contents/Resources/kickstart -uninstall -settings -prefs
/System/Library/CoreServices/ARD Agent.app/Contents/Resources/kickstart -activate
/System/Library/CoreServices/ARD Agent.app/Contents/Resources/kickstart -configure -users admin -access -on -privs -all
(Ed. Note. I’ve put the two scripts and article together in an archive. You can download the scripts from our servers. -Josh)
I cannot get this to work! I followed all directions for 10.3.x; the script runs
and exits properly, but the password ends up being set as… something other
than the contents of my password file!
Has anyone gotten this to work? Any and all help appreciated.
So a couple things to note is that the cat command is in back-ticks – shares
the same key on your keyboard as the tilde (~). The back-ticks, in a crude
way of speaking, do the same as brackets would do in a maths equation –
ensuring that the command within the back-ticks is run first, and the output
applied to the first part of the command… If you have a simple password
you’re trying to apply you can run this script without the `cat /private/tmp/
passwd_file` and simply replace all that with your password in clear text –
there’s obvious disadvantages to this with it being in clear text and visible on
your screen, and I found I had to use the password within a file method as
the password I was setting had an * in it, and this was being interpreted
differently when run….
OK, I’m an idiot. The (only) command in the script:
sudo cpasswd.tcl `cat password_file`
Contains "tick marks" (on the "~" key) and not single quotes. I changed this
and… voila! It works!
Incidentally, I ended up making an AppleScript version of this so that users
can change their own passwords (we remove Accounts pref pane). Here’s the
AppleScript:
set username to do shell script ("echo $USER")
tell application "Finder"
activate
display dialog "Changing password for " & username & ". Please enter
current password." default answer ""
set current to text returned of the result
display dialog "Please enter your new password." default answer ""
set newpass to text returned of the result
end tell
do shell script ("echo " & current & " | sudo /Applications/Utilities/Blue-
Change-Password/.cpasswd.tcl" & " `echo " & newpass & "`")
tell application "Finder"
activate
display dialog "Password successfully changed for " & username & "."
end tell
When I try and run this I get an AppleScript error:
"Password:
sudo: /Applications/Utilities/Blue-Change-Password/.cpasswd.tcl: command
not found"
What am I doing wrong?
The first error I found was that there was a space in "Blue-Change-Password"
not sure why. I found it by typing the command into textwrangler.
Here is what I have:
<code>
set username to do shell script ("echo $USER")
tell application "Finder"
activate
display dialog "Changing password for " & username & ". Please enter
current password." default answer ""
set current to text returned of the result
display dialog "Please enter your new password." default answer ""
set newpass to text returned of the result
end tell
do shell script ("echo " & current & " | sudo /Applications/Utilities/Blue-
Change-Password/.cpasswd.tcl" & " `echo " & newpass & "`")
tell application "Finder"
activate
display dialog "Password successfully changed for " & username & "."
end tell
</code>
Make sure that you have the file ".cpasswd.tcl" available at the path the
applescript is expecting to find it, also, make sure that your .tcl script the
applescript is calling is executable (rwx by the user you’re running the script as)
Great tip, but I’m having trouble with international characters in the
password.
I’d like to use a password with the chars like åøæ (aring, oslash, aelig) and
others, but can’t get it to work. Guess I’m not UNIX savvy enough, or I don’t
understand which text encoding to use when creating the text file on my Mac.
Using netOctopus to push the two files out to test mac with root-only access,
then Apple Remote Desktop to execute the script. Executes fine, but I
subsequently cannot login on same mac with the changed account. Any tips
on how can I get it to work?
Thanks!
I had a similar problem when I was first working this out with a character that
needed to be escaped in the shell. The way I worked around this was by
creating a text file that was accessible to all the machines I was running the
script on (something like an NFS automount on all the machines would be
ideal) and then using the result of a cat of that file to apply to the
cpasswd.tcl – ensure that you’re using back-ticks for the cat – works like
brackets would in math in that it uses the result of the operations within the
back-ticks to apply to the cpasswd.tcl command.
This should work, if it doesn’t perhaps look into ignoring the `cat file` all
together and try escaping the special characters that are proving
troublesome and put this escaped pattern in single quotes…
To treat a special character literally escape it with either ‘\’ or ‘[]’.
For example if you wanted your password to be ‘*.*’ use the pattern ‘\*\.\*’ or
‘[*][.][*]’.
Hey, I rolled the dscl method into a small freeware app, available
here
Enjoy!