Example #1
0
struct dnsserver_serverinfo *dnsserver_init_serverinfo(TALLOC_CTX *mem_ctx,
							struct loadparm_context *lp_ctx,
							struct ldb_context *samdb)
{
	struct dnsserver_serverinfo *serverinfo;
	struct dcerpc_server_info *dinfo;
	struct ldb_dn *domain_dn, *forest_dn;
	struct interface *ifaces;
	int num_interfaces, i;

	serverinfo = talloc_zero(mem_ctx, struct dnsserver_serverinfo);
	if (serverinfo == NULL) {
		return NULL;
	}

	dinfo = lpcfg_dcerpc_server_info(mem_ctx, lp_ctx);
	if (dinfo) {
		serverinfo->dwVersion = (dinfo->version_build & 0x0000FFFF) << 16 |
				(dinfo->version_minor & 0x000000FF) << 8 |
				(dinfo->version_major & 0x000000FF);
		talloc_free(dinfo);
	} else {
		serverinfo->dwVersion = 0x0ECE0205; /* build, os_minor, os_major */;
	}

	serverinfo->fBootMethod = DNS_BOOT_METHOD_DIRECTORY;
	serverinfo->fAdminConfigured = 0;
	serverinfo->fAllowUpdate = 1;
	serverinfo->fDsAvailable = 1;

	serverinfo->pszServerName = talloc_asprintf(mem_ctx, "%s.%s",
					lpcfg_netbios_name(lp_ctx),
					lpcfg_dnsdomain(lp_ctx));

	domain_dn = ldb_get_default_basedn(samdb);
	forest_dn = ldb_get_root_basedn(samdb);

	serverinfo->pszDsContainer = talloc_asprintf(mem_ctx,
					"CN=MicrosoftDNS,DC=DomainDnsZones,%s",
					ldb_dn_get_linearized(domain_dn));

	serverinfo->dwDsForestVersion = dsdb_forest_functional_level(samdb);
	serverinfo->dwDsDomainVersion = dsdb_functional_level(samdb);
	serverinfo->dwDsDsaVersion = 4; /* need to do ldb search here */

	serverinfo->pszDomainName = samdb_dn_to_dns_domain(mem_ctx, domain_dn);
	serverinfo->pszForestName = samdb_dn_to_dns_domain(mem_ctx, forest_dn);

	serverinfo->pszDomainDirectoryPartition = talloc_asprintf(mem_ctx,
							"DC=DomainDnsZones,%s",
							ldb_dn_get_linearized(domain_dn));
	serverinfo->pszForestDirectoryPartition = talloc_asprintf(mem_ctx,
							"DC=ForestDnsZones,%s",
							ldb_dn_get_linearized(forest_dn));

	load_interface_list(mem_ctx, lp_ctx, &ifaces);
	num_interfaces = iface_list_count(ifaces);

	serverinfo->aipServerAddrs = talloc_zero(mem_ctx, struct IP4_ARRAY);

