Merge 1.0.0 changes back to master.
diff --git a/src/chapters/jdbc-auth.xml b/src/chapters/jdbc-auth.xml
index eca6b58..cb33b90 100644
--- a/src/chapters/jdbc-auth.xml
+++ b/src/chapters/jdbc-auth.xml
@@ -169,12 +169,112 @@
             of choice, and also make sure that you obtain the proper licensing for the version
             and edition of SQL Server you are running.</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>
+            "guacamole_db", but the database can be named whatever you like.</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> <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>
+        </section>
+        <section xml:id="jdbc-auth-postgresql">
+            <title>PostgreSQL</title>
+            <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>
+        </section>
+        <section xml:id="jdbc-auth-sqlserver">
+            <title>SQL Server</title>
+            <informalexample>
+                <screen><prompt>$</prompt> <userinput>/opt/mssql-tools/bin/sqlcmd -S localhost -U SA -d <replaceable>guacamole_db</replaceable> -i schema/001-create-schema.sql</userinput>
+<prompt>Password:</prompt> <userinput><replaceable>password</replaceable></userinput>
+<computeroutput>Rule bound to data type.
+The new rule has been bound to column(s) of the specified user data type.
+Rule bound to data type.
+The new rule has been bound to column(s) of the specified user data type.</computeroutput>
+<prompt>$</prompt> <userinput>/opt/mssql-tools/bin/sqlcmd -S localhost -U SA -d <replaceable>guacamole_db</replaceable> -i schema/002-create-admin-user.sql</userinput>
+<prompt>Password:</prompt> <userinput><replaceable>password</replaceable></userinput>
+<computeroutput>
+(1 rows affected)
+
+(3 rows affected)
+                        
+(5 rows affected)</computeroutput>
+</screen>
+            </informalexample>
+        </section>
+    </section>
+    <section>
+        <title>Upgrading an existing Guacamole database</title>
+        <para>If you are upgrading from an older version of Guacamole, 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>
+        <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>
+        <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.13-incubating to version 1.0.0, you would need to run the
+                <filename>upgrade-pre-0.9.14.sql</filename> script (because 0.9.13-incubating is
+            older than 0.9.14), followed by the <filename>upgrade-pre-1.0.0.sql</filename> script
+            (because 0.9.13-incubating is also older than 1.0.0).</para>
+        <important xml:id="jdbc-auth-postgresql-upgrade">
+            <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>
+        </important>
+    </section>
+    <section>
+        <title>Granting Guacamole access to the database</title>
+        <para>For Guacamole to be able to execute queries against the database, you must create a
+            new user for the database and grant that user sufficient privileges to manage the
+            contents of all tables in the database. The user created for Guacamole needs only
+                <code>SELECT</code>, <code>UPDATE</code>, <code>INSERT</code>, and
+                <code>DELETE</code> permissions on all Guacamole tables. Additionally, if using
+            PostgreSQL, the user will need <code>SELECT</code> and <code>USAGE</code> permission on
+            all sequences within all Guacamole tables. <emphasis>No other permissions should be
+                granted.</emphasis></para>
+        <para>These instructions will refer to the user as "guacamole_user" but the 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>
+            <title>MySQL</title>
             <informalexample>
                 <screen><prompt>$</prompt> mysql -u root -p
 <prompt>Enter password:</prompt> <userinput><replaceable>password</replaceable></userinput>
@@ -206,72 +306,9 @@
 <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>
-                <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 to version 0.9.13-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">
+        <section>
             <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)
@@ -286,66 +323,9 @@
 <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>
-                <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 to version 0.9.13-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 xml:id="jdbc-auth-sqlserver">
+        <section>
             <title>SQL Server</title>
