September 28, 2009

Use Snow Leopard’s Built-In VPN Client to Access the ITCom VPN

DISCLAIMER: This post has not been authored by ITCom and any change they make to their VPN systems may break this.

Instead of using the Cisco VPN client to access the ITCom VPN, you can use Snow Leopard’s built-in VPN client to do so. Here are the steps involved:

  1. Open the Network preference pane in System Preferences.
  2. Click the plus sign to add a new network interface.
    • For Interface, select VPN.
    • For VPN Type, select Cisco IPSec
    • Write a descriptive description.
  3. Navigate to the ITCom page to download the desired VPN profile (either off-campus or on-campus).
  4. Viewing the profile as a text file, you can see key-value pairs with the format KEY=VALUE.
  5. Back in the Network preference pane, select your newly-created VPN. Set the following values:
    • Server Address: set to the Host value in the profile.
    • Account Name: set to your uniqname.
    • Password: set to your Kerberos password (though you'll still need to enter it upon connecting).
  6. Click “Authentication Settings...”. Set the following settings:
    • Shared Secret: set to the GroupPwd value in the profile.
    • Group Name: set to the GroupName value in the profile.

Connect to the VPN and you’ll be able to access campus resources from home.

Posted by slauncha at 10:48 AM | Comments (8) | TrackBack

July 17, 2009

Disable Safari 4's Welcome Video (Mac OS X)

If you're deploying Safari 4 into a lab setting, you probably don't want users seeing the welcome video when they launch Safari for the first time. To prevent this from occurring, simply set the following preference for the com.apple.Safari domain (as a string): LastDisplayedWelcomePageVersionString = "4.0".

If you're using MCX, that should be all you need to do. If you're using Radmind, the easiest way to propagate that setting (aside from local MCX) is to write it to /Library/Preferences/com.apple.Safari.plist with the defaults command.

In XML format, the plist should look like this:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>LastDisplayedWelcomePageVersionString</key>
<string>4.0</string>
</dict>
</plist>

Posted by slauncha at 03:41 PM | Comments (0)

February 19, 2009

Matlab FlexLM license

The Matlab FlexLM license file on Mac clients can

1) use a cname and

2) does not appear to require the MAC address of the license server in the config line.

/Applications/MATLABver/licenses/network.lic:

SERVER license-server.x.x.x.x 27000
USE_SERVER

done.

Posted by rdevine at 11:32 AM | Comments (0)

January 06, 2009

A LaunchAgent to Make the Extended Print Dialog Appear by Default

There’s a good tip over at TUAW for making the extended print dialog show up by default, but I wanted to make sure that it applied to every user at login so we’d stop having users confused by the minimal approach to the standard dialog. So, I wrote the following LaunchAgent:





	Label
	edu.umich.printdialog.default.extended
	ProgramArguments
	
		/usr/bin/defaults
		write
		-g
		PMPrintingExpandedStateForPrint
		-bool
		TRUE
	
	RunAtLoad
	

Because the Label string is edu.umich.printdialog.default.extended, the plist is written to /Library/LaunchAgents/edu.umich.printdialog.default.extended.plist.

Posted by slauncha at 11:07 AM | Comments (0) | TrackBack

December 18, 2008

A Shell Script to Randomize Your Computer's Wake Time

Lately, we’ve been exploring the option of having our computers sleep after some idle time. One of our concerns was our nightly maintenance window; we wanted our computers to wake up in the middle of the night, but we didn't want to have them all wake up at exactly the same time. So, I wrote this script to randomize the time at which they wake up nightly:


#!/bin/sh

# a script to randomize the computer's wake time

pmset=`whereis pmset`
type=wakeorpoweron
days=MTWRFSU

# The maximum number of seconds past 3:15 AM to wake up.
maxsleep=5400

# Randomize the number of seconds.
sleeptime=`perl -e 'srand (time ^ $$ ^ unpack "%L*", \` ps axww | gzip\`);\
        print int(rand( $ARGV[0] ));' $maxsleep`

# Default time to wake up is 3:15 AM.
hours=3
minutes=15
seconds=0

# Convert the number of seconds into hour, minutes, seconds

# Subtract hours.
while [ $sleeptime -gt 3599 ]
do
        # At least 1 hour.
        let "hours += 1"
        let "sleeptime -= 3600"
done

# Subtract minutes.
while [ $sleeptime -gt 59 ]
do
        # At least 1 minute.
        let "minutes += 1"
        if [ $minutes -gt 59 ]
        then
                let "hours += 1"
                let "minutes -= 60"
        fi
        let "sleeptime -= 60"
done

seconds=$sleeptime


# Convert to xx:xx:xx format

if [ $hours -lt 10 ]
then
        tmp=$hours
        hours="0${tmp}"
fi

if [ $minutes -lt 10 ]
then
        tmp=$minutes
        minutes="0${tmp}"
fi

if [ $seconds -lt 10 ]
then
        tmp=$seconds
        seconds="0${tmp}"
fi

fulltime="${hours}:${minutes}:${seconds}"

${pmset} repeat ${command} ${type} ${days} ${fulltime}

Posted by slauncha at 04:55 PM | Comments (0)

October 06, 2008

Use Radmind to Manage Shared Dynamic Libraries

Mac OS X Leopard stores shared dynamic libraries at /private/var/db/dyld/. These files are updated via the update_dyld_shared_cache command. If they aren’t present, then applications will be unable to use the shared libraries, increasing virtual memory use and decreasing overall performance. When managing multiple architectures with Radmind, however, this becomes problematic. On a new, Intel Core 2 Duo system, you see this output:

