Files
mars-nwe/TODO.md
ChatGPT cfd036e54c
All checks were successful
Source release / source-package (push) Successful in 49s
nwconn: persist additional AFP metadata attributes
Extend the conservative AFP 2.0 Set File Information smoke path to accept the metadata-only System and Backup file attribute bits alongside the already-supported Finder Invisible bit.

The WebSDK/NWAFP Set File Information request uses the file Attributes bitmap to pass a set/clear attribute word. Netatalk stores several AFP file attributes in AppleDouble metadata while computing open-fork state dynamically and leaving enforcement-sensitive bits to the file/fork paths. Mirror only the low-risk mars_nwe subset here: persist Invisible, System, and Backup in the private org.mars-nwe.afp.attributes xattr, and keep NoWrite, NoRename, NoDelete, NoCopy, data-fork-open, resource-fork-open, timestamps, resource forks, and Entry-ID-only write semantics rejected until they have deliberate enforcement and backend design.

The xattr payload remains versioned and unchanged. Reads now expose the three supported metadata bits through Get/Scan File Information, and writes preserve the existing set/clear semantics over the supported mask.

Update the Linux Set File Information smoke helper with --system/--clear-system and --backup/--clear-backup options, while keeping the smoke-suite default unchanged. Document the expected Linux xattr forms 0x01000004 and 0x01000040 for those optional probes.

Tests: git diff --check; gcc -Iinclude -I/mnt/data/stubs -fsyntax-only tests/linux/afp_set_file_info_smoke.c.
2026-05-30 12:55:25 +02:00

328 lines
16 KiB
Markdown

