Document SMB smbclient compatibility fixes (cipher_count, username case, signing key)

This commit is contained in:
Warren
2026-06-24 22:31:49 +08:00
parent 12ddec24b4
commit f3b75fae3d

View File

@@ -4777,3 +4777,87 @@ markbase-core/src/provider/
- OpenNAS: 65% (storage + backup, no Docker)
**Next Release Target**: 75% coverage (NFS + LDAP + SMB3 encryption)
---
## WebDAV 404 Fix + `MB_WEBDAV_USE_S3`2026-06-24⭐⭐⭐⭐⭐
**Root cause**: User WebDAV (`/webdav/`) returned 404 because `handle_webdav_multi` used S3Vfs when `s3.enabled=true` in `config/s3.toml`. S3Vfs tried to HEAD local files via `http://localhost:11438/webdav-demo/{path}` which returned 404 → `FsError::NotFound`.
**Fix**: Added `MB_WEBDAV_USE_S3` env var (default `false`), decoupling user WebDAV backend from global S3 config. Admin WebDAV already used `LocalFs` directly.
**Files modified**: `markbase-core/src/server.rs` — line 159-161: `use_s3` now reads from `MB_WEBDAV_USE_S3` env var instead of `s3_cfg.s3.enabled`.
**Verified**: `PROPFIND /webdav/` returns HTTP 207 with full file listing (48 files, 596MB video).
---
## SMB Samba smbclient Compatibility Fixes2026-06-24⭐⭐⭐⭐⭐
**Root causes**: Three bugs preventing Samba smbclient from connecting to MarkBase SMB server.
### Bug #1: cipher_count = 2 (SMB 3.x Negotiate) ✅
**Problem**: Samba smbclient validation check at `smbXcli_negprot_smb2_done()` (line 5931):
```c
cipher_count = SVAL(cipher->data.data, 0);
if (cipher_count != 1) {
tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE); // ← This was failing!
}
```
**Fix**: Changed negotiate.rs to advertise single cipher (AES-128-GCM):
```rust
cipher_count: 1, // Was 2
ciphers: vec![EncryptionCapabilities::CIPHER_AES_128_GCM], // Was [AES-GCM, AES-CCM]
```
### Bug #2: Username Case Sensitivity ✅
**Problem**: ACL lookup was case-sensitive, but SMB usernames should be case-insensitive.
**Fix**: Normalized usernames to lowercase at all points:
- `ntlm.rs`: `Identity::User { user: auth.user.to_lowercase(), ... }`
- `builder.rs`: Share.user() + SmbServerBuilder.user() normalize to lowercase
- `session_setup.rs`: `users.get(&u.to_lowercase())`
### Bug #3: SMB 2.x Signing Key Derivation ✅
**Problem**: SMB 2.x was using SMB 3.0 KDF derivation, but should use session_base_key directly.
**Fix**: Per MS-SMB2 §3.1.4.1:
```rust
let signing_key = match dialect {
Some(Dialect::Smb311) => [0u8; 16], // Derived later
Some(Dialect::Smb300) | Some(Dialect::Smb302) => signing_key_30(&session_base_key),
Some(Dialect::Smb202) | Some(Dialect::Smb210) => session_base_key, // Direct for SMB 2.x
...
};
```
### Verification
| SMB Dialect | smbclient Test | Status |
|-------------|----------------|--------|
| SMB 2.02 | `smbclient -m SMB2_02` | ✅ PASS |
| SMB 2.10 | `smbclient -m SMB2_10` | ✅ PASS |
| SMB 3.0 | `smbclient -m SMB3` | ✅ PASS |
| SMB 3.11 | `smbclient -m SMB3_11` | ✅ PASS |
### Commits
| Fix | Commit | Files Changed |
|-----|--------|---------------|
| **#1 + #2** | `6f223c9` | negotiate.rs, ntlm.rs, builder.rs |
| **#3** | `12ddec2` | session_setup.rs |
### Key Reference
**Samba source code** (`libcli/smb/smbXcli_base.c`):
- Line 5575: `smbXcli_negprot_smb2_done()` function
- Line 5931: `cipher_count != 1` validation
- Line 5738-5742: `sign_algo` selection based on protocol
**MS-SMB2 specification**:
- §3.1.4.1: Signing key derivation per dialect
- §3.1.4.2: SP 800-108 KDF for SMB 3.x