00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #include "postgres.h"
00012
00013 #include "access/genam.h"
00014 #include "access/heapam.h"
00015 #include "access/htup_details.h"
00016 #include "access/sysattr.h"
00017 #include "catalog/dependency.h"
00018 #include "catalog/indexing.h"
00019 #include "catalog/pg_namespace.h"
00020 #include "catalog/pg_proc.h"
00021 #include "catalog/pg_type.h"
00022 #include "commands/seclabel.h"
00023 #include "lib/stringinfo.h"
00024 #include "utils/builtins.h"
00025 #include "utils/fmgroids.h"
00026 #include "utils/lsyscache.h"
00027 #include "utils/syscache.h"
00028 #include "utils/tqual.h"
00029
00030 #include "sepgsql.h"
00031
00032
00033
00034
00035
00036
00037
00038 void
00039 sepgsql_proc_post_create(Oid functionId)
00040 {
00041 Relation rel;
00042 ScanKeyData skey;
00043 SysScanDesc sscan;
00044 HeapTuple tuple;
00045 char *nsp_name;
00046 char *scontext;
00047 char *tcontext;
00048 char *ncontext;
00049 uint32 required;
00050 int i;
00051 StringInfoData audit_name;
00052 ObjectAddress object;
00053 Form_pg_proc proForm;
00054
00055
00056
00057
00058
00059 rel = heap_open(ProcedureRelationId, AccessShareLock);
00060
00061 ScanKeyInit(&skey,
00062 ObjectIdAttributeNumber,
00063 BTEqualStrategyNumber, F_OIDEQ,
00064 ObjectIdGetDatum(functionId));
00065
00066 sscan = systable_beginscan(rel, ProcedureOidIndexId, true,
00067 SnapshotSelf, 1, &skey);
00068
00069 tuple = systable_getnext(sscan);
00070 if (!HeapTupleIsValid(tuple))
00071 elog(ERROR, "catalog lookup failed for proc %u", functionId);
00072
00073 proForm = (Form_pg_proc) GETSTRUCT(tuple);
00074
00075
00076
00077
00078 object.classId = NamespaceRelationId;
00079 object.objectId = proForm->pronamespace;
00080 object.objectSubId = 0;
00081 sepgsql_avc_check_perms(&object,
00082 SEPG_CLASS_DB_SCHEMA,
00083 SEPG_DB_SCHEMA__ADD_NAME,
00084 getObjectIdentity(&object),
00085 true);
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096 scontext = sepgsql_get_client_label();
00097 tcontext = sepgsql_get_label(NamespaceRelationId,
00098 proForm->pronamespace, 0);
00099 ncontext = sepgsql_compute_create(scontext, tcontext,
00100 SEPG_CLASS_DB_PROCEDURE,
00101 NameStr(proForm->proname));
00102
00103
00104
00105
00106 initStringInfo(&audit_name);
00107 nsp_name = get_namespace_name(proForm->pronamespace);
00108 appendStringInfo(&audit_name, "%s(",
00109 quote_qualified_identifier(nsp_name, NameStr(proForm->proname)));
00110 for (i = 0; i < proForm->pronargs; i++)
00111 {
00112 if (i > 0)
00113 appendStringInfoChar(&audit_name, ',');
00114
00115 object.classId = TypeRelationId;
00116 object.objectId = proForm->proargtypes.values[i];
00117 object.objectSubId = 0;
00118 appendStringInfoString(&audit_name, getObjectIdentity(&object));
00119 }
00120 appendStringInfoChar(&audit_name, ')');
00121
00122 required = SEPG_DB_PROCEDURE__CREATE;
00123 if (proForm->proleakproof)
00124 required |= SEPG_DB_PROCEDURE__INSTALL;
00125
00126 sepgsql_avc_check_perms_label(ncontext,
00127 SEPG_CLASS_DB_PROCEDURE,
00128 required,
00129 audit_name.data,
00130 true);
00131
00132
00133
00134
00135 object.classId = ProcedureRelationId;
00136 object.objectId = functionId;
00137 object.objectSubId = 0;
00138 SetSecurityLabel(&object, SEPGSQL_LABEL_TAG, ncontext);
00139
00140
00141
00142
00143 systable_endscan(sscan);
00144 heap_close(rel, AccessShareLock);
00145
00146 pfree(audit_name.data);
00147 pfree(tcontext);
00148 pfree(ncontext);
00149 }
00150
00151
00152
00153
00154
00155
00156 void
00157 sepgsql_proc_drop(Oid functionId)
00158 {
00159 ObjectAddress object;
00160 char *audit_name;
00161
00162
00163
00164
00165 object.classId = NamespaceRelationId;
00166 object.objectId = get_func_namespace(functionId);
00167 object.objectSubId = 0;
00168 audit_name = getObjectIdentity(&object);
00169
00170 sepgsql_avc_check_perms(&object,
00171 SEPG_CLASS_DB_SCHEMA,
00172 SEPG_DB_SCHEMA__REMOVE_NAME,
00173 audit_name,
00174 true);
00175 pfree(audit_name);
00176
00177
00178
00179
00180 object.classId = ProcedureRelationId;
00181 object.objectId = functionId;
00182 object.objectSubId = 0;
00183 audit_name = getObjectIdentity(&object);
00184
00185 sepgsql_avc_check_perms(&object,
00186 SEPG_CLASS_DB_PROCEDURE,
00187 SEPG_DB_PROCEDURE__DROP,
00188 audit_name,
00189 true);
00190 pfree(audit_name);
00191 }
00192
00193
00194
00195
00196
00197
00198
00199 void
00200 sepgsql_proc_relabel(Oid functionId, const char *seclabel)
00201 {
00202 ObjectAddress object;
00203 char *audit_name;
00204
00205 object.classId = ProcedureRelationId;
00206 object.objectId = functionId;
00207 object.objectSubId = 0;
00208 audit_name = getObjectIdentity(&object);
00209
00210
00211
00212
00213 sepgsql_avc_check_perms(&object,
00214 SEPG_CLASS_DB_PROCEDURE,
00215 SEPG_DB_PROCEDURE__SETATTR |
00216 SEPG_DB_PROCEDURE__RELABELFROM,
00217 audit_name,
00218 true);
00219
00220
00221
00222
00223 sepgsql_avc_check_perms_label(seclabel,
00224 SEPG_CLASS_DB_PROCEDURE,
00225 SEPG_DB_PROCEDURE__RELABELTO,
00226 audit_name,
00227 true);
00228 pfree(audit_name);
00229 }
00230
00231
00232
00233
00234
00235
00236 void
00237 sepgsql_proc_setattr(Oid functionId)
00238 {
00239 Relation rel;
00240 ScanKeyData skey;
00241 SysScanDesc sscan;
00242 HeapTuple oldtup;
00243 HeapTuple newtup;
00244 Form_pg_proc oldform;
00245 Form_pg_proc newform;
00246 uint32 required;
00247 ObjectAddress object;
00248 char *audit_name;
00249
00250
00251
00252
00253 rel = heap_open(ProcedureRelationId, AccessShareLock);
00254
00255 ScanKeyInit(&skey,
00256 ObjectIdAttributeNumber,
00257 BTEqualStrategyNumber, F_OIDEQ,
00258 ObjectIdGetDatum(functionId));
00259
00260 sscan = systable_beginscan(rel, ProcedureOidIndexId, true,
00261 SnapshotSelf, 1, &skey);
00262 newtup = systable_getnext(sscan);
00263 if (!HeapTupleIsValid(newtup))
00264 elog(ERROR, "catalog lookup failed for function %u", functionId);
00265 newform = (Form_pg_proc) GETSTRUCT(newtup);
00266
00267
00268
00269
00270 oldtup = SearchSysCache1(PROCOID, ObjectIdGetDatum(functionId));
00271 if (!HeapTupleIsValid(oldtup))
00272 elog(ERROR, "cache lookup failed for function %u", functionId);
00273 oldform = (Form_pg_proc) GETSTRUCT(oldtup);
00274
00275
00276
00277
00278 if (newform->pronamespace != oldform->pronamespace)
00279 {
00280 sepgsql_schema_remove_name(oldform->pronamespace);
00281 sepgsql_schema_add_name(oldform->pronamespace);
00282 }
00283 if (strcmp(NameStr(newform->proname), NameStr(oldform->proname)) != 0)
00284 sepgsql_schema_rename(oldform->pronamespace);
00285
00286
00287
00288
00289 required = SEPG_DB_PROCEDURE__SETATTR;
00290 if (!oldform->proleakproof && newform->proleakproof)
00291 required |= SEPG_DB_PROCEDURE__INSTALL;
00292
00293 object.classId = ProcedureRelationId;
00294 object.objectId = functionId;
00295 object.objectSubId = 0;
00296 audit_name = getObjectIdentity(&object);
00297
00298 sepgsql_avc_check_perms(&object,
00299 SEPG_CLASS_DB_PROCEDURE,
00300 required,
00301 audit_name,
00302 true);
00303
00304 pfree(audit_name);
00305
00306 ReleaseSysCache(oldtup);
00307 systable_endscan(sscan);
00308 heap_close(rel, AccessShareLock);
00309 }
00310
00311
00312
00313
00314
00315
00316 void
00317 sepgsql_proc_execute(Oid functionId)
00318 {
00319 ObjectAddress object;
00320 char *audit_name;
00321
00322
00323
00324
00325 object.classId = ProcedureRelationId;
00326 object.objectId = functionId;
00327 object.objectSubId = 0;
00328 audit_name = getObjectIdentity(&object);
00329 sepgsql_avc_check_perms(&object,
00330 SEPG_CLASS_DB_PROCEDURE,
00331 SEPG_DB_PROCEDURE__EXECUTE,
00332 audit_name,
00333 true);
00334 pfree(audit_name);
00335 }