]> git.sur5r.net Git - bacula/bacula/blobdiff - bacula/src/filed/acl.c
update configure
[bacula/bacula] / bacula / src / filed / acl.c
index 4a5547b0dc30f1e4083dbca8d5fd254b6c20c5e5..cfe2c64be3311ef4c4cb0968bd21cfad9f80854d 100644 (file)
@@ -38,8 +38,6 @@
  *   - Solaris (POSIX and NFSv4/ZFS acls)
  *   - Tru64
  *
- * Next to OS specific acls we support AFS acls using the pioctl interface.
- *
  * We handle two different types of ACLs: access and default ACLS.
  * On most systems that support default ACLs they only apply to directories.
  *
@@ -64,7 +62,7 @@
 #include "bacula.h"
 #include "filed.h"
   
-#if !defined(HAVE_ACL) && !defined(HAVE_AFS_ACL)
+#if !defined(HAVE_ACL)
 /**
  * Entry points when compiled without support for ACLs or on an unsupported platform.
  */
@@ -480,7 +478,7 @@ static acl_type_t bac_to_os_acltype(bacl_type acltype)
    case BACL_TYPE_DEFAULT:
       ostype = ACL_TYPE_DEFAULT;
       break;
-#ifdef ACL_TYPE_NFS4
+#ifdef HAVE_ACL_TYPE_NFS4
       /**
        * FreeBSD has an additional acl type named ACL_TYPE_NFS4.
        */
@@ -488,7 +486,7 @@ static acl_type_t bac_to_os_acltype(bacl_type acltype)
       ostype = ACL_TYPE_NFS4;
       break;
 #endif
-#ifdef ACL_TYPE_DEFAULT_DIR
+#ifdef HAVE_ACL_TYPE_DEFAULT_DIR
    case BACL_TYPE_DEFAULT_DIR:
       /**
        * TRU64 has an additional acl type named ACL_TYPE_DEFAULT_DIR.
@@ -496,7 +494,7 @@ static acl_type_t bac_to_os_acltype(bacl_type acltype)
       ostype = ACL_TYPE_DEFAULT_DIR;
       break;
 #endif
-#ifdef ACL_TYPE_EXTENDED
+#ifdef HAVE_ACL_TYPE_EXTENDED
    case BACL_TYPE_EXTENDED:
       /**
        * MacOSX has an additional acl type named ACL_TYPE_EXTENDED.
@@ -515,6 +513,36 @@ static acl_type_t bac_to_os_acltype(bacl_type acltype)
    return ostype;
 }
 
+static int acl_count_entries(acl_t acl)
+{
+   int count = 0;
+#if defined(HAVE_FREEBSD_OS) || \
+    defined(HAVE_LINUX_OS)
+   acl_entry_t ace;
+   int entry_available;
+
+   entry_available = acl_get_entry(acl, ACL_FIRST_ENTRY, &ace);
+   while (entry_available == 1) {
+      count++;
+      entry_available = acl_get_entry(acl, ACL_NEXT_ENTRY, &ace);
+   }
+#elif defined(HAVE_IRIX_OS)
+   count = acl->acl_cnt;
+#elif defined(HAVE_OSF1_OS)
+   count = acl->acl_num;
+#elif defined(HAVE_DARWIN_OS)
+   acl_entry_t ace;
+   int entry_available;
+
+   entry_available = acl_get_entry(acl, ACL_FIRST_ENTRY, &ace);
+   while (entry_available == 0) {
+      count++;
+      entry_available = acl_get_entry(acl, ACL_NEXT_ENTRY, &ace);
+   }
+#endif
+   return count;
+}
+
 #if !defined(HAVE_DARWIN_OS)
 /**
  * See if an acl is a trivial one (e.g. just the stat bits encoded as acl.)
@@ -606,30 +634,23 @@ static bacl_exit_code generic_get_acl_from_os(JCR *jcr, bacl_type acltype)
    acl_type_t ostype;
    char *acl_text;
    berrno be;
+   bacl_exit_code retval = bacl_exit_ok;
 
    ostype = bac_to_os_acltype(acltype);
    acl = acl_get_file(jcr->last_fname, ostype);
    if (acl) {
-#if defined(HAVE_IRIX_OS)
       /**
        * From observation, IRIX's acl_get_file() seems to return a
        * non-NULL acl with a count field of -1 when a file has no ACL
        * defined, while IRIX's acl_to_text() returns NULL when presented
        * with such an ACL. 
        *
-       * Checking the count in the acl structure before calling
-       * acl_to_text() lets us avoid error messages about files
-       * with no ACLs, without modifying the flow of the code used for 
-       * other operating systems, and it saves making some calls
-       * to acl_to_text() besides.
+       * For all other implmentations we check if there are more then
+       * zero entries in the acl returned.
        */
