ldap

package module
v1.6.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 6, 2025 License: MIT Imports: 29 Imported by: 0

README

Simple LDAP Go

Go Reference Go Report Card CI Status Go Version Latest Release Renovate enabled Maintenance PRs Welcome

A simple Go library providing an easy-to-use wrapper around go-ldap/ldap/v3 for common LDAP and Active Directory operations.

This package was extracted from netresearch/raybeam to provide a standalone, reusable LDAP client library.

Why Use Simple LDAP Go?

Working with go-ldap/ldap/v3 directly can be challenging for common LDAP operations. This library solves the pain points you'll encounter:

Problems with Raw go-ldap

Complex Connection Management - Manual connection pooling, health checks, and retry logic ❌ Manual DN Construction - Error-prone string building with security risks (DN injection) ❌ No Caching - Repeated LDAP queries for the same data slow down applications ❌ Verbose Error Handling - Generic LDAP errors without context or specific types ❌ AD vs OpenLDAP Differences - Different APIs and attributes require separate code paths ❌ Security Pitfalls - Easy to introduce vulnerabilities without proper input validation ❌ Boilerplate Code - Simple operations require dozens of lines of setup and teardown

How Simple LDAP Go Solves These

Automatic Connection Pooling - Built-in connection management with health checks and auto-retry ✅ Safe DN Handling - Automatic escaping and validation prevents injection attacks ✅ Built-in Caching - Intelligent caching layer reduces LDAP server load ✅ Comprehensive Error Types - Specific errors like ErrUserNotFound with detailed context ✅ Unified API - Same methods work seamlessly with Active Directory and OpenLDAP ✅ Security by Default - Input validation, proper escaping, and secure connection handling ✅ Simple API - Common operations in just a few lines of code

Code Comparison

Raw go-ldap: Finding and authenticating a user (50+ lines)

import "github.com/go-ldap/ldap/v3"

// Connect and bind
conn, err := ldap.DialURL("ldaps://ldap.example.com:636")
if err != nil {
    return err
}
defer conn.Close()

err = conn.Bind("cn=admin,dc=example,dc=com", "password")
if err != nil {
    return err
}

// Search for user (manual filter construction)
searchReq := ldap.NewSearchRequest(
    "dc=example,dc=com",
    ldap.ScopeWholeSubtree,
    ldap.NeverDerefAliases,
    0, 0, false,
    fmt.Sprintf("(&(objectClass=user)(sAMAccountName=%s))",
        ldap.EscapeFilter(username)), // Manual escaping required
    []string{"dn", "cn", "mail"},
    nil,
)

sr, err := conn.Search(searchReq)
if err != nil {
    return err
}
if len(sr.Entries) == 0 {
    return errors.New("user not found") // Generic error
}

userDN := sr.Entries[0].DN

// Authenticate user (separate bind operation)
err = conn.Bind(userDN, password)
if err != nil {
    return err
}
// ... additional validation and error handling

Simple LDAP Go: Same operation (3 lines)

import ldap "github.com/netresearch/simple-ldap-go"

client, _ := ldap.New(config, "cn=admin,dc=example,dc=com", "password")
user, err := client.CheckPasswordForSAMAccountName("username", "password")
// Returns structured User object with automatic error handling

Features

  • 🔐 User Authentication - One-line password verification with automatic DN resolution and secure binding
  • 👥 User Management - Type-safe user operations with automatic attribute mapping and validation
  • 🏢 Group Operations - Simplified group queries and membership management across AD and OpenLDAP
  • 💻 Computer Management - Active Directory computer object support with automatic schema detection
  • 🔑 Password Management - Secure password changes and admin resets with automatic LDAPS enforcement and policy validation
  • 🛡️ Active Directory Support - Native AD features like SAMAccountName, UPN, and nested group resolution
  • Connection Pooling - Automatic connection management with health checks, retry logic, and resource cleanup
  • 🎯 Smart Caching - Configurable caching layer that reduces server load for repeated queries
  • 🔒 Security by Default - Built-in DN injection protection, input validation, and secure connection handling
  • 📊 Structured Errors - Context-rich error types that make debugging and error handling straightforward
  • 🌐 Context Support - Full context.Context integration for timeouts, cancellation, and request tracing
  • 📝 Structured Logging - Integrated slog support for comprehensive operational visibility

Installation

go get github.com/netresearch/simple-ldap-go

Quick Start

package main

import (
    "fmt"
    "log"
    
    ldap "github.com/netresearch/simple-ldap-go"
)

func main() {
    // Configure LDAP connection
    config := ldap.Config{
        Server:            "ldaps://ldap.example.com:636",
        BaseDN:            "dc=example,dc=com",
        IsActiveDirectory: true, // Set to false for generic LDAP
    }

    // Create client with service account credentials
    client, err := ldap.New(config, "cn=admin,dc=example,dc=com", "password")
    if err != nil {
        log.Fatal(err)
    }

    // Authenticate a user
    user, err := client.CheckPasswordForSAMAccountName("username", "password")
    if err != nil {
        log.Printf("Authentication failed: %v", err)
        return
    }
    
    fmt.Printf("Welcome, %s!\n", user.CN())
}

Examples

Comprehensive examples are available in the examples directory:

API Reference

Core Types
  • Config - LDAP server configuration
  • LDAP - Main client for LDAP operations
  • User - Represents an LDAP user with common attributes
  • Group - Represents an LDAP group with member information
  • Computer - Represents a computer object (Active Directory)
Key Operations
// Basic client creation
client, err := ldap.New(config, username, password)

// Enhanced client with connection pooling and caching
client, err := ldap.NewHighPerformanceClient(config, username, password)
// Or with custom configuration:
client, err := ldap.NewCachedClient(config, username, password, 1000, 5*time.Minute)

// Convenience constructors
client, err := ldap.NewHighPerformanceClient(config, username, password)
client, err := ldap.NewCachedClient(config, username, password, 1000, 5*time.Minute)

// User authentication
user, err := client.CheckPasswordForSAMAccountName("jdoe", "password")

// Find users (standard methods)
user, err := client.FindUserBySAMAccountName("jdoe")
users, err := client.FindUsers()

// Find users (caching is transparent if enabled in config)
user, err := client.FindUserBySAMAccountNameContext(ctx, "jdoe")
// Caching happens automatically if config.EnableCache is true

// User management
err := client.CreateUser(fullUser, "ou=Users,dc=example,dc=com")
err := client.DeleteUser("cn=John Doe,ou=Users,dc=example,dc=com")

// Group operations (caching is transparent if enabled)
group, err := client.FindGroupByDNContext(ctx, "cn=Admins,dc=example,dc=com")
// Caching happens automatically if config.EnableCache is true
err := client.AddUserToGroup(userDN, groupDN)

// Password management
err := client.ChangePasswordForSAMAccountName("jdoe", "oldPass", "newPass")
err := client.ResetPasswordForSAMAccountName("jdoe", "newPass") // Admin reset

See the Go Reference for complete API documentation.

Configuration

Basic Configuration
Generic LDAP Server
config := ldap.Config{
    Server:            "ldap://ldap.example.com:389",
    BaseDN:            "dc=example,dc=com",
    IsActiveDirectory: false,
}
Microsoft Active Directory
config := ldap.Config{
    Server:            "ldaps://ad.example.com:636", // LDAPS recommended
    BaseDN:            "dc=example,dc=com",
    IsActiveDirectory: true, // Enables AD-specific features
}
Performance Configuration

Enable optimization features using configuration flags:

config := ldap.Config{
    Server:               "ldaps://ad.example.com:636",
    BaseDN:               "dc=example,dc=com",
    IsActiveDirectory:    true,

    // Performance optimizations
    EnableOptimizations:  true, // Enable all optimizations
    EnableCache:         true,  // Enable caching separately
    EnableMetrics:       true,  // Enable performance metrics
    EnableBulkOps:       true,  // Enable bulk operations
}

Or configure specific features:

// High-performance client with all optimizations
client, err := ldap.NewHighPerformanceClient(config, username, password)

// Custom configuration with specific features
// Use config flags to enable features:
config.EnableOptimizations = true  // Enable all optimizations
config.EnableCache = true         // Enable caching
config.EnableMetrics = true       // Enable metrics
config.EnableBulkOps = true       // Enable bulk operations

// Then create client with convenience constructors:
client, err := ldap.NewHighPerformanceClient(config, username, password)
// Or:
client, err := ldap.NewCachedClient(config, username, password, 1000, 5*time.Minute)
// Or:
client, err := ldap.NewPooledClient(config, username, password, 20)

Security Best Practices

  • Use LDAPS (TLS encryption) in production environments
  • Use service accounts with minimal required permissions
  • Store credentials securely using environment variables or key management
  • Validate certificates in production deployments
  • ⚠️ Password changes require LDAPS when using Active Directory

Error Handling

The library provides specific error types for common scenarios:

// Check for specific errors
_, err := client.FindUserBySAMAccountName("username")
if err == ldap.ErrUserNotFound {
    // Handle user not found
} else if err != nil {
    // Handle other errors
}

Available error types:

  • ErrUserNotFound - User lookup failed
  • ErrGroupNotFound - Group lookup failed
  • ErrComputerNotFound - Computer lookup failed
  • ErrSAMAccountNameDuplicated - Account name already exists
  • ErrMailDuplicated - Email address already exists
  • ErrActiveDirectoryMustBeLDAPS - LDAPS required for AD operations

Requirements

  • Go 1.23.0 or later
  • Access to an LDAP server (OpenLDAP, Active Directory, etc.)
  • Appropriate credentials and permissions for desired operations

Testing

Tests require a live LDAP server. Set the following environment variables:

export LDAP_SERVER="ldaps://your-server:636"
export LDAP_BASE_DN="dc=example,dc=com" 
export LDAP_READ_USER="cn=service,dc=example,dc=com"
export LDAP_READ_PASSWORD="password"

Then run tests:

go test -v ./...

License

This package is licensed under the MIT License. See the included LICENSE file for details.

Contributing

Contributions are welcome! Please:

  1. Fork the repository
  2. Create a feature branch
  3. Follow Conventional Commits for commit messages
  4. Use gofmt for code formatting
  5. Add tests for new functionality
  6. Submit a pull request

Documentation

Overview

Package ldap provides builder patterns for complex object creation.

Package ldap provides modern concurrency patterns for LDAP operations.

Package ldap provides a simple wrapper around go-ldap/ldap for common LDAP and Active Directory operations.

This package simplifies common LDAP operations including:

  • User authentication and password management
  • User, group, and computer object queries
  • User creation and deletion
  • Group membership management

The package is designed to work with both generic LDAP servers and Microsoft Active Directory, with special handling for AD-specific features like password changes and user account control flags.

Basic Usage

config := ldap.Config{
	Server:            "ldaps://ldap.example.com:636",
	BaseDN:            "dc=example,dc=com",
	IsActiveDirectory: true,
}

client, err := ldap.New(config, "cn=admin,dc=example,dc=com", "password")
if err != nil {
	log.Fatal(err)
}

// Authenticate a user
user, err := client.CheckPasswordForSAMAccountName("username", "password")
if err != nil {
	log.Printf("Authentication failed: %v", err)
	return
}
fmt.Printf("Authenticated user: %s\n", user.CN())

// Find users
users, err := client.FindUsers()
if err != nil {
	log.Printf("Failed to find users: %v", err)
	return
}
for _, u := range users {
	fmt.Printf("User: %s (%s)\n", u.CN(), u.SAMAccountName)
}

Active Directory Considerations

When working with Active Directory, set IsActiveDirectory to true in the Config. This enables AD-specific features:

  • Password changes require LDAPS connection
  • Proper handling of User Account Control flags
  • Support for AD-specific attributes

Error Handling

The package defines specific error variables for common scenarios:

  • ErrUserNotFound: User lookup failed
  • ErrGroupNotFound: Group lookup failed
  • ErrComputerNotFound: Computer lookup failed
  • ErrDNDuplicated: Distinguished name is not unique
  • ErrSAMAccountNameDuplicated: SAM account name already exists
  • ErrMailDuplicated: Email address already exists
  • ErrActiveDirectoryMustBeLDAPS: LDAPS required for AD password operations

Always check for these specific errors when appropriate to provide better error handling in your applications.

Package ldap provides interface segregation for better testability and modularity.

Package ldap provides modern Go patterns for LDAP configuration and initialization.

Example (BackwardCompatibility)

Example_backwardCompatibility shows that existing code works unchanged when pooling is not configured

package main

import (
	"context"
	"fmt"
	"log"

	ldap "github.com/netresearch/simple-ldap-go"
)

func main() {
	// Existing code without pool configuration continues to work
	config := ldap.Config{
		Server: "ldap://localhost:389",
		BaseDN: "dc=example,dc=org",
		// Pool: nil - no pooling, legacy behavior
	}

	client, err := ldap.New(config, "cn=admin,dc=example,dc=org", "password")
	if err != nil {
		log.Fatal(err)
	}
	defer func() { _ = client.Close() }()

	// All existing operations work exactly as before
	ctx := context.Background()
	users, err := client.FindUsersContext(ctx)
	if err != nil {
		log.Printf("Error: %v", err)
		return
	}

	fmt.Printf("Found %d users using direct connections\n", len(users))

	// Pool stats will show no activity when pooling is disabled
	stats := client.GetPoolStats()
	if stats.PoolHits == 0 && stats.PoolMisses == 0 {
		fmt.Println("No connection pooling configured - using direct connections")
	}

}
Output:

Found 150 users using direct connections
No connection pooling configured - using direct connections
Example (ConcurrentOperations)

Example_concurrentOperations shows how connection pooling improves performance under high concurrency

package main

import (
	"context"
	"fmt"
	"log"
	"sync"
	"time"

	ldap "github.com/netresearch/simple-ldap-go"
)

func main() {
	config := ldap.Config{
		Server: "ldap://localhost:389",
		BaseDN: "dc=example,dc=org",
		Pool: &ldap.PoolConfig{
			MaxConnections: 15,
			MinConnections: 3,
		},
	}

	client, err := ldap.New(config, "cn=admin,dc=example,dc=org", "password")
	if err != nil {
		log.Fatal(err)
	}
	defer func() { _ = client.Close() }()

	// Simulate high-concurrency scenario
	const numWorkers = 20
	const operationsPerWorker = 10

	var wg sync.WaitGroup
	start := time.Now()

	for i := 0; i < numWorkers; i++ {
		wg.Add(1)
		go func(workerID int) {
			defer wg.Done()

			ctx := context.Background()
			for j := 0; j < operationsPerWorker; j++ {
				// Each operation will reuse connections from the pool
				users, err := client.FindUsersContext(ctx)
				if err != nil {
					log.Printf("Worker %d error: %v", workerID, err)
					continue
				}
				log.Printf("Worker %d found %d users (operation %d)", workerID, len(users), j+1)
			}
		}(i)
	}

	wg.Wait()
	duration := time.Since(start)

	// Display performance results
	fmt.Printf("Completed %d operations in %v\n", numWorkers*operationsPerWorker, duration)

	stats := client.GetPoolStats()
	fmt.Printf("Final pool stats:\n")
	fmt.Printf("  Total connections created: %d\n", stats.ConnectionsCreated)
	fmt.Printf("  Peak connections: %d\n", stats.TotalConnections)
	fmt.Printf("  Pool hits: %d, misses: %d\n", stats.PoolHits, stats.PoolMisses)

	if stats.PoolHits+stats.PoolMisses > 0 {
		hitRatio := float64(stats.PoolHits) / float64(stats.PoolHits+stats.PoolMisses) * 100
		fmt.Printf("  Hit ratio: %.1f%%\n", hitRatio)
	}

	// Calculate efficiency metrics
	totalOps := int64(numWorkers * operationsPerWorker)
	connectionsPerOp := float64(stats.ConnectionsCreated) / float64(totalOps)
	fmt.Printf("  Efficiency: %.3f connections per operation\n", connectionsPerOp)
	fmt.Printf("  Operations per second: %.1f\n", float64(totalOps)/duration.Seconds())

	// Expected output (performance will vary):
	// Completed 200 operations in 2.5s
	// Final pool stats:
	//   Total connections created: 15
	//   Peak connections: 15
	//   Pool hits: 185, misses: 15
	//   Hit ratio: 92.5%
	//   Efficiency: 0.075 connections per operation
	//   Operations per second: 80.0
}
Example (ConnectionPooling)

Example_connectionPooling demonstrates how to use connection pooling for high-performance LDAP operations

package main

import (
	"context"
	"fmt"
	"log"
	"log/slog"
	"os"
	"time"

	ldap "github.com/netresearch/simple-ldap-go"
)

func main() {
	// Configure connection pooling for high-volume scenarios
	config := ldap.Config{
		Server:            "ldaps://ad.example.com:636",
		BaseDN:            "DC=example,DC=com",
		IsActiveDirectory: true,
		Pool: &ldap.PoolConfig{
			MaxConnections:      20,               // Maximum concurrent connections
			MinConnections:      5,                // Keep 5 connections ready
			MaxIdleTime:         10 * time.Minute, // Close idle connections after 10min
			HealthCheckInterval: 30 * time.Second, // Check connection health every 30s
			ConnectionTimeout:   10 * time.Second, // Timeout for new connections
			GetTimeout:          5 * time.Second,  // Timeout for getting from pool
		},
		Logger: slog.New(slog.NewJSONHandler(os.Stdout, &slog.HandlerOptions{
			Level: slog.LevelInfo,
		})),
	}

	// Create client with connection pooling
	client, err := ldap.New(config, "CN=admin,CN=Users,DC=example,DC=com", "password")
	if err != nil {
		log.Fatal(err)
	}
	defer func() { _ = client.Close() }() // Important: Close to cleanup all pooled connections

	// Perform operations - connections will be reused from the pool
	ctx := context.Background()

	// Single operation
	users, err := client.FindUsersContext(ctx)
	if err != nil {
		log.Printf("Error finding users: %v", err)
		return
	}
	fmt.Printf("Found %d users\n", len(users))

	// Check pool statistics
	stats := client.GetPoolStats()
	fmt.Printf("Pool stats: %d active, %d idle, %d total connections\n",
		stats.ActiveConnections, stats.IdleConnections, stats.TotalConnections)
	fmt.Printf("Pool efficiency: %d hits, %d misses (%.1f%% hit ratio)\n",
		stats.PoolHits, stats.PoolMisses,
		float64(stats.PoolHits)/float64(stats.PoolHits+stats.PoolMisses)*100)

}
Output:

Found 150 users
Pool stats: 0 active, 5 idle, 5 total connections
Pool efficiency: 1 hits, 1 misses (50.0% hit ratio)
Example (PoolConfiguration)

Example_poolConfiguration demonstrates various pool configuration options

package main

import (
	"fmt"
	"log/slog"
	"os"
	"time"

	ldap "github.com/netresearch/simple-ldap-go"
)

func main() {
	// Minimal pool configuration (uses defaults for unspecified values)
	minimalConfig := ldap.Config{
		Server: "ldap://localhost:389",
		BaseDN: "dc=example,dc=org",
		Pool: &ldap.PoolConfig{
			MaxConnections: 15, // Only specify what you need to change
			// Other values will use defaults
		},
	}

	// Full pool configuration for fine-tuning
	fullConfig := ldap.Config{
		Server:            "ldaps://ad.enterprise.com:636",
		BaseDN:            "DC=enterprise,DC=com",
		IsActiveDirectory: true,
		Pool: &ldap.PoolConfig{
			MaxConnections:      50,               // High concurrency support
			MinConnections:      10,               // Keep 10 connections warm
			MaxIdleTime:         15 * time.Minute, // Allow longer idle time
			HealthCheckInterval: 45 * time.Second, // Less frequent health checks
			ConnectionTimeout:   20 * time.Second, // Longer connection timeout
			GetTimeout:          8 * time.Second,  // Generous pool timeout
		},
		Logger: slog.New(slog.NewJSONHandler(os.Stdout, &slog.HandlerOptions{
			Level: slog.LevelInfo,
		})),
	}

	// High-performance configuration for maximum throughput
	highPerfConfig := ldap.Config{
		Server: "ldap://fast-server:389",
		BaseDN: "dc=fast,dc=org",
		Pool: &ldap.PoolConfig{
			MaxConnections:      100,              // Support very high concurrency
			MinConnections:      20,               // Many warm connections
			MaxIdleTime:         30 * time.Minute, // Keep connections longer
			HealthCheckInterval: 60 * time.Second, // Minimal health check overhead
			ConnectionTimeout:   5 * time.Second,  // Fast connection creation
			GetTimeout:          2 * time.Second,  // Fast pool access
		},
	}

	// Conservative configuration for resource-constrained environments
	conservativeConfig := ldap.Config{
		Server: "ldap://limited-server:389",
		BaseDN: "dc=limited,dc=org",
		Pool: &ldap.PoolConfig{
			MaxConnections:      3,                // Minimal resource usage
			MinConnections:      1,                // Just one warm connection
			MaxIdleTime:         2 * time.Minute,  // Cleanup idle connections quickly
			HealthCheckInterval: 15 * time.Second, // Frequent health monitoring
			ConnectionTimeout:   30 * time.Second, // Allow time for slow connections
			GetTimeout:          10 * time.Second, // Patient pool access
		},
	}

	configs := map[string]ldap.Config{
		"Minimal":      minimalConfig,
		"Full":         fullConfig,
		"HighPerf":     highPerfConfig,
		"Conservative": conservativeConfig,
	}

	// Iterate in deterministic order for consistent output
	configOrder := []string{"Minimal", "Full", "HighPerf", "Conservative"}
	for _, name := range configOrder {
		config := configs[name]
		fmt.Printf("%s Configuration:\n", name)
		fmt.Printf("  Max Connections: %d\n", config.Pool.MaxConnections)
		fmt.Printf("  Min Connections: %d\n", config.Pool.MinConnections)
		fmt.Printf("  Max Idle Time: %v\n", config.Pool.MaxIdleTime)
		fmt.Printf("  Health Check Interval: %v\n", config.Pool.HealthCheckInterval)
		fmt.Printf("  Connection Timeout: %v\n", config.Pool.ConnectionTimeout)
		fmt.Printf("  Get Timeout: %v\n", config.Pool.GetTimeout)
		fmt.Println()

		// Note: In real usage, you would create and use the client here
		// client, err := ldap.New(config, bindDN, password)
		// if err != nil { ... }
		// defer client.Close()
	}

}
Output:

Minimal Configuration:
  Max Connections: 15
  Min Connections: 0
  Max Idle Time: 0s
  Health Check Interval: 0s
  Connection Timeout: 0s
  Get Timeout: 0s

Full Configuration:
  Max Connections: 50
  Min Connections: 10
  Max Idle Time: 15m0s
  Health Check Interval: 45s
  Connection Timeout: 20s
  Get Timeout: 8s

HighPerf Configuration:
  Max Connections: 100
  Min Connections: 20
  Max Idle Time: 30m0s
  Health Check Interval: 1m0s
  Connection Timeout: 5s
  Get Timeout: 2s

Conservative Configuration:
  Max Connections: 3
  Min Connections: 1
  Max Idle Time: 2m0s
  Health Check Interval: 15s
  Connection Timeout: 30s
  Get Timeout: 10s
Example (PoolMonitoring)

Example_poolMonitoring demonstrates how to monitor pool health and performance

package main

import (
	"context"
	"fmt"
	"log"
	"time"

	ldap "github.com/netresearch/simple-ldap-go"
)

