Esempio n. 1
0
int
afsconf_LookupServer(const char *service, const char *protocol,
		     const char *cellName, unsigned short afsdbPort,
		     afs_uint32 *cellHostAddrs, char cellHostNames[][MAXHOSTCHARS],
		     unsigned short ports[], unsigned short ipRanks[],
		     int *numServers, int *ttl, char **arealCellName)
{
    int code = 0;
    int r;
    int len;
    unsigned char answer[4096];
    unsigned char *p;
    char *dotcellname = NULL;
    char *realCellName;
    char host[256];
    int server_num = 0;
    int minttl = 0;
    int try_init = 0;
    int dnstype = 0;
    int pass = 0;
    char *IANAname = (char *) afsconf_FindIANAName(service);
    int tservice = afsconf_FindService(service);

    realCellName = NULL;

    *numServers = 0;
    *ttl = 0;
    if (tservice <= 0 || !IANAname)
	return AFSCONF_NOTFOUND;	/* service not found */

    if (strchr(cellName,'.'))
	pass += 2;

#ifdef HAVE_RES_RETRANSRETRY
    if ((_res.options & RES_INIT) == 0 && res_init() == -1)
      return (0);

    /*
     * Rx timeout is typically 56 seconds; limit user experience to
     * similar timeout
     */
    _res.retrans = 18;
    _res.retry = 3;
#endif

 retryafsdb:
    r = -1;
    switch (pass) {
    case 0:
	dnstype = T_SRV;
	r = asprintf(&dotcellname, "_%s._%s.%s.", IANAname, protocol, cellName);
	break;
    case 1:
	dnstype = T_AFSDB;
	r = asprintf(&dotcellname, "%s.", cellName);
	break;
    case 2:
	dnstype = T_SRV;
	r = asprintf(&dotcellname, "_%s._%s.%s", IANAname, protocol, cellName);
	break;
    case 3:
	dnstype = T_AFSDB;
	r = asprintf(&dotcellname, "%s", cellName);
	break;
    }
    if (r < 0 || dotcellname == NULL)
	goto findservererror;

    LOCK_GLOBAL_MUTEX;
    len = res_search(dotcellname, C_IN, dnstype, answer, sizeof(answer));
    UNLOCK_GLOBAL_MUTEX;

    if (dotcellname != NULL) {
	free(dotcellname);
	dotcellname = NULL;
    }

    if (len < 0) {
	if (try_init < 1) {
	    try_init++;
	    res_init();
	    goto retryafsdb;
	}
	if (pass < 3) {
	    pass++;
	    goto retryafsdb;
	} else {
	    code = AFSCONF_NOTFOUND;
	    goto findservererror;
	}
    }

    p = answer + sizeof(HEADER);	/* Skip header */
    code = dn_expand(answer, answer + len, p, host, sizeof(host));
    if (code < 0) {
	code = AFSCONF_NOTFOUND;
	goto findservererror;
    }

    p += code + QFIXEDSZ;	/* Skip name */

    while (p < answer + len) {
	int type, ttl, size;

	code = dn_expand(answer, answer + len, p, host, sizeof(host));
	if (code < 0) {
	    code = AFSCONF_NOTFOUND;
	    goto findservererror;
	}

	p += code;		/* Skip the name */
	type = (p[0] << 8) | p[1];
	p += 4;			/* Skip type and class */
	ttl = (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3];
	p += 4;			/* Skip the TTL */
	size = (p[0] << 8) | p[1];
	p += 2;			/* Skip the size */

	if (type == T_AFSDB) {
	    struct hostent *he;
	    short afsdb_type;

	    afsdb_type = (p[0] << 8) | p[1];
	    if (afsdb_type == 1) {
		/*
		 * We know this is an AFSDB record for our cell, of the
		 * right AFSDB type.  Write down the true cell name that
		 * the resolver gave us above.
		 */
		if (!realCellName)
		    realCellName = strdup(host);
	    }

	    code = dn_expand(answer, answer + len, p + 2, host, sizeof(host));
	    if (code < 0) {
		code = AFSCONF_NOTFOUND;
		goto findservererror;
	    }

	    if ((afsdb_type == 1) && (server_num < MAXHOSTSPERCELL) &&
		/* Do we want to get TTL data for the A record as well? */
		(he = gethostbyname(host))) {
		if (he->h_addrtype == AF_INET) {
		    afs_uint32 ipaddr;
		    memcpy(&ipaddr, he->h_addr, sizeof(ipaddr));
		    cellHostAddrs[server_num] = ipaddr;
		    ports[server_num] = afsdbPort;
		    ipRanks[server_num] = 0;
		    strncpy(cellHostNames[server_num], host,
			    sizeof(cellHostNames[server_num]));
		    server_num++;
		    if (!minttl || ttl < minttl)
			minttl = ttl;
		}
	    }
	}
	if (type == T_SRV) {
	    struct hostent *he;
	    /* math here: _ is 1, _ ._ is 3, _ ._ . is 4. then the domain. */
	    if ((strncmp(host + 1, IANAname, strlen(IANAname)) == 0) &&
		(strncmp(host + strlen(IANAname) + 3, protocol,
			 strlen(protocol)) == 0)) {
		if (!realCellName)
		    realCellName = strdup(host + strlen(IANAname) +
					  strlen(protocol) + 4);
	    }

	    code = dn_expand(answer, answer + len, p + 6, host, sizeof(host));
	    if (code < 0) {
		code = AFSCONF_NOTFOUND;
		goto findservererror;
	    }

	    if ((server_num < MAXHOSTSPERCELL) &&
		/* Do we want to get TTL data for the A record as well? */
		(he = gethostbyname(host))) {
		if (he->h_addrtype == AF_INET) {
		    afs_uint32 ipaddr;

		    memcpy(&ipaddr, he->h_addr, sizeof(ipaddr));
		    cellHostAddrs[server_num] = ipaddr;
		    ipRanks[server_num] = (p[0] << 8) | p[1];
		    ports[server_num] = htons((p[4] << 8) | p[5]);
		    /* weight = (p[2] << 8) | p[3]; */
		    strncpy(cellHostNames[server_num], host,
			    sizeof(cellHostNames[server_num]));
		    server_num++;

		    if (!minttl || ttl < minttl)
			minttl = ttl;
		}
	    }
	}

	p += size;
    }

    if (server_num == 0) {	/* No AFSDB or SRV records */
	code = AFSCONF_NOTFOUND;
	goto findservererror;
    }

    if (realCellName) {
	/* Convert the real cell name to lowercase */
	for (p = (unsigned char *)realCellName; *p; p++)
	    *p = tolower(*p);
    }

    *numServers = server_num;
    *ttl = minttl ? (time(0) + minttl) : 0;

    if ( *numServers > 0 ) {
        code =  0;
	*arealCellName = realCellName;
    } else
        code = AFSCONF_NOTFOUND;

findservererror:
    if (code && realCellName)
	free(realCellName);
    return code;
}
Esempio n. 2
0
    /* If we couldn't find an entry for the requested service
     * and that service happens to be the prservice or kaservice
     * then fallback to searching for afs3-vlserver and assigning
     * the port number here. */
    if (code < 0 && (afsdbport == htons(7002) || afsdbport == htons(7004))) {
        code = afsconf_LookupServer("afs3-vlserver", "udp",
                                    (const char *)acellName, afsdbport,
                                    cellHostAddrs, cellHostNames,
                                    ports, ipRanks, &numServers, &ttl,
                                    &realCellName);
        if (code >= 0) {
            for (i = 0; i < numServers; i++)
                ports[i] = afsdbport;
        }
    }
    if (code == 0) {
	acellInfo->timeout = ttl;
	acellInfo->numServers = numServers;
	for (i = 0; i < numServers; i++) {
	    memcpy(&acellInfo->hostAddr[i].sin_addr.s_addr, &cellHostAddrs[i],
		   sizeof(afs_int32));
	    memcpy(acellInfo->hostName[i], cellHostNames[i], MAXHOSTCHARS);
	    acellInfo->hostAddr[i].sin_family = AF_INET;
	    acellInfo->hostAddr[i].sin_port = ports[i];

	    if (realCellName) {
		strlcpy(acellInfo->name, realCellName,
			sizeof(acellInfo->name));
		free(realCellName);
		realCellName = NULL;
	    }
	}
	acellInfo->linkedCell = NULL;       /* no linked cell */
	acellInfo->flags = 0;
    }
    return code;
}
#else /* windows */
int
afsconf_GetAfsdbInfo(char *acellName, char *aservice,
		     struct afsconf_cell *acellInfo)
{
    afs_int32 i;
    int tservice = afsconf_FindService(aservice);   /* network byte order */
    const char *ianaName = afsconf_FindIANAName(aservice);
    struct afsconf_entry DNSce;
    afs_uint32 cellHostAddrs[AFSMAXCELLHOSTS];
    char cellHostNames[AFSMAXCELLHOSTS][MAXHOSTCHARS];
    unsigned short ipRanks[AFSMAXCELLHOSTS];
    unsigned short ports[AFSMAXCELLHOSTS];          /* network byte order */
    int numServers;
    int rc;
    int ttl;

