<commit_before><?xml version="1.0" encoding="UTF-8"?>

<chapter xml:id="ldap-auth" xmlns="http://docbook.org/ns/docbook" version="5.0" xml:lang="en"
    xmlns:xi="http://www.w3.org/2001/XInclude"
    xmlns:xlink="http://www.w3.org/1999/xlink">
    <title>LDAP authentication</title>
    <indexterm>
        <primary>LDAP</primary>
    </indexterm>
    <para>Guacamole supports LDAP authentication via an extension available from the main project
        website. This extension allows users and connections to be stored directly within an LDAP
        directory. If you have a centralized authentication system that uses LDAP, Guacamole's LDAP
        support can be a good way to allow your users to use their existing usernames and passwords
        to log into Guacamole.</para>
    <para>To use the LDAP authentication extension, you will need:</para>
    <orderedlist>
        <listitem>
            <para>An LDAP directory as storage for all authentication data, such as OpenLDAP.</para>
        </listitem>
        <listitem>
            <para>The ability to modify the schema of your LDAP directory.</para>
        </listitem>
    </orderedlist>
    <para>The instructions here assume you already have an LDAP directory installed and working, and
        do not cover the initial setup of such a directory.</para>
    <important>
        <para>This chapter involves modifying the contents of <varname>GUACAMOLE_HOME</varname> -
            the Guacamole configuration directory. If you are unsure where
                <varname>GUACAMOLE_HOME</varname> is located on your system, please consult <xref
                linkend="configuring-guacamole"/> before proceeding.</para>
    </important>
    <section xml:id="ldap-architecture">
        <title>How Guacamole uses LDAP</title>
        <para>If the LDAP extension is installed, Guacamole will authenticate users against your
            LDAP server by attempting a bind as that user. The given username and password will be
            submitted to the LDAP server during the bind attempt.</para>
        <para>If the bind attempt is successful, the set of available Guacamole connections is
            queried from the LDAP directory by executing an LDAP query as the bound user. Each
            Guacamole connection is represented within the directory as a special type of group:
                <classname>guacConfigGroup</classname>. Attributes associated with the group define
            the protocol and parameters of the connection, and users are allowed access to the
            connection only if they are associated with that group.</para>
        <para>This architecture has a number of benefits:</para>
        <orderedlist>
            <listitem>
                <para>Your users can use their existing usernames and passwords to log into
                    Guacamole.</para>
            </listitem>
            <listitem>
                <para>You can manage Guacamole connections using the same tool that you already use
                    to manage your LDAP directory, such as <link
                        xlink:href="https://directory.apache.org/studio/">Apache Directory
                        Studio</link>.</para>
            </listitem>
            <listitem>
                <para>Existing security restrictions can limit visibility/accessibility of Guacamole
                    connections.</para>
            </listitem>
            <listitem>
                <para>Access to connections can easily be granted and revoked, as each connection is
                    represented by a group.</para>
            </listitem>
        </orderedlist>
        <important>
            <para>Though Guacamole connections can be stored within the LDAP directory, this is not
                required. Connection data can alternatively be stored within a database like MySQL
                or PostgreSQL as long as the LDAP username matches the username of the database
                user. Configuring Guacamole to use a database for authentication or connection
                storage is covered in <xref linkend="jdbc-auth"/> and later in this chapter in <xref
                    linkend="ldap-and-database"/>.</para>
        </important>
    </section>
    <section xml:id="ldap-downloading">
        <title>Downloading the LDAP extension</title>
        <para>The LDAP authentication extension is available separately from the main
                <filename>guacamole.war</filename>. The link for this and all other
            officially-supported and compatible extensions for a particular version of Guacamole are
            provided on the release notes for that version. You can find the release notes for
            current versions of Guacamole here: <link
                xlink:href="http://guacamole.incubator.apache.org/releases/"
                >http://guacamole.incubator.apache.org/releases/</link>.</para>
        <para>The LDAP authentication extension is packaged as a <filename>.tar.gz</filename> file
            containing:</para>
        <variablelist>
            <varlistentry>
                <term><filename>guacamole-auth-ldap-0.9.12-incubating.jar</filename></term>
                <listitem>
                    <para>The Guacamole LDAP support extension itself, which must be placed in
                            <filename>GUACAMOLE_HOME/extensions</filename>.</para>
                </listitem>
            </varlistentry>
            <varlistentry>
                <term><filename>schema/</filename></term>
                <listitem>
                    <para>LDAP schema files. An <filename>.ldif</filename> file compatible with
                        OpenLDAP is provided, as well as a <filename>.schema</filename> file
                        compliant with RFC-2252. The <filename>.schema</filename> file can be
                        transformed into the <filename>.ldif</filename> file automatically.</para>
                </listitem>
            </varlistentry>
        </variablelist>
    </section>
    <section xml:id="ldap-schema-changes">
        <title>Preparing your LDAP directory (optional)</title>
        <para>Although your LDAP directory already provides a means of storing and authenticating
            users, Guacamole also needs storage of connection configuration data, such as hostnames
            and ports, and a means of associating users with connections that they should have
            access to. You can do this either through modifying the LDAP directory schema, or
            through using a database like MySQL or PostgreSQL. If you do not wish to use the LDAP
            directory for connection storage, skip ahead to <xref linkend="ldap-and-database"
            />.</para>
        <para>If you wish to store connection data directly within the LDAP directory, the required
            modifications to the LDAP schema are made through applying one of the provided schema
            files. These schema files define an additional object class,
                <classname>guacConfigGroup</classname>, which contains all configuration information
            for a particular connection, and can be associated with arbitrarily-many users and
            groups. Each connection defined by a <classname>guacConfigGroup</classname> will be
            accessible only by users who are members of that group (specified with the
                <property>member</property> attribute), or who are members of associated groups
            (specified with the <property>seeAlso</property> attribute).</para>
        <important>
            <para>The instructions given for applying the Guacamole LDAP schema changes are specific
                to OpenLDAP, but other LDAP implementations, including Active Directory, will have
                their own methods for updating the schema.</para>
            <para>If you are not using OpenLDAP, a standards-compliant schema file is provided that
                can be used to update the schema of any LDAP directory supporting RFC-2252. Please
                consult the documentation of your LDAP directory to determine how such schema
                changes can be applied.</para>
        </important>
        <para>The schema files are located within the <filename>schema/</filename> directory of the
            archive containing the LDAP extension. You will only need one of these files:</para>
        <variablelist>
            <varlistentry>
                <term><filename>guacConfigGroup.schema</filename></term>
                <listitem>
                    <para>A standards-compliant file describing the schema. This file can be used
                        with any LDAP directory compliant with RFC-2252.</para>
                </listitem>
            </varlistentry>
            <varlistentry>
                <term><filename>guacConfigGroup.ldif</filename></term>
                <listitem>
                    <para>An LDIF file compatible with OpenLDAP. This file was automatically built
                        from the provided <filename>.schema</filename> file for convenience.</para>
                </listitem>
            </varlistentry>
        </variablelist>
        <para>This chapter will cover applying <filename>guacConfigGroup.ldif</filename> to an
            OpenLDAP server. If you are not using OpenLDAP, your LDAP server should provide
            documentation for modifying its schema. If this is the case, please consult the
            documentation of your LDAP server before proceeding.</para>
        <section>
            <title>Applying the schema changes to OpenLDAP</title>
            <para>Schema changes to OpenLDAP are applied using the <command>ldapadd</command>
                utility with the provided <filename>guacConfigGroup.ldif</filename> file:</para>
            <informalexample>
                <screen><prompt>#</prompt> <userinput>ldapadd -Q -Y EXTERNAL -H ldapi:/// -f schema/guacConfigGroup.ldif</userinput>
