switch (expr->type) {
case S_not:
- expr_sink_internal(expr->u.not.child, membership, expr /* parent */);
+ if (expr_sink_internal(expr->u.not.child, membership, expr /* parent */))
+ return (1);
break;
case S_and:
case S_or:
- expr_sink_internal(expr->u.and_or.child_first, membership, expr /* parent */);
+ if (expr_sink_internal(expr->u.and_or.child_first, membership, expr /* parent */))
+ return (1);
break;
case S_user:
case S_group:
tac_list_node_init(&expr->eval_scan.u.entity.notify_expr_node);
expr->u.entity.entity = entity_lookup(expr->type, expr->u.entity.name);
+ if (!expr->u.entity.entity && expr->type == S_host) {
+ expr->u.entity.entity = new_entity(expr->type, (char *)expr->u.entity.name, expr->line);
+ if (!expr->u.entity.entity)
+ return (1);
+ expr->u.entity.name = NULL;
+ }
if (!expr->u.entity.entity) {
report(LOG_ERR, "referenced entity %s %s not found on line %d",
entity_type_to_string(expr->type), expr->u.entity.name, expr->line);
return (1);
- }
+ }
+ /* already NULLed for not-yet-existing S_host */
free((char *) expr->u.entity.name);
expr->u.entity.name = NULL;
break;
report(LOG_DEBUG, "expr_eval_notify_expr: REGISTERED notify " PF_EXPR " when " PF_ENTITY " is known",
PA_EXPR(expr), PA_ENTITY(entity));
- if (tac_list_node_get_list(&expr->eval_scan.u.entity.notify_expr_node))
+ if (tac_list_node_get_list(&expr->eval_scan.u.entity.notify_expr_node)) {
+#ifdef SCAN_PARANOIA
+ if (&entity->eval_scan.notify_expr_list
+ != tac_list_node_get_list(&expr->eval_scan.u.entity.notify_expr_node))
+ report(LOG_ERR, "Another " PF_ENTITY " already registered in notify node of " PF_EXPR,
+ PA_ENTITY(EXPR_ENTITY_TO_NOTIFYING_ENTITY(expr)), PA_EXPR(expr));
+#endif
return;
+ }
tac_list_addtail(&entity->eval_scan.notify_expr_list,
&expr->eval_scan.u.entity.notify_expr_node);
report(LOG_DEBUG, "expr_eval_immediate: bottom_up and_or: full scan: " PF_EXPR,
PA_EXPR(expr_single));
+ /* It would be nice to pretend that all 'veto' decisions already made in the child
+ * had to set our 'result' to the correct value. But 'consent' decisions don't set
+ * us and the behaviour of auto-set from the child in 'veto' case may get changed
+ * in the future versions.
+ * So we rather don't depend on it.
+ * This overhead doesn't change altgorithmic complexity anyway.
+ */
result_parent = consent;
for (expr_child = expr_parent->u.and_or.child_first; expr_child; expr_child = expr_child->next)
{
child_entity = MEMBERSHIP_TO_CHILD_ENTITY( membership);
check_request_scan_entity( child_entity, 0);
+#if 0 /* non-valid membership doesn't YET solve the parent! */
if (child_entity->request_scan.belongs == ER_FALSE || membership_valid == ER_FALSE) {
membership_parent_solve(membership, ER_FALSE);
return;
}
+#endif
+
if (child_entity->request_scan.belongs == ER_TRUE && membership_valid == ER_TRUE ) {
membership_parent_solve(membership, ER_TRUE );
return;
if (parent_entity->request_scan.belongs == ER_UNKNOWN)
register_kicked_entity(parent_entity, 0 /* priority */);
- if ( child_entity->request_scan.belongs != ER_UNKNOWN
- && parent_entity->request_scan.belongs != ER_UNKNOWN)
+ if (parent_entity->request_scan.belongs != ER_UNKNOWN
+ || (child_entity->request_scan.belongs == ER_FALSE || membership_valid == ER_FALSE))
membership_solved(membership);
if (debug & DEBUG_CFGEVAL_FLAG)