access.c 47 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953
  1. /***********************************************************
  2. Copyright 1987, 1998 The Open Group
  3. Copyright 2004 Sun Microsystems, Inc.
  4. All rights reserved.
  5. Permission is hereby granted, free of charge, to any person obtaining a
  6. copy of this software and associated documentation files (the
  7. "Software"), to deal in the Software without restriction, including
  8. without limitation the rights to use, copy, modify, merge, publish,
  9. distribute, and/or sell copies of the Software, and to permit persons
  10. to whom the Software is furnished to do so, provided that the above
  11. copyright notice(s) and this permission notice appear in all copies of
  12. the Software and that both the above copyright notice(s) and this
  13. permission notice appear in supporting documentation.
  14. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  15. OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  16. MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
  17. OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
  18. HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL
  19. INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING
  20. FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
  21. NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
  22. WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  23. Except as contained in this notice, the name of a copyright holder
  24. shall not be used in advertising or otherwise to promote the sale, use
  25. or other dealings in this Software without prior written authorization
  26. of the copyright holder.
  27. X Window System is a trademark of The Open Group.
  28. Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
  29. All Rights Reserved
  30. Permission to use, copy, modify, and distribute this software and its
  31. documentation for any purpose and without fee is hereby granted,
  32. provided that the above copyright notice appear in all copies and that
  33. both that copyright notice and this permission notice appear in
  34. supporting documentation, and that the name of Digital not be
  35. used in advertising or publicity pertaining to distribution of the
  36. software without specific, written prior permission.
  37. DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
  38. ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
  39. DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
  40. ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
  41. WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
  42. ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
  43. SOFTWARE.
  44. ******************************************************************/
  45. #ifdef HAVE_DIX_CONFIG_H
  46. #include <dix-config.h>
  47. #endif
  48. #include <stdio.h>
  49. #include <stdlib.h>
  50. #define XSERV_t
  51. #define TRANS_SERVER
  52. #define TRANS_REOPEN
  53. #include <X11/Xtrans/Xtrans.h>
  54. #include <X11/Xauth.h>
  55. #include <X11/X.h>
  56. #include <X11/Xproto.h>
  57. #include "misc.h"
  58. #include "site.h"
  59. #include <errno.h>
  60. #include <sys/types.h>
  61. #include <sys/socket.h>
  62. #include <sys/ioctl.h>
  63. #include <ctype.h>
  64. #if defined(TCPCONN)
  65. #include <netinet/in.h>
  66. #endif /* TCPCONN */
  67. #ifdef HAS_GETPEERUCRED
  68. # include <ucred.h>
  69. #endif
  70. #if (defined(SYSV) && defined(i386)) || defined(__GNU__)
  71. # include <sys/utsname.h>
  72. #endif
  73. #ifdef __GNU__
  74. #undef SIOCGIFCONF
  75. #include <netdb.h>
  76. #else /*!__GNU__*/
  77. # include <net/if.h>
  78. #endif /*__GNU__ */
  79. #include <netdb.h>
  80. #ifdef CSRG_BASED
  81. #include <sys/param.h>
  82. #if (BSD >= 199103)
  83. #define VARIABLE_IFREQ
  84. #endif
  85. #endif
  86. #ifdef BSD44SOCKETS
  87. #ifndef VARIABLE_IFREQ
  88. #define VARIABLE_IFREQ
  89. #endif
  90. #endif
  91. #ifdef HAS_GETIFADDRS
  92. #include <ifaddrs.h>
  93. #endif
  94. /* Solaris provides an extended interface SIOCGLIFCONF. Other systems
  95. * may have this as well, but the code has only been tested on Solaris
  96. * so far, so we only enable it there. Other platforms may be added as
  97. * needed.
  98. *
  99. * Test for Solaris commented out -- TSI @ UQV 2003.06.13
  100. */
  101. #ifdef SIOCGLIFCONF
  102. /* #if defined(sun) */
  103. #define USE_SIOCGLIFCONF
  104. /* #endif */
  105. #endif
  106. #ifndef PATH_MAX
  107. #include <sys/param.h>
  108. #ifndef PATH_MAX
  109. #ifdef MAXPATHLEN
  110. #define PATH_MAX MAXPATHLEN
  111. #else
  112. #define PATH_MAX 1024
  113. #endif
  114. #endif
  115. #endif
  116. #define X_INCLUDE_NETDB_H
  117. #include <X11/Xos_r.h>
  118. #include "dixstruct.h"
  119. #include "osdep.h"
  120. #ifndef PATH_MAX
  121. #ifdef MAXPATHLEN
  122. #define PATH_MAX MAXPATHLEN
  123. #else
  124. #define PATH_MAX 1024
  125. #endif
  126. #endif
  127. Bool defeatAccessControl = FALSE;
  128. #define acmp(a1, a2, len) memcmp((char *)(a1), (char *)(a2), len)
  129. #define acopy(a1, a2, len) memmove((char *)(a2), (char *)(a1), len)
  130. #define addrEqual(fam, address, length, host) \
  131. ((fam) == (host)->family &&\
  132. (length) == (host)->len &&\
  133. !acmp (address, (host)->addr, length))
  134. static int ConvertAddr(struct sockaddr * /*saddr*/,
  135. int * /*len*/,
  136. pointer * /*addr*/);
  137. static int CheckAddr(int /*family*/,
  138. const void * /*pAddr*/,
  139. unsigned /*length*/);
  140. static Bool NewHost(int /*family*/,
  141. const void * /*addr*/,
  142. int /*len*/,
  143. int /* addingLocalHosts */);
  144. int LocalClientCredAndGroups(ClientPtr client, int *pUid, int *pGid,
  145. int **pSuppGids, int *nSuppGids);
  146. /* XFree86 bug #156: To keep track of which hosts were explicitly requested in
  147. /etc/X<display>.hosts, we've added a requested field to the HOST struct,
  148. and a LocalHostRequested variable. These default to FALSE, but are set
  149. to TRUE in ResetHosts when reading in /etc/X<display>.hosts. They are
  150. checked in DisableLocalHost(), which is called to disable the default
  151. local host entries when stronger authentication is turned on. */
  152. typedef struct _host {
  153. short family;
  154. short len;
  155. unsigned char *addr;
  156. struct _host *next;
  157. int requested;
  158. } HOST;
  159. #define MakeHost(h,l) (h)=malloc(sizeof *(h)+(l));\
  160. if (h) { \
  161. (h)->addr=(unsigned char *) ((h) + 1);\
  162. (h)->requested = FALSE; \
  163. }
  164. #define FreeHost(h) free(h)
  165. static HOST *selfhosts = NULL;
  166. static HOST *validhosts = NULL;
  167. static int AccessEnabled = DEFAULT_ACCESS_CONTROL;
  168. static int LocalHostEnabled = FALSE;
  169. static int LocalHostRequested = FALSE;
  170. static int UsingXdmcp = FALSE;
  171. /* FamilyServerInterpreted implementation */
  172. static Bool siAddrMatch(int family, pointer addr, int len, HOST *host,
  173. ClientPtr client);
  174. static int siCheckAddr(const char *addrString, int length);
  175. static void siTypesInitialize(void);
  176. /*
  177. * called when authorization is not enabled to add the
  178. * local host to the access list
  179. */
  180. void
  181. EnableLocalHost (void)
  182. {
  183. if (!UsingXdmcp)
  184. {
  185. LocalHostEnabled = TRUE;
  186. AddLocalHosts ();
  187. }
  188. }
  189. /*
  190. * called when authorization is enabled to keep us secure
  191. */
  192. void
  193. DisableLocalHost (void)
  194. {
  195. HOST *self;
  196. if (!LocalHostRequested) /* Fix for XFree86 bug #156 */
  197. LocalHostEnabled = FALSE;
  198. for (self = selfhosts; self; self = self->next) {
  199. if (!self->requested) /* Fix for XFree86 bug #156 */
  200. (void) RemoveHost ((ClientPtr)NULL, self->family, self->len, (pointer)self->addr);
  201. }
  202. }
  203. /*
  204. * called at init time when XDMCP will be used; xdmcp always
  205. * adds local hosts manually when needed
  206. */
  207. void
  208. AccessUsingXdmcp (void)
  209. {
  210. UsingXdmcp = TRUE;
  211. LocalHostEnabled = FALSE;
  212. }
  213. #define ifioctl ioctl
  214. /*
  215. * DefineSelf (fd):
  216. *
  217. * Define this host for access control. Find all the hosts the OS knows about
  218. * for this fd and add them to the selfhosts list.
  219. */
  220. #if !defined(SIOCGIFCONF) || (defined (hpux) && ! defined (HAS_IFREQ)) || defined(QNX4)
  221. void
  222. DefineSelf (int fd)
  223. {
  224. #if !defined(TCPCONN) && !defined(UNIXCONN)
  225. return;
  226. #else
  227. int len;
  228. caddr_t addr;
  229. int family;
  230. HOST *host;
  231. struct utsname name;
  232. struct hostent *hp;
  233. union {
  234. struct sockaddr sa;
  235. struct sockaddr_in in;
  236. #if defined(IPv6) && defined(AF_INET6)
  237. struct sockaddr_in6 in6;
  238. #endif
  239. } saddr;
  240. struct sockaddr_in *inetaddr;
  241. struct sockaddr_in6 *inet6addr;
  242. struct sockaddr_in broad_addr;
  243. #ifdef XTHREADS_NEEDS_BYNAMEPARAMS
  244. _Xgethostbynameparams hparams;
  245. #endif
  246. /* Why not use gethostname()? Well, at least on my system, I've had to
  247. * make an ugly kernel patch to get a name longer than 8 characters, and
  248. * uname() lets me access to the whole string (it smashes release, you
  249. * see), whereas gethostname() kindly truncates it for me.
  250. */
  251. uname(&name);
  252. hp = _XGethostbyname(name.nodename, hparams);
  253. if (hp != NULL)
  254. {
  255. saddr.sa.sa_family = hp->h_addrtype;
  256. switch (hp->h_addrtype) {
  257. case AF_INET:
  258. inetaddr = (struct sockaddr_in *) (&(saddr.sa));
  259. acopy ( hp->h_addr, &(inetaddr->sin_addr), hp->h_length);
  260. len = sizeof(saddr.sa);
  261. break;
  262. #if defined(IPv6) && defined(AF_INET6)
  263. case AF_INET6:
  264. inet6addr = (struct sockaddr_in6 *) (&(saddr.sa));
  265. acopy ( hp->h_addr, &(inet6addr->sin6_addr), hp->h_length);
  266. len = sizeof(saddr.in6);
  267. break;
  268. #endif
  269. default:
  270. goto DefineLocalHost;
  271. }
  272. family = ConvertAddr ( &(saddr.sa), &len, (pointer *)&addr);
  273. if ( family != -1 && family != FamilyLocal )
  274. {
  275. for (host = selfhosts;
  276. host && !addrEqual (family, addr, len, host);
  277. host = host->next) ;
  278. if (!host)
  279. {
  280. /* add this host to the host list. */
  281. MakeHost(host,len)
  282. if (host)
  283. {
  284. host->family = family;
  285. host->len = len;
  286. acopy ( addr, host->addr, len);
  287. host->next = selfhosts;
  288. selfhosts = host;
  289. }
  290. #ifdef XDMCP
  291. /*
  292. * If this is an Internet Address, but not the localhost
  293. * address (127.0.0.1), nor the bogus address (0.0.0.0),
  294. * register it.
  295. */
  296. if (family == FamilyInternet &&
  297. !(len == 4 &&
  298. ((addr[0] == 127 && addr[1] == 0 &&
  299. addr[2] == 0 && addr[3] == 1) ||
  300. (addr[0] == 0 && addr[1] == 0 &&
  301. addr[2] == 0 && addr[3] == 0)))
  302. )
  303. {
  304. XdmcpRegisterConnection (family, (char *)addr, len);
  305. broad_addr = *inetaddr;
  306. ((struct sockaddr_in *) &broad_addr)->sin_addr.s_addr =
  307. htonl (INADDR_BROADCAST);
  308. XdmcpRegisterBroadcastAddress ((struct sockaddr_in *)
  309. &broad_addr);
  310. }
  311. #if defined(IPv6) && defined(AF_INET6)
  312. else if (family == FamilyInternet6 &&
  313. !(IN6_IS_ADDR_LOOPBACK((struct in6_addr *)addr)))
  314. {
  315. XdmcpRegisterConnection (family, (char *)addr, len);
  316. }
  317. #endif
  318. #endif /* XDMCP */
  319. }
  320. }
  321. }
  322. /*
  323. * now add a host of family FamilyLocalHost...
  324. */
  325. DefineLocalHost:
  326. for (host = selfhosts;
  327. host && !addrEqual(FamilyLocalHost, "", 0, host);
  328. host = host->next);
  329. if (!host)
  330. {
  331. MakeHost(host, 0);
  332. if (host)
  333. {
  334. host->family = FamilyLocalHost;
  335. host->len = 0;
  336. acopy("", host->addr, 0);
  337. host->next = selfhosts;
  338. selfhosts = host;
  339. }
  340. }
  341. #endif /* !TCPCONN && !UNIXCONN */
  342. }
  343. #else
  344. #ifdef USE_SIOCGLIFCONF
  345. #define ifr_type struct lifreq
  346. #else
  347. #define ifr_type struct ifreq
  348. #endif
  349. #ifdef VARIABLE_IFREQ
  350. #define ifr_size(p) (sizeof (struct ifreq) + \
  351. (p->ifr_addr.sa_len > sizeof (p->ifr_addr) ? \
  352. p->ifr_addr.sa_len - sizeof (p->ifr_addr) : 0))
  353. #define ifraddr_size(a) (a.sa_len)
  354. #else
  355. #define ifr_size(p) (sizeof (ifr_type))
  356. #define ifraddr_size(a) (sizeof (a))
  357. #endif
  358. #if defined(DEF_SELF_DEBUG) || (defined(IPv6) && defined(AF_INET6))
  359. #include <arpa/inet.h>
  360. #endif
  361. #if defined(IPv6) && defined(AF_INET6)
  362. static void
  363. in6_fillscopeid(struct sockaddr_in6 *sin6)
  364. {
  365. #if defined(__KAME__)
  366. if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) {
  367. sin6->sin6_scope_id =
  368. ntohs(*(u_int16_t *)&sin6->sin6_addr.s6_addr[2]);
  369. sin6->sin6_addr.s6_addr[2] = sin6->sin6_addr.s6_addr[3] = 0;
  370. }
  371. #endif
  372. }
  373. #endif
  374. void
  375. DefineSelf (int fd)
  376. {
  377. #ifndef HAS_GETIFADDRS
  378. char buf[2048], *cp, *cplim;
  379. void * bufptr = buf;
  380. #ifdef USE_SIOCGLIFCONF
  381. struct lifconf ifc;
  382. struct lifreq *ifr;
  383. #ifdef SIOCGLIFNUM
  384. struct lifnum ifn;
  385. #endif
  386. #else
  387. struct ifconf ifc;
  388. struct ifreq *ifr;
  389. #endif
  390. #else
  391. struct ifaddrs * ifap, *ifr;
  392. #endif
  393. int len;
  394. unsigned char * addr;
  395. int family;
  396. HOST *host;
  397. #ifndef HAS_GETIFADDRS
  398. len = sizeof(buf);
  399. #ifdef USE_SIOCGLIFCONF
  400. #ifdef SIOCGLIFNUM
  401. ifn.lifn_family = AF_UNSPEC;
  402. ifn.lifn_flags = 0;
  403. if (ioctl (fd, SIOCGLIFNUM, (char *) &ifn) < 0)
  404. Error ("Getting interface count");
  405. if (len < (ifn.lifn_count * sizeof(struct lifreq))) {
  406. len = ifn.lifn_count * sizeof(struct lifreq);
  407. bufptr = malloc(len);
  408. }
  409. #endif
  410. ifc.lifc_family = AF_UNSPEC;
  411. ifc.lifc_flags = 0;
  412. ifc.lifc_len = len;
  413. ifc.lifc_buf = bufptr;
  414. #define IFC_IOCTL_REQ SIOCGLIFCONF
  415. #define IFC_IFC_REQ ifc.lifc_req
  416. #define IFC_IFC_LEN ifc.lifc_len
  417. #define IFR_IFR_ADDR ifr->lifr_addr
  418. #define IFR_IFR_NAME ifr->lifr_name
  419. #else /* Use SIOCGIFCONF */
  420. ifc.ifc_len = len;
  421. ifc.ifc_buf = bufptr;
  422. #define IFC_IOCTL_REQ SIOCGIFCONF
  423. #define IFC_IFC_REQ ifc.ifc_req
  424. #define IFC_IFC_LEN ifc.ifc_len
  425. #define IFR_IFR_ADDR ifr->ifr_addr
  426. #define IFR_IFR_NAME ifr->ifr_name
  427. #endif
  428. if (ifioctl (fd, IFC_IOCTL_REQ, (pointer) &ifc) < 0)
  429. Error ("Getting interface configuration (4)");
  430. cplim = (char *) IFC_IFC_REQ + IFC_IFC_LEN;
  431. for (cp = (char *) IFC_IFC_REQ; cp < cplim; cp += ifr_size (ifr))
  432. {
  433. ifr = (ifr_type *) cp;
  434. len = ifraddr_size (IFR_IFR_ADDR);
  435. family = ConvertAddr ((struct sockaddr *) &IFR_IFR_ADDR,
  436. &len, (pointer *)&addr);
  437. if (family == -1 || family == FamilyLocal)
  438. continue;
  439. #if defined(IPv6) && defined(AF_INET6)
  440. if (family == FamilyInternet6)
  441. in6_fillscopeid((struct sockaddr_in6 *)&IFR_IFR_ADDR);
  442. #endif
  443. #ifdef DEF_SELF_DEBUG
  444. if (family == FamilyInternet)
  445. ErrorF("Xserver: DefineSelf(): ifname = %s, addr = %d.%d.%d.%d\n",
  446. IFR_IFR_NAME, addr[0], addr[1], addr[2], addr[3]);
  447. #if defined(IPv6) && defined(AF_INET6)
  448. else if (family == FamilyInternet6) {
  449. char cp[INET6_ADDRSTRLEN] = "";
  450. inet_ntop(AF_INET6, addr, cp, sizeof(cp));
  451. ErrorF("Xserver: DefineSelf(): ifname = %s, addr = %s\n",
  452. IFR_IFR_NAME, cp);
  453. }
  454. #endif
  455. #endif /* DEF_SELF_DEBUG */
  456. for (host = selfhosts;
  457. host && !addrEqual (family, addr, len, host);
  458. host = host->next)
  459. ;
  460. if (host)
  461. continue;
  462. MakeHost(host,len)
  463. if (host)
  464. {
  465. host->family = family;
  466. host->len = len;
  467. acopy(addr, host->addr, len);
  468. host->next = selfhosts;
  469. selfhosts = host;
  470. }
  471. #ifdef XDMCP
  472. {
  473. #ifdef USE_SIOCGLIFCONF
  474. struct sockaddr_storage broad_addr;
  475. #else
  476. struct sockaddr broad_addr;
  477. #endif
  478. /*
  479. * If this isn't an Internet Address, don't register it.
  480. */
  481. if (family != FamilyInternet
  482. #if defined(IPv6) && defined(AF_INET6)
  483. && family != FamilyInternet6
  484. #endif
  485. )
  486. continue;
  487. /*
  488. * ignore 'localhost' entries as they're not useful
  489. * on the other end of the wire
  490. */
  491. if (family == FamilyInternet &&
  492. addr[0] == 127 && addr[1] == 0 &&
  493. addr[2] == 0 && addr[3] == 1)
  494. continue;
  495. #if defined(IPv6) && defined(AF_INET6)
  496. else if (family == FamilyInternet6 &&
  497. IN6_IS_ADDR_LOOPBACK((struct in6_addr *)addr))
  498. continue;
  499. #endif
  500. /*
  501. * Ignore '0.0.0.0' entries as they are
  502. * returned by some OSes for unconfigured NICs but they are
  503. * not useful on the other end of the wire.
  504. */
  505. if (len == 4 &&
  506. addr[0] == 0 && addr[1] == 0 &&
  507. addr[2] == 0 && addr[3] == 0)
  508. continue;
  509. XdmcpRegisterConnection (family, (char *)addr, len);
  510. #if defined(IPv6) && defined(AF_INET6)
  511. /* IPv6 doesn't support broadcasting, so we drop out here */
  512. if (family == FamilyInternet6)
  513. continue;
  514. #endif
  515. broad_addr = IFR_IFR_ADDR;
  516. ((struct sockaddr_in *) &broad_addr)->sin_addr.s_addr =
  517. htonl (INADDR_BROADCAST);
  518. #if defined(USE_SIOCGLIFCONF) && defined(SIOCGLIFBRDADDR)
  519. {
  520. struct lifreq broad_req;
  521. broad_req = *ifr;
  522. if (ioctl (fd, SIOCGLIFFLAGS, (char *) &broad_req) != -1 &&
  523. (broad_req.lifr_flags & IFF_BROADCAST) &&
  524. (broad_req.lifr_flags & IFF_UP)
  525. )
  526. {
  527. broad_req = *ifr;
  528. if (ioctl (fd, SIOCGLIFBRDADDR, &broad_req) != -1)
  529. broad_addr = broad_req.lifr_broadaddr;
  530. else
  531. continue;
  532. }
  533. else
  534. continue;
  535. }
  536. #elif defined(SIOCGIFBRDADDR)
  537. {
  538. struct ifreq broad_req;
  539. broad_req = *ifr;
  540. if (ifioctl (fd, SIOCGIFFLAGS, (pointer) &broad_req) != -1 &&
  541. (broad_req.ifr_flags & IFF_BROADCAST) &&
  542. (broad_req.ifr_flags & IFF_UP)
  543. )
  544. {
  545. broad_req = *ifr;
  546. if (ifioctl (fd, SIOCGIFBRDADDR, (pointer) &broad_req) != -1)
  547. broad_addr = broad_req.ifr_addr;
  548. else
  549. continue;
  550. }
  551. else
  552. continue;
  553. }
  554. #endif /* SIOCGIFBRDADDR */
  555. #ifdef DEF_SELF_DEBUG
  556. ErrorF("Xserver: DefineSelf(): ifname = %s, baddr = %s\n",
  557. IFR_IFR_NAME,
  558. inet_ntoa(((struct sockaddr_in *) &broad_addr)->sin_addr));
  559. #endif /* DEF_SELF_DEBUG */
  560. XdmcpRegisterBroadcastAddress ((struct sockaddr_in *) &broad_addr);
  561. }
  562. #endif /* XDMCP */
  563. }
  564. if (bufptr != buf)
  565. free(bufptr);
  566. #else /* HAS_GETIFADDRS */
  567. if (getifaddrs(&ifap) < 0) {
  568. ErrorF("Warning: getifaddrs returns %s\n", strerror(errno));
  569. return;
  570. }
  571. for (ifr = ifap; ifr != NULL; ifr = ifr->ifa_next) {
  572. if (!ifr->ifa_addr)
  573. continue;
  574. len = sizeof(*(ifr->ifa_addr));
  575. family = ConvertAddr((struct sockaddr *) ifr->ifa_addr, &len,
  576. (pointer *)&addr);
  577. if (family == -1 || family == FamilyLocal)
  578. continue;
  579. #if defined(IPv6) && defined(AF_INET6)
  580. if (family == FamilyInternet6)
  581. in6_fillscopeid((struct sockaddr_in6 *)ifr->ifa_addr);
  582. #endif
  583. #ifdef DEF_SELF_DEBUG
  584. if (family == FamilyInternet)
  585. ErrorF("Xserver: DefineSelf(): ifname = %s, addr = %d.%d.%d.%d\n",
  586. ifr->ifa_name, addr[0], addr[1], addr[2], addr[3]);
  587. #if defined(IPv6) && defined(AF_INET6)
  588. else if (family == FamilyInternet6) {
  589. char cp[INET6_ADDRSTRLEN];
  590. inet_ntop(AF_INET6, addr, cp, sizeof(cp));
  591. ErrorF("Xserver: DefineSelf(): ifname = %s addr = %s\n",
  592. ifr->ifa_name, cp);
  593. }
  594. #endif
  595. #endif /* DEF_SELF_DEBUG */
  596. for (host = selfhosts;
  597. host != NULL && !addrEqual(family, addr, len, host);
  598. host = host->next)
  599. ;
  600. if (host != NULL)
  601. continue;
  602. MakeHost(host, len);
  603. if (host != NULL) {
  604. host->family = family;
  605. host->len = len;
  606. acopy(addr, host->addr, len);
  607. host->next = selfhosts;
  608. selfhosts = host;
  609. }
  610. #ifdef XDMCP
  611. {
  612. struct sockaddr broad_addr;
  613. /*
  614. * If this isn't an Internet Address, don't register it.
  615. */
  616. if (family != FamilyInternet
  617. #if defined(IPv6) && defined(AF_INET6)
  618. && family != FamilyInternet6
  619. #endif
  620. )
  621. continue;
  622. /*
  623. * ignore 'localhost' entries as they're not useful
  624. * on the other end of the wire
  625. */
  626. if (ifr->ifa_flags & IFF_LOOPBACK)
  627. continue;
  628. if (family == FamilyInternet &&
  629. addr[0] == 127 && addr[1] == 0 &&
  630. addr[2] == 0 && addr[3] == 1)
  631. continue;
  632. /*
  633. * Ignore '0.0.0.0' entries as they are
  634. * returned by some OSes for unconfigured NICs but they are
  635. * not useful on the other end of the wire.
  636. */
  637. if (len == 4 &&
  638. addr[0] == 0 && addr[1] == 0 &&
  639. addr[2] == 0 && addr[3] == 0)
  640. continue;
  641. #if defined(IPv6) && defined(AF_INET6)
  642. else if (family == FamilyInternet6 &&
  643. IN6_IS_ADDR_LOOPBACK((struct in6_addr *)addr))
  644. continue;
  645. #endif
  646. XdmcpRegisterConnection(family, (char *)addr, len);
  647. #if defined(IPv6) && defined(AF_INET6)
  648. if (family == FamilyInternet6)
  649. /* IPv6 doesn't support broadcasting, so we drop out here */
  650. continue;
  651. #endif
  652. if ((ifr->ifa_flags & IFF_BROADCAST) &&
  653. (ifr->ifa_flags & IFF_UP))
  654. broad_addr = *ifr->ifa_broadaddr;
  655. else
  656. continue;
  657. #ifdef DEF_SELF_DEBUG
  658. ErrorF("Xserver: DefineSelf(): ifname = %s, baddr = %s\n",
  659. ifr->ifa_name,
  660. inet_ntoa(((struct sockaddr_in *) &broad_addr)->sin_addr));
  661. #endif /* DEF_SELF_DEBUG */
  662. XdmcpRegisterBroadcastAddress((struct sockaddr_in *)
  663. &broad_addr);
  664. }
  665. #endif /* XDMCP */
  666. } /* for */
  667. freeifaddrs(ifap);
  668. #endif /* HAS_GETIFADDRS */
  669. /*
  670. * add something of FamilyLocalHost
  671. */
  672. for (host = selfhosts;
  673. host && !addrEqual(FamilyLocalHost, "", 0, host);
  674. host = host->next);
  675. if (!host)
  676. {
  677. MakeHost(host, 0);
  678. if (host)
  679. {
  680. host->family = FamilyLocalHost;
  681. host->len = 0;
  682. acopy("", host->addr, 0);
  683. host->next = selfhosts;
  684. selfhosts = host;
  685. }
  686. }
  687. }
  688. #endif /* hpux && !HAS_IFREQ */
  689. #ifdef XDMCP
  690. void
  691. AugmentSelf(pointer from, int len)
  692. {
  693. int family;
  694. pointer addr;
  695. HOST *host;
  696. family = ConvertAddr(from, &len, (pointer *)&addr);
  697. if (family == -1 || family == FamilyLocal)
  698. return;
  699. for (host = selfhosts; host; host = host->next)
  700. {
  701. if (addrEqual(family, addr, len, host))
  702. return;
  703. }
  704. MakeHost(host,len)
  705. if (!host)
  706. return;
  707. host->family = family;
  708. host->len = len;
  709. acopy(addr, host->addr, len);
  710. host->next = selfhosts;
  711. selfhosts = host;
  712. }
  713. #endif
  714. void
  715. AddLocalHosts (void)
  716. {
  717. HOST *self;
  718. for (self = selfhosts; self; self = self->next)
  719. /* Fix for XFree86 bug #156: pass addingLocal = TRUE to
  720. * NewHost to tell that we are adding the default local
  721. * host entries and not to flag the entries as being
  722. * explicitely requested */
  723. (void) NewHost (self->family, self->addr, self->len, TRUE);
  724. }
  725. /* Reset access control list to initial hosts */
  726. void
  727. ResetHosts (const char *display)
  728. {
  729. HOST *host;
  730. char lhostname[120], ohostname[120];
  731. char *hostname;
  732. char fname[PATH_MAX + 1];
  733. int fnamelen;
  734. FILE *fd;
  735. char *ptr;
  736. int i, hostlen;
  737. #if (defined(TCPCONN) && \
  738. (!defined(IPv6) || !defined(AF_INET6)))
  739. union {
  740. struct sockaddr sa;
  741. #if defined(TCPCONN)
  742. struct sockaddr_in in;
  743. #endif /* TCPCONN */
  744. } saddr;
  745. #endif
  746. int family = 0;
  747. pointer addr = NULL;
  748. int len;
  749. siTypesInitialize();
  750. AccessEnabled = defeatAccessControl ? FALSE : DEFAULT_ACCESS_CONTROL;
  751. LocalHostEnabled = FALSE;
  752. while ((host = validhosts) != 0)
  753. {
  754. validhosts = host->next;
  755. FreeHost (host);
  756. }
  757. #define ETC_HOST_PREFIX "/etc/X"
  758. #define ETC_HOST_SUFFIX ".hosts"
  759. fnamelen = strlen(ETC_HOST_PREFIX) + strlen(ETC_HOST_SUFFIX) +
  760. strlen(display) + 1;
  761. if (fnamelen > sizeof(fname))
  762. FatalError("Display name `%s' is too long\n", display);
  763. sprintf(fname, ETC_HOST_PREFIX "%s" ETC_HOST_SUFFIX, display);
  764. if ((fd = fopen (fname, "r")) != 0)
  765. {
  766. while (fgets (ohostname, sizeof (ohostname), fd))
  767. {
  768. family = FamilyWild;
  769. if (*ohostname == '#')
  770. continue;
  771. if ((ptr = strchr(ohostname, '\n')) != 0)
  772. *ptr = 0;
  773. hostlen = strlen(ohostname) + 1;
  774. for (i = 0; i < hostlen; i++)
  775. lhostname[i] = tolower(ohostname[i]);
  776. hostname = ohostname;
  777. if (!strncmp("local:", lhostname, 6))
  778. {
  779. family = FamilyLocalHost;
  780. NewHost(family, "", 0, FALSE);
  781. LocalHostRequested = TRUE; /* Fix for XFree86 bug #156 */
  782. }
  783. #if defined(TCPCONN)
  784. else if (!strncmp("inet:", lhostname, 5))
  785. {
  786. family = FamilyInternet;
  787. hostname = ohostname + 5;
  788. }
  789. #if defined(IPv6) && defined(AF_INET6)
  790. else if (!strncmp("inet6:", lhostname, 6))
  791. {
  792. family = FamilyInternet6;
  793. hostname = ohostname + 6;
  794. }
  795. #endif
  796. #endif
  797. #ifdef SECURE_RPC
  798. else if (!strncmp("nis:", lhostname, 4))
  799. {
  800. family = FamilyNetname;
  801. hostname = ohostname + 4;
  802. }
  803. #endif
  804. else if (!strncmp("si:", lhostname, 3))
  805. {
  806. family = FamilyServerInterpreted;
  807. hostname = ohostname + 3;
  808. hostlen -= 3;
  809. }
  810. if (family == FamilyServerInterpreted)
  811. {
  812. len = siCheckAddr(hostname, hostlen);
  813. if (len >= 0) {
  814. NewHost(family, hostname, len, FALSE);
  815. }
  816. }
  817. else
  818. #ifdef SECURE_RPC
  819. if ((family == FamilyNetname) || (strchr(hostname, '@')))
  820. {
  821. SecureRPCInit ();
  822. (void) NewHost (FamilyNetname, hostname, strlen (hostname), FALSE);
  823. }
  824. else
  825. #endif /* SECURE_RPC */
  826. #if defined(TCPCONN)
  827. {
  828. #if defined(IPv6) && defined(AF_INET6)
  829. if ( (family == FamilyInternet) || (family == FamilyInternet6) ||
  830. (family == FamilyWild) )
  831. {
  832. struct addrinfo *addresses;
  833. struct addrinfo *a;
  834. int f;
  835. if (getaddrinfo(hostname, NULL, NULL, &addresses) == 0) {
  836. for (a = addresses ; a != NULL ; a = a->ai_next) {
  837. len = a->ai_addrlen;
  838. f = ConvertAddr(a->ai_addr,&len,(pointer *)&addr);
  839. if ( (family == f) ||
  840. ((family == FamilyWild) && (f != -1)) ) {
  841. NewHost(f, addr, len, FALSE);
  842. }
  843. }
  844. freeaddrinfo(addresses);
  845. }
  846. }
  847. #else
  848. #ifdef XTHREADS_NEEDS_BYNAMEPARAMS
  849. _Xgethostbynameparams hparams;
  850. #endif
  851. struct hostent *hp;
  852. /* host name */
  853. if ((family == FamilyInternet &&
  854. ((hp = _XGethostbyname(hostname, hparams)) != 0)) ||
  855. ((hp = _XGethostbyname(hostname, hparams)) != 0))
  856. {
  857. saddr.sa.sa_family = hp->h_addrtype;
  858. len = sizeof(saddr.sa);
  859. if ((family = ConvertAddr (&saddr.sa, &len, (pointer *)&addr)) != -1)
  860. {
  861. #ifdef h_addr /* new 4.3bsd version of gethostent */
  862. char **list;
  863. /* iterate over the addresses */
  864. for (list = hp->h_addr_list; *list; list++)
  865. (void) NewHost (family, (pointer)*list, len, FALSE);
  866. #else
  867. (void) NewHost (family, (pointer)hp->h_addr, len, FALSE);
  868. #endif
  869. }
  870. }
  871. #endif /* IPv6 */
  872. }
  873. #endif /* TCPCONN */
  874. // family = FamilyWild;
  875. }
  876. fclose (fd);
  877. }
  878. }
  879. /* Is client on the local host */
  880. _X_EXPORT Bool LocalClient(ClientPtr client)
  881. {
  882. int alen, family, notused;
  883. Xtransaddr *from = NULL;
  884. pointer addr;
  885. HOST *host;
  886. if (!_XSERVTransGetPeerAddr (((OsCommPtr)client->osPrivate)->trans_conn,
  887. &notused, &alen, &from))
  888. {
  889. family = ConvertAddr ((struct sockaddr *) from,
  890. &alen, (pointer *)&addr);
  891. if (family == -1)
  892. {
  893. free((char *) from);
  894. return FALSE;
  895. }
  896. if (family == FamilyLocal)
  897. {
  898. free((char *) from);
  899. return TRUE;
  900. }
  901. for (host = selfhosts; host; host = host->next)
  902. {
  903. if (addrEqual (family, addr, alen, host))
  904. return TRUE;
  905. }
  906. free((char *) from);
  907. }
  908. return FALSE;
  909. }
  910. /*
  911. * Return the uid and gid of a connected local client
  912. * or the uid/gid for nobody those ids cannot be determined
  913. *
  914. * Used by XShm to test access rights to shared memory segments
  915. */
  916. int
  917. LocalClientCred(ClientPtr client, int *pUid, int *pGid)
  918. {
  919. return LocalClientCredAndGroups(client, pUid, pGid, NULL, NULL);
  920. }
  921. /*
  922. * Return the uid and all gids of a connected local client
  923. * or the uid/gid for nobody those ids cannot be determined
  924. *
  925. * If the caller passes non-NULL values for pSuppGids & nSuppGids,
  926. * they are responsible for calling XFree(*pSuppGids) to release the
  927. * memory allocated for the supplemental group ids list.
  928. *
  929. * Used by localuser & localgroup ServerInterpreted access control forms below
  930. */
  931. int
  932. LocalClientCredAndGroups(ClientPtr client, int *pUid, int *pGid,
  933. int **pSuppGids, int *nSuppGids)
  934. {
  935. #if defined(HAS_GETPEEREID) || defined(HAS_GETPEERUCRED) || defined(SO_PEERCRED)
  936. int fd;
  937. XtransConnInfo ci;
  938. #ifdef HAS_GETPEEREID
  939. uid_t uid;
  940. gid_t gid;
  941. #elif defined(HAS_GETPEERUCRED)
  942. ucred_t *peercred = NULL;
  943. #elif defined(SO_PEERCRED)
  944. struct ucred peercred;
  945. socklen_t so_len = sizeof(peercred);
  946. #endif
  947. if (client == NULL)
  948. return -1;
  949. ci = ((OsCommPtr)client->osPrivate)->trans_conn;
  950. /* Most implementations can only determine peer credentials for Unix
  951. * domain sockets - Solaris getpeerucred can work with a bit more, so
  952. * we just let it tell us if the connection type is supported or not
  953. */
  954. if (!_XSERVTransIsLocal(ci)) {
  955. return -1;
  956. }
  957. if (pSuppGids != NULL)
  958. *pSuppGids = NULL;
  959. if (nSuppGids != NULL)
  960. *nSuppGids = 0;
  961. fd = _XSERVTransGetConnectionNumber(ci);
  962. #ifdef HAS_GETPEEREID
  963. if (getpeereid(fd, &uid, &gid) == -1)
  964. return -1;
  965. if (pUid != NULL)
  966. *pUid = uid;
  967. if (pGid != NULL)
  968. *pGid = gid;
  969. return 0;
  970. #elif defined(HAS_GETPEERUCRED)
  971. if (getpeerucred(fd, &peercred) < 0)
  972. return -1;
  973. if (pUid != NULL)
  974. *pUid = ucred_geteuid(peercred);
  975. if (pGid != NULL)
  976. *pGid = ucred_getegid(peercred);
  977. if (pSuppGids != NULL && nSuppGids != NULL) {
  978. const gid_t *gids;
  979. *nSuppGids = ucred_getgroups(peercred, &gids);
  980. if (*nSuppGids > 0) {
  981. *pSuppGids = malloc(sizeof(int) * (*nSuppGids));
  982. if (*pSuppGids == NULL) {
  983. *nSuppGids = 0;
  984. } else {
  985. int i;
  986. for (i = 0 ; i < *nSuppGids; i++) {
  987. (*pSuppGids)[i] = (int) gids[i];
  988. }
  989. }
  990. }
  991. }
  992. ucred_free(peercred);
  993. return 0;
  994. #elif defined(SO_PEERCRED)
  995. if (getsockopt(fd, SOL_SOCKET, SO_PEERCRED, &peercred, &so_len) == -1)
  996. return -1;
  997. if (pUid != NULL)
  998. *pUid = peercred.uid;
  999. if (pGid != NULL)
  1000. *pGid = peercred.gid;
  1001. return 0;
  1002. #endif
  1003. #else
  1004. /* No system call available to get the credentials of the peer */
  1005. #define NO_LOCAL_CLIENT_CRED
  1006. return -1;
  1007. #endif
  1008. }
  1009. static Bool
  1010. AuthorizedClient(ClientPtr client)
  1011. {
  1012. if (!client || defeatAccessControl)
  1013. return TRUE;
  1014. return LocalClient(client);
  1015. }
  1016. /* Add a host to the access control list. This is the external interface
  1017. * called from the dispatcher */
  1018. int
  1019. AddHost (ClientPtr client,
  1020. int family,
  1021. unsigned length, /* of bytes in pAddr */
  1022. const void * pAddr)
  1023. {
  1024. int len;
  1025. if (!AuthorizedClient(client))
  1026. return(BadAccess);
  1027. switch (family) {
  1028. case FamilyLocalHost:
  1029. len = length;
  1030. LocalHostEnabled = TRUE;
  1031. break;
  1032. #ifdef SECURE_RPC
  1033. case FamilyNetname:
  1034. len = length;
  1035. SecureRPCInit ();
  1036. break;
  1037. #endif
  1038. case FamilyInternet:
  1039. #if defined(IPv6) && defined(AF_INET6)
  1040. case FamilyInternet6:
  1041. #endif
  1042. case FamilyDECnet:
  1043. case FamilyChaos:
  1044. case FamilyServerInterpreted:
  1045. if ((len = CheckAddr (family, pAddr, length)) < 0)
  1046. {
  1047. if (client) client->errorValue = length;
  1048. return (BadValue);
  1049. }
  1050. break;
  1051. case FamilyLocal:
  1052. default:
  1053. if (client) client->errorValue = family;
  1054. return (BadValue);
  1055. }
  1056. if (NewHost (family, pAddr, len, FALSE))
  1057. return Success;
  1058. return BadAlloc;
  1059. }
  1060. /* Add a host to the access control list. This is the internal interface
  1061. * called when starting or resetting the server */
  1062. static Bool
  1063. NewHost (int family,
  1064. const void * addr,
  1065. int len,
  1066. int addingLocalHosts)
  1067. {
  1068. HOST *host;
  1069. for (host = validhosts; host; host = host->next)
  1070. {
  1071. if (addrEqual (family, addr, len, host))
  1072. return TRUE;
  1073. }
  1074. if (!addingLocalHosts) { /* Fix for XFree86 bug #156 */
  1075. for (host = selfhosts; host; host = host->next) {
  1076. if (addrEqual (family, addr, len, host)) {
  1077. host->requested = TRUE;
  1078. break;
  1079. }
  1080. }
  1081. }
  1082. MakeHost(host,len)
  1083. if (!host)
  1084. return FALSE;
  1085. host->family = family;
  1086. host->len = len;
  1087. acopy(addr, host->addr, len);
  1088. host->next = validhosts;
  1089. validhosts = host;
  1090. return TRUE;
  1091. }
  1092. /* Remove a host from the access control list */
  1093. int
  1094. RemoveHost (
  1095. ClientPtr client,
  1096. int family,
  1097. unsigned length, /* of bytes in pAddr */
  1098. pointer pAddr)
  1099. {
  1100. int len;
  1101. HOST *host, **prev;
  1102. if (!AuthorizedClient(client))
  1103. return(BadAccess);
  1104. switch (family) {
  1105. case FamilyLocalHost:
  1106. len = length;
  1107. LocalHostEnabled = FALSE;
  1108. break;
  1109. #ifdef SECURE_RPC
  1110. case FamilyNetname:
  1111. len = length;
  1112. break;
  1113. #endif
  1114. case FamilyInternet:
  1115. #if defined(IPv6) && defined(AF_INET6)
  1116. case FamilyInternet6:
  1117. #endif
  1118. case FamilyDECnet:
  1119. case FamilyChaos:
  1120. case FamilyServerInterpreted:
  1121. if ((len = CheckAddr (family, pAddr, length)) < 0)
  1122. {
  1123. client->errorValue = length;
  1124. return(BadValue);
  1125. }
  1126. break;
  1127. case FamilyLocal:
  1128. default:
  1129. client->errorValue = family;
  1130. return(BadValue);
  1131. }
  1132. for (prev = &validhosts;
  1133. (host = *prev) && (!addrEqual (family, pAddr, len, host));
  1134. prev = &host->next)
  1135. ;
  1136. if (host)
  1137. {
  1138. *prev = host->next;
  1139. FreeHost (host);
  1140. }
  1141. return (Success);
  1142. }
  1143. /* Get all hosts in the access control list */
  1144. int
  1145. GetHosts (
  1146. pointer *data,
  1147. int *pnHosts,
  1148. int *pLen,
  1149. BOOL *pEnabled)
  1150. {
  1151. int len;
  1152. int n = 0;
  1153. unsigned char *ptr;
  1154. HOST *host;
  1155. int nHosts = 0;
  1156. *pEnabled = AccessEnabled ? EnableAccess : DisableAccess;
  1157. for (host = validhosts; host; host = host->next)
  1158. {
  1159. nHosts++;
  1160. n += (((host->len + 3) >> 2) << 2) + sizeof(xHostEntry);
  1161. }
  1162. if (n)
  1163. {
  1164. *data = ptr = malloc(n);
  1165. if (!ptr)
  1166. {
  1167. return(BadAlloc);
  1168. }
  1169. for (host = validhosts; host; host = host->next)
  1170. {
  1171. len = host->len;
  1172. ((xHostEntry *)ptr)->family = host->family;
  1173. ((xHostEntry *)ptr)->length = len;
  1174. ptr += sizeof(xHostEntry);
  1175. acopy (host->addr, ptr, len);
  1176. ptr += ((len + 3) >> 2) << 2;
  1177. }
  1178. } else {
  1179. *data = NULL;
  1180. }
  1181. *pnHosts = nHosts;
  1182. *pLen = n;
  1183. return(Success);
  1184. }
  1185. /* Check for valid address family and length, and return address length. */
  1186. /*ARGSUSED*/
  1187. static int
  1188. CheckAddr (
  1189. int family,
  1190. const void * pAddr,
  1191. unsigned length)
  1192. {
  1193. int len;
  1194. switch (family)
  1195. {
  1196. #if defined(TCPCONN)
  1197. case FamilyInternet:
  1198. if (length == sizeof (struct in_addr))
  1199. len = length;
  1200. else
  1201. len = -1;
  1202. break;
  1203. #if defined(IPv6) && defined(AF_INET6)
  1204. case FamilyInternet6:
  1205. if (length == sizeof (struct in6_addr))
  1206. len = length;
  1207. else
  1208. len = -1;
  1209. break;
  1210. #endif
  1211. #endif
  1212. case FamilyServerInterpreted:
  1213. len = siCheckAddr(pAddr, length);
  1214. break;
  1215. default:
  1216. len = -1;
  1217. }
  1218. return (len);
  1219. }
  1220. /* Check if a host is not in the access control list.
  1221. * Returns 1 if host is invalid, 0 if we've found it. */
  1222. int
  1223. InvalidHost (
  1224. register struct sockaddr *saddr,
  1225. int len,
  1226. ClientPtr client)
  1227. {
  1228. int family;
  1229. pointer addr = NULL;
  1230. HOST *selfhost, *host;
  1231. if (!AccessEnabled) /* just let them in */
  1232. return(0);
  1233. family = ConvertAddr (saddr, &len, (pointer *)&addr);
  1234. if (family == -1)
  1235. return 1;
  1236. if (family == FamilyLocal)
  1237. {
  1238. if (!LocalHostEnabled)
  1239. {
  1240. /*
  1241. * check to see if any local address is enabled. This
  1242. * implicitly enables local connections.
  1243. */
  1244. for (selfhost = selfhosts; selfhost; selfhost=selfhost->next)
  1245. {
  1246. for (host = validhosts; host; host=host->next)
  1247. {
  1248. if (addrEqual (selfhost->family, selfhost->addr,
  1249. selfhost->len, host))
  1250. return 0;
  1251. }
  1252. }
  1253. } else
  1254. return 0;
  1255. }
  1256. for (host = validhosts; host; host = host->next)
  1257. {
  1258. if ((host->family == FamilyServerInterpreted)) {
  1259. if (siAddrMatch (family, addr, len, host, client)) {
  1260. return (0);
  1261. }
  1262. } else {
  1263. if (addrEqual (family, addr, len, host))
  1264. return (0);
  1265. }
  1266. }
  1267. return (1);
  1268. }
  1269. static int
  1270. ConvertAddr (
  1271. register struct sockaddr *saddr,
  1272. int *len,
  1273. pointer *addr)
  1274. {
  1275. if (*len == 0)
  1276. return (FamilyLocal);
  1277. switch (saddr->sa_family)
  1278. {
  1279. case AF_UNSPEC:
  1280. #if defined(UNIXCONN) || defined(LOCALCONN)
  1281. case AF_UNIX:
  1282. #endif
  1283. return FamilyLocal;
  1284. #if defined(TCPCONN)
  1285. case AF_INET:
  1286. *len = sizeof (struct in_addr);
  1287. *addr = (pointer) &(((struct sockaddr_in *) saddr)->sin_addr);
  1288. return FamilyInternet;
  1289. #if defined(IPv6) && defined(AF_INET6)
  1290. case AF_INET6:
  1291. {
  1292. struct sockaddr_in6 *saddr6 = (struct sockaddr_in6 *) saddr;
  1293. if (IN6_IS_ADDR_V4MAPPED(&(saddr6->sin6_addr))) {
  1294. *len = sizeof (struct in_addr);
  1295. *addr = (pointer) &(saddr6->sin6_addr.s6_addr[12]);
  1296. return FamilyInternet;
  1297. } else {
  1298. *len = sizeof (struct in6_addr);
  1299. *addr = (pointer) &(saddr6->sin6_addr);
  1300. return FamilyInternet6;
  1301. }
  1302. }
  1303. #endif
  1304. #endif
  1305. default:
  1306. return -1;
  1307. }
  1308. }
  1309. int
  1310. ChangeAccessControl(
  1311. ClientPtr client,
  1312. int fEnabled)
  1313. {
  1314. if (!AuthorizedClient(client))
  1315. return BadAccess;
  1316. AccessEnabled = fEnabled;
  1317. return Success;
  1318. }
  1319. /*****************************************************************************
  1320. * FamilyServerInterpreted host entry implementation
  1321. *
  1322. * Supports an extensible system of host types which the server can interpret
  1323. * See the IPv6 extensions to the X11 protocol spec for the definition.
  1324. *
  1325. * Currently supported schemes:
  1326. *
  1327. * hostname - hostname as defined in IETF RFC 2396
  1328. * ipv6 - IPv6 literal address as defined in IETF RFC's 3513 and <TBD>
  1329. *
  1330. * See xc/doc/specs/SIAddresses for formal definitions of each type.
  1331. */
  1332. /* These definitions and the siTypeAdd function could be exported in the
  1333. * future to enable loading additional host types, but that was not done for
  1334. * the initial implementation.
  1335. */
  1336. typedef Bool (*siAddrMatchFunc)(int family, pointer addr, int len,
  1337. const char *siAddr, int siAddrlen, ClientPtr client, void *siTypePriv);
  1338. typedef int (*siCheckAddrFunc)(const char *addrString, int length,
  1339. void *siTypePriv);
  1340. struct siType {
  1341. struct siType * next;
  1342. const char * typeName;
  1343. siAddrMatchFunc addrMatch;
  1344. siCheckAddrFunc checkAddr;
  1345. void * typePriv; /* Private data for type routines */
  1346. };
  1347. static struct siType *siTypeList;
  1348. static int
  1349. siTypeAdd(const char *typeName, siAddrMatchFunc addrMatch,
  1350. siCheckAddrFunc checkAddr, void *typePriv)
  1351. {
  1352. struct siType *s, *p;
  1353. if ((typeName == NULL) || (addrMatch == NULL) || (checkAddr == NULL))
  1354. return BadValue;
  1355. for (s = siTypeList, p = NULL; s != NULL ; p = s, s = s->next) {
  1356. if (strcmp(typeName, s->typeName) == 0) {
  1357. s->addrMatch = addrMatch;
  1358. s->checkAddr = checkAddr;
  1359. s->typePriv = typePriv;
  1360. return Success;
  1361. }
  1362. }
  1363. s = malloc(sizeof(struct siType));
  1364. if (s == NULL)
  1365. return BadAlloc;
  1366. if (p == NULL)
  1367. siTypeList = s;
  1368. else
  1369. p->next = s;
  1370. s->next = NULL;
  1371. s->typeName = typeName;
  1372. s->addrMatch = addrMatch;
  1373. s->checkAddr = checkAddr;
  1374. s->typePriv = typePriv;
  1375. return Success;
  1376. }
  1377. /* Checks to see if a host matches a server-interpreted host entry */
  1378. static Bool
  1379. siAddrMatch(int family, pointer addr, int len, HOST *host, ClientPtr client)
  1380. {
  1381. Bool matches = FALSE;
  1382. struct siType *s;
  1383. const char *valueString;
  1384. int addrlen;
  1385. valueString = (const char *) memchr(host->addr, '\0', host->len);
  1386. if (valueString != NULL) {
  1387. for (s = siTypeList; s != NULL ; s = s->next) {
  1388. if (strcmp((char *) host->addr, s->typeName) == 0) {
  1389. addrlen = host->len - (strlen((char *)host->addr) + 1);
  1390. matches = s->addrMatch(family, addr, len,
  1391. valueString + 1, addrlen, client, s->typePriv);
  1392. break;
  1393. }
  1394. }
  1395. #ifdef FAMILY_SI_DEBUG
  1396. ErrorF(
  1397. "Xserver: siAddrMatch(): type = %s, value = %*.*s -- %s\n",
  1398. host->addr, addrlen, addrlen, valueString + 1,
  1399. (matches) ? "accepted" : "rejected");
  1400. #endif
  1401. }
  1402. return matches;
  1403. }
  1404. static int
  1405. siCheckAddr(const char *addrString, int length)
  1406. {
  1407. const char *valueString;
  1408. int addrlen, typelen;
  1409. int len = -1;
  1410. struct siType *s;
  1411. /* Make sure there is a \0 byte inside the specified length
  1412. to separate the address type from the address value. */
  1413. valueString = (const char *) memchr(addrString, '\0', length);
  1414. if (valueString != NULL) {
  1415. /* Make sure the first string is a recognized address type,
  1416. * and the second string is a valid address of that type.
  1417. */
  1418. typelen = strlen(addrString) + 1;
  1419. addrlen = length - typelen;
  1420. for (s = siTypeList; s != NULL ; s = s->next) {
  1421. if (strcmp(addrString, s->typeName) == 0) {
  1422. len = s->checkAddr(valueString + 1, addrlen, s->typePriv);
  1423. if (len >= 0) {
  1424. len += typelen;
  1425. }
  1426. break;
  1427. }
  1428. }
  1429. #ifdef FAMILY_SI_DEBUG
  1430. {
  1431. const char *resultMsg;
  1432. if (s == NULL) {
  1433. resultMsg = "type not registered";
  1434. } else {
  1435. if (len == -1)
  1436. resultMsg = "rejected";
  1437. else
  1438. resultMsg = "accepted";
  1439. }
  1440. ErrorF("Xserver: siCheckAddr(): type = %s, value = %*.*s, len = %d -- %s\n",
  1441. addrString, addrlen, addrlen, valueString + 1, len, resultMsg);
  1442. }
  1443. #endif
  1444. }
  1445. return len;
  1446. }
  1447. /***
  1448. * Hostname server-interpreted host type
  1449. *
  1450. * Stored as hostname string, explicitly defined to be resolved ONLY
  1451. * at access check time, to allow for hosts with dynamic addresses
  1452. * but static hostnames, such as found in some DHCP & mobile setups.
  1453. *
  1454. * Hostname must conform to IETF RFC 2396 sec. 3.2.2, which defines it as:
  1455. * hostname = *( domainlabel "." ) toplabel [ "." ]
  1456. * domainlabel = alphanum | alphanum *( alphanum | "-" ) alphanum
  1457. * toplabel = alpha | alpha *( alphanum | "-" ) alphanum
  1458. */
  1459. #ifdef NI_MAXHOST
  1460. # define SI_HOSTNAME_MAXLEN NI_MAXHOST
  1461. #else
  1462. # ifdef MAXHOSTNAMELEN
  1463. # define SI_HOSTNAME_MAXLEN MAXHOSTNAMELEN
  1464. # else
  1465. # define SI_HOSTNAME_MAXLEN 256
  1466. # endif
  1467. #endif
  1468. static Bool
  1469. siHostnameAddrMatch(int family, pointer addr, int len,
  1470. const char *siAddr, int siAddrLen, ClientPtr client, void *typePriv)
  1471. {
  1472. Bool res = FALSE;
  1473. /* Currently only supports checking against IPv4 & IPv6 connections, but
  1474. * support for other address families, such as DECnet, could be added if
  1475. * desired.
  1476. */
  1477. #if defined(IPv6) && defined(AF_INET6)
  1478. if ((family == FamilyInternet) || (family == FamilyInternet6)) {
  1479. char hostname[SI_HOSTNAME_MAXLEN];
  1480. struct addrinfo *addresses;
  1481. struct addrinfo *a;
  1482. int f, hostaddrlen;
  1483. pointer hostaddr = NULL;
  1484. if (siAddrLen >= sizeof(hostname))
  1485. return FALSE;
  1486. strncpy(hostname, siAddr, siAddrLen);
  1487. hostname[siAddrLen] = '\0';
  1488. if (getaddrinfo(hostname, NULL, NULL, &addresses) == 0) {
  1489. for (a = addresses ; a != NULL ; a = a->ai_next) {
  1490. hostaddrlen = a->ai_addrlen;
  1491. f = ConvertAddr(a->ai_addr,&hostaddrlen,&hostaddr);
  1492. if ((f == family) && (len == hostaddrlen) &&
  1493. (acmp (addr, hostaddr, len) == 0) ) {
  1494. res = TRUE;
  1495. break;
  1496. }
  1497. }
  1498. freeaddrinfo(addresses);
  1499. }
  1500. }
  1501. #else /* IPv6 not supported, use gethostbyname instead for IPv4 */
  1502. if (family == FamilyInternet) {
  1503. struct hostent *hp;
  1504. #ifdef XTHREADS_NEEDS_BYNAMEPARAMS
  1505. _Xgethostbynameparams hparams;
  1506. #endif
  1507. char hostname[SI_HOSTNAME_MAXLEN];
  1508. int f, hostaddrlen;
  1509. pointer hostaddr;
  1510. const char **addrlist;
  1511. if (siAddrLen >= sizeof(hostname))
  1512. return FALSE;
  1513. strncpy(hostname, siAddr, siAddrLen);
  1514. hostname[siAddrLen] = '\0';
  1515. if ((hp = _XGethostbyname(hostname, hparams)) != NULL) {
  1516. #ifdef h_addr /* new 4.3bsd version of gethostent */
  1517. /* iterate over the addresses */
  1518. for (addrlist = hp->h_addr_list; *addrlist; addrlist++)
  1519. #else
  1520. addrlist = &hp->h_addr;
  1521. #endif
  1522. {
  1523. struct sockaddr_in sin;
  1524. sin.sin_family = hp->h_addrtype;
  1525. acopy ( *addrlist, &(sin.sin_addr), hp->h_length);
  1526. hostaddrlen = sizeof(sin);
  1527. f = ConvertAddr ((struct sockaddr *)&sin,
  1528. &hostaddrlen, &hostaddr);
  1529. if ((f == family) && (len == hostaddrlen) &&
  1530. (acmp (addr, hostaddr, len) == 0) ) {
  1531. res = TRUE;
  1532. break;
  1533. }
  1534. }
  1535. }
  1536. }
  1537. #endif
  1538. return res;
  1539. }
  1540. static int
  1541. siHostnameCheckAddr(const char *valueString, int length, void *typePriv)
  1542. {
  1543. /* Check conformance of hostname to RFC 2396 sec. 3.2.2 definition.
  1544. * We do not use ctype functions here to avoid locale-specific
  1545. * character sets. Hostnames must be pure ASCII.
  1546. */
  1547. int len = length;
  1548. int i;
  1549. Bool dotAllowed = FALSE;
  1550. Bool dashAllowed = FALSE;
  1551. if ((length <= 0) || (length >= SI_HOSTNAME_MAXLEN)) {
  1552. len = -1;
  1553. } else {
  1554. for (i = 0; i < length; i++) {
  1555. char c = valueString[i];
  1556. if (c == 0x2E) { /* '.' */
  1557. if (dotAllowed == FALSE) {
  1558. len = -1;
  1559. break;
  1560. } else {
  1561. dotAllowed = FALSE;
  1562. dashAllowed = FALSE;
  1563. }
  1564. } else if (c == 0x2D) { /* '-' */
  1565. if (dashAllowed == FALSE) {
  1566. len = -1;
  1567. break;
  1568. } else {
  1569. dotAllowed = FALSE;
  1570. }
  1571. } else if (((c >= 0x30) && (c <= 0x3A)) /* 0-9 */ ||
  1572. ((c >= 0x61) && (c <= 0x7A)) /* a-z */ ||
  1573. ((c >= 0x41) && (c <= 0x5A)) /* A-Z */) {
  1574. dotAllowed = TRUE;
  1575. dashAllowed = TRUE;
  1576. } else { /* Invalid character */
  1577. len = -1;
  1578. break;
  1579. }
  1580. }
  1581. }
  1582. return len;
  1583. }
  1584. #if defined(IPv6) && defined(AF_INET6)
  1585. /***
  1586. * "ipv6" server interpreted type
  1587. *
  1588. * Currently supports only IPv6 literal address as specified in IETF RFC 3513
  1589. *
  1590. * Once draft-ietf-ipv6-scoping-arch-00.txt becomes an RFC, support will be
  1591. * added for the scoped address format it specifies.
  1592. */
  1593. /* Maximum length of an IPv6 address string - increase when adding support
  1594. * for scoped address qualifiers. Includes room for trailing NUL byte.
  1595. */
  1596. #define SI_IPv6_MAXLEN INET6_ADDRSTRLEN
  1597. static Bool
  1598. siIPv6AddrMatch(int family, pointer addr, int len,
  1599. const char *siAddr, int siAddrlen, ClientPtr client, void *typePriv)
  1600. {
  1601. struct in6_addr addr6;
  1602. char addrbuf[SI_IPv6_MAXLEN];
  1603. if ((family != FamilyInternet6) || (len != sizeof(addr6)))
  1604. return FALSE;
  1605. memcpy(addrbuf, siAddr, siAddrlen);
  1606. addrbuf[siAddrlen] = '\0';
  1607. if (inet_pton(AF_INET6, addrbuf, &addr6) != 1) {
  1608. perror("inet_pton");
  1609. return FALSE;
  1610. }
  1611. if (memcmp(addr, &addr6, len) == 0) {
  1612. return TRUE;
  1613. } else {
  1614. return FALSE;
  1615. }
  1616. }
  1617. static int
  1618. siIPv6CheckAddr(const char *addrString, int length, void *typePriv)
  1619. {
  1620. int len;
  1621. /* Minimum length is 3 (smallest legal address is "::1") */
  1622. if (length < 3) {
  1623. /* Address is too short! */
  1624. len = -1;
  1625. } else if (length >= SI_IPv6_MAXLEN) {
  1626. /* Address is too long! */
  1627. len = -1;
  1628. } else {
  1629. /* Assume inet_pton is sufficient validation */
  1630. struct in6_addr addr6;
  1631. char addrbuf[SI_IPv6_MAXLEN];
  1632. memcpy(addrbuf, addrString, length);
  1633. addrbuf[length] = '\0';
  1634. if (inet_pton(AF_INET6, addrbuf, &addr6) != 1) {
  1635. perror("inet_pton");
  1636. len = -1;
  1637. } else {
  1638. len = length;
  1639. }
  1640. }
  1641. return len;
  1642. }
  1643. #endif /* IPv6 */
  1644. #if !defined(NO_LOCAL_CLIENT_CRED)
  1645. /***
  1646. * "localuser" & "localgroup" server interpreted types
  1647. *
  1648. * Allows local connections from a given local user or group
  1649. */
  1650. #include <pwd.h>
  1651. #include <grp.h>
  1652. #define LOCAL_USER 1
  1653. #define LOCAL_GROUP 2
  1654. typedef struct {
  1655. int credType;
  1656. } siLocalCredPrivRec, *siLocalCredPrivPtr;
  1657. static siLocalCredPrivRec siLocalUserPriv = { LOCAL_USER };
  1658. static siLocalCredPrivRec siLocalGroupPriv = { LOCAL_GROUP };
  1659. static Bool
  1660. siLocalCredGetId(const char *addr, int len, siLocalCredPrivPtr lcPriv, int *id)
  1661. {
  1662. Bool parsedOK = FALSE;
  1663. char *addrbuf = malloc(len + 1);
  1664. if (addrbuf == NULL) {
  1665. return FALSE;
  1666. }
  1667. memcpy(addrbuf, addr, len);
  1668. addrbuf[len] = '\0';
  1669. if (addr[0] == '#') { /* numeric id */
  1670. char *cp;
  1671. errno = 0;
  1672. *id = strtol(addrbuf + 1, &cp, 0);
  1673. if ((errno == 0) && (cp != (addrbuf+1))) {
  1674. parsedOK = TRUE;
  1675. }
  1676. } else { /* non-numeric name */
  1677. if (lcPriv->credType == LOCAL_USER) {
  1678. struct passwd *pw = getpwnam(addrbuf);
  1679. if (pw != NULL) {
  1680. *id = (int) pw->pw_uid;
  1681. parsedOK = TRUE;
  1682. }
  1683. } else { /* group */
  1684. struct group *gr = getgrnam(addrbuf);
  1685. if (gr != NULL) {
  1686. *id = (int) gr->gr_gid;
  1687. parsedOK = TRUE;
  1688. }
  1689. }
  1690. }
  1691. free(addrbuf);
  1692. return parsedOK;
  1693. }
  1694. static Bool
  1695. siLocalCredAddrMatch(int family, pointer addr, int len,
  1696. const char *siAddr, int siAddrlen, ClientPtr client, void *typePriv)
  1697. {
  1698. int connUid, connGid, *connSuppGids, connNumSuppGids, siAddrId;
  1699. siLocalCredPrivPtr lcPriv = (siLocalCredPrivPtr) typePriv;
  1700. if (LocalClientCredAndGroups(client, &connUid, &connGid,
  1701. &connSuppGids, &connNumSuppGids) == -1) {
  1702. return FALSE;
  1703. }
  1704. if (siLocalCredGetId(siAddr, siAddrlen, lcPriv, &siAddrId) == FALSE) {
  1705. return FALSE;
  1706. }
  1707. if (lcPriv->credType == LOCAL_USER) {
  1708. if (connUid == siAddrId) {
  1709. return TRUE;
  1710. }
  1711. } else {
  1712. if (connGid == siAddrId) {
  1713. return TRUE;
  1714. }
  1715. if (connSuppGids != NULL) {
  1716. int i;
  1717. for (i = 0 ; i < connNumSuppGids; i++) {
  1718. if (connSuppGids[i] == siAddrId) {
  1719. free(connSuppGids);
  1720. return TRUE;
  1721. }
  1722. }
  1723. free(connSuppGids);
  1724. }
  1725. }
  1726. return FALSE;
  1727. }
  1728. static int
  1729. siLocalCredCheckAddr(const char *addrString, int length, void *typePriv)
  1730. {
  1731. int len = length;
  1732. int id;
  1733. if (siLocalCredGetId(addrString, length,
  1734. (siLocalCredPrivPtr)typePriv, &id) == FALSE) {
  1735. len = -1;
  1736. }
  1737. return len;
  1738. }
  1739. #endif /* localuser */
  1740. static void
  1741. siTypesInitialize(void)
  1742. {
  1743. siTypeAdd("hostname", siHostnameAddrMatch, siHostnameCheckAddr, NULL);
  1744. #if defined(IPv6) && defined(AF_INET6)
  1745. siTypeAdd("ipv6", siIPv6AddrMatch, siIPv6CheckAddr, NULL);
  1746. #endif
  1747. #if !defined(NO_LOCAL_CLIENT_CRED)
  1748. siTypeAdd("localuser", siLocalCredAddrMatch, siLocalCredCheckAddr,
  1749. &siLocalUserPriv);
  1750. siTypeAdd("localgroup", siLocalCredAddrMatch, siLocalCredCheckAddr,
  1751. &siLocalGroupPriv);
  1752. #endif
  1753. }