<computeroutput>adding new entry "cn=guacConfigGroup,cn=schema,cn=config"
</computeroutput>
<prompt>#</prompt></screen>
            </informalexample>
            <para>If the <classname>guacConfigGroup</classname> object was added successfully, you
                should see output as above. You can confirm the presence of the new object class
                using <command>ldapsearch</command>:</para>
            <informalexample>
                <screen><prompt>#</prompt> <userinput>ldapsearch -Q -LLL -Y EXTERNAL -H ldapi:/// -b cn=schema,cn=config dn</userinput>
<computeroutput>dn: cn=schema,cn=config

dn: cn={0}core,cn=schema,cn=config

dn: cn={1}cosine,cn=schema,cn=config

dn: cn={2}nis,cn=schema,cn=config

dn: cn={3}inetorgperson,cn=schema,cn=config

dn: cn={4}guacConfigGroup,cn=schema,cn=config
</computeroutput>
<prompt>#</prompt></screen>
            </informalexample>
        </section>
    </section>
    <section xml:id="ldap-and-database">
        <title>Associating LDAP with a database</title>
        <para>If you install both the LDAP authentication as well as support for MySQL or PostgreSQL
            (following the instructions in <xref linkend="jdbc-auth"/>), Guacamole will
            automatically attempt to authenticate against both systems whenever a user attempts to
            log in. That user will have access to any data associated with them via the database, as
            well as any visible objects within the LDAP directory. The LDAP account will be
            considered equivalent to the database user if the username is identical.</para>
        <para>Data can be manually associated with LDAP users by creating corresponding user
            accounts within the database which each have the same usernames as valid LDAP users. As
            long as the username is identical, a successful login attempt against LDAP will be
            trusted by the database authentication, and that user's associated data will be
            visible.</para>
        <para>If an administrator account (such as the default <systemitem>guacadmin</systemitem>
            user provided with the database authentication) has a corresponding user in the LDAP
            directory with permission to list and read other LDAP users, the Guacamole
            administrative interface will include LDAP users in the overall user list presented to
            the administrator, and allow connections from the database to be associated with those
            users directly.</para>
    </section>
    <section xml:id="installing-ldap-auth">
        <title>Installing LDAP authentication</title>
        <para>Guacamole extensions are self-contained <filename>.jar</filename> files which are
            located within the <filename>GUACAMOLE_HOME/extensions</filename> directory. To install
            the LDAP authentication extension, you must:</para>
        <procedure>
            <step>
                <para>Create the <filename>GUACAMOLE_HOME/extensions</filename> directory, if it
                    does not already exist.</para>
            </step>
            <step>
                <para>Copy <filename>guacamole-auth-ldap-0.9.12-incubating.jar</filename> within
                        <filename>GUACAMOLE_HOME/extensions</filename>.</para>
            </step>
            <step>
                <para>Configure Guacamole to use LDAP authentication, as described below.</para>
            </step>
        </procedure>
        <important>
            <para>You will need to restart Guacamole by restarting your servlet container in order
                to complete the installation. Doing this will disconnect all active users, so be
                sure that it is safe to do so prior to attempting installation. If you do not
                configure the LDAP authentication properly, Guacamole will not start up again until
                the configuration is fixed.</para>
        </important>
        <section>
            <title>Configuring Guacamole for LDAP</title>
            <indexterm>
                <primary>configuring LDAP</primary>
            </indexterm>
            <indexterm>
                <primary>LDAP</primary>
                <secondary>configuration</secondary>
            </indexterm>
            <para>Additional properties may be added to <filename>guacamole.properties</filename> to
                describe how your LDAP directory is organized and how Guacamole should connect (and
                bind) to your LDAP server. Among these properties, only the
                    <property>ldap-user-base-dn</property> property is required:</para>
            <variablelist>
                <varlistentry>
                    <term><property>ldap-hostname</property></term>
                    <listitem>
                        <para>The hostname of your LDAP server. If omitted, "localhost" will be used
                            by default. You will need to use a different value if your LDAP server
                            is located elsewhere.</para>
                    </listitem>
                </varlistentry>
                <varlistentry>
                    <term><property>ldap-port</property></term>
                    <listitem>
                        <para>The port your LDAP server listens on. If omitted, the standard LDAP or
                            LDAPS port will be used, depending on the encryption method specified
                            with <property>ldap-encryption-method</property> (if any). Unencrypted
                            LDAP uses the standard port of 389, while LDAPS uses port 636. Unless
                            you manually configured your LDAP server to do otherwise, your LDAP
                            server probably listens on port 389.</para>
                    </listitem>
                </varlistentry>
                <varlistentry>
                    <term><property>ldap-encryption-method</property></term>
                    <listitem>
                        <para>The encryption mechanism that Guacamole should use when communicating
                            with your LDAP server. Legal values are "none" for unencrypted LDAP,
                            "ssl" for LDAP over SSL/TLS (commonly known as LDAPS), or "starttls" for
                            STARTTLS. If omitted, encryption will not be used.</para>
                        <para>If you do use encryption when connecting to your LDAP server, you will
                            need to ensure that its certificate chain can be verified using the
                            certificates in Java's trust store, often referred to as
                                <filename>cacerts</filename>. If this is not the case, you will need
                            to use Java's <command>keytool</command> utility to either add the
                            necessary certificates or to create a new trust store containing those
                            certificates.</para>
                        <para>If you will be using your own trust store and not the default
                                <filename>cacerts</filename>, you will need to specify the full path
                            to that trust store using the system property
                                <property>javax.net.ssl.trustStore</property>. Note that this is a
                            system property and <emphasis>not</emphasis> a Guacamole property; it
                            must be specified when starting the JVM using the <option>-D</option>
                            option. Your servlet container will provide some means of specifying
                            startup options for the JVM.</para>
                    </listitem>
                </varlistentry>
                <varlistentry>
                    <term><property>ldap-max-search-results</property></term>
                    <listitem>
                        <para>The maximum number of search results that can be returned by a single
                            LDAP query. LDAP queries which exceed this maximum will fail.
                                <emphasis>This property is optional.</emphasis> If omitted, each
                            LDAP query will be limited to a maximum of 1000 results.</para>
                    </listitem>
                </varlistentry>
                <varlistentry>
                    <term><property>ldap-search-bind-dn</property></term>
                    <listitem>
                        <para>The DN (Distinguished Name) of the user to bind as when authenticating
                            users that are attempting to log in. If specified, Guacamole will query
                            the LDAP directory to determine the DN of each user that logs in. If
                            omitted, each user's DN will be derived directly using the base DN
                            specified with <property>ldap-user-base-dn</property>.</para>
                    </listitem>
                </varlistentry>
                <varlistentry>
                    <term><property>ldap-search-bind-password</property></term>
                    <listitem>
                        <para>The password to provide to the LDAP server when binding as
                                <property>ldap-search-bind-dn</property> to authenticate other
                            users. This property is only used if
                                <property>ldap-search-bind-dn</property> is specified. If omitted,
                            but <property>ldap-search-bind-dn</property> is specified, Guacamole
                            will attempt to bind with the LDAP server without a password.</para>
                    </listitem>
                </varlistentry>
                <varlistentry>
                    <term><property>ldap-user-base-dn</property></term>
                    <listitem>
                        <para>The base of the DN for all Guacamole users. <emphasis>This property is
                                absolutely required in all cases.</emphasis> All Guacamole users
                            must be descendents of this base DN.</para>
                        <para>If a search DN is provided (via
                                <property>ldap-search-bind-dn</property>), then Guacamole users need
                            only be somewhere within the subtree of the specified user base
                            DN.</para>
                        <para>If a search DN <emphasis>is not</emphasis> provided, then all
                            Guacamole users must be <emphasis>direct descendents</emphasis> of this
                            base DN, as the base DN will be appended to the username to derive the
                            user's DN. For example, if <property>ldap-user-base-dn</property> is
                                "<systemitem>ou=people,dc=example,dc=net</systemitem>", and
                                <property>ldap-username-attribute</property> is
                                "<property>uid</property>", then a person attempting to login as
                                "<systemitem>user</systemitem>" would be mapped to the following
                            full DN:
                            "<systemitem>uid=user,ou=people,dc=example,dc=net</systemitem>".</para>
                    </listitem>
                </varlistentry>
                <varlistentry>
                    <term><property>ldap-username-attribute</property></term>
                    <listitem>
                        <para>The attribute or attributes which contain the username within all
                            Guacamole user objects in the LDAP directory. Usually, and by default,
                            this will simply be "<property>uid</property>".  If your LDAP directory
                            contains users whose usernames are dictated by different attributes,
                            multiple attributes can be specified here, separated by commas, but
                            beware: <emphasis>doing so requires that a search DN be provided with
                                    <property>ldap-search-bind-dn</property></emphasis>.</para>
                        <para>If a search DN <emphasis>is not</emphasis> provided, then the single
                            username attribute specified here will be used together with the user
                            base DN to directly derive the full DN of each user. For example, if
                                <property>ldap-user-base-dn</property> is
                                "<systemitem>ou=people,dc=example,dc=net</systemitem>", and
                                <property>ldap-username-attribute</property> is
                                "<property>uid</property>", then a person attempting to login as
                                "<systemitem>user</systemitem>" would be mapped to the following
                            full DN:
                            "<systemitem>uid=user,ou=people,dc=example,dc=net</systemitem>".</para>
                    </listitem>
                </varlistentry>
                <varlistentry>
                    <term><property>ldap-config-base-dn</property></term>
                    <listitem>
                        <para>The base of the DN for all Guacamole configurations. <emphasis>This
                                property is optional.</emphasis> If omitted, the configurations of
                            Guacamole connections will simply not be queried from the LDAP
                            directory. If specified, this base DN will be used when querying the
                            configurations accessible by a user once they have successfully logged
                            in.</para>
                        <para>Each configuration is analogous to a connection. Within Guacamole's
                            LDAP support, each configuration functions as a group, having user
                            members (via the <property>member</property> attribute) and optionally
                            group members (via the <property>seeAlso</property> attribute), where
                            each member of a particular configuration group will have access to the
                            connection defined by that configuration.</para>
                    </listitem>
                </varlistentry>
                <varlistentry>
                    <term><property>ldap-group-base-dn</property></term>
                    <listitem>
                        <para>The base of the DN for all groups that may be referenced within
                            Guacamole configurations using the standard <property>seeAlso</property>
                            attribute. All groups which will be used to control access to Guacamole
                            configurations must be descendents of this base DN. <emphasis>If this
                                property is omitted, the <property>seeAlso</property> attribute will
                                have no effect on Guacamole configurations.</emphasis></para>
                    </listitem>
                </varlistentry>
            </variablelist>
            <para>Again, even if the defaults are sufficient for the other properties, <emphasis>you
                    must still specify the <property>ldap-user-base-dn</property>
                    property</emphasis>. An absolutely minimal configuration for LDAP authentication
                will look like the following:</para>
            <programlisting># LDAP properties
