예제 #1
0
        private bool IsOfCorrectType(DirectoryEntry de)
        {
            bool flag;

            List <string> .Enumerator enumerator = this.schemaTypes.GetEnumerator();
            try
            {
                while (enumerator.MoveNext())
                {
                    string current = enumerator.Current;
                    if (!SAMUtils.IsOfObjectClass(de, current))
                    {
                        continue;
                    }
                    flag = true;
                    return(flag);
                }
                return(false);
            }
            finally
            {
                enumerator.Dispose();
            }
            return(flag);
        }
예제 #2
0
파일: SAMUtils.cs 프로젝트: jnm2/corefx
        static internal Principal DirectoryEntryAsPrincipal(DirectoryEntry de, StoreCtx storeCtx)
        {
            string className = de.SchemaClassName;

            // Unlike AD, we don't have to worry about cross-store refs here.  In AD, if there's
            // a cross-store ref, we'll get back a DirectoryEntry of the FPO object.  In the WinNT ADSI
            // provider, we'll get back the DirectoryEntry of the remote object itself --- ADSI does
            // the domain vs. local resolution for us.

            if (SAMUtils.IsOfObjectClass(de, "Computer") ||
                SAMUtils.IsOfObjectClass(de, "User") ||
                SAMUtils.IsOfObjectClass(de, "Group"))
            {
                return(storeCtx.GetAsPrincipal(de, null));
            }
            else
            {
                Debug.Fail(String.Format(
                               CultureInfo.CurrentCulture,
                               "SAMUtils.DirectoryEntryAsPrincipal: fell off end, Path={0}, SchemaClassName={1}",
                               de.Path,
                               de.SchemaClassName));
                return(null);
            }
        }
예제 #3
0
 private static bool IsOfObjectClass(DirectoryEntry de, string className)
 {
     if (!de.Path.StartsWith("WinNT:", StringComparison.Ordinal))
     {
         return(ADUtils.IsOfObjectClass(de, className));
     }
     else
     {
         return(SAMUtils.IsOfObjectClass(de, className));
     }
 }
예제 #4
0
 internal static Principal DirectoryEntryAsPrincipal(DirectoryEntry de, StoreCtx storeCtx)
 {
     if (SAMUtils.IsOfObjectClass(de, "Computer") || SAMUtils.IsOfObjectClass(de, "User") || SAMUtils.IsOfObjectClass(de, "Group"))
     {
         return(storeCtx.GetAsPrincipal(de, null));
     }
     else
     {
         return(null);
     }
 }
예제 #5
0
        private static bool WildcardStringMatch(FilterBase filter, string wildcardFilter, string property)
        {
            Regex extra = filter.Extra as Regex;

            if (extra == null)
            {
                extra        = new Regex(SAMUtils.PAPIQueryToRegexString(wildcardFilter), RegexOptions.Singleline);
                filter.Extra = extra;
            }
            Match match = extra.Match(property);

            return(match.Success);
        }
예제 #6
0
        private bool IsOfCorrectType(DirectoryEntry de)
        {
            // Is the object in question one of the desired types?

            foreach (string schemaType in _schemaTypes)
            {
                if (SAMUtils.IsOfObjectClass(de, schemaType))
                {
                    return(true);
                }
            }

            return(false);
        }
예제 #7
0
        // Throws exception if ctxBase is not a computer object
        public SAMStoreCtx(DirectoryEntry ctxBase, bool ownCtxBase, string username, string password, ContextOptions options)
        {
            Debug.Assert(ctxBase != null);
            GlobalDebug.WriteLineIf(GlobalDebug.Info, "SAMStoreCtx", "Constructing SAMStoreCtx for {0}", ctxBase.Path);

            Debug.Assert(SAMUtils.IsOfObjectClass(ctxBase, "Computer"));

            _ctxBase    = ctxBase;
            _ownCtxBase = ownCtxBase;

            if (username != null && password != null)
            {
                _credentials = new NetCred(username, password);
            }

            _contextOptions = options;
            _authTypes      = SDSUtils.MapOptionsToAuthTypes(options);
        }
