Allow a failure of EINVAL to mean no ACLs are available.
[rsync/rsync.git] / lib / sysacls.c
index beb6d0c..52314bc 100644 (file)
@@ -2,6 +2,7 @@
  * Unix SMB/CIFS implementation.
  * Based on the Samba ACL support code.
  * Copyright (C) Jeremy Allison 2000.
+ * Copyright (C) 2007-2008 Wayne Davison
  *
  * The permission functions have been changed to get/set all bits via
  * one call.  Some functions that rsync doesn't need were also removed.
@@ -550,7 +551,7 @@ SMB_ACL_T sys_acl_init(int count)
         * acl[] array, this actually allocates an ACL with room
         * for (count+1) entries
         */
-       if ((a = (SMB_ACL_T)SMB_MALLOC(sizeof(struct SMB_ACL_T) + count * sizeof(struct acl))) == NULL) {
+       if ((a = (SMB_ACL_T)SMB_MALLOC(sizeof a[0] + count * sizeof (struct acl))) == NULL) {
                errno = ENOMEM;
                return NULL;
        }
@@ -1006,7 +1007,7 @@ SMB_ACL_T sys_acl_init(int count)
         * acl[] array, this actually allocates an ACL with room
         * for (count+1) entries
         */
-       if ((a = SMB_MALLOC(sizeof(struct SMB_ACL_T) + count * sizeof(struct acl))) == NULL) {
+       if ((a = (SMB_ACL_T)SMB_MALLOC(sizeof a[0] + count * sizeof(struct acl))) == NULL) {
                errno = ENOMEM;
                return NULL;
        }
@@ -1637,14 +1638,14 @@ SMB_ACL_T sys_acl_init(int count)
                return NULL;
        }
 
-       if ((a = SMB_MALLOC(sizeof(struct SMB_ACL_T) + sizeof(struct acl))) == NULL) {
+       if ((a = (SMB_ACL_T)SMB_MALLOC(sizeof a[0] + sizeof (struct acl))) == NULL) {
                errno = ENOMEM;
                return NULL;
        }
 
        a->next = -1;
        a->freeaclp = False;
-       a->aclp = (struct acl *)(&a->aclp + sizeof(struct acl *));
+       a->aclp = (struct acl *)((char *)a + sizeof a[0]);
        a->aclp->acl_cnt = 0;
 
        return a;
@@ -1735,6 +1736,13 @@ int sys_acl_get_entry( SMB_ACL_T theacl, int entry_id, SMB_ACL_ENTRY_T *entry_p)
        struct new_acl_entry *entry;
        int keep_going;
 
+       if (entry_id == SMB_ACL_FIRST_ENTRY)
+               theacl->count = 0;
+       else if (entry_id != SMB_ACL_NEXT_ENTRY) {
+               errno = EINVAL;
+               return -1;
+       }
+
        DEBUG(10,("This is the count: %d\n",theacl->count));
 
        /* Check if count was previously set to -1. *
@@ -1804,11 +1812,14 @@ SMB_ACL_T sys_acl_get_file( const char *path_p, SMB_ACL_TYPE_T type)
        struct acl_entry_link *acl_entry_link_head;
        int i;
        int rc = 0;
-       uid_t user_id;
 
        /* AIX has no DEFAULT */
        if  ( type == SMB_ACL_TYPE_DEFAULT ) {
+#ifdef ENOTSUP
                errno = ENOTSUP;
+#else
+               errno = ENOSYS;
+#endif
                return NULL;
        }
 
@@ -2025,7 +2036,6 @@ SMB_ACL_T sys_acl_get_fd(int fd)
        struct acl_entry_link *acl_entry_link_head;
        int i;
        int rc = 0;
-       uid_t user_id;
 
        /* Get the acl using fstatacl */
    
@@ -2255,6 +2265,11 @@ SMB_ACL_T sys_acl_init( int count)
 {
        struct acl_entry_link *theacl = NULL;
  
+       if (count < 0) {
+               errno = EINVAL;
+               return NULL;
+       }
+
        DEBUG(10,("Entering sys_acl_init\n"));
 
        theacl = SMB_MALLOC_P(struct acl_entry_link);
@@ -2373,7 +2388,6 @@ int sys_acl_set_file( const char *name, SMB_ACL_TYPE_T acltype, SMB_ACL_T theacl
        struct acl_entry *acl_entry = NULL;
        struct ace_id *ace_id = NULL;
        uint id_type;
-       uint ace_access;
        uint user_id;
        uint acl_length;
        uint rc;
@@ -2551,7 +2565,7 @@ int sys_acl_set_fd( int fd, SMB_ACL_T theacl)
 }
 #endif
 
-int sys_acl_delete_def_file(const char *name)
+int sys_acl_delete_def_file(UNUSED(const char *name))
 {
        /* AIX has no default ACL */
        return 0;
@@ -2694,6 +2708,8 @@ int sys_acl_set_info(SMB_ACL_ENTRY_T entry, SMB_ACL_TAG_T tag_type, uint32 bits,
                rc = mbr_uid_to_uuid(u_g_id, uu);
        else
                rc = mbr_gid_to_uuid(u_g_id, uu);
+       if (rc != 0)
+               return rc;
 
        if (acl_set_tag_type(entry, tag_type) != 0
         || acl_set_qualifier(entry, &uu) != 0
@@ -2765,6 +2781,11 @@ int no_acl_syscall_error(int err)
                return 1;
        }
 #endif
+       if (err == EINVAL) {
+               /* If the type of SMB_ACL_TYPE_ACCESS or SMB_ACL_TYPE_DEFAULT
+                * isn't valid, then the ACLs must be non-POSIX. */
+               return 1;
+       }
        return 0;
 }