Skip to content

Decide the policy: should a RES= route whose resource has no profile really permit every request? #137

Description

@mgrossmann

Split out of #135 / #136 so the fix there stays behaviour-preserving. This is a policy decision, not a bug.

The situation

After #136, a RES=class:resource route whose resource has no profile defined permits the access. SAF rc 4 ("resource not protected") is normalized to 0, which preserves exactly what httpd does today.

But today's behaviour was never chosen. It is an accident of libc370 setting the wrong RACHECK flag bit (0x10 = DSTYPE=V instead of 0x02 = LOG=NONE, libc370#63), which made RAKF answer 0 where it should answer 4. Until that was found, httpd could not tell "a profile permits this" from "there is no profile at all". Now it can.

Why it is worth a decision

An admin who writes

LOC=/admin/*  AUTH=BASIC RES=FACILITY:HTTPD.ADMIN

into the Parmlib is expressing an intent to gate that subtree. If HTTPD.ADMIN is never defined in RAKF — or is misspelled in either the class or the resource name — stage 2 silently does nothing and the route is protected by authentication alone. The failure is quiet and in the permissive direction, which is the wrong direction for the one config keyword whose entire job is authorization.

The counter-argument is real too: "undefined resource = not protected = allowed" is standard SAF semantics, it is what RACF itself does absent PROTECTALL, and a CGI or route that suddenly denies on an unprotected resource would surprise anyone who knows SAF.

Options

  1. Keep SAF semantics (status quo after Accept RACHECK rc=4 (resource not protected) as allowed #136) — undefined profile permits. Document it, trace it under DEBUG (both done in Accept RACHECK rc=4 (resource not protected) as allowed #136), and treat a missing profile as an admin error to catch at setup time.
  2. Fail closed on RES= — if a route explicitly names a resource, require a profile for it; rc 4 becomes a 403. Matches the admin's evident intent, diverges from SAF, and would lock out anyone who configured RES= on a system where the profile was never created.
  3. Make it configurable — a Parmlib keyword (e.g. RES_UNDEFINED ALLOW|DENY, default ALLOW) so a hardened system can opt into fail-closed without changing the default. More surface for a fairly narrow knob.
  4. Warn at startup instead of at request time — when parsing a RES= route, probe the resource once and write a HTTPDnnnW if it has no profile. Keeps SAF semantics for the decision but makes the misconfiguration loud where it can still be fixed. Composes with (1).

My leaning is (1) + (4): keep SAF semantics for the authorization decision, and move the detection of a missing profile to startup where it is an operator-visible warning rather than a silent per-request allow. That gets the safety benefit of (2) without diverging from SAF and without the lockout risk. Whether the startup probe is cheap and reliable enough to run for every RES= route needs checking — it is a RACHECK under httpd's own ACEE, not the client's, so it answers a slightly different question and may need RACF_ATTR_READ against the STC identity to be meaningful.

Depends on

libc370#63 landing, since rc 4 is not observable before that. No urgency: option 1 is the current state and is safe.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions