########################################################
# Sync Tivoli Directory Server from Lotus Notes Domino.
# Add new Lotus Notes entries to Tivoli.
# Delete old Lotus Notes entries from Tivoli and remove entries from roles.
# Write report and email to respondents.
########################################################
puts "\n executing [info script]\n"
# make script drive independent.
set drive [lindex [file split [info script]] 0 ]
puts "\n proclib = $drive/scripts/TCL/proclib"
########################################################
# Source utility procs.
########################################################
source [ file join $drive /scripts/TCL/proclib/checkFile_proc.tcl ]
source [ file join $drive /scripts/TCL/proclib/smtp_proc.tcl ]
source [ file join $drive /scripts/TCL/proclib/netSend_proc.tcl ]
source [ file join $drive /scripts/TCL/proclib/reportHeader_proc.tcl ]
########################################################
# Source packages.
########################################################
package require ldap
package require Tclx
###########################################
# Toplevel Proc.
###########################################
proc topProc { reportFileId attr } {
if { [ catch { extractDominoPersons } r ] == 0 } {
set dominoPersons $r
} else {
return -code error $r
}
#############################################
# Extract internal users from IBM ldap.
#############################################
if { [ catch { extractldapPersons } r ] == 0 } {
set ldapPersons $r
} else {
return -code error $r
}
#####################################################################################
# compare users - extract and delete the entries that exist in ldap but not in Lotus.
#####################################################################################
if { [ catch { diffPersons $dominoPersons $ldapPersons $attr } r ] == 0 } {
puts $r
} else {
puts $r
return -code error $r
}
}
###########################################
# Extract dominoPersons from Lotus ldap
###########################################
proc extractDominoPersons {} {
global s1
global lotusBaseDN
# Search on objectclass. Return uid.
# Return sorted list
set filter [ list "objectClass=dominoPerson" ]
if { [ catch { ldap::search $s1 $lotusBaseDN $filter {uid} } r ] == 0 } {
return [ lsort $r ]
} else {
return -code error $r
}
}
###########################################
# Extract Internal Users from IBM ldap.
###########################################
proc extractldapPersons {} {
global s2
global ldapBaseDN
# Search on objectclass. Return cn.
# Return sorted list
set filter [ list "objectClass=ldapPerson" ]
if { [ catch { ldap::search $s2 $ldapBaseDN $filter {cn} } r ] == 0 } {
return [ lsort $r ]
} else {
return -code error $r
}
}
###########################################
# Diff Entries.
###########################################
proc diffPersons { dominoPersons ldapPersons attr } {
global reportFileId
global ldapServer
set x 0
# Extract Domino Uids.
foreach i $dominoPersons {
lappend dominoPersonsList [ lindex $dominoPersons $x 1 1 0 ]
incr x
}
set x 0
# Extract Tivoli Cns.
foreach i $ldapPersons {
lappend ldapPersonsList [ lindex $ldapPersons $x 1 1 0 ]
incr x
}
# Threeway match.
foreach { x y z } [ lindex [ intersect3 $dominoPersonsList $ldapPersonsList ] ] {
set addPersons $x
set matchingPersons $y
set deletePersons $z
}
# If the lists are null skip add/delete steps.
set p1 "*****************************************"
set p2 "* No persons to add"
set p3 "* No persons to delete"
# add Domino entry to Tivoli
if { $addPersons == {} || [ string is space $addPersons ] } {
set t1 [ format "%-20s %s" " " $p1 ]
set t2 [ format "%-20s %-30s" " " $p2 ]
puts \n$t1
puts $t2
puts $t1\n
puts $reportFileId \n$t1
puts $reportFileId $t2
puts $reportFileId $t1\n
} else {
if { [ catch { addPersons $addPersons } r ] == 0 } {
set continue true
} else {
return -code error $r
}
}
# delete entry from Tivoli
if { $deletePersons == {} || [ string is space $deletePersons ] } {
set t1 [ format "%-20s %s" " " $p1 ]
set t2 [ format "%-20s %-30s" " " $p3 ]
puts \n$t1
puts $t2
puts $t1\n
puts $reportFileId \n$t1
puts $reportFileId $t2
puts $reportFileId $t1\n
} else {
if { [ catch { deletePersons $deletePersons } r ] == 0 } {
set continue true
} else {
return -code error $r
}
}
}
######################################################################
# Add Persons.
# Add entries which exist on Lotus Domino but do not exist on Tivoli.
######################################################################
proc addPersons { addPersons } {
global s1
global s2
global reportFileId
global ldapBaseDN
global lotusBaseDN
global ldapServer
global bindDN
global pw
set addCount [ llength $addPersons ]
set p1 "*****************************************"
set p2 "* Adding Lotus Persons to LDAP"
set p4 "* Add count is $addCount"
set t1 [ format "%-20s %30s" " " $p1 ]
set t2 [ format "%-20s %-30s" " " $p2 ]
set t7 [ format "%-20s %-30s" " " $p4 ]
puts $t1
puts $t2
puts $t7
puts $t1
puts $reportFileId $t1
puts $reportFileId $t2
puts $reportFileId $t7
puts $reportFileId $t1
foreach i $addPersons {
# select the required attributes from lotus.
set filter "(uid=$i)"
set attributes {cn givenname sn mail}
if { [ catch { ldap::search $s1 $lotusBaseDN $filter $attributes } results ] == 0 } {
set dn cn=$i\,$ldapBaseDN
set objectclass1 top
set objectclass2 person
set objectclass3 organizationalPerson
set objectclass4 inetOrgPerson
set objectclass5 ldapPerson
# Domino entries may have invalid fields.
# Data cleanup is required.
set cn $i
set uid $i
set sList [ lindex $results 0 1 ]
if { [ lsearch $sList {*givenname*} ] == -1 } {
set givenname "$i"
} else {
set index [ lsearch $sList {*givenname*} ]
set givenname [ lindex $sList [ incr index ]]
unset index
}
if { [ lsearch $sList {*sn*} ] == -1 } {
set sn "$i"
} else {
set index [ lsearch $sList {*sn*} ]
set sn [ lindex $sList [ incr index ]]
unset index
}
if { [ lsearch $sList {*mail*} ] == -1 } {
set mail "$i"
} else {
set index [ lsearch $sList {*mail*} ]
set mail [ lindex $sList [ incr index ] ]
unset index
}
set userPassword "password"
# build attribute list
set list1 [ list objectclass ldapPerson \
objectclass inetOrgPerson \
objectclass organizationalPerson \
objectclass person \
objectclass top \
cn $cn \
uid $uid \
sn $sn \
givenname $givenname \
mail $mail \
userPassword $userPassword ]
set g [ string trimleft $givenname givenname= ]
set s [ string trimleft $sn sn= ]
set c [ string trimleft $cn cn= ]
set width [ string length "$s $g \($c\)" ]
set t1 [ format "\n%s %-${width}s %s" "Adding" "$s $g \($c\)" "to $ldapServer" ]
set t2 [ format "\n%s %-${width}s %s" " Added" "$s $g \($c\) " "to $ldapServer" ]
set t3 [ format "%s" " $dn" ]
set t4 [ format "\n%s %-${width}s %s" " Error adding" "$s $g \($c\) " "to $ldapServer" ]
set r ""
set t5 [ format "%s" " $r" ]
puts $t1
puts $t3
puts $reportFileId $t1
# add entry
if { [ catch { ldap::add $s2 $dn $list1 } r ] == 0 } {
puts $t2
puts $t3
puts $reportFileId $t2
puts $reportFileId $t3
} else {
puts $t4
puts $t3
puts $t5
puts $reportFileId $t4
puts $reportFileId $t3
puts [ format "%s" " $r" ]
puts $reportFileId [ format "%s" " $r" ]
}
unset dn
unset objectclass5
unset objectclass4
unset objectclass3
unset objectclass2
unset objectclass1
unset cn
unset uid
unset sn
unset givenname
unset mail
unset userPassword
unset list1
}
}
}
######################################################################
# Delete Persons.
# Delete entries from Tivoli which exist on Domino but do not exist on Tivoli.
######################################################################
proc deletePersons { deletePersons } {
global s1
global s2
global reportFileId
global ldapBaseDN
global attr
global ldapServer
set deleteCount [ llength $deletePersons ]
set p1 "*****************************************"
set p2 "* Deleting Lotus Persons from LDAP"
set p4 "* Delete count is $deleteCount"
set t1 [ format "%-20s %30s" " " $p1 ]
set t2 [ format "%-20s %-30s" " " $p2 ]
set t7 [ format "%-20s %-30s" " " $p4 ]
puts \n$t1
puts $t2
puts $t7
puts $t1
puts $reportFileId \n$t1
puts $reportFileId $t2
puts $reportFileId $t7
puts $reportFileId $t1
foreach i $deletePersons {
# Get the full dn of the target person.
# Search on CN.
set attrs [ ldap::search $s2 $ldapBaseDN "(cn=$i)" { cn givenname sn } ]
set baseDNPerson [ lindex $attrs 0 0 ]
set g [ lindex $attrs 0 1 1 ]
set s [ lindex $attrs 0 1 3 ]
set y "$s $g \($i\)"
set width [ string length $y ]
set t1 [ format "\n%s %-${width}s %s" "Deleting " $y "from $ldapServer" ]
set t2 [ format "\n%s %-${width}s %s" " Deleted " $y "from $ldapServer" ]
set t3 [ format "%s" " $baseDNPerson" ]
set t4 [ format "\n%s %-${width}s %s" " Error deleting " $y "from $ldapServer" ]
set r ""
set t5 [ format "%s" " $r" ]
# get the roles assigned to the target person.
set memberOf [ lindex [ ldap::search $s2 $ldapBaseDN "(cn=$i)" {ibm-allGroups} ] 0 1 1 ]
set replace {}
set delete [ list $attr $baseDNPerson ]
set add {}
# remove the target person from roles.
foreach i $memberOf {
set t6 [ format "\n%s %-${width}s %s" "Removing " $y "from $i" ]
puts $t6
puts $reportFileId $t6
if { [ catch { ldap::modify $s2 $i $replace $delete $add } r ] == 0 } {
set t6 [ format "\n%s %-${width}s %s" "Removed " $y "from $i" ]
puts $t6
puts $reportFileId $t6
} else {
set t6 [ format "\n%s %-${width}s %s" "Error removing " $y "from $i" ]
puts $t6
puts $reportFileId $t6
puts [ format "%s" " $r" ]
puts $reportFileId [ format "%s" " $r" ]
}
}
# delete the target person
puts $t1
puts $t3
puts $reportFileId $t1
if { [ catch { ldap::delete $s2 $baseDNPerson } r ] == 0 } {
puts $t2
puts $t3
puts $reportFileId $t2
puts $reportFileId $t3
} else {
puts $t4
puts $t3
puts $t5
puts $reportFileId $t4
puts $reportFileId $t3
puts [ format "%s" " $r" ]
puts $reportFileId [ format "%s" " $r" ]
}
}
}
###########################################
# Email Report
###########################################
proc emailReport { reportFile reportFileId } {
flush $reportFileId
set computerName $::env(COMPUTERNAME)
set subject "$computerName - Lotus - LDAP Replication"
sendSimpleMessage xxx@xxx.com $subject $reportFile
}
######################################
# Control Section.
######################################
######################################
# Set Variables.
######################################
set fileDate [ clock format [ clock seconds ] -format %Y-%m-%d_%H-%M-%S ]
set reportFile [ file join $drive reports/ldap/lotusSync_$fileDate\.txt ]
set lotusServer xxxxx
set ldapServer yyyyy
set bindDN "cn=xxxxx"
set pw yxyxyx
set attr uniqueMember
puts "reportfile = $reportFile\n"
######################################
# Report Header.
######################################
set reportFileId [ open $reportFile w ]
set header "$::env(COMPUTERNAME) - Lotus LDAP Replication"
set ldapBaseDN "ou=xxxxxxx,o=yyyyy,dc=com.au,c=au"
set lotusBaseDN "o=aaa"
reportHeader $reportFileId $header $reportFile
puts [ format "%-15s %s %s" "Lotus Server" "- " $lotusServer ]
puts [ format "%-15s %s %s" "Tivoli Server" "- " $ldapServer ]
puts $reportFileId [ format "%-15s %s %s" "Lotus Server" "- " $lotusServer ]
puts $reportFileId [ format "%-15s %s %s" "Tivoli Server" "- " $ldapServer ]
###################################
# Connect and bind to ldap servers
###################################
set s1 [ ldap::connect $lotusServer 389 ]
::ldap::bind $s1
set s2 [ ldap::connect $ldapServer 389 ]
::ldap::bind $s2 $bindDN $pw
###################################
# Global variables.
###################################
global s1
global s2
global reportFileId
global ldapBaseDN
global lotusBaseDN
global ldapServer
global bindDN
######################################
# Call toplevel proc.
######################################
if { [ catch { topProc $reportFileId $attr } r ] == 0 } {
puts $r
} else {
puts $r
puts $reportFileId $r
}
#############################################
# Write Report footer.
#############################################
set s "*****************************************"
set t1 [ format "%-20s %s" " " $s ]
set s "The End"
set t2 [ format "%-35s %s" " " $s ]
puts \n$t1
puts $t2
puts $t1
puts $reportFileId \n$t1
puts $reportFileId $t2
puts $reportFileId $t1
##########################################
# Unbind and disconnect from ldap servers
##########################################
::ldap::unbind $s1
::ldap::unbind $s2
::ldap::disconnect $s1
::ldap::disconnect $s2
emailReport $reportFile $reportFileId
close $reportFileId
######################################
# END.
######################################