示例#1
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();
                            Debug.Fail("With a zero-length buffer, this should have never succeeded");
                        }
                    }
                    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(
                              SR.Format(
                                  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);
                }
            }
        }
示例#2
0
        internal AuthZSet(byte[] userSid, NetCred credentials, ContextOptions contextOptions, string flatUserAuthority, StoreCtx userStoreCtx, object userCtxBase)
        {
            this.currentGroup                = -1;
            this.contexts                    = new Hashtable();
            this.localMachineIsDC            = null;
            this.userType                    = userStoreCtx.OwningContext.ContextType;
            this.userCtxBase                 = userCtxBase;
            this.userStoreCtx                = userStoreCtx;
            this.credentials                 = credentials;
            this.contextOptions              = contextOptions;
            this.flatUserAuthority           = flatUserAuthority;
            this.contexts[flatUserAuthority] = userStoreCtx.OwningContext;
            IntPtr zero   = IntPtr.Zero;
            IntPtr intPtr = IntPtr.Zero;
            IntPtr zero1  = IntPtr.Zero;

            try
            {
                try
                {
                    UnsafeNativeMethods.LUID lUID = new UnsafeNativeMethods.LUID();
                    lUID.low          = 0;
                    lUID.high         = 0;
                    this.psMachineSid = new AuthZSet.SafeMemoryPtr(Utils.GetMachineDomainSid());
                    this.psUserSid    = new AuthZSet.SafeMemoryPtr(Utils.ConvertByteArrayToIntPtr(userSid));
                    int  lastWin32Error = 0;
                    bool flag           = UnsafeNativeMethods.AuthzInitializeResourceManager(UnsafeNativeMethods.AUTHZ_RM_FLAG.AUTHZ_RM_FLAG_NO_AUDIT, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, null, out intPtr);
                    if (!flag)
                    {
                        lastWin32Error = Marshal.GetLastWin32Error();
                    }
                    else
                    {
                        flag = UnsafeNativeMethods.AuthzInitializeContextFromSid(0, this.psUserSid.DangerousGetHandle(), intPtr, IntPtr.Zero, lUID, IntPtr.Zero, out zero);
                        if (!flag)
                        {
                            lastWin32Error = Marshal.GetLastWin32Error();
                        }
                        else
                        {
                            int num = 0;
                            flag = UnsafeNativeMethods.AuthzGetInformationFromContext(zero, 2, 0, out num, IntPtr.Zero);
                            if (flag || num <= 0 || Marshal.GetLastWin32Error() != 122)
                            {
                                lastWin32Error = Marshal.GetLastWin32Error();
                            }
                            else
                            {
                                zero1 = Marshal.AllocHGlobal(num);
                                flag  = UnsafeNativeMethods.AuthzGetInformationFromContext(zero, 2, num, out num, zero1);
                                if (!flag)
                                {
                                    lastWin32Error = Marshal.GetLastWin32Error();
                                }
                                else
                                {
                                    UnsafeNativeMethods.TOKEN_GROUPS structure = (UnsafeNativeMethods.TOKEN_GROUPS)Marshal.PtrToStructure(zero1, typeof(UnsafeNativeMethods.TOKEN_GROUPS));
                                    int num1 = structure.groupCount;
                                    UnsafeNativeMethods.SID_AND_ATTR[] sIDANDATTRArray = new UnsafeNativeMethods.SID_AND_ATTR[num1];
                                    IntPtr intPtr1 = new IntPtr(zero1.ToInt64() + (long)Marshal.SizeOf(typeof(UnsafeNativeMethods.TOKEN_GROUPS)) - (long)Marshal.SizeOf(typeof(IntPtr)));
                                    for (int i = 0; i < num1; i++)
                                    {
                                        sIDANDATTRArray[i] = (UnsafeNativeMethods.SID_AND_ATTR)Marshal.PtrToStructure(intPtr1, typeof(UnsafeNativeMethods.SID_AND_ATTR));
                                        intPtr1            = new IntPtr(intPtr1.ToInt64() + (long)Marshal.SizeOf(typeof(UnsafeNativeMethods.SID_AND_ATTR)));
                                    }
                                    this.groupSidList = new SidList(sIDANDATTRArray);
                                }
                            }
                        }
                    }
                    if (flag)
                    {
                        this.psBuffer = new AuthZSet.SafeMemoryPtr(zero1);
                        zero1         = IntPtr.Zero;
                    }
                    else
                    {
                        object[] objArray = new object[1];
                        objArray[0] = lastWin32Error;
                        throw new PrincipalOperationException(string.Format(CultureInfo.CurrentCulture, StringResources.AuthZFailedToRetrieveGroupList, objArray));
                    }
                }
                catch (Exception exception1)
                {
                    Exception exception = exception1;
                    if (this.psBuffer != null && !this.psBuffer.IsInvalid)
                    {
                        this.psBuffer.Close();
                    }
                    if (this.psUserSid != null && !this.psUserSid.IsInvalid)
                    {
                        this.psUserSid.Close();
                    }
                    if (this.psMachineSid != null && !this.psMachineSid.IsInvalid)
                    {
                        this.psMachineSid.Close();
                    }
                    if (exception as DllNotFoundException == null)
                    {
                        if (exception as EntryPointNotFoundException == null)
                        {
                            throw;
                        }
                        else
                        {
                            throw new NotSupportedException(StringResources.AuthZNotSupported, exception);
                        }
                    }
                    else
                    {
                        throw new NotSupportedException(StringResources.AuthZNotSupported, exception);
                    }
                }
            }
            finally
            {
                if (zero != IntPtr.Zero)
                {
                    UnsafeNativeMethods.AuthzFreeContext(zero);
                }
                if (intPtr != IntPtr.Zero)
                {
                    UnsafeNativeMethods.AuthzFreeResourceManager(intPtr);
                }
                if (zero1 != IntPtr.Zero)
                {
                    Marshal.FreeHGlobal(zero1);
                }
            }
        }