3 * Copyright (c) 2012 The FreeBSD Foundation
6 * This software was developed by Edward Tomasz Napierala under sponsorship
7 * from the FreeBSD Foundation.
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
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.
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
33 #include <sys/queue.h>
34 #include <sys/types.h>
48 static struct conf *conf = NULL;
49 static struct auth_group *auth_group = NULL;
50 static struct portal_group *portal_group = NULL;
51 static struct target *target = NULL;
52 static struct lun *lun = NULL;
54 extern void yyerror(const char *);
55 extern int yylex(void);
56 extern void yyrestart(FILE *);
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
106 if (expand_number($2, &tmp) != 0) {
107 yyerror("invalid numeric value");
112 conf->conf_debug = tmp;
120 if (expand_number($2, &tmp) != 0) {
121 yyerror("invalid numeric value");
126 conf->conf_timeout = tmp;
134 if (expand_number($2, &tmp) != 0) {
135 yyerror("invalid numeric value");
140 conf->conf_maxproc = tmp;
146 if (conf->conf_pidfile_path != NULL) {
147 log_warnx("pidfile specified more than once");
151 conf->conf_pidfile_path = $2;
155 isns_server: ISNS_SERVER STR
159 error = isns_new(conf, $2);
166 isns_period: ISNS_PERIOD STR
170 if (expand_number($2, &tmp) != 0) {
171 yyerror("invalid numeric value");
176 conf->conf_isns_period = tmp;
180 isns_timeout: ISNS_TIMEOUT STR
184 if (expand_number($2, &tmp) != 0) {
185 yyerror("invalid numeric value");
190 conf->conf_isns_timeout = tmp;
194 auth_group: AUTH_GROUP auth_group_name
195 OPENING_BRACKET auth_group_entries CLOSING_BRACKET
204 * Make it possible to redefine default
205 * auth-group. but only once.
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;
212 auth_group = auth_group_new(conf, $1);
215 if (auth_group == NULL)
222 auth_group_entries auth_group_entry
230 auth_group_chap_mutual
232 auth_group_initiator_name
234 auth_group_initiator_portal
237 auth_group_auth_type: AUTH_TYPE STR
241 error = auth_group_set_type(auth_group, $2);
248 auth_group_chap: CHAP STR STR
250 const struct auth *ca;
252 ca = auth_new_chap(auth_group, $2, $3);
260 auth_group_chap_mutual: CHAP_MUTUAL STR STR STR STR
262 const struct auth *ca;
264 ca = auth_new_chap_mutual(auth_group, $2, $3, $4, $5);
274 auth_group_initiator_name: INITIATOR_NAME STR
276 const struct auth_name *an;
278 an = auth_name_new(auth_group, $2);
285 auth_group_initiator_portal: INITIATOR_PORTAL STR
287 const struct auth_portal *ap;
289 ap = auth_portal_new(auth_group, $2);
296 portal_group: PORTAL_GROUP portal_group_name
297 OPENING_BRACKET portal_group_entries CLOSING_BRACKET
303 portal_group_name: STR
306 * Make it possible to redefine default
307 * portal-group. but only once.
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;
314 portal_group = portal_group_new(conf, $1);
317 if (portal_group == NULL)
322 portal_group_entries:
324 portal_group_entries portal_group_entry
328 portal_group_discovery_auth_group
330 portal_group_discovery_filter
334 portal_group_listen_iser
337 portal_group_discovery_auth_group: DISCOVERY_AUTH_GROUP STR
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);
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);
357 portal_group_discovery_filter: DISCOVERY_FILTER STR
361 error = portal_group_set_filter(portal_group, $2);
368 portal_group_listen: LISTEN STR
372 error = portal_group_add_listen(portal_group, $2, false);
379 portal_group_listen_iser: LISTEN_ISER STR
383 error = portal_group_add_listen(portal_group, $2, true);
390 target: TARGET target_name
391 OPENING_BRACKET target_entries CLOSING_BRACKET
399 target = target_new(conf, $1);
408 target_entries target_entry
422 target_initiator_name
424 target_initiator_portal
431 target_alias: ALIAS STR
433 if (target->t_alias != NULL) {
434 log_warnx("alias for target \"%s\" "
435 "specified more than once", target->t_name);
438 target->t_alias = $2;
442 target_auth_group: AUTH_GROUP STR
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);
449 log_warnx("cannot use both auth-group and explicit "
450 "authorisations for target \"%s\"",
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);
464 target_auth_type: AUTH_TYPE STR
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\"",
476 target->t_auth_group = auth_group_new(conf, NULL);
477 if (target->t_auth_group == NULL) {
481 target->t_auth_group->ag_target = target;
483 error = auth_group_set_type(target->t_auth_group, $2);
490 target_chap: CHAP STR STR
492 const struct auth *ca;
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\"",
504 target->t_auth_group = auth_group_new(conf, NULL);
505 if (target->t_auth_group == NULL) {
510 target->t_auth_group->ag_target = target;
512 ca = auth_new_chap(target->t_auth_group, $2, $3);
520 target_chap_mutual: CHAP_MUTUAL STR STR STR STR
522 const struct auth *ca;
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\"",
536 target->t_auth_group = auth_group_new(conf, NULL);
537 if (target->t_auth_group == NULL) {
544 target->t_auth_group->ag_target = target;
546 ca = auth_new_chap_mutual(target->t_auth_group,
557 target_initiator_name: INITIATOR_NAME STR
559 const struct auth_name *an;
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\"",
570 target->t_auth_group = auth_group_new(conf, NULL);
571 if (target->t_auth_group == NULL) {
575 target->t_auth_group->ag_target = target;
577 an = auth_name_new(target->t_auth_group, $2);
584 target_initiator_portal: INITIATOR_PORTAL STR
586 const struct auth_portal *ap;
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\"",
597 target->t_auth_group = auth_group_new(conf, NULL);
598 if (target->t_auth_group == NULL) {
602 target->t_auth_group->ag_target = target;
604 ap = auth_portal_new(target->t_auth_group, $2);
611 target_portal_group: PORTAL_GROUP STR
613 if (target->t_portal_group != NULL) {
614 log_warnx("portal-group for target \"%s\" "
615 "specified more than once", target->t_name);
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);
630 target_lun: LUN lun_number
631 OPENING_BRACKET lun_entries CLOSING_BRACKET
641 if (expand_number($1, &tmp) != 0) {
642 yyerror("invalid numeric value");
647 lun = lun_new(target, tmp);
655 lun_entries lun_entry
674 lun_backend: BACKEND STR
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);
683 lun_set_backend(lun, $2);
688 lun_blocksize: BLOCKSIZE STR
692 if (expand_number($2, &tmp) != 0) {
693 yyerror("invalid numeric value");
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);
704 lun_set_blocksize(lun, tmp);
708 lun_device_id: DEVICE_ID STR
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);
717 lun_set_device_id(lun, $2);
722 lun_option: OPTION STR STR
724 struct lun_option *clo;
726 clo = lun_option_new(lun, $2, $3);
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);
743 lun_set_path(lun, $2);
748 lun_serial: SERIAL STR
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);
757 lun_set_serial(lun, $2);
766 if (expand_number($2, &tmp) != 0) {
767 yyerror("invalid numeric value");
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);
778 lun_set_size(lun, tmp);
784 yyerror(const char *str)
787 log_warnx("error in configuration file at line %d near '%s': %s",
788 lineno, yytext, str);
792 check_perms(const char *path)
797 error = stat(path, &sb);
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) {
808 * Ok, this one doesn't matter, but still do it,
809 * just for consistency.
811 log_warnx("%s is world-executable", path);
815 * XXX: Should we also check for owner != 0?
820 conf_new_from_file(const char *path)
822 struct auth_group *ag;
823 struct portal_group *pg;
826 log_debugx("obtaining configuration from %s", path);
830 ag = auth_group_new(conf, "default");
833 ag = auth_group_new(conf, "no-authentication");
835 ag->ag_type = AG_TYPE_NO_AUTHENTICATION;
837 ag = auth_group_new(conf, "no-access");
839 ag->ag_type = AG_TYPE_DENY;
841 pg = portal_group_new(conf, "default");
844 yyin = fopen(path, "r");
846 log_warn("unable to open configuration file %s", path);
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");
869 ag->ag_type = AG_TYPE_DENY;
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");
877 portal_group_add_listen(pg, "0.0.0.0:3260", false);
878 portal_group_add_listen(pg, "[::]:3260", false);
881 conf->conf_kernel_port_on = true;
883 error = conf_verify(conf);