Change criteria for expunging items from the user's PATH: instead of
[become] / src / parser.y
CommitLineData
c4f2d992 1/* -*-c-*-
2 *
03f996bd 3 * $Id: parser.y,v 1.2 1997/08/04 10:24:24 mdw Exp $
c4f2d992 4 *
5 * Parser for `become.conf' files
6 *
7 * (c) 1997 EBI
8 */
9
03f996bd 10/*----- Licensing notice --------------------------------------------------*
c4f2d992 11 *
12 * This file is part of `become'
13 *
14 * `Become' is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2 of the License, or
17 * (at your option) any later version.
18 *
19 * `Become' is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
03f996bd 25 * along with `become'; if not, write to the Free Software Foundation,
26 * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
c4f2d992 27 */
28
29/*----- Revision history --------------------------------------------------*
30 *
31 * $Log: parser.y,v $
03f996bd 32 * Revision 1.2 1997/08/04 10:24:24 mdw
33 * Sources placed under CVS control.
34 *
35 * Revision 1.1 1997/07/21 13:47:45 mdw
c4f2d992 36 * Initial revision
37 *
38 */
39
40/*----- Header files ------------------------------------------------------*/
41%{
42
43/* --- ANSI headers --- */
44
45#include <stdio.h>
46#include <stdlib.h>
47#include <string.h>
48
49/* --- Unix headers --- */
50
51#include <sys/types.h>
52
53#include <pwd.h>
54#include <unistd.h>
55
56/* --- Local headers --- */
57
58#include "class.h"
59#include "daemon.h"
60#include "lexer.h"
61#include "name.h"
62#include "rule.h"
63#include "set.h"
64#include "sym.h"
65#include "userdb.h"
66#include "utils.h"
67
68%}
69/*----- Stack type --------------------------------------------------------*/
70
71%union {
72 long i;
73 char *s;
74 name *n;
75 classdef *c;
76}
77
78/*----- Token and rule declarations ---------------------------------------*/
79
80/* --- Tokens --- */
81
82%token BADTOKEN
83%token USER
84%token COMMAND
85%token HOST
86%token ALLOW
87%token PORT
88%token KEYFILE
89%token <i> INT
90%token <s> WORD
91%token <s> STRING
92%token ARROW
93
94%left ','
95%left '-'
96%left '|'
97%left '&'
98
99/* --- Rules --- */
100
101%type <c> user_class command_class host_class
102%type <c> user_class_opt command_class_opt host_class_opt
103%type <n> name
104
105/*----- Error reporting ---------------------------------------------------*/
106%{
107
108#define YYDEBUG 1
109#define YYERROR_VERBOSE
110
111/* --- @yyprint@ --- *
112 *
113 * Arguments: @FILE *fp@ = pointer to stream to write on
114 * @int type@ = pointer to token type
115 * @YYSTYPE v@ = token value
116 *
117 * Returns: ---
118 *
119 * Use: Displays the semantic value of a token.
120 */
121
122#define YYPRINT(fp, type, value) yyprint(fp, type, value)
123
124static void yyprint(FILE *fp, int type, YYSTYPE v)
125{
126 switch (type) {
127 case INT:
128 fprintf(fp, " %li", v.i);
129 break;
130 case WORD:
131 case STRING:
132 fprintf(fp, " `%s'", v.s);
133 break;
134 }
135}
136
137/* --- @yyerror@ --- *
138 *
139 * Arguments: @const char *msg@ = pointer to error message
140 *
141 * Returns: ---
142 *
143 * Use: Reports parse errors.
144 */
145
146static void yyerror(const char *msg)
147{
148 moan("%s at line %i", msg, lex_line);
149}
150
151%}
152%%
153/*----- The actual grammar ------------------------------------------------*/
154
155/* --- Simple driver things --- */
156
157file : /* empty */
158 | file statement
159 ;
160
161statement : user_spec
162 | command_spec
163 | host_spec
164 | allow_spec
165 | port_spec
166 | key_spec
167 | error ';'
168 ;
169
170/* --- Main statement types --- */
171
172user_spec : USER name '=' user_class ';' {
173 if ($2->c)
174 class_dec($2->c);
175 $2->c = $4;
176 }
177 ;
178
179command_spec : COMMAND name '=' command_class ';' {
180 if ($2->c)
181 class_dec($2->c);
182 $2->c = $4;
183 }
184 ;
185
186host_spec : HOST name '=' host_class ';' {
187 if ($2->c)
188 class_dec($2->c);
189 $2->c = $4;
190 }
191 ;
192
193port_spec : PORT INT ';' { daemon_usePort($2); }
194 ;
195
196key_spec : KEYFILE STRING ';' { daemon_readKey($2); }
197
198/* --- Parsing allow specifications --- */
199
200allow_spec : ALLOW host_class_opt user_class ARROW
201 user_class_opt command_class_opt ';' {
202 rule_add($2, $3, $5, $6);
203 }
204
205host_class_opt : /* empty */ { $$ = class_all; }
206 | '[' host_class ']' { $$ = $2; }
207 ;
208
209user_class_opt : /* empty */ { $$ = class_all; }
210 | user_class { $$ = $1; }
211 ;
212
213command_class_opt : /* empty */ { $$ = class_all; }
214 | ':' command_class { $$ = $2; }
215 ;
216
217/* --- Names get translated into symbols quickly --- */
218
219name : WORD {
220 unsigned f;
221 name *n = name_find($1, 1, &f);
222 if (!f)
223 n->c = 0;
224 $$ = n;
225 }
226
227/*----- Various class expression types ------------------------------------*
228 *
229 * Unfortunately, all these need to handle token types slightly differently
230 * and I can't be bothered to remember the current state.
231 */
232
233/* --- User class expressions --- */
234
235user_class : user_class ',' user_class {
236 if ($1->type != $3->type) {
237 yyerror("type mismatch");
238 class_dec($1);
239 class_dec($3);
240 YYERROR;
241 } else {
242 if ($1 == class_all)
243 $$ = class_all;
244 else
245 $$ = class_create($1->type,
246 set_union($1->t, $3->t));
247 class_dec($1);
248 class_dec($3);
249 }
250 }
251 | user_class '-' user_class {
252 if ($1->type != $3->type) {
253 yyerror("type mismatch");
254 class_dec($1);
255 class_dec($3);
256 YYERROR;
257 } else {
258 $$ = class_create($1->type,
259 set_subtract($1->t, $3->t));
260 class_dec($1);
261 class_dec($3);
262 }
263 }
264 | user_class '&' user_class {
265 if ($1->type != $3->type) {
266 yyerror("type mismatch");
267 class_dec($1);
268 class_dec($3);
269 YYERROR;
270 } else {
271 if ($1 == class_all)
272 $$ = class_all;
273 else
274 $$ = class_create($1->type,
275 set_intersect($1->t, $3->t));
276 class_dec($1);
277 class_dec($3);
278 }
279 }
280 | user_class '|' user_class {
281 if ($1->type != $3->type) {
282 yyerror("type mismatch");
283 class_dec($1);
284 class_dec($3);
285 YYERROR;
286 } else {
287 if ($1 == class_all)
288 $$ = class_all;
289 else
290 $$ = class_create($1->type,
291 set_union($1->t, $3->t));
292 class_dec($1);
293 class_dec($3);
294 }
295 }
296 | INT {
297 sym_table *t = xmalloc(sizeof(*t));
298 int u = $1;
299 sym_createTable(t);
300 sym_find(t, (char *)&u, sizeof(u),
301 sizeof(sym_base), 0);
302 $$ = class_create(clType_user, t);
303 }
304 | STRING {
305 struct passwd *pw;
306 sym_table *t;
307 int u;
308 if ((pw = userdb_userByName($1)) == 0) {
309 moan("user `%s' not known at line %i",
310 $1, lex_line);
311 YYERROR;
312 } else {
313 t = xmalloc(sizeof(*t));
314 u = pw->pw_uid;
315 sym_createTable(t);
316 sym_find(t, (char *)&u, sizeof(u),
317 sizeof(sym_base), 0);
318 $$ = class_create(clType_user, t);
319 }
320 }
321 | WORD {
322 name *n = name_find($1, 0, 0);
323 if (!n || !n->c) {
324 moan("class `%s' not found at line %i",
325 $1, lex_line);
326 YYERROR;
327 } else if (~n->c->type & clType_user) {
328 yyerror("type mismatch");
329 YYERROR;
330 } else {
331 $$ = n->c;
332 class_inc(n->c);
333 }
334 }
335 | '(' user_class ')' { $$ = $2; }
336 ;
337
338/* --- Command class expressions --- */
339
340command_class : command_class ',' command_class {
341 if ($1->type != $3->type) {
342 yyerror("type mismatch");
343 class_dec($1);
344 class_dec($3);
345 YYERROR;
346 } else {
347 if ($1 == class_all)
348 $$ = class_all;
349 else
350 $$ = class_create($1->type,
351 set_union($1->t, $3->t));
352 class_dec($1);
353 class_dec($3);
354 }
355 }
356 | command_class '-' command_class {
357 if ($1->type != $3->type) {
358 yyerror("type mismatch");
359 class_dec($1);
360 class_dec($3);
361 YYERROR;
362 } else {
363 $$ = class_create($1->type,
364 set_subtract($1->t, $3->t));
365 class_dec($1);
366 class_dec($3);
367 }
368 }
369 | command_class '&' command_class {
370 if ($1->type != $3->type) {
371 yyerror("type mismatch");
372 class_dec($1);
373 class_dec($3);
374 YYERROR;
375 } else {
376 if ($1 == class_all)
377 $$ = class_all;
378 else
379 $$ = class_create($1->type,
380 set_intersect($1->t, $3->t));
381 class_dec($1);
382 class_dec($3);
383 }
384 }
385 | command_class '|' command_class {
386 if ($1->type != $3->type) {
387 yyerror("type mismatch");
388 class_dec($1);
389 class_dec($3);
390 YYERROR;
391 } else {
392 if ($1 == class_all)
393 $$ = class_all;
394 else
395 $$ = class_create($1->type,
396 set_union($1->t, $3->t));
397 class_dec($1);
398 class_dec($3);
399 }
400 }
401 | STRING {
402 sym_table *t = xmalloc(sizeof(*t));
403 sym_createTable(t);
404 sym_find(t, $1, -1, sizeof(sym_base), 0);
405 $$ = class_create(clType_command, t);
406 }
407 | WORD {
408 name *n = name_find($1, 0, 0);
409 if (!n || !n->c) {
410 moan("class `%s' not found at line %i",
411 $1, lex_line);
412 YYERROR;
413 } else if (~n->c->type & clType_command) {
414 yyerror("type mismatch");
415 YYERROR;
416 } else {
417 $$ = n->c;
418 class_inc(n->c);
419 }
420 }
421 | '(' command_class ')' { $$ = $2; }
422 ;
423
424/* --- Host class expressions --- */
425
426host_class : host_class ',' host_class {
427 if ($1->type != $3->type) {
428 yyerror("type mismatch");
429 class_dec($1);
430 class_dec($3);
431 YYERROR;
432 } else {
433 if ($1 == class_all)
434 $$ = class_all;
435 else
436 $$ = class_create($1->type,
437 set_union($1->t, $3->t));
438 class_dec($1);
439 class_dec($3);
440 }
441 }
442 | host_class '-' host_class {
443 if ($1->type != $3->type) {
444 yyerror("type mismatch");
445 class_dec($1);
446 class_dec($3);
447 YYERROR;
448 } else {
449 $$ = class_create($1->type,
450 set_subtract($1->t, $3->t));
451 class_dec($1);
452 class_dec($3);
453 }
454 }
455 | host_class '&' host_class {
456 if ($1->type != $3->type) {
457 yyerror("type mismatch");
458 class_dec($1);
459 class_dec($3);
460 YYERROR;
461 } else {
462 if ($1 == class_all)
463 $$ = class_all;
464 else
465 $$ = class_create($1->type,
466 set_intersect($1->t, $3->t));
467 class_dec($1);
468 class_dec($3);
469 }
470 }
471 | host_class '|' host_class {
472 if ($1->type != $3->type) {
473 yyerror("type mismatch");
474 class_dec($1);
475 class_dec($3);
476 YYERROR;
477 } else {
478 if ($1 == class_all)
479 $$ = class_all;
480 else
481 $$ = class_create($1->type,
482 set_union($1->t, $3->t));
483 class_dec($1);
484 class_dec($3);
485 }
486 }
487 | STRING {
488 sym_table *t = xmalloc(sizeof(*t));
489 sym_createTable(t);
490 sym_find(t, $1, -1, sizeof(sym_base), 0);
491 $$ = class_create(clType_host, t);
492 }
493 | WORD {
494 name *n = name_find($1, 0, 0);
495 if (!n || !n->c) {
496 moan("class `%s' not found at line %i",
497 $1, lex_line);
498 YYERROR;
499 } else if (~n->c->type & clType_host) {
500 yyerror("type mismatch");
501 YYERROR;
502 } else {
503 $$ = n->c;
504 class_inc(n->c);
505 }
506 }
507 | '(' host_class ')' { $$ = $2; }
508 ;
509
510/*----- That's all, folks -------------------------------------------------*/