Search
Module:
Directory

   Desktop Functions:

   Smart Device Functions:


Show Recent Changes
Subscribe (RSS)
Misc. Pages
Comments
FAQ
Helpful Tools
Playground
Suggested Reading
Website TODO List
Download Visual Studio Add-In

LsaQueryInformationPolicy (netapi32)
 
.
Summary
Retrieve Local Policy Information for a Local or Remote Host

C# Signature:

[DllImport("Advapi32.dll",SetLastError=true, PreserveSig = true)]

private static extern uint LsaQueryInformationPolicy(IntPtr PolicyHandle, uint InformationClass, out IntPtr Buffer);

VB Signature:

Declare Function LsaQueryInformationPolicy Lib "Advapi32.dll" (ByVal PolicyHandle As IntPtr, ByVal InformationClass As UInteger, ByRef Buffer As IntPtr) As UInteger

User-Defined Types:

None.

Alternative Managed API:

Do you know one? Please contribute it!

Notes:

With all the different information you can get with just one command; this one sure is difficult. Very, very little documentation on this because Microsoft probably doesn't want easy access to these. My company has allowed me to contribute my findings as long as I mention it. We are Digital Boundary Group, based in London, Ontario, Canada, and we do penetration testing. Please visit us at http://digitalboundary.net I will be allowed to continue my contributions as long as my company does not lose credit for its contributions.

Tips & Tricks:

Please add some!

Sample Code:

    public int GetRemoteAuditPolicy(ref string[,] Policies)
    {
        Policies = new string[9, 2] { { "System", "" }, { "Logon", "" }, { "Object Access", "" }, { "Privilige Use", "" }, { "Detailed Tracking", "" }, { "Policy Change", "" }, { "Account Management", "" }, { "Directory Service Access", "" }, { "Account Logon", "" } };

        //Everything from here until the "Good Stuff", was copied from this site
        byte[] Sid = null;
        uint cbSid = 0;
        StringBuilder referencedDomainName = new StringBuilder();
        uint cchReferencedDomainName = (uint)referencedDomainName.Capacity;
        SID_NAME_USE sidUse;

        int err = 0;
        if (!LookupAccountName(this.ResourceName, this.UserName, Sid, ref cbSid, referencedDomainName, ref cchReferencedDomainName, out sidUse))
        {
        err = Marshal.GetLastWin32Error();
        if (err == ERROR_INSUFFICIENT_BUFFER || err == ERROR_INVALID_FLAGS)
        {
            Sid = new byte[cbSid];
            referencedDomainName.EnsureCapacity((int)cchReferencedDomainName);
            err = 0;
            if (!LookupAccountName(this.ResourceName, this.UserName, Sid, ref cbSid, referencedDomainName, ref cchReferencedDomainName, out sidUse))
            err = Marshal.GetLastWin32Error();
            //throw error here
            //return custom error constant
        }
        }

        LSA_UNICODE_STRING aSystemName = new LSA_UNICODE_STRING();

        uint aAccess = (uint)(
        LSA_AccessPolicy.POLICY_AUDIT_LOG_ADMIN |
        LSA_AccessPolicy.POLICY_CREATE_ACCOUNT |
        LSA_AccessPolicy.POLICY_CREATE_PRIVILEGE |
        LSA_AccessPolicy.POLICY_CREATE_SECRET |
        LSA_AccessPolicy.POLICY_GET_PRIVATE_INFORMATION |
        LSA_AccessPolicy.POLICY_LOOKUP_NAMES |
        LSA_AccessPolicy.POLICY_NOTIFICATION |
        LSA_AccessPolicy.POLICY_SERVER_ADMIN |
        LSA_AccessPolicy.POLICY_SET_AUDIT_REQUIREMENTS |
        LSA_AccessPolicy.POLICY_SET_DEFAULT_QUOTA_LIMITS |
        LSA_AccessPolicy.POLICY_TRUST_ADMIN |
        LSA_AccessPolicy.POLICY_VIEW_AUDIT_INFORMATION |
        LSA_AccessPolicy.POLICY_VIEW_LOCAL_INFORMATION
        );

        IntPtr aPolicyHandle = IntPtr.Zero;
        uint infoclass = (uint)POLICY_INFORMATION_CLASS.PolicyAuditEventsInformation;
        IntPtr bufptr = IntPtr.Zero;

        LSA_OBJECT_ATTRIBUTES aObjectAttributes = new LSA_OBJECT_ATTRIBUTES();
        aObjectAttributes.Length = 0;
        aObjectAttributes.RootDirectory = IntPtr.Zero;
        aObjectAttributes.Attributes = 0;
        aObjectAttributes.SecurityDescriptor = IntPtr.Zero;
        aObjectAttributes.SecurityQualityOfService = IntPtr.Zero;

        aSystemName.SetTo(this.ResourceName);

        uint aOpenPolicyResult = LsaOpenPolicy(ref aSystemName, ref aObjectAttributes, aAccess, out aPolicyHandle);

        //Here's the "Good Stuff" folks
        //This example gets Audit Policy information
        uint retval = LsaQueryInformationPolicy(aPolicyHandle, infoclass, out bufptr);
        //do what you want with the retval, this is a pretty lazy example

        _POLICY_AUDIT_EVENTS_INFO pevents;

        //Marshal the pointer to structure; pretty standard stuff
        pevents = (_POLICY_AUDIT_EVENTS_INFO)Marshal.PtrToStructure(bufptr, typeof(_POLICY_AUDIT_EVENTS_INFO));

        //Microsoft states that this could be an arbitrary number of elements because they may expand upon this in later Windows versions
        int[] policy_values = new int[pevents.MaximumAuditEventCount];

        //pevents.MaximumAuditEventCount gives you the number of elements, take this number of elements and Marshall copy the array
        Marshal.Copy(pevents.EventAuditingOptions, policy_values, 0, pevents.MaximumAuditEventCount);

        //Only take the lowest array count
        int max_policies = Policies.GetLength(0);
        max_policies = max_policies > pevents.MaximumAuditEventCount ? pevents.MaximumAuditEventCount : max_policies;

        //Grade 10 programming class
        for (int x = 0; x < max_policies; x++)
        {
        switch (policy_values[x])
        {
            case 0:
            Policies[x, 1] = "None";
            break;
            case 1:
            Policies[x, 1] = "Success";
            break;
            case 2:
            Policies[x, 1] = "Failure";
            break;
            case 3:
            Policies[x, 1] = "Success/Failure";
            break;
        }
        }
        return 0;
    }

