#include "idl_types.h" import "drsuapi.idl", "misc.idl", "samr.idl"; [ uuid("12345778-1234-abcd-0001-00000001"), version(0.0), pointer_default(unique), helpstring("Active Directory Replication LDAP Blobs") ] interface drsblobs { typedef bitmap drsuapi_DsReplicaSyncOptions drsuapi_DsReplicaSyncOptions; typedef bitmap drsuapi_DsReplicaNeighbourFlags drsuapi_DsReplicaNeighbourFlags; typedef [v1_enum] enum drsuapi_DsAttributeId drsuapi_DsAttributeId; /* * replPropertyMetaData * w2k uses version 1 * w2k3 uses version 1 */ typedef struct { drsuapi_DsAttributeId attid; uint32 version; NTTIME_1sec originating_change_time; GUID originating_invocation_id; hyper originating_usn; hyper local_usn; } replPropertyMetaData1; typedef struct { uint32 count; uint32 reserved; replPropertyMetaData1 array[count]; } replPropertyMetaDataCtr1; typedef [nodiscriminant] union { [case(1)] replPropertyMetaDataCtr1 ctr1; } replPropertyMetaDataCtr; typedef [public] struct { uint32 version; uint32 reserved; [switch_is(version)] replPropertyMetaDataCtr ctr; } replPropertyMetaDataBlob; void decode_replPropertyMetaData( [in] replPropertyMetaDataBlob blob ); /* * replUpToDateVector * w2k uses version 1 * w2k3 uses version 2 */ typedef struct { uint32 count; uint32 reserved; drsuapi_DsReplicaCursor cursors[count]; } replUpToDateVectorCtr1; typedef struct { uint32 count; uint32 reserved; drsuapi_DsReplicaCursor2 cursors[count]; } replUpToDateVectorCtr2; typedef [nodiscriminant] union { [case(1)] replUpToDateVectorCtr1 ctr1; [case(2)] replUpToDateVectorCtr2 ctr2; } replUpToDateVectorCtr; typedef [public] struct { uint32 version; uint32 reserved; [switch_is(version)] replUpToDateVectorCtr ctr; } replUpToDateVectorBlob; void decode_replUpToDateVector( [in] replUpToDateVectorBlob blob ); /* * repsFrom/repsTo * w2k uses version 1 * w2k3 uses version 1 */ typedef [public,gensize] struct { [value(strlen(dns_name)+1)] uint32 __dns_name_size; [charset(DOS)] uint8 dns_name[__dns_name_size]; } repsFromTo1OtherInfo; typedef [public,gensize,flag(NDR_PAHEX)] struct { /* this includes the 8 bytes of the repsFromToBlob header */ [value(ndr_size_repsFromTo1(this, ndr->flags)+8)] uint32 blobsize; uint32 consecutive_sync_failures; NTTIME_1sec last_success; NTTIME_1sec last_attempt; WERROR result_last_attempt; [relative] repsFromTo1OtherInfo *other_info; [value(ndr_size_repsFromTo1OtherInfo(other_info, ndr->flags))] uint32 other_info_length; drsuapi_DsReplicaNeighbourFlags replica_flags; uint8 schedule[84]; uint32 reserved; drsuapi_DsReplicaHighWaterMark highwatermark; GUID source_dsa_obj_guid; /* the 'objectGuid' field of the CN=NTDS Settings object */ GUID source_dsa_invocation_id; /* the 'invocationId' field of the CN=NTDS Settings object */ GUID transport_guid; } repsFromTo1; typedef [nodiscriminant] union { [case(1)] repsFromTo1 ctr1; } repsFromTo; typedef [public] struct { uint32 version; uint32 reserved; [switch_is(version)] repsFromTo ctr; } repsFromToBlob; void decode_repsFromTo( [in] repsFromToBlob blob ); /* * partialAttributeSet * w2k uses version 1 * w2k3 uses version 1 */ typedef struct { uint32 count; drsuapi_DsAttributeId array[count]; } partialAttributeSetCtr1; typedef [nodiscriminant] union { [case(1)] partialAttributeSetCtr1 ctr1; } partialAttributeSetCtr; typedef [public] struct { uint32 version; uint32 reserved; [switch_is(version)] partialAttributeSetCtr ctr; } partialAttributeSetBlob; void decode_partialAttributeSet( [in] partialAttributeSetBlob blob ); /* * prefixMap * w2k unknown * w2k3 unknown * samba4 uses 0x44534442 'DSDB' * * as we windows don't return the prefixMap attribute when you ask for * we don't know the format, but the attribute is not replicated * so that we can choose our own format... */ typedef [v1_enum] enum { PREFIX_MAP_VERSION_DSDB = 0x44534442 } prefixMapVersion; typedef [nodiscriminant] union { [case(PREFIX_MAP_VERSION_DSDB)] drsuapi_DsReplicaOIDMapping_Ctr dsdb; } prefixMapCtr; typedef [public] struct { prefixMapVersion version; uint32 reserved; [switch_is(version)] prefixMapCtr ctr; } prefixMapBlob; void decode_prefixMap( [in] prefixMapBlob blob ); /* * the cookie for the LDAP dirsync control */ typedef [nodiscriminant,gensize] union { [case(0)]; [default] replUpToDateVectorBlob uptodateness_vector; } ldapControlDirSyncExtra; typedef struct { [value(3)] uint32 u1; NTTIME time; uint32 u2; uint32 u3; [value(ndr_size_ldapControlDirSyncExtra(&extra, extra.uptodateness_vector.version, 0))] uint32 extra_length; drsuapi_DsReplicaHighWaterMark highwatermark; GUID guid1; [switch_is(extra_length)] ldapControlDirSyncExtra extra; } ldapControlDirSyncBlob; typedef [public,relative_base] struct { [charset(DOS),value("MSDS")] uint8 msds[4]; [subcontext(0)] ldapControlDirSyncBlob blob; } ldapControlDirSyncCookie; void decode_ldapControlDirSync( [in] ldapControlDirSyncCookie cookie ); typedef struct { [value(2*strlen_m(name))] uint16 name_len; [value(strlen(data))] uint16 data_len; uint16 reserved; /* 2 for 'Packages', 1 for 'Primary:*', but should be ignored */ [charset(UTF16)] uint8 name[name_len]; /* * the data field contains data as HEX strings * * 'Packages': * data contains the list of packages * as non termiated UTF16 strings with * a UTF16 NULL byte as separator * * 'Primary:Kerberos-Newer-Keys': * ... * * 'Primary:Kerberos': * ... * * 'Primary:WDigest': * ... * * 'Primary:CLEARTEXT': * data contains the cleartext password * as UTF16 string encoded as HEX string */ [charset(DOS)] uint8 data[data_len]; } supplementalCredentialsPackage; /* this are 0x30 (48) whitespaces (0x20) */ const string SUPPLEMENTAL_CREDENTIALS_PREFIX = " "; typedef [flag(NDR_PAHEX)] enum { SUPPLEMENTAL_CREDENTIALS_SIGNATURE = 0x0050 } supplementalCredentialsSignature; typedef [gensize] struct { [value(SUPPLEMENTAL_CREDENTIALS_PREFIX),charset(UTF16)] uint16 prefix[0x30]; [value(SUPPLEMENTAL_CREDENTIALS_SIGNATURE)] supplementalCredentialsSignature signature; uint16 num_packages; supplementalCredentialsPackage packages[num_packages]; } supplementalCredentialsSubBlob; typedef [public] struct { [value(0)] uint32 unknown1; [value(ndr_size_supplementalCredentialsSubBlob(&sub, ndr->flags))] uint32 __ndr_size; [value(0)] uint32 unknown2; [subcontext(0),subcontext_size(__ndr_size)] supplementalCredentialsSubBlob sub; [value(0)] uint8 unknown3; } supplementalCredentialsBlob; void decode_supplementalCredentials( [in] supplementalCredentialsBlob blob ); typedef [public] struct { [flag(STR_NOTERM|NDR_REMAINING)] string_array names; } package_PackagesBlob; void decode_Packages( [in] package_PackagesBlob blob ); typedef struct { [value(2*strlen_m(string))] uint16 length; [value(2*strlen_m(string))] uint16 size; [relative,subcontext(0),subcontext_size(size),flag(STR_NOTERM|NDR_REMAINING)] string *string; } package_PrimaryKerberosString; typedef struct { [value(0)] uint16 reserved1; [value(0)] uint16 reserved2; [value(0)] uint32 reserved3; uint32 keytype; [value((value?value->length:0))] uint32 value_len; [relative,subcontext(0),subcontext_size(value_len),flag(NDR_REMAINING)] DATA_BLOB *value; } package_PrimaryKerberosKey3; typedef struct { uint16 num_keys; uint16 num_old_keys; package_PrimaryKerberosString salt; package_PrimaryKerberosKey3 keys[num_keys]; package_PrimaryKerberosKey3 old_keys[num_old_keys]; [value(0)] uint32 padding1; [value(0)] uint32 padding2; [value(0)] uint32 padding3; [value(0)] uint32 padding4; [value(0)] uint32 padding5; } package_PrimaryKerberosCtr3; typedef struct { [value(0)] uint16 reserved1; [value(0)] uint16 reserved2; [value(0)] uint32 reserved3; uint32 iteration_count; uint32 keytype; [value((value?value->length:0))] uint32 value_len; [relative,subcontext(0),subcontext_size(value_len),flag(NDR_REMAINING)] DATA_BLOB *value; } package_PrimaryKerberosKey4; typedef struct { uint16 num_keys; [value(0)] uint16 num_service_keys; uint16 num_old_keys; uint16 num_older_keys; package_PrimaryKerberosString salt; uint32 default_iteration_count; package_PrimaryKerberosKey4 keys[num_keys]; package_PrimaryKerberosKey4 service_keys[num_service_keys]; package_PrimaryKerberosKey4 old_keys[num_old_keys]; package_PrimaryKerberosKey4 older_keys[num_older_keys]; } package_PrimaryKerberosCtr4; typedef [nodiscriminant] union { [case(3)] package_PrimaryKerberosCtr3 ctr3; [case(4)] package_PrimaryKerberosCtr4 ctr4; } package_PrimaryKerberosCtr; typedef [public] struct { uint16 version; [value(0)] uint16 flags; [switch_is(version)] package_PrimaryKerberosCtr ctr; } package_PrimaryKerberosBlob; void decode_PrimaryKerberos( [in] package_PrimaryKerberosBlob blob ); typedef [public] struct { [flag(STR_NOTERM|NDR_REMAINING)] string cleartext; } package_PrimaryCLEARTEXTBlob; void decode_PrimaryCLEARTEXT( [in] package_PrimaryCLEARTEXTBlob blob ); typedef [flag(NDR_PAHEX)] struct { uint8 hash[16]; } package_PrimaryWDigestHash; typedef [public] struct { [value(0x31)] uint16 unknown1; [value(0x01)] uint8 unknown2; uint8 num_hashes; [value(0)] uint32 unknown3; [value(0)] udlong uuknown4; package_PrimaryWDigestHash hashes[num_hashes]; } package_PrimaryWDigestBlob; void decode_PrimaryWDigest( [in] package_PrimaryWDigestBlob blob ); typedef struct { NTTIME time1; uint32 unknown1; DATA_BLOB value; [flag(NDR_ALIGN4)] DATA_BLOB _pad; } trustAuthInOutSecret1; typedef struct { [relative] trustAuthInOutSecret1 *value1; [relative] trustAuthInOutSecret1 *value2; } trustAuthInOutCtr1; typedef [v1_enum] enum { TRUST_AUTH_TYPE_NONE = 0, TRUST_AUTH_TYPE_NT4OWF = 1, TRUST_AUTH_TYPE_CLEAR = 2, TRUST_AUTH_TYPE_VERSION = 3 } trustAuthType; typedef struct { [value(0)] uint32 size; } AuthInfoNone; typedef struct { [value(16)] uint32 size; samr_Password password; } AuthInfoNT4Owf; typedef struct { uint32 size; [charset(UTF16)] uint8 password[size]; } AuthInfoClear; typedef struct { [value(4)] uint32 size; uint32 version; } AuthInfoVersion; typedef [nodiscriminant] union { [case(TRUST_AUTH_TYPE_NONE)] AuthInfoNone none; [case(TRUST_AUTH_TYPE_NT4OWF)] AuthInfoNT4Owf nt4owf; [case(TRUST_AUTH_TYPE_CLEAR)] AuthInfoClear clear; [case(TRUST_AUTH_TYPE_VERSION)] AuthInfoVersion version; } AuthInfo; typedef struct { NTTIME LastUpdateTime; trustAuthType AuthType; /* * the secret value is encoded as UTF16 if it's a string * but depending the AuthType, it might also be krb5 trusts have random bytes here, so converting to UTF16 * mayfail... * * TODO: We should try handle the case of a random buffer in all places * we deal with cleartext passwords from windows * * so we don't use this: * * uint32 value_len; * [charset(UTF16)] uint8 value[value_len]; */ [switch_is(AuthType)] AuthInfo AuthInfo; [flag(NDR_ALIGN4)] DATA_BLOB _pad; } AuthenticationInformation; typedef [public] struct { uint32 count; [relative] AuthenticationInformation *authinfo[count]; [relative] AuthenticationInformation *previous_authinfo[count]; } trustAuthInOutBlob; void decode_trustAuthInOut( [in] trustAuthInOutBlob blob ); typedef [public] struct { uint32 marker; DATA_BLOB data; } DsCompressedChunk; typedef [public] struct { DsCompressedChunk chunks[5]; } DsCompressedBlob; void decode_DsCompressed( [in] DsCompressedBlob blob ); }