++ sys_acl_free_acl(*smb_acl);
++ return False;
++}
++
++static mode_t change_sacl_perms(SMB_ACL_T sacl, uchar mask, mode_t old_mode, mode_t mode)
++{
++ SMB_ACL_ENTRY_T entry;
++ int group_id = mask != NO_ENTRY ? SMB_ACL_MASK : SMB_ACL_GROUP_OBJ;
++ const char *errfun;
++ int rc;
++
++ if (S_ISDIR(mode)) {
++ /* If the sticky bit is going on, it's not safe to allow all
++ * the new ACLs to go into effect before it gets set. */
++ if (mode & S_ISVTX && !(old_mode & S_ISVTX))
++ mode &= ~0077;
++ } else {
++ /* If setuid or setgid is going off, it's not safe to allow all
++ * the new ACLs to go into effect before they get cleared. */
++ if ((old_mode & S_ISUID && !(mode & S_ISUID))
++ || (old_mode & S_ISGID && !(mode & S_ISGID)))
++ mode &= ~0077;
++ }
++
++ errfun = "sys_acl_get_entry";
++ for (rc = sys_acl_get_entry(sacl, SMB_ACL_FIRST_ENTRY, &entry);
++ rc == 1;
++ rc = sys_acl_get_entry(sacl, SMB_ACL_NEXT_ENTRY, &entry)) {
++ SMB_ACL_TAG_T tag_type;
++ if ((rc = sys_acl_get_tag_type(entry, &tag_type))) {
++ errfun = "sys_acl_get_tag_type";
++ break;
++ }
++ if (tag_type == SMB_ACL_USER_OBJ)
++ COE2( store_access_in_entry,((mode >> 6) & 7, entry) );
++ else if (tag_type == group_id)
++ COE2( store_access_in_entry,((mode >> 3) & 7, entry) );
++ else if (tag_type == SMB_ACL_OTHER)
++ COE2( store_access_in_entry,(mode & 7, entry) );
++ }
++ if (rc) {
++ error_exit:
++ if (errfun) {
++ rprintf(FERROR, "change_sacl_perms: %s(): %s\n",
++ errfun, strerror(errno));
++ }
++ return ~0u;
++ }
++
++ /* Return the mode of the file on disk, as we will set them. */
++ return (old_mode & ~ACCESSPERMS) | (mode & ACCESSPERMS);