Пример #1
0
		internal SAMGroupsSet(UnsafeNativeMethods.IADsMembers iADsMembers, SAMStoreCtx storeCtx, DirectoryEntry ctxBase)
		{
			this.atBeginning = true;
			this.groupsEnumerator = ((IEnumerable)iADsMembers).GetEnumerator();
			this.storeCtx = storeCtx;
			this.ctxBase = ctxBase;
		}
Пример #2
0
        internal SAMGroupsSet(UnsafeNativeMethods.IADsMembers iADsMembers, SAMStoreCtx storeCtx, DirectoryEntry ctxBase)
        {
            GlobalDebug.WriteLineIf(GlobalDebug.Info, "SAMGroupsSet", "SAMGroupsSet: creating for path={0}", ctxBase.Path);

            _groupsEnumerator = ((IEnumerable)iADsMembers).GetEnumerator();

            _storeCtx = storeCtx;
            _ctxBase = ctxBase;
        }
Пример #3
0
		internal SidList(UnsafeNativeMethods.SID_AND_ATTR[] sidAndAttr)
		{
			this.entries = new List<SidListEntry>();
			int length = (int)sidAndAttr.Length;
			IntPtr[] intPtrArray = new IntPtr[length];
			for (int i = 0; i < length; i++)
			{
				intPtrArray[i] = sidAndAttr[i].pSid;
			}
			this.TranslateSids(null, intPtrArray);
		}
Пример #4
0
        internal SidList(UnsafeNativeMethods.SID_AND_ATTR[] sidAndAttr)
        {
            GlobalDebug.WriteLineIf(GlobalDebug.Info, "SidList", "SidList: processing {0} Sid+Attr SIDs", sidAndAttr.Length);

            // Build the list of SIDs to resolve
            int sidCount = sidAndAttr.Length;
            IntPtr[] pSids = new IntPtr[sidCount];

            for (int i = 0; i < sidCount; i++)
            {
                pSids[i] = sidAndAttr[i].pSid;
            }

            TranslateSids(null, pSids);
        }
Пример #5
0
		internal SAMMembersSet(string groupPath, UnsafeNativeMethods.IADsGroup group, bool recursive, SAMStoreCtx storeCtx, DirectoryEntry ctxBase)
		{
			this.atBeginning = true;
			this.groupsVisited = new List<string>();
			this.groupsToVisit = new List<string>();
			this.foreignMembers = new List<DirectoryEntry>();
			this.foreignGroups = new List<GroupPrincipal>();
			this.storeCtx = storeCtx;
			this.ctxBase = ctxBase;
			this.@group = group;
			this.originalGroup = group;
			this.recursive = recursive;
			this.groupsVisited.Add(groupPath);
			UnsafeNativeMethods.IADsMembers aDsMember = group.Members();
			this.membersEnumerator = ((IEnumerable)aDsMember).GetEnumerator();
		}
