/* ISC license. */ #include #include #include #include #include #include #include s6_accessrules_result_t s6_accessrules_backend_cdb (char const *key, unsigned int keylen, void *data, s6_accessrules_params_t *params) { struct cdb *c = data ; unsigned int execbase, n ; uint16 envlen, execlen ; register int r = cdb_find(c, key, keylen) ; if (r < 0) return S6_ACCESSRULES_ERROR ; else if (!r) return S6_ACCESSRULES_NOTFOUND ; n = cdb_datalen(c) ; if ((n < 5U) || (n > 8197U)) return (errno = EINVAL, S6_ACCESSRULES_ERROR) ; if (!stralloc_readyplus(¶ms->exec, n)) return S6_ACCESSRULES_ERROR ; execbase = params->exec.len ; if (cdb_read(c, params->exec.s + execbase, n, cdb_datapos(c)) < 0) return S6_ACCESSRULES_ERROR ; if (params->exec.s[execbase] == 'D') return S6_ACCESSRULES_DENY ; else if (params->exec.s[execbase] != 'A') return S6_ACCESSRULES_NOTFOUND ; uint16_unpack_big(params->exec.s + execbase + 1U, &envlen) ; if ((envlen > 4096U) || (envlen+5U > n)) return (errno = EINVAL, S6_ACCESSRULES_ERROR) ; uint16_unpack_big(params->exec.s + execbase + 3 + envlen, &execlen) ; if ((execlen > 4096U) || (5U + envlen + execlen != n)) return (errno = EINVAL, S6_ACCESSRULES_ERROR) ; if (!stralloc_catb(¶ms->env, params->exec.s + execbase + 3U, envlen)) return S6_ACCESSRULES_ERROR ; byte_copy(params->exec.s + execbase, execlen, params->exec.s + execbase + 5U + envlen) ; if (execlen) { params->exec.len += execlen ; params->exec.s[params->exec.len++] = 0 ; } return S6_ACCESSRULES_ALLOW ; }