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.

database.c 5.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217
  1. /* -------------------------------------------------------------------------
  2. *
  3. * contrib/sepgsql/database.c
  4. *
  5. * Routines corresponding to database 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/pg_database.h"
  18. #include "catalog/indexing.h"
  19. #include "commands/dbcommands.h"
  20. #include "commands/seclabel.h"
  21. #include "utils/builtins.h"
  22. #include "utils/fmgroids.h"
  23. #include "utils/tqual.h"
  24. #include "sepgsql.h"
  25. /*
  26. * sepgsql_database_post_create
  27. *
  28. * This routine assigns a default security label on a newly defined
  29. * database, and check permission needed for its creation.
  30. */
  31. void
  32. sepgsql_database_post_create(Oid databaseId, const char *dtemplate)
  33. {
  34. Relation rel;
  35. ScanKeyData skey;
  36. SysScanDesc sscan;
  37. HeapTuple tuple;
  38. char *tcontext;
  39. char *ncontext;
  40. ObjectAddress object;
  41. Form_pg_database datForm;
  42. StringInfoData audit_name;
  43. /*
  44. * Oid of the source database is not saved in pg_database catalog, so we
  45. * collect its identifier using contextual information. If NULL, its
  46. * default is "template1" according to createdb().
  47. */
  48. if (!dtemplate)
  49. dtemplate = "template1";
  50. object.classId = DatabaseRelationId;
  51. object.objectId = get_database_oid(dtemplate, false);
  52. object.objectSubId = 0;
  53. tcontext = sepgsql_get_label(object.classId,
  54. object.objectId,
  55. object.objectSubId);
  56. /*
  57. * check db_database:{getattr} permission
  58. */
  59. initStringInfo(&audit_name);
  60. appendStringInfo(&audit_name, "%s", quote_identifier(dtemplate));
  61. sepgsql_avc_check_perms_label(tcontext,
  62. SEPG_CLASS_DB_DATABASE,
  63. SEPG_DB_DATABASE__GETATTR,
  64. audit_name.data,
  65. true);
  66. /*
  67. * Compute a default security label of the newly created database based on
  68. * a pair of security label of client and source database.
  69. *
  70. * XXX - uncoming version of libselinux supports to take object name to
  71. * handle special treatment on default security label.
  72. */
  73. rel = heap_open(DatabaseRelationId, AccessShareLock);
  74. ScanKeyInit(&skey,
  75. Anum_pg_database_oid,
  76. BTEqualStrategyNumber, F_OIDEQ,
  77. ObjectIdGetDatum(databaseId));
  78. sscan = systable_beginscan(rel, DatabaseOidIndexId, true,
  79. SnapshotSelf, 1, &skey);
  80. tuple = systable_getnext(sscan);
  81. if (!HeapTupleIsValid(tuple))
  82. elog(ERROR, "could not find tuple for database %u", databaseId);
  83. datForm = (Form_pg_database) GETSTRUCT(tuple);
  84. ncontext = sepgsql_compute_create(sepgsql_get_client_label(),
  85. tcontext,
  86. SEPG_CLASS_DB_DATABASE,
  87. NameStr(datForm->datname));
  88. /*
  89. * check db_database:{create} permission
  90. */
  91. resetStringInfo(&audit_name);
  92. appendStringInfo(&audit_name, "%s",
  93. quote_identifier(NameStr(datForm->datname)));
  94. sepgsql_avc_check_perms_label(ncontext,
  95. SEPG_CLASS_DB_DATABASE,
  96. SEPG_DB_DATABASE__CREATE,
  97. audit_name.data,
  98. true);
  99. systable_endscan(sscan);
  100. heap_close(rel, AccessShareLock);
  101. /*
  102. * Assign the default security label on the new database
  103. */
  104. object.classId = DatabaseRelationId;
  105. object.objectId = databaseId;
  106. object.objectSubId = 0;
  107. SetSecurityLabel(&object, SEPGSQL_LABEL_TAG, ncontext);
  108. pfree(ncontext);
  109. pfree(tcontext);
  110. }
  111. /*
  112. * sepgsql_database_drop
  113. *
  114. * It checks privileges to drop the supplied database
  115. */
  116. void
  117. sepgsql_database_drop(Oid databaseId)
  118. {
  119. ObjectAddress object;
  120. char *audit_name;
  121. /*
  122. * check db_database:{drop} permission
  123. */
  124. object.classId = DatabaseRelationId;
  125. object.objectId = databaseId;
  126. object.objectSubId = 0;
  127. audit_name = getObjectIdentity(&object);
  128. sepgsql_avc_check_perms(&object,
  129. SEPG_CLASS_DB_DATABASE,
  130. SEPG_DB_DATABASE__DROP,
  131. audit_name,
  132. true);
  133. pfree(audit_name);
  134. }
  135. /*
  136. * sepgsql_database_post_alter
  137. *
  138. * It checks privileges to alter the supplied database
  139. */
  140. void
  141. sepgsql_database_setattr(Oid databaseId)
  142. {
  143. ObjectAddress object;
  144. char *audit_name;
  145. /*
  146. * check db_database:{setattr} permission
  147. */
  148. object.classId = DatabaseRelationId;
  149. object.objectId = databaseId;
  150. object.objectSubId = 0;
  151. audit_name = getObjectIdentity(&object);
  152. sepgsql_avc_check_perms(&object,
  153. SEPG_CLASS_DB_DATABASE,
  154. SEPG_DB_DATABASE__SETATTR,
  155. audit_name,
  156. true);
  157. pfree(audit_name);
  158. }
  159. /*
  160. * sepgsql_database_relabel
  161. *
  162. * It checks privileges to relabel the supplied database with the `seclabel'
  163. */
  164. void
  165. sepgsql_database_relabel(Oid databaseId, const char *seclabel)
  166. {
  167. ObjectAddress object;
  168. char *audit_name;
  169. object.classId = DatabaseRelationId;
  170. object.objectId = databaseId;
  171. object.objectSubId = 0;
  172. audit_name = getObjectIdentity(&object);
  173. /*
  174. * check db_database:{setattr relabelfrom} permission
  175. */
  176. sepgsql_avc_check_perms(&object,
  177. SEPG_CLASS_DB_DATABASE,
  178. SEPG_DB_DATABASE__SETATTR |
  179. SEPG_DB_DATABASE__RELABELFROM,
  180. audit_name,
  181. true);
  182. /*
  183. * check db_database:{relabelto} permission
  184. */
  185. sepgsql_avc_check_perms_label(seclabel,
  186. SEPG_CLASS_DB_DATABASE,
  187. SEPG_DB_DATABASE__RELABELTO,
  188. audit_name,
  189. true);
  190. pfree(audit_name);
  191. }