ldap-user-base-dn:       <replaceable>ou=people,dc=example,dc=net</replaceable></programlisting>
        </section>
        <section>
            <title>Completing the installation</title>
            <para>Guacamole will only reread <filename>guacamole.properties</filename> and load
                newly-installed extensions during startup, so your servlet container will need to be
                restarted before the LDAP authentication will take effect. Restart your servlet
                container and give the new authentication a try.</para>
            <para>
                <important>
                    <para>You only need to restart your servlet container. <emphasis>You do not need
                            to restart <package>guacd</package></emphasis>.</para>
                    <para><package>guacd</package> is completely independent of the web application
                        and does not deal with <filename>guacamole.properties</filename> or the
                        authentication system in any way. Since you are already restarting the
                        servlet container, restarting <package>guacd</package> as well technically
                        won't hurt anything, but doing so is completely pointless.</para>
                </important>
            </para>
            <para>If Guacamole does not come back online after restarting your servlet container,
                check the logs. Problems in the configuration of the LDAP extension will prevent
                Guacamole from starting up, and any such errors will be recorded in the logs of your
                servlet container. If properly configured, you will be able to log in as any user
                within the defined <property>ldap-user-base-dn</property>.</para>
        </section>
    </section>
    <section xml:id="ldap-auth-schema">
        <title>The LDAP schema</title>
        <indexterm>
            <primary>schema</primary>
        </indexterm>
        <para>Guacamole's LDAP support allows users and connections to be managed purely within an
            LDAP directory defined in <filename>guacamole.properties</filename>. This is
            accomplished with a minimum of changes to the standard LDAP schema - all Guacamole users
            are traditional LDAP users and share the same mechanism of authentication. The only new
            type of object required is a representation for Guacamole connections,
                <classname>guacConfigGroup</classname>, which was added to your server's schema
            during the install process above.</para>
        <section>
            <title>Users</title>
            <para>All Guacamole users, as far as the LDAP support is concerned, are LDAP users with
                standard LDAP credentials. When a user signs in to Guacamole, their username and
                password will be used to bind to the LDAP server. If this bind operation is
                successful, the available connections are queried from the directory and the user is
                allowed in.</para>
        </section>
        <section>
            <title>Connections and parameters</title>
            <para>Each connection is represented by an instance of the
                    <classname>guacConfigGroup</classname> object class, an extended version of the
                standard LDAP <classname>groupOfNames</classname>, which provides a protocol and set
                of parameters. Only members of the <classname>guacConfigGroup</classname> will have
                access to the corresponding connection.</para>
            <para>The <classname>guacConfigGroup</classname> object class provides two new
                attributes in addition to those provided by
                <classname>groupOfNames</classname>:</para>
            <variablelist>
                <varlistentry>
                    <term><property>guacConfigProtocol</property></term>
                    <listitem>
                        <para>The protocol associated with the connection, such as
                                "<constant>vnc</constant>" or "<constant>rdp</constant>". This
                            attribute is required for every <classname>guacConfigGroup</classname>
                            and can be given only once.</para>
                    </listitem>
                </varlistentry>
                <varlistentry>
                    <term><property>guacConfigParameter</property></term>
                    <listitem>
                        <para>The name and value of a parameter for the specified protocol. This is
                            given as
                                    <code><replaceable>name</replaceable>=<replaceable>value</replaceable></code>,
                            where "name" is the name of the parameter, as defined by the
                            documentation for the protocol specified, and "value" is any allowed
                            value for that parameter.</para>
                        <para>This attribute can be given multiple times for the same
                            connection.</para>
                    </listitem>
                </varlistentry>
            </variablelist>
            <para>For example, to create a new VNC connection which connects to "localhost" at port
                5900, while granting access to <systemitem>user1</systemitem> and
                    <systemitem>user2</systemitem>, you could create an <filename>.ldif</filename>
                file like the following:</para>
            <informalexample>
                <programlisting>dn: cn=Example Connection,ou=groups,dc=example,dc=net
