Type a page name and press Enter. You'll jump to the page if it exists, or you can create it if it doesn't.
To create a page in a module other than advapi32, prefix the name with the module name and a period.
Declare Unicode Function LsaOpenPolicy Lib "advapi32.dll" ( _
ByRef SystemName As LSA_UNICODE_STRING, _
ByRef ObjectAttributes As LSA_OBJECT_ATTRIBUTES, _
ByVal DesiredAccess As Int32, _
ByRef PolicyHandle As IntPtr) As Int32
User-Defined Types:
None.
Notes:
From the SDK: The LsaOpenPolicy function opens a handle to the Policy object on a local or remote system.
To administer the local security policy of a local or remote system, you must call the LsaOpenPolicy function to establish a session with that system's LSA subsystem. LsaOpenPolicy connects to the LSA of the target system and returns a handle to the Policy object of that system. You can use this handle in subsequent LSA function calls to administer the local security policy information of the target system.
I used a custom marshaler to live a happier life with the "own super special" string type that LSA uses. It marshals LSA_UNICODE_STRINGS to and from normal .NET strings. See "Alternate Sample Code" way below. However I'm quite new to p/invoke and this is my first custom marshaler ever, so please keep your eyes open for problems and bugs with my code. (A problem I had was CleanUpNativeData for data converted from managed to unmanaged aswell as for data converted from unmanaged to managed. Since I didn't allocate the data myself in the latter case my marshaler uses a hash table to keep track of the native data it allocated itself. Don't know if that's the correct way, however. Feel free to mail me at pi AT removethispart frohwalt removethisaswell DOT de for suggestions/corrections. https://www.pinvoke.net/emoticons/regular_smile.gif ) Oh, by the way this also contains an example for LSARetrievePrivateData in case you want to read out some RunAs passwords from the LSA. (My goal is to ultimateley change them, not to read them https://www.pinvoke.net/emoticons/regular_smile.gif )
Sample Code:
public static uint SetRight( string inAccountName, string inPrivilegeName )
{
uint aWinErrorCode = 0; //contains the last error
//pointer an size for the SID
IntPtr aSid = IntPtr.Zero;
int aSidSize = 0;
//StringBuilder and size for the domain name
StringBuilder aDomainName = new StringBuilder();
int aNameSize = 0;
//account-type variable for lookup
int aAccountType = 0;
//lookup the SID for the account
bool aResult = LookupAccountName( String.Empty, inAccountName, aSid, ref aSidSize, aDomainName, ref aNameSize, ref aAccountType );
if ( aResult )
{
//initialize an empty unicode-string
LSA_UNICODE_STRING aSystemName = new LSA_UNICODE_STRING();
//combine all policies
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
);
//initialize a pointer for the policy handle
IntPtr aPolicyHandle = IntPtr.Zero;
//these attributes are not used, but LsaOpenPolicy wants them to exists
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;
//get a policy handle
uint aOpenPolicyResult = LsaOpenPolicy(ref aSystemName, ref aObjectAttributes, aAccess, out aPolicyHandle);
aWinErrorCode = LsaNtStatusToWinError( aOpenPolicyResult );
if( aWinErrorCode == Win32Constants.STATUS_SUCCESS )
{
//Now that we have the SID an the policy,
//we can add rights to the account.
//initialize an unicode-string for the privilege name
LSA_UNICODE_STRING[] aUserRightsLSAString = new LSA_UNICODE_STRING[1];
aUserRightsLSAString[0] = new LSA_UNICODE_STRING();
aUserRightsLSAString[0].Buffer = Marshal.StringToHGlobalUni( inPrivilegeName );
aUserRightsLSAString[0].Length = ( UInt16 )( inPrivilegeName.Length * UnicodeEncoding.CharSize );
aUserRightsLSAString[0].MaximumLength = ( UInt16 )( ( inPrivilegeName.Length + 1 ) * UnicodeEncoding.CharSize );
//add the right to the account
uint aLSAResult = LsaAddAccountRights( aPolicyHandle, aSid, aUserRightsLSAString, 1 );
aWinErrorCode = LsaNtStatusToWinError( aLSAResult );
LsaClose( aPolicyHandle );
}
FreeSid( aSid );
}
else
{
aWinErrorCode = (uint)GetLastError();
}
return aWinErrorCode;
}
Alternate Sample Code:
// This was started from the sample code above (which I originally found on code project).
[StructLayout(LayoutKind.Sequential)]
internal struct LSA_UNICODE_STRING
{
public UInt16 Length;
public UInt16 MaximumLength;
public IntPtr Buffer;
public LSAPolicy(LSA_AccessPolicy access)
public void CleanUpManagedData(object ManagedObj)
{
//initialize an empty unicode-string
string systemName = null;
//these attributes are not used, but LsaOpenPolicy wants them to exist
// (MSDN: "the structure members are not used, initalize them to NULL or zero")
LSA_OBJECT_ATTRIBUTES ObjectAttributes = new LSA_OBJECT_ATTRIBUTES();
ObjectAttributes.Length = 0;
ObjectAttributes.RootDirectory = IntPtr.Zero;
ObjectAttributes.Attributes = 0;
ObjectAttributes.SecurityDescriptor = IntPtr.Zero;
ObjectAttributes.SecurityQualityOfService = IntPtr.Zero;
//get a policy handle
UInt32 resultPolicy = LsaOpenPolicy(ref systemName, ref ObjectAttributes, (int)access, out policy);
UInt32 winErrorCode = LsaNtStatusToWinError(resultPolicy);
if (winErrorCode != 0)
{
throw new Win32Exception(winErrorCode, "OpenPolicy failed: ");
}
[DllImport("advapi32.dll")]
private static extern long LsaClose(IntPtr ObjectHandle);
[StructLayout(LayoutKind.Sequential)]
private struct LSA_OBJECT_ATTRIBUTES
public LSAPolicy(LSA_AccessPolicy access)
{
public int Length;
public IntPtr RootDirectory;
public LSA_UNICODE_STRING ObjectName;
public UInt32 Attributes;
public IntPtr SecurityDescriptor;
public IntPtr SecurityQualityOfService;
}
//initialize an empty unicode-string
string systemName = null;
[DllImport("advapi32.dll", PreserveSig=true)]
private static extern UInt32 LsaOpenPolicy(
[MarshalAs(UnmanagedType.CustomMarshaler,MarshalTypeRef=typeof(LSAStringMarshaler))] ref string SystemName,
ref LSA_OBJECT_ATTRIBUTES ObjectAttributes,
Int32 DesiredAccess,
out IntPtr PolicyHandle
);
//these attributes are not used, but LsaOpenPolicy wants them to exist
// (MSDN: "the structure members are not used, initalize them to NULL or zero")
LSA_OBJECT_ATTRIBUTES ObjectAttributes = new LSA_OBJECT_ATTRIBUTES();
ObjectAttributes.Length = 0;
ObjectAttributes.RootDirectory = IntPtr.Zero;
ObjectAttributes.Attributes = 0;
ObjectAttributes.SecurityDescriptor = IntPtr.Zero;
ObjectAttributes.SecurityQualityOfService = IntPtr.Zero;
[DllImport("advapi32.dll")]
private static extern UInt32 LsaNtStatusToWinError(UInt32 status);
//get a policy handle
UInt32 resultPolicy = LsaOpenPolicy(ref systemName, ref ObjectAttributes, (int)access, out policy);
int winErrorCode = LsaNtStatusToWinError(resultPolicy);
}
if (winErrorCode != 0)
{
throw new Win32Exception(winErrorCode, "OpenPolicy failed: ");
}
}
VB.Net Sample Code:
' Check to see if the Deny permission already exists
Public Function CheckTS(ByVal PC As String) As Boolean
Dim ret, Access, sidsize, count, i As Integer
Dim SystemName, DenyTSRights As LSA_UNICODE_STRING
Dim ObjectAttr As LSA_OBJECT_ATTRIBUTES
Dim Policy, EveryoneSID, EnumBuf, ptr As IntPtr
Dim LsaInfo As LSA_ENUMERATION_INFORMATION
Dim ans As Boolean
~LSAPolicy()
{
Dispose(false);
}
' build a well-known SID for "Everyone"
sidsize = SECURITY_MAX_SID_SIZE
EveryoneSID = Marshal.AllocHGlobal(sidsize)
If CreateWellKnownSid(WinWorldSid, IntPtr.Zero, EveryoneSID, sidsize) = False Then
ret = Marshal.GetLastWin32Error()
Throw New Win32Exception(ret)
End If
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
' setup the parameters for the LsaOpenPolicy API
ObjectAttr.Length = Marshal.SizeOf(ObjectAttr)
SystemName.Length = PC.Length * UnicodeEncoding.CharSize
SystemName.MaximumLength = (PC.Length + 1) * UnicodeEncoding.CharSize
SystemName.Buffer = Marshal.StringToHGlobalUni(PC)
Access = POLICY_ALL_ACCESS
public void Dispose(bool disposing)
{
if (policy != IntPtr.Zero)
{
LsaClose(policy);
policy = IntPtr.Zero;
}
}
' open a policy handle on the remote PC
ret = LsaOpenPolicy(SystemName, ObjectAttr, Access, Policy)
If ret <> 0 Then
Throw New Win32Exception(LsaNtStatusToWinError(ret))
End If
public string RetrievePrivateData(string key)
{
string result = null;
UInt32 ntstatus = LsaRetrievePrivateData(policy, key, ref result);
long winErrorCode = LsaNtStatusToWinError(ntstatus);
if (winErrorCode != 0)
{
throw new Exception("RetreivePrivateData failed: " + winErrorCode);
}
return result;
}
' Setup the input parameters for the LsaEnumerateAccountsWithUserRight API
DenyTSRights.Length = SE_DENY_REMOTE_INTERACTIVE_LOGON_NAME.Length * UnicodeEncoding.CharSize
DenyTSRights.MaximumLength = (SE_DENY_REMOTE_INTERACTIVE_LOGON_NAME.Length + 1) * UnicodeEncoding.CharSize
DenyTSRights.Buffer = Marshal.StringToHGlobalUni(SE_DENY_REMOTE_INTERACTIVE_LOGON_NAME)
' do it!
ret = LsaEnumerateAccountsWithUserRight(Policy, DenyTSRights, EnumBuf, count)
If ret <> 0 Then
Marshal.FreeHGlobal(DenyTSRights.Buffer)
LsaClose(Policy)
' if there are no matching entries
If ret = STATUS_NO_MORE_ENTRIES Then
Return False
End If
Throw New Win32Exception(LsaNtStatusToWinError(ret))
End If
[DllImport("advapi32.dll")]
private static extern long LsaClose(IntPtr ObjectHandle);
' check to see if the Everyone SID is currently in the list
ans = False
For i = 0 To count - 1
ptr = New IntPtr(EnumBuf.ToInt32 + (i * Marshal.SizeOf(LsaInfo)))
LsaInfo = CType(Marshal.PtrToStructure(ptr, GetType(LSA_ENUMERATION_INFORMATION)), LSA_ENUMERATION_INFORMATION)
If EqualSid(LsaInfo.Sid, EveryoneSID) Then
ans = True
Exit For
End If
Next
[StructLayout(LayoutKind.Sequential)]
private struct LSA_OBJECT_ATTRIBUTES
{
public int Length;
public IntPtr RootDirectory;
public LSA_UNICODE_STRING ObjectName;
public UInt32 Attributes;
public IntPtr SecurityDescriptor;
public IntPtr SecurityQualityOfService;
}
' clean up
LsaFreeMemory(EnumBuf)
Marshal.FreeHGlobal(DenyTSRights.Buffer)
LsaClose(Policy)
Return ans
End Function
[DllImport("advapi32.dll", PreserveSig=true)]
private static extern UInt32 LsaOpenPolicy(
[MarshalAs(UnmanagedType.CustomMarshaler,MarshalTypeRef=typeof(LSAStringMarshaler))] ref string SystemName,
ref LSA_OBJECT_ATTRIBUTES ObjectAttributes,
Int32 DesiredAccess,
out IntPtr PolicyHandle
);
Alternative Managed API:
Do you know one? Please contribute it!
[DllImport("advapi32.dll")]
private static extern int LsaNtStatusToWinError(long status);
}
Alternative Managed API:
Do you know one? Please contribute it!
The LsaOpenPolicy function opens a handle to the Policy object on a local or remote system.
The LsaClose function closes a handle to a Policy or TrustedDomain object.
3/16/2007 7:33:16 AM - 66.249.65.229
The LsaRetrievePrivateData function retrieves private data that was stored by the LsaStorePrivateData function.
3/16/2007 7:33:30 AM - -212.242.131.193
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).