QMail Object Get ACL — Group 6, Code 92
Reads back the access-control list stored on a committed object, so a client can show the user who currently has access before changing it with object_set_acl.
PROPOSED — NOT YET IMPLEMENTED
This page documents a command that does not exist on any RAIDA yet. Command code 92 is reserved in qmail_structs.h but has no protocol.c dispatch entry, so requests currently return ERROR_INVALID_COMMAND. Published for design review; do not build against it until this banner is removed.
Quick reference
| Command Group | 6 |
| Command Code | 92 |
| Server function | cmd_qmail_object_get_acl (proposed) |
| Body layout | Preamble (48) + Common prefix (16) + payload (24) = 88 bytes + terminator |
| Transport | TCP only |
| Encryption | Required |
| Authorisation | Requires read permission on the object |
| Idempotent | Yes — pure read |
Purpose
An interface that lets a user share a file must be able to show what the current sharing state actually is. object_get_acl returns the stored ACE list and the current acl_version, so a client can render the sharing state and detect that someone else changed it since the list was last read.
The command requires read permission rather than ownership: a coin that has been granted access may legitimately want to know what it has been granted. It does not require setacl — being able to see the list is not the same as being able to change it.
Request body
Preamble (48 bytes) and common prefix (16 bytes)
As for the other object-transfer commands.
Get-ACL payload (24 bytes, offsets 64–87)
| Offset | Size | Field | Description |
|---|---|---|---|
| 64–79 | 16 | object_id | The committed object whose ACL is being read. |
| 80 | 1 | file_type | Same file_type used at object_begin. |
| 81–87 | 7 | reserved | Must be zero. |
| last 2 | 2 | Terminator | Fixed clear-text terminator. |
Response body
Fixed 40-byte header followed by ace_count 8-byte ACE entries, in the same layout object_set_acl accepts, so a client can read a list, edit it, and write it straight back.
| Field | Size | Description |
|---|---|---|
| common_prefix | 16 | Echoes request_id. |
| object_id | 16 | Echo of the request's object_id. |
| acl_version | 4 | Big Endian. Current version. Read this before an edit and expect it to have advanced afterwards. |
| ace_count | 1 | Number of ACE entries that follow, 1–32. |
| reserved | 3 | Zero. |
| aces | 8 × ace_count | The ACE array. See the ACE entry table on the object_set_acl page. |
Objects committed before ACLs were settable
Every object has always carried an ACL, written at commit. Objects created before object_set_acl existed return the shipped default: one owner ACE with full rights, and one "any" ACE granting read. That is a real stored list, not a synthesised placeholder.
Status codes
| Code | Symbol | Meaning |
|---|---|---|
| 250 | SUCCESS | ACL returned. |
| 218 | ERROR_TCP_REQUIRED | Retry using TCP. |
| 228 | ERROR_OBJECT_NOT_COMMITTED | No committed object with this object_id and file_type. |
| 166 | ERROR_ACL_DENIED | The caller lacks read permission on this object. |
| 198 | ERROR_INVALID_PARAMETER | A reserved field was non-zero, or the body length is wrong. |
| 163 | ERROR_VOLUME_UNAVAILABLE | The volume holding this object is offline. The data is not gone. |
Common mistakes
Editing without re-reading
object_set_acl replaces the whole list, so an edit built from a stale read silently discards any change made in between. Read the list, apply the edit, write it back promptly, and compare acl_version to confirm the version you edited is the version you replaced.
Reading one server and assuming the fleet agrees
ACLs are stored per RAIDA alongside each server's own stripe. A failed set-ACL on one server leaves that server with a different list. When the answers disagree, treat the most restrictive as authoritative for display and re-apply the intended list fleet-wide.