Re: LoadUserProfile( ) fails with system error code 5(ACCESS_DENIED)

Tech Tip: Click here to run a free scan for Windows Errors and optimize PC performance



You are not cleaning the profile struct before calling the LoadUserProfile,
so it may have some garbage values.

memset(&profile, 0, sizeof(PROFILEINFO));

for access tokens, you can refer following example-

http://www.google.com/codesearch?hl=en&q=show:gbfHN-hRKV4:3JfOA7SvKzA:lOeEtVpLiww&sa=N&ct=rd&cs_p=http://www.alter.org.ua/soft/win/myrunas/MyRunAs_v11_src.tgz&cs_f=MyRunAs_v11_src/MyRunAs.cpp


"Rohini" <rohinichandrap@xxxxxxxxx> wrote in message
news:a69ce1cc-8f30-42a6-baf6-d79c68011164@xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Hi,

I am working on a application(windows service) where
I need to load the user profile to fix a fault.

The existing code spawns another process using CreateProcessAsUser().
Below is the order in which the API's called to spawn a process.

1.LogonUser(user.c_str(), domain.c_str(), psw.c_str(),
LOGONTYPE,
LOGON32_PROVIDER_DEFAULT,
&Token);

2.ImpersonateLoggedonUser(Token);

3.CreateEnvironmentBlock(lpEnvironment,NULL,true);

4.CreateProcessAsUser(
Token,
NULL,
"test",
NULL, // Process attr
NULL, // Thread attr
TRUE, // Inherit handles
CREATE_NEW_PROCESS_GROUP | DETACHED_PROCESS |
CREATE_UNICODE_ENVIRONMENT,
lpEnvironment, // Environment
"C:\", // Working directory
&si, // Startup info
&pi // Process info
);

I am trying to call the API LoadUserProfile() in the below manner
before CreateProcessAsUser()
but I am getting ACCESS_DENIED_ERROR.

