Tips October 31, 2004 at 9:30 pm

Using Scripting to Change a Local Password

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)

About

Andrina Kelly is responsible for anything and everything touched by, or connected to, a Mac at Bell Media, Canada's premiere multimedia company. You may recognize her name from the end credits of Canada's evening news broadcast. She has previously spoken at MacSysAdmin, JAMF National Users Conference, Apple's WWDC, Macworld IT conferences, Mac Networkers Retreat, and Canada MacExpo.

No Comments

  • 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!

Leave a reply

You must be logged in to post a comment.