	if (serverinfo->aipServerAddrs) {
		serverinfo->aipServerAddrs->AddrCount = num_interfaces;
		if (num_interfaces > 0) {
			serverinfo->aipServerAddrs->AddrArray = talloc_zero_array(mem_ctx,
									unsigned int,
									num_interfaces);
			if (serverinfo->aipServerAddrs->AddrArray) {
				for (i=0; i<num_interfaces; i++) {
					serverinfo->aipServerAddrs->AddrArray[i] = inet_addr(iface_list_n_ip(ifaces, i));
				}
			} else {
				serverinfo->aipServerAddrs->AddrCount = 0;
			}
		}
Example #2
0
/*
  work out the principal to use for DRS replication connections
 */
NTSTATUS dreplsrv_get_target_principal(struct dreplsrv_service *s,
				       TALLOC_CTX *mem_ctx,
				       const struct repsFromTo1 *rft,
				       const char **target_principal)
{
	TALLOC_CTX *tmp_ctx;
	struct ldb_result *res;
	const char *attrs_server[] = { "dNSHostName", NULL };
	const char *attrs_ntds[] = { "msDS-HasDomainNCs", "hasMasterNCs", NULL };
	int ret;
	const char *hostname, *dnsdomain=NULL;
	struct ldb_dn *ntds_dn, *server_dn;
	struct ldb_dn *forest_dn, *nc_dn;

	*target_principal = NULL;

	tmp_ctx = talloc_new(mem_ctx);

	/* we need to find their hostname */
	ret = dsdb_find_dn_by_guid(s->samdb, tmp_ctx, &rft->source_dsa_obj_guid, &ntds_dn);
	if (ret != LDB_SUCCESS) {
		talloc_free(tmp_ctx);
		/* its OK for their NTDSDSA DN not to be in our database */
		return NT_STATUS_OK;
	}

	server_dn = ldb_dn_copy(tmp_ctx, ntds_dn);
	if (server_dn == NULL) {
		talloc_free(tmp_ctx);
		return NT_STATUS_OK;
	}

	/* strip off the NTDS Settings */
	if (!ldb_dn_remove_child_components(server_dn, 1)) {
		talloc_free(tmp_ctx);
		return NT_STATUS_OK;
	}

	ret = dsdb_search_dn(s->samdb, tmp_ctx, &res, server_dn, attrs_server, 0);
	if (ret != LDB_SUCCESS) {
		talloc_free(tmp_ctx);
		/* its OK for their server DN not to be in our database */
		return NT_STATUS_OK;
	}

	forest_dn = ldb_get_root_basedn(s->samdb);
	if (forest_dn == NULL) {
		talloc_free(tmp_ctx);
		return NT_STATUS_OK;
	}

	hostname = ldb_msg_find_attr_as_string(res->msgs[0], "dNSHostName", NULL);
	if (hostname != NULL) {
		char *local_principal;

		/*
		  if we have the dNSHostName attribute then we can use
		  the GC/hostname/realm SPN. All DCs should have this SPN

		  Windows DC may set up it's dNSHostName before setting up
		  GC/xx/xx SPN. So make sure it exists, before using it.
		 */
		local_principal = talloc_asprintf(mem_ctx, "GC/%s/%s",
						    hostname,
						    samdb_dn_to_dns_domain(tmp_ctx, forest_dn));
		if (dreplsrv_spn_exists(s->samdb, ntds_dn, local_principal)) {
			*target_principal = local_principal;
			talloc_free(tmp_ctx);
			return NT_STATUS_OK;
		}

		talloc_free(local_principal);
	}

	/*
	   if we can't find the dNSHostName then we will try for the
	   E3514235-4B06-11D1-AB04-00C04FC2DCD2/${NTDSGUID}/${DNSDOMAIN}
	   SPN. To use that we need the DNS domain name of the target
	   DC. We find that by first looking for the msDS-HasDomainNCs
	   in the NTDSDSA object of the DC, and if we don't find that,
	   then we look for the hasMasterNCs attribute, and eliminate
	   the known schema and configuruation DNs. Despite how
	   bizarre this seems, Hongwei tells us that this is in fact
	   what windows does to find the SPN!!
	*/
	ret = dsdb_search_dn(s->samdb, tmp_ctx, &res, ntds_dn, attrs_ntds, 0);
	if (ret != LDB_SUCCESS) {
		talloc_free(tmp_ctx);
		return NT_STATUS_OK;
	}

	nc_dn = ldb_msg_find_attr_as_dn(s->samdb, tmp_ctx, res->msgs[0], "msDS-HasDomainNCs");
	if (nc_dn != NULL) {
		dnsdomain = samdb_dn_to_dns_domain(tmp_ctx, nc_dn);
	}

	if (dnsdomain == NULL) {
		struct ldb_message_element *el;
		int i;
		el = ldb_msg_find_element(res->msgs[0], "hasMasterNCs");
		for (i=0; el && i<el->num_values; i++) {
			nc_dn = ldb_dn_from_ldb_val(tmp_ctx, s->samdb, &el->values[i]);
			if (nc_dn == NULL ||
			    ldb_dn_compare(ldb_get_config_basedn(s->samdb), nc_dn) == 0 ||
			    ldb_dn_compare(ldb_get_schema_basedn(s->samdb), nc_dn) == 0) {
				continue;
			}
			/* it must be a domain DN, get the equivalent
			   DNS domain name */
			dnsdomain = samdb_dn_to_dns_domain(tmp_ctx, nc_dn);
			break;
		}
	}

	if (dnsdomain != NULL) {
		*target_principal = talloc_asprintf(mem_ctx,
						    "E3514235-4B06-11D1-AB04-00C04FC2DCD2/%s/%s",
						    GUID_string(tmp_ctx, &rft->source_dsa_obj_guid),
						    dnsdomain);
	}

	talloc_free(tmp_ctx);
	return NT_STATUS_OK;
}
Example #3
0
/*
  work out the principal to use for DRS replication connections
 */
NTSTATUS dreplsrv_get_target_principal(struct dreplsrv_service *s,
				       TALLOC_CTX *mem_ctx,
				       const struct repsFromTo1 *rft,
				       const char **target_principal)
{
	TALLOC_CTX *tmp_ctx;
	struct ldb_result *res;
	const char *attrs[] = { "dNSHostName", NULL };
	int ret;
	const char *hostname;
	struct ldb_dn *dn;
	struct ldb_dn *forest_dn;

	*target_principal = NULL;

	tmp_ctx = talloc_new(mem_ctx);

	/* we need to find their hostname */
	ret = dsdb_find_dn_by_guid(s->samdb, tmp_ctx, &rft->source_dsa_obj_guid, &dn);
	if (ret != LDB_SUCCESS) {
		talloc_free(tmp_ctx);
		/* its OK for their NTDSDSA DN not to be in our database */
		return NT_STATUS_OK;
	}

	/* strip off the NTDS Settings */
	if (!ldb_dn_remove_child_components(dn, 1)) {
		talloc_free(tmp_ctx);
		return NT_STATUS_OK;
	}

	ret = dsdb_search_dn(s->samdb, tmp_ctx, &res, dn, attrs, 0);
	if (ret != LDB_SUCCESS) {
		talloc_free(tmp_ctx);
		/* its OK for their account DN not to be in our database */
		return NT_STATUS_OK;
	}

	hostname = ldb_msg_find_attr_as_string(res->msgs[0], "dNSHostName", NULL);
	if (hostname == NULL) {
		talloc_free(tmp_ctx);
		/* its OK to not have a dnshostname */
		return NT_STATUS_OK;
	}

	/* All DCs have the GC/hostname/realm name, but if some of the
	 * preconditions are not satisfied, then we will fall back to
	 * the
	 * E3514235-4B06-11D1-AB04-00C04FC2DCD2/${NTDSGUID}/${DNSDOMAIN}
	 * name.  This means that if a AD server has a dnsHostName set
	 * on it's record, it must also have GC/hostname/realm
	 * servicePrincipalName */

	forest_dn = ldb_get_root_basedn(s->samdb);
	if (forest_dn == NULL) {
		talloc_free(tmp_ctx);
		return NT_STATUS_OK;
	}

	*target_principal = talloc_asprintf(mem_ctx, "GC/%s/%s",
					    hostname,
					    samdb_dn_to_dns_domain(tmp_ctx, forest_dn));
	talloc_free(tmp_ctx);
	return NT_STATUS_OK;
}