27
LPIC-3 (301 exam) book Michael Boelen - rootkit.nl [ Security+, Linux+, LPIC-1, LPIC-2, CIW Security Professional, ITIL ] Usage notes Last updated 26 October 2008 Goal Provide a study guide for LPIC-3, 117-301 Audience Network and LDAP administrators, people who want to attain LPIC-3 (117-301) certification License Creative Commons license Notes All operations are performed on an Ubuntu system. Keep this in mind when using different file locations or installation/configuration instructions on your system. This book is setup as an step by step guide to install, configure and maintain OpenLDAP. This book is a work in progress and can contain grammar errors. Suggestions or input are appreciated. Progress: Stage 1: Initial writing 100% Stage 2: Completing examples/adding exam questions 45% Stage 3: Finishing questions/after care Stage: 1 2 3 Index Introduction » What is LDAP? Installation » Installation Configuration » General configuration » Database configuration » Slapd » Database configuration and tweaking » Database indexing » LDAP client configuration Security: » Security: SASL » Security: Proxy Authorization » Security: Authentication methods » Security: Client/Server certificates » Security: Hardening LDAP servers » Security: Access Control Lists » Security: TLS/SSL » Security: Security Strength Factors Integration

LPIC

Embed Size (px)

Citation preview

  • LPIC-3 (301 exam) book

    Michael Boelen - rootkit.nl

    [ Security+, Linux+, LPIC-1, LPIC-2, CIW Security Professional, ITIL ]

    Usage notes

    Last

    updated 26 October 2008

    Goal Provide a study guide for LPIC-3, 117-301

    Audience Network and LDAP administrators, people who want to attain

    LPIC-3 (117-301) certification

    License Creative Commons license

    Notes All operations are performed on an Ubuntu system.

    Keep this in mind when using different file locations

    or installation/configuration instructions on your

    system.

    This book is setup as an step by step guide to install,

    configure and maintain OpenLDAP.

    This book is a work in progress and can contain

    grammar errors.

    Suggestions or input are appreciated.

    Progress:

    Stage 1: Initial writing 100%

    Stage 2: Completing

    examples/adding exam questions 45%

    Stage 3: Finishing questions/after

    care

    Stage:

    1 2 3

    Index

    Introduction

    What is LDAP?

    Installation

    Installation

    Configuration

    General configuration

    Database configuration

    Slapd

    Database configuration and tweaking

    Database indexing

    LDAP client configuration

    Security:

    Security: SASL

    Security: Proxy Authorization

    Security: Authentication methods

    Security: Client/Server certificates

    Security: Hardening LDAP servers

    Security: Access Control Lists

    Security: TLS/SSL

    Security: Security Strength Factors

    Integration

  • LDAP and authentication

    Integration: Apache2 and LDAP

    Integration: Postfix and LDAP

    Integration: Sendmail and LDAP

    Integration: FreeRADIUS and LDAP

    Integration: OpenSSH and LDAP

    Integration: Samba and LDAP

    Integration: Dovecot POP/IMAP and LDAP

    Integration: CUPS printing and LDAP

    Integration: Kerberos and LDAP

    Integration: Active Directory and LDAP

    Migration: NIS to LDAP

    Replication

    Debugging: Logging

    Misc:

    Pre capacity planning

    Custom tooling: Perl

    OpenLDAP cheatsheet

    Useful links

    References and Thanks

    What is LDAP?

    LDAP stands for Lightweight Directory Access Protocol, a way to describe directory

    contents as separated records (entries). These entries consist of a collection of attributes, all

    with a globally-unique key, the Distinguished Name (DN). The DN consists of smaller

    pieces, describing the entity.

    Examples (with naming attribute): user (cn), group (cn), computer (cn), container (cn),

    organizational unit (ou), domain (dc).

    LDAP is based on the DAP X.500 standard (created at the University of Michigan), but with

    the goal to be "simple". The X.500 standard is very extensive and often too complex for

    smaller needs, that's why a light version of DAP was created.

    With LDAP we can create and store information for white pages (same as yellow pages, but

    for individuals, not companies), authentication of users and hosts and storing custom data

    sets. Another use is creating meta directories, systems which control the flow between

    multiple directory systems (with all belong to one directory information tree, or DIT) for ie

    single sign-on purposes and more.

    OpenLDAP does not support Class of Service (at the time of writing). The exam requires you

    to know the definition behind it: a way to define templates which can be used when creating

    new records. This templates define default values, often user based. They can be compared to

    the usage of roles.

    A directory namespace is a (big) container in which one or more forests and trees of objects

    reside. This is also know as the context.

    We use the term container to define where an object (like a user) belongs to, for example:

    ou=Sales,dc=rootkit,dc=nl. Container objects can be containers itself, organizational units, or

    domains and can contain other objects (like user objects, group objects, computer objects etc).

    An object class defines the type of the object. It must be present in every LDAP entry

    (example: posixAccount).

    Installation

  • Option 1: install binary package (apt-get/dpkg, rpm) # apt-get install slapd

    Option 2: install from sources # tar xfvz openldap-2.4.8.tgz

    # ./configure --help

    # ./configure

    # make

    # make dep

    # make test

    # make install

    To customize and optimize an OpenLDAP installation, option 2 is preferred. You can tune the

    options and application support your OpenLDAP installation will have. Disabling unused

    modules for your site is one of the options to optimize (for speed and throughput). Read the

    INSTALL file for basic installation details.

    LDAPv3 compliancy OpenLDAP needs SASL libraries to be LDAP version 3 compliant.

    Exam note: You should be familiar with installing OpenLDAP from source or by using

    binary packages (dpkg, apt-get, rpm)

    General configuration

    After installing OpenLDAP, a directory /etc/ldap should be present with the following

    contents: /etc/ldap# ls -l

    -rw-r--r-- 1 root root 245 2008-04-07 23:34 ldap.conf

    drwxr-xr-x 2 root root 4096 2008-04-07 23:34 sasl2

    drwxr-xr-x 2 root root 4096 2008-04-20 16:10 schema

    -rw-r----- 1 root openldap 4746 2008-04-20 16:10 slapd.conf

    The OpenLDAP server configuration file is called slapd.conf. The ldap.conf file is used for

    clients, the sasl2 directory for SASL specific settings and the schema directory to store the

    available schema's. The general format of the slapd.conf file is as follows:

    # Global configuration directives

    # Backend definition

    backend

    # First database definition & Config directives

    database

    # Second database definition & Config directives

    database

    # Other backend, database and config options

  • slapd.conf To store the data from OpenLDAP we define the directory where the database files should be

    located. Default this will be /var/lib/ldap. From a security point of view it's mandatory to lock

    down permissions only to the root and openldap user/group, to avoid reading configuration

    snippets or passwords.

    Exam note: Make sure to know all options in the slapd.conf configuration file.

    Backends Without OpenLDAP a backend is being used to store data. By default some backends are

    already available, while others can be installed or configured while installing OpenLDAP.

    List of available backends:

    Type Description

    bdb Berkeley DB transactional backend

    config Slapd configuration backend

    dnssrv DNS SRV backend

    hdb Hierarchical variant of bdb backend

    ldap Lightweight Directory Access

    Protocol (Proxy) backend

    ldbm Lightweight DBM backend

    ldif Lightweight Data Interchange

    Format backend

    meta Meta Directory backend

    monitor Monitor backend (dynamic, not for

    storing normal data)

    passwd Provides read-only access to

    passwd(5)

    perl Perl Programmable backend

    shell Shell (extern program) backend

    sql SQL Programmable backend

    Exam note: make sure to know which backends are supported and that hdb and bdb are

    often used.

    Database configuration

    Within the slapd.conf file, we can define our database backend and connection settings.

    Access: To define an "manager" account of the database, use the RootDN option. This entity will have

    no limits (like access control limits).

    RootDN: "cn=Manager,dc=rootkit,dc=nl"

    RootPW: secret

  • This DN can be protected with a password, as shown in the example above. The password can

    be saved in clear text or as a hash (hashed password can be created with slappasswd). # slappasswd

    New password:

    Re-enter new password:

    {SSHA}a5vgUC+7Sgc6thpZ8w3IN+OUAOj+HnQL

    Slapd

    To run a OpenLDAP server, we have to start the slapd process, which stands for Stand-alone

    LDAP Daemon. By default the daemon listens at TCP port 389 (or 636 for LDAPS) for

    incoming requests.

    Most options to start the daemon are very common, like defining debug level, network

    connectivity, configuration file location. For security the -r option is interesting, to chroot the

    daemon (and therefor limiting the access to other files in case of a security breach).

    TLS/SSL To use encryption, slapd can be started with the -h parameter, defining which protocols are

    available (and on which network addresses/ports).

    Example: slapd -h ldap://127.0.0.1:389 ldaps:///

    In this example slapd will listen on the local machine at the default port 389 (TCP) for

    unencrypted LDAP requests, and listen to all available network addresses at the default

    LDAPS port (636/TCP) for encrypted requests).

    Tool mode Slapd can also be used to start the more used tools like slapadd, slapcat etc. This "tool mode"

    is available as a backup when the normal scripts/tools are not present.

    Pre capacity planning

    Before creating a directory, you should have at least answered a few basic questions:

    What data do I want to store?

    What is the initial size of the data? What after 1 year? 3 years? 10 years?

    Can I scale my hardware to the needs of the directories?

    What will be my peek times?

    Which redundancy do I need? at what cost?

    Capacity planning can save a lot of troubles later on, especially when the amount of data is

    growing rapidly.

    Creating an initial directory

    A common way to fill a directory is by using LDIF files (LDAP Data Interchange Format).

    These plain text files can be used to insert, modify or delete data. LDIF files can be imported

  • by using ldapadd (which authenticates to a running service) or with slapadd (directly into a

    database while LDAP daemon is offline). The data being imported has to be redirected on the

    stdin (example: slapadd < filename.ldif).

    Example: dn: uid=michael,ou=People,dc=rootkit,dc=nl

    uid: michael

    cn: Michael Boelen

    objectClass: account

    objectClass: posixAccount

    objectClass: top

    userPassword: {crypt}rF4x4xNEP1bA.

    loginShell: /bin/sh

    uidNumber: 3000

    gidNumber: 3000

    homeDirectory: /home/michael

    gecos: Michael Boelen, Administrator

    Changing entries

    To extend or change existing directory entries, we can use a LDIF file with the changetype

    option.

    Example: dn: cn=Michael,ou=People,dc=rootkit,dc=nl

    # modify DN above

    changetype: modify

    # Add phone number

    add: telephonenumber

    telephonenumber: 1234567890

    Common changetypes:

    add: add a field, or if "add" is omitted, add a new entry. Add is the default

    action when no changetype is specified in LDIF files.

    delete: delete a field, or if "delete" is omitted, delete entry

    modify: modify a field

    modrdn: rename DN (only if no child entries are present)

    In addition, for these actions there are commands which can be directly used: ldapadd,

    ldapmodify, ldapdelete, ldapmodrdn.

    Extending directories

    # ldapadd -x -D "cn=admin,dc=rootkit,dc=nl" < /data/ldap/michael.ldif

    ldap_bind: Server is unwilling to perform (53)

    additional info: unauthenticated bind (DN with no password)

    disallowed

    # ldapadd -x -D "cn=admin,dc=rootkit,dc=nl" -W < /data/ldap/michael.ldif

    Enter LDAP Password:

    adding new entry "uid=michael,ou=People,dc=rootkit,dc=nl"

  • LDAP referrals LDAP directories can redirect a request to another server, for example when a "write" request

    is being performed on a read-only slave. The slave host redirects the client with the request, to

    the correct server.

    Schema and objectClass definitions

    Within the context of LDAP, schema's define what a directory looks like and which attributes

    it contains. Every element in a schema is identified by a globally unique Object Identifier

    (OID), which looks the same as in the SNMP protocol. An OID consists of a string with

    numbers (example: 1.3.6.1.4.1.7165.2.2.6). When creating or extending a schema, an unique

    OID should be used and can not be 'hijacked' from an existing OID tree. Instead, a new OID

    should be registered at IANA.

    Schema's can be included in the main configuration file (slapd.conf) by using the include

    directive (example: include /path/to/core.schema).

    Example snippet from core schema: attributeType ( 2.5.4.41 NAME 'name'

    DESC 'name(s) associated with the object'

    EQUALITY caseIgnoreMatch

    SUBSTR caseIgnoreSubstringsMatch

    SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{32768} )

    attributeType ( 2.5.4.3 NAME ( 'cn' 'commonName' )

    DESC 'common name(s) associated with the object'

    SUP name )

    OID 2.5.4.41 has the alias 'name' with a syntax and data type description.

    Structural and auxiliary object classes An object class is structural when it defines to which object(s) the object belongs to. All

    others are auxiliary object classes, which have the purpose to extend existing objects with

    extra attributes. Every entry can not have more than one structural object class. Also if the

    structural object class of an entry has to be changed, this can be only done by recreating the

    entry.

    OpenLDAP has a few default schema's, which are often used. For example, there is a NIS

    based schema, to support authentication of systems and people for example. /etc/ldap/schema# ls -l

    -rw-r--r-- 1 root root 2180 2008-04-07 23:34 collective.schema

    -rw-r--r-- 1 root root 2084 2008-04-07 23:34 corba.schema

    -rw-r--r-- 1 root root 21175 2008-04-07 23:34 core.ldif

    -rw-r--r-- 1 root root 20346 2008-04-07 23:34 core.schema

    -rw-r--r-- 1 root root 12091 2008-04-07 23:34 cosine.ldif

    -rw-r--r-- 1 root root 14030 2008-04-07 23:34 cosine.schema

    -rw-r--r-- 1 root root 10476 2008-04-07 23:34 duaconf.schema

    -rw-r--r-- 1 root root 3146 2008-04-07 23:34 dyngroup.schema

    -rw-r--r-- 1 root root 3573 2008-04-07 23:34 inetorgperson.ldif

    -rw-r--r-- 1 root root 6362 2008-04-07 23:34 inetorgperson.schema

    -rw-r--r-- 1 root root 3295 2008-04-07 23:34 java.schema

    -rw-r--r-- 1 root root 2473 2008-04-07 23:34 misc.schema

    -rw-r--r-- 1 root root 5998 2008-04-07 23:34 nadf.schema

    -rw-r--r-- 1 root root 6891 2008-04-07 23:34 nis.ldif

    -rw-r--r-- 1 root root 7725 2008-04-07 23:34 nis.schema

  • -rw-r--r-- 1 root root 3393 2008-04-07 23:34 openldap.ldif

    -rw-r--r-- 1 root root 1602 2008-04-07 23:34 openldap.schema

    -rw-r--r-- 1 root root 4678 2008-04-07 23:34 ppolicy.schema

    -rw-r--r-- 1 root root 3593 2008-04-07 23:34 README

    Schema files provide useful information about which attributes may or must be filled in.

    samba3.schema example: objectclass ( 1.3.6.1.4.1.7165.2.2.6 NAME 'sambaSamAccount' SUP top

    AUXILIARY

    DESC 'Samba 3.0 Auxilary SAM Account'

    MUST ( uid $ sambaSID )

    MAY ( cn $ sambaLMPassword $ sambaNTPassword $ sambaPwdLastSet $

    sambaLogonTime $ sambaLogoffTime $ sambaKickoffTime $

    sambaPwdCanChange $ sambaPwdMustChange $ sambaAcctFlags $

    displayName $ sambaHomePath $ sambaHomeDrive $

    sambaLogonScript $

    sambaProfilePath $ description $ sambaUserWorkstations $

    sambaPrimaryGroupSID $ sambaDomainName $ sambaMungedDial $

    sambaBadPasswordCount $ sambaBadPasswordTime $

    sambaPasswordHistory $ sambaLogonHours))

    Attributes consist of an unique OID and several fields, to describe what type of data is hold.

    Some examples of the fields are: name (case sensitive unique name)

    - description (description of the data in it)

    - equality (for example to ignore capitals)

    - substring (for example searching a part of the string, is enough to show up as a result)

    - syntax.

    Searching/Querying LDAP directories

    ldapsearch -x "(cn=Michael Boelen)"

    ldapsearch -x "(ou=people)" "(objectClass=account)"

    When multiple records are found, output will be in LDIF format.

    Search on multiple fields: When a search query has to match 2 or more fields, the ampersand sign (&) can be used.

    Example: (&(objectClass=posixAccount)(uid=michael))

    In this example the user id has to be 'michael' and it should be of the type "posix account"

    (used in nis schema).

    Examples: Search full tree:

    ldapsearch -b "dc=rootkit,dc=nl" -s sub "objectclass=*"

    Search a single contact (CN) and return specific fields:

    ldapsearch -b "dc=rootkit,dc=nl" "cn=Michael Boelen" mail telephonenumber

    Search everyone from the office in Germany:

    ldapsearch -b "o=Office Germany,dc=rootkit,dc=nl"

  • Exam note: You should be familiar with searching data and optimizing LDAP queries. Use

    proper search filters to minimize the amount of entries returned.

    LDAP tools overview

    slapadd Usage: add data

    When to use: importing LDIF files to extend or restore the directory.

    Notes: Tool should be used when slapd is offline

    slapacl Usage: test if access control lists are defined properly.

    When to use: for example after creating a new user to see if his/her permissions are correct.

    Notes: -

    slapcat Usage: dump LDAP database to LDIF format.

    When to use: when new data has to be inserted via slapadd or when creating a text backup of

    your database.

    Notes: -

    slapindex Usage: recreate indices for slapd database(s).

    When to use: after changing slapd.conf (like adding/removing schema's), or database

    problems.

    Notes: run as the same slapd id, to prevent file permission issues. Also make sure the

    databases are not in use.

    Exam note: Be familiar with the tools and when to use them.

    Database configuration and tweaking

    By default OpenLDAP uses the hdb backend (which is the hierarchical version of a Berkeley

    Database Backend (BDB)). The database and related configuration file (DB_CONFIG) can be

    found in /var/lib/ldap. /var/lib/ldap# ls -l

    -rw-r--r-- 1 openldap openldap 2048 2008-04-20 16:10 alock

    -rw------- 1 openldap openldap 8192 2008-04-20 16:10 __db.001

    -rw------- 1 openldap openldap 2629632 2008-04-20 16:10 __db.002

    -rw------- 1 openldap openldap 98304 2008-04-20 16:10 __db.003

    -rw------- 1 openldap openldap 565248 2008-04-20 16:10 __db.004

    -rw------- 1 openldap openldap 24576 2008-04-20 16:10 __db.005

    -rw-r--r-- 1 openldap openldap 96 2008-04-20 16:10 DB_CONFIG

    -rw------- 1 openldap openldap 8192 2008-04-20 16:10 dn2id.bdb

    -rw------- 1 openldap openldap 32768 2008-04-20 16:10 id2entry.bdb

    -rw------- 1 openldap openldap 53766 2008-04-20 16:10 log.0000000001

    -rw------- 1 openldap openldap 8192 2008-04-20 16:10 objectClass.bdb

    Common errors: /var/lib/ldap# db4.6_stat -c a

    db4.6_stat: Program version 4.6 doesn't match environment version 0.77

  • db4.6_stat: DB_ENV->open: DB_VERSION_MISMATCH: Database environment

    version mismatch

    Solution: check which db version is used (apt-cache showpkg slapd) and

    install the correct db-utils (apt-get install db4.2-util).

    Tuning cache: One of the options to tune is the cachesize. This size describes the number of entries it will

    hold in it's cache. This option can be set in DB_CONFIG.

    Check points: OpenLDAP can use check points (snapshots). Configuring checkpoints is generally a good

    idea, or else if things crash there will be no recovery point available.

    Example: checkpoint 256 15

    (make a check every 256 kilobyte of data or every 15 minutes, whichever occurs first).

    The option 'dbnosync' can be used together with check points. It can improve performance,

    since changes don't get written back to the database (from memory). However, when the

    server crashes all data between the last check point and the crash, is lost.

    Proper indexing: By using proper indexes, (and well formed) requests could be speed up greatly.

    Database indexing

    To optimize search requests, OpenLDAP can be configured to put an index on one or more

    fields. Using indices can improve performance huge, but also decrease when improperly used

    (ie. index at wrong fields or too much indices). Creating performance statistics (or graphs) can

    be a good help in maintaining a properly optimized LDAP server. The general rule for

    creating an index: if you use the attribute often in a search, create an index for it.

    slapd.conf example: index cn,sn,givenname,mail eq

    This snippet will add an index to the attributes cn, sn, givenname and mail. It will index only

    the full strings in these attributes, since the type is 'eq', which means only exact matches will

    show up in the search results.

    Index types:

    approx: phonetic match

    eq: exact match

    pres: value present or not

    sub: substring matching

    Note: When adding one or more indexes, slapd won't use them automatically. You have to

    run slapindex to recreate the indexes. Keep in mind to execute slapindex as the correct

    database user, to avoid an incorrect file owner on the database files.

  • OpenLDAP client configuration

    The OpenLDAP client tools (ldap*) use the configuration file /etc/openldap/ldap.conf.

    Example /etc/openldap/ldap.conf: URI ldaps://ldap.rootkit.nl/

    BASE dc=rootkit,dc=nl

    TLS_CACERT /etc/ssl/ca-cert.pem

    When using PAM, the nss_ldap module use the /etc/ldap.conf file, to find server connection

    information.

    Example /etc/ldap.conf: host ldap1.rootkit.nl ldap2.rootkit.nl

    base dc=rootkit,dc=nl

    ssl start_tls

    tls_checkpeer yes

    tls_cacertfile /etc/ssl/ca-cert.pem

    LDAP and authentication

    Check if the LDAP module (pam_ldap.so) is already installed, or install if not present. apt-get install libpam-ldap

    Check /etc/auth-client-config/profile.d/ldap-auth-config to see which PAM sections are

    applied and run the auth-client-config tool. # auth-client-config -p lac_ldap -t pam-auth

    # auth-client-config -p lac_ldap -t pam-password

    # auth-client-config -p lac_ldap -t pam-account

    # auth-client-config -p lac_ldap -t pam-session

    This will add the pam_mkhomedir.so, so a new home directory is created after logging in

    Check the nsswitch.conf file to include LDAP in search queries. # /etc/nsswitch.conf

    #

    passwd: compat ldap

    group: compat ldap

    shadow: compat ldap

    Integration: Apache2 and LDAP

    # apt-get install apache2

    # apt-get install php5

    # apt-get install php5-ldap

    # a2enmod ldap

    # a2enmod authnz_ldap

    Add following snippet to the Apache VirtualHost configuration: AuthBasicProvider ldap

    AuthLDAPBindDN "cn=Admin,dc=rootkit,dc=nl"

    AuthLDAPBindPassword "test"

    AuthLDAPURL "ldap://127.0.0.1:389/ou=People,dc=rootkit,dc=nl?uid"

    AuthLDAPGroupAttributeIsDN on

    Require ldap-user michael

    AuthType basic

    AuthName "secret"

    See the Apache 2.2 mod_authnz page for more information.

  • Integration: Postfix and LDAP

    # apt-get install postfix-ldap

    Example snippet from main.cf:

    alias_maps = hash:/etc/aliases, ldap:/etc/postfix/ldap-aliases.cf

    and in /etc/postfix/ldap-aliases.cf:

    server_host = ldap.example.com

    search_base = dc=example, dc=com

    See the Postfix LDAP readme for more information.

    Integration: Sendmail and LDAP

    define(`confLDAP_CLUSTER', `Servers')

    define(`ALIAS_FILE', `ldap:')

    FEATURE(`access_db', `LDAP')

    FEATURE(`virtusertable', `LDAP')

    Integration: FreeRADIUS and LDAP

    Installation: # apt-get install freeradius-ldap

    Configuration: FreeRADIUS has a module called rlm_ldap which can be used for LDAP support. There is a

    mapping file (raddb/ldap.attrmap) between FreeRADIUS and LDAP to match attributes. An

    schema exists with the file name RADIUS-LDAPv3.schema and can be found in the doc

    directory. The objectclass for FreeRADIUS is radiusprofile.

    To configure LDAP support, edit the radiusd.conf configuration file and add an "ldap"

    section to the modules.

    Example: modules { ...

    ldap {

    server = localhost

    port = 636

    net_timeout = 1

    timeout = 2

    timelimit = 5

    ldap_debug = 0x0028

    ldap_connections_number = 5

    basedn = "o=Rootkit Org,c=NL"

    filter = "(uid=%u)"

    start_tls = no

    tls_mode = no

  • tls_cacertfile = /path/to/cacert.pem

    tls_cacertdir = /path/to/ca/dir/

    tls_certfile = /path/to/radius.crt

    tls_keyfile = /path/to/radius.key

    tls_randfile = /path/to/rnd

    tls_require_cert = "allow"

    default_profile = "cn=RadiusProfile,o=Rootkit Org,c=NL"

    access_attr = "dialupAccess"

    } }

    Integration: OpenSSH and LDAP

    include /etc/openldap/schema/openssh-lpk.schema

    sshd_config:

    UseLPK yes

    LpkServers ldap://10.1.7.1 ldap://10.1.7.2

    LpkUserDN ou=users,dc=example,dc=com

    LpkGroupDN ou=groups,dc=example,dc=com

    LpkBindDN cn=Manager,dc=example,dc=com

    LpkBindPw somepasswordifneeded

    LpkServerGroup somegroupname

    LpkForceTLS yes

    LpkSearchTimelimit 3

    LpkBindTimelimit 3

    /etc/ldap.conf (pam_ldap/nss_ldap):

    UseLPK yes

    LpkLdapConf /etc/ldap.conf

    n: uid=michael,ou=People,dc=rootkit,dc=nl

    sn: michael

    cn: Michael Boelen

    gecos: Michael Boelen

    uidNumber: 1001

    gidNumber: 1001

    uid: michael

    homeDirectory: /home/michael

    loginShell: /bin/bash

    objectClass: inetOrgPerson

    objectClass: person

    objectClass: ldapPublicKey

    objectClass: posixAccount

    sshPublicKey: ssh-rsa Ss6tx...

    sshPublicKey: environment="LDP_USER=michael" ssh-rsa AAAAB...

    Integration: Samba and LDAP

    Installing Samba: apt-get install samba

    apt-get install samba-doc

    apt-get install smbldap-tools

    Before Samba can access the LDAP server, you need to store the LDAP admin password in

    the Samba database (secrets.tdb). This can be done with the following command: # smbpasswd -w secret

  • This Samba database can be inspected by using the tdbdump tool.

    Import samba3.schema cp /usr/share/doc/samba-doc/examples/LDAP/samba.schema.gz /etc/ldap/schema/

    gunzip /etc/ldap/schema/samba.schema.gz

    Required schema's for Samba Edit slapd.conf:

    include /etc/openldap/schema/cosine.schema

    include /etc/openldap/schema/inetorgperson.schema

    include /etc/openldap/schema/nis.schema

    include /etc/openldap/schema/samba.schema

    When everything is configured, run `slapindex` to create the indexes.

    To convert smbpasswd databases and create an import for LDAP, it's recommended to use a

    tool (like mkntpwd or pdbedit). Example of importing an existing database: pdbedit --import=smbpasswd:/etc/samba/smbpasswd --

    export=ldapsam:ldap://ldap.example.com

    Example of an samba account (sambaSamAccount) in LDAP: objectClass: sambaSamAccount

    sambaAcctFlags: [U ]

    sambaLMPassword: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

    sambaNTPassword: yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy

    sambaSID: S-1-0-0-14966

    The sambaSID value is created by taking the primary SID and an unique ID. This ID is made

    by taking the Unix uid, multiple it by 2 and add 1000 (or 1001 for groups, or gids). dn: uid=michael,ou=People,dc=rootkit,dc=nl

    sambaLogonTime: 0

    displayName: Michael Boelen

    sambaLMPassword: 552902031BEDE9EFAAD3B435B51404EE

    sambaPrimaryGroupSID: S-1-5-21-2447931902-1787058256-3961074038-1201

    objectClass: posixAccount

    objectClass: sambaSamAccount

    sambaAcctFlags: [UX ]

    userPassword: {crypt}CzZ2ek9Rrreti

    uid: michael

    uidNumber: 1001

    cn: Michael Boelen

    loginShell: /bin/bash

    logoffTime: 2147483647

    gidNumber: 1001

    sambaKickoffTime: 2142283620

    sambaPwdLastSet: 1022199456

    sambaSID: S-1-5-21-2447931902-1787058256-3961074038-5004

    homeDirectory: /home/michael

    sambaPwdCanChange: 0

    sambaPwdMustChange: 2147483647

    sambaNTPassword: 878D8014606CDA29677A44EFA1353FC7

    Example of smb.conf: security = user

    passdb backend = ldapsam:ldap://ldap.example.com

    ldap ssl = start tls

    ldap suffix = dc=example,dc=com

    ldap user suffix = ou=people

    ldap group suffix = ou=group

    ldap admin dn = uid=admin,ou=people,dc=rootkit,dc=nl

  • The option passdb defines which backend is being used, to store passwords. Since we want to

    use LDAP, we use the ldapsam option.

    Required attributes: Samba3 (sambaSamAccount): uid sambaSID

    Integration: Dovecot POP/IMAP and LDAP

    Example snippet from Dovecot configuration file: auth default {

    mechanisms = plain

    passdb ldap {

    args = /etc/dovecot/dovecot-ldap.conf

    }

    userdb ldap {

    args = /etc/dovecot/dovecot-ldap.conf

    }

    }

    The file /etc/dovecot/dovecot-ldap.conf contains the LDAP specific settings (base, scope,

    filter string).

    Integration: Pure-FTPd and LDAP

    Pure-FTPd uses the default 'posixAccount' object class, which is included in the nis schema.

    Integration: CUPS printing and LDAP

    Steps:

    PAM with ldap support (pam_ldap)

    Configure PAM to support LDAP lookups (/etc/pam.d)

    Edit /etc/ldap.conf to match your LDAP settings

    Some of the available LDAP options within cupsd.conf:

    BrowseLDAPBindDN admin

    BrowseLDAPDN foobar

    BrowseLDAPPassword mypass

    BrowseLDAPServer localhost

    BrowseLocalProtocols ldap

    BrowseRemoteProtocols ldap

    Integration: Kerberos and LDAP

  • When combining LDAP with Kerberos a single sign-on solution can be created, for example

    to allow cross platform authentication, but also for usage with different applications.

    Create SSL certificate for LDAP servers: $ kadmin

    > addprinc -randkey ldap/HOSTNAME

    > ktadd -k /etc/openldap/ldap.keytab ldap/HOSTNAME

    $ chgrp ldap /etc/openldap/ldap.keytab; chmod 640

    /etc/openldap/ldap.keytab

    KRB5_KTNAME=/etc/openldap/ldap.keytab /usr/sbin/slapd -u ldap -h "ldap:/// ldaps:///"

    Integration: Active Directory and OpenLDAP

    Integrating Microsoft Active Directory with Unix can be done in different ways, varying in

    software being used:

    Import schema into Active Directory to support additional Unix related fields

    Talk with Winbind (Samba) to Active Directory (domain controller)

    Use OpenLDAP's proxy mechanism

    When using OpenLDAP together with Active Directory (for example when proxying), the

    base option in slapd.conf should be set to: cn=Users,dc=rootkit,dc=nl or

    cn=Users,dc=MyDomain,dc=rootkit,dc=nl. nss_base_passwd cn=Users,dc=rootkit,dc=nl?sub

    nss_base_shadow cn=Users,dc=rootkit,dc=nl?sub

    nss_base_group cn=Users,dc=rootkit,dc=nl?sub

    nss_map_objectclass posixAccount user

    nss_map_objectclass shadowAccount user

    nss_map_attribute uid sAMAccountName

    nss_map_attribute uidNumber msSFU30UidNumber

    nss_map_attribute gidNumber msSFU30GidNumber

    nss_map_attribute loginShell msSFU30LoginShell

    nss_map_attribute gecos name

    nss_map_attribute userPassword msSFU30Password

    nss_map_attribute homeDirectory msSFU30HomeDirectory

    nss_map_objectclass posixGroup Group

    nss_map_attribute uniqueMember msSFU30PosixMember

    nss_map_attribute cn cn

    pam_login_attribute sAMAccountName

    pam_filter objectclass=user

    pam_member_attribute msSFU30PosixMember

    pam_groupdn cn=unixusergroup,dc=rootkit,dc=nl

    pam_password ad

    Integration notes: - Active directory users are in the form of

    "CN=Administrator,CN=Users,DC=ad,DC=rootkit,DC=nl".

    Migration: NIS to LDAP

  • NIS uses maps to combine all information for users, groups and authentication. By using the

    command ypwhich -m we can see which maps are present, together with the master server.

    This information helps when planning a migration to LDAP.

    Map files generally are located within /etc/yp or /var/yp.

    Migration Using migration tools is the recommended way of migrating NIS information to LDAP. The

    tools have builtin checks (to test for issues like double user ids) and convert information

    where needed (like shadow files). In case an user is migrated by hand, make sure the

    password hash type is available in the userPassword field.

    NIS to LDAP gateway When migrating from NIS to LDAP, it can be useful to have a temporary gateway. This way

    new or migrated clients can already talk to the LDAP service directly, while older clients use

    NIS. Another option is a NIS gateway, which uses NIS on the front (client to NIS gateway)

    and LDAP in the back (NIS gateway to LDAP server).

    Some tools:

    Penrose

    Sun's Network Information Service (NIS) to LDAP transition service (N2L

    service)

    ypldapd (from PADL)

    YPTransitd

    Replication

    Replication is the process of syncing data between two or more nodes. In this process there is

    often one master and multiple slave nodes, where the master is leading. The master will

    operate as a replication hub, a central point which pushes data to all slaves, or where all

    slaves connect to for data updates.

    Slurpd Note: Slurpd replication was removed since OpenLDAP 2.4, but still an exam requisite.

    Slurpd is a daemon to keep master and slaves in sync. When data is changed on the master,

    slurpd will replicate data to the slaves, on a regular period. This replication is done by using a

    replication log (defined by the replog option in slapd.conf), with the change(s) and synced to

    the slaves. The format of the log is a variant to the LDIF format, with having extra command

    and information lines in it.

    When a client tries to perform a change on a slave, the slave server will send a referral back

    to the client instructing it to go to the appropriate master server. This way the master server

    also serves as a replication hub, a central point to store data and serve it to the slave server(s)

    connected to it.

    Slurpd has also an option called one-shot mode (with parameter -o). It will do the replication

    between the master and slaves, and exit directly.

    Disadvantages of Slurpd: - Only push-mode: pushing data from master node to slaves

    Setting up

  • Master:

    Add directive: replica

    Add directive: replogfile

    Slave: Same configuration as master, except:

    Do NOT use directives replica and replogfile

    Add updatedn (which should be the same value as binddn on the

    master)

    Make sure the DN has enough rights to write data

    When everything is configured, restart the master LDAP server (tip: running it in read-only

    mode is a good thing, to make sure changes are not propagated to the master instead).

    Syncrepl The LDAP Sync replicator works on a client-server based model. A consumer (client) can

    maintain a (partial) shadow copy of a DIT, which is provided by a provider (server). Syncrepl

    is able to sync from zero to a full replicate, or from a out of date copy to fully updated, by

    using incremental updates.

    The replication can be done in two ways:

    - refreshOnly

    The provider uses a pull-based method, by using the replication request information from the

    consumer. The provider does not maintain a "notify" list of the consumers, when new data is

    available.

    - refreshAndPersist

    The provider uses a push-based method, and keeps track of the consumers which need to be

    notified when new data is available.

    Replication works best when using the back-bdb or back-hdb backend.

    Advantages of Syncrepl: - Can sync full or partial data sets

    Performance testing

    Tests

    Disk - Create a big file with dd to see read/write speed

    - Test output of iostat under low/high utilization, to see CPU

    block on IO requests

    - Create benchmark with bonnie++

    Firewall - Stress test LDAP or other services and measure especially

    CPU load and memory increase

  • Network - Test transfer rate on private network segment, by FTP/SCP

    files

    LDAP

    daemon - Test number of concurrent requests

    - Test answering time of incoming requests

    Tuning and monitoring

    While maintaining a running OpenLDAP server, it's important to monitor several components

    of the system, like CPU usage, memory and disk utilization. This helps in troubleshooting

    capacity problems, but also planning and extending capacity demands.

    Some parts to measure are:

    - Normal amount of requests (per day/hour for trend analysis)

    - Peek times requests, server load

    Monitoring can be best configured while setting up OpenLDAP, so an initial base line is

    available. While finishing the installation/configuration, the impact of ie. data imports can be

    made visible directly. Also test results (and monitoring) can be tested without problems when

    no users are active yet.

    Later on, when everything is in production, trends can be followed (like average increase of

    users, data traffic usage, peek times). Another reason to start monitoring from the beginning,

    is to predict the growth rate of the application(s) and to be ahead with monitoring data before

    problems occur. When they do occur, you can very quickly compare memory usage, CPU

    load, network traffic and more, with the base line created early. With some stress testing tools,

    it's also possible to predict the borders of what your machine can handle and what not. In

    many cases you quickly can identify the bottlenecks of the system at stress tests, by keeping

    an eye on most common factors. If for example CPU load rises to a high value, but memory

    usage stays low, you can conclude that optimizing the processing speed of requests is more

    important instead of adding extra memory banks.

    Using monitoring and testing tools, a performance equation can be made, to test what impact

    small adjustments have on the system (and speed, responsiveness etc). This can be

    adjustments related system tweaking/tuning, but also things which influent the system in a

    "negative" way, like adding an IP chains packet filter (adding a packet filter is good, but it

    will come as usual at a cost, as in extra delay to fulfill a request).

    Most of the monitoring will be performed at connection side of the server. However, don't

    forget to do some testing at the clients like response time of small and big request results.

    Pretty Damn Quick One of the capacity planning tools which you can use, is mentioned in the exam objectives,

    named PDQ (Pretty Damn Quick). See Performance Dynamics Company website.

    Monitoring tools

    CPU usage iostat, mpstat, w, uptime

    Disk utilization iostat, lsof, vmstat (-d)

  • Memory usage top, vmstat, cat /proc/mem

    Network usage ifstat

    Swap file usage swapon -s

    Another nice tool to mention is sar, which can collect system information. If you want to test

    memory at full potential, make sure to disable swap (with swapoff). Swapping itself means

    more disk writes/reads and can be a big influence on system performance and the testing

    results.

    Monitoring LDAP OpenLDAP has special database backend to monitor the system, called "monitor". To enable

    this, perform the following steps:

    - Load module (moduleload back_monitor)

    - Create database section (database monitor) with ACL access to * by dn="cn=Admin,dc=rootkit,dc=nl" read

    by * none

    # ldapsearch -x -D 'cn=Admin,dc=rootkit,dc=nl' -W -b 'cn=Monitor' -s base '(objectClass=*)'

    '*' '+'

    Search result should give something like:

    # Write, Waiters, Monitor

    dn: cn=Write,cn=Waiters,cn=Monitor

    objectClass: monitorCounterObject

    cn: Write

    # search result

    search: 2

    result: 0 Success

    # numResponses: 59

    # numEntries: 58

    The monitoring capabilities are extensive and can give much (detailed) information. A small

    example to see which backends are supported: # ldapsearch -x -D 'cn=Admin,dc=rootkit,dc=nl' -W -b

    'cn=Backends,cn=Monitor' -s base '(objectClass=*)' '+' '*'

    Enter LDAP Password:

    # extended LDIF

    #

    # LDAPv3

    # base with scope baseObject

    # filter: (objectClass=*)

    # requesting: + *

    #

    # Backends, Monitor

    dn: cn=Backends,cn=Monitor

    objectClass: monitorContainer

    structuralObjectClass: monitorContainer

    cn: Backends

    creatorsName:

    modifiersName:

    createTimestamp: 20080427090213Z

    modifyTimestamp: 20080427090213Z

    description: This subsystem contains information about available

    backends.

    monitoredInfo: config

  • monitoredInfo: ldif

    monitoredInfo: hdb

    monitoredInfo: monitor

    entryDN: cn=Backends,cn=Monitor

    subschemaSubentry: cn=Subschema

    hasSubordinates: TRUE

    # search result

    search: 2

    result: 0 Success

    # numResponses: 2

    # numEntries: 1

    Debugging: Logging

    OpenLDAP logs to syslog via the LOCAL4 level. With the option loglevel in slapd.conf we

    can increase or decrease the amount of logging. The option loglevel understands decimal,

    hexdecimal, or names as parameter.

    Example: loglevel 16384 (alias of sync, replication traffic)

    loglevel acl sync (multiple names)

    When using a loglevel of -1, it will enable all debugging information. By default a loglevel of

    256 is used.

    Create an empty log file:

    # touch /var/log/ldap.log

    Edit /etc/syslog.conf:

    local4.* /var/log/ldap.log

    Inform syslogd about the changes:

    # killall -HUP syslogd

    Security: SASL

    SASL stands for Simple Authentication and Security Layer, an additional security layer

    which gives servers and clients the option to discuss which (most secure) authentication they

    both have.

    Steps:

    1. Client initiates session to server

    2. Server acknowledges connection and sends back which authentication methods are

    accepted

    3. Client picks the preferred method from the list and confirms the chosen option

    Cyrus

    Make sure it has support for Kerberos V (and GSSAPI, the API used by the tools to talk).

    Database: /etc/sasldb2.db

    Managing users:

  • Enable/create account: saslpasswd2 -c -u DOMAIN USERID

    Disable/delete account: saslpasswd2 -d -u DOMAIN USERID

    Show users: To view a SASL database, we can use the sasldblistusers2 tool (in package sasl2-bin).

    Example: # sasldblistusers2

    user1@test: userPassword

    With testsaslauthd a newly created account can be tested. Example: # /usr/local/sbin/testsaslauthd -u user1 -p user1

    0: OK "Success."

    Security: Proxy Authorization

    SASL offers the option for authorization proxying, to allow an intermediate user between the

    end user and the LDAP server. This intermediate user will make requests on behalf of the end

    user. An example is when using a web interface, where an user can change his/her password.

    The web application connects with a dedicated user name (ie.

    cn=webproxy,dc=rootkit,dc=nl), but is via ACLs allowed to make changes for another user.

    The LDAP server will think it's the end user itself, who is performing the requests. To make

    proxy authorization work, the LDAP administrator can add the following attributes to LDAP

    entries: dn: cn=webproxy,dc=rootkit,dc=nl

    authzTo: ldap:///dc=rootkit,dc=nl??sub?(objectclass=person)

    This example gives the DN 'cn=webproxy,dc=rootkit,dc=nl' the permission to work on behalf

    of all entities with the objectclass 'person'.

    Another option is to use the authzFrom.

    Security: Authentication methods

    When a client connects to a server, it can do this on two different ways: simple method (with

    -x) or SASL method.

    anonymous: no username or password. Anonymous connections are allowed

    by default, but can be disabled with the option disallow bind_anon.

    unauthenticated: a username name is provided, but no password. By default

    these kind of connections are disabled, but can be enabled with "allow

    bind_anon_cred"

    user/password authenticated: a username and password is provided.

    Simple binds can be completely disabled with disallow bind_simple, to increase security

    when for example SASL is being used..

    Security: Client/Server certificates

  • Client certificates: On the LDAP server side we can ask a client to use (or even force) an client certificate. This

    can be achieved with the TLSVerifyClient option.

    TLSVerifyClient { never | allow | try | demand }

    Never: the server will not ask for a certificate

    Allow: ask the client for a certificate. If a valid one is provided, use it. If the

    certificate is invalid, ignore it.

    Try: same as Allow. However if the certifcate is invalid, inmediately

    disconnect.

    Demand: force the client to provide a certificate. If no certificate is given or a

    certificate is invalid, the connection will be disconnected.

    Server certificates: TLS_REQCERT { never | allow | try | demand }

    This option works the same as TLSVerifyClient, except that it checks the

    certificate from the server instead.

    /etc/ldap.conf:

    TLS_CACERT /usr/share/ssl/certs/ca.cert

    Security: Hardening LDAP servers

    Disallow anonymous binds: Add disallow bind_anon to slapd.conf

    Firewalling with iptables: When using a local LDAP server, iptables should allow local

    traffic: -A INPUT -i lo -j ACCEPT

    When using traffic from the (inter)network, allow incoming traffic (these rules could be

    restricted by adding specific networks or interfaces): # Ports 389 TCP (ldap), 636 TCP(ldaps)

    -A INPUT -m state --state NEW -p tcp --dport ldap -j ACCEPT

    -A INPUT -m state --state NEW -p tcp --dport ldaps -j ACCEPT

    Security: Access Control Lists

    By using the access keyword, access to all or specific DNs can be restricted. This way the

    LDAP server can be protected against unauthorized data removal, changes and inserts.

    When users or hosts connect to a LDAP server, they can be a guest (=anonymous) or an

    authenticated user (=users). If both (anonymous,users) are allowed to connect for example,

    we can use a wildcard (=*). Another possibility is to compare the DN the users belong to with

    dn[.]= (user matches regular expression) or dn.=

    (user is within the scope of a DN). A special one is self, which defines that the owner of the

    entry is the same as the user to authenticate.

  • Permission Alias Gives right to

    none =0 no access

    disclose =d information disclosure on error

    auth =dx authenticate (bind) permission

    compare =cdx compare

    search =scdx apply search filters

    read =rscdx read search results

    write =wrscdx modify/rename data

    manage =mwrscdx manage

    Security: TLS/SSL

    StartTLS TLS is a security enhancement, to allow applications use encrypted conversations, but still

    allow backwards compatibility. This way programs (and the network traffic) can be hardened,

    and still operate at common port numbers (389/TCP by default).

    A simple example to display the use of StartTLS:

    Client Server

    Hello -->

  • Country Name (2 letter code) [AU]:NL

    State or Province Name (full name) [Some-State]:My State

    Locality Name (eg, city) []:My City

    Organization Name (eg, company) [Internet Widgits Pty Ltd]:My Company

    Organizational Unit Name (eg, section) []:

    Common Name (eg, YOUR name) []:ldap.rootkit.nl

    Email Address []:[email protected]

    /etc/ldap/ssl# openssl genrsa -out /etc/ldap/ssl/ca.key 1024

    (Note: Add -des3 to create a CA key WITH password)

    Generating RSA private key, 1024 bit long modulus

    ...........++++++

    ..............................++++++

    e is 65537 (0x10001)

    /etc/ldap/ssl# openssl rsa -in /etc/ldap/ssl/ca.key -out

    /etc/ldap/ssl/ca.key

    writing RSA key

    /etc/ldap/ssl# openssl req -new -x509 -days 365 -key

    /etc/ldap/ssl/ca.key -out /etc/ldap/ssl/ca.crt

    You are about to be asked to enter information that will be

    incorporated

    into your certificate request.

    What you are about to enter is what is called a Distinguished Name or a

    DN.

    There are quite a few fields but you can leave some blank

    For some fields there will be a default value,

    If you enter '.', the field will be left blank.

    -----

    Country Name (2 letter code) [AU]:NL

    State or Province Name (full name) [Some-State]:My State

    Locality Name (eg, city) []:My City

    Organization Name (eg, company) [Internet Widgits Pty Ltd]:My Company

    Organizational Unit Name (eg, section) []:

    Common Name (eg, YOUR name) []:Michael Boelen

    Email Address []:[email protected]

    Add to slapd.conf: TLSCertificateFile /etc/ldap/ssl/server.crt

    TLSCertificateKeyFile /etc/ldap/ssl/server.key

    TLSCACertificateFile /etc/ldap/ssl/ca.crt

    Testing # gnutls-cli --print-cert -p 636 ldap.rootkit.nl (apt-get install gnutls-cli)

    Security: Security Strength Factors

    Existing ACL's can be hardened by adding Security strength factors (SFF) to them. This

    defines the strength of the connection/authentication. For example, DES is 56, 3DES is 112,

    and AES 128, 192, or 256. access to *

    by ssf=128 self write

    by ssf=64 anonymous auth

    by ssf=64 users read

  • Custom tooling: Perl

    Perl scripts Writing small scripts to automate repeating tasks, can be easily done in shell or Perl scripts.

    Since Perl is one of the objectives, will this be discussed further.

    Installation

    Option 1: from tar ball gunzip perl-ldap-0.36.tar.gz

    tar xfvz perl-ldap-0.36.tar

    cd perl-ldap-0.36

    perl Makefile.PL

    make

    make test

    make install

    Option 2: CPAN shell # perl -MCPAN -e shell

    (note: when running first time, CPAN will ask for first time

    settings/preferences)

    cpan> install Net::LDAP

    The CPAN shell will handle dependencies and ask in interactive mode if these have to be

    installed.

    Example code: #!/bin/perl -w

    # Use LDAP library

    use Net::LDAP;

    # Bind DN values (in this case we use RootDN)

    my $dn = "cn=admin,dc=rootkit,dc=nl";

    my $passwd = "test";

    # Connect to LDAP server

    $ldap = Net::LDAP->new('localhost') or die "$@";

    # Bind with DN

    $mesg = $ldap->bind( $dn, password => $passwd, version => 3 ) or die

    "$@" + $mesg->code;

    $mesg = $ldap->search(

    base => "dc=rootkit,dc=nl",

    filter => "cn=Michael Boelen",

    );

    # Amount of entries returned

    my $max = $mesg->count;

    # Show error message if request was not successful

    if ($mesg->code) { print $mesg->error,"\n"; }

    for ( my $index = 0; $index < $max; $index++ ) {

    my $entry = $mesg->entry($index);

    my $dn = $entry->dn; # Obtain DN for entry

    @attrs = $entry->attributes; # Obtain attributes for entry

    foreach my $var (@attrs) {

    # Get all values for attribute

    $attr = $entry->get_value( $var, asref => 1 );

  • if ( defined($attr) ) {

    foreach my $value ( @$attr ) {

    print "$var: $value\n"; # Print each value for the

    attribute.

    }

    }

    }

    }

    # The End