1
0
mirror of https://github.com/bitwarden/directory-connector synced 2025-12-15 15:53:41 +00:00

separate ldap config from sync

This commit is contained in:
Kyle Spearrin
2017-05-18 07:52:26 -04:00
parent 357c4e6576
commit 1c0061bcef
3 changed files with 129 additions and 82 deletions

View File

@@ -535,7 +535,7 @@ namespace Bit.Console
}
if(parameters.ContainsKey("gn"))
{
config.GroupNameAttribute = parameters["gn"];
config.Ldap.GroupNameAttribute = parameters["gn"];
}
if(parameters.ContainsKey("uf"))
@@ -544,34 +544,34 @@ namespace Bit.Console
}
if(parameters.ContainsKey("ue"))
{
config.UserEmailAttribute = parameters["ue"];
config.Ldap.UserEmailAttribute = parameters["ue"];
}
if(parameters.ContainsKey("m"))
{
config.MemberAttribute = parameters["m"];
config.Ldap.MemberAttribute = parameters["m"];
}
config.EmailPrefixSuffix = parameters.ContainsKey("ps");
config.Ldap.EmailPrefixSuffix = parameters.ContainsKey("ps");
if(parameters.ContainsKey("ep"))
{
config.UserEmailPrefixAttribute = parameters["ep"];
config.Ldap.UserEmailPrefixAttribute = parameters["ep"];
}
if(parameters.ContainsKey("es"))
{
config.UserEmailSuffix = parameters["es"];
config.Ldap.UserEmailSuffix = parameters["es"];
}
if(parameters.ContainsKey("c"))
{
config.CreationDateAttribute = parameters["c"];
config.Ldap.CreationDateAttribute = parameters["c"];
}
if(parameters.ContainsKey("r"))
{
config.RevisionDateAttribute = parameters["r"];
config.Ldap.RevisionDateAttribute = parameters["r"];
}
}
}
@@ -588,19 +588,32 @@ namespace Bit.Console
if(config.SyncGroups &&
Core.Services.SettingsService.Instance.Server.Type != Core.Enums.DirectoryType.AzureActiveDirectory)
{
Con.Write("Group object class [{0}]: ", config.Ldap.GroupObjectClass);
input = Con.ReadLine();
if(!string.IsNullOrEmpty(input))
{
config.Ldap.GroupObjectClass = input;
}
Con.Write("Group filter [{0}]: ", config.GroupFilter);
input = Con.ReadLine();
if(!string.IsNullOrEmpty(input))
{
config.GroupFilter = input;
}
Con.Write("Group name attribute [{0}]: ", config.GroupNameAttribute);
Con.Write("Group name attribute [{0}]: ", config.Ldap.GroupNameAttribute);
input = Con.ReadLine();
if(!string.IsNullOrEmpty(input))
{
config.GroupNameAttribute = input;
config.Ldap.GroupNameAttribute = input;
}
}
Con.Write("Group path [{0}]: ", config.Ldap.GroupPath);
input = Con.ReadLine();
if(!string.IsNullOrEmpty(input))
{
config.Ldap.GroupPath = input;
}
Con.Write("Sync users? [{0}]: ", config.SyncUsers ? "y" : "n");
input = Con.ReadLine().ToLower();
if(!string.IsNullOrEmpty(input))
@@ -610,39 +623,51 @@ namespace Bit.Console
if(config.SyncUsers &&
Core.Services.SettingsService.Instance.Server.Type != Core.Enums.DirectoryType.AzureActiveDirectory)
{
Con.Write("User filter [{0}]: ", config.UserFilter);
Con.Write("User path [{0}]: ", config.Ldap.UserPath);
input = Con.ReadLine();
if(!string.IsNullOrEmpty(input))
{
config.UserFilter = input;
config.Ldap.GroupPath = input;
}
Con.Write("User email attribute [{0}]: ", config.UserEmailAttribute);
Con.Write("User object class [{0}]: ", config.Ldap.UserObjectClass);
input = Con.ReadLine();
if(!string.IsNullOrEmpty(input))
{
config.GroupNameAttribute = input;
config.Ldap.GroupObjectClass = input;
}
Con.Write("User email attribute [{0}]: ", config.Ldap.UserEmailAttribute);
input = Con.ReadLine();
if(!string.IsNullOrEmpty(input))
{
config.Ldap.GroupNameAttribute = input;
}
}
Con.Write("User filter [{0}]: ", config.UserFilter);
input = Con.ReadLine();
if(!string.IsNullOrEmpty(input))
{
config.UserFilter = input;
}
if(Core.Services.SettingsService.Instance.Server.Type != Core.Enums.DirectoryType.AzureActiveDirectory)
{
Con.Write("Member Of Attribute [{0}]: ", config.MemberAttribute);
Con.Write("Member Of Attribute [{0}]: ", config.Ldap.MemberAttribute);
input = Con.ReadLine();
if(!string.IsNullOrEmpty(input))
{
config.MemberAttribute = input;
config.Ldap.MemberAttribute = input;
}
Con.Write("Creation Attribute [{0}]: ", config.CreationDateAttribute);
Con.Write("Creation Attribute [{0}]: ", config.Ldap.CreationDateAttribute);
input = Con.ReadLine();
if(!string.IsNullOrEmpty(input))
{
config.CreationDateAttribute = input;
config.Ldap.CreationDateAttribute = input;
}
Con.Write("Changed Attribute [{0}]: ", config.RevisionDateAttribute);
Con.Write("Changed Attribute [{0}]: ", config.Ldap.RevisionDateAttribute);
input = Con.ReadLine();
if(!string.IsNullOrEmpty(input))
{
config.RevisionDateAttribute = input;
config.Ldap.RevisionDateAttribute = input;
}
}

