#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), endpoint("ncacn_np:[\\pipe\\samr]","ncacn_ip_tcp:", "ncalrpc:"), pointer_default(unique) ] interface samr { /* account control (acct_flags) bits */ const int ACB_DISABLED = 0x0001; /* 1 = User account disabled */ const int ACB_HOMDIRREQ = 0x0002; /* 1 = Home directory required */ const int ACB_PWNOTREQ = 0x0004; /* 1 = User password not required */ const int ACB_TEMPDUP = 0x0008; /* 1 = Temporary duplicate account */ const int ACB_NORMAL = 0x0010; /* 1 = Normal user account */ const int ACB_MNS = 0x0020; /* 1 = MNS logon user account */ const int ACB_DOMTRUST = 0x0040; /* 1 = Interdomain trust account */ const int ACB_WSTRUST = 0x0080; /* 1 = Workstation trust account */ const int ACB_SVRTRUST = 0x0100; /* 1 = Server trust account */ const int ACB_PWNOEXP = 0x0200; /* 1 = User password does not expire */ const int ACB_AUTOLOCK = 0x0400; /* 1 = Account auto locked */ /******************/ /* Function: 0x00 */ NTSTATUS samr_Connect ( /* notice the lack of [string] */ [in] uint16 *system_name, [in] uint32 access_mask, [out,ref] policy_handle *connect_handle ); /******************/ /* Function: 0x01 */ NTSTATUS samr_Close ( [in,out,ref] policy_handle *handle ); /******************/ /* Function: 0x02 */ typedef struct { [range(0,0x40000),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 */ /* shutdown the SAM - once you call this the SAM will be dead */ NTSTATUS samr_Shutdown ( [in,ref] policy_handle *connect_handle ); /******************/ /* 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 *connect_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 *connect_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 *connect_handle, [in] uint32 access_mask, [in,ref] dom_sid2 *sid, [out,ref] policy_handle *domain_handle ); /************************/ /* Function 0x08 */ /* server roles */ typedef enum { ROLE_STANDALONE = 0, ROLE_DOMAIN_MEMBER = 1, ROLE_DOMAIN_BDC = 2, ROLE_DOMAIN_PDC = 3 } samr_Role; typedef struct { uint16 min_password_len; uint16 password_history; uint32 password_properties; /* yes, these are signed. They are in negative 100ns */ int64 max_password_age; int64 min_password_age; } samr_DomInfo1; typedef struct { uint64 force_logoff_time; samr_Name comment; samr_Name domain; /* domain name */ samr_Name primary; /* PDC name if this is a BDC */ uint64 sequence_num; uint32 unknown2; uint32 role; uint32 unknown3; uint32 num_users; uint32 num_groups; uint32 num_aliases; } samr_DomInfo2; typedef struct { uint64 force_logoff_time; } samr_DomInfo3; typedef struct { /* I'm not entirely sure this is a comment. win2003 allows it to be set, and it seems harmless (like a comment) but I haven't seen it show up anywhere */ samr_Name comment; } 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; /* w2k3 returns 1 */ } samr_DomInfo9; typedef struct { samr_DomInfo2 info2; 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 *domain_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 *domain_handle, [in] uint16 level, [in,switch_is(level),ref] samr_DomainInfo *info ); /************************/ /* Function 0x0a */ NTSTATUS samr_CreateDomainGroup( [in,ref] policy_handle *domain_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 *domain_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 *domain_handle, [in,ref] samr_Name *account_name, [in] uint32 access_mask, [out,ref] policy_handle *user_handle, [out,ref] uint32 *rid ); /************************/ /* Function 0x0d */ /* w2k3 treats max_size as max_users*54 and sets the resume_handle as the rid of the last user sent */ const int SAMR_ENUM_USERS_MULTIPLIER = 54; NTSTATUS samr_EnumDomainUsers( [in,ref] policy_handle *domain_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 *domain_handle, [in,ref] samr_Name *aliasname, [in] uint32 access_mask, [out,ref] policy_handle *alias_handle, [out,ref] uint32 *rid ); /************************/ /* Function 0x0f */ NTSTATUS samr_EnumDomainAliases( [in,ref] policy_handle *domain_handle, [in,out,ref] uint32 *resume_handle, [in] uint32 acct_flags, [out] samr_SamArray *sam, [out] uint32 num_entries ); /************************/ /* Function 0x10 */ typedef enum { SID_NAME_USE_NONE = 0,/* NOTUSED */ SID_NAME_USER = 1, /* user */ SID_NAME_DOM_GRP = 2, /* domain group */ SID_NAME_DOMAIN = 3, /* domain: don't know what this is */ SID_NAME_ALIAS = 4, /* local group */ SID_NAME_WKN_GRP = 5, /* well-known group */ SID_NAME_DELETED = 6, /* deleted account: needed for c2 rating */ SID_NAME_INVALID = 7, /* invalid account */ SID_NAME_UNKNOWN = 8 /* oops. */ } samr_SidType; typedef struct { [range(0,1024)] uint32 count; [size_is(count)] uint32 *ids; } samr_Ids; NTSTATUS samr_GetAliasMembership( [in,ref] policy_handle *alias_handle, [in,ref] lsa_SidArray *sids, [out] samr_Ids *rids ); /************************/ /* Function 0x11 */ NTSTATUS samr_LookupNames( [in,ref] policy_handle *domain_handle, [in,range(0,1000)] 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 *domain_handle, [in,range(0,1000)] 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 *domain_handle, [in] uint32 access_mask, [in] uint32 rid, [out,ref] policy_handle *group_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 = 2, GroupInfoX = 3, GroupInfoDescription = 4, GroupInfoAll2 = 5 } GroupInfo; typedef union { [case(GroupInfoAll)] samr_GroupInfoAll all; [case(GroupInfoName)] samr_Name name; [case(GroupInfoX)] samr_GroupInfoX unknown; [case(GroupInfoDescription)] samr_Name description; [case(GroupInfoAll2)] samr_GroupInfoAll all2; } samr_GroupInfo; NTSTATUS samr_QueryGroupInfo( [in,ref] policy_handle *group_handle, [in] uint16 level, [out,switch_is(level)] samr_GroupInfo *info ); /************************/ /* Function 0x15 */ NTSTATUS samr_SetGroupInfo( [in,ref] policy_handle *group_handle, [in] uint16 level, [in,switch_is(level),ref] samr_GroupInfo *info ); /************************/ /* Function 0x16 */ NTSTATUS samr_AddGroupMember( [in,ref] policy_handle *group_handle, [in] uint32 rid, [in] uint32 flags ); /************************/ /* Function 0x17 */ NTSTATUS samr_DeleteDomainGroup( [in,out,ref] policy_handle *group_handle ); /************************/ /* Function 0x18 */ NTSTATUS samr_DeleteGroupMember( [in,ref] policy_handle *group_handle, [in] uint32 rid ); /************************/ /* Function 0x19 */ typedef struct { uint32 count; [size_is(count)] uint32 *rids; [size_is(count)] uint32 *unknown; } samr_ridArray; NTSTATUS samr_QueryGroupMember( [in,ref] policy_handle *group_handle, [out] samr_ridArray *rids ); /************************/ /* Function 0x1a */ /* win2003 seems to accept any data at all for the two integers below, and doesn't seem to do anything with them that I can see. Weird. I really expected the first integer to be a rid and the second to be the attributes for that rid member. */ NTSTATUS samr_SetMemberAttributesOfGroup( [in,ref] policy_handle *group_handle, [in] uint32 unknown1, [in] uint32 unknown2 ); /************************/ /* Function 0x1b */ NTSTATUS samr_OpenAlias ( [in,ref] policy_handle *domain_handle, [in] uint32 access_mask, [in] uint32 rid, [out,ref] policy_handle *alias_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 *alias_handle, [in] uint16 level, [out,switch_is(level)] samr_AliasInfo *info ); /************************/ /* Function 0x1d */ NTSTATUS samr_SetAliasInfo( [in,ref] policy_handle *alias_handle, [in] uint16 level, [in,switch_is(level)] samr_AliasInfo info ); /************************/ /* Function 0x1e */ NTSTATUS samr_DeleteDomAlias( [in,out,ref] policy_handle *alias_handle ); /************************/ /* Function 0x1f */ NTSTATUS samr_AddAliasMember( [in,ref] policy_handle *alias_handle, [in,ref] dom_sid2 *sid ); /************************/ /* Function 0x20 */ NTSTATUS samr_DeleteAliasMember( [in,ref] policy_handle *alias_handle, [in,ref] dom_sid2 *sid ); /************************/ /* Function 0x21 */ NTSTATUS samr_GetMembersInAlias( [in,ref] policy_handle *alias_handle, [out,ref] lsa_SidArray *sids ); /************************/ /* Function 0x22 */ NTSTATUS samr_OpenUser( [in,ref] policy_handle *domain_handle, [in] uint32 access_mask, [in] uint32 rid, [out,ref] policy_handle *user_handle ); /************************/ /* Function 0x23 */ NTSTATUS samr_DeleteUser( [in,out,ref] policy_handle *user_handle ); /************************/ /* Function 0x24 */ typedef struct { samr_Name account_name; 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 account_name; samr_Name full_name; uint32 rid; uint32 primary_gid; samr_Name home_directory; samr_Name home_drive; samr_Name logon_script; samr_Name profile_path; samr_Name workstations; NTTIME last_logon; NTTIME last_logoff; NTTIME last_password_change; NTTIME allow_password_change; NTTIME force_password_change; samr_LogonHours logon_hours; uint16 bad_password_count; uint16 num_logons; uint32 acct_flags; } samr_UserInfo3; typedef struct { samr_LogonHours logon_hours; } samr_UserInfo4; typedef struct { samr_Name account_name; samr_Name full_name; uint32 rid; uint32 primary_gid; samr_Name home_directory; samr_Name home_drive; samr_Name logon_script; samr_Name profile_path; samr_Name description; samr_Name workstations; NTTIME last_logon; NTTIME last_logoff; samr_LogonHours logon_hours; uint16 bad_password_count; uint16 num_logons; NTTIME last_password_change; NTTIME acct_expiry; uint32 acct_flags; } samr_UserInfo5; typedef struct { samr_Name account_name; samr_Name full_name; } samr_UserInfo6; typedef struct { samr_Name account_name; } samr_UserInfo7; typedef struct { samr_Name full_name; } samr_UserInfo8; typedef struct { uint32 primary_gid; } samr_UserInfo9; typedef struct { samr_Name home_directory; samr_Name home_drive; } samr_UserInfo10; typedef struct { samr_Name logon_script; } samr_UserInfo11; typedef struct { samr_Name profile_path; } 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; /* this defines the bits used for fields_present in info21 */ const int SAMR_FIELD_NAME = 0x00000002; const int SAMR_FIELD_DESCRIPTION = 0x00000010; const int SAMR_FIELD_COMMENT = 0x00000020; const int SAMR_FIELD_LOGON_SCRIPT = 0x00000100; const int SAMR_FIELD_PROFILE_PATH = 0x00000200; const int SAMR_FIELD_WORKSTATION = 0x00000400; const int SAMR_FIELD_LOGON_HOURS = 0x00002000; const int SAMR_FIELD_ACCT_FLAGS = 0x00100000; const int SAMR_FIELD_CALLBACK = 0x00200000; const int SAMR_FIELD_COUNTRY_CODE = 0x00400000; const int SAMR_FIELD_CODE_PAGE = 0x00800000; const int SAMR_FIELD_PASSWORD = 0x01000000; /* either of these */ const int SAMR_FIELD_PASSWORD2 = 0x02000000; /* two bits seems to work */ typedef struct { NTTIME last_logon; NTTIME last_logoff; NTTIME last_password_change; NTTIME acct_expiry; NTTIME allow_password_change; NTTIME force_password_change; samr_Name account_name; samr_Name full_name; samr_Name home_directory; samr_Name home_drive; samr_Name logon_script; samr_Name profile_path; 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_password_count; uint16 num_logons; uint16 country_code; uint16 code_page; uint8 nt_password_set; uint8 lm_password_set; uint8 expired_flag; uint8 unknown4; } samr_UserInfo21; typedef [flag(NDR_PAHEX)] struct { uint8 data[516]; } samr_CryptPassword; typedef struct { samr_UserInfo21 info; samr_CryptPassword password; } samr_UserInfo23; typedef struct { samr_CryptPassword password; uint16 pw_len; } samr_UserInfo24; typedef [flag(NDR_PAHEX)] struct { uint8 data[532]; } samr_CryptPasswordEx; typedef struct { samr_UserInfo21 info; samr_CryptPasswordEx password; } samr_UserInfo25; typedef struct { samr_CryptPasswordEx password; uint8 pw_len; } samr_UserInfo26; 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; [case(23)] samr_UserInfo23 info23; [case(24)] samr_UserInfo24 info24; [case(25)] samr_UserInfo25 info25; [case(26)] samr_UserInfo26 info26; } samr_UserInfo; NTSTATUS samr_QueryUserInfo( [in,ref] policy_handle *user_handle, [in] uint16 level, [out,switch_is(level)] samr_UserInfo *info ); /************************/ /* Function 0x25 */ NTSTATUS samr_SetUserInfo( [in,ref] policy_handle *user_handle, [in] uint16 level, [in,ref,switch_is(level)] samr_UserInfo *info ); /************************/ /* Function 0x26 */ /* this is a password change interface that doesn't give the server the plaintext password. Depricated. */ NTSTATUS samr_ChangePasswordUser( [in,ref] policy_handle *user_handle, [in] bool8 lm_present, [in] samr_Password *old_lm_crypted, [in] samr_Password *new_lm_crypted, [in] bool8 nt_present, [in] samr_Password *old_nt_crypted, [in] samr_Password *new_nt_crypted, [in] bool8 cross1_present, [in] samr_Password *nt_cross, [in] bool8 cross2_present, [in] samr_Password *lm_cross ); /************************/ /* 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 *user_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_noterm *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 *domain_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 *domain_handle, [in] uint16 level, [in] samr_Name name, [out] uint32 idx ); /************************/ /* Function 0x2a */ /* w2k3 returns NT_STATUS_NOT_IMPLEMENTED for this */ NTSTATUS samr_TestPrivateFunctionsDomain( [in,ref] policy_handle *domain_handle ); /************************/ /* Function 0x2b */ /* w2k3 returns NT_STATUS_NOT_IMPLEMENTED for this */ NTSTATUS samr_TestPrivateFunctionsUser( [in,ref] policy_handle *user_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_password_len; uint32 password_properties; } samr_PwInfo; NTSTATUS samr_GetUserPwInfo( [in,ref] policy_handle *user_handle, [out] samr_PwInfo info ); /************************/ /* Function 0x2d */ NTSTATUS samr_RemoveMemberFromForeignDomain( [in,ref] policy_handle *domain_handle, [in,ref] dom_sid2 *sid ); /************************/ /* Function 0x2e */ /* how is this different from QueryDomainInfo ?? */ NTSTATUS samr_QueryDomainInfo2( [in,ref] policy_handle *domain_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 *user_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 *domain_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 *domain_handle, [in] uint16 level, [in] samr_Name name, [out] uint32 idx ); /************************/ /* Function 0x32 */ NTSTATUS samr_CreateUser2( [in,ref] policy_handle *domain_handle, [in,ref] samr_Name *account_name, [in] uint32 acct_flags, [in] uint32 access_mask, [out,ref] policy_handle *user_handle, [out,ref] uint32 *access_granted, [out,ref] uint32 *rid ); /************************/ /* Function 0x33 */ /* another duplicate. There must be a reason .... */ NTSTATUS samr_QueryDisplayInfo3( [in,ref] policy_handle *domain_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 0x34 */ NTSTATUS samr_AddMultipleMembersToAlias( [in,ref] policy_handle *alias_handle, [in,ref] lsa_SidArray *sids ); /************************/ /* Function 0x35 */ NTSTATUS samr_RemoveMultipleMembersFromAlias( [in,ref] policy_handle *alias_handle, [in,ref] lsa_SidArray *sids ); /************************/ /* Function 0x36 */ NTSTATUS samr_OemChangePasswordUser2( [in] samr_AsciiName *server, [in,ref] samr_AsciiName *account, [in] samr_CryptPassword *password, [in] samr_Password *hash ); /************************/ /* Function 0x37 */ NTSTATUS samr_ChangePasswordUser2( [in] samr_Name *server, [in,ref] samr_Name *account, [in] samr_CryptPassword *nt_password, [in] samr_Password *nt_verifier, [in] bool8 lm_change, [in] samr_CryptPassword *lm_password, [in] samr_Password *lm_verifier ); /************************/ /* Function 0x38 */ NTSTATUS samr_GetDomPwInfo( [in] samr_Name *name, [out] samr_PwInfo info ); /************************/ /* Function 0x39 */ NTSTATUS samr_Connect2( [in] unistr *system_name, [in] uint32 access_mask, [out,ref] policy_handle *connect_handle ); /************************/ /* Function 0x3a */ /* seems to be an exact alias for samr_SetUserInfo() */ NTSTATUS samr_SetUserInfo2( [in,ref] policy_handle *user_handle, [in] uint16 level, [in,ref,switch_is(level)] samr_UserInfo *info ); /************************/ /* Function 0x3b */ /* this one is mysterious. I have a few guesses, but nothing working yet */ NTSTATUS samr_SetBootKeyInformation( [in,ref] policy_handle *connect_handle, [in] uint32 unknown1, [in] uint32 unknown2, [in] uint32 unknown3 ); /************************/ /* Function 0x3c */ NTSTATUS samr_GetBootKeyInformation( [in,ref] policy_handle *domain_handle, [out] uint32 unknown ); /************************/ /* Function 0x3d */ NTSTATUS samr_Connect3( [in] unistr *system_name, /* this unknown value seems to be completely ignored by w2k3 */ [in] uint32 unknown, [in] uint32 access_mask, [out,ref] policy_handle *connect_handle ); /************************/ /* Function 0x3e */ NTSTATUS samr_Connect4( [in] unistr *system_name, [in] uint32 unknown, [in] uint32 access_mask, [out,ref] policy_handle *connect_handle ); /************************/ /* Function 0x3f */ const int SAMR_REJECT_OTHER = 0; const int SAMR_REJECT_TOO_SHORT = 1; const int SAMR_REJECT_COMPLEXITY = 2; typedef struct { uint32 reason; uint32 unknown1; uint32 unknown2; } samr_ChangeReject; NTSTATUS samr_ChangePasswordUser3( [in] samr_Name *server, [in,ref] samr_Name *account, [in] samr_CryptPassword *nt_password, [in] samr_Password *nt_verifier, [in] bool8 lm_change, [in] samr_CryptPassword *lm_password, [in] samr_Password *lm_verifier, [in] samr_CryptPassword *password3, [out] samr_DomInfo1 *dominfo, [out] samr_ChangeReject *reject ); /************************/ /* Function 0x40 */ typedef struct { uint32 unknown1; /* w2k3 gives 3 */ uint32 unknown2; /* w2k3 gives 0 */ } samr_ConnectInfo1; typedef union { [case(1)] samr_ConnectInfo1 info1; } samr_ConnectInfo; NTSTATUS samr_Connect5( [in] unistr *system_name, [in] uint32 access_mask, [in,out] uint32 level, [in,out,switch_is(level),ref] samr_ConnectInfo *info, [out,ref] policy_handle *connect_handle ); /************************/ /* Function 0x41 */ NTSTATUS samr_RidToSid( [in,ref] policy_handle *domain_handle, [in] uint32 rid, [out] dom_sid2 *sid ); /************************/ /* Function 0x42 */ /* this should set the DSRM password for the server, which is used when booting into Directory Services Recovery Mode on a DC. Win2003 gives me NT_STATUS_NOT_SUPPORTED */ NTSTATUS samr_SetDsrmPassword( [in] samr_Name *name, [in] uint32 unknown, [in] samr_Password *hash ); /************************/ /* Function 0x43 */ /* I haven't been able to work out the format of this one yet. Seems to start with a switch level for a union? */ NTSTATUS samr_ValidatePassword(); }