• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 1795
  • Last Modified:

Access registry HKEY_CURRENT_USER subkey from NT Service


Hi,

System : Win NT Server 4.0 or Windows 2000 Adanced Server.

Server is logged in with NT account (say AAA) and
some values are stored in Registry under HKEY_CURRENT_USER branch.

An application reads from the above subkey and works fine.

The application is converted to NT service (service startup is automatic) and made to run with same NT account AAA.

Now, when the server is logged on with NT account AAA and if the service is started, it reads values from registry and works fine.

However, when the server is restarted and NOT logged-on with any nt user account, and when the service starts automatically, it is NOT able to read the registry values.

I understand that registry values under HKEY_CURRENT_USER created with one NT account (say AAA)is available only if server is logged on with same NT account (AAA).
Also, if some other NT account (say BBB) log-on to the server,the HKEY_CURRENT_USER branch created by NT account AAA is not available to applications.

But, I've provided same NT account (AAA) for service to log-on, still if the server restart, the service could not read from HKEY_CURRENT_USER branch.


In UserManager, I added "act as part of operating system" and "log on as batch job" and "log on as service" previleges to the NT account AAA.

Still, registry reading fails on re-start.

Q1. Is there a way to access HKEY_CURRENT_USER branch when the server is not logged on with NT account AAA.

Q2. Can I move the registry content to HKEY_LOCAL_MACHINE branch and restrict the access only to the NT account AAA ?.

Experts, please help.




0
sindbad
Asked:
sindbad
  • 6
  • 2
  • 2
1 Solution
 
jkrCommented:
>>Q1. Is there a way to access HKEY_CURRENT_USER branch when the server is not logged on with NT account AAA.

Yes, the problem is that you have to load the user profile manually from the service.

>>Q2. Can I move the registry content to HKEY_LOCAL_MACHINE branch and restrict the access only to the NT account AAA ?.

Yes, that would even be the logically correct way.
0
 
TrailBlazerCommented:
Hi !
You are trying the right way, but still you will have to clerify what you want to do ??
See, if you want services to start without the AAA or BBB logging on to the server, try some account with full control and admin rights i.e. like XYZ and replace AAA dependancy for services to XYZ. The service will start when the O/S load itself.

If you want to solve the second question, you already solved it. If AAA is not logging on and the services are not getting started then it is the answer to your second question. What do you think ???

Give me updates or queries.
0
 
TrailBlazerCommented:
Hi !
It's me again. Even if you donot want to create a user account for services you can specify it as a system account to get it started in the services specifications itself.
Try It.
0
What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

 
jkrCommented:
>>you can specify it as a system account

This account does not have an entry under HKEY_USERS. Why should it? You cannot log on interactively anyway.
0
 
sindbadAuthor Commented:

Hi jkr and TrailBlazer,

Thanks for your responses.

Trailblazer :

All applications (simple exes, NT services or NT scheduled tasks)using this registry info (created with NT account AAA) should always be run under NT account AAA. This is a requirement due to security reasons.

For client applications using the regsitry, users anyway log-in to the desktop, so accessing registry (HKEY_CURRENT_USER branch) is not an issue.

However, all server applications are NT services and run with NT account AAA. For security and adminstration purposes, NT admins do not leave production servers, logged-in. And, during periodic maintenance window, they shutdown and bring back the server, but they don't log-in to the server. This is where the problem is.

Well, for the solution, I'll be trying the solution in coming weeks (need to look for a Win reg API that restricts access to certain NT accounts) and let you know the results and award the points accordingly.

Thanks.
0
 
jkrCommented:
>>need to look for a Win reg API that restricts access to certain NT accounts

'RegGetKeySecurity()'/'RegSetKeySecurity()' is what you are looking for, e.g.

