public IResult Collect(SearchString searchstring) { _logger.Debug($"Collecting"); LDAPSearchString searchString = (LDAPSearchString)searchstring; List <ILDAPObject> ldapObjects = new List <ILDAPObject>(); var results = Searcher.GetResultEntries(searchString).ToList(); foreach (var result in results) { //If we need User if (searchString.ReturnAttributes.Contains("sAMAccountName")) { var user = User.GetUserObject(result); ldapObjects.Add(user); } else { ldapObjects.Add(new LDAPBaseObject { Attributes = ProcessAttributes(result.Attributes), DistinguishedName = result.DistinguishedName }); } } CollectResult = new LDAPResult { LDAPObjects = ldapObjects, Title = searchstring.Title }; _logger.Debug("LDAP Objects Collected"); return(CollectResult); }
//Find one matching LDAP object from the global catalog //[adsisearcher]::new([adsi]"GC://DC","(filter)").FindOne() internal static SearchResultEntry GetResultEntry(LDAPSearchString searchString) { var connection = ConnectDirectory(true); var request = GetRequest(searchString.DN, searchString.Filter, searchString.ReturnAttributes, searchString.Scope); try { _logger.Debug("Sending Request..."); _logger.Debug($"Collecting {searchString.Filter} from ({searchString.DN}) with SearchScope.{searchString.Scope}"); var response = (SearchResponse)connection.SendRequest(request); _logger.Debug($"{response.Entries.Count} Entries Received"); if (response.Entries.Count == 0) { return(null); } return(response.Entries[0]); } catch (Exception e) { _logger.Warn(e.Message + $"[DN:({searchString.DN}) Filter:({searchString.Filter})]"); return(null); } finally { connection.Dispose(); } }
public IResult Collect(SearchString searchstring) { NestedGMSearchString searchString = (NestedGMSearchString)searchstring; _logger.Debug($"Collecting Nested Group Membership for {searchString.SAMAccountName}"); List <string> groupList = new List <string>(); Dictionary <string, string> groupMap = new Dictionary <string, string>(); string nameFilter = $"(sAMAccountName={searchString.SAMAccountName})"; var ldapSearchString = new LDAPSearchString { DN = Searcher.LdapInfo.RootDN, Filter = nameFilter, Scope = SearchScope.Subtree }; var resultEntry = Searcher.GetResultEntry(ldapSearchString); if (resultEntry == null) { return(null); } using (var userEntry = (Searcher.GetDirectoryEntry(resultEntry.DistinguishedName))) { //https://www.morgantechspace.com/2015/08/active-directory-tokengroups-vs-memberof.html //Use RefreshCach to get the constructed attribute tokenGroups. userEntry.RefreshCache(new string[] { "tokenGroups" }); foreach (byte[] sid in userEntry.Properties["tokenGroups"]) { string groupSID = new SecurityIdentifier(sid, 0).ToString(); string groupName = Helper.SIDNameSID(groupSID); groupList.Add(groupName); groupMap.Add(groupSID, groupName); } } //Somehow these groups are missing groupMap.Add("S-1-5-11", @"NT AUTHORITY\Authenticated Users"); groupMap.Add("S-1-5-15", @"NT AUTHORITY\This Organization"); UserSIDNameDictionary.Add(searchString.SAMAccountName.ToUpper(), groupMap); return(new ListResult { Title = searchString.Title, Result = groupList }); }
//Get the attribute value of a specific LDAP object from the global catalog //[adsisearcher]::new([adsi]"GC://DC","(filter)").FindOne().Properities[attribute] public static object GetSingleAttributeValue(string dn, string filter, string attribute) { _logger.Debug($"Trying to retrieve attribute {attribute}"); //We are searching from the global catalog, the target search base has to set to the forestDN var searchstring = new LDAPSearchString { DN = dn, Filter = filter, ReturnAttributes = new string[] { attribute }, Scope = SearchScope.Subtree, UseGlobalCatalog = true }; var result = GetResultEntry(searchstring); if (result == null) { _logger.Warn($"Cannot find object with {filter}"); return(null); } ; var value = result.Attributes[attribute][0]; return(value); }
//Find all matching LDAP objects from LDAP //[adsisearcher]::new([adsi]"LDAP://DC","(filter)").FindAll() public static IEnumerable <SearchResultEntry> GetResultEntries(LDAPSearchString searchString) { var connection = ConnectDirectory(searchString.UseGlobalCatalog); _logger.Debug($"Collecting {searchString.Filter} from ({searchString.DN}) with SearchScope.{searchString.Scope}"); try { var request = GetRequest(searchString.DN, searchString.Filter, searchString.ReturnAttributes, searchString.Scope); var pageReqControl = new PageResultRequestControl(500); request.Controls.Add(pageReqControl); while (true) { SearchResponse response; try { _logger.Debug("Sending Request..."); response = (SearchResponse)connection.SendRequest(request); _logger.Debug($"{response.Entries.Count} Entries Received"); } catch (Exception e) { _logger.Warn(e.Message + "[DN:" + searchString.DN + " Filter:" + searchString.Filter + "]"); yield break; } if (response.Controls.Length != 1 || !(response.Controls[0] is PageResultResponseControl)) { _logger.Error("The server does not support this advanced search operation"); yield break; } var pageResControl = (PageResultResponseControl)response.Controls[0]; //Console.WriteLine("\n[*] This page contains {0} response entries:\n", response.Entries.Count); if (response.Entries.Count != 0) { foreach (SearchResultEntry entry in response.Entries) { yield return(entry); } } if (pageResControl.Cookie.Length == 0) { break; } pageReqControl.Cookie = pageResControl.Cookie; } } finally { if (!searchString.UseGlobalCatalog) { _connectionPool.Add(connection); } else { connection.Dispose(); } } }