1009ea47eSEdward Tomasz Napierala %{ 2009ea47eSEdward Tomasz Napierala /*- 3009ea47eSEdward Tomasz Napierala * Copyright (c) 2012 The FreeBSD Foundation 4009ea47eSEdward Tomasz Napierala * All rights reserved. 5009ea47eSEdward Tomasz Napierala * 6009ea47eSEdward Tomasz Napierala * This software was developed by Edward Tomasz Napierala under sponsorship 7009ea47eSEdward Tomasz Napierala * from the FreeBSD Foundation. 8009ea47eSEdward Tomasz Napierala * 9009ea47eSEdward Tomasz Napierala * Redistribution and use in source and binary forms, with or without 10009ea47eSEdward Tomasz Napierala * modification, are permitted provided that the following conditions 11009ea47eSEdward Tomasz Napierala * are met: 12009ea47eSEdward Tomasz Napierala * 1. Redistributions of source code must retain the above copyright 13009ea47eSEdward Tomasz Napierala * notice, this list of conditions and the following disclaimer. 14009ea47eSEdward Tomasz Napierala * 2. Redistributions in binary form must reproduce the above copyright 15009ea47eSEdward Tomasz Napierala * notice, this list of conditions and the following disclaimer in the 16009ea47eSEdward Tomasz Napierala * documentation and/or other materials provided with the distribution. 17009ea47eSEdward Tomasz Napierala * 18009ea47eSEdward Tomasz Napierala * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 19009ea47eSEdward Tomasz Napierala * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20009ea47eSEdward Tomasz Napierala * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21009ea47eSEdward Tomasz Napierala * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 22009ea47eSEdward Tomasz Napierala * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23009ea47eSEdward Tomasz Napierala * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 24009ea47eSEdward Tomasz Napierala * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 25009ea47eSEdward Tomasz Napierala * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 26009ea47eSEdward Tomasz Napierala * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 27009ea47eSEdward Tomasz Napierala * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 28009ea47eSEdward Tomasz Napierala * SUCH DAMAGE. 29009ea47eSEdward Tomasz Napierala * 30009ea47eSEdward Tomasz Napierala * $FreeBSD$ 31009ea47eSEdward Tomasz Napierala */ 32009ea47eSEdward Tomasz Napierala 33009ea47eSEdward Tomasz Napierala #include <sys/queue.h> 34009ea47eSEdward Tomasz Napierala #include <sys/types.h> 35009ea47eSEdward Tomasz Napierala #include <sys/stat.h> 36009ea47eSEdward Tomasz Napierala #include <assert.h> 37009ea47eSEdward Tomasz Napierala #include <err.h> 38009ea47eSEdward Tomasz Napierala #include <stdio.h> 39009ea47eSEdward Tomasz Napierala #include <stdint.h> 40009ea47eSEdward Tomasz Napierala #include <stdlib.h> 41009ea47eSEdward Tomasz Napierala #include <string.h> 42009ea47eSEdward Tomasz Napierala 43009ea47eSEdward Tomasz Napierala #include "iscsictl.h" 44009ea47eSEdward Tomasz Napierala 45009ea47eSEdward Tomasz Napierala extern FILE *yyin; 46009ea47eSEdward Tomasz Napierala extern char *yytext; 47009ea47eSEdward Tomasz Napierala extern int lineno; 48009ea47eSEdward Tomasz Napierala 49009ea47eSEdward Tomasz Napierala static struct conf *conf; 50009ea47eSEdward Tomasz Napierala static struct target *target; 51009ea47eSEdward Tomasz Napierala 52009ea47eSEdward Tomasz Napierala extern void yyerror(const char *); 53009ea47eSEdward Tomasz Napierala extern int yylex(void); 54009ea47eSEdward Tomasz Napierala extern void yyrestart(FILE *); 55009ea47eSEdward Tomasz Napierala 56009ea47eSEdward Tomasz Napierala %} 57009ea47eSEdward Tomasz Napierala 58009ea47eSEdward Tomasz Napierala %token AUTH_METHOD HEADER_DIGEST DATA_DIGEST TARGET_NAME TARGET_ADDRESS 59009ea47eSEdward Tomasz Napierala %token INITIATOR_NAME INITIATOR_ADDRESS INITIATOR_ALIAS USER SECRET 60009ea47eSEdward Tomasz Napierala %token MUTUAL_USER MUTUAL_SECRET SESSION_TYPE PROTOCOL IGNORED 61009ea47eSEdward Tomasz Napierala %token EQUALS OPENING_BRACKET CLOSING_BRACKET 62009ea47eSEdward Tomasz Napierala 63009ea47eSEdward Tomasz Napierala %union 64009ea47eSEdward Tomasz Napierala { 65009ea47eSEdward Tomasz Napierala char *str; 66009ea47eSEdward Tomasz Napierala } 67009ea47eSEdward Tomasz Napierala 68009ea47eSEdward Tomasz Napierala %token <str> STR 69009ea47eSEdward Tomasz Napierala 70009ea47eSEdward Tomasz Napierala %% 71009ea47eSEdward Tomasz Napierala 72*5381f862SEdward Tomasz Napierala targets: 73009ea47eSEdward Tomasz Napierala | 74*5381f862SEdward Tomasz Napierala targets target 75009ea47eSEdward Tomasz Napierala ; 76009ea47eSEdward Tomasz Napierala 77*5381f862SEdward Tomasz Napierala target: STR OPENING_BRACKET target_entries CLOSING_BRACKET 78009ea47eSEdward Tomasz Napierala { 79009ea47eSEdward Tomasz Napierala if (target_find(conf, $1) != NULL) 80009ea47eSEdward Tomasz Napierala errx(1, "duplicated target %s", $1); 81009ea47eSEdward Tomasz Napierala target->t_nickname = $1; 82009ea47eSEdward Tomasz Napierala target = target_new(conf); 83009ea47eSEdward Tomasz Napierala } 84009ea47eSEdward Tomasz Napierala ; 85009ea47eSEdward Tomasz Napierala 86009ea47eSEdward Tomasz Napierala target_entries: 87009ea47eSEdward Tomasz Napierala | 88009ea47eSEdward Tomasz Napierala target_entries target_entry 89009ea47eSEdward Tomasz Napierala ; 90009ea47eSEdward Tomasz Napierala 91009ea47eSEdward Tomasz Napierala target_entry: 92*5381f862SEdward Tomasz Napierala target_name 93009ea47eSEdward Tomasz Napierala | 94*5381f862SEdward Tomasz Napierala target_address 95009ea47eSEdward Tomasz Napierala | 96*5381f862SEdward Tomasz Napierala initiator_name 97009ea47eSEdward Tomasz Napierala | 98*5381f862SEdward Tomasz Napierala initiator_address 99009ea47eSEdward Tomasz Napierala | 100*5381f862SEdward Tomasz Napierala initiator_alias 101009ea47eSEdward Tomasz Napierala | 102*5381f862SEdward Tomasz Napierala user 103009ea47eSEdward Tomasz Napierala | 104*5381f862SEdward Tomasz Napierala secret 105009ea47eSEdward Tomasz Napierala | 106*5381f862SEdward Tomasz Napierala mutual_user 107009ea47eSEdward Tomasz Napierala | 108*5381f862SEdward Tomasz Napierala mutual_secret 109009ea47eSEdward Tomasz Napierala | 110*5381f862SEdward Tomasz Napierala auth_method 111009ea47eSEdward Tomasz Napierala | 112*5381f862SEdward Tomasz Napierala header_digest 113009ea47eSEdward Tomasz Napierala | 114*5381f862SEdward Tomasz Napierala data_digest 115009ea47eSEdward Tomasz Napierala | 116*5381f862SEdward Tomasz Napierala session_type 117009ea47eSEdward Tomasz Napierala | 118*5381f862SEdward Tomasz Napierala protocol 119009ea47eSEdward Tomasz Napierala | 120*5381f862SEdward Tomasz Napierala ignored 121009ea47eSEdward Tomasz Napierala ; 122009ea47eSEdward Tomasz Napierala 123*5381f862SEdward Tomasz Napierala target_name: TARGET_NAME EQUALS STR 124009ea47eSEdward Tomasz Napierala { 125009ea47eSEdward Tomasz Napierala if (target->t_name != NULL) 126009ea47eSEdward Tomasz Napierala errx(1, "duplicated TargetName at line %d", lineno + 1); 127009ea47eSEdward Tomasz Napierala target->t_name = $3; 128009ea47eSEdward Tomasz Napierala } 129009ea47eSEdward Tomasz Napierala ; 130009ea47eSEdward Tomasz Napierala 131*5381f862SEdward Tomasz Napierala target_address: TARGET_ADDRESS EQUALS STR 132009ea47eSEdward Tomasz Napierala { 133009ea47eSEdward Tomasz Napierala if (target->t_address != NULL) 134009ea47eSEdward Tomasz Napierala errx(1, "duplicated TargetAddress at line %d", lineno + 1); 135009ea47eSEdward Tomasz Napierala target->t_address = $3; 136009ea47eSEdward Tomasz Napierala } 137009ea47eSEdward Tomasz Napierala ; 138009ea47eSEdward Tomasz Napierala 139*5381f862SEdward Tomasz Napierala initiator_name: INITIATOR_NAME EQUALS STR 140009ea47eSEdward Tomasz Napierala { 141009ea47eSEdward Tomasz Napierala if (target->t_initiator_name != NULL) 142009ea47eSEdward Tomasz Napierala errx(1, "duplicated InitiatorName at line %d", lineno + 1); 143009ea47eSEdward Tomasz Napierala target->t_initiator_name = $3; 144009ea47eSEdward Tomasz Napierala } 145009ea47eSEdward Tomasz Napierala ; 146009ea47eSEdward Tomasz Napierala 147*5381f862SEdward Tomasz Napierala initiator_address: INITIATOR_ADDRESS EQUALS STR 148009ea47eSEdward Tomasz Napierala { 149009ea47eSEdward Tomasz Napierala if (target->t_initiator_address != NULL) 150009ea47eSEdward Tomasz Napierala errx(1, "duplicated InitiatorAddress at line %d", lineno + 1); 151009ea47eSEdward Tomasz Napierala target->t_initiator_address = $3; 152009ea47eSEdward Tomasz Napierala } 153009ea47eSEdward Tomasz Napierala ; 154009ea47eSEdward Tomasz Napierala 155*5381f862SEdward Tomasz Napierala initiator_alias: INITIATOR_ALIAS EQUALS STR 156009ea47eSEdward Tomasz Napierala { 157009ea47eSEdward Tomasz Napierala if (target->t_initiator_alias != NULL) 158009ea47eSEdward Tomasz Napierala errx(1, "duplicated InitiatorAlias at line %d", lineno + 1); 159009ea47eSEdward Tomasz Napierala target->t_initiator_alias = $3; 160009ea47eSEdward Tomasz Napierala } 161009ea47eSEdward Tomasz Napierala ; 162009ea47eSEdward Tomasz Napierala 163*5381f862SEdward Tomasz Napierala user: USER EQUALS STR 164009ea47eSEdward Tomasz Napierala { 165009ea47eSEdward Tomasz Napierala if (target->t_user != NULL) 166009ea47eSEdward Tomasz Napierala errx(1, "duplicated chapIName at line %d", lineno + 1); 167009ea47eSEdward Tomasz Napierala target->t_user = $3; 168009ea47eSEdward Tomasz Napierala } 169009ea47eSEdward Tomasz Napierala ; 170009ea47eSEdward Tomasz Napierala 171*5381f862SEdward Tomasz Napierala secret: SECRET EQUALS STR 172009ea47eSEdward Tomasz Napierala { 173009ea47eSEdward Tomasz Napierala if (target->t_secret != NULL) 174009ea47eSEdward Tomasz Napierala errx(1, "duplicated chapSecret at line %d", lineno + 1); 175009ea47eSEdward Tomasz Napierala target->t_secret = $3; 176009ea47eSEdward Tomasz Napierala } 177009ea47eSEdward Tomasz Napierala ; 178009ea47eSEdward Tomasz Napierala 179*5381f862SEdward Tomasz Napierala mutual_user: MUTUAL_USER EQUALS STR 180009ea47eSEdward Tomasz Napierala { 181009ea47eSEdward Tomasz Napierala if (target->t_mutual_user != NULL) 182009ea47eSEdward Tomasz Napierala errx(1, "duplicated tgtChapName at line %d", lineno + 1); 183009ea47eSEdward Tomasz Napierala target->t_mutual_user = $3; 184009ea47eSEdward Tomasz Napierala } 185009ea47eSEdward Tomasz Napierala ; 186009ea47eSEdward Tomasz Napierala 187*5381f862SEdward Tomasz Napierala mutual_secret: MUTUAL_SECRET EQUALS STR 188009ea47eSEdward Tomasz Napierala { 189009ea47eSEdward Tomasz Napierala if (target->t_mutual_secret != NULL) 190009ea47eSEdward Tomasz Napierala errx(1, "duplicated tgtChapSecret at line %d", lineno + 1); 191009ea47eSEdward Tomasz Napierala target->t_mutual_secret = $3; 192009ea47eSEdward Tomasz Napierala } 193009ea47eSEdward Tomasz Napierala ; 194009ea47eSEdward Tomasz Napierala 195*5381f862SEdward Tomasz Napierala auth_method: AUTH_METHOD EQUALS STR 196009ea47eSEdward Tomasz Napierala { 197009ea47eSEdward Tomasz Napierala if (target->t_auth_method != AUTH_METHOD_UNSPECIFIED) 198009ea47eSEdward Tomasz Napierala errx(1, "duplicated AuthMethod at line %d", lineno + 1); 199009ea47eSEdward Tomasz Napierala if (strcasecmp($3, "none") == 0) 200009ea47eSEdward Tomasz Napierala target->t_auth_method = AUTH_METHOD_NONE; 201009ea47eSEdward Tomasz Napierala else if (strcasecmp($3, "chap") == 0) 202009ea47eSEdward Tomasz Napierala target->t_auth_method = AUTH_METHOD_CHAP; 203009ea47eSEdward Tomasz Napierala else 204009ea47eSEdward Tomasz Napierala errx(1, "invalid AuthMethod at line %d; " 205009ea47eSEdward Tomasz Napierala "must be either \"none\" or \"CHAP\"", lineno + 1); 206009ea47eSEdward Tomasz Napierala } 207009ea47eSEdward Tomasz Napierala ; 208009ea47eSEdward Tomasz Napierala 209*5381f862SEdward Tomasz Napierala header_digest: HEADER_DIGEST EQUALS STR 210009ea47eSEdward Tomasz Napierala { 211009ea47eSEdward Tomasz Napierala if (target->t_header_digest != DIGEST_UNSPECIFIED) 212009ea47eSEdward Tomasz Napierala errx(1, "duplicated HeaderDigest at line %d", lineno + 1); 213009ea47eSEdward Tomasz Napierala if (strcasecmp($3, "none") == 0) 214009ea47eSEdward Tomasz Napierala target->t_header_digest = DIGEST_NONE; 215009ea47eSEdward Tomasz Napierala else if (strcasecmp($3, "CRC32C") == 0) 216009ea47eSEdward Tomasz Napierala target->t_header_digest = DIGEST_CRC32C; 217009ea47eSEdward Tomasz Napierala else 218009ea47eSEdward Tomasz Napierala errx(1, "invalid HeaderDigest at line %d; " 219009ea47eSEdward Tomasz Napierala "must be either \"none\" or \"CRC32C\"", lineno + 1); 220009ea47eSEdward Tomasz Napierala } 221009ea47eSEdward Tomasz Napierala ; 222009ea47eSEdward Tomasz Napierala 223*5381f862SEdward Tomasz Napierala data_digest: DATA_DIGEST EQUALS STR 224009ea47eSEdward Tomasz Napierala { 225009ea47eSEdward Tomasz Napierala if (target->t_data_digest != DIGEST_UNSPECIFIED) 226009ea47eSEdward Tomasz Napierala errx(1, "duplicated DataDigest at line %d", lineno + 1); 227009ea47eSEdward Tomasz Napierala if (strcasecmp($3, "none") == 0) 228009ea47eSEdward Tomasz Napierala target->t_data_digest = DIGEST_NONE; 229009ea47eSEdward Tomasz Napierala else if (strcasecmp($3, "CRC32C") == 0) 230009ea47eSEdward Tomasz Napierala target->t_data_digest = DIGEST_CRC32C; 231009ea47eSEdward Tomasz Napierala else 232009ea47eSEdward Tomasz Napierala errx(1, "invalid DataDigest at line %d; " 233009ea47eSEdward Tomasz Napierala "must be either \"none\" or \"CRC32C\"", lineno + 1); 234009ea47eSEdward Tomasz Napierala } 235009ea47eSEdward Tomasz Napierala ; 236009ea47eSEdward Tomasz Napierala 237*5381f862SEdward Tomasz Napierala session_type: SESSION_TYPE EQUALS STR 238009ea47eSEdward Tomasz Napierala { 239009ea47eSEdward Tomasz Napierala if (target->t_session_type != SESSION_TYPE_UNSPECIFIED) 240009ea47eSEdward Tomasz Napierala errx(1, "duplicated SessionType at line %d", lineno + 1); 241009ea47eSEdward Tomasz Napierala if (strcasecmp($3, "normal") == 0) 242009ea47eSEdward Tomasz Napierala target->t_session_type = SESSION_TYPE_NORMAL; 243009ea47eSEdward Tomasz Napierala else if (strcasecmp($3, "discovery") == 0) 244009ea47eSEdward Tomasz Napierala target->t_session_type = SESSION_TYPE_DISCOVERY; 245009ea47eSEdward Tomasz Napierala else 246009ea47eSEdward Tomasz Napierala errx(1, "invalid SessionType at line %d; " 247009ea47eSEdward Tomasz Napierala "must be either \"normal\" or \"discovery\"", lineno + 1); 248009ea47eSEdward Tomasz Napierala } 249009ea47eSEdward Tomasz Napierala ; 250009ea47eSEdward Tomasz Napierala 251*5381f862SEdward Tomasz Napierala protocol: PROTOCOL EQUALS STR 252009ea47eSEdward Tomasz Napierala { 253009ea47eSEdward Tomasz Napierala if (target->t_protocol != PROTOCOL_UNSPECIFIED) 254009ea47eSEdward Tomasz Napierala errx(1, "duplicated protocol at line %d", lineno + 1); 255009ea47eSEdward Tomasz Napierala if (strcasecmp($3, "iscsi") == 0) 256009ea47eSEdward Tomasz Napierala target->t_protocol = PROTOCOL_ISCSI; 257009ea47eSEdward Tomasz Napierala else if (strcasecmp($3, "iser") == 0) 258009ea47eSEdward Tomasz Napierala target->t_protocol = PROTOCOL_ISER; 259009ea47eSEdward Tomasz Napierala else 260009ea47eSEdward Tomasz Napierala errx(1, "invalid protocol at line %d; " 261009ea47eSEdward Tomasz Napierala "must be either \"iscsi\" or \"iser\"", lineno + 1); 262009ea47eSEdward Tomasz Napierala } 263009ea47eSEdward Tomasz Napierala ; 264009ea47eSEdward Tomasz Napierala 265*5381f862SEdward Tomasz Napierala ignored: IGNORED EQUALS STR 266009ea47eSEdward Tomasz Napierala { 267009ea47eSEdward Tomasz Napierala warnx("obsolete statement ignored at line %d", lineno + 1); 268009ea47eSEdward Tomasz Napierala } 269009ea47eSEdward Tomasz Napierala ; 270009ea47eSEdward Tomasz Napierala 271009ea47eSEdward Tomasz Napierala %% 272009ea47eSEdward Tomasz Napierala 273009ea47eSEdward Tomasz Napierala void 274009ea47eSEdward Tomasz Napierala yyerror(const char *str) 275009ea47eSEdward Tomasz Napierala { 276009ea47eSEdward Tomasz Napierala 277009ea47eSEdward Tomasz Napierala errx(1, "error in configuration file at line %d near '%s': %s", 278009ea47eSEdward Tomasz Napierala lineno + 1, yytext, str); 279009ea47eSEdward Tomasz Napierala } 280009ea47eSEdward Tomasz Napierala 281009ea47eSEdward Tomasz Napierala static void 282009ea47eSEdward Tomasz Napierala check_perms(const char *path) 283009ea47eSEdward Tomasz Napierala { 284009ea47eSEdward Tomasz Napierala struct stat sb; 285009ea47eSEdward Tomasz Napierala int error; 286009ea47eSEdward Tomasz Napierala 287009ea47eSEdward Tomasz Napierala error = stat(path, &sb); 288009ea47eSEdward Tomasz Napierala if (error != 0) { 289009ea47eSEdward Tomasz Napierala warn("stat"); 290009ea47eSEdward Tomasz Napierala return; 291009ea47eSEdward Tomasz Napierala } 292009ea47eSEdward Tomasz Napierala if (sb.st_mode & S_IWOTH) { 293009ea47eSEdward Tomasz Napierala warnx("%s is world-writable", path); 294009ea47eSEdward Tomasz Napierala } else if (sb.st_mode & S_IROTH) { 295009ea47eSEdward Tomasz Napierala warnx("%s is world-readable", path); 296009ea47eSEdward Tomasz Napierala } else if (sb.st_mode & S_IXOTH) { 297009ea47eSEdward Tomasz Napierala /* 298009ea47eSEdward Tomasz Napierala * Ok, this one doesn't matter, but still do it, 299009ea47eSEdward Tomasz Napierala * just for consistency. 300009ea47eSEdward Tomasz Napierala */ 301009ea47eSEdward Tomasz Napierala warnx("%s is world-executable", path); 302009ea47eSEdward Tomasz Napierala } 303009ea47eSEdward Tomasz Napierala 304009ea47eSEdward Tomasz Napierala /* 305009ea47eSEdward Tomasz Napierala * XXX: Should we also check for owner != 0? 306009ea47eSEdward Tomasz Napierala */ 307009ea47eSEdward Tomasz Napierala } 308009ea47eSEdward Tomasz Napierala 309009ea47eSEdward Tomasz Napierala struct conf * 310009ea47eSEdward Tomasz Napierala conf_new_from_file(const char *path) 311009ea47eSEdward Tomasz Napierala { 312009ea47eSEdward Tomasz Napierala int error; 313009ea47eSEdward Tomasz Napierala 314009ea47eSEdward Tomasz Napierala conf = conf_new(); 315009ea47eSEdward Tomasz Napierala target = target_new(conf); 316009ea47eSEdward Tomasz Napierala 317009ea47eSEdward Tomasz Napierala yyin = fopen(path, "r"); 318009ea47eSEdward Tomasz Napierala if (yyin == NULL) 319009ea47eSEdward Tomasz Napierala err(1, "unable to open configuration file %s", path); 320009ea47eSEdward Tomasz Napierala check_perms(path); 321009ea47eSEdward Tomasz Napierala lineno = 0; 322009ea47eSEdward Tomasz Napierala yyrestart(yyin); 323009ea47eSEdward Tomasz Napierala error = yyparse(); 324009ea47eSEdward Tomasz Napierala assert(error == 0); 325009ea47eSEdward Tomasz Napierala fclose(yyin); 326009ea47eSEdward Tomasz Napierala 327009ea47eSEdward Tomasz Napierala assert(target->t_nickname == NULL); 328009ea47eSEdward Tomasz Napierala target_delete(target); 329009ea47eSEdward Tomasz Napierala 330009ea47eSEdward Tomasz Napierala conf_verify(conf); 331009ea47eSEdward Tomasz Napierala 332009ea47eSEdward Tomasz Napierala return (conf); 333009ea47eSEdward Tomasz Napierala } 334