parse.y revision 288760
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 288760 2015-10-05 09:22:31Z mav $ 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 <stdlib.h> 39#include <string.h> 40 41#include "ctld.h" 42 43extern FILE *yyin; 44extern char *yytext; 45extern int lineno; 46 47static struct conf *conf = NULL; 48static struct auth_group *auth_group = NULL; 49static struct portal_group *portal_group = NULL; 50static struct target *target = NULL; 51static struct lun *lun = NULL; 52 53extern void yyerror(const char *); 54extern int yylex(void); 55extern void yyrestart(FILE *); 56 57%} 58 59%token ALIAS AUTH_GROUP AUTH_TYPE BACKEND BLOCKSIZE CHAP CHAP_MUTUAL 60%token CLOSING_BRACKET CTL_LUN DEBUG DEVICE_ID DISCOVERY_AUTH_GROUP 61%token DISCOVERY_FILTER FOREIGN 62%token INITIATOR_NAME INITIATOR_PORTAL ISNS_SERVER ISNS_PERIOD ISNS_TIMEOUT 63%token LISTEN LISTEN_ISER LUN MAXPROC OPENING_BRACKET OPTION 64%token PATH PIDFILE PORT PORTAL_GROUP REDIRECT SEMICOLON SERIAL SIZE STR 65%token TAG TARGET TIMEOUT 66 67%union 68{ 69 char *str; 70} 71 72%token <str> STR 73 74%% 75 76statements: 77 | 78 statements statement 79 | 80 statements statement SEMICOLON 81 ; 82 83statement: 84 debug 85 | 86 timeout 87 | 88 maxproc 89 | 90 pidfile 91 | 92 isns_server 93 | 94 isns_period 95 | 96 isns_timeout 97 | 98 auth_group 99 | 100 portal_group 101 | 102 lun 103 | 104 target 105 ; 106 107debug: DEBUG STR 108 { 109 uint64_t tmp; 110 111 if (expand_number($2, &tmp) != 0) { 112 yyerror("invalid numeric value"); 113 free($2); 114 return (1); 115 } 116 117 conf->conf_debug = tmp; 118 } 119 ; 120 121timeout: TIMEOUT STR 122 { 123 uint64_t tmp; 124 125 if (expand_number($2, &tmp) != 0) { 126 yyerror("invalid numeric value"); 127 free($2); 128 return (1); 129 } 130 131 conf->conf_timeout = tmp; 132 } 133 ; 134 135maxproc: MAXPROC STR 136 { 137 uint64_t tmp; 138 139 if (expand_number($2, &tmp) != 0) { 140 yyerror("invalid numeric value"); 141 free($2); 142 return (1); 143 } 144 145 conf->conf_maxproc = tmp; 146 } 147 ; 148 149pidfile: PIDFILE STR 150 { 151 if (conf->conf_pidfile_path != NULL) { 152 log_warnx("pidfile specified more than once"); 153 free($2); 154 return (1); 155 } 156 conf->conf_pidfile_path = $2; 157 } 158 ; 159 160isns_server: ISNS_SERVER STR 161 { 162 int error; 163 164 error = isns_new(conf, $2); 165 free($2); 166 if (error != 0) 167 return (1); 168 } 169 ; 170 171isns_period: ISNS_PERIOD STR 172 { 173 uint64_t tmp; 174 175 if (expand_number($2, &tmp) != 0) { 176 yyerror("invalid numeric value"); 177 free($2); 178 return (1); 179 } 180 181 conf->conf_isns_period = tmp; 182 } 183 ; 184 185isns_timeout: ISNS_TIMEOUT STR 186 { 187 uint64_t tmp; 188 189 if (expand_number($2, &tmp) != 0) { 190 yyerror("invalid numeric value"); 191 free($2); 192 return (1); 193 } 194 195 conf->conf_isns_timeout = tmp; 196 } 197 ; 198 199auth_group: AUTH_GROUP auth_group_name 200 OPENING_BRACKET auth_group_entries CLOSING_BRACKET 201 { 202 auth_group = NULL; 203 } 204 ; 205 206auth_group_name: STR 207 { 208 /* 209 * Make it possible to redefine default 210 * auth-group. but only once. 211 */ 212 if (strcmp($1, "default") == 0 && 213 conf->conf_default_ag_defined == false) { 214 auth_group = auth_group_find(conf, $1); 215 conf->conf_default_ag_defined = true; 216 } else { 217 auth_group = auth_group_new(conf, $1); 218 } 219 free($1); 220 if (auth_group == NULL) 221 return (1); 222 } 223 ; 224 225auth_group_entries: 226 | 227 auth_group_entries auth_group_entry 228 | 229 auth_group_entries auth_group_entry SEMICOLON 230 ; 231 232auth_group_entry: 233 auth_group_auth_type 234 | 235 auth_group_chap 236 | 237 auth_group_chap_mutual 238 | 239 auth_group_initiator_name 240 | 241 auth_group_initiator_portal 242 ; 243 244auth_group_auth_type: AUTH_TYPE STR 245 { 246 int error; 247 248 error = auth_group_set_type(auth_group, $2); 249 free($2); 250 if (error != 0) 251 return (1); 252 } 253 ; 254 255auth_group_chap: CHAP STR STR 256 { 257 const struct auth *ca; 258 259 ca = auth_new_chap(auth_group, $2, $3); 260 free($2); 261 free($3); 262 if (ca == NULL) 263 return (1); 264 } 265 ; 266 267auth_group_chap_mutual: CHAP_MUTUAL STR STR STR STR 268 { 269 const struct auth *ca; 270 271 ca = auth_new_chap_mutual(auth_group, $2, $3, $4, $5); 272 free($2); 273 free($3); 274 free($4); 275 free($5); 276 if (ca == NULL) 277 return (1); 278 } 279 ; 280 281auth_group_initiator_name: INITIATOR_NAME STR 282 { 283 const struct auth_name *an; 284 285 an = auth_name_new(auth_group, $2); 286 free($2); 287 if (an == NULL) 288 return (1); 289 } 290 ; 291 292auth_group_initiator_portal: INITIATOR_PORTAL STR 293 { 294 const struct auth_portal *ap; 295 296 ap = auth_portal_new(auth_group, $2); 297 free($2); 298 if (ap == NULL) 299 return (1); 300 } 301 ; 302 303portal_group: PORTAL_GROUP portal_group_name 304 OPENING_BRACKET portal_group_entries CLOSING_BRACKET 305 { 306 portal_group = NULL; 307 } 308 ; 309 310portal_group_name: STR 311 { 312 /* 313 * Make it possible to redefine default 314 * portal-group. but only once. 315 */ 316 if (strcmp($1, "default") == 0 && 317 conf->conf_default_pg_defined == false) { 318 portal_group = portal_group_find(conf, $1); 319 conf->conf_default_pg_defined = true; 320 } else { 321 portal_group = portal_group_new(conf, $1); 322 } 323 free($1); 324 if (portal_group == NULL) 325 return (1); 326 } 327 ; 328 329portal_group_entries: 330 | 331 portal_group_entries portal_group_entry 332 | 333 portal_group_entries portal_group_entry SEMICOLON 334 ; 335 336portal_group_entry: 337 portal_group_discovery_auth_group 338 | 339 portal_group_discovery_filter 340 | 341 portal_group_foreign 342 | 343 portal_group_listen 344 | 345 portal_group_listen_iser 346 | 347 portal_group_redirect 348 | 349 portal_group_tag 350 ; 351 352portal_group_discovery_auth_group: DISCOVERY_AUTH_GROUP STR 353 { 354 if (portal_group->pg_discovery_auth_group != NULL) { 355 log_warnx("discovery-auth-group for portal-group " 356 "\"%s\" specified more than once", 357 portal_group->pg_name); 358 return (1); 359 } 360 portal_group->pg_discovery_auth_group = 361 auth_group_find(conf, $2); 362 if (portal_group->pg_discovery_auth_group == NULL) { 363 log_warnx("unknown discovery-auth-group \"%s\" " 364 "for portal-group \"%s\"", 365 $2, portal_group->pg_name); 366 return (1); 367 } 368 free($2); 369 } 370 ; 371 372portal_group_discovery_filter: DISCOVERY_FILTER STR 373 { 374 int error; 375 376 error = portal_group_set_filter(portal_group, $2); 377 free($2); 378 if (error != 0) 379 return (1); 380 } 381 ; 382 383portal_group_foreign: FOREIGN 384 { 385 386 portal_group->pg_foreign = 1; 387 } 388 ; 389 390portal_group_listen: LISTEN STR 391 { 392 int error; 393 394 error = portal_group_add_listen(portal_group, $2, false); 395 free($2); 396 if (error != 0) 397 return (1); 398 } 399 ; 400 401portal_group_listen_iser: LISTEN_ISER STR 402 { 403 int error; 404 405 error = portal_group_add_listen(portal_group, $2, true); 406 free($2); 407 if (error != 0) 408 return (1); 409 } 410 ; 411 412portal_group_redirect: REDIRECT STR 413 { 414 int error; 415 416 error = portal_group_set_redirection(portal_group, $2); 417 free($2); 418 if (error != 0) 419 return (1); 420 } 421 ; 422 423portal_group_tag: TAG STR 424 { 425 uint64_t tmp; 426 427 if (expand_number($2, &tmp) != 0) { 428 yyerror("invalid numeric value"); 429 free($2); 430 return (1); 431 } 432 433 portal_group->pg_tag = tmp; 434 } 435 ; 436 437lun: LUN lun_name 438 OPENING_BRACKET lun_entries CLOSING_BRACKET 439 { 440 lun = NULL; 441 } 442 ; 443 444lun_name: STR 445 { 446 lun = lun_new(conf, $1); 447 free($1); 448 if (lun == NULL) 449 return (1); 450 } 451 ; 452 453target: TARGET target_name 454 OPENING_BRACKET target_entries CLOSING_BRACKET 455 { 456 target = NULL; 457 } 458 ; 459 460target_name: STR 461 { 462 target = target_new(conf, $1); 463 free($1); 464 if (target == NULL) 465 return (1); 466 } 467 ; 468 469target_entries: 470 | 471 target_entries target_entry 472 | 473 target_entries target_entry SEMICOLON 474 ; 475 476target_entry: 477 target_alias 478 | 479 target_auth_group 480 | 481 target_auth_type 482 | 483 target_chap 484 | 485 target_chap_mutual 486 | 487 target_initiator_name 488 | 489 target_initiator_portal 490 | 491 target_portal_group 492 | 493 target_port 494 | 495 target_redirect 496 | 497 target_lun 498 | 499 target_lun_ref 500 ; 501 502target_alias: ALIAS STR 503 { 504 if (target->t_alias != NULL) { 505 log_warnx("alias for target \"%s\" " 506 "specified more than once", target->t_name); 507 return (1); 508 } 509 target->t_alias = $2; 510 } 511 ; 512 513target_auth_group: AUTH_GROUP STR 514 { 515 if (target->t_auth_group != NULL) { 516 if (target->t_auth_group->ag_name != NULL) 517 log_warnx("auth-group for target \"%s\" " 518 "specified more than once", target->t_name); 519 else 520 log_warnx("cannot use both auth-group and explicit " 521 "authorisations for target \"%s\"", 522 target->t_name); 523 return (1); 524 } 525 target->t_auth_group = auth_group_find(conf, $2); 526 if (target->t_auth_group == NULL) { 527 log_warnx("unknown auth-group \"%s\" for target " 528 "\"%s\"", $2, target->t_name); 529 return (1); 530 } 531 free($2); 532 } 533 ; 534 535target_auth_type: AUTH_TYPE STR 536 { 537 int error; 538 539 if (target->t_auth_group != NULL) { 540 if (target->t_auth_group->ag_name != NULL) { 541 log_warnx("cannot use both auth-group and " 542 "auth-type for target \"%s\"", 543 target->t_name); 544 return (1); 545 } 546 } else { 547 target->t_auth_group = auth_group_new(conf, NULL); 548 if (target->t_auth_group == NULL) { 549 free($2); 550 return (1); 551 } 552 target->t_auth_group->ag_target = target; 553 } 554 error = auth_group_set_type(target->t_auth_group, $2); 555 free($2); 556 if (error != 0) 557 return (1); 558 } 559 ; 560 561target_chap: CHAP STR STR 562 { 563 const struct auth *ca; 564 565 if (target->t_auth_group != NULL) { 566 if (target->t_auth_group->ag_name != NULL) { 567 log_warnx("cannot use both auth-group and " 568 "chap for target \"%s\"", 569 target->t_name); 570 free($2); 571 free($3); 572 return (1); 573 } 574 } else { 575 target->t_auth_group = auth_group_new(conf, NULL); 576 if (target->t_auth_group == NULL) { 577 free($2); 578 free($3); 579 return (1); 580 } 581 target->t_auth_group->ag_target = target; 582 } 583 ca = auth_new_chap(target->t_auth_group, $2, $3); 584 free($2); 585 free($3); 586 if (ca == NULL) 587 return (1); 588 } 589 ; 590 591target_chap_mutual: CHAP_MUTUAL STR STR STR STR 592 { 593 const struct auth *ca; 594 595 if (target->t_auth_group != NULL) { 596 if (target->t_auth_group->ag_name != NULL) { 597 log_warnx("cannot use both auth-group and " 598 "chap-mutual for target \"%s\"", 599 target->t_name); 600 free($2); 601 free($3); 602 free($4); 603 free($5); 604 return (1); 605 } 606 } else { 607 target->t_auth_group = auth_group_new(conf, NULL); 608 if (target->t_auth_group == NULL) { 609 free($2); 610 free($3); 611 free($4); 612 free($5); 613 return (1); 614 } 615 target->t_auth_group->ag_target = target; 616 } 617 ca = auth_new_chap_mutual(target->t_auth_group, 618 $2, $3, $4, $5); 619 free($2); 620 free($3); 621 free($4); 622 free($5); 623 if (ca == NULL) 624 return (1); 625 } 626 ; 627 628target_initiator_name: INITIATOR_NAME STR 629 { 630 const struct auth_name *an; 631 632 if (target->t_auth_group != NULL) { 633 if (target->t_auth_group->ag_name != NULL) { 634 log_warnx("cannot use both auth-group and " 635 "initiator-name for target \"%s\"", 636 target->t_name); 637 free($2); 638 return (1); 639 } 640 } else { 641 target->t_auth_group = auth_group_new(conf, NULL); 642 if (target->t_auth_group == NULL) { 643 free($2); 644 return (1); 645 } 646 target->t_auth_group->ag_target = target; 647 } 648 an = auth_name_new(target->t_auth_group, $2); 649 free($2); 650 if (an == NULL) 651 return (1); 652 } 653 ; 654 655target_initiator_portal: INITIATOR_PORTAL STR 656 { 657 const struct auth_portal *ap; 658 659 if (target->t_auth_group != NULL) { 660 if (target->t_auth_group->ag_name != NULL) { 661 log_warnx("cannot use both auth-group and " 662 "initiator-portal for target \"%s\"", 663 target->t_name); 664 free($2); 665 return (1); 666 } 667 } else { 668 target->t_auth_group = auth_group_new(conf, NULL); 669 if (target->t_auth_group == NULL) { 670 free($2); 671 return (1); 672 } 673 target->t_auth_group->ag_target = target; 674 } 675 ap = auth_portal_new(target->t_auth_group, $2); 676 free($2); 677 if (ap == NULL) 678 return (1); 679 } 680 ; 681 682target_portal_group: PORTAL_GROUP STR STR 683 { 684 struct portal_group *tpg; 685 struct auth_group *tag; 686 struct port *tp; 687 688 tpg = portal_group_find(conf, $2); 689 if (tpg == NULL) { 690 log_warnx("unknown portal-group \"%s\" for target " 691 "\"%s\"", $2, target->t_name); 692 free($2); 693 free($3); 694 return (1); 695 } 696 tag = auth_group_find(conf, $3); 697 if (tag == NULL) { 698 log_warnx("unknown auth-group \"%s\" for target " 699 "\"%s\"", $3, target->t_name); 700 free($2); 701 free($3); 702 return (1); 703 } 704 tp = port_new(conf, target, tpg); 705 if (tp == NULL) { 706 log_warnx("can't link portal-group \"%s\" to target " 707 "\"%s\"", $2, target->t_name); 708 free($2); 709 return (1); 710 } 711 tp->p_auth_group = tag; 712 free($2); 713 free($3); 714 } 715 | PORTAL_GROUP STR 716 { 717 struct portal_group *tpg; 718 struct port *tp; 719 720 tpg = portal_group_find(conf, $2); 721 if (tpg == NULL) { 722 log_warnx("unknown portal-group \"%s\" for target " 723 "\"%s\"", $2, target->t_name); 724 free($2); 725 return (1); 726 } 727 tp = port_new(conf, target, tpg); 728 if (tp == NULL) { 729 log_warnx("can't link portal-group \"%s\" to target " 730 "\"%s\"", $2, target->t_name); 731 free($2); 732 return (1); 733 } 734 free($2); 735 } 736 ; 737 738target_port: PORT STR 739 { 740 struct pport *pp; 741 struct port *tp; 742 743 pp = pport_find(conf, $2); 744 if (pp == NULL) { 745 log_warnx("unknown port \"%s\" for target \"%s\"", 746 $2, target->t_name); 747 free($2); 748 return (1); 749 } 750 if (!TAILQ_EMPTY(&pp->pp_ports)) { 751 log_warnx("can't link port \"%s\" to target \"%s\", " 752 "port already linked to some target", 753 $2, target->t_name); 754 free($2); 755 return (1); 756 } 757 tp = port_new_pp(conf, target, pp); 758 if (tp == NULL) { 759 log_warnx("can't link port \"%s\" to target \"%s\"", 760 $2, target->t_name); 761 free($2); 762 return (1); 763 } 764 free($2); 765 } 766 ; 767 768target_redirect: REDIRECT STR 769 { 770 int error; 771 772 error = target_set_redirection(target, $2); 773 free($2); 774 if (error != 0) 775 return (1); 776 } 777 ; 778 779target_lun: LUN lun_number 780 OPENING_BRACKET lun_entries CLOSING_BRACKET 781 { 782 lun = NULL; 783 } 784 ; 785 786lun_number: STR 787 { 788 uint64_t tmp; 789 int ret; 790 char *name; 791 792 if (expand_number($1, &tmp) != 0) { 793 yyerror("invalid numeric value"); 794 free($1); 795 return (1); 796 } 797 798 ret = asprintf(&name, "%s,lun,%ju", target->t_name, tmp); 799 if (ret <= 0) 800 log_err(1, "asprintf"); 801 lun = lun_new(conf, name); 802 if (lun == NULL) 803 return (1); 804 805 lun_set_scsiname(lun, name); 806 target->t_luns[tmp] = lun; 807 } 808 ; 809 810target_lun_ref: LUN STR STR 811 { 812 uint64_t tmp; 813 814 if (expand_number($2, &tmp) != 0) { 815 yyerror("invalid numeric value"); 816 free($2); 817 free($3); 818 return (1); 819 } 820 free($2); 821 822 lun = lun_find(conf, $3); 823 free($3); 824 if (lun == NULL) 825 return (1); 826 827 target->t_luns[tmp] = lun; 828 } 829 ; 830 831lun_entries: 832 | 833 lun_entries lun_entry 834 | 835 lun_entries lun_entry SEMICOLON 836 ; 837 838lun_entry: 839 lun_backend 840 | 841 lun_blocksize 842 | 843 lun_device_id 844 | 845 lun_ctl_lun 846 | 847 lun_option 848 | 849 lun_path 850 | 851 lun_serial 852 | 853 lun_size 854 ; 855 856lun_backend: BACKEND STR 857 { 858 if (lun->l_backend != NULL) { 859 log_warnx("backend for lun \"%s\" " 860 "specified more than once", 861 lun->l_name); 862 free($2); 863 return (1); 864 } 865 lun_set_backend(lun, $2); 866 free($2); 867 } 868 ; 869 870lun_blocksize: BLOCKSIZE STR 871 { 872 uint64_t tmp; 873 874 if (expand_number($2, &tmp) != 0) { 875 yyerror("invalid numeric value"); 876 free($2); 877 return (1); 878 } 879 880 if (lun->l_blocksize != 0) { 881 log_warnx("blocksize for lun \"%s\" " 882 "specified more than once", 883 lun->l_name); 884 return (1); 885 } 886 lun_set_blocksize(lun, tmp); 887 } 888 ; 889 890lun_device_id: DEVICE_ID STR 891 { 892 if (lun->l_device_id != NULL) { 893 log_warnx("device_id for lun \"%s\" " 894 "specified more than once", 895 lun->l_name); 896 free($2); 897 return (1); 898 } 899 lun_set_device_id(lun, $2); 900 free($2); 901 } 902 ; 903 904lun_ctl_lun: CTL_LUN STR 905 { 906 uint64_t tmp; 907 908 if (expand_number($2, &tmp) != 0) { 909 yyerror("invalid numeric value"); 910 free($2); 911 return (1); 912 } 913 914 if (lun->l_ctl_lun >= 0) { 915 log_warnx("ctl_lun for lun \"%s\" " 916 "specified more than once", 917 lun->l_name); 918 return (1); 919 } 920 lun_set_ctl_lun(lun, tmp); 921 } 922 ; 923 924lun_option: OPTION STR STR 925 { 926 struct lun_option *clo; 927 928 clo = lun_option_new(lun, $2, $3); 929 free($2); 930 free($3); 931 if (clo == NULL) 932 return (1); 933 } 934 ; 935 936lun_path: PATH STR 937 { 938 if (lun->l_path != NULL) { 939 log_warnx("path for lun \"%s\" " 940 "specified more than once", 941 lun->l_name); 942 free($2); 943 return (1); 944 } 945 lun_set_path(lun, $2); 946 free($2); 947 } 948 ; 949 950lun_serial: SERIAL STR 951 { 952 if (lun->l_serial != NULL) { 953 log_warnx("serial for lun \"%s\" " 954 "specified more than once", 955 lun->l_name); 956 free($2); 957 return (1); 958 } 959 lun_set_serial(lun, $2); 960 free($2); 961 } 962 ; 963 964lun_size: SIZE STR 965 { 966 uint64_t tmp; 967 968 if (expand_number($2, &tmp) != 0) { 969 yyerror("invalid numeric value"); 970 free($2); 971 return (1); 972 } 973 974 if (lun->l_size != 0) { 975 log_warnx("size for lun \"%s\" " 976 "specified more than once", 977 lun->l_name); 978 return (1); 979 } 980 lun_set_size(lun, tmp); 981 } 982 ; 983%% 984 985void 986yyerror(const char *str) 987{ 988 989 log_warnx("error in configuration file at line %d near '%s': %s", 990 lineno, yytext, str); 991} 992 993static void 994check_perms(const char *path) 995{ 996 struct stat sb; 997 int error; 998 999 error = stat(path, &sb); 1000 if (error != 0) { 1001 log_warn("stat"); 1002 return; 1003 } 1004 if (sb.st_mode & S_IWOTH) { 1005 log_warnx("%s is world-writable", path); 1006 } else if (sb.st_mode & S_IROTH) { 1007 log_warnx("%s is world-readable", path); 1008 } else if (sb.st_mode & S_IXOTH) { 1009 /* 1010 * Ok, this one doesn't matter, but still do it, 1011 * just for consistency. 1012 */ 1013 log_warnx("%s is world-executable", path); 1014 } 1015 1016 /* 1017 * XXX: Should we also check for owner != 0? 1018 */ 1019} 1020 1021struct conf * 1022conf_new_from_file(const char *path, struct conf *oldconf) 1023{ 1024 struct auth_group *ag; 1025 struct portal_group *pg; 1026 struct pport *pp; 1027 int error; 1028 1029 log_debugx("obtaining configuration from %s", path); 1030 1031 conf = conf_new(); 1032 1033 TAILQ_FOREACH(pp, &oldconf->conf_pports, pp_next) 1034 pport_copy(pp, conf); 1035 1036 ag = auth_group_new(conf, "default"); 1037 assert(ag != NULL); 1038 1039 ag = auth_group_new(conf, "no-authentication"); 1040 assert(ag != NULL); 1041 ag->ag_type = AG_TYPE_NO_AUTHENTICATION; 1042 1043 ag = auth_group_new(conf, "no-access"); 1044 assert(ag != NULL); 1045 ag->ag_type = AG_TYPE_DENY; 1046 1047 pg = portal_group_new(conf, "default"); 1048 assert(pg != NULL); 1049 1050 yyin = fopen(path, "r"); 1051 if (yyin == NULL) { 1052 log_warn("unable to open configuration file %s", path); 1053 conf_delete(conf); 1054 return (NULL); 1055 } 1056 check_perms(path); 1057 lineno = 1; 1058 yyrestart(yyin); 1059 error = yyparse(); 1060 auth_group = NULL; 1061 portal_group = NULL; 1062 target = NULL; 1063 lun = NULL; 1064 fclose(yyin); 1065 if (error != 0) { 1066 conf_delete(conf); 1067 return (NULL); 1068 } 1069 1070 if (conf->conf_default_ag_defined == false) { 1071 log_debugx("auth-group \"default\" not defined; " 1072 "going with defaults"); 1073 ag = auth_group_find(conf, "default"); 1074 assert(ag != NULL); 1075 ag->ag_type = AG_TYPE_DENY; 1076 } 1077 1078 if (conf->conf_default_pg_defined == false) { 1079 log_debugx("portal-group \"default\" not defined; " 1080 "going with defaults"); 1081 pg = portal_group_find(conf, "default"); 1082 assert(pg != NULL); 1083 portal_group_add_listen(pg, "0.0.0.0:3260", false); 1084 portal_group_add_listen(pg, "[::]:3260", false); 1085 } 1086 1087 conf->conf_kernel_port_on = true; 1088 1089 error = conf_verify(conf); 1090 if (error != 0) { 1091 conf_delete(conf); 1092 return (NULL); 1093 } 1094 1095 return (conf); 1096} 1097