/[pdpsoft]/trunk/grid-mw-security/ees/src/eval_man/pdl.c
ViewVC logotype

Annotation of /trunk/grid-mw-security/ees/src/eval_man/pdl.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1894 - (hide annotations) (download) (as text)
Thu Aug 26 15:00:24 2010 UTC (11 years, 9 months ago) by aramv
File MIME type: text/x-chdr
File size: 28861 byte(s)
Fixed warnings and a bit of general cleanup
1 aramv 526 #include "pdl.h"
2 aramv 1894 #include <stdlib.h>
3 aramv 1600 #include "plugin_manager.h"
4 aramv 1627 #include "eef_library.h"
5 aramv 526
6 aramv 881 /* Lex/Yacc stuff */
7 aramv 1069 extern FILE * yyin;
8 aramv 1127 extern unsigned int lineno;
9 aramv 1069 extern int yyparse(void);
10     extern int yylex(void);
11 aramv 1127
12 aramv 1416 pdl_data_t config;
13 aramv 1085
14 aramv 1235 /* This function does everything parser related. After running yacc through wrap_yacc(), the created list is reduced to those in the array of named policies, of number_of_policies is greater than 0. The policies are checked for unreachable rules. After the parser has created a list of policies containing lists of rules, these rules are transformed to a tree by the link_dead_end_rules_in_policies() function. Finally, when a list of policies containing rules trees was created, the plug-ins are linked to each rule in the node. */
15     EES_RC start_pdl_parser(char *config_file, int number_of_policies, char* names_of_policies[]){
16 aramv 1416 config.recursion_was_created = 0;
17     config.unknown_variable_was_referenced = 0;
18     config.starting_state_was_reused = 0;
19 aramv 1577 config.parse_errors_detected = 0;
20 aramv 1235
21 aramv 1615 EEF_log(LOG_NOTICE, "Loading config file: %s\n", config_file);
22 aramv 1235 if(wrap_yacc(config_file) == EES_SUCCESS){
23     /* after the config file was successfully parsed, the policies and path to plugins are accessible. We can try to set the global (EEF-wide) modules path if one was provided */
24 aramv 1615 EEF_log(LOG_NOTICE, "Loaded config file: %s\n", config_file);
25 aramv 1235
26     /* set the EEF modules path to the path found by the evaluation manager */
27 aramv 1627 EEF_set_modules_path(get_pdl_path());
28 aramv 1235
29     /* strip policies that are not explicitly passed in the names_of_policies array */
30     if(number_of_policies){
31 aramv 1416 config.policies_list = reduce_policies(config.policies_list, number_of_policies, names_of_policies);
32 aramv 1235 }
33    
34 aramv 1416 if(remove_unreachable_rules_in_policies(config.policies_list) == EES_SUCCESS){
35     if(config.policies_list){
36     link_dead_end_rules_in_policies(config.policies_list);
37     link_rules_to_plugins(config.policies_list);
38 aramv 1235 }
39 aramv 1615 EEF_log(LOG_INFO, "Your configuration file seems sane.\n");
40 aramv 1416 print_policies(config.policies_list);
41 aramv 1235
42     /* this is a callout to the plugin manager, which dlopen()'s the plugin, dlsym()'s the plugin's functions and calls the plugin's initialize function */
43     if(initialize_plugins() == EES_SUCCESS){
44     return EES_SUCCESS;
45     } else {
46 aramv 1615 EEF_log(LOG_ERR, "Failed to initialize plug-ins from policy config file %s\n", config_file);
47 aramv 1235 }
48     } else {
49 aramv 1615 EEF_log(LOG_ERR, "The loaded configuration file defines unreachable rules. Please check your configuration file.");
50 aramv 1235 }
51     } else {
52 aramv 1416 if(config.recursion_was_created){
53 aramv 1615 EEF_log(LOG_ERR, "The loaded configuration file defines recursive rules. Please check your configuration file.");
54 aramv 1235 }
55 aramv 1416 if(config.unknown_variable_was_referenced){
56 aramv 1615 EEF_log(LOG_ERR, "The loaded configuration file references undefined variables. Please check your configuration file.");
57 aramv 1235 }
58 aramv 1416 if(config.starting_state_was_reused){
59 aramv 1615 EEF_log(LOG_ERR, "The loaded configuration file reuses a starting state. Please check your configuration file.");
60 aramv 1236 }
61 aramv 1577 if(config.parse_errors_detected){
62 aramv 1615 EEF_log(LOG_ERR, "The configuration was not parsed correctly. Please check your configuration file.");
63 aramv 1577 }
64 aramv 1235 }
65     return EES_FAILURE;
66     }
67    
68    
69     /*! Initializes the parsing of the configuration file. When parsing has completed successfully, the policy_list is available. This can be transformed to a tree using the link_dead_end_rules_in_policies() function. */
70     EES_RC wrap_yacc(const char* config_file){
71 aramv 1416 config.config_file_s = config_file;
72     if((config.config_file_fp = fopen(config.config_file_s,"r")) != NULL){
73     yyin = config.config_file_fp;
74 aramv 592 yyparse();
75 aramv 1577 if(!config.recursion_was_created && !config.unknown_variable_was_referenced && !config.starting_state_was_reused && !config.parse_errors_detected){
76 aramv 1235 /* callout to the plugin manager */
77     if(add_plugin_structs() == EES_SUCCESS){
78     return EES_SUCCESS;
79     } else {
80 aramv 1615 EEF_log(LOG_ERR, "Failed to load plug-ins from policy config file %s\n", config.config_file_s);
81 aramv 1233 }
82 aramv 890 }
83 aramv 526 } else {
84 aramv 1615 EEF_log(LOG_ERR, "Failed to open policy config file %s", config.config_file_s);
85 aramv 526 }
86 aramv 1077 return EES_FAILURE;
87 aramv 526 }
88    
89 aramv 1156 policy_t* get_policies(){
90 aramv 1416 return config.policies_list;
91 aramv 1156 }
92    
93 aramv 1070 /*! sets the path to modules directory */
94 aramv 1142 void set_pdl_path(record_t* path){
95 aramv 592 size_t path_size = 0;
96 aramv 867 size_t string_size = (sizeof(char) * (strlen(path->string)+2)); /* size of string + extra slash + null byte */
97 aramv 1416 config.pdl_path = "";
98 aramv 881
99 aramv 844 /*struct stat sb;*/
100     /*if stat(MODUL*/
101 aramv 867
102 aramv 592 if(string_size < FILENAME_MAX){
103     path_size = string_size;
104     } else {
105     path_size = FILENAME_MAX;
106     }
107    
108 aramv 1416 if((config.pdl_path = calloc(1, path_size))){
109     strncpy(config.pdl_path, path->string, path_size);
110     strncat(config.pdl_path, "/", 1);
111 aramv 592 }
112 aramv 1070
113 aramv 1615 EEF_log(LOG_DEBUG, "Found a new modules path: %s\n", config.pdl_path);
114 aramv 1070
115 aramv 566 free(path->string);
116 aramv 1211 path->string = NULL;
117 aramv 566 free(path);
118 aramv 1211 path = NULL;
119 aramv 526 }
120    
121 aramv 1077 /*! 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 */
122     void add_variable(record_t* name, record_t* value){
123 aramv 1615 EEF_log(LOG_DEBUG, "Added variable name: %s\n", name->string);
124     EEF_log(LOG_DEBUG, "Added variable value: %s\n", value->string);
125 aramv 566
126 aramv 1077 /* allocate struct and populate fields */
127 aramv 1416 if((config.current_variable = calloc(1,sizeof(var_t)))){
128     config.current_variable->name = strdup(name->string);
129     config.current_variable->value = strdup(value->string);
130     config.current_variable->lineno = name->lineno;
131     config.current_variable->next = NULL;
132 aramv 1077 } else {
133 aramv 1615 EEF_log(LOG_ERR, "Out of memory!");
134 aramv 1077 }
135 aramv 526
136 aramv 1077 /* append to the end of the list */
137 aramv 1416 if(config.variables_list){
138     config.variables_list_last->next = config.current_variable;
139 aramv 1077 } else {
140 aramv 1416 config.variables_list = config.current_variable;
141 aramv 890 }
142 aramv 1416 config.variables_list_last = config.current_variable;
143 aramv 1077
144     /* clean up */
145     free(name->string);
146 aramv 1211 name->string = NULL;
147 aramv 1077 free(name);
148 aramv 1211 name = NULL;
149 aramv 1077 free(value->string);
150 aramv 1211 value->string = NULL;
151 aramv 1077 free(value);
152 aramv 1211 value = NULL;
153 aramv 526 }
154    
155 aramv 1142 /* 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 */
156 aramv 1127 /*! Appends a rule to the global rules_list, which is to be added to a policy when add_policy is called
157 aramv 1235 Will return NULL and log an error when:
158 aramv 1127 - adding the rule to the list will create a recursion in the tree of rules
159     - an unknown variable is referenced
160     */
161 aramv 1077 rule_t* add_rule(record_t* state, record_t* true_branch, record_t* false_branch){
162 aramv 1127 rule_t *new_rule = NULL, *new_false_branch = NULL, *new_true_branch = NULL, *recursive_rule = NULL;
163 aramv 1142 var_t *temp_var = NULL;
164     char *unknown_var_format_string = "Unknown variable %s at line %i in config file %s";
165 aramv 1077
166 aramv 1416 if((new_rule = get_left_hand_rule(config.rules_list, state->string))){
167 aramv 1615 EEF_log(LOG_WARNING, "State %s at line %i is already in use at line %i.\n", state->string, state->lineno, new_rule->lineno);
168 aramv 1416 config.starting_state_was_reused = 1;
169 aramv 1085 } else {
170     /*find variables for rule */
171 aramv 1142 temp_var = get_variable_by_name(state->string);
172     if(temp_var == NULL){
173     /* Errorous state - variable referenced in rule not previously defined */
174 aramv 1615 EEF_log(LOG_ERR, unknown_var_format_string, state->string, state->lineno, config.config_file_s);
175 aramv 1416 config.unknown_variable_was_referenced = 1;
176 aramv 1224 new_rule = clean_rules_tree(new_rule);
177     goto cleanup;
178 aramv 1142 }
179     if(temp_var != NULL){
180 aramv 1085 if((new_rule = calloc(1, sizeof(rule_t)))){
181 aramv 1101 /* populate fields of current state */
182 aramv 1085 new_rule->state = strdup(state->string);
183     new_rule->lineno = state->lineno;
184    
185 aramv 1101 /* populate fields of branches */
186     if(false_branch){
187 aramv 1142 temp_var = get_variable_by_name(false_branch->string);
188     if(temp_var == NULL){
189     /* Errorous state - variable referenced in rule not previously defined */
190 aramv 1615 EEF_log(LOG_ERR, unknown_var_format_string, false_branch->string, false_branch->lineno, config.config_file_s);
191 aramv 1416 config.unknown_variable_was_referenced = 1;
192 aramv 1224 new_rule = clean_rules_tree(new_rule);
193     goto cleanup;
194     } else {
195     if((new_false_branch = calloc(1, sizeof(rule_t)))){
196     new_false_branch->state = strdup(false_branch->string);
197     new_false_branch->lineno = false_branch->lineno;
198     new_rule->false_branch = new_false_branch;
199     }
200 aramv 1142 }
201 aramv 1101 }
202 aramv 1127
203 aramv 1085 if(true_branch){
204 aramv 1142 temp_var = get_variable_by_name(true_branch->string);
205     if(temp_var == NULL){
206     /* Errorous state - variable referenced in rule not previously defined */
207 aramv 1615 EEF_log(LOG_ERR, unknown_var_format_string, true_branch->string, true_branch->lineno, config.config_file_s);
208 aramv 1416 config.unknown_variable_was_referenced = 1;
209 aramv 1224 new_rule = clean_rules_tree(new_rule);
210     goto cleanup;
211     } else {
212     if((new_true_branch = calloc(1, sizeof(rule_t)))){
213     new_true_branch->state = strdup(true_branch->string);
214     new_true_branch->lineno = true_branch->lineno;
215     new_rule->true_branch = new_true_branch;
216     }
217 aramv 1142 }
218 aramv 1085 }
219    
220 aramv 1101 /* check for recursion */
221 aramv 1416 if((recursive_rule = check_for_recursion(config.rules_list, new_rule))){
222 aramv 1615 EEF_log(LOG_WARNING, "Rule %s at line %i leads to recursion into state %s", new_rule->state, new_rule->lineno, recursive_rule->state);
223 aramv 1224 new_rule = clean_rules_tree(new_rule);
224 aramv 1416 config.recursion_was_created = 1;
225 aramv 1259 goto cleanup;
226 aramv 1085 } else {
227 aramv 1101 /* add new rule at the end of the rules list */
228 aramv 1416 if(config.rules_list){
229     config.rules_list_last->next = new_rule;
230 aramv 1101 } else {
231 aramv 1416 config.rules_list = new_rule;
232 aramv 1101 }
233 aramv 1416 config.rules_list_last = new_rule;
234 aramv 1202
235 aramv 1615 EEF_log(LOG_DEBUG, "Added a new rule: %s\n", new_rule->state);
236 aramv 1085 }
237 aramv 1101
238 aramv 1085 } else {
239 aramv 1615 EEF_log(LOG_ERR, "Out of memory!");
240 aramv 1085 }
241 aramv 1077 }
242 aramv 566 }
243 aramv 1077
244 aramv 1224 cleanup:
245    
246 aramv 1077 /* clean up */
247     if(state != NULL){
248     free(state->string);
249     free(state);
250     }
251 aramv 566 if(true_branch != NULL){
252     free(true_branch->string);
253 aramv 1077 free(true_branch);
254 aramv 566 }
255     if(false_branch != NULL){
256     free(false_branch->string);
257 aramv 1077 free(false_branch);
258 aramv 566 }
259 aramv 1077
260 aramv 566 return new_rule;
261 aramv 526 }
262    
263 aramv 1127 /* 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 */
264 aramv 1101 rule_t* check_for_recursion(rule_t* rule_l, rule_t* rule_r){
265 aramv 1106 rule_t* temp_rule = rule_l;
266 aramv 1112
267     /* right hand rule leads to its own recursive state */
268 aramv 1127 /* still need to find a way to reuse the code from the while loop to do this check */
269 aramv 1112 if(rule_r){
270     if(rule_r->true_branch){
271     if(strcmp(rule_r->state, rule_r->true_branch->state) == 0){
272     return rule_r->true_branch;
273     }
274     }
275    
276     if(rule_r->false_branch){
277     if(strcmp(rule_r->state, rule_r->false_branch->state) == 0){
278     return rule_r->false_branch;
279     }
280     }
281     }
282    
283 aramv 1127 /* iterate list of rules */
284 aramv 1106 while(temp_rule){
285     if((temp_rule != NULL) && (rule_r != NULL)){
286     /* left hand and right hand state are equal */
287     if(strcmp(temp_rule->state, rule_r->state) == 0){
288     return rule_r;
289 aramv 1101 }
290 aramv 1112
291 aramv 1106 /* start state and true branch of right hand rule are equal */
292     if(rule_r->true_branch){
293     if(strcmp(temp_rule->state, rule_r->true_branch->state) == 0){
294     return rule_r->true_branch;
295     }
296     }
297 aramv 1108
298     /* start state and false branch of right hand side are equal */
299     if(rule_r->false_branch){
300     if(strcmp(temp_rule->state, rule_r->false_branch->state) == 0){
301     return rule_r->false_branch;
302     }
303     }
304 aramv 1101 }
305 aramv 1127
306 aramv 1106 /* move to next rule */
307     temp_rule = temp_rule->next;
308 aramv 1101 }
309 aramv 1106 return NULL;
310 aramv 1101 }
311    
312 aramv 1235 /* This function iterates the passed list of policies and removes unreachable rules from each policy */
313 aramv 1233 EES_RC remove_unreachable_rules_in_policies(policy_t* policies){
314 aramv 1224 policy_t *temp_policy = policies;
315 aramv 1233 EES_RC retval = EES_SUCCESS;
316 aramv 1224 while(temp_policy){
317 aramv 1235 temp_policy->rules = remove_unreachable_rules(temp_policy->rules, &retval);
318 aramv 1224 temp_policy = temp_policy->next;
319     }
320 aramv 1233 return retval;
321 aramv 1224 }
322    
323 aramv 1235 /* This function iterates the passed list of rules and removes those rules that, while they exist on the left-hand side, are never referenced on the right-hand side of a rule in the list */
324     rule_t* remove_unreachable_rules(rule_t* rules, EES_RC *retval){
325 aramv 1224 rule_t *temp_rule = NULL, *next_rule = NULL, *previous_rule = rules;
326     if(rules){
327     temp_rule = rules->next;
328     while(temp_rule){
329     next_rule = temp_rule->next;
330    
331     if(!(get_right_hand_rule(rules, temp_rule->state))){
332 aramv 1615 EEF_log(LOG_WARNING, "Removing unreachable rule %s at line %i\n", temp_rule->state, temp_rule->lineno);
333 aramv 1224 clean_rules_tree(temp_rule);
334     previous_rule->next = next_rule;
335     temp_rule = previous_rule;
336 aramv 1235 *retval = EES_FAILURE;
337 aramv 1224 }
338     previous_rule = temp_rule;
339     temp_rule = next_rule;
340     }
341     }
342     return rules;
343     }
344    
345     void link_dead_end_rules_in_policies(policy_t* policy){
346 aramv 1208 policy_t* temp_policy = policy;
347     while(temp_policy){
348     link_dead_end_rules(temp_policy, temp_policy->rules);
349     temp_policy = temp_policy->next;
350     }
351     }
352    
353     void link_dead_end_rules(policy_t* policy, rule_t* rule){
354     rule_t *temp_rule = rule, *true_rule, *false_rule;
355     while(temp_rule){
356     if(temp_rule->true_branch){
357 aramv 1224 if((true_rule = get_left_hand_rule(policy->rules, temp_rule->true_branch->state))){
358 aramv 1615 EEF_log(LOG_DEBUG, "Overwriting rule %s with %s\n", temp_rule->true_branch->state, true_rule->state);
359 aramv 1219 clean_rules_tree(temp_rule->true_branch);
360 aramv 1208 temp_rule->true_branch = true_rule;
361     }
362     }
363     if(temp_rule->false_branch){
364 aramv 1224 if((false_rule = get_left_hand_rule(policy->rules, temp_rule->false_branch->state))){
365 aramv 1615 EEF_log(LOG_DEBUG, "Overwriting rule %s with %s\n", temp_rule->false_branch->state, false_rule->state);
366 aramv 1219 clean_rules_tree(temp_rule->false_branch);
367 aramv 1208 temp_rule->false_branch = false_rule;
368     }
369     }
370     temp_rule = temp_rule->next;
371     }
372 aramv 1219 policy->rules_list_transformed_to_tree = 1;
373 aramv 1208 }
374    
375     /*! Tries to find specified state in the rules_list */
376 aramv 1224 rule_t* get_left_hand_rule(rule_t* temp_rule, const char* name){
377 aramv 1202 if(!temp_rule || !name){
378     return NULL;
379     }
380    
381     /* iterate while the rule isn't associated with the given state */
382     while(temp_rule){
383     if(!strcmp(name, temp_rule->state)){
384     return temp_rule;
385     }
386     temp_rule = temp_rule->next;
387     }
388     return NULL;
389     }
390    
391 aramv 1224 /*! Tries to find specified state in the rules_list */
392     rule_t* get_right_hand_rule(rule_t* temp_rule, const char* name){
393     if(!temp_rule || !name){
394     return NULL;
395     } else {
396     /* iterate while the rule isn't associated with the given state */
397     if(temp_rule->true_branch){
398     if(strcmp(name, temp_rule->true_branch->state) == 0){
399     return temp_rule->true_branch;
400     }
401     }
402     if(temp_rule->false_branch){
403     if(strcmp(name, temp_rule->false_branch->state) == 0){
404     return temp_rule->false_branch;
405     }
406     }
407     }
408     return NULL;
409     }
410    
411 aramv 1127 /*! 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 */
412     void add_policy(record_t* policy, rule_t* top_rule){
413 aramv 1123 policy_t* new_policy = NULL;
414     /*eef_log(LOG_DEBUG, "Found a new policy: %s\n", policy->string);*/
415 aramv 1077
416 aramv 1127 if((new_policy = calloc(1, sizeof(policy_t)))){
417 aramv 1123 new_policy->name = strdup(policy->string);
418     new_policy->lineno = policy->lineno;
419 aramv 1127 new_policy->rules = top_rule;
420 aramv 1219 new_policy->rules_list_transformed_to_tree = 0;
421 aramv 1211 new_policy->next = NULL;
422 aramv 1123 }
423    
424     /* append to the end of the list */
425 aramv 1416 if(config.policies_list){
426     config.policies_list_last->next = new_policy;
427 aramv 1123 } else {
428 aramv 1416 config.policies_list = new_policy;
429 aramv 1123 }
430 aramv 1416 config.policies_list_last = new_policy;
431 aramv 1123
432 aramv 1212 /* start a new rules list */
433 aramv 1416 config.rules_list = NULL;
434 aramv 1123
435 aramv 1077 free(policy->string);
436 aramv 1211 policy->string = NULL;
437 aramv 1077 free(policy);
438 aramv 1211 policy = NULL;
439 aramv 1123 }
440 aramv 1077
441 aramv 1201 /* prints the list of policies */
442 aramv 1156 void print_policies(policy_t* policies){
443     policy_t* temp_policy = policies;
444 aramv 1123 while(temp_policy){
445 aramv 1615 EEF_log(LOG_DEBUG, "Policy: %s\n", temp_policy->name);
446 aramv 1208 print_rules(temp_policy, temp_policy->rules);
447 aramv 1123 temp_policy = temp_policy->next;
448     }
449 aramv 1158 return;
450 aramv 1077 }
451    
452 aramv 1201
453     /* prints the list of rules */
454 aramv 1208 void print_rules(policy_t* policy, rule_t* rule){
455     if(rule){
456 aramv 1615 EEF_log(LOG_DEBUG, " | Rule %s\n", rule->state);
457     EEF_log(LOG_DEBUG, " -------------------------\n");
458 aramv 1208 if(rule->true_branch){
459 aramv 1224 print_rules(policy, get_left_hand_rule(policy->rules, rule->true_branch->state));
460 aramv 1208 }
461     if(rule->false_branch){
462 aramv 1224 print_rules(policy, get_left_hand_rule(policy->rules, rule->false_branch->state));
463 aramv 1208 }
464 aramv 1201 }
465     return;
466     }
467    
468 aramv 1158 /* tries to link all policy rules to a plugin in the plugin manager */
469 aramv 1156 EES_RC link_rules_to_plugins(policy_t* policies){
470     policy_t *temp_policy = policies;
471 aramv 1147
472 aramv 1154 while(temp_policy){
473 aramv 1208 link_rule_to_plugin(temp_policy, temp_policy->rules);
474 aramv 1154 temp_policy = temp_policy->next;
475 aramv 1147 }
476 aramv 1158 return EES_SUCCESS;
477 aramv 1147 }
478    
479 aramv 1202 void link_rule_to_plugin(policy_t *policy, rule_t *rule){
480 aramv 1192 var_t *temp_var = NULL;
481 aramv 1201 char** argv;
482     int argc;
483    
484 aramv 1192 eef_plugindl_t *temp_plugin = NULL;
485     if(rule){
486 aramv 1211 if(!rule->plugin){
487     temp_var = get_variable_by_name(rule->state);
488     if(temp_var){
489     argv = _var_to_argv(temp_var->value, &argc);
490 aramv 1201
491 aramv 1698 temp_plugin = get_plugin(temp_var->name);
492 aramv 1211 if(temp_plugin){
493     rule->plugin = temp_plugin;
494     } else {
495 aramv 1615 EEF_log(LOG_WARNING, "Unknown plugin in variable %s\n", temp_var->value);
496 aramv 1211 }
497     free_args(argc, argv);
498 aramv 1192 }
499 aramv 1211 } else {
500 aramv 1615 EEF_log(LOG_DEBUG, "Plugin already linked?\n");
501 aramv 1192 }
502 aramv 1202 link_rule_to_plugin(policy, rule->true_branch);
503     link_rule_to_plugin(policy, rule->false_branch);
504 aramv 1192 }
505 aramv 1201 return;
506 aramv 1192 }
507    
508 aramv 1158 /* iterates the policies and removes those that are not explicitly named in the passed array of strings */
509 aramv 1224 policy_t* reduce_policies(policy_t* policies, int number_of_policies, char* names_of_policies[]){
510 aramv 1158 int i, policy_should_be_removed;
511 aramv 1215 policy_t *temp_policy = policies, *next_policy = NULL;
512 aramv 1211
513 aramv 1215 while(temp_policy){
514 aramv 1158 policy_should_be_removed = 1;
515 aramv 1615 EEF_log(LOG_DEBUG, "Checking policy: %s\n", (temp_policy)->name);
516 aramv 1158 for(i = 0; i < number_of_policies; i++){
517     if(strcmp(temp_policy->name, names_of_policies[i]) == 0){
518     /* if the policy is in the named list, we can continue to the next plugin */
519 aramv 1615 EEF_log(LOG_DEBUG, "Allowed policy: %s\n", names_of_policies[i]);
520 aramv 1158 policy_should_be_removed = 0;
521     break;
522     }
523     }
524    
525 aramv 1215 next_policy = temp_policy->next;
526    
527 aramv 1158 if(policy_should_be_removed){
528 aramv 1615 EEF_log(LOG_DEBUG, "Removing not-allowed policy: %s\n", temp_policy->name);
529 aramv 1215 policies = remove_policy_by_name(policies, temp_policy->name);
530 aramv 1158 }
531 aramv 1215 temp_policy = next_policy;
532 aramv 1212 }
533 aramv 1211
534 aramv 1158 return policies;
535     }
536    
537 aramv 1077 /*! concatenates two strings */
538     record_t* concat_strings(record_t* r1, record_t* r2){
539     record_t* new_record;
540 aramv 1123 /*eef_log(LOG_DEBUG, "Concating: %s with %s\n", r1->string, r2->string);*/
541 aramv 1077 if((new_record = malloc(sizeof(record_t)))){
542     if((new_record->string =
543     calloc(1, sizeof(char)*(strlen(r1->string) + strlen(r2->string)+1)))){
544     strncat(new_record->string, r1->string, strlen(r1->string));
545     strncat(new_record->string, r2->string, strlen(r2->string));
546     free(r1->string);
547     free(r1);
548     free(r2->string);
549     free(r2);
550     return new_record;
551     }
552     }
553     return NULL;
554     }
555    
556     /*! concatenates two strings with a space in between */
557     record_t* concat_strings_with_space(record_t *r1, record_t* r2){
558     record_t *r;
559 aramv 1123 /*eef_log(LOG_DEBUG, "Concating: %s with %s with spaces\n", r1->string, r2->string);*/
560 aramv 1077 if((r = malloc(sizeof(record_t)))){
561     r->string = calloc(1,(sizeof(char)*(strlen(r1->string)+strlen(r2->string)+2)));
562     strncat(r->string, r1->string, strlen(r1->string));
563     strncat(r->string, " ", 1);
564     strncat(r->string, r2->string, strlen(r2->string));
565     free(r1->string);
566     free(r1);
567     free(r2->string);
568     free(r2);
569     return r;
570     }
571     return NULL;
572     }
573    
574     /*! logs errors encountered during parsing */
575     int yyerror(char* string){
576 aramv 1577 config.parse_errors_detected = 1;
577 aramv 1615 EEF_log(LOG_ERR, "Parse error: %s at line %i in config file %s", string, lineno, config.config_file_s);
578 aramv 1077 return 0;
579     }
580    
581     /*! get variable from list */
582     var_t* get_variable_by_name(char* name){
583 aramv 1416 for(config.current_variable = config.variables_list; config.current_variable != NULL; config.current_variable = config.current_variable->next){
584     if(!strncmp(name, config.current_variable->name, strlen(config.current_variable->name))){
585     return config.current_variable;
586 aramv 1077 }
587     }
588     return NULL;
589     }
590    
591 aramv 1070 /*! Removes a policy from the list of policies */
592 aramv 526 void remove_policy(record_t* policy){
593 aramv 1416 policy_t *temp_policy = config.policies_list, *next_policy = NULL;
594 aramv 1615 EEF_log(LOG_DEBUG, "Deleted policy: %s\n", policy->string);
595 aramv 1158
596     while(temp_policy){
597     if(strcmp(temp_policy->name, policy->string) == 0){
598     /* target policy was found */
599     next_policy = temp_policy->next;
600    
601     /* Clean policy fields */
602 aramv 1219 if(temp_policy->rules_list_transformed_to_tree){
603     temp_policy->rules = clean_rules_tree(temp_policy->rules);
604     } else {
605     temp_policy->rules = clean_rules_list(temp_policy->rules);
606     }
607 aramv 1158 free(temp_policy->name);
608 aramv 1211 temp_policy->name = NULL;
609 aramv 1158 free(temp_policy);
610 aramv 1211 temp_policy = NULL;
611 aramv 1158 }
612    
613     /* Move to next policy */
614     temp_policy = next_policy;
615     }
616    
617 aramv 526 free(policy->string);
618     free(policy);
619 aramv 1158 return;
620 aramv 526 }
621    
622 aramv 1158 /*! Removes a policy from the list of policies */
623 aramv 1212 policy_t* remove_policy_by_name(policy_t* policies, char* policy){
624 aramv 1215 policy_t *temp_policy = NULL, *next_policy = NULL, *previous_policy = NULL;
625 aramv 1158
626 aramv 1215 for(temp_policy = policies; temp_policy != NULL; ){
627 aramv 1211 next_policy = temp_policy->next;
628    
629 aramv 1158 if(strcmp(temp_policy->name, policy) == 0){
630     /* target policy was found */
631 aramv 1212
632 aramv 1158 /* Clean policy fields */
633 aramv 1219 if(temp_policy->rules_list_transformed_to_tree){
634 aramv 1220 clean_rules_tree(temp_policy->rules);
635 aramv 1219 } else {
636 aramv 1220 clean_rules_list(temp_policy->rules);
637 aramv 1219 }
638 aramv 1220
639 aramv 1615 EEF_log(LOG_DEBUG, "Deleted policy: %s\n", policy);
640 aramv 1158 free(temp_policy->name);
641     free(temp_policy);
642 aramv 1224
643     /* if the head node is deleted, overwrite it with the next node */
644     if(previous_policy){
645     previous_policy->next = next_policy;
646     } else {
647     policies = next_policy;
648     }
649 aramv 1222 break;
650 aramv 1158 }
651    
652 aramv 1215 previous_policy = temp_policy;
653    
654 aramv 1158 /* Move to next policy */
655     temp_policy = next_policy;
656     }
657 aramv 1212
658     return policies;
659 aramv 1158 }
660    
661 aramv 1070 /*! converts a string to an array of strings by splitting it at each \t delimiter
662     - overwrites the second argument with a pointer to the number of elements in the array */
663 aramv 586 char** _var_to_argv(char* value, int *argc){
664 aramv 1410 char *start_of_arg = NULL, *copy_of_value = NULL, **argv = NULL;
665     char *delimiters = " \t";
666     size_t size_of_arg = 0, size_of_array, i = 0;
667     char *str_ptr;
668    
669 aramv 586 copy_of_value = strdup(value);
670 aramv 1410 size_of_array = (sizeof(char*)*(strlen(copy_of_value)+1));
671    
672 aramv 586 if((argv = calloc(1, size_of_array)) != NULL){
673     start_of_arg = strtok_r(copy_of_value, delimiters, &str_ptr);
674     while(start_of_arg != NULL){
675     size_of_arg = (sizeof(char)*(strlen(start_of_arg)+1));
676     if((argv[i] = calloc(1, size_of_arg))){
677     memcpy(argv[i], start_of_arg, size_of_arg);
678     start_of_arg = strtok_r(NULL, delimiters, &str_ptr);
679     i++;
680     }
681     }
682     }
683     free(copy_of_value);
684 aramv 1211 copy_of_value = NULL;
685 aramv 805 if(i < ARG_MAX){
686     *argc = i;
687     } else {
688     *argc = ARG_MAX;
689     }
690 aramv 586 return argv;
691 aramv 572 }
692    
693 aramv 1127 /*! returns pdl path found in parsed config file */
694 aramv 1077 const char* get_pdl_path(){
695 aramv 1416 return config.pdl_path;
696 aramv 1077 }
697 aramv 890
698 aramv 1156 /*! Iterates list of policies and the rules they contain and tries to let the plugin manager prepare plugin structs*/
699 aramv 1235 EES_RC add_plugin_structs(){
700 aramv 1131 char** argv;
701     int argc;
702 aramv 1235 EES_RC plugin_struct_added_ok = EES_SUCCESS;
703 aramv 1698 var_t* temp_var = config.variables_list;
704 aramv 1131
705 aramv 1235 while((temp_var != NULL) && (plugin_struct_added_ok == EES_SUCCESS)){
706 aramv 1131 argv = _var_to_argv(temp_var->value, &argc);
707    
708 aramv 1156 /* this is a callout to the plug-in manager, which adds a struct describing a single plug-in to its list */
709 aramv 1698 plugin_struct_added_ok = add_plugin_struct(argc, argv, temp_var->name);
710 aramv 1131
711     /* Move to next variable */
712     temp_var = temp_var->next;
713     }
714    
715 aramv 1235 return plugin_struct_added_ok;
716 aramv 890 }
717    
718 aramv 1127 /*! Iterates the list of var_t structures and tries to free them */
719 aramv 1077 EES_RC clean_variables_list(){
720 aramv 1416 config.current_variable = config.variables_list;
721     while(config.current_variable){
722     free(config.current_variable->name);
723     config.current_variable->name = NULL;
724     free(config.current_variable->value);
725     config.current_variable->value = NULL;
726 aramv 1085
727 aramv 1127 /* Move to next variable */
728 aramv 1416 config.variables_list_last = config.current_variable;
729     config.current_variable = config.current_variable->next;
730 aramv 1085
731 aramv 1127 /* Clean last variable struct */
732 aramv 1416 free(config.variables_list_last);
733     config.variables_list_last = NULL;
734 aramv 890 }
735     return EES_SUCCESS;
736     }
737    
738 aramv 1219 /*! Iterates the tree of rule_t structures starting with the passed rule and tries to free them and their true/false branches */
739     rule_t* clean_rules_tree(rule_t* top_rule){
740 aramv 1127 rule_t* temp_rule = top_rule;
741 aramv 1202 if(temp_rule){
742 aramv 1219 clean_rules_tree(temp_rule->true_branch);
743 aramv 1202
744 aramv 1219 clean_rules_tree(temp_rule->false_branch);
745 aramv 1085
746 aramv 1215 free(temp_rule->state);
747 aramv 1202 free(temp_rule);
748 aramv 1211 temp_rule = NULL;
749 aramv 1085 }
750 aramv 1219 return NULL;
751 aramv 1085 }
752    
753 aramv 1219 /*! Iterates the list of rule_t structures starting with the passed rule and tries to free them and their true/false branches */
754     rule_t* clean_rules_list(rule_t* top_rule){
755     rule_t *temp_rule = top_rule, *next_rule = NULL;
756     while(temp_rule){
757     next_rule = temp_rule->next;
758 aramv 1222 clean_rules_tree(temp_rule);
759 aramv 1219 temp_rule = next_rule;
760     }
761     return NULL;
762     }
763    
764 aramv 1147 void free_args(int argc, char** argv){
765     for(; argc > 0; argc--){
766     free(argv[argc-1]);
767 aramv 1211 argv[argc-1] = NULL;
768 aramv 1147 }
769     free(argv);
770 aramv 1211 argv = NULL;
771 aramv 1147 }
772    
773 aramv 1127 /*! Iterates the list of policy_t structures and tries to free them and their rules */
774 aramv 1212 EES_RC clean_policies_list(policy_t* policies){
775     policy_t *temp_policy = policies, *last_policy = NULL;
776 aramv 1127 while(temp_policy){
777     /* Clean policy fields */
778 aramv 1219 if(temp_policy->rules_list_transformed_to_tree){
779     clean_rules_tree(temp_policy->rules);
780     } else {
781     clean_rules_list(temp_policy->rules);
782     }
783 aramv 1127 free(temp_policy->name);
784 aramv 1211 temp_policy->name = NULL;
785 aramv 1127
786     /* Move to next policy */
787     last_policy = temp_policy;
788     temp_policy = temp_policy->next;
789     free(last_policy);
790 aramv 1211 last_policy = NULL;
791 aramv 1127 }
792     return EES_SUCCESS;
793     }
794    
795 aramv 1070 /*! Terminates the parser and tries to free all used memory */
796 aramv 1257 EES_RC pdl_term(){
797 aramv 1077 clean_variables_list();
798 aramv 1416 clean_policies_list(config.policies_list);
799     free(config.pdl_path);
800     config.pdl_path = NULL;
801 aramv 1077
802 aramv 1609 config.recursion_was_created = 0;
803     config.unknown_variable_was_referenced = 0;
804     config.starting_state_was_reused = 0;
805     config.parse_errors_detected = 0;
806    
807     config.variables_list = NULL;
808     config.variables_list_last = NULL;
809     config.current_variable = NULL;
810    
811     config.rules_list = NULL;
812     config.rules_list_last = NULL;
813    
814     config.policies_list = NULL;
815     config.policies_list_last = NULL;
816    
817 aramv 1416 if(config.config_file_fp != NULL){
818 aramv 1069 /* 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 */
819 aramv 1127 #if HAVE_YYLEX_DESTROY /* macro set by configure script */
820 aramv 586 yylex_destroy();
821 aramv 1069 #else
822 aramv 1127 /*eef_log(LOG_WARNING, "Lex function yylex_destroy() not available - possibly unable to free allocated memory for evaluation manager\n");*/
823 aramv 1069 #if HAVE_FLEX
824 aramv 1127 delete_lex_buffer(); /* this function is defined in pdl_lex.l */
825     /*eef_log(LOG_INFO, "Managed to free allocated memory for evaluation manager\n"); */
826     #else
827 aramv 1615 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");
828 aramv 1069 #endif
829 aramv 586 #endif
830 aramv 1127
831 aramv 1416 if((fclose(config.config_file_fp)==0) ){
832 aramv 781 return EES_SUCCESS;
833 aramv 586 }
834 aramv 526 }
835 aramv 781 return EES_FAILURE;
836 aramv 526 }
837    
838 aramv 1070 /*! TODO */
839 aramv 781 EES_RC allow_rules(int val){
840 aramv 1208 /*eef_log(LOG_DEBUG, "Allowed rule: %i\n", val);*/
841 aramv 781 return EES_SUCCESS;
842 aramv 526 }
843    
844 aramv 1070 /*! TODO */
845 aramv 781 EES_RC allowed_policy_rule(const char* label){
846 aramv 1208 /*eef_log(LOG_DEBUG, "Allowed policy rule: %s\n", label);*/
847 aramv 781 return EES_SUCCESS;
848 aramv 526 }

grid.support@nikhef.nl
ViewVC Help
Powered by ViewVC 1.1.28