#include "idl_types.h" /* samr interface definition */ /* Thanks to Todd Sabin for some information from his samr.idl in acltools */ [ uuid(12345778-1234-abcd-ef00-0123456789ac), version(1.0), pointer_default(unique) ] interface samr { /******************/ /* Function: 0x00 */ NTSTATUS samr_Connect ( /* notice the lack of [string] */ [in] uint16 *system_name, [in] uint32 access_mask, [out,ref] policy_handle *handle ); /******************/ /* Function: 0x01 */ NTSTATUS samr_Close ( [in,out,ref] policy_handle *handle ); /******************/ /* Function: 0x02 */ typedef struct { [value(ndr_size_security_descriptor(r->sd))] uint32 sd_size; [subcontext(4)] security_descriptor *sd; } samr_SdBuf; NTSTATUS samr_SetSecurity ( [in,ref] policy_handle *handle, [in] uint32 sec_info, [in,ref] samr_SdBuf *sdbuf ); /******************/ /* Function: 0x03 */ NTSTATUS samr_QuerySecurity ( [in,ref] policy_handle *handle, [in] uint32 sec_info, [out] samr_SdBuf *sdbuf ); /******************/ /* Function: 0x04 */ NTSTATUS samr_Shutdown (); /******************/ /* Function: 0x05 */ typedef struct { [value(2*strlen_m(r->name))] uint16 name_len; [value(r->name_len)] uint16 name_size; unistr_noterm *name; } samr_Name; NTSTATUS samr_LookupDomain ( [in,ref] policy_handle *handle, [in,ref] samr_Name *domain, [out] dom_sid2 *sid ); /******************/ /* Function: 0x06 */ typedef struct { uint32 idx; samr_Name name; } samr_SamEntry; typedef struct { uint32 count; [size_is(count)] samr_SamEntry *entries; } samr_SamArray; NTSTATUS samr_EnumDomains ( [in,ref] policy_handle *handle, [in,out,ref] uint32 *resume_handle, [in] uint32 buf_size, [out] samr_SamArray *sam, [out] uint32 num_entries ); /************************/ /* Function 0x07 */ NTSTATUS samr_OpenDomain( [in,ref] policy_handle *handle, [in] uint32 access_mask, [in,ref] dom_sid2 *sid, [out,ref] policy_handle *domain_handle ); /************************/ /* Function 0x08 */ typedef struct { uint16 min_length_password; uint16 password_history; uint32 flag; NTTIME expire; NTTIME min_passwordage; } samr_DomInfo1; typedef struct { ULONG8 force_logoff_time; samr_Name unknown1; samr_Name domain; /* domain name */ samr_Name primary; /* PDC name if this is a BDC */ HYPER_T sequence_num; uint32 unknown2; uint32 role; uint32 unknown3; uint32 num_users; uint32 num_groups; uint32 num_aliases; } samr_DomInfo2; typedef struct { ULONG8 force_logoff_time; } samr_DomInfo3; typedef struct { samr_Name unknown; } samr_DomInfo4; typedef struct { samr_Name domain; } samr_DomInfo5; typedef struct { samr_Name primary; } samr_DomInfo6; typedef struct { uint32 role; } samr_DomInfo7; typedef struct { HYPER_T sequence_num; NTTIME last_xxx_time; } samr_DomInfo8; typedef struct { uint32 unknown; } samr_DomInfo9; typedef struct { ULONG8 force_logoff_time; samr_Name unknown1; samr_Name domain; samr_Name primary; HYPER_T sequence_num; uint32 unknown2; uint32 role; uint32 unknown3; uint32 num_users; uint32 num_groups; uint32 num_aliases; HYPER_T lockout_duration; HYPER_T lockout_window; uint16 lockout_threshold; } samr_DomInfo11; typedef struct { HYPER_T lockout_duration; HYPER_T lockout_window; uint16 lockout_threshold; } samr_DomInfo12; typedef struct { HYPER_T sequence_num; NTTIME last_xxx_time; uint32 unknown1; uint32 unknown2; } samr_DomInfo13; typedef union { [case(1)] samr_DomInfo1 info1; [case(2)] samr_DomInfo2 info2; [case(3)] samr_DomInfo3 info3; [case(4)] samr_DomInfo4 info4; [case(5)] samr_DomInfo5 info5; [case(6)] samr_DomInfo6 info6; [case(7)] samr_DomInfo7 info7; [case(8)] samr_DomInfo8 info8; [case(9)] samr_DomInfo9 info9; [case(11)] samr_DomInfo11 info11; [case(12)] samr_DomInfo12 info12; [case(13)] samr_DomInfo13 info13; } samr_DomainInfo; NTSTATUS samr_QueryDomainInfo( [in,ref] policy_handle *handle, [in] uint16 level, [out,switch_is(level)] samr_DomainInfo *info ); /************************/ /* Function 0x09 */ /* only levels 1, 3, 4, 6, 7, 9, 12 are valid for this call in w2k3 */ NTSTATUS samr_SetDomainInfo( [in,ref] policy_handle *handle, [in] uint16 level, [in,switch_is(level),ref] samr_DomainInfo *info ); /************************/ /* Function 0x0a */ NTSTATUS samr_CreateDomainGroup( [in,ref] policy_handle *handle, [in,ref] samr_Name *name, [in] uint32 access_mask, [out,ref] policy_handle *group_handle, [out,ref] uint32 *rid ); /************************/ /* Function 0x0b */ NTSTATUS samr_EnumDomainGroups( [in,ref] policy_handle *handle, [in,out,ref] uint32 *resume_handle, [in] uint32 max_size, [out] samr_SamArray *sam, [out] uint32 num_entries ); /************************/ /* Function 0x0c */ NTSTATUS samr_CreateUser( [in,ref] policy_handle *handle, [in,ref] samr_Name *username, [in] uint32 access_mask, [out,ref] policy_handle *acct_handle, [out,ref] uint32 *rid ); /************************/ /* Function 0x0d */ NTSTATUS samr_EnumDomainUsers( [in,ref] policy_handle *handle, [in,out,ref] uint32 *resume_handle, [in] uint32 acct_flags, [in] uint32 max_size, [out] samr_SamArray *sam, [out] uint32 num_entries ); /************************/ /* Function 0x0e */ NTSTATUS samr_CreateDomAlias( [in,ref] policy_handle *handle, [in,ref] samr_Name *aliasname, [in] uint32 access_mask, [out,ref] policy_handle *acct_handle, [out,ref] uint32 *rid ); /************************/ /* Function 0x0f */ NTSTATUS samr_EnumDomainAliases( [in,ref] policy_handle *handle, [in,out,ref] uint32 *resume_handle, [in] uint32 max_size, [out] samr_SamArray *sam, [out] uint32 num_entries ); /************************/ /* Function 0x10 */ typedef struct { uint32 count; [size_is(count)] uint32 *ids; } samr_Ids; NTSTATUS samr_GetAliasMembership( [in,ref] policy_handle *handle, [in,ref] lsa_SidArray *sids, [out] samr_Ids *rids ); /************************/ /* Function 0x11 */ NTSTATUS samr_LookupNames( [in,ref] policy_handle *handle, [in] uint32 num_names, [in,ref,size_is(1000),length_is(num_names)] samr_Name *names, [out] samr_Ids rids, [out] samr_Ids types ); /************************/ /* Function 0x12 */ typedef struct { uint32 count; [size_is(count)] samr_Name *names; } samr_Names; NTSTATUS samr_LookupRids( [in,ref] policy_handle *handle, [in] uint32 num_rids, [in,ref,size_is(1000),length_is(num_rids)] uint32 *rids, [out] samr_Names names, [out] samr_Ids types ); /************************/ /* Function 0x13 */ NTSTATUS samr_OpenGroup( [in,ref] policy_handle *handle, [in] uint32 access_mask, [in] uint32 rid, [out,ref] policy_handle *acct_handle ); /************************/ /* Function 0x14 */ typedef struct { samr_Name name; uint32 unknown; uint32 num_members; samr_Name description; } samr_GroupInfoAll; typedef struct { uint32 unknown; } samr_GroupInfoX; typedef struct { samr_Name description; } samr_GroupInfoDesciption; typedef enum { GroupInfoAll = 1, GroupInfoName, GroupInfoX, GroupInfoDescription } GroupInfo; typedef union { [case(GroupInfoAll)] samr_GroupInfoAll all; [case(GroupInfoName)] samr_Name name; [case(GroupInfoX)] samr_GroupInfoX unknown; [case(GroupInfoDescription)] samr_Name description; } samr_GroupInfo; NTSTATUS samr_QueryGroupInfo( [in,ref] policy_handle *handle, [in] uint16 level, [out,switch_is(level)] samr_GroupInfo *info ); /************************/ /* Function 0x15 */ NTSTATUS samr_SetGroupInfo( [in,ref] policy_handle *handle, [in] uint16 level, [in,switch_is(level),ref] samr_GroupInfo *info ); /************************/ /* Function 0x16 */ NTSTATUS samr_AddGroupMember( [in,ref] policy_handle *handle, [in] uint32 rid, [in] uint32 flags ); /************************/ /* Function 0x17 */ NTSTATUS samr_DeleteDomainGroup( [in,out,ref] policy_handle *handle ); /************************/ /* Function 0x18 */ NTSTATUS samr_DeleteGroupMember( [in,ref] policy_handle *handle, [in] uint32 rid ); /************************/ /* Function 0x19 */ NTSTATUS samr_QUERY_GROUPMEM(); /************************/ /* Function 0x1a */ NTSTATUS samr_SET_MEMBER_ATTRIBUTES_OF_GROUP(); /************************/ /* Function 0x1b */ NTSTATUS samr_OpenAlias ( [in,ref] policy_handle *handle, [in] uint32 access_mask, [in] uint32 rid, [out,ref] policy_handle *acct_handle ); /************************/ /* Function 0x1c */ typedef struct { samr_Name name; uint32 num_members; samr_Name description; } samr_AliasInfoAll; typedef union { [case(1)] samr_AliasInfoAll all; [case(2)] samr_Name name; [case(3)] samr_Name description; } samr_AliasInfo; NTSTATUS samr_QueryAliasInfo( [in,ref] policy_handle *handle, [in] uint16 level, [out,switch_is(level)] samr_AliasInfo *info ); /************************/ /* Function 0x1d */ NTSTATUS samr_SetAliasInfo( [in,ref] policy_handle *handle, [in] uint16 level, [in,switch_is(level)] samr_AliasInfo info ); /************************/ /* Function 0x1e */ NTSTATUS samr_DeleteDomAlias( [in,out,ref] policy_handle *handle ); /************************/ /* Function 0x1f */ NTSTATUS samr_AddAliasMem( [in,ref] policy_handle *handle, [in,ref] dom_sid2 *sid ); /************************/ /* Function 0x20 */ NTSTATUS samr_DelAliasMem( [in,ref] policy_handle *handle, [in,ref] dom_sid2 *sid ); /************************/ /* Function 0x21 */ NTSTATUS samr_GetMembersInAlias( [in,ref] policy_handle *handle, [out,ref] lsa_SidArray *sids ); /************************/ /* Function 0x22 */ NTSTATUS samr_OpenUser( [in,ref] policy_handle *handle, [in] uint32 access_mask, [in] uint32 rid, [out,ref] policy_handle *acct_handle ); /************************/ /* Function 0x23 */ NTSTATUS samr_DeleteUser( [in,out,ref] policy_handle *handle ); /************************/ /* Function 0x24 */ typedef struct { samr_Name username; samr_Name full_name; uint32 primary_gid; samr_Name description; samr_Name comment; } samr_UserInfo1; typedef struct { samr_Name comment; samr_Name unknown; /* settable, but doesn't stick. probably obsolete */ uint16 country_code; uint16 code_page; } samr_UserInfo2; typedef struct { samr_Name username; samr_Name full_name; uint32 Rid; uint32 primary_gid; samr_Name home_directory; samr_Name home_drive; samr_Name logon_script; samr_Name profile; samr_Name workstations; NTTIME last_logon; NTTIME last_logoff; NTTIME last_pwd_change; NTTIME allow_pwd_change; NTTIME force_pwd_change; samr_LogonHours logon_hours; uint16 bad_pwd_count; uint16 num_logons; uint32 acct_flags; } samr_UserInfo3; typedef struct { samr_LogonHours logon_hours; } samr_UserInfo4; typedef struct { samr_Name username; samr_Name full_name; uint32 rid; uint32 primary_gid; samr_Name home_directory; samr_Name home_drive; samr_Name logon_script; samr_Name profile; samr_Name description; samr_Name workstations; NTTIME last_logon; NTTIME last_logoff; samr_LogonHours logon_hours; uint16 bad_pwd_count; uint16 num_logons; NTTIME last_pwd_change; NTTIME acct_expiry; uint32 acct_flags; } samr_UserInfo5; typedef struct { samr_Name username; samr_Name full_name; } samr_UserInfo6; typedef struct { samr_Name username; } samr_UserInfo7; typedef struct { samr_Name full_name; } samr_UserInfo8; typedef struct { uint32 primary_gid; } samr_UserInfo9; typedef struct { samr_Name home_dir; samr_Name home_drive; } samr_UserInfo10; typedef struct { samr_Name logon_script; } samr_UserInfo11; typedef struct { samr_Name profile; } samr_UserInfo12; typedef struct { samr_Name description; } samr_UserInfo13; typedef struct { samr_Name workstations; } samr_UserInfo14; typedef struct { uint32 acct_flags; } samr_UserInfo16; typedef struct { NTTIME acct_expiry; } samr_UserInfo17; typedef struct { samr_Name callback; } samr_UserInfo20; typedef struct { NTTIME last_logon; NTTIME last_logoff; NTTIME last_pwd_change; NTTIME acct_expiry; NTTIME allow_pwd_change; NTTIME force_pwd_change; samr_Name username; samr_Name full_name; samr_Name home_dir; samr_Name home_drive; samr_Name logon_script; samr_Name profile; samr_Name description; samr_Name workstations; samr_Name comment; samr_Name callback; samr_Name unknown1; samr_Name unknown2; samr_Name unknown3; uint32 buf_count; [size_is(buf_count)] uint8 *buffer; uint32 rid; uint32 primary_gid; uint32 acct_flags; uint32 fields_present; samr_LogonHours logon_hours; uint16 bad_pwd_count; uint16 num_logons; uint16 country_code; uint16 code_page; uint8 nt_pwd_set; uint8 lm_pwd_set; uint8 expired_flag; uint8 unknown4; } samr_UserInfo21; typedef union { [case(1)] samr_UserInfo1 info1; [case(2)] samr_UserInfo2 info2; [case(3)] samr_UserInfo3 info3; [case(4)] samr_UserInfo4 info4; [case(5)] samr_UserInfo5 info5; [case(6)] samr_UserInfo6 info6; [case(7)] samr_UserInfo7 info7; [case(8)] samr_UserInfo8 info8; [case(9)] samr_UserInfo9 info9; [case(10)] samr_UserInfo10 info10; [case(11)] samr_UserInfo11 info11; [case(12)] samr_UserInfo12 info12; [case(13)] samr_UserInfo13 info13; [case(14)] samr_UserInfo14 info14; [case(16)] samr_UserInfo16 info16; [case(17)] samr_UserInfo17 info17; [case(20)] samr_UserInfo20 info20; [case(21)] samr_UserInfo21 info21; } samr_UserInfo; NTSTATUS samr_QueryUserInfo( [in,ref] policy_handle *handle, [in] uint16 level, [out,switch_is(level)] samr_UserInfo *info ); /************************/ /* Function 0x25 */ NTSTATUS samr_SetUserInfo( [in,ref] policy_handle *handle, [in] uint16 level, [in,ref,switch_is(level)] samr_UserInfo *info ); /************************/ /* Function 0x26 */ typedef [flag(NDR_PAHEX)] struct { uint8 hash[16]; } samr_Hash; /* this interface is quite mysterious. I can make w2k3 give me NT_STATUS_PASSWORD_RESTRICTION and NT_STATUS_WRONG_PASSWORD with various options, but so far I haven't managed a successful password change. Perhaps this interface is disabled now? Needs testing against NT4 */ NTSTATUS samr_ChangePasswordUser( [in,ref] policy_handle *handle, [in] bool8 unknown1, [in] samr_Hash *hash1, [in] samr_Hash *hash2, [in] bool8 unknown2, [in] samr_Hash *hash3, [in] samr_Hash *hash4, [in] bool8 unknown3, [in] samr_Hash *hash5, [in] bool8 unknown4, [in] samr_Hash *hash6 ); /************************/ /* Function 0x27 */ typedef struct { uint32 rid; uint32 type; } samr_RidType; typedef struct { uint32 count; [size_is(count)] samr_RidType *rid; } samr_RidArray; NTSTATUS samr_GetGroupsForUser( [in,ref] policy_handle *handle, [out] samr_RidArray *rids ); /************************/ /* Function 0x28 */ typedef struct { uint32 idx; uint32 rid; uint32 acct_flags; samr_Name account_name; samr_Name full_name; samr_Name description; } samr_DispEntryGeneral; typedef struct { uint32 count; [size_is(count)] samr_DispEntryGeneral *entries; } samr_DispInfoGeneral; typedef struct { uint32 idx; uint32 rid; uint32 acct_flags; samr_Name account_name; samr_Name description; } samr_DispEntryFull; typedef struct { uint32 count; [size_is(count)] samr_DispEntryFull *entries; } samr_DispInfoFull; typedef struct { [value(strlen_m(r->name))] uint16 name_len; [value(strlen_m(r->name))] uint16 name_size; ascstr *name; } samr_AsciiName; typedef struct { uint32 idx; samr_AsciiName account_name; } samr_DispEntryAscii; typedef struct { uint32 count; [size_is(count)] samr_DispEntryAscii *entries; } samr_DispInfoAscii; typedef union { [case(1)] samr_DispInfoGeneral info1;/* users */ [case(2)] samr_DispInfoFull info2; /* trust accounts? */ [case(3)] samr_DispInfoFull info3; /* groups */ [case(4)] samr_DispInfoAscii info4; /* users */ [case(5)] samr_DispInfoAscii info5; /* groups */ } samr_DispInfo; NTSTATUS samr_QueryDisplayInfo( [in,ref] policy_handle *handle, [in] uint16 level, [in] uint32 start_idx, [in] uint32 max_entries, [in] uint32 buf_size, [out] uint32 total_size, [out] uint32 returned_size, [out,switch_is(level)] samr_DispInfo info ); /************************/ /* Function 0x29 */ /* this seems to be an alphabetic search function. The returned index is the index for samr_QueryDisplayInfo needed to get names occurring after the specified name. The supplied name does not need to exist in the database (for example you can supply just a first letter for searching starting at that letter) The level corresponds to the samr_QueryDisplayInfo level */ NTSTATUS samr_GetDisplayEnumerationIndex( [in,ref] policy_handle *handle, [in] uint16 level, [in] samr_Name name, [out] uint32 idx ); /************************/ /* Function 0x2a */ /* w2k3 return NT_STATUS_NOT_IMPLEMENTED for this */ NTSTATUS samr_TestPrivateFunctionsDomain( [in,ref] policy_handle *handle ); /************************/ /* Function 0x2b */ /* w2k3 return NT_STATUS_NOT_IMPLEMENTED for this */ NTSTATUS samr_TestPrivateFunctionsUser( [in,ref] policy_handle *handle ); /************************/ /* Function 0x2c */ /* password properties flags */ const uint32 DOMAIN_PASSWORD_COMPLEX = 0x00000001; const uint32 DOMAIN_PASSWORD_NO_ANON_CHANGE = 0x00000002; const uint32 DOMAIN_PASSWORD_NO_CLEAR_CHANGE = 0x00000004; const uint32 DOMAIN_PASSWORD_STORE_CLEARTEXT = 0x00000010; const uint32 DOMAIN_REFUSE_PASSWORD_CHANGE = 0x00000020; typedef struct { uint16 min_pwd_len; uint32 password_properties; } samr_PwInfo; NTSTATUS samr_GetUserPwInfo( [in,ref] policy_handle *handle, [out] samr_PwInfo info ); /************************/ /* Function 0x2d */ NTSTATUS samr_RemoveMemberFromForeignDomain( [in,ref] policy_handle *handle, [in,ref] dom_sid2 *sid ); /************************/ /* Function 0x2e */ /* how is this different from QueryDomainInfo ?? */ NTSTATUS samr_QueryDomainInfo2( [in,ref] policy_handle *handle, [in] uint16 level, [out,switch_is(level)] samr_DomainInfo *info ); /************************/ /* Function 0x2f */ /* how is this different from QueryUserInfo ?? */ NTSTATUS samr_QueryUserInfo2( [in,ref] policy_handle *handle, [in] uint16 level, [out,switch_is(level)] samr_UserInfo *info ); /************************/ /* Function 0x30 */ /* how is this different from QueryDisplayInfo?? */ NTSTATUS samr_QueryDisplayInfo2( [in,ref] policy_handle *handle, [in] uint16 level, [in] uint32 start_idx, [in] uint32 max_entries, [in] uint32 buf_size, [out] uint32 total_size, [out] uint32 returned_size, [out,switch_is(level)] samr_DispInfo info ); /************************/ /* Function 0x31 */ /* how is this different from GetDisplayEnumerationIndex ?? */ NTSTATUS samr_GetDisplayEnumerationIndex2( [in,ref] policy_handle *handle, [in] uint16 level, [in] samr_Name name, [out] uint32 idx ); /************************/ /* Function 0x32 */ NTSTATUS samr_CreateUser2( /************************/ [in,ref] policy_handle *handle, [in,ref] samr_Name *username, [in] uint32 acct_flags, [in] uint32 access_mask, [out,ref] policy_handle *acct_handle, [out,ref] uint32 *access_granted, [out,ref] uint32 *rid ); /************************/ /* Function 0x33 */ NTSTATUS samr_QUERY_DISPINFO3(); /************************/ /* Function 0x34 */ NTSTATUS samr_ADD_MULTIPLE_MEMBERS_TO_ALIAS(); /************************/ /* Function 0x35 */ NTSTATUS samr_REMOVE_MULTIPLE_MEMBERS_FROM_ALIAS(); /************************/ /* Function 0x36 */ NTSTATUS samr_OEM_CHANGE_PASSWORD_USER2(); /************************/ /* Function 0x37 */ NTSTATUS samr_UNICODE_CHANGE_PASSWORD_USER2(); /************************/ /* Function 0x38 */ NTSTATUS samr_GET_DOM_PWINFO(); /************************/ /* Function 0x39 */ NTSTATUS samr_Connect2( [in] unistr *system_name, [in] uint32 access_mask, [out,ref] policy_handle *handle ); /************************/ /* Function 0x3a */ NTSTATUS samr_SET_USERINFO2(); /************************/ /* Function 0x3b */ NTSTATUS samr_SET_BOOT_KEY_INFORMATION(); /************************/ /* Function 0x3c */ NTSTATUS samr_GET_BOOT_KEY_INFORMATION(); /************************/ /* Function 0x3d */ NTSTATUS samr_CONNECT3(); /************************/ /* Function 0x3e */ NTSTATUS samr_Connect4( [in] unistr *system_name, [in] uint32 unknown, [in] uint32 access_mask, [out,ref] policy_handle *handle ); /************************/ /* Function 0x3f */ NTSTATUS samr_UNICODE_CHANGE_PASSWORD_USER3(); /************************/ /* Function 0x40 */ NTSTATUS samr_Connect5( [in] unistr *system_name, [in] uint32 access_mask, [in] uint32 unknown0, [in] uint32 unknown1, [in] uint32 unknown2, [in] uint32 unknown3, [out] uint32 unknown4, [out] uint32 unknown5, [out] uint32 unknown6, [out] uint32 unknown7, [out,ref] policy_handle *handle ); /************************/ /* Function 0x41 */ NTSTATUS samr_RID_TO_SID(); /************************/ /* Function 0x42 */ NTSTATUS samr_SET_DSRM_PASSWORD(); /************************/ /* Function 0x43 */ NTSTATUS samr_VALIDATE_PASSWORD(); }