Header And Logo

PostgreSQL
| The world's most advanced open source database.

database.c

Go to the documentation of this file.
00001 /* -------------------------------------------------------------------------
00002  *
00003  * contrib/sepgsql/database.c
00004  *
00005  * Routines corresponding to database objects
00006  *
00007  * Copyright (c) 2010-2013, PostgreSQL Global Development Group
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/pg_database.h"
00019 #include "catalog/indexing.h"
00020 #include "commands/dbcommands.h"
00021 #include "commands/seclabel.h"
00022 #include "utils/builtins.h"
00023 #include "utils/fmgroids.h"
00024 #include "utils/tqual.h"
00025 #include "sepgsql.h"
00026 
00027 /*
00028  * sepgsql_database_post_create
00029  *
00030  * This routine assigns a default security label on a newly defined
00031  * database, and check permission needed for its creation.
00032  */
00033 void
00034 sepgsql_database_post_create(Oid databaseId, const char *dtemplate)
00035 {
00036     Relation    rel;
00037     ScanKeyData skey;
00038     SysScanDesc sscan;
00039     HeapTuple   tuple;
00040     char       *tcontext;
00041     char       *ncontext;
00042     ObjectAddress object;
00043     Form_pg_database datForm;
00044     StringInfoData audit_name;
00045 
00046     /*
00047      * Oid of the source database is not saved in pg_database catalog, so we
00048      * collect its identifier using contextual information. If NULL, its
00049      * default is "template1" according to createdb().
00050      */
00051     if (!dtemplate)
00052         dtemplate = "template1";
00053 
00054     object.classId = DatabaseRelationId;
00055     object.objectId = get_database_oid(dtemplate, false);
00056     object.objectSubId = 0;
00057 
00058     tcontext = sepgsql_get_label(object.classId,
00059                                  object.objectId,
00060                                  object.objectSubId);
00061 
00062     /*
00063      * check db_database:{getattr} permission
00064      */
00065     initStringInfo(&audit_name);
00066     appendStringInfo(&audit_name, "%s", quote_identifier(dtemplate));
00067     sepgsql_avc_check_perms_label(tcontext,
00068                                   SEPG_CLASS_DB_DATABASE,
00069                                   SEPG_DB_DATABASE__GETATTR,
00070                                   audit_name.data,
00071                                   true);
00072 
00073     /*
00074      * Compute a default security label of the newly created database based on
00075      * a pair of security label of client and source database.
00076      *
00077      * XXX - uncoming version of libselinux supports to take object name to
00078      * handle special treatment on default security label.
00079      */
00080     rel = heap_open(DatabaseRelationId, AccessShareLock);
00081 
00082     ScanKeyInit(&skey,
00083                 ObjectIdAttributeNumber,
00084                 BTEqualStrategyNumber, F_OIDEQ,
00085                 ObjectIdGetDatum(databaseId));
00086 
00087     sscan = systable_beginscan(rel, DatabaseOidIndexId, true,
00088                                SnapshotSelf, 1, &skey);
00089     tuple = systable_getnext(sscan);
00090     if (!HeapTupleIsValid(tuple))
00091         elog(ERROR, "catalog lookup failed for database %u", databaseId);
00092 
00093     datForm = (Form_pg_database) GETSTRUCT(tuple);
00094 
00095     ncontext = sepgsql_compute_create(sepgsql_get_client_label(),
00096                                       tcontext,
00097                                       SEPG_CLASS_DB_DATABASE,
00098                                       NameStr(datForm->datname));
00099 
00100     /*
00101      * check db_database:{create} permission
00102      */
00103     resetStringInfo(&audit_name);
00104     appendStringInfo(&audit_name, "%s",
00105                      quote_identifier(NameStr(datForm->datname)));
00106     sepgsql_avc_check_perms_label(ncontext,
00107                                   SEPG_CLASS_DB_DATABASE,
00108                                   SEPG_DB_DATABASE__CREATE,
00109                                   audit_name.data,
00110                                   true);
00111 
00112     systable_endscan(sscan);
00113     heap_close(rel, AccessShareLock);
00114 
00115     /*
00116      * Assign the default security label on the new database
00117      */
00118     object.classId = DatabaseRelationId;
00119     object.objectId = databaseId;
00120     object.objectSubId = 0;
00121 
00122     SetSecurityLabel(&object, SEPGSQL_LABEL_TAG, ncontext);
00123 
00124     pfree(ncontext);
00125     pfree(tcontext);
00126 }
00127 
00128 /*
00129  * sepgsql_database_drop
00130  *
00131  * It checks privileges to drop the supplied database
00132  */
00133 void
00134 sepgsql_database_drop(Oid databaseId)
00135 {
00136     ObjectAddress object;
00137     char       *audit_name;
00138 
00139     /*
00140      * check db_database:{drop} permission
00141      */
00142     object.classId = DatabaseRelationId;
00143     object.objectId = databaseId;
00144     object.objectSubId = 0;
00145     audit_name = getObjectIdentity(&object);
00146 
00147     sepgsql_avc_check_perms(&object,
00148                             SEPG_CLASS_DB_DATABASE,
00149                             SEPG_DB_DATABASE__DROP,
00150                             audit_name,
00151                             true);
00152     pfree(audit_name);
00153 }
00154 
00155 /*
00156  * sepgsql_database_post_alter
00157  *
00158  * It checks privileges to alter the supplied database
00159  */
00160 void
00161 sepgsql_database_setattr(Oid databaseId)
00162 {
00163     ObjectAddress object;
00164     char       *audit_name;
00165 
00166     /*
00167      * check db_database:{setattr} permission
00168      */
00169     object.classId = DatabaseRelationId;
00170     object.objectId = databaseId;
00171     object.objectSubId = 0;
00172     audit_name = getObjectIdentity(&object);
00173 
00174     sepgsql_avc_check_perms(&object,
00175                             SEPG_CLASS_DB_DATABASE,
00176                             SEPG_DB_DATABASE__SETATTR,
00177                             audit_name,
00178                             true);
00179     pfree(audit_name);
00180 }
00181 
00182 /*
00183  * sepgsql_database_relabel
00184  *
00185  * It checks privileges to relabel the supplied database with the `seclabel'
00186  */
00187 void
00188 sepgsql_database_relabel(Oid databaseId, const char *seclabel)
00189 {
00190     ObjectAddress object;
00191     char       *audit_name;
00192 
00193     object.classId = DatabaseRelationId;
00194     object.objectId = databaseId;
00195     object.objectSubId = 0;
00196     audit_name = getObjectIdentity(&object);
00197 
00198     /*
00199      * check db_database:{setattr relabelfrom} permission
00200      */
00201     sepgsql_avc_check_perms(&object,
00202                             SEPG_CLASS_DB_DATABASE,
00203                             SEPG_DB_DATABASE__SETATTR |
00204                             SEPG_DB_DATABASE__RELABELFROM,
00205                             audit_name,
00206                             true);
00207 
00208     /*
00209      * check db_database:{relabelto} permission
00210      */
00211     sepgsql_avc_check_perms_label(seclabel,
00212                                   SEPG_CLASS_DB_DATABASE,
00213                                   SEPG_DB_DATABASE__RELABELTO,
00214                                   audit_name,
00215                                   true);
00216     pfree(audit_name);
00217 }