parse.y revision 279002
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 279002 2015-02-19 14:31:16Z 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 64275642Strasz%token PATH PIDFILE 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 | 468275642Strasz target_redirect 469275642Strasz | 470263722Strasz target_lun 471279002Smav | 472279002Smav target_lun_ref 473255570Strasz ; 474255570Strasz 475263722Strasztarget_alias: ALIAS STR 476255570Strasz { 477255570Strasz if (target->t_alias != NULL) { 478255570Strasz log_warnx("alias for target \"%s\" " 479263723Strasz "specified more than once", target->t_name); 480255570Strasz return (1); 481255570Strasz } 482255570Strasz target->t_alias = $2; 483255570Strasz } 484255570Strasz ; 485255570Strasz 486263722Strasztarget_auth_group: AUTH_GROUP STR 487255570Strasz { 488255570Strasz if (target->t_auth_group != NULL) { 489255570Strasz if (target->t_auth_group->ag_name != NULL) 490255570Strasz log_warnx("auth-group for target \"%s\" " 491263723Strasz "specified more than once", target->t_name); 492255570Strasz else 493263724Strasz log_warnx("cannot use both auth-group and explicit " 494255570Strasz "authorisations for target \"%s\"", 495263723Strasz target->t_name); 496255570Strasz return (1); 497255570Strasz } 498255570Strasz target->t_auth_group = auth_group_find(conf, $2); 499255570Strasz if (target->t_auth_group == NULL) { 500255570Strasz log_warnx("unknown auth-group \"%s\" for target " 501263723Strasz "\"%s\"", $2, target->t_name); 502255570Strasz return (1); 503255570Strasz } 504255570Strasz free($2); 505255570Strasz } 506255570Strasz ; 507255570Strasz 508263724Strasztarget_auth_type: AUTH_TYPE STR 509263724Strasz { 510263724Strasz int error; 511263724Strasz 512263724Strasz if (target->t_auth_group != NULL) { 513263724Strasz if (target->t_auth_group->ag_name != NULL) { 514263724Strasz log_warnx("cannot use both auth-group and " 515263724Strasz "auth-type for target \"%s\"", 516263724Strasz target->t_name); 517263724Strasz return (1); 518263724Strasz } 519263724Strasz } else { 520263724Strasz target->t_auth_group = auth_group_new(conf, NULL); 521263724Strasz if (target->t_auth_group == NULL) { 522263724Strasz free($2); 523263724Strasz return (1); 524263724Strasz } 525263724Strasz target->t_auth_group->ag_target = target; 526263724Strasz } 527275245Strasz error = auth_group_set_type(target->t_auth_group, $2); 528263724Strasz free($2); 529263724Strasz if (error != 0) 530263724Strasz return (1); 531263724Strasz } 532263724Strasz ; 533263724Strasz 534263722Strasztarget_chap: CHAP STR STR 535255570Strasz { 536255570Strasz const struct auth *ca; 537255570Strasz 538255570Strasz if (target->t_auth_group != NULL) { 539255570Strasz if (target->t_auth_group->ag_name != NULL) { 540263724Strasz log_warnx("cannot use both auth-group and " 541263724Strasz "chap for target \"%s\"", 542263723Strasz target->t_name); 543255570Strasz free($2); 544255570Strasz free($3); 545255570Strasz return (1); 546255570Strasz } 547255570Strasz } else { 548255570Strasz target->t_auth_group = auth_group_new(conf, NULL); 549255570Strasz if (target->t_auth_group == NULL) { 550255570Strasz free($2); 551255570Strasz free($3); 552255570Strasz return (1); 553255570Strasz } 554255570Strasz target->t_auth_group->ag_target = target; 555255570Strasz } 556255570Strasz ca = auth_new_chap(target->t_auth_group, $2, $3); 557255570Strasz free($2); 558255570Strasz free($3); 559255570Strasz if (ca == NULL) 560255570Strasz return (1); 561255570Strasz } 562255570Strasz ; 563255570Strasz 564263722Strasztarget_chap_mutual: CHAP_MUTUAL STR STR STR STR 565255570Strasz { 566255570Strasz const struct auth *ca; 567255570Strasz 568255570Strasz if (target->t_auth_group != NULL) { 569255570Strasz if (target->t_auth_group->ag_name != NULL) { 570263724Strasz log_warnx("cannot use both auth-group and " 571263724Strasz "chap-mutual for target \"%s\"", 572263723Strasz target->t_name); 573255570Strasz free($2); 574255570Strasz free($3); 575255570Strasz free($4); 576255570Strasz free($5); 577255570Strasz return (1); 578255570Strasz } 579255570Strasz } else { 580255570Strasz target->t_auth_group = auth_group_new(conf, NULL); 581255570Strasz if (target->t_auth_group == NULL) { 582255570Strasz free($2); 583255570Strasz free($3); 584255570Strasz free($4); 585255570Strasz free($5); 586255570Strasz return (1); 587255570Strasz } 588255570Strasz target->t_auth_group->ag_target = target; 589255570Strasz } 590255570Strasz ca = auth_new_chap_mutual(target->t_auth_group, 591255570Strasz $2, $3, $4, $5); 592255570Strasz free($2); 593255570Strasz free($3); 594255570Strasz free($4); 595255570Strasz free($5); 596255570Strasz if (ca == NULL) 597255570Strasz return (1); 598255570Strasz } 599255570Strasz ; 600255570Strasz 601263722Strasztarget_initiator_name: INITIATOR_NAME STR 602263720Strasz { 603263720Strasz const struct auth_name *an; 604263720Strasz 605263720Strasz if (target->t_auth_group != NULL) { 606263720Strasz if (target->t_auth_group->ag_name != NULL) { 607263724Strasz log_warnx("cannot use both auth-group and " 608263720Strasz "initiator-name for target \"%s\"", 609263723Strasz target->t_name); 610263720Strasz free($2); 611263720Strasz return (1); 612263720Strasz } 613263720Strasz } else { 614263720Strasz target->t_auth_group = auth_group_new(conf, NULL); 615263720Strasz if (target->t_auth_group == NULL) { 616263720Strasz free($2); 617263720Strasz return (1); 618263720Strasz } 619263720Strasz target->t_auth_group->ag_target = target; 620263720Strasz } 621263720Strasz an = auth_name_new(target->t_auth_group, $2); 622263720Strasz free($2); 623263720Strasz if (an == NULL) 624263720Strasz return (1); 625263720Strasz } 626263720Strasz ; 627263720Strasz 628263722Strasztarget_initiator_portal: INITIATOR_PORTAL STR 629263720Strasz { 630263720Strasz const struct auth_portal *ap; 631263720Strasz 632263720Strasz if (target->t_auth_group != NULL) { 633263720Strasz if (target->t_auth_group->ag_name != NULL) { 634263724Strasz log_warnx("cannot use both auth-group and " 635263720Strasz "initiator-portal for target \"%s\"", 636263723Strasz target->t_name); 637263720Strasz free($2); 638263720Strasz return (1); 639263720Strasz } 640263720Strasz } else { 641263720Strasz target->t_auth_group = auth_group_new(conf, NULL); 642263720Strasz if (target->t_auth_group == NULL) { 643263720Strasz free($2); 644263720Strasz return (1); 645263720Strasz } 646263720Strasz target->t_auth_group->ag_target = target; 647263720Strasz } 648263720Strasz ap = auth_portal_new(target->t_auth_group, $2); 649263720Strasz free($2); 650263720Strasz if (ap == NULL) 651263720Strasz return (1); 652263720Strasz } 653263720Strasz ; 654263720Strasz 655263722Strasztarget_portal_group: PORTAL_GROUP STR 656255570Strasz { 657255570Strasz if (target->t_portal_group != NULL) { 658255570Strasz log_warnx("portal-group for target \"%s\" " 659263723Strasz "specified more than once", target->t_name); 660255570Strasz free($2); 661255570Strasz return (1); 662255570Strasz } 663255570Strasz target->t_portal_group = portal_group_find(conf, $2); 664255570Strasz if (target->t_portal_group == NULL) { 665255570Strasz log_warnx("unknown portal-group \"%s\" for target " 666263723Strasz "\"%s\"", $2, target->t_name); 667255570Strasz free($2); 668255570Strasz return (1); 669255570Strasz } 670255570Strasz free($2); 671255570Strasz } 672255570Strasz ; 673255570Strasz 674275642Strasztarget_redirect: REDIRECT STR 675275642Strasz { 676275642Strasz int error; 677275642Strasz 678275642Strasz error = target_set_redirection(target, $2); 679275642Strasz free($2); 680275642Strasz if (error != 0) 681275642Strasz return (1); 682275642Strasz } 683275642Strasz ; 684275642Strasz 685263722Strasztarget_lun: LUN lun_number 686263722Strasz OPENING_BRACKET lun_entries CLOSING_BRACKET 687255570Strasz { 688255570Strasz lun = NULL; 689255570Strasz } 690255570Strasz ; 691255570Strasz 692275186Straszlun_number: STR 693255570Strasz { 694275186Strasz uint64_t tmp; 695279002Smav char *name; 696275186Strasz 697275186Strasz if (expand_number($1, &tmp) != 0) { 698275187Strasz yyerror("invalid numeric value"); 699275186Strasz free($1); 700275186Strasz return (1); 701275186Strasz } 702275186Strasz 703279002Smav asprintf(&name, "%s,lun,%ju", target->t_name, tmp); 704279002Smav lun = lun_new(conf, name); 705255570Strasz if (lun == NULL) 706255570Strasz return (1); 707279002Smav 708279002Smav lun_set_scsiname(lun, name); 709279002Smav target->t_luns[tmp] = lun; 710255570Strasz } 711255570Strasz ; 712255570Strasz 713279002Smavtarget_lun_ref: LUN STR STR 714279002Smav { 715279002Smav uint64_t tmp; 716279002Smav 717279002Smav if (expand_number($2, &tmp) != 0) { 718279002Smav yyerror("invalid numeric value"); 719279002Smav free($2); 720279002Smav free($3); 721279002Smav return (1); 722279002Smav } 723279002Smav free($2); 724279002Smav 725279002Smav lun = lun_find(conf, $3); 726279002Smav free($3); 727279002Smav if (lun == NULL) 728279002Smav return (1); 729279002Smav 730279002Smav target->t_luns[tmp] = lun; 731279002Smav } 732279002Smav ; 733279002Smav 734263722Straszlun_entries: 735255570Strasz | 736263722Strasz lun_entries lun_entry 737275246Strasz | 738275246Strasz lun_entries lun_entry SEMICOLON 739255570Strasz ; 740255570Strasz 741263722Straszlun_entry: 742263722Strasz lun_backend 743255570Strasz | 744263722Strasz lun_blocksize 745255570Strasz | 746263722Strasz lun_device_id 747255570Strasz | 748263722Strasz lun_option 749255570Strasz | 750263722Strasz lun_path 751255570Strasz | 752263722Strasz lun_serial 753255570Strasz | 754263722Strasz lun_size 755255570Strasz ; 756255570Strasz 757263722Straszlun_backend: BACKEND STR 758255570Strasz { 759255570Strasz if (lun->l_backend != NULL) { 760279002Smav log_warnx("backend for lun \"%s\" " 761255570Strasz "specified more than once", 762279002Smav lun->l_name); 763255570Strasz free($2); 764255570Strasz return (1); 765255570Strasz } 766255570Strasz lun_set_backend(lun, $2); 767255570Strasz free($2); 768255570Strasz } 769255570Strasz ; 770255570Strasz 771275186Straszlun_blocksize: BLOCKSIZE STR 772255570Strasz { 773275186Strasz uint64_t tmp; 774275186Strasz 775275186Strasz if (expand_number($2, &tmp) != 0) { 776275187Strasz yyerror("invalid numeric value"); 777275186Strasz free($2); 778275186Strasz return (1); 779275186Strasz } 780275186Strasz 781255570Strasz if (lun->l_blocksize != 0) { 782279002Smav log_warnx("blocksize for lun \"%s\" " 783255570Strasz "specified more than once", 784279002Smav lun->l_name); 785255570Strasz return (1); 786255570Strasz } 787275186Strasz lun_set_blocksize(lun, tmp); 788255570Strasz } 789255570Strasz ; 790255570Strasz 791263722Straszlun_device_id: DEVICE_ID STR 792255570Strasz { 793255570Strasz if (lun->l_device_id != NULL) { 794279002Smav log_warnx("device_id for lun \"%s\" " 795255570Strasz "specified more than once", 796279002Smav lun->l_name); 797255570Strasz free($2); 798255570Strasz return (1); 799255570Strasz } 800255570Strasz lun_set_device_id(lun, $2); 801255570Strasz free($2); 802255570Strasz } 803255570Strasz ; 804255570Strasz 805263722Straszlun_option: OPTION STR STR 806255570Strasz { 807255570Strasz struct lun_option *clo; 808274870Strasz 809255570Strasz clo = lun_option_new(lun, $2, $3); 810255570Strasz free($2); 811255570Strasz free($3); 812255570Strasz if (clo == NULL) 813255570Strasz return (1); 814255570Strasz } 815255570Strasz ; 816255570Strasz 817263722Straszlun_path: PATH STR 818255570Strasz { 819255570Strasz if (lun->l_path != NULL) { 820279002Smav log_warnx("path for lun \"%s\" " 821255570Strasz "specified more than once", 822279002Smav lun->l_name); 823255570Strasz free($2); 824255570Strasz return (1); 825255570Strasz } 826255570Strasz lun_set_path(lun, $2); 827255570Strasz free($2); 828255570Strasz } 829255570Strasz ; 830255570Strasz 831263722Straszlun_serial: SERIAL STR 832255570Strasz { 833255570Strasz if (lun->l_serial != NULL) { 834279002Smav log_warnx("serial for lun \"%s\" " 835255570Strasz "specified more than once", 836279002Smav lun->l_name); 837255570Strasz free($2); 838255570Strasz return (1); 839255570Strasz } 840255570Strasz lun_set_serial(lun, $2); 841255570Strasz free($2); 842275186Strasz } 843275186Strasz ; 844275186Strasz 845275186Straszlun_size: SIZE STR 846267962Sjpaetzel { 847275186Strasz uint64_t tmp; 848267962Sjpaetzel 849275186Strasz if (expand_number($2, &tmp) != 0) { 850275187Strasz yyerror("invalid numeric value"); 851275186Strasz free($2); 852267962Sjpaetzel return (1); 853267962Sjpaetzel } 854255570Strasz 855255570Strasz if (lun->l_size != 0) { 856279002Smav log_warnx("size for lun \"%s\" " 857255570Strasz "specified more than once", 858279002Smav lun->l_name); 859255570Strasz return (1); 860255570Strasz } 861275186Strasz lun_set_size(lun, tmp); 862255570Strasz } 863255570Strasz ; 864255570Strasz%% 865255570Strasz 866255570Straszvoid 867255570Straszyyerror(const char *str) 868255570Strasz{ 869255570Strasz 870255570Strasz log_warnx("error in configuration file at line %d near '%s': %s", 871255570Strasz lineno, yytext, str); 872255570Strasz} 873255570Strasz 874255570Straszstatic void 875255570Straszcheck_perms(const char *path) 876255570Strasz{ 877255570Strasz struct stat sb; 878255570Strasz int error; 879255570Strasz 880255570Strasz error = stat(path, &sb); 881255570Strasz if (error != 0) { 882255570Strasz log_warn("stat"); 883255570Strasz return; 884255570Strasz } 885255570Strasz if (sb.st_mode & S_IWOTH) { 886255570Strasz log_warnx("%s is world-writable", path); 887255570Strasz } else if (sb.st_mode & S_IROTH) { 888255570Strasz log_warnx("%s is world-readable", path); 889255570Strasz } else if (sb.st_mode & S_IXOTH) { 890255570Strasz /* 891255570Strasz * Ok, this one doesn't matter, but still do it, 892255570Strasz * just for consistency. 893255570Strasz */ 894255570Strasz log_warnx("%s is world-executable", path); 895255570Strasz } 896255570Strasz 897255570Strasz /* 898255570Strasz * XXX: Should we also check for owner != 0? 899255570Strasz */ 900255570Strasz} 901255570Strasz 902255570Straszstruct conf * 903255570Straszconf_new_from_file(const char *path) 904255570Strasz{ 905255570Strasz struct auth_group *ag; 906255570Strasz struct portal_group *pg; 907255570Strasz int error; 908255570Strasz 909255570Strasz log_debugx("obtaining configuration from %s", path); 910255570Strasz 911255570Strasz conf = conf_new(); 912255570Strasz 913263726Strasz ag = auth_group_new(conf, "default"); 914263726Strasz assert(ag != NULL); 915263726Strasz 916255570Strasz ag = auth_group_new(conf, "no-authentication"); 917263725Strasz assert(ag != NULL); 918255570Strasz ag->ag_type = AG_TYPE_NO_AUTHENTICATION; 919255570Strasz 920255570Strasz ag = auth_group_new(conf, "no-access"); 921263725Strasz assert(ag != NULL); 922263729Strasz ag->ag_type = AG_TYPE_DENY; 923255570Strasz 924255570Strasz pg = portal_group_new(conf, "default"); 925263725Strasz assert(pg != NULL); 926255570Strasz 927255570Strasz yyin = fopen(path, "r"); 928255570Strasz if (yyin == NULL) { 929255570Strasz log_warn("unable to open configuration file %s", path); 930255570Strasz conf_delete(conf); 931255570Strasz return (NULL); 932255570Strasz } 933255570Strasz check_perms(path); 934263715Strasz lineno = 1; 935255570Strasz yyrestart(yyin); 936255570Strasz error = yyparse(); 937255570Strasz auth_group = NULL; 938255570Strasz portal_group = NULL; 939255570Strasz target = NULL; 940255570Strasz lun = NULL; 941255570Strasz fclose(yyin); 942255570Strasz if (error != 0) { 943255570Strasz conf_delete(conf); 944255570Strasz return (NULL); 945255570Strasz } 946255570Strasz 947263726Strasz if (conf->conf_default_ag_defined == false) { 948263726Strasz log_debugx("auth-group \"default\" not defined; " 949263726Strasz "going with defaults"); 950263726Strasz ag = auth_group_find(conf, "default"); 951263726Strasz assert(ag != NULL); 952263729Strasz ag->ag_type = AG_TYPE_DENY; 953263726Strasz } 954263726Strasz 955263725Strasz if (conf->conf_default_pg_defined == false) { 956263725Strasz log_debugx("portal-group \"default\" not defined; " 957263725Strasz "going with defaults"); 958263725Strasz pg = portal_group_find(conf, "default"); 959263725Strasz assert(pg != NULL); 960263725Strasz portal_group_add_listen(pg, "0.0.0.0:3260", false); 961263725Strasz portal_group_add_listen(pg, "[::]:3260", false); 962263725Strasz } 963263725Strasz 964265511Strasz conf->conf_kernel_port_on = true; 965265511Strasz 966255570Strasz error = conf_verify(conf); 967255570Strasz if (error != 0) { 968255570Strasz conf_delete(conf); 969255570Strasz return (NULL); 970255570Strasz } 971255570Strasz 972255570Strasz return (conf); 973255570Strasz} 974