# TODO
This file collects follow-up work that is known but intentionally not part of the current patches. It is meant for project-level items that are too broad or too low-priority to keep as inline source TODO comments.
## Server / NCP compatibility
### Console privilege model
Current status:
- `NCP 23/200 Check Console Privileges` is implemented as a protocol-compatible status check.
- For now, console privileges are mapped to the existing supervisor-equivalence state computed for the connection.
- Callers with supervisor equivalence get success; other callers get `0xc6` (`No Console Rights`).
Follow-up:
- Add a real console-operator privilege model instead of treating console rights as identical to supervisor equivalence.
- Decide where the console privilege map should live:
- a bindery property,
- a server configuration option,
- or a small explicit internal list similar to queue operator handling.
- Check how NetWare 3.x tools such as `PCONSOLE`, `SYSCON`, and console utilities expect console operators to be represented.
- Keep `NCP 23/200` as a completion-code-only endpoint; only the privilege source should change.
### Queue spool path case handling
Current status:
- Queue job paths can still be rebuilt from DOS/bindery path spelling such as `SYS:SYSTEM/EPSON.QDR`.
- On a case-sensitive Unix filesystem this can differ from the existing directory, for example `system/epson.qdr`.
Follow-up:
- Resolve queue job file paths case-insensitively in the queue connection/path resolver, or use the queue object's already-resolved Unix spool directory instead of rebuilding it from the DOS path.
- Avoid creating duplicate directories that differ only by case.
### NCP 17/4C test coverage
Current status:
- `NCP 17/4C List Relations of an Object` is implemented server-side.
- Existing DOS and Linux tools do not reliably trigger it for all useful set properties such as `GROUP_MEMBERS` and `GROUPS_I'M_IN`.
Follow-up:
- Add a small direct test utility to `mars-dosutils` / `NWTESTS` that sends `NCP 17/4C` directly.
- Suggested test cases:
- `TESTGRP1` type `0x0002`, property `GROUP_MEMBERS`
- `TESTGRP2` type `0x0002`, property `GROUP_MEMBERS`
- `MARIO` type `0x0001`, property `GROUPS_I'M_IN`
- `NOPASSUSER` type `0x0001`, property `GROUPS_I'M_IN`
- `GUEST` type `0x0001`, property `GROUPS_I'M_IN`
### NCP endpoint SDK documentation / stub audit
Current status:
- Several legacy NCP endpoints in `src/nwconn.c` are implemented only as
disabled stubs, explicit `0xfb` unsupported replies, or success/no-op dummies.
- The known candidates now have inline SDK-context comments so future work can
start from the documented wire semantics instead of from guesswork.
Follow-up:
- Implement or deliberately reject remaining endpoint gaps after client
evidence or direct protocol tests.
- Keep SDK details close to the corresponding endpoint in `nwconn.c`, and keep
broader prioritization/status here in `TODO.md`.
### NCP endpoint audit tracking
Current status:
- `src/nwconn.c` contains a mix of implemented, forwarded, partial, dummy,
and intentionally unsupported NCP endpoints.
- Endpoint comments should be aligned with the Novell SDK Web documentation,
SDK headers, the Rust `nwserver` implementation, `lwared`, and the existing
mars_nwe admin/Pascal code where those sources cover the same call.
Follow-up:
- Keep inline `TODO:` comments only where endpoint behavior is incomplete,
approximate, intentionally dummy/no-op, or still needs SDK layout
verification.
- Mirror every real incomplete endpoint in this file so follow-up work remains
visible outside the source code.
- Do not treat every `return(-1)` in `nwconn.c` as incomplete: many of those
paths intentionally forward bindery/global-server work to `nwbind`.
### NCP synchronization endpoint audit
Current status:
- The old NCP synchronization endpoint family in `src/nwconn.c` is now
annotated with Novell SDK endpoint names.
- The existing source already marked this area as not well tested, so the
comments intentionally keep that compatibility warning visible.
- `NCP 0x03`, `0x05`, `0x06`, `0x07`, `0x08`, `0x09`, `0x0a`, `0x0b`,
`0x0d`, `0x0e`, `0x1a`, and `0x1e` have local implementations.
Follow-up:
- Verify the implemented file/logical-record/physical-record calls against the
Novell SDK request/reply layouts and a real DOS requester or direct test
caller.
- Continue direct requester or NWTESTS coverage for the file, logical-record,
and physical-record synchronization calls that are now wired.
- Verify timeout and error-code behavior for set-oriented locking calls against
a real requester, especially where MARS-NWE currently relies on the existing
underlying share implementation.
### Extended volume information field mapping
Current status:
- `NCP 0x16/0x33 Get Extended Volume Information` returns the documented
`NWVolExtendedInfo` reply and fills the core fields that can be derived from
generic Unix filesystem statistics.
- NetWare-specific fields that MARS-NWE does not currently model are returned
as zero for now instead of guessed values.
Follow-up:
- Fill additional `NWVolExtendedInfo` fields when reliable data is available
from the backing filesystem or from MARS-NWE metadata.
- Candidate fields include suballocation, deleted-file/limbo accounting,
compression counters, migration counters, EA counters, Directory Services
object id, and last-modified timestamp data.
- Treat compression-related fields as real follow-up work rather than permanent
zeroes; populate them only when the backing filesystem exposes trustworthy
compressed-file or compressed-block accounting.
### Object disk restriction fallback coverage
Current status:
- `NCP 0x16/0x29 Get Object Disk Usage And Restrictions` keeps the existing
`QUOTA_SUPPORT` split.
- With quota support enabled, the endpoint is routed through `nwbind` so the
bindery Object ID can be mapped to a Unix uid before querying the quota
backend.
- Without quota support, the endpoint returns the SDK-compatible fallback:
unrestricted (`0x40000000`) and no space in use.
Follow-up:
- Add direct tests for both build modes.
- Verify the quota-enabled path against a real Unix quota setup.
- Verify that the quota-disabled fallback remains compatible with requesters
and with the WebSDK rule for invalid object IDs.
## Printing / Queue backend
### Q_UNIX_PRINT backend status
Current status:
- Queue metadata handling and the `Q_UNIX_PRINT` backend are intentionally separate.
- The backend can already call `/usr/bin/lp`, `lpr`, or a custom script.
Follow-up:
- Improve logging around queue job submission to the Unix print command.
- Capture and expose backend exit status where possible.
- Consider direct CUPS integration only if MARS_NWE needs CUPS job IDs, cancellation, or status polling. Do not add a hard CUPS dependency for basic queue compatibility.
### Transaction Tracking System (TTS)
Current status:
- `NCP 0x22/0x00 TTS Is Available` reports the WebSDK-documented
unavailable status.
- MARS-NWE does not currently implement TTS rollback semantics, transaction
files, transaction status tracking, or the begin/end/abort transaction
state machine.
- Other TTS subfunctions remain unsupported instead of pretending to succeed
without real transaction tracking.
Follow-up:
- Implement TTS only if a concrete client requires it.
- Treat this as a real transaction subsystem, not as a completion-code shim:
the WebSDK TTS calls include begin/end/abort transaction, status, threshold,
and control/statistics operations.
### AFP / Mac namespace backend
Current status:
- `NCP 0x23` still returns invalid namespace for AFP calls that are not implemented yet.
- `AFP Get Entry ID From Path Name` is implemented when the optional
Netatalk/libatalk backend is available. Linux smoke coverage exists in
`tests/linux/afp_entry_id_smoke` and has been verified against `SYS:`,
`SYS:PUBLIC`, `SYS:SYSTEM`, and `SYS:BURST` with stat-derived fallback
entry IDs.
- `AFP Get Entry ID From Name` is implemented for the same path-backed
smoke mode. Linux smoke coverage uses `tests/linux/afp_entry_id_smoke --from-name`
and has been verified against `SYS:`, `SYS:PUBLIC`,
`SYS:SYSTEM`, and `SYS:BURST` with stat-derived fallback entry IDs.
- `AFP Get File Information` is implemented for read-only path-based requests.
Linux smoke coverage exists in `tests/linux/afp_file_info_smoke` and has
been verified against `SYS:`, `SYS:PUBLIC`, `SYS:SYSTEM`, and `SYS:BURST`.
The same test verifies the AFP 2.0 Get File Information subfunction via
`--afp20` against the same paths, using the same path-backed read-only reply
for now. The current reply fills stat/libatalk-derived fields and leaves
persistent CNID Parent ID / fuller Mac namespace metadata as future work.
- `AFP Scan File Information` (`0x0a`) and `AFP 2.0 Scan File Information`
(`0x11`) are implemented for path-backed read-only directory scans. Linux
smoke coverage exists in `tests/linux/afp_scan_info_smoke`; the helper
defaults to the AFP 2.0 subfunction and uses `--afp10` for the older
endpoint. Runtime coverage has been verified against `SYS:PUBLIC` by
walking multiple directory entries with the returned `next_last_seen` AFP
Entry ID continuation value. The verified AFP 2.0 and older `0x0a` first
records both return `pmdflts.ini` (`entry_id=0x23c8787d`, `data_len=8161`)
on the sample tree, and an AFP 2.0 continuation with that Entry ID returns
`ohlogscr.bat` (`entry_id=0x260437f6`, `data_len=1296`).
- `AFP Get Entry ID From NetWare Handle` is implemented for read-only data-fork
file handles that are opened in the same client connection. Linux smoke
coverage uses `tests/linux/afp_entry_id_smoke --from-handle` and has been
verified against `SYS:PUBLIC/pmdflts.ini` and `SYS:PUBLIC/ohlogscr.bat`,
returning volume 0, `fork=0`, and stat-derived fallback Entry IDs for now.
- `AFP Open File Fork` is implemented for the same path-backed smoke subset.
Raw `VOL:`-style paths resolve the effective NetWare volume from the path
prefix instead of assuming volume 0, so the same smoke path can cover `SYS:`
and non-`SYS:` volumes. It opens only the data fork read-only and returns a
normal six-byte NetWare file handle plus the current data-fork length; the
Linux smoke helper
`tests/linux/afp_open_file_fork_smoke` closes the returned handle in the same
connection. Runtime smoke coverage is green for
`SYS:PUBLIC/pmdflts.ini` (`fork_len=8161`) and `SYS:PUBLIC/ohlogscr.bat`
(`fork_len=1296`) using `fork=0` and read access `0x01`. Resource-fork
opens, write access, and Entry-ID-only lookup stay TODO until
AppleDouble/resource-fork and persistent CNID/base-ID semantics are available.
- `AFP Alloc Temporary Directory Handle` is implemented for the same
path-backed smoke subset. Raw `VOL:`-style paths resolve the effective
NetWare volume from the path prefix instead of assuming volume 0. Linux
smoke coverage exists in
`tests/linux/afp_temp_dir_handle_smoke`; runtime smoke coverage is green for
`SYS:`, `SYS:PUBLIC`, `SYS:SYSTEM`, and `SYS:BURST`. The helper returns a
temporary NetWare directory handle plus the AFP one-byte access-rights mask
and immediately deallocates the handle in the same connection. Server
diagnostics log the wider internal NetWare effective-rights mask, so
privileged directories can show `rights=0x1ff` while the client prints
`rights=0xff`. Entry-ID-only allocation remains TODO until persistent
CNID/base-ID lookup exists.
- `AFP 2.0 Set File Information` is implemented only for path-backed file
metadata smoke writes: the FinderInfo bitmap (`0x0020`) and the AFP
Attributes bitmap (`0x0001`) restricted to metadata-only file bits: Finder
Invisible, System, and Backup. Linux
smoke coverage exists in `tests/linux/afp_set_file_info_smoke`; runtime
FinderInfo coverage is green for `SYS:PUBLIC/pmdflts.ini` with Finder type
`TEXT` and creator `MARS`. The helper writes 32 bytes of FinderInfo to
`org.mars-nwe.afp.finder-info`, stores the narrow attribute word in
`org.mars-nwe.afp.attributes`, and verifies the result through AFP 2.0 Get
File Information. The smoke-suite report helper now has a green
`failures=0` run for `SYS:PUBLIC/pmdflts.ini`; that run confirms the corrected
FinderInfo payload alignment by reading
`user.org.mars-nwe.afp.finder-info=0x544558544d415253...` (`TEXTMARS` with no
leading padding byte), confirms Invisible set/clear via the versioned
attributes xattr (`0x01000001` then `0x01000000`), and confirms the cached
Entry ID xattr (`0x0100000033f9a1ed`). The first stat-derived AFP entry id
for a path is now cached in the versioned `org.mars-nwe.afp.entry-id` xattr; a
`fallback` marker on that first verification Get File Information diagnostic
describes the entry-id origin, not the FinderInfo write result. Follow-up
probes should read the cached mars_nwe entry id and omit the fallback marker.
System and Backup are now supported by the same narrow xattr-only attribute
path. All other Set File Information bits and AFP attribute bits remain
rejected until their write/enforcement semantics are explicitly designed.
- The AFP dispatcher now decodes the WebSDK/NWAFP subfunction number in
diagnostics so real client probes can be mapped to the corresponding AFP
call before implementation work starts.
- Optional build-time detection/linking for Netatalk/libatalk exists as a first
local metadata backend hook. It is deliberately not an AFP protocol
implementation yet.
- Existing mars_nwe private xattr payloads use the `org.mars-nwe.<domain>.*`
namespace (`org.mars-nwe.netware.archive` and `org.mars-nwe.netware.fileinfo`) rather than
the unreleased test-only `user.mars_nwe.*` names. There is no legacy read
fallback because the old names never shipped outside local test systems.
On Linux, mars_nwe's local xattr helper maps source-level `org.mars-nwe.<domain>.*`
names to the portable `user.org.mars-nwe.<domain>.*` storage namespace, mirroring
Netatalk's `org.netatalk.*` EA abstraction.
- NetWare AFP calls are NCP entry points for Mac namespace semantics on a
NetWare volume, not transport-level AFP proxy calls to `afpd`.
Follow-up:
- Implement the NetWare AFP NCP calls locally, using libatalk helpers rather
than proxying requests to `afpd`.
- Candidate libatalk pieces include the new AppleDouble/Finder Info/resource
fork helper wrappers, plus future CNID/directory-id helpers, attribute
mapping, and filename conversion.
- Keep returning invalid namespace for AFP calls that still lack a real per-volume Mac
namespace/AFP metadata layer. Do not return success for additional AFP calls without
data/resource fork and Finder Info semantics.
- Replace the compatibility stat-derived AFP entry-id generator with a real
CNID/directory-id allocator once the libatalk/CNID backend is integrated.
- mars_nwe-owned AFP entry ids are probed first from the versioned
`org.mars-nwe.afp.entry-id` xattr before consulting Netatalk/libatalk
AppleDouble/CNID metadata. If neither source has an id, mars_nwe derives the
existing stat-compatible id and caches it in that xattr so subsequent probes
can use persistent mars_nwe metadata. Linux smoke coverage confirms the
versioned xattr payload shape, for example `0x010000007b9c42e1` for a cached
`0x7b9c42e1` Entry ID. AFP directory-scan continuation remains directory
iteration based: `last_seen` skips past the previously returned object, but
the next returned Entry ID is not required to be numerically greater than the
continuation token. FinderInfo plus the Finder Invisible/System/Backup AFP attributes now have
deliberately narrow write paths through AFP 2.0 Set File Information; CNID
allocation and broader AFP metadata writes still need a deliberate write-safe
design.
- Put additional future mars_nwe-owned AFP metadata under `org.mars-nwe.afp.*`
(or a compact `org.mars-nwe.afp.metadata` record) and keep Netatalk-owned
metadata under Netatalk's own `org.netatalk.*` keys.
- Extend the Linux AFP smoke tests once additional AFP subfunctions are
implemented, especially Finder Info updates, fork open/read/write paths,
resource-fork handling, and broader directory-scan edge cases.
## Deferred / optional protocol work
* Basic Packet Burst file transfer support is implemented and verified with a
diagnostics-enabled DOS client test.
* Packet Burst support is built by default, but runtime use remains controlled
by `nwserv.conf`.
* Packet Burst/NDS fragmentation support remains out of scope unless a concrete
client requires it.