1255570Strasz%{
2255570Strasz/*-
3255570Strasz * Copyright (c) 2012 The FreeBSD Foundation
4255570Strasz * All rights reserved.
5255570Strasz *
6255570Strasz * This software was developed by Edward Tomasz Napierala under sponsorship
7255570Strasz * from the FreeBSD Foundation.
8255570Strasz *
9255570Strasz * Redistribution and use in source and binary forms, with or without
10255570Strasz * modification, are permitted provided that the following conditions
11255570Strasz * are met:
12255570Strasz * 1. Redistributions of source code must retain the above copyright
13255570Strasz *    notice, this list of conditions and the following disclaimer.
14255570Strasz * 2. Redistributions in binary form must reproduce the above copyright
15255570Strasz *    notice, this list of conditions and the following disclaimer in the
16255570Strasz *    documentation and/or other materials provided with the distribution.
17255570Strasz *
18255570Strasz * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
19255570Strasz * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20255570Strasz * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21255570Strasz * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
22255570Strasz * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23255570Strasz * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24255570Strasz * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25255570Strasz * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26255570Strasz * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27255570Strasz * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28255570Strasz * SUCH DAMAGE.
29255570Strasz *
30255570Strasz * $FreeBSD: releng/11.0/usr.sbin/ctld/parse.y 295212 2016-02-03 15:45:13Z jceel $
31255570Strasz */
32255570Strasz
33255570Strasz#include <sys/queue.h>
34255570Strasz#include <sys/types.h>
35255570Strasz#include <sys/stat.h>
36255570Strasz#include <assert.h>
37255570Strasz#include <stdio.h>
38255570Strasz#include <stdlib.h>
39255570Strasz#include <string.h>
40255570Strasz
41255570Strasz#include "ctld.h"
42255570Strasz
43255570Straszextern FILE *yyin;
44255570Straszextern char *yytext;
45255570Straszextern int lineno;
46255570Strasz
47255570Straszstatic struct conf *conf = NULL;
48255570Straszstatic struct auth_group *auth_group = NULL;
49255570Straszstatic struct portal_group *portal_group = NULL;
50255570Straszstatic struct target *target = NULL;
51255570Straszstatic struct lun *lun = NULL;
52255570Strasz
53255570Straszextern void	yyerror(const char *);
54255570Straszextern int	yylex(void);
55255570Straszextern void	yyrestart(FILE *);
56255570Strasz
57255570Strasz%}
58255570Strasz
59261758Strasz%token ALIAS AUTH_GROUP AUTH_TYPE BACKEND BLOCKSIZE CHAP CHAP_MUTUAL
60288310Smav%token CLOSING_BRACKET CTL_LUN DEBUG DEVICE_ID DEVICE_TYPE
61288310Smav%token DISCOVERY_AUTH_GROUP DISCOVERY_FILTER FOREIGN
62273821Strasz%token INITIATOR_NAME INITIATOR_PORTAL ISNS_SERVER ISNS_PERIOD ISNS_TIMEOUT
63278331Strasz%token LISTEN LISTEN_ISER LUN MAXPROC OFFLOAD OPENING_BRACKET OPTION
64278354Smav%token PATH PIDFILE PORT PORTAL_GROUP REDIRECT SEMICOLON SERIAL SIZE STR
65287534Smav%token TAG TARGET TIMEOUT
66255570Strasz
67255570Strasz%union
68255570Strasz{
69255570Strasz	char *str;
70255570Strasz}
71255570Strasz
72255570Strasz%token <str> STR
73255570Strasz
74255570Strasz%%
75255570Strasz
76255570Straszstatements:
77255570Strasz	|
78255570Strasz	statements statement
79273820Strasz	|
80273820Strasz	statements statement SEMICOLON
81255570Strasz	;
82255570Strasz
83255570Straszstatement:
84261756Strasz	debug
85255570Strasz	|
86261756Strasz	timeout
87255570Strasz	|
88261756Strasz	maxproc
89255570Strasz	|
90261756Strasz	pidfile
91255570Strasz	|
92273635Smav	isns_server
93273635Smav	|
94273635Smav	isns_period
95273635Smav	|
96273635Smav	isns_timeout
97273635Smav	|
98261756Strasz	auth_group
99255570Strasz	|
100261756Strasz	portal_group
101255570Strasz	|
102278037Smav	lun
103278037Smav	|
104261756Strasz	target
105255570Strasz	;
106255570Strasz
107273768Straszdebug:		DEBUG STR
108255570Strasz	{
109273768Strasz		uint64_t tmp;
110273768Strasz
111273768Strasz		if (expand_number($2, &tmp) != 0) {
112273770Strasz			yyerror("invalid numeric value");
113273768Strasz			free($2);
114273768Strasz			return (1);
115273768Strasz		}
116273768Strasz
117273768Strasz		conf->conf_debug = tmp;
118255570Strasz	}
119255570Strasz	;
120255570Strasz
121273768Strasztimeout:	TIMEOUT STR
122255570Strasz	{
123273768Strasz		uint64_t tmp;
124273768Strasz
125273768Strasz		if (expand_number($2, &tmp) != 0) {
126273770Strasz			yyerror("invalid numeric value");
127273768Strasz			free($2);
128273768Strasz			return (1);
129273768Strasz		}
130273768Strasz
131273768Strasz		conf->conf_timeout = tmp;
132255570Strasz	}
133255570Strasz	;
134255570Strasz
135273768Straszmaxproc:	MAXPROC STR
136255570Strasz	{
137273768Strasz		uint64_t tmp;
138273768Strasz
139273768Strasz		if (expand_number($2, &tmp) != 0) {
140273770Strasz			yyerror("invalid numeric value");
141273768Strasz			free($2);
142273768Strasz			return (1);
143273768Strasz		}
144273768Strasz
145273768Strasz		conf->conf_maxproc = tmp;
146255570Strasz	}
147255570Strasz	;
148255570Strasz
149261756Straszpidfile:	PIDFILE STR
150255570Strasz	{
151255570Strasz		if (conf->conf_pidfile_path != NULL) {
152255570Strasz			log_warnx("pidfile specified more than once");
153255570Strasz			free($2);
154255570Strasz			return (1);
155255570Strasz		}
156255570Strasz		conf->conf_pidfile_path = $2;
157255570Strasz	}
158255570Strasz	;
159255570Strasz
160273635Smavisns_server:	ISNS_SERVER STR
161273635Smav	{
162273635Smav		int error;
163273635Smav
164273635Smav		error = isns_new(conf, $2);
165273635Smav		free($2);
166273635Smav		if (error != 0)
167273635Smav			return (1);
168273635Smav	}
169273635Smav	;
170273635Smav
171273770Straszisns_period:	ISNS_PERIOD STR
172273635Smav	{
173273770Strasz		uint64_t tmp;
174273770Strasz
175273770Strasz		if (expand_number($2, &tmp) != 0) {
176273770Strasz			yyerror("invalid numeric value");
177273770Strasz			free($2);
178273770Strasz			return (1);
179273770Strasz		}
180273770Strasz
181273770Strasz		conf->conf_isns_period = tmp;
182273635Smav	}
183273635Smav	;
184273635Smav
185273770Straszisns_timeout:	ISNS_TIMEOUT STR
186273635Smav	{
187273770Strasz		uint64_t tmp;
188273770Strasz
189273770Strasz		if (expand_number($2, &tmp) != 0) {
190273770Strasz			yyerror("invalid numeric value");
191273770Strasz			free($2);
192273770Strasz			return (1);
193273770Strasz		}
194273770Strasz
195273770Strasz		conf->conf_isns_timeout = tmp;
196273635Smav	}
197273635Smav	;
198273635Smav
199261756Straszauth_group:	AUTH_GROUP auth_group_name
200255570Strasz    OPENING_BRACKET auth_group_entries CLOSING_BRACKET
201255570Strasz	{
202255570Strasz		auth_group = NULL;
203255570Strasz	}
204255570Strasz	;
205255570Strasz
206255570Straszauth_group_name:	STR
207255570Strasz	{
208261760Strasz		/*
209261760Strasz		 * Make it possible to redefine default
210261760Strasz		 * auth-group. but only once.
211261760Strasz		 */
212261760Strasz		if (strcmp($1, "default") == 0 &&
213261760Strasz		    conf->conf_default_ag_defined == false) {
214261760Strasz			auth_group = auth_group_find(conf, $1);
215261760Strasz			conf->conf_default_ag_defined = true;
216261760Strasz		} else {
217261760Strasz			auth_group = auth_group_new(conf, $1);
218261760Strasz		}
219255570Strasz		free($1);
220255570Strasz		if (auth_group == NULL)
221255570Strasz			return (1);
222255570Strasz	}
223255570Strasz	;
224255570Strasz
225255570Straszauth_group_entries:
226255570Strasz	|
227255570Strasz	auth_group_entries auth_group_entry
228273820Strasz	|
229273820Strasz	auth_group_entries auth_group_entry SEMICOLON
230255570Strasz	;
231255570Strasz
232255570Straszauth_group_entry:
233261758Strasz	auth_group_auth_type
234261758Strasz	|
235255570Strasz	auth_group_chap
236255570Strasz	|
237255570Strasz	auth_group_chap_mutual
238261754Strasz	|
239261754Strasz	auth_group_initiator_name
240261754Strasz	|
241261754Strasz	auth_group_initiator_portal
242255570Strasz	;
243255570Strasz
244261758Straszauth_group_auth_type:	AUTH_TYPE STR
245261758Strasz	{
246261758Strasz		int error;
247261758Strasz
248273816Strasz		error = auth_group_set_type(auth_group, $2);
249261758Strasz		free($2);
250261758Strasz		if (error != 0)
251261758Strasz			return (1);
252261758Strasz	}
253261758Strasz	;
254261758Strasz
255255570Straszauth_group_chap:	CHAP STR STR
256255570Strasz	{
257255570Strasz		const struct auth *ca;
258255570Strasz
259255570Strasz		ca = auth_new_chap(auth_group, $2, $3);
260255570Strasz		free($2);
261255570Strasz		free($3);
262255570Strasz		if (ca == NULL)
263255570Strasz			return (1);
264255570Strasz	}
265255570Strasz	;
266255570Strasz
267255570Straszauth_group_chap_mutual:	CHAP_MUTUAL STR STR STR STR
268255570Strasz	{
269255570Strasz		const struct auth *ca;
270255570Strasz
271255570Strasz		ca = auth_new_chap_mutual(auth_group, $2, $3, $4, $5);
272255570Strasz		free($2);
273255570Strasz		free($3);
274255570Strasz		free($4);
275255570Strasz		free($5);
276255570Strasz		if (ca == NULL)
277255570Strasz			return (1);
278255570Strasz	}
279255570Strasz	;
280255570Strasz
281261754Straszauth_group_initiator_name:	INITIATOR_NAME STR
282261754Strasz	{
283261754Strasz		const struct auth_name *an;
284261754Strasz
285261754Strasz		an = auth_name_new(auth_group, $2);
286261754Strasz		free($2);
287261754Strasz		if (an == NULL)
288261754Strasz			return (1);
289261754Strasz	}
290261754Strasz	;
291261754Strasz
292261754Straszauth_group_initiator_portal:	INITIATOR_PORTAL STR
293261754Strasz	{
294261754Strasz		const struct auth_portal *ap;
295261754Strasz
296261754Strasz		ap = auth_portal_new(auth_group, $2);
297261754Strasz		free($2);
298261754Strasz		if (ap == NULL)
299261754Strasz			return (1);
300261754Strasz	}
301261754Strasz	;
302261754Strasz
303261756Straszportal_group:	PORTAL_GROUP portal_group_name
304255570Strasz    OPENING_BRACKET portal_group_entries CLOSING_BRACKET
305255570Strasz	{
306255570Strasz		portal_group = NULL;
307255570Strasz	}
308255570Strasz	;
309255570Strasz
310255570Straszportal_group_name:	STR
311255570Strasz	{
312261759Strasz		/*
313261759Strasz		 * Make it possible to redefine default
314261759Strasz		 * portal-group. but only once.
315261759Strasz		 */
316261759Strasz		if (strcmp($1, "default") == 0 &&
317261759Strasz		    conf->conf_default_pg_defined == false) {
318261759Strasz			portal_group = portal_group_find(conf, $1);
319261759Strasz			conf->conf_default_pg_defined = true;
320261759Strasz		} else {
321261759Strasz			portal_group = portal_group_new(conf, $1);
322261759Strasz		}
323255570Strasz		free($1);
324255570Strasz		if (portal_group == NULL)
325255570Strasz			return (1);
326255570Strasz	}
327255570Strasz	;
328255570Strasz
329255570Straszportal_group_entries:
330255570Strasz	|
331255570Strasz	portal_group_entries portal_group_entry
332273820Strasz	|
333273820Strasz	portal_group_entries portal_group_entry SEMICOLON
334255570Strasz	;
335255570Strasz
336255570Straszportal_group_entry:
337255570Strasz	portal_group_discovery_auth_group
338255570Strasz	|
339273813Strasz	portal_group_discovery_filter
340273813Strasz	|
341287534Smav	portal_group_foreign
342287534Smav	|
343255570Strasz	portal_group_listen
344255570Strasz	|
345255570Strasz	portal_group_listen_iser
346274308Strasz	|
347279392Strasz	portal_group_offload
348279392Strasz	|
349290615Smav	portal_group_option
350290615Smav	|
351274308Strasz	portal_group_redirect
352287534Smav	|
353287534Smav	portal_group_tag
354255570Strasz	;
355255570Strasz
356255570Straszportal_group_discovery_auth_group:	DISCOVERY_AUTH_GROUP STR
357255570Strasz	{
358255570Strasz		if (portal_group->pg_discovery_auth_group != NULL) {
359255570Strasz			log_warnx("discovery-auth-group for portal-group "
360255570Strasz			    "\"%s\" specified more than once",
361255570Strasz			    portal_group->pg_name);
362255570Strasz			return (1);
363255570Strasz		}
364255570Strasz		portal_group->pg_discovery_auth_group =
365255570Strasz		    auth_group_find(conf, $2);
366255570Strasz		if (portal_group->pg_discovery_auth_group == NULL) {
367255570Strasz			log_warnx("unknown discovery-auth-group \"%s\" "
368255570Strasz			    "for portal-group \"%s\"",
369255570Strasz			    $2, portal_group->pg_name);
370255570Strasz			return (1);
371255570Strasz		}
372255570Strasz		free($2);
373255570Strasz	}
374255570Strasz	;
375255570Strasz
376273813Straszportal_group_discovery_filter:	DISCOVERY_FILTER STR
377273813Strasz	{
378273813Strasz		int error;
379273813Strasz
380273816Strasz		error = portal_group_set_filter(portal_group, $2);
381273813Strasz		free($2);
382273813Strasz		if (error != 0)
383273813Strasz			return (1);
384273813Strasz	}
385273813Strasz	;
386273813Strasz
387287534Smavportal_group_foreign:	FOREIGN
388287534Smav	{
389287534Smav
390287534Smav		portal_group->pg_foreign = 1;
391287534Smav	}
392287534Smav	;
393287534Smav
394255570Straszportal_group_listen:	LISTEN STR
395255570Strasz	{
396255570Strasz		int error;
397255570Strasz
398255570Strasz		error = portal_group_add_listen(portal_group, $2, false);
399255570Strasz		free($2);
400255570Strasz		if (error != 0)
401255570Strasz			return (1);
402255570Strasz	}
403255570Strasz	;
404255570Strasz
405255570Straszportal_group_listen_iser:	LISTEN_ISER STR
406255570Strasz	{
407255570Strasz		int error;
408255570Strasz
409255570Strasz		error = portal_group_add_listen(portal_group, $2, true);
410255570Strasz		free($2);
411255570Strasz		if (error != 0)
412255570Strasz			return (1);
413255570Strasz	}
414255570Strasz	;
415255570Strasz
416279392Straszportal_group_offload:	OFFLOAD STR
417279392Strasz	{
418279392Strasz		int error;
419279392Strasz
420279392Strasz		error = portal_group_set_offload(portal_group, $2);
421279392Strasz		free($2);
422279392Strasz		if (error != 0)
423279392Strasz			return (1);
424279392Strasz	}
425279392Strasz	;
426279392Strasz
427290615Smavportal_group_option:	OPTION STR STR
428290615Smav	{
429290615Smav		struct option *o;
430290615Smav
431290615Smav		o = option_new(&portal_group->pg_options, $2, $3);
432290615Smav		free($2);
433290615Smav		free($3);
434290615Smav		if (o == NULL)
435290615Smav			return (1);
436290615Smav	}
437290615Smav	;
438290615Smav
439274308Straszportal_group_redirect:	REDIRECT STR
440274308Strasz	{
441274308Strasz		int error;
442274308Strasz
443274308Strasz		error = portal_group_set_redirection(portal_group, $2);
444274308Strasz		free($2);
445274308Strasz		if (error != 0)
446274308Strasz			return (1);
447274308Strasz	}
448274308Strasz	;
449274308Strasz
450287534Smavportal_group_tag:	TAG STR
451287534Smav	{
452287534Smav		uint64_t tmp;
453287534Smav
454287534Smav		if (expand_number($2, &tmp) != 0) {
455287534Smav			yyerror("invalid numeric value");
456287534Smav			free($2);
457287534Smav			return (1);
458287534Smav		}
459287534Smav
460287534Smav		portal_group->pg_tag = tmp;
461287534Smav	}
462287534Smav	;
463287534Smav
464278037Smavlun:	LUN lun_name
465278037Smav    OPENING_BRACKET lun_entries CLOSING_BRACKET
466278037Smav	{
467278037Smav		lun = NULL;
468278037Smav	}
469278037Smav	;
470278037Smav
471278037Smavlun_name:	STR
472278037Smav	{
473278037Smav		lun = lun_new(conf, $1);
474278037Smav		free($1);
475278037Smav		if (lun == NULL)
476278037Smav			return (1);
477278037Smav	}
478278037Smav	;
479278037Smav
480261756Strasztarget:	TARGET target_name
481255570Strasz    OPENING_BRACKET target_entries CLOSING_BRACKET
482255570Strasz	{
483255570Strasz		target = NULL;
484255570Strasz	}
485255570Strasz	;
486255570Strasz
487261756Strasztarget_name:	STR
488255570Strasz	{
489255570Strasz		target = target_new(conf, $1);
490255570Strasz		free($1);
491255570Strasz		if (target == NULL)
492255570Strasz			return (1);
493255570Strasz	}
494255570Strasz	;
495255570Strasz
496255570Strasztarget_entries:
497255570Strasz	|
498255570Strasz	target_entries target_entry
499273820Strasz	|
500273820Strasz	target_entries target_entry SEMICOLON
501255570Strasz	;
502255570Strasz
503255570Strasztarget_entry:
504261756Strasz	target_alias
505255570Strasz	|
506261756Strasz	target_auth_group
507255570Strasz	|
508261758Strasz	target_auth_type
509261758Strasz	|
510261756Strasz	target_chap
511255570Strasz	|
512261756Strasz	target_chap_mutual
513255570Strasz	|
514261756Strasz	target_initiator_name
515261754Strasz	|
516261756Strasz	target_initiator_portal
517261754Strasz	|
518261756Strasz	target_portal_group
519255570Strasz	|
520278354Smav	target_port
521278354Smav	|
522274308Strasz	target_redirect
523274308Strasz	|
524261756Strasz	target_lun
525278037Smav	|
526278037Smav	target_lun_ref
527255570Strasz	;
528255570Strasz
529261756Strasztarget_alias:	ALIAS STR
530255570Strasz	{
531255570Strasz		if (target->t_alias != NULL) {
532255570Strasz			log_warnx("alias for target \"%s\" "
533261757Strasz			    "specified more than once", target->t_name);
534255570Strasz			return (1);
535255570Strasz		}
536255570Strasz		target->t_alias = $2;
537255570Strasz	}
538255570Strasz	;
539255570Strasz
540261756Strasztarget_auth_group:	AUTH_GROUP STR
541255570Strasz	{
542255570Strasz		if (target->t_auth_group != NULL) {
543255570Strasz			if (target->t_auth_group->ag_name != NULL)
544255570Strasz				log_warnx("auth-group for target \"%s\" "
545261757Strasz				    "specified more than once", target->t_name);
546255570Strasz			else
547261758Strasz				log_warnx("cannot use both auth-group and explicit "
548255570Strasz				    "authorisations for target \"%s\"",
549261757Strasz				    target->t_name);
550255570Strasz			return (1);
551255570Strasz		}
552255570Strasz		target->t_auth_group = auth_group_find(conf, $2);
553255570Strasz		if (target->t_auth_group == NULL) {
554255570Strasz			log_warnx("unknown auth-group \"%s\" for target "
555261757Strasz			    "\"%s\"", $2, target->t_name);
556255570Strasz			return (1);
557255570Strasz		}
558255570Strasz		free($2);
559255570Strasz	}
560255570Strasz	;
561255570Strasz
562261758Strasztarget_auth_type:	AUTH_TYPE STR
563261758Strasz	{
564261758Strasz		int error;
565261758Strasz
566261758Strasz		if (target->t_auth_group != NULL) {
567261758Strasz			if (target->t_auth_group->ag_name != NULL) {
568261758Strasz				log_warnx("cannot use both auth-group and "
569261758Strasz				    "auth-type for target \"%s\"",
570261758Strasz				    target->t_name);
571261758Strasz				return (1);
572261758Strasz			}
573261758Strasz		} else {
574261758Strasz			target->t_auth_group = auth_group_new(conf, NULL);
575261758Strasz			if (target->t_auth_group == NULL) {
576261758Strasz				free($2);
577261758Strasz				return (1);
578261758Strasz			}
579261758Strasz			target->t_auth_group->ag_target = target;
580261758Strasz		}
581273816Strasz		error = auth_group_set_type(target->t_auth_group, $2);
582261758Strasz		free($2);
583261758Strasz		if (error != 0)
584261758Strasz			return (1);
585261758Strasz	}
586261758Strasz	;
587261758Strasz
588261756Strasztarget_chap:	CHAP STR STR
589255570Strasz	{
590255570Strasz		const struct auth *ca;
591255570Strasz
592255570Strasz		if (target->t_auth_group != NULL) {
593255570Strasz			if (target->t_auth_group->ag_name != NULL) {
594261758Strasz				log_warnx("cannot use both auth-group and "
595261758Strasz				    "chap for target \"%s\"",
596261757Strasz				    target->t_name);
597255570Strasz				free($2);
598255570Strasz				free($3);
599255570Strasz				return (1);
600255570Strasz			}
601255570Strasz		} else {
602255570Strasz			target->t_auth_group = auth_group_new(conf, NULL);
603255570Strasz			if (target->t_auth_group == NULL) {
604255570Strasz				free($2);
605255570Strasz				free($3);
606255570Strasz				return (1);
607255570Strasz			}
608255570Strasz			target->t_auth_group->ag_target = target;
609255570Strasz		}
610255570Strasz		ca = auth_new_chap(target->t_auth_group, $2, $3);
611255570Strasz		free($2);
612255570Strasz		free($3);
613255570Strasz		if (ca == NULL)
614255570Strasz			return (1);
615255570Strasz	}
616255570Strasz	;
617255570Strasz
618261756Strasztarget_chap_mutual:	CHAP_MUTUAL STR STR STR STR
619255570Strasz	{
620255570Strasz		const struct auth *ca;
621255570Strasz
622255570Strasz		if (target->t_auth_group != NULL) {
623255570Strasz			if (target->t_auth_group->ag_name != NULL) {
624261758Strasz				log_warnx("cannot use both auth-group and "
625261758Strasz				    "chap-mutual for target \"%s\"",
626261757Strasz				    target->t_name);
627255570Strasz				free($2);
628255570Strasz				free($3);
629255570Strasz				free($4);
630255570Strasz				free($5);
631255570Strasz				return (1);
632255570Strasz			}
633255570Strasz		} else {
634255570Strasz			target->t_auth_group = auth_group_new(conf, NULL);
635255570Strasz			if (target->t_auth_group == NULL) {
636255570Strasz				free($2);
637255570Strasz				free($3);
638255570Strasz				free($4);
639255570Strasz				free($5);
640255570Strasz				return (1);
641255570Strasz			}
642255570Strasz			target->t_auth_group->ag_target = target;
643255570Strasz		}
644255570Strasz		ca = auth_new_chap_mutual(target->t_auth_group,
645255570Strasz		    $2, $3, $4, $5);
646255570Strasz		free($2);
647255570Strasz		free($3);
648255570Strasz		free($4);
649255570Strasz		free($5);
650255570Strasz		if (ca == NULL)
651255570Strasz			return (1);
652255570Strasz	}
653255570Strasz	;
654255570Strasz
655261756Strasztarget_initiator_name:	INITIATOR_NAME STR
656261754Strasz	{
657261754Strasz		const struct auth_name *an;
658261754Strasz
659261754Strasz		if (target->t_auth_group != NULL) {
660261754Strasz			if (target->t_auth_group->ag_name != NULL) {
661261758Strasz				log_warnx("cannot use both auth-group and "
662261754Strasz				    "initiator-name for target \"%s\"",
663261757Strasz				    target->t_name);
664261754Strasz				free($2);
665261754Strasz				return (1);
666261754Strasz			}
667261754Strasz		} else {
668261754Strasz			target->t_auth_group = auth_group_new(conf, NULL);
669261754Strasz			if (target->t_auth_group == NULL) {
670261754Strasz				free($2);
671261754Strasz				return (1);
672261754Strasz			}
673261754Strasz			target->t_auth_group->ag_target = target;
674261754Strasz		}
675261754Strasz		an = auth_name_new(target->t_auth_group, $2);
676261754Strasz		free($2);
677261754Strasz		if (an == NULL)
678261754Strasz			return (1);
679261754Strasz	}
680261754Strasz	;
681261754Strasz
682261756Strasztarget_initiator_portal:	INITIATOR_PORTAL STR
683261754Strasz	{
684261754Strasz		const struct auth_portal *ap;
685261754Strasz
686261754Strasz		if (target->t_auth_group != NULL) {
687261754Strasz			if (target->t_auth_group->ag_name != NULL) {
688261758Strasz				log_warnx("cannot use both auth-group and "
689261754Strasz				    "initiator-portal for target \"%s\"",
690261757Strasz				    target->t_name);
691261754Strasz				free($2);
692261754Strasz				return (1);
693261754Strasz			}
694261754Strasz		} else {
695261754Strasz			target->t_auth_group = auth_group_new(conf, NULL);
696261754Strasz			if (target->t_auth_group == NULL) {
697261754Strasz				free($2);
698261754Strasz				return (1);
699261754Strasz			}
700261754Strasz			target->t_auth_group->ag_target = target;
701261754Strasz		}
702261754Strasz		ap = auth_portal_new(target->t_auth_group, $2);
703261754Strasz		free($2);
704261754Strasz		if (ap == NULL)
705261754Strasz			return (1);
706261754Strasz	}
707261754Strasz	;
708261754Strasz
709278322Smavtarget_portal_group:	PORTAL_GROUP STR STR
710255570Strasz	{
711278322Smav		struct portal_group *tpg;
712278322Smav		struct auth_group *tag;
713278322Smav		struct port *tp;
714278322Smav
715278322Smav		tpg = portal_group_find(conf, $2);
716278322Smav		if (tpg == NULL) {
717278322Smav			log_warnx("unknown portal-group \"%s\" for target "
718278322Smav			    "\"%s\"", $2, target->t_name);
719255570Strasz			free($2);
720278322Smav			free($3);
721255570Strasz			return (1);
722255570Strasz		}
723278322Smav		tag = auth_group_find(conf, $3);
724278322Smav		if (tag == NULL) {
725278322Smav			log_warnx("unknown auth-group \"%s\" for target "
726278322Smav			    "\"%s\"", $3, target->t_name);
727278322Smav			free($2);
728278322Smav			free($3);
729278322Smav			return (1);
730278322Smav		}
731278322Smav		tp = port_new(conf, target, tpg);
732278322Smav		if (tp == NULL) {
733278322Smav			log_warnx("can't link portal-group \"%s\" to target "
734278322Smav			    "\"%s\"", $2, target->t_name);
735278322Smav			free($2);
736278322Smav			return (1);
737278322Smav		}
738278322Smav		tp->p_auth_group = tag;
739278322Smav		free($2);
740278322Smav		free($3);
741278322Smav	}
742278322Smav	|		PORTAL_GROUP STR
743278322Smav	{
744278322Smav		struct portal_group *tpg;
745278322Smav		struct port *tp;
746278322Smav
747278322Smav		tpg = portal_group_find(conf, $2);
748278322Smav		if (tpg == NULL) {
749255570Strasz			log_warnx("unknown portal-group \"%s\" for target "
750261757Strasz			    "\"%s\"", $2, target->t_name);
751255570Strasz			free($2);
752255570Strasz			return (1);
753255570Strasz		}
754278322Smav		tp = port_new(conf, target, tpg);
755278322Smav		if (tp == NULL) {
756278322Smav			log_warnx("can't link portal-group \"%s\" to target "
757278322Smav			    "\"%s\"", $2, target->t_name);
758278322Smav			free($2);
759278322Smav			return (1);
760278322Smav		}
761255570Strasz		free($2);
762255570Strasz	}
763255570Strasz	;
764255570Strasz
765278354Smavtarget_port:	PORT STR
766278354Smav	{
767278354Smav		struct pport *pp;
768278354Smav		struct port *tp;
769278354Smav
770278354Smav		pp = pport_find(conf, $2);
771278354Smav		if (pp == NULL) {
772278354Smav			log_warnx("unknown port \"%s\" for target \"%s\"",
773278354Smav			    $2, target->t_name);
774278354Smav			free($2);
775278354Smav			return (1);
776278354Smav		}
777278354Smav		if (!TAILQ_EMPTY(&pp->pp_ports)) {
778278354Smav			log_warnx("can't link port \"%s\" to target \"%s\", "
779278354Smav			    "port already linked to some target",
780278354Smav			    $2, target->t_name);
781278354Smav			free($2);
782278354Smav			return (1);
783278354Smav		}
784278354Smav		tp = port_new_pp(conf, target, pp);
785278354Smav		if (tp == NULL) {
786278354Smav			log_warnx("can't link port \"%s\" to target \"%s\"",
787278354Smav			    $2, target->t_name);
788278354Smav			free($2);
789278354Smav			return (1);
790278354Smav		}
791278354Smav		free($2);
792278354Smav	}
793278354Smav	;
794278354Smav
795274308Strasztarget_redirect:	REDIRECT STR
796274308Strasz	{
797274308Strasz		int error;
798274308Strasz
799274308Strasz		error = target_set_redirection(target, $2);
800274308Strasz		free($2);
801274308Strasz		if (error != 0)
802274308Strasz			return (1);
803274308Strasz	}
804274308Strasz	;
805274308Strasz
806261756Strasztarget_lun:	LUN lun_number
807261756Strasz    OPENING_BRACKET lun_entries CLOSING_BRACKET
808255570Strasz	{
809255570Strasz		lun = NULL;
810255570Strasz	}
811255570Strasz	;
812255570Strasz
813273768Straszlun_number:	STR
814255570Strasz	{
815273768Strasz		uint64_t tmp;
816279314Strasz		int ret;
817278037Smav		char *name;
818273768Strasz
819273768Strasz		if (expand_number($1, &tmp) != 0) {
820273770Strasz			yyerror("invalid numeric value");
821273768Strasz			free($1);
822273768Strasz			return (1);
823273768Strasz		}
824273768Strasz
825279314Strasz		ret = asprintf(&name, "%s,lun,%ju", target->t_name, tmp);
826279314Strasz		if (ret <= 0)
827279314Strasz			log_err(1, "asprintf");
828278037Smav		lun = lun_new(conf, name);
829255570Strasz		if (lun == NULL)
830255570Strasz			return (1);
831278037Smav
832278037Smav		lun_set_scsiname(lun, name);
833278037Smav		target->t_luns[tmp] = lun;
834255570Strasz	}
835255570Strasz	;
836255570Strasz
837278037Smavtarget_lun_ref:	LUN STR STR
838278037Smav	{
839278037Smav		uint64_t tmp;
840278037Smav
841278037Smav		if (expand_number($2, &tmp) != 0) {
842278037Smav			yyerror("invalid numeric value");
843278037Smav			free($2);
844278037Smav			free($3);
845278037Smav			return (1);
846278037Smav		}
847278037Smav		free($2);
848278037Smav
849278037Smav		lun = lun_find(conf, $3);
850278037Smav		free($3);
851278037Smav		if (lun == NULL)
852278037Smav			return (1);
853278037Smav
854278037Smav		target->t_luns[tmp] = lun;
855278037Smav	}
856278037Smav	;
857278037Smav
858261756Straszlun_entries:
859255570Strasz	|
860261756Strasz	lun_entries lun_entry
861273820Strasz	|
862273820Strasz	lun_entries lun_entry SEMICOLON
863255570Strasz	;
864255570Strasz
865261756Straszlun_entry:
866261756Strasz	lun_backend
867255570Strasz	|
868261756Strasz	lun_blocksize
869255570Strasz	|
870261756Strasz	lun_device_id
871255570Strasz	|
872288310Smav	lun_device_type
873288310Smav	|
874287823Smav	lun_ctl_lun
875287823Smav	|
876261756Strasz	lun_option
877255570Strasz	|
878261756Strasz	lun_path
879255570Strasz	|
880261756Strasz	lun_serial
881255570Strasz	|
882261756Strasz	lun_size
883255570Strasz	;
884255570Strasz
885261756Straszlun_backend:	BACKEND STR
886255570Strasz	{
887255570Strasz		if (lun->l_backend != NULL) {
888278037Smav			log_warnx("backend for lun \"%s\" "
889255570Strasz			    "specified more than once",
890278037Smav			    lun->l_name);
891255570Strasz			free($2);
892255570Strasz			return (1);
893255570Strasz		}
894255570Strasz		lun_set_backend(lun, $2);
895255570Strasz		free($2);
896255570Strasz	}
897255570Strasz	;
898255570Strasz
899273768Straszlun_blocksize:	BLOCKSIZE STR
900255570Strasz	{
901273768Strasz		uint64_t tmp;
902273768Strasz
903273768Strasz		if (expand_number($2, &tmp) != 0) {
904273770Strasz			yyerror("invalid numeric value");
905273768Strasz			free($2);
906273768Strasz			return (1);
907273768Strasz		}
908273768Strasz
909255570Strasz		if (lun->l_blocksize != 0) {
910278037Smav			log_warnx("blocksize for lun \"%s\" "
911255570Strasz			    "specified more than once",
912278037Smav			    lun->l_name);
913255570Strasz			return (1);
914255570Strasz		}
915273768Strasz		lun_set_blocksize(lun, tmp);
916255570Strasz	}
917255570Strasz	;
918255570Strasz
919261756Straszlun_device_id:	DEVICE_ID STR
920255570Strasz	{
921255570Strasz		if (lun->l_device_id != NULL) {
922278037Smav			log_warnx("device_id for lun \"%s\" "
923255570Strasz			    "specified more than once",
924278037Smav			    lun->l_name);
925255570Strasz			free($2);
926255570Strasz			return (1);
927255570Strasz		}
928255570Strasz		lun_set_device_id(lun, $2);
929255570Strasz		free($2);
930255570Strasz	}
931255570Strasz	;
932255570Strasz
933288310Smavlun_device_type:	DEVICE_TYPE STR
934288310Smav	{
935288310Smav		uint64_t tmp;
936288310Smav
937288310Smav		if (strcasecmp($2, "disk") == 0 ||
938288310Smav		    strcasecmp($2, "direct") == 0)
939288310Smav			tmp = 0;
940288310Smav		else if (strcasecmp($2, "processor") == 0)
941288310Smav			tmp = 3;
942288310Smav		else if (strcasecmp($2, "cd") == 0 ||
943288310Smav		    strcasecmp($2, "cdrom") == 0 ||
944288310Smav		    strcasecmp($2, "dvd") == 0 ||
945288310Smav		    strcasecmp($2, "dvdrom") == 0)
946288310Smav			tmp = 5;
947288310Smav		else if (expand_number($2, &tmp) != 0 ||
948288310Smav		    tmp > 15) {
949288310Smav			yyerror("invalid numeric value");
950288310Smav			free($2);
951288310Smav			return (1);
952288310Smav		}
953288310Smav
954288310Smav		lun_set_device_type(lun, tmp);
955288310Smav	}
956288310Smav	;
957288310Smav
958287823Smavlun_ctl_lun:	CTL_LUN STR
959287823Smav	{
960287823Smav		uint64_t tmp;
961287823Smav
962287823Smav		if (expand_number($2, &tmp) != 0) {
963287823Smav			yyerror("invalid numeric value");
964287823Smav			free($2);
965287823Smav			return (1);
966287823Smav		}
967287823Smav
968287823Smav		if (lun->l_ctl_lun >= 0) {
969287823Smav			log_warnx("ctl_lun for lun \"%s\" "
970287823Smav			    "specified more than once",
971287823Smav			    lun->l_name);
972287823Smav			return (1);
973287823Smav		}
974287823Smav		lun_set_ctl_lun(lun, tmp);
975287823Smav	}
976287823Smav	;
977287823Smav
978261756Straszlun_option:	OPTION STR STR
979255570Strasz	{
980290615Smav		struct option *o;
981273464Strasz
982290615Smav		o = option_new(&lun->l_options, $2, $3);
983255570Strasz		free($2);
984255570Strasz		free($3);
985290615Smav		if (o == NULL)
986255570Strasz			return (1);
987255570Strasz	}
988255570Strasz	;
989255570Strasz
990261756Straszlun_path:	PATH STR
991255570Strasz	{
992255570Strasz		if (lun->l_path != NULL) {
993278037Smav			log_warnx("path for lun \"%s\" "
994255570Strasz			    "specified more than once",
995278037Smav			    lun->l_name);
996255570Strasz			free($2);
997255570Strasz			return (1);
998255570Strasz		}
999255570Strasz		lun_set_path(lun, $2);
1000255570Strasz		free($2);
1001255570Strasz	}
1002255570Strasz	;
1003255570Strasz
1004261756Straszlun_serial:	SERIAL STR
1005255570Strasz	{
1006255570Strasz		if (lun->l_serial != NULL) {
1007278037Smav			log_warnx("serial for lun \"%s\" "
1008255570Strasz			    "specified more than once",
1009278037Smav			    lun->l_name);
1010255570Strasz			free($2);
1011255570Strasz			return (1);
1012255570Strasz		}
1013255570Strasz		lun_set_serial(lun, $2);
1014255570Strasz		free($2);
1015273768Strasz	}
1016273768Strasz	;
1017273768Strasz
1018273768Straszlun_size:	SIZE STR
1019267833Sjpaetzel	{
1020273768Strasz		uint64_t tmp;
1021267833Sjpaetzel
1022273768Strasz		if (expand_number($2, &tmp) != 0) {
1023273770Strasz			yyerror("invalid numeric value");
1024273768Strasz			free($2);
1025267833Sjpaetzel			return (1);
1026267833Sjpaetzel		}
1027255570Strasz
1028255570Strasz		if (lun->l_size != 0) {
1029278037Smav			log_warnx("size for lun \"%s\" "
1030255570Strasz			    "specified more than once",
1031278037Smav			    lun->l_name);
1032255570Strasz			return (1);
1033255570Strasz		}
1034273768Strasz		lun_set_size(lun, tmp);
1035255570Strasz	}
1036255570Strasz	;
1037255570Strasz%%
1038255570Strasz
1039255570Straszvoid
1040255570Straszyyerror(const char *str)
1041255570Strasz{
1042255570Strasz
1043255570Strasz	log_warnx("error in configuration file at line %d near '%s': %s",
1044255570Strasz	    lineno, yytext, str);
1045255570Strasz}
1046255570Strasz
1047295212Sjceelint
1048295212Sjceelparse_conf(struct conf *newconf, const char *path)
1049255570Strasz{
1050255570Strasz	int error;
1051255570Strasz
1052295212Sjceel	conf = newconf;
1053255570Strasz	yyin = fopen(path, "r");
1054255570Strasz	if (yyin == NULL) {
1055255570Strasz		log_warn("unable to open configuration file %s", path);
1056295212Sjceel		return (1);
1057255570Strasz	}
1058295212Sjceel
1059261767Strasz	lineno = 1;
1060255570Strasz	yyrestart(yyin);
1061255570Strasz	error = yyparse();
1062255570Strasz	auth_group = NULL;
1063255570Strasz	portal_group = NULL;
1064255570Strasz	target = NULL;
1065255570Strasz	lun = NULL;
1066255570Strasz	fclose(yyin);
1067255570Strasz
1068295212Sjceel	return (error);
1069255570Strasz}
1070