DB2 UDB 安全模型主要包括两部分:身份验证(authentication) 和授权(authorization)。
身份验证
身份验证就是使用安全机制验证所提供用户 ID 和口令的过程。用户和组身份验证由 DB2 UDB 外部的设施管理,比如操作系统、域控制器或者 Kerberos 安全系统。这和其他数据库管理系统(DBMS)是不同的,如 Oracle 和 SQL Server,后者既可以在数据库本身中定义和验证用户帐户,也可在外部设施(如操作系统)中完成。
一旦用户 ID 和口令作为实例附件或数据库连接请求的一部分明确地提供给 DB2 UDB,DB2 UDB 就会尝试使用该外部安全设施验证用户 ID 和口令。如果请求中没有提供用户 ID 和口令,则 DB2 UDB 隐含使用登录到发出请求的工作站时所用的用户 ID 和口令。
实际的验证位置由 DB2 UDB 实例参数 AUTHENTICATION 的值决定。有不同的身份验证方案,包括让用户在 DB2 UDB 服务器上验证(使用服务器的安全设施)、在客户机上验证(允许 “单点登录” 访问)、使用 Kerberos 安全设施验证,或者用户定义的通用安全服务(Generic Security Service,GSS)插件验证。其他身份验证选项包括当用户名和口令以及数据在客户机和服务器之间的网络上传递时进行加密。为 AUTHENTICATION 参数选择的值依赖于具体环境和本地安全策略。关于各种身份验证方案的完整描述,请参阅 DB2 UDB 文档。
比如,连接语句供用户 bob 使用口令 bobpsw 连接到 finance 数据库。身份验证过程包括七个步骤:
CONNECT 语句传递给 DB2 UDB 服务器。
如果没有明确配置安全插件,则使用默认的安全插件。如果包含 finance 数据库的实例的 AUTHENTICATION 参数设为 SERVER(默认设置),连接请求中的用户 ID 和口令则由 DB2 UDB 服务器上的安全设施验证。默认插件将用户 ID 和口令发送给操作系统进行验证。操作系统确认bob/bobpsw 组合是否有效,把该信息返回给安全插件。安全插件激活 DB2 UDB 安全机制,对用户 bob 查询 DB2 UDB 目录表,看看该用户是否被授予了该数据库的 CONNECT 权限。默认情况下,CONNECT 特权被授予 PUBLIC,就是说任何通过身份验证的用户都能连接到数据库。DB2 UDB 安全机制验证用户 bob 或者返回错误。
安全插件把成功或者失败的消息返回给用户。如果用户没有通过身份验证,DB2 UDB 就会拒绝连接请求,并向客户机应用程序返回错误消息,如下所示:
清单 1. 用户身份验证失败时 DB2 UDB 返回应用程序的消息:
SQL30082N Attempt to establish connection failed with security
reason "24" ("USERNAME AND/OR PASSWord
INVALID"). SQLSTATE=08001
DB2 UDB 服务器上的 DB2 UDB 诊断日志(db2diag.log)中也会出现类似于下面这样的记录:
清单 2. 用户身份验证失败时 DB2 诊断日志中的消息:
2005-07-09-16.18.33.546000-240 I729347H256
LEVEL: Severe
PID : 3888
TID : 604
FUNCTION: DB2 Common, Security,
Users and Groups, secLogMessage, probe:20
DATA #1 : String, 44 bytes
check password failed with rc = -2146500502
在 Windows 上,诊断日志可以在数据库实例主目录中找到,默认为 C:Program FilesIBMSQLLIBDB2。在 Unix 上默认位置是 /DB2/db2dump,其中 是实例所有者的路径。
如果遇到这样的消息,一定要确认连接到数据库的用户或应用程序是否提供了合法的用户 ID 和口令。该用户 ID 和口令必须存在于执行用户身份验证的设施中(由目标 DB2 UDB 实例的 AUTHENTICATION 参数决定)。
授权
授权是决定指定用户 ID 对特定数据库对象和动作的访问和特权信息的过程。DB2 UDB 在内部存储和维护用户/组的授权信息。每当提交一个命令时,DB2 UDB 执行授权检查以保证您有执行该动作的正确特权。
特权可以授予特定的用户或者用户组。用户和组的定义本身同样在 DB2 UDB 外部定义。作为组成员的用户自动继承该组的特权。授予用户的特定权限优先于和该用户参与的任何组关联的特权,并且一直有效,即使后来从组中删除了用户。就是说,明确授予用户的特权必须明确收回。
多数数据库对象都由一组相关的权限,可使用 SQL 语句 GRANT 和 REVOKE 分配给用户和组。比如,下面的 SQL 语句将 ADM.ACCTABC 表的 SELECT 权限授予用户 bob:GRANT SELECT ON TABLE ADM.ACCTABC TO USER BOB。
一旦发出该语句,用户 bob 就可以提交引用该表的 SELECT 语句。类似的,下面的 SQL 语句从 clerks 组收回 ADM.LEGERS 视图的 INSERT 权限:REVOKE INSERT ON VIEW ADM.LEGERS FROM GROUP CLERKS。
只能收回以前授予的权限。关于能够授予用户和组的各种数据库对象特权的详细信息,请参阅 DB2 UDB 文当。
必须指出,特别是对 DB2 UDB 新用户,GRANT 语句不会检验用户和组帐户是否存在于外部设施中。这意味着,可以把权限和数据库中存储的信息授予不存在的用户和组帐户。这就造成了一种错误的印象,即可以在 DB2 UDB 中定义用户和组。比方说,连接到 finance 数据库时可以发出下面的语句:
GRANT SELECT ON TABLE ADM.TAXCODE TO USER XYZ。
其中的 xyz 是一个任意的字符串,没有映射为外部安全设施中的已有用户,然后 DB2 UDB 就会在其 GUI 工具或者某些目录表中显示 xyz。但这并不意味着存在或创建了名为 xyz 的用户。
下方显示了一个授权场景的例子。这个用户叫 bob,已经成功连接到数据库,现在尝试对表 ADM.TAXCODES 执行 SELECT 语句。DB2 UDB 查看其目录表,看看该用户是否被授予了这个表的 SELECT 权限。因为此权限已经授予 bob,DB2 UDB 允许执行 SELECT 语句。
如果用户未经授权而对某个对象执行一种操作,DB2 UDB 就会拒绝操作并向客户机应用程序返回错误信息。比方说,如果用户 bob 尝试向 ADM.TAXCODES 表中插入一行,但是没有足够的权限,就会返回下面的错误消息:
清单 3. 用户授权失败时 DB2 UDB 返回的消息:
DB21034E The command was processed
as an SQL statement because it
was not a valid Command Line
Processor command. During SQL
processing it returned:
SQL0551N "BOB" does not
have the privilege to perform
operation "INSERT" on object "ADM.TAXCODES".
SQLSTATE=42501
如果遇到类似的消息,一定要确认连接到数据库所提供的用户 ID 是否具有执行目标操作的适当权限。必须明确授予该用户此特权,或者该用户属于拥有该特权的组,或者该用户是超级用户。
超级用户
可以为某些用户组分配特定的实例和数据库权限。DB2 UDB 定义了超级用户授权的层次结构(SYSADM、SYSCTRL、SYSMAINT、SYSMON),每一种都具有执行管理操作子集的能力,比如创建数据库、迫使用户离开系统和对数据库进行备份。关于授权级别的详细讨论请参阅 DB2 UDB 文当(参见 参考资料)。
可以使用相关的实例级参数配置实例的授权(SYSADM_GRP、SYSCTRL_GRP、SYSMAIN_GRP、SYSMON_GRP)。每个参数可以设置为具有该授权的用户组名(在 DB2 UDB 外部定义)。
比如,如果定义组 snrdba 包含所有高级 DBA 用户帐户,就可使用下面的命令将 SYSADM_GRP 实例参数值设为 snrdba,从而使所有这些用户成为 SYSADM 超级用户:
清单 4. 更新 SYSADM_GRP 实例参数
UPDATE DBM CFG USING SYSADM_GRP snrdba
db2stop
db2start
snrdba 组中的所有用户都将拥有和 SYSADM 授权级别关联的全部特权,从而能够执行授权级别所需要的全部管理任务。
以这种方式定义授权就可以区分 DB2 UDB 管理员和系统/网络管理员。比如,DBA 可能要求拥有 DB2 UDB 实例的全部管理授权,但不需要本地机器或网络的管理授权。在这种情况下,可以将该 DBA 的用户帐户添加到对系统/网络没有完全访问权限、但是对 DB2 UDB 实例有完全访问权限的组,只要在 SYSADM_GRP 实例参数中指定该组名即可。
在 Windows 上的 DB2 UDB 默认安装中,这些实例级超级用户授权参数(SYSADM_GRP、SYSCTRL_GRP、SYSMAIN_GRP、SYSMON_GRP))的值默认设为 NULL。这意味着超级用户权限被授予属于本地 Administrators 组的所有合法帐户。我们强烈建议明确将这些参数值改为合法的组名,以便防止未授权的访问。在 Linux 和 UNIX 安装中,这不是一个大问题,因为 NULL 值默认为实例所有者的基本组,而基本组在安装后只包含实例所有者的用户 ID。
还可以为用户分配一组数据库级的授权。数据库授权使用标准的 SQL GRANT 和 REVOKE 语句。关于这些数据库授权级别的更多信息,请参阅 DB2 UDB 文档(参见 参考资料)。
