Link to home
Start Free TrialLog in
Avatar of GPaterson
GPaterson

asked on

Registry Permissions C++

I am trying to create a program which takes ownership of a registry key (and subkeys), adds the current user to the permissions list and then deletes the key and all subkeys.

I can succesfully take ownership of the key and I can change the permissions on it. However all subkeys are unaffected and I cant seem to find a way to make it propogate these changes to all the subkeys.

I would like to do this if possible without having to enumerate all the subkeys and repeat the process. Is there any fast way that I am missing?

I need to know this for both 1. Taking Ownership and 2. Setting DACL's

Below is the code I am using... (I know some of it is doubled up, I will fix all that stuff once it all works)



void PStoresFix::TakeOwnership()
{
      DWORD dwResult = 0, cbtiSize = 0;
      PTOKEN_USER ptiUser = NULL;
      SECURITY_DESCRIPTOR sd;
      HANDLE hToken;
      HKEY hKey = NULL;
      
      if (!OpenProcessToken(GetCurrentProcess(),
            TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken))
            return;

      GetTokenInformation (hToken, TokenUser, NULL, 0, &cbtiSize);

      // Allocate buffer for user information in the token.
      ptiUser = (PTOKEN_USER) HeapAlloc(GetProcessHeap(), 0, cbtiSize);

      // Retrieve the user information from the token.
      GetTokenInformation(hToken, TokenUser, ptiUser, cbtiSize, &cbtiSize);

      if (!SetPrivilege(hToken, SE_TAKE_OWNERSHIP_NAME, TRUE))
      {
            std::cout<<"Could not set SE_TAKE_OWNERSHIP_NAME"<<std::endl;
            return;
      }

      if (!SetPrivilege(hToken, SE_RESTORE_NAME, TRUE))
      {
            std::cout<<"Could not set SE_RESTORE_NAME"<<std::endl;
      }

      if(!InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION))
      {
            std::cout<<"Error initializing SD"<<std::endl;
      }

      if(!SetSecurityDescriptorOwner(&sd, ptiUser->User.Sid, FALSE))
      {
            std::cout<<"Error setting SD owner"<<std::endl;
      }

      // Open registry with WRITE_OWNER priveledge.
      dwResult = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
                                       "SOFTWARE\\Microsoft\\Protected Storage System Provider",
                                       0,
                                       WRITE_OWNER,
                                       &hKey);
      if(dwResult != ERROR_SUCCESS)
      {
            std::cout<<"Error opening key: "<<dwResult<<std::endl;
      }

    // Set the owner in the object's security descriptor.
      dwResult = RegSetKeySecurity(hKey, OWNER_SECURITY_INFORMATION, &sd);
    if (dwResult != ERROR_SUCCESS)
    {
            std::cout<<"Could not set owner 1. Error: "<<dwResult<<std::endl;
        //return;
    }

      // This propogates changes to all children objects
      dwResult = SetNamedSecurityInfo("MACHINE\\SOFTWARE\\Microsoft\\Protected Storage System Provider",
            SE_REGISTRY_KEY, OWNER_SECURITY_INFORMATION,ptiUser->User.Sid, NULL, NULL, NULL);
      if (dwResult != ERROR_SUCCESS)
      {
            // Errorcheck
            std::cout<<"Error setting named security info: "<<dwResult<<std::endl;
      }

      // Disable the SE_TAKE_OWNERSHIP_NAME privilege.
      if (!SetPrivilege(hToken, SE_TAKE_OWNERSHIP_NAME, FALSE))
      {
            //printf("Failed SetPrivilege call unexpectedly.\n");
            return;
      }

      // Disable the SE_TAKE_OWNERSHIP_NAME privilege.
      if (!SetPrivilege(hToken, SE_RESTORE_NAME, FALSE))
      {
            //printf("Failed SetPrivilege call unexpectedly.\n");
            return;
      }

      // Close registry.
      dwResult = RegCloseKey(hKey);
}