-      if (acl->acl_cnt <= 0) {
-         pm_strcpy(jcr->acl_data->content, "");
-         jcr->acl_data->content_length = 0;
-         acl_free(acl);
-         return bacl_exit_ok;
+      if (acl_count_entries(acl) <= 0) {
+         goto bail_out;
       }
-#endif
 
       /**
        * Make sure this is not just a trivial ACL.
@@ -640,10 +661,7 @@ static bacl_exit_code generic_get_acl_from_os(JCR *jcr, bacl_type acltype)
           * The ACLs simply reflect the (already known) standard permissions
           * So we don't send an ACL stream to the SD.
           */
-         pm_strcpy(jcr->acl_data->content, "");
-         jcr->acl_data->content_length = 0;
-         acl_free(acl);
-         return bacl_exit_ok;
+         goto bail_out;
       }
 #endif
 #if defined(HAVE_FREEBSD_OS) && defined(_PC_ACL_NFS4)
@@ -655,15 +673,15 @@ static bacl_exit_code generic_get_acl_from_os(JCR *jcr, bacl_type acltype)
                 * The ACLs simply reflect the (already known) standard permissions
                 * So we don't send an ACL stream to the SD.
                 */
-               pm_strcpy(jcr->acl_data->content, "");
-               jcr->acl_data->content_length = 0;
-               acl_free(acl);
-               return bacl_exit_ok;
+               goto bail_out;
             }
          }
       }
 #endif
 