View File

@@ -18,18 +18,15 @@ namespace Bit.Core.Models
switch(type)
{
case DirectoryType.ActiveDirectory:
CreationDateAttribute = "whenCreated";
RevisionDateAttribute = "whenChanged";
UserEmailPrefixAttribute = "sAMAccountName";
Ldap.CreationDateAttribute = "whenCreated";
Ldap.RevisionDateAttribute = "whenChanged";
Ldap.UserEmailPrefixAttribute = "sAMAccountName";
Ldap.UserPath = "Users";
Ldap.GroupPath = "Users";
break;
case DirectoryType.AzureActiveDirectory:
GroupFilter = null;
UserFilter = null;
MemberAttribute = null;
GroupNameAttribute = null;
UserEmailAttribute = null;
UserEmailPrefixAttribute = null;
UserEmailSuffix = null;
break;
case DirectoryType.Other:
IntervalMinutes = 60;
@@ -39,18 +36,27 @@ namespace Bit.Core.Models
}
}
public string GroupFilter { get; set; } = "(&(objectClass=group))";
public string UserFilter { get; set; } = "(&(objectClass=person))";
public string GroupFilter { get; set; }
public string UserFilter { get; set; }
public bool SyncGroups { get; set; } = true;
public bool SyncUsers { get; set; } = true;
public string MemberAttribute { get; set; } = "member";
public string GroupNameAttribute { get; set; } = "name";
public string UserEmailAttribute { get; set; } = "mail";
public bool EmailPrefixSuffix { get; set; } = false;
public string UserEmailPrefixAttribute { get; set; } = "cn";
public string UserEmailSuffix { get; set; } = "@companyname.com";
public string CreationDateAttribute { get; set; }
public string RevisionDateAttribute { get; set; }
public int IntervalMinutes { get; set; } = 5;
public LdapSyncConfiguration Ldap { get; set; } = new LdapSyncConfiguration();
public class LdapSyncConfiguration
{
public string UserPath { get; set; }
public string GroupPath { get; set; }
public string UserObjectClass { get; set; } = "person";
public string GroupObjectClass { get; set; } = "group";
public string MemberAttribute { get; set; } = "member";
public string GroupNameAttribute { get; set; } = "name";
public string UserEmailAttribute { get; set; } = "mail";
public bool EmailPrefixSuffix { get; set; } = false;
public string UserEmailPrefixAttribute { get; set; } = "cn";
public string UserEmailSuffix { get; set; } = "@companyname.com";
public string CreationDateAttribute { get; set; }
public string RevisionDateAttribute { get; set; }
}
}
}

View File