void PStoresFix::GrantAccess()
{
      DWORD dwResult = 0, dwAclSize = 0, cbtiSize = 0;
      HKEY hKey = NULL;
      HANDLE hToken;
      PTOKEN_USER ptiUser = NULL;
      PACL pDACL = NULL;
      SECURITY_DESCRIPTOR sd;
      
      // Open registry with WRITE_DAC priveledge.
      dwResult = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
                                       "SOFTWARE\\Microsoft\\Protected Storage System Provider",
                                       0,
                                       WRITE_DAC,
                                       &hKey);
      if(dwResult != ERROR_SUCCESS)
      {
            std::cout<<"Error opening key: "<<dwResult<<std::endl;
      }
      
      if (!OpenProcessToken(GetCurrentProcess(),
            TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken))
      {
            std::cout<<"Error opening process token."<<std::endl;
            return;
      }

      GetTokenInformation (hToken, TokenUser, NULL, 0, &cbtiSize);

      // Allocate buffer for user information in the token.
      ptiUser = (PTOKEN_USER) HeapAlloc(GetProcessHeap(), 0, cbtiSize);

      // Retrieve the user information from the token.
      GetTokenInformation(hToken, TokenUser, ptiUser, cbtiSize, &cbtiSize);

      dwAclSize = sizeof(ACL) + sizeof(ACCESS_ALLOWED_ACE) - sizeof(DWORD) +
            GetLengthSid(ptiUser->User.Sid);

      pDACL = (PACL)HeapAlloc(GetProcessHeap(), 0, dwAclSize);
      if(pDACL==NULL)
      {
            std::cout<<"Error allocating mem for ACL"<<std::endl;
      }

      if(!InitializeAcl(pDACL, dwAclSize, ACL_REVISION))
      {
            std::cout<<"Error initializing ACL"<<std::endl;
      }

      if(!AddAccessAllowedAce(pDACL, ACL_REVISION, KEY_ALL_ACCESS, ptiUser->User.Sid))
      {
            std::cout<<"Error adding ACE"<<std::endl;
      }

      if(!InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION))
      {
            std::cout<<"Error initializing SD"<<std::endl;
      }

      if(!SetSecurityDescriptorDacl(&sd, TRUE, pDACL, FALSE))
      {
            std::cout<<"Error setting SD DACL"<<std::endl;
      }

      dwResult = RegSetKeySecurity(hKey, DACL_SECURITY_INFORMATION, &sd);
    if (dwResult != ERROR_SUCCESS)
    {
            std::cout<<"Could not set add permissions Error: "<<dwResult<<std::endl;
        //return;
    }

      dwResult = SetNamedSecurityInfo("MACHINE\\SOFTWARE\\Microsoft\\Protected Storage System Provider",
            SE_REGISTRY_KEY, DACL_SECURITY_INFORMATION, NULL, NULL, pDACL, NULL);
      if (dwResult != ERROR_SUCCESS)
      {
            // Errorcheck
            std::cout<<"Error setting named security info."<<std::endl;
      }

      if(pDACL != NULL)
       HeapFree(GetProcessHeap(), 0, pDACL);

      RegCloseKey(hKey);
}
ASKER CERTIFIED SOLUTION
Avatar of jkr
jkr
Flag of Germany image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of GPaterson
GPaterson

ASKER

Does that apply to both setting permissions and also taking ownership?

I sort of guessed maybe it was so when taking ownership, however, in setting permissions I thought maybe different
as in regedt32 you can take ownership of the parent and reset permissions on all child folders without actually taking ownership of all the child folders.
regedt32 pretty much does the same when you select that option. Had to do something similar a few yeary ago and had to make it work recursively, too...
Does that apply to both setting permissions and also taking ownership?

I sort of guessed maybe it was so when taking ownership, however, in setting permissions I thought maybe different
as in regedt32 you can take ownership of the parent and reset permissions on all child folders without actually taking ownership of all the child folders.
>>Does that apply to both setting permissions and also taking ownership?

To both - there is only one API ( 'RegSetKeySecurity()'), and there's no way to tell that API todo either operation recursively.
Strange my last comment went up twice at two different times. Oh well, back to drawing board.