r4087: - add idl and torture tests for drsuapi_DsReplicaGetInfo()
authorStefan Metzmacher <metze@samba.org>
Tue, 7 Dec 2004 12:20:28 +0000 (12:20 +0000)
committerGerald (Jerry) Carter <jerry@samba.org>
Wed, 10 Oct 2007 18:06:25 +0000 (13:06 -0500)
(NOTE: that the drsuapi_DsReplicaObjMetaData2 struct is not corrently parsed yet
 and there're some unknown fields left in someother infotypes)

metze
(This used to be commit 4fd57d5e7cff085a8c003ea82f282e26dc1346d9)

source4/librpc/idl/drsuapi.idl
source4/rpc_server/drsuapi/dcesrv_drsuapi.c
source4/torture/rpc/drsuapi.c

index b4784da95b9e52c2db7191f0080faae057b04c88..15d1ca8efcd1c44f7cb73fc5e4eea7a6eb0dbc47 100644 (file)
@@ -17,8 +17,12 @@ interface drsuapi
                [size_is(length)] uint8 data[];
        } drsuapi_DsBindInfo;
 
-       /* this is a magic guid you need to pass to DsBind to make drsuapi_DsWriteAccountSpn() work */
+       /* this is a magic guid you need to pass to DsBind to make drsuapi_DsWriteAccountSpn() work
+        * 
+        * maybe the bind_guid could also be the invocation_id see drsuapi_DsReplicaConnection04
+        */
        const string DRSUAPI_DS_BIND_GUID = "e24d201a-4fd6-11d1-a3da-0000f875ae0d";
+       
 
        /* this are the bind info blobs returned (seemed to be const):
                w2k3    7ffbff1f81a6ff5d80139441a372e9b779d70268f801000000000000
@@ -310,8 +314,284 @@ interface drsuapi
        WERROR DRSUAPI_EXECUTE_KCC();
 
        /*****************/