You'll need:

     enum POLICY_INFORMATION_CLASS
     {
         PolicyAuditLogInformation = 1,
         PolicyAuditEventsInformation,
         PolicyPrimaryDomainInformation,
         PolicyPdAccountInformation,
         PolicyAccountDomainInformation,
         PolicyLsaServerRoleInformation,
         PolicyReplicaSourceInformation,
         PolicyDefaultQuotaInformation,
         PolicyModificationInformation,
         PolicyAuditFullSetInformation,
         PolicyAuditFullQueryInformation,
         PolicyDnsDomainInformation
    }

    public enum LSA_AccessPolicy : long
    {
        POLICY_VIEW_LOCAL_INFORMATION = 0x00000001L,
        POLICY_VIEW_AUDIT_INFORMATION = 0x00000002L,
        POLICY_GET_PRIVATE_INFORMATION = 0x00000004L,
        POLICY_TRUST_ADMIN = 0x00000008L,
        POLICY_CREATE_ACCOUNT = 0x00000010L,
        POLICY_CREATE_SECRET = 0x00000020L,
        POLICY_CREATE_PRIVILEGE = 0x00000040L,
        POLICY_SET_DEFAULT_QUOTA_LIMITS = 0x00000080L,
        POLICY_SET_AUDIT_REQUIREMENTS = 0x00000100L,
        POLICY_AUDIT_LOG_ADMIN = 0x00000200L,
        POLICY_SERVER_ADMIN = 0x00000400L,
        POLICY_LOOKUP_NAMES = 0x00000800L,
        POLICY_NOTIFICATION = 0x00001000L
    }

     public struct _POLICY_AUDIT_EVENTS_INFO
     {
         public bool AuditingMode;
         public IntPtr EventAuditingOptions;
         public Int32 MaximumAuditEventCount;
     }

    Microsoft also has an enumeration for the different policies; but like I said above, they strongly caution you to not fix the number of elements in the array because that can and probably will change.  Use my array at the top of the function for now.

    Happy coding!  http://digitalboundary.net


Documentation

Please edit this page!

Do you have...

  • helpful tips or sample code to share for using this API in managed code?
  • corrections to the existing content?
  • variations of the signature you want to share?
  • additional languages you want to include?

Select "Edit This Page" on the right hand toolbar and edit it! Or add new pages containing supporting types needed for this API (structures, delegates, and more).

 
Access PInvoke.net directly from VS:
Terms of Use
Find References
Show Printable Version
Revisions