mirror of
https://github.com/samba-team/samba.git
synced 2025-01-08 21:18:16 +03:00
libcli: Add ads_dns_query_srv_send()/recv()
This issues the "query" for SRV records site-aware and siteless. If there are SRV records returned without IP addresses, it will issue A and AAAA requests, waiting up to async_dns_timeout seconds. If that timeout is reached, ads_dns_query_srv_recv() returns whatever is around. Superdebug added by Jeremy <jra@samba.org> :-) Signed-off-by: Volker Lendecke <vl@samba.org> Reviewed-by: Jeremy Allison <jra@samba.org>
This commit is contained in:
parent
60b96580d2
commit
31d85404fc
560
lib/addns/dnsquery_srv.c
Normal file
560
lib/addns/dnsquery_srv.c
Normal file
@ -0,0 +1,560 @@
|
||||
/*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "replace.h"
|
||||
#include "dnsquery.h"
|
||||
#include "dnsquery_srv.h"
|
||||
#include "lib/util/debug.h"
|
||||
#include "lib/util/tevent_ntstatus.h"
|
||||
#include "lib/util/talloc_stack.h"
|
||||
#include "lib/util/samba_util.h"
|
||||
#include "librpc/gen_ndr/dns.h"
|
||||
#include "librpc/ndr/libndr.h"
|
||||
|
||||
/*
|
||||
* For an array of dns_rr_srv records, issue A/AAAA queries for those
|
||||
* records where the initial reply did not return IP addresses.
|
||||
*/
|
||||
|
||||
struct dns_rr_srv_fill_state {
|
||||
struct dns_rr_srv *srvs;
|
||||
size_t num_srvs;
|
||||
|
||||
struct tevent_req **subreqs;
|
||||
size_t num_outstanding;
|
||||
};
|
||||
|
||||
static void dns_rr_srv_fill_done_a(struct tevent_req *subreq);
|
||||
#if defined(HAVE_IPV6)
|
||||
static void dns_rr_srv_fill_done_aaaa(struct tevent_req *subreq);
|
||||
#endif
|
||||
static void dns_rr_srv_fill_timedout(struct tevent_req *subreq);
|
||||
|
||||
static struct tevent_req *dns_rr_srv_fill_send(
|
||||
TALLOC_CTX *mem_ctx,
|
||||
struct tevent_context *ev,
|
||||
struct dns_rr_srv *srvs,
|
||||
size_t num_srvs,
|
||||
uint32_t timeout)
|
||||
{
|
||||
struct tevent_req *req = NULL, *subreq = NULL;
|
||||
struct dns_rr_srv_fill_state *state = NULL;
|
||||
size_t i, num_subreqs;
|
||||
|
||||
req = tevent_req_create(mem_ctx, &state, struct dns_rr_srv_fill_state);
|
||||
if (req == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
state->srvs = srvs;
|
||||
state->num_srvs = num_srvs;
|
||||
|
||||
/*
|
||||
* Without IPv6 we only use half of this, but who does not
|
||||
* have IPv6 these days?
|
||||
*/
|
||||
num_subreqs = num_srvs * 2;
|
||||
|
||||
state->subreqs = talloc_zero_array(
|
||||
state, struct tevent_req *, num_subreqs);
|
||||
if (tevent_req_nomem(state->subreqs, req)) {
|
||||
return tevent_req_post(req, ev);
|
||||
}
|
||||
|
||||
for (i=0; i<num_srvs; i++) {
|
||||
|
||||
if (srvs[i].hostname == NULL) {
|
||||
continue;
|
||||
}
|
||||
if (srvs[i].ss_s != NULL) {
|
||||
/* IP address returned in SRV record. */
|
||||
continue;
|
||||
}
|
||||
|
||||
subreq = ads_dns_lookup_a_send(
|
||||
state->subreqs, ev, srvs[i].hostname);
|
||||
if (tevent_req_nomem(subreq, req)) {
|
||||
TALLOC_FREE(state->subreqs);
|
||||
return tevent_req_post(req, ev);
|
||||
}
|
||||
tevent_req_set_callback(
|
||||
subreq, dns_rr_srv_fill_done_a, req);
|
||||
|
||||
state->subreqs[i*2] = subreq;
|
||||
state->num_outstanding += 1;
|
||||
|
||||
#if defined(HAVE_IPV6)
|
||||
subreq = ads_dns_lookup_aaaa_send(
|
||||
state->subreqs, ev, srvs[i].hostname);
|
||||
if (tevent_req_nomem(subreq, req)) {
|
||||
TALLOC_FREE(state->subreqs);
|
||||
return tevent_req_post(req, ev);
|
||||
}
|
||||
tevent_req_set_callback(
|
||||
subreq, dns_rr_srv_fill_done_aaaa, req);
|
||||
|
||||
state->subreqs[i*2+1] = subreq;
|
||||
state->num_outstanding += 1;
|
||||
#endif
|
||||
}
|
||||
|
||||
if (state->num_outstanding == 0) {
|
||||
tevent_req_done(req);
|
||||
return tevent_req_post(req, ev);
|
||||
}
|
||||
|
||||
subreq = tevent_wakeup_send(
|
||||
state->subreqs,
|
||||
ev,
|
||||
tevent_timeval_current_ofs(timeout, 0));
|
||||
if (tevent_req_nomem(subreq, req)) {
|
||||
return tevent_req_post(req, ev);
|
||||
}
|
||||
tevent_req_set_callback(subreq, dns_rr_srv_fill_timedout, req);
|
||||
|
||||
return req;
|
||||
}
|
||||
|
||||
static void dns_rr_srv_fill_done(
|
||||
struct tevent_req *subreq,
|
||||
NTSTATUS (*recv_fn)(
|
||||
struct tevent_req *req,
|
||||
TALLOC_CTX *mem_ctx,
|
||||
uint8_t *rcode_out,
|
||||
size_t *num_names_out,
|
||||
char ***hostnames_out,
|
||||
struct samba_sockaddr **addrs_out))
|
||||
{
|
||||
struct tevent_req *req = tevent_req_callback_data(
|
||||
subreq, struct tevent_req);
|
||||
struct dns_rr_srv_fill_state *state = tevent_req_data(
|
||||
req, struct dns_rr_srv_fill_state);
|
||||
size_t num_subreqs = talloc_array_length(state->subreqs);
|
||||
struct dns_rr_srv *srv = NULL;
|
||||
size_t num_ips;
|
||||
struct sockaddr_storage *tmp = NULL;
|
||||
uint8_t rcode = 0;
|
||||
char **hostnames_out = NULL;
|
||||
struct samba_sockaddr *addrs = NULL;
|
||||
size_t num_addrs = 0;
|
||||
NTSTATUS status;
|
||||
size_t i;
|
||||
const char *ip_dbg_str = (recv_fn == ads_dns_lookup_a_recv) ?
|
||||
"A" : "AAAA";
|
||||
|
||||
/*
|
||||
* This loop walks all potential subreqs. Typical setups won't
|
||||
* have more than a few DCs. If you have really many DCs
|
||||
* (hundreds) and a DNS that doesn't return the DC IPs in the
|
||||
* SRV reply, you have bigger problems than this loop linearly
|
||||
* walking a pointer array. This is theoretically O(n^2), but
|
||||
* probably the DNS roundtrip time outweights this by a
|
||||
* lot. And we have a global timeout on this whole
|
||||
* dns_rr_srv_fill routine.
|
||||
*/
|
||||
for (i=0; i<num_subreqs; i++) {
|
||||
if (state->subreqs[i] == subreq) {
|
||||
state->subreqs[i] = NULL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (i == num_subreqs) {
|
||||
tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
|
||||
return;
|
||||
}
|
||||
|
||||
srv = &state->srvs[i/2]; /* 2 subreq per srv */
|
||||
|
||||
status = recv_fn(
|
||||
subreq,
|
||||
state,
|
||||
&rcode,
|
||||
&num_addrs,
|
||||
&hostnames_out,
|
||||
&addrs);
|
||||
TALLOC_FREE(subreq);
|
||||
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
DBG_INFO("async DNS %s lookup for %s returned %s\n",
|
||||
ip_dbg_str,
|
||||
srv->hostname,
|
||||
nt_errstr(status));
|
||||
num_addrs = 0;
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (rcode != DNS_RCODE_OK) {
|
||||
DBG_INFO("async DNS %s lookup for %s returned DNS code "
|
||||
"%"PRIu8"\n",
|
||||
ip_dbg_str,
|
||||
srv->hostname,
|
||||
rcode);
|
||||
num_addrs = 0;
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (num_addrs == 0) {
|
||||
DBG_INFO("async DNS %s lookup for %s returned 0 addresses.\n",
|
||||
ip_dbg_str,
|
||||
srv->hostname);
|
||||
goto done;
|
||||
}
|
||||
|
||||
num_ips = talloc_array_length(srv->ss_s);
|
||||
|
||||
if (num_ips + num_addrs < num_addrs) {
|
||||
/* overflow */
|
||||
goto done;
|
||||
}
|
||||
|
||||
tmp = talloc_realloc(
|
||||
state->srvs,
|
||||
srv->ss_s,
|
||||
struct sockaddr_storage,
|
||||
num_ips + num_addrs);
|
||||
if (tmp == NULL) {
|
||||
goto done;
|
||||
}
|
||||
|
||||
for (i=0; i<num_addrs; i++) {
|
||||
char addr[INET6_ADDRSTRLEN];
|
||||
DBG_INFO("async DNS %s lookup for %s [%zu] got %s -> %s\n",
|
||||
ip_dbg_str,
|
||||
srv->hostname,
|
||||
i,
|
||||
hostnames_out[i],
|
||||
print_sockaddr(addr, sizeof(addr), &addrs[i].u.ss));
|
||||
tmp[num_ips + i] = addrs[i].u.ss;
|
||||
}
|
||||
srv->ss_s = tmp;
|
||||
srv->num_ips = num_ips + num_addrs;
|
||||
|
||||
done:
|
||||
state->num_outstanding -= 1;
|
||||
if (state->num_outstanding == 0) {
|
||||
tevent_req_done(req);
|
||||
}
|
||||
}
|
||||
|
||||
static void dns_rr_srv_fill_done_a(struct tevent_req *subreq)
|
||||
{
|
||||
dns_rr_srv_fill_done(subreq, ads_dns_lookup_a_recv);
|
||||
}
|
||||
|
||||
#if defined(HAVE_IPV6)
|
||||
static void dns_rr_srv_fill_done_aaaa(struct tevent_req *subreq)
|
||||
{
|
||||
dns_rr_srv_fill_done(subreq, ads_dns_lookup_aaaa_recv);
|
||||
}
|
||||
#endif
|
||||
|
||||
static void dns_rr_srv_fill_timedout(struct tevent_req *subreq)
|
||||
{
|
||||
struct tevent_req *req = tevent_req_callback_data(
|
||||
subreq, struct tevent_req);
|
||||
struct dns_rr_srv_fill_state *state = tevent_req_data(
|
||||
req, struct dns_rr_srv_fill_state);
|
||||
bool ok;
|
||||
|
||||
if (DEBUGLEVEL >= DBGLVL_INFO) {
|
||||
size_t i, num_addrs = 0;
|
||||
|
||||
for (i=0; i<state->num_srvs; i++) {
|
||||
/*
|
||||
* Count for the debug. Code that fills this
|
||||
* in ensures no wrap.
|
||||
*/
|
||||
num_addrs += state->srvs[i].num_ips;
|
||||
}
|
||||
|
||||
DBG_INFO("async DNS lookup timed out after %zu addresses "
|
||||
"returned (not an error)\n",
|
||||
num_addrs);
|
||||
}
|
||||
|
||||
ok = tevent_wakeup_recv(subreq);
|
||||
TALLOC_FREE(subreq);
|
||||
TALLOC_FREE(state->subreqs);
|
||||
if (!ok) {
|
||||
tevent_req_oom(subreq);
|
||||
return;
|
||||
}
|
||||
|
||||
tevent_req_done(req);
|
||||
}
|
||||
|
||||
static NTSTATUS dns_rr_srv_fill_recv(struct tevent_req *req)
|
||||
{
|
||||
return tevent_req_simple_recv_ntstatus(req);
|
||||
}
|
||||
|
||||
/*
|
||||
* Request a SRV record and fill in the A/AAAA records if the SRV
|
||||
* record did not carry them.
|
||||
*/
|
||||
|
||||
struct ads_dns_query_srv_state {
|
||||
struct tevent_context *ev;
|
||||
uint32_t async_dns_timeout;
|
||||
const char *query;
|
||||
|
||||
struct tevent_req *fill_req;
|
||||
struct tevent_req *timeout_req;
|
||||
struct dns_rr_srv *srvs;
|
||||
size_t num_srvs;
|
||||
};
|
||||
|
||||
static void ads_dns_query_srv_site_aware_done(struct tevent_req *subreq);
|
||||
static void ads_dns_query_srv_done(struct tevent_req *subreq);
|
||||
static void ads_dns_query_srv_filled(struct tevent_req *subreq);
|
||||
|
||||
struct tevent_req *ads_dns_query_srv_send(
|
||||
TALLOC_CTX *mem_ctx,
|
||||
struct tevent_context *ev,
|
||||
uint32_t async_dns_timeout,
|
||||
const char *sitename,
|
||||
const char *query)
|
||||
{
|
||||
struct tevent_req *req = NULL, *subreq = NULL;
|
||||
struct ads_dns_query_srv_state *state = NULL;
|
||||
|
||||
req = tevent_req_create(
|
||||
mem_ctx, &state, struct ads_dns_query_srv_state);
|
||||
if (req == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
state->ev = ev;
|
||||
state->async_dns_timeout = async_dns_timeout;
|
||||
state->query = query;
|
||||
|
||||
if ((sitename != NULL) && (sitename[0] != '\0')) {
|
||||
char *after_tcp = NULL;
|
||||
char *site_aware = NULL;
|
||||
|
||||
/*
|
||||
* ".<SITENAME>._sites" comes after "._tcp."
|
||||
*/
|
||||
after_tcp = strstr(state->query, "._tcp.");
|
||||
if (after_tcp == NULL) {
|
||||
tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
|
||||
return tevent_req_post(req, ev);
|
||||
}
|
||||
after_tcp += 6; /* strlen("._tcp.") */
|
||||
|
||||
site_aware = talloc_asprintf(
|
||||
state,
|
||||
"%.*s%s._sites.%s",
|
||||
(int)(after_tcp - state->query),
|
||||
state->query,
|
||||
sitename,
|
||||
after_tcp);
|
||||
if (tevent_req_nomem(site_aware, req)) {
|
||||
return tevent_req_post(req, ev);
|
||||
}
|
||||
|
||||
subreq = ads_dns_lookup_srv_send(state, ev, site_aware);
|
||||
if (tevent_req_nomem(subreq, req)) {
|
||||
return tevent_req_post(req, ev);
|
||||
}
|
||||
tevent_req_set_callback(
|
||||
subreq, ads_dns_query_srv_site_aware_done, req);
|
||||
return req;
|
||||
}
|
||||
|
||||
subreq = ads_dns_lookup_srv_send(state, state->ev, state->query);
|
||||
if (tevent_req_nomem(subreq, req)) {
|
||||
return tevent_req_post(req, ev);
|
||||
}
|
||||
tevent_req_set_callback(subreq, ads_dns_query_srv_done, req);
|
||||
return req;
|
||||
}
|
||||
|
||||
static void ads_dns_query_srv_site_aware_done(struct tevent_req *subreq)
|
||||
{
|
||||
struct tevent_req *req = tevent_req_callback_data(
|
||||
subreq, struct tevent_req);
|
||||
struct ads_dns_query_srv_state *state = tevent_req_data(
|
||||
req, struct ads_dns_query_srv_state);
|
||||
NTSTATUS status;
|
||||
|
||||
status = ads_dns_lookup_srv_recv(
|
||||
subreq, state, &state->srvs, &state->num_srvs);
|
||||
TALLOC_FREE(subreq);
|
||||
|
||||
if (NT_STATUS_EQUAL(status, NT_STATUS_IO_TIMEOUT) ||
|
||||
NT_STATUS_EQUAL(status, NT_STATUS_CONNECTION_REFUSED)) {
|
||||
tevent_req_nterror(req, status);
|
||||
return;
|
||||
}
|
||||
|
||||
if (NT_STATUS_IS_OK(status) && (state->num_srvs != 0)) {
|
||||
if (state->async_dns_timeout == 0) {
|
||||
tevent_req_done(req);
|
||||
return;
|
||||
}
|
||||
|
||||
subreq = dns_rr_srv_fill_send(
|
||||
state,
|
||||
state->ev,
|
||||
state->srvs,
|
||||
state->num_srvs,
|
||||
state->async_dns_timeout);
|
||||
if (tevent_req_nomem(subreq, req)) {
|
||||
return;
|
||||
}
|
||||
tevent_req_set_callback(
|
||||
subreq, ads_dns_query_srv_filled, req);
|
||||
return;
|
||||
}
|
||||
|
||||
subreq = ads_dns_lookup_srv_send(state, state->ev, state->query);
|
||||
if (tevent_req_nomem(subreq, req)) {
|
||||
return;
|
||||
}
|
||||
tevent_req_set_callback(subreq, ads_dns_query_srv_done, req);
|
||||
}
|
||||
|
||||
static void ads_dns_query_srv_done(struct tevent_req *subreq)
|
||||
{
|
||||
struct tevent_req *req = tevent_req_callback_data(
|
||||
subreq, struct tevent_req);
|
||||
struct ads_dns_query_srv_state *state = tevent_req_data(
|
||||
req, struct ads_dns_query_srv_state);
|
||||
NTSTATUS status;
|
||||
|
||||
status = ads_dns_lookup_srv_recv(
|
||||
subreq, state, &state->srvs, &state->num_srvs);
|
||||
if (tevent_req_nterror(req, status)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ((state->num_srvs == 0) || (state->async_dns_timeout == 0)) {
|
||||
tevent_req_done(req);
|
||||
return;
|
||||
}
|
||||
|
||||
subreq = dns_rr_srv_fill_send(
|
||||
state,
|
||||
state->ev,
|
||||
state->srvs,
|
||||
state->num_srvs,
|
||||
state->async_dns_timeout);
|
||||
if (tevent_req_nomem(subreq, req)) {
|
||||
return;
|
||||
}
|
||||
tevent_req_set_callback(subreq, ads_dns_query_srv_filled, req);
|
||||
}
|
||||
|
||||
static void ads_dns_query_srv_filled(struct tevent_req *subreq)
|
||||
{
|
||||
NTSTATUS status = dns_rr_srv_fill_recv(subreq);
|
||||
return tevent_req_simple_finish_ntstatus(subreq, status);
|
||||
}
|
||||
|
||||
NTSTATUS ads_dns_query_srv_recv(
|
||||
struct tevent_req *req,
|
||||
TALLOC_CTX *mem_ctx,
|
||||
struct dns_rr_srv **srvs,
|
||||
size_t *num_srvs)
|
||||
{
|
||||
struct ads_dns_query_srv_state *state = tevent_req_data(
|
||||
req, struct ads_dns_query_srv_state);
|
||||
NTSTATUS status;
|
||||
|
||||
if (tevent_req_is_nterror(req, &status)) {
|
||||
tevent_req_received(req);
|
||||
return status;
|
||||
}
|
||||
if (srvs != NULL) {
|
||||
*srvs = talloc_move(mem_ctx, &state->srvs);
|
||||
}
|
||||
if (num_srvs != NULL) {
|
||||
*num_srvs = state->num_srvs;
|
||||
}
|
||||
tevent_req_received(req);
|
||||
return NT_STATUS_OK;
|
||||
}
|
||||
|
||||
NTSTATUS ads_dns_query_srv(
|
||||
TALLOC_CTX *mem_ctx,
|
||||
uint32_t async_dns_timeout,
|
||||
const char *sitename,
|
||||
const char *query,
|
||||
struct dns_rr_srv **srvs,
|
||||
size_t *num_srvs)
|
||||
{
|
||||
TALLOC_CTX *frame = talloc_stackframe();
|
||||
struct tevent_context *ev = NULL;
|
||||
struct tevent_req *req = NULL;
|
||||
NTSTATUS status = NT_STATUS_NO_MEMORY;
|
||||
|
||||
ev = samba_tevent_context_init(frame);
|
||||
if (ev == NULL) {
|
||||
goto fail;
|
||||
}
|
||||
req = ads_dns_query_srv_send(
|
||||
frame, ev, async_dns_timeout, sitename, query);
|
||||
if (req == NULL) {
|
||||
goto fail;
|
||||
}
|
||||
if (!tevent_req_poll_ntstatus(req, ev, &status)) {
|
||||
goto fail;
|
||||
}
|
||||
status = ads_dns_query_srv_recv(req, mem_ctx, srvs, num_srvs);
|
||||
fail:
|
||||
TALLOC_FREE(frame);
|
||||
return status;
|
||||
}
|
||||
|
||||
char *ads_dns_query_string_dcs(TALLOC_CTX *mem_ctx, const char *realm)
|
||||
{
|
||||
char *ret = talloc_asprintf(mem_ctx, "_ldap._tcp.dc._msdcs.%s", realm);
|
||||
return ret;
|
||||
}
|
||||
|
||||
char *ads_dns_query_string_gcs(TALLOC_CTX *mem_ctx, const char *realm)
|
||||
{
|
||||
char *ret = talloc_asprintf(mem_ctx, "_ldap._tcp.gc._msdcs.%s", realm);
|
||||
return ret;
|
||||
}
|
||||
|
||||
char *ads_dns_query_string_kdcs(TALLOC_CTX *mem_ctx, const char *realm)
|
||||
{
|
||||
char *ret = talloc_asprintf(
|
||||
mem_ctx, "_kerberos._tcp.dc._msdcs.%s", realm);
|
||||
return ret;
|
||||
}
|
||||
|
||||
char *ads_dns_query_string_pdc(TALLOC_CTX *mem_ctx, const char *realm)
|
||||
{
|
||||
char *ret = talloc_asprintf(
|
||||
mem_ctx, "_ldap._tcp.pdc._msdcs.%s", realm);
|
||||
return ret;
|
||||
}
|
||||
|
||||
char *ads_dns_query_string_dcs_guid(
|
||||
TALLOC_CTX *mem_ctx,
|
||||
const struct GUID *domain_guid,
|
||||
const char *realm)
|
||||
{
|
||||
struct GUID_txt_buf buf;
|
||||
char *ret = NULL;
|
||||
|
||||
talloc_asprintf(
|
||||
mem_ctx,
|
||||
"_ldap._tcp.%s.domains._msdcs.%s",
|
||||
GUID_buf_string(domain_guid, &buf),
|
||||
realm);
|
||||
return ret;
|
||||
}
|
54
lib/addns/dnsquery_srv.h
Normal file
54
lib/addns/dnsquery_srv.h
Normal file
@ -0,0 +1,54 @@
|
||||
/*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __LIB_ADDNS_DNSQUERY_SRV_H__
|
||||
#define __LIB_ADDNS_DNSQUERY_SRV_H__
|
||||
|
||||
#include "replace.h"
|
||||
#include <tevent.h>
|
||||
#include "libcli/util/ntstatus.h"
|
||||
#include "libcli/dns/dns.h"
|
||||
|
||||
struct tevent_req *ads_dns_query_srv_send(
|
||||
TALLOC_CTX *mem_ctx,
|
||||
struct tevent_context *ev,
|
||||
uint32_t async_dns_timeout,
|
||||
const char *sitename,
|
||||
const char *query);
|
||||
NTSTATUS ads_dns_query_srv_recv(
|
||||
struct tevent_req *req,
|
||||
TALLOC_CTX *mem_ctx,
|
||||
struct dns_rr_srv **srvs,
|
||||
size_t *num_srvs);
|
||||
NTSTATUS ads_dns_query_srv(
|
||||
TALLOC_CTX *mem_ctx,
|
||||
uint32_t async_dns_timeout,
|
||||
const char *sitename,
|
||||
const char *query,
|
||||
struct dns_rr_srv **srvs,
|
||||
size_t *num_srvs);
|
||||
|
||||
char *ads_dns_query_string_dcs(TALLOC_CTX *mem_ctx, const char *realm);
|
||||
char *ads_dns_query_string_gcs(TALLOC_CTX *mem_ctx, const char *realm);
|
||||
char *ads_dns_query_string_kdcs(TALLOC_CTX *mem_ctx, const char *realm);
|
||||
char *ads_dns_query_string_pdc(TALLOC_CTX *mem_ctx, const char *realm);
|
||||
|
||||
struct GUID;
|
||||
char *ads_dns_query_string_dcs_guid(
|
||||
TALLOC_CTX *mem_ctx,
|
||||
const struct GUID *domain_guid,
|
||||
const char *realm);
|
||||
|
||||
#endif /* _ADS_DNS_H */
|
@ -9,6 +9,7 @@ bld.SAMBA_LIBRARY('addns',
|
||||
dnsgss.c
|
||||
dnsmarshall.c
|
||||
error.c
|
||||
dnsquery_srv.c
|
||||
''',
|
||||
public_deps='samba-util gssapi ndr resolv dns_lookup',
|
||||
private_library=True,
|
||||
|
Loading…
Reference in New Issue
Block a user