1255570Strasz%{ 2255570Strasz/*- 3255570Strasz * Copyright (c) 2012 The FreeBSD Foundation 4255570Strasz * All rights reserved. 5255570Strasz * 6255570Strasz * This software was developed by Edward Tomasz Napierala under sponsorship 7255570Strasz * from the FreeBSD Foundation. 8255570Strasz * 9255570Strasz * Redistribution and use in source and binary forms, with or without 10255570Strasz * modification, are permitted provided that the following conditions 11255570Strasz * are met: 12255570Strasz * 1. Redistributions of source code must retain the above copyright 13255570Strasz * notice, this list of conditions and the following disclaimer. 14255570Strasz * 2. Redistributions in binary form must reproduce the above copyright 15255570Strasz * notice, this list of conditions and the following disclaimer in the 16255570Strasz * documentation and/or other materials provided with the distribution. 17255570Strasz * 18255570Strasz * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 19255570Strasz * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20255570Strasz * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21255570Strasz * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 22255570Strasz * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23255570Strasz * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 24255570Strasz * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 25255570Strasz * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 26255570Strasz * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 27255570Strasz * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 28255570Strasz * SUCH DAMAGE. 29255570Strasz * 30255570Strasz * $FreeBSD: stable/10/usr.sbin/ctld/parse.y 311866 2017-01-10 08:25:03Z mav $ 31255570Strasz */ 32255570Strasz 33255570Strasz#include <sys/queue.h> 34255570Strasz#include <sys/types.h> 35255570Strasz#include <sys/stat.h> 36255570Strasz#include <assert.h> 37255570Strasz#include <stdio.h> 38255570Strasz#include <stdlib.h> 39255570Strasz#include <string.h> 40255570Strasz 41255570Strasz#include "ctld.h" 42255570Strasz 43255570Straszextern FILE *yyin; 44255570Straszextern char *yytext; 45255570Straszextern int lineno; 46255570Strasz 47255570Straszstatic struct conf *conf = NULL; 48255570Straszstatic struct auth_group *auth_group = NULL; 49255570Straszstatic struct portal_group *portal_group = NULL; 50255570Straszstatic struct target *target = NULL; 51255570Straszstatic struct lun *lun = NULL; 52255570Strasz 53255570Straszextern void yyerror(const char *); 54255570Straszextern int yylex(void); 55255570Straszextern void yyrestart(FILE *); 56255570Strasz 57255570Strasz%} 58255570Strasz 59263724Strasz%token ALIAS AUTH_GROUP AUTH_TYPE BACKEND BLOCKSIZE CHAP CHAP_MUTUAL 60288810Smav%token CLOSING_BRACKET CTL_LUN DEBUG DEVICE_ID DEVICE_TYPE 61288810Smav%token DISCOVERY_AUTH_GROUP DISCOVERY_FILTER FOREIGN 62275247Strasz%token INITIATOR_NAME INITIATOR_PORTAL ISNS_SERVER ISNS_PERIOD ISNS_TIMEOUT 63275247Strasz%token LISTEN LISTEN_ISER LUN MAXPROC OPENING_BRACKET OPTION 64279055Smav%token PATH PIDFILE PORT PORTAL_GROUP REDIRECT SEMICOLON SERIAL SIZE STR 65288729Smav%token TAG TARGET TIMEOUT 66255570Strasz 67255570Strasz%union 68255570Strasz{ 69255570Strasz char *str; 70255570Strasz} 71255570Strasz 72255570Strasz%token <str> STR 73255570Strasz 74255570Strasz%% 75255570Strasz 76255570Straszstatements: 77255570Strasz | 78255570Strasz statements statement 79275246Strasz | 80275246Strasz statements statement SEMICOLON 81255570Strasz ; 82255570Strasz 83255570Straszstatement: 84263722Strasz debug 85255570Strasz | 86263722Strasz timeout 87255570Strasz | 88263722Strasz maxproc 89255570Strasz | 90263722Strasz pidfile 91255570Strasz | 92274939Smav isns_server 93274939Smav | 94274939Smav isns_period 95274939Smav | 96274939Smav isns_timeout 97274939Smav | 98263722Strasz auth_group 99255570Strasz | 100263722Strasz portal_group 101255570Strasz | 102279002Smav lun 103279002Smav | 104263722Strasz target 105255570Strasz ; 106255570Strasz 107275186Straszdebug: DEBUG STR 108255570Strasz { 109275186Strasz uint64_t tmp; 110275186Strasz 111275186Strasz if (expand_number($2, &tmp) != 0) { 112275187Strasz yyerror("invalid numeric value"); 113275186Strasz free($2); 114275186Strasz return (1); 115275186Strasz } 116275186Strasz 117275186Strasz conf->conf_debug = tmp; 118255570Strasz } 119255570Strasz ; 120255570Strasz 121275186Strasztimeout: TIMEOUT STR 122255570Strasz { 123275186Strasz uint64_t tmp; 124275186Strasz 125275186Strasz if (expand_number($2, &tmp) != 0) { 126275187Strasz yyerror("invalid numeric value"); 127275186Strasz free($2); 128275186Strasz return (1); 129275186Strasz } 130275186Strasz 131275186Strasz conf->conf_timeout = tmp; 132255570Strasz } 133255570Strasz ; 134255570Strasz 135275186Straszmaxproc: MAXPROC STR 136255570Strasz { 137275186Strasz uint64_t tmp; 138275186Strasz 139275186Strasz if (expand_number($2, &tmp) != 0) { 140275187Strasz yyerror("invalid numeric value"); 141275186Strasz free($2); 142275186Strasz return (1); 143275186Strasz } 144275186Strasz 145275186Strasz conf->conf_maxproc = tmp; 146255570Strasz } 147255570Strasz ; 148255570Strasz 149263722Straszpidfile: PIDFILE STR 150255570Strasz { 151255570Strasz if (conf->conf_pidfile_path != NULL) { 152255570Strasz log_warnx("pidfile specified more than once"); 153255570Strasz free($2); 154255570Strasz return (1); 155255570Strasz } 156255570Strasz conf->conf_pidfile_path = $2; 157255570Strasz } 158255570Strasz ; 159255570Strasz 160274939Smavisns_server: ISNS_SERVER STR 161274939Smav { 162274939Smav int error; 163274939Smav 164274939Smav error = isns_new(conf, $2); 165274939Smav free($2); 166274939Smav if (error != 0) 167274939Smav return (1); 168274939Smav } 169274939Smav ; 170274939Smav 171275187Straszisns_period: ISNS_PERIOD STR 172274939Smav { 173275187Strasz uint64_t tmp; 174275187Strasz 175275187Strasz if (expand_number($2, &tmp) != 0) { 176275187Strasz yyerror("invalid numeric value"); 177275187Strasz free($2); 178275187Strasz return (1); 179275187Strasz } 180275187Strasz 181275187Strasz conf->conf_isns_period = tmp; 182274939Smav } 183274939Smav ; 184274939Smav 185275187Straszisns_timeout: ISNS_TIMEOUT STR 186274939Smav { 187275187Strasz uint64_t tmp; 188275187Strasz 189275187Strasz if (expand_number($2, &tmp) != 0) { 190275187Strasz yyerror("invalid numeric value"); 191275187Strasz free($2); 192275187Strasz return (1); 193275187Strasz } 194275187Strasz 195275187Strasz conf->conf_isns_timeout = tmp; 196274939Smav } 197274939Smav ; 198274939Smav 199263722Straszauth_group: AUTH_GROUP auth_group_name 200255570Strasz OPENING_BRACKET auth_group_entries CLOSING_BRACKET 201255570Strasz { 202255570Strasz auth_group = NULL; 203255570Strasz } 204255570Strasz ; 205255570Strasz 206255570Straszauth_group_name: STR 207255570Strasz { 208263726Strasz /* 209263726Strasz * Make it possible to redefine default 210263726Strasz * auth-group. but only once. 211263726Strasz */ 212263726Strasz if (strcmp($1, "default") == 0 && 213263726Strasz conf->conf_default_ag_defined == false) { 214263726Strasz auth_group = auth_group_find(conf, $1); 215263726Strasz conf->conf_default_ag_defined = true; 216263726Strasz } else { 217263726Strasz auth_group = auth_group_new(conf, $1); 218263726Strasz } 219255570Strasz free($1); 220255570Strasz if (auth_group == NULL) 221255570Strasz return (1); 222255570Strasz } 223255570Strasz ; 224255570Strasz 225255570Straszauth_group_entries: 226255570Strasz | 227255570Strasz auth_group_entries auth_group_entry 228275246Strasz | 229275246Strasz auth_group_entries auth_group_entry SEMICOLON 230255570Strasz ; 231255570Strasz 232255570Straszauth_group_entry: 233263724Strasz auth_group_auth_type 234263724Strasz | 235255570Strasz auth_group_chap 236255570Strasz | 237255570Strasz auth_group_chap_mutual 238263720Strasz | 239263720Strasz auth_group_initiator_name 240263720Strasz | 241263720Strasz auth_group_initiator_portal 242255570Strasz ; 243255570Strasz 244263724Straszauth_group_auth_type: AUTH_TYPE STR 245263724Strasz { 246263724Strasz int error; 247263724Strasz 248275245Strasz error = auth_group_set_type(auth_group, $2); 249263724Strasz free($2); 250263724Strasz if (error != 0) 251263724Strasz return (1); 252263724Strasz } 253263724Strasz ; 254263724Strasz 255255570Straszauth_group_chap: CHAP STR STR 256255570Strasz { 257255570Strasz const struct auth *ca; 258255570Strasz 259255570Strasz ca = auth_new_chap(auth_group, $2, $3); 260255570Strasz free($2); 261255570Strasz free($3); 262255570Strasz if (ca == NULL) 263255570Strasz return (1); 264255570Strasz } 265255570Strasz ; 266255570Strasz 267255570Straszauth_group_chap_mutual: CHAP_MUTUAL STR STR STR STR 268255570Strasz { 269255570Strasz const struct auth *ca; 270255570Strasz 271255570Strasz ca = auth_new_chap_mutual(auth_group, $2, $3, $4, $5); 272255570Strasz free($2); 273255570Strasz free($3); 274255570Strasz free($4); 275255570Strasz free($5); 276255570Strasz if (ca == NULL) 277255570Strasz return (1); 278255570Strasz } 279255570Strasz ; 280255570Strasz 281263720Straszauth_group_initiator_name: INITIATOR_NAME STR 282263720Strasz { 283263720Strasz const struct auth_name *an; 284263720Strasz 285263720Strasz an = auth_name_new(auth_group, $2); 286263720Strasz free($2); 287263720Strasz if (an == NULL) 288263720Strasz return (1); 289263720Strasz } 290263720Strasz ; 291263720Strasz 292263720Straszauth_group_initiator_portal: INITIATOR_PORTAL STR 293263720Strasz { 294263720Strasz const struct auth_portal *ap; 295263720Strasz 296263720Strasz ap = auth_portal_new(auth_group, $2); 297263720Strasz free($2); 298263720Strasz if (ap == NULL) 299263720Strasz return (1); 300263720Strasz } 301263720Strasz ; 302263720Strasz 303263722Straszportal_group: PORTAL_GROUP portal_group_name 304255570Strasz OPENING_BRACKET portal_group_entries CLOSING_BRACKET 305255570Strasz { 306255570Strasz portal_group = NULL; 307255570Strasz } 308255570Strasz ; 309255570Strasz 310255570Straszportal_group_name: STR 311255570Strasz { 312263725Strasz /* 313263725Strasz * Make it possible to redefine default 314263725Strasz * portal-group. but only once. 315263725Strasz */ 316263725Strasz if (strcmp($1, "default") == 0 && 317263725Strasz conf->conf_default_pg_defined == false) { 318263725Strasz portal_group = portal_group_find(conf, $1); 319263725Strasz conf->conf_default_pg_defined = true; 320263725Strasz } else { 321263725Strasz portal_group = portal_group_new(conf, $1); 322263725Strasz } 323255570Strasz free($1); 324255570Strasz if (portal_group == NULL) 325255570Strasz return (1); 326255570Strasz } 327255570Strasz ; 328255570Strasz 329255570Straszportal_group_entries: 330255570Strasz | 331255570Strasz portal_group_entries portal_group_entry 332275246Strasz | 333275246Strasz portal_group_entries portal_group_entry SEMICOLON 334255570Strasz ; 335255570Strasz 336255570Straszportal_group_entry: 337255570Strasz portal_group_discovery_auth_group 338255570Strasz | 339275244Strasz portal_group_discovery_filter 340275244Strasz | 341288729Smav portal_group_foreign 342288729Smav | 343255570Strasz portal_group_listen 344255570Strasz | 345255570Strasz portal_group_listen_iser 346275642Strasz | 347291387Smav portal_group_option 348291387Smav | 349275642Strasz portal_group_redirect 350288729Smav | 351288729Smav portal_group_tag 352255570Strasz ; 353255570Strasz 354255570Straszportal_group_discovery_auth_group: DISCOVERY_AUTH_GROUP STR 355255570Strasz { 356255570Strasz if (portal_group->pg_discovery_auth_group != NULL) { 357255570Strasz log_warnx("discovery-auth-group for portal-group " 358255570Strasz "\"%s\" specified more than once", 359255570Strasz portal_group->pg_name); 360255570Strasz return (1); 361255570Strasz } 362255570Strasz portal_group->pg_discovery_auth_group = 363255570Strasz auth_group_find(conf, $2); 364255570Strasz if (portal_group->pg_discovery_auth_group == NULL) { 365255570Strasz log_warnx("unknown discovery-auth-group \"%s\" " 366255570Strasz "for portal-group \"%s\"", 367255570Strasz $2, portal_group->pg_name); 368255570Strasz return (1); 369255570Strasz } 370255570Strasz free($2); 371255570Strasz } 372255570Strasz ; 373255570Strasz 374275244Straszportal_group_discovery_filter: DISCOVERY_FILTER STR 375275244Strasz { 376275244Strasz int error; 377275244Strasz 378275245Strasz error = portal_group_set_filter(portal_group, $2); 379275244Strasz free($2); 380275244Strasz if (error != 0) 381275244Strasz return (1); 382275244Strasz } 383275244Strasz ; 384275244Strasz 385288729Smavportal_group_foreign: FOREIGN 386288729Smav { 387288729Smav 388288729Smav portal_group->pg_foreign = 1; 389288729Smav } 390288729Smav ; 391288729Smav 392255570Straszportal_group_listen: LISTEN STR 393255570Strasz { 394255570Strasz int error; 395255570Strasz 396255570Strasz error = portal_group_add_listen(portal_group, $2, false); 397255570Strasz free($2); 398255570Strasz if (error != 0) 399255570Strasz return (1); 400255570Strasz } 401255570Strasz ; 402255570Strasz 403255570Straszportal_group_listen_iser: LISTEN_ISER STR 404255570Strasz { 405255570Strasz int error; 406255570Strasz 407255570Strasz error = portal_group_add_listen(portal_group, $2, true); 408255570Strasz free($2); 409255570Strasz if (error != 0) 410255570Strasz return (1); 411255570Strasz } 412255570Strasz ; 413255570Strasz 414291387Smavportal_group_option: OPTION STR STR 415291387Smav { 416291387Smav struct option *o; 417291387Smav 418291387Smav o = option_new(&portal_group->pg_options, $2, $3); 419291387Smav free($2); 420291387Smav free($3); 421291387Smav if (o == NULL) 422291387Smav return (1); 423291387Smav } 424291387Smav ; 425291387Smav 426275642Straszportal_group_redirect: REDIRECT STR 427275642Strasz { 428275642Strasz int error; 429275642Strasz 430275642Strasz error = portal_group_set_redirection(portal_group, $2); 431275642Strasz free($2); 432275642Strasz if (error != 0) 433275642Strasz return (1); 434275642Strasz } 435275642Strasz ; 436275642Strasz 437288729Smavportal_group_tag: TAG STR 438288729Smav { 439288729Smav uint64_t tmp; 440288729Smav 441288729Smav if (expand_number($2, &tmp) != 0) { 442288729Smav yyerror("invalid numeric value"); 443288729Smav free($2); 444288729Smav return (1); 445288729Smav } 446288729Smav 447288729Smav portal_group->pg_tag = tmp; 448288729Smav } 449288729Smav ; 450288729Smav 451279002Smavlun: LUN lun_name 452279002Smav OPENING_BRACKET lun_entries CLOSING_BRACKET 453279002Smav { 454279002Smav lun = NULL; 455279002Smav } 456279002Smav ; 457279002Smav 458279002Smavlun_name: STR 459279002Smav { 460279002Smav lun = lun_new(conf, $1); 461279002Smav free($1); 462279002Smav if (lun == NULL) 463279002Smav return (1); 464279002Smav } 465279002Smav ; 466279002Smav 467263722Strasztarget: TARGET target_name 468255570Strasz OPENING_BRACKET target_entries CLOSING_BRACKET 469255570Strasz { 470255570Strasz target = NULL; 471255570Strasz } 472255570Strasz ; 473255570Strasz 474263722Strasztarget_name: STR 475255570Strasz { 476255570Strasz target = target_new(conf, $1); 477255570Strasz free($1); 478255570Strasz if (target == NULL) 479255570Strasz return (1); 480255570Strasz } 481255570Strasz ; 482255570Strasz 483255570Strasztarget_entries: 484255570Strasz | 485255570Strasz target_entries target_entry 486275246Strasz | 487275246Strasz target_entries target_entry SEMICOLON 488255570Strasz ; 489255570Strasz 490255570Strasztarget_entry: 491263722Strasz target_alias 492255570Strasz | 493263722Strasz target_auth_group 494255570Strasz | 495263724Strasz target_auth_type 496263724Strasz | 497263722Strasz target_chap 498255570Strasz | 499263722Strasz target_chap_mutual 500255570Strasz | 501263722Strasz target_initiator_name 502263720Strasz | 503263722Strasz target_initiator_portal 504263720Strasz | 505263722Strasz target_portal_group 506255570Strasz | 507279055Smav target_port 508279055Smav | 509275642Strasz target_redirect 510275642Strasz | 511263722Strasz target_lun 512279002Smav | 513279002Smav target_lun_ref 514255570Strasz ; 515255570Strasz 516263722Strasztarget_alias: ALIAS STR 517255570Strasz { 518255570Strasz if (target->t_alias != NULL) { 519255570Strasz log_warnx("alias for target \"%s\" " 520263723Strasz "specified more than once", target->t_name); 521255570Strasz return (1); 522255570Strasz } 523255570Strasz target->t_alias = $2; 524255570Strasz } 525255570Strasz ; 526255570Strasz 527263722Strasztarget_auth_group: AUTH_GROUP STR 528255570Strasz { 529255570Strasz if (target->t_auth_group != NULL) { 530255570Strasz if (target->t_auth_group->ag_name != NULL) 531255570Strasz log_warnx("auth-group for target \"%s\" " 532263723Strasz "specified more than once", target->t_name); 533255570Strasz else 534263724Strasz log_warnx("cannot use both auth-group and explicit " 535255570Strasz "authorisations for target \"%s\"", 536263723Strasz target->t_name); 537255570Strasz return (1); 538255570Strasz } 539255570Strasz target->t_auth_group = auth_group_find(conf, $2); 540255570Strasz if (target->t_auth_group == NULL) { 541255570Strasz log_warnx("unknown auth-group \"%s\" for target " 542263723Strasz "\"%s\"", $2, target->t_name); 543255570Strasz return (1); 544255570Strasz } 545255570Strasz free($2); 546255570Strasz } 547255570Strasz ; 548255570Strasz 549263724Strasztarget_auth_type: AUTH_TYPE STR 550263724Strasz { 551263724Strasz int error; 552263724Strasz 553263724Strasz if (target->t_auth_group != NULL) { 554263724Strasz if (target->t_auth_group->ag_name != NULL) { 555263724Strasz log_warnx("cannot use both auth-group and " 556263724Strasz "auth-type for target \"%s\"", 557263724Strasz target->t_name); 558263724Strasz return (1); 559263724Strasz } 560263724Strasz } else { 561263724Strasz target->t_auth_group = auth_group_new(conf, NULL); 562263724Strasz if (target->t_auth_group == NULL) { 563263724Strasz free($2); 564263724Strasz return (1); 565263724Strasz } 566263724Strasz target->t_auth_group->ag_target = target; 567263724Strasz } 568275245Strasz error = auth_group_set_type(target->t_auth_group, $2); 569263724Strasz free($2); 570263724Strasz if (error != 0) 571263724Strasz return (1); 572263724Strasz } 573263724Strasz ; 574263724Strasz 575263722Strasztarget_chap: CHAP STR STR 576255570Strasz { 577255570Strasz const struct auth *ca; 578255570Strasz 579255570Strasz if (target->t_auth_group != NULL) { 580255570Strasz if (target->t_auth_group->ag_name != NULL) { 581263724Strasz log_warnx("cannot use both auth-group and " 582263724Strasz "chap for target \"%s\"", 583263723Strasz target->t_name); 584255570Strasz free($2); 585255570Strasz free($3); 586255570Strasz return (1); 587255570Strasz } 588255570Strasz } else { 589255570Strasz target->t_auth_group = auth_group_new(conf, NULL); 590255570Strasz if (target->t_auth_group == NULL) { 591255570Strasz free($2); 592255570Strasz free($3); 593255570Strasz return (1); 594255570Strasz } 595255570Strasz target->t_auth_group->ag_target = target; 596255570Strasz } 597255570Strasz ca = auth_new_chap(target->t_auth_group, $2, $3); 598255570Strasz free($2); 599255570Strasz free($3); 600255570Strasz if (ca == NULL) 601255570Strasz return (1); 602255570Strasz } 603255570Strasz ; 604255570Strasz 605263722Strasztarget_chap_mutual: CHAP_MUTUAL STR STR STR STR 606255570Strasz { 607255570Strasz const struct auth *ca; 608255570Strasz 609255570Strasz if (target->t_auth_group != NULL) { 610255570Strasz if (target->t_auth_group->ag_name != NULL) { 611263724Strasz log_warnx("cannot use both auth-group and " 612263724Strasz "chap-mutual for target \"%s\"", 613263723Strasz target->t_name); 614255570Strasz free($2); 615255570Strasz free($3); 616255570Strasz free($4); 617255570Strasz free($5); 618255570Strasz return (1); 619255570Strasz } 620255570Strasz } else { 621255570Strasz target->t_auth_group = auth_group_new(conf, NULL); 622255570Strasz if (target->t_auth_group == NULL) { 623255570Strasz free($2); 624255570Strasz free($3); 625255570Strasz free($4); 626255570Strasz free($5); 627255570Strasz return (1); 628255570Strasz } 629255570Strasz target->t_auth_group->ag_target = target; 630255570Strasz } 631255570Strasz ca = auth_new_chap_mutual(target->t_auth_group, 632255570Strasz $2, $3, $4, $5); 633255570Strasz free($2); 634255570Strasz free($3); 635255570Strasz free($4); 636255570Strasz free($5); 637255570Strasz if (ca == NULL) 638255570Strasz return (1); 639255570Strasz } 640255570Strasz ; 641255570Strasz 642263722Strasztarget_initiator_name: INITIATOR_NAME STR 643263720Strasz { 644263720Strasz const struct auth_name *an; 645263720Strasz 646263720Strasz if (target->t_auth_group != NULL) { 647263720Strasz if (target->t_auth_group->ag_name != NULL) { 648263724Strasz log_warnx("cannot use both auth-group and " 649263720Strasz "initiator-name for target \"%s\"", 650263723Strasz target->t_name); 651263720Strasz free($2); 652263720Strasz return (1); 653263720Strasz } 654263720Strasz } else { 655263720Strasz target->t_auth_group = auth_group_new(conf, NULL); 656263720Strasz if (target->t_auth_group == NULL) { 657263720Strasz free($2); 658263720Strasz return (1); 659263720Strasz } 660263720Strasz target->t_auth_group->ag_target = target; 661263720Strasz } 662263720Strasz an = auth_name_new(target->t_auth_group, $2); 663263720Strasz free($2); 664263720Strasz if (an == NULL) 665263720Strasz return (1); 666263720Strasz } 667263720Strasz ; 668263720Strasz 669263722Strasztarget_initiator_portal: INITIATOR_PORTAL STR 670263720Strasz { 671263720Strasz const struct auth_portal *ap; 672263720Strasz 673263720Strasz if (target->t_auth_group != NULL) { 674263720Strasz if (target->t_auth_group->ag_name != NULL) { 675263724Strasz log_warnx("cannot use both auth-group and " 676263720Strasz "initiator-portal for target \"%s\"", 677263723Strasz target->t_name); 678263720Strasz free($2); 679263720Strasz return (1); 680263720Strasz } 681263720Strasz } else { 682263720Strasz target->t_auth_group = auth_group_new(conf, NULL); 683263720Strasz if (target->t_auth_group == NULL) { 684263720Strasz free($2); 685263720Strasz return (1); 686263720Strasz } 687263720Strasz target->t_auth_group->ag_target = target; 688263720Strasz } 689263720Strasz ap = auth_portal_new(target->t_auth_group, $2); 690263720Strasz free($2); 691263720Strasz if (ap == NULL) 692263720Strasz return (1); 693263720Strasz } 694263720Strasz ; 695263720Strasz 696279006Smavtarget_portal_group: PORTAL_GROUP STR STR 697255570Strasz { 698279006Smav struct portal_group *tpg; 699279006Smav struct auth_group *tag; 700279006Smav struct port *tp; 701279006Smav 702279006Smav tpg = portal_group_find(conf, $2); 703279006Smav if (tpg == NULL) { 704279006Smav log_warnx("unknown portal-group \"%s\" for target " 705279006Smav "\"%s\"", $2, target->t_name); 706255570Strasz free($2); 707279006Smav free($3); 708255570Strasz return (1); 709255570Strasz } 710279006Smav tag = auth_group_find(conf, $3); 711279006Smav if (tag == NULL) { 712279006Smav log_warnx("unknown auth-group \"%s\" for target " 713279006Smav "\"%s\"", $3, target->t_name); 714279006Smav free($2); 715279006Smav free($3); 716279006Smav return (1); 717279006Smav } 718279006Smav tp = port_new(conf, target, tpg); 719279006Smav if (tp == NULL) { 720279006Smav log_warnx("can't link portal-group \"%s\" to target " 721279006Smav "\"%s\"", $2, target->t_name); 722279006Smav free($2); 723279006Smav return (1); 724279006Smav } 725279006Smav tp->p_auth_group = tag; 726279006Smav free($2); 727279006Smav free($3); 728279006Smav } 729279006Smav | PORTAL_GROUP STR 730279006Smav { 731279006Smav struct portal_group *tpg; 732279006Smav struct port *tp; 733279006Smav 734279006Smav tpg = portal_group_find(conf, $2); 735279006Smav if (tpg == NULL) { 736255570Strasz log_warnx("unknown portal-group \"%s\" for target " 737263723Strasz "\"%s\"", $2, target->t_name); 738255570Strasz free($2); 739255570Strasz return (1); 740255570Strasz } 741279006Smav tp = port_new(conf, target, tpg); 742279006Smav if (tp == NULL) { 743279006Smav log_warnx("can't link portal-group \"%s\" to target " 744279006Smav "\"%s\"", $2, target->t_name); 745279006Smav free($2); 746279006Smav return (1); 747279006Smav } 748255570Strasz free($2); 749255570Strasz } 750255570Strasz ; 751255570Strasz 752279055Smavtarget_port: PORT STR 753279055Smav { 754279055Smav struct pport *pp; 755279055Smav struct port *tp; 756279055Smav 757279055Smav pp = pport_find(conf, $2); 758279055Smav if (pp == NULL) { 759279055Smav log_warnx("unknown port \"%s\" for target \"%s\"", 760279055Smav $2, target->t_name); 761279055Smav free($2); 762279055Smav return (1); 763279055Smav } 764279055Smav if (!TAILQ_EMPTY(&pp->pp_ports)) { 765279055Smav log_warnx("can't link port \"%s\" to target \"%s\", " 766279055Smav "port already linked to some target", 767279055Smav $2, target->t_name); 768279055Smav free($2); 769279055Smav return (1); 770279055Smav } 771279055Smav tp = port_new_pp(conf, target, pp); 772279055Smav if (tp == NULL) { 773279055Smav log_warnx("can't link port \"%s\" to target \"%s\"", 774279055Smav $2, target->t_name); 775279055Smav free($2); 776279055Smav return (1); 777279055Smav } 778279055Smav free($2); 779279055Smav } 780279055Smav ; 781279055Smav 782275642Strasztarget_redirect: REDIRECT STR 783275642Strasz { 784275642Strasz int error; 785275642Strasz 786275642Strasz error = target_set_redirection(target, $2); 787275642Strasz free($2); 788275642Strasz if (error != 0) 789275642Strasz return (1); 790275642Strasz } 791275642Strasz ; 792275642Strasz 793263722Strasztarget_lun: LUN lun_number 794263722Strasz OPENING_BRACKET lun_entries CLOSING_BRACKET 795255570Strasz { 796255570Strasz lun = NULL; 797255570Strasz } 798255570Strasz ; 799255570Strasz 800275186Straszlun_number: STR 801255570Strasz { 802275186Strasz uint64_t tmp; 803288699Smav int ret; 804279002Smav char *name; 805275186Strasz 806275186Strasz if (expand_number($1, &tmp) != 0) { 807275187Strasz yyerror("invalid numeric value"); 808275186Strasz free($1); 809275186Strasz return (1); 810275186Strasz } 811311866Smav if (tmp >= MAX_LUNS) { 812311866Smav yyerror("LU number is too big"); 813311866Smav free($1); 814311866Smav return (1); 815311866Smav } 816275186Strasz 817288699Smav ret = asprintf(&name, "%s,lun,%ju", target->t_name, tmp); 818288699Smav if (ret <= 0) 819288699Smav log_err(1, "asprintf"); 820279002Smav lun = lun_new(conf, name); 821255570Strasz if (lun == NULL) 822255570Strasz return (1); 823279002Smav 824279002Smav lun_set_scsiname(lun, name); 825279002Smav target->t_luns[tmp] = lun; 826255570Strasz } 827255570Strasz ; 828255570Strasz 829279002Smavtarget_lun_ref: LUN STR STR 830279002Smav { 831279002Smav uint64_t tmp; 832279002Smav 833279002Smav if (expand_number($2, &tmp) != 0) { 834279002Smav yyerror("invalid numeric value"); 835279002Smav free($2); 836279002Smav free($3); 837279002Smav return (1); 838279002Smav } 839279002Smav free($2); 840311866Smav if (tmp >= MAX_LUNS) { 841311866Smav yyerror("LU number is too big"); 842311866Smav free($3); 843311866Smav return (1); 844311866Smav } 845279002Smav 846279002Smav lun = lun_find(conf, $3); 847279002Smav free($3); 848279002Smav if (lun == NULL) 849279002Smav return (1); 850279002Smav 851279002Smav target->t_luns[tmp] = lun; 852279002Smav } 853279002Smav ; 854279002Smav 855263722Straszlun_entries: 856255570Strasz | 857263722Strasz lun_entries lun_entry 858275246Strasz | 859275246Strasz lun_entries lun_entry SEMICOLON 860255570Strasz ; 861255570Strasz 862263722Straszlun_entry: 863263722Strasz lun_backend 864255570Strasz | 865263722Strasz lun_blocksize 866255570Strasz | 867263722Strasz lun_device_id 868255570Strasz | 869288810Smav lun_device_type 870288810Smav | 871288760Smav lun_ctl_lun 872288760Smav | 873263722Strasz lun_option 874255570Strasz | 875263722Strasz lun_path 876255570Strasz | 877263722Strasz lun_serial 878255570Strasz | 879263722Strasz lun_size 880255570Strasz ; 881255570Strasz 882263722Straszlun_backend: BACKEND STR 883255570Strasz { 884255570Strasz if (lun->l_backend != NULL) { 885279002Smav log_warnx("backend for lun \"%s\" " 886255570Strasz "specified more than once", 887279002Smav lun->l_name); 888255570Strasz free($2); 889255570Strasz return (1); 890255570Strasz } 891255570Strasz lun_set_backend(lun, $2); 892255570Strasz free($2); 893255570Strasz } 894255570Strasz ; 895255570Strasz 896275186Straszlun_blocksize: BLOCKSIZE STR 897255570Strasz { 898275186Strasz uint64_t tmp; 899275186Strasz 900275186Strasz if (expand_number($2, &tmp) != 0) { 901275187Strasz yyerror("invalid numeric value"); 902275186Strasz free($2); 903275186Strasz return (1); 904275186Strasz } 905275186Strasz 906255570Strasz if (lun->l_blocksize != 0) { 907279002Smav log_warnx("blocksize for lun \"%s\" " 908255570Strasz "specified more than once", 909279002Smav lun->l_name); 910255570Strasz return (1); 911255570Strasz } 912275186Strasz lun_set_blocksize(lun, tmp); 913255570Strasz } 914255570Strasz ; 915255570Strasz 916263722Straszlun_device_id: DEVICE_ID STR 917255570Strasz { 918255570Strasz if (lun->l_device_id != NULL) { 919279002Smav log_warnx("device_id for lun \"%s\" " 920255570Strasz "specified more than once", 921279002Smav lun->l_name); 922255570Strasz free($2); 923255570Strasz return (1); 924255570Strasz } 925255570Strasz lun_set_device_id(lun, $2); 926255570Strasz free($2); 927255570Strasz } 928255570Strasz ; 929255570Strasz 930288810Smavlun_device_type: DEVICE_TYPE STR 931288810Smav { 932288810Smav uint64_t tmp; 933288810Smav 934288810Smav if (strcasecmp($2, "disk") == 0 || 935288810Smav strcasecmp($2, "direct") == 0) 936288810Smav tmp = 0; 937288810Smav else if (strcasecmp($2, "processor") == 0) 938288810Smav tmp = 3; 939288810Smav else if (strcasecmp($2, "cd") == 0 || 940288810Smav strcasecmp($2, "cdrom") == 0 || 941288810Smav strcasecmp($2, "dvd") == 0 || 942288810Smav strcasecmp($2, "dvdrom") == 0) 943288810Smav tmp = 5; 944288810Smav else if (expand_number($2, &tmp) != 0 || 945288810Smav tmp > 15) { 946288810Smav yyerror("invalid numeric value"); 947288810Smav free($2); 948288810Smav return (1); 949288810Smav } 950288810Smav 951288810Smav lun_set_device_type(lun, tmp); 952288810Smav } 953288810Smav ; 954288810Smav 955288760Smavlun_ctl_lun: CTL_LUN STR 956288760Smav { 957288760Smav uint64_t tmp; 958288760Smav 959288760Smav if (expand_number($2, &tmp) != 0) { 960288760Smav yyerror("invalid numeric value"); 961288760Smav free($2); 962288760Smav return (1); 963288760Smav } 964288760Smav 965288760Smav if (lun->l_ctl_lun >= 0) { 966288760Smav log_warnx("ctl_lun for lun \"%s\" " 967288760Smav "specified more than once", 968288760Smav lun->l_name); 969288760Smav return (1); 970288760Smav } 971288760Smav lun_set_ctl_lun(lun, tmp); 972288760Smav } 973288760Smav ; 974288760Smav 975263722Straszlun_option: OPTION STR STR 976255570Strasz { 977291387Smav struct option *o; 978274870Strasz 979291387Smav o = option_new(&lun->l_options, $2, $3); 980255570Strasz free($2); 981255570Strasz free($3); 982291387Smav if (o == NULL) 983255570Strasz return (1); 984255570Strasz } 985255570Strasz ; 986255570Strasz 987263722Straszlun_path: PATH STR 988255570Strasz { 989255570Strasz if (lun->l_path != NULL) { 990279002Smav log_warnx("path for lun \"%s\" " 991255570Strasz "specified more than once", 992279002Smav lun->l_name); 993255570Strasz free($2); 994255570Strasz return (1); 995255570Strasz } 996255570Strasz lun_set_path(lun, $2); 997255570Strasz free($2); 998255570Strasz } 999255570Strasz ; 1000255570Strasz 1001263722Straszlun_serial: SERIAL STR 1002255570Strasz { 1003255570Strasz if (lun->l_serial != NULL) { 1004279002Smav log_warnx("serial for lun \"%s\" " 1005255570Strasz "specified more than once", 1006279002Smav lun->l_name); 1007255570Strasz free($2); 1008255570Strasz return (1); 1009255570Strasz } 1010255570Strasz lun_set_serial(lun, $2); 1011255570Strasz free($2); 1012275186Strasz } 1013275186Strasz ; 1014275186Strasz 1015275186Straszlun_size: SIZE STR 1016267962Sjpaetzel { 1017275186Strasz uint64_t tmp; 1018267962Sjpaetzel 1019275186Strasz if (expand_number($2, &tmp) != 0) { 1020275187Strasz yyerror("invalid numeric value"); 1021275186Strasz free($2); 1022267962Sjpaetzel return (1); 1023267962Sjpaetzel } 1024255570Strasz 1025255570Strasz if (lun->l_size != 0) { 1026279002Smav log_warnx("size for lun \"%s\" " 1027255570Strasz "specified more than once", 1028279002Smav lun->l_name); 1029255570Strasz return (1); 1030255570Strasz } 1031275186Strasz lun_set_size(lun, tmp); 1032255570Strasz } 1033255570Strasz ; 1034255570Strasz%% 1035255570Strasz 1036255570Straszvoid 1037255570Straszyyerror(const char *str) 1038255570Strasz{ 1039255570Strasz 1040255570Strasz log_warnx("error in configuration file at line %d near '%s': %s", 1041255570Strasz lineno, yytext, str); 1042255570Strasz} 1043255570Strasz 1044255570Straszstatic void 1045255570Straszcheck_perms(const char *path) 1046255570Strasz{ 1047255570Strasz struct stat sb; 1048255570Strasz int error; 1049255570Strasz 1050255570Strasz error = stat(path, &sb); 1051255570Strasz if (error != 0) { 1052255570Strasz log_warn("stat"); 1053255570Strasz return; 1054255570Strasz } 1055255570Strasz if (sb.st_mode & S_IWOTH) { 1056255570Strasz log_warnx("%s is world-writable", path); 1057255570Strasz } else if (sb.st_mode & S_IROTH) { 1058255570Strasz log_warnx("%s is world-readable", path); 1059255570Strasz } else if (sb.st_mode & S_IXOTH) { 1060255570Strasz /* 1061255570Strasz * Ok, this one doesn't matter, but still do it, 1062255570Strasz * just for consistency. 1063255570Strasz */ 1064255570Strasz log_warnx("%s is world-executable", path); 1065255570Strasz } 1066255570Strasz 1067255570Strasz /* 1068255570Strasz * XXX: Should we also check for owner != 0? 1069255570Strasz */ 1070255570Strasz} 1071255570Strasz 1072255570Straszstruct conf * 1073279055Smavconf_new_from_file(const char *path, struct conf *oldconf) 1074255570Strasz{ 1075255570Strasz struct auth_group *ag; 1076255570Strasz struct portal_group *pg; 1077279055Smav struct pport *pp; 1078255570Strasz int error; 1079255570Strasz 1080255570Strasz log_debugx("obtaining configuration from %s", path); 1081255570Strasz 1082255570Strasz conf = conf_new(); 1083255570Strasz 1084279055Smav TAILQ_FOREACH(pp, &oldconf->conf_pports, pp_next) 1085279055Smav pport_copy(pp, conf); 1086279055Smav 1087263726Strasz ag = auth_group_new(conf, "default"); 1088263726Strasz assert(ag != NULL); 1089263726Strasz 1090255570Strasz ag = auth_group_new(conf, "no-authentication"); 1091263725Strasz assert(ag != NULL); 1092255570Strasz ag->ag_type = AG_TYPE_NO_AUTHENTICATION; 1093255570Strasz 1094255570Strasz ag = auth_group_new(conf, "no-access"); 1095263725Strasz assert(ag != NULL); 1096263729Strasz ag->ag_type = AG_TYPE_DENY; 1097255570Strasz 1098255570Strasz pg = portal_group_new(conf, "default"); 1099263725Strasz assert(pg != NULL); 1100255570Strasz 1101255570Strasz yyin = fopen(path, "r"); 1102255570Strasz if (yyin == NULL) { 1103255570Strasz log_warn("unable to open configuration file %s", path); 1104255570Strasz conf_delete(conf); 1105255570Strasz return (NULL); 1106255570Strasz } 1107255570Strasz check_perms(path); 1108263715Strasz lineno = 1; 1109255570Strasz yyrestart(yyin); 1110255570Strasz error = yyparse(); 1111255570Strasz auth_group = NULL; 1112255570Strasz portal_group = NULL; 1113255570Strasz target = NULL; 1114255570Strasz lun = NULL; 1115255570Strasz fclose(yyin); 1116255570Strasz if (error != 0) { 1117255570Strasz conf_delete(conf); 1118255570Strasz return (NULL); 1119255570Strasz } 1120255570Strasz 1121263726Strasz if (conf->conf_default_ag_defined == false) { 1122263726Strasz log_debugx("auth-group \"default\" not defined; " 1123263726Strasz "going with defaults"); 1124263726Strasz ag = auth_group_find(conf, "default"); 1125263726Strasz assert(ag != NULL); 1126263729Strasz ag->ag_type = AG_TYPE_DENY; 1127263726Strasz } 1128263726Strasz 1129263725Strasz if (conf->conf_default_pg_defined == false) { 1130263725Strasz log_debugx("portal-group \"default\" not defined; " 1131263725Strasz "going with defaults"); 1132263725Strasz pg = portal_group_find(conf, "default"); 1133263725Strasz assert(pg != NULL); 1134263725Strasz portal_group_add_listen(pg, "0.0.0.0:3260", false); 1135263725Strasz portal_group_add_listen(pg, "[::]:3260", false); 1136263725Strasz } 1137263725Strasz 1138265511Strasz conf->conf_kernel_port_on = true; 1139265511Strasz 1140255570Strasz error = conf_verify(conf); 1141255570Strasz if (error != 0) { 1142255570Strasz conf_delete(conf); 1143255570Strasz return (NULL); 1144255570Strasz } 1145255570Strasz 1146255570Strasz return (conf); 1147255570Strasz} 1148