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_database.h"
00020 #include "catalog/pg_namespace.h"
00021 #include "commands/seclabel.h"
00022 #include "lib/stringinfo.h"
00023 #include "miscadmin.h"
00024 #include "utils/builtins.h"
00025 #include "utils/fmgroids.h"
00026 #include "utils/lsyscache.h"
00027 #include "utils/tqual.h"
00028
00029 #include "sepgsql.h"
00030
00031
00032
00033
00034
00035
00036
00037 void
00038 sepgsql_schema_post_create(Oid namespaceId)
00039 {
00040 Relation rel;
00041 ScanKeyData skey;
00042 SysScanDesc sscan;
00043 HeapTuple tuple;
00044 char *tcontext;
00045 char *ncontext;
00046 const char *nsp_name;
00047 ObjectAddress object;
00048 Form_pg_namespace nspForm;
00049 StringInfoData audit_name;
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059 rel = heap_open(NamespaceRelationId, AccessShareLock);
00060
00061 ScanKeyInit(&skey,
00062 ObjectIdAttributeNumber,
00063 BTEqualStrategyNumber, F_OIDEQ,
00064 ObjectIdGetDatum(namespaceId));
00065
00066 sscan = systable_beginscan(rel, NamespaceOidIndexId, true,
00067 SnapshotSelf, 1, &skey);
00068 tuple = systable_getnext(sscan);
00069 if (!HeapTupleIsValid(tuple))
00070 elog(ERROR, "catalog lookup failed for namespace %u", namespaceId);
00071
00072 nspForm = (Form_pg_namespace) GETSTRUCT(tuple);
00073 nsp_name = NameStr(nspForm->nspname);
00074 if (strncmp(nsp_name, "pg_temp_", 8) == 0)
00075 nsp_name = "pg_temp";
00076 else if (strncmp(nsp_name, "pg_toast_temp_", 14) == 0)
00077 nsp_name = "pg_toast_temp";
00078
00079 tcontext = sepgsql_get_label(DatabaseRelationId, MyDatabaseId, 0);
00080 ncontext = sepgsql_compute_create(sepgsql_get_client_label(),
00081 tcontext,
00082 SEPG_CLASS_DB_SCHEMA,
00083 nsp_name);
00084
00085
00086
00087 initStringInfo(&audit_name);
00088 appendStringInfo(&audit_name, "%s", quote_identifier(nsp_name));
00089 sepgsql_avc_check_perms_label(ncontext,
00090 SEPG_CLASS_DB_SCHEMA,
00091 SEPG_DB_SCHEMA__CREATE,
00092 audit_name.data,
00093 true);
00094 systable_endscan(sscan);
00095 heap_close(rel, AccessShareLock);
00096
00097
00098
00099
00100 object.classId = NamespaceRelationId;
00101 object.objectId = namespaceId;
00102 object.objectSubId = 0;
00103 SetSecurityLabel(&object, SEPGSQL_LABEL_TAG, ncontext);
00104
00105 pfree(ncontext);
00106 pfree(tcontext);
00107 }
00108
00109
00110
00111
00112
00113
00114 void
00115 sepgsql_schema_drop(Oid namespaceId)
00116 {
00117 ObjectAddress object;
00118 char *audit_name;
00119
00120
00121
00122
00123 object.classId = NamespaceRelationId;
00124 object.objectId = namespaceId;
00125 object.objectSubId = 0;
00126 audit_name = getObjectIdentity(&object);
00127
00128 sepgsql_avc_check_perms(&object,
00129 SEPG_CLASS_DB_SCHEMA,
00130 SEPG_DB_SCHEMA__DROP,
00131 audit_name,
00132 true);
00133 pfree(audit_name);
00134 }
00135
00136
00137
00138
00139
00140
00141
00142 void
00143 sepgsql_schema_relabel(Oid namespaceId, const char *seclabel)
00144 {
00145 ObjectAddress object;
00146 char *audit_name;
00147
00148 object.classId = NamespaceRelationId;
00149 object.objectId = namespaceId;
00150 object.objectSubId = 0;
00151 audit_name = getObjectIdentity(&object);
00152
00153
00154
00155
00156 sepgsql_avc_check_perms(&object,
00157 SEPG_CLASS_DB_SCHEMA,
00158 SEPG_DB_SCHEMA__SETATTR |
00159 SEPG_DB_SCHEMA__RELABELFROM,
00160 audit_name,
00161 true);
00162
00163
00164
00165
00166 sepgsql_avc_check_perms_label(seclabel,
00167 SEPG_CLASS_DB_SCHEMA,
00168 SEPG_DB_SCHEMA__RELABELTO,
00169 audit_name,
00170 true);
00171 pfree(audit_name);
00172 }
00173
00174
00175
00176
00177
00178
00179 static bool
00180 check_schema_perms(Oid namespaceId, uint32 required, bool abort_on_violation)
00181 {
00182 ObjectAddress object;
00183 char *audit_name;
00184 bool result;
00185
00186 object.classId = NamespaceRelationId;
00187 object.objectId = namespaceId;
00188 object.objectSubId = 0;
00189 audit_name = getObjectIdentity(&object);
00190
00191 result = sepgsql_avc_check_perms(&object,
00192 SEPG_CLASS_DB_SCHEMA,
00193 required,
00194 audit_name,
00195 abort_on_violation);
00196 pfree(audit_name);
00197
00198 return result;
00199 }
00200
00201
00202 void
00203 sepgsql_schema_setattr(Oid namespaceId)
00204 {
00205 check_schema_perms(namespaceId, SEPG_DB_SCHEMA__SETATTR, true);
00206 }
00207
00208
00209 bool
00210 sepgsql_schema_search(Oid namespaceId, bool abort_on_violation)
00211 {
00212 return check_schema_perms(namespaceId,
00213 SEPG_DB_SCHEMA__SEARCH,
00214 abort_on_violation);
00215 }
00216
00217 void
00218 sepgsql_schema_add_name(Oid namespaceId)
00219 {
00220 check_schema_perms(namespaceId, SEPG_DB_SCHEMA__ADD_NAME, true);
00221 }
00222
00223 void
00224 sepgsql_schema_remove_name(Oid namespaceId)
00225 {
00226 check_schema_perms(namespaceId, SEPG_DB_SCHEMA__REMOVE_NAME, true);
00227 }
00228
00229 void
00230 sepgsql_schema_rename(Oid namespaceId)
00231 {
00232 check_schema_perms(namespaceId,
00233 SEPG_DB_SCHEMA__ADD_NAME |
00234 SEPG_DB_SCHEMA__REMOVE_NAME,
00235 true);
00236 }