public static IEnumerable <DNSRecord> Get_DomainDNSRecord(Args_Get_DomainDNSRecord args = null)
        {
            if (args == null)
            {
                args = new Args_Get_DomainDNSRecord();
            }

            var SearcherArguments = new Args_Get_DomainSearcher
            {
                LDAPFilter       = @"(objectClass=dnsNode)",
                SearchBasePrefix = $@"DC={args.ZoneName},CN=MicrosoftDNS,DC=DomainDnsZones",
                Domain           = args.Domain,
                Server           = args.Server,
                Properties       = args.Properties,
                ResultPageSize   = args.ResultPageSize,
                ServerTimeLimit  = args.ServerTimeLimit,
                Credential       = args.Credential
            };
            var DNSSearcher = GetDomainSearcher.Get_DomainSearcher(SearcherArguments);

            SearchResult[]   Results = null;
            List <DNSRecord> Outs    = null;

            if (DNSSearcher != null)
            {
                if (args.FindOne)
                {
                    Results = new SearchResult[] { DNSSearcher.FindOne() };
                }
                else
                {
                    var items = DNSSearcher.FindAll();
                    if (items != null)
                    {
                        Results = new SearchResult[items.Count];
                        items.CopyTo(Results, 0);
                    }
                }
                if (Results != null)
                {
                    foreach (var result in Results)
                    {
                        DNSRecord Out = null;
                        try
                        {
                            var ldapProperty = ConvertLDAPProperty.Convert_LDAPProperty(result.Properties);
                            Out = new DNSRecord
                            {
                                name = ldapProperty.name,
                                distinguishedname = ldapProperty.distinguishedname,
                                dnsrecord         = ldapProperty.dnsrecord,
                                whencreated       = ldapProperty.whencreated,
                                whenchanged       = ldapProperty.whenchanged,
                                ZoneName          = args.ZoneName
                            };

                            // convert the record and extract the properties
                            DNSRecord Record = null;
                            if (Out.dnsrecord is System.DirectoryServices.ResultPropertyValueCollection)
                            {
                                // TODO: handle multiple nested records properly?
                                Record = Convert_DNSRecord((Out.dnsrecord as System.DirectoryServices.ResultPropertyValueCollection)[0] as byte[]);
                            }
                            else
                            {
                                Record = Convert_DNSRecord(Out.dnsrecord as byte[]);
                            }

                            if (Record != null)
                            {
                                if (Record.RecordType != null)
                                {
                                    Out.RecordType = Record.RecordType;
                                }
                                else if (Record.UpdatedAtSerial != null)
                                {
                                    Out.UpdatedAtSerial = Record.UpdatedAtSerial;
                                }
                                else if (Record.TTL != null)
                                {
                                    Out.TTL = Record.TTL;
                                }
                                else if (Record.Age != null)
                                {
                                    Out.Age = Record.Age;
                                }
                                else if (Record.TimeStamp != null)
                                {
                                    Out.TimeStamp = Record.TimeStamp;
                                }
                                else if (Record.Data.IsNotNullOrEmpty())
                                {
                                    Out.Data = Record.Data;
                                }
                                else if (Record.ZoneName.IsNotNullOrEmpty())
                                {
                                    Out.ZoneName = Record.ZoneName;
                                }
                                else if (Record.name.IsNotNullOrEmpty())
                                {
                                    Out.name = Record.name;
                                }
                                else if (Record.distinguishedname.IsNotNullOrEmpty())
                                {
                                    Out.distinguishedname = Record.distinguishedname;
                                }
                                else if (Record.dnsrecord != null)
                                {
                                    Out.dnsrecord = Record.dnsrecord;
                                }
                                else if (Record.whencreated != null)
                                {
                                    Out.whencreated = Record.whencreated;
                                }
                                else if (Record.whenchanged != null)
                                {
                                    Out.whenchanged = Record.whenchanged;
                                }
                            }
                        }
                        catch (Exception e)
                        {
                            Logger.Write_Warning($@"[Get-DomainDNSRecord] Error: {e}");
                        }
                        if (Outs == null)
                        {
                            Outs = new List <DNSRecord>();
                        }
                        Outs.Add(Out);
                    }
                }
                DNSSearcher.Dispose();
            }
            return(Outs);
        }
Beispiel #2
0
        public static IEnumerable <IDomainTrust> Get_DomainTrust(Args_Get_DomainTrust args = null)
        {
            if (args == null)
            {
                args = new Args_Get_DomainTrust();
            }

            var LdapSearcherArguments = new Args_Get_DomainSearcher
            {
                Domain          = args.Domain,
                LDAPFilter      = args.LDAPFilter,
                Properties      = args.Properties,
                SearchBase      = args.SearchBase,
                Server          = args.Server,
                SearchScope     = args.SearchScope,
                ResultPageSize  = args.ResultPageSize,
                ServerTimeLimit = args.ServerTimeLimit,
                Tombstone       = args.Tombstone,
                Credential      = args.Credential
            };

            Args_Get_DomainSID NetSearcherArguments = null;
            string             SourceDomain         = null;

            if (!args.API)
            {
                NetSearcherArguments = new Args_Get_DomainSID();
                if (args.Domain.IsNotNullOrEmpty() && args.Domain.Trim() != "")
                {
                    SourceDomain = args.Domain;
                }
                else
                {
                    if (args.Credential != null)
                    {
                        SourceDomain = GetDomain.Get_Domain(new Args_Get_Domain {
                            Credential = args.Credential
                        }).Name;
                    }
                    else
                    {
                        SourceDomain = GetDomain.Get_Domain().Name;
                    }
                }
            }
            else if (!args.NET)
            {
                if (args.Domain != null && args.Domain.Trim() != "")
                {
                    SourceDomain = args.Domain;
                }
                else
                {
                    SourceDomain = Environment.GetEnvironmentVariable("USERDNSDOMAIN");
                }
            }

            var DomainTrusts = new List <IDomainTrust>();

            if (!args.API && !args.NET)
            {
                // if we're searching for domain trusts through LDAP/ADSI
                var TrustSearcher = GetDomainSearcher.Get_DomainSearcher(LdapSearcherArguments);
                var SourceSID     = GetDomainSID.Get_DomainSID(NetSearcherArguments);

                if (TrustSearcher != null)
                {
                    TrustSearcher.Filter = @"(objectClass=trustedDomain)";

                    SearchResult[] Results = null;
                    if (args.FindOne)
                    {
                        Results = new SearchResult[] { TrustSearcher.FindOne() };
                    }
                    else
                    {
                        var items = TrustSearcher.FindAll();
                        if (items != null)
                        {
                            Results = new SearchResult[items.Count];
                            items.CopyTo(Results, 0);
                        }
                    }
                    if (Results != null)
                    {
                        foreach (var result in Results)
                        {
                            var Props       = result.Properties;
                            var DomainTrust = new LdapDomainTrust();

                            var TrustAttrib = (TrustAttribute)Props[@"trustattributes"][0];

                            var Direction = (TrustDirection)Props[@"trustdirection"][0];

                            var TrustType = (TrustType)Props[@"trusttype"][0];

                            var Distinguishedname = Props[@"distinguishedname"][0] as string;
                            var SourceNameIndex   = Distinguishedname.IndexOf(@"DC=");
                            if (SourceNameIndex != 0)
                            {
                                SourceDomain = Distinguishedname.Substring(SourceNameIndex).Replace(@"DC=", @"").Replace(@",", @".");
                            }
                            else
                            {
                                SourceDomain = @"";
                            }

                            var    TargetNameIndex = Distinguishedname.IndexOf(@",CN=System");
                            string TargetDomain    = null;
                            if (SourceNameIndex != 0)
                            {
                                TargetDomain = Distinguishedname.Substring(3, TargetNameIndex - 3);
                            }
                            else
                            {
                                TargetDomain = @"";
                            }

                            var ObjectGuid = new Guid(Props[@"objectguid"][0] as byte[]);
                            var TargetSID  = (new System.Security.Principal.SecurityIdentifier(Props[@"securityidentifier"][0] as byte[], 0)).Value;

                            DomainTrust = new LdapDomainTrust
                            {
                                SourceName      = SourceDomain,
                                TargetName      = Props[@"name"][0] as string,
                                TrustType       = TrustType,
                                TrustAttributes = TrustAttrib,
                                TrustDirection  = Direction,
                                WhenCreated     = Props[@"whencreated"][0],
                                WhenChanged     = Props[@"whenchanged"][0]
                            };
                            DomainTrusts.Add(DomainTrust);
                        }
                    }
                    TrustSearcher.Dispose();
                }
            }
            else if (args.API)
            {
                // if we're searching for domain trusts through Win32 API functions
                string TargetDC = null;
                if (args.Server.IsNotNullOrEmpty())
                {
                    TargetDC = args.Server;
                }
                else if (args.Domain != null && args.Domain.Trim() != @"")
                {
                    TargetDC = args.Domain;
                }
                else
                {
                    // see https://msdn.microsoft.com/en-us/library/ms675976(v=vs.85).aspx for default NULL behavior
                    TargetDC = null;
                }

                // arguments for DsEnumerateDomainTrusts
                var PtrInfo = IntPtr.Zero;

                // 63 = DS_DOMAIN_IN_FOREST + DS_DOMAIN_DIRECT_OUTBOUND + DS_DOMAIN_TREE_ROOT + DS_DOMAIN_PRIMARY + DS_DOMAIN_NATIVE_MODE + DS_DOMAIN_DIRECT_INBOUND
                uint Flags       = 63;
                uint DomainCount = 0;

                // get the trust information from the target server
                var Result = NativeMethods.DsEnumerateDomainTrusts(TargetDC, Flags, out PtrInfo, out DomainCount);

                // Locate the offset of the initial intPtr
                var Offset = PtrInfo.ToInt64();

                // 0 = success
                if (Result == 0 && Offset > 0)
                {
                    // Work out how much to increment the pointer by finding out the size of the structure
                    var Increment = Marshal.SizeOf(typeof(NativeMethods.DS_DOMAIN_TRUSTS));

                    // parse all the result structures
                    for (var i = 0; i < DomainCount; i++)
                    {
                        // create a new int ptr at the given offset and cast the pointer as our result structure
                        var NewIntPtr = new IntPtr(Offset);
                        var Info      = (NativeMethods.DS_DOMAIN_TRUSTS)Marshal.PtrToStructure(NewIntPtr, typeof(NativeMethods.DS_DOMAIN_TRUSTS));

                        Offset  = NewIntPtr.ToInt64();
                        Offset += Increment;

                        var  SidString = @"";
                        bool ret       = NativeMethods.ConvertSidToStringSid(Info.DomainSid, out SidString);
                        var  LastError = Marshal.GetLastWin32Error();

                        if (ret == false)
                        {
                            Logger.Write_Verbose($@"[Get-DomainTrust] Error: {new System.ComponentModel.Win32Exception(LastError).Message}");
                        }
                        else
                        {
                            var DomainTrust = new ApiDomainTrust
                            {
                                SourceName        = SourceDomain,
                                TargetName        = Info.DnsDomainName,
                                TargetNetbiosName = Info.NetbiosDomainName,
                                Flags             = Info.Flags,
                                ParentIndex       = Info.ParentIndex,
                                TrustType         = (NativeMethods.DS_DOMAIN_TRUST_TYPE)Info.TrustType,
                                TrustAttributes   = Info.TrustAttributes,
                                TargetSid         = SidString,
                                TargetGuid        = Info.DomainGuid
                            };
                            DomainTrusts.Add(DomainTrust);
                        }
                    }
                    // free up the result buffer
                    NativeMethods.NetApiBufferFree(PtrInfo);
                }
                else
                {
                    Logger.Write_Verbose($@"[Get-DomainTrust] Error: {new System.ComponentModel.Win32Exception((int)Result).Message}");
                }
            }
            else
            {
                // if we're searching for domain trusts through .NET methods
                var FoundDomain = GetDomain.Get_Domain(new Args_Get_Domain
                {
                    Domain     = NetSearcherArguments.Domain,
                    Credential = NetSearcherArguments.Credential
                });
                if (FoundDomain != null)
                {
                    var items = FoundDomain.GetAllTrustRelationships();
                    foreach (TrustRelationshipInformation item in items)
                    {
                        DomainTrusts.Add(new NetDomainTrust
                        {
                            SourceName     = item.SourceName,
                            TargetName     = item.TargetName,
                            TrustDirection = item.TrustDirection,
                            TrustType      = item.TrustType
                        });
                    }
                }
            }
            return(DomainTrusts);
        }
