* Copyright (C) 1989 by NeXT, Inc.
*/
#include <libc.h>
+#include <string.h>
#include <syslog.h>
#include <netinfo/ni.h>
#include <rpc/pmap_clnt.h>
#include <net/if.h>
#include <ctype.h>
#include "clib.h"
+#include "sys_interfaces.h"
+
+#define LOCAL_PORT 1033
#define NI_TIMEOUT_SHORT 5 /* 5 second timeout for transactions */
#define NI_TIMEOUT_LONG 60 /* 60 second timeout for writes */
/* Hack for determining if an IP address is a broadcast address. -GRS */
/* Note that addr is network byte order (big endian) - BKM */
-
+
#define IS_BROADCASTADDR(addr) (((unsigned char *) &addr)[0] == 0xFF)
#ifndef INADDR_LOOPBACK
static const ni_name NAME_USERS = "users";
static const ni_name NAME_UID = "uid";
+static const ni_name NAME_DOMAIN_SERVERS = "domain_servers";
+
typedef struct getreg_stuff {
nibind_getregister_res res;
ni_private *ni;
}
-/*
- * Is the NetInfo binder running?
- */
-static int
-nibind_up(
- ni_private *ni
- )
-{
- int sock;
- struct sockaddr_in sin;
- int res;
-
- sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
- if (sock < 0) {
- return (0);
- }
- sin.sin_family = AF_INET;
- sin.sin_port = htons(PMAPPORT);
- sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
- bzero(sin.sin_zero, sizeof(sin.sin_zero));
- res = connect(sock, (struct sockaddr *)&sin, sizeof(sin));
- close(sock);
- if (res != 0) {
- return (0);
- }
- sin.sin_port = htons(pmap_getport(&sin, NIBIND_PROG, NIBIND_VERS,
- IPPROTO_TCP));
- if (sin.sin_port == 0) {
- return (0);
- }
- sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
- if (sock < 0) {
- return (0);
- }
- res = connect(sock, (struct sockaddr *)&sin, sizeof(sin));
- close(sock);
- return (res == 0);
-}
-
-
static void
createauth(
ni_private *ni
* Connect to a given address/tag
*/
static int
-connectit(
- ni_private *ni
- )
+connectit(ni_private *ni)
{
struct sockaddr_in sin;
int sock;
struct timeval tv;
enum clnt_stat stat;
nibind_getregister_res res;
-
+
+ sock = -1;
bzero(&sin, sizeof(sin));
sin.sin_port = 0;
sin.sin_family = AF_INET;
- sin.sin_addr = ni->addrs[0];
- ni_settimeout(ni, ni->rtv_sec == 0 ? NI_TIMEOUT_SHORT : ni->rtv_sec);
- fixtimeout(&tv, ni->tv_sec, NI_TRIES);
- sock = socket_open(&sin, NIBIND_PROG, NIBIND_VERS, ni->tv_sec,
- NI_TRIES, IPPROTO_UDP);
- if (sock < 0) {
- return (0);
- }
- cl = clntudp_create(&sin, NIBIND_PROG, NIBIND_VERS, tv,
- &sock);
- if (cl == NULL) {
- close(sock);
- return (0);
- }
+
tv.tv_sec = ni->rtv_sec == 0 ? NI_TIMEOUT_SHORT : ni->rtv_sec;
tv.tv_usec = 0;
- stat = clnt_call(cl, NIBIND_GETREGISTER, xdr_ni_name, &ni->tags[0],
- xdr_nibind_getregister_res, &res, tv);
- clnt_destroy(cl);
- close(sock);
- if (stat != RPC_SUCCESS || res.status != NI_OK) {
- return (0);
- }
+ ni_settimeout(ni, tv.tv_sec);
+ fixtimeout(&tv, ni->tv_sec, NI_TRIES);
+
/*
- * Found the address, now connect to it.
+ * If connecting to local domain, try using the "well-known" port first.
*/
- sin.sin_port = htons(res.nibind_getregister_res_u.addrs.tcp_port);
- sock = socket_open(&sin, NI_PROG, NI_VERS, ni->tv_sec, NI_TRIES,
- IPPROTO_TCP);
- if (sock < 0) {
- return (0);
+ if (!strcmp(ni->tags[0], "local"))
+ {
+ interface_list_t *ilist;
+
+ ilist = sys_interfaces();
+ if (sys_is_my_address(ilist, &ni->addrs[0]))
+ {
+ sin.sin_port = htons(LOCAL_PORT);
+ sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
+ sock = socket_open(&sin, NI_PROG, NI_VERS, ni->tv_sec, NI_TRIES, IPPROTO_TCP);
+ }
+ sys_interfaces_release(ilist);
+ }
+
+ /*
+ * If connecting to a domain other than the local domain,
+ * or if connection to local didn't work with local's well-known port,
+ * then go through portmap & nibindd to find the port and connect.
+ */
+ if (sock < 0)
+ {
+ sin.sin_port = 0;
+ sin.sin_addr = ni->addrs[0];
+
+ sock = socket_open(&sin, NIBIND_PROG, NIBIND_VERS, ni->tv_sec, NI_TRIES, IPPROTO_UDP);
+ if (sock < 0) return (0);
+
+ cl = clntudp_create(&sin, NIBIND_PROG, NIBIND_VERS, tv, &sock);
+ if (cl == NULL)
+ {
+ close(sock);
+ return (0);
+ }
+
+ tv.tv_sec = ni->rtv_sec == 0 ? NI_TIMEOUT_SHORT : ni->rtv_sec;
+ tv.tv_usec = 0;
+
+ stat = clnt_call(cl, NIBIND_GETREGISTER, xdr_ni_name, &ni->tags[0], xdr_nibind_getregister_res, &res, tv);
+ clnt_destroy(cl);
+ close(sock);
+ if (stat != RPC_SUCCESS || res.status != NI_OK) return (0);
+
+ sin.sin_port = htons(res.nibind_getregister_res_u.addrs.tcp_port);
+ sock = socket_open(&sin, NI_PROG, NI_VERS, ni->tv_sec, NI_TRIES, IPPROTO_TCP);
}
+
+ if (sock < 0) return (0);
+
cl = clnttcp_create(&sin, NI_PROG, NI_VERS, &sock, 0, 0);
- if (cl == NULL) {
+ if (cl == NULL)
+ {
close(sock);
return (0);
}
+
clnt_control(cl, CLSET_TIMEOUT, &tv);
ni->tc = cl;
ni->tsock = sock;
ni->tport = getmyport(sock);
createauth(ni);
- (void) fcntl(ni->tsock, F_SETFD, 1);
+ fcntl(ni->tsock, F_SETFD, 1);
return (1);
}
}
-static unsigned long
-sys_netmask(void)
-{
- struct ifconf ifc;
- struct ifreq *ifr;
- char buf[1024]; /* XXX */
- int i, len, ifreq_size, offset, sockaddr_size, size;
- int sock;
- struct sockaddr_in *sin;
- unsigned long n_addr;
-
- sock = socket(AF_INET, SOCK_DGRAM, 0);
-
- if (sock < 0) return (htonl(IN_CLASSA_NET));
-
- ifc.ifc_len = sizeof(buf);
- ifc.ifc_buf = buf;
-
- if (ioctl(sock, SIOCGIFCONF, (char *)&ifc) < 0)
- {
- close(sock);
- return (htonl(IN_CLASSA_NET));
- }
-
- ifreq_size = sizeof(struct ifreq);
- sockaddr_size = sizeof(struct sockaddr);
-
- offset = 0;
- len = ifc.ifc_len / ifreq_size;
- for (i = 0; i < len; i++)
- {
- ifr = (struct ifreq *)(ifc.ifc_buf + offset);
- offset += IFNAMSIZ;
- offset += sockaddr_size;
-
- size = ifr->ifr_addr.sa_len;
- if (size > sockaddr_size) offset += (size - sockaddr_size);
-
- if (ifr->ifr_addr.sa_family != AF_INET) continue;
- if (ioctl(sock, SIOCGIFFLAGS, (char *)ifr) < 0) continue;
-
- sin = (struct sockaddr_in *)&ifr->ifr_addr;
- if ((ifr->ifr_flags & IFF_UP) &&
- !(ifr->ifr_flags & IFF_LOOPBACK) &&
- (sin->sin_addr.s_addr != 0))
- {
- ioctl(sock, SIOCGIFNETMASK, (char *)ifr);
- n_addr = ((struct sockaddr_in *)&(ifr->ifr_addr))->sin_addr.s_addr;
- close(sock);
- return (n_addr);
- }
- }
-
- close(sock);
- return (htonl(IN_CLASSA_NET));
-}
-
-
-static unsigned long
-sys_address(void)
-{
- struct ifconf ifc;
- struct ifreq *ifr;
- char buf[1024]; /* XXX */
- int i, len, ifreq_size, offset, sockaddr_size, size;
- int sock;
-
- sock = socket(AF_INET, SOCK_DGRAM, 0);
-
- if (sock < 0)
- {
- return (htonl(INADDR_LOOPBACK));
- }
-
- ifc.ifc_len = sizeof(buf);
- ifc.ifc_buf = buf;
-
- if (ioctl(sock, SIOCGIFCONF, (char *)&ifc) < 0)
- {
- close(sock);
- return (htonl(INADDR_LOOPBACK));
- }
-
- ifreq_size = sizeof(struct ifreq);
- sockaddr_size = sizeof(struct sockaddr);
-
- offset = 0;
- len = ifc.ifc_len / ifreq_size;
- for (i = 0; i < len; i++)
- {
- ifr = (struct ifreq *)(ifc.ifc_buf + offset);
- offset += IFNAMSIZ;
- offset += sockaddr_size;
-
- size = ifr->ifr_addr.sa_len;
- if (size > sockaddr_size) offset += (size - sockaddr_size);
-
- if (ifr->ifr_addr.sa_family != AF_INET) continue;
- if (ioctl(sock, SIOCGIFFLAGS, ifr) < 0) continue;
-
- if ((ifr->ifr_flags & IFF_UP) && (!(ifr->ifr_flags & IFF_LOOPBACK)))
- {
- close(sock);
- return (((struct sockaddr_in *)&(ifr->ifr_addr))->sin_addr.s_addr);
- }
- }
-
- close(sock);
- return (htonl(INADDR_LOOPBACK));
-}
-
-
/*
* Returns a client handle to the NetInfo server, if it's running
*/
{
int printed = 0;
- if (!nibind_up(ni)) {
- return (0);
- }
ni->naddrs = 1;
ni->addrs = (struct in_addr *)malloc(sizeof(struct in_addr));
ni->addrs[0].s_addr = htonl(INADDR_LOOPBACK);
ni->tags = (ni_name *)malloc(sizeof(ni_name));
ni->tags[0] = ni_name_dup("local");
ni->whichwrite = 0;
- while (!connectit(ni)) {
- if (!printed) {
+
+ while (!connectit(ni))
+ {
+ if (!printed)
+ {
syslog(LOG_ERR, "NetInfo timeout connecting to local domain, sleeping");
printed++;
}
+
sleep(NI_SLEEPTIME);
/* wait forever */
}
- if (printed) {
+
+ if (printed)
+ {
syslog(LOG_ERR, "NetInfo connection to local domain waking");
}
+
return (1);
}
struct in_addr tmp_addr;
ni_name tmp_tag;
+ if (a == b) return;
+
tmp_addr = ni->addrs[a];
tmp_tag = ni->tags[a];
}
+/*
+ * shuffle addresses
+ */
+static void
+shuffle(ni_private *ni)
+{
+ int *shuffle;
+ int i, j;
+ int rfd;
+
+ if (ni->naddrs <= 1) return;
+
+ rfd = open("/dev/random", O_RDONLY, 0);
+ shuffle = (int *)malloc(ni->naddrs * sizeof(int));
+ for (i = 0; i < ni->naddrs; i++) shuffle[i] = i;
+ for (i = 0, j = ni->naddrs; j > 0; i++, j--) {
+ unsigned int rEnt;
+ long rVal;
+ int tEnt;
+
+ /* get a random number */
+ if ((rfd < 0) ||
+ (read(rfd, &rVal, sizeof(rVal)) != sizeof(rVal))) {
+ /* if we could not read from /dev/random */
+ static int initialized = 0;
+ if (!initialized)
+ {
+ srandom(gethostid() ^ time(NULL));
+ initialized++;
+ }
+ rVal = random();
+ }
+
+ rEnt = (unsigned int)rVal % j; /* pick one of the remaining entries */
+ tEnt = shuffle[rEnt]; /* grab the random entry */
+ shuffle[rEnt] = shuffle[j-1]; /* the last entry moves to the random slot */
+ shuffle[j-1] = tEnt; /* the last slot gets the random entry */
+ ni_swap(ni, rEnt, j-1); /* and swap the actual NI addresses */
+ }
+ free(shuffle);
+ if (rfd > 0) (void)close(rfd);
+ return;
+}
+
+
static int
rebind(
ni_private *ni
int printed = 0;
int nlocal;
int nnetwork;
- unsigned long myaddr;
- unsigned long mynetmask;
- unsigned long mynetwork;
+ interface_list_t *ilist;
int i;
if (ni->naddrs == 1) {
* all other servers are next
*/
- myaddr = sys_address();
- mynetmask = sys_netmask();
- mynetwork = myaddr & mynetmask;
+ ilist = sys_interfaces();
+
+ /*
+ * shuffle addresses
+ */
+ shuffle(ni);
/*
* move local servers to the head of the list
*/
nlocal = 0;
for (i = nlocal; i < ni->naddrs; i++) {
- if ((ni->addrs[i].s_addr == myaddr) ||
- (ni->addrs[i].s_addr == htonl(INADDR_LOOPBACK)))
+ if (sys_is_my_address(ilist, &ni->addrs[i]))
{
ni_swap(ni, nlocal, i);
nlocal++;
*/
nnetwork = nlocal;
for (i = nnetwork; i < ni->naddrs; i++) {
- if (((ni->addrs[i].s_addr & mynetmask) == mynetwork) ||
+ if (sys_is_my_network(ilist, &ni->addrs[i]) ||
IS_BROADCASTADDR(ni->addrs[i].s_addr))
{
ni_swap(ni, nnetwork, i);
}
}
+ sys_interfaces_release(ilist);
+
stuff.ni = ni;
for (;;) {
/*
* Somebody closed our socket. Do not close it, it could
* be owned by somebody else now.
*/
- auth_destroy(ni->tc->cl_auth);
- clnt_destroy(ni->tc);
- ni->tc = NULL;
+ if (ni->tc != NULL)
+ {
+ if (ni->tc->cl_auth != NULL) auth_destroy(ni->tc->cl_auth);
+ clnt_destroy(ni->tc);
+ ni->tc = NULL;
+ }
}
if (!needwrite && !rebind(ni) && ni->abort) {
return (0);
ni->needwrite = needwrite;
return (0);
}
+ NI_INIT(&nl);
if (ni_lookupprop(ni, &root, NAME_MASTER, &nl) != NI_OK) {
ni->needwrite = needwrite;
return (0);
}
*sep++ = 0;
master = nl.ninl_val[0];
+ NI_INIT(&idl);
if (ni_lookup(ni, &root, NAME_NAME, NAME_MACHINES, &idl) != NI_OK) {
ni->needwrite = needwrite;
ni_namelist_free(&nl);
}
id.nii_object = idl.niil_val[0];
ni_idlist_free(&idl);
+ NI_INIT(&idl);
if (ni_lookup(ni, &id, NAME_NAME, master, &idl) != NI_OK) {
ni_namelist_free(&nl);
ni->needwrite = needwrite;
}
id.nii_object = idl.niil_val[0];
ni_idlist_free(&idl);
+ NI_INIT(&nl);
if (ni_lookupprop(ni, &id, NAME_IP_ADDRESS, &nl) != NI_OK) {
return (0);
}
}
return (resp);
}
- clnt_geterr(ni->tc, &err);
- if (err.re_status != RPC_CANTRECV) {
- break;
+ if (ni->tc != NULL)
+ {
+ clnt_geterr(ni->tc, &err);
+ if (err.re_status != RPC_CANTRECV) break;
}
if (i + 1 < NI_MAXCONNTRIES) {
/*
}
+static void
+add_addr_tag(ni_private *ni, ni_name addrtag)
+{
+ struct in_addr addr;
+ ni_name tag;
+ char *slash;
+
+ slash = strchr(addrtag, '/');
+ if (slash == NULL) return;
+
+ tag = slash + 1;
+ if (tag[0] == '\0') return;
+
+ *slash = '\0';
+
+ if (inet_aton(addrtag, &addr) == 0) return;
+
+ if (ni->naddrs == 0)
+ {
+ ni->addrs = (struct in_addr *)calloc(1, sizeof(struct in_addr));
+ if (ni->addrs == NULL) return;
+
+ ni->tags = (ni_name *)calloc(1, sizeof(ni_name));
+ if (ni->tags == NULL) return;
+ }
+ else
+ {
+ ni->addrs = (struct in_addr *)realloc(ni->addrs, ((ni->naddrs + 1) * sizeof(struct in_addr)));
+ if (ni->addrs == NULL) return;
+
+ ni->tags = (ni_name *)realloc(ni->tags, ((ni->naddrs + 1) * sizeof(ni_name)));
+ if (ni->tags == NULL) return;
+ }
+
+ ni->addrs[ni->naddrs] = addr;
+ ni->tags[ni->naddrs] = ni_name_dup(tag);
+ ni->naddrs++;
+}
+
static int
-addaddr(
- void *ni,
- ni_index ido,
- ni_name tag,
- ni_private *target_ni
- )
+addaddr(void *ni, ni_index ido, ni_name tag, ni_private *target_ni)
{
ni_id id;
ni_namelist nl;
int i;
id.nii_object = ido;
- if (ni_lookupprop(ni, &id, NAME_IP_ADDRESS, &nl) != NI_OK) {
- return (0);
- }
- if (nl.ninl_len == 0) {
- return(0);
- }
+ NI_INIT(&nl);
+ if (ni_lookupprop(ni, &id, NAME_IP_ADDRESS, &nl) != NI_OK) return 0;
- if (target_ni->naddrs == 0) {
- target_ni->addrs =
- (struct in_addr *)malloc(nl.ninl_len * sizeof(struct in_addr));
- target_ni->tags =
- (ni_name *)malloc(nl.ninl_len * sizeof(ni_name));
- } else {
- target_ni->addrs =
- (struct in_addr *)realloc(target_ni->addrs,
- ((target_ni->naddrs + nl.ninl_len) * sizeof(struct in_addr)));
- target_ni->tags =
- (ni_name *)realloc(target_ni->tags,
- ((target_ni->naddrs + nl.ninl_len) * sizeof(ni_name)));
+ if (nl.ni_namelist_len == 0) return 0;
+
+ if (target_ni->naddrs == 0)
+ {
+ target_ni->addrs = (struct in_addr *)malloc(nl.ni_namelist_len * sizeof(struct in_addr));
+ target_ni->tags = (ni_name *)malloc(nl.ni_namelist_len * sizeof(ni_name));
+ }
+ else
+ {
+ target_ni->addrs = (struct in_addr *)realloc(target_ni->addrs, ((target_ni->naddrs + nl.ni_namelist_len) * sizeof(struct in_addr)));
+ target_ni->tags = (ni_name *)realloc(target_ni->tags, ((target_ni->naddrs + nl.ni_namelist_len) * sizeof(ni_name)));
}
- for (i=0; i<nl.ninl_len; i++) {
- addr.s_addr = inet_addr(nl.ninl_val[i]);
+ for (i = 0; i < nl.ni_namelist_len; i++)
+ {
+ addr.s_addr = inet_addr(nl.ni_namelist_val[i]);
target_ni->addrs[target_ni->naddrs] = addr;
target_ni->tags[target_ni->naddrs] = ni_name_dup(tag);
target_ni->naddrs++;
}
ni_namelist_free(&nl);
- return (1);
+ return 1;
}
-
static int
-get_daddr(
- ni_private *ni,
- ni_name dom,
- ni_private *target_ni
- )
+get_daddr(ni_private *ni, ni_name dom, ni_private *target_ni)
{
- ni_id id;
+ ni_id nid;
ni_idlist ids;
- ni_namelist nl;
ni_entrylist entries;
+ ni_proplist pl;
ni_index i;
ni_index j;
ni_name tag;
- if (ni_root(ni, &id) != NI_OK) {
- return(0);
- }
-
- if (ni_lookup(ni, &id, NAME_NAME, NAME_MACHINES, &ids) != NI_OK) {
- return (0);
- }
-
- id.nii_object = ids.niil_val[0];
- ni_idlist_free(&ids);
-
- if (ni_list(ni, &id, NAME_SERVES, &entries) != NI_OK) {
- return (0);
- }
+ if (dom == NULL) return 0;
- for (i = 0; i < entries.niel_len; i++) {
- if (entries.niel_val[i].names != NULL) {
- nl = *entries.niel_val[i].names;
- for (j = 0; j < nl.ninl_len; j++) {
- if (match(dom, nl.ninl_val[j], &tag)) {
- if (addaddr(ni,
- entries.niel_val[i].id,
- tag,
- target_ni)) {
- ni_name_free(&tag);
- break;
+ if (!strcmp(dom, "."))
+ {
+ /* check for server list */
+ NI_INIT(&pl);
+ if (ni_statistics(ni, &pl) == NI_OK)
+ {
+ i = ni_proplist_match(pl, NAME_DOMAIN_SERVERS, NULL);
+ if (i != NI_INDEX_NULL)
+ {
+ if (pl.ni_proplist_val[i].nip_val.ni_namelist_len > 0)
+ {
+ for (j = 0; j < pl.ni_proplist_val[i].nip_val.ni_namelist_len; j++)
+ {
+ add_addr_tag(target_ni, pl.ni_proplist_val[i].nip_val.ni_namelist_val[j]);
}
- ni_name_free(&tag);
+ ni_proplist_free(&pl);
+ return 1;
}
}
+ ni_proplist_free(&pl);
}
-
}
- ni_entrylist_free(&entries);
- return (target_ni->naddrs > 0);
-}
+ if (ni_root(ni, &nid) != NI_OK) return 0;
+ NI_INIT(&ids);
+ if (ni_lookup(ni, &nid, NAME_NAME, NAME_MACHINES, &ids) != NI_OK) return 0;
-#ifdef notdef
-static int
-get_haddr(
- ni_private *ni,
- ni_name hname,
- ni_name tag,
- ni_private *target_ni
- )
-{
- ni_id id;
- ni_idlist ids;
-
- if (ni_root(ni, &id) != NI_OK) {
- return(0);
- }
- if (ni_lookup(ni, &id, NAME_NAME, NAME_MACHINES, &ids) != NI_OK) {
- return (0);
- }
- id.nii_object = ids.niil_val[0];
+ nid.nii_object = ids.niil_val[0];
ni_idlist_free(&ids);
- if (ni_lookup(ni, &id, NAME_NAME, hname, &ids) != NI_OK) {
- return (0);
- }
- id.nii_object = ids.niil_val[0];
- ni_idlist_free(&ids);
- if (!addaddr(ni, id.nii_object, tag, target_ni)) {
- return (0);
+ NI_INIT(&entries);
+ if (ni_list(ni, &nid, NAME_SERVES, &entries) != NI_OK) return 0;
+
+ for (i = 0; i < entries.niel_len; i++)
+ {
+ if (entries.niel_val[i].names == NULL) continue;
+
+ for (j = 0; j < entries.niel_val[i].names->ni_namelist_len; j++)
+ {
+ if (match(dom, entries.niel_val[i].names->ni_namelist_val[j], &tag))
+ {
+ addaddr(ni, entries.niel_val[i].id, tag, target_ni);
+ ni_name_free(&tag);
+ }
+ }
}
- return (1);
-}
-#endif
+ ni_entrylist_free(&entries);
+ return (target_ni->naddrs > 0);
+}
static ni_status
getparent(ni_private *oldni, ni_private **newni)
{
ni_rparent_res *resp;
- ni_private *ni;
+ ni_private *ni = NULL;
ni_private *dupni;
- int found;
+ int found = 0;
ni_index i;
struct in_addr raddr;
int printed = 0;
int inlist = 0;
- found = 0;
- while (!found) {
+ while (found == 0)
+ {
/*
* First, find our parent, any parent
*/
- for (;;) {
+ for (;;)
+ {
resp = RCALLIT(oldni, _ni_rparent_2, NULL);
- if (resp == NULL) {
- return (NI_FAILED);
- }
- if (resp->status != NI_NORESPONSE) {
- break;
- }
- if (!printed) {
+ if (resp == NULL) return NI_FAILED;
+ if (resp->status != NI_NORESPONSE) break;
+
+ if (!printed)
+ {
syslog(LOG_ERR, "NetInfo timeout finding server for parent of %s/%s, sleeping",
inet_ntoa(oldni->addrs[0]), oldni->tags[0]);
printed++;
}
+
sleep(NI_SLEEPTIME);
}
- if (printed) {
+
+ if (printed)
+ {
raddr.s_addr = htonl(resp->ni_rparent_res_u.binding.addr);
syslog(LOG_ERR, "NetInfo %s/%s found parent %s/%s",
inet_ntoa(oldni->addrs[0]), oldni->tags[0],
inet_ntoa(raddr), resp->ni_rparent_res_u.binding.tag);
}
- if (resp->status != NI_OK) {
- return (resp->status);
- }
+
+ if (resp->status != NI_OK) return (resp->status);
+
ni = ni_alloc();
*ni = *oldni;
ni_clear(ni);
ni = ni_alloc();
*ni = *dupni;
ni_clear(ni);
- if (get_daddr(dupni, ".", ni)) {
-
+ if (get_daddr(dupni, ".", ni) == 0)
+ {
+ if (oldni->abort == 1) break;
+ }
+ else
+ {
/*
- * Now make sure returned parent is head of
- * list
+ * Make sure returned parent is head of list
*/
- for (i = 0; i < ni->naddrs; i++) {
- if (ni->addrs[i].s_addr ==
- dupni->addrs[0].s_addr) {
+ for (i = 0; i < ni->naddrs; i++)
+ {
+ if (ni->addrs[i].s_addr == dupni->addrs[0].s_addr)
+ {
ni_switch(ni, i);
inlist++;
break;
dupni->tsock = -1;
dupni->tport = -1;
dupni->tc = NULL;
- found++;
+ found = 1;
/*
* If returned parent wasn't in list, it's a rogue.
* Log an error and drop the connection.
*/
- if (inlist == 0) {
+ if (inlist == 0)
+ {
syslog(LOG_ERR, "Rogue NetInfo server detected: %s/%s",
inet_ntoa(dupni->addrs[0]), dupni->tags[0]);
reinit(ni);
}
ni_free(dupni);
}
- if (found) {
+
+ if (found)
+ {
*newni = ni;
- return (NI_OK);
- } else {
- ni_free(ni);
- return (NI_FAILED);
+ return NI_OK;
}
+
+ if (ni != NULL) ni_free(ni);
+ return NI_FAILED;
}
if (ni_root(ni, &id) != NI_OK) {
return(NI_NOUSER);
}
+ NI_INIT(&ids);
if (ni_lookup(ni, &id, NAME_NAME, NAME_USERS, &ids) != NI_OK) {
return (NI_NOUSER);
}
id.nii_object = ids.niil_val[0];
ni_idlist_free(&ids);
+ NI_INIT(&ids);
if (ni_lookup(ni, &id, NAME_NAME, user, &ids) != NI_OK) {
return (NI_NOUSER);
}
id.nii_object = ids.niil_val[0];
ni_idlist_free(&ids);
+ NI_INIT(&nl);
if (ni_lookupprop(ni, &id, NAME_UID, &nl) != NI_OK) {
return (NI_NOUSER);
}
)
{
int sock;
-
+ int reuse = 1;
+
/*
* If no port number given ask the pmap for one
*/
return (-1);
}
(void)bindresvport(sock, (struct sockaddr_in *)0);
+ setsockopt(sock, SOL_SOCKET, SO_REUSEPORT, &reuse, sizeof(int));
if (proto == IPPROTO_TCP) {
if (connect(sock, (struct sockaddr *)raddr,
sizeof(*raddr)) < 0) {