GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: usr.sbin/ypldap/parse.c Lines: 0 265 0.0 %
Date: 2017-11-07 Branches: 0 202 0.0 %

Line Branch Exec Source
1
#include <stdlib.h>
2
#include <string.h>
3
#define YYBYACC 1
4
#define YYMAJOR 1
5
#define YYMINOR 9
6
#define YYLEX yylex()
7
#define YYEMPTY -1
8
#define yyclearin (yychar=(YYEMPTY))
9
#define yyerrok (yyerrflag=0)
10
#define YYRECOVERING() (yyerrflag!=0)
11
#define YYPREFIX "yy"
12
#line 27 "parse.y"
13
#include <sys/types.h>
14
#include <sys/time.h>
15
#include <sys/queue.h>
16
#include <sys/tree.h>
17
#include <sys/socket.h>
18
#include <sys/stat.h>
19
20
#include <netinet/in.h>
21
#include <arpa/inet.h>
22
23
#include <ctype.h>
24
#include <err.h>
25
#include <errno.h>
26
#include <event.h>
27
#include <fcntl.h>
28
#include <limits.h>
29
#include <netdb.h>
30
#include <pwd.h>
31
#include <stdarg.h>
32
#include <stdio.h>
33
#include <stdlib.h>
34
#include <string.h>
35
#include <syslog.h>
36
#include <unistd.h>
37
38
#include "ypldap.h"
39
40
TAILQ_HEAD(files, file)		 files = TAILQ_HEAD_INITIALIZER(files);
41
static struct file {
42
	TAILQ_ENTRY(file)	 entry;
43
	FILE			*stream;
44
	char			*name;
45
	int			 lineno;
46
	int			 errors;
47
} *file, *topfile;
48
struct file	*pushfile(const char *, int);
49
int		 popfile(void);
50
int		 check_file_secrecy(int, const char *);
51
int		 yyparse(void);
52
int		 yylex(void);
53
int		 yyerror(const char *, ...)
54
    __attribute__((__format__ (printf, 1, 2)))
55
    __attribute__((__nonnull__ (1)));
56
int		 kw_cmp(const void *, const void *);
57
int		 lookup(char *);
58
int		 lgetc(int);
59
int		 lungetc(int);
60
int		 findeol(void);
61
62
TAILQ_HEAD(symhead, sym)	 symhead = TAILQ_HEAD_INITIALIZER(symhead);
63
struct sym {
64
	TAILQ_ENTRY(sym)	 entry;
65
	int			 used;
66
	int			 persist;
67
	char			*nam;
68
	char			*val;
69
};
70
int		 symset(const char *, const char *, int);
71
char		*symget(const char *);
72
73
struct env		*conf = NULL;
74
struct idm		*idm = NULL;
75
static int		 errors = 0;
76
77
typedef struct {
78
	union {
79
		int64_t		 number;
80
		char		*string;
81
	} v;
82
	int lineno;
83
} YYSTYPE;
84
85
#line 86 "parse.c"
86
#define SERVER 257
87
#define FILTER 258
88
#define ATTRIBUTE 259
89
#define BASEDN 260
90
#define BINDDN 261
91
#define GROUPDN 262
92
#define BINDCRED 263
93
#define MAPS 264
94
#define CHANGE 265
95
#define DOMAIN 266
96
#define PROVIDE 267
97
#define USER 268
98
#define GROUP 269
99
#define TO 270
100
#define EXPIRE 271
101
#define HOME 272
102
#define SHELL 273
103
#define GECOS 274
104
#define UID 275
105
#define GID 276
106
#define INTERVAL 277
107
#define PASSWD 278
108
#define NAME 279
109
#define FIXED 280
110
#define LIST 281
111
#define GROUPNAME 282
112
#define GROUPPASSWD 283
113
#define GROUPGID 284
114
#define MAP 285
115
#define INCLUDE 286
116
#define DIRECTORY 287
117
#define CLASS 288
118
#define PORT 289
119
#define ERROR 290
120
#define GROUPMEMBERS 291
121
#define LDAPS 292
122
#define TLS 293
123
#define CAFILE 294
124
#define STRING 295
125
#define NUMBER 296
126
#define YYERRCODE 256
127
const short yylhs[] =
128
	{                                        -1,
129
    0,    0,    0,    0,    0,    0,    0,    9,   10,   10,
130
    5,    6,    3,    3,    3,    1,    1,    2,    2,    2,
131
    2,    2,    2,    2,    2,    2,    2,    2,    2,    2,
132
    2,   11,   11,   11,   11,   11,   11,   11,   11,    4,
133
    4,    4,   12,    7,    8,    8,    8,    8,   13,   13,
134
};
135
const short yylen[] =
136
	{                                         2,
137
    0,    2,    3,    3,    3,    3,    3,    2,    2,    0,
138
    2,    3,    2,    2,    0,    1,    1,    1,    1,    1,
139
    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
140
    1,    2,    2,    2,    2,    3,    5,    4,    5,    0,
141
    1,    1,    0,    9,    2,    2,    3,    2,    3,    2,
142
};
143
const short yydefred[] =
144
	{                                      1,
145
    0,    0,    0,    0,    0,    0,    0,    0,    0,    2,
146
    0,    0,    0,    0,    7,   46,    0,   45,   11,    0,
147
   48,    0,    3,    4,    5,    6,   47,    0,    0,   12,
148
   13,   14,   41,   42,   43,    0,    0,    0,    0,    9,
149
    0,    0,    0,    0,    0,   16,   17,    0,    0,    0,
150
    0,    0,   23,   24,   26,   27,   25,   20,   21,   19,
151
   18,   28,   29,   30,   22,   31,    0,   34,   32,   35,
152
   33,    0,    0,    0,   50,   44,    0,    0,    0,    0,
153
   36,    0,   49,    0,   38,    0,    8,   37,   39,
154
};
155
const short yydgoto[] =
156
	{                                       1,
157
   50,   67,   29,   35,   11,   12,   13,   14,   83,   39,
158
   51,   36,   52,
159
};
160
const short yysindex[] =
161
	{                                      0,
162
  -10,   -4, -271, -260, -270, -266, -253, -252,  -17,    0,
163
   35,   38,   39,   41,    0,    0, -241,    0,    0, -233,
164
    0, -236,    0,    0,    0,    0,    0, -287, -273,    0,
165
    0,    0,    0,    0,    0,  -63,   51,   51, -228,    0,
166
 -261, -232, -231, -230, -229,    0,    0, -197, -261, -191,
167
   51, -123,    0,    0,    0,    0,    0,    0,    0,    0,
168
    0,    0,    0,    0,    0,    0, -196,    0,    0,    0,
169
    0, -261, -195, -225,    0,    0,   61, -198, -222, -194,
170
    0,   51,    0, -221,    0, -220,    0,    0,    0,};
