tests: add DOS quota write-deny smoke
This commit is contained in:
@@ -51,6 +51,7 @@ set(MARS_DOSUTILS_NEW_ONLY_TOOLS
|
||||
creator
|
||||
whoami
|
||||
ncopy
|
||||
tests
|
||||
)
|
||||
|
||||
if(MARS_DOSUTILS_BUILD_FROM_SOURCE)
|
||||
|
||||
@@ -727,3 +727,5 @@ Prints the effective-rights values returned by several Client32/NCP paths for co
|
||||
`TESTS EFFRIGHT path` also prints exploratory old NCP22 effective-rights call variants for comparing with Novell RIGHTS.
|
||||
|
||||
`TESTS EFFRIGHT path` additionally tests NCP22 subfunction 50 object effective rights using the current login object id.
|
||||
|
||||
`TESTS WRITE4K file [count]` writes one or more exact 4K blocks and returns non-zero if open/write/close fails. It is used by the DOS quota smoke to prove that the 13th 4K write is denied after Linux/MARS-NWE set a 12x4K user quota.
|
||||
|
||||
76
nwtests.c
76
nwtests.c
@@ -25,6 +25,11 @@
|
||||
|
||||
#include "net.h"
|
||||
#include "ncpapi.h"
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <io.h>
|
||||
#include <errno.h>
|
||||
|
||||
#define TEST_RIGHT_S 0x01
|
||||
#define TEST_RIGHT_R 0x02
|
||||
@@ -55,6 +60,7 @@ static void tests_usage(void)
|
||||
fprintf(stdout, " TESTS NCP2225CREATE file [date time id] (create xattr metadata)\n");
|
||||
fprintf(stdout, " TESTS NCP2225MODID file [id] (modifier-id xattr metadata)\n");
|
||||
fprintf(stdout, " TESTS NCP2225MAXSPACE dir [blocks] (directory maximum-space/quota)\n");
|
||||
fprintf(stdout, " TESTS WRITE4K file [count] (write count 4K blocks; default 1)\n");
|
||||
fprintf(stdout, " TESTS NCP221EINFO dir (dump NCP22/1E directory info layout)\n");
|
||||
fprintf(stdout, " TESTS NCP22S4 path RF|42|0x42|ALL|NONE\n");
|
||||
fprintf(stdout, " TESTS NCP22REN oldpath newpath (NCP22/2E Rename Or Move old)\n");
|
||||
@@ -1236,6 +1242,68 @@ static int tests_ncp2225adate(char *path, char *date_arg)
|
||||
|
||||
|
||||
|
||||
|
||||
static int tests_parse_int_arg(char *s, int *value_out)
|
||||
{
|
||||
long v;
|
||||
char *end;
|
||||
|
||||
if (!s || !*s || !value_out)
|
||||
return(-1);
|
||||
|
||||
v = strtol(s, &end, 0);
|
||||
if (!end || *end || v < 1 || v > 32767L)
|
||||
return(-1);
|
||||
|
||||
*value_out = (int)v;
|
||||
return(0);
|
||||
}
|
||||
|
||||
static int tests_write4k(char *path, char *count_arg)
|
||||
{
|
||||
char buf[4096];
|
||||
int count = 1;
|
||||
int fd;
|
||||
int i;
|
||||
|
||||
if (!path || !*path) {
|
||||
fprintf(stdout, "Usage: TESTS WRITE4K file [count]\n");
|
||||
return(1);
|
||||
}
|
||||
|
||||
if (count_arg && tests_parse_int_arg(count_arg, &count)) {
|
||||
fprintf(stdout, "Bad WRITE4K count '%s'. Use a positive decimal/hex number.\n", count_arg);
|
||||
return(1);
|
||||
}
|
||||
|
||||
memset(buf, 'Q', sizeof(buf));
|
||||
fd = open(path, O_BINARY | O_RDWR | O_CREAT | O_TRUNC | O_DENYNONE,
|
||||
S_IREAD | S_IWRITE);
|
||||
if (fd < 0) {
|
||||
fprintf(stdout, "WRITE4K open failed path=%s errno=%d\n", path, errno);
|
||||
return(2);
|
||||
}
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
unsigned written = 0;
|
||||
if (_dos_write(fd, buf, sizeof(buf), &written) || written != sizeof(buf)) {
|
||||
fprintf(stdout, "WRITE4K write failed path=%s block=%d/%d written=%u errno=%d\n",
|
||||
path, i + 1, count, written, errno);
|
||||
close(fd);
|
||||
return(3);
|
||||
}
|
||||
}
|
||||
|
||||
if (close(fd)) {
|
||||
fprintf(stdout, "WRITE4K close failed path=%s errno=%d\n", path, errno);
|
||||
return(4);
|
||||
}
|
||||
|
||||
fprintf(stdout, "WRITE4K ok path=%s blocks=%d bytes=%ld\n",
|
||||
path, count, (long)count * 4096L);
|
||||
return(0);
|
||||
}
|
||||
|
||||
static int tests_ncp2225maxspace(char *path, char *space_arg)
|
||||
{
|
||||
uint8 dhandle = 0;
|
||||
@@ -2669,6 +2737,14 @@ int func_tests(int argc, char *argv[], int mode)
|
||||
return tests_ncp2225adate(argv[2], argv[3]);
|
||||
}
|
||||
|
||||
if (tool_strsame(argv[1], "WRITE4K")) {
|
||||
if (argc < 3)
|
||||
return tests_write4k(NULL, NULL);
|
||||
if (argc < 4)
|
||||
return tests_write4k(argv[2], NULL);
|
||||
return tests_write4k(argv[2], argv[3]);
|
||||
}
|
||||
|
||||
if (tool_strsame(argv[1], "NCP2225MAXSPACE")) {
|
||||
if (argc < 3)
|
||||
return tests_ncp2225maxspace(NULL, NULL);
|
||||
|
||||
@@ -72,6 +72,7 @@ script or log.
|
||||
| `rightsuser/` | varies | Additional user-rights experiments. |
|
||||
| `renmove/` | varies | Rename/move experiments. |
|
||||
| `ncopy/` | varies | NCOPY experiments. |
|
||||
| `quota/` | `DQTSTA.BAT` + `DQTC.BAT` | Mixed Linux/DOS userquota write-deny smoke: Linux sets quota, DOS writes until deny. |
|
||||
| `filer/` | varies | FILER-related notes/experiments. |
|
||||
|
||||
## Host-side NSS/OES metadata readback
|
||||
@@ -84,7 +85,7 @@ sh dosutils/test/cmnwmeta.sh /path/to/SYS /path/to/nwfs_xattr_dump > meta.log
|
||||
```
|
||||
|
||||
The collector decodes `netware.metadata`, `netware.quota`, and
|
||||
`netware.userquota` from the files and directories changed by the DOS tests.
|
||||
`netware.userquota.0` from the files and directories changed by the DOS tests.
|
||||
This is the expected verification layer for the NSS migration: DOS tools or
|
||||
NCPFS perform the mutation, and `nwfs_xattr_dump` proves that the resulting
|
||||
state landed in the OES-compatible `netware.*` metadata rather than only in the
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
# sh dosutils/test/cmnwmeta.sh /path/to/SYS /path/to/nwfs_xattr_dump > meta.log
|
||||
#
|
||||
# The dumper reads the mars-nwe userspace xattr mapping, so on Linux it looks
|
||||
# at user.netware.metadata, user.netware.quota and user.netware.userquota.
|
||||
# at user.netware.metadata, user.netware.quota and user.netware.userquota.0.
|
||||
|
||||
set -eu
|
||||
|
||||
@@ -44,7 +44,8 @@ for rel in \
|
||||
NDIRTST NDIRCMP \
|
||||
TFILE \
|
||||
NCPTST NCPCMP \
|
||||
RUTEST RUTCMP
|
||||
RUTEST RUTCMP \
|
||||
DQTTEST DQTCMP
|
||||
do
|
||||
if [ -e "$SYSROOT/$rel" ]; then
|
||||
find "$SYSROOT/$rel" -xdev \( -type f -o -type d \) -print
|
||||
|
||||
61
test/quota/DQTC.BAT
Normal file
61
test/quota/DQTC.BAT
Normal file
@@ -0,0 +1,61 @@
|
||||
@ECHO OFF
|
||||
REM DQTC.BAT
|
||||
REM Run as NOPASSUSER after Linux-side quota setup.
|
||||
|
||||
F:
|
||||
CD \
|
||||
IF NOT EXIST DQTCMP\NUL MD DQTCMP
|
||||
IF NOT EXIST DQTCMP\DOS\NUL MD DQTCMP\DOS
|
||||
IF NOT EXIST DQTTEST\NCPQFILL\NUL MD DQTTEST\NCPQFILL
|
||||
IF EXIST F:\DQTCMP\PASS.TAG DEL F:\DQTCMP\PASS.TAG
|
||||
IF EXIST F:\DQTCMP\FAIL.TAG DEL F:\DQTCMP\FAIL.TAG
|
||||
IF EXIST F:\DQTCMP\DOS\WRITE.LOG DEL F:\DQTCMP\DOS\WRITE.LOG
|
||||
|
||||
ECHO DQTC DOS quota write test as current user > F:\DQTCMP\DOS\WRITE.LOG
|
||||
ECHO Writing 12 allowed 4K files. >> F:\DQTCMP\DOS\WRITE.LOG
|
||||
|
||||
PUBLIC\TESTS WRITE4K F:\DQTTEST\NCPQFILL\Q00001.BIN 1 >> F:\DQTCMP\DOS\WRITE.LOG
|
||||
IF ERRORLEVEL 1 GOTO FAILGOOD
|
||||
PUBLIC\TESTS WRITE4K F:\DQTTEST\NCPQFILL\Q00002.BIN 1 >> F:\DQTCMP\DOS\WRITE.LOG
|
||||
IF ERRORLEVEL 1 GOTO FAILGOOD
|
||||
PUBLIC\TESTS WRITE4K F:\DQTTEST\NCPQFILL\Q00003.BIN 1 >> F:\DQTCMP\DOS\WRITE.LOG
|
||||
IF ERRORLEVEL 1 GOTO FAILGOOD
|
||||
PUBLIC\TESTS WRITE4K F:\DQTTEST\NCPQFILL\Q00004.BIN 1 >> F:\DQTCMP\DOS\WRITE.LOG
|
||||
IF ERRORLEVEL 1 GOTO FAILGOOD
|
||||
PUBLIC\TESTS WRITE4K F:\DQTTEST\NCPQFILL\Q00005.BIN 1 >> F:\DQTCMP\DOS\WRITE.LOG
|
||||
IF ERRORLEVEL 1 GOTO FAILGOOD
|
||||
PUBLIC\TESTS WRITE4K F:\DQTTEST\NCPQFILL\Q00006.BIN 1 >> F:\DQTCMP\DOS\WRITE.LOG
|
||||
IF ERRORLEVEL 1 GOTO FAILGOOD
|
||||
PUBLIC\TESTS WRITE4K F:\DQTTEST\NCPQFILL\Q00007.BIN 1 >> F:\DQTCMP\DOS\WRITE.LOG
|
||||
IF ERRORLEVEL 1 GOTO FAILGOOD
|
||||
PUBLIC\TESTS WRITE4K F:\DQTTEST\NCPQFILL\Q00008.BIN 1 >> F:\DQTCMP\DOS\WRITE.LOG
|
||||
IF ERRORLEVEL 1 GOTO FAILGOOD
|
||||
PUBLIC\TESTS WRITE4K F:\DQTTEST\NCPQFILL\Q00009.BIN 1 >> F:\DQTCMP\DOS\WRITE.LOG
|
||||
IF ERRORLEVEL 1 GOTO FAILGOOD
|
||||
PUBLIC\TESTS WRITE4K F:\DQTTEST\NCPQFILL\Q00010.BIN 1 >> F:\DQTCMP\DOS\WRITE.LOG
|
||||
IF ERRORLEVEL 1 GOTO FAILGOOD
|
||||
PUBLIC\TESTS WRITE4K F:\DQTTEST\NCPQFILL\Q00011.BIN 1 >> F:\DQTCMP\DOS\WRITE.LOG
|
||||
IF ERRORLEVEL 1 GOTO FAILGOOD
|
||||
PUBLIC\TESTS WRITE4K F:\DQTTEST\NCPQFILL\Q00012.BIN 1 >> F:\DQTCMP\DOS\WRITE.LOG
|
||||
IF ERRORLEVEL 1 GOTO FAILGOOD
|
||||
|
||||
ECHO Attempting expected failing 13th 4K file. >> F:\DQTCMP\DOS\WRITE.LOG
|
||||
PUBLIC\TESTS WRITE4K F:\DQTTEST\NCPQFILL\QFAIL.BIN 1 >> F:\DQTCMP\DOS\WRITE.LOG
|
||||
IF ERRORLEVEL 1 GOTO PASS
|
||||
|
||||
ECHO FAIL: expected QFAIL.BIN to be denied, but it succeeded. >> F:\DQTCMP\DOS\WRITE.LOG
|
||||
ECHO FAIL > F:\DQTCMP\FAIL.TAG
|
||||
GOTO END
|
||||
|
||||
:FAILGOOD
|
||||
ECHO FAIL: an allowed 4K write failed before the quota boundary. >> F:\DQTCMP\DOS\WRITE.LOG
|
||||
ECHO FAIL > F:\DQTCMP\FAIL.TAG
|
||||
GOTO END
|
||||
|
||||
:PASS
|
||||
ECHO PASS: 13th 4K file was denied. >> F:\DQTCMP\DOS\WRITE.LOG
|
||||
ECHO PASS > F:\DQTCMP\PASS.TAG
|
||||
GOTO END
|
||||
|
||||
:END
|
||||
TYPE F:\DQTCMP\DOS\WRITE.LOG
|
||||
87
test/quota/DQTSTA.BAT
Normal file
87
test/quota/DQTSTA.BAT
Normal file
@@ -0,0 +1,87 @@
|
||||
@ECHO OFF
|
||||
REM DQTSTA.BAT
|
||||
REM DOS-side quota write-deny smoke for MARS-NWE.
|
||||
REM
|
||||
REM This is intentionally a mixed Linux/DOS test:
|
||||
REM 1. Run DQTSTA PREP as SUPERVISOR from the target volume.
|
||||
REM 2. On Linux set the volume userquota for NOPASSUSER.
|
||||
REM 3. Login as NOPASSUSER and run DQTC.BAT from this directory.
|
||||
REM 4. Login as SUPERVISOR and run DQTSTA PART2, then DQTZIP.
|
||||
|
||||
IF "%1"=="" GOTO PREP
|
||||
IF "%1"=="PREP" GOTO PREP
|
||||
IF "%1"=="prep" GOTO PREP
|
||||
IF "%1"=="PART2" GOTO PART2
|
||||
IF "%1"=="part2" GOTO PART2
|
||||
ECHO Usage: DQTSTA [PREP^|PART2]
|
||||
GOTO END
|
||||
|
||||
:PREP
|
||||
F:
|
||||
CD \
|
||||
|
||||
IF EXIST DQTTEST\NUL DELTREE /Y DQTTEST\*.*
|
||||
IF EXIST DQTCMP\NUL DELTREE /Y DQTCMP\*.*
|
||||
IF NOT EXIST DQTTEST\NUL MD DQTTEST
|
||||
IF NOT EXIST DQTTEST\NCPQFILL\NUL MD DQTTEST\NCPQFILL
|
||||
IF NOT EXIST DQTCMP\NUL MD DQTCMP
|
||||
IF NOT EXIST DQTCMP\DOS\NUL MD DQTCMP\DOS
|
||||
IF NOT EXIST DQTCMP\SETUP\NUL MD DQTCMP\SETUP
|
||||
|
||||
IF EXIST F:\DQTCMP\RUN.LOG DEL F:\DQTCMP\RUN.LOG
|
||||
IF EXIST F:\DQTCMP\SUMMARY.TXT DEL F:\DQTCMP\SUMMARY.TXT
|
||||
IF EXIST F:\DQTCMP\FAIL.TAG DEL F:\DQTCMP\FAIL.TAG
|
||||
IF EXIST F:\DQTCMP\PASS.TAG DEL F:\DQTCMP\PASS.TAG
|
||||
IF EXIST F:\DQTCMP\DQTSTA.ZIP DEL F:\DQTCMP\DQTSTA.ZIP
|
||||
IF EXIST F:\DQTCMP\ZIP.LOG DEL F:\DQTCMP\ZIP.LOG
|
||||
IF EXIST F:\DQTCMP\DOS\*.OUT DEL F:\DQTCMP\DOS\*.OUT
|
||||
|
||||
ECHO DQTSTA DOS quota write-deny smoke > F:\DQTCMP\RUN.LOG
|
||||
ECHO Volume-side setup is done from DOS. Quota limit is set from Linux. >> F:\DQTCMP\RUN.LOG
|
||||
ECHO Expected Linux setup: userquota for NOPASSUSER allows 12x4K, then DOS write 13th file fails. >> F:\DQTCMP\RUN.LOG
|
||||
ECHO. >> F:\DQTCMP\RUN.LOG
|
||||
|
||||
REM Give the normal user enough rights to create files and write result logs.
|
||||
IF EXIST F:\NPUBLIC\GRANT.EXE GOTO HAVEGRANT
|
||||
ECHO ERROR: F:\NPUBLIC\GRANT.EXE not found. >> F:\DQTCMP\RUN.LOG
|
||||
ECHO ERROR: F:\NPUBLIC\GRANT.EXE not found.
|
||||
GOTO END
|
||||
|
||||
:HAVEGRANT
|
||||
NPUBLIC\GRANT R W C E M F A FOR F:\DQTTEST TO USER NOPASSUSER > F:\DQTCMP\SETUP\GRANT1.OUT
|
||||
NPUBLIC\GRANT R W C E M F A FOR F:\DQTTEST\NCPQFILL TO USER NOPASSUSER > F:\DQTCMP\SETUP\GRANT2.OUT
|
||||
NPUBLIC\GRANT R W C E M F A FOR F:\DQTCMP TO USER NOPASSUSER > F:\DQTCMP\SETUP\GRANT3.OUT
|
||||
NPUBLIC\RIGHTS F:\DQTTEST\NCPQFILL > F:\DQTCMP\SETUP\RIGHTS.OUT
|
||||
|
||||
ECHO === NEXT LINUX STEP === > F:\DQTCMP\LINUX.TXT
|
||||
ECHO Set volume userquota for NOPASSUSER to 12x4K on this volume. >> F:\DQTCMP\LINUX.TXT
|
||||
ECHO Then login as NOPASSUSER and run: >> F:\DQTCMP\LINUX.TXT
|
||||
ECHO F:\DQTC.BAT >> F:\DQTCMP\LINUX.TXT
|
||||
ECHO Then login as SUPERVISOR and run: >> F:\DQTCMP\LINUX.TXT
|
||||
ECHO F:\DQTSTA.BAT PART2 >> F:\DQTCMP\LINUX.TXT
|
||||
|
||||
ECHO DQTSTA PREP finished. >> F:\DQTCMP\RUN.LOG
|
||||
ECHO.
|
||||
ECHO DQTSTA PREP fertig.
|
||||
ECHO Jetzt Linux quota fuer NOPASSUSER setzen, dann als NOPASSUSER F:\DQTC.BAT starten.
|
||||
GOTO END
|
||||
|
||||
:PART2
|
||||
F:
|
||||
CD \
|
||||
IF NOT EXIST DQTCMP\NUL MD DQTCMP
|
||||
|
||||
ECHO DQTSTA PART2 summary > F:\DQTCMP\SUMMARY.TXT
|
||||
IF EXIST F:\DQTCMP\PASS.TAG ECHO PASS: DOS quota deny observed. >> F:\DQTCMP\SUMMARY.TXT
|
||||
IF EXIST F:\DQTCMP\FAIL.TAG ECHO FAIL: DOS quota deny was not observed. >> F:\DQTCMP\SUMMARY.TXT
|
||||
IF NOT EXIST F:\DQTCMP\PASS.TAG IF NOT EXIST F:\DQTCMP\FAIL.TAG ECHO UNKNOWN: DQTC.BAT result tags missing. >> F:\DQTCMP\SUMMARY.TXT
|
||||
ECHO. >> F:\DQTCMP\SUMMARY.TXT
|
||||
ECHO DOS log files are in F:\DQTCMP\DOS. >> F:\DQTCMP\SUMMARY.TXT
|
||||
ECHO Linux/nw.log evidence should be collected with the matching mars-nwe smoke wrapper. >> F:\DQTCMP\SUMMARY.TXT
|
||||
|
||||
ECHO.
|
||||
TYPE F:\DQTCMP\SUMMARY.TXT
|
||||
ECHO Optional: run DQTZIP.
|
||||
GOTO END
|
||||
|
||||
:END
|
||||
19
test/quota/DQTZIP.BAT
Normal file
19
test/quota/DQTZIP.BAT
Normal file
@@ -0,0 +1,19 @@
|
||||
@ECHO OFF
|
||||
REM DQTZIP.BAT
|
||||
REM Optional packer for DOS quota smoke result files.
|
||||
|
||||
F:
|
||||
CD \DQTCMP
|
||||
|
||||
IF EXIST DQTSTA.ZIP DEL DQTSTA.ZIP
|
||||
IF EXIST ZIP.LOG DEL ZIP.LOG
|
||||
|
||||
ECHO Creating DQTSTA.ZIP > ZIP.LOG
|
||||
ZIP -r DQTSTA.ZIP RUN.LOG SUMMARY.TXT LINUX.TXT PASS.TAG FAIL.TAG DOS SETUP >> ZIP.LOG
|
||||
|
||||
ECHO.
|
||||
ECHO ZIP step finished.
|
||||
ECHO Check:
|
||||
ECHO F:\DQTCMP\DQTSTA.ZIP
|
||||
ECHO F:\DQTCMP\ZIP.LOG
|
||||
ECHO.
|
||||
55
test/quota/README.md
Normal file
55
test/quota/README.md
Normal file
@@ -0,0 +1,55 @@
|
||||
# DOS quota write-deny smoke
|
||||
|
||||
This test proves the last step of NetWare-style quota enforcement with DOS
|
||||
board tools: Linux/NCPFS sets the user quota, then a real DOS client logs in as
|
||||
`NOPASSUSER` and attempts the file writes.
|
||||
|
||||
It is intentionally split because the authoritative quota setup remains on the
|
||||
Linux/MARS-NWE side:
|
||||
|
||||
1. In DOS, login as `SUPERVISOR` on the target volume and run:
|
||||
|
||||
```bat
|
||||
F:
|
||||
DQTSTA PREP
|
||||
```
|
||||
|
||||
This creates `F:\DQTTEST\NCPQFILL`, grants `NOPASSUSER` write/create rights,
|
||||
and creates `F:\DQTCMP` for logs.
|
||||
|
||||
2. On Linux, set the user quota for `NOPASSUSER` to 12 4K blocks on the same
|
||||
volume. With the mars-nwe ncpfs helper this is typically:
|
||||
|
||||
```sh
|
||||
./nwfs_ncpfs_userquota -S MARS -U SUPERVISOR -P 'password' \
|
||||
--volume QUOTA --object NOPASSUSER --type 1 --limit-4k 12
|
||||
```
|
||||
|
||||
For SYS/NWQUOTA metadata-backend testing, use `--volume SYS` instead.
|
||||
|
||||
3. In DOS, login as `NOPASSUSER` and run:
|
||||
|
||||
```bat
|
||||
F:\DQTC.BAT
|
||||
```
|
||||
|
||||
`DQTC` writes `Q00001.BIN` through `Q00012.BIN` as 4K files, then expects
|
||||
`QFAIL.BIN` to be denied.
|
||||
|
||||
4. In DOS, login as `SUPERVISOR` and run:
|
||||
|
||||
```bat
|
||||
F:\DQTSTA PART2
|
||||
F:\DQTZIP
|
||||
```
|
||||
|
||||
Expected result:
|
||||
|
||||
```text
|
||||
PASS: DOS quota deny observed.
|
||||
```
|
||||
|
||||
The test does not set quotas itself. That keeps the authority split explicit:
|
||||
Linuxquota volumes are configured/enforced by the Linux backend, while NWQUOTA
|
||||
metadata volumes use the MARS-NWE metadata backend. The DOS part proves the
|
||||
client-visible write behavior.
|
||||
Reference in New Issue
Block a user