/* ISC license. */ #include #include #include #include #include #include #include s6net_accessrules_result_t s6net_accessrules_backend_fs (char const *key, unsigned int keylen, void *data, s6net_accessrules_params_t *params) { char *dir = data ; unsigned int dirlen = str_len(dir) ; unsigned int envbase = params->env.len ; int wasnull = !params->env.s ; { char tmp[dirlen + keylen + 10] ; byte_copy(tmp, dirlen, dir) ; tmp[dirlen] = '/' ; byte_copy(tmp + dirlen + 1, keylen, key) ; byte_copy(tmp + dirlen + keylen + 1, 7, "/allow") ; if (access(tmp, R_OK) < 0) { if ((errno != EACCES) && (errno != ENOENT)) return S6NET_ACCESSRULES_ERROR ; byte_copy(tmp + dirlen + keylen + 2, 5, "deny") ; return (access(tmp, R_OK) == 0) ? S6NET_ACCESSRULES_DENY : (errno != EACCES) && (errno != ENOENT) ? S6NET_ACCESSRULES_ERROR : S6NET_ACCESSRULES_NOTFOUND ; } byte_copy(tmp + dirlen + keylen + 2, 4, "env") ; if ((envdir(tmp, ¶ms->env) < 0) && (errno != ENOENT)) return S6NET_ACCESSRULES_ERROR ; if (!stralloc_readyplus(¶ms->exec, 4097)) { if (wasnull) stralloc_free(¶ms->env) ; else params->env.len = envbase ; return S6NET_ACCESSRULES_ERROR ; } byte_copy(tmp + dirlen + keylen + 2, 5, "exec") ; { register int r = openreadnclose(tmp, params->exec.s + params->exec.len, 4096) ; if ((r < 0) && (errno != EACCES) && (errno != ENOENT)) { if (wasnull) stralloc_free(¶ms->env) ; else params->env.len = envbase ; return S6NET_ACCESSRULES_ERROR ; } if (r > 0) { params->exec.len += r ; params->exec.s[params->exec.len++] = 0 ; } } } return S6NET_ACCESSRULES_ALLOW ; }