Re: LoadUserProfile( ) fails with system error code 5(ACCESS_DENIED)
- From: "Manish Agarwal" <manishkrishan@xxxxxxxxxxx>
- Date: Thu, 27 Nov 2008 16:37:47 +0530
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
.
- References:
- Prev by Date: passing this object
- Next by Date: Re: passing this object
- Previous by thread: LoadUserProfile( ) fails with system error code 5(ACCESS_DENIED)
- Next by thread: Re: Solution-global settings?
- Index(es):
Relevant Pages
|