1 |
#include "pdl.h" |
2 |
|
3 |
/* Lex/Yacc stuff */ |
4 |
extern FILE * yyin; |
5 |
extern unsigned int lineno; |
6 |
extern int yyparse(void); |
7 |
extern int yylex(void); |
8 |
|
9 |
/* Lex/Yacc cleanup functions */ |
10 |
extern void delete_lex_buffer(void); |
11 |
#if HAVE_YYLEX_DESTROY |
12 |
extern int yylex_destroy(void); |
13 |
#endif |
14 |
|
15 |
/* internal data */ |
16 |
static const char* config_file_s; |
17 |
FILE* config_file_fp; |
18 |
static char* _pdl_path; |
19 |
|
20 |
var_t* variables_list; |
21 |
var_t* variables_list_last; |
22 |
var_t* current_variable; |
23 |
|
24 |
rule_t* rules_list; |
25 |
rule_t* rules_list_last; |
26 |
rule_t* current_rule; |
27 |
|
28 |
policy_t* policies_list; |
29 |
policy_t* policies_list_last; |
30 |
policy_t* current_policy; |
31 |
|
32 |
/*! initializes the parsing of the configuration file */ |
33 |
EES_RC pdl_init(const char* config_file_name){ |
34 |
config_file_s = config_file_name; |
35 |
|
36 |
if((config_file_fp = fopen(config_file_s,"r")) != NULL){ |
37 |
yyin = config_file_fp; |
38 |
yyparse(); |
39 |
if(add_prepared_plugins() == EES_SUCCESS){ |
40 |
return EES_SUCCESS; |
41 |
} else { |
42 |
eef_log(LOG_ERR, "Failed to load plug-ins from policy config file %s\n", config_file_s); |
43 |
} |
44 |
} else { |
45 |
eef_log(LOG_ERR, "Failed to open policy config file %s", config_file_s); |
46 |
} |
47 |
return EES_FAILURE; |
48 |
} |
49 |
|
50 |
policy_t* get_policies(){ |
51 |
return policies_list; |
52 |
} |
53 |
|
54 |
/*! sets the path to modules directory */ |
55 |
void set_pdl_path(record_t* path){ |
56 |
size_t path_size = 0; |
57 |
size_t string_size = (sizeof(char) * (strlen(path->string)+2)); /* size of string + extra slash + null byte */ |
58 |
_pdl_path = ""; |
59 |
|
60 |
/*struct stat sb;*/ |
61 |
/*if stat(MODUL*/ |
62 |
|
63 |
if(string_size < FILENAME_MAX){ |
64 |
path_size = string_size; |
65 |
} else { |
66 |
path_size = FILENAME_MAX; |
67 |
} |
68 |
|
69 |
if((_pdl_path = calloc(1, path_size))){ |
70 |
strncpy(_pdl_path, path->string, path_size); |
71 |
strncat(_pdl_path, "/", 1); |
72 |
} |
73 |
|
74 |
eef_log(LOG_DEBUG, "Found a new modules path: %s\n", _pdl_path); |
75 |
|
76 |
free(path->string); |
77 |
path->string = NULL; |
78 |
free(path); |
79 |
path = NULL; |
80 |
} |
81 |
|
82 |
/*! Handles a variable representing a plug-in; creates a structure containing its values and adds it to the list of var_t structs variables_list */ |
83 |
void add_variable(record_t* name, record_t* value){ |
84 |
eef_log(LOG_DEBUG, "Added variable name: %s\n", name->string); |
85 |
eef_log(LOG_DEBUG, "Added variable value: %s\n", value->string); |
86 |
|
87 |
/* allocate struct and populate fields */ |
88 |
if((current_variable = calloc(1,sizeof(var_t)))){ |
89 |
current_variable->name = strdup(name->string); |
90 |
current_variable->value = strdup(value->string); |
91 |
current_variable->lineno = name->lineno; |
92 |
current_variable->next = NULL; |
93 |
} else { |
94 |
eef_log(LOG_ERR, "Out of memory!"); |
95 |
} |
96 |
|
97 |
/* append to the end of the list */ |
98 |
if(variables_list){ |
99 |
variables_list_last->next = current_variable; |
100 |
} else { |
101 |
variables_list = current_variable; |
102 |
} |
103 |
variables_list_last = current_variable; |
104 |
|
105 |
/* clean up */ |
106 |
free(name->string); |
107 |
name->string = NULL; |
108 |
free(name); |
109 |
name = NULL; |
110 |
free(value->string); |
111 |
value->string = NULL; |
112 |
free(value); |
113 |
value = NULL; |
114 |
} |
115 |
|
116 |
/* TODO I think this function is a bit of a kludge and could probably be rewritten to be more efficient and more legible - I think it might do too much, so extracting some functions might help */ |
117 |
/*! Appends a rule to the global rules_list, which is to be added to a policy when add_policy is called |
118 |
Will return an error when: |
119 |
- adding the rule to the list will create a recursion in the tree of rules |
120 |
- an unknown variable is referenced |
121 |
*/ |
122 |
rule_t* add_rule(record_t* state, record_t* true_branch, record_t* false_branch){ |
123 |
rule_t *new_rule = NULL, *new_false_branch = NULL, *new_true_branch = NULL, *recursive_rule = NULL; |
124 |
var_t *temp_var = NULL; |
125 |
char *unknown_var_format_string = "Unknown variable %s at line %i in config file %s"; |
126 |
|
127 |
if((new_rule = get_rule(rules_list, state->string))){ |
128 |
eef_log(LOG_WARNING, "State %s at line %i is already in use at line %i.\n", state->string, state->lineno, new_rule->lineno); |
129 |
} else { |
130 |
/*find variables for rule */ |
131 |
temp_var = get_variable_by_name(state->string); |
132 |
if(temp_var == NULL){ |
133 |
/* Errorous state - variable referenced in rule not previously defined */ |
134 |
eef_log(LOG_ERR, unknown_var_format_string, state->string, state->lineno, config_file_s); |
135 |
} |
136 |
if(temp_var != NULL){ |
137 |
if((new_rule = calloc(1, sizeof(rule_t)))){ |
138 |
/* populate fields of current state */ |
139 |
new_rule->state = strdup(state->string); |
140 |
new_rule->lineno = state->lineno; |
141 |
|
142 |
/* populate fields of branches */ |
143 |
if(false_branch){ |
144 |
temp_var = get_variable_by_name(false_branch->string); |
145 |
if(temp_var == NULL){ |
146 |
/* Errorous state - variable referenced in rule not previously defined */ |
147 |
eef_log(LOG_ERR, unknown_var_format_string, false_branch->string, false_branch->lineno, config_file_s); |
148 |
return NULL; |
149 |
} |
150 |
if((new_false_branch = calloc(1, sizeof(rule_t)))){ |
151 |
new_false_branch->state = strdup(false_branch->string); |
152 |
new_false_branch->lineno = false_branch->lineno; |
153 |
new_rule->false_branch = new_false_branch; |
154 |
} |
155 |
} |
156 |
|
157 |
if(true_branch){ |
158 |
temp_var = get_variable_by_name(true_branch->string); |
159 |
if(temp_var == NULL){ |
160 |
/* Errorous state - variable referenced in rule not previously defined */ |
161 |
eef_log(LOG_ERR, unknown_var_format_string, true_branch->string, true_branch->lineno, config_file_s); |
162 |
return NULL; |
163 |
} |
164 |
if((new_true_branch = calloc(1, sizeof(rule_t)))){ |
165 |
new_true_branch->state = strdup(true_branch->string); |
166 |
new_true_branch->lineno = true_branch->lineno; |
167 |
new_rule->true_branch = new_true_branch; |
168 |
} |
169 |
} |
170 |
|
171 |
/* check for recursion */ |
172 |
if((recursive_rule = check_for_recursion(rules_list, new_rule))){ |
173 |
eef_log(LOG_WARNING, "Rule %s at line %i leads to recursion into state %s", new_rule->state, new_rule->lineno, recursive_rule->state); |
174 |
new_rule = NULL; |
175 |
} else { |
176 |
/* add new rule at the end of the rules list */ |
177 |
if(rules_list){ |
178 |
rules_list_last->next = new_rule; |
179 |
} else { |
180 |
rules_list = new_rule; |
181 |
} |
182 |
rules_list_last = new_rule; |
183 |
|
184 |
eef_log(LOG_DEBUG, "Added a new rule: %s\n", new_rule->state); |
185 |
} |
186 |
|
187 |
} else { |
188 |
eef_log(LOG_ERR, "Out of memory!"); |
189 |
} |
190 |
} |
191 |
} |
192 |
|
193 |
/* clean up */ |
194 |
if(state != NULL){ |
195 |
free(state->string); |
196 |
free(state); |
197 |
} |
198 |
if(true_branch != NULL){ |
199 |
free(true_branch->string); |
200 |
free(true_branch); |
201 |
} |
202 |
if(false_branch != NULL){ |
203 |
free(false_branch->string); |
204 |
free(false_branch); |
205 |
} |
206 |
|
207 |
return new_rule; |
208 |
} |
209 |
|
210 |
/* Tries to find a recursion in the list of rules by iterating through all the tree branches. When the same rule is encountered in the current list a recursion has been found */ |
211 |
rule_t* check_for_recursion(rule_t* rule_l, rule_t* rule_r){ |
212 |
rule_t* temp_rule = rule_l; |
213 |
|
214 |
/* right hand rule leads to its own recursive state */ |
215 |
/* still need to find a way to reuse the code from the while loop to do this check */ |
216 |
if(rule_r){ |
217 |
if(rule_r->true_branch){ |
218 |
if(strcmp(rule_r->state, rule_r->true_branch->state) == 0){ |
219 |
return rule_r->true_branch; |
220 |
} |
221 |
} |
222 |
|
223 |
if(rule_r->false_branch){ |
224 |
if(strcmp(rule_r->state, rule_r->false_branch->state) == 0){ |
225 |
return rule_r->false_branch; |
226 |
} |
227 |
} |
228 |
} |
229 |
|
230 |
/* iterate list of rules */ |
231 |
while(temp_rule){ |
232 |
if((temp_rule != NULL) && (rule_r != NULL)){ |
233 |
/* left hand and right hand state are equal */ |
234 |
if(strcmp(temp_rule->state, rule_r->state) == 0){ |
235 |
return rule_r; |
236 |
} |
237 |
|
238 |
/* start state and true branch of right hand rule are equal */ |
239 |
if(rule_r->true_branch){ |
240 |
if(strcmp(temp_rule->state, rule_r->true_branch->state) == 0){ |
241 |
return rule_r->true_branch; |
242 |
} |
243 |
} |
244 |
|
245 |
/* start state and false branch of right hand side are equal */ |
246 |
if(rule_r->false_branch){ |
247 |
if(strcmp(temp_rule->state, rule_r->false_branch->state) == 0){ |
248 |
return rule_r->false_branch; |
249 |
} |
250 |
} |
251 |
} |
252 |
|
253 |
/* move to next rule */ |
254 |
temp_rule = temp_rule->next; |
255 |
} |
256 |
return NULL; |
257 |
} |
258 |
|
259 |
void link_dead_end_rules_in_policy(policy_t* policy){ |
260 |
policy_t* temp_policy = policy; |
261 |
while(temp_policy){ |
262 |
link_dead_end_rules(temp_policy, temp_policy->rules); |
263 |
temp_policy = temp_policy->next; |
264 |
} |
265 |
} |
266 |
|
267 |
void link_dead_end_rules(policy_t* policy, rule_t* rule){ |
268 |
rule_t *temp_rule = rule, *true_rule, *false_rule; |
269 |
while(temp_rule){ |
270 |
if(temp_rule->true_branch){ |
271 |
if((true_rule = get_rule(policy->rules, temp_rule->true_branch->state))){ |
272 |
eef_log(LOG_DEBUG, "Overwriting rule %s with %s\n", temp_rule->true_branch->state, true_rule->state); |
273 |
clean_rules_list(temp_rule->true_branch); |
274 |
temp_rule->true_branch = true_rule; |
275 |
} |
276 |
} |
277 |
if(temp_rule->false_branch){ |
278 |
if((false_rule = get_rule(policy->rules, temp_rule->false_branch->state))){ |
279 |
eef_log(LOG_DEBUG, "Overwriting rule %s with %s\n", temp_rule->false_branch->state, false_rule->state); |
280 |
clean_rules_list(temp_rule->false_branch); |
281 |
temp_rule->false_branch = false_rule; |
282 |
} |
283 |
} |
284 |
temp_rule = temp_rule->next; |
285 |
} |
286 |
} |
287 |
|
288 |
/*! Tries to find specified state in the rules_list */ |
289 |
rule_t* get_rule(rule_t* temp_rule, const char* name){ |
290 |
if(!temp_rule || !name){ |
291 |
return NULL; |
292 |
} |
293 |
|
294 |
/* iterate while the rule isn't associated with the given state */ |
295 |
while(temp_rule){ |
296 |
if(!strcmp(name, temp_rule->state)){ |
297 |
return temp_rule; |
298 |
} |
299 |
temp_rule = temp_rule->next; |
300 |
} |
301 |
return NULL; |
302 |
} |
303 |
|
304 |
/*! Adds a new policy_t structure to the policies_list which will hold the current rules_list. rules_list is nulled after creating a policy so a new list can be created for the next policy */ |
305 |
void add_policy(record_t* policy, rule_t* top_rule){ |
306 |
policy_t* new_policy = NULL; |
307 |
/*eef_log(LOG_DEBUG, "Found a new policy: %s\n", policy->string);*/ |
308 |
|
309 |
if((new_policy = calloc(1, sizeof(policy_t)))){ |
310 |
new_policy->name = strdup(policy->string); |
311 |
new_policy->lineno = policy->lineno; |
312 |
new_policy->rules = top_rule; |
313 |
new_policy->next = NULL; |
314 |
} |
315 |
|
316 |
/* append to the end of the list */ |
317 |
if(policies_list){ |
318 |
policies_list_last->next = new_policy; |
319 |
} else { |
320 |
policies_list = new_policy; |
321 |
} |
322 |
policies_list_last = new_policy; |
323 |
|
324 |
/* start a new rules list */ |
325 |
rules_list = NULL; |
326 |
|
327 |
free(policy->string); |
328 |
policy->string = NULL; |
329 |
free(policy); |
330 |
policy = NULL; |
331 |
} |
332 |
|
333 |
/* prints the list of policies */ |
334 |
void print_policies(policy_t* policies){ |
335 |
policy_t* temp_policy = policies; |
336 |
while(temp_policy){ |
337 |
eef_log(LOG_DEBUG, "Policy: %s\n", temp_policy->name); |
338 |
print_rules(temp_policy, temp_policy->rules); |
339 |
temp_policy = temp_policy->next; |
340 |
} |
341 |
return; |
342 |
} |
343 |
|
344 |
|
345 |
/* prints the list of rules */ |
346 |
void print_rules(policy_t* policy, rule_t* rule){ |
347 |
if(rule){ |
348 |
eef_log(LOG_DEBUG, " | Rule %s\n", rule->state); |
349 |
eef_log(LOG_DEBUG, " -------------------------\n"); |
350 |
if(rule->true_branch){ |
351 |
print_rules(policy, get_rule(policy->rules, rule->true_branch->state)); |
352 |
} |
353 |
if(rule->false_branch){ |
354 |
print_rules(policy, get_rule(policy->rules, rule->false_branch->state)); |
355 |
} |
356 |
} |
357 |
return; |
358 |
} |
359 |
|
360 |
/* tries to link all policy rules to a plugin in the plugin manager */ |
361 |
EES_RC link_rules_to_plugins(policy_t* policies){ |
362 |
policy_t *temp_policy = policies; |
363 |
|
364 |
while(temp_policy){ |
365 |
link_rule_to_plugin(temp_policy, temp_policy->rules); |
366 |
temp_policy = temp_policy->next; |
367 |
} |
368 |
return EES_SUCCESS; |
369 |
} |
370 |
|
371 |
void link_rule_to_plugin(policy_t *policy, rule_t *rule){ |
372 |
var_t *temp_var = NULL; |
373 |
char** argv; |
374 |
int argc; |
375 |
|
376 |
eef_plugindl_t *temp_plugin = NULL; |
377 |
if(rule){ |
378 |
eef_log(LOG_DEBUG, "Got rule: %s\n", rule->state); |
379 |
if(!rule->plugin){ |
380 |
temp_var = get_variable_by_name(rule->state); |
381 |
if(temp_var){ |
382 |
argv = _var_to_argv(temp_var->value, &argc); |
383 |
eef_log(LOG_DEBUG, "Trying to find plugin: %s\n", argv[0]); |
384 |
|
385 |
temp_plugin = get_plugin(argv[0]); |
386 |
if(temp_plugin){ |
387 |
rule->plugin = temp_plugin; |
388 |
} else { |
389 |
eef_log(LOG_DEBUG, "Unknown plugin in variable %s\n", temp_var->value); |
390 |
} |
391 |
free_args(argc, argv); |
392 |
} |
393 |
} else { |
394 |
eef_log(LOG_DEBUG, "Plugin already linked?\n"); |
395 |
} |
396 |
link_rule_to_plugin(policy, rule->true_branch); |
397 |
link_rule_to_plugin(policy, rule->false_branch); |
398 |
} |
399 |
return; |
400 |
} |
401 |
|
402 |
/* iterates the policies and removes those that are not explicitly named in the passed array of strings */ |
403 |
policy_t** reduce_policy_tree(policy_t** policies, int number_of_policies, char* names_of_policies[]){ |
404 |
int i, policy_should_be_removed; |
405 |
policy_t *temp_policy = NULL, *previous_policy = NULL; |
406 |
|
407 |
for(temp_policy = *policies; temp_policy != NULL; previous_policy = temp_policy, temp_policy = temp_policy->next){ |
408 |
policy_should_be_removed = 1; |
409 |
eef_log(LOG_DEBUG, "Checking policy: %s\n", (temp_policy)->name); |
410 |
for(i = 0; i < number_of_policies; i++){ |
411 |
if(strcmp(temp_policy->name, names_of_policies[i]) == 0){ |
412 |
/* if the policy is in the named list, we can continue to the next plugin */ |
413 |
eef_log(LOG_DEBUG, "Allowed policy: %s\n", names_of_policies[i]); |
414 |
policy_should_be_removed = 0; |
415 |
break; |
416 |
} |
417 |
} |
418 |
|
419 |
if(policy_should_be_removed){ |
420 |
eef_log(LOG_DEBUG, "Removing not-allowed policy: %s\n", temp_policy->name); |
421 |
|
422 |
/* if the head node is deleted, overwrite it with the next node */ |
423 |
if(previous_policy == NULL){ |
424 |
*policies = temp_policy->next; |
425 |
} else { |
426 |
previous_policy->next = temp_policy->next; |
427 |
} |
428 |
|
429 |
/* Clean policy fields */ |
430 |
eef_log(LOG_DEBUG, "Deleted policy: %s\n", temp_policy->name); |
431 |
temp_policy->rules = clean_rules_list(temp_policy->rules); |
432 |
free(temp_policy->name); |
433 |
free(temp_policy); |
434 |
} |
435 |
} |
436 |
|
437 |
return policies; |
438 |
} |
439 |
|
440 |
/*! concatenates two strings */ |
441 |
record_t* concat_strings(record_t* r1, record_t* r2){ |
442 |
record_t* new_record; |
443 |
/*eef_log(LOG_DEBUG, "Concating: %s with %s\n", r1->string, r2->string);*/ |
444 |
if((new_record = malloc(sizeof(record_t)))){ |
445 |
if((new_record->string = |
446 |
calloc(1, sizeof(char)*(strlen(r1->string) + strlen(r2->string)+1)))){ |
447 |
strncat(new_record->string, r1->string, strlen(r1->string)); |
448 |
strncat(new_record->string, r2->string, strlen(r2->string)); |
449 |
free(r1->string); |
450 |
free(r1); |
451 |
free(r2->string); |
452 |
free(r2); |
453 |
return new_record; |
454 |
} |
455 |
} |
456 |
return NULL; |
457 |
} |
458 |
|
459 |
/*! concatenates two strings with a space in between */ |
460 |
record_t* concat_strings_with_space(record_t *r1, record_t* r2){ |
461 |
record_t *r; |
462 |
/*eef_log(LOG_DEBUG, "Concating: %s with %s with spaces\n", r1->string, r2->string);*/ |
463 |
if((r = malloc(sizeof(record_t)))){ |
464 |
r->string = calloc(1,(sizeof(char)*(strlen(r1->string)+strlen(r2->string)+2))); |
465 |
strncat(r->string, r1->string, strlen(r1->string)); |
466 |
strncat(r->string, " ", 1); |
467 |
strncat(r->string, r2->string, strlen(r2->string)); |
468 |
free(r1->string); |
469 |
free(r1); |
470 |
free(r2->string); |
471 |
free(r2); |
472 |
return r; |
473 |
} |
474 |
return NULL; |
475 |
} |
476 |
|
477 |
/*! logs errors encountered during parsing */ |
478 |
int yyerror(char* string){ |
479 |
eef_log(LOG_ERR, "Parse error: %s at line %i in config file %s", string, lineno, config_file_s); |
480 |
return 0; |
481 |
} |
482 |
|
483 |
/*! get variable from list */ |
484 |
var_t* get_variable_by_name(char* name){ |
485 |
for(current_variable = variables_list; current_variable != NULL; current_variable = current_variable->next){ |
486 |
if(!strncmp(name, current_variable->name, strlen(current_variable->name))){ |
487 |
return current_variable; |
488 |
} |
489 |
} |
490 |
return NULL; |
491 |
} |
492 |
|
493 |
/*! Removes a policy from the list of policies */ |
494 |
void remove_policy(record_t* policy){ |
495 |
policy_t *temp_policy = policies_list, *next_policy = NULL; |
496 |
eef_log(LOG_DEBUG, "Deleted policy: %s\n", policy->string); |
497 |
|
498 |
while(temp_policy){ |
499 |
if(strcmp(temp_policy->name, policy->string) == 0){ |
500 |
/* target policy was found */ |
501 |
next_policy = temp_policy->next; |
502 |
|
503 |
/* Clean policy fields */ |
504 |
temp_policy->rules = clean_rules_list(temp_policy->rules); |
505 |
free(temp_policy->name); |
506 |
temp_policy->name = NULL; |
507 |
free(temp_policy); |
508 |
temp_policy = NULL; |
509 |
} |
510 |
|
511 |
/* Move to next policy */ |
512 |
temp_policy = next_policy; |
513 |
} |
514 |
|
515 |
free(policy->string); |
516 |
free(policy); |
517 |
return; |
518 |
} |
519 |
|
520 |
/*! Removes a policy from the list of policies */ |
521 |
policy_t* remove_policy_by_name(policy_t* policies, char* policy){ |
522 |
policy_t *temp_policy = policies, *next_policy = NULL; |
523 |
|
524 |
while(temp_policy){ |
525 |
printf("Iterating to %s\n", temp_policy->name); |
526 |
next_policy = temp_policy->next; |
527 |
|
528 |
if(strcmp(temp_policy->name, policy) == 0){ |
529 |
/* target policy was found */ |
530 |
|
531 |
/* if the head node is deleted, overwrite it with the next node */ |
532 |
if(temp_policy == policies){ |
533 |
policies = next_policy; |
534 |
} |
535 |
|
536 |
/* Clean policy fields */ |
537 |
temp_policy->rules = clean_rules_list(temp_policy->rules); |
538 |
eef_log(LOG_DEBUG, "Deleted policy: %s\n", policy); |
539 |
free(temp_policy->name); |
540 |
free(temp_policy); |
541 |
/*break;*/ |
542 |
} |
543 |
|
544 |
/* Move to next policy */ |
545 |
temp_policy = next_policy; |
546 |
} |
547 |
|
548 |
printf("Done removing %s, here is the list\n", policy); |
549 |
print_policies(policies); |
550 |
free(policy); |
551 |
return policies; |
552 |
} |
553 |
|
554 |
/*! converts a string to an array of strings by splitting it at each \t delimiter |
555 |
- overwrites the second argument with a pointer to the number of elements in the array */ |
556 |
char** _var_to_argv(char* value, int *argc){ |
557 |
char *start_of_arg = NULL, *copy_of_value = NULL, **argv = NULL; |
558 |
char *delimiters = " \t"; |
559 |
size_t size_of_arg = 0, size_of_array, i = 0; |
560 |
char *str_ptr; |
561 |
copy_of_value = strdup(value); |
562 |
size_of_array = (sizeof(char)*(strlen(copy_of_value)+1)); |
563 |
if((argv = calloc(1, size_of_array)) != NULL){ |
564 |
start_of_arg = strtok_r(copy_of_value, delimiters, &str_ptr); |
565 |
while(start_of_arg != NULL){ |
566 |
size_of_arg = (sizeof(char)*(strlen(start_of_arg)+1)); |
567 |
if((argv[i] = calloc(1, size_of_arg))){ |
568 |
memcpy(argv[i], start_of_arg, size_of_arg); |
569 |
start_of_arg = strtok_r(NULL, delimiters, &str_ptr); |
570 |
i++; |
571 |
} |
572 |
} |
573 |
} |
574 |
free(copy_of_value); |
575 |
copy_of_value = NULL; |
576 |
if(i < ARG_MAX){ |
577 |
*argc = i; |
578 |
} else { |
579 |
*argc = ARG_MAX; |
580 |
} |
581 |
return argv; |
582 |
} |
583 |
|
584 |
/*! returns pdl path found in parsed config file */ |
585 |
const char* get_pdl_path(){ |
586 |
return _pdl_path; |
587 |
} |
588 |
|
589 |
/*! Iterates list of policies and the rules they contain and tries to let the plugin manager prepare plugin structs*/ |
590 |
EES_RC add_prepared_plugins(){ |
591 |
char** argv; |
592 |
int argc; |
593 |
EES_RC plugin_initialized_ok = EES_SUCCESS; |
594 |
var_t *temp_var = variables_list; |
595 |
|
596 |
while((temp_var != NULL) && (plugin_initialized_ok == EES_SUCCESS)){ |
597 |
argv = _var_to_argv(temp_var->value, &argc); |
598 |
|
599 |
/* this is a callout to the plug-in manager, which adds a struct describing a single plug-in to its list */ |
600 |
plugin_initialized_ok = add_prepared_plugin(argc, argv); |
601 |
|
602 |
/* Move to next variable */ |
603 |
temp_var = temp_var->next; |
604 |
} |
605 |
|
606 |
return plugin_initialized_ok; |
607 |
} |
608 |
|
609 |
/*! Iterates the list of var_t structures and tries to free them */ |
610 |
EES_RC clean_variables_list(){ |
611 |
current_variable = variables_list; |
612 |
while(current_variable){ |
613 |
free(current_variable->name); |
614 |
current_variable->name = NULL; |
615 |
free(current_variable->value); |
616 |
current_variable->value = NULL; |
617 |
|
618 |
/* Move to next variable */ |
619 |
variables_list_last = current_variable; |
620 |
current_variable = current_variable->next; |
621 |
|
622 |
/* Clean last variable struct */ |
623 |
free(variables_list_last); |
624 |
variables_list_last = NULL; |
625 |
} |
626 |
return EES_SUCCESS; |
627 |
} |
628 |
|
629 |
/*! Iterates the list of rule_t structures starting with the passed rule and tries to free them and their true/false branches */ |
630 |
rule_t* clean_rules_list(rule_t* top_rule){ |
631 |
rule_t* temp_rule = top_rule; |
632 |
if(temp_rule){ |
633 |
free(temp_rule->state); |
634 |
|
635 |
clean_rules_list(temp_rule->true_branch); |
636 |
|
637 |
clean_rules_list(temp_rule->false_branch); |
638 |
|
639 |
free(temp_rule); |
640 |
temp_rule = NULL; |
641 |
} |
642 |
return top_rule; |
643 |
} |
644 |
|
645 |
void free_args(int argc, char** argv){ |
646 |
for(; argc > 0; argc--){ |
647 |
free(argv[argc-1]); |
648 |
argv[argc-1] = NULL; |
649 |
} |
650 |
free(argv); |
651 |
argv = NULL; |
652 |
} |
653 |
|
654 |
/*! Iterates the list of policy_t structures and tries to free them and their rules */ |
655 |
EES_RC clean_policies_list(policy_t* policies){ |
656 |
policy_t *temp_policy = policies, *last_policy = NULL; |
657 |
while(temp_policy){ |
658 |
/* Clean policy fields */ |
659 |
temp_policy->rules = clean_rules_list(temp_policy->rules); |
660 |
free(temp_policy->name); |
661 |
temp_policy->name = NULL; |
662 |
|
663 |
/* Move to next policy */ |
664 |
last_policy = temp_policy; |
665 |
temp_policy = temp_policy->next; |
666 |
free(last_policy); |
667 |
last_policy = NULL; |
668 |
} |
669 |
return EES_SUCCESS; |
670 |
} |
671 |
|
672 |
/*! Terminates the parser and tries to free all used memory */ |
673 |
EES_RC pdl_term(policy_t* policies){ |
674 |
clean_variables_list(); |
675 |
clean_policies_list(policies); |
676 |
free(_pdl_path); |
677 |
_pdl_path = NULL; |
678 |
|
679 |
if(config_file_fp != NULL){ |
680 |
/* This is the preferred way of cleaning up various flex versions - See: http://flex.sourceforge.net/manual/Memory-leak-_002d-16386-bytes-allocated-by-malloc_002e.html#Memory-leak-_002d-16386-bytes-allocated-by-malloc_002e */ |
681 |
#if HAVE_YYLEX_DESTROY /* macro set by configure script */ |
682 |
yylex_destroy(); |
683 |
#else |
684 |
/*eef_log(LOG_WARNING, "Lex function yylex_destroy() not available - possibly unable to free allocated memory for evaluation manager\n");*/ |
685 |
#if HAVE_FLEX |
686 |
delete_lex_buffer(); /* this function is defined in pdl_lex.l */ |
687 |
/*eef_log(LOG_INFO, "Managed to free allocated memory for evaluation manager\n"); */ |
688 |
#else |
689 |
eef_log(LOG_WARNING, "Lex functions yylex_destroy() and yy_delete_buffer() are both not available - unable to free allocated memory for evaluation manager\n"); |
690 |
#endif |
691 |
#endif |
692 |
|
693 |
if((fclose(config_file_fp)==0) ){ |
694 |
return EES_SUCCESS; |
695 |
} |
696 |
} |
697 |
return EES_FAILURE; |
698 |
} |
699 |
|
700 |
/*! TODO */ |
701 |
EES_RC allow_rules(int val){ |
702 |
/*eef_log(LOG_DEBUG, "Allowed rule: %i\n", val);*/ |
703 |
return EES_SUCCESS; |
704 |
} |
705 |
|
706 |
/*! TODO */ |
707 |
EES_RC allowed_policy_rule(const char* label){ |
708 |
/*eef_log(LOG_DEBUG, "Allowed policy rule: %s\n", label);*/ |
709 |
return EES_SUCCESS; |
710 |
} |