]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - usr.bin/iscsictl/parse.y
Revert r278642
[FreeBSD/FreeBSD.git] / usr.bin / iscsictl / parse.y
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$
31  */
32
33 #include <sys/queue.h>
34 #include <sys/types.h>
35 #include <sys/stat.h>
36 #include <assert.h>
37 #include <err.h>
38 #include <stdio.h>
39 #include <stdint.h>
40 #include <stdlib.h>
41 #include <string.h>
42
43 #include "iscsictl.h"
44
45 extern FILE *yyin;
46 extern char *yytext;
47 extern int lineno;
48
49 static struct conf *conf;
50 static struct target *target;
51
52 extern void     yyerror(const char *);
53 extern int      yylex(void);
54 extern void     yyrestart(FILE *);
55
56 %}
57
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
62
63 %union
64 {
65         char *str;
66 }
67
68 %token <str> STR
69
70 %%
71
72 targets:
73         |
74         targets target
75         ;
76
77 target:         STR OPENING_BRACKET target_entries CLOSING_BRACKET
78         {
79                 if (target_find(conf, $1) != NULL)
80                         errx(1, "duplicated target %s", $1);
81                 target->t_nickname = $1;
82                 target = target_new(conf);
83         }
84         ;
85
86 target_entries:
87         |
88         target_entries target_entry
89         |
90         target_entries target_entry SEMICOLON
91         ;
92
93 target_entry:
94         target_name
95         |
96         target_address
97         |
98         initiator_name
99         |
100         initiator_address
101         |
102         initiator_alias
103         |
104         user
105         |
106         secret
107         |
108         mutual_user
109         |
110         mutual_secret
111         |
112         auth_method
113         |
114         header_digest
115         |
116         data_digest
117         |
118         session_type
119         |
120         offload
121         |
122         protocol
123         |
124         ignored
125         ;
126
127 target_name:    TARGET_NAME EQUALS STR
128         {
129                 if (target->t_name != NULL)
130                         errx(1, "duplicated TargetName at line %d", lineno);
131                 target->t_name = $3;
132         }
133         ;
134
135 target_address: TARGET_ADDRESS EQUALS STR
136         {
137                 if (target->t_address != NULL)
138                         errx(1, "duplicated TargetAddress at line %d", lineno);
139                 target->t_address = $3;
140         }
141         ;
142
143 initiator_name: INITIATOR_NAME EQUALS STR
144         {
145                 if (target->t_initiator_name != NULL)
146                         errx(1, "duplicated InitiatorName at line %d", lineno);
147                 target->t_initiator_name = $3;
148         }
149         ;
150
151 initiator_address:      INITIATOR_ADDRESS EQUALS STR
152         {
153                 if (target->t_initiator_address != NULL)
154                         errx(1, "duplicated InitiatorAddress at line %d", lineno);
155                 target->t_initiator_address = $3;
156         }
157         ;
158
159 initiator_alias:        INITIATOR_ALIAS EQUALS STR
160         {
161                 if (target->t_initiator_alias != NULL)
162                         errx(1, "duplicated InitiatorAlias at line %d", lineno);
163                 target->t_initiator_alias = $3;
164         }
165         ;
166
167 user:           USER EQUALS STR
168         {
169                 if (target->t_user != NULL)
170                         errx(1, "duplicated chapIName at line %d", lineno);
171                 target->t_user = $3;
172         }
173         ;
174
175 secret:         SECRET EQUALS STR
176         {
177                 if (target->t_secret != NULL)
178                         errx(1, "duplicated chapSecret at line %d", lineno);
179                 target->t_secret = $3;
180         }
181         ;
182
183 mutual_user:    MUTUAL_USER EQUALS STR
184         {
185                 if (target->t_mutual_user != NULL)
186                         errx(1, "duplicated tgtChapName at line %d", lineno);
187                 target->t_mutual_user = $3;
188         }
189         ;
190
191 mutual_secret:  MUTUAL_SECRET EQUALS STR
192         {
193                 if (target->t_mutual_secret != NULL)
194                         errx(1, "duplicated tgtChapSecret at line %d", lineno);
195                 target->t_mutual_secret = $3;
196         }
197         ;
198
199 auth_method:    AUTH_METHOD EQUALS STR
200         {
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;
207                 else
208                         errx(1, "invalid AuthMethod at line %d; "
209                             "must be either \"none\" or \"CHAP\"", lineno);
210         }
211         ;
212
213 header_digest:  HEADER_DIGEST EQUALS STR
214         {
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;
221                 else
222                         errx(1, "invalid HeaderDigest at line %d; "
223                             "must be either \"none\" or \"CRC32C\"", lineno);
224         }
225         ;
226
227 data_digest:    DATA_DIGEST EQUALS STR
228         {
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;
235                 else
236                         errx(1, "invalid DataDigest at line %d; "
237                             "must be either \"none\" or \"CRC32C\"", lineno);
238         }
239         ;
240
241 session_type:   SESSION_TYPE EQUALS STR
242         {
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;
249                 else
250                         errx(1, "invalid SessionType at line %d; "
251                             "must be either \"normal\" or \"discovery\"", lineno);
252         }
253         ;
254
255 offload:        OFFLOAD EQUALS STR
256         {
257                 if (target->t_offload != NULL)
258                         errx(1, "duplicated offload at line %d", lineno);
259                 target->t_offload = $3;
260         }
261         ;
262
263 protocol:       PROTOCOL EQUALS STR
264         {
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;
271                 else
272                         errx(1, "invalid protocol at line %d; "
273                             "must be either \"iscsi\" or \"iser\"", lineno);
274         }
275         ;
276
277 ignored:        IGNORED EQUALS STR
278         {
279                 warnx("obsolete statement ignored at line %d", lineno);
280         }
281         ;
282
283 %%
284
285 void
286 yyerror(const char *str)
287 {
288
289         errx(1, "error in configuration file at line %d near '%s': %s",
290             lineno, yytext, str);
291 }
292
293 static void
294 check_perms(const char *path)
295 {
296         struct stat sb;
297         int error;
298
299         error = stat(path, &sb);
300         if (error != 0) {
301                 warn("stat");
302                 return;
303         }
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) {
309                 /*
310                  * Ok, this one doesn't matter, but still do it,
311                  * just for consistency.
312                  */
313                 warnx("%s is world-executable", path);
314         }
315
316         /*
317          * XXX: Should we also check for owner != 0?
318          */
319 }
320
321 struct conf *
322 conf_new_from_file(const char *path)
323 {
324         int error;
325
326         conf = conf_new();
327         target = target_new(conf);
328
329         yyin = fopen(path, "r");
330         if (yyin == NULL)
331                 err(1, "unable to open configuration file %s", path);
332         check_perms(path);
333         lineno = 1;
334         yyrestart(yyin);
335         error = yyparse();
336         assert(error == 0);
337         fclose(yyin);
338
339         assert(target->t_nickname == NULL);
340         target_delete(target);
341
342         conf_verify(conf);
343
344         return (conf);
345 }