#ifdef HAVE_DIX_CONFIG_H
#include <dix-config.h>
#endif
#ifdef WIN32
#include <X11/Xwinsock.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#define XSERV_t
#define TRANS_SERVER
#define TRANS_REOPEN
#include <X11/Xtrans/Xtrans.h>
#include <X11/Xauth.h>
#include <X11/X.h>
#include <X11/Xproto.h>
#include "misc.h"
#include "site.h"
#include <errno.h>
#include <sys/types.h>
#ifndef WIN32
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <ctype.h>
#if defined(TCPCONN) || defined(STREAMSCONN) || defined(__SCO__)
#include <netinet/in.h>
#endif
#ifdef DNETCONN
#include <netdnet/dn.h>
#include <netdnet/dnetdb.h>
#endif
#ifdef HAS_GETPEERUCRED
# include <ucred.h>
# ifdef sun
# include <zone.h>
# endif
#endif
#if defined(SVR4) || (defined(SYSV) && defined(__i386__)) || defined(__GNU__)
# include <sys/utsname.h>
#endif
#if defined(SYSV) && defined(__i386__)
# include <sys/stream.h>
#endif
#ifdef __GNU__
#undef SIOCGIFCONF
#include <netdb.h>
#else
# include <net/if.h>
#endif
#ifdef SVR4
#include <sys/sockio.h>
#include <sys/stropts.h>
#endif
#include <netdb.h>
#ifdef CSRG_BASED
#include <sys/param.h>
#if (BSD >= 199103)
#define VARIABLE_IFREQ
#endif
#endif
#ifdef BSD44SOCKETS
#ifndef VARIABLE_IFREQ
#define VARIABLE_IFREQ
#endif
#endif
#ifdef HAS_GETIFADDRS
#include <ifaddrs.h>
#endif
#ifdef SIOCGLIFCONF
#define USE_SIOCGLIFCONF
#endif
#endif
#ifndef PATH_MAX
#include <sys/param.h>
#ifndef PATH_MAX
#ifdef MAXPATHLEN
#define PATH_MAX MAXPATHLEN
#else
#define PATH_MAX 1024
#endif
#endif
#endif
#ifdef __SCO__
#undef PATH_MAX
#endif
#define X_INCLUDE_NETDB_H
#include <X11/Xos_r.h>
#include "dixstruct.h"
#include "osdep.h"
#include "xace.h"
#ifndef PATH_MAX
#ifdef MAXPATHLEN
#define PATH_MAX MAXPATHLEN
#else
#define PATH_MAX 1024
#endif
#endif
Bool defeatAccessControl = FALSE;
#define acmp(a1, a2, len) memcmp((char *)(a1), (char *)(a2), len)
#define acopy(a1, a2, len) memmove((char *)(a2), (char *)(a1), len)
#define addrEqual(fam, address, length, host) \
((fam) == (host)->family &&\
(length) == (host)->len &&\
!acmp (address, (host)->addr, length))
static int ConvertAddr(struct sockaddr * ,
int * ,
pointer * );
static int CheckAddr(int ,
pointer ,
unsigned );
static Bool NewHost(int ,
pointer ,
int ,
int );
typedef struct _host {
short family;
short len;
unsigned char *addr;
struct _host *next;
int requested;
} HOST;
#define MakeHost(h,l) (h)=(HOST *) xalloc(sizeof *(h)+(l));\
if (h) { \
(h)->addr=(unsigned char *) ((h) + 1);\
(h)->requested = FALSE; \
}
#define FreeHost(h) xfree(h)
static HOST *selfhosts = NULL;
static HOST *validhosts = NULL;
static int AccessEnabled = DEFAULT_ACCESS_CONTROL;
static int LocalHostEnabled = FALSE;
static int LocalHostRequested = FALSE;
static int UsingXdmcp = FALSE;
static Bool siAddrMatch(int family, pointer addr, int len, HOST *host,
ClientPtr client);
static int siCheckAddr(const char *addrString, int length);
static void siTypesInitialize(void);
void
EnableLocalHost (void)
{
if (!UsingXdmcp)
{
LocalHostEnabled = TRUE;
AddLocalHosts ();
}
}
void
DisableLocalHost (void)
{
HOST *self;
if (!LocalHostRequested)
LocalHostEnabled = FALSE;
for (self = selfhosts; self; self = self->next) {
if (!self->requested)
(void) RemoveHost ((ClientPtr)NULL, self->family, self->len, (pointer)self->addr);
}
}
void
AccessUsingXdmcp (void)
{
UsingXdmcp = TRUE;
LocalHostEnabled = FALSE;
}
#if defined(SVR4) && !defined(SCO325) && !defined(sun) && defined(SIOCGIFCONF) && !defined(USE_SIOCGLIFCONF)
static int
ifioctl (int fd, int cmd, char *arg)
{
struct strioctl ioc;
int ret;
bzero((char *) &ioc, sizeof(ioc));
ioc.ic_cmd = cmd;
ioc.ic_timout = 0;
if (cmd == SIOCGIFCONF)
{
ioc.ic_len = ((struct ifconf *) arg)->ifc_len;
ioc.ic_dp = ((struct ifconf *) arg)->ifc_buf;
}
else
{
ioc.ic_len = sizeof(struct ifreq);
ioc.ic_dp = arg;
}
ret = ioctl(fd, I_STR, (char *) &ioc);
if (ret >= 0 && cmd == SIOCGIFCONF)
#ifdef SVR4
((struct ifconf *) arg)->ifc_len = ioc.ic_len;
#endif
return(ret);
}
#else
#define ifioctl ioctl
#endif
#if !defined(SIOCGIFCONF)
void
DefineSelf (int fd)
{
#if !defined(TCPCONN) && !defined(STREAMSCONN) && !defined(UNIXCONN) && !defined(MNX_TCPCONN)
return;
#else
register int n;
int len;
caddr_t addr;
int family;
register HOST *host;
#ifndef WIN32
struct utsname name;
#else
struct {
char nodename[512];
} name;
#endif
register struct hostent *hp;
union {
struct sockaddr sa;
struct sockaddr_in in;
#if defined(IPv6) && defined(AF_INET6)
struct sockaddr_in6 in6;
#endif
} saddr;
struct sockaddr_in *inetaddr;
struct sockaddr_in6 *inet6addr;
struct sockaddr_in broad_addr;
#ifdef XTHREADS_NEEDS_BYNAMEPARAMS
_Xgethostbynameparams hparams;
#endif
#ifndef WIN32
uname(&name);
#else
gethostname(name.nodename, sizeof(name.nodename));
#endif
hp = _XGethostbyname(name.nodename, hparams);
if (hp != NULL)
{
saddr.sa.sa_family = hp->h_addrtype;
switch (hp->h_addrtype) {
case AF_INET:
inetaddr = (struct sockaddr_in *) (&(saddr.sa));
acopy ( hp->h_addr, &(inetaddr->sin_addr), hp->h_length);
len = sizeof(saddr.sa);
break;
#if defined(IPv6) && defined(AF_INET6)
case AF_INET6:
inet6addr = (struct sockaddr_in6 *) (&(saddr.sa));
acopy ( hp->h_addr, &(inet6addr->sin6_addr), hp->h_length);
len = sizeof(saddr.in6);
break;
#endif
default:
goto DefineLocalHost;
}
family = ConvertAddr ( &(saddr.sa), &len, (pointer *)&addr);
if ( family != -1 && family != FamilyLocal )
{
for (host = selfhosts;
host && !addrEqual (family, addr, len, host);
host = host->next) ;
if (!host)
{
MakeHost(host,len)
if (host)
{
host->family = family;
host->len = len;
acopy ( addr, host->addr, len);
host->next = selfhosts;
selfhosts = host;
}
#ifdef XDMCP
if (family == FamilyInternet &&
!(len == 4 &&
((addr[0] == 127 && addr[1] == 0 &&
addr[2] == 0 && addr[3] == 1) ||
(addr[0] == 0 && addr[1] == 0 &&
addr[2] == 0 && addr[3] == 0)))
)
{
XdmcpRegisterConnection (family, (char *)addr, len);
broad_addr = *inetaddr;
((struct sockaddr_in *) &broad_addr)->sin_addr.s_addr =
htonl (INADDR_BROADCAST);
XdmcpRegisterBroadcastAddress ((struct sockaddr_in *)
&broad_addr);
}
#if defined(IPv6) && defined(AF_INET6)
else if (family == FamilyInternet6 &&
!(IN6_IS_ADDR_LOOPBACK((struct in6_addr *)addr)))
{
XdmcpRegisterConnection (family, (char *)addr, len);
}
#endif
#endif
}
}
}
DefineLocalHost:
for (host = selfhosts;
host && !addrEqual(FamilyLocalHost, "", 0, host);
host = host->next);
if (!host)
{
MakeHost(host, 0);
if (host)
{
host->family = FamilyLocalHost;
host->len = 0;
acopy("", host->addr, 0);
host->next = selfhosts;
selfhosts = host;
}
}
#endif
}
#else
#ifdef USE_SIOCGLIFCONF
#define ifr_type struct lifreq
#else
#define ifr_type struct ifreq
#endif
#ifdef VARIABLE_IFREQ
#define ifr_size(p) (sizeof (struct ifreq) + \
(p->ifr_addr.sa_len > sizeof (p->ifr_addr) ? \
p->ifr_addr.sa_len - sizeof (p->ifr_addr) : 0))
#define ifraddr_size(a) (a.sa_len)
#else
#define ifr_size(p) (sizeof (ifr_type))
#define ifraddr_size(a) (sizeof (a))
#endif
#if defined(IPv6) && defined(AF_INET6)
#include <arpa/inet.h>
#endif
#if defined(IPv6) && defined(AF_INET6)
static void
in6_fillscopeid(struct sockaddr_in6 *sin6)
{
#if defined(__KAME__)
if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) {
sin6->sin6_scope_id =
ntohs(*(u_int16_t *)&sin6->sin6_addr.s6_addr[2]);
sin6->sin6_addr.s6_addr[2] = sin6->sin6_addr.s6_addr[3] = 0;
}
#endif
}
#endif
void
DefineSelf (int fd)
{
#ifndef HAS_GETIFADDRS
char *cp, *cplim;
# ifdef USE_SIOCGLIFCONF
struct sockaddr_storage buf[16];
struct lifconf ifc;
register struct lifreq *ifr;
# ifdef SIOCGLIFNUM
struct lifnum ifn;
# endif
# else
char buf[2048];
struct ifconf ifc;
register struct ifreq *ifr;
# endif
void * bufptr = buf;
#else
struct ifaddrs * ifap, *ifr;
#endif
int len;
unsigned char * addr;
int family;
register HOST *host;
#ifdef DNETCONN
struct dn_naddr *dnaddr = getnodeadd();
if (dnaddr)
{
addr = (unsigned char *) dnaddr;
len = dnaddr->a_len + sizeof(dnaddr->a_len);
family = FamilyDECnet;
for (host = selfhosts;
host && !addrEqual (family, addr, len, host);
host = host->next)
;
if (!host)
{
MakeHost(host,len)
if (host)
{
host->family = family;
host->len = len;
acopy(addr, host->addr, len);
host->next = selfhosts;
selfhosts = host;
}
}
}
#endif
#ifndef HAS_GETIFADDRS
len = sizeof(buf);
#ifdef USE_SIOCGLIFCONF
#ifdef SIOCGLIFNUM
ifn.lifn_family = AF_UNSPEC;
ifn.lifn_flags = 0;
if (ioctl (fd, SIOCGLIFNUM, (char *) &ifn) < 0)
Error ("Getting interface count");
if (len < (ifn.lifn_count * sizeof(struct lifreq))) {
len = ifn.lifn_count * sizeof(struct lifreq);
bufptr = xalloc(len);
}
#endif
ifc.lifc_family = AF_UNSPEC;
ifc.lifc_flags = 0;
ifc.lifc_len = len;
ifc.lifc_buf = bufptr;
#define IFC_IOCTL_REQ SIOCGLIFCONF
#define IFC_IFC_REQ ifc.lifc_req
#define IFC_IFC_LEN ifc.lifc_len
#define IFR_IFR_ADDR ifr->lifr_addr
#define IFR_IFR_NAME ifr->lifr_name
#else
ifc.ifc_len = len;
ifc.ifc_buf = bufptr;
#define IFC_IOCTL_REQ SIOCGIFCONF
#define IFC_IFC_REQ ifc.ifc_req
#define IFC_IFC_LEN ifc.ifc_len
#define IFR_IFR_ADDR ifr->ifr_addr
#define IFR_IFR_NAME ifr->ifr_name
#endif
if (ifioctl (fd, IFC_IOCTL_REQ, (pointer) &ifc) < 0)
Error ("Getting interface configuration (4)");
cplim = (char *) IFC_IFC_REQ + IFC_IFC_LEN;
for (cp = (char *) IFC_IFC_REQ; cp < cplim; cp += ifr_size (ifr))
{
ifr = (ifr_type *) cp;
len = ifraddr_size (IFR_IFR_ADDR);
family = ConvertAddr ((struct sockaddr *) &IFR_IFR_ADDR,
&len, (pointer *)&addr);
#ifdef DNETCONN
if (family == AF_DECnet)
continue;
#endif
if (family == -1 || family == FamilyLocal)
continue;
#if defined(IPv6) && defined(AF_INET6)
if (family == FamilyInternet6)
in6_fillscopeid((struct sockaddr_in6 *)&IFR_IFR_ADDR);
#endif
for (host = selfhosts;
host && !addrEqual (family, addr, len, host);
host = host->next)
;
if (host)
continue;
MakeHost(host,len)
if (host)
{
host->family = family;
host->len = len;
acopy(addr, host->addr, len);
host->next = selfhosts;
selfhosts = host;
}
#ifdef XDMCP
{
#ifdef USE_SIOCGLIFCONF
struct sockaddr_storage broad_addr;
#else
struct sockaddr broad_addr;
#endif
if (family != FamilyInternet
#if defined(IPv6) && defined(AF_INET6)
&& family != FamilyInternet6
#endif
)
continue;
if (family == FamilyInternet &&
addr[0] == 127 && addr[1] == 0 &&
addr[2] == 0 && addr[3] == 1)
continue;
#if defined(IPv6) && defined(AF_INET6)
else if (family == FamilyInternet6 &&
IN6_IS_ADDR_LOOPBACK((struct in6_addr *)addr))
continue;
#endif
if (len == 4 &&
addr[0] == 0 && addr[1] == 0 &&
addr[2] == 0 && addr[3] == 0)
continue;
XdmcpRegisterConnection (family, (char *)addr, len);
#if defined(IPv6) && defined(AF_INET6)
if (family == FamilyInternet6)
continue;
#endif
broad_addr = IFR_IFR_ADDR;
((struct sockaddr_in *) &broad_addr)->sin_addr.s_addr =
htonl (INADDR_BROADCAST);
#if defined(USE_SIOCGLIFCONF) && defined(SIOCGLIFBRDADDR)
{
struct lifreq broad_req;
broad_req = *ifr;
if (ioctl (fd, SIOCGLIFFLAGS, (char *) &broad_req) != -1 &&
(broad_req.lifr_flags & IFF_BROADCAST) &&
(broad_req.lifr_flags & IFF_UP)
)
{
broad_req = *ifr;
if (ioctl (fd, SIOCGLIFBRDADDR, &broad_req) != -1)
broad_addr = broad_req.lifr_broadaddr;
else
continue;
}
else
continue;
}
#elif defined(SIOCGIFBRDADDR)
{
struct ifreq broad_req;
broad_req = *ifr;
if (ifioctl (fd, SIOCGIFFLAGS, (pointer) &broad_req) != -1 &&
(broad_req.ifr_flags & IFF_BROADCAST) &&
(broad_req.ifr_flags & IFF_UP)
)
{
broad_req = *ifr;
if (ifioctl (fd, SIOCGIFBRDADDR, (pointer) &broad_req) != -1)
broad_addr = broad_req.ifr_addr;
else
continue;
}
else
continue;
}
#endif
XdmcpRegisterBroadcastAddress ((struct sockaddr_in *) &broad_addr);
}
#endif
}
if (bufptr != buf)
free(bufptr);
#else
if (getifaddrs(&ifap) < 0) {
ErrorF("Warning: getifaddrs returns %s\n", strerror(errno));
return;
}
for (ifr = ifap; ifr != NULL; ifr = ifr->ifa_next) {
if (!ifr->ifa_addr)
continue;
#ifdef DNETCONN
if (ifr->ifa_addr.sa_family == AF_DECnet)
continue;
#endif
len = sizeof(*(ifr->ifa_addr));
family = ConvertAddr(ifr->ifa_addr, &len, (pointer *)&addr);
if (family == -1 || family == FamilyLocal)
continue;
#if defined(IPv6) && defined(AF_INET6)
if (family == FamilyInternet6)
in6_fillscopeid((struct sockaddr_in6 *)ifr->ifa_addr);
#endif
for (host = selfhosts;
host != NULL && !addrEqual(family, addr, len, host);
host = host->next)
;
if (host != NULL)
continue;
MakeHost(host, len);
if (host != NULL) {
host->family = family;
host->len = len;
acopy(addr, host->addr, len);
host->next = selfhosts;
selfhosts = host;
}
#ifdef XDMCP
{
struct sockaddr broad_addr;
if (family != FamilyInternet
#if defined(IPv6) && defined(AF_INET6)
&& family != FamilyInternet6
#endif
)
continue;
if (ifr->ifa_flags & IFF_LOOPBACK)
continue;
if (family == FamilyInternet &&
addr[0] == 127 && addr[1] == 0 &&
addr[2] == 0 && addr[3] == 1)
continue;
if (len == 4 &&
addr[0] == 0 && addr[1] == 0 &&
addr[2] == 0 && addr[3] == 0)
continue;
#if defined(IPv6) && defined(AF_INET6)
else if (family == FamilyInternet6 &&
IN6_IS_ADDR_LOOPBACK((struct in6_addr *)addr))
continue;
#endif
XdmcpRegisterConnection(family, (char *)addr, len);
#if defined(IPv6) && defined(AF_INET6)
if (family == FamilyInternet6)
continue;
#endif
if ((ifr->ifa_flags & IFF_BROADCAST) &&
(ifr->ifa_flags & IFF_UP))
broad_addr = *ifr->ifa_broadaddr;
else
continue;
XdmcpRegisterBroadcastAddress((struct sockaddr_in *)
&broad_addr);
}
#endif
}
freeifaddrs(ifap);
#endif
for (host = selfhosts;
host && !addrEqual(FamilyLocalHost, "", 0, host);
host = host->next);
if (!host)
{
MakeHost(host, 0);
if (host)
{
host->family = FamilyLocalHost;
host->len = 0;
acopy("", host->addr, 0);
host->next = selfhosts;
selfhosts = host;
}
}
}
#endif
#ifdef XDMCP
void
AugmentSelf(pointer from, int len)
{
int family;
pointer addr;
register HOST *host;
family = ConvertAddr(from, &len, (pointer *)&addr);
if (family == -1 || family == FamilyLocal)
return;
for (host = selfhosts; host; host = host->next)
{
if (addrEqual(family, addr, len, host))
return;
}
MakeHost(host,len)
if (!host)
return;
host->family = family;
host->len = len;
acopy(addr, host->addr, len);
host->next = selfhosts;
selfhosts = host;
}
#endif
void
AddLocalHosts (void)
{
HOST *self;
for (self = selfhosts; self; self = self->next)
(void) NewHost (self->family, self->addr, self->len, TRUE);
}
void
ResetHosts (char *display)
{
register HOST *host;
char lhostname[120], ohostname[120];
char *hostname = ohostname;
char fname[PATH_MAX + 1];
int fnamelen;
FILE *fd;
char *ptr;
int i, hostlen;
#if ((defined(TCPCONN) || defined(STREAMSCONN) || defined(MNX_TCPCONN)) && \
(!defined(IPv6) || !defined(AF_INET6))) || defined(DNETCONN)
union {
struct sockaddr sa;
#if defined(TCPCONN) || defined(STREAMSCONN) || defined(MNX_TCPCONN)
struct sockaddr_in in;
#endif
#ifdef DNETCONN
struct sockaddr_dn dn;
#endif
} saddr;
#endif
#ifdef DNETCONN
struct nodeent *np;
struct dn_naddr dnaddr, *dnaddrp, *dnet_addr();
#endif
int family = 0;
pointer addr;
int len;
siTypesInitialize();
AccessEnabled = defeatAccessControl ? FALSE : DEFAULT_ACCESS_CONTROL;
LocalHostEnabled = FALSE;
while ((host = validhosts) != 0)
{
validhosts = host->next;
FreeHost (host);
}
#if defined WIN32 && defined __MINGW32__
#define ETC_HOST_PREFIX "X"
#else
#define ETC_HOST_PREFIX "/etc/X"
#endif
#define ETC_HOST_SUFFIX ".hosts"
fnamelen = strlen(ETC_HOST_PREFIX) + strlen(ETC_HOST_SUFFIX) +
strlen(display) + 1;
if (fnamelen > sizeof(fname))
FatalError("Display name `%s' is too long\n", display);
snprintf(fname, sizeof(fname), ETC_HOST_PREFIX "%s" ETC_HOST_SUFFIX,
display);
if ((fd = fopen (fname, "r")) != 0)
{
while (fgets (ohostname, sizeof (ohostname), fd))
{
family = FamilyWild;
if (*ohostname == '#')
continue;
if ((ptr = strchr(ohostname, '\n')) != 0)
*ptr = 0;
hostlen = strlen(ohostname) + 1;
for (i = 0; i < hostlen; i++)
lhostname[i] = tolower(ohostname[i]);
hostname = ohostname;
if (!strncmp("local:", lhostname, 6))
{
family = FamilyLocalHost;
NewHost(family, "", 0, FALSE);
LocalHostRequested = TRUE;
}
#if defined(TCPCONN) || defined(STREAMSCONN) || defined(MNX_TCPCONN)
else if (!strncmp("inet:", lhostname, 5))
{
family = FamilyInternet;
hostname = ohostname + 5;
}
#if defined(IPv6) && defined(AF_INET6)
else if (!strncmp("inet6:", lhostname, 6))
{
family = FamilyInternet6;
hostname = ohostname + 6;
}
#endif
#endif
#ifdef DNETCONN
else if (!strncmp("dnet:", lhostname, 5))
{
family = FamilyDECnet;
hostname = ohostname + 5;
}
#endif
#ifdef SECURE_RPC
else if (!strncmp("nis:", lhostname, 4))
{
family = FamilyNetname;
hostname = ohostname + 4;
}
#endif
else if (!strncmp("si:", lhostname, 3))
{
family = FamilyServerInterpreted;
hostname = ohostname + 3;
hostlen -= 3;
}
if (family == FamilyServerInterpreted)
{
len = siCheckAddr(hostname, hostlen);
if (len >= 0) {
NewHost(family, hostname, len, FALSE);
}
}
else
#ifdef DNETCONN
if ((family == FamilyDECnet) || ((family == FamilyWild) &&
(ptr = strchr(hostname, ':')) && (*(ptr + 1) == ':') &&
!(*ptr = '\0')))
{
dnaddrp = dnet_addr(hostname);
if (!dnaddrp && (np = getnodebyname (hostname)))
{
saddr.sa.sa_family = np->n_addrtype;
len = sizeof(saddr.sa);
if (ConvertAddr (&saddr.sa, &len, (pointer *)&addr) == FamilyDECnet)
{
bzero ((char *) &dnaddr, sizeof (dnaddr));
dnaddr.a_len = np->n_length;
acopy (np->n_addr, dnaddr.a_addr, np->n_length);
dnaddrp = &dnaddr;
}
}
if (dnaddrp)
(void) NewHost(FamilyDECnet, (pointer)dnaddrp,
(int)(dnaddrp->a_len + sizeof(dnaddrp->a_len)), FALSE);
}
else
#endif
#ifdef SECURE_RPC
if ((family == FamilyNetname) || (strchr(hostname, '@')))
{
SecureRPCInit ();
(void) NewHost (FamilyNetname, hostname, strlen (hostname), FALSE);
}
else
#endif
#if defined(TCPCONN) || defined(STREAMSCONN) || defined(MNX_TCPCONN)
{
#if defined(IPv6) && defined(AF_INET6)
if ( (family == FamilyInternet) || (family == FamilyInternet6) ||
(family == FamilyWild) )
{
struct addrinfo *addresses;
struct addrinfo *a;
int f;
if (getaddrinfo(hostname, NULL, NULL, &addresses) == 0) {
for (a = addresses ; a != NULL ; a = a->ai_next) {
len = a->ai_addrlen;
f = ConvertAddr(a->ai_addr,&len,(pointer *)&addr);
if ( (family == f) ||
((family == FamilyWild) && (f != -1)) ) {
NewHost(f, addr, len, FALSE);
}
}
freeaddrinfo(addresses);
}
}
#else
#ifdef XTHREADS_NEEDS_BYNAMEPARAMS
_Xgethostbynameparams hparams;
#endif
register struct hostent *hp;
if ((family == FamilyInternet &&
((hp = _XGethostbyname(hostname, hparams)) != 0)) ||
((hp = _XGethostbyname(hostname, hparams)) != 0))
{
saddr.sa.sa_family = hp->h_addrtype;
len = sizeof(saddr.sa);
if ((family = ConvertAddr (&saddr.sa, &len, (pointer *)&addr)) != -1)
{
#ifdef h_addr
char **list;
for (list = hp->h_addr_list; *list; list++)
(void) NewHost (family, (pointer)*list, len, FALSE);
#else
(void) NewHost (family, (pointer)hp->h_addr, len, FALSE);
#endif
}
}
#endif
}
#endif
family = FamilyWild;
}
fclose (fd);
}
}
_X_EXPORT Bool LocalClient(ClientPtr client)
{
int alen, family, notused;
Xtransaddr *from = NULL;
pointer addr;
register HOST *host;
if (!_XSERVTransGetPeerAddr (((OsCommPtr)client->osPrivate)->trans_conn,
¬used, &alen, &from))
{
family = ConvertAddr ((struct sockaddr *) from,
&alen, (pointer *)&addr);
if (family == -1)
{
xfree ((char *) from);
return FALSE;
}
if (family == FamilyLocal)
{
xfree ((char *) from);
return TRUE;
}
for (host = selfhosts; host; host = host->next)
{
if (addrEqual (family, addr, alen, host))
return TRUE;
}
xfree ((char *) from);
}
return FALSE;
}
int
LocalClientCred(ClientPtr client, int *pUid, int *pGid)
{
LocalClientCredRec *lcc;
int ret = GetLocalClientCreds(client, &lcc);
if (ret == 0) {
#ifdef HAVE_GETZONEID
if ((lcc->fieldsSet & LCC_ZID_SET) && (lcc->zoneid != getzoneid())) {
FreeLocalClientCreds(lcc);
return -1;
}
#endif
if ((lcc->fieldsSet & LCC_UID_SET) && (pUid != NULL))
*pUid = lcc->euid;
if ((lcc->fieldsSet & LCC_GID_SET) && (pGid != NULL))
*pGid = lcc->egid;
FreeLocalClientCreds(lcc);
}
return ret;
}
int
GetLocalClientCreds(ClientPtr client, LocalClientCredRec **lccp)
{
#if defined(HAS_GETPEEREID) || defined(HAS_GETPEERUCRED) || defined(SO_PEERCRED)
int fd;
XtransConnInfo ci;
LocalClientCredRec *lcc;
#ifdef HAS_GETPEEREID
uid_t uid;
gid_t gid;
#elif defined(HAS_GETPEERUCRED)
ucred_t *peercred = NULL;
const gid_t *gids;
#elif defined(SO_PEERCRED)
struct ucred peercred;
socklen_t so_len = sizeof(peercred);
#endif
if (client == NULL)
return -1;
ci = ((OsCommPtr)client->osPrivate)->trans_conn;
#if !(defined(sun) && defined(HAS_GETPEERUCRED))
if (!_XSERVTransIsLocal(ci)) {
return -1;
}
#endif
*lccp = Xcalloc(sizeof(LocalClientCredRec));
if (*lccp == NULL)
return -1;
lcc = *lccp;
fd = _XSERVTransGetConnectionNumber(ci);
#ifdef HAS_GETPEEREID
if (getpeereid(fd, &uid, &gid) == -1) {
FreeLocalClientCreds(lcc);
return -1;
}
lcc->euid = uid;
lcc->egid = gid;
lcc->fieldsSet = LCC_UID_SET | LCC_GID_SET;
return 0;
#elif defined(HAS_GETPEERUCRED)
if (getpeerucred(fd, &peercred) < 0) {
FreeLocalClientCreds(lcc);
return -1;
}
lcc->euid = ucred_geteuid(peercred);
if (lcc->euid != -1)
lcc->fieldsSet |= LCC_UID_SET;
lcc->egid = ucred_getegid(peercred);
if (lcc->egid != -1)
lcc->fieldsSet |= LCC_GID_SET;
lcc->pid = ucred_getpid(peercred);
if (lcc->pid != -1)
lcc->fieldsSet |= LCC_PID_SET;
#ifdef HAVE_GETZONEID
lcc->zoneid = ucred_getzoneid(peercred);
if (lcc->zoneid != -1)
lcc->fieldsSet |= LCC_ZID_SET;
#endif
lcc->nSuppGids = ucred_getgroups(peercred, &gids);
if (lcc->nSuppGids > 0) {
lcc->pSuppGids = Xcalloc((lcc->nSuppGids) * sizeof(int));
if (lcc->pSuppGids == NULL) {
lcc->nSuppGids = 0;
} else {
int i;
for (i = 0 ; i < lcc->nSuppGids; i++) {
(lcc->pSuppGids)[i] = (int) gids[i];
}
}
} else {
lcc->nSuppGids = 0;
}
ucred_free(peercred);
return 0;
#elif defined(SO_PEERCRED)
if (getsockopt(fd, SOL_SOCKET, SO_PEERCRED, &peercred, &so_len) == -1) {
FreeLocalClientCreds(lcc);
return -1;
}
lcc->euid = peercred.uid;
lcc->egid = peercred.gid;
lcc->pid = peercred.pid;
lcc->fieldsSet = LCC_UID_SET | LCC_GID_SET | LCC_PID_SET;
return 0;
#endif
#else
#define NO_LOCAL_CLIENT_CRED
return -1;
#endif
}
void
FreeLocalClientCreds(LocalClientCredRec *lcc)
{
if (lcc != NULL) {
if (lcc->nSuppGids > 0) {
Xfree(lcc->pSuppGids);
}
Xfree(lcc);
}
}
static int
AuthorizedClient(ClientPtr client)
{
int rc;
if (!client || defeatAccessControl)
return Success;
rc = XaceHook(XACE_SERVER_ACCESS, client, DixManageAccess);
if (rc != Success)
return rc;
return LocalClient(client) ? Success : BadAccess;
}
int
AddHost (ClientPtr client,
int family,
unsigned length,
pointer pAddr)
{
int rc, len;
rc = AuthorizedClient(client);
if (rc != Success)
return rc;
switch (family) {
case FamilyLocalHost:
len = length;
LocalHostEnabled = TRUE;
break;
#ifdef SECURE_RPC
case FamilyNetname:
len = length;
SecureRPCInit ();
break;
#endif
case FamilyInternet:
#if defined(IPv6) && defined(AF_INET6)
case FamilyInternet6:
#endif
case FamilyDECnet:
case FamilyChaos:
case FamilyServerInterpreted:
if ((len = CheckAddr (family, pAddr, length)) < 0)
{
client->errorValue = length;
return (BadValue);
}
break;
case FamilyLocal:
default:
client->errorValue = family;
return (BadValue);
}
if (NewHost (family, pAddr, len, FALSE))
return Success;
return BadAlloc;
}
Bool
ForEachHostInFamily (int family,
Bool (*func)(
unsigned char * ,
short ,
pointer ),
pointer closure)
{
HOST *host;
for (host = validhosts; host; host = host->next)
if (family == host->family && func (host->addr, host->len, closure))
return TRUE;
return FALSE;
}
static Bool
NewHost (int family,
pointer addr,
int len,
int addingLocalHosts)
{
register HOST *host;
for (host = validhosts; host; host = host->next)
{
if (addrEqual (family, addr, len, host))
return TRUE;
}
if (!addingLocalHosts) {
for (host = selfhosts; host; host = host->next) {
if (addrEqual (family, addr, len, host)) {
host->requested = TRUE;
break;
}
}
}
MakeHost(host,len)
if (!host)
return FALSE;
host->family = family;
host->len = len;
acopy(addr, host->addr, len);
host->next = validhosts;
validhosts = host;
return TRUE;
}
int
RemoveHost (
ClientPtr client,
int family,
unsigned length,
pointer pAddr)
{
int rc, len;
register HOST *host, **prev;
rc = AuthorizedClient(client);
if (rc != Success)
return rc;
switch (family) {
case FamilyLocalHost:
len = length;
LocalHostEnabled = FALSE;
break;
#ifdef SECURE_RPC
case FamilyNetname:
len = length;
break;
#endif
case FamilyInternet:
#if defined(IPv6) && defined(AF_INET6)
case FamilyInternet6:
#endif
case FamilyDECnet:
case FamilyChaos:
case FamilyServerInterpreted:
if ((len = CheckAddr (family, pAddr, length)) < 0)
{
client->errorValue = length;
return(BadValue);
}
break;
case FamilyLocal:
default:
client->errorValue = family;
return(BadValue);
}
for (prev = &validhosts;
(host = *prev) && (!addrEqual (family, pAddr, len, host));
prev = &host->next)
;
if (host)
{
*prev = host->next;
FreeHost (host);
}
return (Success);
}
int
GetHosts (
pointer *data,
int *pnHosts,
int *pLen,
BOOL *pEnabled)
{
int len;
register int n = 0;
register unsigned char *ptr;
register HOST *host;
int nHosts = 0;
*pEnabled = AccessEnabled ? EnableAccess : DisableAccess;
for (host = validhosts; host; host = host->next)
{
nHosts++;
n += (((host->len + 3) >> 2) << 2) + sizeof(xHostEntry);
}
if (n)
{
*data = ptr = (pointer) xalloc (n);
if (!ptr)
{
return(BadAlloc);
}
for (host = validhosts; host; host = host->next)
{
len = host->len;
((xHostEntry *)ptr)->family = host->family;
((xHostEntry *)ptr)->length = len;
ptr += sizeof(xHostEntry);
acopy (host->addr, ptr, len);
ptr += ((len + 3) >> 2) << 2;
}
} else {
*data = NULL;
}
*pnHosts = nHosts;
*pLen = n;
return(Success);
}
static int
CheckAddr (
int family,
pointer pAddr,
unsigned length)
{
int len;
switch (family)
{
#if defined(TCPCONN) || defined(STREAMSCONN) || defined(MNX_TCPCONN)
case FamilyInternet:
if (length == sizeof (struct in_addr))
len = length;
else
len = -1;
break;
#if defined(IPv6) && defined(AF_INET6)
case FamilyInternet6:
if (length == sizeof (struct in6_addr))
len = length;
else
len = -1;
break;
#endif
#endif
#ifdef DNETCONN
case FamilyDECnet:
{
struct dn_naddr *dnaddr = (struct dn_naddr *) pAddr;
if ((length < sizeof(dnaddr->a_len)) ||
(length < dnaddr->a_len + sizeof(dnaddr->a_len)))
len = -1;
else
len = dnaddr->a_len + sizeof(dnaddr->a_len);
if (len > sizeof(struct dn_naddr))
len = -1;
}
break;
#endif
case FamilyServerInterpreted:
len = siCheckAddr(pAddr, length);
break;
default:
len = -1;
}
return (len);
}
int
InvalidHost (
register struct sockaddr *saddr,
int len,
ClientPtr client)
{
int family;
pointer addr;
register HOST *selfhost, *host;
if (!AccessEnabled)
return(0);
family = ConvertAddr (saddr, &len, (pointer *)&addr);
if (family == -1)
return 1;
if (family == FamilyLocal)
{
if (!LocalHostEnabled)
{
for (selfhost = selfhosts; selfhost; selfhost=selfhost->next)
{
for (host = validhosts; host; host=host->next)
{
if (addrEqual (selfhost->family, selfhost->addr,
selfhost->len, host))
return 0;
}
}
} else
return 0;
}
for (host = validhosts; host; host = host->next)
{
if ((host->family == FamilyServerInterpreted)) {
if (siAddrMatch (family, addr, len, host, client)) {
return (0);
}
} else {
if (addrEqual (family, addr, len, host))
return (0);
}
}
return (1);
}
static int
ConvertAddr (
register struct sockaddr *saddr,
int *len,
pointer *addr)
{
if (*len == 0)
return (FamilyLocal);
switch (saddr->sa_family)
{
case AF_UNSPEC:
#if defined(UNIXCONN) || defined(LOCALCONN)
case AF_UNIX:
#endif
return FamilyLocal;
#if defined(TCPCONN) || defined(STREAMSCONN) || defined(MNX_TCPCONN)
case AF_INET:
#ifdef WIN32
if (16777343 == *(long*)&((struct sockaddr_in *) saddr)->sin_addr)
return FamilyLocal;
#endif
*len = sizeof (struct in_addr);
*addr = (pointer) &(((struct sockaddr_in *) saddr)->sin_addr);
return FamilyInternet;
#if defined(IPv6) && defined(AF_INET6)
case AF_INET6:
{
struct sockaddr_in6 *saddr6 = (struct sockaddr_in6 *) saddr;
if (IN6_IS_ADDR_V4MAPPED(&(saddr6->sin6_addr))) {
*len = sizeof (struct in_addr);
*addr = (pointer) &(saddr6->sin6_addr.s6_addr[12]);
return FamilyInternet;
} else {
*len = sizeof (struct in6_addr);
*addr = (pointer) &(saddr6->sin6_addr);
return FamilyInternet6;
}
}
#endif
#endif
#ifdef DNETCONN
case AF_DECnet:
{
struct sockaddr_dn *sdn = (struct sockaddr_dn *) saddr;
*len = sdn->sdn_nodeaddrl + sizeof(sdn->sdn_nodeaddrl);
*addr = (pointer) &(sdn->sdn_add);
}
return FamilyDECnet;
#endif
#ifdef CHAOSCONN
case AF_CHAOS:
{
not implemented
}
return FamilyChaos;
#endif
default:
return -1;
}
}
int
ChangeAccessControl(
ClientPtr client,
int fEnabled)
{
int rc = AuthorizedClient(client);
if (rc != Success)
return rc;
AccessEnabled = fEnabled;
return Success;
}
int
GetAccessControl(void)
{
return AccessEnabled;
}
typedef Bool (*siAddrMatchFunc)(int family, pointer addr, int len,
const char *siAddr, int siAddrlen, ClientPtr client, void *siTypePriv);
typedef int (*siCheckAddrFunc)(const char *addrString, int length,
void *siTypePriv);
struct siType {
struct siType * next;
const char * typeName;
siAddrMatchFunc addrMatch;
siCheckAddrFunc checkAddr;
void * typePriv;
};
static struct siType *siTypeList;
static int
siTypeAdd(const char *typeName, siAddrMatchFunc addrMatch,
siCheckAddrFunc checkAddr, void *typePriv)
{
struct siType *s, *p;
if ((typeName == NULL) || (addrMatch == NULL) || (checkAddr == NULL))
return BadValue;
for (s = siTypeList, p = NULL; s != NULL ; p = s, s = s->next) {
if (strcmp(typeName, s->typeName) == 0) {
s->addrMatch = addrMatch;
s->checkAddr = checkAddr;
s->typePriv = typePriv;
return Success;
}
}
s = (struct siType *) xalloc(sizeof(struct siType));
if (s == NULL)
return BadAlloc;
if (p == NULL)
siTypeList = s;
else
p->next = s;
s->next = NULL;
s->typeName = typeName;
s->addrMatch = addrMatch;
s->checkAddr = checkAddr;
s->typePriv = typePriv;
return Success;
}
static Bool
siAddrMatch(int family, pointer addr, int len, HOST *host, ClientPtr client)
{
Bool matches = FALSE;
struct siType *s;
const char *valueString;
int addrlen;
valueString = (const char *) memchr(host->addr, '\0', host->len);
if (valueString != NULL) {
for (s = siTypeList; s != NULL ; s = s->next) {
if (strcmp((char *) host->addr, s->typeName) == 0) {
addrlen = host->len - (strlen((char *)host->addr) + 1);
matches = s->addrMatch(family, addr, len,
valueString + 1, addrlen, client, s->typePriv);
break;
}
}
#ifdef FAMILY_SI_DEBUG
ErrorF(
"Xserver: siAddrMatch(): type = %s, value = %*.*s -- %s\n",
host->addr, addrlen, addrlen, valueString + 1,
(matches) ? "accepted" : "rejected");
#endif
}
return matches;
}
static int
siCheckAddr(const char *addrString, int length)
{
const char *valueString;
int addrlen, typelen;
int len = -1;
struct siType *s;
valueString = (const char *) memchr(addrString, '\0', length);
if (valueString != NULL) {
typelen = strlen(addrString) + 1;
addrlen = length - typelen;
for (s = siTypeList; s != NULL ; s = s->next) {
if (strcmp(addrString, s->typeName) == 0) {
len = s->checkAddr(valueString + 1, addrlen, s->typePriv);
if (len >= 0) {
len += typelen;
}
break;
}
}
#ifdef FAMILY_SI_DEBUG
{
const char *resultMsg;
if (s == NULL) {
resultMsg = "type not registered";
} else {
if (len == -1)
resultMsg = "rejected";
else
resultMsg = "accepted";
}
ErrorF("Xserver: siCheckAddr(): type = %s, value = %*.*s, len = %d -- %s\n",
addrString, addrlen, addrlen, valueString + 1, len, resultMsg);
}
#endif
}
return len;
}
#ifdef NI_MAXHOST
# define SI_HOSTNAME_MAXLEN NI_MAXHOST
#else
# ifdef MAXHOSTNAMELEN
# define SI_HOSTNAME_MAXLEN MAXHOSTNAMELEN
# else
# define SI_HOSTNAME_MAXLEN 256
# endif
#endif
static Bool
siHostnameAddrMatch(int family, pointer addr, int len,
const char *siAddr, int siAddrLen, ClientPtr client, void *typePriv)
{
Bool res = FALSE;
#if defined(IPv6) && defined(AF_INET6)
if ((family == FamilyInternet) || (family == FamilyInternet6)) {
char hostname[SI_HOSTNAME_MAXLEN];
struct addrinfo *addresses;
struct addrinfo *a;
int f, hostaddrlen;
pointer hostaddr;
if (siAddrLen >= sizeof(hostname))
return FALSE;
strncpy(hostname, siAddr, siAddrLen);
hostname[siAddrLen] = '\0';
if (getaddrinfo(hostname, NULL, NULL, &addresses) == 0) {
for (a = addresses ; a != NULL ; a = a->ai_next) {
hostaddrlen = a->ai_addrlen;
f = ConvertAddr(a->ai_addr,&hostaddrlen,&hostaddr);
if ((f == family) && (len == hostaddrlen) &&
(acmp (addr, hostaddr, len) == 0) ) {
res = TRUE;
break;
}
}
freeaddrinfo(addresses);
}
}
#else
if (family == FamilyInternet) {
register struct hostent *hp;
#ifdef XTHREADS_NEEDS_BYNAMEPARAMS
_Xgethostbynameparams hparams;
#endif
char hostname[SI_HOSTNAME_MAXLEN];
int f, hostaddrlen;
pointer hostaddr;
const char **addrlist;
if (siAddrLen >= sizeof(hostname))
return FALSE;
strncpy(hostname, siAddr, siAddrLen);
hostname[siAddrLen] = '\0';
if ((hp = _XGethostbyname(hostname, hparams)) != NULL) {
#ifdef h_addr
for (addrlist = hp->h_addr_list; *addrlist; addrlist++)
#else
addrlist = &hp->h_addr;
#endif
{
struct sockaddr_in sin;
sin.sin_family = hp->h_addrtype;
acopy ( *addrlist, &(sin.sin_addr), hp->h_length);
hostaddrlen = sizeof(sin);
f = ConvertAddr ((struct sockaddr *)&sin,
&hostaddrlen, &hostaddr);
if ((f == family) && (len == hostaddrlen) &&
(acmp (addr, hostaddr, len) == 0) ) {
res = TRUE;
break;
}
}
}
}
#endif
return res;
}
static int
siHostnameCheckAddr(const char *valueString, int length, void *typePriv)
{
int len = length;
int i;
Bool dotAllowed = FALSE;
Bool dashAllowed = FALSE;
if ((length <= 0) || (length >= SI_HOSTNAME_MAXLEN)) {
len = -1;
} else {
for (i = 0; i < length; i++) {
char c = valueString[i];
if (c == 0x2E) {
if (dotAllowed == FALSE) {
len = -1;
break;
} else {
dotAllowed = FALSE;
dashAllowed = FALSE;
}
} else if (c == 0x2D) {
if (dashAllowed == FALSE) {
len = -1;
break;
} else {
dotAllowed = FALSE;
}
} else if (((c >= 0x30) && (c <= 0x3A)) ||
((c >= 0x61) && (c <= 0x7A)) ||
((c >= 0x41) && (c <= 0x5A)) ) {
dotAllowed = TRUE;
dashAllowed = TRUE;
} else {
len = -1;
break;
}
}
}
return len;
}
#if defined(IPv6) && defined(AF_INET6)
#define SI_IPv6_MAXLEN INET6_ADDRSTRLEN
static Bool
siIPv6AddrMatch(int family, pointer addr, int len,
const char *siAddr, int siAddrlen, ClientPtr client, void *typePriv)
{
struct in6_addr addr6;
char addrbuf[SI_IPv6_MAXLEN];
if ((family != FamilyInternet6) || (len != sizeof(addr6)))
return FALSE;
memcpy(addrbuf, siAddr, siAddrlen);
addrbuf[siAddrlen] = '\0';
if (inet_pton(AF_INET6, addrbuf, &addr6) != 1) {
perror("inet_pton");
return FALSE;
}
if (memcmp(addr, &addr6, len) == 0) {
return TRUE;
} else {
return FALSE;
}
}
static int
siIPv6CheckAddr(const char *addrString, int length, void *typePriv)
{
int len;
if (length < 3) {
len = -1;
} else if (length >= SI_IPv6_MAXLEN) {
len = -1;
} else {
struct in6_addr addr6;
char addrbuf[SI_IPv6_MAXLEN];
memcpy(addrbuf, addrString, length);
addrbuf[length] = '\0';
if (inet_pton(AF_INET6, addrbuf, &addr6) != 1) {
perror("inet_pton");
len = -1;
} else {
len = length;
}
}
return len;
}
#endif
#if !defined(NO_LOCAL_CLIENT_CRED)
#include <pwd.h>
#include <grp.h>
#define LOCAL_USER 1
#define LOCAL_GROUP 2
typedef struct {
int credType;
} siLocalCredPrivRec, *siLocalCredPrivPtr;
static siLocalCredPrivRec siLocalUserPriv = { LOCAL_USER };
static siLocalCredPrivRec siLocalGroupPriv = { LOCAL_GROUP };
static Bool
siLocalCredGetId(const char *addr, int len, siLocalCredPrivPtr lcPriv, int *id)
{
Bool parsedOK = FALSE;
char *addrbuf = xalloc(len + 1);
if (addrbuf == NULL) {
return FALSE;
}
memcpy(addrbuf, addr, len);
addrbuf[len] = '\0';
if (addr[0] == '#') {
char *cp;
errno = 0;
*id = strtol(addrbuf + 1, &cp, 0);
if ((errno == 0) && (cp != (addrbuf+1))) {
parsedOK = TRUE;
}
} else {
if (lcPriv->credType == LOCAL_USER) {
struct passwd *pw = getpwnam(addrbuf);
if (pw != NULL) {
*id = (int) pw->pw_uid;
parsedOK = TRUE;
}
} else {
struct group *gr = getgrnam(addrbuf);
if (gr != NULL) {
*id = (int) gr->gr_gid;
parsedOK = TRUE;
}
}
}
xfree(addrbuf);
return parsedOK;
}
static Bool
siLocalCredAddrMatch(int family, pointer addr, int len,
const char *siAddr, int siAddrlen, ClientPtr client, void *typePriv)
{
int siAddrId;
LocalClientCredRec *lcc;
siLocalCredPrivPtr lcPriv = (siLocalCredPrivPtr) typePriv;
if (GetLocalClientCreds(client, &lcc) == -1) {
return FALSE;
}
#ifdef HAVE_GETZONEID
if ((lcc->fieldsSet & LCC_ZID_SET) && (lcc->zoneid != getzoneid())) {
FreeLocalClientCreds(lcc);
return FALSE;
}
#endif
if (siLocalCredGetId(siAddr, siAddrlen, lcPriv, &siAddrId) == FALSE) {
FreeLocalClientCreds(lcc);
return FALSE;
}
if (lcPriv->credType == LOCAL_USER) {
if ((lcc->fieldsSet & LCC_UID_SET) && (lcc->euid == siAddrId)) {
FreeLocalClientCreds(lcc);
return TRUE;
}
} else {
if ((lcc->fieldsSet & LCC_GID_SET) && (lcc->egid == siAddrId)) {
FreeLocalClientCreds(lcc);
return TRUE;
}
if (lcc->pSuppGids != NULL) {
int i;
for (i = 0 ; i < lcc->nSuppGids; i++) {
if (lcc->pSuppGids[i] == siAddrId) {
FreeLocalClientCreds(lcc);
return TRUE;
}
}
}
}
FreeLocalClientCreds(lcc);
return FALSE;
}
static int
siLocalCredCheckAddr(const char *addrString, int length, void *typePriv)
{
int len = length;
int id;
if (siLocalCredGetId(addrString, length,
(siLocalCredPrivPtr)typePriv, &id) == FALSE) {
len = -1;
}
return len;
}
#endif
static void
siTypesInitialize(void)
{
siTypeAdd("hostname", siHostnameAddrMatch, siHostnameCheckAddr, NULL);
#if defined(IPv6) && defined(AF_INET6)
siTypeAdd("ipv6", siIPv6AddrMatch, siIPv6CheckAddr, NULL);
#endif
#if !defined(NO_LOCAL_CLIENT_CRED)
siTypeAdd("localuser", siLocalCredAddrMatch, siLocalCredCheckAddr,
&siLocalUserPriv);
siTypeAdd("localgroup", siLocalCredAddrMatch, siLocalCredCheckAddr,
&siLocalGroupPriv);
#endif
}