Example #1
0
/*
 * sepgsql_relation_setattr
 *
 * It checks privileges to set attribute of the supplied relation
 */
void
sepgsql_relation_setattr(Oid relOid)
{
	Relation	rel;
	ScanKeyData skey;
	SysScanDesc sscan;
	HeapTuple	oldtup;
	HeapTuple	newtup;
	Form_pg_class oldform;
	Form_pg_class newform;
	ObjectAddress object;
	char	   *audit_name;
	uint16_t	tclass;

	switch (get_rel_relkind(relOid))
	{
		case RELKIND_RELATION:
			tclass = SEPG_CLASS_DB_TABLE;
			break;
		case RELKIND_SEQUENCE:
			tclass = SEPG_CLASS_DB_SEQUENCE;
			break;
		case RELKIND_VIEW:
			tclass = SEPG_CLASS_DB_VIEW;
			break;
		case RELKIND_INDEX:
			/* deal with indexes specially */
			sepgsql_index_modify(relOid);
			return;
		default:
			/* other relkinds don't need additional work */
			return;
	}

	/*
	 * Fetch newer catalog
	 */
	rel = heap_open(RelationRelationId, AccessShareLock);

	ScanKeyInit(&skey,
				ObjectIdAttributeNumber,
				BTEqualStrategyNumber, F_OIDEQ,
				ObjectIdGetDatum(relOid));

	sscan = systable_beginscan(rel, ClassOidIndexId, true,
							   SnapshotSelf, 1, &skey);

	newtup = systable_getnext(sscan);
	if (!HeapTupleIsValid(newtup))
		elog(ERROR, "catalog lookup failed for relation %u", relOid);
	newform = (Form_pg_class) GETSTRUCT(newtup);

	/*
	 * Fetch older catalog
	 */
	oldtup = SearchSysCache1(RELOID, ObjectIdGetDatum(relOid));
	if (!HeapTupleIsValid(oldtup))
		elog(ERROR, "cache lookup failed for relation %u", relOid);
	oldform = (Form_pg_class) GETSTRUCT(oldtup);

	/*
	 * Does this ALTER command takes operation to namespace?
	 */
	if (newform->relnamespace != oldform->relnamespace)
	{
		sepgsql_schema_remove_name(oldform->relnamespace);
		sepgsql_schema_add_name(newform->relnamespace);
	}
	if (strcmp(NameStr(newform->relname), NameStr(oldform->relname)) != 0)
		sepgsql_schema_rename(oldform->relnamespace);

	/*
	 * XXX - In the future version, db_tuple:{use} of system catalog entry
	 * shall be checked, if tablespace configuration is changed.
	 */

	/*
	 * check db_xxx:{setattr} permission
	 */
	object.classId = RelationRelationId;
	object.objectId = relOid;
	object.objectSubId = 0;
	audit_name = getObjectIdentity(&object);

	sepgsql_avc_check_perms(&object,
							tclass,
							SEPG_DB_TABLE__SETATTR,
							audit_name,
							true);
	pfree(audit_name);

	ReleaseSysCache(oldtup);
	systable_endscan(sscan);
	heap_close(rel, AccessShareLock);
}
Example #2
0
/*
 * sepgsql_proc_setattr
 *
 * It checks privileges to alter the supplied function.
 */
void
sepgsql_proc_setattr(Oid functionId)
{
	Relation	rel;
	ScanKeyData skey;
	SysScanDesc sscan;
	HeapTuple	oldtup;
	HeapTuple	newtup;
	Form_pg_proc oldform;
	Form_pg_proc newform;
	uint32		required;
	ObjectAddress object;
	char	   *audit_name;

	/*
	 * Fetch newer catalog
	 */
	rel = heap_open(ProcedureRelationId, AccessShareLock);

	ScanKeyInit(&skey,
				ObjectIdAttributeNumber,
				BTEqualStrategyNumber, F_OIDEQ,
				ObjectIdGetDatum(functionId));

	sscan = systable_beginscan(rel, ProcedureOidIndexId, true,
							   SnapshotSelf, 1, &skey);
	newtup = systable_getnext(sscan);
	if (!HeapTupleIsValid(newtup))
		elog(ERROR, "catalog lookup failed for function %u", functionId);
	newform = (Form_pg_proc) GETSTRUCT(newtup);

	/*
	 * Fetch older catalog
	 */
	oldtup = SearchSysCache1(PROCOID, ObjectIdGetDatum(functionId));
	if (!HeapTupleIsValid(oldtup))
		elog(ERROR, "cache lookup failed for function %u", functionId);
	oldform = (Form_pg_proc) GETSTRUCT(oldtup);

	/*
	 * Does this ALTER command takes operation to namespace?
	 */
	if (newform->pronamespace != oldform->pronamespace)
	{
		sepgsql_schema_remove_name(oldform->pronamespace);
		sepgsql_schema_add_name(oldform->pronamespace);
	}
	if (strcmp(NameStr(newform->proname), NameStr(oldform->proname)) != 0)
		sepgsql_schema_rename(oldform->pronamespace);

	/*
	 * check db_procedure:{setattr (install)} permission
	 */
	required = SEPG_DB_PROCEDURE__SETATTR;
	if (!oldform->proleakproof && newform->proleakproof)
		required |= SEPG_DB_PROCEDURE__INSTALL;

	object.classId = ProcedureRelationId;
	object.objectId = functionId;
	object.objectSubId = 0;
	audit_name = getObjectIdentity(&object);

	sepgsql_avc_check_perms(&object,
							SEPG_CLASS_DB_PROCEDURE,
							required,
							audit_name,
							true);
	/* cleanups */
	pfree(audit_name);

	ReleaseSysCache(oldtup);
	systable_endscan(sscan);
	heap_close(rel, AccessShareLock);
}