예제 #8
0
        //
        // Conversion routines
        //

        private static bool WildcardStringMatch(FilterBase filter, string wildcardFilter, string property)
        {
            // Build a Regex that matches valueToMatch, and store it on the Filter (so that we don't have
            // to have the CLR constantly reparse the regex string).
            // Ideally, we'd like to use a compiled Regex (RegexOptions.Compiled) for performance,
            // but the CLR cannot release generated MSIL.  Thus, our memory usage would grow without bound
            // each time a query was performed.

            Regex regex = filter.Extra as Regex;

            if (regex == null)
            {
                regex        = new Regex(SAMUtils.PAPIQueryToRegexString(wildcardFilter), RegexOptions.Singleline);
                filter.Extra = regex;
            }

            return(regex.IsMatch(property));
        }
예제 #9
0
파일: SAMUtils.cs 프로젝트: jnm2/corefx
        internal static bool GetOSVersion(DirectoryEntry computerDE, out int versionMajor, out int versionMinor)
        {
            Debug.Assert(SAMUtils.IsOfObjectClass(computerDE, "Computer"));

            versionMajor = 0;
            versionMinor = 0;

            string version = null;

            try
            {
                if (computerDE.Properties["OperatingSystemVersion"].Count > 0)
                {
                    Debug.Assert(computerDE.Properties["OperatingSystemVersion"].Count == 1);

                    version = (string)computerDE.Properties["OperatingSystemVersion"].Value;
                }
            }
            catch (COMException e)
            {
                GlobalDebug.WriteLineIf(GlobalDebug.Error, "SAMUtils", "GetOSVersion: caught COMException with message " + e.Message);

                // Couldn't retrieve the value
                if (e.ErrorCode == unchecked ((int)0x80070035))  // ERROR_BAD_NETPATH
                {
                    return(false);
                }

                throw;
            }

            // Couldn't retrieve the value
            if (version == null || version.Length == 0)
            {
                return(false);
            }

            // This string should be in the form "M.N", where M and N are integers.
            // We'll also accept "M", which we'll treat as "M.0".
            //
            // We'll split the string into its period-separated components, and parse
            // each component into an int.
            string[] versionComponents = version.Split(new char[] { '.' });

            Debug.Assert(versionComponents.Length >= 1);    // since version was a non-empty string

            try
            {
                versionMajor = Int32.Parse(versionComponents[0], CultureInfo.InvariantCulture);

                if (versionComponents.Length > 1)
                {
                    versionMinor = Int32.Parse(versionComponents[1], CultureInfo.InvariantCulture);
                }

                // Sanity check: there are no negetive OS versions, nor is there a version "0".
                if (versionMajor <= 0 || versionMinor < 0)
                {
                    Debug.Fail(String.Format(
                                   CultureInfo.CurrentCulture,
                                   "SAMUtils.GetOSVersion: {0} claims to have negetive OS version, {1}",
                                   computerDE.Path,
                                   version));

                    return(false);
                }
            }
            catch (FormatException)
            {
                Debug.Fail(String.Format(
                               CultureInfo.CurrentCulture,
                               "SAMUtils.GetOSVersion: FormatException on {0} for {1}",
                               version,
                               computerDE.Path));

                return(false);
            }
            catch (OverflowException)
            {
                Debug.Fail(String.Format(
                               CultureInfo.CurrentCulture,
                               "SAMUtils.GetOSVersion: OverflowException on {0} for {1}",
                               version,
                               computerDE.Path));
                return(false);
            }

            return(true);
        }
