PostgreSQL Source Code  git master
proc.c File Reference
#include "postgres.h"
#include "access/genam.h"
#include "access/htup_details.h"
#include "access/sysattr.h"
#include "access/table.h"
#include "catalog/dependency.h"
#include "catalog/pg_namespace.h"
#include "catalog/pg_proc.h"
#include "catalog/pg_type.h"
#include "commands/seclabel.h"
#include "lib/stringinfo.h"
#include "sepgsql.h"
#include "utils/builtins.h"
#include "utils/fmgroids.h"
#include "utils/lsyscache.h"
#include "utils/snapmgr.h"
#include "utils/syscache.h"
Include dependency graph for proc.c:

Go to the source code of this file.

Functions

void sepgsql_proc_post_create (Oid functionId)
 
void sepgsql_proc_drop (Oid functionId)
 
void sepgsql_proc_relabel (Oid functionId, const char *seclabel)
 
void sepgsql_proc_setattr (Oid functionId)
 
void sepgsql_proc_execute (Oid functionId)
 

Function Documentation

◆ sepgsql_proc_drop()

void sepgsql_proc_drop ( Oid  functionId)

Definition at line 155 of file proc.c.

156 {
157  ObjectAddress object;
158  char *audit_name;
159 
160  /*
161  * check db_schema:{remove_name} permission
162  */
163  object.classId = NamespaceRelationId;
164  object.objectId = get_func_namespace(functionId);
165  object.objectSubId = 0;
166  audit_name = getObjectIdentity(&object, false);
167 
168  sepgsql_avc_check_perms(&object,
171  audit_name,
172  true);
173  pfree(audit_name);
174 
175  /*
176  * check db_procedure:{drop} permission
177  */
178  object.classId = ProcedureRelationId;
179  object.objectId = functionId;
180  object.objectSubId = 0;
181  audit_name = getObjectIdentity(&object, false);
182 
183  sepgsql_avc_check_perms(&object,
186  audit_name,
187  true);
188  pfree(audit_name);
189 }
Oid get_func_namespace(Oid funcid)
Definition: lsyscache.c:1610
void pfree(void *pointer)
Definition: mcxt.c:1508
char * getObjectIdentity(const ObjectAddress *object, bool missing_ok)
#define SEPG_CLASS_DB_SCHEMA
Definition: sepgsql.h:45
#define SEPG_DB_SCHEMA__REMOVE_NAME
Definition: sepgsql.h:135
#define SEPG_DB_PROCEDURE__DROP
Definition: sepgsql.h:161
#define SEPG_CLASS_DB_PROCEDURE
Definition: sepgsql.h:48
bool sepgsql_avc_check_perms(const ObjectAddress *tobject, uint16 tclass, uint32 required, const char *audit_name, bool abort_on_violation)
Definition: uavc.c:420

References ObjectAddress::classId, get_func_namespace(), getObjectIdentity(), pfree(), SEPG_CLASS_DB_PROCEDURE, SEPG_CLASS_DB_SCHEMA, SEPG_DB_PROCEDURE__DROP, SEPG_DB_SCHEMA__REMOVE_NAME, and sepgsql_avc_check_perms().

Referenced by sepgsql_object_access().

◆ sepgsql_proc_execute()

void sepgsql_proc_execute ( Oid  functionId)

Definition at line 315 of file proc.c.

316 {
317  ObjectAddress object;
318  char *audit_name;
319 
320  /*
321  * check db_procedure:{execute} permission
322  */
323  object.classId = ProcedureRelationId;
324  object.objectId = functionId;
325  object.objectSubId = 0;
326  audit_name = getObjectIdentity(&object, false);
327  sepgsql_avc_check_perms(&object,
330  audit_name,
331  true);
332  pfree(audit_name);
333 }
#define SEPG_DB_PROCEDURE__EXECUTE
Definition: sepgsql.h:166

References ObjectAddress::classId, getObjectIdentity(), pfree(), SEPG_CLASS_DB_PROCEDURE, SEPG_DB_PROCEDURE__EXECUTE, and sepgsql_avc_check_perms().

Referenced by sepgsql_object_access().

