예제 #1
0
        bool SetKeyPermissions(IntPtr hKey, ACCOUNT_PERM Account)
        {
            // apply key permissions
            int iLength = 0;
            int iReturn = 0;
            IntPtr pOldSD = IntPtr.Zero;
            IntPtr pSec = IntPtr.Zero;
            MEM_DATA tMem = new MEM_DATA();

            try
            {
                tMem.pAcl = IntPtr.Zero;
                tMem.pSd = IntPtr.Zero;

                // allocate space
                iReturn = RegGetKeySecurity(hKey, DACL_SECURITY_INFORMATION, pOldSD, ref iLength);
                if (iLength > 0)
                {
                    pOldSD = (LocalAlloc(LMEM_INITIALIZED, iLength));
                    if (pOldSD != IntPtr.Zero)
                    {
                        // load structure
                        if ((RegGetKeySecurity(hKey, DACL_SECURITY_INFORMATION, pOldSD, ref iLength) == 0))
                        {
                            // create dacl
                            if (CreateKeyDescriptor(pOldSD, Account, ref tMem))
                            {
                                // set descriptor
                                return (RegSetKeySecurity(hKey, DACL_SECURITY_INFORMATION, tMem.pSd) == ERROR_SUCCESS);
                            }
                        }
                    }
                }
                return false;
            }

            finally
            {
                // cleanup
                if (pOldSD != IntPtr.Zero)
                {
                    LocalFree(pOldSD);
                    pOldSD = IntPtr.Zero;
                }
                if (tMem.pSd != IntPtr.Zero)
                {
                    LocalFree(tMem.pSd);
                    tMem.pSd = IntPtr.Zero;
                }
                if (tMem.pAcl != IntPtr.Zero)
                {
                    LocalFree(tMem.pAcl);
                    tMem.pAcl = IntPtr.Zero;
                }
            }
        }
