parse.y revision 301033
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: head/usr.bin/iscsictl/parse.y 301033 2016-05-31 11:32:07Z trasz $ 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 42281461Strasz#include <libxo/xo.h> 43281461Strasz 44255570Strasz#include "iscsictl.h" 45255570Strasz 46255570Straszextern FILE *yyin; 47255570Straszextern char *yytext; 48255570Straszextern int lineno; 49255570Strasz 50255570Straszstatic struct conf *conf; 51255570Straszstatic struct target *target; 52255570Strasz 53255570Straszextern void yyerror(const char *); 54255570Straszextern int yylex(void); 55255570Straszextern void yyrestart(FILE *); 56255570Strasz 57255570Strasz%} 58255570Strasz 59301033Strasz%token AUTH_METHOD ENABLE HEADER_DIGEST DATA_DIGEST TARGET_NAME TARGET_ADDRESS 60255570Strasz%token INITIATOR_NAME INITIATOR_ADDRESS INITIATOR_ALIAS USER SECRET 61278232Strasz%token MUTUAL_USER MUTUAL_SECRET SEMICOLON SESSION_TYPE PROTOCOL OFFLOAD 62278232Strasz%token IGNORED EQUALS OPENING_BRACKET CLOSING_BRACKET 63255570Strasz 64255570Strasz%union 65255570Strasz{ 66255570Strasz char *str; 67255570Strasz} 68255570Strasz 69255570Strasz%token <str> STR 70255570Strasz 71255570Strasz%% 72255570Strasz 73261711Strasztargets: 74255570Strasz | 75261711Strasz targets target 76255570Strasz ; 77255570Strasz 78261711Strasztarget: STR OPENING_BRACKET target_entries CLOSING_BRACKET 79255570Strasz { 80255570Strasz if (target_find(conf, $1) != NULL) 81281461Strasz xo_errx(1, "duplicated target %s", $1); 82255570Strasz target->t_nickname = $1; 83255570Strasz target = target_new(conf); 84255570Strasz } 85255570Strasz ; 86255570Strasz 87255570Strasztarget_entries: 88255570Strasz | 89255570Strasz target_entries target_entry 90261714Strasz | 91261714Strasz target_entries target_entry SEMICOLON 92255570Strasz ; 93255570Strasz 94255570Strasztarget_entry: 95261711Strasz target_name 96255570Strasz | 97261711Strasz target_address 98255570Strasz | 99261711Strasz initiator_name 100255570Strasz | 101261711Strasz initiator_address 102255570Strasz | 103261711Strasz initiator_alias 104255570Strasz | 105261711Strasz user 106255570Strasz | 107261711Strasz secret 108255570Strasz | 109261711Strasz mutual_user 110255570Strasz | 111261711Strasz mutual_secret 112255570Strasz | 113261711Strasz auth_method 114255570Strasz | 115261711Strasz header_digest 116255570Strasz | 117261711Strasz data_digest 118255570Strasz | 119261711Strasz session_type 120255570Strasz | 121301033Strasz enable 122301033Strasz | 123278232Strasz offload 124278232Strasz | 125261711Strasz protocol 126255570Strasz | 127261711Strasz ignored 128255570Strasz ; 129255570Strasz 130261711Strasztarget_name: TARGET_NAME EQUALS STR 131255570Strasz { 132255570Strasz if (target->t_name != NULL) 133281461Strasz xo_errx(1, "duplicated TargetName at line %d", lineno); 134255570Strasz target->t_name = $3; 135255570Strasz } 136255570Strasz ; 137255570Strasz 138261711Strasztarget_address: TARGET_ADDRESS EQUALS STR 139255570Strasz { 140255570Strasz if (target->t_address != NULL) 141281461Strasz xo_errx(1, "duplicated TargetAddress at line %d", lineno); 142255570Strasz target->t_address = $3; 143255570Strasz } 144255570Strasz ; 145255570Strasz 146261711Straszinitiator_name: INITIATOR_NAME EQUALS STR 147255570Strasz { 148255570Strasz if (target->t_initiator_name != NULL) 149281461Strasz xo_errx(1, "duplicated InitiatorName at line %d", lineno); 150255570Strasz target->t_initiator_name = $3; 151255570Strasz } 152255570Strasz ; 153255570Strasz 154261711Straszinitiator_address: INITIATOR_ADDRESS EQUALS STR 155255570Strasz { 156255570Strasz if (target->t_initiator_address != NULL) 157281461Strasz xo_errx(1, "duplicated InitiatorAddress at line %d", lineno); 158255570Strasz target->t_initiator_address = $3; 159255570Strasz } 160255570Strasz ; 161255570Strasz 162261711Straszinitiator_alias: INITIATOR_ALIAS EQUALS STR 163255570Strasz { 164255570Strasz if (target->t_initiator_alias != NULL) 165281461Strasz xo_errx(1, "duplicated InitiatorAlias at line %d", lineno); 166255570Strasz target->t_initiator_alias = $3; 167255570Strasz } 168255570Strasz ; 169255570Strasz 170261711Straszuser: USER EQUALS STR 171255570Strasz { 172255570Strasz if (target->t_user != NULL) 173281461Strasz xo_errx(1, "duplicated chapIName at line %d", lineno); 174255570Strasz target->t_user = $3; 175255570Strasz } 176255570Strasz ; 177255570Strasz 178261711Straszsecret: SECRET EQUALS STR 179255570Strasz { 180255570Strasz if (target->t_secret != NULL) 181281461Strasz xo_errx(1, "duplicated chapSecret at line %d", lineno); 182255570Strasz target->t_secret = $3; 183255570Strasz } 184255570Strasz ; 185255570Strasz 186261711Straszmutual_user: MUTUAL_USER EQUALS STR 187255570Strasz { 188255570Strasz if (target->t_mutual_user != NULL) 189281461Strasz xo_errx(1, "duplicated tgtChapName at line %d", lineno); 190255570Strasz target->t_mutual_user = $3; 191255570Strasz } 192255570Strasz ; 193255570Strasz 194261711Straszmutual_secret: MUTUAL_SECRET EQUALS STR 195255570Strasz { 196255570Strasz if (target->t_mutual_secret != NULL) 197281461Strasz xo_errx(1, "duplicated tgtChapSecret at line %d", lineno); 198255570Strasz target->t_mutual_secret = $3; 199255570Strasz } 200255570Strasz ; 201255570Strasz 202261711Straszauth_method: AUTH_METHOD EQUALS STR 203255570Strasz { 204255570Strasz if (target->t_auth_method != AUTH_METHOD_UNSPECIFIED) 205281461Strasz xo_errx(1, "duplicated AuthMethod at line %d", lineno); 206255570Strasz if (strcasecmp($3, "none") == 0) 207255570Strasz target->t_auth_method = AUTH_METHOD_NONE; 208255570Strasz else if (strcasecmp($3, "chap") == 0) 209255570Strasz target->t_auth_method = AUTH_METHOD_CHAP; 210255570Strasz else 211281461Strasz xo_errx(1, "invalid AuthMethod at line %d; " 212261713Strasz "must be either \"none\" or \"CHAP\"", lineno); 213255570Strasz } 214255570Strasz ; 215255570Strasz 216261711Straszheader_digest: HEADER_DIGEST EQUALS STR 217255570Strasz { 218255570Strasz if (target->t_header_digest != DIGEST_UNSPECIFIED) 219281461Strasz xo_errx(1, "duplicated HeaderDigest at line %d", lineno); 220255570Strasz if (strcasecmp($3, "none") == 0) 221255570Strasz target->t_header_digest = DIGEST_NONE; 222255570Strasz else if (strcasecmp($3, "CRC32C") == 0) 223255570Strasz target->t_header_digest = DIGEST_CRC32C; 224255570Strasz else 225281461Strasz xo_errx(1, "invalid HeaderDigest at line %d; " 226261713Strasz "must be either \"none\" or \"CRC32C\"", lineno); 227255570Strasz } 228255570Strasz ; 229255570Strasz 230261711Straszdata_digest: DATA_DIGEST EQUALS STR 231255570Strasz { 232255570Strasz if (target->t_data_digest != DIGEST_UNSPECIFIED) 233281461Strasz xo_errx(1, "duplicated DataDigest at line %d", lineno); 234255570Strasz if (strcasecmp($3, "none") == 0) 235255570Strasz target->t_data_digest = DIGEST_NONE; 236255570Strasz else if (strcasecmp($3, "CRC32C") == 0) 237255570Strasz target->t_data_digest = DIGEST_CRC32C; 238255570Strasz else 239281461Strasz xo_errx(1, "invalid DataDigest at line %d; " 240261713Strasz "must be either \"none\" or \"CRC32C\"", lineno); 241255570Strasz } 242255570Strasz ; 243255570Strasz 244261711Straszsession_type: SESSION_TYPE EQUALS STR 245255570Strasz { 246255570Strasz if (target->t_session_type != SESSION_TYPE_UNSPECIFIED) 247281461Strasz xo_errx(1, "duplicated SessionType at line %d", lineno); 248255570Strasz if (strcasecmp($3, "normal") == 0) 249255570Strasz target->t_session_type = SESSION_TYPE_NORMAL; 250255570Strasz else if (strcasecmp($3, "discovery") == 0) 251255570Strasz target->t_session_type = SESSION_TYPE_DISCOVERY; 252255570Strasz else 253281461Strasz xo_errx(1, "invalid SessionType at line %d; " 254261713Strasz "must be either \"normal\" or \"discovery\"", lineno); 255255570Strasz } 256255570Strasz ; 257255570Strasz 258301033Straszenable: ENABLE EQUALS STR 259301033Strasz { 260301033Strasz if (target->t_enable != ENABLE_UNSPECIFIED) 261301033Strasz xo_errx(1, "duplicated enable at line %d", lineno); 262301033Strasz target->t_enable = parse_enable($3); 263301033Strasz if (target->t_enable == ENABLE_UNSPECIFIED) 264301033Strasz xo_errx(1, "invalid enable at line %d; " 265301033Strasz "must be either \"on\" or \"off\"", lineno); 266301033Strasz } 267301033Strasz ; 268301033Strasz 269278232Straszoffload: OFFLOAD EQUALS STR 270278232Strasz { 271278232Strasz if (target->t_offload != NULL) 272281461Strasz xo_errx(1, "duplicated offload at line %d", lineno); 273278232Strasz target->t_offload = $3; 274278232Strasz } 275278232Strasz ; 276278232Strasz 277261711Straszprotocol: PROTOCOL EQUALS STR 278255570Strasz { 279255570Strasz if (target->t_protocol != PROTOCOL_UNSPECIFIED) 280281461Strasz xo_errx(1, "duplicated protocol at line %d", lineno); 281255570Strasz if (strcasecmp($3, "iscsi") == 0) 282255570Strasz target->t_protocol = PROTOCOL_ISCSI; 283255570Strasz else if (strcasecmp($3, "iser") == 0) 284255570Strasz target->t_protocol = PROTOCOL_ISER; 285255570Strasz else 286281461Strasz xo_errx(1, "invalid protocol at line %d; " 287261713Strasz "must be either \"iscsi\" or \"iser\"", lineno); 288255570Strasz } 289255570Strasz ; 290255570Strasz 291261711Straszignored: IGNORED EQUALS STR 292255570Strasz { 293281461Strasz xo_warnx("obsolete statement ignored at line %d", lineno); 294255570Strasz } 295255570Strasz ; 296255570Strasz 297255570Strasz%% 298255570Strasz 299255570Straszvoid 300255570Straszyyerror(const char *str) 301255570Strasz{ 302255570Strasz 303281461Strasz xo_errx(1, "error in configuration file at line %d near '%s': %s", 304261713Strasz lineno, yytext, str); 305255570Strasz} 306255570Strasz 307255570Straszstatic void 308255570Straszcheck_perms(const char *path) 309255570Strasz{ 310255570Strasz struct stat sb; 311255570Strasz int error; 312255570Strasz 313255570Strasz error = stat(path, &sb); 314255570Strasz if (error != 0) { 315281461Strasz xo_warn("stat"); 316255570Strasz return; 317255570Strasz } 318255570Strasz if (sb.st_mode & S_IWOTH) { 319281461Strasz xo_warnx("%s is world-writable", path); 320255570Strasz } else if (sb.st_mode & S_IROTH) { 321281461Strasz xo_warnx("%s is world-readable", path); 322255570Strasz } else if (sb.st_mode & S_IXOTH) { 323255570Strasz /* 324255570Strasz * Ok, this one doesn't matter, but still do it, 325255570Strasz * just for consistency. 326255570Strasz */ 327281461Strasz xo_warnx("%s is world-executable", path); 328255570Strasz } 329255570Strasz 330255570Strasz /* 331255570Strasz * XXX: Should we also check for owner != 0? 332255570Strasz */ 333255570Strasz} 334255570Strasz 335255570Straszstruct conf * 336255570Straszconf_new_from_file(const char *path) 337255570Strasz{ 338255570Strasz int error; 339255570Strasz 340255570Strasz conf = conf_new(); 341255570Strasz target = target_new(conf); 342255570Strasz 343255570Strasz yyin = fopen(path, "r"); 344255570Strasz if (yyin == NULL) 345281461Strasz xo_err(1, "unable to open configuration file %s", path); 346255570Strasz check_perms(path); 347261713Strasz lineno = 1; 348255570Strasz yyrestart(yyin); 349255570Strasz error = yyparse(); 350255570Strasz assert(error == 0); 351255570Strasz fclose(yyin); 352255570Strasz 353255570Strasz assert(target->t_nickname == NULL); 354255570Strasz target_delete(target); 355255570Strasz 356255570Strasz conf_verify(conf); 357255570Strasz 358255570Strasz return (conf); 359255570Strasz} 360