up
This commit is contained in:
2025-09-14 23:13:06 +07:00
parent ee892854a6
commit 9690ed5634
80 changed files with 8417 additions and 0 deletions

View File

@@ -0,0 +1,357 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
==============================================================================
APACHE GUACAMOLE SUBCOMPONENTS
Apache Guacamole includes a number of subcomponents with separate copyright
notices and license terms. Your use of these subcomponents is subject to the
terms and conditions of the following licenses.
AOP Alliance (http://aopalliance.sourceforge.net/)
--------------------------------------------------
Version: 1.0
From: 'AOP Alliance' (http://aopalliance.sourceforge.net/members.html)
License(s):
Public Domain (bundled/aopalliance-1.0/LICENSE)
From http://aopalliance.sourceforge.net/:
LICENCE: all the source code provided by AOP Alliance is Public Domain.
Checker Framework qualifiers (https://checkerframework.org/)
------------------------------------------------------------
Version: 3.37.0
From: 'Checker Framework developers' (https://checkerframework.org/)
License(s):
MIT (bundled/checker-qual-3.37.0/LICENSE.txt)
Checker Framework qualifiers
Copyright 2004-present by the Checker Framework developers
MIT License:
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
Error Prone (https://errorprone.info/)
--------------------------------------
Version: 2.21.1
From: 'Google Inc.' (http://www.google.com/)
License(s):
Apache v2.0
Google Guice (https://github.com/google/guice)
----------------------------------------------
Version: 5.1.0
From: 'Google Inc.' (http://www.google.com/)
License(s):
Apache v2.0
Guava: Google Core Libraries for Java (https://github.com/google/guava)
-----------------------------------------------------------------------
Version: 32.1.3-jre
From: 'Google Inc.' (http://www.google.com/)
License(s):
Apache v2.0
Java to Objective-C Annotations (https://github.com/google/j2objc)
------------------------------------------------------------------
Version: 2.8
From: 'Google Inc.' (http://www.google.com/)
License(s):
Apache v2.0
JSR-305 Reference Implementation (http://code.google.com/p/jsr-305/)
--------------------------------------------------------------------
Version: 3.0.2 (originally 0.1-SNAPSHOT, redistributed by FindBugs 3.0.2)
From: 'JSR305 expert group' (https://code.google.com/archive/p/jsr-305/)
License(s):
BSD 3-clause (bundled/findbugs-jsr305-3.0.2/LICENSE)
Copyright (c) 2007-2009, JSR305 expert group
All rights reserved.
http://www.opensource.org/licenses/bsd-license.php
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
* Neither the name of the JSR305 expert group nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
JSR-330 / Dependency Injection for Java (http://code.google.com/p/atinject/)
----------------------------------------------------------------------------
Version: 1
From: 'JSR-330 Expert Group' (https://jcp.org/en/jsr/detail?id=330)
License(s):
Apache v2.0
MyBatis (http://www.mybatis.org/mybatis-3/)
-------------------------------------------
Version: 3.5.14
From: 'MyBatis' (http://www.mybatis.org/)
License(s):
Apache v2.0
MyBatis-Guice (http://www.mybatis.org/guice/)
---------------------------------------------
Version: 3.18
From: 'MyBatis' (http://www.mybatis.org/)
License(s):
Apache v2.0

View File

@@ -0,0 +1,69 @@
Apache Guacamole
Copyright 2020 The Apache Software Foundation
This product includes software developed at
The Apache Software Foundation (https://www.apache.org/).
======== NOTICE for "MyBatis" ========
iBATIS
This product includes software developed by
The Apache Software Foundation (http://www.apache.org/).
Copyright 2010 The Apache Software Foundation
OGNL
//--------------------------------------------------------------------------
// Copyright (c) 2004, Drew Davidson and Luke Blanshard
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
// Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
// Neither the name of the Drew Davidson nor the names of its contributors
// may be used to endorse or promote products derived from this software
// without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
// OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
// AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
// DAMAGE.
//--------------------------------------------------------------------------
Refactored SqlBuilder class (SQL, AbstractSQL)
This product includes software developed by
Adam Gent (https://gist.github.com/3650165)
Copyright 2010 Adam Gent
======== NOTICE for "MyBatis-Guice" ========
MyBatis-Guice
Copyright 2010-2013
This product includes software developed by
The MyBatis Team (http://www.mybatis.org/).
iBATIS
This product includes software developed by
The Apache Software Foundation (http://www.apache.org/).
Copyright 2010 The Apache Software Foundation
Google Guice
Copyright 2010 The Apache Software Foundation

View File

@@ -0,0 +1,4 @@
Apache Guacamole includes a number of subcomponents with separate copyright
notices and license terms. Your use of these subcomponents is subject to the
terms and conditions of their respective licenses, included within this
directory for reference.

View File

@@ -0,0 +1,4 @@
From http://aopalliance.sourceforge.net/:
LICENCE: all the source code provided by AOP Alliance is Public Domain.

View File

@@ -0,0 +1,22 @@
Checker Framework qualifiers
Copyright 2004-present by the Checker Framework developers
MIT License:
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

View File

@@ -0,0 +1,28 @@
Copyright (c) 2007-2009, JSR305 expert group
All rights reserved.
http://www.opensource.org/licenses/bsd-license.php
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
* Neither the name of the JSR305 expert group nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.

View File

@@ -0,0 +1,45 @@
iBATIS
This product includes software developed by
The Apache Software Foundation (http://www.apache.org/).
Copyright 2010 The Apache Software Foundation
OGNL
//--------------------------------------------------------------------------
// Copyright (c) 2004, Drew Davidson and Luke Blanshard
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
// Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
// Neither the name of the Drew Davidson nor the names of its contributors
// may be used to endorse or promote products derived from this software
// without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
// OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
// AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
// DAMAGE.
//--------------------------------------------------------------------------
Refactored SqlBuilder class (SQL, AbstractSQL)
This product includes software developed by
Adam Gent (https://gist.github.com/3650165)
Copyright 2010 Adam Gent

View File

@@ -0,0 +1,15 @@
MyBatis-Guice
Copyright 2010-2013
This product includes software developed by
The MyBatis Team (http://www.mybatis.org/).
iBATIS
This product includes software developed by
The Apache Software Foundation (http://www.apache.org/).
Copyright 2010 The Apache Software Foundation
Google Guice
Copyright 2010 The Apache Software Foundation

View File

@@ -0,0 +1,613 @@
--
-- Licensed to the Apache Software Foundation (ASF) under one
-- or more contributor license agreements. See the NOTICE file
-- distributed with this work for additional information
-- regarding copyright ownership. The ASF licenses this file
-- to you under the Apache License, Version 2.0 (the
-- "License"); you may not use this file except in compliance
-- with the License. You may obtain a copy of the License at
--
-- http://www.apache.org/licenses/LICENSE-2.0
--
-- Unless required by applicable law or agreed to in writing,
-- software distributed under the License is distributed on an
-- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-- KIND, either express or implied. See the License for the
-- specific language governing permissions and limitations
-- under the License.
--
--
-- Table of connection groups. Each connection group has a name.
--
CREATE TABLE `guacamole_connection_group` (
`connection_group_id` int(11) NOT NULL AUTO_INCREMENT,
`parent_id` int(11),
`connection_group_name` varchar(128) NOT NULL,
`type` enum('ORGANIZATIONAL',
'BALANCING') NOT NULL DEFAULT 'ORGANIZATIONAL',
-- Concurrency limits
`max_connections` int(11),
`max_connections_per_user` int(11),
`enable_session_affinity` boolean NOT NULL DEFAULT 0,
PRIMARY KEY (`connection_group_id`),
UNIQUE KEY `connection_group_name_parent` (`connection_group_name`, `parent_id`),
CONSTRAINT `guacamole_connection_group_ibfk_1`
FOREIGN KEY (`parent_id`)
REFERENCES `guacamole_connection_group` (`connection_group_id`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
--
-- Table of connections. Each connection has a name, protocol, and
-- associated set of parameters.
-- A connection may belong to a connection group.
--
CREATE TABLE `guacamole_connection` (
`connection_id` int(11) NOT NULL AUTO_INCREMENT,
`connection_name` varchar(128) NOT NULL,
`parent_id` int(11),
`protocol` varchar(32) NOT NULL,
-- Guacamole proxy (guacd) overrides
`proxy_port` integer,
`proxy_hostname` varchar(512),
`proxy_encryption_method` enum('NONE', 'SSL'),
-- Concurrency limits
`max_connections` int(11),
`max_connections_per_user` int(11),
-- Load-balancing behavior
`connection_weight` int(11),
`failover_only` boolean NOT NULL DEFAULT 0,
PRIMARY KEY (`connection_id`),
UNIQUE KEY `connection_name_parent` (`connection_name`, `parent_id`),
CONSTRAINT `guacamole_connection_ibfk_1`
FOREIGN KEY (`parent_id`)
REFERENCES `guacamole_connection_group` (`connection_group_id`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
--
-- Table of base entities which may each be either a user or user group. Other
-- tables which represent qualities shared by both users and groups will point
-- to guacamole_entity, while tables which represent qualities specific to
-- users or groups will point to guacamole_user or guacamole_user_group.
--
CREATE TABLE `guacamole_entity` (
`entity_id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(128) NOT NULL,
`type` enum('USER',
'USER_GROUP') NOT NULL,
PRIMARY KEY (`entity_id`),
UNIQUE KEY `guacamole_entity_name_scope` (`type`, `name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
--
-- Table of users. Each user has a unique username and a hashed password
-- with corresponding salt. Although the authentication system will always set
-- salted passwords, other systems may set unsalted passwords by simply not
-- providing the salt.
--
CREATE TABLE `guacamole_user` (
`user_id` int(11) NOT NULL AUTO_INCREMENT,
`entity_id` int(11) NOT NULL,
-- Optionally-salted password
`password_hash` binary(32) NOT NULL,
`password_salt` binary(32),
`password_date` datetime NOT NULL,
-- Account disabled/expired status
`disabled` boolean NOT NULL DEFAULT 0,
`expired` boolean NOT NULL DEFAULT 0,
-- Time-based access restriction
`access_window_start` TIME,
`access_window_end` TIME,
-- Date-based access restriction
`valid_from` DATE,
`valid_until` DATE,
-- Timezone used for all date/time comparisons and interpretation
`timezone` VARCHAR(64),
-- Profile information
`full_name` VARCHAR(256),
`email_address` VARCHAR(256),
`organization` VARCHAR(256),
`organizational_role` VARCHAR(256),
PRIMARY KEY (`user_id`),
UNIQUE KEY `guacamole_user_single_entity` (`entity_id`),
CONSTRAINT `guacamole_user_entity`
FOREIGN KEY (`entity_id`)
REFERENCES `guacamole_entity` (`entity_id`)
ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
--
-- Table of user groups. Each user group may have an arbitrary set of member
-- users and member groups, with those members inheriting the permissions
-- granted to that group.
--
CREATE TABLE `guacamole_user_group` (
`user_group_id` int(11) NOT NULL AUTO_INCREMENT,
`entity_id` int(11) NOT NULL,
-- Group disabled status
`disabled` boolean NOT NULL DEFAULT 0,
PRIMARY KEY (`user_group_id`),
UNIQUE KEY `guacamole_user_group_single_entity` (`entity_id`),
CONSTRAINT `guacamole_user_group_entity`
FOREIGN KEY (`entity_id`)
REFERENCES `guacamole_entity` (`entity_id`)
ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
--
-- Table of users which are members of given user groups.
--
CREATE TABLE `guacamole_user_group_member` (
`user_group_id` int(11) NOT NULL,
`member_entity_id` int(11) NOT NULL,
PRIMARY KEY (`user_group_id`, `member_entity_id`),
-- Parent must be a user group
CONSTRAINT `guacamole_user_group_member_parent_id`
FOREIGN KEY (`user_group_id`)
REFERENCES `guacamole_user_group` (`user_group_id`) ON DELETE CASCADE,
-- Member may be either a user or a user group (any entity)
CONSTRAINT `guacamole_user_group_member_entity_id`
FOREIGN KEY (`member_entity_id`)
REFERENCES `guacamole_entity` (`entity_id`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
--
-- Table of sharing profiles. Each sharing profile has a name, associated set
-- of parameters, and a primary connection. The primary connection is the
-- connection that the sharing profile shares, and the parameters dictate the
-- restrictions/features which apply to the user joining the connection via the
-- sharing profile.
--
CREATE TABLE guacamole_sharing_profile (
`sharing_profile_id` int(11) NOT NULL AUTO_INCREMENT,
`sharing_profile_name` varchar(128) NOT NULL,
`primary_connection_id` int(11) NOT NULL,
PRIMARY KEY (`sharing_profile_id`),
UNIQUE KEY `sharing_profile_name_primary` (sharing_profile_name, primary_connection_id),
CONSTRAINT `guacamole_sharing_profile_ibfk_1`
FOREIGN KEY (`primary_connection_id`)
REFERENCES `guacamole_connection` (`connection_id`)
ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
--
-- Table of connection parameters. Each parameter is simply a name/value pair
-- associated with a connection.
--
CREATE TABLE `guacamole_connection_parameter` (
`connection_id` int(11) NOT NULL,
`parameter_name` varchar(128) NOT NULL,
`parameter_value` varchar(4096) NOT NULL,
PRIMARY KEY (`connection_id`,`parameter_name`),
CONSTRAINT `guacamole_connection_parameter_ibfk_1`
FOREIGN KEY (`connection_id`)
REFERENCES `guacamole_connection` (`connection_id`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
--
-- Table of sharing profile parameters. Each parameter is simply
-- name/value pair associated with a sharing profile. These parameters dictate
-- the restrictions/features which apply to the user joining the associated
-- connection via the sharing profile.
--
CREATE TABLE guacamole_sharing_profile_parameter (
`sharing_profile_id` integer NOT NULL,
`parameter_name` varchar(128) NOT NULL,
`parameter_value` varchar(4096) NOT NULL,
PRIMARY KEY (`sharing_profile_id`, `parameter_name`),
CONSTRAINT `guacamole_sharing_profile_parameter_ibfk_1`
FOREIGN KEY (`sharing_profile_id`)
REFERENCES `guacamole_sharing_profile` (`sharing_profile_id`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
--
-- Table of arbitrary user attributes. Each attribute is simply a name/value
-- pair associated with a user. Arbitrary attributes are defined by other
-- extensions. Attributes defined by this extension will be mapped to
-- properly-typed columns of a specific table.
--
CREATE TABLE guacamole_user_attribute (
`user_id` int(11) NOT NULL,
`attribute_name` varchar(128) NOT NULL,
`attribute_value` varchar(4096) NOT NULL,
PRIMARY KEY (user_id, attribute_name),
KEY `user_id` (`user_id`),
CONSTRAINT guacamole_user_attribute_ibfk_1
FOREIGN KEY (user_id)
REFERENCES guacamole_user (user_id) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
--
-- Table of arbitrary user group attributes. Each attribute is simply a
-- name/value pair associated with a user group. Arbitrary attributes are
-- defined by other extensions. Attributes defined by this extension will be
-- mapped to properly-typed columns of a specific table.
--
CREATE TABLE guacamole_user_group_attribute (
`user_group_id` int(11) NOT NULL,
`attribute_name` varchar(128) NOT NULL,
`attribute_value` varchar(4096) NOT NULL,
PRIMARY KEY (`user_group_id`, `attribute_name`),
KEY `user_group_id` (`user_group_id`),
CONSTRAINT `guacamole_user_group_attribute_ibfk_1`
FOREIGN KEY (`user_group_id`)
REFERENCES `guacamole_user_group` (`user_group_id`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
--
-- Table of arbitrary connection attributes. Each attribute is simply a
-- name/value pair associated with a connection. Arbitrary attributes are
-- defined by other extensions. Attributes defined by this extension will be
-- mapped to properly-typed columns of a specific table.
--
CREATE TABLE guacamole_connection_attribute (
`connection_id` int(11) NOT NULL,
`attribute_name` varchar(128) NOT NULL,
`attribute_value` varchar(4096) NOT NULL,
PRIMARY KEY (connection_id, attribute_name),
KEY `connection_id` (`connection_id`),
CONSTRAINT guacamole_connection_attribute_ibfk_1
FOREIGN KEY (connection_id)
REFERENCES guacamole_connection (connection_id) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
--
-- Table of arbitrary connection group attributes. Each attribute is simply a
-- name/value pair associated with a connection group. Arbitrary attributes are
-- defined by other extensions. Attributes defined by this extension will be
-- mapped to properly-typed columns of a specific table.
--
CREATE TABLE guacamole_connection_group_attribute (
`connection_group_id` int(11) NOT NULL,
`attribute_name` varchar(128) NOT NULL,
`attribute_value` varchar(4096) NOT NULL,
PRIMARY KEY (connection_group_id, attribute_name),
KEY `connection_group_id` (`connection_group_id`),
CONSTRAINT guacamole_connection_group_attribute_ibfk_1
FOREIGN KEY (connection_group_id)
REFERENCES guacamole_connection_group (connection_group_id) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
--
-- Table of arbitrary sharing profile attributes. Each attribute is simply a
-- name/value pair associated with a sharing profile. Arbitrary attributes are
-- defined by other extensions. Attributes defined by this extension will be
-- mapped to properly-typed columns of a specific table.
--
CREATE TABLE guacamole_sharing_profile_attribute (
`sharing_profile_id` int(11) NOT NULL,
`attribute_name` varchar(128) NOT NULL,
`attribute_value` varchar(4096) NOT NULL,
PRIMARY KEY (sharing_profile_id, attribute_name),
KEY `sharing_profile_id` (`sharing_profile_id`),
CONSTRAINT guacamole_sharing_profile_attribute_ibfk_1
FOREIGN KEY (sharing_profile_id)
REFERENCES guacamole_sharing_profile (sharing_profile_id) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
--
-- Table of connection permissions. Each connection permission grants a user or
-- user group specific access to a connection.
--
CREATE TABLE `guacamole_connection_permission` (
`entity_id` int(11) NOT NULL,
`connection_id` int(11) NOT NULL,
`permission` enum('READ',
'UPDATE',
'DELETE',
'ADMINISTER') NOT NULL,
PRIMARY KEY (`entity_id`,`connection_id`,`permission`),
CONSTRAINT `guacamole_connection_permission_ibfk_1`
FOREIGN KEY (`connection_id`)
REFERENCES `guacamole_connection` (`connection_id`) ON DELETE CASCADE,
CONSTRAINT `guacamole_connection_permission_entity`
FOREIGN KEY (`entity_id`)
REFERENCES `guacamole_entity` (`entity_id`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
--
-- Table of connection group permissions. Each group permission grants a user
-- or user group specific access to a connection group.
--
CREATE TABLE `guacamole_connection_group_permission` (
`entity_id` int(11) NOT NULL,
`connection_group_id` int(11) NOT NULL,
`permission` enum('READ',
'UPDATE',
'DELETE',
'ADMINISTER') NOT NULL,
PRIMARY KEY (`entity_id`,`connection_group_id`,`permission`),
CONSTRAINT `guacamole_connection_group_permission_ibfk_1`
FOREIGN KEY (`connection_group_id`)
REFERENCES `guacamole_connection_group` (`connection_group_id`) ON DELETE CASCADE,
CONSTRAINT `guacamole_connection_group_permission_entity`
FOREIGN KEY (`entity_id`)
REFERENCES `guacamole_entity` (`entity_id`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
--
-- Table of sharing profile permissions. Each sharing profile permission grants
-- a user or user group specific access to a sharing profile.
--
CREATE TABLE guacamole_sharing_profile_permission (
`entity_id` integer NOT NULL,
`sharing_profile_id` integer NOT NULL,
`permission` enum('READ',
'UPDATE',
'DELETE',
'ADMINISTER') NOT NULL,
PRIMARY KEY (`entity_id`, `sharing_profile_id`, `permission`),
CONSTRAINT `guacamole_sharing_profile_permission_ibfk_1`
FOREIGN KEY (`sharing_profile_id`)
REFERENCES `guacamole_sharing_profile` (`sharing_profile_id`) ON DELETE CASCADE,
CONSTRAINT `guacamole_sharing_profile_permission_entity`
FOREIGN KEY (`entity_id`)
REFERENCES `guacamole_entity` (`entity_id`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
--
-- Table of system permissions. Each system permission grants a user or user
-- group a system-level privilege of some kind.
--
CREATE TABLE `guacamole_system_permission` (
`entity_id` int(11) NOT NULL,
`permission` enum('CREATE_CONNECTION',
'CREATE_CONNECTION_GROUP',
'CREATE_SHARING_PROFILE',
'CREATE_USER',
'CREATE_USER_GROUP',
'ADMINISTER') NOT NULL,
PRIMARY KEY (`entity_id`,`permission`),
CONSTRAINT `guacamole_system_permission_entity`
FOREIGN KEY (`entity_id`)
REFERENCES `guacamole_entity` (`entity_id`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
--
-- Table of user permissions. Each user permission grants a user or user group
-- access to another user (the "affected" user) for a specific type of
-- operation.
--
CREATE TABLE `guacamole_user_permission` (
`entity_id` int(11) NOT NULL,
`affected_user_id` int(11) NOT NULL,
`permission` enum('READ',
'UPDATE',
'DELETE',
'ADMINISTER') NOT NULL,
PRIMARY KEY (`entity_id`,`affected_user_id`,`permission`),
CONSTRAINT `guacamole_user_permission_ibfk_1`
FOREIGN KEY (`affected_user_id`)
REFERENCES `guacamole_user` (`user_id`) ON DELETE CASCADE,
CONSTRAINT `guacamole_user_permission_entity`
FOREIGN KEY (`entity_id`)
REFERENCES `guacamole_entity` (`entity_id`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
--
-- Table of user group permissions. Each user group permission grants a user
-- or user group access to a another user group (the "affected" user group) for
-- a specific type of operation.
--
CREATE TABLE `guacamole_user_group_permission` (
`entity_id` int(11) NOT NULL,
`affected_user_group_id` int(11) NOT NULL,
`permission` enum('READ',
'UPDATE',
'DELETE',
'ADMINISTER') NOT NULL,
PRIMARY KEY (`entity_id`, `affected_user_group_id`, `permission`),
CONSTRAINT `guacamole_user_group_permission_affected_user_group`
FOREIGN KEY (`affected_user_group_id`)
REFERENCES `guacamole_user_group` (`user_group_id`) ON DELETE CASCADE,
CONSTRAINT `guacamole_user_group_permission_entity`
FOREIGN KEY (`entity_id`)
REFERENCES `guacamole_entity` (`entity_id`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
--
-- Table of connection history records. Each record defines a specific user's
-- session, including the connection used, the start time, and the end time
-- (if any).
--
CREATE TABLE `guacamole_connection_history` (
`history_id` int(11) NOT NULL AUTO_INCREMENT,
`user_id` int(11) DEFAULT NULL,
`username` varchar(128) NOT NULL,
`remote_host` varchar(256) DEFAULT NULL,
`connection_id` int(11) DEFAULT NULL,
`connection_name` varchar(128) NOT NULL,
`sharing_profile_id` int(11) DEFAULT NULL,
`sharing_profile_name` varchar(128) DEFAULT NULL,
`start_date` datetime NOT NULL,
`end_date` datetime DEFAULT NULL,
PRIMARY KEY (`history_id`),
KEY `user_id` (`user_id`),
KEY `connection_id` (`connection_id`),
KEY `sharing_profile_id` (`sharing_profile_id`),
KEY `start_date` (`start_date`),
KEY `end_date` (`end_date`),
KEY `connection_start_date` (`connection_id`, `start_date`),
CONSTRAINT `guacamole_connection_history_ibfk_1`
FOREIGN KEY (`user_id`)
REFERENCES `guacamole_user` (`user_id`) ON DELETE SET NULL,
CONSTRAINT `guacamole_connection_history_ibfk_2`
FOREIGN KEY (`connection_id`)
REFERENCES `guacamole_connection` (`connection_id`) ON DELETE SET NULL,
CONSTRAINT `guacamole_connection_history_ibfk_3`
FOREIGN KEY (`sharing_profile_id`)
REFERENCES `guacamole_sharing_profile` (`sharing_profile_id`) ON DELETE SET NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
--
-- User login/logout history
--
CREATE TABLE guacamole_user_history (
`history_id` int(11) NOT NULL AUTO_INCREMENT,
`user_id` int(11) DEFAULT NULL,
`username` varchar(128) NOT NULL,
`remote_host` varchar(256) DEFAULT NULL,
`start_date` datetime NOT NULL,
`end_date` datetime DEFAULT NULL,
PRIMARY KEY (history_id),
KEY `user_id` (`user_id`),
KEY `start_date` (`start_date`),
KEY `end_date` (`end_date`),
KEY `user_start_date` (`user_id`, `start_date`),
CONSTRAINT guacamole_user_history_ibfk_1
FOREIGN KEY (user_id)
REFERENCES guacamole_user (user_id) ON DELETE SET NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
--
-- User password history
--
CREATE TABLE guacamole_user_password_history (
`password_history_id` int(11) NOT NULL AUTO_INCREMENT,
`user_id` int(11) NOT NULL,
-- Salted password
`password_hash` binary(32) NOT NULL,
`password_salt` binary(32),
`password_date` datetime NOT NULL,
PRIMARY KEY (`password_history_id`),
KEY `user_id` (`user_id`),
CONSTRAINT `guacamole_user_password_history_ibfk_1`
FOREIGN KEY (`user_id`)
REFERENCES `guacamole_user` (`user_id`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

View File

@@ -0,0 +1,53 @@
--
-- Licensed to the Apache Software Foundation (ASF) under one
-- or more contributor license agreements. See the NOTICE file
-- distributed with this work for additional information
-- regarding copyright ownership. The ASF licenses this file
-- to you under the Apache License, Version 2.0 (the
-- "License"); you may not use this file except in compliance
-- with the License. You may obtain a copy of the License at
--
-- http://www.apache.org/licenses/LICENSE-2.0
--
-- Unless required by applicable law or agreed to in writing,
-- software distributed under the License is distributed on an
-- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-- KIND, either express or implied. See the License for the
-- specific language governing permissions and limitations
-- under the License.
--
-- Create default user "guacadmin" with password "guacadmin"
INSERT INTO guacamole_entity (name, type) VALUES ('guacadmin', 'USER');
INSERT INTO guacamole_user (entity_id, password_hash, password_salt, password_date)
SELECT
entity_id,
x'CA458A7D494E3BE824F5E1E175A1556C0F8EEF2C2D7DF3633BEC4A29C4411960', -- 'guacadmin'
x'FE24ADC5E11E2B25288D1704ABE67A79E342ECC26064CE69C5B3177795A82264',
NOW()
FROM guacamole_entity WHERE name = 'guacadmin';
-- Grant this user all system permissions
INSERT INTO guacamole_system_permission (entity_id, permission)
SELECT entity_id, permission
FROM (
SELECT 'guacadmin' AS username, 'CREATE_CONNECTION' AS permission
UNION SELECT 'guacadmin' AS username, 'CREATE_CONNECTION_GROUP' AS permission
UNION SELECT 'guacadmin' AS username, 'CREATE_SHARING_PROFILE' AS permission
UNION SELECT 'guacadmin' AS username, 'CREATE_USER' AS permission
UNION SELECT 'guacadmin' AS username, 'CREATE_USER_GROUP' AS permission
UNION SELECT 'guacadmin' AS username, 'ADMINISTER' AS permission
) permissions
JOIN guacamole_entity ON permissions.username = guacamole_entity.name AND guacamole_entity.type = 'USER';
-- Grant admin permission to read/update/administer self
INSERT INTO guacamole_user_permission (entity_id, affected_user_id, permission)
SELECT guacamole_entity.entity_id, guacamole_user.user_id, permission
FROM (
SELECT 'guacadmin' AS username, 'guacadmin' AS affected_username, 'READ' AS permission
UNION SELECT 'guacadmin' AS username, 'guacadmin' AS affected_username, 'UPDATE' AS permission
UNION SELECT 'guacadmin' AS username, 'guacadmin' AS affected_username, 'ADMINISTER' AS permission
) permissions
JOIN guacamole_entity ON permissions.username = guacamole_entity.name AND guacamole_entity.type = 'USER'
JOIN guacamole_entity affected ON permissions.affected_username = affected.name AND guacamole_entity.type = 'USER'
JOIN guacamole_user ON guacamole_user.entity_id = affected.entity_id;

View File

@@ -0,0 +1,86 @@
--
-- Licensed to the Apache Software Foundation (ASF) under one
-- or more contributor license agreements. See the NOTICE file
-- distributed with this work for additional information
-- regarding copyright ownership. The ASF licenses this file
-- to you under the Apache License, Version 2.0 (the
-- "License"); you may not use this file except in compliance
-- with the License. You may obtain a copy of the License at
--
-- http://www.apache.org/licenses/LICENSE-2.0
--
-- Unless required by applicable law or agreed to in writing,
-- software distributed under the License is distributed on an
-- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-- KIND, either express or implied. See the License for the
-- specific language governing permissions and limitations
-- under the License.
--
--
-- Table of connection groups. Each connection group has a name.
--
CREATE TABLE `guacamole_connection_group` (
`connection_group_id` int(11) NOT NULL AUTO_INCREMENT,
`parent_id` int(11),
`connection_group_name` varchar(128) NOT NULL,
`type` enum('ORGANIZATIONAL',
'BALANCING') NOT NULL DEFAULT 'ORGANIZATIONAL',
PRIMARY KEY (`connection_group_id`),
UNIQUE KEY `connection_group_name_parent` (`connection_group_name`, `parent_id`),
CONSTRAINT `guacamole_connection_group_ibfk_1`
FOREIGN KEY (`parent_id`)
REFERENCES `guacamole_connection_group` (`connection_group_id`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
--
-- Changes to connection table to support grouping.
--
ALTER TABLE `guacamole_connection` ADD COLUMN `parent_id` int(11) AFTER `connection_name`;
ALTER TABLE `guacamole_connection` DROP INDEX `connection_name`;
ALTER TABLE `guacamole_connection` ADD UNIQUE KEY `connection_name_parent` (`connection_name`, `parent_id`);
ALTER TABLE `guacamole_connection` ADD CONSTRAINT `guacamole_connection_ibfk_1`
FOREIGN KEY (`parent_id`)
REFERENCES `guacamole_connection_group` (`connection_group_id`) ON DELETE CASCADE;
--
-- Table of connection group permissions. Each group permission grants a user
-- specific access to a connection group.
--
CREATE TABLE `guacamole_connection_group_permission` (
`user_id` int(11) NOT NULL,
`connection_group_id` int(11) NOT NULL,
`permission` enum('READ',
'UPDATE',
'DELETE',
'ADMINISTER') NOT NULL,
PRIMARY KEY (`user_id`,`connection_group_id`,`permission`),
CONSTRAINT `guacamole_connection_group_permission_ibfk_1`
FOREIGN KEY (`connection_group_id`)
REFERENCES `guacamole_connection_group` (`connection_group_id`) ON DELETE CASCADE,
CONSTRAINT `guacamole_connection_group_permission_ibfk_2`
FOREIGN KEY (`user_id`)
REFERENCES `guacamole_user` (`user_id`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
ALTER TABLE `guacamole_system_permission` MODIFY `permission`
enum('CREATE_CONNECTION',
'CREATE_CONNECTION_GROUP',
'CREATE_USER',
'ADMINISTER') NOT NULL;

View File

@@ -0,0 +1,184 @@
--
-- Licensed to the Apache Software Foundation (ASF) under one
-- or more contributor license agreements. See the NOTICE file
-- distributed with this work for additional information
-- regarding copyright ownership. The ASF licenses this file
-- to you under the Apache License, Version 2.0 (the
-- "License"); you may not use this file except in compliance
-- with the License. You may obtain a copy of the License at
--
-- http://www.apache.org/licenses/LICENSE-2.0
--
-- Unless required by applicable law or agreed to in writing,
-- software distributed under the License is distributed on an
-- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-- KIND, either express or implied. See the License for the
-- specific language governing permissions and limitations
-- under the License.
--
--
-- User and connection IDs within history table can now be null
--
ALTER TABLE guacamole_connection_history
MODIFY COLUMN user_id INT(11) DEFAULT NULL;
ALTER TABLE guacamole_connection_history
MODIFY COLUMN connection_id INT(11) DEFAULT NULL;
--
-- Add new username and connection_name columns to history table
--
ALTER TABLE guacamole_connection_history
ADD COLUMN username VARCHAR(128);
ALTER TABLE guacamole_connection_history
ADD COLUMN connection_name VARCHAR(128);
--
-- Populate new name columns by joining corresponding tables
--
UPDATE guacamole_connection_history
JOIN guacamole_user
ON guacamole_user.user_id = guacamole_connection_history.user_id
SET guacamole_connection_history.username = guacamole_user.username;
UPDATE guacamole_connection_history
JOIN guacamole_connection
ON guacamole_connection.connection_id =
guacamole_connection_history.connection_id
SET guacamole_connection_history.connection_name =
guacamole_connection.connection_name;
--
-- Set NOT NULL now that the column is fully populated
--
ALTER TABLE guacamole_connection_history
MODIFY username VARCHAR(128) NOT NULL;
ALTER TABLE guacamole_connection_history
MODIFY connection_name VARCHAR(128) NOT NULL;
--
-- Remove old foreign key constraints with ON DELETE CASCADE
--
ALTER TABLE guacamole_connection_history
DROP FOREIGN KEY guacamole_connection_history_ibfk_1;
ALTER TABLE guacamole_connection_history
DROP FOREIGN KEY guacamole_connection_history_ibfk_2;
--
-- Recreate foreign key constraints with ON DELETE SET NULL
--
ALTER TABLE guacamole_connection_history
ADD CONSTRAINT guacamole_connection_history_ibfk_1
FOREIGN KEY (user_id)
REFERENCES guacamole_user (user_id) ON DELETE SET NULL;
ALTER TABLE guacamole_connection_history
ADD CONSTRAINT guacamole_connection_history_ibfk_2
FOREIGN KEY (connection_id)
REFERENCES guacamole_connection (connection_id) ON DELETE SET NULL;
--
-- Add session affinity column
--
ALTER TABLE guacamole_connection_group
ADD COLUMN enable_session_affinity boolean NOT NULL DEFAULT 0;
--
-- Add new system-level permission
--
ALTER TABLE `guacamole_system_permission`
MODIFY `permission` enum('CREATE_CONNECTION',
'CREATE_CONNECTION_GROUP',
'CREATE_SHARING_PROFILE',
'CREATE_USER',
'ADMINISTER') NOT NULL;
--
-- Add sharing profile table
--
CREATE TABLE guacamole_sharing_profile (
`sharing_profile_id` int(11) NOT NULL AUTO_INCREMENT,
`sharing_profile_name` varchar(128) NOT NULL,
`primary_connection_id` int(11) NOT NULL,
PRIMARY KEY (`sharing_profile_id`),
UNIQUE KEY `sharing_profile_name_primary` (sharing_profile_name, primary_connection_id),
CONSTRAINT `guacamole_sharing_profile_ibfk_1`
FOREIGN KEY (`primary_connection_id`)
REFERENCES `guacamole_connection` (`connection_id`)
ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
--
-- Add table of sharing profile parameters
--
CREATE TABLE guacamole_sharing_profile_parameter (
`sharing_profile_id` integer NOT NULL,
`parameter_name` varchar(128) NOT NULL,
`parameter_value` varchar(4096) NOT NULL,
PRIMARY KEY (`sharing_profile_id`, `parameter_name`),
CONSTRAINT `guacamole_sharing_profile_parameter_ibfk_1`
FOREIGN KEY (`sharing_profile_id`)
REFERENCES `guacamole_sharing_profile` (`sharing_profile_id`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
--
-- Object-level permission table for sharing profiles
--
CREATE TABLE guacamole_sharing_profile_permission (
`user_id` integer NOT NULL,
`sharing_profile_id` integer NOT NULL,
`permission` enum('READ',
'UPDATE',
'DELETE',
'ADMINISTER') NOT NULL,
PRIMARY KEY (`user_id`, `sharing_profile_id`, `permission`),
CONSTRAINT `guacamole_sharing_profile_permission_ibfk_1`
FOREIGN KEY (`sharing_profile_id`)
REFERENCES `guacamole_sharing_profile` (`sharing_profile_id`) ON DELETE CASCADE,
CONSTRAINT `guacamole_sharing_profile_permission_ibfk_2`
FOREIGN KEY (`user_id`)
REFERENCES `guacamole_user` (`user_id`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
--
-- Add new (optional) sharing profile ID and name columns to connection history
--
ALTER TABLE guacamole_connection_history
ADD COLUMN sharing_profile_id INT(11);
ALTER TABLE guacamole_connection_history
ADD COLUMN sharing_profile_name VARCHAR(128);
ALTER TABLE guacamole_connection_history
ADD CONSTRAINT guacamole_connection_history_ibfk_3
FOREIGN KEY (sharing_profile_id)
REFERENCES guacamole_sharing_profile (sharing_profile_id) ON DELETE SET NULL;

View File

@@ -0,0 +1,53 @@
--
-- Licensed to the Apache Software Foundation (ASF) under one
-- or more contributor license agreements. See the NOTICE file
-- distributed with this work for additional information
-- regarding copyright ownership. The ASF licenses this file
-- to you under the Apache License, Version 2.0 (the
-- "License"); you may not use this file except in compliance
-- with the License. You may obtain a copy of the License at
--
-- http://www.apache.org/licenses/LICENSE-2.0
--
-- Unless required by applicable law or agreed to in writing,
-- software distributed under the License is distributed on an
-- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-- KIND, either express or implied. See the License for the
-- specific language governing permissions and limitations
-- under the License.
--
--
-- Add per-user password set date
--
ALTER TABLE guacamole_user
ADD COLUMN password_date DATETIME;
UPDATE guacamole_user SET password_date = NOW();
ALTER TABLE guacamole_user
MODIFY COLUMN password_date DATETIME NOT NULL;
--
-- User password history
--
CREATE TABLE guacamole_user_password_history (
`password_history_id` int(11) NOT NULL AUTO_INCREMENT,
`user_id` int(11) NOT NULL,
-- Salted password
`password_hash` binary(32) NOT NULL,
`password_salt` binary(32),
`password_date` datetime NOT NULL,
PRIMARY KEY (`password_history_id`),
KEY `user_id` (`user_id`),
CONSTRAINT `guacamole_user_password_history_ibfk_1`
FOREIGN KEY (`user_id`)
REFERENCES `guacamole_user` (`user_id`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

View File

@@ -0,0 +1,40 @@
--
-- Licensed to the Apache Software Foundation (ASF) under one
-- or more contributor license agreements. See the NOTICE file
-- distributed with this work for additional information
-- regarding copyright ownership. The ASF licenses this file
-- to you under the Apache License, Version 2.0 (the
-- "License"); you may not use this file except in compliance
-- with the License. You may obtain a copy of the License at
--
-- http://www.apache.org/licenses/LICENSE-2.0
--
-- Unless required by applicable law or agreed to in writing,
-- software distributed under the License is distributed on an
-- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-- KIND, either express or implied. See the License for the
-- specific language governing permissions and limitations
-- under the License.
--
--
-- Add guacd per-connection override columns
--
ALTER TABLE guacamole_connection ADD COLUMN proxy_port INT(11);
ALTER TABLE guacamole_connection ADD COLUMN proxy_hostname VARCHAR(512);
ALTER TABLE guacamole_connection ADD COLUMN proxy_encryption_method ENUM(
'NONE',
'SSL'
);
--
-- Add new user profile columns
--
ALTER TABLE guacamole_user ADD COLUMN full_name VARCHAR(256);
ALTER TABLE guacamole_user ADD COLUMN email_address VARCHAR(256);
ALTER TABLE guacamole_user ADD COLUMN organization VARCHAR(256);
ALTER TABLE guacamole_user ADD COLUMN organizational_role VARCHAR(256);

View File

@@ -0,0 +1,70 @@
--
-- Licensed to the Apache Software Foundation (ASF) under one
-- or more contributor license agreements. See the NOTICE file
-- distributed with this work for additional information
-- regarding copyright ownership. The ASF licenses this file
-- to you under the Apache License, Version 2.0 (the
-- "License"); you may not use this file except in compliance
-- with the License. You may obtain a copy of the License at
--
-- http://www.apache.org/licenses/LICENSE-2.0
--
-- Unless required by applicable law or agreed to in writing,
-- software distributed under the License is distributed on an
-- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-- KIND, either express or implied. See the License for the
-- specific language governing permissions and limitations
-- under the License.
--
--
-- Add per-connection weight
--
ALTER TABLE guacamole_connection
ADD COLUMN connection_weight int(11);
--
-- Add failover-only flag
--
ALTER TABLE guacamole_connection
ADD COLUMN failover_only BOOLEAN NOT NULL DEFAULT 0;
--
-- Add remote_host to connection history
--
ALTER TABLE guacamole_connection_history
ADD COLUMN remote_host VARCHAR(256) DEFAULT NULL;
--
-- Add covering index for connection history connection and start date
--
ALTER TABLE guacamole_connection_history ADD KEY (connection_id, start_date);
--
-- User login/logout history
--
CREATE TABLE guacamole_user_history (
`history_id` int(11) NOT NULL AUTO_INCREMENT,
`user_id` int(11) DEFAULT NULL,
`username` varchar(128) NOT NULL,
`remote_host` varchar(256) DEFAULT NULL,
`start_date` datetime NOT NULL,
`end_date` datetime DEFAULT NULL,
PRIMARY KEY (history_id),
KEY `user_id` (`user_id`),
KEY `start_date` (`start_date`),
KEY `end_date` (`end_date`),
KEY `user_start_date` (`user_id`, `start_date`),
CONSTRAINT guacamole_user_history_ibfk_1
FOREIGN KEY (user_id)
REFERENCES guacamole_user (user_id) ON DELETE SET NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

View File

@@ -0,0 +1,36 @@
--
-- Licensed to the Apache Software Foundation (ASF) under one
-- or more contributor license agreements. See the NOTICE file
-- distributed with this work for additional information
-- regarding copyright ownership. The ASF licenses this file
-- to you under the Apache License, Version 2.0 (the
-- "License"); you may not use this file except in compliance
-- with the License. You may obtain a copy of the License at
--
-- http://www.apache.org/licenses/LICENSE-2.0
--
-- Unless required by applicable law or agreed to in writing,
-- software distributed under the License is distributed on an
-- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-- KIND, either express or implied. See the License for the
-- specific language governing permissions and limitations
-- under the License.
--
--
-- Explicitly add permission for each user to READ him/herself
--
INSERT INTO guacamole_user_permission
(user_id, affected_user_id, permission)
SELECT user_id, user_id, 'READ'
FROM guacamole_user
WHERE
user_id NOT IN (
SELECT user_id
FROM guacamole_user_permission
WHERE
user_id = affected_user_id
AND permission = 'READ'
);

View File

@@ -0,0 +1,31 @@
--
-- Licensed to the Apache Software Foundation (ASF) under one
-- or more contributor license agreements. See the NOTICE file
-- distributed with this work for additional information
-- regarding copyright ownership. The ASF licenses this file
-- to you under the Apache License, Version 2.0 (the
-- "License"); you may not use this file except in compliance
-- with the License. You may obtain a copy of the License at
--
-- http://www.apache.org/licenses/LICENSE-2.0
--
-- Unless required by applicable law or agreed to in writing,
-- software distributed under the License is distributed on an
-- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-- KIND, either express or implied. See the License for the
-- specific language governing permissions and limitations
-- under the License.
--
--
-- Add per-user disable flag
--
ALTER TABLE guacamole_user ADD COLUMN disabled BOOLEAN NOT NULL DEFAULT 0;
--
-- Add per-user password expiration flag
--
ALTER TABLE guacamole_user ADD COLUMN expired BOOLEAN NOT NULL DEFAULT 0;

View File

@@ -0,0 +1,52 @@
--
-- Licensed to the Apache Software Foundation (ASF) under one
-- or more contributor license agreements. See the NOTICE file
-- distributed with this work for additional information
-- regarding copyright ownership. The ASF licenses this file
-- to you under the Apache License, Version 2.0 (the
-- "License"); you may not use this file except in compliance
-- with the License. You may obtain a copy of the License at
--
-- http://www.apache.org/licenses/LICENSE-2.0
--
-- Unless required by applicable law or agreed to in writing,
-- software distributed under the License is distributed on an
-- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-- KIND, either express or implied. See the License for the
-- specific language governing permissions and limitations
-- under the License.
--
--
-- Add per-user time-based access restrictions.
--
ALTER TABLE guacamole_user ADD COLUMN access_window_start TIME;
ALTER TABLE guacamole_user ADD COLUMN access_window_end TIME;
--
-- Add per-user date-based account validity restrictions.
--
ALTER TABLE guacamole_user ADD COLUMN valid_from DATE;
ALTER TABLE guacamole_user ADD COLUMN valid_until DATE;
--
-- Add per-user timezone for sake of time comparisons/interpretation.
--
ALTER TABLE guacamole_user ADD COLUMN timezone VARCHAR(64);
--
-- Add connection concurrency limits
--
ALTER TABLE guacamole_connection ADD COLUMN max_connections INT(11);
ALTER TABLE guacamole_connection ADD COLUMN max_connections_per_user INT(11);
--
-- Add connection group concurrency limits
--
ALTER TABLE guacamole_connection_group ADD COLUMN max_connections INT(11);
ALTER TABLE guacamole_connection_group ADD COLUMN max_connections_per_user INT(11);

View File

@@ -0,0 +1,26 @@
--
-- Licensed to the Apache Software Foundation (ASF) under one
-- or more contributor license agreements. See the NOTICE file
-- distributed with this work for additional information
-- regarding copyright ownership. The ASF licenses this file
-- to you under the Apache License, Version 2.0 (the
-- "License"); you may not use this file except in compliance
-- with the License. You may obtain a copy of the License at
--
-- http://www.apache.org/licenses/LICENSE-2.0
--
-- Unless required by applicable law or agreed to in writing,
-- software distributed under the License is distributed on an
-- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-- KIND, either express or implied. See the License for the
-- specific language governing permissions and limitations
-- under the License.
--
--
-- Ensure history entry start/end dates are indexed.
--
ALTER TABLE guacamole_connection_history ADD KEY (start_date);
ALTER TABLE guacamole_connection_history ADD KEY (end_date);
ALTER TABLE guacamole_connection_history ADD KEY search_index (start_date, connection_id, user_id);

View File

@@ -0,0 +1,441 @@
--
-- Licensed to the Apache Software Foundation (ASF) under one
-- or more contributor license agreements. See the NOTICE file
-- distributed with this work for additional information
-- regarding copyright ownership. The ASF licenses this file
-- to you under the Apache License, Version 2.0 (the
-- "License"); you may not use this file except in compliance
-- with the License. You may obtain a copy of the License at
--
-- http://www.apache.org/licenses/LICENSE-2.0
--
-- Unless required by applicable law or agreed to in writing,
-- software distributed under the License is distributed on an
-- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-- KIND, either express or implied. See the License for the
-- specific language governing permissions and limitations
-- under the License.
--
--
-- Add new system-level permission
--
ALTER TABLE `guacamole_system_permission`
MODIFY `permission` enum('CREATE_CONNECTION',
'CREATE_CONNECTION_GROUP',
'CREATE_SHARING_PROFILE',
'CREATE_USER',
'CREATE_USER_GROUP',
'ADMINISTER') NOT NULL;
--
-- Table of base entities which may each be either a user or user group. Other
-- tables which represent qualities shared by both users and groups will point
-- to guacamole_entity, while tables which represent qualities specific to
-- users or groups will point to guacamole_user or guacamole_user_group.
--
CREATE TABLE `guacamole_entity` (
`entity_id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(128) NOT NULL,
`type` enum('USER',
'USER_GROUP') NOT NULL,
PRIMARY KEY (`entity_id`),
UNIQUE KEY `guacamole_entity_name_scope` (`type`, `name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
--
-- Table of user groups. Each user group may have an arbitrary set of member
-- users and member groups, with those members inheriting the permissions
-- granted to that group.
--
CREATE TABLE `guacamole_user_group` (
`user_group_id` int(11) NOT NULL AUTO_INCREMENT,
`entity_id` int(11) NOT NULL,
-- Group disabled status
`disabled` boolean NOT NULL DEFAULT 0,
PRIMARY KEY (`user_group_id`),
UNIQUE KEY `guacamole_user_group_single_entity` (`entity_id`),
CONSTRAINT `guacamole_user_group_entity`
FOREIGN KEY (`entity_id`)
REFERENCES `guacamole_entity` (`entity_id`)
ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
--
-- Table of users which are members of given user groups.
--
CREATE TABLE `guacamole_user_group_member` (
`user_group_id` int(11) NOT NULL,
`member_entity_id` int(11) NOT NULL,
PRIMARY KEY (`user_group_id`, `member_entity_id`),
-- Parent must be a user group
CONSTRAINT `guacamole_user_group_member_parent_id`
FOREIGN KEY (`user_group_id`)
REFERENCES `guacamole_user_group` (`user_group_id`) ON DELETE CASCADE,
-- Member may be either a user or a user group (any entity)
CONSTRAINT `guacamole_user_group_member_entity_id`
FOREIGN KEY (`member_entity_id`)
REFERENCES `guacamole_entity` (`entity_id`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
--
-- Table of user group permissions. Each user group permission grants a user
-- or user group access to a another user group (the "affected" user group) for
-- a specific type of operation.
--
CREATE TABLE `guacamole_user_group_permission` (
`entity_id` int(11) NOT NULL,
`affected_user_group_id` int(11) NOT NULL,
`permission` enum('READ',
'UPDATE',
'DELETE',
'ADMINISTER') NOT NULL,
PRIMARY KEY (`entity_id`, `affected_user_group_id`, `permission`),
CONSTRAINT `guacamole_user_group_permission_affected_user_group`
FOREIGN KEY (`affected_user_group_id`)
REFERENCES `guacamole_user_group` (`user_group_id`) ON DELETE CASCADE,
CONSTRAINT `guacamole_user_group_permission_entity`
FOREIGN KEY (`entity_id`)
REFERENCES `guacamole_entity` (`entity_id`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
--
-- Modify guacamole_user table to use guacamole_entity as a base
--
-- Add new entity_id column
ALTER TABLE guacamole_user ADD COLUMN entity_id int(11);
-- Create user entities for each guacamole_user entry
INSERT INTO guacamole_entity (name, type)
SELECT username, 'USER' FROM guacamole_user;
-- Update guacamole_user to point to corresponding guacamole_entity
UPDATE guacamole_user SET entity_id = (
SELECT entity_id FROM guacamole_entity
WHERE
username = guacamole_entity.name
AND type = 'USER'
);
-- The entity_id column should now be safely non-NULL
ALTER TABLE guacamole_user MODIFY entity_id int(11) NOT NULL;
-- The entity_id column should now be unique for each user
ALTER TABLE guacamole_user
ADD CONSTRAINT guacamole_user_single_entity
UNIQUE (entity_id);
-- The entity_id column should now safely point to guacamole_entity entries
ALTER TABLE guacamole_user
ADD CONSTRAINT guacamole_user_entity
FOREIGN KEY (entity_id)
REFERENCES guacamole_entity (entity_id)
ON DELETE CASCADE;
-- The username column can now safely be removed
ALTER TABLE guacamole_user DROP COLUMN username;
--
-- Modify guacamole_connection_permission to use guacamole_entity instead of
-- guacamole_user
--
-- Add new entity_id column
ALTER TABLE guacamole_connection_permission ADD COLUMN entity_id int(11);
-- Update guacamole_connection_permission to point to the guacamole_entity
-- that has been granted the permission
UPDATE guacamole_connection_permission SET entity_id = (
SELECT entity_id FROM guacamole_user
WHERE guacamole_user.user_id = guacamole_connection_permission.user_id
);
-- The entity_id column should now be safely non-NULL
ALTER TABLE guacamole_connection_permission MODIFY entity_id int(11) NOT NULL;
-- The entity_id column should now safely point to guacamole_entity entries
ALTER TABLE guacamole_connection_permission
ADD CONSTRAINT guacamole_connection_permission_entity
FOREIGN KEY (entity_id)
REFERENCES guacamole_entity (entity_id)
ON DELETE CASCADE;
-- Remove user_id column
ALTER TABLE guacamole_connection_permission DROP FOREIGN KEY guacamole_connection_permission_ibfk_2;
ALTER TABLE guacamole_connection_permission DROP PRIMARY KEY;
ALTER TABLE guacamole_connection_permission DROP COLUMN user_id;
-- Add new primary key which uses entity_id
ALTER TABLE guacamole_connection_permission
ADD PRIMARY KEY (entity_id, connection_id, permission);
--
-- Modify guacamole_connection_group_permission to use guacamole_entity instead
-- of guacamole_user
--
-- Add new entity_id column
ALTER TABLE guacamole_connection_group_permission ADD COLUMN entity_id int(11);
-- Update guacamole_connection_group_permission to point to the guacamole_entity
-- that has been granted the permission
UPDATE guacamole_connection_group_permission SET entity_id = (
SELECT entity_id FROM guacamole_user
WHERE guacamole_user.user_id = guacamole_connection_group_permission.user_id
);
-- The entity_id column should now be safely non-NULL
ALTER TABLE guacamole_connection_group_permission MODIFY entity_id int(11) NOT NULL;
-- The entity_id column should now safely point to guacamole_entity entries
ALTER TABLE guacamole_connection_group_permission
ADD CONSTRAINT guacamole_connection_group_permission_entity
FOREIGN KEY (entity_id)
REFERENCES guacamole_entity (entity_id)
ON DELETE CASCADE;
-- Remove user_id column
ALTER TABLE guacamole_connection_group_permission DROP FOREIGN KEY guacamole_connection_group_permission_ibfk_2;
ALTER TABLE guacamole_connection_group_permission DROP PRIMARY KEY;
ALTER TABLE guacamole_connection_group_permission DROP COLUMN user_id;
-- Add new primary key which uses entity_id
ALTER TABLE guacamole_connection_group_permission
ADD PRIMARY KEY (entity_id, connection_group_id, permission);
--
-- Modify guacamole_sharing_profile_permission to use guacamole_entity instead
-- of guacamole_user
--
-- Add new entity_id column
ALTER TABLE guacamole_sharing_profile_permission ADD COLUMN entity_id int(11);
-- Update guacamole_sharing_profile_permission to point to the guacamole_entity
-- that has been granted the permission
UPDATE guacamole_sharing_profile_permission SET entity_id = (
SELECT entity_id FROM guacamole_user
WHERE guacamole_user.user_id = guacamole_sharing_profile_permission.user_id
);
-- The entity_id column should now be safely non-NULL
ALTER TABLE guacamole_sharing_profile_permission MODIFY entity_id int(11) NOT NULL;
-- The entity_id column should now safely point to guacamole_entity entries
ALTER TABLE guacamole_sharing_profile_permission
ADD CONSTRAINT guacamole_sharing_profile_permission_entity
FOREIGN KEY (entity_id)
REFERENCES guacamole_entity (entity_id)
ON DELETE CASCADE;
-- Remove user_id column
ALTER TABLE guacamole_sharing_profile_permission DROP FOREIGN KEY guacamole_sharing_profile_permission_ibfk_2;
ALTER TABLE guacamole_sharing_profile_permission DROP PRIMARY KEY;
ALTER TABLE guacamole_sharing_profile_permission DROP COLUMN user_id;
-- Add new primary key which uses entity_id
ALTER TABLE guacamole_sharing_profile_permission
ADD PRIMARY KEY (entity_id, sharing_profile_id, permission);
--
-- Modify guacamole_user_permission to use guacamole_entity instead of
-- guacamole_user
--
-- Add new entity_id column
ALTER TABLE guacamole_user_permission ADD COLUMN entity_id int(11);
-- Update guacamole_user_permission to point to the guacamole_entity
-- that has been granted the permission
UPDATE guacamole_user_permission SET entity_id = (
SELECT entity_id FROM guacamole_user
WHERE guacamole_user.user_id = guacamole_user_permission.user_id
);
-- The entity_id column should now be safely non-NULL
ALTER TABLE guacamole_user_permission MODIFY entity_id int(11) NOT NULL;
-- The entity_id column should now safely point to guacamole_entity entries
ALTER TABLE guacamole_user_permission
ADD CONSTRAINT guacamole_user_permission_entity
FOREIGN KEY (entity_id)
REFERENCES guacamole_entity (entity_id)
ON DELETE CASCADE;
-- Remove user_id column
ALTER TABLE guacamole_user_permission DROP FOREIGN KEY guacamole_user_permission_ibfk_2;
ALTER TABLE guacamole_user_permission DROP PRIMARY KEY;
ALTER TABLE guacamole_user_permission DROP COLUMN user_id;
-- Add new primary key which uses entity_id
ALTER TABLE guacamole_user_permission
ADD PRIMARY KEY (entity_id, affected_user_id, permission);
--
-- Modify guacamole_system_permission to use guacamole_entity instead of
-- guacamole_user
--
-- Add new entity_id column
ALTER TABLE guacamole_system_permission ADD COLUMN entity_id int(11);
-- Update guacamole_system_permission to point to the guacamole_entity
-- that has been granted the permission
UPDATE guacamole_system_permission SET entity_id = (
SELECT entity_id FROM guacamole_user
WHERE guacamole_user.user_id = guacamole_system_permission.user_id
);
-- The entity_id column should now be safely non-NULL
ALTER TABLE guacamole_system_permission MODIFY entity_id int(11) NOT NULL;
-- The entity_id column should now safely point to guacamole_entity entries
ALTER TABLE guacamole_system_permission
ADD CONSTRAINT guacamole_system_permission_entity
FOREIGN KEY (entity_id)
REFERENCES guacamole_entity (entity_id)
ON DELETE CASCADE;
-- Remove user_id column
ALTER TABLE guacamole_system_permission DROP FOREIGN KEY guacamole_system_permission_ibfk_1;
ALTER TABLE guacamole_system_permission DROP PRIMARY KEY;
ALTER TABLE guacamole_system_permission DROP COLUMN user_id;
-- Add new primary key which uses entity_id
ALTER TABLE guacamole_system_permission
ADD PRIMARY KEY (entity_id, permission);
--
-- Table of arbitrary user attributes. Each attribute is simply a name/value
-- pair associated with a user. Arbitrary attributes are defined by other
-- extensions. Attributes defined by this extension will be mapped to
-- properly-typed columns of a specific table.
--
CREATE TABLE guacamole_user_attribute (
`user_id` int(11) NOT NULL,
`attribute_name` varchar(128) NOT NULL,
`attribute_value` varchar(4096) NOT NULL,
PRIMARY KEY (user_id, attribute_name),
KEY `user_id` (`user_id`),
CONSTRAINT guacamole_user_attribute_ibfk_1
FOREIGN KEY (user_id)
REFERENCES guacamole_user (user_id) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
--
-- Table of arbitrary user group attributes. Each attribute is simply a
-- name/value pair associated with a user group. Arbitrary attributes are
-- defined by other extensions. Attributes defined by this extension will be
-- mapped to properly-typed columns of a specific table.
--
CREATE TABLE guacamole_user_group_attribute (
`user_group_id` int(11) NOT NULL,
`attribute_name` varchar(128) NOT NULL,
`attribute_value` varchar(4096) NOT NULL,
PRIMARY KEY (`user_group_id`, `attribute_name`),
KEY `user_group_id` (`user_group_id`),
CONSTRAINT `guacamole_user_group_attribute_ibfk_1`
FOREIGN KEY (`user_group_id`)
REFERENCES `guacamole_user_group` (`user_group_id`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
--
-- Table of arbitrary connection attributes. Each attribute is simply a
-- name/value pair associated with a connection. Arbitrary attributes are
-- defined by other extensions. Attributes defined by this extension will be
-- mapped to properly-typed columns of a specific table.
--
CREATE TABLE guacamole_connection_attribute (
`connection_id` int(11) NOT NULL,
`attribute_name` varchar(128) NOT NULL,
`attribute_value` varchar(4096) NOT NULL,
PRIMARY KEY (connection_id, attribute_name),
KEY `connection_id` (`connection_id`),
CONSTRAINT guacamole_connection_attribute_ibfk_1
FOREIGN KEY (connection_id)
REFERENCES guacamole_connection (connection_id) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
--
-- Table of arbitrary connection group attributes. Each attribute is simply a
-- name/value pair associated with a connection group. Arbitrary attributes are
-- defined by other extensions. Attributes defined by this extension will be
-- mapped to properly-typed columns of a specific table.
--
CREATE TABLE guacamole_connection_group_attribute (
`connection_group_id` int(11) NOT NULL,
`attribute_name` varchar(128) NOT NULL,
`attribute_value` varchar(4096) NOT NULL,
PRIMARY KEY (connection_group_id, attribute_name),
KEY `connection_group_id` (`connection_group_id`),
CONSTRAINT guacamole_connection_group_attribute_ibfk_1
FOREIGN KEY (connection_group_id)
REFERENCES guacamole_connection_group (connection_group_id) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
--
-- Table of arbitrary sharing profile attributes. Each attribute is simply a
-- name/value pair associated with a sharing profile. Arbitrary attributes are
-- defined by other extensions. Attributes defined by this extension will be
-- mapped to properly-typed columns of a specific table.
--
CREATE TABLE guacamole_sharing_profile_attribute (
`sharing_profile_id` int(11) NOT NULL,
`attribute_name` varchar(128) NOT NULL,
`attribute_value` varchar(4096) NOT NULL,
PRIMARY KEY (sharing_profile_id, attribute_name),
KEY `sharing_profile_id` (`sharing_profile_id`),
CONSTRAINT guacamole_sharing_profile_attribute_ibfk_1
FOREIGN KEY (sharing_profile_id)
REFERENCES guacamole_sharing_profile (sharing_profile_id) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

View File

@@ -0,0 +1,736 @@
--
-- Licensed to the Apache Software Foundation (ASF) under one
-- or more contributor license agreements. See the NOTICE file
-- distributed with this work for additional information
-- regarding copyright ownership. The ASF licenses this file
-- to you under the Apache License, Version 2.0 (the
-- "License"); you may not use this file except in compliance
-- with the License. You may obtain a copy of the License at
--
-- http://www.apache.org/licenses/LICENSE-2.0
--
-- Unless required by applicable law or agreed to in writing,
-- software distributed under the License is distributed on an
-- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-- KIND, either express or implied. See the License for the
-- specific language governing permissions and limitations
-- under the License.
--
--
-- Connection group types
--
CREATE TYPE guacamole_connection_group_type AS ENUM(
'ORGANIZATIONAL',
'BALANCING'
);
--
-- Entity types
--
CREATE TYPE guacamole_entity_type AS ENUM(
'USER',
'USER_GROUP'
);
--
-- Object permission types
--
CREATE TYPE guacamole_object_permission_type AS ENUM(
'READ',
'UPDATE',
'DELETE',
'ADMINISTER'
);
--
-- System permission types
--
CREATE TYPE guacamole_system_permission_type AS ENUM(
'CREATE_CONNECTION',
'CREATE_CONNECTION_GROUP',
'CREATE_SHARING_PROFILE',
'CREATE_USER',
'CREATE_USER_GROUP',
'ADMINISTER'
);
--
-- Guacamole proxy (guacd) encryption methods
--
CREATE TYPE guacamole_proxy_encryption_method AS ENUM(
'NONE',
'SSL'
);
--
-- Table of connection groups. Each connection group has a name.
--
CREATE TABLE guacamole_connection_group (
connection_group_id serial NOT NULL,
parent_id integer,
connection_group_name varchar(128) NOT NULL,
type guacamole_connection_group_type
NOT NULL DEFAULT 'ORGANIZATIONAL',
-- Concurrency limits
max_connections integer,
max_connections_per_user integer,
enable_session_affinity boolean NOT NULL DEFAULT FALSE,
PRIMARY KEY (connection_group_id),
CONSTRAINT connection_group_name_parent
UNIQUE (connection_group_name, parent_id),
CONSTRAINT guacamole_connection_group_ibfk_1
FOREIGN KEY (parent_id)
REFERENCES guacamole_connection_group (connection_group_id)
ON DELETE CASCADE
);
CREATE INDEX guacamole_connection_group_parent_id
ON guacamole_connection_group(parent_id);
--
-- Table of connections. Each connection has a name, protocol, and
-- associated set of parameters.
-- A connection may belong to a connection group.
--
CREATE TABLE guacamole_connection (
connection_id serial NOT NULL,
connection_name varchar(128) NOT NULL,
parent_id integer,
protocol varchar(32) NOT NULL,
-- Concurrency limits
max_connections integer,
max_connections_per_user integer,
-- Connection Weight
connection_weight integer,
failover_only boolean NOT NULL DEFAULT FALSE,
-- Guacamole proxy (guacd) overrides
proxy_port integer,
proxy_hostname varchar(512),
proxy_encryption_method guacamole_proxy_encryption_method,
PRIMARY KEY (connection_id),
CONSTRAINT connection_name_parent
UNIQUE (connection_name, parent_id),
CONSTRAINT guacamole_connection_ibfk_1
FOREIGN KEY (parent_id)
REFERENCES guacamole_connection_group (connection_group_id)
ON DELETE CASCADE
);
CREATE INDEX guacamole_connection_parent_id
ON guacamole_connection(parent_id);
--
-- Table of base entities which may each be either a user or user group. Other
-- tables which represent qualities shared by both users and groups will point
-- to guacamole_entity, while tables which represent qualities specific to
-- users or groups will point to guacamole_user or guacamole_user_group.
--
CREATE TABLE guacamole_entity (
entity_id serial NOT NULL,
name varchar(128) NOT NULL,
type guacamole_entity_type NOT NULL,
PRIMARY KEY (entity_id),
CONSTRAINT guacamole_entity_name_scope
UNIQUE (type, name)
);
--
-- Table of users. Each user has a unique username and a hashed password
-- with corresponding salt. Although the authentication system will always set
-- salted passwords, other systems may set unsalted passwords by simply not
-- providing the salt.
--
CREATE TABLE guacamole_user (
user_id serial NOT NULL,
entity_id integer NOT NULL,
-- Optionally-salted password
password_hash bytea NOT NULL,
password_salt bytea,
password_date timestamptz NOT NULL,
-- Account disabled/expired status
disabled boolean NOT NULL DEFAULT FALSE,
expired boolean NOT NULL DEFAULT FALSE,
-- Time-based access restriction
access_window_start time,
access_window_end time,
-- Date-based access restriction
valid_from date,
valid_until date,
-- Timezone used for all date/time comparisons and interpretation
timezone varchar(64),
-- Profile information
full_name varchar(256),
email_address varchar(256),
organization varchar(256),
organizational_role varchar(256),
PRIMARY KEY (user_id),
CONSTRAINT guacamole_user_single_entity
UNIQUE (entity_id),
CONSTRAINT guacamole_user_entity
FOREIGN KEY (entity_id)
REFERENCES guacamole_entity (entity_id)
ON DELETE CASCADE
);
--
-- Table of user groups. Each user group may have an arbitrary set of member
-- users and member groups, with those members inheriting the permissions
-- granted to that group.
--
CREATE TABLE guacamole_user_group (
user_group_id serial NOT NULL,
entity_id integer NOT NULL,
-- Group disabled status
disabled boolean NOT NULL DEFAULT FALSE,
PRIMARY KEY (user_group_id),
CONSTRAINT guacamole_user_group_single_entity
UNIQUE (entity_id),
CONSTRAINT guacamole_user_group_entity
FOREIGN KEY (entity_id)
REFERENCES guacamole_entity (entity_id)
ON DELETE CASCADE
);
--
-- Table of users which are members of given user groups.
--
CREATE TABLE guacamole_user_group_member (
user_group_id integer NOT NULL,
member_entity_id integer NOT NULL,
PRIMARY KEY (user_group_id, member_entity_id),
-- Parent must be a user group
CONSTRAINT guacamole_user_group_member_parent
FOREIGN KEY (user_group_id)
REFERENCES guacamole_user_group (user_group_id) ON DELETE CASCADE,
-- Member may be either a user or a user group (any entity)
CONSTRAINT guacamole_user_group_member_entity
FOREIGN KEY (member_entity_id)
REFERENCES guacamole_entity (entity_id) ON DELETE CASCADE
);
--
-- Table of sharing profiles. Each sharing profile has a name, associated set
-- of parameters, and a primary connection. The primary connection is the
-- connection that the sharing profile shares, and the parameters dictate the
-- restrictions/features which apply to the user joining the connection via the
-- sharing profile.
--
CREATE TABLE guacamole_sharing_profile (
sharing_profile_id serial NOT NULL,
sharing_profile_name varchar(128) NOT NULL,
primary_connection_id integer NOT NULL,
PRIMARY KEY (sharing_profile_id),
CONSTRAINT sharing_profile_name_primary
UNIQUE (sharing_profile_name, primary_connection_id),
CONSTRAINT guacamole_sharing_profile_ibfk_1
FOREIGN KEY (primary_connection_id)
REFERENCES guacamole_connection (connection_id)
ON DELETE CASCADE
);
CREATE INDEX guacamole_sharing_profile_primary_connection_id
ON guacamole_sharing_profile(primary_connection_id);
--
-- Table of connection parameters. Each parameter is simply a name/value pair
-- associated with a connection.
--
CREATE TABLE guacamole_connection_parameter (
connection_id integer NOT NULL,
parameter_name varchar(128) NOT NULL,
parameter_value varchar(4096) NOT NULL,
PRIMARY KEY (connection_id,parameter_name),
CONSTRAINT guacamole_connection_parameter_ibfk_1
FOREIGN KEY (connection_id)
REFERENCES guacamole_connection (connection_id) ON DELETE CASCADE
);
CREATE INDEX guacamole_connection_parameter_connection_id
ON guacamole_connection_parameter(connection_id);
--
-- Table of sharing profile parameters. Each parameter is simply
-- name/value pair associated with a sharing profile. These parameters dictate
-- the restrictions/features which apply to the user joining the associated
-- connection via the sharing profile.
--
CREATE TABLE guacamole_sharing_profile_parameter (
sharing_profile_id integer NOT NULL,
parameter_name varchar(128) NOT NULL,
parameter_value varchar(4096) NOT NULL,
PRIMARY KEY (sharing_profile_id, parameter_name),
CONSTRAINT guacamole_sharing_profile_parameter_ibfk_1
FOREIGN KEY (sharing_profile_id)
REFERENCES guacamole_sharing_profile (sharing_profile_id) ON DELETE CASCADE
);
CREATE INDEX guacamole_sharing_profile_parameter_sharing_profile_id
ON guacamole_sharing_profile_parameter(sharing_profile_id);
--
-- Table of arbitrary user attributes. Each attribute is simply a name/value
-- pair associated with a user. Arbitrary attributes are defined by other
-- extensions. Attributes defined by this extension will be mapped to
-- properly-typed columns of a specific table.
--
CREATE TABLE guacamole_user_attribute (
user_id integer NOT NULL,
attribute_name varchar(128) NOT NULL,
attribute_value varchar(4096) NOT NULL,
PRIMARY KEY (user_id, attribute_name),
CONSTRAINT guacamole_user_attribute_ibfk_1
FOREIGN KEY (user_id)
REFERENCES guacamole_user (user_id) ON DELETE CASCADE
);
CREATE INDEX guacamole_user_attribute_user_id
ON guacamole_user_attribute(user_id);
--
-- Table of arbitrary user group attributes. Each attribute is simply a
-- name/value pair associated with a user group. Arbitrary attributes are
-- defined by other extensions. Attributes defined by this extension will be
-- mapped to properly-typed columns of a specific table.
--
CREATE TABLE guacamole_user_group_attribute (
user_group_id integer NOT NULL,
attribute_name varchar(128) NOT NULL,
attribute_value varchar(4096) NOT NULL,
PRIMARY KEY (user_group_id, attribute_name),
CONSTRAINT guacamole_user_group_attribute_ibfk_1
FOREIGN KEY (user_group_id)
REFERENCES guacamole_user_group (user_group_id) ON DELETE CASCADE
);
CREATE INDEX guacamole_user_group_attribute_user_group_id
ON guacamole_user_group_attribute(user_group_id);
--
-- Table of arbitrary connection attributes. Each attribute is simply a
-- name/value pair associated with a connection. Arbitrary attributes are
-- defined by other extensions. Attributes defined by this extension will be
-- mapped to properly-typed columns of a specific table.
--
CREATE TABLE guacamole_connection_attribute (
connection_id integer NOT NULL,
attribute_name varchar(128) NOT NULL,
attribute_value varchar(4096) NOT NULL,
PRIMARY KEY (connection_id, attribute_name),
CONSTRAINT guacamole_connection_attribute_ibfk_1
FOREIGN KEY (connection_id)
REFERENCES guacamole_connection (connection_id) ON DELETE CASCADE
);
CREATE INDEX guacamole_connection_attribute_connection_id
ON guacamole_connection_attribute(connection_id);
--
-- Table of arbitrary connection group attributes. Each attribute is simply a
-- name/value pair associated with a connection group. Arbitrary attributes are
-- defined by other extensions. Attributes defined by this extension will be
-- mapped to properly-typed columns of a specific table.
--
CREATE TABLE guacamole_connection_group_attribute (
connection_group_id integer NOT NULL,
attribute_name varchar(128) NOT NULL,
attribute_value varchar(4096) NOT NULL,
PRIMARY KEY (connection_group_id, attribute_name),
CONSTRAINT guacamole_connection_group_attribute_ibfk_1
FOREIGN KEY (connection_group_id)
REFERENCES guacamole_connection_group (connection_group_id) ON DELETE CASCADE
);
CREATE INDEX guacamole_connection_group_attribute_connection_group_id
ON guacamole_connection_group_attribute(connection_group_id);
--
-- Table of arbitrary sharing profile attributes. Each attribute is simply a
-- name/value pair associated with a sharing profile. Arbitrary attributes are
-- defined by other extensions. Attributes defined by this extension will be
-- mapped to properly-typed columns of a specific table.
--
CREATE TABLE guacamole_sharing_profile_attribute (
sharing_profile_id integer NOT NULL,
attribute_name varchar(128) NOT NULL,
attribute_value varchar(4096) NOT NULL,
PRIMARY KEY (sharing_profile_id, attribute_name),
CONSTRAINT guacamole_sharing_profile_attribute_ibfk_1
FOREIGN KEY (sharing_profile_id)
REFERENCES guacamole_sharing_profile (sharing_profile_id) ON DELETE CASCADE
);
CREATE INDEX guacamole_sharing_profile_attribute_sharing_profile_id
ON guacamole_sharing_profile_attribute(sharing_profile_id);
--
-- Table of connection permissions. Each connection permission grants a user or
-- user group specific access to a connection.
--
CREATE TABLE guacamole_connection_permission (
entity_id integer NOT NULL,
connection_id integer NOT NULL,
permission guacamole_object_permission_type NOT NULL,
PRIMARY KEY (entity_id, connection_id, permission),
CONSTRAINT guacamole_connection_permission_ibfk_1
FOREIGN KEY (connection_id)
REFERENCES guacamole_connection (connection_id) ON DELETE CASCADE,
CONSTRAINT guacamole_connection_permission_entity
FOREIGN KEY (entity_id)
REFERENCES guacamole_entity (entity_id) ON DELETE CASCADE
);
CREATE INDEX guacamole_connection_permission_connection_id
ON guacamole_connection_permission(connection_id);
CREATE INDEX guacamole_connection_permission_entity_id
ON guacamole_connection_permission(entity_id);
--
-- Table of connection group permissions. Each group permission grants a user
-- or user group specific access to a connection group.
--
CREATE TABLE guacamole_connection_group_permission (
entity_id integer NOT NULL,
connection_group_id integer NOT NULL,
permission guacamole_object_permission_type NOT NULL,
PRIMARY KEY (entity_id, connection_group_id, permission),
CONSTRAINT guacamole_connection_group_permission_ibfk_1
FOREIGN KEY (connection_group_id)
REFERENCES guacamole_connection_group (connection_group_id) ON DELETE CASCADE,
CONSTRAINT guacamole_connection_group_permission_entity
FOREIGN KEY (entity_id)
REFERENCES guacamole_entity (entity_id) ON DELETE CASCADE
);
CREATE INDEX guacamole_connection_group_permission_connection_group_id
ON guacamole_connection_group_permission(connection_group_id);
CREATE INDEX guacamole_connection_group_permission_entity_id
ON guacamole_connection_group_permission(entity_id);
--
-- Table of sharing profile permissions. Each sharing profile permission grants
-- a user or user group specific access to a sharing profile.
--
CREATE TABLE guacamole_sharing_profile_permission (
entity_id integer NOT NULL,
sharing_profile_id integer NOT NULL,
permission guacamole_object_permission_type NOT NULL,
PRIMARY KEY (entity_id, sharing_profile_id, permission),
CONSTRAINT guacamole_sharing_profile_permission_ibfk_1
FOREIGN KEY (sharing_profile_id)
REFERENCES guacamole_sharing_profile (sharing_profile_id) ON DELETE CASCADE,
CONSTRAINT guacamole_sharing_profile_permission_entity
FOREIGN KEY (entity_id)
REFERENCES guacamole_entity (entity_id) ON DELETE CASCADE
);
CREATE INDEX guacamole_sharing_profile_permission_sharing_profile_id
ON guacamole_sharing_profile_permission(sharing_profile_id);
CREATE INDEX guacamole_sharing_profile_permission_entity_id
ON guacamole_sharing_profile_permission(entity_id);
--
-- Table of system permissions. Each system permission grants a user or user
-- group a system-level privilege of some kind.
--
CREATE TABLE guacamole_system_permission (
entity_id integer NOT NULL,
permission guacamole_system_permission_type NOT NULL,
PRIMARY KEY (entity_id, permission),
CONSTRAINT guacamole_system_permission_entity
FOREIGN KEY (entity_id)
REFERENCES guacamole_entity (entity_id) ON DELETE CASCADE
);
CREATE INDEX guacamole_system_permission_entity_id
ON guacamole_system_permission(entity_id);
--
-- Table of user permissions. Each user permission grants a user or user group
-- access to another user (the "affected" user) for a specific type of
-- operation.
--
CREATE TABLE guacamole_user_permission (
entity_id integer NOT NULL,
affected_user_id integer NOT NULL,
permission guacamole_object_permission_type NOT NULL,
PRIMARY KEY (entity_id, affected_user_id, permission),
CONSTRAINT guacamole_user_permission_ibfk_1
FOREIGN KEY (affected_user_id)
REFERENCES guacamole_user (user_id) ON DELETE CASCADE,
CONSTRAINT guacamole_user_permission_entity
FOREIGN KEY (entity_id)
REFERENCES guacamole_entity (entity_id) ON DELETE CASCADE
);
CREATE INDEX guacamole_user_permission_affected_user_id
ON guacamole_user_permission(affected_user_id);
CREATE INDEX guacamole_user_permission_entity_id
ON guacamole_user_permission(entity_id);
--
-- Table of user group permissions. Each user group permission grants a user
-- or user group access to a another user group (the "affected" user group) for
-- a specific type of operation.
--
CREATE TABLE guacamole_user_group_permission (
entity_id integer NOT NULL,
affected_user_group_id integer NOT NULL,
permission guacamole_object_permission_type NOT NULL,
PRIMARY KEY (entity_id, affected_user_group_id, permission),
CONSTRAINT guacamole_user_group_permission_affected_user_group
FOREIGN KEY (affected_user_group_id)
REFERENCES guacamole_user_group (user_group_id) ON DELETE CASCADE,
CONSTRAINT guacamole_user_group_permission_entity
FOREIGN KEY (entity_id)
REFERENCES guacamole_entity (entity_id) ON DELETE CASCADE
);
CREATE INDEX guacamole_user_group_permission_affected_user_group_id
ON guacamole_user_group_permission(affected_user_group_id);
CREATE INDEX guacamole_user_group_permission_entity_id
ON guacamole_user_group_permission(entity_id);
--
-- Table of connection history records. Each record defines a specific user's
-- session, including the connection used, the start time, and the end time
-- (if any).
--
CREATE TABLE guacamole_connection_history (
history_id serial NOT NULL,
user_id integer DEFAULT NULL,
username varchar(128) NOT NULL,
remote_host varchar(256) DEFAULT NULL,
connection_id integer DEFAULT NULL,
connection_name varchar(128) NOT NULL,
sharing_profile_id integer DEFAULT NULL,
sharing_profile_name varchar(128) DEFAULT NULL,
start_date timestamptz NOT NULL,
end_date timestamptz DEFAULT NULL,
PRIMARY KEY (history_id),
CONSTRAINT guacamole_connection_history_ibfk_1
FOREIGN KEY (user_id)
REFERENCES guacamole_user (user_id) ON DELETE SET NULL,
CONSTRAINT guacamole_connection_history_ibfk_2
FOREIGN KEY (connection_id)
REFERENCES guacamole_connection (connection_id) ON DELETE SET NULL,
CONSTRAINT guacamole_connection_history_ibfk_3
FOREIGN KEY (sharing_profile_id)
REFERENCES guacamole_sharing_profile (sharing_profile_id) ON DELETE SET NULL
);
CREATE INDEX guacamole_connection_history_user_id
ON guacamole_connection_history(user_id);
CREATE INDEX guacamole_connection_history_connection_id
ON guacamole_connection_history(connection_id);
CREATE INDEX guacamole_connection_history_sharing_profile_id
ON guacamole_connection_history(sharing_profile_id);
CREATE INDEX guacamole_connection_history_start_date
ON guacamole_connection_history(start_date);
CREATE INDEX guacamole_connection_history_end_date
ON guacamole_connection_history(end_date);
CREATE INDEX guacamole_connection_history_connection_id_start_date
ON guacamole_connection_history(connection_id, start_date);
--
-- User login/logout history
--
CREATE TABLE guacamole_user_history (
history_id serial NOT NULL,
user_id integer DEFAULT NULL,
username varchar(128) NOT NULL,
remote_host varchar(256) DEFAULT NULL,
start_date timestamptz NOT NULL,
end_date timestamptz DEFAULT NULL,
PRIMARY KEY (history_id),
CONSTRAINT guacamole_user_history_ibfk_1
FOREIGN KEY (user_id)
REFERENCES guacamole_user (user_id) ON DELETE SET NULL
);
CREATE INDEX guacamole_user_history_user_id
ON guacamole_user_history(user_id);
CREATE INDEX guacamole_user_history_start_date
ON guacamole_user_history(start_date);
CREATE INDEX guacamole_user_history_end_date
ON guacamole_user_history(end_date);
CREATE INDEX guacamole_user_history_user_id_start_date
ON guacamole_user_history(user_id, start_date);
--
-- User password history
--
CREATE TABLE guacamole_user_password_history (
password_history_id serial NOT NULL,
user_id integer NOT NULL,
-- Salted password
password_hash bytea NOT NULL,
password_salt bytea,
password_date timestamptz NOT NULL,
PRIMARY KEY (password_history_id),
CONSTRAINT guacamole_user_password_history_ibfk_1
FOREIGN KEY (user_id)
REFERENCES guacamole_user (user_id) ON DELETE CASCADE
);
CREATE INDEX guacamole_user_password_history_user_id
ON guacamole_user_password_history(user_id);

View File

@@ -0,0 +1,55 @@
--
-- Licensed to the Apache Software Foundation (ASF) under one
-- or more contributor license agreements. See the NOTICE file
-- distributed with this work for additional information
-- regarding copyright ownership. The ASF licenses this file
-- to you under the Apache License, Version 2.0 (the
-- "License"); you may not use this file except in compliance
-- with the License. You may obtain a copy of the License at
--
-- http://www.apache.org/licenses/LICENSE-2.0
--
-- Unless required by applicable law or agreed to in writing,
-- software distributed under the License is distributed on an
-- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-- KIND, either express or implied. See the License for the
-- specific language governing permissions and limitations
-- under the License.
--
-- Create default user "guacadmin" with password "guacadmin"
INSERT INTO guacamole_entity (name, type) VALUES ('guacadmin', 'USER');
INSERT INTO guacamole_user (entity_id, password_hash, password_salt, password_date)
SELECT
entity_id,
decode('CA458A7D494E3BE824F5E1E175A1556C0F8EEF2C2D7DF3633BEC4A29C4411960', 'hex'), -- 'guacadmin'
decode('FE24ADC5E11E2B25288D1704ABE67A79E342ECC26064CE69C5B3177795A82264', 'hex'),
CURRENT_TIMESTAMP
FROM guacamole_entity WHERE name = 'guacadmin' AND guacamole_entity.type = 'USER';
-- Grant this user all system permissions
INSERT INTO guacamole_system_permission (entity_id, permission)
SELECT entity_id, permission::guacamole_system_permission_type
FROM (
VALUES
('guacadmin', 'CREATE_CONNECTION'),
('guacadmin', 'CREATE_CONNECTION_GROUP'),
('guacadmin', 'CREATE_SHARING_PROFILE'),
('guacadmin', 'CREATE_USER'),
('guacadmin', 'CREATE_USER_GROUP'),
('guacadmin', 'ADMINISTER')
) permissions (username, permission)
JOIN guacamole_entity ON permissions.username = guacamole_entity.name AND guacamole_entity.type = 'USER';
-- Grant admin permission to read/update/administer self
INSERT INTO guacamole_user_permission (entity_id, affected_user_id, permission)
SELECT guacamole_entity.entity_id, guacamole_user.user_id, permission::guacamole_object_permission_type
FROM (
VALUES
('guacadmin', 'guacadmin', 'READ'),
('guacadmin', 'guacadmin', 'UPDATE'),
('guacadmin', 'guacadmin', 'ADMINISTER')
) permissions (username, affected_username, permission)
JOIN guacamole_entity ON permissions.username = guacamole_entity.name AND guacamole_entity.type = 'USER'
JOIN guacamole_entity affected ON permissions.affected_username = affected.name AND guacamole_entity.type = 'USER'
JOIN guacamole_user ON guacamole_user.entity_id = affected.entity_id;

View File

@@ -0,0 +1,196 @@
--
-- Licensed to the Apache Software Foundation (ASF) under one
-- or more contributor license agreements. See the NOTICE file
-- distributed with this work for additional information
-- regarding copyright ownership. The ASF licenses this file
-- to you under the Apache License, Version 2.0 (the
-- "License"); you may not use this file except in compliance
-- with the License. You may obtain a copy of the License at
--
-- http://www.apache.org/licenses/LICENSE-2.0
--
-- Unless required by applicable law or agreed to in writing,
-- software distributed under the License is distributed on an
-- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-- KIND, either express or implied. See the License for the
-- specific language governing permissions and limitations
-- under the License.
--
--
-- User and connection IDs within history table can now be null
--
ALTER TABLE guacamole_connection_history
ALTER COLUMN user_id SET DEFAULT NULL,
ALTER COLUMN user_id DROP NOT NULL;
ALTER TABLE guacamole_connection_history
ALTER COLUMN connection_id SET DEFAULT NULL,
ALTER COLUMN connection_id DROP NOT NULL;
--
-- Add new username and connection_name columns to history table
--
ALTER TABLE guacamole_connection_history
ADD COLUMN username varchar(128);
ALTER TABLE guacamole_connection_history
ADD COLUMN connection_name varchar(128);
--
-- Populate new name columns by joining corresponding tables
--
UPDATE guacamole_connection_history
SET username = guacamole_user.username
FROM guacamole_user
WHERE guacamole_user.user_id = guacamole_connection_history.user_id;
UPDATE guacamole_connection_history
SET connection_name = guacamole_connection.connection_name
FROM guacamole_connection
WHERE guacamole_connection.connection_id =
guacamole_connection_history.connection_id;
--
-- Set NOT NULL now that the column is fully populated
--
ALTER TABLE guacamole_connection_history
ALTER COLUMN username SET NOT NULL;
ALTER TABLE guacamole_connection_history
ALTER COLUMN connection_name SET NOT NULL;
--
-- Remove old foreign key constraints with ON DELETE CASCADE
--
ALTER TABLE guacamole_connection_history
DROP CONSTRAINT guacamole_connection_history_ibfk_1;
ALTER TABLE guacamole_connection_history
DROP CONSTRAINT guacamole_connection_history_ibfk_2;
--
-- Recreate foreign key constraints with ON DELETE SET NULL
--
ALTER TABLE guacamole_connection_history
ADD CONSTRAINT guacamole_connection_history_ibfk_1
FOREIGN KEY (user_id)
REFERENCES guacamole_user (user_id) ON DELETE SET NULL;
ALTER TABLE guacamole_connection_history
ADD CONSTRAINT guacamole_connection_history_ibfk_2
FOREIGN KEY (connection_id)
REFERENCES guacamole_connection (connection_id) ON DELETE SET NULL;
--
-- Add session affinity column
--
ALTER TABLE guacamole_connection_group
ADD COLUMN enable_session_affinity boolean NOT NULL DEFAULT FALSE;
--
-- Add new system-level permission
--
ALTER TYPE guacamole_system_permission_type
ADD VALUE 'CREATE_SHARING_PROFILE'
AFTER 'CREATE_CONNECTION_GROUP';
--
-- Add sharing profile table
--
CREATE TABLE guacamole_sharing_profile (
sharing_profile_id serial NOT NULL,
sharing_profile_name varchar(128) NOT NULL,
primary_connection_id integer NOT NULL,
PRIMARY KEY (sharing_profile_id),
CONSTRAINT sharing_profile_name_primary
UNIQUE (sharing_profile_name, primary_connection_id),
CONSTRAINT guacamole_sharing_profile_ibfk_1
FOREIGN KEY (primary_connection_id)
REFERENCES guacamole_connection (connection_id)
ON DELETE CASCADE
);
CREATE INDEX guacamole_sharing_profile_primary_connection_id
ON guacamole_sharing_profile(primary_connection_id);
--
-- Add table of sharing profile parameters
--
CREATE TABLE guacamole_sharing_profile_parameter (
sharing_profile_id integer NOT NULL,
parameter_name varchar(128) NOT NULL,
parameter_value varchar(4096) NOT NULL,
PRIMARY KEY (sharing_profile_id, parameter_name),
CONSTRAINT guacamole_sharing_profile_parameter_ibfk_1
FOREIGN KEY (sharing_profile_id)
REFERENCES guacamole_sharing_profile (sharing_profile_id) ON DELETE CASCADE
);
CREATE INDEX guacamole_sharing_profile_parameter_sharing_profile_id
ON guacamole_sharing_profile_parameter(sharing_profile_id);
--
-- Object-level permission table for sharing profiles
--
CREATE TABLE guacamole_sharing_profile_permission (
user_id integer NOT NULL,
sharing_profile_id integer NOT NULL,
permission guacamole_object_permission_type NOT NULL,
PRIMARY KEY (user_id,sharing_profile_id,permission),
CONSTRAINT guacamole_sharing_profile_permission_ibfk_1
FOREIGN KEY (sharing_profile_id)
REFERENCES guacamole_sharing_profile (sharing_profile_id) ON DELETE CASCADE,
CONSTRAINT guacamole_sharing_profile_permission_ibfk_2
FOREIGN KEY (user_id)
REFERENCES guacamole_user (user_id) ON DELETE CASCADE
);
CREATE INDEX guacamole_sharing_profile_permission_sharing_profile_id
ON guacamole_sharing_profile_permission(sharing_profile_id);
CREATE INDEX guacamole_sharing_profile_permission_user_id
ON guacamole_sharing_profile_permission(user_id);
--
-- Add new (optional) sharing profile ID and name columns to connection history
--
ALTER TABLE guacamole_connection_history
ADD COLUMN sharing_profile_id integer;
ALTER TABLE guacamole_connection_history
ADD COLUMN sharing_profile_name varchar(128);
ALTER TABLE guacamole_connection_history
ADD CONSTRAINT guacamole_connection_history_ibfk_3
FOREIGN KEY (sharing_profile_id)
REFERENCES guacamole_sharing_profile (sharing_profile_id) ON DELETE SET NULL;
CREATE INDEX guacamole_connection_history_sharing_profile_id
ON guacamole_connection_history(sharing_profile_id);

View File

@@ -0,0 +1,55 @@
--
-- Licensed to the Apache Software Foundation (ASF) under one
-- or more contributor license agreements. See the NOTICE file
-- distributed with this work for additional information
-- regarding copyright ownership. The ASF licenses this file
-- to you under the Apache License, Version 2.0 (the
-- "License"); you may not use this file except in compliance
-- with the License. You may obtain a copy of the License at
--
-- http://www.apache.org/licenses/LICENSE-2.0
--
-- Unless required by applicable law or agreed to in writing,
-- software distributed under the License is distributed on an
-- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-- KIND, either express or implied. See the License for the
-- specific language governing permissions and limitations
-- under the License.
--
--
-- Add per-user password set date
--
ALTER TABLE guacamole_user
ADD COLUMN password_date timestamptz;
UPDATE guacamole_user SET password_date = CURRENT_TIMESTAMP;
ALTER TABLE guacamole_user
ALTER COLUMN password_date SET NOT NULL;
--
-- User password history
--
CREATE TABLE guacamole_user_password_history (
password_history_id serial NOT NULL,
user_id integer NOT NULL,
-- Salted password
password_hash bytea NOT NULL,
password_salt bytea,
password_date timestamptz NOT NULL,
PRIMARY KEY (password_history_id),
CONSTRAINT guacamole_user_password_history_ibfk_1
FOREIGN KEY (user_id)
REFERENCES guacamole_user (user_id) ON DELETE CASCADE
);
CREATE INDEX guacamole_user_password_history_user_id
ON guacamole_user_password_history(user_id);

View File

@@ -0,0 +1,45 @@
--
-- Licensed to the Apache Software Foundation (ASF) under one
-- or more contributor license agreements. See the NOTICE file
-- distributed with this work for additional information
-- regarding copyright ownership. The ASF licenses this file
-- to you under the Apache License, Version 2.0 (the
-- "License"); you may not use this file except in compliance
-- with the License. You may obtain a copy of the License at
--
-- http://www.apache.org/licenses/LICENSE-2.0
--
-- Unless required by applicable law or agreed to in writing,
-- software distributed under the License is distributed on an
-- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-- KIND, either express or implied. See the License for the
-- specific language governing permissions and limitations
-- under the License.
--
--
-- Add new guacd encryption method type
--
CREATE TYPE guacamole_proxy_encryption_method AS ENUM(
'NONE',
'SSL'
);
--
-- Add guacd per-connection override columns
--
ALTER TABLE guacamole_connection ADD COLUMN proxy_port integer;
ALTER TABLE guacamole_connection ADD COLUMN proxy_hostname varchar(512);
ALTER TABLE guacamole_connection ADD COLUMN proxy_encryption_method guacamole_proxy_encryption_method;
--
-- Add new user profile columns
--
ALTER TABLE guacamole_user ADD COLUMN full_name VARCHAR(256);
ALTER TABLE guacamole_user ADD COLUMN email_address VARCHAR(256);
ALTER TABLE guacamole_user ADD COLUMN organization VARCHAR(256);
ALTER TABLE guacamole_user ADD COLUMN organizational_role VARCHAR(256);

View File

@@ -0,0 +1,79 @@
--
-- Licensed to the Apache Software Foundation (ASF) under one
-- or more contributor license agreements. See the NOTICE file
-- distributed with this work for additional information
-- regarding copyright ownership. The ASF licenses this file
-- to you under the Apache License, Version 2.0 (the
-- "License"); you may not use this file except in compliance
-- with the License. You may obtain a copy of the License at
--
-- http://www.apache.org/licenses/LICENSE-2.0
--
-- Unless required by applicable law or agreed to in writing,
-- software distributed under the License is distributed on an
-- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-- KIND, either express or implied. See the License for the
-- specific language governing permissions and limitations
-- under the License.
--
--
-- Add per-connection weight
--
ALTER TABLE guacamole_connection
ADD COLUMN connection_weight int;
--
-- Add failover-only flag
--
ALTER TABLE guacamole_connection
ADD COLUMN failover_only BOOLEAN NOT NULL DEFAULT FALSE;
--
-- Add remote_host to connection history
--
ALTER TABLE guacamole_connection_history
ADD COLUMN remote_host VARCHAR(256) DEFAULT NULL;
--
-- Add covering index for connection history connection and start date
--
CREATE INDEX guacamole_connection_history_connection_id_start_date
ON guacamole_connection_history(connection_id, start_date);
--
-- User login/logout history
--
CREATE TABLE guacamole_user_history (
history_id serial NOT NULL,
user_id integer DEFAULT NULL,
username varchar(128) NOT NULL,
remote_host varchar(256) DEFAULT NULL,
start_date timestamptz NOT NULL,
end_date timestamptz DEFAULT NULL,
PRIMARY KEY (history_id),
CONSTRAINT guacamole_user_history_ibfk_1
FOREIGN KEY (user_id)
REFERENCES guacamole_user (user_id) ON DELETE SET NULL
);
CREATE INDEX guacamole_user_history_user_id
ON guacamole_user_history(user_id);
CREATE INDEX guacamole_user_history_start_date
ON guacamole_user_history(start_date);
CREATE INDEX guacamole_user_history_end_date
ON guacamole_user_history(end_date);
CREATE INDEX guacamole_user_history_user_id_start_date
ON guacamole_user_history(user_id, start_date);

View File

@@ -0,0 +1,31 @@
--
-- Licensed to the Apache Software Foundation (ASF) under one
-- or more contributor license agreements. See the NOTICE file
-- distributed with this work for additional information
-- regarding copyright ownership. The ASF licenses this file
-- to you under the Apache License, Version 2.0 (the
-- "License"); you may not use this file except in compliance
-- with the License. You may obtain a copy of the License at
--
-- http://www.apache.org/licenses/LICENSE-2.0
--
-- Unless required by applicable law or agreed to in writing,
-- software distributed under the License is distributed on an
-- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-- KIND, either express or implied. See the License for the
-- specific language governing permissions and limitations
-- under the License.
--
--
-- Add per-user disable flag
--
ALTER TABLE guacamole_user ADD COLUMN disabled boolean NOT NULL DEFAULT FALSE;
--
-- Add per-user password expiration flag
--
ALTER TABLE guacamole_user ADD COLUMN expired boolean NOT NULL DEFAULT FALSE;

View File

@@ -0,0 +1,52 @@
--
-- Licensed to the Apache Software Foundation (ASF) under one
-- or more contributor license agreements. See the NOTICE file
-- distributed with this work for additional information
-- regarding copyright ownership. The ASF licenses this file
-- to you under the Apache License, Version 2.0 (the
-- "License"); you may not use this file except in compliance
-- with the License. You may obtain a copy of the License at
--
-- http://www.apache.org/licenses/LICENSE-2.0
--
-- Unless required by applicable law or agreed to in writing,
-- software distributed under the License is distributed on an
-- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-- KIND, either express or implied. See the License for the
-- specific language governing permissions and limitations
-- under the License.
--
--
-- Add per-user time-based access restrictions.
--
ALTER TABLE guacamole_user ADD COLUMN access_window_start time;
ALTER TABLE guacamole_user ADD COLUMN access_window_end time;
--
-- Add per-user date-based account validity restrictions.
--
ALTER TABLE guacamole_user ADD COLUMN valid_from date;
ALTER TABLE guacamole_user ADD COLUMN valid_until date;
--
-- Add per-user timezone for sake of time comparisons/interpretation.
--
ALTER TABLE guacamole_user ADD COLUMN timezone varchar(64);
--
-- Add connection concurrency limits
--
ALTER TABLE guacamole_connection ADD COLUMN max_connections integer;
ALTER TABLE guacamole_connection ADD COLUMN max_connections_per_user integer;
--
-- Add connection group concurrency limits
--
ALTER TABLE guacamole_connection_group ADD COLUMN max_connections integer;
ALTER TABLE guacamole_connection_group ADD COLUMN max_connections_per_user integer;

View File

@@ -0,0 +1,32 @@
--
-- Licensed to the Apache Software Foundation (ASF) under one
-- or more contributor license agreements. See the NOTICE file
-- distributed with this work for additional information
-- regarding copyright ownership. The ASF licenses this file
-- to you under the Apache License, Version 2.0 (the
-- "License"); you may not use this file except in compliance
-- with the License. You may obtain a copy of the License at
--
-- http://www.apache.org/licenses/LICENSE-2.0
--
-- Unless required by applicable law or agreed to in writing,
-- software distributed under the License is distributed on an
-- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-- KIND, either express or implied. See the License for the
-- specific language governing permissions and limitations
-- under the License.
--
--
-- Ensure history entry start/end dates are indexed.
--
CREATE INDEX guacamole_connection_history_start_date
ON guacamole_connection_history(start_date);
CREATE INDEX guacamole_connection_history_end_date
ON guacamole_connection_history(end_date);
CREATE INDEX guacamole_connection_history_search_index
ON guacamole_connection_history(start_date, connection_id, user_id);

View File

@@ -0,0 +1,471 @@
--
-- Licensed to the Apache Software Foundation (ASF) under one
-- or more contributor license agreements. See the NOTICE file
-- distributed with this work for additional information
-- regarding copyright ownership. The ASF licenses this file
-- to you under the Apache License, Version 2.0 (the
-- "License"); you may not use this file except in compliance
-- with the License. You may obtain a copy of the License at
--
-- http://www.apache.org/licenses/LICENSE-2.0
--
-- Unless required by applicable law or agreed to in writing,
-- software distributed under the License is distributed on an
-- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-- KIND, either express or implied. See the License for the
-- specific language governing permissions and limitations
-- under the License.
--
--
-- Add new system-level permission
--
ALTER TYPE guacamole_system_permission_type
ADD VALUE 'CREATE_USER_GROUP'
AFTER 'CREATE_USER';
--
-- Entity types
--
CREATE TYPE guacamole_entity_type AS ENUM(
'USER',
'USER_GROUP'
);
--
-- Table of base entities which may each be either a user or user group. Other
-- tables which represent qualities shared by both users and groups will point
-- to guacamole_entity, while tables which represent qualities specific to
-- users or groups will point to guacamole_user or guacamole_user_group.
--
CREATE TABLE guacamole_entity (
entity_id serial NOT NULL,
name varchar(128) NOT NULL,
type guacamole_entity_type NOT NULL,
PRIMARY KEY (entity_id),
CONSTRAINT guacamole_entity_name_scope
UNIQUE (type, name)
);
--
-- Table of user groups. Each user group may have an arbitrary set of member
-- users and member groups, with those members inheriting the permissions
-- granted to that group.
--
CREATE TABLE guacamole_user_group (
user_group_id serial NOT NULL,
entity_id integer NOT NULL,
-- Group disabled status
disabled boolean NOT NULL DEFAULT FALSE,
PRIMARY KEY (user_group_id),
CONSTRAINT guacamole_user_group_single_entity
UNIQUE (entity_id),
CONSTRAINT guacamole_user_group_entity
FOREIGN KEY (entity_id)
REFERENCES guacamole_entity (entity_id)
ON DELETE CASCADE
);
--
-- Table of users which are members of given user groups.
--
CREATE TABLE guacamole_user_group_member (
user_group_id integer NOT NULL,
member_entity_id integer NOT NULL,
PRIMARY KEY (user_group_id, member_entity_id),
-- Parent must be a user group
CONSTRAINT guacamole_user_group_member_parent
FOREIGN KEY (user_group_id)
REFERENCES guacamole_user_group (user_group_id) ON DELETE CASCADE,
-- Member may be either a user or a user group (any entity)
CONSTRAINT guacamole_user_group_member_entity
FOREIGN KEY (member_entity_id)
REFERENCES guacamole_entity (entity_id) ON DELETE CASCADE
);
--
-- Table of user group permissions. Each user group permission grants a user
-- access to a particular user group for a specific type of operation.
--
CREATE TABLE guacamole_user_group_permission (
entity_id integer NOT NULL,
affected_user_group_id integer NOT NULL,
permission guacamole_object_permission_type NOT NULL,
PRIMARY KEY (entity_id, affected_user_group_id, permission),
CONSTRAINT guacamole_user_group_permission_affected_user_group
FOREIGN KEY (affected_user_group_id)
REFERENCES guacamole_user_group (user_group_id) ON DELETE CASCADE,
CONSTRAINT guacamole_user_group_permission_entity
FOREIGN KEY (entity_id)
REFERENCES guacamole_entity (entity_id) ON DELETE CASCADE
);
CREATE INDEX guacamole_user_group_permission_affected_user_group_id
ON guacamole_user_group_permission(affected_user_group_id);
CREATE INDEX guacamole_user_group_permission_entity_id
ON guacamole_user_group_permission(entity_id);
--
-- Modify guacamole_user table to use guacamole_entity as a base
--
-- Add new entity_id column
ALTER TABLE guacamole_user ADD COLUMN entity_id integer;
-- Create user entities for each guacamole_user entry
INSERT INTO guacamole_entity (name, type)
SELECT username, 'USER' FROM guacamole_user;
-- Update guacamole_user to point to corresponding guacamole_entity
UPDATE guacamole_user SET entity_id = (
SELECT entity_id FROM guacamole_entity
WHERE
username = guacamole_entity.name
AND type = 'USER'
);
-- The entity_id column should now be safely non-NULL
ALTER TABLE guacamole_user
ALTER COLUMN entity_id SET NOT NULL;
-- The entity_id column should now be unique for each user
ALTER TABLE guacamole_user
ADD CONSTRAINT guacamole_user_single_entity
UNIQUE (entity_id);
-- The entity_id column should now safely point to guacamole_entity entries
ALTER TABLE guacamole_user
ADD CONSTRAINT guacamole_user_entity
FOREIGN KEY (entity_id)
REFERENCES guacamole_entity (entity_id)
ON DELETE CASCADE;
-- The username column can now safely be removed
ALTER TABLE guacamole_user DROP COLUMN username;
--
-- Modify guacamole_connection_permission to use guacamole_entity instead of
-- guacamole_user
--
-- Add new entity_id column
ALTER TABLE guacamole_connection_permission ADD COLUMN entity_id integer;
-- Update guacamole_connection_permission to point to the guacamole_entity
-- that has been granted the permission
UPDATE guacamole_connection_permission SET entity_id = (
SELECT entity_id FROM guacamole_user
WHERE guacamole_user.user_id = guacamole_connection_permission.user_id
);
-- The entity_id column should now be safely non-NULL
ALTER TABLE guacamole_connection_permission
ALTER COLUMN entity_id SET NOT NULL;
-- The entity_id column should now safely point to guacamole_entity entries
ALTER TABLE guacamole_connection_permission
ADD CONSTRAINT guacamole_connection_permission_entity
FOREIGN KEY (entity_id)
REFERENCES guacamole_entity (entity_id)
ON DELETE CASCADE;
CREATE INDEX guacamole_connection_permission_entity_id
ON guacamole_connection_permission(entity_id);
-- Remove user_id column (implicitly drops associated contraints/keys)
ALTER TABLE guacamole_connection_permission DROP COLUMN user_id;
-- Add new primary key which uses entity_id
ALTER TABLE guacamole_connection_permission
ADD PRIMARY KEY (entity_id, connection_id, permission);
--
-- Modify guacamole_connection_group_permission to use guacamole_entity instead
-- of guacamole_user
--
-- Add new entity_id column
ALTER TABLE guacamole_connection_group_permission ADD COLUMN entity_id integer;
-- Update guacamole_connection_group_permission to point to the guacamole_entity
-- that has been granted the permission
UPDATE guacamole_connection_group_permission SET entity_id = (
SELECT entity_id FROM guacamole_user
WHERE guacamole_user.user_id = guacamole_connection_group_permission.user_id
);
-- The entity_id column should now be safely non-NULL
ALTER TABLE guacamole_connection_group_permission
ALTER COLUMN entity_id SET NOT NULL;
-- The entity_id column should now safely point to guacamole_entity entries
ALTER TABLE guacamole_connection_group_permission
ADD CONSTRAINT guacamole_connection_group_permission_entity
FOREIGN KEY (entity_id)
REFERENCES guacamole_entity (entity_id)
ON DELETE CASCADE;
CREATE INDEX guacamole_connection_group_permission_entity_id
ON guacamole_connection_group_permission(entity_id);
-- Remove user_id column (implicitly drops associated contraints/keys)
ALTER TABLE guacamole_connection_group_permission DROP COLUMN user_id;
-- Add new primary key which uses entity_id
ALTER TABLE guacamole_connection_group_permission
ADD PRIMARY KEY (entity_id, connection_group_id, permission);
--
-- Modify guacamole_sharing_profile_permission to use guacamole_entity instead
-- of guacamole_user
--
-- Add new entity_id column
ALTER TABLE guacamole_sharing_profile_permission ADD COLUMN entity_id integer;
-- Update guacamole_sharing_profile_permission to point to the guacamole_entity
-- that has been granted the permission
UPDATE guacamole_sharing_profile_permission SET entity_id = (
SELECT entity_id FROM guacamole_user
WHERE guacamole_user.user_id = guacamole_sharing_profile_permission.user_id
);
-- The entity_id column should now be safely non-NULL
ALTER TABLE guacamole_sharing_profile_permission
ALTER COLUMN entity_id SET NOT NULL;
-- The entity_id column should now safely point to guacamole_entity entries
ALTER TABLE guacamole_sharing_profile_permission
ADD CONSTRAINT guacamole_sharing_profile_permission_entity
FOREIGN KEY (entity_id)
REFERENCES guacamole_entity (entity_id)
ON DELETE CASCADE;
CREATE INDEX guacamole_sharing_profile_permission_entity_id
ON guacamole_sharing_profile_permission(entity_id);
-- Remove user_id column (implicitly drops associated contraints/keys)
ALTER TABLE guacamole_sharing_profile_permission DROP COLUMN user_id;
-- Add new primary key which uses entity_id
ALTER TABLE guacamole_sharing_profile_permission
ADD PRIMARY KEY (entity_id, sharing_profile_id, permission);
--
-- Modify guacamole_user_permission to use guacamole_entity instead of
-- guacamole_user
--
-- Add new entity_id column
ALTER TABLE guacamole_user_permission ADD COLUMN entity_id integer;
-- Update guacamole_user_permission to point to the guacamole_entity
-- that has been granted the permission
UPDATE guacamole_user_permission SET entity_id = (
SELECT entity_id FROM guacamole_user
WHERE guacamole_user.user_id = guacamole_user_permission.user_id
);
-- The entity_id column should now be safely non-NULL
ALTER TABLE guacamole_user_permission
ALTER COLUMN entity_id SET NOT NULL;
-- The entity_id column should now safely point to guacamole_entity entries
ALTER TABLE guacamole_user_permission
ADD CONSTRAINT guacamole_user_permission_entity
FOREIGN KEY (entity_id)
REFERENCES guacamole_entity (entity_id)
ON DELETE CASCADE;
CREATE INDEX guacamole_user_permission_entity_id
ON guacamole_user_permission(entity_id);
-- Remove user_id column (implicitly drops associated contraints/keys)
ALTER TABLE guacamole_user_permission DROP COLUMN user_id;
-- Add new primary key which uses entity_id
ALTER TABLE guacamole_user_permission
ADD PRIMARY KEY (entity_id, affected_user_id, permission);
--
-- Modify guacamole_system_permission to use guacamole_entity instead of
-- guacamole_user
--
-- Add new entity_id column
ALTER TABLE guacamole_system_permission ADD COLUMN entity_id integer;
-- Update guacamole_system_permission to point to the guacamole_entity
-- that has been granted the permission
UPDATE guacamole_system_permission SET entity_id = (
SELECT entity_id FROM guacamole_user
WHERE guacamole_user.user_id = guacamole_system_permission.user_id
);
-- The entity_id column should now be safely non-NULL
ALTER TABLE guacamole_system_permission
ALTER COLUMN entity_id SET NOT NULL;
-- The entity_id column should now safely point to guacamole_entity entries
ALTER TABLE guacamole_system_permission
ADD CONSTRAINT guacamole_system_permission_entity
FOREIGN KEY (entity_id)
REFERENCES guacamole_entity (entity_id)
ON DELETE CASCADE;
CREATE INDEX guacamole_system_permission_entity_id
ON guacamole_system_permission(entity_id);
-- Remove user_id column (implicitly drops associated contraints/keys)
ALTER TABLE guacamole_system_permission DROP COLUMN user_id;
-- Add new primary key which uses entity_id
ALTER TABLE guacamole_system_permission
ADD PRIMARY KEY (entity_id, permission);
--
-- Table of arbitrary user attributes. Each attribute is simply a name/value
-- pair associated with a user. Arbitrary attributes are defined by other
-- extensions. Attributes defined by this extension will be mapped to
-- properly-typed columns of a specific table.
--
CREATE TABLE guacamole_user_attribute (
user_id integer NOT NULL,
attribute_name varchar(128) NOT NULL,
attribute_value varchar(4096) NOT NULL,
PRIMARY KEY (user_id, attribute_name),
CONSTRAINT guacamole_user_attribute_ibfk_1
FOREIGN KEY (user_id)
REFERENCES guacamole_user (user_id) ON DELETE CASCADE
);
CREATE INDEX guacamole_user_attribute_user_id
ON guacamole_user_attribute(user_id);
--
-- Table of arbitrary user group attributes. Each attribute is simply a
-- name/value pair associated with a user group. Arbitrary attributes are
-- defined by other extensions. Attributes defined by this extension will be
-- mapped to properly-typed columns of a specific table.
--
CREATE TABLE guacamole_user_group_attribute (
user_group_id integer NOT NULL,
attribute_name varchar(128) NOT NULL,
attribute_value varchar(4096) NOT NULL,
PRIMARY KEY (user_group_id, attribute_name),
CONSTRAINT guacamole_user_group_attribute_ibfk_1
FOREIGN KEY (user_group_id)
REFERENCES guacamole_user_group (user_group_id) ON DELETE CASCADE
);
CREATE INDEX guacamole_user_group_attribute_user_group_id
ON guacamole_user_group_attribute(user_group_id);
--
-- Table of arbitrary connection attributes. Each attribute is simply a
-- name/value pair associated with a connection. Arbitrary attributes are
-- defined by other extensions. Attributes defined by this extension will be
-- mapped to properly-typed columns of a specific table.
--
CREATE TABLE guacamole_connection_attribute (
connection_id integer NOT NULL,
attribute_name varchar(128) NOT NULL,
attribute_value varchar(4096) NOT NULL,
PRIMARY KEY (connection_id, attribute_name),
CONSTRAINT guacamole_connection_attribute_ibfk_1
FOREIGN KEY (connection_id)
REFERENCES guacamole_connection (connection_id) ON DELETE CASCADE
);
CREATE INDEX guacamole_connection_attribute_connection_id
ON guacamole_connection_attribute(connection_id);
--
-- Table of arbitrary connection group attributes. Each attribute is simply a
-- name/value pair associated with a connection group. Arbitrary attributes are
-- defined by other extensions. Attributes defined by this extension will be
-- mapped to properly-typed columns of a specific table.
--
CREATE TABLE guacamole_connection_group_attribute (
connection_group_id integer NOT NULL,
attribute_name varchar(128) NOT NULL,
attribute_value varchar(4096) NOT NULL,
PRIMARY KEY (connection_group_id, attribute_name),
CONSTRAINT guacamole_connection_group_attribute_ibfk_1
FOREIGN KEY (connection_group_id)
REFERENCES guacamole_connection_group (connection_group_id) ON DELETE CASCADE
);
CREATE INDEX guacamole_connection_group_attribute_connection_group_id
ON guacamole_connection_group_attribute(connection_group_id);
--
-- Table of arbitrary sharing profile attributes. Each attribute is simply a
-- name/value pair associated with a sharing profile. Arbitrary attributes are
-- defined by other extensions. Attributes defined by this extension will be
-- mapped to properly-typed columns of a specific table.
--
CREATE TABLE guacamole_sharing_profile_attribute (
sharing_profile_id integer NOT NULL,
attribute_name varchar(128) NOT NULL,
attribute_value varchar(4096) NOT NULL,
PRIMARY KEY (sharing_profile_id, attribute_name),
CONSTRAINT guacamole_sharing_profile_attribute_ibfk_1
FOREIGN KEY (sharing_profile_id)
REFERENCES guacamole_sharing_profile (sharing_profile_id) ON DELETE CASCADE
);
CREATE INDEX guacamole_sharing_profile_attribute_sharing_profile_id
ON guacamole_sharing_profile_attribute(sharing_profile_id);

View File

@@ -0,0 +1,972 @@
--
-- Licensed to the Apache Software Foundation (ASF) under one
-- or more contributor license agreements. See the NOTICE file
-- distributed with this work for additional information
-- regarding copyright ownership. The ASF licenses this file
-- to you under the Apache License, Version 2.0 (the
-- "License"); you may not use this file except in compliance
-- with the License. You may obtain a copy of the License at
--
-- http://www.apache.org/licenses/LICENSE-2.0
--
-- Unless required by applicable law or agreed to in writing,
-- software distributed under the License is distributed on an
-- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-- KIND, either express or implied. See the License for the
-- specific language governing permissions and limitations
-- under the License.
--
--
-- Connection group types
--
CREATE RULE [guacamole_connection_group_type_list] AS @list IN (
'ORGANIZATIONAL',
'BALANCING'
);
GO
CREATE TYPE [guacamole_connection_group_type] FROM [nvarchar](16);
EXEC sp_bindrule
'guacamole_connection_group_type_list',
'guacamole_connection_group_type';
GO
--
-- Entity types
--
CREATE RULE [guacamole_entity_type_list] AS @list IN (
'USER',
'USER_GROUP'
);
GO
CREATE TYPE [guacamole_entity_type] FROM [nvarchar](16);
EXEC sp_bindrule
'guacamole_entity_type_list',
'guacamole_entity_type';
GO
--
-- Object permission types
--
CREATE RULE [guacamole_object_permission_list] AS @list IN (
'READ',
'UPDATE',
'DELETE',
'ADMINISTER'
);
GO
CREATE TYPE [guacamole_object_permission] FROM [nvarchar](16);
EXEC sp_bindrule
'guacamole_object_permission_list',
'guacamole_object_permission';
GO
--
-- System permission types
--
CREATE RULE [guacamole_system_permission_list] AS @list IN (
'CREATE_CONNECTION',
'CREATE_CONNECTION_GROUP',
'CREATE_SHARING_PROFILE',
'CREATE_USER',
'CREATE_USER_GROUP',
'ADMINISTER'
);
GO
CREATE TYPE [guacamole_system_permission] FROM [nvarchar](32);
EXEC sp_bindrule
'guacamole_system_permission_list',
'guacamole_system_permission';
GO
--
-- Guacamole proxy (guacd) encryption methods.
--
CREATE RULE [guacamole_proxy_encryption_method_list] AS @list IN (
'NONE',
'SSL'
);
GO
CREATE TYPE [guacamole_proxy_encryption_method] FROM [nvarchar](8);
EXEC sp_bindrule
'guacamole_proxy_encryption_method_list',
'guacamole_proxy_encryption_method';
GO
--
-- Table of connection groups. Each connection group has a name, type, and
-- optional parent connection group.
--
CREATE TABLE [guacamole_connection_group] (
[connection_group_id] [int] IDENTITY(1,1) NOT NULL,
[parent_id] [int],
[connection_group_name] [nvarchar](128) NOT NULL,
[type] [guacamole_connection_group_type]
NOT NULL DEFAULT 'ORGANIZATIONAL',
-- Concurrency limits
[max_connections] [int],
[max_connections_per_user] [int],
[enable_session_affinity] [bit] NOT NULL DEFAULT 0,
CONSTRAINT [PK_guacamole_connection_group]
PRIMARY KEY CLUSTERED ([connection_group_id]),
CONSTRAINT [AK_guacamole_connection_group_name_parent]
UNIQUE ([connection_group_name], [parent_id]),
CONSTRAINT [FK_guacamole_connection_group_parent_id]
FOREIGN KEY ([parent_id])
REFERENCES [guacamole_connection_group] ([connection_group_id])
-- ON DELETE CASCADE handled by guacamole_delete_connection_group trigger
);
CREATE NONCLUSTERED INDEX [IX_guacamole_connection_group_parent_id]
ON [guacamole_connection_group] ([parent_id]);
GO
--
-- Table of connections. Each connection has a name, protocol, and
-- associated set of parameters. A connection may belong to a connection group.
--
CREATE TABLE [guacamole_connection] (
[connection_id] [int] IDENTITY(1,1) NOT NULL,
[connection_name] [nvarchar](128) NOT NULL,
[parent_id] [int],
[protocol] [nvarchar](32) NOT NULL,
-- Concurrency limits
[max_connections] [int],
[max_connections_per_user] [int],
-- Connection Weight
[connection_weight] [int],
[failover_only] [bit] NOT NULL DEFAULT 0,
-- Guacamole proxy (guacd) overrides
[proxy_port] [int],
[proxy_hostname] [nvarchar](512),
[proxy_encryption_method] [guacamole_proxy_encryption_method],
CONSTRAINT [PK_guacamole_connection]
PRIMARY KEY CLUSTERED ([connection_id]),
CONSTRAINT [AK_guacamole_connection_name_parent]
UNIQUE ([connection_name], [parent_id]),
CONSTRAINT [FK_guacamole_connection_parent_id]
FOREIGN KEY ([parent_id])
REFERENCES [guacamole_connection_group] ([connection_group_id])
-- ON DELETE CASCADE handled by guacamole_delete_connection_group trigger
);
CREATE NONCLUSTERED INDEX [IX_guacamole_connection_parent_id]
ON [guacamole_connection] ([parent_id]);
GO
--
-- Table of base entities which may each be either a user or user group. Other
-- tables which represent qualities shared by both users and groups will point
-- to guacamole_entity, while tables which represent qualities specific to
-- users or groups will point to guacamole_user or guacamole_user_group.
--
CREATE TABLE [guacamole_entity] (
[entity_id] [int] IDENTITY(1,1) NOT NULL,
[name] [nvarchar](128) NOT NULL,
[type] [guacamole_entity_type] NOT NULL,
CONSTRAINT [PK_guacamole_entity]
PRIMARY KEY CLUSTERED ([entity_id]),
CONSTRAINT [AK_guacamole_entity_name_scope]
UNIQUE ([type], [name])
);
GO
--
-- Table of users. Each user has a unique username and a hashed password
-- with corresponding salt. Although the authentication system will always set
-- salted passwords, other systems may set unsalted passwords by simply not
-- providing the salt.
--
CREATE TABLE [guacamole_user] (
[user_id] [int] IDENTITY(1,1) NOT NULL,
[entity_id] [int] NOT NULL,
-- Optionally-salted password
[password_hash] [binary](32) NOT NULL,
[password_salt] [binary](32),
[password_date] [datetime] NOT NULL,
-- Account disabled/expired status
[disabled] [bit] NOT NULL DEFAULT 0,
[expired] [bit] NOT NULL DEFAULT 0,
-- Time-based access restriction
[access_window_start] [time](7),
[access_window_end] [time](7),
-- Date-based access restriction
[valid_from] [date],
[valid_until] [date],
-- Timezone used for all date/time comparisons and interpretation
[timezone] [nvarchar](64),
-- Profile information
[full_name] [nvarchar](256),
[email_address] [nvarchar](256),
[organization] [nvarchar](256),
[organizational_role] [nvarchar](256),
CONSTRAINT [PK_guacamole_user]
PRIMARY KEY CLUSTERED ([user_id]),
CONSTRAINT [AK_guacamole_user_single_entity]
UNIQUE ([entity_id]),
CONSTRAINT [FK_guacamole_user_entity]
FOREIGN KEY ([entity_id])
REFERENCES [guacamole_entity] ([entity_id])
ON DELETE CASCADE
);
GO
--
-- Table of user groups. Each user group may have an arbitrary set of member
-- users and member groups, with those members inheriting the permissions
-- granted to that group.
--
CREATE TABLE [guacamole_user_group] (
[user_group_id] [int] IDENTITY(1,1) NOT NULL,
[entity_id] [int] NOT NULL,
-- Group disabled status
[disabled] [bit] NOT NULL DEFAULT 0,
CONSTRAINT [PK_guacamole_user_group]
PRIMARY KEY CLUSTERED ([user_group_id]),
CONSTRAINT [guacamole_user_group_single_entity]
UNIQUE ([entity_id]),
CONSTRAINT [guacamole_user_group_entity]
FOREIGN KEY ([entity_id])
REFERENCES [guacamole_entity] ([entity_id])
ON DELETE CASCADE
);
GO
--
-- Table of users which are members of given user groups.
--
CREATE TABLE [guacamole_user_group_member] (
[user_group_id] [int] NOT NULL,
[member_entity_id] [int] NOT NULL,
CONSTRAINT [PK_guacamole_user_group_member]
PRIMARY KEY CLUSTERED ([user_group_id], [member_entity_id]),
-- Parent must be a user group
CONSTRAINT [guacamole_user_group_member_parent_id]
FOREIGN KEY ([user_group_id])
REFERENCES [guacamole_user_group] ([user_group_id])
ON DELETE CASCADE,
-- Member may be either a user or a user group (any entity)
CONSTRAINT [guacamole_user_group_member_entity_id]
FOREIGN KEY ([member_entity_id])
REFERENCES [guacamole_entity] ([entity_id])
-- ON DELETE CASCADE handled by guacamole_delete_entity trigger
);
GO
--
-- Table of sharing profiles. Each sharing profile has a name, associated set
-- of parameters, and a primary connection. The primary connection is the
-- connection that the sharing profile shares, and the parameters dictate the
-- restrictions/features which apply to the user joining the connection via the
-- sharing profile.
--
CREATE TABLE [guacamole_sharing_profile] (
[sharing_profile_id] [int] IDENTITY(1,1) NOT NULL,
[sharing_profile_name] [nvarchar](128) NOT NULL,
[primary_connection_id] [int] NOT NULL,
CONSTRAINT [PK_guacamole_sharing_profile]
PRIMARY KEY CLUSTERED ([sharing_profile_id]),
CONSTRAINT [AK_guacamole_sharing_profile_name_primary_connection]
UNIQUE ([sharing_profile_name], [primary_connection_id]),
CONSTRAINT [FK_guacamole_sharing_profile_primary_connection_id]
FOREIGN KEY ([primary_connection_id])
REFERENCES [guacamole_connection] ([connection_id])
-- ON DELETE CASCADE handled by guacamole_delete_connection trigger
);
CREATE NONCLUSTERED INDEX [IX_guacamole_sharing_profile_primary_connection_id]
ON [guacamole_sharing_profile] ([primary_connection_id]);
GO
--
-- Table of arbitrary user attributes. Each attribute is simply a name/value
-- pair associated with a user. Arbitrary attributes are defined by other
-- extensions. Attributes defined by this extension will be mapped to
-- properly-typed columns of a specific table.
--
CREATE TABLE [guacamole_user_attribute] (
[user_id] [int] NOT NULL,
[attribute_name] [nvarchar](128) NOT NULL,
[attribute_value] [nvarchar](4000) NOT NULL,
CONSTRAINT [PK_guacamole_user_attribute]
PRIMARY KEY CLUSTERED ([user_id], [attribute_name]),
CONSTRAINT [FK_guacamole_user_attribute_user_id]
FOREIGN KEY ([user_id])
REFERENCES [guacamole_user] ([user_id])
ON DELETE CASCADE
);
CREATE NONCLUSTERED INDEX [IX_guacamole_user_attribute_user_id]
ON [guacamole_user_attribute] ([user_id])
INCLUDE ([attribute_name], [attribute_value]);
GO
--
-- Table of arbitrary user group attributes. Each attribute is simply a
-- name/value pair associated with a user group. Arbitrary attributes are
-- defined by other extensions. Attributes defined by this extension will be
-- mapped to properly-typed columns of a specific table.
--
CREATE TABLE [guacamole_user_group_attribute] (
[user_group_id] [int] NOT NULL,
[attribute_name] [nvarchar](128) NOT NULL,
[attribute_value] [nvarchar](4000) NOT NULL,
CONSTRAINT [PK_guacamole_user_group_attribute]
PRIMARY KEY CLUSTERED ([user_group_id], [attribute_name]),
CONSTRAINT [FK_guacamole_user_attribute_user_group_id]
FOREIGN KEY ([user_group_id])
REFERENCES [guacamole_user_group] ([user_group_id])
ON DELETE CASCADE
);
CREATE NONCLUSTERED INDEX [IX_guacamole_user_group_attribute_user_id]
ON [guacamole_user_group_attribute] ([user_group_id])
INCLUDE ([attribute_name], [attribute_value]);
GO
--
-- Table of arbitrary connection attributes. Each attribute is simply a
-- name/value pair associated with a connection. Arbitrary attributes are
-- defined by other extensions. Attributes defined by this extension will be
-- mapped to properly-typed columns of a specific table.
--
CREATE TABLE [guacamole_connection_attribute] (
[connection_id] [int] NOT NULL,
[attribute_name] [nvarchar](128) NOT NULL,
[attribute_value] [nvarchar](4000) NOT NULL,
PRIMARY KEY (connection_id, attribute_name),
CONSTRAINT [FK_guacamole_connection_attribute_connection_id]
FOREIGN KEY ([connection_id])
REFERENCES [guacamole_connection] ([connection_id])
ON DELETE CASCADE
);
CREATE NONCLUSTERED INDEX [IX_guacamole_connection_attribute_connection_id]
ON [guacamole_connection_attribute] ([connection_id])
INCLUDE ([attribute_name], [attribute_value]);
GO
--
-- Table of arbitrary connection group attributes. Each attribute is simply a
-- name/value pair associated with a connection group. Arbitrary attributes are
-- defined by other extensions. Attributes defined by this extension will be
-- mapped to properly-typed columns of a specific table.
--
CREATE TABLE [guacamole_connection_group_attribute] (
[connection_group_id] [int] NOT NULL,
[attribute_name] [nvarchar](128) NOT NULL,
[attribute_value] [nvarchar](4000) NOT NULL,
PRIMARY KEY (connection_group_id, attribute_name),
CONSTRAINT [FK_guacamole_connection_group_attribute_connection_group_id]
FOREIGN KEY ([connection_group_id])
REFERENCES [guacamole_connection_group] ([connection_group_id])
ON DELETE CASCADE
);
CREATE NONCLUSTERED INDEX [IX_guacamole_connection_group_attribute_connection_group_id]
ON [guacamole_connection_group_attribute] ([connection_group_id])
INCLUDE ([attribute_name], [attribute_value]);
GO
--
-- Table of arbitrary sharing profile attributes. Each attribute is simply a
-- name/value pair associated with a sharing profile. Arbitrary attributes are
-- defined by other extensions. Attributes defined by this extension will be
-- mapped to properly-typed columns of a specific table.
--
CREATE TABLE [guacamole_sharing_profile_attribute] (
[sharing_profile_id] [int] NOT NULL,
[attribute_name] [nvarchar](128) NOT NULL,
[attribute_value] [nvarchar](4000) NOT NULL,
PRIMARY KEY (sharing_profile_id, attribute_name),
CONSTRAINT [FK_guacamole_sharing_profile_attribute_sharing_profile_id]
FOREIGN KEY ([sharing_profile_id])
REFERENCES [guacamole_sharing_profile] ([sharing_profile_id])
ON DELETE CASCADE
);
CREATE NONCLUSTERED INDEX [IX_guacamole_sharing_profile_attribute_sharing_profile_id]
ON [guacamole_sharing_profile_attribute] ([sharing_profile_id])
INCLUDE ([attribute_name], [attribute_value]);
GO
--
-- Table of connection parameters. Each parameter is simply a name/value pair
-- associated with a connection.
--
CREATE TABLE [guacamole_connection_parameter] (
[connection_id] [int] NOT NULL,
[parameter_name] [nvarchar](128) NOT NULL,
[parameter_value] [nvarchar](4000) NOT NULL,
CONSTRAINT [PK_guacamole_connection_parameter]
PRIMARY KEY CLUSTERED ([connection_id], [parameter_name]),
CONSTRAINT [FK_guacamole_connection_parameter_connection_id]
FOREIGN KEY ([connection_id])
REFERENCES [guacamole_connection] ([connection_id])
ON DELETE CASCADE
);
CREATE NONCLUSTERED INDEX [IX_guacamole_connection_parameter_connection_id]
ON [guacamole_connection_parameter] ([connection_id]);
GO
--
-- Table of sharing profile parameters. Each parameter is simply
-- name/value pair associated with a sharing profile. These parameters dictate
-- the restrictions/features which apply to the user joining the associated
-- connection via the sharing profile.
--
CREATE TABLE [guacamole_sharing_profile_parameter] (
[sharing_profile_id] [int] NOT NULL,
[parameter_name] [nvarchar](128) NOT NULL,
[parameter_value] [nvarchar](4000) NOT NULL,
CONSTRAINT [PK_guacamole_sharing_profile_parameter]
PRIMARY KEY CLUSTERED ([sharing_profile_id], [parameter_name]),
CONSTRAINT [FK_guacamole_sharing_profile_parameter_connection_id]
FOREIGN KEY ([sharing_profile_id])
REFERENCES [guacamole_sharing_profile] ([sharing_profile_id])
ON DELETE CASCADE
);
CREATE NONCLUSTERED INDEX [IX_guacamole_sharing_profile_parameter_sharing_profile_id]
ON [guacamole_sharing_profile_parameter] ([sharing_profile_id]);
GO
--
-- Table of connection permissions. Each connection permission grants a user or
-- user group specific access to a connection.
--
CREATE TABLE [guacamole_connection_permission] (
[entity_id] [int] NOT NULL,
[connection_id] [int] NOT NULL,
[permission] [guacamole_object_permission] NOT NULL,
CONSTRAINT [PK_guacamole_connection_permission]
PRIMARY KEY CLUSTERED ([entity_id], [connection_id], [permission]),
CONSTRAINT [FK_guacamole_connection_permission_connection_id]
FOREIGN KEY ([connection_id])
REFERENCES [guacamole_connection] ([connection_id])
ON DELETE CASCADE,
CONSTRAINT [FK_guacamole_connection_permission_entity_id]
FOREIGN KEY ([entity_id])
REFERENCES [guacamole_entity] ([entity_id])
ON DELETE CASCADE
);
CREATE NONCLUSTERED INDEX [IX_guacamole_connection_permission_connection_id]
ON [guacamole_connection_permission] ([connection_id]);
CREATE NONCLUSTERED INDEX [IX_guacamole_connection_permission_entity_id]
ON [guacamole_connection_permission] ([entity_id]);
GO
--
-- Table of connection group permissions. Each group permission grants a user
-- or user group specific access to a connection group.
--
CREATE TABLE [guacamole_connection_group_permission] (
[entity_id] [int] NOT NULL,
[connection_group_id] [int] NOT NULL,
[permission] [guacamole_object_permission] NOT NULL,
CONSTRAINT [PK_guacamole_connection_group_permission]
PRIMARY KEY CLUSTERED ([entity_id], [connection_group_id], [permission]),
CONSTRAINT [FK_guacamole_connection_group_permission_connection_group_id]
FOREIGN KEY ([connection_group_id])
REFERENCES [guacamole_connection_group] ([connection_group_id])
ON DELETE CASCADE,
CONSTRAINT [FK_guacamole_connection_group_permission_entity_id]
FOREIGN KEY ([entity_id])
REFERENCES [guacamole_entity] ([entity_id])
ON DELETE CASCADE
);
CREATE NONCLUSTERED INDEX [IX_guacamole_connection_group_permission_connection_group_id]
ON [guacamole_connection_group_permission] ([connection_group_id]);
CREATE NONCLUSTERED INDEX [IX_guacamole_connection_group_permission_entity_id]
ON [guacamole_connection_group_permission] ([entity_id]);
GO
--
-- Table of sharing profile permissions. Each sharing profile permission grants
-- a user or user group specific access to a sharing profile.
--
CREATE TABLE [guacamole_sharing_profile_permission] (
[entity_id] [int] NOT NULL,
[sharing_profile_id] [int] NOT NULL,
[permission] [guacamole_object_permission] NOT NULL,
CONSTRAINT [PK_guacamole_sharing_profile_permission]
PRIMARY KEY CLUSTERED ([entity_id], [sharing_profile_id], [permission]),
CONSTRAINT [FK_guacamole_sharing_profile_permission_sharing_profile_id]
FOREIGN KEY ([sharing_profile_id])
REFERENCES [guacamole_sharing_profile] ([sharing_profile_id])
ON DELETE CASCADE,
CONSTRAINT [FK_guacamole_sharing_profile_permission_entity_id]
FOREIGN KEY ([entity_id])
REFERENCES [guacamole_entity] ([entity_id])
ON DELETE CASCADE
);
CREATE NONCLUSTERED INDEX [IX_guacamole_sharing_profile_permission_sharing_profile_id]
ON [guacamole_sharing_profile_permission] ([sharing_profile_id]);
CREATE NONCLUSTERED INDEX [IX_guacamole_sharing_profile_permission_entity_id]
ON [guacamole_sharing_profile_permission] ([entity_id]);
GO
--
-- Table of system permissions. Each system permission grants a user or user
-- group a system-level privilege of some kind.
--
CREATE TABLE [guacamole_system_permission] (
[entity_id] [int] NOT NULL,
[permission] [guacamole_system_permission] NOT NULL,
CONSTRAINT [PK_guacamole_system_permission]
PRIMARY KEY CLUSTERED ([entity_id], [permission]),
CONSTRAINT [FK_guacamole_system_permission_entity_id]
FOREIGN KEY ([entity_id])
REFERENCES [guacamole_entity] ([entity_id])
ON DELETE CASCADE
);
CREATE NONCLUSTERED INDEX [IX_guacamole_system_permission_entity_id]
ON [guacamole_system_permission] ([entity_id]);
GO
--
-- Table of user permissions. Each user permission grants a user or user group
-- access to another user (the "affected" user) for a specific type of
-- operation.
--
CREATE TABLE [guacamole_user_permission] (
[entity_id] [int] NOT NULL,
[affected_user_id] [int] NOT NULL,
[permission] [guacamole_object_permission] NOT NULL,
CONSTRAINT [PK_guacamole_user_permission]
PRIMARY KEY CLUSTERED ([entity_id], [affected_user_id], [permission]),
CONSTRAINT [FK_guacamole_user_permission_affected_user_id]
FOREIGN KEY ([affected_user_id])
REFERENCES [guacamole_user] ([user_id])
ON DELETE CASCADE,
CONSTRAINT [FK_guacamole_user_permission_entity_id]
FOREIGN KEY ([entity_id])
REFERENCES [guacamole_entity] ([entity_id])
-- ON DELETE CASCADE handled by guacamole_delete_entity trigger
);
CREATE NONCLUSTERED INDEX [IX_guacamole_user_permission_entity_id]
ON [guacamole_user_permission] ([entity_id]);
CREATE NONCLUSTERED INDEX [IX_guacamole_user_permission_affected_user_id]
ON [guacamole_user_permission] ([affected_user_id]);
GO
--
-- Table of user group permissions. Each user group permission grants a user
-- or user group access to a another user group (the "affected" user group) for
-- a specific type of operation.
--
CREATE TABLE [guacamole_user_group_permission] (
[entity_id] [int] NOT NULL,
[affected_user_group_id] [int] NOT NULL,
[permission] [guacamole_object_permission] NOT NULL,
CONSTRAINT [PK_guacamole_user_group_permission]
PRIMARY KEY CLUSTERED ([entity_id], [affected_user_group_id], [permission]),
CONSTRAINT [FK_guacamole_user_group_permission_affected_user_group_id]
FOREIGN KEY ([affected_user_group_id])
REFERENCES [guacamole_user_group] ([user_group_id])
ON DELETE CASCADE,
CONSTRAINT [FK_guacamole_user_group_permission_entity_id]
FOREIGN KEY ([entity_id])
REFERENCES [guacamole_entity] ([entity_id])
-- ON DELETE CASCADE handled by guacamole_delete_entity trigger
);
CREATE NONCLUSTERED INDEX [IX_guacamole_user_group_permission_entity_id]
ON [guacamole_user_group_permission] ([entity_id]);
CREATE NONCLUSTERED INDEX [IX_guacamole_user_group_permission_affected_user_group_id]
ON [guacamole_user_group_permission] ([affected_user_group_id]);
GO
--
-- Table of connection history records. Each record defines a specific user's
-- session, including the connection used, the start time, and the end time
-- (if any).
--
CREATE TABLE [guacamole_connection_history] (
[history_id] [int] IDENTITY(1,1) NOT NULL,
[user_id] [int],
[username] [nvarchar](128) NOT NULL,
[remote_host] [nvarchar](256),
[connection_id] [int],
[connection_name] [nvarchar](128) NOT NULL,
[sharing_profile_id] [int],
[sharing_profile_name] [nvarchar](128),
[start_date] [datetime] NOT NULL,
[end_date] [datetime],
CONSTRAINT [PK_guacamole_connection_history]
PRIMARY KEY CLUSTERED ([history_id]),
CONSTRAINT [FK_guacamole_connection_history_user_id]
FOREIGN KEY ([user_id])
REFERENCES [guacamole_user] ([user_id])
ON DELETE SET NULL,
CONSTRAINT [FK_guacamole_connection_history_connection_id]
FOREIGN KEY ([connection_id])
REFERENCES [guacamole_connection] ([connection_id])
ON DELETE SET NULL,
CONSTRAINT [FK_guacamole_connection_history_sharing_profile_id]
FOREIGN KEY ([sharing_profile_id])
REFERENCES [guacamole_sharing_profile] ([sharing_profile_id])
-- ON DELETE SET NULL handled by guacamole_delete_sharing profile trigger
);
CREATE NONCLUSTERED INDEX [IX_guacamole_connection_history_user_id]
ON [guacamole_connection_history] ([user_id]);
CREATE NONCLUSTERED INDEX [IX_guacamole_connection_history_connection_id]
ON [guacamole_connection_history] ([connection_id]);
CREATE NONCLUSTERED INDEX [IX_guacamole_connection_history_sharing_profile_id]
ON [guacamole_connection_history] ([sharing_profile_id]);
CREATE NONCLUSTERED INDEX [IX_guacamole_connection_history_start_date]
ON [guacamole_connection_history] ([start_date]);
CREATE NONCLUSTERED INDEX [IX_guacamole_connection_history_end_date]
ON [guacamole_connection_history] ([end_date]);
CREATE NONCLUSTERED INDEX [IX_guacamole_connection_history_connection_id_start_date]
ON [guacamole_connection_history] ([connection_id], [start_date]);
GO
--
-- User login/logout history
--
CREATE TABLE [guacamole_user_history] (
[history_id] [int] IDENTITY(1,1) NOT NULL,
[user_id] [int] DEFAULT NULL,
[username] [nvarchar](128) NOT NULL,
[remote_host] [nvarchar](256) DEFAULT NULL,
[start_date] [datetime] NOT NULL,
[end_date] [datetime] DEFAULT NULL,
PRIMARY KEY (history_id),
CONSTRAINT FK_guacamole_user_history_user_id
FOREIGN KEY (user_id)
REFERENCES guacamole_user (user_id) ON DELETE SET NULL
);
CREATE NONCLUSTERED INDEX [IX_guacamole_user_history_user_id]
ON [guacamole_user_history] ([user_id]);
CREATE NONCLUSTERED INDEX [IX_guacamole_user_history_start_date]
ON [guacamole_user_history] ([start_date]);
CREATE NONCLUSTERED INDEX [IX_guacamole_user_history_end_date]
ON [guacamole_user_history] ([end_date]);
CREATE NONCLUSTERED INDEX [IX_guacamole_user_history_user_id_start_date]
ON [guacamole_user_history] ([user_id], [start_date]);
GO
--
-- The user_password_history table stores password history
-- for users, allowing for enforcing rules associated with
-- reuse of passwords.
--
CREATE TABLE [guacamole_user_password_history] (
[password_history_id] [int] IDENTITY(1,1) NOT NULL,
[user_id] [int] NOT NULL,
-- Salted password
[password_hash] [binary](32) NOT NULL,
[password_salt] [binary](32),
[password_date] [datetime] NOT NULL,
CONSTRAINT [PK_guacamole_user_password_history]
PRIMARY KEY CLUSTERED ([password_history_id]),
CONSTRAINT [FK_guacamole_user_password_history_user_id]
FOREIGN KEY ([user_id])
REFERENCES [guacamole_user] ([user_id])
ON DELETE CASCADE
);
CREATE NONCLUSTERED INDEX [IX_guacamole_user_password_history_user_id]
ON [guacamole_user_password_history] ([user_id]);
GO
--
-- Handle cascading deletion/updates of records in response to deletion of
-- guacamole_entity records, where such deletion is not already covered by
-- ON DELETE CASCADE or ON DELETE SET NULL.
--
CREATE TRIGGER [guacamole_delete_entity]
ON [guacamole_entity]
INSTEAD OF DELETE
AS BEGIN
-- Do not take trigger into account when producing row counts for the DELETE
SET NOCOUNT ON;
-- Delete all associated permissions not covered by ON DELETE CASCADE
DELETE FROM [guacamole_user_permission]
WHERE [entity_id] IN (SELECT [entity_id] FROM DELETED);
DELETE FROM [guacamole_user_group_permission]
WHERE [entity_id] IN (SELECT [entity_id] FROM DELETED);
-- Delete all associated group memberships not covered by ON DELETE CASCADE
DELETE FROM [guacamole_user_group_member]
WHERE [member_entity_id] IN (SELECT [entity_id] FROM DELETED);
-- Perform original deletion
DELETE FROM [guacamole_entity]
WHERE [entity_id] IN (SELECT [entity_id] FROM DELETED);
END
GO
--
-- Handle cascading deletion/updates of records in response to deletion of
-- guacamole_connection records, where such deletion is not already covered by
-- ON DELETE CASCADE or ON DELETE SET NULL.
--
CREATE TRIGGER [guacamole_delete_connection]
ON [guacamole_connection]
INSTEAD OF DELETE
AS BEGIN
-- Do not take trigger into account when producing row counts for the DELETE
SET NOCOUNT ON;
-- Delete associated sharing profiles
DELETE FROM [guacamole_sharing_profile]
WHERE [primary_connection_id] IN (SELECT [connection_id] FROM DELETED);
-- Perform original deletion
DELETE FROM [guacamole_connection]
WHERE [connection_id] IN (SELECT [connection_id] FROM DELETED);
END
GO
--
-- Handle cascading deletion/updates of records in response to deletion of
-- guacamole_connection_group records, where such deletion is not already
-- covered by ON DELETE CASCADE or ON DELETE SET NULL.
--
CREATE TRIGGER [guacamole_delete_connection_group]
ON [guacamole_connection_group]
INSTEAD OF DELETE
AS BEGIN
-- Do not take trigger into account when producing row counts for the DELETE
SET NOCOUNT ON;
-- Delete all descendant connections
WITH [connection_groups] ([connection_group_id]) AS (
SELECT [connection_group_id] FROM DELETED
UNION ALL
SELECT [guacamole_connection_group].[connection_group_id]
FROM [guacamole_connection_group]
JOIN [connection_groups] ON [connection_groups].[connection_group_id] = [guacamole_connection_group].[parent_id]
)
DELETE FROM [guacamole_connection]
WHERE [parent_id] IN (
SELECT [connection_group_id]
FROM [connection_groups]
);
-- Delete all requested connection groups, including descendants
WITH [connection_groups] ([connection_group_id]) AS (
SELECT [connection_group_id] FROM DELETED
UNION ALL
SELECT [guacamole_connection_group].[connection_group_id]
FROM [guacamole_connection_group]
JOIN [connection_groups] ON [connection_groups].[connection_group_id] = [guacamole_connection_group].[parent_id]
)
DELETE FROM [guacamole_connection_group]
WHERE [connection_group_id] IN (
SELECT [connection_group_id]
FROM [connection_groups]
);
END
GO
--
-- Handle cascading deletion/updates of records in response to deletion of
-- guacamole_sharing_profile records, where such deletion is not already
-- covered by ON DELETE CASCADE or ON DELETE SET NULL.
--
CREATE TRIGGER [guacamole_delete_sharing_profile]
ON [guacamole_sharing_profile]
INSTEAD OF DELETE
AS BEGIN
-- Do not take trigger into account when producing row counts for the DELETE
SET NOCOUNT ON;
-- Delete all associated permissions not covered by ON DELETE CASCADE
UPDATE [guacamole_connection_history]
SET [sharing_profile_id] = NULL
WHERE [sharing_profile_id] IN (SELECT [sharing_profile_id] FROM DELETED);
-- Perform original deletion
DELETE FROM [guacamole_sharing_profile]
WHERE [sharing_profile_id] IN (SELECT [sharing_profile_id] FROM DELETED);
END
GO

View File

@@ -0,0 +1,63 @@
--
-- Licensed to the Apache Software Foundation (ASF) under one
-- or more contributor license agreements. See the NOTICE file
-- distributed with this work for additional information
-- regarding copyright ownership. The ASF licenses this file
-- to you under the Apache License, Version 2.0 (the
-- "License"); you may not use this file except in compliance
-- with the License. You may obtain a copy of the License at
--
-- http://www.apache.org/licenses/LICENSE-2.0
--
-- Unless required by applicable law or agreed to in writing,
-- software distributed under the License is distributed on an
-- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-- KIND, either express or implied. See the License for the
-- specific language governing permissions and limitations
-- under the License.
--
-- Create default user "guacadmin" with password "guacadmin"
INSERT INTO [guacamole_entity] ([name], [type]) VALUES ('guacadmin', 'USER');
INSERT INTO [guacamole_user] (
[entity_id],
[password_hash],
[password_salt],
[password_date]
)
SELECT
[entity_id],
0xCA458A7D494E3BE824F5E1E175A1556C0F8EEF2C2D7DF3633BEC4A29C4411960,
0xFE24ADC5E11E2B25288D1704ABE67A79E342ECC26064CE69C5B3177795A82264,
getdate()
FROM [guacamole_entity] WHERE [name] = 'guacadmin';
-- Grant this user all system permissions
INSERT INTO [guacamole_system_permission]
SELECT
[entity_id],
[permission]
FROM (
SELECT 'guacadmin', 'CREATE_CONNECTION'
UNION SELECT 'guacadmin', 'CREATE_CONNECTION_GROUP'
UNION SELECT 'guacadmin', 'CREATE_SHARING_PROFILE'
UNION SELECT 'guacadmin', 'CREATE_USER'
UNION SELECT 'guacadmin', 'CREATE_USER_GROUP'
UNION SELECT 'guacadmin', 'ADMINISTER'
) [permissions] ([username], [permission])
JOIN [guacamole_entity] ON [permissions].[username] = [guacamole_entity].[name] AND [guacamole_entity].[type] = 'USER';
INSERT INTO [guacamole_user_permission]
SELECT
[guacamole_entity].[entity_id],
[guacamole_user].[user_id],
[permission]
FROM (
SELECT 'guacadmin', 'guacadmin', 'READ'
UNION SELECT 'guacadmin', 'guacadmin', 'UPDATE'
UNION SELECT 'guacadmin', 'guacadmin', 'ADMINISTER'
) [permissions] ([username], [affected_username], [permission])
JOIN [guacamole_entity] ON [permissions].[username] = [guacamole_entity].[name] AND [guacamole_entity].[type] = 'USER'
JOIN [guacamole_entity] [affected] ON [permissions].[affected_username] = [affected].[name] AND [guacamole_entity].[type] = 'USER'
JOIN [guacamole_user] ON [guacamole_user].[entity_id] = [affected].[entity_id];
GO

View File

@@ -0,0 +1,659 @@
--
-- Licensed to the Apache Software Foundation (ASF) under one
-- or more contributor license agreements. See the NOTICE file
-- distributed with this work for additional information
-- regarding copyright ownership. The ASF licenses this file
-- to you under the Apache License, Version 2.0 (the
-- "License"); you may not use this file except in compliance
-- with the License. You may obtain a copy of the License at
--
-- http://www.apache.org/licenses/LICENSE-2.0
--
-- Unless required by applicable law or agreed to in writing,
-- software distributed under the License is distributed on an
-- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-- KIND, either express or implied. See the License for the
-- specific language governing permissions and limitations
-- under the License.
--
--
-- Add new system-level permission
--
EXEC sp_unbindrule 'guacamole_system_permission';
DROP RULE [guacamole_system_permission_list];
GO
CREATE RULE [guacamole_system_permission_list] AS @list IN (
'CREATE_CONNECTION',
'CREATE_CONNECTION_GROUP',
'CREATE_SHARING_PROFILE',
'CREATE_USER',
'CREATE_USER_GROUP',
'ADMINISTER'
);
GO
EXEC sp_bindrule
'guacamole_system_permission_list',
'guacamole_system_permission';
GO
--
-- Entity types
--
CREATE RULE [guacamole_entity_type_list] AS @list IN (
'USER',
'USER_GROUP'
);
GO
CREATE TYPE [guacamole_entity_type] FROM [nvarchar](16);
EXEC sp_bindrule
'guacamole_entity_type_list',
'guacamole_entity_type';
GO
--
-- Table of base entities which may each be either a user or user group. Other
-- tables which represent qualities shared by both users and groups will point
-- to guacamole_entity, while tables which represent qualities specific to
-- users or groups will point to guacamole_user or guacamole_user_group.
--
CREATE TABLE [guacamole_entity] (
[entity_id] [int] IDENTITY(1,1) NOT NULL,
[name] [nvarchar](128) NOT NULL,
[type] [guacamole_entity_type] NOT NULL,
CONSTRAINT [PK_guacamole_entity]
PRIMARY KEY CLUSTERED ([entity_id]),
CONSTRAINT [AK_guacamole_entity_name_scope]
UNIQUE ([type], [name])
);
GO
--
-- Table of user groups. Each user group may have an arbitrary set of member
-- users and member groups, with those members inheriting the permissions
-- granted to that group.
--
CREATE TABLE [guacamole_user_group] (
[user_group_id] [int] IDENTITY(1,1) NOT NULL,
[entity_id] [int] NOT NULL,
-- Group disabled status
[disabled] [bit] NOT NULL DEFAULT 0,
CONSTRAINT [PK_guacamole_user_group]
PRIMARY KEY CLUSTERED ([user_group_id]),
CONSTRAINT [guacamole_user_group_single_entity]
UNIQUE ([entity_id]),
CONSTRAINT [guacamole_user_group_entity]
FOREIGN KEY ([entity_id])
REFERENCES [guacamole_entity] ([entity_id])
ON DELETE CASCADE
);
GO
--
-- Table of users which are members of given user groups.
--
CREATE TABLE [guacamole_user_group_member] (
[user_group_id] [int] NOT NULL,
[member_entity_id] [int] NOT NULL,
CONSTRAINT [PK_guacamole_user_group_member]
PRIMARY KEY CLUSTERED ([user_group_id], [member_entity_id]),
-- Parent must be a user group
CONSTRAINT [guacamole_user_group_member_parent_id]
FOREIGN KEY ([user_group_id])
REFERENCES [guacamole_user_group] ([user_group_id])
ON DELETE CASCADE,
-- Member may be either a user or a user group (any entity)
CONSTRAINT [guacamole_user_group_member_entity_id]
FOREIGN KEY ([member_entity_id])
REFERENCES [guacamole_entity] ([entity_id])
-- ON DELETE CASCADE handled by guacamole_delete_entity trigger
);
GO
--
-- Table of user group permissions. Each user group permission grants a user
-- or user group access to a another user group (the "affected" user group) for
-- a specific type of operation.
--
CREATE TABLE [guacamole_user_group_permission] (
[entity_id] [int] NOT NULL,
[affected_user_group_id] [int] NOT NULL,
[permission] [guacamole_object_permission] NOT NULL,
CONSTRAINT [PK_guacamole_user_group_permission]
PRIMARY KEY CLUSTERED ([entity_id], [affected_user_group_id], [permission]),
CONSTRAINT [FK_guacamole_user_group_permission_affected_user_group_id]
FOREIGN KEY ([affected_user_group_id])
REFERENCES [guacamole_user_group] ([user_group_id])
ON DELETE CASCADE,
CONSTRAINT [FK_guacamole_user_group_permission_entity_id]
FOREIGN KEY ([entity_id])
REFERENCES [guacamole_entity] ([entity_id])
-- ON DELETE CASCADE handled by guacamole_delete_entity trigger
);
CREATE NONCLUSTERED INDEX [IX_guacamole_user_group_permission_entity_id]
ON [guacamole_user_group_permission] ([entity_id]);
CREATE NONCLUSTERED INDEX [IX_guacamole_user_group_permission_affected_user_group_id]
ON [guacamole_user_group_permission] ([affected_user_group_id]);
GO
--
-- The guacamole_delete_entity trigger effectively replaces the
-- guacamole_delete_user trigger, which is no longer necessary and will cease
-- being correct after the columns of existing tables are updated.
--
DROP TRIGGER [guacamole_delete_user];
GO
--
-- Modify guacamole_user table to use guacamole_entity as a base
--
-- Add new entity_id column
ALTER TABLE [guacamole_user] ADD [entity_id] [int];
GO
-- Create user entities for each guacamole_user entry
INSERT INTO [guacamole_entity] ([name], [type])
SELECT [username], 'USER' FROM [guacamole_user];
GO
-- Update guacamole_user to point to corresponding guacamole_entity
UPDATE [guacamole_user] SET [entity_id] = (
SELECT [entity_id] FROM [guacamole_entity]
WHERE
[username] = [guacamole_entity].[name]
AND type = 'USER'
);
GO
-- The entity_id column should now be safely non-NULL
ALTER TABLE [guacamole_user]
ALTER COLUMN [entity_id] [int] NOT NULL;
-- The entity_id column should now be unique for each user
ALTER TABLE [guacamole_user]
ADD CONSTRAINT [AK_guacamole_user_single_entity]
UNIQUE ([entity_id]);
-- The entity_id column should now safely point to guacamole_entity entries
ALTER TABLE [guacamole_user]
ADD CONSTRAINT [FK_guacamole_user_entity]
FOREIGN KEY ([entity_id])
REFERENCES [guacamole_entity] ([entity_id])
ON DELETE CASCADE;
-- The username column can now safely be removed
ALTER TABLE [guacamole_user] DROP [AK_guacamole_user_username];
ALTER TABLE [guacamole_user] DROP COLUMN [username];
GO
--
-- Modify guacamole_connection_permission to use guacamole_entity instead of
-- guacamole_user
--
-- Add new entity_id column
ALTER TABLE [guacamole_connection_permission] ADD [entity_id] [int];
GO
-- Update guacamole_connection_permission to point to the guacamole_entity
-- that has been granted the permission
UPDATE [guacamole_connection_permission] SET [entity_id] = (
SELECT [entity_id] FROM [guacamole_user]
WHERE [guacamole_user].[user_id] = [guacamole_connection_permission].[user_id]
);
GO
-- The entity_id column should now be safely non-NULL
ALTER TABLE [guacamole_connection_permission]
ALTER COLUMN [entity_id] [int] NOT NULL;
-- Remove user_id column
DROP INDEX [IX_guacamole_connection_permission_user_id] ON [guacamole_connection_permission];
ALTER TABLE [guacamole_connection_permission] DROP [PK_guacamole_connection_permission];
ALTER TABLE [guacamole_connection_permission] DROP [FK_guacamole_connection_permission_user_id];
ALTER TABLE [guacamole_connection_permission] DROP COLUMN [user_id];
-- The entity_id column should now safely point to guacamole_entity entries
ALTER TABLE [guacamole_connection_permission]
ADD CONSTRAINT [FK_guacamole_connection_permission_entity_id]
FOREIGN KEY ([entity_id])
REFERENCES [guacamole_entity] ([entity_id])
ON DELETE CASCADE;
CREATE NONCLUSTERED INDEX [IX_guacamole_connection_permission_entity_id]
ON [guacamole_connection_permission] ([entity_id]);
-- Add new primary key which uses entity_id
ALTER TABLE [guacamole_connection_permission]
ADD CONSTRAINT [PK_guacamole_connection_permission]
PRIMARY KEY CLUSTERED ([entity_id], [connection_id], [permission]);
GO
--
-- Modify guacamole_connection_group_permission to use guacamole_entity instead
-- of guacamole_user
--
-- Add new entity_id column
ALTER TABLE [guacamole_connection_group_permission] ADD [entity_id] [int];
GO
-- Update guacamole_connection_group_permission to point to the guacamole_entity
-- that has been granted the permission
UPDATE guacamole_connection_group_permission SET entity_id = (
SELECT entity_id FROM guacamole_user
WHERE guacamole_user.user_id = guacamole_connection_group_permission.user_id
);
GO
-- The entity_id column should now be safely non-NULL
ALTER TABLE [guacamole_connection_group_permission]
ALTER COLUMN [entity_id] [int] NOT NULL;
-- Remove user_id column
DROP INDEX [IX_guacamole_connection_group_permission_user_id] ON [guacamole_connection_group_permission];
ALTER TABLE [guacamole_connection_group_permission] DROP [PK_guacamole_connection_group_permission];
ALTER TABLE [guacamole_connection_group_permission] DROP [FK_guacamole_connection_group_permission_user_id];
ALTER TABLE [guacamole_connection_group_permission] DROP COLUMN user_id;
-- The entity_id column should now safely point to guacamole_entity entries
ALTER TABLE [guacamole_connection_group_permission]
ADD CONSTRAINT [FK_guacamole_connection_group_permission_entity_id]
FOREIGN KEY ([entity_id])
REFERENCES [guacamole_entity] ([entity_id])
ON DELETE CASCADE;
CREATE NONCLUSTERED INDEX [IX_guacamole_connection_group_permission_entity_id]
ON [guacamole_connection_group_permission] ([entity_id]);
-- Add new primary key which uses entity_id
ALTER TABLE [guacamole_connection_group_permission]
ADD CONSTRAINT [PK_guacamole_connection_group_permission]
PRIMARY KEY CLUSTERED ([entity_id], [connection_group_id], [permission]);
GO
--
-- Modify guacamole_sharing_profile_permission to use guacamole_entity instead
-- of guacamole_user
--
-- Add new entity_id column
ALTER TABLE [guacamole_sharing_profile_permission] ADD [entity_id] [int];
GO
-- Update guacamole_sharing_profile_permission to point to the guacamole_entity
-- that has been granted the permission
UPDATE guacamole_sharing_profile_permission SET entity_id = (
SELECT entity_id FROM guacamole_user
WHERE guacamole_user.user_id = guacamole_sharing_profile_permission.user_id
);
GO
-- The entity_id column should now be safely non-NULL
ALTER TABLE [guacamole_sharing_profile_permission]
ALTER COLUMN [entity_id] [int] NOT NULL;
-- Remove user_id column
DROP INDEX [IX_guacamole_sharing_profile_permission_user_id] ON [guacamole_sharing_profile_permission];
ALTER TABLE [guacamole_sharing_profile_permission] DROP [PK_guacamole_sharing_profile_permission];
ALTER TABLE [guacamole_sharing_profile_permission] DROP [FK_guacamole_sharing_profile_permission_user_id];
ALTER TABLE [guacamole_sharing_profile_permission] DROP COLUMN user_id;
-- The entity_id column should now safely point to guacamole_entity entries
ALTER TABLE [guacamole_sharing_profile_permission]
ADD CONSTRAINT [FK_guacamole_sharing_profile_permission_entity_id]
FOREIGN KEY ([entity_id])
REFERENCES [guacamole_entity] ([entity_id])
ON DELETE CASCADE;
CREATE NONCLUSTERED INDEX [IX_guacamole_sharing_profile_permission_entity_id]
ON [guacamole_sharing_profile_permission] ([entity_id]);
-- Add new primary key which uses entity_id
ALTER TABLE [guacamole_sharing_profile_permission]
ADD CONSTRAINT [PK_guacamole_sharing_profile_permission]
PRIMARY KEY CLUSTERED ([entity_id], [sharing_profile_id], [permission]);
GO
--
-- Modify guacamole_user_permission to use guacamole_entity instead of
-- guacamole_user
--
-- Add new entity_id column
ALTER TABLE [guacamole_user_permission] ADD [entity_id] [int];
GO
-- Update guacamole_user_permission to point to the guacamole_entity
-- that has been granted the permission
UPDATE guacamole_user_permission SET entity_id = (
SELECT entity_id FROM guacamole_user
WHERE guacamole_user.user_id = guacamole_user_permission.user_id
);
GO
-- The entity_id column should now be safely non-NULL
ALTER TABLE [guacamole_user_permission]
ALTER COLUMN [entity_id] [int] NOT NULL;
-- The entity_id column should now safely point to guacamole_entity entries
ALTER TABLE [guacamole_user_permission]
ADD CONSTRAINT [FK_guacamole_user_permission_entity_id]
FOREIGN KEY ([entity_id])
REFERENCES [guacamole_entity] ([entity_id]);
-- ON DELETE CASCADE handled by guacamole_delete_entity trigger
-- The affected_user_id column now has ON DELETE CASCADE
ALTER TABLE [guacamole_user_permission] DROP [FK_guacamole_user_permission_affected_user_id];
ALTER TABLE [guacamole_user_permission]
ADD CONSTRAINT [FK_guacamole_user_permission_affected_user_id]
FOREIGN KEY ([affected_user_id])
REFERENCES [guacamole_user] ([user_id])
ON DELETE CASCADE;
CREATE NONCLUSTERED INDEX [IX_guacamole_user_permission_entity_id]
ON [guacamole_user_permission] ([entity_id]);
-- Remove user_id column
DROP INDEX [IX_guacamole_user_permission_user_id] ON [guacamole_user_permission];
ALTER TABLE [guacamole_user_permission] DROP [PK_guacamole_user_permission];
ALTER TABLE [guacamole_user_permission] DROP [FK_guacamole_user_permission_user_id];
ALTER TABLE [guacamole_user_permission] DROP COLUMN user_id;
-- Add new primary key which uses entity_id
ALTER TABLE [guacamole_user_permission]
ADD CONSTRAINT [PK_guacamole_user_permission]
PRIMARY KEY CLUSTERED ([entity_id], [affected_user_id], [permission]);
GO
--
-- Modify guacamole_system_permission to use guacamole_entity instead of
-- guacamole_user
--
-- Add new entity_id column
ALTER TABLE [guacamole_system_permission] ADD [entity_id] [int];
GO
-- Update guacamole_system_permission to point to the guacamole_entity
-- that has been granted the permission
UPDATE [guacamole_system_permission] SET [entity_id] = (
SELECT [entity_id] FROM [guacamole_user]
WHERE [guacamole_user].[user_id] = [guacamole_system_permission].[user_id]
);
GO
-- The entity_id column should now be safely non-NULL
ALTER TABLE [guacamole_system_permission]
ALTER COLUMN [entity_id] [int] NOT NULL;
-- Remove user_id column
DROP INDEX [IX_guacamole_system_permission_user_id] ON [guacamole_system_permission];
ALTER TABLE [guacamole_system_permission] DROP [PK_guacamole_system_permission];
ALTER TABLE [guacamole_system_permission] DROP [FK_guacamole_system_permission_user_id];
ALTER TABLE [guacamole_system_permission] DROP COLUMN [user_id];
-- The entity_id column should now safely point to guacamole_entity entries
ALTER TABLE [guacamole_system_permission]
ADD CONSTRAINT [FK_guacamole_system_permission_entity_id]
FOREIGN KEY ([entity_id])
REFERENCES [guacamole_entity] ([entity_id])
ON DELETE CASCADE;
CREATE NONCLUSTERED INDEX [IX_guacamole_system_permission_entity_id]
ON [guacamole_system_permission] ([entity_id]);
-- Add new primary key which uses entity_id
ALTER TABLE [guacamole_system_permission]
ADD CONSTRAINT [PK_guacamole_system_permission]
PRIMARY KEY CLUSTERED ([entity_id], [permission]);
GO
--
-- Handle cascading deletion/updates of records in response to deletion of
-- guacamole_entity records, where such deletion is not already covered by
-- ON DELETE CASCADE or ON DELETE SET NULL.
--
CREATE TRIGGER [guacamole_delete_entity]
ON [guacamole_entity]
INSTEAD OF DELETE
AS BEGIN
-- Do not take trigger into account when producing row counts for the DELETE
SET NOCOUNT ON;
-- Delete all associated permissions not covered by ON DELETE CASCADE
DELETE FROM [guacamole_user_permission]
WHERE [entity_id] IN (SELECT [entity_id] FROM DELETED);
DELETE FROM [guacamole_user_group_permission]
WHERE [entity_id] IN (SELECT [entity_id] FROM DELETED);
-- Delete all associated group memberships not covered by ON DELETE CASCADE
DELETE FROM [guacamole_user_group_member]
WHERE [member_entity_id] IN (SELECT [entity_id] FROM DELETED);
-- Perform original deletion
DELETE FROM [guacamole_entity]
WHERE [entity_id] IN (SELECT [entity_id] FROM DELETED);
END
GO
--
-- Update guacamole_delete_connection_group trigger to remove descendant
-- connections first.
--
DROP TRIGGER [guacamole_delete_connection_group];
GO
CREATE TRIGGER [guacamole_delete_connection_group]
ON [guacamole_connection_group]
INSTEAD OF DELETE
AS BEGIN
-- Do not take trigger into account when producing row counts for the DELETE
SET NOCOUNT ON;
-- Delete all descendant connections
WITH [connection_groups] ([connection_group_id]) AS (
SELECT [connection_group_id] FROM DELETED
UNION ALL
SELECT [guacamole_connection_group].[connection_group_id]
FROM [guacamole_connection_group]
JOIN [connection_groups] ON [connection_groups].[connection_group_id] = [guacamole_connection_group].[parent_id]
)
DELETE FROM [guacamole_connection]
WHERE [parent_id] IN (
SELECT [connection_group_id]
FROM [connection_groups]
);
-- Delete all requested connection groups, including descendants
WITH [connection_groups] ([connection_group_id]) AS (
SELECT [connection_group_id] FROM DELETED
UNION ALL
SELECT [guacamole_connection_group].[connection_group_id]
FROM [guacamole_connection_group]
JOIN [connection_groups] ON [connection_groups].[connection_group_id] = [guacamole_connection_group].[parent_id]
)
DELETE FROM [guacamole_connection_group]
WHERE [connection_group_id] IN (
SELECT [connection_group_id]
FROM [connection_groups]
);
END
GO
--
-- Table of arbitrary user attributes. Each attribute is simply a name/value
-- pair associated with a user. Arbitrary attributes are defined by other
-- extensions. Attributes defined by this extension will be mapped to
-- properly-typed columns of a specific table.
--
CREATE TABLE [guacamole_user_attribute] (
[user_id] [int] NOT NULL,
[attribute_name] [nvarchar](128) NOT NULL,
[attribute_value] [nvarchar](4000) NOT NULL,
CONSTRAINT [PK_guacamole_user_attribute]
PRIMARY KEY CLUSTERED ([user_id], [attribute_name]),
CONSTRAINT [FK_guacamole_user_attribute_user_id]
FOREIGN KEY ([user_id])
REFERENCES [guacamole_user] ([user_id])
ON DELETE CASCADE
);
CREATE NONCLUSTERED INDEX [IX_guacamole_user_attribute_user_id]
ON [guacamole_user_attribute] ([user_id])
INCLUDE ([attribute_name], [attribute_value]);
GO
--
-- Table of arbitrary user group attributes. Each attribute is simply a
-- name/value pair associated with a user group. Arbitrary attributes are
-- defined by other extensions. Attributes defined by this extension will be
-- mapped to properly-typed columns of a specific table.
--
CREATE TABLE [guacamole_user_group_attribute] (
[user_group_id] [int] NOT NULL,
[attribute_name] [nvarchar](128) NOT NULL,
[attribute_value] [nvarchar](4000) NOT NULL,
CONSTRAINT [PK_guacamole_user_group_attribute]
PRIMARY KEY CLUSTERED ([user_group_id], [attribute_name]),
CONSTRAINT [FK_guacamole_user_attribute_user_group_id]
FOREIGN KEY ([user_group_id])
REFERENCES [guacamole_user_group] ([user_group_id])
ON DELETE CASCADE
);
CREATE NONCLUSTERED INDEX [IX_guacamole_user_group_attribute_user_id]
ON [guacamole_user_group_attribute] ([user_group_id])
INCLUDE ([attribute_name], [attribute_value]);
GO
--
-- Table of arbitrary connection attributes. Each attribute is simply a
-- name/value pair associated with a connection. Arbitrary attributes are
-- defined by other extensions. Attributes defined by this extension will be
-- mapped to properly-typed columns of a specific table.
--
CREATE TABLE [guacamole_connection_attribute] (
[connection_id] [int] NOT NULL,
[attribute_name] [nvarchar](128) NOT NULL,
[attribute_value] [nvarchar](4000) NOT NULL,
PRIMARY KEY (connection_id, attribute_name),
CONSTRAINT [FK_guacamole_connection_attribute_connection_id]
FOREIGN KEY ([connection_id])
REFERENCES [guacamole_connection] ([connection_id])
ON DELETE CASCADE
);
CREATE NONCLUSTERED INDEX [IX_guacamole_connection_attribute_connection_id]
ON [guacamole_connection_attribute] ([connection_id])
INCLUDE ([attribute_name], [attribute_value]);
GO
--
-- Table of arbitrary connection group attributes. Each attribute is simply a
-- name/value pair associated with a connection group. Arbitrary attributes are
-- defined by other extensions. Attributes defined by this extension will be
-- mapped to properly-typed columns of a specific table.
--
CREATE TABLE [guacamole_connection_group_attribute] (
[connection_group_id] [int] NOT NULL,
[attribute_name] [nvarchar](128) NOT NULL,
[attribute_value] [nvarchar](4000) NOT NULL,
PRIMARY KEY (connection_group_id, attribute_name),
CONSTRAINT [FK_guacamole_connection_group_attribute_connection_group_id]
FOREIGN KEY ([connection_group_id])
REFERENCES [guacamole_connection_group] ([connection_group_id])
ON DELETE CASCADE
);
CREATE NONCLUSTERED INDEX [IX_guacamole_connection_group_attribute_connection_group_id]
ON [guacamole_connection_group_attribute] ([connection_group_id])
INCLUDE ([attribute_name], [attribute_value]);
GO
--
-- Table of arbitrary sharing profile attributes. Each attribute is simply a
-- name/value pair associated with a sharing profile. Arbitrary attributes are
-- defined by other extensions. Attributes defined by this extension will be
-- mapped to properly-typed columns of a specific table.
--
CREATE TABLE [guacamole_sharing_profile_attribute] (
[sharing_profile_id] [int] NOT NULL,
[attribute_name] [nvarchar](128) NOT NULL,
[attribute_value] [nvarchar](4000) NOT NULL,
PRIMARY KEY (sharing_profile_id, attribute_name),
CONSTRAINT [FK_guacamole_sharing_profile_attribute_sharing_profile_id]
FOREIGN KEY ([sharing_profile_id])
REFERENCES [guacamole_sharing_profile] ([sharing_profile_id])
ON DELETE CASCADE
);
CREATE NONCLUSTERED INDEX [IX_guacamole_sharing_profile_attribute_sharing_profile_id]
ON [guacamole_sharing_profile_attribute] ([sharing_profile_id])
INCLUDE ([attribute_name], [attribute_value]);
GO