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, &params->env) < 0) && (errno != ENOENT))
34       return S6_ACCESSRULES_ERROR ;
35     if (!stralloc_readyplus(&params->exec, 4097))
36     {
37       if (wasnull) stralloc_free(&params->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(&params->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