예제 #10
0
        // computerInfoLock must be held coming in here
        private void LoadComputerInfo()
        {
            GlobalDebug.WriteLineIf(GlobalDebug.Info, "SAMStoreCtx", "LoadComputerInfo");

            Debug.Assert(_ctxBase != null);
            Debug.Assert(SAMUtils.IsOfObjectClass(_ctxBase, "Computer"));

            //
            // Target OS version
            //
            int versionMajor;
            int versionMinor;

            if (!SAMUtils.GetOSVersion(_ctxBase, out versionMajor, out versionMinor))
            {
                throw new PrincipalOperationException(SR.SAMStoreCtxUnableToRetrieveVersion);
            }

            Debug.Assert(versionMajor > 0);
            Debug.Assert(versionMinor >= 0);

            if (versionMajor >= 6)      // 6.0 == Longhorn
            {
                _isLSAM = true;
            }
            else
            {
                _isLSAM = false;
            }

            GlobalDebug.WriteLineIf(GlobalDebug.Info, "SAMStoreCtx", "LoadComputerInfo: ver={0}.{1}", versionMajor, versionMinor);

            //
            // Machine user-supplied name
            //

            // This ADSI property stores the machine name as supplied by the user in the ADsPath.
            // It could be a flat name or a DNS name.
            if (_ctxBase.Properties["Name"].Count > 0)
            {
                Debug.Assert(_ctxBase.Properties["Name"].Count == 1);

                _machineUserSuppliedName = (string)_ctxBase.Properties["Name"].Value;
                GlobalDebug.WriteLineIf(GlobalDebug.Info, "SAMStoreCtx", "LoadComputerInfo: machineUserSuppliedName={0}", _machineUserSuppliedName);
            }
            else
            {
                throw new PrincipalOperationException(SR.SAMStoreCtxUnableToRetrieveMachineName);
            }

            //
            // Machine flat name
            //
            IntPtr buffer = IntPtr.Zero;

            try
            {
                // This function takes in a flat or DNS name, and returns the flat name of the computer
                int err = UnsafeNativeMethods.NetWkstaGetInfo(_machineUserSuppliedName, 100, ref buffer);
                if (err == 0)
                {
                    UnsafeNativeMethods.WKSTA_INFO_100 wkstaInfo =
                        (UnsafeNativeMethods.WKSTA_INFO_100)Marshal.PtrToStructure(buffer, typeof(UnsafeNativeMethods.WKSTA_INFO_100));

                    _machineFlatName = wkstaInfo.wki100_computername;
                    GlobalDebug.WriteLineIf(GlobalDebug.Info, "SAMStoreCtx", "LoadComputerInfo: machineFlatName={0}", _machineFlatName);
                }
                else
                {
                    throw new PrincipalOperationException(
                              SR.Format(
                                  SR.SAMStoreCtxUnableToRetrieveFlatMachineName,
                                  err));
                }
            }
            finally
            {
                if (buffer != IntPtr.Zero)
                {
                    UnsafeNativeMethods.NetApiBufferFree(buffer);
                }
            }
        }
