コード例 #1
0
ファイル: dsgetdcname.c プロジェクト: Distrotech/samba
static NTSTATUS process_dc_dns(TALLOC_CTX *mem_ctx,
			       const char *domain_name,
			       uint32_t flags,
			       struct ip_service_name *dclist,
			       int num_dcs,
			       struct netr_DsRGetDCNameInfo **info)
{
	int i = 0;
	bool valid_dc = false;
	struct netlogon_samlogon_response *r = NULL;
	uint32_t nt_version = NETLOGON_NT_VERSION_5 |
			      NETLOGON_NT_VERSION_5EX;
	uint32_t ret_flags = 0;
	NTSTATUS status;

	nt_version |= map_ds_flags_to_nt_version(flags);

	for (i=0; i<num_dcs; i++) {

		char addr[INET6_ADDRSTRLEN];
		print_sockaddr(addr, sizeof(addr), &dclist[i].ss);

		DEBUG(10,("LDAP ping to %s (%s)\n", dclist[i].hostname, addr));

		if (ads_cldap_netlogon(mem_ctx, &dclist[i].ss,
					domain_name,
					nt_version,
					&r))
		{
			nt_version = r->ntver;
			ret_flags = get_cldap_reply_server_flags(r, nt_version);

			if (check_cldap_reply_required_flags(ret_flags, flags)) {
				valid_dc = true;
				break;
			}
		}

		continue;
	}

	if (!valid_dc) {
		return NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND;
	}

	status = make_dc_info_from_cldap_reply(mem_ctx, flags, &dclist[i].ss,
					       &r->data.nt5_ex, info);
	if (NT_STATUS_IS_OK(status)) {
		return store_cldap_reply(mem_ctx, flags, &dclist[i].ss,
					 nt_version, &r->data.nt5_ex);
	}

	return status;
}
コード例 #2
0
static NTSTATUS process_dc_netbios(TALLOC_CTX *mem_ctx,
				   struct messaging_context *msg_ctx,
				   const char *domain_name,
				   uint32_t flags,
				   struct ip_service_name *dclist,
				   int num_dcs,
				   struct netr_DsRGetDCNameInfo **info)
{
	struct sockaddr_storage ss;
	struct ip_service ip_list;
	enum nbt_name_type name_type = NBT_NAME_LOGON;
	NTSTATUS status;
	int i;
	const char *dc_name = NULL;
	fstring tmp_dc_name;
	struct netlogon_samlogon_response *r = NULL;
	bool store_cache = false;
	uint32_t nt_version = NETLOGON_NT_VERSION_1 |
			      NETLOGON_NT_VERSION_5 |
			      NETLOGON_NT_VERSION_5EX_WITH_IP;

	if (!msg_ctx) {
		msg_ctx = msg_context(mem_ctx);
	}

	if (flags & DS_PDC_REQUIRED) {
		name_type = NBT_NAME_PDC;
	}

	nt_version |= map_ds_flags_to_nt_version(flags);

	DEBUG(10,("process_dc_netbios\n"));

	for (i=0; i<num_dcs; i++) {

		ip_list.ss = dclist[i].ss;
		ip_list.port = 0;

		if (!interpret_string_addr(&ss, dclist[i].hostname, AI_NUMERICHOST)) {
			return NT_STATUS_UNSUCCESSFUL;
		}

		if (send_getdc_request(mem_ctx, msg_ctx,
				       &dclist[i].ss, domain_name,
				       NULL, nt_version))
		{
			int k;
			smb_msleep(300);
			for (k=0; k<5; k++) {
				if (receive_getdc_response(mem_ctx,
							   &dclist[i].ss,
							   domain_name,
							   &nt_version,
							   &dc_name,
							   &r)) {
					store_cache = true;
					namecache_store(dc_name, NBT_NAME_SERVER, 1, &ip_list);
					goto make_reply;
				}
				smb_msleep(1500);
			}
		}

		if (name_status_find(domain_name,
				     name_type,
				     NBT_NAME_SERVER,
				     &dclist[i].ss,
				     tmp_dc_name))
		{
			struct NETLOGON_SAM_LOGON_RESPONSE_NT40 logon1;

			r = TALLOC_ZERO_P(mem_ctx, struct netlogon_samlogon_response);
			NT_STATUS_HAVE_NO_MEMORY(r);

			ZERO_STRUCT(logon1);

			nt_version = NETLOGON_NT_VERSION_1;

			logon1.nt_version = nt_version;
			logon1.server = tmp_dc_name;
			logon1.domain = talloc_strdup_upper(mem_ctx, domain_name);
			NT_STATUS_HAVE_NO_MEMORY(logon1.domain);

			r->data.nt4 = logon1;
			r->ntver = nt_version;

			map_netlogon_samlogon_response(r);

			namecache_store(tmp_dc_name, NBT_NAME_SERVER, 1, &ip_list);

			goto make_reply;
		}
	}

	return NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND;

 make_reply:

	status = make_dc_info_from_cldap_reply(mem_ctx, flags, &dclist[i].ss,
					       &r->data.nt5_ex, info);
	if (NT_STATUS_IS_OK(status) && store_cache) {
		return store_cldap_reply(mem_ctx, flags, &dclist[i].ss,
					 nt_version, &r->data.nt5_ex);
	}

	return status;
}