#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     */
	NTSTATUS samr_SET_DOMAIN_INFO();

	/************************/
	/* Function    0x0a     */
	NTSTATUS samr_CREATE_DOM_GROUP();

	/************************/
	/* 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_SET_GROUPINFO();

	/************************/
	/* Function    0x16     */
	NTSTATUS samr_ADD_GROUPMEM();

	/************************/
	/* Function    0x17     */
	NTSTATUS samr_DELETE_DOM_GROUP();

	/************************/
	/* Function    0x18     */
	NTSTATUS samr_DEL_GROUPMEM();

	/************************/
	/* 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     */
	NTSTATUS samr_CHANGE_PASSWORD_USER();

	/************************/
	/* 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     */
	NTSTATUS samr_GET_DISPLAY_ENUMERATION_INDEX();

	/************************/
	/* Function    0x2a     */
	NTSTATUS samr_TEST_PRIVATE_FUNCTIONS_DOMAIN();

	/************************/
	/* Function    0x2b     */
	NTSTATUS samr_TEST_PRIVATE_FUNCTIONS_USER();


	/************************/
	/* 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_REMOVE_MEMBER_FROM_FOREIGN_DOMAIN();

	/************************/
	/* Function    0x2e     */
	NTSTATUS samr_QUERY_INFORMATION_DOMAIN2();

	/************************/
	/* Function    0x2f     */
	NTSTATUS samr_QUERY_INFORMATION_USER2();

	/************************/
	/* Function    0x30     */
	NTSTATUS samr_QUERY_DISPINFO2();

	/************************/
	/* Function    0x31     */
	NTSTATUS samr_GET_DISPLAY_ENUMERATION_INDEX2();

	/************************/
	/* 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();

}