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 SEMICOLON SERIAL SIZE STR
64 %token TARGET TIMEOUT ISNS_SERVER ISNS_PERIOD ISNS_TIMEOUT
79 statements statement SEMICOLON
108 if (expand_number($2, &tmp) != 0) {
109 yyerror("invalid numeric value");
114 conf->conf_debug = tmp;
122 if (expand_number($2, &tmp) != 0) {
123 yyerror("invalid numeric value");
128 conf->conf_timeout = tmp;
136 if (expand_number($2, &tmp) != 0) {
137 yyerror("invalid numeric value");
142 conf->conf_maxproc = tmp;
148 if (conf->conf_pidfile_path != NULL) {
149 log_warnx("pidfile specified more than once");
153 conf->conf_pidfile_path = $2;
157 isns_server: ISNS_SERVER STR
161 error = isns_new(conf, $2);
168 isns_period: ISNS_PERIOD STR
172 if (expand_number($2, &tmp) != 0) {
173 yyerror("invalid numeric value");
178 conf->conf_isns_period = tmp;
182 isns_timeout: ISNS_TIMEOUT STR
186 if (expand_number($2, &tmp) != 0) {
187 yyerror("invalid numeric value");
192 conf->conf_isns_timeout = tmp;
196 auth_group: AUTH_GROUP auth_group_name
197 OPENING_BRACKET auth_group_entries CLOSING_BRACKET
206 * Make it possible to redefine default
207 * auth-group. but only once.
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;
214 auth_group = auth_group_new(conf, $1);
217 if (auth_group == NULL)
224 auth_group_entries auth_group_entry
226 auth_group_entries auth_group_entry SEMICOLON
234 auth_group_chap_mutual
236 auth_group_initiator_name
238 auth_group_initiator_portal
241 auth_group_auth_type: AUTH_TYPE STR
245 error = auth_group_set_type(auth_group, $2);
252 auth_group_chap: CHAP STR STR
254 const struct auth *ca;
256 ca = auth_new_chap(auth_group, $2, $3);
264 auth_group_chap_mutual: CHAP_MUTUAL STR STR STR STR
266 const struct auth *ca;
268 ca = auth_new_chap_mutual(auth_group, $2, $3, $4, $5);
278 auth_group_initiator_name: INITIATOR_NAME STR
280 const struct auth_name *an;
282 an = auth_name_new(auth_group, $2);
289 auth_group_initiator_portal: INITIATOR_PORTAL STR
291 const struct auth_portal *ap;
293 ap = auth_portal_new(auth_group, $2);
300 portal_group: PORTAL_GROUP portal_group_name
301 OPENING_BRACKET portal_group_entries CLOSING_BRACKET
307 portal_group_name: STR
310 * Make it possible to redefine default
311 * portal-group. but only once.
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;
318 portal_group = portal_group_new(conf, $1);
321 if (portal_group == NULL)
326 portal_group_entries:
328 portal_group_entries portal_group_entry
330 portal_group_entries portal_group_entry SEMICOLON
334 portal_group_discovery_auth_group
336 portal_group_discovery_filter
340 portal_group_listen_iser
343 portal_group_discovery_auth_group: DISCOVERY_AUTH_GROUP STR
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);
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);
363 portal_group_discovery_filter: DISCOVERY_FILTER STR
367 error = portal_group_set_filter(portal_group, $2);
374 portal_group_listen: LISTEN STR
378 error = portal_group_add_listen(portal_group, $2, false);
385 portal_group_listen_iser: LISTEN_ISER STR
389 error = portal_group_add_listen(portal_group, $2, true);
396 target: TARGET target_name
397 OPENING_BRACKET target_entries CLOSING_BRACKET
405 target = target_new(conf, $1);
414 target_entries target_entry
416 target_entries target_entry SEMICOLON
430 target_initiator_name
432 target_initiator_portal
439 target_alias: ALIAS STR
441 if (target->t_alias != NULL) {
442 log_warnx("alias for target \"%s\" "
443 "specified more than once", target->t_name);
446 target->t_alias = $2;
450 target_auth_group: AUTH_GROUP STR
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);
457 log_warnx("cannot use both auth-group and explicit "
458 "authorisations for target \"%s\"",
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);
472 target_auth_type: AUTH_TYPE STR
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\"",
484 target->t_auth_group = auth_group_new(conf, NULL);
485 if (target->t_auth_group == NULL) {
489 target->t_auth_group->ag_target = target;
491 error = auth_group_set_type(target->t_auth_group, $2);
498 target_chap: CHAP STR STR
500 const struct auth *ca;
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\"",
512 target->t_auth_group = auth_group_new(conf, NULL);
513 if (target->t_auth_group == NULL) {
518 target->t_auth_group->ag_target = target;
520 ca = auth_new_chap(target->t_auth_group, $2, $3);
528 target_chap_mutual: CHAP_MUTUAL STR STR STR STR
530 const struct auth *ca;
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\"",
544 target->t_auth_group = auth_group_new(conf, NULL);
545 if (target->t_auth_group == NULL) {
552 target->t_auth_group->ag_target = target;
554 ca = auth_new_chap_mutual(target->t_auth_group,
565 target_initiator_name: INITIATOR_NAME STR
567 const struct auth_name *an;
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\"",
578 target->t_auth_group = auth_group_new(conf, NULL);
579 if (target->t_auth_group == NULL) {
583 target->t_auth_group->ag_target = target;
585 an = auth_name_new(target->t_auth_group, $2);
592 target_initiator_portal: INITIATOR_PORTAL STR
594 const struct auth_portal *ap;
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\"",
605 target->t_auth_group = auth_group_new(conf, NULL);
606 if (target->t_auth_group == NULL) {
610 target->t_auth_group->ag_target = target;
612 ap = auth_portal_new(target->t_auth_group, $2);
619 target_portal_group: PORTAL_GROUP STR
621 if (target->t_portal_group != NULL) {
622 log_warnx("portal-group for target \"%s\" "
623 "specified more than once", target->t_name);
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);
638 target_lun: LUN lun_number
639 OPENING_BRACKET lun_entries CLOSING_BRACKET
649 if (expand_number($1, &tmp) != 0) {
650 yyerror("invalid numeric value");
655 lun = lun_new(target, tmp);
663 lun_entries lun_entry
665 lun_entries lun_entry SEMICOLON
684 lun_backend: BACKEND STR
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);
693 lun_set_backend(lun, $2);
698 lun_blocksize: BLOCKSIZE STR
702 if (expand_number($2, &tmp) != 0) {
703 yyerror("invalid numeric value");
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);
714 lun_set_blocksize(lun, tmp);
718 lun_device_id: DEVICE_ID STR
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);
727 lun_set_device_id(lun, $2);
732 lun_option: OPTION STR STR
734 struct lun_option *clo;
736 clo = lun_option_new(lun, $2, $3);
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);
753 lun_set_path(lun, $2);
758 lun_serial: SERIAL STR
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);
767 lun_set_serial(lun, $2);
776 if (expand_number($2, &tmp) != 0) {
777 yyerror("invalid numeric value");
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);
788 lun_set_size(lun, tmp);
794 yyerror(const char *str)
797 log_warnx("error in configuration file at line %d near '%s': %s",
798 lineno, yytext, str);
802 check_perms(const char *path)
807 error = stat(path, &sb);
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) {
818 * Ok, this one doesn't matter, but still do it,
819 * just for consistency.
821 log_warnx("%s is world-executable", path);
825 * XXX: Should we also check for owner != 0?
830 conf_new_from_file(const char *path)
832 struct auth_group *ag;
833 struct portal_group *pg;
836 log_debugx("obtaining configuration from %s", path);
840 ag = auth_group_new(conf, "default");
843 ag = auth_group_new(conf, "no-authentication");
845 ag->ag_type = AG_TYPE_NO_AUTHENTICATION;
847 ag = auth_group_new(conf, "no-access");
849 ag->ag_type = AG_TYPE_DENY;
851 pg = portal_group_new(conf, "default");
854 yyin = fopen(path, "r");
856 log_warn("unable to open configuration file %s", path);
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");
879 ag->ag_type = AG_TYPE_DENY;
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");
887 portal_group_add_listen(pg, "0.0.0.0:3260", false);
888 portal_group_add_listen(pg, "[::]:3260", false);
891 conf->conf_kernel_port_on = true;
893 error = conf_verify(conf);