Deleted Added
full compact
parse.y (275244) parse.y (275245)
1%{
2/*-
3 * Copyright (c) 2012 The FreeBSD Foundation
4 * All rights reserved.
5 *
6 * This software was developed by Edward Tomasz Napierala under sponsorship
7 * from the FreeBSD Foundation.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
19 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
22 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28 * SUCH DAMAGE.
29 *
1%{
2/*-
3 * Copyright (c) 2012 The FreeBSD Foundation
4 * All rights reserved.
5 *
6 * This software was developed by Edward Tomasz Napierala under sponsorship
7 * from the FreeBSD Foundation.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
19 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
22 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28 * SUCH DAMAGE.
29 *
30 * $FreeBSD: stable/10/usr.sbin/ctld/parse.y 275244 2014-11-29 15:32:15Z trasz $
30 * $FreeBSD: stable/10/usr.sbin/ctld/parse.y 275245 2014-11-29 15:34:17Z trasz $
31 */
32
33#include <sys/queue.h>
34#include <sys/types.h>
35#include <sys/stat.h>
36#include <assert.h>
37#include <stdio.h>
38#include <stdint.h>
39#include <stdlib.h>
40#include <string.h>
41
42#include "ctld.h"
43
44extern FILE *yyin;
45extern char *yytext;
46extern int lineno;
47
48static struct conf *conf = NULL;
49static struct auth_group *auth_group = NULL;
50static struct portal_group *portal_group = NULL;
51static struct target *target = NULL;
52static struct lun *lun = NULL;
53
54extern void yyerror(const char *);
55extern int yylex(void);
56extern void yyrestart(FILE *);
57
58%}
59
60%token ALIAS AUTH_GROUP AUTH_TYPE BACKEND BLOCKSIZE CHAP CHAP_MUTUAL
61%token CLOSING_BRACKET DEBUG DEVICE_ID DISCOVERY_AUTH_GROUP DISCOVERY_FILTER
62%token INITIATOR_NAME INITIATOR_PORTAL LISTEN LISTEN_ISER LUN MAXPROC
63%token OPENING_BRACKET OPTION PATH PIDFILE PORTAL_GROUP SERIAL SIZE STR
64%token TARGET TIMEOUT ISNS_SERVER ISNS_PERIOD ISNS_TIMEOUT
65
66%union
67{
68 char *str;
69}
70
71%token <str> STR
72
73%%
74
75statements:
76 |
77 statements statement
78 ;
79
80statement:
81 debug
82 |
83 timeout
84 |
85 maxproc
86 |
87 pidfile
88 |
89 isns_server
90 |
91 isns_period
92 |
93 isns_timeout
94 |
95 auth_group
96 |
97 portal_group
98 |
99 target
100 ;
101
102debug: DEBUG STR
103 {
104 uint64_t tmp;
105
106 if (expand_number($2, &tmp) != 0) {
107 yyerror("invalid numeric value");
108 free($2);
109 return (1);
110 }
111
112 conf->conf_debug = tmp;
113 }
114 ;
115
116timeout: TIMEOUT STR
117 {
118 uint64_t tmp;
119
120 if (expand_number($2, &tmp) != 0) {
121 yyerror("invalid numeric value");
122 free($2);
123 return (1);
124 }
125
126 conf->conf_timeout = tmp;
127 }
128 ;
129
130maxproc: MAXPROC STR
131 {
132 uint64_t tmp;
133
134 if (expand_number($2, &tmp) != 0) {
135 yyerror("invalid numeric value");
136 free($2);
137 return (1);
138 }
139
140 conf->conf_maxproc = tmp;
141 }
142 ;
143
144pidfile: PIDFILE STR
145 {
146 if (conf->conf_pidfile_path != NULL) {
147 log_warnx("pidfile specified more than once");
148 free($2);
149 return (1);
150 }
151 conf->conf_pidfile_path = $2;
152 }
153 ;
154
155isns_server: ISNS_SERVER STR
156 {
157 int error;
158
159 error = isns_new(conf, $2);
160 free($2);
161 if (error != 0)
162 return (1);
163 }
164 ;
165
166isns_period: ISNS_PERIOD STR
167 {
168 uint64_t tmp;
169
170 if (expand_number($2, &tmp) != 0) {
171 yyerror("invalid numeric value");
172 free($2);
173 return (1);
174 }
175
176 conf->conf_isns_period = tmp;
177 }
178 ;
179
180isns_timeout: ISNS_TIMEOUT STR
181 {
182 uint64_t tmp;
183
184 if (expand_number($2, &tmp) != 0) {
185 yyerror("invalid numeric value");
186 free($2);
187 return (1);
188 }
189
190 conf->conf_isns_timeout = tmp;
191 }
192 ;
193
194auth_group: AUTH_GROUP auth_group_name
195 OPENING_BRACKET auth_group_entries CLOSING_BRACKET
196 {
197 auth_group = NULL;
198 }
199 ;
200
201auth_group_name: STR
202 {
203 /*
204 * Make it possible to redefine default
205 * auth-group. but only once.
206 */
207 if (strcmp($1, "default") == 0 &&
208 conf->conf_default_ag_defined == false) {
209 auth_group = auth_group_find(conf, $1);
210 conf->conf_default_ag_defined = true;
211 } else {
212 auth_group = auth_group_new(conf, $1);
213 }
214 free($1);
215 if (auth_group == NULL)
216 return (1);
217 }
218 ;
219
220auth_group_entries:
221 |
222 auth_group_entries auth_group_entry
223 ;
224
225auth_group_entry:
226 auth_group_auth_type
227 |
228 auth_group_chap
229 |
230 auth_group_chap_mutual
231 |
232 auth_group_initiator_name
233 |
234 auth_group_initiator_portal
235 ;
236
237auth_group_auth_type: AUTH_TYPE STR
238 {
239 int error;
240
31 */
32
33#include <sys/queue.h>
34#include <sys/types.h>
35#include <sys/stat.h>
36#include <assert.h>
37#include <stdio.h>
38#include <stdint.h>
39#include <stdlib.h>
40#include <string.h>
41
42#include "ctld.h"
43
44extern FILE *yyin;
45extern char *yytext;
46extern int lineno;
47
48static struct conf *conf = NULL;
49static struct auth_group *auth_group = NULL;
50static struct portal_group *portal_group = NULL;
51static struct target *target = NULL;
52static struct lun *lun = NULL;
53
54extern void yyerror(const char *);
55extern int yylex(void);
56extern void yyrestart(FILE *);
57
58%}
59
60%token ALIAS AUTH_GROUP AUTH_TYPE BACKEND BLOCKSIZE CHAP CHAP_MUTUAL
61%token CLOSING_BRACKET DEBUG DEVICE_ID DISCOVERY_AUTH_GROUP DISCOVERY_FILTER
62%token INITIATOR_NAME INITIATOR_PORTAL LISTEN LISTEN_ISER LUN MAXPROC
63%token OPENING_BRACKET OPTION PATH PIDFILE PORTAL_GROUP SERIAL SIZE STR
64%token TARGET TIMEOUT ISNS_SERVER ISNS_PERIOD ISNS_TIMEOUT
65
66%union
67{
68 char *str;
69}
70
71%token <str> STR
72
73%%
74
75statements:
76 |
77 statements statement
78 ;
79
80statement:
81 debug
82 |
83 timeout
84 |
85 maxproc
86 |
87 pidfile
88 |
89 isns_server
90 |
91 isns_period
92 |
93 isns_timeout
94 |
95 auth_group
96 |
97 portal_group
98 |
99 target
100 ;
101
102debug: DEBUG STR
103 {
104 uint64_t tmp;
105
106 if (expand_number($2, &tmp) != 0) {
107 yyerror("invalid numeric value");
108 free($2);
109 return (1);
110 }
111
112 conf->conf_debug = tmp;
113 }
114 ;
115
116timeout: TIMEOUT STR
117 {
118 uint64_t tmp;
119
120 if (expand_number($2, &tmp) != 0) {
121 yyerror("invalid numeric value");
122 free($2);
123 return (1);
124 }
125
126 conf->conf_timeout = tmp;
127 }
128 ;
129
130maxproc: MAXPROC STR
131 {
132 uint64_t tmp;
133
134 if (expand_number($2, &tmp) != 0) {
135 yyerror("invalid numeric value");
136 free($2);
137 return (1);
138 }
139
140 conf->conf_maxproc = tmp;
141 }
142 ;
143
144pidfile: PIDFILE STR
145 {
146 if (conf->conf_pidfile_path != NULL) {
147 log_warnx("pidfile specified more than once");
148 free($2);
149 return (1);
150 }
151 conf->conf_pidfile_path = $2;
152 }
153 ;
154
155isns_server: ISNS_SERVER STR
156 {
157 int error;
158
159 error = isns_new(conf, $2);
160 free($2);
161 if (error != 0)
162 return (1);
163 }
164 ;
165
166isns_period: ISNS_PERIOD STR
167 {
168 uint64_t tmp;
169
170 if (expand_number($2, &tmp) != 0) {
171 yyerror("invalid numeric value");
172 free($2);
173 return (1);
174 }
175
176 conf->conf_isns_period = tmp;
177 }
178 ;
179
180isns_timeout: ISNS_TIMEOUT STR
181 {
182 uint64_t tmp;
183
184 if (expand_number($2, &tmp) != 0) {
185 yyerror("invalid numeric value");
186 free($2);
187 return (1);
188 }
189
190 conf->conf_isns_timeout = tmp;
191 }
192 ;
193
194auth_group: AUTH_GROUP auth_group_name
195 OPENING_BRACKET auth_group_entries CLOSING_BRACKET
196 {
197 auth_group = NULL;
198 }
199 ;
200
201auth_group_name: STR
202 {
203 /*
204 * Make it possible to redefine default
205 * auth-group. but only once.
206 */
207 if (strcmp($1, "default") == 0 &&
208 conf->conf_default_ag_defined == false) {
209 auth_group = auth_group_find(conf, $1);
210 conf->conf_default_ag_defined = true;
211 } else {
212 auth_group = auth_group_new(conf, $1);
213 }
214 free($1);
215 if (auth_group == NULL)
216 return (1);
217 }
218 ;
219
220auth_group_entries:
221 |
222 auth_group_entries auth_group_entry
223 ;
224
225auth_group_entry:
226 auth_group_auth_type
227 |
228 auth_group_chap
229 |
230 auth_group_chap_mutual
231 |
232 auth_group_initiator_name
233 |
234 auth_group_initiator_portal
235 ;
236
237auth_group_auth_type: AUTH_TYPE STR
238 {
239 int error;
240
241 error = auth_group_set_type_str(auth_group, $2);
241 error = auth_group_set_type(auth_group, $2);
242 free($2);
243 if (error != 0)
244 return (1);
245 }
246 ;
247
248auth_group_chap: CHAP STR STR
249 {
250 const struct auth *ca;
251
252 ca = auth_new_chap(auth_group, $2, $3);
253 free($2);
254 free($3);
255 if (ca == NULL)
256 return (1);
257 }
258 ;
259
260auth_group_chap_mutual: CHAP_MUTUAL STR STR STR STR
261 {
262 const struct auth *ca;
263
264 ca = auth_new_chap_mutual(auth_group, $2, $3, $4, $5);
265 free($2);
266 free($3);
267 free($4);
268 free($5);
269 if (ca == NULL)
270 return (1);
271 }
272 ;
273
274auth_group_initiator_name: INITIATOR_NAME STR
275 {
276 const struct auth_name *an;
277
278 an = auth_name_new(auth_group, $2);
279 free($2);
280 if (an == NULL)
281 return (1);
282 }
283 ;
284
285auth_group_initiator_portal: INITIATOR_PORTAL STR
286 {
287 const struct auth_portal *ap;
288
289 ap = auth_portal_new(auth_group, $2);
290 free($2);
291 if (ap == NULL)
292 return (1);
293 }
294 ;
295
296portal_group: PORTAL_GROUP portal_group_name
297 OPENING_BRACKET portal_group_entries CLOSING_BRACKET
298 {
299 portal_group = NULL;
300 }
301 ;
302
303portal_group_name: STR
304 {
305 /*
306 * Make it possible to redefine default
307 * portal-group. but only once.
308 */
309 if (strcmp($1, "default") == 0 &&
310 conf->conf_default_pg_defined == false) {
311 portal_group = portal_group_find(conf, $1);
312 conf->conf_default_pg_defined = true;
313 } else {
314 portal_group = portal_group_new(conf, $1);
315 }
316 free($1);
317 if (portal_group == NULL)
318 return (1);
319 }
320 ;
321
322portal_group_entries:
323 |
324 portal_group_entries portal_group_entry
325 ;
326
327portal_group_entry:
328 portal_group_discovery_auth_group
329 |
330 portal_group_discovery_filter
331 |
332 portal_group_listen
333 |
334 portal_group_listen_iser
335 ;
336
337portal_group_discovery_auth_group: DISCOVERY_AUTH_GROUP STR
338 {
339 if (portal_group->pg_discovery_auth_group != NULL) {
340 log_warnx("discovery-auth-group for portal-group "
341 "\"%s\" specified more than once",
342 portal_group->pg_name);
343 return (1);
344 }
345 portal_group->pg_discovery_auth_group =
346 auth_group_find(conf, $2);
347 if (portal_group->pg_discovery_auth_group == NULL) {
348 log_warnx("unknown discovery-auth-group \"%s\" "
349 "for portal-group \"%s\"",
350 $2, portal_group->pg_name);
351 return (1);
352 }
353 free($2);
354 }
355 ;
356
357portal_group_discovery_filter: DISCOVERY_FILTER STR
358 {
359 int error;
360
242 free($2);
243 if (error != 0)
244 return (1);
245 }
246 ;
247
248auth_group_chap: CHAP STR STR
249 {
250 const struct auth *ca;
251
252 ca = auth_new_chap(auth_group, $2, $3);
253 free($2);
254 free($3);
255 if (ca == NULL)
256 return (1);
257 }
258 ;
259
260auth_group_chap_mutual: CHAP_MUTUAL STR STR STR STR
261 {
262 const struct auth *ca;
263
264 ca = auth_new_chap_mutual(auth_group, $2, $3, $4, $5);
265 free($2);
266 free($3);
267 free($4);
268 free($5);
269 if (ca == NULL)
270 return (1);
271 }
272 ;
273
274auth_group_initiator_name: INITIATOR_NAME STR
275 {
276 const struct auth_name *an;
277
278 an = auth_name_new(auth_group, $2);
279 free($2);
280 if (an == NULL)
281 return (1);
282 }
283 ;
284
285auth_group_initiator_portal: INITIATOR_PORTAL STR
286 {
287 const struct auth_portal *ap;
288
289 ap = auth_portal_new(auth_group, $2);
290 free($2);
291 if (ap == NULL)
292 return (1);
293 }
294 ;
295
296portal_group: PORTAL_GROUP portal_group_name
297 OPENING_BRACKET portal_group_entries CLOSING_BRACKET
298 {
299 portal_group = NULL;
300 }
301 ;
302
303portal_group_name: STR
304 {
305 /*
306 * Make it possible to redefine default
307 * portal-group. but only once.
308 */
309 if (strcmp($1, "default") == 0 &&
310 conf->conf_default_pg_defined == false) {
311 portal_group = portal_group_find(conf, $1);
312 conf->conf_default_pg_defined = true;
313 } else {
314 portal_group = portal_group_new(conf, $1);
315 }
316 free($1);
317 if (portal_group == NULL)
318 return (1);
319 }
320 ;
321
322portal_group_entries:
323 |
324 portal_group_entries portal_group_entry
325 ;
326
327portal_group_entry:
328 portal_group_discovery_auth_group
329 |
330 portal_group_discovery_filter
331 |
332 portal_group_listen
333 |
334 portal_group_listen_iser
335 ;
336
337portal_group_discovery_auth_group: DISCOVERY_AUTH_GROUP STR
338 {
339 if (portal_group->pg_discovery_auth_group != NULL) {
340 log_warnx("discovery-auth-group for portal-group "
341 "\"%s\" specified more than once",
342 portal_group->pg_name);
343 return (1);
344 }
345 portal_group->pg_discovery_auth_group =
346 auth_group_find(conf, $2);
347 if (portal_group->pg_discovery_auth_group == NULL) {
348 log_warnx("unknown discovery-auth-group \"%s\" "
349 "for portal-group \"%s\"",
350 $2, portal_group->pg_name);
351 return (1);
352 }
353 free($2);
354 }
355 ;
356
357portal_group_discovery_filter: DISCOVERY_FILTER STR
358 {
359 int error;
360
361 error = portal_group_set_filter_str(portal_group, $2);
361 error = portal_group_set_filter(portal_group, $2);
362 free($2);
363 if (error != 0)
364 return (1);
365 }
366 ;
367
368portal_group_listen: LISTEN STR
369 {
370 int error;
371
372 error = portal_group_add_listen(portal_group, $2, false);
373 free($2);
374 if (error != 0)
375 return (1);
376 }
377 ;
378
379portal_group_listen_iser: LISTEN_ISER STR
380 {
381 int error;
382
383 error = portal_group_add_listen(portal_group, $2, true);
384 free($2);
385 if (error != 0)
386 return (1);
387 }
388 ;
389
390target: TARGET target_name
391 OPENING_BRACKET target_entries CLOSING_BRACKET
392 {
393 target = NULL;
394 }
395 ;
396
397target_name: STR
398 {
399 target = target_new(conf, $1);
400 free($1);
401 if (target == NULL)
402 return (1);
403 }
404 ;
405
406target_entries:
407 |
408 target_entries target_entry
409 ;
410
411target_entry:
412 target_alias
413 |
414 target_auth_group
415 |
416 target_auth_type
417 |
418 target_chap
419 |
420 target_chap_mutual
421 |
422 target_initiator_name
423 |
424 target_initiator_portal
425 |
426 target_portal_group
427 |
428 target_lun
429 ;
430
431target_alias: ALIAS STR
432 {
433 if (target->t_alias != NULL) {
434 log_warnx("alias for target \"%s\" "
435 "specified more than once", target->t_name);
436 return (1);
437 }
438 target->t_alias = $2;
439 }
440 ;
441
442target_auth_group: AUTH_GROUP STR
443 {
444 if (target->t_auth_group != NULL) {
445 if (target->t_auth_group->ag_name != NULL)
446 log_warnx("auth-group for target \"%s\" "
447 "specified more than once", target->t_name);
448 else
449 log_warnx("cannot use both auth-group and explicit "
450 "authorisations for target \"%s\"",
451 target->t_name);
452 return (1);
453 }
454 target->t_auth_group = auth_group_find(conf, $2);
455 if (target->t_auth_group == NULL) {
456 log_warnx("unknown auth-group \"%s\" for target "
457 "\"%s\"", $2, target->t_name);
458 return (1);
459 }
460 free($2);
461 }
462 ;
463
464target_auth_type: AUTH_TYPE STR
465 {
466 int error;
467
468 if (target->t_auth_group != NULL) {
469 if (target->t_auth_group->ag_name != NULL) {
470 log_warnx("cannot use both auth-group and "
471 "auth-type for target \"%s\"",
472 target->t_name);
473 return (1);
474 }
475 } else {
476 target->t_auth_group = auth_group_new(conf, NULL);
477 if (target->t_auth_group == NULL) {
478 free($2);
479 return (1);
480 }
481 target->t_auth_group->ag_target = target;
482 }
362 free($2);
363 if (error != 0)
364 return (1);
365 }
366 ;
367
368portal_group_listen: LISTEN STR
369 {
370 int error;
371
372 error = portal_group_add_listen(portal_group, $2, false);
373 free($2);
374 if (error != 0)
375 return (1);
376 }
377 ;
378
379portal_group_listen_iser: LISTEN_ISER STR
380 {
381 int error;
382
383 error = portal_group_add_listen(portal_group, $2, true);
384 free($2);
385 if (error != 0)
386 return (1);
387 }
388 ;
389
390target: TARGET target_name
391 OPENING_BRACKET target_entries CLOSING_BRACKET
392 {
393 target = NULL;
394 }
395 ;
396
397target_name: STR
398 {
399 target = target_new(conf, $1);
400 free($1);
401 if (target == NULL)
402 return (1);
403 }
404 ;
405
406target_entries:
407 |
408 target_entries target_entry
409 ;
410
411target_entry:
412 target_alias
413 |
414 target_auth_group
415 |
416 target_auth_type
417 |
418 target_chap
419 |
420 target_chap_mutual
421 |
422 target_initiator_name
423 |
424 target_initiator_portal
425 |
426 target_portal_group
427 |
428 target_lun
429 ;
430
431target_alias: ALIAS STR
432 {
433 if (target->t_alias != NULL) {
434 log_warnx("alias for target \"%s\" "
435 "specified more than once", target->t_name);
436 return (1);
437 }
438 target->t_alias = $2;
439 }
440 ;
441
442target_auth_group: AUTH_GROUP STR
443 {
444 if (target->t_auth_group != NULL) {
445 if (target->t_auth_group->ag_name != NULL)
446 log_warnx("auth-group for target \"%s\" "
447 "specified more than once", target->t_name);
448 else
449 log_warnx("cannot use both auth-group and explicit "
450 "authorisations for target \"%s\"",
451 target->t_name);
452 return (1);
453 }
454 target->t_auth_group = auth_group_find(conf, $2);
455 if (target->t_auth_group == NULL) {
456 log_warnx("unknown auth-group \"%s\" for target "
457 "\"%s\"", $2, target->t_name);
458 return (1);
459 }
460 free($2);
461 }
462 ;
463
464target_auth_type: AUTH_TYPE STR
465 {
466 int error;
467
468 if (target->t_auth_group != NULL) {
469 if (target->t_auth_group->ag_name != NULL) {
470 log_warnx("cannot use both auth-group and "
471 "auth-type for target \"%s\"",
472 target->t_name);
473 return (1);
474 }
475 } else {
476 target->t_auth_group = auth_group_new(conf, NULL);
477 if (target->t_auth_group == NULL) {
478 free($2);
479 return (1);
480 }
481 target->t_auth_group->ag_target = target;
482 }
483 error = auth_group_set_type_str(target->t_auth_group, $2);
483 error = auth_group_set_type(target->t_auth_group, $2);
484 free($2);
485 if (error != 0)
486 return (1);
487 }
488 ;
489
490target_chap: CHAP STR STR
491 {
492 const struct auth *ca;
493
494 if (target->t_auth_group != NULL) {
495 if (target->t_auth_group->ag_name != NULL) {
496 log_warnx("cannot use both auth-group and "
497 "chap for target \"%s\"",
498 target->t_name);
499 free($2);
500 free($3);
501 return (1);
502 }
503 } else {
504 target->t_auth_group = auth_group_new(conf, NULL);
505 if (target->t_auth_group == NULL) {
506 free($2);
507 free($3);
508 return (1);
509 }
510 target->t_auth_group->ag_target = target;
511 }
512 ca = auth_new_chap(target->t_auth_group, $2, $3);
513 free($2);
514 free($3);
515 if (ca == NULL)
516 return (1);
517 }
518 ;
519
520target_chap_mutual: CHAP_MUTUAL STR STR STR STR
521 {
522 const struct auth *ca;
523
524 if (target->t_auth_group != NULL) {
525 if (target->t_auth_group->ag_name != NULL) {
526 log_warnx("cannot use both auth-group and "
527 "chap-mutual for target \"%s\"",
528 target->t_name);
529 free($2);
530 free($3);
531 free($4);
532 free($5);
533 return (1);
534 }
535 } else {
536 target->t_auth_group = auth_group_new(conf, NULL);
537 if (target->t_auth_group == NULL) {
538 free($2);
539 free($3);
540 free($4);
541 free($5);
542 return (1);
543 }
544 target->t_auth_group->ag_target = target;
545 }
546 ca = auth_new_chap_mutual(target->t_auth_group,
547 $2, $3, $4, $5);
548 free($2);
549 free($3);
550 free($4);
551 free($5);
552 if (ca == NULL)
553 return (1);
554 }
555 ;
556
557target_initiator_name: INITIATOR_NAME STR
558 {
559 const struct auth_name *an;
560
561 if (target->t_auth_group != NULL) {
562 if (target->t_auth_group->ag_name != NULL) {
563 log_warnx("cannot use both auth-group and "
564 "initiator-name for target \"%s\"",
565 target->t_name);
566 free($2);
567 return (1);
568 }
569 } else {
570 target->t_auth_group = auth_group_new(conf, NULL);
571 if (target->t_auth_group == NULL) {
572 free($2);
573 return (1);
574 }
575 target->t_auth_group->ag_target = target;
576 }
577 an = auth_name_new(target->t_auth_group, $2);
578 free($2);
579 if (an == NULL)
580 return (1);
581 }
582 ;
583
584target_initiator_portal: INITIATOR_PORTAL STR
585 {
586 const struct auth_portal *ap;
587
588 if (target->t_auth_group != NULL) {
589 if (target->t_auth_group->ag_name != NULL) {
590 log_warnx("cannot use both auth-group and "
591 "initiator-portal for target \"%s\"",
592 target->t_name);
593 free($2);
594 return (1);
595 }
596 } else {
597 target->t_auth_group = auth_group_new(conf, NULL);
598 if (target->t_auth_group == NULL) {
599 free($2);
600 return (1);
601 }
602 target->t_auth_group->ag_target = target;
603 }
604 ap = auth_portal_new(target->t_auth_group, $2);
605 free($2);
606 if (ap == NULL)
607 return (1);
608 }
609 ;
610
611target_portal_group: PORTAL_GROUP STR
612 {
613 if (target->t_portal_group != NULL) {
614 log_warnx("portal-group for target \"%s\" "
615 "specified more than once", target->t_name);
616 free($2);
617 return (1);
618 }
619 target->t_portal_group = portal_group_find(conf, $2);
620 if (target->t_portal_group == NULL) {
621 log_warnx("unknown portal-group \"%s\" for target "
622 "\"%s\"", $2, target->t_name);
623 free($2);
624 return (1);
625 }
626 free($2);
627 }
628 ;
629
630target_lun: LUN lun_number
631 OPENING_BRACKET lun_entries CLOSING_BRACKET
632 {
633 lun = NULL;
634 }
635 ;
636
637lun_number: STR
638 {
639 uint64_t tmp;
640
641 if (expand_number($1, &tmp) != 0) {
642 yyerror("invalid numeric value");
643 free($1);
644 return (1);
645 }
646
647 lun = lun_new(target, tmp);
648 if (lun == NULL)
649 return (1);
650 }
651 ;
652
653lun_entries:
654 |
655 lun_entries lun_entry
656 ;
657
658lun_entry:
659 lun_backend
660 |
661 lun_blocksize
662 |
663 lun_device_id
664 |
665 lun_option
666 |
667 lun_path
668 |
669 lun_serial
670 |
671 lun_size
672 ;
673
674lun_backend: BACKEND STR
675 {
676 if (lun->l_backend != NULL) {
677 log_warnx("backend for lun %d, target \"%s\" "
678 "specified more than once",
679 lun->l_lun, target->t_name);
680 free($2);
681 return (1);
682 }
683 lun_set_backend(lun, $2);
684 free($2);
685 }
686 ;
687
688lun_blocksize: BLOCKSIZE STR
689 {
690 uint64_t tmp;
691
692 if (expand_number($2, &tmp) != 0) {
693 yyerror("invalid numeric value");
694 free($2);
695 return (1);
696 }
697
698 if (lun->l_blocksize != 0) {
699 log_warnx("blocksize for lun %d, target \"%s\" "
700 "specified more than once",
701 lun->l_lun, target->t_name);
702 return (1);
703 }
704 lun_set_blocksize(lun, tmp);
705 }
706 ;
707
708lun_device_id: DEVICE_ID STR
709 {
710 if (lun->l_device_id != NULL) {
711 log_warnx("device_id for lun %d, target \"%s\" "
712 "specified more than once",
713 lun->l_lun, target->t_name);
714 free($2);
715 return (1);
716 }
717 lun_set_device_id(lun, $2);
718 free($2);
719 }
720 ;
721
722lun_option: OPTION STR STR
723 {
724 struct lun_option *clo;
725
726 clo = lun_option_new(lun, $2, $3);
727 free($2);
728 free($3);
729 if (clo == NULL)
730 return (1);
731 }
732 ;
733
734lun_path: PATH STR
735 {
736 if (lun->l_path != NULL) {
737 log_warnx("path for lun %d, target \"%s\" "
738 "specified more than once",
739 lun->l_lun, target->t_name);
740 free($2);
741 return (1);
742 }
743 lun_set_path(lun, $2);
744 free($2);
745 }
746 ;
747
748lun_serial: SERIAL STR
749 {
750 if (lun->l_serial != NULL) {
751 log_warnx("serial for lun %d, target \"%s\" "
752 "specified more than once",
753 lun->l_lun, target->t_name);
754 free($2);
755 return (1);
756 }
757 lun_set_serial(lun, $2);
758 free($2);
759 }
760 ;
761
762lun_size: SIZE STR
763 {
764 uint64_t tmp;
765
766 if (expand_number($2, &tmp) != 0) {
767 yyerror("invalid numeric value");
768 free($2);
769 return (1);
770 }
771
772 if (lun->l_size != 0) {
773 log_warnx("size for lun %d, target \"%s\" "
774 "specified more than once",
775 lun->l_lun, target->t_name);
776 return (1);
777 }
778 lun_set_size(lun, tmp);
779 }
780 ;
781%%
782
783void
784yyerror(const char *str)
785{
786
787 log_warnx("error in configuration file at line %d near '%s': %s",
788 lineno, yytext, str);
789}
790
791static void
792check_perms(const char *path)
793{
794 struct stat sb;
795 int error;
796
797 error = stat(path, &sb);
798 if (error != 0) {
799 log_warn("stat");
800 return;
801 }
802 if (sb.st_mode & S_IWOTH) {
803 log_warnx("%s is world-writable", path);
804 } else if (sb.st_mode & S_IROTH) {
805 log_warnx("%s is world-readable", path);
806 } else if (sb.st_mode & S_IXOTH) {
807 /*
808 * Ok, this one doesn't matter, but still do it,
809 * just for consistency.
810 */
811 log_warnx("%s is world-executable", path);
812 }
813
814 /*
815 * XXX: Should we also check for owner != 0?
816 */
817}
818
819struct conf *
820conf_new_from_file(const char *path)
821{
822 struct auth_group *ag;
823 struct portal_group *pg;
824 int error;
825
826 log_debugx("obtaining configuration from %s", path);
827
828 conf = conf_new();
829
830 ag = auth_group_new(conf, "default");
831 assert(ag != NULL);
832
833 ag = auth_group_new(conf, "no-authentication");
834 assert(ag != NULL);
835 ag->ag_type = AG_TYPE_NO_AUTHENTICATION;
836
837 ag = auth_group_new(conf, "no-access");
838 assert(ag != NULL);
839 ag->ag_type = AG_TYPE_DENY;
840
841 pg = portal_group_new(conf, "default");
842 assert(pg != NULL);
843
844 yyin = fopen(path, "r");
845 if (yyin == NULL) {
846 log_warn("unable to open configuration file %s", path);
847 conf_delete(conf);
848 return (NULL);
849 }
850 check_perms(path);
851 lineno = 1;
852 yyrestart(yyin);
853 error = yyparse();
854 auth_group = NULL;
855 portal_group = NULL;
856 target = NULL;
857 lun = NULL;
858 fclose(yyin);
859 if (error != 0) {
860 conf_delete(conf);
861 return (NULL);
862 }
863
864 if (conf->conf_default_ag_defined == false) {
865 log_debugx("auth-group \"default\" not defined; "
866 "going with defaults");
867 ag = auth_group_find(conf, "default");
868 assert(ag != NULL);
869 ag->ag_type = AG_TYPE_DENY;
870 }
871
872 if (conf->conf_default_pg_defined == false) {
873 log_debugx("portal-group \"default\" not defined; "
874 "going with defaults");
875 pg = portal_group_find(conf, "default");
876 assert(pg != NULL);
877 portal_group_add_listen(pg, "0.0.0.0:3260", false);
878 portal_group_add_listen(pg, "[::]:3260", false);
879 }
880
881 conf->conf_kernel_port_on = true;
882
883 error = conf_verify(conf);
884 if (error != 0) {
885 conf_delete(conf);
886 return (NULL);
887 }
888
889 return (conf);
890}
484 free($2);
485 if (error != 0)
486 return (1);
487 }
488 ;
489
490target_chap: CHAP STR STR
491 {
492 const struct auth *ca;
493
494 if (target->t_auth_group != NULL) {
495 if (target->t_auth_group->ag_name != NULL) {
496 log_warnx("cannot use both auth-group and "
497 "chap for target \"%s\"",
498 target->t_name);
499 free($2);
500 free($3);
501 return (1);
502 }
503 } else {
504 target->t_auth_group = auth_group_new(conf, NULL);
505 if (target->t_auth_group == NULL) {
506 free($2);
507 free($3);
508 return (1);
509 }
510 target->t_auth_group->ag_target = target;
511 }
512 ca = auth_new_chap(target->t_auth_group, $2, $3);
513 free($2);
514 free($3);
515 if (ca == NULL)
516 return (1);
517 }
518 ;
519
520target_chap_mutual: CHAP_MUTUAL STR STR STR STR
521 {
522 const struct auth *ca;
523
524 if (target->t_auth_group != NULL) {
525 if (target->t_auth_group->ag_name != NULL) {
526 log_warnx("cannot use both auth-group and "
527 "chap-mutual for target \"%s\"",
528 target->t_name);
529 free($2);
530 free($3);
531 free($4);
532 free($5);
533 return (1);
534 }
535 } else {
536 target->t_auth_group = auth_group_new(conf, NULL);
537 if (target->t_auth_group == NULL) {
538 free($2);
539 free($3);
540 free($4);
541 free($5);
542 return (1);
543 }
544 target->t_auth_group->ag_target = target;
545 }
546 ca = auth_new_chap_mutual(target->t_auth_group,
547 $2, $3, $4, $5);
548 free($2);
549 free($3);
550 free($4);
551 free($5);
552 if (ca == NULL)
553 return (1);
554 }
555 ;
556
557target_initiator_name: INITIATOR_NAME STR
558 {
559 const struct auth_name *an;
560
561 if (target->t_auth_group != NULL) {
562 if (target->t_auth_group->ag_name != NULL) {
563 log_warnx("cannot use both auth-group and "
564 "initiator-name for target \"%s\"",
565 target->t_name);
566 free($2);
567 return (1);
568 }
569 } else {
570 target->t_auth_group = auth_group_new(conf, NULL);
571 if (target->t_auth_group == NULL) {
572 free($2);
573 return (1);
574 }
575 target->t_auth_group->ag_target = target;
576 }
577 an = auth_name_new(target->t_auth_group, $2);
578 free($2);
579 if (an == NULL)
580 return (1);
581 }
582 ;
583
584target_initiator_portal: INITIATOR_PORTAL STR
585 {
586 const struct auth_portal *ap;
587
588 if (target->t_auth_group != NULL) {
589 if (target->t_auth_group->ag_name != NULL) {
590 log_warnx("cannot use both auth-group and "
591 "initiator-portal for target \"%s\"",
592 target->t_name);
593 free($2);
594 return (1);
595 }
596 } else {
597 target->t_auth_group = auth_group_new(conf, NULL);
598 if (target->t_auth_group == NULL) {
599 free($2);
600 return (1);
601 }
602 target->t_auth_group->ag_target = target;
603 }
604 ap = auth_portal_new(target->t_auth_group, $2);
605 free($2);
606 if (ap == NULL)
607 return (1);
608 }
609 ;
610
611target_portal_group: PORTAL_GROUP STR
612 {
613 if (target->t_portal_group != NULL) {
614 log_warnx("portal-group for target \"%s\" "
615 "specified more than once", target->t_name);
616 free($2);
617 return (1);
618 }
619 target->t_portal_group = portal_group_find(conf, $2);
620 if (target->t_portal_group == NULL) {
621 log_warnx("unknown portal-group \"%s\" for target "
622 "\"%s\"", $2, target->t_name);
623 free($2);
624 return (1);
625 }
626 free($2);
627 }
628 ;
629
630target_lun: LUN lun_number
631 OPENING_BRACKET lun_entries CLOSING_BRACKET
632 {
633 lun = NULL;
634 }
635 ;
636
637lun_number: STR
638 {
639 uint64_t tmp;
640
641 if (expand_number($1, &tmp) != 0) {
642 yyerror("invalid numeric value");
643 free($1);
644 return (1);
645 }
646
647 lun = lun_new(target, tmp);
648 if (lun == NULL)
649 return (1);
650 }
651 ;
652
653lun_entries:
654 |
655 lun_entries lun_entry
656 ;
657
658lun_entry:
659 lun_backend
660 |
661 lun_blocksize
662 |
663 lun_device_id
664 |
665 lun_option
666 |
667 lun_path
668 |
669 lun_serial
670 |
671 lun_size
672 ;
673
674lun_backend: BACKEND STR
675 {
676 if (lun->l_backend != NULL) {
677 log_warnx("backend for lun %d, target \"%s\" "
678 "specified more than once",
679 lun->l_lun, target->t_name);
680 free($2);
681 return (1);
682 }
683 lun_set_backend(lun, $2);
684 free($2);
685 }
686 ;
687
688lun_blocksize: BLOCKSIZE STR
689 {
690 uint64_t tmp;
691
692 if (expand_number($2, &tmp) != 0) {
693 yyerror("invalid numeric value");
694 free($2);
695 return (1);
696 }
697
698 if (lun->l_blocksize != 0) {
699 log_warnx("blocksize for lun %d, target \"%s\" "
700 "specified more than once",
701 lun->l_lun, target->t_name);
702 return (1);
703 }
704 lun_set_blocksize(lun, tmp);
705 }
706 ;
707
708lun_device_id: DEVICE_ID STR
709 {
710 if (lun->l_device_id != NULL) {
711 log_warnx("device_id for lun %d, target \"%s\" "
712 "specified more than once",
713 lun->l_lun, target->t_name);
714 free($2);
715 return (1);
716 }
717 lun_set_device_id(lun, $2);
718 free($2);
719 }
720 ;
721
722lun_option: OPTION STR STR
723 {
724 struct lun_option *clo;
725
726 clo = lun_option_new(lun, $2, $3);
727 free($2);
728 free($3);
729 if (clo == NULL)
730 return (1);
731 }
732 ;
733
734lun_path: PATH STR
735 {
736 if (lun->l_path != NULL) {
737 log_warnx("path for lun %d, target \"%s\" "
738 "specified more than once",
739 lun->l_lun, target->t_name);
740 free($2);
741 return (1);
742 }
743 lun_set_path(lun, $2);
744 free($2);
745 }
746 ;
747
748lun_serial: SERIAL STR
749 {
750 if (lun->l_serial != NULL) {
751 log_warnx("serial for lun %d, target \"%s\" "
752 "specified more than once",
753 lun->l_lun, target->t_name);
754 free($2);
755 return (1);
756 }
757 lun_set_serial(lun, $2);
758 free($2);
759 }
760 ;
761
762lun_size: SIZE STR
763 {
764 uint64_t tmp;
765
766 if (expand_number($2, &tmp) != 0) {
767 yyerror("invalid numeric value");
768 free($2);
769 return (1);
770 }
771
772 if (lun->l_size != 0) {
773 log_warnx("size for lun %d, target \"%s\" "
774 "specified more than once",
775 lun->l_lun, target->t_name);
776 return (1);
777 }
778 lun_set_size(lun, tmp);
779 }
780 ;
781%%
782
783void
784yyerror(const char *str)
785{
786
787 log_warnx("error in configuration file at line %d near '%s': %s",
788 lineno, yytext, str);
789}
790
791static void
792check_perms(const char *path)
793{
794 struct stat sb;
795 int error;
796
797 error = stat(path, &sb);
798 if (error != 0) {
799 log_warn("stat");
800 return;
801 }
802 if (sb.st_mode & S_IWOTH) {
803 log_warnx("%s is world-writable", path);
804 } else if (sb.st_mode & S_IROTH) {
805 log_warnx("%s is world-readable", path);
806 } else if (sb.st_mode & S_IXOTH) {
807 /*
808 * Ok, this one doesn't matter, but still do it,
809 * just for consistency.
810 */
811 log_warnx("%s is world-executable", path);
812 }
813
814 /*
815 * XXX: Should we also check for owner != 0?
816 */
817}
818
819struct conf *
820conf_new_from_file(const char *path)
821{
822 struct auth_group *ag;
823 struct portal_group *pg;
824 int error;
825
826 log_debugx("obtaining configuration from %s", path);
827
828 conf = conf_new();
829
830 ag = auth_group_new(conf, "default");
831 assert(ag != NULL);
832
833 ag = auth_group_new(conf, "no-authentication");
834 assert(ag != NULL);
835 ag->ag_type = AG_TYPE_NO_AUTHENTICATION;
836
837 ag = auth_group_new(conf, "no-access");
838 assert(ag != NULL);
839 ag->ag_type = AG_TYPE_DENY;
840
841 pg = portal_group_new(conf, "default");
842 assert(pg != NULL);
843
844 yyin = fopen(path, "r");
845 if (yyin == NULL) {
846 log_warn("unable to open configuration file %s", path);
847 conf_delete(conf);
848 return (NULL);
849 }
850 check_perms(path);
851 lineno = 1;
852 yyrestart(yyin);
853 error = yyparse();
854 auth_group = NULL;
855 portal_group = NULL;
856 target = NULL;
857 lun = NULL;
858 fclose(yyin);
859 if (error != 0) {
860 conf_delete(conf);
861 return (NULL);
862 }
863
864 if (conf->conf_default_ag_defined == false) {
865 log_debugx("auth-group \"default\" not defined; "
866 "going with defaults");
867 ag = auth_group_find(conf, "default");
868 assert(ag != NULL);
869 ag->ag_type = AG_TYPE_DENY;
870 }
871
872 if (conf->conf_default_pg_defined == false) {
873 log_debugx("portal-group \"default\" not defined; "
874 "going with defaults");
875 pg = portal_group_find(conf, "default");
876 assert(pg != NULL);
877 portal_group_add_listen(pg, "0.0.0.0:3260", false);
878 portal_group_add_listen(pg, "[::]:3260", false);
879 }
880
881 conf->conf_kernel_port_on = true;
882
883 error = conf_verify(conf);
884 if (error != 0) {
885 conf_delete(conf);
886 return (NULL);
887 }
888
889 return (conf);
890}