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