blob: 930ceb1eb9883abb30b0d2f7582dde17ec564d3d [file] [log] [blame]
<?xml version="1.0" encoding="UTF-8"?>
<chapter xml:id="jdbc-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>Database authentication</title>
<indexterm>
<primary>MySQL</primary>
</indexterm>
<indexterm>
<primary>PostgreSQL</primary>
</indexterm>
<indexterm>
<primary>load balancing</primary>
</indexterm>
<para>Guacamole supports authentication via MySQL or PostgreSQL databases through extensions
available from the project website. Using a database for authentication provides additional
features, such as the ability to use load balancing groups of connections and a web-based
administrative interface. Unlike the default, XML-driven authentication module, all changes
to users and connections take effect immediately; users need not logout and back in to see
new connections.</para>
<para>While most authentication extensions function independently, the database authentication
can act in a subordinate role, allowing users from other authentication extensions to be
associated with connections within the database. Users are considered identical to users
within the database if they have the same usernames, and the authentication result of
another extension will be trusted if it succeeds. A user with an account under multiple
systems will thus be able to see data from each system after successfully logging in. For
more information on using the database authentication alongside other mechanisms, see <xref
linkend="ldap-and-database"/> within <xref linkend="ldap-auth"/>.</para>
<para>To use the database authentication extension, you will need:</para>
<orderedlist>
<listitem>
<para>A supported database - currently MariaDB, MySQL, or PostgreSQL.</para>
</listitem>
<listitem>
<para>Sufficient permission to create new databases, to create new users, and to grant
those users permissions.</para>
</listitem>
<listitem>
<para>Network access to the database from the Guacamole server.</para>
</listitem>
</orderedlist>
<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>
<title>Downloading the database authentication extension</title>
<para>The database 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 database authentication extension is packaged as a <filename>.tar.gz</filename>
file containing:</para>
<variablelist>
<varlistentry>
<term><filename>mysql/</filename></term>
<listitem>
<para>Contains the MySQL/MariaDB authentication extension,
<filename>guacamole-auth-jdbc-mysql-0.9.13-incubating.jar</filename>,
along with a <filename>schema/</filename> directory containing
MySQL-specific SQL scripts required to set up the database. The
<filename>guacamole-auth-jdbc-mysql-0.9.13-incubating.jar</filename>
file will ultimately need to be placed within
<filename>GUACAMOLE_HOME/extensions</filename>, while the MySQL JDBC
driver must be placed within <filename>GUACAMOLE_HOME/lib</filename>.</para>
<para><emphasis>The MySQL JDBC driver is not included with the
extension.</emphasis> You must obtain the JDBC driver
<filename>.jar</filename> yourself from <link
xlink:href="http://dev.mysql.com/downloads/connector/j/">MySQL's
website</link>. The driver is known as "Connector/J", and the required
<filename>.jar</filename> will be within a <filename>.tar.gz</filename>
archive.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><filename>postgresql/</filename></term>
<listitem>
<para>Contains the PostgreSQL authentication extension,
<filename>guacamole-auth-jdbc-postgresql-0.9.13-incubating.jar</filename>,
along with a <filename>schema/</filename> directory containing
PostgreSQL-specific SQL scripts required to set up the database. The
<filename>guacamole-auth-jdbc-postgresql-0.9.13-incubating.jar</filename>
file will ultimately need to be placed within
<filename>GUACAMOLE_HOME/extensions</filename>, while the PostgreSQL
JDBC driver must be placed within
<filename>GUACAMOLE_HOME/lib</filename>.</para>
<para><emphasis>The PostgreSQL JDBC driver is not included with the
extension.</emphasis> You must obtain the JDBC driver
<filename>.jar</filename> yourself from <link
xlink:href="https://jdbc.postgresql.org/download.html#current"
>PostgreSQL's website</link>. The proper <filename>.jar</filename> file
depends on the version of Java you have installed. </para>
</listitem>
</varlistentry>
</variablelist>
<para>Only one of the directories within the archive will be applicable to you, depending on
whether you are using MariaDB, MySQL, or PostgreSQL.</para>
</section>
<section xml:id="jdbc-auth-database-creation">
<title>Creating the Guacamole database</title>
<para>The database authentication module will need a database to store authentication data
and a user to use only for data access and manipulation. You can use an existing
database and existing user, but for the sake of simplicity and security, these
instructions assume you will be creating a new database and new user that will be used
only by Guacamole and only for this authentication module.</para>
<para>You need MariaDB, MySQL, or PostgreSQL installed, and must have sufficient access to
create and administer databases. If this is not the case, install your database of
choice now. Most distributions will provide a convenient MySQL or PostgreSQL package
which will set up everything for you, including the root database user, if
applicable.</para>
<para>For the sake of clarity, these instructions will refer to the database as
"guacamole_db" and the user as "guacamole_user", but the database and user can be named
whatever you like. Naturally, you should also choose a real password for your user
rather than the string "some_password" used as a placeholder below.</para>
<section xml:id="jdbc-auth-mysql">
<title>MySQL</title>
<para>If using MySQL, you must create your database and user first:</para>
<informalexample>
<screen><prompt>$</prompt> mysql -u root -p
<prompt>Enter password:</prompt> <userinput><replaceable>password</replaceable></userinput>
<computeroutput>Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 233
Server version: 5.5.29-0ubuntu0.12.10.1 (Ubuntu)
Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
</computeroutput>
<prompt>mysql></prompt> <userinput>CREATE DATABASE <replaceable>guacamole_db</replaceable>;</userinput>
<computeroutput>Query OK, 1 row affected (0.00 sec)</computeroutput>
<prompt>mysql></prompt> <userinput>CREATE USER '<replaceable>guacamole_user'</replaceable>@'localhost' IDENTIFIED BY '<replaceable>some_password</replaceable>';</userinput>
<computeroutput>Query OK, 0 rows affected (0.00 sec)</computeroutput>
<prompt>mysql></prompt> <userinput>GRANT SELECT,INSERT,UPDATE,DELETE ON <replaceable>guacamole_db</replaceable>.* TO '<replaceable>guacamole_user'</replaceable>@'localhost';</userinput>
<computeroutput>Query OK, 0 rows affected (0.00 sec)</computeroutput>
<prompt>mysql></prompt> <userinput>FLUSH PRIVILEGES;</userinput>
<computeroutput>Query OK, 0 rows affected (0.02 sec)</computeroutput>
<prompt>mysql></prompt> <userinput>quit</userinput>
<computeroutput>Bye</computeroutput>
<prompt>$</prompt></screen>
</informalexample>
<para>Once the database and user are created, the database schema must be applied by
running the supplied SQL scripts. These SQL scripts are included in the
<filename>mysql/schema/</filename> directory of the archive you downloaded from
the Guacamole website. They are named such that they can be run in order with one
command:</para>
<informalexample>
<screen><prompt>$</prompt> <userinput>ls schema/</userinput>
<computeroutput>001-create-schema.sql 002-create-admin-user.sql upgrade</computeroutput>
<prompt>$</prompt> <userinput>cat schema/*.sql | mysql -u root -p <replaceable>guacamole_db</replaceable></userinput>
<prompt>Enter password:</prompt> <userinput><replaceable>password</replaceable></userinput>
<prompt>$</prompt></screen>
</informalexample>
<para>If the operation is successful, all tables have been created successfully, and the
database is now ready for use.</para>
<important xml:id="jdbc-auth-mysql-upgrade">
<para>If you are upgrading from an older version of Guacamole and were already using
MySQL, you may need to run one or more database schema upgrade scripts located
within the <filename>schema/upgrade/</filename> directory. Each of these scripts
is named <filename>upgrade-pre-<replaceable>VERSION</replaceable>.sql</filename>
where <replaceable>VERSION</replaceable> is the version of Guacamole where those
changes were introduced. They need to be run when you are upgrading from a
version of Guacamole older than <replaceable>VERSION</replaceable>:</para>
<informalexample>
<screen><prompt>$</prompt> <userinput>ls schema/upgrade/</userinput>
<computeroutput>upgrade-pre-0.8.2.sql upgrade-pre-0.9.13.sql upgrade-pre-0.9.8.sql
upgrade-pre-0.9.10.sql upgrade-pre-0.9.6.sql upgrade-pre-0.9.9.sql
upgrade-pre-0.9.11.sql upgrade-pre-0.9.7.sql</computeroutput>
<prompt>$</prompt></screen>
</informalexample>
<para>These scripts are incremental and, when relevant, <emphasis>must be run in
order</emphasis>. For example, if you are upgrading an existing database
from version 0.9.10-incubating, you would need to run the
<filename>upgrade-pre-0.9.11.sql</filename> script (because 0.9.10 is older
than 0.9.11), followed by the <filename>upgrade-pre-0.9.13.sql</filename> script
(because 0.9.10 is also older than 0.9.13):</para>
<informalexample>
<screen><prompt>$</prompt> <userinput>mysql -u root -p <replaceable>guacamole_db</replaceable> &lt; schema/upgrade/upgrade-pre-0.9.11.sql</userinput>
<prompt>Enter password:</prompt> <userinput><replaceable>password</replaceable></userinput>
<prompt>$</prompt>
<prompt>$</prompt> <userinput>mysql -u root -p <replaceable>guacamole_db</replaceable> &lt; schema/upgrade/upgrade-pre-0.9.13.sql</userinput>
<prompt>Enter password:</prompt> <userinput><replaceable>password</replaceable></userinput>
<prompt>$</prompt></screen>
</informalexample>
<para>If there are no
<filename>upgrade-pre-<replaceable>VERSION</replaceable>.sql</filename>
scripts present in the <filename>schema/upgrade/</filename> directory which
apply to your existing Guacamole database, then the schema has not changed
between your version and the version your are installing, and there is no need
to run any database upgrade scripts.</para>
</important>
</section>
<section xml:id="jdbc-auth-postgresql">
<title>PostgreSQL</title>
<para>If using PostgreSQL, the database and schema must be created first:</para>
<informalexample>
<screen><prompt>$</prompt> <userinput>createdb <replaceable>guacamole_db</replaceable></userinput>
<prompt>$</prompt> <userinput>ls schema/</userinput>
<computeroutput>001-create-schema.sql 002-create-admin-user.sql</computeroutput>
<prompt>$</prompt> <userinput>cat schema/*.sql | psql -d <replaceable>guacamole_db</replaceable> -f -</userinput>
<computeroutput>CREATE TYPE
CREATE TYPE
CREATE TYPE
CREATE TABLE
CREATE INDEX</computeroutput>
...
<computeroutput>INSERT 0 1
INSERT 0 4
INSERT 0 3</computeroutput>
<prompt>$</prompt></screen>
</informalexample>
<para>Once the database exists, you can safely create a new user for the database, and
grant that user sufficient privileges to manage the contents of all tables in the
database:</para>
<informalexample>
<screen><prompt>$</prompt> <userinput>psql -d <replaceable>guacamole_db</replaceable></userinput>
<computeroutput>psql (9.3.6)
Type "help" for help.
</computeroutput>
<prompt>guacamole=# </prompt><userinput>CREATE USER <replaceable>guacamole_user</replaceable> WITH PASSWORD '<replaceable>some_password</replaceable>';</userinput>
<computeroutput>CREATE ROLE</computeroutput>
<prompt>guacamole=# </prompt><userinput>GRANT SELECT,INSERT,UPDATE,DELETE ON ALL TABLES IN SCHEMA public TO <replaceable>guacamole_user</replaceable>;</userinput>
<computeroutput>GRANT</computeroutput>
<prompt>guacamole=# </prompt><userinput>GRANT SELECT,USAGE ON ALL SEQUENCES IN SCHEMA public TO <replaceable>guacamole_user</replaceable>;</userinput>
<computeroutput>GRANT</computeroutput>
<prompt>guacamole=# </prompt><userinput>\q</userinput>
<prompt>$</prompt></screen>
</informalexample>
<important xml:id="jdbc-auth-postgresql-upgrade">
<para>If you are upgrading from an older version of Guacamole and were already using
PostgreSQL, you may need to run one or more database schema upgrade scripts
located within the <filename>schema/upgrade/</filename> directory. Each of these
scripts is named
<filename>upgrade-pre-<replaceable>VERSION</replaceable>.sql</filename>
where <replaceable>VERSION</replaceable> is the version of Guacamole where those
changes were introduced. They need to be run when you are upgrading from a
version of Guacamole older than <replaceable>VERSION</replaceable>:</para>
<informalexample>
<screen><prompt>$</prompt> <userinput>ls schema/upgrade/</userinput>
<computeroutput>upgrade-pre-0.9.10.sql upgrade-pre-0.9.13.sql upgrade-pre-0.9.8.sql
upgrade-pre-0.9.11.sql upgrade-pre-0.9.7.sql upgrade-pre-0.9.9.sql</computeroutput>
<prompt>$</prompt></screen>
</informalexample>
<para>These scripts are incremental and, when relevant, <emphasis>must be run in
order</emphasis>. For example, if you are upgrading an existing database
from version 0.9.10-incubating, you would need to run the
<filename>upgrade-pre-0.9.11.sql</filename> script (because 0.9.10 is older
than 0.9.11), followed by the <filename>upgrade-pre-0.9.13.sql</filename> script
(because 0.9.10 is also older than 0.9.13):</para>
<informalexample>
<screen><prompt>$</prompt> <userinput>psql -d <replaceable>guacamole_db</replaceable> -f schema/upgrade/upgrade-pre-0.9.11.sql</userinput>
<computeroutput>ALTER TABLE
CREATE TABLE
CREATE INDEX</computeroutput>
<prompt>$</prompt> <userinput>psql -d <replaceable>guacamole_db</replaceable> -f schema/upgrade/upgrade-pre-0.9.13.sql</userinput>
<computeroutput>CREATE TYPE
ALTER TABLE
ALTER TABLE
ALTER TABLE
ALTER TABLE
ALTER TABLE
ALTER TABLE
ALTER TABLE</computeroutput>
<prompt>$</prompt></screen>
</informalexample>
<para>Because the permissions granted to the Guacamole-specific PostgreSQL user when
the database was first created will not automatically be granted for any new
tables and sequences, you will also need to re-grant those permissions after
applying any upgrade relevant scripts:</para>
<informalexample>
<screen><prompt>$</prompt> <userinput>psql -d <replaceable>guacamole_db</replaceable></userinput>
<computeroutput>psql (9.3.6)
Type "help" for help.
</computeroutput>
<prompt>guacamole=# </prompt><userinput>GRANT SELECT,INSERT,UPDATE,DELETE ON ALL TABLES IN SCHEMA public TO <replaceable>guacamole_user</replaceable>;</userinput>
<computeroutput>GRANT</computeroutput>
<prompt>guacamole=# </prompt><userinput>GRANT SELECT,USAGE ON ALL SEQUENCES IN SCHEMA public TO <replaceable>guacamole_user</replaceable>;</userinput>
<computeroutput>GRANT</computeroutput>
<prompt>guacamole=# </prompt><userinput>\q</userinput>
<prompt>$</prompt></screen>
</informalexample>
<para>If there are no
<filename>upgrade-pre-<replaceable>VERSION</replaceable>.sql</filename>
scripts present in the <filename>schema/upgrade/</filename> directory which
apply to your existing Guacamole database, then the schema has not changed
between your version and the version your are installing, and there is no need
to run any database upgrade scripts.</para>
</important>
</section>
</section>
<section xml:id="jdbc-auth-installation">
<title>Installing database 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 database 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-jdbc-mysql-0.9.13-incubating.jar</filename>
<emphasis>or</emphasis>
<filename>guacamole-auth-jdbc-postgresql-0.9.13-incubating.jar</filename> within
<filename>GUACAMOLE_HOME/extensions</filename>, depending on whether you are
using MySQL/MariaDB or PostgreSQL.</para>
</step>
<step>
<para>Copy the JDBC driver for your database to
<filename>GUACAMOLE_HOME/lib</filename>. Without a JDBC driver for your
database, Guacamole will not be able to connect and authenticate users.</para>
</step>
<step>
<para>Configure Guacamole to use database 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 database authentication properly, Guacamole will not start up again
until the configuration is fixed.</para>
</important>
<section xml:id="jdbc-auth-configuration">
<title>Configuring Guacamole for database authentication</title>
<para>Additional properties must be added to <filename>guacamole.properties</filename>
for Guacamole to properly connect to your database. These properties are specific to
the database being used, and must be set correctly for authentication to
work.</para>
<para>To use a MySQL database, you will need to specify the following:</para>
<informalexample>
<programlisting># MySQL properties
mysql-hostname: localhost
mysql-port: 3306
mysql-database: <replaceable>guacamole_db</replaceable>
mysql-username: <replaceable>guacamole_user</replaceable>
mysql-password: <replaceable>some_password</replaceable></programlisting>
<para>For PostgreSQL, the properties are similar, but with different
prefixes:</para>
<informalexample>
<programlisting># PostgreSQL properties
postgresql-hostname: localhost
postgresql-port: 5432
postgresql-database: <replaceable>guacamole_db</replaceable>
postgresql-username: <replaceable>guacamole_user</replaceable>
postgresql-password: <replaceable>some_password</replaceable></programlisting>
</informalexample>
</informalexample>
<para>The properties absolutely required by the database authentication extension are
relatively few and self-explanatory, describing only how the connection to the
database is to be established, and how Guacamole will authenticate when querying the
database:</para>
<informaltable frame="all">
<tgroup cols="3">
<colspec colname="c1" colnum="1" colwidth="1*"/>
<colspec colname="c2" colnum="2" colwidth="1*"/>
<colspec colname="c3" colnum="3" colwidth="2*"/>
<thead>
<row>
<entry>MySQL/MariaDB Property</entry>
<entry>PostgreSQL Property</entry>
<entry>Description</entry>
</row>
</thead>
<tbody>
<row>
<entry><property>mysql-hostname</property></entry>
<entry><property>postgresql-hostname</property></entry>
<entry>
<para>The hostname or IP address of the server hosting your
database.</para>
</entry>
</row>
<row>
<entry><property>mysql-port</property></entry>
<entry><property>postgresql-port</property></entry>
<entry>
<para>The port number of the database to connect to. For MySQL and
MariaDB, this will likely be 3306. For PostgreSQL, this will
likely be 5432.</para>
</entry>
</row>
<row>
<entry><property>mysql-database</property></entry>
<entry><property>postgresql-database</property></entry>
<entry>
<para>The name of the database that you created for Guacamole. This
is given as "guacamole_db" in the examples given in this
chapter.</para>
</entry>
</row>
<row>
<entry><property>mysql-username</property></entry>
<entry><property>postgresql-username</property></entry>
<entry>
<para>The username of the user that Guacamole should use to connect
to the database. This is given as "guacamole_user" in the
examples given in this chapter.</para>
</entry>
</row>
<row>
<entry><property>mysql-password</property></entry>
<entry><property>postgresql-password</property></entry>
<entry>
<para>The password Guacamole should provide when authenticating with
the database. This is given as "some_password" in the examples
given in this chapter.</para>
</entry>
</row>
</tbody>
</tgroup>
</informaltable>
<para>Be sure to specify the correct username and password for the database user you
created, and to specify the correct database. Authentication will not work if these
parameters are not correct.</para>
<section>
<title>Enforcing password policies</title>
<para>Configuration options are available for enforcing rules intended to encourage
password complexity and regular changing of passwords. None of these options are
enabled by default, but can be selectively enabled through additional properties
in <filename>guacamole.properties</filename>.</para>
<section>
<title>Password complexity</title>
<para>Administrators can require that passwords have a certain level of
complexity, such as having both uppercase and lowercase letters ("multiple
case"), at least one digit, or at least one symbol, and can prohibit
passwords from containing the user's own username.</para>
<para>For the sake of password content, the database authentication defines a
"digit" as any numeric character. This takes non-English languages into
account, and is not be simply "0" thorough "9". There are quite a few <link
xlink:href="https://en.wikipedia.org/wiki/Numerals_in_Unicode">numeric
characters defined by Unicode</link>. A "symbol" is defined as any
non-alphanumeric character - any character which Unicode does not define as
alphabetic or numeric.</para>
<para>The check for whether a password contains the user's own username is
performed in a case-insensitive manner. For example, if the user's username
is "phil", the passwords "ch!0roPhil" and "PHIL-o-dendr0n" would still be
prohibited.</para>
<informalexample>
<programlisting># MySQL
mysql-user-password-min-length: <replaceable>8</replaceable>
mysql-user-password-require-multiple-case: true
mysql-user-password-require-symbol: true
mysql-user-password-require-digit: true
mysql-user-password-prohibit-username: true
# PostgreSQL
postgresql-user-password-min-length: <replaceable>8</replaceable>
postgresql-user-password-require-multiple-case: true
postgresql-user-password-require-symbol: true
postgresql-user-password-require-digit: true
postgresql-user-password-prohibit-username: true</programlisting>
</informalexample>
</section>
<section>
<title>Password age / expiration</title>
<para>"Password age" refers to two separate concepts:</para>
<orderedlist>
<listitem>
<para>Requiring users to change their password after a certain amount of
time has elapsed since the last password change (maximum password
age).</para>
</listitem>
<listitem>
<para>Preventing users from changing their password too frequently
(minimum password age).</para>
</listitem>
</orderedlist>
<para>In both cases, these values are specified in units of days, and are both
disabled by default.</para>
<para>While it may seem strange to prevent users from changing their password
too frequently, it does make sense if you are concerned that rapid password
changes may defeat password expiration (users could immediately change the
password back) or tracking of password history (users could cycle through
passwords until the history is exhausted and their old password is
back).</para>
<para>So that administrators can always intervene in the case that a password
needs to be reset despite restrictions, the minimum age restriction does not
apply to any user with permission to administer the system.</para>
<informalexample>
<programlisting># MySQL
mysql-user-password-min-age: <replaceable>7</replaceable>
mysql-user-password-max-age: <replaceable>90</replaceable>
# PostgreSQL
postgresql-user-password-min-age: <replaceable>7</replaceable>
postgresql-user-password-max-age: <replaceable>90</replaceable></programlisting>
</informalexample>
</section>
<section>
<title>Preventing password reuse</title>
<para>If desired, Guacamole can keep track of each user's most recently used
passwords, and will prohibit reuse of those passwords until the password has
been changed sufficiently many times. By default, Guacamole will not keep
track of old passwords.</para>
<para>Note that these passwords are hashed in the same manner as each user's
current password. When a user's password is changed, the hash, salt, etc.
currently stored for that user is actually just copied verbatim (along with
a timestamp) into a list of historical passwords, with older entries from
this list being automatically deleted.</para>
<informalexample>
<programlisting># MySQL
mysql-user-password-history-size: <replaceable>6</replaceable>
# PostgreSQL
postgresql-user-password-history-size: <replaceable>6</replaceable></programlisting>
</informalexample>
</section>
</section>
<section xml:id="jdbc-auth-concurrency">
<title>Concurrent use of Guacamole connections</title>
<para>The database authentication module provides configuration options to restrict
concurrent use of connections or connection groups. These options are set
through <filename>guacamole.properties</filename> and specify the default
concurrency policies for connections and connection groups. The values set
through the properties can be overridden later on a per-connection basis using
the administrative interface:</para>
<informalexample>
<programlisting># MySQL
mysql-default-max-connections: 1
mysql-default-max-group-connections: 1
# PostgreSQL
postgresql-default-max-connections: 1
postgresql-default-max-group-connections: 1</programlisting>
</informalexample>
<para>These properties are not required, but with the above properties in place,
users attempting to use a connection or group that is already in use will be
denied access. By default, concurrent access is allowed.</para>
<para>Concurrent access can also be restricted such that a particular user may only
use a connection or group a certain number of times. By default, per-user
concurrent use is limited for connection groups (to avoid allowing a single user
to exhaust the contents of the group) but otherwise unrestricted. This default
behavior can be modified through <filename>guacamole.properties</filename> or
the per-connection settings exposed in the administrative interface:</para>
<informalexample>
<programlisting># MySQL
mysql-default-max-connections-per-user: 0
mysql-default-max-group-connections-per-user: 0
# PostgreSQL
postgresql-default-max-connections-per-user: 0
postgresql-default-max-group-connections-per-user: 0</programlisting>
</informalexample>
<para>The above properties replace the "simultaneous" and "duplicate" properties used
by prior Guacamole releases. The older properties will still work, but are now
deprecated. If you continue to use those properties, you will receive warnings
in the logs advising you of their deprecated status and including examples for
providing the same behavior with the new properties described above:</para>
<informalexample>
<screen><computeroutput>WARN o.g.g.a.p.PostgreSQLAuthenticationProvider - The
"postgresql-disallow-simultaneous-connections" property is deprecated.
Use "postgresql-default-max-connections" and
"postgresql-default-max-group-connections" instead.
INFO o.g.g.a.p.PostgreSQLAuthenticationProvider - To achieve the same
result of setting "postgresql-disallow-simultaneous-connections" to
"false", set "postgresql-default-max-connections" to "0" and
"postgresql-default-max-group-connections" to "0".</computeroutput></screen>
</informalexample>
<para>If you wish to impose an absolute limit on the number of connections that can
be established through Guacamole, ignoring which users or connections are
involved, this can be done as well. By default, Guacamole will impose no such
limit:</para>
<informalexample>
<programlisting># MySQL
mysql-absolute-max-connections: 0
# PostgreSQL
postgresql-absolute-max-connections: 0</programlisting>
</informalexample>
</section>
</section>
<section xml:id="jdbc-auth-restrict">
<title>Restricting authentication to database users only</title>
<para>By default, users will be allowed access to Guacamole as long as they are
authenticated by at least one extension. If database authentication is in use, and a
user is not associated with the database, then that user will be allowed access to
Guacamole if another extension grants this access, and will be provided with a view
of the data exposed by other extensions for that user account.</para>
<para>In some situations, such as when <link linkend="ldap-and-database">combining LDAP
with a database</link>, it would be preferable to let the database have the last
word regarding whether a user should be allowed into the system: restricting access
to only those users which exist in the database, and explicitly denying
authentication through all other means unless that user has been associated with the
database as well. This behavior can be forced by setting properties which declare
that database user accounts are required:</para>
<informalexample>
<programlisting># MySQL
mysql-user-required: true
# PostgreSQL
postgresql-user-required: true</programlisting>
</informalexample>
<para>With the above properties set, successful authentication attempts for users which
are not associated with the database will be vetoed by the database authentication.
Guacamole will report that the login is invalid, as if the user does not exist at
all.</para>
</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 database 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 database authentication
extension will prevent Guacamole from starting up, and any such errors will be
recorded in the logs of your servlet container.</para>
</section>
</section>
<section xml:id="jdbc-auth-default-user">
<title>Logging in</title>
<indexterm>
<primary>default user</primary>
</indexterm>
<indexterm>
<primary><systemitem>guacadmin</systemitem></primary>
</indexterm>
<para>The default Guacamole user created by the provided SQL scripts is
"<systemitem>guacadmin</systemitem>", with a default password of
"<systemitem>guacadmin</systemitem>". Once you have verified that the database
authentication is working, <emphasis>you should change your password
immediately</emphasis>.</para>
<para>More detailed instructions for managing users and connections is given in <xref
linkend="administration"/>.</para>
</section>
<section xml:id="jdbc-auth-schema">
<title>Modifying data manually</title>
<indexterm>
<primary>schema</primary>
</indexterm>
<para>If necessary, it is possible to modify the data backing the authentication module
manually by executing SQL statements against the database. In general use, this will not
be common, but if you need to bulk-insert a large number of users or connections, or you
wish to translate an existing configuration automatically, you will need to know how
everything is laid out at a high level.</para>
<para>This section assumes knowledge of SQL and your chosen database, and that whatever you
need to do can be accomplished if only you had high-level information about Guacamole's
SQL schema.</para>
<section xml:id="jdbc-auth-schema-users">
<title>Users</title>
<indexterm>
<primary><classname>guacamole_user</classname></primary>
</indexterm>
<para>Every user has a corresponding entry in the <classname>guacamole_user</classname>
table. Each user has a corresponding unique username and salted password. The salted
password is split into two columns: one containing the salt, and the other
containing the password hashed with SHA-256.</para>
<para>The <classname>guacamole_user</classname> table contains the following
columns:</para>
<variablelist>
<varlistentry>
<term><property>user_id</property></term>
<listitem>
<para>The unique integer associated with each user. This value is generated
automatically when a new entry is inserted into the
<classname>guacamole_user</classname> table.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><property>username</property></term>
<listitem>
<para>The unique name associated with each user. This value must be
specified manually, and must be different from any existing username in
the table. References to users in other tables use the value from
<property>user_id</property>, not
<property>username</property>.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><property>password_hash</property></term>
<listitem>
<para>The result of hashing the user's password concatenated with the
contents of <property>password_salt</property> using SHA-256. The salt
is appended to the password prior to hashing.</para>
<para>Although passwords set through Guacamole will always be salted, it is
possible to use unsalted password hashes when inserted manually or
through an external system. If <property>password_salt</property> is
<constant>NULL</constant>, the <property>password_hash</property>
will be handled as a simple unsalted hash of the password.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><property>password_salt</property></term>
<listitem>
<para>A 32-byte random value. When a new user is created from the web
interface, this value is randomly generated using a
cryptographically-secure random number generator.</para>
<para>This will always be set for users whose passwords are set through
Guacamole, but it is possible to use unsalted password hashes when
inserted manually or through an external system. If
<property>password_salt</property> is <constant>NULL</constant>, the
<property>password_hash</property> will be handled as a simple
unsalted hash of the password.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><property>password_date</property></term>
<listitem>
<para>The date (and time) that the password was last changed. When a
password is changed via the Guacamole interface, this value is updated.
This, along with the contents of the
<classname>guacamole_user_password_history</classname> table, is
used to enforce password policies.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><property>disabled</property></term>
<listitem>
<para>Whether login attempts as this user account should be rejected. If
this column is set to <constant>TRUE</constant> or
<constant>1</constant>, login attempts by this user will be rejected
as if the user did not exist. By default, user accounts are not
disabled, and login attempts will succeed if the user provides the
correct password.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><property>expired</property></term>
<listitem>
<para>If set to <constant>TRUE</constant> or <constant>1</constant>,
requires that the user reset their password prior to fully logging in.
The user will be presented with a password reset form, and will not be
allowed to log into Guacamole until the password has been changed. By
default, user accounts are not expired, and no password reset will be
required upon login.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><property>access_window_start</property></term>
<listitem>
<para>The time of day (not date) after which this user account may be used.
If <constant>NULL</constant>, this restriction does not apply. If set to
non-<constant>NULL</constant>, attempts to log in after the
specified time will be allowed, while attempts to log in before the
specified time will be denied.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><property>access_window_end</property></term>
<listitem>
<para>The time of day (not date) after which this user account may
<emphasis>not</emphasis> be used. If <constant>NULL</constant>, this
restriction does not apply. If set to non-<constant>NULL</constant>,
attempts to log in after the specified time will be denied, while
attempts to log in before the specified time will be allowed.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><property>valid_from</property></term>
<listitem>
<para>The date (not time of day) after which this user account may be used.
If <constant>NULL</constant>, this restriction does not apply. If set to
non-<constant>NULL</constant>, attempts to log in after the
specified date will be allowed, while attempts to log in before the
specified date will be denied.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><property>valid_until</property></term>
<listitem>
<para>The date (not time of day) after which this user account may
<emphasis>not</emphasis> be used. If <constant>NULL</constant>, this
restriction does not apply. If set to non-<constant>NULL</constant>,
attempts to log in after the specified date will be denied, while
attempts to log in before the specified date will be allowed.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><property>timezone</property></term>
<listitem>
<para>The time zone to use when interpreting the
<property>access_window_start</property>,
<property>access_window_end</property>,
<property>valid_from</property>, and
<property>valid_until</property> values. This value may be any Java
<classname>TimeZone</classname> ID, as defined by <link
xlink:href="http://docs.oracle.com/javase/7/docs/api/java/util/TimeZone.html#getAvailableIDs()"
><methodname
>getAvailableIDs()</methodname></link>, though the Guacamole
management interface will only present a subset of these time
zones.</para>
</listitem>
</varlistentry>
</variablelist>
<important>
<para>If you choose to manually set unsalted password hashes, please be sure you
understand the security implications of doing so.</para>
<para>In the event that your database is compromised, finding the password for a
<emphasis>salted</emphasis> hash is computationally infeasible, but finding
the password for an <emphasis>unsalted</emphasis> hash is often not. In many
cases, the password which corresponds to an unsalted hash can be found simply by
entering the hash into a search engine like Google.</para>
</important>
<para>If creating a user manually, the main complication is the salt, which must be
determined before the <command>INSERT</command> statement can be constructed, but
this can be dealt with using variables. For MySQL:</para>
<informalexample>
<programlisting>-- Generate salt
SET @salt = UNHEX(SHA2(UUID(), 256));
-- Create user and hash password with salt
INSERT INTO guacamole_user (username, password_salt, password_hash)
VALUES ('myuser', @salt, UNHEX(SHA2(CONCAT('mypassword', HEX(@salt)), 256)));</programlisting>
</informalexample>
<para>This sort of statement is useful for both creating new users or for changing
passwords, especially if all administrators have forgotten theirs.</para>
<para>If you are not using MySQL, or you are using a version of MySQL that lacks the
<methodname>SHA2</methodname> function, you will need to calculate the SHA-256
value manually (by using the <command>sha256sum</command> command, for
example).</para>
<section xml:id="jdbc-auth-schema-password-history">
<title>Password history</title>
<indexterm>
<primary><classname>guacamole_user_password_history</classname></primary>
</indexterm>
<para>When a user's password is changed, a copy of the previous password's hash and
salt is made within the <classname>guacamole_user_password_history</classname>.
Each entry in this table is associated with the user whose password changed,
along with the date that password first applied.</para>
<para>Old entries within this table are automatically deleted on a per-user basis
depending on the requirements of the password policy. For example, if the
password policy has been configured to require that users not reuse any of their
previous six passwords, then there will be no more than six entries in this
table for each user.</para>
<variablelist>
<varlistentry>
<term><property>password_history_id</property></term>
<listitem>
<para>The unique integer associated with each password history record.
This value is generated automatically when a new entry is inserted
into the <classname>guacamole_user_password_history</classname>
table.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><property>user_id</property></term>
<listitem>
<para>The value of the <property>user_id</property> column from the
entry in <classname>guacamole_user</classname> associated with the
user who previously had this password.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><property>password_hash</property></term>
<listitem>
<para>The hashed password specified within the
<property>password_hash</property> column of
<classname>guacamole_user</classname> prior to the password
being changed.</para>
<para>In most cases, this will be a salted hash, though it is possible
to force the use of unsalted hashes when making changes to the
database manually or through an external system.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><property>password_salt</property></term>
<listitem>
<para>The salt value specified within the
<property>password_salt</property> column of
<classname>guacamole_user</classname> prior to the password
being changed.</para>
<para>This will always be set for users whose passwords are set through
Guacamole, but it is possible to use unsalted password hashes when
inserted manually or through an external system, in which case this
may be <constant>NULL</constant>.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><property>password_date</property></term>
<listitem>
<para>The date (and time) that the password was set. The time that the
password ceased being used is recorded either by the password_date
of the next related entry in
<classname>guacamole_user_password_history</classname> or
<property>password_date</property> of
<classname>guacamole_user</classname> (if there is no such
history entry).</para>
</listitem>
</varlistentry>
</variablelist>
</section>
</section>
<section xml:id="jdbc-auth-schema-connections">
<title>Connections and parameters</title>
<indexterm>
<primary><classname>guacamole_connection</classname></primary>
</indexterm>
<indexterm>
<primary><classname>guacamole_connection_parameter</classname></primary>
</indexterm>
<para>Each connection has an entry in the <classname>guacamole_connection</classname>
table, with a one-to-many relationship to parameters, stored as name/value pairs in
the <classname>guacamole_connection_parameter</classname> table.</para>
<para>The <classname>guacamole_connection</classname> table is simply a pairing of a
unique and descriptive name with the protocol to be used for the connection. It
contains the following columns:</para>
<variablelist>
<varlistentry>
<term><property>connection_id</property></term>
<listitem>
<para>The unique integer associated with each connection. This value is
generated automatically when a new entry is inserted into the
<classname>guacamole_connection</classname> table.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><property>connection_name</property></term>
<listitem>
<para>The unique name associated with each connection. This value must be
specified manually, and must be different from any existing connection
name in the same connection group. References to connections in other
tables use the value from <property>connection_id</property>, not
<property>connection_name</property>.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><property>protocol</property></term>
<listitem>
<para>The protocol to use with this connection. This is the name of the
protocol that should be sent to <package>guacd</package> when
connecting, for example "<constant>vnc</constant>" or
"<constant>rdp</constant>".</para>
</listitem>
</varlistentry>
<varlistentry>
<term><property>parent_id</property></term>
<listitem>
<para>The unique integer associated with the connection group containing
this connection, or <constant>NULL</constant> if this connection is
within the root group.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><property>max_connections</property></term>
<listitem>
<para>The maximum number of concurrent connections to allow to this
connection at any one time <emphasis>regardless of user</emphasis>.
<constant>NULL</constant> will use the default value specified in
<filename>guacamole.properties</filename> with the
<property>mysql-default-max-connections</property> or
<property>postgresql-default-max-connections</property> properties,
and a value of <constant>0</constant> denotes unlimited.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><property>max_connections_per_user</property></term>
<listitem>
<para>The maximum number of concurrent connections to allow to this
connection at any one time <emphasis>from a single user</emphasis>.
<constant>NULL</constant> will use the default value specified in
<filename>guacamole.properties</filename> with the
<property>mysql-default-max-connections</property> or
<property>postgresql-default-max-connections</property> properties,
and a value of <constant>0</constant> denotes unlimited.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><property>proxy_hostname</property></term>
<listitem>
<para>The hostname or IP address of the Guacamole proxy daemon
(<package>guacd</package>) which should be used for this connection.
If <constant>NULL</constant>, the value defined with the
<property>guacd-hostname</property> property in
<filename>guacamole.properties</filename> will be used.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><property>proxy_port</property></term>
<listitem>
<para>The TCP port number of the Guacamole proxy daemon
(<package>guacd</package>) which should be used for this connection.
If <constant>NULL</constant>, the value defined with the
<property>guacd-port</property> property in
<filename>guacamole.properties</filename> will be used.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><property>proxy_encryption_method</property></term>
<listitem>
<para>The encryption method which should be used when communicating with the
Guacamole proxy daemon (<package>guacd</package>) for this connection.
This can be either <constant>NONE</constant>, for no encryption, or
<constant>SSL</constant>, for SSL/TLS. If <constant>NULL</constant>,
the encryption method will be dictated by the
<property>guacd-ssl</property> property in
<filename>guacamole.properties</filename>.</para>
</listitem>
</varlistentry>
</variablelist>
<para>As there are potentially multiple parameters per connection, where the names of
each parameter are completely arbitrary and determined only by the protocol in use,
every parameter for a given connection has an entry in table
<classname>guacamole_connection_parameter</classname> table associated with its
corresponding connection. This table contains the following columns:</para>
<variablelist>
<varlistentry>
<term><property>connection_id</property></term>
<listitem>
<para>The <property>connection_id</property> value from the connection this
parameter is for.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><property>parameter_name</property></term>
<listitem>
<para>The name of the parameter to set. This is the name listed in the
documentation for the protocol specified in the associated
connection.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><property>parameter_value</property></term>
<listitem>
<para>The value to assign to the parameter named. While this value is an
arbitrary string, it must conform to the requirements of the protocol as
documented for the connection to be successful.</para>
</listitem>
</varlistentry>
</variablelist>
<para>Adding a connection and corresponding parameters is relatively easy compared to
adding a user as there is no salt to generate nor password to hash:</para>
<informalexample>
<programlisting>-- Create connection
INSERT INTO guacamole_connection (connection_name, protocol) VALUES ('<replaceable>test</replaceable>', '<replaceable>vnc</replaceable>');
-- Determine the connection_id
SELECT * FROM guacamole_connection WHERE connection_name = '<replaceable>test</replaceable>' AND parent_id IS NULL;
-- Add parameters to the new connection
INSERT INTO guacamole_connection_parameter VALUES (<replaceable>1</replaceable>, 'hostname', '<replaceable>localhost</replaceable>');
INSERT INTO guacamole_connection_parameter VALUES (<replaceable>1</replaceable>, 'port', '<replaceable>5901</replaceable>');</programlisting>
</informalexample>
<section xml:id="jdbc-auth-schema-connection-history">
<title>Usage history</title>
<indexterm>
<primary><classname>guacamole_connection_history</classname></primary>
</indexterm>
<para>When a connection is initiated or terminated, a corresponding entry in the
<classname>guacamole_connection_history</classname> table is created or
updated respectively. Each entry is associated with the user using the
connection, the connection itself, the <link
linkend="jdbc-auth-schema-sharing-profiles">sharing profile</link> in use
(if the connection is being shared), and the time the connection started. If the
connection has ended, the end time is also stored.</para>
<para>It is very unlikely that a user will need to update this table, but knowing
the structure is potentially useful if you wish to generate a report of
Guacamole usage. The <classname>guacamole_connection_history</classname> table
has the following columns:</para>
<variablelist>
<varlistentry>
<term><property>history_id</property></term>
<listitem>
<para>The unique integer associated with each history record. This value
is generated automatically when a new entry is inserted into the
<classname>guacamole_connection_history</classname>
table.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><property>user_id</property></term>
<listitem>
<para>The value of the <property>user_id</property> from the entry in
<classname>guacamole_user</classname> associated with the user
using the connection. If the user no longer exists, this will be
<constant>NULL</constant>.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><property>username</property></term>
<listitem>
<para>The username associated with the user at the time that they used
the connection. This username value is not guaranteed to uniquely
identify a user, as the original user may be subsequently renamed or
deleted.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><property>connection_id</property></term>
<listitem>
<para>The value of the <property>connection_id</property> from the entry
in <classname>guacamole_connection</classname> associated the
connection being used. If the connection associated with the history
record no longer exists, this will be
<constant>NULL</constant>.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><property>connection_name</property></term>
<listitem>
<para>The name associated with the connection at the time that it was
used.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><property>sharing_profile_id</property></term>
<listitem>
<para>The value of the <property>sharing_profile_id</property> from the
entry in <classname>guacamole_sharing_profile</classname> associated
the sharing profile being used to access the connection. If the
connection is not being shared (no sharing profile is being used),
or if the sharing profile associated with the history record no
longer exists, this will be <constant>NULL</constant>.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><property>sharing_profile_name</property></term>
<listitem>
<para>The name associated with the sharing profile being used to access
the connection at the time this history entry was recorded. If the
connection is not being shared, this will be
<constant>NULL</constant>.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><property>start_date</property></term>
<listitem>
<para>The time at which the connection was started by the user
specified. Despite its name, this column also stores time
information in addition to the date.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><property>end_date</property></term>
<listitem>
<para>The time at which the connection ended. If the connection is still
active, the value in this column will be <constant>NULL</constant>.
Despite its name, this column also stores time information in
addition to the date.</para>
</listitem>
</varlistentry>
</variablelist>
</section>
</section>
<section xml:id="jdbc-auth-schema-sharing-profiles">
<title>Sharing profiles and parameters</title>
<indexterm>
<primary><classname>guacamole_sharing_profile</classname></primary>
</indexterm>
<indexterm>
<primary><classname>guacamole_sharing_profile_parameter</classname></primary>
</indexterm>
<para>Each sharing profile has an entry in the
<classname>guacamole_sharing_profile</classname> table, with a one-to-many
relationship to parameters, stored as name/value pairs in the
<classname>guacamole_sharing_profile_parameter</classname> table.</para>
<para>The <classname>guacamole_sharing_profile</classname> table is simply a pairing of
a unique and descriptive name with the connection that can be shared using the
sharing profile, also known as the "primary connection". It contains the following
columns:</para>
<variablelist>
<varlistentry>
<term><property>sharing_profile_id</property></term>
<listitem>
<para>The unique integer associated with each sharing profile. This value is
generated automatically when a new entry is inserted into the
<classname>guacamole_sharing_profile</classname> table.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><property>sharing_profile_name</property></term>
<listitem>
<para>The unique name associated with each sharing profile. This value must
be specified manually, and must be different from any existing sharing
profile name associated with the same primary connection. References to
sharing profiles in other tables use the value from
<property>sharing_profile_id</property>, not
<property>sharing_profile_name</property>.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><property>primary_connection_id</property></term>
<listitem>
<para>The unique integer associated with the primary connection. The
"primary connection" is the connection which can be shared using this
sharing profile.</para>
</listitem>
</varlistentry>
</variablelist>
<para>As there are potentially multiple parameters per sharing profile, where the names
of each parameter are completely arbitrary and determined only by the protocol
associated with the primary connection, every parameter for a given sharing profile
has an entry in the <classname>guacamole_sharing_profile_parameter</classname> table
associated with its corresponding sharing profile. This table contains the following
columns:</para>
<variablelist>
<varlistentry>
<term><property>sharing_profile_id</property></term>
<listitem>
<para>The <property>sharing_profile_id</property> value from the entry in
the <classname>guacamole_sharing_profile</classname> table for the
sharing profile this parameter applies to.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><property>parameter_name</property></term>
<listitem>
<para>The name of the parameter to set. This is the name listed in the
documentation for the protocol of the primary connection of the
associated sharing profile.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><property>parameter_value</property></term>
<listitem>
<para>The value to assign to the parameter named. While this value is an
arbitrary string, it must conform to the requirements of the protocol as
documented.</para>
</listitem>
</varlistentry>
</variablelist>
</section>
<section xml:id="jdbc-auth-schema-connection-groups">
<title>Connection groups</title>
<indexterm>
<primary><classname>guacamole_connection_group</classname></primary>
</indexterm>
<para>Each connection group has an entry in the
<classname>guacamole_connection_group</classname> table, with a one-to-many
relationship to other groups and connections.</para>
<para>The <classname>guacamole_connection_group</classname> table is simply a pairing of
a unique and descriptive name with a group type, which can be either
<type>ORGANIZATIONAL</type> or <type>BALANCING</type>. It contains the following
columns:</para>
<variablelist>
<varlistentry>
<term><property>connection_group_id</property></term>
<listitem>
<para>The unique integer associated with each connection group. This value
is generated automatically when a new entry is inserted into the
<classname>guacamole_connection_group</classname> table.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><property>connection_group_name</property></term>
<listitem>
<para>The unique name associated with each connection group. This value must
be specified manually, and must be different from any existing
connection group name in the same connection group. References to
connections in other tables use the value from
<property>connection_group_id</property>, not
<property>connection_group_name</property>.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><property>type</property></term>
<listitem>
<para>The type of this connection group. This can be either
<type>ORGANIZATIONAL</type> or <type>BALANCING</type>.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><property>parent_id</property></term>
<listitem>
<para>The unique integer associated with the connection group containing
this connection group, or <constant>NULL</constant> if this connection
group is within the root group.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><property>max_connections</property></term>
<listitem>
<para>The maximum number of concurrent connections to allow to this
connection group at any one time <emphasis>regardless of
user</emphasis>. <constant>NULL</constant> will use the default value
specified in <filename>guacamole.properties</filename> with the
<property>mysql-default-max-connections</property> or
<property>postgresql-default-max-connections</property> properties,
and a value of <constant>0</constant> denotes unlimited. This only has
an effect on <type>BALANCING</type> groups.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><property>max_connections_per_user</property></term>
<listitem>
<para>The maximum number of concurrent connections to allow to this
connection group at any one time <emphasis>from a single
user</emphasis>. <constant>NULL</constant> will use the default value
specified in <filename>guacamole.properties</filename> with the
<property>mysql-default-max-connections</property> or
<property>postgresql-default-max-connections</property> properties,
and a value of <constant>0</constant> denotes unlimited. This only has
an effect on <type>BALANCING</type> groups.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><property>enable_session_affinity</property></term>
<listitem>
<para>Whether session affinity should apply to this connection group. If
this column is set to <constant>TRUE</constant> or
<constant>1</constant>, users will be consistently routed to the
same underlying connection until they log out. The normal balancing
behavior will only apply for each user's first connection attempt during
any one Guacamole session. By default, session affinity is not enabled,
and connections will always be balanced across the entire connection
group. This only has an effect on <type>BALANCING</type> groups.</para>
</listitem>
</varlistentry>
</variablelist>
<para>Adding a connection group is even simpler than adding a new connection as there
are no associated parameters stored in a separate table:</para>
<informalexample>
<programlisting>-- Create connection group
INSERT INTO guacamole_connection_group (connection_group_name, type)
VALUES ('<replaceable>test</replaceable>', '<replaceable>ORGANIZATIONAL</replaceable>');</programlisting>
</informalexample>
</section>
<section xml:id="jdbc-auth-schema-permissions">
<title>Permissions</title>
<para>There are three permissions tables in the schema which correspond to the three
types of permissions in Guacamole's authentication model: system permissions, which
control operations that affect the system as a whole, and user and connection
permissions, which control operations that affect specific, existing users or
connections respectively.</para>
<section xml:id="jdbc-auth-schema-system-permissions">
<title>System permissions</title>
<indexterm>
<primary><classname>guacamole_system_permission</classname></primary>
</indexterm>
<para>System permissions are defined by entries in the
<classname>guacamole_system_permission</classname> table. Each entry grants
permission for a specific user to perform a specific system operation.</para>
<para>The <classname>guacamole_system_permission</classname> table contains the
following columns:</para>
<variablelist>
<varlistentry>
<term><property>user_id</property></term>
<listitem>
<para>The value of the <property>user_id</property> column of the entry
associated with the user owning this permission.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><property>permission</property></term>
<listitem>
<para>The permission being granted. This column can have one of three
possible values: <constant>ADMINISTER</constant>, which grants the
ability to administer the entire system (essentially a wildcard
permission), <constant>CREATE_CONNECTION</constant>, which grants
the ability to create connections,
<constant>CREATE_CONNECTION_GROUP</constant>, which grants the
ability to create connections groups, or
<constant>CREATE_USER</constant>, which grants the ability to
create users.</para>
</listitem>
</varlistentry>
</variablelist>
</section>
<section xml:id="jdbc-auth-schema-user-permissions">
<title>User permissions</title>
<indexterm>
<primary><classname>guacamole_user_permission</classname></primary>
</indexterm>
<para>User permissions are defined by entries in the
<classname>guacamole_user_permission</classname> table. Each entry grants
permission for a specific user to perform a specific operation on another
existing user.</para>
<para>The <classname>guacamole_user_permission</classname> table contains the
following columns:</para>
<variablelist>
<varlistentry>
<term><property>user_id</property></term>
<listitem>
<para>The value of the <property>user_id</property> column of the entry
associated with the user owning this permission.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><property>affected_user_id</property></term>
<listitem>
<para>The value of the <property>user_id</property> column of the entry
associated with the user <emphasis>affected</emphasis> by this
permission. This is the user that would be the object of the
operation represented by this permission.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><property>permission</property></term>
<listitem>
<para>The permission being granted. This column can have one of four
possible values: <constant>ADMINISTER</constant>, which grants the
ability to add or remove permissions which affect the user,
<constant>READ</constant>, which grants the ability to read data
associated with the user, <constant>UPDATE</constant>, which grants
the ability to update data associated with the user, or
<constant>DELETE</constant>, which grants the ability to delete
the user.</para>
</listitem>
</varlistentry>
</variablelist>
</section>
<section xml:id="jdbc-auth-schema-connection-permissions">
<title>Connection permissions</title>
<indexterm>
<primary><classname>guacamole_connection_permission</classname></primary>
</indexterm>
<para>Connection permissions are defined by entries in the
<classname>guacamole_connection_permission</classname> table. Each entry
grants permission for a specific user to perform a specific operation on an
existing connection.</para>
<para>The <classname>guacamole_connection_permission</classname> table contains the
following columns:</para>
<variablelist>
<varlistentry>
<term><property>user_id</property></term>
<listitem>
<para>The value of the <property>user_id</property> column of the entry
associated with the user owning this permission.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><property>connection_id</property></term>
<listitem>
<para>The value of the <property>connection_id</property> column of the
entry associated with the connection affected by this permission.
This is the connection that would be the object of the operation
represented by this permission.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><property>permission</property></term>
<listitem>
<para>The permission being granted. This column can have one of four
possible values: <constant>ADMINISTER</constant>, which grants the
ability to add or remove permissions which affect the connection,
<constant>READ</constant>, which grants the ability to read data
associated with the connection (a prerequisite for connecting),
<constant>UPDATE</constant>, which grants the ability to update
data associated with the connection, or <constant>DELETE</constant>,
which grants the ability to delete the connection.</para>
</listitem>
</varlistentry>
</variablelist>
</section>
<section xml:id="jdbc-auth-schema-sharing-profile-permissions">
<title>Sharing profile permissions</title>
<indexterm>
<primary><classname>guacamole_sharing_profile_permission</classname></primary>
</indexterm>
<para>Sharing profile permissions are defined by entries in the
<classname>guacamole_sharing_profile_permission</classname> table. Each
entry grants permission for a specific user to perform a specific operation on
an existing sharing profile.</para>
<para>The <classname>guacamole_sharing_profile_permission</classname> table contains
the following columns:</para>
<variablelist>
<varlistentry>
<term><property>user_id</property></term>
<listitem>
<para>The value of the <property>user_id</property> column of the entry
associated with the user owning this permission.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><property>sharing_profile_id</property></term>
<listitem>
<para>The value of the <property>sharing_profile_id</property> column of
the entry associated with the sharing profile affected by this
permission. This is the sharing profile that would be the object of
the operation represented by this permission.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><property>permission</property></term>
<listitem>
<para>The permission being granted. This column can have one of four
possible values: <constant>ADMINISTER</constant>, which grants the
ability to add or remove permissions which affect the sharing
profile, <constant>READ</constant>, which grants the ability to read
data associated with the sharing profile (a prerequisite for using
the sharing profile to share an active connection),
<constant>UPDATE</constant>, which grants the ability to update
data associated with the sharing profile, or
<constant>DELETE</constant>, which grants the ability to delete
the sharing profile.</para>
</listitem>
</varlistentry>
</variablelist>
</section>
<section xml:id="jdbc-auth-schema-connection-group-permissions">
<title>Connection group permissions</title>
<indexterm>
<primary><classname>guacamole_connection_group_permission</classname></primary>
</indexterm>
<para>Connection group permissions are defined by entries in the
<classname>guacamole_connection_group_permission</classname> table. Each
entry grants permission for a specific user to perform a specific operation on
an existing connection group.</para>
<para>The <classname>guacamole_connection_group_permission</classname> table
contains the following columns:</para>
<variablelist>
<varlistentry>
<term><property>user_id</property></term>
<listitem>
<para>The value of the <property>user_id</property> column of the entry
associated with the user owning this permission.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><property>connection_group_id</property></term>
<listitem>
<para>The value of the <property>connection_group_id</property> column
of the entry associated with the connection group affected by this
permission. This is the connection group that would be the object of
the operation represented by this permission.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><property>permission</property></term>
<listitem>
<para>The permission being granted. This column can have one of four
possible values: <constant>ADMINISTER</constant>, which grants the
ability to add or remove permissions which affect the connection
group, <constant>READ</constant>, which grants the ability to read
data associated with the connection group,
<constant>UPDATE</constant>, which grants the ability to update
data associated with the connection group, or
<constant>DELETE</constant>, which grants the ability to delete
the connection group (and implicitly its contents).</para>
</listitem>
</varlistentry>
</variablelist>
</section>
</section>
</section>
</chapter>