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