s3:utils: let smbstatus report anonymous signing/encryption explicitly
[samba.git] / source3 / modules / vfs_fake_acls.c
index e6983d49c584725e06e15d7c118d13d2e1f8c5b2..fefe6c5483e388ab802a02dee8d7db90fb9a88dd 100644 (file)
 #define FAKE_ACL_ACCESS_XATTR "system.fake_access_acl"
 #define FAKE_ACL_DEFAULT_XATTR "system.fake_default_acl"
 
-static int fake_acls_uid(vfs_handle_struct *handle,
-                        struct smb_filename *smb_fname,
-                        uid_t *uid)
-{
-       ssize_t size;
-       uint8_t uid_buf[4];
-       size = SMB_VFS_NEXT_GETXATTR(handle, smb_fname,
-                       FAKE_UID, uid_buf, sizeof(uid_buf));
-       if (size == -1 && errno == ENOATTR) {
-               return 0;
-       }
-       if (size != 4) {
-               return -1;
-       }
-       *uid = IVAL(uid_buf, 0);
-       return 0;
-}
-
-static int fake_acls_gid(vfs_handle_struct *handle,
-                        struct smb_filename *smb_fname,
-                        uid_t *gid)
-{
-       ssize_t size;
-       uint8_t gid_buf[4];
-
-       size = SMB_VFS_NEXT_GETXATTR(handle, smb_fname,
-                       FAKE_GID, gid_buf, sizeof(gid_buf));
-       if (size == -1 && errno == ENOATTR) {
-               return 0;
-       }
-       if (size != 4) {
-               return -1;
-       }
-       *gid = IVAL(gid_buf, 0);
-       return 0;
-}
+struct in_pathref_data {
+       bool calling_pathref_fsp;
+};
 
 static int fake_acls_fuid(vfs_handle_struct *handle,
                           files_struct *fsp,
@@ -112,42 +79,100 @@ static int fake_acls_stat(vfs_handle_struct *handle,
                           struct smb_filename *smb_fname)
 {
        int ret = -1;
+       struct in_pathref_data *prd = NULL;
+       struct smb_filename *smb_fname_cp = NULL;
+       struct files_struct *fsp = NULL;
+
+       SMB_VFS_HANDLE_GET_DATA(handle,
+                               prd,
+                               struct in_pathref_data,
+                               return -1);
 
        ret = SMB_VFS_NEXT_STAT(handle, smb_fname);
-       if (ret == 0) {
-               TALLOC_CTX *frame = talloc_stackframe();
-               char *path;
-               struct smb_filename smb_fname_base = {
-                       .base_name = smb_fname->base_name
-               };
+       if (ret != 0) {
+               return ret;
+       }
+
+       if (smb_fname->fsp != NULL) {
+               fsp = metadata_fsp(smb_fname->fsp);
+       } else {
                NTSTATUS status;
+
                /*
-                * As we're calling getxattr directly here
-                * we need to use only the base_name, not
-                * the full name containing any stream name.
+                * Ensure openat_pathref_fsp()
+                * can't recurse into fake_acls_stat().
+                * openat_pathref_fsp() doesn't care
+                * about the uid/gid values, it only
+                * wants a valid/invalid stat answer
+                * and we know smb_fname exists as
+                * the SMB_VFS_NEXT_STAT() returned
+                * zero above.
                 */
-               status = get_full_smb_filename(frame, &smb_fname_base, &path);
-               if (!NT_STATUS_IS_OK(status)) {
-                       errno = map_errno_from_nt_status(status);
-                       TALLOC_FREE(frame);
-                       return -1;
+               if (prd->calling_pathref_fsp) {
+                       return 0;
                }
-               
-               ret = fake_acls_uid(handle, &smb_fname_base,
-                                       &smb_fname->st.st_ex_uid);
-               if (ret != 0) {
-                       TALLOC_FREE(frame);
-                       return ret;
+
+               /*
+                * openat_pathref_fsp() expects a talloc'ed
+                * smb_filename. stat can be passed a struct
+                * from the stack. Make a talloc'ed copy
+                * so openat_pathref_fsp() can add its
+                * destructor.
+                */
+               smb_fname_cp = cp_smb_filename(talloc_tos(),
+                                              smb_fname);
+               if (smb_fname_cp == NULL) {
+                       errno = ENOMEM;
+                       return -1;
                }
-               ret = fake_acls_gid(handle, &smb_fname_base,
-                                       &smb_fname->st.st_ex_gid);
-               if (ret != 0) {
-                       TALLOC_FREE(frame);
-                       return ret;
+
+               /* Recursion guard. */
+               prd->calling_pathref_fsp = true;
+               status = openat_pathref_fsp(handle->conn->cwd_fsp,
+                                           smb_fname_cp);
+               /* End recursion guard. */
+               prd->calling_pathref_fsp = false;
+
+               if (!NT_STATUS_IS_OK(status)) {
+                       /*
+                        * Ignore errors here. We know
+                        * the path exists (the SMB_VFS_NEXT_STAT()
+                        * above succeeded. So being unable to
+                        * open a pathref fsp can be due to a
+                        * range of errors (startup path beginning
+                        * with '/' for example, path = ".." when
+                        * enumerating a directory. Just treat this
+                        * the same way as the path not having the
+                        * FAKE_UID or FAKE_GID EA's present. For the
+                        * test purposes of this module (fake NT ACLs
+                        * from windows clients) this is close enough.
+                        * Just report for debugging purposes.
+                        */
+                       DBG_DEBUG("Unable to get pathref fsp on %s. "
+                                 "Error %s\n",
+                                 smb_fname_str_dbg(smb_fname_cp),
+                                 nt_errstr(status));
+                       TALLOC_FREE(smb_fname_cp);
+                       return 0;
                }
-               TALLOC_FREE(frame);
+               fsp = smb_fname_cp->fsp;
        }
 
+       ret = fake_acls_fuid(handle,
+                            fsp,
+                            &smb_fname->st.st_ex_uid);
+       if (ret != 0) {
+               TALLOC_FREE(smb_fname_cp);
+               return ret;
+       }
+       ret = fake_acls_fgid(handle,
+                            fsp,
+                            &smb_fname->st.st_ex_gid);
+       if (ret != 0) {
+               TALLOC_FREE(smb_fname_cp);
+               return ret;
+       }
+       TALLOC_FREE(smb_fname_cp);
        return ret;
 }
 
@@ -155,39 +180,63 @@ static int fake_acls_lstat(vfs_handle_struct *handle,
                           struct smb_filename *smb_fname)
 {
        int ret = -1;
+       struct in_pathref_data *prd = NULL;
+
+       SMB_VFS_HANDLE_GET_DATA(handle,
+                               prd,
+                               struct in_pathref_data,
+                               return -1);
 
        ret = SMB_VFS_NEXT_LSTAT(handle, smb_fname);
        if (ret == 0) {
-               TALLOC_CTX *frame = talloc_stackframe();
-               char *path;
-               struct smb_filename smb_fname_base = {
-                       .base_name = smb_fname->base_name
-               };
+               struct smb_filename *smb_fname_base = NULL;
+               SMB_STRUCT_STAT sbuf = { 0 };
                NTSTATUS status;
+
                /*
-                * As we're calling getxattr directly here
-                * we need to use only the base_name, not
-                * the full name containing any stream name.
+                * Ensure synthetic_pathref()
+                * can't recurse into fake_acls_lstat().
+                * synthetic_pathref() doesn't care
+                * about the uid/gid values, it only
+                * wants a valid/invalid stat answer
+                * and we know smb_fname exists as
+                * the SMB_VFS_NEXT_LSTAT() returned
+                * zero above.
                 */
-               status = get_full_smb_filename(frame, &smb_fname_base, &path);
-               if (!NT_STATUS_IS_OK(status)) {
-                       errno = map_errno_from_nt_status(status);
-                       TALLOC_FREE(frame);
-                       return -1;
+               if (prd->calling_pathref_fsp) {
+                       return 0;
                }
 
-               /* This isn't quite right (calling getxattr not
-                * lgetxattr), but for the test purposes of this
-                * module (fake NT ACLs from windows clients), it is
-                * close enough.  We removed the l*xattr functions
-                * because linux doesn't support using them, but we
-                * could fake them in xattr_tdb if we really wanted
-                * to.  We ignore errors because the link might not point anywhere */
-               fake_acls_uid(handle, &smb_fname_base,
-                       &smb_fname->st.st_ex_uid);
-               fake_acls_gid(handle, &smb_fname_base,
-                       &smb_fname->st.st_ex_gid);
-               TALLOC_FREE(frame);
+               /* Recursion guard. */
+               prd->calling_pathref_fsp = true;
+               status = synthetic_pathref(talloc_tos(),
+                                          handle->conn->cwd_fsp,
+                                          smb_fname->base_name,
+                                          NULL,
+                                          &sbuf,
+                                          smb_fname->twrp,
+                                          0, /* we want stat, not lstat. */
+                                          &smb_fname_base);
+               /* End recursion guard. */
+               prd->calling_pathref_fsp = false;
+               if (NT_STATUS_IS_OK(status)) {
+                       /*
+                        * This isn't quite right (calling fgetxattr not
+                        * lgetxattr), but for the test purposes of this
+                        * module (fake NT ACLs from windows clients), it is
+                        * close enough.  We removed the l*xattr functions
+                        * because linux doesn't support using them, but we
+                        * could fake them in xattr_tdb if we really wanted
+                        * to. We ignore errors because the link might not
+                        * point anywhere */
+                       fake_acls_fuid(handle,
+                                      smb_fname_base->fsp,
+                                      &smb_fname->st.st_ex_uid);
+                       fake_acls_fgid(handle,
+                                      smb_fname_base->fsp,
+                                      &smb_fname->st.st_ex_gid);
+               }
+               TALLOC_FREE(smb_fname_base);
        }
 
        return ret;
@@ -247,16 +296,17 @@ static DATA_BLOB fake_acls_acl2blob(TALLOC_CTX *mem_ctx, SMB_ACL_T acl)
        return blob;
 }
 
-static SMB_ACL_T fake_acls_sys_acl_get_file(struct vfs_handle_struct *handle,
-                               const struct smb_filename *smb_fname,
-                               SMB_ACL_TYPE_T type,
-                               TALLOC_CTX *mem_ctx)
+static SMB_ACL_T fake_acls_sys_acl_get_fd(struct vfs_handle_struct *handle,
+                                         files_struct *fsp,
+                                         SMB_ACL_TYPE_T type,
+                                         TALLOC_CTX *mem_ctx)
 {
        DATA_BLOB blob = data_blob_null;
        ssize_t length;
        const char *name = NULL;
        struct smb_acl_t *acl = NULL;
        TALLOC_CTX *frame = talloc_stackframe();
+               
        switch (type) {
        case SMB_ACL_TYPE_ACCESS:
                name = FAKE_ACL_ACCESS_XATTR;
@@ -264,41 +314,16 @@ static SMB_ACL_T fake_acls_sys_acl_get_file(struct vfs_handle_struct *handle,
        case SMB_ACL_TYPE_DEFAULT:
                name = FAKE_ACL_DEFAULT_XATTR;
                break;
+       default:
+               DBG_ERR("Illegal ACL type %d\n", (int)type);
+               break;
        }
 
-       do {
-               blob.length += 1000;
-               blob.data = talloc_realloc(frame, blob.data, uint8_t, blob.length);
-               if (!blob.data) {
-                       errno = ENOMEM;
-                       TALLOC_FREE(frame);
-                       return NULL;
-               }
-               length = SMB_VFS_NEXT_GETXATTR(handle, smb_fname,
-                               name, blob.data, blob.length);
-               blob.length = length;
-       } while (length == -1 && errno == ERANGE);
-       if (length == -1 && errno == ENOATTR) {
+       if (name == NULL) {
                TALLOC_FREE(frame);
                return NULL;
        }
-       if (length != -1) {
-               acl = fake_acls_blob2acl(&blob, mem_ctx);
-       }
-       TALLOC_FREE(frame);
-       return acl;
-}
 
-static SMB_ACL_T fake_acls_sys_acl_get_fd(struct vfs_handle_struct *handle,
-                                         files_struct *fsp,
-                                         TALLOC_CTX *mem_ctx)
-{
-       DATA_BLOB blob = data_blob_null;
-       ssize_t length;
-       const char *name = FAKE_ACL_ACCESS_XATTR;
-       struct smb_acl_t *acl = NULL;
-       TALLOC_CTX *frame = talloc_stackframe();
-               
        do {
                blob.length += 1000;
                blob.data = talloc_realloc(frame, blob.data, uint8_t, blob.length);
@@ -321,11 +346,10 @@ static SMB_ACL_T fake_acls_sys_acl_get_fd(struct vfs_handle_struct *handle,
        return acl;
 }
 
-
-static int fake_acls_sys_acl_set_file(vfs_handle_struct *handle,
-                       const struct smb_filename *smb_fname,
-                       SMB_ACL_TYPE_T acltype,
-                       SMB_ACL_T theacl)
+static int fake_acls_sys_acl_set_fd(vfs_handle_struct *handle,
+                                   struct files_struct *fsp,
+                                   SMB_ACL_TYPE_T type,
+                                   SMB_ACL_T theacl)
 {
        int ret;
        const char *name = NULL;
@@ -337,114 +361,44 @@ static int fake_acls_sys_acl_set_file(vfs_handle_struct *handle,
                errno = EINVAL;
                return -1;
        }
-       switch (acltype) {
+
+       switch (type) {
        case SMB_ACL_TYPE_ACCESS:
                name = FAKE_ACL_ACCESS_XATTR;
                break;
        case SMB_ACL_TYPE_DEFAULT:
                name = FAKE_ACL_DEFAULT_XATTR;
                break;
-       }
-       ret = SMB_VFS_NEXT_SETXATTR(handle, smb_fname,
-                       name, blob.data, blob.length, 0);
-       TALLOC_FREE(frame);
-       return ret;
-}
-
-static int fake_acls_sys_acl_set_fd(vfs_handle_struct *handle, files_struct *fsp, SMB_ACL_T theacl)
-{
-       int ret;
-       const char *name = FAKE_ACL_ACCESS_XATTR;
-       TALLOC_CTX *frame = talloc_stackframe();
-       DATA_BLOB blob = fake_acls_acl2blob(frame, theacl);
-       if (!blob.data) {
-               DEBUG(0, ("Failed to convert ACL to linear blob for xattr storage\n"));
-               TALLOC_FREE(frame);
+       default:
                errno = EINVAL;
                return -1;
        }
+
        ret = SMB_VFS_NEXT_FSETXATTR(handle, fsp, name, blob.data, blob.length, 0);
        TALLOC_FREE(frame);
        return ret;
 }
 
-static int fake_acls_sys_acl_delete_def_file(vfs_handle_struct *handle,
-                       const struct smb_filename *smb_fname_in)
+static int fake_acls_sys_acl_delete_def_fd(vfs_handle_struct *handle,
+                       struct files_struct *fsp)
 {
        int ret;
        const char *name = FAKE_ACL_DEFAULT_XATTR;
-       TALLOC_CTX *frame = talloc_stackframe();
-       struct smb_filename *smb_fname = cp_smb_filename_nostream(talloc_tos(),
-                                               smb_fname_in);
-
-       if (smb_fname == NULL) {
-               TALLOC_FREE(frame);
-               errno = ENOMEM;
-               return -1;
-       }
 
-       ret = SMB_VFS_NEXT_STAT(handle, smb_fname);
-       if (ret == -1) {
-               TALLOC_FREE(frame);
-               return -1;
-       }
-
-       if (!S_ISDIR(smb_fname->st.st_ex_mode)) {
+       if (!fsp->fsp_flags.is_directory) {
                errno = EINVAL;
-               TALLOC_FREE(frame);
                return -1;
        }
 
-       ret = SMB_VFS_NEXT_REMOVEXATTR(handle, smb_fname, name);
+       ret = SMB_VFS_NEXT_FREMOVEXATTR(handle, fsp, name);
        if (ret == -1 && errno == ENOATTR) {
                ret = 0;
                errno = 0;
        }
 
-       TALLOC_FREE(frame);
        return ret;
 }
 
-static int fake_acls_chown(vfs_handle_struct *handle,
-                       const struct smb_filename *smb_fname,
-                       uid_t uid,
-                       gid_t gid)
-{
-       int ret;
-       uint8_t id_buf[4];
-       if (uid != -1) {
-               uid_t current_uid = get_current_uid(handle->conn);
-
-               if (current_uid != 0 && current_uid != uid) {
-                       return EACCES;
-               }
-
-               SIVAL(id_buf, 0, uid);
-               ret = SMB_VFS_NEXT_SETXATTR(handle,
-                               smb_fname,
-                               FAKE_UID,
-                               id_buf,
-                               sizeof(id_buf),
-                               0);
-               if (ret != 0) {
-                       return ret;
-               }
-       }
-       if (gid != -1) {
-               SIVAL(id_buf, 0, gid);
-               ret = SMB_VFS_NEXT_SETXATTR(handle,
-                               smb_fname,
-                               FAKE_GID,
-                               id_buf,
-                               sizeof(id_buf),
-                               0);
-               if (ret != 0) {
-                       return ret;
-               }
-       }
-       return 0;
-}
-
 static int fake_acls_lchown(vfs_handle_struct *handle,
                        const struct smb_filename *smb_fname,
                        uid_t uid,
@@ -468,8 +422,8 @@ static int fake_acls_lchown(vfs_handle_struct *handle,
                 * to.
                 */
                SIVAL(id_buf, 0, uid);
-               ret = SMB_VFS_NEXT_SETXATTR(handle,
-                               smb_fname,
+               ret = SMB_VFS_NEXT_FSETXATTR(handle,
+                               smb_fname->fsp,
                                FAKE_UID,
                                id_buf,
                                sizeof(id_buf),
@@ -480,8 +434,8 @@ static int fake_acls_lchown(vfs_handle_struct *handle,
        }
        if (gid != -1) {
                SIVAL(id_buf, 0, gid);
-               ret = SMB_VFS_NEXT_SETXATTR(handle,
-                               smb_fname,
+               ret = SMB_VFS_NEXT_FSETXATTR(handle,
+                               smb_fname->fsp,
                                FAKE_GID,
                                id_buf,
                                sizeof(id_buf),
@@ -520,19 +474,223 @@ static int fake_acls_fchown(vfs_handle_struct *handle, files_struct *fsp, uid_t
        return 0;
 }
 
+/*
+ * Implement the chmod uid/mask/other mode changes on a fake ACL.
+ */
+
+static int fake_acl_process_chmod(SMB_ACL_T *pp_the_acl,
+                               uid_t owner,
+                               mode_t mode)
+{
+       bool got_mask = false;
+       int entry_id = SMB_ACL_FIRST_ENTRY;
+       mode_t umode = 0;
+       mode_t mmode = 0;
+       mode_t omode = 0;
+       int ret = -1;
+       SMB_ACL_T the_acl = *pp_the_acl;
+
+       /* Split the mode into u/mask/other masks. */
+       umode = unix_perms_to_acl_perms(mode, S_IRUSR, S_IWUSR, S_IXUSR);
+       mmode = unix_perms_to_acl_perms(mode, S_IRGRP, S_IWGRP, S_IXGRP);
+       omode = unix_perms_to_acl_perms(mode, S_IROTH, S_IWOTH, S_IXOTH);
+
+       while (1) {
+               SMB_ACL_ENTRY_T entry;
+               SMB_ACL_TAG_T tagtype;
+               SMB_ACL_PERMSET_T permset;
+               uid_t *puid = NULL;
+
+               ret = sys_acl_get_entry(the_acl,
+                                       entry_id,
+                                       &entry);
+               if (ret == 0) {
+                       /* End of ACL */
+                       break;
+               }
+               if (ret == -1) {
+                       return -1;
+               }
+
+               ret = sys_acl_get_tag_type(entry, &tagtype);
+               if (ret == -1) {
+                       return -1;
+               }
+               ret = sys_acl_get_permset(entry, &permset);
+               if (ret == -1) {
+                       return -1;
+               }
+               switch (tagtype) {
+                       case SMB_ACL_USER_OBJ:
+                               ret = map_acl_perms_to_permset(umode, &permset);
+                               if (ret == -1) {
+                                       return -1;
+                               }
+                               break;
+                       case SMB_ACL_USER:
+                               puid = (uid_t *)sys_acl_get_qualifier(entry);
+                               if (puid == NULL) {
+                                       return -1;
+                               }
+                               if (owner != *puid) {
+                                       break;
+                               }
+                               ret = map_acl_perms_to_permset(umode, &permset);
+                               if (ret == -1) {
+                                       return -1;
+                               }
+                               break;
+                       case SMB_ACL_GROUP_OBJ:
+                       case SMB_ACL_GROUP:
+                               /* Ignore all group entries. */
+                               break;
+                       case SMB_ACL_MASK:
+                               ret = map_acl_perms_to_permset(mmode, &permset);
+                               if (ret == -1) {
+                                       return -1;
+                               }
+                               got_mask = true;
+                               break;
+                       case SMB_ACL_OTHER:
+                               ret = map_acl_perms_to_permset(omode, &permset);
+                               if (ret == -1) {
+                                       return -1;
+                               }
+                               break;
+                       default:
+                               errno = EINVAL;
+                               return -1;
+               }
+               ret = sys_acl_set_permset(entry, permset);
+               if (ret == -1) {
+                       return -1;
+               }
+               /* Move to next entry. */
+               entry_id = SMB_ACL_NEXT_ENTRY;
+       }
+
+       /*
+        * If we didn't see a mask entry, add one.
+        */
+
+       if (!got_mask) {
+               SMB_ACL_ENTRY_T mask_entry;
+               uint32_t mask_perm = 0;
+               SMB_ACL_PERMSET_T mask_permset = &mask_perm;
+               ret = sys_acl_create_entry(&the_acl, &mask_entry);
+               if (ret == -1) {
+                       return -1;
+               }
+               ret = map_acl_perms_to_permset(mmode, &mask_permset);
+               if (ret == -1) {
+                       return -1;
+               }
+               ret = sys_acl_set_permset(mask_entry, mask_permset);
+               if (ret == -1) {
+                       return -1;
+               }
+               ret = sys_acl_set_tag_type(mask_entry, SMB_ACL_MASK);
+               if (ret == -1) {
+                       return -1;
+               }
+               /* In case we were realloced and moved. */
+               *pp_the_acl = the_acl;
+       }
+
+       return 0;
+}
+
+static int fake_acls_fchmod(vfs_handle_struct *handle,
+                       files_struct *fsp,
+                       mode_t mode)
+{
+       TALLOC_CTX *frame = talloc_stackframe();
+       int ret = -1;
+       SMB_ACL_T the_acl = NULL;
+
+       /*
+        * Passthrough first to preserve the
+        * S_ISUID | S_ISGID | S_ISVTX
+        * bits.
+        */
+
+       ret = SMB_VFS_NEXT_FCHMOD(handle,
+                               fsp,
+                               mode);
+       if (ret == -1) {
+               TALLOC_FREE(frame);
+               return -1;
+       }
+
+       the_acl = fake_acls_sys_acl_get_fd(handle,
+                               fsp,
+                               SMB_ACL_TYPE_ACCESS,
+                               talloc_tos());
+       if (the_acl == NULL) {
+               TALLOC_FREE(frame);
+               if (errno == ENOATTR) {
+                       /* No ACL on this file. Just passthrough. */
+                       return 0;
+               }
+               return -1;
+       }
+       ret = fake_acl_process_chmod(&the_acl,
+                       fsp->fsp_name->st.st_ex_uid,
+                       mode);
+       if (ret == -1) {
+               TALLOC_FREE(frame);
+               return -1;
+       }
+       ret = fake_acls_sys_acl_set_fd(handle,
+                               fsp,
+                               SMB_ACL_TYPE_ACCESS,
+                               the_acl);
+       TALLOC_FREE(frame);
+       return ret;
+}
+
+static int fake_acls_connect(struct vfs_handle_struct *handle,
+                            const char *service,
+                            const char *user)
+{
+       struct in_pathref_data *prd = NULL;
+       int ret;
+
+       ret = SMB_VFS_NEXT_CONNECT(handle, service, user);
+       if (ret < 0) {
+               return ret;
+       }
+       /*
+        * Create a struct can tell us if we're recursing
+        * into openat_pathref_fsp() in this module. This will
+        * go away once we have SMB_VFS_STATX() and we will
+        * have a way for a caller to as for specific stat
+        * fields in a granular way. Then we will know exactly
+        * what fields the caller wants, so we won't have to
+        * fill in everything.
+        */
+       prd = talloc_zero(handle->conn, struct in_pathref_data);
+       if (prd == NULL) {
+               return -1;
+       }
+       SMB_VFS_HANDLE_SET_DATA(handle,
+                               prd,
+                               NULL,
+                               struct in_pathref_data,
+                               return -1);
+       return 0;
+}
 
 static struct vfs_fn_pointers vfs_fake_acls_fns = {
+       .connect_fn = fake_acls_connect,
        .stat_fn = fake_acls_stat,
        .lstat_fn = fake_acls_lstat,
        .fstat_fn = fake_acls_fstat,
-       .sys_acl_get_file_fn = fake_acls_sys_acl_get_file,
+       .fchmod_fn = fake_acls_fchmod,
        .sys_acl_get_fd_fn = fake_acls_sys_acl_get_fd,
-       .sys_acl_blob_get_file_fn = posix_sys_acl_blob_get_file,
        .sys_acl_blob_get_fd_fn = posix_sys_acl_blob_get_fd,
-       .sys_acl_set_file_fn = fake_acls_sys_acl_set_file,
        .sys_acl_set_fd_fn = fake_acls_sys_acl_set_fd,
-       .sys_acl_delete_def_file_fn = fake_acls_sys_acl_delete_def_file,
-       .chown_fn = fake_acls_chown,
+       .sys_acl_delete_def_fd_fn = fake_acls_sys_acl_delete_def_fd,
        .lchown_fn = fake_acls_lchown,
        .fchown_fn = fake_acls_fchown,