DWORD AddToRegKeySD ( PSECURITY_DESCRIPTOR pRelSD, PSID pGroupSID,
               DWORD dwAccessMask,      HKEY      hSecurityRegKey)
{
 PSECURITY_DESCRIPTOR pAbsSD = NULL;

 PACL  pDACL;

 DWORD  dwSDLength = 0;
 DWORD  dwSDRevision;
 DWORD  dwDACLLength = 0;

 SECURITY_DESCRIPTOR_CONTROL sdcSDControl;

 PACL  pNewDACL  = NULL;
 DWORD  dwAddDACLLength = 0;

 BOOL  fAceFound = 0;

 BOOL  fHasDACL  = FALSE;
 BOOL  fDACLDefaulted = FALSE;

 ACCESS_ALLOWED_ACE  *pDACLAce;

 DWORD  dwError = 0;

 DWORD  i;

 // get SD control bits
 if ( ! GetSecurityDescriptorControl ( pRelSD,
        ( PSECURITY_DESCRIPTOR_CONTROL) &sdcSDControl,
             ( LPDWORD) &dwSDRevision) )
  return ( GetLastError() );

 // check if DACL is present
 if ( SE_DACL_PRESENT & sdcSDControl)
 {
  // get dacl
  if ( ! GetSecurityDescriptorDacl ( pRelSD, ( LPBOOL) &fHasDACL,
           ( PACL *) &pDACL,
           ( LPBOOL) &fDACLDefaulted) )
   return ( GetLastError());

  // get dacl length
  dwDACLLength = pDACL->AclSize;

  // now check if SID's ACE is there
  for ( i = 0; i < pDACL->AceCount; i++)
  {
   if ( ! GetAce ( pDACL, i, ( LPVOID *) &pDACLAce) )
    return ( GetLastError());

   // check if group sid is already there
   if ( EqualSid ( ( PSID) &(pDACLAce->SidStart), pGroupSID) )
    break;
  }


  // exit if found (means already has been set)
  if ( i < pDACL->AceCount)
  {
   dwError = ERROR_GROUP_EXISTS;

   return ( dwError);
  }

  // get length of new DACL
  dwAddDACLLength = sizeof ( ACCESS_ALLOWED_ACE) -
        sizeof ( DWORD) + GetLengthSid ( pGroupSID);
 }
 else
  // get length of new DACL
  dwAddDACLLength = sizeof ( ACL) + sizeof ( ACCESS_ALLOWED_ACE) -
        sizeof ( DWORD) + GetLengthSid ( pGroupSID);

 // get memory needed for new DACL
 if ( ! ( pNewDACL = ( PACL) malloc ( dwDACLLength + dwAddDACLLength) ) )
  return ( GetLastError());

 // get the sd length
 dwSDLength = GetSecurityDescriptorLength ( pRelSD);

 // get memory for new SD
 if ( ! ( pAbsSD = ( PSECURITY_DESCRIPTOR)
       malloc ( dwSDLength + dwAddDACLLength) ) )
 {
  dwError = GetLastError();

  goto ErrorExit;
 }

 // change self-relative SD to absolute by making new SD
 if ( ! InitializeSecurityDescriptor ( pAbsSD,
            SECURITY_DESCRIPTOR_REVISION) )
 {
  dwError = GetLastError();

  goto ErrorExit;
 }

 // init new DACL
 if ( ! InitializeAcl ( pNewDACL, dwDACLLength + dwAddDACLLength,
               ACL_REVISION) )
 {
  dwError = GetLastError();

  goto ErrorExit;
 }

 // now add in all of the ACEs into the new DACL (if org DACL is there)
 if ( SE_DACL_PRESENT & sdcSDControl)
 {
  for ( i = 0; i < pDACL->AceCount; i++)
  {
   // get ace from original dacl
   if ( ! GetAce ( pDACL, i, ( LPVOID *) &pDACLAce) )
   {
    dwError = GetLastError();

    goto ErrorExit;
   }

   // now add ace to new dacl
   if ( ! AddAccessAllowedAce ( pNewDACL,
           ACL_REVISION,
           pDACLAce->Mask,
           ( PSID) &(pDACLAce->SidStart) ) )
   {
    dwError = GetLastError();

    goto ErrorExit;
   }
  }
 }

 // now add new ACE to new DACL
 if ( ! AddAccessAllowedAce ( pNewDACL, ACL_REVISION, dwAccessMask,
               pGroupSID) )
 {
  dwError = GetLastError();

  goto ErrorExit;
 }

 // check if everything went ok
 if ( ! IsValidAcl ( pNewDACL) )
 {
  dwError = GetLastError();

  goto ErrorExit;
 }

 // now set security descriptor DACL
 if ( ! SetSecurityDescriptorDacl ( pAbsSD, TRUE, pNewDACL,
              fDACLDefaulted) )
 {
  dwError = GetLastError();

  goto ErrorExit;
 }

 // check if everything went ok
 if ( ! IsValidSecurityDescriptor ( pAbsSD) )
 {
  dwError = GetLastError();

  goto ErrorExit;
 }

 // now set the reg key security (this will overwrite any existing security)
 dwError = RegSetKeySecurity (
      hSecurityRegKey,
      (SECURITY_INFORMATION)( DACL_SECURITY_INFORMATION),
      pAbsSD);

 // close reg key
// RegCloseKey ( hSecurityRegKey);


ErrorExit:

 // free memory
 if ( pAbsSD)
  free ( ( VOID *) pAbsSD);
 if ( pNewDACL)
  free ( ( VOID *) pNewDACL);

 return ( dwError);
}
0
 
jkrCommented:
BTW, you can find some samples on this at http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnsecure/html/msdn_ntprog.asp ("Windows NT Security")
0
 
jkrCommented:
sindbad, are you still with us?
0
 
sindbadAuthor Commented:

I'm not getting time to work on this problem. I'll defenitelylet you know once I resolve the problem.
0
 
jkrCommented:
Hm, this question is answered...
0

Featured Post

Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

  • 6
  • 2
  • 2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now