예제 #11
0
        private bool MoveNextLocal()
        {
            bool needToRetry;

            do
            {
                needToRetry = false;

                bool f = _membersEnumerator.MoveNext();

                if (f) // got a value
                {
                    GlobalDebug.WriteLineIf(GlobalDebug.Info, "SAMMembersSet", "MoveNextLocal: got a value from the enumerator");

                    UnsafeNativeMethods.IADs nativeMember = (UnsafeNativeMethods.IADs)_membersEnumerator.Current;

                    // If we encountered a group member corresponding to a fake principal such as
                    // NT AUTHORITY/NETWORK SERVICE, construct and prepare to return the fake principal.
                    byte[]  sid     = (byte[])nativeMember.Get("objectSid");
                    SidType sidType = Utils.ClassifySID(sid);
                    if (sidType == SidType.FakeObject)
                    {
                        GlobalDebug.WriteLineIf(GlobalDebug.Info, "SAMMembersSet", "MoveNextLocal: fake principal, sid={0}", Utils.ByteArrayToString(sid));

                        _currentFakePrincipal = _storeCtx.ConstructFakePrincipalFromSID(sid);
                        _current        = null;
                        _currentForeign = null;

                        if (_foreignResultSet != null)
                        {
                            _foreignResultSet.Dispose();
                        }
                        _foreignResultSet = null;
                        return(true);
                    }

                    // We do this, rather than using the DirectoryEntry constructor that takes a native IADs object,
                    // is so the credentials get transferred to the new DirectoryEntry.  If we just use the native
                    // object constructor, the native object will have the right credentials, but the DirectoryEntry
                    // will have default (null) credentials, which it'll use anytime it needs to use credentials.
                    DirectoryEntry de = SDSUtils.BuildDirectoryEntry(
                        _storeCtx.Credentials,
                        _storeCtx.AuthTypes);

                    if (sidType == SidType.RealObjectFakeDomain)
                    {
                        // Transform the "WinNT://BUILTIN/foo" path to "WinNT://machineName/foo"
                        string builtinADsPath = nativeMember.ADsPath;

                        UnsafeNativeMethods.Pathname     pathCracker = new UnsafeNativeMethods.Pathname();
                        UnsafeNativeMethods.IADsPathname pathName    = (UnsafeNativeMethods.IADsPathname)pathCracker;

                        pathName.Set(builtinADsPath, 1 /* ADS_SETTYPE_FULL */);

                        // Build the "WinNT://" portion of the new path
                        StringBuilder adsPath = new StringBuilder();
                        adsPath.Append("WinNT://");
                        //adsPath.Append(pathName.Retrieve(9 /*ADS_FORMAT_SERVER */));

                        // Build the "WinNT://machineName/" portion of the new path
                        adsPath.Append(_storeCtx.MachineUserSuppliedName);
                        adsPath.Append('/');

                        // Build the "WinNT://machineName/foo" portion of the new path
                        int cElements = pathName.GetNumElements();

                        Debug.Assert(cElements >= 2);       // "WinNT://BUILTIN/foo" == 2 elements

                        // Note that the ADSI WinNT provider indexes them backwards, e.g., in
                        // "WinNT://BUILTIN/A/B", BUILTIN == 2, A == 1, B == 0.
                        for (int i = cElements - 2; i >= 0; i--)
                        {
                            adsPath.Append(pathName.GetElement(i));
                            adsPath.Append('/');
                        }

                        adsPath.Remove(adsPath.Length - 1, 1);  // remove the trailing "/"

                        de.Path = adsPath.ToString();

                        GlobalDebug.WriteLineIf(GlobalDebug.Info, "SAMMembersSet", "MoveNextLocal: fake domain: {0} --> {1}", builtinADsPath, adsPath);
                    }
                    else
                    {
                        Debug.Assert(sidType == SidType.RealObject);
                        de.Path = nativeMember.ADsPath;

                        GlobalDebug.WriteLineIf(GlobalDebug.Info, "SAMMembersSet", "MoveNextLocal: real domain {0}", de.Path);
                    }

                    //  Debug.Assert(Utils.AreBytesEqual(sid, (byte[]) de.Properties["objectSid"].Value));

                    if (IsLocalMember(sid))
                    {
                        // If we're processing recursively, and the member is a group,
                        // we don't return it but instead treat it as something to recursively
                        // visit (expand) later.
                        if (!_recursive || !SAMUtils.IsOfObjectClass(de, "Group"))
                        {
                            GlobalDebug.WriteLineIf(GlobalDebug.Info, "SAMMembersSet", "MoveNextLocal: setting current to {0}", de.Path);

                            // Not recursive, or not a group.  Return the principal.
                            _current = de;
                            _currentFakePrincipal = null;
                            _currentForeign       = null;

                            if (_foreignResultSet != null)
                            {
                                _foreignResultSet.Dispose();
                            }
                            _foreignResultSet = null;
                            return(true);
                        }
                        else
                        {
                            GlobalDebug.WriteLineIf(GlobalDebug.Info, "SAMMembersSet", "MoveNextLocal: adding {0} to groupsToVisit", de.Path);

                            // Save off for later, if we haven't done so already.
                            if (!_groupsVisited.Contains(de.Path) && !_groupsToVisit.Contains(de.Path))
                            {
                                _groupsToVisit.Add(de.Path);
                            }

                            needToRetry = true;
                            continue;
                        }
                    }
                    else
                    {
                        // It's a foreign principal (e..g, an AD user or group).
                        // Save it off for later.

                        GlobalDebug.WriteLineIf(GlobalDebug.Info, "SAMMembersSet", "MoveNextLocal: adding {0} to foreignMembers", de.Path);

                        _foreignMembers.Add(de);
                        needToRetry = true;
                        continue;
                    }
                }
                else
                {
                    // We reached the end of this group's membership.
                    // If we're supposed to be recursively expanding, we need to expand
                    // any remaining non-foreign groups we earlier visited.
                    if (_recursive)
                    {
                        GlobalDebug.WriteLineIf(GlobalDebug.Info, "SAMMembersSet", "MoveNextLocal: recursive processing, groupsToVisit={0}", _groupsToVisit.Count);

                        if (_groupsToVisit.Count > 0)
                        {
                            // Pull off the next group to visit
                            string groupPath = _groupsToVisit[0];
                            GlobalDebug.WriteLineIf(GlobalDebug.Info, "SAMMembersSet", "MoveNextLocal: recursively processing {0}", groupPath);

                            _groupsToVisit.RemoveAt(0);
                            _groupsVisited.Add(groupPath);

                            // Set up for the next round of enumeration
                            DirectoryEntry de = SDSUtils.BuildDirectoryEntry(
                                groupPath,
                                _storeCtx.Credentials,
                                _storeCtx.AuthTypes);

                            _group = (UnsafeNativeMethods.IADsGroup)de.NativeObject;

                            UnsafeNativeMethods.IADsMembers iADsMembers = _group.Members();
                            _membersEnumerator = ((IEnumerable)iADsMembers).GetEnumerator();

                            // and go on to the first member of this new group
                            needToRetry = true;
                            continue;
                        }
                    }
                }
            }while (needToRetry);

            return(false);
        }
