parse.y revision 262840
1100280Sgordon%{ 2100280Sgordon/*- 3118638Sfjoe * Copyright (c) 2012 The FreeBSD Foundation 466830Sobrien * All rights reserved. 566830Sobrien * 666830Sobrien * This software was developed by Edward Tomasz Napierala under sponsorship 766830Sobrien * from the FreeBSD Foundation. 866830Sobrien * 966830Sobrien * Redistribution and use in source and binary forms, with or without 1066830Sobrien * modification, are permitted provided that the following conditions 1166830Sobrien * are met: 1266830Sobrien * 1. Redistributions of source code must retain the above copyright 1366830Sobrien * notice, this list of conditions and the following disclaimer. 1466830Sobrien * 2. Redistributions in binary form must reproduce the above copyright 1566830Sobrien * notice, this list of conditions and the following disclaimer in the 1666830Sobrien * documentation and/or other materials provided with the distribution. 1766830Sobrien * 1866830Sobrien * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 1966830Sobrien * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2066830Sobrien * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2166830Sobrien * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 2266830Sobrien * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2366830Sobrien * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2466830Sobrien * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2566830Sobrien * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2666830Sobrien * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2751231Ssheldonh * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 28100280Sgordon * SUCH DAMAGE. 29108191Sdillon * 30127663Sluigi * $FreeBSD: stable/10/usr.bin/iscsictl/parse.y 262840 2014-03-06 11:05:35Z trasz $ 31108191Sdillon */ 32108191Sdillon 33127663Sluigi#include <sys/queue.h> 34127663Sluigi#include <sys/types.h> 35127663Sluigi#include <sys/stat.h> 36127663Sluigi#include <assert.h> 37108191Sdillon#include <err.h> 38127663Sluigi#include <stdio.h> 39127663Sluigi#include <stdint.h> 40127663Sluigi#include <stdlib.h> 41108191Sdillon#include <string.h> 42127663Sluigi 43127663Sluigi#include "iscsictl.h" 44127663Sluigi 45127663Sluigiextern FILE *yyin; 46149170Sbrooksextern char *yytext; 47127663Sluigiextern int lineno; 48127663Sluigi 49127663Sluigistatic struct conf *conf; 50127663Sluigistatic struct target *target; 51127663Sluigi 52127663Sluigiextern void yyerror(const char *); 53149170Sbrooksextern int yylex(void); 54130151Sschweikhextern void yyrestart(FILE *); 55127663Sluigi 56127663Sluigi%} 57149170Sbrooks 58149170Sbrooks%token AUTH_METHOD HEADER_DIGEST DATA_DIGEST TARGET_NAME TARGET_ADDRESS 59108191Sdillon%token INITIATOR_NAME INITIATOR_ADDRESS INITIATOR_ALIAS USER SECRET 60127663Sluigi%token MUTUAL_USER MUTUAL_SECRET SESSION_TYPE PROTOCOL IGNORED 61127663Sluigi%token EQUALS OPENING_BRACKET CLOSING_BRACKET 62126787Sphk 63127663Sluigi%union 64108191Sdillon{ 65127663Sluigi char *str; 66127663Sluigi} 67127663Sluigi 68127663Sluigi%token <str> STR 69127663Sluigi 70127663Sluigi%% 71108191Sdillon 72179014Sbmstargets: 73179014Sbms | 74179014Sbms targets target 75179014Sbms ; 76182895Sbms 77182895Sbmstarget: STR OPENING_BRACKET target_entries CLOSING_BRACKET 78182895Sbms { 79182895Sbms if (target_find(conf, $1) != NULL) 80182895Sbms errx(1, "duplicated target %s", $1); 81182895Sbms target->t_nickname = $1; 82182895Sbms target = target_new(conf); 83182895Sbms } 84182895Sbms ; 85182895Sbms 86127663Sluigitarget_entries: 87164862Sluigi | 88164862Sluigi target_entries target_entry 89164862Sluigi ; 90164862Sluigi 91164862Sluigitarget_entry: 92164862Sluigi target_name 93164862Sluigi | 94161824Sbrooks target_address 95161824Sbrooks | 96161824Sbrooks initiator_name 97108191Sdillon | 98127663Sluigi initiator_address 99127663Sluigi | 100127663Sluigi initiator_alias 101127663Sluigi | 102127663Sluigi user 103127663Sluigi | 104127663Sluigi secret 105127663Sluigi | 106127663Sluigi mutual_user 107127663Sluigi | 108108191Sdillon mutual_secret 109127663Sluigi | 110127663Sluigi auth_method 111127663Sluigi | 112127663Sluigi header_digest 113108191Sdillon | 114127663Sluigi data_digest 115127663Sluigi | 116127663Sluigi session_type 117127663Sluigi | 118161824Sbrooks protocol 119161824Sbrooks | 120161824Sbrooks ignored 121161824Sbrooks ; 122161824Sbrooks 123208060Sdougbtarget_name: TARGET_NAME EQUALS STR 124127663Sluigi { 125127663Sluigi if (target->t_name != NULL) 126161533Sru errx(1, "duplicated TargetName at line %d", lineno); 127161533Sru target->t_name = $3; 128161533Sru } 129161533Sru ; 130161533Sru 131161533Srutarget_address: TARGET_ADDRESS EQUALS STR 132127663Sluigi { 133161533Sru if (target->t_address != NULL) 134161533Sru errx(1, "duplicated TargetAddress at line %d", lineno); 135161533Sru target->t_address = $3; 136161533Sru } 137161533Sru ; 138161533Sru 139127663Sluigiinitiator_name: INITIATOR_NAME EQUALS STR 140127663Sluigi { 141127663Sluigi if (target->t_initiator_name != NULL) 142127663Sluigi errx(1, "duplicated InitiatorName at line %d", lineno); 143127663Sluigi target->t_initiator_name = $3; 144126868Sbrooks } 145127663Sluigi ; 146127663Sluigi 147108191Sdilloninitiator_address: INITIATOR_ADDRESS EQUALS STR 148100280Sgordon { 149100280Sgordon if (target->t_initiator_address != NULL) 150164862Sluigi errx(1, "duplicated InitiatorAddress at line %d", lineno); 151164862Sluigi target->t_initiator_address = $3; 152164862Sluigi } 153164862Sluigi ; 154164862Sluigi 155164862Sluigiinitiator_alias: INITIATOR_ALIAS EQUALS STR 156164862Sluigi { 157164862Sluigi if (target->t_initiator_alias != NULL) 15843803Sdillon errx(1, "duplicated InitiatorAlias at line %d", lineno); 15943803Sdillon target->t_initiator_alias = $3; 16043803Sdillon } 16143803Sdillon ; 16243803Sdillon 16343803Sdillonuser: USER EQUALS STR 164179014Sbms { 16551231Ssheldonh if (target->t_user != NULL) 166108191Sdillon errx(1, "duplicated chapIName at line %d", lineno); 167179014Sbms target->t_user = $3; 168179014Sbms } 169179014Sbms ; 170108191Sdillon 171108191Sdillonsecret: SECRET EQUALS STR 172108191Sdillon { 173108191Sdillon if (target->t_secret != NULL) 174108191Sdillon errx(1, "duplicated chapSecret at line %d", lineno); 175108191Sdillon target->t_secret = $3; 176108191Sdillon } 177108191Sdillon ; 178108191Sdillon 17943803Sdillonmutual_user: MUTUAL_USER EQUALS STR 18043803Sdillon { 181164862Sluigi if (target->t_mutual_user != NULL) 182164862Sluigi errx(1, "duplicated tgtChapName at line %d", lineno); 183164862Sluigi target->t_mutual_user = $3; 184164862Sluigi } 185164862Sluigi ; 186164862Sluigi 187164862Sluigimutual_secret: MUTUAL_SECRET EQUALS STR 188164862Sluigi { 189164862Sluigi if (target->t_mutual_secret != NULL) 190164862Sluigi errx(1, "duplicated tgtChapSecret at line %d", lineno); 191164862Sluigi target->t_mutual_secret = $3; 192164862Sluigi } 193164862Sluigi ; 194164862Sluigi 195164862Sluigiauth_method: AUTH_METHOD EQUALS STR 196164862Sluigi { 197164862Sluigi if (target->t_auth_method != AUTH_METHOD_UNSPECIFIED) 198108191Sdillon errx(1, "duplicated AuthMethod at line %d", lineno); 199108191Sdillon if (strcasecmp($3, "none") == 0) 200108191Sdillon target->t_auth_method = AUTH_METHOD_NONE; 201154239Sbrooks else if (strcasecmp($3, "chap") == 0) 20275931Simp target->t_auth_method = AUTH_METHOD_CHAP; 20375931Simp else 204108191Sdillon errx(1, "invalid AuthMethod at line %d; " 205108191Sdillon "must be either \"none\" or \"CHAP\"", lineno); 206108191Sdillon } 207164862Sluigi ; 208110942Sjhay 209121014Skrisheader_digest: HEADER_DIGEST EQUALS STR 210108191Sdillon { 211108191Sdillon if (target->t_header_digest != DIGEST_UNSPECIFIED) 212108191Sdillon errx(1, "duplicated HeaderDigest at line %d", lineno); 213164862Sluigi if (strcasecmp($3, "none") == 0) 214108191Sdillon target->t_header_digest = DIGEST_NONE; 215108191Sdillon else if (strcasecmp($3, "CRC32C") == 0) 216108191Sdillon target->t_header_digest = DIGEST_CRC32C; 217108191Sdillon else 218108191Sdillon errx(1, "invalid HeaderDigest at line %d; " 21943803Sdillon "must be either \"none\" or \"CRC32C\"", lineno); 22043803Sdillon } 22155520Sluigi ; 22243803Sdillon 22351231Ssheldonhdata_digest: DATA_DIGEST EQUALS STR 22443803Sdillon { 22555520Sluigi if (target->t_data_digest != DIGEST_UNSPECIFIED) 22655520Sluigi errx(1, "duplicated DataDigest at line %d", lineno); 22755520Sluigi if (strcasecmp($3, "none") == 0) 228149170Sbrooks target->t_data_digest = DIGEST_NONE; 229126787Sphk else if (strcasecmp($3, "CRC32C") == 0) 230126787Sphk target->t_data_digest = DIGEST_CRC32C; 231126787Sphk else 232128706Sru errx(1, "invalid DataDigest at line %d; " 233126787Sphk "must be either \"none\" or \"CRC32C\"", lineno); 234126787Sphk } 235126787Sphk ; 236126787Sphk 237126787Sphksession_type: SESSION_TYPE EQUALS STR 238126787Sphk { 239126787Sphk if (target->t_session_type != SESSION_TYPE_UNSPECIFIED) 240126787Sphk errx(1, "duplicated SessionType at line %d", lineno); 241126787Sphk if (strcasecmp($3, "normal") == 0) 242126787Sphk target->t_session_type = SESSION_TYPE_NORMAL; 243126787Sphk else if (strcasecmp($3, "discovery") == 0) 244126787Sphk target->t_session_type = SESSION_TYPE_DISCOVERY; 245126787Sphk else 246149170Sbrooks errx(1, "invalid SessionType at line %d; " 247150169Srwatson "must be either \"normal\" or \"discovery\"", lineno); 248127657Sluigi } 249149170Sbrooks ; 250126787Sphk 25143803Sdillonprotocol: PROTOCOL EQUALS STR 252164862Sluigi { 253121067Sdougb if (target->t_protocol != PROTOCOL_UNSPECIFIED) 254128706Sru errx(1, "duplicated protocol at line %d", lineno); 255117087Sbrooks if (strcasecmp($3, "iscsi") == 0) 256117087Sbrooks target->t_protocol = PROTOCOL_ISCSI; 257117087Sbrooks else if (strcasecmp($3, "iser") == 0) 258117087Sbrooks target->t_protocol = PROTOCOL_ISER; 259117087Sbrooks else 260117087Sbrooks errx(1, "invalid protocol at line %d; " 261117087Sbrooks "must be either \"iscsi\" or \"iser\"", lineno); 262117087Sbrooks } 263127657Sluigi ; 264149170Sbrooks 265149170Sbrooksignored: IGNORED EQUALS STR 266149170Sbrooks { 267149170Sbrooks warnx("obsolete statement ignored at line %d", lineno); 268149170Sbrooks } 269149170Sbrooks ; 270149170Sbrooks 271149170Sbrooks%% 272149170Sbrooks 273149170Sbrooksvoid 274127657Sluigiyyerror(const char *str) 275161824Sbrooks{ 276164862Sluigi 277126868Sbrooks errx(1, "error in configuration file at line %d near '%s': %s", 278108191Sdillon lineno, yytext, str); 279121067Sdougb} 280108191Sdillon 28143803Sdillonstatic void 282108191Sdilloncheck_perms(const char *path) 283108191Sdillon{ 284108191Sdillon struct stat sb; 285108191Sdillon int error; 286108191Sdillon 287108191Sdillon error = stat(path, &sb); 288108191Sdillon if (error != 0) { 289108191Sdillon warn("stat"); 290108191Sdillon return; 291108191Sdillon } 292108191Sdillon if (sb.st_mode & S_IWOTH) { 293117087Sbrooks warnx("%s is world-writable", path); 294117087Sbrooks } else if (sb.st_mode & S_IROTH) { 295117087Sbrooks warnx("%s is world-readable", path); 296117087Sbrooks } else if (sb.st_mode & S_IXOTH) { 297108191Sdillon /* 298164862Sluigi * Ok, this one doesn't matter, but still do it, 299127657Sluigi * just for consistency. 300108191Sdillon */ 301164862Sluigi warnx("%s is world-executable", path); 302164862Sluigi } 303108191Sdillon 304108191Sdillon /* 305164862Sluigi * XXX: Should we also check for owner != 0? 30643803Sdillon */ 307164862Sluigi} 308164862Sluigi 309182895Sbmsstruct conf * 310182895Sbmsconf_new_from_file(const char *path) 311182895Sbms{ 312182895Sbms int error; 313182895Sbms 314182895Sbms conf = conf_new(); 315182895Sbms target = target_new(conf); 316182895Sbms 317182895Sbms yyin = fopen(path, "r"); 318182895Sbms if (yyin == NULL) 319182895Sbms err(1, "unable to open configuration file %s", path); 320182895Sbms check_perms(path); 321182895Sbms lineno = 1; 322182895Sbms yyrestart(yyin); 323182895Sbms error = yyparse(); 324182895Sbms assert(error == 0); 325182895Sbms fclose(yyin); 326182895Sbms 327182895Sbms assert(target->t_nickname == NULL); 328182895Sbms target_delete(target); 329182895Sbms 330182895Sbms conf_verify(conf); 331182895Sbms 332182895Sbms return (conf); 333182895Sbms} 334182895Sbms