summaryrefslogtreecommitdiff
path: root/source4/rpc_server
diff options
context:
space:
mode:
authorAmitay Isaacs <amitay@gmail.com>2011-12-16 12:11:42 +1100
committerAmitay Isaacs <amitay@gmail.com>2011-12-23 16:18:24 +1100
commit3d139b49cbf2d036bc59bf34f657643c1069ebc0 (patch)
treea86769a04b18e6d29605499ba3d0144984f47708 /source4/rpc_server
parent07639b502382a3c708350bdf4ca19d9437e0beaa (diff)
downloadsamba-3d139b49cbf2d036bc59bf34f657643c1069ebc0.tar.gz
s4:rpc-dnsserver: Implement DirectoryPartitionInfo RPC operation
Diffstat (limited to 'source4/rpc_server')
-rw-r--r--source4/rpc_server/dnsserver/dcerpc_dnsserver.c42
-rw-r--r--source4/rpc_server/dnsserver/dnsdb.c99
-rw-r--r--source4/rpc_server/dnsserver/dnsserver.h11
3 files changed, 151 insertions, 1 deletions
diff --git a/source4/rpc_server/dnsserver/dcerpc_dnsserver.c b/source4/rpc_server/dnsserver/dcerpc_dnsserver.c
index 345cfb814e8..8aaa36b6f0a 100644
--- a/source4/rpc_server/dnsserver/dcerpc_dnsserver.c
+++ b/source4/rpc_server/dnsserver/dcerpc_dnsserver.c
@@ -1329,7 +1329,47 @@ static WERROR dnsserver_complex_operate_server(struct dnsserver_state *dsstate,
}
return WERR_OK;
} else if (strcasecmp(operation, "DirectoryPartitionInfo") == 0) {
- valid_operation = true;
+ struct dnsserver_partition *p;
+ struct dnsserver_partition_info *partinfo;
+ struct DNS_RPC_DP_INFO *dpinfo = NULL;
+
+ if (typeid_in != DNSSRV_TYPEID_LPSTR) {
+ return WERR_DNS_ERROR_INVALID_PROPERTY;
+ }
+
+ *typeid_out = DNSSRV_TYPEID_DP_INFO;
+
+ for (p = dsstate->partitions; p; p = p->next) {
+ if (strcmp(p->pszDpFqdn, rin->String) == 0) {
+ dpinfo = talloc_zero(mem_ctx, struct DNS_RPC_DP_INFO);
+ W_ERROR_HAVE_NO_MEMORY(dpinfo);
+
+ partinfo = dnsserver_db_partition_info(mem_ctx, dsstate->samdb, p);
+ W_ERROR_HAVE_NO_MEMORY(partinfo);
+
+ dpinfo->pszDpFqdn = talloc_strdup(dpinfo, p->pszDpFqdn);
+ dpinfo->pszDpDn = talloc_strdup(dpinfo, ldb_dn_get_linearized(p->partition_dn));
+ dpinfo->pszCrDn = talloc_steal(dpinfo, partinfo->pszCrDn);
+ dpinfo->dwFlags = p->dwDpFlags;
+ dpinfo->dwZoneCount = p->zones_count;
+ dpinfo->dwState = partinfo->dwState;
+ dpinfo->dwReplicaCount = partinfo->dwReplicaCount;
+ if (partinfo->dwReplicaCount > 0) {
+ dpinfo->ReplicaArray = talloc_steal(dpinfo,
+ partinfo->ReplicaArray);
+ } else {
+ dpinfo->ReplicaArray = NULL;
+ }
+ break;
+ }
+ }
+
+ if (dpinfo == NULL) {
+ return WERR_DNS_ERROR_DP_DOES_NOT_EXIST;
+ }
+
+ rout->DirectoryPartition = dpinfo;
+ return WERR_OK;
} else if (strcasecmp(operation, "Statistics") == 0) {
valid_operation = true;
} else if (strcasecmp(operation, "IpValidate") == 0) {
diff --git a/source4/rpc_server/dnsserver/dnsdb.c b/source4/rpc_server/dnsserver/dnsdb.c
index 707f7b842cd..e7bd28d3827 100644
--- a/source4/rpc_server/dnsserver/dnsdb.c
+++ b/source4/rpc_server/dnsserver/dnsdb.c
@@ -140,6 +140,105 @@ failed:
}
+/* Find DNS partition information */
+struct dnsserver_partition_info *dnsserver_db_partition_info(TALLOC_CTX *mem_ctx,
+ struct ldb_context *samdb,
+ struct dnsserver_partition *p)
+{
+ const char * const attrs[] = { "instanceType", "msDs-masteredBy", NULL };
+ const char * const attrs_none[] = { NULL };
+ struct ldb_result *res;
+ struct ldb_message_element *el;
+ struct ldb_dn *dn;
+ struct dnsserver_partition_info *partinfo;
+ int i, ret, instance_type;
+ TALLOC_CTX *tmp_ctx;
+
+ tmp_ctx = talloc_new(mem_ctx);
+ if (tmp_ctx == NULL) {
+ return NULL;
+ }
+
+ partinfo = talloc_zero(mem_ctx, struct dnsserver_partition_info);
+ if (partinfo == NULL) {
+ talloc_free(tmp_ctx);
+ return NULL;
+ }
+
+ /* Search for the active replica and state */
+ ret = ldb_search(samdb, tmp_ctx, &res, p->partition_dn, LDB_SCOPE_BASE,
+ attrs, NULL);
+ if (ret != LDB_SUCCESS || res->count != 1) {
+ goto failed;
+ }
+
+ /* Set the state of the partition */
+ instance_type = ldb_msg_find_attr_as_int(res->msgs[0], "instanceType", -1);
+ if (instance_type == -1) {
+ partinfo->dwState = DNS_DP_STATE_UNKNOWN;
+ } else if (instance_type & INSTANCE_TYPE_NC_COMING) {
+ partinfo->dwState = DNS_DP_STATE_REPL_INCOMING;
+ } else if (instance_type & INSTANCE_TYPE_NC_GOING) {
+ partinfo->dwState = DNS_DP_STATE_REPL_OUTGOING;
+ } else {
+ partinfo->dwState = DNS_DP_OKAY;
+ }
+
+ el = ldb_msg_find_element(res->msgs[0], "msDs-masteredBy");
+ if (el == NULL) {
+ partinfo->dwReplicaCount = 0;
+ partinfo->ReplicaArray = NULL;
+ } else {
+ partinfo->dwReplicaCount = el->num_values;
+ partinfo->ReplicaArray = talloc_zero_array(partinfo,
+ struct DNS_RPC_DP_REPLICA *,
+ el->num_values);
+ if (partinfo->ReplicaArray == NULL) {
+ goto failed;
+ }
+ for (i=0; i<el->num_values; i++) {
+ partinfo->ReplicaArray[i] = talloc_zero(partinfo,
+ struct DNS_RPC_DP_REPLICA);
+ if (partinfo->ReplicaArray[i] == NULL) {
+ goto failed;
+ }
+ partinfo->ReplicaArray[i]->pszReplicaDn = talloc_strdup(
+ partinfo,
+ (const char *)el->values[i].data);
+ if (partinfo->ReplicaArray[i]->pszReplicaDn == NULL) {
+ goto failed;
+ }
+ }
+ }
+ talloc_free(res);
+
+ /* Search for cross-reference object */
+ dn = ldb_dn_copy(tmp_ctx, ldb_get_config_basedn(samdb));
+ if (dn == NULL) {
+ goto failed;
+ }
+
+ ret = ldb_search(samdb, tmp_ctx, &res, dn, LDB_SCOPE_DEFAULT, attrs_none,
+ "(nCName=%s)", ldb_dn_get_linearized(p->partition_dn));
+ if (ret != LDB_SUCCESS || res->count != 1) {
+ goto failed;
+ }
+ partinfo->pszCrDn = talloc_strdup(partinfo, ldb_dn_get_linearized(res->msgs[0]->dn));
+ if (partinfo->pszCrDn == NULL) {
+ goto failed;
+ }
+ talloc_free(res);
+
+ talloc_free(tmp_ctx);
+ return partinfo;
+
+failed:
+ talloc_free(tmp_ctx);
+ talloc_free(partinfo);
+ return NULL;
+}
+
+
static unsigned int dnsserver_update_soa(TALLOC_CTX *mem_ctx,
struct ldb_context *samdb,
struct dnsserver_zone *z)
diff --git a/source4/rpc_server/dnsserver/dnsserver.h b/source4/rpc_server/dnsserver/dnsserver.h
index 938f2f4b013..63224c55c14 100644
--- a/source4/rpc_server/dnsserver/dnsserver.h
+++ b/source4/rpc_server/dnsserver/dnsserver.h
@@ -150,6 +150,14 @@ struct dnsserver_partition {
};
+struct dnsserver_partition_info {
+ const char *pszCrDn;
+ uint32_t dwState;
+ uint32_t dwReplicaCount;
+ struct DNS_RPC_DP_REPLICA **ReplicaArray;
+};
+
+
struct dnsserver_zone {
struct dnsserver_zone *prev, *next;
struct dnsserver_partition *partition;
@@ -218,6 +226,9 @@ struct dnsserver_partition *dnsserver_db_enumerate_partitions(TALLOC_CTX *mem_ct
struct dnsserver_zone *dnsserver_db_enumerate_zones(TALLOC_CTX *mem_ctx,
struct ldb_context *samdb,
struct dnsserver_partition *p);
+struct dnsserver_partition_info *dnsserver_db_partition_info(TALLOC_CTX *mem_ctx,
+ struct ldb_context *samdb,
+ struct dnsserver_partition *p);
WERROR dnsserver_db_add_empty_node(TALLOC_CTX *mem_ctx,
struct ldb_context *samdb,
struct dnsserver_zone *z,