LCOV - code coverage report
Current view: top level - src/client - acl.c (source / functions) Hit Total Coverage
Test: burp-coverage-clean.info Lines: 0 89 0.0 %
Date: 2015-10-31 Functions: 0 7 0.0 %

          Line data    Source code
       1             : #include "../burp.h"
       2             : #include "../alloc.h"
       3             : #include "../cmd.h"
       4             : #include "../log.h"
       5             : #include "../prepend.h"
       6             : #include "../sbuf.h"
       7             : #include "acl.h"
       8             : #include "extrameta.h"
       9             : 
      10             : #ifdef HAVE_ACL
      11             : #if defined(HAVE_LINUX_OS) || \
      12             :     defined(HAVE_FREEBSD_OS) || \
      13             :     defined(HAVE_OPENBSD_OS) || \
      14             :     defined(HAVE_NETBSD_OS)
      15             : #include "sys/acl.h"
      16             : 
      17             : /* Linux can do shorter ACLs */
      18             : #if defined(HAVE_LINUX_OS)
      19             : #include <acl/libacl.h>
      20             : #define acl_to_text(acl,len)        (acl_to_any_text((acl), NULL, ',', TEXT_ABBREVIATE|TEXT_NUMERIC_IDS))
      21             : #endif
      22             : 
      23             : // section of acl_is_trivial copied from bacula 
      24           0 : static int acl_is_trivial(acl_t acl)
      25             : {
      26             : #if defined(HAVE_LINUX_OS) \
      27             :  || defined(HAVE_FREEBSD_OS) \
      28             :  || defined(HAVE_OPENBSD_OS) \
      29             :  || defined(HAVE_NETBSD_OS)
      30             :         /*
      31             :          * acl is trivial if it has only the following entries:
      32             :          * "user::",
      33             :          * "group::",
      34             :          * "other::"
      35             :          */
      36             :         acl_entry_t ace;
      37             :         acl_tag_t tag;
      38             :         int entry_available;
      39             : 
      40           0 :         entry_available = acl_get_entry(acl, ACL_FIRST_ENTRY, &ace);
      41           0 :         while(entry_available==1)
      42             :         {
      43             :                 /*
      44             :                  * Get the tag type of this acl entry.
      45             :                  * If we fail to get the tagtype we call the acl non-trivial.
      46             :                  */
      47           0 :                 if (acl_get_tag_type(ace, &tag) < 0)
      48           0 :                         return true;
      49             :                 /*
      50             :                  * Anything other the ACL_USER_OBJ, ACL_GROUP_OBJ
      51             :                  * or ACL_OTHER breaks the spell.
      52             :                  */
      53           0 :                 if(tag!=ACL_USER_OBJ
      54           0 :                   && tag!=ACL_GROUP_OBJ
      55           0 :                   && tag!=ACL_OTHER)
      56           0 :                         return 0;
      57           0 :                 entry_available=acl_get_entry(acl, ACL_NEXT_ENTRY, &ace);
      58             :         }
      59             : #endif
      60           0 :         return 1;
      61             : }
      62             : 
      63           0 : static acl_t acl_contains_something(const char *path, int acl_type)
      64             : {
      65           0 :         acl_t acl=NULL;
      66           0 :         if(!(acl=acl_get_file(path, acl_type))) return NULL;
      67           0 :         if(!acl_is_trivial(acl)) return acl;
      68           0 :         acl_free(acl);
      69           0 :         return NULL;
      70             : }
      71             : 
      72           0 : int has_acl(const char *path, enum cmd cmd)
      73             : {
      74           0 :         acl_t acl=NULL;
      75           0 :         if(!(acl=acl_contains_something(path, ACL_TYPE_ACCESS))
      76           0 :           || (cmd==CMD_DIRECTORY
      77           0 :             && !(acl=acl_contains_something(path, ACL_TYPE_DEFAULT))))
      78           0 :                 return 0;
      79           0 :         acl_free(acl);
      80           0 :         return 1;
      81             : }
      82             : 
      83           0 : static int get_acl_string(struct asfd *asfd, acl_t acl, char **acltext,
      84             :         size_t *alen, const char *path, char type, struct cntr *cntr)
      85             : {
      86           0 :         int ret=0;
      87           0 :         char pre[10]="";
      88           0 :         char *tmp=NULL;
      89           0 :         ssize_t tlen=0;
      90           0 :         char *ourtext=NULL;
      91           0 :         ssize_t maxlen=0xFFFFFFFF/2;
      92             : 
      93           0 :         if(!(tmp=acl_to_text(acl, NULL)))
      94             :         {
      95           0 :                 logw(asfd, cntr, "could not get ACL text of '%s'\n", path);
      96           0 :                 goto end; // carry on
      97             :         }
      98             : 
      99           0 :         tlen=strlen(tmp);
     100             : 
     101           0 :         if(tlen>maxlen)
     102             :         {
     103           0 :                 logw(asfd, cntr, "ACL of '%s' too long: %d\n", path, tlen);
     104           0 :                 goto end; // carry on
     105             :         }
     106             : 
     107           0 :         snprintf(pre, sizeof(pre), "%c%08X", type, (unsigned int)tlen);
     108           0 :         if(!(ourtext=prepend(pre, tmp))
     109           0 :           || !(*acltext=prepend_len(*acltext,
     110           0 :                 *alen, ourtext, tlen+9, "", 0, alen)))
     111           0 :                         ret=-1;
     112             : end:
     113           0 :         free_w(&tmp);
     114           0 :         free_w(&ourtext);
     115           0 :         return ret;
     116             : }
     117             : 
     118           0 : int get_acl(struct asfd *asfd, struct sbuf *sb,
     119             :         char **acltext, size_t *alen, struct cntr *cntr)
     120             : {
     121           0 :         acl_t acl=NULL;
     122           0 :         const char *path=sb->path.buf;
     123             : 
     124           0 :         if((acl=acl_contains_something(path, ACL_TYPE_ACCESS)))
     125             :         {
     126           0 :                 if(get_acl_string(asfd, acl,
     127           0 :                         acltext, alen, path, META_ACCESS_ACL, cntr))
     128             :                 {
     129           0 :                         acl_free(acl);
     130           0 :                         return -1;
     131             :                 }
     132           0 :                 acl_free(acl);
     133             :         }
     134             : 
     135           0 :         if(S_ISDIR(sb->statp.st_mode))
     136             :         {
     137           0 :                 if((acl=acl_contains_something(path, ACL_TYPE_DEFAULT)))
     138             :                 {
     139           0 :                         if(get_acl_string(asfd, acl,
     140           0 :                                 acltext, alen, path, META_DEFAULT_ACL, cntr))
     141             :                         {
     142           0 :                                 acl_free(acl);
     143           0 :                                 return -1;
     144             :                         }
     145           0 :                         acl_free(acl);
     146             :                 }
     147             :         }
     148           0 :         return 0;
     149             : }
     150             : 
     151           0 : static int do_set_acl(struct asfd *asfd, const char *path,
     152             :         const char *acltext, size_t alen,
     153             :         int acltype, struct cntr *cntr)
     154             : {
     155             :         acl_t acl;
     156           0 :         int ret=-1;
     157           0 :         if(!(acl=acl_from_text(acltext)))
     158             :         {
     159             :                 logp("acl_from_text error on %s (%s): %s\n",
     160           0 :                         path, acltext, strerror(errno));
     161             :                 logw(asfd, cntr, "acl_from_text error on %s (%s): %s\n",
     162           0 :                         path, acltext, strerror(errno));
     163           0 :                 goto end;
     164             :         }
     165             : //#ifndef HAVE_FREEBSD_OS // Bacula says that acl_valid fails on valid input
     166             :                         // on freebsd. It works OK for me on FreeBSD 8.2.
     167           0 :         if(acl_valid(acl))
     168             :         {
     169           0 :                 logp("acl_valid error on %s: %s", path, strerror(errno));
     170             :                 logw(asfd, cntr, "acl_valid error on %s: %s\n",
     171           0 :                         path, strerror(errno));
     172           0 :                 goto end;
     173             :         }
     174             : //#endif
     175           0 :         if(acl_set_file(path, acltype, acl))
     176             :         {
     177           0 :                 logp("acl set error on %s: %s", path, strerror(errno));
     178             :                 logw(asfd, cntr, "acl set error on %s: %s\n",
     179           0 :                         path, strerror(errno));
     180           0 :                 goto end;
     181             :         }
     182           0 :         ret=0;
     183             : end:
     184           0 :         if(acl) acl_free(acl);
     185           0 :         return ret; 
     186             : }
     187             : 
     188           0 : int set_acl(struct asfd *asfd, const char *path, struct sbuf *sb,
     189             :         const char *acltext, size_t alen, char metacmd, struct cntr *cntr)
     190             : {
     191           0 :         switch(metacmd)
     192             :         {
     193             :                 case META_ACCESS_ACL:
     194             :                         return do_set_acl(asfd, path,
     195           0 :                                 acltext, alen, ACL_TYPE_ACCESS, cntr);
     196             :                 case META_DEFAULT_ACL:
     197             :                         return do_set_acl(asfd, path,
     198           0 :                                 acltext, alen, ACL_TYPE_DEFAULT, cntr);
     199             :                 default:
     200           0 :                         logp("unknown acl type: %c\n", metacmd);
     201           0 :                         logw(asfd, cntr, "unknown acl type: %c\n", metacmd);
     202           0 :                         break;
     203             :         }
     204           0 :         return -1;
     205             : }
     206             : 
     207             : #endif // LINUX | BSD
     208             : #endif // HAVE_ACL

Generated by: LCOV version 1.10