diff --git a/syscall.c b/syscall.c
index ecca2f1..4b82d97 100644
--- a/syscall.c
+++ b/syscall.c
@@ -22,6 +22,10 @@
 
 #include "rsync.h"
 
+#ifdef HAVE_SYS_ACL_H
+#include <sys/acl.h>
+#endif
+
 #if !defined MKNOD_CREATES_SOCKETS && defined HAVE_SYS_UN_H
 #include <sys/un.h>
 #endif
@@ -214,8 +218,31 @@ int do_chmod(const char *path, mode_t mode)
 # else
 		code = 1;
 # endif
-	} else
+	} else {
+#ifdef HAVE_AIX_ACLS
+		struct stat s;
+		if (stat(path, &s) == -1)
+			return -1;
+#endif
 		code = chmod(path, mode & CHMOD_BITS); /* DISCOURAGED FUNCTION */
+#ifdef HAVE_AIX_ACLS
+		/* The extended permissions are disabled when use the
+		 * chmod() on AIX, so we must enable it again */
+		struct acl *acl;
+		
+		if (s.st_mode & S_IXACL) {
+			/* BUFSIZ equal MAX_ACL_SIZE */
+			if ((acl = (struct acl *)calloc(BUFSIZ, 1)) == NULL)
+				return -1;
+			if (statacl((char *)path, 0, acl, BUFSIZ) < 0)
+				return -1;
+			acl->acl_mode |= S_IXACL;
+			if (chacl((char *)path, acl, acl->acl_len) < 0)
+				return -1;
+			free(acl);
+		}
+#endif
+	}
 #endif /* !HAVE_LCHMOD */
 	if (code != 0 && (preserve_perms || preserve_executability))
 		return code;
diff --git a/rsync.c b/rsync.c
index f1404ce..faacc04 100644
--- a/rsync.c
+++ b/rsync.c
@@ -579,7 +579,11 @@ int set_file_attrs(const char *fname, struct file_struct *file, stat_x *sxp,
 #endif
 
 #ifdef HAVE_CHMOD
+#ifndef HAVE_AIX_ACLS
 	if (!BITS_EQUAL(sxp->st.st_mode, new_mode, CHMOD_BITS)) {
+#endif
+		/* Because chmod will disable extended permissions on
+		 * AIX, so always use do_chmod update permissions */
 		int ret = am_root < 0 ? 0 : do_chmod(fname, new_mode);
 		if (ret < 0) {
 			rsyserr(FERROR_XFER, errno,
@@ -589,8 +593,10 @@ int set_file_attrs(const char *fname, struct file_struct *file, stat_x *sxp,
 		}
 		if (ret == 0) /* ret == 1 if symlink could not be set */
 			updated = 1;
+#ifndef HAVE_AIX_ACLS
 	}
 #endif
+#endif
 
 	if (INFO_GTE(NAME, 2) && flags & ATTRS_REPORT) {
 		if (updated)
diff --git a/lib/sysacls.c b/lib/sysacls.c
index e11a988..c7491c7 100644
--- a/lib/sysacls.c
+++ b/lib/sysacls.c
@@ -1796,6 +1796,7 @@ int sys_acl_get_tag_type( SMB_ACL_ENTRY_T entry_d, SMB_ACL_TAG_T *tag_type_p)
 	case SMB_ACL_USER_OBJ:
 	case SMB_ACL_GROUP_OBJ:
 	case SMB_ACL_OTHER:
+	case SMB_ACL_MASK:
 		*tag_type_p = entry_d->ace_id->id_type;
 		break;
 
@@ -2418,7 +2419,7 @@ int sys_acl_set_file( const char *name, SMB_ACL_TYPE_T acltype, SMB_ACL_T theacl
 	file_acl->acl_mode = S_IXACL;
 
 	for(acl_entry_link=theacl; acl_entry_link != NULL; acl_entry_link = acl_entry_link->nextp) {
-		acl_entry_link->entryp->ace_access >>= 6;
+		/* acl_entry_link->entryp->ace_access >>= 6; */
 		id_type = acl_entry_link->entryp->ace_id->id_type;
 
 		switch(id_type) {
