You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
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.
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.
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.
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.
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:resourceroute 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=Vinstead of0x02=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
into the Parmlib is expressing an intent to gate that subtree. If
HTTPD.ADMINis 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
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 configuredRES=on a system where the profile was never created.RES_UNDEFINED ALLOW|DENY, defaultALLOW) so a hardened system can opt into fail-closed without changing the default. More surface for a fairly narrow knob.RES=route, probe the resource once and write aHTTPDnnnWif 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 needRACF_ATTR_READagainst 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.