5.3 Reading and writing a file's security descriptor
A file's SD can be accessed by path or by fd. In both cases secinfo is a mask of KACS_SECINFO_* bits selecting which components (owner, group, DACL, SACL, …) the operation touches — you read or write just the parts you name and leave the rest alone.
The rights required scale with the components you touch (see Managing file security):
Component (KACS_SECINFO_*) | Reading needs | Writing needs |
|---|---|---|
OWNER / GROUP | READ_CONTROL | WRITE_OWNER (plus owner-SID validation) |
DACL | READ_CONTROL | WRITE_DAC |
SACL | ACCESS_SYSTEM_SECURITY | ACCESS_SYSTEM_SECURITY |
LABEL | READ_CONTROL | WRITE_OWNER (the label cannot rise above the caller's integrity without SeRelabelPrivilege) |
ACCESS_SYSTEM_SECURITY is itself gated by SeSecurityPrivilege; READ_CONTROL and WRITE_DAC are implicitly granted to the owner. SACL and LABEL cannot be combined in one call (EINVAL). The check is all-or-nothing: if any requested component fails its check, the whole call fails.
5.3.0.1 By path #
ssize_t ;
int ;
peios_file_get_sdreads thesecinfo-selected components ofpath's SD intobuf, getxattr-style (two-call protocol — probe withcap == 0, and a too-small non-zero buffer failsERANGEwithout truncating).at_flagsacceptsAT_SYMLINK_NOFOLLOW; at the pinned source below, it queries the terminal symlink's own SD instead of following it. Errors:EACCES(component right missing),EINVAL(SACL+LABELtogether;NULLpath, orNULLbuffer with non-zerocap),ERANGE(non-probe buffer too small),ENOENT(path doesn't exist),ELOOP(a path-resolution failure, not a blanket rejection of a terminal symlink under no-follow).peios_file_set_sdwrites thesecinfocomponents ofsdontopath, preserving the components you did not select. So to change only the DACL, build an SD with a DACL, passsecinfo = KACS_SECINFO_DACL, and the owner/group/SACL are untouched. Errors:EACCES(component right missing),EPERM(owner-SID validation failed withoutSeRestorePrivilege; label raised withoutSeRelabelPrivilege; MANDATORY attribute removed withoutSeTcbPrivilege),EINVAL(malformed SD,SACL+LABELtogether,NULLor zero-lengthsd),ENOENT,ELOOP.
5.3.0.2 By fd #
ssize_t ;
int ;
The same operations against the object fd already refers to. The access check they perform depends on the fd type: a normal file fd is checked against its cached granted mask (the one baked in at open), while an O_PATH, pidfd, or token fd triggers a live check. That distinction — cached for the fixed-grant file fd, live for the others — is documented in the Peios Kernel TRM §3.9, FACS; the practical upshot is that a file fd already opened with the right access can get/set its SD without a second path resolution.
The required rights and errors match the by-path calls, minus the path-resolution failures (ENOENT/ELOOP), plus EBADF (bad fd).
5.3.0.3 By System V IPC kind and id #
ssize_t ;
int ;
System V message queues, shared memory segments and semaphore arrays carry security descriptors too (Peios Kernel TRM §3.11), but have neither a path nor an fd. kind is one of KACS_SD_AT_SYSV_SHM, KACS_SD_AT_SYSV_MSG or KACS_SD_AT_SYSV_SEM from <pkm/ipc.h>, and id is what shmget, msgget or semget returned. The object is looked up in the caller's IPC namespace and the check is always live against its descriptor: READ_CONTROL (or ACCESS_SYSTEM_SECURITY for the SACL) to read, WRITE_DAC / WRITE_OWNER to write, with the same preserve-unselected-components merge as the file calls. Errors as for the by-fd calls, with EINVAL for an id that names nothing and EIDRM for an object that has been removed. The Rust crate exposes the same pair as file::sysv_get_sd / file::sysv_set_sd with a SysvKind enum.