objectClass: guacConfigGroup
objectClass: groupOfNames
cn: Example Connection
guacConfigProtocol: vnc
guacConfigParameter: hostname=localhost
guacConfigParameter: port=5900
guacConfigParameter: password=<PASSWORD>
member: cn=user1,ou=people,dc=example,dc=net
member: cn=user2,ou=people,dc=example,dc=net</programlisting>
            </informalexample>
            <para>The new connection can then be created using the <command>ldapadd</command>
                utility:</para>
            <informalexample>
                <screen><prompt>$</prompt> <userinput>ldapadd -x -D <replaceable>cn=admin,dc=example,dc=net</replaceable> -W -f <replaceable>example-connection.ldif</replaceable></userinput>
<computeroutput>Enter LDAP Password: 
adding new entry "cn=Example Connection,ou=groups,dc=example,dc=net"
</computeroutput>
<prompt>$</prompt></screen>
            </informalexample>
            <para>Where <systemitem>cn=admin,dc=example,dc=net</systemitem> is an administrator
                account with permission to create new entries, and
                    <filename>example-connection.ldif</filename> is the name of the
                    <filename>.ldif</filename> file you just created.</para>
            <para>There is, of course, no need to use only the standard LDAP utilities to create
                connections and users. There are useful graphical environments for manipulating LDAP
                directories, such as <link xlink:href="https://directory.apache.org/studio/">Apache
                    Directory Studio</link>, which make many of the tasks given above much
                easier.</para>
        </section>
    </section>
</chapter>
<commit_msg>GUACAMOLE-244: Add documentation for new ldap-dereference-alises parameter.<commit_after><?xml version="1.0" encoding="UTF-8"?>