    if (tservice < 0) {
        if (aservice)
            return AFSCONF_NOTFOUND;
        else
            tservice = 0;       /* port will be assigned by caller */
    }

    if (ianaName == NULL)
        ianaName = "afs3-vlserver";

    DNSce.cellInfo.numServers = 0;
    DNSce.next = NULL;

    rc = getAFSServer(ianaName, "udp", acellName, tservice,
                      cellHostAddrs, cellHostNames, ports, ipRanks, &numServers,
		      &ttl);
    /* ignore the ttl here since this code is only called by transitory programs
     * like klog, etc. */

    /* If we couldn't find an entry for the requested service
     * and that service happens to be the prservice or kaservice
     * then fallback to searching for afs3-vlserver and assigning
     * the port number here. */
    if (rc < 0 && (tservice == htons(7002) || tservice == htons(7004))) {
        rc = getAFSServer("afs3-vlserver", "udp", acellName, tservice,
                           cellHostAddrs, cellHostNames, ports, ipRanks, &numServers,
                           &ttl);
        if (rc >= 0) {
            for (i = 0; i < numServers; i++)
                ports[i] = tservice;
        }
    }

    if (rc < 0 || numServers == 0)
	return -1;

    for (i = 0; i < numServers; i++) {
	memcpy(&acellInfo->hostAddr[i].sin_addr.s_addr, &cellHostAddrs[i],
	       sizeof(afs_uint32));
	memcpy(acellInfo->hostName[i], cellHostNames[i], MAXHOSTCHARS);
	acellInfo->hostAddr[i].sin_family = AF_INET;
        if (aservice)
            acellInfo->hostAddr[i].sin_port = ports[i];
        else
            acellInfo->hostAddr[i].sin_port = 0;
    }