root# ls -1 /var/db/dyld/
dyld_shared_cache_i386
dyld_shared_cache_i386.map
dyld_shared_cache_rosetta
dyld_shared_cache_rosetta.map
dyld_shared_cache_x86_64
dyld_shared_cache_x86_64.map
shared_region_roots

Whereas on an older, PowerPC-based system, you see this output:

root# ls -1 /var/db/dyld/
dyld_shared_cache_ppc
dyld_shared_cache_ppc.map
dyld_shared_cache_ppc64
dyld_shared_cache_ppc64.map
shared_region_roots

Without being properly managed, you may see error messages in the system log as follows:

Jun 26 14:50:04 slc48 com.apple.dyld[354]: update_dyld_shared_cache[354] for arch=ppc failed: /var/db/dyld/shared_region_roots/ does not exist, errno=2

To properly manage this with Radmind, you should do the following:

This will allow your systems to remain up-to-date and still allow you to manage them through Radmind.

Posted by slauncha at 04:41 PM | Comments (0) | TrackBack

July 29, 2008

Customize Firefox’s Default Profile Without Creating One

We recently ran into problems with our default Firefox profile after upgrading to Firefox 3. Before, we’d defined a default profile in the default user’s ~/Library/Application Support/Firefox/Profiles folder, set it up to have the settings and homepage we desired, and let that copy into a new user’s profile on login. After having some problems with some of the settings that restricted extension installation, we discovered a way to define defaults for Firefox without having to pre-create a user’s profile. There are a few files to change in the application bundle that cause it to work as we’d like:

Your needs may vary, and you can do a lot more inside the application bundle, such as putting extensions in the /Applications/Firefox.app/Contents/MacOS/extensions folder. Putting default settings here has two main advantages over putting it in the default user profile:

  1. Firefox profiles are only created as needed. Not copying over a default profile reduces login time, and users who use Safari will never need a Firefox profile.
  2. Using a default profile, all profiles have the same name (e.g. ~/Library/Application Support/Firefox/Profiles/m6oj7kr0.default/). The method I’ve outlined in this post results in differently-named Firefox profiles. I have no idea if this is an advantage, but Firefox’s developers randomize the profile folder name for a reason, and this method preserves their methodology.

Update 8/5/08: Added application.ini info.

Posted by slauncha at 03:03 PM | Comments (1) | TrackBack

July 08, 2008

Prune old transcripts with tkpruner

One of the things we’ve noticed is that since we sync out our loadsets to several servers around campus, we’re wasting time syncing old loadsets that aren’t in use anymore. Even with rsync, the files need to be compared. So, to that end, I wrote a script I call “tkpruner? that walks the config file of a Radmind server, finds the loadsets that are in use, and backs everything else up to ~/transcript/obsolete and ~/file/obsolete. It also backs up unused command files, moving them to ~/command/obsolete. Everything the script backs up is timestamped: ~/transcript/foo/bar/FooBar.T would become ~/transcript/obsolete/FooBar.20080708.T if I backed it up today.

Using this script, we can automate the archival process for old transcripts. Our obsolete folder isn’t included in syncs, and it’s located on a RAID array, so we aren’t concerned about data loss, merely with ensuring that our satellite servers have the transcripts that are in use.

Here’s the script:

#!/bin/bash

##
# Walk the config file and move unused transcripts to ~/transcript/obsolete
##

# Declarations
RadmindFolder="/var/radmind"
configfile="${RadmindFolder}/config"
ExcludeFile="${RadmindFolder}/etc/tpruner.exclude"
TranscriptFolder="${RadmindFolder}/transcript"
CommandFolder="${RadmindFolder}/command"
ObsoleteTFolder="${TranscriptFolder}/obsolete"
ObsoleteKFolder="${CommandFolder}/obsolete"