<chapter xml:id="ldap-auth" xmlns="http://docbook.org/ns/docbook" version="5.0" xml:lang="en"
    xmlns:xi="http://www.w3.org/2001/XInclude"
    xmlns:xlink="http://www.w3.org/1999/xlink">
    <title>LDAP authentication</title>
    <indexterm>
        <primary>LDAP</primary>
    </indexterm>
    <para>Guacamole supports LDAP authentication via an extension available from the main project
        website. This extension allows users and connections to be stored directly within an LDAP
        directory. If you have a centralized authentication system that uses LDAP, Guacamole's LDAP
        support can be a good way to allow your users to use their existing usernames and passwords
        to log into Guacamole.</para>
    <para>To use the LDAP authentication extension, you will need:</para>
    <orderedlist>
        <listitem>
            <para>An LDAP directory as storage for all authentication data, such as OpenLDAP.</para>
        </listitem>
        <listitem>
            <para>The ability to modify the schema of your LDAP directory.</para>
        </listitem>
    </orderedlist>
    <para>The instructions here assume you already have an LDAP directory installed and working, and
        do not cover the initial setup of such a directory.</para>
    <important>
        <para>This chapter involves modifying the contents of <varname>GUACAMOLE_HOME</varname> -
            the Guacamole configuration directory. If you are unsure where
                <varname>GUACAMOLE_HOME</varname> is located on your system, please consult <xref
                linkend="configuring-guacamole"/> before proceeding.</para>
    </important>
    <section xml:id="ldap-architecture">
        <title>How Guacamole uses LDAP</title>
        <para>If the LDAP extension is installed, Guacamole will authenticate users against your
            LDAP server by attempting a bind as that user. The given username and password will be
            submitted to the LDAP server during the bind attempt.</para>
        <para>If the bind attempt is successful, the set of available Guacamole connections is
            queried from the LDAP directory by executing an LDAP query as the bound user. Each
            Guacamole connection is represented within the directory as a special type of group:
                <classname>guacConfigGroup</classname>. Attributes associated with the group define
            the protocol and parameters of the connection, and users are allowed access to the
            connection only if they are associated with that group.</para>
        <para>This architecture has a number of benefits:</para>
        <orderedlist>
            <listitem>
                <para>Your users can use their existing usernames and passwords to log into
                    Guacamole.</para>
            </listitem>
            <listitem>
                <para>You can manage Guacamole connections using the same tool that you already use
                    to manage your LDAP directory, such as <link
                        xlink:href="https://directory.apache.org/studio/">Apache Directory
                        Studio</link>.</para>
            </listitem>
            <listitem>
                <para>Existing security restrictions can limit visibility/accessibility of Guacamole
                    connections.</para>
            </listitem>
            <listitem>
                <para>Access to connections can easily be granted and revoked, as each connection is
                    represented by a group.</para>
            </listitem>
        </orderedlist>
        <important>
            <para>Though Guacamole connections can be stored within the LDAP directory, this is not
                required. Connection data can alternatively be stored within a database like MySQL
                or PostgreSQL as long as the LDAP username matches the username of the database
                user. Configuring Guacamole to use a database for authentication or connection
                storage is covered in <xref linkend="jdbc-auth"/> and later in this chapter in <xref
                    linkend="ldap-and-database"/>.</para>
        </important>
    </section>
    <section xml:id="ldap-downloading">
        <title>Downloading the LDAP extension</title>
        <para>The LDAP authentication extension is available separately from the main
                <filename>guacamole.war</filename>. The link for this and all other
            officially-supported and compatible extensions for a particular version of Guacamole are
            provided on the release notes for that version. You can find the release notes for
            current versions of Guacamole here: <link
                xlink:href="http://guacamole.incubator.apache.org/releases/"
                >http://guacamole.incubator.apache.org/releases/</link>.</para>
        <para>The LDAP authentication extension is packaged as a <filename>.tar.gz</filename> file
            containing:</para>
        <variablelist>
            <varlistentry>
                <term><filename>guacamole-auth-ldap-0.9.12-incubating.jar</filename></term>
                <listitem>
                    <para>The Guacamole LDAP support extension itself, which must be placed in
                            <filename>GUACAMOLE_HOME/extensions</filename>.</para>
                </listitem>
            </varlistentry>
            <varlistentry>
                <term><filename>schema/</filename></term>
                <listitem>
                    <para>LDAP schema files. An <filename>.ldif</filename> file compatible with
                        OpenLDAP is provided, as well as a <filename>.schema</filename> file
                        compliant with RFC-2252. The <filename>.schema</filename> file can be
                        transformed into the <filename>.ldif</filename> file automatically.</para>
                </listitem>
            </varlistentry>
        </variablelist>
    </section>
    <section xml:id="ldap-schema-changes">
        <title>Preparing your LDAP directory (optional)</title>
        <para>Although your LDAP directory already provides a means of storing and authenticating
            users, Guacamole also needs storage of connection configuration data, such as hostnames
            and ports, and a means of associating users with connections that they should have
            access to. You can do this either through modifying the LDAP directory schema, or
            through using a database like MySQL or PostgreSQL. If you do not wish to use the LDAP
            directory for connection storage, skip ahead to <xref linkend="ldap-and-database"
            />.</para>
        <para>If you wish to store connection data directly within the LDAP directory, the required
            modifications to the LDAP schema are made through applying one of the provided schema
            files. These schema files define an additional object class,
                <classname>guacConfigGroup</classname>, which contains all configuration information
            for a particular connection, and can be associated with arbitrarily-many users and
            groups. Each connection defined by a <classname>guacConfigGroup</classname> will be
            accessible only by users who are members of that group (specified with the
                <property>member</property> attribute), or who are members of associated groups
            (specified with the <property>seeAlso</property> attribute).</para>
        <important>
            <para>The instructions given for applying the Guacamole LDAP schema changes are specific
                to OpenLDAP, but other LDAP implementations, including Active Directory, will have
                their own methods for updating the schema.</para>
            <para>If you are not using OpenLDAP, a standards-compliant schema file is provided that
                can be used to update the schema of any LDAP directory supporting RFC-2252. Please
                consult the documentation of your LDAP directory to determine how such schema
                changes can be applied.</para>
        </important>
        <para>The schema files are located within the <filename>schema/</filename> directory of the
            archive containing the LDAP extension. You will only need one of these files:</para>
        <variablelist>
            <varlistentry>
                <term><filename>guacConfigGroup.schema</filename></term>
                <listitem>
                    <para>A standards-compliant file describing the schema. This file can be used
                        with any LDAP directory compliant with RFC-2252.</para>
                </listitem>
            </varlistentry>
            <varlistentry>
                <term><filename>guacConfigGroup.ldif</filename></term>
                <listitem>
                    <para>An LDIF file compatible with OpenLDAP. This file was automatically built
                        from the provided <filename>.schema</filename> file for convenience.</para>
                </listitem>
            </varlistentry>
        </variablelist>
        <para>This chapter will cover applying <filename>guacConfigGroup.ldif</filename> to an
            OpenLDAP server. If you are not using OpenLDAP, your LDAP server should provide
            documentation for modifying its schema. If this is the case, please consult the
            documentation of your LDAP server before proceeding.</para>
        <section>
            <title>Applying the schema changes to OpenLDAP</title>
            <para>Schema changes to OpenLDAP are applied using the <command>ldapadd</command>
                utility with the provided <filename>guacConfigGroup.ldif</filename> file:</para>
            <informalexample>
                <screen><prompt>#</prompt> <userinput>ldapadd -Q -Y EXTERNAL -H ldapi:/// -f schema/guacConfigGroup.ldif</userinput>