-        /* Function 0x13 */
-       WERROR DRSUAPI_GET_REPL_INFO();
+       /* Function 0x13 */
+       typedef enum {
+               DRSUAPI_DS_REPLICA_GET_INFO                             = 1,
+               DRSUAPI_DS_REPLICA_GET_INFO2                            = 2
+       } drsuapi_DsReplicaGetInfoLevel;
+
+       typedef enum {
+               DRSUAPI_DS_REPLICA_INFO_NEIGHBORS                       = 0,
+               DRSUAPI_DS_REPLICA_INFO_CURSORS                         = 1,
+               DRSUAPI_DS_REPLICA_INFO_OBJ_METADATA                    = 2,
+               DRSUAPI_DS_REPLICA_INFO_KCC_DSA_CONNECT_FAILURES        = 3,
+               DRSUAPI_DS_REPLICA_INFO_KCC_DSA_LINK_FAILURES           = 4,
+               DRSUAPI_DS_REPLICA_INFO_PENDING_OPS                     = 5,
+               DRSUAPI_DS_REPLICA_INFO_ATTRIBUTE_VALUE_METADATA        = 6,
+               DRSUAPI_DS_REPLICA_INFO_CURSORS2                        = 7,
+               DRSUAPI_DS_REPLICA_INFO_CURSORS3                        = 8,
+               DRSUAPI_DS_REPLICA_INFO_OBJ_METADATA2                   = 9,
+               DRSUAPI_DS_REPLICA_INFO_ATTRIBUTE_VALUE_METADATA2       = 10,
+               DRSUAPI_DS_REPLICA_INFO_NEIGHBORS02                     = -2,
+               DRSUAPI_DS_REPLICA_INFO_CONNECTIONS04                   = -4,
+               DRSUAPI_DS_REPLICA_INFO_CURSURS05                       = -5,
+               DRSUAPI_DS_REPLICA_INFO_06                              = -6
+       } drsuapi_DsReplicaInfoType;
+
+       typedef struct {
+               int32 info_type;
+               unistr *object_dn;
+               GUID guid1;
+       } drsuapi_DsReplicaGetInfoRequest1;
+
+       typedef struct {
+               int32 info_type;
+               unistr *object_dn;
+               GUID guid1;
+               uint32 unknown1;
+               unistr *string1;
+               unistr *string2;
+               uint32 unknown2;
+       } drsuapi_DsReplicaGetInfoRequest2;
+
+       typedef union {
+               [case(1)] drsuapi_DsReplicaGetInfoRequest1 req1;
+               [case(2)] drsuapi_DsReplicaGetInfoRequest2 req2;
+       } drsuapi_DsReplicaGetInfoRequest;
+
+       typedef struct {
+               unistr *naming_context_dn;
+               unistr *source_dsa_obj_dn;
+               unistr *source_dsa_address;
+               unistr *transport_obj_dn;
+               uint32 replica_flags;
+               uint32 reserved;
+               GUID naming_context_obj_guid;
+               GUID source_dsa_obj_guid;
+               GUID source_dsa_invocation_id;
+               GUID transport_obj_guid;
+               uint64 tmp_highest_usn;
+               uint64 highest_usn;
+               NTTIME last_success;
+               NTTIME last_attempt;
+               WERROR result_last_attempt;
+               uint32 consecutive_sync_failures;
+       } drsuapi_DsReplicaNeighbour;
+
+       typedef struct {
+               uint32 count;
+               uint32 reserved;
+               [size_is(count)] drsuapi_DsReplicaNeighbour array[];
+       } drsuapi_DsReplicaNeighbourCtr;
+
+       typedef struct {
+               GUID source_dsa_invocation_id;
+               uint64 highest_usn;
+       } drsuapi_DsReplicaCoursor;
+
+       typedef struct {
+               uint32 count;
+               uint32 reserved;
+               [size_is(count)] drsuapi_DsReplicaCoursor array[];
+       } drsuapi_DsReplicaCoursorCtr;
+
+       typedef struct {
+               unistr *attribute_name;
+               uint32 version;
+               NTTIME originating_last_changed;
+               GUID originating_dsa_invocation_id;
+               uint64 originating_usn;
+               uint64 local_usn;
+       } drsuapi_DsReplicaObjMetaData;
+
+       typedef struct {
+               uint32 count;
+               uint32 reserved;
+               [size_is(count)] drsuapi_DsReplicaObjMetaData array[];
+       } drsuapi_DsReplicaObjMetaDataCtr;
+
+       typedef struct {
+               unistr *dsa_obj_dn;
+               GUID dsa_obj_guid;
+               NTTIME first_failure;
+               uint32 num_failures;
+               WERROR last_result;
+       } drsuapi_DsReplicaKccDsaFailure;
+
+       typedef struct {
+               uint32 count;
+               uint32 reserved;
+               [size_is(count)] drsuapi_DsReplicaKccDsaFailure array[];
+       } drsuapi_DsReplicaKccDsaFailuresCtr;
+
+       typedef struct {
+               NTTIME operation_start;
+               uint32 serial_num; /* unique till reboot */
+               uint32 priority;
+               uint16 operation_type;
+               uint32 options_flags;
+               unistr *nc_dn;
+               unistr *remote_dsa_obj_dn;
+               unistr *remote_dsa_address;
+               GUID nc_obj_guid;
+               GUID remote_dsa_obj_guid;
+       } drsuapi_DsReplicaOp;
+
+       typedef struct {
+               NTTIME time;
+               uint32 count;
+               [size_is(count)] drsuapi_DsReplicaOp array[];
+       } drsuapi_DsReplicaOpCtr;
+
+       typedef struct {
+               unistr *attribute_name;
+               unistr *object_dn;
+               uint32 value_length;
+               [size_is(value_length)] uint8 *value;
+               NTTIME deleted;
+               NTTIME created;
+               uint32 version;
+               NTTIME originating_last_changed;
+               GUID originating_dsa_invocation_id;
+               uint64 originating_usn;
+               uint64 local_usn;
+       } drsuapi_DsReplicaAttrValMetaData;
+
+       typedef struct {
+               uint32 count;
+               int32 enumeration_context;
+               [size_is(count)] drsuapi_DsReplicaAttrValMetaData array[];
+       } drsuapi_DsReplicaAttrValMetaDataCtr;
+
+       typedef struct {
+               GUID source_dsa_invocation_id;
+               uint64 highest_usn;
+               NTTIME last_sync_success;
+       } drsuapi_DsReplicaCoursor2;
+
+       typedef struct {
+               uint32 count;
+               int32 enumeration_context;
+               [size_is(count)] drsuapi_DsReplicaCoursor2 array[];
+       } drsuapi_DsReplicaCoursor2Ctr;
+
+       typedef struct {
+               GUID source_dsa_invocation_id;
+               uint64 highest_usn;
+               NTTIME last_sync_success;
+               unistr *source_dsa_obj_dn;
+       } drsuapi_DsReplicaCoursor3;
+
+       typedef struct {
+               uint32 count;
+               int32 enumeration_context;
+               [size_is(count)] drsuapi_DsReplicaCoursor3 array[];
+       } drsuapi_DsReplicaCoursor3Ctr;
+
+       typedef struct {
+               uint32 attribute_name;/*unistr *attribute_name;*/
+               uint32 version;
+               NTTIME originating_last_changed;
+               GUID originating_dsa_invocation_id;
+               uint64 originating_usn;
+               uint64 local_usn;
+               uint32 originating_dsa_obj_dn;/*unistr *originating_dsa_obj_dn;*/
+               uint32 u1; /* in the last element this is not present; some stupid alignment? */
+       } drsuapi_DsReplicaObjMetaData2;
+
+       typedef struct {
+               uint32 count;
+               int32 enumeration_context;
+               [size_is(count)] drsuapi_DsReplicaObjMetaData2 array[];
+       } drsuapi_DsReplicaObjMetaData2Ctr;
+
+       typedef struct {
+               unistr *attribute_name;
+               unistr *object_dn;
+               uint32 value_length;
+               [size_is(value_length)] uint8 *value;
+               NTTIME deleted;
+               NTTIME created;
+               uint32 version;
+               NTTIME originating_last_changed;
+               GUID originating_dsa_invocation_id;
+               uint64 originating_usn;
+               uint64 local_usn;
+               unistr *originating_dsa_obj_dn;
+       } drsuapi_DsReplicaAttrValMetaData2;
+
+       typedef struct {
+               uint32 count;
+               int32 enumeration_context;
+               [size_is(count)] drsuapi_DsReplicaAttrValMetaData2 array[];
+       } drsuapi_DsReplicaAttrValMetaData2Ctr;
+
+       typedef struct {
+               uint64 u1; /* session number? */
+               uint32 u2;
+               uint32 u3;
+               GUID bind_guid;
+               NTTIME_1sec bind_time;
+               uint32 u4; /* flags? */
+               uint32 u5;
+       } drsuapi_DsReplicaConnection04;
+
+       typedef struct {
+               [range(0,10000)] uint32 count;
+               uint32 reserved;
+               [size_is(count)] drsuapi_DsReplicaConnection04 array[];
+       } drsuapi_DsReplicaConnection04Ctr;
+
+       typedef struct {
+               uint32 u1;
+               uint32 u2;
+               [range(0,0x100000)] uint32 count;
+               uint32 u3;
+               [size_is(count)] drsuapi_DsReplicaCoursor array[];
+       } drsuapi_DsReplicaCoursor05Ctr;
+
+       typedef struct {
+               unistr *str1;
+               uint32 u1;
+               uint32 u2;
+               uint32 u3;
+               uint32 u4;
+               uint32 u5;
+               uint64 u6;
+               uint32 u7;
+       } drsuapi_DsReplica06;
+
+       typedef struct {
+               [range(0,256)] uint32 count;
+               uint32 reserved;
+               [size_is(count)] drsuapi_DsReplica06 array[];
+       } drsuapi_DsReplica06Ctr;
+
+       typedef union {
+               [case(0)] drsuapi_DsReplicaNeighbourCtr *neighbours;
+               [case(1)] drsuapi_DsReplicaCoursorCtr *coursors;
+               [case(2)] drsuapi_DsReplicaObjMetaDataCtr *objmetadata;
+               [case(3)] drsuapi_DsReplicaKccDsaFailuresCtr *connectfailures;
+               [case(4)] drsuapi_DsReplicaKccDsaFailuresCtr *linkfailures;
+               [case(5)] drsuapi_DsReplicaOpCtr *pendingops;
+               [case(6)] drsuapi_DsReplicaAttrValMetaDataCtr *attrvalmetadata;
+               [case(7)] drsuapi_DsReplicaCoursor2Ctr *coursors2;
+               [case(8)] drsuapi_DsReplicaCoursor3Ctr *coursors3;
+               [case(9)] drsuapi_DsReplicaObjMetaData2Ctr *objmetadata2;
+               [case(10)] drsuapi_DsReplicaAttrValMetaData2Ctr *attrvalmetadata2;
+               [case(-2)] drsuapi_DsReplicaNeighbourCtr *neighbours02;
+               [case(-4)] drsuapi_DsReplicaConnection04Ctr *connections04;
+               [case(-5)] drsuapi_DsReplicaCoursor05Ctr *coursors05;
+               [case(-6)] drsuapi_DsReplica06Ctr *i06;
+       } drsuapi_DsReplicaInfo;
+
+       WERROR drsuapi_DsReplicaGetInfo(
+               [in,ref] policy_handle *bind_handle,
+               [in] int32 level,
+               [in,switch_is(level)] drsuapi_DsReplicaGetInfoRequest req,
+               [out] int32 info_type,
+               [out,switch_is(info_type)] drsuapi_DsReplicaInfo info
+               );
 
        /*****************/
         /* Function 0x14 */