    acellInfo->numServers = numServers;
    strlcpy(acellInfo->name, acellName, sizeof acellInfo->name);
    acellInfo->linkedCell = NULL;	/* no linked cell */
    acellInfo->flags = 0;
    return 0;
}
Esempio n. 3
0
$NetBSD$

--- src/auth/cellconfig.c.orig	2012-04-22 23:40:23.000000000 -0400
+++ src/auth/cellconfig.c	2013-01-06 18:00:28.000000000 -0500
@@ -976,6 +976,11 @@
     int pass = 0;
     char *IANAname = (char *) afsconf_FindIANAName(service);
     int tservice = afsconf_FindService(service);
+#ifdef __NetBSD__
+    res_state res;
+#else
+#define res (&_res)
+#endif
 
     realCellName = NULL;
 
@@ -994,15 +999,18 @@
 	return AFSCONF_NOTFOUND;	/* service not found */
 
 #ifdef HAVE_RES_RETRANSRETRY
-    if ((_res.options & RES_INIT) == 0 && res_init() == -1)
+#ifdef __NetBSD__
+    res = __res_get_state();
+#else
+    if ((res->options & RES_INIT) == 0 && res_init() == -1)
       return (0);
-
+#endif
     /*
      * Rx timeout is typically 56 seconds; limit user experience to
      * similar timeout