/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2014 Nexenta Systems, Inc. All rights reserved.
*/
/*
* DNS query helper functions for addisc.c
*/
#include <stdio.h>
#include <string.h>
#include <strings.h>
#include <unistd.h>
#include <assert.h>
#include <stdlib.h>
#include <resolv.h>
#include <netdb.h>
#include <ctype.h>
#include <errno.h>
#include <ldap.h>
#include <sys/u8_textprep.h>
#include <syslog.h>
#include "adutils_impl.h"
#include "addisc_impl.h"
static void do_getaddrinfo(ad_disc_cds_t *);
static void get_addresses(ad_disc_cds_t *, int);
/*
* Simplified version of srv_query() for domain auto-discovery.
*/
int
{
union {
} msg;
/* query necessary resource records */
}
if (len < 0) {
"DNS search for '%s' failed (%s)",
}
return (-1);
}
"DNS query %ib message doesn't fit into %ib buffer",
}
/* parse the reply header */
/* skip the question section */
if (len < 0) {
return (-1);
}
/* parse the answer section */
if (ancount < 1) {
return (-1);
}
if (len < 0) {
return (-1);
}
return (-1);
}
return (0);
}
/*
* Compare SRC RRs; used with qsort(). Sort order:
* "Earliest" (lowest number) priority first,
* then weight highest to lowest.
*/
static int
{
return (-1);
return (1);
return (1);
return (-1);
return (0);
}
/*
* Query or search the SRV RRs for a given name.
*
* If dname == NULL then search (as in res_nsearch(3RESOLV), honoring any
*
* The output TTL will be the one of the SRV RR with the lowest TTL.
*/
{
return (NULL);
}
/* query necessary resource records */
/* Search, querydomain or query */
dname = "*";
svc_name);
}
if (len < 0) {
"DNS search for '%s' failed (%s)",
}
goto errout;
}
} else { /* dname != NULL */
}
if (len < 0) {
}
goto errout;
}
}
"DNS query %ib message doesn't fit into %ib buffer",
}
/* parse the reply header */
goto errout;
/* sort list of candidates */
if (scnt > 1)
(int (*)(const void *, const void *))srvcmp);
return (cds_res);
return (NULL);
}
static ad_disc_cds_t *
{
/* LINTED E_FUNC_SET_NOT_USED */
/* skip the question section */
if (len < 0) {
return (NULL);
}
/*
* Walk through the answer section, building the result array.
* The array size is +2 because we (possibly) add the preferred
* DC if it was not there, and an empty one (null termination).
*/
return (NULL);
}
for (i = 0; i < ancount; i++) {
sizeof (namebuf));
if (len < 0) {
goto err;
}
goto err;
}
continue;
}
if (len < 0) {
goto err;
}
" ttl=%d pri=%d weight=%d %s:%d",
}
cds++;
/* move ptr to the end of current record */
}
/* skip the nameservers section (if any) */
if (len < 0) {
goto err;
}
/* walk through the additional records */
for (i = 0; i < arcount; i++) {
sizeof (namebuf));
if (len < 0) {
goto err;
}
goto err;
}
switch (type) {
case ns_t_a:
break;
case ns_t_aaaa:
break;
default:
continue;
}
const char *ap;
}
/* Find the server, add to its address list. */
/* move ptr to the end of current record */
}
return (cds_res);
err:
return (NULL);
}
/*
* Save this address on the server, if not already there.
*/
static void
{
return;
ai->ai_addrlen)) {
/* it's already there */
return;
}
}
/* Not found. Append. */
} else {
}
}
static struct addrinfo *
{
int slen;
goto errout;
}
switch (af) {
case AF_INET:
goto errout;
}
break;
case AF_INET6:
if (alen < sizeof (in6_addr_t)) {
goto errout;
}
alen = sizeof (in6_addr_t);
break;
default:
goto errout;
}
return (ai);
return (NULL);
}
/*
* Set a preferred candidate, which may already be in the list,
* in which case we just bump its priority, or else add it.
*/
static void
{
int i;
for (i = 0; i < *nds; i++) {
/* Force this element to be sorted first. */
return;
}
}
/*
* The preferred DC was not found in this DNS response,
* so add it. Again arrange for it to be sorted first.
* Address info. is added later.
*/
*nds = i + 1;
}
/*
* Do another pass over the array to check for missing addresses and
* try resolving the names. Normally, the DNS response from AD will
* have supplied additional address records for all the SRV records.
*/
static void
{
int i;
for (i = 0; i < cnt; i++) {
do_getaddrinfo(&cds[i]);
}
}
}
static void
{
int err;
/*
* This getaddrinfo call may take a LONG time, i.e. if our
* DNS servers are misconfigured or not responding.
* We need something like getaddrinfo_a(), with a timeout.
* For now, just log when this happens so we'll know
* if these calls are taking a long time.
*/
}
if (err != 0) {
/* Make this sort at the end. */
return;
}
}
void
{
}
}
}