Пример #6
0
        internal SAMMembersSet(string groupPath, UnsafeNativeMethods.IADsGroup group, bool recursive, SAMStoreCtx storeCtx, DirectoryEntry ctxBase)
        {
            GlobalDebug.WriteLineIf(GlobalDebug.Info,
                                    "SAMMembersSet",
                                    "SAMMembersSet: groupPath={0}, recursive={1}, base={2}",
                                    groupPath,
                                    recursive,
                                    ctxBase.Path);

            _storeCtx = storeCtx;
            _ctxBase = ctxBase;

            _group = group;
            _originalGroup = group;
            _recursive = recursive;

            _groupsVisited.Add(groupPath);    // so we don't revisit it

            UnsafeNativeMethods.IADsMembers iADsMembers = group.Members();
            _membersEnumerator = ((IEnumerable)iADsMembers).GetEnumerator();
        }
        private bool BindSam(string target, string userName, string password)
        {
            StringBuilder adsPath = new StringBuilder();

            adsPath.Append("WinNT://");
            adsPath.Append(_serverName);
            adsPath.Append(",computer");
            Guid   g     = new Guid("fd8256d0-fd15-11ce-abc4-02608c9e7553"); // IID_IUnknown
            object value = null;
            // always attempt secure auth..
            int    authenticationType = 1;
            object unmanagedResult    = null;

            try
            {
                if (Thread.CurrentThread.GetApartmentState() == ApartmentState.Unknown)
                {
                    Thread.CurrentThread.SetApartmentState(ApartmentState.MTA);
                }
                // We need the credentials to be in the form <machine>\\<user>
                // if they just passed user then append the machine name here.
                if (null != userName)
                {
                    int index = userName.IndexOf('\\');
                    if (index == -1)
                    {
                        userName = _serverName + "\\" + userName;
                    }
                }

                int hr = UnsafeNativeMethods.ADsOpenObject(adsPath.ToString(), userName, password, (int)authenticationType, ref g, out value);

                if (hr != 0)
                {
                    if (hr == unchecked ((int)(ExceptionHelper.ERROR_HRESULT_LOGON_FAILURE)))
                    {
                        // This is the invalid credetials case.  We want to return false
                        // instead of throwing an exception
                        return(false);
                    }
                    else
                    {
                        throw ExceptionHelper.GetExceptionFromErrorCode(hr);
                    }
                }

                unmanagedResult = ((UnsafeNativeMethods.IADs)value).Get("name");
            }
            catch (System.Runtime.InteropServices.COMException e)
            {
                if (e.ErrorCode == unchecked ((int)(ExceptionHelper.ERROR_HRESULT_LOGON_FAILURE)))
                {
                    return(false);
                }
                else
                {
                    throw ExceptionHelper.GetExceptionFromCOMException(e);
                }
            }
            finally
            {
                if (value != null)
                {
                    System.Runtime.InteropServices.Marshal.ReleaseComObject(value);
                }
            }

            return(true);
        }
Пример #8
0
		public static extern int DsRoleGetPrimaryDomainInformation(IntPtr lpServer, UnsafeNativeMethods.DSROLE_PRIMARY_DOMAIN_INFO_LEVEL InfoLevel, out IntPtr Buffer);
Пример #9
0
		public static extern bool AuthzInitializeContextFromSid(int Flags, IntPtr UserSid, IntPtr AuthzResourceManager, IntPtr pExpirationTime, UnsafeNativeMethods.LUID Identitifier, IntPtr DynamicGroupArgs, out IntPtr pAuthzClientContext);
