Collectives™ on Stack Overflow

Find centralized, trusted content and collaborate around the technologies you use most.

Learn more about Collectives

Teams

Q&A for work

Connect and share knowledge within a single location that is structured and easy to search.

Learn more about Teams

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!

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, 2009 at 5: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, 2009 at 5:55

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"
  • 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, 2009 at 5:46 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, 2017 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, 2020 at 12:15

    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.)"

    In German / Auf Deutsch: Öffne Lokale Sicherheitsrichtlinie, unter Lokale RichtlinieZuweisen von Benutzerrechten, in dem Eintrag Ersetzen eines Tokens auf Prozessebene den Benutzer, bzw. die Gruppe hinzufügen. – Martini Bianco Dec 2, 2021 at 12:35 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, 2009 at 6:14 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(); 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();

    Thanks for contributing an answer to Stack Overflow!

    • Please be sure to answer the question. Provide details and share your research!

    But avoid

    • Asking for help, clarification, or responding to other answers.
    • Making statements based on opinion; back them up with references or personal experience.

    To learn more, see our tips on writing great answers.