parse.y revision 279055
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 279055 2015-02-20 17:09:49Z 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 <stdint.h> 39255570Strasz#include <stdlib.h> 40255570Strasz#include <string.h> 41255570Strasz 42255570Strasz#include "ctld.h" 43255570Strasz 44255570Straszextern FILE *yyin; 45255570Straszextern char *yytext; 46255570Straszextern int lineno; 47255570Strasz 48255570Straszstatic struct conf *conf = NULL; 49255570Straszstatic struct auth_group *auth_group = NULL; 50255570Straszstatic struct portal_group *portal_group = NULL; 51255570Straszstatic struct target *target = NULL; 52255570Straszstatic struct lun *lun = NULL; 53255570Strasz 54255570Straszextern void yyerror(const char *); 55255570Straszextern int yylex(void); 56255570Straszextern void yyrestart(FILE *); 57255570Strasz 58255570Strasz%} 59255570Strasz 60263724Strasz%token ALIAS AUTH_GROUP AUTH_TYPE BACKEND BLOCKSIZE CHAP CHAP_MUTUAL 61275244Strasz%token CLOSING_BRACKET DEBUG DEVICE_ID DISCOVERY_AUTH_GROUP DISCOVERY_FILTER 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 65275642Strasz%token 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 | 341255570Strasz portal_group_listen 342255570Strasz | 343255570Strasz portal_group_listen_iser 344275642Strasz | 345275642Strasz portal_group_redirect 346255570Strasz ; 347255570Strasz 348255570Straszportal_group_discovery_auth_group: DISCOVERY_AUTH_GROUP STR 349255570Strasz { 350255570Strasz if (portal_group->pg_discovery_auth_group != NULL) { 351255570Strasz log_warnx("discovery-auth-group for portal-group " 352255570Strasz "\"%s\" specified more than once", 353255570Strasz portal_group->pg_name); 354255570Strasz return (1); 355255570Strasz } 356255570Strasz portal_group->pg_discovery_auth_group = 357255570Strasz auth_group_find(conf, $2); 358255570Strasz if (portal_group->pg_discovery_auth_group == NULL) { 359255570Strasz log_warnx("unknown discovery-auth-group \"%s\" " 360255570Strasz "for portal-group \"%s\"", 361255570Strasz $2, portal_group->pg_name); 362255570Strasz return (1); 363255570Strasz } 364255570Strasz free($2); 365255570Strasz } 366255570Strasz ; 367255570Strasz 368275244Straszportal_group_discovery_filter: DISCOVERY_FILTER STR 369275244Strasz { 370275244Strasz int error; 371275244Strasz 372275245Strasz error = portal_group_set_filter(portal_group, $2); 373275244Strasz free($2); 374275244Strasz if (error != 0) 375275244Strasz return (1); 376275244Strasz } 377275244Strasz ; 378275244Strasz 379255570Straszportal_group_listen: LISTEN STR 380255570Strasz { 381255570Strasz int error; 382255570Strasz 383255570Strasz error = portal_group_add_listen(portal_group, $2, false); 384255570Strasz free($2); 385255570Strasz if (error != 0) 386255570Strasz return (1); 387255570Strasz } 388255570Strasz ; 389255570Strasz 390255570Straszportal_group_listen_iser: LISTEN_ISER STR 391255570Strasz { 392255570Strasz int error; 393255570Strasz 394255570Strasz error = portal_group_add_listen(portal_group, $2, true); 395255570Strasz free($2); 396255570Strasz if (error != 0) 397255570Strasz return (1); 398255570Strasz } 399255570Strasz ; 400255570Strasz 401275642Straszportal_group_redirect: REDIRECT STR 402275642Strasz { 403275642Strasz int error; 404275642Strasz 405275642Strasz error = portal_group_set_redirection(portal_group, $2); 406275642Strasz free($2); 407275642Strasz if (error != 0) 408275642Strasz return (1); 409275642Strasz } 410275642Strasz ; 411275642Strasz 412279002Smavlun: LUN lun_name 413279002Smav OPENING_BRACKET lun_entries CLOSING_BRACKET 414279002Smav { 415279002Smav lun = NULL; 416279002Smav } 417279002Smav ; 418279002Smav 419279002Smavlun_name: STR 420279002Smav { 421279002Smav lun = lun_new(conf, $1); 422279002Smav free($1); 423279002Smav if (lun == NULL) 424279002Smav return (1); 425279002Smav } 426279002Smav ; 427279002Smav 428263722Strasztarget: TARGET target_name 429255570Strasz OPENING_BRACKET target_entries CLOSING_BRACKET 430255570Strasz { 431255570Strasz target = NULL; 432255570Strasz } 433255570Strasz ; 434255570Strasz 435263722Strasztarget_name: STR 436255570Strasz { 437255570Strasz target = target_new(conf, $1); 438255570Strasz free($1); 439255570Strasz if (target == NULL) 440255570Strasz return (1); 441255570Strasz } 442255570Strasz ; 443255570Strasz 444255570Strasztarget_entries: 445255570Strasz | 446255570Strasz target_entries target_entry 447275246Strasz | 448275246Strasz target_entries target_entry SEMICOLON 449255570Strasz ; 450255570Strasz 451255570Strasztarget_entry: 452263722Strasz target_alias 453255570Strasz | 454263722Strasz target_auth_group 455255570Strasz | 456263724Strasz target_auth_type 457263724Strasz | 458263722Strasz target_chap 459255570Strasz | 460263722Strasz target_chap_mutual 461255570Strasz | 462263722Strasz target_initiator_name 463263720Strasz | 464263722Strasz target_initiator_portal 465263720Strasz | 466263722Strasz target_portal_group 467255570Strasz | 468279055Smav target_port 469279055Smav | 470275642Strasz target_redirect 471275642Strasz | 472263722Strasz target_lun 473279002Smav | 474279002Smav target_lun_ref 475255570Strasz ; 476255570Strasz 477263722Strasztarget_alias: ALIAS STR 478255570Strasz { 479255570Strasz if (target->t_alias != NULL) { 480255570Strasz log_warnx("alias for target \"%s\" " 481263723Strasz "specified more than once", target->t_name); 482255570Strasz return (1); 483255570Strasz } 484255570Strasz target->t_alias = $2; 485255570Strasz } 486255570Strasz ; 487255570Strasz 488263722Strasztarget_auth_group: AUTH_GROUP STR 489255570Strasz { 490255570Strasz if (target->t_auth_group != NULL) { 491255570Strasz if (target->t_auth_group->ag_name != NULL) 492255570Strasz log_warnx("auth-group for target \"%s\" " 493263723Strasz "specified more than once", target->t_name); 494255570Strasz else 495263724Strasz log_warnx("cannot use both auth-group and explicit " 496255570Strasz "authorisations for target \"%s\"", 497263723Strasz target->t_name); 498255570Strasz return (1); 499255570Strasz } 500255570Strasz target->t_auth_group = auth_group_find(conf, $2); 501255570Strasz if (target->t_auth_group == NULL) { 502255570Strasz log_warnx("unknown auth-group \"%s\" for target " 503263723Strasz "\"%s\"", $2, target->t_name); 504255570Strasz return (1); 505255570Strasz } 506255570Strasz free($2); 507255570Strasz } 508255570Strasz ; 509255570Strasz 510263724Strasztarget_auth_type: AUTH_TYPE STR 511263724Strasz { 512263724Strasz int error; 513263724Strasz 514263724Strasz if (target->t_auth_group != NULL) { 515263724Strasz if (target->t_auth_group->ag_name != NULL) { 516263724Strasz log_warnx("cannot use both auth-group and " 517263724Strasz "auth-type for target \"%s\"", 518263724Strasz target->t_name); 519263724Strasz return (1); 520263724Strasz } 521263724Strasz } else { 522263724Strasz target->t_auth_group = auth_group_new(conf, NULL); 523263724Strasz if (target->t_auth_group == NULL) { 524263724Strasz free($2); 525263724Strasz return (1); 526263724Strasz } 527263724Strasz target->t_auth_group->ag_target = target; 528263724Strasz } 529275245Strasz error = auth_group_set_type(target->t_auth_group, $2); 530263724Strasz free($2); 531263724Strasz if (error != 0) 532263724Strasz return (1); 533263724Strasz } 534263724Strasz ; 535263724Strasz 536263722Strasztarget_chap: CHAP STR STR 537255570Strasz { 538255570Strasz const struct auth *ca; 539255570Strasz 540255570Strasz if (target->t_auth_group != NULL) { 541255570Strasz if (target->t_auth_group->ag_name != NULL) { 542263724Strasz log_warnx("cannot use both auth-group and " 543263724Strasz "chap for target \"%s\"", 544263723Strasz target->t_name); 545255570Strasz free($2); 546255570Strasz free($3); 547255570Strasz return (1); 548255570Strasz } 549255570Strasz } else { 550255570Strasz target->t_auth_group = auth_group_new(conf, NULL); 551255570Strasz if (target->t_auth_group == NULL) { 552255570Strasz free($2); 553255570Strasz free($3); 554255570Strasz return (1); 555255570Strasz } 556255570Strasz target->t_auth_group->ag_target = target; 557255570Strasz } 558255570Strasz ca = auth_new_chap(target->t_auth_group, $2, $3); 559255570Strasz free($2); 560255570Strasz free($3); 561255570Strasz if (ca == NULL) 562255570Strasz return (1); 563255570Strasz } 564255570Strasz ; 565255570Strasz 566263722Strasztarget_chap_mutual: CHAP_MUTUAL STR STR STR STR 567255570Strasz { 568255570Strasz const struct auth *ca; 569255570Strasz 570255570Strasz if (target->t_auth_group != NULL) { 571255570Strasz if (target->t_auth_group->ag_name != NULL) { 572263724Strasz log_warnx("cannot use both auth-group and " 573263724Strasz "chap-mutual for target \"%s\"", 574263723Strasz target->t_name); 575255570Strasz free($2); 576255570Strasz free($3); 577255570Strasz free($4); 578255570Strasz free($5); 579255570Strasz return (1); 580255570Strasz } 581255570Strasz } else { 582255570Strasz target->t_auth_group = auth_group_new(conf, NULL); 583255570Strasz if (target->t_auth_group == NULL) { 584255570Strasz free($2); 585255570Strasz free($3); 586255570Strasz free($4); 587255570Strasz free($5); 588255570Strasz return (1); 589255570Strasz } 590255570Strasz target->t_auth_group->ag_target = target; 591255570Strasz } 592255570Strasz ca = auth_new_chap_mutual(target->t_auth_group, 593255570Strasz $2, $3, $4, $5); 594255570Strasz free($2); 595255570Strasz free($3); 596255570Strasz free($4); 597255570Strasz free($5); 598255570Strasz if (ca == NULL) 599255570Strasz return (1); 600255570Strasz } 601255570Strasz ; 602255570Strasz 603263722Strasztarget_initiator_name: INITIATOR_NAME STR 604263720Strasz { 605263720Strasz const struct auth_name *an; 606263720Strasz 607263720Strasz if (target->t_auth_group != NULL) { 608263720Strasz if (target->t_auth_group->ag_name != NULL) { 609263724Strasz log_warnx("cannot use both auth-group and " 610263720Strasz "initiator-name for target \"%s\"", 611263723Strasz target->t_name); 612263720Strasz free($2); 613263720Strasz return (1); 614263720Strasz } 615263720Strasz } else { 616263720Strasz target->t_auth_group = auth_group_new(conf, NULL); 617263720Strasz if (target->t_auth_group == NULL) { 618263720Strasz free($2); 619263720Strasz return (1); 620263720Strasz } 621263720Strasz target->t_auth_group->ag_target = target; 622263720Strasz } 623263720Strasz an = auth_name_new(target->t_auth_group, $2); 624263720Strasz free($2); 625263720Strasz if (an == NULL) 626263720Strasz return (1); 627263720Strasz } 628263720Strasz ; 629263720Strasz 630263722Strasztarget_initiator_portal: INITIATOR_PORTAL STR 631263720Strasz { 632263720Strasz const struct auth_portal *ap; 633263720Strasz 634263720Strasz if (target->t_auth_group != NULL) { 635263720Strasz if (target->t_auth_group->ag_name != NULL) { 636263724Strasz log_warnx("cannot use both auth-group and " 637263720Strasz "initiator-portal for target \"%s\"", 638263723Strasz target->t_name); 639263720Strasz free($2); 640263720Strasz return (1); 641263720Strasz } 642263720Strasz } else { 643263720Strasz target->t_auth_group = auth_group_new(conf, NULL); 644263720Strasz if (target->t_auth_group == NULL) { 645263720Strasz free($2); 646263720Strasz return (1); 647263720Strasz } 648263720Strasz target->t_auth_group->ag_target = target; 649263720Strasz } 650263720Strasz ap = auth_portal_new(target->t_auth_group, $2); 651263720Strasz free($2); 652263720Strasz if (ap == NULL) 653263720Strasz return (1); 654263720Strasz } 655263720Strasz ; 656263720Strasz 657279006Smavtarget_portal_group: PORTAL_GROUP STR STR 658255570Strasz { 659279006Smav struct portal_group *tpg; 660279006Smav struct auth_group *tag; 661279006Smav struct port *tp; 662279006Smav 663279006Smav tpg = portal_group_find(conf, $2); 664279006Smav if (tpg == NULL) { 665279006Smav log_warnx("unknown portal-group \"%s\" for target " 666279006Smav "\"%s\"", $2, target->t_name); 667255570Strasz free($2); 668279006Smav free($3); 669255570Strasz return (1); 670255570Strasz } 671279006Smav tag = auth_group_find(conf, $3); 672279006Smav if (tag == NULL) { 673279006Smav log_warnx("unknown auth-group \"%s\" for target " 674279006Smav "\"%s\"", $3, target->t_name); 675279006Smav free($2); 676279006Smav free($3); 677279006Smav return (1); 678279006Smav } 679279006Smav tp = port_new(conf, target, tpg); 680279006Smav if (tp == NULL) { 681279006Smav log_warnx("can't link portal-group \"%s\" to target " 682279006Smav "\"%s\"", $2, target->t_name); 683279006Smav free($2); 684279006Smav return (1); 685279006Smav } 686279006Smav tp->p_auth_group = tag; 687279006Smav free($2); 688279006Smav free($3); 689279006Smav } 690279006Smav | PORTAL_GROUP STR 691279006Smav { 692279006Smav struct portal_group *tpg; 693279006Smav struct port *tp; 694279006Smav 695279006Smav tpg = portal_group_find(conf, $2); 696279006Smav if (tpg == NULL) { 697255570Strasz log_warnx("unknown portal-group \"%s\" for target " 698263723Strasz "\"%s\"", $2, target->t_name); 699255570Strasz free($2); 700255570Strasz return (1); 701255570Strasz } 702279006Smav tp = port_new(conf, target, tpg); 703279006Smav if (tp == NULL) { 704279006Smav log_warnx("can't link portal-group \"%s\" to target " 705279006Smav "\"%s\"", $2, target->t_name); 706279006Smav free($2); 707279006Smav return (1); 708279006Smav } 709255570Strasz free($2); 710255570Strasz } 711255570Strasz ; 712255570Strasz 713279055Smavtarget_port: PORT STR 714279055Smav { 715279055Smav struct pport *pp; 716279055Smav struct port *tp; 717279055Smav 718279055Smav pp = pport_find(conf, $2); 719279055Smav if (pp == NULL) { 720279055Smav log_warnx("unknown port \"%s\" for target \"%s\"", 721279055Smav $2, target->t_name); 722279055Smav free($2); 723279055Smav return (1); 724279055Smav } 725279055Smav if (!TAILQ_EMPTY(&pp->pp_ports)) { 726279055Smav log_warnx("can't link port \"%s\" to target \"%s\", " 727279055Smav "port already linked to some target", 728279055Smav $2, target->t_name); 729279055Smav free($2); 730279055Smav return (1); 731279055Smav } 732279055Smav tp = port_new_pp(conf, target, pp); 733279055Smav if (tp == NULL) { 734279055Smav log_warnx("can't link port \"%s\" to target \"%s\"", 735279055Smav $2, target->t_name); 736279055Smav free($2); 737279055Smav return (1); 738279055Smav } 739279055Smav free($2); 740279055Smav } 741279055Smav ; 742279055Smav 743275642Strasztarget_redirect: REDIRECT STR 744275642Strasz { 745275642Strasz int error; 746275642Strasz 747275642Strasz error = target_set_redirection(target, $2); 748275642Strasz free($2); 749275642Strasz if (error != 0) 750275642Strasz return (1); 751275642Strasz } 752275642Strasz ; 753275642Strasz 754263722Strasztarget_lun: LUN lun_number 755263722Strasz OPENING_BRACKET lun_entries CLOSING_BRACKET 756255570Strasz { 757255570Strasz lun = NULL; 758255570Strasz } 759255570Strasz ; 760255570Strasz 761275186Straszlun_number: STR 762255570Strasz { 763275186Strasz uint64_t tmp; 764279002Smav char *name; 765275186Strasz 766275186Strasz if (expand_number($1, &tmp) != 0) { 767275187Strasz yyerror("invalid numeric value"); 768275186Strasz free($1); 769275186Strasz return (1); 770275186Strasz } 771275186Strasz 772279002Smav asprintf(&name, "%s,lun,%ju", target->t_name, tmp); 773279002Smav lun = lun_new(conf, name); 774255570Strasz if (lun == NULL) 775255570Strasz return (1); 776279002Smav 777279002Smav lun_set_scsiname(lun, name); 778279002Smav target->t_luns[tmp] = lun; 779255570Strasz } 780255570Strasz ; 781255570Strasz 782279002Smavtarget_lun_ref: LUN STR STR 783279002Smav { 784279002Smav uint64_t tmp; 785279002Smav 786279002Smav if (expand_number($2, &tmp) != 0) { 787279002Smav yyerror("invalid numeric value"); 788279002Smav free($2); 789279002Smav free($3); 790279002Smav return (1); 791279002Smav } 792279002Smav free($2); 793279002Smav 794279002Smav lun = lun_find(conf, $3); 795279002Smav free($3); 796279002Smav if (lun == NULL) 797279002Smav return (1); 798279002Smav 799279002Smav target->t_luns[tmp] = lun; 800279002Smav } 801279002Smav ; 802279002Smav 803263722Straszlun_entries: 804255570Strasz | 805263722Strasz lun_entries lun_entry 806275246Strasz | 807275246Strasz lun_entries lun_entry SEMICOLON 808255570Strasz ; 809255570Strasz 810263722Straszlun_entry: 811263722Strasz lun_backend 812255570Strasz | 813263722Strasz lun_blocksize 814255570Strasz | 815263722Strasz lun_device_id 816255570Strasz | 817263722Strasz lun_option 818255570Strasz | 819263722Strasz lun_path 820255570Strasz | 821263722Strasz lun_serial 822255570Strasz | 823263722Strasz lun_size 824255570Strasz ; 825255570Strasz 826263722Straszlun_backend: BACKEND STR 827255570Strasz { 828255570Strasz if (lun->l_backend != NULL) { 829279002Smav log_warnx("backend for lun \"%s\" " 830255570Strasz "specified more than once", 831279002Smav lun->l_name); 832255570Strasz free($2); 833255570Strasz return (1); 834255570Strasz } 835255570Strasz lun_set_backend(lun, $2); 836255570Strasz free($2); 837255570Strasz } 838255570Strasz ; 839255570Strasz 840275186Straszlun_blocksize: BLOCKSIZE STR 841255570Strasz { 842275186Strasz uint64_t tmp; 843275186Strasz 844275186Strasz if (expand_number($2, &tmp) != 0) { 845275187Strasz yyerror("invalid numeric value"); 846275186Strasz free($2); 847275186Strasz return (1); 848275186Strasz } 849275186Strasz 850255570Strasz if (lun->l_blocksize != 0) { 851279002Smav log_warnx("blocksize for lun \"%s\" " 852255570Strasz "specified more than once", 853279002Smav lun->l_name); 854255570Strasz return (1); 855255570Strasz } 856275186Strasz lun_set_blocksize(lun, tmp); 857255570Strasz } 858255570Strasz ; 859255570Strasz 860263722Straszlun_device_id: DEVICE_ID STR 861255570Strasz { 862255570Strasz if (lun->l_device_id != NULL) { 863279002Smav log_warnx("device_id for lun \"%s\" " 864255570Strasz "specified more than once", 865279002Smav lun->l_name); 866255570Strasz free($2); 867255570Strasz return (1); 868255570Strasz } 869255570Strasz lun_set_device_id(lun, $2); 870255570Strasz free($2); 871255570Strasz } 872255570Strasz ; 873255570Strasz 874263722Straszlun_option: OPTION STR STR 875255570Strasz { 876255570Strasz struct lun_option *clo; 877274870Strasz 878255570Strasz clo = lun_option_new(lun, $2, $3); 879255570Strasz free($2); 880255570Strasz free($3); 881255570Strasz if (clo == NULL) 882255570Strasz return (1); 883255570Strasz } 884255570Strasz ; 885255570Strasz 886263722Straszlun_path: PATH STR 887255570Strasz { 888255570Strasz if (lun->l_path != NULL) { 889279002Smav log_warnx("path for lun \"%s\" " 890255570Strasz "specified more than once", 891279002Smav lun->l_name); 892255570Strasz free($2); 893255570Strasz return (1); 894255570Strasz } 895255570Strasz lun_set_path(lun, $2); 896255570Strasz free($2); 897255570Strasz } 898255570Strasz ; 899255570Strasz 900263722Straszlun_serial: SERIAL STR 901255570Strasz { 902255570Strasz if (lun->l_serial != NULL) { 903279002Smav log_warnx("serial for lun \"%s\" " 904255570Strasz "specified more than once", 905279002Smav lun->l_name); 906255570Strasz free($2); 907255570Strasz return (1); 908255570Strasz } 909255570Strasz lun_set_serial(lun, $2); 910255570Strasz free($2); 911275186Strasz } 912275186Strasz ; 913275186Strasz 914275186Straszlun_size: SIZE STR 915267962Sjpaetzel { 916275186Strasz uint64_t tmp; 917267962Sjpaetzel 918275186Strasz if (expand_number($2, &tmp) != 0) { 919275187Strasz yyerror("invalid numeric value"); 920275186Strasz free($2); 921267962Sjpaetzel return (1); 922267962Sjpaetzel } 923255570Strasz 924255570Strasz if (lun->l_size != 0) { 925279002Smav log_warnx("size for lun \"%s\" " 926255570Strasz "specified more than once", 927279002Smav lun->l_name); 928255570Strasz return (1); 929255570Strasz } 930275186Strasz lun_set_size(lun, tmp); 931255570Strasz } 932255570Strasz ; 933255570Strasz%% 934255570Strasz 935255570Straszvoid 936255570Straszyyerror(const char *str) 937255570Strasz{ 938255570Strasz 939255570Strasz log_warnx("error in configuration file at line %d near '%s': %s", 940255570Strasz lineno, yytext, str); 941255570Strasz} 942255570Strasz 943255570Straszstatic void 944255570Straszcheck_perms(const char *path) 945255570Strasz{ 946255570Strasz struct stat sb; 947255570Strasz int error; 948255570Strasz 949255570Strasz error = stat(path, &sb); 950255570Strasz if (error != 0) { 951255570Strasz log_warn("stat"); 952255570Strasz return; 953255570Strasz } 954255570Strasz if (sb.st_mode & S_IWOTH) { 955255570Strasz log_warnx("%s is world-writable", path); 956255570Strasz } else if (sb.st_mode & S_IROTH) { 957255570Strasz log_warnx("%s is world-readable", path); 958255570Strasz } else if (sb.st_mode & S_IXOTH) { 959255570Strasz /* 960255570Strasz * Ok, this one doesn't matter, but still do it, 961255570Strasz * just for consistency. 962255570Strasz */ 963255570Strasz log_warnx("%s is world-executable", path); 964255570Strasz } 965255570Strasz 966255570Strasz /* 967255570Strasz * XXX: Should we also check for owner != 0? 968255570Strasz */ 969255570Strasz} 970255570Strasz 971255570Straszstruct conf * 972279055Smavconf_new_from_file(const char *path, struct conf *oldconf) 973255570Strasz{ 974255570Strasz struct auth_group *ag; 975255570Strasz struct portal_group *pg; 976279055Smav struct pport *pp; 977255570Strasz int error; 978255570Strasz 979255570Strasz log_debugx("obtaining configuration from %s", path); 980255570Strasz 981255570Strasz conf = conf_new(); 982255570Strasz 983279055Smav TAILQ_FOREACH(pp, &oldconf->conf_pports, pp_next) 984279055Smav pport_copy(pp, conf); 985279055Smav 986263726Strasz ag = auth_group_new(conf, "default"); 987263726Strasz assert(ag != NULL); 988263726Strasz 989255570Strasz ag = auth_group_new(conf, "no-authentication"); 990263725Strasz assert(ag != NULL); 991255570Strasz ag->ag_type = AG_TYPE_NO_AUTHENTICATION; 992255570Strasz 993255570Strasz ag = auth_group_new(conf, "no-access"); 994263725Strasz assert(ag != NULL); 995263729Strasz ag->ag_type = AG_TYPE_DENY; 996255570Strasz 997255570Strasz pg = portal_group_new(conf, "default"); 998263725Strasz assert(pg != NULL); 999255570Strasz 1000255570Strasz yyin = fopen(path, "r"); 1001255570Strasz if (yyin == NULL) { 1002255570Strasz log_warn("unable to open configuration file %s", path); 1003255570Strasz conf_delete(conf); 1004255570Strasz return (NULL); 1005255570Strasz } 1006255570Strasz check_perms(path); 1007263715Strasz lineno = 1; 1008255570Strasz yyrestart(yyin); 1009255570Strasz error = yyparse(); 1010255570Strasz auth_group = NULL; 1011255570Strasz portal_group = NULL; 1012255570Strasz target = NULL; 1013255570Strasz lun = NULL; 1014255570Strasz fclose(yyin); 1015255570Strasz if (error != 0) { 1016255570Strasz conf_delete(conf); 1017255570Strasz return (NULL); 1018255570Strasz } 1019255570Strasz 1020263726Strasz if (conf->conf_default_ag_defined == false) { 1021263726Strasz log_debugx("auth-group \"default\" not defined; " 1022263726Strasz "going with defaults"); 1023263726Strasz ag = auth_group_find(conf, "default"); 1024263726Strasz assert(ag != NULL); 1025263729Strasz ag->ag_type = AG_TYPE_DENY; 1026263726Strasz } 1027263726Strasz 1028263725Strasz if (conf->conf_default_pg_defined == false) { 1029263725Strasz log_debugx("portal-group \"default\" not defined; " 1030263725Strasz "going with defaults"); 1031263725Strasz pg = portal_group_find(conf, "default"); 1032263725Strasz assert(pg != NULL); 1033263725Strasz portal_group_add_listen(pg, "0.0.0.0:3260", false); 1034263725Strasz portal_group_add_listen(pg, "[::]:3260", false); 1035263725Strasz } 1036263725Strasz 1037265511Strasz conf->conf_kernel_port_on = true; 1038265511Strasz 1039255570Strasz error = conf_verify(conf); 1040255570Strasz if (error != 0) { 1041255570Strasz conf_delete(conf); 1042255570Strasz return (NULL); 1043255570Strasz } 1044255570Strasz 1045255570Strasz return (conf); 1046255570Strasz} 1047