00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00041 #include <stdarg.h>
00042 #include <stdio.h>
00043 #include <stdlib.h>
00044 #include <string.h>
00045
00046 #include "_lcmaps_pluginmanager.h"
00047 #include "lcmaps_log.h"
00048 #include "pdl.h"
00049 #include "pdl_variable.h"
00050 #include "pdl_policy.h"
00051 #include "pdl_rule.h"
00052
00053 static const char* script_name = NULL;
00054 static const char* d_path = "/usr/lib";
00055 static const char* path = 0;
00056 static int path_lineno = 0;
00057 static plugin_t* top_plugin = NULL;
00058 static BOOL default_path = TRUE;
00059 static BOOL parse_error = FALSE;
00060 static char* level_str[PDL_SAME];
00061
00062 static const policy_t* current_policy = 0;
00063 static const rule_t* current_rule = 0;
00064
00065 unsigned int lineno = 1;
00066
00067 void _set_path(const record_t* _path);
00068 record_t* _concat_strings(const record_t* s1, const record_t* s2, const char* extra);
00069 void reduce_policies(void);
00070 void init_name_args(plugin_t** plugin, const rule_t* rule, rule_type_t type);
00071 BOOL plugin_exists(const char* string);
00072 int find_first_space(const char* string);
00073
00074
00079 const policy_t* get_current_policy(void)
00080 {
00081 return current_policy;
00082 }
00083
00093 int pdl_init(const char* name)
00094 {
00095 if (name) {
00096 FILE* file;
00097
00098 script_name = strdup(name);
00099
00100 file = fopen(name, "r");
00101 if (file)
00102 yyin = file;
00103 else {
00104 warning(PDL_ERROR, "Could not open file '%s'.", name);
00105 return -1;
00106 }
00107 }
00108
00109
00110 path = d_path;
00111 default_path = TRUE;
00112
00113
00114
00115
00116
00117 if (top_plugin) free_plugins(&top_plugin);
00118
00119
00120
00121
00122
00123
00124
00125 level_str[PDL_INFO] = "info";
00126 level_str[PDL_WARNING] = "warning";
00127 level_str[PDL_ERROR] = "error";
00128 level_str[PDL_UNKNOWN] = "<unknown>";
00129
00130 parse_error = FALSE;
00131
00132 return 0;
00133 }
00134
00135
00142 int yyparse_errors(void)
00143 {
00144 return parse_error ? -1 : 0;
00145 }
00146
00147
00154 const plugin_t* get_plugins(void)
00155 {
00156 plugin_t* plugin;
00157 policy_t* policy;
00158
00159
00160
00161
00162
00163
00164 if (!policies_have_been_reduced()) {
00165 lcmaps_log(1, "The policies have not been reduced. Probably the startElevaluationManager has failed or has not been called yet.\n");
00166 return 0;
00167 }
00168
00169
00170
00171
00172
00173 if (top_plugin)
00174 return top_plugin;
00175
00176 policy = get_policies();
00177
00178 while (policy) {
00179 rule_t* rule = policy->rule;
00180
00181 lcmaps_log_debug(1, "processing policy: %s\n", policy->name);
00182 while (rule) {
00183 lcmaps_log_debug(1, " processing rule: %s -> %s | %s\n", rule->state, rule->true_branch, rule->false_branch);
00184
00185 lcmaps_log_debug(1, " get_plugins: initializing...\n");
00186 init_name_args(&plugin, rule, STATE);
00187 init_name_args(&plugin, rule, TRUE_BRANCH);
00188 init_name_args(&plugin, rule, FALSE_BRANCH);
00189 lcmaps_log_debug(1, " get_plugins: initializing done.\n");
00190
00191 rule = rule->next;
00192 }
00193 policy = policy->next;
00194 }
00195
00196 return top_plugin;
00197 }
00198
00209 int free_plugins(
00210 plugin_t ** list
00211 )
00212 {
00213 plugin_t * p_list = NULL;
00214 plugin_t * tmp_p_list = NULL;
00215
00216 p_list = *list;
00217 while (p_list) {
00218 tmp_p_list = p_list->next;
00219
00220 lcmaps_log_debug(3, "freeing plugin %s at address %p\n", p_list->name, p_list);
00221 if (p_list->name){
00222 free(p_list->name);
00223 p_list->name = NULL;
00224 }
00225 if (p_list->args){
00226 free(p_list->args);
00227 p_list->args = NULL;
00228 }
00229 p_list->next = NULL;
00230 free((plugin_t*)p_list);
00231
00232 p_list = tmp_p_list;
00233 }
00234 *list=p_list=NULL;
00235 return 0;
00236 }
00237
00245 BOOL plugin_exists(const char* string)
00246 {
00247 int space, remainder;
00248 plugin_t *plugin;
00249
00250 space = find_first_space(string);
00251 remainder = strlen(string) - space - 1;
00252 plugin = top_plugin;
00253
00254 while (plugin) {
00255 if (plugin->name && strncmp(plugin->name, string, space)==0) {
00256 if (plugin->args)
00257 if (strncmp(plugin->args, string+space+1, remainder)!=0) {
00258 plugin = plugin->next;
00259 continue;
00260 }
00261 return TRUE;
00262 }
00263 plugin = plugin->next;
00264 }
00265
00266 return FALSE;
00267 }
00268
00269
00273 void init_name_args(plugin_t** plugin, const rule_t* rule, rule_type_t type)
00274 {
00275 int space, remainder;
00276 const char* string;
00277
00278 switch (type) {
00279 case STATE:
00280 string = rule->state;
00281 break;
00282 case TRUE_BRANCH:
00283 string = rule->true_branch;
00284 break;
00285 case FALSE_BRANCH:
00286 string = rule->false_branch;
00287 break;
00288 default:
00289 warning(PDL_ERROR, "init_name_args: unknown type!");
00290 return;
00291 }
00292
00293 lcmaps_log_debug(1, " init_name_args: processing: %s\n", string);
00294
00295 if (!string || plugin_exists(string)) {
00296 lcmaps_log_debug(1, " init_name_args: Either the plugin exists or string == 0.\n");
00297 return;
00298 }
00299
00300 lcmaps_log_debug(1, " init_name_args: plugin does not exists.\n");
00301
00302 if (!top_plugin) {
00303 top_plugin = (plugin_t*)malloc(sizeof(plugin_t));
00304 *plugin = top_plugin;
00305 }
00306 else {
00307 (*plugin)->next = (plugin_t*)malloc(sizeof(plugin_t));
00308 *plugin = (*plugin)->next;
00309 }
00310
00311 (*plugin)->name = (*plugin)->args = 0;
00312 (*plugin)->next = 0;
00313
00314 space = find_first_space(string);
00315
00316 lcmaps_log_debug(1, " init_name_args: space found a pos: %d strlen = %d.\n", space, strlen(string));
00317
00318 (*plugin)->name = (char *)malloc(space+1);
00319 strncpy((*plugin)->name, string, space);
00320 *((*plugin)->name+space) = '\0';
00321
00322 remainder = strlen(string)-space-1;
00323 if (remainder > 0) {
00324 (*plugin)->args = (char *)malloc(remainder+1);
00325 strncpy((*plugin)->args, string+space+1, remainder);
00326 *((*plugin)->args+remainder) = '\0';
00327 } else
00328 (*plugin)->args = 0;
00329
00330 (*plugin)->lineno = rule->lineno;
00331 (*plugin)->next = 0;
00332
00333 lcmaps_log_debug(1, " init_name_args: plugin->name = %s\n", (*plugin)->name);
00334 lcmaps_log_debug(1, " init_name_args: plugin->args = %s\n", (*plugin)->args);
00335 }
00336
00337
00347 int find_first_space(const char* string)
00348 {
00349 int space, max_length;
00350 space = 0;
00351 max_length = strlen(string);
00352
00353 for (; *string++ != ' ' && space < max_length; ++space);
00354
00355 return space;
00356 }
00357
00358
00364 const char *pdl_path(void)
00365 {
00366 return path;
00367 };
00368
00369
00377 int yyerror(const char* s)
00378 {
00379
00380
00381 warning(PDL_ERROR, s);
00382
00383 return 0;
00384 }
00385
00386
00394 void set_path(record_t* path)
00395 {
00396 _set_path(path);
00397
00398 free(path->string);
00399 free(path);
00400 }
00401
00402
00411 void _set_path(const record_t* _path)
00412 {
00413
00414
00415 if (!default_path) {
00416 warning(PDL_ERROR, "path already defined in: %d; ignoring this instance.", path_lineno);
00417 return;
00418 }
00419
00420 default_path = FALSE;
00421 path_lineno = _path->lineno;
00422 path = strdup(_path->string);
00423 }
00424
00425
00426
00430 void free_path(void)
00431 {
00432 if (!default_path && path) {
00433 free((char*)path);
00434 default_path = TRUE;
00435 path = 0;
00436 }
00437 }
00438
00439
00440
00451 record_t* concat_strings(record_t* s1, record_t* s2)
00452 {
00453 record_t* r = _concat_strings(s1, s2, 0);
00454
00455 free(s1->string);
00456 free(s2->string);
00457 free(s1);
00458 free(s2);
00459
00460 return r;
00461 }
00462
00463
00473 record_t* _concat_strings(const record_t* s1, const record_t* s2,
00474 const char* extra)
00475 {
00476 int len = strlen(s1->string);
00477 int len_extra = extra ? strlen(extra) : 0;
00478
00479 record_t* record = (record_t *)malloc(sizeof(record_t));
00480
00481 if (!(record->string = (char *)malloc(len + len_extra + strlen(s2->string)+1))) {
00482 warning(PDL_ERROR, "out of memory");
00483 return 0;
00484 }
00485
00486 strcpy(record->string, s1->string);
00487 if (extra)
00488 strcpy(record->string+len, extra);
00489 strcpy(record->string+len+len_extra, s2->string);
00490
00491
00492
00493 return record;
00494 }
00495
00496
00507 record_t* concat_strings_with_space(record_t* s1, record_t* s2)
00508 {
00509 record_t* r;
00510
00511
00512 if (strlen(s2->string)!=0) {
00513
00514
00515
00516
00517 if ((s1->string[strlen(s1->string)-1]=='"') &&
00518 (s2->string[strlen(s2->string)-1]=='"'))
00519 r = _concat_strings(s1, s2, 0);
00520 else
00521 r = _concat_strings(s1, s2, " ");
00522
00523 free(s1->string);
00524 free(s2->string);
00525 free(s1);
00526 free(s2);
00527 } else {
00528
00529
00530
00531
00532 r = (record_t*)malloc(sizeof(r));
00533 memcpy(r, s1, sizeof(r));
00534 }
00535
00536 return r;
00537 }
00538
00539
00557 const char* pdl_next_plugin(plugin_status_t status)
00558 {
00559 char* string = 0;
00560 const char* state = 0;
00561
00562 switch (status) {
00563 case EVALUATION_START:
00564
00565 if (!(current_policy = get_policies()))
00566 return 0;
00567 if (!(current_rule = current_policy->rule))
00568 return 0;
00569
00570 state = current_rule->state;
00571 break;
00572
00573 case EVALUATION_SUCCESS:
00574 if (current_rule)
00575 state = current_rule->true_branch;
00576
00577 if (current_policy && state)
00578 current_rule = find_state(current_policy->rule, state);
00579 else
00580 current_rule = 0;
00581 break;
00582
00583 case EVALUATION_FAILURE:
00584
00585
00586
00587
00588
00589
00590
00591
00592
00593
00594
00595
00596
00597
00598 if (current_rule)
00599 state = current_rule->false_branch;
00600
00601
00602
00603
00604
00605
00606
00607
00608
00609 if (!(current_rule && state)) {
00610 if (current_policy && (current_policy = current_policy->next)) {
00611 if ((current_rule = current_policy->rule)) {
00612 int rc;
00613 state = current_rule->state;
00614 lcmaps_log_debug(1, "evaluationmanager: Resetting credential data for policy: %s\n", current_policy->name);
00615 rc = resetCredentialData();
00616
00617 if (rc) {
00618 warning(PDL_ERROR, "Resetting credential data failed: rc = %d", rc);
00619 return 0;
00620 }
00621 }
00622 }
00623 } else {
00624
00625 if (current_policy)
00626 current_rule = find_state(current_policy->rule, state);
00627 }
00628
00629 break;
00630 }
00631
00632
00633
00634
00635
00636
00637
00638 if (state) {
00639 const char* tmp;
00640 int state_length, path_length;
00641
00642 tmp = state;
00643 state_length = path_length = 0;
00644
00645 while (*tmp!=' ' && *tmp++!='\0') {
00646 ++state_length;
00647 }
00648 path_length = strlen(pdl_path());
00649
00650
00651 string = (char*)malloc(state_length + path_length + 2);
00652 strcpy(string, pdl_path());
00653
00654
00655 if (string[path_length-1] != '/')
00656 string[path_length++] = '/';
00657 strncpy(string + path_length, state, state_length);
00658 string[path_length + state_length] = '\0';
00659
00660 lcmaps_log_debug(1, "evaluationmanager: found plugin: %s\n", string);
00661 }
00662
00663 return string;
00664 }
00665
00666
00671 void free_resources(void)
00672 {
00673 if (script_name) {
00674 free((char*)script_name);
00675 script_name = 0;
00676 }
00677
00678 free_path();
00679
00680 free_variables();
00681 free_policies();
00682
00683 free_plugins(&top_plugin);
00684
00685
00686
00687
00688
00689
00690 if (yyin!=stdin && yyin!=stderr) {
00691 if (yyin)
00692 fclose(yyin);
00693 yyin=stdin;
00694 }
00695
00696 #ifdef HAVE_FLEX
00697 delete_lex_buffer();
00698 #endif
00699 }
00700
00701
00710 void warning(pdl_error_t error, const char* s, ...)
00711 {
00712 static char* level = 0;
00713 char buf[2048];
00714 int res;
00715
00716 va_list args;
00717
00718 if (error == PDL_ERROR)
00719 parse_error = TRUE;
00720
00721 if (!level)
00722 level = level_str[PDL_UNKNOWN];
00723
00724 if (error != PDL_SAME)
00725 level = level_str[error];
00726
00727
00728
00729
00730
00731 res = sprintf(buf, "%s:%d: [%s] ", script_name, lineno, level);
00732
00733
00734 va_start(args, s);
00735 res += vsnprintf(buf+res, sizeof(buf)-res-2, s, args);
00736 va_end(args);
00737
00738
00739
00740
00741
00742
00743 buf[res<sizeof(buf)-1 ? res++ : sizeof(buf)-2] = '\n';
00744 buf[res<sizeof(buf) ? res : sizeof(buf)-1] = '\0';
00745
00746 lcmaps_log(0, buf);
00747 }
00748