3 * Copyright (c) 2012 The FreeBSD Foundation
6 * This software was developed by Edward Tomasz Napierala under sponsorship
7 * from the FreeBSD Foundation.
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
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.
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
33 #include <sys/queue.h>
34 #include <sys/types.h>
49 static struct conf *conf;
50 static struct target *target;
52 extern void yyerror(const char *);
53 extern int yylex(void);
54 extern void yyrestart(FILE *);
58 %token AUTH_METHOD HEADER_DIGEST DATA_DIGEST TARGET_NAME TARGET_ADDRESS
59 %token INITIATOR_NAME INITIATOR_ADDRESS INITIATOR_ALIAS USER SECRET
60 %token MUTUAL_USER MUTUAL_SECRET SEMICOLON SESSION_TYPE PROTOCOL OFFLOAD
61 %token IGNORED EQUALS OPENING_BRACKET CLOSING_BRACKET
77 target: STR OPENING_BRACKET target_entries CLOSING_BRACKET
79 if (target_find(conf, $1) != NULL)
80 errx(1, "duplicated target %s", $1);
81 target->t_nickname = $1;
82 target = target_new(conf);
88 target_entries target_entry
90 target_entries target_entry SEMICOLON
127 target_name: TARGET_NAME EQUALS STR
129 if (target->t_name != NULL)
130 errx(1, "duplicated TargetName at line %d", lineno);
135 target_address: TARGET_ADDRESS EQUALS STR
137 if (target->t_address != NULL)
138 errx(1, "duplicated TargetAddress at line %d", lineno);
139 target->t_address = $3;
143 initiator_name: INITIATOR_NAME EQUALS STR
145 if (target->t_initiator_name != NULL)
146 errx(1, "duplicated InitiatorName at line %d", lineno);
147 target->t_initiator_name = $3;
151 initiator_address: INITIATOR_ADDRESS EQUALS STR
153 if (target->t_initiator_address != NULL)
154 errx(1, "duplicated InitiatorAddress at line %d", lineno);
155 target->t_initiator_address = $3;
159 initiator_alias: INITIATOR_ALIAS EQUALS STR
161 if (target->t_initiator_alias != NULL)
162 errx(1, "duplicated InitiatorAlias at line %d", lineno);
163 target->t_initiator_alias = $3;
167 user: USER EQUALS STR
169 if (target->t_user != NULL)
170 errx(1, "duplicated chapIName at line %d", lineno);
175 secret: SECRET EQUALS STR
177 if (target->t_secret != NULL)
178 errx(1, "duplicated chapSecret at line %d", lineno);
179 target->t_secret = $3;
183 mutual_user: MUTUAL_USER EQUALS STR
185 if (target->t_mutual_user != NULL)
186 errx(1, "duplicated tgtChapName at line %d", lineno);
187 target->t_mutual_user = $3;
191 mutual_secret: MUTUAL_SECRET EQUALS STR
193 if (target->t_mutual_secret != NULL)
194 errx(1, "duplicated tgtChapSecret at line %d", lineno);
195 target->t_mutual_secret = $3;
199 auth_method: AUTH_METHOD EQUALS STR
201 if (target->t_auth_method != AUTH_METHOD_UNSPECIFIED)
202 errx(1, "duplicated AuthMethod at line %d", lineno);
203 if (strcasecmp($3, "none") == 0)
204 target->t_auth_method = AUTH_METHOD_NONE;
205 else if (strcasecmp($3, "chap") == 0)
206 target->t_auth_method = AUTH_METHOD_CHAP;
208 errx(1, "invalid AuthMethod at line %d; "
209 "must be either \"none\" or \"CHAP\"", lineno);
213 header_digest: HEADER_DIGEST EQUALS STR
215 if (target->t_header_digest != DIGEST_UNSPECIFIED)
216 errx(1, "duplicated HeaderDigest at line %d", lineno);
217 if (strcasecmp($3, "none") == 0)
218 target->t_header_digest = DIGEST_NONE;
219 else if (strcasecmp($3, "CRC32C") == 0)
220 target->t_header_digest = DIGEST_CRC32C;
222 errx(1, "invalid HeaderDigest at line %d; "
223 "must be either \"none\" or \"CRC32C\"", lineno);
227 data_digest: DATA_DIGEST EQUALS STR
229 if (target->t_data_digest != DIGEST_UNSPECIFIED)
230 errx(1, "duplicated DataDigest at line %d", lineno);
231 if (strcasecmp($3, "none") == 0)
232 target->t_data_digest = DIGEST_NONE;
233 else if (strcasecmp($3, "CRC32C") == 0)
234 target->t_data_digest = DIGEST_CRC32C;
236 errx(1, "invalid DataDigest at line %d; "
237 "must be either \"none\" or \"CRC32C\"", lineno);
241 session_type: SESSION_TYPE EQUALS STR
243 if (target->t_session_type != SESSION_TYPE_UNSPECIFIED)
244 errx(1, "duplicated SessionType at line %d", lineno);
245 if (strcasecmp($3, "normal") == 0)
246 target->t_session_type = SESSION_TYPE_NORMAL;
247 else if (strcasecmp($3, "discovery") == 0)
248 target->t_session_type = SESSION_TYPE_DISCOVERY;
250 errx(1, "invalid SessionType at line %d; "
251 "must be either \"normal\" or \"discovery\"", lineno);
255 offload: OFFLOAD EQUALS STR
257 if (target->t_offload != NULL)
258 errx(1, "duplicated offload at line %d", lineno);
259 target->t_offload = $3;
263 protocol: PROTOCOL EQUALS STR
265 if (target->t_protocol != PROTOCOL_UNSPECIFIED)
266 errx(1, "duplicated protocol at line %d", lineno);
267 if (strcasecmp($3, "iscsi") == 0)
268 target->t_protocol = PROTOCOL_ISCSI;
269 else if (strcasecmp($3, "iser") == 0)
270 target->t_protocol = PROTOCOL_ISER;
272 errx(1, "invalid protocol at line %d; "
273 "must be either \"iscsi\" or \"iser\"", lineno);
277 ignored: IGNORED EQUALS STR
279 warnx("obsolete statement ignored at line %d", lineno);
286 yyerror(const char *str)
289 errx(1, "error in configuration file at line %d near '%s': %s",
290 lineno, yytext, str);
294 check_perms(const char *path)
299 error = stat(path, &sb);
304 if (sb.st_mode & S_IWOTH) {
305 warnx("%s is world-writable", path);
306 } else if (sb.st_mode & S_IROTH) {
307 warnx("%s is world-readable", path);
308 } else if (sb.st_mode & S_IXOTH) {
310 * Ok, this one doesn't matter, but still do it,
311 * just for consistency.
313 warnx("%s is world-executable", path);
317 * XXX: Should we also check for owner != 0?
322 conf_new_from_file(const char *path)
327 target = target_new(conf);
329 yyin = fopen(path, "r");
331 err(1, "unable to open configuration file %s", path);
339 assert(target->t_nickname == NULL);
340 target_delete(target);