Leaked source code of windows server 2003
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.
 
 
 
 
 
 

1120 lines
31 KiB

/*++
Copyright (c) 1997-1999 Microsoft Corporation
Module Name:
wmisecur.c
Abstract:
Wmi security tool
Author:
16-Jan-1997 AlanWar
Revision History:
5-20-2002 DamianH: Added new parameter so that the SD is printed
in SDDL format (querysddl). Fix ChangePrivs so that the privilege
is actually disabled.
--*/
#define INITGUID
#include <nt.h>
#include <ntrtl.h>
#include <nturtl.h>
#include <windows.h>
#include <ole2.h>
#include <stdio.h>
#include <stdlib.h>
#include <aclapi.h>
#include <sddl.h> // For ConvertSecurityDescriptorToStringSecurityDescriptor
#include <tchar.h> // For TCHAR
#include "wmium.h"
#include "wmiumkm.h"
void EditGuidSecurity(
LPTSTR GuidString,
LPGUID Guid
);
#define SE_WMIGUID_OBJECT 11
#define WMI_SECURITY_REGSTR "SYSTEM\\CurrentControlSet\\Control\\WMI\\Security"
#define WmipAllocEvent() CreateEvent(NULL, FALSE, FALSE, NULL)
#define WmipFreeEvent(EventHandle) CloseHandle(EventHandle)
HANDLE WmipKMHandle;
ULONG PrintSecurityString(LPSTR Guid, BOOL fPrintSDDL);
ULONG ChangePrivs(
BOOLEAN Enable
)
{
HANDLE Token;
PTOKEN_PRIVILEGES NewPrivileges;
PBYTE pbOldPriv;
BYTE OldPriv[2048];
ULONG cbNeeded;
LUID LuidPrivilege;
ULONG Status;
if (OpenProcessToken( GetCurrentProcess(),
TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,
&Token))
{
cbNeeded = 0;
//
// Initialize the privilege adjustment structure
//
LookupPrivilegeValue( NULL, SE_SECURITY_NAME, &LuidPrivilege );
NewPrivileges = (PTOKEN_PRIVILEGES)malloc( sizeof(TOKEN_PRIVILEGES) +
sizeof(LUID_AND_ATTRIBUTES)
);
if (NewPrivileges != NULL)
{
NewPrivileges->PrivilegeCount = 1;
NewPrivileges->Privileges[0].Luid = LuidPrivilege;
NewPrivileges->Privileges[0].Attributes = Enable ?
SE_PRIVILEGE_ENABLED : 0;
//
// Enable the privilege
//
pbOldPriv = OldPriv;
if (AdjustTokenPrivileges( Token,
FALSE,
NewPrivileges,
sizeof( OldPriv ),
(PTOKEN_PRIVILEGES)pbOldPriv,
&cbNeeded
))
{
CloseHandle(Token);
if (OpenProcessToken( GetCurrentProcess(),
TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,
&Token))
{
printf("token is %p\n", Token);
}
Status = ERROR_SUCCESS;
} else {
Status = GetLastError();
free( NewPrivileges );
NewPrivileges = NULL;
}
} else {
Status = ERROR_NOT_ENOUGH_MEMORY;
}
CloseHandle( Token );
} else {
Status = GetLastError();
}
return(Status);
}
ULONG WmipSendWmiKMRequest(
ULONG Ioctl,
PVOID Buffer,
ULONG InBufferSize,
ULONG MaxBufferSize,
ULONG *ReturnSize
)
/*+++
Routine Description:
This routine does the work of sending WMI requests to the WMI kernel
mode device. Any retry errors returned by the WMI device are handled
in this routine.
Arguments:
Ioctl is the IOCTL code to send to the WMI device
Buffer is the input and output buffer for the call to the WMI device
InBufferSize is the size of the buffer passed to the device
MaxBufferSize is the maximum number of bytes that can be written
into the buffer
*ReturnSize on return has the actual number of bytes written in buffer
Return Value:
ERROR_SUCCESS or an error code
---*/
{
OVERLAPPED Overlapped;
ULONG Status;
BOOL IoctlSuccess;
if (WmipKMHandle == NULL)
{
//
// If device is not open for then open it now. The
// handle is closed in the process detach dll callout (DlllMain)
WmipKMHandle = CreateFile(WMIDataDeviceName,
GENERIC_READ | GENERIC_WRITE,
0,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL |
FILE_FLAG_OVERLAPPED,
NULL);
if (WmipKMHandle == (HANDLE)-1)
{
WmipKMHandle = NULL;
return(GetLastError());
}
}
Overlapped.hEvent = WmipAllocEvent();
if (Overlapped.hEvent == NULL)
{
return(ERROR_NOT_ENOUGH_MEMORY);
}
do
{
IoctlSuccess = DeviceIoControl(WmipKMHandle,
Ioctl,
Buffer,
InBufferSize,
Buffer,
MaxBufferSize,
ReturnSize,
&Overlapped);
if (GetLastError() == ERROR_IO_PENDING)
{
IoctlSuccess = GetOverlappedResult(WmipKMHandle,
&Overlapped,
ReturnSize,
TRUE);
}
if (! IoctlSuccess)
{
Status = GetLastError();
} else {
Status = ERROR_SUCCESS;
}
} while (Status == ERROR_WMI_TRY_AGAIN);
WmipFreeEvent(Overlapped.hEvent);
return(Status);
}
#ifdef SET_SECURITY_BY_HANDLE
ULONG WmipOpenKernelGuid(
LPGUID Guid,
ACCESS_MASK DesiredAccess,
PHANDLE Handle
)
{
WMIOPENGUIDBLOCK WmiOpenGuidBlock;
ULONG ReturnSize;
ULONG Status;
WmiOpenGuidBlock.Guid = *Guid;
WmiOpenGuidBlock.DesiredAccess = DesiredAccess;
Status = WmipSendWmiKMRequest(IOCTL_WMI_OPEN_GUID,
(PVOID)&WmiOpenGuidBlock,
sizeof(WMIOPENGUIDBLOCK),
sizeof(WMIOPENGUIDBLOCK),
&ReturnSize);
if (Status == ERROR_SUCCESS)
{
*Handle = WmiOpenGuidBlock.Handle;
} else {
*Handle = NULL;
}
return(Status);
}
#endif
ULONG SetWmiGuidSecurityInfo(
LPGUID Guid,
SECURITY_INFORMATION SecurityInformation,
PSID OwnerSid,
PSID GroupSid,
PACL Dacl,
PACL Sacl
)
{
HANDLE Handle;
ULONG Status;
#ifdef SET_SECURITY_BY_HANDLE
Status = WmipOpenKernelGuid(Guid,
WRITE_DAC | WRITE_OWNER,
&Handle);
if (Status == ERROR_SUCCESS)
{
Status = SetSecurityInfo(Handle,
SE_KERNEL_OBJECT,
SecurityInformation,
OwnerSid,
GroupSid,
Dacl,
Sacl);
CloseHandle(Handle);
}
#else
PCHAR GuidName;
Status = UuidToString(Guid,
&GuidName);
if (Status == ERROR_SUCCESS)
{
Status = SetNamedSecurityInfo(GuidName,
SE_WMIGUID_OBJECT,
SecurityInformation,
OwnerSid,
GroupSid,
Dacl,
Sacl);
RpcStringFree(&GuidName);
}
#endif
return(Status);
}
ULONG GetWmiGuidSecurityInfo(
LPGUID Guid,
SECURITY_INFORMATION SecurityInformation,
PSID *OwnerSid,
PSID *GroupSid,
PACL *Dacl,
PACL *Sacl,
PSECURITY_DESCRIPTOR *Sd
)
{
HANDLE Handle;
ULONG Status;
#ifdef SET_SECURITY_BY_HANDLE
Status = WmipOpenKernelGuid(Guid,
READ_CONTROL,
&Handle);
if (Status == ERROR_SUCCESS)
{
Status = GetSecurityInfo(Handle,
SE_KERNEL_OBJECT,
SecurityInformation,
OwnerSid,
GroupSid,
Dacl,
Sacl,
Sd);
CloseHandle(Handle);
}
#else
PCHAR GuidName;
Status = UuidToString(Guid,
&GuidName);
if (Status == ERROR_SUCCESS)
{
Status = GetNamedSecurityInfo(GuidName,
SE_WMIGUID_OBJECT,
SecurityInformation,
OwnerSid,
GroupSid,
Dacl,
Sacl,
Sd);
RpcStringFree(&GuidName);
}
#endif
return(Status);
}
//
// The routines below were blantenly stolen without remorse from the ole
// sources in \nt\private\ole32\com\class\compapi.cxx. They are copied here
// so that WMI doesn't need to load in ole32 only to convert a guid string
// into its binary representation.
//
//+-------------------------------------------------------------------------
//
// Function: HexStringToDword (private)
//
// Synopsis: scan lpsz for a number of hex digits (at most 8); update lpsz
// return value in Value; check for chDelim;
//
// Arguments: [lpsz] - the hex string to convert
// [Value] - the returned value
// [cDigits] - count of digits
//
// Returns: TRUE for success
//
//--------------------------------------------------------------------------
BOOL HexStringToDword(LPCSTR lpsz, DWORD * RetValue,
int cDigits, WCHAR chDelim)
{
int Count;
DWORD Value;
Value = 0;
for (Count = 0; Count < cDigits; Count++, lpsz++)
{
if (*lpsz >= '0' && *lpsz <= '9')
Value = (Value << 4) + *lpsz - '0';
else if (*lpsz >= 'A' && *lpsz <= 'F')
Value = (Value << 4) + *lpsz - 'A' + 10;
else if (*lpsz >= 'a' && *lpsz <= 'f')
Value = (Value << 4) + *lpsz - 'a' + 10;
else
return(FALSE);
}
*RetValue = Value;
if (chDelim != 0)
return *lpsz++ == chDelim;
else
return TRUE;
}
//+-------------------------------------------------------------------------
//
// Function: wUUIDFromString (internal)
//
// Synopsis: Parse UUID such as 00000000-0000-0000-0000-000000000000
//
// Arguments: [lpsz] - Supplies the UUID string to convert
// [pguid] - Returns the GUID.
//
// Returns: TRUE if successful
//
//--------------------------------------------------------------------------
BOOL wUUIDFromString(LPCSTR lpsz, LPGUID pguid)
{
DWORD dw;
if (!HexStringToDword(lpsz, &pguid->Data1, sizeof(DWORD)*2, '-'))
return FALSE;
lpsz += sizeof(DWORD)*2 + 1;
if (!HexStringToDword(lpsz, &dw, sizeof(WORD)*2, '-'))
return FALSE;
lpsz += sizeof(WORD)*2 + 1;
pguid->Data2 = (WORD)dw;
if (!HexStringToDword(lpsz, &dw, sizeof(WORD)*2, '-'))
return FALSE;
lpsz += sizeof(WORD)*2 + 1;
pguid->Data3 = (WORD)dw;
if (!HexStringToDword(lpsz, &dw, sizeof(BYTE)*2, 0))
return FALSE;
lpsz += sizeof(BYTE)*2;
pguid->Data4[0] = (BYTE)dw;
if (!HexStringToDword(lpsz, &dw, sizeof(BYTE)*2, '-'))
return FALSE;
lpsz += sizeof(BYTE)*2+1;
pguid->Data4[1] = (BYTE)dw;
if (!HexStringToDword(lpsz, &dw, sizeof(BYTE)*2, 0))
return FALSE;
lpsz += sizeof(BYTE)*2;
pguid->Data4[2] = (BYTE)dw;
if (!HexStringToDword(lpsz, &dw, sizeof(BYTE)*2, 0))
return FALSE;
lpsz += sizeof(BYTE)*2;
pguid->Data4[3] = (BYTE)dw;
if (!HexStringToDword(lpsz, &dw, sizeof(BYTE)*2, 0))
return FALSE;
lpsz += sizeof(BYTE)*2;
pguid->Data4[4] = (BYTE)dw;
if (!HexStringToDword(lpsz, &dw, sizeof(BYTE)*2, 0))
return FALSE;
lpsz += sizeof(BYTE)*2;
pguid->Data4[5] = (BYTE)dw;
if (!HexStringToDword(lpsz, &dw, sizeof(BYTE)*2, 0))
return FALSE;
lpsz += sizeof(BYTE)*2;
pguid->Data4[6] = (BYTE)dw;
if (!HexStringToDword(lpsz, &dw, sizeof(BYTE)*2, 0))
return FALSE;
lpsz += sizeof(BYTE)*2;
pguid->Data4[7] = (BYTE)dw;
return TRUE;
}
//+-------------------------------------------------------------------------
//
// Function: wGUIDFromString (internal)
//
// Synopsis: Parse GUID such as {00000000-0000-0000-0000-000000000000}
//
// Arguments: [lpsz] - the guid string to convert
// [pguid] - guid to return
//
// Returns: TRUE if successful
//
//--------------------------------------------------------------------------
BOOL wGUIDFromString(LPCSTR lpsz, LPGUID pguid)
{
DWORD dw;
if (*lpsz == '{' )
lpsz++;
if(wUUIDFromString(lpsz, pguid) != TRUE)
return FALSE;
lpsz +=36;
if (*lpsz == '}' )
lpsz++;
if (*lpsz != '\0') // check for zero terminated string - test bug #18307
{
return FALSE;
}
return TRUE;
}
ULONG RemoveWmiSD(
LPGUID Guid
)
{
CHAR GuidName[MAX_PATH];
HKEY RegistryKey;
ULONG Status;
Status = RegOpenKey(HKEY_LOCAL_MACHINE,
"System\\CurrentControlSet\\Control\\Wmi\\Security",
&RegistryKey);
if (Status != ERROR_SUCCESS)
{
printf("RegOpenKey returned %d\n", Status);
return(Status);
}
if (Guid != NULL)
{
wsprintf(GuidName, "%08x-%04x-%04x-%02x%02x%02x%02x%02x%02x%02x%02x",
Guid->Data1, Guid->Data2,
Guid->Data3,
Guid->Data4[0], Guid->Data4[1],
Guid->Data4[2], Guid->Data4[3],
Guid->Data4[4], Guid->Data4[5],
Guid->Data4[6], Guid->Data4[7]);
} else {
strcpy(GuidName, "00000000-0000-0000-0000000000000000");
}
RegDeleteValue(RegistryKey,
GuidName);
RegCloseKey(RegistryKey);
return(ERROR_SUCCESS);
}
void Usage(
void
)
{
printf("wmisecur <guid> [query | querysddl | edit | owner | group | dacl | adacl] [parameters]\n");
printf(" wmisecur <guid> query\n");
printf(" queries and prints the security string appropriate for inclusion in INF file\n\n");
printf(" wmisecur <guid> querysddl\n");
printf(" queries and prints the security string as SDDL\n\n");
printf(" wmisecur <guid> querysddl\n");
printf(" queries and prints the security descriptor in SDDL format\n\n");
printf(" wmisecur <guid> edit\n");
printf(" opens a security descriptor property sheet for editing the DACL of the guid\n\n");
printf(" wmisecur <guid> owner <account name>\n");
printf(" sets owner of guid to be <account name>\n\n");
printf(" wmisecur <guid> group <account name>\n");
printf(" sets group of guid to be <account name>\n\n");
printf(" wmisecur <guid> dacl <account name> [allow | deny] <right1> <right2> ....\n");
printf(" resets dacl to assign <right1>, <right2>, ... to <account name>\n\n");
printf(" wmisecur <guid> adacl <account name> [allow | deny] <right1> <right2> ....\n");
printf(" appends ace to dacl,<right1>, <right2>, ... assigned to <account name>\n\n");
printf(" Rights: WMIGUID_QUERY\n");
printf(" WMIGUID_SET\n");
printf(" WMIGUID_NOTIFICATION\n");
printf(" WMIGUID_READ_DESCRIPTION\n");
printf(" WMIGUID_EXECUTE\n");
printf(" TRACELOG_CREATE_REALTIME\n");
printf(" TRACELOG_CREATE_ONDISK\n");
printf(" TRACELOG_GUID_ENABLE\n");
printf(" TRACELOG_ACCESS_KERNEL_LOGGER\n");
printf(" TRACELOG_CREATE_INPROC\n");
printf(" TRACELOG_ACCESS_REALTIME\n");
printf(" READ_CONTROL\n");
printf(" WRITE_DAC\n");
printf(" WRITE_OWNER\n");
printf(" DELETE\n");
printf(" SYNCHRONIZE\n");
printf(" ALL (all wmi specific rights)\n");
printf(" ALLRIGHTS (STANDARD_RIGHTS_ALL | SPECIFIC_RIGHTS_ALL)\n");
printf(" Examples:\n");
printf(" wmisecur 78ebc105-4cf9-11d2-ba4a-00a0c9062910 edit\n\n");
printf(" wmisecur 78ebc105-4cf9-11d2-ba4a-00a0c9062910 query\n");
}
typedef enum
{
SetOwner,
SetGroup,
ResetDacl,
AppendDacl,
CopyDacl,
QueryGuid,
EditGuid,
ResetSACL,
CopySACL,
AppendSACL,
QueryGuidSDDL
} OPERATION;
typedef enum
{
Allow,
Deny
} ALLOWORDENY;
ULONG SetOwnerOrGroup(
OPERATION Operation,
LPGUID Guid,
PSID Sid
)
{
ULONG Status;
if (Operation == SetOwner)
{
Status = SetWmiGuidSecurityInfo(Guid,
OWNER_SECURITY_INFORMATION,
Sid,
NULL,
NULL,
NULL);
} else {
Status = SetWmiGuidSecurityInfo(Guid,
GROUP_SECURITY_INFORMATION,
NULL,
Sid,
NULL,
NULL);
}
return(Status);
}
ULONG ResetOrAppendDacl(
OPERATION Operation,
LPGUID Guid,
PSID Sid,
ALLOWORDENY AllowOrDeny,
ULONG Rights
)
{
ULONG Status;
PSECURITY_DESCRIPTOR OldSD;
PACL OldDacl, NewDacl;
UCHAR NewDaclBuffer[512];
NewDacl = (PACL)NewDaclBuffer;
if ((Operation == AppendDacl) || (Operation == CopyDacl))
{
Status = GetWmiGuidSecurityInfo(Guid,
DACL_SECURITY_INFORMATION,
NULL,
NULL,
&OldDacl,
NULL,
&OldSD);
if (Status != ERROR_SUCCESS)
{
return(Status);
}
memcpy(NewDacl, OldDacl, OldDacl->AclSize);
LocalFree(OldSD);
NewDacl->AclSize = sizeof(NewDaclBuffer);
} else {
RtlCreateAcl(NewDacl,
sizeof(NewDaclBuffer),
ACL_REVISION);
}
if (Operation != CopyDacl)
{
if (AllowOrDeny == Deny)
{
if (! AddAccessDeniedAce(NewDacl,
ACL_REVISION,
Rights,
Sid))
{
return(GetLastError());
}
} else {
if (! AddAccessAllowedAce(NewDacl,
ACL_REVISION,
Rights,
Sid))
{
return(GetLastError());
}
}
}
Status = SetWmiGuidSecurityInfo(Guid,
DACL_SECURITY_INFORMATION,
NULL,
NULL,
NewDacl,
NULL);
return(Status);
}
ULONG ResetOrAppendSacl(
OPERATION Operation,
LPGUID Guid,
PSID Sid,
ALLOWORDENY AllowOrDeny,
ULONG Rights
)
{
ULONG Status;
PSECURITY_DESCRIPTOR OldSD;
PACL OldDacl, NewDacl;
UCHAR NewDaclBuffer[512];
Status = ChangePrivs(TRUE);
if (Status == ERROR_SUCCESS)
{
NewDacl = (PACL)NewDaclBuffer;
if ((Operation == AppendSACL) || (Operation == CopySACL))
{
Status = GetWmiGuidSecurityInfo(Guid,
SACL_SECURITY_INFORMATION,
NULL,
NULL,
NULL,
&OldDacl,
&OldSD);
if (Status != ERROR_SUCCESS)
{
return(Status);
}
memcpy(NewDacl, OldDacl, OldDacl->AclSize);
LocalFree(OldSD);
NewDacl->AclSize = sizeof(NewDaclBuffer);
} else {
RtlCreateAcl(NewDacl,
sizeof(NewDaclBuffer),
ACL_REVISION);
}
if (Operation != CopySACL)
{
if (AllowOrDeny == Deny)
{
if (! AddAccessDeniedAce(NewDacl,
ACL_REVISION,
Rights,
Sid))
{
return(GetLastError());
}
} else {
if (! AddAccessAllowedAce(NewDacl,
ACL_REVISION,
Rights,
Sid))
{
return(GetLastError());
}
}
}
Status = SetWmiGuidSecurityInfo(Guid,
SACL_SECURITY_INFORMATION,
NULL,
NULL,
NULL,
NewDacl);
ChangePrivs(FALSE);
}
return(Status);
}
BOOLEAN RightNameToDWord(
PCHAR RightName,
PDWORD RightDWord
)
{
*RightDWord = 0;
if (_stricmp(RightName, "WMIGUID_QUERY") == 0)
{
*RightDWord = WMIGUID_QUERY;
} else if (_stricmp(RightName, "WMIGUID_SET") == 0) {
*RightDWord = WMIGUID_SET;
} else if (_stricmp(RightName, "WMIGUID_NOTIFICATION") == 0) {
*RightDWord = WMIGUID_NOTIFICATION;
} else if (_stricmp(RightName, "WMIGUID_READ_DESCRIPTION") == 0) {
*RightDWord = WMIGUID_READ_DESCRIPTION;
} else if (_stricmp(RightName, "WMIGUID_EXECUTE") == 0) {
*RightDWord = WMIGUID_EXECUTE;
} else if (_stricmp(RightName, "TRACELOG_CREATE_REALTIME") == 0) {
*RightDWord = TRACELOG_CREATE_REALTIME;
} else if (_stricmp(RightName, "TRACELOG_CREATE_ONDISK") == 0) {
*RightDWord = TRACELOG_CREATE_ONDISK;
} else if (_stricmp(RightName, "TRACELOG_GUID_ENABLE") == 0) {
*RightDWord = TRACELOG_GUID_ENABLE;
} else if (_stricmp(RightName, "TRACELOG_ACCESS_KERNEL_LOGGER") == 0) {
*RightDWord = TRACELOG_ACCESS_KERNEL_LOGGER;
} else if (_stricmp(RightName, "TRACELOG_CREATE_INPROC") == 0) {
*RightDWord = TRACELOG_CREATE_INPROC;
} else if (_stricmp(RightName, "TRACELOG_ACCESS_REALTIME") == 0) {
*RightDWord = TRACELOG_ACCESS_REALTIME;
} else if (_stricmp(RightName, "READ_CONTROL") == 0) {
*RightDWord = READ_CONTROL;
} else if (_stricmp(RightName, "WRITE_DAC") == 0) {
*RightDWord = WRITE_DAC;
} else if (_stricmp(RightName, "WRITE_OWNER") == 0) {
*RightDWord = WRITE_OWNER;
} else if (_stricmp(RightName, "WRITE_DAC") == 0) {
*RightDWord = WRITE_DAC;
} else if (_stricmp(RightName, "DELETE") == 0) {
*RightDWord = DELETE;
} else if (_stricmp(RightName, "SYNCHRONIZE") == 0) {
*RightDWord = SYNCHRONIZE;
} else if (_stricmp(RightName, "ALL") == 0) {
*RightDWord = WMIGUID_ALL_ACCESS;
} else if (_stricmp(RightName, "ALLRIGHTS") == 0) {
*RightDWord = STANDARD_RIGHTS_ALL | SPECIFIC_RIGHTS_ALL;
} else {
return(FALSE);
}
return(TRUE);
}
int __cdecl main(int argc, char *argv[])
{
int i;
ALLOWORDENY AllowOrDeny;
OPERATION Operation;
DWORD Rights;
DWORD NewRight;
PSID Sid;
UCHAR SidBuffer[512];
ULONG SidLength;
GUID Guid;
CHAR ReferencedDomain[512];
SID_NAME_USE SidNameUse;
ULONG ReferencedDomainSize;
ULONG Status;
if (argc <= 2)
{
Usage();
return(0);
}
if (_stricmp(argv[2], "owner") == 0)
{
Operation = SetOwner;
} else if (_stricmp(argv[2], "group") == 0) {
Operation = SetGroup;
} else if (_stricmp(argv[2], "dacl") == 0) {
Operation = ResetDacl;
} else if (_stricmp(argv[2], "adacl") == 0) {
Operation = AppendDacl;
} else if (_stricmp(argv[2], "copy") == 0) {
Operation = CopyDacl;
} else if (_stricmp(argv[2], "query") == 0) {
Operation = QueryGuid;
} else if (_stricmp(argv[2], "edit") == 0) {
Operation = EditGuid;
} else if (_stricmp(argv[2], "sacl") == 0) {
Operation = ResetSACL;
} else if (_stricmp(argv[2], "asacl") == 0) {
Operation = AppendSACL;
} else if (_stricmp(argv[2], "csacl") == 0) {
Operation = CopySACL;
} else if (_stricmp(argv[2], "querysddl") == 0) {
Operation = QueryGuidSDDL;
} else {
Usage();
return(0);
}
//
// Parse the guid parameter
if (! wUUIDFromString(argv[1], &Guid))
{
printf("Bad guid %s\n", argv[1]);
return(0);
}
if (Operation == EditGuid)
{
Status = ChangePrivs(TRUE);
if (Status == ERROR_SUCCESS)
{
EditGuidSecurity(argv[1], &Guid);
}
ChangePrivs(FALSE);
return(0);
}
if (Operation == QueryGuid)
{
if (PrintSecurityString(argv[1],FALSE))
printf("Cannot find security set for given guid\n");
return 0;
}
if (Operation == QueryGuidSDDL)
{
DWORD dwErr=ERROR_SUCCESS;
dwErr=PrintSecurityString(argv[1],TRUE);
if (ERROR_SUCCESS!=dwErr) {
printf("Cannot find security set for given guid (error: 0x%08X )\n",
dwErr);
}
return 0;
}
if (Operation == CopyDacl)
{
Status = ResetOrAppendDacl(Operation, &Guid, NULL, Allow, 0);
printf("Status is %d\n", Status);
return(Status);
}
if (Operation == CopySACL)
{
Status = ResetOrAppendSacl(Operation, &Guid, NULL, Allow, 0);
printf("Status is %d\n", Status);
return(Status);
}
if (_stricmp(argv[3], "LocalSystem") == 0)
{
//
// This is a special SID we need to build by hand
//
//
// Create SID for LocalSystem dynamically
//
Sid = (PSID)malloc(RtlLengthRequiredSid( 1 ));
if (Sid != NULL)
{
SID_IDENTIFIER_AUTHORITY NtAuthority = SECURITY_NT_AUTHORITY;
RtlInitializeSid( Sid, &NtAuthority, 1);
*(RtlSubAuthoritySid( Sid, 0 )) = SECURITY_LOCAL_SYSTEM_RID;
} else {
printf("Not enougfh memory for local system sid\n");
return(ERROR_NOT_ENOUGH_MEMORY);
}
} else {
//
// Parse the account name parameter
Sid = (PSID)SidBuffer;
SidLength = sizeof(SidBuffer);
ReferencedDomainSize = sizeof(ReferencedDomain);
if (! LookupAccountName(NULL,
argv[3],
Sid,
&SidLength,
ReferencedDomain,
&ReferencedDomainSize,
&SidNameUse))
{
printf("Error %d looking up account %s\n", GetLastError(), argv[3]);
return(0);
}
}
if ((Operation == SetOwner) ||
(Operation == SetGroup))
{
Status = SetOwnerOrGroup(Operation, &Guid, Sid);
printf("Status is %d\n", Status);
if (Status == 0) {
PrintSecurityString(argv[1],FALSE);
}
} else {
if (argc < 4)
{
Usage();
return(0);
}
if (_stricmp(argv[4], "allow") == 0)
{
AllowOrDeny = Allow;
} else if (_stricmp(argv[4], "deny") == 0) {
AllowOrDeny = Deny;
} else {
Usage();
return(0);
}
Rights = 0;
for (i = 5; i < argc; i++)
{
if (! RightNameToDWord(argv[i], &NewRight))
{
printf("Invalid right %s\n", argv[i]);
return(0);
}
Rights |= NewRight;
}
if ((Operation == AppendDacl) || (Operation == ResetDacl))
{
Status = ResetOrAppendDacl(Operation, &Guid, Sid, AllowOrDeny, Rights);
} else {
Status = ResetOrAppendSacl(Operation, &Guid, Sid, AllowOrDeny, Rights);
}
printf("Status is %d\n", Status);
if (Status == 0) {
PrintSecurityString(argv[1],FALSE);
}
}
}
ULONG
PrintSecurityString(LPSTR GuidStr, BOOL fPrintSDDL)
{
ULONG status;
HKEY hKey;
UCHAR buffer[1024]={0};
ULONG size, i;
LPTSTR pszSD=NULL;
status = RegOpenKeyEx(
HKEY_LOCAL_MACHINE,
WMI_SECURITY_REGSTR,
0L,
KEY_QUERY_VALUE,
&hKey);
if (status != ERROR_SUCCESS)
return status;
size = 1024;
status = RegQueryValueEx(
hKey,
GuidStr,
NULL,
NULL,
buffer,
&size);
if (status != ERROR_SUCCESS) {
RegCloseKey(hKey);
return status;
}
printf("\nHKLM,\"%s\",\"%s\",0x00030003,\\\n",
WMI_SECURITY_REGSTR, GuidStr);
if (!fPrintSDDL) {
for (i=0; i<size; i++) {
if ((i%16) == 0) {
if (i>0)
printf(",\\\n");
printf(" ");
printf("%02x", buffer[i]);
}
else
printf(",%02x", buffer[i]);
}
printf("\n");
}
else {
if (ConvertSecurityDescriptorToStringSecurityDescriptor(
(PSECURITY_DESCRIPTOR)buffer,
SDDL_REVISION_1,
OWNER_SECURITY_INFORMATION |
GROUP_SECURITY_INFORMATION |
DACL_SECURITY_INFORMATION |
SACL_SECURITY_INFORMATION,
&pszSD,
NULL)) {
_tprintf(_T("SD: %s"),
pszSD);
LocalFree(pszSD);
}
else {
_tprintf(_T("ConvertSecurityDescriptorToStringSecurityDescriptor failed (%d)"),
GetLastError());
return GetLastError();
}
}
RegCloseKey(hKey);
return ERROR_SUCCESS;
}