locked
Protected Registry key access under Vista. RRS feed

  • Question

  • I have code which works on 2k and XP, which, when run under an administrators
    account, changes the permissions on a hardware/enum key in the registry so
    that we can make changes to a value for our device. Normally the local
    administrator does not have this access but creating a new DACL for the
    account, then opening the key with WRITE_DAC access and setting the new access
    allows opening the final key with write permissions.

    This has stopped working in Vista. Everything about the procedure including
    AllocateAndInitializeSid, InitializeAcl, AddAccessAllowedAce,
    InitializeSecurityDescriptor, SetSecurityDescriptorDacl goes off without a
    hitch just like under 2k and XP but then RegOpenKeyEx with WRITE_DAC access
    fails with Error 5 (Acess Denied) exactly as if nothing above had done
    anything at all.

    Anyone know what might have changed in Vista administrator ACLS or the
    registry permissions themselves that might have caused this? The registry
    permissions for the key look the same in Vista as XP as far as I can tell.

    Code:

        //
        // Create a security descriptor that has full permissions to the administrators group
        //

        SID_IDENTIFIER_AUTHORITY sia = SECURITY_NT_AUTHORITY;
        PSID pAdministratorsSid = NULL;
        SECURITY_DESCRIPTOR sd;
        PACL pDacl = NULL;
        DWORD dwAclSize;

        // Preprare a Sid representing the well-known admin group
        if(!AllocateAndInitializeSid(
            &sia,
            2,
            SECURITY_BUILTIN_DOMAIN_RID,
            DOMAIN_ALIAS_RID_ADMINS,
            0, 0, 0, 0, 0, 0,
            &pAdministratorsSid
          ))
        {
            PrintError("AllocateAndInitializeSid (Admins) failed:", GetLastError());
            goto final_cleanup;
        }

        // Compute size of new acl
        dwAclSize = sizeof(ACL) +
                    1 * ( sizeof(ACCESS_ALLOWED_ACE) - sizeof(DWORD) ) +
                    GetLengthSid(pAdministratorsSid);

        // Allocate storage for Acl
        pDacl = (PACL)HeapAlloc(GetProcessHeap(), 0, dwAclSize);
        if(pDacl == NULL) goto final_cleanup;

        if(!InitializeAcl(pDacl, dwAclSize, ACL_REVISION))
        {
            PrintError("InitializeAcl failed: ", GetLastError());
            goto final_cleanup;
        }

        // Grant the Administrators Sid KEY_ALL_ACCESS access to the perf key
        if(!AddAccessAllowedAce(
            pDacl,
            ACL_REVISION,
            KEY_ALL_ACCESS,
            pAdministratorsSid
            ))
        {
            PrintError("AddAccessAllowedAce (Admins) failed: ", GetLastError());
            goto final_cleanup;
        }

        // Initialize and set the security descriptor and DACL
        if(!InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION))
        {
            PrintError("InitializeSecurityDescriptor", GetLastError());
            goto final_cleanup;
        }
        if(!SetSecurityDescriptorDacl(&sd, TRUE, pDacl, FALSE))
        {
            PrintError("SetSecurityDescriptorDacl", GetLastError());
            goto final_cleanup;
        }

        //
        // Now we can open the registry to the Enum/HID/<MSR VID/PID> key and enumerate installed MSRs
        //
       
        // Open the registry to the Enum\HID\Vid_04b4&Pid_210 key
        HKEY hKey, hDeviceKey;
        DWORD dwErr;
        if ((dwErr = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
                                  g_szKeyboardDeviceSearchPath,
                                  0,
                                  KEY_ENUMERATE_SUB_KEYS,
                                  &hKey)) != ERROR_SUCCESS)
        {
            PrintError(_T("Failed to open the Enum/HID registry key for enumeration: "), dwErr);
            goto final_cleanup;
        }

        // Enum all the keys under the Vid_04b4&Pid_210 key
        TCHAR szKey[256];
        int nIdx = 0;
        unsigned char *pSDOld = 0;
        while (RegEnumKey(hKey, nIdx, szKey, 256) == ERROR_SUCCESS)
        {
            TCHAR szDeviceKey[MAX_PATH];
            _tcscpy(szDeviceKey, g_szKeyboardDeviceSearchPath);
            _tcscat(szDeviceKey, _T("\\"));
            _tcscat(szDeviceKey, szKey);

            hDeviceKey = 0;

            // Open the enumed key for WRITE_DAC and READ_CONTROL access
            if ((dwErr = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
                                      szDeviceKey,
                                      0,
                                      WRITE_DAC | READ_CONTROL,
                                      &hDeviceKey)) != ERROR_SUCCESS)
            {
                PrintError("Failed to open the device key for WRITE_DAC access: ", dwErr);
                goto cleanup;
            }

    [SNIP]

    The call to RegOpenKeyEx with WRITE_DAC access fails with error 5 Access Denied on Vista
    when run from a local administrators account but not 2k or XP.

    Tuesday, September 12, 2006 5:39 PM

