parse.y revision 262840
118334Speter%{ 252298Sobrien/*- 318334Speter * Copyright (c) 2012 The FreeBSD Foundation 418334Speter * All rights reserved. 518334Speter * 618334Speter * This software was developed by Edward Tomasz Napierala under sponsorship 718334Speter * from the FreeBSD Foundation. 818334Speter * 918334Speter * Redistribution and use in source and binary forms, with or without 1018334Speter * modification, are permitted provided that the following conditions 1118334Speter * are met: 1218334Speter * 1. Redistributions of source code must retain the above copyright 1318334Speter * notice, this list of conditions and the following disclaimer. 1418334Speter * 2. Redistributions in binary form must reproduce the above copyright 1518334Speter * notice, this list of conditions and the following disclaimer in the 1618334Speter * documentation and/or other materials provided with the distribution. 1718334Speter * 1818334Speter * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 1918334Speter * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2018334Speter * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2152298Sobrien * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 2252298Sobrien * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2318334Speter * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2418334Speter * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2518334Speter * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2618334Speter * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2718334Speter * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2818334Speter * SUCH DAMAGE. 2918334Speter * 3018334Speter * $FreeBSD: stable/10/usr.bin/iscsictl/parse.y 262840 2014-03-06 11:05:35Z trasz $ 3150448Sobrien */ 3250448Sobrien 3350448Sobrien#include <sys/queue.h> 3450448Sobrien#include <sys/types.h> 3518334Speter#include <sys/stat.h> 3618334Speter#include <assert.h> 3718334Speter#include <err.h> 3818334Speter#include <stdio.h> 3918334Speter#include <stdint.h> 4050448Sobrien#include <stdlib.h> 4118334Speter#include <string.h> 4218334Speter 4318334Speter#include "iscsictl.h" 4452298Sobrien 4552298Sobrienextern FILE *yyin; 4618334Speterextern char *yytext; 4752298Sobrienextern int lineno; 4852298Sobrien 4952298Sobrienstatic struct conf *conf; 5052298Sobrienstatic struct target *target; 5152298Sobrien 5250448Sobrienextern void yyerror(const char *); 5350448Sobrienextern int yylex(void); 5450448Sobrienextern void yyrestart(FILE *); 5550448Sobrien 5618334Speter%} 5718334Speter 5818334Speter%token AUTH_METHOD HEADER_DIGEST DATA_DIGEST TARGET_NAME TARGET_ADDRESS 5918334Speter%token INITIATOR_NAME INITIATOR_ADDRESS INITIATOR_ALIAS USER SECRET 6018334Speter%token MUTUAL_USER MUTUAL_SECRET SESSION_TYPE PROTOCOL IGNORED 6118334Speter%token EQUALS OPENING_BRACKET CLOSING_BRACKET 6218334Speter 6318334Speter%union 6452298Sobrien{ 6552298Sobrien char *str; 6650448Sobrien} 6750448Sobrien 6850448Sobrien%token <str> STR 6918334Speter 7050448Sobrien%% 7118334Speter 7250448Sobrientargets: 7352298Sobrien | 7418334Speter targets target 7550448Sobrien ; 7652298Sobrien 7718334Spetertarget: STR OPENING_BRACKET target_entries CLOSING_BRACKET 7818334Speter { 7918334Speter if (target_find(conf, $1) != NULL) 8018334Speter errx(1, "duplicated target %s", $1); 8118334Speter target->t_nickname = $1; 8218334Speter target = target_new(conf); 8318334Speter } 8452298Sobrien ; 8550448Sobrien 8650448Sobrientarget_entries: 8750448Sobrien | 8850448Sobrien target_entries target_entry 8950448Sobrien ; 9050448Sobrien 9150448Sobrientarget_entry: 9252298Sobrien target_name 9318334Speter | 9450448Sobrien target_address 9518334Speter | 9618334Speter initiator_name 9718334Speter | 9850448Sobrien initiator_address 9950448Sobrien | 10018334Speter initiator_alias 10118334Speter | 10250448Sobrien user 10350448Sobrien | 10450448Sobrien secret 10550448Sobrien | 10650448Sobrien mutual_user 10718334Speter | 10850448Sobrien mutual_secret 10950448Sobrien | 11052298Sobrien auth_method 11152298Sobrien | 11252298Sobrien header_digest 11350448Sobrien | 11418334Speter data_digest 11518334Speter | 11618334Speter session_type 11750448Sobrien | 11818334Speter protocol 11918334Speter | 12018334Speter ignored 12118334Speter ; 12218334Speter 12318334Spetertarget_name: TARGET_NAME EQUALS STR 12418334Speter { 12518334Speter if (target->t_name != NULL) 12618334Speter errx(1, "duplicated TargetName at line %d", lineno); 12752298Sobrien target->t_name = $3; 12852298Sobrien } 12952298Sobrien ; 13018334Speter 13118334Spetertarget_address: TARGET_ADDRESS EQUALS STR 13218334Speter { 13318334Speter if (target->t_address != NULL) 13418334Speter errx(1, "duplicated TargetAddress at line %d", lineno); 13518334Speter target->t_address = $3; 13618334Speter } 13718334Speter ; 13818334Speter 13918334Speterinitiator_name: INITIATOR_NAME EQUALS STR 14018334Speter { 14118334Speter if (target->t_initiator_name != NULL) 14218334Speter errx(1, "duplicated InitiatorName at line %d", lineno); 14350448Sobrien target->t_initiator_name = $3; 14418334Speter } 14518334Speter ; 14618334Speter 14750448Sobrieninitiator_address: INITIATOR_ADDRESS EQUALS STR 14818334Speter { 14918334Speter if (target->t_initiator_address != NULL) 15018334Speter errx(1, "duplicated InitiatorAddress at line %d", lineno); 15118334Speter target->t_initiator_address = $3; 15218334Speter } 15318334Speter ; 15418334Speter 15550448Sobrieninitiator_alias: INITIATOR_ALIAS EQUALS STR 15650448Sobrien { 15718334Speter if (target->t_initiator_alias != NULL) 15818334Speter errx(1, "duplicated InitiatorAlias at line %d", lineno); 15950448Sobrien target->t_initiator_alias = $3; 16050448Sobrien } 16118334Speter ; 16252298Sobrien 16350448Sobrienuser: USER EQUALS STR 16418334Speter { 16518334Speter if (target->t_user != NULL) 16618334Speter errx(1, "duplicated chapIName at line %d", lineno); 16718334Speter target->t_user = $3; 16818334Speter } 16918334Speter ; 17018334Speter 17118334Spetersecret: SECRET EQUALS STR 17252298Sobrien { 17318334Speter if (target->t_secret != NULL) 17418334Speter errx(1, "duplicated chapSecret at line %d", lineno); 17518334Speter target->t_secret = $3; 17618334Speter } 17750448Sobrien ; 17818334Speter 17918334Spetermutual_user: MUTUAL_USER EQUALS STR 18050448Sobrien { 18150448Sobrien if (target->t_mutual_user != NULL) 18218334Speter errx(1, "duplicated tgtChapName at line %d", lineno); 18350448Sobrien target->t_mutual_user = $3; 18450448Sobrien } 18550448Sobrien ; 18618334Speter 18718334Spetermutual_secret: MUTUAL_SECRET EQUALS STR 18818334Speter { 18918334Speter if (target->t_mutual_secret != NULL) 19050448Sobrien errx(1, "duplicated tgtChapSecret at line %d", lineno); 19150448Sobrien target->t_mutual_secret = $3; 19250448Sobrien } 19350448Sobrien ; 19450448Sobrien 19550448Sobrienauth_method: AUTH_METHOD EQUALS STR 19650448Sobrien { 19750448Sobrien if (target->t_auth_method != AUTH_METHOD_UNSPECIFIED) 19850448Sobrien errx(1, "duplicated AuthMethod at line %d", lineno); 19950448Sobrien if (strcasecmp($3, "none") == 0) 20050448Sobrien target->t_auth_method = AUTH_METHOD_NONE; 20150448Sobrien else if (strcasecmp($3, "chap") == 0) 20250448Sobrien target->t_auth_method = AUTH_METHOD_CHAP; 20350448Sobrien else 20450448Sobrien errx(1, "invalid AuthMethod at line %d; " 20552298Sobrien "must be either \"none\" or \"CHAP\"", lineno); 20650448Sobrien } 20750448Sobrien ; 20850448Sobrien 20950448Sobrienheader_digest: HEADER_DIGEST EQUALS STR 21050448Sobrien { 21150448Sobrien if (target->t_header_digest != DIGEST_UNSPECIFIED) 21250448Sobrien errx(1, "duplicated HeaderDigest at line %d", lineno); 21350448Sobrien if (strcasecmp($3, "none") == 0) 21450448Sobrien target->t_header_digest = DIGEST_NONE; 21550448Sobrien else if (strcasecmp($3, "CRC32C") == 0) 21650448Sobrien target->t_header_digest = DIGEST_CRC32C; 21750448Sobrien else 21850448Sobrien errx(1, "invalid HeaderDigest at line %d; " 21950448Sobrien "must be either \"none\" or \"CRC32C\"", lineno); 22018334Speter } 22118334Speter ; 22218334Speter 22318334Speterdata_digest: DATA_DIGEST EQUALS STR 22418334Speter { 22518334Speter if (target->t_data_digest != DIGEST_UNSPECIFIED) 22618334Speter errx(1, "duplicated DataDigest at line %d", lineno); 22718334Speter if (strcasecmp($3, "none") == 0) 22818334Speter target->t_data_digest = DIGEST_NONE; 22918334Speter else if (strcasecmp($3, "CRC32C") == 0) 23018334Speter target->t_data_digest = DIGEST_CRC32C; 23118334Speter else 23218334Speter errx(1, "invalid DataDigest at line %d; " 23318334Speter "must be either \"none\" or \"CRC32C\"", lineno); 23418334Speter } 23518334Speter ; 23618334Speter 23750448Sobriensession_type: SESSION_TYPE EQUALS STR 23850448Sobrien { 23950448Sobrien if (target->t_session_type != SESSION_TYPE_UNSPECIFIED) 24050448Sobrien errx(1, "duplicated SessionType at line %d", lineno); 24150448Sobrien if (strcasecmp($3, "normal") == 0) 24250448Sobrien target->t_session_type = SESSION_TYPE_NORMAL; 24350448Sobrien else if (strcasecmp($3, "discovery") == 0) 24450448Sobrien target->t_session_type = SESSION_TYPE_DISCOVERY; 24550448Sobrien else 24650448Sobrien errx(1, "invalid SessionType at line %d; " 24750448Sobrien "must be either \"normal\" or \"discovery\"", lineno); 24850448Sobrien } 24952298Sobrien ; 25050448Sobrien 25152298Sobrienprotocol: PROTOCOL EQUALS STR 25252298Sobrien { 25350448Sobrien if (target->t_protocol != PROTOCOL_UNSPECIFIED) 25450448Sobrien errx(1, "duplicated protocol at line %d", lineno); 25550448Sobrien if (strcasecmp($3, "iscsi") == 0) 25650448Sobrien target->t_protocol = PROTOCOL_ISCSI; 25750448Sobrien else if (strcasecmp($3, "iser") == 0) 25818334Speter target->t_protocol = PROTOCOL_ISER; 25918334Speter else 26018334Speter errx(1, "invalid protocol at line %d; " 26118334Speter "must be either \"iscsi\" or \"iser\"", lineno); 26250448Sobrien } 26318334Speter ; 26418334Speter 26518334Speterignored: IGNORED EQUALS STR 26618334Speter { 26750448Sobrien warnx("obsolete statement ignored at line %d", lineno); 26818334Speter } 26950448Sobrien ; 27018334Speter 27150448Sobrien%% 27218334Speter 27350448Sobrienvoid 27418334Speteryyerror(const char *str) 27550448Sobrien{ 27652298Sobrien 27752298Sobrien errx(1, "error in configuration file at line %d near '%s': %s", 27852298Sobrien lineno, yytext, str); 27952298Sobrien} 28052298Sobrien 28152298Sobrienstatic void 28252298Sobriencheck_perms(const char *path) 28352298Sobrien{ 28418334Speter struct stat sb; 28552298Sobrien int error; 28618334Speter 28718334Speter error = stat(path, &sb); 28818334Speter if (error != 0) { 28918334Speter warn("stat"); 29052298Sobrien return; 29118334Speter } 29250448Sobrien if (sb.st_mode & S_IWOTH) { 29350448Sobrien warnx("%s is world-writable", path); 29450448Sobrien } else if (sb.st_mode & S_IROTH) { 29552298Sobrien warnx("%s is world-readable", path); 29652298Sobrien } else if (sb.st_mode & S_IXOTH) { 29752298Sobrien /* 29818334Speter * Ok, this one doesn't matter, but still do it, 29918334Speter * just for consistency. 30018334Speter */ 30150448Sobrien warnx("%s is world-executable", path); 30250448Sobrien } 30318334Speter 30418334Speter /* 30552298Sobrien * XXX: Should we also check for owner != 0? 30652298Sobrien */ 30718334Speter} 30818334Speter 30918334Speterstruct conf * 31052298Sobrienconf_new_from_file(const char *path) 31152298Sobrien{ 31252298Sobrien int error; 31352298Sobrien 31452298Sobrien conf = conf_new(); 31552298Sobrien target = target_new(conf); 31652298Sobrien 31752298Sobrien yyin = fopen(path, "r"); 31852298Sobrien if (yyin == NULL) 31952298Sobrien err(1, "unable to open configuration file %s", path); 32052298Sobrien check_perms(path); 32152298Sobrien lineno = 1; 32252298Sobrien yyrestart(yyin); 32318334Speter error = yyparse(); 32418334Speter assert(error == 0); 32518334Speter fclose(yyin); 32618334Speter 32718334Speter assert(target->t_nickname == NULL); 32818334Speter target_delete(target); 32918334Speter 33050448Sobrien conf_verify(conf); 33150448Sobrien 33250448Sobrien return (conf); 33350448Sobrien} 33418334Speter