pgsql-v9.2-sepgsql-create-permissions-part-4.v2.proc.patch
application/octet-stream
Filename: pgsql-v9.2-sepgsql-create-permissions-part-4.v2.proc.patch
Type: application/octet-stream
Part: 0
Patch
Same data as JSON:
GET /api/v1/attachments/:id/patch
the parsed metadata as JSON — format, series position, per-file stats; never the diff bytes.
API reference →
Format: unified
Series: patch v9
| File | + | − |
|---|---|---|
| contrib/sepgsql/expected/create.out | 12 | 1 |
| contrib/sepgsql/proc.c | 49 | 6 |
| contrib/sepgsql/sql/create.sql | 7 | 0 |
contrib/sepgsql/expected/create.out | 13 +++++++-
contrib/sepgsql/proc.c | 55 +++++++++++++++++++++++++++++++----
contrib/sepgsql/sql/create.sql | 7 ++++
3 files changed, 68 insertions(+), 7 deletions(-)
diff --git a/contrib/sepgsql/expected/create.out b/contrib/sepgsql/expected/create.out
index 9b5c3d1..0f04a3e 100644
--- a/contrib/sepgsql/expected/create.out
+++ b/contrib/sepgsql/expected/create.out
@@ -56,14 +56,25 @@ CREATE SEQUENCE regtest_seq;
LOG: SELinux: allowed { add_name } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_schema_t:s0 tclass=db_schema name="schema regtest_schema"
LOG: SELinux: allowed { create } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_seq_t:s0 tclass=db_sequence name="sequence regtest_seq"
CREATE TYPE regtest_comptype AS (a int, b text);
+CREATE FUNCTION regtest_func(text,int[]) RETURNS bool LANGUAGE plpgsql
+ AS 'BEGIN RAISE NOTICE ''regtest_func => %'', $1; RETURN true; END';
+LOG: SELinux: allowed { add_name } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_schema_t:s0 tclass=db_schema name="schema regtest_schema"
+LOG: SELinux: allowed { create } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_proc_exec_t:s0 tclass=db_procedure name="function regtest_func(text,integer[])"
+CREATE AGGREGATE regtest_agg (
+ sfunc1 = int4pl, basetype = int4, stype1 = int4, initcond1 = '0'
+);
+LOG: SELinux: allowed { add_name } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_schema_t:s0 tclass=db_schema name="schema regtest_schema"
+LOG: SELinux: allowed { create } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_proc_exec_t:s0 tclass=db_procedure name="function regtest_agg(integer)"
--
-- clean-up
--
DROP DATABASE IF EXISTS regtest_sepgsql_test_database;
DROP SCHEMA IF EXISTS regtest_schema CASCADE;
-NOTICE: drop cascades to 5 other objects
+NOTICE: drop cascades to 7 other objects
DETAIL: drop cascades to table regtest_table
drop cascades to table regtest_table_2
drop cascades to view regtest_view
drop cascades to sequence regtest_seq
drop cascades to type regtest_comptype
+drop cascades to function regtest_func(text,integer[])
+drop cascades to function regtest_agg(integer)
diff --git a/contrib/sepgsql/proc.c b/contrib/sepgsql/proc.c
index 9630d45..14231c4 100644
--- a/contrib/sepgsql/proc.c
+++ b/contrib/sepgsql/proc.c
@@ -18,6 +18,7 @@
#include "catalog/pg_namespace.h"
#include "catalog/pg_proc.h"
#include "commands/seclabel.h"
+#include "utils/builtins.h"
#include "utils/fmgroids.h"
#include "utils/lsyscache.h"
#include "utils/tqual.h"
@@ -37,11 +38,13 @@ sepgsql_proc_post_create(Oid functionId)
ScanKeyData skey;
SysScanDesc sscan;
HeapTuple tuple;
- Oid namespaceId;
- ObjectAddress object;
char *scontext;
char *tcontext;
char *ncontext;
+ int i;
+ StringInfoData audit_name;
+ ObjectAddress object;
+ Form_pg_proc proForm;
/*
* Fetch namespace of the new procedure. Because pg_proc entry is not
@@ -61,21 +64,54 @@ sepgsql_proc_post_create(Oid functionId)
if (!HeapTupleIsValid(tuple))
elog(ERROR, "catalog lookup failed for proc %u", functionId);
- namespaceId = ((Form_pg_proc) GETSTRUCT(tuple))->pronamespace;
+ proForm = (Form_pg_proc) GETSTRUCT(tuple);
+
+ /*
+ * check db_schema:{add_name} permission of the namespace
+ */
+ object.classId = NamespaceRelationId;
+ object.objectId = proForm->pronamespace;
+ object.objectSubId = 0;
+ sepgsql_avc_check_perms(&object,
+ SEPG_CLASS_DB_SCHEMA,
+ SEPG_DB_SCHEMA__ADD_NAME,
+ getObjectDescription(&object),
+ true);
+ /*
+ * XXX - db_language:{implement} also should be checked here
+ */
- systable_endscan(sscan);
- heap_close(rel, AccessShareLock);
/*
* Compute a default security label when we create a new procedure object
* under the specified namespace.
*/
scontext = sepgsql_get_client_label();
- tcontext = sepgsql_get_label(NamespaceRelationId, namespaceId, 0);
+ tcontext = sepgsql_get_label(NamespaceRelationId,
+ proForm->pronamespace, 0);
ncontext = sepgsql_compute_create(scontext, tcontext,
SEPG_CLASS_DB_PROCEDURE);
/*
+ * check db_procedure:{create} permission
+ */
+ initStringInfo(&audit_name);
+ appendStringInfo(&audit_name, "function %s(", NameStr(proForm->proname));
+ for (i=0; i < proForm->pronargs; i++)
+ {
+ Oid typeoid = proForm->proargtypes.values[i];
+ if (i > 0)
+ appendStringInfoChar(&audit_name, ',');
+ appendStringInfoString(&audit_name, format_type_be(typeoid));
+ }
+ appendStringInfoChar(&audit_name, ')');
+
+ sepgsql_avc_check_perms_label(ncontext,
+ SEPG_CLASS_DB_PROCEDURE,
+ SEPG_DB_PROCEDURE__CREATE,
+ audit_name.data,
+ true);
+ /*
* Assign the default security label on a new procedure
*/
object.classId = ProcedureRelationId;
@@ -83,6 +119,13 @@ sepgsql_proc_post_create(Oid functionId)
object.objectSubId = 0;
SetSecurityLabel(&object, SEPGSQL_LABEL_TAG, ncontext);
+ /*
+ * Cleanup
+ */
+ systable_endscan(sscan);
+ heap_close(rel, AccessShareLock);
+
+ pfree(audit_name.data);
pfree(tcontext);
pfree(ncontext);
}
diff --git a/contrib/sepgsql/sql/create.sql b/contrib/sepgsql/sql/create.sql
index 9a1db91..b0695b4 100644
--- a/contrib/sepgsql/sql/create.sql
+++ b/contrib/sepgsql/sql/create.sql
@@ -31,6 +31,13 @@ CREATE SEQUENCE regtest_seq;
CREATE TYPE regtest_comptype AS (a int, b text);
+CREATE FUNCTION regtest_func(text,int[]) RETURNS bool LANGUAGE plpgsql
+ AS 'BEGIN RAISE NOTICE ''regtest_func => %'', $1; RETURN true; END';
+
+CREATE AGGREGATE regtest_agg (
+ sfunc1 = int4pl, basetype = int4, stype1 = int4, initcond1 = '0'
+);
+
--
-- clean-up
--