Compare commits

..

7 commits

Author SHA1 Message Date
Fedora Release Engineering
8a1b36445d dist-git conversion 2010-07-29 12:35:37 +00:00
Bill Nottingham
d46b4f7823 Fix typo that causes a failure to update the common directory. (releng
#2781)
2009-11-26 01:38:42 +00:00
KaiGai Kohei
c443499dc0 upgrade base PostgreSQL v8.3.7->8.3.8 2009-09-10 12:19:48 +00:00
KaiGai Kohei
9c31ac1a07 upgrade base PostgreSQL version 8.3.6->8.3.7 2009-03-27 03:48:13 +00:00
KaiGai Kohei
640edf5fd4 bugfix: possible information leak by the order of permission checks in row
level permission checks.
2009-02-26 12:28:47 +00:00
KaiGai Kohei
e2c9545395 upgrade base postgresql 8.3.5->8.3.6 2009-02-06 02:32:18 +00:00
Jesse Keating
6bd3a519b5 Initialize branch F-10 for sepostgresql 2008-11-07 03:55:42 +00:00
11 changed files with 15048 additions and 1 deletions

1
.gitignore vendored Normal file
View file

@ -0,0 +1 @@
postgresql-8.3.8.tar.bz2

View file

@ -1 +0,0 @@
SE-PostgreSQL was merged into mainstream as contrib/sepgsql extension

View file

@ -0,0 +1,87 @@
Index: trunk/src/Makefile.global.in
===================================================================
--- trunk/src/Makefile.global.in (revision 430)
+++ trunk/src/Makefile.global.in (working copy)
@@ -73,14 +73,14 @@
datadir := @datadir@
ifeq "$(findstring pgsql, $(datadir))" ""
ifeq "$(findstring postgres, $(datadir))" ""
-override datadir := $(datadir)/postgresql
+override datadir := $(datadir)/sepgsql
endif
endif
sysconfdir := @sysconfdir@
ifeq "$(findstring pgsql, $(sysconfdir))" ""
ifeq "$(findstring postgres, $(sysconfdir))" ""
-override sysconfdir := $(sysconfdir)/postgresql
+override sysconfdir := $(sysconfdir)/sepgsql
endif
endif
@@ -89,7 +89,7 @@
pkglibdir = $(libdir)
ifeq "$(findstring pgsql, $(pkglibdir))" ""
ifeq "$(findstring postgres, $(pkglibdir))" ""
-override pkglibdir := $(pkglibdir)/postgresql
+override pkglibdir := $(pkglibdir)/sepgsql
endif
endif
@@ -98,7 +98,7 @@
pkgincludedir = $(includedir)
ifeq "$(findstring pgsql, $(pkgincludedir))" ""
ifeq "$(findstring postgres, $(pkgincludedir))" ""
-override pkgincludedir := $(pkgincludedir)/postgresql
+override pkgincludedir := $(pkgincludedir)/sepgsql
endif
endif
@@ -109,7 +109,7 @@
ifneq (,$(docdir))
ifeq "$(findstring pgsql, $(docdir))" ""
ifeq "$(findstring postgres, $(docdir))" ""
-override docdir := $(docdir)/postgresql
+override docdir := $(docdir)/sepgsql
endif
endif
endif
Index: trunk/src/bin/pg_ctl/pg_ctl.c
===================================================================
--- trunk/src/bin/pg_ctl/pg_ctl.c (revision 429)
+++ trunk/src/bin/pg_ctl/pg_ctl.c (working copy)
@@ -557,7 +557,7 @@
postmaster_path = pg_malloc(MAXPGPATH);
- if ((ret = find_other_exec(argv0, "postgres", PM_VERSIONSTR,
+ if ((ret = find_other_exec(argv0, "sepostgres", PM_VERSIONSTR,
postmaster_path)) < 0)
{
char full_path[MAXPGPATH];
Index: trunk/src/bin/initdb/initdb.c
===================================================================
--- trunk/src/bin/initdb/initdb.c (revision 429)
+++ trunk/src/bin/initdb/initdb.c (working copy)
@@ -2646,7 +2646,7 @@
sprintf(pgdenv, "PGDATA=%s", pg_data);
putenv(pgdenv);
- if ((ret = find_other_exec(argv[0], "postgres", PG_VERSIONSTR,
+ if ((ret = find_other_exec(argv[0], "sepostgres", PG_VERSIONSTR,
backend_exec)) < 0)
{
char full_path[MAXPGPATH];
Index: trunk/src/bin/pg_dump/pg_dumpall.c
===================================================================
--- trunk/src/bin/pg_dump/pg_dumpall.c (revision 429)
+++ trunk/src/bin/pg_dump/pg_dumpall.c (working copy)
@@ -139,7 +139,7 @@
}
}
- if ((ret = find_other_exec(argv[0], "pg_dump", PGDUMP_VERSIONSTR,
+ if ((ret = find_other_exec(argv[0], "sepg_dump", PGDUMP_VERSIONSTR,
pg_dump_bin)) < 0)
{
char full_path[MAXPGPATH];

View file

@ -0,0 +1,670 @@
diff -rpNU3 base/src/bin/initdb/initdb.c sepgsql/src/bin/initdb/initdb.c
--- base/src/bin/initdb/initdb.c 2009-09-10 20:11:35.000000000 +0900
+++ sepgsql/src/bin/initdb/initdb.c 2009-09-10 20:54:22.000000000 +0900
@@ -94,6 +94,7 @@ static bool debug = false;
static bool noclean = false;
static bool show_setting = false;
static char *xlog_dir = "";
+static char *pgace_feature = "none";
/* internal vars */
@@ -1224,6 +1225,11 @@ setup_config(void)
"#default_text_search_config = 'pg_catalog.simple'",
repltok);
+ snprintf(repltok, sizeof(repltok),
+ "pgace_feature = '%s'", pgace_feature);
+ conflines = replace_token(conflines,
+ "#pgace_feature = 'none'", repltok);
+
snprintf(path, sizeof(path), "%s/postgresql.conf", pg_data);
writefile(path, conflines);
@@ -2395,6 +2401,7 @@ usage(const char *progname)
printf(_(" -U, --username=NAME database superuser name\n"));
printf(_(" -W, --pwprompt prompt for a password for the new superuser\n"));
printf(_(" --pwfile=FILE read password for the new superuser from file\n"));
+ printf(_(" --pgace-feature=FEATURE specify an enhanced security feature\n"));
printf(_(" -?, --help show this help, then exit\n"));
printf(_(" -V, --version output version information, then exit\n"));
printf(_("\nLess commonly used options:\n"));
@@ -2429,6 +2436,7 @@ main(int argc, char *argv[])
{"auth", required_argument, NULL, 'A'},
{"pwprompt", no_argument, NULL, 'W'},
{"pwfile", required_argument, NULL, 9},
+ {"pgace-feature", required_argument, NULL, 10},
{"username", required_argument, NULL, 'U'},
{"help", no_argument, NULL, '?'},
{"version", no_argument, NULL, 'V'},
@@ -2543,6 +2551,9 @@ main(int argc, char *argv[])
case 9:
pwfilename = xstrdup(optarg);
break;
+ case 10:
+ pgace_feature = xstrdup(optarg);
+ break;
case 's':
show_setting = true;
break;
diff -rpNU3 base/src/bin/pg_dump/pg_ace_dump.h sepgsql/src/bin/pg_dump/pg_ace_dump.h
--- base/src/bin/pg_dump/pg_ace_dump.h 1970-01-01 09:00:00.000000000 +0900
+++ sepgsql/src/bin/pg_dump/pg_ace_dump.h 2008-10-14 15:38:18.000000000 +0900
@@ -0,0 +1,284 @@
+#ifndef PG_ACE_DUMP_H
+#define PG_ACE_DUMP_H
+
+#include "pg_backup.h"
+#include "pg_dump.h"
+
+#define PG_ACE_FEATURE_NOTHING 0
+#define PG_ACE_FEATURE_SELINUX 1
+
+#define SELINUX_SYSATTR_NAME "security_context"
+
+/*
+ * pg_ace_dumpCheckServerFeature
+ *
+ * This hook checks whether the server has required feature, or not.
+ */
+static inline void
+pg_ace_dumpCheckServerFeature(int feature, PGconn *conn)
+{
+ const char *serv_feature;
+
+ if (feature == PG_ACE_FEATURE_NOTHING)
+ return;
+
+ serv_feature = PQparameterStatus(conn, "pgace_security_feature");
+ if (!serv_feature)
+ {
+ fprintf(stderr, "could not get pgace_feature parameter.\n");
+ exit(1);
+ }
+
+ if (feature == PG_ACE_FEATURE_SELINUX)
+ {
+ if (strcmp(serv_feature, "selinux") != 0)
+ {
+ fprintf(stderr, "server does not have SELinux feature\n");
+ exit(1);
+ }
+ }
+}
+
+/*
+ * pg_ace_dumpDatabaseXXXX
+ *
+ * These hooks gives a chance to inject a security system column
+ * on dumping pg_database system catalog.
+ * A modified part must have ",d.<security column>" style, and
+ * its result should be printed to buf.
+ */
+static inline const char *
+pg_ace_dumpDatabaseQuery(int feature)
+{
+ if (feature == PG_ACE_FEATURE_SELINUX)
+ return (",d." SELINUX_SYSATTR_NAME);
+
+ return "";
+}
+
+static inline void
+pg_ace_dumpDatabasePrint(int feature, PQExpBuffer buf,
+ PGresult *res, int index)
+{
+ if (feature == PG_ACE_FEATURE_SELINUX)
+ {
+ int i_security = PQfnumber(res, SELINUX_SYSATTR_NAME);
+ char *dbsecurity = PQgetvalue(res, index, i_security);
+
+ if (dbsecurity && dbsecurity[0] != '\0')
+ appendPQExpBuffer(buf, " SECURITY_CONTEXT = '%s'", dbsecurity);
+ }
+}
+
+/*
+ * pg_ace_dumpClassXXXX
+ *
+ * These hooks give a chance to inject a security system column
+ * on dumping pg_class system catalog. The modified part has to
+ * be formalized to ",c.<security column>" style. The result
+ * should be preserved at TableInfo->relsecurity to print later,
+ * if exist.
+ */
+static inline const char *
+pg_ace_dumpClassQuery(int feature)
+{
+ if (feature == PG_ACE_FEATURE_SELINUX)
+ return (",c." SELINUX_SYSATTR_NAME);
+
+ return "";
+}
+
+static inline char *
+pg_ace_dumpClassPreserve(int feature, PGresult *res, int index)
+{
+ if (feature == PG_ACE_FEATURE_SELINUX)
+ {
+ int attno = PQfnumber(res, SELINUX_SYSATTR_NAME);
+ char *relcontext;
+
+ if (attno < 0)
+ return NULL;
+
+ relcontext = PQgetvalue(res, index, attno);
+
+ if (!relcontext || relcontext[0] == '\0')
+ return NULL;
+
+ return strdup(relcontext);
+ }
+
+ return NULL;
+}
+
+static inline void
+pg_ace_dumpClassPrint(int feature, PQExpBuffer buf, TableInfo *tbinfo)
+{
+ if (feature == PG_ACE_FEATURE_SELINUX)
+ {
+ char *relcontext = tbinfo->relsecurity;
+
+ if (relcontext)
+ appendPQExpBuffer(buf, " SECURITY_CONTEXT = '%s'", relcontext);
+
+ return;
+ }
+}
+
+/*
+ * pg_ace_dumpAttributeXXXX
+ *
+ * These hooks give a chance to inject a security system column
+ * on dumping pg_attribute system catalog. The modified part has
+ * to be formalized to ",a.<security conlumn>" style. The result
+ * should be preserved at TableInfo->attsecurity[index] to print
+ * later, if exist.
+ */
+static inline const char *
+pg_ace_dumpAttributeQuery(int feature)
+{
+ if (feature == PG_ACE_FEATURE_SELINUX)
+ return (",a." SELINUX_SYSATTR_NAME);
+
+ return "";
+}
+
+static inline char *
+pg_ace_dumpAttributePreserve(int feature, PGresult *res, int index)
+{
+ if (feature == PG_ACE_FEATURE_SELINUX)
+ {
+ int attno = PQfnumber(res, SELINUX_SYSATTR_NAME);
+ char *attcontext;
+
+ if (attno < 0)
+ return NULL;
+
+ attcontext = PQgetvalue(res, index, attno);
+ if (!attcontext || attcontext[0] == '\0')
+ return NULL;
+
+ return strdup(attcontext);
+ }
+
+ return NULL;
+}
+
+static inline void
+pg_ace_dumpAttributePrint(int feature, PQExpBuffer buf,
+ TableInfo *tbinfo, int index)
+{
+ if (feature == PG_ACE_FEATURE_SELINUX)
+ {
+ char *relcontext = tbinfo->relsecurity;
+ char *attcontext = tbinfo->attsecurity[index];
+
+ if (attcontext)
+ {
+ if (relcontext && strcmp(relcontext, attcontext) == 0)
+ return;
+
+ appendPQExpBuffer(buf, " SECURITY_CONTEXT = '%s'", attcontext);
+ }
+ return;
+ }
+}
+
+/*
+ * pg_ace_dumpProcXXXX
+ *
+ * These hooks give a chance to inject a security system column
+ * on dumping pg_proc system catalog. The modified part has to be
+ * formalized to "<security conlumn>" style. The result should be
+ * printed later, if exist.
+ */
+static inline const char *
+pg_ace_dumpProcQuery(int feature)
+{
+ if (feature == PG_ACE_FEATURE_SELINUX)
+ return ("," SELINUX_SYSATTR_NAME);
+
+ return "";
+}
+
+static inline void
+pg_ace_dumpProcPrint(int feature, PQExpBuffer buf,
+ PGresult *res, int index)
+{
+ if (feature == PG_ACE_FEATURE_SELINUX)
+ {
+ int i_selinux = PQfnumber(res, SELINUX_SYSATTR_NAME);
+ char *prosecurity;
+
+ if (i_selinux < 0)
+ return;
+
+ prosecurity = PQgetvalue(res, index, i_selinux);
+ if (prosecurity && prosecurity[0] != '\0')
+ appendPQExpBuffer(buf, " SECURITY_CONTEXT = '%s'", prosecurity);
+ }
+}
+
+/*
+ * pg_ace_dumpTableDataQuery
+ *
+ * This hook gives a chance to inject a security attribute system column
+ * on dumping of user's table.
+ * It must have ",<security column>" style.
+ */
+static inline const char *
+pg_ace_dumpTableDataQuery(int feature)
+{
+ if (feature == PG_ACE_FEATURE_SELINUX)
+ return ("," SELINUX_SYSATTR_NAME);
+
+ return "";
+}
+
+/*
+ * pg_ace_dumpCopyColumnList
+ *
+ * This hook gives a chance to inject a security attribute column within
+ * COPY statement. When a column is added, you have to return true. It
+ * enables to set needComma 'true', otherwise 'false'.
+ */
+static inline bool
+pg_ace_dumpCopyColumnList(int feature, PQExpBuffer buf)
+{
+ if (feature == PG_ACE_FEATURE_SELINUX)
+ {
+ appendPQExpBuffer(buf, SELINUX_SYSATTR_NAME);
+ return true;
+ }
+
+ return false;
+}
+
+/*
+ * pg_ace_dumpBlobComments
+ *
+ * This hook gives a chance to inject a query to restore a security
+ * attribute of binary large object.
+ */
+static inline void
+pg_ace_dumpBlobComments(int feature, Archive *AH, PGconn *conn, Oid blobOid)
+{
+ if (feature == PG_ACE_FEATURE_SELINUX)
+ {
+ PGresult *res;
+ char query[256];
+
+ snprintf(query, sizeof(query),
+ "SELECT lo_get_security(%u)", blobOid);
+ res = PQexec(conn, query);
+ if (!res)
+ return;
+
+ if (PQresultStatus(res) == PGRES_TUPLES_OK && PQntuples(res) == 1)
+ archprintf(AH, "SELECT lo_set_security(%u, '%s');\n",
+ blobOid, PQgetvalue(res, 0, 0));
+
+ PQclear(res);
+ }
+}
+
+#endif
diff -rpNU3 base/src/bin/pg_dump/pg_dump.c sepgsql/src/bin/pg_dump/pg_dump.c
--- base/src/bin/pg_dump/pg_dump.c 2009-09-10 20:11:35.000000000 +0900
+++ sepgsql/src/bin/pg_dump/pg_dump.c 2009-09-10 20:54:22.000000000 +0900
@@ -50,6 +50,7 @@ int optreset;
#include "pg_backup_archiver.h"
#include "dumputils.h"
+#include "pg_ace_dump.h"
extern char *optarg;
extern int optind,
@@ -118,6 +119,8 @@ static int g_numNamespaces;
/* flag to turn on/off dollar quoting */
static int disable_dollar_quoting = 0;
+/* flag to turn on/off security attribute support */
+static int pg_ace_feature = PG_ACE_FEATURE_NOTHING;
static void help(const char *progname);
static void expand_schema_name_patterns(SimpleStringList *patterns,
@@ -267,6 +270,7 @@ main(int argc, char **argv)
{"disable-dollar-quoting", no_argument, &disable_dollar_quoting, 1},
{"disable-triggers", no_argument, &disable_triggers, 1},
{"use-set-session-authorization", no_argument, &use_setsessauth, 1},
+ {"security-context", no_argument, &pg_ace_feature, PG_ACE_FEATURE_SELINUX},
{NULL, 0, NULL, 0}
};
@@ -419,6 +423,8 @@ main(int argc, char **argv)
disable_triggers = 1;
else if (strcmp(optarg, "use-set-session-authorization") == 0)
use_setsessauth = 1;
+ else if (strcmp(optarg, "security-context") == 0)
+ pg_ace_feature = PG_ACE_FEATURE_SELINUX;
else
{
fprintf(stderr,
@@ -549,6 +555,8 @@ main(int argc, char **argv)
std_strings = PQparameterStatus(g_conn, "standard_conforming_strings");
g_fout->std_strings = (std_strings && strcmp(std_strings, "on") == 0);
+ pg_ace_dumpCheckServerFeature(pg_ace_feature, g_conn);
+
/* Set the datestyle to ISO to ensure the dump's portability */
do_sql_command(g_conn, "SET DATESTYLE = ISO");
@@ -771,6 +779,7 @@ help(const char *progname)
printf(_(" --use-set-session-authorization\n"
" use SESSION AUTHORIZATION commands instead of\n"
" ALTER OWNER commands to set ownership\n"));
+ printf(_(" --security-context enable to dump security context of SE-PostgreSQL\n"));
printf(_("\nConnection options:\n"));
printf(_(" -h, --host=HOSTNAME database server host or socket directory\n"));
@@ -1171,7 +1180,8 @@ dumpTableData_insert(Archive *fout, void
if (fout->remoteVersion >= 70100)
{
appendPQExpBuffer(q, "DECLARE _pg_dump_cursor CURSOR FOR "
- "SELECT * FROM ONLY %s",
+ "SELECT * %s FROM ONLY %s",
+ pg_ace_dumpTableDataQuery(pg_ace_feature),
fmtQualifiedId(tbinfo->dobj.namespace->dobj.name,
classname));
}
@@ -1791,11 +1801,14 @@ dumpBlobComments(Archive *AH, void *arg)
Oid blobOid;
char *comment;
+ blobOid = atooid(PQgetvalue(res, i, 0));
+
+ pg_ace_dumpBlobComments(pg_ace_feature, AH, g_conn, blobOid);
+
/* ignore blobs without comments */
if (PQgetisnull(res, i, 1))
continue;
- blobOid = atooid(PQgetvalue(res, i, 0));
comment = PQgetvalue(res, i, 1);
printfPQExpBuffer(commentcmd, "COMMENT ON LARGE OBJECT %u IS ",
@@ -2933,6 +2946,7 @@ getTables(int *numTables)
"d.refobjsubid as owning_col, "
"(SELECT spcname FROM pg_tablespace t WHERE t.oid = c.reltablespace) AS reltablespace, "
"array_to_string(c.reloptions, ', ') as reloptions "
+ "%s "
"from pg_class c "
"left join pg_depend d on "
"(c.relkind = '%c' and "
@@ -2942,6 +2956,7 @@ getTables(int *numTables)
"where relkind in ('%c', '%c', '%c', '%c') "
"order by c.oid",
username_subquery,
+ pg_ace_dumpClassQuery(pg_ace_feature),
RELKIND_SEQUENCE,
RELKIND_RELATION, RELKIND_SEQUENCE,
RELKIND_VIEW, RELKIND_COMPOSITE_TYPE);
@@ -3138,6 +3153,7 @@ getTables(int *numTables)
}
tblinfo[i].reltablespace = strdup(PQgetvalue(res, i, i_reltablespace));
tblinfo[i].reloptions = strdup(PQgetvalue(res, i, i_reloptions));
+ tblinfo[i].relsecurity = pg_ace_dumpClassPreserve(pg_ace_feature, res, i);
/* other fields were zeroed above */
@@ -4369,11 +4385,13 @@ getTableAttrs(TableInfo *tblinfo, int nu
appendPQExpBuffer(q, "SELECT a.attnum, a.attname, a.atttypmod, a.attstattarget, a.attstorage, t.typstorage, "
"a.attnotnull, a.atthasdef, a.attisdropped, a.attislocal, "
"pg_catalog.format_type(t.oid,a.atttypmod) as atttypname "
+ "%s " /* security context, if required */
"from pg_catalog.pg_attribute a left join pg_catalog.pg_type t "
"on a.atttypid = t.oid "
"where a.attrelid = '%u'::pg_catalog.oid "
"and a.attnum > 0::pg_catalog.int2 "
"order by a.attrelid, a.attnum",
+ pg_ace_dumpAttributeQuery(pg_ace_feature),
tbinfo->dobj.catId.oid);
}
else if (g_fout->remoteVersion >= 70100)
@@ -4432,6 +4450,7 @@ getTableAttrs(TableInfo *tblinfo, int nu
tbinfo->typstorage = (char *) malloc(ntups * sizeof(char));
tbinfo->attisdropped = (bool *) malloc(ntups * sizeof(bool));
tbinfo->attislocal = (bool *) malloc(ntups * sizeof(bool));
+ tbinfo->attsecurity = (char **) malloc(ntups * sizeof(char *));
tbinfo->notnull = (bool *) malloc(ntups * sizeof(bool));
tbinfo->attrdefs = (AttrDefInfo **) malloc(ntups * sizeof(AttrDefInfo *));
tbinfo->inhAttrs = (bool *) malloc(ntups * sizeof(bool));
@@ -4463,6 +4482,8 @@ getTableAttrs(TableInfo *tblinfo, int nu
tbinfo->inhAttrs[j] = false;
tbinfo->inhAttrDef[j] = false;
tbinfo->inhNotNull[j] = false;
+
+ tbinfo->attsecurity[j] = pg_ace_dumpAttributePreserve(pg_ace_feature, res, j);
}
PQclear(res);
@@ -6466,8 +6487,10 @@ dumpFunc(Archive *fout, FuncInfo *finfo)
"provolatile, proisstrict, prosecdef, "
"proconfig, procost, prorows, "
"(SELECT lanname FROM pg_catalog.pg_language WHERE oid = prolang) as lanname "
+ "%s " /* security context, if required */
"FROM pg_catalog.pg_proc "
"WHERE oid = '%u'::pg_catalog.oid",
+ pg_ace_dumpProcQuery(pg_ace_feature),
finfo->dobj.catId.oid);
}
else if (g_fout->remoteVersion >= 80100)
@@ -6705,6 +6728,8 @@ dumpFunc(Archive *fout, FuncInfo *finfo)
if (prosecdef[0] == 't')
appendPQExpBuffer(q, " SECURITY DEFINER");
+ pg_ace_dumpProcPrint(pg_ace_feature, q, res, 0);
+
/*
* COST and ROWS are emitted only if present and not default, so as not to
* break backwards-compatibility of the dump without need. Keep this code
@@ -8786,6 +8811,8 @@ dumpTableSchema(Archive *fout, TableInfo
if (tbinfo->notnull[j] && !tbinfo->inhNotNull[j])
appendPQExpBuffer(q, " NOT NULL");
+ pg_ace_dumpAttributePrint(pg_ace_feature, q, tbinfo, j);
+
actual_atts++;
}
}
@@ -8833,6 +8860,8 @@ dumpTableSchema(Archive *fout, TableInfo
if (tbinfo->reloptions && strlen(tbinfo->reloptions) > 0)
appendPQExpBuffer(q, "\nWITH (%s)", tbinfo->reloptions);
+ pg_ace_dumpClassPrint(pg_ace_feature, q, tbinfo);
+
appendPQExpBuffer(q, ";\n");
/* Loop dumping statistics and storage statements */
@@ -10250,6 +10279,10 @@ fmtCopyColumnList(const TableInfo *ti)
appendPQExpBuffer(q, "(");
needComma = false;
+
+ if (pg_ace_dumpCopyColumnList(pg_ace_feature, q))
+ needComma = true;
+
for (i = 0; i < numatts; i++)
{
if (attisdropped[i])
diff -rpNU3 base/src/bin/pg_dump/pg_dump.h sepgsql/src/bin/pg_dump/pg_dump.h
--- base/src/bin/pg_dump/pg_dump.h 2009-02-02 11:47:17.000000000 +0900
+++ sepgsql/src/bin/pg_dump/pg_dump.h 2009-02-02 11:58:34.000000000 +0900
@@ -238,6 +238,7 @@ typedef struct _tableInfo
char relkind;
char *reltablespace; /* relation tablespace */
char *reloptions; /* options specified by WITH (...) */
+ char *relsecurity; /* security attribute of the relation */
bool hasindex; /* does it have any indexes? */
bool hasrules; /* does it have any rules? */
bool hasoids; /* does it have OIDs? */
@@ -262,6 +263,7 @@ typedef struct _tableInfo
char *typstorage; /* type storage scheme */
bool *attisdropped; /* true if attr is dropped; don't dump it */
bool *attislocal; /* true if attr has local definition */
+ char **attsecurity; /* security attribute of attribute (column) */
/*
* Note: we need to store per-attribute notnull, default, and constraint
diff -rpNU3 base/src/bin/pg_dump/pg_dumpall.c sepgsql/src/bin/pg_dump/pg_dumpall.c
--- base/src/bin/pg_dump/pg_dumpall.c 2008-01-07 23:51:33.000000000 +0900
+++ sepgsql/src/bin/pg_dump/pg_dumpall.c 2008-07-11 14:10:51.000000000 +0900
@@ -27,6 +27,7 @@ int optreset;
#endif
#include "dumputils.h"
+#include "pg_ace_dump.h"
/* version string we expect back from pg_dump */
@@ -67,6 +68,9 @@ static int disable_triggers = 0;
static int use_setsessauth = 0;
static int server_version;
+/* flag to turn on/off security attribute support */
+static int pg_ace_feature = PG_ACE_FEATURE_NOTHING;
+
static FILE *OPF;
static char *filename = NULL;
@@ -119,6 +123,7 @@ main(int argc, char *argv[])
{"disable-dollar-quoting", no_argument, &disable_dollar_quoting, 1},
{"disable-triggers", no_argument, &disable_triggers, 1},
{"use-set-session-authorization", no_argument, &use_setsessauth, 1},
+ {"security-context", no_argument, &pg_ace_feature, PG_ACE_FEATURE_SELINUX},
{NULL, 0, NULL, 0}
};
@@ -290,6 +295,8 @@ main(int argc, char *argv[])
appendPQExpBuffer(pgdumpopts, " --disable-triggers");
else if (strcmp(optarg, "use-set-session-authorization") == 0)
/* no-op, still allowed for compatibility */ ;
+ else if (strcmp(optarg, "security-context") == 0)
+ pg_ace_feature = PG_ACE_FEATURE_SELINUX;
else
{
fprintf(stderr,
@@ -316,6 +323,8 @@ main(int argc, char *argv[])
appendPQExpBuffer(pgdumpopts, " --disable-triggers");
if (use_setsessauth)
appendPQExpBuffer(pgdumpopts, " --use-set-session-authorization");
+ if (pg_ace_feature == PG_ACE_FEATURE_SELINUX)
+ appendPQExpBuffer(pgdumpopts, " --security-context");
if (optind < argc)
{
@@ -391,6 +400,8 @@ main(int argc, char *argv[])
}
}
+ pg_ace_dumpCheckServerFeature(pg_ace_feature, conn);
+
/*
* Open the output file if required, otherwise use stdout
*/
@@ -505,6 +516,7 @@ help(void)
printf(_(" --use-set-session-authorization\n"
" use SESSION AUTHORIZATION commands instead of\n"
" OWNER TO commands\n"));
+ printf(_(" --security-context enables to dump security context of SE-PostgreSQL\n"));
printf(_("\nConnection options:\n"));
printf(_(" -h, --host=HOSTNAME database server host or socket directory\n"));
@@ -915,16 +927,18 @@ dumpCreateDB(PGconn *conn)
fprintf(OPF, "--\n-- Database creation\n--\n\n");
if (server_version >= 80100)
- res = executeQuery(conn,
+ appendPQExpBuffer(buf,
"SELECT datname, "
"coalesce(rolname, (select rolname from pg_authid where oid=(select datdba from pg_database where datname='template0'))), "
"pg_encoding_to_char(d.encoding), "
"datistemplate, datacl, datconnlimit, "
"(SELECT spcname FROM pg_tablespace t WHERE t.oid = d.dattablespace) AS dattablespace "
+ "%s "
"FROM pg_database d LEFT JOIN pg_authid u ON (datdba = u.oid) "
- "WHERE datallowconn ORDER BY 1");
+ "WHERE datallowconn ORDER BY 1",
+ pg_ace_dumpDatabaseQuery(pg_ace_feature));
else if (server_version >= 80000)
- res = executeQuery(conn,
+ appendPQExpBuffer(buf,
"SELECT datname, "
"coalesce(usename, (select usename from pg_shadow where usesysid=(select datdba from pg_database where datname='template0'))), "
"pg_encoding_to_char(d.encoding), "
@@ -933,7 +947,7 @@ dumpCreateDB(PGconn *conn)
"FROM pg_database d LEFT JOIN pg_shadow u ON (datdba = usesysid) "
"WHERE datallowconn ORDER BY 1");
else if (server_version >= 70300)
- res = executeQuery(conn,
+ appendPQExpBuffer(buf,
"SELECT datname, "
"coalesce(usename, (select usename from pg_shadow where usesysid=(select datdba from pg_database where datname='template0'))), "
"pg_encoding_to_char(d.encoding), "
@@ -942,7 +956,7 @@ dumpCreateDB(PGconn *conn)
"FROM pg_database d LEFT JOIN pg_shadow u ON (datdba = usesysid) "
"WHERE datallowconn ORDER BY 1");
else if (server_version >= 70100)
- res = executeQuery(conn,
+ appendPQExpBuffer(buf,
"SELECT datname, "
"coalesce("
"(select usename from pg_shadow where usesysid=datdba), "
@@ -958,7 +972,7 @@ dumpCreateDB(PGconn *conn)
* Note: 7.0 fails to cope with sub-select in COALESCE, so just deal
* with getting a NULL by not printing any OWNER clause.
*/
- res = executeQuery(conn,
+ appendPQExpBuffer(buf,
"SELECT datname, "
"(select usename from pg_shadow where usesysid=datdba), "
"pg_encoding_to_char(d.encoding), "
@@ -968,6 +982,7 @@ dumpCreateDB(PGconn *conn)
"FROM pg_database d "
"ORDER BY 1");
}
+ res = executeQuery(conn, buf->data);
for (i = 0; i < PQntuples(res); i++)
{
@@ -1021,6 +1036,8 @@ dumpCreateDB(PGconn *conn)
appendPQExpBuffer(buf, " CONNECTION LIMIT = %s",
dbconnlimit);
+ pg_ace_dumpDatabasePrint(pg_ace_feature, buf, res, i);
+
appendPQExpBuffer(buf, ";\n");
if (strcmp(dbistemplate, "t") == 0)

View file

@ -0,0 +1,821 @@
diff -rpNU3 base/src/backend/security/sepgsql/policy/Makefile sepgsql/src/backend/security/sepgsql/policy/Makefile
--- base/src/backend/security/sepgsql/policy/Makefile 1970-01-01 09:00:00.000000000 +0900
+++ sepgsql/src/backend/security/sepgsql/policy/Makefile 2008-07-11 14:10:51.000000000 +0900
@@ -0,0 +1,41 @@
+#
+# contrib/sepgsql_policy/Makefile
+# Makefile of security policy module for SE-PostgreSQL
+#
+top_builddir = ../../../../..
+include $(top_builddir)/src/Makefile.global
+
+policy_basedir := /usr/share/selinux
+policy_makefile := $(policy_basedir)/devel/Makefile
+policy_types := targeted mls
+policy := $(strip $(shell $(AWK) -F= '/^SELINUXTYPE/{ print $$2 }' /etc/selinux/config))
+package_names := sepostgresql sepostgresql-devel
+prefix_ptn := "s/%%__prefix__%%/$(shell echo $(prefix)|sed 's/\//\\\//g')/g"
+bindir_ptn := "s/%%__bindir__%%/$(shell echo $(bindir)|sed 's/\//\\\//g')/g"
+libdir_ptn := "s/%%__libdir__%%/$(shell echo $(pkglibdir)|sed 's/\//\\\//g')/g"
+
+all:
+ $(foreach pkg, $(package_names), $(foreach p, $(policy_types), $(MAKE) $(MAKEOVERRIDES) policy=$(p) $(pkg).pp;))
+ $(foreach pkg, $(package_names), test -e $(pkg).pp.$(policy) && ln -sf $(pkg).pp.$(policy) $(pkg).pp;)
+
+.install-policy:
+ test -d $(DESTDIR)$(policy_basedir)/$(policy) || install -d $(DESTDIR)$(policy_basedir)/$(policy)
+ $(foreach pkg, $(package_names), install -p -m 644 $(pkg).pp.$(policy) $(DESTDIR)$(policy_basedir)/$(policy)/$(pkg).pp;)
+
+install: all
+ $(foreach p, $(policy_types), $(MAKE) $(MAKEOVERRIDES) policy=$(p) .install-policy;)
+
+%.pp: %.te %.if %.fc
+ rm -f $@
+ $(MAKE) NAME=$(policy) -f $(policy_makefile) $@
+ mv $@ $@.$(policy)
+
+sepostgresql-devel.fc: sepostgresql.fc.template
+ cat $< | grep -v ^/var | sed -e $(prefix_ptn) -e $(bindir_ptn) -e $(libdir_ptn) > $@
+
+sepostgresql.fc: sepostgresql.fc.template
+ cat $< | sed -e $(prefix_ptn) -e $(bindir_ptn) -e $(libdir_ptn) > $@
+
+clean:
+ $(MAKE) -f $(policy_makefile) clean
+ rm -f *.pp.* *.fc
diff -rpNU3 base/src/backend/security/sepgsql/policy/README sepgsql/src/backend/security/sepgsql/policy/README
--- base/src/backend/security/sepgsql/policy/README 1970-01-01 09:00:00.000000000 +0900
+++ sepgsql/src/backend/security/sepgsql/policy/README 2008-07-11 14:10:51.000000000 +0900
@@ -0,0 +1,49 @@
+The security policy module of SE-PostgreSQL
+-------------------------------------------
+
+o Introduction
+
+ We provide two kind of security policy modules.
+
+ One is "sepostgresql.pp" which contains full-set of security policy
+ and suitable for legacy base policy (selinux-policy-3.4.1, or prior).
+
+ The other is "sepostgresql-devel.pp" which provides several booleans
+ for developers, and suitable for newer base policy (selinux-policy-3.4.2,
+ or later).
+
+ In the selinux-policy-3.4.2, most part of the policy got upstreamed.
+ So, we don't need to install "sepostgresql.pp" explicitly on the newer
+ base security policy.
+
+ If you need to run regression test, or (don't) want to generate access
+ logs, install "sepostgresql-devel.pp" and turn on/off booleans.
+
+o Build & Installation
+
+ $ cd src/backend/security/sepgsql/policy
+ $ make
+ $ su
+ # /usr/sbin/semodule -i sepostgresql-devel.pp
+ or
+ # /usr/sbin/semodule -i sepostgresql.pp
+
+o Booleans
+
+- sepgsql_enable_users_ddl (default: on)
+ This boolean enables to control to execute DDL statement come from
+ confined users.
+
+- sepgsql_enable_auditallow (default: off)
+ This boolean enables to generate access allow logs except for tuple
+ level.
+
+- sepgsql_enable_auditdeny (default: on)
+ This boolean enables to generata access denied logs except for tuple
+ level.
+
+- sepgsql_regression_test_mode (default: off)
+ This boolean provides several permission to run regression test on
+ your home directory. It enables to load shared library files deployed
+ on home directory.
+ However, we don't recommend it to turn on in the operation phase.
diff -rpNU3 base/src/backend/security/sepgsql/policy/sepostgresql-devel.if sepgsql/src/backend/security/sepgsql/policy/sepostgresql-devel.if
--- base/src/backend/security/sepgsql/policy/sepostgresql-devel.if 1970-01-01 09:00:00.000000000 +0900
+++ sepgsql/src/backend/security/sepgsql/policy/sepostgresql-devel.if 2008-07-11 14:10:51.000000000 +0900
@@ -0,0 +1 @@
+## There are no interface declaration
diff -rpNU3 base/src/backend/security/sepgsql/policy/sepostgresql-devel.te sepgsql/src/backend/security/sepgsql/policy/sepostgresql-devel.te
--- base/src/backend/security/sepgsql/policy/sepostgresql-devel.te 1970-01-01 09:00:00.000000000 +0900
+++ sepgsql/src/backend/security/sepgsql/policy/sepostgresql-devel.te 2009-02-26 21:30:17.000000000 +0900
@@ -0,0 +1,120 @@
+policy_module(sepostgresql-devel, 3.23)
+
+gen_require(`
+ class db_database all_db_database_perms;
+ class db_table all_db_table_perms;
+ class db_procedure all_db_procedure_perms;
+ class db_column all_db_column_perms;
+ class db_tuple all_db_tuple_perms;
+ class db_blob all_db_blob_perms;
+
+ attribute sepgsql_client_type;
+ attribute sepgsql_unconfined_type;
+
+ attribute sepgsql_database_type;
+ attribute sepgsql_table_type;
+ attribute sepgsql_sysobj_table_type;
+ attribute sepgsql_procedure_type;
+ attribute sepgsql_blob_type;
+ attribute sepgsql_module_type;
+
+ # for regression test
+ type bin_t;
+ type user_home_t;
+ type sepgsql_trusted_proc_t;
+
+ attribute tmpfile;
+ attribute user_ptynode;
+')
+
+#################################
+#
+# Domain for Testcases
+#
+
+role sepgsql_test_r;
+
+userdom_unpriv_user_template(sepgsql_test)
+
+ifdef(`postgresql_role', `
+ postgresql_role(sepgsql_test_r, sepgsql_test_t)
+',`
+ postgresql_userdom_template(sepgsql_test, sepgsql_test_t, sepgsql_test_r)
+')
+
+allow sepgsql_test_t tmpfile : dir search_dir_perms;
+allow sepgsql_test_t tmpfile : file rw_file_perms;
+allow sepgsql_test_t user_ptynode : chr_file rw_file_perms;
+
+optional_policy(`
+ gen_require(`
+ type unconfined_t;
+ role unconfined_r;
+ ')
+ allow unconfined_t sepgsql_test_t : process transition;
+ role unconfined_r types sepgsql_test_t;
+ role unconfined_r types sepgsql_trusted_proc_t;
+')
+
+#################################
+#
+# SE-PostgreSQL Declarations
+#
+
+## <desc>
+## <p>
+## Allow to generate auditallow logs
+## </p>
+## </desc>
+gen_tunable(sepgsql_enable_auditallow, false)
+
+## <desc>
+## <p>
+## Allow to generate auditdeny logs
+## </p>
+## </desc>
+gen_tunable(sepgsql_enable_auditdeny, true)
+
+## <desc>
+## <p>
+## Allow widespread permissions for regression test
+## Don't set TRUE on operation phase
+## </p>
+## </desc>
+gen_tunable(sepgsql_regression_test_mode, false)
+
+########################################
+#
+# SE-PostgreSQL audit switch for debugging
+#
+tunable_policy(`sepgsql_enable_auditallow',`
+ auditallow domain sepgsql_database_type : db_database *;
+ auditallow domain sepgsql_table_type : db_table *;
+ auditallow domain sepgsql_table_type : db_column *;
+ auditallow domain sepgsql_table_type : db_tuple { relabelfrom relabelto };
+ auditallow domain sepgsql_procedure_type : db_procedure *;
+ auditallow domain sepgsql_blob_type : db_blob *;
+ auditallow domain sepgsql_module_type : db_database { install_module };
+ auditallow sepgsql_database_type sepgsql_module_type : db_database { load_module };
+')
+
+tunable_policy(`! sepgsql_enable_auditdeny',`
+ dontaudit domain sepgsql_database_type : db_database *;
+ dontaudit domain sepgsql_table_type : db_table *;
+ dontaudit domain sepgsql_table_type : db_column *;
+ dontaudit domain sepgsql_table_type : db_tuple { relabelfrom relabelto };
+ dontaudit domain sepgsql_procedure_type : db_procedure *;
+ dontaudit domain sepgsql_blob_type : db_blob *;
+ dontaudit domain sepgsql_module_type : db_database { install_module };
+ dontaudit sepgsql_database_type sepgsql_module_type : db_database { load_module };
+')
+
+########################################
+#
+# SE-PostgreSQL regression test mode switch
+#
+tunable_policy(`sepgsql_regression_test_mode',`
+ allow sepgsql_client_type user_home_t : db_database { install_module };
+ allow sepgsql_unconfined_type user_home_t : db_database { install_module };
+ allow sepgsql_database_type user_home_t : db_database { load_module };
+')
diff -rpNU3 base/src/backend/security/sepgsql/policy/sepostgresql.fc.template sepgsql/src/backend/security/sepgsql/policy/sepostgresql.fc.template
--- base/src/backend/security/sepgsql/policy/sepostgresql.fc.template 1970-01-01 09:00:00.000000000 +0900
+++ sepgsql/src/backend/security/sepgsql/policy/sepostgresql.fc.template 2008-07-11 14:10:51.000000000 +0900
@@ -0,0 +1,15 @@
+#
+# SE-PostgreSQL install path
+#
+%%__prefix__%%(/.*)? -- gen_context(system_u:object_r:usr_t,s0)
+
+%%__bindir__%%/(se)?postgres -- gen_context(system_u:object_r:postgresql_exec_t,s0)
+%%__bindir__%%/(se)?pg_ctl -- gen_context(system_u:object_r:initrc_exec_t,s0)
+%%__bindir__%%/initdb(\.sepgsql)? -- gen_context(system_u:object_r:postgresql_exec_t,s0)
+%%__bindir__%%(/.*)? -- gen_context(system_u:object_r:bin_t,s0)
+
+%%__libdir__%%(/.*)? -- gen_context(system_u:object_r:lib_t,s0)
+
+/var/lib/sepgsql(/.*)? gen_context(system_u:object_r:postgresql_db_t,s0)
+/var/lib/sepgsql/pgstartup\.log gen_context(system_u:object_r:postgresql_log_t,s0)
+/var/log/sepostgresql\.log.* -- gen_context(system_u:object_r:postgresql_log_t,s0)
diff -rpNU3 base/src/backend/security/sepgsql/policy/sepostgresql.if sepgsql/src/backend/security/sepgsql/policy/sepostgresql.if
--- base/src/backend/security/sepgsql/policy/sepostgresql.if 1970-01-01 09:00:00.000000000 +0900
+++ sepgsql/src/backend/security/sepgsql/policy/sepostgresql.if 2008-07-11 17:12:06.000000000 +0900
@@ -0,0 +1,259 @@
+#######################################
+## <summary>
+## The userdomain template for the SE-PostgreSQL.
+## </summary>
+## <desc>
+## This template creates a delivered types which are used
+## for given userdomains.
+## </desc>
+## <param name="userdomain_prefix">
+## <summary>
+## The prefix of the user domain (e.g., user
+## is the prefix for user_t).
+## </summary>
+## </param>
+## <param name="user_domain">
+## <summary>
+## The type of the user domain.
+## </summary>
+## </param>
+## <param name="user_role">
+## <summary>
+## The role associated with the user domain.
+## </summary>
+## </param>
+#
+template(`sepgsql_userdom_template',`
+ gen_require(`
+ class db_database all_db_database_perms;
+ class db_table all_db_table_perms;
+ class db_procedure all_db_procedure_perms;
+ class db_column all_db_column_perms;
+ class db_tuple all_db_tuple_perms;
+ class db_blob all_db_blob_perms;
+
+ attribute sepgsql_client_type;
+ attribute sepgsql_database_type;
+ attribute sepgsql_sysobj_table_type;
+
+ type sepgsql_trusted_proc_t;
+ type sepgsql_trusted_proc_exec_t;
+ ')
+
+ ########################################
+ #
+ # Declarations
+ #
+
+ typeattribute $2 sepgsql_client_type;
+
+ type $1_sepgsql_blob_t;
+ sepgsql_blob_object($1_sepgsql_blob_t)
+
+ type $1_sepgsql_proc_exec_t;
+ sepgsql_procedure_object($1_sepgsql_proc_exec_t)
+
+ type $1_sepgsql_sysobj_t;
+ sepgsql_system_table_object($1_sepgsql_sysobj_t)
+
+ type $1_sepgsql_table_t;
+ sepgsql_table_object($1_sepgsql_table_t)
+
+ role $3 types sepgsql_trusted_proc_t;
+
+ ##############################
+ #
+ # Client local policy
+ #
+
+ tunable_policy(`sepgsql_enable_users_ddl',`
+ allow $2 $1_sepgsql_table_t : db_table { create drop };
+ type_transition $2 sepgsql_database_type:db_table $1_sepgsql_table_t;
+
+ allow $2 $1_sepgsql_table_t : db_column { create drop };
+
+ allow $2 $1_sepgsql_sysobj_t : db_tuple { update insert delete };
+ type_transition $2 sepgsql_sysobj_table_type:db_tuple $1_sepgsql_sysobj_t;
+ ')
+
+ allow $2 $1_sepgsql_table_t : db_table { getattr setattr use select update insert delete };
+ allow $2 $1_sepgsql_table_t : db_column { getattr setattr use select update insert };
+ allow $2 $1_sepgsql_table_t : db_tuple { use select update insert delete };
+ allow $2 $1_sepgsql_sysobj_t : db_tuple { use select };
+
+ allow $2 $1_sepgsql_proc_exec_t : db_procedure { create drop getattr setattr execute };
+ type_transition $2 sepgsql_database_type:db_procedure $1_sepgsql_proc_exec_t;
+
+ allow $2 $1_sepgsql_blob_t : db_blob { create drop getattr setattr read write };
+ type_transition $2 sepgsql_database_type:db_blob $1_sepgsql_blob_t;
+
+ allow $2 sepgsql_trusted_proc_t:process transition;
+ type_transition $2 sepgsql_trusted_proc_exec_t:process sepgsql_trusted_proc_t;
+')
+
+########################################
+## <summary>
+## Marks as a SE-PostgreSQL loadable shared library module
+## </summary>
+## <param name="type">
+## <summary>
+## Type marked as a database object type.
+## </summary>
+## </param>
+#
+interface(`sepgsql_loadable_module',`
+ gen_require(`
+ attribute sepgsql_module_type;
+ ')
+
+ typeattribute $1 sepgsql_module_type;
+')
+
+########################################
+## <summary>
+## Marks as a SE-PostgreSQL database object type
+## </summary>
+## <param name="type">
+## <summary>
+## Type marked as a database object type.
+## </summary>
+## </param>
+#
+interface(`sepgsql_database_object',`
+ gen_require(`
+ attribute sepgsql_database_type;
+ ')
+
+ typeattribute $1 sepgsql_database_type;
+')
+
+########################################
+## <summary>
+## Marks as a SE-PostgreSQL table/column/tuple object type
+## </summary>
+## <param name="type">
+## <summary>
+## Type marked as a table/column/tuple object type.
+## </summary>
+## </param>
+#
+interface(`sepgsql_table_object',`
+ gen_require(`
+ attribute sepgsql_table_type;
+ ')
+
+ typeattribute $1 sepgsql_table_type;
+')
+
+########################################
+## <summary>
+## Marks as a SE-PostgreSQL system table/column/tuple object type
+## </summary>
+## <param name="type">
+## <summary>
+## Type marked as a table/column/tuple object type.
+## </summary>
+## </param>
+#
+interface(`sepgsql_system_table_object',`
+ gen_require(`
+ attribute sepgsql_table_type;
+ attribute sepgsql_sysobj_table_type;
+ ')
+
+ typeattribute $1 sepgsql_table_type;
+ typeattribute $1 sepgsql_sysobj_table_type;
+')
+
+########################################
+## <summary>
+## Marks as a SE-PostgreSQL procedure object type
+## </summary>
+## <param name="type">
+## <summary>
+## Type marked as a database object type.
+## </summary>
+## </param>
+#
+interface(`sepgsql_procedure_object',`
+ gen_require(`
+ attribute sepgsql_procedure_type;
+ ')
+
+ typeattribute $1 sepgsql_procedure_type;
+')
+
+########################################
+## <summary>
+## Marks as a SE-PostgreSQL binary large object type
+## </summary>
+## <param name="type">
+## <summary>
+## Type marked as a database binary large object type.
+## </summary>
+## </param>
+#
+interface(`sepgsql_blob_object',`
+ gen_require(`
+ attribute sepgsql_blob_type;
+ ')
+
+ typeattribute $1 sepgsql_blob_type;
+')
+
+########################################
+## <summary>
+## Allow the specified domain unprivileged accesses to unifined database objects
+## managed by SE-PostgreSQL,
+## </summary>
+## <param name="domain">
+## <summary>
+## Domain allowed access.
+## </summary>
+## </param>
+#
+interface(`sepgsql_unpriv_client',`
+ gen_require(`
+ class db_table all_db_table_perms;
+ class db_procedure all_db_procedure_perms;
+ class db_blob all_db_blob_perms;
+
+ attribute sepgsql_client_type;
+ attribute sepgsql_database_type;
+
+ type sepgsql_table_t;
+ type sepgsql_proc_t;
+ type sepgsql_blob_t;
+
+ type sepgsql_trusted_proc_t;
+ type sepgsql_trusted_proc_exec_t;
+ ')
+
+ typeattribute $1 sepgsql_client_type;
+
+ type_transition $1 sepgsql_database_type:db_table sepgsql_table_t;
+ type_transition $1 sepgsql_database_type:db_procedure sepgsql_proc_t;
+ type_transition $1 sepgsql_database_type:db_blob sepgsql_blob_t;
+
+ type_transition $1 sepgsql_trusted_proc_exec_t:process sepgsql_trusted_proc_t;
+ allow $1 sepgsql_trusted_proc_t:process transition;
+')
+
+########################################
+## <summary>
+## Allow the specified domain unconfined accesses to any database objects
+## managed by SE-PostgreSQL,
+## </summary>
+## <param name="domain">
+## <summary>
+## Domain allowed access.
+## </summary>
+## </param>
+#
+interface(`sepgsql_unconfined',`
+ gen_require(`
+ attribute sepgsql_unconfined_type;
+ ')
+
+ typeattribute $1 sepgsql_unconfined_type;
+')
diff -rpNU3 base/src/backend/security/sepgsql/policy/sepostgresql.te sepgsql/src/backend/security/sepgsql/policy/sepostgresql.te
--- base/src/backend/security/sepgsql/policy/sepostgresql.te 1970-01-01 09:00:00.000000000 +0900
+++ sepgsql/src/backend/security/sepgsql/policy/sepostgresql.te 2008-07-11 17:12:06.000000000 +0900
@@ -0,0 +1,308 @@
+policy_module(sepostgresql, 3.11)
+
+gen_require(`
+ class db_database all_db_database_perms;
+ class db_table all_db_table_perms;
+ class db_procedure all_db_procedure_perms;
+ class db_column all_db_column_perms;
+ class db_tuple all_db_tuple_perms;
+ class db_blob all_db_blob_perms;
+
+ attribute domain, home_type;
+ type postgresql_t, unlabeled_t;
+
+ role system_r;
+')
+
+#################################
+#
+# SE-PostgreSQL Declarations
+#
+
+## <desc>
+## <p>
+## Allow to generate auditallow logs
+## </p>
+## </desc>
+gen_tunable(sepgsql_enable_auditallow, false)
+
+## <desc>
+## <p>
+## Allow to generate auditdeny logs
+## </p>
+## </desc>
+gen_tunable(sepgsql_enable_auditdeny, true)
+
+## <desc>
+## <p>
+## Allow unprivileged users to execute DDL statement
+## </p>
+## </desc>
+gen_tunable(sepgsql_enable_users_ddl, true)
+
+## <desc>
+## <p>
+## Allow widespread permissions for regression test
+## Don't set TRUE on operation phase
+## </p>
+## </desc>
+gen_tunable(sepgsql_regression_test_mode, false)
+
+# database clients attribute
+attribute sepgsql_client_type;
+attribute sepgsql_unconfined_type;
+
+# database objects attribute
+attribute sepgsql_database_type;
+attribute sepgsql_table_type;
+attribute sepgsql_sysobj_table_type;
+attribute sepgsql_procedure_type;
+attribute sepgsql_blob_type;
+attribute sepgsql_module_type;
+
+# database object types
+type sepgsql_blob_t;
+sepgsql_blob_object(sepgsql_blob_t)
+
+type sepgsql_db_t;
+sepgsql_database_object(sepgsql_db_t)
+
+type sepgsql_fixed_table_t;
+sepgsql_table_object(sepgsql_fixed_table_t)
+
+type sepgsql_proc_t;
+sepgsql_procedure_object(sepgsql_proc_t)
+
+type sepgsql_ro_blob_t;
+sepgsql_blob_object(sepgsql_ro_blob_t)
+
+type sepgsql_ro_table_t;
+sepgsql_table_object(sepgsql_ro_table_t)
+
+type sepgsql_secret_blob_t;
+sepgsql_blob_object(sepgsql_secret_blob_t)
+
+type sepgsql_secret_table_t;
+sepgsql_table_object(sepgsql_secret_table_t)
+
+type sepgsql_sysobj_t;
+sepgsql_system_table_object(sepgsql_sysobj_t)
+
+type sepgsql_table_t;
+sepgsql_table_object(sepgsql_table_t)
+
+type sepgsql_trusted_proc_exec_t;
+sepgsql_procedure_object(sepgsql_trusted_proc_exec_t)
+
+# Trusted Procedure Domain
+type sepgsql_trusted_proc_t;
+domain_type(sepgsql_trusted_proc_t)
+sepgsql_unconfined(sepgsql_trusted_proc_t)
+role system_r types sepgsql_trusted_proc_t;
+
+########################################
+#
+# SE-PostgreSQL Local Policy
+#
+allow postgresql_t self:netlink_selinux_socket create_socket_perms;
+selinux_get_enforce_mode(postgresql_t)
+selinux_validate_context(postgresql_t)
+selinux_compute_access_vector(postgresql_t)
+selinux_compute_create_context(postgresql_t)
+selinux_compute_relabel_context(postgresql_t)
+seutil_libselinux_linked(postgresql_t)
+
+allow postgresql_t sepgsql_database_type:db_database *;
+type_transition postgresql_t postgresql_t:db_database sepgsql_db_t;
+
+allow postgresql_t sepgsql_module_type:db_database install_module;
+allow postgresql_t sepgsql_table_type:{ db_table db_column db_tuple } *;
+allow postgresql_t sepgsql_procedure_type:db_procedure *;
+allow postgresql_t sepgsql_blob_type:db_blob *;
+
+# server specific type transitions
+type_transition postgresql_t sepgsql_database_type:db_table sepgsql_sysobj_t;
+type_transition postgresql_t sepgsql_database_type:db_procedure sepgsql_proc_t;
+type_transition postgresql_t sepgsql_database_type:db_blob sepgsql_blob_t;
+
+# Database/Loadable module
+allow sepgsql_database_type sepgsql_module_type:db_database load_module;
+
+########################################
+#
+# Rules common to all clients
+#
+
+# Client domain constraint
+allow sepgsql_client_type sepgsql_db_t:db_database { getattr access get_param set_param };
+type_transition sepgsql_client_type sepgsql_client_type:db_database sepgsql_db_t;
+
+allow sepgsql_client_type sepgsql_fixed_table_t:db_table { getattr use select insert };
+allow sepgsql_client_type sepgsql_fixed_table_t:db_column { getattr use select insert };
+allow sepgsql_client_type sepgsql_fixed_table_t:db_tuple { use select insert };
+
+allow sepgsql_client_type sepgsql_table_t:db_table { getattr use select update insert delete };
+allow sepgsql_client_type sepgsql_table_t:db_column { getattr use select update insert };
+allow sepgsql_client_type sepgsql_table_t:db_tuple { use select update insert delete };
+
+allow sepgsql_client_type sepgsql_ro_table_t:db_table { getattr use select };
+allow sepgsql_client_type sepgsql_ro_table_t:db_column { getattr use select };
+allow sepgsql_client_type sepgsql_ro_table_t:db_tuple { use select };
+
+allow sepgsql_client_type sepgsql_secret_table_t:db_table getattr;
+allow sepgsql_client_type sepgsql_secret_table_t:db_column getattr;
+
+allow sepgsql_client_type sepgsql_sysobj_t:db_table { getattr use select };
+allow sepgsql_client_type sepgsql_sysobj_t:db_column { getattr use select };
+allow sepgsql_client_type sepgsql_sysobj_t:db_tuple { use select };
+
+allow sepgsql_client_type sepgsql_proc_t:db_procedure { getattr execute };
+allow sepgsql_client_type sepgsql_trusted_proc_t:db_procedure { getattr execute entrypoint };
+
+allow sepgsql_client_type sepgsql_blob_t:db_blob { create drop getattr setattr read write };
+allow sepgsql_client_type sepgsql_ro_blob_t:db_blob { getattr read };
+allow sepgsql_client_type sepgsql_secret_blob_t:db_blob getattr;
+
+tunable_policy(`sepgsql_enable_users_ddl',`
+ allow sepgsql_client_type sepgsql_table_t:db_table { create drop setattr };
+ allow sepgsql_client_type sepgsql_table_t:db_column { create drop setattr };
+ allow sepgsql_client_type sepgsql_sysobj_t:db_tuple { update insert delete };
+')
+
+########################################
+#
+# Unconfined access to this module
+#
+
+allow sepgsql_unconfined_type sepgsql_database_type:db_database *;
+allow sepgsql_unconfined_type sepgsql_table_type:{ db_table db_column db_tuple } *;
+allow sepgsql_unconfined_type sepgsql_blob_type:db_blob *;
+allow sepgsql_unconfined_type { sepgsql_proc_t sepgsql_trusted_proc_t }:db_procedure *;
+allow sepgsql_unconfined_type sepgsql_procedure_type:db_procedure { create drop getattr setattr relabelfrom relabelto };
+allow sepgsql_unconfined_type sepgsql_module_type:db_database install_module;
+
+type_transition sepgsql_unconfined_type sepgsql_unconfined_type:db_database sepgsql_db_t;
+type_transition sepgsql_unconfined_type sepgsql_database_type:db_table sepgsql_table_t;
+type_transition sepgsql_unconfined_type sepgsql_database_type:db_procedure sepgsql_proc_t;
+type_transition sepgsql_unconfined_type sepgsql_database_type:db_blob sepgsql_blob_t;
+
+
+########################################
+#
+# Allow permission to external domains
+#
+
+# relabelfrom for invalid security context
+allow sepgsql_unconfined_type unlabeled_t:db_database { setattr relabelfrom };
+allow sepgsql_unconfined_type unlabeled_t:db_table { setattr relabelfrom };
+allow sepgsql_unconfined_type unlabeled_t:db_procedure { setattr relabelfrom };
+allow sepgsql_unconfined_type unlabeled_t:db_column { setattr relabelfrom };
+allow sepgsql_unconfined_type unlabeled_t:db_tuple { update relabelfrom };
+allow sepgsql_unconfined_type unlabeled_t:db_blob { setattr relabelfrom };
+
+# administrative client domain
+optional_policy(`
+ gen_require(`
+ type unconfined_t;
+ ')
+ sepgsql_unconfined(unconfined_t)
+')
+
+optional_policy(`
+ gen_require(`
+ type sysadm_t;
+ ')
+ sepgsql_unconfined(sysadm_t)
+')
+
+# unprivilleged client domain
+optional_policy(`
+ gen_require(`
+ type user_t;
+ role user_r;
+ ')
+ sepgsql_userdom_template(user,user_t,user_r)
+')
+
+optional_policy(`
+ gen_require(`
+ type staff_t;
+ role staff_r;
+ ')
+ sepgsql_userdom_template(staff,staff_t,staff_r)
+')
+
+optional_policy(`
+ gen_require(`
+ type guest_t;
+ role guest_r;
+ ')
+ sepgsql_userdom_template(guest,guest_t,guest_r)
+')
+
+optional_policy(`
+ gen_require(`
+ type xguest_t;
+ role xguest_r;
+ ')
+ sepgsql_userdom_template(xguest,xguest_t,xguest_r)
+')
+
+optional_policy(`
+ gen_require(`
+ type httpd_t;
+ ')
+ sepgsql_unpriv_client(httpd_t)
+')
+
+optional_policy(`
+ gen_require(`
+ type httpd_sys_script_t;
+ ')
+ sepgsql_unpriv_client(httpd_sys_script_t)
+')
+
+# SE-PostgreSQL loadable modules
+optional_policy(`
+ gen_require(`
+ type lib_t, textrel_shlib_t;
+ ')
+ sepgsql_loadable_module(lib_t)
+ sepgsql_loadable_module(textrel_shlib_t)
+')
+
+########################################
+#
+# SE-PostgreSQL audit switch for debugging
+#
+tunable_policy(`sepgsql_enable_auditallow',`
+ auditallow domain sepgsql_database_type : db_database *;
+ auditallow domain sepgsql_table_type : db_table *;
+ auditallow domain sepgsql_table_type : db_column *;
+ auditallow domain sepgsql_procedure_type : db_procedure *;
+ auditallow domain sepgsql_blob_type : db_blob *;
+ auditallow domain sepgsql_module_type : db_database { install_module };
+ auditallow sepgsql_database_type sepgsql_module_type : db_database { load_module };
+')
+
+tunable_policy(`! sepgsql_enable_auditdeny',`
+ dontaudit domain sepgsql_database_type : db_database *;
+ dontaudit domain sepgsql_table_type : db_table *;
+ dontaudit domain sepgsql_table_type : db_column *;
+ dontaudit domain sepgsql_procedure_type : db_procedure *;
+ dontaudit domain sepgsql_blob_type : db_blob *;
+ dontaudit domain sepgsql_module_type : db_database { install_module };
+ dontaudit sepgsql_database_type sepgsql_module_type : db_database { load_module };
+')
+
+dontaudit domain { sepgsql_table_type - sepgsql_sysobj_table_type } : db_tuple { use select update insert delete };
+
+########################################
+#
+# SE-PostgreSQL regression test mode switch
+#
+tunable_policy(`sepgsql_regression_test_mode',`
+ allow sepgsql_client_type home_type : db_database { install_module };
+ allow sepgsql_unconfined_type home_type : db_database { install_module };
+ allow sepgsql_database_type home_type : db_database { load_module };
+')

File diff suppressed because it is too large Load diff

137
sepostgresql.8 Normal file
View file

@ -0,0 +1,137 @@
.TH "sepostgresql" "8" "Jul 15 2007" "kaigai@kaigai.gr.jp" "Security-Enhanced PostgreSQL"
.SH "NAME"
sepostgresql \- Security-Enhances PostgreSQL
.SH "DESCRIPTION"
Security-Enhanced PostgreSQL (SE-PostgreSQL) is an enhancement of PostgreSQL,
to apply fine grained mandatory access control for database objects based on
the security policy of SELinux.
These features enable to apply flexible integrated access control policy
on both of operating system and database management system, during all
stages of the life of the information.
.PP
This document describes the way to customize SE-PostgreSQL on the default
security policy.
.SH "BOOLEANS"
The SELinux policy is customizable via BOOLEAN variable. This variable has
two states, 1 (on) or 0 (off). We can validate or invalidate a part of the
security policy depending on the state of boolean variables.
\fBsepgsql_enable_users_ddl\fP enables to toggle permissions of confined
users/applications to invoke DDL statement, like CREATE TABLE. It is set to
\fBon\fP in the default.
In most cases, DDL statements are used to set up initial database structure,
and permissions to invoke them are not necessary on operation phase.
You can turn off this boolean as follows:
.EX
setsebool -P sepgsql_enable_users_ddl ( \fBon\fP | off )
.EE
Rest of booleans are provided by \fBselinux-devel.pp\fP policy module.
It provides developments/debugs related permissions.
You can install it as follows:
.EX
semodule -i /usr/share/selinux/targeted/sepostgresql-devel.pp
.EE
\fBsepgsql_enable_auditallow\fP toggles output of audit messages in the case
when required permission checks are allowed, except for tuples because it
easily make a flood of audit logs.
In the default, it is set to off. You can set it as follows:
.EX
setsebool -P sepgsql_enable_auditallow ( on | \fBoff\fP )
.EE
\fBsepgsql_enable_auditdeny\fP toggles output of audit messages in the case
when required permission checks are denied, except for tuples because it
easily make a flood of audit logs.
In the default, it is set to on. You can set it as follows:
.EX
setsebool -P sepgsql_enable_auditdeny ( \fBon\fP | off )
.EE
\fBsepgsql_regression_test_mode\fP allows to load shared libraries deployed
on user's home directory. We recommend you to keep \fBoff\fP in operation
phase to prevent to load malicious libraries.
However, typical PostgreSQL regression test requires to load it, so we
have to reduce several restriction during the test.
In the default, it is set to off. You can set it as follows:
.EX
setsebool -P sepgsql_regression_test_mode ( on | \fBoff\fP )
.EE
.SH "TYPES"
\fBsepgsql_db_t\fP is a only type for database itself.
It is attched for newly created databases in the default.
\fBsepgsql_table_t\fP is a type for tables, columns and tuples.
It is the default type of newly created tables by unconfined or
non-roled domain. It allows confined clietns to access with any
kind of operations except for relabeling, so we can use this type
for compatible purpose.
\fBsepgsql_secret_table_t\fP is a type for tables, columns and tuples.
It never allows confined clients to access, so we can use this type
to store sensitive information. We reccomend to apply trusted procedures
to access tables/columns/tuples with this type under safe operation.
\fBsepgsql_ro_table_t\fP is a type for read-only tables, columns and tuples.
It does not allow confined clients to modify any objects with this type.
\fBsepgsql_fixed_table_t\fP is a type for non-manupulatable tables, columns
and tuples. It does not allow confined clients to update or delete any
objects with this type.
\fBsepgsql_ROLE_table_t\fP is a type for a role specific tables, columns
and tuples. It allows confined clients with its role to access with any
kind of operations except for relabeling.
It is the default type of newly created tables by confined clients with
its role, and we can use this type to describe role level separation.
\fBsepgsql_proc_t\fP is a type for procedures.
It is attached for newly created procedures by unconfined clients.
It allows any clients to invoke procedures with this type.
All of PostgreSQL built-in functions are labeled as this type in the default.
\fBsepgsql_ROLE_proc_t\fP is a type for a role specific procedure.
It is attached for newly created procedures by confined clients with its role.
It allows clients with same role to invoke procedure with this type.
Note that unconfined clients cannot invoke this type to avoid to execute
dangerous functions with unconfined authorities. They have to confirm its
contains and relabel to \fBsepgsql_proc_t\fP for its invocation.
\fBsepgsql_trusted_proc_exec_t\fP is a type for trusted procedures.
To call procedures with this type invokes domain transition to
unconfined domain, so it can access any kind of database objects.
We can use this type to provide a secure method to access sensitive
information.
\fBsepgsql_blob_t\fP is a type for binary large objects (blob).
It is attached for newly created blob in the default.
Non-administrative clients can read and write the blobs with this type.
\fBsepgsql_ro_blob_t\fP is a type for read-only binary large objects (blob).
Non-administrative clients cannot write the blobs with this type.
.SH "BACKUP and RESTORE"
\fI--enable-selinux\fP option in \fBsepg_dump\fP and \fBsepg_dumpall\fP enable to dump database image with security context. We can restore the dumped image using the standard \fIpg_restore\fP and so on.
.EX
Example)
$ sepg_dump -Ft -b --enable-selinux postgres | gzip -c > postgres.tgz
.EE
.SH AUTHOR
This manual page was written by KaiGai Kohei <kaigai@kaigai.gr.jp>
.SH "SEE ALSO"
selinux(8), boolean(8)

213
sepostgresql.init Normal file
View file

@ -0,0 +1,213 @@
#!/bin/sh
# sepostgresql This is the init script for starting up SE-PostgreSQL
#
# chkconfig: - 62 38
# description: Starts and stops the SE-PostgreSQL backend daemon
# processname: postmaster
# pidfile: /var/run/postmaster.pid
#---------------------------------------------------------------------
PGVERSION="8.3.8"
PGMAJORVERSION=`echo "$PGVERSION" | sed 's/^\([0-9]*\.[0-9a-z]*\).*$/\1/'`
SEPGVERSION="2.2300"
# source function library
. /etc/rc.d/init.d/functions
# get config
. /etc/sysconfig/network
# find the name of the script
NAME=`basename $0`
if [ ${NAME:0:1} = "S" -o ${NAME:0:1} = "K" ]; then
NAME=${NAME:3}
fi
# set defaults for configurable variables
SEPGSQL_BIN="/usr/bin"
SEPGSQL_DATA="/var/lib/sepgsql/data"
SEPGSQL_OPTS="-i -p 5432"
SEPGSQL_STARTUP_LOG="/var/lib/sepgsql/pgstartup.log"
SEPGSQL_LOG="/var/log/sepostgresql.log"
SEPGSQL_FALLBACK_CONTEXT="user_u:user_r:user_t"
# override defaults from /etc/sysconfig/sepostgresql
test -f /etc/sysconfig/${NAME} && . /etc/sysconfig/${NAME}
export SEPGSQL_FALLBACK_CONTEXT
# Check that networking is up.
test "${NETWORKING}" = "no" && exit 0
test -f "${SEPGSQL_BIN}/sepostgres" || exit 1
script_result=0
do_start() {
PSQL_START=$"Starting ${NAME} service: "
echo -n "$PSQL_START"
# make sure startup-time log file is valid
if [ ! -e "${SEPGSQL_STARTUP_LOG}" -a ! -h "${SEPGSQL_STARTUP_LOG}" ]; then
touch "${SEPGSQL_STARTUP_LOG}" || exit 1
chown sepgsql:sepgsql "${SEPGSQL_STARTUP_LOG}"
chmod 600 "${SEPGSQL_STARTUP_LOG}"
/sbin/restorecon "${SEPGSQL_STARTUP_LOG}"
fi
# check for the SEPGSQL_DATA structure
if [ -f "${SEPGSQL_DATA}/PG_VERSION" ] && [ -d "${SEPGSQL_DATA}/base" ]; then
if [ x`cat "${SEPGSQL_DATA}/PG_VERSION"` != x"${PGMAJORVERSION}" ]; then
echo_failure
echo
echo "HINT: An old version of the database format was found."
echo "HINT: You need to upgrade the data format before using SE-PostgreSQL."
exit 1
fi
else
echo_failure
echo
echo "HINT: ${SEPGSQL_DATA} is missing."
echo "HINT: Use '/etc/init.d/${NAME} initdb'"
echo "HINT: to initialize the database cluster first."
exit 1
fi
# make sure SEPGSQL_LOG
touch ${SEPGSQL_LOG}
chown sepgsql:sepgsql ${SEPGSQL_LOG}
chmod 600 ${SEPGSQL_LOG}
test -x /sbin/restorecon && /sbin/restorecon ${SEPGSQL_LOG}
cd ${SEPGSQL_BIN}
/sbin/runuser sepgsql -c "./sepg_ctl -l ${SEPGSQL_LOG} -D ${SEPGSQL_DATA} -o '${SEPGSQL_OPTS}' start" \
>> ${SEPGSQL_STARTUP_LOG} 2>&1 < /dev/null
sleep 1
PID=`/sbin/runuser sepgsql -c "./sepg_ctl -D ${SEPGSQL_DATA} status 2>/dev/null \
| sed 's/^.*PID: //g' | sed 's/[^0-9].*$//g'"`
if [ ${PIPESTATUS[0]} -eq 0 ]; then
echo "$PID" > "/var/run/${NAME}.pid"
touch "/var/lock/subsys/${NAME}.lock"
echo_success
else
script_result=1
echo_failure
fi
echo
}
do_stop() {
echo -n $"Stopping ${NAME} service: "
cd ${SEPGSQL_BIN}
/sbin/runuser sepgsql -c "./sepg_ctl -D ${SEPGSQL_DATA} stop" \
>> ${SEPGSQL_STARTUP_LOG} 2>&1 < /dev/null
ret=$?
if [ $ret -eq 0 ]; then
echo_success
else
echo_failure
script_result=1
fi
echo
rm -f "/var/run/${NAME}.pid"
rm -f "/var/lock/subsys/${NAME}.lock"
}
do_status() {
cd ${SEPGSQL_BIN}
/sbin/runuser sepgsql -- -c "./sepg_ctl -D ${SEPGSQL_DATA} status" 2>/dev/null \
| head -1 | sed "s/^sepg_ctl:/${NAME}:/g"
if [ ${PIPESTATUS[0]} -ne 0 ]; then
script_result=3
test -e "/var/run/${NAME}.pid" && script_result=1
test -e "/var/lock/subsys/${NAME}.lock" && script_result=2
fi
}
do_condrestart() {
cd ${SEPGSQL_BIN}
/sbin/runuser sepgsql -- -c "./sepg_ctl -D ${SEPGSQL_DATA} status" &>/dev/null && do_stop && do_start
}
do_condstop() {
cd ${SEPGSQL_BIN}
/sbin/runuser sepgsql -- -c "./sepg_ctl -D ${SEPGSQL_DATA} status" &>/dev/null && do_stop
}
do_reload() {
echo -n $"Reloading ${NAME} service: "
cd ${SEPGSQL_BIN}
/sbin/runuser sepgsql -- -c "./sepg_ctl -D ${SEPGSQL_DATA} reload" &>/dev/null < /dev/null
if [ $? -eq 0 ]; then
echo_success
else
echo_failure
script_result=1
fi
echo
}
do_initdb() {
echo -n $"Initializing database: "
if [ -f "${SEPGSQL_DATA}/PG_VERSION" ]; then
echo_failure
echo
echo "HINT: Data directory is not empty"
script_result=1
else
if [ ! -e "${SEPGSQL_DATA}" -a ! -h "${SEPGSQL_DATA}" ]; then
mkdir -p "${SEPGSQL_DATA}" || exit 1
chown sepgsql:sepgsql "${SEPGSQL_DATA}"
chmod 600 "${SEPGSQL_DATA}"
fi
# cleanup SELinux labeling for "${SEPGSQL_DATA}"
test -x /sbin/restorecon && /sbin/restorecon -R "${SEPGSQL_DATA}"
# Initialize the database
cd ${SEPGSQL_BIN}
/sbin/runuser -- sepgsql -c "./initdb.sepgsql --pgace-feature=selinux -A 'ident sameuser' ${SEPGSQL_DATA}" \
>> "${SEPGSQL_STARTUP_LOG}" 2>&1 < /dev/null
if [ -f "${SEPGSQL_DATA}/PG_VERSION" ]; then
echo_success
else
echo_failure
script_result=1
fi
echo
fi
}
# see how we were called.
case "$1" in
start)
do_start
;;
stop)
do_stop
;;
status)
do_status
;;
restart)
do_stop
do_start
;;
condrestart)
do_condrestart
;;
condstop)
do_condstop
;;
reload|force-reload)
do_reload
;;
initdb)
do_initdb
;;
*)
echo $"Usage: $0 {start|stop|status|restart|condrestart|condstop|reload|force-reload|initdb}"
exit 1
;;
esac
exit $script_result

11
sepostgresql.logrotate Normal file
View file

@ -0,0 +1,11 @@
# logrotate configuration for SE-PostgreSQL
/var/log/sepostgresql.log {
rotate 4
compress
size 4M
notifempty
postrotate
/sbin/service sepostgresql restart >& /dev/null
endscript
}

457
sepostgresql.spec Normal file
View file

@ -0,0 +1,457 @@
#
# Security Enhanced PostgreSQL (SE-PostgreSQL)
#
# Copyright 2007 KaiGai Kohei <kaigai@kaigai.gr.jp>
# -----------------------------------------------------
# SE-PostgreSQL status extension
%define selinux_policy_stores targeted mls
%{!?ssl:%define ssl 1}
Summary: Security Enhanced PostgreSQL
Name: sepostgresql
Version: 8.3.8
Release: 2.2300%{?sepgsql_extension}%{?dist}
License: BSD
Group: Applications/Databases
Url: http://code.google.com/p/sepgsql/
Buildroot: %(mktemp -ud %{_tmppath}/%{name}-%{version}-%{release}-XXXXXX)
Source0: ftp://ftp.postgresql.org/pub/source/v%{version}/postgresql-%{version}.tar.bz2
Source1: sepostgresql.init
Source2: sepostgresql.8
Source3: sepostgresql.logrotate
Patch0: sepostgresql-sepgsql-8.3.8-2.patch
Patch1: sepostgresql-policy-8.3.8-2.patch
Patch2: sepostgresql-pg_dump-8.3.8-2.patch
Patch3: sepostgresql-fedora-prefix.patch
BuildRequires: perl glibc-devel bison flex readline-devel zlib-devel >= 1.0.4
BuildRequires: checkpolicy libselinux-devel >= 2.0.43
BuildRequires: selinux-policy >= 3.4.2
%if %{ssl}
BuildRequires: openssl-devel
%endif
Requires(pre): shadow-utils
Requires(post): policycoreutils /sbin/chkconfig
Requires(preun): /sbin/chkconfig /sbin/service
Requires(postun): policycoreutils
Requires: postgresql-server = %{version}
Requires: policycoreutils >= 2.0.16 libselinux >= 2.0.43
Requires: selinux-policy >= 3.4.2
Requires: tzdata logrotate
%description
Security Enhanced PostgreSQL is an extension of PostgreSQL
based on SELinux security policy, that applies fine grained
mandatory access control to many objects within the database,
and takes advantage of user authorization integrated within
the operating system. SE-PostgreSQL works as a userspace
reference monitor to check any SQL query.
%prep
%setup -q -n postgresql-%{version}
%patch0 -p1
%patch1 -p1
%patch2 -p1
%patch3 -p1
%build
CFLAGS="${CFLAGS:-%optflags}" ; export CFLAGS
CXXFLAGS="${CXXFLAGS:-%optflags}" ; export CXXFLAGS
# build SE-PostgreSQL
%configure --disable-rpath \
--enable-selinux \
%if %{ssl}
--with-openssl \
%endif
%if %{defined sepgextension}
--enable-debug \
--enable-cassert \
%endif
--libdir=%{_libdir}/pgsql \
--datadir=%{_datadir}/sepgsql \
--with-system-tzdata=/usr/share/zoneinfo
# parallel build, if possible
make %{?_smp_mflags}
touch src/backend/security/sepgsql/policy/sepostgresql-devel.fc
make -C src/backend/security/sepgsql/policy
%install
rm -rf %{buildroot}
make DESTDIR=%{buildroot} install
for store in %{selinux_policy_stores}
do
install -d %{buildroot}%{_datadir}/selinux/${store}
install -p -m 644 src/backend/security/sepgsql/policy/sepostgresql-devel.pp.${store} \
%{buildroot}%{_datadir}/selinux/${store}/sepostgresql-devel.pp
done
# avoid to conflict with native postgresql package
mv %{buildroot}%{_bindir} %{buildroot}%{_bindir}.orig
install -d %{buildroot}%{_bindir}
mv %{buildroot}%{_bindir}.orig/initdb %{buildroot}%{_bindir}/initdb.sepgsql
mv %{buildroot}%{_bindir}.orig/pg_ctl %{buildroot}%{_bindir}/sepg_ctl
mv %{buildroot}%{_bindir}.orig/postgres %{buildroot}%{_bindir}/sepostgres
mv %{buildroot}%{_bindir}.orig/pg_dump %{buildroot}%{_bindir}/sepg_dump
mv %{buildroot}%{_bindir}.orig/pg_dumpall %{buildroot}%{_bindir}/sepg_dumpall
# remove unnecessary files
rm -rf %{buildroot}%{_bindir}.orig
rm -rf %{buildroot}%{_libdir}
rm -rf %{buildroot}%{_includedir}
rm -rf %{buildroot}%{_usr}/doc
rm -rf %{buildroot}%{_datadir}/sepgsql/timezone
rm -rf %{buildroot}%{_mandir}
# /var/lib/sepgsql
install -d -m 700 %{buildroot}%{_localstatedir}/lib/sepgsql
install -d -m 700 %{buildroot}%{_localstatedir}/lib/sepgsql/data
install -d -m 700 %{buildroot}%{_localstatedir}/lib/sepgsql/backups
# /etc/rc.d/init.d/*
mkdir -p %{buildroot}%{_initrddir}
install -p -m 755 %{SOURCE1} %{buildroot}%{_initrddir}/sepostgresql
# /usr/share/man/*
mkdir -p %{buildroot}%{_mandir}/man8
install -p -m 644 %{SOURCE2} %{buildroot}%{_mandir}/man8
# /etc/logrotate.d/
mkdir -p %{buildroot}%{_sysconfdir}/logrotate.d
install -p -m 644 %{SOURCE3} %{buildroot}%{_sysconfdir}/logrotate.d/sepostgresql
%clean
rm -rf %{buildroot}
%pre
getent group sepgsql >/dev/null || groupadd -r sepgsql
getent passwd sepgsql >/dev/null || \
useradd -r -g sepgsql -d %{_localstatedir}/lib/sepgsql -s /bin/bash \
-c "SE-PostgreSQL server" sepgsql
exit 0
%post
/sbin/chkconfig --add %{name}
/sbin/ldconfig
for store in %{selinux_policy_stores}
do
# clean up legacy policy module (now it is unnecessary)
%{_sbindir}/semodule -s ${store} -r sepostgresql >& /dev/null || :
if %{_sbindir}/semodule -s ${store} -l 2>/dev/null | grep -Eq "^sepostgresql-devel"; then
%{_sbindir}/semodule -s ${store} \
-i %{_datadir}/selinux/${store}/sepostgresql-devel.pp >& /dev/null || :
fi
done
# Fix up non-standard file contexts
/sbin/fixfiles -R %{name} restore || :
/sbin/restorecon -R %{_localstatedir}/lib/sepgsql || :
%preun
if [ $1 -eq 0 ]; then # rpm -e case
/sbin/service %{name} condstop >/dev/null 2>&1
/sbin/chkconfig --del %{name}
fi
%postun
/sbin/ldconfig
if [ $1 -ge 1 ]; then # rpm -U case
/sbin/service %{name} condrestart >/dev/null 2>&1 || :
fi
if [ $1 -eq 0 ]; then # rpm -e case
for store in %{selinux_policy_stores}
do
%{_sbindir}/semodule -s ${store} -r sepostgresql-devel >& /dev/null || :
done
/sbin/fixfiles -R %{name} restore || :
test -d %{_localstatedir}/lib/sepgsql && /sbin/restorecon -R %{_localstatedir}/lib/sepgsql || :
fi
%files
%defattr(-,root,root,-)
%doc COPYRIGHT README
%{_initrddir}/sepostgresql
%{_sysconfdir}/logrotate.d/sepostgresql
%{_bindir}/initdb.sepgsql
%{_bindir}/sepg_ctl
%{_bindir}/sepostgres
%{_bindir}/sepg_dump
%{_bindir}/sepg_dumpall
%{_mandir}/man8/sepostgresql.*
%dir %{_datadir}/sepgsql
%{_datadir}/sepgsql/postgres.bki
%{_datadir}/sepgsql/postgres.description
%{_datadir}/sepgsql/postgres.shdescription
%{_datadir}/sepgsql/system_views.sql
%{_datadir}/sepgsql/*.sample
%{_datadir}/sepgsql/snowball_create.sql
%{_datadir}/sepgsql/timezonesets/
%{_datadir}/sepgsql/tsearch_data/
%{_datadir}/sepgsql/conversion_create.sql
%{_datadir}/sepgsql/information_schema.sql
%{_datadir}/sepgsql/sql_features.txt
%attr(644,root,root) %{_datadir}/selinux/*/sepostgresql-devel.pp
%attr(700,sepgsql,sepgsql) %dir %{_localstatedir}/lib/sepgsql
%attr(700,sepgsql,sepgsql) %dir %{_localstatedir}/lib/sepgsql/data
%attr(700,sepgsql,sepgsql) %dir %{_localstatedir}/lib/sepgsql/backups
%changelog
* Thu Sep 10 2009 KaiGai Kohei <kaigai@kaigai.gr.jp> - 8.3.8-2300
- upgrade base PostgreSQL v8.3.7->8.3.8
* Fri Apr 17 2009 KaiGai Kohei <kaigai@kaigai.gr.jp> - 8.3.7-1772
- bugfix: /etc/init.d/sepostgresql initdb didn't work correctly
* Fri Mar 27 2009 KaiGai Kohei <kaigai@kaigai.gr.jp> - 8.3.7-2.1770
- upgrade base PostgreSQL version 8.3.6->8.3.7
* Thu Feb 26 2009 KaiGai Kohei <kaigai@kaigai.gr.jp> - 8.3.6-2.1635
- bugfix: possible information leak by the order of permission checks
in row level permission checks.
* Wed Feb 25 2009 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 8.3.6-3.1518
- Rebuilt for https://fedoraproject.org/wiki/Fedora_11_Mass_Rebuild
* Fri Feb 6 2009 <kaigai@kaigai.gr.jp> - 8.3.6-2.1523
- upgrade base PostgreSQL version 8.3.5->8.3.6
- backport features from 8.4devel tree
- security policy fix for Fedora 9
* Sat Jan 17 2009 Tomas Mraz <tmraz@redhat.com> - 8.3.5-2.1183
- rebuild with new openssl
* Wed Nov 5 2008 <kaigai@kaigai.gr.jp> - 8.3.5-2.1182
- upgrade base PostgreSQL version 8.3.4->8.3.5
- backport cumulative bugfixes from 8.4devel series
* Thu Oct 2 2008 <kaigai@kaigai.gr.jp> - 8.3.4-2.1076
- bugfix: "(null)" audit logs for non-cached decision making.
- A hook is added for "COPY TO/FROM <file>" cases.
* Sat Sep 27 2008 <kaigai@kaigai.gr.jp> - 8.3.4-2.1066
- update base version to 8.3.4
- sepostgresql.pp was marked as obsolute
* Tue Sep 23 2008 <kaigai@kaigai.gr.jp> - 8.3.3-2.1043
- bugfix: a case when INSERT a FK reference to invisible PK
* Wed Aug 13 2008 <kaigai@kaigai.gr.jp> - 8.3.3-2.964
- bugfix: trusted procedure invokation
* Fri Jul 11 2008 <kaigai@kaigai.gr.jp> - 8.3.3-2.952
- Security policy module updates
* Fri Jul 11 2008 <kaigai@kaigai.gr.jp> - 8.3.3-2.945
- Add OpenSSL support
- backport 8.4devel fixes
* Sun Jun 15 2008 <kaigai@kaigai.gr.jp> - 8.3.3-2.889
- backport 8.4devel features.
* Fri Jun 13 2008 <kaigai@kaigai.gr.jp> - 8.3.3-2.869
- upgrade base PostgreSQL 8.3.1 -> 8.3.3
* Wed Apr 30 2008 <kaigai@kaigai.gr.jp> - 8.3.1-2.197
- Inconsistent version number format at Changelogs
* Wed Apr 30 2008 <kaigai@kaigai.gr.jp> - 8.3.1-2.196
- BUGFIX: ROW-level control did not work correctly on TRUNCATE
* Sun Mar 9 2008 <kaigai@kaigai.gr.jp> - 8.3.0-2.129
- BUGFIX: more conprehensive fixes in "SELECT COUNT(*) ..."
* Sun Mar 2 2008 <kaigai@kaigai.gr.jp> - 8.3.0-2.120
- BUGFIX: CREATE TABLE statement with explicit labeled columns
- BUGFIX: SELECT count(*) does not filter unallowed tuples
* Wed Feb 27 2008 <kaigai@kaigai.gr.jp> - 8.3.0-2.117
- ".beta" removed.
* Wed Feb 27 2008 <kaigai@kaigai.gr.jp> - 8.3.0-2.114
- Security policy updates
* Tue Feb 26 2008 <kaigai@kaigai.gr.jp> - 8.3.0-2.113
- BUGFIX: CREATE/ALTER TABLE with CONTEXT='...' did nothing.
* Thu Feb 7 2008 <kaigai@kaigai.gr.jp> - 8.3.0-2.108
- add /etc/logrotate.d/sepostgresql
* Thu Feb 7 2008 <kaigai@kaigai.gr.jp> - 8.3.0-2.105
- update base version to stable 8.3.0
- add tzdata dependency
- allow db_database:{get_param set_param} for generic domain
- error message cleanups
- Improve large object hooks in PGACE framework
- BUGFIX: db_blob:{drop} was checked at loread()
- BUGFIX: incorrect permission in DELETE with RETURNING clause
- incorrect permission when we read and update security_context in same time.
* Fri Jan 25 2008 <kaigai@kaigai.gr.jp> - 8.3RC2-2.62
- BUGFIX: add handling to invalid contexts already stored
* Tue Jan 22 2008 <kaigai@kaigai.gr.jp> - 8.3RC2-2.56
- BUGFIX: lack of locks when refering buffer pages at update/delete hooks
- BUGFIX: explicit labeling using SELECT ... INTO statement.
* Sun Jan 20 2008 <kaigai@kaigai.gr.jp> - 8.3RC2-2.52
- shares /usr/lib/pgsql/*.so libraries, with original postgresql.
* Thu Jan 10 2008 <kaigai@kaigai.gr.jp> - 8.3RC1-2.37
- add sepg_dump/sepg_dumpall support for 8.3base package.
* Mon Nov 26 2007 <kaigai@kaigai.gr.jp> - 8.3beta3-2.0
- Branch from 8.2.x tree
* Wed Nov 21 2007 <kaigai@kaigai.gr.jp> - 8.2.5-1.66
- Add a policy module hotfix for labeled networking
* Thu Nov 1 2007 <kaigai@kaigai.gr.jp> - 8.2.5-1.51
- Re-organize repository to prepare to branch 8.3.x based tree.
(no differences from 8.2.5-1.33)
* Wed Oct 17 2007 <kaigai@kaigai.gr.jp> - 8.2.5-1.33
- Fix bug: security context was not canonicalized
when irregular context (but interpretable) was inputed.
* Mon Oct 15 2007 <kaigai@kaigai.gr.jp> - 8.2.5-1.31
- Fix bug: type definitions of security_label_to_text()
and text_to_security_label() are mismatched.
* Sat Sep 22 2007 <kaigai@kaigai.gr.jp> - 8.2.5-1.23
- update base PostgreSQL to 8.2.5
* Mon Sep 1 2007 <kaigai@kaigai.gr.jp> - 8.2.4-1.0
- mark as SE-PostgreSQL 8.2.4-1.0
* Thu Aug 28 2007 <kaigai@kaigai.gr.jp> - 8.2.4-0.434.beta
- add Requires: postgresql-server, instead of Conflicts: tag
(Some sharable files are removed from sepostgresql package)
* Fri Aug 24 2007 <kaigai@kaigai.gr.jp> - 8.2.4-0.429.beta
- add policycoreutils to Requires(post/postun)
- upstreamed selinux-policy got SE-PostgreSQL related object classes definition.
* Sat Aug 18 2007 <kaigai@kaigai.gr.jp> - 8.2.4-0.427.beta
- sepg_dumpall uses /usr/bin/sepg_dump
* Fri Aug 17 2007 <kaigai@kaigai.gr.jp> - 8.2.4-0.423.beta
- fix policy not to execute sepgsql_user_proc_t from administrative domain
* Fri Aug 10 2007 <kaigai@kaigai.gr.jp> - 8.2.4-0.418.beta
- object classes are renamed with "db_" prefix
- /etc/init.d/sepostgresql script is improved.
* Thu Aug 2 2007 <kaigai@kaigai.gr.jp> - 8.2.4-0.409.beta
- specfile updated based on the following comments
https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=249522#c5
* Mon Jul 30 2007 <kaigai@kaigai.gr.jp> - 8.2.4-0.407.beta
- fix spec file based on Fedora reviewing process
- add rawhide support
* Mon Jul 23 2007 <kaigai@kaigai.gr.jp> - 8.2.4-0.402.beta
- add manpage of sepostgresql
- fix specfile convention for Fedora suitable
* Sun Jul 15 2007 <kaigai@kaigai.gr.jp> - 8.2.4-0.398.beta
- SECCLASS_DATABASE is updated (fc7->62, fc6->61)
* Sun Jul 1 2007 <kaigai@kaigai.gr.jp> - 8.2.4-0.391.beta
- Mark as a beta version.
* Sat Jun 30 2007 <kaigai@kaigai.gr.jp> - 8.2.4-0.384.alpha
- add fallback context support with $SEPGSQL_FALLBACK_CONTEXT
- add sepgsql_enable_users_ddl boolean to restrict sepgsql_sysobj_t
- BUGFIX: incorrect inherited attribute expanding for RECORD type (attno=0)
- BUGFIX: trigger functions were not checked in COPY FROM statement
* Tue Jun 26 2007 <kaigai@kaigai.gr.jp> - 8.2.4-0.376.alpha
- add pgaceExecutorStart() to hook ExecutorStart()
* Mon Jun 25 2007 <kaigai@kaigai.gr.jp> - 8.2.4-0.372.alpha
- add table name prefix for column name on audit messages
- use security_label_raw_in as an alternative for security_label_in
- add hook for query execution path with SPI_ interface
- add trigger function suppoer
- BUGFIX: remove unnecessary checks for COPY TO/FROM on non-table relation
- BUGFIX: remove unnecessary checks for LOCK on non-table relation
- BUGFIX: incorrect object id for tuples within pg_security
- BUGFIX: CommandCounterIncrement() might be called during heap_create_with_catalog.
- BUGFIX: correct self-deadlock
- update security policy: sepgsql_sysobj_t, sepgsql_user_proc_t, sepgsql_ro_blob_t
* Tue Jun 19 2007 <kaigai@kaigai.gr.jp> - 8.2.4-0.351.alpha
- BUGFIX: sepgsql_compute_avc_datum() accessed userspace AVC without
holding any lock.
- improve build scripts.
* Sat Jun 16 2007 <kaigai@kaigai.gr.jp> - 8.2.4-0.320.alpha
- update: sepostgresql.pp security policy fot strict/mls suitable
- BUGFIX: column:drop evaluation for ALTER TABLE tbl DROP col; statement
- add --enable-security option for pg_dumpall command
- add {use} permission for table/column/tuple object classes
* Tue May 29 2007 <kaigai@kaigai.gr.jp> - 8.2.4-0.306.alpha
- BUGFIX: RangeTblEntry->requiredPerms are polluted.
* Sun May 27 2007 <kaigai@kaigai.gr.jp> - 8.2.4-0.304.alpha
- add support for dynamic object class/access vector mapping
- BUGFIX: Lack of implicit labeling on COPY FROM statement for system catalogs
- BUGFIX: Incorrect security context handling for inherited tables
* Fri May 25 2007 <kaigai@kaigai.gr.jp> - 8.2.4-0.292.alpha
- add pg_dump/pg_dumpall/pg_restore with --enable-security option
- add support on OUTER JOIN by rewriting query.
- add security_context support on COPY TO/FROM statement
- add unlabeled security context support (enable to obtain /selinux/initial_contexts/*)
- BUGFIX: lack of checks on JOIN ON condition
- BUGFIX: pseudo relation object (sequence, toast, ...) are not handled as database obj.
- BUGFIX: lack of tuple:insert checks at COPY FROM statement
- BUGFIX: server crash when CREATE TABLE command with newly defined CONTEXT = '...'.
* Wed May 16 2007 <kaigai@kaigai.gr.jp> - 8.2.4-0.266.alpha
- BUGFIX: incorrect security context of newly generated system object.
- BUGFIX: missing error text when audit log is disabled.
- BUGFIX: incorrect Oid of newly generated tuples within pg_security.
- BUGFIX: sepgsql_enable_audittuple is misconditioned.
- add checks for T_RowExpr/T_RowCompareExpr/T_BooleanTest
T_DistinctExpr/T_ConvertRowtypeExpr
- add support CONTEXT = 'xxx' for CREATE TABLE/FUNCTION/DATABASE statement
* Sun Apr 30 2007 <kaigai@kaigai.gr.jp> - 8.2.4-0.240.alpha
- update base version 8.2.3 -> 8.2.4
- BUGFIX: unexpected expose in OUTER JOIN statement.
add rewrite OUTER JOIN into SUBQUERY to ensure filtering violated tuples.
- BUGFIX: strange operation in text_to_security_label()
- BUGFIX: infinite recursive call on security label -> oid mapping
- BUGFIX: sepgsql_avc_init() is called in policy state monitoring process
to avoid nonsense initialization of avc_shmem.
* Fri Apr 27 2007 <kaigai@kaigai.gr.jp> - 8.2.3-0.232.alpha
- object class numbers were redefined. (SECCLASS_DATABASE got into 61)
- is_selinux_enabled() was cached on the shared memory segment.
- BUGFIX: server went into infinit loop on foreign key constraint.
* Mon Apr 16 2007 <kaigai@kaigai.gr.jp> - 8.2.3-0.226.alpha
- BUGFIX: cases when several variables with same type in a single table
* Sat Apr 07 2007 <kaigai@kaigai.gr.jp> - 8.2.3-0.214.alpha
- add the first implementation of SE-PostgreSQL on PGACE framework
* Wed Mar 21 2007 <kaigai@kaigai.gr.jp> - 8.2.3-0.212.alpha
- BUGFIX: SetOperation didn't handle its subquery correctly.
So, it caused server crash.
* Wed Mar 07 2007 <kaigai@kaigai.gr.jp> - 8.2.3-0.209.alpha
- BUGFIX: var->varlevelsup was ignored, so outer references
from subqueries cause a fault.
* Tue Feb 27 2007 <kaigai@kaigai.gr.jp> - 8.2.3-0.178.alpha
- Initial RPM build

1
sources Normal file
View file

@ -0,0 +1 @@
aac683d03f765dc58a3a0e5eaa1927bf postgresql-8.3.8.tar.bz2