static bool MethodsParseTreeCheck(const Promise *pp, Seq *errors) { bool success = true; for (size_t i = 0; i < SeqLength(pp->conlist); i++) { const Constraint *cp = SeqAt(pp->conlist, i); // ensure: if call and callee are resolved, then they have matching arity if (StringSafeEqual(cp->lval, "usebundle")) { if (cp->rval.type == RVAL_TYPE_FNCALL) { const FnCall *call = (const FnCall *)cp->rval.item; const Bundle *callee = PolicyGetBundle(PolicyFromPromise(pp), NULL, "agent", call->name); if (!callee) { callee = PolicyGetBundle(PolicyFromPromise(pp), NULL, "common", call->name); } if (callee) { if (RlistLen(call->args) != RlistLen(callee->args)) { SeqAppend(errors, PolicyErrorNew(POLICY_ELEMENT_TYPE_CONSTRAINT, cp, POLICY_ERROR_METHODS_BUNDLE_ARITY, call->name, RlistLen(callee->args), RlistLen(call->args))); success = false; } } } } } return success; }
static bool AclCheck(const Body *body, Seq *errors) { bool success = true; if (BodyHasConstraint(body, "acl_directory_inherit") && BodyHasConstraint(body, "acl_default")) { SeqAppend(errors, PolicyErrorNew(POLICY_ELEMENT_TYPE_BODY, body, "An acl body cannot have both acl_directory_inherit and acl_default. Please use acl_default only")); success = false; } if (BodyHasConstraint(body, "specify_inherit_aces") && BodyHasConstraint(body, "specify_default_aces")) { SeqAppend(errors, PolicyErrorNew(POLICY_ELEMENT_TYPE_BODY, body, "An acl body cannot have both specify_inherit_aces and specify_default_aces. Please use specify_default_aces only")); success = false; } return success; }
static bool VarsParseTreeCheck(const Promise *pp, Seq *errors) { bool success = true; if (!CheckIdentifierNotPurelyNumerical(pp->promiser)) { SeqAppend(errors, PolicyErrorNew(POLICY_ELEMENT_TYPE_PROMISE, pp, POLICY_ERROR_VARS_PROMISER_NUMERICAL)); success = false; } if (!CheckParseVariableName(pp->promiser)) { SeqAppend(errors, PolicyErrorNew(POLICY_ELEMENT_TYPE_PROMISE, pp, POLICY_ERROR_VARS_PROMISER_RESERVED)); success = false; } // ensure variables are declared with only one type. { char *data_type = NULL; for (size_t i = 0; i < SeqLength(pp->conlist); i++) { Constraint *cp = SeqAt(pp->conlist, i); if (DataTypeFromString(cp->lval) != CF_DATA_TYPE_NONE) { if (data_type != NULL) { SeqAppend(errors, PolicyErrorNew(POLICY_ELEMENT_TYPE_CONSTRAINT, cp, POLICY_ERROR_VARS_CONSTRAINT_DUPLICATE_TYPE, data_type, cp->lval)); success = false; } data_type = cp->lval; } } } return success; }
static bool ClassesParseTreeCheck(const Promise *pp, Seq *errors) { bool success = true; if (!CheckIdentifierNotPurelyNumerical(pp->promiser)) { SeqAppend(errors, PolicyErrorNew(POLICY_ELEMENT_TYPE_PROMISE, pp, POLICY_ERROR_CLASSES_PROMISER_NUMERICAL)); success = false; } return success; }
static bool ActionCheck(const Body *body, Seq *errors) { bool success = true; if (BodyHasConstraint(body, "log_kept") || BodyHasConstraint(body, "log_repaired") || BodyHasConstraint(body, "log_failed")) { if (!BodyHasConstraint(body, "log_string")) { SeqAppend(errors, PolicyErrorNew(POLICY_ELEMENT_TYPE_BODY, body, "An action body with log_kept, log_repaired or log_failed is required to have a log_string attribute")); success = false; } } return success; }
static bool MethodsParseTreeCheck(const Promise *pp, Seq *errors) { bool success = true; for (size_t i = 0; i < SeqLength(pp->conlist); i++) { const Constraint *cp = SeqAt(pp->conlist, i); // ensure: if call and callee are resolved, then they have matching arity if (StringSafeEqual(cp->lval, "usebundle")) { if (cp->rval.type == RVAL_TYPE_FNCALL) { // HACK: exploiting the fact that class-references and call-references are similar FnCall *call = RvalFnCallValue(cp->rval); ClassRef ref = ClassRefParse(call->name); if (!ClassRefIsQualified(ref)) { ClassRefQualify(&ref, PromiseGetNamespace(pp)); } const Bundle *callee = PolicyGetBundle(PolicyFromPromise(pp), ref.ns, "agent", ref.name); if (!callee) { callee = PolicyGetBundle(PolicyFromPromise(pp), ref.ns, "common", ref.name); } ClassRefDestroy(ref); if (callee) { if (RlistLen(call->args) != RlistLen(callee->args)) { SeqAppend(errors, PolicyErrorNew(POLICY_ELEMENT_TYPE_CONSTRAINT, cp, POLICY_ERROR_METHODS_BUNDLE_ARITY, call->name, RlistLen(callee->args), RlistLen(call->args))); success = false; } } } } } return success; }
static bool AccessParseTreeCheck(const Promise *pp, Seq *errors) { bool success = true; bool isResourceType = false; bool isReportDataSelect = false; Constraint *data_select_const = NULL; for (size_t i = 0; i <SeqLength(pp->conlist); i++) { Constraint *con = SeqAt(pp->conlist, i); if (StringSafeCompare("resource_type", con->lval) == 0) { if (con->rval.type == RVAL_TYPE_SCALAR) { if (StringSafeCompare("query", (char*)con->rval.item) == 0) { isResourceType = true; } } } else if (StringSafeCompare("report_data_select", con->lval) == 0) { data_select_const = con; isReportDataSelect = true; } } if (isReportDataSelect && !isResourceType) { SeqAppend(errors, PolicyErrorNew(POLICY_ELEMENT_TYPE_CONSTRAINT, data_select_const, POLICY_ERROR_WRONG_RESOURCE_FOR_DATA_SELECT)); success = false; } return success; }