-            <para>If using SQL Server, the database and schema must be created first.  The example below assumes
-                that you are running SQL Server on Linux, using the command-line tools to manage it, however, this
-                code can be run using any tool capable of running SQL against a SQL Server database.</para>
             <informalexample>
                 <screen><prompt>$</prompt> <userinput>/opt/mssql-tools/bin/sqlcmd -S localhost -U SA</userinput>
 <prompt>Password:</prompt> <userinput><replaceable>password</replaceable></userinput>
@@ -361,28 +341,6 @@
 <prompt>2></prompt> <userinput>ALTER ROLE db_datareader ADD MEMBER <replaceable>guacamole_user</replaceable>;</userinput>
 <prompt>3></prompt> <userinput>GO</userinput></screen>
             </informalexample>
-            <para>Once the database and user account is created, and the user associated with the database, you can use
-                the supplied scripts to load the schema into the database.  These scripts are included in the
-                <filename>sqlserver/schema/</filename> directory of the archive you downloaded from the Guacamole
-                web site.</para>
-            <informalexample>
-                <screen><prompt>$</prompt> <userinput>/opt/mssql-tools/bin/sqlcmd -S localhost -U <replaceable>guacamole_user</replaceable> -d <replaceable>guacamole_db</replaceable> -i schema/001-create-schema.sql</userinput>
-<prompt>Password:</prompt> <userinput><replaceable>some_password</replaceable></userinput>
-<computeroutput>Rule bound to data type.
-The new rule has been bound to column(s) of the specified user data type.
-Rule bound to data type.
-The new rule has been bound to column(s) of the specified user data type.</computeroutput>
-<prompt>$</prompt> <userinput>/opt/mssql-tools/bin/sqlcmd -S localhost -U <replaceable>guacamole_user</replaceable> -d <replaceable>guacamole_db</replaceable> -i schema/002-create-admin-user.sql</userinput>
-<prompt>Password:</prompt> <userinput><replaceable>some_password</replaceable></userinput>
-<computeroutput>
-(1 rows affected)
-
-(3 rows affected)
-                        
-(5 rows affected)</computeroutput></screen>
-            </informalexample>
-            <para>If the operation is successful, the tables and permissions have been created successfully, and you
-                can now use the database with the Guacamole client web application.</para>
         </section>
     </section>
     <section xml:id="jdbc-auth-installation">
@@ -543,13 +501,13 @@
                         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>With respect to password content, the database authentication defines a
+                        "digit" as any numeric character and a "symbol" is any non-alphanumeric
+                        character. This takes non-English languages into account, thus a digit is
+                        not simply "0" through "9" but rather <link
+                            xlink:href="https://en.wikipedia.org/wiki/Numerals_in_Unicode">any
+                            character defined in Unicode as numeric</link>, and a symbol is 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
@@ -591,17 +549,17 @@
                                 (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>
+                        passwords until the history is exhausted and their old password is usable
+                        again).</para>
+                    <para>By default, the database authentication does not apply any limits to
+                        password age, and users with permission to change their passwords may do so
+                        as frequently or infrequently as they wish. Password age limits can be
+                        enabled using a pair of properties, each accepting values given in units of
+                        days:</para>
                     <informalexample>
                         <programlisting># MySQL
 mysql-user-password-min-age: <replaceable>7</replaceable>
@@ -615,6 +573,12 @@
 sqlserver-user-password-min-age: <replaceable>7</replaceable>
 sqlserver-user-password-max-age: <replaceable>90</replaceable></programlisting>
                     </informalexample>
+                    <important>
+                        <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>
+                    </important>
                 </section>
                 <section>
                     <title>Preventing password reuse</title>
@@ -779,15 +743,72 @@
         <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-entities">