=============================================================
if ( !SetPrivilege( Token, SE_RESTORE_NAME, true) ) {
printf("SetPrivilege(SE_RESTORE_NAME) failed for the token with
error :%d",GetLastError());
}

if (!SetPrivilege( Token, SE_BACKUP_NAME, true) ) {
printf("SetPrivilege(SE_BACKUP_NAME) failed for the token with
error :%d",GetLastError());
}


PROFILEINFO profile;
profile.dwSize=sizeof(profile);
profile.lpUserName =(char*) user.c_str();
profile.dwFlags = PI_NOUI;

LoadUserProfile(Token,&profile);
==============================================================

Below is the SetPrivilege() function(source:MSDN) used to enable the
two privileges.

===============================================================

BOOL SetPrivilege(
HANDLE hToken, // access token handle
LPCTSTR lpszPrivilege, // name of privilege to enable/disable
BOOL bEnablePrivilege // to enable or disable privilege
)
{
TOKEN_PRIVILEGES tp;
LUID luid;

if ( !LookupPrivilegeValue(
NULL, // lookup privilege on local system
lpszPrivilege, // privilege to lookup
&luid ) ) // receives LUID of privilege
{
printf("LookupPrivilegeValue error: %u\n", GetLastError() );
return FALSE;
}

tp.PrivilegeCount = 1;
tp.Privileges[0].Luid = luid;
if (bEnablePrivilege)
tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
else
tp.Privileges[0].Attributes = 0;

// Enable the privilege or disable all privileges.

if ( !AdjustTokenPrivileges(
hToken,
FALSE,
&tp,
sizeof(TOKEN_PRIVILEGES),
(PTOKEN_PRIVILEGES) NULL,
(PDWORD) NULL) )
{
printf("AdjustTokenPrivileges error: %u\n", GetLastError() );
return FALSE;
}

if (GetLastError() == ERROR_NOT_ALL_ASSIGNED)

{
printf("The token does not have the specified privilege. \n");
return FALSE;
}

return TRUE;
}

=======================================================================


I have assigned the privileges SE_RESTORE_NAME and SE_BACKUP_NAME to
the local group in which
the user is a member.I have enabled these two privileges before
calling LoaduserProfile().
I am not able to undestand which/what privileges are missing.

The SetPrivilege() seems to have succeeded since I did not get any
error messages.

Below is what I observed in the userenv.log
========================================================================================
USERENV(2bd8.2700) 10:00:01:963 LoadUserProfile: Yes, we can
impersonate the user. Running as self
USERENV(2bd8.2700) 10:00:01:963
=========================================================
USERENV(2bd8.2700) 10:00:01:963 LoadUserProfile: Entering, hToken =
<0x384>, lpProfileInfo = 0xe2f464
USERENV(2bd8.2700) 10:00:01:963 LoadUserProfile: lpProfileInfo-
dwFlags = <0x1>
USERENV(2bd8.2700) 10:00:01:963 LoadUserProfile: lpProfileInfo-
lpUserName = <delta>
USERENV(2bd8.2700) 10:00:01:963 LoadUserProfile: lpProfileInfo-
lpProfilePath = <8î³>
USERENV(2bd8.2700) 10:00:01:963 LoadUserProfile: lpProfileInfo-
lpDefaultPath = <À6³>
USERENV(2bd8.2700) 10:00:01:963 LoadUserProfile: lpProfileInfo-
lpServerName = <?ð?uÐ?ö?,E>
USERENV(2bd8.2700) 10:00:01:963 LoadUserProfile: Failed to enable the
restore privilege. error = c0000022
USERENV(2bd8.2700) 10:00:01:963 LoadUserProfile: Returning FALSE.
Error = 5
=========================================================================================
As I understood from the log,the privilege SE_RESTORE_NAME is not
enabled.

But,I see the same error when I do not try to enable the
privileges,when the
privileges are not assigned and also when I enable the privileges.

Are there any other privileges that need to be assigned and enabled?

The service is running under Local System Account.
When LoadUserProfile() is called before calling
ImpersonateLoggedonUser()(i.e.outside the impersonation scope),
LoadUserProfile() succeeds.What I understood from this is that since
the API is called under the
Local System Account when called outside the impersonation scope,it
succeeded because of the higher privileges
the Local System Account has.

Also,what is the difference between passing a token from LogonUser()
and token from OpenProcessToken()
to LoadUserProfile()?

Could anyone please help me with any suggestions.

Thanks in advance.

Best Regards,
Rohini Chandra


.



Relevant Pages

  • Re: Getting logged in user from a service?
    ... That would be surprising considering that privileges can't be added to an existing token since tokens are mostly immutable. ... His own token, if he specifies "Impersonation" when creating an instance of a WMI class, then all he can do is specified by his own privileges. ... That way it's possible to perform some administrative tasks without you, the client, to run as an administrator, you are simply delegating the task to another more privileged process, which on it's turn is rather restricted. ...
    (microsoft.public.dotnet.languages.csharp)
  • Re: ImpersonateLoggedOnUser & ShellExecute
    ... now I've made sure that the calling account has the required privileges ... option to set the needed access rights there. ... > the access rights to the process's access tokens, ... > the process that calls the API CreateProcessAsUser(), ...
    (microsoft.public.win32.programmer.networks)
  • Re: Setting SeSecurityPrivilege on IWbemServices in C++
    ... (not all tokens have all the privileges) ... and if you check the "enable-all-privileges" check-box, ... >>> All the code snippets I've found by now are in VB but I need to to it ...
    (microsoft.public.win32.programmer.wmi)
  • Re: Setting SeSecurityPrivilege on IWbemServices in C++
    ... If you are local administrator of the Domain Controller, ... non-enabled privileges are stripped away across a LRPC ... >> (not all tokens have all the privileges) ...
    (microsoft.public.win32.programmer.wmi)
  • Re: LoadUserProfile failing
    ... _own_ profile, which strikes me as a bit odd. ... account has admin privileges ... MSDN states that starting from XP SP2 and Windows Server 2003 you can only ...
    (microsoft.public.win32.programmer.kernel)