Microsoft KB Archive/301037

= BUG: Service Auditing Fails on Windows 2000 =

Article ID: 301037

Article Last Modified on 11/21/2006

-

APPLIES TO


 * Microsoft Win32 Application Programming Interface, when used with:
 * Microsoft Windows 2000 Standard Edition

-



This article was previously published under Q301037



SYMPTOMS
A service is a securable object that should be auditable. However, on Windows 2000 prior to Service Pack 2, access to a service object does not generate the expected audit events in the security log.



STATUS
Microsoft has confirmed that this is a bug in the Microsoft products that are listed at the beginning of this article.

This bug was corrected in Windows 2000 Service Pack (SP) 2.



MORE INFORMATION
Access to a securable object can be audited on Windows NT and Windows 2000 as long as the following is true:
 * 1) An administrator has enabled the Audit object access entry within the system's Local Security Policy.
 * 2) The object's security descriptor has a system access-control list (SACL) that contains the necessary access control entries (ACEs) specifying which users should be audited.

On Windows NT 4.0 and Windows 2000 with SP2, auditing works as detailed below for service objects:
 * When a service handle is opened, an audit event with ID 560 is logged in the security log.
 * When a service handle is closed, an audit event with ID 562 is logged in the security log.

Sample Code
The following sample code can be used to audit both successful and failed access to a service. This code adds a SACL to the security descriptor for the service. The SACL contains an ACE for the Everyone group.


 * 1) include 
 * 2) include 

void ReportError(char* apiName) {

LPVOID lpMsgBuf; char  szMsg[4096];

FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER        | FORMAT_MESSAGE_FROM_SYSTEM         | FORMAT_MESSAGE_IGNORE_INSERTS,         NULL, GetLastError,         MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),         (LPTSTR) &lpMsgBuf, 0, NULL );

printf(szMsg, &quot;%s failed with error %ld\n%s&quot;, apiName,         GetLastError, lpMsgBuf); LocalFree(lpMsgBuf); }

BOOL EnableSecurityName {

// A process that tries to read or write a SACL needs // to have and enable the SE_SECURITY_NAME privilege. LUID  SecurityNameValue; HANDLE hToken; TOKEN_PRIVILEGES tp;

if (!OpenProcessToken(GetCurrentProcess, TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken)) { ReportError(&quot;OpenProcessToken&quot;); return FALSE; }

if (!LookupPrivilegeValue(NULL, SE_SECURITY_NAME, &SecurityNameValue)) { ReportError(&quot;LookupPrivilegeValue&quot;); return FALSE; }

tp.PrivilegeCount = 1; tp.Privileges[0].Luid = SecurityNameValue; tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;

if (!AdjustTokenPrivileges(hToken, FALSE, &tp, sizeof(tp), NULL, NULL)) { ReportError(&quot;AdjustTokenPrivileges&quot;); return FALSE; }

return TRUE ; }

BOOL AddEveryoneAceToServiceSacl(SC_HANDLE hObjectHandle,     DWORD dwAccessMask) {

BOOL bReturn   = FALSE; PSID psidWorld = NULL; PACL pNewACL   = NULL; DWORD dwNewACLSize; UCHAR NewSD[SECURITY_DESCRIPTOR_MIN_LENGTH];

SID_IDENTIFIER_AUTHORITY authWorld = SECURITY_WORLD_SID_AUTHORITY;

__try {

// Build the &quot;Everyone&quot; SID if (!AllocateAndInitializeSid(&authWorld, 1, SECURITY_WORLD_RID, 0, 0, 0, 0, 0, 0, 0, &psidWorld)) { ReportError(&quot;AllocateAndInitializeSid&quot;); __leave; }

// Initialize new SD     if (!InitializeSecurityDescriptor(&NewSD, SECURITY_DESCRIPTOR_REVISION)) { ReportError(&quot;InitializeSecurityDescriptor&quot;); __leave; }

// Compute size needed for the new ACL dwNewACLSize = sizeof(ACL) + sizeof(ACCESS_ALLOWED_ACE) + GetLengthSid(psidWorld) - sizeof(DWORD); // Allocate memory for new ACL pNewACL = (PACL) HeapAlloc(GetProcessHeap, 0, dwNewACLSize); if (!pNewACL) { ReportError(&quot;HeapAlloc&quot;); __leave; }

// Initialize the new ACL if (!InitializeAcl(pNewACL, dwNewACLSize, ACL_REVISION2)) { ReportError(&quot;InitializeAcl&quot;); __leave; }     // Add the audit ACE to the new SACL if (!AddAuditAccessAce(pNewACL, ACL_REVISION2, dwAccessMask, psidWorld, TRUE /* Audit Success */, TRUE /* Audit Failure */)) { ReportError(&quot;AddAuditAccessAce&quot;); __leave; }

// Add the SACL to the new SD     if (!SetSecurityDescriptorSacl(&NewSD, TRUE, pNewACL, FALSE)) { ReportError(&quot;SetSecurityDescriptorSacl&quot;); __leave; }

// Set the security on the service using the new SD     if (!SetServiceObjectSecurity(hObjectHandle, SACL_SECURITY_INFORMATION, &NewSD)) { ReportError(&quot;SetServiceObjectSecurity&quot;); __leave; }

bReturn = TRUE; }  __finally {     // Free the allocated SID. if (psidWorld) FreeSid(psidWorld);

// Free the memory allocated for the new ACL. if (pNewACL) HeapFree(GetProcessHeap, 0, pNewACL); }

return bReturn; }

void main(int argc, char *argv[]) {

SC_HANDLE hSCM    = NULL; SC_HANDLE hService = NULL;

if (argc != 2) { printf(&quot;Usage: %s \n&quot;, argv[0]); return; }

__try {

// Enable the SE_SECURITY_NAME privilege. if (!EnableSecurityName) __leave;

hSCM = OpenSCManager(NULL, 0, SC_MANAGER_ALL_ACCESS); if (!hSCM) { ReportError(&quot;OpenSCManager&quot;); __leave; }

hService = OpenService(hSCM, argv[1],           SERVICE_ALL_ACCESS | ACCESS_SYSTEM_SECURITY); if (!hService) { ReportError(&quot;OpenService&quot;); __leave; }

// Add the ACE to the SACL. if (!AddEveryoneAceToServiceSacl(hService, GENERIC_ALL | ACCESS_SYSTEM_SECURITY)) printf(&quot;Could not add audit entry to SACL\n&quot;); else printf(&quot;Added audit entry to SACL\n&quot;);

// NOTE //      // The following audit mask combinations duplicate the // different audit settings that you can apply to files // using Explorer in Windows NT 4.0 //      // Read                FILE_GENERIC_READ | ACCESS_SYSTEM_SECURITY // Write              FILE_GENERIC_WRITE | ACCESS_SYSTEM_SECURITY // Execute            FILE_GENERIC_EXECUTE // Delete             DELETE // Change Permissions WRITE_DAC // Write Owner        WRITE_OWNER

} __finally {

if (hService) CloseServiceHandle(hService);

if (hSCM)     CloseServiceHandle(hSCM); }

}

Keywords: kbacl kbapi kbbug kbnofix kbsechack kbsecurity kbsecvulnerability kbservice KB301037

-

[mailto:TECHNET@MICROSOFT.COM Send feedback to Microsoft]

© Microsoft Corporation. All rights reserved.