nwconn: route legacy AFP set file information
All checks were successful
Source release / source-package (push) Successful in 47s
All checks were successful
Source release / source-package (push) Successful in 47s
Wire the older WebSDK/NWAFP Set File Information subfunction (0x09) through the same deliberately narrow metadata-write implementation as AFP 2.0 Set File Information (0x10). Both subfunctions now accept the path-backed VOL:-style smoke subset and persist only FinderInfo plus the metadata-only Invisible/System/Backup AFP attribute bits through mars_nwe's org.mars-nwe.afp.* xattrs. This keeps the implementation conservative: 0x09 does not add timestamp writes, DOS/NetWare mode-bit mapping, create/delete/rename behavior, fork-write semantics, or entry-id-only lookup. It simply exposes the same already-tested FinderInfo/attribute payload semantics to clients that issue the legacy AFP Set File Information opcode. Update the Linux smoke helper with --afp09/--afp20 selection and include the legacy FinderInfo probe in afp_smoke_suite.sh so future reports cover both write opcodes automatically. Tests: - bash -n tests/linux/afp_smoke_suite.sh - gcc -Iinclude -I/mnt/data/stubs -fsyntax-only tests/linux/afp_set_file_info_smoke.c - git diff --check
This commit is contained in:
11
TODO.md
11
TODO.md
@@ -246,8 +246,9 @@ Current status:
|
||||
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
|
||||
- `AFP Set File Information` (`0x09`) and `AFP 2.0 Set File Information`
|
||||
(`0x10`) are 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
|
||||
@@ -255,7 +256,8 @@ Current status:
|
||||
`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 includes FinderInfo plus Invisible/System/Backup set/clear probes and has a green
|
||||
File Information. The smoke-suite report helper now includes AFP 2.0 FinderInfo, legacy AFP `0x09` FinderInfo, plus Invisible/System/Backup set/clear probes
|
||||
and 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
|
||||
@@ -312,7 +314,8 @@ Follow-up:
|
||||
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
|
||||
deliberately narrow write paths through AFP Set File Information `0x09` and
|
||||
AFP 2.0 Set File Information `0x10`; 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.*`
|
||||
|
||||
11
src/nwconn.c
11
src/nwconn.c
@@ -423,6 +423,7 @@ static const char *afp_call_name(int ufunc)
|
||||
case 0x06: return("AFP Get Entry ID From NetWare Handle");
|
||||
case 0x07: return("AFP Rename");
|
||||
case 0x08: return("AFP Open File Fork");
|
||||
case 0x09: return("AFP Set File Information");
|
||||
case 0x0a: return("AFP Scan File Information");
|
||||
case 0x0b: return("AFP Alloc Temporary Dir Handle");
|
||||
case 0x0c: return("AFP Get Entry ID From Path Name");
|
||||
@@ -3340,7 +3341,8 @@ static int handle_ncp_serv(void)
|
||||
* Information (0x05), Get Entry ID From
|
||||
* NetWare Handle (0x06), Rename (0x07), Open File Fork
|
||||
* (0x08), Alloc Temporary Dir Handle (0x0b), Get Entry ID
|
||||
* From Path Name (0x0c), the AFP 2.0 create calls
|
||||
* From Path Name (0x0c), the AFP Set File Information
|
||||
* write call (0x09), the AFP 2.0 create calls
|
||||
* (0x0d/0x0e), Get/Set File Information (0x0f/0x10), and
|
||||
* Scan File Information (0x11).
|
||||
*
|
||||
@@ -3361,8 +3363,9 @@ static int handle_ncp_serv(void)
|
||||
* returns a connection-local NetWare directory handle plus
|
||||
* effective rights. Then expose
|
||||
* the read-only AFP Get File Information query for the same
|
||||
* SYS:-style path inputs. AFP 2.0 Set File Information
|
||||
* accepts only FinderInfo plus the
|
||||
* SYS:-style path inputs. AFP Set File Information (0x09)
|
||||
* and AFP 2.0 Set File Information (0x10) accept only
|
||||
* FinderInfo plus the
|
||||
* metadata-only Invisible/System/Backup file attributes as
|
||||
* xattr write smoke paths. AFP 2.0 Get File Information
|
||||
* uses the same request/reply layout for this read-only
|
||||
@@ -3403,7 +3406,7 @@ static int handle_ncp_serv(void)
|
||||
afp_call_name(ufunc));
|
||||
if (result > -1) data_len = result;
|
||||
else completition = (uint8)-result;
|
||||
} else if (ufunc == 0x10) {
|
||||
} else if (ufunc == 0x09 || ufunc == 0x10) {
|
||||
int result = afp_set_file_information(afp_req,
|
||||
afp_len, afp_call_name(ufunc));
|
||||
if (result > -1) data_len = result;
|
||||
|
||||
@@ -56,7 +56,8 @@ Example from the build `tests/linux` directory:
|
||||
|
||||
The report includes AFP Entry ID, Entry ID From NetWare Handle, Get File
|
||||
Information, Scan File Information, Alloc Temporary Directory Handle, Open File
|
||||
Fork, FinderInfo Set File Information, Invisible/System/Backup Set/Clear File
|
||||
Fork, FinderInfo Set File Information for both AFP 2.0 (`0x10`) and the legacy AFP
|
||||
Set File Information (`0x09`), Invisible/System/Backup Set/Clear File
|
||||
Information, and the Linux xattr checks for:
|
||||
|
||||
```text
|
||||
@@ -448,9 +449,12 @@ when a scan continuation is expected to reach the end of the directory.
|
||||
|
||||
## AFP Set File Information metadata smoke test
|
||||
|
||||
`afp_set_file_info_smoke` sends the WebSDK-documented NetWare AFP 2.0 request:
|
||||
`afp_set_file_info_smoke` sends the WebSDK-documented NetWare AFP Set File
|
||||
Information requests. It defaults to the AFP 2.0 subfunction and can exercise
|
||||
the older AFP subfunction with `--afp09`:
|
||||
|
||||
```text
|
||||
NCP 0x2222/35/09 AFP Set File Information
|
||||
NCP 0x2222/35/16 AFP 2.0 Set File Information
|
||||
```
|
||||
|
||||
@@ -474,10 +478,22 @@ Example:
|
||||
SYS:PUBLIC/pmdflts.ini
|
||||
```
|
||||
|
||||
|
||||
|
||||
The same FinderInfo payload can be sent through the older Set File Information
|
||||
subfunction:
|
||||
|
||||
```sh
|
||||
./tests/linux/afp_set_file_info_smoke \
|
||||
-S MARS -U SUPERVISOR -P secret \
|
||||
--afp09 --finder-info-only --type TEXT --creator MARS \
|
||||
SYS:PUBLIC/pmdflts.ini
|
||||
```
|
||||
|
||||
Verified runtime output:
|
||||
|
||||
```text
|
||||
AFP Set File Info path=SYS:PUBLIC/pmdflts.ini bitmap=0x0020 finder_type=TEXT finder_creator=MARS entry_id=0x23c8787d verified
|
||||
AFP Set File Info subfunction=0x10 path=SYS:PUBLIC/pmdflts.ini bitmap=0x0020 attrs=0x0000 finder_type=TEXT finder_creator=MARS entry_id=0x23c8787d verified
|
||||
```
|
||||
|
||||
Server diagnostics show the effective resolved volume, the request volume byte,
|
||||
@@ -561,13 +577,17 @@ attribute word: Backup persisted as `0x0040`, so Invisible set/clear produced
|
||||
`0x0041` and `0x0040` while still being correct for the Invisible bit.
|
||||
|
||||
```text
|
||||
AFP Set File Info path=SYS:PUBLIC/pmdflts.ini bitmap=0x0001 attrs=0x0004 finder_type=TEXT finder_creator=MARS entry_id=0x62ecb463 verified
|
||||
AFP Set File Info path=SYS:PUBLIC/pmdflts.ini bitmap=0x0001 attrs=0x0000 finder_type=TEXT finder_creator=MARS entry_id=0x62ecb463 verified
|
||||
AFP Set File Info path=SYS:PUBLIC/pmdflts.ini bitmap=0x0001 attrs=0x0040 finder_type=TEXT finder_creator=MARS entry_id=0x62ecb463 verified
|
||||
AFP Set File Info subfunction=0x10 path=SYS:PUBLIC/pmdflts.ini bitmap=0x0001 attrs=0x0004 finder_type=TEXT finder_creator=MARS entry_id=0x62ecb463 verified
|
||||
AFP Set File Info subfunction=0x10 path=SYS:PUBLIC/pmdflts.ini bitmap=0x0001 attrs=0x0000 finder_type=TEXT finder_creator=MARS entry_id=0x62ecb463 verified
|
||||
AFP Set File Info subfunction=0x10 path=SYS:PUBLIC/pmdflts.ini bitmap=0x0001 attrs=0x0040 finder_type=TEXT finder_creator=MARS entry_id=0x62ecb463 verified
|
||||
AFP 2.0 Set File Information: vol=0 request_vol=0 entry=0x00000000 mask=0x0001 path='SYS:PUBLIC/pmdflts.ini' attributes attrs=0x8004
|
||||
AFP 2.0 Set File Information: vol=0 request_vol=0 entry=0x00000000 mask=0x0001 path='SYS:PUBLIC/pmdflts.ini' attributes attrs=0x0004
|
||||
AFP 2.0 Set File Information: vol=0 request_vol=0 entry=0x00000000 mask=0x0001 path='SYS:PUBLIC/pmdflts.ini' attributes attrs=0x8040
|
||||
```
|
||||
The legacy `0x09` endpoint is deliberately routed through the same narrow
|
||||
metadata-only implementation as AFP 2.0 `0x10`; it does not add create, rename,
|
||||
delete, timestamp, or fork-write semantics.
|
||||
|
||||
All other Set File Information bitmap bits and AFP attribute bits, including
|
||||
NoWrite, NoRename, NoDelete, NoCopy, and the computed data/resource-fork-open
|
||||
flags, are intentionally rejected for now. That keeps timestamp,
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Linux smoke test for NetWare AFP 2.0 Set File Information metadata writes.
|
||||
* Linux smoke test for NetWare AFP Set File Information metadata writes.
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
@@ -20,6 +20,7 @@
|
||||
#endif
|
||||
|
||||
#define AFP20_GET_FILE_INFORMATION 0x0f
|
||||
#define AFP_SET_FILE_INFORMATION 0x09
|
||||
#define AFP20_SET_FILE_INFORMATION 0x10
|
||||
#define AFP_ATTRIBUTES_MASK 0x0001
|
||||
#define AFP_FINDER_INFO_MASK 0x0020
|
||||
@@ -35,7 +36,7 @@
|
||||
static void usage(const char *prog)
|
||||
{
|
||||
fprintf(stderr,
|
||||
"Usage: %s [--allow-invalid-namespace] [--allow-invalid-path] "
|
||||
"Usage: %s [--afp09|--afp20] [--allow-invalid-namespace] [--allow-invalid-path] "
|
||||
"[--volume N] [--entry-id ID] [--type FOUR] [--creator FOUR] "
|
||||
"[--invisible|--clear-invisible|--system|--clear-system|--backup|--clear-backup] "
|
||||
"[--finder-info-only|--attributes-only] "
|
||||
@@ -138,6 +139,7 @@ int main(int argc, char **argv)
|
||||
uint32_t volume_number = 0;
|
||||
uint32_t entry_id = 0;
|
||||
uint8_t finder_info[32];
|
||||
uint8_t set_subfunction = AFP20_SET_FILE_INFORMATION;
|
||||
uint16_t request_mask = AFP_FINDER_INFO_MASK;
|
||||
uint16_t attr_request = 0;
|
||||
uint16_t attr_verify_mask = 0;
|
||||
@@ -167,7 +169,11 @@ int main(int argc, char **argv)
|
||||
}
|
||||
|
||||
for (i = 1; i < argc; i++) {
|
||||
if (!strcmp(argv[i], "--allow-invalid-namespace")) {
|
||||
if (!strcmp(argv[i], "--afp09")) {
|
||||
set_subfunction = AFP_SET_FILE_INFORMATION;
|
||||
} else if (!strcmp(argv[i], "--afp20")) {
|
||||
set_subfunction = AFP20_SET_FILE_INFORMATION;
|
||||
} else if (!strcmp(argv[i], "--allow-invalid-namespace")) {
|
||||
allow_invalid_namespace = 1;
|
||||
} else if (!strcmp(argv[i], "--allow-invalid-path")) {
|
||||
allow_invalid_path = 1;
|
||||
@@ -288,7 +294,7 @@ int main(int argc, char **argv)
|
||||
}
|
||||
|
||||
err = NWRequestSimple(conn,
|
||||
NCPC_SFN(0x23, AFP20_SET_FILE_INFORMATION),
|
||||
NCPC_SFN(0x23, set_subfunction),
|
||||
request,
|
||||
data_off,
|
||||
NULL);
|
||||
@@ -337,8 +343,8 @@ int main(int argc, char **argv)
|
||||
return 1;
|
||||
}
|
||||
|
||||
printf("AFP Set File Info path=%s bitmap=0x%04x attrs=0x%04x finder_type=%.4s finder_creator=%.4s entry_id=0x%08x verified\n",
|
||||
path, request_mask, be16_to_cpu(verify_buf + 8),
|
||||
printf("AFP Set File Info subfunction=0x%02x path=%s bitmap=0x%04x attrs=0x%04x finder_type=%.4s finder_creator=%.4s entry_id=0x%08x verified\n",
|
||||
set_subfunction, path, request_mask, be16_to_cpu(verify_buf + 8),
|
||||
finder_info + 0, finder_info + 4, be32_to_cpu(verify_buf + 0));
|
||||
|
||||
ncp_close(conn);
|
||||
|
||||
@@ -235,6 +235,12 @@ run_cmd \
|
||||
"$SCRIPT_DIR/afp_set_file_info_smoke" -S "$SERVER" -U "$USER_NAME" -P "$PASSWORD" \
|
||||
--finder-info-only --type "$FINDER_TYPE" --creator "$FINDER_CREATOR" "$NETWARE_PATH"
|
||||
|
||||
run_cmd \
|
||||
"AFP Set File Information FinderInfo legacy" \
|
||||
"./afp_set_file_info_smoke $COMMON_PRINT --afp09 --finder-info-only --type '$FINDER_TYPE' --creator '$FINDER_CREATOR' '$NETWARE_PATH'" \
|
||||
"$SCRIPT_DIR/afp_set_file_info_smoke" -S "$SERVER" -U "$USER_NAME" -P "$PASSWORD" \
|
||||
--afp09 --finder-info-only --type "$FINDER_TYPE" --creator "$FINDER_CREATOR" "$NETWARE_PATH"
|
||||
|
||||
run_cmd \
|
||||
"AFP Set File Information Invisible" \
|
||||
"./afp_set_file_info_smoke $COMMON_PRINT --attributes-only --invisible '$NETWARE_PATH'" \
|
||||
|
||||
Reference in New Issue
Block a user