All replies

  • Well I see the /basic./ problem. On 2k/xp the local administrator has the right to alter the permission of the registry keys in question from regedit (as well as by using the above code). On Vista the same operation in regedit itself returns an Access Denied error.

    So the default permissions HAVE changed on certain registry keys and/or the local admins ACL. It seems that write permission or the ability to change access at all is now only allowed by the SYSTEM account. Would I also be right in thinking that there is no way that a program run under an administrator account possibly impersonate a SYSTEM user?

    Has the ability to add data to this key now just been made compeltely impossible via code or account access?

    Specifically: HKLM\System\CurrentControlSet\Enum\HID\Vid_XXXX&Pid_XXXX (Our product key)

    Wednesday, September 13, 2006 10:26 PM
  • I offer no solutions, but would like to relate the following unusual scenario that I find myself in...  My app saves user preferences in the registry - preferences are stored together in a collection we call a profile.  We provide a user interface that allows our users to select from among a list of profiles.  We also give the users a way to manage their profiles - create new profiles, delete profiles, rename profiles, etc.  User actions taken within the Manage Profiles dialog can have the effect of modifying the registry.  But the user might choose Cancel on the Manage Profiles dialog, at which point we want to undo any changes that have been made to the registry.  To accomplish this, when the Manage Profiles dialog is first displayed, we export the portion of the registry that could possibly be affected to a temporary .reg file, spawning RegEdit in a background process!  If the user chooses Cancel, we import the saved .reg file (also via a spawned RegEdit), thus restoring the registry.

    Here's the problem:  Vista complains when you try to spawn RegEdit from within your (my) application.  In fact, Vista complains (UAC warnings) when I run RegEdit via the Start menu.  Ironically, I get no warnings when I make direct API calls to modify the registry.  I would like to spare my users from unnecessary annoying UAC warnings. Therefore, I guess I will have to write some code to do the work that RegEdit was doing for me.  Which do you suppose is the greater security risk -- having RegEdit import a file into the registry, or having a programmer like me (potentially) write some buggy code that inadvertently screws up the user's registry?  It seems to me that programmers like me are the greater risk, yet the irony is that my buggy code will not generate a UAC warning, but RegEdit will.  Thanks Microsoft.

    Thursday, February 1, 2007 5:31 PM
  • if you have exe application - try to add manifest file with
    <trustInfo xmlns="urn:schemas-microsoft-com:asm.v2">
        <security>
            <requestedPrivileges>
                <requestedExecutionLevel level="requireAdministrator" uiAccess="false"/>
            </requestedPrivileges>
        </security>
    </trustInfo>

    you can find more info in the web from this start point.
    Friday, February 2, 2007 1:35 PM
  • Is there a solution if it's a managed .Net dll?

     

    I've searched and I can't find any...

     

    Bob

     

    Friday, March 16, 2007 7:23 AM