Sun Java System Identity Synchronization for Windows 6.0 Deployment Planning Guide

Periodic idsync resync Operations

Periodic idsync resync Operation for Primary Installation

As Global Telco uses Identity Manager to provision users and has not configured Identity Synchronization for Windows to synchronize the creation of new users, idsync resync must be run periodically to establish links between recently created users. If these users are not linked, modifications to their passwords will not synchronize. Running a full idsync resync operation for 500,000 users could take a few hours because synchronization of new changes is delayed during an idsync resync operation. It is unacceptable to have Identity Synchronization for Windows offline for so long, so Global Telco uses the Active Directory usnCreated attribute to synchronize only those users that have been created recently. The administrator uses the following script, which is run every hour, to synchronize users that have been created in the last three days. This script is run on users created in the last three days instead of only the last hour because a new employee might not have a Directory Server account until a few days after the Active Directory account is created.

The script is run periodically with the following arguments, using cron: usnCreated 
-f /var/opt/SUNWisw/samples/linkusers-simple-gt.cfg 
-i NEW_LINKED_USERS -b -w - -q - < /var/opt/SUNWisw/passwords

The first argument is the name of the Active Directory domain controller that the connector communicates with. The second argument determines whether the idsync resync command should be run only on entries that were created recently. The remaining arguments are passed directly to resync. In this case, the Directory Server password is reset for all users that are newly linked. The - value used for the two password options directs the idsync resync command to read the values from STDIN; which prevents passwords from appearing in the command line and being available to anyone on the system using commands such as ps. The configuration directory password and the configuration password are written to /var/opt/SUNWisw/passwords, and this file is then protected with the strictest file system permissions. script:

# This sample script shows how to run idsync resync only on users
# that have changed recently and can be used to reduce the
# impact of running resync frequently.  By default it
# only resync's users that were modified or created in
# the last three days.  The script stores a daily history
# of Active Directory's highestCommittedUSN attribute.
# The arguments of the command are
#  <Active Directory-domain-controller-name\>
#  (usnChanged|usnCreated)
#  [args-for-resync]
# To link users that were created recently run the command
# usnCreated -k -f link.cfg -q <pw\> -q <pw\>
# To synchronize all users that were modified recently
# usnChanged -q <pw\> -q <pw\>
# To prime the object cache for users that were modified recently
# usnChanged -u -q <pw\> -q <pw\>
# NOTE: this script is only provided as a guide.
# It must be adapted to the specific Identity
# Synchronization for Windows environment by
# changing the paths and options below as appropriate
# and adding additional error handling code.
my $USAGE = "USAGE: “.
    “<Active Directory-domain-controller-name\> ".
    "(usnChanged|usnCreated) [args-for-resync]\\n";

my $IDSYNC = "/opt/SUNWisw/bin/idsync";
my $USN_FILE = "/opt/SUNWisw/bin/usnHistory";



# Argument parsing
my $adDomainController = shift @ARGV or die "$USAGE";
my $usnSearchAttr = shift @ARGV or die "$USAGE";
$usnSearchAttr =~ /usnChanged/i or
     $usnSearchAttr =~ /usnCreated/i or
    die "$USAGE\\n";
my $resyncArgs = getArgsAsString(@ARGV);

