saltcorn-samba 0.4.10 → 0.4.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +68 -0
- package/package.json +1 -1
- package/readdir-compat.js +15 -2
- package/smb-client.js +24 -20
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,74 @@ All notable changes to `saltcorn-samba` are documented here.
|
|
|
4
4
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/)
|
|
5
5
|
and this project adheres to [Semantic Versioning](https://semver.org/).
|
|
6
6
|
|
|
7
|
+
## [0.4.11] – 2026-07-06
|
|
8
|
+
|
|
9
|
+
### Changed – **Ehrliche Fehlerpropagation statt stiller Fallback**
|
|
10
|
+
|
|
11
|
+
In 0.4.10 wurde der neue `readdir-compat.js`-Wrapper eingeführt, der
|
|
12
|
+
vor dem eigentlichen `QUERY_DIRECTORY` die FileInformationClass
|
|
13
|
+
automatisch von 37 → 3 → 1 durchprobiert. Zwei Probleme kamen dabei
|
|
14
|
+
zum Vorschein:
|
|
15
|
+
|
|
16
|
+
1. **Alle drei Info-Klassen lieferten weiterhin `0xC0000033`** auf
|
|
17
|
+
dem betroffenen Server. Das Umschalten der Info-Klasse ist also
|
|
18
|
+
*nicht* die eigentliche Ursache — die Annahme aus 0.4.10 war falsch.
|
|
19
|
+
2. **Der Wrapper in `smb-client.js` fiel bei totalem Compat-Fehler
|
|
20
|
+
still auf das kaputte `client.readdir()` zurück**, das exakt
|
|
21
|
+
dieselbe (kaputte) FileInformationClass 37 verwendet. Dadurch
|
|
22
|
+
wurde die 0.4.10-Diagnostik komplett verschluckt und das Symptom
|
|
23
|
+
sah unverändert aus wie vor 0.4.10.
|
|
24
|
+
|
|
25
|
+
**Fixes in 0.4.11:**
|
|
26
|
+
|
|
27
|
+
- `smb-client.js` erkennt jetzt den 0xC0000033-Erschöpfungsfehler aus
|
|
28
|
+
dem Compat-Modul (Muster `"all classes exhausted"`) und propagiert
|
|
29
|
+
ihn direkt — kein stiller Retry mehr über das kaputte
|
|
30
|
+
`client.readdir()`.
|
|
31
|
+
- `readdir-compat.js` wirft bei Ausschöpfung aller drei Klassen einen
|
|
32
|
+
synthetischen Fehler mit klarem Wortlaut:
|
|
33
|
+
`"QUERY_DIRECTORY failed: 0xC0000033 (all classes exhausted; no
|
|
34
|
+
working FileInformationClass on this server). Tried:
|
|
35
|
+
FileIdBothDirectoryInformation=37, FileBothDirectoryInformation=3,
|
|
36
|
+
FileDirectoryInformation=1."`
|
|
37
|
+
Der Fehler trägt zusätzlich ein `.attempts`-Array mit den
|
|
38
|
+
NT-Statuscodes pro Klasse für spätere Diagnose.
|
|
39
|
+
|
|
40
|
+
### Was das für dich bedeutet
|
|
41
|
+
|
|
42
|
+
Der gelbe Hinweis und `QUERY_DIRECTORY failed: 0xC0000033` sind
|
|
43
|
+
**noch nicht behoben** — 0.4.11 macht den Fehler nur ehrlich sichtbar,
|
|
44
|
+
sodass wir aus dem nächsten Diagnoselauf echte Signale bekommen.
|
|
45
|
+
|
|
46
|
+
**Nächster Schritt — bitte auf dem Saltcorn-Server ausführen** (im
|
|
47
|
+
entpackten Plugin-Verzeichnis, oder direkt aus dem ZIP):
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
cd /pfad/zu/saltcorn-samba
|
|
51
|
+
node tools/diag-basepath.js \
|
|
52
|
+
--host 192.168.110.10 \
|
|
53
|
+
--share buero \
|
|
54
|
+
--path static \
|
|
55
|
+
--user 01_vassen \
|
|
56
|
+
--domain buero.ib-vassen.de \
|
|
57
|
+
--password 'DEIN_PASSWORT'
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
Das Skript führt 6 Sonden mit rohen NT-Statuscodes aus (TREE_CONNECT,
|
|
61
|
+
CREATE, QUERY_DIRECTORY mit allen drei Info-Klassen, `stat`-Probe).
|
|
62
|
+
Die Ausgabe zeigt, an welcher Stelle Samba den Fehler wirft und mit
|
|
63
|
+
welchem Statuscode. Damit können wir 0.4.12 gezielt schreiben statt
|
|
64
|
+
weiter zu raten.
|
|
65
|
+
|
|
66
|
+
Ein heißer Kandidat für 0.4.12 (Wire-Format-Bug in `smb3-client`):
|
|
67
|
+
`encodeQueryDirectoryRequest` setzt `FileNameOffset` immer auf 96,
|
|
68
|
+
auch wenn kein Suchmuster gesendet wird — laut
|
|
69
|
+
[MS-SMB2 §2.2.33](https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-smb2/10906442-294c-46d3-8515-c277efe1f752)
|
|
70
|
+
MUSS das Feld dann 0 sein. Bestätigung dafür aber bitte erst nach
|
|
71
|
+
der Diagnose.
|
|
72
|
+
|
|
73
|
+
---
|
|
74
|
+
|
|
7
75
|
## [0.4.10] – 2026-07-05
|
|
8
76
|
|
|
9
77
|
### Fixed – **`0xC0000033` beim tatsächlichen Auflisten (Tree-View, File-Manager) endgültig behoben**
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "saltcorn-samba",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.11",
|
|
4
4
|
"description": "Saltcorn plugin: browse, upload, rename and delete files on a Samba/CIFS share via SMB 3.1.1 (AES-CMAC signing, optional encryption). File-manager view, directory tree, inline PDF viewer, external-app open (smb://).",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"scripts": {
|
package/readdir-compat.js
CHANGED
|
@@ -331,6 +331,7 @@ async function readdirCompat(rawClient, sharePath) {
|
|
|
331
331
|
: TRY_ORDER.slice();
|
|
332
332
|
|
|
333
333
|
let lastErr = null;
|
|
334
|
+
const attempts = [];
|
|
334
335
|
for (const cls of order) {
|
|
335
336
|
try {
|
|
336
337
|
const entries = await queryAll({
|
|
@@ -349,9 +350,10 @@ async function readdirCompat(rawClient, sharePath) {
|
|
|
349
350
|
return entries.map(dirEntryToPluginEntry);
|
|
350
351
|
} catch (err) {
|
|
351
352
|
lastErr = err;
|
|
353
|
+
const msg = String((err && err.message) || err || "");
|
|
354
|
+
attempts.push({ class: cls.name, code: cls.code, error: msg });
|
|
352
355
|
// Only retry with a different class on OBJECT_NAME_INVALID / info-class
|
|
353
356
|
// rejection — any other error (auth, connection, missing) is fatal.
|
|
354
|
-
const msg = String((err && err.message) || err || "");
|
|
355
357
|
const isInfoClassBug =
|
|
356
358
|
/0xC0000033|OBJECT_NAME_INVALID|STATUS_INVALID_INFO_CLASS/i.test(msg);
|
|
357
359
|
if (!isInfoClassBug) {
|
|
@@ -360,7 +362,18 @@ async function readdirCompat(rawClient, sharePath) {
|
|
|
360
362
|
// else: fall through to next class in order
|
|
361
363
|
}
|
|
362
364
|
}
|
|
363
|
-
|
|
365
|
+
// All classes tried and all failed with 0xC0000033. Report a
|
|
366
|
+
// synthesised error that is uniquely identifiable ("all classes
|
|
367
|
+
// exhausted") so the caller can decide not to fall back to
|
|
368
|
+
// smb3-client's own readdir (which uses class 37 again).
|
|
369
|
+
const finalMsg =
|
|
370
|
+
"QUERY_DIRECTORY failed: 0xC0000033 (all classes exhausted; " +
|
|
371
|
+
"no working FileInformationClass on this server). Tried: " +
|
|
372
|
+
attempts.map((a) => a.class + "=" + a.code).join(", ") + ".";
|
|
373
|
+
const summary = new Error(finalMsg);
|
|
374
|
+
summary.cause = lastErr;
|
|
375
|
+
summary.attempts = attempts;
|
|
376
|
+
throw summary;
|
|
364
377
|
} finally {
|
|
365
378
|
// Always close the handle. Ignore errors.
|
|
366
379
|
try {
|
package/smb-client.js
CHANGED
|
@@ -274,30 +274,34 @@ async function buildClient(config) {
|
|
|
274
274
|
*/
|
|
275
275
|
async readdir(rel) {
|
|
276
276
|
const full = resolvePath(rel);
|
|
277
|
-
// v0.4.
|
|
278
|
-
// FileInformationClass values
|
|
279
|
-
//
|
|
280
|
-
//
|
|
281
|
-
//
|
|
282
|
-
//
|
|
283
|
-
//
|
|
284
|
-
|
|
277
|
+
// v0.4.11: prefer the compat readdir (which tries multiple
|
|
278
|
+
// FileInformationClass values). If it succeeds we are done — no
|
|
279
|
+
// extra per-entry stat fan-out needed because compat returns rich
|
|
280
|
+
// entries directly. If it fails, we ONLY fall back to smb3-client's
|
|
281
|
+
// built-in readdir when the compat failure was not itself the
|
|
282
|
+
// Samba-4.23 bug (0xC0000033 across all classes). If it *was*, the
|
|
283
|
+
// built-in readdir will produce the exact same 0xC0000033 — no
|
|
284
|
+
// point trying it, and it would hide the diagnostics compat has
|
|
285
|
+
// gathered. Instead we rethrow the compat error verbatim so the
|
|
286
|
+
// caller sees the true root cause.
|
|
287
|
+
let compatErr = null;
|
|
285
288
|
try {
|
|
286
|
-
|
|
287
|
-
return entriesFromCompat;
|
|
289
|
+
return await readdirCompat(client, full);
|
|
288
290
|
} catch (err) {
|
|
289
|
-
|
|
290
|
-
// handling as before. This preserves prior behaviour for servers
|
|
291
|
-
// where the compat path fails for reasons unrelated to the
|
|
292
|
-
// FileInformationClass bug (e.g. missing dir, permission).
|
|
291
|
+
compatErr = err;
|
|
293
292
|
const compatMsg = String((err && err.message) || err || "");
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
293
|
+
// If compat ran into the exact same info-class rejection with
|
|
294
|
+
// ALL classes exhausted, the built-in readdir cannot possibly
|
|
295
|
+
// help — it uses class 37, which compat already tried. Rethrow
|
|
296
|
+
// now so callers see the real reason.
|
|
297
|
+
if (/0xC0000033|OBJECT_NAME_INVALID/i.test(compatMsg) &&
|
|
298
|
+
/all classes exhausted|no working FileInformationClass/i.test(compatMsg)) {
|
|
299
|
+
throw err;
|
|
300
300
|
}
|
|
301
|
+
// Otherwise (compat failed for structural reasons like an unknown
|
|
302
|
+
// internal-module path, or a transient socket error) fall through
|
|
303
|
+
// to the classic path so the existing German error rewrites still
|
|
304
|
+
// apply.
|
|
301
305
|
}
|
|
302
306
|
let dirents;
|
|
303
307
|
try {
|