/* * Security Account Manager support functions * * This file is part of System Informer. */ #ifndef _NTSAM_H #define _NTSAM_H // // Types // #define SAM_MAXIMUM_LOOKUP_COUNT (1000) #define SAM_MAXIMUM_LOOKUP_LENGTH (32000) #define SAM_MAX_PASSWORD_LENGTH (256) #define SAM_PASSWORD_ENCRYPTION_SALT_LEN (16) typedef PVOID SAM_HANDLE, *PSAM_HANDLE; typedef ULONG SAM_ENUMERATE_HANDLE, *PSAM_ENUMERATE_HANDLE; typedef struct _SAM_RID_ENUMERATION { ULONG RelativeId; UNICODE_STRING Name; } SAM_RID_ENUMERATION, *PSAM_RID_ENUMERATION; typedef struct _SAM_SID_ENUMERATION { PSID Sid; UNICODE_STRING Name; } SAM_SID_ENUMERATION, *PSAM_SID_ENUMERATION; typedef struct _SAM_BYTE_ARRAY { ULONG Size; _Field_size_bytes_(Size) PUCHAR Data; } SAM_BYTE_ARRAY, *PSAM_BYTE_ARRAY; typedef struct _SAM_BYTE_ARRAY_32K { ULONG Size; _Field_size_bytes_(Size) PUCHAR Data; } SAM_BYTE_ARRAY_32K, *PSAM_BYTE_ARRAY_32K; typedef SAM_BYTE_ARRAY_32K SAM_SHELL_OBJECT_PROPERTIES, *PSAM_SHELL_OBJECT_PROPERTIES; // // Basic // NTSYSAPI NTSTATUS NTAPI SamFreeMemory( _In_ PVOID Buffer ); /** * The SamCloseHandle method closes (that is, releases server-side resources used by) any handle. * * \param SamHandle The object handle. * \return NTSTATUS Successful or errant status. * \sa https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-samr/55d134df-e257-48ad-8afa-cb2ca45cd3cc */ NTSYSAPI NTSTATUS NTAPI SamCloseHandle( _In_ SAM_HANDLE SamHandle ); NTSYSAPI NTSTATUS NTAPI SamSetSecurityObject( _In_ SAM_HANDLE ObjectHandle, _In_ SECURITY_INFORMATION SecurityInformation, _In_ PSECURITY_DESCRIPTOR SecurityDescriptor ); /** * The SamQuerySecurityObject method queries the access control on a server, domain, user, group, or alias object. * * \param ObjectHandle The "Domain", "User", "Group", or "Alias" object handle. * \param SecurityInformation A bit field that specifies which fields of SecurityDescriptor the client is requesting to be returned. * \param SecurityDescriptor A security descriptor expressing accesses that are specific to the ObjectHandle and the owner and group of the object. * \return NTSTATUS Successful or errant status. * \sa https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-samr/0ecf8fec-d17e-4a88-b7f1-e0f0f66790db */ NTSYSAPI NTSTATUS NTAPI SamQuerySecurityObject( _In_ SAM_HANDLE ObjectHandle, _In_ SECURITY_INFORMATION SecurityInformation, _Outptr_ PSECURITY_DESCRIPTOR *SecurityDescriptor ); /** * The SamRidToSid method obtains the SID of an account, given a RID. * * \param ObjectHandle The "Domain", "User", "Group", or "Alias" object handle. * \param Rid The RID of the object. * \param Sid The SID of the object referenced by Rid. * \return NTSTATUS Successful or errant status. * \sa https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-samr/00ff8192-a4f6-45ba-9f65-917e46b6a693 */ NTSYSAPI NTSTATUS NTAPI SamRidToSid( _In_ SAM_HANDLE ObjectHandle, _In_ ULONG Rid, _Outptr_ PSID *Sid ); NTSYSAPI NTSTATUS NTAPI SamQueryLapsManagedAccount( _In_ SAM_HANDLE ObjectHandle, _Outptr_ PSID *AccountSid ); // // Server // #define SAM_SERVER_CONNECT 0x0001 #define SAM_SERVER_SHUTDOWN 0x0002 #define SAM_SERVER_INITIALIZE 0x0004 #define SAM_SERVER_CREATE_DOMAIN 0x0008 #define SAM_SERVER_ENUMERATE_DOMAINS 0x0010 #define SAM_SERVER_LOOKUP_DOMAIN 0x0020 #define SAM_SERVER_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED | \ SAM_SERVER_CONNECT | \ SAM_SERVER_INITIALIZE | \ SAM_SERVER_CREATE_DOMAIN | \ SAM_SERVER_SHUTDOWN | \ SAM_SERVER_ENUMERATE_DOMAINS | \ SAM_SERVER_LOOKUP_DOMAIN) #define SAM_SERVER_READ (STANDARD_RIGHTS_READ | \ SAM_SERVER_ENUMERATE_DOMAINS) #define SAM_SERVER_WRITE (STANDARD_RIGHTS_WRITE | \ SAM_SERVER_INITIALIZE | \ SAM_SERVER_CREATE_DOMAIN | \ SAM_SERVER_SHUTDOWN) #define SAM_SERVER_EXECUTE (STANDARD_RIGHTS_EXECUTE | \ SAM_SERVER_CONNECT | \ SAM_SERVER_LOOKUP_DOMAIN) typedef struct _RPC_AUTH_IDENTITY_HANDLE *PRPC_AUTH_IDENTITY_HANDLE; // // Functions // /** * The SamConnect method returns a handle to a server. * * \param ServerName The NETBIOS name of the server; this parameter MAY be ignored on receipt. * \param ServerHandle A handle representing a server. * \param DesiredAccess The access requested for ServerHandle upon output. * \param ObjectAttributes The OBJECT_ATTRIBUTES structure that specifies the properties of the server handle to be opened. * \return NTSTATUS Successful or errant status. * \sa https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-samr/47492d59-e095-4398-b03e-8a062b989123 */ NTSYSAPI NTSTATUS NTAPI SamConnect( _In_opt_ PCUNICODE_STRING ServerName, _Out_ PSAM_HANDLE ServerHandle, _In_ ACCESS_MASK DesiredAccess, _In_ PCOBJECT_ATTRIBUTES ObjectAttributes ); NTSYSAPI NTSTATUS NTAPI SamConnectWithCreds( _In_ PCUNICODE_STRING ServerName, _Out_ PSAM_HANDLE ServerHandle, _In_ ACCESS_MASK DesiredAccess, _In_ PCOBJECT_ATTRIBUTES ObjectAttributes, _In_ PRPC_AUTH_IDENTITY_HANDLE Creds, _In_ PWCHAR Spn, _Out_ PBOOL DestinationIsWindows2K ); NTSYSAPI NTSTATUS NTAPI SamShutdownSamServer( _In_ SAM_HANDLE ServerHandle ); // // Domain // #define DOMAIN_READ_PASSWORD_PARAMETERS 0x0001 #define DOMAIN_WRITE_PASSWORD_PARAMS 0x0002 #define DOMAIN_READ_OTHER_PARAMETERS 0x0004 #define DOMAIN_WRITE_OTHER_PARAMETERS 0x0008 #define DOMAIN_CREATE_USER 0x0010 #define DOMAIN_CREATE_GROUP 0x0020 #define DOMAIN_CREATE_ALIAS 0x0040 #define DOMAIN_GET_ALIAS_MEMBERSHIP 0x0080 #define DOMAIN_LIST_ACCOUNTS 0x0100 #define DOMAIN_LOOKUP 0x0200 #define DOMAIN_ADMINISTER_SERVER 0x0400 #define DOMAIN_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED | \ DOMAIN_READ_OTHER_PARAMETERS | \ DOMAIN_WRITE_OTHER_PARAMETERS | \ DOMAIN_WRITE_PASSWORD_PARAMS | \ DOMAIN_CREATE_USER | \ DOMAIN_CREATE_GROUP | \ DOMAIN_CREATE_ALIAS | \ DOMAIN_GET_ALIAS_MEMBERSHIP | \ DOMAIN_LIST_ACCOUNTS | \ DOMAIN_READ_PASSWORD_PARAMETERS | \ DOMAIN_LOOKUP | \ DOMAIN_ADMINISTER_SERVER) #define DOMAIN_READ (STANDARD_RIGHTS_READ | \ DOMAIN_GET_ALIAS_MEMBERSHIP | \ DOMAIN_READ_OTHER_PARAMETERS) #define DOMAIN_WRITE (STANDARD_RIGHTS_WRITE | \ DOMAIN_WRITE_OTHER_PARAMETERS | \ DOMAIN_WRITE_PASSWORD_PARAMS | \ DOMAIN_CREATE_USER | \ DOMAIN_CREATE_GROUP | \ DOMAIN_CREATE_ALIAS | \ DOMAIN_ADMINISTER_SERVER) #define DOMAIN_EXECUTE (STANDARD_RIGHTS_EXECUTE | \ DOMAIN_READ_PASSWORD_PARAMETERS | \ DOMAIN_LIST_ACCOUNTS | \ DOMAIN_LOOKUP) #define DOMAIN_PROMOTION_INCREMENT { 0x0, 0x10 } #define DOMAIN_PROMOTION_MASK { 0x0, 0xfffffff0 } // // SamQueryInformationDomain/SamSetInformationDomain types // typedef enum _DOMAIN_INFORMATION_CLASS { DomainPasswordInformation = 1, // qs: DOMAIN_PASSWORD_INFORMATION DomainGeneralInformation, // q: DOMAIN_GENERAL_INFORMATION DomainLogoffInformation, // qs: DOMAIN_LOGOFF_INFORMATION DomainOemInformation, // qs: DOMAIN_OEM_INFORMATION DomainNameInformation, // q: DOMAIN_NAME_INFORMATION DomainReplicationInformation, // qs: DOMAIN_REPLICATION_INFORMATION DomainServerRoleInformation, // qs: DOMAIN_SERVER_ROLE_INFORMATION DomainModifiedInformation, // q: DOMAIN_MODIFIED_INFORMATION DomainStateInformation, // qs: DOMAIN_STATE_INFORMATION DomainUasInformation, // qs: DOMAIN_UAS_INFORMATION DomainGeneralInformation2, // q: DOMAIN_GENERAL_INFORMATION2 DomainLockoutInformation, // qs: DOMAIN_LOCKOUT_INFORMATION DomainModifiedInformation2, // q: DOMAIN_MODIFIED_INFORMATION2 DomainMaxInformation } DOMAIN_INFORMATION_CLASS; typedef enum _DOMAIN_SERVER_ENABLE_STATE { DomainServerEnabled = 1, DomainServerDisabled } DOMAIN_SERVER_ENABLE_STATE, *PDOMAIN_SERVER_ENABLE_STATE; typedef enum _DOMAIN_SERVER_ROLE { DomainServerRoleBackup = 2, DomainServerRolePrimary } DOMAIN_SERVER_ROLE, *PDOMAIN_SERVER_ROLE; typedef struct _DOMAIN_GENERAL_INFORMATION { LARGE_INTEGER ForceLogoff; UNICODE_STRING OemInformation; UNICODE_STRING DomainName; UNICODE_STRING ReplicaSourceNodeName; LARGE_INTEGER DomainModifiedCount; DOMAIN_SERVER_ENABLE_STATE DomainServerState; DOMAIN_SERVER_ROLE DomainServerRole; BOOLEAN UasCompatibilityRequired; ULONG UserCount; ULONG GroupCount; ULONG AliasCount; } DOMAIN_GENERAL_INFORMATION, *PDOMAIN_GENERAL_INFORMATION; typedef struct _DOMAIN_GENERAL_INFORMATION2 { DOMAIN_GENERAL_INFORMATION I1; LARGE_INTEGER LockoutDuration; // delta time LARGE_INTEGER LockoutObservationWindow; // delta time USHORT LockoutThreshold; } DOMAIN_GENERAL_INFORMATION2, *PDOMAIN_GENERAL_INFORMATION2; typedef struct _DOMAIN_UAS_INFORMATION { BOOLEAN UasCompatibilityRequired; } DOMAIN_UAS_INFORMATION; #ifndef _DOMAIN_PASSWORD_INFORMATION_DEFINED // defined in ntsecapi.h #define _DOMAIN_PASSWORD_INFORMATION_DEFINED typedef struct _DOMAIN_PASSWORD_INFORMATION { USHORT MinPasswordLength; USHORT PasswordHistoryLength; ULONG PasswordProperties; LARGE_INTEGER MaxPasswordAge; LARGE_INTEGER MinPasswordAge; } DOMAIN_PASSWORD_INFORMATION, *PDOMAIN_PASSWORD_INFORMATION; // // PasswordProperties flags // #define DOMAIN_PASSWORD_COMPLEX 0x00000001L #define DOMAIN_PASSWORD_NO_ANON_CHANGE 0x00000002L #define DOMAIN_PASSWORD_NO_CLEAR_CHANGE 0x00000004L #define DOMAIN_LOCKOUT_ADMINS 0x00000008L #define DOMAIN_PASSWORD_STORE_CLEARTEXT 0x00000010L #define DOMAIN_REFUSE_PASSWORD_CHANGE 0x00000020L #define DOMAIN_NO_LM_OWF_CHANGE 0x00000040L #endif // _DOMAIN_PASSWORD_INFORMATION_DEFINED typedef enum _DOMAIN_PASSWORD_CONSTRUCTION { DomainPasswordSimple = 1, DomainPasswordComplex } DOMAIN_PASSWORD_CONSTRUCTION; typedef struct _DOMAIN_LOGOFF_INFORMATION { LARGE_INTEGER ForceLogoff; } DOMAIN_LOGOFF_INFORMATION, *PDOMAIN_LOGOFF_INFORMATION; typedef struct _DOMAIN_OEM_INFORMATION { UNICODE_STRING OemInformation; } DOMAIN_OEM_INFORMATION, *PDOMAIN_OEM_INFORMATION; typedef struct _DOMAIN_NAME_INFORMATION { UNICODE_STRING DomainName; } DOMAIN_NAME_INFORMATION, *PDOMAIN_NAME_INFORMATION; typedef struct _DOMAIN_SERVER_ROLE_INFORMATION { DOMAIN_SERVER_ROLE DomainServerRole; } DOMAIN_SERVER_ROLE_INFORMATION, *PDOMAIN_SERVER_ROLE_INFORMATION; typedef struct _DOMAIN_REPLICATION_INFORMATION { UNICODE_STRING ReplicaSourceNodeName; } DOMAIN_REPLICATION_INFORMATION, *PDOMAIN_REPLICATION_INFORMATION; typedef struct _DOMAIN_MODIFIED_INFORMATION { LARGE_INTEGER DomainModifiedCount; LARGE_INTEGER CreationTime; } DOMAIN_MODIFIED_INFORMATION, *PDOMAIN_MODIFIED_INFORMATION; typedef struct _DOMAIN_MODIFIED_INFORMATION2 { LARGE_INTEGER DomainModifiedCount; LARGE_INTEGER CreationTime; LARGE_INTEGER ModifiedCountAtLastPromotion; } DOMAIN_MODIFIED_INFORMATION2, *PDOMAIN_MODIFIED_INFORMATION2; typedef struct _DOMAIN_STATE_INFORMATION { DOMAIN_SERVER_ENABLE_STATE DomainServerState; } DOMAIN_STATE_INFORMATION, *PDOMAIN_STATE_INFORMATION; typedef struct _DOMAIN_LOCKOUT_INFORMATION { LARGE_INTEGER LockoutDuration; // delta time LARGE_INTEGER LockoutObservationWindow; // delta time USHORT LockoutThreshold; // zero means no lockout } DOMAIN_LOCKOUT_INFORMATION, *PDOMAIN_LOCKOUT_INFORMATION; // // SamQueryDisplayInformation types // typedef enum _DOMAIN_DISPLAY_INFORMATION { DomainDisplayUser = 1, // DOMAIN_DISPLAY_USER DomainDisplayMachine, // DOMAIN_DISPLAY_MACHINE DomainDisplayGroup, // DOMAIN_DISPLAY_GROUP DomainDisplayOemUser, // DOMAIN_DISPLAY_OEM_USER DomainDisplayOemGroup, // DOMAIN_DISPLAY_OEM_GROUP DomainDisplayServer, // DOMAIN_DISPLAY_MACHINE DomainDisplayMax } DOMAIN_DISPLAY_INFORMATION, *PDOMAIN_DISPLAY_INFORMATION; typedef struct _DOMAIN_DISPLAY_USER { ULONG Index; ULONG Rid; ULONG AccountControl; UNICODE_STRING LogonName; UNICODE_STRING AdminComment; UNICODE_STRING FullName; } DOMAIN_DISPLAY_USER, *PDOMAIN_DISPLAY_USER; typedef struct _DOMAIN_DISPLAY_MACHINE { ULONG Index; ULONG Rid; ULONG AccountControl; UNICODE_STRING Machine; UNICODE_STRING Comment; } DOMAIN_DISPLAY_MACHINE, *PDOMAIN_DISPLAY_MACHINE; typedef struct _DOMAIN_DISPLAY_GROUP { ULONG Index; ULONG Rid; ULONG Attributes; UNICODE_STRING Group; UNICODE_STRING Comment; } DOMAIN_DISPLAY_GROUP, *PDOMAIN_DISPLAY_GROUP; typedef struct _DOMAIN_DISPLAY_OEM_USER { ULONG Index; OEM_STRING User; } DOMAIN_DISPLAY_OEM_USER, *PDOMAIN_DISPLAY_OEM_USER; typedef struct _DOMAIN_DISPLAY_OEM_GROUP { ULONG Index; OEM_STRING Group; } DOMAIN_DISPLAY_OEM_GROUP, *PDOMAIN_DISPLAY_OEM_GROUP; // // SamQueryLocalizableAccountsInDomain types // typedef enum _DOMAIN_LOCALIZABLE_ACCOUNTS_INFORMATION { DomainLocalizableAccountsBasic = 1, } DOMAIN_LOCALIZABLE_ACCOUNTS_INFORMATION, *PDOMAIN_LOCALIZABLE_ACCOUNTS_INFORMATION; typedef struct _DOMAIN_LOCALIZABLE_ACCOUNTS_ENTRY { ULONG Rid; SID_NAME_USE Use; UNICODE_STRING Name; UNICODE_STRING AdminComment; } DOMAIN_LOCALIZABLE_ACCOUNT_ENTRY, *PDOMAIN_LOCALIZABLE_ACCOUNT_ENTRY; typedef struct _DOMAIN_LOCALIZABLE_ACCOUNTS { ULONG Count; _Field_size_(Count) DOMAIN_LOCALIZABLE_ACCOUNT_ENTRY *Entries; } DOMAIN_LOCALIZABLE_ACCOUNTS_BASIC, *PDOMAIN_LOCALIZABLE_ACCOUNTS_BASIC; typedef union _DOMAIN_LOCALIZABLE_INFO_BUFFER { DOMAIN_LOCALIZABLE_ACCOUNTS_BASIC Basic; } DOMAIN_LOCALIZABLE_ACCOUNTS_INFO_BUFFER, *PDOMAIN_LOCALIZABLE_ACCOUNTS_INFO_BUFFER; // // Functions // /** * The SamLookupDomainInSamServer method obtains the SID of a domain, given the object's name. * * \param ServerHandle A handle representing a server. * \param Name A UTF-16 encoded string. * \param DomainId A SID value of a domain that corresponds to the Name. * \return NTSTATUS Successful or errant status. * \sa https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-samr/47492d59-e095-4398-b03e-8a062b989123 */ NTSYSAPI NTSTATUS NTAPI SamLookupDomainInSamServer( _In_ SAM_HANDLE ServerHandle, _In_ PCUNICODE_STRING Name, _Outptr_ PSID *DomainId ); /** * The SamEnumerateDomainsInSamServer method obtains a listing of all domains hosted by the server side of this protocol. * * \param ServerHandle A handle representing a server. * \param EnumerationContext An opaque value that the server can use to continue an enumeration on a subsequent call. * \param Buffer A listing of domain information. * \param PreferedMaximumLength The requested maximum number of bytes to return in Buffer. * \param CountReturned The count of domain elements returned in Buffer. * \return NTSTATUS Successful or errant status. * \sa https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-samr/2142fd2d-0854-42c1-a9fb-2fe964e381ce */ NTSYSAPI NTSTATUS NTAPI SamEnumerateDomainsInSamServer( _In_ SAM_HANDLE ServerHandle, _Inout_ PSAM_ENUMERATE_HANDLE EnumerationContext, _Outptr_ PVOID *Buffer, // PSAM_SID_ENUMERATION *Buffer _In_ ULONG PreferedMaximumLength, _Out_ PULONG CountReturned ); /** * The SamOpenDomain method obtains a handle to a domain, given a SID. * * \param ServerHandle A handle representing a server. * \param DesiredAccess The desired access to the domain. * \param DomainId A SID value of a domain hosted by the server. * \param DomainHandle A handle to the requested domain. * \return NTSTATUS Successful or errant status. * \sa https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-samr/ba710c90-5b12-42f8-9e5a-d4aacc1329fa */ NTSYSAPI NTSTATUS NTAPI SamOpenDomain( _In_ SAM_HANDLE ServerHandle, _In_ ACCESS_MASK DesiredAccess, _In_ PSID DomainId, _Out_ PSAM_HANDLE DomainHandle ); /** * The SamQueryInformationDomain method obtains attributes from a domain object. * * \param DomainHandle A handle representing a domain. * \param DomainInformationClass An enumeration indicating which attributes to return. * \param Buffer The requested attributes on output. * \return NTSTATUS Successful or errant status. * \sa https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-samr/5d6a2817-caa9-41ca-a269-fd13ecbb4fa8 */ NTSYSAPI NTSTATUS NTAPI SamQueryInformationDomain( _In_ SAM_HANDLE DomainHandle, _In_ DOMAIN_INFORMATION_CLASS DomainInformationClass, _Outptr_ PVOID *Buffer ); /** * The SamSetInformationDomain method updates attributes of a domain object. * * \param DomainHandle A handle representing a domain. * \param DomainInformationClass An enumeration indicating which attributes to update. * \param Buffer The provided attributes on output. * \return NTSTATUS Successful or errant status. */ NTSYSAPI NTSTATUS NTAPI SamSetInformationDomain( _In_ SAM_HANDLE DomainHandle, _In_ DOMAIN_INFORMATION_CLASS DomainInformationClass, _In_ PVOID Buffer ); /** * The SamLookupNamesInDomain method translates a set of account names into a set of RIDs. * * \param DomainHandle A handle representing a domain. * \param Count The number of elements in Names. * \param Names An array of strings that are to be mapped to RIDs. * \param RelativeIds An array of RIDs of accounts that correspond to the elements in Names. * \param Use An array of SID_NAME_USE enumeration values that describe the type of account for each entry in RelativeIds. * \return NTSTATUS Successful or errant status. * \sa https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-samr/d91271c6-7b2e-4194-9927-8fabfa429f90 */ NTSYSAPI NTSTATUS NTAPI SamLookupNamesInDomain( _In_ SAM_HANDLE DomainHandle, _In_ ULONG Count, _In_reads_(Count) PCUNICODE_STRING Names, _Out_ _Deref_post_count_(Count) PULONG *RelativeIds, _Out_ _Deref_post_count_(Count) PSID_NAME_USE *Use ); NTSYSAPI NTSTATUS NTAPI SamLookupNamesInDomain2( _In_ SAM_HANDLE DomainHandle, _In_ ULONG Count, _In_reads_(Count) PCUNICODE_STRING Names, _Out_ _Deref_post_count_(Count) PSID* Sids, _Out_ _Deref_post_count_(Count) PSID_NAME_USE* Use ); /** * The SamLookupIdsInDomain method translates a set of RIDs into account names. * * \param DomainHandle A handle representing a domain. * \param Count The number of elements in RelativeIds. * \param RelativeIds An array of RIDs that are to be mapped to account names. * \param Names An array of account names that correspond to the elements in RelativeIds. * \param Use An array of SID_NAME_USE enumeration values that describe the type of account for each entry in RelativeIds. * \return NTSTATUS Successful or errant status. * \sa https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-samr/c870951c-74b3-4714-9857-224595ffc61a */ NTSYSAPI NTSTATUS NTAPI SamLookupIdsInDomain( _In_ SAM_HANDLE DomainHandle, _In_ ULONG Count, _In_reads_(Count) PULONG RelativeIds, _Out_ _Deref_post_count_(Count) PUNICODE_STRING *Names, _Out_ _Deref_post_opt_count_(Count) PSID_NAME_USE *Use ); /** * The SamRemoveMemberFromForeignDomain method removes a member from all aliases. * * \param DomainHandle A handle representing a domain. * \param MemberId The SID to remove from the membership. * \return NTSTATUS Successful or errant status. * \sa https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-samr/03afc843-584d-473b-834a-3f5a1ac86cce */ NTSYSAPI NTSTATUS NTAPI SamRemoveMemberFromForeignDomain( _In_ SAM_HANDLE DomainHandle, _In_ PSID MemberId ); NTSYSAPI NTSTATUS NTAPI SamQueryLocalizableAccountsInDomain( _In_ SAM_HANDLE Domain, _In_ ULONG Flags, _In_ ULONG LanguageId, _In_ DOMAIN_LOCALIZABLE_ACCOUNTS_INFORMATION Class, _Outptr_ PVOID *Buffer ); // // Group // #define GROUP_READ_INFORMATION 0x0001 #define GROUP_WRITE_ACCOUNT 0x0002 #define GROUP_ADD_MEMBER 0x0004 #define GROUP_REMOVE_MEMBER 0x0008 #define GROUP_LIST_MEMBERS 0x0010 #define GROUP_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED | \ GROUP_LIST_MEMBERS | \ GROUP_WRITE_ACCOUNT | \ GROUP_ADD_MEMBER | \ GROUP_REMOVE_MEMBER | \ GROUP_READ_INFORMATION) #define GROUP_READ (STANDARD_RIGHTS_READ | \ GROUP_LIST_MEMBERS) #define GROUP_WRITE (STANDARD_RIGHTS_WRITE | \ GROUP_WRITE_ACCOUNT | \ GROUP_ADD_MEMBER | \ GROUP_REMOVE_MEMBER) #define GROUP_EXECUTE (STANDARD_RIGHTS_EXECUTE | \ GROUP_READ_INFORMATION) typedef struct _GROUP_MEMBERSHIP { ULONG RelativeId; ULONG Attributes; } GROUP_MEMBERSHIP, *PGROUP_MEMBERSHIP; // // SamQueryInformationGroup/SamSetInformationGroup types // typedef enum _GROUP_INFORMATION_CLASS { GroupGeneralInformation = 1, // q: GROUP_GENERAL_INFORMATION GroupNameInformation, // qs: GROUP_NAME_INFORMATION GroupAttributeInformation, // qs: GROUP_ATTRIBUTE_INFORMATION GroupAdminCommentInformation, // qs: GROUP_ADM_COMMENT_INFORMATION GroupReplicationInformation, // q: GROUP_REPLICATION_INFORMATION GroupMaxInformation } GROUP_INFORMATION_CLASS; typedef struct _GROUP_GENERAL_INFORMATION { UNICODE_STRING Name; ULONG Attributes; ULONG MemberCount; UNICODE_STRING AdminComment; } GROUP_GENERAL_INFORMATION, *PGROUP_GENERAL_INFORMATION; typedef struct _GROUP_NAME_INFORMATION { UNICODE_STRING Name; } GROUP_NAME_INFORMATION, *PGROUP_NAME_INFORMATION; typedef struct _GROUP_ATTRIBUTE_INFORMATION { ULONG Attributes; } GROUP_ATTRIBUTE_INFORMATION, *PGROUP_ATTRIBUTE_INFORMATION; typedef struct _GROUP_ADM_COMMENT_INFORMATION { UNICODE_STRING AdminComment; } GROUP_ADM_COMMENT_INFORMATION, *PGROUP_ADM_COMMENT_INFORMATION; typedef struct _GROUP_REPLICATION_INFORMATION { LARGE_INTEGER LastWriteTime; } GROUP_REPLICATION_INFORMATION, *PGROUP_REPLICATION_INFORMATION; // // Functions // /** * The SamEnumerateGroupsInDomain method enumerates all groups. * * \param DomainHandle A handle representing a domain. * \param EnumerationContext An opaque value that the server can use to continue an enumeration on a subsequent call. * \param Buffer A listing of group information. * \param PreferedMaximumLength The requested maximum number of bytes to return in Buffer. * \param CountReturned The count of domain elements returned in Buffer. * \return NTSTATUS Successful or errant status. * \sa https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-samr/e0b7a4b7-ecfc-405f-9d7d-32b3cd2cd6c8 */ NTSYSAPI NTSTATUS NTAPI SamEnumerateGroupsInDomain( _In_ SAM_HANDLE DomainHandle, _Inout_ PSAM_ENUMERATE_HANDLE EnumerationContext, _Outptr_ PVOID *Buffer, // PSAM_RID_ENUMERATION * _In_ ULONG PreferedMaximumLength, _Out_ PULONG CountReturned ); NTSYSAPI NTSTATUS NTAPI SamCreateGroupInDomain( _In_ SAM_HANDLE DomainHandle, _In_ PCUNICODE_STRING AccountName, _In_ ACCESS_MASK DesiredAccess, _Out_ PSAM_HANDLE GroupHandle, _Out_ PULONG RelativeId ); NTSYSAPI NTSTATUS NTAPI SamOpenGroup( _In_ SAM_HANDLE DomainHandle, _In_ ACCESS_MASK DesiredAccess, _In_ ULONG GroupId, _Out_ PSAM_HANDLE GroupHandle ); NTSYSAPI NTSTATUS NTAPI SamDeleteGroup( _In_ SAM_HANDLE GroupHandle ); NTSYSAPI NTSTATUS NTAPI SamQueryInformationGroup( _In_ SAM_HANDLE GroupHandle, _In_ GROUP_INFORMATION_CLASS GroupInformationClass, _Outptr_ PVOID *Buffer ); NTSYSAPI NTSTATUS NTAPI SamSetInformationGroup( _In_ SAM_HANDLE GroupHandle, _In_ GROUP_INFORMATION_CLASS GroupInformationClass, _In_ PVOID Buffer ); NTSYSAPI NTSTATUS NTAPI SamAddMemberToGroup( _In_ SAM_HANDLE GroupHandle, _In_ ULONG MemberId, _In_ ULONG Attributes ); NTSYSAPI NTSTATUS NTAPI SamRemoveMemberFromGroup( _In_ SAM_HANDLE GroupHandle, _In_ ULONG MemberId ); NTSYSAPI NTSTATUS NTAPI SamGetMembersInGroup( _In_ SAM_HANDLE GroupHandle, _Out_ _Deref_post_count_(*MemberCount) PULONG *MemberIds, _Out_ _Deref_post_count_(*MemberCount) PULONG *Attributes, _Out_ PULONG MemberCount ); NTSYSAPI NTSTATUS NTAPI SamSetMemberAttributesOfGroup( _In_ SAM_HANDLE GroupHandle, _In_ ULONG MemberId, _In_ ULONG Attributes ); // // Alias // #define ALIAS_ADD_MEMBER 0x0001 #define ALIAS_REMOVE_MEMBER 0x0002 #define ALIAS_LIST_MEMBERS 0x0004 #define ALIAS_READ_INFORMATION 0x0008 #define ALIAS_WRITE_ACCOUNT 0x0010 #define ALIAS_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED | \ ALIAS_READ_INFORMATION | \ ALIAS_WRITE_ACCOUNT | \ ALIAS_LIST_MEMBERS | \ ALIAS_ADD_MEMBER | \ ALIAS_REMOVE_MEMBER) #define ALIAS_READ (STANDARD_RIGHTS_READ | \ ALIAS_LIST_MEMBERS) #define ALIAS_WRITE (STANDARD_RIGHTS_WRITE | \ ALIAS_WRITE_ACCOUNT | \ ALIAS_ADD_MEMBER | \ ALIAS_REMOVE_MEMBER) #define ALIAS_EXECUTE (STANDARD_RIGHTS_EXECUTE | \ ALIAS_READ_INFORMATION) // // SamQueryInformationAlias/SamSetInformationAlias types // typedef enum _ALIAS_INFORMATION_CLASS { AliasGeneralInformation = 1, // q: ALIAS_GENERAL_INFORMATION AliasNameInformation, // qs: ALIAS_NAME_INFORMATION AliasAdminCommentInformation, // qs: ALIAS_ADM_COMMENT_INFORMATION AliasReplicationInformation, // q: ALIAS_REPLICATION_INFORMATION AliasExtendedInformation, // q: ALIAS_EXTENDED_INFORMATION AliasMaxInformation } ALIAS_INFORMATION_CLASS; typedef struct _ALIAS_GENERAL_INFORMATION { UNICODE_STRING Name; ULONG MemberCount; UNICODE_STRING AdminComment; } ALIAS_GENERAL_INFORMATION, *PALIAS_GENERAL_INFORMATION; typedef struct _ALIAS_NAME_INFORMATION { UNICODE_STRING Name; } ALIAS_NAME_INFORMATION, *PALIAS_NAME_INFORMATION; typedef struct _ALIAS_ADM_COMMENT_INFORMATION { UNICODE_STRING AdminComment; } ALIAS_ADM_COMMENT_INFORMATION, *PALIAS_ADM_COMMENT_INFORMATION; typedef struct _ALIAS_REPLICATION_INFORMATION { LARGE_INTEGER LastWriteTime; } ALIAS_REPLICATION_INFORMATION, *PALIAS_REPLICATION_INFORMATION; #define ALIAS_ALL_NAME (0x00000001L) #define ALIAS_ALL_MEMBER_COUNT (0x00000002L) #define ALIAS_ALL_ADMIN_COMMENT (0x00000004L) #define ALIAS_ALL_SHELL_ADMIN_OBJECT_PROPERTIES (0x00000008L) typedef struct _ALIAS_EXTENDED_INFORMATION { ULONG WhichFields; SAM_SHELL_OBJECT_PROPERTIES ShellAdminObjectProperties; } ALIAS_EXTENDED_INFORMATION, *PALIAS_EXTENDED_INFORMATION; // // Functions // NTSYSAPI NTSTATUS NTAPI SamEnumerateAliasesInDomain( _In_ SAM_HANDLE DomainHandle, _Inout_ PSAM_ENUMERATE_HANDLE EnumerationContext, _Outptr_ PVOID *Buffer, // PSAM_RID_ENUMERATION *Buffer _In_ ULONG PreferedMaximumLength, _Out_ PULONG CountReturned ); NTSYSAPI NTSTATUS NTAPI SamCreateAliasInDomain( _In_ SAM_HANDLE DomainHandle, _In_ PCUNICODE_STRING AccountName, _In_ ACCESS_MASK DesiredAccess, _Out_ PSAM_HANDLE AliasHandle, _Out_ PULONG RelativeId ); NTSYSAPI NTSTATUS NTAPI SamOpenAlias( _In_ SAM_HANDLE DomainHandle, _In_ ACCESS_MASK DesiredAccess, _In_ ULONG AliasId, _Out_ PSAM_HANDLE AliasHandle ); NTSYSAPI NTSTATUS NTAPI SamDeleteAlias( _In_ SAM_HANDLE AliasHandle ); NTSYSAPI NTSTATUS NTAPI SamQueryInformationAlias( _In_ SAM_HANDLE AliasHandle, _In_ ALIAS_INFORMATION_CLASS AliasInformationClass, _Outptr_ PVOID *Buffer ); NTSYSAPI NTSTATUS NTAPI SamSetInformationAlias( _In_ SAM_HANDLE AliasHandle, _In_ ALIAS_INFORMATION_CLASS AliasInformationClass, _In_ PVOID Buffer ); NTSYSAPI NTSTATUS NTAPI SamAddMemberToAlias( _In_ SAM_HANDLE AliasHandle, _In_ PSID MemberId ); NTSYSAPI NTSTATUS NTAPI SamAddMultipleMembersToAlias( _In_ SAM_HANDLE AliasHandle, _In_reads_(MemberCount) PSID *MemberIds, _In_ ULONG MemberCount ); NTSYSAPI NTSTATUS NTAPI SamRemoveMemberFromAlias( _In_ SAM_HANDLE AliasHandle, _In_ PSID MemberId ); NTSYSAPI NTSTATUS NTAPI SamRemoveMultipleMembersFromAlias( _In_ SAM_HANDLE AliasHandle, _In_reads_(MemberCount) PSID *MemberIds, _In_ ULONG MemberCount ); NTSYSAPI NTSTATUS NTAPI SamGetMembersInAlias( _In_ SAM_HANDLE AliasHandle, _Out_ _Deref_post_count_(*MemberCount) PSID **MemberIds, _Out_ PULONG MemberCount ); NTSYSAPI NTSTATUS NTAPI SamGetAliasMembership( _In_ SAM_HANDLE DomainHandle, _In_ ULONG PassedCount, _In_reads_(PassedCount) PSID *Sids, _Out_ PULONG MembershipCount, _Out_ _Deref_post_count_(*MembershipCount) PULONG *Aliases ); // // Group types // #define GROUP_TYPE_BUILTIN_LOCAL_GROUP 0x00000001 #define GROUP_TYPE_ACCOUNT_GROUP 0x00000002 #define GROUP_TYPE_RESOURCE_GROUP 0x00000004 #define GROUP_TYPE_UNIVERSAL_GROUP 0x00000008 #define GROUP_TYPE_APP_BASIC_GROUP 0x00000010 #define GROUP_TYPE_APP_QUERY_GROUP 0x00000020 #define GROUP_TYPE_SECURITY_ENABLED 0x80000000 #define GROUP_TYPE_RESOURCE_BEHAVOIR (GROUP_TYPE_RESOURCE_GROUP | \ GROUP_TYPE_APP_BASIC_GROUP | \ GROUP_TYPE_APP_QUERY_GROUP) // // User // #define USER_READ_GENERAL 0x0001 #define USER_READ_PREFERENCES 0x0002 #define USER_WRITE_PREFERENCES 0x0004 #define USER_READ_LOGON 0x0008 #define USER_READ_ACCOUNT 0x0010 #define USER_WRITE_ACCOUNT 0x0020 #define USER_CHANGE_PASSWORD 0x0040 #define USER_FORCE_PASSWORD_CHANGE 0x0080 #define USER_LIST_GROUPS 0x0100 #define USER_READ_GROUP_INFORMATION 0x0200 #define USER_WRITE_GROUP_INFORMATION 0x0400 #define USER_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED | \ USER_READ_PREFERENCES | \ USER_READ_LOGON | \ USER_LIST_GROUPS | \ USER_READ_GROUP_INFORMATION | \ USER_WRITE_PREFERENCES | \ USER_CHANGE_PASSWORD | \ USER_FORCE_PASSWORD_CHANGE | \ USER_READ_GENERAL | \ USER_READ_ACCOUNT | \ USER_WRITE_ACCOUNT | \ USER_WRITE_GROUP_INFORMATION) #define USER_READ (STANDARD_RIGHTS_READ | \ USER_READ_PREFERENCES | \ USER_READ_LOGON | \ USER_READ_ACCOUNT | \ USER_LIST_GROUPS | \ USER_READ_GROUP_INFORMATION) #define USER_WRITE (STANDARD_RIGHTS_WRITE | \ USER_WRITE_PREFERENCES | \ USER_CHANGE_PASSWORD) #define USER_EXECUTE (STANDARD_RIGHTS_EXECUTE | \ USER_READ_GENERAL | \ USER_CHANGE_PASSWORD) // // User account control flags // #define USER_ACCOUNT_DISABLED (0x00000001) #define USER_HOME_DIRECTORY_REQUIRED (0x00000002) #define USER_PASSWORD_NOT_REQUIRED (0x00000004) #define USER_TEMP_DUPLICATE_ACCOUNT (0x00000008) #define USER_NORMAL_ACCOUNT (0x00000010) #define USER_MNS_LOGON_ACCOUNT (0x00000020) #define USER_INTERDOMAIN_TRUST_ACCOUNT (0x00000040) #define USER_WORKSTATION_TRUST_ACCOUNT (0x00000080) #define USER_SERVER_TRUST_ACCOUNT (0x00000100) #define USER_DONT_EXPIRE_PASSWORD (0x00000200) #define USER_ACCOUNT_AUTO_LOCKED (0x00000400) #define USER_ENCRYPTED_TEXT_PASSWORD_ALLOWED (0x00000800) #define USER_SMARTCARD_REQUIRED (0x00001000) #define USER_TRUSTED_FOR_DELEGATION (0x00002000) #define USER_NOT_DELEGATED (0x00004000) #define USER_USE_DES_KEY_ONLY (0x00008000) #define USER_DONT_REQUIRE_PREAUTH (0x00010000) #define USER_PASSWORD_EXPIRED (0x00020000) #define USER_TRUSTED_TO_AUTHENTICATE_FOR_DELEGATION (0x00040000) #define USER_NO_AUTH_DATA_REQUIRED (0x00080000) #define USER_PARTIAL_SECRETS_ACCOUNT (0x00100000) #define USER_USE_AES_KEYS (0x00200000) #define NEXT_FREE_ACCOUNT_CONTROL_BIT (USER_USE_AES_KEYS << 1) #define USER_MACHINE_ACCOUNT_MASK ( \ USER_INTERDOMAIN_TRUST_ACCOUNT | \ USER_WORKSTATION_TRUST_ACCOUNT | \ USER_SERVER_TRUST_ACCOUNT \ ) #define USER_ACCOUNT_TYPE_MASK ( \ USER_TEMP_DUPLICATE_ACCOUNT | \ USER_NORMAL_ACCOUNT | \ USER_MACHINE_ACCOUNT_MASK \ ) #define USER_COMPUTED_ACCOUNT_CONTROL_BITS ( \ USER_ACCOUNT_AUTO_LOCKED | \ USER_PASSWORD_EXPIRED \ ) // Logon times may be expressed in day, hour, or minute granularity. #define SAM_DAYS_PER_WEEK (7) #define SAM_HOURS_PER_WEEK (24 * SAM_DAYS_PER_WEEK) #define SAM_MINUTES_PER_WEEK (60 * SAM_HOURS_PER_WEEK) typedef struct _LOGON_HOURS { USHORT UnitsPerWeek; // UnitsPerWeek is the number of equal length time units the week is // divided into. This value is used to compute the length of the bit // string in logon_hours. Must be less than or equal to // SAM_UNITS_PER_WEEK (10080) for this release. // // LogonHours is a bit map of valid logon times. Each bit represents // a unique division in a week. The largest bit map supported is 1260 // bytes (10080 bits), which represents minutes per week. In this case // the first bit (bit 0, byte 0) is Sunday, 00:00:00 - 00-00:59; bit 1, // byte 0 is Sunday, 00:01:00 - 00:01:59, etc. A NULL pointer means // DONT_CHANGE for SamSetInformationUser() calls. PUCHAR LogonHours; } LOGON_HOURS, *PLOGON_HOURS; /** * The SR_SECURITY_DESCRIPTOR structure contains information about the security privileges of the user. * * \sa https://learn.microsoft.com/en-us/windows/win32/api/subauth/ns-subauth-sr_security_descriptor */ typedef struct _SR_SECURITY_DESCRIPTOR { ULONG Length; // Indicates the size in bytes of the structure. PUCHAR SecurityDescriptor; // Indicates the user's security privileges. } SR_SECURITY_DESCRIPTOR, *PSR_SECURITY_DESCRIPTOR; // // SamQueryInformationUser/SamSetInformationUser types // typedef enum _USER_INFORMATION_CLASS { UserGeneralInformation = 1, // q: USER_GENERAL_INFORMATION UserPreferencesInformation, // qs: USER_PREFERENCES_INFORMATION UserLogonInformation, // q: USER_LOGON_INFORMATION UserLogonHoursInformation, // qs: USER_LOGON_HOURS_INFORMATION UserAccountInformation, // q: USER_ACCOUNT_INFORMATION UserNameInformation, // qs: USER_NAME_INFORMATION UserAccountNameInformation, // qs: USER_ACCOUNT_NAME_INFORMATION UserFullNameInformation, // qs: USER_FULL_NAME_INFORMATION UserPrimaryGroupInformation, // qs: USER_PRIMARY_GROUP_INFORMATION UserHomeInformation, // qs: USER_HOME_INFORMATION // 10 UserScriptInformation, // qs: USER_SCRIPT_INFORMATION UserProfileInformation, // qs: USER_PROFILE_INFORMATION UserAdminCommentInformation, // qs: USER_ADMIN_COMMENT_INFORMATION UserWorkStationsInformation, // qs: USER_WORKSTATIONS_INFORMATION UserSetPasswordInformation, // s: USER_SET_PASSWORD_INFORMATION UserControlInformation, // qs: USER_CONTROL_INFORMATION UserExpiresInformation, // qs: USER_EXPIRES_INFORMATION UserInternal1Information, // qs: USER_INTERNAL1_INFORMATION UserInternal2Information, // qs: USER_INTERNAL2_INFORMATION UserParametersInformation, // qs: USER_PARAMETERS_INFORMATION // 20 UserAllInformation, // qs: USER_ALL_INFORMATION UserInternal3Information, // qs: USER_INTERNAL3_INFORMATION UserInternal4Information, // qs: USER_INTERNAL4_INFORMATION UserInternal5Information, // qs: USER_INTERNAL5_INFORMATION UserInternal4InformationNew, // qs: USER_INTERNAL4_INFORMATION_NEW UserInternal5InformationNew, // qs: USER_INTERNAL5_INFORMATION_NEW UserInternal6Information, // qs: USER_INTERNAL6_INFORMATION UserExtendedInformation, // qs: USER_EXTENDED_INFORMATION UserLogonUIInformation, // q: USER_LOGON_UI_INFORMATION // since VISTA UserAuthInformation, // qs: USER_AUTH_INFORMATION // since WIN10 // 30 UserInternal7Information, // qs: USER_INTERNAL7_INFORMATION // since 20H1 UserInternal8Information, // qs: USER_INTERNAL8_INFORMATION UserMaxInformation } USER_INFORMATION_CLASS, *PUSER_INFORMATION_CLASS; typedef struct _USER_GENERAL_INFORMATION { UNICODE_STRING UserName; UNICODE_STRING FullName; ULONG PrimaryGroupId; UNICODE_STRING AdminComment; UNICODE_STRING UserComment; } USER_GENERAL_INFORMATION, *PUSER_GENERAL_INFORMATION; typedef struct _USER_PREFERENCES_INFORMATION { UNICODE_STRING UserComment; UNICODE_STRING Reserved1; USHORT CountryCode; USHORT CodePage; } USER_PREFERENCES_INFORMATION, *PUSER_PREFERENCES_INFORMATION; typedef struct _USER_LOGON_INFORMATION { UNICODE_STRING UserName; UNICODE_STRING FullName; ULONG UserId; ULONG PrimaryGroupId; UNICODE_STRING HomeDirectory; UNICODE_STRING HomeDirectoryDrive; UNICODE_STRING ScriptPath; UNICODE_STRING ProfilePath; UNICODE_STRING WorkStations; LARGE_INTEGER LastLogon; LARGE_INTEGER LastLogoff; LARGE_INTEGER PasswordLastSet; LARGE_INTEGER PasswordCanChange; LARGE_INTEGER PasswordMustChange; LOGON_HOURS LogonHours; USHORT BadPasswordCount; USHORT LogonCount; ULONG UserAccountControl; } USER_LOGON_INFORMATION, *PUSER_LOGON_INFORMATION; typedef struct _USER_LOGON_HOURS_INFORMATION { LOGON_HOURS LogonHours; } USER_LOGON_HOURS_INFORMATION, *PUSER_LOGON_HOURS_INFORMATION; typedef struct _USER_ACCOUNT_INFORMATION { UNICODE_STRING UserName; UNICODE_STRING FullName; ULONG UserId; ULONG PrimaryGroupId; UNICODE_STRING HomeDirectory; UNICODE_STRING HomeDirectoryDrive; UNICODE_STRING ScriptPath; UNICODE_STRING ProfilePath; UNICODE_STRING AdminComment; UNICODE_STRING WorkStations; LARGE_INTEGER LastLogon; LARGE_INTEGER LastLogoff; LOGON_HOURS LogonHours; USHORT BadPasswordCount; USHORT LogonCount; LARGE_INTEGER PasswordLastSet; LARGE_INTEGER AccountExpires; ULONG UserAccountControl; } USER_ACCOUNT_INFORMATION, *PUSER_ACCOUNT_INFORMATION; typedef struct _USER_NAME_INFORMATION { UNICODE_STRING UserName; UNICODE_STRING FullName; } USER_NAME_INFORMATION, *PUSER_NAME_INFORMATION; typedef struct _USER_ACCOUNT_NAME_INFORMATION { UNICODE_STRING UserName; } USER_ACCOUNT_NAME_INFORMATION, *PUSER_ACCOUNT_NAME_INFORMATION; typedef struct _USER_FULL_NAME_INFORMATION { UNICODE_STRING FullName; } USER_FULL_NAME_INFORMATION, *PUSER_FULL_NAME_INFORMATION; typedef struct _USER_PRIMARY_GROUP_INFORMATION { ULONG PrimaryGroupId; } USER_PRIMARY_GROUP_INFORMATION, *PUSER_PRIMARY_GROUP_INFORMATION; typedef struct _USER_HOME_INFORMATION { UNICODE_STRING HomeDirectory; UNICODE_STRING HomeDirectoryDrive; } USER_HOME_INFORMATION, *PUSER_HOME_INFORMATION; typedef struct _USER_SCRIPT_INFORMATION { UNICODE_STRING ScriptPath; } USER_SCRIPT_INFORMATION, *PUSER_SCRIPT_INFORMATION; typedef struct _USER_PROFILE_INFORMATION { UNICODE_STRING ProfilePath; } USER_PROFILE_INFORMATION, *PUSER_PROFILE_INFORMATION; typedef struct _USER_ADMIN_COMMENT_INFORMATION { UNICODE_STRING AdminComment; } USER_ADMIN_COMMENT_INFORMATION, *PUSER_ADMIN_COMMENT_INFORMATION; typedef struct _USER_WORKSTATIONS_INFORMATION { UNICODE_STRING WorkStations; } USER_WORKSTATIONS_INFORMATION, *PUSER_WORKSTATIONS_INFORMATION; typedef struct _USER_SET_PASSWORD_INFORMATION { UNICODE_STRING Password; BOOLEAN PasswordExpired; } USER_SET_PASSWORD_INFORMATION, *PUSER_SET_PASSWORD_INFORMATION; typedef struct _USER_CONTROL_INFORMATION { ULONG UserAccountControl; } USER_CONTROL_INFORMATION, *PUSER_CONTROL_INFORMATION; typedef struct _USER_EXPIRES_INFORMATION { LARGE_INTEGER AccountExpires; } USER_EXPIRES_INFORMATION, *PUSER_EXPIRES_INFORMATION; #define CYPHER_BLOCK_LENGTH 8 typedef struct _CYPHER_BLOCK { CHAR data[CYPHER_BLOCK_LENGTH]; } CYPHER_BLOCK, *PCYPHER_BLOCK; typedef struct _ENCRYPTED_NT_OWF_PASSWORD { CYPHER_BLOCK data[2]; } ENCRYPTED_NT_OWF_PASSWORD, *PENCRYPTED_NT_OWF_PASSWORD; typedef struct _ENCRYPTED_LM_OWF_PASSWORD { CYPHER_BLOCK data[2]; } ENCRYPTED_LM_OWF_PASSWORD, *PENCRYPTED_LM_OWF_PASSWORD; typedef struct _USER_INTERNAL1_INFORMATION { ENCRYPTED_NT_OWF_PASSWORD EncryptedNtOwfPassword; ENCRYPTED_LM_OWF_PASSWORD EncryptedLmOwfPassword; BOOLEAN NtPasswordPresent; BOOLEAN LmPasswordPresent; BOOLEAN PasswordExpired; } USER_INTERNAL1_INFORMATION, *PUSER_INTERNAL1_INFORMATION; typedef struct _USER_INTERNAL2_INFORMATION { ULONG StatisticsToApply; LARGE_INTEGER LastLogon; LARGE_INTEGER LastLogoff; USHORT BadPasswordCount; USHORT LogonCount; } USER_INTERNAL2_INFORMATION, *PUSER_INTERNAL2_INFORMATION; typedef struct _USER_PARAMETERS_INFORMATION { UNICODE_STRING Parameters; } USER_PARAMETERS_INFORMATION, *PUSER_PARAMETERS_INFORMATION; // // Flags for WhichFields in USER_ALL_INFORMATION // #define USER_ALL_USERNAME 0x00000001 #define USER_ALL_FULLNAME 0x00000002 #define USER_ALL_USERID 0x00000004 #define USER_ALL_PRIMARYGROUPID 0x00000008 #define USER_ALL_ADMINCOMMENT 0x00000010 #define USER_ALL_USERCOMMENT 0x00000020 #define USER_ALL_HOMEDIRECTORY 0x00000040 #define USER_ALL_HOMEDIRECTORYDRIVE 0x00000080 #define USER_ALL_SCRIPTPATH 0x00000100 #define USER_ALL_PROFILEPATH 0x00000200 #define USER_ALL_WORKSTATIONS 0x00000400 #define USER_ALL_LASTLOGON 0x00000800 #define USER_ALL_LASTLOGOFF 0x00001000 #define USER_ALL_LOGONHOURS 0x00002000 #define USER_ALL_BADPASSWORDCOUNT 0x00004000 #define USER_ALL_LOGONCOUNT 0x00008000 #define USER_ALL_PASSWORDCANCHANGE 0x00010000 #define USER_ALL_PASSWORDMUSTCHANGE 0x00020000 #define USER_ALL_PASSWORDLASTSET 0x00040000 #define USER_ALL_ACCOUNTEXPIRES 0x00080000 #define USER_ALL_USERACCOUNTCONTROL 0x00100000 #define USER_ALL_PARAMETERS 0x00200000 #define USER_ALL_COUNTRYCODE 0x00400000 #define USER_ALL_CODEPAGE 0x00800000 #define USER_ALL_NTPASSWORDPRESENT 0x01000000 // field AND boolean #define USER_ALL_LMPASSWORDPRESENT 0x02000000 // field AND boolean #define USER_ALL_PRIVATEDATA 0x04000000 // field AND boolean #define USER_ALL_PASSWORDEXPIRED 0x08000000 #define USER_ALL_SECURITYDESCRIPTOR 0x10000000 #define USER_ALL_OWFPASSWORD 0x20000000 // boolean #define USER_ALL_UNDEFINED_MASK 0xc0000000 // Fields that require USER_READ_GENERAL access to read. #define USER_ALL_READ_GENERAL_MASK \ (USER_ALL_USERNAME | \ USER_ALL_FULLNAME | \ USER_ALL_USERID | \ USER_ALL_PRIMARYGROUPID | \ USER_ALL_ADMINCOMMENT | \ USER_ALL_USERCOMMENT) // Fields that require USER_READ_LOGON access to read. #define USER_ALL_READ_LOGON_MASK \ (USER_ALL_HOMEDIRECTORY | \ USER_ALL_HOMEDIRECTORYDRIVE | \ USER_ALL_SCRIPTPATH | \ USER_ALL_PROFILEPATH | \ USER_ALL_WORKSTATIONS | \ USER_ALL_LASTLOGON | \ USER_ALL_LASTLOGOFF | \ USER_ALL_LOGONHOURS | \ USER_ALL_BADPASSWORDCOUNT | \ USER_ALL_LOGONCOUNT | \ USER_ALL_PASSWORDCANCHANGE | \ USER_ALL_PASSWORDMUSTCHANGE) // Fields that require USER_READ_ACCOUNT access to read. #define USER_ALL_READ_ACCOUNT_MASK \ (USER_ALL_PASSWORDLASTSET | \ USER_ALL_ACCOUNTEXPIRES | \ USER_ALL_USERACCOUNTCONTROL | \ USER_ALL_PARAMETERS) // Fields that require USER_READ_PREFERENCES access to read. #define USER_ALL_READ_PREFERENCES_MASK \ (USER_ALL_COUNTRYCODE | USER_ALL_CODEPAGE) // Fields that can only be read by trusted clients. #define USER_ALL_READ_TRUSTED_MASK \ (USER_ALL_NTPASSWORDPRESENT | \ USER_ALL_LMPASSWORDPRESENT | \ USER_ALL_PASSWORDEXPIRED | \ USER_ALL_SECURITYDESCRIPTOR | \ USER_ALL_PRIVATEDATA) // Fields that can't be read. #define USER_ALL_READ_CANT_MASK USER_ALL_UNDEFINED_MASK // Fields that require USER_WRITE_ACCOUNT access to write. #define USER_ALL_WRITE_ACCOUNT_MASK \ (USER_ALL_USERNAME | \ USER_ALL_FULLNAME | \ USER_ALL_PRIMARYGROUPID | \ USER_ALL_HOMEDIRECTORY | \ USER_ALL_HOMEDIRECTORYDRIVE | \ USER_ALL_SCRIPTPATH | \ USER_ALL_PROFILEPATH | \ USER_ALL_ADMINCOMMENT | \ USER_ALL_WORKSTATIONS | \ USER_ALL_LOGONHOURS | \ USER_ALL_ACCOUNTEXPIRES | \ USER_ALL_USERACCOUNTCONTROL | \ USER_ALL_PARAMETERS) // Fields that require USER_WRITE_PREFERENCES access to write. #define USER_ALL_WRITE_PREFERENCES_MASK \ (USER_ALL_USERCOMMENT | USER_ALL_COUNTRYCODE | USER_ALL_CODEPAGE) // Fields that require USER_FORCE_PASSWORD_CHANGE access to write. // // Note that non-trusted clients only set the NT password as a // UNICODE string. The wrapper will convert it to an LM password, // OWF and encrypt both versions. Trusted clients can pass in OWF // versions of either or both. #define USER_ALL_WRITE_FORCE_PASSWORD_CHANGE_MASK \ (USER_ALL_NTPASSWORDPRESENT | \ USER_ALL_LMPASSWORDPRESENT | \ USER_ALL_PASSWORDEXPIRED) // Fields that can only be written by trusted clients. #define USER_ALL_WRITE_TRUSTED_MASK \ (USER_ALL_LASTLOGON | \ USER_ALL_LASTLOGOFF | \ USER_ALL_BADPASSWORDCOUNT | \ USER_ALL_LOGONCOUNT | \ USER_ALL_PASSWORDLASTSET | \ USER_ALL_SECURITYDESCRIPTOR | \ USER_ALL_PRIVATEDATA) // Fields that can't be written. #define USER_ALL_WRITE_CANT_MASK \ (USER_ALL_USERID | \ USER_ALL_PASSWORDCANCHANGE | \ USER_ALL_PASSWORDMUSTCHANGE | \ USER_ALL_UNDEFINED_MASK) typedef struct _USER_ALL_INFORMATION { LARGE_INTEGER LastLogon; LARGE_INTEGER LastLogoff; LARGE_INTEGER PasswordLastSet; LARGE_INTEGER AccountExpires; LARGE_INTEGER PasswordCanChange; LARGE_INTEGER PasswordMustChange; UNICODE_STRING UserName; UNICODE_STRING FullName; UNICODE_STRING HomeDirectory; UNICODE_STRING HomeDirectoryDrive; UNICODE_STRING ScriptPath; UNICODE_STRING ProfilePath; UNICODE_STRING AdminComment; UNICODE_STRING WorkStations; UNICODE_STRING UserComment; UNICODE_STRING Parameters; UNICODE_STRING LmPassword; UNICODE_STRING NtPassword; UNICODE_STRING PrivateData; SR_SECURITY_DESCRIPTOR SecurityDescriptor; ULONG UserId; ULONG PrimaryGroupId; ULONG UserAccountControl; ULONG WhichFields; LOGON_HOURS LogonHours; USHORT BadPasswordCount; USHORT LogonCount; USHORT CountryCode; USHORT CodePage; BOOLEAN LmPasswordPresent; BOOLEAN NtPasswordPresent; BOOLEAN PasswordExpired; BOOLEAN PrivateDataSensitive; } USER_ALL_INFORMATION, *PUSER_ALL_INFORMATION; typedef struct _USER_INTERNAL3_INFORMATION { USER_ALL_INFORMATION I1; LARGE_INTEGER LastBadPasswordTime; } USER_INTERNAL3_INFORMATION, *PUSER_INTERNAL3_INFORMATION; typedef struct _ENCRYPTED_USER_PASSWORD { UCHAR Buffer[(SAM_MAX_PASSWORD_LENGTH * 2) + 4]; } ENCRYPTED_USER_PASSWORD, *PENCRYPTED_USER_PASSWORD; typedef struct _USER_INTERNAL4_INFORMATION { USER_ALL_INFORMATION I1; ENCRYPTED_USER_PASSWORD UserPassword; } USER_INTERNAL4_INFORMATION, *PUSER_INTERNAL4_INFORMATION; typedef struct _USER_INTERNAL5_INFORMATION { ENCRYPTED_USER_PASSWORD UserPassword; BOOLEAN PasswordExpired; } USER_INTERNAL5_INFORMATION, *PUSER_INTERNAL5_INFORMATION; typedef struct _ENCRYPTED_USER_PASSWORD_NEW { UCHAR Buffer[(SAM_MAX_PASSWORD_LENGTH * 2) + 4 + SAM_PASSWORD_ENCRYPTION_SALT_LEN]; } ENCRYPTED_USER_PASSWORD_NEW, *PENCRYPTED_USER_PASSWORD_NEW; typedef struct _USER_INTERNAL4_INFORMATION_NEW { USER_ALL_INFORMATION I1; ENCRYPTED_USER_PASSWORD_NEW UserPassword; } USER_INTERNAL4_INFORMATION_NEW, *PUSER_INTERNAL4_INFORMATION_NEW; typedef struct _USER_INTERNAL5_INFORMATION_NEW { ENCRYPTED_USER_PASSWORD_NEW UserPassword; BOOLEAN PasswordExpired; } USER_INTERNAL5_INFORMATION_NEW, *PUSER_INTERNAL5_INFORMATION_NEW; typedef struct _USER_ALLOWED_TO_DELEGATE_TO_LIST { ULONG Size; ULONG NumSPNs; UNICODE_STRING SPNList[ANYSIZE_ARRAY]; } USER_ALLOWED_TO_DELEGATE_TO_LIST, *PUSER_ALLOWED_TO_DELEGATE_TO_LIST; #define USER_EXTENDED_FIELD_UPN 0x00000001L #define USER_EXTENDED_FIELD_A2D2 0x00000002L typedef struct _USER_INTERNAL6_INFORMATION { USER_ALL_INFORMATION I1; LARGE_INTEGER LastBadPasswordTime; ULONG ExtendedFields; BOOLEAN UPNDefaulted; UNICODE_STRING UPN; PUSER_ALLOWED_TO_DELEGATE_TO_LIST A2D2List; } USER_INTERNAL6_INFORMATION, *PUSER_INTERNAL6_INFORMATION; typedef SAM_BYTE_ARRAY_32K SAM_USER_TILE, *PSAM_USER_TILE; // 0xff000fff is reserved for internal callers and implementation. #define USER_EXTENDED_FIELD_USER_TILE (0x00001000L) #define USER_EXTENDED_FIELD_PASSWORD_HINT (0x00002000L) #define USER_EXTENDED_FIELD_DONT_SHOW_IN_LOGON_UI (0x00004000L) #define USER_EXTENDED_FIELD_SHELL_ADMIN_OBJECT_PROPERTIES (0x00008000L) typedef struct _USER_EXTENDED_INFORMATION { ULONG ExtendedWhichFields; SAM_USER_TILE UserTile; UNICODE_STRING PasswordHint; BOOLEAN DontShowInLogonUI; SAM_SHELL_OBJECT_PROPERTIES ShellAdminObjectProperties; } USER_EXTENDED_INFORMATION, *PUSER_EXTENDED_INFORMATION; // For local callers only. typedef struct _USER_LOGON_UI_INFORMATION { BOOLEAN PasswordIsBlank; BOOLEAN AccountIsDisabled; } USER_LOGON_UI_INFORMATION, *PUSER_LOGON_UI_INFORMATION; typedef struct _USER_AUTH_INFORMATION { SAM_BYTE_ARRAY_32K AuthData; } USER_AUTH_INFORMATION, *PUSER_AUTH_INFORMATION; typedef struct _ENCRYPTED_PASSWORD_AES { UCHAR AuthData[64]; UCHAR Salt[SAM_PASSWORD_ENCRYPTION_SALT_LEN]; ULONG cbCipher; PUCHAR Cipher; ULONGLONG PBKDF2Iterations; } ENCRYPTED_PASSWORD_AES, *PENCRYPTED_PASSWORD_AES; typedef struct _USER_INTERNAL7_INFORMATION { ENCRYPTED_PASSWORD_AES UserPassword; BOOLEAN PasswordExpired; } USER_INTERNAL7_INFORMATION, *PUSER_INTERNAL7_INFORMATION; typedef struct _USER_INTERNAL8_INFORMATION { USER_ALL_INFORMATION I1; ENCRYPTED_PASSWORD_AES UserPassword; } USER_INTERNAL8_INFORMATION, *PUSER_INTERNAL8_INFORMATION; // SamChangePasswordUser3 types // Error values: // * SAM_PWD_CHANGE_NO_ERROR // * SAM_PWD_CHANGE_PASSWORD_TOO_SHORT // * SAM_PWD_CHANGE_PWD_IN_HISTORY // * SAM_PWD_CHANGE_USERNAME_IN_PASSWORD // * SAM_PWD_CHANGE_FULLNAME_IN_PASSWORD // * SAM_PWD_CHANGE_MACHINE_PASSWORD_NOT_DEFAULT // * SAM_PWD_CHANGE_FAILED_BY_FILTER typedef struct _USER_PWD_CHANGE_FAILURE_INFORMATION { ULONG ExtendedFailureReason; UNICODE_STRING FilterModuleName; } USER_PWD_CHANGE_FAILURE_INFORMATION, *PUSER_PWD_CHANGE_FAILURE_INFORMATION; // // ExtendedFailureReason values // #define SAM_PWD_CHANGE_NO_ERROR 0 #define SAM_PWD_CHANGE_PASSWORD_TOO_SHORT 1 #define SAM_PWD_CHANGE_PWD_IN_HISTORY 2 #define SAM_PWD_CHANGE_USERNAME_IN_PASSWORD 3 #define SAM_PWD_CHANGE_FULLNAME_IN_PASSWORD 4 #define SAM_PWD_CHANGE_NOT_COMPLEX 5 #define SAM_PWD_CHANGE_MACHINE_PASSWORD_NOT_DEFAULT 6 #define SAM_PWD_CHANGE_FAILED_BY_FILTER 7 #define SAM_PWD_CHANGE_PASSWORD_TOO_LONG 8 #define SAM_PWD_CHANGE_FAILURE_REASON_MAX 8 // // Functions // NTSYSAPI NTSTATUS NTAPI SamEnumerateUsersInDomain( _In_ SAM_HANDLE DomainHandle, _Inout_ PSAM_ENUMERATE_HANDLE EnumerationContext, _In_ ULONG UserAccountControl, _Outptr_ PVOID *Buffer, // PSAM_RID_ENUMERATION * _In_ ULONG PreferedMaximumLength, _Out_ PULONG CountReturned ); // rev NTSYSAPI NTSTATUS NTAPI SamEnumerateUsersInDomain2( _In_ SAM_HANDLE DomainHandle, _Inout_ PSAM_ENUMERATE_HANDLE EnumerationContext, _In_ ULONG UserAccountControl, _In_ ULONG Flags, _Outptr_ PVOID *Buffer, // PSAM_RID_ENUMERATION * _In_ ULONG PreferedMaximumLength, _Out_ PULONG CountReturned ); NTSYSAPI NTSTATUS NTAPI SamCreateUserInDomain( _In_ SAM_HANDLE DomainHandle, _In_ PCUNICODE_STRING AccountName, _In_ ACCESS_MASK DesiredAccess, _Out_ PSAM_HANDLE UserHandle, _Out_ PULONG RelativeId ); NTSYSAPI NTSTATUS NTAPI SamCreateUser2InDomain( _In_ SAM_HANDLE DomainHandle, _In_ PCUNICODE_STRING AccountName, _In_ ULONG AccountType, _In_ ACCESS_MASK DesiredAccess, _Out_ PSAM_HANDLE UserHandle, _Out_ PULONG GrantedAccess, _Out_ PULONG RelativeId ); NTSYSAPI NTSTATUS NTAPI SamOpenUser( _In_ SAM_HANDLE DomainHandle, _In_ ACCESS_MASK DesiredAccess, _In_ ULONG UserId, _Out_ PSAM_HANDLE UserHandle ); NTSYSAPI NTSTATUS NTAPI SamDeleteUser( _In_ SAM_HANDLE UserHandle ); NTSYSAPI NTSTATUS NTAPI SamQueryInformationUser( _In_ SAM_HANDLE UserHandle, _In_ USER_INFORMATION_CLASS UserInformationClass, _Outptr_ PVOID *Buffer ); NTSYSAPI NTSTATUS NTAPI SamSetInformationUser( _In_ SAM_HANDLE UserHandle, _In_ USER_INFORMATION_CLASS UserInformationClass, _In_ PVOID Buffer ); NTSYSAPI NTSTATUS NTAPI SamGetGroupsForUser( _In_ SAM_HANDLE UserHandle, _Out_ _Deref_post_count_(*MembershipCount) PGROUP_MEMBERSHIP *Groups, _Out_ PULONG MembershipCount ); NTSYSAPI NTSTATUS NTAPI SamChangePasswordUser( _In_ SAM_HANDLE UserHandle, _In_ PCUNICODE_STRING OldPassword, _In_ PCUNICODE_STRING NewPassword ); NTSYSAPI NTSTATUS NTAPI SamChangePasswordUser2( _In_ PCUNICODE_STRING ServerName, _In_ PCUNICODE_STRING UserName, _In_ PCUNICODE_STRING OldPassword, _In_ PCUNICODE_STRING NewPassword ); NTSYSAPI NTSTATUS NTAPI SamChangePasswordUser3( _In_ PCUNICODE_STRING ServerName, _In_ PCUNICODE_STRING UserName, _In_ PCUNICODE_STRING OldPassword, _In_ PCUNICODE_STRING NewPassword, _Outptr_ PDOMAIN_PASSWORD_INFORMATION *EffectivePasswordPolicy, _Outptr_ PUSER_PWD_CHANGE_FAILURE_INFORMATION *PasswordChangeFailureInfo ); NTSYSAPI NTSTATUS NTAPI SamQueryDisplayInformation( _In_ SAM_HANDLE DomainHandle, _In_ DOMAIN_DISPLAY_INFORMATION DisplayInformation, _In_ ULONG Index, _In_ ULONG EntryCount, _In_ ULONG PreferredMaximumLength, _Out_ PULONG TotalAvailable, _Out_ PULONG TotalReturned, _Out_ PULONG ReturnedEntryCount, _Outptr_ PVOID *SortedBuffer ); /** * The SamGetDisplayEnumerationIndex method obtains an index into an ascending account-name–sorted list of accounts. * * \param DomainHandle A handle representing a domain. * \param DisplayInformation An enumeration indicating which set of objects to return an index. * \param Prefix A string matched against the account name to find a starting point for an enumeration. * \param Index A value to use as input to SamQueryDisplayInformation in order to control the accounts that are returned from that method. * \return NTSTATUS Successful or errant status. * \sa https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-samr/bd429624-f2d5-4717-8aa2-659952c3e209 */ NTSYSAPI NTSTATUS NTAPI SamGetDisplayEnumerationIndex( _In_ SAM_HANDLE DomainHandle, _In_ DOMAIN_DISPLAY_INFORMATION DisplayInformation, _In_ PCUNICODE_STRING Prefix, _Out_ PULONG Index ); // // Database replication // typedef enum _SECURITY_DB_DELTA_TYPE { SecurityDbNew = 1, SecurityDbRename, SecurityDbDelete, SecurityDbChangeMemberAdd, SecurityDbChangeMemberSet, SecurityDbChangeMemberDel, SecurityDbChange, SecurityDbChangePassword } SECURITY_DB_DELTA_TYPE, *PSECURITY_DB_DELTA_TYPE; typedef enum _SECURITY_DB_OBJECT_TYPE { SecurityDbObjectSamDomain = 1, SecurityDbObjectSamUser, SecurityDbObjectSamGroup, SecurityDbObjectSamAlias, SecurityDbObjectLsaPolicy, SecurityDbObjectLsaTDomain, SecurityDbObjectLsaAccount, SecurityDbObjectLsaSecret } SECURITY_DB_OBJECT_TYPE, *PSECURITY_DB_OBJECT_TYPE; typedef enum _SAM_ACCOUNT_TYPE { SamObjectUser = 1, SamObjectGroup, SamObjectAlias } SAM_ACCOUNT_TYPE, *PSAM_ACCOUNT_TYPE; #define SAM_USER_ACCOUNT (0x00000001) #define SAM_GLOBAL_GROUP_ACCOUNT (0x00000002) #define SAM_LOCAL_GROUP_ACCOUNT (0x00000004) typedef struct _SAM_GROUP_MEMBER_ID { ULONG MemberRid; } SAM_GROUP_MEMBER_ID, *PSAM_GROUP_MEMBER_ID; typedef struct _SAM_ALIAS_MEMBER_ID { PSID MemberSid; } SAM_ALIAS_MEMBER_ID, *PSAM_ALIAS_MEMBER_ID; typedef union _SAM_DELTA_DATA { SAM_GROUP_MEMBER_ID GroupMemberId; SAM_ALIAS_MEMBER_ID AliasMemberId; ULONG AccountControl; } SAM_DELTA_DATA, *PSAM_DELTA_DATA; typedef _Function_class_(SAM_DELTA_NOTIFICATION_ROUTINE) NTSTATUS NTAPI SAM_DELTA_NOTIFICATION_ROUTINE( _In_ PSID DomainSid, _In_ SECURITY_DB_DELTA_TYPE DeltaType, _In_ SECURITY_DB_OBJECT_TYPE ObjectType, _In_ ULONG ObjectRid, _In_opt_ PCUNICODE_STRING ObjectName, _In_ PLARGE_INTEGER ModifiedCount, _In_opt_ PSAM_DELTA_DATA DeltaData ); typedef SAM_DELTA_NOTIFICATION_ROUTINE* PSAM_DELTA_NOTIFICATION_ROUTINE; #define SAM_DELTA_NOTIFY_ROUTINE "DeltaNotify" NTSYSAPI NTSTATUS NTAPI SamRegisterObjectChangeNotification( _In_ SECURITY_DB_OBJECT_TYPE ObjectType, _In_ HANDLE NotificationEventHandle ); NTSYSAPI NTSTATUS NTAPI SamUnregisterObjectChangeNotification( _In_ SECURITY_DB_OBJECT_TYPE ObjectType, _In_ HANDLE NotificationEventHandle ); // // Compatibility mode // #define SAM_SID_COMPATIBILITY_ALL 0 #define SAM_SID_COMPATIBILITY_LAX 1 #define SAM_SID_COMPATIBILITY_STRICT 2 NTSYSAPI NTSTATUS NTAPI SamGetCompatibilityMode( _In_ SAM_HANDLE ObjectHandle, _Out_ ULONG *Mode ); // // Password validation // typedef enum _PASSWORD_POLICY_VALIDATION_TYPE { SamValidateAuthentication = 1, SamValidatePasswordChange, SamValidatePasswordReset } PASSWORD_POLICY_VALIDATION_TYPE; typedef struct _SAM_VALIDATE_PASSWORD_HASH { ULONG Length; _Field_size_bytes_(Length) PUCHAR Hash; } SAM_VALIDATE_PASSWORD_HASH, *PSAM_VALIDATE_PASSWORD_HASH; // Flags for PresentFields in SAM_VALIDATE_PERSISTED_FIELDS #define SAM_VALIDATE_PASSWORD_LAST_SET 0x00000001 #define SAM_VALIDATE_BAD_PASSWORD_TIME 0x00000002 #define SAM_VALIDATE_LOCKOUT_TIME 0x00000004 #define SAM_VALIDATE_BAD_PASSWORD_COUNT 0x00000008 #define SAM_VALIDATE_PASSWORD_HISTORY_LENGTH 0x00000010 #define SAM_VALIDATE_PASSWORD_HISTORY 0x00000020 typedef struct _SAM_VALIDATE_PERSISTED_FIELDS { ULONG PresentFields; LARGE_INTEGER PasswordLastSet; LARGE_INTEGER BadPasswordTime; LARGE_INTEGER LockoutTime; ULONG BadPasswordCount; ULONG PasswordHistoryLength; _Field_size_bytes_(PasswordHistoryLength) PSAM_VALIDATE_PASSWORD_HASH PasswordHistory; } SAM_VALIDATE_PERSISTED_FIELDS, *PSAM_VALIDATE_PERSISTED_FIELDS; typedef enum _SAM_VALIDATE_VALIDATION_STATUS { SamValidateSuccess = 0, SamValidatePasswordMustChange, SamValidateAccountLockedOut, SamValidatePasswordExpired, SamValidatePasswordIncorrect, SamValidatePasswordIsInHistory, SamValidatePasswordTooShort, SamValidatePasswordTooLong, SamValidatePasswordNotComplexEnough, SamValidatePasswordTooRecent, SamValidatePasswordFilterError } SAM_VALIDATE_VALIDATION_STATUS, *PSAM_VALIDATE_VALIDATION_STATUS; typedef struct _SAM_VALIDATE_STANDARD_OUTPUT_ARG { SAM_VALIDATE_PERSISTED_FIELDS ChangedPersistedFields; SAM_VALIDATE_VALIDATION_STATUS ValidationStatus; } SAM_VALIDATE_STANDARD_OUTPUT_ARG, *PSAM_VALIDATE_STANDARD_OUTPUT_ARG; typedef struct _SAM_VALIDATE_AUTHENTICATION_INPUT_ARG { SAM_VALIDATE_PERSISTED_FIELDS InputPersistedFields; BOOLEAN PasswordMatched; } SAM_VALIDATE_AUTHENTICATION_INPUT_ARG, *PSAM_VALIDATE_AUTHENTICATION_INPUT_ARG; typedef struct _SAM_VALIDATE_PASSWORD_CHANGE_INPUT_ARG { SAM_VALIDATE_PERSISTED_FIELDS InputPersistedFields; UNICODE_STRING ClearPassword; UNICODE_STRING UserAccountName; SAM_VALIDATE_PASSWORD_HASH HashedPassword; BOOLEAN PasswordMatch; // denotes if the old password supplied by user matched or not } SAM_VALIDATE_PASSWORD_CHANGE_INPUT_ARG, *PSAM_VALIDATE_PASSWORD_CHANGE_INPUT_ARG; typedef struct _SAM_VALIDATE_PASSWORD_RESET_INPUT_ARG { SAM_VALIDATE_PERSISTED_FIELDS InputPersistedFields; UNICODE_STRING ClearPassword; UNICODE_STRING UserAccountName; SAM_VALIDATE_PASSWORD_HASH HashedPassword; BOOLEAN PasswordMustChangeAtNextLogon; // looked at only for password reset BOOLEAN ClearLockout; // can be used clear user account lockout } SAM_VALIDATE_PASSWORD_RESET_INPUT_ARG, *PSAM_VALIDATE_PASSWORD_RESET_INPUT_ARG; typedef union _SAM_VALIDATE_INPUT_ARG { SAM_VALIDATE_AUTHENTICATION_INPUT_ARG ValidateAuthenticationInput; SAM_VALIDATE_PASSWORD_CHANGE_INPUT_ARG ValidatePasswordChangeInput; SAM_VALIDATE_PASSWORD_RESET_INPUT_ARG ValidatePasswordResetInput; } SAM_VALIDATE_INPUT_ARG, *PSAM_VALIDATE_INPUT_ARG; typedef union _SAM_VALIDATE_OUTPUT_ARG { SAM_VALIDATE_STANDARD_OUTPUT_ARG ValidateAuthenticationOutput; SAM_VALIDATE_STANDARD_OUTPUT_ARG ValidatePasswordChangeOutput; SAM_VALIDATE_STANDARD_OUTPUT_ARG ValidatePasswordResetOutput; } SAM_VALIDATE_OUTPUT_ARG, *PSAM_VALIDATE_OUTPUT_ARG; NTSYSAPI NTSTATUS NTAPI SamValidatePassword( _In_opt_ PCUNICODE_STRING ServerName, _In_ PASSWORD_POLICY_VALIDATION_TYPE ValidationType, _In_ PSAM_VALIDATE_INPUT_ARG InputArg, _Out_ PSAM_VALIDATE_OUTPUT_ARG *OutputArg ); // // Generic operation // typedef enum _SAM_GENERIC_OPERATION_TYPE { SamObjectChangeNotificationOperation } SAM_GENERIC_OPERATION_TYPE, *PSAM_GENERIC_OPERATION_TYPE; typedef struct _SAM_OPERATION_OBJCHG_INPUT { BOOLEAN Register; ULONG64 EventHandle; SECURITY_DB_OBJECT_TYPE ObjectType; ULONG ProcessID; } SAM_OPERATION_OBJCHG_INPUT, *PSAM_OPERATION_OBJCHG_INPUT; typedef struct _SAM_OPERATION_OBJCHG_OUTPUT { ULONG Reserved; } SAM_OPERATION_OBJCHG_OUTPUT, *PSAM_OPERATION_OBJCHG_OUTPUT; typedef union _SAM_GENERIC_OPERATION_INPUT { SAM_OPERATION_OBJCHG_INPUT ObjChangeIn; } SAM_GENERIC_OPERATION_INPUT, *PSAM_GENERIC_OPERATION_INPUT; typedef union _SAM_GENERIC_OPERATION_OUTPUT { SAM_OPERATION_OBJCHG_OUTPUT ObjChangeOut; } SAM_GENERIC_OPERATION_OUTPUT, *PSAM_GENERIC_OPERATION_OUTPUT; NTSYSAPI NTSTATUS NTAPI SamPerformGenericOperation( _In_opt_ PCWSTR ServerName, _In_ SAM_GENERIC_OPERATION_TYPE OperationType, _In_ PSAM_GENERIC_OPERATION_INPUT OperationIn, _Out_ PSAM_GENERIC_OPERATION_OUTPUT *OperationOut ); #endif // _NTSAM_H