1 /* ISC license. */
2
3 #include <string.h>
4 #include <unistd.h>
5 #include <errno.h>
6 #include <skalibs/stralloc.h>
7 #include <skalibs/env.h>
8 #include <skalibs/djbunix.h>
9 #include <s6/accessrules.h>
10
s6_accessrules_backend_fs(char const * key,size_t keylen,void * data,s6_accessrules_params_t * params)11 s6_accessrules_result_t s6_accessrules_backend_fs (char const *key, size_t keylen, void *data, s6_accessrules_params_t *params)
12 {
13 char *dir = data ;
14 size_t dirlen = strlen(dir) ;
15 size_t envbase = params->env.len ;
16 int wasnull = !params->env.s ;
17 {
18 char tmp[dirlen + keylen + 10] ;
19 memcpy(tmp, dir, dirlen) ;
20 tmp[dirlen] = '/' ;
21 memcpy(tmp + dirlen + 1, key, keylen) ;
22 memcpy(tmp + dirlen + keylen + 1, "/allow", 7) ;
23 if (access(tmp, R_OK) < 0)
24 {
25 if ((errno != EACCES) && (errno != ENOENT))
26 return S6_ACCESSRULES_ERROR ;
27 memcpy(tmp + dirlen + keylen + 2, "deny", 5) ;
28 return (access(tmp, R_OK) == 0) ? S6_ACCESSRULES_DENY :
29 (errno != EACCES) && (errno != ENOENT) ? S6_ACCESSRULES_ERROR :
30 S6_ACCESSRULES_NOTFOUND ;
31 }
32 memcpy(tmp + dirlen + keylen + 2, "env", 4) ;
33 if ((envdir(tmp, ¶ms->env) < 0) && (errno != ENOENT))
34 return S6_ACCESSRULES_ERROR ;
35 if (!stralloc_readyplus(¶ms->exec, 4097))
36 {
37 if (wasnull) stralloc_free(¶ms->env) ;
38 else params->env.len = envbase ;
39 return S6_ACCESSRULES_ERROR ;
40 }
41 memcpy(tmp + dirlen + keylen + 2, "exec", 5) ;
42 {
43 ssize_t r = openreadnclose(tmp, params->exec.s + params->exec.len, 4096) ;
44 if ((r < 0) && (errno != EACCES) && (errno != ENOENT))
45 {
46 if (wasnull) stralloc_free(¶ms->env) ;
47 else params->env.len = envbase ;
48 return S6_ACCESSRULES_ERROR ;
49 }
50 if (r > 0)
51 {
52 params->exec.len += r ;
53 params->exec.s[params->exec.len++] = 0 ;
54 }
55 }
56 }
57 return S6_ACCESSRULES_ALLOW ;
58 }
59