# Read the highestCommittedUSN history and add today's
# date to it if not it's there and then write the history
# out.
my %usnHistory = readUsnHistory();
my $today = getCurrentDate();
if (!$usnHistory{$today}) {
    $usnHistory{$today} = getHighestUsn($adDomainController);

# Run the resync command based on the oldest usnChanged
# value in the history.
my $oldestUsn = getOldestUsn(%usnHistory);
my $filter = "($usnSearchAttr\>=$oldestUsn)";
my $resyncCmd = "$IDSYNC resync -a \\"$filter\\" $resyncArgs";
print "Running $resyncCmd\\n";


# Return the current date as a string, e.g. 2004/03/04
sub getCurrentDate {
    my ($day, $month, $year) = (localtime(time))[3,4,5];
    $year += 1900;
    return sprintf "%d/%02d/%02d", $year, $month, $day;
# Searches the root DSE at the specified host and returns
# the highestCommittedUSN value.
sub getHighestUsn {
    my $adHost = shift @_;
    my $cmd = "ldapsearch -h $adHost -b \\"\\" -s base ".
        "\\"(objectclass=*)\\" highestCommittedUSN | ".
        "grep highestCommittedUSN | sed \\"s/[^0-9]//g\\"";
    my $highestUsn = '$cmd';
    chomp $highestUsn;
    print "highestCommittedUSN at $adHost is $highestUsn.\\n";
    return $highestUsn;

# Converts the command line args into a string.
sub getArgsAsString {
    my $args = "";
    for my $arg (@_) {
        $args .= " \\"$arg\\"";
    return $args;

# Returns the oldest usnChanged value from the history.
sub getOldestUsn {
    my %usnHistory = @_;

    my @dates = getHistoryDates(%usnHistory);

        # Return the last element.
    return $usnHistory{$dates[$#dates]};

# Return a sorted list of the dates in the history.
sub getHistoryDates {
    my %history = @_;
    return reverse sort(keys %usnHistory);

# Writes the most recent daily history of highestCommittedUSN.
# No more than $MAX_DAYS_HISTORY days history is recorded.
sub writeUsnHistory {
    my %usnHistory = @_;
    if (!open(OUT, "\>$USN_FILE")) {
        print STDERR "Could not open $USN_FILE for writing.\\n";

        # Write the history up to the last $MAX_DAYS_HISTORY days.
    my @dates = getHistoryDates(%usnHistory);
    for (my $i = 0;
         $i <= $#dates and $i < $MAX_DAYS_HISTORY;
        my $date = $dates[$i];
        print OUT "$date:$usnHistory{$date}\\n";


# Reads the daily history of highestCommittedUSN

sub readUsnHistory {
    my %usnHistory = ();
    if (!open(IN, "<$USN_FILE")) {
        print STDERR "Could not read history from $USN_FILE.\\n";
        return %usnHistory;

    while (my $line = <IN\>) {
        chomp $line;
        my ($date, $usn) = split /:/, $line;
        $usnHistory{$date} = $usn;

    return %usnHistory

An alternative to running idsync resync periodically is to modify the process to set the necessary link information when the Directory Server entry is processed. The process is straightforward:

  1. Add the dspswuser object class to the user entry.

  2. Set the dspswuserlink attribute to match the user's objectguid attribute (from Active Directory).

  3. (Optional) Set the dspswvalidate attribute to true to force on-demand password synchronization.

Periodic idsync resync Operation for Failover Installation

To speed the failover process, the idsync resync operation is run periodically on the failover installation to keep the object cache database in the Active Directory Connector up-to-date. If the object cache is not kept up-to-date, the Active Directory Connector will detect and propagate many changes that were already synchronized by the primary installation. Not keeping the object cache database up-to-date will also significantly increase the load, and place a heavier load on Directory Server during the failover scenario.

The same script that is used in the primary installation is used in this installation except that it is run from the system that contains the failover installation Core, The cron command is used to run the script daily with the following arguments. The -u option is specified to update only the Active Directory Connector's object cache. usnCreated -u -b -w - -q - < /var/opt/SUNWisw/passwords

Note –

The more often this script is run in the failover environment, the more likely changes will be lost during the failover process. idsync resync -u should not be run after the primary installation fails. If the command is run often (for example, every hour), it is likely that it will be run while the primary installation has failed, but the failure has not yet been detected. As this script keeps track of a three-day history of the highestCommittedUSN values, it could be updated to search for entries that were modified in the last three days but not modified in the last day. As long as the primary installation failure is detected within one day and the cron job of this script was stopped, no Active Directory changes are lost.