dsimportexport is broken… using PHP/LDAP instead…
So not only does dsimportexport not actually export as well as import, but it doesn't even import properly.
It turns out that you can't use the -O overwrite flag and expect to get the same behaviour as when you import exactly the same file using Workgroup Manager. sheesh…
so anyway, as I was using php anyway for the automation scripts, it turns out it is far faster to just use php ldap functions than even thwacking dscl around to put the data in yourself, and much easier if you're already constructing arrays from SQL queries.
So say we're wanting to completely replace the membership list for a group called 'thisgroup'.
It will look something like this:
<?php
$od['server'] = 'your.odmaster.com';
$od['port'] = '389';
$od['v3'] = '1'; // By default OS X Server uses LDAPv3.
$od['tls'] = '1'; // if you're using TLS
$od['user'] = 'uid=your-od-admin-username,cn=users,dc=mythical,dc=edu,dc=au';
$od['pass'] = 'your-od-admin-password';
$od['base'] = 'dc=mythical,dc=edu,dc=au';
$groupname = 'testgroup';
$groupmembers = array('andyclark', 'jerryfodor', 'danieldenntt', 'gottlobfrege');
$update_connection = ldap_connect($od['server'], $od[port])
or die("Could not connect to LDAP server.");
if ($od['v3'])
{
ldap_set_option($update_connection, LDAP_OPT_PROTOCOL_VERSION, 3);
}
if ($od['tls'])
{
ldap_start_tls($update_connection);
}
$update_bind = ldap_bind($update_connection, $od['user'], $od['pass']);
if (! $update_bind)
{
die("LDAP bind failed");
}
else
{
$update_array[memberuid] = $groupmembers;
// In this example, $update_dn will be "cn=testgroup, cn=groups, dc=mythical, dc=edu, dc=au"
$update_dn = "cn=$groupname, cn=groups, $od['base']";
$update_results = ldap_mod_replace($update_connection, $update_dn, $update_array);
if ($update_results)
{
echo "update successful";
}
else
{
echo "Unable to update group";
}
}
ldap_close($update_connection);
?>
So really you want some sanity checking around the values you're whacking into LDAP. Remember, that this kind of stuff is faster than dsimportexport because it doesn't check the values…. you're basically doing exactly the same thing as enabling Inspector in Workgroup Manager and putting your own values in. You'll want to make sure your 'shortnames' in the $groupmembers array don't contain spaces, evil characters etc.
It's fast though. Several orders of magnitude faster than dealing with a broken disimportexport…
(edit): I should note that you really want a unique array for work like this, but there are some caveats.
You can't just do something like:
$update_array[memberuid] = array_unique($groupmembers);
due to the way php makes unique arrays by not messing with the index.
You instead need to make sure you have a continuous index for the unique array, like this:
$update_array[memberuid] = array_merge (array_unique($groupmembers));
You wouldn't expect it, but array_merge, when given only one array as an argument, will reindex the array in a continuous way.
You know, I love php, but I wish they'd get some more consistency in their function names….