parse.y revision 262840
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.bin/iscsictl/parse.y 262840 2014-03-06 11:05:35Z trasz $ 31255570Strasz */ 32255570Strasz 33255570Strasz#include <sys/queue.h> 34255570Strasz#include <sys/types.h> 35255570Strasz#include <sys/stat.h> 36255570Strasz#include <assert.h> 37255570Strasz#include <err.h> 38255570Strasz#include <stdio.h> 39255570Strasz#include <stdint.h> 40255570Strasz#include <stdlib.h> 41255570Strasz#include <string.h> 42255570Strasz 43255570Strasz#include "iscsictl.h" 44255570Strasz 45255570Straszextern FILE *yyin; 46255570Straszextern char *yytext; 47255570Straszextern int lineno; 48255570Strasz 49255570Straszstatic struct conf *conf; 50255570Straszstatic struct target *target; 51255570Strasz 52255570Straszextern void yyerror(const char *); 53255570Straszextern int yylex(void); 54255570Straszextern void yyrestart(FILE *); 55255570Strasz 56255570Strasz%} 57255570Strasz 58255570Strasz%token AUTH_METHOD HEADER_DIGEST DATA_DIGEST TARGET_NAME TARGET_ADDRESS 59255570Strasz%token INITIATOR_NAME INITIATOR_ADDRESS INITIATOR_ALIAS USER SECRET 60255570Strasz%token MUTUAL_USER MUTUAL_SECRET SESSION_TYPE PROTOCOL IGNORED 61255570Strasz%token EQUALS OPENING_BRACKET CLOSING_BRACKET 62255570Strasz 63255570Strasz%union 64255570Strasz{ 65255570Strasz char *str; 66255570Strasz} 67255570Strasz 68255570Strasz%token <str> STR 69255570Strasz 70255570Strasz%% 71255570Strasz 72262838Strasztargets: 73255570Strasz | 74262838Strasz targets target 75255570Strasz ; 76255570Strasz 77262838Strasztarget: STR OPENING_BRACKET target_entries CLOSING_BRACKET 78255570Strasz { 79255570Strasz if (target_find(conf, $1) != NULL) 80255570Strasz errx(1, "duplicated target %s", $1); 81255570Strasz target->t_nickname = $1; 82255570Strasz target = target_new(conf); 83255570Strasz } 84255570Strasz ; 85255570Strasz 86255570Strasztarget_entries: 87255570Strasz | 88255570Strasz target_entries target_entry 89255570Strasz ; 90255570Strasz 91255570Strasztarget_entry: 92262838Strasz target_name 93255570Strasz | 94262838Strasz target_address 95255570Strasz | 96262838Strasz initiator_name 97255570Strasz | 98262838Strasz initiator_address 99255570Strasz | 100262838Strasz initiator_alias 101255570Strasz | 102262838Strasz user 103255570Strasz | 104262838Strasz secret 105255570Strasz | 106262838Strasz mutual_user 107255570Strasz | 108262838Strasz mutual_secret 109255570Strasz | 110262838Strasz auth_method 111255570Strasz | 112262838Strasz header_digest 113255570Strasz | 114262838Strasz data_digest 115255570Strasz | 116262838Strasz session_type 117255570Strasz | 118262838Strasz protocol 119255570Strasz | 120262838Strasz ignored 121255570Strasz ; 122255570Strasz 123262838Strasztarget_name: TARGET_NAME EQUALS STR 124255570Strasz { 125255570Strasz if (target->t_name != NULL) 126262840Strasz errx(1, "duplicated TargetName at line %d", lineno); 127255570Strasz target->t_name = $3; 128255570Strasz } 129255570Strasz ; 130255570Strasz 131262838Strasztarget_address: TARGET_ADDRESS EQUALS STR 132255570Strasz { 133255570Strasz if (target->t_address != NULL) 134262840Strasz errx(1, "duplicated TargetAddress at line %d", lineno); 135255570Strasz target->t_address = $3; 136255570Strasz } 137255570Strasz ; 138255570Strasz 139262838Straszinitiator_name: INITIATOR_NAME EQUALS STR 140255570Strasz { 141255570Strasz if (target->t_initiator_name != NULL) 142262840Strasz errx(1, "duplicated InitiatorName at line %d", lineno); 143255570Strasz target->t_initiator_name = $3; 144255570Strasz } 145255570Strasz ; 146255570Strasz 147262838Straszinitiator_address: INITIATOR_ADDRESS EQUALS STR 148255570Strasz { 149255570Strasz if (target->t_initiator_address != NULL) 150262840Strasz errx(1, "duplicated InitiatorAddress at line %d", lineno); 151255570Strasz target->t_initiator_address = $3; 152255570Strasz } 153255570Strasz ; 154255570Strasz 155262838Straszinitiator_alias: INITIATOR_ALIAS EQUALS STR 156255570Strasz { 157255570Strasz if (target->t_initiator_alias != NULL) 158262840Strasz errx(1, "duplicated InitiatorAlias at line %d", lineno); 159255570Strasz target->t_initiator_alias = $3; 160255570Strasz } 161255570Strasz ; 162255570Strasz 163262838Straszuser: USER EQUALS STR 164255570Strasz { 165255570Strasz if (target->t_user != NULL) 166262840Strasz errx(1, "duplicated chapIName at line %d", lineno); 167255570Strasz target->t_user = $3; 168255570Strasz } 169255570Strasz ; 170255570Strasz 171262838Straszsecret: SECRET EQUALS STR 172255570Strasz { 173255570Strasz if (target->t_secret != NULL) 174262840Strasz errx(1, "duplicated chapSecret at line %d", lineno); 175255570Strasz target->t_secret = $3; 176255570Strasz } 177255570Strasz ; 178255570Strasz 179262838Straszmutual_user: MUTUAL_USER EQUALS STR 180255570Strasz { 181255570Strasz if (target->t_mutual_user != NULL) 182262840Strasz errx(1, "duplicated tgtChapName at line %d", lineno); 183255570Strasz target->t_mutual_user = $3; 184255570Strasz } 185255570Strasz ; 186255570Strasz 187262838Straszmutual_secret: MUTUAL_SECRET EQUALS STR 188255570Strasz { 189255570Strasz if (target->t_mutual_secret != NULL) 190262840Strasz errx(1, "duplicated tgtChapSecret at line %d", lineno); 191255570Strasz target->t_mutual_secret = $3; 192255570Strasz } 193255570Strasz ; 194255570Strasz 195262838Straszauth_method: AUTH_METHOD EQUALS STR 196255570Strasz { 197255570Strasz if (target->t_auth_method != AUTH_METHOD_UNSPECIFIED) 198262840Strasz errx(1, "duplicated AuthMethod at line %d", lineno); 199255570Strasz if (strcasecmp($3, "none") == 0) 200255570Strasz target->t_auth_method = AUTH_METHOD_NONE; 201255570Strasz else if (strcasecmp($3, "chap") == 0) 202255570Strasz target->t_auth_method = AUTH_METHOD_CHAP; 203255570Strasz else 204255570Strasz errx(1, "invalid AuthMethod at line %d; " 205262840Strasz "must be either \"none\" or \"CHAP\"", lineno); 206255570Strasz } 207255570Strasz ; 208255570Strasz 209262838Straszheader_digest: HEADER_DIGEST EQUALS STR 210255570Strasz { 211255570Strasz if (target->t_header_digest != DIGEST_UNSPECIFIED) 212262840Strasz errx(1, "duplicated HeaderDigest at line %d", lineno); 213255570Strasz if (strcasecmp($3, "none") == 0) 214255570Strasz target->t_header_digest = DIGEST_NONE; 215255570Strasz else if (strcasecmp($3, "CRC32C") == 0) 216255570Strasz target->t_header_digest = DIGEST_CRC32C; 217255570Strasz else 218255570Strasz errx(1, "invalid HeaderDigest at line %d; " 219262840Strasz "must be either \"none\" or \"CRC32C\"", lineno); 220255570Strasz } 221255570Strasz ; 222255570Strasz 223262838Straszdata_digest: DATA_DIGEST EQUALS STR 224255570Strasz { 225255570Strasz if (target->t_data_digest != DIGEST_UNSPECIFIED) 226262840Strasz errx(1, "duplicated DataDigest at line %d", lineno); 227255570Strasz if (strcasecmp($3, "none") == 0) 228255570Strasz target->t_data_digest = DIGEST_NONE; 229255570Strasz else if (strcasecmp($3, "CRC32C") == 0) 230255570Strasz target->t_data_digest = DIGEST_CRC32C; 231255570Strasz else 232255570Strasz errx(1, "invalid DataDigest at line %d; " 233262840Strasz "must be either \"none\" or \"CRC32C\"", lineno); 234255570Strasz } 235255570Strasz ; 236255570Strasz 237262838Straszsession_type: SESSION_TYPE EQUALS STR 238255570Strasz { 239255570Strasz if (target->t_session_type != SESSION_TYPE_UNSPECIFIED) 240262840Strasz errx(1, "duplicated SessionType at line %d", lineno); 241255570Strasz if (strcasecmp($3, "normal") == 0) 242255570Strasz target->t_session_type = SESSION_TYPE_NORMAL; 243255570Strasz else if (strcasecmp($3, "discovery") == 0) 244255570Strasz target->t_session_type = SESSION_TYPE_DISCOVERY; 245255570Strasz else 246255570Strasz errx(1, "invalid SessionType at line %d; " 247262840Strasz "must be either \"normal\" or \"discovery\"", lineno); 248255570Strasz } 249255570Strasz ; 250255570Strasz 251262838Straszprotocol: PROTOCOL EQUALS STR 252255570Strasz { 253255570Strasz if (target->t_protocol != PROTOCOL_UNSPECIFIED) 254262840Strasz errx(1, "duplicated protocol at line %d", lineno); 255255570Strasz if (strcasecmp($3, "iscsi") == 0) 256255570Strasz target->t_protocol = PROTOCOL_ISCSI; 257255570Strasz else if (strcasecmp($3, "iser") == 0) 258255570Strasz target->t_protocol = PROTOCOL_ISER; 259255570Strasz else 260255570Strasz errx(1, "invalid protocol at line %d; " 261262840Strasz "must be either \"iscsi\" or \"iser\"", lineno); 262255570Strasz } 263255570Strasz ; 264255570Strasz 265262838Straszignored: IGNORED EQUALS STR 266255570Strasz { 267262840Strasz warnx("obsolete statement ignored at line %d", lineno); 268255570Strasz } 269255570Strasz ; 270255570Strasz 271255570Strasz%% 272255570Strasz 273255570Straszvoid 274255570Straszyyerror(const char *str) 275255570Strasz{ 276255570Strasz 277255570Strasz errx(1, "error in configuration file at line %d near '%s': %s", 278262840Strasz lineno, yytext, str); 279255570Strasz} 280255570Strasz 281255570Straszstatic void 282255570Straszcheck_perms(const char *path) 283255570Strasz{ 284255570Strasz struct stat sb; 285255570Strasz int error; 286255570Strasz 287255570Strasz error = stat(path, &sb); 288255570Strasz if (error != 0) { 289255570Strasz warn("stat"); 290255570Strasz return; 291255570Strasz } 292255570Strasz if (sb.st_mode & S_IWOTH) { 293255570Strasz warnx("%s is world-writable", path); 294255570Strasz } else if (sb.st_mode & S_IROTH) { 295255570Strasz warnx("%s is world-readable", path); 296255570Strasz } else if (sb.st_mode & S_IXOTH) { 297255570Strasz /* 298255570Strasz * Ok, this one doesn't matter, but still do it, 299255570Strasz * just for consistency. 300255570Strasz */ 301255570Strasz warnx("%s is world-executable", path); 302255570Strasz } 303255570Strasz 304255570Strasz /* 305255570Strasz * XXX: Should we also check for owner != 0? 306255570Strasz */ 307255570Strasz} 308255570Strasz 309255570Straszstruct conf * 310255570Straszconf_new_from_file(const char *path) 311255570Strasz{ 312255570Strasz int error; 313255570Strasz 314255570Strasz conf = conf_new(); 315255570Strasz target = target_new(conf); 316255570Strasz 317255570Strasz yyin = fopen(path, "r"); 318255570Strasz if (yyin == NULL) 319255570Strasz err(1, "unable to open configuration file %s", path); 320255570Strasz check_perms(path); 321262840Strasz lineno = 1; 322255570Strasz yyrestart(yyin); 323255570Strasz error = yyparse(); 324255570Strasz assert(error == 0); 325255570Strasz fclose(yyin); 326255570Strasz 327255570Strasz assert(target->t_nickname == NULL); 328255570Strasz target_delete(target); 329255570Strasz 330255570Strasz conf_verify(conf); 331255570Strasz 332255570Strasz return (conf); 333255570Strasz} 334