func main() {
	config := ldap.Config{
		Server: "ldap://localhost:389",
		BaseDN: "dc=example,dc=org",
		Pool: &ldap.PoolConfig{
			MaxConnections:      10,
			MinConnections:      2,
			HealthCheckInterval: 5 * time.Second, // Frequent health checks for demo
		},
	}

	client, err := ldap.New(config, "cn=admin,dc=example,dc=org", "password")
	if err != nil {
		log.Fatal(err)
	}
	defer func() { _ = client.Close() }()

	// Monitor pool statistics over time
	ticker := time.NewTicker(2 * time.Second)
	defer ticker.Stop()

	ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second)
	defer cancel()

	fmt.Println("Monitoring pool statistics:")
	fmt.Println("Time\t\tActive\tIdle\tTotal\tHits\tMisses\tHealth(P/F)")

	for {
		select {
		case <-ticker.C:
			stats := client.GetPoolStats()
			fmt.Printf("%s\t%d\t%d\t%d\t%d\t%d\t%d/%d\n",
				time.Now().Format("15:04:05"),
				stats.ActiveConnections,
				stats.IdleConnections,
				stats.TotalConnections,
				stats.PoolHits,
				stats.PoolMisses,
				stats.HealthChecksPassed,
				stats.HealthChecksFailed)

			// Perform some operations to generate activity
			go func() {
				if users, err := client.FindUsersContext(context.Background()); err == nil {
					_ = len(users) // Use result to avoid unused variable
				}
			}()

		case <-ctx.Done():
			fmt.Println("Monitoring complete")
			return
		}
	}

	// Expected output:
	// Monitoring pool statistics:
	// Time		Active	Idle	Total	Hits	Misses	Health(P/F)
	// 14:30:01	0	2	2	0	0	4/0
	// 14:30:03	0	2	2	1	1	8/0
	// 14:30:05	0	2	2	2	1	12/0
	// 14:30:07	0	2	2	3	1	16/0
	// Monitoring complete
}

Index

Examples

Constants

View Source
const (
	// MaxFilterLength defines the maximum length for LDAP filters to prevent DoS attacks
	MaxFilterLength = 10000
	// MaxDNLength defines the maximum length for Distinguished Names
	MaxDNLength = 8000
	// MaxSAMAccountNameLength defines the maximum length for sAMAccountName
	MaxSAMAccountNameLength = 20
)

Security validation constants

View Source
const (
	// MaxValueLength defines the maximum length for attribute values
	MaxValueLength = 8192
)

Constants for validation limits

Variables

View Source
var (
	// ErrCacheDisabled is returned when cache operations are performed on a disabled cache
	ErrCacheDisabled = errors.New("cache is disabled")
	// ErrCacheKeyNotFound is returned when a cache key is not found
	ErrCacheKeyNotFound = errors.New("cache key not found")
	// ErrCacheFull is returned when the cache has reached its maximum size
	ErrCacheFull = errors.New("cache is full")
)
View Source
var (
	// Authentication errors
	ErrInvalidCredentials = errors.New("invalid credentials")
	ErrAccountLocked      = errors.New("account locked")
	ErrAccountDisabled    = errors.New("account disabled")
	ErrPasswordExpired    = errors.New("password expired")

	// Connection errors
	ErrConnectionFailed  = errors.New("connection failed")
	ErrServerUnavailable = errors.New("server unavailable")
	ErrTimeoutExceeded   = errors.New("timeout exceeded")

	// Search/Object errors
	ErrObjectNotFound = errors.New("object not found")

	// Validation errors
	ErrInvalidDN     = errors.New("invalid distinguished name")
	ErrInvalidFilter = errors.New("invalid LDAP filter")

	// Context errors
	ErrContextCancelled        = errors.New("context cancelled")
	ErrContextDeadlineExceeded = errors.New("context deadline exceeded")
)

Standard LDAP errors - these are sentinel errors for error classification

View Source
var (
	// ErrPoolClosed is returned when attempting to use a closed connection pool
	ErrPoolClosed = errors.New("connection pool is closed")
	// ErrPoolExhausted is returned when the pool has reached max connections and timeout is reached
	ErrPoolExhausted = errors.New("connection pool exhausted")
	// ErrConnectionUnhealthy is returned when a connection fails health checks
	ErrConnectionUnhealthy = errors.New("connection is unhealthy")
)
View Source
var (
	// ErrUserNotFound is returned when a user search operation finds no matching entries.
	ErrUserNotFound = errors.New("user not found")
	// ErrSAMAccountNameDuplicated is returned when multiple users have the same sAMAccountName,
	// indicating a data integrity issue in the directory.
	ErrSAMAccountNameDuplicated = errors.New("sAMAccountName is not unique")
	// ErrMailDuplicated is returned when multiple users have the same email address,
	// indicating a data integrity issue in the directory.
	ErrMailDuplicated = errors.New("mail is not unique")
)
View Source
var (

	// ErrActiveDirectoryMustBeLDAPS is returned when attempting to change passwords on Active Directory
	// over an unencrypted connection. Password changes in AD require LDAPS (LDAP over SSL/TLS).
	ErrActiveDirectoryMustBeLDAPS = errors.New("ActiveDirectory servers must be connected to via LDAPS to change passwords")
)
View Source
var ErrComputerNotFound = errors.New("computer not found")

ErrComputerNotFound is returned when a computer search operation finds no matching entries.

View Source
var ErrDNDuplicated = errors.New("DN is not unique")

ErrDNDuplicated is returned when a search operation finds multiple entries with the same DN, indicating a data integrity issue.

View Source
var ErrGroupNotFound = errors.New("group not found")

ErrGroupNotFound is returned when a group search operation finds no matching entries.

Functions

func Create added in v1.1.0

func Create[T LDAPObject](ctx context.Context, l *LDAP, obj T) (string, error)

Create performs a generic create operation for LDAP objects. This function provides type safety for LDAP object creation.

Type parameter T must implement LDAPObject and Creatable constraints.

Parameters:

  • ctx: Context for controlling the create timeout and cancellation
  • l: LDAP client to use for the creation
  • obj: The object to create in LDAP

Returns:

  • string: The distinguished name of the created object
  • error: Any error encountered during the creation operation

Example:

user := &FullUser{
    CN: "John Doe",
    SAMAccountName: "jdoe",
    Mail: stringPtr("john.doe@example.com"),
}

dn, err := Create[*FullUser](ctx, client, user)
if err != nil {
    return err
}
fmt.Printf("Created user with DN: %s\n", dn)

func CreateSecureTLSConfig added in v1.1.0

func CreateSecureTLSConfig(cfg *TLSConfig) *tls.Config

CreateSecureTLSConfig creates a secure TLS configuration from TLSConfig

func Delete added in v1.1.0

func Delete[T LDAPObject](ctx context.Context, l *LDAP, obj T) error

Delete performs a generic delete operation for LDAP objects. This function provides type safety for LDAP object deletion.

Type parameter T must implement LDAPObject constraint.

Parameters:

  • ctx: Context for controlling the delete timeout and cancellation
  • l: LDAP client to use for the deletion
  • obj: The object to delete (only DN is used)

Returns:

  • error: Any error encountered during the deletion operation

Example:

err := Delete[*User](ctx, client, user)
if err != nil {
    return err
}

func DeleteByDN added in v1.1.0

func DeleteByDN(ctx context.Context, l *LDAP, dn string) error

DeleteByDN performs a generic delete operation by distinguished name. This function provides a convenient way to delete objects by DN.

Parameters:

  • ctx: Context for controlling the delete timeout and cancellation
  • l: LDAP client to use for the deletion
  • dn: Distinguished name of the object to delete

Returns:

  • error: Any error encountered during the deletion operation

func EscapeFilterValue added in v1.1.0

func EscapeFilterValue(value string) string

EscapeFilterValue escapes special characters in LDAP filter values

func ExtractDN added in v1.1.0

func ExtractDN(err error) string

ExtractDN extracts the distinguished name from an LDAP error. Returns empty string if no DN is available.

func ExtractOperation added in v1.1.0

func ExtractOperation(err error) string

ExtractOperation extracts the operation name from an LDAP error. Returns empty string if no operation is available.

func FindByDN added in v1.1.0

func FindByDN[T LDAPObject](ctx context.Context, l *LDAP, dn string) (T, error)

FindByDN performs a generic search by distinguished name. This function provides type safety for DN-based lookups.

Type parameter T must implement LDAPObject constraint.

Parameters:

  • ctx: Context for controlling the search timeout and cancellation
  • l: LDAP client to use for the search
  • dn: Distinguished name to search for

Returns:

  • T: The found object
  • error: Any error encountered during the search, including ErrNotFound if no object is found

Example:

user, err := FindByDN[*User](ctx, client, "CN=John Doe,OU=Users,DC=example,DC=com")
if err != nil {
    return err
}
fmt.Printf("Found user: %s\n", user.CN())

func FormatErrorWithContext added in v1.1.0

func FormatErrorWithContext(err error) string

FormatErrorWithContext returns a detailed error description including context information. Sensitive information is masked to prevent data leakage.

func GenerateCacheKey added in v1.1.0

func GenerateCacheKey(operation string, components ...string) string

GenerateCacheKey creates a cache key from multiple components

func GetErrorContext added in v1.1.0

func GetErrorContext(err error) map[string]interface{}

GetErrorContext extracts context information from an error. Returns nil if the error doesn't contain context information.

func GetLDAPResultCode added in v1.1.0

func GetLDAPResultCode(err error) int

GetLDAPResultCode extracts the LDAP result code from an error. Returns 0 if no LDAP result code is available.

func IsAuthenticationError added in v1.1.0

func IsAuthenticationError(err error) bool

IsAuthenticationError checks if an error is related to authentication.

func IsConnectionError added in v1.1.0

func IsConnectionError(err error) bool

IsConnectionError checks if an error is related to connection issues.

func IsContextError added in v1.1.0

func IsContextError(err error) bool

IsContextError checks if an error is related to context operations.

func IsNoSuchObjectError added in v1.1.0

func IsNoSuchObjectError(err error) bool

IsNoSuchObjectError checks if an error indicates no such object was found.

func IsNotFoundError added in v1.1.0

func IsNotFoundError(err error) bool

IsNotFoundError checks if an error indicates that an object was not found.

func IsRetryable added in v1.1.0

func IsRetryable(err error) bool

IsRetryable determines if an error is retryable based on its type.

func IsValidationError added in v1.1.0

func IsValidationError(err error) bool

IsValidationError checks if an error is related to input validation.

func IsValidationErrorCode added in v1.1.0

func IsValidationErrorCode(err error, code string) bool

IsValidationErrorCode checks if a validation error has a specific code.

func Modify added in v1.1.0

func Modify[T LDAPObject](ctx context.Context, l *LDAP, obj T, changes map[string][]string) error

Modify performs a generic modify operation for LDAP objects. This function provides type safety for LDAP object modifications.

Type parameter T must implement LDAPObject and Modifiable constraints.

Parameters:

  • ctx: Context for controlling the modify timeout and cancellation
  • l: LDAP client to use for the modification
  • obj: The object to modify
  • changes: Map of attribute names to new values

Returns:

  • error: Any error encountered during the modification operation

Example:

changes := map[string][]string{
    "description": {"Updated description"},
    "mail": {"new.email@example.com"},
}

err := Modify[*User](ctx, client, user, changes)
if err != nil {
    return err
}

func SanitizeDN added in v1.1.0

func SanitizeDN(dn string) string

SanitizeDN sanitizes a DN by removing or escaping dangerous characters

func SanitizeFilter added in v1.1.0

func SanitizeFilter(filter string) string

SanitizeFilter sanitizes an LDAP filter by removing or escaping dangerous characters

func Search[T LDAPObject](ctx context.Context, l *LDAP, filter string, baseDN string) ([]T, error)

Search performs a generic search operation that returns typed results. This function provides type safety for LDAP searches while reducing code duplication.

Type parameter T must implement LDAPObject and Searchable constraints.

