1
0
mirror of https://github.com/samba-team/samba.git synced 2025-01-11 05:18:09 +03:00

s4:rpc-dnsserver: Implement DirectoryPartitionInfo RPC operation

This commit is contained in:
Amitay Isaacs 2011-12-16 12:11:42 +11:00
parent 07639b5023
commit 3d139b49cb
3 changed files with 151 additions and 1 deletions

View File

@ -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) {

View File

@ -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)

View File

@ -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,