GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: usr.sbin/ldapctl/parse.c Lines: 0 253 0.0 %
Date: 2017-11-07 Branches: 0 218 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 25 "/usr/src/usr.sbin/ldapctl/../ldapd/parse.y"
13
#include <sys/types.h>
14
#include <sys/queue.h>
15
#include <sys/tree.h>
16
#include <sys/socket.h>
17
#include <sys/stat.h>
18
#include <sys/un.h>
19
#include <netinet/in.h>
20
#include <arpa/inet.h>
21
22
#include <ctype.h>
23
#include <err.h>
24
#include <errno.h>
25
#include <ifaddrs.h>
26
#include <limits.h>
27
#include <netdb.h>
28
#include <stdarg.h>
29
#include <stdio.h>
30
#include <stdlib.h>
31
#include <string.h>
32
#include <syslog.h>
33
#include <unistd.h>
34
35
#include "ldapd.h"
36
#include "log.h"
37
38
TAILQ_HEAD(files, file)		 files = TAILQ_HEAD_INITIALIZER(files);
39
static struct file {
40
	TAILQ_ENTRY(file)	 entry;
41
	FILE			*stream;
42
	char			*name;
43
	int			 lineno;
44
	int			 errors;
45
} *file, *topfile;
46
struct file	*pushfile(const char *, int);
47
int		 popfile(void);
48
int		 check_file_secrecy(int, const char *);
49
int		 yyparse(void);
50
int		 yylex(void);
51
int		 yyerror(const char *, ...)
52
    __attribute__((__format__ (printf, 1, 2)))
53
    __attribute__((__nonnull__ (1)));
54
int		 kw_cmp(const void *, const void *);
55
int		 lookup(char *);
56
int		 lgetc(int);
57
int		 lungetc(int);
58
int		 findeol(void);
59
60
struct listener *host_unix(const char *path);
61
struct listener	*host_v4(const char *, in_port_t);
62
struct listener	*host_v6(const char *, in_port_t);
63
int		 host_dns(const char *, const char *,
64
		    struct listenerlist *, int, in_port_t, u_int8_t);
65
int		 host(const char *, const char *,
66
		    struct listenerlist *, int, in_port_t, u_int8_t);
67
int		 interface(const char *, const char *,
68
		    struct listenerlist *, int, in_port_t, u_int8_t);
69
int		 load_certfile(struct ldapd_config *, const char *, u_int8_t);
70
71
TAILQ_HEAD(symhead, sym)	 symhead = TAILQ_HEAD_INITIALIZER(symhead);
72
struct sym {
73
	TAILQ_ENTRY(sym)	 entry;
74
	int			 used;
75
	int			 persist;
76
	char			*nam;
77
	char			*val;
78
};
79
int		 symset(const char *, const char *, int);
80
char		*symget(const char *);
81
82
struct ldapd_config	*conf;
83
84
SPLAY_GENERATE(ssltree, ssl, ssl_nodes, ssl_cmp);
85
86
static struct aci	*mk_aci(int type, int rights, enum scope scope,
87
				char *target, char *subject);
88
89
typedef struct {
90
	union {
91
		int64_t		 number;
92
		char		*string;
93
		struct aci	*aci;
94
	} v;
95
	int lineno;
96
} YYSTYPE;
97
98
static struct namespace *current_ns = NULL;
99
100
#line 101 "parse.c"
101
#define ERROR 257
102
#define LISTEN 258
103
#define ON 259
104
#define TLS 260
105
#define LDAPS 261
106
#define PORT 262
107
#define NAMESPACE 263
108
#define ROOTDN 264
109
#define ROOTPW 265
110
#define INDEX 266
111
#define SECURE 267
112
#define RELAX 268
113
#define STRICT 269
114
#define SCHEMA 270
115
#define USE 271
116
#define COMPRESSION 272
117
#define LEVEL 273
118
#define INCLUDE 274
119
#define CERTIFICATE 275
120
#define FSYNC 276
121
#define CACHE_SIZE 277
122
#define INDEX_CACHE_SIZE 278
123
#define DENY 279
124
#define ALLOW 280
125
#define READ 281
126
#define WRITE 282
127
#define BIND 283
128
#define ACCESS 284
129
#define TO 285
130
#define ROOT 286
131
#define REFERRAL 287
132
#define ANY 288
133
#define CHILDREN 289
134
#define OF 290
135
#define ATTRIBUTE 291
136
#define IN 292
137
#define SUBTREE 293
138
#define BY 294
139
#define SELF 295
140
#define STRING 296
141
#define NUMBER 297
142
#define YYERRCODE 256
143
const short yylhs[] =
144
	{                                        -1,
145
    0,    0,    0,    0,    0,    0,    0,    0,    0,    2,
146
    2,    2,    2,   12,   12,    1,    1,    1,   16,   16,
147
   16,   16,   20,   17,    3,    3,   19,   19,   19,   21,
148
   21,   21,   21,   21,   21,   21,   21,   21,   21,   21,
149
    4,    4,   13,   13,    5,    5,    6,    6,    6,    7,
150
    7,    8,    8,    8,    9,    9,    9,   10,   10,   10,
151
   11,   11,   11,   11,   14,   15,   18,
152
};
153
const short yylen[] =
154
	{                                         2,
155
    0,    2,    3,    3,    3,    3,    3,    3,    3,    0,
156
    1,    1,    1,    0,    2,    2,    2,    0,    6,    2,
157
    2,    2,    0,    7,    1,    1,    0,    2,    3,    2,
158
    2,    2,    2,    2,    2,    1,    2,    2,    3,    2,
159
    0,    2,    6,    2,    1,    1,    0,    1,    2,    1,
160
    3,    1,    1,    1,    0,    1,    2,    1,    1,    1,
161
    0,    2,    2,    2,    2,    3,    2,
162
};
163
const short yydefred[] =
164
	{                                      1,
165
    0,    0,    0,    0,    0,    0,    0,    0,   45,   46,
166
    0,    0,    2,    0,    0,    0,    0,    0,    0,    0,
167
    6,    0,    0,   21,   22,   67,   65,   20,    0,   52,
168
   53,   54,   48,    0,    0,   50,    8,    3,    4,    5,
169
    7,    9,    0,    0,   66,    0,   49,    0,    0,    0,
170
   23,    0,   56,    0,   51,   16,   17,   11,   12,   13,
171
    0,   27,   57,   59,   58,   60,    0,    0,   19,    0,
172
    0,   43,   15,    0,    0,    0,    0,    0,    0,    0,
173
    0,    0,    0,   28,   24,   36,    0,   62,   64,   63,
174
   30,   31,   32,   37,   38,    0,   26,   25,   35,   33,
175
   34,   40,   29,    0,   39,   42,
176
};
177
const short yydgoto[] =
178
	{                                       1,
179
   50,   61,   99,  105,   14,   34,   35,   36,   54,   67,
180
   72,   69,   15,   16,   17,   18,   19,   20,   70,   62,
181
   87,
182
};
183
const short yysindex[] =
184
	{                                      0,
185
  -10,    1, -245, -276, -270, -262, -261, -260,    0,    0,
186
 -259,  -23,    0, -254,   29,   30,   32,   33,   34,   35,
187
    0, -249,  -77,    0,    0,    0,    0,    0, -247,    0,
188
    0,    0,    0, -237,  -41,    0,    0,    0,    0,    0,
189
    0,    0, -212,   41,    0, -268,    0, -250, -274, -248,
190
    0, -238,    0, -281,    0,    0,    0,    0,    0,    0,
191
 -222,    0,    0,    0,    0,    0, -240, -241,    0,   14,
192
 -279,    0,    0, -239, -236, -235, -214, -211, -210, -255,
193
 -234, -233, -231,    0,    0,    0,   48,    0,    0,    0,
194
    0,    0,    0,    0,    0, -207,    0,    0,    0,    0,
195
    0,    0,    0, -230,    0,    0,};
196
const short yyrindex[] =
197
	{                                      0,
198
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
199
    0,    0,    0,   -9,    0,    0,    0,    0,    0,    0,
200
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
201
    0,    0,    0,   58,    0,    0,    0,    0,    0,    0,
202
    0,    0,   -4,    0,    0, -278,    0,    0,    0,   -8,
203
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
204
   59,    0,    0,    0,    0,    0,   60,    0,    0,    0,
205
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
206
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
207
    0,    0,    0,    0,    0,   34,    0,    0,    0,    0,
208
    0,    0,    0,    0,    0,    0,};