<computeroutput>adding new entry "cn=guacConfigGroup,cn=schema,cn=config"
</computeroutput>
<prompt>#</prompt></screen>
            </informalexample>
            <para>If the <classname>guacConfigGroup</classname> object was added successfully, you
                should see output as above. You can confirm the presence of the new object class
                using <command>ldapsearch</command>:</para>
            <informalexample>
                <screen><prompt>#</prompt> <userinput>ldapsearch -Q -LLL -Y EXTERNAL -H ldapi:/// -b cn=schema,cn=config dn</userinput>
<computeroutput>dn: cn=schema,cn=config

dn: cn={0}core,cn=schema,cn=config

dn: cn={1}cosine,cn=schema,cn=config

dn: cn={2}nis,cn=schema,cn=config

dn: cn={3}inetorgperson,cn=schema,cn=config

dn: cn={4}guacConfigGroup,cn=schema,cn=config
</computeroutput>
<prompt>#</prompt></screen>
            </informalexample>
        </section>
    </section>
    <section xml:id="ldap-and-database">
        <title>Associating LDAP with a database</title>
        <para>If you install both the LDAP authentication as well as support for MySQL or PostgreSQL
            (following the instructions in <xref linkend="jdbc-auth"/>), Guacamole will
            automatically attempt to authenticate against both systems whenever a user attempts to
            log in. That user will have access to any data associated with them via the database, as
            well as any visible objects within the LDAP directory. The LDAP account will be
            considered equivalent to the database user if the username is identical.</para>
        <para>Data can be manually associated with LDAP users by creating corresponding user
            accounts within the database which each have the same usernames as valid LDAP users. As
            long as the username is identical, a successful login attempt against LDAP will be
            trusted by the database authentication, and that user's associated data will be
            visible.</para>
        <para>If an administrator account (such as the default <systemitem>guacadmin</systemitem>
            user provided with the database authentication) has a corresponding user in the LDAP
            directory with permission to list and read other LDAP users, the Guacamole
            administrative interface will include LDAP users in the overall user list presented to
            the administrator, and allow connections from the database to be associated with those
            users directly.</para>
    </section>
    <section xml:id="installing-ldap-auth">
        <title>Installing LDAP authentication</title>
        <para>Guacamole extensions are self-contained <filename>.jar</filename> files which are
            located within the <filename>GUACAMOLE_HOME/extensions</filename> directory. To install
            the LDAP authentication extension, you must:</para>
        <procedure>
            <step>
                <para>Create the <filename>GUACAMOLE_HOME/extensions</filename> directory, if it
                    does not already exist.</para>
            </step>
            <step>
                <para>Copy <filename>guacamole-auth-ldap-0.9.12-incubating.jar</filename> within
                        <filename>GUACAMOLE_HOME/extensions</filename>.</para>
            </step>
            <step>
                <para>Configure Guacamole to use LDAP authentication, as described below.</para>
            </step>
        </procedure>
        <important>
            <para>You will need to restart Guacamole by restarting your servlet container in order
                to complete the installation. Doing this will disconnect all active users, so be
                sure that it is safe to do so prior to attempting installation. If you do not
                configure the LDAP authentication properly, Guacamole will not start up again until
                the configuration is fixed.</para>
        </important>
        <section>
            <title>Configuring Guacamole for LDAP</title>
            <indexterm>
                <primary>configuring LDAP</primary>
            </indexterm>
            <indexterm>
                <primary>LDAP</primary>
                <secondary>configuration</secondary>
            </indexterm>
            <para>Additional properties may be added to <filename>guacamole.properties</filename> to
                describe how your LDAP directory is organized and how Guacamole should connect (and
                bind) to your LDAP server. Among these properties, only the
                    <property>ldap-user-base-dn</property> property is required:</para>
            <variablelist>
                <varlistentry>
                    <term><property>ldap-hostname</property></term>
                    <listitem>
                        <para>The hostname of your LDAP server. If omitted, "localhost" will be used
                            by default. You will need to use a different value if your LDAP server
                            is located elsewhere.</para>
                    </listitem>
                </varlistentry>
                <varlistentry>
                    <term><property>ldap-port</property></term>
                    <listitem>
                        <para>The port your LDAP server listens on. If omitted, the standard LDAP or
                            LDAPS port will be used, depending on the encryption method specified
                            with <property>ldap-encryption-method</property> (if any). Unencrypted
                            LDAP uses the standard port of 389, while LDAPS uses port 636. Unless
                            you manually configured your LDAP server to do otherwise, your LDAP
                            server probably listens on port 389.</para>
                    </listitem>
                </varlistentry>
                <varlistentry>
                    <term><property>ldap-encryption-method</property></term>
                    <listitem>
                        <para>The encryption mechanism that Guacamole should use when communicating
                            with your LDAP server. Legal values are "none" for unencrypted LDAP,
                            "ssl" for LDAP over SSL/TLS (commonly known as LDAPS), or "starttls" for
                            STARTTLS. If omitted, encryption will not be used.</para>
                        <para>If you do use encryption when connecting to your LDAP server, you will
                            need to ensure that its certificate chain can be verified using the
                            certificates in Java's trust store, often referred to as
                                <filename>cacerts</filename>. If this is not the case, you will need
                            to use Java's <command>keytool</command> utility to either add the
                            necessary certificates or to create a new trust store containing those
                            certificates.</para>
                        <para>If you will be using your own trust store and not the default
                                <filename>cacerts</filename>, you will need to specify the full path
                            to that trust store using the system property
                                <property>javax.net.ssl.trustStore</property>. Note that this is a
                            system property and <emphasis>not</emphasis> a Guacamole property; it
                            must be specified when starting the JVM using the <option>-D</option>
                            option. Your servlet container will provide some means of specifying
                            startup options for the JVM.</para>
                    </listitem>
                </varlistentry>
                <varlistentry>
                    <term><property>ldap-max-search-results</property></term>
                    <listitem>
                        <para>The maximum number of search results that can be returned by a single
                            LDAP query. LDAP queries which exceed this maximum will fail.
                                <emphasis>This property is optional.</emphasis> If omitted, each
                            LDAP query will be limited to a maximum of 1000 results.</para>
                    </listitem>
                </varlistentry>
                <varlistentry>
                    <term><property>ldap-search-bind-dn</property></term>
                    <listitem>
                        <para>The DN (Distinguished Name) of the user to bind as when authenticating
                            users that are attempting to log in. If specified, Guacamole will query
                            the LDAP directory to determine the DN of each user that logs in. If
                            omitted, each user's DN will be derived directly using the base DN
                            specified with <property>ldap-user-base-dn</property>.</para>
                    </listitem>
                </varlistentry>
                <varlistentry>
                    <term><property>ldap-search-bind-password</property></term>
                    <listitem>
                        <para>The password to provide to the LDAP server when binding as
                                <property>ldap-search-bind-dn</property> to authenticate other
                            users. This property is only used if
                                <property>ldap-search-bind-dn</property> is specified. If omitted,
                            but <property>ldap-search-bind-dn</property> is specified, Guacamole
                            will attempt to bind with the LDAP server without a password.</para>
                    </listitem>
                </varlistentry>
                <varlistentry>
                    <term><property>ldap-user-base-dn</property></term>
                    <listitem>
                        <para>The base of the DN for all Guacamole users. <emphasis>This property is
                                absolutely required in all cases.</emphasis> All Guacamole users
                            must be descendents of this base DN.</para>
                        <para>If a search DN is provided (via
                                <property>ldap-search-bind-dn</property>), then Guacamole users need
                            only be somewhere within the subtree of the specified user base
                            DN.</para>
                        <para>If a search DN <emphasis>is not</emphasis> provided, then all
                            Guacamole users must be <emphasis>direct descendents</emphasis> of this
                            base DN, as the base DN will be appended to the username to derive the
                            user's DN. For example, if <property>ldap-user-base-dn</property> is
                                "<systemitem>ou=people,dc=example,dc=net</systemitem>", and
                                <property>ldap-username-attribute</property> is
                                "<property>uid</property>", then a person attempting to login as
                                "<systemitem>user</systemitem>" would be mapped to the following
                            full DN:
                            "<systemitem>uid=user,ou=people,dc=example,dc=net</systemitem>".</para>
                    </listitem>
                </varlistentry>
                <varlistentry>
                    <term><property>ldap-username-attribute</property></term>
                    <listitem>
                        <para>The attribute or attributes which contain the username within all
                            Guacamole user objects in the LDAP directory. Usually, and by default,
                            this will simply be "<property>uid</property>".  If your LDAP directory
                            contains users whose usernames are dictated by different attributes,
                            multiple attributes can be specified here, separated by commas, but
                            beware: <emphasis>doing so requires that a search DN be provided with
                                    <property>ldap-search-bind-dn</property></emphasis>.</para>
                        <para>If a search DN <emphasis>is not</emphasis> provided, then the single
                            username attribute specified here will be used together with the user
                            base DN to directly derive the full DN of each user. For example, if
                                <property>ldap-user-base-dn</property> is
                                "<systemitem>ou=people,dc=example,dc=net</systemitem>", and
                                <property>ldap-username-attribute</property> is
                                "<property>uid</property>", then a person attempting to login as
                                "<systemitem>user</systemitem>" would be mapped to the following
                            full DN:
                            "<systemitem>uid=user,ou=people,dc=example,dc=net</systemitem>".</para>
                    </listitem>
                </varlistentry>
                <varlistentry>
                    <term><property>ldap-config-base-dn</property></term>
                    <listitem>
                        <para>The base of the DN for all Guacamole configurations. <emphasis>This
                                property is optional.</emphasis> If omitted, the configurations of
                            Guacamole connections will simply not be queried from the LDAP
                            directory. If specified, this base DN will be used when querying the
                            configurations accessible by a user once they have successfully logged
                            in.</para>
                        <para>Each configuration is analogous to a connection. Within Guacamole's
                            LDAP support, each configuration functions as a group, having user
                            members (via the <property>member</property> attribute) and optionally
                            group members (via the <property>seeAlso</property> attribute), where
                            each member of a particular configuration group will have access to the
                            connection defined by that configuration.</para>
                    </listitem>
                </varlistentry>
                <varlistentry>
                    <term><property>ldap-group-base-dn</property></term>
                    <listitem>
                        <para>The base of the DN for all groups that may be referenced within
                            Guacamole configurations using the standard <property>seeAlso</property>
                            attribute. All groups which will be used to control access to Guacamole
                            configurations must be descendents of this base DN. <emphasis>If this
                                property is omitted, the <property>seeAlso</property> attribute will
                                have no effect on Guacamole configurations.</emphasis></para>
                    </listitem>
                </varlistentry>
                <varlistentry>
                    <term><property>ldap-dereference-aliases</property></term>
                    <listitem>
                        <para>Controls whether or not the LDAP connection follows (dereferences) aliases
                            as it searches the tree.  There are four possible values: never (the default),
                            finding, searching, and always.  Never means aliases will never be followed;
                            searching means they will be dereferenced during search, but not when finding
                            the start of the search; finding means only when finding the start of the search,
                            but not during the search; always means they will always be followed.</para>
                    </listitem>
                </varlistentry>
            </variablelist>
            <para>Again, even if the defaults are sufficient for the other properties, <emphasis>you
                    must still specify the <property>ldap-user-base-dn</property>
                    property</emphasis>. An absolutely minimal configuration for LDAP authentication
                will look like the following:</para>
            <programlisting># LDAP properties
