summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAmitay Isaacs <amitay@gmail.com>2011-12-15 17:44:32 +1100
committerAmitay Isaacs <amitay@gmail.com>2011-12-23 16:17:09 +1100
commit5673e2cec946502da84956f866658718e7632a3e (patch)
treeee9a38f49b49d6d7fcdedd2e83ec52eaa1e8ccdf
parent9f76e076fa2593fdc67c3b82fb262670154bad09 (diff)
downloadsamba-5673e2cec946502da84956f866658718e7632a3e.tar.gz
samba-5673e2cec946502da84956f866658718e7632a3e.tar.bz2
samba-5673e2cec946502da84956f866658718e7632a3e.zip
s4:rpc-dnsserver: Cache DNS partition information
This information will be used for the RPC calls for partition information.
-rw-r--r--source4/rpc_server/dnsserver/dcerpc_dnsserver.c67
-rw-r--r--source4/rpc_server/dnsserver/dnsdb.c96
-rw-r--r--source4/rpc_server/dnsserver/dnsserver.h24
-rw-r--r--source4/rpc_server/dnsserver/dnsutils.c53
4 files changed, 151 insertions, 89 deletions
diff --git a/source4/rpc_server/dnsserver/dcerpc_dnsserver.c b/source4/rpc_server/dnsserver/dcerpc_dnsserver.c
index 98e935ca99..715b8a6c37 100644
--- a/source4/rpc_server/dnsserver/dcerpc_dnsserver.c
+++ b/source4/rpc_server/dnsserver/dcerpc_dnsserver.c
@@ -31,6 +31,7 @@
struct dnsserver_state {
struct loadparm_context *lp_ctx;
struct ldb_context *samdb;
+ struct dnsserver_partition *partitions;
struct dnsserver_zone *zones;
int zones_count;
struct dnsserver_serverinfo *serverinfo;
@@ -42,7 +43,8 @@ struct dnsserver_state {
static struct dnsserver_state *dnsserver_connect(struct dcesrv_call_state *dce_call)
{
struct dnsserver_state *dsstate;
- struct dnsserver_zone *zones, *z;
+ struct dnsserver_zone *zones, *z, *znext;
+ struct dnsserver_partition *partitions, *p;
dsstate = talloc_get_type(dce_call->context->private_data, struct dnsserver_state);
if (dsstate != NULL) {
@@ -72,31 +74,30 @@ static struct dnsserver_state *dnsserver_connect(struct dcesrv_call_state *dce_c
goto failed;
}
- /* Search for DNS zones */
- zones = dnsserver_db_enumerate_zones(dsstate, dsstate->samdb, true);
- if (zones == NULL) {
+ /* Search for DNS partitions */
+ partitions = dnsserver_db_enumerate_partitions(dsstate, dsstate->serverinfo, dsstate->samdb);
+ if (partitions == NULL) {
goto failed;
}
- for (z = zones; z; z = z->next) {
- z->zoneinfo = dnsserver_init_zoneinfo(z, dsstate->serverinfo, true);
- if (z->zoneinfo == NULL) {
- goto failed;
- }
- DLIST_ADD_END(dsstate->zones, z, NULL);
- dsstate->zones_count++;
- }
+ dsstate->partitions = partitions;
- zones = dnsserver_db_enumerate_zones(dsstate, dsstate->samdb, false);
- if (zones == NULL) {
- goto failed;
- }
- for (z = zones; z; z = z->next) {
- z->zoneinfo = dnsserver_init_zoneinfo(z, dsstate->serverinfo, false);
- if (z->zoneinfo == NULL) {
+ /* Search for DNS zones */
+ for (p = partitions; p; p = p->next) {
+ zones = dnsserver_db_enumerate_zones(dsstate, dsstate->samdb, p);
+ if (zones == NULL) {
goto failed;
}
- DLIST_ADD_END(dsstate->zones, z, NULL);
- dsstate->zones_count++;
+ for (z = zones; z; ) {
+ znext = z->next;
+ z->zoneinfo = dnsserver_init_zoneinfo(z, dsstate->serverinfo);
+ if (z->zoneinfo == NULL) {
+ goto failed;
+ }
+ DLIST_ADD_END(dsstate->zones, z, NULL);
+ p->zones_count++;
+ dsstate->zones_count++;
+ z = znext;
+ }
}
dce_call->context->private_data = dsstate;
@@ -773,8 +774,8 @@ static WERROR dnsserver_query_zone(struct dnsserver_state *dsstate,
r->Zone->Flags = zoneinfo->Flags;
r->Zone->ZoneType = zoneinfo->dwZoneType;
r->Zone->Version = zoneinfo->Version;
- r->Zone->dwDpFlags = zoneinfo->dwDpFlags;
- r->Zone->pszDpFqdn = talloc_strdup(mem_ctx, zoneinfo->pszDpFqdn);
+ r->Zone->dwDpFlags = z->partition->dwDpFlags;
+ r->Zone->pszDpFqdn = talloc_strdup(mem_ctx, z->partition->pszDpFqdn);
}
return WERR_OK;
}
@@ -835,8 +836,8 @@ static WERROR dnsserver_query_zone(struct dnsserver_state *dsstate,
r->ZoneInfoDotNet->dwForwarderTimeout = zoneinfo->dwForwarderTimeout;
r->ZoneInfoDotNet->fForwarderSlave = zoneinfo->fForwarderSlave;
r->ZoneInfoDotNet->aipLocalMasters = ip4_array_copy(mem_ctx, zoneinfo->aipLocalMasters);
- r->ZoneInfoDotNet->dwDpFlags = zoneinfo->dwDpFlags;
- r->ZoneInfoDotNet->pszDpFqdn = talloc_strdup(mem_ctx, zoneinfo->pszDpFqdn);
+ r->ZoneInfoDotNet->dwDpFlags = z->partition->dwDpFlags;
+ r->ZoneInfoDotNet->pszDpFqdn = talloc_strdup(mem_ctx, z->partition->pszDpFqdn);
r->ZoneInfoDotNet->pwszZoneDn = talloc_strdup(mem_ctx, zoneinfo->pwszZoneDn);
r->ZoneInfoDotNet->dwLastSuccessfulSoaCheck = zoneinfo->dwLastSuccessfulSoaCheck;
r->ZoneInfoDotNet->dwLastSuccessfulXfr = zoneinfo->dwLastSuccessfulXfr;
@@ -870,8 +871,8 @@ static WERROR dnsserver_query_zone(struct dnsserver_state *dsstate,
r->ZoneInfo->dwForwarderTimeout = zoneinfo->dwForwarderTimeout;
r->ZoneInfo->fForwarderSlave = zoneinfo->fForwarderSlave;
r->ZoneInfo->aipLocalMasters = ip4_array_to_dns_addr_array(mem_ctx, zoneinfo->aipLocalMasters);
- r->ZoneInfo->dwDpFlags = zoneinfo->dwDpFlags;
- r->ZoneInfo->pszDpFqdn = talloc_strdup(mem_ctx, zoneinfo->pszDpFqdn);
+ r->ZoneInfo->dwDpFlags = z->partition->dwDpFlags;
+ r->ZoneInfo->pszDpFqdn = talloc_strdup(mem_ctx, z->partition->pszDpFqdn);
r->ZoneInfo->pwszZoneDn = talloc_strdup(mem_ctx, zoneinfo->pwszZoneDn);
r->ZoneInfo->dwLastSuccessfulSoaCheck = zoneinfo->dwLastSuccessfulSoaCheck;
r->ZoneInfo->dwLastSuccessfulXfr = zoneinfo->dwLastSuccessfulXfr;
@@ -998,7 +999,7 @@ static WERROR dnsserver_query_zone(struct dnsserver_state *dsstate,
answer_string = talloc_strdup(mem_ctx, zoneinfo->pszDataFile);
is_string = 1;
} else if (strcasecmp(operation, "ApplicationDirectoryPartition") == 0) {
- answer_string = talloc_strdup(mem_ctx, zoneinfo->pszDpFqdn);
+ answer_string = talloc_strdup(mem_ctx, z->partition->pszDpFqdn);
is_string = 1;
} else if (strcasecmp(operation, "BreakOnNameUpdate") == 0) {
answer_string = NULL;
@@ -1153,7 +1154,7 @@ static WERROR dnsserver_complex_operate_server(struct dnsserver_state *dsstate,
}
if (rin->Dword & DNS_ZONE_REQUEST_AUTO) {
if (z->zoneinfo->fAutoCreated
- || z->zoneinfo->dwDpFlags & DNS_DP_AUTOCREATED) {
+ || z->partition->dwDpFlags & DNS_DP_AUTOCREATED) {
found1 = true;
}
}
@@ -1202,12 +1203,12 @@ static WERROR dnsserver_complex_operate_server(struct dnsserver_state *dsstate,
}
}
if (rin->Dword & DNS_ZONE_REQUEST_DOMAIN_DP) {
- if (!(z->zoneinfo->dwDpFlags & DNS_DP_DOMAIN_DEFAULT)) {
+ if (!(z->partition->dwDpFlags & DNS_DP_DOMAIN_DEFAULT)) {
found3 = true;
}
}
if (rin->Dword & DNS_ZONE_REQUEST_FOREST_DP) {
- if (!(z->zoneinfo->dwDpFlags & DNS_DP_FOREST_DEFAULT)) {
+ if (!(z->partition->dwDpFlags & DNS_DP_FOREST_DEFAULT)) {
found3 = true;
}
}
@@ -1282,8 +1283,8 @@ static WERROR dnsserver_complex_operate_server(struct dnsserver_state *dsstate,
rout->ZoneList->ZoneArray[i]->Flags = zlist[i]->zoneinfo->Flags;
rout->ZoneList->ZoneArray[i]->ZoneType = zlist[i]->zoneinfo->dwZoneType;
rout->ZoneList->ZoneArray[i]->Version = zlist[i]->zoneinfo->Version;
- rout->ZoneList->ZoneArray[i]->dwDpFlags = zlist[i]->zoneinfo->dwDpFlags;
- rout->ZoneList->ZoneArray[i]->pszDpFqdn = talloc_strdup(mem_ctx, zlist[i]->zoneinfo->pszDpFqdn);
+ rout->ZoneList->ZoneArray[i]->dwDpFlags = zlist[i]->partition->dwDpFlags;
+ rout->ZoneList->ZoneArray[i]->pszDpFqdn = talloc_strdup(mem_ctx, zlist[i]->partition->pszDpFqdn);
}
rout->ZoneList->dwRpcStructureVersion = 1;
rout->ZoneList->dwZoneCount = zcount;
diff --git a/source4/rpc_server/dnsserver/dnsdb.c b/source4/rpc_server/dnsserver/dnsdb.c
index ffa1757fdd..a181e069b6 100644
--- a/source4/rpc_server/dnsserver/dnsdb.c
+++ b/source4/rpc_server/dnsserver/dnsdb.c
@@ -23,17 +23,65 @@
#include "dnsserver.h"
#include "lib/util/dlinklist.h"
#include "librpc/gen_ndr/ndr_dnsp.h"
+#include "dsdb/samdb/samdb.h"
+
+/* There are only 2 fixed partitions for DNS */
+struct dnsserver_partition *dnsserver_db_enumerate_partitions(TALLOC_CTX *mem_ctx,
+ struct dnsserver_serverinfo *serverinfo,
+ struct ldb_context *samdb)
+{
+ struct dnsserver_partition *partitions, *p;
+
+ partitions = NULL;
+
+ /* Domain partition */
+ p = talloc_zero(mem_ctx, struct dnsserver_partition);
+ if (p == NULL) {
+ goto failed;
+ }
+
+ p->partition_dn = ldb_dn_new(p, samdb, serverinfo->pszDomainDirectoryPartition);
+ if (p->partition_dn == NULL) {
+ goto failed;
+ }
+
+ p->pszDpFqdn = samdb_dn_to_dns_domain(p, p->partition_dn);
+ p->dwDpFlags = DNS_DP_AUTOCREATED | DNS_DP_DOMAIN_DEFAULT | DNS_DP_ENLISTED;
+ p->is_forest = false;
+
+ DLIST_ADD_END(partitions, p, NULL);
+
+ /* Forest Partition */
+ p = talloc_zero(mem_ctx, struct dnsserver_partition);
+ if (p == NULL) {
+ goto failed;
+ }
+
+ p->partition_dn = ldb_dn_new(p, samdb, serverinfo->pszForestDirectoryPartition);
+ if (p->partition_dn == NULL) {
+ goto failed;
+ }
+
+ p->pszDpFqdn = samdb_dn_to_dns_domain(p, p->partition_dn);
+ p->dwDpFlags = DNS_DP_AUTOCREATED | DNS_DP_FOREST_DEFAULT | DNS_DP_ENLISTED;
+ p->is_forest = true;
+
+ DLIST_ADD_END(partitions, p, NULL);
+
+ return partitions;
+
+failed:
+ return NULL;
+
+}
struct dnsserver_zone *dnsserver_db_enumerate_zones(TALLOC_CTX *mem_ctx,
struct ldb_context *samdb,
- bool is_forest)
+ struct dnsserver_partition *p)
{
TALLOC_CTX *tmp_ctx;
- const char *domain_prefix = "DC=DomainDnsZones";
- const char *forest_prefix = "DC=ForestDnsZones";
- const char *prefix;
const char * const attrs[] = {"name", NULL};
- struct ldb_dn *dn_base, *partition_dn, *dn;
+ struct ldb_dn *dn;
struct ldb_result *res;
struct dnsserver_zone *zones, *z;
int i, ret;
@@ -43,28 +91,7 @@ struct dnsserver_zone *dnsserver_db_enumerate_zones(TALLOC_CTX *mem_ctx,
return NULL;
}
- if (is_forest) {
- dn_base = ldb_get_root_basedn(samdb);
- } else {
- dn_base = ldb_get_default_basedn(samdb);
- }
-
- partition_dn = ldb_dn_copy(tmp_ctx, dn_base);
- if (partition_dn == NULL) {
- goto failed;
- }
-
- if (is_forest) {
- prefix = forest_prefix;
- } else {
- prefix = domain_prefix;
- }
-
- if (!ldb_dn_add_child_fmt(partition_dn, "%s", prefix)) {
- goto failed;
- }
-
- dn = ldb_dn_copy(tmp_ctx, partition_dn);
+ dn = ldb_dn_copy(tmp_ctx, p->partition_dn);
if (dn == NULL) {
goto failed;
}
@@ -73,7 +100,7 @@ struct dnsserver_zone *dnsserver_db_enumerate_zones(TALLOC_CTX *mem_ctx,
}
ret = ldb_search(samdb, tmp_ctx, &res, dn, LDB_SCOPE_SUBTREE,
- attrs, "(&(objectClass=dnsZone)(!(name=RootDNSServers)))");
+ attrs, "(objectClass=dnsZone)");
if (ret != LDB_SUCCESS) {
DEBUG(0, ("dnsserver: Failed to find DNS Zones in %s\n",
ldb_dn_get_linearized(dn)));
@@ -82,18 +109,25 @@ struct dnsserver_zone *dnsserver_db_enumerate_zones(TALLOC_CTX *mem_ctx,
zones = NULL;
for(i=0; i<res->count; i++) {
+ char *name;
z = talloc_zero(mem_ctx, struct dnsserver_zone);
if (z == NULL) {
goto failed;
}
- z->name = talloc_strdup(z,
+ z->partition = p;
+ name = talloc_strdup(z,
ldb_msg_find_attr_as_string(res->msgs[i], "name", NULL));
- DEBUG(2, ("dnsserver: Found DNS zone %s\n", z->name));
+ if (strcmp(name, "RootDNSServers") == 0) {
+ talloc_free(name);
+ z->name = talloc_strdup(z, ".");
+ } else {
+ z->name = name;
+ }
z->zone_dn = talloc_steal(z, res->msgs[i]->dn);
- z->partition_dn = talloc_steal(z, partition_dn);
DLIST_ADD_END(zones, z, NULL);
+ DEBUG(2, ("dnsserver: Found DNS zone %s\n", z->name));
}
return zones;
diff --git a/source4/rpc_server/dnsserver/dnsserver.h b/source4/rpc_server/dnsserver/dnsserver.h
index 818dc60b62..938f2f4b01 100644
--- a/source4/rpc_server/dnsserver/dnsserver.h
+++ b/source4/rpc_server/dnsserver/dnsserver.h
@@ -126,8 +126,6 @@ struct dnsserver_zoneinfo {
struct IP4_ARRAY * aipLocalMasters;
- uint32_t dwDpFlags;
- char * pszDpFqdn;
char * pwszZoneDn;
uint32_t dwLastSuccessfulSoaCheck;
@@ -142,10 +140,20 @@ struct dnsserver_zoneinfo {
};
+struct dnsserver_partition {
+ struct dnsserver_partition *prev, *next;
+ struct ldb_dn *partition_dn;
+ const char *pszDpFqdn;
+ uint32_t dwDpFlags;
+ bool is_forest;
+ int zones_count;
+};
+
+
struct dnsserver_zone {
struct dnsserver_zone *prev, *next;
+ struct dnsserver_partition *partition;
const char *name;
- struct ldb_dn *partition_dn;
struct ldb_dn *zone_dn;
struct dnsserver_zoneinfo *zoneinfo;
};
@@ -192,8 +200,9 @@ struct dnsserver_serverinfo *dnsserver_init_serverinfo(TALLOC_CTX *mem_ctx,
struct loadparm_context *lp_ctx,
struct ldb_context *samdb);
struct dnsserver_zoneinfo *dnsserver_init_zoneinfo(struct dnsserver_zone *zone,
- struct dnsserver_serverinfo *serverinfo,
- bool is_forest);
+ struct dnsserver_serverinfo *serverinfo);
+struct dnsserver_partition *dnsserver_find_partition(struct dnsserver_partition *partitions,
+ const char *dp_fqdn);
struct dnsserver_zone *dnsserver_find_zone(struct dnsserver_zone *zones,
const char *zone_name);
struct ldb_dn *dnsserver_name_to_dn(TALLOC_CTX *mem_ctx, struct dnsserver_zone *z,
@@ -203,9 +212,12 @@ uint32_t dnsserver_zone_to_request_filter(const char *zone);
/* Database functions from dnsdb.c */
+struct dnsserver_partition *dnsserver_db_enumerate_partitions(TALLOC_CTX *mem_ctx,
+ struct dnsserver_serverinfo *serverinfo,
+ struct ldb_context *samdb);
struct dnsserver_zone *dnsserver_db_enumerate_zones(TALLOC_CTX *mem_ctx,
struct ldb_context *samdb,
- bool is_forest);
+ struct dnsserver_partition *p);
WERROR dnsserver_db_add_empty_node(TALLOC_CTX *mem_ctx,
struct ldb_context *samdb,
struct dnsserver_zone *z,
diff --git a/source4/rpc_server/dnsserver/dnsutils.c b/source4/rpc_server/dnsserver/dnsutils.c
index 3ae47a8c5f..5390384e57 100644
--- a/source4/rpc_server/dnsserver/dnsutils.c
+++ b/source4/rpc_server/dnsserver/dnsutils.c
@@ -154,11 +154,9 @@ struct dnsserver_serverinfo *dnsserver_init_serverinfo(TALLOC_CTX *mem_ctx,
struct dnsserver_zoneinfo *dnsserver_init_zoneinfo(struct dnsserver_zone *zone,
- struct dnsserver_serverinfo *serverinfo,
- bool is_forest)
+ struct dnsserver_serverinfo *serverinfo)
{
struct dnsserver_zoneinfo *zoneinfo;
- uint32_t dp_flags;
uint32_t fReverse;
const char *revzone = "in-addr.arpa";
int len1, len2;
@@ -168,13 +166,6 @@ struct dnsserver_zoneinfo *dnsserver_init_zoneinfo(struct dnsserver_zone *zone,
return NULL;
}
- dp_flags = DNS_DP_AUTOCREATED | DNS_DP_ENLISTED;
- if (is_forest) {
- dp_flags |= DNS_DP_FOREST_DEFAULT;
- } else {
- dp_flags |= DNS_DP_DOMAIN_DEFAULT;
- }
-
/* If the zone name ends with in-addr.arpa, it's reverse zone */
fReverse = 0;
len1 = strlen(zone->name);
@@ -184,32 +175,42 @@ struct dnsserver_zoneinfo *dnsserver_init_zoneinfo(struct dnsserver_zone *zone,
}
zoneinfo->Version = 0x32;
- zoneinfo->Flags = DNS_RPC_ZONE_DSINTEGRATED | DNS_RPC_ZONE_UPDATE_SECURE;
- zoneinfo->dwZoneType = DNS_ZONE_TYPE_PRIMARY;
+ zoneinfo->Flags = DNS_RPC_ZONE_DSINTEGRATED;
+
+ if (strcmp(zone->name, ".") == 0) {
+ zoneinfo->dwZoneType = DNS_ZONE_TYPE_CACHE;
+ zoneinfo->fAllowUpdate = DNS_ZONE_UPDATE_OFF;
+ zoneinfo->fSecureSecondaries = DNS_ZONE_SECSECURE_NO_SECURITY;
+ zoneinfo->fNotifyLevel = DNS_ZONE_NOTIFY_OFF;
+ zoneinfo->dwNoRefreshInterval = 0;
+ zoneinfo->dwRefreshInterval = 0;
+ } else {
+ zoneinfo->Flags |= DNS_RPC_ZONE_UPDATE_SECURE;
+ zoneinfo->dwZoneType = DNS_ZONE_TYPE_PRIMARY;
+ zoneinfo->fAllowUpdate = DNS_ZONE_UPDATE_SECURE;
+ zoneinfo->fSecureSecondaries = DNS_ZONE_SECSECURE_NO_XFER;
+ zoneinfo->fNotifyLevel = DNS_ZONE_NOTIFY_LIST_ONLY;
+ zoneinfo->dwNoRefreshInterval = serverinfo->dwDefaultNoRefreshInterval;
+ zoneinfo->dwRefreshInterval = serverinfo->dwDefaultRefreshInterval;
+ }
+
zoneinfo->fReverse = fReverse;
- zoneinfo->fAllowUpdate = DNS_ZONE_UPDATE_SECURE;
zoneinfo->fPaused = 0;
zoneinfo->fShutdown = 0;
zoneinfo->fAutoCreated = 0;
zoneinfo->fUseDatabase = 1;
zoneinfo->pszDataFile = NULL;
zoneinfo->aipMasters = NULL;
- zoneinfo->fSecureSecondaries = DNS_ZONE_SECSECURE_NO_XFER;
- zoneinfo->fNotifyLevel = DNS_ZONE_NOTIFY_LIST_ONLY;
zoneinfo->aipSecondaries = NULL;
zoneinfo->aipNotify = NULL;
zoneinfo->fUseWins = 0;
zoneinfo->fUseNbstat = 0;
zoneinfo->fAging = 0;
- zoneinfo->dwNoRefreshInterval = serverinfo->dwDefaultNoRefreshInterval;
- zoneinfo->dwRefreshInterval = serverinfo->dwDefaultRefreshInterval;
zoneinfo->dwAvailForScavengeTime = 0;
zoneinfo->aipScavengeServers = NULL;
zoneinfo->dwForwarderTimeout = 0;
zoneinfo->fForwarderSlave = 0;
zoneinfo->aipLocalMasters = NULL;
- zoneinfo->dwDpFlags = dp_flags;
- zoneinfo->pszDpFqdn = samdb_dn_to_dns_domain(zone, zone->partition_dn);
zoneinfo->pwszZoneDn = discard_const_p(char, ldb_dn_get_linearized(zone->zone_dn));
zoneinfo->dwLastSuccessfulSoaCheck = 0;
zoneinfo->dwLastSuccessfulXfr = 0;
@@ -222,6 +223,20 @@ struct dnsserver_zoneinfo *dnsserver_init_zoneinfo(struct dnsserver_zone *zone,
return zoneinfo;
}
+struct dnsserver_partition *dnsserver_find_partition(struct dnsserver_partition *partitions,
+ const char *dp_fqdn)
+{
+ struct dnsserver_partition *p = NULL;
+
+ for (p = partitions; p; p = p->next) {
+ if (strcmp(dp_fqdn, p->pszDpFqdn) == 0) {
+ break;
+ }
+ }
+
+ return p;
+}
+
struct dnsserver_zone *dnsserver_find_zone(struct dnsserver_zone *zones, const char *zone_name)
{
struct dnsserver_zone *z = NULL;