Skip to main content

smb2_client/
lib.rs

1//! A minimal SMB2 client — from-scratch pure Rust, scoped to what
2//! named-pipe DCE/RPC needs: negotiate (dialect 2.1.0), NTLM session setup, tree-connect to
3//! IPC$, create a pipe, and FSCTL_PIPE_TRANSCEIVE to carry RPC PDUs.
4//!
5//! Raw NTLMSSP is placed directly in the session-setup security buffer (Windows accepts it
6//! without a SPNEGO wrapper). SMB 2.x message signing (HMAC-SHA256, truncated to 16 bytes)
7//! is applied once a session key is established, since DCs require signing on IPC$.
8
9pub mod client;
10pub mod header;
11pub mod msg;
12pub mod server;
13pub mod socks;
14pub mod spnego;
15pub mod transport;
16
17pub use client::{Cred, SmbClient};
18pub use msg::DirEntry;
19
20#[derive(Debug, thiserror::Error)]
21pub enum SmbError {
22    #[error("truncated SMB2 message")]
23    Truncated,
24    #[error("bad protocol id")]
25    BadProtocol,
26    #[error("SMB2 status {0:#010x} for command {1:#06x}")]
27    Status(u32, u16),
28    #[error("unexpected security token")]
29    BadToken,
30    #[error("ntlm: {0}")]
31    Ntlm(String),
32    #[error(transparent)]
33    Io(#[from] std::io::Error),
34}
35
36pub type Result<T> = std::result::Result<T, SmbError>;
37
38/// SMB2 status codes we branch on.
39pub mod status {
40    pub const SUCCESS: u32 = 0x0000_0000;
41    pub const PENDING: u32 = 0x0000_0103; // interim async response; the real one follows
42    pub const MORE_PROCESSING_REQUIRED: u32 = 0xC000_0016;
43    pub const END_OF_FILE: u32 = 0xC000_0011;
44    pub const OBJECT_NAME_NOT_FOUND: u32 = 0xC000_0034;
45    pub const SHARING_VIOLATION: u32 = 0xC000_0043;
46    /// STATUS_NO_MORE_FILES — QUERY_DIRECTORY has returned the last entry.
47    pub const NO_MORE_FILES: u32 = 0x8000_0006;
48}