ldap-user-base-dn:       <replaceable>ou=people,dc=example,dc=net</replaceable></programlisting>
        </section>
        <section>
            <title>Completing the installation</title>
            <para>Guacamole will only reread <filename>guacamole.properties</filename> and load
                newly-installed extensions during startup, so your servlet container will need to be
                restarted before the LDAP authentication will take effect. Restart your servlet
                container and give the new authentication a try.</para>
            <para>
                <important>
                    <para>You only need to restart your servlet container. <emphasis>You do not need
                            to restart <package>guacd</package></emphasis>.</para>
                    <para><package>guacd</package> is completely independent of the web application
                        and does not deal with <filename>guacamole.properties</filename> or the
                        authentication system in any way. Since you are already restarting the
                        servlet container, restarting <package>guacd</package> as well technically
                        won't hurt anything, but doing so is completely pointless.</para>
                </important>
            </para>
            <para>If Guacamole does not come back online after restarting your servlet container,
                check the logs. Problems in the configuration of the LDAP extension will prevent
                Guacamole from starting up, and any such errors will be recorded in the logs of your
                servlet container. If properly configured, you will be able to log in as any user
                within the defined <property>ldap-user-base-dn</property>.</para>
        </section>
    </section>
    <section xml:id="ldap-auth-schema">
        <title>The LDAP schema</title>
        <indexterm>
            <primary>schema</primary>
        </indexterm>
        <para>Guacamole's LDAP support allows users and connections to be managed purely within an
            LDAP directory defined in <filename>guacamole.properties</filename>. This is
            accomplished with a minimum of changes to the standard LDAP schema - all Guacamole users
            are traditional LDAP users and share the same mechanism of authentication. The only new
            type of object required is a representation for Guacamole connections,
                <classname>guacConfigGroup</classname>, which was added to your server's schema
            during the install process above.</para>
        <section>
            <title>Users</title>
            <para>All Guacamole users, as far as the LDAP support is concerned, are LDAP users with
                standard LDAP credentials. When a user signs in to Guacamole, their username and
                password will be used to bind to the LDAP server. If this bind operation is
                successful, the available connections are queried from the directory and the user is
                allowed in.</para>
        </section>
        <section>
            <title>Connections and parameters</title>
            <para>Each connection is represented by an instance of the
                    <classname>guacConfigGroup</classname> object class, an extended version of the
                standard LDAP <classname>groupOfNames</classname>, which provides a protocol and set
                of parameters. Only members of the <classname>guacConfigGroup</classname> will have
                access to the corresponding connection.</para>
            <para>The <classname>guacConfigGroup</classname> object class provides two new
                attributes in addition to those provided by
                <classname>groupOfNames</classname>:</para>
            <variablelist>
                <varlistentry>
                    <term><property>guacConfigProtocol</property></term>
                    <listitem>
                        <para>The protocol associated with the connection, such as
                                "<constant>vnc</constant>" or "<constant>rdp</constant>". This
                            attribute is required for every <classname>guacConfigGroup</classname>
                            and can be given only once.</para>
                    </listitem>
                </varlistentry>
                <varlistentry>
                    <term><property>guacConfigParameter</property></term>
                    <listitem>
                        <para>The name and value of a parameter for the specified protocol. This is
                            given as
                                    <code><replaceable>name</replaceable>=<replaceable>value</replaceable></code>,
                            where "name" is the name of the parameter, as defined by the
                            documentation for the protocol specified, and "value" is any allowed
                            value for that parameter.</para>
                        <para>This attribute can be given multiple times for the same
                            connection.</para>
                    </listitem>
                </varlistentry>
            </variablelist>
            <para>For example, to create a new VNC connection which connects to "localhost" at port
                5900, while granting access to <systemitem>user1</systemitem> and
                    <systemitem>user2</systemitem>, you could create an <filename>.ldif</filename>
                file like the following:</para>
            <informalexample>
                <programlisting>dn: cn=Example Connection,ou=groups,dc=example,dc=net
