I am trying to programmatically turn on auditing for our users so that
we can use event viewer to trace DCOM issues. These users are not
computer savvy and we need to do as much programmatically for them as
possible.
I have figured out how to read the audit settings, but when I try to
write them I get an error that I have an invalid handle. I put code
in to close the handle immediately after doing the
LsaQueryInformationPolicy and it gets the same error, invalid handle.
It looks like the LsaQueryInformationPolicy call is corrupting the
handle
Has anyone been able to successfully use the LsaQueryInformationPolicy
and LsaSetInformationPolicy to turn on auditing? Any ideas would be
great, thanks!
Below is the code that I'm using. If I put a breakpoint in after the
LsaQueryInformationPolicy and CopyMemory, the audit entries do match
up with what I have, so the LsaQueryInformationPolicy is querying and
returning the data properly
===============================================
Private Type Policy_Audit_Event_Type
AuditCategorySystem As Long
AuditCategoryLogon As Long
AuditCategoryObjectAccess As Long
AuditCategoryPrivilegeUse As Long
AuditCategoryDetailedTracking As Long
AuditCategoryPolicyChange As Long
AuditCategoryAccountManagement As Long
AuditCategoryDirectoryServiceAccess As Long
AuditCategoryAccountLogon As Long
End Type
Private Type Policy_Audit_Events_Info
AuditingMode As Boolean
EventAuditingOptionsPtr As Long
MaximumAuditEventCount As Long
End Type
Private Declare Function LsaOpenPolicy Lib "advapi32.dll" ( _
SysNameLsaUnicodeStringPtr As Any, _
ptrLSAObjAttrib As Any, _
ByVal DesiredAccess As Long, _
ptrPolicyHandle As Long) As Long
Private Declare Function LsaClose Lib "advapi32.dll" ( _
ObjectHandle As Long) As Long
Private Declare Function LsaQueryInformationPolicy Lib
"advapi32.dll" ( _
ByVal PolicyHandle As Long, _
ByVal PolicyInformationClass As POLICY_INFORMATION_CLASS, _
varBuffer As Long) As Long
Private Declare Function LsaSetInformationPolicy Lib "ADVAPI32" ( _
ByRef PolicyHandle As Long, _
ByVal InformationClass As POLICY_INFORMATION_CLASS, _
buffer As Any) As Long
Private Declare Function LsaNtStatusToWinError Lib "advapi32.dll" ( _
ByVal NTStatus As Long) As Long
Private Declare Sub CopyMemory Lib "kernel32" Alias
"RtlMoveMemory" ( _
Destination As Any, _
Source As Any, _
ByVal Length As Long)
Public Const STATUS_SUCCESS As Long = 0
Public Const POLICY_VIEW_LOCAL_INFORMATION = 1
Public Const POLICY_VIEW_AUDIT_INFORMATION = 2
Public Const POLICY_GET_PRIVATE_INFORMATION = 4
Public Const POLICY_TRUST_ADMIN = 8
Public Const POLICY_CREATE_ACCOUNT = 16
Public Const POLICY_CREATE_SECRET = 32
Public Const POLICY_CREATE_PRIVILEGE = 64
Public Const POLICY_SET_DEFAULT_QUOTA_LIMITS = 128
Public Const POLICY_SET_AUDIT_REQUIREMENTS = 256
Public Const POLICY_AUDIT_LOG_ADMIN = 512
Public Const POLICY_SERVER_ADMIN = 1024
Public Const POLICY_LOOKUP_NAMES = 2048
Public Const POLICY_NOTIFICATION = 4096
Public Const GENERIC_READ = POLICY_VIEW_AUDIT_INFORMATION Or
POLICY_GET_PRIVATE_INFORMATION
Public Const GENERIC_EXECUTE = POLICY_VIEW_LOCAL_INFORMATION Or
POLICY_LOOKUP_NAMES
Public Const POLICY_ALL_ACCESS = POLICY_VIEW_LOCAL_INFORMATION Or
POLICY_VIEW_AUDIT_INFORMATION Or POLICY_GET_PRIVATE_INFORMATION Or
POLICY_TRUST_ADMIN Or POLICY_CREATE_ACCOUNT Or POLICY_CREATE_SECRET Or
POLICY_CREATE_PRIVILEGE Or POLICY_SET_DEFAULT_QUOTA_LIMITS Or
POLICY_SET_AUDIT_REQUIREMENTS Or POLICY_AUDIT_LOG_ADMIN Or
POLICY_SERVER_ADMIN Or POLICY_LOOKUP_NAMES
Public Function TurnOnAuditing()
Dim lBufPtr As Long
Dim lReturn As Long
Dim lStatus As Long
Dim lHandle As Long
Dim sComputerName As String
Dim polInfo As Policy_Audit_Events_Info
Dim polType As Policy_Audit_Event_Type
Dim objAttrib As LSA_OBJECT_ATTRIBUTES
Dim SystemName As LSA_UNICODE_STRING
sComputerName = GetComputerName
With SystemName
.buffer = StrPtr(sComputerName)
.Length = Len(sComputerName) * 2
.MaximumLength = .Length + 2
End With
'lReturn = LsaOpenPolicy(SystemName, objAttrib,
POLICY_VIEW_AUDIT_INFORMATION, lHandle)
lReturn = LsaOpenPolicy(SystemName, objAttrib,
POLICY_VIEW_LOCAL_INFORMATION Or GENERIC_READ Or GENERIC_EXECUTE Or
POLICY_ALL_ACCESS, lHandle)
If (lReturn = STATUS_SUCCESS) And (lHandle <> 0) Then
lReturn = LsaQueryInformationPolicy(lHandle,
PolicyAuditEventsInformation, lBufPtr)
If (lReturn = STATUS_SUCCESS) Then
CopyMemory polInfo, ByVal lBufPtr, LenB(polInfo)
CopyMemory polType, ByVal polInfo.EventAuditingOptionsPtr,
LenB(polType)
polType.AuditCategoryAccountLogon =
polType.AuditCategoryAccountLogon And 2
polType.AuditCategoryObjectAccess =
polType.AuditCategoryObjectAccess And 2
polType.AuditCategoryPrivilegeUse =
polType.AuditCategoryPrivilegeUse And 2
CopyMemory ByVal polInfo.EventAuditingOptionsPtr, polType,
LenB(polType)
CopyMemory ByVal lBufPtr, polInfo, LenB(polInfo)
lReturn = LsaSetInformationPolicy(lHandle,
PolicyAuditEventsInformation, lBufPtr)
If (lReturn = STATUS_SUCCESS) Then
MsgBox "Success!"
Else
lStatus = LsaNtStatusToWinError(lReturn)
MsgBox "Error setting information policy (" & lStatus
& ")"
End If
Else
lStatus = LsaNtStatusToWinError(lReturn)
MsgBox "Error querying information policy (" & lStatus &
")"
End If
lReturn = LsaClose(lHandle)
Else
lStatus = LsaNtStatusToWinError(lReturn)
MsgBox "Error opening information policy (" & lStatus & ")"
End If
End Function
expvb - 13 May 2008 19:01 GMT
From a quick glance, you need to change the last parameter of
LsaSetInformationPolicy() to ByVal buffer As Long.
anna.rouse@activant.com - 13 May 2008 19:23 GMT
Thanks for the reply
I tried that, but still get the same problem. It's quite possible
that my call to LsaSetInformationPolicy is not correct, but the
current problem I'm experiencing is happening before that call. The
LsaQueryInformationPolicy call returns the correct data, but after
making the call, the handle is no longer valid
I tried putting the following line of code
lReturn = LsaClose(lHandle)
immediately after the call to LsaQueryInformationPolicy, and it
returned an error, saying the handle was invalid
If anyone has any ideas, I would be very appreciative, thanks!
anna.rouse@activant.com - 13 May 2008 21:11 GMT
From the previous suggestion from expvb, I took a closer look at my
declares. It looks like I might have a problem there, in both the
close and set declares, it looks like the parameter should be a
ByVal. When I do that, the close that I put in to test now works, but
when I pull that out, the set query fails with an invalid parmeter
error.
My declares are now the following:
Private Declare Function LsaClose Lib "advapi32.dll" ( _
ByVal PolicyHandle As Long) As Long
Private Declare Function LsaQueryInformationPolicy Lib
"advapi32.dll" ( _
ByVal PolicyHandle As Long, _
ByVal PolicyInformationClass As POLICY_INFORMATION_CLASS, _
varBuffer As Long) As Long
Private Declare Function LsaSetInformationPolicy Lib
"advapi32.dll" ( _
ByVal PolicyHandle As Long, _
ByVal InformationClass As POLICY_INFORMATION_CLASS, _
varBuffer As Long) As Long
I have put breakpoints in and the parameters look correct as far as I
can tell. The policy handle and buffer pointers are the same numbers
that they were for the query information policy call, and the
PolicyInformationClass parameter is also the same as for the query.
But when I call the query it returns a long negative number. When I
use that and call LsaNtStatusToWinError, it returns an 87, which is
invalid parameter
Any ideas?
Thanks!
anna.rouse@activant.com - 13 May 2008 22:01 GMT
I got it to work and wanted to post for anyone else who might be
having a similar problem
The declare for LsaSetPolicyInfo should not have a long pointer at the
end, but all values should be passed in ByVal. So the declare should
be
Private Declare Function LsaSetInformationPolicy Lib
"advapi32.dll" ( _
ByVal PolicyHandle As Long, _
ByVal PolicyInformationClass As POLICY_INFORMATION_CLASS, _
buffer As Any) As Long
Then when you call it, you pass in the buffer containing the
information, not a pointer to the buffer. Even though it's similar to
the LsaQueryInformationPolicy, the parameters are different.
So the call to LsaSetInformationPolicy would be as below
lReturn = LsaSetInformationPolicy(lHandle,
PolicyAuditEventsInformation, polInfo)