예제 #12
0
        private bool MoveNextLocal()
        {
            bool flag;

            do
            {
                flag = false;
                bool flag1 = this.membersEnumerator.MoveNext();
                if (!flag1)
                {
                    if (!this.recursive || this.groupsToVisit.Count <= 0)
                    {
                        continue;
                    }
                    string item = this.groupsToVisit[0];
                    this.groupsToVisit.RemoveAt(0);
                    this.groupsVisited.Add(item);
                    DirectoryEntry directoryEntry = SDSUtils.BuildDirectoryEntry(item, this.storeCtx.Credentials, this.storeCtx.AuthTypes);
                    this.@group = (UnsafeNativeMethods.IADsGroup)directoryEntry.NativeObject;
                    UnsafeNativeMethods.IADsMembers aDsMember = [email protected]();
                    this.membersEnumerator = ((IEnumerable)aDsMember).GetEnumerator();
                    flag = true;
                }
                else
                {
                    UnsafeNativeMethods.IADs current = (UnsafeNativeMethods.IADs) this.membersEnumerator.Current;
                    byte[]  numArray = (byte[])current.Get("objectSid");
                    SidType sidType  = Utils.ClassifySID(numArray);
                    if (sidType != SidType.FakeObject)
                    {
                        DirectoryEntry aDsPath = SDSUtils.BuildDirectoryEntry(this.storeCtx.Credentials, this.storeCtx.AuthTypes);
                        if (sidType != SidType.RealObjectFakeDomain)
                        {
                            aDsPath.Path = current.ADsPath;
                        }
                        else
                        {
                            string str = current.ADsPath;
                            UnsafeNativeMethods.Pathname     pathname    = new UnsafeNativeMethods.Pathname();
                            UnsafeNativeMethods.IADsPathname aDsPathname = (UnsafeNativeMethods.IADsPathname)pathname;
                            aDsPathname.Set(str, 1);
                            StringBuilder stringBuilder = new StringBuilder();
                            stringBuilder.Append("WinNT://");
                            stringBuilder.Append(this.storeCtx.MachineUserSuppliedName);
                            stringBuilder.Append("/");
                            int numElements = aDsPathname.GetNumElements();
                            for (int i = numElements - 2; i >= 0; i--)
                            {
                                stringBuilder.Append(aDsPathname.GetElement(i));
                                stringBuilder.Append("/");
                            }
                            stringBuilder.Remove(stringBuilder.Length - 1, 1);
                            aDsPath.Path = stringBuilder.ToString();
                        }
                        if (!this.IsLocalMember(numArray))
                        {
                            this.foreignMembers.Add(aDsPath);
                            flag = true;
                        }
                        else
                        {
                            if (!this.recursive || !SAMUtils.IsOfObjectClass(aDsPath, "Group"))
                            {
                                this.current = aDsPath;
                                this.currentFakePrincipal = null;
                                this.currentForeign       = null;
                                if (this.foreignResultSet != null)
                                {
                                    this.foreignResultSet.Dispose();
                                }
                                this.foreignResultSet = null;
                                return(true);
                            }
                            else
                            {
                                if (!this.groupsVisited.Contains(aDsPath.Path) && !this.groupsToVisit.Contains(aDsPath.Path))
                                {
                                    this.groupsToVisit.Add(aDsPath.Path);
                                }
                                flag = true;
                            }
                        }
                    }
                    else
                    {
                        this.currentFakePrincipal = this.storeCtx.ConstructFakePrincipalFromSID(numArray);
                        this.current        = null;
                        this.currentForeign = null;
                        if (this.foreignResultSet != null)
                        {
                            this.foreignResultSet.Dispose();
                        }
                        this.foreignResultSet = null;
                        return(true);
                    }
                }
            }while (flag);
            return(false);
        }