void trace_tree_emit_rule(struct xswitch *sw, struct trace_tree *tree) { struct match *ma = match(); struct action *ac_pi = action(); action_add(ac_pi, AC_PACKET_IN, 0); emit_rule(sw, sw->table0, tree, ma, 1, ac_pi); action_free(ac_pi); match_free(ma); }
bool trans_set_action(Transition *trans, struct r_action *action){ // TODO Check shell value for an existing shell (?) // TODO Check uid for an existing user (?) bool success = true; action_free(trans->raction); trans->raction = action; end: return success; }
static void logfile_free(Logfile *self) { if (self->file) fclose(self->file); action_free(self->first); free(self->baseName); free(self->dirName); free(self->name); free(self); }
void freeactions( ACTIONS * chain ) { while ( chain ) { ACTIONS * n = chain->next; action_free( chain->action ); BJAM_FREE( chain ); chain = n; } }
static int json_printer_ft1(char *buf, int pos, struct trace_tree *tree) { int i; int priority; struct trace_tree_V *tv; struct trace_tree_T *tt; struct trace_tree_D *td; struct trace_tree_G *tg; struct match *ma; struct action *ac_pi; switch(tree->type) { case TT_L: case TT_E: return pos; case TT_D: td = (struct trace_tree_D *)tree; return json_printer_ft1(buf, pos, td->t); case TT_V: tv = (struct trace_tree_V *)tree; for(i = 0; i < tv->num_branches; i++) { pos = json_printer_ft1(buf, pos, tv->branches[i].tree); } return pos; case TT_T: tt = (struct trace_tree_T *)tree; pos = json_printer_ft1(buf, pos, tt->f); pos = json_printer_ft1(buf, pos, tt->t); return pos; case TT_G: tg = (struct trace_tree_G *)tree; priority = 0; ac_pi = action(); action_add(ac_pi, AC_PACKET_IN, 0); ma = match(); pos += sprintf(buf+pos, "{\"tid\":\"%d\",", flow_table_get_tid(tg->ft)); pos += sprintf(buf+pos, "\"columns\":[\"priority\",\"in_port\","); pos += header_print_json(tg->new_spec, buf+pos); if(buf[pos-1] == ',') pos--; pos += sprintf(buf+pos, ",\"actions\"],"); pos += sprintf(buf+pos, "\"data\":["); pos = json_printer_ft(buf, pos, tg->t, ma, &priority, ac_pi, tg->new_spec); if(buf[pos-1] == ',') pos--; pos += sprintf(buf+pos, "]},"); action_free(ac_pi); match_free(ma); pos = json_printer_ft1(buf, pos, tg->t); return pos; } assert(0); }
/*----------------------------------------------------------------------------*/ static void purge_actions(list_t actions) { action_t *e; action_t *next; for(e = list_head(actions); e != NULL;) { next = e->next; action_free(e); e = next; } }
Transition* trans_clist_free_1(struct reactor_d *reactor, Transition *trans){ Transition *ret; if(trans == NULL) return NULL; if(trans->enrequisites != NULL) reactor_slist_foreach(trans->enrequisites, en_remove_one_curr_trans, trans); while(trans->enrequisites != NULL){ en_unref(reactor, trans->enrequisites->data); trans->enrequisites = reactor_slist_delete_link(trans->enrequisites, trans->enrequisites); } ret = trans_clist_remove_link(trans); state_unref(reactor, trans->dest); action_free(trans->raction); free(trans); return ret; }
/* helper */ static void init_entry(struct xswitch *sw, struct flow_table *ft) { struct match *ma; struct msgbuf *msg; struct action *ac; int index; ma = match(); ac = action(); action_add(ac, AC_PACKET_IN, 0); index = flow_table_get_entry_index(ft); assert(index == 0); msg = msg_flow_entry_add(ft, index, 0, ma, ac); match_free(ma); action_free(ac); xswitch_send(sw, msg); }
/* destructor */ void trace_tree_free(struct trace_tree *t) { int i; struct trace_tree_V *tv; struct trace_tree_T *tt; struct trace_tree_L *tl; struct trace_tree_D *td; struct trace_tree_G *tg; switch(t->type) { case TT_E: free(t); break; case TT_L: tl = (struct trace_tree_L *)t; action_free(tl->ac); free(t); break; case TT_V: tv = (struct trace_tree_V *)t; for(i = 0; i < tv->num_branches; i++) trace_tree_free(tv->branches[i].tree); free(t); break; case TT_T: tt = (struct trace_tree_T *)t; trace_tree_free(tt->t); trace_tree_free(tt->f); free(t); break; case TT_D: td = (struct trace_tree_D *)t; trace_tree_free(td->t); free(t); break; case TT_G: tg = (struct trace_tree_G *)t; trace_tree_free(tg->t); if(tg->ft) flow_table_free(tg->ft); free(t); break; } }
void * action_thread_main_loop (void *c) { ldap_context_t *context = c; action_t *action = NULL; int rc; int loop = 1; while( loop ){ action = action_pop(context->action_list); /* handle action */ if (action){ switch (action->type){ case LDAP_AUTH_ACTION_AUTH: if( DOINFO(context->verb ) ){ LOGINFO ( "Authentication requested for user %s", ((auth_context_t *)action->context)->username); } rc = la_ldap_handle_authentication( context, action ); /* we need to write the result to auth_control_file */ if( DODEBUG(context->verb ) ){ LOGDEBUG( "User %s: Writing %c to auth_control_file %s", ((auth_context_t *)action->context)->username, rc == OPENVPN_PLUGIN_FUNC_SUCCESS ? '1' : '0', ((auth_context_t *)action->context)->auth_control_file); } write_to_auth_control_file ( ((auth_context_t *)action->context)->auth_control_file, rc == OPENVPN_PLUGIN_FUNC_SUCCESS ? '1' : '0'); break; case LDAP_AUTH_ACTION_QUIT: if( DOINFO(context->verb ) ){ LOGINFO( "Authentication thread received ACTION_QUIT\n"); } loop = 0; break; default: LOGWARNING( "%s:%d %s() Unknown action %d", __FILE__, __LINE__, __FUNCTION__, action->type); } action_free( action ); } } pthread_exit (NULL); }
END_TEST START_TEST(test_parser_cmd_rule){ struct r_rule *rule; struct rr_obj *fromobj, *toobj, *eventsobj, *actionobj; struct r_action *action; struct cmd_action *cmdaction; char *line; line = "STATE_A STATE_B event1& event2 &event3& event4 CMD echo \"test\" >> /tmp/test"; rule = r_rule_parse(line); fail_unless(rule != NULL); fail_unless(rule->errors == NULL); fail_unless((fromobj = get_rule_obj(rule->objs, RULE_FROM)) != NULL); fail_unless(strcmp((char *)fromobj->data, "STATE_A") == 0); fail_unless((toobj = get_rule_obj(rule->objs, RULE_TO)) != NULL); fail_unless(strcmp((char *)toobj->data, "STATE_B") == 0); fail_unless((eventsobj = get_rule_obj(rule->objs, RULE_EVENTS)) != NULL); fail_unless(eventsobj->down != NULL); fail_unless(get_rule_obj(eventsobj->down, 0) != NULL); fail_unless(strcmp((char *)(get_rule_obj(eventsobj->down, 0))->data, "event1") == 0); fail_unless(get_rule_obj(eventsobj->down, 1) != NULL); fail_unless(strcmp((char *)(get_rule_obj(eventsobj->down, 1))->data, "event2") == 0); fail_unless(get_rule_obj(eventsobj->down, 2) != NULL); fail_unless(strcmp((char *)(get_rule_obj(eventsobj->down, 2))->data, "event3") == 0); fail_unless(get_rule_obj(eventsobj->down, 3) != NULL); fail_unless(strcmp((char *)(get_rule_obj(eventsobj->down, 3))->data, "event4") == 0); fail_unless((actionobj = get_rule_obj(rule->objs, RULE_RACTION)) != NULL); fail_unless((action = (struct r_action *) actionobj->data) != NULL); fail_unless(actionobj->next == NULL); fail_unless(actionobj->down == NULL); fail_unless(action->atype == CMD); cmdaction = (struct cmd_action *)action->action; fail_unless(strcmp(cmdaction->cmd, "echo \"test\" >> /tmp/test") == 0); action_free(actionobj->data); actionobj->data = NULL; rule_objs_free(actionobj); actionobj = NULL; eventsobj->next = NULL; rules_free(rule); line = "STATE_A STATE_B event1& event2 &event3& event4 CMD"; rule = r_rule_parse(line); fail_unless(rule != NULL); fail_unless(rule->errors != NULL); fail_unless(rule->objs == NULL); }
END_TEST START_TEST(test_parser_none_rule){ struct r_rule *rule; struct rr_obj *fromobj, *toobj, *eventsobj, *actionobj; struct r_action *action; char *line = "STATE_A STATE_B event1"; rule = r_rule_parse(line); fail_unless(rule != NULL); fail_unless(rule->errors == NULL); fail_unless((fromobj = get_rule_obj(rule->objs, RULE_FROM)) != NULL); fail_unless(strcmp((char *)fromobj->data, "STATE_A") == 0); fail_unless((toobj = get_rule_obj(rule->objs, RULE_TO)) != NULL); fail_unless(strcmp((char *)toobj->data, "STATE_B") == 0); fail_unless((eventsobj = get_rule_obj(rule->objs, RULE_EVENTS)) != NULL); fail_unless(eventsobj->down != NULL); fail_unless(get_rule_obj(eventsobj->down, 0) != NULL); fail_unless(strcmp((char *)(get_rule_obj(eventsobj->down, 0))->data, "event1") == 0); fail_unless((get_rule_obj(eventsobj->down, 0))->next == NULL); fail_unless((get_rule_obj(eventsobj->down, 0))->down == NULL); fail_unless((actionobj = get_rule_obj(rule->objs, RULE_RACTION)) != NULL); fail_unless((action = (struct r_action *) actionobj->data) != NULL); fail_unless(actionobj->next == NULL); fail_unless(actionobj->down == NULL); fail_unless(action->atype == NONE); action_free(actionobj->data); actionobj->data = NULL; rule_objs_free(actionobj); actionobj = NULL; eventsobj->next = NULL; rules_free(rule); line = "STATE_A STATE_B event1 NONE"; rule = r_rule_parse(line); fail_unless(rule != NULL); fail_unless(rule->errors == NULL); fail_unless((fromobj = get_rule_obj(rule->objs, RULE_FROM)) != NULL); fail_unless(strcmp((char *)fromobj->data, "STATE_A") == 0); fail_unless((toobj = get_rule_obj(rule->objs, RULE_TO)) != NULL); fail_unless(strcmp((char *)toobj->data, "STATE_B") == 0); fail_unless((eventsobj = get_rule_obj(rule->objs, RULE_EVENTS)) != NULL); fail_unless(eventsobj->down != NULL); fail_unless(get_rule_obj(eventsobj->down, 0) != NULL); fail_unless(strcmp((char *)(get_rule_obj(eventsobj->down, 0))->data, "event1") == 0); fail_unless((get_rule_obj(eventsobj->down, 0))->next == NULL); fail_unless((get_rule_obj(eventsobj->down, 0))->down == NULL); fail_unless((actionobj = get_rule_obj(rule->objs, RULE_RACTION)) != NULL); fail_unless((action = (struct r_action *) actionobj->data) != NULL); fail_unless(actionobj->next == NULL); fail_unless(actionobj->down == NULL); fail_unless(action->atype == NONE); action_free(actionobj->data); actionobj->data = NULL; rule_objs_free(actionobj); actionobj = NULL; eventsobj->next = NULL; rules_free(rule); line = "STATE_A STATE_B event1 NONE this shouldn't be here"; rule = r_rule_parse(line); fail_unless(rule != NULL); fail_unless(rule->errors != NULL); fail_unless(rule->objs == NULL); rules_free(rule); }
static int emit_rule(struct xswitch *sw, struct flow_table *ft, struct trace_tree *tree, struct match *ma, int priority, struct action *ac_pi) { int i; struct trace_tree_L *tl; struct trace_tree_V *tv; struct trace_tree_T *tt; struct trace_tree_D *td; struct trace_tree_G *tg; struct msgbuf *msg; struct match *maa; struct action *a; char buf[128], buf2[128]; struct expr *move_expr; switch(tree->type) { case TT_L: tl = (struct trace_tree_L *)tree; match_dump(ma, buf, 128); action_dump(tl->ac, buf2, 128); xdebug("tid %d: %2d, %s, %s\n", flow_table_get_tid(ft), priority, buf, buf2); if(tl->index == -1) { tl->index = flow_table_get_entry_index(ft); msg = msg_flow_entry_add(ft, tl->index, priority, ma, tl->ac); } else { msg = msg_flow_entry_mod(ft, tl->index, priority, ma, tl->ac); } xswitch_send(sw, msg); return priority + 1; case TT_V: tv = (struct trace_tree_V *)tree; for(i = 0; i < tv->num_branches; i++) { maa = match_copy(ma); match_add(maa, tv->name, tv->branches[i].value, value_from_64(0xffffffffffffffffull)); priority = emit_rule(sw, ft, tv->branches[i].tree, maa, priority, ac_pi); match_free(maa); } return priority; case TT_T: tt = (struct trace_tree_T *)tree; priority = emit_rule(sw, ft, tt->f, ma, priority, ac_pi); maa = match_copy(ma); match_add(maa, tt->name, tt->value, value_from_64(0xffffffffffffffffull)); action_dump(ac_pi, buf, 128); xdebug("tid %d: %2d, BARRIER, %s\n", flow_table_get_tid(ft), priority, buf); if(tt->barrier_index == -1) { tt->barrier_index = flow_table_get_entry_index(ft); msg = msg_flow_entry_add(ft, tt->barrier_index, priority, maa, ac_pi); } else { msg = msg_flow_entry_mod(ft, tt->barrier_index, priority, maa, ac_pi); } xswitch_send(sw, msg); priority = emit_rule(sw, ft, tt->t, maa, priority + 1, ac_pi); match_free(maa); return priority; case TT_G: tg = (struct trace_tree_G *)tree; if(tg->ft == NULL) { int tid = sw->next_table_id++; // add a new table tg->ft = header_make_flow_table(tg->new_spec, tid); msg = msg_flow_table_add(tg->ft); xswitch_send(sw, msg); init_entry(sw, tg->ft); } // insert GOTO_TABLE into orig table a = action(); if(tg->old_spec) move_expr = header_get_length(tg->old_spec); else move_expr = expr_value(0); expr_generate_action(move_expr, tg->old_spec, tg->ft, tg->stack_base, a); match_dump(ma, buf, 128); action_dump(a, buf2, 128); xdebug("tid %d: %2d, %s, %s\n", flow_table_get_tid(ft), priority, buf, buf2); if(tg->index == -1) { tg->index = flow_table_get_entry_index(ft); msg = msg_flow_entry_add(ft, tg->index, priority, ma, a); } else { msg = msg_flow_entry_mod(ft, tg->index, priority, ma, a); } xswitch_send(sw, msg); action_free(a); maa = match(); emit_rule(sw, tg->ft, tg->t, maa, 1, ac_pi); match_free(maa); return priority + 1; case TT_D: td = (struct trace_tree_D *)tree; return emit_rule(sw, ft, td->t, ma, priority, ac_pi); case TT_E: return priority; } assert(0); }
static int json_printer_ft(char *buf, int pos, struct trace_tree *tree, struct match *ma, int *priority, struct action *ac_pi, struct header *h) { int i; struct trace_tree_L *tl; struct trace_tree_V *tv; struct trace_tree_T *tt; struct trace_tree_D *td; struct trace_tree_G *tg; struct match *maa; struct action *a; char buf2[128]; struct expr *move_expr; switch(tree->type) { case TT_L: tl = (struct trace_tree_L *)tree; pos = json_printer_fe(buf, pos, *priority, h, ma, tl->ac); (*priority)++; return pos; case TT_V: tv = (struct trace_tree_V *)tree; for(i = 0; i < tv->num_branches; i++) { maa = match_copy(ma); match_add(maa, tv->name, tv->branches[i].value, value_from_64(0xffffffffffffffffull)); pos = json_printer_ft(buf, pos, tv->branches[i].tree, maa, priority, ac_pi, h); match_free(maa); } return pos; case TT_T: tt = (struct trace_tree_T *)tree; pos = json_printer_ft(buf, pos, tt->f, ma, priority, ac_pi, h); maa = match_copy(ma); match_add(maa, tt->name, tt->value, value_from_64(0xffffffffffffffffull)); pos = json_printer_fe(buf, pos, *priority, h, maa, ac_pi); (*priority)++; pos = json_printer_ft(buf, pos, tt->t, maa, priority, ac_pi, h); match_free(maa); return pos; case TT_G: tg = (struct trace_tree_G *)tree; // insert GOTO_TABLE into orig table a = action(); if(tg->old_spec) move_expr = header_get_length(tg->old_spec); else move_expr = expr_value(0); expr_generate_action(move_expr, tg->old_spec, tg->ft, tg->stack_base, a); action_dump(a, buf2, 128); pos = json_printer_fe(buf, pos, *priority, h, ma, a); action_free(a); (*priority)++; return pos; case TT_D: td = (struct trace_tree_D *)tree; return json_printer_ft(buf, pos, td->t, ma, priority, ac_pi, h); case TT_E: return pos; } assert(0); }
static Logfile * logfile_new(const CfgLog *cl) { struct stat st; int fd; char *realName; Logfile *curr; char *tmp, *baseName, *dirName; Logfile *self = NULL; Action *action = createActions(cl); if (!action) { /* a logfile without actions doesn't have to be watched */ Daemon_printf_level(LEVEL_WARNING, "Ignoring `%s' without actions.", cfgLog_name(cl)); return NULL; } /* calculate paths */ tmp = lladCloneString(cfgLog_name(cl)); baseName = basename(tmp); dirName = realpath(dirname(tmp), NULL); if (!dirName) { /* at least the directory has to exist */ Daemon_printf_level(LEVEL_WARNING, "Can't get real directory of `%s': %s", tmp, strerror(errno)); free(tmp); action_free(action); return NULL; } if (stat(dirName, &st) < 0) { /* and the directory has to be accessible */ Daemon_printf_level(LEVEL_WARNING, "Could not stat `%s': %s", dirName, strerror(errno)); free(dirName); free(tmp); action_free(action); return NULL; } if (!S_ISDIR(st.st_mode)) { /* and it has to actually BE a directory */ Daemon_printf_level(LEVEL_WARNING, "%s: Not a directory", dirName); free(dirName); free(tmp); action_free(action); return NULL; } /* determine canonical path name */ realName = lladAlloc(strlen(dirName) + strlen(baseName) + 2); strcpy(realName, dirName); strcat(realName, "/"); strcat(realName, baseName); /* check whether this logfile is already in the list */ curr = firstLog; while (curr) { if (!strcmp(curr->name, realName)) { /* if it is, append actions there */ free(realName); free(dirName); free(tmp); if (curr->first) { action_append(curr->first, action); } else { curr->first = action; } return NULL; } curr = curr->next; } /* otherwise, create new Logfile object */ self = lladAlloc(sizeof(Logfile)); self->name = realName; self->dirName = dirName; self->baseName = lladCloneString(baseName); free(tmp); self->file = NULL; /* try to open it directly for reading */ if ((self->file = fopen(self->name, "r"))) { fd = fileno(self->file); fcntl(fd, F_SETFL, fcntl(fd, F_GETFL, 0) | O_NONBLOCK); fseeko(self->file, 0L, SEEK_END); } else { /* it's ok if this isn't possible -- the directory should be watched * and maybe we can open it later */ Daemon_printf_level(LEVEL_NOTICE, "Could not open `%s': %s", self->name, strerror(errno)); } self->next = NULL; self->first = action; return self; }