171
const short yyrindex[] =
172
	{                                      0,
173
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
174
    0,    0,    0,    0,    0,    0,    0,    0,    0, -122,
175
    0,    0,    0,    0,    0,    0,    0,    0,  -46,    0,
176
    0,    0,    0,    0,    0,    0, -223, -118,    0,    0,
177
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
178
 -118,    0,    0,    0,    0,    0,    0,    0,    0,    0,
179
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
180
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
181
    0, -118,    0,    0,    0,    0,    0,    0,    0,};
182
const short yygindex[] =
183
	{                                      0,
184
    0,  -44,    0,    0,    0,    0,    0,    0,    0,  -35,
185
   26,    0,    0,
186
};
187
#define YYTABLESIZE 285
188
const short yytable[] =
189
	{                                      10,
190
   15,   76,   40,   53,   73,   15,   10,   31,   32,   54,
191
   55,   56,   57,   58,   59,   75,   60,   61,   33,   34,
192
   62,   63,   64,   16,   17,   18,   65,   79,   19,   66,
193
   41,   42,   43,   44,   45,   10,   10,   10,   10,   10,
194
   46,   20,   21,   22,   23,   10,   87,   24,   25,   47,
195
   26,   48,   49,   27,   10,   28,   10,   10,   30,   37,
196
   38,   72,   68,   69,   70,   71,   74,   78,   80,   81,
197
   82,   84,   85,   88,   89,   86,   40,   77,    0,    0,
198
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
199
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
200
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
201
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
202
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
203
    0,    0,    0,    0,    0,   41,   42,   43,   44,   45,
204
   10,   10,   10,   10,   10,   46,    0,    0,    0,    0,
205
   10,    0,    0,    0,   47,    0,   48,   49,    0,   10,
206
    0,   10,   10,    0,    0,    0,    0,    0,    0,   15,
207
   15,    0,    0,    0,    0,    0,    0,    0,    0,    0,
208
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
209
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
210
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
211
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
212
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
213
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
214
    0,    0,    0,    0,    0,    2,    0,    0,    0,    0,
215
    0,    0,    0,    0,    0,    3,    4,    0,    0,    0,
216
    0,    0,    0,    0,    0,    0,    5,    0,    0,    0,
217
    0,    0,    0,    0,    0,    6,    7,    0,    0,    0,
218
    0,    0,    0,    8,    9,
219
};
220
const short yycheck[] =
221
	{                                      10,
222
  123,  125,   38,  265,   49,   10,  125,  295,  296,  271,
223
  272,  273,  274,  275,  276,   51,  278,  279,  292,  293,
224
  282,  283,  284,  295,  285,  296,  288,   72,  295,  291,
225
  259,  260,  261,  262,  263,  259,  260,  261,  262,  263,
226
  269,  295,  295,   61,   10,  269,   82,   10,   10,  278,
227
   10,  280,  281,  295,  278,  289,  280,  281,  295,  123,
228
   10,  259,  295,  295,  295,  295,  258,  264,  264,  295,
229
   10,  270,  295,  295,  295,  270,  123,   52,   -1,   -1,
230
   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
231
   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
232
   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
233
   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
234
   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
235
   -1,   -1,   -1,   -1,   -1,  259,  260,  261,  262,  263,
236
  259,  260,  261,  262,  263,  269,   -1,   -1,   -1,   -1,
237
  269,   -1,   -1,   -1,  278,   -1,  280,  281,   -1,  278,
238
   -1,  280,  281,   -1,   -1,   -1,   -1,   -1,   -1,  292,
239
  293,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
240
   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
241
   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
242
   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
243
   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
244
   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
245
   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
246
   -1,   -1,   -1,   -1,   -1,  256,   -1,   -1,   -1,   -1,
247
   -1,   -1,   -1,   -1,   -1,  266,  267,   -1,   -1,   -1,
248
   -1,   -1,   -1,   -1,   -1,   -1,  277,   -1,   -1,   -1,
249
   -1,   -1,   -1,   -1,   -1,  286,  287,   -1,   -1,   -1,
250
   -1,   -1,   -1,  294,  295,
251
};
252
#define YYFINAL 1
253
#ifndef YYDEBUG
254
#define YYDEBUG 0
255
#endif
256
#define YYMAXTOKEN 296
257
#if YYDEBUG
258
const char * const yyname[] =
259
	{
260
"end-of-file",0,0,0,0,0,0,0,0,0,"'\\n'",0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
261
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,"'='",0,0,0,0,0,0,0,
262
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
263
0,0,0,0,0,0,0,0,0,0,0,0,0,0,"'{'",0,"'}'",0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
264
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
265
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
266
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,"SERVER",
267
"FILTER","ATTRIBUTE","BASEDN","BINDDN","GROUPDN","BINDCRED","MAPS","CHANGE",
268
"DOMAIN","PROVIDE","USER","GROUP","TO","EXPIRE","HOME","SHELL","GECOS","UID",
269
"GID","INTERVAL","PASSWD","NAME","FIXED","LIST","GROUPNAME","GROUPPASSWD",
270
"GROUPGID","MAP","INCLUDE","DIRECTORY","CLASS","PORT","ERROR","GROUPMEMBERS",
271
"LDAPS","TLS","CAFILE","STRING","NUMBER",
272
};
273
const char * const yyrule[] =
274
	{"$accept : grammar",
275
"grammar :",
276
"grammar : grammar '\\n'",
277
"grammar : grammar include '\\n'",
278
"grammar : grammar varset '\\n'",
279
"grammar : grammar directory '\\n'",
280
"grammar : grammar main '\\n'",
281
"grammar : grammar error '\\n'",
282
"nl : '\\n' optnl",
283
"optnl : '\\n' optnl",
284
"optnl :",
285
"include : INCLUDE STRING",
286
"varset : STRING '=' STRING",
287
"port : PORT STRING",
288
"port : PORT NUMBER",
289
"port :",
290
"opcode : GROUP",
291
"opcode : PASSWD",
292
"attribute : NAME",
293
"attribute : PASSWD",
294
"attribute : UID",
295
"attribute : GID",
296
"attribute : CLASS",
297
"attribute : CHANGE",
298
"attribute : EXPIRE",
299
"attribute : GECOS",
300
"attribute : HOME",
301
"attribute : SHELL",
302
"attribute : GROUPNAME",
303
"attribute : GROUPPASSWD",
304
"attribute : GROUPGID",
305
"attribute : GROUPMEMBERS",
306
"diropt : BINDDN STRING",
307
"diropt : BINDCRED STRING",
308
"diropt : BASEDN STRING",
309
"diropt : GROUPDN STRING",
310
"diropt : opcode FILTER STRING",
311
"diropt : ATTRIBUTE attribute MAPS TO STRING",
312
"diropt : FIXED ATTRIBUTE attribute STRING",
313
"diropt : LIST attribute MAPS TO STRING",
314
"ssl :",
315
"ssl : LDAPS",
316
"ssl : TLS",
317
"$$1 :",
318
"directory : DIRECTORY STRING port ssl $$1 '{' optnl diropts '}'",
319
"main : INTERVAL NUMBER",
320
"main : DOMAIN STRING",
321
"main : PROVIDE MAP STRING",
322
"main : CAFILE STRING",
323
"diropts : diropts diropt nl",
324
"diropts : diropt optnl",
325
};
326
#endif
327
#ifdef YYSTACKSIZE
328
#undef YYMAXDEPTH
329
#define YYMAXDEPTH YYSTACKSIZE
330
#else
331
#ifdef YYMAXDEPTH
332
#define YYSTACKSIZE YYMAXDEPTH
333
#else
334
#define YYSTACKSIZE 10000
335
#define YYMAXDEPTH 10000
336
#endif
337
#endif
338
#define YYINITSTACKSIZE 200
339
/* LINTUSED */
340
int yydebug;
341
int yynerrs;
342
int yyerrflag;
343
int yychar;
344
short *yyssp;
345
YYSTYPE *yyvsp;
346
YYSTYPE yyval;
347
YYSTYPE yylval;
348
short *yyss;
349
short *yysslim;
350
YYSTYPE *yyvs;
351
unsigned int yystacksize;
352
int yyparse(void);
353
#line 410 "parse.y"
354
355
struct keywords {
356
	const char	*k_name;
357
	int		 k_val;
358
};
359
360
int
361
yyerror(const char *fmt, ...)
362
{
363
	va_list		 ap;
364
	char		*msg;
365
366
	file->errors++;
367
	va_start(ap, fmt);
368
	if (vasprintf(&msg, fmt, ap) == -1)
369
		fatalx("yyerror vasprintf");
370
	va_end(ap);
371
	logit(LOG_CRIT, "%s:%d: %s", file->name, yylval.lineno, msg);
372
	free(msg);
373
	return (0);
374
}
375
376
int
377
kw_cmp(const void *k, const void *e)
378
{
379
	return (strcmp(k, ((const struct keywords *)e)->k_name));
380
}
381
382
int
383
lookup(char *s)
384
{
385
	/* this has to be sorted always */
386
	static const struct keywords keywords[] = {
387
		{ "attribute",		ATTRIBUTE },
388
		{ "basedn",		BASEDN },
389
		{ "bindcred",		BINDCRED },
390
		{ "binddn",		BINDDN },
391
		{ "cafile",		CAFILE },
392
		{ "change",		CHANGE },
393
		{ "class",		CLASS },
394
		{ "directory",		DIRECTORY },
395
		{ "domain",		DOMAIN },
396
		{ "expire",		EXPIRE },
397
		{ "filter",		FILTER },
398
		{ "fixed",		FIXED },
399
		{ "gecos",		GECOS },
400
		{ "gid",		GID },
401
		{ "group",		GROUP },
402
		{ "groupdn",		GROUPDN },
403
		{ "groupgid",		GROUPGID },
404
		{ "groupmembers",	GROUPMEMBERS },
405
		{ "groupname",		GROUPNAME },
406
		{ "grouppasswd",	GROUPPASSWD },
407
		{ "home",		HOME },
408
		{ "include",		INCLUDE },
409
		{ "interval",		INTERVAL },
410
		{ "ldaps",		LDAPS },
411
		{ "list",		LIST },
412
		{ "map",		MAP },
413
		{ "maps",		MAPS },
414
		{ "name",		NAME },
415
		{ "passwd",		PASSWD },
416
		{ "port",		PORT },
417
		{ "provide",		PROVIDE },
418
		{ "server",		SERVER },
419
		{ "shell",		SHELL },
420
		{ "tls",		TLS },
421
		{ "to",			TO },
422
		{ "uid",		UID },
423
		{ "user",		USER },
424
	};
425
	const struct keywords	*p;
426
427
	p = bsearch(s, keywords, sizeof(keywords)/sizeof(keywords[0]),
428
	    sizeof(keywords[0]), kw_cmp);
429
430
	if (p)
431
		return (p->k_val);
432
	else
433
		return (STRING);
434
}
435
436
#define MAXPUSHBACK	128
437
438
u_char	*parsebuf;
439
int	 parseindex;
440
u_char	 pushback_buffer[MAXPUSHBACK];
441
int	 pushback_index = 0;
442
443
int
444
lgetc(int quotec)
445
{
446
	int		c, next;
447
448
	if (parsebuf) {
449
		/* Read character from the parsebuffer instead of input. */
450
		if (parseindex >= 0) {
451
			c = parsebuf[parseindex++];
452
			if (c != '\0')
453
				return (c);
454
			parsebuf = NULL;
455
		} else
456
			parseindex++;
457
	}
458
459
	if (pushback_index)
460
		return (pushback_buffer[--pushback_index]);
461
462
	if (quotec) {
463
		if ((c = getc(file->stream)) == EOF) {
464
			yyerror("reached end of file while parsing "
465
			    "quoted string");
466
			if (file == topfile || popfile() == EOF)
467
				return (EOF);
468
			return (quotec);
469
		}
470
		return (c);
471
	}
472
473
	while ((c = getc(file->stream)) == '\\') {
474
		next = getc(file->stream);
475
		if (next != '\n') {
476
			c = next;
477
			break;
478
		}
479
		yylval.lineno = file->lineno;
480
		file->lineno++;
481
	}
482
483
	while (c == EOF) {
484
		if (file == topfile || popfile() == EOF)
485
			return (EOF);
486
		c = getc(file->stream);
487
	}
488
	return (c);
489
}
490
491
int
492
lungetc(int c)
493
{
494
	if (c == EOF)
495
		return (EOF);
496
	if (parsebuf) {
497
		parseindex--;
498
		if (parseindex >= 0)
499
			return (c);
500
	}
501
	if (pushback_index < MAXPUSHBACK-1)
502
		return (pushback_buffer[pushback_index++] = c);
503
	else
504
		return (EOF);
505
}
506
507
int
508
findeol(void)
509
{
510
	int	c;
511
512
	parsebuf = NULL;
513
514
	/* skip to either EOF or the first real EOL */
515
	while (1) {
516
		if (pushback_index)
517
			c = pushback_buffer[--pushback_index];
518
		else
519
			c = lgetc(0);
520
		if (c == '\n') {
521
			file->lineno++;
522
			break;
523
		}
524
		if (c == EOF)
525
			break;
526
	}
527
	return (ERROR);
528
}
529
530
int
531
yylex(void)
532
{
533
	u_char	 buf[8096];
534
	u_char	*p, *val;
535
	int	 quotec, next, c;
536
	int	 token;
537
538
top:
539
	p = buf;
540
	while ((c = lgetc(0)) == ' ' || c == '\t')
541
		; /* nothing */
542
543
	yylval.lineno = file->lineno;
544
	if (c == '#')
545
		while ((c = lgetc(0)) != '\n' && c != EOF)
546
			; /* nothing */
547
	if (c == '$' && parsebuf == NULL) {
548
		while (1) {
549
			if ((c = lgetc(0)) == EOF)
550
				return (0);
551
552
			if (p + 1 >= buf + sizeof(buf) - 1) {
553
				yyerror("string too long");
554
				return (findeol());
555
			}
556
			if (isalnum(c) || c == '_') {
557
				*p++ = c;
558
				continue;
559
			}
560
			*p = '\0';
561
			lungetc(c);
562
			break;
563
		}
564
		val = symget(buf);
565
		if (val == NULL) {
566
			yyerror("macro '%s' not defined", buf);
567
			return (findeol());
568
		}
569
		parsebuf = val;
570
		parseindex = 0;
571
		goto top;
572
	}
573
574
	switch (c) {
575
	case '\'':
576
	case '"':
577
		quotec = c;
578
		while (1) {
579
			if ((c = lgetc(quotec)) == EOF)
580
				return (0);
581
			if (c == '\n') {
582
				file->lineno++;
583
				continue;
584
			} else if (c == '\\') {
585
				if ((next = lgetc(quotec)) == EOF)
586
					return (0);
587
				if (next == quotec || c == ' ' || c == '\t')
588
					c = next;
589
				else if (next == '\n') {
590
					file->lineno++;
591
					continue;
592
				} else
593
					lungetc(next);
594
			} else if (c == quotec) {
595
				*p = '\0';
596
				break;
597
			} else if (c == '\0') {
598
				yyerror("syntax error");
599
				return (findeol());
600
			}
601
			if (p + 1 >= buf + sizeof(buf) - 1) {
602
				yyerror("string too long");
603
				return (findeol());
604
			}
605
			*p++ = c;
606
		}
607
		yylval.v.string = strdup(buf);
608
		if (yylval.v.string == NULL)
609
			err(1, "yylex: strdup");
610
		return (STRING);
611
	}
612
613
#define allowed_to_end_number(x) \
614
	(isspace(x) || x == ')' || x ==',' || x == '/' || x == '}' || x == '=')
615
616
	if (c == '-' || isdigit(c)) {
617
		do {
618
			*p++ = c;
619
			if ((unsigned)(p-buf) >= sizeof(buf)) {
620
				yyerror("string too long");
621
				return (findeol());
622
			}
623
		} while ((c = lgetc(0)) != EOF && isdigit(c));
624
		lungetc(c);
625
		if (p == buf + 1 && buf[0] == '-')
626
			goto nodigits;
627
		if (c == EOF || allowed_to_end_number(c)) {
628
			const char *errstr = NULL;
629
630
			*p = '\0';
631
			yylval.v.number = strtonum(buf, LLONG_MIN,
632
			    LLONG_MAX, &errstr);
633
			if (errstr) {
634
				yyerror("\"%s\" invalid number: %s",
635
				    buf, errstr);
636
				return (findeol());
637
			}
638
			return (NUMBER);
639
		} else {
640
nodigits:
641
			while (p > buf + 1)
642
				lungetc(*--p);
643
			c = *--p;
644
			if (c == '-')
645
				return (c);
646
		}
647
	}
648
649
#define allowed_in_string(x) \
650
	(isalnum(x) || (ispunct(x) && x != '(' && x != ')' && \
651
	x != '{' && x != '}' && x != '<' && x != '>' && \
652
	x != '!' && x != '=' && x != '#' && \
653
	x != ','))
654
655
	if (isalnum(c) || c == ':' || c == '_') {
656
		do {
657
			*p++ = c;
658
			if ((unsigned)(p-buf) >= sizeof(buf)) {
659
				yyerror("string too long");
660
				return (findeol());
661
			}
662
		} while ((c = lgetc(0)) != EOF && (allowed_in_string(c)));
663
		lungetc(c);
664
		*p = '\0';
665
		if ((token = lookup(buf)) == STRING)
666
			if ((yylval.v.string = strdup(buf)) == NULL)
667
				err(1, "yylex: strdup");
668
		return (token);
669
	}
670
	if (c == '\n') {
671
		yylval.lineno = file->lineno;
672
		file->lineno++;
673
	}
674
	if (c == EOF)
675
		return (0);
676
	return (c);
677
}
678
679
int
680
check_file_secrecy(int fd, const char *fname)
681
{
682
	struct stat	st;
683
684
	if (fstat(fd, &st)) {
685
		log_warn("cannot stat %s", fname);
686
		return (-1);
687
	}
688
	if (st.st_uid != 0 && st.st_uid != getuid()) {
689
		log_warnx("%s: owner not root or current user", fname);
690
		return (-1);
691
	}
692
	if (st.st_mode & (S_IWGRP | S_IXGRP | S_IRWXO)) {
693
		log_warnx("%s: group writable or world read/writable", fname);
694
		return (-1);
695
	}
696
	return (0);
697
}
698
699
struct file *
700
pushfile(const char *name, int secret)
701
{
702
	struct file	*nfile;
703
704
	if ((nfile = calloc(1, sizeof(struct file))) == NULL) {
705
		log_warn("malloc");
706
		return (NULL);
707
	}
708
	if ((nfile->name = strdup(name)) == NULL) {
709
		log_warn("malloc");
710
		free(nfile);
711
		return (NULL);
712
	}
713
	if ((nfile->stream = fopen(nfile->name, "r")) == NULL) {
714
		log_warn("%s", nfile->name);
715
		free(nfile->name);
716
		free(nfile);
717
		return (NULL);
718
	} else if (secret &&
719
	    check_file_secrecy(fileno(nfile->stream), nfile->name)) {
720
		fclose(nfile->stream);
721
		free(nfile->name);
722
		free(nfile);
723
		return (NULL);
724
	}
725
	nfile->lineno = 1;
726
	TAILQ_INSERT_TAIL(&files, nfile, entry);
727
	return (nfile);
728
}
729
730
int
731
popfile(void)
732
{
733
	struct file	*prev;
734
735
	if ((prev = TAILQ_PREV(file, files, entry)) != NULL)
736
		prev->errors += file->errors;
737
738
	TAILQ_REMOVE(&files, file, entry);
739
	fclose(file->stream);
740
	free(file->name);
741
	free(file);
742
	file = prev;
743
	return (file ? 0 : EOF);
744
}
745
746
int
747
parse_config(struct env *x_conf, const char *filename, int opts)
748
{
749
	struct sym	*sym, *next;
750
751
	conf = x_conf;
752
	bzero(conf, sizeof(*conf));
753
754
	TAILQ_INIT(&conf->sc_idms);
755
	conf->sc_conf_tv.tv_sec = DEFAULT_INTERVAL;
756
	conf->sc_conf_tv.tv_usec = 0;
757
	conf->sc_cafile = strdup(YPLDAP_CERT_FILE);
758
	if (conf->sc_cafile == NULL) {
759
		log_warn("malloc");
760
		return (-1);
761
	}
762
763
	errors = 0;
764
765
	if ((file = pushfile(filename, 1)) == NULL) {
766
		return (-1);
767
	}
768
	topfile = file;
769
770
	/*
771
	 * parse configuration
772
	 */
773
	setservent(1);
774
	yyparse();
775
	endservent();
776
	errors = file->errors;
777
	popfile();
778
779
	/* Free macros and check which have not been used. */
780
	TAILQ_FOREACH_SAFE(sym, &symhead, entry, next) {
781
		if ((opts & YPLDAP_OPT_VERBOSE) && !sym->used)
782
			fprintf(stderr, "warning: macro '%s' not "
783
			    "used\n", sym->nam);
784
		if (!sym->persist) {
785
			free(sym->nam);
786
			free(sym->val);
787
			TAILQ_REMOVE(&symhead, sym, entry);
788
			free(sym);
789
		}
790
	}
791
792
	if (errors) {
793
		return (-1);
794
	}
795
796
	return (0);
797
}
798
799
int
800
symset(const char *nam, const char *val, int persist)
801
{
802
	struct sym	*sym;
803
804
	TAILQ_FOREACH(sym, &symhead, entry) {
805
		if (strcmp(nam, sym->nam) == 0)
806
			break;
807
	}
808
809
	if (sym != NULL) {
810
		if (sym->persist == 1)
811
			return (0);
812
		else {
813
			free(sym->nam);
814
			free(sym->val);
815
			TAILQ_REMOVE(&symhead, sym, entry);
816
			free(sym);
817
		}
818
	}
819
	if ((sym = calloc(1, sizeof(*sym))) == NULL)
820
		return (-1);
821
822
	sym->nam = strdup(nam);
823
	if (sym->nam == NULL) {
824
		free(sym);
825
		return (-1);
826
	}
827
	sym->val = strdup(val);
828
	if (sym->val == NULL) {
829
		free(sym->nam);
830
		free(sym);
831
		return (-1);
832
	}
833
	sym->used = 0;
834
	sym->persist = persist;
835
	TAILQ_INSERT_TAIL(&symhead, sym, entry);
836
	return (0);
837
}
838
839
int
840
cmdline_symset(char *s)
841
{
842
	char	*sym, *val;
843
	int	ret;
844
	size_t	len;
845
846
	if ((val = strrchr(s, '=')) == NULL)
847
		return (-1);
848
849
	len = strlen(s) - strlen(val) + 1;
850
	if ((sym = malloc(len)) == NULL)
851
		errx(1, "cmdline_symset: malloc");
852
853
	(void)strlcpy(sym, s, len);
854
855
	ret = symset(sym, val + 1, 1);
856
	free(sym);
857
858
	return (ret);
859
}
860
861
char *
862
symget(const char *nam)
863
{
864
	struct sym	*sym;
865
866
	TAILQ_FOREACH(sym, &symhead, entry) {
867
		if (strcmp(nam, sym->nam) == 0) {
868
			sym->used = 1;
869
			return (sym->val);
870
		}
871
	}
872
	return (NULL);
873
}
874
#line 867 "parse.c"
875
/* allocate initial stack or double stack size, up to YYMAXDEPTH */
876
static int yygrowstack(void)
877
{
878
    unsigned int newsize;
879
    long sslen;
880
    short *newss;
881
    YYSTYPE *newvs;
882
883
    if ((newsize = yystacksize) == 0)
884
        newsize = YYINITSTACKSIZE;
885
    else if (newsize >= YYMAXDEPTH)
886
        return -1;
887
    else if ((newsize *= 2) > YYMAXDEPTH)
888
        newsize = YYMAXDEPTH;
889
    sslen = yyssp - yyss;
890
#ifdef SIZE_MAX
891
#define YY_SIZE_MAX SIZE_MAX
892
#else
893
#define YY_SIZE_MAX 0xffffffffU
894
#endif
895
    if (newsize && YY_SIZE_MAX / newsize < sizeof *newss)
896
        goto bail;
897
    newss = yyss ? (short *)realloc(yyss, newsize * sizeof *newss) :
898
      (short *)malloc(newsize * sizeof *newss); /* overflow check above */
899
    if (newss == NULL)
900
        goto bail;
901
    yyss = newss;
902
    yyssp = newss + sslen;
903
    if (newsize && YY_SIZE_MAX / newsize < sizeof *newvs)
904
        goto bail;
905
    newvs = yyvs ? (YYSTYPE *)realloc(yyvs, newsize * sizeof *newvs) :
906
      (YYSTYPE *)malloc(newsize * sizeof *newvs); /* overflow check above */
907
    if (newvs == NULL)
908
        goto bail;
909
    yyvs = newvs;
910
    yyvsp = newvs + sslen;
911
    yystacksize = newsize;
912
    yysslim = yyss + newsize - 1;
913
    return 0;
914
bail:
915
    if (yyss)
916
            free(yyss);
917
    if (yyvs)
918
            free(yyvs);
919
    yyss = yyssp = NULL;
920
    yyvs = yyvsp = NULL;
921
    yystacksize = 0;
922
    return -1;
923
}
924
925
#define YYABORT goto yyabort
926
#define YYREJECT goto yyabort
927
#define YYACCEPT goto yyaccept
928
#define YYERROR goto yyerrlab
929
int
930
yyparse(void)
931
{
932
    int yym, yyn, yystate;
933
#if YYDEBUG
934
    const char *yys;
935
936
    if ((yys = getenv("YYDEBUG")))
937
    {
938
        yyn = *yys;
939
        if (yyn >= '0' && yyn <= '9')
940
            yydebug = yyn - '0';
941
    }
942
#endif /* YYDEBUG */
943
944
    yynerrs = 0;
945
    yyerrflag = 0;
946
    yychar = (-1);
947
948
    if (yyss == NULL && yygrowstack()) goto yyoverflow;
949
    yyssp = yyss;
950
    yyvsp = yyvs;
951
    *yyssp = yystate = 0;
952
953
yyloop:
954
    if ((yyn = yydefred[yystate]) != 0) goto yyreduce;
955
    if (yychar < 0)
956
    {
957
        if ((yychar = yylex()) < 0) yychar = 0;
958
#if YYDEBUG
959
        if (yydebug)
960
        {
961
            yys = 0;
962
            if (yychar <= YYMAXTOKEN) yys = yyname[yychar];
963
            if (!yys) yys = "illegal-symbol";
964
            printf("%sdebug: state %d, reading %d (%s)\n",
965
                    YYPREFIX, yystate, yychar, yys);
966
        }
967
#endif
968
    }
969
    if ((yyn = yysindex[yystate]) && (yyn += yychar) >= 0 &&
970
            yyn <= YYTABLESIZE && yycheck[yyn] == yychar)
971
    {
972
#if YYDEBUG
973
        if (yydebug)
974
            printf("%sdebug: state %d, shifting to state %d\n",
975
                    YYPREFIX, yystate, yytable[yyn]);
976
#endif
977
        if (yyssp >= yysslim && yygrowstack())
978
        {
979
            goto yyoverflow;
980
        }
981
        *++yyssp = yystate = yytable[yyn];
982
        *++yyvsp = yylval;
983
        yychar = (-1);
984
        if (yyerrflag > 0)  --yyerrflag;
985
        goto yyloop;
986
    }
987
    if ((yyn = yyrindex[yystate]) && (yyn += yychar) >= 0 &&
988
            yyn <= YYTABLESIZE && yycheck[yyn] == yychar)
989
    {
990
        yyn = yytable[yyn];
991
        goto yyreduce;
992
    }
993
    if (yyerrflag) goto yyinrecovery;
994
#if defined(__GNUC__)
995
    goto yynewerror;
996
#endif
997
yynewerror:
998
    yyerror("syntax error");
999
#if defined(__GNUC__)
1000
    goto yyerrlab;
1001
#endif
1002
yyerrlab:
1003
    ++yynerrs;
1004
yyinrecovery:
1005
    if (yyerrflag < 3)
1006
    {
1007
        yyerrflag = 3;
1008
        for (;;)
1009
        {
1010
            if ((yyn = yysindex[*yyssp]) && (yyn += YYERRCODE) >= 0 &&
1011
                    yyn <= YYTABLESIZE && yycheck[yyn] == YYERRCODE)
1012
            {
1013
#if YYDEBUG
1014
                if (yydebug)
1015
                    printf("%sdebug: state %d, error recovery shifting\
1016
 to state %d\n", YYPREFIX, *yyssp, yytable[yyn]);
1017
#endif
1018
                if (yyssp >= yysslim && yygrowstack())
1019
                {
1020
                    goto yyoverflow;
1021
                }
1022
                *++yyssp = yystate = yytable[yyn];
1023
                *++yyvsp = yylval;
1024
                goto yyloop;
1025
            }
1026
            else
1027
            {
1028
#if YYDEBUG
1029
                if (yydebug)
1030
                    printf("%sdebug: error recovery discarding state %d\n",
1031
                            YYPREFIX, *yyssp);
1032
#endif
1033
                if (yyssp <= yyss) goto yyabort;
1034
                --yyssp;
1035
                --yyvsp;
1036
            }
1037
        }
1038
    }
1039
    else
1040
    {
1041
        if (yychar == 0) goto yyabort;
1042
#if YYDEBUG
1043
        if (yydebug)
1044
        {
1045
            yys = 0;
1046
            if (yychar <= YYMAXTOKEN) yys = yyname[yychar];
1047
            if (!yys) yys = "illegal-symbol";
1048
            printf("%sdebug: state %d, error recovery discards token %d (%s)\n",
1049
                    YYPREFIX, yystate, yychar, yys);
1050
        }
1051
#endif
1052
        yychar = (-1);
1053
        goto yyloop;
1054
    }
1055
yyreduce:
1056
#if YYDEBUG
1057
    if (yydebug)
1058
        printf("%sdebug: state %d, reducing by rule %d (%s)\n",
1059
                YYPREFIX, yystate, yyn, yyrule[yyn]);
1060
#endif
1061
    yym = yylen[yyn];
1062
    if (yym)
1063
        yyval = yyvsp[1-yym];
1064
    else
1065
        memset(&yyval, 0, sizeof yyval);
1066
    switch (yyn)
1067
    {
1068
case 7:
1069
#line 119 "parse.y"
1070
{ file->errors++; }
1071
break;
1072
case 11:
1073
#line 130 "parse.y"
1074
{
1075
			struct file	*nfile;
1076
1077
			if ((nfile = pushfile(yyvsp[0].v.string, 0)) == NULL) {
1078
				yyerror("failed to include file %s", yyvsp[0].v.string);
1079
				free(yyvsp[0].v.string);
1080
				YYERROR;
1081
			}
1082
			free(yyvsp[0].v.string);
1083
1084
			file = nfile;
1085
			lungetc('\n');
1086
		}
1087
break;
1088
case 12:
1089
#line 145 "parse.y"
1090
{
1091
			char *s = yyvsp[-2].v.string;
1092
			while (*s++) {
1093
				if (isspace((unsigned char)*s)) {
1094
					yyerror("macro name cannot contain "
1095
					    "whitespace");
1096
					YYERROR;
1097
				}
1098
			}
1099
			if (symset(yyvsp[-2].v.string, yyvsp[0].v.string, 0) == -1)
1100
				fatal("cannot store variable");
1101
			free(yyvsp[-2].v.string);
1102
			free(yyvsp[0].v.string);
1103
		}
1104
break;
1105
case 13:
1106
#line 161 "parse.y"
1107
{
1108
			struct servent *servent;
1109
1110
			servent = getservbyname(yyvsp[0].v.string, "tcp");
1111
			if (servent == NULL) {
1112
				yyerror("port %s is invalid", yyvsp[0].v.string);
1113
				free(yyvsp[0].v.string);
1114
				YYERROR;
1115
			}
1116
			yyval.v.number = ntohs(servent->s_port);
1117
			free(yyvsp[0].v.string);
1118
		}
1119
break;
1120
case 14:
1121
#line 173 "parse.y"
1122
{
1123
			if (yyvsp[0].v.number <= 0 || yyvsp[0].v.number > (int)USHRT_MAX) {
1124
				yyerror("invalid port: %lld", yyvsp[0].v.number);
1125
				YYERROR;
1126
			}
1127
			yyval.v.number = yyvsp[0].v.number;
1128
		}
1129
break;
1130
case 15:
1131
#line 180 "parse.y"
1132
{
1133
			yyval.v.number = 0;
1134
		}
1135
break;
1136
case 16:
1137
#line 185 "parse.y"
1138
{ yyval.v.number = 0; }
1139
break;
1140
case 17:
1141
#line 186 "parse.y"
1142
{ yyval.v.number = 1; }
1143
break;
1144
case 18:
1145
#line 190 "parse.y"
1146
{ yyval.v.number = 0; }
1147
break;
1148
case 19:
1149
#line 191 "parse.y"
1150
{ yyval.v.number = 1; }
1151
break;
1152
case 20:
1153
#line 192 "parse.y"
1154
{ yyval.v.number = 2; }
1155
break;
1156
case 21:
1157
#line 193 "parse.y"
1158
{ yyval.v.number = 3; }
1159
break;
1160
case 22:
1161
#line 194 "parse.y"
1162
{ yyval.v.number = 4; }
1163
break;
1164
case 23:
1165
#line 195 "parse.y"
1166
{ yyval.v.number = 5; }
1167
break;
1168
case 24:
1169
#line 196 "parse.y"
1170
{ yyval.v.number = 6; }
1171
break;
1172
case 25:
1173
#line 197 "parse.y"
1174
{ yyval.v.number = 7; }
1175
break;
1176
case 26:
1177
#line 198 "parse.y"
1178
{ yyval.v.number = 8; }
1179
break;
1180
case 27:
1181
#line 199 "parse.y"
1182
{ yyval.v.number = 9; }
1183
break;
1184
case 28:
1185
#line 200 "parse.y"
1186
{ yyval.v.number = 10; }
1187
break;
1188
case 29:
1189
#line 201 "parse.y"
1190
{ yyval.v.number = 11; }
1191
break;
1192
case 30:
1193
#line 202 "parse.y"
1194
{ yyval.v.number = 12; }
1195
break;
1196
case 31:
1197
#line 203 "parse.y"
1198
{ yyval.v.number = 13; }
1199
break;
1200
case 32:
1201
#line 206 "parse.y"
1202
{
1203
			idm->idm_flags |= F_NEEDAUTH;
1204
			if (strlcpy(idm->idm_binddn, yyvsp[0].v.string,
1205
			    sizeof(idm->idm_binddn)) >=
1206
			    sizeof(idm->idm_binddn)) {
1207
				yyerror("directory binddn truncated");
1208
				free(yyvsp[0].v.string);
1209
				YYERROR;
1210
			}
1211
			free(yyvsp[0].v.string);
1212
		}
1213
break;
1214
case 33:
1215
#line 217 "parse.y"
1216
{
1217
			idm->idm_flags |= F_NEEDAUTH;
1218
			if (strlcpy(idm->idm_bindcred, yyvsp[0].v.string,
1219
			    sizeof(idm->idm_bindcred)) >=
1220
			    sizeof(idm->idm_bindcred)) {
1221
				yyerror("directory bindcred truncated");
1222
				free(yyvsp[0].v.string);
1223
				YYERROR;
1224
			}
1225
			free(yyvsp[0].v.string);
1226
		}
1227
break;
1228
case 34:
1229
#line 228 "parse.y"
1230
{
1231
			if (strlcpy(idm->idm_basedn, yyvsp[0].v.string,
1232
			    sizeof(idm->idm_basedn)) >=
1233
			    sizeof(idm->idm_basedn)) {
1234
				yyerror("directory basedn truncated");
1235
				free(yyvsp[0].v.string);
1236
				YYERROR;
1237
			}
1238
			free(yyvsp[0].v.string);
1239
		}
1240
break;
1241
case 35:
1242
#line 238 "parse.y"
1243
{
1244
			if(strlcpy(idm->idm_groupdn, yyvsp[0].v.string,
1245
			    sizeof(idm->idm_groupdn)) >=
1246
			    sizeof(idm->idm_groupdn)) {
1247
				yyerror("directory groupdn truncated");
1248
				free(yyvsp[0].v.string);
1249
				YYERROR;
1250
			}
1251
			free(yyvsp[0].v.string);
1252
		}
1253
break;
1254
case 36:
1255
#line 248 "parse.y"
1256
{
1257
			if (strlcpy(idm->idm_filters[yyvsp[-2].v.number], yyvsp[0].v.string,
1258
			    sizeof(idm->idm_filters[yyvsp[-2].v.number])) >=
1259
			    sizeof(idm->idm_filters[yyvsp[-2].v.number])) {
1260
				yyerror("filter truncated");
1261
				free(yyvsp[0].v.string);
1262
				YYERROR;
1263
			}
1264
			free(yyvsp[0].v.string);
1265
		}
1266
break;
1267
case 37:
1268
#line 258 "parse.y"
1269
{
1270
			if (strlcpy(idm->idm_attrs[yyvsp[-3].v.number], yyvsp[0].v.string,
1271
			    sizeof(idm->idm_attrs[yyvsp[-3].v.number])) >=
1272
			    sizeof(idm->idm_attrs[yyvsp[-3].v.number])) {
1273
				yyerror("attribute truncated");
1274
				free(yyvsp[0].v.string);
1275
				YYERROR;
1276
			}
1277
			free(yyvsp[0].v.string);
1278
		}
1279
break;
1280
case 38:
1281
#line 268 "parse.y"
1282
{
1283
			if (strlcpy(idm->idm_attrs[yyvsp[-1].v.number], yyvsp[0].v.string,
1284
			    sizeof(idm->idm_attrs[yyvsp[-1].v.number])) >=
1285
			    sizeof(idm->idm_attrs[yyvsp[-1].v.number])) {
1286
				yyerror("attribute truncated");
1287
				free(yyvsp[0].v.string);
1288
				YYERROR;
1289
			}
1290
			idm->idm_flags |= F_FIXED_ATTR(yyvsp[-1].v.number);
1291
			free(yyvsp[0].v.string);
1292
		}
1293
break;
1294
case 39:
1295
#line 279 "parse.y"
1296
{
1297
			if (strlcpy(idm->idm_attrs[yyvsp[-3].v.number], yyvsp[0].v.string,
1298
			    sizeof(idm->idm_attrs[yyvsp[-3].v.number])) >=
1299
			    sizeof(idm->idm_attrs[yyvsp[-3].v.number])) {
1300
				yyerror("attribute truncated");
1301
				free(yyvsp[0].v.string);
1302
				YYERROR;
1303
			}
1304
			idm->idm_list |= F_LIST(yyvsp[-3].v.number);
1305
			free(yyvsp[0].v.string);
1306
		}
1307
break;
1308
case 40:
1309
#line 292 "parse.y"
1310
{ yyval.v.number = 0; }
1311
break;
1312
case 41:
1313
#line 293 "parse.y"
1314
{ yyval.v.number = F_SSL; }
1315
break;
1316
case 42:
1317
#line 294 "parse.y"
1318
{ yyval.v.number = F_STARTTLS; }
1319
break;
1320
case 43:
1321
#line 297 "parse.y"
1322
{
1323
			if ((idm = calloc(1, sizeof(*idm))) == NULL)
1324
				fatal(NULL);
1325
			idm->idm_id = conf->sc_maxid++;
1326
1327
			if (strlcpy(idm->idm_name, yyvsp[-2].v.string,
1328
			    sizeof(idm->idm_name)) >=
1329
			    sizeof(idm->idm_name)) {
1330
				yyerror("attribute truncated");
1331
				free(yyvsp[-2].v.string);
1332
				YYERROR;
1333
			}
1334
			free(yyvsp[-2].v.string);
1335
1336
			idm->idm_port = yyvsp[-1].v.number;
1337
1338
			if (yyvsp[0].v.number != 0) {
1339
				if (tls_init()) {
1340
					yyerror("tls init failed");
1341
					YYERROR;
1342
				}
1343
1344
				idm->idm_flags |= yyvsp[0].v.number;
1345
				idm->idm_tls_config = tls_config_new();
1346
				if (idm->idm_tls_config == NULL) {
1347
					yyerror("tls config failed");
1348
					YYERROR;
1349
				}
1350
1351
				if (tls_config_set_protocols(
1352
				    idm->idm_tls_config,
1353
				    TLS_PROTOCOLS_ALL) == -1) {
1354
					yyerror("tls set protocols failed: %s",
1355
					    tls_config_error(
1356
					    idm->idm_tls_config));
1357
					tls_config_free(idm->idm_tls_config);
1358
					idm->idm_tls_config = NULL;
1359
					YYERROR;
1360
				}
1361
				if (tls_config_set_ciphers(idm->idm_tls_config,
1362
				    "compat") == -1) {
1363
					yyerror("tls set ciphers failed: %s",
1364
					    tls_config_error(
1365
					    idm->idm_tls_config));
1366
					tls_config_free(idm->idm_tls_config);
1367
					idm->idm_tls_config = NULL;
1368
					YYERROR;
1369
				}
1370
1371
				if (tls_config_set_ca_file(idm->idm_tls_config,
1372
				    conf->sc_cafile) == -1) {
1373
					yyerror("tls set CA bundle failed: %s",
1374
					    tls_config_error(
1375
					    idm->idm_tls_config));
1376
					tls_config_free(idm->idm_tls_config);
1377
					idm->idm_tls_config = NULL;
1378
					YYERROR;
1379
				}
1380
			}
1381
1382
		}
1383
break;
1384
case 44:
1385
#line 357 "parse.y"
1386
{
1387
			TAILQ_INSERT_TAIL(&conf->sc_idms, idm, idm_entry);
1388
			idm = NULL;
1389
		}
1390
break;
1391
case 45:
1392
#line 363 "parse.y"
1393
{
1394
			conf->sc_conf_tv.tv_sec = yyvsp[0].v.number;
1395
			conf->sc_conf_tv.tv_usec = 0;
1396
		}
1397
break;
1398
case 46:
1399
#line 367 "parse.y"
1400
{
1401
			if (strlcpy(conf->sc_domainname, yyvsp[0].v.string,
1402
			    sizeof(conf->sc_domainname)) >=
1403
			    sizeof(conf->sc_domainname)) {
1404
				yyerror("domainname truncated");
1405
				free(yyvsp[0].v.string);
1406
				YYERROR;
1407
			}
1408
			free(yyvsp[0].v.string);
1409
		}
1410
break;
1411
case 47:
1412
#line 377 "parse.y"
1413
{
1414
			if (strcmp(yyvsp[0].v.string, "passwd.byname") == 0)
1415
				conf->sc_flags |= YPMAP_PASSWD_BYNAME;
1416
			else if (strcmp(yyvsp[0].v.string, "passwd.byuid") == 0)
1417
				conf->sc_flags |= YPMAP_PASSWD_BYUID;
1418
			else if (strcmp(yyvsp[0].v.string, "master.passwd.byname") == 0)
1419
				conf->sc_flags |= YPMAP_MASTER_PASSWD_BYNAME;
1420
			else if (strcmp(yyvsp[0].v.string, "master.passwd.byuid") == 0)
1421
				conf->sc_flags |= YPMAP_MASTER_PASSWD_BYUID;
1422
			else if (strcmp(yyvsp[0].v.string, "group.byname") == 0)
1423
				conf->sc_flags |= YPMAP_GROUP_BYNAME;
1424
			else if (strcmp(yyvsp[0].v.string, "group.bygid") == 0)
1425
				conf->sc_flags |= YPMAP_GROUP_BYGID;
1426
			else if (strcmp(yyvsp[0].v.string, "netid.byname") == 0)
1427
				conf->sc_flags |= YPMAP_NETID_BYNAME;
1428
			else {
1429
				yyerror("unsupported map type: %s", yyvsp[0].v.string);
1430
				free(yyvsp[0].v.string);
1431
				YYERROR;
1432
			}
1433
			free(yyvsp[0].v.string);
1434
		}
1435
break;
1436
case 48:
1437
#line 399 "parse.y"
1438
{
1439
			free(conf->sc_cafile);
1440
			conf->sc_cafile = yyvsp[0].v.string;
1441
		}
1442
break;
1443
#line 1436 "parse.c"
1444
    }
1445
    yyssp -= yym;
1446
    yystate = *yyssp;
1447
    yyvsp -= yym;
1448
    yym = yylhs[yyn];
1449
    if (yystate == 0 && yym == 0)
1450
    {
1451
#if YYDEBUG
1452
        if (yydebug)
1453
            printf("%sdebug: after reduction, shifting from state 0 to\
1454
 state %d\n", YYPREFIX, YYFINAL);
1455
#endif
1456
        yystate = YYFINAL;
1457
        *++yyssp = YYFINAL;
1458
        *++yyvsp = yyval;
1459
        if (yychar < 0)
1460
        {
1461
            if ((yychar = yylex()) < 0) yychar = 0;
1462
#if YYDEBUG
1463
            if (yydebug)
1464
            {
1465
                yys = 0;
1466
                if (yychar <= YYMAXTOKEN) yys = yyname[yychar];
1467
                if (!yys) yys = "illegal-symbol";
1468
                printf("%sdebug: state %d, reading %d (%s)\n",
1469
                        YYPREFIX, YYFINAL, yychar, yys);
1470
            }
1471
#endif
1472
        }
1473
        if (yychar == 0) goto yyaccept;
1474
        goto yyloop;
1475
    }
1476
    if ((yyn = yygindex[yym]) && (yyn += yystate) >= 0 &&
1477
            yyn <= YYTABLESIZE && yycheck[yyn] == yystate)
1478
        yystate = yytable[yyn];
1479
    else
1480
        yystate = yydgoto[yym];
1481
#if YYDEBUG
1482
    if (yydebug)
1483
        printf("%sdebug: after reduction, shifting from state %d \
1484
to state %d\n", YYPREFIX, *yyssp, yystate);
1485
#endif
1486
    if (yyssp >= yysslim && yygrowstack())
1487
    {
1488
        goto yyoverflow;
1489
    }
1490
    *++yyssp = yystate;
1491
    *++yyvsp = yyval;
1492
    goto yyloop;
1493
yyoverflow:
1494
    yyerror("yacc stack overflow");
1495
yyabort:
1496
    if (yyss)
1497
            free(yyss);
1498
    if (yyvs)
1499
            free(yyvs);
1500
    yyss = yyssp = NULL;
1501
    yyvs = yyvsp = NULL;
1502
    yystacksize = 0;
1503
    return (1);
1504
yyaccept:
1505
    if (yyss)
1506
            free(yyss);
1507
    if (yyvs)
1508
            free(yyvs);
1509
    yyss = yyssp = NULL;
1510
    yyvs = yyvsp = NULL;
1511
    yystacksize = 0;
1512
    return (0);
1513
}