Your first program
This is a complete program you can compile and run. It does not touch the kernel — it works entirely with the security-descriptor vocabulary from <peios/security.h>, which makes it a safe first outing: no privileges, no live tokens, just the conventions from Library conventions put to work.
The task: take a security descriptor written in SDDL text, turn it into wire bytes, read its owner, and print that owner's SID in string form. Along the way you exercise the two-call buffer protocol twice, parse with a zero-copy view, and handle errors the libpeios way.
The program #
int
Building and running #
Expected output:
security descriptor: 44 bytes
owner: S-1-5-32-544
S-1-5-32-544 is the well-known SID for the local Administrators group — which is exactly the BA you wrote in the SDDL string. (The byte count may differ across versions; the owner will not.)
What just happened #
Every convention from the previous page showed up here:
- The two-call protocol, twice.
peios_sddl_parse_sdandpeios_sid_formatwere each called first with aNULL/0buffer to learn the size, then again to fill a right-sized allocation. Neither could ever truncate: a too-small buffer would have returned-1withERANGE, not a partial result. - A string length excludes the NUL. That is why the SID string buffer was
slen + 1. - A zero-copy view borrowed our buffer.
ownerpointed intosd, sosdhad to stay alive and unmodified until after the finalpeios_sid_format. Freeing it earlier would have leftownerdangling — the one mistake this pattern invites, and the reason step 5 frees last. - Errors came back through the return value and
errno. Every call was checked;strerror(errno)explained any failure. No exceptions, no out-of-band error channel.
A shortcut worth knowing #
Not every buffer needs a probe. Some results have a known ceiling, and the library gives you a constant so you can use a fixed stack buffer and skip the first call entirely. A SID is the classic case — it is never larger than PEIOS_SID_MAX_BYTES:
unsigned char sid;
ssize_t n = ;
/* n > 0: `sid` holds S-1-5-32-544 in wire form, no malloc, no probe. */
Use the probe when a length is genuinely unbounded (strings, whole descriptors, ACLs); use the fixed-size shortcut when the module documents a ceiling for the thing you are building.
Where to go next #
You now have the mechanics. From here, pick the subsystem you need:
- Access control (KACS) — the security vocabulary you just used, plus tokens, access checks, file security, and process security.
- The registry (LCS) — reading and writing Peios's configuration store.
- Events (KMES) — emitting and consuming the audit/event stream.