◆ sepgsql_proc_post_create()

void sepgsql_proc_post_create ( Oid  functionId)

Definition at line 37 of file proc.c.

38 {
39  Relation rel;
40  ScanKeyData skey;
41  SysScanDesc sscan;
42  HeapTuple tuple;
43  char *nsp_name;
44  char *scontext;
45  char *tcontext;
46  char *ncontext;
48  int i;
49  StringInfoData audit_name;
50  ObjectAddress object;
51  Form_pg_proc proForm;
52 
53  /*
54  * Fetch namespace of the new procedure. Because pg_proc entry is not
55  * visible right now, we need to scan the catalog using SnapshotSelf.
56  */
57  rel = table_open(ProcedureRelationId, AccessShareLock);
58 
59  ScanKeyInit(&skey,
60  Anum_pg_proc_oid,
61  BTEqualStrategyNumber, F_OIDEQ,
62  ObjectIdGetDatum(functionId));
63 
64  sscan = systable_beginscan(rel, ProcedureOidIndexId, true,
65  SnapshotSelf, 1, &skey);
66 
67  tuple = systable_getnext(sscan);
68  if (!HeapTupleIsValid(tuple))
69  elog(ERROR, "could not find tuple for function %u", functionId);
70 
71  proForm = (Form_pg_proc) GETSTRUCT(tuple);
72 
73  /*
74  * check db_schema:{add_name} permission of the namespace
75  */
76  object.classId = NamespaceRelationId;
77  object.objectId = proForm->pronamespace;
78  object.objectSubId = 0;
82  getObjectIdentity(&object, false),
83  true);
84 
85  /*
86  * XXX - db_language:{implement} also should be checked here
87  */
88 
89 
90  /*
91  * Compute a default security label when we create a new procedure object
92  * under the specified namespace.
93  */
94  scontext = sepgsql_get_client_label();
95  tcontext = sepgsql_get_label(NamespaceRelationId,
96  proForm->pronamespace, 0);
97  ncontext = sepgsql_compute_create(scontext, tcontext,
99  NameStr(proForm->proname));
100 
101  /*
102  * check db_procedure:{create (install)} permission
103  */
104  initStringInfo(&audit_name);
105  nsp_name = get_namespace_name(proForm->pronamespace);
106  appendStringInfo(&audit_name, "%s(",
107  quote_qualified_identifier(nsp_name, NameStr(proForm->proname)));
108  for (i = 0; i < proForm->pronargs; i++)
109  {
110  if (i > 0)
111  appendStringInfoChar(&audit_name, ',');
112 
113  object.classId = TypeRelationId;
114  object.objectId = proForm->proargtypes.values[i];
115  object.objectSubId = 0;
116  appendStringInfoString(&audit_name, getObjectIdentity(&object, false));
117  }
118  appendStringInfoChar(&audit_name, ')');
119 
121  if (proForm->proleakproof)
123 
126  required,
127  audit_name.data,
128  true);
129 
130  /*
131  * Assign the default security label on a new procedure
132  */
133  object.classId = ProcedureRelationId;
134  object.objectId = functionId;
135  object.objectSubId = 0;
136  SetSecurityLabel(&object, SEPGSQL_LABEL_TAG, ncontext);
137 
138  /*
139  * Cleanup
140  */
141  systable_endscan(sscan);
143 
144  pfree(audit_name.data);
145  pfree(tcontext);
146  pfree(ncontext);
147 }
#define NameStr(name)
Definition: c.h:733
unsigned int uint32
Definition: c.h:493
#define ERROR
Definition: elog.h:39
#define elog(elevel,...)
Definition: elog.h:224
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:596
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:503
SysScanDesc systable_beginscan(Relation heapRelation, Oid indexId, bool indexOK, Snapshot snapshot, int nkeys, ScanKey key)
Definition: genam.c:384
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
#define GETSTRUCT(TUP)
Definition: htup_details.h:653
int i
Definition: isn.c:73
char * sepgsql_get_label(Oid classId, Oid objectId, int32 subId)
Definition: label.c:445
char * sepgsql_get_client_label(void)
Definition: label.c:80
#define AccessShareLock
Definition: lockdefs.h:36
char * get_namespace_name(Oid nspid)
Definition: lsyscache.c:3344
FormData_pg_proc * Form_pg_proc
Definition: pg_proc.h:136
static Datum ObjectIdGetDatum(Oid X)
Definition: postgres.h:252
char * quote_qualified_identifier(const char *qualifier, const char *ident)
Definition: ruleutils.c:12437
void ScanKeyInit(ScanKey entry, AttrNumber attributeNumber, StrategyNumber strategy, RegProcedure procedure, Datum argument)
Definition: scankey.c:76
void SetSecurityLabel(const ObjectAddress *object, const char *provider, const char *label)
Definition: seclabel.c:404
char * sepgsql_compute_create(const char *scontext, const char *tcontext, uint16 tclass, const char *objname)
Definition: selinux.c:842
#define SEPG_DB_PROCEDURE__CREATE
Definition: sepgsql.h:160
bool sepgsql_avc_check_perms_label(const char *tcontext, uint16 tclass, uint32 required, const char *audit_name, bool abort_on_violation)
Definition: uavc.c:337
#define SEPG_DB_PROCEDURE__INSTALL
Definition: sepgsql.h:168
#define SEPG_DB_SCHEMA__ADD_NAME
Definition: sepgsql.h:134
#define SEPGSQL_LABEL_TAG
Definition: sepgsql.h:23
#define SnapshotSelf
Definition: snapmgr.h:32
#define BTEqualStrategyNumber
Definition: stratnum.h:31
void appendStringInfo(StringInfo str, const char *fmt,...)
Definition: stringinfo.c:97
void appendStringInfoString(StringInfo str, const char *s)
Definition: stringinfo.c:182
void appendStringInfoChar(StringInfo str, char ch)
Definition: stringinfo.c:194
void initStringInfo(StringInfo str)
Definition: stringinfo.c:59
void table_close(Relation relation, LOCKMODE lockmode)
Definition: table.c:126
Relation table_open(Oid relationId, LOCKMODE lockmode)
Definition: table.c:40