209
const short yygindex[] =
210
	{                                      0,
211
    0,    0,    0,    0,    0,    0,    0,   23,    0,    0,
212
    0,    0,    2,    0,    0,    0,    0,    0,    0,    0,
213
    0,
214
};
215
#define YYTABLESIZE 301
216
const short yytable[] =
217
	{                                      13,
218
   47,   10,   48,   97,   64,   18,   65,   55,   88,   55,
219
   21,   58,   59,   22,   66,   89,   90,   55,   60,   23,
220
   52,   56,   57,   84,   53,   24,   30,   31,   32,   33,
221
   30,   31,   32,   25,   26,   27,   28,   29,   37,   38,
222
   98,   39,   40,   41,   42,   44,   43,   46,   45,   49,
223
   51,   63,   68,   71,   73,   94,   91,  103,   95,   92,
224
   93,   96,  100,  101,  102,  104,  106,   44,   14,   61,
225
   55,   86,    0,    0,    0,    0,    0,    0,    0,    0,
226
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
227
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
228
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
229
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
230
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
231
    0,    0,    0,    0,    0,    0,    0,    0,   85,    0,
232
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
233
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
234
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
235
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
236
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
237
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
238
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
239
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
240
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
241
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
242
    0,    0,   47,    0,    0,    2,    0,    3,    0,    0,
243
    0,    0,    4,    5,    6,   18,   18,    0,    0,    7,
244
    0,    0,   18,    8,    0,    0,   10,    0,    9,   10,
245
   18,    0,    0,    0,    0,   47,   11,   74,   75,   76,
246
    0,   77,   78,    0,   79,   12,    0,    0,    0,   80,
247
   81,   82,    9,   10,    0,    0,    0,    0,    0,    0,
248
   83,
249
};
250
const short yycheck[] =
251
	{                                      10,
252
   10,   10,   44,  259,  286,   10,  288,  286,  288,  288,
253
   10,  260,  261,  259,  296,  295,  296,  296,  267,  296,
254
  289,  296,  297,   10,  293,  296,  281,  282,  283,  284,
255
  281,  282,  283,  296,  296,  296,  296,   61,   10,   10,
256
  296,   10,   10,   10,   10,  123,  296,  285,  296,  262,
257
   10,  290,  275,  294,  296,  270,  296,   10,  270,  296,
258
  296,  272,  297,  297,  296,  273,  297,   10,   10,   10,
259
   48,   70,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
260
   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
261
   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
262
   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
263
   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
264
   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
265
   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,  125,   -1,
266
   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
267
   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
268
   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
269
   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
270
   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
271
   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
272
   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
273
   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
274
   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
275
   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
276
   -1,   -1,  284,   -1,   -1,  256,   -1,  258,   -1,   -1,
277
   -1,   -1,  263,  264,  265,  260,  261,   -1,   -1,  270,
278
   -1,   -1,  267,  274,   -1,   -1,  275,   -1,  279,  280,
279
  275,   -1,   -1,   -1,   -1,  285,  287,  264,  265,  266,
280
   -1,  268,  269,   -1,  271,  296,   -1,   -1,   -1,  276,
281
  277,  278,  279,  280,   -1,   -1,   -1,   -1,   -1,   -1,
282
  287,
283
};
284
#define YYFINAL 1
285
#ifndef YYDEBUG
286
#define YYDEBUG 0
287
#endif
288
#define YYMAXTOKEN 297
289
#if YYDEBUG
290
const char * const yyname[] =
291
	{
292
"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,
293
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,
294
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,
295
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,
296
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,
297
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,
298
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,"ERROR",
299
"LISTEN","ON","TLS","LDAPS","PORT","NAMESPACE","ROOTDN","ROOTPW","INDEX",
300
"SECURE","RELAX","STRICT","SCHEMA","USE","COMPRESSION","LEVEL","INCLUDE",
301
"CERTIFICATE","FSYNC","CACHE_SIZE","INDEX_CACHE_SIZE","DENY","ALLOW","READ",
302
"WRITE","BIND","ACCESS","TO","ROOT","REFERRAL","ANY","CHILDREN","OF",
303
"ATTRIBUTE","IN","SUBTREE","BY","SELF","STRING","NUMBER",
304
};
305
const char * const yyrule[] =
306
	{"$accept : grammar",
307
"grammar :",
308
"grammar : grammar '\\n'",
309
"grammar : grammar include '\\n'",
310
"grammar : grammar varset '\\n'",
311
"grammar : grammar conf_main '\\n'",
312
"grammar : grammar error '\\n'",
313
"grammar : grammar namespace '\\n'",
314
"grammar : grammar aci '\\n'",
315
"grammar : grammar schema '\\n'",
316
"ssl :",
317
"ssl : TLS",
318
"ssl : LDAPS",
319
"ssl : SECURE",
320
"certname :",
321
"certname : CERTIFICATE STRING",
322
"port : PORT STRING",
323
"port : PORT NUMBER",
324
"port :",
325
"conf_main : LISTEN ON STRING port ssl certname",
326
"conf_main : REFERRAL STRING",
327
"conf_main : ROOTDN STRING",
328
"conf_main : ROOTPW STRING",
329
"$$1 :",
330
"namespace : NAMESPACE STRING '{' '\\n' $$1 ns_opts '}'",
331
"boolean : STRING",
332
"boolean : ON",
333
"ns_opts :",
334
"ns_opts : ns_opts '\\n'",
335
"ns_opts : ns_opts ns_opt '\\n'",
336
"ns_opt : ROOTDN STRING",
337
"ns_opt : ROOTPW STRING",
338
"ns_opt : INDEX STRING",
339
"ns_opt : CACHE_SIZE NUMBER",
340
"ns_opt : INDEX_CACHE_SIZE NUMBER",
341
"ns_opt : FSYNC boolean",
342
"ns_opt : aci",
343
"ns_opt : RELAX SCHEMA",
344
"ns_opt : STRICT SCHEMA",
345
"ns_opt : USE COMPRESSION comp_level",
346
"ns_opt : REFERRAL STRING",
347
"comp_level :",
348
"comp_level : LEVEL NUMBER",
349
"aci : aci_type aci_access TO aci_scope aci_target aci_subject",
350
"aci : aci_type aci_access",
351
"aci_type : DENY",
352
"aci_type : ALLOW",
353
"aci_access :",
354
"aci_access : ACCESS",
355
"aci_access : aci_rights ACCESS",
356
"aci_rights : aci_right",
357
"aci_rights : aci_rights ',' aci_right",
358
"aci_right : READ",
359
"aci_right : WRITE",
360
"aci_right : BIND",
361
"aci_scope :",
362
"aci_scope : SUBTREE",
363
"aci_scope : CHILDREN OF",
364
"aci_target : ANY",
365
"aci_target : ROOT",
366
"aci_target : STRING",
367
"aci_subject :",
368
"aci_subject : BY ANY",
369
"aci_subject : BY STRING",
370
"aci_subject : BY SELF",
371
"include : INCLUDE STRING",
372
"varset : STRING '=' STRING",
373
"schema : SCHEMA STRING",
374
};
375
#endif
376
#ifdef YYSTACKSIZE
377
#undef YYMAXDEPTH
378
#define YYMAXDEPTH YYSTACKSIZE
379
#else
380
#ifdef YYMAXDEPTH
381
#define YYSTACKSIZE YYMAXDEPTH
382
#else
383
#define YYSTACKSIZE 10000
384
#define YYMAXDEPTH 10000
385
#endif
386
#endif
387
#define YYINITSTACKSIZE 200
388
/* LINTUSED */
389
int yydebug;
390
int yynerrs;
391
int yyerrflag;
392
int yychar;
393
short *yyssp;
394
YYSTYPE *yyvsp;
395
YYSTYPE yyval;
396
YYSTYPE yylval;
397
short *yyss;
398
short *yysslim;
399
YYSTYPE *yyvs;
400
unsigned int yystacksize;
401
int yyparse(void);
402
#line 390 "/usr/src/usr.sbin/ldapctl/../ldapd/parse.y"
403
404
struct keywords {
405
	const char	*k_name;
406
	int		 k_val;
407
};
408
409
int
410
yyerror(const char *fmt, ...)
411
{
412
	va_list		 ap;
413
	char		*msg;
414
415
	file->errors++;
416
	va_start(ap, fmt);
417
	if (vasprintf(&msg, fmt, ap) == -1)
418
		fatalx("yyerror vasprintf");
419
	va_end(ap);
420
	logit(LOG_CRIT, "%s:%d: %s", file->name, yylval.lineno, msg);
421
	free(msg);
422
	return (0);
423
}
424
425
int
426
kw_cmp(const void *k, const void *e)
427
{
428
	return (strcmp(k, ((const struct keywords *)e)->k_name));
429
}
430
431
int
432
lookup(char *s)
433
{
434
	/* this has to be sorted always */
435
	static const struct keywords keywords[] = {
436
		{ "access",		ACCESS },
437
		{ "allow",		ALLOW },
438
		{ "any",		ANY },
439
		{ "bind",		BIND },
440
		{ "by",			BY },
441
		{ "cache-size",		CACHE_SIZE },
442
		{ "certificate",	CERTIFICATE },
443
		{ "children",		CHILDREN },
444
		{ "compression",	COMPRESSION },
445
		{ "deny",		DENY },
446
		{ "fsync",		FSYNC },
447
		{ "in",			IN },
448
		{ "include",		INCLUDE },
449
		{ "index",		INDEX },
450
		{ "index-cache-size",	INDEX_CACHE_SIZE },
451
		{ "ldaps",		LDAPS },
452
		{ "level",		LEVEL },
453
		{ "listen",		LISTEN },
454
		{ "namespace",		NAMESPACE },
455
		{ "of",			OF },
456
		{ "on",			ON },
457
		{ "port",		PORT },
458
		{ "read",		READ },
459
		{ "referral",		REFERRAL },
460
		{ "relax",		RELAX },
461
		{ "root",		ROOT },
462
		{ "rootdn",		ROOTDN },
463
		{ "rootpw",		ROOTPW },
464
		{ "schema",		SCHEMA },
465
		{ "secure",		SECURE },
466
		{ "self",		SELF },
467
		{ "strict",		STRICT },
468
		{ "subtree",		SUBTREE },
469
		{ "tls",		TLS },
470
		{ "to",			TO },
471
		{ "use",		USE },
472
		{ "write",		WRITE },
473
474
	};
475
	const struct keywords	*p;
476
477
	p = bsearch(s, keywords, sizeof(keywords)/sizeof(keywords[0]),
478
	    sizeof(keywords[0]), kw_cmp);
479
480
	if (p)
481
		return (p->k_val);
482
	else
483
		return (STRING);
484
}
485
486
#define MAXPUSHBACK	128
487
488
u_char	*parsebuf;
489
int	 parseindex;
490
u_char	 pushback_buffer[MAXPUSHBACK];
491
int	 pushback_index = 0;
492
493
int
494
lgetc(int quotec)
495
{
496
	int		c, next;
497
498
	if (parsebuf) {
499
		/* Read character from the parsebuffer instead of input. */
500
		if (parseindex >= 0) {
501
			c = parsebuf[parseindex++];
502
			if (c != '\0')
503
				return (c);
504
			parsebuf = NULL;
505
		} else
506
			parseindex++;
507
	}
508
509
	if (pushback_index)
510
		return (pushback_buffer[--pushback_index]);
511
512
	if (quotec) {
513
		if ((c = getc(file->stream)) == EOF) {
514
			yyerror("reached end of file while parsing "
515
			    "quoted string");
516
			if (file == topfile || popfile() == EOF)
517
				return (EOF);
518
			return (quotec);
519
		}
520
		return (c);
521
	}
522
523
	while ((c = getc(file->stream)) == '\\') {
524
		next = getc(file->stream);
525
		if (next != '\n') {
526
			c = next;
527
			break;
528
		}
529
		yylval.lineno = file->lineno;
530
		file->lineno++;
531
	}
532
533
	while (c == EOF) {
534
		if (file == topfile || popfile() == EOF)
535
			return (EOF);
536
		c = getc(file->stream);
537
	}
538
	return (c);
539
}
540
541
int
542
lungetc(int c)
543
{
544
	if (c == EOF)
545
		return (EOF);
546
	if (parsebuf) {
547
		parseindex--;
548
		if (parseindex >= 0)
549
			return (c);
550
	}
551
	if (pushback_index < MAXPUSHBACK-1)
552
		return (pushback_buffer[pushback_index++] = c);
553
	else
554
		return (EOF);
555
}
556
557
int
558
findeol(void)
559
{
560
	int	c;
561
562
	parsebuf = NULL;
563
564
	/* skip to either EOF or the first real EOL */
565
	while (1) {
566
		if (pushback_index)
567
			c = pushback_buffer[--pushback_index];
568
		else
569
			c = lgetc(0);
570
		if (c == '\n') {
571
			file->lineno++;
572
			break;
573
		}
574
		if (c == EOF)
575
			break;
576
	}
577
	return (ERROR);
578
}
579
580
int
581
yylex(void)
582
{
583
	u_char	 buf[4096];
584
	u_char	*p, *val;
585
	int	 quotec, next, c;
586
	int	 token;
587
588
top:
589
	p = buf;
590
	while ((c = lgetc(0)) == ' ' || c == '\t')
591
		; /* nothing */
592
593
	yylval.lineno = file->lineno;
594
	if (c == '#')
595
		while ((c = lgetc(0)) != '\n' && c != EOF)
596
			; /* nothing */
597
	if (c == '$' && parsebuf == NULL) {
598
		while (1) {
599
			if ((c = lgetc(0)) == EOF)
600
				return (0);
601
602
			if (p + 1 >= buf + sizeof(buf) - 1) {
603
				yyerror("string too long");
604
				return (findeol());
605
			}
606
			if (isalnum(c) || c == '_') {
607
				*p++ = c;
608
				continue;
609
			}
610
			*p = '\0';
611
			lungetc(c);
612
			break;
613
		}
614
		val = symget(buf);
615
		if (val == NULL) {
616
			yyerror("macro '%s' not defined", buf);
617
			return (findeol());
618
		}
619
		parsebuf = val;
620
		parseindex = 0;
621
		goto top;
622
	}
623
624
	switch (c) {
625
	case '\'':
626
	case '"':
627
		quotec = c;
628
		while (1) {
629
			if ((c = lgetc(quotec)) == EOF)
630
				return (0);
631
			if (c == '\n') {
632
				file->lineno++;
633
				continue;
634
			} else if (c == '\\') {
635
				if ((next = lgetc(quotec)) == EOF)
636
					return (0);
637
				if (next == quotec || c == ' ' || c == '\t')
638
					c = next;
639
				else if (next == '\n') {
640
					file->lineno++;
641
					continue;
642
				} else
643
					lungetc(next);
644
			} else if (c == quotec) {
645
				*p = '\0';
646
				break;
647
			} else if (c == '\0') {
648
				yyerror("syntax error");
649
				return (findeol());
650
			}
651
			if (p + 1 >= buf + sizeof(buf) - 1) {
652
				log_warnx("string too long");
653
				return (findeol());
654
			}
655
			*p++ = c;
656
		}
657
		yylval.v.string = strdup(buf);
658
		if (yylval.v.string == NULL)
659
			fatal("yylex: strdup");
660
		return (STRING);
661
	}
662
663
#define allowed_to_end_number(x) \
664
	(isspace(x) || x == ')' || x ==',' || x == '/' || x == '}' || x == '=')
665
666
	if (c == '-' || isdigit(c)) {
667
		do {
668
			*p++ = c;
669
			if ((unsigned)(p-buf) >= sizeof(buf)) {
670
				yyerror("string too long");
671
				return (findeol());
672
			}
673
		} while ((c = lgetc(0)) != EOF && isdigit(c));
674
		lungetc(c);
675
		if (p == buf + 1 && buf[0] == '-')
676
			goto nodigits;
677
		if (c == EOF || allowed_to_end_number(c)) {
678
			const char *errstr = NULL;
679
680
			*p = '\0';
681
			yylval.v.number = strtonum(buf, LLONG_MIN,
682
			    LLONG_MAX, &errstr);
683
			if (errstr) {
684
				yyerror("\"%s\" invalid number: %s",
685
				    buf, errstr);
686
				return (findeol());
687
			}
688
			return (NUMBER);
689
		} else {
690
nodigits:
691
			while (p > buf + 1)
692
				lungetc(*--p);
693
			c = *--p;
694
			if (c == '-')
695
				return (c);
696
		}
697
	}
698
699
#define allowed_in_string(x) \
700
	(isalnum(x) || (ispunct(x) && x != '(' && x != ')' && \
701
	x != '{' && x != '}' && x != '<' && x != '>' && \
702
	x != '!' && x != '=' && x != '/' && x != '#' && \
703
	x != ','))
704
705
	if (isalnum(c) || c == ':' || c == '_' || c == '*') {
706
		do {
707
			*p++ = c;
708
			if ((unsigned)(p-buf) >= sizeof(buf)) {
709
				yyerror("string too long");
710
				return (findeol());
711
			}
712
		} while ((c = lgetc(0)) != EOF && (allowed_in_string(c)));
713
		lungetc(c);
714
		*p = '\0';
715
		if ((token = lookup(buf)) == STRING)
716
			if ((yylval.v.string = strdup(buf)) == NULL)
717
				fatal("yylex: strdup");
718
		return (token);
719
	}
720
	if (c == '\n') {
721
		yylval.lineno = file->lineno;
722
		file->lineno++;
723
	}
724
	if (c == EOF)
725
		return (0);
726
	return (c);
727
}
728
729
int
730
check_file_secrecy(int fd, const char *fname)
731
{
732
	struct stat	st;
733
734
	if (fstat(fd, &st)) {
735
		log_warn("cannot stat %s", fname);
736
		return (-1);
737
	}
738
	if (st.st_uid != 0 && st.st_uid != getuid()) {
739
		log_warnx("%s: owner not root or current user", fname);
740
		return (-1);
741
	}
742
	if (st.st_mode & (S_IWGRP | S_IXGRP | S_IRWXO)) {
743
		log_warnx("%s: group writable or world read/writable", fname);
744
		return (-1);
745
	}
746
	return (0);
747
}
748
749
struct file *
750
pushfile(const char *name, int secret)
751
{
752
	struct file	*nfile;
753
754
	log_debug("parsing config %s", name);
755
756
	if ((nfile = calloc(1, sizeof(struct file))) == NULL) {
757
		log_warn("malloc");
758
		return (NULL);
759
	}
760
	if ((nfile->name = strdup(name)) == NULL) {
761
		log_warn("malloc");
762
		free(nfile);
763
		return (NULL);
764
	}
765
	if ((nfile->stream = fopen(nfile->name, "r")) == NULL) {
766
		log_warn("%s", nfile->name);
767
		free(nfile->name);
768
		free(nfile);
769
		return (NULL);
770
	}
771
	if (secret &&
772
	    check_file_secrecy(fileno(nfile->stream), nfile->name)) {
773
		fclose(nfile->stream);
774
		free(nfile->name);
775
		free(nfile);
776
		return (NULL);
777
	}
778
	nfile->lineno = 1;
779
	TAILQ_INSERT_TAIL(&files, nfile, entry);
780
	return (nfile);
781
}
782
783
int
784
popfile(void)
785
{
786
	struct file	*prev;
787
788
	if ((prev = TAILQ_PREV(file, files, entry)) != NULL)
789
		prev->errors += file->errors;
790
791
	TAILQ_REMOVE(&files, file, entry);
792
	fclose(file->stream);
793
	free(file->name);
794
	free(file);
795
	file = prev;
796
	return (file ? 0 : EOF);
797
}
798
799
int
800
parse_config(char *filename)
801
{
802
	struct sym		*sym, *next;
803
	int			 errors = 0;
804
805
	if ((conf = calloc(1, sizeof(struct ldapd_config))) == NULL)
806
		fatal(NULL);
807
808
	conf->schema = schema_new();
809
	if (conf->schema == NULL)
810
		fatal("schema_new");
811
812
	TAILQ_INIT(&conf->namespaces);
813
	TAILQ_INIT(&conf->listeners);
814
	if ((conf->sc_ssl = calloc(1, sizeof(*conf->sc_ssl))) == NULL)
815
		fatal(NULL);
816
	SPLAY_INIT(conf->sc_ssl);
817
	SIMPLEQ_INIT(&conf->acl);
818
	SLIST_INIT(&conf->referrals);
819
820
	if ((file = pushfile(filename, 1)) == NULL) {
821
		free(conf);
822
		return (-1);
823
	}
824
	topfile = file;
825
826
	yyparse();
827
	errors = file->errors;
828
	popfile();
829
830
	/* Free macros and check which have not been used. */
831
	TAILQ_FOREACH_SAFE(sym, &symhead, entry, next) {
832
		log_debug("warning: macro \"%s\" not used", sym->nam);
833
		if (!sym->persist) {
834
			free(sym->nam);
835
			free(sym->val);
836
			TAILQ_REMOVE(&symhead, sym, entry);
837
			free(sym);
838
		}
839
	}
840
841
	return (errors ? -1 : 0);
842
}
843
844
int
845
symset(const char *nam, const char *val, int persist)
846
{
847
	struct sym	*sym;
848
849
	TAILQ_FOREACH(sym, &symhead, entry) {
850
		if (strcmp(nam, sym->nam) == 0)
851
			break;
852
	}
853
854
	if (sym != NULL) {
855
		if (sym->persist == 1)
856
			return (0);
857
		else {
858
			free(sym->nam);
859
			free(sym->val);
860
			TAILQ_REMOVE(&symhead, sym, entry);
861
			free(sym);
862
		}
863
	}
864
	if ((sym = calloc(1, sizeof(*sym))) == NULL)
865
		return (-1);
866
867
	sym->nam = strdup(nam);
868
	if (sym->nam == NULL) {
869
		free(sym);
870
		return (-1);
871
	}
872
	sym->val = strdup(val);
873
	if (sym->val == NULL) {
874
		free(sym->nam);
875
		free(sym);
876
		return (-1);
877
	}
878
	sym->used = 0;
879
	sym->persist = persist;
880
	TAILQ_INSERT_TAIL(&symhead, sym, entry);
881
	return (0);
882
}
883
884
int
885
cmdline_symset(char *s)
886
{
887
	char	*sym, *val;
888
	int	ret;
889
	size_t	len;
890
891
	if ((val = strrchr(s, '=')) == NULL)
892
		return (-1);
893
894
	len = strlen(s) - strlen(val) + 1;
895
	if ((sym = malloc(len)) == NULL)
896
		fatal("cmdline_symset: malloc");
897
898
	strlcpy(sym, s, len);
899
900
	ret = symset(sym, val + 1, 1);
901
	free(sym);
902
903
	return (ret);
904
}
905
906
char *
907
symget(const char *nam)
908
{
909
	struct sym	*sym;
910
911
	TAILQ_FOREACH(sym, &symhead, entry) {
912
		if (strcmp(nam, sym->nam) == 0) {
913
			sym->used = 1;
914
			return (sym->val);
915
		}
916
	}
917
	return (NULL);
918
}
919
920
struct listener *
921
host_unix(const char *path)
922
{
923
	struct sockaddr_un	*saun;
924
	struct listener		*h;
925
926
	if (*path != '/')
927
		return (NULL);
928
929
	if ((h = calloc(1, sizeof(*h))) == NULL)
930
		fatal(NULL);
931
	saun = (struct sockaddr_un *)&h->ss;
932
	saun->sun_len = sizeof(struct sockaddr_un);
933
	saun->sun_family = AF_UNIX;
934
	if (strlcpy(saun->sun_path, path, sizeof(saun->sun_path)) >=
935
	    sizeof(saun->sun_path))
936
		fatal("socket path too long");
937
	h->flags = F_SECURE;
938
939
	return (h);
940
}
941
942
struct listener *
943
host_v4(const char *s, in_port_t port)
944
{
945
	struct in_addr		 ina;
946
	struct sockaddr_in	*sain;
947
	struct listener		*h;
948
949
	memset(&ina, 0, sizeof(ina));
950
	if (inet_pton(AF_INET, s, &ina) != 1)
951
		return (NULL);
952
953
	if ((h = calloc(1, sizeof(*h))) == NULL)
954
		fatal(NULL);
955
	sain = (struct sockaddr_in *)&h->ss;
956
	sain->sin_len = sizeof(struct sockaddr_in);
957
	sain->sin_family = AF_INET;
958
	sain->sin_addr.s_addr = ina.s_addr;
959
	sain->sin_port = port;
960
961
	return (h);
962
}
963
964
struct listener *
965
host_v6(const char *s, in_port_t port)
966
{
967
	struct in6_addr		 ina6;
968
	struct sockaddr_in6	*sin6;
969
	struct listener		*h;
970
971
	memset(&ina6, 0, sizeof(ina6));
972
	if (inet_pton(AF_INET6, s, &ina6) != 1)
973
		return (NULL);
974
975
	if ((h = calloc(1, sizeof(*h))) == NULL)
976
		fatal(NULL);
977
	sin6 = (struct sockaddr_in6 *)&h->ss;
978
	sin6->sin6_len = sizeof(struct sockaddr_in6);
979
	sin6->sin6_family = AF_INET6;
980
	sin6->sin6_port = port;
981
	memcpy(&sin6->sin6_addr, &ina6, sizeof(ina6));
982
983
	return (h);
984
}
985
986
int
987
host_dns(const char *s, const char *cert,
988
    struct listenerlist *al, int max, in_port_t port, u_int8_t flags)
