# ms-lsad
Pure-Rust client for the [MS-LSAD] Local Security Authority Domain Policy
Remote Protocol.
Companion to [`ms-lsat`](https://crates.io/crates/ms-lsat) — both bind against
`\PIPE\lsarpc` (interface UUID `12345778-1234-abcd-ef00-0123456789ab`, v0.0).
LSAT covers SID↔name translation; this crate covers **domain policy read** and
**trusted-domain object (TDO) enumeration**.
**Dual-use** — audit / DFIR tools enumerate trust configuration; red-team tools
use trust enumeration as a scouting step before cross-forest attack chains.
## v0.1 opnums
| 44 | `LsarOpenPolicy2` | ✅ (reused from `ms-lsat`) |
| 13 | `LsarEnumerateTrustedDomains` | ✅ live-validated against Server 2025 |
| 0 | `LsarClose` | ✅ (reused) |
Live-validated against Windows Server 2025 DC (`testlab.local`, stand-alone,
0 configured trusts) — full stack `SmbClient → login → tree_connect(IPC$) →
open_pipe(lsarpc) → bind(LSA UUID) → LsarOpenPolicy2 → LsarEnumerateTrustedDomains`
completes with no RPC fault; decoder returns the empty page cleanly.
Multi-entry deferred-data ordering is covered by synthetic-fixture unit tests.
## Example
```rust,no_run
use ms_lsad::LsadClient;
use smb2_client::SmbClient;
#[tokio::main(flavor = "current_thread")]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let mut smb = SmbClient::connect("dc01.testlab.local").await?;
smb.login("dc01.testlab.local", "testlab.local", "labuser", "pass").await?;
smb.tree_connect("\\\\dc01.testlab.local\\IPC$").await?;
let pipe = smb.open_pipe("lsarpc").await?;
let mut client = LsadClient::bind(&mut smb, pipe).await?;
for t in client.enumerate_trusts("").await? {
println!("{} {}", t.sid, t.name);
}
Ok(())
}
```
Runnable variant: `cargo run --example enum_trusts -- <host> <domain> <user> <password>`.
## Roadmap
- **v0.2** — `LsarEnumerateTrustedDomainsEx` (opnum 50) for richer TDO info;
`LsarQueryTrustedDomainInfoByName` (opnum 48) for trust-key read.
- **v0.3** — `LsarOpenSecret` + `LsarRetrievePrivateData` (opnums 28 + 43) for
domain DPAPI backup key extraction (`G$BCKUPKEY_*` secret path).
## Composes with
- [`dcerpc`](https://crates.io/crates/dcerpc) — sealed LSARPC transport
- [`ms-lsat`](https://crates.io/crates/ms-lsat) — shares the LSA policy handle
- [`ms-drsr`](https://crates.io/crates/ms-drsr) — alternative trust-key path via
DRS bulk `GetNCChanges` replication
## License
MIT.
[MS-LSAD]: https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-lsad/