Beispiel #3
0
        public static Dictionary <string, string> Get_DomainGUIDMap(Args_Get_DomainGUIDMap args = null)
        {
            if (args == null)
            {
                args = new Args_Get_DomainGUIDMap();
            }

            var GUIDs = new Dictionary <string, string>
            {
                { @"00000000-0000-0000-0000-000000000000", @"All" }
            };

            var ForestArguments = new Args_Get_Forest()
            {
                Credential = args.Credential
            };

            string SchemaPath = null;

            try
            {
                SchemaPath = GetForest.Get_Forest(ForestArguments).Forest.Schema.Name;
            }
            catch
            {
                throw new Exception(@"[Get-DomainGUIDMap] Error in retrieving forest schema path from Get-Forest");
            }
            if (SchemaPath.IsNullOrEmpty())
            {
                throw new Exception(@"[Get-DomainGUIDMap] Error in retrieving forest schema path from Get-Forest");
            }

            var SearcherArguments = new Args_Get_DomainSearcher
            {
                SearchBase      = SchemaPath,
                LDAPFilter      = @"(schemaIDGUID=*)",
                Domain          = args.Domain,
                Server          = args.Server,
                ResultPageSize  = args.ResultPageSize,
                ServerTimeLimit = args.ServerTimeLimit,
                Credential      = args.Credential
            };
            var SchemaSearcher = GetDomainSearcher.Get_DomainSearcher(SearcherArguments);

            if (SchemaSearcher != null)
            {
                try
                {
                    var Results = SchemaSearcher.FindAll();
                    if (Results != null)
                    {
                        foreach (SearchResult result in Results)
                        {
                            GUIDs[(new Guid(result.Properties["schemaidguid"][0] as byte[])).ToString()] = result.Properties["name"][0].ToString();
                        }
                        try { Results.Dispose(); }
                        catch (Exception e)
                        {
                            Logger.Write_Verbose($@"[Get-DomainGUIDMap] Error disposing of the Results object: {e}");
                        }
                    }
                    SchemaSearcher.Dispose();
                }
                catch (Exception e)
                {
                    Logger.Write_Verbose($@"[Get-DomainGUIDMap] Error in building GUID map: {e}");
                }
            }

            SearcherArguments.SearchBase = SchemaPath.Replace(@"Schema", @"Extended-Rights");
            SearcherArguments.LDAPFilter = @"(objectClass=controlAccessRight)";
            var RightsSearcher = GetDomainSearcher.Get_DomainSearcher(SearcherArguments);

            if (RightsSearcher != null)
            {
                try
                {
                    var Results = RightsSearcher.FindAll();
                    if (Results != null)
                    {
                        foreach (SearchResult result in Results)
                        {
                            GUIDs[(new Guid(result.Properties["rightsguid"][0] as byte[])).ToString()] = result.Properties["name"][0].ToString();
                        }
                        try { Results.Dispose(); }
                        catch (Exception e)
                        {
                            Logger.Write_Verbose($@"[Get-DomainGUIDMap] Error disposing of the Results object: {e}");
                        }
                    }
                    RightsSearcher.Dispose();
                }
                catch (Exception e)
                {
                    Logger.Write_Verbose($@"[Get-DomainGUIDMap] Error in building GUID map: {e}");
                }
            }
            return(GUIDs);
        }
