/// <summary> /// Determines if given LDAP object is group. /// </summary> /// <param name="entry">LDAP search result entry.</param> /// <param name="groupCategory">Group category Distinguished name.</param> public static bool IsGroup(SearchResultEntry entry, string groupCategory = "CN=Group") { string attributeToCheck = null; string valueToCheck = null; if (IsDeleted(entry)) { // Tombsones don't have object category, check object class attributeToCheck = GetAttributeString(entry.Attributes["objectClass"]); valueToCheck = "group"; } else { attributeToCheck = GetAttributeString(entry.Attributes["objectCategory"]); valueToCheck = groupCategory; } return (!string.IsNullOrEmpty(attributeToCheck) && !string.IsNullOrEmpty(valueToCheck) && attributeToCheck.ToLowerInvariant().Contains(valueToCheck.ToLowerInvariant())); }
/// <summary> /// Convert an search result entry to the LDAP User Entity /// /// NOT TESTED: Because it's difficult to mockup the SearchResultEntry Obj /// </summary> /// <param name="searchResultEntry">Result of a ldap search operation</param> /// <returns></returns> private static ILdapUser ConvertToLdapUser(SearchResultEntry searchResultEntry) { //Required attributes inizialization var tempUserCn = DefaultUserCn; var tempUserSn = DefaultUserSn; var tempUserOtherAttributes = new Dictionary<string, List<string>>(); //Cycle attributes if (searchResultEntry.Attributes.Values == null) return new LdapUser(searchResultEntry.DistinguishedName, tempUserCn, tempUserSn, tempUserOtherAttributes); foreach (DirectoryAttribute userReturnAttribute in searchResultEntry.Attributes.Values) { //if is CN or SN, set right String else add attribute to dictionary switch (userReturnAttribute.Name.ToUpper()) { case "CN": tempUserCn = (string)userReturnAttribute.GetValues(Type.GetType("System.String"))[0]; break; case "SN": tempUserSn = (string)userReturnAttribute.GetValues(Type.GetType("System.String"))[0]; break; default: tempUserOtherAttributes.Add( userReturnAttribute.Name, new List<string>(Array.ConvertAll( userReturnAttribute.GetValues(Type.GetType("System.String")), Convert.ToString))); break; } } return new LdapUser(searchResultEntry.DistinguishedName, tempUserCn, tempUserSn,tempUserOtherAttributes); }
protected static string StringOrNull(SearchResultEntry se, string attrName) { if (se.Attributes.Contains(attrName)) { return ((string[])se.Attributes[attrName].GetValues(typeof(string)))[0]; } return null; }
public override void Load(System.DirectoryServices.Protocols.SearchResultEntry entry) { ChangeTrackingDisabled = true; base.Load(entry); Sid = GetAttribute(entry.Attributes, SID); Parent = entry.DistinguishedName; ChangeTrackingDisabled = false; }
private SearchResultEntryCollection EntryHelper() { SearchResultEntryCollection searchResultEntryCollection = new SearchResultEntryCollection(); XmlNodeList xmlNodeLists = this.dsmlNode.SelectNodes("dsml:searchResultEntry", this.dsmlNS); if (xmlNodeLists.Count != 0) { foreach (XmlNode xmlNodes in xmlNodeLists) { SearchResultEntry searchResultEntry = new SearchResultEntry((XmlElement)xmlNodes); searchResultEntryCollection.Add(searchResultEntry); } } return(searchResultEntryCollection); }
private SearchResultEntryCollection EntryHelper() { SearchResultEntryCollection entrys = new SearchResultEntryCollection(); XmlNodeList list = base.dsmlNode.SelectNodes("dsml:searchResultEntry", base.dsmlNS); if (list.Count != 0) { foreach (XmlNode node in list) { SearchResultEntry entry = new SearchResultEntry((XmlElement)node); entrys.Add(entry); } } return(entrys); }
public void ReloadFromEntry(SearchResultEntry se) { this.DistinguishedName = se.DistinguishedName; this.OriginalDn = se.DistinguishedName; this.IsDnDirty = false; this.IsSuperiorDirty = false; this.Attrs.Clear(); foreach (string s in se.Attributes.AttributeNames) { this.Attrs.Add(s.ToLowerInvariant(), new Attr(s.ToLowerInvariant(), se.Attributes[s].GetValues(typeof(string)))); } }
private SearchResultEntryCollection EntryHelper() { SearchResultEntryCollection resultCollection = new SearchResultEntryCollection(); // Get the set of control nodes XmlNodeList nodeList = dsmlNode.SelectNodes("dsml:searchResultEntry", dsmlNS); if (nodeList.Count != 0) { foreach (XmlNode node in nodeList) { Debug.Assert(node is XmlElement); SearchResultEntry attribute = new SearchResultEntry((XmlElement)node); resultCollection.Add(attribute); } } return(resultCollection); }
/// <summary> /// Get LDAP object's uSNChanged attribute value. /// </summary> /// <param name="entry">LDAP object</param> public static long GetUsnChanged(SearchResultEntry entry) { return GetLongAttribute(entry, "uSNChanged") ?? 0; }
/// <summary> /// Determines whether user is enabled in domain. /// </summary> /// <param name="entry">User object</param> public static bool IsUserEnabled(SearchResultEntry entry) { if ((entry != null) && entry.Attributes.Contains("userAccountControl")) { int userAccountControl = Int32.Parse(entry.Attributes["userAccountControl"][0].ToString()); // Conjunct with disabled flag return !Convert.ToBoolean(userAccountControl & 0x0002); } return false; }
/// <summary> /// Get members of a group. /// </summary> /// <param name="entry">Group to get members from.</param> public static IEnumerable<string> GetGroupMembers(SearchResultEntry entry) { if ((entry != null) && IsGroup(entry) && (entry.Attributes.Contains("member"))) { return entry.Attributes["member"].GetValues(typeof(string)).Cast<string>(); } return new List<string>(); }
internal SearchResultEntry ConstructEntry(IntPtr entryMessage) { IntPtr dn = (IntPtr)0; string entryDn = null; IntPtr attribute = (IntPtr)0; IntPtr address = (IntPtr)0; SearchResultAttributeCollection attributes = null; try { // get the dn dn = Wldap32.ldap_get_dn(ldapHandle, entryMessage); if (dn != (IntPtr)0) { entryDn = Marshal.PtrToStringUni(dn); Wldap32.ldap_memfree(dn); dn = (IntPtr)0; } SearchResultEntry resultEntry = new SearchResultEntry(entryDn); attributes = resultEntry.Attributes; // get attributes attribute = Wldap32.ldap_first_attribute(ldapHandle, entryMessage, ref address); int tempcount = 0; while (attribute != (IntPtr)0) { DirectoryAttribute attr = ConstructAttribute(entryMessage, attribute); attributes.Add(attr.Name, attr); Wldap32.ldap_memfree(attribute); tempcount++; attribute = Wldap32.ldap_next_attribute(ldapHandle, entryMessage, address); } if (address != (IntPtr)0) { Wldap32.ber_free(address, 0); address = (IntPtr)0; } return resultEntry; } finally { if (dn != (IntPtr)0) { Wldap32.ldap_memfree(dn); } if (attribute != (IntPtr)0) Wldap32.ldap_memfree(attribute); if (address != (IntPtr)0) { Wldap32.ber_free(address, 0); } } }
public void CopyTo(SearchResultEntry[] values, int index) { base.InnerList.CopyTo(values, index); }
internal int Add(SearchResultEntry entry) { return base.InnerList.Add(entry); }
/// <summary> /// Handle single role. /// </summary> /// <param name="entry">Group LDAP object.</param> private void HandleGroup(SearchResultEntry entry) { // Create CMS object from LDAP object var role = new Role(LdapHelper.GetObjectGuid(entry), LdapHelper.GetAttributeString(entry.Attributes["sAMAccountName"], true), LdapHelper.GetAttributeString(entry.Attributes["displayName"]), GroupBindings.Select(k => new KeyValuePair<string, string>(k.Cms, LdapHelper.GetAttributeString(entry.Attributes[k.Ldap]))).ToList()); var existing = Replica.Groups.FirstOrDefault(g => g.Guid == role.Guid); List<User> currentMembers = (existing == null) ? new List<User>() : Replica.Bindings.Where(b => b.RoleId == existing.Id).SelectMany(b => Replica.Users.Where(u => u.Id == b.UserId)).ToList(); List<User> newMembers = LdapHelper.GetGroupMembers(entry).SelectMany(d => Replica.Users.Where(u => string.Equals(u.DistinguishedName, d, StringComparison.InvariantCultureIgnoreCase))).ToList(); if (LdapHelper.IsDeleted(entry)) { if (existing != null) { // Delete role Sender.RemoveRole(existing); Replica.Groups.Remove(existing); } } else { if (existing != null) { role.Id = existing.Id; // Check if any attribute has changed var roleXml = Sender.GetRole(role.Id); if (!string.IsNullOrEmpty(roleXml)) { bool roleChanged = Role.InternalBindings.Any( b => RestHelper.GetAttributeFromReponse(roleXml, b.Value) != (LdapHelper.GetAttributeString(entry.Attributes[b.Key], b.Key == "sAMAccountName") ?? string.Empty)); roleChanged |= GroupBindings.Any( b => RestHelper.GetAttributeFromReponse(roleXml, b.Cms) != (LdapHelper.GetAttributeString(entry.Attributes[b.Ldap]) ?? string.Empty)); if (roleChanged) { // Modify role Sender.ModifyRole(role); } } } else { // Add role long? roleId = Sender.AddRole(role); if (roleId != null) { role.Id = roleId.Value; Replica.Groups.Add(role); } } // Add members var addedMembers = newMembers.Where(m => currentMembers.All(c => c.Guid != m.Guid)).ToList(); foreach (var member in addedMembers) { var userroleId = Sender.AddUserToRole(member.Id, role.Id); if (userroleId != null) { Replica.Bindings.Add(new UserRoleBinding(member.Id, role.Id) { Id = userroleId.Value }); } } // Remove members var removedMembers = currentMembers.Where(m => newMembers.All(c => c.Guid != m.Guid)) .SelectMany(m => Replica.Bindings.Where(b => (b.RoleId == role.Id) && (b.UserId == m.Id))) .ToList(); foreach (var member in removedMembers) { Sender.RemoveUserFromRole(member.Id); Replica.Bindings.Remove(member); } } }
internal SearchResultEntry ConstructEntry(IntPtr entryMessage) { SearchResultEntry searchResultEntry; IntPtr intPtr = (IntPtr)0; string stringUni = null; IntPtr intPtr1 = (IntPtr)0; IntPtr intPtr2 = (IntPtr)0; try { intPtr = Wldap32.ldap_get_dn(this.ldapHandle, entryMessage); if (intPtr != (IntPtr)0) { stringUni = Marshal.PtrToStringUni(intPtr); Wldap32.ldap_memfree(intPtr); intPtr = (IntPtr)0; } SearchResultEntry searchResultEntry1 = new SearchResultEntry(stringUni); SearchResultAttributeCollection attributes = searchResultEntry1.Attributes; intPtr1 = Wldap32.ldap_first_attribute(this.ldapHandle, entryMessage, ref intPtr2); int num = 0; while (intPtr1 != (IntPtr)0) { DirectoryAttribute directoryAttribute = this.ConstructAttribute(entryMessage, intPtr1); attributes.Add(directoryAttribute.Name, directoryAttribute); Wldap32.ldap_memfree(intPtr1); num++; intPtr1 = Wldap32.ldap_next_attribute(this.ldapHandle, entryMessage, intPtr2); } if (intPtr2 != (IntPtr)0) { Wldap32.ber_free(intPtr2, 0); intPtr2 = (IntPtr)0; } searchResultEntry = searchResultEntry1; } finally { if (intPtr != (IntPtr)0) { Wldap32.ldap_memfree(intPtr); } if (intPtr1 != (IntPtr)0) { Wldap32.ldap_memfree(intPtr1); } if (intPtr2 != (IntPtr)0) { Wldap32.ber_free(intPtr2, 0); } } return searchResultEntry; }
private void SetCerts(SearchResultEntry entry, X509Certificate2Collection retVal) { if (entry.Attributes.Values == null || entry.Attributes.Count <= 0) { throw new LdapCertResolverException(LDAPError.NoUserCertificateAttribute); } foreach (DirectoryAttribute entryAttr in entry.Attributes.Values) { if (entryAttr.Count > 0) { // search could possibly return more than one entry and each entry may contain // more that one certificates foreach (object t in entryAttr) { try { var cert = new X509Certificate2((byte[])t); retVal.Add(cert); } catch (Exception ex) { this.Error.NotifyEvent(this, ex); } } } } }
private SearchResultEntryCollection EntryHelper() { SearchResultEntryCollection searchResultEntryCollection = new SearchResultEntryCollection(); XmlNodeList xmlNodeLists = this.dsmlNode.SelectNodes("dsml:searchResultEntry", this.dsmlNS); if (xmlNodeLists.Count != 0) { foreach (XmlNode xmlNodes in xmlNodeLists) { SearchResultEntry searchResultEntry = new SearchResultEntry((XmlElement)xmlNodes); searchResultEntryCollection.Add(searchResultEntry); } } return searchResultEntryCollection; }
private SearchResultEntryCollection EntryHelper() { SearchResultEntryCollection resultCollection = new SearchResultEntryCollection(); // Get the set of control nodes XmlNodeList nodeList = dsmlNode.SelectNodes("dsml:searchResultEntry", dsmlNS); if (nodeList.Count != 0) { foreach (XmlNode node in nodeList) { Debug.Assert(node is XmlElement); SearchResultEntry attribute = new SearchResultEntry((XmlElement)node); resultCollection.Add(attribute); } } return resultCollection; }
public Entry(SearchResultEntry se) { this.ReloadFromEntry(se); }
public override void Load(System.DirectoryServices.Protocols.SearchResultEntry entry) { base.Load(entry); Roles = GetRoles(Key, true); }
/// <summary> /// Handle single user. /// </summary> /// <param name="entry">User LDAP object.</param> private void HandleUser(SearchResultEntry entry) { // Create CMS object from LDAP object var user = new User( LdapHelper.GetObjectGuid(entry), LdapHelper.GetAttributeString(entry.Attributes["name"], true), LdapHelper.IsUserEnabled(entry), UserBindings.Select(k => new KeyValuePair<string, string>(k.Cms, LdapHelper.GetAttributeString(entry.Attributes[k.Ldap]))).ToList()); // Find existing object in LDAP replica var existing = Replica.Users.FirstOrDefault(u => u.Guid == user.Guid); if (LdapHelper.IsDeleted(entry)) { if (existing != null) { // Remove user Sender.RemoveUser(existing); Replica.Users.Remove(existing); } } else if (existing != null) { // Check if any attribute has changed var userXml = Sender.GetUser(user.Guid); if (!string.IsNullOrEmpty(userXml)) { bool userChanged = User.InternalBindings.Any( b => RestHelper.GetAttributeFromReponse(userXml, b.Value) != ((b.Key == "userAccountControl" ? LdapHelper.IsUserEnabled(entry).ToString().ToLowerInvariant() : LdapHelper.GetAttributeString(entry.Attributes[b.Key], b.Key == "name")) ?? string.Empty)); userChanged |= UserBindings.Any( b => RestHelper.GetAttributeFromReponse(userXml, b.Cms) != (LdapHelper.GetAttributeString(entry.Attributes[b.Ldap]) ?? string.Empty)); if (userChanged) { // Modify user Sender.ModifyUser(user); } } } else { // Add user long? userId = Sender.AddUser(user); if (userId != null) { user.Id = userId.Value; user.DistinguishedName = entry.DistinguishedName; Replica.Users.Add(user); } } }
public bool Contains(SearchResultEntry value) { return base.InnerList.Contains(value); }
/// <summary> /// Gets the first byte array attribute value from the supplied entry. /// </summary> /// <param name="name">The name of the attribute to retrieve.</param> /// <param name="entry">The SearchResultEntry to get the attribute value from.</param> /// <returns>A first byte value held in the attribute, or null array if there was an error retrieving the value or the attribute was empty.</returns> public byte[] GetByteAttributeValue(string name, SearchResultEntry entry) { byte[][] values = GetByteAttributeValues(name, entry); if (values.Any()) { return values[0]; } else { return null; } }
public int IndexOf(SearchResultEntry value) { return base.InnerList.IndexOf(value); }
/// <summary> /// Gets the first string attribute value from the supplied entry. /// </summary> /// <param name="name">The name of the attribute to retrieve.</param> /// <param name="entry">The SearchResultEntry to get the attribute value from.</param> /// <returns>A first string value held in the attribute, or null if there was an error retrieving the value or the attribute was empty.</returns> public string GetStringAttributeValue(string name, SearchResultEntry entry) { List<string> values = GetStringAttributeValues(name, entry); if (values != null && values.Count > 0) { return values[0]; } else { return null; } }
static string AttributeOf(SearchResultEntry entry, string attr) { return (string)entry.Attributes[attr]?.GetValues(typeof(string))[0]; }
/// <summary> /// Gets all string attribute values from the supplied entry. /// </summary> /// <param name="name">The name of the attribute to retrieve.</param> /// <param name="entry">The SearchResultEntry to get the attribute value from.</param> /// <returns>A list of string values held in the attribute, or null if there was an error retrieving the values or the attribute was empty.</returns> public List<string> GetStringAttributeValues(string name, SearchResultEntry entry) { if (!string.IsNullOrWhiteSpace(name) && entry != null) { if (entry.Attributes.Contains(name)) { try { return new List<string>((string[])entry.Attributes[name].GetValues(typeof(string))); } catch { // There was an error retrieving the value. return null; } } else { // The entry does not contain an attribute with the supplied name. return null; } } else { return null; } }
/// <summary> /// Get LDAP object GUID. /// </summary> /// <param name="entry">LDAP object</param> public static Guid GetObjectGuid(SearchResultEntry entry) { if ((entry != null) && (entry.Attributes.Contains("objectGUID"))) { return new Guid((byte[])entry.Attributes["objectGUID"][0]); } return Guid.Empty; }
/// <summary> /// Determines whether object has been deleted. /// </summary> /// <param name="entry">LDAP search result entry.</param> public static bool IsDeleted(SearchResultEntry entry) { return entry.Attributes.Contains("isDeleted") && Convert.ToBoolean(GetAttributeString(entry.Attributes["isDeleted"])); }
/// <summary> /// Get LDAP object's attribute long representation. /// </summary> /// <param name="entry">LDAP object</param> /// <param name="attribute">Attribute to get</param> public static long? GetLongAttribute(SearchResultEntry entry, string attribute) { if ((entry != null) && (entry.Attributes.Contains(attribute))) { return Convert.ToInt64(GetAttributeString(entry.Attributes[attribute])); } return null; }
public bool Contains(SearchResultEntry value) { return(InnerList.Contains(value)); }
// ----- CONSTRUCTORS ----- /// <summary> /// Establishes a connection with an LDAP server that can be used to query or modify its contents. /// <param name="servers">A list of servers by fully qualified domain name, host name, ip address, or null.</param> /// <param name="portNumber">The port number on the LDAP server that is listening for requests.</param> /// <param name="authType">(Optional) The type of authentication to use when connecting with the server. By default this is set to Anonymous (i.e. no credentials required).</param> /// <param name="userName">(Optional) The user name to use when connecting to the LDAP server.</param> /// <param name="password">(Optional) The password to use with the user name provided to connect to the LDAP server.</param> /// <param name="domainName">(Optional) The domain or computer name associated with the user credentials provided.</param> /// </summary> public LDAP(List<string> servers, int portNumber, AuthType authType = AuthType.Anonymous, string userName = null, SecureString password = null, string domainName = null) { if (servers != null && servers.Count > 0 && portNumber > 0 && !string.IsNullOrWhiteSpace(userName) && password != null) { try { // Setup the server information for the connection. LdapDirectoryIdentifier directoryIdentifier = new LdapDirectoryIdentifier(servers.ToArray(), portNumber, false, false); // Setup the credential to use when accessing the server. (Or null for Anonymous.) NetworkCredential credential = null; if (authType != AuthType.Anonymous) { credential = new NetworkCredential(userName, password); if (!string.IsNullOrWhiteSpace(domainName)) { // A domain was provided. Use it when creating the credential. credential.Domain = domainName; } } // Create the connection to the server(s). try { connection = new LdapConnection(directoryIdentifier, credential, authType); // Gather information about the LDAP server(s) from the RootDSE entry. SearchResponse rootDSESearchResponse = (SearchResponse)connection.SendRequest(new SearchRequest(null, "(objectClass=*)", SearchScope.Base)); if (rootDSESearchResponse != null && rootDSESearchResponse.ResultCode == ResultCode.Success) { // Save the rootDSE for access by API clients. rootDSE = rootDSESearchResponse.Entries[0]; SearchResultAttributeCollection attributes = rootDSE.Attributes; // Check that LDAP V3 is supported. if (attributes["supportedLDAPVersion"].GetValues(typeof(string)).Contains("3")) { // Get all of the naming contexts this server(s) supports. namingContexts = (string[])attributes["namingContexts"].GetValues(typeof(string)); // Set the base DN for searching to the first naming context in the list. searchBaseDN = namingContexts[0]; // Get any alternate servers can complete our requests should this one stop responding. // If there are not other servers to contact this attribute is not available. if (attributes.Contains("altServer")) { alternateServers = (string[])attributes["altServer"].GetValues(typeof(string)); } } else { throw new NotSupportedException("The directory server does not support LDAP v3."); } } // Bind to the ldap server with the connection credentials if supplied. if (connection.AuthType != AuthType.Anonymous) { connection.Bind(); } } catch (System.ComponentModel.InvalidEnumArgumentException) { // Thrown when authType is out of range. throw new ArgumentOutOfRangeException("authType"); } } catch (ArgumentException) { throw new ArgumentException("Entries in the servers parameter can not have spaces."); } } else { if (servers == null || servers.Count == 0) { throw new ArgumentNullException("servers", "The list of servers can not be null or empty."); } if (portNumber <= 0) { throw new ArgumentOutOfRangeException("portNumber", "A port number must be positive."); } } }
public override ReadOnlyCollection<object> GetValuesAsLanguageType(SearchResultEntry se, string attrName) { AttributeSchema aSchema = this.GetAttribute(attrName); if (aSchema == null) throw new ApplicationException("Unknown attribute " + attrName); List<object> results = new List<object>(); switch (attrName.ToLower()) { case "pwdlastset": case "accountexpires": case "badpasswordtime": case "lockouttime": case "lastlogontimestamp": case "lastlogon": { foreach (string s in se.Attributes[attrName].GetValues(typeof(string))) { Int64 n = Int64.Parse(s); if (n == 0 || n == 0x7FFFFFFFFFFFFFFF) results.Add("NEVER"); else try { results.Add(DateTime.FromFileTimeUtc(n)); } catch (Exception ex) { logger.Warn("Couldn't convert {0} to DateTime: {1}", s, ex.Message); } } } break; case "objectguid": { foreach (byte[] bytes in se.Attributes[attrName].GetValues(typeof(byte[]))) results.Add(new Guid(bytes)); } break; default: switch (aSchema.LangType) { case AttrLangType.NtSID: { foreach (byte[] bytes in se.Attributes[attrName].GetValues(typeof(byte[]))) results.Add(new SecurityIdentifier(bytes, 0)); } break; case AttrLangType.NtSecurityDescriptor: { foreach (byte[] bytes in se.Attributes[attrName].GetValues(typeof(byte[]))) results.Add(new RawSecurityDescriptor(bytes, 0)); } break; default: return base.GetValuesAsLanguageType(se, attrName); } break; } return new System.Collections.ObjectModel.ReadOnlyCollection<object>(results); }
internal int Add(SearchResultEntry entry) { return(InnerList.Add(entry)); }
public MutableEntry(SearchResultEntry se) : base(se) { }
public int IndexOf(SearchResultEntry value) { return(InnerList.IndexOf(value)); }
public virtual ReadOnlyCollection<object> GetValuesAsLanguageType(SearchResultEntry se, string attrName) { AttributeSchema aSchema = this.GetAttribute(attrName); if (aSchema == null) throw new ApplicationException("Unknown attribute " + attrName); List<object> results = new List<object>(); if (se.Attributes.Contains(attrName)) { switch (aSchema.LangType) { case AttrLangType.GeneralizedTime: foreach (string s in se.Attributes[attrName].GetValues(typeof(string))) { // 20090203065703.0Z string t = s.Replace(".0Z", ""); DateTime dt = DateTime.ParseExact(t, new string[] { "yyyyMMddHHmmss"}, null, System.Globalization.DateTimeStyles.AssumeUniversal); results.Add(dt); } break; case AttrLangType.Boolean: { foreach (string s in se.Attributes[attrName].GetValues(typeof(string))) results.Add(bool.Parse(s)); } break; case AttrLangType.Int32: { foreach (string s in se.Attributes[attrName].GetValues(typeof(string))) results.Add(Int32.Parse(s)); } break; case AttrLangType.Int64: { foreach (string s in se.Attributes[attrName].GetValues(typeof(string))) results.Add(Int64.Parse(s)); } break; case AttrLangType.OctetString: results.AddRange(se.Attributes[attrName].GetValues(typeof(byte[]))); break; case AttrLangType.DirectoryString: case AttrLangType.CaseInsensitiveString: case AttrLangType.DN: default: results.AddRange(se.Attributes[attrName].GetValues(typeof(string))); break; } } return new System.Collections.ObjectModel.ReadOnlyCollection<object>(results); }