Skip to content

Commit

Permalink
Fix error printout on correct security label
Browse files Browse the repository at this point in the history
For all security labels from provider `timescaledb` an error was
printed, which make `pg_restore` fail because the security labels are
printed to the dump.

Instead, we only print an error if the security label is not of the
correct format.

Fixes #3760
  • Loading branch information
mkindahl committed Nov 15, 2021
1 parent e4ec15d commit 5d22a56
Show file tree
Hide file tree
Showing 3 changed files with 187 additions and 5 deletions.
53 changes: 52 additions & 1 deletion src/loader/loader.c
Original file line number Diff line number Diff line change
Expand Up @@ -470,6 +470,44 @@ post_analyze_hook(ParseState *pstate, Query *query, JumbleState *jstate)
}
}

/*
* Simplified check if a string is an UUID.
*
* This assumes that the UUID is a string consisting of dash-separated
* hexadecimal numbers and the string of of exact length 36 characters,
* containing 4 dashes, and with groups of digits of the size 8-4-4-4-12.
*/
static bool
is_uuid(const char *str)
{
int digits = 0;
int hyphens = 0;
size_t lengths[] = { 8, 4, 4, 4, 12 };

if (strlen(str) != 36)
return false;
for (; *str; ++str)
{
if (!isxdigit(*str) && *str != '-')
return false;
if (hyphens > sizeof(lengths) / sizeof(*lengths) ||
(*str == '-' && digits != lengths[hyphens]))
{
return false;
}
if (*str == '-')
{
digits = 0;
++hyphens;
}
else
{
++digits;
}
}
return (hyphens == 4);
}

