You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
203 lines
6.9 KiB
203 lines
6.9 KiB
/**************************** Module Header ********************************\
|
|
* Module Name: service.c
|
|
*
|
|
* Copyright (c) 1985 - 1999, Microsoft Corporation
|
|
*
|
|
* Service Support Routines
|
|
*
|
|
* History:
|
|
* 12-22-93 JimA Created.
|
|
\***************************************************************************/
|
|
|
|
#include "precomp.h"
|
|
#pragma hdrstop
|
|
|
|
|
|
/***************************************************************************\
|
|
* xxxConnectService
|
|
*
|
|
* Open the windowstation assigned to the service logon session. If no
|
|
* windowstation exists, create the windowstation and a default desktop.
|
|
*
|
|
* History:
|
|
* 12-23-93 JimA Created.
|
|
\***************************************************************************/
|
|
HWINSTA xxxConnectService(
|
|
PUNICODE_STRING pstrWinSta,
|
|
HDESK *phdesk)
|
|
{
|
|
NTSTATUS Status;
|
|
HANDLE hToken;
|
|
ULONG ulLength;
|
|
PTOKEN_USER ptuService;
|
|
PSECURITY_DESCRIPTOR psdService;
|
|
PSID psid;
|
|
PACCESS_ALLOWED_ACE paceService = NULL, pace;
|
|
OBJECT_ATTRIBUTES ObjService;
|
|
HWINSTA hwinsta;
|
|
UNICODE_STRING strDesktop;
|
|
TL tlPoolSdService, tlPoolAceService, tlPoolToken;
|
|
|
|
/*
|
|
* Open the token of the service.
|
|
*/
|
|
Status = OpenEffectiveToken(&hToken);
|
|
if (!NT_SUCCESS(Status)) {
|
|
RIPMSG1(RIP_WARNING, "ConnectService: Could not open process/thread token (0x%X)", Status);
|
|
return NULL;
|
|
}
|
|
|
|
/*
|
|
* Get the user SID assigned to the service.
|
|
*/
|
|
ptuService = NULL;
|
|
paceService = NULL;
|
|
psdService = NULL;
|
|
hwinsta = NULL;
|
|
ZwQueryInformationToken(hToken, TokenUser, NULL, 0, &ulLength);
|
|
ptuService = (PTOKEN_USER)UserAllocPool(ulLength, TAG_TOKEN);
|
|
if (ptuService == NULL) {
|
|
RIPMSG1(RIP_WARNING, "ConnectService: Can't alloc buffer (size=%d) for token info", ulLength);
|
|
ZwClose(hToken);
|
|
goto sd_error;
|
|
}
|
|
Status = ZwQueryInformationToken(hToken, TokenUser, ptuService,
|
|
ulLength, &ulLength);
|
|
ZwClose(hToken);
|
|
if (!NT_SUCCESS(Status)) {
|
|
RIPMSG1(RIP_WARNING, "ConnectService: QueryInformationToken failed (0x%X)", Status);
|
|
goto sd_error;
|
|
}
|
|
psid = ptuService->User.Sid;
|
|
|
|
/*
|
|
* Create ACE list.
|
|
*/
|
|
paceService = AllocAce(NULL, ACCESS_ALLOWED_ACE_TYPE, 0,
|
|
WINSTA_CREATEDESKTOP | WINSTA_READATTRIBUTES |
|
|
WINSTA_ACCESSGLOBALATOMS | WINSTA_EXITWINDOWS |
|
|
WINSTA_ACCESSCLIPBOARD | STANDARD_RIGHTS_REQUIRED,
|
|
psid, &ulLength);
|
|
if (paceService == NULL) {
|
|
RIPMSG0(RIP_WARNING, "ConnectService: AllocAce for WindowStation attributes failed");
|
|
goto sd_error;
|
|
}
|
|
pace = AllocAce(paceService, ACCESS_ALLOWED_ACE_TYPE, OBJECT_INHERIT_ACE |
|
|
INHERIT_ONLY_ACE | NO_PROPAGATE_INHERIT_ACE,
|
|
DESKTOP_READOBJECTS | DESKTOP_WRITEOBJECTS | DESKTOP_ENUMERATE |
|
|
DESKTOP_CREATEWINDOW | DESKTOP_CREATEMENU | DESKTOP_HOOKCONTROL |
|
|
STANDARD_RIGHTS_REQUIRED,
|
|
psid, &ulLength);
|
|
if (pace == NULL) {
|
|
RIPMSG0(RIP_WARNING, "ConnectService: AllocAce for Desktop Attributes failed");
|
|
goto sd_error;
|
|
}
|
|
paceService = pace;
|
|
pace = AllocAce(pace, ACCESS_ALLOWED_ACE_TYPE, 0,
|
|
WINSTA_ENUMERATE,
|
|
SeExports->SeAliasAdminsSid, &ulLength);
|
|
if (pace == NULL) {
|
|
RIPMSG0(RIP_WARNING, "ConnectService: AllocAce for admin WinSta enumerate failed");
|
|
goto sd_error;
|
|
}
|
|
paceService = pace;
|
|
pace = AllocAce(pace, ACCESS_ALLOWED_ACE_TYPE, OBJECT_INHERIT_ACE |
|
|
INHERIT_ONLY_ACE | NO_PROPAGATE_INHERIT_ACE,
|
|
DESKTOP_READOBJECTS | DESKTOP_WRITEOBJECTS | DESKTOP_ENUMERATE,
|
|
SeExports->SeAliasAdminsSid, &ulLength);
|
|
if (pace == NULL) {
|
|
RIPMSG0(RIP_WARNING, "ConnectService: AllocAce for admin Desktop access failed");
|
|
goto sd_error;
|
|
}
|
|
paceService = pace;
|
|
|
|
/*
|
|
* Initialize the SD
|
|
*/
|
|
psdService = CreateSecurityDescriptor(paceService, ulLength, FALSE);
|
|
if (psdService == NULL) {
|
|
RIPMSG0(RIP_WARNING, "ConnectService: CreateSecurityDescriptor failed");
|
|
goto sd_error;
|
|
}
|
|
|
|
ThreadLockPool(PtiCurrent(), ptuService, &tlPoolToken);
|
|
ThreadLockPool(PtiCurrent(), paceService, &tlPoolAceService);
|
|
ThreadLockPool(PtiCurrent(), psdService, &tlPoolSdService);
|
|
|
|
/*
|
|
* The windowstation does not exist and must be created.
|
|
*/
|
|
try {
|
|
InitializeObjectAttributes(&ObjService,
|
|
pstrWinSta,
|
|
OBJ_OPENIF,
|
|
NULL,
|
|
psdService);
|
|
} except (W32ExceptionHandler(FALSE, RIP_WARNING)) {
|
|
Status = GetExceptionCode();
|
|
}
|
|
|
|
if (NT_SUCCESS(Status)) {
|
|
hwinsta = xxxCreateWindowStation(&ObjService,
|
|
KernelMode,
|
|
MAXIMUM_ALLOWED,
|
|
NULL,
|
|
0,
|
|
NULL,
|
|
NULL,
|
|
0);
|
|
}
|
|
|
|
if (hwinsta != NULL) {
|
|
TRACE_INIT(("Service windowstation created\n"));
|
|
|
|
/*
|
|
* We have the windowstation, now create the desktop. The security
|
|
* descriptor will be inherited from the windowstation. Save the
|
|
* winsta handle because the access struct may be moved by the
|
|
* desktop creation.
|
|
*/
|
|
RtlInitUnicodeString(&strDesktop, TEXT("Default"));
|
|
InitializeObjectAttributes(&ObjService, &strDesktop,
|
|
OBJ_OPENIF | OBJ_CASE_INSENSITIVE, hwinsta, NULL);
|
|
|
|
*phdesk = xxxCreateDesktop(&ObjService,
|
|
KernelMode,
|
|
NULL,
|
|
NULL,
|
|
0,
|
|
MAXIMUM_ALLOWED);
|
|
if (*phdesk == NULL) {
|
|
/*
|
|
* The creation failed so close the windowstation and leave.
|
|
*/
|
|
RIPMSGF0(RIP_WARNING, "CreateDesktop('Default') failed.");
|
|
|
|
ZwClose(hwinsta);
|
|
hwinsta = NULL;
|
|
} else {
|
|
TRACE_INIT(("Default desktop in Service windowstation created\n"));
|
|
}
|
|
} else {
|
|
*phdesk = NULL;
|
|
}
|
|
|
|
ThreadUnlockPool(PtiCurrent(), &tlPoolSdService);
|
|
ThreadUnlockPool(PtiCurrent(), &tlPoolAceService);
|
|
ThreadUnlockPool(PtiCurrent(), &tlPoolToken);
|
|
|
|
sd_error:
|
|
if (ptuService != NULL) {
|
|
UserFreePool(ptuService);
|
|
}
|
|
|
|
if (paceService != NULL) {
|
|
UserFreePool(paceService);
|
|
}
|
|
|
|
if (psdService != NULL) {
|
|
UserFreePool(psdService);
|
|
}
|
|
|
|
return hwinsta;
|
|
}
|