3
Read options from kdmrc
5
Copyright (C) 2001-2005 Oswald Buddenhagen <ossi@kde.org>
8
This program is free software; you can redistribute it and/or modify
9
it under the terms of the GNU General Public License as published by
10
the Free Software Foundation; either version 2 of the License, or
11
(at your option) any later version.
13
This program is distributed in the hope that it will be useful,
14
but WITHOUT ANY WARRANTY; without even the implied warranty of
15
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
GNU General Public License for more details.
18
You should have received a copy of the GNU General Public License
19
along with this program; if not, write to the Free Software
20
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
24
#include <config-workspace.h>
35
#include <netinet/in.h>
37
#ifdef _POSIX_PRIORITY_SCHEDULING
42
#ifdef FamilyInternet6
48
#define WANT_CONF_READ
52
* Section/Entry definition structs
69
* Parsed ini file structs
72
typedef struct Entry {
80
typedef struct Section {
84
const char *name, *dname, *dhost, *dnum, *dclass;
85
int nlen, dlen, dhostl, dnuml, dclassl;
90
* Split up display-name/-class for fast comparison
92
typedef struct DSpec {
93
const char *dhost, *dnum, *dclass;
94
int dhostl, dnuml, dclassl;
99
* Config value storage structures
102
typedef union Value {
105
int len; /* including 0-terminator */
109
int totlen; /* summed up length of all contained strings */
119
typedef struct ValArr {
121
int nents, esiz, nchars, nptrs;
125
static void *Malloc(size_t size);
126
static void *Realloc(void *ptr, size_t size);
129
#define LOG_NAME "kdm_config"
130
#define LOG_DEBUG_MASK DEBUG_CONFIG
131
#define LOG_PANIC_EXIT 1
132
#define STATIC static
141
if (!(ret = malloc(size)))
147
Realloc(void *ptr, size_t size)
151
if (!(ret = realloc(ptr, size)) && size)
158
mkDSpec(DSpec *spec, const char *dname, const char *dclass)
161
for (spec->dhostl = 0; dname[spec->dhostl] != ':'; spec->dhostl++);
162
spec->dnum = dname + spec->dhostl + 1;
163
spec->dnuml = strlen(spec->dnum);
164
spec->dclass = dclass;
165
spec->dclassl = strlen(dclass);
172
reader(void *buf, int count)
176
for (rlen = 0; rlen < count;) {
178
ret = read(rfd, (char *)buf + rlen, count - rlen);
194
gRead(void *buf, int count)
196
if (reader(buf, count) != count)
197
logPanic("Cannot read from core\n");
201
gWrite(const void *buf, int count)
203
if (write(wfd, buf, count) != count)
204
logPanic("Cannot write to core\n");
205
#ifdef _POSIX_PRIORITY_SCHEDULING
206
if ((debugLevel & DEBUG_HLPCON))
214
gWrite(&val, sizeof(val));
218
gSendStr(const char *buf)
221
int len = strlen(buf) + 1;
222
gWrite(&len, sizeof(len));
225
gWrite(&buf, sizeof(int));
230
gSendNStr(const char *buf, int len)
233
gWrite(&tlen, sizeof(tlen));
240
gSendArr(int len, const char *data)
242
gWrite(&len, sizeof(len));
250
if (reader(val, sizeof(*val)) != sizeof(*val))
260
gRead(&val, sizeof(val));
273
if (!(buf = malloc(len)))
274
logPanic("No memory for read buffer");
280
/* #define WANT_CLOSE 1 */
282
typedef struct File {
283
char *buf, *eof, *cur;
284
#if defined(HAVE_MMAP) && defined(WANT_CLOSE)
290
readFile(File *file, const char *fn, const char *what)
295
if ((fd = open(fn, O_RDONLY)) < 0) {
296
logInfo("Cannot open %s file %s\n", what, fn);
300
flen = lseek(fd, 0, SEEK_END);
303
file->ismapped = False;
305
file->buf = mmap(0, flen + 1, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);
308
file->ismapped = True;
315
if (!(file->buf = Malloc(flen + 1))) {
319
lseek(fd, 0, SEEK_SET);
320
if (read(fd, file->buf, flen) != flen) {
322
logError("Cannot read %s file %s\n", what, fn);
327
file->eof = (file->cur = file->buf) + flen;
338
munmap(file->buf, file->eof - file->buf + 1);
347
#define C_MTYPE_MASK 0x30000000
348
# define C_PATH 0x10000000 /* C_TYPE_STR is a path spec */
349
# define C_BOOL 0x10000000 /* C_TYPE_INT is a boolean */
350
# define C_ENUM 0x20000000 /* C_TYPE_INT is an enum (option) */
351
# define C_GRP 0x30000000 /* C_TYPE_INT is a group spec */
352
#define C_INTERNAL 0x40000000 /* don't expose to core */
353
#define C_CONFIG 0x80000000 /* process only for finding deps */
357
PrequestPort(Value *retval)
359
if (!VxdmcpEnable.num) {
368
emptyStr = { { "", 1 } },
369
nullValue = { { 0, 0 } },
370
emptyArgv = { { (char *)&nullValue, 0 } };
373
PnoPassUsers(Value *retval)
375
if (!VnoPassEnable.num) {
383
PautoLoginX(Value *retval)
385
if (!VautoLoginEnable.num) {
394
static const char *kdmrc = KDMCONF "/kdmrc";
396
static Section *rootsec;
401
const char *nstr, *dstr, *cstr, *dhost, *dnum, *dclass;
402
char *s, *e, *st, *en, *ek, *sl, *pt;
406
int nlen, dlen, clen, dhostl, dnuml, dclassl;
407
int i, line, sectmoan, restl;
415
debug("reading config %s ...\n", kdmrc);
416
if (!readFile(&file, kdmrc, "master configuration"))
419
for (s = file.buf, line = 0, cursec = 0, sectmoan = 1; s < file.eof; s++) {
422
while ((s < file.eof) && isspace(*s) && (*s != '\n'))
425
if ((s < file.eof) && ((*s == '\n') || (*s == '#'))) {
427
while ((s < file.eof) && (*s != '\n'))
435
while ((s < file.eof) && (*s != '\n'))
438
while ((e > sl) && isspace(*e))
442
logError("Invalid section header at %s:%d\n", kdmrc, line);
447
for (cursec = rootsec; cursec; cursec = cursec->next)
448
if (nlen == cursec->nlen &&
449
!memcmp(nstr, cursec->name, nlen))
451
logInfo("Multiple occurrences of section [%.*s] in %s. "
452
"Consider merging them.\n", nlen, nstr, kdmrc);
455
if (nstr[0] == 'X' && nstr[1] == '-') {
458
while (++clen, *--cstr != '-');
459
if (cstr == nstr + 1)
462
dlen = nlen - clen - 2;
465
for (restl = dlen; restl; restl--) {
466
if (dhost[dhostl] == ':') {
467
dnum = dhost + dhostl + 1;
469
for (restl--; restl; restl--) {
470
if (dnum[dnuml] == '_') {
471
dclass = dnum + dnuml + 1;
501
for (i = 0; i < as(allSects); i++)
502
if ((int)strlen(allSects[i]->name) == clen &&
503
!memcmp(allSects[i]->name, cstr, clen))
507
logError("Unrecognized section name [%.*s] at %s:%d\n",
508
nlen, nstr, kdmrc, line);
511
if (!(cursec = Malloc(sizeof(*cursec))))
515
cursec->dname = dstr;
517
cursec->dhost = dhost;
518
cursec->dhostl = dhostl;
520
cursec->dnuml = dnuml;
521
cursec->dclass = dclass;
522
cursec->dclassl = dclassl;
523
cursec->sect = allSects[i];
525
cursec->next = rootsec;
527
/*debug("now in section [%.*s], dpy '%.*s', core '%.*s'\n",
528
nlen, nstr, dlen, dstr, clen, cstr);*/
536
logError("Entry outside any section at %s:%d", kdmrc, line);
541
for (; (s < file.eof) && (*s != '\n'); s++)
544
logError("Invalid entry (missing '=') at %s:%d\n", kdmrc, line);
548
for (ek = s - 1; ; ek--) {
550
logError("Invalid entry (empty key) at %s:%d\n", kdmrc, line);
558
while ((s < file.eof) && isspace(*s) && (*s != '\n'))
560
for (pt = st = en = s; s < file.eof && *s != '\n'; s++) {
563
if (s >= file.eof || *s == '\n') {
564
logError("Trailing backslash at %s:%d\n", kdmrc, line);
568
case 's': *pt++ = ' '; break;
569
case 't': *pt++ = '\t'; break;
570
case 'n': *pt++ = '\n'; break;
571
case 'r': *pt++ = '\r'; break;
572
case '\\': *pt++ = '\\'; break;
573
default: *pt++ = '\\'; *pt++ = *s; break;
578
if (*s != ' ' && *s != '\t')
585
/*debug("read entry '%.*s'='%.*s'\n", nlen, nstr, en - st, st);*/
586
for (i = 0; i < cursec->sect->numents; i++) {
587
ce = cursec->sect->ents + i;
588
if ((int)strlen(ce->name) == nlen &&
589
!memcmp(ce->name, nstr, nlen))
592
logError("Unrecognized key '%.*s' in section [%.*s] at %s:%d\n",
593
nlen, nstr, cursec->nlen, cursec->name, kdmrc, line);
596
for (curent = cursec->entries; curent; curent = curent->next)
597
if (ce == curent->ent) {
598
logError("Multiple occurrences of key '%s' in section [%.*s] of %s\n",
599
ce->name, cursec->nlen, cursec->name, kdmrc);
602
if (!(curent = Malloc(sizeof(*curent))))
607
curent->vallen = en - st;
608
curent->next = cursec->entries;
609
cursec->entries = curent;
621
for (cursec = rootsec; cursec; cursec = cursec->next)
623
for (curent = cursec->entries; curent; curent = curent->next)
624
if (curent->ent->id == id) {
625
debug("line %d: %s = %'.*s\n",
626
curent->line, curent->ent->name,
627
curent->vallen, curent->val);
633
/* Display name match scoring:
634
* - class (any/exact) -> 0/1
635
* - number (any/exact) -> 0/2
636
* - host (any/nonempty/trail/exact) -> 0/4/8/12
639
findDEnt(int id, DSpec *dspec)
641
Section *cursec, *bestsec = 0;
642
Entry *curent, *bestent;
643
int score, bestscore;
645
bestscore = -1, bestent = 0;
646
for (cursec = rootsec; cursec; cursec = cursec->next)
649
if (cursec->dclassl != 1 || cursec->dclass[0] != '*') {
650
if (cursec->dclassl == dspec->dclassl &&
651
!memcmp(cursec->dclass, dspec->dclass, dspec->dclassl))
656
if (cursec->dnuml != 1 || cursec->dnum[0] != '*') {
657
if (cursec->dnuml == dspec->dnuml &&
658
!memcmp(cursec->dnum, dspec->dnum, dspec->dnuml))
663
if (cursec->dhostl != 1 || cursec->dhost[0] != '*') {
664
if (cursec->dhostl == 1 && cursec->dhost[0] == '+') {
669
} else if (cursec->dhost[0] == '.') {
670
if (cursec->dhostl < dspec->dhostl &&
671
!memcmp(cursec->dhost,
672
dspec->dhost + dspec->dhostl - cursec->dhostl,
678
if (cursec->dhostl == dspec->dhostl &&
679
!memcmp(cursec->dhost, dspec->dhost, dspec->dhostl))
685
if (score > bestscore) {
686
for (curent = cursec->entries; curent; curent = curent->next)
687
if (curent->ent->id == id) {
696
debug("line %d: %.*s:%.*s_%.*s/%s = %'.*s\n", bestent->line,
697
bestsec->dhostl, bestsec->dhost,
698
bestsec->dnuml, bestsec->dnum,
699
bestsec->dclassl, bestsec->dclass,
700
bestent->ent->name, bestent->vallen, bestent->val);
705
convertValue(Ent *et, Value *retval, int vallen, const char *val, char **eopts)
708
int i, b, e, tlen, nents, esiz;
711
switch (et->id & C_TYPE_MASK) {
713
for (i = 0; i < vallen && i < (int)sizeof(buf) - 1; i++)
714
buf[i] = tolower(val[i]);
716
if ((et->id & C_MTYPE_MASK) == C_BOOL) {
717
if (!strcmp(buf, "true") ||
718
!strcmp(buf, "on") ||
719
!strcmp(buf, "yes") ||
722
else if (!strcmp(buf, "false") ||
723
!strcmp(buf, "off") ||
724
!strcmp(buf, "no") ||
730
} else if ((et->id & C_MTYPE_MASK) == C_ENUM) {
731
for (i = 0; eopts[i]; i++)
732
if (!memcmp(eopts[i], val, vallen) && !eopts[i][vallen]) {
737
} else if ((et->id & C_MTYPE_MASK) == C_GRP) {
739
if ((ge = getgrnam(buf))) {
740
retval->num = ge->gr_gid;
744
if (sscanf(buf, "%i", &retval->num) != 1)
748
retval->str.ptr = val;
749
retval->str.len = vallen + 1;
750
if ((et->id & C_MTYPE_MASK) == C_PATH)
751
if (vallen && val[vallen-1] == '/')
755
if (!(ents = Malloc(sizeof(Value) * (esiz = 10))))
757
for (nents = 0, tlen = 0, i = 0; ; i++) {
758
for (; i < vallen && isspace(val[i]); i++) ;
759
for (b = i; i < vallen && val[i] != ','; i++) ;
762
for (e = i; e > b && isspace(val[e - 1]); e--) ;
763
if (esiz < nents + 2) {
764
Value *entsn = Realloc(ents, sizeof(Value) * (esiz = esiz * 2 + 1));
769
ents[nents].str.ptr = val + b;
770
ents[nents].str.len = e - b;
774
ents[nents].str.ptr = 0;
775
retval->argv.ptr = ents;
776
retval->argv.totlen = tlen;
779
logError("Internal error: unknown value type in id %#x\n", et->id);
785
getValue(Ent *et, DSpec *dspec, Value *retval, char **eopts)
790
/* debug("Getting value %#x\n", et->id);*/
792
ent = findDEnt(et->id, dspec);
794
ent = findGEnt(et->id);
796
if (!(errs = convertValue(et, retval, ent->vallen, ent->val, eopts)))
798
logError("Invalid %s value '%.*s' at %s:%d\n",
799
errs, ent->vallen, ent->val, kdmrc, ent->line);
801
debug("default: %s = %'s\n", et->name, et->def);
802
if ((errs = convertValue(et, retval, strlen(et->def), et->def, eopts)))
803
logError("Internal error: invalid default %s value '%s' for key %s\n",
804
errs, et->def, et->name);
808
addValue(ValArr *va, int id, Value *val)
812
/* debug("Addig value %#x\n", id);*/
813
if (va->nents == va->esiz) {
814
va->ents = Realloc(va->ents, sizeof(Val) * (va->esiz += 50));
818
va->ents[va->nents].id = id;
819
va->ents[va->nents].val = *val;
821
switch (id & C_TYPE_MASK) {
825
va->nchars += val->str.len;
828
va->nchars += val->argv.totlen;
829
for (nu = 0; val->argv.ptr[nu++].str.ptr;);
837
copyValues(ValArr *va, Sect *sec, DSpec *dspec, int isconfig)
842
debug("getting values for section class [%s]\n", sec->name);
843
for (i = 0; i < sec->numents; i++) {
844
/*debug ("value %#x\n", sec->ents[i].id);*/
845
if ((sec->ents[i].id & (int)C_CONFIG) != isconfig) {
846
} else if (sec->ents[i].id & C_INTERNAL) {
847
getValue(sec->ents + i, dspec, ((Value *)sec->ents[i].ptr), 0);
849
if (((sec->ents[i].id & C_MTYPE_MASK) == C_ENUM) ||
851
!((int (*)(Value *))sec->ents[i].ptr)(&val))
853
getValue(sec->ents + i, dspec, &val,
854
(char **)sec->ents[i].ptr);
856
if (!addValue(va, sec->ents[i].id, &val))
864
sendValues(ValArr *va)
871
gSendInt(0/*va->nints*/);
872
gSendInt(va->nchars);
873
for (i = 0; i < va->nents; i++) {
874
gSendInt(va->ents[i].id & ~C_PRIVATE);
875
switch (va->ents[i].id & C_TYPE_MASK) {
877
gSendInt(va->ents[i].val.num);
880
gSendNStr(va->ents[i].val.str.ptr, va->ents[i].val.str.len - 1);
883
cst = va->ents[i].val.argv.ptr;
884
for (nu = 0; cst[nu].str.ptr; nu++);
886
for (; cst->str.ptr; cst++)
887
gSendNStr(cst->str.ptr, cst->str.len);
896
readWord(File *file, int *len, int EOFatEOL)
898
char *wordp, *wordBuffer;
903
wordp = wordBuffer = file->cur;
907
if (file->cur == file->eof) {
909
if (wordp == wordBuffer)
913
*len = wordp - wordBuffer;
922
if (file->cur == file->eof)
928
if (EOFatEOL && !quoted) {
932
if (wordp != wordBuffer) {
939
if (wordp != wordBuffer)
953
#define ALIAS_CHARACTER '%'
954
#define EQUAL_CHARACTER '='
955
#define NEGATE_CHARACTER '!'
956
#define CHOOSER_STRING "CHOOSER"
957
#define BROADCAST_STRING "BROADCAST"
958
#define NOBROADCAST_STRING "NOBROADCAST"
959
#define LISTEN_STRING "LISTEN"
960
#define WILDCARD_STRING "*"
962
typedef struct _HostEntry {
963
struct _HostEntry *next;
976
typedef struct _ListenEntry {
977
struct _ListenEntry *next;
983
typedef struct _AliasEntry {
984
struct _AliasEntry *next;
992
typedef struct _AclEntry {
993
struct _AclEntry *next;
994
HostEntry **pEntries;
1005
hasGlobCharacters(char *s)
1018
#define PARSE_NO_BCAST 1
1019
#define PARSE_NO_PAT 2
1020
#define PARSE_NO_ALIAS 4
1023
parseHost(int *nHosts, HostEntry ***hostPtr, int *nChars,
1024
char *hostOrAlias, int len, int parse)
1026
#if defined(IPv6) && defined(AF_INET6)
1027
struct addrinfo *ai;
1029
struct hostent *hostent;
1032
int addr_type, addr_len;
1034
if (!(**hostPtr = Malloc(sizeof(HostEntry))))
1036
if (!(parse & PARSE_NO_BCAST) && !strcmp(hostOrAlias, BROADCAST_STRING)) {
1037
(**hostPtr)->type = HOST_BROADCAST;
1038
} else if (!(parse & PARSE_NO_ALIAS) && *hostOrAlias == ALIAS_CHARACTER) {
1039
(**hostPtr)->type = HOST_ALIAS;
1040
(**hostPtr)->entry.aliasPattern = hostOrAlias + 1;
1042
} else if (!(parse & PARSE_NO_PAT) && hasGlobCharacters(hostOrAlias)) {
1043
(**hostPtr)->type = HOST_PATTERN;
1044
(**hostPtr)->entry.hostPattern = hostOrAlias;
1047
(**hostPtr)->type = HOST_ADDRESS;
1048
#if defined(IPv6) && defined(AF_INET6)
1049
if (getaddrinfo(hostOrAlias, 0, 0, &ai))
1051
if (!(hostent = gethostbyname(hostOrAlias)))
1054
logWarn("XDMCP ACL: unresolved host %'s\n", hostOrAlias);
1058
#if defined(IPv6) && defined(AF_INET6)
1059
addr_type = ai->ai_addr->sa_family;
1060
if (ai->ai_family == AF_INET) {
1061
addr = &((struct sockaddr_in *)ai->ai_addr)->sin_addr;
1062
addr_len = sizeof(struct in_addr);
1063
} else /*if (ai->ai_addr->sa_family == AF_INET6)*/ {
1064
addr = &((struct sockaddr_in6 *)ai->ai_addr)->sin6_addr;
1065
addr_len = sizeof(struct in6_addr);
1068
addr_type = hostent->h_addrtype;
1069
addr = hostent->h_addr;
1070
addr_len = hostent->h_length;
1072
if (!((**hostPtr)->entry.displayAddress.hostAddress =
1075
#if defined(IPv6) && defined(AF_INET6)
1081
memcpy((**hostPtr)->entry.displayAddress.hostAddress, addr, addr_len);
1082
*nChars += addr_len;
1083
(**hostPtr)->entry.displayAddress.hostAddrLen = addr_len;
1084
(**hostPtr)->entry.displayAddress.connectionType = addr_type;
1085
#if defined(IPv6) && defined(AF_INET6)
1089
*hostPtr = &(**hostPtr)->next;
1094
/* Returns True if string is matched by pattern. Does case folding. */
1096
patternMatch(const char *string, const char *pattern)
1105
switch (p = *pattern++) {
1109
for (string--; *string; string++)
1110
if (patternMatch(string, pattern))
1123
if (tolower(p) != tolower(s))
1129
#define MAX_DEPTH 32
1132
#define CHECK_NO_PAT 2
1135
checkHostlist(HostEntry **hosts, int nh, AliasEntry *aliases, int na,
1136
int depth, int flags)
1142
for (h = *hosts, hn = 0; hn < nh; hn++, h = h->next)
1143
if (h->type == HOST_ALIAS) {
1144
if (depth == MAX_DEPTH) {
1145
logError("XDMCP ACL: alias recursion involving %%%s\n",
1146
h->entry.aliasPattern);
1149
for (a = aliases, an = 0, am = False; an < na; an++, a = a->next)
1150
if (patternMatch(a->name, h->entry.aliasPattern)) {
1152
if ((flags & CHECK_NOT) && a->hasBad) {
1153
logError("XDMCP ACL: alias %%%s with unresolved hosts "
1154
"in denying rule\n", a->name);
1157
if (checkHostlist(a->pHosts, a->nhosts, aliases, na,
1162
if (flags & CHECK_NOT) {
1163
logError("XDMCP ACL: unresolved alias pattern %%%s "
1164
"in denying rule\n", h->entry.aliasPattern);
1167
logWarn("XDMCP ACL: unresolved alias pattern %%%s\n",
1168
h->entry.aliasPattern);
1170
} else if (h->type == HOST_PATTERN && (flags & CHECK_NO_PAT)) {
1171
logWarn("XDMCP ACL: wildcarded pattern %'s in host-only context\n",
1172
h->entry.hostPattern);
1178
readAccessFile(const char *fname)
1180
HostEntry *hostList, **hostPtr = &hostList;
1181
AliasEntry *aliasList, **aliasPtr = &aliasList;
1182
AclEntry *acList, **acPtr = &acList, *acl;
1183
ListenEntry *listenList, **listenPtr = &listenList;
1184
char *displayOrAlias, *hostOrAlias;
1186
int nHosts, nAliases, nAcls, nListens, nChars, error, bad;
1189
nHosts = nAliases = nAcls = nListens = nChars = 0;
1191
if (!readFile(&file, fname, "XDMCP access control"))
1193
while ((displayOrAlias = readWord(&file, &len, False))) {
1194
if (*displayOrAlias == ALIAS_CHARACTER) {
1195
if (!(*aliasPtr = Malloc(sizeof(AliasEntry)))) {
1199
(*aliasPtr)->name = displayOrAlias + 1;
1201
(*aliasPtr)->hosts = nHosts;
1202
(*aliasPtr)->pHosts = hostPtr;
1203
(*aliasPtr)->nhosts = 0;
1204
(*aliasPtr)->hasBad = False;
1205
while ((hostOrAlias = readWord(&file, &len, True))) {
1206
if (parseHost(&nHosts, &hostPtr, &nChars, hostOrAlias, len,
1208
(*aliasPtr)->nhosts++;
1210
(*aliasPtr)->hasBad = True;
1212
aliasPtr = &(*aliasPtr)->next;
1214
} else if (!strcmp(displayOrAlias, LISTEN_STRING)) {
1215
if (!(*listenPtr = Malloc(sizeof(ListenEntry)))) {
1219
(*listenPtr)->iface = nHosts;
1220
if (!(hostOrAlias = readWord(&file, &len, True)) ||
1221
!strcmp(hostOrAlias, WILDCARD_STRING) ||
1222
!parseHost(&nHosts, &hostPtr, &nChars, hostOrAlias, len,
1223
PARSE_NO_BCAST | PARSE_NO_PAT | PARSE_NO_ALIAS))
1225
(*listenPtr)->iface = -1;
1227
(*listenPtr)->mcasts = nHosts;
1228
(*listenPtr)->nmcasts = 0;
1229
while ((hostOrAlias = readWord(&file, &len, True)))
1230
if (parseHost(&nHosts, &hostPtr, &nChars, hostOrAlias, len,
1231
PARSE_NO_BCAST | PARSE_NO_PAT | PARSE_NO_ALIAS))
1232
(*listenPtr)->nmcasts++;
1233
listenPtr = &(*listenPtr)->next;
1236
if (!(*acPtr = Malloc(sizeof(AclEntry)))) {
1240
(*acPtr)->flags = 0;
1241
if (*displayOrAlias == NEGATE_CHARACTER) {
1242
(*acPtr)->flags |= a_notAllowed;
1244
} else if (*displayOrAlias == EQUAL_CHARACTER) {
1247
(*acPtr)->entries = nHosts;
1248
(*acPtr)->pEntries = hostPtr;
1249
(*acPtr)->nentries = 1;
1250
if (!parseHost(&nHosts, &hostPtr, &nChars, displayOrAlias, len,
1253
if ((*acPtr)->flags & a_notAllowed) {
1254
logError("XDMCP ACL: unresolved host in denying rule\n");
1260
(*acPtr)->hosts = nHosts;
1261
(*acPtr)->pHosts = hostPtr;
1262
(*acPtr)->nhosts = 0;
1263
while ((hostOrAlias = readWord(&file, &len, True))) {
1264
if (!strcmp(hostOrAlias, CHOOSER_STRING)) {
1265
(*acPtr)->flags |= a_useChooser;
1266
} else if (!strcmp(hostOrAlias, NOBROADCAST_STRING)) {
1267
(*acPtr)->flags |= a_notBroadcast;
1269
if (parseHost(&nHosts, &hostPtr, &nChars,
1270
hostOrAlias, len, PARSE_NO_PAT))
1275
acPtr = &(*acPtr)->next;
1282
if (!(*listenPtr = Malloc(sizeof(ListenEntry)))) {
1285
(*listenPtr)->iface = -1;
1286
(*listenPtr)->mcasts = nHosts;
1287
(*listenPtr)->nmcasts = 0;
1288
#if defined(IPv6) && defined(AF_INET6) && defined(XDM_DEFAULT_MCAST_ADDR6)
1289
if (parseHost(&nHosts, &hostPtr, &nChars,
1290
XDM_DEFAULT_MCAST_ADDR6,
1291
sizeof(XDM_DEFAULT_MCAST_ADDR6) - 1,
1293
(*listenPtr)->nmcasts++;
1299
for (acl = acList, i = 0; i < nAcls; i++, acl = acl->next)
1300
if (checkHostlist(acl->pEntries, acl->nentries, aliasList, nAliases,
1301
0, (acl->flags & a_notAllowed) ? CHECK_NOT : 0) ||
1302
checkHostlist(acl->pHosts, acl->nhosts, aliasList, nAliases,
1309
nHosts = nAliases = nAcls = nListens = nChars = 0;
1311
logError("No XDMCP requests will be granted\n");
1318
for (i = 0; i < nHosts; i++, hostList = hostList->next) {
1319
gSendInt(hostList->type);
1320
switch (hostList->type) {
1322
gSendStr(hostList->entry.aliasPattern);
1325
gSendStr(hostList->entry.hostPattern);
1328
gSendArr(hostList->entry.displayAddress.hostAddrLen,
1329
hostList->entry.displayAddress.hostAddress);
1330
gSendInt(hostList->entry.displayAddress.connectionType);
1334
for (i = 0; i < nListens; i++, listenList = listenList->next) {
1335
gSendInt(listenList->iface);
1336
gSendInt(listenList->mcasts);
1337
gSendInt(listenList->nmcasts);
1339
for (i = 0; i < nAliases; i++, aliasList = aliasList->next) {
1340
gSendStr(aliasList->name);
1341
gSendInt(aliasList->hosts);
1342
gSendInt(aliasList->nhosts);
1344
for (i = 0; i < nAcls; i++, acList = acList->next) {
1345
gSendInt(acList->entries);
1346
gSendInt(acList->nentries);
1347
gSendInt(acList->hosts);
1348
gSendInt(acList->nhosts);
1349
gSendInt(acList->flags);
1355
int main(int argc ATTR_UNUSED, char **argv)
1359
char *ci, *disp, *dcls, *cfgfile;
1362
if (!(ci = getenv("CONINFO"))) {
1363
fprintf(stderr, "This program is part of kdm and should not be run manually.\n");
1366
if (sscanf(ci, "%d %d", &rfd, &wfd) != 2)
1371
if ((debugLevel = gRecvInt()) & DEBUG_WCONFIG)
1374
/* debug ("parsing command line\n");*/
1383
/* debug ("Awaiting command ...\n");*/
1384
if (!gRecvCmd(&what))
1388
/* debug ("GC_Files\n");*/
1390
copyValues(0, &secGeneral, 0, C_CONFIG);
1392
copyValues(0, &secXdmcp, 0, C_CONFIG);
1400
gSendNStr(VXaccess.str.ptr, VXaccess.str.len - 1);
1403
for (; (what = gRecvInt()) != -1;)
1420
/* debug("GC_GetConf\n");*/
1421
memset(&va, 0, sizeof(va));
1423
cfgfile = gRecvStr();
1426
/* debug("GC_gGlobal\n");*/
1427
debug("getting global config\n");
1429
copyValues(&va, &secGeneral, 0, 0);
1431
copyValues(&va, &secXdmcp, 0, 0);
1433
copyValues(&va, &secShutdown, 0, 0);
1437
/* debug("GC_gDisplay\n");*/
1439
/* debug(" Display %s\n", disp);*/
1441
/* debug(" Class %s\n", dcls);*/
1442
debug("getting config for display %s, class %s\n", disp, dcls);
1443
mkDSpec(&dspec, disp, dcls ? dcls : "");
1445
copyValues(&va, &sec_Core, &dspec, 0);
1446
copyValues(&va, &sec_Greeter, &dspec, 0);
1453
readAccessFile(cfgfile);
1457
debug("Unsupported config category %#x\n", what);
1462
debug("Unknown config command %#x\n", what);
1466
/* debug("Config reader exiting ...");*/