]> git.sur5r.net Git - bacula/bacula/blobdiff - bacula/src/filed/acl.c
ebl Use MTIMEONLY fileset option in accurate check
[bacula/bacula] / bacula / src / filed / acl.c
index 3f2303f6df851f11c31cfd2a816427a8436be86d..533c24320ea3bc1ffa3a84d4912448eb1410e208 100644 (file)
@@ -1,7 +1,7 @@
 /*
    Bacula® - The Network Backup Solution
 
-   Copyright (C) 2004-2008 Free Software Foundation Europe e.V.
+   Copyright (C) 2004-2009 Free Software Foundation Europe e.V.
 
    The main author of Bacula is Kern Sibbald, with contributions from
    many others, a complete list can be found in the file AUTHORS.
    Switzerland, email:ftf@fsfeurope.org.
 */
 /*
- * Functions to handle ACL for bacula.
+ * Functions to handle ACLs for bacula.
  *
- * We handle two different typers of ACLs: access and default ACLS.
- * Default ACLs only apply to directories.
+ * We handle two different types of ACLs: access and default ACLS.
+ * On most systems that support default ACLs they only apply to directories.
  *
  * On some systems (eg. linux and FreeBSD) we must obtain the two ACLs
  * independently, while others (eg. Solaris) provide both in one call.
  *
- * As for the streams to use, we have two choices:
+ * The Filed saves ACLs in their native format and uses different streams
+ * for all different platforms. Currently we only allow ACLs to be restored
+ * which were saved in the native format of the platform they are extracted
+ * on. Later on we might add conversion functions for mapping from one
+ * platform to an other or allow restores of systems that use the same
+ * native format.
  *
- * 1. Build a generic framework.
- *    With two different types of ACLs, supported differently, we
- *    probably end up encoding and decoding everything ourselves.
+ * Its also interesting to see what the exact format of acl text is on
+ * certain platforms and if they use they same encoding we might allow
+ * different platform streams to be decoded on an other similar platform.
+ * As we implement the decoding/restoring process as a big switch based
+ * on the stream number being passed in extending the switching code is
+ * easy.
  *
- * 2. Take the easy way out.
- *    Just handle each platform individually, assuming that backups
- *    and restores are done on the same (kind of) client.
- *
- * Currently we take the easy way out. We use two kinds of streams, one
- * for access ACLs and one for default ACLs. If an OS mixes the two, we
- * send the mix in the access ACL stream.
- *
- * Looking at more man pages, supporting a framework seems really hard
- * if we want to support HP-UX. Deity knows what AIX is up to.
- *
- *   Written by Preben 'Peppe' Guldberg, December MMIV
+ *   Original written by Preben 'Peppe' Guldberg, December MMIV
+ *   Major rewrite by Marco van Wieringen, November MMVIII
  *
  *   Version $Id$
  */
-
-
-#ifndef TEST_PROGRAM
-
+  
 #include "bacula.h"
 #include "filed.h"
-
-#endif
-
+  
 /*
- * List of supported OSs.
+ * List of supported OSes. Everything outside that gets stub functions.
+ * Also when ACL support is explicitly disabled.
  * Not sure if all the HAVE_XYZ_OS are correct for autoconf.
  * The ones that says man page, are coded according to man pages only.
  */
@@ -100,7 +94,7 @@ bool parse_acl_stream(JCR *jcr, int stream)
 /*
  * Send an ACL stream to the SD.
  */