+            <title>Entities</title>
+            <indexterm>
+                <primary><classname>guacamole_entity</classname></primary>
+            </indexterm>
+            <para>Every user and user group has a corresponding entry in the
+                    <classname>guacamole_entity</classname> table which serves as the basis for
+                assignment of a unique name, permissions, as well as relations which are common to
+                both users and groups like group membership. Each entity has a corresponding name
+                which is unique across all other entities of the same type.</para>
+            <para>If deleting a user or user group, the corresponding entity should also be deleted.
+                As any user or group which points to the entity will be deleted automatically when
+                the entity is deleted through cascading deletion, <emphasis>it is advisable to use
+                    the entity as the basis for any delete operation</emphasis>.</para>
+            <para>The <classname>guacamole_entity</classname> table contains the following
+                columns:</para>
+            <variablelist>
+                <varlistentry>
+                    <term><property>entity_id</property></term>
+                    <listitem>
+                        <para>The unique integer associated with each entity (user or user group).
+                            This value is generated automatically when a new entry is inserted into
+                            the <classname>guacamole_entity</classname> table and is distinct from
+                            the unique integer associated with the user entry in <link
+                                linkend="jdbc-auth-schema-users"
+                                    ><classname>guacamole_user</classname></link> or the user group
+                            entry in <link linkend="jdbc-auth-schema-groups"
+                                    ><classname>guacamole_user_group</classname></link>.</para>
+                    </listitem>
+                </varlistentry>
+                <varlistentry>
+                    <term><property>name</property></term>
+                    <listitem>
+                        <para>The unique name associated with each user or group. This value must be
+                            specified manually, and must be different from any existing user or
+                            group in the table. The name need only be unique relative to the names
+                            of other entities having the same type (a user may have the same name as
+                            a group).</para>
+                    </listitem>
+                </varlistentry>
+                <varlistentry>
+                    <term><property>type</property></term>
+                    <listitem>
+                        <para>The type of this entity. This can be either <type>USER</type> or
+                                <type>USER_GROUP</type>.</para>
+                    </listitem>
+                </varlistentry>
+            </variablelist>
+        </section>
         <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>
+                and <link linkend="jdbc-auth-schema-entities"
+                        ><classname>guacamole_entity</classname></link> tables. Each user has a
+                corresponding unique username, specified via
+                <classname>guacamole_entity</classname>, 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>If deleting a user, the <link linkend="jdbc-auth-schema-entities">corresponding
+                    entity</link> should also be deleted. As any user which points to the entity
+                will be deleted automatically when the entity is deleted through cascading deletion,
+                    <emphasis>it is advisable to use the entity as the basis for any delete
+                    operation</emphasis>.</para>
             <para>The <classname>guacamole_user</classname> table contains the following
                 columns:</para>
             <variablelist>
@@ -800,13 +821,11 @@
                     </listitem>
                 </varlistentry>
                 <varlistentry>
-                    <term><property>username</property></term>
+                    <term><property>entity_id</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>
+                        <para>The value of the <property>entity_id</property> column of the
+                                <classname>guacamole_entity</classname> entry representing this
+                            user.</para>
                     </listitem>
                 </varlistentry>
                 <varlistentry>
@@ -918,9 +937,8 @@
                                 <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
+                                    ><methodname>getAvailableIDs()</methodname></link>, though the
+                            Guacamole management interface will only present a subset of these time
                             zones.</para>
                     </listitem>
                 </varlistentry>
@@ -984,9 +1002,26 @@
                 <programlisting>-- Generate salt
 SET @salt = UNHEX(SHA2(UUID(), 256));
 
+-- Create base entity entry for user
+INSERT INTO guacamole_entity (name, type)
+VALUES ('<replaceable>myuser</replaceable>', 'USER');
+
 -- 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>
+INSERT INTO guacamole_user (
+    entity_id,
+    password_salt,
+    password_hash,
+    password_date
+)
+SELECT
+    entity_id,
+    @salt,
+    UNHEX(SHA2(CONCAT('<replaceable>mypassword</replaceable>', HEX(@salt)), 256)),
+    CURRENT_TIMESTAMP
+FROM guacamole_entity
+WHERE
+    name = '<replaceable>myuser</replaceable>'
+    AND type = 'USER';</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>
@@ -1133,6 +1168,81 @@
                 </variablelist>
             </section>
         </section>
