From d0d3e4a5c18a79e598d555022f2c088f6b68f0e1 Mon Sep 17 00:00:00 2001 From: OAI Date: Mon, 1 Jun 2026 22:32:16 +0000 Subject: [PATCH] docs: document ncp23 basic environment layouts --- AI.md | 1 + TODO.md | 43 +++++++++++++-- src/nwbind.c | 145 +++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 184 insertions(+), 5 deletions(-) diff --git a/AI.md b/AI.md index 0868aa3..1674695 100644 --- a/AI.md +++ b/AI.md @@ -35,6 +35,7 @@ use, the current project status that the user pasted into the chat. - For forwarded paths, document any nwconn-side payload mutation as part of the audit. Examples in the current tree include queue create path expansion, queue job file-handle insertion, quota bindery prehandling, and semaphore/message group forwarding. If a forwarded subfunction is not audited yet, record it as a target-file follow-up rather than only documenting the nwconn dispatcher. - For documentation-only endpoint patches, do not change parser offsets, byte order, reply layout, or completion behavior. Always compare the code parser/reply layout against the applicable SDK/WebSDK/PDF request format and, when available, the uploaded SDK include prototypes. If the code differs from the SDK layout, document the concrete difference inline and mirror it in `TODO.md` for later testing. If it matches, say so in the patch summary so the audit trail is clear. - When an SDK/WebSDK/PDF endpoint number is written in decimal notation, convert it carefully to the wire `case` value before adding inline documentation. Example: Directory Services `0x2222/22/12` in the PDF means SubFunctionCode decimal 12, i.e. wire `case 0x0c`; it is not the existing `case 0x12` / decimal 18 Allocate Permanent Directory Handle. Place disabled stubs directly at the correct numeric slot inside the dispatcher, never appended at the end of the function. +- If a PDF/WebSDK page title and an internal table row disagree, prefer the endpoint title plus include/WebSDK cross-checks and record the mismatch instead of inventing a new wire case. Example: `0x2222/23 Verify Serialization` is titled SDK decimal `23/12` / wire `0x0c`, even though one PDF table row prints `SubFunctionCode (212)`; do not add a wire `0xd4` case without a packet trace or include-level confirmation. - In `TODO.md` and endpoint summaries, avoid ambiguous mixed notation for grouped subfunctions. Write SDK/PDF numbers as decimal and include the wire byte explicitly when it differs or could be confused, for example `SDK 22/18 / wire 0x12` or `SDK 22/12 / wire 0x0c`. Do not write `22/12` for a wire `case 0x12` unless the SDK number is actually decimal 12. - Keep `TODO.md` endpoint audit notes grouped by endpoint family and NetWare generation instead of as one long flat list. - The rejected `0152-docs-note-message-control-subfunction.patch` must not be applied: it documented `0x2222/21/0x0c Connection Message Control`, which is outside the default NetWare 1.x/2.x/3.x MARS-NWE target scope. diff --git a/TODO.md b/TODO.md index 91f4ea1..ec571b1 100644 --- a/TODO.md +++ b/TODO.md @@ -426,9 +426,25 @@ Current status: - The group header is documented inline as `SubFuncStrucLen` (Hi-Lo), `SubFunctionCode`, and subfunction payload. - Endpoint numbers in SDK/PDF/WebSDK prose are decimal unless explicitly - prefixed. The local subfunction cases audited so far are: + prefixed. The local/forwarded subfunction cases audited so far are: + - SDK `23/00` / wire `0x00` Login User (old) -- disabled future stub + - SDK `23/01` / wire `0x01` Change User Password (old) -- hard failure stub + - SDK `23/02` / wire `0x02` Get User Connection List (old) -- disabled future stub + - SDK `23/05` / wire `0x05` Get Station's Logged Info (old) -- disabled future stub + - SDK `23/12` / wire `0x0c` Verify Serialization -- hard failure stub - SDK `23/15` / wire `0x0f` Scan File Information - SDK `23/16` / wire `0x10` Set File Information + - SDK `23/17` / wire `0x11` Get File Server Information + - SDK `23/18` / wire `0x12` Get Network Serial Number + - SDK `23/19` / wire `0x13` Get Internet Address (old) + - SDK `23/20` / wire `0x14` Login Object + - SDK `23/21` / wire `0x15` Get Object Connection List (old) + - SDK `23/22` / wire `0x16` Get Station's Logged Info (old) + - SDK `23/23` / wire `0x17` Get Login Key + - SDK `23/24` / wire `0x18` Keyed Object Login + - SDK `23/26` / wire `0x1a` Get Internet Address + - SDK `23/27` / wire `0x1b` Get Object Connection List + - SDK `23/28` / wire `0x1c` Get Station's Logged Info - SDK `23/15` request payload offsets match the current parser: `LastSearchIndex`, `DirectoryHandle`, `SearchAttributes`, `FileNameLen`, and `FileName`. The reply shape also matches the documented fixed file @@ -441,15 +457,32 @@ Current status: search attributes, and filename to `nw_set_file_information()`. - Include cross-checks: `NWScanFileInformation()`/`NWIntScanFileInformation()` and `NWSetFileInformation()` in `nwfile.h` refer to this same SDK-level - file-information family. + file-information family. The server/connection calls cross-check against + `NWGetFileServerInformation()`, `NWGetNetworkSerialNumber()`, + `NWGetInternetAddress()`, `NWGetConnectionInformation()`, + `NWGetObjectConnectionNumbers()`, and related connection/server headers. Follow-up: - Verify SDK `23/15` search-index byte order against a real old requester or direct test caller before changing the current big-endian parser/reply. -- Audit the remaining forwarded `0x2222/23` login, bindery, queue, and - management subfunctions in the files that actually handle them instead of - treating the `nwconn.c` forwarding points as complete local implementations. +- SDK `23/12` / wire `0x0c` Verify Serialization is currently a hard failure + stub; the PDF/WebSDK endpoint title is decimal `23/12`, while one table row + prints `SubFunctionCode (212)`, so do not add a wire `0xd4` case without a + packet trace or include-level confirmation. +- SDK `23/17` / wire `0x11` returns the legacy server-info block; later PDF + revisions name additional fields inside the current reserved tail. Keep the + current behaviour until a client requires those fields. +- SDK `23/18` / wire `0x12` documents the serial/application reply as Lo-Hi, + while the current code writes both fields with big-endian helpers. +- SDK `23/23` / wire `0x17` documents a TargetConnection byte, but the current + implementation ignores it and returns a login key for the active connection. +- SDK `23/27` / wire `0x1b` documents `SearchConnNumber` and returned + connection numbers as Lo-Hi long values; the current code reads the search + number with `GET_BE32()` and returns 16-bit connection numbers. +- Audit the remaining forwarded `0x2222/23` bindery, queue, and management + subfunctions in the files that actually handle them instead of treating the + `nwconn.c` forwarding points as complete local implementations. ### Extended volume information field mapping diff --git a/src/nwbind.c b/src/nwbind.c index b463d61..1b38aee 100644 --- a/src/nwbind.c +++ b/src/nwbind.c @@ -813,11 +813,65 @@ static void handle_fxx(int gelen, int func) * and the final nwbind parser below. */ switch (ufunc) { +#if 0 + case 0x00 : { /* SDK 23/00 / wire 0x00 Login User (old) */ + /* + * NetWare 1.x/2.x legacy login shorthand for USER + * objects. SDK/PDF request payload after + * SubFunctionCode: + * byte UserNameLen + * byte UserName[UserNameLen] + * byte PasswordLen + * byte Password[PasswordLen] + * Not implemented here; keep as a documented future + * compatibility stub, not a NetWare-4-only endpoint. + */ + completition=0xfb; + } + break; +#endif + case 0x01 : { /* Change User Password OLD */ + /* + * SDK 23/01 / wire 0x01 Change User Password (old). + * The current handler is a hard failure stub. The old + * PDF/WebSDK layout belongs to the NetWare 1.x/2.x + * compatibility bucket and should be filled in only when + * the legacy password-change semantics are implemented. + */ completition=0xff; } break; +#if 0 + case 0x02 : { /* SDK 23/02 / wire 0x02 Get User Connection List (old) */ + /* + * SDK/PDF request payload after SubFunctionCode: + * byte UserNameLen + * byte UserName[UserNameLen] + * Reply: byte ListLen, then byte connection numbers. + * This earliest form is equivalent to the later object + * connection-list call for object type USER. + */ + completition=0xfb; + } + break; +#endif + +#if 0 + case 0x05 : { /* SDK 23/05 / wire 0x05 Get Station's Logged Info (old) */ + /* + * NetWare 2.x compatibility call. Request payload after + * SubFunctionCode: byte TargetConnectionNumber. + * Reply is the fixed 258-byte legacy log record; the + * later SDK 23/22 and SDK 23/28 calls are implemented + * below as wire 0x16 and wire 0x1c. + */ + completition=0xfb; + } + break; +#endif + #if FUNC_17_02_IS_DEBUG case 0x02 : { /* I hope this is call isn't used */ /* now missused as a debug switch :) */ @@ -836,6 +890,16 @@ static void handle_fxx(int gelen, int func) #endif case 0x0c : { /* Verify Serialization */ + /* + * SDK 23/12 / wire 0x0c Verify Serialization. + * SDK/PDF request payload is documented as a 4-byte + * ServerSerialNumber (Lo-Hi). The PDF table has a + * known-looking inconsistency that prints + * SubFunctionCode (212) even though the endpoint title + * is 23/12; keep this bucketed by the decimal endpoint + * number and do not treat it as wire 0xd4. + * Current code is still a hard failure stub. + */ completition=0xff; } break; @@ -849,6 +913,16 @@ static void handle_fxx(int gelen, int func) #endif case 0x11 : { /* Get FileServer Info */ + /* + * SDK 23/17 / wire 0x11 Get File Server Information. + * SDK/PDF request payload after SubFunctionCode is + * empty. The reply is the legacy server-info block: 48 + * bytes server name, version/subversion, connection and + * volume counters, and feature-version bytes. Later + * PDF revisions name additional bytes after offset 76; + * this code returns the same fixed-size block but keeps + * those later fields inside the reserved tail. + */ struct XDATA { uint8 servername[48]; uint8 version; /* 2 or 3 */ @@ -915,6 +989,14 @@ static void handle_fxx(int gelen, int func) break; case 0x12 : { /* Get Network Serial Number */ + /* + * SDK 23/18 / wire 0x12 Get Network Serial Number. + * SDK/PDF request payload is empty. The PDF describes + * ServerSerialNumber and ApplicationNumber as Lo-Hi, + * while the current reply writes both with BE helpers; + * keep that as an audit item until an old requester is + * tested. + */ struct XDATA { uint8 serial_number[4]; uint8 appl_number[2]; @@ -929,6 +1011,15 @@ static void handle_fxx(int gelen, int func) case 0x13 : /* Get Connection Internet Address, old */ case 0x1a : { /* Get Connection Internet Address, new */ + /* + * SDK 23/19 / wire 0x13 Get Internet Address (old): + * byte TargetConnection + * SDK 23/26 / wire 0x1a Get Internet Address: + * long TargetConnection (Lo-Hi) + * The old path reads the documented byte. The new path + * uses GET_32(), matching the documented Lo-Hi order, and + * appends ConnectionType=2 for NCP. + */ int conn = (ufunc == 0x13) ? ((max_connections < 256) ? (int) *rdata @@ -951,6 +1042,17 @@ static void handle_fxx(int gelen, int func) } break; case 0x14 : { /* Login Objekt, unencrypted passwords */ + /* + * SDK 23/20 / wire 0x14 Login Object. + * Request payload after SubFunctionCode: + * word ObjectType (Hi-Lo) + * byte ClientNameLen + * byte ClientName[ClientNameLen] + * byte PasswordLen + * byte Password[PasswordLen] + * Parser follows the documented layout and clears the + * plaintext password bytes after copying them. + */ uint8 *p = rdata; uint8 *p1 = p+3 + *(p+2); /* here is password */ int result; @@ -1002,6 +1104,14 @@ static void handle_fxx(int gelen, int func) } break; case 0x15 : { /* Get Object Connection List (old) */ + /* + * SDK 23/21 / wire 0x15 Get Object Connection List (old). + * Request payload: ObjectType (Hi-Lo), ObjectNameLen, + * ObjectName. The SDK/PDF old reply is byte ListLen plus + * connection-number entries; this implementation returns + * one byte per connection, matching the low-byte legacy + * form used by old clients. + */ uint8 *p = rdata; int result; NETOBJ obj; @@ -1029,6 +1139,15 @@ static void handle_fxx(int gelen, int func) case 0x16 : /* Get Connection Info, old */ case 0x1c : { /* Get Connection Info, new ( > 255 connections) */ + /* + * SDK 23/22 / wire 0x16 Get Station's Logged Info (old): + * byte TargetConnectionNumber + * SDK 23/28 / wire 0x1c Get Station's Logged Info: + * long TargetConnectionNum (Lo-Hi) + * The reply shape matches the documented user-id, type, + * name, login-time, and reserved-byte block. The new path + * reads the 32-bit connection with GET_32(). + */ struct XDATA { uint8 object_id[4]; uint8 object_type[2]; @@ -1064,6 +1183,13 @@ static void handle_fxx(int gelen, int func) } break; case 0x17 : { /* get crypt key */ + /* + * SDK 23/23 / wire 0x17 Get Login Key. + * SDK/PDF request payload contains TargetConnection as a + * byte, but the current implementation ignores it and + * returns a freshly generated key for the active + * connection. Track that semantic difference in TODO. + */ int k = sizeof(act_c->crypt_key); uint8 *p = act_c->crypt_key; uint8 *pp = responsedata; @@ -1078,6 +1204,16 @@ static void handle_fxx(int gelen, int func) break; case 0x18 : { /* crypt_keyed LOGIN */ + /* + * SDK 23/24 / wire 0x18 Keyed Object Login. + * Request payload after SubFunctionCode: + * byte Key[8] + * word ObjectType (Hi-Lo) + * byte ObjectNameLen + * byte ObjectName[ObjectNameLen] + * Parser consumes the key first and then reads the + * documented object type/name fields. + */ uint8 *p = rdata+sizeof(act_c->crypt_key); NETOBJ obj; int result; @@ -1122,6 +1258,15 @@ static void handle_fxx(int gelen, int func) case 0x1B : { /* Get Object Connection List */ + /* + * SDK 23/27 / wire 0x1b Get Object Connection List. + * Request payload: SearchConnNumber (Lo-Hi), ObjectType + * (Hi-Lo), ObjectNameLen, ObjectName. Reply is byte + * ConnListLen plus connection numbers. The code reads + * SearchConnNumber with GET_BE32() but writes returned + * connection numbers with U16_TO_16(); verify both widths + * and byte order against an old requester before changing. + */ uint8 *p = rdata; int result; NETOBJ obj;