-static bool send_acl_stream(JCR *jcr, int stream, int len)
+static bool send_acl_stream(JCR *jcr, int stream)
 {
    BSOCK *sd = jcr->store_bsock;
    POOLMEM *msgsave;
@@ -124,7 +118,7 @@ static bool send_acl_stream(JCR *jcr, int stream, int len)
    Dmsg1(400, "Backing up ACL <%s>\n", jcr->acl_data);
    msgsave = sd->msg;
    sd->msg = jcr->acl_data;
-   sd->msglen = len + 1;
+   sd->msglen = jcr->acl_data_len + 1;
    if (!sd->send()) {
       sd->msg = msgsave;
       sd->msglen = 0;
@@ -155,13 +149,12 @@ static bool send_acl_stream(JCR *jcr, int stream, int len)
 static bool aix_build_acl_streams(JCR *jcr, FF_PKT *ff_pkt)
 {
    char *acl_text;
-   int len;
 
    if ((acl_text = acl_get(jcr->last_fname)) != NULL) {
-      len = pm_strcpy(jcr->acl_data, acl_text);
+      jcr->acl_data_len = pm_strcpy(jcr->acl_data, acl_text);
       actuallyfree(acl_text);
 
-      return send_acl_stream(jcr, STREAM_ACL_AIX_TEXT, len);
+      return send_acl_stream(jcr, STREAM_ACL_AIX_TEXT);
    }
 
    return false;
@@ -246,26 +239,18 @@ static acl_type_t bac_to_os_acltype(bacl_type acltype)
        * This should never happen, as the per os version function only tries acl
        * types supported on a certain platform.
        */
-      ostype = ACL_TYPE_NONE;
+      ostype = (acl_type_t)ACL_TYPE_NONE;
       break;
    }
 
    return ostype;
 }
 
+#if !defined(HAVE_DARWIN_OS)
 /*
  * See if an acl is a trivial one (e.g. just the stat bits encoded as acl.)
  * There is no need to store those acls as we already store the stat bits too.
  */
-#if defined(HAVE_DARWIN_OS)
-static bool acl_is_trivial(acl_t acl)
-{
-   /*
-    * acl is trivial if it is empty.
-    */
-   return (acl_entries(acl) == 0);
-}
-#else /* FreeBSD, IRIX, OSF1, Linux */
 static bool acl_is_trivial(acl_t acl)
 {
   /*
@@ -383,12 +368,11 @@ static int generic_get_acl_from_os(JCR *jcr, bacl_type acltype)
       }
 #endif
 
+#if !defined(HAVE_DARWIN_OS)
       /*
        * Make sure this is not just a trivial ACL.
        */
-      if ((acltype == BACL_TYPE_ACCESS ||
-           acltype == BACL_TYPE_EXTENDED) &&
-           acl_is_trivial(acl)) {
+      if (acltype == BACL_TYPE_ACCESS && acl_is_trivial(acl)) {
          /*
           * The ACLs simply reflect the (already known) standard permissions
           * So we don't send an ACL stream to the SD.
@@ -397,6 +381,7 @@ static int generic_get_acl_from_os(JCR *jcr, bacl_type acltype)
          acl_free(acl);
          return 0;
       }
+#endif
 
       if ((acl_text = acl_to_text(acl, NULL)) != NULL) {
          len = pm_strcpy(jcr->acl_data, acl_text);
@@ -520,8 +505,6 @@ static bool generic_set_acl_on_os(JCR *jcr, bacl_type acltype)
 #if defined(HAVE_DARWIN_OS)
 static bool darwin_build_acl_streams(JCR *jcr, FF_PKT *ff_pkt)
 {
-   int len;
-
 #if defined(ACL_TYPE_EXTENDED)
    /*
     * On MacOS X, acl_get_file (name, ACL_TYPE_ACCESS)
@@ -532,20 +515,20 @@ static bool darwin_build_acl_streams(JCR *jcr, FF_PKT *ff_pkt)
     *
     * Read access ACLs for files, dirs and links
     */
-   if ((len = generic_get_acl_from_os(jcr, BACL_TYPE_EXTENDED)) < 0)
+   if ((jcr->acl_data_len = generic_get_acl_from_os(jcr, BACL_TYPE_EXTENDED)) < 0)
       return false;
 #else
    /*
     * Read access ACLs for files, dirs and links
     */
-   if ((len = generic_get_acl_from_os(jcr, BACL_TYPE_ACCESS)) < 0)
+   if ((jcr->acl_data_len = generic_get_acl_from_os(jcr, BACL_TYPE_ACCESS)) < 0)
       return false;
-#endif
 
-   if (len > 0) {
-      if (!send_acl_stream(jcr, STREAM_ACL_DARWIN_ACCESS_ACL_T, len))
+   if (jcr->acl_data_len > 0) {
+      if (!send_acl_stream(jcr, STREAM_ACL_DARWIN_ACCESS_ACL))
          return false;
    }
+#endif
 
    return true;
 }
@@ -554,7 +537,7 @@ static bool darwin_parse_acl_stream(JCR *jcr, int stream)
 {
    switch (stream) {
    case STREAM_UNIX_ACCESS_ACL:
-   case STREAM_ACL_DARWIN_ACCESS_ACL_T:
+   case STREAM_ACL_DARWIN_ACCESS_ACL:
       return generic_set_acl_on_os(jcr, BACL_TYPE_ACCESS);
    }
 
@@ -563,16 +546,14 @@ static bool darwin_parse_acl_stream(JCR *jcr, int stream)
 #elif defined(HAVE_FREEBSD_OS)
 static bool freebsd_build_acl_streams(JCR *jcr, FF_PKT *ff_pkt)
 {
-   int len;
-
    /*
     * Read access ACLs for files, dirs and links
     */
-   if ((len = generic_get_acl_from_os(jcr, BACL_TYPE_ACCESS)) < 0)
+   if ((jcr->acl_data_len = generic_get_acl_from_os(jcr, BACL_TYPE_ACCESS)) < 0)
       return false;
 
-   if (len > 0) {
-      if (!send_acl_stream(jcr, STREAM_ACL_FREEBSD_ACCESS_ACL_T, len))
+   if (jcr->acl_data_len > 0) {
+      if (!send_acl_stream(jcr, STREAM_ACL_FREEBSD_ACCESS_ACL))
          return false;
    }
 
@@ -580,11 +561,11 @@ static bool freebsd_build_acl_streams(JCR *jcr, FF_PKT *ff_pkt)
     * Directories can have default ACLs too
     */
    if (ff_pkt->type == FT_DIREND) {
-      if ((len = generic_get_acl_from_os(jcr, BACL_TYPE_DEFAULT)) < 0)
+      if ((jcr->acl_data_len = generic_get_acl_from_os(jcr, BACL_TYPE_DEFAULT)) < 0)
          return false;
 
-      if (len > 0) {
-         if (!send_acl_stream(jcr, STREAM_ACL_FREEBSD_DEFAULT_ACL_T, len))
+      if (jcr->acl_data_len > 0) {
+         if (!send_acl_stream(jcr, STREAM_ACL_FREEBSD_DEFAULT_ACL))
             return false;
       }
    }
@@ -596,10 +577,10 @@ static bool freebsd_parse_acl_stream(JCR *jcr, int stream)
 {
    switch (stream) {
    case STREAM_UNIX_ACCESS_ACL:
-   case STREAM_ACL_FREEBSD_ACCESS_ACL_T:
+   case STREAM_ACL_FREEBSD_ACCESS_ACL:
       return generic_set_acl_on_os(jcr, BACL_TYPE_ACCESS);
    case STREAM_UNIX_DEFAULT_ACL:
-   case STREAM_ACL_FREEBSD_DEFAULT_ACL_T:
+   case STREAM_ACL_FREEBSD_DEFAULT_ACL:
       return generic_set_acl_on_os(jcr, BACL_TYPE_DEFAULT);
    }
 
@@ -608,16 +589,14 @@ static bool freebsd_parse_acl_stream(JCR *jcr, int stream)
 #elif defined(HAVE_IRIX_OS)
 static bool irix_build_acl_streams(JCR *jcr, FF_PKT *ff_pkt)
 {
-   int len;
-
    /*
     * Read access ACLs for files, dirs and links
     */
-   if ((len = generic_get_acl_from_os(jcr, BACL_TYPE_ACCESS)) < 0)
+   if ((jcr->acl_data_len = generic_get_acl_from_os(jcr, BACL_TYPE_ACCESS)) < 0)
       return false;
 
-   if (len > 0) {
-      if (!send_acl_stream(jcr, STREAM_ACL_IRIX_ACCESS_ACL_T, len))
+   if (jcr->acl_data_len > 0) {
+      if (!send_acl_stream(jcr, STREAM_ACL_IRIX_ACCESS_ACL))
          return false;
    }
 
@@ -625,11 +604,11 @@ static bool irix_build_acl_streams(JCR *jcr, FF_PKT *ff_pkt)
     * Directories can have default ACLs too
     */
    if (ff_pkt->type == FT_DIREND) {
-      if ((len = generic_get_acl_from_os(jcr, BACL_TYPE_DEFAULT)) < 0)
+      if ((jcr->acl_data_len = generic_get_acl_from_os(jcr, BACL_TYPE_DEFAULT)) < 0)
          return false;
 
-      if (len > 0) {
-         if (!send_acl_stream(jcr, STREAM_ACL_IRIX_DEFAULT_ACL_T, len))
+      if (jcr->acl_data_len > 0) {
+         if (!send_acl_stream(jcr, STREAM_ACL_IRIX_DEFAULT_ACL))
             return false;
       }
    }
@@ -641,10 +620,10 @@ static bool irix_parse_acl_stream(JCR *jcr, int stream)
 {
    switch (stream) {
    case STREAM_UNIX_ACCESS_ACL:
-   case STREAM_ACL_IRIX_ACCESS_ACL_T:
+   case STREAM_ACL_IRIX_ACCESS_ACL:
       return generic_set_acl_on_os(jcr, BACL_TYPE_ACCESS);
    case STREAM_UNIX_DEFAULT_ACL:
-   case STREAM_ACL_IRIX_DEFAULT_ACL_T:
+   case STREAM_ACL_IRIX_DEFAULT_ACL:
       return generic_set_acl_on_os(jcr, BACL_TYPE_DEFAULT);
    }
 
@@ -653,16 +632,14 @@ static bool irix_parse_acl_stream(JCR *jcr, int stream)
 #elif defined(HAVE_LINUX_OS)
 static bool linux_build_acl_streams(JCR *jcr, FF_PKT *ff_pkt)
 {
-   int len;
-
    /*
     * Read access ACLs for files, dirs and links
     */
-   if ((len = generic_get_acl_from_os(jcr, BACL_TYPE_ACCESS)) < 0)
+   if ((jcr->acl_data_len = generic_get_acl_from_os(jcr, BACL_TYPE_ACCESS)) < 0)
       return false;
 
-   if (len > 0) {
-      if (!send_acl_stream(jcr, STREAM_ACL_LINUX_ACCESS_ACL_T, len))
+   if (jcr->acl_data_len > 0) {
+      if (!send_acl_stream(jcr, STREAM_ACL_LINUX_ACCESS_ACL))
          return false;
    }
 
@@ -670,11 +647,11 @@ static bool linux_build_acl_streams(JCR *jcr, FF_PKT *ff_pkt)
     * Directories can have default ACLs too
     */
    if (ff_pkt->type == FT_DIREND) {
-      if ((len = generic_get_acl_from_os(jcr, BACL_TYPE_DEFAULT)) < 0)
+      if ((jcr->acl_data_len = generic_get_acl_from_os(jcr, BACL_TYPE_DEFAULT)) < 0)
          return false;
 
-      if (len > 0) {
-         if (!send_acl_stream(jcr, STREAM_ACL_LINUX_DEFAULT_ACL_T, len))
+      if (jcr->acl_data_len > 0) {
+         if (!send_acl_stream(jcr, STREAM_ACL_LINUX_DEFAULT_ACL))
             return false;
       }
    }
@@ -686,10 +663,10 @@ static bool linux_parse_acl_stream(JCR *jcr, int stream)
 {
    switch (stream) {
    case STREAM_UNIX_ACCESS_ACL:
-   case STREAM_ACL_LINUX_ACCESS_ACL_T:
+   case STREAM_ACL_LINUX_ACCESS_ACL:
       return generic_set_acl_on_os(jcr, BACL_TYPE_ACCESS);
    case STREAM_UNIX_DEFAULT_ACL:
-   case STREAM_ACL_LINUX_DEFAULT_ACL_T:
+   case STREAM_ACL_LINUX_DEFAULT_ACL:
       return generic_set_acl_on_os(jcr, BACL_TYPE_DEFAULT);
    }
 
@@ -698,16 +675,14 @@ static bool linux_parse_acl_stream(JCR *jcr, int stream)
 #elif defined(HAVE_OSF1_OS)
 static bool tru64_build_acl_streams(JCR *jcr, FF_PKT *ff_pkt)
 {
-   int len;
-
    /*
     * Read access ACLs for files, dirs and links
     */
-   if ((len = generic_get_acl_from_os(jcr, BACL_TYPE_ACCESS)) < 0)
+   if ((jcr->acl_data_len = generic_get_acl_from_os(jcr, BACL_TYPE_ACCESS)) < 0)
       return false;
 
-   if (len > 0) {
-      if (!send_acl_stream(jcr, STREAM_ACL_TRU64_ACCESS_ACL_T, len))
+   if (jcr->acl_data_len > 0) {
+      if (!send_acl_stream(jcr, STREAM_ACL_TRU64_ACCESS_ACL))
          return false;
    }
 
@@ -715,11 +690,11 @@ static bool tru64_build_acl_streams(JCR *jcr, FF_PKT *ff_pkt)
     * Directories can have default ACLs too
     */
    if (ff_pkt->type == FT_DIREND) {
-      if ((len = generic_get_acl_from_os(jcr, BACL_TYPE_DEFAULT)) < 0)
+      if ((jcr->acl_data_len = generic_get_acl_from_os(jcr, BACL_TYPE_DEFAULT)) < 0)
          return false;
 
-      if (len > 0) {
-         if (!send_acl_stream(jcr, STREAM_ACL_TRU64_DEFAULT_ACL_T, len))
+      if (jcr->acl_data_len > 0) {
+         if (!send_acl_stream(jcr, STREAM_ACL_TRU64_DEFAULT_ACL))
             return false;
       }
 
@@ -729,11 +704,11 @@ static bool tru64_build_acl_streams(JCR *jcr, FF_PKT *ff_pkt)
        * See http://www.helsinki.fi/atk/unix/dec_manuals/DOC_40D/AQ0R2DTE/DOCU_018.HTM
        * Section 21.5 Default ACLs 
        */
-      if ((len = generic_get_acl_from_os(jcr, BACL_TYPE_DEFAULT_DIR)) < 0)
+      if ((jcr->acl_data_len = generic_get_acl_from_os(jcr, BACL_TYPE_DEFAULT_DIR)) < 0)
          return false;
 
-      if (len > 0) {
-         if (!send_acl_stream(jcr, STREAM_ACL_TRU64_DEFAULT_DIR_ACL_T, len))
+      if (jcr->acl_data_len > 0) {
+         if (!send_acl_stream(jcr, STREAM_ACL_TRU64_DEFAULT_DIR_ACL))
             return false;
       }
    }
@@ -745,12 +720,12 @@ static bool tru64_parse_acl_stream(JCR *jcr, int stream)
 {
    switch (stream) {
    case STREAM_UNIX_ACCESS_ACL:
-   case STREAM_ACL_TRU64_ACCESS_ACL_T:
+   case STREAM_ACL_TRU64_ACCESS_ACL:
       return generic_set_acl_on_os(jcr, BACL_TYPE_ACCESS);
    case STREAM_UNIX_DEFAULT_ACL:
-   case STREAM_ACL_TRU64_DEFAULT_ACL_T:
+   case STREAM_ACL_TRU64_DEFAULT_ACL:
       return generic_set_acl_on_os(jcr, BACL_TYPE_DEFAULT);
-   case STREAM_ACL_TRU64_DEFAULT_DIR_ACL_T:
+   case STREAM_ACL_TRU64_DEFAULT_DIR_ACL:
       return generic_set_acl_on_os(jcr, BACL_TYPE_DEFAULT_DIR);
 }
 #endif
@@ -793,7 +768,7 @@ static bool acl_is_trivial(int count, struct acl_entry *entries, struct stat sb)
  */
 static bool hpux_build_acl_streams(JCR *jcr, FF_PKT *ff_pkt)
 {
-   int n, len;
+   int n;
    struct acl_entry acls[NACLENTRIES];
    char *acl_text;
 
@@ -835,10 +810,10 @@ static bool hpux_build_acl_streams(JCR *jcr, FF_PKT *ff_pkt)
       }
 
       if ((acl_text = acltostr(n, acls, FORM_SHORT)) != NULL) {
-         len = pm_strcpy(jcr->acl_data, acl_text);
+         jcr->acl_data_len = pm_strcpy(jcr->acl_data, acl_text);
          actuallyfree(acl_text);
 
-         return send_acl_stream(jcr, STREAM_ACL_HPUX_ACL_ENTRY, len);
+         return send_acl_stream(jcr, STREAM_ACL_HPUX_ACL_ENTRY);
       }
 
       berrno be;
@@ -939,35 +914,45 @@ char *acl_strerror(int);
  */
 static bool solaris_build_acl_streams(JCR *jcr, FF_PKT *ff_pkt)
 {
-   int len, flags;
+   int acl_enabled, flags;
    acl_t *aclp;
    char *acl_text;
    bool stream_status = false;
+   berrno be;
+
+   /*
+    * See if filesystem supports acls.
+    */
+   acl_enabled = pathconf(jcr->last_fname, _PC_ACL_ENABLED);
+   switch (acl_enabled) {
+   case 0:
+      pm_strcpy(jcr->acl_data, "");
+
+      return true;
+   case -1:
+      Jmsg2(jcr, M_ERROR, 0, _("pathconf error on file \"%s\": ERR=%s\n"),
+         jcr->last_fname, be.bstrerror());
+      Dmsg2(100, "pathconf error file=%s ERR=%s\n",  
+         jcr->last_fname, be.bstrerror());
+
+      return false;
+   default:
+      break;
+   }
 
    /*
     * Get ACL info: don't bother allocating space if there is only a trivial ACL.
     */
    if (acl_get(jcr->last_fname, ACL_NO_TRIVIAL, &aclp) != 0) {
-      switch (errno) {
-#if defined(BACL_ENOTSUP)
-      case BACL_ENOTSUP:
-         /*
-          * Not supported, just pretend there is nothing to see
-          */
-         pm_strcpy(jcr->acl_data, "");
-         return true;
-#endif
-      default:
-         Jmsg2(jcr, M_ERROR, 0, _("acl_get error on file \"%s\": ERR=%s\n"),
-            jcr->last_fname, acl_strerror(errno));
-         Dmsg2(100, "acl_get error file=%s ERR=%s\n",  
-            jcr->last_fname, acl_strerror(errno));
+      Jmsg2(jcr, M_ERROR, 0, _("acl_get error on file \"%s\": ERR=%s\n"),
+         jcr->last_fname, acl_strerror(errno));
+      Dmsg2(100, "acl_get error file=%s ERR=%s\n",  
+         jcr->last_fname, acl_strerror(errno));
 
-         return false;
-      }
+      return false;
    }
 
-   if (aclp == NULL) {
+   if (!aclp) {
       /*
        * The ACLs simply reflect the (already known) standard permissions
        * So we don't send an ACL stream to the SD.
@@ -986,15 +971,15 @@ static bool solaris_build_acl_streams(JCR *jcr, FF_PKT *ff_pkt)
 #endif /* ACL_SID_FMT */
 
    if ((acl_text = acl_totext(aclp, flags)) != NULL) {
-      len = pm_strcpy(jcr->acl_data, acl_text);
+      jcr->acl_data_len = pm_strcpy(jcr->acl_data, acl_text);
       actuallyfree(acl_text);
 
       switch (acl_type(aclp)) {
       case ACLENT_T:
-         stream_status = send_acl_stream(jcr, STREAM_ACL_SOLARIS_ACLENT_T, len);
+         stream_status = send_acl_stream(jcr, STREAM_ACL_SOLARIS_ACLENT);
          break;
       case ACE_T:
-         stream_status = send_acl_stream(jcr, STREAM_ACL_SOLARIS_ACE_T, len);
+         stream_status = send_acl_stream(jcr, STREAM_ACL_SOLARIS_ACE);
          break;
       default:
          break;
@@ -1009,12 +994,64 @@ static bool solaris_build_acl_streams(JCR *jcr, FF_PKT *ff_pkt)
 static bool solaris_parse_acl_stream(JCR *jcr, int stream)
 {
    acl_t *aclp;
-   int error;
+   int acl_enabled, error;
+   berrno be;
 
    switch (stream) {
    case STREAM_UNIX_ACCESS_ACL:
-   case STREAM_ACL_SOLARIS_ACLENT_T:
-   case STREAM_ACL_SOLARIS_ACE_T:
+   case STREAM_ACL_SOLARIS_ACLENT:
+   case STREAM_ACL_SOLARIS_ACE:
+      /*
+       * First make sure the filesystem supports acls.
+       */
+      acl_enabled = pathconf(jcr->last_fname, _PC_ACL_ENABLED);
+      switch (acl_enabled) {
+      case 0:
+         Jmsg1(jcr, M_ERROR, 0, _("Trying to restore acl on file \"%s\" on filesystem without acl support\n"),
+            jcr->last_fname);
+
+         return false;
+      case -1:
+         Jmsg2(jcr, M_ERROR, 0, _("pathconf error on file \"%s\": ERR=%s\n"),
+            jcr->last_fname, be.bstrerror());
+         Dmsg3(100, "pathconf error acl=%s file=%s ERR=%s\n",  
+            jcr->acl_data, jcr->last_fname, be.bstrerror());
+
+         return false;
+      default:
+         /*
+          * On a filesystem with ACL support make sure this particilar ACL type can be restored.
+          */
+         switch (stream) {
+         case STREAM_ACL_SOLARIS_ACLENT:
+            /*
+             * An aclent can be restored on filesystems with _ACL_ACLENT_ENABLED or _ACL_ACE_ENABLED support.
+             */
+            if ((acl_enabled & (_ACL_ACLENT_ENABLED | _ACL_ACE_ENABLED)) == 0) {
+               Jmsg1(jcr, M_ERROR, 0, _("Trying to restore acl on file \"%s\" on filesystem without aclent acl support\n"),
+                  jcr->last_fname);
+               return false;
+            }
+            break;
+         case STREAM_ACL_SOLARIS_ACE:
+            /*
+             * An ace can only be restored on a filesystem with _ACL_ACE_ENABLED support.
+             */
+            if ((acl_enabled & _ACL_ACE_ENABLED) == 0) {
+               Jmsg1(jcr, M_ERROR, 0, _("Trying to restore acl on file \"%s\" on filesystem without ace acl support\n"),
+                  jcr->last_fname);
+               return false;
+            }
+            break;
+         default:
+            /*
+             * Stream id which doesn't describe the type of acl which is encoded.
+             */
+            break;
+         }
+         break;
+      }
+
       if ((error = acl_fromtext(jcr->acl_data, &aclp)) != 0) {
          Jmsg2(jcr, M_ERROR, 0, _("acl_fromtext error on file \"%s\": ERR=%s\n"),
             jcr->last_fname, acl_strerror(error));
@@ -1027,18 +1064,20 @@ static bool solaris_parse_acl_stream(JCR *jcr, int stream)
        * Validate that the conversion gave us the correct acl type.
        */
       switch (stream) {
-      case STREAM_ACL_SOLARIS_ACLENT_T:
+      case STREAM_ACL_SOLARIS_ACLENT:
          if (acl_type(aclp) != ACLENT_T) {
             Jmsg1(jcr, M_ERROR, 0, _("wrong encoding of acl type in acl stream on file \"%s\"\n"),
                jcr->last_fname);
             return false;
          }
-      case STREAM_ACL_SOLARIS_ACE_T:
+         break;
+      case STREAM_ACL_SOLARIS_ACE:
          if (acl_type(aclp) != ACE_T) {
             Jmsg1(jcr, M_ERROR, 0, _("wrong encoding of acl type in acl stream on file \"%s\"\n"),
                jcr->last_fname);
             return false;
          }
+         break;
       default:
          /*
           * Stream id which doesn't describe the type of acl which is encoded.
@@ -1098,12 +1137,12 @@ static bool acl_is_trivial(int count, aclent_t *entries)
  */
 static bool solaris_build_acl_streams(JCR *jcr, FF_PKT *ff_pkt);
 {
-   int n, len;
+   int n;
    aclent_t *acls;
    char *acl_text;
 
    n = acl(jcr->last_fname, GETACLCNT, 0, NULL);
-   if (n < MIN_ACL_ENTRIES) {
+   if (n < MIN_ACL_ENTRIES)
       return false;
 
    acls = (aclent_t *)malloc(n * sizeof(aclent_t));
@@ -1119,11 +1158,11 @@ static bool solaris_build_acl_streams(JCR *jcr, FF_PKT *ff_pkt);
       }
 
       if ((acl_text = acltotext(acls, n)) != NULL) {
-         len = pm_strcpy(jcr->acl_data, acl_text);
+         jcr->acl_data_len = pm_strcpy(jcr->acl_data, acl_text);
          actuallyfree(acl_text);
          free(acls);
 
-         return send_acl_stream(jcr, STREAM_ACL_SOLARIS_ACLENT_T, len);
+         return send_acl_stream(jcr, STREAM_ACL_SOLARIS_ACLENT);
       }
 
       berrno be;
@@ -1225,13 +1264,13 @@ bool parse_acl_stream(JCR *jcr, int stream)
       return aix_parse_acl_stream(jcr, stream);
 #elif defined(HAVE_DARWIN_OS)
    case STREAM_UNIX_ACCESS_ACL:
-   case STREAM_ACL_DARWIN_ACCESS_ACL_T:
+   case STREAM_ACL_DARWIN_ACCESS_ACL:
       return darwin_parse_acl_stream(jcr, stream);
 #elif defined(HAVE_FREEBSD_OS)
    case STREAM_UNIX_ACCESS_ACL:
    case STREAM_UNIX_DEFAULT_ACL:
-   case STREAM_ACL_FREEBSD_DEFAULT_ACL_T:
-   case STREAM_ACL_FREEBSD_ACCESS_ACL_T:
+   case STREAM_ACL_FREEBSD_DEFAULT_ACL:
+   case STREAM_ACL_FREEBSD_ACCESS_ACL:
       return freebsd_parse_acl_stream(jcr, stream);
 #elif defined(HAVE_HPUX_OS)
    case STREAM_UNIX_ACCESS_ACL:
@@ -1240,27 +1279,27 @@ bool parse_acl_stream(JCR *jcr, int stream)
 #elif defined(HAVE_IRIX_OS)
    case STREAM_UNIX_ACCESS_ACL:
    case STREAM_UNIX_DEFAULT_ACL:
-   case STREAM_ACL_IRIX_DEFAULT_ACL_T:
-   case STREAM_ACL_IRIX_ACCESS_ACL_T:
+   case STREAM_ACL_IRIX_DEFAULT_ACL:
+   case STREAM_ACL_IRIX_ACCESS_ACL:
       return irix_parse_acl_stream(jcr, stream);
 #elif defined(HAVE_LINUX_OS)
    case STREAM_UNIX_ACCESS_ACL:
    case STREAM_UNIX_DEFAULT_ACL:
-   case STREAM_ACL_LINUX_DEFAULT_ACL_T:
-   case STREAM_ACL_LINUX_ACCESS_ACL_T:
+   case STREAM_ACL_LINUX_DEFAULT_ACL:
+   case STREAM_ACL_LINUX_ACCESS_ACL:
       return linux_parse_acl_stream(jcr, stream);
 #elif defined(HAVE_OSF1_OS)
    case STREAM_UNIX_ACCESS_ACL:
    case STREAM_UNIX_DEFAULT_ACL:
-   case STREAM_ACL_TRU64_DEFAULT_ACL_T:
-   case STREAM_ACL_TRU64_ACCESS_ACL_T:
-   case STREAM_ACL_TRU64_DEFAULT_DIR_ACL_T:
+   case STREAM_ACL_TRU64_DEFAULT_ACL:
+   case STREAM_ACL_TRU64_ACCESS_ACL:
+   case STREAM_ACL_TRU64_DEFAULT_DIR_ACL:
       return tru64_parse_acl_stream(jcr, stream);
 #elif defined(HAVE_SUN_OS)
    case STREAM_UNIX_ACCESS_ACL:
-   case STREAM_ACL_SOLARIS_ACLENT_T:
+   case STREAM_ACL_SOLARIS_ACLENT:
 #if defined(HAVE_EXTENDED_ACL)
-   case STREAM_ACL_SOLARIS_ACE_T:
+   case STREAM_ACL_SOLARIS_ACE:
 #endif
       return solaris_parse_acl_stream(jcr, stream);
 #endif