Integrate LDAP sync in your enterprise applications with ease
Tailor-made features
Cut time and costs with done-for-you synchronization.
Don’t reinvent the wheel. Save time and cut costs by using a solution made specifically for synchronizing LDAP directories.
Handle syncs of any complexity
Directory structures and items can be nested and difficult to map out accurately. Tested on over hundreds of corporate networks, LDAP Connector can sync directories of any complexity.
Point and consume
Install our agent, point to your directory, then specify the cloud storage (Amazon SQS, S3 and others) where you want the data to be stored. Get a JSON, XML or raw format file, ready for consumption.
Intuitive user interface
Whether you’re working with one or multiple directories, our intuitive UI makes the whole process a breeze. In addition, you can create custom filtering rules and schedule syncs for specific hours.
def send_email(subject, message):
# Only for demonstation purposes
# Sender's email address and password
sender_email = "directroy-scanning@company.com"
# Recipient's email address
recipient_email = "hr@company.com"
print(f"Sending email:\n\rFrom:{sender_email} To: {recipient_email}\n\rSubject: {subject}\n\rBody: {message}")
while(True):
messages = sqs.receive_message(
QueueUrl=queue_url,
AttributeNames=[
'SentTimestamp'
],
MaxNumberOfMessages=1,
MessageAttributeNames=[
'All'
],
VisibilityTimeout=10,
WaitTimeSeconds=10
)
for message in messages['Messages']:
dssEvent = json.loads(message['Body'])
dssEventType = dssEvent['EventType']
subject = f"⭐ Received new directory event of type: {dssEventType}"
match dssEventType:
case 'NewEntities':
for dsEntity in dssEvent['DsEntities']:
text = f"{dsEntity['EntityType']} '{dsEntity['Name']}' was added to directory start node. Ldap id is {dsEntity['LdapUniqueId']}"
send_email(subject, text)
case 'ChangedEntities':
for dsEntity in dssEvent['DsEntities']:
text = f"{dsEntity['EntityType']} '{dsEntity['Name']}' was affected by update. Ldap id is {dsEntity['LdapUniqueId']}"
send_email(subject, text)
case 'DeletedSyncEntities':
for dsEntity in dssEvent['DsSyncEntities']:
text = f"{dsEntity['Entity']['EntityType']} '{dsEntity['Entity']['Name']}' was removed from parent {dsEntity['Parent']['Entity']['Name']} of type {dsEntity['Parent']['Entity']['EntityType']}. Path was {dsEntity['Path']}"
send_email(subject, text)
case 'ChangedSyncEntities':
text = 'Relations updated. Affected relations hierarchy:'
for dsSyncEntity in dssEvent['DsSyncEntities']:
stringHierarchy = recursive_ds_sync_entity_showcase(dsSyncEntity, True);
text += f"\n{stringHierarchy}"
send_email(subject, text)
sqs.delete_message(QueueUrl=queue_url, ReceiptHandle=message['ReceiptHandle'])
Console.WriteLine($"⭐ Received new directory event of type: {directoryEvent.EventType}");
switch (directoryEvent.EventType)
{
case "NewEntities":
foreach (var directoryEntity in directoryEvent.DsEntities)
{
SendEmail($"New directory event of type {directoryEvent.EventType}",
$"{directoryEntity.EntityType} {directoryEntity.Name} was added to directory start node. Ldap id is {directoryEntity.LdapUniqueId}");
}
break;
case "ChangedEntities":
foreach (var directoryEntity in directoryEvent.DsEntities)
{
SendEmail($"New directory event of type {directoryEvent.EventType}",
$"{directoryEntity.EntityType} {directoryEntity.Name} was updated. Ldap id is {directoryEntity.LdapUniqueId}");
}
break;
case "DeletedSyncEntities":
foreach (var directorySyncEntity in directoryEvent.DsSyncEntities)
{
SendEmail($"New directory event of type {directoryEvent.EventType}",
$"{directorySyncEntity.Entity.EntityType} {directorySyncEntity.Entity.Name} was removed from parent {directorySyncEntity.Parent.Entity.Name} of type {directorySyncEntity.Parent.Entity.EntityType}. Path was {directorySyncEntity.Path}");
}
break;
case "ChangedSyncEntities":
var changedRelationsSummary = new StringBuilder("Relations updated. Affected relations hierarchy:");
foreach (var directorySyncEntity in directoryEvent.DsSyncEntities)
{
var stringHierarchy = RecursiveDsSyncEntityShowcase(directorySyncEntity, true);
changedRelationsSummary.Append($"\n{stringHierarchy}");
}
SendEmail($"New directory event of type {directoryEvent.EventType}",
changedRelationsSummary.ToString());
break;
}
function sendEmail(subject, message) {
// Only for demostration purposes
// Email options
const mailOptions = {
from: 'directory-scanning@company.com',
to: 'hr@company.com',
subject: subject,
text: message,
};
console.log(`Sending email:\n\rFrom:${mailOptions.from} To: ${mailOptions.to}\n\rSubject: ${mailOptions.subject}\n\rBody: ${mailOptions.text}`)
}
function recursiveDsSyncEntityShowcase(dsSyncEntity, isStart) {
var prefix = isStart ? "" : " ->";
if (!dsSyncEntity)
return "";
return prefix + ` [${dsSyncEntity.Entity.EntityType}] ${dsSyncEntity.Entity.Name}` + recursiveDsSyncEntityShowcase(dsSyncEntity.Parent, false);
}
function sqsDeleteMessage(message) {
var deleteParams = {
QueueUrl: queueURL,
ReceiptHandle: message.ReceiptHandle
};
sqs.deleteMessage(deleteParams, function (err, data) {
if (err) {
console.log("Sqs message delete error", err);
} else {
console.log(`Sqs message with id ${message.MessageId} deleted`);
}
});
}
switch directoryEvent.EventType {
case "NewEntities":
for _, element := range directoryEvent.DsEntities {
message := fmt.Sprintf("%s %s was added to directory start node. Ldap id is %s\n", element.EntityType, element.Name, element.LdapUniqueId)
sendEmail(subject, message)
}
case "ChangedEntities":
for _, element := range directoryEvent.DsEntities {
message := fmt.Sprintf("%s %s was affected by update. Ldap id is %s\n", element.EntityType, element.Name, element.LdapUniqueId)
sendEmail(subject, message)
}
case "DeletedSyncEntities":
for _, element := range directoryEvent.DsSyncEntities {
message := fmt.Sprintf("%s %s was removed from parent %s of type %s. Path was %s\n", element.Entity.EntityType, element.Entity.Name, element.Parent.Entity.Name, element.Parent.Entity.EntityType, element.Path)
sendEmail(subject, message)
}
case "ChangedSyncEntities":
message := fmt.Sprintln("Relations updated. Affected relations hierarchy:")
for _, element := range directoryEvent.DsSyncEntities {
stringHierarchy := recursiveDsSyncEntityShowcase(&element, true)
message += fmt.Sprintln(stringHierarchy)
}
sendEmail(subject, message)
}
// Delete the message from the queue (if needed)
deleteMessageInput := &sqs.DeleteMessageInput{
QueueUrl: aws.String(queueURL),
ReceiptHandle: message.ReceiptHandle,
}
_, err = client.DeleteMessage(deleteMessageInput)
if err != nil {
fmt.Println("Error deleting message:", err)
}
}
Code Sample
Once LDAP Connector has synced the changes from the directory to your destination (Amazon SQS or S3), the data can be easily consumed as needed through your own integrations. Here is an example NodeJS program that parses LDAP change events (new entities, changed entities or deletions) from SQS:
Our 16 years of achievements
With our super powers we have reached this
1000+
Happy customers globally, 10% from Fortune 1000, 400 from the USA
25,000+
Engineering and non-engineering software applications supported
15+
Industries served
15%
Minimum IT License cost savings annually
Ready to sync?
We offer new users a 6-month trial for LDAP Connector.
Have questions? Need a custom implementation?