예제 #2
0
        bool CreateKeyDescriptor(IntPtr pOldSD, ACCOUNT_PERM Account, ref MEM_DATA MemData)
        {
            // reconstruct security descriptor
            bool bDefault = false;
            bool bPresent = false;
            int iControlBits = 0;
            int iControlSet = 0;
            int iDomain = 0;
            int iFlag = 0;
            int iLength = 0;
            int iRevision = 0;
            int iSidLen = 0;
            int iTotal = 0;
            int iUse = 0;
            StringBuilder sDomain = new StringBuilder(256);
            IntPtr pNewACL = IntPtr.Zero;
            IntPtr pAcl = IntPtr.Zero;
            IntPtr pSid = IntPtr.Zero;
            IntPtr pPnt = IntPtr.Zero;
            ACL_SIZE_INFORMATION tAclSize = new ACL_SIZE_INFORMATION();
            ACL tTempACL = new ACL();
            ACE tTempAce = new ACE();

            try
            {
                MemData.pAcl = IntPtr.Zero;
                MemData.pSd = IntPtr.Zero;
                // get size
                pSid = LocalAlloc(LMEM_INITIALIZED, SECURITY_DESCRIPTOR_MIN_LENGTH);
                if (pSid == IntPtr.Zero)
                {
                    return false;
                }
                // store pointer
                MemData.pSd = pSid;

                // init descriptor
                if (InitializeSecurityDescriptor(pSid, SECURITY_DESCRIPTOR_REVISION) == 0)
                {
                    return false;
                }

                // check for existing sd
                if (pOldSD != IntPtr.Zero)
                {
                    if (GetSecurityDescriptorDacl(pOldSD, out bPresent, ref pAcl, out bDefault) == true)
                    {
                        // extract dacl
                        if ((bPresent == true) && (pAcl != IntPtr.Zero))
                        {
                            if (GetAclInformation(pAcl, ref tAclSize, Marshal.SizeOf(tAclSize), ACL_INFORMATION_CLASS.AclSizeInformation) == false)
                            {
                                return false;
                            }
                            else
                            {
                                iTotal = tAclSize.AclBytesInUse;
                            }
                        }
                        else
                        {
                            iTotal = Marshal.SizeOf(tTempACL);
                        }
                    }
                    else
                    {
                        return false;
                    }
                }

                // allocate sid //
                // get callers sid
                if (Account.pSid == IntPtr.Zero)
                {
                    iDomain = 256;
                    // get size
                    LookupAccountName(null, Account.AccountName, IntPtr.Zero, ref iSidLen, sDomain, ref iDomain, out iUse);
                    Account.pSid = LocalAlloc(LMEM_INITIALIZED, iSidLen);
                    if (Account.pSid == IntPtr.Zero)
                    {
                        return false;
                    }
                    // get the sid
                    if (LookupAccountName(null, Account.AccountName, Account.pSid, ref iSidLen, sDomain, ref iDomain, out iUse) == false)
                    {
                        return false;
                    }
                }

                // ace buffer
                iLength = (Marshal.SizeOf(tTempAce) + GetLengthSid(Account.pSid)) - 4;
                iTotal += iLength;
                pNewACL = LocalAlloc(LMEM_INITIALIZED, iTotal);
                if (pNewACL == IntPtr.Zero)
                {
                    return false;
                }
                // store pointer
                MemData.pAcl = pNewACL;

                // init acl
                if (InitializeAcl(pNewACL, iTotal, ACL_REVISION) == false)
                {
                    return false;
                }

                // build dacl in sequence
                if (Account.AceType == ACCESS_DENIED_ACE_TYPE)
                {
                    if (BuildACE(pNewACL, Account.AceType, Account.AceFlags, Account.AccessMask, Account.pSid) == false)
                    {
                        return false;
                    }
                }

                // copy non-inherited ace
                if ((bPresent == true) && (pAcl != IntPtr.Zero) && (tAclSize.AceCount > 0))
                {
                    // combine old and new ACE entries
                    for (int count = 0; count < tAclSize.AceCount; count++)
                    {
                        // next ace
                        GetAce(pAcl, count, out pPnt);
                        if (pPnt == IntPtr.Zero)
                        {
                            return false;
                        }
                        RtlMoveMemory(ref tTempAce, pPnt, Marshal.SizeOf(tTempAce));
                        // exit on inherited ace
                        if (((int)tTempAce.Header.AceFlags & INHERITED_ACE) == INHERITED_ACE)
                        {
                            break;
                        }
                        int x = (int)pPnt + 8;
                        IntPtr pPt = new IntPtr(x);
                        // check ace value
                        if (!SidIsEqual(Account.pSid, pPt))
                        {
                            // add ace
                            AddAce(pNewACL, ACL_REVISION, MAXDWORD, pPnt, tTempAce.Header.AceSize);
                        }
                    }
                }

                // add explicit permit
                if (Account.AceType == ACCESS_ALLOWED_ACE_TYPE)
                {
                    BuildACE(pNewACL, Account.AceType, Account.AceFlags, Account.AccessMask, Account.pSid);
                }

                // enties with inheritence flag
                if ((bPresent == true) && (pAcl != IntPtr.Zero) && (tAclSize.AceCount > 0))
                {
                    for (int count = 0; count < tAclSize.AceCount; count++)
                    {
                        GetAce(pAcl, count, out pPnt);
                        RtlMoveMemory(ref tTempAce, pPnt, Marshal.SizeOf(tTempAce));
                        AddAce(pNewACL, ACL_REVISION, MAXDWORD, pPnt, tTempAce.Header.AceSize);
                    }
                }

                // descriptor flags
                if (pOldSD != IntPtr.Zero)
                {
                    if (GetSecurityDescriptorControl(pOldSD, out iFlag, out iRevision) != 0)
                    {
                        if ((iFlag & SE_DACL_AUTO_INHERITED) == SE_DACL_AUTO_INHERITED)
                        {
                            iControlBits = SE_DACL_AUTO_INHERIT_REQ | SE_DACL_AUTO_INHERITED;
                            iControlSet = iControlBits;
                        }
                        else if ((iFlag & SE_DACL_PROTECTED) == SE_DACL_PROTECTED)
                        {
                            iControlBits = SE_DACL_PROTECTED;
                            iControlSet = iControlBits;
                        }
                        if (iControlSet != 0)
                        {
                            SetSecurityDescriptorControl(pSid, iControlBits, iControlSet);
                        }
                    }
                }
                // add dacl
                return SetSecurityDescriptorDacl(pSid, 1, pNewACL, 0);
            }

            finally
            {
                if (Account.pSid != IntPtr.Zero)
                {
                    LocalFree(Account.pSid);
                    Account.pSid = IntPtr.Zero;
                }
            }
        }