@@ -85,19 +85,13 @@ namespace Bit.Core.Services
var entry = SettingsService.Instance.Server.Ldap.GetDirectoryEntry();
string originalFilter;
var filter = originalFilter = string.IsNullOrWhiteSpace(SettingsService.Instance.Sync.GroupFilter) ? null :
SettingsService.Instance.Sync.GroupFilter;
var originalFilter = BuildBaseFilter(SettingsService.Instance.Sync.Ldap.GroupObjectClass,
SettingsService.Instance.Sync.GroupFilter);
var searchSinceRevision = !force && !string.IsNullOrWhiteSpace(SettingsService.Instance.Sync.RevisionDateAttribute) &&
SettingsService.Instance.LastGroupSyncDate.HasValue;
if(searchSinceRevision)
{
filter = string.Format("(&{0}({1}>={2}))",
filter,
SettingsService.Instance.Sync.RevisionDateAttribute,
SettingsService.Instance.LastGroupSyncDate.Value.ToGeneralizedTimeUTC());
}
var filter = originalFilter;
var revisionFilter = BuildRevisionFilter(filter, force, SettingsService.Instance.LastGroupSyncDate);
var searchSinceRevision = filter != revisionFilter;
filter = revisionFilter;
var searcher = new DirectorySearcher(entry, filter);
var result = searcher.FindAll();
@@ -118,8 +112,8 @@ namespace Bit.Core.Services
result = searcher.FindAll();
}
var userFilter = string.IsNullOrWhiteSpace(SettingsService.Instance.Sync.UserFilter) ? null :
SettingsService.Instance.Sync.UserFilter;
var userFilter = BuildBaseFilter(SettingsService.Instance.Sync.Ldap.UserObjectClass,
SettingsService.Instance.Sync.UserFilter);
var userSearcher = new DirectorySearcher(entry, userFilter);
var userResult = userSearcher.FindAll();
@@ -181,10 +175,10 @@ namespace Bit.Core.Services
}
// Name
if(item.Properties.Contains(SettingsService.Instance.Sync.GroupNameAttribute) &&
item.Properties[SettingsService.Instance.Sync.GroupNameAttribute].Count > 0)
if(item.Properties.Contains(SettingsService.Instance.Sync.Ldap.GroupNameAttribute) &&
item.Properties[SettingsService.Instance.Sync.Ldap.GroupNameAttribute].Count > 0)
{
group.Name = item.Properties[SettingsService.Instance.Sync.GroupNameAttribute][0].ToString();
group.Name = item.Properties[SettingsService.Instance.Sync.Ldap.GroupNameAttribute][0].ToString();
}
else if(item.Properties.Contains("cn") && item.Properties["cn"].Count > 0)
{
@@ -196,14 +190,14 @@ namespace Bit.Core.Services
}
// Dates
group.CreationDate = item.Properties.ParseDateTime(SettingsService.Instance.Sync.CreationDateAttribute);
group.RevisionDate = item.Properties.ParseDateTime(SettingsService.Instance.Sync.RevisionDateAttribute);
group.CreationDate = item.Properties.ParseDateTime(SettingsService.Instance.Sync.Ldap.CreationDateAttribute);
group.RevisionDate = item.Properties.ParseDateTime(SettingsService.Instance.Sync.Ldap.RevisionDateAttribute);
// Members
if(item.Properties.Contains(SettingsService.Instance.Sync.MemberAttribute) &&
item.Properties[SettingsService.Instance.Sync.MemberAttribute].Count > 0)
if(item.Properties.Contains(SettingsService.Instance.Sync.Ldap.MemberAttribute) &&
item.Properties[SettingsService.Instance.Sync.Ldap.MemberAttribute].Count > 0)
{
foreach(var member in item.Properties[SettingsService.Instance.Sync.MemberAttribute])
foreach(var member in item.Properties[SettingsService.Instance.Sync.Ldap.MemberAttribute])
{
var memberDn = member.ToString();
if(userIndex.ContainsKey(memberDn) && !group.UserMemberExternalIds.Contains(userIndex[memberDn]))
@@ -243,17 +237,9 @@ namespace Bit.Core.Services
}
var entry = SettingsService.Instance.Server.Ldap.GetDirectoryEntry();
var filter = string.IsNullOrWhiteSpace(SettingsService.Instance.Sync.UserFilter) ? null :
SettingsService.Instance.Sync.UserFilter;
if(!force && !string.IsNullOrWhiteSpace(SettingsService.Instance.Sync.RevisionDateAttribute) &&
SettingsService.Instance.LastUserSyncDate.HasValue)
{
filter = string.Format("(&{0}({1}>={2}))",
filter,
SettingsService.Instance.Sync.RevisionDateAttribute,
SettingsService.Instance.LastUserSyncDate.Value.ToGeneralizedTimeUTC());
}
var filter = BuildBaseFilter(SettingsService.Instance.Sync.Ldap.UserObjectClass,
SettingsService.Instance.Sync.UserFilter);
filter = BuildRevisionFilter(filter, force, SettingsService.Instance.LastUserSyncDate);
var searcher = new DirectorySearcher(entry, filter);
var result = searcher.FindAll();
@@ -293,6 +279,36 @@ namespace Bit.Core.Services
return Task.FromResult(users);
}
private static string BuildBaseFilter(string objectClass, string subFilter)
{
var filter = BuildObjectClassFilter(objectClass);
if(!string.IsNullOrWhiteSpace(subFilter))
{
filter = string.Format("(&{0}{1})", filter, subFilter);
}
return filter;
}
private static string BuildObjectClassFilter(string objectClass)
{
return string.Format("(&(objectClass={0}))", objectClass);
}
private static string BuildRevisionFilter(string baseFilter, bool force, DateTime? lastRevisionDate)
{
if(!force && lastRevisionDate.HasValue &&
!string.IsNullOrWhiteSpace(SettingsService.Instance.Sync.Ldap.RevisionDateAttribute))
{
baseFilter = string.Format("(&{0}({1}>={2}))",
baseFilter,
SettingsService.Instance.Sync.Ldap.RevisionDateAttribute,
lastRevisionDate.Value.ToGeneralizedTimeUTC());
}
return baseFilter;
}
private static UserEntry BuildUser(SearchResult item, bool deleted)
{
var user = new UserEntry
@@ -319,19 +335,19 @@ namespace Bit.Core.Services
user.Disabled = EntryDisabled(item);
// Email
if(SettingsService.Instance.Sync.EmailPrefixSuffix &&
item.Properties.Contains(SettingsService.Instance.Sync.UserEmailPrefixAttribute) &&
item.Properties[SettingsService.Instance.Sync.UserEmailPrefixAttribute].Count > 0 &&
!string.IsNullOrWhiteSpace(SettingsService.Instance.Sync.UserEmailSuffix))
if(SettingsService.Instance.Sync.Ldap.EmailPrefixSuffix &&
item.Properties.Contains(SettingsService.Instance.Sync.Ldap.UserEmailPrefixAttribute) &&
item.Properties[SettingsService.Instance.Sync.Ldap.UserEmailPrefixAttribute].Count > 0 &&
!string.IsNullOrWhiteSpace(SettingsService.Instance.Sync.Ldap.UserEmailSuffix))
{
user.Email = string.Concat(
item.Properties[SettingsService.Instance.Sync.UserEmailPrefixAttribute][0].ToString(),
SettingsService.Instance.Sync.UserEmailSuffix).ToLowerInvariant();
item.Properties[SettingsService.Instance.Sync.Ldap.UserEmailPrefixAttribute][0].ToString(),
SettingsService.Instance.Sync.Ldap.UserEmailSuffix).ToLowerInvariant();
}
else if(item.Properties.Contains(SettingsService.Instance.Sync.UserEmailAttribute) &&
item.Properties[SettingsService.Instance.Sync.UserEmailAttribute].Count > 0)
else if(item.Properties.Contains(SettingsService.Instance.Sync.Ldap.UserEmailAttribute) &&
item.Properties[SettingsService.Instance.Sync.Ldap.UserEmailAttribute].Count > 0)
{
user.Email = item.Properties[SettingsService.Instance.Sync.UserEmailAttribute][0]
user.Email = item.Properties[SettingsService.Instance.Sync.Ldap.UserEmailAttribute][0]
.ToString()
.ToLowerInvariant();
}
@@ -341,8 +357,8 @@ namespace Bit.Core.Services
}
// Dates
user.CreationDate = item.Properties.ParseDateTime(SettingsService.Instance.Sync.CreationDateAttribute);
user.RevisionDate = item.Properties.ParseDateTime(SettingsService.Instance.Sync.RevisionDateAttribute);
user.CreationDate = item.Properties.ParseDateTime(SettingsService.Instance.Sync.Ldap.CreationDateAttribute);
user.RevisionDate = item.Properties.ParseDateTime(SettingsService.Instance.Sync.Ldap.RevisionDateAttribute);
return user;
}