static void KeepQueryAccessPromise(EvalContext *ctx, const Promise *pp) { Auth *dp = GetOrCreateAuth(pp->promiser, &SV.vardeny, &SV.vardenytail), *ap = GetOrCreateAuth(pp->promiser, &SV.varadmit, &SV.varadmittail); RegisterLiteralServerData(ctx, pp->promiser, pp); ap->literal = true; size_t pos = acl_SortedInsert(&query_acl, pp->promiser); if (pos == (size_t) -1) { /* Should never happen, besides when allocation fails. */ Log(LOG_LEVEL_CRIT, "acl_Insert: %s", GetErrorStr()); exit(255); } AccessPromise_AddAccessConstraints(ctx, pp, &query_acl->acls[pos], ap, dp); }
static void KeepServerRolePromise(EvalContext *ctx, const Promise *pp) { Rlist *rp; Auth *ap; ap = GetOrCreateAuth(pp->promiser, &SV.roles, &SV.rolestail); for (size_t i = 0; i < SeqLength(pp->conlist); i++) { Constraint *cp = SeqAt(pp->conlist, i); if (!IsDefinedClass(ctx, cp->classes)) { continue; } switch (cp->rval.type) { case RVAL_TYPE_LIST: for (rp = (Rlist *) cp->rval.item; rp != NULL; rp = rp->next) { /* This is for remote class activation by means of cf-runagent.*/ if (strcmp(cp->lval, CF_REMROLE_BODIES[REMOTE_ROLE_AUTHORIZE].lval) == 0) { PrependItem(&(ap->accesslist), RlistScalarValue(rp), NULL); continue; } } break; case RVAL_TYPE_FNCALL: UnexpectedError("Constraint of type FNCALL is invalid in this context!"); break; default: if ((strcmp(cp->lval, "comment") == 0) || (strcmp(cp->lval, "handle") == 0)) { } else { Log(LOG_LEVEL_ERR, "Right-hand side of authorize promise for '%s' should be a list", pp->promiser); } break; } } }
static void KeepServerRolePromise(EvalContext *ctx, const Promise *pp) { Auth *ap = GetOrCreateAuth(pp->promiser, &SV.roles, &SV.rolestail); const char *const authorizer = CF_REMROLE_BODIES[REMOTE_ROLE_AUTHORIZE].lval; size_t i = SeqLength(pp->conlist); while (i > 0) { i--; Constraint *cp = SeqAt(pp->conlist, i); if (strcmp(cp->lval, authorizer) == 0) { if (cp->rval.type != RVAL_TYPE_LIST) { Log(LOG_LEVEL_ERR, "Right-hand side of authorize promise for '%s' should be a list", pp->promiser); } else if (IsDefinedClass(ctx, cp->classes)) { /* This is for remote class activation by means of cf-runagent.*/ for (const Rlist *rp = cp->rval.item; rp != NULL; rp = rp->next) { PrependItem(&(ap->accesslist), RlistScalarValue(rp), NULL); } } } else if (strcmp(cp->lval, "comment") != 0 && strcmp(cp->lval, "handle") != 0 && /* Are there other known list constraints ? if not, skip this: */ cp->rval.type != RVAL_TYPE_LIST) { Log(LOG_LEVEL_WARNING, "Unrecognised promise '%s' for %s", cp->lval, pp->promiser); } } }
void KeepLiteralAccessPromise(EvalContext *ctx, const Promise *pp, const char *type) { Auth *ap, *dp; const char *handle = PromiseGetHandle(pp); if (handle == NULL && strcmp(type, "literal") == 0) { Log(LOG_LEVEL_ERR, "Access to literal server data requires you to define a promise handle for reference"); return; } if (strcmp(type, "literal") == 0) { Log(LOG_LEVEL_VERBOSE,"Looking at literal access promise '%s', type '%s'", pp->promiser, type); ap = GetOrCreateAuth(handle, &SV.varadmit, &SV.varadmittail); dp = GetOrCreateAuth(handle, &SV.vardeny, &SV.vardenytail); RegisterLiteralServerData(ctx, handle, pp); ap->literal = true; size_t pos = acl_SortedInsert(&literals_acl, handle); if (pos == (size_t) -1) { /* Should never happen, besides when allocation fails. */ Log(LOG_LEVEL_CRIT, "acl_Insert: %s", GetErrorStr()); exit(255); } AccessPromise_AddAccessConstraints(ctx, pp, &literals_acl->acls[pos], ap, dp); } else { Log(LOG_LEVEL_VERBOSE,"Looking at context/var access promise '%s', type '%s'", pp->promiser, type); ap = GetOrCreateAuth(pp->promiser, &SV.varadmit, &SV.varadmittail); dp = GetOrCreateAuth(pp->promiser, &SV.vardeny, &SV.vardenytail); if (strcmp(type, "context") == 0) { ap->classpattern = true; size_t pos = acl_SortedInsert(&classes_acl, pp->promiser); if (pos == (size_t) -1) { /* Should never happen, besides when allocation fails. */ Log(LOG_LEVEL_CRIT, "acl_Insert: %s", GetErrorStr()); exit(255); } AccessPromise_AddAccessConstraints(ctx, pp, &classes_acl->acls[pos], ap, dp); } else if (strcmp(type, "variable") == 0) { ap->variable = true; size_t pos = acl_SortedInsert(&vars_acl, pp->promiser); if (pos == (size_t) -1) { /* Should never happen, besides when allocation fails. */ Log(LOG_LEVEL_CRIT, "acl_Insert: %s", GetErrorStr()); exit(255); } AccessPromise_AddAccessConstraints(ctx, pp, &vars_acl->acls[pos], ap, dp); } } }
static void KeepFileAccessPromise(const EvalContext *ctx, const Promise *pp) { char path[PATH_MAX]; size_t path_len = strlen(pp->promiser); if (path_len > sizeof(path) - 1) { goto err_too_long; } memcpy(path, pp->promiser, path_len + 1); /* Resolve symlinks and canonicalise access_rules path. */ size_t ret2 = PreprocessRequestPath(path, sizeof(path)); if (ret2 == (size_t) -1) { if (errno != ENOENT) /* something went wrong */ { Log(LOG_LEVEL_ERR, "Failed to canonicalize path '%s' in access_rules, ignoring!", pp->promiser); return; } else /* file does not exist, it doesn't matter */ { Log(LOG_LEVEL_INFO, "Path does not exist, it's added as-is in access rules: %s", path); Log(LOG_LEVEL_INFO, "WARNING: this means that (not) having a trailing slash defines if it's (not) a directory!"); /* Legacy: convert trailing "/." to "/" */ if (path_len >= 2 && path[path_len - 1] == '.' && path[path_len - 2] == '/') { path[path_len - 1] = '\0'; path_len--; } } } else /* file exists, path canonicalised */ { /* If it's a directory append trailing '/' */ path_len = ret2; int is_dir = IsDirReal(path); if (is_dir == 1 && path[path_len - 1] != FILE_SEPARATOR) { if (path_len + 2 > sizeof(path)) { goto err_too_long; } PathAppendTrailingSlash(path, path_len); path_len++; } } size_t pos = acl_SortedInsert(&paths_acl, path); if (pos == (size_t) -1) { /* Should never happen, besides when allocation fails. */ Log(LOG_LEVEL_CRIT, "acl_Insert: %s", GetErrorStr()); exit(255); } /* Legacy code */ if (path_len != 1) { DeleteSlash(path); } Auth *ap = GetOrCreateAuth(path, &SV.admit, &SV.admittail); Auth *dp = GetOrCreateAuth(path, &SV.deny, &SV.denytail); AccessPromise_AddAccessConstraints(ctx, pp, &paths_acl->acls[pos], ap, dp); return; err_too_long: Log(LOG_LEVEL_ERR, "Path '%s' in access_rules is too long (%zu > %d), ignoring!", pp->promiser, strlen(pp->promiser), PATH_MAX); return; }