339 lines
11 KiB
Rust
339 lines
11 KiB
Rust
//! SMB Server Configuration Templates
|
|
//! Provides preset configurations for common deployment scenarios
|
|
|
|
use std::path::PathBuf;
|
|
|
|
/// SMB Server Configuration
|
|
#[derive(Clone, Debug)]
|
|
pub struct SmbConfig {
|
|
pub port: u16,
|
|
pub root: PathBuf,
|
|
pub share_name: String,
|
|
pub read_only: bool,
|
|
pub users: Vec<(String, String)>,
|
|
pub backend: SmbBackend,
|
|
pub ldap: Option<LdapConfig>,
|
|
pub cache: CacheConfig,
|
|
pub encryption: EncryptionConfig,
|
|
}
|
|
|
|
#[derive(Clone, Debug)]
|
|
pub enum SmbBackend {
|
|
LocalFs,
|
|
S3 {
|
|
endpoint: String,
|
|
bucket: String,
|
|
access_key: String,
|
|
secret_key: String,
|
|
region: String,
|
|
},
|
|
}
|
|
|
|
#[derive(Clone, Debug)]
|
|
pub struct LdapConfig {
|
|
pub url: String,
|
|
pub base_dn: String,
|
|
pub bind_dn: String,
|
|
pub bind_password: String,
|
|
pub user_search_base: String,
|
|
pub group_search_base: String,
|
|
pub user_id_attr: String,
|
|
pub user_filter: String,
|
|
pub group_filter: String,
|
|
pub home_dir_attr: String,
|
|
pub home_dir_prefix: String,
|
|
pub user_groups_attr: String,
|
|
}
|
|
|
|
#[derive(Clone, Debug)]
|
|
pub struct CacheConfig {
|
|
pub read_cache_size_mb: usize,
|
|
pub write_cache_size_mb: usize,
|
|
pub cache_ttl_secs: u64,
|
|
}
|
|
|
|
#[derive(Clone, Debug)]
|
|
pub enum EncryptionConfig {
|
|
Disabled,
|
|
Aes128Ctr,
|
|
Aes256Gcm,
|
|
}
|
|
|
|
impl Default for SmbConfig {
|
|
fn default() -> Self {
|
|
Self {
|
|
port: 4445,
|
|
root: PathBuf::from("/data/smb"),
|
|
share_name: "share".to_string(),
|
|
read_only: false,
|
|
users: vec![("demo".to_string(), "demo123".to_string())],
|
|
backend: SmbBackend::LocalFs,
|
|
ldap: None,
|
|
cache: CacheConfig::default(),
|
|
encryption: EncryptionConfig::Aes128Ctr,
|
|
}
|
|
}
|
|
}
|
|
|
|
impl Default for LdapConfig {
|
|
fn default() -> Self {
|
|
Self {
|
|
url: "ldap://localhost:389".to_string(),
|
|
base_dn: "dc=example,dc=com".to_string(),
|
|
bind_dn: "cn=admin,dc=example,dc=com".to_string(),
|
|
bind_password: "".to_string(),
|
|
user_search_base: "ou=users,dc=example,dc=com".to_string(),
|
|
group_search_base: "ou=groups,dc=example,dc=com".to_string(),
|
|
user_id_attr: "uid".to_string(),
|
|
user_filter: "(objectClass=person)".to_string(),
|
|
group_filter: "(objectClass=group)".to_string(),
|
|
home_dir_attr: "homeDirectory".to_string(),
|
|
home_dir_prefix: "/home".to_string(),
|
|
user_groups_attr: "memberOf".to_string(),
|
|
}
|
|
}
|
|
}
|
|
|
|
impl Default for CacheConfig {
|
|
fn default() -> Self {
|
|
Self {
|
|
read_cache_size_mb: 64,
|
|
write_cache_size_mb: 32,
|
|
cache_ttl_secs: 300,
|
|
}
|
|
}
|
|
}
|
|
|
|
impl SmbConfig {
|
|
/// Generate TOML configuration template
|
|
pub fn generate_template() -> String {
|
|
let config = Self::default();
|
|
|
|
format!(
|
|
"# === SMB Server Configuration ===
|
|
# MarkBase SMB2/3 File Server
|
|
|
|
[smb]
|
|
# === Network Settings ===
|
|
port = {} # SMB server port (default: 4445)
|
|
share_name = \"{}\" # Share name visible to clients
|
|
read_only = {} # Read-only mode (default: false)
|
|
|
|
# === Storage Backend ===
|
|
# Options: localfs, s3
|
|
backend = \"localfs\" # Default: local filesystem
|
|
root = \"{}\" # Local filesystem root path
|
|
|
|
# === User Authentication ===
|
|
# Format: [[smb.users]]
|
|
# name = \"username\"
|
|
# password = \"password\" (bcrypt hashed in production)
|
|
|
|
[[smb.users]]
|
|
name = \"{}\"
|
|
password = \"{}\" # ⚠️ Use bcrypt hash in production
|
|
|
|
# === LDAP Integration (Optional) ===
|
|
# Uncomment to enable LDAP authentication
|
|
# [smb.ldap]
|
|
# url = \"ldap://localhost:389\" # LDAP server URL
|
|
# base_dn = \"dc=example,dc=com\" # Base DN
|
|
# bind_dn = \"cn=admin,dc=example,dc=com\" # Bind DN for search
|
|
# bind_password = \"admin_password\" # Bind password
|
|
# user_search_base = \"ou=users,dc=example,dc=com\"
|
|
# group_search_base = \"ou=groups,dc=example,dc=com\"
|
|
# user_id_attr = \"uid\" # User ID attribute
|
|
# user_filter = \"(objectClass=person)\" # User object filter
|
|
# group_filter = \"(objectClass=group)\" # Group object filter
|
|
# home_dir_attr = \"homeDirectory\" # Home directory attribute
|
|
# home_dir_prefix = \"/home\" # Home directory prefix
|
|
# user_groups_attr = \"memberOf\" # Group membership attribute
|
|
|
|
# === Performance Settings ===
|
|
[smb.cache]
|
|
read_cache_size_mb = {} # Read cache size (default: 64MB)
|
|
write_cache_size_mb = {} # Write cache size (default: 32MB)
|
|
cache_ttl_secs = {} # Cache TTL (default: 300s)
|
|
|
|
# === Security Settings ===
|
|
[smb.encryption]
|
|
# Options: disabled, aes128-ctr, aes256-gcm
|
|
mode = \"aes128-ctr\" # SMB3 encryption mode (default: AES-128-CTR)
|
|
|
|
# === S3 Backend (Optional) ===
|
|
# Uncomment to use S3 backend instead of local filesystem
|
|
# [smb.s3]
|
|
# endpoint = \"https://s3.amazonaws.com\"
|
|
# bucket = \"my-bucket\"
|
|
# access_key = \"AKIAIOSFODNN7EXAMPLE\"
|
|
# secret_key = \"wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY\"
|
|
# region = \"us-east-1\"
|
|
",
|
|
config.port,
|
|
config.share_name,
|
|
config.read_only,
|
|
config.root.display(),
|
|
config.users[0].0,
|
|
config.users[0].1,
|
|
config.cache.read_cache_size_mb,
|
|
config.cache.write_cache_size_mb,
|
|
config.cache.cache_ttl_secs,
|
|
)
|
|
}
|
|
|
|
/// Preset: Local File Server (simple deployment)
|
|
pub fn preset_local_file_server() -> Self {
|
|
Self {
|
|
port: 4445,
|
|
root: PathBuf::from("/data/smb"),
|
|
share_name: "files".to_string(),
|
|
read_only: false,
|
|
users: vec![
|
|
("alice".to_string(), "alice123".to_string()),
|
|
("bob".to_string(), "bob123".to_string()),
|
|
],
|
|
backend: SmbBackend::LocalFs,
|
|
ldap: None,
|
|
cache: CacheConfig {
|
|
read_cache_size_mb: 64,
|
|
write_cache_size_mb: 32,
|
|
cache_ttl_secs: 300,
|
|
},
|
|
encryption: EncryptionConfig::Aes128Ctr,
|
|
}
|
|
}
|
|
|
|
/// Preset: S3 Backend (cloud storage)
|
|
pub fn preset_s3_backend() -> Self {
|
|
Self {
|
|
port: 4445,
|
|
root: PathBuf::from("demo/"),
|
|
share_name: "s3share".to_string(),
|
|
read_only: false,
|
|
users: vec![("demo".to_string(), "demo123".to_string())],
|
|
backend: SmbBackend::S3 {
|
|
endpoint: "https://s3.amazonaws.com".to_string(),
|
|
bucket: "my-bucket".to_string(),
|
|
access_key: "AKIAIOSFODNN7EXAMPLE".to_string(),
|
|
secret_key: "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY".to_string(),
|
|
region: "us-east-1".to_string(),
|
|
},
|
|
ldap: None,
|
|
cache: CacheConfig {
|
|
read_cache_size_mb: 128,
|
|
write_cache_size_mb: 64,
|
|
cache_ttl_secs: 600,
|
|
},
|
|
encryption: EncryptionConfig::Aes256Gcm,
|
|
}
|
|
}
|
|
|
|
/// Preset: LDAP Enterprise (Active Directory integration)
|
|
pub fn preset_ldap_enterprise() -> Self {
|
|
Self {
|
|
port: 4445,
|
|
root: PathBuf::from("/data/smb"),
|
|
share_name: "enterprise".to_string(),
|
|
read_only: false,
|
|
users: vec![], // LDAP handles authentication
|
|
backend: SmbBackend::LocalFs,
|
|
ldap: Some(LdapConfig {
|
|
url: "ldap://ad.example.com:389".to_string(),
|
|
base_dn: "dc=example,dc=com".to_string(),
|
|
bind_dn: "cn=admin,cn=users,dc=example,dc=com".to_string(),
|
|
bind_password: "admin_password".to_string(),
|
|
user_search_base: "cn=users,dc=example,dc=com".to_string(),
|
|
group_search_base: "cn=groups,dc=example,dc=com".to_string(),
|
|
user_id_attr: "sAMAccountName".to_string(),
|
|
user_filter: "(objectClass=user)".to_string(),
|
|
group_filter: "(objectClass=group)".to_string(),
|
|
home_dir_attr: "homeDirectory".to_string(),
|
|
home_dir_prefix: "/home".to_string(),
|
|
user_groups_attr: "memberOf".to_string(),
|
|
}),
|
|
cache: CacheConfig {
|
|
read_cache_size_mb: 128,
|
|
write_cache_size_mb: 64,
|
|
cache_ttl_secs: 300,
|
|
},
|
|
encryption: EncryptionConfig::Aes256Gcm,
|
|
}
|
|
}
|
|
|
|
/// Preset: Read-Only Archive (public documents)
|
|
pub fn preset_read_only_archive() -> Self {
|
|
Self {
|
|
port: 4445,
|
|
root: PathBuf::from("/data/archive"),
|
|
share_name: "archive".to_string(),
|
|
read_only: true,
|
|
users: vec![("public".to_string(), "".to_string())],
|
|
backend: SmbBackend::LocalFs,
|
|
ldap: None,
|
|
cache: CacheConfig {
|
|
read_cache_size_mb: 256,
|
|
write_cache_size_mb: 0,
|
|
cache_ttl_secs: 3600,
|
|
},
|
|
encryption: EncryptionConfig::Disabled,
|
|
}
|
|
}
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod tests {
|
|
use super::*;
|
|
|
|
#[test]
|
|
fn test_default_config() {
|
|
let config = SmbConfig::default();
|
|
assert_eq!(config.port, 4445);
|
|
assert_eq!(config.share_name, "share");
|
|
assert!(!config.read_only);
|
|
assert_eq!(config.users.len(), 1);
|
|
}
|
|
|
|
#[test]
|
|
fn test_generate_template() {
|
|
let template = SmbConfig::generate_template();
|
|
assert!(template.contains("port = 4445"));
|
|
assert!(template.contains("share_name = \"share\""));
|
|
assert!(template.contains("backend = \"localfs\""));
|
|
assert!(template.contains("[smb.users]"));
|
|
assert!(template.contains("[smb.cache]"));
|
|
assert!(template.contains("[smb.encryption]"));
|
|
}
|
|
|
|
#[test]
|
|
fn test_preset_local_file_server() {
|
|
let config = SmbConfig::preset_local_file_server();
|
|
assert_eq!(config.port, 4445);
|
|
assert_eq!(config.share_name, "files");
|
|
assert_eq!(config.users.len(), 2);
|
|
assert!(config.ldap.is_none());
|
|
}
|
|
|
|
#[test]
|
|
fn test_preset_s3_backend() {
|
|
let config = SmbConfig::preset_s3_backend();
|
|
assert_eq!(config.share_name, "s3share");
|
|
assert!(matches!(config.backend, SmbBackend::S3 { .. }));
|
|
assert!(matches!(config.encryption, EncryptionConfig::Aes256Gcm));
|
|
}
|
|
|
|
#[test]
|
|
fn test_preset_ldap_enterprise() {
|
|
let config = SmbConfig::preset_ldap_enterprise();
|
|
assert_eq!(config.share_name, "enterprise");
|
|
assert!(config.ldap.is_some());
|
|
assert_eq!(config.users.len(), 0);
|
|
}
|
|
|
|
#[test]
|
|
fn test_preset_read_only_archive() {
|
|
let config = SmbConfig::preset_read_only_archive();
|
|
assert!(config.read_only);
|
|
assert_eq!(config.share_name, "archive");
|
|
assert!(matches!(config.encryption, EncryptionConfig::Disabled));
|
|
}
|
|
} |