如何防止数据库链接到 Oracle 中的同一数据库

问题描述

我的主要目标是编写一个 PLsql 程序来在给定主机、端口、服务、用户名和密码时创建数据库链接。在那里我需要阻止创建到同一数据库数据库链接。 如何阻止创建指向同一数据库数据库链接,以便通知用户不允许数据库链接到同一数据库

解决方法

确保您提供的主机和服务名称与您正在运行的数据库不同。您可以从“USERENV”命名空间中的 SYS_CONTEXT function 获取此信息:

SELECT SYS_CONTEXT('USERENV','SERVICE_NAME') AS SERVICE_NAME,SYS_CONTEXT('USERENV','SERVER_HOST') AS SERVER_HOST
  FROM DUAL

例如,您的程序可能如下所示:

CREATE OR REPLACE PROCEDURE CREATE_DB_LINK(pinHost     IN VARCHAR2,pinPort     IN NUMBER,pinService  IN VARCHAR2,pinUsername IN VARCHAR2,pinPassword IN VARCHAR2)
AS
  strHost      VARCHAR2(100);
  strService   VARCHAR2(100);
BEGIN
  SELECT SYS_CONTEXT('USERENV','SERVICE_NAME'),'SERVER_HOST')
    INTO strService,strHost
    FROM DUAL;

  IF pinHost = strHost AND
     pinService = strService
  THEN
    RAISE_APPLICATION_ERROR(-20001,'Cannot create link to current DB');
  END IF;

  -- rest of code
END CREATE_DB_LINK;
,

因为它是您编写的过程,所以将check包含在其中。

例如,存储应该排除在表中的数据库列表(这样您就不必将它们的名称硬编码到过程中)。然后检查数据库 - 您将其参数作为参数 - 是否被列入黑名单。如果是,请通知用户无法创建数据库链接。

怎么样?通过过程的 OUT 参数或 RAISE_APPLICATION_ERROR

,

在创建数据库链接的过程中,在实际创建数据库链接之前,您可以让它检查这些视图之一。

  • DBA_DB_LINKS - 数据库中定义的所有数据库链接
  • ALL_DB_LINKS - 当前用户有权访问的所有数据库链接
  • USER_DB_LINKS - 当前用户拥有的所有数据库链接

如果链接已存在于其中一个视图中,要么引发错误,要么不再创建它。

,

您的方法有一个致命的缺陷:任何使用默认调用者权限运行此过程的人都必须获得授予他们的 CREATE DATABASE LINK 特权才能使该过程工作。这将允许他们直接创建链接并完全绕过您的程序。

或者,如果该过程被创建为使用所有者的权限而不是默认调用者的权限运行,那么它要么在另一个模式中创建一个数据库链接,用户无论如何都无法访问它,或者您将有要创建公共 数据库链接 - 通常不应使用,而应该只由 DBA 创建。期间。

简而言之,整个概念存在缺陷,无法按照您的描述实施。用户要么忽略你的程序,和/或它会造成安全噩梦。总的来说,我同意 @EdStevens 和 @MarmiteBomber 早先的评论,即数据库链接应该只由 DBA 创建。我什至更进一步,建议应该通过使用 API 模式中的本地视图和同义词来访问链接,而永远不要由用户直接访问。

访问数据库链接打开了一个关于大多数用户不应该访问的远程数据库信息的世界(比如 ALL_USERS 来获取系统上每个有效用户帐户的列表),并且应该永远是一个正式的、版本控制的数据模式的一部分。使用 API 通过链接拉取数据可以防止用户直接查询远程数据字典,增强了两个系统的安全性。