Beispiel #4
0
        public static IEnumerable <object> Get_DomainObject(Args_Get_DomainObject args = null)
        {
            if (args == null)
            {
                args = new Args_Get_DomainObject();
            }

            var SearcherArguments = new Args_Get_DomainSearcher
            {
                Domain          = args.Domain,
                Properties      = args.Properties,
                SearchBase      = args.SearchBase,
                Server          = args.Server,
                SearchScope     = args.SearchScope,
                ResultPageSize  = args.ResultPageSize,
                ServerTimeLimit = args.ServerTimeLimit,
                SecurityMasks   = args.SecurityMasks,
                Tombstone       = args.Tombstone,
                Credential      = args.Credential
            };

            var ObjectSearcher = GetDomainSearcher.Get_DomainSearcher(SearcherArguments);
            var Objects        = new List <object>();

            if (ObjectSearcher != null)
            {
                var IdentityFilter = "";
                var Filter         = "";
                if (args.Identity != null)
                {
                    foreach (var samName in args.Identity)
                    {
                        var IdentityInstance = samName.Replace(@"(", @"\28").Replace(@")", @"\29");
                        if (new Regex(@"^S-1-").Match(IdentityInstance).Success)
                        {
                            IdentityFilter += $@"(objectsid={IdentityInstance})";
                        }
                        else if (new Regex(@"^(CN|OU|DC)=").Match(IdentityInstance).Success)
                        {
                            IdentityFilter += $@"(distinguishedname={IdentityInstance})";
                            if (args.Domain.IsNullOrEmpty() && args.SearchBase.IsNullOrEmpty())
                            {
                                // if a -Domain isn't explicitly set, extract the object domain out of the distinguishedname
                                // and rebuild the domain searcher
                                var IdentityDomain = IdentityInstance.Substring(IdentityInstance.IndexOf(@"DC=")).Replace(@"DC=", @"").Replace(@",", @".");
                                Logger.Write_Verbose($@"[Get-DomainObject] Extracted domain '{IdentityDomain}' from '{IdentityInstance}'");
                                SearcherArguments.Domain = IdentityDomain;
                                ObjectSearcher           = GetDomainSearcher.Get_DomainSearcher(SearcherArguments);
                                if (ObjectSearcher == null)
                                {
                                    Logger.Write_Warning($@"[Get-DomainObject] Unable to retrieve domain searcher for '{IdentityDomain}'");
                                }
                            }
                        }
                        else if (new Regex(@"^[0-9A-F]{8}-([0-9A-F]{4}-){3}[0-9A-F]{12}$").Match(IdentityInstance).Success)
                        {
                            var GuidByteString = string.Join(string.Empty, Guid.Parse(IdentityInstance).ToByteArray().Select(x => x.ToString(@"\X2")));
                            IdentityFilter += $@"(objectguid={GuidByteString})";
                        }
                        else if (IdentityInstance.Contains(@"\"))
                        {
                            var ConvertedIdentityInstance = ConvertADName.Convert_ADName(new Args_Convert_ADName
                            {
                                OutputType = ADSNameType.Canonical,
                                Identity   = new string[] { IdentityInstance.Replace(@"\28", @"(").Replace(@"\29", @")") }
                            });
                            if (ConvertedIdentityInstance != null && ConvertedIdentityInstance.Any())
                            {
                                var ObjectDomain = ConvertedIdentityInstance.First().Substring(0, ConvertedIdentityInstance.First().IndexOf('/'));
                                var ObjectName   = IdentityInstance.Split(new char[] { '\\' })[1];
                                IdentityFilter          += $@"(samAccountName={ObjectName})";
                                SearcherArguments.Domain = ObjectDomain;
                                Logger.Write_Verbose($@"[Get-DomainObject] Extracted domain '{ObjectDomain}' from '{IdentityInstance}'");
                                ObjectSearcher = GetDomainSearcher.Get_DomainSearcher(SearcherArguments);
                            }
                        }
                        else if (IdentityInstance.Contains(@"."))
                        {
                            IdentityFilter += $@"(|(samAccountName={IdentityInstance})(name={IdentityInstance})(dnshostname={IdentityInstance}))";
                        }
                        else
                        {
                            IdentityFilter += $@"(|(samAccountName={IdentityInstance})(name={IdentityInstance})(displayname={IdentityInstance}))";
                        }
                    }
                }
                if (IdentityFilter != null && IdentityFilter.Trim() != "")
                {
                    Filter += $@"(|{IdentityFilter})";
                }
                if (args.LDAPFilter.IsNotNullOrEmpty())
                {
                    Logger.Write_Verbose($@"[Get-DomainObject] Using additional LDAP filter: {args.LDAPFilter}");
                    Filter += $@"{args.LDAPFilter}";
                }
                // build the LDAP filter for the dynamic UAC filter value
                var uacs = args.UACFilter.ExtractValues();
                foreach (var uac in uacs)
                {
                    if (uac.IsNot())
                    {
                        Filter += $@"(!(userAccountControl:1.2.840.113556.1.4.803:={uac.GetValueAsInteger()}))";
                    }
                    else
                    {
                        Filter += $@"(userAccountControl:1.2.840.113556.1.4.803:={uac.GetValueAsInteger()})";
                    }
                }
                if (Filter != null && Filter != "")
                {
                    ObjectSearcher.Filter = $@"(&{Filter})";
                }
                Logger.Write_Verbose($@"[Get-DomainObject] Get-DomainComputer filter string: {ObjectSearcher.Filter}");

                if (args.FindOne)
                {
                    var result = ObjectSearcher.FindOne();
                    if (args.Raw)
                    {
                        // return raw result objects
                        Objects.Add(result);
                    }
                    else
                    {
                        Objects.Add(ConvertLDAPProperty.Convert_LDAPProperty(result.Properties));
                    }
                }
                else
                {
                    var Results = ObjectSearcher.FindAll();
                    foreach (SearchResult result in Results)
                    {
                        if (args.Raw)
                        {
                            // return raw result objects
                            Objects.Add(result);
                        }
                        else
                        {
                            Objects.Add(ConvertLDAPProperty.Convert_LDAPProperty(result.Properties));
                        }
                    }
                    if (Results != null)
                    {
                        try { Results.Dispose(); }
                        catch (Exception e)
                        {
                            Logger.Write_Verbose($@"[Get-DomainObject] Error disposing of the Results object: {e}");
                        }
                    }
                }
                ObjectSearcher.Dispose();
            }
            return(Objects);
        }
Beispiel #5
0
        private static IEnumerable <DFSShare> Get_DomainDFSShareV2(Args_Get_DomainSearcher args = null)
        {
            if (args == null)
            {
                args = new Args_Get_DomainSearcher();
            }

            var DFSSearcher = GetDomainSearcher.Get_DomainSearcher(args);

            if (DFSSearcher != null)
            {
                var DFSShares = new List <DFSShare>();
                ResultPropertyCollection Properties = null;
                DFSSearcher.Filter = @"(&(objectClass=msDFS-Linkv2))";
                DFSSearcher.PropertiesToLoad.AddRange(new string[] { @"msdfs-linkpathv2", @"msDFS-TargetListv2" });

                try
                {
                    var Results = DFSSearcher.FindAll();
                    if (Results != null)
                    {
                        foreach (SearchResult result in Results)
                        {
                            Properties = result.Properties;
                            var target_list = Properties[@"msdfs-targetlistv2"][0] as byte[];
                            var xml         = new XmlDocument();
                            xml.LoadXml(System.Text.Encoding.Unicode.GetString(target_list.Skip(2).Take(target_list.Length - 1 + 1 - 2).ToArray()));
                            if (xml.FirstChild != null)
                            {
                                foreach (XmlNode node in xml.FirstChild.ChildNodes)
                                {
                                    try
                                    {
                                        var Target = node.InnerText;
                                        if (Target.Contains(@"\"))
                                        {
                                            var DFSroot   = Target.Split('\\')[3];
                                            var ShareName = Properties[@"msdfs-linkpathv2"][0] as string;
                                            DFSShares.Add(new DFSShare {
                                                Name = $@"{DFSroot}{ShareName}", RemoteServerName = Target.Split('\\')[2]
                                            });
                                        }
                                    }
                                    catch (Exception e)
                                    {
                                        Logger.Write_Verbose($@"[Get-DomainDFSShare] Get-DomainDFSShareV2 error in parsing target : {e}");
                                    }
                                }
                            }
                        }
                        try { Results.Dispose(); }
                        catch (Exception e)
                        {
                            Logger.Write_Verbose($@"[Get-DomainDFSShare] Error disposing of the Results object: {e}");
                        }
                    }
                    DFSSearcher.Dispose();
                }
                catch (Exception e)
                {
                    Logger.Write_Warning($@"[Get-DomainDFSShare] Get-DomainDFSShareV2 error : {e}");
                }
                return(DFSShares);
            }
            return(null);
        }
Beispiel #6
0
        public static IEnumerable <ACL> Get_DomainObjectAcl(Args_Get_DomainObjectAcl args = null)
        {
            if (args == null)
            {
                args = new Args_Get_DomainObjectAcl();
            }

            var SearcherArguments = new Args_Get_DomainSearcher
            {
                Properties      = new[] { "samaccountname", "ntsecuritydescriptor", "distinguishedname", "objectsid" },
                SecurityMasks   = args.Sacl ? SecurityMasks.Sacl : SecurityMasks.Dacl,
                Domain          = args.Domain,
                SearchBase      = args.SearchBase,
                Server          = args.Server,
                SearchScope     = args.SearchScope,
                ResultPageSize  = args.ResultPageSize,
                ServerTimeLimit = args.ServerTimeLimit,
                Tombstone       = args.Tombstone,
                Credential      = args.Credential
            };
            var Searcher = GetDomainSearcher.Get_DomainSearcher(SearcherArguments);

            var DomainGUIDMapArguments = new Args_Get_DomainGUIDMap
            {
                Domain          = args.Domain,
                Server          = args.Server,
                ResultPageSize  = args.ResultPageSize,
                ServerTimeLimit = args.ServerTimeLimit,
                Credential      = args.Credential
            };

            // get a GUID -> name mapping
            IDictionary <string, string> GUIDs = null;

            if (args.ResolveGUIDs)
            {
                GUIDs = GetDomainGUIDMap.Get_DomainGUIDMap(DomainGUIDMapArguments);
            }

            var ACLs = new List <ACL>();

            if (Searcher != null)
            {
                var IdentityFilter = "";
                var Filter         = "";
                if (args.Identity != null)
                {
                    foreach (var item in args.Identity)
                    {
                        var IdentityInstance = item.Replace(@"(", @"\28").Replace(@")", @"\29");
                        if (IdentityInstance.IsRegexMatch(@"^S-1-.*"))
                        {
                            IdentityFilter += $@"(objectsid={IdentityInstance})";
                        }
                        else if (IdentityInstance.IsRegexMatch(@"^(CN|OU|DC)=.*"))
                        {
                            IdentityFilter += $@"(distinguishedname={IdentityInstance})";
                            if (args.Domain.IsNullOrEmpty() && args.SearchBase.IsNullOrEmpty())
                            {
                                // if a -Domain isn't explicitly set, extract the object domain out of the distinguishedname
                                // and rebuild the domain searcher
                                var IdentityDomain = IdentityInstance.Substring(IdentityInstance.IndexOf("DC=")).Replace("DC=", "").Replace(",", ".");
                                Logger.Write_Verbose($@"[Get-DomainObjectAcl] Extracted domain '{IdentityDomain}' from '{IdentityInstance}'");
                                SearcherArguments.Domain = IdentityDomain;
                                Searcher = GetDomainSearcher.Get_DomainSearcher(SearcherArguments);
                                if (Searcher == null)
                                {
                                    Logger.Write_Warning($@"[Get-DomainObjectAcl] Unable to retrieve domain searcher for '{IdentityDomain}'");
                                }
                            }
                        }
                        else if (IdentityInstance.IsRegexMatch(@"^[0-9A-F]{8}-([0-9A-F]{4}-){3}[0-9A-F]{12}$"))
                        {
                            var GuidByteString = string.Join(string.Empty, Guid.Parse(IdentityInstance).ToByteArray().Select(x => x.ToString(@"\X2")));
                            IdentityFilter += $@"(objectguid={GuidByteString})";
                        }
                        else if (IdentityInstance.Contains('.'))
                        {
                            IdentityFilter += $@"(|(samAccountName={IdentityInstance})(name={IdentityInstance})(dnshostname={IdentityInstance}))";
                        }
                        else
                        {
                            IdentityFilter += $@"(|(samAccountName={IdentityInstance})(name={IdentityInstance})(displayname={IdentityInstance}))";
                        }
                    }
                }
                if (IdentityFilter != null && IdentityFilter.Trim() != "")
                {
                    Filter += $@"(|{IdentityFilter})";
                }

                if (args.LDAPFilter.IsNotNullOrEmpty())
                {
                    Logger.Write_Verbose($@"[Get-DomainObjectAcl] Using additional LDAP filter: {args.LDAPFilter}");
                    Filter += $@"{args.LDAPFilter}";
                }

                if (Filter.IsNotNullOrEmpty())
                {
                    Searcher.Filter = $@"(&{Filter})";
                }
                Logger.Write_Verbose($@"[Get-DomainObjectAcl] Get-DomainObjectAcl filter string: {Searcher.Filter}");

                var Results = Searcher.FindAll();
                foreach (SearchResult result in Results)
                {
                    var Object = result.Properties;

                    string ObjectSid = null;
                    if (Object["objectsid"] != null && Object["objectsid"].Count > 0 && Object["objectsid"][0] != null)
                    {
                        ObjectSid = new System.Security.Principal.SecurityIdentifier(Object["objectsid"][0] as byte[], 0).Value;
                    }
                    else
                    {
                        ObjectSid = null;
                    }

                    try
                    {
                        var rsd    = new System.Security.AccessControl.RawSecurityDescriptor(Object["ntsecuritydescriptor"][0] as byte[], 0);
                        var rawAcl = args.Sacl ? rsd.SystemAcl : rsd.DiscretionaryAcl;
                        foreach (var ace in rawAcl)
                        {
                            var acl = new ACL {
                                Ace = ace
                            };
                            bool Continue = false;
                            if (args.RightsFilter != null)
                            {
                                string GuidFilter = null;
                                switch (args.RightsFilter.Value)
                                {
                                case Rights.ResetPassword:
                                    GuidFilter = "00299570-246d-11d0-a768-00aa006e0529";
                                    break;

                                case Rights.WriteMembers:
                                    GuidFilter = "bf9679c0-0de6-11d0-a285-00aa003049e2";
                                    break;

                                default:
                                    GuidFilter = "00000000-0000-0000-0000-000000000000";
                                    break;
                                }
                                if (ace is System.Security.AccessControl.ObjectAccessRule)
                                {
                                    if (string.Compare(((object)ace as System.Security.AccessControl.ObjectAccessRule).ObjectType.ToString(), GuidFilter, StringComparison.OrdinalIgnoreCase) == 0)
                                    {
                                        acl.ObjectDN  = Object["distinguishedname"][0] as string;
                                        acl.ObjectSID = ObjectSid;
                                        Continue      = true;
                                    }
                                }
                            }
                            else
                            {
                                acl.ObjectDN  = Object["distinguishedname"][0] as string;
                                acl.ObjectSID = ObjectSid;
                                Continue      = true;
                            }
                            if (Continue)
                            {
                                if (ace is System.Security.AccessControl.KnownAce)
                                {
                                    acl.ActiveDirectoryRights = (System.DirectoryServices.ActiveDirectoryRights)(ace as System.Security.AccessControl.KnownAce).AccessMask;
                                }
                                if (GUIDs != null)
                                {
                                    // if we're resolving GUIDs, map them them to the resolved hash table
                                    if (ace is ObjectAce)
                                    {
                                        try { (acl.Ace as ObjectAce).ObjectAceType = new Guid(GUIDs[(ace as ObjectAce).ObjectAceType.ToString()]); }
                                        catch { }
                                        try { (acl.Ace as ObjectAce).InheritedObjectAceType = new Guid(GUIDs[(ace as ObjectAce).InheritedObjectAceType.ToString()]); }
                                        catch { }
                                    }
                                    else if (ace is ObjectAccessRule)
                                    {
                                        /*try { (acl.Ace as ObjectAccessRule).ObjectType = new Guid(GUIDs[(ace as ObjectAccessRule).ObjectType.ToString()]); }
                                         * catch { }
                                         * try { (acl.Ace as ObjectAccessRule).InheritedObjectType = new Guid(GUIDs[(ace as ObjectAccessRule).InheritedObjectType.ToString()]); }
                                         * catch { }*/
                                    }
                                }

                                ACLs.Add(acl);
                            }
                        }
                    }
                    catch (Exception e)
                    {
                        Logger.Write_Verbose($@"[Get-DomainObjectAcl] Error: {e}");
                    }
                }
            }
            return(ACLs);
        }
Beispiel #7
0
        public static IEnumerable <object> Get_DomainGroup(Args_Get_DomainGroup args = null)
        {
            if (args == null)
            {
                args = new Args_Get_DomainGroup();
            }

            var SearcherArguments = new Args_Get_DomainSearcher
            {
                Domain          = args.Domain,
                Properties      = args.Properties,
                SearchBase      = args.SearchBase,
                Server          = args.Server,
                SearchScope     = args.SearchScope,
                ResultPageSize  = args.ResultPageSize,
                ServerTimeLimit = args.ServerTimeLimit,
                SecurityMasks   = args.SecurityMasks,
                Tombstone       = args.Tombstone,
                Credential      = args.Credential
            };

            var ObjectArguments = new Args_Get_DomainObject
            {
                Domain          = args.Domain,
                Properties      = args.Properties,
                SearchBase      = args.SearchBase,
                Server          = args.Server,
                SearchScope     = args.SearchScope,
                ResultPageSize  = args.ResultPageSize,
                ServerTimeLimit = args.ServerTimeLimit,
                SecurityMasks   = args.SecurityMasks,
                Tombstone       = args.Tombstone,
                Credential      = args.Credential
            };

            var GroupSearcher = GetDomainSearcher.Get_DomainSearcher(SearcherArguments);
            var Groups        = new List <object>();

            if (GroupSearcher != null)
            {
                if (args.MemberIdentity != null)
                {
                    string[] OldProperties = null;
                    if (args.Properties != null)
                    {
                        OldProperties = SearcherArguments.Properties;
                    }

                    ObjectArguments.Identity = args.MemberIdentity;
                    ObjectArguments.Raw      = true;

                    var Objects = GetDomainObject.Get_DomainObject(ObjectArguments);
                    if (Objects != null)
                    {
                    }
                    foreach (SearchResult obj in Objects)
                    {
                        // convert the user/group to a directory entry
                        var ObjectDirectoryEntry = obj.GetDirectoryEntry();

                        // cause the cache to calculate the token groups for the user/group
                        ObjectDirectoryEntry.RefreshCache(new string[] { @"tokenGroups" });
                        foreach (byte[] tokenGroup in ObjectDirectoryEntry.Properties[@"tokenGroups"])
                        {
                            // convert the token group sid
                            var GroupSid = new System.Security.Principal.SecurityIdentifier(tokenGroup, 0).Value;

                            // ignore the built in groups
                            if (new Regex(@"^S-1-5-32-.*").Match(GroupSid).Success == false)
                            {
                                ObjectArguments.Identity = new string[] { GroupSid };
                                ObjectArguments.Raw      = false;
                                if (OldProperties != null)
                                {
                                    ObjectArguments.Properties = OldProperties;
                                }
                                var Group = GetDomainObject.Get_DomainObject(ObjectArguments);
                                if (Group != null)
                                {
                                    Groups.AddRange(Group);
                                }
                            }
                        }
                    }
                }
                else
                {
                    var IdentityFilter = "";
                    var Filter         = "";
                    if (args.Identity != null)
                    {
                        foreach (var samName in args.Identity)
                        {
                            var IdentityInstance = samName.Replace(@"(", @"\28").Replace(@")", @"\29");
                            if (new Regex(@"^S-1-").Match(IdentityInstance).Success)
                            {
                                IdentityFilter += $@"(objectsid={IdentityInstance})";
                            }
                            else if (new Regex(@"^CN=").Match(IdentityInstance).Success)
                            {
                                IdentityFilter += $@"(distinguishedname={IdentityInstance})";
                                if (args.Domain.IsNullOrEmpty() && args.SearchBase.IsNullOrEmpty())
                                {
                                    // if a -Domain isn't explicitly set, extract the object domain out of the distinguishedname
                                    // and rebuild the domain searcher
                                    var IdentityDomain = IdentityInstance.Substring(IdentityInstance.IndexOf(@"DC=")).Replace(@"DC=", @"").Replace(@",", @".");
                                    Logger.Write_Verbose($@"[Get-DomainGroup] Extracted domain '{IdentityDomain}' from '{IdentityInstance}'");
                                    SearcherArguments.Domain = IdentityDomain;
                                    GroupSearcher            = GetDomainSearcher.Get_DomainSearcher(SearcherArguments);
                                    if (GroupSearcher == null)
                                    {
                                        Logger.Write_Warning($@"[Get-DomainGroup] Unable to retrieve domain searcher for '{IdentityDomain}'");
                                    }
                                }
                            }
                            else if (new Regex(@"^[0-9A-F]{8}-([0-9A-F]{4}-){3}[0-9A-F]{12}$").Match(IdentityInstance).Success)
                            {
                                var GuidByteString = string.Join(string.Empty, Guid.Parse(IdentityInstance).ToByteArray().Select(x => x.ToString(@"\X2")));
                                IdentityFilter += $@"(objectguid={GuidByteString})";
                            }
                            else if (IdentityInstance.Contains(@"\"))
                            {
                                var ConvertedIdentityInstance = ConvertADName.Convert_ADName(new Args_Convert_ADName
                                {
                                    OutputType = ADSNameType.Canonical,
                                    Identity   = new string[] { IdentityInstance.Replace(@"\28", @"(").Replace(@"\29", @")") }
                                });
                                if (ConvertedIdentityInstance != null && ConvertedIdentityInstance.Any())
                                {
                                    var GroupDomain = ConvertedIdentityInstance.First().Substring(0, ConvertedIdentityInstance.First().IndexOf('/'));
                                    var GroupName   = IdentityInstance.Split(new char[] { '\\' })[1];
                                    IdentityFilter          += $@"(samAccountName={GroupName})";
                                    SearcherArguments.Domain = GroupDomain;
                                    Logger.Write_Verbose($@"[Get-DomainUser] Extracted domain '{GroupDomain}' from '{IdentityInstance}'");
                                    GroupSearcher = GetDomainSearcher.Get_DomainSearcher(SearcherArguments);
                                }
                            }
                            else
                            {
                                IdentityFilter += $@"(|(samAccountName={IdentityInstance})(name={IdentityInstance}))";
                            }
                        }
                    }

                    if (IdentityFilter != null && IdentityFilter.Trim() != "")
                    {
                        Filter += $@"(|{IdentityFilter})";
                    }

                    if (args.AdminCount)
                    {
                        Logger.Write_Verbose(@"[Get-DomainGroup] Searching for adminCount=1");
                        Filter += "(admincount=1)";
                    }
                    if (args.GroupScope != null)
                    {
                        switch (args.GroupScope.Value)
                        {
                        case GroupScope.DomainLocal:
                            Filter = "(groupType:1.2.840.113556.1.4.803:=4)";
                            break;

                        case GroupScope.NotDomainLocal:
                            Filter = "(!(groupType:1.2.840.113556.1.4.803:=4))";
                            break;

                        case GroupScope.Global:
                            Filter = "(groupType:1.2.840.113556.1.4.803:=2)";
                            break;

                        case GroupScope.NotGlobal:
                            Filter = "(!(groupType:1.2.840.113556.1.4.803:=2))";
                            break;

                        case GroupScope.Universal:
                            Filter = "(groupType:1.2.840.113556.1.4.803:=8)";
                            break;

                        case GroupScope.NotUniversal:
                            Filter = "(!(groupType:1.2.840.113556.1.4.803:=8))";
                            break;

                        default:
                            break;
                        }
                        Logger.Write_Verbose($@"[Get-DomainGroup] Searching for group scope '{args.GroupScope.Value.ToString()}'");
                    }
                    if (args.GroupProperty != null)
                    {
                        switch (args.GroupProperty.Value)
                        {
                        case GroupProperty.Security:
                            Filter = "(groupType:1.2.840.113556.1.4.803:=2147483648)";
                            break;

                        case GroupProperty.Distribution:
                            Filter = "(!(groupType:1.2.840.113556.1.4.803:=2147483648))";
                            break;

                        case GroupProperty.CreatedBySystem:
                            Filter = "(groupType:1.2.840.113556.1.4.803:=1)";
                            break;

                        case GroupProperty.NotCreatedBySystem:
                            Filter = "(!(groupType:1.2.840.113556.1.4.803:=1))";
                            break;

                        default:
                            break;
                        }
                        Logger.Write_Verbose($@"[Get-DomainGroup] Searching for group property '{args.GroupProperty.Value.ToString()}'");
                    }
                    if (args.LDAPFilter.IsNotNullOrEmpty())
                    {
                        Logger.Write_Verbose($@"[Get-DomainGroup] Using additional LDAP filter: {args.LDAPFilter}");
                        Filter += $@"{args.LDAPFilter}";
                    }

                    GroupSearcher.Filter = $@"(&(objectCategory=group){Filter})";
                    Logger.Write_Verbose($@"[Get-DomainGroup] filter string: {GroupSearcher.Filter}");

                    if (args.FindOne)
                    {
                        var result = GroupSearcher.FindOne();
                        if (args.Raw)
                        {
                            // return raw result objects
                            Groups.Add(result);
                        }
                        else
                        {
                            Groups.Add(ConvertLDAPProperty.Convert_LDAPProperty(result.Properties));
                        }
                    }
                    else
                    {
                        var Results = GroupSearcher.FindAll();
                        foreach (SearchResult result in Results)
                        {
                            if (args.Raw)
                            {
                                // return raw result objects
                                Groups.Add(result);
                            }
                            else
                            {
                                Groups.Add(ConvertLDAPProperty.Convert_LDAPProperty(result.Properties));
                            }
                        }
                        if (Results != null)
                        {
                            try { Results.Dispose(); }
                            catch (Exception e)
                            {
                                Logger.Write_Verbose($@"[Get-DomainGroup] Error disposing of the Results object: {e}");
                            }
                        }
                    }
                    GroupSearcher.Dispose();
                }
            }
            return(Groups);
        }
Beispiel #8
0
        private static IEnumerable <DFSShare> Get_DomainDFSShareV1(Args_Get_DomainSearcher args = null)
        {
            if (args == null)
            {
                args = new Args_Get_DomainSearcher();
            }

            var DFSSearcher = GetDomainSearcher.Get_DomainSearcher(args);

            if (DFSSearcher != null)
            {
                var DFSShares = new List <DFSShare>();
                ResultPropertyCollection Properties = null;
                DFSSearcher.Filter = @"(&(objectClass=fTDfs))";

                try
                {
                    ResultPropertyValueCollection Pkt = null;
                    var Results = DFSSearcher.FindAll();
                    if (Results != null)
                    {
                        foreach (SearchResult result in Results)
                        {
                            Properties = result.Properties;
                            var RemoteNames = Properties[@"remoteservername"];
                            Pkt = Properties[@"pkt"];

                            if (RemoteNames != null)
                            {
                                foreach (string name in RemoteNames)
                                {
                                    try
                                    {
                                        if (name.Contains(@"\"))
                                        {
                                            DFSShares.Add(new DFSShare
                                            {
                                                Name             = Properties[@"name"][0] as string,
                                                RemoteServerName = name.Split(new char[] { '\\' })[2]
                                            });
                                        }
                                    }
                                    catch (Exception e)
                                    {
                                        Logger.Write_Verbose($@"[Get-DomainDFSShare] Get-DomainDFSShareV1 error in parsing DFS share : {e}");
                                    }
                                }
                            }
                            try { Results.Dispose(); }
                            catch (Exception e)
                            {
                                Logger.Write_Verbose($@"[Get-DomainDFSShare] Get-DomainDFSShareV1 error disposing of the Results object: {e}");
                            }
                        }

                        DFSSearcher.Dispose();

                        if (Pkt != null && Pkt[0] != null)
                        {
                            var servers = Parse_Pkt(Pkt[0] as byte[]);
                            if (servers != null)
                            {
                                foreach (var server in servers)
                                {
                                    // If a folder doesn't have a redirection it will have a target like
                                    // \\null\TestNameSpace\folder\.DFSFolderLink so we do actually want to match
                                    // on 'null' rather than $Null
                                    if (server != null && server != @"null" &&
                                        DFSShares.Any(x => x.RemoteServerName == server))
                                    {
                                        DFSShares.Add(new DFSShare {
                                            Name = Properties[@"name"][0] as string, RemoteServerName = server
                                        });
                                    }
                                }
                            }
                        }
                    }
                }
                catch (Exception e)
                {
                    Logger.Write_Warning($@"[Get-DomainDFSShare] Get-DomainDFSShareV1 error : {e}");
                }
                return(DFSShares);
            }
            return(null);
        }
Beispiel #9
0
        public static IEnumerable <DNSZone> Get_DomainDNSZone(Args_Get_DomainDNSZone args = null)
        {
            if (args == null)
            {
                args = new Args_Get_DomainDNSZone();
            }

            var SearcherArguments = new Args_Get_DomainSearcher
            {
                LDAPFilter      = @"(objectClass=dnsZone)",
                Domain          = args.Domain,
                Server          = args.Server,
                Properties      = args.Properties,
                ResultPageSize  = args.ResultPageSize,
                ServerTimeLimit = args.ServerTimeLimit,
                Credential      = args.Credential
            };
            var DNSSearcher1 = GetDomainSearcher.Get_DomainSearcher(SearcherArguments);

            SearchResult[] Results = null;
            List <DNSZone> Outs    = null;

            if (DNSSearcher1 != null)
            {
                if (args.FindOne)
                {
                    Results = new SearchResult[] { DNSSearcher1.FindOne() };
                }
                else
                {
                    var items = DNSSearcher1.FindAll();
                    if (items != null)
                    {
                        Results = new SearchResult[items.Count];
                        items.CopyTo(Results, 0);
                    }
                }
                if (Results != null)
                {
                    foreach (var result in Results)
                    {
                        var Out = new DNSZone(ConvertLDAPProperty.Convert_LDAPProperty(result.Properties));
                        Outs.Add(Out);
                    }
                }
                DNSSearcher1.Dispose();
            }

            SearcherArguments.SearchBasePrefix = @"CN=MicrosoftDNS,DC=DomainDnsZones";
            var DNSSearcher2 = GetDomainSearcher.Get_DomainSearcher(SearcherArguments);

            if (DNSSearcher2 != null)
            {
                try
                {
                    if (args.FindOne)
                    {
                        Results = new SearchResult[] { DNSSearcher2.FindOne() };
                    }
                    else
                    {
                        var items = DNSSearcher2.FindAll();
                        if (items != null)
                        {
                            Results = new SearchResult[items.Count];
                            items.CopyTo(Results, 0);
                        }
                    }
                    if (Results != null)
                    {
                        foreach (var result in Results)
                        {
                            var Out = new DNSZone(ConvertLDAPProperty.Convert_LDAPProperty(result.Properties));
                            Outs.Add(Out);
                        }
                    }
                }
                catch
                {
                    Logger.Write_Verbose(@"[Get-DomainDNSZone] Error accessing 'CN=MicrosoftDNS,DC=DomainDnsZones'");
                }
                DNSSearcher2.Dispose();
            }
            return(Outs);
        }
Beispiel #10
0
        public static IEnumerable <object> Get_DomainGPO(Args_Get_DomainGPO args = null)
        {
            if (args == null)
            {
                args = new Args_Get_DomainGPO();
            }

            var SearcherArguments = new Args_Get_DomainSearcher
            {
                Domain          = args.Domain,
                Properties      = args.Properties,
                SearchBase      = args.SearchBase,
                Server          = args.Server,
                SearchScope     = args.SearchScope,
                ResultPageSize  = args.ResultPageSize,
                ServerTimeLimit = args.ServerTimeLimit,
                SecurityMasks   = args.SecurityMasks,
                Tombstone       = args.Tombstone,
                Credential      = args.Credential
            };
            var GPOSearcher = GetDomainSearcher.Get_DomainSearcher(SearcherArguments);

            var GPOs = new List <object>();

            if (GPOSearcher != null)
            {
                if (args.ComputerIdentity != null || args.UserIdentity != null)
                {
                    var      GPOAdsPaths   = new List <string>();
                    string[] OldProperties = null;
                    if (SearcherArguments.Properties != null)
                    {
                        OldProperties = SearcherArguments.Properties;
                    }
                    SearcherArguments.Properties = new[] { @"distinguishedname", @"dnshostname" };
                    string TargetComputerName = null;
                    string ObjectDN           = null;

                    if (args.ComputerIdentity.IsNotNullOrEmpty())
                    {
                        var Computer = GetDomainComputer.Get_DomainComputer(new Args_Get_DomainComputer(SearcherArguments)
                        {
                            Identity = new[] { args.ComputerIdentity },
                            FindOne  = true
                        }).First() as LDAPProperty;
                        if (Computer == null)
                        {
                            Logger.Write_Verbose($@"[Get-DomainGPO] Computer '{args.ComputerIdentity}' not found!");
                        }
                        ObjectDN           = Computer.distinguishedname;
                        TargetComputerName = Computer.dnshostname;
                    }
                    else
                    {
                        var User = GetDomainUser.Get_DomainUser(new Args_Get_DomainUser(SearcherArguments)
                        {
                            Identity = new[] { args.UserIdentity },
                            FindOne  = true
                        }) as LDAPProperty;
                        if (User == null)
                        {
                            Logger.Write_Verbose($@"[Get-DomainGPO] User '{args.UserIdentity}' not found!");
                        }
                        ObjectDN = User.distinguishedname;
                    }

                    // extract all OUs the target user/computer is a part of
                    var ObjectOUs = new List <string>();
                    foreach (var item in ObjectDN.Split(','))
                    {
                        if (item.StartsWith(@"OU="))
                        {
                            ObjectOUs.Add(ObjectDN.Substring(ObjectDN.IndexOf($@"{item},")));
                        }
                    }
                    Logger.Write_Verbose($@"[Get-DomainGPO] object OUs: {ObjectOUs}");

                    if (ObjectOUs != null)
                    {
                        // find all the GPOs linked to the user/computer's OUs
                        SearcherArguments.Properties = null;
                        var InheritanceDisabled = false;
                        foreach (var ObjectOU in ObjectOUs)
                        {
                            var ous = GetDomainOU.Get_DomainOU(new Args_Get_DomainOU(SearcherArguments)
                            {
                                Identity = new[] { ObjectOU }
                            });
                            foreach (LDAPProperty ou in ous)
                            {
                                // extract any GPO links for this particular OU the computer is a part of
                                if (ou.gplink.IsNotNullOrEmpty())
                                {
                                    foreach (var item in ou.gplink.Split(new[] { @"][" }, StringSplitOptions.None))
                                    {
                                        if (item.StartsWith(@"LDAP"))
                                        {
                                            var Parts    = item.Split(';');
                                            var GpoDN    = Parts[0];
                                            var Enforced = Parts[1];

                                            if (InheritanceDisabled)
                                            {
                                                // if inheritance has already been disabled and this GPO is set as "enforced"
                                                // then add it, otherwise ignore it
                                                if (Enforced == @"2")
                                                {
                                                    GPOAdsPaths.Add(GpoDN);
                                                }
                                            }
                                            else
                                            {
                                                // inheritance not marked as disabled yet
                                                GPOAdsPaths.Add(GpoDN);
                                            }
                                        }
                                    }
                                }

                                //if this OU has GPO inheritence disabled, break so additional OUs aren't processed
                                if (ou.gpoptions == 1)
                                {
                                    InheritanceDisabled = true;
                                }
                            }
                        }
                    }

                    if (TargetComputerName.IsNotNullOrEmpty())
                    {
                        // find all the GPOs linked to the computer's site
                        var ComputerSite = GetNetComputerSiteName.Get_NetComputerSiteName(new Args_Get_NetComputerSiteName {
                            ComputerName = new[] { TargetComputerName }
                        }).First().SiteName;
                        if (ComputerSite.IsNotNullOrEmpty() && !ComputerSite.IsLikeMatch(@"Error*"))
                        {
                            var sites = GetDomainSite.Get_DomainSite(new Args_Get_DomainSite(SearcherArguments)
                            {
                                Identity = new[] { ComputerSite }
                            });
                            foreach (LDAPProperty site in sites)
                            {
                                if (site.gplink.IsNotNullOrEmpty())
                                {
                                    // extract any GPO links for this particular site the computer is a part of
                                    foreach (var item in site.gplink.Split(new[] { @"][" }, StringSplitOptions.None))
                                    {
                                        if (item.StartsWith(@"LDAP"))
                                        {
                                            GPOAdsPaths.Add(item.Split(';')[0]);
                                        }
                                    }
                                }
                            }
                        }
                    }

                    // find any GPOs linked to the user/computer's domain
                    var ObjectDomainDN = ObjectDN.Substring(ObjectDN.IndexOf(@"DC="));
                    SearcherArguments.Properties = null;
                    SearcherArguments.LDAPFilter = $@"(objectclass=domain)(distinguishedname={ObjectDomainDN})";
                    var objs = GetDomainObject.Get_DomainObject(new Args_Get_DomainObject(SearcherArguments));
                    foreach (LDAPProperty obj in objs)
                    {
                        if (obj.gplink.IsNotNullOrEmpty())
                        {
                            // extract any GPO links for this particular domain the computer is a part of
                            foreach (var item in obj.gplink.Split(new[] { @"][" }, StringSplitOptions.None))
                            {
                                if (item.StartsWith(@"LDAP"))
                                {
                                    GPOAdsPaths.Add(item.Split(';')[0]);
                                }
                            }
                        }
                    }
                    Logger.Write_Verbose($@"[Get-DomainGPO] GPOAdsPaths: {GPOAdsPaths}");

                    // restore the old properites to return, if set
                    if (OldProperties != null)
                    {
                        SearcherArguments.Properties = OldProperties;
                    }
                    else
                    {
                        SearcherArguments.Properties = null;
                    }

                    foreach (var path in GPOAdsPaths.Where(x => x != null && x != ""))
                    {
                        // use the gplink as an ADS path to enumerate all GPOs for the computer
                        SearcherArguments.SearchBase = path;
                        SearcherArguments.LDAPFilter = @"(objectCategory=groupPolicyContainer)";
                        objs = GetDomainObject.Get_DomainObject(new Args_Get_DomainObject(SearcherArguments));
                        foreach (LDAPProperty obj in objs)
                        {
                            GPOs.Add(new GPO(obj));
                        }
                    }
                }
                else
                {
                    var IdentityFilter = @"";
                    var Filter         = @"";
                    if (args.Identity != null)
                    {
                        foreach (var item in args.Identity)
                        {
                            var IdentityInstance = item.Replace(@"(", @"\28").Replace(@")", @"\29");
                            if (IdentityInstance.IsRegexMatch(@"LDAP://|^CN=.*"))
                            {
                                IdentityFilter += $@"(distinguishedname={IdentityInstance})";
                                if (args.Domain.IsNullOrEmpty() && args.SearchBase.IsNullOrEmpty())
                                {
                                    // if a -Domain isn't explicitly set, extract the object domain out of the distinguishedname
                                    // and rebuild the domain searcher
                                    var IdentityDomain = IdentityInstance.Substring(IdentityInstance.IndexOf(@"DC=")).Replace(@"DC=", @"").Replace(@",", @".");
                                    Logger.Write_Verbose($@"[Get-DomainGPO] Extracted domain '{IdentityDomain}' from '{IdentityInstance}'");
                                    SearcherArguments.Domain = IdentityDomain;
                                    GPOSearcher = GetDomainSearcher.Get_DomainSearcher(SearcherArguments);
                                    if (GPOSearcher == null)
                                    {
                                        Logger.Write_Warning($@"[Get-DomainGPO] Unable to retrieve domain searcher for '{IdentityDomain}'");
                                    }
                                }
                            }
                            else if (IdentityInstance.IsRegexMatch(@"{.*}"))
                            {
                                IdentityFilter += $@"(name={IdentityInstance})";
                            }
                            else
                            {
                                try
                                {
                                    var GuidByteString = string.Join(string.Empty, Guid.Parse(IdentityInstance).ToByteArray().Select(x => x.ToString(@"\X2")));
                                    IdentityFilter += $@"(objectguid={GuidByteString})";
                                }
                                catch
                                {
                                    IdentityFilter += $@"(displayname={IdentityInstance})";
                                }
                            }
                        }
                    }

                    if (IdentityFilter != null && IdentityFilter.Trim() != @"")
                    {
                        Filter += $@"(|{IdentityFilter})";
                    }

                    if (args.LDAPFilter.IsNotNullOrEmpty())
                    {
                        Logger.Write_Verbose($@"[Get-DomainGPO] Using additional LDAP filter: {args.LDAPFilter}");
                        Filter += $@"{args.LDAPFilter}";
                    }

                    GPOSearcher.Filter = $@"(&(objectCategory=groupPolicyContainer){Filter})";
                    Logger.Write_Verbose($@"[Get-DomainGPO] filter string: {GPOSearcher.Filter}");

                    SearchResult[] Results = null;
                    if (args.FindOne)
                    {
                        Results = new SearchResult[] { GPOSearcher.FindOne() };
                    }
                    else
                    {
                        var items = GPOSearcher.FindAll();
                        if (items != null)
                        {
                            Results = new SearchResult[items.Count];
                            items.CopyTo(Results, 0);
                        }
                    }
                    if (Results != null)
                    {
                        foreach (var result in Results)
                        {
                            if (args.Raw)
                            {
                                // return raw result objects
                                GPOs.Add(result);
                            }
                            else
                            {
                                GPO GPO;
                                if (args.SearchBase.IsNotNullOrEmpty() && args.SearchBase.IsRegexMatch(@"^GC://"))
                                {
                                    GPO = new GPO(ConvertLDAPProperty.Convert_LDAPProperty(result.Properties));
                                    try
                                    {
                                        var GPODN          = GPO.distinguishedname;
                                        var GPODomain      = GPODN.Substring(GPODN.IndexOf(@"DC=")).Replace(@"DC=", @"").Replace(@",", @".");
                                        var gpcfilesyspath = $@"\\{GPODomain}\SysVol\{GPODomain}\Policies\{GPO.cn}";
                                        GPO.gpcfilesyspath = gpcfilesyspath;
                                    }
                                    catch
                                    {
                                        Logger.Write_Verbose($@"[Get-DomainGPO] Error calculating gpcfilesyspath for: {GPO.distinguishedname}");
                                    }
                                }
                                else
                                {
                                    GPO = new GPO(ConvertLDAPProperty.Convert_LDAPProperty(result.Properties));
                                }
                                GPOs.Add(GPO);
                            }
                        }
                    }
                }
                GPOSearcher.Dispose();
            }
            return(GPOs);
        }
Beispiel #11
0
        public static IEnumerable <object> Get_DomainSite(Args_Get_DomainSite args = null)
        {
            if (args == null)
            {
                args = new Args_Get_DomainSite();
            }

            var SearcherArguments = new Args_Get_DomainSearcher
            {
                SearchBasePrefix = @"CN=Sites,CN=Configuration",
                Domain           = args.Domain,
                Properties       = args.Properties,
                SearchBase       = args.SearchBase,
                Server           = args.Server,
                SearchScope      = args.SearchScope,
                ResultPageSize   = args.ResultPageSize,
                ServerTimeLimit  = args.ServerTimeLimit,
                SecurityMasks    = args.SecurityMasks,
                Tombstone        = args.Tombstone,
                Credential       = args.Credential
            };
            var SiteSearcher = GetDomainSearcher.Get_DomainSearcher(SearcherArguments);
            var Sites        = new List <object>();

            if (SiteSearcher != null)
            {
                var IdentityFilter = @"";
                var Filter         = @"";
                if (args.Identity != null)
                {
                    foreach (var item in args.Identity)
                    {
                        var IdentityInstance = item.Replace(@"(", @"\28").Replace(@")", @"\29");
                        if (IdentityInstance.IsRegexMatch(@"^CN=.*"))
                        {
                            IdentityFilter += $@"(distinguishedname={IdentityInstance})";
                            if (args.Domain.IsNullOrEmpty() && args.SearchBase.IsNullOrEmpty())
                            {
                                // if a -Domain isn't explicitly set, extract the object domain out of the distinguishedname
                                //   and rebuild the domain searcher
                                var IdentityDomain = IdentityInstance.Substring(IdentityInstance.IndexOf(@"DC=")).Replace(@"DC=", @"").Replace(@",", @".");
                                Logger.Write_Verbose($@"[Get-DomainSite] Extracted domain '{IdentityDomain}' from '{IdentityInstance}'");
                                SearcherArguments.Domain = IdentityDomain;
                                SiteSearcher             = GetDomainSearcher.Get_DomainSearcher(SearcherArguments);
                                if (SiteSearcher == null)
                                {
                                    Logger.Write_Warning($@"[Get-DomainSite] Unable to retrieve domain searcher for '{IdentityDomain}'");
                                }
                            }
                        }
                        else
                        {
                            try
                            {
                                var GuidByteString = string.Join(string.Empty, Guid.Parse(IdentityInstance).ToByteArray().Select(x => x.ToString(@"\X2")));
                                IdentityFilter += $@"(objectguid={GuidByteString})";
                            }
                            catch
                            {
                                IdentityFilter += $@"(name={IdentityInstance})";
                            }
                        }
                    }
                }
                if (IdentityFilter != null && IdentityFilter.Trim() != @"")
                {
                    Filter += $@"(|{IdentityFilter})";
                }

                if (args.GPLink.IsNotNullOrEmpty())
                {
                    Logger.Write_Verbose($@"[Get-DomainSite] Searching for sites with {args.GPLink} set in the gpLink property");
                    Filter += $@"(gplink=*{args.GPLink}*)";
                }

                if (args.LDAPFilter.IsNotNullOrEmpty())
                {
                    Logger.Write_Verbose($@"[Get-DomainSite] Using additional LDAP filter: {args.LDAPFilter}");
                    Filter += $@"{args.LDAPFilter}";
                }

                SiteSearcher.Filter = $@"(&(objectCategory=site){Filter})";
                Logger.Write_Verbose($@"[Get-DomainSite] Get-DomainSite filter string: {SiteSearcher.Filter}");

                SearchResult[] Results = null;
                if (args.FindOne)
                {
                    Results = new SearchResult[] { SiteSearcher.FindOne() };
                }
                else
                {
                    var items = SiteSearcher.FindAll();
                    if (items != null)
                    {
                        Results = new SearchResult[items.Count];
                        items.CopyTo(Results, 0);
                    }
                }
                if (Results != null)
                {
                    foreach (var result in Results)
                    {
                        if (args.Raw)
                        {
                            // return raw result objects
                            Sites.Add(result);
                        }
                        else
                        {
                            var Site = ConvertLDAPProperty.Convert_LDAPProperty(result.Properties);
                            Sites.Add(Site);
                        }
                    }
                }
                SiteSearcher.Dispose();
            }
            return(Sites);
        }
Beispiel #12
0
        public static IEnumerable <object> Get_DomainComputer(Args_Get_DomainComputer args = null)
        {
            if (args == null)
            {
                args = new Args_Get_DomainComputer();
            }

            var SearcherArguments = new Args_Get_DomainSearcher
            {
                Domain          = args.Domain,
                Properties      = args.Properties,
                SearchBase      = args.SearchBase,
                Server          = args.Server,
                SearchScope     = args.SearchScope,
                ResultPageSize  = args.ResultPageSize,
                ServerTimeLimit = args.ServerTimeLimit,
                SecurityMasks   = args.SecurityMasks,
                Tombstone       = args.Tombstone,
                Credential      = args.Credential
            };

            var CompSearcher = GetDomainSearcher.Get_DomainSearcher(SearcherArguments);
            var Computers    = new List <object>();

            if (CompSearcher != null)
            {
                var IdentityFilter = @"";
                var Filter         = @"";
                if (args.Identity != null)
                {
                    foreach (var samName in args.Identity)
                    {
                        var IdentityInstance = samName.Replace(@"(", @"\28").Replace(@")", @"\29");
                        if (new Regex(@"^S-1-").Match(IdentityInstance).Success)
                        {
                            IdentityFilter += $@"(objectsid={IdentityInstance})";
                        }
                        else if (new Regex(@"^CN=").Match(IdentityInstance).Success)
                        {
                            IdentityFilter += $@"(distinguishedname={IdentityInstance})";
                            if (args.Domain.IsNullOrEmpty() && args.SearchBase.IsNullOrEmpty())
                            {
                                // if a -Domain isn't explicitly set, extract the object domain out of the distinguishedname
                                // and rebuild the domain searcher
                                var IdentityDomain = IdentityInstance.Substring(IdentityInstance.IndexOf(@"DC=")).Replace(@"DC=", @"").Replace(@",", @".");
                                Logger.Write_Verbose($@"[Get-DomainComputer] Extracted domain '{IdentityDomain}' from '{IdentityInstance}'");
                                SearcherArguments.Domain = IdentityDomain;
                                CompSearcher             = GetDomainSearcher.Get_DomainSearcher(SearcherArguments);
                                if (CompSearcher == null)
                                {
                                    Logger.Write_Warning($@"[Get-DomainComputer] Unable to retrieve domain searcher for '{IdentityDomain}'");
                                }
                            }
                        }
                        else if (IdentityInstance.Contains(@"."))
                        {
                            IdentityFilter += $@"(|(name={IdentityInstance})(dnshostname={IdentityInstance}))";
                        }
                        else if (new Regex(@"^[0-9A-F]{8}-([0-9A-F]{4}-){3}[0-9A-F]{12}$").Match(IdentityInstance).Success)
                        {
                            var GuidByteString = string.Join(string.Empty, Guid.Parse(IdentityInstance).ToByteArray().Select(x => x.ToString(@"\X2")));
                            IdentityFilter += $@"(objectguid={GuidByteString})";
                        }
                        else
                        {
                            IdentityFilter += $@"(name={IdentityInstance})";
                        }
                    }
                }
                if (IdentityFilter != null && IdentityFilter.Trim() != "")
                {
                    Filter += $@"(|{IdentityFilter})";
                }

                if (args.Unconstrained)
                {
                    Logger.Write_Verbose(@"[Get-DomainComputer] Searching for computers with for unconstrained delegation");
                    Filter += @"(userAccountControl:1.2.840.113556.1.4.803:=524288)";
                }
                if (args.TrustedToAuth)
                {
                    Logger.Write_Verbose(@"[Get-DomainComputer] Searching for computers that are trusted to authenticate for other principals");
                    Filter += @"(msds-allowedtodelegateto=*)";
                }
                if (args.Printers)
                {
                    Logger.Write_Verbose("[Get-DomainComputer] Searching for printers");
                    Filter += @"(objectCategory=printQueue)";
                }
                if (args.SPN.IsNotNullOrEmpty())
                {
                    Logger.Write_Verbose($@"[Get-DomainComputer] Searching for computers with SPN: {args.SPN}");
                    Filter += $@"(servicePrincipalName={args.SPN})";
                }
                if (args.OperatingSystem.IsNotNullOrEmpty())
                {
                    Logger.Write_Verbose($@"[Get-DomainComputer] Searching for computers with operating system: {args.OperatingSystem}");
                    Filter += $@"(operatingsystem={args.OperatingSystem})";
                }
                if (args.ServicePack.IsNotNullOrEmpty())
                {
                    Logger.Write_Verbose($@"[Get-DomainComputer] Searching for computers with service pack: {args.ServicePack}");
                    Filter += $@"(operatingsystemservicepack={args.ServicePack})";
                }
                if (args.SiteName.IsNotNullOrEmpty())
                {
                    Logger.Write_Verbose($@"[Get-DomainComputer] Searching for computers with site name: {args.SiteName}");
                    Filter += $@"(serverreferencebl={args.SiteName})";
                }
                if (args.LDAPFilter.IsNotNullOrEmpty())
                {
                    Logger.Write_Verbose($@"[Get-DomainComputer] Using additional LDAP filter: {args.LDAPFilter}");
                    Filter += $@"{args.LDAPFilter}";
                }
                // build the LDAP filter for the dynamic UAC filter value
                var uacs = args.UACFilter.ExtractValues();
                foreach (var uac in uacs)
                {
                    if (uac.IsNot())
                    {
                        Filter += $@"(!(userAccountControl:1.2.840.113556.1.4.803:={uac.GetValueAsInteger()}))";
                    }
                    else
                    {
                        Filter += $@"(userAccountControl:1.2.840.113556.1.4.803:={uac.GetValueAsInteger()})";
                    }
                }

                CompSearcher.Filter = $@"(&(samAccountType=805306369){Filter})";
                Logger.Write_Verbose($@"[Get-DomainComputer] Get-DomainComputer filter string: {CompSearcher.Filter}");

                if (args.FindOne)
                {
                    var result = CompSearcher.FindOne();
                    var Up     = true;
                    if (args.Ping)
                    {
                        Up = TestConnection.Ping(result.Properties["dnshostname"][0] as string, 1);
                    }
                    if (Up)
                    {
                        if (args.Raw)
                        {
                            // return raw result objects
                            Computers.Add(result);
                        }
                        else
                        {
                            Computers.Add(ConvertLDAPProperty.Convert_LDAPProperty(result.Properties));
                        }
                    }
                }
                else
                {
                    var Results = CompSearcher.FindAll();
                    foreach (SearchResult result in Results)
                    {
                        var Up = true;
                        if (args.Ping)
                        {
                            Up = TestConnection.Ping(result.Properties["dnshostname"][0] as string, 1);
                        }
                        if (Up)
                        {
                            if (args.Raw)
                            {
                                // return raw result objects
                                Computers.Add(result);
                            }
                            else
                            {
                                Computers.Add(ConvertLDAPProperty.Convert_LDAPProperty(result.Properties));
                            }
                        }
                    }
                    if (Results != null)
                    {
                        try { Results.Dispose(); }
                        catch (Exception e)
                        {
                            Logger.Write_Verbose($@"[Get-DomainComputer] Error disposing of the Results object: {e}");
                        }
                    }
                }
                CompSearcher.Dispose();
            }
            return(Computers);
        }
Beispiel #13
0
        public static string[] Get_DomainFileServer(Args_Get_DomainFileServer args = null)
        {
            if (args == null)
            {
                args = new Args_Get_DomainFileServer();
            }

            var SearcherArguments = new Args_Get_DomainSearcher
            {
                LDAPFilter      = "(&(samAccountType=805306368)(!(userAccountControl:1.2.840.113556.1.4.803:=2))(|(homedirectory=*)(scriptpath=*)(profilepath=*)))",
                Properties      = new string[] { "homedirectory", "scriptpath", "profilepath" },
                SearchBase      = args.SearchBase,
                Server          = args.Server,
                SearchScope     = args.SearchScope,
                ResultPageSize  = args.ResultPageSize,
                ServerTimeLimit = args.ServerTimeLimit,
                Tombstone       = args.Tombstone,
                Credential      = args.Credential
            };

            var retValues = new List <string>();

            if (args.Domain != null)
            {
                foreach (var TargetDomain in args.Domain)
                {
                    SearcherArguments.Domain = TargetDomain;
                    var UserSearcher = GetDomainSearcher.Get_DomainSearcher(SearcherArguments);
                    // get all results w/o the pipeline and uniquify them (I know it's not pretty)
                    foreach (SearchResult UserResult in UserSearcher.FindAll())
                    {
                        if (UserResult.Properties["homedirectory"] != null)
                        {
                            var val = Split_Path(UserResult.Properties["homedirectory"][0] as string);
                            if (!retValues.Any(x => x == val))
                            {
                                retValues.Add(val);
                            }
                        }
                        if (UserResult.Properties["scriptpath"] != null)
                        {
                            var val = Split_Path(UserResult.Properties["scriptpath"][0] as string);
                            if (!retValues.Any(x => x == val))
                            {
                                retValues.Add(val);
                            }
                        }
                        if (UserResult.Properties["profilepath"] != null)
                        {
                            var val = Split_Path(UserResult.Properties["profilepath"][0] as string);
                            if (!retValues.Any(x => x == val))
                            {
                                retValues.Add(val);
                            }
                        }
                    }
                }
            }
            else
            {
                var UserSearcher = GetDomainSearcher.Get_DomainSearcher(SearcherArguments);
                // get all results w/o the pipeline and uniquify them (I know it's not pretty)
                foreach (SearchResult UserResult in UserSearcher.FindAll())
                {
                    if (UserResult.Properties["homedirectory"] != null)
                    {
                        var val = Split_Path(UserResult.Properties["homedirectory"][0] as string);
                        if (!retValues.Any(x => x == val))
                        {
                            retValues.Add(val);
                        }
                    }
                    if (UserResult.Properties["scriptpath"] != null)
                    {
                        var val = Split_Path(UserResult.Properties["scriptpath"][0] as string);
                        if (!retValues.Any(x => x == val))
                        {
                            retValues.Add(val);
                        }
                    }
                    if (UserResult.Properties["profilepath"] != null)
                    {
                        var val = Split_Path(UserResult.Properties["profilepath"][0] as string);
                        if (!retValues.Any(x => x == val))
                        {
                            retValues.Add(val);
                        }
                    }
                }
            }
            return(retValues.ToArray());
        }
Beispiel #14
0
        public static IEnumerable <object> Get_DomainUser(Args_Get_DomainUser args = null)
        {
            if (args == null)
            {
                args = new Args_Get_DomainUser();
            }

            var SearcherArguments = new Args_Get_DomainSearcher
            {
                Domain          = args.Domain,
                Properties      = args.Properties,
                SearchBase      = args.SearchBase,
                Server          = args.Server,
                SearchScope     = args.SearchScope,
                ResultPageSize  = args.ResultPageSize,
                ServerTimeLimit = args.ServerTimeLimit,
                SecurityMasks   = args.SecurityMasks,
                Tombstone       = args.Tombstone,
                Credential      = args.Credential
            };

            var UserSearcher = GetDomainSearcher.Get_DomainSearcher(SearcherArguments);
            var Users        = new List <object>();

            if (UserSearcher != null)
            {
                var IdentityFilter = "";
                var Filter         = "";
                if (args.Identity != null)
                {
                    foreach (var samName in args.Identity)
                    {
                        var IdentityInstance = samName.Replace(@"(", @"\28").Replace(@")", @"\29");
                        if (new Regex(@"^S-1-").Match(IdentityInstance).Success)
                        {
                            IdentityFilter += $@"(objectsid={IdentityInstance})";
                        }
                        else if (new Regex(@"^CN=").Match(IdentityInstance).Success)
                        {
                            IdentityFilter += $@"(distinguishedname={IdentityInstance})";
                            if (args.Domain.IsNullOrEmpty() && args.SearchBase.IsNullOrEmpty())
                            {
                                // if a -Domain isn't explicitly set, extract the object domain out of the distinguishedname
                                // and rebuild the domain searcher
                                var IdentityDomain = IdentityInstance.Substring(IdentityInstance.IndexOf(@"DC=")).Replace(@"DC=", @"").Replace(@",", @".");
                                Logger.Write_Verbose($@"[Get-DomainUser] Extracted domain '{IdentityDomain}' from '{IdentityInstance}'");
                                SearcherArguments.Domain = IdentityDomain;
                                UserSearcher             = GetDomainSearcher.Get_DomainSearcher(SearcherArguments);
                                if (UserSearcher == null)
                                {
                                    Logger.Write_Warning($@"[Get-DomainUser] Unable to retrieve domain searcher for '{IdentityDomain}'");
                                }
                            }
                        }
                        else if (new Regex(@"^[0-9A-F]{8}-([0-9A-F]{4}-){3}[0-9A-F]{12}$").Match(IdentityInstance).Success)
                        {
                            var GuidByteString = string.Join(string.Empty, Guid.Parse(IdentityInstance).ToByteArray().Select(x => x.ToString(@"\X2")));
                            IdentityFilter += $@"(objectguid={GuidByteString})";
                        }
                        else if (IdentityInstance.Contains(@"\"))
                        {
                            var ConvertedIdentityInstance = ConvertADName.Convert_ADName(new Args_Convert_ADName
                            {
                                OutputType = ADSNameType.Canonical,
                                Identity   = new string[] { IdentityInstance.Replace(@"\28", @"(").Replace(@"\29", @")") }
                            });
                            if (ConvertedIdentityInstance != null && ConvertedIdentityInstance.Any())
                            {
                                var UserDomain = ConvertedIdentityInstance.First().Substring(0, ConvertedIdentityInstance.First().IndexOf('/'));
                                var UserName   = IdentityInstance.Split(new char[] { '\\' })[1];
                                IdentityFilter          += $@"(samAccountName={UserName})";
                                SearcherArguments.Domain = UserDomain;
                                Logger.Write_Verbose($@"[Get-DomainUser] Extracted domain '{UserDomain}' from '{IdentityInstance}'");
                                UserSearcher = GetDomainSearcher.Get_DomainSearcher(SearcherArguments);
                            }
                        }
                        else
                        {
                            IdentityFilter += $@"(samAccountName={IdentityInstance})";
                        }
                    }
                }

                if (IdentityFilter != null && IdentityFilter.Trim() != "")
                {
                    Filter += $@"(|{IdentityFilter})";
                }

                if (args.SPN)
                {
                    Logger.Write_Verbose(@"[Get-DomainUser] Searching for non-null service principal names");
                    Filter += "(servicePrincipalName=*)";
                }
                if (args.AllowDelegation)
                {
                    Logger.Write_Verbose(@"[Get-DomainUser] Searching for users who can be delegated");
                    // negation of "Accounts that are sensitive and not trusted for delegation"
                    Filter += "(!(userAccountControl:1.2.840.113556.1.4.803:=1048574))";
                }
                if (args.DisallowDelegation)
                {
                    Logger.Write_Verbose(@"[Get-DomainUser] Searching for users who are sensitive and not trusted for delegation");
                    Filter += "(userAccountControl:1.2.840.113556.1.4.803:=1048574)";
                }
                if (args.AdminCount)
                {
                    Logger.Write_Verbose(@"[Get-DomainUser] Searching for adminCount=1");
                    Filter += "(admincount=1)";
                }
                if (args.TrustedToAuth)
                {
                    Logger.Write_Verbose("[Get-DomainUser] Searching for users that are trusted to authenticate for other principals");
                    Filter += "(msds-allowedtodelegateto=*)";
                }
                if (args.PreauthNotRequired)
                {
                    Logger.Write_Verbose("[Get-DomainUser] Searching for user accounts that do not require kerberos preauthenticate");
                    Filter += "(userAccountControl:1.2.840.113556.1.4.803:=4194304)";
                }
                if (args.LDAPFilter.IsNotNullOrEmpty())
                {
                    Logger.Write_Verbose($@"[Get-DomainUser] Using additional LDAP filter: {args.LDAPFilter}");
                    Filter += $@"{args.LDAPFilter}";
                }

                // build the LDAP filter for the dynamic UAC filter value
                var uacs = args.UACFilter.ExtractValues();
                foreach (var uac in uacs)
                {
                    if (uac.IsNot())
                    {
                        Filter += $@"(!(userAccountControl:1.2.840.113556.1.4.803:={uac.GetValueAsInteger()}))";
                    }
                    else
                    {
                        Filter += $@"(userAccountControl:1.2.840.113556.1.4.803:={uac.GetValueAsInteger()})";
                    }
                }

                UserSearcher.Filter = $@"(&(samAccountType=805306368){Filter})";
                Logger.Write_Verbose($@"[Get-DomainUser] filter string: {UserSearcher.Filter}");

                if (args.FindOne)
                {
                    var result = UserSearcher.FindOne();
                    if (args.Raw)
                    {
                        // return raw result objects
                        Users.Add(result);
                    }
                    else
                    {
                        Users.Add(ConvertLDAPProperty.Convert_LDAPProperty(result.Properties));
                    }
                }
                else
                {
                    var Results = UserSearcher.FindAll();
                    foreach (SearchResult result in Results)
                    {
                        if (args.Raw)
                        {
                            // return raw result objects
                            Users.Add(result);
                        }
                        else
                        {
                            Users.Add(ConvertLDAPProperty.Convert_LDAPProperty(result.Properties));
                        }
                    }
                    if (Results != null)
                    {
                        try { Results.Dispose(); }
                        catch (Exception e)
                        {
                            Logger.Write_Verbose($@"[Get-DomainUser] Error disposing of the Results object: {e}");
                        }
                    }
                }
                UserSearcher.Dispose();
            }
            return(Users);
        }
        public static IEnumerable <GroupMember> Get_DomainGroupMember(Args_Get_DomainGroupMember args = null)
        {
            if (args == null)
            {
                args = new Args_Get_DomainGroupMember();
            }

            var SearcherArguments = new Args_Get_DomainSearcher()
            {
                Properties      = new string[] { @"member", @"samaccountname", @"distinguishedname" },
                Domain          = args.Domain,
                LDAPFilter      = args.LDAPFilter,
                SearchBase      = args.SearchBase,
                Server          = args.Server,
                SearchScope     = args.SearchScope,
                ResultPageSize  = args.ResultPageSize,
                ServerTimeLimit = args.ServerTimeLimit,
                Tombstone       = args.Tombstone,
                Credential      = args.Credential
            };

            var ADNameArguments = new Args_Convert_ADName
            {
                Domain     = args.Domain,
                Server     = args.Server,
                Credential = args.Credential
            };

            var GroupMembers  = new List <GroupMember>();
            var GroupSearcher = GetDomainSearcher.Get_DomainSearcher(SearcherArguments);

            if (GroupSearcher != null)
            {
                string        GroupFoundDomain = null;
                string        GroupFoundName   = null;
                string        GroupFoundDN     = null;
                List <string> Members          = null;
                if (args.RecurseUsingMatchingRule)
                {
                    var GroupArguments = new Args_Get_DomainGroup()
                    {
                        Properties      = SearcherArguments.Properties,
                        Domain          = SearcherArguments.Domain,
                        LDAPFilter      = SearcherArguments.LDAPFilter,
                        SearchBase      = SearcherArguments.SearchBase,
                        Server          = SearcherArguments.Server,
                        SearchScope     = SearcherArguments.SearchScope,
                        ResultPageSize  = SearcherArguments.ResultPageSize,
                        ServerTimeLimit = SearcherArguments.ServerTimeLimit,
                        Tombstone       = SearcherArguments.Tombstone,
                        Credential      = SearcherArguments.Credential,
                        Identity        = args.Identity,
                        Raw             = true
                    };
                    var Groups = GetDomainGroup.Get_DomainGroup(GroupArguments);

                    if (Groups == null)
                    {
                        Logger.Write_Warning($@"[Get-DomainGroupMember] Error searching for group with identity: {args.Identity}");
                    }
                    else
                    {
                        var Group = Groups.First() as SearchResult;
                        GroupFoundName = Group.Properties[@"samaccountname"][0] as string;
                        GroupFoundDN   = Group.Properties[@"distinguishedname"][0] as string;
                        if (args.Domain.IsNotNullOrEmpty())
                        {
                            GroupFoundDomain = args.Domain;
                        }
                        else
                        {
                            // if a domain isn't passed, try to extract it from the found group distinguished name
                            if (GroupFoundDN.IsNotNullOrEmpty())
                            {
                                GroupFoundDomain = GroupFoundDN.Substring(GroupFoundDN.IndexOf(@"DC=")).Replace(@"DC=", @"").Replace(@",", @".");
                            }
                        }
                        Logger.Write_Verbose($@"[Get-DomainGroupMember] Using LDAP matching rule to recurse on '{GroupFoundDN}', only user accounts will be returned.");
                        GroupSearcher.Filter = $@"(&(samAccountType=805306368)(memberof:1.2.840.113556.1.4.1941:={GroupFoundDN}))";
                        GroupSearcher.PropertiesToLoad.AddRange(new string[] { @"distinguishedName" });
                        var Results = GroupSearcher.FindAll();
                        if (Results != null)
                        {
                            Members = new List <string>();
                            foreach (SearchResult result in Results)
                            {
                                Members.Add(result.Properties[@"distinguishedname"][0] as string);
                            }
                        }
                    }
                }
                else
                {
                    var IdentityFilter = @"";
                    var Filter         = @"";
                    if (args.Identity != null)
                    {
                        foreach (var item in args.Identity)
                        {
                            var IdentityInstance = item.Replace(@"(", @"\28").Replace(@")", @"\29");
                            if (new Regex(@"^S-1-").Match(IdentityInstance).Success)
                            {
                                IdentityFilter += $@"(objectsid={IdentityInstance})";
                            }
                            else if (new Regex(@"^CN=").Match(IdentityInstance).Success)
                            {
                                IdentityFilter += $@"(distinguishedname={IdentityInstance})";
                                if (args.Domain.IsNullOrEmpty() && args.SearchBase.IsNullOrEmpty())
                                {
                                    // if a -Domain isn't explicitly set, extract the object domain out of the distinguishedname
                                    //   and rebuild the domain searcher
                                    var IdentityDomain = IdentityInstance.Substring(IdentityInstance.IndexOf(@"DC=")).Replace(@"DC=", @"".Replace(@",", @"."));
                                    Logger.Write_Verbose($@"[Get-DomainGroupMember] Extracted domain '{IdentityDomain}' from '{IdentityInstance}'");
                                    SearcherArguments.Domain = IdentityDomain;
                                    GroupSearcher            = GetDomainSearcher.Get_DomainSearcher(SearcherArguments);
                                    if (GroupSearcher == null)
                                    {
                                        Logger.Write_Warning($@"[Get-DomainGroupMember] Unable to retrieve domain searcher for '{IdentityDomain}'");
                                    }
                                }
                            }
                            else if (new Regex(@"^[0-9A-F]{8}-([0-9A-F]{4}-){3}[0-9A-F]{12}$").Match(IdentityInstance).Success)
                            {
                                var GuidByteString = string.Join(string.Empty, Guid.Parse(IdentityInstance).ToByteArray().Select(x => x.ToString(@"\X2")));
                                IdentityFilter += $@"(objectguid={GuidByteString})";
                            }
                            else if (IdentityInstance.Contains(@"\"))
                            {
                                var ConvertedIdentityInstance = ConvertADName.Convert_ADName(new Args_Convert_ADName
                                {
                                    OutputType = ADSNameType.Canonical,
                                    Identity   = new string[] { IdentityInstance.Replace(@"\28", @"(").Replace(@"\29", @")") }
                                });
                                if (ConvertedIdentityInstance != null && ConvertedIdentityInstance.Any())
                                {
                                    var GroupDomain = ConvertedIdentityInstance.First().Substring(0, ConvertedIdentityInstance.First().IndexOf('/'));
                                    var GroupName   = IdentityInstance.Split(new char[] { '\\' })[1];
                                    IdentityFilter          += $@"(samAccountName={GroupName})";
                                    SearcherArguments.Domain = GroupDomain;
                                    Logger.Write_Verbose($@"[Get-DomainGroupMember] Extracted domain '{GroupDomain}' from '{IdentityInstance}'");
                                    GroupSearcher = GetDomainSearcher.Get_DomainSearcher(SearcherArguments);
                                }
                            }
                            else
                            {
                                IdentityFilter += $@"(samAccountName={IdentityInstance})";
                            }
                        }
                    }

                    if (IdentityFilter != null && IdentityFilter.Trim() != @"")
                    {
                        Filter += $@"(|{IdentityFilter})";
                    }

                    if (args.LDAPFilter.IsNotNullOrEmpty())
                    {
                        Logger.Write_Verbose($@"[Get-DomainGroupMember] Using additional LDAP filter: {args.LDAPFilter}");
                        Filter += $@"{args.LDAPFilter}";
                    }

                    GroupSearcher.Filter = $@"(&(objectCategory=group){Filter})";
                    Logger.Write_Verbose($@"[Get-DomainGroupMember] Get-DomainGroupMember filter string: {GroupSearcher.Filter}");
                    SearchResult Result = null;
                    try
                    {
                        Result = GroupSearcher.FindOne();
                    }
                    catch (Exception e)
                    {
                        Logger.Write_Warning($@"[Get-DomainGroupMember] Error searching for group with identity '{args.Identity}': {e}");
                        Members = new List <string>();
                    }

                    GroupFoundName = @"";
                    GroupFoundDN   = @"";

                    if (Result != null)
                    {
                        var tmpProperty = Result.Properties[@"member"];
                        var tmpValues   = new string[tmpProperty.Count];
                        tmpProperty.CopyTo(tmpValues, 0);
                        Members = tmpValues.ToList();
                        string RangedProperty = "";

                        if (Members.Count == 0)
                        {
                            // ranged searching, thanks @meatballs__ !
                            var Finished = false;
                            var Bottom   = 0;
                            var Top      = 0;

                            while (!Finished)
                            {
                                Top = Bottom + 1499;
                                var MemberRange = $@"member;range={Bottom}-{Top}";
                                Bottom += 1500;
                                GroupSearcher.PropertiesToLoad.Clear();
                                GroupSearcher.PropertiesToLoad.Add($@"{MemberRange}");
                                GroupSearcher.PropertiesToLoad.Add(@"samaccountname");
                                GroupSearcher.PropertiesToLoad.Add(@"distinguishedname");

                                try
                                {
                                    Result         = GroupSearcher.FindOne();
                                    RangedProperty = Result.Properties.PropertyNames.GetFirstMatch(@"member;range=*");
                                    tmpProperty    = Result.Properties[RangedProperty];
                                    tmpValues      = new string[tmpProperty.Count];
                                    tmpProperty.CopyTo(tmpValues, 0);
                                    Members.AddRange(tmpValues.ToList());
                                    GroupFoundName = Result.Properties[@"samaccountname"][0] as string;
                                    GroupFoundDN   = Result.Properties[@"distinguishedname"][0] as string;

                                    if (Members.Count == 0)
                                    {
                                        Finished = true;
                                    }
                                }
                                catch
                                {
                                    Finished = true;
                                }
                            }
                        }
                        else
                        {
                            GroupFoundName = Result.Properties[@"samaccountname"][0] as string;
                            GroupFoundDN   = Result.Properties[@"distinguishedname"][0] as string;
                            tmpProperty    = Result.Properties[RangedProperty];
                            tmpValues      = new string[tmpProperty.Count];
                            tmpProperty.CopyTo(tmpValues, 0);
                            Members.AddRange(tmpValues.ToList());
                        }

                        if (args.Domain.IsNotNullOrEmpty())
                        {
                            GroupFoundDomain = args.Domain;
                        }
                        else
                        {
                            // if a domain isn't passed, try to extract it from the found group distinguished name
                            if (GroupFoundDN.IsNotNullOrEmpty())
                            {
                                GroupFoundDomain = GroupFoundDN.Substring(GroupFoundDN.IndexOf(@"DC=")).Replace(@"DC=", @"".Replace(@",", @"."));
                            }
                        }
                    }

                    var    UseMatchingRule = false;
                    string MemberDomain    = null;
                    foreach (var Member in Members)
                    {
                        ResultPropertyCollection Properties = null;
                        if (args.Recurse && UseMatchingRule)
                        {
                            //$Properties = $_.Properties
                        }
                        else
                        {
                            var ObjectSearcherArguments = new Args_Get_DomainObject
                            {
                                ADSPath          = SearcherArguments.ADSPath,
                                Credential       = SearcherArguments.Credential,
                                Domain           = SearcherArguments.Domain,
                                DomainController = SearcherArguments.DomainController,
                                Filter           = SearcherArguments.Filter,
                                LDAPFilter       = SearcherArguments.LDAPFilter,
                                Properties       = SearcherArguments.Properties,
                                ResultPageSize   = SearcherArguments.ResultPageSize,
                                SearchBase       = SearcherArguments.SearchBase,
                                SearchScope      = SearcherArguments.SearchScope,
                                SecurityMasks    = SearcherArguments.SecurityMasks,
                                Server           = SearcherArguments.Server,
                                ServerTimeLimit  = SearcherArguments.ServerTimeLimit,
                                Tombstone        = SearcherArguments.Tombstone
                            };
                            ObjectSearcherArguments.Identity   = new string[] { Member };
                            ObjectSearcherArguments.Raw        = true;
                            ObjectSearcherArguments.Properties = new string[] { @"distinguishedname", @"cn", @"samaccountname", @"objectsid", @"objectclass" };
                            var Object = GetDomainObject.Get_DomainObject(ObjectSearcherArguments)?.FirstOrDefault() as SearchResult;
                            Properties = Object.Properties;
                        }

                        if (Properties != null)
                        {
                            var GroupMember = new GroupMember
                            {
                                GroupDomain            = GroupFoundDomain,
                                GroupName              = GroupFoundName,
                                GroupDistinguishedName = GroupFoundDN
                            };

                            string MemberSID = null;
                            if (Properties["objectsid"] != null)
                            {
                                MemberSID = new System.Security.Principal.SecurityIdentifier(Properties["objectsid"][0] as byte[], 0).Value;
                            }
                            else
                            {
                                MemberSID = null;
                            }

                            string MemberDN = null;
                            try
                            {
                                MemberDN = Properties["distinguishedname"][0].ToString();
                                if (MemberDN.IsRegexMatch(@"ForeignSecurityPrincipals|S-1-5-21"))
                                {
                                    try
                                    {
                                        if (MemberSID.IsNullOrEmpty())
                                        {
                                            MemberSID = Properties["cn"][0].ToString();
                                        }
                                        ADNameArguments.Identity   = new string[] { MemberSID };
                                        ADNameArguments.OutputType = ADSNameType.DomainSimple;
                                        var MemberSimpleName = ConvertADName.Convert_ADName(ADNameArguments);

                                        if (MemberSimpleName != null && MemberSimpleName.Any())
                                        {
                                            MemberDomain = MemberSimpleName.First().Split('@')[1];
                                        }
                                        else
                                        {
                                            Logger.Write_Warning($@"[Get-DomainGroupMember] Error converting {MemberDN}");
                                            MemberDomain = null;
                                        }
                                    }
                                    catch
                                    {
                                        Logger.Write_Warning($@"[Get-DomainGroupMember] Error converting {MemberDN}");
                                        MemberDomain = null;
                                    }
                                }
                                else
                                {
                                    // extract the FQDN from the Distinguished Name
                                    MemberDomain = MemberDN.Substring(MemberDN.IndexOf(@"DC=")).Replace(@"DC=", @"").Replace(@",", @".");
                                }
                            }
                            catch
                            {
                                MemberDN     = null;
                                MemberDomain = null;
                            }
                            string MemberName = null;
                            if (Properties["samaccountname"] != null)
                            {
                                // forest users have the samAccountName set
                                MemberName = Properties["samaccountname"][0].ToString();
                            }
                            else
                            {
                                // external trust users have a SID, so convert it
                                try
                                {
                                    MemberName = ConvertFromSID.ConvertFrom_SID(new Args_ConvertFrom_SID
                                    {
                                        ObjectSID  = new string[] { Properties["cn"][0].ToString() },
                                        Domain     = ADNameArguments.Domain,
                                        Server     = ADNameArguments.Server,
                                        Credential = ADNameArguments.Credential
                                    }).First();
                                }
                                catch
                                {
                                    // if there's a problem contacting the domain to resolve the SID
                                    MemberName = Properties["cn"][0].ToString();
                                }
                            }

                            string MemberObjectClass = null;
                            if (Properties["objectclass"].RegexContains(@"computer"))
                            {
                                MemberObjectClass = @"computer";
                            }
                            else if (Properties["objectclass"].RegexContains(@"group"))
                            {
                                MemberObjectClass = @"group";
                            }
                            else if (Properties["objectclass"].RegexContains(@"user"))
                            {
                                MemberObjectClass = @"user";
                            }
                            else
                            {
                                MemberObjectClass = null;
                            }
                            GroupMember.MemberDomain            = MemberDomain;
                            GroupMember.MemberName              = MemberName;
                            GroupMember.MemberDistinguishedName = MemberDN;
                            GroupMember.MemberObjectClass       = MemberObjectClass;
                            GroupMember.MemberSID = MemberSID;
                            GroupMembers.Add(GroupMember);

                            // if we're doing manual recursion
                            if (args.Recurse && MemberDN.IsNotNullOrEmpty() && MemberObjectClass.IsRegexMatch(@"group"))
                            {
                                Logger.Write_Verbose($@"[Get-DomainGroupMember] Manually recursing on group: {MemberDN}");
                                var GroupArguments = new Args_Get_DomainGroupMember()
                                {
                                    Domain          = SearcherArguments.Domain,
                                    LDAPFilter      = SearcherArguments.LDAPFilter,
                                    SearchBase      = SearcherArguments.SearchBase,
                                    Server          = SearcherArguments.Server,
                                    SearchScope     = SearcherArguments.SearchScope,
                                    ResultPageSize  = SearcherArguments.ResultPageSize,
                                    ServerTimeLimit = SearcherArguments.ServerTimeLimit,
                                    Tombstone       = SearcherArguments.Tombstone,
                                    Credential      = SearcherArguments.Credential,
                                    Identity        = new string[] { MemberDN }
                                };
                                GroupMembers.AddRange(Get_DomainGroupMember(GroupArguments));
                            }
                        }
                    }
                }
                GroupSearcher.Dispose();
            }
            return(GroupMembers);
        }