References AccessShareLock, appendStringInfo(), appendStringInfoChar(), appendStringInfoString(), BTEqualStrategyNumber, StringInfoData::data, elog, ERROR, get_namespace_name(), getObjectIdentity(), GETSTRUCT, HeapTupleIsValid, i, initStringInfo(), NameStr, ObjectIdGetDatum(), pfree(), quote_qualified_identifier(), generate_unaccent_rules::required, ScanKeyInit(), SEPG_CLASS_DB_PROCEDURE, SEPG_CLASS_DB_SCHEMA, SEPG_DB_PROCEDURE__CREATE, SEPG_DB_PROCEDURE__INSTALL, SEPG_DB_SCHEMA__ADD_NAME, sepgsql_avc_check_perms(), sepgsql_avc_check_perms_label(), sepgsql_compute_create(), sepgsql_get_client_label(), sepgsql_get_label(), SEPGSQL_LABEL_TAG, SetSecurityLabel(), SnapshotSelf, systable_beginscan(), systable_endscan(), systable_getnext(), table_close(), and table_open().

Referenced by sepgsql_object_access().

◆ sepgsql_proc_relabel()

void sepgsql_proc_relabel ( Oid  functionId,
const char *  seclabel 
)

Definition at line 198 of file proc.c.

199 {
200  ObjectAddress object;
201  char *audit_name;
202 
203  object.classId = ProcedureRelationId;
204  object.objectId = functionId;
205  object.objectSubId = 0;
206  audit_name = getObjectIdentity(&object, false);
207 
208  /*
209  * check db_procedure:{setattr relabelfrom} permission
210  */
211  sepgsql_avc_check_perms(&object,
215  audit_name,
216  true);
217 
218  /*
219  * check db_procedure:{relabelto} permission
220  */
224  audit_name,
225  true);
226  pfree(audit_name);
227 }
#define SEPG_DB_PROCEDURE__RELABELFROM
Definition: sepgsql.h:164
#define SEPG_DB_PROCEDURE__RELABELTO
Definition: sepgsql.h:165
#define SEPG_DB_PROCEDURE__SETATTR
Definition: sepgsql.h:163

References ObjectAddress::classId, getObjectIdentity(), pfree(), SEPG_CLASS_DB_PROCEDURE, SEPG_DB_PROCEDURE__RELABELFROM, SEPG_DB_PROCEDURE__RELABELTO, SEPG_DB_PROCEDURE__SETATTR, sepgsql_avc_check_perms(), and sepgsql_avc_check_perms_label().

Referenced by sepgsql_object_relabel().

◆ sepgsql_proc_setattr()

void sepgsql_proc_setattr ( Oid  functionId)

Definition at line 235 of file proc.c.

236 {
237  Relation rel;
238  ScanKeyData skey;
239  SysScanDesc sscan;
240  HeapTuple oldtup;
241  HeapTuple newtup;
242  Form_pg_proc oldform;
243  Form_pg_proc newform;
245  ObjectAddress object;
246  char *audit_name;
247 
248  /*
249  * Fetch newer catalog
250  */
251  rel = table_open(ProcedureRelationId, AccessShareLock);
252 
253  ScanKeyInit(&skey,
254  Anum_pg_proc_oid,
255  BTEqualStrategyNumber, F_OIDEQ,
256  ObjectIdGetDatum(functionId));
257 
258  sscan = systable_beginscan(rel, ProcedureOidIndexId, true,
259  SnapshotSelf, 1, &skey);
260  newtup = systable_getnext(sscan);
261  if (!HeapTupleIsValid(newtup))
262  elog(ERROR, "could not find tuple for function %u", functionId);
263  newform = (Form_pg_proc) GETSTRUCT(newtup);
264 
265  /*
266  * Fetch older catalog
267  */
268  oldtup = SearchSysCache1(PROCOID, ObjectIdGetDatum(functionId));
269  if (!HeapTupleIsValid(oldtup))
270  elog(ERROR, "cache lookup failed for function %u", functionId);
271  oldform = (Form_pg_proc) GETSTRUCT(oldtup);
272 
273  /*
274  * Does this ALTER command takes operation to namespace?
275  */
276  if (newform->pronamespace != oldform->pronamespace)
277  {
278  sepgsql_schema_remove_name(oldform->pronamespace);
279  sepgsql_schema_add_name(oldform->pronamespace);
280  }
281  if (strcmp(NameStr(newform->proname), NameStr(oldform->proname)) != 0)
282  sepgsql_schema_rename(oldform->pronamespace);
283 
284  /*
285  * check db_procedure:{setattr (install)} permission
286  */
288  if (!oldform->proleakproof && newform->proleakproof)
290 
291  object.classId = ProcedureRelationId;
292  object.objectId = functionId;
293  object.objectSubId = 0;
294  audit_name = getObjectIdentity(&object, false);
295 
296  sepgsql_avc_check_perms(&object,
298  required,
299  audit_name,
300  true);
301  /* cleanups */
302  pfree(audit_name);
303 
304  ReleaseSysCache(oldtup);
305  systable_endscan(sscan);
307 }
void sepgsql_schema_rename(Oid namespaceId)
Definition: schema.c:229
void sepgsql_schema_remove_name(Oid namespaceId)
Definition: schema.c:223
void sepgsql_schema_add_name(Oid namespaceId)
Definition: schema.c:217
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:266
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:218

References AccessShareLock, BTEqualStrategyNumber, elog, ERROR, getObjectIdentity(), GETSTRUCT, HeapTupleIsValid, NameStr, ObjectIdGetDatum(), pfree(), ReleaseSysCache(), generate_unaccent_rules::required, ScanKeyInit(), SearchSysCache1(), SEPG_CLASS_DB_PROCEDURE, SEPG_DB_PROCEDURE__INSTALL, SEPG_DB_PROCEDURE__SETATTR, sepgsql_avc_check_perms(), sepgsql_schema_add_name(), sepgsql_schema_remove_name(), sepgsql_schema_rename(), SnapshotSelf, systable_beginscan(), systable_endscan(), systable_getnext(), table_close(), and table_open().

Referenced by sepgsql_object_access().