I was reminded by a recent post to the radmind mailing list that there are usually still some loose ends to clean up when you use radmind to update machines from 10.3 to 10.4. One such loose end is the NetInfo database. Typically, most people don’t manage the NetInfo database via radmind. The Tiger installer has some post-upgrade scripts that run and add certain users and groups required by various Tiger services. You’ll need to replicate this functionality. I did it by creating a startup script (I have a generic StartupItem that simply runs every executable in a certain directory) that does everything the post-upgrade scripts do. The way the script is written there is no harm if it runs every startup – it looks to see if the required users and groups are there, and creates them if they’re not. Here’s the script:
#!/bin/sh
# Updates NetInfo with users and groups required by Tiger
# Based on posflight script in BaseSystem.pkg and
# CreateSystemUsers script in Essentials.pkg
#
# This version by Greg Neagle, May 2005
# June 8, 2005: added reboot logic if securityagent or
# windowserver users are created
echo "Validating and creating system users… "
/usr/bin/nicl . -read "groups/mysql" >/dev/null 2>&1
if [ $? != 0 ] ; then
/usr/bin/nicl . -create "/groups/mysql"
/usr/bin/nicl . -create "/groups/mysql" 'gid' '74'
/usr/bin/nicl . -create "/groups/mysql" 'passwd' '*'
/usr/bin/nicl . -create "/users/mysql"
/usr/bin/nicl . -create "/users/mysql" 'uid' '74'
/usr/bin/nicl . -create "/users/mysql" 'gid' '74'
/usr/bin/nicl . -create "/users/mysql" 'passwd' '*'
/usr/bin/nicl . -create "/users/mysql" 'change' '0'
/usr/bin/nicl . -create "/users/mysql" 'expire' '0'
/usr/bin/nicl . -create "/users/mysql" 'realname' 'MySQL User'
/usr/bin/nicl . -create "/users/mysql" 'home' '/dev/null'
/usr/bin/nicl . -create "/users/mysql" 'shell' '/dev/null'
/usr/bin/nicl . -create "/users/mysql" '_writers_passwd' 'mysql'
fi
/usr/bin/nicl . -read "groups/sshd" >/dev/null 2>&1
if [ $? != 0 ] ; then
/usr/bin/nicl . -create "/groups/sshd"
/usr/bin/nicl . -create "/groups/sshd" 'gid' '75'
/usr/bin/nicl . -create "/groups/sshd" 'passwd' '*'
/usr/bin/nicl . -create "/users/sshd"
/usr/bin/nicl . -create "/users/sshd" 'uid' '75'
/usr/bin/nicl . -create "/users/sshd" 'gid' '75'
/usr/bin/nicl . -create "/users/sshd" 'passwd' '*'
/usr/bin/nicl . -create "/users/sshd" 'change' '0'
/usr/bin/nicl . -create "/users/sshd" 'expire' '0'
/usr/bin/nicl . -create "/users/sshd" 'realname' 'sshd Privilege separation'
/usr/bin/nicl . -create "/users/sshd" 'home' '/var/empty'
/usr/bin/nicl . -create "/users/sshd" 'shell' '/dev/null'
/usr/bin/nicl . -create "/users/sshd" '_writers_passwd' 'sshd'
fi
/usr/bin/nicl . -read "groups/smmsp" >/dev/null 2>&1
if [ $? != 0 ] ; then
/usr/bin/nicl . -create "/groups/smmsp"
/usr/bin/nicl . -create "/groups/smmsp" 'gid' '25'
/usr/bin/nicl . -create "/groups/smmsp" 'passwd' '*'
/usr/bin/nicl . -create "/users/smmsp"
/usr/bin/nicl . -create "/users/smmsp" 'uid' '25'
/usr/bin/nicl . -create "/users/smmsp" 'gid' '25'
/usr/bin/nicl . -create "/users/smmsp" 'passwd' '*'
/usr/bin/nicl . -create "/users/smmsp" 'change' '0'
/usr/bin/nicl . -create "/users/smmsp" 'expire' '0'
/usr/bin/nicl . -create "/users/smmsp" 'realname' 'Sendmail User'
/usr/bin/nicl . -create "/users/smmsp" 'home' '/private/etc/mail'
/usr/bin/nicl . -create "/users/smmsp" 'shell' '/dev/null'
/usr/bin/nicl . -create "/users/smmsp" '_writers_passwd' 'smmsp'
fi
/bin/chmod 700 "/private/var/db/netinfo/local.nidb"
/bin/chmod 600 "/private/var/db/netinfo/local.nidb/Clean"
# add the amavisd user
nicl . -read /users/amavisd >/dev/null 2>&1
if [ $? != 0 ] ; then
nicl . -create /users/amavisd
nicl . -createprop /users/amavisd uid 83
nicl . -createprop /users/amavisd gid 83
nicl . -createprop /users/amavisd passwd '*'
nicl . -createprop /users/amavisd change 0
nicl . -createprop /users/amavisd expire 0
nicl . -createprop /users/amavisd realname 'Amavisd User'
nicl . -createprop /users/amavisd home '/var/virusmails'
nicl . -createprop /users/amavisd shell '/bin/tcsh'
nicl . -createprop /users/amavisd _writers_passwd 'amavisd'
echo "niutil: User 'amavisd' added."
fi
# add the amavisd group
nicl . -read /groups/amavisd >/dev/null 2>&1
if [ $? != 0 ] ; then
nicl . -create /groups/amavisd
nicl . -createprop /groups/amavisd gid 83
nicl . -createprop /groups/amavisd passwd '*'
echo "niutil: Group 'amavisd' added."
fi
# add the appowner user
nicl . -read /users/appowner >/dev/null 2>&1
if [ $? != 0 ] ; then
nicl . -create /users/appowner
nicl . -createprop /users/appowner uid 87
nicl . -createprop /users/appowner gid 87
nicl . -createprop /users/appowner passwd '*'
nicl . -createprop /users/appowner change 0
nicl . -createprop /users/appowner expire 0
nicl . -createprop /users/appowner realname 'Application Owner'
nicl . -createprop /users/appowner home '/var/empty'
nicl . -createprop /users/appowner shell '/usr/bin/false'
nicl . -createprop /users/appowner _writers_passwd 'appowner'
echo "niutil: User 'appowner' added."
fi
# add the appowner group
nicl . -read /groups/appowner >/dev/null 2>&1
if [ $? != 0 ] ; then
nicl . -create /groups/appowner
nicl . -createprop /groups/appowner gid 87
nicl . -createprop /groups/appowner passwd '*'
echo "niutil: Group 'appowner' added."
fi
# rename the 'appserver' group to 'appserverusr'
nicl . -read /groups/appserver >/dev/null 2>&1
if [ $? == 0 ] ; then
nicl . -createprop /groups/appserver name appserverusr
echo "niutil: Group 'appserver' renamed to 'appserverusr'."
fi
# add the appserver user
# echo "Adding user 'appserver'"
nicl . -read /users/appserver >/dev/null 2>&1
if [ $? != 0 ] ; then
nicl . -create /users/appserver
nicl . -createprop /users/appserver uid 79
nicl . -createprop /users/appserver gid 79
nicl . -createprop /users/appserver passwd '*'
nicl . -createprop /users/appserver change 0
nicl . -createprop /users/appserver expire 0
nicl . -createprop /users/appserver realname 'Application Server'
nicl . -createprop /users/appserver home '/var/empty'
nicl . -createprop /users/appserver shell '/usr/bin/false'
nicl . -createprop /users/appserver _writers_passwd 'appserver'
echo "niutil: User 'appserver' added."
fi
# add the appserverusr group
# echo "Adding group 'appserverusr'"
nicl . -read /groups/appserverusr >/dev/null 2>&1
if [ $? != 0 ] ; then
nicl . -create /groups/appserverusr
nicl . -createprop /groups/appserverusr gid 79
nicl . -createprop /groups/appserverusr passwd '*'
echo "niutil: Group 'appserverusr' added."
fi
# add the clamav user
nicl . -read /users/clamav >/dev/null 2>&1
if [ $? != 0 ] ; then
nicl . -create /users/clamav
nicl . -createprop /users/clamav uid 82
nicl . -createprop /users/clamav gid 82
nicl . -createprop /users/clamav passwd '*'
nicl . -createprop /users/clamav change 0
nicl . -createprop /users/clamav expire 0
nicl . -createprop /users/clamav realname 'Clamav User'
nicl . -createprop /users/clamav home '/var/virusmails'
nicl . -createprop /users/clamav shell '/bin/tcsh'
nicl . -createprop /users/clamav _writers_passwd 'clamav'
echo "niutil: User 'clamav' added."
fi
# add the clamav group
nicl . -read /groups/clamav >/dev/null 2>&1
if [ $? != 0 ] ; then
nicl . -create /groups/clamav
nicl . -createprop /groups/clamav gid 82
nicl . -createprop /groups/clamav passwd '*'
echo "niutil: Group 'clamav' added."
fi
# rename the 'cyrus' user to 'cyrusimap'
nicl . -read /users/cyrus >/dev/null 2>&1
if [ $? == 0 ] ; then
nicl . -createprop /users/cyrus realname 'Cyrus IMAP User'
nicl . -createprop /users/cyrus _writers_passwd 'cyrusimap'
nicl . -createprop /users/cyrus name 'cyrusimap'
echo "niutil: User 'cyrus' renamed to 'cyrusimap'."
fi
# add the cyrusimap user
# echo "Adding user 'cyrusimap'"
nicl . -read /users/cyrusimap >/dev/null 2>&1
if [ $? != 0 ] ; then
nicl . -create /users/cyrusimap
nicl . -createprop /users/cyrusimap uid 77
nicl . -createprop /users/cyrusimap gid 6
nicl . -createprop /users/cyrusimap passwd '*'
nicl . -createprop /users/cyrusimap change 0
nicl . -createprop /users/cyrusimap expire 0
nicl . -createprop /users/cyrusimap realname 'Cyrus IMAP User'
nicl . -createprop /users/cyrusimap home '/var/imap'
nicl . -createprop /users/cyrusimap shell '/usr/bin/false'
nicl . -createprop /users/cyrusimap _writers_passwd 'cyrusimap'
echo "niutil: User 'cyrusimap' added."
fi
# add the eppc user
# echo "Adding user 'eppc'"
nicl . -read /users/eppc >/dev/null 2>&1
if [ $? != 0 ] ; then
nicl . -create /users/eppc
nicl . -createprop /users/eppc uid 71
nicl . -createprop /users/eppc gid 71
nicl . -createprop /users/eppc passwd '*'
nicl . -createprop /users/eppc change 0
nicl . -createprop /users/eppc expire 0
nicl . -createprop /users/eppc realname 'Apple Events User'
nicl . -createprop /users/eppc home '/var/empty'
nicl . -createprop /users/eppc shell '/usr/bin/false'
nicl . -createprop /users/eppc _writers_passwd 'eppc'
echo "niutil: User 'eppc' added."
fi
# add the jabber user
nicl . -read /users/jabber >/dev/null 2>&1
if [ $? != 0 ] ; then
nicl . -create /users/jabber
nicl . -createprop /users/jabber uid 84
nicl . -createprop /users/jabber gid 84
nicl . -createprop /users/jabber passwd '*'
nicl . -createprop /users/jabber change 0
nicl . -createprop /users/jabber expire 0
nicl . -createprop /users/jabber realname 'jabber'
nicl . -createprop /users/jabber home '/var/empty'
nicl . -createprop /users/jabber shell '/usr/bin/false'
nicl . -createprop /users/jabber _writers_passwd 'jabber'
echo "niutil: User 'jabber' added."
fi
# add the jabber group
nicl . -read /groups/jabber >/dev/null 2>&1
if [ $? != 0 ] ; then
nicl . -create /groups/jabber
nicl . -createprop /groups/jabber gid 84
nicl . -createprop /groups/jabber passwd '*'
echo "niutil: Group 'jabber' added."
fi
# add the lp user
# echo "Adding user 'lp'"
nicl . -read /users/lp >/dev/null 2>&1
if [ $? != 0 ] ; then
nicl . -create /users/lp
nicl . -createprop /users/lp uid 26
nicl . -createprop /users/lp gid 26
nicl . -createprop /users/lp passwd '*'
nicl . -createprop /users/lp change 0
nicl . -createprop /users/lp expire 0
nicl . -createprop /users/lp realname 'Printing Services'
nicl . -createprop /users/lp home '/var/spool/cups'
nicl . -createprop /users/lp shell '/usr/bin/false'
nicl . -createprop /users/lp _writers_passwd 'lp'
echo "niutil: User 'lp' added."
fi
# add the postdrop lp
# echo "Adding group 'lp'"
nicl . -read /groups/lp >/dev/null 2>&1
if [ $? != 0 ] ; then
nicl . -create /groups/lp
nicl . -createprop /groups/lp gid 26
nicl . -createprop /groups/lp passwd '*'
echo "niutil: Group 'lp' added."
fi
# add the mailman user
# echo "Adding user 'mailman'"
nicl . -read /users/mailman >/dev/null 2>&1
if [ $? != 0 ] ; then
nicl . -create /users/mailman
nicl . -createprop /users/mailman uid 78
nicl . -createprop /users/mailman gid 78
nicl . -createprop /users/mailman passwd '*'
nicl . -createprop /users/mailman change 0
nicl . -createprop /users/mailman expire 0
nicl . -createprop /users/mailman realname 'Mailman user'
nicl . -createprop /users/mailman home '/var/empty'
nicl . -createprop /users/mailman shell '/usr/bin/false'
nicl . -createprop /users/mailman _writers_passwd 'mailman'
echo "niutil: User 'mailman' added."
fi
# add the mailman group
# echo "Adding group 'mailman'"
nicl . -read /groups/mailman >/dev/null 2>&1
if [ $? != 0 ] ; then
nicl . -create /groups/mailman
nicl . -createprop /groups/mailman gid 78
nicl . -createprop /groups/mailman passwd '*'
echo "niutil: Group 'mailman' added."
fi
# add the postfix user
# echo "Adding user 'postfix'"
nicl . -read /users/postfix >/dev/null 2>&1
if [ $? != 0 ] ; then
nicl . -create /users/postfix
nicl . -createprop /users/postfix uid 27
nicl . -createprop /users/postfix gid 27
nicl . -createprop /users/postfix passwd '*'
nicl . -createprop /users/postfix change 0
nicl . -createprop /users/postfix expire 0
nicl . -createprop /users/postfix realname 'Postfix User'
nicl . -createprop /users/postfix home '/var/spool/postfix'
nicl . -createprop /users/postfix shell '/usr/bin/false'
nicl . -createprop /users/postfix _writers_passwd 'postfix'
echo "niutil: User 'postfix' added."
fi
# add the postfix group
# echo "Adding group 'postfix'"
nicl . -read /groups/postfix >/dev/null 2>&1
if [ $? != 0 ] ; then
nicl . -create /groups/postfix
nicl . -createprop /groups/postfix gid 27
nicl . -createprop /groups/postfix passwd '*'
echo "niutil: Group 'postfix' added."
fi
# add the postdrop group
# echo "Adding group 'postdrop'"
nicl . -read /groups/postdrop >/dev/null 2>&1
if [ $? != 0 ] ; then
nicl . -create /groups/postdrop
nicl . -createprop /groups/postdrop gid 28
nicl . -createprop /groups/postdrop passwd '*'
echo "niutil: Group 'postdrop' added."
fi
# add the qtss user
# echo "Adding user 'qtss'"
nicl . -read /users/qtss >/dev/null 2>&1
if [ $? != 0 ] ; then
nicl . -create /users/qtss
nicl . -createprop /users/qtss uid 76
nicl . -createprop /users/qtss gid 76
nicl . -createprop /users/qtss passwd '*'
nicl . -createprop /users/qtss change 0
nicl . -createprop /users/qtss expire 0
nicl . -createprop /users/qtss realname 'QuickTime Streaming Server'
nicl . -createprop /users/qtss home '/var/empty'
nicl . -createprop /users/qtss shell '/usr/bin/false'
nicl . -createprop /users/qtss _writers_passwd 'qtss'
echo "niutil: User 'qtss' added."
fi
# add the qtss group
# echo "Adding group 'qtss'"
nicl . -read /groups/qtss >/dev/null 2>&1
if [ $? != 0 ] ; then
nicl . -create /groups/qtss
nicl . -createprop /groups/qtss gid 76
nicl . -createprop /groups/qtss passwd '*'
echo "niutil: Group 'qtss' added."
fi
NEEDTOREBOOT=0
# add the securityagent user
nicl . -read /users/securityagent >/dev/null 2>&1
if [ $? != 0 ] ; then
nicl . -create /users/securityagent
nicl . -createprop /users/securityagent uid 92
nicl . -createprop /users/securityagent gid 92
nicl . -createprop /users/securityagent passwd '*'
nicl . -createprop /users/securityagent change 0
nicl . -createprop /users/securityagent expire 0
nicl . -createprop /users/securityagent realname 'SecurityAgent'
nicl . -createprop /users/securityagent home '/var/empty'
nicl . -createprop /users/securityagent shell '/usr/bin/false'
nicl . -createprop /users/securityagent _writers_passwd 'securityagent'
echo "niutil: User 'securityagent' added."
NEEDTOREBOOT=1
fi
# add the securityagent group
nicl . -read /groups/securityagent >/dev/null 2>&1
if [ $? != 0 ] ; then
nicl . -create /groups/securityagent
nicl . -createprop /groups/securityagent gid 92
nicl . -createprop /groups/securityagent passwd '*'
echo "niutil: Group 'securityagent' added."
NEEDTOREBOOT=1
fi
# add the tokend user
nicl . -read /users/tokend >/dev/null 2>&1
if [ $? != 0 ] ; then
nicl . -create /users/tokend
nicl . -createprop /users/tokend uid 91
nicl . -createprop /users/tokend gid 91
nicl . -createprop /users/tokend passwd '*'
nicl . -createprop /users/tokend change 0
nicl . -createprop /users/tokend expire 0
nicl . -createprop /users/tokend realname 'Token Daemon'
nicl . -createprop /users/tokend home '/var/empty'
nicl . -createprop /users/tokend shell '/usr/bin/false'
nicl . -createprop /users/tokend _writers_passwd 'tokend'
echo "niutil: User 'tokend' added."
fi
# add the tokend group
nicl . -read /groups/tokend >/dev/null 2>&1
if [ $? != 0 ] ; then
nicl . -create /groups/tokend
nicl . -createprop /groups/tokend gid 91
nicl . -createprop /groups/tokend passwd '*'
echo "niutil: Group 'tokend' added."
fi
# add the windowserver user
nicl . -read /users/windowserver >/dev/null 2>&1
if [ $? != 0 ] ; then
nicl . -create /users/windowserver
nicl . -createprop /users/windowserver uid 88
nicl . -createprop /users/windowserver gid 88
nicl . -createprop /users/windowserver passwd '*'
nicl . -createprop /users/windowserver change 0
nicl . -createprop /users/windowserver expire 0
nicl . -createprop /users/windowserver realname 'WindowServer'
nicl . -createprop /users/windowserver home '/var/empty'
nicl . -createprop /users/windowserver shell '/usr/bin/false'
nicl . -createprop /users/windowserver _writers_passwd 'windowserver'
echo "niutil: User 'windowserver' added."
NEEDTOREBOOT=1
fi
# add the windowserver group
nicl . -read /groups/windowserver >/dev/null 2>&1
if [ $? != 0 ] ; then
nicl . -create /groups/windowserver
nicl . -createprop /groups/windowserver gid 88
nicl . -createprop /groups/windowserver passwd '*'
echo "niutil: Group 'windowserver' added."
NEEDTOREBOOT=1
fi
# add the xgridagent user
nicl . -read /users/xgridagent >/dev/null 2>&1
if [ $? != 0 ] ; then
nicl . -create /users/xgridagent
nicl . -createprop /users/xgridagent uid 86
nicl . -createprop /users/xgridagent gid 86
nicl . -createprop /users/xgridagent passwd '*'
nicl . -createprop /users/xgridagent change 0
nicl . -createprop /users/xgridagent expire 0
nicl . -createprop /users/xgridagent realname 'Xgrid Agent'
nicl . -createprop /users/xgridagent home '/var/xgrid/agent'
nicl . -createprop /users/xgridagent shell '/usr/bin/false'
nicl . -createprop /users/xgridagent _writers_passwd 'xgridagent'
echo "niutil: User 'xgridagent' added."
fi
# add the xgridagent group
nicl . -read /groups/xgridagent >/dev/null 2>&1
if [ $? != 0 ] ; then
nicl . -create /groups/xgridagent
nicl . -createprop /groups/xgridagent gid 86
nicl . -createprop /groups/xgridagent passwd '*'
echo "niutil: Group 'xgridagent' added."
fi
# add the xgridcontroller user
nicl . -read /users/xgridcontroller >/dev/null 2>&1
if [ $? != 0 ] ; then
nicl . -create /users/xgridcontroller
nicl . -createprop /users/xgridcontroller uid 85
nicl . -createprop /users/xgridcontroller gid 85
nicl . -createprop /users/xgridcontroller passwd '*'
nicl . -createprop /users/xgridcontroller change 0
nicl . -createprop /users/xgridcontroller expire 0
nicl . -createprop /users/xgridcontroller realname 'Xgrid Controller'
nicl . -createprop /users/xgridcontroller home '/var/xgrid/controller'
nicl . -createprop /users/xgridcontroller shell '/usr/bin/false'
nicl . -createprop /users/xgridcontroller _writers_passwd 'xgridcontroller'
echo "niutil: User 'xgridcontroller' added."
fi
# add the xgridcontroller group
nicl . -read /groups/xgridcontroller >/dev/null 2>&1
if [ $? != 0 ] ; then
nicl . -create /groups/xgridcontroller
nicl . -createprop /groups/xgridcontroller gid 85
nicl . -createprop /groups/xgridcontroller passwd '*'
echo "niutil: Group 'xgridcontroller' added."
fi
echo "Validation and creation of system users completed"
if [ $NEEDTOREBOOT = 1 ] ; then
# this is almost certainly the first reboot after an update
# from 10.3 to 10.4… should run radmind to amke sure we
# have all needed files
echo "Running radmind"
/usr/local/radmind/scripts/radmindNow
echo "System reboot required"
USER=`who | grep console`
if [ "$USER" = "" ] ; then
/sbin/shutdown -r now
else
/usr/bin/osascript -e 'tell application "System Events" to restart'
fi
fi
exit 0
Pretty neat script Greg. I have something very similar I wrote in Python but for dscl. I will post it for you when I am done.
The vast majority of the script is just a cut-and-paste job from a couple of post-upgrade scripts that are part of the Tiger install metapackage. This way – whatever the script does, it should be identical to what happens if you use Apple’s Installer to upgrade to Tiger. I don’t have to do a lot of testing or debugging.
Nice script indeed Greg 🙂
Just a small WP tip, use the more tag to keep your post to a minimum and have the largest part on a separate post page. There’s just to much scrolling on the first page 🙂
Greetz M
Thanks. Michael. I added the
Ouch. I guess it’s dangerous to add the more tag to a comment! Anyway, I added the more tag.
Any tips on working wiht code in WordPress posts? WordPress’s editor really wants to mangle it.