diff options
Diffstat (limited to 'src/bin')
-rw-r--r-- | src/bin/pg_dump/dumputils.c | 44 | ||||
-rw-r--r-- | src/bin/pg_dump/dumputils.h | 4 | ||||
-rw-r--r-- | src/bin/pg_dump/pg_dump.c | 18 | ||||
-rw-r--r-- | src/bin/pg_dump/pg_dumpall.c | 56 |
4 files changed, 111 insertions, 11 deletions
diff --git a/src/bin/pg_dump/dumputils.c b/src/bin/pg_dump/dumputils.c index 6e5e625e6d0..acce7f82fa4 100644 --- a/src/bin/pg_dump/dumputils.c +++ b/src/bin/pg_dump/dumputils.c @@ -1166,3 +1166,47 @@ processSQLNamePattern(PGconn *conn, PQExpBuffer buf, const char *pattern, return added_clause; #undef WHEREAND } + +/* + * buildShSecLabelQuery + * + * Build a query to retrieve security labels for a shared object. + */ +void +buildShSecLabelQuery(PGconn *conn, const char *catalog_name, uint32 objectId, + PQExpBuffer sql) +{ + appendPQExpBuffer(sql, + "SELECT provider, label FROM pg_catalog.pg_shseclabel " + "WHERE classoid = '%s'::pg_catalog.regclass AND " + "objoid = %u", catalog_name, objectId); +} + +/* + * emitShSecLabels + * + * Format security label data retrieved by the query generated in + * buildShSecLabelQuery. + */ +void +emitShSecLabels(PGconn *conn, PGresult *res, PQExpBuffer buffer, + const char *target, const char *objname) +{ + int i; + + for (i = 0; i < PQntuples(res); i++) + { + char *provider = PQgetvalue(res, i, 0); + char *label = PQgetvalue(res, i, 1); + + /* must use fmtId result before calling it again */ + appendPQExpBuffer(buffer, + "SECURITY LABEL FOR %s ON %s", + fmtId(provider), target); + appendPQExpBuffer(buffer, + " %s IS ", + fmtId(objname)); + appendStringLiteralConn(buffer, label, conn); + appendPQExpBuffer(buffer, ";\n"); + } +} diff --git a/src/bin/pg_dump/dumputils.h b/src/bin/pg_dump/dumputils.h index 44d90669b61..40bbc81ae8d 100644 --- a/src/bin/pg_dump/dumputils.h +++ b/src/bin/pg_dump/dumputils.h @@ -47,5 +47,9 @@ extern bool processSQLNamePattern(PGconn *conn, PQExpBuffer buf, bool have_where, bool force_escape, const char *schemavar, const char *namevar, const char *altnamevar, const char *visibilityrule); +extern void buildShSecLabelQuery(PGconn *conn, const char *catalog_name, + uint32 objectId, PQExpBuffer sql); +extern void emitShSecLabels(PGconn *conn, PGresult *res, + PQExpBuffer buffer, const char *target, const char *objname); #endif /* DUMPUTILS_H */ diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index 9e69b0fc524..f2ee57cabd3 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -2048,6 +2048,24 @@ dumpDatabase(Archive *AH) PQclear(res); + /* Dump shared security label. */ + if (!no_security_labels && g_fout->remoteVersion >= 90200) + { + PQExpBuffer seclabelQry = createPQExpBuffer(); + + buildShSecLabelQuery(g_conn, "pg_database", dbCatId.oid, seclabelQry); + res = PQexec(g_conn, seclabelQry->data); + check_sql_result(res, g_conn, seclabelQry->data, PGRES_TUPLES_OK); + resetPQExpBuffer(seclabelQry); + emitShSecLabels(g_conn, res, seclabelQry, "DATABASE", datname); + if (strlen(seclabelQry->data)) + ArchiveEntry(AH, dbCatId, createDumpId(), datname, NULL, NULL, + dba, false, "SECURITY LABEL", SECTION_NONE, + seclabelQry->data, "", NULL, + &dbDumpId, 1, NULL, NULL); + destroyPQExpBuffer(seclabelQry); + } + destroyPQExpBuffer(dbQry); destroyPQExpBuffer(delQry); destroyPQExpBuffer(creaQry); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index b3ad2eac29b..b5f64e8d68e 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -52,6 +52,9 @@ static void dumpTimestamp(char *msg); static void doShellQuoting(PQExpBuffer buf, const char *str); static int runPgDump(const char *dbname); +static void buildShSecLabels(PGconn *conn, const char *catalog_name, + uint32 objectId, PQExpBuffer buffer, + const char *target, const char *objname); static PGconn *connectDatabase(const char *dbname, const char *pghost, const char *pgport, const char *pguser, enum trivalue prompt_password, bool fail_on_error); static PGresult *executeQuery(PGconn *conn, const char *query); @@ -718,15 +721,15 @@ dumpRoles(PGconn *conn) for (i = 0; i < PQntuples(res); i++) { const char *rolename; + Oid auth_oid; + auth_oid = atooid(PQgetvalue(res, i, i_oid)); rolename = PQgetvalue(res, i, i_rolname); resetPQExpBuffer(buf); if (binary_upgrade) { - Oid auth_oid = atooid(PQgetvalue(res, i, i_oid)); - appendPQExpBuffer(buf, "\n-- For binary upgrade, must preserve pg_authid.oid\n"); appendPQExpBuffer(buf, "SELECT binary_upgrade.set_next_pg_authid_oid('%u'::pg_catalog.oid);\n\n", @@ -796,6 +799,10 @@ dumpRoles(PGconn *conn) appendPQExpBuffer(buf, ";\n"); } + if (!no_security_labels && server_version >= 90200) + buildShSecLabels(conn, "pg_authid", auth_oid, + buf, "ROLE", rolename); + fprintf(OPF, "%s", buf->data); if (server_version >= 70300) @@ -981,7 +988,7 @@ dumpTablespaces(PGconn *conn) * pg_xxx) */ if (server_version >= 90000) - res = executeQuery(conn, "SELECT spcname, " + res = executeQuery(conn, "SELECT oid, spcname, " "pg_catalog.pg_get_userbyid(spcowner) AS spcowner, " "spclocation, spcacl, " "array_to_string(spcoptions, ', ')," @@ -990,7 +997,7 @@ dumpTablespaces(PGconn *conn) "WHERE spcname !~ '^pg_' " "ORDER BY 1"); else if (server_version >= 80200) - res = executeQuery(conn, "SELECT spcname, " + res = executeQuery(conn, "SELECT oid, spcname, " "pg_catalog.pg_get_userbyid(spcowner) AS spcowner, " "spclocation, spcacl, null, " "pg_catalog.shobj_description(oid, 'pg_tablespace') " @@ -998,7 +1005,7 @@ dumpTablespaces(PGconn *conn) "WHERE spcname !~ '^pg_' " "ORDER BY 1"); else - res = executeQuery(conn, "SELECT spcname, " + res = executeQuery(conn, "SELECT oid, spcname, " "pg_catalog.pg_get_userbyid(spcowner) AS spcowner, " "spclocation, spcacl, " "null, null " @@ -1012,12 +1019,13 @@ dumpTablespaces(PGconn *conn) for (i = 0; i < PQntuples(res); i++) { PQExpBuffer buf = createPQExpBuffer(); - char *spcname = PQgetvalue(res, i, 0); - char *spcowner = PQgetvalue(res, i, 1); - char *spclocation = PQgetvalue(res, i, 2); - char *spcacl = PQgetvalue(res, i, 3); - char *spcoptions = PQgetvalue(res, i, 4); - char *spccomment = PQgetvalue(res, i, 5); + uint32 spcoid = atooid(PQgetvalue(res, i, 0)); + char *spcname = PQgetvalue(res, i, 1); + char *spcowner = PQgetvalue(res, i, 2); + char *spclocation = PQgetvalue(res, i, 3); + char *spcacl = PQgetvalue(res, i, 4); + char *spcoptions = PQgetvalue(res, i, 5); + char *spccomment = PQgetvalue(res, i, 6); char *fspcname; /* needed for buildACLCommands() */ @@ -1051,6 +1059,10 @@ dumpTablespaces(PGconn *conn) appendPQExpBuffer(buf, ";\n"); } + if (!no_security_labels && server_version >= 90200) + buildShSecLabels(conn, "pg_tablespace", spcoid, + buf, "TABLESPACE", fspcname); + fprintf(OPF, "%s", buf->data); free(fspcname); @@ -1615,6 +1627,28 @@ runPgDump(const char *dbname) return ret; } +/* + * buildShSecLabels + * + * Build SECURITY LABEL command(s) for an shared object + * + * The caller has to provide object type and identifier to select security + * labels from pg_seclabels system view. + */ +static void +buildShSecLabels(PGconn *conn, const char *catalog_name, uint32 objectId, + PQExpBuffer buffer, const char *target, const char *objname) +{ + PQExpBuffer sql = createPQExpBuffer(); + PGresult *res; + + buildShSecLabelQuery(conn, catalog_name, objectId, sql); + res = executeQuery(conn, sql->data); + emitShSecLabels(conn, res, buffer, target, objname); + + PQclear(res); + destroyPQExpBuffer(sql); +} /* * Make a database connection with the given parameters. An |