Net::LDAP Documentation

repository·master·Indexed 19 days ago

https://github.com/ruby-ldap/ruby-net-ldap

A pure Ruby client implementation for the Lightweight Directory Access Protocol (LDAP), used to access distributed directory services like OpenLDAP and Active Directory. It provides tools for LDAP searching, binding, and authentication, including support for SASL and GSS-SPNEGO. The library includes utilities for handling LDAP entries and converting data to and from the LDAP Data Interchange Format (LDIF) via Net::LDAP::Dataset.

Tokens
4K
Snippets
17
Records
20
Agent score
60%

What's inside Net::LDAP

  1. Overview of Net::LDAP

    master
    Net::LDAP (net-ldap) is a pure Ruby implementation of a client for the Lightweight Directory Access Protocol (LDAP). It is designed to access distributed directory services and has been tested against popular servers like OpenLDAP and Active Directory. It is compliant with several IETF LDAP RFCs (including 2251–2256, 2829–2830, 3377, and 3771).
  2. Understand the Net::LDAP::Dataset abstraction

    master

    A Net::LDAP::Dataset acts as an intermediate format for converting LDAP data between Net::LDAP::Entry objects and LDIF strings.

    It inherits from Hash, where:

    • Keys: Represent the Distinguished Name (DN) of an LDAP entry.
    • Values: Are hashes where keys are attribute names (symbols) and values are arrays of attribute values.

    It supports metadata such as version and comments which are preserved during LDIF export.

  3. Implement a custom authentication adapter

    master

    To support custom authentication methods in Net::LDAP, you must create a class that inherits from Net::LDAP::AuthAdapter and implements the bind method. Once implemented, you must register your adapter using Net::LDAP::AuthAdapter.register to make it available for use by name.

    class MyCustomAdapter < Net::LDAP::AuthAdapter
      def bind
        # Implement custom binding logic using @connection
      end
    end
    
    # Register the adapter
    Net::LDAP::AuthAdapter.register(:my_method, MyCustomAdapter)
  4. Use GSS-SPNEGO authentication with Net::LDAP

    master

    GSS-SPNEGO authentication is a provisional method used to perform GSS-SPNEGO authentication with a server (typically Microsoft Active Directory).

    Warning: This implementation is PROVISIONAL and intended only for testing SASL implementations. It is not recommended for production use.

    To use this method, call #bind on your Net::LDAP instance with the :method parameter set to :gss_spnego. This method requires both :username (or :dn) and :password attributes, similar to the :simple authentication method.

    ldap = Net::LDAP.new(
      host: 'your-ad-server.com',
      port: 389
    )
    
    ldap.bind(
      method: :gss_spnego,
      username: 'user@DOMAIN.COM',
      password: 'your_password'
    )
  5. Configure the integration test environment via Docker Compose

    master

    The project uses Docker Compose to orchestrate an integration testing environment consisting of an OpenLDAP server and multiple Ruby runtime containers (Standard Ruby, TruffleRuby, and JRuby).

    OpenLDAP Service

    The openldap service uses the osixia/openldap:1.4.0 image. Key configurations include:

    • Network Aliases: The service is accessible via ldap.example.org and cert.mismatch.example.org.
    • Environment Variables:
      • LDAP_TLS_VERIFY_CLIENT: Set to try.
      • LDAP_SEED_INTERNAL_LDIF_PATH: Set to /ldif to load initial data.
    • Volumes: Mounts ./test/fixtures/ldif to /ldif (read-only) to seed the LDAP directory.

    CI Runtime Services

    Multiple services (e.g., ci-3.0 through ci-3.4, ci-truffleruby, ci-jruby-9.3, ci-jruby-9.4) run the integration tests using /code/ci-run.sh. These services rely on the following environment variables to connect to the LDAP server:

    • INTEGRATION: Set to openldap.
    • INTEGRATION_HOST: Set to ldap.example.org.

    All CI services depend on the openldap service being healthy before starting.

    services:
      openldap:
        image: osixia/openldap:1.4.0
        environment:
          LDAP_TLS_VERIFY_CLIENT: "try"
          LDAP_SEED_INTERNAL_LDIF_PATH: "/ldif"
        volumes:
          - ./test/fixtures/ldif:/ldif:ro
    
      ci-3.4:
        image: ruby:3.4
        environment:
          INTEGRATION: openldap
          INTEGRATION_HOST: ldap.example.org
        depends_on:
          - openldap
  6. Handle Net::LDAP connection and protocol errors

    master

    When working with Net::LDAP, you should rescue Net::LDAP::Error to catch most library-specific issues. For connection-specific failures, the library provides specialized error classes.

    Key error classes include:

    • Net::LDAP::ConnectionError: Raised when the client is unable to connect to any of the provided servers. It provides a detailed message listing the specific errors encountered for each host and port.
    • Net::LDAP::SocketError: Related to underlying socket issues.
    • Net::LDAP::AlreadyOpenedError: Raised if an attempt is made to open a connection that is already open.
    • Net::LDAP::StartTLSError: Raised when a StartTLS operation fails.
    • Net::LDAP::NoOpenSSLError: Raised if OpenSSL is not available.

    For protocol and LDAP-specific logic errors, use these classes:

    • Net::LDAP::InvalidDNError / Net::LDAP::EmptyDNError: Issues with Distinguished Names.
    • Net::LDAP::SearchFilterError / Net::LDAP::FilterSyntaxInvalidError: Issues with LDAP search filters.
    • Net::LDAP::AuthMethodUnsupportedError / Net::LDAP::BindingInformationInvalidError: Issues with authentication or binding.
    • Net::LDAP::EncryptionUnsupportedError / Net::LDAP::EncMethodUnsupportedError: Issues with encryption settings.
  7. Register custom authentication adapters

    master

    Use Net::LDAP::AuthAdapter.register(names, adapter) to map one or more authentication method names to a specific adapter class.

    • names: A single symbol/string or an array of symbols/strings representing the authentication methods.
    • adapter: The class that implements the authentication logic.
    Net::LDAP::AuthAdapter.register([:method_one, :method_two], MyAdapterClass)
  8. Retrieve a registered authentication adapter

    master

    You can retrieve a registered adapter by its name using the bracket syntax: Net::LDAP::AuthAdapter[name].

    If the requested name has not been registered, it will raise a Net::LDAP::AuthMethodUnsupportedError with the message "Unsupported auth method (#{name})".

    adapter = Net::LDAP::AuthAdapter[:my_method]
  9. Configure SASL authentication with Net::LDAP

    master

    When performing a SASL bind, you must provide an authentication hash containing three specific keys: :mechanism, :initial_credential, and :challenge_response.

    • :mechanism: A string representing the SASL mechanism (e.g., 'DIGEST-MD5').
    • :initial_credential: The initial credential (usually a string) sent in the first BindRequest.
    • :challenge_response: A Ruby Proc used to handle multi-step authentication. This block is triggered when the server returns a result code of 14 (saslBindInProgress). The proc receives the server's credentials (from the saslServerCreds field) as an argument and must return the next credential string to be sent to the server. The proc may be called multiple times until authentication is complete.

    Note: The authentication process is limited to a maximum of 10 challenges to prevent infinite loops; exceeding this will raise a Net::LDAP::SASLChallengeOverflowError.

    # Example of a SASL authentication hash
    auth_params = {
      mechanism: 'DIGEST-MD5',
      initial_credential: 'initial_password',
      challenge_response: ->(server_creds) {
        # server_creds contains the data from saslServerCreds
        # Return the next response string required by the server
        "next_response_string"
      }
    }
    
    # Usage with a Net::LDAP connection
    ldap.bind(auth_params)
  10. Read and write attributes in Net::LDAP::Entry

    master

    You can manipulate attributes within an Net::LDAP::Entry using bracket notation. The library handles canonicalization (lowercasing and symbol conversion) internally.

    • Reading: entry[:name] or entry['name'] returns an Array of values. To get just the first value, use entry.first(:name).
    • Writing: entry[:name] = value sets or replaces the attribute values. The value is automatically converted into an array.

    Example of manual instantiation and manipulation:

    entry = Net::LDAP::Entry.new("dc=com")
    entry["foo"] = 12345  # Sets attribute 'foo' to [12345]
    puts entry.foo          # => [12345]
    entry = Net::LDAP::Entry.new("dc=com")
    entry.foo             # => NoMethodError
    entry["foo"] = 12345  # => [12345]
    entry.foo             # => [12345]