17

I want create a process under another user. So I use LogonUser and CreateProcessAsUser. But my problem is, that CreatePtocessAsUser always returns the errorcode 1314, which means "A required privilige is not held by the client". So my question is, what I am doing wrong? Or how can i give the priviliges to the handle? (I think the handle should have the privileges, or I am wrong?) Sorry for my english mistakes, but my english knowledge isn't the best :)

Plesase help if anyone knows how to correct my application.

This a part of my code.

STARTUPINFO StartInfo;
PROCESS_INFORMATION ProcInfo;
TOKEN_PRIVILEGES tp;
memset(&ProcInfo, 0, sizeof(ProcInfo));
memset(&StartInfo, 0 , sizeof(StartInfo)); 
StartInfo.cb = sizeof(StartInfo); 
HANDLE handle = NULL;

if (!OpenProcessToken(GetCurrentProcess(),
TOKEN_ALL_ACCESS, &handle)) printf("\nOpenProcessError");

if (!LookupPrivilegeValue(NULL,SE_TCB_NAME,
//SE_TCB_NAME,
&tp.Privileges[0].Luid)) {
printf("\nLookupPriv error");
}

tp.PrivilegeCount = 1;
tp.Privileges[0].Attributes =
SE_PRIVILEGE_ENABLED;//SE_PRIVILEGE_ENABLED;
if (!AdjustTokenPrivileges(handle, FALSE, &tp, 0, NULL, 0)) {
printf("\nAdjustToken error");
}

i = LogonUser(user, domain, password, LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, &handle);
printf("\nLogonUser return  : %d",i);
i = GetLastError();
printf("\nLogonUser getlast : %d",i);
if (! ImpersonateLoggedOnUser(handle) ) printf("\nImpLoggedOnUser!");

i = CreateProcessAsUser(handle, "c:\\windows\\system32\\notepad.exe",NULL, NULL, NULL, true, 
CREATE_UNICODE_ENVIRONMENT |NORMAL_PRIORITY_CLASS | CREATE_NEW_CONSOLE, NULL, NULL, 
&StartInfo, &ProcInfo);    
printf("\nCreateProcessAsUser return  : %d",i);
i = GetLastError();
printf("\nCreateProcessAsUser getlast : %d",i);

CloseHandle(handle); 
CloseHandle(ProcInfo.hProcess); 
CloseHandle(ProcInfo.hThread); 

Thanks in advance!

kampi
  • 2,362
  • 12
  • 52
  • 91
  • You're lucky that you even know the error number. The correct way to call GetLastError is to call it immediately after calling an API, if the API failed. If you call anything else in between (for example printf) then GetLastError will usually give you a later error instead of the error that you wanted. – Windows programmer Sep 25 '09 at 05:44
  • Yes, you are right, and i know it too, but i tried so many ways to solve this problem, and i have forgotten to delete the printf. My mistake :( – kampi Sep 25 '09 at 05:55
  • ERROR_PRIVILEGE_NOT_HELD just in case someone searches for the error name and not 1314. – Millie Smith Aug 16 '17 at 16:56

4 Answers4

19

The local account that is running your app must have these privileges enabled in the Local Security Policy:

  • Act as part of the operating system
  • Create a token object
  • Log on as a batch job

Edit: Please see Patel's answer below. The correct privilege in this case should be:

  • "Replace a process level token"
lod3n
  • 2,893
  • 15
  • 16
  • 1
    Hi! I want to use a domain and a local account too. I think maybe creating a token object would be the easiest way, and i hope, it will workvunder both accounts. Could you give me maybe a sample code, how to generate a token object with the requiered privileges? Thanks, kampi – kampi Sep 25 '09 at 05:46
  • 1
    How do I set those privileges? – Joel Jan 28 '16 at 10:12
  • 1
    For everyone coming by: I didn't end up needing the first two of these (although I'm already in "Log on as batch job"). Instead, I finally got it to work by adding "Replace a process level token" like @Patel suggested. – Millie Smith Aug 16 '17 at 16:55
  • I don't believe this answer is correct despite being marked as such. "Create token object" is a very protected privilege and is normally only held by processes such as winlogon and lsass, the security manager. The second answer is the correct one. "Replace a process level token" is the only privilege required and is held by default by all service processes. – Benj May 18 '20 at 12:15
14

After looking for answer for hours, I finally found it in following link from MSDN. Hope it may help someone in future.

https://social.msdn.microsoft.com/Forums/vstudio/en-US/c905c900-cae1-4081-b0c9-00f10238e7ad/createprocessasuser-failed?forum=clr

"To resolve this problem, you'll need to elevate the rights of the account calling CreateProcessAsUser with the "Replace a process level token" right. To do so, open the Control Panel / Administrative Tools / Local Security Policy and add the user account to the "Replace a process level token" right. (You may have to logout or even reboot to have this change take effect.)"

Patel
  • 399
  • 5
  • 12
0

Your code adds the SE_TCB_NAME privilege to your token.

MSDN says "Typically, the process that calls the CreateProcessAsUser function must have the SE_ASSIGNPRIMARYTOKEN_NAME and SE_INCREASE_QUOTA_NAME privileges."

Windows programmer
  • 7,871
  • 1
  • 22
  • 23
  • Yes, i know that too. My problem is, that how should i add these privileges? If i try this: if (!LookupPrivilegeValue(NULL,SE_ASSIGNPRIMARYTOKEN_NAME & SE_INCREASE_QUOTA_NAME, &tp.Privileges[0].Luid)) I get the error : Invalid operands of types to binary operator '&' So how do i add these two privileges at the same thime? – kampi Sep 25 '09 at 06:14
0

I checked the links, and it worked good. Check this

void main()
{

DWORD dwSessionId;
HANDLE hToken = NULL;

TOKEN_PRIVILEGES tp;
PROCESS_INFORMATION pi;
STARTUPINFOW si;

// Initialize structures.
ZeroMemory(&tp, sizeof(tp));
ZeroMemory(&pi, sizeof(pi));
ZeroMemory(&si, sizeof(si));
si.cb = sizeof(si);


LPTSTR lpszUsername = "user\0";
LPTSTR lpszDomain = ".";//"bgt\0";
LPTSTR lpszPassword = "password\0";

if (!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY
| TOKEN_ADJUST_PRIVILEGES , &hToken)) {

MyError();
}



// Look up the LUID for the TCB Name privilege.
if (!LookupPrivilegeValue(NULL,SE_TCB_NAME, //SE_SHUTDOWN_NAME ,
//SE_TCB_NAME,
&tp.Privileges[0].Luid)) {
MyError();
}


tp.PrivilegeCount = 1;
tp.Privileges[0].Attributes =
SE_PRIVILEGE_ENABLED;//SE_PRIVILEGE_ENABLED;
if (!AdjustTokenPrivileges(hToken, FALSE, &tp, 0, NULL, 0)) {

MyError();
}


if(LogonUser(lpszUsername,lpszDomain,lpszPassword,
LOGON32_LOGON_INTERACTIVE,LOGON32_PROVIDER_DEFAULT,&hToken) == 0)
{
MyError();
}
else
{
STARTUPINFO sInfo;
PROCESS_INFORMATION ProcessInfo;
memset(&sInfo,0,sizeof(STARTUPINFO));
sInfo.cb = sizeof(STARTUPINFO);
sInfo.dwX = CW_USEDEFAULT;
sInfo.dwY = CW_USEDEFAULT;
sInfo.dwXSize = CW_USEDEFAULT;
sInfo.dwYSize = CW_USEDEFAULT;


bool bRet = CreateProcessAsUser(hToken,
"c:\\windows\\system32\\notepad.exe",
NULL,
NULL,
NULL,
TRUE,
CREATE_NEW_CONSOLE,
NULL,
NULL,
&sInfo,
&ProcessInfo);

if(bRet == 0)
MyError();
}
Toni Frankola
  • 1,652
  • 15
  • 26
binyo66
  • 9
  • 1