目录
背景
原因:
解决方法
背景
今天遇到一个大坑,新建的一个数据库用户调用apps下的程序包,程序反馈未授权无法使用。
但是DBA确认已经给了授权。
查询授权表也是有正确授权的,但就是显示无效授权。
后来debug进去,程序是可以step进到程序包里面的,证明授权是正常的。只是查询到一个sql里面selelct into 报这个错误,很诡异,纠结很久。
找到原来的程序开发人员,一轮调试,发现pkg的包头声明被加了AUTHID CURRENT_USER。
比对测试环境没有这个授权。
发生这种情况是公司EBS系统凌晨5点进行了patch升级,自动编译了数据库对象(patch中是不包含这个pkg的,应该是升级把所有的数据库对象给刷了一遍)
这种情况及时给其他数据库用户授权,也无法被有效调用,注释掉就可以了。
原因:
Oracle Metalink有以下解释
文档号:Doc ID 1286602.1
原文
APPLIES TO:
Oracle Applications DBA - Version 12.0.0 to 12.1.3 [Release 12 to 12.1]
Information in this document applies to any platform.
After upgrading to 12.1.3, custom packages created under apps schema have the clause ‘AUTHID CURRENT_USER’ added automatically to their package specification.
Steps To Reproduce
=================
1. Create a custom package under apps schema.
2. Upgrade to 12.1.3
The custom packages contain the text 'Header' in their definition, which causes AD utilities to manipulate them, and add the clause 'AUTHID CURRENT_USER' to them, as reported in Bug 3098429.
1. Replace the text 'Header' in the custom packages with any other similar text like 'Version'.
2. Compile the apps schema using adadmin, then it will be noticed that the AUTHID clause is not added.
NOTE:119935.1 - 11i: Applications Objects with Invoker's Rights and Processing Modes
解释起来应该就是:
程序包的包头注释中如果有 'Header'的字符,那么就会自动加上 'AUTHID CURRENT_USER'
比如:
ORACLE PLSQL中提供两种授权选择:
--AUTHID DEFINER (定义者权限):指编译存储对象的所有者。也是默认权限模式。
--AUTHID CURRENT_USER(调用者权限):指拥有当前会话权限的模式,这可能和当前登录用户相同或不同(alter session set current_schema 可以改变调用者Schema)
也就是说AUTHID CURRENT_USER只能操作本次连接的数据库用户下的对象,无法跨数据库用户操作数据库对象。
举个例子:
1. 在A用户和B用户,各建立一个table test_user(heder_id number);
2. 在A用户下建立一个procedure update_id,里面更新test_user.heder_id = 123;
3. 把update_id从A用户授权给B用户使用;
4. B用户下调用这个procedure A.update_id;
如果update_id没有使用AUTHID CURRENT_USER声明,会更新A用户的test_user数据,B用户的test_user的数据无变化。
如果update_id有使用AUTHID CURRENT_USER声明,会更新B用户的test_user数据,A用户的test_user的数据无变化。
如果该用户下无该table对象,则报错,如表或视图不存在、没有有效授权之类的。
查询亦然!!!
SELECT *
FROM Dba_Role_Privs t
WHERE t.Grantee = 'MPP'
ORDER BY t.Grantable
,t.Owner
,t.Table_Name;
查找数据库中被修改的对象
SELECT Do.Owner
,Do.Object_Name
,Do.Object_Type
,Ds.Line
,Ds.Text
,Do.Created
,Do.Last_Ddl_Time
FROM Dba_Objects Do
,Dba_Source Ds
WHERE 1 = 1
AND Do.Owner = Ds.Owner
AND Do.Object_Type = Ds.Type
AND Do.Object_Name = Ds.Name
AND Upper(Ds.Text) LIKE '%AUTHID CURRENT_USER%'
-- AND Ds.Line >= 10
AND (Do.Object_Name LIKE 'XX%' OR Do.Object_Name LIKE 'CUX%' OR Do.Object_Name LIKE 'CUS%')
--AND Do. >= SYSDATE - 2
--AND Do.Object_Type = 'PACKAGE'
AND To_Char(Do.Last_Ddl_Time, 'yyyy-mm-dd') = '2023-01-31'
ORDER BY Do.Owner
,Do.Object_Name
,Do.Last_Ddl_Time;
解决方法
找DBA手动把它改回来呗。