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

LsaRetrievePrivateData (advapi32)
 
.
NOTE
Summary
The LsaRetrievePrivateData function retrieves private data that was stored by the LsaStorePrivateData function.

C# Signature:

[DllImport("advapi32.dll", SetLastError = true, PreserveSig = true)]
    private static extern uint LsaRetrievePrivateData(
                IntPtr PolicyHandle,
                ref LSA_UNICODE_STRING KeyName,
                out IntPtr PrivateData
    );

VB Signature:

Private Declare Function LsaRetrievePrivateData Lib "ADVAPI32.dll" (ByVal PolicyHandle As Long, ByRef KeyName As LSA_UNICODE_STRING, ByVal PrivateData As Long) As Long

User-Defined Types:

Private Type LSA_UNICODE_STRING
   Length          As Integer  ' WORD
   MaximumLength   As Integer  ' WORD
   Buffer          As Long     ' PWCHAR - pointer
End Type

Alternative Managed API:

Do you know one? Please contribute it!

Notes:

See LsaOpenPolicy for the custom marshaler and some more info on it.

Tips & Tricks:

Do not use the LSA private data functions. Instead, use the CryptProtectData and CryptUnprotectData functions.

(However, these won't do when you need to modify COM runas Passwords ...)

Sample Code:

using System;

using System.Text;

using System.Runtime.InteropServices;

namespace pinvoke.lsautil.lsautil

{

    public class LSAutil
    {

    [StructLayout(LayoutKind.Sequential)]
    private struct LSA_UNICODE_STRING
    {
        public UInt16 Length;
        public UInt16 MaximumLength;
        public IntPtr Buffer;
    }

    [StructLayout(LayoutKind.Sequential)]
    private struct LSA_OBJECT_ATTRIBUTES
    {
        public int Length;
        public IntPtr RootDirectory;
        public LSA_UNICODE_STRING ObjectName;
        public uint Attributes;
        public IntPtr SecurityDescriptor;
        public IntPtr SecurityQualityOfService;
    }

    private 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
    }

    [DllImport("advapi32.dll", SetLastError = true, PreserveSig = true)]
    private static extern uint LsaRetrievePrivateData(
                IntPtr PolicyHandle,
                ref LSA_UNICODE_STRING KeyName,
                out IntPtr PrivateData
    );

    [DllImport("advapi32.dll", SetLastError = true, PreserveSig = true)]
    private static extern uint LsaStorePrivateData(
         IntPtr policyHandle,
         ref LSA_UNICODE_STRING KeyName,
         ref LSA_UNICODE_STRING PrivateData
    );

    [DllImport("advapi32.dll", SetLastError = true, PreserveSig = true)]
    private static extern uint LsaOpenPolicy(
       ref LSA_UNICODE_STRING SystemName,
       ref LSA_OBJECT_ATTRIBUTES ObjectAttributes,
       uint DesiredAccess,
       out IntPtr PolicyHandle
    );

    [DllImport("advapi32.dll", SetLastError = true, PreserveSig = true)]
    private static extern uint LsaNtStatusToWinError(
        uint status
    );

    [DllImport("advapi32.dll", SetLastError = true, PreserveSig = true)]
    private static extern uint LsaClose(
        IntPtr policyHandle
    );

    [DllImport("advapi32.dll", SetLastError = true, PreserveSig = true)]
    private static extern uint LsaFreeMemory(
        IntPtr buffer
    );

    private LSA_OBJECT_ATTRIBUTES objectAttributes;
    private LSA_UNICODE_STRING localsystem;
    private LSA_UNICODE_STRING secretName;

    public LSAutil(string key)
    {
        if (key.Length == 0)
        {
        throw new Exception("Key lenght zero");
        }

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

        localsystem = new LSA_UNICODE_STRING();
        localsystem.Buffer = IntPtr.Zero;
        localsystem.Length = 0;
        localsystem.MaximumLength = 0;

        secretName = new LSA_UNICODE_STRING();
        secretName.Buffer = Marshal.StringToHGlobalUni(key);
        secretName.Length = (UInt16)(key.Length * UnicodeEncoding.CharSize);
        secretName.MaximumLength = (UInt16)((key.Length + 1) * UnicodeEncoding.CharSize);

    }

    private IntPtr GetLsaPolicy(LSA_AccessPolicy access)
    {
        IntPtr LsaPolicyHandle;

        uint ntsResult = LsaOpenPolicy(ref this.localsystem, ref this.objectAttributes, (uint)access, out LsaPolicyHandle);

        uint winErrorCode = LsaNtStatusToWinError(ntsResult);
        if (winErrorCode != 0)
        {
        throw new Exception("LsaOpenPolicy failed: " + winErrorCode);
        }

        return LsaPolicyHandle;
    }

    private static void ReleaseLsaPolicy(IntPtr LsaPolicyHandle)
    {
        uint ntsResult = LsaClose(LsaPolicyHandle);
        uint winErrorCode = LsaNtStatusToWinError(ntsResult);
        if (winErrorCode != 0)
        {
        throw new Exception("LsaClose failed: " + winErrorCode);
        }
    }

    private static void  FreeMemory(IntPtr Buffer)
    {
        uint ntsResult = LsaFreeMemory(Buffer);
        uint winErrorCode = LsaNtStatusToWinError(ntsResult);
        if (winErrorCode != 0)
        {
        throw new Exception("LsaFreeMemory failed: " + winErrorCode);
        }
    }

    public  void SetSecret(string value)
    {
        LSA_UNICODE_STRING lusSecretData = new LSA_UNICODE_STRING();

        if (value.Length > 0)
        {
        //Create data and key
        lusSecretData.Buffer = Marshal.StringToHGlobalUni(value);
        lusSecretData.Length = (UInt16)(value.Length * UnicodeEncoding.CharSize);
        lusSecretData.MaximumLength = (UInt16)((value.Length + 1) * UnicodeEncoding.CharSize);
        }
        else
        {
        //Delete data and key
        lusSecretData.Buffer = IntPtr.Zero;
        lusSecretData.Length = 0;
        lusSecretData.MaximumLength = 0;
        }

        IntPtr LsaPolicyHandle = GetLsaPolicy(LSA_AccessPolicy.POLICY_CREATE_SECRET);
        uint result = LsaStorePrivateData(LsaPolicyHandle, ref secretName, ref lusSecretData);
        ReleaseLsaPolicy(LsaPolicyHandle);

        uint winErrorCode = LsaNtStatusToWinError(result);
        if (winErrorCode != 0)
        {
        throw new Exception("StorePrivateData failed: " + winErrorCode);
        }
    }

    public string GetSecret()
    {
        IntPtr PrivateData = IntPtr.Zero;

        IntPtr LsaPolicyHandle = GetLsaPolicy(LSA_AccessPolicy.POLICY_GET_PRIVATE_INFORMATION);
        uint ntsResult = LsaRetrievePrivateData(LsaPolicyHandle, ref secretName, out PrivateData);
        ReleaseLsaPolicy(LsaPolicyHandle);

        uint winErrorCode = LsaNtStatusToWinError(ntsResult);
        if (winErrorCode != 0)
        {
        throw new Exception("RetreivePrivateData failed: " + winErrorCode);
        }

        LSA_UNICODE_STRING lusSecretData =
        (LSA_UNICODE_STRING)Marshal.PtrToStructure(PrivateData, typeof(LSA_UNICODE_STRING));
        string value = Marshal.PtrToStringAuto(lusSecretData.Buffer).Substring(0, lusSecretData.Length / 2);

        FreeMemory(PrivateData);

        return value;
    }

    }

}

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
Edit This Page
Find References
Show Printable Version
Revisions