samrpc.ndl revision eef90b8611c0908d0d8deb269e914563046e39dd
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright 2015 Nexenta Systems, Inc. All rights reserved.
*/
#ifndef _MLSVC_SAM_NDL_
#define _MLSVC_SAM_NDL_
/*
* Security Accounts Manager RPC (SAMR) interface definition.
*/
#include "ndrtypes.ndl"
/* Windows NT */
#define SAMR_OPNUM_Connect 0x00 /* SamrConnect */
#define SAMR_OPNUM_CloseHandle 0x01
#define SAMR_OPNUM_SetSecObject 0x02
#define SAMR_OPNUM_QuerySecObject 0x03
#define SAMR_OPNUM_ShutdownSamServer 0x04 /* NotUsedOnWire */
#define SAMR_OPNUM_LookupDomain 0x05
#define SAMR_OPNUM_EnumLocalDomains 0x06
#define SAMR_OPNUM_OpenDomain 0x07
#define SAMR_OPNUM_QueryDomainInfo 0x08
#define SAMR_OPNUM_SetDomainInfo 0x09
#define SAMR_OPNUM_CreateDomainGroup 0x0a
#define SAMR_OPNUM_QueryDomainGroups 0x0b
#define SAMR_OPNUM_CreateDomainUser 0x0c
#define SAMR_OPNUM_EnumDomainUsers 0x0d
#define SAMR_OPNUM_CreateDomainAlias 0x0e
#define SAMR_OPNUM_EnumDomainAliases 0x0f
#define SAMR_OPNUM_LookupIds 0x10 /* GetAliasMembership */
#define SAMR_OPNUM_LookupNames 0x11
#define SAMR_OPNUM_LookupDomainIds 0x12
#define SAMR_OPNUM_OpenGroup 0x13
#define SAMR_OPNUM_QueryGroupInfo 0x14
#define SAMR_OPNUM_StoreGroupInfo 0x15
#define SAMR_OPNUM_AddGroupMember 0x16
#define SAMR_OPNUM_DeleteDomainGroup 0x17
#define SAMR_OPNUM_DeleteGroupMember 0x18
#define SAMR_OPNUM_ListGroupMembers 0x19
#define SAMR_OPNUM_SetGroupMemberAttributes 0x1a
#define SAMR_OPNUM_OpenAlias 0x1b
#define SAMR_OPNUM_QueryAliasInfo 0x1c
#define SAMR_OPNUM_SetAliasInfo 0x1d
#define SAMR_OPNUM_DeleteDomainAlias 0x1e
#define SAMR_OPNUM_AddAliasMember 0x1f
#define SAMR_OPNUM_DeleteAliasMember 0x20
#define SAMR_OPNUM_ListAliasMembers 0x21
#define SAMR_OPNUM_OpenUser 0x22
#define SAMR_OPNUM_DeleteUser 0x23
#define SAMR_OPNUM_QueryUserInfo 0x24
#define SAMR_OPNUM_SetUserInfo0 0x25 /* SetUserInfo */
#define SAMR_OPNUM_ChangeUserPassword0 0x26 /* ChangeUserPassword */
#define SAMR_OPNUM_QueryUserGroups 0x27
#define SAMR_OPNUM_QueryDispInfo 0x28 /* QueryDispInfo1 */
#define SAMR_OPNUM_GetDisplayEnumIndex 0x29
#define SAMR_OPNUM_TestPrivateDomainFunctions 0x2a /* NotUsedOnWire */
#define SAMR_OPNUM_TestPrivateUserFunctions 0x2b /* NotUsedOnWire */
#define SAMR_OPNUM_GetUserPwInfo 0x2c
/* Windows 2000 */
#define SAMR_OPNUM_RemoveMemberFromForeignDomain 0x2d
#define SAMR_OPNUM_QueryInfoDomain2 0x2e
#define SAMR_OPNUM_QueryInfoUser2 0x2f
#define SAMR_OPNUM_EnumDomainGroups 0x30 /* QueryDispInfo2 */
#define SAMR_OPNUM_GetDisplayEnumIndex2 0x31
#define SAMR_OPNUM_CreateUser 0x32
#define SAMR_OPNUM_QueryDispInfo4 0x33
#define SAMR_OPNUM_AddMultipleAliasMembers 0x34
#define SAMR_OPNUM_RemoveMultipleAliasMembers 0x35
#define SAMR_OPNUM_ChangeUserOemPassword 0x36
#define SAMR_OPNUM_ChangePasswordUser2 0x37 /* UnicodePasswd */
#define SAMR_OPNUM_GetDomainPwInfo 0x38
#define SAMR_OPNUM_Connect2 0x39 /* SamrConnect2 */
#define SAMR_OPNUM_SetUserInfo 0x3a /* SetInfoUser2 */
#define SAMR_OPNUM_SetBootKeyInformation 0x3b
#define SAMR_OPNUM_GetBootKeyInformation 0x3c
#define SAMR_OPNUM_Connect3 0x3d /* NotUsedOnWire */
#define SAMR_OPNUM_Connect4 0x3e /* SamrConnect4 */
#define SAMR_OPNUM_ChangeUserUnicodePassword3 0x3f
/* Windows XP and Windows Server 2003 */
#define SAMR_OPNUM_Connect5 0x40 /* SamrConnect5 */
#define SAMR_OPNUM_RidToSid 0x41
#define SAMR_OPNUM_SetDSRMPassword 0x42
#define SAMR_OPNUM_ValidatePassword 0x43
/* Windows Vista */
#define SAMR_OPNUM_QueryLocalizableAccountsInDomain 0x44
#define SAMR_OPNUM_PerformGenericOperation 0x45
/*
* Sam account flags used when creating an account. These flags seem
* to be very similar to the USER_INFO_X flags (UF_XXX) in lmaccess.h
* but the values are different.
*/
#define SAMR_AF_ACCOUNTDISABLE 0x0001
#define SAMR_AF_HOMEDIR_REQUIRED 0x0002
#define SAMR_AF_PASSWD_NOTREQD 0x0004
#define SAMR_AF_TEMP_DUPLICATE_ACCOUNT 0x0008
#define SAMR_AF_NORMAL_ACCOUNT 0x0010
#define SAMR_AF_MNS_LOGON_ACCOUNT 0x0020
#define SAMR_AF_INTERDOMAIN_TRUST_ACCOUNT 0x0040
#define SAMR_AF_WORKSTATION_TRUST_ACCOUNT 0x0080
#define SAMR_AF_SERVER_TRUST_ACCOUNT 0x0100
#define SAMR_AF_DONT_EXPIRE_PASSWD 0x0200
#define SAMR_AF_ACCOUNT_AUTOLOCK 0x0400
#define SAMR_AF_MACHINE_ACCOUNT_MASK ( \
SAMR_AF_INTERDOMAIN_TRUST_ACCOUNT \
| SAMR_AF_WORKSTATION_TRUST_ACCOUNT \
| SAMR_AF_SERVER_TRUST_ACCOUNT)
#define SAMR_AF_ACCOUNT_TYPE_MASK ( \
SAMR_AF_TEMP_DUPLICATE_ACCOUNT \
| SAMR_AF_NORMAL_ACCOUNT \
| SAMR_AF_INTERDOMAIN_TRUST_ACCOUNT \
| SAMR_AF_WORKSTATION_TRUST_ACCOUNT \
| SAMR_AF_SERVER_TRUST_ACCOUNT)
/*
* QueryUserInfo UserAllInformation WhichFields
*/
#define SAMR_USER_ALL_USERNAME 0x00000001
#define SAMR_USER_ALL_FULLNAME 0x00000002
#define SAMR_USER_ALL_USERID 0x00000004
#define SAMR_USER_ALL_PRIMARYGROUPID 0x00000008
#define SAMR_USER_ALL_ADMINCOMMENT 0x00000010
#define SAMR_USER_ALL_USERCOMMENT 0x00000020
#define SAMR_USER_ALL_HOMEDIRECTORY 0x00000040
#define SAMR_USER_ALL_HOMEDIRECTORYDRIVE 0x00000080
#define SAMR_USER_ALL_SCRIPTPATH 0x00000100
#define SAMR_USER_ALL_PROFILEPATH 0x00000200
#define SAMR_USER_ALL_WORKSTATIONS 0x00000400
#define SAMR_USER_ALL_LASTLOGON 0x00000800
#define SAMR_USER_ALL_LASTLOGOFF 0x00001000
#define SAMR_USER_ALL_LOGONHOURS 0x00002000
#define SAMR_USER_ALL_BADPASSWORDCOUNT 0x00004000
#define SAMR_USER_ALL_LOGONCOUNT 0x00008000
#define SAMR_USER_ALL_PASSWORDCANCHANGE 0x00010000
#define SAMR_USER_ALL_PASSWORDMUSTCHANGE 0x00020000
#define SAMR_USER_ALL_PASSWORDLASTSET 0x00040000
#define SAMR_USER_ALL_ACCOUNTEXPIRES 0x00080000
#define SAMR_USER_ALL_USERACCOUNTCONTROL 0x00100000
#define SAMR_USER_ALL_PARAMETERS 0x00200000
#define SAMR_USER_ALL_COUNTRYCODE 0x00400000
#define SAMR_USER_ALL_CODEPAGE 0x00800000
#define SAMR_USER_ALL_NTPASSWORDPRESENT 0x01000000
#define SAMR_USER_ALL_LMPASSWORDPRESENT 0x02000000
#define SAMR_USER_ALL_PRIVATEDATA 0x04000000
#define SAMR_USER_ALL_PASSWORDEXPIRED 0x08000000
#define SAMR_USER_ALL_SECURITYDESCRIPTOR 0x10000000
#define SAMR_USER_ALL_OWF_PASSWORD 0x20000000
#define SAMR_USER_ALL_UNDEFINED_MASK 0xC0000000
/*
* Alias Access Mask values for SAMR
* Section 2.2.1.6 of MS-SAMR
*/
#define SAMR_ALIAS_ACCESS_EXECUTE 0x00020008
#define SAMR_ALIAS_ACCESS_WRITE 0x00020013
#define SAMR_ALIAS_ACCESS_READ 0x00020004
#define SAMR_ALIAS_ACCESS_ALL_ACCESS 0x000F001F
#define SAMR_ALIAS_ACCESS_WRITE_ACCOUNT 0x00000010
#define SAMR_ALIAS_ACCESS_READ_INFO 0x00000008
#define SAMR_ALIAS_ACCESS_LIST_MEMBERS 0x00000004
#define SAMR_ALIAS_ACCESS_REMOVE_MEMBER 0x00000002
#define SAMR_ALIAS_ACCESS_ADD_MEMBER 0x00000001
#define SAMR_REVISION_1 1 /* Pre Windows 2000 */
#define SAMR_REVISION_2 2 /* Windows 2000 */
#define SAMR_REVISION_3 3 /* Post Windows 2000 */
/*
* Definition for a SID. The ndl compiler does not allow a typedef of
* a structure containing variable size members.
* Note: cast compatible with smb_sid_t, and code depends on that.
*/
struct samr_sid {
BYTE Revision;
BYTE SubAuthCount;
BYTE Authority[6];
SIZE_IS(SubAuthCount)
DWORD SubAuthority[ANY_SIZE_ARRAY];
};
/*
* SAMR definition of a security_descriptor.
*/
struct samr_sec_desc {
BYTE Revision;
BYTE Sbz1;
WORD Control;
struct samr_sid *owner;
struct samr_sid *group;
struct samr_sid *sacl;
struct samr_sid *dacl;
};
struct samr_sd {
DWORD length;
SIZE_IS(length)
BYTE *data;
};
typedef struct samr_sd samr_sd_t;
/*
* See RPC_STRING in the MS IDL.
* Definition for a string. The length and allosize should be set to
* twice the string length (i.e. strlen(str) * 2). The runtime code
* will perform the appropriate string to a wide-char conversions,
* so str should point to a regular char * string.
*/
struct samr_string {
WORD length;
WORD allosize;
LPTSTR str;
};
typedef struct samr_string samr_string_t;
/*
* Alternative varying/conformant string definition - for
* non-null terminated strings. This definition must match
* ndr_vcbuf_t.
*/
struct samr_vcb {
/*
* size_is (actually a copy of length_is) will
* be inserted here by the marshalling library.
*/
DWORD vc_first_is;
DWORD vc_length_is;
SIZE_IS(vc_length_is)
WORD buffer[ANY_SIZE_ARRAY];
};
struct samr_vcbuf {
WORD wclen;
WORD wcsize;
struct samr_vcb *vcb;
};
typedef struct samr_vcbuf samr_vcbuf_t;
CONTEXT_HANDLE(samr_handle) samr_handle_t;
/*
* OLD_LARGE_INTEGER: a 64-bit value.
*/
struct samr_quad {
DWORD low;
DWORD high;
};
typedef struct samr_quad samr_quad_t;
/*
* Blob used for the NT and LM OWF passwords.
* The length and maxlen should be 16.
*/
struct samr_short_blob {
WORD length;
WORD maxlen;
SIZE_IS(length / 2)
WORD *buf;
};
#define DOMAIN_PASSWORD_COMPLEX 0x00000001
#define DOMAIN_PASSWORD_NO_ANON_CHANGE 0x00000002
#define DOMAIN_PASSWORD_NO_CLEAR_CHANGE 0x00000004
#define DOMAIN_LOCKOUT_ADMINS 0x00000008
#define DOMAIN_PASSWORD_STORE_CLEARTEXT 0x00000010
#define DOMAIN_REFUSE_PASSWORD_CHANGE 0x00000020
struct samr_password_info {
WORD min_length;
DWORD properties;
};
typedef struct samr_password_info samr_password_info_t;
/*
* There is some sort of logon bitmap structure in here, which I
* think is a varying and conformant array, i.e.
*
* struct samr_logon_hours {
* DWORD size_is; (1260)
* DWORD first_is; (zero)
* DWORD length_is; (168)
* BYTE bitmap[21];
* };
*
* struct samr_logon_info {
* DWORD length;
* SIZE_IS(length / 8)
* struct samr_logon_hours *hours;
* };
*
* There are 10080 minutes/week => 10080/8 = 1260 (0x04EC).
* So size_is is set as some sort of maximum.
*
* There are 168 hours/week => 168/8 = 21 (0xA8). Since there are 21
* bytes (all set to 0xFF), this is is probably the default setting.
*/
#define SAMR_MINS_PER_WEEK 10080
#define SAMR_HOURS_PER_WEEK 168
#define SAMR_HOURS_MAX_SIZE (SAMR_MINS_PER_WEEK / 8)
#define SAMR_HOURS_SET_LEN(LEN) ((LEN) / 8)
#define SAMR_SET_USER_HOURS_SZ 21
struct samr_logon_hours {
DWORD size;
DWORD first;
DWORD length;
BYTE bitmap[SAMR_SET_USER_HOURS_SZ];
};
struct samr_logon_info {
DWORD units;
DWORD hours;
};
struct samr_logon_hours_all {
WORD units_per_week;
SIZE_IS(units_per_week / 8)
BYTE *hours;
};
/*
* SAMPR_USER_PASSWORD (in the MS Net API) or
* struct samr_user_password (internal use) is
* the "clear" form of struct samr_encr_passwd
* (SAMPR_ENCRYPTED_USER_PASSWORD in MS Net).
* It's not used by ndrgen, but is declared here
* to help clarify the relationship between these,
* and for the benefit of our client-side code.
*/
#ifndef NDRGEN
#define SAMR_USER_PWLEN 256
struct samr_user_password {
smb_wchar_t Buffer[SAMR_USER_PWLEN];
DWORD Length;
};
#endif /* NDRGEN */
/* SAMPR_ENCRYPTED_USER_PASSWORD */
#define SAMR_ENCR_PWLEN 516 /* sizeof samr_user_password */
struct samr_encr_passwd {
BYTE data[SAMR_ENCR_PWLEN];
};
/* ENCRYPTED_NT_OWF_PASSWORD */
#define SAMR_PWHASH_LEN 16
struct samr_encr_hash {
BYTE data[SAMR_PWHASH_LEN];
};
/*
***********************************************************************
* SamrConnect.
***********************************************************************
*/
OPERATION(SAMR_OPNUM_Connect)
struct samr_Connect {
IN DWORD *servername;
IN DWORD access_mask;
OUT samr_handle_t handle;
OUT DWORD status;
};
/*
***********************************************************************
* SamrConnect2.
***********************************************************************
*/
OPERATION(SAMR_OPNUM_Connect2)
struct samr_Connect2 {
IN LPTSTR servername;
IN DWORD access_mask;
OUT samr_handle_t handle;
OUT DWORD status;
};
/*
***********************************************************************
* SamrConnect4. A new form of connect first seen with Windows 2000.
* A new field has been added to the input request. Value: 0x00000002.
***********************************************************************
*/
OPERATION(SAMR_OPNUM_Connect4)
struct samr_Connect4 {
IN LPTSTR servername;
IN DWORD revision;
IN DWORD access_mask;
OUT samr_handle_t handle;
OUT DWORD status;
};
/*
***********************************************************************
* SamrConnect5. A new form of connect first seen with Windows XP.
* The server name is the fully qualified domain name, i.e.
* \\server.sun.com.
*
* [in] DWORD InVersion,
* [in] [switch_is(InVersion)] samr_revision_info *InRevisionInfo
* [out] DWORD *OutVersion
* [out] [switch_is(*OutVersion)] *samr_revision_info *OutRevisionInfo
*
* SupportedFeatures (see notes in [MS-SAMR]
* 0x00000001 RID values returned from the server must not be
* concatenated with the domain SID.
* 0x00000002 Reserved
* 0x00000004 Reserved
***********************************************************************
*/
struct samr_revision_info1 {
DWORD revision;
DWORD supported_features;
};
typedef struct samr_revision_info1 samr_revision_info1_t;
union samr_revision_info {
UNION_INFO_ENT(1,samr_revision_info);
DEFAULT char *nullptr;
};
OPERATION(SAMR_OPNUM_Connect5)
struct samr_Connect5 {
IN LPTSTR servername;
IN DWORD access_mask;
/*
* This should be a union, but instead this is
* done this way because unions are hard to
* express in this RPC implementation.
*/
INOUT DWORD unknown2_00000001; /* V1 */
INOUT DWORD unknown3_00000001; /* V1 */
/* SAMPR_REVISION_INFO_V1 */
INOUT DWORD unknown4_00000003; /* Revision */
INOUT DWORD unknown5_00000000; /* SupportedFeatures */
OUT samr_handle_t handle;
OUT DWORD status;
};
/*
***********************************************************************
* CloseHandle closes an association with the SAM. Using the same
* structure as the LSA seems to work.
***********************************************************************
*/
OPERATION(SAMR_OPNUM_CloseHandle)
struct samr_CloseHandle {
IN samr_handle_t handle;
OUT samr_handle_t result_handle;
OUT DWORD status;
};
/*
***********************************************************************
* LookupDomain: lookup up the domain SID.
***********************************************************************
*/
OPERATION(SAMR_OPNUM_LookupDomain)
struct samr_LookupDomain {
IN samr_handle_t handle;
IN samr_string_t domain_name;
OUT struct samr_sid *sid;
OUT DWORD status;
};
/*
***********************************************************************
* EnumLocalDomain
*
* This looks like a request to get the local domains supported by a
* remote server. NT always seems to return 2 domains: the local
* domain (hostname) and the Builtin domain.
*
* The max_length field is set to 0x2000.
* Enum_context is set to 0 in the request and set to entries_read in
* the reply. Like most of these enums, total_entries is the same as
* entries_read.
***********************************************************************
*/
struct samr_LocalDomainEntry {
DWORD unknown;
samr_string_t name;
};
struct samr_LocalDomainInfo {
DWORD entries_read;
SIZE_IS(entries_read)
struct samr_LocalDomainEntry *entry;
};
OPERATION(SAMR_OPNUM_EnumLocalDomains)
struct samr_EnumLocalDomain {
IN samr_handle_t handle;
INOUT DWORD enum_context;
IN DWORD max_length;
OUT struct samr_LocalDomainInfo *info;
OUT DWORD total_entries;
OUT DWORD status;
};
/*
***********************************************************************
* OpenDomain
*
* Open a specific domain within the SAM. From this I assume that each
* SAM can handle multiple domains so you need to identify the one with
* which you want to work. Working with a domain handle does appear to
* offer the benefit that you can then use RIDs instead of full SIDs,
* which simplifies things a bit. The domain handle can be used to get
* user and group handles.
***********************************************************************
*/
OPERATION(SAMR_OPNUM_OpenDomain)
struct samr_OpenDomain {
IN samr_handle_t handle;
IN DWORD access_mask;
IN REFERENCE struct samr_sid *sid;
OUT samr_handle_t domain_handle;
OUT DWORD status;
};
/*
***********************************************************************
* QueryDomainInfo
*
* Windows 95 Server Manager sends requests for levels 6 and 7 when
* the services menu item is selected.
***********************************************************************
*/
#define SAMR_QUERY_DOMAIN_INFO_2 2
#define SAMR_QUERY_DOMAIN_INFO_6 6
#define SAMR_QUERY_DOMAIN_INFO_7 7
struct samr_QueryDomainInfo2 {
DWORD unknown1; /* 00 00 00 00 */
DWORD unknown2; /* 00 00 00 80 */
samr_string_t s1;
samr_string_t domain;
samr_string_t s2;
DWORD sequence_num; /* 2B 00 00 00 */
DWORD unknown3; /* 00 00 00 00 */
DWORD unknown4; /* 01 00 00 00 */
DWORD unknown5; /* 03 00 00 00 */
DWORD unknown6; /* 01 */
DWORD num_users;
DWORD num_groups;
DWORD num_aliases;
};
struct samr_QueryDomainInfo6 {
DWORD unknown1; /* 00 00 00 00 */
DWORD unknown2; /* B0 7F 14 00 */
DWORD unknown3; /* 00 00 00 00 */
DWORD unknown4; /* 00 00 00 00 */
DWORD unknown5; /* 00 00 00 00 */
};
struct samr_QueryDomainInfo7 {
DWORD unknown1; /* 03 00 00 00 */
};
union samr_QueryDomainInfo_ru {
UNION_INFO_ENT(2,samr_QueryDomainInfo);
UNION_INFO_ENT(6,samr_QueryDomainInfo);
UNION_INFO_ENT(7,samr_QueryDomainInfo);
DEFAULT char *nullptr;
};
struct samr_QueryDomainInfoRes {
WORD switch_value;
SWITCH(switch_value)
union samr_QueryDomainInfo_ru ru;
};
OPERATION(SAMR_OPNUM_QueryDomainInfo)
struct samr_QueryDomainInfo {
IN samr_handle_t domain_handle;
IN WORD info_level;
OUT struct samr_QueryDomainInfoRes *info;
OUT DWORD status;
};
/*
* Identical to SAMR_OPNUM_QueryDomainInfo.
*/
OPERATION(SAMR_OPNUM_QueryInfoDomain2)
struct samr_QueryInfoDomain2 {
IN samr_handle_t domain_handle;
IN WORD info_level;
OUT struct samr_QueryDomainInfoRes *info;
OUT DWORD status;
};
#define SAMR_QUERY_ALIAS_INFO_GENERAL 1
#define SAMR_QUERY_ALIAS_INFO_NAME 2
#define SAMR_QUERY_ALIAS_INFO_COMMENT 3
struct samr_QueryAliasInfoGeneral {
WORD level;
samr_string_t name;
DWORD member_count;
samr_string_t desc;
};
struct samr_QueryAliasInfoName {
WORD level;
samr_string_t name;
};
struct samr_QueryAliasInfoComment {
WORD level;
samr_string_t desc;
};
union samr_QueryAliasInfo_ru {
CASE(1) struct samr_QueryAliasInfoGeneral info1;
CASE(2) struct samr_QueryAliasInfoName info2;
CASE(3) struct samr_QueryAliasInfoComment info3;
DEFAULT char *nullptr;
};
struct samr_QueryAliasInfoRes {
DWORD address;
WORD switch_value;
SWITCH(switch_value)
union samr_QueryAliasInfo_ru ru;
};
OPERATION(SAMR_OPNUM_QueryAliasInfo)
struct samr_QueryAliasInfo {
IN samr_handle_t alias_handle;
IN WORD level;
OUT DWORD address;
SWITCH (level)
OUT union samr_QueryAliasInfo_ru ru;
OUT DWORD status;
};
OPERATION(SAMR_OPNUM_CreateDomainAlias)
struct samr_CreateDomainAlias {
IN samr_handle_t domain_handle;
IN samr_string_t alias_name;
IN DWORD access_mask;
OUT samr_handle_t alias_handle;
OUT DWORD rid;
OUT DWORD status;
};
OPERATION(SAMR_OPNUM_SetAliasInfo)
struct samr_SetAliasInfo {
IN samr_handle_t alias_handle;
IN WORD level;
/* TBD */
OUT DWORD status;
};
OPERATION(SAMR_OPNUM_DeleteDomainAlias)
struct samr_DeleteDomainAlias {
INOUT samr_handle_t alias_handle;
OUT DWORD status;
};
OPERATION(SAMR_OPNUM_OpenAlias)
struct samr_OpenAlias {
IN samr_handle_t domain_handle;
IN DWORD access_mask;
IN DWORD rid;
OUT samr_handle_t alias_handle;
OUT DWORD status;
};
struct name_rid {
DWORD rid;
samr_string_t name;
};
struct aliases_info {
DWORD count;
DWORD address;
SIZE_IS(count)
struct name_rid info[ANY_SIZE_ARRAY];
};
OPERATION(SAMR_OPNUM_EnumDomainAliases)
struct samr_EnumDomainAliases {
IN samr_handle_t domain_handle;
IN DWORD resume_handle;
IN DWORD mask;
OUT DWORD out_resume;
OUT struct aliases_info *aliases;
OUT DWORD entries;
OUT DWORD status;
};
struct user_acct_info {
DWORD index;
DWORD rid;
DWORD ctrl;
samr_string_t name;
samr_string_t fullname;
samr_string_t desc;
};
struct user_disp_info {
OUT DWORD total_size;
OUT DWORD returned_size;
OUT WORD switch_value;
DWORD count;
SIZE_IS(count)
struct user_acct_info *acct;
};
OPERATION(SAMR_OPNUM_QueryDispInfo)
struct samr_QueryDispInfo {
IN samr_handle_t domain_handle;
IN WORD level;
IN DWORD start_idx;
IN DWORD max_entries;
IN DWORD pref_maxsize;
OUT struct user_disp_info users;
OUT DWORD status;
};
struct group_acct_info {
DWORD index;
DWORD rid;
DWORD ctrl;
samr_string_t name;
samr_string_t desc;
};
struct group_disp_info {
DWORD count;
/* right now we just need one entry */
struct group_acct_info acct[1];
};
OPERATION(SAMR_OPNUM_EnumDomainGroups)
struct samr_EnumDomainGroups {
IN samr_handle_t domain_handle;
IN WORD level;
IN DWORD start_idx;
IN DWORD max_entries;
IN DWORD pref_maxsize;
OUT DWORD total_size;
OUT DWORD returned_size;
OUT WORD switch_value;
OUT DWORD count;
OUT struct group_disp_info *groups;
OUT DWORD status;
};
/*
***********************************************************************
* OpenUser
*
* Input must be a domain handle obtained via SAMR_OPNUM_OpenDomain,
* an access mask and the appropriate user rid. The output will be a
* handle for use with the specified user.
***********************************************************************
*/
OPERATION(SAMR_OPNUM_OpenUser)
struct samr_OpenUser {
IN samr_handle_t handle;
IN DWORD access_mask;
IN DWORD rid;
OUT samr_handle_t user_handle;
OUT DWORD status;
};
/*
***********************************************************************
* DeleteUser
***********************************************************************
*/
OPERATION(SAMR_OPNUM_DeleteUser)
struct samr_DeleteUser {
INOUT samr_handle_t user_handle;
OUT DWORD status;
};
/*
***********************************************************************
* QueryUserInfo
*
* Provides various pieces of information on a specific user (see
* SAM_Q_QUERY_USERINFO and SAM_R_QUERY_USERINFO). The handle must
* be a valid SAM user handle.
*
* QueryUserInfo (
* IN samr_handle_t user_handle,
* IN WORD switch_value,
* OUT union switch(switch_value) {
* case 1: struct QueryUserInfo1 *info1;
* } bufptr,
* OUT DWORD status
* )
*
* typedef enum _USER_INFORMATION_CLASS {
* UserGeneralInformation = 1,
* UserPreferencesInformation = 2,
* UserLogonInformation = 3,
* UserLogonHoursInformation = 4,
* UserAccountInformation = 5,
* UserNameInformation = 6,
* UserAccountNameInformation = 7,
* UserFullNameInformation = 8,
* UserPrimaryGroupInformation = 9,
* UserHomeInformation = 10,
* UserScriptInformation = 11,
* UserProfileInformation = 12,
* UserAdminCommentInformation = 13,
* UserWorkStationsInformation = 14,
* UserControlInformation = 16,
* UserExpiresInformation = 17,
* UserInternal1Information = 18,
* UserParametersInformation = 20,
* UserAllInformation = 21,
* UserInternal4Information = 23,
* UserInternal5Information = 24,
* UserInternal4InformationNew = 25,
* UserInternal5InformationNew = 26,
* } USER_INFORMATION_CLASS;
*
* 1 = username, fullname, description and some other stuff.
* 3 = large structure containing user rid, group rid, username
* and fullname.
* 5 = large structure (like 3) containing user rid, group rid,
* username, fullname and description.
* 6 = username and fullname
* 7 = username
* 8 = fullname
* 9 = group rid
* 16 = used after creating a new account
*
* Due to an ndrgen bug, a function must be provided to to patch the
* offsets used by the unmarshalling code at runtime. In order to
* simplify things it is useful to use a naming convention that
* indicates the switch value for each structure.
*
***********************************************************************
*/
#define SAMR_QUERY_USER_INFO_1 1
#define SAMR_QUERY_USER_UNAME_AND_FNAME 6
#define SAMR_QUERY_USER_USERNAME 7
#define SAMR_QUERY_USER_FULLNAME 8
#define SAMR_QUERY_USER_GROUPRID 9
#define SAMR_QUERY_USER_CONTROL_INFO 16
#define SAMR_QUERY_USER_ALL_INFO 21
struct samr_QueryUserInfo1 {
samr_string_t username;
samr_string_t fullname;
DWORD group_rid;
samr_string_t description;
samr_string_t unknown;
};
struct samr_QueryUserInfo6 {
samr_string_t username;
samr_string_t fullname;
};
struct samr_QueryUserInfo7 {
samr_string_t username;
};
struct samr_QueryUserInfo8 {
samr_string_t fullname;
};
struct samr_QueryUserInfo9 {
DWORD group_rid;
};
struct samr_QueryUserInfo16 {
DWORD UserAccountControl;
};
/*
* SAMR_USER_ALL_INFORMATION
*/
struct samr_QueryUserInfo21 {
samr_quad_t LastLogon;
samr_quad_t LastLogoff;
samr_quad_t PasswordLastSet;
samr_quad_t AccountExpires;
samr_quad_t PasswordCanChange;
samr_quad_t PasswordMustChange;
samr_string_t UserName;
samr_string_t FullName;
samr_string_t HomeDirectory;
samr_string_t HomeDirectoryDrive;
samr_string_t ScriptPath;
samr_string_t ProfilePath;
samr_string_t AdminComment;
samr_string_t WorkStations;
samr_string_t UserComment;
samr_string_t Parameters;
struct samr_short_blob LmOwfPassword;
struct samr_short_blob NtOwfPassword;
samr_string_t PrivateData;
samr_sd_t SecurityDescriptor;
DWORD UserId;
DWORD PrimaryGroupId;
DWORD UserAccountControl;
DWORD WhichFields;
struct samr_logon_hours_all LogonHours;
WORD BadPasswordCount;
WORD LogonCount;
WORD CountryCode;
WORD CodePage;
BYTE LmPasswordPresent;
BYTE NtPasswordPresent;
BYTE PasswordExpired;
BYTE PrivateDataSensitive;
};
/* See also: fixup_samr_QueryUserInfo() */
union QueryUserInfo_result_u {
UNION_INFO_ENT(1,samr_QueryUserInfo);
UNION_INFO_ENT(6,samr_QueryUserInfo);
UNION_INFO_ENT(7,samr_QueryUserInfo);
UNION_INFO_ENT(8,samr_QueryUserInfo);
UNION_INFO_ENT(9,samr_QueryUserInfo);
UNION_INFO_ENT(16,samr_QueryUserInfo);
UNION_INFO_ENT(21,samr_QueryUserInfo);
DEFAULT char *nullptr;
};
/*
* This structure needs to be declared, even though it can't be used in
* samr_QueryUserInfo, in order to get the appropriate size to calculate
* the correct fixup offsets. If ndrgen did the right thing,
* QueryUserInfo_result would be one of the out parameters. However, if
* we do it that way, the switch_value isn't known early enough to do
* the fixup calculation. So it all has to go in samr_QueryUserInfo.
*/
struct QueryUserInfo_result {
DWORD address;
WORD switch_value;
SWITCH(switch_value)
union QueryUserInfo_result_u ru;
};
OPERATION(SAMR_OPNUM_QueryUserInfo)
struct samr_QueryUserInfo {
IN samr_handle_t user_handle;
IN WORD switch_value;
/*
* Can't use this form because we need to include members explicitly.
* OUT struct QueryUserInfo_result result;
*/
OUT DWORD address;
OUT WORD switch_index;
SWITCH(switch_value)
OUT union QueryUserInfo_result_u ru;
OUT DWORD status;
};
/*
***********************************************************************
* QueryUserGroups
***********************************************************************
*/
struct samr_UserGroups {
DWORD rid;
DWORD attr;
};
struct samr_UserGroupInfo {
DWORD n_entry;
SIZE_IS(n_entry)
struct samr_UserGroups *groups;
};
OPERATION(SAMR_OPNUM_QueryUserGroups)
struct samr_QueryUserGroups {
IN samr_handle_t user_handle;
OUT struct samr_UserGroupInfo *info;
OUT DWORD status;
};
/*
***********************************************************************
* LookupName
***********************************************************************
*/
struct samr_LookupNameTable {
DWORD n_entry;
SIZE_IS(n_entry)
samr_string_t names[ANY_SIZE_ARRAY];
};
struct samr_LookupRidTable {
DWORD n_entry;
SIZE_IS(n_entry)
DWORD *rid;
};
struct samr_RidType {
DWORD n_entry;
SIZE_IS(n_entry)
DWORD *rid_type;
};
OPERATION(SAMR_OPNUM_LookupNames)
struct samr_LookupNames {
IN samr_handle_t handle;
IN DWORD n_entry;
IN DWORD max_n_entry;
IN DWORD index;
IN DWORD total;
IN samr_string_t name;
OUT struct samr_LookupRidTable rids;
OUT struct samr_RidType rid_types;
OUT DWORD status;
};
/*
***********************************************************************
* OpenGroup
*
* Input must be a domain handle obtained via SAMR_OPNUM_OpenDomain,
* an access mask and the appropriate group rid. The output will be a
* handle for use with the specified group.
***********************************************************************
*/
OPERATION(SAMR_OPNUM_OpenGroup)
struct samr_OpenGroup {
IN samr_handle_t handle;
IN DWORD access_mask;
IN DWORD rid;
OUT samr_handle_t group_handle;
OUT DWORD status;
};
/*
***********************************************************************
* QueryGroupInfo
*
* Input must be a group handle obtained via SAMR_OPNUM_OpenGroup,
* an access mask and the appropriate group rid. The output will
* be a handle for use with the specified group.
***********************************************************************
*/
struct samr_QueryGroupInfo1 {
samr_string_t groupname;
};
union samr_QueryGroupInfo_result_u {
UNION_INFO_ENT(1,samr_QueryGroupInfo);
DEFAULT char *nullptr;
};
struct samr_QueryGroupInfo_result {
DWORD address;
WORD switch_index;
SWITCH(switch_index)
union samr_QueryGroupInfo_result_u ru;
};
OPERATION(SAMR_OPNUM_QueryGroupInfo)
struct samr_QueryGroupInfo {
IN samr_handle_t group_handle;
IN DWORD switch_value;
OUT DWORD address;
OUT WORD switch_index;
SWITCH(switch_index)
OUT union samr_QueryGroupInfo_result_u ru;
OUT DWORD status;
};
/*
***********************************************************************
* StoreGroupInfo
*
* This definition is mostly just a place holder in case this is useful
* in the future. Note that it may not be correct. The information is
* from a netmon trace captured when I added a group description. I
* haven't implemented it because we don't have to update anything on
* the PDC. The description should almost certainly be in a separate
* structure.
***********************************************************************
*/
OPERATION(SAMR_OPNUM_StoreGroupInfo)
struct samr_StoreGroupInfo {
IN samr_handle_t group_handle;
IN DWORD switch_value;
IN samr_string_t group_description;
OUT DWORD status;
};
/*
* AddAliasMember
*/
OPERATION(SAMR_OPNUM_AddAliasMember)
struct samr_AddAliasMember {
IN samr_handle_t alias_handle;
IN REFERENCE struct samr_sid *sid;
OUT DWORD status;
};
/*
* DeleteAliasMember
*/
OPERATION(SAMR_OPNUM_DeleteAliasMember)
struct samr_DeleteAliasMember {
IN samr_handle_t alias_handle;
IN REFERENCE struct samr_sid *sid;
OUT DWORD status;
};
struct samr_SidList {
struct samr_sid *sid;
};
struct samr_SidInfo {
DWORD n_entry;
SIZE_IS(n_entry)
struct samr_SidList *sidlist;
};
/*
* ListAliasMembers
*/
OPERATION(SAMR_OPNUM_ListAliasMembers)
struct samr_ListAliasMembers {
IN samr_handle_t alias_handle;
OUT struct samr_SidInfo info;
OUT DWORD status;
};
/*
***********************************************************************
* GetUserDomainPasswordInformation
***********************************************************************
*/
OPERATION(SAMR_OPNUM_GetUserPwInfo)
struct samr_GetUserPwInfo {
IN samr_handle_t user_handle;
OUT REFERENCE samr_password_info_t *pwinfo;
OUT DWORD status;
};
/*
***********************************************************************
* CreateUser
*
* Create a user in the domain specified by the domain handle. The
* domain handle is obtained obtained via SAMR_OPNUM_OpenDomain.
* DesiredAccess: 0xe00500b0.
* The output will be a handle for use with the specified user and the
* user's RID. I think the RID may be a unique pointer (it can be null).
***********************************************************************
*/
OPERATION(SAMR_OPNUM_CreateUser)
struct samr_CreateUser {
IN samr_handle_t handle;
IN samr_vcbuf_t username;
IN DWORD account_flags;
IN DWORD desired_access;
OUT samr_handle_t user_handle;
OUT DWORD maybe_ptr;
OUT DWORD rid;
OUT DWORD status;
};
/*
***********************************************************************
* ChangePasswordUser2 - See:
* SamrUnicodeChangePasswordUser2 [MS-SAMR 3.1.5.10.3]
***********************************************************************
*/
OPERATION(SAMR_OPNUM_ChangePasswordUser2)
struct samr_ChangePasswordUser2 {
IN samr_string_t *servername;
IN REF samr_string_t *username;
IN struct samr_encr_passwd *nt_newpw;
IN struct samr_encr_hash *nt_oldpw;
IN BYTE lm_present;
IN struct samr_encr_passwd *lm_newpw;
IN struct samr_encr_hash *lm_oldpw;
OUT DWORD status;
};
/*
***********************************************************************
* GetDomainPwInfo
***********************************************************************
*/
OPERATION(SAMR_OPNUM_GetDomainPwInfo)
struct samr_GetDomainPwInfo {
IN DWORD unused;
OUT REFERENCE samr_password_info_t *pwinfo;
OUT DWORD status;
};
/*
***********************************************************************
* SetUserInfo
* [MS-SAMR] SamrSetInformationUser2
***********************************************************************
*/
/* USER_CONTROL_INFORMATION */
struct samr_SetUserInfo16 {
DWORD UserAccountControl;
};
/*
* samr_SetUserInfo21, a.k.a
* SAMR_USER_ALL_INFORMATION
*
* We now know this is the same as samr_QueryUserInfo21
* Could merge, except for the samr_vcbuf_t mess.
*/
#define SAMR_SET_USER_INFO_21 21
struct samr_SetUserInfo21 {
samr_quad_t LastLogon;
samr_quad_t LastLogoff;
samr_quad_t PasswordLastSet;
samr_quad_t AccountExpires;
samr_quad_t PasswordCanChange;
samr_quad_t PasswordMustChange;
samr_vcbuf_t UserName;
samr_vcbuf_t FullName;
samr_vcbuf_t HomeDirectory;
samr_vcbuf_t HomeDirectoryDrive;
samr_vcbuf_t ScriptPath;
samr_vcbuf_t ProfilePath;
samr_vcbuf_t AdminComment;
samr_vcbuf_t WorkStations;
samr_vcbuf_t UserComment;
samr_vcbuf_t Parameters;
struct samr_short_blob LmOwfPassword;
struct samr_short_blob NtOwfPassword;
samr_vcbuf_t PrivateData;
samr_sd_t SecurityDescriptor;
DWORD UserId; /* RID */
DWORD PrimaryGroupId;
DWORD UserAccountControl;
DWORD WhichFields;
/*
* This should be samr_logon_hours_all, but apparently
* ndrgen doesn't get that quite right, so instead, the
* client-side code patches this up.
*/
struct samr_logon_info LogonHours;
WORD BadPasswordCount;
WORD LogonCount;
WORD CountryCode;
WORD CodePage;
BYTE LmPasswordPresent;
BYTE NtPasswordPresent;
BYTE PasswordExpired;
BYTE PrivateDataSensitive;
};
/*
* SAMPR_USER_INTERNAL4_INFORMATION
* UserInternal4Information (23)
*/
#define SAMR_SET_USER_INFO_23 23
struct samr_SetUserInfo23 {
struct samr_SetUserInfo21 info21;
struct samr_encr_passwd encr_pw;
};
/*
* SAMPR_USER_INTERNAL5_INFORMATION
* UserInternal5Information (24)
*/
#define SAMR_SET_USER_INFO_24 24
struct samr_SetUserInfo24 {
struct samr_encr_passwd encr_pw;
BYTE password_expired;
};
union samr_SetUserInfo_u {
UNION_INFO_ENT(16,samr_SetUserInfo);
UNION_INFO_ENT(21,samr_SetUserInfo);
UNION_INFO_ENT(23,samr_SetUserInfo);
UNION_INFO_ENT(24,samr_SetUserInfo);
DEFAULT DWORD nothing;
};
struct samr_SetUserInfo_s {
WORD info_level;
WORD switch_value;
SWITCH(switch_value)
union samr_SetUserInfo_u ru;
};
OPERATION(SAMR_OPNUM_SetUserInfo)
struct samr_SetUserInfo {
IN samr_handle_t user_handle;
IN struct samr_SetUserInfo_s info;
OUT DWORD status;
};
/*
***********************************************************************
* The SAMR interface definition.
***********************************************************************
*/
INTERFACE(0)
union samr_interface {
CASE(SAMR_OPNUM_Connect)
struct samr_Connect Connect;
CASE(SAMR_OPNUM_CloseHandle)
struct samr_CloseHandle CloseHandle;
CASE(SAMR_OPNUM_LookupDomain)
struct samr_LookupDomain LookupDomain;
CASE(SAMR_OPNUM_EnumLocalDomains)
struct samr_EnumLocalDomain EnumLocalDomain;
CASE(SAMR_OPNUM_OpenDomain)
struct samr_OpenDomain OpenDomain;
CASE(SAMR_OPNUM_QueryDomainInfo)
struct samr_QueryDomainInfo QueryDomainInfo;
CASE(SAMR_OPNUM_QueryInfoDomain2)
struct samr_QueryInfoDomain2 QueryInfoDomain2;
CASE(SAMR_OPNUM_LookupNames)
struct samr_LookupNames LookupNames;
CASE(SAMR_OPNUM_OpenUser)
struct samr_OpenUser OpenUser;
CASE(SAMR_OPNUM_DeleteUser)
struct samr_DeleteUser DeleteUser;
CASE(SAMR_OPNUM_QueryUserInfo)
struct samr_QueryUserInfo QueryUserInfo;
CASE(SAMR_OPNUM_QueryUserGroups)
struct samr_QueryUserGroups QueryUserGroups;
CASE(SAMR_OPNUM_OpenGroup)
struct samr_OpenGroup OpenGroup;
CASE(SAMR_OPNUM_AddAliasMember)
struct samr_AddAliasMember AddAliasMember;
CASE(SAMR_OPNUM_DeleteAliasMember)
struct samr_DeleteAliasMember DeleteAliasMember;
CASE(SAMR_OPNUM_ListAliasMembers)
struct samr_ListAliasMembers ListAliasMembers;
CASE(SAMR_OPNUM_GetUserPwInfo)
struct samr_GetUserPwInfo GetUserPwInfo;
CASE(SAMR_OPNUM_CreateUser)
struct samr_CreateUser CreateUser;
CASE(SAMR_OPNUM_ChangePasswordUser2)
struct samr_ChangePasswordUser2 ChangePasswordUser2;
CASE(SAMR_OPNUM_GetDomainPwInfo)
struct samr_GetDomainPwInfo GetDomainPwInfo;
CASE(SAMR_OPNUM_Connect2)
struct samr_Connect2 Connect2;
CASE(SAMR_OPNUM_SetUserInfo)
struct samr_SetUserInfo SetUserInfo;
CASE(SAMR_OPNUM_Connect4)
struct samr_Connect4 Connect4;
CASE(SAMR_OPNUM_Connect5)
struct samr_Connect5 Connect5;
CASE(SAMR_OPNUM_QueryDispInfo)
struct samr_QueryDispInfo QueryDispInfo;
CASE(SAMR_OPNUM_OpenAlias)
struct samr_OpenAlias OpenAlias;
CASE(SAMR_OPNUM_CreateDomainAlias)
struct samr_CreateDomainAlias CreateDomainAlias;
CASE(SAMR_OPNUM_SetAliasInfo)
struct samr_SetAliasInfo SetAliasInfo;
CASE(SAMR_OPNUM_QueryAliasInfo)
struct samr_QueryAliasInfo QueryAliasInfo;
CASE(SAMR_OPNUM_DeleteDomainAlias)
struct samr_DeleteDomainAlias DeleteDomainAlias;
CASE(SAMR_OPNUM_EnumDomainAliases)
struct samr_EnumDomainAliases EnumDomainAliases;
CASE(SAMR_OPNUM_EnumDomainGroups)
struct samr_EnumDomainGroups EnumDomainGroups;
};
typedef union samr_interface samr_interface_t;
EXTERNTYPEINFO(samr_interface)
#endif /* _MLSVC_SAM_NDL_ */