Decode the whole route block in HTTPDSRV, and call it MOD - #153
Conversation
/.dsrv's HTTPCGI field table stopped at +0010, so the four fields the per-route auth policy added in #98 -- auth, resattr, resclass, resname -- were in the hex dump but never named. The row it did show, login, is the legacy byte, which leaves the table unable to answer the one question it would be opened for: /zosmf/info reads "Login Required 0" and answers 401, and nothing in the table says what decides that. How thoroughly unreadable the block was without labels is visible in the issue itself: the dump there has 01 at +0014, which is HTTP_AUTH_NONE -- that route is public as far as httpd's gate is concerned, and its 401 comes from mvsMF's own auth, not from here. The byte was read as "auth required" because a bare 01 in a hex dump does not say otherwise. All ten fields are named now. auth and resattr are spelled out rather than printed as bare numbers, because neither value means what it looks like: AUTH=DEFAULT is not "no authentication", it means the route carried no AUTH= keyword and inherits the global LOGIN policy, and resattr 0 is not "no access", it is the unset value racf_auth() reads as READ. login keeps its row -- it is still in the block and still in the hex -- but is labelled as the legacy field that no longer decides. The vocabulary follows. The Parmlib keywords have been MOD= and LOC= since the Parmlib configuration went in, so the target is ?target=MOD, the headings read "Route Array" and "Route #n (MOD|LOC)", and the row labels are route->. No CGI alias: the maintainer confirmed there are no consumers of the old spelling. One ordering detail: target matches as a prefix, so the MOD test sits after the MGR test and ?target=M keeps resolving to MGR as it always has. The HTTPD block table had the same drift, so it is audited in the same pass. The struct is 320 bytes and the table stopped at +009C: docroot, codepage, the keep-alive and session-timeout settings, the SMF level and type, the UFS/debug enable flags, the bind retry counts, the client array and the credential handles were all dumped and none was named. The reserved slots left by the 4.0.0 removals are listed too, so the table can be walked against the hex without a gap. credkey is a plain pointer on purpose and not a /.dm link -- that link would be a one-click dump of the blowfish key. Two rows used to disappear when their field was NULL (dbg, socket_thread), which is the same defect in miniature: an offset that vanishes from a table claiming to explain the block. They are always present now, linked only when there is something to link to. Docs: CLAUDE.md's display-module section loses the known-bug paragraph this fixes and gains a note on reading auth vs login, the target table says MOD, and the two struct sizes are corrected -- HTTPD is 320 bytes (0x140), not 288, and HTTPCGI is 32, not 20. Fixes #146
Live verification — deployed to mvsdev, STC restartedHTTPD block (
|
The row added a commit ago printed httpd->codepage verbatim, and on a system with no CODEPAGE keyword that is "" -- which reads as "none set" when it means CP037. set_defaults() leaves the field empty (httpprm.c:137), http_prm passes that through as NULL (httpprm.c:62), and http_xlate_init() maps NULL to the CP037 tables (httpxlat.c:395). That is the same shape as the login row this branch is fixing: a raw value that does not say what is in force. An empty codepage now renders as CP037 with the reason, the same way resattr 0 renders as READ. Relates to #146
|
Addendum: the Follow-up filed for the second surface: #155 ( |
Fixes #146
What changed
The route field table (
/.dsrv?target=MOD). All tenHTTPCGIfields are named now, not just the first six.authandresattrare spelled out rather than printed as bare numbers, because neither value reads the way it looks:AUTH=DEFAULT(0) is not "no authentication" — it means the route carried noAUTH=keyword and inherits the globalLOGINpolicy.resattr0 is not "no access" — it is the unset valueracf_auth()reads as READ.loginkeeps its row (it is still in the block and still in the hex) but is labelled as the legacy field that no longer decides.One correction to the issue's own analysis, worth recording. The issue reads the
01at+0014as the gate that makes/zosmf/infoanswer 401.HTTP_AUTH_NONEis 1 (httpd.h:257), andauth_gate()setsneed_authn = 0for that mode with noresclass, so that route is public as far as httpd is concerned — its 401 comes from mvsMF's own auth track. The defect and the fix are unchanged; if anything this is the sharper example, since a bare01in an unlabelled dump misled the person who filed the issue.Vocabulary.
?target=MOD, headings "Route Array" / "Route #n (MOD|LOC)", row labelsroute->, statics renamed todisplay_route/display_route_row. NoCGIalias, per the maintainer's comment on the issue.One behavior change worth reviewing:
targetmatches as a prefix (http_cmpn(target, …, strlen(target))), so?target=Mhas always resolved to MGR. Putting the MOD test first would have silently stolen it. The MOD test therefore sits after the MGR test and?target=Mstill means MGR.HTTPD block table audit (the issue's "not affected" section asked for this in the same pass). The struct is 320 bytes; the table stopped at
+009C. Added:httpc,docroot,codepage,listen_queue, the keep-alive and session-timeout settings,smf_level/smf_type,ufs_enabled/dbg_enabled,bind_tries/bind_sleep,credkey/credarr, and every reserved slot, so the table can be walked against the hex without a gap.credkeyis a plain pointer and deliberately not a/.dm?m=link — that would be a one-click dump of the blowfish key.dbgandsocket_threadused to vanish from the table when NULL; they are always present now, linked only when there is something to link to.Docs (
CLAUDE.md). The "Known display bug" paragraph citing this issue is removed, replaced by a note on readingauthvslogin. Target table saysMOD. Struct sizes corrected: HTTPD 288/0x120→ 320/0x140, HTTPCGI 20 → 32 bytes.Verification
makeis clean under-Wall -Werror, all six modules link. That is compile-only — no assertion about the rendered output, and CI will not check it either.Manual check on the live system after deploy:
GET /.dsrv→ readhttpd->httpcgiat+44, follow the link.GET /.dsrv?target=MOD&m=<addr>→ each route showsroute->authdecoded, plusresattr/resclass/resname, androute->loginmarked legacy.GET /.dsrv?target=M→ still MGR, not the route array.GET /.dsrv→ walk the HTTPD table against the hex dump above it; every offset from+00to+13Cshould have a row.(Write curl's
-uflag inline, not via a shell variable — zsh does not word-split it and every request 401s.)Left out of scope
httpdbug.c:74printsLogin=%uin the?debug=cgiroute dump — the same defect class on a second surface. Not touched here to keep the diff to HTTPDSRV; worth its own issue.mvslovers/CLAUDE.md(outside this repo) also documentstarget=CGIand needs the same edit separately.HTTPCGIstruct itself and retires the globalLOGINbitmask. This PR only changes what HTTPDSRV displays, so Auth model cleanup (post-4.0.0): rename HTTPCGI -> route type; retire the global LOGIN bitmask #105 inherits a table that already has all the rows.