+        <section xml:id="jdbc-auth-schema-groups">
+            <title>User groups</title>
+            <indexterm>
+                <primary><classname>guacamole_user_group</classname></primary>
+            </indexterm>
+            <para>Similar to <link linkend="jdbc-auth-schema-users">users</link>, every user group
+                has a corresponding entry in the <classname>guacamole_user_group</classname> and
+                    <link linkend="jdbc-auth-schema-entities"
+                        ><classname>guacamole_entity</classname></link> tables. Each user group has
+                a corresponding unique name specified via
+                <classname>guacamole_entity</classname>.</para>
+            <para>If deleting a user group, the <link linkend="jdbc-auth-schema-entities"
+                    >corresponding entity</link> should also be deleted. As any user group which
+                points to the entity will be deleted automatically when the entity is deleted
+                through cascading deletion, <emphasis>it is advisable to use the entity as the basis
+                    for any delete operation</emphasis>.</para>
+            <para>The <classname>guacamole_user_group</classname> table contains the following
+                columns:</para>
+            <variablelist>
+                <varlistentry>
+                    <term><property>user_group_id</property></term>
+                    <listitem>
+                        <para>The unique integer associated with each user group. This value is
+                            generated automatically when a new entry is inserted into the
+                                <classname>guacamole_user_group</classname> table.</para>
+                    </listitem>
+                </varlistentry>
+                <varlistentry>
+                    <term><property>entity_id</property></term>
+                    <listitem>
+                        <para>The value of the <property>entity_id</property> column of the
+                                <classname>guacamole_entity</classname> entry representing this user
+                            group.</para>
+                    </listitem>
+                </varlistentry>
+                <varlistentry>
+                    <term><property>disabled</property></term>
+                    <listitem>
+                        <para>Whether membership within this group should be taken into account when
+                            determining the permissions granted to a particular user. If this column
+                            is set to <constant>TRUE</constant> or <constant>1</constant>,
+                            membership in this group will have no effect on user permissions,
+                            whether those permissions are granted to this group directly or
+                            indirectly through the groups that this group is a member of. By
+                            default, user groups are not disabled, and permissions granted to a user
+                            through the group will be taken into account.</para>
+                    </listitem>
+                </varlistentry>
+            </variablelist>
+            <indexterm>
+                <primary><classname>guacamole_user_group_member</classname></primary>
+            </indexterm>
+            <para>Membership within a user group is dictated through entries in the
+                    <classname>guacamole_user_group_member</classname> table. As both users and user
+                groups may be members of groups, each entry associates the containing group with the
+                entity of the member.</para>
+            <para>The <classname>guacamole_user_group_member</classname> table contains the
+                following columns:</para>
+            <variablelist>
+                <varlistentry>
+                    <term><property>user_group_id</property></term>
+                    <listitem>
+                        <para>The <property>user_group_id</property> value of the user group having
+                            the specified member.</para>
+                    </listitem>
+                </varlistentry>
+                <varlistentry>
+                    <term><property>member_entity_id</property></term>
+                    <listitem>
+                        <para>The <property>entity_id</property> value of the user or user group
+                            that is a member of the specified group.</para>
+                    </listitem>
+                </varlistentry>
+            </variablelist>
+        </section>
         <section xml:id="jdbc-auth-schema-connections">
             <title>Connections and parameters</title>
             <indexterm>
@@ -1590,41 +1700,46 @@
         </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>
+            <para>There are several permissions tables in the schema which correspond to the types
+                of permissions in Guacamole's authentication model: system permissions, which
+                control operations that affect the system as a whole, and permissions which control
+                operations that affect specific objects within the system, such as users,
+                connections, or groups.</para>
             <section xml:id="jdbc-auth-schema-system-permissions">