+      /**
+       * Convert the internal acl representation into a text representation.
+       */
       if ((acl_text = acl_to_text(acl, NULL)) != NULL) {
          jcr->acl_data->content_length = pm_strcpy(jcr->acl_data->content, acl_text);
          acl_free(acl);
@@ -676,16 +694,12 @@ static bacl_exit_code generic_get_acl_from_os(JCR *jcr, bacl_type acltype)
       Dmsg2(100, "acl_to_text error file=%s ERR=%s\n",  
             jcr->last_fname, be.bstrerror());
 
-      pm_strcpy(jcr->acl_data->content, "");
-      jcr->acl_data->content_length = 0;
-      acl_free(acl);
-      return bacl_exit_error;
-   }
-
-   /**
-    * Handle errors gracefully.
-    */
-   if (acl == (acl_t)NULL) {
+      retval = bacl_exit_error;
+      goto bail_out;
+   } else {
+      /**
+       * Handle errors gracefully.
+       */
       switch (errno) {
 #if defined(BACL_ENOTSUP)
       case BACL_ENOTSUP:
@@ -696,12 +710,10 @@ static bacl_exit_code generic_get_acl_from_os(JCR *jcr, bacl_type acltype)
           * when we change from one filesystem to an other.
           */
          jcr->acl_data->flags &= ~BACL_FLAG_SAVE_NATIVE;
-         break;                       /* not supported */
+         goto bail_out;
 #endif
       case ENOENT:
-         pm_strcpy(jcr->acl_data->content, "");
-         jcr->acl_data->content_length = 0;
-         return bacl_exit_ok;
+         goto bail_out;
       default:
          /* Some real error */
          Mmsg2(jcr->errmsg, _("acl_get_file error on file \"%s\": ERR=%s\n"),
@@ -709,18 +721,18 @@ static bacl_exit_code generic_get_acl_from_os(JCR *jcr, bacl_type acltype)
          Dmsg2(100, "acl_get_file error file=%s ERR=%s\n",  
                jcr->last_fname, be.bstrerror());
 
-         pm_strcpy(jcr->acl_data->content, "");
-         jcr->acl_data->content_length = 0;
-         return bacl_exit_error;
+         retval = bacl_exit_error;
+         goto bail_out;
       }
    }
 
-   /**
-    * Not supported, just pretend there is nothing to see
-    */
+bail_out:
+   if (acl) {
+      acl_free(acl);
+   }
    pm_strcpy(jcr->acl_data->content, "");
    jcr->acl_data->content_length = 0;
-   return bacl_exit_ok;
+   return retval;
 }
 
 /**
@@ -810,7 +822,7 @@ static int os_default_acl_streams[1] = { -1 };
 
 static bacl_exit_code darwin_build_acl_streams(JCR *jcr, FF_PKT *ff_pkt)
 {
-#if defined(ACL_TYPE_EXTENDED)
+#if defined(HAVE_ACL_TYPE_EXTENDED)
    /**
     * On MacOS X, acl_get_file (name, ACL_TYPE_ACCESS)
     * and acl_get_file (name, ACL_TYPE_DEFAULT)
@@ -838,7 +850,7 @@ static bacl_exit_code darwin_build_acl_streams(JCR *jcr, FF_PKT *ff_pkt)
 
 static bacl_exit_code darwin_parse_acl_streams(JCR *jcr, int stream)
 {
-#if defined(ACL_TYPE_EXTENDED)
+#if defined(HAVE_ACL_TYPE_EXTENDED)
       return generic_set_acl_on_os(jcr, BACL_TYPE_EXTENDED);
 #else
       return generic_set_acl_on_os(jcr, BACL_TYPE_ACCESS);
@@ -881,6 +893,8 @@ static bacl_exit_code freebsd_build_acl_streams(JCR *jcr, FF_PKT *ff_pkt)
                jcr->last_fname, be.bstrerror());
          return bacl_exit_error;
       }
+   case 0:
+      break;
    default:
       acltype = BACL_TYPE_NFS4;
       break;
@@ -904,6 +918,8 @@ static bacl_exit_code freebsd_build_acl_streams(JCR *jcr, FF_PKT *ff_pkt)
                   jcr->last_fname, be.bstrerror());
             return bacl_exit_error;
          }
+      case 0:
+         break;
       default:
          acltype = BACL_TYPE_ACCESS;
          break;
@@ -973,6 +989,7 @@ static bacl_exit_code freebsd_build_acl_streams(JCR *jcr, FF_PKT *ff_pkt)
 static bacl_exit_code freebsd_parse_acl_streams(JCR *jcr, int stream)
 {
    int acl_enabled = 0;
+   const char *acl_type_name;
    berrno be;
 
    /**
@@ -984,21 +1001,20 @@ static bacl_exit_code freebsd_parse_acl_streams(JCR *jcr, int stream)
    case STREAM_UNIX_DEFAULT_ACL:
    case STREAM_ACL_FREEBSD_DEFAULT_ACL:
       acl_enabled = pathconf(jcr->last_fname, _PC_ACL_EXTENDED);
+      acl_type_name = "POSIX";
       break;
    case STREAM_ACL_FREEBSD_NFS4_ACL:
 #if defined(_PC_ACL_NFS4)
       acl_enabled = pathconf(jcr->last_fname, _PC_ACL_NFS4);
 #endif
+      acl_type_name = "NFS4";
       break;
    default:
+      acl_type_name = "unknown";
       break;
    }
 
    switch (acl_enabled) {
-   case 0:
-      Mmsg1(jcr->errmsg, _("Trying to restore acl on file \"%s\" on filesystem without acl support\n"),
-            jcr->last_fname);
-      return bacl_exit_error;
    case -1:
       switch (errno) {
       case ENOENT:
@@ -1010,6 +1026,12 @@ static bacl_exit_code freebsd_parse_acl_streams(JCR *jcr, int stream)
                jcr->acl_data->content, jcr->last_fname, be.bstrerror());
          return bacl_exit_error;
       }
+   case 0:
+      Mmsg2(jcr->errmsg, _("Trying to restore acl on file \"%s\" on filesystem without %s acl support\n"),
+            jcr->last_fname, acl_type_name);
+      return bacl_exit_error;
+   default:
+      break;
    }
 
    /**