# Subroutines
processconfig(){
        for x in `cat "$configfile" | grep -v "#" | awk '{ print $2 }'`; do
                isinkarray=0

                for command in ${karray[@]}; do
                        if [ "$command" == "${CommandFolder}/$x" ]; then
                                isinkarray=1
                                continue
                        fi
                done

                if [ $isinkarray == 0 ]; then
                        karray[${#karray[@]}]="${CommandFolder}/$x"
                        processk "${CommandFolder}/$x"
                fi
        done
}

processk(){
        for x in `cat $1 | awk '{ if ($1=="p" || $1=="n") print $2 }'`; do
                isintarray=0

                for transcript in ${tarray[@]}; do
                        if [ "$transcript" == "${TranscriptFolder}/$x" ]; then
                                isintarray=1
                                continue
                        fi
                done

                if [ $isintarray == 0 ]; then
                        tarray[${#tarray[@]}]="${TranscriptFolder}/$x"
                fi

        done

        for x in `cat $1 | awk '{ if ($1=="k") print $2 }'`; do
                isinkarray=0

                for command in ${karray[@]}; do
                        if [ "$command" == "${CommandFolder}/$x" ]; then
                                isinkarray=1
                                continue
                        fi
                done

                if [ $isinkarray == 0 ]; then
                        karray[${#karray[@]}]="${CommandFolder}/$x"
                        processk "${CommandFolder}/$x"
                fi

        done
}

evald(){
        cd $1

        for transcript in `ls | grep \\\\.T`; do
                if [ -f $transcript ]; then
                        evalt "`pwd`/$transcript"
                fi
        done

        for command in `ls | grep \\\\.K`; do
                if [ -f $command ]; then
                        evalk "`pwd`/$command"
                fi
        done

        for file in `ls | grep -v \\\\.T`; do
                if [ -d $file ]; then
                        directory="`pwd`/$file"
                        if [ "`grep $directory "$ExcludeFile"`" == "" ]; then
                                evald "$directory"
                        fi
                fi
        done

        cd ..
}

evalt(){
        isintarray=0

        for transcript in ${tarray[@]}; do
                if [ "$transcript" == "$1" ]; then
                        isintarray=1
                        continue
                fi
        done

        if [ $isintarray == 0 ]; then
                ttomovearray[${#ttomovearray[@]}]="$1"
        fi
}

evalk(){
        isinkarray=0

        for command in ${karray[@]}; do
                if [ "$command" == "$1" ]; then
                        isinkarray=1
                        continue
                fi
        done

        if [ $isinkarray == 0 ]; then
                ktomovearray[${#ktomovearray[@]}]="$1"
        fi
}

movet(){
        Transcript=$1
        TranscriptNoPath="`echo $Transcript | awk 'BEGIN { FS = "/" } { print $NF }'`"
        TranscriptNoEnding="`echo $TranscriptNoPath | sed -e \"s/\.T//\"`"
        Today="`date +%Y%m%d`"
        Target="${ObsoleteTFolder}/${TranscriptNoEnding}.${Today}.T"

        mv $1 $Target

        sourcefiledir="`echo $1 | sed -e \"s/\/var\/radmind\/transcript/\/var\/radmind\/file/\"`"
        targetfiledir="`echo $Target | sed -e \"s/\/var\/radmind\/transcript/\/var\/radmind\/file/\"`/"

        mv $sourcefiledir $targetfiledir
}

movek(){
        Command=$1
        CommandNoPath="`echo $Command | awk 'BEGIN { FS = "/" } { print $NF }'`"
        CommandNoEnding="`echo $CommandNoPath | sed -e \"s/\.K//\"`"
        Today="`date +%Y%m%d`"
        Target="${ObsoleteKFolder}/${CommandNoEnding}.${Today}.K"

        mv $1 $Target
}

# Initiate the array.
processconfig

# Walk the filesystem.
evald "$TranscriptFolder"
evald "$CommandFolder"

echo The following will be backed up:
echo "${#ktomovearray[@]} command file(s)"
echo "${#ttomovearray[@]} transcript(s)"
echo
echo "(R)eview changes, (A)pply changes or (C)ancel?"

read response

if [ "$response" == "R" -o "$response" == "r" ]; then
        echo "Command file(s) to back up:"
        for x in `jot ${#ktomovearray[@]} 0`; do
                echo "  ${ktomovearray[$x]}"
        done

        echo

        echo "Transcript(s) to back up:"
        for x in `jot ${#ttomovearray[@]} 0`; do
                echo "  ${ttomovearray[$x]}"
        done

        echo
        echo "(A)pply changes or (C)ancel?"

        read response
fi


if [ "$response" == "A" -o "$response" == "a" ]; then
        for x in `jot ${#ktomovearray[@]} 0`; do
                movek "${ktomovearray[$x]}"
        done

        for x in `jot ${#ttomovearray[@]} 0`; do
                movet "${ttomovearray[$x]}"
        done
fi

exit 0

Posted by slauncha at 10:06 AM | Comments (0) | TrackBack

June 23, 2008

Leopard Site-Wide

Mac OS X 10.5 “Leopard? has been deployed site-wide.

Posted by slauncha at 05:19 PM | Comments (0)

June 03, 2008

Union and Consultant Workstation Leopard deployment

We upgraded the Union Mug (cyber) and Union Tap (full-use) workstations to Leopard today. We also upgraded the Angell Hall and SEB consultant workstations and very much look forward to user-feedback as we proceed with our site-wide Leopard deployment for Summer term.

Posted by rdevine at 10:17 PM | Comments (0)

May 22, 2008

Quick script to back up a transcript

I was sick of writing lmerge /path/to/transcript.T /dev/null ~/transcript/obsolete/transcript.timestamp.T every time I wanted to back up a transcript before making a change, so I wrote a quick script to back up a transcript to a timestamped file:

#!/bin/bash

# Backs up a transcript to ~/transcript/obsolete

Transcript=$1
TranscriptNoPath="`echo $Transcript | awk 'BEGIN { FS = "/" } { print $NF }'`"
TranscriptNoEnding="`echo $TranscriptNoPath | sed -e \"s/\.T//\"`"
Today="`date +%Y%m%d`"
Target="/var/radmind/transcript/obsolete/${TranscriptNoEnding}.${Today}.T"

/usr/local/bin/lmerge -I $Transcript /dev/null $Target

Just change “/var/radmind/transcript/obsolete/? to whatever folder you want to use.

Posted by slauncha at 11:40 AM | Comments (0) | TrackBack

Set Hostname to Network-Supplied Hostname

Nobody wants their production machines to have hostnames like “Sites’ iMac.? To get around this issue, we created a script called HostNamer to find the hostname and set it. Under Tiger, we got away with calling hostname -s, but under Leopard this would often return the current hostname, not the desired one. So, we created a script to look at the DNS entry for the computer's IP address.

#!/bin/bash

# HostNamer - Gets proper hostname from server and tells OS X to use it.

PATH=/bin:/usr/bin:/usr/sbin:/sbin:/usr/local/bin; export PATH

get_ip(){
        IPADDR="`/sbin/ifconfig en0 | awk '{ if ( $1 == "inet" ) print $2 }'`"
        IPBEGIN="`echo ${IPADDR} | awk '{ split($1, a, "."); print a[1] }'`"
}

# Get IP address.
get_ip

# Make sure that IP is valid (i.e. starts with "141.")  If not, wait and try again.
# Will only try 10 times.
count=0

while [ "${IPBEGIN}" != "141" ]; do
        let "count += 1"
        echo $count
        if [ $count -gt 10 ]; then
                logger -is Failed to get correct IP address.
                exit 1
        fi

        sleep 10

        get_ip
done

HOSTNAME="`host ${IPADDR} | awk ' { for ( x = 1; x < 20; x++ ) if ( $x == "pointer" ) print $(x+1) }' | awk '{ split($1, a, "."); print a[1] }'`"

scutil --set ComputerName "${HOSTNAME}"
scutil --set LocalHostName "${HOSTNAME}"
scutil --set HostName "${HOSTNAME}"

# Now, rename the disk.

# Get the correct disk name to use
DiskName="`diskutil list | grep -m 1 Apple_HFS | awk '{ print $NF }'`"

diskutil rename $DiskName $HOSTNAME

The portion that checks for a correct IP (for us, 141) is there because on Intel-based Macs, we noticed that the script was called before the network was up—we’re running it via a StartupItem. We also created a link to this script in our Radmind post-apply folder, so the system will be renamed before rebooting. That way, it comes up with its correct name. Finally, we rename the hard disk to the hostname to allow for easy identifiation of in-use computers.

Posted by slauncha at 09:56 AM | Comments (0)

May 19, 2008

Angell Hall Cyberstation - Color Printing fix

We will be deploying the 'pstoxeroxps' client-side cups filter to the Angell cyberstations this evening to resolve the Xerox 7400 Color Phaser 'paused' queue printing issue we identified last week. Both the 'pstophaserps' and 'pstoxeroxps' filters are noted dependencies in the Xerox PPDS.

Posted by rdevine at 04:30 PM | Comments (0)

Angell Hall Fishbowl Cyber - Leopard Deployment

We have deployed our Leopard loadsets to the Angell Hall Fishbowl cyberstations this afternoon. These machines will be upgrading to leopard on next user logout or nightly maintenance session, whichever should occur first.

Posted by rdevine at 04:18 PM | Comments (0)

May 15, 2008

Angell Hall Cyberstation - Leopard Deployment

As part of our Leopard migration process, we upgraded the Angell Hall Cyberstations (stations 3-28) to Leopard today. Pending feedback, we plan to upgrade the Angell Fishbowl cyberstations and the Angell Hall/SEB consultant workstations with our full-use Leopard offering within the next few days. Currently, the Angell Hall Color printer is not functioning properly in the Angell Cyberstation loadset and we are currently working on this issue. Enjoy!

Posted by rdevine at 07:58 PM | Comments (0)

May 07, 2008

Using iHook in Leopard Over the Login Window

After upgrading a station to Leopard, we recently noticed that our nightly script that starts our Radmind scripts (using iHook) was failing. Upon looking at the logs I realized that this was because of one of Leopard’s new security features: applications cannot open a GUI window over the login window without both being written specifically to do that and being called from a LaunchAgent. iHook version 1.1.1 is compatible with running this way, so the only thing one needs to do is create a LaunchAgent to do so. This thread from the Radmind Users mailing list illustrates this, with a sample LaunchAgent plist.

Posted by slauncha at 03:42 PM | Comments (0) | TrackBack

April 29, 2008

Using Chroot to Update the Kernel

One of the biggest problems with using Radmind to manage your systems instead of an imaging utility, despite all of Radmind’s advantages, is updating the kernel. You can’t just update the kernel and reboot; trying to reboot will result in a “Bad system call” error. In fact, trying to do anything after updating the kernel will result in an error. So how can you go from, say, Tiger to Leopard without hand-rebooting the computer once lapply finishes? The answer lies in the chroot utility. Using chroot, you can make a copy of your system's kernel and run from that instead of the regular kernel. Here’s how to set it up:

  1. Create a directory for the chroot “jail” in some directory that’s in your Radmind negative so it doesn’t get overwritten. I recommend creating a subdirectory of /tmp for this.
  2. Determine which tools you need to copy to the fake kernel system. For our script, we use the following:
    • /bin/bash
    • /bin/sh
    • /bin/ps
    • /sbin/reboot
    • /usr/bin/grep
  3. Using otool, figure out which dependencies these tools have. otool requires Apple's Developer Tools to be installed.
  4. Recreate the directory structure in your chroot jail folder for all the tools and their libraries and copy them into it. You will also need these system components:
    • /usr/lib/dyld
    • /usr/lib/system/libMathCommon.A.dylib
  5. Now that you’ve gotten the chroot jail set up, you can use it to watch lapply. Run lapply as usual after running ktcheck and fsdiff, but run it as a background process (e.g. lapply -your -options -here &).
  6. Use chroot to change your root directory to your chroot jail. From the jail, you can use ps to view the running processes (use ps -A to view all users’ processes).
  7. Once lapply is done, use your protected copy of reboot to reboot the system, and you're all set to run with the new version of the kernel.

Note: You need to be careful with your negative transcripts when you go from OS to OS. If something in the operating system needs to be in the negative (such as /dev or, in Leopard, /Network) isn’t in the new negative, you can run into errors in either your fsdiff or lapply steps.

Scripting examples of this after the jump.

So let’s say you want to add something into your Radmind scripts to automatically set up a chroot space when your system needs to be updated. The ideal script will have the following attributes:

To do this, we added a preapply script to run on the transcript that fsdiff creates:

#!/bin/sh

# chroot logic for kernel updates
# requires script to test passed as $1

# uses the following tools:
#  /bin/bash
#  /bin/sh
#  /bin/ps
#  /sbin/reboot
#  /usr/bin/grep

# and the following for chroot:
#  /usr/lib/dyld
#  /usr/lib/system/libmathCommon.A.dylib

# declarations
toolList="/bin/bash /bin/sh /bin/ps /sbin/reboot /usr/bin/grep /bin/sleep /bin/t
est"
dependencyList="/usr/lib/dyld /usr/lib/system/libmathCommon.A.dylib"
markerFile="/tmp/.chrootlogicneeded"
searchList="/mach_kernel"
chrootJailLocation="/tmp/chrootjail"

# if otool exists, use that to dynamically generate a list of dependencies
# use a pre-made list if it doesn't
if [ -x "/usr/bin/otool" ]; then
   for x in ${toolList}; do 
      for y in `otool -LX $x | awk '{ print $1 }'`; do 
         dependencyList="${dependencyList} $y"; 
      done; 
   done
else
   dependencyList="/usr/lib/dyld /usr/lib/libgcc_s.1.dylib /usr/lib/libiconv.2.d
ylib /usr/lib/libncurses.5.4.dylib /usr/lib/libSystem.B.dylib /usr/lib/system/li
bmathCommon.A.dylib"
fi

for x in `for y in ${toolList} ${dependencyList}; do echo $y; done | sort -fu`; 
do 
   searchList="${searchList} $x"; 
done

if [ "`for x in ${searchList}; do grep "$x" "$1"; done`" != "" ]; then 
   touch "${markerFile}"; 

   mkdir -p ${chrootJailLocation}/usr/lib/system
   mkdir -p ${chrootJailLocation}/bin
   mkdir -p ${chrootJailLocation}/sbin
   mkdir -p ${chrootJailLocation}/usr/bin

   for x in ${searchList}; do
      ditto $x ${chrootJailLocation}$x
   done
fi

Now, all you need is a portion of your Radmind script that looks for the marker file and, if it exists, runs lapply in the background. Set up another script to reboot the computer when lapply finishes:

#!/bin/sh

# reboots the system from a protected location after lapply finishes

while [ "`ps -A | grep lapply | grep -v grep`" != "" ]; do
   sleep 60
done

/sbin/reboot

After you run lapply in the background, run this script from your chroot space with the following command: “chroot /path/to/chroot/space /bin/sh path/to/command.” Note that the path to the script is relative to the location of your chroot jail, so you’ll have to copy it into the folder.

Posted by slauncha at 09:59 AM | Comments (0) | TrackBack

April 24, 2008

Using dscl to Create New Users and Groups in Leopard

It's of course possible to create a new user in Apple's System Preferences (under the "Accounts" pane), but if you want more control over your new user, the dscl command comes in handy. Under Leopard, here is the code to create a new user:

dscl . -create /Users/newusername (This creates the user's entry in the local database)
dscl . -create /Users/newusername UserShell /bin/bash
dscl . -create /Users/newusername RealName "New User's Real Name"
(This is the user's full name for display at login, etc.)
dscl . -create /Users/newusername UniqueID 503 (The standard behavior is to use number 50X, where X is the lowest available number. The account you create when you set up a new Mac is always user 501.)
dscl . -create /Users/newusername PrimaryGroupID 20
dscl . -create /Users/newusername NFSHomeDirectory /path/to/user/folder
(Apple's Tiger documentation explains that though this is named NFSHomeDirectory, it can be used for local folders.)
passwd newusername (This sets the password).

Now your new user should be all set up.

If you're using Radmind, you'll want to include these files in a transcript:

Posted by slauncha at 10:55 AM | Comments (0) | TrackBack

March 28, 2008

Installing IPP Printers from the Command Line in Mac OS X

We've rolled out some scripts for departments using our IPP printers that install these printers via the command line. I thought I'd share the syntax in case anyone else needs to do this. First, you need to install the driver (obviously) and get the .PPD for the printer. Then, use the lpadmin command:

lpadmin -p "Printer_Name" -v "ipp://some.print.server.here:port/path/to/printer" -D "Printer Name" -E -P "/path/to/ppd"

That will install the printer as an IPP printer using the specified PPD.

Posted by slauncha at 02:08 PM | Comments (0) | TrackBack

March 25, 2008

Office 2008

We've prepared Office 2008 transcripts for testing. We still need to make default user profiles and re-do applications that hook in to Office (Adobe Acrobat, EndNote, etc.) to work with the new version, but we should have a finished version for Spring semester.

Posted by slauncha at 11:44 AM | Comments (0)

Fragmentation Bug in Disk Utility and Boot Camp Assistant

We've noticed a bug in Disk Utility and Boot Camp Assistant in 10.5.2. When trying to shrink a volume without reformatting it, if there are file fragments at the end of the volume, Disk Utility will fail, with an error message reporting "not enough free space." Using Boot Camp Assistant to shrink the volume will result in a kernel panic as the underlying shrinking process fails.

The workaround for this issue is as follows: boot the Mac into target disk mode, connect it to another Leopard-based Mac, and make a backup image from the drive. Erase the drive and apply the newly created backup image to it, effectively defragmenting it, and you will be able to shrink the partition without error.

Posted by slauncha at 11:39 AM | Comments (0)

March 05, 2008

Leveraging NetBoot for Mac OS Kernel Updates

One of the things that have troubled us in the past has been using Radmind for major OS updates. If the kernel is updated, or if /System/Library/CoreServices/BootX is touched, Radmind can fail to update the loadset and in some cases our scripts won't reboot the station. In our transition from 10.3 to 10.4, we had student employees rebooting stations across campus after their Radmind session finished. Looking forward to the 10.4 to 10.5 transition, I think I'm going to develop a set of scripts to get around this issue. Here's how it'll work:

  1. After fsdiff runs, a pre-apply script checks the difference transcript against a list of items that may break the update (e.g. mach_kernel and BootX).
  2. If one of those items is present, it touches a file that acts as a flag (maybe /var/radmind/client/.UpdateSystemFiles). Then it sets the default boot behavior to our NetBoot image.
  3. The NetBoot image, upon detecting the file on the hard drive, runs ktcheck to get the proper command file for the hostname. It checks the version of the OS contained in the command file (using the transcripts' names) against the version of the OS currently on the hard drive. If there's a major discrepancy, such as 10.4 to 10.5 (really, anything that would use a different negative), it will apply an ASR image to the hard drive.
  4. The NetBoot image runs a Radmind session (thanks to relative paths) on the hard drive, updating the kernel and other sensitive files as necessary.
  5. The computer reboots, and has been updated without any user interaction.

This method will allow us not only to deploy 10.5 to stations running 10.4, but also to deploy future system updates. Say 10.5.3 updates the kernel, for instance. It'll probably take a while for this to all come into place, but it will set the groundwork for making our lives a lot easier.

Posted by slauncha at 03:32 PM | Comments (0) | TrackBack

March 04, 2008

Mac Kernel Panics

Recently we've been having strange problems where some of our Macs, after having an ASR image applied to them, show a kernel panic and complain that they can't find drivers for their hardware types. We've noticed this on PowerMac G5s and iMac G5s. Though we're not sure why these errors are suddenly occurring, we're working to identify and resolve the issue.

Update: We discovered that the reason these Macs were having a kernel panic had to do with the ASR image. When I updated the NetBoot server to accommodate the pains of the aluminum iMacs, I noticed that the NetBoot image was pointing to an older ASR image. I changed it to the new one and we never noticed a problem until this week when certain PowerPC-based Macs started panicking on boot. I changed the old NetBoot image back to pointing to the old ASR image, and now everything is happy again.

Posted by slauncha at 10:04 AM | Comments (0)

February 29, 2008

OpenAFS 1.4.6 upgrade

We have recently upgraded to OpenAFS 1.4.6 over spring break. After not having received any further reports of cache code of Finder crashing problems in OpenAFS 1.4.5, we are optimistic that the the improved reliability will continue with OpenAFS 1.4.6.

Posted by rdevine at 02:30 PM | Comments (0)

MS Office 2008 for Mac installer issues

Should you install Office 2008 for Mac on your personally managed machines, please beware that there are some known issues/problems with the installer that will result filesystem permissions problems.

We thought this installer issue was going to be resolved by the time we received our official distribution media, but this is unfortunately appears to not be the case. Consequently, you may encounter font problems and issues with other programs with font dependencies until you manually correct/repair some filesystem permissions.

For further info, you can check out the following articles:

http://www.macworld.com/article/131822/2008/01/office2008issues.htm
http://www.officeformac.com/blog/Security-issue-in-Mac-Office-2008-Installerl

Update: These articles are currently unavailable.

We do not anticipate this being an issue in our Mac loadsets because we will manually correct any inappropriate filesystem permissions that have gone awry via Microsoft's installer prior to its site-wide deployment.

Posted by rdevine at 01:10 PM | Comments (0)

February 28, 2008

Logout hooks vs. Startup Items

On Intel machines, we've had some difficulties with our startup items. Things like our print monitor pages, our HostNamer script that changes the machine's hostname, and the aforementioned SPSS License Activator don't run at startup, as they're run before the network is available. No matter what you do in the script—sleep, ping servers, etc.—any operation that depends on the network may not complete on an Intel Mac. To get around this, we've been making logout hooks that run these startup items, ensuring that they complete with network connectivity.

Posted by slauncha at 02:31 PM | Comments (0)

February 20, 2008

Printer Transcripts

I recently moved all of our printer transcripts from ~/transcript/ to ~/transcript/mac/ccs/printers in an effort to clean up ~/transcript/. I also ensured that they were all using the most up-to-date PPDs, as all of our sites now have HP 4350s. Many of the transcripts still contained 4300 (or even 8150!) PPDs from the past.

Posted by slauncha at 04:57 PM | Comments (0)

Using NetBoot with Aluminum iMacs

We deploy our Mac loadset using Radmind, but to get a base image onto a new computer, we use a combination of NetBoot and Apple Software Restore. A station boots to the NetBoot server and then applies an ASR-ready disk image to the station's hard drive, which is then booted to for Radmind. We noticed that none of the new aluminum iMacs would boot to the NetBoot server, even though older Intel-based iMacs had done so just fine. Initially thinking that this was due perhaps to changes in hardware, we tried to create a new NetBoot image that would boot all of our Macs, but to no avail. Eventually, we stumbled upon some Apple documentation of the problem.

The solution in this case was to re-create the NetBoot image from scratch, since we don't want to upgrade it to Leopard yet. I re-installed OS X 10.4.11 on an aluminum iMac from the CDs it shipped with, then configured it with our NetBoot configuration. I used Mike Bombich's NetRestore software to create the new NetBoot image, and set it up on our NetBoot server to only apply to aluminum iMacs.

We now have two NetBoot images: one for aluminum iMacs, one for everything else. When we upgrade to Leopard, we'll be able to make one image that will boot all of our computers (unless, of course, this type of thing occurs with whatever Apple's next hardware upgrade is).

Our custom NetBoot build is as follows: there is a local user account set to log in automatically on startup. When that user logs in, a login hook runs an in-house program, NetBoot Assistant, which presents a menu and does not quit without a password. The default menu option restores the ASR image to the hard drive, then boots to the drive.

Posted by slauncha at 04:40 PM | Comments (0)

February 15, 2008

Fixing Server Monitor on 10.5.2 Non-Server Clients

With the release of 10.5.2, Server Monitor doesn't work on an upgraded non-server Mac. To get the new version of Server Monitor, you need a server that's been updated to 10.5.2. Then, it's a matter of copying the files. You need both the Server Monitor application and the IPMI tool. Use the following commands on the non-server Mac:

sudo scp -pr userwithaccess@someserver.institution.edu:/Applications/Server/Server\\\ Monitor.app /Applications/Server/
sudo scp -pr userwithaccess@someserver.institution.edu:/usr/bin/ipmitool /usr/bin

More information can be found on Apple's website.

Posted by slauncha at 09:40 AM | Comments (0)

January 29, 2008

SPSS 16 Site License Activation

Having a site license instead of a network license for SPSS 16, we found it difficult to deploy, since each computer must have its own unique activation code in order to use the software. With 900 computers, no one wants to activate all of them by hand. To that end, we pursued a way of activating it without manually touching the computer. After some e-mails with our on-campus SPSS support representative, we found that the spssactivator.jar file that came on our media does not support running non-interactively. We downloaded a new version from SPSS, which works quite well. By creating a StartupItem that activates the product, we're able to license each of our machines without going around and doing them by hand.

The first step in setting this kind of thing up when you're using Radmind is to identify where the license is stored. In this case, it's /Applications/SPSSInc/SPSS16/SPSS16.0.app/Contents/bin/lservrc. (Note: this is the default installation directory. Yours may vary.) By creating a negative file with this line in it:

f ./Applications/SPSSInc/SPSS16/SPSS16.0.app/Contents/bin/lservrc 0644     0    80 1201558821       0 2jmj7l5rSw0yVb/vlWAYkK/YBwk=

we can tell Radmind to ignore the contents of that file. (Note: if the file does not exist, Radmind will create it, but it will be empty.) Then in our StartupItem, we check to see if that file has data in it, and if not, we run the activation command. Here is our StartupItem:

#!/bin/sh

##
# Activate SPSS 16 site license
# The license is stored in the file lservrc
##

. /etc/rc.common

workingfolder="/Applications/SPSSInc/SPSS16/SPSS16.0.app/Contents/bin"
licensefile="/Applications/SPSSInc/SPSS16/SPSS16.0.app/Contents/bin/lservrc"
jarfile="/Applications/SPSSInc/SPSS16/SPSS16.0.app/Contents/bin/spssactivator.jar"
authcode=
spssserverport=80
spssserver=lm.spss.com
logfile="/private/var/log/spssactivator.log"

StartService ()
{
    if [ -s "$workingfolder/lservrc" ]; then
            # since the file already exists and has data, don't do anything
            exit 0
    else
            # first, do some pinging to ensure network connectivity
            ping -c 10 $spssserver

            # activate the license with SPSS.  Must be done from this folder.
            cd $workingfolder
            java -jar $jarfile CONSOLEMODE codes=$authcode proxyport=$spssserverport proxyhost=$spssserver > $logfile 2>&1
    fi

    # ensure that the license code isn't readable by users
    chmod 700 $logfile
}

StopService ()
{
    return 0
}

RestartService ()
{
    return 0
}

RunService "$1"

Our activation code (not displayed here for security reasons) is after authcode=.

Posted by slauncha at 03:41 PM | Comments (0) | TrackBack

January 24, 2008

Revamping the Print Queue Monitors

We had been having problems with our print queue monitors recently, the most common of which being that the display, instead of being the print queue, was a blank white screen. To fix this, we changed how they display. Before, there was a local user, printmonitor, which would log in and start the program Teremok, a kiosk browsing application. Now, instead of there even being a printmonitor user, there is a StartupItem that launches Teremok, giving us both more reliability and the added security of a user actually being logged in.

The first problem that this resolves is that the print monitors weren't receiving nightly updates. This was a side effect of the way the printmonitor user logged in: /Library/Preferences/loginwindow.plist specified that it should login automatically. So, when the system started up, LoginWindow started and printmonitor logged in. The nightly radmind script includes this portion:

if who | grep console > /dev/null; then
    logger -si -t $0 User logged in, radmind session will begin on next logout.
    exit 0
fi

So, since printmonitor was always logged in, this script never ran. The solution that was in place was a daily script that ran before the radmind script:

#! /bin/sh

# kill the loginwindow so the radmind.hook will run

PATH=/bin:/usr/bin; export PATH

logger -i -t $0 Killing loginwindow...
killall loginwindow 2> /dev/null

# give the loginwindow a chance to relaunch
sleep 30

exit 0

This script had the effect of killing loginwindow, which woulld of course restart loginwindow. As loginwindow restarted, it read /Library/Preferences/loginwindow.plist and logged the user printmonitor in, which then started Teremok. Then the radmind script ran and detected a user logged in, so it failed to run. So on and so forth until the end of time–one of the print monitors I updated had an uptime of 156 days.

The fix for this was creating a StartupItem, which we call PrintMonitor, that starts Teremok. To get around the whitescreen problem, which we believe to be caused by Teremok starting before the network was ready, we start Teremok, wait 5 seconds, kill Teremok, wait 5 more seconds, and start Teremok again. The StartupItem also does power management settings. Since no user is logged in–root runs Teremok over the LoginWindow (which won't work in Leopard)–the radmind script gleefully updates the computer every night, and everything runs smoothly.

There is also a launchd job set up to run every three minutes that checks to see if Teremok is running and, if it isn't, tells the StartupItem to restart. This ensures the display is always showing what we want.

Posted by slauncha at 10:40 AM | Comments (0) | TrackBack

January 09, 2008

Radmind update to 1.11.0

With the update to the new Radmind version, 1.11.0, we are going to have to ensure that the Radmind tools go out to the clients before the servers are upgraded. The new version changes the server port from 6662 to 6222, the new IANA-registered standard. The client versions of the tools (fsdiff and lapply are the most relevant or our daily purposes) will fail through to 6662 if 6222 is unavailable, but if the server is running 1.11.0 while the clients are running an older version, the clients will only look for the old port and never find the new one. In short, the client and server will miss each other completely. The transition should work just fine as long as we ensure that all stations receive the new tools before the servers.

We may investigate forwarding port 6662 to port 6222 on the servers as we upgrade them in order to prevent this failover from affecting older or nonworking stations that don't receive the update from getting new updates.

Posted by slauncha at 11:25 AM | Comments (0)

December 13, 2007

LaunchServices and Document Handlers

Recently, we have been receiving reports of users being confused by Pages opening Microsoft Word-formatted documents instead of Microsoft Word. So, we made some changes to the file ~/Library/Preferences/com.apple.LaunchServices.plist, which is the file responsible for file associations (and storing which applications open using Rosetta). On login, however, the LaunchServices file was changing—only the lines relating to Microsoft Word were removed.

Andrew Mortensen was kind enough to share a utility he wrote, "dh," that reads the content of a file and sets document handlers accordingly. Using this utility, I created a login script that runs and reads a file containing the Microsoft Word information. This successfully sets the correct file behavior on login.

Posted by slauncha at 10:25 AM | Comments (0) | TrackBack

December 06, 2007

Safari 3.0 and Mac OS X 10.4.11

The issue that was stopping the deployment of the 10.4.11 update was that when a user launched Safari, the first time he or she tried to download a file, they would see an error message stating that Safari could not download the file due to insufficient free space. We'd seen similar errors before, and they involved the download folder location (specified in ~/Library/Preferences/com.apple.internetconfig.plist) pointing to the default user profile folder instead of the logged in user's profile. This time, the default folder was not set, but the error was still occurring.

After trying various fixes, we realized that Safari 3.0 defaults to saving downloads to ~/Downloads instead of ~/Desktop. Since ~/Downloads doesn't exist in our default user profile, the folder didn't exist for the regular users and Safari, after the first failure, defaulted to the desktop.

To fix this issue, we changed ~/Library/Preferences/com.apple.Safari.plist to point to ~/Desktop.

The lines added in ~/Library/Preferences/com.apple.Safari.plist were the following:

<key>DownloadsPath</key>
<string>~/Downloads</string>
<key>DownloadsPathWasConverted</key>
<true/>

Posted by slauncha at 03:09 PM | Comments (0) | TrackBack

December 05, 2007

XServe RAID Problems

Lately we've had some problems with server hard drives that have required rebuilding the software RAIDs on some of our servers. Unfortunately, most of them were set up well before we put Mac OS X Server 10.4.11 on them, so they were using AppleRAID 1, which OS X 10.4 can't rebuild. After making a backup, we used the command diskutil convertRAID /path/to/volume to convert the RAID arrays to AppleRAID 2, allowing us to rebuild the RAID using Disk Utility.

Posted by slauncha at 09:50 AM | Comments (0)

November 28, 2007

OpenAFS 1.4.5 upgrade

In response to recent reports of users who have encountered the dreaded spinning wheel of death while trying to access their AFS space, we have further investigated and identified the following relevant log messages:

kernel[0]: Starting AFS cache scan...[201] waiting for afs_osi_ctxtp
kernel[0]: [202] waiting for afs_osi_ctxtp

It appears that the OpenAFS cache code problem has resurfaced and is causing the Finder to occasionally choke.

Accordingly, we plan to test and upgrade to OpenAFS 1.4.5 for Winter Term since it contains numerous panic fixes and touts improved stability.

Posted by rdevine at 01:45 PM | Comments (0)

November 26, 2007

Mac OS X 10.4.11 is here ... finally

We have deployed the much awaited Mac OS X 10.4.11 update to our West zone Mac workstations:

West
Fletcher
Ford School
Ford Podiums
Law Lab
Newberry
SORC
South Quad
Union
Union Cyber
Union First
Union Fourth Floor
Union Tap Room
West Quad

This final Mac OS X 10.4 update contains more than two dozen fixes and also includes the final version of Safari 3.0 for Tiger.

Presuming we do not encounter any aberrant system behavior or problems related to these systems "fixes", we plan on deploying this system update site-wide later this week.

Update 12-4-2007: Due to some problems with Safari's download preferences, we've delayed the large-scale deployment of 10.4.11. Thanks to the current software freeze, we're going to wait until December 24th to deploy the update.

Posted by rdevine at 04:14 PM | Comments (0)

November 01, 2007

OpenAFS StartupItem

We've been noticing that on some newly-deployed Macs, the directory /afs is never created during the initial load. This causes OpenAFS to fail to start, leaving IFS home directories inaccessible to users. To fix this, I edited the OpenAFS startup item (/Library/StartupItems/OpenAFS/OpenAFS) to include a function that creates the directory if it doesn't exist. This should ensure that IFS home directories are properly mounted for all users.

Posted by slauncha at 08:15 AM | Comments (0)

October 03, 2007

Angell Hall Cyberstation Large Jobs Bug Fix

We identified a problem where print jobs sent from Angell Hall Cyberstations to the 'Angell Large Jobs' queue were inadvertently printing in large format (11" x 17"). Upon further inspection, the Angell Large Jobs PPD deployed to the cyberstations was out-of-date compared with the PPD deployed to the floor machines. Updating the PPD appeared to correct the problems. Machines will receive the updated PPD on next logout/nightly update, whichever should occur first.

Posted by rdevine at 03:34 PM | Comments (0)

October 02, 2007

Universal Photoshop CS3 Printing Issues

In response to recently reported Photoshop CS3 color printing woes on Intel iMacs, we have found that others are encountering similar problems:

http://forum.adobe.com/cgi-bin/webx/.3bc47348/0

As a workaround, we have deployed a setting that will cause Photoshop to run in Rosetta emulation until we can get some new HP drivers that behave properly.

Posted by rdevine at 04:11 PM | Comments (0)