Parameters:

  • ctx: Context for controlling the search timeout and cancellation
  • l: LDAP client to use for the search
  • filter: LDAP filter string for the search
  • baseDN: Base distinguished name for the search (empty string uses client's base DN)

Returns:

  • []T: Slice of typed LDAP objects matching the search criteria
  • error: Any error encountered during the search operation

Example:

// Search for users
users, err := Search[*User](ctx, client, "(objectClass=user)", "")
if err != nil {
    return err
}
for _, user := range users {
    fmt.Printf("Found user: %s\n", user.CN())
}

// Search for groups
groups, err := Search[*Group](ctx, client, "(objectClass=group)", "")
if err != nil {
    return err
}
for _, group := range groups {
    fmt.Printf("Found group: %s\n", group.CN())
}

func TestMain added in v1.1.0

func TestMain(m *testing.M)

TestMain is a stub that just runs the tests normally

func ValidateComputerSAMAccountName added in v1.1.0

func ValidateComputerSAMAccountName(samAccountName string) bool

ValidateComputerSAMAccountName validates computer SAMAccountName format with stricter rules

func ValidateDN added in v1.1.0

func ValidateDN(dn string) (string, error)

ValidateDN validates and normalizes a Distinguished Name (DN)

func ValidateEmail added in v1.1.0

func ValidateEmail(email string) error

ValidateEmail validates email address format

func ValidateEmailFormat added in v1.1.0

func ValidateEmailFormat(email string) bool

ValidateEmailFormat validates an email address format

func ValidateIPAddress added in v1.1.0

func ValidateIPAddress(ip string) bool

ValidateIPAddress validates an IP address

func ValidateIPWhitelist added in v1.1.0

func ValidateIPWhitelist(whitelist []string) ([]*net.IPNet, error)

ValidateIPWhitelist validates a list of IP addresses/CIDR blocks

func ValidateLDAPFilter added in v1.1.0

func ValidateLDAPFilter(filter string) (string, error)

ValidateLDAPFilter validates LDAP search filters for security

func ValidatePassword added in v1.1.0

func ValidatePassword(password string) error

ValidatePassword validates password strength and format

func ValidateSAMAccountName added in v1.1.0

func ValidateSAMAccountName(sam string) error

ValidateSAMAccountName validates sAMAccountName format

func ValidateServerURL added in v1.1.0

func ValidateServerURL(serverURL string) error

ValidateServerURL validates LDAP server URL format and security

func ValidateTLSConfig added in v1.1.0

func ValidateTLSConfig(config *tls.Config) error

ValidateTLSConfig validates a TLS configuration for security compliance

func WrapLDAPError added in v1.1.0

func WrapLDAPError(op, server string, err error) error

WrapLDAPError wraps an error with LDAP-specific context information. This function analyzes the underlying error to extract LDAP-specific information and classify the error type for proper handling.

Types

type AddRequest added in v1.1.0

type AddRequest struct {
	DN         string
	Attributes []Attribute
}

AddRequest represents an add request with modern Go patterns.

type Attribute added in v1.1.0

type Attribute struct {
	Type string
	Vals []string
}

Attribute represents an LDAP attribute with modern Go patterns.

type BatchOperation added in v1.1.0

type BatchOperation[T LDAPObject] struct {
	Operation string // "create", "modify", "delete"
	Object    T
	Changes   map[string][]string // For modify operations
}

BatchOperation represents a batch operation that can be performed on multiple objects.

type BatchProcessor added in v1.1.0

type BatchProcessor[T any] struct {
	// contains filtered or unexported fields
}

BatchProcessor provides efficient batch processing of LDAP operations.

func NewBatchProcessor added in v1.1.0

func NewBatchProcessor[T any](client *LDAP, batchSize int, timeout time.Duration,
	processor func(context.Context, *LDAP, []T) error) *BatchProcessor[T]

NewBatchProcessor creates a new batch processor.

Example:

processor := NewBatchProcessor(client, 10, 1*time.Second,
    func(ctx context.Context, client *LDAP, users []*FullUser) error {
        // Process batch of users
        for _, user := range users {
            _, err := client.CreateUserContext(ctx, *user, "password")
            if err != nil {
                return err
            }
        }
        return nil
    })

defer processor.Close()

// Add items for processing
for _, user := range users {
    processor.Add(user)
}

func (*BatchProcessor[T]) Add added in v1.1.0

func (bp *BatchProcessor[T]) Add(item T)

Add adds an item to the batch for processing.

func (*BatchProcessor[T]) Close added in v1.1.0

func (bp *BatchProcessor[T]) Close()

Close processes any remaining items and shuts down the processor.

type BatchResult added in v1.1.0

type BatchResult[T LDAPObject] struct {
	Object T
	Error  error
	DN     string // For create operations
}

BatchResult represents the result of a batch operation.

func BatchProcess added in v1.1.0

func BatchProcess[T LDAPObject](ctx context.Context, l *LDAP, operations []BatchOperation[T]) ([]BatchResult[T], error)

BatchProcess performs batch operations on multiple objects with type safety. This function provides efficient processing of multiple LDAP operations.

Type parameter T must implement LDAPObject constraint.

Parameters:

  • ctx: Context for controlling the batch timeout and cancellation
  • l: LDAP client to use for the operations
  • operations: Slice of operations to perform

Returns:

  • []BatchResult[T]: Results for each operation, including any errors
  • error: Any error that prevented the batch from running at all

Example:

operations := []BatchOperation[*User]{
    {Operation: "create", Object: newUser1},
    {Operation: "modify", Object: existingUser, Changes: changes},
    {Operation: "delete", Object: oldUser},
}

results, err := BatchProcess[*User](ctx, client, operations)
if err != nil {
    return err
}

for i, result := range results {
    if result.Error != nil {
        fmt.Printf("Operation %d failed: %v\n", i, result.Error)
    }
}

type BulkSearchOptions added in v1.1.0

type BulkSearchOptions struct {
	// BatchSize determines how many searches to perform concurrently
	BatchSize int
	// Timeout sets a custom timeout for the entire bulk operation
	Timeout time.Duration
	// ContinueOnError enables continuing even if some searches fail
	ContinueOnError bool
	// UseCache enables/disables caching for bulk searches
	UseCache bool
	// CachePrefix is a prefix for cache keys in bulk operations
	CachePrefix string
	// MaxConcurrency limits the number of concurrent searches
	MaxConcurrency int
	// RetryAttempts specifies how many times to retry failed searches
	RetryAttempts int
	// RetryDelay specifies the delay between retry attempts
	RetryDelay time.Duration
}

BulkSearchOptions provides configuration for optimized bulk search operations

type Bulkhead added in v1.1.0

type Bulkhead struct {
	// contains filtered or unexported fields
}

Bulkhead implements the bulkhead pattern for resource isolation

func NewBulkhead added in v1.1.0

func NewBulkhead(name string, config *BulkheadConfig, logger *slog.Logger) *Bulkhead

NewBulkhead creates a new bulkhead

func (*Bulkhead) Execute added in v1.1.0

func (b *Bulkhead) Execute(ctx context.Context, fn func() error) error

Execute executes a function with bulkhead protection

func (*Bulkhead) GetStats added in v1.1.0

func (b *Bulkhead) GetStats() map[string]interface{}

GetStats returns bulkhead statistics

type BulkheadConfig added in v1.1.0

type BulkheadConfig struct {
	MaxConcurrency int           `json:"max_concurrency"`
	QueueSize      int           `json:"queue_size"`
	Timeout        time.Duration `json:"timeout"`
}

BulkheadConfig holds configuration for the bulkhead pattern

func DefaultBulkheadConfig added in v1.1.0

func DefaultBulkheadConfig() *BulkheadConfig

DefaultBulkheadConfig returns a sensible default configuration

type Cache added in v1.1.0

type Cache interface {
	// Basic operations
	Get(key string) (interface{}, bool)
	Set(key string, value interface{}, ttl time.Duration) error
	Delete(key string) bool
	Clear()

	// Context-aware operations
	GetContext(ctx context.Context, key string) (interface{}, bool)
	SetContext(ctx context.Context, key string, value interface{}, ttl time.Duration) error

	// Advanced operations
	GetWithRefresh(key string, refreshFunc func() (interface{}, error)) (interface{}, error)
	SetNegative(key string, ttl time.Duration) error

	// Cache key tracking operations
	RegisterCacheKey(primaryKey string, cacheKey string)
	InvalidateByPrimaryKey(primaryKey string) int
	SetWithPrimaryKey(cacheKey string, value interface{}, ttl time.Duration, primaryKey string) error
	GetRelatedKeys(primaryKey string) []string

	// Statistics and management
	Stats() CacheStats
	Close() error
}

Cache interface defines the caching operations

type CacheConfig added in v1.1.0

type CacheConfig struct {
	// Enabled controls whether caching is active (default: false for backwards compatibility)
	Enabled bool
	// TTL is the default time-to-live for cache entries (default: 5 minutes)
	TTL time.Duration
	// MaxSize is the maximum number of cache entries (default: 1000)
	MaxSize int
	// RefreshInterval is how often to perform background cache maintenance (default: 1 minute)
	RefreshInterval time.Duration
	// RefreshOnAccess enables automatic refresh of stale entries on access (default: true)
	RefreshOnAccess bool
	// NegativeCacheTTL is the TTL for negative (not found) results (default: 30 seconds)
	NegativeCacheTTL time.Duration
	// MaxMemoryMB is the approximate maximum memory usage in MB (default: 64 MB)
	MaxMemoryMB int
	// CompressionEnabled enables gzip compression for large entries (default: false)
	CompressionEnabled bool
	// CompressionThreshold is the size threshold for compression in bytes (default: 1KB)
	CompressionThreshold int
}

CacheConfig holds the configuration for the intelligent caching system

func DefaultCacheConfig added in v1.1.0

func DefaultCacheConfig() *CacheConfig

DefaultCacheConfig returns a CacheConfig with sensible defaults

type CacheEntry added in v1.1.0

type CacheEntry struct {
	// Core data
	Key   string
	Value interface{}

	// Timing information
	CreatedAt  time.Time
	LastAccess time.Time
	ExpiresAt  time.Time
	TTL        time.Duration

	// Metadata
	Size        int32 // Approximate size in bytes
	AccessCount int64 // Number of times accessed
	IsNegative  bool  // Whether this is a negative cache entry (not found result)
	Compressed  bool  // Whether the value is compressed
	// contains filtered or unexported fields
}

CacheEntry represents a cached item with metadata

func (*CacheEntry) IsExpired added in v1.1.0

func (e *CacheEntry) IsExpired() bool

IsExpired checks if the cache entry has expired

func (*CacheEntry) IsStale added in v1.1.0

func (e *CacheEntry) IsStale() bool

IsStale checks if the cache entry is getting stale (75% of TTL elapsed)

type CacheStats added in v1.1.0

type CacheStats struct {
	Hits             int64         `json:"hits"`
	Misses           int64         `json:"misses"`
	HitRatio         float64       `json:"hit_ratio"`
	TotalEntries     int32         `json:"total_entries"`
	MaxEntries       int32         `json:"max_entries"`
	MemoryUsageMB    float64       `json:"memory_usage_mb"`
	MemoryUsageBytes int64         `json:"memory_usage_bytes"`
	AvgGetTime       time.Duration `json:"avg_get_time"`
	AvgSetTime       time.Duration `json:"avg_set_time"`
	Sets             int64         `json:"sets"`
	Deletes          int64         `json:"deletes"`
	Evictions        int64         `json:"evictions"`
	Expirations      int64         `json:"expirations"`
	NegativeHits     int64         `json:"negative_hits"`
	NegativeEntries  int32         `json:"negative_entries"`
	RefreshOps       int64         `json:"refresh_ops"`
	CleanupOps       int64         `json:"cleanup_ops"`
}

CacheStats contains cache performance statistics

type Change added in v1.1.0

type Change struct {
	Operation int
	Attribute Attribute
}

Change represents a modification change with modern Go patterns.

type CircuitBreaker added in v1.1.0

type CircuitBreaker struct {
	// contains filtered or unexported fields
}

CircuitBreaker implements the circuit breaker pattern for resilient error handling

func NewCircuitBreaker added in v1.1.0

func NewCircuitBreaker(name string, config *CircuitBreakerConfig, logger *slog.Logger) *CircuitBreaker

NewCircuitBreaker creates a new circuit breaker

func (*CircuitBreaker) Execute added in v1.1.0

func (cb *CircuitBreaker) Execute(fn func() error) error

Execute executes a function with circuit breaker protection

func (*CircuitBreaker) GetStats added in v1.1.0

func (cb *CircuitBreaker) GetStats() map[string]interface{}

GetStats returns circuit breaker statistics

func (*CircuitBreaker) Reset added in v1.1.0

func (cb *CircuitBreaker) Reset()

Reset resets the circuit breaker to closed state

type CircuitBreakerConfig added in v1.1.0

type CircuitBreakerConfig struct {
	// MaxFailures is the number of failures before opening the circuit
	MaxFailures int64 `json:"max_failures"`
	// Timeout is how long to wait before transitioning from open to half-open
	Timeout time.Duration `json:"timeout"`
	// HalfOpenMaxRequests is the maximum number of requests allowed in half-open state
	HalfOpenMaxRequests int64 `json:"half_open_max_requests"`
}

CircuitBreakerConfig holds configuration for the circuit breaker

func DefaultCircuitBreakerConfig added in v1.1.0

func DefaultCircuitBreakerConfig() *CircuitBreakerConfig

DefaultCircuitBreakerConfig returns a sensible default configuration

type CircuitBreakerError added in v1.1.0

type CircuitBreakerError struct {
	State       string
	Failures    int
	LastFailure time.Time
	NextRetry   time.Time
}

Circuit breaker error - with fields expected by resilience.go

func (*CircuitBreakerError) Error added in v1.1.0

func (e *CircuitBreakerError) Error() string

type CircuitBreakerState added in v1.1.0

type CircuitBreakerState int32

CircuitBreakerState represents the state of a circuit breaker

const (
	StateCircuitClosed CircuitBreakerState = iota
	StateCircuitOpen
	StateCircuitHalfOpen
)

func (CircuitBreakerState) String added in v1.1.0

func (s CircuitBreakerState) String() string

type Computer

type Computer struct {
	Object
	// SAMAccountName is the Security Account Manager account name for the computer (typically ends with $).
	SAMAccountName string
	// Enabled indicates whether the computer account is enabled (not disabled by userAccountControl).
	Enabled bool
	// OS contains the operating system name from the operatingSystem attribute.
	OS string
	// OSVersion contains the operating system version from the operatingSystemVersion attribute.
	OSVersion string
	// Groups contains a list of distinguished names (DNs) of groups the computer belongs to.
	Groups []string
}

Computer represents an LDAP computer object with common attributes.

type ComputerBuilder added in v1.1.0

type ComputerBuilder struct {
	// contains filtered or unexported fields
}

ComputerBuilder implements the builder pattern for creating FullComputer objects.

func NewComputerBuilder added in v1.1.0

func NewComputerBuilder() *ComputerBuilder

NewComputerBuilder creates a new ComputerBuilder with default values.

Example:

computer, err := NewComputerBuilder().
    WithCN("WORKSTATION01").
    WithSAMAccountName("WORKSTATION01$").
    WithDescription("Development Workstation").
    WithEnabled(true).
    Build()

func (*ComputerBuilder) Build added in v1.1.0

func (b *ComputerBuilder) Build() (*FullComputer, error)

Build creates the FullComputer object and validates all required fields.

func (*ComputerBuilder) MustBuild added in v1.1.0

func (b *ComputerBuilder) MustBuild() *FullComputer

MustBuild creates the FullComputer object and panics if validation fails. This follows Go's convention for Must* functions which panic on error. Use Build() if you want to handle errors gracefully.

func (*ComputerBuilder) WithCN added in v1.1.0

func (b *ComputerBuilder) WithCN(cn string) *ComputerBuilder

WithCN sets the common name for the computer.

func (*ComputerBuilder) WithDNSHostName added in v1.1.0

func (b *ComputerBuilder) WithDNSHostName(dnsHostName string) *ComputerBuilder

WithDNSHostName sets the DNS host name for the computer.

func (*ComputerBuilder) WithDescription added in v1.1.0

func (b *ComputerBuilder) WithDescription(description string) *ComputerBuilder

WithDescription sets the description for the computer.

func (*ComputerBuilder) WithEnabled added in v1.1.0

func (b *ComputerBuilder) WithEnabled(enabled bool) *ComputerBuilder

WithEnabled sets whether the computer account is enabled.

func (*ComputerBuilder) WithOperatingSystem added in v1.1.0

func (b *ComputerBuilder) WithOperatingSystem(os string) *ComputerBuilder

WithOperatingSystem sets the operating system information for the computer.

func (*ComputerBuilder) WithSAMAccountName added in v1.1.0

func (b *ComputerBuilder) WithSAMAccountName(samAccountName string) *ComputerBuilder

WithSAMAccountName sets the SAM account name for the computer. Computer SAM account names should end with $ (dollar sign).

type ComputerCache added in v1.1.0

type ComputerCache = GenericLRUCache[*Computer]

ComputerCache provides a type-safe cache for Computer objects

func NewComputerCache added in v1.1.0

func NewComputerCache(config *CacheConfig, logger *slog.Logger) (*ComputerCache, error)

NewComputerCache creates a new cache specifically for Computer objects

type ComputerManager added in v1.1.0

type ComputerManager interface {
	ComputerReader
	ComputerWriter
}

ComputerManager combines ComputerReader and ComputerWriter interfaces for complete computer management. This interface provides a comprehensive set of computer management operations.

type ComputerReader added in v1.1.0

type ComputerReader interface {
	// FindComputerByDN retrieves a computer by their distinguished name
	FindComputerByDN(dn string) (*Computer, error)
	// FindComputerByDNContext retrieves a computer by their distinguished name with context
	FindComputerByDNContext(ctx context.Context, dn string) (*Computer, error)
	// FindComputerBySAMAccountName retrieves a computer by their SAM account name
	FindComputerBySAMAccountName(name string) (*Computer, error)
	// FindComputerBySAMAccountNameContext retrieves a computer by their SAM account name with context
	FindComputerBySAMAccountNameContext(ctx context.Context, name string) (*Computer, error)
}

ComputerReader defines methods for reading computer information from LDAP. This interface follows the Interface Segregation Principle by separating read operations.

type ComputerWriter added in v1.1.0

type ComputerWriter interface {
	// CreateComputer creates a new computer with the provided information
	CreateComputer(computer FullComputer) (string, error)
	// CreateComputerContext creates a new computer with the provided information with context
	CreateComputerContext(ctx context.Context, computer FullComputer) (string, error)
	// DeleteComputer deletes a computer by their distinguished name
	DeleteComputer(dn string) error
	// DeleteComputerContext deletes a computer by their distinguished name with context
	DeleteComputerContext(ctx context.Context, dn string) error
}

ComputerWriter defines methods for writing/modifying computer information in LDAP. This interface follows the Interface Segregation Principle by separating write operations.

type ConcurrentLDAPOperations added in v1.1.0

type ConcurrentLDAPOperations struct {
	// contains filtered or unexported fields
}

ConcurrentLDAPOperations provides common patterns for concurrent LDAP operations.

func NewConcurrentOperations added in v1.1.0

func NewConcurrentOperations(client *LDAP, maxConcurrency int) *ConcurrentLDAPOperations

NewConcurrentOperations creates a new concurrent operations helper.

func (*ConcurrentLDAPOperations) BulkCreateUsers added in v1.1.0

func (co *ConcurrentLDAPOperations) BulkCreateUsers(ctx context.Context, users []FullUser, password string) []error

BulkCreateUsers creates multiple users concurrently with rate limiting.

func (*ConcurrentLDAPOperations) BulkDeleteUsers added in v1.1.0

func (co *ConcurrentLDAPOperations) BulkDeleteUsers(ctx context.Context, dns []string) []error

BulkDeleteUsers deletes multiple users concurrently.

func (*ConcurrentLDAPOperations) BulkFindUsers added in v1.1.0

func (co *ConcurrentLDAPOperations) BulkFindUsers(ctx context.Context, dns []string) ([]*User, []error)

BulkFindUsers finds multiple users concurrently.

type Config

type Config struct {
	Server            string
	Port              int
	BaseDN            string
	IsActiveDirectory bool
	TLSConfig         *tls.Config
	DialTimeout       time.Duration
	ReadTimeout       time.Duration
	WriteTimeout      time.Duration

	// Additional configuration options
	Pool        *PoolConfig
	Cache       *CacheConfig
	Performance *PerformanceConfig
	Resilience  *ResilienceConfig
	Logger      *slog.Logger
	DialOptions []ldap.DialOpt

	// Optimization flags for enabling enhanced features
	EnableOptimizations bool // Enable all optimizations (caching, performance monitoring, bulk operations)
	EnableCache         bool // Enable caching separately (overrides EnableOptimizations for cache)
	EnableMetrics       bool // Enable performance metrics separately (overrides EnableOptimizations for metrics)
	EnableBulkOps       bool // Enable bulk operations separately (overrides EnableOptimizations for bulk)
}

Config contains the configuration for LDAP connections

type ConfigBuilder added in v1.1.0

type ConfigBuilder struct {
	// contains filtered or unexported fields
}

ConfigBuilder implements the builder pattern for creating Config objects.

func NewConfigBuilder added in v1.1.0

func NewConfigBuilder() *ConfigBuilder

NewConfigBuilder creates a new ConfigBuilder with default values.

Example:

config, err := NewConfigBuilder().
    WithServer("ldaps://ad.example.com:636").
    WithBaseDN("DC=example,DC=com").
    WithActiveDirectory(true).
    WithConnectionPool(poolConfig).
    Build()

func (*ConfigBuilder) Build added in v1.1.0

func (b *ConfigBuilder) Build() (*Config, error)

Build creates the Config object and validates all required fields.

func (*ConfigBuilder) MustBuild added in v1.1.0

func (b *ConfigBuilder) MustBuild() *Config

MustBuild creates the Config object and panics if validation fails. This follows Go's convention for Must* functions which panic on error. Use Build() if you want to handle errors gracefully.

func (*ConfigBuilder) WithActiveDirectory added in v1.1.0

func (b *ConfigBuilder) WithActiveDirectory(isAD bool) *ConfigBuilder

WithActiveDirectory sets whether the server is Active Directory.

func (*ConfigBuilder) WithBaseDN added in v1.1.0

func (b *ConfigBuilder) WithBaseDN(baseDN string) *ConfigBuilder

WithBaseDN sets the base distinguished name for searches.

func (*ConfigBuilder) WithCache added in v1.1.0

func (b *ConfigBuilder) WithCache(cacheConfig *CacheConfig) *ConfigBuilder

WithCache sets the cache configuration.

func (*ConfigBuilder) WithConnectionPool added in v1.1.0

func (b *ConfigBuilder) WithConnectionPool(poolConfig *PoolConfig) *ConfigBuilder

WithConnectionPool sets the connection pool configuration.

func (*ConfigBuilder) WithPerformanceMonitoring added in v1.1.0

func (b *ConfigBuilder) WithPerformanceMonitoring(perfConfig *PerformanceConfig) *ConfigBuilder

WithPerformanceMonitoring sets the performance monitoring configuration.

func (*ConfigBuilder) WithServer added in v1.1.0

func (b *ConfigBuilder) WithServer(server string) *ConfigBuilder

WithServer sets the LDAP server URL.

type Connection added in v1.1.0

type Connection interface {
	// Basic connection operations
	Close() error
	Bind(username, password string) error

	// Search operations
	Search(searchRequest *SearchRequest) (*SearchResult, error)
	SearchContext(ctx context.Context, searchRequest *SearchRequest) (*SearchResult, error)

	// Modify operations
	Add(addRequest *AddRequest) error
	AddContext(ctx context.Context, addRequest *AddRequest) error
	Modify(modifyRequest *ModifyRequest) error
	ModifyContext(ctx context.Context, modifyRequest *ModifyRequest) error
	Del(delRequest *DelRequest) error
	DelRequest(ctx context.Context, delRequest *DelRequest) error

	// Password operations
	PasswordModify(passwordModifyRequest *PasswordModifyRequest) error
	PasswordModifyContext(ctx context.Context, passwordModifyRequest *PasswordModifyRequest) error
}

Connection represents an LDAP connection with modern interface design. This interface abstracts the underlying connection implementation for better testability.

type ConnectionCredentials added in v1.4.0

type ConnectionCredentials struct {
	DN       string // Distinguished Name for LDAP bind
	Password string // Password for LDAP bind
}

ConnectionCredentials stores authentication information for a pooled connection. This enables per-user connection tracking and credential-aware connection reuse in multi-user scenarios (e.g., web applications, multi-tenant systems).

type ConnectionOptions added in v1.1.0

type ConnectionOptions struct {
	// ConnectionTimeout is the timeout for establishing LDAP connections
	ConnectionTimeout time.Duration
	// OperationTimeout is the timeout for LDAP operations
	OperationTimeout time.Duration
	// MaxRetries is the maximum number of retry attempts for failed operations
	MaxRetries int
	// RetryDelay is the delay between retry attempts
	RetryDelay time.Duration
	// EnableTLS forces TLS encryption for all connections
	EnableTLS bool
	// TLSMinVersion is the minimum TLS version to accept
	TLSMinVersion uint16
	// ValidateCertificates controls whether to validate server certificates
	ValidateCertificates bool
}

ConnectionOptions holds connection-related configuration options.

func DefaultConnectionOptions added in v1.1.0

func DefaultConnectionOptions() *ConnectionOptions

DefaultConnectionOptions returns a ConnectionOptions with sensible defaults.

type ConnectionPool added in v1.1.0

type ConnectionPool struct {
	// contains filtered or unexported fields
}

ConnectionPool manages a pool of LDAP connections with health monitoring and lifecycle management

func NewConnectionPool added in v1.1.0

func NewConnectionPool(config *PoolConfig, ldapConfig Config, user, password string, logger *slog.Logger) (*ConnectionPool, error)

NewConnectionPool creates a new connection pool with the specified configuration

func (*ConnectionPool) Close added in v1.1.0

func (p *ConnectionPool) Close() error

Close shuts down the pool and closes all connections

func (*ConnectionPool) Get added in v1.1.0

func (p *ConnectionPool) Get(ctx context.Context) (*ldap.Conn, error)

Get retrieves a connection from the pool, creating one if necessary

func (*ConnectionPool) GetWithCredentials added in v1.4.0

func (p *ConnectionPool) GetWithCredentials(ctx context.Context, dn, password string) (*ldap.Conn, error)

GetWithCredentials returns a connection from the pool authenticated with specific credentials. This method enables per-user connection pooling in multi-user scenarios where different users need separate authenticated connections.

The pool will: - Reuse existing connections with matching credentials - Create new connections when no matching credentials found - Prevent credential mixing for security

Use cases: - Web applications with per-user LDAP operations - Multi-tenant systems - Delegated operations on behalf of authenticated users

Example:

// User A's connection
connA, err := pool.GetWithCredentials(ctx, "cn=userA,dc=example,dc=com", "passwordA")
if err != nil {
    return err
}
defer pool.Put(connA)

// User B's connection (different connection from User A)
connB, err := pool.GetWithCredentials(ctx, "cn=userB,dc=example,dc=com", "passwordB")
if err != nil {
    return err
}
defer pool.Put(connB)

func (*ConnectionPool) Put added in v1.1.0

func (p *ConnectionPool) Put(conn *ldap.Conn) error

Put returns a connection to the pool

func (*ConnectionPool) Stats added in v1.1.0

func (p *ConnectionPool) Stats() PoolStats

Stats returns current pool statistics

type ConnectionPoolStats added in v1.1.0

type ConnectionPoolStats struct {
	// Basic pool information
	MaxConnections    int `json:"max_connections"`
	MinConnections    int `json:"min_connections"`
	ActiveConnections int `json:"active_connections"`
	IdleConnections   int `json:"idle_connections"`

	// Performance metrics
	TotalRequests int64 `json:"total_requests"`
	PoolHits      int64 `json:"pool_hits"`
	PoolMisses    int64 `json:"pool_misses"`

	// Timing statistics
	AvgWaitTime time.Duration `json:"avg_wait_time"`
	MaxWaitTime time.Duration `json:"max_wait_time"`

	// Health metrics
	FailedConnections int64 `json:"failed_connections"`
	TimeoutsCount     int64 `json:"timeouts_count"`
}

ConnectionPoolStats represents connection pool statistics

type ContextKey added in v1.1.0

type ContextKey string

ContextKey is a type for context keys to avoid collisions

const (
	ContextKeyClientIP    ContextKey = "client_ip"
	ContextKeyUserAgent   ContextKey = "user_agent"
	ContextKeyRequestID   ContextKey = "request_id"
	ContextKeySessionID   ContextKey = "session_id"
	ContextKeySecurityCtx ContextKey = "security_context"
)

Context keys for passing security-related information

type Creatable added in v1.1.0

type Creatable[T LDAPObject] interface {
	LDAPObject
	// ToAddRequest converts the object to an LDAP add request
	ToAddRequest() (*ldap.AddRequest, error)
	// Validate validates the object before creation
	Validate() error
}

Creatable defines the constraint for LDAP objects that can be created. This extends LDAPObject with creation-specific methods.

type CredentialProvider added in v1.1.0

type CredentialProvider interface {
	// GetCredentials returns the current username and password
	GetCredentials() (string, string)
	// ZeroizeCredentials securely clears credential data from memory
	ZeroizeCredentials() error
	// ValidateCredentials validates the credential format and requirements
	ValidateCredentials() error
}

CredentialProvider interface allows for custom credential management strategies

type DefaultCredentialProvider added in v1.1.0

type DefaultCredentialProvider struct {
	// contains filtered or unexported fields
}

DefaultCredentialProvider implements basic in-memory credential management

func (*DefaultCredentialProvider) GetCredentials added in v1.1.0

func (p *DefaultCredentialProvider) GetCredentials() (string, string)

GetCredentials returns the stored credentials

func (*DefaultCredentialProvider) ValidateCredentials added in v1.1.0

func (p *DefaultCredentialProvider) ValidateCredentials() error

ValidateCredentials performs basic validation

func (*DefaultCredentialProvider) ZeroizeCredentials added in v1.1.0

func (p *DefaultCredentialProvider) ZeroizeCredentials() error

ZeroizeCredentials clears the credential strings (basic implementation)

type DelRequest added in v1.1.0

type DelRequest struct {
	DN string
}

DelRequest represents a delete request with modern Go patterns.

type DirectoryManager added in v1.1.0

type DirectoryManager interface {
	UserManager
	GroupManager
	ComputerManager

	// Connection management
	GetConnection() (Connection, error)
	GetConnectionContext(ctx context.Context) (Connection, error)
	Close() error

	// Statistics and monitoring
	GetPoolStats() PerformanceStats
	GetCacheStats() CacheStats
	GetPerformanceStats() PerformanceStats
	ClearCache()
}

DirectoryManager is the main interface that combines all LDAP management capabilities. This interface provides a unified API for all directory operations.

type Entry added in v1.1.0

type Entry struct {
	DN         string
	Attributes []*EntryAttribute
}

Entry represents an LDAP entry with modern Go patterns.

type EntryAttribute added in v1.1.0

type EntryAttribute struct {
	Name   string
	Values []string
}

EntryAttribute represents an LDAP entry attribute with modern Go patterns.

type ErrorSeverity added in v1.1.0

type ErrorSeverity int

ErrorSeverity represents the severity level of an error.

const (
	SeverityInfo ErrorSeverity = iota
	SeverityWarning
	SeverityError
	SeverityCritical
)

func GetErrorSeverity added in v1.1.0

func GetErrorSeverity(err error) ErrorSeverity

GetErrorSeverity determines the severity level of an error.

func (ErrorSeverity) String added in v1.1.0

func (s ErrorSeverity) String() string

String returns the string representation of the error severity.

type FanOut added in v1.1.0

type FanOut[T, U any] struct {
	// contains filtered or unexported fields
}

FanOut provides a fan-out pattern for distributing work across multiple workers.

func NewFanOut added in v1.1.0

func NewFanOut[T, U any](ctx context.Context, logger *slog.Logger, bufferSize int) *FanOut[T, U]

NewFanOut creates a new fan-out processor.

Example:

fanOut := NewFanOut[string, *User](ctx, logger, 100)

// Add workers
fanOut.AddWorker(func(ctx context.Context, dn string) (*User, error) {
    return client.FindUserByDNContext(ctx, dn)
})
fanOut.AddWorker(func(ctx context.Context, dn string) (*User, error) {
    return client.FindUserByDNContext(ctx, dn)
})

go fanOut.Start()

// Send work
for _, dn := range userDNs {
    fanOut.Input() <- dn
}
close(fanOut.Input())

// Collect results
for user := range fanOut.Output() {
    fmt.Printf("Found user: %s\n", user.CN())
}

func (*FanOut[T, U]) AddWorker added in v1.1.0

func (f *FanOut[T, U]) AddWorker(worker func(context.Context, T) (U, error))

AddWorker adds a worker function to the fan-out.

func (*FanOut[T, U]) Close added in v1.1.0

func (f *FanOut[T, U]) Close()

Close stops the fan-out processor.

func (*FanOut[T, U]) Errors added in v1.1.0

func (f *FanOut[T, U]) Errors() <-chan error

Errors returns the error channel.

func (*FanOut[T, U]) Input added in v1.1.0

func (f *FanOut[T, U]) Input() chan<- T

Input returns the input channel.

func (*FanOut[T, U]) Output added in v1.1.0

func (f *FanOut[T, U]) Output() <-chan U

Output returns the output channel.

func (*FanOut[T, U]) Start added in v1.1.0

func (f *FanOut[T, U]) Start()

Start begins processing with fan-out pattern.

type FullComputer added in v1.1.0

type FullComputer struct {
	// CN is the common name of the computer (required, used as the RDN component).
	CN string
	// SAMAccountName is the Security Account Manager account name (required, typically ends with $).
	SAMAccountName string
	// Description provides additional information about the computer (optional).
	Description string
	// UserAccountControl defines the account control flags for the computer account.
	UserAccountControl uint32
	// DNSHostName is the fully qualified domain name of the computer (optional).
	DNSHostName string
	// OperatingSystem contains the operating system name (optional).
	OperatingSystem string
	// OperatingSystemVersion contains the operating system version (optional).
	OperatingSystemVersion string
	// OperatingSystemServicePack contains the service pack information (optional).
	OperatingSystemServicePack string
	// MemberOf contains a list of distinguished names (DNs) of groups the computer belongs to.
	MemberOf []string
	// OtherAttributes contains additional LDAP attributes not covered by the above fields.
	OtherAttributes map[string][]string
}

FullComputer represents a complete LDAP computer object for creation and modification operations.

type FullGroup added in v1.1.0

type FullGroup struct {
	// CN is the common name of the group (required, used as the RDN component).
	CN string
	// SAMAccountName is the Security Account Manager account name (optional).
	SAMAccountName string
	// Description provides additional information about the group (optional).
	Description string
	// GroupType defines the type and scope of the group (required for Active Directory).
	GroupType uint32
	// Member contains a list of distinguished names (DNs) of group members.
	Member []string
	// MemberOf contains a list of distinguished names (DNs) of parent groups.
	MemberOf []string
	// OtherAttributes contains additional LDAP attributes not covered by the above fields.
	OtherAttributes map[string][]string
}

FullGroup represents a complete LDAP group object for creation and modification operations.

type FullUser

type FullUser struct {
	// CN is the common name of the user (required, used as the RDN component).
	CN string
	// SAMAccountName is the Security Account Manager account name (optional for creation).
	SAMAccountName *string
	// FirstName is the user's given name (required).
	FirstName string
	// LastName is the user's surname (required).
	LastName string
	// DisplayName is the name displayed in address lists (optional, defaults to CN if nil).
	DisplayName *string
	// Description contains additional information about the user (optional).
	Description *string
	// Email is the user's email address (optional).
	Email *string
	// ObjectClasses defines the LDAP object classes (optional, defaults to standard user classes).
	ObjectClasses []string
	// AccountExpires represents the expiration date of the user's account.
	// When set to nil, the account never expires.
	AccountExpires *time.Time
	// UserAccountControl contains the account control flags (enabled/disabled, password policies, etc.).
	UserAccountControl UAC
	// Path specifies the organizational unit path relative to BaseDN (optional, defaults to BaseDN).
	Path *string
}

FullUser represents a complete user object for creation operations with all configurable attributes.

type GenericCache added in v1.1.0

type GenericCache[T any] interface {
	// Basic operations
	Get(key string) (T, bool)
	Set(key string, value T, ttl time.Duration) error
	Delete(key string) bool
	Clear()

	// Context-aware operations
	GetContext(ctx context.Context, key string) (T, bool)
	SetContext(ctx context.Context, key string, value T, ttl time.Duration) error

	// Advanced operations
	GetWithRefresh(key string, refreshFunc func() (T, error)) (T, error)
	SetNegative(key string, ttl time.Duration) error

	// Statistics and management
	Stats() CacheStats
	Close() error
}

GenericCache interface defines the caching operations with type safety

type GenericCacheEntry added in v1.1.0

type GenericCacheEntry[T any] struct {
	// Core data
	Key   string
	Value T

	// Timing information
	CreatedAt  time.Time
	LastAccess time.Time
	ExpiresAt  time.Time
	TTL        time.Duration

	// Metadata
	Size        int32 // Approximate size in bytes
	AccessCount int64 // Number of times accessed
	IsNegative  bool  // Whether this is a negative cache entry (not found result)
	Compressed  bool  // Whether the value is compressed
	// contains filtered or unexported fields
}

GenericCacheEntry represents a cached item with metadata for generic cache

func (*GenericCacheEntry[T]) IsExpired added in v1.1.0

func (e *GenericCacheEntry[T]) IsExpired() bool

IsExpired checks if the cache entry has expired

func (*GenericCacheEntry[T]) IsStale added in v1.1.0

func (e *GenericCacheEntry[T]) IsStale() bool

IsStale checks if the cache entry is getting stale (75% of TTL elapsed)

type GenericLRUCache added in v1.1.0

type GenericLRUCache[T any] struct {
	// contains filtered or unexported fields
}

GenericLRUCache implements a type-safe LRU cache with advanced features

func NewGenericLRUCache added in v1.1.0

func NewGenericLRUCache[T any](config *CacheConfig, logger *slog.Logger) (*GenericLRUCache[T], error)

NewGenericLRUCache creates a new type-safe LRU cache with the specified configuration

func (*GenericLRUCache[T]) Clear added in v1.1.0

func (c *GenericLRUCache[T]) Clear()

Clear removes all entries from the cache

func (*GenericLRUCache[T]) Close added in v1.1.0

func (c *GenericLRUCache[T]) Close() error

Close stops the cache and its background tasks

func (*GenericLRUCache[T]) Delete added in v1.1.0

func (c *GenericLRUCache[T]) Delete(key string) bool

Delete removes a value from the cache

func (*GenericLRUCache[T]) Get added in v1.1.0

func (c *GenericLRUCache[T]) Get(key string) (T, bool)

Get retrieves a value from the cache

func (*GenericLRUCache[T]) GetContext added in v1.1.0

func (c *GenericLRUCache[T]) GetContext(ctx context.Context, key string) (T, bool)

GetContext retrieves a value from the cache with context support

func (*GenericLRUCache[T]) GetWithRefresh added in v1.1.0

func (c *GenericLRUCache[T]) GetWithRefresh(key string, refreshFunc func() (T, error)) (T, error)

GetWithRefresh retrieves a value from the cache, refreshing it if stale or missing

func (*GenericLRUCache[T]) Set added in v1.1.0

func (c *GenericLRUCache[T]) Set(key string, value T, ttl time.Duration) error

Set stores a value in the cache

func (*GenericLRUCache[T]) SetContext added in v1.1.0

func (c *GenericLRUCache[T]) SetContext(ctx context.Context, key string, value T, ttl time.Duration) error

SetContext stores a value in the cache with context support

func (*GenericLRUCache[T]) SetNegative added in v1.1.0

func (c *GenericLRUCache[T]) SetNegative(key string, ttl time.Duration) error

SetNegative stores a negative (not found) result in the cache

func (*GenericLRUCache[T]) Stats added in v1.1.0

func (c *GenericLRUCache[T]) Stats() CacheStats

Stats returns current cache statistics

type Group

type Group struct {
	Object
	// Members contains a list of distinguished names (DNs) of group members.
	Members []string
}

Group represents an LDAP group object with its members.

type GroupBuilder added in v1.1.0

type GroupBuilder struct {
	// contains filtered or unexported fields
}

GroupBuilder implements the builder pattern for creating FullGroup objects.

func NewGroupBuilder added in v1.1.0

func NewGroupBuilder() *GroupBuilder

NewGroupBuilder creates a new GroupBuilder with default values.

Example:

group, err := NewGroupBuilder().
    WithCN("Developers").
    WithDescription("Software Development Team").
    WithGroupType(GlobalSecurityGroup).
    Build()

func (*GroupBuilder) Build added in v1.1.0

func (b *GroupBuilder) Build() (*FullGroup, error)

Build creates the FullGroup object and validates all required fields.

func (*GroupBuilder) MustBuild added in v1.1.0

func (b *GroupBuilder) MustBuild() *FullGroup

MustBuild creates the FullGroup object and panics if validation fails. This follows Go's convention for Must* functions which panic on error. Use Build() if you want to handle errors gracefully.

func (*GroupBuilder) WithCN added in v1.1.0

func (b *GroupBuilder) WithCN(cn string) *GroupBuilder

WithCN sets the common name for the group.

func (*GroupBuilder) WithDescription added in v1.1.0

func (b *GroupBuilder) WithDescription(description string) *GroupBuilder

WithDescription sets the description for the group.

func (*GroupBuilder) WithGroupType added in v1.1.0

func (b *GroupBuilder) WithGroupType(groupType uint32) *GroupBuilder

WithGroupType sets the group type using Active Directory group type constants.

func (*GroupBuilder) WithMembers added in v1.1.0

func (b *GroupBuilder) WithMembers(memberDNs []string) *GroupBuilder

WithMembers sets the initial members of the group.

func (*GroupBuilder) WithSAMAccountName added in v1.1.0

func (b *GroupBuilder) WithSAMAccountName(samAccountName string) *GroupBuilder

WithSAMAccountName sets the SAM account name for the group.

type GroupCache added in v1.1.0

type GroupCache = GenericLRUCache[*Group]

GroupCache provides a type-safe cache for Group objects

func NewGroupCache added in v1.1.0

func NewGroupCache(config *CacheConfig, logger *slog.Logger) (*GroupCache, error)

NewGroupCache creates a new cache specifically for Group objects

type GroupManager added in v1.1.0

type GroupManager interface {
	GroupReader
	GroupWriter
	// GetGroupMembers retrieves the members of a group
	GetGroupMembers(groupDN string) ([]User, error)
	// GetGroupMembersContext retrieves the members of a group with context
	GetGroupMembersContext(ctx context.Context, groupDN string) ([]User, error)
}

GroupManager combines GroupReader and GroupWriter interfaces for complete group management. This interface provides a comprehensive set of group management operations.

type GroupReader added in v1.1.0

type GroupReader interface {
	// FindGroupByDN retrieves a group by their distinguished name
	FindGroupByDN(dn string) (*Group, error)
	// FindGroupByDNContext retrieves a group by their distinguished name with context
	FindGroupByDNContext(ctx context.Context, dn string) (*Group, error)
	// FindGroupByCN retrieves a group by their common name
	FindGroupByCN(cn string) (*Group, error)
	// FindGroupByCNContext retrieves a group by their common name with context
	FindGroupByCNContext(ctx context.Context, cn string) (*Group, error)
}

GroupReader defines methods for reading group information from LDAP. This interface follows the Interface Segregation Principle by separating read operations.

type GroupWriter added in v1.1.0

type GroupWriter interface {
	// CreateGroup creates a new group with the provided information
	CreateGroup(group FullGroup) (string, error)
	// CreateGroupContext creates a new group with the provided information with context
	CreateGroupContext(ctx context.Context, group FullGroup) (string, error)
	// DeleteGroup deletes a group by their distinguished name
	DeleteGroup(dn string) error
	// DeleteGroupContext deletes a group by their distinguished name with context
	DeleteGroupContext(ctx context.Context, dn string) error
	// AddUserToGroup adds a user to a group
	AddUserToGroup(userDN, groupDN string) error
	// AddUserToGroupContext adds a user to a group with context
	AddUserToGroupContext(ctx context.Context, userDN, groupDN string) error
	// RemoveUserFromGroup removes a user from a group
	RemoveUserFromGroup(userDN, groupDN string) error
	// RemoveUserFromGroupContext removes a user from a group with context
	RemoveUserFromGroupContext(ctx context.Context, userDN, groupDN string) error
}

GroupWriter defines methods for writing/modifying group information in LDAP. This interface follows the Interface Segregation Principle by separating write operations.

type IndexedComputerCache added in v1.5.0

type IndexedComputerCache struct {
	*GenericLRUCache[*Computer]
	// contains filtered or unexported fields
}

IndexedComputerCache extends GenericLRUCache with O(1) indexed lookups for Computer objects.

Provides FindByDN and FindBySAMAccountName methods for constant-time lookups without knowing the cache key. Indexes are automatically maintained on Set, Delete, and Clear operations.

func NewIndexedComputerCache added in v1.5.0

func NewIndexedComputerCache(config *CacheConfig, logger *slog.Logger) (*IndexedComputerCache, error)

NewIndexedComputerCache creates a new indexed cache for Computer objects.

The cache supports O(1) lookups by DN and SAMAccountName in addition to standard cache key lookups. All index operations are thread-safe.

func (*IndexedComputerCache) Clear added in v1.5.0

func (c *IndexedComputerCache) Clear()

Clear removes all entries and clears indexes

func (*IndexedComputerCache) Delete added in v1.5.0

func (c *IndexedComputerCache) Delete(key string) bool

Delete removes a Computer from the cache and updates indexes

func (*IndexedComputerCache) FindByDN added in v1.5.0

func (c *IndexedComputerCache) FindByDN(dn string) (*Computer, bool)

FindByDN finds a Computer by Distinguished Name with O(1) lookup

func (*IndexedComputerCache) FindBySAMAccountName added in v1.5.0

func (c *IndexedComputerCache) FindBySAMAccountName(samAccountName string) (*Computer, bool)

FindBySAMAccountName finds a Computer by SAMAccountName with O(1) lookup

func (*IndexedComputerCache) Set added in v1.5.0

func (c *IndexedComputerCache) Set(key string, value *Computer, ttl time.Duration) error

Set stores a Computer in the cache and updates indexes

type IndexedGroupCache added in v1.5.0

type IndexedGroupCache struct {
	*GenericLRUCache[*Group]
	// contains filtered or unexported fields
}

IndexedGroupCache extends GenericLRUCache with O(1) indexed lookups for Group objects.

Provides FindByDN method for constant-time lookups by Distinguished Name without knowing the cache key. Index is automatically maintained on Set, Delete, and Clear operations.

func NewIndexedGroupCache added in v1.5.0

func NewIndexedGroupCache(config *CacheConfig, logger *slog.Logger) (*IndexedGroupCache, error)

NewIndexedGroupCache creates a new indexed cache for Group objects.

The cache supports O(1) lookups by DN in addition to standard cache key lookups. All index operations are thread-safe.

func (*IndexedGroupCache) Clear added in v1.5.0

func (c *IndexedGroupCache) Clear()

Clear removes all entries and clears indexes

func (*IndexedGroupCache) Delete added in v1.5.0

func (c *IndexedGroupCache) Delete(key string) bool

Delete removes a Group from the cache and updates indexes

func (*IndexedGroupCache) FindByDN added in v1.5.0

func (c *IndexedGroupCache) FindByDN(dn string) (*Group, bool)

FindByDN finds a Group by Distinguished Name with O(1) lookup

func (*IndexedGroupCache) Set added in v1.5.0

func (c *IndexedGroupCache) Set(key string, value *Group, ttl time.Duration) error

Set stores a Group in the cache and updates indexes

type IndexedUserCache added in v1.5.0

type IndexedUserCache struct {
	*GenericLRUCache[*User]
	// contains filtered or unexported fields
}

IndexedUserCache extends GenericLRUCache with O(1) indexed lookups for User objects.

Provides FindByDN and FindBySAMAccountName methods for constant-time lookups without knowing the cache key. Indexes are automatically maintained on Set, Delete, and Clear operations.

func NewIndexedUserCache added in v1.5.0

func NewIndexedUserCache(config *CacheConfig, logger *slog.Logger) (*IndexedUserCache, error)

NewIndexedUserCache creates a new indexed cache for User objects.

The cache supports O(1) lookups by DN and SAMAccountName in addition to standard cache key lookups. All index operations are thread-safe.

Example:

config := &CacheConfig{
	Enabled: true,
	TTL: 5 * time.Minute,
	MaxSize: 1000,
}
cache, err := NewIndexedUserCache(config, logger)
if err != nil {
	return err
}
defer cache.Close()

func (*IndexedUserCache) Clear added in v1.5.0

func (c *IndexedUserCache) Clear()

Clear removes all entries from the cache and clears all indexes.

func (*IndexedUserCache) Delete added in v1.5.0

func (c *IndexedUserCache) Delete(key string) bool

Delete removes a User from the cache and cleans up indexes.

Automatically removes DN and SAMAccountName index entries.

func (*IndexedUserCache) FindByDN added in v1.5.0

func (c *IndexedUserCache) FindByDN(dn string) (*User, bool)

FindByDN finds a User by Distinguished Name with O(1) lookup.

Returns the cached User and true if found, or nil and false if not found or if the DN is empty. Performance is constant-time regardless of cache size.

Example:

user, found := cache.FindByDN("cn=john.doe,dc=example,dc=com")
if found {
	fmt.Printf("Found user: %s\n", user.SAMAccountName)
}

func (*IndexedUserCache) FindBySAMAccountName added in v1.5.0

func (c *IndexedUserCache) FindBySAMAccountName(samAccountName string) (*User, bool)

FindBySAMAccountName finds a User by SAMAccountName with O(1) lookup.

Returns the cached User and true if found, or nil and false if not found or if the SAMAccountName is empty. Performance is constant-time regardless of cache size.

Example:

user, found := cache.FindBySAMAccountName("john.doe")
if found {
	fmt.Printf("Found user DN: %s\n", user.DN())
}

func (*IndexedUserCache) Set added in v1.5.0

func (c *IndexedUserCache) Set(key string, value *User, ttl time.Duration) error

Set stores a User in the cache and updates indexes.

Automatically maintains DN and SAMAccountName indexes for O(1) lookups. If the user's DN or SAMAccountName is empty, the index entry is skipped.

type LDAP

type LDAP struct {
	// contains filtered or unexported fields
}

LDAP represents the main LDAP client with connection management and security features

func New

func New(config Config, username, password string, opts ...Option) (*LDAP, error)

New creates a new LDAP client with the given configuration and optional functional options

func NewBasicClient added in v1.1.0

func NewBasicClient(config Config, username, password string) (*LDAP, error)

NewBasicClient creates a basic LDAP client with minimal configuration.

func NewCachedClient added in v1.1.0

func NewCachedClient(config Config, username, password string, maxSize int, ttl time.Duration) (*LDAP, error)

NewCachedClient creates an LDAP client with caching enabled.

func NewHighPerformanceClient added in v1.1.0

func NewHighPerformanceClient(config Config, username, password string) (*LDAP, error)

NewHighPerformanceClient creates an LDAP client optimized for high performance with pooling, caching, and monitoring.

func NewPooledClient added in v1.1.0

func NewPooledClient(config Config, username, password string, maxConnections int) (*LDAP, error)

NewPooledClient creates an LDAP client with connection pooling enabled.

func NewReadOnlyClient added in v1.1.0

func NewReadOnlyClient(config Config, username, password string) (*LDAP, error)

NewReadOnlyClient creates an LDAP client optimized for read-only operations with caching.

func NewSecureClient added in v1.1.0

func NewSecureClient(config Config, username, password string, tlsConfigs ...*tls.Config) (*LDAP, error)

NewSecureClient creates an LDAP client with enhanced security settings.

func (*LDAP) AddUserToGroup

func (l *LDAP) AddUserToGroup(dn, groupDN string) error

AddUserToGroup adds a user to a group by modifying the group's member attribute.

Parameters:

  • dn: The distinguished name of the user to add to the group
  • groupDN: The distinguished name of the group to modify

Returns:

  • error: Any LDAP operation error, including insufficient permissions or if the user is already a member

This operation requires write permissions on the target group object.

func (*LDAP) AddUserToGroupContext added in v1.1.0

func (l *LDAP) AddUserToGroupContext(ctx context.Context, dn, groupDN string) error

AddUserToGroupContext adds a user to a group by modifying the group's member attribute with context support.

Parameters:

  • ctx: Context for controlling the operation timeout and cancellation
  • dn: The distinguished name of the user to add to the group
  • groupDN: The distinguished name of the group to modify

Returns:

  • error: Any LDAP operation error, including insufficient permissions, if the user is already a member, or context cancellation error

This operation requires write permissions on the target group object.

func (*LDAP) BulkCreateUsers added in v1.2.0

func (l *LDAP) BulkCreateUsers(users []FullUser, password string) ([]WorkResult[FullUser], error)

BulkCreateUsers creates multiple users in LDAP using concurrent operations.

Parameters:

  • users: Array of FullUser objects to create
  • password: Default password for all users (if empty, users will have no password)

Returns:

  • []WorkResult[FullUser]: Results for each user creation attempt, including success/failure status
  • error: Critical error that prevented the operation from starting

This method uses a worker pool to create users concurrently for improved performance. Each user creation is attempted independently, so some may succeed while others fail.

func (*LDAP) BulkCreateUsersContext added in v1.2.0

func (l *LDAP) BulkCreateUsersContext(ctx context.Context, users []FullUser, password string, config *WorkerPoolConfig) ([]WorkResult[FullUser], error)

BulkCreateUsersContext creates multiple users with context and configurable concurrency.

Parameters:

  • ctx: Context for controlling the operation timeout and cancellation
  • users: Array of FullUser objects to create
  • password: Default password for all users
  • config: Optional worker pool configuration (uses defaults if nil)

Returns:

  • []WorkResult[FullUser]: Results for each user creation attempt
  • error: Critical error that prevented the operation from starting

func (*LDAP) BulkDeleteUsers added in v1.2.0

func (l *LDAP) BulkDeleteUsers(dns []string) ([]WorkResult[string], error)

BulkDeleteUsers deletes multiple users from LDAP using concurrent operations.

Parameters:

  • dns: Array of distinguished names to delete

Returns:

  • []WorkResult[string]: Results for each deletion attempt
  • error: Critical error that prevented the operation from starting

Warning: This operation is irreversible. Ensure you have proper backups before deletion.

func (*LDAP) BulkDeleteUsersContext added in v1.2.0

func (l *LDAP) BulkDeleteUsersContext(ctx context.Context, dns []string, config *WorkerPoolConfig) ([]WorkResult[string], error)

BulkDeleteUsersContext deletes multiple users with context and configurable concurrency.

Parameters:

  • ctx: Context for controlling the operation timeout and cancellation
  • dns: Array of distinguished names to delete
  • config: Optional worker pool configuration (uses defaults if nil)

Returns:

  • []WorkResult[string]: Results for each deletion attempt
  • error: Critical error that prevented the operation from starting

func (*LDAP) BulkFindUsersBySAMAccountName added in v1.1.0

func (l *LDAP) BulkFindUsersBySAMAccountName(ctx context.Context, samAccountNames []string, options *BulkSearchOptions) (map[string]*User, error)

BulkFindUsersBySAMAccountName searches for multiple users by their SAM account names in bulk. This method optimizes performance by batching requests and using concurrent searches.

Parameters:

  • ctx: The context for the operation
  • samAccountNames: List of SAM account names to search for
  • options: Bulk search options for controlling batch size, concurrency, and caching

Returns:

  • map[string]*User: A map of SAM account name to User object for found users
  • error: Any error encountered during the bulk search

func (*LDAP) BulkModifyUsers added in v1.2.0

func (l *LDAP) BulkModifyUsers(modifications []UserModification) ([]WorkResult[UserModification], error)

BulkModifyUsers modifies multiple users in LDAP using concurrent operations.

Parameters:

  • modifications: Array of UserModification objects describing the changes

Returns:

  • []WorkResult[UserModification]: Results for each modification attempt
  • error: Critical error that prevented the operation from starting

func (*LDAP) BulkModifyUsersContext added in v1.2.0

func (l *LDAP) BulkModifyUsersContext(ctx context.Context, modifications []UserModification, config *WorkerPoolConfig) ([]WorkResult[UserModification], error)

BulkModifyUsersContext modifies multiple users with context and configurable concurrency.

Parameters:

  • ctx: Context for controlling the operation timeout and cancellation
  • modifications: Array of UserModification objects describing the changes
  • config: Optional worker pool configuration (uses defaults if nil)

Returns:

  • []WorkResult[UserModification]: Results for each modification attempt
  • error: Critical error that prevented the operation from starting

func (*LDAP) ChangePasswordForSAMAccountName

func (l *LDAP) ChangePasswordForSAMAccountName(sAMAccountName, oldPassword, newPassword string) (err error)

ChangePasswordForSAMAccountName changes a user's password in Active Directory. This method requires the current password for authentication and changes it to the new password.

Parameters:

  • sAMAccountName: The Security Account Manager account name of the user
  • oldPassword: The current password (required for authentication)
  • newPassword: The new password to set

Returns:

  • error: ErrActiveDirectoryMustBeLDAPS if trying to change AD passwords over unencrypted connection, ErrUserNotFound if user doesn't exist, authentication error if old password is wrong, or any other LDAP operation error

Requirements:

  • For Active Directory servers, LDAPS (SSL/TLS) connection is mandatory
  • User must provide their current password for verification
  • New password must meet the domain's password policy requirements

The password change uses the Microsoft-specific unicodePwd attribute with proper UTF-16LE encoding. Reference: https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-adts/6e803168-f140-4d23-b2d3-c3a8ab5917d2

func (*LDAP) ChangePasswordForSAMAccountNameContext added in v1.1.0

func (l *LDAP) ChangePasswordForSAMAccountNameContext(ctx context.Context, sAMAccountName, oldPassword, newPassword string) (err error)

ChangePasswordForSAMAccountNameContext changes a user's password in Active Directory with context support. This method requires the current password for authentication and changes it to the new password.

Parameters:

  • ctx: Context for controlling the operation timeout and cancellation
  • sAMAccountName: The Security Account Manager account name of the user
  • oldPassword: The current password (required for authentication)
  • newPassword: The new password to set

Returns:

  • error: ErrActiveDirectoryMustBeLDAPS if trying to change AD passwords over unencrypted connection, ErrUserNotFound if user doesn't exist, authentication error if old password is wrong, context cancellation error, or any other LDAP operation error

Requirements:

  • For Active Directory servers, LDAPS (SSL/TLS) connection is mandatory
  • User must provide their current password for verification
  • New password must meet the domain's password policy requirements

The password change uses the Microsoft-specific unicodePwd attribute with proper UTF-16LE encoding. Reference: https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-adts/6e803168-f140-4d23-b2d3-c3a8ab5917d2

func (*LDAP) CheckPasswordForDN

func (l *LDAP) CheckPasswordForDN(dn, password string) (*User, error)

CheckPasswordForDN validates a user's password by attempting to bind with their credentials. This method finds the user by their distinguished name and then attempts authentication.

Parameters:

  • dn: The distinguished name of the user (e.g., "CN=John Doe,CN=Users,DC=example,DC=com")
  • password: The password to validate

Returns:

  • *User: The user object if authentication succeeds
  • error: ErrUserNotFound if the user doesn't exist, or authentication error if credentials are invalid

This method is useful when you already have the user's DN and want to validate their password.

func (*LDAP) CheckPasswordForDNContext added in v1.1.0

func (l *LDAP) CheckPasswordForDNContext(ctx context.Context, dn, password string) (*User, error)

CheckPasswordForDNContext validates a user's password by attempting to bind with their credentials. This method finds the user by their distinguished name and then attempts authentication.

Parameters:

  • ctx: Context for controlling the operation timeout and cancellation
  • dn: The distinguished name of the user (e.g., "CN=John Doe,CN=Users,DC=example,DC=com")
  • password: The password to validate

Returns:

  • *User: The user object if authentication succeeds
  • error: ErrUserNotFound if the user doesn't exist, authentication error if credentials are invalid, or context cancellation error

This method is useful when you already have the user's DN and want to validate their password.

func (*LDAP) CheckPasswordForSAMAccountName

func (l *LDAP) CheckPasswordForSAMAccountName(sAMAccountName, password string) (*User, error)

CheckPasswordForSAMAccountName validates a user's password by attempting to bind with their credentials. This method finds the user by their sAMAccountName and then attempts authentication.

Parameters:

  • sAMAccountName: The Security Account Manager account name (e.g., "jdoe" for john.doe@domain.com)
  • password: The password to validate

Returns:

  • *User: The user object if authentication succeeds
  • error: ErrUserNotFound if the user doesn't exist, or authentication error if credentials are invalid

This is commonly used for login validation in Active Directory environments.

func (*LDAP) CheckPasswordForSAMAccountNameContext added in v1.1.0

func (l *LDAP) CheckPasswordForSAMAccountNameContext(ctx context.Context, sAMAccountName, password string) (*User, error)

CheckPasswordForSAMAccountNameContext validates a user's password by attempting to bind with their credentials. This method finds the user by their sAMAccountName and then attempts authentication.

Parameters:

  • ctx: Context for controlling the operation timeout and cancellation
  • sAMAccountName: The Security Account Manager account name (e.g., "jdoe" for john.doe@domain.com)
  • password: The password to validate

Returns:

  • *User: The user object if authentication succeeds
  • error: ErrUserNotFound if the user doesn't exist, authentication error if credentials are invalid, or context cancellation error

This is commonly used for login validation in Active Directory environments.

func (*LDAP) Close added in v1.1.0

func (l *LDAP) Close() error

Close closes the LDAP client and cleans up resources. This method properly closes connection pools, caches, and other resources.

Returns:

  • error: Any error encountered during cleanup

func (*LDAP) CreateUser

func (l *LDAP) CreateUser(user FullUser, password string) (string, error)

CreateUser creates a new user in the directory with the specified attributes.

Parameters:

  • user: The FullUser object containing all user attributes
  • password: The initial password for the user (currently not implemented in this version)

Returns:

  • string: The distinguished name of the created user
  • error: Any LDAP operation error, including duplicate entries or insufficient permissions

Default behaviors:

  • ObjectClasses defaults to ["top", "person", "organizationalPerson", "user"] if not specified
  • DisplayName defaults to CN if not specified
  • The user is created at the specified Path relative to BaseDN, or directly under BaseDN if Path is nil

Example:

user := FullUser{
    CN: "John Doe",
    FirstName: "John",
    LastName: "Doe",
    SAMAccountName: &"jdoe",
    Email: &"john.doe@example.com",
    UserAccountControl: UAC{NormalAccount: true},
}
dn, err := client.CreateUser(user, "")

func (*LDAP) CreateUserContext added in v1.1.0

func (l *LDAP) CreateUserContext(ctx context.Context, user FullUser, password string) (dn string, err error)

CreateUserContext creates a new user in the directory with the specified attributes with context support.

Parameters:

  • ctx: Context for controlling the operation timeout and cancellation
  • user: The FullUser object containing all user attributes
  • password: The initial password for the user (currently not implemented in this version)

Returns:

  • string: The distinguished name of the created user
  • error: Any LDAP operation error, including duplicate entries, insufficient permissions, or context cancellation error

Default behaviors:

  • ObjectClasses defaults to ["top", "person", "organizationalPerson", "user"] if not specified
  • DisplayName defaults to CN if not specified
  • The user is created at the specified Path relative to BaseDN, or directly under BaseDN if Path is nil

func (*LDAP) DeleteUser

func (l *LDAP) DeleteUser(dn string) error

DeleteUser removes a user from the directory.

Parameters:

  • dn: The distinguished name of the user to delete

Returns:

  • error: Any LDAP operation error, including user not found or insufficient permissions

Warning: This operation is irreversible. Ensure you have proper backups and permissions before deletion.

func (*LDAP) DeleteUserContext added in v1.1.0

func (l *LDAP) DeleteUserContext(ctx context.Context, dn string) (err error)

DeleteUserContext removes a user from the directory with context support.

Parameters:

  • ctx: Context for controlling the operation timeout and cancellation
  • dn: The distinguished name of the user to delete

Returns:

  • error: Any LDAP operation error, including user not found, insufficient permissions, or context cancellation error

Warning: This operation is irreversible. Ensure you have proper backups and permissions before deletion.

func (*LDAP) FindComputerByDN

func (l *LDAP) FindComputerByDN(dn string) (computer *Computer, err error)

FindComputerByDN retrieves a computer by its distinguished name.

Parameters:

  • dn: The distinguished name of the computer (e.g., "CN=COMPUTER01,CN=Computers,DC=example,DC=com")

Returns:

  • *Computer: The computer object if found
  • error: ErrComputerNotFound if no computer exists with the given DN, ErrDNDuplicated if multiple entries share the same DN (data integrity issue), or any LDAP operation error

func (*LDAP) FindComputerByDNContext added in v1.1.0

func (l *LDAP) FindComputerByDNContext(ctx context.Context, dn string) (computer *Computer, err error)

FindComputerByDNContext retrieves a computer by its distinguished name with context support.

Parameters:

  • ctx: Context for controlling the operation timeout and cancellation
  • dn: The distinguished name of the computer (e.g., "CN=COMPUTER01,CN=Computers,DC=example,DC=com")

Returns:

  • *Computer: The computer object if found
  • error: ErrComputerNotFound if no computer exists with the given DN, ErrDNDuplicated if multiple entries share the same DN (data integrity issue), context cancellation error, or any LDAP operation error

func (*LDAP) FindComputerBySAMAccountName

func (l *LDAP) FindComputerBySAMAccountName(sAMAccountName string) (computer *Computer, err error)

FindComputerBySAMAccountName retrieves a computer by its Security Account Manager account name.

Parameters:

  • sAMAccountName: The SAM account name of the computer (e.g., "COMPUTER01$")

Returns:

  • *Computer: The computer object if found
  • error: ErrComputerNotFound if no computer exists with the given sAMAccountName, ErrSAMAccountNameDuplicated if multiple computers have the same sAMAccountName, or any LDAP operation error

This method performs a subtree search starting from the configured BaseDN. Computer sAMAccountNames typically end with a dollar sign ($).

func (*LDAP) FindComputerBySAMAccountNameContext added in v1.1.0

func (l *LDAP) FindComputerBySAMAccountNameContext(ctx context.Context, sAMAccountName string) (computer *Computer, err error)

FindComputerBySAMAccountNameContext retrieves a computer by its Security Account Manager account name with context support.

Parameters:

  • ctx: Context for controlling the operation timeout and cancellation
  • sAMAccountName: The SAM account name of the computer (e.g., "COMPUTER01$")

Returns:

  • *Computer: The computer object if found
  • error: ErrComputerNotFound if no computer exists with the given sAMAccountName, ErrSAMAccountNameDuplicated if multiple computers have the same sAMAccountName, context cancellation error, or any LDAP operation error

This method performs a subtree search starting from the configured BaseDN. Computer sAMAccountNames typically end with a dollar sign ($).

func (*LDAP) FindComputers

func (l *LDAP) FindComputers() (computers []Computer, err error)

FindComputers retrieves all computer objects from the directory.

Returns:

  • []Computer: A slice of all computer objects found in the directory
  • error: Any LDAP operation error

This method performs a subtree search starting from the configured BaseDN. Computers that cannot be parsed (due to missing required attributes) are skipped.

func (*LDAP) FindComputersContext added in v1.1.0

func (l *LDAP) FindComputersContext(ctx context.Context) (computers []Computer, err error)

FindComputersContext retrieves all computer objects from the directory with context support.

Parameters:

  • ctx: Context for controlling the operation timeout and cancellation

Returns:

  • []Computer: A slice of all computer objects found in the directory
  • error: Any LDAP operation error or context cancellation error

This method performs a subtree search starting from the configured BaseDN. Computers that cannot be parsed (due to missing required attributes) are skipped.

func (*LDAP) FindGroupByDN

func (l *LDAP) FindGroupByDN(dn string) (group *Group, err error)

FindGroupByDN retrieves a group by its distinguished name.

Parameters:

  • dn: The distinguished name of the group (e.g., "CN=Administrators,CN=Builtin,DC=example,DC=com")

Returns:

  • *Group: The group object if found
  • error: ErrGroupNotFound if no group exists with the given DN, ErrDNDuplicated if multiple entries share the same DN (data integrity issue), or any LDAP operation error

func (*LDAP) FindGroupByDNContext added in v1.1.0

func (l *LDAP) FindGroupByDNContext(ctx context.Context, dn string) (group *Group, err error)

FindGroupByDNContext retrieves a group by its distinguished name with context support.

Parameters:

  • ctx: Context for controlling the operation timeout and cancellation
  • dn: The distinguished name of the group (e.g., "CN=Administrators,CN=Builtin,DC=example,DC=com")

Returns:

  • *Group: The group object if found
  • error: ErrGroupNotFound if no group exists with the given DN, ErrDNDuplicated if multiple entries share the same DN (data integrity issue), context cancellation error, or any LDAP operation error

func (*LDAP) FindGroups

func (l *LDAP) FindGroups() (groups []Group, err error)

FindGroups retrieves all group objects from the directory.

Returns:

  • []Group: A slice of all group objects found in the directory
  • error: Any LDAP operation error

This method performs a subtree search starting from the configured BaseDN. Groups that cannot be parsed are skipped and not included in the results.

func (*LDAP) FindGroupsContext added in v1.1.0

func (l *LDAP) FindGroupsContext(ctx context.Context) (groups []Group, err error)

FindGroupsContext retrieves all group objects from the directory with context support.

Parameters:

  • ctx: Context for controlling the operation timeout and cancellation

Returns:

  • []Group: A slice of all group objects found in the directory
  • error: Any LDAP operation error or context cancellation error

This method performs a subtree search starting from the configured BaseDN. Groups that cannot be parsed are skipped and not included in the results.

func (*LDAP) FindUserByDN

func (l *LDAP) FindUserByDN(dn string) (user *User, err error)

FindUserByDN retrieves a user by their distinguished name.

Parameters:

  • dn: The distinguished name of the user (e.g., "CN=John Doe,CN=Users,DC=example,DC=com")

Returns:

  • *User: The user object if found
  • error: ErrUserNotFound if no user exists with the given DN, ErrDNDuplicated if multiple entries share the same DN (data integrity issue), or any LDAP operation error

func (*LDAP) FindUserByDNContext added in v1.1.0

func (l *LDAP) FindUserByDNContext(ctx context.Context, dn string) (user *User, err error)

FindUserByDNContext retrieves a user by their distinguished name with context support.

Parameters:

  • ctx: Context for controlling the operation timeout and cancellation
  • dn: The distinguished name of the user (e.g., "CN=John Doe,CN=Users,DC=example,DC=com")

Returns:

  • *User: The user object if found
  • error: ErrUserNotFound if no user exists with the given DN, ErrDNDuplicated if multiple entries share the same DN (data integrity issue), context cancellation error, or any LDAP operation error

func (*LDAP) FindUserByMail

func (l *LDAP) FindUserByMail(mail string) (user *User, err error)

FindUserByMail retrieves a user by their email address.

Parameters:

  • mail: The email address to search for (e.g., "john.doe@example.com")

Returns:

  • *User: The user object if found
  • error: ErrUserNotFound if no user exists with the given email, ErrMailDuplicated if multiple users have the same email address, or any LDAP operation error

This method performs a subtree search starting from the configured BaseDN.

func (*LDAP) FindUserByMailContext added in v1.1.0

func (l *LDAP) FindUserByMailContext(ctx context.Context, mail string) (user *User, err error)

FindUserByMailContext retrieves a user by their email address with context support.

Parameters:

  • ctx: Context for controlling the operation timeout and cancellation
  • mail: The email address to search for (e.g., "john.doe@example.com")

Returns:

  • *User: The user object if found
  • error: ErrUserNotFound if no user exists with the given email, ErrMailDuplicated if multiple users have the same email address, context cancellation error, or any LDAP operation error

This method performs a subtree search starting from the configured BaseDN.

func (*LDAP) FindUserBySAMAccountName

func (l *LDAP) FindUserBySAMAccountName(sAMAccountName string) (user *User, err error)

FindUserBySAMAccountName retrieves a user by their Security Account Manager account name.

Parameters:

  • sAMAccountName: The SAM account name (e.g., "jdoe" for john.doe@domain.com)

Returns:

  • *User: The user object if found
  • error: ErrUserNotFound if no user exists with the given sAMAccountName, ErrSAMAccountNameDuplicated if multiple users have the same sAMAccountName, or any LDAP operation error

This method performs a subtree search starting from the configured BaseDN. For OpenLDAP compatibility, it also searches for uid attribute when sAMAccountName is not found.

func (*LDAP) FindUserBySAMAccountNameContext added in v1.1.0

func (l *LDAP) FindUserBySAMAccountNameContext(ctx context.Context, sAMAccountName string) (user *User, err error)

FindUserBySAMAccountNameContext retrieves a user by their Security Account Manager account name with context support.

Parameters:

  • ctx: Context for controlling the operation timeout and cancellation
  • sAMAccountName: The SAM account name (e.g., "jdoe" for john.doe@domain.com)

Returns:

  • *User: The user object if found
  • error: ErrUserNotFound if no user exists with the given sAMAccountName, ErrSAMAccountNameDuplicated if multiple users have the same sAMAccountName, context cancellation error, or any LDAP operation error

This method performs a subtree search starting from the configured BaseDN. For OpenLDAP compatibility, it also searches for uid attribute when sAMAccountName is not found.

func (*LDAP) FindUsers

func (l *LDAP) FindUsers() (users []User, err error)

FindUsers retrieves all user objects from the directory.

Returns:

  • []User: A slice of all user objects found in the directory
  • error: Any LDAP operation error

This method performs a subtree search starting from the configured BaseDN. Users that cannot be parsed (due to missing required attributes) are skipped.

func (*LDAP) FindUsersBySAMAccountNames added in v1.3.0

func (l *LDAP) FindUsersBySAMAccountNames(sAMAccountNames []string) ([]*User, error)

FindUsersBySAMAccountNames retrieves multiple users by their Security Account Manager account names. This is a convenience method for batch user lookups, commonly used in scenarios where operations need to be performed on multiple users simultaneously (e.g., admin panels, bulk operations, reporting).

Parameters:

  • sAMAccountNames: A slice of SAM account names to search for (e.g., ["jdoe", "asmith", "bjones"])

Returns:

  • []*User: A slice of user objects for found users (may be shorter than input if some users don't exist)
  • error: Returns error only for system failures (connection errors, invalid configuration, etc.) Individual user lookup failures result in that user being omitted from the results

Example:

// Lookup multiple users for batch operations
names := []string{"admin", "jdoe", "asmith"}
users, err := client.FindUsersBySAMAccountNames(names)
if err != nil {
    // Handle connection/system errors
    log.Fatal(err)
}
// Users slice contains only found users (may be 0-3 users)
for _, user := range users {
    fmt.Printf("Found: %s (%s)\n", user.SAMAccountName, user.DN())
}

Note: This method returns partial results - if some users are not found, they are silently omitted from the results. Check the length of returned slice against input to detect missing users. For detailed error handling per user, use individual FindUserBySAMAccountName calls.

func (*LDAP) FindUsersBySAMAccountNamesContext added in v1.3.0

func (l *LDAP) FindUsersBySAMAccountNamesContext(ctx context.Context, sAMAccountNames []string) ([]*User, error)

FindUsersBySAMAccountNamesContext retrieves multiple users by their Security Account Manager account names with context support for timeout and cancellation control.

Parameters:

  • ctx: Context for controlling the operation timeout and cancellation
  • sAMAccountNames: A slice of SAM account names to search for

Returns:

  • []*User: A slice of user objects for found users
  • error: Returns error only for context cancellation or system failures

This method looks up users sequentially. Individual lookup failures result in that user being omitted from the results. The context can be used to set a timeout for the entire operation or cancel it midway through.

func (*LDAP) FindUsersContext added in v1.1.0

func (l *LDAP) FindUsersContext(ctx context.Context) (users []User, err error)

FindUsersContext retrieves all user objects from the directory with context support.

Parameters:

  • ctx: Context for controlling the operation timeout and cancellation

Returns:

  • []User: A slice of all user objects found in the directory
  • error: Any LDAP operation error or context cancellation error

This method performs a subtree search starting from the configured BaseDN. Users that cannot be parsed (due to missing required attributes) are skipped.

func (*LDAP) GetCacheStats added in v1.1.0

func (l *LDAP) GetCacheStats() *CacheStats

GetCacheStats returns cache statistics

func (*LDAP) GetCircuitBreakerStats added in v1.2.0

func (l *LDAP) GetCircuitBreakerStats() map[string]interface{}

GetCircuitBreakerStats returns circuit breaker statistics if configured. Returns nil if circuit breaker is not enabled.

func (*LDAP) GetConnection

func (l *LDAP) GetConnection() (*ldap.Conn, error)

GetConnection returns a new LDAP connection

func (*LDAP) GetConnectionContext added in v1.1.0

func (l *LDAP) GetConnectionContext(ctx context.Context) (*ldap.Conn, error)

GetConnectionContext returns a new LDAP connection with context

func (*LDAP) GetConnectionProtected added in v1.2.0

func (l *LDAP) GetConnectionProtected() (*ldap.Conn, error)

GetConnectionProtected returns a new LDAP connection with circuit breaker protection. If a circuit breaker is configured and the circuit is OPEN, it will return immediately with a CircuitBreakerError instead of attempting to connect. This provides fast failure and prevents connection storms when the LDAP server is down.

func (*LDAP) GetConnectionProtectedContext added in v1.2.0

func (l *LDAP) GetConnectionProtectedContext(ctx context.Context) (*ldap.Conn, error)

GetConnectionProtectedContext returns a new LDAP connection with context and circuit breaker protection. If circuit breaker is not configured, it falls back to regular GetConnectionContext.

func (*LDAP) GetPerformanceStats added in v1.1.0

func (l *LDAP) GetPerformanceStats() PerformanceStats

GetPerformanceStats returns detailed performance statistics for LDAP operations.

Returns:

  • PerformanceStats: Comprehensive performance metrics including timing, cache hit ratios, error counts, and resource usage

The returned statistics include:

  • Operation counts and timing percentiles (P50, P95, P99)
  • Cache hit/miss ratios and slow query detection
  • Memory usage and goroutine counts
  • Operation breakdown by type and error statistics

This method provides detailed insights into the performance characteristics of LDAP operations, including timing percentiles, cache hit ratios, and slow query detection.

func (*LDAP) GetPoolStats added in v1.1.0

func (l *LDAP) GetPoolStats() PerformanceStats

GetPoolStats returns pool statistics for backward compatibility. This method is an alias for GetPerformanceStats().

Returns:

  • PerformanceStats: Performance and pool statistics

func (*LDAP) GroupMembersIter added in v1.2.0

func (l *LDAP) GroupMembersIter(ctx context.Context, groupDN string) iter.Seq2[string, error]

GroupMembersIter returns an iterator over group members. This efficiently handles large groups without loading all members into memory.

func (*LDAP) ModifyUser added in v1.2.0

func (l *LDAP) ModifyUser(dn string, attributes map[string][]string) error

ModifyUser modifies attributes of an existing user in the directory.

Parameters:

  • dn: The distinguished name of the user to modify
  • attributes: Map of attributes to modify (key: attribute name, value: new values)

Returns:

  • error: Any LDAP operation error, including user not found or insufficient permissions

Example:

attributes := map[string][]string{
    "mail": {"newemail@example.com"},
    "description": {"Updated description"},
}
err := client.ModifyUser("uid=jdoe,ou=users,dc=example,dc=com", attributes)

func (*LDAP) ModifyUserContext added in v1.2.0

func (l *LDAP) ModifyUserContext(ctx context.Context, dn string, attributes map[string][]string) (err error)

ModifyUserContext modifies attributes of an existing user with context support.

Parameters:

  • ctx: Context for controlling the operation timeout and cancellation
  • dn: The distinguished name of the user to modify
  • attributes: Map of attributes to modify (key: attribute name, value: new values)

Returns:

  • error: Any LDAP operation error, including user not found, insufficient permissions, or context cancellation error

func (*LDAP) ReleaseConnection added in v1.5.2

func (l *LDAP) ReleaseConnection(conn *ldap.Conn) error

ReleaseConnection properly returns a connection to the pool or closes it if no pool exists. This method should be used in defer statements instead of directly calling conn.Close() to ensure proper connection lifecycle management with connection pools.

Parameters:

  • conn: The LDAP connection to release

Returns:

  • error: Any error encountered during release/close

Example:

conn, err := l.GetConnectionContext(ctx)
if err != nil {
    return err
}
defer l.ReleaseConnection(conn)

func (*LDAP) RemoveUserFromGroup

func (l *LDAP) RemoveUserFromGroup(dn, groupDN string) error

RemoveUserFromGroup removes a user from a group by modifying the group's member attribute.

Parameters:

  • dn: The distinguished name of the user to remove from the group
  • groupDN: The distinguished name of the group to modify

Returns:

  • error: Any LDAP operation error, including insufficient permissions or if the user is not a member

This operation requires write permissions on the target group object.

func (*LDAP) RemoveUserFromGroupContext added in v1.1.0

func (l *LDAP) RemoveUserFromGroupContext(ctx context.Context, dn, groupDN string) error

RemoveUserFromGroupContext removes a user from a group by modifying the group's member attribute with context support.

Parameters:

  • ctx: Context for controlling the operation timeout and cancellation
  • dn: The distinguished name of the user to remove from the group
  • groupDN: The distinguished name of the group to modify

Returns:

  • error: Any LDAP operation error, including insufficient permissions, if the user is not a member, or context cancellation error

This operation requires write permissions on the target group object.

func (*LDAP) ResetPasswordForSAMAccountName added in v1.6.0

func (l *LDAP) ResetPasswordForSAMAccountName(sAMAccountName, newPassword string) error

ResetPasswordForSAMAccountName performs an administrative password reset for a user. This method does NOT require the old password and is intended for administrative password reset operations.

Parameters:

  • sAMAccountName: The Security Account Manager account name of the user
  • newPassword: The new password to set

Returns:

  • error: ErrActiveDirectoryMustBeLDAPS if trying to reset AD passwords over unencrypted connection, ErrUserNotFound if user doesn't exist, or any other LDAP operation error

Requirements:

  • For Active Directory servers, LDAPS (SSL/TLS) connection is mandatory
  • The service account must have "Reset password" permission on the target user object
  • New password must meet the domain's password policy requirements

Security Notes:

  • This is an administrative operation that bypasses old password verification
  • Requires elevated LDAP permissions (Reset password permission in AD)
  • Should only be used for password reset workflows, not regular password changes
  • Best practice: Use a dedicated service account with minimal permissions (only password reset)

The password reset uses the Microsoft-specific unicodePwd attribute with proper UTF-16LE encoding. Reference: https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-adts/6e803168-f140-4d23-b2d3-c3a8ab5917d2

func (*LDAP) ResetPasswordForSAMAccountNameContext added in v1.6.0

func (l *LDAP) ResetPasswordForSAMAccountNameContext(ctx context.Context, sAMAccountName, newPassword string) error

ResetPasswordForSAMAccountNameContext performs an administrative password reset with context support.

func (*LDAP) SearchIter added in v1.2.0

func (l *LDAP) SearchIter(ctx context.Context, searchRequest *ldap.SearchRequest) iter.Seq2[*ldap.Entry, error]

SearchIter performs an LDAP search and returns an iterator over the results. This allows for memory-efficient processing of large result sets. The iterator supports early termination by the caller. If circuit breaker is configured, it provides fast failure when LDAP is down.

func (*LDAP) SearchPagedIter added in v1.2.0

func (l *LDAP) SearchPagedIter(ctx context.Context, searchRequest *ldap.SearchRequest, pageSize uint32) iter.Seq2[*ldap.Entry, error]

SearchPagedIter performs a paged LDAP search and returns an iterator. This is more memory-efficient for very large result sets as it fetches results in chunks from the server. If circuit breaker is configured, it provides fast failure when LDAP is down.

func (*LDAP) WithCredentials

func (l *LDAP) WithCredentials(dn, password string) (*LDAP, error)

WithCredentials creates a new LDAP client with different credentials. This method allows for creating a client authenticated as a different user while maintaining the same configuration and connection settings.

Parameters:

  • dn: The distinguished name (DN) for the new credentials
  • password: The password for the new credentials

Returns:

  • *LDAP: A new LDAP client authenticated with the provided credentials
  • error: Any error encountered during client creation

type LDAPError added in v1.1.0

type LDAPError struct {
	// Op is the operation name (e.g., "FindUserBySAMAccountName", "CheckPassword")
	Op string
	// DN is the distinguished name involved in the operation (if applicable)
	DN string
	// Server is the LDAP server URL
	Server string
	// Code is the LDAP result code (if applicable)
	Code int
	// Err is the underlying error
	Err error
	// Context contains additional context information for debugging
	Context map[string]interface{}

	// Timestamp indicates when the error occurred
	Timestamp time.Time
	// contains filtered or unexported fields
}

LDAPError represents an enhanced error with rich context for LDAP operations. It wraps underlying errors while providing operation-specific context for debugging.

Example

ExampleLDAPError demonstrates how to use enhanced error handling

// Simulate an authentication failure
baseErr := &ldap.Error{ResultCode: ldap.LDAPResultInvalidCredentials}

// Wrap with enhanced context
enhancedErr := WrapLDAPError("AuthenticateUser", "ldaps://ad.company.com", baseErr)

// Check error type
if IsAuthenticationError(enhancedErr) {
	fmt.Println("Authentication failed")
}

// Get severity for logging
severity := GetErrorSeverity(enhancedErr)
fmt.Printf("Error severity: %s\n", severity)

// Check if retryable
if IsRetryable(enhancedErr) {
	fmt.Println("This error might be resolved by retrying")
} else {
	fmt.Println("This error requires different credentials or configuration")
}
Output:

Authentication failed
Error severity: ERROR
This error requires different credentials or configuration

func NewLDAPError added in v1.1.0

func NewLDAPError(op, server string, err error) *LDAPError

NewLDAPError creates a new enhanced LDAP error with the specified operation, server, and underlying error. The error includes a timestamp and empty context map for additional information.

func (*LDAPError) Error added in v1.1.0

func (e *LDAPError) Error() string

Error implements the error interface, providing a formatted error message. Sensitive information is masked to prevent data leakage in logs.

func (*LDAPError) Is added in v1.1.0

func (e *LDAPError) Is(target error) bool

Is implements the Go 1.13+ error comparison interface for compatibility with errors.Is.

func (*LDAPError) UnmaskedError added in v1.1.0

func (e *LDAPError) UnmaskedError() string

UnmaskedError returns the error message without masking sensitive data. This method is intended for testing and debugging purposes only.

func (*LDAPError) Unwrap added in v1.1.0

func (e *LDAPError) Unwrap() error

Unwrap implements the Go 1.13+ error unwrapping interface.

func (*LDAPError) WithCode added in v1.1.0

func (e *LDAPError) WithCode(code int) *LDAPError

WithCode adds an LDAP result code to the error context.

func (*LDAPError) WithContext added in v1.1.0

func (e *LDAPError) WithContext(key string, value interface{}) *LDAPError

WithContext adds additional context information to the error. This method is thread-safe.

func (*LDAPError) WithDN added in v1.1.0

func (e *LDAPError) WithDN(dn string) *LDAPError

WithDN adds a distinguished name to the error context.

type LDAPObject added in v1.1.0

type LDAPObject interface {
	// DN returns the distinguished name of the object
	DN() string
	// CN returns the common name of the object
	CN() string
}

LDAPObject defines the constraint for all LDAP objects that can be used with generic functions. This interface ensures type safety for LDAP operations while providing common methods.

type LDAPObjectPtr added in v1.1.0

type LDAPObjectPtr[T LDAPObject] interface {
	*T
}

LDAPObjectPtr defines a constraint for pointers to LDAP objects. This is used for generic functions that need to work with object pointers.

type LRUCache added in v1.1.0

type LRUCache struct {
	// contains filtered or unexported fields
}

LRUCache implements an intelligent LRU cache with advanced features

func NewLRUCache added in v1.1.0

func NewLRUCache(config *CacheConfig, logger *slog.Logger) (*LRUCache, error)

NewLRUCache creates a new LRU cache with the specified configuration

func (*LRUCache) Clear added in v1.1.0

func (c *LRUCache) Clear()

Clear removes all entries from the cache

func (*LRUCache) Close added in v1.1.0

func (c *LRUCache) Close() error

Close shuts down the cache and releases resources

func (*LRUCache) Delete added in v1.1.0

func (c *LRUCache) Delete(key string) bool

Delete removes a value from the cache

func (*LRUCache) Get added in v1.1.0

func (c *LRUCache) Get(key string) (interface{}, bool)

Get retrieves a value from the cache

func (*LRUCache) GetContext added in v1.1.0

func (c *LRUCache) GetContext(ctx context.Context, key string) (interface{}, bool)

GetContext retrieves a value from the cache with context support

func (*LRUCache) GetRelatedKeys added in v1.2.0

func (c *LRUCache) GetRelatedKeys(primaryKey string) []string

GetRelatedKeys returns all cache keys associated with a primary key

func (*LRUCache) GetWithRefresh added in v1.1.0

func (c *LRUCache) GetWithRefresh(key string, refreshFunc func() (interface{}, error)) (interface{}, error)

GetWithRefresh retrieves a value, refreshing it if stale

func (*LRUCache) InvalidateByPrimaryKey added in v1.2.0

func (c *LRUCache) InvalidateByPrimaryKey(primaryKey string) int

InvalidateByPrimaryKey invalidates all cache entries related to a primary key This is efficient as it doesn't require fetching the cached object

func (*LRUCache) RegisterCacheKey added in v1.2.0

func (c *LRUCache) RegisterCacheKey(primaryKey string, cacheKey string)

RegisterCacheKey registers a cache key with its primary identifier This allows efficient invalidation without needing to fetch the cached object

func (*LRUCache) Set added in v1.1.0

func (c *LRUCache) Set(key string, value interface{}, ttl time.Duration) error

Set stores a value in the cache with the specified TTL

func (*LRUCache) SetContext added in v1.1.0

func (c *LRUCache) SetContext(ctx context.Context, key string, value interface{}, ttl time.Duration) error

SetContext stores a value in the cache with context support

func (*LRUCache) SetNegative added in v1.1.0

func (c *LRUCache) SetNegative(key string, ttl time.Duration) error

SetNegative stores a negative cache entry (for "not found" results)

func (*LRUCache) SetWithPrimaryKey added in v1.2.0

func (c *LRUCache) SetWithPrimaryKey(cacheKey string, value interface{}, ttl time.Duration, primaryKey string) error

SetWithPrimaryKey stores a value in cache and registers it with a primary key

func (*LRUCache) Stats added in v1.1.0

func (c *LRUCache) Stats() CacheStats

Stats returns current cache statistics

type Modifiable added in v1.1.0

type Modifiable[T LDAPObject] interface {
	LDAPObject
	// ToModifyRequest converts changes to an LDAP modify request
	ToModifyRequest(changes map[string][]string) (*ldap.ModifyRequest, error)
	// GetModifiableAttributes returns the attributes that can be modified
	GetModifiableAttributes() []string
}

Modifiable defines the constraint for LDAP objects that can be modified. This extends LDAPObject with modification-specific methods.

type ModifyRequest added in v1.1.0

type ModifyRequest struct {
	DN      string
	Changes []Change
}

ModifyRequest represents a modify request with modern Go patterns.

type MultiError added in v1.1.0

type MultiError struct {
	Errors []error
}

MultiError represents multiple errors that occurred together.

func NewMultiError added in v1.1.0

func NewMultiError(errors ...error) *MultiError

NewMultiError creates a new multi-error from the provided errors.

func (*MultiError) Add added in v1.1.0

func (m *MultiError) Add(err error)

Add appends an error to the multi-error.

func (*MultiError) As added in v1.1.0

func (m *MultiError) As(target interface{}) bool

As implements error type matching for all contained errors.

func (*MultiError) Error added in v1.1.0

func (m *MultiError) Error() string

Error implements the error interface.

func (*MultiError) HasErrors added in v1.1.0

func (m *MultiError) HasErrors() bool

HasErrors returns true if there are any errors.

func (*MultiError) Is added in v1.1.0

func (m *MultiError) Is(target error) bool

Is implements error matching for all contained errors.

func (*MultiError) Unwrap added in v1.1.0

func (m *MultiError) Unwrap() error

Unwrap returns the first error for compatibility with errors.Is/As.

type Object

type Object struct {
	// contains filtered or unexported fields
}

Object represents the base LDAP object with common name and distinguished name.

func (Object) CN

func (o Object) CN() string

CN returns the common name of the object. The common name is the human-readable name component of the distinguished name.

func (Object) DN

func (o Object) DN() string

DN returns the distinguished name of the object. The distinguished name uniquely identifies an object in the LDAP directory tree.

type OperationMetric added in v1.1.0

type OperationMetric struct {
	Operation    string        `json:"operation"`
	StartTime    time.Time     `json:"start_time"`
	Duration     time.Duration `json:"duration"`
	Success      bool          `json:"success"`
	ErrorMessage string        `json:"error_message,omitempty"`
	CacheHit     bool          `json:"cache_hit"`
	ResultCount  int           `json:"result_count"`
	UserAgent    string        `json:"user_agent,omitempty"`
	ClientIP     string        `json:"client_ip,omitempty"`
}

OperationMetric represents metrics for a single operation

type OperationPipeline added in v1.1.0

type OperationPipeline[T LDAPObject] struct {
	// contains filtered or unexported fields
}

OperationPipeline provides a fluent API for chaining LDAP operations with type safety. This is different from the general-purpose Pipeline in concurrency.go

func NewOperationPipeline added in v1.1.0

func NewOperationPipeline[T LDAPObject](ctx context.Context, l *LDAP) *OperationPipeline[T]

NewOperationPipeline creates a new typed pipeline for LDAP operations.

func (*OperationPipeline[T]) Create added in v1.1.0

func (p *OperationPipeline[T]) Create(obj T) *OperationPipeline[T]

Create adds a create operation to the pipeline.

func (*OperationPipeline[T]) Delete added in v1.1.0

func (p *OperationPipeline[T]) Delete(obj T) *OperationPipeline[T]

Delete adds a delete operation to the pipeline.

func (*OperationPipeline[T]) Execute added in v1.1.0

func (p *OperationPipeline[T]) Execute() error

Execute completes the pipeline and returns any accumulated errors.

func (*OperationPipeline[T]) Modify added in v1.1.0

func (p *OperationPipeline[T]) Modify(obj T, changes map[string][]string) *OperationPipeline[T]

Modify adds a modify operation to the pipeline.

type Option added in v1.1.0

type Option func(*LDAP)

Option represents a functional option for configuring an LDAP client. This follows the functional options pattern for flexible and extensible configuration.

func WithCache added in v1.1.0

func WithCache(cacheConfig *CacheConfig) Option

WithCache enables intelligent caching with the specified configuration. Caching improves performance for read-heavy workloads by reducing LDAP server load.

Example:

cacheConfig := &CacheConfig{
    Enabled: true,
    TTL: 5 * time.Minute,
    MaxSize: 1000,
    MaxMemoryMB: 100,
}
client, err := New(config, username, password, WithCache(cacheConfig))

func WithCircuitBreaker added in v1.2.0

func WithCircuitBreaker(config *CircuitBreakerConfig) Option

WithCircuitBreaker enables circuit breaker protection with the given configuration. If config is nil, default configuration will be used.

Example:

client, err := New(config, username, password,
    WithCircuitBreaker(&CircuitBreakerConfig{
        MaxFailures: 5,
        Timeout: 30 * time.Second,
    }))

func WithConnectionOptions added in v1.1.0

func WithConnectionOptions(connOptions *ConnectionOptions) Option

WithConnectionOptions configures connection settings for the LDAP client. This includes timeout settings, retry policies, and other connection-related configurations.

Example:

connConfig := &ConnectionOptions{
    ConnectionTimeout: 30 * time.Second,
    OperationTimeout: 60 * time.Second,
    MaxRetries: 3,
    RetryDelay: 1 * time.Second,
}
client, err := New(config, username, password, WithConnectionOptions(connConfig))

func WithConnectionPool added in v1.1.0

func WithConnectionPool(poolConfig *PoolConfig) Option

WithConnectionPool enables connection pooling with the specified configuration. Connection pooling significantly improves performance for high-volume applications.

Example:

poolConfig := &PoolConfig{
    MaxConnections: 20,
    MinConnections: 5,
    MaxIdleTime: 10 * time.Minute,
    HealthCheckInterval: 1 * time.Minute,
}
client, err := New(config, username, password, WithConnectionPool(poolConfig))

func WithDialOptions added in v1.1.0

func WithDialOptions(dialOpts ...ldap.DialOpt) Option

WithDialOptions adds custom dial options for LDAP connections. This allows fine-grained control over connection establishment.

Example:

dialOpts := []ldap.DialOpt{
    ldap.DialWithDialer(&net.Dialer{Timeout: 10 * time.Second}),
}
client, err := New(config, username, password, WithDialOptions(dialOpts...))

func WithLogger added in v1.1.0

func WithLogger(logger *slog.Logger) Option

WithLogger sets a custom structured logger for LDAP operations. If not provided, a no-op logger will be used.

Example:

logger := slog.New(slog.NewJSONHandler(os.Stdout, nil))
client, err := New(config, username, password, WithLogger(logger))

func WithPerformanceMonitoring added in v1.1.0

func WithPerformanceMonitoring(perfConfig *PerformanceConfig) Option

WithPerformanceMonitoring enables performance monitoring with the specified configuration. Performance monitoring provides detailed metrics and helps identify bottlenecks.

Example:

perfConfig := &PerformanceConfig{
    Enabled: true,
    SlowQueryThreshold: 500 * time.Millisecond,
    MetricsInterval: 1 * time.Minute,
}
client, err := New(config, username, password, WithPerformanceMonitoring(perfConfig))

func WithTLS added in v1.1.0

func WithTLS(tlsConfig *tls.Config) Option

WithTLS configures TLS settings for secure LDAP connections. This option allows fine-grained control over TLS configuration.

Example:

tlsConfig := &tls.Config{
    InsecureSkipVerify: false,
    ServerName: "ldap.example.com",
}
client, err := New(config, username, password, WithTLS(tlsConfig))

func WithTimeout added in v1.1.0

func WithTimeout(connectionTimeout, operationTimeout time.Duration) Option

WithTimeout sets operation timeouts for LDAP operations. This is a convenience option for common timeout scenarios.

The connectionTimeout is used for establishing LDAP connections. The operationTimeout is stored in the LDAP client and can be used to create contexts with timeouts for individual LDAP operations.

Example:

client, err := New(config, username, password,
    WithTimeout(30*time.Second, 60*time.Second))

type PasswordAnalysis added in v1.1.0

type PasswordAnalysis struct {
	Length     int     `json:"length"`
	Strength   float64 `json:"strength"`    // 0.0 to 1.0
	Entropy    float64 `json:"entropy"`     // Bits of entropy
	HasUpper   bool    `json:"has_upper"`   // Contains uppercase letters
	HasLower   bool    `json:"has_lower"`   // Contains lowercase letters
	HasDigit   bool    `json:"has_digit"`   // Contains digits
	HasSpecial bool    `json:"has_special"` // Contains special characters
}

PasswordAnalysis contains analysis results for password strength

type PasswordModifyRequest added in v1.1.0

type PasswordModifyRequest struct {
	UserDN      string
	OldPassword string
	NewPassword string
}

PasswordModifyRequest represents a password modify request with modern Go patterns.

type PasswordValidator added in v1.1.0

type PasswordValidator struct {
	MinLength        int
	RequireUppercase bool
	RequireLowercase bool
	RequireNumbers   bool
	RequireSymbols   bool
	ForbiddenWords   []string
}

PasswordValidator provides password strength validation

func DefaultPasswordValidator added in v1.1.0

func DefaultPasswordValidator() *PasswordValidator

DefaultPasswordValidator returns a validator with strong password requirements

func (*PasswordValidator) ValidatePassword added in v1.1.0

func (pv *PasswordValidator) ValidatePassword(password string) error

ValidatePassword checks if a password meets the security requirements

type PerformanceConfig added in v1.1.0

type PerformanceConfig struct {
	Enabled             bool          `json:"enabled"`               // Enable performance monitoring
	SlowQueryThreshold  time.Duration `json:"slow_query_threshold"`  // Threshold for slow query detection
	MetricsRetention    time.Duration `json:"metrics_retention"`     // How long to keep metrics data
	SampleRate          float64       `json:"sample_rate"`           // Sample rate for detailed metrics (0.0-1.0)
	DetailedMetrics     bool          `json:"detailed_metrics"`      // Enable detailed per-operation metrics
	BufferSize          int           `json:"buffer_size"`           // Size of metrics buffer
	FlushInterval       time.Duration `json:"flush_interval"`        // How often to flush metrics
	ExportPrometheus    bool          `json:"export_prometheus"`     // Enable Prometheus metrics export
	PrometheusNamespace string        `json:"prometheus_namespace"`  // Namespace for Prometheus metrics
	MemoryStatsInterval time.Duration `json:"memory_stats_interval"` // How often to collect memory stats
	HistogramBuckets    []float64     `json:"histogram_buckets"`     // Custom histogram buckets for response times

	// Additional fields for compatibility with examples
	MetricsRetentionPeriod time.Duration `json:"metrics_retention_period"` // Alias for MetricsRetention
	MaxSearchResults       int           `json:"max_search_results"`       // Maximum number of search results
	SearchTimeout          time.Duration `json:"search_timeout"`           // Timeout for search operations
	EnablePrefetch         bool          `json:"enable_prefetch"`          // Enable prefetching optimizations
	EnableBulkOperations   bool          `json:"enable_bulk_operations"`   // Enable bulk operation optimizations
}

PerformanceConfig contains configuration for performance monitoring

func DefaultPerformanceConfig added in v1.1.0

func DefaultPerformanceConfig() *PerformanceConfig

DefaultPerformanceConfig returns a PerformanceConfig with sensible defaults

type PerformanceMetrics added in v1.1.0

type PerformanceMetrics struct {
	// Basic counters
	OperationsTotal int64 `json:"operations_total"`
	ErrorCount      int64 `json:"error_count"`
	TimeoutCount    int64 `json:"timeout_count"`
	SlowQueries     int64 `json:"slow_queries"`
	CacheHits       int64 `json:"cache_hits"`
	CacheMisses     int64 `json:"cache_misses"`

	// Timing statistics
	AvgResponseTime time.Duration `json:"avg_response_time"`
	MinResponseTime time.Duration `json:"min_response_time"`
	MaxResponseTime time.Duration `json:"max_response_time"`
	P50ResponseTime time.Duration `json:"p50_response_time"`
	P95ResponseTime time.Duration `json:"p95_response_time"`
	P99ResponseTime time.Duration `json:"p99_response_time"`

	// Resource usage
	MemoryUsageMB  float64 `json:"memory_usage_mb"`
	GoroutineCount int     `json:"goroutine_count"`

	// Operation breakdown
	OperationsByType  map[string]int64 `json:"operations_by_type"`
	ErrorsByType      map[string]int64 `json:"errors_by_type"`
	SlowQueriesByType map[string]int64 `json:"slow_queries_by_type"`

	// Time series data (recent samples)
	ResponseTimes []time.Duration `json:"response_times,omitempty"`
	TimeStamps    []time.Time     `json:"timestamps,omitempty"`

	// Cache statistics
	CacheHitRatio float64 `json:"cache_hit_ratio"`

	// Backward compatibility fields for direct pool access
	PoolHits           int64 `json:"pool_hits"`
	PoolMisses         int64 `json:"pool_misses"`
	TotalConnections   int   `json:"total_connections"`
	ConnectionsCreated int64 `json:"connections_created"`

	// Additional fields for example compatibility
	ActiveConnections   int               `json:"active_connections"`
	IdleConnections     int               `json:"idle_connections"`
	HealthChecksPassed  int64             `json:"health_checks_passed"`
	HealthChecksFailed  int64             `json:"health_checks_failed"`
	ConnectionsClosed   int64             `json:"connections_closed"`
	ConnectionPoolRatio float64           `json:"connection_pool_ratio"`
	TopSlowOperations   []OperationMetric `json:"top_slow_operations,omitempty"`

	// Connection pool stats (if available)
	PoolStats *ConnectionPoolStats `json:"pool_stats,omitempty"`
}

PerformanceMetrics represents aggregated performance statistics

type PerformanceMonitor added in v1.1.0

type PerformanceMonitor struct {
	// contains filtered or unexported fields
}

PerformanceMonitor provides comprehensive performance monitoring and metrics collection

func NewPerformanceMonitor added in v1.1.0

func NewPerformanceMonitor(config *PerformanceConfig, logger *slog.Logger) *PerformanceMonitor

NewPerformanceMonitor creates a new performance monitor with the given configuration

func (*PerformanceMonitor) Close added in v1.1.0

func (pm *PerformanceMonitor) Close() error

Close stops background tasks and cleans up resources

func (*PerformanceMonitor) Flush added in v1.2.0

func (pm *PerformanceMonitor) Flush()

Flush writes any pending metrics data

func (*PerformanceMonitor) GetOperationHistory added in v1.1.0

func (pm *PerformanceMonitor) GetOperationHistory() []OperationMetric

GetOperationHistory returns detailed operation history

func (*PerformanceMonitor) GetStats added in v1.1.0

func (pm *PerformanceMonitor) GetStats() *PerformanceMetrics

GetStats returns current performance statistics

func (*PerformanceMonitor) RecordOperation added in v1.1.0

func (pm *PerformanceMonitor) RecordOperation(ctx context.Context, operation string, duration time.Duration, cacheHit bool, err error, resultCount int)

RecordOperation records the completion of an LDAP operation

func (*PerformanceMonitor) Reset added in v1.1.0

func (pm *PerformanceMonitor) Reset()

Reset clears all performance metrics (useful for testing)

func (*PerformanceMonitor) SetCache added in v1.1.0

func (pm *PerformanceMonitor) SetCache(cache Cache)

SetCache links a cache instance for integrated metrics collection

func (*PerformanceMonitor) SetConnectionPool added in v1.1.0

func (pm *PerformanceMonitor) SetConnectionPool(pool *ConnectionPool)

SetConnectionPool links a connection pool instance for integrated metrics collection

func (*PerformanceMonitor) StartOperation added in v1.1.0

func (pm *PerformanceMonitor) StartOperation(ctx context.Context, operation string) func(bool, error, int)

StartOperation returns a function to record operation completion (convenience method)

type PerformanceStats added in v1.1.0

type PerformanceStats = PerformanceMetrics

PerformanceStats is an alias for PerformanceMetrics for interface compatibility

type Pipeline added in v1.1.0

type Pipeline[T, U any] struct {
	// contains filtered or unexported fields
}

Pipeline provides a pipeline pattern for streaming LDAP operations. This pattern is useful for processing large datasets with multiple stages.

func NewPipeline added in v1.1.0

func NewPipeline[T, U any](ctx context.Context, logger *slog.Logger, bufferSize int) *Pipeline[T, U]

NewPipeline creates a new processing pipeline.

Example:

pipeline := NewPipeline[string, *User](ctx, logger, 100)

// Add stages
pipeline.AddStage("parse", func(ctx context.Context, dn string) (*FullUser, error) {
    // Parse DN and create user object
    return parseUserFromDN(dn), nil
}, 5)

pipeline.AddStage("create", func(ctx context.Context, user *FullUser) (*User, error) {
    // Create user in LDAP
    dn, err := client.CreateUserContext(ctx, *user, "password")
    if err != nil {
        return nil, err
    }
    return client.FindUserByDNContext(ctx, dn)
}, 10)

// Process items
go pipeline.Start()

// Send input
for _, dn := range userDNs {
    pipeline.Input() <- dn
}
close(pipeline.Input())

// Receive output
for user := range pipeline.Output() {
    fmt.Printf("Created user: %s\n", user.CN())
}

func (*Pipeline[T, U]) AddStage added in v1.1.0

func (p *Pipeline[T, U]) AddStage(name string, transform func(context.Context, any) (any, error), parallel int)

AddStage adds a processing stage to the pipeline.

func (*Pipeline[T, U]) Close added in v1.1.0

func (p *Pipeline[T, U]) Close()

Close stops the pipeline and cleans up resources.

func (*Pipeline[T, U]) Errors added in v1.1.0

func (p *Pipeline[T, U]) Errors() []error

Errors returns all errors collected during pipeline processing.

func (*Pipeline[T, U]) Input added in v1.1.0

func (p *Pipeline[T, U]) Input() chan<- T

Input returns the input channel for the pipeline.

func (*Pipeline[T, U]) Output added in v1.1.0

func (p *Pipeline[T, U]) Output() <-chan U

Output returns the output channel for the pipeline.

func (*Pipeline[T, U]) Start added in v1.1.0

func (p *Pipeline[T, U]) Start()

Start begins processing the pipeline.

type PipelineStage added in v1.1.0

type PipelineStage[T, U any] struct {
	Name      string
	Transform func(ctx context.Context, input T) (U, error)
	Parallel  int // Number of goroutines for this stage
}

PipelineStage represents a stage in the pipeline.

type PoolConfig added in v1.1.0

type PoolConfig struct {
	// MaxConnections is the maximum number of concurrent connections (default: 10)
	MaxConnections int
	// MinConnections is the minimum number of idle connections to maintain (default: 2)
	MinConnections int
	// MaxIdleTime is the maximum time a connection can remain idle before cleanup (default: 5min)
	MaxIdleTime time.Duration
	// HealthCheckInterval is how frequently to check connection health (default: 30s)
	HealthCheckInterval time.Duration
	// ConnectionTimeout is the timeout for establishing new connections (default: 30s)
	ConnectionTimeout time.Duration
	// GetTimeout is the timeout for getting a connection from the pool (default: 10s)
	GetTimeout time.Duration

	// Self-healing configuration
	// EnableSelfHealing enables automatic leak detection and recovery (default: true)
	EnableSelfHealing bool
	// LeakDetectionThreshold is the duration after which a connection is suspected as leaked (default: 5min)
	LeakDetectionThreshold time.Duration
	// LeakEvictionThreshold is the duration after which a leaked connection is force-evicted (default: 10min)
	LeakEvictionThreshold time.Duration
}

PoolConfig holds configuration options for the connection pool

func DefaultPoolConfig added in v1.1.0

func DefaultPoolConfig() *PoolConfig

DefaultPoolConfig returns a PoolConfig with sensible defaults

type PoolStats added in v1.1.0

type PoolStats struct {
	// ActiveConnections is the number of connections currently in use
	ActiveConnections int32
	// IdleConnections is the number of connections available in the pool
	IdleConnections int32
	// TotalConnections is the total number of connections (active + idle)
	TotalConnections int32
	// PoolHits is the number of successful connection retrievals from pool
	PoolHits int64
	// PoolMisses is the number of times new connections had to be created
	PoolMisses int64
	// HealthChecksPassed is the number of successful health checks
	HealthChecksPassed int64
	// HealthChecksFailed is the number of failed health checks
	HealthChecksFailed int64
	// ConnectionsCreated is the total number of connections created
	ConnectionsCreated int64
	// ConnectionsClosed is the total number of connections closed
	ConnectionsClosed int64
	// LeakedConnections is the number of leaked connections detected and evicted
	LeakedConnections int64
	// SelfHealingEvents is the number of self-healing recovery operations
	SelfHealingEvents int64
}

PoolStats provides statistics and metrics about the connection pool

type QueryBuilder added in v1.1.0

type QueryBuilder struct {
	// contains filtered or unexported fields
}

QueryBuilder implements the builder pattern for creating complex LDAP queries.

func NewQueryBuilder added in v1.1.0

func NewQueryBuilder() *QueryBuilder

NewQueryBuilder creates a new QueryBuilder.

Example:

query := NewQueryBuilder().
    WithBaseDN("DC=example,DC=com").
    WithScope(ldap.ScopeWholeSubtree).
    FilterByObjectClass("user").
    FilterByAttribute("mail", "*@example.com").
    WithAttributes("cn", "mail", "sAMAccountName").
    Build()

func (*QueryBuilder) BuildFilter added in v1.1.0

func (b *QueryBuilder) BuildFilter() (string, error)

BuildFilter returns the constructed LDAP filter string.

func (*QueryBuilder) FilterByAttribute added in v1.1.0

func (b *QueryBuilder) FilterByAttribute(attribute, value string) *QueryBuilder

FilterByAttribute adds an attribute filter.

func (*QueryBuilder) FilterByObjectClass added in v1.1.0

func (b *QueryBuilder) FilterByObjectClass(objectClass string) *QueryBuilder

FilterByObjectClass adds an object class filter.

func (*QueryBuilder) WithAttributes added in v1.1.0

func (b *QueryBuilder) WithAttributes(attributes ...string) *QueryBuilder

WithAttributes sets the attributes to retrieve.

func (*QueryBuilder) WithBaseDN added in v1.1.0

func (b *QueryBuilder) WithBaseDN(baseDN string) *QueryBuilder

WithBaseDN sets the base DN for the search.

func (*QueryBuilder) WithScope added in v1.1.0

func (b *QueryBuilder) WithScope(scope int) *QueryBuilder

WithScope sets the search scope.

func (*QueryBuilder) WithSizeLimit added in v1.1.0

func (b *QueryBuilder) WithSizeLimit(limit int) *QueryBuilder

WithSizeLimit sets the maximum number of entries to return.

func (*QueryBuilder) WithTimeLimit added in v1.1.0

func (b *QueryBuilder) WithTimeLimit(limit int) *QueryBuilder

WithTimeLimit sets the maximum time to wait for results.

type RateLimiter added in v1.1.0

type RateLimiter struct {
	// contains filtered or unexported fields
}

RateLimiter provides authentication rate limiting functionality

func NewRateLimiter added in v1.1.0

func NewRateLimiter(config *RateLimiterConfig, logger *slog.Logger) *RateLimiter

NewRateLimiter creates a new rate limiter with the given configuration

func (*RateLimiter) CheckLimit added in v1.1.0

func (rl *RateLimiter) CheckLimit(identifier string) bool

CheckLimit verifies if the authentication attempt is allowed

func (*RateLimiter) Close added in v1.1.0

func (rl *RateLimiter) Close()

Close stops the rate limiter and cleanup routines

func (*RateLimiter) GetMetrics added in v1.1.0

func (rl *RateLimiter) GetMetrics() RateLimiterMetrics

GetMetrics returns current rate limiter metrics

func (*RateLimiter) RecordFailure added in v1.1.0

func (rl *RateLimiter) RecordFailure(identifier string)

RecordFailure records a failed authentication attempt

func (*RateLimiter) RecordSuccess added in v1.1.0

func (rl *RateLimiter) RecordSuccess(identifier string)

RecordSuccess records a successful authentication

func (*RateLimiter) Reset added in v1.1.0

func (rl *RateLimiter) Reset()

Reset clears all rate limiter entries and metrics

type RateLimiterConfig added in v1.1.0

type RateLimiterConfig struct {
	// MaxAttempts is the maximum number of authentication attempts allowed
	MaxAttempts int

	// Window is the time window for rate limiting
	Window time.Duration

	// LockoutDuration is how long to lock out after exceeding MaxAttempts
	LockoutDuration time.Duration

	// CleanupInterval is how often to clean up expired entries
	CleanupInterval time.Duration

	// MaxEntries is the maximum number of entries to track
	MaxEntries int
}

RateLimiterConfig contains configuration for authentication rate limiting

func DefaultRateLimiterConfig added in v1.1.0

func DefaultRateLimiterConfig() *RateLimiterConfig

DefaultRateLimiterConfig returns a RateLimiterConfig with sensible defaults

type RateLimiterEntry added in v1.1.0

type RateLimiterEntry struct {
	Attempts     int
	FirstAttempt time.Time
	LastAttempt  time.Time
	LockedUntil  time.Time
}

RateLimiterEntry tracks authentication attempts for a specific identifier

type RateLimiterMetrics added in v1.1.0

type RateLimiterMetrics struct {
	TotalAttempts       int64    `json:"total_attempts"`
	BlockedAttempts     int64    `json:"blocked_attempts"`
	SuccessfulAttempts  int64    `json:"successful_attempts"`
	WhitelistedAttempts int64    `json:"whitelisted_attempts"`
	ActiveLockouts      int64    `json:"active_lockouts"`
	SuccessfulAuth      int64    `json:"successful_auth"`
	FailedAuth          int64    `json:"failed_auth"`
	AverageAttempts     float64  `json:"average_attempts"`
	TopOffenders        []string `json:"top_offenders,omitempty"`

	// Security analysis metrics
	ViolationEvents    int64 `json:"violation_events"`
	SuspiciousPatterns int64 `json:"suspicious_patterns"`
	BurstAttacks       int64 `json:"burst_attacks"`
	RepeatedViolators  int64 `json:"repeated_violators"`

	// Resource usage metrics
	UniqueIdentifiers int64 `json:"unique_identifiers"`
	MemoryUsageBytes  int64 `json:"memory_usage_bytes"`

	// Performance metrics
	AvgCheckTime         time.Duration `json:"avg_check_time"`
	PeakConcurrentChecks int           `json:"peak_concurrent_checks"`
}

RateLimiterMetrics provides statistics about rate limiting

type ReadOnlyDirectory added in v1.1.0

type ReadOnlyDirectory interface {
	UserReader
	GroupReader
	ComputerReader

	// Connection management (read-only)
	GetConnection() (Connection, error)
	GetConnectionContext(ctx context.Context) (Connection, error)

	// Statistics and monitoring (read-only)
	GetPoolStats() PerformanceStats
	GetCacheStats() CacheStats
	GetPerformanceStats() PerformanceStats
}

ReadOnlyDirectory is a read-only interface for LDAP operations. This interface is useful for applications that only need read access.

type ResilienceConfig added in v1.2.0

type ResilienceConfig struct {
	// EnableCircuitBreaker enables circuit breaker protection for LDAP connections
	EnableCircuitBreaker bool
	// CircuitBreaker is the circuit breaker configuration
	CircuitBreaker *CircuitBreakerConfig
}

ResilienceConfig holds resilience-related configuration options.

func DefaultResilienceConfig added in v1.2.0

func DefaultResilienceConfig() *ResilienceConfig

DefaultResilienceConfig returns a ResilienceConfig with sensible defaults. Circuit breaker is disabled by default for backward compatibility.

type ResourceExhaustionError added in v1.1.0

type ResourceExhaustionError struct {
	Resource  string
	Current   int64
	Limit     int64
	Action    string
	Retryable bool
}

ResourceExhaustionError with constructor expected by resilience.go

func NewResourceExhaustionError added in v1.1.0

func NewResourceExhaustionError(resource string, current, limit int64, action string, retryable ...bool) *ResourceExhaustionError

NewResourceExhaustionError creates a new resource exhaustion error - matches resilience.go signature

func (*ResourceExhaustionError) Error added in v1.1.0

func (e *ResourceExhaustionError) Error() string

func (*ResourceExhaustionError) Temporary added in v1.1.0

func (e *ResourceExhaustionError) Temporary() bool

type RetryableError added in v1.1.0

type RetryableError interface {
	error
	IsRetryable() bool
}

RetryableError interface defines errors that can be retried.

func WithRetryInfo added in v1.1.0

func WithRetryInfo(err error, retryable bool) RetryableError

WithRetryInfo wraps an error with retry information.

type SamAccountType

type SamAccountType uint32

SamAccountType represents the Security Account Manager account type values used in Active Directory. This enumeration defines the type of account object and is stored in the sAMAccountType attribute.

Reference: https://learn.microsoft.com/en-us/windows/win32/adschema/a-samaccounttype

const (
	// SamDomainObject (0x0) represents a domain object.
	SamDomainObject SamAccountType = 0x0
	// SamGroupObject (0x10000000) represents a security group object.
	SamGroupObject SamAccountType = 0x10000000
	// SamNonSecurityGroupObject (0x10000001) represents a non-security group object.
	SamNonSecurityGroupObject SamAccountType = 0x10000001
	// SamAliasObject (0x20000000) represents an alias object (local group).
	SamAliasObject SamAccountType = 0x20000000
	// SamNonSecurityAliasObject (0x20000001) represents a non-security alias object.
	SamNonSecurityAliasObject SamAccountType = 0x20000001
	// SamUserObject (0x30000000) represents a normal user account (also known as SAM_NORMAL_USER_ACCOUNT).
	SamUserObject SamAccountType = 0x30000000
	// SamMachineAccount (0x30000001) represents a computer/machine account.
	SamMachineAccount SamAccountType = 0x30000001
	// SamTrustAccount (0x30000002) represents an interdomain trust account.
	SamTrustAccount SamAccountType = 0x30000002
	// SamAppBasicGroup (0x40000000) represents an application basic group.
	SamAppBasicGroup SamAccountType = 0x40000000
	// SamAppQueryGroup (0x40000001) represents an application query group.
	SamAppQueryGroup SamAccountType = 0x40000001
	// SamAccountTypeMax (0x7fffffff) represents the maximum account type value.
	SamAccountTypeMax SamAccountType = 0x7fffffff
)

func (SamAccountType) String

func (t SamAccountType) String() string

String returns a human-readable description of the SAM account type.

Returns:

  • string: A descriptive name for the account type, or "Unknown" for unrecognized values

This method is useful for logging and debugging to understand what type of account object is being processed.

type SearchOptions added in v1.1.0

type SearchOptions struct {
	// UseCache enables/disables caching for this search
	UseCache bool
	// CacheKey is a custom cache key for this search (optional)
	CacheKey string
	// TTL overrides the default cache TTL (optional)
	TTL time.Duration
	// RefreshStale enables background refresh of stale entries
	RefreshStale bool
	// BackgroundLoad enables background loading to warm the cache
	BackgroundLoad bool
	// UseNegativeCache enables caching of negative results
	UseNegativeCache bool
	// MaxResults limits the number of results returned
	MaxResults int
	// Timeout sets a custom timeout for this operation
	Timeout time.Duration
	// AttributeFilter specifies which attributes to retrieve
	AttributeFilter []string
}

SearchOptions provides configuration for optimized search operations

func DefaultSearchOptions added in v1.1.0

func DefaultSearchOptions() *SearchOptions

DefaultSearchOptions returns SearchOptions with sensible defaults

type SearchRequest added in v1.1.0

type SearchRequest struct {
	BaseDN       string
	Scope        int
	DerefAliases int
	SizeLimit    int
	TimeLimit    int
	TypesOnly    bool
	Filter       string
	Attributes   []string
}

SearchRequest represents a search request with modern Go patterns.

type SearchResult added in v1.1.0

type SearchResult struct {
	Entries   []*Entry
	Referrals []string
}

SearchResult represents search results with modern Go patterns.

type Searchable added in v1.1.0

type Searchable[T LDAPObject] interface {
	LDAPObject
	// FromEntry creates an object from an LDAP entry
	FromEntry(entry *ldap.Entry) (T, error)
	// GetObjectClass returns the LDAP object class for searching
	GetObjectClass() string
	// GetSearchAttributes returns the attributes to retrieve during search
	GetSearchAttributes() []string
}

Searchable defines the constraint for LDAP objects that can be searched. This extends LDAPObject with search-specific methods.

type SecureCredential added in v1.1.0

type SecureCredential struct {
	// contains filtered or unexported fields
}

SecureCredential provides secure handling of authentication credentials with memory protection

func NewSecureCredential added in v1.1.0

func NewSecureCredential(provider CredentialProvider) (*SecureCredential, error)

NewSecureCredential creates a new SecureCredential with the given provider

func NewSecureCredentialSimple added in v1.1.0

func NewSecureCredentialSimple(username, password string) (*SecureCredential, error)

NewSecureCredentialSimple creates a SecureCredential with basic string credentials

func NewSecureCredentialWithTimeout added in v1.1.0

func NewSecureCredentialWithTimeout(username, password string, timeout time.Duration) *SecureCredential

NewSecureCredentialWithTimeout creates a new SecureCredential with username, password and timeout (for test compatibility)

func (*SecureCredential) Clone added in v1.1.0

func (sc *SecureCredential) Clone() (*SecureCredential, error)

Clone creates a copy of the SecureCredential for use in different contexts

func (*SecureCredential) GetCredentials added in v1.1.0

func (sc *SecureCredential) GetCredentials() (string, string)

GetCredentials returns the username and password for authentication

func (*SecureCredential) IsExpired added in v1.1.0

func (sc *SecureCredential) IsExpired() bool

IsExpired checks if the credential has expired

func (*SecureCredential) Zeroize added in v1.1.0

func (sc *SecureCredential) Zeroize()

Zeroize securely clears credential data from memory

func (*SecureCredential) ZeroizeCredentials added in v1.1.0

func (sc *SecureCredential) ZeroizeCredentials() error

ZeroizeCredentials securely clears credential data from memory

type SecurityConfig added in v1.1.0

type SecurityConfig struct {
	// TLSConfig specifies custom TLS configuration for LDAPS connections
	TLSConfig *tls.Config

	// RequireSecureConnection forces the use of LDAPS (TLS encryption)
	RequireSecureConnection bool

	// DisableTLSVerification disables TLS certificate verification (INSECURE - use only for testing)
	DisableTLSVerification bool

	// ConnectionTimeout specifies the timeout for establishing connections
	ConnectionTimeout time.Duration

	// ReadTimeout specifies the timeout for read operations
	ReadTimeout time.Duration

	// WriteTimeout specifies the timeout for write operations
	WriteTimeout time.Duration

	// MaxPasswordLength limits the maximum password length for security
	MaxPasswordLength int

	// RequireStrongPasswords enforces strong password requirements
	RequireStrongPasswords bool

	// EnableAuditLogging enables detailed security audit logging
	EnableAuditLogging bool

	// AuditLogLevel specifies the minimum log level for audit events
	AuditLogLevel slog.Level
}

SecurityConfig contains security-related configuration options

func DefaultSecurityConfig added in v1.1.0

func DefaultSecurityConfig() *SecurityConfig

DefaultSecurityConfig returns a SecurityConfig with secure defaults

type SecurityContext added in v1.1.0

type SecurityContext struct {
	ClientIP          string
	UserAgent         string
	RequestID         string
	SessionID         string
	AuthenticatedUser string
	Permissions       []string
	RateLimited       bool
	AuditEnabled      bool
}

SecurityContext contains security-related information for operations

func GetSecurityContext added in v1.1.0

func GetSecurityContext(ctx context.Context) *SecurityContext

GetSecurityContext extracts security context from a Go context

func NewSecurityContext added in v1.1.0

func NewSecurityContext() *SecurityContext

NewSecurityContext creates a new security context

func (*SecurityContext) AddToContext added in v1.1.0

func (sc *SecurityContext) AddToContext(ctx context.Context) context.Context

AddToContext adds the security context to a Go context

type Semaphore added in v1.1.0

type Semaphore struct {
	// contains filtered or unexported fields
}

Semaphore provides a semaphore for controlling concurrent LDAP operations.

func NewSemaphore added in v1.1.0

func NewSemaphore(capacity int) *Semaphore

NewSemaphore creates a new semaphore with the specified capacity.

func (*Semaphore) Acquire added in v1.1.0

func (s *Semaphore) Acquire(ctx context.Context) error

Acquire acquires a semaphore permit.

func (*Semaphore) Release added in v1.1.0

func (s *Semaphore) Release() error

Release releases a semaphore permit. It returns an error if Release is called without a corresponding Acquire.

func (*Semaphore) WithSemaphore added in v1.1.0

func (s *Semaphore) WithSemaphore(ctx context.Context, fn func() error) error

WithSemaphore executes a function with semaphore protection.

type SharedTestContainer added in v1.1.0

type SharedTestContainer struct {
	// contains filtered or unexported fields
}

SharedTestContainer is a stub for non-integration builds

type StringCache added in v1.1.0

type StringCache = GenericLRUCache[string]

StringCache provides a type-safe cache for string values

func NewStringCache added in v1.1.0

func NewStringCache(config *CacheConfig, logger *slog.Logger) (*StringCache, error)

NewStringCache creates a new cache specifically for string values

type TLSConfig added in v1.1.0

type TLSConfig struct {
	// MinVersion specifies the minimum TLS version
	MinVersion uint16

	// MaxVersion specifies the maximum TLS version
	MaxVersion uint16

	// CipherSuites specifies allowed cipher suites
	CipherSuites []uint16

	// InsecureSkipVerify disables certificate verification (INSECURE)
	InsecureSkipVerify bool

	// ServerName specifies the server name for SNI
	ServerName string

	// Certificates specifies client certificates
	Certificates []tls.Certificate

	// RootCAs specifies custom root CAs
	RootCAs []string
}

TLSConfig represents TLS configuration settings

type TestComputer added in v1.1.0

type TestComputer struct {
	CN             string
	SAMAccountName string
	DN             string
}

TestComputer is a stub for non-integration builds

type TestContainer added in v1.1.0

type TestContainer struct {
	Config      Config
	AdminUser   string
	AdminPass   string
	BaseDN      string
	UsersOU     string
	GroupsOU    string
	ComputersOU string
}

TestContainer is a stub for non-integration builds

func SetupTestContainer added in v1.1.0

func SetupTestContainer(t *testing.T) *TestContainer

SetupTestContainer is a stub that skips if called without integration build tag

func (*TestContainer) Cleanup added in v1.1.0

func (tc *TestContainer) Cleanup()

Cleanup is a stub method

func (*TestContainer) Close added in v1.1.0

func (tc *TestContainer) Close(t *testing.T)

Close is a stub method

func (*TestContainer) GetLDAPClient added in v1.1.0

func (tc *TestContainer) GetLDAPClient(t *testing.T) *LDAP

GetLDAPClient is a stub method

func (*TestContainer) GetTestData added in v1.1.0

func (tc *TestContainer) GetTestData() *TestData

GetTestData is a stub method

type TestData added in v1.1.0

type TestData struct {
	Users     []TestUser
	Groups    []TestGroup
	Computers []TestComputer

	// Authentication test data
	ValidUserDN          string
	ValidUserCN          string
	ValidUserUID         string
	ValidUserMail        string
	ValidUserPassword    string
	InvalidUserUID       string
	InvalidPassword      string
	DisabledUserUID      string
	DisabledUserDN       string
	DisabledUserPassword string

	// Computer test data
	ValidComputerDN string
	ValidComputerCN string

	// Group test data
	ValidGroupDN string
	ValidGroupCN string
}

TestData is a stub for non-integration builds

type TestGroup added in v1.1.0

type TestGroup struct {
	CN      string
	DN      string
	Members []string
}

TestGroup is a stub for non-integration builds

type TestUser added in v1.1.0

type TestUser struct {
	CN             string
	SAMAccountName string
	Email          string
	Password       string
	DN             string
}

TestUser is a stub for non-integration builds

type ThreatContext added in v1.1.0

type ThreatContext struct {
	// Level of threat detected
	ThreatLevel string `json:"threat_level"` // low, medium, high, critical

	// List of specific threats detected
	DetectedThreats []string `json:"detected_threats"`

	// Source IP if available
	SourceIP string `json:"source_ip,omitempty"`

	// Confidence level in threat detection (0.0-1.0)
	Confidence float64 `json:"confidence"`

	// Recommended action
	RecommendedAction string `json:"recommended_action"` // allow, warn, block, escalate

	// Risk score for the threat (0.0-1.0)
	RiskScore float64 `json:"risk_score"`

	// Additional metadata about the threat
	Metadata map[string]interface{} `json:"metadata,omitempty"`
}

ThreatContext contains information about potential security threats detected during validation

type TimeoutError added in v1.1.0

type TimeoutError struct {
	Operation     string
	Duration      time.Duration
	TimeoutPeriod time.Duration // renamed from Timeout to avoid method name conflict
	Err           error
}

TimeoutError with constructor expected by resilience.go

func NewTimeoutError added in v1.1.0

func NewTimeoutError(operation string, duration, timeout time.Duration, err ...error) *TimeoutError

NewTimeoutError creates a new timeout error - matches resilience.go signature

func (*TimeoutError) Error added in v1.1.0

func (e *TimeoutError) Error() string

func (*TimeoutError) Temporary added in v1.1.0

func (e *TimeoutError) Temporary() bool

func (*TimeoutError) Timeout added in v1.1.0

func (e *TimeoutError) Timeout() bool

type TimeoutManager added in v1.1.0

type TimeoutManager struct {
	// contains filtered or unexported fields
}

TimeoutManager provides sophisticated timeout management

func NewTimeoutManager added in v1.1.0

func NewTimeoutManager(baseTimeout, maxTimeout time.Duration, backoffFactor float64) *TimeoutManager

NewTimeoutManager creates a new timeout manager

func (*TimeoutManager) ExecuteWithAdaptiveTimeout added in v1.1.0

func (tm *TimeoutManager) ExecuteWithAdaptiveTimeout(ctx context.Context, operation string, fn func(context.Context) error) error

ExecuteWithAdaptiveTimeout executes a function with adaptive timeout

func (*TimeoutManager) GetAdaptiveTimeout added in v1.1.0

func (tm *TimeoutManager) GetAdaptiveTimeout(operation string) time.Duration

GetAdaptiveTimeout returns an adaptive timeout based on operation history

func (*TimeoutManager) GetTimeoutStats added in v1.1.0

func (tm *TimeoutManager) GetTimeoutStats() map[string]interface{}

GetTimeoutStats returns timeout statistics for all operations

func (*TimeoutManager) RecordOperationResult added in v1.1.0

func (tm *TimeoutManager) RecordOperationResult(operation string, duration time.Duration, success bool)

RecordOperationResult records the result of an operation for adaptive timeout calculation

type UAC

type UAC struct {
	// LogonScript (0x1) - Execute a logon script for the user
	LogonScript bool
	// AccountDisabled (0x2) - The account is disabled
	AccountDisabled bool
	// HomeDirRequired (0x8) - A home directory is required for the user
	HomeDirRequired bool
	// Lockout (0x10) - The account is locked out (read-only flag, set by the system)
	Lockout bool
	// PasswordNotRequired (0x20) - No password is required for the account
	PasswordNotRequired bool
	// PasswordCantChange (0x40) - The user cannot change their password
	PasswordCantChange bool
	// EncryptedTextPasswordAllowed (0x80) - Allows encrypted text passwords for the account
	EncryptedTextPasswordAllowed bool
	// TempDuplicateAccount (0x100) - This is a temporary duplicate account
	TempDuplicateAccount bool
	// NormalAccount (0x200) - This is a default account type representing a typical user
	NormalAccount bool
	// InterdomainTrustAccount (0x800) - This is a permit to trust account for a system domain that trusts other domains
	InterdomainTrustAccount bool
	// WorkstationTrustAccount (0x1000) - This is a computer account for a computer that is a member of this domain
	WorkstationTrustAccount bool
	// ServerTrustAccount (0x2000) - This is a computer account for a system backup domain controller that is a member of this domain
	ServerTrustAccount bool
	// NoPasswordExpiration (0x10000) - The password for this account does not expire
	NoPasswordExpiration bool
	// MNSLogonAccount (0x20000) - This is an MNS logon account
	MNSLogonAccount bool
	// SmartCardRequired (0x40000) - The user is required to log on using a smart card
	SmartCardRequired bool
	// TrustedForDelegation (0x80000) - The service account (user or computer account) under which a service runs is trusted for Kerberos delegation
	TrustedForDelegation bool
	// NotDelegated (0x100000) - The security context of the user will not be delegated to a service even if the service account is set as trusted for Kerberos delegation
	NotDelegated bool
	// UseDESKeyOnly (0x200000) - Use DES encryption types for keys for this account
	UseDESKeyOnly bool
	// DontRequirePreauth (0x400000) - This account does not require Kerberos pre-authentication for logon
	DontRequirePreauth bool
	// PasswordExpired (0x800000) - The user password has expired
	PasswordExpired bool
	// TrustedToAuthenticateForDelegation (0x1000000) - The account is enabled for delegation; used with the Kerberos constrained delegation feature
	TrustedToAuthenticateForDelegation bool
}

UAC represents the User Account Control flags for Active Directory user and computer accounts. These flags control various security settings and account behaviors.

Reference: https://learn.microsoft.com/en-us/windows/win32/adschema/a-useraccountcontrol

func UACFromUint32

func UACFromUint32(v uint32) UAC

UACFromUint32 creates a UAC struct from a uint32 userAccountControl value. This function decodes the bitmask flags from Active Directory's userAccountControl attribute.

Parameters:

  • v: The uint32 value from the userAccountControl attribute

Returns:

  • UAC: A UAC struct with boolean flags corresponding to the bitmask

Example:

// For a typical enabled user account (0x200 = ADS_UF_NORMAL_ACCOUNT)
uac := UACFromUint32(512)
// uac.NormalAccount will be true, AccountDisabled will be false

func (UAC) String

func (u UAC) String() string

String returns a human-readable representation of the UAC flags. Only flags that are set to true are included in the output string.

Returns:

  • string: A comma-separated list of active UAC flag names

Example output: "NormalAccount, NoPasswordExpiration" If no flags are set, returns an empty string.

func (UAC) Uint32

func (u UAC) Uint32() uint32

Uint32 converts the UAC struct back to a uint32 userAccountControl value. This function encodes the boolean flags into the bitmask format expected by Active Directory.

Returns:

  • uint32: The userAccountControl bitmask value suitable for Active Directory operations

This method is useful when creating or modifying user accounts and need to set the userAccountControl attribute with the appropriate flags.

type User

type User struct {
	Object
	// Enabled indicates whether the user account is enabled (not disabled by userAccountControl).
	Enabled bool
	// SAMAccountName is the Security Account Manager account name (unique identifier for Windows authentication).
	SAMAccountName string
	// Description contains the user's description or notes.
	Description string
	// Mail contains the user's email address (nil if not set).
	Mail *string
	// Groups contains a list of distinguished names (DNs) of groups the user belongs to.
	Groups []string
}

User represents an LDAP user object with common attributes.

func (*User) IsMemberOf added in v1.3.0

func (u *User) IsMemberOf(groupDN string) bool

IsMemberOf checks if the user is a member of the specified group. The comparison is case-insensitive and handles whitespace normalization, as LDAP distinguished names are case-insensitive according to RFC 4512.

Parameters:

  • groupDN: The distinguished name of the group to check membership for (e.g., "CN=Admins,OU=Groups,DC=example,DC=com")

Returns:

  • bool: true if the user is a direct member of the group, false otherwise

Example:

if user.IsMemberOf("CN=Admins,OU=Groups,DC=example,DC=com") {
    // User has admin privileges
}

Note: This method only checks direct group membership. For nested group membership checking in Active Directory, use the LDAP_MATCHING_RULE_IN_CHAIN filter with FindUserBySAMAccountName or similar methods.

type UserBuilder added in v1.1.0

type UserBuilder struct {
	// contains filtered or unexported fields
}

UserBuilder implements the builder pattern for creating FullUser objects. This provides a fluent, chainable API for constructing users with validation.

func NewUserBuilder added in v1.1.0

func NewUserBuilder() *UserBuilder

NewUserBuilder creates a new UserBuilder with default values.

Example:

user, err := NewUserBuilder().
    WithCN("John Doe").
    WithSAMAccountName("jdoe").
    WithMail("john.doe@example.com").
    WithDescription("Software Engineer").
    Build()

func (*UserBuilder) Build added in v1.1.0

func (b *UserBuilder) Build() (*FullUser, error)

Build creates the FullUser object and validates all required fields. Returns an error if any validation failed during the building process.

func (*UserBuilder) MustBuild added in v1.1.0

func (b *UserBuilder) MustBuild() *FullUser

MustBuild creates the FullUser object and panics if validation fails. This follows Go's convention for Must* functions which panic on error. Use Build() if you want to handle errors gracefully. This method should only be used when you're certain the configuration is valid.

func (*UserBuilder) WithCN added in v1.1.0

func (b *UserBuilder) WithCN(cn string) *UserBuilder

WithCN sets the common name for the user. The CN is required and will be validated.

func (*UserBuilder) WithDescription added in v1.1.0

func (b *UserBuilder) WithDescription(description string) *UserBuilder

WithDescription sets the description for the user.

func (*UserBuilder) WithEnabled added in v1.1.0

func (b *UserBuilder) WithEnabled(enabled bool) *UserBuilder

WithEnabled sets whether the user account is enabled.

func (*UserBuilder) WithFirstName added in v1.1.0

func (b *UserBuilder) WithFirstName(firstName string) *UserBuilder

WithFirstName sets the first name for the user.

func (*UserBuilder) WithGroups added in v1.1.0

func (b *UserBuilder) WithGroups(groupDNs []string) *UserBuilder

WithGroups sets the groups the user should belong to. Note: Group membership is typically managed after user creation

func (*UserBuilder) WithLastName added in v1.1.0

func (b *UserBuilder) WithLastName(lastName string) *UserBuilder

WithLastName sets the last name for the user.

func (*UserBuilder) WithMail added in v1.1.0

func (b *UserBuilder) WithMail(email string) *UserBuilder

WithMail sets the email address for the user. The email address will be validated for proper format.

func (*UserBuilder) WithSAMAccountName added in v1.1.0

func (b *UserBuilder) WithSAMAccountName(samAccountName string) *UserBuilder

WithSAMAccountName sets the SAM account name for the user. The SAM account name is required for Active Directory and will be validated.

type UserCache added in v1.1.0

type UserCache = GenericLRUCache[*User]

UserCache provides a type-safe cache for User objects

func NewUserCache added in v1.1.0

func NewUserCache(config *CacheConfig, logger *slog.Logger) (*UserCache, error)

NewUserCache creates a new cache specifically for User objects

type UserManager added in v1.1.0

type UserManager interface {
	UserReader
	UserWriter
	// GetUserGroups retrieves the groups a user belongs to
	GetUserGroups(userDN string) ([]Group, error)
	// GetUserGroupsContext retrieves the groups a user belongs to with context
	GetUserGroupsContext(ctx context.Context, userDN string) ([]Group, error)
}

UserManager combines UserReader and UserWriter interfaces for complete user management. This interface provides a comprehensive set of user management operations.

type UserModification added in v1.2.0

type UserModification struct {
	DN         string
	Attributes map[string][]string
}

UserModification represents a modification to apply to a user.

type UserReader added in v1.1.0

type UserReader interface {
	// FindUserByDN retrieves a user by their distinguished name
	FindUserByDN(dn string) (*User, error)
	// FindUserByDNContext retrieves a user by their distinguished name with context
	FindUserByDNContext(ctx context.Context, dn string) (*User, error)
	// FindUserBySAMAccountName retrieves a user by their SAM account name
	FindUserBySAMAccountName(name string) (*User, error)
	// FindUserBySAMAccountNameContext retrieves a user by their SAM account name with context
	FindUserBySAMAccountNameContext(ctx context.Context, name string) (*User, error)
	// FindUserByMail retrieves a user by their email address
	FindUserByMail(mail string) (*User, error)
	// FindUserByMailContext retrieves a user by their email address with context
	FindUserByMailContext(ctx context.Context, mail string) (*User, error)
}

UserReader defines methods for reading user information from LDAP. This interface follows the Interface Segregation Principle by separating read operations.

type UserWriter added in v1.1.0

type UserWriter interface {
	// CreateUser creates a new user with the provided information and password
	CreateUser(user FullUser, password string) (string, error)
	// CreateUserContext creates a new user with the provided information and password with context
	CreateUserContext(ctx context.Context, user FullUser, password string) (string, error)
	// DeleteUser deletes a user by their distinguished name
	DeleteUser(dn string) error
	// DeleteUserContext deletes a user by their distinguished name with context
	DeleteUserContext(ctx context.Context, dn string) error
	// UpdateUserPassword updates a user's password
	UpdateUserPassword(dn string, newPassword string) error
	// UpdateUserPasswordContext updates a user's password with context
	UpdateUserPasswordContext(ctx context.Context, dn, newPassword string) error
}

UserWriter defines methods for writing/modifying user information in LDAP. This interface follows the Interface Segregation Principle by separating write operations.

type ValidationConfig added in v1.1.0

type ValidationConfig struct {
	// Enable strict validation mode
	StrictMode bool `json:"strict_mode"`

	// Maximum lengths for various inputs
	MaxDNLength        int `json:"max_dn_length"`
	MaxFilterLength    int `json:"max_filter_length"`
	MaxAttributeLength int `json:"max_attribute_length"`
	MaxValueLength     int `json:"max_value_length"`

	// Allow lists for various inputs
	AllowedAttributes    []string `json:"allowed_attributes"`
	AllowedObjectClasses []string `json:"allowed_object_classes"`

	// Custom validation patterns
	CustomDNPattern        *regexp.Regexp `json:"-"`
	CustomAttributePattern *regexp.Regexp `json:"-"`

	// Security settings
	BlockSuspiciousPatterns bool `json:"block_suspicious_patterns"`
	ValidateUTF8            bool `json:"validate_utf8"`
	NormalizeInput          bool `json:"normalize_input"`
}

ValidationConfig contains configuration for input validation

func DefaultValidationConfig added in v1.1.0

func DefaultValidationConfig() *ValidationConfig

DefaultValidationConfig returns a ValidationConfig with sensible defaults

type ValidationError added in v1.1.0

type ValidationError struct {
	Field   string
	Value   interface{}
	Message string
	Code    string
}

ValidationError represents input validation errors with field-specific details.

func NewValidationError added in v1.1.0

func NewValidationError(field string, value interface{}, message, code string) *ValidationError

NewValidationError creates a new validation error.

func (*ValidationError) Error added in v1.1.0

func (v *ValidationError) Error() string

Error implements the error interface.

type ValidationResult added in v1.1.0

type ValidationResult struct {
	Valid           bool                   `json:"valid"`
	NormalizedInput string                 `json:"normalized_input"`
	Warnings        []string               `json:"warnings"`
	Errors          []string               `json:"errors"`
	ThreatContext   *ThreatContext         `json:"threat_context,omitempty"`
	Metadata        map[string]interface{} `json:"metadata"`
}

ValidationResult contains the result of input validation

func ValidateComputer added in v1.1.0

func ValidateComputer(computer *FullComputer) ValidationResult

ValidateComputer validates a computer object created by ComputerBuilder.

func ValidateGroup added in v1.1.0

func ValidateGroup(group *FullGroup) ValidationResult

ValidateGroup validates a group object created by GroupBuilder.

func ValidateUser added in v1.1.0

func ValidateUser(user *FullUser) ValidationResult

ValidateUser validates a user object created by UserBuilder.

type ValidationSummary added in v1.1.0

type ValidationSummary struct {
	TotalChecks     int                 `json:"total_checks"`
	PassedChecks    int                 `json:"passed_checks"`
	FailedChecks    int                 `json:"failed_checks"`
	OverallValid    bool                `json:"overall_valid"`
	SecurityScore   float64             `json:"security_score"` // 0.0 to 1.0
	Recommendations []string            `json:"recommendations"`
	Results         []*ValidationResult `json:"results"`
	GeneratedAt     time.Time           `json:"generated_at"`
}

ValidationSummary contains aggregated validation results

func CreateValidationSummary added in v1.1.0

func CreateValidationSummary(results []*ValidationResult) *ValidationSummary

CreateValidationSummary creates a summary from multiple validation results

type Validator added in v1.1.0

type Validator struct {
	// contains filtered or unexported fields
}

Validator provides comprehensive input validation for LDAP operations

func NewValidator added in v1.1.0

func NewValidator(config *ValidationConfig) *Validator

NewValidator creates a new validator with the given configuration

func (*Validator) ValidateAttribute added in v1.1.0

func (v *Validator) ValidateAttribute(attributeName, attributeValue string) *ValidationResult

ValidateAttribute validates an LDAP attribute name and value

func (*Validator) ValidateCredentials added in v1.1.0

func (v *Validator) ValidateCredentials(username, password string) *ValidationResult

ValidateCredentials validates username and password credentials

func (*Validator) ValidateDN added in v1.1.0

func (v *Validator) ValidateDN(dn string) *ValidationResult

ValidateDN validates a distinguished name

func (*Validator) ValidateDNSyntax added in v1.1.0

func (v *Validator) ValidateDNSyntax(dn string) *ValidationResult

ValidateDNSyntax validates a distinguished name syntax - alias for ValidateDN for compatibility

func (*Validator) ValidateFilter added in v1.1.0

func (v *Validator) ValidateFilter(filter string) *ValidationResult

ValidateFilter validates an LDAP search filter

func (*Validator) ValidateValue added in v1.1.0

func (v *Validator) ValidateValue(value string) *ValidationResult

ValidateValue validates an LDAP attribute value

type WorkItem added in v1.1.0

type WorkItem[T any] struct {
	ID   string
	Data T
	Fn   func(ctx context.Context, client *LDAP, data T) error
}

WorkItem represents a unit of work to be processed by the worker pool.

type WorkResult added in v1.1.0

type WorkResult[T any] struct {
	ID       string
	Data     T
	Error    error
	Duration time.Duration
}

WorkResult represents the result of processing a work item.

type WorkerPool added in v1.1.0

type WorkerPool[T any] struct {
	// contains filtered or unexported fields
}

WorkerPool provides a worker pool pattern for concurrent LDAP operations. This pattern is useful for bulk operations like creating multiple users or processing search results.

func NewWorkerPool added in v1.1.0

func NewWorkerPool[T any](client *LDAP, config *WorkerPoolConfig) *WorkerPool[T]

NewWorkerPool creates a new worker pool for concurrent LDAP operations.

Example:

pool := NewWorkerPool[*FullUser](client, &WorkerPoolConfig{
    WorkerCount: 10,
    BufferSize: 50,
    Timeout: 2 * time.Minute,
})
defer pool.Close()

// Submit work items
for _, user := range users {
    pool.Submit(WorkItem[*FullUser]{
        ID: user.SAMAccountName,
        Data: user,
        Fn: func(ctx context.Context, client *LDAP, data *FullUser) error {
            _, err := client.CreateUserContext(ctx, *data, "defaultPassword")
            return err
        },
    })
}

// Collect results
results := pool.Results()
for result := range results {
    if result.Error != nil {
        log.Printf("Error processing %s: %v", result.ID, result.Error)
    }
}

func (*WorkerPool[T]) Close added in v1.1.0

func (p *WorkerPool[T]) Close()

Close shuts down the worker pool and waits for all workers to finish.

func (*WorkerPool[T]) Results added in v1.1.0

func (p *WorkerPool[T]) Results() <-chan WorkResult[T]

Results returns a channel that receives work results. The channel will be closed when all work is complete.

func (*WorkerPool[T]) Stats added in v1.1.0

func (p *WorkerPool[T]) Stats() WorkerPoolStats

Stats returns current worker pool statistics.

func (*WorkerPool[T]) Submit added in v1.1.0

func (p *WorkerPool[T]) Submit(item WorkItem[T]) error

Submit adds a work item to the pool for processing.

type WorkerPoolConfig added in v1.1.0

type WorkerPoolConfig struct {
	// WorkerCount is the number of concurrent workers
	WorkerCount int `json:"worker_count"`
	// BufferSize is the size of the work item buffer
	BufferSize int `json:"buffer_size"`
	// Timeout is the maximum time to wait for operations
	Timeout time.Duration `json:"timeout"`
	// FailFast determines if the pool should stop on first error
	FailFast bool `json:"fail_fast"`
}

WorkerPoolConfig configures a worker pool.

func DefaultWorkerPoolConfig added in v1.1.0

func DefaultWorkerPoolConfig() *WorkerPoolConfig

DefaultWorkerPoolConfig returns sensible defaults for a worker pool.

type WorkerPoolStats added in v1.1.0

type WorkerPoolStats struct {
	WorkerCount     int
	Processed       int64
	Errors          int64
	AverageDuration time.Duration
}

Stats returns worker pool statistics.

type WriteOnlyDirectory added in v1.1.0

type WriteOnlyDirectory interface {
	UserWriter
	GroupWriter
	ComputerWriter

	// Connection management
	GetConnection() (Connection, error)
	GetConnectionContext(ctx context.Context) (Connection, error)
	Close() error
}

WriteOnlyDirectory is a write-only interface for LDAP operations. This interface is useful for applications that only need write access.

Directories

Path Synopsis
examples
authentication command
Package main demonstrates authentication operations using simple-ldap-go
Package main demonstrates authentication operations using simple-ldap-go
basic-usage command
Package main demonstrates basic LDAP operations using simple-ldap-go
Package main demonstrates basic LDAP operations using simple-ldap-go
context-usage command
enhanced_errors command
modern_patterns command
Package main demonstrates modern Go patterns in the LDAP library.
Package main demonstrates modern Go patterns in the LDAP library.
performance command
user-management command
Package main demonstrates user management operations using simple-ldap-go
Package main demonstrates user management operations using simple-ldap-go

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL