using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Runtime.InteropServices;
using System.Security;
using System.Text;
using Vanara.Extensions;
using Vanara.InteropServices;
using FILETIME = System.Runtime.InteropServices.ComTypes.FILETIME;
namespace Vanara.PInvoke
{
public static partial class AdvApi32
{
/// Flags that provide more information about the collision.
[PInvokeData("ntsecapi.h", MSDNShortId = "9f9d2f57-0e7f-4222-be35-e3f026b60e93")]
[Flags]
public enum CollisionFlags
{
/// The top-level name trust record is disabled during initial creation.
LSA_TLN_DISABLED_NEW = 0x00000001,
/// The top-level name trust record is disabled by the domain administrator.
LSA_TLN_DISABLED_ADMIN = 0x00000002,
/// The top-level name trust record is disabled due to a conflict.
LSA_TLN_DISABLED_CONFLICT = 0x00000004,
/// The domain information trust record is disabled by the domain administrator.
LSA_SID_DISABLED_ADMIN = 0x00000001,
/// The domain information trust record is disabled due to a conflict.
LSA_SID_DISABLED_CONFLICT = 0x00000002,
/// The domain information trust record is disabled by the domain administrator.
LSA_NB_DISABLED_ADMIN = 0x00000004,
/// The domain information trust record is disabled due to a conflict.
LSA_NB_DISABLED_CONFLICT = 0x00000008,
/// The domain information trust record is disabled.
LSA_FTRECORD_DISABLED_REASONS = 0x0000FFFF,
}
///
///
/// The LSA_FOREST_TRUST_COLLISION_RECORD_TYPE enumeration defines the types of collision that can occur between Local
/// Security Authority forest trust records.
///
///
///
/// This enumeration is used by the LSA_FOREST_TRUST_COLLISION_RECORD structure.
///
// https://docs.microsoft.com/en-us/windows/desktop/api/ntsecapi/ne-ntsecapi-lsa_forest_trust_collision_record_type typedef enum {
// CollisionTdo, CollisionXref, CollisionOther } ;
[PInvokeData("ntsecapi.h", MSDNShortId = "67c89d75-2c2d-4980-a1c9-32e7f64a7b49")]
public enum LSA_FOREST_TRUST_COLLISION_RECORD_TYPE
{
/// Collision between TrustedDomain objects. This indicates a collision with a namespace element of another forest.
CollisionTdo,
/// Collision between cross-references. This indicates a collision with a domain in the same forest.
CollisionXref,
/// Collision that is not a collision between TrustedDomain objects or cross-references.
CollisionOther,
}
///
/// The LSA_FOREST_TRUST_RECORD_TYPE enumeration defines the type of a Local Security Authority forest trust record.
///
///
/// This enumeration is used by the LSA_FOREST_TRUST_RECORD structure.
///
// https://docs.microsoft.com/en-us/windows/desktop/api/ntsecapi/ne-ntsecapi-lsa_forest_trust_record_type typedef enum
// LSA_FOREST_TRUST_RECORD_TYPE { ForestTrustTopLevelName , ForestTrustTopLevelNameEx , ForestTrustDomainInfo ,
// ForestTrustRecordTypeLast } ;
[PInvokeData("ntsecapi.h", MSDNShortId = "8a4a7080-fab0-4ab2-a0b4-e929cce21f0c")]
public enum LSA_FOREST_TRUST_RECORD_TYPE
{
/// Record contains an included top-level name.
ForestTrustTopLevelName,
/// Record contains an excluded top-level name.
ForestTrustTopLevelNameEx,
/// Record contains an LSA_FOREST_TRUST_DOMAIN_INFO structure.
ForestTrustDomainInfo,
/// Marks the end of an enumeration.
ForestTrustRecordTypeLast,
}
/// Flags used by LSA_FOREST_TRUST_RECORD.
[PInvokeData("ntsecapi.h", MSDNShortId = "19b4ee56-664f-4f37-bfc9-129032ebeb22")]
[Flags]
public enum LSA_TLN
{
///
/// The top-level name trust record is disabled during initial creation. This flag MUST be used only with
/// forest trust record types of ForestTrustTopLevelName and ForestTrustTopLevelNameEx.
///
LSA_TLN_DISABLED_NEW = 0x00000001,
///
/// The top-level name trust record is disabled by the domain administrator. This flag MUST be used only with
/// forest trust record types of ForestTrustTopLevelName and ForestTrustTopLevelNameEx.
///
LSA_TLN_DISABLED_ADMIN = 0x00000002,
///
/// The top-level name trust record is disabled due to a conflict. This flag MUST be used only with forest
/// trust record types of ForestTrustTopLevelName and ForestTrustTopLevelNameEx.
///
LSA_TLN_DISABLED_CONFLICT = 0x00000004,
///
/// The domain information trust record is disabled by the domain administrator. This flag MUST be used only
/// with a forest trust record type of ForestTrustDomainInfo.
///
LSA_SID_DISABLED_ADMIN = 0x00000001,
///
/// The domain information trust record is disabled due to a conflict. This flag MUST be used only with a
/// forest trust record type of ForestTrustDomainInfo.
///
LSA_SID_DISABLED_CONFLICT = 0x00000002,
///
/// The domain information trust record is disabled by the domain administrator. This flag MUST be used only
/// with a forest trust record type of ForestTrustDomainInfo.
///
LSA_NB_DISABLED_ADMIN = 0x00000004,
///
/// The domain information trust record is disabled due to a conflict. This flag MUST be used only with a
/// forest trust record type of ForestTrustDomainInfo.
///
LSA_NB_DISABLED_CONFLICT = 0x00000008,
///
/// The domain information trust record is disabled. This set of flags is reserved; for current and future
/// reasons, the trust is disabled.
///
LSA_FTRECORD_DISABLED_REASONS = 0x0000FFFF,
}
/// The Policy object has the following object-specific access types:
[Flags]
[PInvokeData("ntsecapi.h")]
public enum LsaPolicyRights : uint
{
///
/// This access type is needed to read the target system's miscellaneous security policy information. This includes the default
/// quota, auditing, server state and role information, and trust information. This access type is also needed to enumerate
/// trusted domains, accounts, and privileges.
///
POLICY_VIEW_LOCAL_INFORMATION = 1,
/// This access type is needed to view audit trail or audit requirements information.
POLICY_VIEW_AUDIT_INFORMATION = 2,
///
/// This access type is needed to view sensitive information, such as the names of accounts established for trusted domain relationships.
///
POLICY_GET_PRIVATE_INFORMATION = 4,
/// This access type is needed to change the account domain or primary domain information.
POLICY_TRUST_ADMIN = 8,
/// This access type is needed to create a new Account object.
POLICY_CREATE_ACCOUNT = 0x10,
/// This access type is needed to create a new Private Data object.
POLICY_CREATE_SECRET = 0x20,
/// Not yet supported.
POLICY_CREATE_PRIVILEGE = 0x40,
/// Set the default system quotas that are applied to user accounts.
POLICY_SET_DEFAULT_QUOTA_LIMITS = 0x80,
/// This access type is needed to update the auditing requirements of the system.
POLICY_SET_AUDIT_REQUIREMENTS = 0x100,
///
/// This access type is needed to change the characteristics of the audit trail such as its maximum size or the retention period
/// for audit records, or to clear the log.
///
POLICY_AUDIT_LOG_ADMIN = 0x200,
///
/// This access type is needed to modify the server state or role (master/replica) information. It is also needed to change the
/// replica source and account name information.
///
POLICY_SERVER_ADMIN = 0x400,
/// This access type is needed to translate between names and SIDs.
POLICY_LOOKUP_NAMES = 0x800,
/// The policy notification
POLICY_NOTIFICATION = 0x1000,
/// All access
POLICY_ALL_ACCESS = ACCESS_MASK.STANDARD_RIGHTS_REQUIRED |
POLICY_VIEW_LOCAL_INFORMATION |
POLICY_VIEW_AUDIT_INFORMATION |
POLICY_GET_PRIVATE_INFORMATION |
POLICY_TRUST_ADMIN |
POLICY_CREATE_ACCOUNT |
POLICY_CREATE_SECRET |
POLICY_CREATE_PRIVILEGE |
POLICY_SET_DEFAULT_QUOTA_LIMITS |
POLICY_SET_AUDIT_REQUIREMENTS |
POLICY_AUDIT_LOG_ADMIN |
POLICY_SERVER_ADMIN |
POLICY_LOOKUP_NAMES,
/// Read access
POLICY_READ = ACCESS_MASK.STANDARD_RIGHTS_READ |
POLICY_VIEW_AUDIT_INFORMATION |
POLICY_GET_PRIVATE_INFORMATION,
/// Write access
POLICY_WRITE = ACCESS_MASK.STANDARD_RIGHTS_WRITE |
POLICY_TRUST_ADMIN |
POLICY_CREATE_ACCOUNT |
POLICY_CREATE_SECRET |
POLICY_CREATE_PRIVILEGE |
POLICY_SET_DEFAULT_QUOTA_LIMITS |
POLICY_SET_AUDIT_REQUIREMENTS |
POLICY_AUDIT_LOG_ADMIN |
POLICY_SERVER_ADMIN,
/// Execute access
POLICY_EXECUTE = ACCESS_MASK.STANDARD_RIGHTS_EXECUTE |
POLICY_VIEW_LOCAL_INFORMATION |
POLICY_LOOKUP_NAMES,
}
///
/// The LsaAddAccountRights function assigns one or more privileges to an account. If the account does not exist,
/// LsaAddAccountRights creates it.
///
///
/// A handle to a Policy object. The handle must have the POLICY_LOOKUP_NAMES access right. If the account identified by the
/// AccountSid parameter does not exist, the handle must have the POLICY_CREATE_ACCOUNT access right. For more information, see
/// Opening a Policy Object Handle.
///
/// Pointer to the SID of the account to which the function assigns privileges.
///
/// Pointer to an array of LSA_UNICODE_STRING structures. Each structure contains the name of a privilege to add to the account. For
/// a list of privilege names, see Privilege Constants.
///
/// Specifies the number of elements in the UserRights array.
///
/// If the function succeeds, the return value is STATUS_SUCCESS.
///
/// If the function fails, the return value is an NTSTATUS code, which can be the following value or one of the LSA Policy Function
/// Return Values.
///
///
///
/// Return code
/// Description
///
/// -
/// STATUS_NO_SUCH_PRIVILEGE
/// One of the privilege names is not valid.
///
///
/// You can use the LsaNtStatusToWinError function to convert the NTSTATUS code to a Windows error code.
///
///
/// If you specify privileges already granted to the account, they are ignored.
/// For an example that demonstrates calling this function, see Managing Account Permissions.
///
// https://docs.microsoft.com/en-us/windows/win32/api/ntsecapi/nf-ntsecapi-lsaaddaccountrights NTSTATUS LsaAddAccountRights(
// LSA_HANDLE PolicyHandle, PSID AccountSid, PLSA_UNICODE_STRING UserRights, ULONG CountOfRights );
[DllImport(Lib.AdvApi32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("ntsecapi.h", MSDNShortId = "66b78404-02c2-48e9-92c3-d27b68f77c23")]
public static extern NTStatus LsaAddAccountRights(LSA_HANDLE PolicyHandle, PSID AccountSid,
[In, MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(LsaUnicodeStringArrayMarshaler))] string[] UserRights, uint CountOfRights);
///
/// The LsaAddAccountRights function assigns one or more privileges to an account. If the account does not exist,
/// LsaAddAccountRights creates it.
///
///
/// A handle to a Policy object. The handle must have the POLICY_LOOKUP_NAMES access right. If the account identified by the
/// AccountSid parameter does not exist, the handle must have the POLICY_CREATE_ACCOUNT access right. For more information, see
/// Opening a Policy Object Handle.
///
/// Pointer to the SID of the account to which the function assigns privileges.
///
/// Pointer to an array of LSA_UNICODE_STRING structures. Each structure contains the name of a privilege to add to the account. For
/// a list of privilege names, see Privilege Constants.
///
///
/// If the function succeeds, the return value is STATUS_SUCCESS.
///
/// If the function fails, the return value is an NTSTATUS code, which can be the following value or one of the LSA Policy Function
/// Return Values.
///
///
///
/// Return code
/// Description
///
/// -
/// STATUS_NO_SUCH_PRIVILEGE
/// One of the privilege names is not valid.
///
///
/// You can use the LsaNtStatusToWinError function to convert the NTSTATUS code to a Windows error code.
///
///
/// If you specify privileges already granted to the account, they are ignored.
/// For an example that demonstrates calling this function, see Managing Account Permissions.
///
// https://docs.microsoft.com/en-us/windows/win32/api/ntsecapi/nf-ntsecapi-lsaaddaccountrights NTSTATUS LsaAddAccountRights(
// LSA_HANDLE PolicyHandle, PSID AccountSid, PLSA_UNICODE_STRING UserRights, ULONG CountOfRights );
[PInvokeData("ntsecapi.h", MSDNShortId = "66b78404-02c2-48e9-92c3-d27b68f77c23")]
public static NTStatus LsaAddAccountRights(LSA_HANDLE PolicyHandle, PSID AccountSid,
[In, MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(LsaUnicodeStringArrayMarshaler))] params string[] UserRights) =>
LsaAddAccountRights(PolicyHandle, AccountSid, UserRights, (uint)UserRights?.Length);
/// Undocumented function for creating an account.
/// A handle to a Policy object. For more information, see Opening a Policy Object Handle.
/// Pointer to the SID of the account for which to enumerate privileges.
/// The desired access.
/// The account handle.
///
/// If the function succeeds, the return value is STATUS_SUCCESS. If the function fails, the return value is an NTSTATUS code.For
/// more information, see LSA Policy Function Return Values. You can use the LsaNtStatusToWinError function to convert the NTSTATUS
/// code to a Windows error code.
///
[PInvokeData("ntlsa.h")]
[DllImport(Lib.AdvApi32, ExactSpelling = true)]
public static extern NTStatus LsaCreateAccount(LSA_HANDLE PolicyHandle, PSID AccountSid, LsaAccountAccessMask DesiredAccess, out SafeLSA_HANDLE AccountHandle);
/// The LsaCreateTrustedDomainEx function establishes a new trusted domain by creating a new TrustedDomain object.
///
/// A handle to a Policy object. For the object to be created, the caller must have permission to create children on the
/// System container. For information about policy object handles, see Opening a Policy Object Handle.
///
///
/// Pointer to a TRUSTED_DOMAIN_INFORMATION_EX structure that contains the name and SID of the new trusted domain.
///
///
/// Pointer to a TRUSTED_DOMAIN_AUTH_INFORMATION structure that contains authentication information for the new trusted domain.
///
/// An ACCESS_MASK structure that specifies the accesses to be granted for the new trusted domain.
///
///
/// Receives the LSA policy handle of the remote trusted domain. You can pass this handle into LSA function calls to manage the LSA
/// policy of the trusted domain.
///
/// When your application no longer needs this handle, it should call LsaClose to delete the handle.
///
///
/// If the function succeeds, the function returns STATUS_SUCCESS.
///
/// If the function fails, it returns an NTSTATUS code, which can be one of the following values or one of the LSA Policy
/// Function Return Values.
///
///
///
/// Return code
/// Description
///
/// -
/// STATUS_DIRECTORY_SERVICE_REQUIRED
/// The target system (specified in the TrustedDomainInformation parameter) for the TrustedDomain object is not a domain controller.
///
/// -
/// STATUS_INVALID_SID
/// The specified SID is not valid.
///
/// -
/// STATUS_UNSUCCESSFUL
/// Unable to determine whether the target system is a domain controller.
///
///
/// You can use the LsaNtStatusToWinError function to convert the NTSTATUS code to a Windows error code.
///
///
/// LsaCreateTrustedDomainEx does not check whether the specified domain name matches the specified SID or whether the SID and
/// name represent an actual domain.
///
// https://docs.microsoft.com/en-us/windows/desktop/api/ntsecapi/nf-ntsecapi-lsacreatetrusteddomainex NTSTATUS
// LsaCreateTrustedDomainEx( LSA_HANDLE PolicyHandle, PTRUSTED_DOMAIN_INFORMATION_EX TrustedDomainInformation,
// PTRUSTED_DOMAIN_AUTH_INFORMATION AuthenticationInformation, ACCESS_MASK DesiredAccess, PLSA_HANDLE TrustedDomainHandle );
[DllImport(Lib.AdvApi32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("ntsecapi.h", MSDNShortId = "2f458098-9498-4f08-bd13-ac572678d734")]
public static extern NTStatus LsaCreateTrustedDomainEx(LSA_HANDLE PolicyHandle, in TRUSTED_DOMAIN_INFORMATION_EX TrustedDomainInformation,
in TRUSTED_DOMAIN_AUTH_INFORMATION AuthenticationInformation, ACCESS_MASK DesiredAccess, out SafeLSA_HANDLE TrustedDomainHandle);
///
/// The LsaDeleteTrustedDomain function removes a trusted domain from the list of trusted domains for a system and deletes the
/// associated TrustedDomain object.
///
/// A handle to a Policy object. For more information, see Opening a Policy Object Handle.
/// Pointer to the SID of the trusted domain to be removed.
///
/// If the function succeeds, the return value is STATUS_SUCCESS.
/// If the function fails, the return value is an NTSTATUS code. For more information, see LSA Policy Function Return Values.
/// You can use the LsaNtStatusToWinError function to convert the NTSTATUS code to a Windows error code.
///
// https://docs.microsoft.com/en-us/windows/desktop/api/ntsecapi/nf-ntsecapi-lsadeletetrusteddomain NTSTATUS LsaDeleteTrustedDomain(
// LSA_HANDLE PolicyHandle, PSID TrustedDomainSid );
[DllImport(Lib.AdvApi32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("ntsecapi.h", MSDNShortId = "4a7afa28-1786-4a58-a955-d2d8b12e62e4")]
public static extern NTStatus LsaDeleteTrustedDomain(LSA_HANDLE PolicyHandle, PSID TrustedDomainSid);
///
/// The LsaEnumerateAccountRights function enumerates the privileges assigned to an account.
///
///
///
/// A handle to a Policy object. The handle must have the POLICY_LOOKUP_NAMES access right. For more information, see Opening a
/// Policy Object Handle.
///
///
///
/// Pointer to the SID of the account for which to enumerate privileges.
///
///
///
/// Receives a pointer to an array of LSA_UNICODE_STRING structures. Each structure contains the name of a privilege held by the
/// account. For a list of privilege names, see Privilege Constants
///
/// When you no longer need the information, pass the returned pointer to LsaFreeMemory.
///
///
/// Pointer to a variable that receives the number of privileges in the UserRights array.
///
///
/// If at least one account right is found, the function succeeds and returns STATUS_SUCCESS.
///
/// If no account rights are found or if the function fails for any other reason, the function returns an NTSTATUS code such as
/// FILE_NOT_FOUND. For more information, see LSA Policy Function Return Values. Use the LsaNtStatusToWinError function to convert
/// the NTSTATUS code to a Windows error code.
///
///
// https://docs.microsoft.com/en-us/windows/desktop/api/ntsecapi/nf-ntsecapi-lsaenumerateaccountrights NTSTATUS
// LsaEnumerateAccountRights( LSA_HANDLE PolicyHandle, PSID AccountSid, PLSA_UNICODE_STRING *UserRights, PULONG CountOfRights );
[DllImport(Lib.AdvApi32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("ntsecapi.h", MSDNShortId = "3f4a4a9a-66ca-410a-8bdc-c390e8b966e3")]
public static extern NTStatus LsaEnumerateAccountRights(
LSA_HANDLE PolicyHandle,
PSID AccountSid,
out SafeLsaMemoryHandle UserRights,
out uint CountOfRights);
/// The LsaEnumerateAccountRights function enumerates the privileges assigned to an account.
///
/// A handle to a Policy object. The handle must have the POLICY_LOOKUP_NAMES access right. For more information, see Opening a
/// Policy Object Handle.
///
/// Pointer to the SID of the account for which to enumerate privileges.
///
/// An enumeration of strings containing the names of privileges held by the account. For a list of privilege names, see Privilege Constants.
///
public static IEnumerable LsaEnumerateAccountRights(LSA_HANDLE PolicyHandle, PSID AccountSid)
{
var ret = LsaEnumerateAccountRights(PolicyHandle, AccountSid, out var mem, out var cnt);
var winErr = LsaNtStatusToWinError(ret);
if (winErr == Win32Error.ERROR_FILE_NOT_FOUND) return new string[0];
winErr.ThrowIfFailed();
return mem.DangerousGetHandle().ToIEnum((int)cnt).Select(u => (string)u.ToString().Clone()).ToArray();
}
///
///
/// The LsaEnumerateAccountsWithUserRight function returns the accounts in the database of a Local Security Authority (LSA)
/// Policy object that hold a specified privilege. The accounts returned by this function hold the specified privilege directly
/// through the user account, not as part of membership to a group.
///
///
///
///
/// A handle to a Policy object. The handle must have POLICY_LOOKUP_NAMES and POLICY_VIEW_LOCAL_INFORMATION user rights. For more
/// information, see Opening a Policy Object Handle.
///
///
///
///
/// Pointer to an LSA_UNICODE_STRING structure that specifies the name of a privilege. For a list of privileges, see Privilege
/// Constants and Account Rights Constants.
///
///
/// If this parameter is NULL, the function enumerates all accounts in the LSA database of the system associated with the
/// Policy object.
///
///
///
///
/// Pointer to a variable that receives a pointer to an array of LSA_ENUMERATION_INFORMATION structures. The Sid member of
/// each structure is a pointer to the security identifier (SID) of an account that holds the specified privilege.
///
/// When you no longer need the information, free the memory by passing the returned pointer to the LsaFreeMemory function.
///
///
/// Pointer to a variable that receives the number of entries returned in the EnumerationBuffer parameter.
///
///
/// If the function succeeds, the function returns STATUS_SUCCESS.
///
/// If the function fails, it returns an NTSTATUS code, which can be one of the following values or one of the LSA Policy
/// Function Return Values.
///
///
///
/// Value
/// Description
///
/// -
/// STATUS_NO_SUCH_PRIVILEGE
/// The privilege string specified was not a valid privilege.
///
/// -
/// STATUS_NO_MORE_ENTRIES
/// There were no accounts with the specified privilege.
///
///
/// You can use the LsaNtStatusToWinError function to convert the NTSTATUS code to a Windows error code.
///
// https://docs.microsoft.com/en-us/windows/desktop/api/ntsecapi/nf-ntsecapi-lsaenumerateaccountswithuserright NTSTATUS
// LsaEnumerateAccountsWithUserRight( LSA_HANDLE PolicyHandle, PLSA_UNICODE_STRING UserRight, PVOID *Buffer, PULONG CountReturned );
[DllImport(Lib.AdvApi32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("ntsecapi.h", MSDNShortId = "97e7180e-4edb-4edd-915e-0477e7e7a9ff")]
// public static extern NTSTATUS LsaEnumerateAccountsWithUserRight(LSA_HANDLE PolicyHandle, PLSA_UNICODE_STRING UserRight, ref IntPtr
// Buffer, ref uint CountReturned);
public static extern NTStatus LsaEnumerateAccountsWithUserRight(
LSA_HANDLE PolicyHandle,
[In, Optional, MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(LsaUnicodeStringMarshaler))] string UserRight,
out SafeLsaMemoryHandle Buffer,
out int CountReturned);
///
/// The LsaEnumerateAccountsWithUserRight function returns the accounts in the database of a Local Security Authority (LSA) Policy
/// object that hold a specified privilege. The accounts returned by this function hold the specified privilege directly through the
/// user account, not as part of membership to a group.
///
///
/// A handle to a Policy object. The handle must have POLICY_LOOKUP_NAMES and POLICY_VIEW_LOCAL_INFORMATION user rights. For more
/// information, see Opening a Policy Object Handle.
///
///
/// A string that specifies the name of a privilege. For a list of privileges, see Privilege Constants and Account Rights Constants.
///
/// If this parameter is NULL, the function enumerates all accounts in the LSA database of the system associated with the Policy object.
///
///
/// An enumeration of security identifiers (SID) of accounts that holds the specified privilege.
public static IEnumerable LsaEnumerateAccountsWithUserRight(LSA_HANDLE PolicyHandle, [Optional] string UserRights)
{
var ret = LsaEnumerateAccountsWithUserRight(PolicyHandle, UserRights, out var mem, out var cnt);
if (ret == NTStatus.STATUS_NO_MORE_ENTRIES) return new PSID[0];
LsaNtStatusToWinError(ret).ThrowIfFailed();
return mem.DangerousGetHandle().ToIEnum(cnt).Select(u => u.Sid).ToArray();
}
///
///
/// The LsaEnumerateTrustedDomains function retrieves the names and SIDs of domains trusted to authenticate logon credentials.
/// LsaEnumerateTrustedDomains is intended for use on systems running Windows NT 4.0 or earlier versions of Windows NT. Use
/// DsEnumerateDomainTrusts for any other trust enumeration purpose. Specifically, LsaEnumerateTrustedDomains can only be used
/// if one or more of the following is true:
///
///
/// -
/// The calling system is running Windows NT 4.0 or an earlier version of Windows NT.
///
/// -
///
/// The target system (specified using the PolicyHandle parameter), is a domain controller running Windows NT 4.0 or an earlier version.
///
///
/// -
///
/// The calling system is running Windows NT 4.0 or earlier version and is not a domain controller, and the target system is a domain
/// controller in the calling system's domain. The target system can be running any version of Windows NT, including Windows 2000 and
/// Windows XP.
///
///
///
///
///
/// A handle to a Policy object. The handle must have the POLICY_VIEW_LOCAL_INFORMATION access right. For more information, see
/// Opening a Policy Object Handle.
///
///
/// Pointer to an enumeration handle that enables you to make multiple calls to enumerate all the trusted domains. On the first call
/// to LsaEnumerateTrustedDomains, EnumerationContext must point to a variable that has been initialized to zero. On
/// subsequent calls to LsaEnumerateTrustedDomains, EnumerationContext must point to the enumeration handle returned by the
/// previous call.
///
///
///
/// Receives a pointer to an array of LSA_TRUST_INFORMATION structures that contain the names and SIDs of one or more trusted domains.
///
/// When you no longer need the information, pass the returned pointer to LsaFreeMemory.
///
///
/// Specifies the preferred maximum size, in bytes, of the returned buffer. This information is approximate; the actual number of
/// bytes returned may be greater than this value.
///
/// Pointer to a variable that receives the number of elements returned in the Buffer parameter.
///
/// If the function is successful, the return value is one of the following NTSTATUS values.
///
///
/// Value
/// Description
///
/// -
/// STATUS_SUCCESS
/// The enumeration has been successfully completed.
///
/// -
/// STATUS_MORE_ENTRIES
///
/// The call was successful, but there are more trusted domains to be enumerated. Call LsaEnumerateTrustedDomains again, passing the
/// value returned in the EnumerationContext parameter.
///
///
/// -
/// STATUS_NO_MORE_ENTRIES
/// There are no more trusted domains to enumerate.
///
///
/// If the function fails, the return value is an NTSTATUS code. For more information, see LSA Policy Function Return Values.
/// You can use the LsaNtStatusToWinError function to convert the NTSTATUS code to a Windows error code.
///
///
///
/// For domains with domain controllers running only Windows NT 4.0 or earlier versions of Windows NT,
/// LsaEnumerateTrustedDomains returns a list of all trusted domains. In releases of Windows NT up to and including release
/// 4.0, all trusted domains are directly trusted.
///
///
/// In Windows XP and Windows 2000 mixed-mode domains, domain controllers may be running Windows XP, Windows 2000, or Windows NT.
/// Therefore, in mixed-mode domains, some trusted domains are directly trusted and others are indirectly trusted. When enumerating
/// the trusted domains of a system in a mixed-mode domain, LsaEnumerateTrustedDomains returns only directly trusted domains.
///
///
/// In contrast, Windows XP and Windows 2000 native-mode domains contain only Windows 2000 domain controllers, even though there may
/// be members in the domain running Windows NT 4.0 or earlier versions. When enumerating the trusted domains of a system in a
/// native-mode Windows XP and Windows 2000 domain, LsaEnumerateTrustedDomains returns both directly trusted and indirectly
/// trusted domains.
///
///
/// Retrieving all trust information may require more than a single LsaEnumerateTrustedDomains call. You can use the
/// EnumerationContext parameter to make multiple calls, as follows: On the first call, set the variable pointed to by
/// EnumerationContext to zero. If LsaEnumerateTrustedDomains returns STATUS_SUCCESS or STATUS_MORE_ENTRIES, call the function
/// again, passing in the EnumerationContext value returned by the previous call. The enumeration is complete when the function
/// returns STATUS_NO_MORE_ENTRIES.
///
///
// https://docs.microsoft.com/en-us/windows/desktop/api/ntsecapi/nf-ntsecapi-lsaenumeratetrusteddomains NTSTATUS
// LsaEnumerateTrustedDomains( LSA_HANDLE PolicyHandle, PLSA_ENUMERATION_HANDLE EnumerationContext, PVOID *Buffer, ULONG
// PreferedMaximumLength, PULONG CountReturned );
[DllImport(Lib.AdvApi32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("ntsecapi.h", MSDNShortId = "5c371d5a-26cf-4a99-a8e1-006b6b3cc91f")]
public static extern NTStatus LsaEnumerateTrustedDomains(LSA_HANDLE PolicyHandle, ref LSA_ENUMERATION_HANDLE EnumerationContext, out SafeLsaMemoryHandle Buffer, uint PreferedMaximumLength, out uint CountReturned);
///
///
/// The LsaEnumerateTrustedDomains function retrieves the names and SIDs of domains trusted to authenticate logon credentials.
/// LsaEnumerateTrustedDomains is intended for use on systems running Windows NT 4.0 or earlier versions of Windows NT. Use
/// DsEnumerateDomainTrusts for any other trust enumeration purpose. Specifically, LsaEnumerateTrustedDomains can only be used
/// if one or more of the following is true:
///
///
/// -
/// The calling system is running Windows NT 4.0 or an earlier version of Windows NT.
///
/// -
///
/// The target system (specified using the PolicyHandle parameter), is a domain controller running Windows NT 4.0 or an earlier version.
///
///
/// -
///
/// The calling system is running Windows NT 4.0 or earlier version and is not a domain controller, and the target system is a domain
/// controller in the calling system's domain. The target system can be running any version of Windows NT, including Windows 2000 and
/// Windows XP.
///
///
///
///
///
/// A handle to a Policy object. The handle must have the POLICY_VIEW_LOCAL_INFORMATION access right. For more information, see
/// Opening a Policy Object Handle.
///
/// An enumeration of LSA_TRUST_INFORMATION structures that contain the names and SIDs of one or more trusted domains.
[PInvokeData("ntsecapi.h", MSDNShortId = "5c371d5a-26cf-4a99-a8e1-006b6b3cc91f")]
public static IEnumerable LsaEnumerateTrustedDomains(LSA_HANDLE PolicyHandle)
{
const uint maxBuf = 4096;
var hEnum = LSA_ENUMERATION_HANDLE.NULL;
NTStatus ret = NTStatus.STATUS_SUCCESS;
while ((ret = LsaEnumerateTrustedDomains(PolicyHandle, ref hEnum, out var buf, maxBuf, out var count)) == NTStatus.STATUS_MORE_ENTRIES)
{
foreach (var i in buf.ToArray((int)count))
yield return i;
}
ret.ThrowIfFailed();
}
///
/// The LsaEnumerateTrustedDomainsEx function returns information about the domains trusted by the local system.
/// LsaEnumerateTrustedDomainsEx returns information only on direct trusts. DsEnumerateDomainTrusts is recommended for more
/// complete trust enumeration purposes.
///
///
/// A handle to a Policy object. This call requires POLICY_VIEW_LOCAL_INFORMATION access to the Policy object. For more
/// information, see Opening a Policy Object Handle.
///
///
/// A pointer to an LSA_ENUMERATION_HANDLE that you can use to make multiple calls to LsaEnumerateTrustedDomainsEx to retrieve
/// all of the trusted domain information. For more information, see Remarks.
///
///
///
/// Pointer to a buffer that receives a list of TRUSTED_DOMAIN_INFORMATION_EX structures that contain information about the
/// enumerated trusted domains.
///
/// Your application should free this buffer when it is no longer needed by calling LsaFreeMemory.
///
///
/// Preferred maximum length, in bytes, of returned data. This is not a hard upper limit, but serves as a guide. Due to data
/// conversion between systems with different natural data sizes, the actual amount of data returned may be greater than this value.
///
/// Pointer to a LONG that receives the number of trusted domain objects returned.
///
/// If the function succeeds, the function returns STATUS_SUCCESS.
///
/// If the function fails, it returns an NTSTATUS code, which can be one of the following values or one of the LSA Policy
/// Function Return Values.
///
///
///
/// Value
/// Description
///
/// -
/// STATUS_ACCESS_DENIED
/// Caller does not have the appropriate access to complete the operation.
///
/// -
/// STATUS_NO_MORE_ENTRIES
///
/// There are no more entries. This warning is returned if no objects have been enumerated because the EnumerationContext value is
/// too high.
///
///
///
/// You can use the LsaNtStatusToWinError function to convert the NTSTATUS code to a Windows error code.
///
///
/// Retrieving all trust information may require more than a single LsaEnumerateTrustedDomainsEx call.
/// To use the EnumerationContext parameter to make multiple calls
///
/// -
/// Set the variable pointed to by EnumerationContext to zero.
///
/// -
///
/// If LsaEnumerateTrustedDomainsEx returns STATUS_SUCCESS or STATUS_MORE_ENTRIES, call the function again, passing in the
/// EnumerationContext value returned by the previous call.
///
///
/// -
/// The enumeration is complete when the function returns STATUS_NO_MORE_ENTRIES.
///
///
///
// https://docs.microsoft.com/en-us/windows/desktop/api/ntsecapi/nf-ntsecapi-lsaenumeratetrusteddomainsex NTSTATUS
// LsaEnumerateTrustedDomainsEx( LSA_HANDLE PolicyHandle, PLSA_ENUMERATION_HANDLE EnumerationContext, PVOID *Buffer, ULONG
// PreferedMaximumLength, PULONG CountReturned );
[DllImport(Lib.AdvApi32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("ntsecapi.h", MSDNShortId = "4a203bff-c3e1-4d95-b556-617dc8c2e8c2")]
public static extern NTStatus LsaEnumerateTrustedDomainsEx(LSA_HANDLE PolicyHandle, ref LSA_ENUMERATION_HANDLE EnumerationContext, out SafeLsaMemoryHandle Buffer, uint PreferedMaximumLength, out uint CountReturned);
/// [Undocumented] Gets system access for an account.
/// The account handle.
/// The system access.
/// If the function succeeds, the function returns one of the following NTSTATUS values.
[PInvokeData("ntlsa.h")]
[DllImport(Lib.AdvApi32, ExactSpelling = true)]
public static extern NTStatus LsaGetSystemAccessAccount(LSA_HANDLE AccountHandle, out int SystemAccess);
///
///
/// The LsaLookupNames function retrieves the security identifiers (SIDs) that correspond to an array of user, group, or local
/// group names.
///
///
/// The LsaLookupNames function is superseded by the LsaLookupNames2 function. Applications should use the
/// LsaLookupNames2 function to ensure future compatibility.
///
/// The LsaLookupNames function can also retrieve computer accounts.
///
///
/// A handle to a Policy object. The handle must have the POLICY_LOOKUP_NAMES access right. For more information, see Opening a
/// Policy Object Handle.
///
///
/// Specifies the number of names in the Names array. This is also the number of entries returned in the Sids array.
///
///
///
/// Pointer to an array of LSA_UNICODE_STRING structures that contain the names to look up. The strings in these structures can be
/// the names of user, group, or local group accounts, or the names of domains. Domain names can be DNS domain names or NetBIOS
/// domain names.
///
/// For more information about the format of the name strings, see Remarks.
///
///
///
/// Receives a pointer to an LSA_REFERENCED_DOMAIN_LIST structure. The Domains member of this structure is an array that
/// contains an entry for each domain in which a name was found. The DomainIndex member of each entry in the Sids array is the
/// index of the Domains array entry for the domain in which the name was found.
///
///
/// When you have finished using the returned pointer, free the memory by calling the LsaFreeMemory function. This memory must be
/// freed even when the function fails with the either of the error codes STATUS_NONE_MAPPED or STATUS_SOME_NOT_MAPPED
///
///
///
///
/// Receives a pointer to an array of LSA_TRANSLATED_SID structures. Each entry in the Sids array contains the SID information for
/// the corresponding entry in the Names array.
///
///
/// When you have finished using the returned pointer, free the memory by calling the LsaFreeMemory function. This memory must be
/// freed even when the function fails with the either of the error codes STATUS_NONE_MAPPED or STATUS_SOME_NOT_MAPPED
///
///
///
/// If the function succeeds, the function returns one of the following NTSTATUS values.
///
///
/// Value
/// Description
///
/// -
/// STATUS_SOME_NOT_MAPPED
/// Some of the names could not be translated. This is an informational-level return value.
///
/// -
/// STATUS_SUCCESS
/// All of the names were found and successfully translated.
///
///
///
/// If the function fails, the return value is the following NTSTATUS value or one of the LSA Policy Function Return Values.
///
///
///
/// Value
/// Description
///
/// -
/// STATUS_NONE_MAPPED
/// None of the names were translated.
///
///
/// Use the LsaNtStatusToWinError function to convert the NTSTATUS code to a Windows error code.
///
///
///
/// Use fully qualified account names (for example, domain_name\user_name) instead of isolated names (for example, user_name). Fully
/// qualified names are unambiguous and provide better performance when the lookup is performed. This function also supports fully
/// qualified DNS names (for example, example.example.com\user_name) and user principal names (UPN) (for example, someone@example.com).
///
///
/// Translation of isolated names introduces the possibility of name collisions because the same name may be used in multiple
/// domains. The LsaLookupNames function uses the following algorithm to translate isolated names
///
/// To translate isolated names
///
/// -
///
/// If the name is a well-known name, such as Local or Interactive, the function returns the corresponding well-known security
/// identifier (SID).
///
///
/// -
/// If the name is the name of the built-in domain, the function returns the SID of that domain.
///
/// -
/// If the name is the name of the account domain, the function returns the SID of that domain.
///
/// -
/// If the name is the name of the primary domain, the function returns the SID of that domain.
///
/// -
/// If the name is one of the names of the trusted domain, the function returns the SID of that domain.
///
/// -
/// If the name is a user, group, or local group account in the built-in domain, the function returns the SID of that account.
///
/// -
///
/// If the name is a user, group, or local group account in the account domain on the local system, the function returns the SID of
/// that account.
///
///
/// -
/// If the name is a user, group, or a local group in the primary domain, the function returns the SID of that account.
///
/// -
/// After looking in the primary domain, the primary domain looks in each of its trusted domains.
///
/// -
/// Otherwise, the name is not translated.
///
///
///
/// In addition to looking up local accounts, local domain accounts, and explicitly trusted domain accounts, LsaLookupNames
/// can look up the name of any account in any domain in the Windows forest.
///
/// Examples
/// For an example that calls this function, see Translating Between Names and SIDs.
///
// https://docs.microsoft.com/en-us/windows/desktop/api/ntsecapi/nf-ntsecapi-lsalookupnames NTSTATUS LsaLookupNames( LSA_HANDLE
// PolicyHandle, ULONG Count, PLSA_UNICODE_STRING Names, PLSA_REFERENCED_DOMAIN_LIST *ReferencedDomains, PLSA_TRANSLATED_SID *Sids );
[DllImport(Lib.AdvApi32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("ntsecapi.h", MSDNShortId = "867604aa-7a39-4da7-b189-a9183461e9a0")]
public static extern NTStatus LsaLookupNames(LSA_HANDLE PolicyHandle, uint Count, [In, MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(LsaUnicodeStringArrayMarshaler))] string[] Names,
out SafeLsaMemoryHandle ReferencedDomains, out SafeLsaMemoryHandle Sids);
///
///
/// The LsaLookupNames2 function retrieves the security identifiers (SIDs) for specified account names. LsaLookupNames2
/// can look up the SID for any account in any domain in a Windows forest.
///
///
/// The LsaLookupNames function is superseded by the LsaLookupNames2 function. Applications should use the
/// LsaLookupNames2 function to ensure future compatibility.
///
///
/// This function differs from the LsaLookupNames function in that LsaLookupNames2 returns each SID as a single element, while
/// LsaLookupNames divides each SID into an RID/domain pair.
///
///
///
///
/// A handle to a Policy object. The handle must have the POLICY_LOOKUP_NAMES access right. For more information, see Opening a
/// Policy Object Handle.
///
///
///
/// Values that control the behavior of this function. The following value is currently defined.
///
///
/// Value
/// Meaning
///
/// -
/// LSA_LOOKUP_ISOLATED_AS_LOCAL 0x80000000
///
/// The function searches only on the local systems for names that do not specify a domain. The function does search on remote
/// systems for names that do specify a domain.
///
///
///
///
///
/// Specifies the number of names in the Names array. This is also the number of entries returned in the Sids array.
///
///
///
/// Pointer to an array of LSA_UNICODE_STRING structures that contain the names to look up. These strings can be the names of user,
/// group, or local group accounts, or the names of domains. Domain names can be DNS domain names or NetBIOS domain names.
///
/// For more information about the format of the name strings, see Remarks.
///
///
///
/// Receives a pointer to an LSA_REFERENCED_DOMAIN_LIST structure. The Domains member of this structure is an array that
/// contains an entry for each domain in which a name was found. The DomainIndex member of each entry in the Sids array is the
/// index of the Domains array entry for the domain in which the name was found.
///
///
/// When you have finished using the returned pointer, free it by calling the LsaFreeMemory function. This memory must be freed even
/// when the function fails with the either of the error codes STATUS_NONE_MAPPED or STATUS_SOME_NOT_MAPPED
///
///
///
///
/// Receives a pointer to an array of LSA_TRANSLATED_SID2 structures. Each entry in the Sids array contains the SID information for
/// the corresponding entry in the Names array.
///
///
/// When you have finished using the returned pointer, free it by calling the LsaFreeMemory function. This memory must be freed even
/// when the function fails with the either of the error codes STATUS_NONE_MAPPED or STATUS_SOME_NOT_MAPPED
///
///
///
/// If the function succeeds, the function returns one of the following NTSTATUS values.
///
///
/// Value
/// Description
///
/// -
/// STATUS_SOME_NOT_MAPPED
/// Some of the names could not be translated. This is an informational-level return value.
///
/// -
/// STATUS_SUCCESS
/// All of the names were found and successfully translated.
///
///
///
/// If the function fails, the return value is the following NTSTATUS value or one of the LSA Policy Function Return Values.
///
///
///
/// Value
/// Description
///
/// -
/// STATUS_NONE_MAPPED
/// None of the names were translated.
///
///
/// Use the LsaNtStatusToWinError function to convert the NTSTATUS code to a Windows error code.
///
///
///
/// Use fully qualified account names (for example, DomainName<i>UserName) instead of isolated names (for example, UserName).
/// Fully qualified names are unambiguous and provide better performance when the lookup is performed. This function also supports
/// fully qualified DNS names (for example, Example.Example.com<i>UserName) and user principal names (UPN) (for example, Someone@Example.com).
///
///
/// Translation of isolated names introduces the possibility of name collisions because the same name may be used in multiple
/// domains. The LsaLookupNames2 function uses the following algorithm to translate isolated names.
///
/// To translate isolated names
///
/// -
///
/// If the name is a well-known name, such as Local or Interactive, the function returns the corresponding well-known security
/// identifier (SID).
///
///
/// -
/// If the name is the name of the built-in domain, the function returns the SID of that domain.
///
/// -
/// If the name is the name of the account domain, the function returns the SID of that domain.
///
/// -
/// If the name is the name of the primary domain, the function returns the SID of that domain.
///
/// -
/// If the name is one of the names of the trusted domain, the function returns the SID of that domain.
///
/// -
/// If the name is a user, group, or local group account in the built-in domain, the function returns the SID of that account.
///
/// -
///
/// If the name is a user, group, or local group account in the account domain on the local system, the function returns the SID of
/// that account.
///
///
/// -
/// If the name is a user, group, or a local group in the primary domain, the function returns the SID of that account.
///
/// -
/// After looking in the primary domain, the function looks in each of the primary domain's trusted domains.
///
/// -
/// Otherwise, the name is not translated.
///
///
///
// https://docs.microsoft.com/en-us/windows/desktop/api/ntsecapi/nf-ntsecapi-lsalookupnames2 NTSTATUS LsaLookupNames2( LSA_HANDLE
// PolicyHandle, ULONG Flags, ULONG Count, PLSA_UNICODE_STRING Names, PLSA_REFERENCED_DOMAIN_LIST *ReferencedDomains,
// PLSA_TRANSLATED_SID2 *Sids );
[DllImport(Lib.AdvApi32, SetLastError = false, ExactSpelling = true, CharSet = CharSet.Unicode)]
[PInvokeData("ntsecapi.h", MSDNShortId = "fe219070-6a00-4b8c-b2e4-2ad290a1cb9c")]
// public static extern NTSTATUS LsaLookupNames2(LSA_HANDLE PolicyHandle, uint Flags, uint Count, PLSA_UNICODE_STRING Names, ref
// PLSA_REFERENCED_DOMAIN_LIST ReferencedDomains, ref PLSA_TRANSLATED_SID2 Sids);
public static extern NTStatus LsaLookupNames2(
LSA_HANDLE PolicyHandle,
LsaLookupNamesFlags Flags,
uint Count,
[In, MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(LsaUnicodeStringArrayMarshaler))]
string[] Names,
out SafeLsaMemoryHandle ReferencedDomains,
out SafeLsaMemoryHandle Sids);
///
///
/// [ LsaLookupSids is available for use in the operating systems specified in the Requirements section. It may be altered or
/// unavailable in subsequent versions. Instead, use LsaLookupSids2.]
///
///
/// The LsaLookupSids function looks up the names that correspond to an array of security identifiers (SIDs). If
/// LsaLookupSids cannot find a name that corresponds to a SID, the function returns the SID in character form.
///
///
///
/// A handle to a Policy object. This handle must have the POLICY_LOOKUP_NAMES access right. For more information, see Opening a
/// Policy Object Handle.
///
///
/// Specifies the number of SIDs in the Sids array. This is also the number of entries returned in the Names array.
///
///
/// Pointer to an array of SID pointers to look up. The SIDs can be well-known SIDs, user, group, or local group account SIDs, or
/// domain SIDs.
///
///
///
/// Receives a pointer to a pointer to a LSA_REFERENCED_DOMAIN_LIST structure. The Domains member of this structure is an
/// array that contains an entry for each domain in which a SID was found. The entry for each domain contains the SID and flat name
/// of the domain. For Windows domains, the flat name is the NetBIOS name. For links with non–Windows domains, the flat name is the
/// identifying name of that domain, or it is NULL.
///
///
/// When you no longer need the information, pass the returned pointer to LsaFreeMemory. This memory must be freed even when the
/// function fails with the either of the error codes STATUS_NONE_MAPPED or STATUS_SOME_NOT_MAPPED
///
///
///
///
/// Receives a pointer to an array of LSA_TRANSLATED_NAME structures. Each entry in the Names array contains the name information for
/// the corresponding entry in the Sids array. For account SIDs, the Name member of each structure contains the isolated name
/// of the account. For domain SIDs, the Name member is not valid.
///
///
/// The DomainIndex member of each entry in the Names array is the index of an entry in the Domains array returned in
/// the ReferencedDomains parameter. The index identifies the Domains array for the domain in which the SID was found.
///
///
/// When you no longer need the information, pass the returned pointer to LsaFreeMemory. This memory must be freed even when the
/// function fails with the either of the error codes STATUS_NONE_MAPPED or STATUS_SOME_NOT_MAPPED
///
///
///
/// If the function succeeds, the return value is one of the following NTSTATUS values.
///
///
/// Return code
/// Description
///
/// -
/// STATUS_SOME_NOT_MAPPED
/// Some of the SIDs could not be translated. This is an informational-level return value.
///
/// -
/// STATUS_SUCCESS
/// All of the SIDs were found and successfully translated.
///
///
///
/// If the function fails, the return value is an NTSTATUS code, which can be one of the following values or one of the LSA
/// Policy Function Return Values.
///
///
///
/// Return code
/// Description
///
/// -
/// STATUS_NONE_MAPPED
/// None of the SIDs were translated. This is an error-level return value.
///
///
/// You can use the LsaNtStatusToWinError function to convert the NTSTATUS code to a Windows error code.
///
///
///
/// For account SIDs, the string returned in the Name member is the isolated name of the account (for example, user_name). If
/// you need the composite name of the account (for example, Acctg\user_name), get the domain name from the ReferencedDomains buffer
/// and append a backslash and the isolated name.
///
/// If the LsaLookupSids function cannot translate a SID, the function uses the following algorithm:
///
/// -
///
/// If the SID's domain is known, the ReferencedDomains buffer contains an entry for the domain, and the string returned in the Names
/// parameter is a Unicode representation of the account's relative identifier (RID) from the SID.
///
///
/// -
///
/// If the SID's domain is not known, the string returned in the Names parameter is a Unicode representation of the entire SID, and
/// there is no domain record for this SID in the ReferencedDomains buffer.
///
///
///
///
/// In addition to looking up SIDs for local accounts, local domain accounts, and explicitly trusted domain accounts,
/// LsaLookupSids can look up SIDs for any account in any domain in the Windows forest, including SIDs that appear only in the
/// SIDhistory field of an account in the forest. The SIDhistory field stores the former SIDs of an account that has
/// been moved from another domain. To perform these searches, the function queries the global catalog of the forest.
///
///
// https://docs.microsoft.com/en-us/windows/desktop/api/ntsecapi/nf-ntsecapi-lsalookupsids NTSTATUS LsaLookupSids( LSA_HANDLE
// PolicyHandle, ULONG Count, PSID *Sids, PLSA_REFERENCED_DOMAIN_LIST *ReferencedDomains, PLSA_TRANSLATED_NAME *Names );
[DllImport(Lib.AdvApi32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("ntsecapi.h", MSDNShortId = "69051bad-91e7-469d-9010-48ac3d20f8af")]
public static extern NTStatus LsaLookupSids(LSA_HANDLE PolicyHandle, uint Count, [In] PSID[] Sids, out SafeLsaMemoryHandle ReferencedDomains, out SafeLsaMemoryHandle Names);
///
///
/// The LsaLookupSids2 function looks up the names that correspond to an array of security identifiers (SIDs) and supports
/// Internet provider identities. If LsaLookupSids2 cannot find a name that corresponds to a SID, the function returns the SID
/// in character form. You should use this function instead of the LsaLookupSids function.
///
///
///
///
/// A handle to a Policy object. This handle must have the POLICY_LOOKUP_NAMES access right. For more information, see Opening a
/// Policy Object Handle.
///
///
///
/// Flags that modify the lookup behavior.
///
///
/// Value
/// Meaning
///
/// -
/// LSA_LOOKUP_DISALLOW_CONNECTED_ACCOUNT_INTERNET_SID
///
/// Internet SIDs from identity providers for connected accounts are disallowed. Connected accounts are those accounts which have a
/// corresponding shadow account in the local SAM database connected to an online identity provider. For example, MicrosoftAccount is
/// a connected account.
///
///
/// -
/// LSA_LOOKUP_PREFER_INTERNET_NAMES
///
/// Returns the internet names. Otherwise the NT4 style name (domain\username) is returned. The exception is if the Microsoft Account
/// internet SID is specified, in which case the internet name is returned unless LSA_LOOKUP_DISALLOW_NON_WINDOWS_INTERNET_SID is specified.
///
///
/// -
/// LSA_LOOKUP_RETURN_LOCAL_NAMES
/// Always returns local SAM account names even for Internet provider identities.
///
///
///
///
/// Specifies the number of SIDs in the Sids array. This is also the number of entries returned in the Names array.
///
///
///
/// Pointer to an array of SID pointers to look up. The SIDs can be well-known SIDs, user, group, or local group account SIDs, or
/// domain SIDs.
///
///
///
///
/// Receives a pointer to a pointer to a LSA_REFERENCED_DOMAIN_LIST structure. The Domains member of this structure is an
/// array that contains an entry for each domain in which a SID was found. The entry for each domain contains the SID and flat name
/// of the domain. For Windows domains, the flat name is the NetBIOS name. For links with non–Windows domains, the flat name is the
/// identifying name of that domain, or it is NULL.
///
///
/// When you no longer need the information, pass the returned pointer to LsaFreeMemory. This memory must be freed even when the
/// function fails with the either of the error codes STATUS_NONE_MAPPED or STATUS_SOME_NOT_MAPPED
///
///
///
///
/// Receives a pointer to an array of LSA_TRANSLATED_NAME structures. Each entry in the Names array contains the name information for
/// the corresponding entry in the Sids array. For account SIDs, the Name member of each structure contains the isolated name
/// of the account. For domain SIDs, the Name member is not valid.
///
///
/// The DomainIndex member of each entry in the Names array is the index of an entry in the Domains array returned in
/// the ReferencedDomains parameter. The index identifies the Domains array for the domain in which the SID was found.
///
///
/// When you no longer need the information, pass the returned pointer to LsaFreeMemory. This memory must be freed even when the
/// function fails with the either of the error codes STATUS_NONE_MAPPED or STATUS_SOME_NOT_MAPPED
///
///
///
/// If the function succeeds, the return value is one of the following NTSTATUS values.
///
///
/// Return code
/// Description
///
/// -
/// STATUS_SOME_NOT_MAPPED
/// Some of the SIDs could not be translated. This is an informational-level return value.
///
/// -
/// STATUS_SUCCESS
/// All of the SIDs were found and successfully translated.
///
///
///
/// If the function fails, the return value is an NTSTATUS code, which can be one of the following values or one of the LSA
/// Policy Function Return Values.
///
///
///
/// Return code
/// Description
///
/// -
/// STATUS_NONE_MAPPED
/// None of the SIDs were translated. This is an error-level return value.
///
///
/// You can use the LsaNtStatusToWinError function to convert the NTSTATUS code to a Windows error code.
///
///
///
/// The flag LSA_LOOKUP_PREFER_INTERNET_NAMES should be used for internet accounts such as MicrosoftAccount and Azure Active
/// Directory accounts. When this flag is specified then SID-Name lookup returns the UPN of the account in the form
/// MicrosoftAccount\foo@outlook.com or AzureAD\foo@contoso.com. For Microsoft Accounts both the local SAM SID and the internet SID
/// result in the UPN being returned if this flag is specified. If LSA_LOOKUP_PREFER_INTERNET_NAMES is not specified then for AAD
/// accounts the NT4 style name of the form AzureAD\foo is returned. The NT4 style name is machine specific and its usage should be
/// carefully evaluated and if possible should be avoided. For MicrosoftAccounts if LSA_LOOKUP_PREFER_INTERNET_NAMES is not specified
/// then the local SID of the account translates to the local SAM name, and the internet SID translates to the UPN name.
///
///
/// For account SIDs, the string returned in the Name member is the isolated name of the account (for example, user_name). If
/// you need the composite name of the account (for example, Acctg\user_name), get the domain name from the ReferencedDomains buffer
/// and append a backslash and the isolated name.
///
/// If the LsaLookupSids2 function cannot translate a SID, the function uses the following algorithm:
///
/// -
///
/// If the SID's domain is known, the ReferencedDomains buffer contains an entry for the domain, and the string returned in the Names
/// parameter is a Unicode representation of the account's relative identifier (RID) from the SID.
///
///
/// -
///
/// If the SID's domain is not known, the string returned in the Names parameter is a Unicode representation of the entire SID, and
/// there is no domain record for this SID in the ReferencedDomains buffer.
///
///
///
///
/// In addition to looking up SIDs for local accounts, local domain accounts, and explicitly trusted domain accounts,
/// LsaLookupSids2 can look up SIDs for any account in any domain in the Windows forest, including SIDs that appear only in
/// the SIDhistory field of an account in the forest. The SIDhistory field stores the former SIDs of an account that
/// has been moved from another domain. To perform these searches, the function queries the global catalog of the forest.
///
///
// https://docs.microsoft.com/en-us/windows/desktop/api/ntsecapi/nf-ntsecapi-lsalookupsids2 NTSTATUS LsaLookupSids2( LSA_HANDLE
// PolicyHandle, ULONG LookupOptions, ULONG Count, PSID *Sids, PLSA_REFERENCED_DOMAIN_LIST *ReferencedDomains, PLSA_TRANSLATED_NAME
// *Names ); public static extern NTSTATUS LsaLookupSids2(LSA_HANDLE PolicyHandle, uint LookupOptions, uint Count, ref PSID Sids, ref
// PLSA_REFERENCED_DOMAIN_LIST ReferencedDomains, ref PLSA_TRANSLATED_NAME Names);
[PInvokeData("ntsecapi.h", MSDNShortId = "6B30D1FF-35DC-44E8-A765-36A5761EC0CE")]
[DllImport(Lib.AdvApi32, SetLastError = false, ExactSpelling = true, CharSet = CharSet.Unicode)]
public static extern NTStatus LsaLookupSids2(
LSA_HANDLE PolicyHandle,
LsaLookupSidsFlags LookupOptions,
uint Count,
[In, MarshalAs(UnmanagedType.LPArray)] PSID[] Sids,
out SafeLsaMemoryHandle ReferencedDomains,
out SafeLsaMemoryHandle Names);
///
/// The LsaNtStatusToWinError function converts an NTSTATUS code returned by an LSA function to a Windows error code.
///
/// An NTSTATUS code returned by an LSA function call. This value will be converted to a System error code.
///
/// The return value is the Windows error code that corresponds to the Status parameter. If there is no corresponding Windows error
/// code, the return value is ERROR_MR_MID_NOT_FOUND.
///
// https://docs.microsoft.com/en-us/windows/win32/api/ntsecapi/nf-ntsecapi-lsantstatustowinerror ULONG LsaNtStatusToWinError(
// NTSTATUS Status );
[DllImport(Lib.AdvApi32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("ntsecapi.h", MSDNShortId = "fa91794c-c502-4b36-84cc-a8d77c8e9d9f")]
public static extern Win32Error LsaNtStatusToWinError(NTStatus Status);
/// [Undocumented] Opens an account.
/// The policy handle.
/// The account sid.
/// The desired access.
/// The account handle.
/// NTSTATUS
[PInvokeData("ntlsa.h")]
[DllImport(Lib.AdvApi32, ExactSpelling = true)]
public static extern NTStatus LsaOpenAccount(LSA_HANDLE PolicyHandle, PSID AccountSid, LsaAccountAccessMask DesiredAccess, out SafeLSA_HANDLE AccountHandle);
///
/// The LsaOpenPolicy function opens a handle to the Policy object on a local or remote system.
/// You must run the process "As Administrator" so that the call doesn't fail with ERROR_ACCESS_DENIED.
///
///
///
/// A pointer to an LSA_UNICODE_STRING structure that contains the name of the target system. The name can have the form
/// "ComputerName" or "\ComputerName". If this parameter is NULL, the function opens the Policy object on the local system.
///
///
///
///
/// A pointer to an LSA_OBJECT_ATTRIBUTES structure that specifies the connection attributes. The structure members are not used;
/// initialize them to NULL or zero.
///
///
///
///
/// An ACCESS_MASK that specifies the requested access rights. The function fails if the DACL of the target system does not allow the
/// caller the requested access. To determine the access rights that you need, see the documentation for the LSA functions with which
/// you want to use the policy handle.
///
///
///
/// A pointer to an LSA_HANDLE variable that receives a handle to the Policy object.
/// When you no longer need this handle, pass it to the LsaClose function to close it.
///
///
/// If the function succeeds, the function returns STATUS_SUCCESS.
/// If the function fails, it returns an NTSTATUS code. For more information, see LSA Policy Function Return Values.
/// You can use the LsaNtStatusToWinError function to convert the NTSTATUS code to a Windows error code.
///
///
///
/// 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.
///
/// For an example that demonstrates calling this function see Opening a Policy Object Handle.
///
// https://docs.microsoft.com/en-us/windows/desktop/api/ntsecapi/nf-ntsecapi-lsaopenpolicy NTSTATUS LsaOpenPolicy(
// PLSA_UNICODE_STRING SystemName, PLSA_OBJECT_ATTRIBUTES ObjectAttributes, ACCESS_MASK DesiredAccess, PLSA_HANDLE PolicyHandle );
[DllImport(Lib.AdvApi32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("ntsecapi.h", MSDNShortId = "361bc962-1e97-4606-a835-cbce37692c55")]
// public static extern NTSTATUS LsaOpenPolicy(PLSA_UNICODE_STRING SystemName, PLSA_OBJECT_ATTRIBUTES ObjectAttributes, ACCESS_MASK
// DesiredAccess, PLSA_HANDLE PolicyHandle);
public static extern NTStatus LsaOpenPolicy(
[In, MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(LsaUnicodeStringMarshaler))] string SystemName,
in LSA_OBJECT_ATTRIBUTES ObjectAttributes,
LsaPolicyRights DesiredAccess,
out SafeLSA_HANDLE PolicyHandle);
///
/// The LsaOpenPolicy function opens a handle to the Policy object on a local or remote system. You must run the process "As
/// Administrator" so that the call doesn't fail with ERROR_ACCESS_DENIED.
///
///
/// An ACCESS_MASK that specifies the requested access rights. The function fails if the DACL of the target system does not allow the
/// caller the requested access. To determine the access rights that you need, see the documentation for the LSA functions with which
/// you want to use the policy handle.
///
///
/// Name of the target system. The name can have the form "ComputerName" or "\\ComputerName". If this parameter is NULL, the function
/// opens the Policy object on the local system.
///
/// A pointer to an LSA_HANDLE variable that receives a handle to the Policy object.
[PInvokeData("ntsecapi.h", MSDNShortId = "361bc962-1e97-4606-a835-cbce37692c55")]
public static SafeLSA_HANDLE LsaOpenPolicy(LsaPolicyRights DesiredAccess, string SystemName = null)
{
LsaNtStatusToWinError(LsaOpenPolicy(SystemName, LSA_OBJECT_ATTRIBUTES.Empty, DesiredAccess, out var handle)).ThrowIfFailed();
return handle;
}
///
/// The LsaOpenTrustedDomainByName function opens the LSA policy handle of a remote trusted domain. You can pass this handle
/// into LSA function calls in order to set or query the LSA policy of the remote machine.
///
///
/// A handle to a Policy object. This is the policy handle of the local machine. For more information, see Opening a Policy Object Handle.
///
///
/// Name of the trusted domain. This name can be either the flat name, or the Domain Name System (DNS) domain name.
///
///
/// An ACCESS_MASK structure that specifies the access permissions requested on the remote trusted domain object.
///
///
///
/// Pointer that receives the address of the LSA policy handle of the remote trusted domain. You can pass this handle into LSA
/// function calls in order to query and manage the LSA policy of the remote machine.
///
/// When your application no longer needs this handle, it should call LsaClose to delete the handle.
///
///
/// If the function succeeds, the return value is STATUS_SUCCESS.
///
/// If the function fails, the return value is an NTSTATUS code, which can be one of the following values or one of the LSA Policy
/// Function Return Values.
///
///
///
/// Value
/// Description
///
/// -
/// STATUS_ACCESS_DENIED
/// Caller does not have the appropriate access to complete the operation.
///
/// -
/// STATUS_OBJECT_NAME_NOT_FOUND
/// There is no Trusted Domain object in the target system's LSA Database having the specified name.
///
///
/// You can use the LsaNtStatusToWinError function to convert the NTSTATUS code to a Windows error code.
///
// https://docs.microsoft.com/en-us/windows/desktop/api/ntsecapi/nf-ntsecapi-lsaopentrusteddomainbyname NTSTATUS
// LsaOpenTrustedDomainByName( LSA_HANDLE PolicyHandle, PLSA_UNICODE_STRING TrustedDomainName, ACCESS_MASK DesiredAccess, PLSA_HANDLE
// TrustedDomainHandle );
[DllImport(Lib.AdvApi32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("ntsecapi.h", MSDNShortId = "6c55f8b4-d8a2-48e3-8074-b3ca22ce487a")]
public static extern NTStatus LsaOpenTrustedDomainByName(LSA_HANDLE PolicyHandle, [In, MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(LsaUnicodeStringMarshaler))] string TrustedDomainName, ACCESS_MASK DesiredAccess, out SafeLSA_HANDLE TrustedDomainHandle);
/// The LsaQueryDomainInformationPolicy function retrieves domain information from the Policyobject.
/// A handle to the Policy object for the system.
///
///
/// POLICY_DOMAIN_INFORMATION_CLASS enumeration that specifies the information to be returned from the Policyobject. The following
/// table shows the possible values.
///
///
///
/// Value
/// Meaning
///
/// -
/// PolicyDomainEfsInformation
/// The information is for Encrypting File System.
///
/// -
/// PolicyDomainKerberosTicketInformation
/// The information is for a Kerberos ticket.
///
///
///
/// Pointer to a buffer that receives the requested information.
///
/// If the function succeeds, the return value is STATUS_SUCCESS.
///
/// If the function fails, the return value is an NTSTATUS code, which can be the following value or one of the LSA Policy Function
/// Return Values.
///
///
///
/// Return code/value
/// Description
///
/// -
/// STATUS_INTERNAL_DB_CORRUPTION
/// The policy database is corrupt. The returned policy information is not valid for the given class.
///
///
///
///
/// The POLICY_VIEW_LOCAL_INFORMATION access type is required to retrieve domain information from the Policyobject. For more
/// information, see Policy Object Access Rights.
///
// https://docs.microsoft.com/en-us/windows/desktop/api/ntsecapi/nf-ntsecapi-lsaquerydomaininformationpolicy NTSTATUS
// LsaQueryDomainInformationPolicy( LSA_HANDLE PolicyHandle, POLICY_DOMAIN_INFORMATION_CLASS InformationClass, PVOID *Buffer );
[DllImport(Lib.AdvApi32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("ntsecapi.h", MSDNShortId = "39a511d7-46fc-4d12-ba43-771f6db2a33b")]
public static extern NTStatus LsaQueryDomainInformationPolicy(LSA_HANDLE PolicyHandle, POLICY_DOMAIN_INFORMATION_CLASS InformationClass, out SafeLsaMemoryHandle Buffer);
///
/// The LsaQueryForestTrustInformation function retrieves forest trust information for the specified Local Security Authority
/// TrustedDomain object.
///
/// A handle to the Policy object for the system.
///
/// Pointer to an LSA_UNICODE_STRING structure that contains the name of the TrustedDomain object for which to retrieve forest trust information.
///
///
/// Pointer to an LSA_FOREST_TRUST_INFORMATION structure that returns the forest trust information for the TrustedDomain object
/// specified by the TrustedDomainName parameter.
///
///
/// If the function succeeds, the return value is STATUS_SUCCESS.
///
/// If the function fails, the return value is an NTSTATUS code, which can be one of the following values or one of the LSA Policy
/// Function Return Values.
///
///
///
/// Return code/value
/// Description
///
/// -
/// STATUS_INVALID_DOMAIN_ROLE
/// The operation is legal only on the primary domain controller.
///
/// -
/// STATUS_INVALID_DOMAIN_STATE
/// The operation is legal only on domain controllers in the root domain.
///
/// -
/// STATUS_NO_SUCH_DOMAIN
/// The specified TrustedDomain object does not exist.
///
/// -
/// STATUS_NOT_FOUND
/// The specified TrustedDomain object does not contain forest trust information.
///
///
///
/// Access to this function is protected by a securable object.
// https://docs.microsoft.com/en-us/windows/desktop/api/ntsecapi/nf-ntsecapi-lsaqueryforesttrustinformation NTSTATUS
// LsaQueryForestTrustInformation( LSA_HANDLE PolicyHandle, PLSA_UNICODE_STRING TrustedDomainName, PLSA_FOREST_TRUST_INFORMATION
// *ForestTrustInfo );
[DllImport(Lib.AdvApi32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("ntsecapi.h", MSDNShortId = "38857f1f-e2c7-4ce5-a928-335bc3bd2176")]
public static extern NTStatus LsaQueryForestTrustInformation(LSA_HANDLE PolicyHandle, [In, MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(LsaUnicodeStringMarshaler))] string TrustedDomainName,
out SafeLsaMemoryHandle ForestTrustInfo);
/// The LsaQueryInformationPolicy function retrieves information about a Policy object.
///
/// A handle to a Policy object. The required access rights for this handle depend on the value of the InformationClass parameter.
/// For more information, see Opening a Policy Object Handle.
///
///
///
/// Specifies one of the following values from the POLICY_INFORMATION_CLASS enumeration type. The value indicates the type of
/// information to retrieve.
///
///
///
/// Value
/// Meaning
///
/// -
/// PolicyAuditEventsInformation
///
/// Retrieves the system's auditing rules. The handle passed in the PolicyHandle parameter must have the
/// POLICY_VIEW_AUDIT_INFORMATION access right. The Buffer parameter receives a pointer to a POLICY_AUDIT_EVENTS_INFO structure.
///
///
/// -
/// PolicyPrimaryDomainInformation
///
/// Retrieves the name and SID of the system's primary domain. The handle passed in the PolicyHandle parameter must have the
/// POLICY_VIEW_LOCAL_INFORMATION access right. The Buffer parameter receives a pointer to a POLICY_PRIMARY_DOMAIN_INFO structure.
///
///
/// -
/// PolicyAccountDomainInformation
///
/// Retrieves the name and SID of the system's account domain. The handle passed in the PolicyHandle parameter must have the
/// POLICY_VIEW_LOCAL_INFORMATION access right. The Buffer parameter receives a pointer to a POLICY_ACCOUNT_DOMAIN_INFO structure.
///
///
/// -
/// PolicyLsaServerRoleInformation
///
/// Retrieves the role of an LSA server. The handle passed in the PolicyHandle parameter must have the POLICY_VIEW_LOCAL_INFORMATION
/// access right. The Buffer parameter receives a pointer to a POLICY_LSA_SERVER_ROLE_INFO structure.
///
///
/// -
/// PolicyModificationInformation
///
/// Retrieves information about the creation time and last modification of the LSA database. The handle passed in the PolicyHandle
/// parameter must have the POLICY_VIEW_LOCAL_INFORMATION access right. The Buffer parameter receives a pointer to a
/// POLICY_MODIFICATION_INFO structure.
///
///
/// -
/// PolicyDnsDomainInformation
///
/// Retrieves the Domain Name System (DNS) information about the primary domain associated with the Policy object. The handle passed
/// in the PolicyHandle parameter must have the POLICY_VIEW_LOCAL_INFORMATION access right. The Buffer parameter receives a pointer
/// to a POLICY_DNS_DOMAIN_INFO structure.
///
///
///
///
///
///
/// Pointer to a variable that receives a pointer to a structure containing the requested information. The type of structure depends
/// on the value of the InformationClass parameter.
///
/// When you no longer need the information, pass the returned pointer to LsaFreeMemory.
///
///
/// If the LsaQueryInformationPolicy function succeeds, the return value is STATUS_SUCCESS.
/// If the function fails, the return value is an NTSTATUS code. For more information, see LSA Policy Function Return Values.
/// You can use the LsaNtStatusToWinError function to convert the NTSTATUS code to a Windows error code.
///
/// For an example that demonstrates calling this function see Managing Policy Information.
// https://docs.microsoft.com/en-us/windows/desktop/api/ntsecapi/nf-ntsecapi-lsaqueryinformationpolicy NTSTATUS
// LsaQueryInformationPolicy( LSA_HANDLE PolicyHandle, POLICY_INFORMATION_CLASS InformationClass, PVOID *Buffer );
[DllImport(Lib.AdvApi32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("ntsecapi.h", MSDNShortId = "2d543500-f639-4ef7-91f4-cdc5060dd567")]
public static extern NTStatus LsaQueryInformationPolicy(LSA_HANDLE PolicyHandle, POLICY_INFORMATION_CLASS InformationClass, out SafeLsaMemoryHandle Buffer);
/// The LsaQueryInformationPolicy function retrieves information about a Policy object.
///
/// A handle to a Policy object. The required access rights for this handle depend on the value of the InformationClass parameter.
/// For more information, see Opening a Policy Object Handle.
///
///
/// The structure containing the requested information.
///
/// For an example that demonstrates calling this function see Managing Policy Information.
[PInvokeData("ntsecapi.h", MSDNShortId = "2d543500-f639-4ef7-91f4-cdc5060dd567")]
public static T LsaQueryInformationPolicy(LSA_HANDLE PolicyHandle) where T : struct
{
if (!CorrespondingTypeAttribute.CanGet(out var ic))
throw new ArgumentException($"Type mismatch between {ic} and {typeof(T).Name}.");
LsaQueryInformationPolicy(PolicyHandle, ic, out var mem).ThrowIfFailed();
using (mem)
return mem.DangerousGetHandle().Convert(uint.MaxValue, CharSet.Unicode);
}
///
/// The LsaQueryTrustedDomainInfo function retrieves information about a trusted domain.
///
///
///
/// A handle to the Policy object of a domain controller that has a trust relationship with the domain identified by the
/// TrustedDomainSid parameter. The handle must have the POLICY_VIEW_LOCAL_INFORMATION access right. For more information, see
/// Opening a Policy Object Handle.
///
///
///
/// Pointer to the SID of the trusted domain to query.
///
///
///
/// Specifies one of the following values from the TRUSTED_INFORMATION_CLASS enumeration type. The value indicates the type of
/// information being requested.
///
///
///
/// Value
/// Meaning
///
/// -
/// TrustedDomainNameInformation
/// Retrieves the name of the trusted domain. The Buffer parameter receives a pointer to a TRUSTED_DOMAIN_NAME_INFO structure.
///
/// -
/// TrustedPosixOffsetInformation
///
/// Retrieves the value used to generate Posix user and group identifiers for the trusted domain. The Buffer parameter receives a
/// pointer to a TRUSTED_POSIX_OFFSET_INFO structure.
///
///
/// -
/// TrustedPasswordInformation
///
/// Retrieves the password for the trusted domain. The Buffer parameter receives a pointer to a TRUSTED_PASSWORD_INFO structure. The
/// handle passed in the PolicyHandle parameter must have the POLICY_GET_PRIVATE_INFORMATION access right.
///
///
/// -
/// TrustedDomainInformationEx
///
/// Retrieves extended information for the trusted domain. The Buffer parameter receives a pointer to a TRUSTED_DOMAIN_INFORMATION_EX structure.
///
///
/// -
/// TrustedDomainInformationBasic
/// This value is not supported.
///
/// -
/// TrustedDomainFullInformation
///
/// Retrieves complete information for the trusted domain. This information includes the Posix offset information, authentication
/// information, and the extended information returned for the TrustedDomainInformationEx value. The Buffer parameter receives a
/// pointer to a TRUSTED_DOMAIN_FULL_INFORMATION structure.
///
///
///
///
///
///
/// A pointer to a buffer that receives a pointer to a structure that contains the requested information. The type of structure
/// depends on the value of the InformationClass parameter.
///
/// When you have finished using the information, free the returned pointer by passing it to LsaFreeMemory.
///
///
/// If the function succeeds, the function returns STATUS_SUCCESS.
///
/// If the function fails, it returns an NTSTATUS value that indicates the error. For more information, see LSA Policy
/// Function Return Values.
///
/// You can use the LsaNtStatusToWinError function to convert the NTSTATUS value to a Windows error code.
///
// https://docs.microsoft.com/en-us/windows/desktop/api/ntsecapi/nf-ntsecapi-lsaquerytrusteddomaininfo NTSTATUS
// LsaQueryTrustedDomainInfo( LSA_HANDLE PolicyHandle, PSID TrustedDomainSid, TRUSTED_INFORMATION_CLASS InformationClass, PVOID
// *Buffer );
[DllImport(Lib.AdvApi32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("ntsecapi.h", MSDNShortId = "62925515-a6f3-4b5f-bf97-edb968af19a3")]
public static extern NTStatus LsaQueryTrustedDomainInfo(LSA_HANDLE PolicyHandle, PSID TrustedDomainSid, TRUSTED_INFORMATION_CLASS InformationClass, out SafeLsaMemoryHandle Buffer);
/// The LsaQueryTrustedDomainInfoByName function returns information about a trusted domain.
///
/// A handle to a Policy object. This handle must have the POLICY_VIEW_LOCAL_INFORMATION access right. For more information, see
/// Opening a Policy Object Handle.
///
///
/// String that contains the name of the trusted domain. This can either be the domain name or the flat name.
///
///
/// Specifies the type of information to retrieve. This parameter can be one of the following values.
///
///
/// Value
/// Meaning
///
/// -
/// TrustedDomainNameInformation
/// Name of the trusted domain.
///
/// -
/// TrustedPosixInformation
/// Posix offset of the trusted domain.
///
/// -
/// TrustedPasswordInformation
/// Returns the password on the outbound side of the trust.
///
/// -
/// TrustedDomainInformationBasic
/// This value is not supported.
///
/// -
/// TrustedDomainInformationEx
/// Extended trust information, including the basic information and DNS domain name, and attributes about the trust.
///
/// -
/// TrustedDomainFullInformation
/// Full information, including the Posix offset and the authentication information.
///
///
///
///
///
/// Receives a pointer to the returned buffer that contains the requested information. The format and content of this buffer depend
/// on the information class. For example, if InformationClass is set to TrustedDomainInformationEx, Buffer receives a pointer to a
/// TRUSTED_DOMAIN_INFORMATION_EX structure. For more information, see TRUSTED_INFORMATION_CLASS.
///
/// When you have finished using the buffer, free it by calling the LsaFreeMemory function.
///
///
/// If the function succeeds, the function returns STATUS_SUCCESS.
///
/// If the function fails, it returns an NTSTATUS value, which can be one of the following values or one of the LSA Policy
/// Function Return Values.
///
///
///
/// Value
/// Description
///
/// -
/// STATUS_ACCESS_DENIED
///
/// Caller does not have the appropriate access to complete the operation. For a list of the required access types, see the
/// description of the InformationClass parameter.
///
///
/// -
/// STATUS_INSUFFICIENT_ RESOURCES
/// Insufficient system resources, such as memory, to complete the call.
///
///
/// You can use the LsaNtStatusToWinError function to convert the NTSTATUS value to a Windows error code.
///
// https://docs.microsoft.com/en-us/windows/desktop/api/ntsecapi/nf-ntsecapi-lsaquerytrusteddomaininfobyname NTSTATUS
// LsaQueryTrustedDomainInfoByName( LSA_HANDLE PolicyHandle, PLSA_UNICODE_STRING TrustedDomainName, TRUSTED_INFORMATION_CLASS
// InformationClass, PVOID *Buffer );
[DllImport(Lib.AdvApi32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("ntsecapi.h", MSDNShortId = "d33d6cee-bd8b-49f4-8e65-07cdc65bec7c")]
public static extern NTStatus LsaQueryTrustedDomainInfoByName(LSA_HANDLE PolicyHandle,
[In, MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(LsaUnicodeStringMarshaler))] string TrustedDomainName,
TRUSTED_INFORMATION_CLASS InformationClass, out SafeLsaMemoryHandle Buffer);
///
///
/// The LsaRemoveAccountRights function removes one or more privileges from an account. You can specify the privileges to be
/// removed, or you can set a flag to remove all privileges. When you remove all privileges, the function deletes the account. If you
/// specify privileges not held by the account, the function ignores them.
///
///
///
///
/// A handle to a Policy object. The handle must have the POLICY_LOOKUP_NAMES access right. For more information, see Opening a
/// Policy Object Handle.
///
///
///
/// Pointer to the security identifier (SID) of the account from which the privileges are removed.
///
///
///
/// If TRUE, the function removes all privileges and deletes the account. In this case, the function ignores the UserRights
/// parameter. If FALSE, the function removes the privileges specified by the UserRights parameter.
///
///
///
///
/// Pointer to an array of LSA_UNICODE_STRING structures. Each structure contains the name of a privilege to be removed from the
/// account. For a list of privilege names, see Privilege Constants.
///
///
///
/// Specifies the number of elements in the UserRights array.
///
///
/// If the function succeeds, the return value is STATUS_SUCCESS.
///
/// If the function fails, the return value is an NTSTATUS code, which can be one of the following values or one of the LSA Policy
/// Function Return Values.
///
///
///
/// Value
/// Description
///
/// -
/// STATUS_NO_SUCH_PRIVILEGE
/// One of the privilege names is not valid.
///
/// -
/// STATUS_INVALID_PARAMETER
/// Indicates the UserRights parameter was NULL and the AllRights parameter was FALSE.
///
///
/// You can use the LsaNtStatusToWinError function to convert the NTSTATUS code to a Windows error code.
///
// https://docs.microsoft.com/en-us/windows/desktop/api/ntsecapi/nf-ntsecapi-lsaremoveaccountrights NTSTATUS LsaRemoveAccountRights(
// LSA_HANDLE PolicyHandle, PSID AccountSid, BOOLEAN AllRights, PLSA_UNICODE_STRING UserRights, ULONG CountOfRights );
[DllImport(Lib.AdvApi32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("ntsecapi.h", MSDNShortId = "ad250a01-7a24-4fae-975c-aa3e65731c82")]
// public static extern NTSTATUS LsaRemoveAccountRights(LSA_HANDLE PolicyHandle, PSID AccountSid, [MarshalAs(UnmanagedType.U1)] bool
// AllRights, PLSA_UNICODE_STRING UserRights, uint CountOfRights);
public static extern NTStatus LsaRemoveAccountRights( LSA_HANDLE PolicyHandle, PSID AccountSid, [MarshalAs(UnmanagedType.Bool)] bool AllRights,
[In, MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(LsaUnicodeStringArrayMarshaler))] string[] UserRights, uint CountOfRights);
///
///
/// The LsaRemoveAccountRights function removes one or more privileges from an account. You can specify the privileges to be
/// removed, or you can set a flag to remove all privileges. When you remove all privileges, the function deletes the account. If you
/// specify privileges not held by the account, the function ignores them.
///
///
///
///
/// A handle to a Policy object. The handle must have the POLICY_LOOKUP_NAMES access right. For more information, see Opening a
/// Policy Object Handle.
///
///
///
/// Pointer to the security identifier (SID) of the account from which the privileges are removed.
///
///
///
/// If TRUE, the function removes all privileges and deletes the account. In this case, the function ignores the UserRights
/// parameter. If FALSE, the function removes the privileges specified by the UserRights parameter.
///
///
///
///
/// Pointer to an array of LSA_UNICODE_STRING structures. Each structure contains the name of a privilege to be removed from the
/// account. For a list of privilege names, see Privilege Constants.
///
///
///
/// If the function succeeds, the return value is STATUS_SUCCESS.
///
/// If the function fails, the return value is an NTSTATUS code, which can be one of the following values or one of the LSA Policy
/// Function Return Values.
///
///
///
/// Value
/// Description
///
/// -
/// STATUS_NO_SUCH_PRIVILEGE
/// One of the privilege names is not valid.
///
/// -
/// STATUS_INVALID_PARAMETER
/// Indicates the UserRights parameter was NULL and the AllRights parameter was FALSE.
///
///
/// You can use the LsaNtStatusToWinError function to convert the NTSTATUS code to a Windows error code.
///
// https://docs.microsoft.com/en-us/windows/desktop/api/ntsecapi/nf-ntsecapi-lsaremoveaccountrights NTSTATUS LsaRemoveAccountRights(
// LSA_HANDLE PolicyHandle, PSID AccountSid, BOOLEAN AllRights, PLSA_UNICODE_STRING UserRights, ULONG CountOfRights );
[PInvokeData("ntsecapi.h", MSDNShortId = "ad250a01-7a24-4fae-975c-aa3e65731c82")]
// public static extern NTSTATUS LsaRemoveAccountRights(LSA_HANDLE PolicyHandle, PSID AccountSid, [MarshalAs(UnmanagedType.U1)] bool
// AllRights, PLSA_UNICODE_STRING UserRights, uint CountOfRights);
public static NTStatus LsaRemoveAccountRights(LSA_HANDLE PolicyHandle, PSID AccountSid, [MarshalAs(UnmanagedType.Bool)] bool AllRights,
[In, MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(LsaUnicodeStringArrayMarshaler))] params string[] UserRights) =>
LsaRemoveAccountRights(PolicyHandle, AccountSid, AllRights, UserRights, (uint)UserRights?.Length);
/// Do not use the LSA private data functions. Instead, use the CryptProtectData and CryptUnprotectData functions.
///
/// A handle to a Policy object. The handle must have the POLICY_GET_PRIVATE_INFORMATION access right. For more information, see
/// Opening a Policy Object Handle.
///
///
/// Pointer to an LSA_UNICODE_STRING structure that contains the name of the key under which the private data is stored.
/// To create a specialized object, add one of the following prefixes to the key name.
///
///
/// Prefix
/// Meaning
///
/// -
/// L$
/// For local objects.
///
/// -
/// G$
/// For global objects.
///
/// -
/// M$
/// For computer objects.
///
///
///
/// If you are not creating one of these specialized types, you do not need to specify a key name prefix. For more information, see
/// Private Data Object.
///
///
///
/// Pointer to a variable that receives a pointer to an LSA_UNICODE_STRING structure that contains the private data.
/// When you no longer need the information, pass the returned pointer to LsaFreeMemory.
///
///
/// If the function succeeds, the function returns STATUS_SUCCESS.
///
/// If the function fails, it returns an NTSTATUS value, which can be the following value or one of the LSA Policy Function
/// Return Values.
///
///
///
/// Return code
/// Description
///
/// -
/// STATUS_OBJECT_NAME_NOT_FOUND
/// No private data is stored under the name specified by the KeyName parameter.
///
///
/// You can use the LsaNtStatusToWinError function to convert the NTSTATUS value to a Windows error code.
///
/// You must run this process "As Administrator" or the call fails with ERROR_ACCESS_DENIED.
// https://docs.microsoft.com/en-us/windows/desktop/api/ntsecapi/nf-ntsecapi-lsaretrieveprivatedata NTSTATUS LsaRetrievePrivateData(
// LSA_HANDLE PolicyHandle, PLSA_UNICODE_STRING KeyName, PLSA_UNICODE_STRING *PrivateData );
[DllImport(Lib.AdvApi32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("ntsecapi.h", MSDNShortId = "005460db-0919-46eb-b057-37c5b6042243")]
public static extern NTStatus LsaRetrievePrivateData(LSA_HANDLE PolicyHandle, [In, MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(LsaUnicodeStringMarshaler))] string KeyName,
out SafeLsaMemoryHandle PrivateData);
/// The LsaSetDomainInformationPolicy function sets domain information to the Policyobject.
/// A handle to the Policy object for the system.
///
///
/// POLICY_DOMAIN_INFORMATION_CLASS enumeration that specifies the information to be set to the Policyobject. The following table
/// shows the possible values.
///
///
///
/// Value
/// Meaning
///
/// -
/// PolicyDomainEfsInformation
/// The information is for Encrypting File System.
///
/// -
/// PolicyDomainKerberosTicketInformation
/// The information is for a Kerberos ticket.
///
///
///
/// Pointer to a buffer that contains the information to set to the Policyobject.
///
/// If the function succeeds, the return value is STATUS_SUCCESS.
///
/// If the function fails, the return value is an NTSTATUS code, which can be the following value or one of the LSA Policy Function
/// Return Values.
///
///
///
/// Return code/value
/// Description
///
/// -
/// STATUS_INTERNAL_DB_CORRUPTION
/// The policy database is corrupt. The returned policy information is not valid for the given class.
///
///
///
///
/// The POLICY_TRUST_ADMIN access type is required to set domain information to the Policyobject. For more information, see Policy
/// Object Access Rights.
///
// https://docs.microsoft.com/en-us/windows/desktop/api/ntsecapi/nf-ntsecapi-lsasetdomaininformationpolicy NTSTATUS
// LsaSetDomainInformationPolicy( LSA_HANDLE PolicyHandle, POLICY_DOMAIN_INFORMATION_CLASS InformationClass, PVOID Buffer );
[DllImport(Lib.AdvApi32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("ntsecapi.h", MSDNShortId = "77af6fdc-a52e-476c-9de2-36ee48133a87")]
public static extern NTStatus LsaSetDomainInformationPolicy(LSA_HANDLE PolicyHandle, POLICY_DOMAIN_INFORMATION_CLASS InformationClass, IntPtr Buffer);
/// The LsaSetDomainInformationPolicy function sets domain information to the Policyobject.
/// The type of the structure being passed as .
/// A handle to the Policy object for the system.
/// The information to set to the Policyobject.
///
/// The POLICY_TRUST_ADMIN access type is required to set domain information to the Policyobject. For more information, see Policy
/// Object Access Rights.
///
[PInvokeData("ntsecapi.h", MSDNShortId = "77af6fdc-a52e-476c-9de2-36ee48133a87")]
public static void LsaSetDomainInformationPolicy(LSA_HANDLE PolicyHandle, in T value) where T : struct
{
if (!CorrespondingTypeAttribute.CanSet(out var ic))
throw new ArgumentException($"Unable to use {typeof(T).Name} with this function.");
using var mem = SafeHGlobalHandle.CreateFromStructure(value);
LsaSetDomainInformationPolicy(PolicyHandle, ic, mem).ThrowIfFailed();
}
///
///
/// The LsaSetForestTrustInformation function sets the forest trust information for a specified Local Security Authority
/// TrustedDomain object.
///
///
///
/// A handle to the Policy object for the system.
///
///
///
/// Pointer to an LSA_UNICODE_STRING structure that contains the name of the TrustedDomain object to which to set the forest trust
/// information specified by the ForestTrustInfo parameter.
///
///
///
///
/// Pointer to an LSA_FOREST_TRUST_INFORMATION structure that contains the forest trust information to set to the TrustedDomain
/// object specified by the TrustedDomainName parameter.
///
///
///
///
/// Boolean value that specifies whether changes to the TrustedDomain object are persisted. If this value is TRUE, this
/// function will check for collisions with the specified parameters but will not set the forest trust information specified by the
/// ForestTrustInfo parameter to the TrustedDomain object specified by the TrustedDomainName parameter. If this value is
/// FALSE, the forest trust information will be set to the TrustedDomain object.
///
///
///
///
/// Pointer to a pointer to an LSA_FOREST_TRUST_COLLISION_INFORMATION structure that returns information about any collisions that occurred.
///
///
///
/// If the function succeeds, the return value is STATUS_SUCCESS.
///
/// If the function fails, the return value is an NTSTATUS code, which can be one of the following values or one of the LSA Policy
/// Function Return Values.
///
///
///
/// Return code/value
/// Description
///
/// -
/// STATUS_INVALID_DOMAIN_STATE
/// The operation is legal only on domain controllers in the root domain.
///
/// -
/// STATUS_INVALID_DOMAIN_ROLE
/// The operation is legal only on the primary domain controller.
///
///
///
// https://docs.microsoft.com/en-us/windows/desktop/api/ntsecapi/nf-ntsecapi-lsasetforesttrustinformation NTSTATUS
// LsaSetForestTrustInformation( LSA_HANDLE PolicyHandle, PLSA_UNICODE_STRING TrustedDomainName, PLSA_FOREST_TRUST_INFORMATION
// ForestTrustInfo, BOOLEAN CheckOnly, PLSA_FOREST_TRUST_COLLISION_INFORMATION *CollisionInfo );
[DllImport(Lib.AdvApi32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("ntsecapi.h", MSDNShortId = "8b0f90ed-7dd4-4803-97c6-31d191b6d2b3")]
public static extern NTStatus LsaSetForestTrustInformation(LSA_HANDLE PolicyHandle, [In, MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(LsaUnicodeStringMarshaler))] string TrustedDomainName,
in LSA_FOREST_TRUST_INFORMATION ForestTrustInfo, [MarshalAs(UnmanagedType.U1)] bool CheckOnly, out SafeLsaMemoryHandle CollisionInfo);
/// The LsaSetInformationPolicy function modifies information in a Policy object.
///
/// A handle to a Policy object. The required access rights for this handle depend on the value of the InformationClass parameter.
/// For more information, see Opening a Policy Object Handle.
///
///
///
/// Specifies one of the following values from the POLICY_INFORMATION_CLASS enumeration type. The value indicates the type of
/// information to set.
///
///
///
/// Value
/// Meaning
///
/// -
/// PolicyAuditEventsInformation
///
/// Sets the system's auditing rules. The handle passed in the PolicyHandle parameter must have the POLICY_SET_AUDIT_REQUIREMENTS
/// access right. The Buffer parameter must be a pointer to a POLICY_AUDIT_EVENTS_INFO structure.
///
///
/// -
/// PolicyPrimaryDomainInformation
///
/// Sets the name and SID of the system's primary domain. The handle passed in the PolicyHandle parameter must have the
/// POLICY_TRUST_ADMIN access right. The Buffer parameter must be a pointer to a POLICY_PRIMARY_DOMAIN_INFO structure.
///
///
/// -
/// PolicyAccountDomainInformation
///
/// Sets the name and SID of the system's account domain. The handle passed in the PolicyHandle parameter must have the
/// POLICY_TRUST_ADMIN access right. The Buffer parameter must be a pointer to a POLICY_ACCOUNT_DOMAIN_INFO structure.
///
///
/// -
/// PolicyDnsDomainInformation
///
/// Sets Domain Name System (DNS) information about the primary domain associated with the Policy object. The handle passed in the
/// PolicyHandle parameter must have the POLICY_TRUST_ADMIN access right. The Buffer parameter must be a pointer to a
/// POLICY_DNS_DOMAIN_INFO structure.
///
///
/// -
/// PolicyLsaServerRoleInformation
///
/// Sets the role of an LSA server. The handle passed in the PolicyHandle parameter must have the POLICY_SERVER_ADMIN access right.
/// The Buffer parameter must be a pointer to a POLICY_LSA_SERVER_ROLE_INFO structure. Changing a server's role from primary to
/// backup has no effect (although the function returns STATUS_SUCCESS). Changing a server's role from backup to primary requires
/// extensive network operations and may be slow.
///
///
///
///
///
/// Pointer to a structure containing the information to set. The type of structure depends on the value of the InformationClass parameter.
///
///
/// If the function succeeds, the return value is STATUS_SUCCESS.
/// If the function fails, the return value is an NTSTATUS code. For more information, see LSA Policy Function Return Values.
/// You can use the LsaNtStatusToWinError function to convert the NTSTATUS code to a Windows error code.
///
// https://docs.microsoft.com/en-us/windows/desktop/api/ntsecapi/nf-ntsecapi-lsasetinformationpolicy NTSTATUS
// LsaSetInformationPolicy( LSA_HANDLE PolicyHandle, POLICY_INFORMATION_CLASS InformationClass, PVOID Buffer );
[DllImport(Lib.AdvApi32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("ntsecapi.h", MSDNShortId = "2aa3b09e-2cd9-4a09-bfd6-b37c97266dcb")]
public static extern NTStatus LsaSetInformationPolicy(LSA_HANDLE PolicyHandle, POLICY_INFORMATION_CLASS InformationClass, IntPtr Buffer);
///
/// The LsaSetInformationPolicy function modifies information in a Policy object.
///
/// The type of the structure being passed as .
/// A handle to a Policy object. The required access rights for this handle depend on the value of the InformationClass parameter.
/// For more information, see Opening a Policy Object Handle.
/// A structure containing the information to set.
/// Unable to use {typeof(T).Name} with this function.
[PInvokeData("ntsecapi.h", MSDNShortId = "2aa3b09e-2cd9-4a09-bfd6-b37c97266dcb")]
public static void LsaSetInformationPolicy(LSA_HANDLE PolicyHandle, in T value) where T : struct
{
if (!CorrespondingTypeAttribute.CanSet(out var ic))
throw new ArgumentException($"Unable to use {typeof(T).Name} with this function.");
using var mem = SafeHGlobalHandle.CreateFromStructure(value);
LsaSetInformationPolicy(PolicyHandle, ic, mem).ThrowIfFailed();
}
/// Undocumented.
/// The account handle.
/// The system access.
///
/// If the function succeeds, the return value is STATUS_SUCCESS. If the function fails, the return value is an NTSTATUS code, which
/// can be one of the following values or one of the LSA Policy Function Return Values.
///
[PInvokeData("ntlsa.h")]
[DllImport(Lib.AdvApi32, ExactSpelling = true)]
public static extern NTStatus LsaSetSystemAccessAccount(LSA_HANDLE AccountHandle, int SystemAccess);
/// The LsaSetTrustedDomainInfoByName function sets values for a TrustedDomain object.
///
/// A handle to a Policy object. The security descriptor of the trusted domain object determines whether the caller's changes are
/// accepted. For information about policy object handles, see Opening a Policy Object Handle.
///
///
/// Name of the trusted domain to set values for. This can either be the domain name or the flat name.
///
///
/// Specifies the type of information to set. Specify one of the following values.
///
///
/// Value
/// Meaning
///
/// -
/// TrustedPosixInformation
/// Posix offset of the trusted domain.
///
/// -
/// TrustedDomainInformationEx
/// Extended trust information, including the basic information and DNS domain name, and attributes about the trust.
///
/// -
/// TrustedDomainAuthInformation
///
/// Authentication information for the trust, including authentication information for both the inbound and outbound side of the
/// trust (if it exists).
///
///
/// -
/// TrustedDomainFullInformation
/// Full information, including the Posix offset and the authentication information.
///
///
///
///
/// Pointer to a structure that contains the information to set. The type of structure depends on the value of the InformationClass parameter.
///
///
/// If the function succeeds, the return value is STATUS_SUCCESS.
///
/// If the function fails, the return value is an NTSTATUS code. For more information, see the "LSA Policy Function Return Values"
/// section of Security Management Return Values.
///
/// You can use the LsaNtStatusToWinError function to convert the NTSTATUS code to a Windows error code.
///
// https://docs.microsoft.com/en-us/windows/desktop/api/ntsecapi/nf-ntsecapi-lsasettrusteddomaininfobyname NTSTATUS
// LsaSetTrustedDomainInfoByName( LSA_HANDLE PolicyHandle, PLSA_UNICODE_STRING TrustedDomainName, TRUSTED_INFORMATION_CLASS
// InformationClass, PVOID Buffer );
[DllImport(Lib.AdvApi32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("ntsecapi.h", MSDNShortId = "263e1025-1010-463d-8bc7-cdf916ce9872")]
public static extern NTStatus LsaSetTrustedDomainInfoByName(LSA_HANDLE PolicyHandle, [In, MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(LsaUnicodeStringMarshaler))] string TrustedDomainName,
TRUSTED_INFORMATION_CLASS InformationClass, IntPtr Buffer);
///
/// The LsaSetTrustedDomainInformation function modifies a Policy object's information about a trusted domain.
///
///
///
/// A handle to the Policy object of a domain controller. The required user rights for this handle depend on the value of the
/// InformationClass parameter. For more information, see Opening a Policy Object Handle.
///
///
///
///
/// Pointer to the SID of the trusted domain whose information is modified. If the InformationClass parameter is set to
/// TrustedDomainNameInformation, this parameter must point to the SID of the domain to add to the list of trusted domains.
///
///
///
///
/// Specifies one of the following values from the TRUSTED_INFORMATION_CLASS enumeration type. The value indicates the type of
/// information being set.
///
///
///
/// Value
/// Meaning
///
/// -
/// TrustedDomainNameInformation
///
/// If the specified domain is not in the list of trusted domains, the LsaSetTrustedDomainInformation function adds it. The
/// TrustedDomainSid parameter must be the SID of the domain to add. The Buffer parameter must be a pointer to a
/// TRUSTED_DOMAIN_NAME_INFO structure containing the name of the domain to add. If the specified domain is already in the list of
/// trusted domains, the function fails.
///
///
/// -
/// TrustedPosixOffsetInformation
///
/// Sets the value used to generate Posix user and group identifiers. The Buffer parameter must be a pointer to a
/// TRUSTED_POSIX_OFFSET_INFO structure.
///
///
/// -
/// TrustedPasswordInformation
///
/// Sets the password for the trusted domain. The Buffer parameter must be a pointer to a TRUSTED_PASSWORD_INFO structure containing
/// the old and new passwords for the specified domain. The handle passed in the PolicyHandle parameter must have the
/// POLICY_CREATE_SECRET access right. The old password string can be NULL.
///
///
///
///
///
///
/// Pointer to a structure containing the information to set. The type of structure depends on the value of the InformationClass parameter.
///
///
///
/// If the function succeeds, the return value is STATUS_SUCCESS.
/// If the function fails, the return value is an NTSTATUS code. For more information, see LSA Policy Function Return Values.
/// You can use the LsaNtStatusToWinError function to convert the NTSTATUS code to a Windows error code.
///
// https://docs.microsoft.com/en-us/windows/desktop/api/ntsecapi/nf-ntsecapi-lsasettrusteddomaininformation NTSTATUS
// LsaSetTrustedDomainInformation( LSA_HANDLE PolicyHandle, PSID TrustedDomainSid, TRUSTED_INFORMATION_CLASS InformationClass, PVOID
// Buffer );
[DllImport(Lib.AdvApi32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("ntsecapi.h", MSDNShortId = "a7b89ea7-af92-46ba-ac73-2fba1cc27680")]
public static extern NTStatus LsaSetTrustedDomainInformation(LSA_HANDLE PolicyHandle, PSID TrustedDomainSid, TRUSTED_INFORMATION_CLASS InformationClass, IntPtr Buffer);
/// Do not use the LSA private data functions. Instead, use the CryptProtectData and CryptUnprotectData functions.
///
/// A handle to a Policy object. The handle must have the POLICY_CREATE_SECRET access right if this is the first time data is being
/// stored under the key specified by the KeyName parameter. For more information, see Opening a Policy Object Handle.
///
///
/// Pointer to an LSA_UNICODE_STRING structure containing the name of the key under which the private data is stored.
///
///
///
/// Pointer to an LSA_UNICODE_STRING structure containing the private data to store. The function encrypts this data before storing it.
///
///
/// If this parameter is NULL, the function deletes any private data stored under the key and deletes the key. Subsequent
/// attempts to retrieve data from the key will return the STATUS_OBJECT_NAME_NOT_FOUND error code.
///
///
///
/// If the function succeeds, the return value is STATUS_SUCCESS.
/// If the function fails, the return value is an NTSTATUS code. For more information, see LSA Policy Function Return Values.
/// You can use the LsaNtStatusToWinError function to convert the NTSTATUS code to a Windows error code.
///
///
/// The LsaStorePrivateData function can be used by server applications to store client and machine passwords.
///
/// As described in Private Data Object, private data objects include three specialized types: local, global, and machine.
/// Specialized objects are identified by a prefix in the key name: "L$" for local objects, "G$" for global objects, and "M$" for
/// machine objects. Local objects cannot be accessed remotely. Machine objects can be accessed only by the operating system.
///
///
/// In addition to these prefixes, the following values also indicate local or machine objects. These values are supported for
/// backward compatibility and should not be used when you create new local or machine objects. The key name of local private data
/// objects may also be "$machine.acc", "SAC", "SAI", "SANSC", or start with "RasDialParms" or "RasCredentials". The key name for
/// machine objects may also start with, "NL$" or "sc".
///
///
/// Private data objects which do not use any of the preceding key name conventions can be accessed remotely and are not replicated
/// to other domains.
///
///
/// The data stored by the LsaStorePrivateData function is not absolutely protected. However, the data is encrypted before
/// being stored, and the key has a DACL that allows only the creator and administrators to read the data.
///
/// Use the LsaRetrievePrivateData function to retrieve the value stored by LsaStorePrivateData.
///
// https://docs.microsoft.com/en-us/windows/desktop/api/ntsecapi/nf-ntsecapi-lsastoreprivatedata NTSTATUS LsaStorePrivateData(
// LSA_HANDLE PolicyHandle, PLSA_UNICODE_STRING KeyName, PLSA_UNICODE_STRING PrivateData );
[DllImport(Lib.AdvApi32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("ntsecapi.h", MSDNShortId = "95d6cf30-fd08-473e-b0b3-3f7ca5e85357")]
public static extern NTStatus LsaStorePrivateData(LSA_HANDLE PolicyHandle, [In, MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(LsaUnicodeStringMarshaler))] string KeyName,
[In, MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(LsaUnicodeStringMarshaler))] string PrivateData);
///
/// The LsaClose function closes a handle to a Policy or TrustedDomain object.
///
///
///
/// A handle to a Policy object returned by the LsaOpenPolicy function or to a TrustedDomain object returned by the
/// LsaOpenTrustedDomainByName function. Following the completion of this call, the handle is no longer valid.
///
///
///
/// If the function succeeds, the return value is STATUS_SUCCESS.
/// If the function fails, the return value is an NTSTATUS code. For more information, see LSA Policy Function Return Values.
/// You can use the LsaNtStatusToWinError function to convert the NTSTATUS code to a Windows error code.
///
// https://docs.microsoft.com/en-us/windows/desktop/api/ntsecapi/nf-ntsecapi-lsaclose NTSTATUS LsaClose( LSA_HANDLE ObjectHandle );
[DllImport(Lib.AdvApi32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("ntsecapi.h", MSDNShortId = "6283b1da-4ec3-48e1-91f6-321c6390befe")]
// public static extern NTSTATUS LsaClose(LSA_HANDLE ObjectHandle);
private static extern NTStatus LsaClose(LSA_HANDLE ObjectHandle);
///
///
/// The LsaFreeMemory function frees memory allocated for an output buffer by an LSA function call. LSA functions that return
/// variable-length output buffers always allocate the buffer on behalf of the caller. The caller must free this memory by passing
/// the returned buffer pointer to LsaFreeMemory when the memory is no longer required.
///
///
///
///
/// Pointer to memory buffer that was allocated by an LSA function call. If LsaFreeMemory is successful, this buffer is freed.
///
///
///
/// If the function succeeds, the return value is STATUS_SUCCESS.
///
/// If the function fails, the return value is an NTSTATUS code, which can be the following value or one of the LSA Policy Function
/// Return Values.
///
///
///
/// Return code
/// Description
///
/// -
/// STATUS_UNSUCCESSFUL
/// Memory could not be freed because it was not allocated by an LSA function call.
///
///
/// You can use the LsaNtStatusToWinError function to convert the NTSTATUS code to a Windows error code.
///
// https://docs.microsoft.com/en-us/windows/desktop/api/ntsecapi/nf-ntsecapi-lsafreememory NTSTATUS LsaFreeMemory( PVOID Buffer );
[DllImport(Lib.AdvApi32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("ntsecapi.h", MSDNShortId = "6eb3d18f-c54c-4e51-8a4b-b7a3f930cfa9")]
// public static extern NTSTATUS LsaFreeMemory(IntPtr Buffer);
private static extern NTStatus LsaFreeMemory(IntPtr Buffer);
/// Provides a handle to an LSA enumeration.
[StructLayout(LayoutKind.Sequential)]
public struct LSA_ENUMERATION_HANDLE : IHandle
{
private readonly IntPtr handle;
/// Initializes a new instance of the struct.
/// An object that represents the pre-existing handle to use.
public LSA_ENUMERATION_HANDLE(IntPtr preexistingHandle) => handle = preexistingHandle;
/// Returns an invalid handle by instantiating a object with .
public static LSA_ENUMERATION_HANDLE NULL => new LSA_ENUMERATION_HANDLE(IntPtr.Zero);
/// Gets a value indicating whether this instance is a null handle.
public bool IsNull => handle == IntPtr.Zero;
/// Performs an explicit conversion from to .
/// The handle.
/// The result of the conversion.
public static explicit operator IntPtr(LSA_ENUMERATION_HANDLE h) => h.handle;
/// Performs an implicit conversion from to .
/// The pointer to a handle.
/// The result of the conversion.
public static implicit operator LSA_ENUMERATION_HANDLE(IntPtr h) => new LSA_ENUMERATION_HANDLE(h);
/// Implements the operator !=.
/// The first handle.
/// The second handle.
/// The result of the operator.
public static bool operator !=(LSA_ENUMERATION_HANDLE h1, LSA_ENUMERATION_HANDLE h2) => !(h1 == h2);
/// Implements the operator ==.
/// The first handle.
/// The second handle.
/// The result of the operator.
public static bool operator ==(LSA_ENUMERATION_HANDLE h1, LSA_ENUMERATION_HANDLE h2) => h1.Equals(h2);
///
public override bool Equals(object obj) => obj is LSA_ENUMERATION_HANDLE h ? handle == h.handle : false;
///
public override int GetHashCode() => handle.GetHashCode();
///
public IntPtr DangerousGetHandle() => handle;
}
/// Used with the LsaEnumerateAccountsWithUserRight function to return a pointer to a SID.
// https://docs.microsoft.com/en-us/windows/desktop/api/ntsecapi/ns-ntsecapi-_lsa_enumeration_information typedef struct
// _LSA_ENUMERATION_INFORMATION { PSID Sid; } LSA_ENUMERATION_INFORMATION, *PLSA_ENUMERATION_INFORMATION;
[PInvokeData("ntsecapi.h", MSDNShortId = "7577548f-3ceb-43a5-b447-6f66a09963fe")]
[StructLayout(LayoutKind.Sequential)]
public struct LSA_ENUMERATION_INFORMATION
{
/// Pointer to a SID.
public PSID Sid;
}
///
/// The LSA_FOREST_TRUST_BINARY_DATA structure contains binary data used in Local Security Authority forest trust operations.
///
// https://docs.microsoft.com/en-us/windows/desktop/api/ntsecapi/ns-ntsecapi-_lsa_forest_trust_binary_data typedef struct
// _LSA_FOREST_TRUST_BINARY_DATA { #if ... ULONG Length; #if ... PUCHAR Buffer; #else ULONG Length; #endif #else PUCHAR Buffer;
// #endif } LSA_FOREST_TRUST_BINARY_DATA, *PLSA_FOREST_TRUST_BINARY_DATA;
[PInvokeData("ntsecapi.h", MSDNShortId = "2ddcf54e-c30f-4146-8cb6-71fcdd42ae68")]
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
public struct LSA_FOREST_TRUST_BINARY_DATA
{
/// The count of bytes in Buffer.
public uint Length;
/// The trust record. If the Length field has a value other than 0, this field MUST NOT be NULL.
public IntPtr Buffer;
}
///
/// The LSA_FOREST_TRUST_COLLISION_INFORMATION structure contains information about Local Security Authority forest trust collisions.
///
// https://docs.microsoft.com/en-us/windows/desktop/api/ntsecapi/ns-ntsecapi-lsa_forest_trust_collision_information typedef struct
// _LSA_FOREST_TRUST_COLLISION_INFORMATION { ULONG RecordCount; PLSA_FOREST_TRUST_COLLISION_RECORD *Entries; }
// LSA_FOREST_TRUST_COLLISION_INFORMATION, *PLSA_FOREST_TRUST_COLLISION_INFORMATION;
[PInvokeData("ntsecapi.h", MSDNShortId = "a4a3b040-c074-4756-a30f-408d8bca87ba")]
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
public struct LSA_FOREST_TRUST_COLLISION_INFORMATION
{
/// Number of LSA_FOREST_TRUST_COLLISION_RECORD structures in the array pointed to by the Entries member.
public uint RecordCount;
///
/// Pointer to a pointer to an array of LSA_FOREST_TRUST_COLLISION_RECORD structures, each of which contains information about a
/// single collision.
///
public IntPtr Entries;
}
///
/// The LSA_FOREST_TRUST_COLLISION_RECORD structure contains information about a Local Security Authority forest trust collision.
///
// https://docs.microsoft.com/en-us/windows/desktop/api/ntsecapi/ns-ntsecapi-lsa_forest_trust_collision_record typedef struct
// _LSA_FOREST_TRUST_COLLISION_RECORD { ULONG Index; LSA_FOREST_TRUST_COLLISION_RECORD_TYPE Type; ULONG Flags; LSA_UNICODE_STRING
// Name; } LSA_FOREST_TRUST_COLLISION_RECORD, *PLSA_FOREST_TRUST_COLLISION_RECORD;
[PInvokeData("ntsecapi.h", MSDNShortId = "9f9d2f57-0e7f-4222-be35-e3f026b60e93")]
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
public struct LSA_FOREST_TRUST_COLLISION_RECORD
{
///
/// Index of this collision record in the array of LSA_FOREST_TRUST_COLLISION_RECORD structures pointed to by the
/// Entries member of the LSA_FOREST_TRUST_COLLISION_INFORMATION structure.
///
public uint Index;
///
/// Type of the collision. The following table shows the possible values.
///
///
/// Value
/// Meaning
///
/// -
/// CollisionTdo
/// Collision between TrustedDomain objects.
///
/// -
/// CollisionXref
/// Collision between cross-references.
///
/// -
/// CollisionOther
/// Collision that is not a collision between TrustedDomain objects or cross-references.
///
///
///
public LSA_FOREST_TRUST_COLLISION_RECORD_TYPE Type;
///
///
/// Flags that provide more information about the collision. The following table lists the possible values for this member when
/// the Type member is CollisionTdo.
///
/// LSA_TLN_DISABLED_NEW (0x00000001)
/// LSA_TLN_DISABLED_ADMIN (0x00000002)
/// LSA_TLN_DISABLED_CONFLICT (0x00000004)
/// The following table lists the possible values for this member when the Type member is CollisionXref.
/// LSA_SID_DISABLED_ADMIN (0x00000001)
/// LSA_SID_DISABLED_CONFLICT (0x00000002)
/// LSA_NB_DISABLED_ADMIN (0x00000004)
/// LSA_NB_DISABLED_CONFLICT (0x00000008)
///
public CollisionFlags Flags;
/// LSA_UNICODE_STRING structure that contains the name of the collision record.
public LSA_UNICODE_STRING Name;
}
/// The LSA_FOREST_TRUST_DOMAIN_INFO structure contains identifying information for a domain.
// https://docs.microsoft.com/en-us/windows/desktop/api/ntsecapi/ns-ntsecapi-_lsa_forest_trust_domain_info typedef struct
// _LSA_FOREST_TRUST_DOMAIN_INFO { #if ... PISID Sid; #else PSID Sid; #endif LSA_UNICODE_STRING DnsName; LSA_UNICODE_STRING
// NetbiosName; } LSA_FOREST_TRUST_DOMAIN_INFO, *PLSA_FOREST_TRUST_DOMAIN_INFO;
[PInvokeData("ntsecapi.h", MSDNShortId = "c0e06735-ca10-4bee-a45b-6db5b6666e31")]
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
public struct LSA_FOREST_TRUST_DOMAIN_INFO
{
/// Domain SID for the trusted domain.
public PSID Sid;
/// LSA_UNICODE_STRING structure that contains the DNS name of the domain.
public LSA_UNICODE_STRING DnsName;
/// LSA_UNICODE_STRING structure that contains the NetBIOS name of the domain.
public LSA_UNICODE_STRING NetbiosName;
}
/// The LSA_FOREST_TRUST_INFORMATION structure contains Local Security Authority forest trust information.
// https://docs.microsoft.com/en-us/windows/desktop/api/ntsecapi/ns-ntsecapi-_lsa_forest_trust_information typedef struct
// _LSA_FOREST_TRUST_INFORMATION { #if ... ULONG RecordCount; #if ... PLSA_FOREST_TRUST_RECORD *Entries; #else ULONG RecordCount;
// #endif #else PLSA_FOREST_TRUST_RECORD *Entries; #endif } LSA_FOREST_TRUST_INFORMATION, *PLSA_FOREST_TRUST_INFORMATION;
[PInvokeData("ntsecapi.h", MSDNShortId = "9e456462-59a9-4f18-ba47-92fc2350889b")]
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
public struct LSA_FOREST_TRUST_INFORMATION
{
/// A count of elements in the Entries array.
public uint RecordCount;
///
/// An array of LSA_FOREST_TRUST_RECORD structures. If the RecordCount field has a value other than 0, this field MUST NOT be NULL.
///
public IntPtr Entries;
}
///
/// The LSA_FOREST_TRUST_RECORD structure represents a Local Security Authority forest trust record.
///
// https://docs.microsoft.com/en-us/windows/desktop/api/ntsecapi/ns-ntsecapi-_lsa_forest_trust_record typedef struct
// _LSA_FOREST_TRUST_RECORD { ULONG Flags; LSA_FOREST_TRUST_RECORD_TYPE ForestTrustType; LARGE_INTEGER Time; #if ... union {
// LSA_UNICODE_STRING TopLevelName; LSA_FOREST_TRUST_DOMAIN_INFO DomainInfo; LSA_FOREST_TRUST_BINARY_DATA Data; } ForestTrustData;
// #else union { LSA_UNICODE_STRING TopLevelName; LSA_FOREST_TRUST_DOMAIN_INFO DomainInfo; LSA_FOREST_TRUST_BINARY_DATA Data; }
// ForestTrustData; #endif } LSA_FOREST_TRUST_RECORD, *PLSA_FOREST_TRUST_RECORD;
[PInvokeData("ntsecapi.h", MSDNShortId = "19b4ee56-664f-4f37-bfc9-129032ebeb22")]
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
public struct LSA_FOREST_TRUST_RECORD
{
/// Flags that control the behavior of the operation.
public LSA_TLN Flags;
///
///
/// LSA_FOREST_TRUST_RECORD_TYPE enumeration that indicates the type of the record. The following table shows the possible values.
///
///
///
/// Value
/// Meaning
///
/// -
/// ForestTrustTopLevelName
/// Record contains an included top-level name.
///
/// -
/// ForestTrustTopLevelNameEx
/// Record contains an excluded top-level name.
///
/// -
/// ForestTrustDomainInfo
/// Record contains an LSA_FOREST_TRUST_DOMAIN_INFO structure.
///
/// -
/// ForestTrustRecordTypeLast
/// Marks the end of an enumeration.
///
///
///
public LSA_FOREST_TRUST_RECORD_TYPE ForestTrustType;
/// Time stamp of the record.
public FILETIME Time;
///
/// An LSA_UNICODE_STRING or LSA_FOREST_TRUST_DOMAIN_INFO structure, depending on the value ForestTrustType as specified in the
/// structure definition for LSA_FOREST_TRUST_RECORD.
///
public ForestTrustDataUnion ForestTrustData;
///
/// An LSA_UNICODE_STRING or LSA_FOREST_TRUST_DOMAIN_INFO structure, depending on the value ForestTrustType as specified in the
/// structure definition for LSA_FOREST_TRUST_RECORD.
///
[StructLayout(LayoutKind.Explicit)]
public struct ForestTrustDataUnion
{
/// Top-level name. This member is used only if the ForestTrustType member is ForestTrustTopLevelName or ForestTrustTopLevelNameEx.
[FieldOffset(0)]
public LSA_UNICODE_STRING TopLevelName;
/// Domain information. This member is used only if the ForestTrustType member is ForestTrustDomainInfo.
[FieldOffset(0)]
public LSA_FOREST_TRUST_DOMAIN_INFO DomainInfo;
/// Binary data. This member is used for unrecognized entries after ForestTrustRecordTypeLast.
[FieldOffset(0)]
public LSA_FOREST_TRUST_BINARY_DATA Data;
}
}
/// Provides a handle to a LSA handle.
[StructLayout(LayoutKind.Sequential)]
public struct LSA_HANDLE : IHandle
{
private readonly IntPtr handle;
/// Initializes a new instance of the struct.
/// An object that represents the pre-existing handle to use.
public LSA_HANDLE(IntPtr preexistingHandle) => handle = preexistingHandle;
/// Returns an invalid handle by instantiating a object with .
public static LSA_HANDLE NULL => new LSA_HANDLE(IntPtr.Zero);
/// Gets a value indicating whether this instance is a null handle.
public bool IsNull => handle == IntPtr.Zero;
/// Performs an explicit conversion from to .
/// The handle.
/// The result of the conversion.
public static explicit operator IntPtr(LSA_HANDLE h) => h.handle;
/// Performs an implicit conversion from to .
/// The pointer to a handle.
/// The result of the conversion.
public static implicit operator LSA_HANDLE(IntPtr h) => new LSA_HANDLE(h);
/// Implements the operator !=.
/// The first handle.
/// The second handle.
/// The result of the operator.
public static bool operator !=(LSA_HANDLE h1, LSA_HANDLE h2) => !(h1 == h2);
/// Implements the operator ==.
/// The first handle.
/// The second handle.
/// The result of the operator.
public static bool operator ==(LSA_HANDLE h1, LSA_HANDLE h2) => h1.Equals(h2);
///
public override bool Equals(object obj) => obj is LSA_HANDLE h ? handle == h.handle : false;
///
public override int GetHashCode() => handle.GetHashCode();
///
public IntPtr DangerousGetHandle() => handle;
}
/// The LSA_REFERENCED_DOMAIN_LIST structure contains information about the domains referenced in a lookup operation.
// typedef struct _LSA_REFERENCED_DOMAIN_LIST { ULONG Entries; PLSA_TRUST_INFORMATION Domains;} LSA_REFERENCED_DOMAIN_LIST,
// *PLSA_REFERENCED_DOMAIN_LIST; https://msdn.microsoft.com/en-us/library/windows/desktop/ms721834(v=vs.85).aspx
[PInvokeData("Ntsecapi.h", MSDNShortId = "ms721834")]
[StructLayout(LayoutKind.Sequential)]
public struct LSA_REFERENCED_DOMAIN_LIST
{
/// Specifies the number of entries in the Domains array.
public uint Entries;
/// Pointer to an array of LSA_TRUST_INFORMATION structures that identify the referenced domains.
public IntPtr Domains;
/// Gets the list of structures from the field.
public IEnumerable DomainList => Domains.ToIEnum((int)Entries);
}
///
/// The LSA_TRANSLATED_SID structure is used with the LsaLookupNames function to return information about the SID that
/// identifies an account.
///
// https://docs.microsoft.com/en-us/windows/desktop/api/ntsecapi/ns-ntsecapi-_lsa_translated_sid typedef struct _LSA_TRANSLATED_SID {
// SID_NAME_USE Use; ULONG RelativeId; LONG DomainIndex; } LSA_TRANSLATED_SID, *PLSA_TRANSLATED_SID;
[PInvokeData("ntsecapi.h", MSDNShortId = "1fa8fb74-3e61-4982-aa6b-a0ffe979abd4")]
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
public struct LSA_TRANSLATED_SID
{
///
/// A value from the SID_NAME_USE enumeration type that identifies the type of SID.
///
/// If Use has one of the following values, one or both of the RelativeId or DomainIndex members of
/// LSA_TRANSLATED_SID is not valid. These members are valid if Use has any other value.
///
///
///
/// Value
/// Meaning
///
/// -
/// SidTypeDomain
/// The DomainIndex member is valid, but the RelativeId member is not valid and must be ignored.
///
/// -
/// SidTypeInvalid
/// Both DomainIndex and RelativeId are not valid and must be ignored.
///
/// -
/// SidTypeUnknown
/// Both DomainIndex and RelativeId members are not valid and must be ignored.
///
///
///
public SID_NAME_USE Use;
///
/// Specifies the relative identifier (RID) of the account's SID. The RID identifies the account relative to the domain
/// referenced by the DomainIndex member. The account's complete SID consists of the domain SID followed by the RID.
///
public uint RelativeId;
///
///
/// Specifies the zero-based index of an entry in the LSA_REFERENCED_DOMAIN_LIST structure returned by the LsaLookupNames
/// function. This entry contains the name and SID of the domain in which the account was found.
///
/// If there is no corresponding domain for an account, this member contains a negative value.
///
public int DomainIndex;
}
///
/// The LSA_TRUST_INFORMATION structure identifies a domain.
///
///
/// TRUSTED_DOMAIN_INFORMATION_BASIC is an alias for this structure.
///
/// The TRUSTED_DOMAIN_INFORMATION_BASIC structure identifies a domain. This structure is used by the LsaQueryTrustedDomainInfo
/// function when its InformationClass parameter is set to TrustedDomainInformationBasic.
///
///
// https://docs.microsoft.com/en-us/windows/desktop/api/lsalookup/ns-lsalookup-_lsa_trust_information typedef struct
// _LSA_TRUST_INFORMATION { LSA_UNICODE_STRING Name; PSID Sid; } LSA_TRUST_INFORMATION, *PLSA_TRUST_INFORMATION;
[PInvokeData("lsalookup.h", MSDNShortId = "2b5e6f79-b97a-4018-a45a-37c300c3dc0d")]
[StructLayout(LayoutKind.Sequential)]
public struct LSA_TRUST_INFORMATION
{
/// An LSA_UNICODE_STRING structure that contains the name of the domain.
public LSA_UNICODE_STRING Name;
/// Pointer to the SID of the domain.
public PSID Sid;
}
///
/// The LSA_UNICODE_STRING structure is used by various Local Security Authority (LSA) functions to specify a Unicode string. Also an
/// example of unnecessary over-engineering and re-engineering.
///
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode, Pack = 8)]
[PInvokeData("Ntsecapi.h", MSDNShortId = "ms721841")]
public struct LSA_UNICODE_STRING
{
///
/// Specifies the length, in bytes, of the string pointed to by the Buffer member, not including the terminating null character,
/// if any.
///
public ushort length;
///
/// Specifies the total size, in bytes, of the memory allocated for Buffer. Up to MaximumLength bytes can be written into the
/// buffer without trampling memory.
///
public ushort MaximumLength;
///
/// Pointer to a wide character string. Note that the strings returned by the various LSA functions might not be null-terminated.
///
public StrPtrUni Buffer;
/* REMOVED TO AVOID MEMORY LEAK
*
/// Initializes a new instance of the struct from a string.
/// The string value.
/// String exceeds 32Kb of data.
public LSA_UNICODE_STRING(string s)
{
if (s == null)
{
length = MaximumLength = 0;
Buffer = IntPtr.Zero;
}
else
{
var l = s.Length * UnicodeEncoding.CharSize;
// Unicode strings max. 32KB
if (l >= ushort.MaxValue)
throw new ArgumentException("String too long");
Buffer = s;
length = (ushort)l;
MaximumLength = (ushort)(l + UnicodeEncoding.CharSize);
}
}
*/
/// Gets the number of characters in the string.
public int Length => length / UnicodeEncoding.CharSize;
/// Returns a that represents this instance.
/// A that represents this instance.
public override string ToString() => StringHelper.GetString((IntPtr)Buffer, CharSet.Unicode, length) ?? string.Empty;
/// Performs an implicit conversion from to .
/// The value.
/// The result of the conversion.
public static implicit operator string(LSA_UNICODE_STRING value) => value.ToString();
}
/// Smart wrapper for LSA_FOREST_TRUST_INFORMATION.
public class LsaForestTrustInformation : IDisposable
{
private SafeAllocatedMemoryHandle allocatedMemory;
/// A list of LsaForestTrustRecord entries that wrap LSA_FOREST_TRUST_RECORD.
/// Returns a value.
public List Entries { get; } = new List();
/// Creates a new instance from a memory pointer. This can fail if the memory is not allocated properly.
/// The memory pointer.
/// A new instance of .
public static LsaForestTrustInformation FromBuffer(IntPtr ptr)
{
var ret = new LsaForestTrustInformation();
var info = ptr.ToStructure();
foreach (var e in info.Entries.ToIEnum((int)info.RecordCount))
{
if (e.ForestTrustType == LSA_FOREST_TRUST_RECORD_TYPE.ForestTrustRecordTypeLast) break;
LsaForestTrustRecord rec = null;
switch (e.ForestTrustType)
{
case LSA_FOREST_TRUST_RECORD_TYPE.ForestTrustTopLevelName:
rec = new LsaForestTrustTopLevelName(e.ForestTrustData.TopLevelName, false);
break;
case LSA_FOREST_TRUST_RECORD_TYPE.ForestTrustTopLevelNameEx:
rec = new LsaForestTrustTopLevelName(e.ForestTrustData.TopLevelName, true);
break;
case LSA_FOREST_TRUST_RECORD_TYPE.ForestTrustDomainInfo:
rec = new LsaForestTrustDomainInfo { DnsName = e.ForestTrustData.DomainInfo.DnsName, NetbiosName = e.ForestTrustData.DomainInfo.NetbiosName, Sid = e.ForestTrustData.DomainInfo.Sid };
break;
default:
throw new ArgumentException("Unrecognized record type.", nameof(ptr));
}
rec.Flags = e.Flags;
rec.Time = e.Time.ToDateTime();
ret.Entries.Add(rec);
}
return ret;
}
///
/// Returns an instance of . Warning! The memory allocated for the entries is tied to
/// this instance and will be disposed with it. Thus, if the returned structure is copied, the pointers within it may become
/// invalid if its scope outlives this instance's scope. Subsequent calls to this method will also invalidate the pointers within
/// any previous structures. In other words, just use this method to extract the structure for one time use and ensure this
/// instance does not go out of scope while the structure's being used.
///
/// A instance matching the values of this instance.
public LSA_FOREST_TRUST_INFORMATION DangerousGetLSA_FOREST_TRUST_INFORMATION()
{
((IDisposable)this).Dispose();
allocatedMemory = SafeHGlobalHandle.CreateFromList(Entries.Select(e => e.Convert())); //.Concat(new[] { new LSA_FOREST_TRUST_RECORD { ForestTrustType = LSA_FOREST_TRUST_RECORD_TYPE.ForestTrustRecordTypeLast } }));
return new LSA_FOREST_TRUST_INFORMATION { RecordCount = (uint)Entries.Count, Entries = allocatedMemory.DangerousGetHandle() };
}
/// Releases the unmanaged resources used by this object, and optionally releases the managed resources.
void IDisposable.Dispose() => allocatedMemory?.Dispose();
/// Represents a LSA_FOREST_TRUST_RECORD with the ForestTrustType value set to ForestTrustDomainInfo.
[DebuggerDisplay("DnsName:{DnsName}, NB:{NetbiosName}, Time:{Time:u}, Flg:{Flags}")]
public class LsaForestTrustDomainInfo : LsaForestTrustRecord
{
private SafeLSA_UNICODE_STRING dnsName = new SafeLSA_UNICODE_STRING(null);
private SafeLSA_UNICODE_STRING netbiosName = new SafeLSA_UNICODE_STRING(null);
/// The DNS name of the domain.
public string DnsName { get => dnsName; set => dnsName = value; }
/// The NetBIOS name of the domain.
public string NetbiosName { get => netbiosName; set => netbiosName = value; }
/// Domain SID for the trusted domain.
public SafePSID Sid { get; set; }
/// Converts this instance.
/// A LSA_FOREST_TRUST_RECORD instance.
protected internal override LSA_FOREST_TRUST_RECORD Convert()
{
var ret = base.Convert();
ret.ForestTrustType = LSA_FOREST_TRUST_RECORD_TYPE.ForestTrustDomainInfo;
ret.ForestTrustData.DomainInfo.DnsName = dnsName;
ret.ForestTrustData.DomainInfo.NetbiosName = netbiosName;
ret.ForestTrustData.DomainInfo.Sid = Sid;
return ret;
}
}
/// Represents a LSA_FOREST_TRUST_RECORD.
public abstract class LsaForestTrustRecord
{
/// Flags that control the behavior of the operation.
public LSA_TLN Flags { get; set; }
/// Time stamp of the record.
public DateTime Time { get; set; }
/// Converts this instance.
/// A LSA_FOREST_TRUST_RECORD instance.
protected internal virtual LSA_FOREST_TRUST_RECORD Convert() =>
new LSA_FOREST_TRUST_RECORD { Flags = Flags, Time = Time.ToFileTimeStruct() };
}
///
/// Represents a LSA_FOREST_TRUST_RECORD with the ForestTrustType value set to ForestTrustTopLevelNameEx if the
/// property is and ForestTrustTopLevelName if the property
/// is .
///
[DebuggerDisplay("TopName:{TopLevelName}, Excl:{Excluded}, Time:{Time:u}, Flg:{Flags}")]
public class LsaForestTrustTopLevelName : LsaForestTrustRecord
{
private SafeLSA_UNICODE_STRING topLevelName = new SafeLSA_UNICODE_STRING(null);
/// Initializes a new instance of the class.
/// The name.
/// if set to true [exclude].
public LsaForestTrustTopLevelName(string name = null, bool exclude = false)
{
TopLevelName = name;
Excluded = exclude;
}
///
/// Gets or sets a value indicating whether this contains an excluded top-level name..
///
/// true if excluded; otherwise, false to include.
public bool Excluded { get; set; }
/// Top-level name. This member is used only if the ForestTrustType member is ForestTrustTopLevelName or ForestTrustTopLevelNameEx.
public string TopLevelName { get => topLevelName; set => topLevelName = value; }
/// Converts this instance.
/// A LSA_FOREST_TRUST_RECORD instance.
protected internal override LSA_FOREST_TRUST_RECORD Convert()
{
var ret = base.Convert();
ret.ForestTrustType = Excluded ? LSA_FOREST_TRUST_RECORD_TYPE.ForestTrustTopLevelNameEx : LSA_FOREST_TRUST_RECORD_TYPE.ForestTrustTopLevelName;
ret.ForestTrustData.TopLevelName = topLevelName;
return ret;
}
}
}
///
/// Provides a to a LSA handle that releases a created LSA_HANDLE instance at disposal using LsaClose.
///
public class SafeLSA_HANDLE : SafeHANDLE
{
/// Initializes a new instance of the class and assigns an existing handle.
/// An object that represents the pre-existing handle to use.
///
/// to reliably release the handle during the finalization phase; otherwise, (not recommended).
///
public SafeLSA_HANDLE(IntPtr preexistingHandle, bool ownsHandle = true) : base(preexistingHandle, ownsHandle) { }
/// Initializes a new instance of the class.
private SafeLSA_HANDLE() : base() { }
/// Performs an implicit conversion from to .
/// The safe handle instance.
/// The result of the conversion.
public static implicit operator LSA_HANDLE(SafeLSA_HANDLE h) => h.handle;
///
protected override bool InternalReleaseHandle() => LsaClose(this).Succeeded;
}
/// Provides a for that manages its own memory allocations.
public class SafeLSA_UNICODE_STRING : SafeHANDLE
{
/// Initializes a new instance of the class.
/// The value of the string to assign.
public SafeLSA_UNICODE_STRING(string value) : base(IntPtr.Zero, true) => Buffer = value;
/// Initializes a new instance of the class and assigns an existing handle.
/// An object that represents the pre-existing handle to use.
///
/// to reliably release the handle during the finalization phase; otherwise, (not recommended).
///
public SafeLSA_UNICODE_STRING(IntPtr preexistingHandle, bool ownsHandle = true) : base(preexistingHandle, ownsHandle) { }
/// Initializes a new instance of the class.
private SafeLSA_UNICODE_STRING() : base() { }
/// The string value.
public string Buffer
{
get => LsaUnicodeStringMarshaler.MarshalPtr(handle);
set
{
Close();
SetHandle(LsaUnicodeStringMarshaler.MarshalValue(value));
}
}
///
/// Specifies the length, in bytes, of the string pointed to by the Buffer member, not including the terminating null character,
/// if any.
///
public short length => IsInvalid ? (short)0 : Marshal.ReadInt16(handle);
///
/// Specifies the total size, in bytes, of the memory allocated for Buffer. Up to MaximumLength bytes can be written into the
/// buffer without trampling memory.
///
public short MaximumLength => IsInvalid ? (short)0 : Marshal.ReadInt16(handle, 2);
/// Performs an implicit conversion from to .
/// The safe handle instance.
/// The result of the conversion.
public static implicit operator LSA_UNICODE_STRING(SafeLSA_UNICODE_STRING h) => h.handle.ToStructure();
/// Performs an implicit conversion from to .
/// The string value.
/// The result of the conversion.
public static implicit operator SafeLSA_UNICODE_STRING(string val) => new SafeLSA_UNICODE_STRING(val);
/// Performs an implicit conversion from to .
/// The instance.
/// The result of the conversion.
public static implicit operator string(SafeLSA_UNICODE_STRING h) => h.Buffer;
///
protected override bool InternalReleaseHandle()
{
if (handle != IntPtr.Zero)
Marshal.FreeCoTaskMem(handle);
return true;
}
}
///
/// Provides a to a LSA memory handle that releases a created LsaMemoryHandle instance at disposal using .
///
public class SafeLsaMemoryHandle : SafeLsaMemoryHandleBase
{
/// Initializes a new instance of the class and assigns an existing handle.
/// An object that represents the pre-existing handle to use.
///
/// to reliably release the handle during the finalization phase; otherwise, (not recommended).
///
public SafeLsaMemoryHandle(IntPtr preexistingHandle, bool ownsHandle = true) : base(preexistingHandle, ownsHandle) { }
/// Initializes a new instance of the class.
private SafeLsaMemoryHandle() : base() { }
///
protected override bool InternalReleaseHandle() => LsaFreeMemory(handle).Succeeded;
}
/// Base class for other LSA memory handles.
public abstract class SafeLsaMemoryHandleBase : SafeHANDLE
{
/// Initializes a new instance of the class.
protected SafeLsaMemoryHandleBase() : base()
{
}
/// Initializes a new instance of the class and assigns an existing handle.
/// An object that represents the pre-existing handle to use.
///
/// to reliably release the handle during the finalization phase; otherwise, (not recommended).
///
protected SafeLsaMemoryHandleBase(IntPtr preexistingHandle, bool ownsHandle = true) : base(preexistingHandle, ownsHandle) => SetHandle(preexistingHandle);
/// Gets or sets the size that will be passed to limit buffer overruns.
/// The size.
public SizeT Size { get; set; } = 0;
///
/// Extracts an array of structures of containing items. This
/// call can cause memory exceptions if the pointer does not have sufficient allocated memory to retrieve all the structures.
///
/// The type of the structures to retrieve.
/// The number of structures to retrieve.
/// The number of bytes to skip before reading the structures.
/// An array of structures of .
public T[] ToArray(int count, int prefixBytes = 0)
{
if (IsInvalid) return null;
return handle.ToArray(count, prefixBytes, Size == 0 ? (SizeT)int.MaxValue : Size);
}
///
/// Marshals data from this block of memory to a newly allocated managed object of the type specified by a generic type parameter.
///
/// The type of the object to which the data is to be copied. This must be a structure.
/// A managed object that contains the data that this holds.
public T ToStructure()
{
if (IsInvalid) return default;
return handle.ToStructure(Size == 0 ? (SizeT)int.MaxValue : Size);
}
}
///
/// A for values that must be freed using the function.
///
public sealed class SafeLsaReturnBufferHandle : SafeLsaMemoryHandleBase
{
/// Initializes a new instance of the class.
/// The pointer to the memory allocated by an Lsa function.
/// if set to true release the memory when out of scope.
public SafeLsaReturnBufferHandle(IntPtr preexistingHandle, bool ownsHandle = true) : base(preexistingHandle, ownsHandle) { }
/// Initializes a new instance of the class.
private SafeLsaReturnBufferHandle() : base() { }
///
protected override bool InternalReleaseHandle() => Secur32.LsaFreeReturnBuffer(handle) == 0;
}
/// A custom marshaler for functions using LSA_UNICODE_STRING arrays so that managed string arrays can be used.
///
internal class LsaUnicodeStringArrayMarshaler : ICustomMarshaler
{
public static ICustomMarshaler GetInstance(string _) => new LsaUnicodeStringArrayMarshaler();
public void CleanUpManagedData(object ManagedObj)
{
}
public void CleanUpNativeData(IntPtr pNativeData)
{
if (pNativeData == IntPtr.Zero) return;
Marshal.FreeCoTaskMem(pNativeData);
}
public int GetNativeDataSize() => -1;
public IntPtr MarshalManagedToNative(object ManagedObj)
{
if (ManagedObj is string[] a)
{
var uma = Array.ConvertAll(a, p => new LSA_UNICODE_STRING { length = (ushort)StringHelper.GetByteCount(p, false, CharSet.Unicode) });
var strSz = uma.Sum(s => s.length + UnicodeEncoding.CharSize);
var result = Marshal.AllocCoTaskMem(LsaUnicodeStringMarshaler.ssz * a.Length + strSz);
var strPtr = result.Offset(LsaUnicodeStringMarshaler.ssz * a.Length);
for (var i = 0; i < uma.Length; i++)
{
uma[i].Buffer = strPtr;
StringHelper.Write(a[i], (IntPtr)uma[i].Buffer, out var byteCnt, true, CharSet.Unicode);
uma[i].MaximumLength = (ushort)byteCnt;
strPtr = strPtr.Offset(byteCnt);
Marshal.StructureToPtr(uma[i], result.Offset(i * LsaUnicodeStringMarshaler.ssz), false);
}
return result;
}
return IntPtr.Zero;
}
public object MarshalNativeToManaged(IntPtr pNativeData)
{
if (pNativeData == IntPtr.Zero) return null;
throw new InvalidOperationException(@"Unable to marshal LSA_UNICODE_STRING arrays from unmanaged to managed code.");
}
}
/// A custom marshaler for functions using LSA_UNICODE_STRING so that managed strings can be used.
///
internal class LsaUnicodeStringMarshaler : ICustomMarshaler
{
internal static readonly int ssz = Marshal.SizeOf(typeof(LSA_UNICODE_STRING));
public static ICustomMarshaler GetInstance(string _) => new LsaUnicodeStringMarshaler();
public void CleanUpManagedData(object ManagedObj)
{
}
public void CleanUpNativeData(IntPtr pNativeData)
{
if (pNativeData == IntPtr.Zero) return;
Marshal.FreeCoTaskMem(pNativeData);
}
public int GetNativeDataSize() => Marshal.SizeOf(typeof(LSA_UNICODE_STRING));
public IntPtr MarshalManagedToNative(object ManagedObj) => ManagedObj is string s ? MarshalValue(s) : IntPtr.Zero;
public object MarshalNativeToManaged(IntPtr pNativeData)
{
var s = MarshalPtr(pNativeData);
LsaFreeMemory(pNativeData);
return s;
}
internal static string MarshalPtr(IntPtr ptr) => ptr == IntPtr.Zero ? null : StringHelper.GetString(ptr.Offset(4), CharSet.Unicode, Marshal.ReadInt16(ptr));
internal static IntPtr MarshalValue(string value)
{
if (value is null) return IntPtr.Zero;
var lus = new LSA_UNICODE_STRING { length = (ushort)StringHelper.GetByteCount(value, false, CharSet.Unicode) };
lus.MaximumLength = (ushort)(lus.length + UnicodeEncoding.CharSize);
var mem = Marshal.AllocCoTaskMem(ssz + lus.MaximumLength);
lus.Buffer = mem.Offset(ssz);
mem.Write(lus);
StringHelper.Write(value, mem.Offset(ssz), out _, true, CharSet.Unicode, lus.MaximumLength);
return mem;
}
}
}
}