CreateProcess() vs. CreateProcessAsUser()

14/11/2008 - 02:01 von Thomas Steinbach | Report spam
Hallo NG,

ich habe da ein Problem, wenn ich einen Prozess als
User starten will. Also mit CreateProcessAsUser(...)

Wenn ich es mit dem unten auskommentiertem CreateProcess
starte, dann wird postgres auch gestartet. bei CreateProcessAsUser
nicht.

Nachdem ich GetLastError abfrage bekomme ich den
Fehler #1314 "A required privelege is not held by the client"
vgl.: http://www.failure.bravehost.com/prog/win/priv/

Jetzt frage ich mich a) wie ich herausbekomme welches Privileg
das ist und b) warum geht es mit CreateProcess unter
dem gleichen Account "user" mit dem gegebenen Passwort
"password"?

Um schonmal generell die (S)ACL aendern zu koennen,
habe ich mich zwar in die SecurityAttribute etc- eingelesen,
aber so ganz steige ich noch nicht durch.

So wie ich das verstanden habe, muss ich doch einen SecurityDescritor,
die auf eine ACL Struktur zeigt, erzeugen und dann der
SecurityAttributes Struktur mitteilen in welchem SecurityDescriptor
nun die "erhoehten" (also um das fehlende Privileg) Rechte
stehen. Dies SecurityStruktur kann ich dann dem CreateProcessAsUser
mitgeben, damit dieser mit dem entsprechenden Privilegien gestartet
wird, nicht?

Nun frage ich mich noch wo und vor allem wie ich diese geaenderten
Rechte setzten kann. Also es muesste ja irgendwie in der ACL
sowas wie ein myacl.PRIVS = CreatePrimaryToken; oder so aehnlich
geben. Aber ich glaube da bin ich auf dem Holzweg, da die Struktur
ACL nicht solche Felder hat... Was mich nun auch wieder hilfos drein-
schauen laesst.

Danach moechte ich das ganze noch versuchen unter, bzw. mit dem
"LocalSystem" Account zu starten.

Mein Source sieht so aus. (eben in einem Proggi und so nicht getestet)
Auch auf: http://www.failure.bravehost.com/pr..._1314.html
bzw.: http://www.failure.bravehost.com/pr...ple_1314.c

int MyProgStart(void)
{
STARTUPINFO si;
PROCESS_INFORMATION pi;

HANDLE hTok = NULL;

SECURITY_ATTRIBUTES sa;
SECURITY_DESCRIPTOR sd;
ACL myacl;

TCHAR szMsgBuf[MAX_PATH] = _TEXT("");
LPTSTR lpszMsgBuf = NULL;

ZeroMemory(&si, sizeof(si));
sip.cb = sizeof(si);
ZeroMemory(&pi, sizeof(pi));

ZeroMemory(&sa, sizeof(sa));
sap.nLength = sizeof(sa);

LogonUser("user", ".", "password", LOGON32_LOGON_INTERACTIVE,
LOGON32_PROVIDER_DEFAULT, &hTok);

SetSecurityDescriptorSacl(&sd, TRUE, &myacl, FALSE);
sap.lpSecurityDescriptor = &sd;

/*if( !CreateProcess(NULL, "pg_ctl.exe+PARAMS", NULL, NULL, FALSE, 0, NULL,
NULL, &sip, &pip) ) {*/
if( !CreateProcessAsUser(hTok, NULL, "pg_ctl.exe+PARAMS", &sa, NULL, FALSE,
0, NULL, NULL, &si, &pi) ) {
{

CloseHandle(pi.hProcess);

FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM,
NULL,
GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL), (LPTSTR)
&lpszMsgBuf, 0, NULL);
wsprintf(szMsgBuf, "#%d = %s", GetLastError(), lpszMsgBuf);
MessageBox(NULL, szMsgBuf, "Error", MB_OK|MB_ICONINFORMATION);

ZeroMemory(&si, sizeof(si));
sip.cb = sizeof(si);
ZeroMemory(&pi, sizeof(pi));

return 1; /* failed to create process */
}

ZeroMemory(&si, sizeof(si));
sip.cb = sizeof(si);
ZeroMemory(&pi, sizeof(pi));

CloseHandle(pi.hProcess);

return 0;
}

Ich hoffe jemadn weiss was ich da machen kann und vielleicht
sogar wie ich das ganze dann noch umsetze um den Process
mit dem "LocalSystem" Account zu starten.

Thomas
 

Lesen sie die antworten

#1 Volker Birk
14/11/2008 - 19:31 | Warnen spam
Thomas Steinbach wrote:
Jetzt frage ich mich a) wie ich herausbekomme welches Privileg
das ist und b) warum geht es mit CreateProcess unter
dem gleichen Account "user" mit dem gegebenen Passwort
"password"?



Das Sicherheitskonzept im Windows-Kernel erfordert, dass ein Prozess das
entsprechende Privileg hat, will er einen Kindprozess unter einem andern
Nutzerkontext starten.

Quellcode für "gib mir jetzt das Privileg" findest Du z.B. hier drin:
http://www.dingens.org/win32sec-en-src.zip

- snip -
BOOL setPrivilege(HANDLE hToken, LPCTSTR lpszPrivilege, BOOL
bEnablePrivilege)
{
TOKEN_PRIVILEGES tp;
LUID luid;

if (!LookupPrivilegeValue(NULL, lpszPrivilege, &luid))
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;

AdjustTokenPrivileges(hToken, FALSE, &tp, sizeof(TOKEN_PRIVILEGES),
(PTOKEN_PRIVILEGES) NULL, (PDWORD) NULL);
return GetLastError() == ERROR_SUCCESS;
}
- snap -

Benutzt wird das Ding mit:

- snip -
HANDLE hToken;
BOOL result;

if (!OpenProcessToken(GetCurrentProcess(),
TOKEN_READ | TOKEN_WRITE, &hToken))
return FALSE;

result = setPrivilege(hToken, SE_ASSIGNPRIMARYTOKEN_NAME, TRUE)
|| setPrivilege(hToken, SE_INCREASE_QUOTA_NAME, TRUE);
- snap -


Die Privilegien, die Du suchst, sind bei CreateProcessAsUser()
dokumentiert:

<http://msdn.microsoft.com/en-us/lib...9.aspx>
| Typically, the process that calls the CreateProcessAsUser function
| must have the SE_ASSIGNPRIMARYTOKEN_NAME and SE_INCREASE_QUOTA_NAME
| privileges. If this function fails with ERROR_PRIVILEGE_NOT_HELD (1314),
| use the CreateProcessWithLogonW function instead.
| CreateProcessWithLogonW requires no special privileges, but the
| specified user account must be allowed to log on interactively.

Viele Grüsse,
VB.
"Den Rechtsstaat macht aus, dass Unschuldige wieder frei kommen."

Dr. Wolfgang Schàuble, Bundesinnenminister

Ähnliche fragen