Friday, May 15, 2009

Installing Composer-style .dmg Without Casper

On occassion I have needed to install software where we created a .dmg package using Composer when I did not have Casper installed.

Here is an example of doing it.  (Names, etc, will change when you do it yourself).  Note that this will not fill user templates or copy files to all users.

$ # Mount the file while retaining permissions
$ hdiutil attach ~/Desktop/iWork\ 08.dmg -owners on
expected   CRC32 $880FA4DB
/dev/disk1           Apple_partition_scheme          
/dev/disk1s1         Apple_partition_map             
/dev/disk1s2         Apple_HFS                       /Volumes/iWork 08
$ sudo cp -Rp /Volumes/iWork\ 08/ /
Password:
cp: /Volumes/iWork 08/: unable to copy extended attributes to /: Is a directory
cp: /Volumes/iWork 08/: unable to copy ACL to /: Is a directory
$ hdiutil detach /Volumes/iWork\ 08/
"disk1" unmounted.
"disk1" ejected.

Wednesday, April 8, 2009

Use MAC Address to Look Up Computer In Open Directory

Occassionally you know a Mac computer is in your Open Directory, but don't know what it is named in there. If you know the primary MAC address, you can look it up.

After you open up a trusty Terminal, you can make a list of all of the Computer Names and their Mac addresses by doing this (on one line):

dscl /LDAPv3/192.168.100.100 -readall /Computers RecordName macAddress > out.txt

Then, open up out.txt in a text editor, and do a search for your MAC address, or, from the command line, do this:

grep -A 1 "00:1b:63:36:95:35" out.txt

The result will look like:

dsAttrTypeNative:macAddress: 00:1b:63:36:95:35
RecordName:
ComputerNameHere

If you have access to a computer over ssh or ARD, you can get the MAC address with this command:

ifconfig en0 | grep eth

'en0' is the first interface, which is almost always ethernet, and should be the value stored in the directory. Using 'en1' would give you the second interface's MAC address; it is almost always the Airport.

Thursday, March 26, 2009

OD Archive fails due to "Keychain -25300" error

At my workplace, we have been having problems with Apple Open Directory. [I'm using OS X Server, 10.5.6.] One thing we noticed is that, if you go to Server Admin, and tell it to make an archive or your directory, it will appear to happily do so, but, if you check, you will not end up with an archive; no file will have been created, and, in looking at the "Configuration Log" (/Library/Logs/slapconfig.log), you will see at the end that there was some sort of mysterious keychain error at the end of step 5:

Error in backing up keychain -25300
Removed directory at path /tmp/slapconfig_backup_stage[funky-unique-name].
Searching the web for the keychain error message merely revealed other people who were having the problem, and had not come up with a solution.

At length, I found that Apple has open-sourced a number of their projects, including parts of Open Directory, and that the source is available for download.

When looking for the source for slapconfig (the tool used in creating the Open Directory archive), which does not appear to be available, I came across a posting where someone identified which keychain is missing.

The missing keychain is a System keychain called com.apple.opendirectory. Here is how you re-create it:

Run Keychain Access (it is in /Applications/Utilities).

Click on the "System" Keychain (on the left) and note that the com.apple.opendirectory keychain does not exist. [The picture below shows it after it has been created.]

You will need to add a new keychain item. Click on the "+" symbol at the bottom. [You may have to unlock your keychain first]

I did some testing. It is important that the account name be your server's hostname followed by a dollar sign. If you use something else -- for example, I tried the hostname of the server that used to be our Open Directory Master -- you will get keychain errors when you try to create the archive.

We went to some effort to recover the former password [cool enough, if you have a keychain, you can hit the 'i' button (or press Cmd-I) to see the info on it, and then tick the "Show password" checkbox to see the password.] This was needless; it turns out that the password you use really doesn't matter. I don't think you'd ever need to know it again, and while I don't know what purpose it serves, I'd use a reasonably strong password.

Having created your new key, can you make a backup? Yes, well, ..., erm, well, yes, but, not through the GUI tool. When you use Server Admin now (and I even tried rebooting to see if it would make a difference), things still do not work right. If you click on Open Directory and then on "Archive", it may say "loading information" for a couple of minutes, and, when you finally try to create the archive, it will fail silently, logging:

Error in backing up keychain -25308
a different error, which, I gather, means it couldn't communicate with the keychain. (Sigh)

But, you can now create the backup manually.

Open up a trusty Terminal, and issue a the backup command:

sudo slapconfig -backupdb Desktop/backup

The latter parameter is the path and filename of the backup to create. You will be asked for your admin password [by sudo], and then for a password for the sparseimage archive of your directory [by slapconfig]. It goes ahead and does it thing, even stopping to ask if it can access the keychain, and, you'll notice at the end of step 5 it says,

Backed Up Keycahin

[That is a direct cut-and-paste, by the way. Bugs come in all shapes and sizes.] You now have a successful backup!

Restoring the Backup

I went to a pristine server and tried to restore the backup. In Server Admin, select the server, choose "Open Directory", click on the "Archive" icon, and choose "Restore". It didn't work. The log said, "The directories were not merged because the kerberos realms are different."

Okay, fine. I changed the server from being an Open Directory Master to being a Standalone server. Then, I changed it back to being an Open Directory Master. This time I was sure to enter in the realm information used by our existing master, and to change the base path to correspond. Afterward, I was able to restore, right from the GUI tool.

I tested the restored master with Workgroup Manager and dscl, and su. It looks good. Making an Open Directory Archive from Server Admin worked, too!

Hooray!

Addendum

If the com.apple.opendirectory keychain does not exist, it will be created when you take a standalone server and make it into an Open Directory Master.  

Thursday, March 5, 2009

Python Subprocess Wrapper for MySQL

Compiling MySQL support for Python under OS X Leopard is a pain, and, so far as I can see, there is no handy way to do it with a redistributable universal binary.

So, I decided to call MySQL from within Python using a subprocess. This is the code that I came up with, which should work fine with a default installation of MAMP. It likely has more overhead than using MySQLdb, and would likely choke if you got a really large result-set back. However, I think it will serve my purposes admirably.

#!/usr/bin/env python

from subprocess import Popen, PIPE

# Set the command you need to connect to your database
# WARNING: password will be visible in a process listing!
mysql_cmd_line = "/Applications/MAMP/Library/bin/mysql -u root -p"
mysql_password = "root"

def RunSqlCommand(sql_statement, database=None):
    
    """Pass in the SQL statement that you would like executed.
    Optionally, specify a database to operate on.  Returns the result."""
    
    command_list = mysql_cmd_line.split()
    if database:
        command_list.append(database)
        
    # Run mysql in a subprocess
    process = Popen(command_list, stdin=PIPE, stdout=PIPE,
                    stderr=PIPE, close_fds=True)
    
    # pass it our commands, and get the results
    (stdout, stderr) = process.communicate( mysql_password )

    return stdout

def test():
    """Performs a simple test connection."""

    print "This specified MySQL server has the following databases:"
    print
    print RunSqlCommand("SHOW DATABASES;")

    print RunSqlCommand("SELECT * FROM USER_PRIVILEGES LIMIT 2;", "information_schema")

if __name__ == "__main__":
    test()

The output of that command, against a pristine MAMP installation, is:

This specified MySQL server has the following databases:

Database
information_schema
mysql
test

GRANTEE TABLE_CATALOG PRIVILEGE_TYPE IS_GRANTABLE
'root'@'localhost' NULL SELECT YES
'root'@'localhost' NULL INSERT YES

Sunday, March 1, 2009

Which World? 
Hello, World!