Пример #10
0
        protected void TranslateSids(string target, IntPtr[] pSids)
        {
            GlobalDebug.WriteLineIf(GlobalDebug.Info, "AuthZSet", "SidList: processing {0} SIDs", pSids.Length);

            // if there are no SIDs to translate return
            if (pSids.Length == 0)
            {
                return;
            }

            // Build the list of SIDs to resolve
            int sidCount = pSids.Length;

            // Translate the SIDs in bulk
            IntPtr pOA           = IntPtr.Zero;
            IntPtr pPolicyHandle = IntPtr.Zero;

            IntPtr pDomains = IntPtr.Zero;

            UnsafeNativeMethods.LSA_TRUST_INFORMATION[] domains;

            IntPtr pNames = IntPtr.Zero;

            UnsafeNativeMethods.LSA_TRANSLATED_NAME[] names;

            try
            {
                //
                // Get the policy handle
                //
                UnsafeNativeMethods.LSA_OBJECT_ATTRIBUTES oa = new UnsafeNativeMethods.LSA_OBJECT_ATTRIBUTES();

                pOA = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(UnsafeNativeMethods.LSA_OBJECT_ATTRIBUTES)));
                Marshal.StructureToPtr(oa, pOA, false);

                int err = 0;
                if (target == null)
                {
                    err = UnsafeNativeMethods.LsaOpenPolicy(
                        IntPtr.Zero,
                        pOA,
                        0x800,                    // POLICY_LOOKUP_NAMES
                        ref pPolicyHandle);
                }
                else
                {
                    // Build an entry.  Note that LSA_UNICODE_STRING.length is in bytes,
                    // while PtrToStringUni expects a length in characters.
                    UnsafeNativeMethods.LSA_UNICODE_STRING_Managed lsaTargetString = new UnsafeNativeMethods.LSA_UNICODE_STRING_Managed();
                    lsaTargetString.buffer        = target;
                    lsaTargetString.length        = (ushort)(target.Length * 2);
                    lsaTargetString.maximumLength = lsaTargetString.length;

                    IntPtr lsaTargetPr = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(UnsafeNativeMethods.LSA_UNICODE_STRING)));

                    try
                    {
                        Marshal.StructureToPtr(lsaTargetString, lsaTargetPr, false);

                        err = UnsafeNativeMethods.LsaOpenPolicy(
                            lsaTargetPr,
                            pOA,
                            0x800,                    // POLICY_LOOKUP_NAMES
                            ref pPolicyHandle);
                    }
                    finally
                    {
                        if (lsaTargetPr != IntPtr.Zero)
                        {
                            UnsafeNativeMethods.LSA_UNICODE_STRING lsaTargetUnmanagedPtr =
                                (UnsafeNativeMethods.LSA_UNICODE_STRING)Marshal.PtrToStructure(lsaTargetPr, typeof(UnsafeNativeMethods.LSA_UNICODE_STRING));
                            if (lsaTargetUnmanagedPtr.buffer != IntPtr.Zero)
                            {
                                Marshal.FreeHGlobal(lsaTargetUnmanagedPtr.buffer);
                                lsaTargetUnmanagedPtr.buffer = IntPtr.Zero;
                            }
                            Marshal.FreeHGlobal(lsaTargetPr);
                        }
                    }
                }

                if (err != 0)
                {
                    GlobalDebug.WriteLineIf(GlobalDebug.Warn, "AuthZSet", "SidList: couldn't get policy handle, err={0}", err);

                    throw new PrincipalOperationException(string.Format(CultureInfo.CurrentCulture,
                                                                        SR.AuthZErrorEnumeratingGroups,
                                                                        SafeNativeMethods.LsaNtStatusToWinError(err)));
                }

                Debug.Assert(pPolicyHandle != IntPtr.Zero);

                //
                // Translate the SIDs
                //

                err = UnsafeNativeMethods.LsaLookupSids(
                    pPolicyHandle,
                    sidCount,
                    pSids,
                    out pDomains,
                    out pNames);

                // ignore error STATUS_SOME_NOT_MAPPED = 0x00000107 and
                // STATUS_NONE_MAPPED = 0xC0000073
                if (err != 0 &&
                    err != 263 &&
                    err != -1073741709)
                {
                    GlobalDebug.WriteLineIf(GlobalDebug.Warn, "AuthZSet", "SidList: LsaLookupSids failed, err={0}", err);

                    throw new PrincipalOperationException(string.Format(CultureInfo.CurrentCulture,
                                                                        SR.AuthZErrorEnumeratingGroups,
                                                                        SafeNativeMethods.LsaNtStatusToWinError(err)));
                }

                //
                // Get the group names in managed form
                //
                names = new UnsafeNativeMethods.LSA_TRANSLATED_NAME[sidCount];
                IntPtr pCurrentName = pNames;

                for (int i = 0; i < sidCount; i++)
                {
                    names[i] = (UnsafeNativeMethods.LSA_TRANSLATED_NAME)
                               Marshal.PtrToStructure(pCurrentName, typeof(UnsafeNativeMethods.LSA_TRANSLATED_NAME));

                    pCurrentName = new IntPtr(pCurrentName.ToInt64() + Marshal.SizeOf(typeof(UnsafeNativeMethods.LSA_TRANSLATED_NAME)));
                }

                //
                // Get the domain names in managed form
                //

                // Extract LSA_REFERENCED_DOMAIN_LIST.Entries

                UnsafeNativeMethods.LSA_REFERENCED_DOMAIN_LIST referencedDomains = (UnsafeNativeMethods.LSA_REFERENCED_DOMAIN_LIST)Marshal.PtrToStructure(pDomains, typeof(UnsafeNativeMethods.LSA_REFERENCED_DOMAIN_LIST));

                int domainCount = referencedDomains.entries;

                // Extract LSA_REFERENCED_DOMAIN_LIST.Domains, by iterating over the array and marshalling
                // each native LSA_TRUST_INFORMATION into a managed LSA_TRUST_INFORMATION.

                domains = new UnsafeNativeMethods.LSA_TRUST_INFORMATION[domainCount];

                IntPtr pCurrentDomain = referencedDomains.domains;

                for (int i = 0; i < domainCount; i++)
                {
                    domains[i]     = (UnsafeNativeMethods.LSA_TRUST_INFORMATION)Marshal.PtrToStructure(pCurrentDomain, typeof(UnsafeNativeMethods.LSA_TRUST_INFORMATION));
                    pCurrentDomain = new IntPtr(pCurrentDomain.ToInt64() + Marshal.SizeOf(typeof(UnsafeNativeMethods.LSA_TRUST_INFORMATION)));
                }

                GlobalDebug.WriteLineIf(GlobalDebug.Info, "AuthZSet", "SidList: got {0} groups in {1} domains", sidCount, domainCount);

                //
                // Build the list of entries
                //
                Debug.Assert(names.Length == sidCount);

                for (int i = 0; i < names.Length; i++)
                {
                    UnsafeNativeMethods.LSA_TRANSLATED_NAME name = names[i];

                    // Build an entry.  Note that LSA_UNICODE_STRING.length is in bytes,
                    // while PtrToStringUni expects a length in characters.
                    SidListEntry entry = new SidListEntry();

                    Debug.Assert(name.name.length % 2 == 0);
                    entry.name = Marshal.PtrToStringUni(name.name.buffer, name.name.length / 2);

                    // Get the domain associated with this name
                    Debug.Assert(name.domainIndex < domains.Length);
                    if (name.domainIndex >= 0)
                    {
                        UnsafeNativeMethods.LSA_TRUST_INFORMATION domain = domains[name.domainIndex];
                        Debug.Assert(domain.name.length % 2 == 0);
                        entry.sidIssuerName = Marshal.PtrToStringUni(domain.name.buffer, domain.name.length / 2);
                    }

                    entry.pSid = pSids[i];

                    _entries.Add(entry);
                }

                // Sort the list so they are oriented by the issuer name.
                // this.entries.Sort( new SidListComparer());
            }
            finally
            {
                if (pDomains != IntPtr.Zero)
                {
                    UnsafeNativeMethods.LsaFreeMemory(pDomains);
                }

                if (pNames != IntPtr.Zero)
                {
                    UnsafeNativeMethods.LsaFreeMemory(pNames);
                }

                if (pPolicyHandle != IntPtr.Zero)
                {
                    UnsafeNativeMethods.LsaClose(pPolicyHandle);
                }

                if (pOA != IntPtr.Zero)
                {
                    Marshal.FreeHGlobal(pOA);
                }
            }
        }
