windows-nt/Source/XPSP1/NT/base/screg/sc/client/tsec.c
2020-09-26 16:20:57 +08:00

678 lines
14 KiB
C

/*++
Copyright (c) 1991-92 Microsoft Corporation
Module Name:
tsec.c
Abstract:
Test for the security functionality in service controller.
Author:
Rita Wong (ritaw) 16-Mar-1992
Environment:
User Mode - Win32
Revision History:
--*/
#include <stdio.h>
#include <nt.h>
#include <ntrtl.h>
#include <nturtl.h>
#include <windef.h> // IN, BOOL, LPTSTR, etc.
#include <winbase.h>
#ifndef UNICODE
#define UNICODE
#endif
#include <winsvc.h> // Win32 service control APIs
DWORD
TestOpenService(
IN SC_HANDLE hScManager,
OUT LPSC_HANDLE hService,
IN LPWSTR ServiceName,
IN DWORD DesiredAccess,
IN DWORD ExpectedError
);
DWORD
TestOpenSCManager(
OUT LPSC_HANDLE hScManager,
IN LPWSTR DatabaseName,
IN DWORD DesiredAccess,
IN DWORD ExpectedError
);
DWORD
TestEnumServicesStatus(
IN SC_HANDLE hSCManager,
IN DWORD ExpectedError
);
DWORD
TestQueryServiceStatus(
IN SC_HANDLE hService,
IN DWORD ExpectedError
);
DWORD
TestControlService(
IN SC_HANDLE hService,
IN DWORD ControlCode,
IN DWORD ExpectedError
);
DWORD
TestStartService(
IN SC_HANDLE hService,
IN DWORD ExpectedError
);
VOID
DisplayStatus(
IN LPWSTR ServiceName OPTIONAL,
IN LPSERVICE_STATUS ServiceStatus
);
BYTE WorkBuffer[1024];
VOID __cdecl
main(
void
)
{
DWORD status;
SC_HANDLE hScManager;
SC_HANDLE hService;
PSECURITY_DESCRIPTOR lpSecurity = (PSECURITY_DESCRIPTOR) WorkBuffer;
DWORD BytesRequired;
//
// Bad database name
//
(void) TestOpenSCManager(
&hScManager,
L"Bogus",
0,
ERROR_INVALID_NAME
);
//
// Failed database name
//
(void) TestOpenSCManager(
&hScManager,
L"SERVICESFAILED",
0,
ERROR_DATABASE_DOES_NOT_EXIST
);
//
// Active database name
//
if (TestOpenSCManager(
&hScManager,
L"SERVICESactive",
0,
NO_ERROR
) == NO_ERROR) {
(void) CloseServiceHandle(hScManager);
}
//
// Invalid desired access
//
(void) TestOpenSCManager(
&hScManager,
NULL,
0xff00,
ERROR_ACCESS_DENIED
);
//
// Valid desired access
//
if (TestOpenSCManager(
&hScManager,
NULL,
SC_MANAGER_CONNECT,
NO_ERROR
) == NO_ERROR) {
//
// Invalid operation follows
//
(void) TestEnumServicesStatus(
hScManager,
ERROR_ACCESS_DENIED
);
(void) TestOpenService(
hScManager,
&hService,
L"Lumpy",
0xf000,
ERROR_ACCESS_DENIED
);
(void) TestOpenService(
hScManager,
&hService,
L"Lu mpy",
SERVICE_QUERY_STATUS,
ERROR_INVALID_NAME
);
(void) TestOpenService(
hScManager,
&hService,
L"\\Lumpy",
SERVICE_QUERY_STATUS,
ERROR_INVALID_NAME
);
(void) TestOpenService(
hScManager,
&hService,
L"Lum/py",
SERVICE_QUERY_STATUS,
ERROR_INVALID_NAME
);
(void) TestOpenService(
hScManager,
&hService,
L"Lump",
SERVICE_QUERY_STATUS,
ERROR_SERVICE_DOES_NOT_EXIST
);
//
// Service handle opened with only query access
//
status = TestOpenService(
hScManager,
&hService,
L"Lumpy",
SERVICE_QUERY_STATUS,
NO_ERROR
);
if (status == NO_ERROR) {
(void) TestControlService(
hService,
SERVICE_CONTROL_PAUSE,
ERROR_ACCESS_DENIED
);
(void) TestStartService(
hService,
ERROR_ACCESS_DENIED
);
(void) TestQueryServiceStatus(
hService,
NO_ERROR
);
(void) CloseServiceHandle(hService);
}
//
// Test QueryServiceObjectSecurity and SetServiceObjectSecurity
//
status = TestOpenService(
hScManager,
&hService,
L"Lumpy",
READ_CONTROL | WRITE_DAC,
NO_ERROR
);
if (status == NO_ERROR) {
if (QueryServiceObjectSecurity(
hService,
DACL_SECURITY_INFORMATION,
lpSecurity,
sizeof(WorkBuffer),
&BytesRequired
)) {
printf("QueryServiceObjectSecurity: OK. BytesRequired=%lu\n",
BytesRequired);
if (SetServiceObjectSecurity(
hService,
DACL_SECURITY_INFORMATION,
lpSecurity
)) {
printf("SetServiceObjectSecurity: OK.\n");
}
else {
printf("SetServiceObjectSecurity: Failed=%lu\n", GetLastError());
}
}
else {
printf("QueryServiceObjectSecurity: Failed=%lu\n", GetLastError());
}
(void) CloseServiceHandle(hService);
}
(void) CloseServiceHandle(hScManager);
}
//
// Try MAXIMUM_ALLOWED desired access
//
status = TestOpenSCManager(
&hScManager,
NULL,
MAXIMUM_ALLOWED,
NO_ERROR
);
if (status == NO_ERROR) {
(void) TestEnumServicesStatus(
hScManager,
NO_ERROR
);
(void) CloseServiceHandle(hScManager);
}
}
DWORD
TestOpenSCManager(
OUT LPSC_HANDLE hScManager,
IN LPWSTR DatabaseName,
IN DWORD DesiredAccess,
IN DWORD ExpectedError
)
{
DWORD status = NO_ERROR;
if (DatabaseName != NULL) {
printf("OpenSCManager: DatabaseName=%ws, DesiredAccess=%08lx\n",
DatabaseName, DesiredAccess);
}
else {
printf("OpenSCManager: DatabaseName=(null), DesiredAccess=%08lx\n",
DesiredAccess);
}
*hScManager = OpenSCManager(
NULL,
DatabaseName,
DesiredAccess
);
if (*hScManager == (SC_HANDLE) NULL) {
status = GetLastError();
if (ExpectedError != status) {
printf(" FAILED. Expected %lu, got %lu\n",
ExpectedError, status);
return status;
}
}
else {
if (ExpectedError != NO_ERROR) {
printf(" FAILED. Expected %lu, got NO_ERROR\n",
ExpectedError);
return NO_ERROR;
}
}
printf(" Got %lu as expected\n", status);
return status;
}
DWORD
TestOpenService(
IN SC_HANDLE hScManager,
OUT LPSC_HANDLE hService,
IN LPWSTR ServiceName,
IN DWORD DesiredAccess,
IN DWORD ExpectedError
)
{
DWORD status = NO_ERROR;
printf("OpenService: ServiceName=%ws, DesiredAccess=%08lx\n",
ServiceName, DesiredAccess);
*hService = OpenService(
hScManager,
ServiceName,
DesiredAccess
);
if (*hService == (SC_HANDLE) NULL) {
status = GetLastError();
if (ExpectedError != status) {
printf(" FAILED. Expected %lu, got %lu\n",
ExpectedError, status);
return status;
}
}
else {
if (ExpectedError != NO_ERROR) {
printf(" FAILED. Expected %lu, got NO_ERROR\n",
ExpectedError);
return NO_ERROR;
}
}
printf(" Got %lu as expected\n", status);
return status;
}
DWORD
TestEnumServicesStatus(
IN SC_HANDLE hSCManager,
IN DWORD ExpectedError
)
{
DWORD status = NO_ERROR;
BYTE OutputBuffer[1024];
LPENUM_SERVICE_STATUS EnumBuffer = (LPENUM_SERVICE_STATUS) OutputBuffer;
DWORD BytesNeeded;
DWORD EntriesRead;
DWORD i;
if (! EnumServicesStatus(
hSCManager,
SERVICE_TYPE_ALL,
SERVICE_STATE_ALL,
EnumBuffer,
1024,
&BytesNeeded,
&EntriesRead,
NULL
)) {
status = GetLastError();
}
if (ExpectedError != status) {
printf(" FAILED. Expected %lu, got %lu\n",
ExpectedError, status);
return status;
}
else {
printf(" Got %lu as expected\n", status);
}
if ((status == NO_ERROR) || (status == ERROR_MORE_DATA)) {
for (i = 0; i < EntriesRead; i++) {
for (i = 0; i < EntriesRead; i++) {
DisplayStatus(
EnumBuffer->lpServiceName,
&(EnumBuffer->ServiceStatus));
EnumBuffer++;
}
}
}
return status;
}
DWORD
TestQueryServiceStatus(
IN SC_HANDLE hService,
IN DWORD ExpectedError
)
{
DWORD status = NO_ERROR;
SERVICE_STATUS ServiceStatus;
printf("QueryService: \n");
if (! QueryServiceStatus(
hService,
&ServiceStatus
)) {
status = GetLastError();
}
if (ExpectedError != status) {
printf(" FAILED. Expected %lu, got %lu\n",
ExpectedError, status);
return status;
}
if (status == NO_ERROR) {
DisplayStatus(NULL, &ServiceStatus);
}
printf(" Got %lu as expected\n", status);
return status;
}
DWORD
TestControlService(
IN SC_HANDLE hService,
IN DWORD ControlCode,
IN DWORD ExpectedError
)
{
DWORD status = NO_ERROR;
SERVICE_STATUS ServiceStatus;
printf("ControlService: Control=%08lx\n", ControlCode);
if (! ControlService(
hService,
ControlCode,
&ServiceStatus
)) {
status = GetLastError();
}
if (ExpectedError != status) {
printf(" FAILED. Expected %lu, got %lu\n",
ExpectedError, status);
return status;
}
if (status == NO_ERROR) {
DisplayStatus(NULL, &ServiceStatus);
}
printf(" Got %lu as expected\n", status);
return status;
}
DWORD
TestStartService(
IN SC_HANDLE hService,
IN DWORD ExpectedError
)
{
DWORD status = NO_ERROR;
printf("StartService: \n");
if (! StartService(
hService,
0,
NULL
)) {
status = GetLastError();
}
if (ExpectedError != status) {
printf(" FAILED. Expected %lu, got %lu\n",
ExpectedError, status);
return status;
}
printf(" Got %lu as expected\n", status);
return status;
}
VOID
DisplayStatus(
IN LPWSTR ServiceName OPTIONAL,
IN LPSERVICE_STATUS ServiceStatus
)
/*++
Routine Description:
Displays the service name and the service status.
|
|SERVICE_NAME: messenger
| TYPE : WIN32
| STATE : ACTIVE SERVICE_STOPPABLE SERVICE_PAUSABLE
| EXIT_CODE : 0xC002001
| CHECKPOINT : 0x00000001
| WAIT_HINT : 0x00003f21
|
Arguments:
ServiceName - This is a pointer to a string containing the name of
the service.
ServiceStatus - This is a pointer to a SERVICE_STATUS structure from
which information is to be displayed.
Return Value:
none.
--*/
{
if (ARGUMENT_PRESENT(ServiceName)) {
printf("\nSERVICE_NAME: %ws\n", ServiceName);
}
printf(" TYPE : %lx ", ServiceStatus->dwServiceType);
switch(ServiceStatus->dwServiceType){
case SERVICE_WIN32:
printf("WIN32 \n");
break;
case SERVICE_DRIVER:
printf("DRIVER \n");
break;
default:
printf(" ERROR \n");
}
printf(" STATE : %lx ", ServiceStatus->dwCurrentState);
switch(ServiceStatus->dwCurrentState){
case SERVICE_STOPPED:
printf("STOPPED ");
break;
case SERVICE_START_PENDING:
printf("START_PENDING ");
break;
case SERVICE_STOP_PENDING:
printf("STOP_PENDING ");
break;
case SERVICE_RUNNING:
printf("RUNNING ");
break;
case SERVICE_CONTINUE_PENDING:
printf("CONTINUE_PENDING ");
break;
case SERVICE_PAUSE_PENDING:
printf("PAUSE_PENDING ");
break;
case SERVICE_PAUSED:
printf("PAUSED ");
break;
default:
printf(" ERROR ");
}
//
// Print Controls Accepted Information
//
if (ServiceStatus->dwControlsAccepted & SERVICE_ACCEPT_STOP) {
printf(" (STOPPABLE,");
}
else {
printf(" (NOT_STOPPABLE,");
}
if (ServiceStatus->dwControlsAccepted & SERVICE_ACCEPT_PAUSE_CONTINUE) {
printf("PAUSABLE )\n");
}
else {
printf("NOT_PAUSABLE )\n");
}
//
// Print Exit Code
//
printf(" WIN32_EXIT_CODE : 0x%lx\n", ServiceStatus->dwWin32ExitCode );
printf(" SERVICE_EXIT_CODE : 0x%lx\n",
ServiceStatus->dwServiceSpecificExitCode );
//
// Print CheckPoint & WaitHint Information
//
printf(" CHECKPOINT : 0x%lx\n", ServiceStatus->dwCheckPoint);
printf(" WAIT_HINT : 0x%lx\n", ServiceStatus->dwWaitHint );
return;
}