You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

schema.c 5.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237
  1. /* -------------------------------------------------------------------------
  2. *
  3. * contrib/sepgsql/schema.c
  4. *
  5. * Routines corresponding to schema objects
  6. *
  7. * Copyright (c) 2010-2019, PostgreSQL Global Development Group
  8. *
  9. * -------------------------------------------------------------------------
  10. */
  11. #include "postgres.h"
  12. #include "access/genam.h"
  13. #include "access/heapam.h"
  14. #include "access/htup_details.h"
  15. #include "access/sysattr.h"
  16. #include "catalog/dependency.h"
  17. #include "catalog/indexing.h"
  18. #include "catalog/pg_database.h"
  19. #include "catalog/pg_namespace.h"
  20. #include "commands/seclabel.h"
  21. #include "lib/stringinfo.h"
  22. #include "miscadmin.h"
  23. #include "utils/builtins.h"
  24. #include "utils/fmgroids.h"
  25. #include "utils/lsyscache.h"
  26. #include "utils/tqual.h"
  27. #include "sepgsql.h"
  28. /*
  29. * sepgsql_schema_post_create
  30. *
  31. * This routine assigns a default security label on a newly defined
  32. * schema.
  33. */
  34. void
  35. sepgsql_schema_post_create(Oid namespaceId)
  36. {
  37. Relation rel;
  38. ScanKeyData skey;
  39. SysScanDesc sscan;
  40. HeapTuple tuple;
  41. char *tcontext;
  42. char *ncontext;
  43. const char *nsp_name;
  44. ObjectAddress object;
  45. Form_pg_namespace nspForm;
  46. StringInfoData audit_name;
  47. /*
  48. * Compute a default security label when we create a new schema object
  49. * under the working database.
  50. *
  51. * XXX - uncoming version of libselinux supports to take object name to
  52. * handle special treatment on default security label; such as special
  53. * label on "pg_temp" schema.
  54. */
  55. rel = heap_open(NamespaceRelationId, AccessShareLock);
  56. ScanKeyInit(&skey,
  57. Anum_pg_namespace_oid,
  58. BTEqualStrategyNumber, F_OIDEQ,
  59. ObjectIdGetDatum(namespaceId));
  60. sscan = systable_beginscan(rel, NamespaceOidIndexId, true,
  61. SnapshotSelf, 1, &skey);
  62. tuple = systable_getnext(sscan);
  63. if (!HeapTupleIsValid(tuple))
  64. elog(ERROR, "could not find tuple for namespace %u", namespaceId);
  65. nspForm = (Form_pg_namespace) GETSTRUCT(tuple);
  66. nsp_name = NameStr(nspForm->nspname);
  67. if (strncmp(nsp_name, "pg_temp_", 8) == 0)
  68. nsp_name = "pg_temp";
  69. else if (strncmp(nsp_name, "pg_toast_temp_", 14) == 0)
  70. nsp_name = "pg_toast_temp";
  71. tcontext = sepgsql_get_label(DatabaseRelationId, MyDatabaseId, 0);
  72. ncontext = sepgsql_compute_create(sepgsql_get_client_label(),
  73. tcontext,
  74. SEPG_CLASS_DB_SCHEMA,
  75. nsp_name);
  76. /*
  77. * check db_schema:{create}
  78. */
  79. initStringInfo(&audit_name);
  80. appendStringInfo(&audit_name, "%s", quote_identifier(nsp_name));
  81. sepgsql_avc_check_perms_label(ncontext,
  82. SEPG_CLASS_DB_SCHEMA,
  83. SEPG_DB_SCHEMA__CREATE,
  84. audit_name.data,
  85. true);
  86. systable_endscan(sscan);
  87. heap_close(rel, AccessShareLock);
  88. /*
  89. * Assign the default security label on a new procedure
  90. */
  91. object.classId = NamespaceRelationId;
  92. object.objectId = namespaceId;
  93. object.objectSubId = 0;
  94. SetSecurityLabel(&object, SEPGSQL_LABEL_TAG, ncontext);
  95. pfree(ncontext);
  96. pfree(tcontext);
  97. }
  98. /*
  99. * sepgsql_schema_drop
  100. *
  101. * It checks privileges to drop the supplied schema object.
  102. */
  103. void
  104. sepgsql_schema_drop(Oid namespaceId)
  105. {
  106. ObjectAddress object;
  107. char *audit_name;
  108. /*
  109. * check db_schema:{drop} permission
  110. */
  111. object.classId = NamespaceRelationId;
  112. object.objectId = namespaceId;
  113. object.objectSubId = 0;
  114. audit_name = getObjectIdentity(&object);
  115. sepgsql_avc_check_perms(&object,
  116. SEPG_CLASS_DB_SCHEMA,
  117. SEPG_DB_SCHEMA__DROP,
  118. audit_name,
  119. true);
  120. pfree(audit_name);
  121. }
  122. /*
  123. * sepgsql_schema_relabel
  124. *
  125. * It checks privileges to relabel the supplied schema
  126. * by the `seclabel'.
  127. */
  128. void
  129. sepgsql_schema_relabel(Oid namespaceId, const char *seclabel)
  130. {
  131. ObjectAddress object;
  132. char *audit_name;
  133. object.classId = NamespaceRelationId;
  134. object.objectId = namespaceId;
  135. object.objectSubId = 0;
  136. audit_name = getObjectIdentity(&object);
  137. /*
  138. * check db_schema:{setattr relabelfrom} permission
  139. */
  140. sepgsql_avc_check_perms(&object,
  141. SEPG_CLASS_DB_SCHEMA,
  142. SEPG_DB_SCHEMA__SETATTR |
  143. SEPG_DB_SCHEMA__RELABELFROM,
  144. audit_name,
  145. true);
  146. /*
  147. * check db_schema:{relabelto} permission
  148. */
  149. sepgsql_avc_check_perms_label(seclabel,
  150. SEPG_CLASS_DB_SCHEMA,
  151. SEPG_DB_SCHEMA__RELABELTO,
  152. audit_name,
  153. true);
  154. pfree(audit_name);
  155. }
  156. /*
  157. * sepgsql_schema_check_perms
  158. *
  159. * utility routine to check db_schema:{xxx} permissions
  160. */
  161. static bool
  162. check_schema_perms(Oid namespaceId, uint32 required, bool abort_on_violation)
  163. {
  164. ObjectAddress object;
  165. char *audit_name;
  166. bool result;
  167. object.classId = NamespaceRelationId;
  168. object.objectId = namespaceId;
  169. object.objectSubId = 0;
  170. audit_name = getObjectIdentity(&object);
  171. result = sepgsql_avc_check_perms(&object,
  172. SEPG_CLASS_DB_SCHEMA,
  173. required,
  174. audit_name,
  175. abort_on_violation);
  176. pfree(audit_name);
  177. return result;
  178. }
  179. /* db_schema:{setattr} permission */
  180. void
  181. sepgsql_schema_setattr(Oid namespaceId)
  182. {
  183. check_schema_perms(namespaceId, SEPG_DB_SCHEMA__SETATTR, true);
  184. }
  185. /* db_schema:{search} permission */
  186. bool
  187. sepgsql_schema_search(Oid namespaceId, bool abort_on_violation)
  188. {
  189. return check_schema_perms(namespaceId,
  190. SEPG_DB_SCHEMA__SEARCH,
  191. abort_on_violation);
  192. }
  193. void
  194. sepgsql_schema_add_name(Oid namespaceId)
  195. {
  196. check_schema_perms(namespaceId, SEPG_DB_SCHEMA__ADD_NAME, true);
  197. }
  198. void
  199. sepgsql_schema_remove_name(Oid namespaceId)
  200. {
  201. check_schema_perms(namespaceId, SEPG_DB_SCHEMA__REMOVE_NAME, true);
  202. }
  203. void
  204. sepgsql_schema_rename(Oid namespaceId)
  205. {
  206. check_schema_perms(namespaceId,
  207. SEPG_DB_SCHEMA__ADD_NAME |
  208. SEPG_DB_SCHEMA__REMOVE_NAME,
  209. true);
  210. }