Пример #11
0
        internal AuthZSet(
            byte[] userSid,
            NetCred credentials,
            ContextOptions contextOptions,
            string flatUserAuthority,
            StoreCtx userStoreCtx,
            object userCtxBase)
        {
            GlobalDebug.WriteLineIf(GlobalDebug.Info,
                                    "AuthZSet",
                                    "AuthZSet: SID={0}, authority={1}, storeCtx={2}",
                                    Utils.ByteArrayToString(userSid),
                                    flatUserAuthority,
                                    userStoreCtx.GetType());

            _userType       = userStoreCtx.OwningContext.ContextType;
            _userCtxBase    = userCtxBase;
            _userStoreCtx   = userStoreCtx;
            _credentials    = credentials;
            _contextOptions = contextOptions;

            // flatUserAuthority is flat domain name if userType == Domain,
            // flat host name if userType == LocalMachine
            _flatUserAuthority = flatUserAuthority;

            // Preload the PrincipalContext cache with the user's PrincipalContext
            _contexts[flatUserAuthority] = userStoreCtx.OwningContext;

            IntPtr hUser = IntPtr.Zero;

            //
            // Get the SIDs of the groups to which the user belongs
            //

            IntPtr pClientContext = IntPtr.Zero;
            IntPtr pResManager    = IntPtr.Zero;
            IntPtr pBuffer        = IntPtr.Zero;

            try
            {
                UnsafeNativeMethods.LUID luid = new UnsafeNativeMethods.LUID();
                luid.low  = 0;
                luid.high = 0;

                _psMachineSid = new SafeMemoryPtr(Utils.GetMachineDomainSid());
                _psUserSid    = new SafeMemoryPtr(Utils.ConvertByteArrayToIntPtr(userSid));

                bool f;
                int  lastError = 0;

                GlobalDebug.WriteLineIf(GlobalDebug.Info, "AuthZSet", "Initializing resource manager");

                // Create a resource manager
                f = UnsafeNativeMethods.AuthzInitializeResourceManager(
                    UnsafeNativeMethods.AUTHZ_RM_FLAG.AUTHZ_RM_FLAG_NO_AUDIT,
                    IntPtr.Zero,
                    IntPtr.Zero,
                    IntPtr.Zero,
                    null,
                    out pResManager
                    );

                if (f)
                {
                    GlobalDebug.WriteLineIf(GlobalDebug.Info, "AuthZSet", "Getting ctx from SID");

                    // Construct a context for the user based on the user's SID
                    f = UnsafeNativeMethods.AuthzInitializeContextFromSid(
                        0,                                          // default flags
                        _psUserSid.DangerousGetHandle(),
                        pResManager,
                        IntPtr.Zero,
                        luid,
                        IntPtr.Zero,
                        out pClientContext
                        );

                    if (f)
                    {
                        int bufferSize = 0;

                        GlobalDebug.WriteLineIf(GlobalDebug.Info, "AuthZSet", "Getting info from ctx");

                        // Extract the group SIDs from the user's context.  Determine the size of the buffer we need.
                        f = UnsafeNativeMethods.AuthzGetInformationFromContext(
                            pClientContext,
                            2,                                          // AuthzContextInfoGroupsSids
                            0,
                            out bufferSize,
                            IntPtr.Zero
                            );
                        if (!f && (bufferSize > 0) && (Marshal.GetLastWin32Error() == 122) /*ERROR_INSUFFICIENT_BUFFER*/)
                        {
                            GlobalDebug.WriteLineIf(GlobalDebug.Info, "AuthZSet", "Getting info from ctx (size={0})", bufferSize);

                            Debug.Assert(bufferSize > 0);

                            // Set up the needed buffer
                            pBuffer = Marshal.AllocHGlobal(bufferSize);

                            // Extract the group SIDs from the user's context, into our buffer.0
                            f = UnsafeNativeMethods.AuthzGetInformationFromContext(
                                pClientContext,
                                2,                                              // AuthzContextInfoGroupsSids
                                bufferSize,
                                out bufferSize,
                                pBuffer
                                );

                            if (f)
                            {
                                // Marshall the native buffer into managed SID_AND_ATTR structures.
                                // The native buffer holds a TOKEN_GROUPS structure:
                                //
                                //        struct TOKEN_GROUPS {
                                //                DWORD GroupCount;
                                //                SID_AND_ATTRIBUTES Groups[ANYSIZE_ARRAY];
                                //        };
                                //

                                // Extract TOKEN_GROUPS.GroupCount

                                UnsafeNativeMethods.TOKEN_GROUPS tokenGroups = (UnsafeNativeMethods.TOKEN_GROUPS)Marshal.PtrToStructure(pBuffer, typeof(UnsafeNativeMethods.TOKEN_GROUPS));

                                int groupCount = tokenGroups.groupCount;

                                GlobalDebug.WriteLineIf(GlobalDebug.Info, "AuthZSet", "Found {0} groups", groupCount);

                                // Extract TOKEN_GROUPS.Groups, by iterating over the array and marshalling
                                // each native SID_AND_ATTRIBUTES into a managed SID_AND_ATTR.
                                UnsafeNativeMethods.SID_AND_ATTR[] groups = new UnsafeNativeMethods.SID_AND_ATTR[groupCount];

                                IntPtr currentItem = new IntPtr(pBuffer.ToInt64() + Marshal.SizeOf(typeof(UnsafeNativeMethods.TOKEN_GROUPS)) - IntPtr.Size);

                                for (int i = 0; i < groupCount; i++)
                                {
                                    groups[i] = (UnsafeNativeMethods.SID_AND_ATTR)Marshal.PtrToStructure(currentItem, typeof(UnsafeNativeMethods.SID_AND_ATTR));

                                    currentItem = new IntPtr(currentItem.ToInt64() + Marshal.SizeOf(typeof(UnsafeNativeMethods.SID_AND_ATTR)));
                                }

                                _groupSidList = new SidList(groups);
                            }
                            else
                            {
                                lastError = Marshal.GetLastWin32Error();
                            }
                        }
                        else
                        {
                            lastError = Marshal.GetLastWin32Error();
                            // With a zero-length buffer, this should have never succeeded
                            Debug.Assert(false);
                        }
                    }
                    else
                    {
                        lastError = Marshal.GetLastWin32Error();
                    }
                }
                else
                {
                    lastError = Marshal.GetLastWin32Error();
                }

                if (!f)
                {
                    GlobalDebug.WriteLineIf(GlobalDebug.Warn, "AuthZSet", "Failed to retrieve group list, {0}", lastError);

                    throw new PrincipalOperationException(
                              String.Format(
                                  CultureInfo.CurrentCulture,
                                  SR.AuthZFailedToRetrieveGroupList,
                                  lastError));
                }

                // Save off the buffer since it still holds the native SIDs referenced by SidList
                _psBuffer = new SafeMemoryPtr(pBuffer);
                pBuffer   = IntPtr.Zero;
            }
            catch (Exception e)
            {
                GlobalDebug.WriteLineIf(GlobalDebug.Error, "AuthZSet", "Caught exception {0} with message {1}", e.GetType(), e.Message);

                if (_psBuffer != null && !_psBuffer.IsInvalid)
                {
                    _psBuffer.Close();
                }

                if (_psUserSid != null && !_psUserSid.IsInvalid)
                {
                    _psUserSid.Close();
                }

                if (_psMachineSid != null && !_psMachineSid.IsInvalid)
                {
                    _psMachineSid.Close();
                }

                // We're on a platform that doesn't have the AuthZ library
                if (e is DllNotFoundException)
                {
                    throw new NotSupportedException(SR.AuthZNotSupported, e);
                }

                if (e is EntryPointNotFoundException)
                {
                    throw new NotSupportedException(SR.AuthZNotSupported, e);
                }

                throw;
            }
            finally
            {
                if (pClientContext != IntPtr.Zero)
                {
                    UnsafeNativeMethods.AuthzFreeContext(pClientContext);
                }

                if (pResManager != IntPtr.Zero)
                {
                    UnsafeNativeMethods.AuthzFreeResourceManager(pResManager);
                }

                if (pBuffer != IntPtr.Zero)
                {
                    Marshal.FreeHGlobal(pBuffer);
                }
            }
        }