LoadUserProfile() returns ERROR_ACCESS_DENIED



I'm trying to call LoadUserProfile(), which fails. GetLastError() returns 5
[access denied]. I've read the MSDN doc on LoadUserProfile, which indicates
that the calling process must have the SE_RESTORE_NAME and SE_BACKUP_NAME
privs, which I believe I've enabled.

Can't figure it out -- LoadUserProfile always returns FALSE. What am I
missing?

Note: code is a collection of code I found on public internet and some
glue-code that I added.

Code snippet:
int main( int argc, char *argv[] ) {
LPTSTR User, Domain, Password, Command, lpNameBuffer = NULL;
DWORD dwSize = 0;
int RC = 0;

if ( argc != 5 ) {
usage( argv[0] );
RC = -1;
} else {
GetUserNameEx( NameSamCompatible, lpNameBuffer, &dwSize );
if ( GetLastError() == ERROR_MORE_DATA ) {
lpNameBuffer = (LPTSTR) HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
dwSize + 1 );
if ( GetUserNameEx( NameSamCompatible, lpNameBuffer, &dwSize ) ) {
sprintf( buffer, "Calling User: %s\n", lpNameBuffer );
debug( buffer );
if ( lpNameBuffer != NULL ) HeapFree( GetProcessHeap(), 0, (LPVOID)
lpNameBuffer );
}
}

User = argv[1];
Domain = argv[2];
Password = argv[3];
Command = argv[4];
sprintf( buffer, "User = %s\n", argv[1] );
debug( buffer );
sprintf( buffer, "Domain = %s\n", argv[2] );
debug( buffer );
debug( "Password supplied, not logged\n" );
sprintf( buffer, "Command = %s\n", argv[4] );
debug( buffer );

if ( !AdjustCaller() ) {
RC = -1;
} else {
if ( !StartProcess( User, Domain, Password, Command ) ) {
RC = -1;
debug( "Couldn't start interactive client process!\n" );
}
}
}

if ( log != NULL ) (void) fclose( log );

return RC;
}

BOOL AdjustCaller( void ) {
HANDLE hToken;

if ( !OpenProcessToken( GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES |
TOKEN_QUERY, &hToken ) ) {
debug( "OpenProcessToken() failed, unable to query or adjust token
privs\n" );
return FALSE;
}

if ( !SetPrivilege( hToken, SE_TCB_NAME, TRUE ) ) {
debug( "Couldn't set 'SE_TCB_NAME' privilege for this process!\n" );
return FALSE;
}

if ( !SetPrivilege( hToken, SE_ASSIGNPRIMARYTOKEN_NAME, TRUE ) ) {
debug( "Couldn't set 'SE_ASSIGNPRIMARYTOKEN_NAME' privilege for this
process!\n" );
return FALSE;
}

if ( !SetPrivilege( hToken, SE_RESTORE_NAME, TRUE ) ) {
debug( "non-fatal: Couldn't set 'SE_RESTORE_NAME' privilege for this
process! Needed for LoadUserProfile()\n" );
}

if ( !SetPrivilege( hToken, SE_BACKUP_NAME, TRUE ) ) {
debug( "non-fatal: Couldn't set 'SE_BACKUP_NAME' privilege for this
process! Needed for LoadUserProfile()\n" );
}

if ( !SetPrivilege( hToken, SE_CHANGE_NOTIFY_NAME, TRUE ) ) {
debug( "non-fatal: Couldn't set 'SE_CHANGE_NOTIFY_NAME' privilege for
this process!\n" );
}

if ( !SetPrivilege( hToken, SE_INCREASE_QUOTA_NAME, TRUE ) ) {
debug( "Couldn't set 'SE_ASSIGNPRIMARYTOKEN_NAME' privilege for this
process!\n" );
return FALSE;
}

debug( "AdjustCaller(): privileges enabled -- YAY!\n" );
return TRUE;
}

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
(void) sprintf( buffer, "Privilege: %s: LookupPrivilegeValue error:
%u\n", lpszPrivilege, GetLastError( ) );
debug( buffer );
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) ) {
(void) sprintf( buffer, "Privilege: %s: AdjustTokenPrivileges error:
%u\n", lpszPrivilege, GetLastError( ) );
debug( buffer );
return FALSE;
}

if ( GetLastError() == ERROR_NOT_ALL_ASSIGNED ) {
(void) sprintf( buffer, "Privilege: %s: The token does not have the
specified privilege.\n", lpszPrivilege );
debug( buffer );
return FALSE;
}

return TRUE;
}

BOOL StartProcess( LPTSTR lpszUsername, LPTSTR lpszDomain,
LPTSTR lpszPassword, LPTSTR lpCommandLine ) {
HANDLE hToken;
PROFILE_INFORMATION profileInformation;
BOOL bProfileLoaded = FALSE;

if ( !LogonUser( lpszUsername, lpszDomain, lpszPassword,
LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, &hToken ) ) {
return FALSE;
}

ZeroMemory( &profileInformation, sizeof( profileInformation ) );
profileInformation.dwSize = sizeof( profileInformation );
profileInformation.lpUserName = lpszUsername;
profileInformation.dwFlags = PI_NOUI;

if ( (bProfileLoaded = LoadUserProfile( hToken, &profileInformation )) ==
FALSE ) {
sprintf( buffer, "LoadUserProfile() failed: LastError: %u\n",
GetLastError( ) );
debug( buffer );
}

.
.
.
}
--end of code snippet--


.



Relevant Pages

  • Re: Strange C error
    ... Getting debug output back via wimp error boxes sounds a bit painful! ... is the length of the icon's buffer? ... variables in a function with gcc? ...
    (comp.sys.acorn.programmer)
  • Re: cxx0017: ... symbol not found VC++6
    ... You are running a debug build of the project with debug symbols ... // At this point should be pointing at workingBuf at the point of the ... // buffer end is reached before a $ is found the device should be ... // First check for end of buffer and read input buffer (newBuf) if ...
    (microsoft.public.vc.language)
  • Re: waveINxxx "bad pointer" error in Debug version
    ... This seems to indicate something with the debug rt library causing the ... preparing the buffers once, receiving full buffers for MM_WIM_DATA and ... The pointer pwaveHdr1 is in your data section so if the pointer ... _wctime_s needs a buffer of 26 characters. ...
    (microsoft.public.win32.programmer.mmedia)
  • Re: VerQueryValue Bug?
    ... call to verqueryvalue was not called there was not problem. ... I believe that debug and verqueryvalue can have unexpected side effects. ... >> Allocated a buffer ...
    (microsoft.public.win32.programmer.kernel)
  • Re: ORA-01031: insufficient privileges when open a Cursor
    ... The procedure goes to the exception when get to the open cursor ... I am able to debug the procedure and seems that all the ... There is no privilege required to open a cursor. ... Also i can execute the procedure as a script with no ...
    (comp.databases.oracle.server)