1%{ 2/*- 3 * Copyright (c) 2012 The FreeBSD Foundation 4 * All rights reserved. 5 * 6 * This software was developed by Edward Tomasz Napierala under sponsorship 7 * from the FreeBSD Foundation. 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions 11 * are met: 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 2. Redistributions in binary form must reproduce the above copyright 15 * notice, this list of conditions and the following disclaimer in the 16 * documentation and/or other materials provided with the distribution. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 19 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 22 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 24 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 28 * SUCH DAMAGE. 29 *
| 1%{ 2/*- 3 * Copyright (c) 2012 The FreeBSD Foundation 4 * All rights reserved. 5 * 6 * This software was developed by Edward Tomasz Napierala under sponsorship 7 * from the FreeBSD Foundation. 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions 11 * are met: 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 2. Redistributions in binary form must reproduce the above copyright 15 * notice, this list of conditions and the following disclaimer in the 16 * documentation and/or other materials provided with the distribution. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 19 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 22 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 24 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 28 * SUCH DAMAGE. 29 *
|
30 * $FreeBSD: stable/10/usr.sbin/ctld/parse.y 263723 2014-03-25 12:10:30Z trasz $
| 30 * $FreeBSD: stable/10/usr.sbin/ctld/parse.y 263724 2014-03-25 12:12:37Z trasz $
|
31 */ 32 33#include <sys/queue.h> 34#include <sys/types.h> 35#include <sys/stat.h> 36#include <assert.h> 37#include <stdio.h> 38#include <stdint.h> 39#include <stdlib.h> 40#include <string.h> 41 42#include "ctld.h" 43 44extern FILE *yyin; 45extern char *yytext; 46extern int lineno; 47 48static struct conf *conf = NULL; 49static struct auth_group *auth_group = NULL; 50static struct portal_group *portal_group = NULL; 51static struct target *target = NULL; 52static struct lun *lun = NULL; 53 54extern void yyerror(const char *); 55extern int yylex(void); 56extern void yyrestart(FILE *); 57 58%} 59
| 31 */ 32 33#include <sys/queue.h> 34#include <sys/types.h> 35#include <sys/stat.h> 36#include <assert.h> 37#include <stdio.h> 38#include <stdint.h> 39#include <stdlib.h> 40#include <string.h> 41 42#include "ctld.h" 43 44extern FILE *yyin; 45extern char *yytext; 46extern int lineno; 47 48static struct conf *conf = NULL; 49static struct auth_group *auth_group = NULL; 50static struct portal_group *portal_group = NULL; 51static struct target *target = NULL; 52static struct lun *lun = NULL; 53 54extern void yyerror(const char *); 55extern int yylex(void); 56extern void yyrestart(FILE *); 57 58%} 59
|
60%token ALIAS AUTH_GROUP BACKEND BLOCKSIZE CHAP CHAP_MUTUAL CLOSING_BRACKET 61%token DEBUG DEVICE_ID DISCOVERY_AUTH_GROUP INITIATOR_NAME INITIATOR_PORTAL 62%token LISTEN LISTEN_ISER LUN MAXPROC NUM OPENING_BRACKET OPTION PATH PIDFILE 63%token PORTAL_GROUP SERIAL SIZE STR TARGET TIMEOUT
| 60%token ALIAS AUTH_GROUP AUTH_TYPE BACKEND BLOCKSIZE CHAP CHAP_MUTUAL 61%token CLOSING_BRACKET DEBUG DEVICE_ID DISCOVERY_AUTH_GROUP INITIATOR_NAME 62%token INITIATOR_PORTAL LISTEN LISTEN_ISER LUN MAXPROC NUM OPENING_BRACKET 63%token OPTION PATH PIDFILE PORTAL_GROUP SERIAL SIZE STR TARGET TIMEOUT
|
64 65%union 66{ 67 uint64_t num; 68 char *str; 69} 70 71%token <num> NUM 72%token <str> STR 73 74%% 75 76statements: 77 | 78 statements statement 79 ; 80 81statement: 82 debug 83 | 84 timeout 85 | 86 maxproc 87 | 88 pidfile 89 | 90 auth_group 91 | 92 portal_group 93 | 94 target 95 ; 96 97debug: DEBUG NUM 98 { 99 conf->conf_debug = $2; 100 } 101 ; 102 103timeout: TIMEOUT NUM 104 { 105 conf->conf_timeout = $2; 106 } 107 ; 108 109maxproc: MAXPROC NUM 110 { 111 conf->conf_maxproc = $2; 112 } 113 ; 114 115pidfile: PIDFILE STR 116 { 117 if (conf->conf_pidfile_path != NULL) { 118 log_warnx("pidfile specified more than once"); 119 free($2); 120 return (1); 121 } 122 conf->conf_pidfile_path = $2; 123 } 124 ; 125 126auth_group: AUTH_GROUP auth_group_name 127 OPENING_BRACKET auth_group_entries CLOSING_BRACKET 128 { 129 auth_group = NULL; 130 } 131 ; 132 133auth_group_name: STR 134 { 135 auth_group = auth_group_new(conf, $1); 136 free($1); 137 if (auth_group == NULL) 138 return (1); 139 } 140 ; 141 142auth_group_entries: 143 | 144 auth_group_entries auth_group_entry 145 ; 146 147auth_group_entry:
| 64 65%union 66{ 67 uint64_t num; 68 char *str; 69} 70 71%token <num> NUM 72%token <str> STR 73 74%% 75 76statements: 77 | 78 statements statement 79 ; 80 81statement: 82 debug 83 | 84 timeout 85 | 86 maxproc 87 | 88 pidfile 89 | 90 auth_group 91 | 92 portal_group 93 | 94 target 95 ; 96 97debug: DEBUG NUM 98 { 99 conf->conf_debug = $2; 100 } 101 ; 102 103timeout: TIMEOUT NUM 104 { 105 conf->conf_timeout = $2; 106 } 107 ; 108 109maxproc: MAXPROC NUM 110 { 111 conf->conf_maxproc = $2; 112 } 113 ; 114 115pidfile: PIDFILE STR 116 { 117 if (conf->conf_pidfile_path != NULL) { 118 log_warnx("pidfile specified more than once"); 119 free($2); 120 return (1); 121 } 122 conf->conf_pidfile_path = $2; 123 } 124 ; 125 126auth_group: AUTH_GROUP auth_group_name 127 OPENING_BRACKET auth_group_entries CLOSING_BRACKET 128 { 129 auth_group = NULL; 130 } 131 ; 132 133auth_group_name: STR 134 { 135 auth_group = auth_group_new(conf, $1); 136 free($1); 137 if (auth_group == NULL) 138 return (1); 139 } 140 ; 141 142auth_group_entries: 143 | 144 auth_group_entries auth_group_entry 145 ; 146 147auth_group_entry:
|
| 148 auth_group_auth_type 149 |
|
148 auth_group_chap 149 | 150 auth_group_chap_mutual 151 | 152 auth_group_initiator_name 153 | 154 auth_group_initiator_portal 155 ; 156
| 150 auth_group_chap 151 | 152 auth_group_chap_mutual 153 | 154 auth_group_initiator_name 155 | 156 auth_group_initiator_portal 157 ; 158
|
| 159auth_group_auth_type: AUTH_TYPE STR 160 { 161 int error; 162 163 error = auth_group_set_type_str(auth_group, $2); 164 free($2); 165 if (error != 0) 166 return (1); 167 } 168 ; 169
|
157auth_group_chap: CHAP STR STR 158 { 159 const struct auth *ca; 160 161 ca = auth_new_chap(auth_group, $2, $3); 162 free($2); 163 free($3); 164 if (ca == NULL) 165 return (1); 166 } 167 ; 168 169auth_group_chap_mutual: CHAP_MUTUAL STR STR STR STR 170 { 171 const struct auth *ca; 172 173 ca = auth_new_chap_mutual(auth_group, $2, $3, $4, $5); 174 free($2); 175 free($3); 176 free($4); 177 free($5); 178 if (ca == NULL) 179 return (1); 180 } 181 ; 182 183auth_group_initiator_name: INITIATOR_NAME STR 184 { 185 const struct auth_name *an; 186 187 an = auth_name_new(auth_group, $2); 188 free($2); 189 if (an == NULL) 190 return (1); 191 } 192 ; 193 194auth_group_initiator_portal: INITIATOR_PORTAL STR 195 { 196 const struct auth_portal *ap; 197 198 ap = auth_portal_new(auth_group, $2); 199 free($2); 200 if (ap == NULL) 201 return (1); 202 } 203 ; 204 205portal_group: PORTAL_GROUP portal_group_name 206 OPENING_BRACKET portal_group_entries CLOSING_BRACKET 207 { 208 portal_group = NULL; 209 } 210 ; 211 212portal_group_name: STR 213 { 214 portal_group = portal_group_new(conf, $1); 215 free($1); 216 if (portal_group == NULL) 217 return (1); 218 } 219 ; 220 221portal_group_entries: 222 | 223 portal_group_entries portal_group_entry 224 ; 225 226portal_group_entry: 227 portal_group_discovery_auth_group 228 | 229 portal_group_listen 230 | 231 portal_group_listen_iser 232 ; 233 234portal_group_discovery_auth_group: DISCOVERY_AUTH_GROUP STR 235 { 236 if (portal_group->pg_discovery_auth_group != NULL) { 237 log_warnx("discovery-auth-group for portal-group " 238 "\"%s\" specified more than once", 239 portal_group->pg_name); 240 return (1); 241 } 242 portal_group->pg_discovery_auth_group = 243 auth_group_find(conf, $2); 244 if (portal_group->pg_discovery_auth_group == NULL) { 245 log_warnx("unknown discovery-auth-group \"%s\" " 246 "for portal-group \"%s\"", 247 $2, portal_group->pg_name); 248 return (1); 249 } 250 free($2); 251 } 252 ; 253 254portal_group_listen: LISTEN STR 255 { 256 int error; 257 258 error = portal_group_add_listen(portal_group, $2, false); 259 free($2); 260 if (error != 0) 261 return (1); 262 } 263 ; 264 265portal_group_listen_iser: LISTEN_ISER STR 266 { 267 int error; 268 269 error = portal_group_add_listen(portal_group, $2, true); 270 free($2); 271 if (error != 0) 272 return (1); 273 } 274 ; 275 276target: TARGET target_name 277 OPENING_BRACKET target_entries CLOSING_BRACKET 278 { 279 target = NULL; 280 } 281 ; 282 283target_name: STR 284 { 285 target = target_new(conf, $1); 286 free($1); 287 if (target == NULL) 288 return (1); 289 } 290 ; 291 292target_entries: 293 | 294 target_entries target_entry 295 ; 296 297target_entry: 298 target_alias 299 | 300 target_auth_group 301 |
| 170auth_group_chap: CHAP STR STR 171 { 172 const struct auth *ca; 173 174 ca = auth_new_chap(auth_group, $2, $3); 175 free($2); 176 free($3); 177 if (ca == NULL) 178 return (1); 179 } 180 ; 181 182auth_group_chap_mutual: CHAP_MUTUAL STR STR STR STR 183 { 184 const struct auth *ca; 185 186 ca = auth_new_chap_mutual(auth_group, $2, $3, $4, $5); 187 free($2); 188 free($3); 189 free($4); 190 free($5); 191 if (ca == NULL) 192 return (1); 193 } 194 ; 195 196auth_group_initiator_name: INITIATOR_NAME STR 197 { 198 const struct auth_name *an; 199 200 an = auth_name_new(auth_group, $2); 201 free($2); 202 if (an == NULL) 203 return (1); 204 } 205 ; 206 207auth_group_initiator_portal: INITIATOR_PORTAL STR 208 { 209 const struct auth_portal *ap; 210 211 ap = auth_portal_new(auth_group, $2); 212 free($2); 213 if (ap == NULL) 214 return (1); 215 } 216 ; 217 218portal_group: PORTAL_GROUP portal_group_name 219 OPENING_BRACKET portal_group_entries CLOSING_BRACKET 220 { 221 portal_group = NULL; 222 } 223 ; 224 225portal_group_name: STR 226 { 227 portal_group = portal_group_new(conf, $1); 228 free($1); 229 if (portal_group == NULL) 230 return (1); 231 } 232 ; 233 234portal_group_entries: 235 | 236 portal_group_entries portal_group_entry 237 ; 238 239portal_group_entry: 240 portal_group_discovery_auth_group 241 | 242 portal_group_listen 243 | 244 portal_group_listen_iser 245 ; 246 247portal_group_discovery_auth_group: DISCOVERY_AUTH_GROUP STR 248 { 249 if (portal_group->pg_discovery_auth_group != NULL) { 250 log_warnx("discovery-auth-group for portal-group " 251 "\"%s\" specified more than once", 252 portal_group->pg_name); 253 return (1); 254 } 255 portal_group->pg_discovery_auth_group = 256 auth_group_find(conf, $2); 257 if (portal_group->pg_discovery_auth_group == NULL) { 258 log_warnx("unknown discovery-auth-group \"%s\" " 259 "for portal-group \"%s\"", 260 $2, portal_group->pg_name); 261 return (1); 262 } 263 free($2); 264 } 265 ; 266 267portal_group_listen: LISTEN STR 268 { 269 int error; 270 271 error = portal_group_add_listen(portal_group, $2, false); 272 free($2); 273 if (error != 0) 274 return (1); 275 } 276 ; 277 278portal_group_listen_iser: LISTEN_ISER STR 279 { 280 int error; 281 282 error = portal_group_add_listen(portal_group, $2, true); 283 free($2); 284 if (error != 0) 285 return (1); 286 } 287 ; 288 289target: TARGET target_name 290 OPENING_BRACKET target_entries CLOSING_BRACKET 291 { 292 target = NULL; 293 } 294 ; 295 296target_name: STR 297 { 298 target = target_new(conf, $1); 299 free($1); 300 if (target == NULL) 301 return (1); 302 } 303 ; 304 305target_entries: 306 | 307 target_entries target_entry 308 ; 309 310target_entry: 311 target_alias 312 | 313 target_auth_group 314 |
|
| 315 target_auth_type 316 |
|
302 target_chap 303 | 304 target_chap_mutual 305 | 306 target_initiator_name 307 | 308 target_initiator_portal 309 | 310 target_portal_group 311 | 312 target_lun 313 ; 314 315target_alias: ALIAS STR 316 { 317 if (target->t_alias != NULL) { 318 log_warnx("alias for target \"%s\" " 319 "specified more than once", target->t_name); 320 return (1); 321 } 322 target->t_alias = $2; 323 } 324 ; 325 326target_auth_group: AUTH_GROUP STR 327 { 328 if (target->t_auth_group != NULL) { 329 if (target->t_auth_group->ag_name != NULL) 330 log_warnx("auth-group for target \"%s\" " 331 "specified more than once", target->t_name); 332 else
| 317 target_chap 318 | 319 target_chap_mutual 320 | 321 target_initiator_name 322 | 323 target_initiator_portal 324 | 325 target_portal_group 326 | 327 target_lun 328 ; 329 330target_alias: ALIAS STR 331 { 332 if (target->t_alias != NULL) { 333 log_warnx("alias for target \"%s\" " 334 "specified more than once", target->t_name); 335 return (1); 336 } 337 target->t_alias = $2; 338 } 339 ; 340 341target_auth_group: AUTH_GROUP STR 342 { 343 if (target->t_auth_group != NULL) { 344 if (target->t_auth_group->ag_name != NULL) 345 log_warnx("auth-group for target \"%s\" " 346 "specified more than once", target->t_name); 347 else
|
333 log_warnx("cannot mix auth-group with explicit "
| 348 log_warnx("cannot use both auth-group and explicit "
|
334 "authorisations for target \"%s\"", 335 target->t_name); 336 return (1); 337 } 338 target->t_auth_group = auth_group_find(conf, $2); 339 if (target->t_auth_group == NULL) { 340 log_warnx("unknown auth-group \"%s\" for target " 341 "\"%s\"", $2, target->t_name); 342 return (1); 343 } 344 free($2); 345 } 346 ; 347
| 349 "authorisations for target \"%s\"", 350 target->t_name); 351 return (1); 352 } 353 target->t_auth_group = auth_group_find(conf, $2); 354 if (target->t_auth_group == NULL) { 355 log_warnx("unknown auth-group \"%s\" for target " 356 "\"%s\"", $2, target->t_name); 357 return (1); 358 } 359 free($2); 360 } 361 ; 362
|
| 363target_auth_type: AUTH_TYPE STR 364 { 365 int error; 366 367 if (target->t_auth_group != NULL) { 368 if (target->t_auth_group->ag_name != NULL) { 369 log_warnx("cannot use both auth-group and " 370 "auth-type for target \"%s\"", 371 target->t_name); 372 return (1); 373 } 374 } else { 375 target->t_auth_group = auth_group_new(conf, NULL); 376 if (target->t_auth_group == NULL) { 377 free($2); 378 return (1); 379 } 380 target->t_auth_group->ag_target = target; 381 } 382 error = auth_group_set_type_str(target->t_auth_group, $2); 383 free($2); 384 if (error != 0) 385 return (1); 386 } 387 ; 388
|
348target_chap: CHAP STR STR 349 { 350 const struct auth *ca; 351 352 if (target->t_auth_group != NULL) { 353 if (target->t_auth_group->ag_name != NULL) {
| 389target_chap: CHAP STR STR 390 { 391 const struct auth *ca; 392 393 if (target->t_auth_group != NULL) { 394 if (target->t_auth_group->ag_name != NULL) {
|
354 log_warnx("cannot mix auth-group with explicit " 355 "authorisations for target \"%s\"",
| 395 log_warnx("cannot use both auth-group and " 396 "chap for target \"%s\"",
|
356 target->t_name); 357 free($2); 358 free($3); 359 return (1); 360 } 361 } else { 362 target->t_auth_group = auth_group_new(conf, NULL); 363 if (target->t_auth_group == NULL) { 364 free($2); 365 free($3); 366 return (1); 367 } 368 target->t_auth_group->ag_target = target; 369 } 370 ca = auth_new_chap(target->t_auth_group, $2, $3); 371 free($2); 372 free($3); 373 if (ca == NULL) 374 return (1); 375 } 376 ; 377 378target_chap_mutual: CHAP_MUTUAL STR STR STR STR 379 { 380 const struct auth *ca; 381 382 if (target->t_auth_group != NULL) { 383 if (target->t_auth_group->ag_name != NULL) {
| 397 target->t_name); 398 free($2); 399 free($3); 400 return (1); 401 } 402 } else { 403 target->t_auth_group = auth_group_new(conf, NULL); 404 if (target->t_auth_group == NULL) { 405 free($2); 406 free($3); 407 return (1); 408 } 409 target->t_auth_group->ag_target = target; 410 } 411 ca = auth_new_chap(target->t_auth_group, $2, $3); 412 free($2); 413 free($3); 414 if (ca == NULL) 415 return (1); 416 } 417 ; 418 419target_chap_mutual: CHAP_MUTUAL STR STR STR STR 420 { 421 const struct auth *ca; 422 423 if (target->t_auth_group != NULL) { 424 if (target->t_auth_group->ag_name != NULL) {
|
384 log_warnx("cannot mix auth-group with explicit " 385 "authorisations for target \"%s\"",
| 425 log_warnx("cannot use both auth-group and " 426 "chap-mutual for target \"%s\"",
|
386 target->t_name); 387 free($2); 388 free($3); 389 free($4); 390 free($5); 391 return (1); 392 } 393 } else { 394 target->t_auth_group = auth_group_new(conf, NULL); 395 if (target->t_auth_group == NULL) { 396 free($2); 397 free($3); 398 free($4); 399 free($5); 400 return (1); 401 } 402 target->t_auth_group->ag_target = target; 403 } 404 ca = auth_new_chap_mutual(target->t_auth_group, 405 $2, $3, $4, $5); 406 free($2); 407 free($3); 408 free($4); 409 free($5); 410 if (ca == NULL) 411 return (1); 412 } 413 ; 414 415target_initiator_name: INITIATOR_NAME STR 416 { 417 const struct auth_name *an; 418 419 if (target->t_auth_group != NULL) { 420 if (target->t_auth_group->ag_name != NULL) {
| 427 target->t_name); 428 free($2); 429 free($3); 430 free($4); 431 free($5); 432 return (1); 433 } 434 } else { 435 target->t_auth_group = auth_group_new(conf, NULL); 436 if (target->t_auth_group == NULL) { 437 free($2); 438 free($3); 439 free($4); 440 free($5); 441 return (1); 442 } 443 target->t_auth_group->ag_target = target; 444 } 445 ca = auth_new_chap_mutual(target->t_auth_group, 446 $2, $3, $4, $5); 447 free($2); 448 free($3); 449 free($4); 450 free($5); 451 if (ca == NULL) 452 return (1); 453 } 454 ; 455 456target_initiator_name: INITIATOR_NAME STR 457 { 458 const struct auth_name *an; 459 460 if (target->t_auth_group != NULL) { 461 if (target->t_auth_group->ag_name != NULL) {
|
421 log_warnx("cannot mix auth-group with "
| 462 log_warnx("cannot use both auth-group and "
|
422 "initiator-name for target \"%s\"", 423 target->t_name); 424 free($2); 425 return (1); 426 } 427 } else { 428 target->t_auth_group = auth_group_new(conf, NULL); 429 if (target->t_auth_group == NULL) { 430 free($2); 431 return (1); 432 } 433 target->t_auth_group->ag_target = target; 434 } 435 an = auth_name_new(target->t_auth_group, $2); 436 free($2); 437 if (an == NULL) 438 return (1); 439 } 440 ; 441 442target_initiator_portal: INITIATOR_PORTAL STR 443 { 444 const struct auth_portal *ap; 445 446 if (target->t_auth_group != NULL) { 447 if (target->t_auth_group->ag_name != NULL) {
| 463 "initiator-name for target \"%s\"", 464 target->t_name); 465 free($2); 466 return (1); 467 } 468 } else { 469 target->t_auth_group = auth_group_new(conf, NULL); 470 if (target->t_auth_group == NULL) { 471 free($2); 472 return (1); 473 } 474 target->t_auth_group->ag_target = target; 475 } 476 an = auth_name_new(target->t_auth_group, $2); 477 free($2); 478 if (an == NULL) 479 return (1); 480 } 481 ; 482 483target_initiator_portal: INITIATOR_PORTAL STR 484 { 485 const struct auth_portal *ap; 486 487 if (target->t_auth_group != NULL) { 488 if (target->t_auth_group->ag_name != NULL) {
|
448 log_warnx("cannot mix auth-group with "
| 489 log_warnx("cannot use both auth-group and "
|
449 "initiator-portal for target \"%s\"", 450 target->t_name); 451 free($2); 452 return (1); 453 } 454 } else { 455 target->t_auth_group = auth_group_new(conf, NULL); 456 if (target->t_auth_group == NULL) { 457 free($2); 458 return (1); 459 } 460 target->t_auth_group->ag_target = target; 461 } 462 ap = auth_portal_new(target->t_auth_group, $2); 463 free($2); 464 if (ap == NULL) 465 return (1); 466 } 467 ; 468 469target_portal_group: PORTAL_GROUP STR 470 { 471 if (target->t_portal_group != NULL) { 472 log_warnx("portal-group for target \"%s\" " 473 "specified more than once", target->t_name); 474 free($2); 475 return (1); 476 } 477 target->t_portal_group = portal_group_find(conf, $2); 478 if (target->t_portal_group == NULL) { 479 log_warnx("unknown portal-group \"%s\" for target " 480 "\"%s\"", $2, target->t_name); 481 free($2); 482 return (1); 483 } 484 free($2); 485 } 486 ; 487 488target_lun: LUN lun_number 489 OPENING_BRACKET lun_entries CLOSING_BRACKET 490 { 491 lun = NULL; 492 } 493 ; 494 495lun_number: NUM 496 { 497 lun = lun_new(target, $1); 498 if (lun == NULL) 499 return (1); 500 } 501 ; 502 503lun_entries: 504 | 505 lun_entries lun_entry 506 ; 507 508lun_entry: 509 lun_backend 510 | 511 lun_blocksize 512 | 513 lun_device_id 514 | 515 lun_option 516 | 517 lun_path 518 | 519 lun_serial 520 | 521 lun_size 522 ; 523 524lun_backend: BACKEND STR 525 { 526 if (lun->l_backend != NULL) { 527 log_warnx("backend for lun %d, target \"%s\" " 528 "specified more than once", 529 lun->l_lun, target->t_name); 530 free($2); 531 return (1); 532 } 533 lun_set_backend(lun, $2); 534 free($2); 535 } 536 ; 537 538lun_blocksize: BLOCKSIZE NUM 539 { 540 if (lun->l_blocksize != 0) { 541 log_warnx("blocksize for lun %d, target \"%s\" " 542 "specified more than once", 543 lun->l_lun, target->t_name); 544 return (1); 545 } 546 lun_set_blocksize(lun, $2); 547 } 548 ; 549 550lun_device_id: DEVICE_ID STR 551 { 552 if (lun->l_device_id != NULL) { 553 log_warnx("device_id for lun %d, target \"%s\" " 554 "specified more than once", 555 lun->l_lun, target->t_name); 556 free($2); 557 return (1); 558 } 559 lun_set_device_id(lun, $2); 560 free($2); 561 } 562 ; 563 564lun_option: OPTION STR STR 565 { 566 struct lun_option *clo; 567 568 clo = lun_option_new(lun, $2, $3); 569 free($2); 570 free($3); 571 if (clo == NULL) 572 return (1); 573 } 574 ; 575 576lun_path: PATH STR 577 { 578 if (lun->l_path != NULL) { 579 log_warnx("path for lun %d, target \"%s\" " 580 "specified more than once", 581 lun->l_lun, target->t_name); 582 free($2); 583 return (1); 584 } 585 lun_set_path(lun, $2); 586 free($2); 587 } 588 ; 589 590lun_serial: SERIAL STR 591 { 592 if (lun->l_serial != NULL) { 593 log_warnx("serial for lun %d, target \"%s\" " 594 "specified more than once", 595 lun->l_lun, target->t_name); 596 free($2); 597 return (1); 598 } 599 lun_set_serial(lun, $2); 600 free($2); 601 } 602 ; 603 604lun_size: SIZE NUM 605 { 606 if (lun->l_size != 0) { 607 log_warnx("size for lun %d, target \"%s\" " 608 "specified more than once", 609 lun->l_lun, target->t_name); 610 return (1); 611 } 612 lun_set_size(lun, $2); 613 } 614 ; 615%% 616 617void 618yyerror(const char *str) 619{ 620 621 log_warnx("error in configuration file at line %d near '%s': %s", 622 lineno, yytext, str); 623} 624 625static void 626check_perms(const char *path) 627{ 628 struct stat sb; 629 int error; 630 631 error = stat(path, &sb); 632 if (error != 0) { 633 log_warn("stat"); 634 return; 635 } 636 if (sb.st_mode & S_IWOTH) { 637 log_warnx("%s is world-writable", path); 638 } else if (sb.st_mode & S_IROTH) { 639 log_warnx("%s is world-readable", path); 640 } else if (sb.st_mode & S_IXOTH) { 641 /* 642 * Ok, this one doesn't matter, but still do it, 643 * just for consistency. 644 */ 645 log_warnx("%s is world-executable", path); 646 } 647 648 /* 649 * XXX: Should we also check for owner != 0? 650 */ 651} 652 653struct conf * 654conf_new_from_file(const char *path) 655{ 656 struct auth_group *ag; 657 struct portal_group *pg; 658 int error; 659 660 log_debugx("obtaining configuration from %s", path); 661 662 conf = conf_new(); 663 664 ag = auth_group_new(conf, "no-authentication"); 665 ag->ag_type = AG_TYPE_NO_AUTHENTICATION; 666 667 /* 668 * Here, the type doesn't really matter, as the group doesn't contain 669 * any entries and thus will always deny access. 670 */ 671 ag = auth_group_new(conf, "no-access"); 672 ag->ag_type = AG_TYPE_CHAP; 673 674 pg = portal_group_new(conf, "default"); 675 portal_group_add_listen(pg, "0.0.0.0:3260", false); 676 portal_group_add_listen(pg, "[::]:3260", false); 677 678 yyin = fopen(path, "r"); 679 if (yyin == NULL) { 680 log_warn("unable to open configuration file %s", path); 681 conf_delete(conf); 682 return (NULL); 683 } 684 check_perms(path); 685 lineno = 1; 686 yyrestart(yyin); 687 error = yyparse(); 688 auth_group = NULL; 689 portal_group = NULL; 690 target = NULL; 691 lun = NULL; 692 fclose(yyin); 693 if (error != 0) { 694 conf_delete(conf); 695 return (NULL); 696 } 697 698 error = conf_verify(conf); 699 if (error != 0) { 700 conf_delete(conf); 701 return (NULL); 702 } 703 704 return (conf); 705}
| 490 "initiator-portal for target \"%s\"", 491 target->t_name); 492 free($2); 493 return (1); 494 } 495 } else { 496 target->t_auth_group = auth_group_new(conf, NULL); 497 if (target->t_auth_group == NULL) { 498 free($2); 499 return (1); 500 } 501 target->t_auth_group->ag_target = target; 502 } 503 ap = auth_portal_new(target->t_auth_group, $2); 504 free($2); 505 if (ap == NULL) 506 return (1); 507 } 508 ; 509 510target_portal_group: PORTAL_GROUP STR 511 { 512 if (target->t_portal_group != NULL) { 513 log_warnx("portal-group for target \"%s\" " 514 "specified more than once", target->t_name); 515 free($2); 516 return (1); 517 } 518 target->t_portal_group = portal_group_find(conf, $2); 519 if (target->t_portal_group == NULL) { 520 log_warnx("unknown portal-group \"%s\" for target " 521 "\"%s\"", $2, target->t_name); 522 free($2); 523 return (1); 524 } 525 free($2); 526 } 527 ; 528 529target_lun: LUN lun_number 530 OPENING_BRACKET lun_entries CLOSING_BRACKET 531 { 532 lun = NULL; 533 } 534 ; 535 536lun_number: NUM 537 { 538 lun = lun_new(target, $1); 539 if (lun == NULL) 540 return (1); 541 } 542 ; 543 544lun_entries: 545 | 546 lun_entries lun_entry 547 ; 548 549lun_entry: 550 lun_backend 551 | 552 lun_blocksize 553 | 554 lun_device_id 555 | 556 lun_option 557 | 558 lun_path 559 | 560 lun_serial 561 | 562 lun_size 563 ; 564 565lun_backend: BACKEND STR 566 { 567 if (lun->l_backend != NULL) { 568 log_warnx("backend for lun %d, target \"%s\" " 569 "specified more than once", 570 lun->l_lun, target->t_name); 571 free($2); 572 return (1); 573 } 574 lun_set_backend(lun, $2); 575 free($2); 576 } 577 ; 578 579lun_blocksize: BLOCKSIZE NUM 580 { 581 if (lun->l_blocksize != 0) { 582 log_warnx("blocksize for lun %d, target \"%s\" " 583 "specified more than once", 584 lun->l_lun, target->t_name); 585 return (1); 586 } 587 lun_set_blocksize(lun, $2); 588 } 589 ; 590 591lun_device_id: DEVICE_ID STR 592 { 593 if (lun->l_device_id != NULL) { 594 log_warnx("device_id for lun %d, target \"%s\" " 595 "specified more than once", 596 lun->l_lun, target->t_name); 597 free($2); 598 return (1); 599 } 600 lun_set_device_id(lun, $2); 601 free($2); 602 } 603 ; 604 605lun_option: OPTION STR STR 606 { 607 struct lun_option *clo; 608 609 clo = lun_option_new(lun, $2, $3); 610 free($2); 611 free($3); 612 if (clo == NULL) 613 return (1); 614 } 615 ; 616 617lun_path: PATH STR 618 { 619 if (lun->l_path != NULL) { 620 log_warnx("path for lun %d, target \"%s\" " 621 "specified more than once", 622 lun->l_lun, target->t_name); 623 free($2); 624 return (1); 625 } 626 lun_set_path(lun, $2); 627 free($2); 628 } 629 ; 630 631lun_serial: SERIAL STR 632 { 633 if (lun->l_serial != NULL) { 634 log_warnx("serial for lun %d, target \"%s\" " 635 "specified more than once", 636 lun->l_lun, target->t_name); 637 free($2); 638 return (1); 639 } 640 lun_set_serial(lun, $2); 641 free($2); 642 } 643 ; 644 645lun_size: SIZE NUM 646 { 647 if (lun->l_size != 0) { 648 log_warnx("size for lun %d, target \"%s\" " 649 "specified more than once", 650 lun->l_lun, target->t_name); 651 return (1); 652 } 653 lun_set_size(lun, $2); 654 } 655 ; 656%% 657 658void 659yyerror(const char *str) 660{ 661 662 log_warnx("error in configuration file at line %d near '%s': %s", 663 lineno, yytext, str); 664} 665 666static void 667check_perms(const char *path) 668{ 669 struct stat sb; 670 int error; 671 672 error = stat(path, &sb); 673 if (error != 0) { 674 log_warn("stat"); 675 return; 676 } 677 if (sb.st_mode & S_IWOTH) { 678 log_warnx("%s is world-writable", path); 679 } else if (sb.st_mode & S_IROTH) { 680 log_warnx("%s is world-readable", path); 681 } else if (sb.st_mode & S_IXOTH) { 682 /* 683 * Ok, this one doesn't matter, but still do it, 684 * just for consistency. 685 */ 686 log_warnx("%s is world-executable", path); 687 } 688 689 /* 690 * XXX: Should we also check for owner != 0? 691 */ 692} 693 694struct conf * 695conf_new_from_file(const char *path) 696{ 697 struct auth_group *ag; 698 struct portal_group *pg; 699 int error; 700 701 log_debugx("obtaining configuration from %s", path); 702 703 conf = conf_new(); 704 705 ag = auth_group_new(conf, "no-authentication"); 706 ag->ag_type = AG_TYPE_NO_AUTHENTICATION; 707 708 /* 709 * Here, the type doesn't really matter, as the group doesn't contain 710 * any entries and thus will always deny access. 711 */ 712 ag = auth_group_new(conf, "no-access"); 713 ag->ag_type = AG_TYPE_CHAP; 714 715 pg = portal_group_new(conf, "default"); 716 portal_group_add_listen(pg, "0.0.0.0:3260", false); 717 portal_group_add_listen(pg, "[::]:3260", false); 718 719 yyin = fopen(path, "r"); 720 if (yyin == NULL) { 721 log_warn("unable to open configuration file %s", path); 722 conf_delete(conf); 723 return (NULL); 724 } 725 check_perms(path); 726 lineno = 1; 727 yyrestart(yyin); 728 error = yyparse(); 729 auth_group = NULL; 730 portal_group = NULL; 731 target = NULL; 732 lun = NULL; 733 fclose(yyin); 734 if (error != 0) { 735 conf_delete(conf); 736 return (NULL); 737 } 738 739 error = conf_verify(conf); 740 if (error != 0) { 741 conf_delete(conf); 742 return (NULL); 743 } 744 745 return (conf); 746}
|