rpms/sepostgresql/devel sepostgresql-core-8.3.patch, NONE, 1.1 sepostgresql-test-8.3.patch, NONE, 1.1 sepostgresql-utils-8.3.patch, NONE, 1.1 .cvsignore, 1.13, 1.14 sepostgresql.init, 1.30, 1.31 sepostgresql.spec, 1.33, 1.34 sources, 1.10, 1.11 sepostgresql-pg_dump-8.3.6-2.patch, 1.1, NONE sepostgresql-policy-8.3.6-2.patch, 1.2, NONE sepostgresql-sepgsql-8.3.6-2.patch, 1.2, NONE
KaiGai Kohei
kaigai at fedoraproject.org
Fri Mar 27 03:54:43 UTC 2009
- Previous message: rpms/sepostgresql/F-10 sepostgresql-pg_dump-8.3.7-2.patch, NONE, 1.1 sepostgresql-policy-8.3.7-2.patch, NONE, 1.1 sepostgresql-sepgsql-8.3.7-2.patch, NONE, 1.1 .cvsignore, 1.13, 1.14 sepostgresql.init, 1.30, 1.31 sepostgresql.spec, 1.31, 1.32 sources, 1.10, 1.11 sepostgresql-pg_dump-8.3.6-2.patch, 1.1, NONE sepostgresql-policy-8.3.6-2.patch, 1.2, NONE sepostgresql-sepgsql-8.3.6-2.patch, 1.2, NONE
- Next message: rpms/repoview/devel .cvsignore, 1.10, 1.11 repoview.spec, 1.13, 1.14 sources, 1.11, 1.12 repoview-case.patch, 1.1, NONE
- Messages sorted by:
[ date ]
[ thread ]
[ subject ]
[ author ]
Author: kaigai
Update of /cvs/pkgs/rpms/sepostgresql/devel
In directory cvs1.fedora.phx.redhat.com:/tmp/cvs-serv9053
Modified Files:
.cvsignore sepostgresql.init sepostgresql.spec sources
Added Files:
sepostgresql-core-8.3.patch sepostgresql-test-8.3.patch
sepostgresql-utils-8.3.patch
Removed Files:
sepostgresql-pg_dump-8.3.6-2.patch
sepostgresql-policy-8.3.6-2.patch
sepostgresql-sepgsql-8.3.6-2.patch
Log Message:
- upgrade base PostgreSQL 8.3.6->8.3.7
- backport features from 8.4devel tree
sepostgresql-core-8.3.patch:
--- NEW FILE sepostgresql-core-8.3.patch ---
diff -rpNU3 base/configure sepgsql-new/configure
--- base/configure 2009-03-15 17:47:25.000000000 +0900
+++ sepgsql-new/configure 2009-03-15 17:58:10.000000000 +0900
@@ -314,7 +314,7 @@ ac_includes_default="\
# include <unistd.h>
#endif"
-ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS configure_args build build_cpu build_vendor build_os host host_cpu host_vendor host_os PORTNAME docdir enable_nls WANTED_LANGUAGES default_port enable_shared enable_rpath enable_debug enable_profiling DTRACE DTRACEFLAGS enable_dtrace CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT CPP GCC TAS autodepend INCLUDES enable_thread_safety with_tcl with_perl with_python with_gssapi with_krb5 krb_srvtab with_pam with_ldap with_bonjour with_openssl with_ossp_uuid XML2_CONFIG with_libxml with_libxslt with_system_tzdata with_zlib EGREP ELF_SYS LDFLAGS_SL LD with_gnu_ld ld_R_works RANLIB ac_ct_RANLIB STRIP ac_ct_STRIP STRIP_STATIC_LIB STRIP_SHARED
_LIB TAR LN_S AWK YACC YFLAGS FLEX FLEXFLAGS PERL perl_archlibexp perl_privlibexp perl_useshrplib perl_embed_ldflags PYTHON python_version python_configdir python_includespec python_libdir python_libspec python_additional_libs OSSP_UUID_LIBS HAVE_IPV6 LIBOBJS acx_pthread_config PTHREAD_CC PTHREAD_LIBS PTHREAD_CFLAGS LDAP_LIBS_FE LDAP_LIBS_BE HAVE_POSIX_SIGNALS MSGFMT MSGMERGE XGETTEXT localedir TCLSH TCL_CONFIG_SH TCL_INCLUDE_SPEC TCL_LIB_FILE TCL_LIBS TCL_LIB_SPEC TCL_SHARED_BUILD TCL_SHLIB_LD_LIBS NSGMLS JADE have_docbook DOCBOOKSTYLE COLLATEINDEX SGMLSPL vpath_build LTLIBOBJS'
+ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS configure_args build build_cpu build_vendor build_os host host_cpu host_vendor host_os PORTNAME docdir enable_nls WANTED_LANGUAGES default_port enable_shared enable_rpath enable_debug enable_profiling DTRACE DTRACEFLAGS enable_dtrace CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT CPP GCC TAS autodepend INCLUDES enable_thread_safety with_tcl with_perl with_python with_gssapi with_krb5 krb_srvtab with_pam with_ldap with_bonjour with_openssl with_ossp_uuid XML2_CONFIG with_libxml with_libxslt with_system_tzdata with_zlib enable_selinux EGREP ELF_SYS LDFLAGS_SL LD with_gnu_ld ld_R_works RANLIB ac_ct_RANLIB STRIP ac_ct_STRIP STRIP_STATIC_L
IB STRIP_SHARED_LIB TAR LN_S AWK YACC YFLAGS FLEX FLEXFLAGS PERL perl_archlibexp perl_privlibexp perl_useshrplib perl_embed_ldflags PYTHON python_version python_configdir python_includespec python_libdir python_libspec python_additional_libs OSSP_UUID_LIBS HAVE_IPV6 LIBOBJS acx_pthread_config PTHREAD_CC PTHREAD_LIBS PTHREAD_CFLAGS LDAP_LIBS_FE LDAP_LIBS_BE HAVE_POSIX_SIGNALS MSGFMT MSGMERGE XGETTEXT localedir TCLSH TCL_CONFIG_SH TCL_INCLUDE_SPEC TCL_LIB_FILE TCL_LIBS TCL_LIB_SPEC TCL_SHARED_BUILD TCL_SHLIB_LD_LIBS NSGMLS JADE have_docbook DOCBOOKSTYLE COLLATEINDEX SGMLSPL vpath_build LTLIBOBJS'
ac_subst_files=''
# Initialize some variables set by options.
@@ -871,6 +871,7 @@ Optional Features:
--enable-cassert enable assertion checks (for debugging)
--enable-thread-safety make client libraries thread-safe
--enable-thread-safety-force force thread-safety despite thread test failure
+ --enable-selinux enable to build with SELinux support
--disable-largefile omit support for large files
Optional Packages:
@@ -4619,6 +4620,115 @@ fi;
#
+# SELinux support
+#
+
+pgac_args="$pgac_args enable_selinux"
+
+# Check whether --enable-selinux or --disable-selinux was given.
+if test "${enable_selinux+set}" = set; then
+ enableval="$enable_selinux"
+
+ case $enableval in
+ yes)
+ :
+ ;;
+ no)
+ :
+ ;;
+ *)
+ { { echo "$as_me:$LINENO: error: no argument expected for --enable-selinux option" >&5
+echo "$as_me: error: no argument expected for --enable-selinux option" >&2;}
+ { (exit 1); exit 1; }; }
+ ;;
+ esac
+
+else
+ enable_selinux=no
+
+fi;
+
+if test "$enable_selinux" = yes; then
+ echo "$as_me:$LINENO: checking for getpeercon in -lselinux" >&5
+echo $ECHO_N "checking for getpeercon in -lselinux... $ECHO_C" >&6
+if test "${ac_cv_lib_selinux_getpeercon+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lselinux $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+/* Override any gcc2 internal prototype to avoid an error. */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char getpeercon ();
+int
+main ()
+{
+getpeercon ();
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_lib_selinux_getpeercon=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_selinux_getpeercon=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_selinux_getpeercon" >&5
+echo "${ECHO_T}$ac_cv_lib_selinux_getpeercon" >&6
+if test $ac_cv_lib_selinux_getpeercon = yes; then
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_SELINUX 1
+_ACEOF
+
+
+else
+ { { echo "$as_me:$LINENO: error: \"--enable-selinux requires libselinux.\"" >&5
+echo "$as_me: error: \"--enable-selinux requires libselinux.\"" >&2;}
+ { (exit 1); exit 1; }; }
+fi
+
+fi
+
+#
# Elf
#
@@ -26019,6 +26129,7 @@ s, at with_libxml@,$with_libxml,;t t
s, at with_libxslt@,$with_libxslt,;t t
s, at with_system_tzdata@,$with_system_tzdata,;t t
s, at with_zlib@,$with_zlib,;t t
+s, at enable_selinux@,$enable_selinux,;t t
s, at EGREP@,$EGREP,;t t
s, at ELF_SYS@,$ELF_SYS,;t t
s, at LDFLAGS_SL@,$LDFLAGS_SL,;t t
diff -rpNU3 base/configure.in sepgsql-new/configure.in
--- base/configure.in 2009-03-15 17:47:25.000000000 +0900
+++ sepgsql-new/configure.in 2009-03-15 17:58:10.000000000 +0900
@@ -626,6 +626,19 @@ PGAC_ARG_BOOL(with, zlib, yes,
AC_SUBST(with_zlib)
#
+# SELinux support
+#
+PGAC_ARG_BOOL(enable, selinux, no,
+ [ --enable-selinux enable to build with SELinux support])
+if test "$enable_selinux" = yes; then
+ AC_CHECK_LIB(selinux, getpeercon,
+ AC_DEFINE_UNQUOTED(HAVE_SELINUX, 1,
+ [SE-PostgreSQL feature is enabled])
+ AC_SUBST(enable_selinux),
+ AC_MSG_ERROR("--enable-selinux requires libselinux."))
+fi
+
+#
# Elf
#
diff -rpNU3 base/src/Makefile.global.in sepgsql-new/src/Makefile.global.in
--- base/src/Makefile.global.in 2007-11-17 20:15:40.000000000 +0900
+++ sepgsql-new/src/Makefile.global.in 2009-03-13 18:14:33.000000000 +0900
@@ -165,6 +165,7 @@ enable_rpath = @enable_rpath@
enable_nls = @enable_nls@
enable_debug = @enable_debug@
enable_dtrace = @enable_dtrace@
+enable_selinux = @enable_selinux@
enable_thread_safety = @enable_thread_safety@
python_includespec = @python_includespec@
diff -rpNU3 base/src/backend/Makefile sepgsql-new/src/backend/Makefile
--- base/src/backend/Makefile 2008-01-07 23:51:33.000000000 +0900
+++ sepgsql-new/src/backend/Makefile 2009-03-13 18:14:33.000000000 +0900
@@ -16,7 +16,7 @@ include $(top_builddir)/src/Makefile.glo
DIRS = access bootstrap catalog parser commands executor lib libpq \
main nodes optimizer port postmaster regex rewrite \
- storage tcop tsearch utils $(top_builddir)/src/timezone
+ security storage tcop tsearch utils $(top_builddir)/src/timezone
SUBSYSOBJS = $(DIRS:%=%/SUBSYS.o)
@@ -32,6 +32,11 @@ LIBS := $(filter-out -lpgport, $(LIBS))
# The backend doesn't need everything that's in LIBS, however
LIBS := $(filter-out -lz -lreadline -ledit -ltermcap -lncurses -lcurses, $(LIBS))
+# SELinux needs libselinux
+ifeq ($(enable_selinux), yes)
+LIBS += -lselinux
+endif
+
[...9394 lines suppressed...]
+sepgsqlTransToInternalPerms(security_class_t tclass_ex, struct av_decision *avd);
+
+extern const char *
+sepgsqlGetClassString(security_class_t tclass);
+
+extern const char *
+sepgsqlGetPermissionString(security_class_t tclass, access_vector_t av);
+
+extern bool
+sepgsqlCheckObjectPerms(Relation rel, HeapTuple tuple,
+ access_vector_t required, bool abort);
+
+#else /* HAVE_SELINUX */
+
+// avc.c
+#define sepgsqlShmemSize() (0)
+#define sepgsqlStartupWorkerProcess() (0)
+// checker.c
+#define sepgsqlCheckRTEPerms(a) do {} while(0)
+#define sepgsqlCheckSelectInto(a) do {} while(0)
+#define sepgsqlExecScan(a,b,c,d) (true)
+#define sepgsqlHeapTupleInsert(a,b,c) (true)
+#define sepgsqlHeapTupleUpdate(a,b,c,d) (true)
+#define sepgsqlHeapTupleDelete(a,b,c) (true)
+// core.c
+#define sepgsqlIsEnabled() (false)
+#define sepgsqlInitialize() do {} while(0)
+// hooks.c
+#define sepgsqlCheckDatabaseAccess(a) (true)
+#define sepgsqlCheckDatabaseSuperuser() (true)
+#define sepgsqlCheckDatabaseInstallModule(a) do {} while(0)
+#define sepgsqlCheckDatabaseLoadModule(a) do {} while(0)
+#define sepgsqlCheckTableLock(a) (true)
+#define sepgsqlCheckTableTruncate(a) (true)
+#define sepgsqlCheckProcedureExecute(a) (true)
+#define sepgsqlCheckProcedureEntrypoint(a,b) do {} while(0)
+#define sepgsqlCheckBlobDrop(a) do {} while(0)
+#define sepgsqlCheckBlobRead(a) do {} while(0)
+#define sepgsqlCheckBlobWrite(a) do {} while(0)
+#define sepgsqlCheckBlobGetattr(a) do {} while(0)
+#define sepgsqlCheckBlobSetattr(a) do {} while(0)
+#define sepgsqlCheckBlobExport(a,b,c) do {} while(0)
+#define sepgsqlCheckBlobImport(a,b,c) do {} while(0)
+#define sepgsqlCheckBlobRelabel(a,b) do {} while(0)
+#define sepgsqlCheckFileRead(a,b) do {} while(0)
+#define sepgsqlCheckFileWrite(a,b) do {} while(0)
+#define sepgsqlAllowFunctionInlined(a) (true)
+// label.c
+#define sepgsqlTupleDescHasSecLabel(a) (false)
+#define sepgsqlMetaSecurityLabel() (NULL)
+#define sepgsqlInputGivenSecLabel(a) (InvalidOid)
+#define sepgsqlInputGivenSecLabelRelation(a) (NIL)
+#define sepgsqlSecurityLabelTransIn(a) (a)
+#define sepgsqlSecurityLabelTransOut(a) (a)
+#define sepgsqlCheckValidSecurityLabel(a) (false)
+
+#endif /* HAVE_SELINUX */
+
+extern Datum sepgsql_getcon(PG_FUNCTION_ARGS);
+extern Datum sepgsql_getservcon(PG_FUNCTION_ARGS);
+extern Datum sepgsql_get_user(PG_FUNCTION_ARGS);
+extern Datum sepgsql_get_role(PG_FUNCTION_ARGS);
+extern Datum sepgsql_get_type(PG_FUNCTION_ARGS);
+extern Datum sepgsql_get_range(PG_FUNCTION_ARGS);
+extern Datum sepgsql_set_user(PG_FUNCTION_ARGS);
+extern Datum sepgsql_set_role(PG_FUNCTION_ARGS);
+extern Datum sepgsql_set_type(PG_FUNCTION_ARGS);
+extern Datum sepgsql_set_range(PG_FUNCTION_ARGS);
+
+#endif /* SEPGSQL_H */
diff -rpNU3 base/src/include/storage/fd.h sepgsql-new/src/include/storage/fd.h
--- base/src/include/storage/fd.h 2008-01-07 23:51:33.000000000 +0900
+++ sepgsql-new/src/include/storage/fd.h 2009-03-13 18:14:33.000000000 +0900
@@ -67,6 +67,7 @@ extern int FileWrite(File file, char *bu
extern int FileSync(File file);
extern long FileSeek(File file, long offset, int whence);
extern int FileTruncate(File file, long offset);
+extern int FileRawDescriptor(File file);
/* Operations that allow use of regular stdio --- USE WITH CAUTION */
extern FILE *AllocateFile(const char *name, const char *mode);
diff -rpNU3 base/src/include/storage/large_object.h sepgsql-new/src/include/storage/large_object.h
--- base/src/include/storage/large_object.h 2008-01-07 23:51:33.000000000 +0900
+++ sepgsql-new/src/include/storage/large_object.h 2009-03-13 18:14:33.000000000 +0900
@@ -44,6 +44,7 @@ typedef struct LargeObjectDesc
#define IFS_RDLOCK (1 << 0)
#define IFS_WRLOCK (1 << 1)
+ Oid secid; /* security id of the largeobject */
} LargeObjectDesc;
@@ -79,5 +80,7 @@ extern int inv_tell(LargeObjectDesc *obj
extern int inv_read(LargeObjectDesc *obj_desc, char *buf, int nbytes);
extern int inv_write(LargeObjectDesc *obj_desc, const char *buf, int nbytes);
extern void inv_truncate(LargeObjectDesc *obj_desc, int len);
+extern Oid inv_get_security(Oid loid);
+extern void inv_set_security(Oid loid, Oid secid);
#endif /* LARGE_OBJECT_H */
diff -rpNU3 base/src/include/storage/lwlock.h sepgsql-new/src/include/storage/lwlock.h
--- base/src/include/storage/lwlock.h 2008-01-07 23:51:33.000000000 +0900
+++ sepgsql-new/src/include/storage/lwlock.h 2009-03-13 18:14:33.000000000 +0900
@@ -63,6 +63,7 @@ typedef enum LWLockId
AutovacuumLock,
AutovacuumScheduleLock,
SyncScanLock,
+ SepgsqlAvcLock,
/* Individual lock IDs end here */
FirstBufMappingLock,
FirstLockMgrLock = FirstBufMappingLock + NUM_BUFFER_PARTITIONS,
diff -rpNU3 base/src/include/utils/builtins.h sepgsql-new/src/include/utils/builtins.h
--- base/src/include/utils/builtins.h 2008-01-07 23:51:33.000000000 +0900
+++ sepgsql-new/src/include/utils/builtins.h 2009-03-13 13:09:47.000000000 +0900
@@ -617,6 +617,14 @@ extern Datum varchartypmodout(PG_FUNCTIO
extern Datum varchar(PG_FUNCTION_ARGS);
/* varlena.c */
+extern text *cstring_to_text(const char *s);
+extern text *cstring_to_text_with_len(const char *s, int len);
+extern char *text_to_cstring(const text *t);
+extern void text_to_cstring_buffer(const text *src, char *dst, size_t dst_len);
+
+#define CStringGetTextDatum(s) PointerGetDatum(cstring_to_text(s))
+#define TextDatumGetCString(d) text_to_cstring((text *) DatumGetPointer(d))
+
extern Datum textin(PG_FUNCTION_ARGS);
extern Datum textout(PG_FUNCTION_ARGS);
extern Datum textrecv(PG_FUNCTION_ARGS);
diff -rpNU3 base/src/include/utils/catcache.h sepgsql-new/src/include/utils/catcache.h
--- base/src/include/utils/catcache.h 2008-01-07 23:51:33.000000000 +0900
+++ sepgsql-new/src/include/utils/catcache.h 2009-03-13 18:14:33.000000000 +0900
@@ -172,6 +172,7 @@ extern HeapTuple SearchCatCache(CatCache
Datum v1, Datum v2,
Datum v3, Datum v4);
extern void ReleaseCatCache(HeapTuple tuple);
+extern void InsertCatCache(CatCache *cache, HeapTuple tuple);
extern CatCList *SearchCatCacheList(CatCache *cache, int nkeys,
Datum v1, Datum v2,
diff -rpNU3 base/src/include/utils/errcodes.h sepgsql-new/src/include/utils/errcodes.h
--- base/src/include/utils/errcodes.h 2008-01-07 23:51:33.000000000 +0900
+++ sepgsql-new/src/include/utils/errcodes.h 2009-03-13 18:14:33.000000000 +0900
@@ -339,6 +339,11 @@
#define ERRCODE_NO_DATA_FOUND MAKE_SQLSTATE('P','0', '0','0','2')
#define ERRCODE_TOO_MANY_ROWS MAKE_SQLSTATE('P','0', '0','0','3')
+/* Class SE - SE-PostgreSQL Error */
+#define ERRCODE_SELINUX_ERROR MAKE_SQLSTATE('S','E', '0','0','1')
+#define ERRCODE_SELINUX_AUDIT MAKE_SQLSTATE('S','E', '0','0','2')
+#define ERRCODE_SELINUX_INFO MAKE_SQLSTATE('S','E', '0','0','3')
+
/* Class XX - Internal Error (PostgreSQL-specific error class) */
/* (this is for "can't-happen" conditions and software bugs) */
#define ERRCODE_INTERNAL_ERROR MAKE_SQLSTATE('X','X', '0','0','0')
diff -rpNU3 base/src/include/utils/syscache.h sepgsql-new/src/include/utils/syscache.h
--- base/src/include/utils/syscache.h 2008-01-07 23:51:33.000000000 +0900
+++ sepgsql-new/src/include/utils/syscache.h 2009-03-13 18:14:33.000000000 +0900
@@ -64,18 +64,20 @@
#define RELNAMENSP 33
#define RELOID 34
#define RULERELNAME 35
-#define STATRELATT 36
-#define TSCONFIGMAP 37
-#define TSCONFIGNAMENSP 38
-#define TSCONFIGOID 39
-#define TSDICTNAMENSP 40
-#define TSDICTOID 41
-#define TSPARSERNAMENSP 42
-#define TSPARSEROID 43
-#define TSTEMPLATENAMENSP 44
-#define TSTEMPLATEOID 45
-#define TYPENAMENSP 46
-#define TYPEOID 47
+#define SECURITYLABEL 36
+#define SECURITYOID 37
+#define STATRELATT 38
+#define TSCONFIGMAP 39
+#define TSCONFIGNAMENSP 40
+#define TSCONFIGOID 41
+#define TSDICTNAMENSP 42
+#define TSDICTOID 43
+#define TSPARSERNAMENSP 44
+#define TSPARSEROID 45
+#define TSTEMPLATENAMENSP 46
+#define TSTEMPLATEOID 47
+#define TYPENAMENSP 48
+#define TYPEOID 49
extern void InitCatalogCache(void);
extern void InitCatalogCachePhase2(void);
@@ -84,6 +86,8 @@ extern HeapTuple SearchSysCache(int cach
Datum key1, Datum key2, Datum key3, Datum key4);
extern void ReleaseSysCache(HeapTuple tuple);
+extern void InsertSysCache(Oid relid, HeapTuple tuple);
+
/* convenience routines */
extern HeapTuple SearchSysCacheCopy(int cacheId,
Datum key1, Datum key2, Datum key3, Datum key4);
sepostgresql-test-8.3.patch:
--- NEW FILE sepostgresql-test-8.3.patch ---
diff -rpNU3 base/src/test/regress/expected/sanity_check.out sepgsql-new/src/test/regress/expected/sanity_check.out
--- base/src/test/regress/expected/sanity_check.out 2007-11-25 12:49:12.000000000 +0900
+++ sepgsql-new/src/test/regress/expected/sanity_check.out 2009-03-13 18:14:33.000000000 +0900
@@ -111,6 +111,7 @@ SELECT relname, relhasindex
pg_pltemplate | t
pg_proc | t
pg_rewrite | t
+ pg_security | t
pg_shdepend | t
pg_shdescription | t
pg_statistic | t
@@ -149,7 +150,7 @@ SELECT relname, relhasindex
timetz_tbl | f
tinterval_tbl | f
varchar_tbl | f
-(138 rows)
+(139 rows)
--
-- another sanity check: every system catalog that has OIDs should have
diff -rpNU3 base/src/test/sepgsql/Makefile sepgsql-new/src/test/sepgsql/Makefile
--- base/src/test/sepgsql/Makefile 1970-01-01 09:00:00.000000000 +0900
+++ sepgsql-new/src/test/sepgsql/Makefile 2009-03-15 17:38:39.000000000 +0900
@@ -0,0 +1,65 @@
+# ----------------------------------------------------
+# Makefile for SE-PostgreSQL testcases
+# ----------------------------------------------------
+PSQL := $(shell which psql)
+DIFF := $(shell which diff)
+RUNCON := $(shell which runcon)
+GETSEBOOL := $(shell which getsebool)
+DBNAME := test
+
+TESTCASES = $(wildcard sql/*.sql)
+
+test: init check setup results.diff
+
+init:
+ rm -f results.diff results/*.out results/*.diff
+
+clean: init
+ rm -f launch_psql
+
+launch_psql: launch_psql.c
+ $(CC) $< -o $@ -lselinux
+
+results.diff: $(TESTCASES:sql/%.sql=results/%.diff)
+ @for x in $^; do cat $$x >> $@; done
+ @test -s $@ && echo "HINT: See $@ to confirm errors" || :
+
+results/%.diff: sql/%.sql
+ @./launch_psql $(PSQL) -a $(DBNAME) < $< >& $(@:%.diff=%.out)
+ @$(DIFF) -u $(<:sql/%.sql=expected/%.out) \
+ $(<:sql/%.sql=results/%.out) >& $@ \
+ && echo -n "PASS: " || echo -n "FAIL: "
+ @echo $(notdir $(@:.diff=))
+
+setup: launch_psql
+ @cp -f /dev/null /tmp/sepgsql_test_copy_1
+ @cp -f /dev/null /tmp/sepgsql_test_copy_2
+ @chcon -t postgresql_tmp_t -l s0 /tmp/sepgsql_test_copy_1
+ @chcon -t postgresql_db_t -l s0 /tmp/sepgsql_test_copy_2
+ @dd if=/dev/zero of=/tmp/sepgsql_test_blob1 bs=1024 count=20 >& /dev/null
+ @dd if=/dev/zero of=/tmp/sepgsql_test_blob2 bs=1024 count=20 >& /dev/null
+ @chcon -t postgresql_tmp_t -l s0 /tmp/sepgsql_test_blob1
+ @chcon -t postgresql_db_t -l s0 /tmp/sepgsql_test_blob2
+ @chmod 0666 /tmp/sepgsql_test_*
+ @echo "PASS: setup filesystem objects"
+
+check:
+ @test -x $(PSQL) || \
+ (echo "HINT: $(PSQL) is not available"; exit 1)
+ @$(PSQL) -qt -c 'SHOW sepostgresql' -d $(DBNAME) 2>/dev/null | grep -q on || \
+ (echo "HINT: database \"$(DBNAME)\" is not available"; \
+ echo "HINT: SE-PostgreSQL may not be available on server"; exit 1)
+ @$(GETSEBOOL) allow_user_postgresql_connect | grep -q on || \
+ (echo "HINT: check allow_user_postgresql_connect boolean"; exit 1)
+ @$(GETSEBOOL) sepgsql_regression_test_mode | grep -q on || \
+ (echo "HINT: check sepgsql_regression_test_mode boolean"; \
+ echo "HINT: check sepostgresql-devel.pp installed"; exit 1)
+ @$(RUNCON) -t sepgsql_test_t -l s0-s0:c0.c15 \
+ $(PSQL) -c 'SELECT sepgsql_getcon()' $(DBNAME) >& /dev/null || \
+ (echo "HINT: /sbin/restorecon -R <prefix> and restart"; \
+ echo "HINT: user shell should have 's0-s0:c0.c15' range, at least"; \
+ echo " semanage enables to set up it"; exit 1)
+ @test -x /etc/init.d/mcstrans && /etc/init.d/mcstrans status >& /dev/null && \
+ (echo "HINT: stop mcstrans daemon"; exit 1) || \
+ (test $$? -eq 3 && exit 0 || exit 1)
+ @echo "PASS: check runtime environment"
diff -rpNU3 base/src/test/sepgsql/expected/basic.out sepgsql-new/src/test/sepgsql/expected/basic.out
--- base/src/test/sepgsql/expected/basic.out 1970-01-01 09:00:00.000000000 +0900
+++ sepgsql-new/src/test/sepgsql/expected/basic.out 2009-03-15 17:38:39.000000000 +0900
@@ -0,0 +1,108 @@
+-- at SECURITY_CONTEXT=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c15
+SELECT sepgsql_getcon();
+ sepgsql_getcon
+-----------------------------------------------------
+ unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c15
+(1 row)
+
+-- cleanup previous tests
+SET client_min_messages TO 'error';
+SET
+DROP TABLE IF EXISTS t4 CASCADE;
+DROP TABLE
+DROP TABLE IF EXISTS t3 CASCADE;
+DROP TABLE
+DROP TABLE IF EXISTS t2 CASCADE;
+DROP TABLE
+DROP TABLE IF EXISTS t1 CASCADE;
+DROP TABLE
+DROP FUNCTION IF EXISTS f1(int) CASCADE;
+DROP FUNCTION
+RESET client_min_messages;
+RESET
+-- SETUP
+CREATE TABLE t1
+(
+ a int,
+ b text
+ SECURITY_CONTEXT = 'unconfined_u:object_r:sepgsql_ro_table_t:s0',
+ c bool
+ SECURITY_CONTEXT = 'unconfined_u:object_r:sepgsql_secret_table_t:s0'
+);
+CREATE TABLE
+INSERT INTO t1 VALUES (1, 'aaa', false), (2, 'bbb', true);
+INSERT 0 2
+CREATE TABLE t2
+(
+ s int,
+ t int,
+ u int
+) SECURITY_CONTEXT = 'unconfined_u:object_r:sepgsql_table_t:s0:c0';
+CREATE TABLE
+ALTER TABLE t2 DROP COLUMN t; -- disturbing factor
+ALTER TABLE
+CREATE TABLE t3
+(
+ x text
+ SECURITY_CONTEXT = 'unconfined_u:object_r:sepgsql_table_t:s0:c1'
+) inherits(t2);
+CREATE TABLE
+-- at SECURITY_CONTEXT=unconfined_u:unconfined_r:sepgsql_test_t:s0-s0:c0
+SELECT sepgsql_getcon();
+ sepgsql_getcon
+---------------------------------------------------
+ unconfined_u:unconfined_r:sepgsql_test_t:s0-s0:c0
+(1 row)
+
+SELECT * FROM t1; -- to be denied
+ERROR: SELinux: denied { select } scontext=unconfined_u:unconfined_r:sepgsql_test_t:s0-s0:c0 tcontext=unconfined_u:object_r:sepgsql_secret_table_t:s0 tclass=db_column name=t1.c
+SELECT a, b FROM t1;
+ a | b
+---+-----
+ 1 | aaa
+ 2 | bbb
+(2 rows)
+
+SELECT COUNT(*) FROM t1 WHERE c; -- to be denied
+ERROR: SELinux: denied { select } scontext=unconfined_u:unconfined_r:sepgsql_test_t:s0-s0:c0 tcontext=unconfined_u:object_r:sepgsql_secret_table_t:s0 tclass=db_column name=t1.c
+UPDATE t1 SET b = 'ccc'; -- to be denied
+ERROR: SELinux: denied { update } scontext=unconfined_u:unconfined_r:sepgsql_test_t:s0-s0:c0 tcontext=unconfined_u:object_r:sepgsql_ro_table_t:s0 tclass=db_column name=t1.b
+UPDATE t1 SET a = a + 2;
+UPDATE 2
+INSERT INTO t1 VALUES (5, 'eee', true); -- to be denied
+ERROR: SELinux: denied { insert } scontext=unconfined_u:unconfined_r:sepgsql_test_t:s0-s0:c0 tcontext=unconfined_u:object_r:sepgsql_ro_table_t:s0 tclass=db_column name=t1.b
+INSERT INTO t1 VALUES (5);
+INSERT 0 1
+SELECT * FROM t2;
+ s | u
+---+---
+(0 rows)
+
+SELECT t2 FROM t2;
+ t2
+----
+(0 rows)
+
+SELECT t3 FROM t3; -- to be denied
+ERROR: SELinux: denied { select } scontext=unconfined_u:unconfined_r:sepgsql_test_t:s0-s0:c0 tcontext=unconfined_u:object_r:sepgsql_table_t:s0:c1 tclass=db_column name=t3.x
+SELECT 1 FROM t3;
+ ?column?
+----------
+(0 rows)
+
+-- at SECURITY_CONTEXT=unconfined_u:unconfined_r:sepgsql_test_t:s0-s0:c1
+SELECT sepgsql_getcon();
+ sepgsql_getcon
+---------------------------------------------------
+ unconfined_u:unconfined_r:sepgsql_test_t:s0-s0:c1
+(1 row)
+
+SELECT * FROM t2; -- to be denied
+ERROR: SELinux: denied { select } scontext=unconfined_u:unconfined_r:sepgsql_test_t:s0-s0:c1 tcontext=unconfined_u:object_r:sepgsql_table_t:s0:c0 tclass=db_table name=t2
+SELECT t2 FROM t2; -- to be denied
+ERROR: SELinux: denied { select } scontext=unconfined_u:unconfined_r:sepgsql_test_t:s0-s0:c1 tcontext=unconfined_u:object_r:sepgsql_table_t:s0:c0 tclass=db_table name=t2
+SELECT t3 FROM t3;
+ t3
+----
+(0 rows)
+
diff -rpNU3 base/src/test/sepgsql/expected/copy_stmt.out sepgsql-new/src/test/sepgsql/expected/copy_stmt.out
--- base/src/test/sepgsql/expected/copy_stmt.out 1970-01-01 09:00:00.000000000 +0900
+++ sepgsql-new/src/test/sepgsql/expected/copy_stmt.out 2009-03-15 17:38:39.000000000 +0900
@@ -0,0 +1,90 @@
+-- at SECURITY_CONTEXT=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c15
+SELECT sepgsql_getcon();
+ sepgsql_getcon
+-----------------------------------------------------
+ unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c15
+(1 row)
+
+-- cleanup previous tests
+SET client_min_messages TO 'error';
+SET
+DROP TABLE IF EXISTS t3 CASCADE;
+DROP TABLE
+DROP TABLE IF EXISTS t2 CASCADE;
+DROP TABLE
+DROP TABLE IF EXISTS t1 CASCADE;
+DROP TABLE
+DROP FUNCTION IF EXISTS f1(int) CASCADE;
+DROP FUNCTION
+RESET client_min_messages;
+RESET
+-- setup tables
+CREATE TABLE t1
+(
+ a int,
+ b text
+);
+CREATE TABLE
+INSERT INTO t1 VALUES (1, 'aaa'), (2, 'bbb');
+INSERT 0 2
+CREATE TABLE t2
+(
+ x int,
+ y text
+ SECURITY_CONTEXT = 'unconfined_u:object_r:sepgsql_secret_table_t:s0'
+);
+CREATE TABLE
+SELECT security_context from pg_attribute where attrelid = 't2'::regclass and attname = 'y';
+ security_context
+-------------------------------------------------
+ unconfined_u:object_r:sepgsql_secret_table_t:s0
+(1 row)
+
+INSERT INTO t2 VALUES (1, 'xxx'), (2, 'yyy');
+INSERT 0 2
+CREATE TABLE t3 -- read only table
+(
+ s int,
+ t text
+) SECURITY_CONTEXT = 'unconfined_u:object_r:sepgsql_ro_table_t:s0';
+CREATE TABLE
+INSERT INTO t2 VALUES (1, 'sss'), (2, 'ttt');
+INSERT 0 2
+-- at SECURITY_CONTEXT=unconfined_u:unconfined_r:sepgsql_test_t:s0-s0:c0
+SELECT sepgsql_getcon();
+ sepgsql_getcon
+---------------------------------------------------
+ unconfined_u:unconfined_r:sepgsql_test_t:s0-s0:c0
+(1 row)
+
+COPY t1 TO stdout;
+1 aaa
+2 bbb
+COPY t1 FROM stdin;
+COPY t1 TO '/tmp/sepgsql_test_copy_1';
+COPY 4
+COPY t1 TO '/tmp/sepgsql_test_copy_2'; -- to be denied
+ERROR: SELinux: denied { write } scontext=unconfined_u:unconfined_r:sepgsql_test_t:s0-s0:c0 tcontext=unconfined_u:object_r:postgresql_db_t:s0 tclass=file name=/tmp/sepgsql_test_copy_2
+COPY t2 TO stdout; -- to be denied
+ERROR: SELinux: denied { select } scontext=unconfined_u:unconfined_r:sepgsql_test_t:s0-s0:c0 tcontext=unconfined_u:object_r:sepgsql_secret_table_t:s0 tclass=db_column name=t2.y
+COPY t2 FROM stdin; -- to be denied
+ERROR: SELinux: denied { insert } scontext=unconfined_u:unconfined_r:sepgsql_test_t:s0-s0:c0 tcontext=unconfined_u:object_r:sepgsql_secret_table_t:s0 tclass=db_column name=t2.y
+COPY t2 (x) TO stdout;
+1
+2
+1
+2
+COPY t3 TO stdout;
+COPY t3 FROM '/tmp/sepgsql_test_copy_1'; -- to be denied
+ERROR: SELinux: denied { insert } scontext=unconfined_u:unconfined_r:sepgsql_test_t:s0-s0:c0 tcontext=unconfined_u:object_r:sepgsql_ro_table_t:s0 tclass=db_table name=t3
+COPY t1 FROM '/tmp/sepgsql_test_copy_1';
+COPY 4
+COPY t1 TO stdout;
+1 aaa
+2 bbb
+3 ccc
+4 ddd
+1 aaa
+2 bbb
+3 ccc
+4 ddd
diff -rpNU3 base/src/test/sepgsql/expected/enhanced_ddl_stmt.out sepgsql-new/src/test/sepgsql/expected/enhanced_ddl_stmt.out
--- base/src/test/sepgsql/expected/enhanced_ddl_stmt.out 1970-01-01 09:00:00.000000000 +0900
+++ sepgsql-new/src/test/sepgsql/expected/enhanced_ddl_stmt.out 2009-03-15 17:38:39.000000000 +0900
@@ -0,0 +1,180 @@
+-- at SECURITY_CONTEXT=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c15
+SELECT sepgsql_getcon();
+ sepgsql_getcon
+-----------------------------------------------------
+ unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c15
+(1 row)
+
+-- cleanup previous tests
+SET client_min_messages TO 'error';
+SET
+DROP TABLE IF EXISTS t4 CASCADE;
+DROP TABLE
+DROP TABLE IF EXISTS t3 CASCADE;
+DROP TABLE
+DROP TABLE IF EXISTS t2 CASCADE;
+DROP TABLE
+DROP TABLE IF EXISTS t1 CASCADE;
+DROP TABLE
+DROP FUNCTION IF EXISTS f1(int) CASCADE;
+DROP FUNCTION
+DROP FUNCTION IF EXISTS f2(int) CASCADE;
+DROP FUNCTION
+RESET client_min_messages;
+RESET
+-- CREATE TABLE with SECURITY_LABEL clause
+CREATE TABLE t1 (
+ a int,
+ b text
+);
+CREATE TABLE
+SELECT relname, security_context FROM pg_class WHERE oid = 't1'::regclass;
+ relname | security_context
+---------+------------------------------------------
+ t1 | unconfined_u:object_r:sepgsql_table_t:s0
+(1 row)
+
+SELECT attname, security_context FROM pg_attribute WHERE attrelid = 't1'::regclass and attnum > 0;
+ attname | security_context
+---------+------------------------------------------
+ a | unconfined_u:object_r:sepgsql_table_t:s0
+ b | unconfined_u:object_r:sepgsql_table_t:s0
+(2 rows)
+
+CREATE TABLE t2 (
+ a int,
+ b text
+) SECURITY_CONTEXT = 'unconfined_u:object_r:sepgsql_ro_table_t:s0';
+CREATE TABLE
+SELECT relname, security_context FROM pg_class WHERE oid = 't2'::regclass;
+ relname | security_context
+---------+---------------------------------------------
+ t2 | unconfined_u:object_r:sepgsql_ro_table_t:s0
+(1 row)
+
+SELECT attname, security_context FROM pg_attribute WHERE attrelid = 't2'::regclass and attnum > 0;
+ attname | security_context
+---------+---------------------------------------------
+ a | unconfined_u:object_r:sepgsql_ro_table_t:s0
+ b | unconfined_u:object_r:sepgsql_ro_table_t:s0
+(2 rows)
+
+CREATE TABLE t3 (
+ a int,
+ b text SECURITY_CONTEXT = 'unconfined_u:object_r:sepgsql_fixed_table_t:s0',
+ c bool SECURITY_CONTEXT = 'unconfined_u:object_r:sepgsql_secret_table_t:s0',
+ d int
+) SECURITY_CONTEXT = 'unconfined_u:object_r:sepgsql_table_t:s0:c0';
+CREATE TABLE
+SELECT relname, security_context FROM pg_class WHERE oid = 't3'::regclass;
+ relname | security_context
+---------+---------------------------------------------
+ t3 | unconfined_u:object_r:sepgsql_table_t:s0:c0
+(1 row)
+
+SELECT attname, security_context FROM pg_attribute WHERE attrelid = 't3'::regclass and attnum > 0;
+ attname | security_context
+---------+-------------------------------------------------
+ a | unconfined_u:object_r:sepgsql_table_t:s0
+ b | unconfined_u:object_r:sepgsql_fixed_table_t:s0
+ c | unconfined_u:object_r:sepgsql_secret_table_t:s0
+ d | unconfined_u:object_r:sepgsql_table_t:s0
+(4 rows)
+
+CREATE TABLE t4 (
+ a int,
+ b text
+) SECURITY_CONTEXT = 'unconfined_u:object_r:invalid_label_t:s0'; -- to be failed
+ERROR: invalid security label: unconfined_u:object_r:invalid_label_t:s0
+CREATE TABLE t4 (
+ a int,
+ b text
+) SECURITY_CONTEXT = 'unconfined_u:object_r:sepgsql_proc_t:s0'; -- to be denied
+ERROR: SELinux: denied { create } scontext=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c15 tcontext=unconfined_u:object_r:sepgsql_proc_t:s0 tclass=db_table name=t4
+-- ALTER TABLE with SECURITY_CONTEXT clause
+ALTER TABLE t2 SECURITY_CONTEXT = 'unconfined_u:object_r:sepgsql_secret_table_t:s0';
+ALTER TABLE
+ALTER TABLE t2 ADD COLUMN c bool; -- it inherits table's one
+ALTER TABLE
+SELECT relname, security_context FROM pg_class WHERE oid = 't2'::regclass;
+ relname | security_context
+---------+-------------------------------------------------
+ t2 | unconfined_u:object_r:sepgsql_secret_table_t:s0
+(1 row)
+
+SELECT attname, security_context FROM pg_attribute WHERE attrelid = 't2'::regclass and attnum > 0;
+ attname | security_context
+---------+-------------------------------------------------
+ a | unconfined_u:object_r:sepgsql_ro_table_t:s0
+ b | unconfined_u:object_r:sepgsql_ro_table_t:s0
+ c | unconfined_u:object_r:sepgsql_secret_table_t:s0
+(3 rows)
+
+ALTER TABLE t3 ALTER b SECURITY_CONTEXT = 'unconfined_u:object_r:sepgsql_table_t:s0';
+ALTER TABLE
+SELECT relname, security_context FROM pg_class WHERE oid = 't3'::regclass;
+ relname | security_context
+---------+---------------------------------------------
+ t3 | unconfined_u:object_r:sepgsql_table_t:s0:c0
+(1 row)
+
+SELECT attname, security_context FROM pg_attribute WHERE attrelid = 't3'::regclass and attnum > 0;
+ attname | security_context
+---------+-------------------------------------------------
+ a | unconfined_u:object_r:sepgsql_table_t:s0
+ b | unconfined_u:object_r:sepgsql_table_t:s0
+ c | unconfined_u:object_r:sepgsql_secret_table_t:s0
+ d | unconfined_u:object_r:sepgsql_table_t:s0
+(4 rows)
+
+-- CREATE FUNCTION with SECURITY_CONTEXT clause
+CREATE FUNCTION f1 (int) RETURNS int
+ LANGUAGE 'sql'
+ SECURITY_CONTEXT = 'unconfined_u:object_r:sepgsql_proc_t:s0:c0'
+ AS 'SELECT $1 * 2';
+CREATE FUNCTION
+SELECT proname, security_context FROM pg_proc WHERE oid = 'f1'::regproc;
+ proname | security_context
+---------+--------------------------------------------
+ f1 | unconfined_u:object_r:sepgsql_proc_t:s0:c0
+(1 row)
+
+CREATE FUNCTION f2 (int) RETURNS int
+ LANGUAGE 'sql'
+ SECURITY_CONTEXT = 'unconfined_u:object_r:invalid_label_t:s0'
+ AS 'SELECT $1 + $1'; -- to be failed
+ERROR: invalid security label: unconfined_u:object_r:invalid_label_t:s0
+CREATE FUNCTION f2 (int) RETURNS int
+ LANGUAGE 'sql'
+ SECURITY_CONTEXT = 'unconfined_u:object_r:sepgsql_proc_t:s0:c16'
+ AS 'SELECT $1 + $1'; -- to be denied
+ERROR: SELinux: denied { create } scontext=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c15 tcontext=unconfined_u:object_r:sepgsql_proc_t:s0:c16 tclass=db_procedure name=f2
+CREATE FUNCTION f2 (int) RETURNS int
+ LANGUAGE 'sql'
+ AS 'SELECT $1 + $1';
+CREATE FUNCTION
+SELECT proname, security_context FROM pg_proc WHERE oid = 'f2'::regproc;
+ proname | security_context
+---------+-----------------------------------------
+ f2 | unconfined_u:object_r:sepgsql_proc_t:s0
+(1 row)
+
+-- ALTER FUNCTION with SECURITY_CONTEXT clause
+ALTER FUNCTION f1(int)
+ SECURITY_CONTEXT = 'unconfined_u:object_r:sepgsql_proc_t:s0:c1';
+ALTER FUNCTION
+SELECT proname, security_context FROM pg_proc WHERE oid = 'f1'::regproc;
+ proname | security_context
+---------+--------------------------------------------
+ f1 | unconfined_u:object_r:sepgsql_proc_t:s0:c1
+(1 row)
+
+ALTER FUNCTION f2(int)
+ SECURITY_CONTEXT = 'unconfined_u:object_r:sepgsql_proc_t:s0:c16'; -- to be denied
+ERROR: SELinux: denied { relabelto } scontext=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c15 tcontext=unconfined_u:object_r:sepgsql_proc_t:s0:c16 tclass=db_procedure name=f2
+SELECT proname, security_context FROM pg_proc WHERE oid = 'f2'::regproc;
+ proname | security_context
+---------+-----------------------------------------
+ f2 | unconfined_u:object_r:sepgsql_proc_t:s0
+(1 row)
+
diff -rpNU3 base/src/test/sepgsql/expected/join_query.out sepgsql-new/src/test/sepgsql/expected/join_query.out
--- base/src/test/sepgsql/expected/join_query.out 1970-01-01 09:00:00.000000000 +0900
+++ sepgsql-new/src/test/sepgsql/expected/join_query.out 2009-03-15 17:38:39.000000000 +0900
@@ -0,0 +1,85 @@
+-- at SECURITY_CONTEXT=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c15
+SELECT sepgsql_getcon();
+ sepgsql_getcon
+-----------------------------------------------------
+ unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c15
+(1 row)
+
+-- cleanup previous tests
+SET client_min_messages TO 'error';
+SET
+DROP TABLE IF EXISTS t4 CASCADE;
+DROP TABLE
+DROP TABLE IF EXISTS t3 CASCADE;
+DROP TABLE
+DROP TABLE IF EXISTS t2 CASCADE;
+DROP TABLE
+DROP TABLE IF EXISTS t1 CASCADE;
+DROP TABLE
+DROP FUNCTION IF EXISTS f1(int) CASCADE;
+DROP FUNCTION
+RESET client_min_messages;
+RESET
+-- SETUP
+CREATE TABLE t1
+(
+ a int,
+ b text,
+ c int
+ SECURITY_CONTEXT = 'unconfined_u:object_r:sepgsql_secret_table_t:s0'
+);
+CREATE TABLE
+INSERT INTO t1 VALUES (1, 'aaa'), (2, 'bbb'), (3, 'ccc');
+INSERT 0 3
+CREATE TABLE t2
+(
+ x int,
+ y text
+);
+CREATE TABLE
+INSERT INTO t2 VALUES (2, 'xxx'), (3, 'yyy'), (4,'zzz');
+INSERT 0 3
+CREATE TABLE t3
+(
+ d int
+) INHERITS (t1);
+CREATE TABLE
+INSERT INTO t3 VALUES (4, 'ddd'), (5, 'eee');
+INSERT 0 2
+CREATE TABLE t4
+(
+ z int
+ SECURITY_CONTEXT = 'unconfined_u:object_r:sepgsql_secret_table_t:s0'
+) INHERITS (t2);
+CREATE TABLE
+INSERT INTO t2 VALUES (1, 'sss'), (5, 'ttt');
+INSERT 0 2
+-- at SECURITY_CONTEXT=unconfined_u:unconfined_r:sepgsql_test_t:s0-s0:c0
+SELECT sepgsql_getcon();
+ sepgsql_getcon
+---------------------------------------------------
+ unconfined_u:unconfined_r:sepgsql_test_t:s0-s0:c0
+(1 row)
+
+SELECT * FROM t1 JOIN t2 ON a = x; -- to be denied
+ERROR: SELinux: denied { select } scontext=unconfined_u:unconfined_r:sepgsql_test_t:s0-s0:c0 tcontext=unconfined_u:object_r:sepgsql_secret_table_t:s0 tclass=db_column name=t1.c
+SELECT a, b, y FROM t1 JOIN t2 ON a = x;
+ a | b | y
+---+-----+-----
+ 1 | aaa | sss
+ 2 | bbb | xxx
+ 3 | ccc | yyy
+ 4 | ddd | zzz
+ 5 | eee | ttt
+(5 rows)
+
+SELECT a, b, y FROM t1 JOIN t2 ON c = x; -- to be denied
+ERROR: SELinux: denied { select } scontext=unconfined_u:unconfined_r:sepgsql_test_t:s0-s0:c0 tcontext=unconfined_u:object_r:sepgsql_secret_table_t:s0 tclass=db_column name=t1.c
+SELECT COUNT(*) FROM t1 JOIN t2 ON a = x;
+ count
+-------
+ 5
+(1 row)
+
+SELECT j FROM (t1 JOIN t2 ON a = x) AS j; -- to be denied
+ERROR: SELinux: denied { select } scontext=unconfined_u:unconfined_r:sepgsql_test_t:s0-s0:c0 tcontext=unconfined_u:object_r:sepgsql_secret_table_t:s0 tclass=db_column name=t1.c
diff -rpNU3 base/src/test/sepgsql/expected/large_object.out sepgsql-new/src/test/sepgsql/expected/large_object.out
--- base/src/test/sepgsql/expected/large_object.out 1970-01-01 09:00:00.000000000 +0900
+++ sepgsql-new/src/test/sepgsql/expected/large_object.out 2009-03-15 17:38:39.000000000 +0900
@@ -0,0 +1,293 @@
+-- at SECURITY_CONTEXT=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c15
+SELECT sepgsql_getcon();
+ sepgsql_getcon
+-----------------------------------------------------
+ unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c15
+(1 row)
+
+-- cleanup previous tests
+SET client_min_messages TO 'error';
+SET
+DROP TABLE IF EXISTS lolabel CASCADE;
+DROP TABLE
+DROP FUNCTION IF EXISTS lo_label(oid) CASCADE;
+DROP FUNCTION
+RESET client_min_messages;
+RESET
+CREATE TABLE lolabel(
+ loid oid,
+ label text
+);
+CREATE TABLE
+CREATE OR REPLACE FUNCTION lo_label(oid)
+ RETURNS TEXT LANGUAGE 'sql'
+ AS 'SELECT label FROM lolabel WHERE loid = $1';
+CREATE FUNCTION
+INSERT INTO lolabel (SELECT lo_import('/tmp/sepgsql_test_blob1'), 'normal');
+INSERT 0 1
+INSERT INTO lolabel (SELECT lo_import('/tmp/sepgsql_test_blob1'), 'readonly');
+INSERT 0 1
+INSERT INTO lolabel (SELECT lo_import('/tmp/sepgsql_test_blob1'), 'secret');
+INSERT 0 1
+SELECT lo_set_security(loid, 'system_u:object_r:sepgsql_blob_t:s0')
+ FROM lolabel WHERE label = 'normal';
+ lo_set_security
+-----------------
+ t
+(1 row)
+
+SELECT lo_set_security(loid, 'system_u:object_r:sepgsql_ro_blob_t:s0')
+ FROM lolabel WHERE label = 'readonly';
+ lo_set_security
+-----------------
+ t
+(1 row)
+
+SELECT lo_set_security(loid, 'system_u:object_r:sepgsql_secret_blob_t:s0')
+ FROM lolabel WHERE label = 'secret';
+ lo_set_security
+-----------------
+ t
+(1 row)
+
+-- at SECURITY_CONTEXT=unconfined_u:unconfined_r:sepgsql_test_t:s0:c0
+SELECT sepgsql_getcon();
+ sepgsql_getcon
+------------------------------------------------
+ unconfined_u:unconfined_r:sepgsql_test_t:s0:c0
+(1 row)
+
+SELECT lo_get_security(loid) FROM lolabel;
+ lo_get_security
+--------------------------------------------
+ system_u:object_r:sepgsql_blob_t:s0
+ system_u:object_r:sepgsql_ro_blob_t:s0
+ system_u:object_r:sepgsql_secret_blob_t:s0
+(3 rows)
+
+SELECT security_context, lo_label(loid) AS label, COUNT(*)
+ FROM pg_largeobject GROUP BY security_context, loid ORDER by label;
+ security_context | label | count
+--------------------------------------------+----------+-------
+ system_u:object_r:sepgsql_blob_t:s0 | normal | 10
+ system_u:object_r:sepgsql_ro_blob_t:s0 | readonly | 10
+ system_u:object_r:sepgsql_secret_blob_t:s0 | secret | 10
+(3 rows)
+
+-- read large object
+BEGIN;
+BEGIN
+SELECT lo_open(loid, x'40000'::int) FROM lolabel WHERE label = 'normal';
+ lo_open
+---------
+ 0
+(1 row)
+
+SELECT loread(0, 32);
+ loread
+----------------------------------------------------------------------------------------------------------------------------------
+ \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000
+(1 row)
+
+ROLLBACK;
+ROLLBACK
+BEGIN;
+BEGIN
+SELECT lo_open(loid, x'40000'::int) FROM lolabel WHERE label = 'readonly';
+ lo_open
+---------
+ 0
+(1 row)
+
+SELECT loread(0, 32);
+ loread
+----------------------------------------------------------------------------------------------------------------------------------
+ \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000
+(1 row)
+
+ROLLBACK;
+ROLLBACK
+BEGIN;
+BEGIN
+SELECT lo_open(loid, x'40000'::int) FROM lolabel WHERE label = 'secret';
+ lo_open
+---------
+ 0
+(1 row)
+
+SELECT loread(0, 32); -- to be denied
+ERROR: SELinux: security policy violation
+ROLLBACK;
+ROLLBACK
+-- write large object
+BEGIN;
+BEGIN
+SELECT lo_open(loid, x'20000'::int) FROM lolabel WHERE label = 'normal';
+ lo_open
+---------
+ 0
+(1 row)
+
+SELECT lowrite(0, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ');
+ lowrite
+---------
+ 26
+(1 row)
+
+ROLLBACK;
+ROLLBACK
+BEGIN;
+BEGIN
+SELECT lo_open(loid, x'20000'::int) FROM lolabel WHERE label = 'readonly';
+ lo_open
+---------
+ 0
+(1 row)
+
+SELECT lowrite(0, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'); -- to be denied
+ERROR: SELinux: security policy violation
+ROLLBACK;
+ROLLBACK
+BEGIN;
+BEGIN
+SELECT lo_open(loid, x'20000'::int) FROM lolabel WHERE label = 'secret';
+ lo_open
+---------
+ 0
+(1 row)
+
+SELECT lowrite(0, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'); -- to be denied
+ERROR: SELinux: security policy violation
+ROLLBACK;
+ROLLBACK
+-- create large object
+BEGIN;
+BEGIN
+INSERT INTO lolabel (SELECT lo_create(6004), 'local');
+INSERT 0 1
+SELECT lo_open(loid, x'20000'::int) FROM lolabel WHERE label = 'local';
+ lo_open
+---------
+ 0
+(1 row)
+
+SELECT lowrite(0, 'abcdefghijklmnopqrstuvwxyz');
+ lowrite
+---------
+ 26
+(1 row)
+
+SELECT lo_close(0);
+ lo_close
+----------
+ 0
+(1 row)
+
+COMMIT;
+COMMIT
+-- getattr/setattr
+BEGIN;
+BEGIN
+SELECT lo_open(loid, x'20000'::int) FROM lolabel WHERE label = 'local';
+ lo_open
+---------
+ 0
+(1 row)
+
+SELECT lo_lseek(0, 0, 2); -- seek to end
+ lo_lseek
+----------
+ 26
+(1 row)
+
+SELECT lowrite(0, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ');
+ lowrite
+---------
+ 26
+(1 row)
+
+SELECT lo_tell(0);
+ lo_tell
+---------
+ 52
+(1 row)
+
+SELECT lo_lseek(0, 0, 0); -- seek to head
+ lo_lseek
+----------
+ 0
+(1 row)
+
+SELECT loread(0, 50);
+ loread
+----------------------------------------------------
+ abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWX
+(1 row)
+
+SELECT lo_close(0);
+ lo_close
+----------
+ 0
+(1 row)
+
+COMMIT;
+COMMIT
+-- at SECURITY_CONTEXT=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c15
+SELECT sepgsql_getcon();
+ sepgsql_getcon
+-----------------------------------------------------
+ unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c15
+(1 row)
+
+-- change security label
+BEGIN;
+BEGIN
+SELECT lo_open(loid, x'40000'::int) FROM lolabel; -- a seed of trouble
+ lo_open
+---------
+ 0
+ 1
+ 2
+ 3
+(4 rows)
+
+SELECT lo_set_security(loid, 'system_u:object_r:sepgsql_blob_t:s0:c4')
+ FROM lolabel WHERE label in ('normal', 'readonly');
+ lo_set_security
+-----------------
+ t
+ t
+(2 rows)
+
+SELECT lo_get_security(loid) FROM lolabel;
+ lo_get_security
+---------------------------------------------------------
+ system_u:object_r:sepgsql_blob_t:s0:c4
+ system_u:object_r:sepgsql_blob_t:s0:c4
+ system_u:object_r:sepgsql_secret_blob_t:s0
+ unconfined_u:object_r:sepgsql_test_sepgsql_blob_t:s0:c0
+(4 rows)
+
+SELECT security_context, lo_label(loid) AS label, count(*)
+ FROM pg_largeobject WHERE loid in (SELECT loid FROM lolabel)
+ GROUP BY security_context, loid ORDER BY label;
+ security_context | label | count
+---------------------------------------------------------+----------+-------
+ unconfined_u:object_r:sepgsql_test_sepgsql_blob_t:s0:c0 | local | 1
+ system_u:object_r:sepgsql_blob_t:s0:c4 | normal | 10
+ system_u:object_r:sepgsql_blob_t:s0:c4 | readonly | 10
+ system_u:object_r:sepgsql_secret_blob_t:s0 | secret | 10
+(4 rows)
+
+ROLLBACK;
+ROLLBACK
+-- cleanup
+SELECT lo_unlink(loid) FROM lolabel;
+ lo_unlink
+-----------
+ 1
+ 1
+ 1
+ 1
+(4 rows)
+
diff -rpNU3 base/src/test/sepgsql/expected/row_level.out sepgsql-new/src/test/sepgsql/expected/row_level.out
--- base/src/test/sepgsql/expected/row_level.out 1970-01-01 09:00:00.000000000 +0900
+++ sepgsql-new/src/test/sepgsql/expected/row_level.out 2009-03-15 17:38:39.000000000 +0900
@@ -0,0 +1,131 @@
+-- at SECURITY_CONTEXT=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c15
+SELECT sepgsql_getcon();
+ sepgsql_getcon
+-----------------------------------------------------
+ unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c15
+(1 row)
+
+-- cleanup previous tests
+SET client_min_messages TO 'error';
+SET
+DROP TABLE IF EXISTS t4 CASCADE;
+DROP TABLE
+DROP TABLE IF EXISTS t3 CASCADE;
+DROP TABLE
+DROP TABLE IF EXISTS t2 CASCADE;
+DROP TABLE
+DROP TABLE IF EXISTS t1 CASCADE;
+DROP TABLE
+DROP FUNCTION IF EXISTS f1(int) CASCADE;
+DROP FUNCTION
+DROP FUNCTION IF EXISTS f2(int) CASCADE;
+DROP FUNCTION
+RESET client_min_messages;
+RESET
+-- test begins here
+CREATE TABLE t1 (
+ a int primary key,
+ b text
+);
+NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "t1_pkey" for table "t1"
+CREATE TABLE
+CREATE TABLE t2 (
+ x int references t1 (a) on update cascade,
+ y text
+);
+CREATE TABLE
+INSERT INTO t1 (security_context, a, b) VALUES
+ ('system_u:object_r:sepgsql_table_t:s0', 1, 'aaa'),
+ ('system_u:object_r:sepgsql_table_t:s0:c0', 2, 'bbb'),
+ ('system_u:object_r:sepgsql_table_t:s0:c1', 3, 'ccc'),
+ ('system_u:object_r:sepgsql_ro_table_t:s0', 4, 'ddd'),
+ ('system_u:object_r:sepgsql_ro_table_t:s0:c0', 5, 'eee'),
+ ('system_u:object_r:sepgsql_ro_table_t:s0:c1', 6, 'fff');
+INSERT 0 6
+INSERT INTO t2 (security_context, x, y) VALUES
+ ('system_u:object_r:sepgsql_table_t:s0:c1', 1, 'xxx'),
+ ('system_u:object_r:sepgsql_table_t:s0:c0', 2, 'yyy'),
+ ('system_u:object_r:sepgsql_table_t:s0', 3, 'zzz');
+INSERT 0 3
+SELECT security_context, * FROM t1;
+ security_context | a | b
+--------------------------------------------+---+-----
+ system_u:object_r:sepgsql_table_t:s0 | 1 | aaa
+ system_u:object_r:sepgsql_table_t:s0:c0 | 2 | bbb
+ system_u:object_r:sepgsql_table_t:s0:c1 | 3 | ccc
+ system_u:object_r:sepgsql_ro_table_t:s0 | 4 | ddd
+ system_u:object_r:sepgsql_ro_table_t:s0:c0 | 5 | eee
+ system_u:object_r:sepgsql_ro_table_t:s0:c1 | 6 | fff
+(6 rows)
+
+SELECT security_context, * FROM t2;
+ security_context | x | y
+-----------------------------------------+---+-----
+ system_u:object_r:sepgsql_table_t:s0:c1 | 1 | xxx
+ system_u:object_r:sepgsql_table_t:s0:c0 | 2 | yyy
+ system_u:object_r:sepgsql_table_t:s0 | 3 | zzz
+(3 rows)
+
+-- at SECURITY_CONTEXT=unconfined_u:unconfined_r:sepgsql_test_t:s0:c0
+SELECT sepgsql_getcon();
+ sepgsql_getcon
+------------------------------------------------
+ unconfined_u:unconfined_r:sepgsql_test_t:s0:c0
+(1 row)
+
+SELECT security_context, * FROM t1;
+ security_context | a | b
+--------------------------------------------+---+-----
+ system_u:object_r:sepgsql_table_t:s0 | 1 | aaa
+ system_u:object_r:sepgsql_table_t:s0:c0 | 2 | bbb
+ system_u:object_r:sepgsql_ro_table_t:s0 | 4 | ddd
+ system_u:object_r:sepgsql_ro_table_t:s0:c0 | 5 | eee
+(4 rows)
+
+SELECT security_context, * FROM t2;
+ security_context | x | y
+-----------------------------------------+---+-----
+ system_u:object_r:sepgsql_table_t:s0:c0 | 2 | yyy
+ system_u:object_r:sepgsql_table_t:s0 | 3 | zzz
+(2 rows)
+
+COPY t1 TO stdout;
+1 aaa
+2 bbb
+4 ddd
+5 eee
+COPY t2 (security_context, x, y) TO stdout;
+system_u:object_r:sepgsql_table_t:s0:c0 2 yyy
+system_u:object_r:sepgsql_table_t:s0 3 zzz
+UPDATE t1 SET a = 99 WHERE a = 1 RETURNING *; -- to be failed
+ERROR: SELinux: security policy violation
+CONTEXT: SQL statement "UPDATE ONLY "public"."t2" SET "x" = $1 WHERE $2 OPERATOR(pg_catalog.=) "x""
+UPDATE t1 SET a = 99 WHERE a = 2 RETURNING *;
+ a | b
+----+-----
+ 99 | bbb
+(1 row)
+
+UPDATE 1
+UPDATE t1 SET a = 99 WHERE a = 4 RETURNING *; -- to be denied
+ a | b
+---+---
+(0 rows)
+
+UPDATE 0
+INSERT INTO t1 VALUES (3, 'ccc'); -- to be failed
+ERROR: duplicate key value violates unique constraint "t1_pkey"
+INSERT INTO t1 VALUES (7, 'ggg');
+INSERT 0 1
+INSERT INTO t2 VALUES (3, 'XXX'); -- to be failed
+ERROR: insert or update on table "t2" violates foreign key constraint "t2_x_fkey"
+DETAIL: Key (x)=(3) is not present in table "t1".
+INSERT INTO t2 VALUES (4, 'XXX');
+INSERT 0 1
+DELETE FROM t1; -- to be failed
+ERROR: SELinux: security policy violation
+CONTEXT: SQL statement "SELECT 1 FROM ONLY "public"."t2" x WHERE $1 OPERATOR(pg_catalog.=) "x" FOR SHARE OF x"
+DELETE FROM t1 WHERE a not in (SELECT x FROM t2); -- to be failed
+ERROR: SELinux: security policy violation
+DELETE FROM t1 WHERE a = 7;
+DELETE 1
diff -rpNU3 base/src/test/sepgsql/expected/security_label.out sepgsql-new/src/test/sepgsql/expected/security_label.out
--- base/src/test/sepgsql/expected/security_label.out 1970-01-01 09:00:00.000000000 +0900
+++ sepgsql-new/src/test/sepgsql/expected/security_label.out 2009-03-15 17:38:39.000000000 +0900
@@ -0,0 +1,127 @@
+-- at SECURITY_CONTEXT=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c15
+SELECT sepgsql_getcon();
+ sepgsql_getcon
+-----------------------------------------------------
+ unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c15
+(1 row)
+
+-- cleanup previous tests
+SET client_min_messages TO 'error';
+SET
+DROP TABLE IF EXISTS t4 CASCADE;
+DROP TABLE
+DROP TABLE IF EXISTS t3 CASCADE;
+DROP TABLE
+DROP TABLE IF EXISTS t2 CASCADE;
+DROP TABLE
+DROP TABLE IF EXISTS t1 CASCADE;
+DROP TABLE
+DROP FUNCTION IF EXISTS f1(int) CASCADE;
+DROP FUNCTION
+DROP FUNCTION IF EXISTS f2(int) CASCADE;
+DROP FUNCTION
+RESET client_min_messages;
+RESET
+-- test begins here
+CREATE TABLE t1 (
+ a int,
+ b text
+);
+CREATE TABLE
+CREATE TABLE t2 (
+ x int,
+ y text
+);
+CREATE TABLE
+CREATE TABLE t3 (
+ s int,
+ t text
+) SECURITY_CONTEXT = 'unconfined_u:object_r:sepgsql_fixed_table_t:s0';
+CREATE TABLE
+INSERT INTO t1 VALUES (1, 'aaa');
+INSERT 0 1
+INSERT INTO t1 (security_context, a, b) VALUES ('unconfined_u:object_r:sepgsql_ro_table_t:s0', 2, 'bbb');
+INSERT 0 1
+INSERT INTO t1 (security_context, a, b) VALUES ('unconfined_u:object_r:sepgsql_table_t:s0:c1', 3, 'ccc');
+INSERT 0 1
+INSERT INTO t1 VALUES (4, 'ddd'), (5, 'eee');
+INSERT 0 2
+INSERT INTO t1 (security_context, a, b) VALUES ('invalid security context', 6, 'fff'); -- to be failed
+ERROR: invalid security label: invalid security context
+INSERT INTO t1 (security_context, a, b) VALUES ('system_u:object_r:sepgsql_table_t:s0:c20', 6, 'fff'); -- to be denied
+INSERT 0 0
+SELECT security_context, * FROM t1;
+ security_context | a | b
+---------------------------------------------+---+-----
+ unconfined_u:object_r:sepgsql_table_t:s0 | 1 | aaa
+ unconfined_u:object_r:sepgsql_ro_table_t:s0 | 2 | bbb
+ unconfined_u:object_r:sepgsql_table_t:s0:c1 | 3 | ccc
+ unconfined_u:object_r:sepgsql_table_t:s0 | 4 | ddd
+ unconfined_u:object_r:sepgsql_table_t:s0 | 5 | eee
+(5 rows)
+
+INSERT INTO t2 (security_context, x, y)
+ (SELECT sepgsql_set_user(security_context, 'system_u'), a + 5, b || '_cpy' FROM t1);
+INSERT 0 5
+SELECT security_context, * FROM t2;
+ security_context | x | y
+-----------------------------------------+----+---------
+ system_u:object_r:sepgsql_table_t:s0 | 6 | aaa_cpy
+ system_u:object_r:sepgsql_ro_table_t:s0 | 7 | bbb_cpy
+ system_u:object_r:sepgsql_table_t:s0:c1 | 8 | ccc_cpy
+ system_u:object_r:sepgsql_table_t:s0 | 9 | ddd_cpy
+ system_u:object_r:sepgsql_table_t:s0 | 10 | eee_cpy
+(5 rows)
+
+INSERT INTO t3 VALUES (98, 'xxx');
+INSERT 0 1
+INSERT INTO t3 (security_context, s, t) VALUES ('system_u:object_r:sepgsql_ro_table_t:s0', 99, 'yyy');
+INSERT 0 1
+INSERT INTO t3 (SELECT * FROM t1);
+INSERT 0 5
+INSERT INTO t3 (security_context, s, t) (SELECT security_context, x, y FROM t2);
+INSERT 0 5
+SELECT security_context, * FROM t3;
+ security_context | s | t
+------------------------------------------------+----+---------
+ unconfined_u:object_r:sepgsql_fixed_table_t:s0 | 98 | xxx
+ system_u:object_r:sepgsql_ro_table_t:s0 | 99 | yyy
+ unconfined_u:object_r:sepgsql_fixed_table_t:s0 | 1 | aaa
+ unconfined_u:object_r:sepgsql_fixed_table_t:s0 | 2 | bbb
+ unconfined_u:object_r:sepgsql_fixed_table_t:s0 | 3 | ccc
+ unconfined_u:object_r:sepgsql_fixed_table_t:s0 | 4 | ddd
+ unconfined_u:object_r:sepgsql_fixed_table_t:s0 | 5 | eee
+ system_u:object_r:sepgsql_table_t:s0 | 6 | aaa_cpy
+ system_u:object_r:sepgsql_ro_table_t:s0 | 7 | bbb_cpy
+ system_u:object_r:sepgsql_table_t:s0:c1 | 8 | ccc_cpy
+ system_u:object_r:sepgsql_table_t:s0 | 9 | ddd_cpy
+ system_u:object_r:sepgsql_table_t:s0 | 10 | eee_cpy
+(12 rows)
+
+SELECT sepgsql_set_range(security_context, 's0:c' || s) AS security_context, * INTO t4 FROM t3; -- partially denied
+SELECT
+SELECT security_context, * FROM t4;
+ security_context | s | t
+---------------------------------------------------+----+---------
+ unconfined_u:object_r:sepgsql_fixed_table_t:s0:c1 | 1 | aaa
+ unconfined_u:object_r:sepgsql_fixed_table_t:s0:c2 | 2 | bbb
+ unconfined_u:object_r:sepgsql_fixed_table_t:s0:c3 | 3 | ccc
+ unconfined_u:object_r:sepgsql_fixed_table_t:s0:c4 | 4 | ddd
+ unconfined_u:object_r:sepgsql_fixed_table_t:s0:c5 | 5 | eee
+ system_u:object_r:sepgsql_table_t:s0:c6 | 6 | aaa_cpy
+ system_u:object_r:sepgsql_ro_table_t:s0:c7 | 7 | bbb_cpy
+ system_u:object_r:sepgsql_table_t:s0:c8 | 8 | ccc_cpy
+ system_u:object_r:sepgsql_table_t:s0:c9 | 9 | ddd_cpy
+ system_u:object_r:sepgsql_table_t:s0:c10 | 10 | eee_cpy
+(10 rows)
+
+COPY t1 (security_context, a, b) FROM stdin; -- partially denied
+COPY t1 (security_context, a, b) TO stdout;
+unconfined_u:object_r:sepgsql_table_t:s0 1 aaa
+unconfined_u:object_r:sepgsql_ro_table_t:s0 2 bbb
+unconfined_u:object_r:sepgsql_table_t:s0:c1 3 ccc
+unconfined_u:object_r:sepgsql_table_t:s0 4 ddd
+unconfined_u:object_r:sepgsql_table_t:s0 5 eee
+system_u:object_r:sepgsql_table_t:s0:c2 10 kkk
+system_u:object_r:sepgsql_table_t:s0:c3 11 lll
+system_u:object_r:sepgsql_table_t:s0:c4 13 nnn
diff -rpNU3 base/src/test/sepgsql/launch_psql.c sepgsql-new/src/test/sepgsql/launch_psql.c
--- base/src/test/sepgsql/launch_psql.c 1970-01-01 09:00:00.000000000 +0900
+++ sepgsql-new/src/test/sepgsql/launch_psql.c 2009-03-15 17:38:39.000000000 +0900
@@ -0,0 +1,87 @@
+/*
+ * launch_psql.c
+ *
+ * It invokes psql with proper security context.
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <errno.h>
+#include <selinux/selinux.h>
+
+#define SETEXECCON_CMD "-- at SECURITY_CONTEXT="
+
+int main(int argc, char *const argv[])
+{
+ char buffer[2048], cmd[512];
+ FILE *filp = NULL;
+ int i, ofs;
+
+ if (argc < 2)
+ {
+ fprintf(stderr, "usage: %s <command> [<options> ...]\n", argv[0]);
+ return 1;
+ }
+
+ for (i=1, ofs=0; argv[i] != NULL; i++)
+ ofs += snprintf(cmd + ofs, sizeof(cmd) - ofs, " %s", argv[i]);
+
+ while (fgets(buffer, sizeof(buffer), stdin) != NULL)
+ {
+ if (strncasecmp(buffer, SETEXECCON_CMD,
+ sizeof(SETEXECCON_CMD) - 1) == 0)
+ {
+ security_context_t context = buffer + sizeof(SETEXECCON_CMD) - 1;
+ char *pos;
+
+ /* set exec security context */
+ pos = strchr(context, '#');
+ if (pos)
+ *pos = '\0';
+ pos = context + strlen(context) - 1;
+ while (isspace(*pos))
+ *pos-- = '\0';
+ if (setexeccon(context) < 0)
+ {
+ fprintf(stderr, "%s: setexeccon('%s') = %s\n",
+ argv[0], context, strerror(errno));
+ return 1;
+ }
+
+ if (filp != NULL)
+ {
+ pclose(filp);
+ filp = NULL;
+ }
+
+ /* Inject a pseudo sepgsql_getcon() to confirm new context */
+ ofs = strlen(buffer);
+ snprintf(buffer + ofs, sizeof(buffer) - ofs,
+ "\nSELECT sepgsql_getcon();\n");
+ }
+
+ if (filp == NULL)
+ {
+ filp = popen(cmd, "w");
+ if (!filp)
+ {
+ fprintf(stderr, "%s: popen('%s', 'w') = %s\n",
+ argv[0], cmd, strerror(errno));
+ return 1;
+ }
+ }
+
+ if (fwrite(buffer, 1, strlen(buffer), filp) < 0)
+ {
+ fprintf(stderr, "%s: fwrite(...) = %s\n",
+ argv[0], strerror(errno));
+ return 1;
+ }
+ }
+
+ if (filp)
+ pclose(filp);
+
+ return 0;
+}
diff -rpNU3 base/src/test/sepgsql/sql/basic.sql sepgsql-new/src/test/sepgsql/sql/basic.sql
--- base/src/test/sepgsql/sql/basic.sql 1970-01-01 09:00:00.000000000 +0900
+++ sepgsql-new/src/test/sepgsql/sql/basic.sql 2009-03-15 17:38:39.000000000 +0900
@@ -0,0 +1,59 @@
+-- at SECURITY_CONTEXT=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c15
+
+-- cleanup previous tests
+SET client_min_messages TO 'error';
+
+DROP TABLE IF EXISTS t4 CASCADE;
+DROP TABLE IF EXISTS t3 CASCADE;
+DROP TABLE IF EXISTS t2 CASCADE;
+DROP TABLE IF EXISTS t1 CASCADE;
+
+DROP FUNCTION IF EXISTS f1(int) CASCADE;
+
+RESET client_min_messages;
+
+-- SETUP
+
+CREATE TABLE t1
+(
+ a int,
+ b text
+ SECURITY_CONTEXT = 'unconfined_u:object_r:sepgsql_ro_table_t:s0',
+ c bool
+ SECURITY_CONTEXT = 'unconfined_u:object_r:sepgsql_secret_table_t:s0'
+);
+INSERT INTO t1 VALUES (1, 'aaa', false), (2, 'bbb', true);
+
+CREATE TABLE t2
+(
+ s int,
+ t int,
+ u int
+) SECURITY_CONTEXT = 'unconfined_u:object_r:sepgsql_table_t:s0:c0';
+ALTER TABLE t2 DROP COLUMN t; -- disturbing factor
+
+CREATE TABLE t3
+(
+ x text
+ SECURITY_CONTEXT = 'unconfined_u:object_r:sepgsql_table_t:s0:c1'
+) inherits(t2);
+
+-- at SECURITY_CONTEXT=unconfined_u:unconfined_r:sepgsql_test_t:s0-s0:c0
+
+SELECT * FROM t1; -- to be denied
+SELECT a, b FROM t1;
+SELECT COUNT(*) FROM t1 WHERE c; -- to be denied
+UPDATE t1 SET b = 'ccc'; -- to be denied
+UPDATE t1 SET a = a + 2;
+INSERT INTO t1 VALUES (5, 'eee', true); -- to be denied
+INSERT INTO t1 VALUES (5);
+
+SELECT * FROM t2;
+SELECT t2 FROM t2;
+SELECT t3 FROM t3; -- to be denied
+SELECT 1 FROM t3;
+
+-- at SECURITY_CONTEXT=unconfined_u:unconfined_r:sepgsql_test_t:s0-s0:c1
+SELECT * FROM t2; -- to be denied
+SELECT t2 FROM t2; -- to be denied
+SELECT t3 FROM t3;
diff -rpNU3 base/src/test/sepgsql/sql/copy_stmt.sql sepgsql-new/src/test/sepgsql/sql/copy_stmt.sql
--- base/src/test/sepgsql/sql/copy_stmt.sql 1970-01-01 09:00:00.000000000 +0900
+++ sepgsql-new/src/test/sepgsql/sql/copy_stmt.sql 2009-03-15 17:38:39.000000000 +0900
@@ -0,0 +1,58 @@
+-- at SECURITY_CONTEXT=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c15
+
+-- cleanup previous tests
+SET client_min_messages TO 'error';
+
+DROP TABLE IF EXISTS t3 CASCADE;
+DROP TABLE IF EXISTS t2 CASCADE;
+DROP TABLE IF EXISTS t1 CASCADE;
+
+DROP FUNCTION IF EXISTS f1(int) CASCADE;
+
+RESET client_min_messages;
+
+-- setup tables
+
+CREATE TABLE t1
+(
+ a int,
+ b text
+);
+
+INSERT INTO t1 VALUES (1, 'aaa'), (2, 'bbb');
+
+CREATE TABLE t2
+(
+ x int,
+ y text
+ SECURITY_CONTEXT = 'unconfined_u:object_r:sepgsql_secret_table_t:s0'
+);
+SELECT security_context from pg_attribute where attrelid = 't2'::regclass and attname = 'y';
+INSERT INTO t2 VALUES (1, 'xxx'), (2, 'yyy');
+
+CREATE TABLE t3 -- read only table
+(
+ s int,
+ t text
+) SECURITY_CONTEXT = 'unconfined_u:object_r:sepgsql_ro_table_t:s0';
+INSERT INTO t2 VALUES (1, 'sss'), (2, 'ttt');
+
+-- at SECURITY_CONTEXT=unconfined_u:unconfined_r:sepgsql_test_t:s0-s0:c0
+COPY t1 TO stdout;
+COPY t1 FROM stdin;
+3 ccc
+4 ddd
+\.
+
+COPY t1 TO '/tmp/sepgsql_test_copy_1';
+COPY t1 TO '/tmp/sepgsql_test_copy_2'; -- to be denied
+
+COPY t2 TO stdout; -- to be denied
+COPY t2 FROM stdin; -- to be denied
+COPY t2 (x) TO stdout;
+
+COPY t3 TO stdout;
+COPY t3 FROM '/tmp/sepgsql_test_copy_1'; -- to be denied
+
+COPY t1 FROM '/tmp/sepgsql_test_copy_1';
+COPY t1 TO stdout;
diff -rpNU3 base/src/test/sepgsql/sql/enhanced_ddl_stmt.sql sepgsql-new/src/test/sepgsql/sql/enhanced_ddl_stmt.sql
--- base/src/test/sepgsql/sql/enhanced_ddl_stmt.sql 1970-01-01 09:00:00.000000000 +0900
+++ sepgsql-new/src/test/sepgsql/sql/enhanced_ddl_stmt.sql 2009-03-15 17:38:39.000000000 +0900
@@ -0,0 +1,89 @@
+-- at SECURITY_CONTEXT=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c15
+
+-- cleanup previous tests
+SET client_min_messages TO 'error';
+
+DROP TABLE IF EXISTS t4 CASCADE;
+DROP TABLE IF EXISTS t3 CASCADE;
+DROP TABLE IF EXISTS t2 CASCADE;
+DROP TABLE IF EXISTS t1 CASCADE;
+
+DROP FUNCTION IF EXISTS f1(int) CASCADE;
+DROP FUNCTION IF EXISTS f2(int) CASCADE;
+
+RESET client_min_messages;
+
+-- CREATE TABLE with SECURITY_LABEL clause
+CREATE TABLE t1 (
+ a int,
+ b text
+);
+SELECT relname, security_context FROM pg_class WHERE oid = 't1'::regclass;
+SELECT attname, security_context FROM pg_attribute WHERE attrelid = 't1'::regclass and attnum > 0;
+
+CREATE TABLE t2 (
+ a int,
+ b text
+) SECURITY_CONTEXT = 'unconfined_u:object_r:sepgsql_ro_table_t:s0';
+SELECT relname, security_context FROM pg_class WHERE oid = 't2'::regclass;
+SELECT attname, security_context FROM pg_attribute WHERE attrelid = 't2'::regclass and attnum > 0;
+
+CREATE TABLE t3 (
+ a int,
+ b text SECURITY_CONTEXT = 'unconfined_u:object_r:sepgsql_fixed_table_t:s0',
+ c bool SECURITY_CONTEXT = 'unconfined_u:object_r:sepgsql_secret_table_t:s0',
+ d int
+) SECURITY_CONTEXT = 'unconfined_u:object_r:sepgsql_table_t:s0:c0';
+SELECT relname, security_context FROM pg_class WHERE oid = 't3'::regclass;
+SELECT attname, security_context FROM pg_attribute WHERE attrelid = 't3'::regclass and attnum > 0;
+
+CREATE TABLE t4 (
+ a int,
+ b text
+) SECURITY_CONTEXT = 'unconfined_u:object_r:invalid_label_t:s0'; -- to be failed
+
+CREATE TABLE t4 (
+ a int,
+ b text
+) SECURITY_CONTEXT = 'unconfined_u:object_r:sepgsql_proc_t:s0'; -- to be denied
+
+-- ALTER TABLE with SECURITY_CONTEXT clause
+ALTER TABLE t2 SECURITY_CONTEXT = 'unconfined_u:object_r:sepgsql_secret_table_t:s0';
+ALTER TABLE t2 ADD COLUMN c bool; -- it inherits table's one
+SELECT relname, security_context FROM pg_class WHERE oid = 't2'::regclass;
+SELECT attname, security_context FROM pg_attribute WHERE attrelid = 't2'::regclass and attnum > 0;
+
+ALTER TABLE t3 ALTER b SECURITY_CONTEXT = 'unconfined_u:object_r:sepgsql_table_t:s0';
+SELECT relname, security_context FROM pg_class WHERE oid = 't3'::regclass;
+SELECT attname, security_context FROM pg_attribute WHERE attrelid = 't3'::regclass and attnum > 0;
+
+-- CREATE FUNCTION with SECURITY_CONTEXT clause
+CREATE FUNCTION f1 (int) RETURNS int
+ LANGUAGE 'sql'
+ SECURITY_CONTEXT = 'unconfined_u:object_r:sepgsql_proc_t:s0:c0'
+ AS 'SELECT $1 * 2';
+SELECT proname, security_context FROM pg_proc WHERE oid = 'f1'::regproc;
+
+CREATE FUNCTION f2 (int) RETURNS int
+ LANGUAGE 'sql'
+ SECURITY_CONTEXT = 'unconfined_u:object_r:invalid_label_t:s0'
+ AS 'SELECT $1 + $1'; -- to be failed
+
+CREATE FUNCTION f2 (int) RETURNS int
+ LANGUAGE 'sql'
+ SECURITY_CONTEXT = 'unconfined_u:object_r:sepgsql_proc_t:s0:c16'
+ AS 'SELECT $1 + $1'; -- to be denied
+
+CREATE FUNCTION f2 (int) RETURNS int
+ LANGUAGE 'sql'
+ AS 'SELECT $1 + $1';
+SELECT proname, security_context FROM pg_proc WHERE oid = 'f2'::regproc;
+
+-- ALTER FUNCTION with SECURITY_CONTEXT clause
+ALTER FUNCTION f1(int)
+ SECURITY_CONTEXT = 'unconfined_u:object_r:sepgsql_proc_t:s0:c1';
+SELECT proname, security_context FROM pg_proc WHERE oid = 'f1'::regproc;
+
+ALTER FUNCTION f2(int)
+ SECURITY_CONTEXT = 'unconfined_u:object_r:sepgsql_proc_t:s0:c16'; -- to be denied
+SELECT proname, security_context FROM pg_proc WHERE oid = 'f2'::regproc;
diff -rpNU3 base/src/test/sepgsql/sql/join_query.sql sepgsql-new/src/test/sepgsql/sql/join_query.sql
--- base/src/test/sepgsql/sql/join_query.sql 1970-01-01 09:00:00.000000000 +0900
+++ sepgsql-new/src/test/sepgsql/sql/join_query.sql 2009-03-15 17:38:39.000000000 +0900
@@ -0,0 +1,50 @@
+-- at SECURITY_CONTEXT=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c15
+
+-- cleanup previous tests
+SET client_min_messages TO 'error';
+
+DROP TABLE IF EXISTS t4 CASCADE;
+DROP TABLE IF EXISTS t3 CASCADE;
+DROP TABLE IF EXISTS t2 CASCADE;
+DROP TABLE IF EXISTS t1 CASCADE;
+
+DROP FUNCTION IF EXISTS f1(int) CASCADE;
+
+RESET client_min_messages;
+
+-- SETUP
+CREATE TABLE t1
+(
+ a int,
+ b text,
+ c int
+ SECURITY_CONTEXT = 'unconfined_u:object_r:sepgsql_secret_table_t:s0'
+);
+INSERT INTO t1 VALUES (1, 'aaa'), (2, 'bbb'), (3, 'ccc');
+
+CREATE TABLE t2
+(
+ x int,
+ y text
+);
+INSERT INTO t2 VALUES (2, 'xxx'), (3, 'yyy'), (4,'zzz');
+
+CREATE TABLE t3
+(
+ d int
+) INHERITS (t1);
+INSERT INTO t3 VALUES (4, 'ddd'), (5, 'eee');
+
+CREATE TABLE t4
+(
+ z int
+ SECURITY_CONTEXT = 'unconfined_u:object_r:sepgsql_secret_table_t:s0'
+) INHERITS (t2);
+INSERT INTO t2 VALUES (1, 'sss'), (5, 'ttt');
+
+-- at SECURITY_CONTEXT=unconfined_u:unconfined_r:sepgsql_test_t:s0-s0:c0
+SELECT * FROM t1 JOIN t2 ON a = x; -- to be denied
+SELECT a, b, y FROM t1 JOIN t2 ON a = x;
+SELECT a, b, y FROM t1 JOIN t2 ON c = x; -- to be denied
+SELECT COUNT(*) FROM t1 JOIN t2 ON a = x;
+SELECT j FROM (t1 JOIN t2 ON a = x) AS j; -- to be denied
diff -rpNU3 base/src/test/sepgsql/sql/large_object.sql sepgsql-new/src/test/sepgsql/sql/large_object.sql
--- base/src/test/sepgsql/sql/large_object.sql 1970-01-01 09:00:00.000000000 +0900
+++ sepgsql-new/src/test/sepgsql/sql/large_object.sql 2009-03-15 17:38:39.000000000 +0900
@@ -0,0 +1,103 @@
+-- at SECURITY_CONTEXT=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c15
+
+-- cleanup previous tests
+SET client_min_messages TO 'error';
+
+DROP TABLE IF EXISTS lolabel CASCADE;
+DROP FUNCTION IF EXISTS lo_label(oid) CASCADE;
+
+RESET client_min_messages;
+
+CREATE TABLE lolabel(
+ loid oid,
+ label text
+);
+
+CREATE OR REPLACE FUNCTION lo_label(oid)
+ RETURNS TEXT LANGUAGE 'sql'
+ AS 'SELECT label FROM lolabel WHERE loid = $1';
+
+INSERT INTO lolabel (SELECT lo_import('/tmp/sepgsql_test_blob1'), 'normal');
+INSERT INTO lolabel (SELECT lo_import('/tmp/sepgsql_test_blob1'), 'readonly');
+INSERT INTO lolabel (SELECT lo_import('/tmp/sepgsql_test_blob1'), 'secret');
+
+SELECT lo_set_security(loid, 'system_u:object_r:sepgsql_blob_t:s0')
+ FROM lolabel WHERE label = 'normal';
+SELECT lo_set_security(loid, 'system_u:object_r:sepgsql_ro_blob_t:s0')
+ FROM lolabel WHERE label = 'readonly';
+SELECT lo_set_security(loid, 'system_u:object_r:sepgsql_secret_blob_t:s0')
+ FROM lolabel WHERE label = 'secret';
+
+-- at SECURITY_CONTEXT=unconfined_u:unconfined_r:sepgsql_test_t:s0:c0
+
+SELECT lo_get_security(loid) FROM lolabel;
+
+SELECT security_context, lo_label(loid) AS label, COUNT(*)
+ FROM pg_largeobject GROUP BY security_context, loid ORDER by label;
+
+-- read large object
+BEGIN;
+SELECT lo_open(loid, x'40000'::int) FROM lolabel WHERE label = 'normal';
+SELECT loread(0, 32);
+ROLLBACK;
+
+BEGIN;
+SELECT lo_open(loid, x'40000'::int) FROM lolabel WHERE label = 'readonly';
+SELECT loread(0, 32);
+ROLLBACK;
+
+BEGIN;
+SELECT lo_open(loid, x'40000'::int) FROM lolabel WHERE label = 'secret';
+SELECT loread(0, 32); -- to be denied
+ROLLBACK;
+
+-- write large object
+BEGIN;
+SELECT lo_open(loid, x'20000'::int) FROM lolabel WHERE label = 'normal';
+SELECT lowrite(0, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ');
+ROLLBACK;
+
+BEGIN;
+SELECT lo_open(loid, x'20000'::int) FROM lolabel WHERE label = 'readonly';
+SELECT lowrite(0, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'); -- to be denied
+ROLLBACK;
+
+BEGIN;
+SELECT lo_open(loid, x'20000'::int) FROM lolabel WHERE label = 'secret';
+SELECT lowrite(0, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'); -- to be denied
+ROLLBACK;
+
+-- create large object
+BEGIN;
+INSERT INTO lolabel (SELECT lo_create(6004), 'local');
+SELECT lo_open(loid, x'20000'::int) FROM lolabel WHERE label = 'local';
+SELECT lowrite(0, 'abcdefghijklmnopqrstuvwxyz');
+SELECT lo_close(0);
+COMMIT;
+
+-- getattr/setattr
+BEGIN;
+SELECT lo_open(loid, x'20000'::int) FROM lolabel WHERE label = 'local';
+SELECT lo_lseek(0, 0, 2); -- seek to end
+SELECT lowrite(0, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ');
+SELECT lo_tell(0);
+SELECT lo_lseek(0, 0, 0); -- seek to head
+SELECT loread(0, 50);
+SELECT lo_close(0);
+COMMIT;
+
+-- at SECURITY_CONTEXT=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c15
+
+-- change security label
+BEGIN;
+SELECT lo_open(loid, x'40000'::int) FROM lolabel; -- a seed of trouble
+SELECT lo_set_security(loid, 'system_u:object_r:sepgsql_blob_t:s0:c4')
+ FROM lolabel WHERE label in ('normal', 'readonly');
+SELECT lo_get_security(loid) FROM lolabel;
+SELECT security_context, lo_label(loid) AS label, count(*)
+ FROM pg_largeobject WHERE loid in (SELECT loid FROM lolabel)
+ GROUP BY security_context, loid ORDER BY label;
+ROLLBACK;
+
+-- cleanup
+SELECT lo_unlink(loid) FROM lolabel;
diff -rpNU3 base/src/test/sepgsql/sql/row_level.sql sepgsql-new/src/test/sepgsql/sql/row_level.sql
--- base/src/test/sepgsql/sql/row_level.sql 1970-01-01 09:00:00.000000000 +0900
+++ sepgsql-new/src/test/sepgsql/sql/row_level.sql 2009-03-15 17:38:39.000000000 +0900
@@ -0,0 +1,61 @@
+-- at SECURITY_CONTEXT=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c15
+
+-- cleanup previous tests
+SET client_min_messages TO 'error';
+
+DROP TABLE IF EXISTS t4 CASCADE;
+DROP TABLE IF EXISTS t3 CASCADE;
+DROP TABLE IF EXISTS t2 CASCADE;
+DROP TABLE IF EXISTS t1 CASCADE;
+
+DROP FUNCTION IF EXISTS f1(int) CASCADE;
+DROP FUNCTION IF EXISTS f2(int) CASCADE;
+
+RESET client_min_messages;
+
+-- test begins here
+CREATE TABLE t1 (
+ a int primary key,
+ b text
+);
+
+CREATE TABLE t2 (
+ x int references t1 (a) on update cascade,
+ y text
+);
+
+INSERT INTO t1 (security_context, a, b) VALUES
+ ('system_u:object_r:sepgsql_table_t:s0', 1, 'aaa'),
+ ('system_u:object_r:sepgsql_table_t:s0:c0', 2, 'bbb'),
+ ('system_u:object_r:sepgsql_table_t:s0:c1', 3, 'ccc'),
+ ('system_u:object_r:sepgsql_ro_table_t:s0', 4, 'ddd'),
+ ('system_u:object_r:sepgsql_ro_table_t:s0:c0', 5, 'eee'),
+ ('system_u:object_r:sepgsql_ro_table_t:s0:c1', 6, 'fff');
+
+INSERT INTO t2 (security_context, x, y) VALUES
+ ('system_u:object_r:sepgsql_table_t:s0:c1', 1, 'xxx'),
+ ('system_u:object_r:sepgsql_table_t:s0:c0', 2, 'yyy'),
+ ('system_u:object_r:sepgsql_table_t:s0', 3, 'zzz');
+
+SELECT security_context, * FROM t1;
+SELECT security_context, * FROM t2;
+
+-- at SECURITY_CONTEXT=unconfined_u:unconfined_r:sepgsql_test_t:s0:c0
+SELECT security_context, * FROM t1;
+SELECT security_context, * FROM t2;
+
+COPY t1 TO stdout;
+COPY t2 (security_context, x, y) TO stdout;
+
+UPDATE t1 SET a = 99 WHERE a = 1 RETURNING *; -- to be failed
+UPDATE t1 SET a = 99 WHERE a = 2 RETURNING *;
+UPDATE t1 SET a = 99 WHERE a = 4 RETURNING *; -- to be denied
+
+INSERT INTO t1 VALUES (3, 'ccc'); -- to be failed
+INSERT INTO t1 VALUES (7, 'ggg');
+INSERT INTO t2 VALUES (3, 'XXX'); -- to be failed
+INSERT INTO t2 VALUES (4, 'XXX');
+
+DELETE FROM t1; -- to be failed
+DELETE FROM t1 WHERE a not in (SELECT x FROM t2); -- to be failed
+DELETE FROM t1 WHERE a = 7;
diff -rpNU3 base/src/test/sepgsql/sql/security_label.sql sepgsql-new/src/test/sepgsql/sql/security_label.sql
--- base/src/test/sepgsql/sql/security_label.sql 1970-01-01 09:00:00.000000000 +0900
+++ sepgsql-new/src/test/sepgsql/sql/security_label.sql 2009-03-15 17:38:39.000000000 +0900
@@ -0,0 +1,60 @@
+-- at SECURITY_CONTEXT=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c15
+
+-- cleanup previous tests
+SET client_min_messages TO 'error';
+
+DROP TABLE IF EXISTS t4 CASCADE;
+DROP TABLE IF EXISTS t3 CASCADE;
+DROP TABLE IF EXISTS t2 CASCADE;
+DROP TABLE IF EXISTS t1 CASCADE;
+
+DROP FUNCTION IF EXISTS f1(int) CASCADE;
+DROP FUNCTION IF EXISTS f2(int) CASCADE;
+
+RESET client_min_messages;
+
+-- test begins here
+CREATE TABLE t1 (
+ a int,
+ b text
+);
+
+CREATE TABLE t2 (
+ x int,
+ y text
+);
+
+CREATE TABLE t3 (
+ s int,
+ t text
+) SECURITY_CONTEXT = 'unconfined_u:object_r:sepgsql_fixed_table_t:s0';
+
+INSERT INTO t1 VALUES (1, 'aaa');
+INSERT INTO t1 (security_context, a, b) VALUES ('unconfined_u:object_r:sepgsql_ro_table_t:s0', 2, 'bbb');
+INSERT INTO t1 (security_context, a, b) VALUES ('unconfined_u:object_r:sepgsql_table_t:s0:c1', 3, 'ccc');
+INSERT INTO t1 VALUES (4, 'ddd'), (5, 'eee');
+INSERT INTO t1 (security_context, a, b) VALUES ('invalid security context', 6, 'fff'); -- to be failed
+INSERT INTO t1 (security_context, a, b) VALUES ('system_u:object_r:sepgsql_table_t:s0:c20', 6, 'fff'); -- to be denied
+SELECT security_context, * FROM t1;
+
+INSERT INTO t2 (security_context, x, y)
+ (SELECT sepgsql_set_user(security_context, 'system_u'), a + 5, b || '_cpy' FROM t1);
+SELECT security_context, * FROM t2;
+
+INSERT INTO t3 VALUES (98, 'xxx');
+INSERT INTO t3 (security_context, s, t) VALUES ('system_u:object_r:sepgsql_ro_table_t:s0', 99, 'yyy');
+INSERT INTO t3 (SELECT * FROM t1);
+INSERT INTO t3 (security_context, s, t) (SELECT security_context, x, y FROM t2);
+SELECT security_context, * FROM t3;
+
+SELECT sepgsql_set_range(security_context, 's0:c' || s) AS security_context, * INTO t4 FROM t3; -- partially denied
+SELECT security_context, * FROM t4;
+
+COPY t1 (security_context, a, b) FROM stdin; -- partially denied
+system_u:object_r:sepgsql_table_t:s0:c2 10 kkk
+system_u:object_r:sepgsql_table_t:s0:c3 11 lll
+system_u:object_r:sepgsql_table_t:s0:c20 12 mmm
+system_u:object_r:sepgsql_table_t:s0:c4 13 nnn
+\.
+
+COPY t1 (security_context, a, b) TO stdout;
sepostgresql-utils-8.3.patch:
--- NEW FILE sepostgresql-utils-8.3.patch ---
diff -rpNU3 base/src/bin/initdb/initdb.c sepgsql-new/src/bin/initdb/initdb.c
--- base/src/bin/initdb/initdb.c 2008-11-05 09:57:00.000000000 +0900
+++ sepgsql-new/src/bin/initdb/initdb.c 2009-03-13 18:14:33.000000000 +0900
@@ -94,6 +94,7 @@ static bool debug = false;
static bool noclean = false;
static bool show_setting = false;
static char *xlog_dir = "";
+static bool enable_selinux = false;
/* internal vars */
@@ -1212,6 +1213,13 @@ setup_config(void)
"#default_text_search_config = 'pg_catalog.simple'",
repltok);
+ if (enable_selinux)
+ {
+ strcpy(repltok, "sepostgresql = on");
+ conflines = replace_token(conflines,
+ "#sepostgresql = off", repltok);
+ }
+
snprintf(path, sizeof(path), "%s/postgresql.conf", pg_data);
writefile(path, conflines);
@@ -2383,6 +2391,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(_(" --enable-selinux enables SELinux support, if compiled\n"));
printf(_(" -?, --help show this help, then exit\n"));
printf(_(" -V, --version output version information, then exit\n"));
printf(_("\nLess commonly used options:\n"));
@@ -2417,6 +2426,7 @@ main(int argc, char *argv[])
{"auth", required_argument, NULL, 'A'},
{"pwprompt", no_argument, NULL, 'W'},
{"pwfile", required_argument, NULL, 9},
+ {"enable-selinux", no_argument, NULL, 10},
{"username", required_argument, NULL, 'U'},
{"help", no_argument, NULL, '?'},
{"version", no_argument, NULL, 'V'},
@@ -2531,6 +2541,9 @@ main(int argc, char *argv[])
case 9:
pwfilename = xstrdup(optarg);
break;
+ case 10:
+ enable_selinux = true;
+ break;
case 's':
show_setting = true;
break;
diff -rpNU3 base/src/bin/pg_dump/pg_dump.c sepgsql-new/src/bin/pg_dump/pg_dump.c
--- base/src/bin/pg_dump/pg_dump.c 2009-02-02 11:47:17.000000000 +0900
+++ sepgsql-new/src/bin/pg_dump/pg_dump.c 2009-03-13 18:14:33.000000000 +0900
@@ -118,6 +118,8 @@ static int g_numNamespaces;
/* flag to turn on/off dollar quoting */
static int disable_dollar_quoting = 0;
+/* flag to turn on/off security context support */
+static int enable_selinux = 0;
static void help(const char *progname);
static void expand_schema_name_patterns(SimpleStringList *patterns,
@@ -267,6 +269,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, &enable_selinux, 1},
{NULL, 0, NULL, 0}
};
@@ -419,6 +422,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)
+ enable_selinux = 1;
else
{
fprintf(stderr,
@@ -549,6 +554,24 @@ main(int argc, char **argv)
std_strings = PQparameterStatus(g_conn, "standard_conforming_strings");
g_fout->std_strings = (std_strings && strcmp(std_strings, "on") == 0);
+ /* check availability of SE-PostgreSQL */
+ if (enable_selinux > 0)
+ {
+ const char *sepostgresql
+ = PQparameterStatus(g_conn, "sepostgresql");
+
+ if (!sepostgresql)
+ {
+ write_msg(NULL, "could not obtain server status.");
+ exit(1);
+ }
+ if (strcmp(sepostgresql, "on") != 0)
+ {
+ write_msg(NULL, "SE-PostgreSQL is not available now.");
+ exit(1);
+ }
+ }
+
/* Set the datestyle to ISO to ensure the dump's portability */
do_sql_command(g_conn, "SET DATESTYLE = ISO");
@@ -771,6 +794,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 +1195,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",
+ (enable_selinux > 0 ? "security_context," : ""),
fmtQualifiedId(tbinfo->dobj.namespace->dobj.name,
classname));
}
@@ -1785,11 +1810,29 @@ dumpBlobComments(Archive *AH, void *arg)
Oid blobOid;
char *comment;
+ blobOid = atooid(PQgetvalue(res, i, 0));
+ if (enable_selinux > 0)
+ {
+ char query[256];
+ PGresult *sres;
+
+ snprintf(query, sizeof(query),
+ "SELECT lo_get_security(%u)", blobOid);
+ sres = PQexec(g_conn, query);
+ if (sres)
+ {
+ if (PQresultStatus(res) == PGRES_TUPLES_OK
+ && PQntuples(res) == 1)
+ archprintf(AH, "SELECT lo_set_security(%u, '%s');\n",
+ blobOid, PQgetvalue(sres, 0, 0));
+ PQclear(sres);
+ }
+ }
+
/* 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 ",
@@ -2887,6 +2930,7 @@ getTables(int *numTables)
int i_owning_col;
int i_reltablespace;
int i_reloptions;
+ int i_relseclabel;
/* Make sure we are in proper schema */
selectSourceSchema("pg_catalog");
@@ -2926,7 +2970,8 @@ getTables(int *numTables)
"d.refobjid as owning_tab, "
"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 "
+ "array_to_string(c.reloptions, ', ') as reloptions, "
+ "%s as security_label "
"from pg_class c "
"left join pg_depend d on "
"(c.relkind = '%c' and "
@@ -2936,6 +2981,7 @@ getTables(int *numTables)
"where relkind in ('%c', '%c', '%c', '%c') "
"order by c.oid",
username_subquery,
+ (enable_selinux > 0 ? "c.security_context" : "NULL"),
RELKIND_SEQUENCE,
RELKIND_RELATION, RELKIND_SEQUENCE,
RELKIND_VIEW, RELKIND_COMPOSITE_TYPE);
@@ -2955,7 +3001,8 @@ getTables(int *numTables)
"d.refobjid as owning_tab, "
"d.refobjsubid as owning_col, "
"(SELECT spcname FROM pg_tablespace t WHERE t.oid = c.reltablespace) AS reltablespace, "
- "NULL as reloptions "
+ "NULL as reloptions, "
+ "NULL as security_label "
"from pg_class c "
"left join pg_depend d on "
"(c.relkind = '%c' and "
@@ -2984,7 +3031,8 @@ getTables(int *numTables)
"d.refobjid as owning_tab, "
"d.refobjsubid as owning_col, "
"NULL as reltablespace, "
- "NULL as reloptions "
+ "NULL as reloptions, "
+ "NULL as security_label, "
"from pg_class c "
"left join pg_depend d on "
"(c.relkind = '%c' and "
@@ -3009,7 +3057,8 @@ getTables(int *numTables)
"NULL::oid as owning_tab, "
"NULL::int4 as owning_col, "
"NULL as reltablespace, "
- "NULL as reloptions "
+ "NULL as reloptions, "
+ "NULL as security_label, "
"from pg_class "
"where relkind in ('%c', '%c', '%c') "
"order by oid",
@@ -3029,7 +3078,8 @@ getTables(int *numTables)
"NULL::oid as owning_tab, "
"NULL::int4 as owning_col, "
"NULL as reltablespace, "
- "NULL as reloptions "
+ "NULL as reloptions, "
+ "NULL as security_label "
"from pg_class "
"where relkind in ('%c', '%c', '%c') "
"order by oid",
@@ -3059,7 +3109,8 @@ getTables(int *numTables)
"NULL::oid as owning_tab, "
"NULL::int4 as owning_col, "
"NULL as reltablespace, "
- "NULL as reloptions "
+ "NULL as reloptions, "
+ "NULL as security_label "
"from pg_class c "
"where relkind in ('%c', '%c') "
"order by oid",
@@ -3102,6 +3153,7 @@ getTables(int *numTables)
i_owning_col = PQfnumber(res, "owning_col");
i_reltablespace = PQfnumber(res, "reltablespace");
i_reloptions = PQfnumber(res, "reloptions");
+ i_relseclabel = PQfnumber(res, "security_label");
for (i = 0; i < ntups; i++)
{
@@ -3132,6 +3184,7 @@ getTables(int *numTables)
}
tblinfo[i].reltablespace = strdup(PQgetvalue(res, i, i_reltablespace));
tblinfo[i].reloptions = strdup(PQgetvalue(res, i, i_reloptions));
+ tblinfo[i].relseclabel = strdup(PQgetvalue(res, i, i_relseclabel));
/* other fields were zeroed above */
@@ -4320,6 +4373,7 @@ getTableAttrs(TableInfo *tblinfo, int nu
int i_atthasdef;
int i_attisdropped;
int i_attislocal;
+ int i_attseclabel;
PGresult *res;
int ntups;
bool hasdefaults;
@@ -4362,12 +4416,14 @@ getTableAttrs(TableInfo *tblinfo, int nu
/* need left join here to not fail on dropped columns ... */
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 "
+ "pg_catalog.format_type(t.oid,a.atttypmod) as atttypname, "
+ "%s as security_label "
"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",
+ (enable_selinux > 0 ? "a.security_context" : "NULL"),
tbinfo->dobj.catId.oid);
}
else if (g_fout->remoteVersion >= 70100)
@@ -4379,7 +4435,8 @@ getTableAttrs(TableInfo *tblinfo, int nu
*/
appendPQExpBuffer(q, "SELECT a.attnum, a.attname, a.atttypmod, -1 as attstattarget, a.attstorage, t.typstorage, "
"a.attnotnull, a.atthasdef, false as attisdropped, false as attislocal, "
- "format_type(t.oid,a.atttypmod) as atttypname "
+ "format_type(t.oid,a.atttypmod) as atttypname, "
+ "NULL as security_label "
"from pg_attribute a left join pg_type t "
"on a.atttypid = t.oid "
"where a.attrelid = '%u'::oid "
@@ -4392,7 +4449,8 @@ getTableAttrs(TableInfo *tblinfo, int nu
/* format_type not available before 7.1 */
appendPQExpBuffer(q, "SELECT attnum, attname, atttypmod, -1 as attstattarget, attstorage, attstorage as typstorage, "
"attnotnull, atthasdef, false as attisdropped, false as attislocal, "
- "(select typname from pg_type where oid = atttypid) as atttypname "
+ "(select typname from pg_type where oid = atttypid) as atttypname, "
+ "NULL as security_label "
"from pg_attribute a "
"where attrelid = '%u'::oid "
"and attnum > 0::int2 "
@@ -4416,6 +4474,7 @@ getTableAttrs(TableInfo *tblinfo, int nu
i_atthasdef = PQfnumber(res, "atthasdef");
i_attisdropped = PQfnumber(res, "attisdropped");
i_attislocal = PQfnumber(res, "attislocal");
+ i_attseclabel = PQfnumber(res, "attseclabel");
tbinfo->numatts = ntups;
tbinfo->attnames = (char **) malloc(ntups * sizeof(char *));
@@ -4426,6 +4485,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->attseclabel = (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));
@@ -4449,6 +4509,7 @@ getTableAttrs(TableInfo *tblinfo, int nu
tbinfo->typstorage[j] = *(PQgetvalue(res, j, i_typstorage));
tbinfo->attisdropped[j] = (PQgetvalue(res, j, i_attisdropped)[0] == 't');
tbinfo->attislocal[j] = (PQgetvalue(res, j, i_attislocal)[0] == 't');
+ tbinfo->attseclabel[j] = strdup(PQgetvalue(res, j, i_attseclabel));
tbinfo->notnull[j] = (PQgetvalue(res, j, i_attnotnull)[0] == 't');
tbinfo->attrdefs[j] = NULL; /* fix below */
if (PQgetvalue(res, j, i_atthasdef)[0] == 't')
@@ -6430,6 +6491,7 @@ dumpFunc(Archive *fout, FuncInfo *finfo)
char *procost;
char *prorows;
char *lanname;
+ char *proseclabel;
char *rettypename;
int nallargs;
char **allargtypes = NULL;
@@ -6459,9 +6521,11 @@ dumpFunc(Archive *fout, FuncInfo *finfo)
"proallargtypes, proargmodes, proargnames, "
"provolatile, proisstrict, prosecdef, "
"proconfig, procost, prorows, "
- "(SELECT lanname FROM pg_catalog.pg_language WHERE oid = prolang) as lanname "
+ "(SELECT lanname FROM pg_catalog.pg_language WHERE oid = prolang) as lanname, "
+ "%s as security_label "
"FROM pg_catalog.pg_proc "
"WHERE oid = '%u'::pg_catalog.oid",
+ (enable_selinux > 0 ? "security_context" : "NULL"),
finfo->dobj.catId.oid);
}
else if (g_fout->remoteVersion >= 80100)
@@ -6471,7 +6535,8 @@ dumpFunc(Archive *fout, FuncInfo *finfo)
"proallargtypes, proargmodes, proargnames, "
"provolatile, proisstrict, prosecdef, "
"null as proconfig, 0 as procost, 0 as prorows, "
- "(SELECT lanname FROM pg_catalog.pg_language WHERE oid = prolang) as lanname "
+ "(SELECT lanname FROM pg_catalog.pg_language WHERE oid = prolang) as lanname, "
+ "NULL as security_label "
"FROM pg_catalog.pg_proc "
"WHERE oid = '%u'::pg_catalog.oid",
finfo->dobj.catId.oid);
@@ -6485,7 +6550,8 @@ dumpFunc(Archive *fout, FuncInfo *finfo)
"proargnames, "
"provolatile, proisstrict, prosecdef, "
"null as proconfig, 0 as procost, 0 as prorows, "
- "(SELECT lanname FROM pg_catalog.pg_language WHERE oid = prolang) as lanname "
+ "(SELECT lanname FROM pg_catalog.pg_language WHERE oid = prolang) as lanname, "
+ "NULL as security_label "
"FROM pg_catalog.pg_proc "
"WHERE oid = '%u'::pg_catalog.oid",
finfo->dobj.catId.oid);
@@ -6499,7 +6565,8 @@ dumpFunc(Archive *fout, FuncInfo *finfo)
"null as proargnames, "
"provolatile, proisstrict, prosecdef, "
"null as proconfig, 0 as procost, 0 as prorows, "
- "(SELECT lanname FROM pg_catalog.pg_language WHERE oid = prolang) as lanname "
+ "(SELECT lanname FROM pg_catalog.pg_language WHERE oid = prolang) as lanname, "
+ "NULL as security_label "
"FROM pg_catalog.pg_proc "
"WHERE oid = '%u'::pg_catalog.oid",
finfo->dobj.catId.oid);
@@ -6515,7 +6582,8 @@ dumpFunc(Archive *fout, FuncInfo *finfo)
"proisstrict, "
"'f'::boolean as prosecdef, "
"null as proconfig, 0 as procost, 0 as prorows, "
- "(SELECT lanname FROM pg_language WHERE oid = prolang) as lanname "
+ "(SELECT lanname FROM pg_language WHERE oid = prolang) as lanname, "
+ "NULL as security_label "
"FROM pg_proc "
"WHERE oid = '%u'::oid",
finfo->dobj.catId.oid);
@@ -6531,7 +6599,8 @@ dumpFunc(Archive *fout, FuncInfo *finfo)
"'f'::boolean as proisstrict, "
"'f'::boolean as prosecdef, "
"null as proconfig, 0 as procost, 0 as prorows, "
- "(SELECT lanname FROM pg_language WHERE oid = prolang) as lanname "
+ "(SELECT lanname FROM pg_language WHERE oid = prolang) as lanname, "
+ "NULL as security_label "
"FROM pg_proc "
"WHERE oid = '%u'::oid",
finfo->dobj.catId.oid);
@@ -6562,6 +6631,7 @@ dumpFunc(Archive *fout, FuncInfo *finfo)
procost = PQgetvalue(res, 0, PQfnumber(res, "procost"));
prorows = PQgetvalue(res, 0, PQfnumber(res, "prorows"));
lanname = PQgetvalue(res, 0, PQfnumber(res, "lanname"));
+ proseclabel = PQgetvalue(res, 0, PQfnumber(res, "security_label"));
/*
* See backend/commands/define.c for details of how the 'AS' clause is
@@ -6699,6 +6769,9 @@ dumpFunc(Archive *fout, FuncInfo *finfo)
if (prosecdef[0] == 't')
appendPQExpBuffer(q, " SECURITY DEFINER");
+ if (proseclabel[0] != '\0')
+ appendPQExpBuffer(q, " SECURITY_CONTEXT = '%s'", proseclabel);
+
/*
* 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
@@ -8780,6 +8853,10 @@ dumpTableSchema(Archive *fout, TableInfo
if (tbinfo->notnull[j] && !tbinfo->inhNotNull[j])
appendPQExpBuffer(q, " NOT NULL");
+ if (tbinfo->attseclabel[j] != '\0' &&
+ strcmp(tbinfo->attseclabel[j], tbinfo->relseclabel) != 0)
+ appendPQExpBuffer(q, " SECURITY_CONTEXT = '%s'", tbinfo->attseclabel[j]);
+
actual_atts++;
}
}
@@ -8827,6 +8904,9 @@ dumpTableSchema(Archive *fout, TableInfo
if (tbinfo->reloptions && strlen(tbinfo->reloptions) > 0)
appendPQExpBuffer(q, "\nWITH (%s)", tbinfo->reloptions);
+ if (tbinfo->relseclabel[0] != '\0')
+ appendPQExpBuffer(q, " SECURITY_CONTEXT = '%s'", tbinfo->relseclabel);
+
appendPQExpBuffer(q, ";\n");
/* Loop dumping statistics and storage statements */
@@ -10244,6 +10324,13 @@ fmtCopyColumnList(const TableInfo *ti)
appendPQExpBuffer(q, "(");
needComma = false;
+
+ if (enable_selinux > 0)
+ {
+ appendPQExpBuffer(q, "%s", "security_context");
+ needComma = true;
+ }
+
for (i = 0; i < numatts; i++)
{
if (attisdropped[i])
diff -rpNU3 base/src/bin/pg_dump/pg_dump.h sepgsql-new/src/bin/pg_dump/pg_dump.h
--- base/src/bin/pg_dump/pg_dump.h 2009-02-02 11:47:17.000000000 +0900
+++ sepgsql-new/src/bin/pg_dump/pg_dump.h 2009-03-13 18:14:33.000000000 +0900
@@ -238,6 +238,7 @@ typedef struct _tableInfo
char relkind;
char *reltablespace; /* relation tablespace */
char *reloptions; /* options specified by WITH (...) */
+ char *relseclabel; /* security context 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 **attseclabel; /* security context 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-new/src/bin/pg_dump/pg_dumpall.c
--- base/src/bin/pg_dump/pg_dumpall.c 2008-01-07 23:51:33.000000000 +0900
+++ sepgsql-new/src/bin/pg_dump/pg_dumpall.c 2009-03-13 18:14:33.000000000 +0900
@@ -67,6 +67,9 @@ static int disable_triggers = 0;
static int use_setsessauth = 0;
static int server_version;
+/* flag to turn on/off security context support */
+static int enable_selinux = 0;
+
static FILE *OPF;
static char *filename = NULL;
@@ -119,6 +122,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, &enable_selinux, 1},
{NULL, 0, NULL, 0}
};
@@ -290,6 +294,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)
+ enable_selinux = 1;
else
{
fprintf(stderr,
@@ -316,6 +322,8 @@ main(int argc, char *argv[])
appendPQExpBuffer(pgdumpopts, " --disable-triggers");
if (use_setsessauth)
appendPQExpBuffer(pgdumpopts, " --use-set-session-authorization");
+ if (enable_selinux)
+ appendPQExpBuffer(pgdumpopts, " --security-context");
if (optind < argc)
{
@@ -391,6 +399,24 @@ main(int argc, char *argv[])
}
}
+ /* check availability of SE-PostgreSQL */
+ if (enable_selinux > 0)
+ {
+ const char *sepostgresql
+ = PQparameterStatus(conn, "sepostgresql");
+
+ if (!sepostgresql)
+ {
+ fprintf(stderr, "could not obtain server status.");
+ exit(1);
+ }
+ if (strcmp(sepostgresql, "on") != 0)
+ {
+ fprintf(stderr, "SE-PostgreSQL is not available now.");
+ exit(1);
+ }
+ }
+
/*
* Open the output file if required, otherwise use stdout
*/
@@ -505,6 +531,7 @@ help(void)
printf(_(" --use-set-session-authorization\n"
" use SESSION AUTHORIZATION commands instead of\n"
" OWNER TO commands\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"));
@@ -915,41 +942,46 @@ 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 "
+ "(SELECT spcname FROM pg_tablespace t WHERE t.oid = d.dattablespace) AS dattablespace, "
+ "%s as security_label "
"FROM pg_database d LEFT JOIN pg_authid u ON (datdba = u.oid) "
- "WHERE datallowconn ORDER BY 1");
+ "WHERE datallowconn ORDER BY 1",
+ (enable_selinux > 0 ? "d.security_context" : "NULL"));
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), "
"datistemplate, datacl, -1 as datconnlimit, "
- "(SELECT spcname FROM pg_tablespace t WHERE t.oid = d.dattablespace) AS dattablespace "
+ "(SELECT spcname FROM pg_tablespace t WHERE t.oid = d.dattablespace) AS dattablespace, "
+ "NULL as security_label "
"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), "
"datistemplate, datacl, -1 as datconnlimit, "
- "'pg_default' AS dattablespace "
+ "'pg_default' AS dattablespace, "
+ "NULL as security_label "
"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), "
"(select usename from pg_shadow where usesysid=(select datdba from pg_database where datname='template0'))), "
"pg_encoding_to_char(d.encoding), "
"datistemplate, '' as datacl, -1 as datconnlimit, "
- "'pg_default' AS dattablespace "
+ "'pg_default' AS dattablespace, "
+ "NULL as security_label "
"FROM pg_database d "
"WHERE datallowconn ORDER BY 1");
else
@@ -958,16 +990,18 @@ 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), "
"'f' as datistemplate, "
"'' as datacl, -1 as datconnlimit, "
- "'pg_default' AS dattablespace "
+ "'pg_default' AS dattablespace, "
+ "NULL as security_label "
"FROM pg_database d "
"ORDER BY 1");
}
+ res = executeQuery(conn, buf->data);
for (i = 0; i < PQntuples(res); i++)
{
@@ -978,6 +1012,7 @@ dumpCreateDB(PGconn *conn)
char *dbacl = PQgetvalue(res, i, 4);
char *dbconnlimit = PQgetvalue(res, i, 5);
char *dbtablespace = PQgetvalue(res, i, 6);
+ char *dbseclabel = PQgetvalue(res, i, 7);
char *fdbname;
fdbname = strdup(fmtId(dbname));
@@ -1021,6 +1056,9 @@ dumpCreateDB(PGconn *conn)
appendPQExpBuffer(buf, " CONNECTION LIMIT = %s",
dbconnlimit);
+ if (dbseclabel[0] != '\0')
+ appendPQExpBuffer(buf, " SECURITY_CONTEXT = '%s'", dbseclabel);
+
appendPQExpBuffer(buf, ";\n");
if (strcmp(dbistemplate, "t") == 0)
Index: .cvsignore
===================================================================
RCS file: /cvs/pkgs/rpms/sepostgresql/devel/.cvsignore,v
retrieving revision 1.13
retrieving revision 1.14
diff -u -r1.13 -r1.14
--- .cvsignore 6 Feb 2009 02:34:41 -0000 1.13
+++ .cvsignore 27 Mar 2009 03:54:13 -0000 1.14
@@ -1 +1 @@
-postgresql-8.3.6.tar.bz2
+postgresql-8.3.7.tar.bz2
Index: sepostgresql.init
===================================================================
RCS file: /cvs/pkgs/rpms/sepostgresql/devel/sepostgresql.init,v
retrieving revision 1.30
retrieving revision 1.31
diff -u -r1.30 -r1.31
--- sepostgresql.init 26 Feb 2009 12:31:05 -0000 1.30
+++ sepostgresql.init 27 Mar 2009 03:54:13 -0000 1.31
@@ -7,9 +7,9 @@
# pidfile: /var/run/postmaster.pid
#---------------------------------------------------------------------
-PGVERSION="8.3.6"
+PGVERSION="8.3.7"
PGMAJORVERSION=`echo "$PGVERSION" | sed 's/^\([0-9]*\.[0-9a-z]*\).*$/\1/'`
-SEPGVERSION="2.1634"
+SEPGVERSION="1770"
# source function library
. /etc/rc.d/init.d/functions
Index: sepostgresql.spec
===================================================================
RCS file: /cvs/pkgs/rpms/sepostgresql/devel/sepostgresql.spec,v
retrieving revision 1.33
retrieving revision 1.34
diff -u -r1.33 -r1.34
--- sepostgresql.spec 26 Feb 2009 12:31:05 -0000 1.33
+++ sepostgresql.spec 27 Mar 2009 03:54:13 -0000 1.34
@@ -7,22 +7,12 @@
# SE-PostgreSQL status extension
%define selinux_policy_stores targeted mls
-# Check required policy version
-%define fedora9 %(rpm -E '%{dist}' | grep -cE '^\.fc[1-9]$')
-%if %{fedora9}
-%define required_policy_version 3.3.1
-%else
-%define required_policy_version 3.4.2
-%endif
-
-
-
%{!?ssl:%define ssl 1}
Summary: Security Enhanced PostgreSQL
Name: sepostgresql
-Version: 8.3.6
-Release: 2.1634%{?sepgsql_extension}%{?dist}
+Version: 8.3.7
+Release: 1770%{?dist}
License: BSD
Group: Applications/Databases
Url: http://code.google.com/p/sepgsql/
@@ -31,16 +21,13 @@
Source1: sepostgresql.init
Source2: sepostgresql.8
Source3: sepostgresql.logrotate
-Patch0: sepostgresql-sepgsql-8.3.6-2.patch
-Patch1: sepostgresql-policy-8.3.6-2.patch
-Patch2: sepostgresql-pg_dump-8.3.6-2.patch
+Patch0: sepostgresql-core-8.3.patch
+Patch1: sepostgresql-utils-8.3.patch
+Patch2: sepostgresql-test-8.3.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 >= %{required_policy_version}
-%if %{fedora9}
-BuildRequires: selinux-policy-devel
-%endif
+BuildRequires: selinux-policy >= 3.4.2
%if %{ssl}
BuildRequires: openssl-devel
%endif
@@ -50,7 +37,7 @@
Requires(postun): policycoreutils
Requires: postgresql-server = %{version}
Requires: policycoreutils >= 2.0.16 libselinux >= 2.0.43
-Requires: selinux-policy >= %{required_policy_version}
+Requires: selinux-policy >= 3.4.2
Requires: tzdata logrotate
%description
@@ -78,34 +65,28 @@
%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}
-%if !%{fedora9}
touch src/backend/security/sepgsql/policy/sepostgresql-devel.fc
make -C src/backend/security/sepgsql/policy
-%endif
%install
rm -rf %{buildroot}
make DESTDIR=%{buildroot} install
-%if !%{fedora9}
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
-%endif
# avoid to conflict with native postgresql package
mv %{buildroot}%{_bindir} %{buildroot}%{_bindir}.orig
@@ -155,7 +136,6 @@
/sbin/chkconfig --add %{name}
/sbin/ldconfig
-%if !%{fedora9}
for store in %{selinux_policy_stores}
do
# clean up legacy policy module (now it is unnecessary)
@@ -165,7 +145,6 @@
-i %{_datadir}/selinux/${store}/sepostgresql-devel.pp >& /dev/null || :
fi
done
-%endif
# Fix up non-standard file contexts
/sbin/fixfiles -R %{name} restore || :
@@ -193,7 +172,7 @@
%files
%defattr(-,root,root,-)
-%doc COPYRIGHT README HISTORY
+%doc COPYRIGHT README
%{_initrddir}/sepostgresql
%{_sysconfdir}/logrotate.d/sepostgresql
%{_bindir}/initdb.sepgsql
@@ -214,14 +193,16 @@
%{_datadir}/sepgsql/conversion_create.sql
%{_datadir}/sepgsql/information_schema.sql
%{_datadir}/sepgsql/sql_features.txt
-%if !%{fedora9}
%attr(644,root,root) %{_datadir}/selinux/*/sepostgresql-devel.pp
-%endif
%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
+* Fri Mar 27 2009 KaiGai Kohei <kaigai at kaigai.gr.jp> - 8.3.7-1770
+- upgrade base PostgreSQL versin 8.3.6->8.3.7
+- backport features from v8.4devel
+
* Thu Feb 26 2009 KaiGai Kohei <kaigai at kaigai.gr.jp> - 8.3.6-2.1635
- bugfix: possible information leak by the order of permission checks
in row level permission checks.
Index: sources
===================================================================
RCS file: /cvs/pkgs/rpms/sepostgresql/devel/sources,v
retrieving revision 1.10
retrieving revision 1.11
diff -u -r1.10 -r1.11
--- sources 6 Feb 2009 02:34:41 -0000 1.10
+++ sources 27 Mar 2009 03:54:13 -0000 1.11
@@ -1 +1 @@
-4f8c67d802bd03b5b844e268bba7d44a postgresql-8.3.6.tar.bz2
+7b7e91a2221e55fe1b167e663217a96d postgresql-8.3.7.tar.bz2
--- sepostgresql-pg_dump-8.3.6-2.patch DELETED ---
--- sepostgresql-policy-8.3.6-2.patch DELETED ---
--- sepostgresql-sepgsql-8.3.6-2.patch DELETED ---
- Previous message: rpms/sepostgresql/F-10 sepostgresql-pg_dump-8.3.7-2.patch, NONE, 1.1 sepostgresql-policy-8.3.7-2.patch, NONE, 1.1 sepostgresql-sepgsql-8.3.7-2.patch, NONE, 1.1 .cvsignore, 1.13, 1.14 sepostgresql.init, 1.30, 1.31 sepostgresql.spec, 1.31, 1.32 sources, 1.10, 1.11 sepostgresql-pg_dump-8.3.6-2.patch, 1.1, NONE sepostgresql-policy-8.3.6-2.patch, 1.2, NONE sepostgresql-sepgsql-8.3.6-2.patch, 1.2, NONE
- Next message: rpms/repoview/devel .cvsignore, 1.10, 1.11 repoview.spec, 1.13, 1.14 sources, 1.11, 1.12 repoview-case.patch, 1.1, NONE
- Messages sorted by:
[ date ]
[ thread ]
[ subject ]
[ author ]
More information about the scm-commits
mailing list