989
{
990
	struct addrinfo		 hints, *res0, *res;
991
	int			 error, cnt = 0;
992
	struct sockaddr_in	*sain;
993
	struct sockaddr_in6	*sin6;
994
	struct listener		*h;
995
996
	memset(&hints, 0, sizeof(hints));
997
	hints.ai_family = PF_UNSPEC;
998
	hints.ai_socktype = SOCK_DGRAM; /* DUMMY */
999
	error = getaddrinfo(s, NULL, &hints, &res0);
1000
	if (error == EAI_AGAIN || error == EAI_NODATA || error == EAI_NONAME)
1001
		return (0);
1002
	if (error) {
1003
		log_warnx("host_dns: could not parse \"%s\": %s", s,
1004
		    gai_strerror(error));
1005
		return (-1);
1006
	}
1007
1008
	for (res = res0; res && cnt < max; res = res->ai_next) {
1009
		if (res->ai_family != AF_INET &&
1010
		    res->ai_family != AF_INET6)
1011
			continue;
1012
		if ((h = calloc(1, sizeof(*h))) == NULL)
1013
			fatal(NULL);
1014
1015
		h->port = port;
1016
		h->flags = flags;
1017
		h->ss.ss_family = res->ai_family;
1018
		h->ssl = NULL;
1019
		h->ssl_cert_name[0] = '\0';
1020
		if (cert != NULL)
1021
			(void)strlcpy(h->ssl_cert_name, cert, sizeof(h->ssl_cert_name));
1022
1023
		if (res->ai_family == AF_INET) {
1024
			sain = (struct sockaddr_in *)&h->ss;
1025
			sain->sin_len = sizeof(struct sockaddr_in);
1026
			sain->sin_addr.s_addr = ((struct sockaddr_in *)
1027
			    res->ai_addr)->sin_addr.s_addr;
1028
			sain->sin_port = port;
1029
		} else {
1030
			sin6 = (struct sockaddr_in6 *)&h->ss;
1031
			sin6->sin6_len = sizeof(struct sockaddr_in6);
1032
			memcpy(&sin6->sin6_addr, &((struct sockaddr_in6 *)
1033
			    res->ai_addr)->sin6_addr, sizeof(struct in6_addr));
1034
			sin6->sin6_port = port;
1035
		}
1036
1037
		TAILQ_INSERT_HEAD(al, h, entry);
1038
		cnt++;
1039
	}
1040
	if (cnt == max && res) {
1041
		log_warnx("host_dns: %s resolves to more than %d hosts",
1042
		    s, max);
1043
	}
1044
	freeaddrinfo(res0);
1045
	return (cnt);
1046
}
1047
1048
int
1049
host(const char *s, const char *cert, struct listenerlist *al,
1050
    int max, in_port_t port, u_int8_t flags)
