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 static const policy_t* current_policy = 0;
00056 static const rule_t* current_rule = 0;
00057
00058 unsigned int lineno = 1;
00059
00060 void _set_path(const record_t* _path);
00061 record_t* _concat_strings(const record_t* s1, const record_t* s2, const char* extra);
00062 void reduce_policies(void);
00063 void init_name_args(plugin_t** plugin, const rule_t* rule, rule_type_t type);
00064 BOOL plugin_exists(const char* string);
00065 int find_first_space(const char* string);
00066
00067
00072 policy_t* get_current_policy(void)
00073 {
00074 return current_policy;
00075 }
00076
00086 int pdl_init(const char* name)
00087 {
00088 if (name) {
00089 FILE* file;
00090
00091 script_name = strdup(name);
00092
00093 file = fopen(name, "r");
00094 if (file)
00095 yyin = file;
00096 else {
00097 warning(PDL_ERROR, "Could not open file '%s'.", name);
00098 return -1;
00099 }
00100 }
00101
00102
00103 path = d_path;
00104 default_path = TRUE;
00105
00106
00107
00108
00109
00110 while (top_plugin) {
00111 free(top_plugin->name);
00112 free(top_plugin->args);
00113 top_plugin = top_plugin->next;
00114 }
00115
00116
00117 level_str[PDL_INFO] = "info";
00118 level_str[PDL_WARNING] = "warning";
00119 level_str[PDL_ERROR] = "error";
00120 level_str[PDL_UNKNOWN] = "<unknown>";
00121
00122 parse_error = FALSE;
00123
00124 return 0;
00125 }
00126
00127
00134 int yyparse_errors(void)
00135 {
00136 return parse_error ? -1 : 0;
00137 }
00138
00139
00146 const plugin_t* get_plugins(void)
00147 {
00148 plugin_t* plugin;
00149 policy_t* policy;
00150
00151
00152
00153
00154
00155
00156 if (!policies_have_been_reduced()) {
00157 lcmaps_log(1, "The policies have not been reduced. Probably the startElevaluationManager has failed or has not been called yet.\n");
00158 return 0;
00159 }
00160
00161
00162
00163
00164
00165 if (top_plugin)
00166 return top_plugin;
00167
00168 policy = get_policies();
00169
00170 while (policy) {
00171 rule_t* rule = policy->rule;
00172
00173 lcmaps_log_debug(1, "processing policy: %s\n", policy->name);
00174 while (rule) {
00175 lcmaps_log_debug(1, " processing rule: %s -> %s | %s\n", rule->state, rule->true_branch, rule->false_branch);
00176
00177 lcmaps_log_debug(1, " get_plugins: initializing...\n");
00178 init_name_args(&plugin, rule, STATE);
00179 init_name_args(&plugin, rule, TRUE_BRANCH);
00180 init_name_args(&plugin, rule, FALSE_BRANCH);
00181 lcmaps_log_debug(1, " get_plugins: initializing done.\n");
00182
00183 rule = rule->next;
00184 }
00185 policy = policy->next;
00186 }
00187
00188 return top_plugin;
00189 }
00190
00191
00199 BOOL plugin_exists(const char* string)
00200 {
00201 int space, remainder;
00202 plugin_t *plugin;
00203
00204 space = find_first_space(string);
00205 remainder = strlen(string) - space - 1;
00206 plugin = top_plugin;
00207
00208 while (plugin) {
00209 if (plugin->name && strncmp(plugin->name, string, space)==0) {
00210 if (plugin->args)
00211 if (strncmp(plugin->args, string+space+1, remainder)!=0) {
00212 plugin = plugin->next;
00213 continue;
00214 }
00215 return TRUE;
00216 }
00217 plugin = plugin->next;
00218 }
00219
00220 return FALSE;
00221 }
00222
00223
00227 void init_name_args(plugin_t** plugin, const rule_t* rule, rule_type_t type)
00228 {
00229 int space, remainder;
00230 const char* string;
00231
00232 switch (type) {
00233 case STATE:
00234 string = rule->state;
00235 break;
00236 case TRUE_BRANCH:
00237 string = rule->true_branch;
00238 break;
00239 case FALSE_BRANCH:
00240 string = rule->false_branch;
00241 break;
00242 default:
00243 warning(PDL_ERROR, "init_name_args: unknown type!");
00244 return;
00245 }
00246
00247 lcmaps_log_debug(1, " init_name_args: processing: %s\n", string);
00248
00249 if (!string || plugin_exists(string)) {
00250 lcmaps_log_debug(1, " init_name_args: Either the plugin exists or string == 0.\n");
00251 return;
00252 }
00253
00254 lcmaps_log_debug(1, " init_name_args: plugin does not exists.\n");
00255
00256 if (!top_plugin) {
00257 top_plugin = (plugin_t*)malloc(sizeof(plugin_t));
00258 *plugin = top_plugin;
00259 }
00260 else {
00261 (*plugin)->next = (plugin_t*)malloc(sizeof(plugin_t));
00262 *plugin = (*plugin)->next;
00263 }
00264
00265 (*plugin)->name = (*plugin)->args = 0;
00266 (*plugin)->next = 0;
00267
00268 space = find_first_space(string);
00269
00270 lcmaps_log_debug(1, " init_name_args: space found a pos: %d strlen = %d.\n", space, strlen(string));
00271
00272 (*plugin)->name = (char *)malloc(space+1);
00273 strncpy((*plugin)->name, string, space);
00274 *((*plugin)->name+space) = '\0';
00275
00276 remainder = strlen(string)-space-1;
00277 if (remainder > 0) {
00278 (*plugin)->args = (char *)malloc(remainder+1);
00279 strncpy((*plugin)->args, string+space+1, remainder);
00280 *((*plugin)->args+remainder) = '\0';
00281 } else
00282 (*plugin)->args = 0;
00283
00284 (*plugin)->lineno = rule->lineno;
00285 (*plugin)->next = 0;
00286
00287 lcmaps_log_debug(1, " init_name_args: plugin->name = %s\n", (*plugin)->name);
00288 lcmaps_log_debug(1, " init_name_args: plugin->args = %s\n", (*plugin)->args);
00289 }
00290
00291
00301 int find_first_space(const char* string)
00302 {
00303 int space, max_length;
00304 space = 0;
00305 max_length = strlen(string);
00306
00307 for (; *string++ != ' ' && space < max_length; ++space);
00308
00309 return space;
00310 }
00311
00312
00318 const char *pdl_path(void)
00319 {
00320 return path;
00321 };
00322
00323
00331 int yyerror(const char* s)
00332 {
00333
00334
00335 warning(PDL_ERROR, s);
00336
00337 return 0;
00338 }
00339
00340
00348 void set_path(record_t* path)
00349 {
00350 _set_path(path);
00351
00352 free(path->string);
00353 free(path);
00354 }
00355
00356
00365 void _set_path(const record_t* _path)
00366 {
00367
00368
00369 if (!default_path) {
00370 warning(PDL_ERROR, "path already defined in: %d; ignoring this instance.", path_lineno);
00371 return;
00372 }
00373
00374 default_path = FALSE;
00375 path_lineno = _path->lineno;
00376 path = strdup(_path->string);
00377 }
00378
00379
00380
00384 void free_path(void)
00385 {
00386 if (!default_path && path) {
00387 free((char*)path);
00388 default_path = TRUE;
00389 path = 0;
00390 }
00391 }
00392
00393
00394
00405 record_t* concat_strings(record_t* s1, record_t* s2)
00406 {
00407 record_t* r = _concat_strings(s1, s2, 0);
00408
00409 free(s1->string);
00410 free(s2->string);
00411 free(s1);
00412 free(s2);
00413
00414 return r;
00415 }
00416
00417
00426 record_t* _concat_strings(const record_t* s1, const record_t* s2,
00427 const char* extra)
00428 {
00429 int len = strlen(s1->string);
00430 int len_extra = extra ? strlen(extra) : 0;
00431
00432 record_t* record = (record_t *)malloc(sizeof(record_t));
00433
00434 if (!(record->string = (char *)malloc(len + len_extra + strlen(s2->string)+1))) {
00435 warning(PDL_ERROR, "out of memory");
00436 return 0;
00437 }
00438
00439 strcpy(record->string, s1->string);
00440 if (extra)
00441 strcpy(record->string+len, extra);
00442 strcpy(record->string+len+len_extra, s2->string);
00443
00444
00445
00446 return record;
00447 }
00448
00449
00460 record_t* concat_strings_with_space(record_t* s1, record_t* s2)
00461 {
00462 record_t* r;
00463
00464
00465 if (strlen(s2->string)!=0) {
00466
00467
00468
00469
00470 if ((s1->string[strlen(s1->string)-1]=='"') &&
00471 (s2->string[strlen(s2->string)-1]=='"'))
00472 r = _concat_strings(s1, s2, 0);
00473 else
00474 r = _concat_strings(s1, s2, " ");
00475
00476 free(s1->string);
00477 free(s2->string);
00478 free(s1);
00479 free(s2);
00480 } else {
00481
00482
00483
00484
00485 r = (record_t*)malloc(sizeof(r));
00486 memcpy(r, s1, sizeof(r));
00487 }
00488
00489 return r;
00490 }
00491
00492
00510 const char* pdl_next_plugin(plugin_status_t status)
00511 {
00512 char* string = 0;
00513 const char* state = 0;
00514
00515 switch (status) {
00516 case EVALUATION_START:
00517
00518 if (!(current_policy = get_policies()))
00519 return 0;
00520 if (!(current_rule = current_policy->rule))
00521 return 0;
00522
00523 state = current_rule->state;
00524 break;
00525
00526 case EVALUATION_SUCCESS:
00527 if (current_rule)
00528 state = current_rule->true_branch;
00529
00530 if (current_policy && state)
00531 current_rule = find_state(current_policy->rule, state);
00532 else
00533 current_rule = 0;
00534 break;
00535
00536 case EVALUATION_FAILURE:
00537
00538
00539
00540
00541
00542
00543
00544
00545
00546
00547
00548
00549
00550
00551 if (current_rule)
00552 state = current_rule->false_branch;
00553
00554
00555
00556
00557
00558
00559
00560
00561
00562 if (!(current_rule && state)) {
00563 if (current_policy && (current_policy = current_policy->next)) {
00564 if ((current_rule = current_policy->rule)) {
00565 int rc;
00566 state = current_rule->state;
00567 lcmaps_log_debug(1, "evaluationmanager: Resetting credential data for policy: %s\n", current_policy->name);
00568 rc = resetCredentialData();
00569
00570 if (rc) {
00571 warning(PDL_ERROR, "Resetting credential data failed: rc = %d", rc);
00572 return 0;
00573 }
00574 }
00575 }
00576 } else {
00577
00578 if (current_policy)
00579 current_rule = find_state(current_policy->rule, state);
00580 }
00581
00582 break;
00583 }
00584
00585
00586
00587
00588
00589
00590
00591 if (state) {
00592 const char* tmp;
00593 int state_length, path_length;
00594
00595 tmp = state;
00596 state_length = path_length = 0;
00597
00598 while (*tmp!=' ' && *tmp++!='\0') {
00599 ++state_length;
00600 }
00601 path_length = strlen(pdl_path());
00602
00603
00604 string = (char*)malloc(state_length + path_length + 2);
00605 strcpy(string, pdl_path());
00606
00607
00608 if (string[path_length-1] != '/')
00609 string[path_length++] = '/';
00610 strncpy(string + path_length, state, state_length);
00611 string[path_length + state_length] = '\0';
00612 }
00613
00614 return string;
00615 }
00616
00617
00622 void free_resources(void)
00623 {
00624 if (script_name) {
00625 free((char*)script_name);
00626 script_name = 0;
00627 }
00628
00629 free_path();
00630
00631 free_variables();
00632 free_policies();
00633
00634
00635
00636
00637
00638
00639 if (yyin!=stdin && yyin!=stderr) {
00640 fclose(yyin);
00641 yyin=stdin;
00642 }
00643
00644 #ifdef HAVE_FLEX
00645 delete_lex_buffer();
00646 #endif
00647 }
00648
00649
00658 void warning(pdl_error_t error, const char* s, ...)
00659 {
00660 static char* level = 0;
00661 char buf[2048];
00662 int res;
00663
00664 va_list args;
00665
00666 if (error == PDL_ERROR)
00667 parse_error = TRUE;
00668
00669 if (!level)
00670 level = level_str[PDL_UNKNOWN];
00671
00672 if (error != PDL_SAME)
00673 level = level_str[error];
00674
00675
00676
00677
00678
00679 res = sprintf(buf, "%s:%d: [%s] ", script_name, lineno, level);
00680
00681
00682 va_start(args, s);
00683 res += vsnprintf(buf+res, sizeof(buf)-res-2, s, args);
00684 va_end(args);
00685
00686
00687
00688
00689
00690
00691 buf[res<sizeof(buf)-1 ? res++ : sizeof(buf)-2] = '\n';
00692 buf[res<sizeof(buf) ? res : sizeof(buf)-1] = '\0';
00693
00694 lcmaps_log(0, buf);
00695 }
00696