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 *
| 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 *
|
126auth_group: AUTH_GROUP auth_group_name 127 OPENING_BRACKET auth_group_entries CLOSING_BRACKET 128 { 129 auth_group = NULL; 130 } 131 ; 132 133auth_group_name: STR 134 { 135 /* 136 * Make it possible to redefine default 137 * auth-group. but only once. 138 */ 139 if (strcmp($1, "default") == 0 && 140 conf->conf_default_ag_defined == false) { 141 auth_group = auth_group_find(conf, $1); 142 conf->conf_default_ag_defined = true; 143 } else { 144 auth_group = auth_group_new(conf, $1); 145 } 146 free($1); 147 if (auth_group == NULL) 148 return (1); 149 } 150 ; 151 152auth_group_entries: 153 | 154 auth_group_entries auth_group_entry 155 ; 156 157auth_group_entry: 158 auth_group_auth_type 159 | 160 auth_group_chap 161 | 162 auth_group_chap_mutual 163 | 164 auth_group_initiator_name 165 | 166 auth_group_initiator_portal 167 ; 168 169auth_group_auth_type: AUTH_TYPE STR 170 { 171 int error; 172 173 error = auth_group_set_type_str(auth_group, $2); 174 free($2); 175 if (error != 0) 176 return (1); 177 } 178 ; 179 180auth_group_chap: CHAP STR STR 181 { 182 const struct auth *ca; 183 184 ca = auth_new_chap(auth_group, $2, $3); 185 free($2); 186 free($3); 187 if (ca == NULL) 188 return (1); 189 } 190 ; 191 192auth_group_chap_mutual: CHAP_MUTUAL STR STR STR STR 193 { 194 const struct auth *ca; 195 196 ca = auth_new_chap_mutual(auth_group, $2, $3, $4, $5); 197 free($2); 198 free($3); 199 free($4); 200 free($5); 201 if (ca == NULL) 202 return (1); 203 } 204 ; 205 206auth_group_initiator_name: INITIATOR_NAME STR 207 { 208 const struct auth_name *an; 209 210 an = auth_name_new(auth_group, $2); 211 free($2); 212 if (an == NULL) 213 return (1); 214 } 215 ; 216 217auth_group_initiator_portal: INITIATOR_PORTAL STR 218 { 219 const struct auth_portal *ap; 220 221 ap = auth_portal_new(auth_group, $2); 222 free($2); 223 if (ap == NULL) 224 return (1); 225 } 226 ; 227 228portal_group: PORTAL_GROUP portal_group_name 229 OPENING_BRACKET portal_group_entries CLOSING_BRACKET 230 { 231 portal_group = NULL; 232 } 233 ; 234 235portal_group_name: STR 236 { 237 /* 238 * Make it possible to redefine default 239 * portal-group. but only once. 240 */ 241 if (strcmp($1, "default") == 0 && 242 conf->conf_default_pg_defined == false) { 243 portal_group = portal_group_find(conf, $1); 244 conf->conf_default_pg_defined = true; 245 } else { 246 portal_group = portal_group_new(conf, $1); 247 } 248 free($1); 249 if (portal_group == NULL) 250 return (1); 251 } 252 ; 253 254portal_group_entries: 255 | 256 portal_group_entries portal_group_entry 257 ; 258 259portal_group_entry: 260 portal_group_discovery_auth_group 261 | 262 portal_group_listen 263 | 264 portal_group_listen_iser 265 ; 266 267portal_group_discovery_auth_group: DISCOVERY_AUTH_GROUP STR 268 { 269 if (portal_group->pg_discovery_auth_group != NULL) { 270 log_warnx("discovery-auth-group for portal-group " 271 "\"%s\" specified more than once", 272 portal_group->pg_name); 273 return (1); 274 } 275 portal_group->pg_discovery_auth_group = 276 auth_group_find(conf, $2); 277 if (portal_group->pg_discovery_auth_group == NULL) { 278 log_warnx("unknown discovery-auth-group \"%s\" " 279 "for portal-group \"%s\"", 280 $2, portal_group->pg_name); 281 return (1); 282 } 283 free($2); 284 } 285 ; 286 287portal_group_listen: LISTEN STR 288 { 289 int error; 290 291 error = portal_group_add_listen(portal_group, $2, false); 292 free($2); 293 if (error != 0) 294 return (1); 295 } 296 ; 297 298portal_group_listen_iser: LISTEN_ISER STR 299 { 300 int error; 301 302 error = portal_group_add_listen(portal_group, $2, true); 303 free($2); 304 if (error != 0) 305 return (1); 306 } 307 ; 308 309target: TARGET target_name 310 OPENING_BRACKET target_entries CLOSING_BRACKET 311 { 312 target = NULL; 313 } 314 ; 315 316target_name: STR 317 { 318 target = target_new(conf, $1); 319 free($1); 320 if (target == NULL) 321 return (1); 322 } 323 ; 324 325target_entries: 326 | 327 target_entries target_entry 328 ; 329 330target_entry: 331 target_alias 332 | 333 target_auth_group 334 | 335 target_auth_type 336 | 337 target_chap 338 | 339 target_chap_mutual 340 | 341 target_initiator_name 342 | 343 target_initiator_portal 344 | 345 target_portal_group 346 | 347 target_lun 348 ; 349 350target_alias: ALIAS STR 351 { 352 if (target->t_alias != NULL) { 353 log_warnx("alias for target \"%s\" " 354 "specified more than once", target->t_name); 355 return (1); 356 } 357 target->t_alias = $2; 358 } 359 ; 360 361target_auth_group: AUTH_GROUP STR 362 { 363 if (target->t_auth_group != NULL) { 364 if (target->t_auth_group->ag_name != NULL) 365 log_warnx("auth-group for target \"%s\" " 366 "specified more than once", target->t_name); 367 else 368 log_warnx("cannot use both auth-group and explicit " 369 "authorisations for target \"%s\"", 370 target->t_name); 371 return (1); 372 } 373 target->t_auth_group = auth_group_find(conf, $2); 374 if (target->t_auth_group == NULL) { 375 log_warnx("unknown auth-group \"%s\" for target " 376 "\"%s\"", $2, target->t_name); 377 return (1); 378 } 379 free($2); 380 } 381 ; 382 383target_auth_type: AUTH_TYPE STR 384 { 385 int error; 386 387 if (target->t_auth_group != NULL) { 388 if (target->t_auth_group->ag_name != NULL) { 389 log_warnx("cannot use both auth-group and " 390 "auth-type for target \"%s\"", 391 target->t_name); 392 return (1); 393 } 394 } else { 395 target->t_auth_group = auth_group_new(conf, NULL); 396 if (target->t_auth_group == NULL) { 397 free($2); 398 return (1); 399 } 400 target->t_auth_group->ag_target = target; 401 } 402 error = auth_group_set_type_str(target->t_auth_group, $2); 403 free($2); 404 if (error != 0) 405 return (1); 406 } 407 ; 408 409target_chap: CHAP STR STR 410 { 411 const struct auth *ca; 412 413 if (target->t_auth_group != NULL) { 414 if (target->t_auth_group->ag_name != NULL) { 415 log_warnx("cannot use both auth-group and " 416 "chap for target \"%s\"", 417 target->t_name); 418 free($2); 419 free($3); 420 return (1); 421 } 422 } else { 423 target->t_auth_group = auth_group_new(conf, NULL); 424 if (target->t_auth_group == NULL) { 425 free($2); 426 free($3); 427 return (1); 428 } 429 target->t_auth_group->ag_target = target; 430 } 431 ca = auth_new_chap(target->t_auth_group, $2, $3); 432 free($2); 433 free($3); 434 if (ca == NULL) 435 return (1); 436 } 437 ; 438 439target_chap_mutual: CHAP_MUTUAL STR STR STR STR 440 { 441 const struct auth *ca; 442 443 if (target->t_auth_group != NULL) { 444 if (target->t_auth_group->ag_name != NULL) { 445 log_warnx("cannot use both auth-group and " 446 "chap-mutual for target \"%s\"", 447 target->t_name); 448 free($2); 449 free($3); 450 free($4); 451 free($5); 452 return (1); 453 } 454 } else { 455 target->t_auth_group = auth_group_new(conf, NULL); 456 if (target->t_auth_group == NULL) { 457 free($2); 458 free($3); 459 free($4); 460 free($5); 461 return (1); 462 } 463 target->t_auth_group->ag_target = target; 464 } 465 ca = auth_new_chap_mutual(target->t_auth_group, 466 $2, $3, $4, $5); 467 free($2); 468 free($3); 469 free($4); 470 free($5); 471 if (ca == NULL) 472 return (1); 473 } 474 ; 475 476target_initiator_name: INITIATOR_NAME STR 477 { 478 const struct auth_name *an; 479 480 if (target->t_auth_group != NULL) { 481 if (target->t_auth_group->ag_name != NULL) { 482 log_warnx("cannot use both auth-group and " 483 "initiator-name for target \"%s\"", 484 target->t_name); 485 free($2); 486 return (1); 487 } 488 } else { 489 target->t_auth_group = auth_group_new(conf, NULL); 490 if (target->t_auth_group == NULL) { 491 free($2); 492 return (1); 493 } 494 target->t_auth_group->ag_target = target; 495 } 496 an = auth_name_new(target->t_auth_group, $2); 497 free($2); 498 if (an == NULL) 499 return (1); 500 } 501 ; 502 503target_initiator_portal: INITIATOR_PORTAL STR 504 { 505 const struct auth_portal *ap; 506 507 if (target->t_auth_group != NULL) { 508 if (target->t_auth_group->ag_name != NULL) { 509 log_warnx("cannot use both auth-group and " 510 "initiator-portal for target \"%s\"", 511 target->t_name); 512 free($2); 513 return (1); 514 } 515 } else { 516 target->t_auth_group = auth_group_new(conf, NULL); 517 if (target->t_auth_group == NULL) { 518 free($2); 519 return (1); 520 } 521 target->t_auth_group->ag_target = target; 522 } 523 ap = auth_portal_new(target->t_auth_group, $2); 524 free($2); 525 if (ap == NULL) 526 return (1); 527 } 528 ; 529 530target_portal_group: PORTAL_GROUP STR 531 { 532 if (target->t_portal_group != NULL) { 533 log_warnx("portal-group for target \"%s\" " 534 "specified more than once", target->t_name); 535 free($2); 536 return (1); 537 } 538 target->t_portal_group = portal_group_find(conf, $2); 539 if (target->t_portal_group == NULL) { 540 log_warnx("unknown portal-group \"%s\" for target " 541 "\"%s\"", $2, target->t_name); 542 free($2); 543 return (1); 544 } 545 free($2); 546 } 547 ; 548 549target_lun: LUN lun_number 550 OPENING_BRACKET lun_entries CLOSING_BRACKET 551 { 552 lun = NULL; 553 } 554 ; 555 556lun_number: NUM 557 { 558 lun = lun_new(target, $1); 559 if (lun == NULL) 560 return (1); 561 } 562 ; 563 564lun_entries: 565 | 566 lun_entries lun_entry 567 ; 568 569lun_entry: 570 lun_backend 571 | 572 lun_blocksize 573 | 574 lun_device_id 575 | 576 lun_option 577 | 578 lun_path 579 | 580 lun_serial 581 | 582 lun_size 583 ; 584 585lun_backend: BACKEND STR 586 { 587 if (lun->l_backend != NULL) { 588 log_warnx("backend for lun %d, target \"%s\" " 589 "specified more than once", 590 lun->l_lun, target->t_name); 591 free($2); 592 return (1); 593 } 594 lun_set_backend(lun, $2); 595 free($2); 596 } 597 ; 598 599lun_blocksize: BLOCKSIZE NUM 600 { 601 if (lun->l_blocksize != 0) { 602 log_warnx("blocksize for lun %d, target \"%s\" " 603 "specified more than once", 604 lun->l_lun, target->t_name); 605 return (1); 606 } 607 lun_set_blocksize(lun, $2); 608 } 609 ; 610 611lun_device_id: DEVICE_ID STR 612 { 613 if (lun->l_device_id != NULL) { 614 log_warnx("device_id for lun %d, target \"%s\" " 615 "specified more than once", 616 lun->l_lun, target->t_name); 617 free($2); 618 return (1); 619 } 620 lun_set_device_id(lun, $2); 621 free($2); 622 } 623 ; 624 625lun_option: OPTION STR STR 626 { 627 struct lun_option *clo; 628 629 clo = lun_option_new(lun, $2, $3); 630 free($2); 631 free($3); 632 if (clo == NULL) 633 return (1); 634 } 635 ; 636 637lun_path: PATH STR 638 { 639 if (lun->l_path != NULL) { 640 log_warnx("path for lun %d, target \"%s\" " 641 "specified more than once", 642 lun->l_lun, target->t_name); 643 free($2); 644 return (1); 645 } 646 lun_set_path(lun, $2); 647 free($2); 648 } 649 ; 650 651lun_serial: SERIAL STR 652 { 653 if (lun->l_serial != NULL) { 654 log_warnx("serial for lun %d, target \"%s\" " 655 "specified more than once", 656 lun->l_lun, target->t_name); 657 free($2); 658 return (1); 659 } 660 lun_set_serial(lun, $2); 661 free($2); 662 } | SERIAL NUM 663 { 664 char *str = NULL; 665 666 if (lun->l_serial != NULL) { 667 log_warnx("serial for lun %d, target \"%s\" " 668 "specified more than once", 669 lun->l_lun, target->t_name); 670 return (1); 671 } 672 asprintf(&str, "%ju", $2); 673 lun_set_serial(lun, str); 674 free(str); 675 } 676 ; 677 678lun_size: SIZE NUM 679 { 680 if (lun->l_size != 0) { 681 log_warnx("size for lun %d, target \"%s\" " 682 "specified more than once", 683 lun->l_lun, target->t_name); 684 return (1); 685 } 686 lun_set_size(lun, $2); 687 } 688 ; 689%% 690 691void 692yyerror(const char *str) 693{ 694 695 log_warnx("error in configuration file at line %d near '%s': %s", 696 lineno, yytext, str); 697} 698 699static void 700check_perms(const char *path) 701{ 702 struct stat sb; 703 int error; 704 705 error = stat(path, &sb); 706 if (error != 0) { 707 log_warn("stat"); 708 return; 709 } 710 if (sb.st_mode & S_IWOTH) { 711 log_warnx("%s is world-writable", path); 712 } else if (sb.st_mode & S_IROTH) { 713 log_warnx("%s is world-readable", path); 714 } else if (sb.st_mode & S_IXOTH) { 715 /* 716 * Ok, this one doesn't matter, but still do it, 717 * just for consistency. 718 */ 719 log_warnx("%s is world-executable", path); 720 } 721 722 /* 723 * XXX: Should we also check for owner != 0? 724 */ 725} 726 727struct conf * 728conf_new_from_file(const char *path) 729{ 730 struct auth_group *ag; 731 struct portal_group *pg; 732 int error; 733 734 log_debugx("obtaining configuration from %s", path); 735 736 conf = conf_new(); 737 738 ag = auth_group_new(conf, "default"); 739 assert(ag != NULL); 740 741 ag = auth_group_new(conf, "no-authentication"); 742 assert(ag != NULL); 743 ag->ag_type = AG_TYPE_NO_AUTHENTICATION; 744 745 ag = auth_group_new(conf, "no-access"); 746 assert(ag != NULL); 747 ag->ag_type = AG_TYPE_DENY; 748 749 pg = portal_group_new(conf, "default"); 750 assert(pg != NULL); 751 752 yyin = fopen(path, "r"); 753 if (yyin == NULL) { 754 log_warn("unable to open configuration file %s", path); 755 conf_delete(conf); 756 return (NULL); 757 } 758 check_perms(path); 759 lineno = 1; 760 yyrestart(yyin); 761 error = yyparse(); 762 auth_group = NULL; 763 portal_group = NULL; 764 target = NULL; 765 lun = NULL; 766 fclose(yyin); 767 if (error != 0) { 768 conf_delete(conf); 769 return (NULL); 770 } 771 772 if (conf->conf_default_ag_defined == false) { 773 log_debugx("auth-group \"default\" not defined; " 774 "going with defaults"); 775 ag = auth_group_find(conf, "default"); 776 assert(ag != NULL); 777 ag->ag_type = AG_TYPE_DENY; 778 } 779 780 if (conf->conf_default_pg_defined == false) { 781 log_debugx("portal-group \"default\" not defined; " 782 "going with defaults"); 783 pg = portal_group_find(conf, "default"); 784 assert(pg != NULL); 785 portal_group_add_listen(pg, "0.0.0.0:3260", false); 786 portal_group_add_listen(pg, "[::]:3260", false); 787 } 788 789 conf->conf_kernel_port_on = true; 790 791 error = conf_verify(conf); 792 if (error != 0) { 793 conf_delete(conf); 794 return (NULL); 795 } 796 797 return (conf); 798}
| 156auth_group: AUTH_GROUP auth_group_name 157 OPENING_BRACKET auth_group_entries CLOSING_BRACKET 158 { 159 auth_group = NULL; 160 } 161 ; 162 163auth_group_name: STR 164 { 165 /* 166 * Make it possible to redefine default 167 * auth-group. but only once. 168 */ 169 if (strcmp($1, "default") == 0 && 170 conf->conf_default_ag_defined == false) { 171 auth_group = auth_group_find(conf, $1); 172 conf->conf_default_ag_defined = true; 173 } else { 174 auth_group = auth_group_new(conf, $1); 175 } 176 free($1); 177 if (auth_group == NULL) 178 return (1); 179 } 180 ; 181 182auth_group_entries: 183 | 184 auth_group_entries auth_group_entry 185 ; 186 187auth_group_entry: 188 auth_group_auth_type 189 | 190 auth_group_chap 191 | 192 auth_group_chap_mutual 193 | 194 auth_group_initiator_name 195 | 196 auth_group_initiator_portal 197 ; 198 199auth_group_auth_type: AUTH_TYPE STR 200 { 201 int error; 202 203 error = auth_group_set_type_str(auth_group, $2); 204 free($2); 205 if (error != 0) 206 return (1); 207 } 208 ; 209 210auth_group_chap: CHAP STR STR 211 { 212 const struct auth *ca; 213 214 ca = auth_new_chap(auth_group, $2, $3); 215 free($2); 216 free($3); 217 if (ca == NULL) 218 return (1); 219 } 220 ; 221 222auth_group_chap_mutual: CHAP_MUTUAL STR STR STR STR 223 { 224 const struct auth *ca; 225 226 ca = auth_new_chap_mutual(auth_group, $2, $3, $4, $5); 227 free($2); 228 free($3); 229 free($4); 230 free($5); 231 if (ca == NULL) 232 return (1); 233 } 234 ; 235 236auth_group_initiator_name: INITIATOR_NAME STR 237 { 238 const struct auth_name *an; 239 240 an = auth_name_new(auth_group, $2); 241 free($2); 242 if (an == NULL) 243 return (1); 244 } 245 ; 246 247auth_group_initiator_portal: INITIATOR_PORTAL STR 248 { 249 const struct auth_portal *ap; 250 251 ap = auth_portal_new(auth_group, $2); 252 free($2); 253 if (ap == NULL) 254 return (1); 255 } 256 ; 257 258portal_group: PORTAL_GROUP portal_group_name 259 OPENING_BRACKET portal_group_entries CLOSING_BRACKET 260 { 261 portal_group = NULL; 262 } 263 ; 264 265portal_group_name: STR 266 { 267 /* 268 * Make it possible to redefine default 269 * portal-group. but only once. 270 */ 271 if (strcmp($1, "default") == 0 && 272 conf->conf_default_pg_defined == false) { 273 portal_group = portal_group_find(conf, $1); 274 conf->conf_default_pg_defined = true; 275 } else { 276 portal_group = portal_group_new(conf, $1); 277 } 278 free($1); 279 if (portal_group == NULL) 280 return (1); 281 } 282 ; 283 284portal_group_entries: 285 | 286 portal_group_entries portal_group_entry 287 ; 288 289portal_group_entry: 290 portal_group_discovery_auth_group 291 | 292 portal_group_listen 293 | 294 portal_group_listen_iser 295 ; 296 297portal_group_discovery_auth_group: DISCOVERY_AUTH_GROUP STR 298 { 299 if (portal_group->pg_discovery_auth_group != NULL) { 300 log_warnx("discovery-auth-group for portal-group " 301 "\"%s\" specified more than once", 302 portal_group->pg_name); 303 return (1); 304 } 305 portal_group->pg_discovery_auth_group = 306 auth_group_find(conf, $2); 307 if (portal_group->pg_discovery_auth_group == NULL) { 308 log_warnx("unknown discovery-auth-group \"%s\" " 309 "for portal-group \"%s\"", 310 $2, portal_group->pg_name); 311 return (1); 312 } 313 free($2); 314 } 315 ; 316 317portal_group_listen: LISTEN STR 318 { 319 int error; 320 321 error = portal_group_add_listen(portal_group, $2, false); 322 free($2); 323 if (error != 0) 324 return (1); 325 } 326 ; 327 328portal_group_listen_iser: LISTEN_ISER STR 329 { 330 int error; 331 332 error = portal_group_add_listen(portal_group, $2, true); 333 free($2); 334 if (error != 0) 335 return (1); 336 } 337 ; 338 339target: TARGET target_name 340 OPENING_BRACKET target_entries CLOSING_BRACKET 341 { 342 target = NULL; 343 } 344 ; 345 346target_name: STR 347 { 348 target = target_new(conf, $1); 349 free($1); 350 if (target == NULL) 351 return (1); 352 } 353 ; 354 355target_entries: 356 | 357 target_entries target_entry 358 ; 359 360target_entry: 361 target_alias 362 | 363 target_auth_group 364 | 365 target_auth_type 366 | 367 target_chap 368 | 369 target_chap_mutual 370 | 371 target_initiator_name 372 | 373 target_initiator_portal 374 | 375 target_portal_group 376 | 377 target_lun 378 ; 379 380target_alias: ALIAS STR 381 { 382 if (target->t_alias != NULL) { 383 log_warnx("alias for target \"%s\" " 384 "specified more than once", target->t_name); 385 return (1); 386 } 387 target->t_alias = $2; 388 } 389 ; 390 391target_auth_group: AUTH_GROUP STR 392 { 393 if (target->t_auth_group != NULL) { 394 if (target->t_auth_group->ag_name != NULL) 395 log_warnx("auth-group for target \"%s\" " 396 "specified more than once", target->t_name); 397 else 398 log_warnx("cannot use both auth-group and explicit " 399 "authorisations for target \"%s\"", 400 target->t_name); 401 return (1); 402 } 403 target->t_auth_group = auth_group_find(conf, $2); 404 if (target->t_auth_group == NULL) { 405 log_warnx("unknown auth-group \"%s\" for target " 406 "\"%s\"", $2, target->t_name); 407 return (1); 408 } 409 free($2); 410 } 411 ; 412 413target_auth_type: AUTH_TYPE STR 414 { 415 int error; 416 417 if (target->t_auth_group != NULL) { 418 if (target->t_auth_group->ag_name != NULL) { 419 log_warnx("cannot use both auth-group and " 420 "auth-type for target \"%s\"", 421 target->t_name); 422 return (1); 423 } 424 } else { 425 target->t_auth_group = auth_group_new(conf, NULL); 426 if (target->t_auth_group == NULL) { 427 free($2); 428 return (1); 429 } 430 target->t_auth_group->ag_target = target; 431 } 432 error = auth_group_set_type_str(target->t_auth_group, $2); 433 free($2); 434 if (error != 0) 435 return (1); 436 } 437 ; 438 439target_chap: CHAP STR STR 440 { 441 const struct auth *ca; 442 443 if (target->t_auth_group != NULL) { 444 if (target->t_auth_group->ag_name != NULL) { 445 log_warnx("cannot use both auth-group and " 446 "chap for target \"%s\"", 447 target->t_name); 448 free($2); 449 free($3); 450 return (1); 451 } 452 } else { 453 target->t_auth_group = auth_group_new(conf, NULL); 454 if (target->t_auth_group == NULL) { 455 free($2); 456 free($3); 457 return (1); 458 } 459 target->t_auth_group->ag_target = target; 460 } 461 ca = auth_new_chap(target->t_auth_group, $2, $3); 462 free($2); 463 free($3); 464 if (ca == NULL) 465 return (1); 466 } 467 ; 468 469target_chap_mutual: CHAP_MUTUAL STR STR STR STR 470 { 471 const struct auth *ca; 472 473 if (target->t_auth_group != NULL) { 474 if (target->t_auth_group->ag_name != NULL) { 475 log_warnx("cannot use both auth-group and " 476 "chap-mutual for target \"%s\"", 477 target->t_name); 478 free($2); 479 free($3); 480 free($4); 481 free($5); 482 return (1); 483 } 484 } else { 485 target->t_auth_group = auth_group_new(conf, NULL); 486 if (target->t_auth_group == NULL) { 487 free($2); 488 free($3); 489 free($4); 490 free($5); 491 return (1); 492 } 493 target->t_auth_group->ag_target = target; 494 } 495 ca = auth_new_chap_mutual(target->t_auth_group, 496 $2, $3, $4, $5); 497 free($2); 498 free($3); 499 free($4); 500 free($5); 501 if (ca == NULL) 502 return (1); 503 } 504 ; 505 506target_initiator_name: INITIATOR_NAME STR 507 { 508 const struct auth_name *an; 509 510 if (target->t_auth_group != NULL) { 511 if (target->t_auth_group->ag_name != NULL) { 512 log_warnx("cannot use both auth-group and " 513 "initiator-name for target \"%s\"", 514 target->t_name); 515 free($2); 516 return (1); 517 } 518 } else { 519 target->t_auth_group = auth_group_new(conf, NULL); 520 if (target->t_auth_group == NULL) { 521 free($2); 522 return (1); 523 } 524 target->t_auth_group->ag_target = target; 525 } 526 an = auth_name_new(target->t_auth_group, $2); 527 free($2); 528 if (an == NULL) 529 return (1); 530 } 531 ; 532 533target_initiator_portal: INITIATOR_PORTAL STR 534 { 535 const struct auth_portal *ap; 536 537 if (target->t_auth_group != NULL) { 538 if (target->t_auth_group->ag_name != NULL) { 539 log_warnx("cannot use both auth-group and " 540 "initiator-portal for target \"%s\"", 541 target->t_name); 542 free($2); 543 return (1); 544 } 545 } else { 546 target->t_auth_group = auth_group_new(conf, NULL); 547 if (target->t_auth_group == NULL) { 548 free($2); 549 return (1); 550 } 551 target->t_auth_group->ag_target = target; 552 } 553 ap = auth_portal_new(target->t_auth_group, $2); 554 free($2); 555 if (ap == NULL) 556 return (1); 557 } 558 ; 559 560target_portal_group: PORTAL_GROUP STR 561 { 562 if (target->t_portal_group != NULL) { 563 log_warnx("portal-group for target \"%s\" " 564 "specified more than once", target->t_name); 565 free($2); 566 return (1); 567 } 568 target->t_portal_group = portal_group_find(conf, $2); 569 if (target->t_portal_group == NULL) { 570 log_warnx("unknown portal-group \"%s\" for target " 571 "\"%s\"", $2, target->t_name); 572 free($2); 573 return (1); 574 } 575 free($2); 576 } 577 ; 578 579target_lun: LUN lun_number 580 OPENING_BRACKET lun_entries CLOSING_BRACKET 581 { 582 lun = NULL; 583 } 584 ; 585 586lun_number: NUM 587 { 588 lun = lun_new(target, $1); 589 if (lun == NULL) 590 return (1); 591 } 592 ; 593 594lun_entries: 595 | 596 lun_entries lun_entry 597 ; 598 599lun_entry: 600 lun_backend 601 | 602 lun_blocksize 603 | 604 lun_device_id 605 | 606 lun_option 607 | 608 lun_path 609 | 610 lun_serial 611 | 612 lun_size 613 ; 614 615lun_backend: BACKEND STR 616 { 617 if (lun->l_backend != NULL) { 618 log_warnx("backend for lun %d, target \"%s\" " 619 "specified more than once", 620 lun->l_lun, target->t_name); 621 free($2); 622 return (1); 623 } 624 lun_set_backend(lun, $2); 625 free($2); 626 } 627 ; 628 629lun_blocksize: BLOCKSIZE NUM 630 { 631 if (lun->l_blocksize != 0) { 632 log_warnx("blocksize for lun %d, target \"%s\" " 633 "specified more than once", 634 lun->l_lun, target->t_name); 635 return (1); 636 } 637 lun_set_blocksize(lun, $2); 638 } 639 ; 640 641lun_device_id: DEVICE_ID STR 642 { 643 if (lun->l_device_id != NULL) { 644 log_warnx("device_id for lun %d, target \"%s\" " 645 "specified more than once", 646 lun->l_lun, target->t_name); 647 free($2); 648 return (1); 649 } 650 lun_set_device_id(lun, $2); 651 free($2); 652 } 653 ; 654 655lun_option: OPTION STR STR 656 { 657 struct lun_option *clo; 658 659 clo = lun_option_new(lun, $2, $3); 660 free($2); 661 free($3); 662 if (clo == NULL) 663 return (1); 664 } 665 ; 666 667lun_path: PATH STR 668 { 669 if (lun->l_path != NULL) { 670 log_warnx("path for lun %d, target \"%s\" " 671 "specified more than once", 672 lun->l_lun, target->t_name); 673 free($2); 674 return (1); 675 } 676 lun_set_path(lun, $2); 677 free($2); 678 } 679 ; 680 681lun_serial: SERIAL STR 682 { 683 if (lun->l_serial != NULL) { 684 log_warnx("serial for lun %d, target \"%s\" " 685 "specified more than once", 686 lun->l_lun, target->t_name); 687 free($2); 688 return (1); 689 } 690 lun_set_serial(lun, $2); 691 free($2); 692 } | SERIAL NUM 693 { 694 char *str = NULL; 695 696 if (lun->l_serial != NULL) { 697 log_warnx("serial for lun %d, target \"%s\" " 698 "specified more than once", 699 lun->l_lun, target->t_name); 700 return (1); 701 } 702 asprintf(&str, "%ju", $2); 703 lun_set_serial(lun, str); 704 free(str); 705 } 706 ; 707 708lun_size: SIZE NUM 709 { 710 if (lun->l_size != 0) { 711 log_warnx("size for lun %d, target \"%s\" " 712 "specified more than once", 713 lun->l_lun, target->t_name); 714 return (1); 715 } 716 lun_set_size(lun, $2); 717 } 718 ; 719%% 720 721void 722yyerror(const char *str) 723{ 724 725 log_warnx("error in configuration file at line %d near '%s': %s", 726 lineno, yytext, str); 727} 728 729static void 730check_perms(const char *path) 731{ 732 struct stat sb; 733 int error; 734 735 error = stat(path, &sb); 736 if (error != 0) { 737 log_warn("stat"); 738 return; 739 } 740 if (sb.st_mode & S_IWOTH) { 741 log_warnx("%s is world-writable", path); 742 } else if (sb.st_mode & S_IROTH) { 743 log_warnx("%s is world-readable", path); 744 } else if (sb.st_mode & S_IXOTH) { 745 /* 746 * Ok, this one doesn't matter, but still do it, 747 * just for consistency. 748 */ 749 log_warnx("%s is world-executable", path); 750 } 751 752 /* 753 * XXX: Should we also check for owner != 0? 754 */ 755} 756 757struct conf * 758conf_new_from_file(const char *path) 759{ 760 struct auth_group *ag; 761 struct portal_group *pg; 762 int error; 763 764 log_debugx("obtaining configuration from %s", path); 765 766 conf = conf_new(); 767 768 ag = auth_group_new(conf, "default"); 769 assert(ag != NULL); 770 771 ag = auth_group_new(conf, "no-authentication"); 772 assert(ag != NULL); 773 ag->ag_type = AG_TYPE_NO_AUTHENTICATION; 774 775 ag = auth_group_new(conf, "no-access"); 776 assert(ag != NULL); 777 ag->ag_type = AG_TYPE_DENY; 778 779 pg = portal_group_new(conf, "default"); 780 assert(pg != NULL); 781 782 yyin = fopen(path, "r"); 783 if (yyin == NULL) { 784 log_warn("unable to open configuration file %s", path); 785 conf_delete(conf); 786 return (NULL); 787 } 788 check_perms(path); 789 lineno = 1; 790 yyrestart(yyin); 791 error = yyparse(); 792 auth_group = NULL; 793 portal_group = NULL; 794 target = NULL; 795 lun = NULL; 796 fclose(yyin); 797 if (error != 0) { 798 conf_delete(conf); 799 return (NULL); 800 } 801 802 if (conf->conf_default_ag_defined == false) { 803 log_debugx("auth-group \"default\" not defined; " 804 "going with defaults"); 805 ag = auth_group_find(conf, "default"); 806 assert(ag != NULL); 807 ag->ag_type = AG_TYPE_DENY; 808 } 809 810 if (conf->conf_default_pg_defined == false) { 811 log_debugx("portal-group \"default\" not defined; " 812 "going with defaults"); 813 pg = portal_group_find(conf, "default"); 814 assert(pg != NULL); 815 portal_group_add_listen(pg, "0.0.0.0:3260", false); 816 portal_group_add_listen(pg, "[::]:3260", false); 817 } 818 819 conf->conf_kernel_port_on = true; 820 821 error = conf_verify(conf); 822 if (error != 0) { 823 conf_delete(conf); 824 return (NULL); 825 } 826 827 return (conf); 828}
|