objectClass: guacConfigGroup
objectClass: groupOfNames
cn: Example Connection
guacConfigProtocol: vnc
guacConfigParameter: hostname=localhost
guacConfigParameter: port=5900
guacConfigParameter: password=<PASSWORD>
member: cn=user1,ou=people,dc=example,dc=net
member: cn=user2,ou=people,dc=example,dc=net</programlisting>
            </informalexample>
            <para>The new connection can then be created using the <command>ldapadd</command>
                utility:</para>
            <informalexample>
                <screen><prompt>$</prompt> <userinput>ldapadd -x -D <replaceable>cn=admin,dc=example,dc=net</replaceable> -W -f <replaceable>example-connection.ldif</replaceable></userinput>
<computeroutput>Enter LDAP Password: 
adding new entry "cn=Example Connection,ou=groups,dc=example,dc=net"
</computeroutput>
<prompt>$</prompt></screen>
            </informalexample>
            <para>Where <systemitem>cn=admin,dc=example,dc=net</systemitem> is an administrator
                account with permission to create new entries, and
                    <filename>example-connection.ldif</filename> is the name of the
                    <filename>.ldif</filename> file you just created.</para>
            <para>There is, of course, no need to use only the standard LDAP utilities to create
                connections and users. There are useful graphical environments for manipulating LDAP
                directories, such as <link xlink:href="https://directory.apache.org/studio/">Apache
                    Directory Studio</link>, which make many of the tasks given above much
                easier.</para>
        </section>
    </section>
</chapter>

{'fraction_non_alphanumeric': 0.07079487676502602, 'fraction_numerical': 0.0019830915353303414, 'mean_word_length': 1.8504398826979471, 'pattern_counts': {'":': 0, '<': 1271, '<?xml version=': 2, '>': 1271, 'https://': 4, 'lorem ipsum': 0, 'www.': 4, 'xml': 24}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 15, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '743919', 'n_tokens_mistral': 15779, 'n_tokens_neox': 14992, 'n_words': 5806}