static void
loader_process_utility_hook(PlannedStmt *pstmt, const char *query_string,
#if PG14_GE
Expand Down Expand Up @@ -505,8 +543,21 @@ loader_process_utility_hook(PlannedStmt *pstmt, const char *query_string,
{
SecLabelStmt *stmt = castNode(SecLabelStmt, pstmt->utilityStmt);

/*
* Since this statement can be in a dump output, we only print an
* error on anything that doesn't looks like a sane distributed
* UUID.
*/
if (stmt->provider && strcmp(stmt->provider, SECLABEL_DIST_PROVIDER) == 0)
ereport(ERROR, (errmsg("TimescaleDB label is for internal use only")));
{
const char *uuid = strchr(stmt->label, SECLABEL_DIST_TAG_SEPARATOR);
if (!uuid || strncmp(stmt->label, SECLABEL_DIST_TAG, uuid - stmt->label) != 0 ||
!is_uuid(&uuid[1]))
ereport(ERROR,
(errmsg("TimescaleDB label is for internal use only"),
errdetail("Security label is \"%s\".", stmt->label),
errhint("Security label has to be of format \"dist_uuid:<UUID>\".")));
}
break;
}
default:
Expand Down
87 changes: 85 additions & 2 deletions tsl/test/expected/data_node_bootstrap.out
Original file line number Diff line number Diff line change
Expand Up @@ -452,12 +452,95 @@ SELECT substr(label, 0, 10) || ':uuid'
(1 row)

\c :TEST_DBNAME :ROLE_CLUSTER_SUPERUSER;
-- Check that timescaledb security label cannot be used directly
-- Check that timescaledb security label cannot be used directly. To
-- support pg_dump, we do not print an error when a proper label is
-- used, but print an error if something that doesn't look like a
-- distributed uuid is used.
SECURITY LABEL FOR timescaledb
ON DATABASE drop_db_test
IS 'dist_uuid:4ab3b1bc-438f-11ec-8919-23804e22321a';
\set ON_ERROR_STOP 0
\set VERBOSITY default
-- No colon
SECURITY LABEL FOR timescaledb
ON DATABASE drop_db_test
IS 'bad_label';
ERROR: TimescaleDB label is for internal use only
DETAIL: Security label is "bad_label".
HINT: Security label has to be of format "dist_uuid:<UUID>".
-- Bad tag, but still an UUID
SECURITY LABEL FOR timescaledb
ON DATABASE drop_db_test
IS 'uuid:4ab3b1bc-438f-11ec-8919-23804e22321a';
ERROR: TimescaleDB label is for internal use only
DETAIL: Security label is "uuid:4ab3b1bc-438f-11ec-8919-23804e22321a".
HINT: Security label has to be of format "dist_uuid:<UUID>".
-- Length is not correct
SECURITY LABEL FOR timescaledb
ON DATABASE drop_db_test
IS 'dist_uuid:4ab3b1bcd-438f-11ec-8919-23804e2232';
ERROR: TimescaleDB label is for internal use only
DETAIL: Security label is "dist_uuid:4ab3b1bcd-438f-11ec-8919-23804e2232".
HINT: Security label has to be of format "dist_uuid:<UUID>".
SECURITY LABEL FOR timescaledb
ON DATABASE drop_db_test
IS 'dist_uuid:4ab3b1bcd-438f-11ec-8919-23804e223215';
ERROR: TimescaleDB label is for internal use only
DETAIL: Security label is "dist_uuid:4ab3b1bcd-438f-11ec-8919-23804e223215".
HINT: Security label has to be of format "dist_uuid:<UUID>".
-- Length is correct, but it contains something that is not a
-- hexadecimal digit.
SECURITY LABEL FOR timescaledb
ON DATABASE drop_db_test
IS 'dist_uuid:4ab3b1bcd-4x8f-11ec-8919-23804e22321';
ERROR: TimescaleDB label is for internal use only
DETAIL: Security label is "dist_uuid:4ab3b1bcd-4x8f-11ec-8919-23804e22321".
HINT: Security label has to be of format "dist_uuid:<UUID>".
-- Total length is correct, but not the right number of hyphens.
SECURITY LABEL FOR timescaledb
ON DATABASE drop_db_test
IS 'dist_uuid:4ab3-1bcd-438f-11ec-8919-23804e22321';
ERROR: TimescaleDB label is for internal use only
DETAIL: Security label is "dist_uuid:4ab3-1bcd-438f-11ec-8919-23804e22321".
HINT: Security label has to be of format "dist_uuid:<UUID>".
SECURITY LABEL FOR timescaledb
ON DATABASE drop_db_test
IS 'dist_uuid:4ab3b1bcd438f-11ec-8919-23804e223213';
ERROR: TimescaleDB label is for internal use only
DETAIL: Security label is "dist_uuid:4ab3b1bcd438f-11ec-8919-23804e223213".
HINT: Security label has to be of format "dist_uuid:<UUID>".
-- Total length is correct, but length of groups is not
SECURITY LABEL FOR timescaledb
ON DATABASE drop_db_test
IS 'dist_uuid:4ab3b1bcd-438f-11ec-8919-23804e22321';
ERROR: TimescaleDB label is for internal use only
DETAIL: Security label is "dist_uuid:4ab3b1bcd-438f-11ec-8919-23804e22321".
HINT: Security label has to be of format "dist_uuid:<UUID>".
SECURITY LABEL FOR timescaledb
ON DATABASE drop_db_test
IS 'dist_uuid:4ab3b1bc-438f-11ec-891-23804e22321ab';
ERROR: TimescaleDB label is for internal use only
DETAIL: Security label is "dist_uuid:4ab3b1bc-438f-11ec-891-23804e22321ab".
HINT: Security label has to be of format "dist_uuid:<UUID>".
SECURITY LABEL FOR timescaledb
ON DATABASE drop_db_test
IS 'dist_uuid:4ab3b1bc-438f-11e-8919-23804e22321ab';
ERROR: TimescaleDB label is for internal use only
DETAIL: Security label is "dist_uuid:4ab3b1bc-438f-11e-8919-23804e22321ab".
HINT: Security label has to be of format "dist_uuid:<UUID>".
SECURITY LABEL FOR timescaledb
ON DATABASE drop_db_test
IS 'dist_uuid:4ab3b1bc-438-11ec-8919-23804e22321ab';
ERROR: TimescaleDB label is for internal use only
DETAIL: Security label is "dist_uuid:4ab3b1bc-438-11ec-8919-23804e22321ab".
HINT: Security label has to be of format "dist_uuid:<UUID>".
SECURITY LABEL FOR timescaledb
ON DATABASE drop_db_test
IS 'dist_uuid:00000000-0000-0000-0000-00000000000';
IS 'dist_uuid:4ab3b1bca-438f-11ec-8919-23804e22321';
ERROR: TimescaleDB label is for internal use only
DETAIL: Security label is "dist_uuid:4ab3b1bca-438f-11ec-8919-23804e22321".
HINT: Security label has to be of format "dist_uuid:<UUID>".
\set VERBOSITY terse
\set ON_ERROR_STOP 1
-- Check that security label functionality is working
CREATE TABLE seclabel_test(id int);
Expand Down
52 changes: 50 additions & 2 deletions tsl/test/sql/data_node_bootstrap.sql
Original file line number Diff line number Diff line change
Expand Up @@ -358,11 +358,59 @@ SELECT substr(label, 0, 10) || ':uuid'

\c :TEST_DBNAME :ROLE_CLUSTER_SUPERUSER;

-- Check that timescaledb security label cannot be used directly
-- Check that timescaledb security label cannot be used directly. To
-- support pg_dump, we do not print an error when a proper label is
-- used, but print an error if something that doesn't look like a
-- distributed uuid is used.
SECURITY LABEL FOR timescaledb
ON DATABASE drop_db_test
IS 'dist_uuid:4ab3b1bc-438f-11ec-8919-23804e22321a';
\set ON_ERROR_STOP 0
\set VERBOSITY default
-- No colon
SECURITY LABEL FOR timescaledb
ON DATABASE drop_db_test
IS 'bad_label';
-- Bad tag, but still an UUID
SECURITY LABEL FOR timescaledb
ON DATABASE drop_db_test
IS 'uuid:4ab3b1bc-438f-11ec-8919-23804e22321a';
-- Length is not correct
SECURITY LABEL FOR timescaledb
ON DATABASE drop_db_test
IS 'dist_uuid:4ab3b1bcd-438f-11ec-8919-23804e2232';
SECURITY LABEL FOR timescaledb
ON DATABASE drop_db_test
IS 'dist_uuid:4ab3b1bcd-438f-11ec-8919-23804e223215';
-- Length is correct, but it contains something that is not a
-- hexadecimal digit.
SECURITY LABEL FOR timescaledb
ON DATABASE drop_db_test
IS 'dist_uuid:4ab3b1bcd-4x8f-11ec-8919-23804e22321';
-- Total length is correct, but not the right number of hyphens.
SECURITY LABEL FOR timescaledb
ON DATABASE drop_db_test
IS 'dist_uuid:4ab3-1bcd-438f-11ec-8919-23804e22321';
SECURITY LABEL FOR timescaledb
ON DATABASE drop_db_test
IS 'dist_uuid:4ab3b1bcd438f-11ec-8919-23804e223213';
-- Total length is correct, but length of groups is not
SECURITY LABEL FOR timescaledb
ON DATABASE drop_db_test
IS 'dist_uuid:4ab3b1bcd-438f-11ec-8919-23804e22321';
SECURITY LABEL FOR timescaledb
ON DATABASE drop_db_test
IS 'dist_uuid:4ab3b1bc-438f-11ec-891-23804e22321ab';
SECURITY LABEL FOR timescaledb
ON DATABASE drop_db_test
IS 'dist_uuid:4ab3b1bc-438f-11e-8919-23804e22321ab';
SECURITY LABEL FOR timescaledb
ON DATABASE drop_db_test
IS 'dist_uuid:4ab3b1bc-438-11ec-8919-23804e22321ab';
SECURITY LABEL FOR timescaledb
ON DATABASE drop_db_test
IS 'dist_uuid:00000000-0000-0000-0000-00000000000';
IS 'dist_uuid:4ab3b1bca-438f-11ec-8919-23804e22321';
\set VERBOSITY terse
\set ON_ERROR_STOP 1

-- Check that security label functionality is working
Expand Down

0 comments on commit 5d22a56

Please sign in to comment.