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