1051
{
1052
	struct listener *h;
1053
1054
	/* Unix socket path? */
1055
	h = host_unix(s);
1056
1057
	/* IPv4 address? */
1058
	if (h == NULL)
1059
		h = host_v4(s, port);
1060
1061
	/* IPv6 address? */
1062
	if (h == NULL)
1063
		h = host_v6(s, port);
1064
1065
	if (h != NULL) {
1066
		h->port = port;
1067
		h->flags |= flags;
1068
		h->ssl = NULL;
1069
		h->ssl_cert_name[0] = '\0';
1070
		if (cert != NULL)
1071
			strlcpy(h->ssl_cert_name, cert, sizeof(h->ssl_cert_name));
1072
1073
		TAILQ_INSERT_HEAD(al, h, entry);
1074
		return (1);
1075
	}
1076
1077
	return (host_dns(s, cert, al, max, port, flags));
1078
}
1079
1080
int
1081
interface(const char *s, const char *cert,
1082
    struct listenerlist *al, int max, in_port_t port, u_int8_t flags)
1083
{
1084
	int			 ret = 0;
1085
	struct ifaddrs		*ifap, *p;
1086
	struct sockaddr_in	*sain;
1087
	struct sockaddr_in6	*sin6;
1088
	struct listener		*h;
1089
1090
	if (getifaddrs(&ifap) == -1)
1091
		fatal("getifaddrs");
1092
1093
	for (p = ifap; p != NULL; p = p->ifa_next) {
1094
		if (strcmp(s, p->ifa_name) != 0)
1095
			continue;
1096
1097
		switch (p->ifa_addr->sa_family) {
1098
		case AF_INET:
1099
			if ((h = calloc(1, sizeof(*h))) == NULL)
1100
				fatal(NULL);
1101
			sain = (struct sockaddr_in *)&h->ss;
1102
			*sain = *(struct sockaddr_in *)p->ifa_addr;
1103
			sain->sin_len = sizeof(struct sockaddr_in);
1104
			sain->sin_port = port;
1105
1106
			h->fd = -1;
1107
			h->port = port;
1108
			h->flags = flags;
1109
			h->ssl = NULL;
1110
			h->ssl_cert_name[0] = '\0';
1111
			if (cert != NULL)
1112
				(void)strlcpy(h->ssl_cert_name, cert, sizeof(h->ssl_cert_name));
1113
1114
			ret = 1;
1115
			TAILQ_INSERT_HEAD(al, h, entry);
1116
1117
			break;
1118
1119
		case AF_INET6:
1120
			if ((h = calloc(1, sizeof(*h))) == NULL)
1121
				fatal(NULL);
1122
			sin6 = (struct sockaddr_in6 *)&h->ss;
1123
			*sin6 = *(struct sockaddr_in6 *)p->ifa_addr;
1124
			sin6->sin6_len = sizeof(struct sockaddr_in6);
1125
			sin6->sin6_port = port;
1126
1127
			h->fd = -1;
1128
			h->port = port;
1129
			h->flags = flags;
1130
			h->ssl = NULL;
1131
			h->ssl_cert_name[0] = '\0';
1132
			if (cert != NULL)
1133
				(void)strlcpy(h->ssl_cert_name, cert, sizeof(h->ssl_cert_name));
1134
1135
			ret = 1;
1136
			TAILQ_INSERT_HEAD(al, h, entry);
1137
1138
			break;
1139
		}
1140
	}
1141
1142
	freeifaddrs(ifap);
1143
1144
	return ret;
1145
}
1146
1147
static struct aci *
1148
mk_aci(int type, int rights, enum scope scope, char *target, char *subject)
1149
{
1150
	struct aci	*aci;
1151
1152
	if ((aci = calloc(1, sizeof(*aci))) == NULL) {
1153
		yyerror("calloc");
1154
		return NULL;
1155
	}
1156
	aci->type = type;
1157
	aci->rights = rights;
1158
	aci->scope = scope;
1159
	aci->target = target;
1160
	aci->subject = subject;
1161
1162
	log_debug("%s %02X access to %s scope %d by %s",
1163
	    aci->type == ACI_DENY ? "deny" : "allow",
1164
	    aci->rights,
1165
	    aci->target ? aci->target : "any",
1166
	    aci->scope,
1167
	    aci->subject ? aci->subject : "any");
1168
1169
	return aci;
1170
}
1171
1172
struct namespace *
1173
namespace_new(const char *suffix)
1174
{
1175
	struct namespace		*ns;
1176
1177
	if ((ns = calloc(1, sizeof(*ns))) == NULL)
1178
		return NULL;
1179
	ns->suffix = strdup(suffix);
1180
	ns->sync = 1;
1181
	ns->cache_size = 1024;
1182
	ns->index_cache_size = 512;
1183
	if (ns->suffix == NULL) {
1184
		free(ns->suffix);
1185
		free(ns);
1186
		return NULL;
1187
	}
1188
	TAILQ_INIT(&ns->indices);
1189
	TAILQ_INIT(&ns->request_queue);
1190
	SIMPLEQ_INIT(&ns->acl);
1191
	SLIST_INIT(&ns->referrals);
1192
1193
	return ns;
1194
}
1195
1196
int
1197
ssl_cmp(struct ssl *s1, struct ssl *s2)
1198
{
1199
	return (strcmp(s1->ssl_name, s2->ssl_name));
1200
}
1201
1202
int
1203
load_certfile(struct ldapd_config *env, const char *name, u_int8_t flags)
1204
{
1205
	struct ssl	*s;
1206
	struct ssl	 key;
1207
	char		 certfile[PATH_MAX];
1208
1209
	if (strlcpy(key.ssl_name, name, sizeof(key.ssl_name))
1210
	    >= sizeof(key.ssl_name)) {
1211
		log_warn("load_certfile: certificate name truncated");
1212
		return -1;
1213
	}
1214
1215
	s = SPLAY_FIND(ssltree, env->sc_ssl, &key);
1216
	if (s != NULL) {
1217
		s->flags |= flags;
1218
		return 0;
1219
	}
1220
1221
	if ((s = calloc(1, sizeof(*s))) == NULL)
1222
		fatal(NULL);
1223
1224
	s->flags = flags;
1225
	(void)strlcpy(s->ssl_name, key.ssl_name, sizeof(s->ssl_name));
1226
1227
	s->config = tls_config_new();
1228
	if (s->config == NULL)
1229
		goto err;
1230
1231
	if (tls_config_set_protocols(s->config, TLS_PROTOCOLS_ALL) != 0) {
1232
		log_warn("load_certfile: failed to set tls protocols: %s",
1233
		    tls_config_error(s->config));
1234
		goto err;
1235
	}
1236
	if (tls_config_set_ciphers(s->config, "all")) {
1237
		log_warn("load_certfile: failed to set tls ciphers: %s",
1238
		    tls_config_error(s->config));
1239
		goto err;
1240
	}
1241
1242
	if ((name[0] == '/' &&
1243
	     !bsnprintf(certfile, sizeof(certfile), "%s.crt", name)) ||
1244
	    !bsnprintf(certfile, sizeof(certfile), "/etc/ldap/certs/%s.crt",
1245
		name)) {
1246
		log_warn("load_certfile: path truncated");
1247
		goto err;
1248
	}
1249
1250
	log_debug("loading certificate file %s", certfile);
1251
	s->ssl_cert = tls_load_file(certfile, &s->ssl_cert_len, NULL);
1252
	if (s->ssl_cert == NULL)
1253
		goto err;
1254
1255
	if (tls_config_set_cert_mem(s->config, s->ssl_cert, s->ssl_cert_len)) {
1256
		log_warn("load_certfile: failed to set tls certificate: %s",
1257
		    tls_config_error(s->config));
1258
		goto err;
1259
	}
1260
1261
	if ((name[0] == '/' &&
1262
	     !bsnprintf(certfile, sizeof(certfile), "%s.key", name)) ||
1263
	    !bsnprintf(certfile, sizeof(certfile), "/etc/ldap/certs/%s.key",
1264
		name)) {
1265
		log_warn("load_certfile: path truncated");
1266
		goto err;
1267
	}
1268
1269
	log_debug("loading key file %s", certfile);
1270
	s->ssl_key = tls_load_file(certfile, &s->ssl_key_len, NULL);
1271
	if (s->ssl_key == NULL)
1272
		goto err;
1273
1274
	if (tls_config_set_key_mem(s->config, s->ssl_key, s->ssl_key_len)) {
1275
		log_warn("load_certfile: failed to set tls key: %s",
1276
		    tls_config_error(s->config));
1277
		goto err;
1278
	}
1279
1280
	SPLAY_INSERT(ssltree, env->sc_ssl, s);
1281
1282
	return (0);
1283
err:
1284
	free(s->ssl_cert);
1285
	free(s->ssl_key);
1286
	tls_config_free(s->config);
1287
	free(s);
1288
	return (-1);
1289
}
1290
#line 1283 "parse.c"
1291
/* allocate initial stack or double stack size, up to YYMAXDEPTH */
1292
static int yygrowstack(void)
1293
{
1294
    unsigned int newsize;
1295
    long sslen;
1296
    short *newss;
1297
    YYSTYPE *newvs;
1298
1299
    if ((newsize = yystacksize) == 0)
1300
        newsize = YYINITSTACKSIZE;
1301
    else if (newsize >= YYMAXDEPTH)
1302
        return -1;
1303
    else if ((newsize *= 2) > YYMAXDEPTH)
1304
        newsize = YYMAXDEPTH;
1305
    sslen = yyssp - yyss;
1306
#ifdef SIZE_MAX
1307
#define YY_SIZE_MAX SIZE_MAX
1308
#else
1309
#define YY_SIZE_MAX 0xffffffffU
1310
#endif
1311
    if (newsize && YY_SIZE_MAX / newsize < sizeof *newss)
1312
        goto bail;
1313
    newss = yyss ? (short *)realloc(yyss, newsize * sizeof *newss) :
1314
      (short *)malloc(newsize * sizeof *newss); /* overflow check above */
1315
    if (newss == NULL)
1316
        goto bail;
1317
    yyss = newss;
1318
    yyssp = newss + sslen;
1319
    if (newsize && YY_SIZE_MAX / newsize < sizeof *newvs)
1320
        goto bail;
1321
    newvs = yyvs ? (YYSTYPE *)realloc(yyvs, newsize * sizeof *newvs) :
1322
      (YYSTYPE *)malloc(newsize * sizeof *newvs); /* overflow check above */
1323
    if (newvs == NULL)
1324
        goto bail;
1325
    yyvs = newvs;
1326
    yyvsp = newvs + sslen;
1327
    yystacksize = newsize;
1328
    yysslim = yyss + newsize - 1;
1329
    return 0;
1330
bail:
1331
    if (yyss)
1332
            free(yyss);
1333
    if (yyvs)
1334
            free(yyvs);
1335
    yyss = yyssp = NULL;
1336
    yyvs = yyvsp = NULL;
1337
    yystacksize = 0;
1338
    return -1;
1339
}
1340
1341
#define YYABORT goto yyabort
1342
#define YYREJECT goto yyabort
1343
#define YYACCEPT goto yyaccept
1344
#define YYERROR goto yyerrlab
1345
int
1346
yyparse(void)
1347
{
1348
    int yym, yyn, yystate;
1349
#if YYDEBUG
1350
    const char *yys;
1351
1352
    if ((yys = getenv("YYDEBUG")))
1353
    {
1354
        yyn = *yys;
1355
        if (yyn >= '0' && yyn <= '9')
1356
            yydebug = yyn - '0';
1357
    }
1358
#endif /* YYDEBUG */
1359
1360
    yynerrs = 0;
1361
    yyerrflag = 0;
1362
    yychar = (-1);
1363
1364
    if (yyss == NULL && yygrowstack()) goto yyoverflow;
1365
    yyssp = yyss;
1366
    yyvsp = yyvs;
1367
    *yyssp = yystate = 0;
1368
1369
yyloop:
1370
    if ((yyn = yydefred[yystate]) != 0) goto yyreduce;
1371
    if (yychar < 0)
1372
    {
1373
        if ((yychar = yylex()) < 0) yychar = 0;
1374
#if YYDEBUG
1375
        if (yydebug)
1376
        {
1377
            yys = 0;
1378
            if (yychar <= YYMAXTOKEN) yys = yyname[yychar];
1379
            if (!yys) yys = "illegal-symbol";
1380
            printf("%sdebug: state %d, reading %d (%s)\n",
1381
                    YYPREFIX, yystate, yychar, yys);
1382
        }
1383
#endif
1384
    }
1385
    if ((yyn = yysindex[yystate]) && (yyn += yychar) >= 0 &&
1386
            yyn <= YYTABLESIZE && yycheck[yyn] == yychar)
1387
    {
1388
#if YYDEBUG
1389
        if (yydebug)
1390
            printf("%sdebug: state %d, shifting to state %d\n",
1391
                    YYPREFIX, yystate, yytable[yyn]);
1392
#endif
1393
        if (yyssp >= yysslim && yygrowstack())
1394
        {
1395
            goto yyoverflow;
1396
        }
1397
        *++yyssp = yystate = yytable[yyn];
1398
        *++yyvsp = yylval;
1399
        yychar = (-1);
1400
        if (yyerrflag > 0)  --yyerrflag;
1401
        goto yyloop;
1402
    }
1403
    if ((yyn = yyrindex[yystate]) && (yyn += yychar) >= 0 &&
1404
            yyn <= YYTABLESIZE && yycheck[yyn] == yychar)
1405
    {
1406
        yyn = yytable[yyn];
1407
        goto yyreduce;
1408
    }
1409
    if (yyerrflag) goto yyinrecovery;
1410
#if defined(__GNUC__)
1411
    goto yynewerror;
1412
#endif
1413
yynewerror:
1414
    yyerror("syntax error");
1415
#if defined(__GNUC__)
1416
    goto yyerrlab;
1417
#endif
1418
yyerrlab:
1419
    ++yynerrs;
1420
yyinrecovery:
1421
    if (yyerrflag < 3)
1422
    {
1423
        yyerrflag = 3;
1424
        for (;;)
1425
        {
1426
            if ((yyn = yysindex[*yyssp]) && (yyn += YYERRCODE) >= 0 &&
1427
                    yyn <= YYTABLESIZE && yycheck[yyn] == YYERRCODE)
1428
            {
1429
#if YYDEBUG
1430
                if (yydebug)
1431
                    printf("%sdebug: state %d, error recovery shifting\
1432
 to state %d\n", YYPREFIX, *yyssp, yytable[yyn]);
1433
#endif
1434
                if (yyssp >= yysslim && yygrowstack())
1435
                {
1436
                    goto yyoverflow;
1437
                }
1438
                *++yyssp = yystate = yytable[yyn];
1439
                *++yyvsp = yylval;
1440
                goto yyloop;
1441
            }
1442
            else
1443
            {
1444
#if YYDEBUG
1445
                if (yydebug)
1446
                    printf("%sdebug: error recovery discarding state %d\n",
1447
                            YYPREFIX, *yyssp);
1448
#endif
1449
                if (yyssp <= yyss) goto yyabort;
1450
                --yyssp;
1451
                --yyvsp;
1452
            }
1453
        }
1454
    }
1455
    else
1456
    {
1457
        if (yychar == 0) goto yyabort;
1458
#if YYDEBUG
1459
        if (yydebug)
1460
        {
1461
            yys = 0;
1462
            if (yychar <= YYMAXTOKEN) yys = yyname[yychar];
1463
            if (!yys) yys = "illegal-symbol";
1464
            printf("%sdebug: state %d, error recovery discards token %d (%s)\n",
1465
                    YYPREFIX, yystate, yychar, yys);
1466
        }
1467
#endif
1468
        yychar = (-1);
1469
        goto yyloop;
1470
    }
1471
yyreduce:
1472
#if YYDEBUG
1473
    if (yydebug)
1474
        printf("%sdebug: state %d, reducing by rule %d (%s)\n",
1475
                YYPREFIX, yystate, yyn, yyrule[yyn]);
1476
#endif
1477
    yym = yylen[yyn];
1478
    if (yym)
1479
        yyval = yyvsp[1-yym];
1480
    else
1481
        memset(&yyval, 0, sizeof yyval);
1482
    switch (yyn)
1483
    {
1484
case 6:
1485
#line 133 "/usr/src/usr.sbin/ldapctl/../ldapd/parse.y"
1486
{ file->errors++; }
1487
break;
1488
case 8:
1489
#line 135 "/usr/src/usr.sbin/ldapctl/../ldapd/parse.y"
1490
{
1491
			SIMPLEQ_INSERT_TAIL(&conf->acl, yyvsp[-1].v.aci, entry);
1492
		}
1493
break;
1494
case 10:
1495
#line 141 "/usr/src/usr.sbin/ldapctl/../ldapd/parse.y"
1496
{ yyval.v.number = 0; }
1497
break;
1498
case 11:
1499
#line 142 "/usr/src/usr.sbin/ldapctl/../ldapd/parse.y"
1500
{ yyval.v.number = F_STARTTLS; }
1501
break;
1502
case 12:
1503
#line 143 "/usr/src/usr.sbin/ldapctl/../ldapd/parse.y"
1504
{ yyval.v.number = F_LDAPS; }
1505
break;
1506
case 13:
1507
#line 144 "/usr/src/usr.sbin/ldapctl/../ldapd/parse.y"
1508
{ yyval.v.number = F_SECURE; }
1509
break;
1510
case 14:
1511
#line 147 "/usr/src/usr.sbin/ldapctl/../ldapd/parse.y"
1512
{ yyval.v.string = NULL; }
1513
break;
1514
case 15:
1515
#line 148 "/usr/src/usr.sbin/ldapctl/../ldapd/parse.y"
1516
{ yyval.v.string = yyvsp[0].v.string; }
1517
break;
1518
case 16:
1519
#line 151 "/usr/src/usr.sbin/ldapctl/../ldapd/parse.y"
1520
{
1521
			struct servent	*servent;
1522
1523
			servent = getservbyname(yyvsp[0].v.string, "tcp");
1524
			if (servent == NULL) {
1525
				yyerror("port %s is invalid", yyvsp[0].v.string);
1526
				free(yyvsp[0].v.string);
1527
				YYERROR;
1528
			}
1529
			yyval.v.number = servent->s_port;
1530
			free(yyvsp[0].v.string);
1531
		}
1532
break;
1533
case 17:
1534
#line 163 "/usr/src/usr.sbin/ldapctl/../ldapd/parse.y"
1535
{
1536
			if (yyvsp[0].v.number <= 0 || yyvsp[0].v.number > (int)USHRT_MAX) {
1537
				yyerror("invalid port: %lld", yyvsp[0].v.number);
1538
				YYERROR;
1539
			}
1540
			yyval.v.number = htons(yyvsp[0].v.number);
1541
		}
1542
break;
1543
case 18:
1544
#line 170 "/usr/src/usr.sbin/ldapctl/../ldapd/parse.y"
1545
{
1546
			yyval.v.number = 0;
1547
		}
1548
break;
1549
case 19:
1550
#line 175 "/usr/src/usr.sbin/ldapctl/../ldapd/parse.y"
1551
{
1552
			char			*cert;
1553
1554
			if (yyvsp[-2].v.number == 0) {
1555
				if (yyvsp[-1].v.number == F_LDAPS)
1556
					yyvsp[-2].v.number = htons(LDAPS_PORT);
1557
				else
1558
					yyvsp[-2].v.number = htons(LDAP_PORT);
1559
			}
1560
1561
			cert = (yyvsp[0].v.string != NULL) ? yyvsp[0].v.string : yyvsp[-3].v.string;
1562
1563
			if ((yyvsp[-1].v.number == F_STARTTLS || yyvsp[-1].v.number == F_LDAPS) &&
1564
			    load_certfile(conf, cert, F_SCERT) < 0) {
1565
				yyerror("cannot load certificate: %s", cert);
1566
				free(yyvsp[0].v.string);
1567
				free(yyvsp[-3].v.string);
1568
				YYERROR;
1569
			}
1570
1571
			if (! interface(yyvsp[-3].v.string, cert, &conf->listeners,
1572
				MAX_LISTEN, yyvsp[-2].v.number, yyvsp[-1].v.number)) {
1573
				if (host(yyvsp[-3].v.string, cert, &conf->listeners,
1574
					MAX_LISTEN, yyvsp[-2].v.number, yyvsp[-1].v.number) <= 0) {
1575
					yyerror("invalid virtual ip or interface: %s", yyvsp[-3].v.string);
1576
					free(yyvsp[0].v.string);
1577
					free(yyvsp[-3].v.string);
1578
					YYERROR;
1579
				}
1580
			}
1581
			free(yyvsp[0].v.string);
1582
			free(yyvsp[-3].v.string);
1583
		}
1584
break;
1585
case 20:
1586
#line 208 "/usr/src/usr.sbin/ldapctl/../ldapd/parse.y"
1587
{
1588
			struct referral	*ref;
1589
			if ((ref = calloc(1, sizeof(*ref))) == NULL) {
1590
				yyerror("calloc");
1591
				free(yyvsp[0].v.string);
1592
				YYERROR;
1593
			}
1594
			ref->url = yyvsp[0].v.string;
1595
			SLIST_INSERT_HEAD(&conf->referrals, ref, next);
1596
		}
1597
break;
1598
case 21:
1599
#line 218 "/usr/src/usr.sbin/ldapctl/../ldapd/parse.y"
1600
{
1601
			conf->rootdn = yyvsp[0].v.string;
1602
			normalize_dn(conf->rootdn);
1603
		}
1604
break;
1605
case 22:
1606
#line 222 "/usr/src/usr.sbin/ldapctl/../ldapd/parse.y"
1607
{ conf->rootpw = yyvsp[0].v.string; }
1608
break;
1609
case 23:
1610
#line 225 "/usr/src/usr.sbin/ldapctl/../ldapd/parse.y"
1611
{
1612
			log_debug("parsing namespace %s", yyvsp[-2].v.string);
1613
			current_ns = namespace_new(yyvsp[-2].v.string);
1614
			free(yyvsp[-2].v.string);
1615
			TAILQ_INSERT_TAIL(&conf->namespaces, current_ns, next);
1616
		}
1617
break;
1618
case 24:
1619
#line 230 "/usr/src/usr.sbin/ldapctl/../ldapd/parse.y"
1620
{ current_ns = NULL; }
1621
break;
1622
case 25:
1623
#line 233 "/usr/src/usr.sbin/ldapctl/../ldapd/parse.y"
1624
{
1625
			if (strcasecmp(yyvsp[0].v.string, "true") == 0 ||
1626
			    strcasecmp(yyvsp[0].v.string, "yes") == 0)
1627
				yyval.v.number = 1;
1628
			else if (strcasecmp(yyvsp[0].v.string, "false") == 0 ||
1629
			    strcasecmp(yyvsp[0].v.string, "off") == 0 ||
1630
			    strcasecmp(yyvsp[0].v.string, "no") == 0)
1631
				yyval.v.number = 0;
1632
			else {
1633
				yyerror("invalid boolean value '%s'", yyvsp[0].v.string);
1634
				free(yyvsp[0].v.string);
1635
				YYERROR;
1636
			}
1637
			free(yyvsp[0].v.string);
1638
		}
1639
break;
1640
case 26:
1641
#line 248 "/usr/src/usr.sbin/ldapctl/../ldapd/parse.y"
1642
{ yyval.v.number = 1; }
1643
break;
1644
case 30:
1645
#line 256 "/usr/src/usr.sbin/ldapctl/../ldapd/parse.y"
1646
{
1647
			current_ns->rootdn = yyvsp[0].v.string;
1648
			normalize_dn(current_ns->rootdn);
1649
		}
1650
break;
1651
case 31:
1652
#line 260 "/usr/src/usr.sbin/ldapctl/../ldapd/parse.y"
1653
{ current_ns->rootpw = yyvsp[0].v.string; }
1654
break;
1655
case 32:
1656
#line 261 "/usr/src/usr.sbin/ldapctl/../ldapd/parse.y"
1657
{
1658
			struct attr_index	*ai;
1659
			if ((ai = calloc(1, sizeof(*ai))) == NULL) {
1660
				yyerror("calloc");
1661
                                free(yyvsp[0].v.string);
1662
				YYERROR;
1663
			}
1664
			ai->attr = yyvsp[0].v.string;
1665
			ai->type = INDEX_EQUAL;
1666
			TAILQ_INSERT_TAIL(&current_ns->indices, ai, next);
1667
		}
1668
break;
1669
case 33:
1670
#line 272 "/usr/src/usr.sbin/ldapctl/../ldapd/parse.y"
1671
{ current_ns->cache_size = yyvsp[0].v.number; }
1672
break;
1673
case 34:
1674
#line 273 "/usr/src/usr.sbin/ldapctl/../ldapd/parse.y"
1675
{ current_ns->index_cache_size = yyvsp[0].v.number; }
1676
break;
1677
case 35:
1678
#line 274 "/usr/src/usr.sbin/ldapctl/../ldapd/parse.y"
1679
{ current_ns->sync = yyvsp[0].v.number; }
1680
break;
1681
case 36:
1682
#line 275 "/usr/src/usr.sbin/ldapctl/../ldapd/parse.y"
1683
{
1684
			SIMPLEQ_INSERT_TAIL(&current_ns->acl, yyvsp[0].v.aci, entry);
1685
		}
1686
break;
1687
case 37:
1688
#line 278 "/usr/src/usr.sbin/ldapctl/../ldapd/parse.y"
1689
{ current_ns->relax = 1; }
1690
break;
1691
case 38:
1692
#line 279 "/usr/src/usr.sbin/ldapctl/../ldapd/parse.y"
1693
{ current_ns->relax = 0; }
1694
break;
1695
case 39:
1696
#line 280 "/usr/src/usr.sbin/ldapctl/../ldapd/parse.y"
1697
{ current_ns->compression_level = yyvsp[0].v.number; }
1698
break;
1699
case 40:
1700
#line 281 "/usr/src/usr.sbin/ldapctl/../ldapd/parse.y"
1701
{
1702
			struct referral	*ref;
1703
			if ((ref = calloc(1, sizeof(*ref))) == NULL) {
1704
				yyerror("calloc");
1705
				free(yyvsp[0].v.string);
1706
				YYERROR;
1707
			}
1708
			ref->url = yyvsp[0].v.string;
1709
			SLIST_INSERT_HEAD(&current_ns->referrals, ref, next);
1710
		}
1711
break;
1712
case 41:
1713
#line 293 "/usr/src/usr.sbin/ldapctl/../ldapd/parse.y"
1714
{ yyval.v.number = 6; }
1715
break;
1716
case 42:
1717
#line 294 "/usr/src/usr.sbin/ldapctl/../ldapd/parse.y"
1718
{ yyval.v.number = yyvsp[0].v.number; }
1719
break;
1720
case 43:
1721
#line 297 "/usr/src/usr.sbin/ldapctl/../ldapd/parse.y"
1722
{
1723
			if ((yyval.v.aci = mk_aci(yyvsp[-5].v.number, yyvsp[-4].v.number, yyvsp[-2].v.number, yyvsp[-1].v.string, yyvsp[0].v.string)) == NULL) {
1724
				free(yyvsp[-1].v.string);
1725
				free(yyvsp[0].v.string);
1726
				YYERROR;
1727
			}
1728
		}
1729
break;
1730
case 44:
1731
#line 304 "/usr/src/usr.sbin/ldapctl/../ldapd/parse.y"
1732
{
1733
			if ((yyval.v.aci = mk_aci(yyvsp[-1].v.number, yyvsp[0].v.number, LDAP_SCOPE_SUBTREE, NULL,
1734
			    NULL)) == NULL) {
1735
				YYERROR;
1736
			}
1737
		}
1738
break;
1739
case 45:
1740
#line 312 "/usr/src/usr.sbin/ldapctl/../ldapd/parse.y"
1741
{ yyval.v.number = ACI_DENY; }
1742
break;
1743
case 46:
1744
#line 313 "/usr/src/usr.sbin/ldapctl/../ldapd/parse.y"
1745
{ yyval.v.number = ACI_ALLOW; }
1746
break;
1747
case 47:
1748
#line 316 "/usr/src/usr.sbin/ldapctl/../ldapd/parse.y"
1749
{ yyval.v.number = ACI_ALL; }
1750
break;
1751
case 48:
1752
#line 317 "/usr/src/usr.sbin/ldapctl/../ldapd/parse.y"
1753
{ yyval.v.number = ACI_ALL; }
1754
break;
1755
case 49:
1756
#line 318 "/usr/src/usr.sbin/ldapctl/../ldapd/parse.y"
1757
{ yyval.v.number = yyvsp[-1].v.number; }
1758
break;
1759
case 50:
1760
#line 321 "/usr/src/usr.sbin/ldapctl/../ldapd/parse.y"
1761
{ yyval.v.number = yyvsp[0].v.number; }
1762
break;
1763
case 51:
1764
#line 322 "/usr/src/usr.sbin/ldapctl/../ldapd/parse.y"
1765
{ yyval.v.number = yyvsp[-2].v.number | yyvsp[0].v.number; }
1766
break;
1767
case 52:
1768
#line 325 "/usr/src/usr.sbin/ldapctl/../ldapd/parse.y"
1769
{ yyval.v.number = ACI_READ; }
1770
break;
1771
case 53:
1772
#line 326 "/usr/src/usr.sbin/ldapctl/../ldapd/parse.y"
1773
{ yyval.v.number = ACI_WRITE; }
1774
break;
1775
case 54:
1776
#line 327 "/usr/src/usr.sbin/ldapctl/../ldapd/parse.y"
1777
{ yyval.v.number = ACI_BIND; }
1778
break;
1779
case 55:
1780
#line 331 "/usr/src/usr.sbin/ldapctl/../ldapd/parse.y"
1781
{ yyval.v.number = LDAP_SCOPE_BASE; }
1782
break;
1783
case 56:
1784
#line 332 "/usr/src/usr.sbin/ldapctl/../ldapd/parse.y"
1785
{ yyval.v.number = LDAP_SCOPE_SUBTREE; }
1786
break;
1787
case 57:
1788
#line 333 "/usr/src/usr.sbin/ldapctl/../ldapd/parse.y"
1789
{ yyval.v.number = LDAP_SCOPE_ONELEVEL; }
1790
break;
1791
case 58:
1792
#line 336 "/usr/src/usr.sbin/ldapctl/../ldapd/parse.y"
1793
{ yyval.v.string = NULL; }
1794
break;
1795
case 59:
1796
#line 337 "/usr/src/usr.sbin/ldapctl/../ldapd/parse.y"
1797
{ yyval.v.string = strdup(""); }
1798
break;
1799
case 60:
1800
#line 338 "/usr/src/usr.sbin/ldapctl/../ldapd/parse.y"
1801
{ yyval.v.string = yyvsp[0].v.string; normalize_dn(yyval.v.string); }
1802
break;
1803
case 61:
1804
#line 341 "/usr/src/usr.sbin/ldapctl/../ldapd/parse.y"
1805
{ yyval.v.string = NULL; }
1806
break;
1807
case 62:
1808
#line 342 "/usr/src/usr.sbin/ldapctl/../ldapd/parse.y"
1809
{ yyval.v.string = NULL; }
1810
break;
1811
case 63:
1812
#line 343 "/usr/src/usr.sbin/ldapctl/../ldapd/parse.y"
1813
{ yyval.v.string = yyvsp[0].v.string; normalize_dn(yyval.v.string); }
1814
break;
1815
case 64:
1816
#line 344 "/usr/src/usr.sbin/ldapctl/../ldapd/parse.y"
1817
{ yyval.v.string = strdup("@"); }
1818
break;
1819
case 65:
1820
#line 347 "/usr/src/usr.sbin/ldapctl/../ldapd/parse.y"
1821
{
1822
			struct file	*nfile;
1823
1824
			if ((nfile = pushfile(yyvsp[0].v.string, 1)) == NULL) {
1825
				yyerror("failed to include file %s", yyvsp[0].v.string);
1826
				free(yyvsp[0].v.string);
1827
				YYERROR;
1828
			}
1829
			free(yyvsp[0].v.string);
1830
1831
			file = nfile;
1832
			lungetc('\n');
1833
		}
1834
break;
1835
case 66:
1836
#line 362 "/usr/src/usr.sbin/ldapctl/../ldapd/parse.y"
1837
{
1838
			char *s = yyvsp[-2].v.string;
1839
			while (*s++) {
1840
				if (isspace((unsigned char)*s)) {
1841
					yyerror("macro name cannot contain "
1842
					    "whitespace");
1843
					YYERROR;
1844
				}
1845
			}
1846
			if (symset(yyvsp[-2].v.string, yyvsp[0].v.string, 0) == -1)
1847
				fatal("cannot store variable");
1848
			free(yyvsp[-2].v.string);
1849
			free(yyvsp[0].v.string);
1850
		}
1851
break;
1852
case 67:
1853
#line 378 "/usr/src/usr.sbin/ldapctl/../ldapd/parse.y"
1854
{
1855
			int	 ret;
1856
1857
			ret = schema_parse(conf->schema, yyvsp[0].v.string);
1858
			free(yyvsp[0].v.string);
1859
			if (ret != 0) {
1860
				YYERROR;
1861
			}
1862
		}
1863
break;
1864
#line 1857 "parse.c"
1865
    }
1866
    yyssp -= yym;
1867
    yystate = *yyssp;
1868
    yyvsp -= yym;
1869
    yym = yylhs[yyn];
1870
    if (yystate == 0 && yym == 0)
1871
    {
1872
#if YYDEBUG
1873
        if (yydebug)
1874
            printf("%sdebug: after reduction, shifting from state 0 to\
1875
 state %d\n", YYPREFIX, YYFINAL);
1876
#endif
1877
        yystate = YYFINAL;
1878
        *++yyssp = YYFINAL;
1879
        *++yyvsp = yyval;
1880
        if (yychar < 0)
1881
        {
1882
            if ((yychar = yylex()) < 0) yychar = 0;
1883
#if YYDEBUG
1884
            if (yydebug)
1885
            {
1886
                yys = 0;
1887
                if (yychar <= YYMAXTOKEN) yys = yyname[yychar];
1888
                if (!yys) yys = "illegal-symbol";
1889
                printf("%sdebug: state %d, reading %d (%s)\n",
1890
                        YYPREFIX, YYFINAL, yychar, yys);
1891
            }
1892
#endif
1893
        }
1894
        if (yychar == 0) goto yyaccept;
1895
        goto yyloop;
1896
    }
1897
    if ((yyn = yygindex[yym]) && (yyn += yystate) >= 0 &&
1898
            yyn <= YYTABLESIZE && yycheck[yyn] == yystate)
1899
        yystate = yytable[yyn];
1900
    else
1901
        yystate = yydgoto[yym];
1902
#if YYDEBUG
1903
    if (yydebug)
1904
        printf("%sdebug: after reduction, shifting from state %d \
1905
to state %d\n", YYPREFIX, *yyssp, yystate);
1906
#endif
1907
    if (yyssp >= yysslim && yygrowstack())
1908
    {
1909
        goto yyoverflow;
1910
    }
1911
    *++yyssp = yystate;
1912
    *++yyvsp = yyval;
1913
    goto yyloop;
1914
yyoverflow:
1915
    yyerror("yacc stack overflow");
1916
yyabort:
1917
    if (yyss)
1918
            free(yyss);
1919
    if (yyvs)
1920
            free(yyvs);
1921
    yyss = yyssp = NULL;
1922
    yyvs = yyvsp = NULL;
1923
    yystacksize = 0;
1924
    return (1);
1925
yyaccept:
1926
    if (yyss)
1927
            free(yyss);
1928
    if (yyvs)
1929
            free(yyvs);
1930
    yyss = yyssp = NULL;
1931
    yyvs = yyvsp = NULL;
1932
    yystacksize = 0;
1933
    return (0);
1934
}