00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00034 #include <stdarg.h>
00035 #include <stdio.h>
00036 #include <stdlib.h>
00037 #include <string.h>
00038
00039 #include "_lcmaps_pluginmanager.h"
00040 #include "lcmaps_log.h"
00041 #include "pdl.h"
00042 #include "pdl_variable.h"
00043 #include "pdl_policy.h"
00044 #include "pdl_rule.h"
00045
00046 static const char* script_name = NULL;
00047 static const char* d_path = "/usr/lib";
00048 static const char* path = 0;
00049 static int path_lineno = 0;
00050 static plugin_t* top_plugin = NULL;
00051 static BOOL default_path = TRUE;
00052 static BOOL parse_error = FALSE;
00053 static char* level_str[PDL_SAME];
00054
00055 unsigned int lineno = 1;
00056
00057 void _set_path(const record_t* _path);
00058 record_t* _concat_strings(const record_t* s1, const record_t* s2, const char* extra);
00059 void reduce_policies(void);
00060 void init_name_args(plugin_t** plugin, const rule_t* rule, rule_type_t type);
00061 BOOL plugin_exists(const char* string);
00062 int find_first_space(const char* string);
00063
00064
00074 int pdl_init(const char* name)
00075 {
00076 if (name) {
00077 FILE* file;
00078
00079 script_name = strdup(name);
00080
00081 file = fopen(name, "r");
00082 if (file)
00083 yyin = file;
00084 else {
00085 warning(PDL_ERROR, "Could not open file '%s'.", name);
00086 return -1;
00087 }
00088 }
00089
00090
00091 path = d_path;
00092 default_path = TRUE;
00093
00094
00095
00096
00097
00098 while (top_plugin) {
00099 free(top_plugin->name);
00100 free(top_plugin->args);
00101 top_plugin = top_plugin->next;
00102 }
00103
00104
00105 level_str[PDL_INFO] = "info";
00106 level_str[PDL_WARNING] = "warning";
00107 level_str[PDL_ERROR] = "error";
00108 level_str[PDL_UNKNOWN] = "<unknown>";
00109
00110 parse_error = FALSE;
00111
00112 return 0;
00113 }
00114
00115
00122 int yyparse_errors(void)
00123 {
00124 return parse_error ? -1 : 0;
00125 }
00126
00127
00134 const plugin_t* get_plugins(void)
00135 {
00136 plugin_t* plugin;
00137 policy_t* policy;
00138
00139
00140
00141
00142
00143
00144 if (!policies_have_been_reduced()) {
00145 lcmaps_log(1, "The policies have not been reduced. Probably the startElevaluationManager has failed or has not been called yet.\n");
00146 return 0;
00147 }
00148
00149
00150
00151
00152
00153 if (top_plugin)
00154 return top_plugin;
00155
00156 policy = get_policies();
00157
00158 while (policy) {
00159 rule_t* rule = policy->rule;
00160
00161 lcmaps_log_debug(1, "processing policy: %s\n", policy->name);
00162 while (rule) {
00163 lcmaps_log_debug(1, " processing rule: %s -> %s | %s\n", rule->state, rule->true_branch, rule->false_branch);
00164
00165 lcmaps_log_debug(1, " get_plugins: initializing...\n");
00166 init_name_args(&plugin, rule, STATE);
00167 init_name_args(&plugin, rule, TRUE_BRANCH);
00168 init_name_args(&plugin, rule, FALSE_BRANCH);
00169 lcmaps_log_debug(1, " get_plugins: initializing done.\n");
00170
00171 rule = rule->next;
00172 }
00173 policy = policy->next;
00174 }
00175
00176 return top_plugin;
00177 }
00178
00179
00187 BOOL plugin_exists(const char* string)
00188 {
00189 int space, remainder;
00190 plugin_t *plugin;
00191
00192 space = find_first_space(string);
00193 remainder = strlen(string) - space - 1;
00194 plugin = top_plugin;
00195
00196 while (plugin) {
00197 if (plugin->name && strncmp(plugin->name, string, space)==0) {
00198 if (plugin->args)
00199 if (strncmp(plugin->args, string+space+1, remainder)!=0) {
00200 plugin = plugin->next;
00201 continue;
00202 }
00203 return TRUE;
00204 }
00205 plugin = plugin->next;
00206 }
00207
00208 return FALSE;
00209 }
00210
00211
00215 void init_name_args(plugin_t** plugin, const rule_t* rule, rule_type_t type)
00216 {
00217 int space, remainder;
00218 const char* string;
00219
00220 switch (type) {
00221 case STATE:
00222 string = rule->state;
00223 break;
00224 case TRUE_BRANCH:
00225 string = rule->true_branch;
00226 break;
00227 case FALSE_BRANCH:
00228 string = rule->false_branch;
00229 break;
00230 default:
00231 warning(PDL_ERROR, "init_name_args: unknown type!");
00232 return;
00233 }
00234
00235 lcmaps_log_debug(1, " init_name_args: processing: %s\n", string);
00236
00237 if (!string || plugin_exists(string)) {
00238 lcmaps_log_debug(1, " init_name_args: Either the plugin exists or string == 0.\n");
00239 return;
00240 }
00241
00242 lcmaps_log_debug(1, " init_name_args: plugin does not exists.\n");
00243
00244 if (!top_plugin) {
00245 top_plugin = (plugin_t*)malloc(sizeof(plugin_t));
00246 *plugin = top_plugin;
00247 }
00248 else {
00249 (*plugin)->next = (plugin_t*)malloc(sizeof(plugin_t));
00250 *plugin = (*plugin)->next;
00251 }
00252
00253 (*plugin)->name = (*plugin)->args = 0;
00254 (*plugin)->next = 0;
00255
00256 space = find_first_space(string);
00257
00258 lcmaps_log_debug(1, " init_name_args: space found a pos: %d strlen = %d.\n", space, strlen(string));
00259
00260 (*plugin)->name = (char *)malloc(space+1);
00261 strncpy((*plugin)->name, string, space);
00262 *((*plugin)->name+space) = '\0';
00263
00264 remainder = strlen(string)-space-1;
00265 if (remainder > 0) {
00266 (*plugin)->args = (char *)malloc(remainder+1);
00267 strncpy((*plugin)->args, string+space+1, remainder);
00268 *((*plugin)->args+remainder) = '\0';
00269 } else
00270 (*plugin)->args = 0;
00271
00272 (*plugin)->lineno = rule->lineno;
00273 (*plugin)->next = 0;
00274
00275 lcmaps_log_debug(1, " init_name_args: plugin->name = %s\n", (*plugin)->name);
00276 lcmaps_log_debug(1, " init_name_args: plugin->args = %s\n", (*plugin)->args);
00277 }
00278
00279
00289 int find_first_space(const char* string)
00290 {
00291 int space, max_length;
00292 space = 0;
00293 max_length = strlen(string);
00294
00295 for (; *string++ != ' ' && space < max_length; ++space);
00296
00297 return space;
00298 }
00299
00300
00306 const char *pdl_path(void)
00307 {
00308 return path;
00309 };
00310
00311
00319 int yyerror(const char* s)
00320 {
00321
00322
00323 warning(PDL_ERROR, s);
00324
00325 return 0;
00326 }
00327
00328
00336 void set_path(record_t* path)
00337 {
00338 _set_path(path);
00339
00340 free(path->string);
00341 free(path);
00342 }
00343
00344
00353 void _set_path(const record_t* _path)
00354 {
00355
00356
00357 if (!default_path) {
00358 warning(PDL_ERROR, "path already defined in: %d; ignoring this instance.", path_lineno);
00359 return;
00360 }
00361
00362 default_path = FALSE;
00363 path_lineno = _path->lineno;
00364 path = strdup(_path->string);
00365 }
00366
00367
00368
00372 void free_path(void)
00373 {
00374 if (!default_path && path) {
00375 free((char*)path);
00376 default_path = TRUE;
00377 path = 0;
00378 }
00379 }
00380
00381
00382
00393 record_t* concat_strings(record_t* s1, record_t* s2)
00394 {
00395 record_t* r = _concat_strings(s1, s2, 0);
00396
00397 free(s1->string);
00398 free(s2->string);
00399 free(s1);
00400 free(s2);
00401
00402 return r;
00403 }
00404
00405
00414 record_t* _concat_strings(const record_t* s1, const record_t* s2,
00415 const char* extra)
00416 {
00417 int len = strlen(s1->string);
00418 int len_extra = extra ? strlen(extra) : 0;
00419
00420 record_t* record = (record_t *)malloc(sizeof(record_t));
00421
00422 if (!(record->string = (char *)malloc(len + len_extra + strlen(s2->string)+1))) {
00423 warning(PDL_ERROR, "out of memory");
00424 return 0;
00425 }
00426
00427 strcpy(record->string, s1->string);
00428 if (extra)
00429 strcpy(record->string+len, extra);
00430 strcpy(record->string+len+len_extra, s2->string);
00431
00432
00433
00434 return record;
00435 }
00436
00437
00448 record_t* concat_strings_with_space(record_t* s1, record_t* s2)
00449 {
00450 record_t* r;
00451
00452
00453 if (strlen(s2->string)!=0) {
00454
00455
00456
00457
00458 if ((s1->string[strlen(s1->string)-1]=='"') &&
00459 (s2->string[strlen(s2->string)-1]=='"'))
00460 r = _concat_strings(s1, s2, 0);
00461 else
00462 r = _concat_strings(s1, s2, " ");
00463
00464 free(s1->string);
00465 free(s2->string);
00466 free(s1);
00467 free(s2);
00468 } else {
00469
00470
00471
00472
00473 r = (record_t*)malloc(sizeof(r));
00474 memcpy(r, s1, sizeof(r));
00475 }
00476
00477 return r;
00478 }
00479
00480
00498 const char* pdl_next_plugin(plugin_status_t status)
00499 {
00500 const static policy_t* current_policy = 0;
00501 const static rule_t* current_rule = 0;
00502 char* string = 0;
00503 const char* state = 0;
00504
00505 switch (status) {
00506 case EVALUATION_START:
00507
00508 if (!(current_policy = get_policies()))
00509 return 0;
00510 if (!(current_rule = current_policy->rule))
00511 return 0;
00512
00513 state = current_rule->state;
00514 break;
00515
00516 case EVALUATION_SUCCESS:
00517 if (current_rule)
00518 state = current_rule->true_branch;
00519
00520 if (current_policy && state)
00521 current_rule = find_state(current_policy->rule, state);
00522 else
00523 current_rule = 0;
00524 break;
00525
00526 case EVALUATION_FAILURE:
00527
00528
00529
00530
00531
00532
00533
00534
00535
00536
00537
00538
00539
00540
00541 if (current_rule)
00542 state = current_rule->false_branch;
00543
00544
00545
00546
00547
00548
00549
00550
00551
00552 if (!(current_rule && state)) {
00553 if (current_policy && (current_policy = current_policy->next)) {
00554 if ((current_rule = current_policy->rule)) {
00555 int rc;
00556 state = current_rule->state;
00557 lcmaps_log_debug(1, "evaluationmanager: Resetting credential data for policy: %s\n", current_policy->name);
00558 rc = resetCredentialData();
00559
00560 if (rc) {
00561 warning(PDL_ERROR, "Resetting credential data failed: rc = %d", rc);
00562 return 0;
00563 }
00564 }
00565 }
00566 } else {
00567
00568 if (current_policy)
00569 current_rule = find_state(current_policy->rule, state);
00570 }
00571
00572 break;
00573 }
00574
00575
00576
00577
00578
00579
00580
00581 if (state) {
00582 const char* tmp;
00583 int state_length, path_length;
00584
00585 tmp = state;
00586 state_length = path_length = 0;
00587
00588 while (*tmp!=' ' && *tmp++!='\0') {
00589 ++state_length;
00590 }
00591 path_length = strlen(pdl_path());
00592
00593
00594 string = (char*)malloc(state_length + path_length + 2);
00595 strcpy(string, pdl_path());
00596
00597
00598 if (string[path_length-1] != '/')
00599 string[path_length++] = '/';
00600 strncpy(string + path_length, state, state_length);
00601 string[path_length + state_length] = '\0';
00602 }
00603
00604 return string;
00605 }
00606
00607
00612 void free_resources(void)
00613 {
00614 if (script_name) {
00615 free((char*)script_name);
00616 script_name = 0;
00617 }
00618
00619 free_path();
00620
00621 free_variables();
00622 free_policies();
00623
00624
00625
00626
00627
00628
00629 if (yyin!=stdin && yyin!=stderr) {
00630 fclose(yyin);
00631 yyin=stdin;
00632 }
00633
00634 #ifdef HAVE_FLEX
00635 delete_lex_buffer();
00636 #endif
00637 }
00638
00639
00648 void warning(pdl_error_t error, const char* s, ...)
00649 {
00650 static char* level = 0;
00651 char buf[2048];
00652 int res;
00653
00654 va_list args;
00655
00656 if (error == PDL_ERROR)
00657 parse_error = TRUE;
00658
00659 if (!level)
00660 level = level_str[PDL_UNKNOWN];
00661
00662 if (error != PDL_SAME)
00663 level = level_str[error];
00664
00665
00666
00667
00668
00669 res = sprintf(buf, "%s:%d: [%s] ", script_name, lineno, level);
00670
00671
00672 va_start(args, s);
00673 res += vsnprintf(buf+res, sizeof(buf)-res-2, s, args);
00674 va_end(args);
00675
00676
00677
00678
00679
00680
00681 buf[res<sizeof(buf)-1 ? res++ : sizeof(buf)-2] = '\n';
00682 buf[res<sizeof(buf) ? res : sizeof(buf)-1] = '\0';
00683
00684 lcmaps_log(0, buf);
00685 }
00686