From cead12981f86f8c30daf50995d61ff3af9439898 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 15 Mar 2005 14:42:09 +0000 Subject: [PATCH] r5799: more DsGetNCChanges updates, I'm starting to understand it... also add a really simple torture test for DsGetNCChanges metze (This used to be commit bcde67a7eff9ad82919e90fd64c02a17610c6f0e) --- source4/librpc/idl/drsuapi.idl | 120 ++++++++++++++++++++++++++++++++++------- source4/librpc/ndr/ndr_sec.c | 10 ++++ source4/torture/rpc/drsuapi.c | 110 +++++++++++++++++++++++++++++++------ 3 files changed, 205 insertions(+), 35 deletions(-) diff --git a/source4/librpc/idl/drsuapi.idl b/source4/librpc/idl/drsuapi.idl index 21a364180a5..c4b94ba850b 100644 --- a/source4/librpc/idl/drsuapi.idl +++ b/source4/librpc/idl/drsuapi.idl @@ -6,7 +6,8 @@ endpoint("ncacn_np:[\\pipe\\lsass]","ncacn_np:[\\pipe\\protected_storage]", "ncacn_ip_tcp:", "ncalrpc:"), authservice("ldap"), helpstring("Active Directory Replication"), - pointer_default(unique) + pointer_default(unique), + depends(security) ] interface drsuapi { @@ -114,12 +115,12 @@ interface drsuapi /*****************/ /* Function 0x02 */ typedef [gensize,flag(NDR_PAHEX)] struct { - [value(ndr_size_drsuapi_DsReplicaSyncRequest1Info(r, ndr->flags)-4)] uint32 __ndr_size; - uint32 unknown1; - GUID guid1; - uint8 byte_array[28]; - [flag(STR_SIZE4|STR_CHARLEN|STR_CONFORMANT)] string nc_dn; - } drsuapi_DsReplicaSyncRequest1Info; + [value(ndr_size_drsuapi_DsReplicaObjectIdentifier(r, ndr->flags)-4)] uint32 __ndr_size; + [value(ndr_length_dom_sid(&r->sid))] uint32 __ndr_size_sid; + GUID guid; + [subcontext_size(28),subcontext(0)] dom_sid sid; + [flag(STR_SIZE4|STR_CHARLEN|STR_CONFORMANT)] string dn; + } drsuapi_DsReplicaObjectIdentifier; typedef bitmap { DRSUAPI_DS_REPLICA_SYNC_ASYNCHRONOUS_OPERATION = 0x00000001, @@ -149,7 +150,7 @@ interface drsuapi } drsuapi_DsReplicaSyncOptions; typedef struct { - drsuapi_DsReplicaSyncRequest1Info *info; + drsuapi_DsReplicaObjectIdentifier *naming_context; GUID guid1; astring *string1; drsuapi_DsReplicaSyncOptions options; @@ -189,7 +190,7 @@ interface drsuapi typedef struct { GUID guid1; GUID guid2; - [ref] drsuapi_DsReplicaSyncRequest1Info *sync_req_info1; + [ref] drsuapi_DsReplicaObjectIdentifier *naming_context; drsuapi_DsGetNCChangesUsnTriple usn1; drsuapi_DsReplicaCoursor05Ctr *coursor; uint32 unknown1; @@ -217,7 +218,7 @@ interface drsuapi typedef struct { GUID guid1; GUID guid2; - [ref] drsuapi_DsReplicaSyncRequest1Info *sync_req_info1; + [ref] drsuapi_DsReplicaObjectIdentifier *naming_context; drsuapi_DsGetNCChangesUsnTriple usn1; drsuapi_DsReplicaCoursor05Ctr *coursor; uint32 unknown1; @@ -249,9 +250,76 @@ interface drsuapi } drsuapi_DsReplicaCoursorEx05Ctr; typedef struct { + uint32 version; + NTTIME_1sec time; + GUID guid; + hyper usn; + } drsuapi_DsReplicaMetaData; + + typedef struct { + [range(0,1048576)] uint32 count; + [size_is(count)] drsuapi_DsReplicaMetaData meta_data[]; + } drsuapi_DsReplicaMetaDataCtr; + + typedef [flag(NDR_PAHEX)] struct { + [range(0,10485760)] uint32 length; + DATA_BLOB *data; + } drsuapi_DsReplicaAttributeValue; + + typedef struct { + [range(0,10485760)] uint32 num_values; + [size_is(num_values)] drsuapi_DsReplicaAttributeValue *values[]; + } drsuapi_DsReplicaAttributeValueCtr; + + typedef [v1_enum] enum { + DRSUAPI_ATTR_objectClass = 0x00000000, + DRSUAPI_ATTR_description = 0x0000000d, + DRSUAPI_ATTR_ntSecurityDescriptor = 0x00020119, + DRSUAPI_ATTR_objectSid = 0x00090092 + } drsuapi_DsAttributeId; + + typedef [flag(NDR_PAHEX)] struct { + drsuapi_DsAttributeId attid; + drsuapi_DsReplicaAttributeValueCtr value_ctr; + } drsuapi_DsReplicaAttribute; + + typedef struct { + [range(0,1048576)] uint32 num_attributes; + [size_is(num_attributes)] drsuapi_DsReplicaAttribute *attributes[]; + } drsuapi_DsReplicaAttributeCtr; + + typedef struct { + drsuapi_DsReplicaObjectIdentifier *identifier; + uint32 unknown1; + drsuapi_DsReplicaAttributeCtr attribute_ctr; + } drsuapi_DsReplicaObject; + + typedef struct { + /* TODO: fix ndr_print for next_info! */ + [print_option(linked_list_next)] drsuapi_DsGetNCChangesInfo1 *next; + drsuapi_DsReplicaObject object; + uint32 unknown1; + GUID *guid; + drsuapi_DsReplicaMetaDataCtr *meta_data_ctr; + } drsuapi_DsGetNCChangesInfo1; + + typedef struct { + GUID guid1; + GUID guid2; + drsuapi_DsReplicaObjectIdentifier *naming_context; + drsuapi_DsGetNCChangesUsnTriple usn1; + drsuapi_DsGetNCChangesUsnTriple usn2; + drsuapi_DsReplicaCoursorEx05Ctr *coursor_ex; + drsuapi_DsGetNCChangesRequest_Ctr12 ctr12; + uint32 u1[3]; + drsuapi_DsGetNCChangesInfo1 *info1; + uint32 u2; + } drsuapi_DsGetNCChangesCtr1; + + typedef struct { GUID guid1; GUID guid2; - drsuapi_DsReplicaSyncRequest1Info *sync_req_info1; + drsuapi_DsReplicaObjectIdentifier *naming_context; drsuapi_DsGetNCChangesUsnTriple usn1; drsuapi_DsGetNCChangesUsnTriple usn2; drsuapi_DsReplicaCoursorEx05Ctr *coursor_ex; @@ -265,9 +333,19 @@ interface drsuapi } drsuapi_DsGetNCChangesCtr6; typedef struct { + uint32 u1;/* decompressed_length ? */ + uint32 compressed_length; + DATA_BLOB *compressed; + } drsuapi_DsGetNCChangesCtr7CompressedInfo; + + typedef struct { + uint32 u1; + uint16 u2; /* enum */ + drsuapi_DsGetNCChangesCtr7CompressedInfo info; } drsuapi_DsGetNCChangesCtr7; typedef [switch_type(int32)] union { + [case(1)] drsuapi_DsGetNCChangesCtr1 ctr1; [case(6)] drsuapi_DsGetNCChangesCtr6 ctr6; [case(7)] drsuapi_DsGetNCChangesCtr7 ctr7; } drsuapi_DsGetNCChangesCtr; @@ -290,12 +368,10 @@ interface drsuapi } drsuapi_DsReplicaUpdateRefsOptions; typedef struct { - uint32 unknown1; - uint32 unknown2; + [ref] drsuapi_DsReplicaObjectIdentifier *naming_context; + [ref] ascstr *dest_dsa_dns_name; GUID dest_dsa_guid; drsuapi_DsReplicaUpdateRefsOptions options; - drsuapi_DsReplicaSyncRequest1Info sync_req_info1; - ascstr dest_dsa_dns_name; } drsuapi_DsReplicaUpdateRefsRequest1; typedef [switch_type(int32)] union { @@ -534,10 +610,16 @@ interface drsuapi [size_is(count)] drsuapi_DsGetDCInfo01 *array[]; } drsuapi_DsGetDCInfoCtr01; - typedef [switch_type(int32)] union { - [case(1)] drsuapi_DsGetDCInfoCtr1 ctr1; - [case(2)] drsuapi_DsGetDCInfoCtr2 ctr2; - [case(-1)] drsuapi_DsGetDCInfoCtr01 ctr01; + typedef [v1_enum] enum { + DRSUAPI_DC_INFO_CTR_1 = 1, + DRSUAPI_DC_INFO_CTR_2 = 2, + DRSUAPI_DC_INFO_CTR_01 = -1 + } drsuapi_DsGetDCInfoCtrLevels; + + typedef [switch_type(int32)] union { + [case(DRSUAPI_DC_INFO_CTR_1)] drsuapi_DsGetDCInfoCtr1 ctr1; + [case(DRSUAPI_DC_INFO_CTR_2)] drsuapi_DsGetDCInfoCtr2 ctr2; + [case(DRSUAPI_DC_INFO_CTR_01)] drsuapi_DsGetDCInfoCtr01 ctr01; } drsuapi_DsGetDCInfoCtr; WERROR drsuapi_DsGetDomainControllerInfo( diff --git a/source4/librpc/ndr/ndr_sec.c b/source4/librpc/ndr/ndr_sec.c index 162d684b036..22479be7e51 100644 --- a/source4/librpc/ndr/ndr_sec.c +++ b/source4/librpc/ndr/ndr_sec.c @@ -80,6 +80,16 @@ size_t ndr_size_dom_sid(struct dom_sid *sid) } /* + return the wire size of a dom_sid +*/ +size_t ndr_length_dom_sid(struct dom_sid *sid) +{ + if (!sid) return 0; + if (sid->sid_rev_num == 0) return 0; + return 8 + 4*sid->num_auths; +} + +/* return the wire size of a security_ace */ size_t ndr_size_security_ace(struct security_ace *ace) diff --git a/source4/torture/rpc/drsuapi.c b/source4/torture/rpc/drsuapi.c index a6c0f5b9c65..57382289a29 100644 --- a/source4/torture/rpc/drsuapi.c +++ b/source4/torture/rpc/drsuapi.c @@ -764,8 +764,9 @@ static BOOL test_DsReplicaSync(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, BOOL ret = True; int i; struct drsuapi_DsReplicaSync r; - struct drsuapi_DsReplicaSyncRequest1Info info1; - + struct drsuapi_DsReplicaObjectIdentifier nc; + struct GUID null_guid; + struct dom_sid null_sid; struct { int32_t level; } array[] = { @@ -779,6 +780,9 @@ static BOOL test_DsReplicaSync(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, return True; } + ZERO_STRUCT(null_guid); + ZERO_STRUCT(null_sid); + r.in.bind_handle = &priv->bind_handle; for (i=0; i < ARRAY_SIZE(array); i++) { @@ -788,11 +792,11 @@ static BOOL test_DsReplicaSync(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, r.in.level = array[i].level; switch(r.in.level) { case 1: - r.in.req.req1.info = &info1; - r.in.req.req1.info->unknown1 = 0; - ZERO_STRUCT(r.in.req.req1.info->guid1); - ZERO_STRUCT(r.in.req.req1.info->byte_array); - r.in.req.req1.info->nc_dn = priv->domain_obj_dn?priv->domain_obj_dn:""; + nc.guid = null_guid; + nc.sid = null_sid; + nc.dn = priv->domain_obj_dn?priv->domain_obj_dn:""; + + r.in.req.req1.naming_context = &nc; r.in.req.req1.guid1 = priv->dcinfo.ntds_guid; r.in.req.req1.string1 = NULL; r.in.req.req1.options = 16; @@ -823,7 +827,9 @@ static BOOL test_DsReplicaUpdateRefs(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, BOOL ret = True; int i; struct drsuapi_DsReplicaUpdateRefs r; + struct drsuapi_DsReplicaObjectIdentifier nc; struct GUID null_guid; + struct dom_sid null_sid; struct { int32_t level; } array[] = { @@ -833,6 +839,7 @@ static BOOL test_DsReplicaUpdateRefs(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, }; ZERO_STRUCT(null_guid); + ZERO_STRUCT(null_sid); r.in.bind_handle = &priv->bind_handle; @@ -843,16 +850,15 @@ static BOOL test_DsReplicaUpdateRefs(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, r.in.level = array[i].level; switch(r.in.level) { case 1: - r.in.req.req1.unknown1 = 0; - r.in.req.req1.unknown2 = 0; - r.in.req.req1.dest_dsa_guid = null_guid; - r.in.req.req1.options = 0; - r.in.req.req1.sync_req_info1.unknown1 = 0; - r.in.req.req1.sync_req_info1.guid1 = null_guid; - ZERO_STRUCT(r.in.req.req1.sync_req_info1.byte_array); - r.in.req.req1.sync_req_info1.nc_dn = priv->domain_obj_dn?priv->domain_obj_dn:""; - r.in.req.req1.dest_dsa_dns_name = talloc_asprintf(mem_ctx, "__some_dest_dsa_guid_string._msdn.%s", + nc.guid = null_guid; + nc.sid = null_sid; + nc.dn = priv->domain_obj_dn?priv->domain_obj_dn:""; + + r.in.req.req1.naming_context = &nc; + r.in.req.req1.dest_dsa_dns_name = talloc_asprintf(mem_ctx, "__some_dest_dsa_guid_string._msdn.%s", priv->domain_dns_name); + r.in.req.req1.dest_dsa_guid = null_guid; + r.in.req.req1.options = 0; break; } @@ -873,6 +879,76 @@ static BOOL test_DsReplicaUpdateRefs(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, return ret; } +static BOOL test_DsGetNCChanges(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, + struct DsPrivate *priv) +{ + NTSTATUS status; + BOOL ret = True; + int i; + struct drsuapi_DsGetNCChanges r; + struct drsuapi_DsReplicaObjectIdentifier nc; + struct GUID null_guid; + struct dom_sid null_sid; + struct { + int32_t level; + } array[] = { + { + 5 + }, + { + 8 + } + }; + + ZERO_STRUCT(null_guid); + ZERO_STRUCT(null_sid); + + for (i=0; i < ARRAY_SIZE(array); i++) { + printf("testing DsGetNCChanges level %d\n", + array[i].level); + + ZERO_STRUCT(r.in); + r.in.bind_handle = &priv->bind_handle; + r.in.level = array[i].level; + + switch (r.in.level) { + case 5: + nc.guid = null_guid; + nc.sid = null_sid; + nc.dn = talloc_asprintf(mem_ctx, "CN=Schema,CN=Configuration,%s", + priv->domain_obj_dn?priv->domain_obj_dn:""); + nc.dn = priv->domain_obj_dn?priv->domain_obj_dn:""; + + r.in.req.req5.naming_context = &nc; + r.in.req.req5.usn1.usn1 = 0; + break; + case 8: + nc.guid = null_guid; + nc.sid = null_sid; + nc.dn = priv->domain_obj_dn?priv->domain_obj_dn:""; + + r.in.req.req8.naming_context = &nc; + r.in.req.req8.usn1.usn1 = 0; + break; + } + + status = dcerpc_drsuapi_DsGetNCChanges(p, mem_ctx, &r); + if (!NT_STATUS_IS_OK(status)) { + const char *errstr = nt_errstr(status); + if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) { + errstr = dcerpc_errstr(mem_ctx, p->last_fault_code); + } + printf("dcerpc_drsuapi_DsGetNCChanges failed - %s\n", errstr); + ret = False; + } else if (!W_ERROR_IS_OK(r.out.result)) { + printf("DsGetNCChanges failed - %s\n", win_errstr(r.out.result)); + ret = False; + } + } + + return ret; +} + static BOOL test_DsUnbind(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, struct DsPrivate *priv) { @@ -937,6 +1013,8 @@ BOOL torture_rpc_drsuapi(void) ret &= test_DsReplicaUpdateRefs(p, mem_ctx, &priv); + ret &= test_DsGetNCChanges(p, mem_ctx, &priv); + ret &= test_DsUnbind(p, mem_ctx, &priv); talloc_free(mem_ctx); -- 2.11.4.GIT