summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source4/librpc/idl/drsuapi.idl137
-rw-r--r--source4/rpc_server/drsuapi/dcesrv_drsuapi.c18
-rw-r--r--source4/torture/rpc/drsuapi.c70
3 files changed, 201 insertions, 24 deletions
diff --git a/source4/librpc/idl/drsuapi.idl b/source4/librpc/idl/drsuapi.idl
index 759599e707..8a6a96dcac 100644
--- a/source4/librpc/idl/drsuapi.idl
+++ b/source4/librpc/idl/drsuapi.idl
@@ -4,6 +4,7 @@
uuid("e3514235-4b06-11d1-ab04-00c04fc2dcd2"),
version(4.0),
endpoint("ncacn_np:[\\pipe\\lsass]","ncacn_np:[\\pipe\\protected_storage]", "ncacn_ip_tcp:", "ncalrpc:"),
+ authservice("ldap"),
helpstring("Active Directory Replication"),
pointer_default(unique)
]
@@ -112,19 +113,46 @@ interface drsuapi
/*****************/
/* Function 0x02 */
- typedef [flag(NDR_PAHEX)] struct {
+ typedef [gensize,flag(NDR_PAHEX)] struct {
+ [value(ndr_size_drsuapi_DsReplicaSyncRequest1Info(r, ndr->flags)-4)] uint32 __ndr_size;
uint32 unknown1;
- uint32 unknown2;
GUID guid1;
- uint8 unknown3[28];
+ uint8 byte_array[28];
[flag(STR_SIZE4|STR_CHARLEN|STR_CONFORMANT)] string nc_dn;
} drsuapi_DsReplicaSyncRequest1Info;
+ typedef bitmap {
+ DRSUAPI_DS_REPLICA_SYNC_ASYNCHRONOUS_OPERATION = 0x00000001,
+ DRSUAPI_DS_REPLICA_SYNC_WRITEABLE = 0x00000002,
+ DRSUAPI_DS_REPLICA_SYNC_PERIODIC = 0x00000004,
+ DRSUAPI_DS_REPLICA_SYNC_INTERSITE_MESSAGING = 0x00000008,
+ DRSUAPI_DS_REPLICA_SYNC_ALL_SOURCES = 0x00000010,
+ DRSUAPI_DS_REPLICA_SYNC_FULL = 0x00000020,
+ DRSUAPI_DS_REPLICA_SYNC_URGENT = 0x00000040,
+ DRSUAPI_DS_REPLICA_SYNC_NO_DISCARD = 0x00000080,
+ DRSUAPI_DS_REPLICA_SYNC_FORCE = 0x00000100,
+ DRSUAPI_DS_REPLICA_SYNC_ADD_REFERENCE = 0x00000200,
+ DRSUAPI_DS_REPLICA_SYNC_NEVER_COMPLETED = 0x00000400,
+ DRSUAPI_DS_REPLICA_SYNC_TWO_WAY = 0x00000800,
+ DRSUAPI_DS_REPLICA_SYNC_NEVER_NOTIFY = 0x00001000,
+ DRSUAPI_DS_REPLICA_SYNC_INITIAL = 0x00002000,
+ DRSUAPI_DS_REPLICA_SYNC_USE_COMPRESSION = 0x00004000,
+ DRSUAPI_DS_REPLICA_SYNC_ABANDONED = 0x00008000,
+ DRSUAPI_DS_REPLICA_SYNC_INITIAL_IN_PROGRESS = 0x00010000,
+ DRSUAPI_DS_REPLICA_SYNC_PARTIAL_ATTRIBUTE_SET = 0x00020000,
+ DRSUAPI_DS_REPLICA_SYNC_REQUEUE = 0x00040000,
+ DRSUAPI_DS_REPLICA_SYNC_NOTIFICATION = 0x00080000,
+ DRSUAPI_DS_REPLICA_SYNC_ASYNCHRONOUS_REPLICA = 0x00100000,
+ DRSUAPI_DS_REPLICA_SYNC_CRITICAL = 0x00200000,
+ DRSUAPI_DS_REPLICA_SYNC_FULL_IN_PROGRESS = 0x00400000,
+ DRSUAPI_DS_REPLICA_SYNC_PREEMPTED = 0x00800000
+ } drsuapi_DsReplicaSyncOptions;
+
typedef struct {
drsuapi_DsReplicaSyncRequest1Info *info;
GUID guid1;
astring *string1;
- uint32 unknown1;
+ drsuapi_DsReplicaSyncOptions options;
} drsuapi_DsReplicaSyncRequest1;
typedef [switch_type(int32)] union {
@@ -138,23 +166,95 @@ interface drsuapi
);
/*****************/
- /* Function 0x03 */
- WERROR DRSUAPI_GET_NC_CHANGES();
+ /* Function 0x03 */
+ typedef struct {
+ hyper usn1;
+ hyper usn2;
+ hyper usn3;
+ } drsuapi_DsGetNCChangesUsnTriple;
+
+ typedef struct {
+ GUID guid1;
+ GUID guid2;
+ uint32 unknown1[20];
+ drsuapi_DsReplicaSyncRequest1Info sync_req_info1;
+ drsuapi_DsGetNCChangesUsnTriple usn;
+ } drsuapi_DsGetNCChangesRequest8;
+
+ typedef [switch_type(int32)] union {
+ [case(8)] drsuapi_DsGetNCChangesRequest8 req8;
+ } drsuapi_DsGetNCChangesRequest;
+
+ typedef struct {
+ } drsuapi_DsGetNCChangesCtr7;
+
+ typedef [switch_type(int32)] union {
+ [case(7)] drsuapi_DsGetNCChangesCtr7 ctr7;
+ } drsuapi_DsGetNCChangesCtr;
+
+ WERROR drsuapi_DsGetNCChanges(
+ [in,ref] policy_handle *bind_handle,
+ [in,out] int32 level,
+ [in,switch_is(level)] drsuapi_DsGetNCChangesRequest req,
+ [out,switch_is(level)] drsuapi_DsGetNCChangesCtr ctr
+ );
/*****************/
/* Function 0x04 */
- WERROR DRSUAPI_UPDATE_REFS();
+ typedef bitmap {
+ DRSUAPI_DS_REPLICA_UPDATE_ASYNCHRONOUS_OPERATION = 0x00000001,
+ DRSUAPI_DS_REPLICA_UPDATE_WRITEABLE = 0x00000002,
+ DRSUAPI_DS_REPLICA_UPDATE_ADD_REFERENCE = 0x00000004,
+ DRSUAPI_DS_REPLICA_UPDATE_DELETE_REFERENCE = 0x00000008,
+ DRSUAPI_DS_REPLICA_UPDATE_0x00000010 = 0x00000010
+ } drsuapi_DsReplicaUpdateRefsOptions;
+
+ typedef struct {
+ uint32 unknown1;
+ uint32 unknown2;
+ GUID dest_dsa_guid;
+ drsuapi_DsReplicaUpdateRefsOptions options;
+ drsuapi_DsReplicaSyncRequest1Info sync_req_info1;
+ ascstr dest_dsa_dns_name;
+ } drsuapi_DsReplicaUpdateRefsRequest1;
+
+ typedef [switch_type(int32)] union {
+ [case(1)] drsuapi_DsReplicaUpdateRefsRequest1 req1;
+ } drsuapi_DsReplicaUpdateRefsRequest;
+
+ WERROR drsuapi_DsReplicaUpdateRefs(
+ [in,ref] policy_handle *bind_handle,
+ [in] int32 level,
+ [in,switch_is(level)] drsuapi_DsReplicaUpdateRefsRequest req
+ );
/*****************/
/* Function 0x05 */
+ typedef bitmap {
+ DRSUAPI_DS_REPLICA_ADD_ASYNCHRONOUS_OPERATION = 0x00000001,
+ DRSUAPI_DS_REPLICA_ADD_WRITEABLE = 0x00000002
+ /* TODO ... */
+ } drsuapi_DsReplicaAddOptions;
+
WERROR DRSUAPI_REPLICA_ADD();
/*****************/
/* Function 0x06 */
+ typedef bitmap {
+ DRSUAPI_DS_REPLICA_DELETE_ASYNCHRONOUS_OPERATION = 0x00000001,
+ DRSUAPI_DS_REPLICA_DELETE_WRITEABLE = 0x00000002
+ /* TODO ... */
+ } drsuapi_DsReplicaDeleteOptions;
+
WERROR DRSUAPI_REPLICA_DEL();
/*****************/
/* Function 0x07 */
+ typedef bitmap {
+ DRSUAPI_DS_REPLICA_MODIFY_ASYNCHRONOUS_OPERATION = 0x00000001,
+ DRSUAPI_DS_REPLICA_MODIFY_WRITEABLE = 0x00000002
+ } drsuapi_DsReplicaModifyOptions;
+
WERROR DRSUAPI_REPLICA_MODIFY();
/*****************/
@@ -369,7 +469,7 @@ interface drsuapi
/*****************/
/* Function 0x11 */
- WERROR DRSUAPI_ADD_ENTRY();
+ WERROR drsuapi_DsAddEntry();
/*****************/
/* Function 0x12 */
@@ -486,12 +586,29 @@ interface drsuapi
[size_is(count)] drsuapi_DsReplicaKccDsaFailure array[];
} drsuapi_DsReplicaKccDsaFailuresCtr;
+ typedef enum {
+ DRSUAPI_DS_REPLICA_OP_TYPE_SYNC = 0,
+ DRSUAPI_DS_REPLICA_OP_TYPE_ADD = 1,
+ DRSUAPI_DS_REPLICA_OP_TYPE_DELETE = 2,
+ DRSUAPI_DS_REPLICA_OP_TYPE_MODIFY = 3,
+ DRSUAPI_DS_REPLICA_OP_TYPE_UPDATE_REFS = 4
+ } drsuapi_DsReplicaOpType;
+
+ typedef [switch_type(drsuapi_DsReplicaOpType)] union {
+ [case(DRSUAPI_DS_REPLICA_OP_TYPE_SYNC)] drsuapi_DsReplicaSyncOptions sync;
+ [case(DRSUAPI_DS_REPLICA_OP_TYPE_ADD)] drsuapi_DsReplicaAddOptions add;
+ [case(DRSUAPI_DS_REPLICA_OP_TYPE_DELETE)] drsuapi_DsReplicaDeleteOptions delete;
+ [case(DRSUAPI_DS_REPLICA_OP_TYPE_MODIFY)] drsuapi_DsReplicaModifyOptions modify;
+ [case(DRSUAPI_DS_REPLICA_OP_TYPE_UPDATE_REFS)] drsuapi_DsReplicaUpdateRefsOptions update_refs;
+ [default] uint32 unknown;
+ } drsuapi_DsRplicaOpOptions;
+
typedef struct {
NTTIME operation_start;
uint32 serial_num; /* unique till reboot */
uint32 priority;
- uint16 operation_type;
- uint32 options_flags;
+ drsuapi_DsReplicaOpType operation_type;
+ [switch_is(operation_type)] drsuapi_DsRplicaOpOptions options;
unistr *nc_dn;
unistr *remote_dsa_obj_dn;
unistr *remote_dsa_address;
diff --git a/source4/rpc_server/drsuapi/dcesrv_drsuapi.c b/source4/rpc_server/drsuapi/dcesrv_drsuapi.c
index 6a1ccb00d5..13058296a5 100644
--- a/source4/rpc_server/drsuapi/dcesrv_drsuapi.c
+++ b/source4/rpc_server/drsuapi/dcesrv_drsuapi.c
@@ -110,20 +110,20 @@ static WERROR drsuapi_DsReplicaSync(struct dcesrv_call_state *dce_call, TALLOC_C
/*
- DRSUAPI_GET_NC_CHANGES
+ drsuapi_DsGetNCChanges
*/
-static WERROR DRSUAPI_GET_NC_CHANGES(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
- struct DRSUAPI_GET_NC_CHANGES *r)
+static WERROR drsuapi_DsGetNCChanges(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
+ struct drsuapi_DsGetNCChanges *r)
{
DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
}
/*
- DRSUAPI_UPDATE_REFS
+ drsuapi_DsReplicaUpdateRefs
*/
-static WERROR DRSUAPI_UPDATE_REFS(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
- struct DRSUAPI_UPDATE_REFS *r)
+static WERROR drsuapi_DsReplicaUpdateRefs(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
+ struct drsuapi_DsReplicaUpdateRefs *r)
{
DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
}
@@ -246,10 +246,10 @@ static WERROR drsuapi_DsGetDomainControllerInfo(struct dcesrv_call_state *dce_ca
/*
- DRSUAPI_ADD_ENTRY
+ drsuapi_DsAddEntry
*/
-static WERROR DRSUAPI_ADD_ENTRY(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
- struct DRSUAPI_ADD_ENTRY *r)
+static WERROR drsuapi_DsAddEntry(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
+ struct drsuapi_DsAddEntry *r)
{
DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
}
diff --git a/source4/torture/rpc/drsuapi.c b/source4/torture/rpc/drsuapi.c
index e10c088e36..a6c0f5b9c6 100644
--- a/source4/torture/rpc/drsuapi.c
+++ b/source4/torture/rpc/drsuapi.c
@@ -29,6 +29,7 @@ struct DsPrivate {
struct GUID bind_guid;
const char *domain_obj_dn;
const char *domain_guid_str;
+ const char *domain_dns_name;
struct GUID domain_guid;
struct drsuapi_DsGetDCInfo2 dcinfo;
};
@@ -133,6 +134,7 @@ static BOOL test_DsCrackNames(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
return ret;
}
+ priv->domain_dns_name = r.out.ctr.ctr1->array[0].dns_domain_name;
priv->domain_guid_str = r.out.ctr.ctr1->array[0].result_name;
GUID_from_string(priv->domain_guid_str, &priv->domain_guid);
@@ -780,21 +782,20 @@ static BOOL test_DsReplicaSync(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
r.in.bind_handle = &priv->bind_handle;
for (i=0; i < ARRAY_SIZE(array); i++) {
- printf("testing DsReplicaGetInfo level %d\n",
+ printf("testing DsReplicaSync level %d\n",
array[i].level);
r.in.level = array[i].level;
switch(r.in.level) {
case 1:
r.in.req.req1.info = &info1;
- r.in.req.req1.info->unknown1 = 32;
- r.in.req.req1.info->unknown2 = 120;
+ r.in.req.req1.info->unknown1 = 0;
ZERO_STRUCT(r.in.req.req1.info->guid1);
- ZERO_STRUCT(r.in.req.req1.info->unknown3);
+ ZERO_STRUCT(r.in.req.req1.info->byte_array);
r.in.req.req1.info->nc_dn = priv->domain_obj_dn?priv->domain_obj_dn:"";
r.in.req.req1.guid1 = priv->dcinfo.ntds_guid;
r.in.req.req1.string1 = NULL;
- r.in.req.req1.unknown1 = 16;
+ r.in.req.req1.options = 16;
break;
}
@@ -815,6 +816,63 @@ static BOOL test_DsReplicaSync(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
return ret;
}
+static BOOL test_DsReplicaUpdateRefs(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
+ struct DsPrivate *priv)
+{
+ NTSTATUS status;
+ BOOL ret = True;
+ int i;
+ struct drsuapi_DsReplicaUpdateRefs r;
+ struct GUID null_guid;
+ struct {
+ int32_t level;
+ } array[] = {
+ {
+ 1
+ }
+ };
+
+ ZERO_STRUCT(null_guid);
+
+ r.in.bind_handle = &priv->bind_handle;
+
+ for (i=0; i < ARRAY_SIZE(array); i++) {
+ printf("testing DsReplicaUpdateRefs level %d\n",
+ array[i].level);
+
+ 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",
+ priv->domain_dns_name);
+ break;
+ }
+
+ status = dcerpc_drsuapi_DsReplicaUpdateRefs(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_DsReplicaUpdateRefs failed - %s\n", errstr);
+ ret = False;
+ } else if (!W_ERROR_IS_OK(r.out.result)) {
+ printf("DsReplicaUpdateRefs 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)
{
@@ -877,6 +935,8 @@ BOOL torture_rpc_drsuapi(void)
ret &= test_DsReplicaSync(p, mem_ctx, &priv);
+ ret &= test_DsReplicaUpdateRefs(p, mem_ctx, &priv);
+
ret &= test_DsUnbind(p, mem_ctx, &priv);
talloc_free(mem_ctx);