index f033c07ff776e35ad09b6e15ccfb54f11ef348e4..a8c48d680507184fccf90a535a31274e9243d430 100644 (file)
@@ -273,10 +273,10 @@ static WERROR DRSUAPI_EXECUTE_KCC(struct dcesrv_call_state *dce_call, TALLOC_CTX
 
 
 /* 
-  DRSUAPI_GET_REPL_INFO 
+  drsuapi_DsReplicaGetInfo 
 */
-static WERROR DRSUAPI_GET_REPL_INFO(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
-                      struct DRSUAPI_GET_REPL_INFO *r)
+static WERROR drsuapi_DsReplicaGetInfo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
+                      struct drsuapi_DsReplicaGetInfo *r)
 {
        DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
 }
index b6b1ddf6dcfa20e4a6704cd478f300da75465afa..e5b7e2ca0c6ee701a8b23b1ca64b758074aa3c82 100644 (file)
@@ -27,7 +27,9 @@
 struct DsPrivate {
        struct policy_handle bind_handle;
        struct GUID bind_guid;
+       const char *domain_obj_dn;
        const char *domain_guid_str;
+       struct GUID domain_guid;
        struct drsuapi_DsGetDCInfo2 dcinfo;
 };
 
@@ -71,7 +73,6 @@ static BOOL test_DsCrackNames(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
        BOOL ret = True;
        const char *dns_domain;
        const char *nt4_domain;
-       const char *FQDN_1779_domain;
        const char *FQDN_1779_name;
 
        ZERO_STRUCT(r);
@@ -133,6 +134,8 @@ static BOOL test_DsCrackNames(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
        }
 
        priv->domain_guid_str = r.out.ctr.ctr1->array[0].result_name;
+       GUID_from_string(priv->domain_guid_str, &priv->domain_guid);
+
 
        r.in.req.req1.format_offered    = DRSUAPI_DS_NAME_FORMAT_GUID;
        r.in.req.req1.format_desired    = DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT;
@@ -182,7 +185,7 @@ static BOOL test_DsCrackNames(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
                return ret;
        }
 
-       FQDN_1779_domain = r.out.ctr.ctr1->array[0].result_name;
+       priv->domain_obj_dn = r.out.ctr.ctr1->array[0].result_name;
 
        r.in.req.req1.format_offered    = DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT;
        r.in.req.req1.format_desired    = DRSUAPI_DS_NAME_FORMAT_FQDN_1779;
@@ -421,7 +424,7 @@ static BOOL test_DsCrackNames(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
        r.in.req.req1.format_desired    = DRSUAPI_DS_NAME_FORMAT_FQDN_1779;
        names[0].str = GUID_string2(mem_ctx, &priv->bind_guid);
 
-       printf("testing DsCrackNames with NTDS GUID '%s' desired format:%d\n",
+       printf("testing DsCrackNames with BIND GUID '%s' desired format:%d\n",
                        names[0].str, r.in.req.req1.format_desired);
 
        status = dcerpc_drsuapi_DsCrackNames(p, mem_ctx, &r);
@@ -627,6 +630,131 @@ static BOOL test_DsWriteAccountSpn(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
        return ret;
 }
 
+static BOOL test_DsReplicaGetInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
+                       struct DsPrivate *priv)
+{
+       NTSTATUS status;
+       struct drsuapi_DsReplicaGetInfo r;
+       BOOL ret = True;
+       int i;
+       struct {
+               int32 level;
+               int32 infotype;
+               const char *obj_dn;
+       } array[] = {
+               {       
+                       DRSUAPI_DS_REPLICA_GET_INFO,
+                       DRSUAPI_DS_REPLICA_INFO_NEIGHBORS,
+                       NULL
+               },{
+                       DRSUAPI_DS_REPLICA_GET_INFO,
+                       DRSUAPI_DS_REPLICA_INFO_CURSORS,
+                       NULL
+               },{
+                       DRSUAPI_DS_REPLICA_GET_INFO,
+                       DRSUAPI_DS_REPLICA_INFO_OBJ_METADATA,
+                       NULL
+               },{
+                       DRSUAPI_DS_REPLICA_GET_INFO,
+                       DRSUAPI_DS_REPLICA_INFO_KCC_DSA_CONNECT_FAILURES,
+                       NULL
+               },{
+                       DRSUAPI_DS_REPLICA_GET_INFO,
+                       DRSUAPI_DS_REPLICA_INFO_KCC_DSA_LINK_FAILURES,
+                       NULL
+               },{
+                       DRSUAPI_DS_REPLICA_GET_INFO,
+                       DRSUAPI_DS_REPLICA_INFO_PENDING_OPS,
+                       NULL
+               },{
+                       DRSUAPI_DS_REPLICA_GET_INFO2,
+                       DRSUAPI_DS_REPLICA_INFO_ATTRIBUTE_VALUE_METADATA,
+                       NULL
+               },{
+                       DRSUAPI_DS_REPLICA_GET_INFO2,
+                       DRSUAPI_DS_REPLICA_INFO_CURSORS2,
+                       NULL
+               },{
+                       DRSUAPI_DS_REPLICA_GET_INFO2,
+                       DRSUAPI_DS_REPLICA_INFO_CURSORS3,
+                       NULL
+               },{
+                       DRSUAPI_DS_REPLICA_GET_INFO2,
+                       DRSUAPI_DS_REPLICA_INFO_OBJ_METADATA2,
+                       NULL
+               },{
+                       DRSUAPI_DS_REPLICA_GET_INFO2,
+                       DRSUAPI_DS_REPLICA_INFO_ATTRIBUTE_VALUE_METADATA2,
+                       NULL
+               },{
+                       DRSUAPI_DS_REPLICA_GET_INFO2,
+                       DRSUAPI_DS_REPLICA_INFO_NEIGHBORS02,
+                       NULL
+               },{
+                       DRSUAPI_DS_REPLICA_GET_INFO2,
+                       DRSUAPI_DS_REPLICA_INFO_CONNECTIONS04,
+                       "__IGNORED__"
+               },{
+                       DRSUAPI_DS_REPLICA_GET_INFO2,
+                       DRSUAPI_DS_REPLICA_INFO_CURSURS05,
+                       NULL
+               },{
+                       DRSUAPI_DS_REPLICA_GET_INFO2,
+                       DRSUAPI_DS_REPLICA_INFO_06,
+                       NULL
+               }
+       };
+
+       r.in.bind_handle        = &priv->bind_handle;
+
+       for (i=0; i < ARRAY_SIZE(array); i++) {
+               const char *object_dn;
+
+               printf("testing DsReplicaGetInfo level %d infotype %d\n",
+                       array[i].level, array[i].infotype);
+
+               object_dn = (array[i].obj_dn ? array[i].obj_dn : priv->domain_obj_dn);
+
+               r.in.level = array[i].level;
+               switch(r.in.level) {
+               case DRSUAPI_DS_REPLICA_GET_INFO:
+                       r.in.req.req1.info_type = array[i].infotype;
+                       r.in.req.req1.object_dn = object_dn;
+                       ZERO_STRUCT(r.in.req.req1.guid1);
+                       break;
+               case DRSUAPI_DS_REPLICA_GET_INFO2:
+                       r.in.req.req2.info_type = array[i].infotype;
+                       r.in.req.req2.object_dn = object_dn;
+                       ZERO_STRUCT(r.in.req.req1.guid1);
+                       r.in.req.req2.unknown1  = 0;
+                       r.in.req.req2.string1   = NULL;
+                       r.in.req.req2.string2   = NULL;
+                       r.in.req.req2.unknown2  = 0;
+                       break;
+               }
+
+               status = dcerpc_drsuapi_DsReplicaGetInfo(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);
+                       }
+                       if (p->last_fault_code != DCERPC_FAULT_INVALID_TAG) {
+                               printf("dcerpc_drsuapi_DsReplicaGetInfo failed - %s\n", errstr);
+                               ret = False;
+                       } else {
+                               printf("DsReplicaGetInfo level %d and/or infotype %d not supported by server\n",
+                                       array[i].level, array[i].infotype);
+                       }
+               } else if (!W_ERROR_IS_OK(r.out.result)) {
+                       printf("DsReplicaGetInfo 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)
 {
@@ -693,6 +821,10 @@ BOOL torture_rpc_drsuapi(void)
                ret = False;
        }
 
+       if (!test_DsReplicaGetInfo(p, mem_ctx, &priv)) {
+               ret = False;
+       }
+
        if (!test_DsUnbind(p, mem_ctx, &priv)) {
                ret = False;
        }