-                <title>System permissions</title>
+                <title>lSystem 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>
+                    permission for a specific user or user group 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>
+                        <term><property>entity_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>
+                            <para>The value of the <property>entity_id</property> column of the
+                                entry associated with the user or user group 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
+                            <para>The permission being granted. This column can have one of six
                                 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>
+                                ability to create connections groups,
+                                    <constant>CREATE_SHARING_PROFILE</constant>, which grants the
+                                ability to create sharing profiles,
+                                <constant>CREATE_USER</constant>, which grants the ability to create
+                                users, or <constant>CREATE_USER_GROUP</constant>, which grants the
+                                ability to create user groups.</para>
                         </listitem>
                     </varlistentry>
                 </variablelist>
@@ -1636,16 +1751,17 @@
                 </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>
+                    permission for a specific user or user group to perform a specific operation on
+                    an existing user.</para>
                 <para>The <classname>guacamole_user_permission</classname> table contains the
                     following columns:</para>
                 <variablelist>
                     <varlistentry>
-                        <term><property>user_id</property></term>
+                        <term><property>entity_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>
+                            <para>The value of the <property>entity_id</property> column of the
+                                entry associated with the user or user group owning this
+                                permission.</para>
                         </listitem>
                     </varlistentry>
                     <varlistentry>
@@ -1672,6 +1788,50 @@
                     </varlistentry>
                 </variablelist>
             </section>
+            <section xml:id="jdbc-auth-schema-group-permissions">
+                <title>User group permissions</title>
+                <indexterm>
+                    <primary><classname>guacamole_user_group_permission</classname></primary>
+                </indexterm>
+                <para>User group permissions are defined by entries in the
+                        <classname>guacamole_user_group_permission</classname> table. Each entry
+                    grants permission for a specific user or user group to perform a specific
+                    operation on an existing user group.</para>
+                <para>The <classname>guacamole_user_group_permission</classname> table contains the
+                    following columns:</para>
+                <variablelist>
+                    <varlistentry>
+                        <term><property>entity_id</property></term>
+                        <listitem>
+                            <para>The value of the <property>entity_id</property> column of the
+                                entry associated with the user or user group owning this
+                                permission.</para>
+                        </listitem>
+                    </varlistentry>
+                    <varlistentry>
+                        <term><property>affected_user_group_id</property></term>
+                        <listitem>
+                            <para>The value of the <property>user_group_id</property> column of the
+                                entry associated with the user group <emphasis>affected</emphasis>
+                                by this permission. This is the user 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 user group,
+                                    <constant>READ</constant>, which grants the ability to read data
+                                associated with the user group, <constant>UPDATE</constant>, which
+                                grants the ability to update data associated with the user group, or
+                                    <constant>DELETE</constant>, which grants the ability to delete
+                                the user group.</para>
+                        </listitem>
+                    </varlistentry>
+                </variablelist>
+            </section>
             <section xml:id="jdbc-auth-schema-connection-permissions">
                 <title>Connection permissions</title>
                 <indexterm>
@@ -1679,16 +1839,17 @@
                 </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>
+                    grants permission for a specific user or user group 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>
+                        <term><property>entity_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>
+                            <para>The value of the <property>entity_id</property> column of the
+                                entry associated with the user or user group owning this
+                                permission.</para>
                         </listitem>
                     </varlistentry>
                     <varlistentry>
@@ -1722,16 +1883,17 @@
                 </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>
+                    entry grants permission for a specific user or user group 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>
+                        <term><property>entity_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>
+                            <para>The value of the <property>entity_id</property> column of the
+                                entry associated with the user or user group owning this
+                                permission.</para>
                         </listitem>
                     </varlistentry>
                     <varlistentry>
@@ -1767,16 +1929,17 @@
                 </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>
+                    entry grants permission for a specific user or user group 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>
+                        <term><property>entity_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>
+                            <para>The value of the <property>entity_id</property> column of the
+                                entry associated with the user or user group owning this
+                                permission.</para>
                         </listitem>
                     </varlistentry>
                     <varlistentry>