转载自:http://www.cnblogs.com/chenleiustc/archive/2009/09/20/1570576.html
口令文件:
oracle的口令文件的作用是存放所有以sysdba或者sysoper权限连接数据库的用户的口令,如果想以sysdba权限远程连接数据库,必须使用口令文件,否则不能连上,由于sys用户在连接数据库时必须以sysdba or sysoper方式,也就是说sys用户要想连接数据库必须使用口令文件,因此我认为在数据库中存放sys用户的口令其实没有任何意义!使用口令文件的好处是即使数据库不处于open状态,依然可以通过口令文件验证来连接数据库。开始安装完oracle,没有给普通用户授予sysdba权限,口令文件中只存放了sys的口令,如果之后把sysdba权限授予了普通用户,那么此时会把普通用户的口令从数据库中读到口令文件中保存下来,当然这时必须要求数据库处于open状态。如:
SQL> grant sysdba to test;
授权成功。
SQL> connect test/aaa@orcl as sysdba
ERROR:
ORA-01017: 用户名/口令无效; 登录被拒绝
警告: 您不再连接到 ORACLE。
SQL> connect test/test@orcl as sysdba
已连接。
SQL> alter database close;
数据库已更改。
SQL> grant sysdba, sysoper to test;
grant sysdba, sysoper to test
*
第 1 行出现错误:
ORA-01109: 数据库未打开
到底有几个用户被授予了sysdba或者sysoper权限,可以通过查询如下v$pwfile_users获得,v$pwfile_users的信息就是源于口令文件的(This view lists users who have been granted SYSDBA and SYSOPER privileges as derived from the password file.)
SQL> select * from v$pwfile_users;
USERNAME SYSDB SYSOP
------------------------------ ----- -----
SYS TRUE TRUE
TEST TRUE FALSE
从用户剥夺sysdba权限:revoke sysdba from test;
到底可以有几个用户被授予sysdba或者sysoper权限,是由创建口令文件时指定的entries数决定的,准确的说还不完全是,最终还和os block的大小有关,如果entries指定了5,一个os block可以存放8个用户的口令,那么可以由8个用户被授予sysdba或者sysoper。
下面看一个简单的测试:-----给数据库添加100个新用户
SQL> declare
2 v_string varchar2(100);
3 begin
4 for i in 1..100 loop
5 v_string := 'create user test'||i||' identified by test'||i;
6 execute immediate v_string ; ----执行create user语句
7 end loop;
8 end;
9 /
PL/SQL 过程已成功完成。
SQL> select count(*) from dba_users where username like '%TEST%';
COUNT(*)
----------
101
这里之所以是101,是因为之前已经创建过test用户
SQL> declare
2 v_string varchar2(100);
3 begin
4 for i in 1..100 loop
5 v_string := 'grant sysdba to test'||i; ---为这100个新用户赋sysdba权限。考察可以付多少个
6 execute immediate v_string ;
7 end loop ;
8 end ;
9 /
declare
*
第 1 行出现错误:
ORA-01996: GRANT 失败: 口令文件 '' 已满
ORA-06512: 在 line 6
SQL> select * from v$pwfile_users;
USERNAME SYSDB SYSOP
------------------------------ ----- -----
SYS TRUE TRUE
TEST1 TRUE FALSE
TEST2 TRUE FALSE
TEST3 TRUE FALSE
TEST4 TRUE FALSE
TEST5 TRUE FALSE
TEST6 TRUE FALSE
TEST7 TRUE FALSE
TEST8 TRUE FALSE
已选择9行。
SQL>
可以清楚的看到v$pwfile_users里面并不是创建口令文件时指定的entries=5而是9条记录,意味着9个用户的口令占用了一个os block,其实也可能是多个os block,总之这些block都是满的,但是观察口令文件,还是占了2k,这是我解释不清的地方。通过os命令发现;每个簇字节数4096;这里其实就是os block 大小实际上是4k,但是口令文件占用了2k,根本没有用满一个os block,不知道何故,也是我的疑惑 。
win下查看os block大小
C:\WINDOWS\system32>fsutil fsinfo ntfsinfo e:
NTFS 卷序列号 : 0x12afb454f6e54b31
版本 : 3.1
区数量 : 0x00000000040270d0
簇总数 : 0x0000000000804e1a
可用簇 : 0x00000000000b8d41
保留总数 : 0x0000000000000000
每个扇区字节数 : 512
每个簇字节数 : 4096
每个 FileRecord 段的字节数 : 1024
每个 FileRecord 段的簇数 : 0
Mft 有效数据长度 : 0x00000000058d0000
Mft 起始 Lcn : 0x0000000000000004
Mft2 起始 Lcn : 0x0000000000080000
Mft 区域起始 : 0x0000000000483740
Mft 区域结尾 : 0x000000000049c760
C:WINDOWS\system32>
还有一个问题修改了口令,口令长度增加了,按说占用的空间多了,但是查询v$pwfile_users发现还是9条记录?不过这个问题突然想到了答案,那就是不论我们的口令多长,加密之后的长度几乎都是相同的,也就是说口令文件占用的大小和口令指定的长度几乎关系不大!
创建口令文件需要注意的是=前后没有空格!另外值得一提的是10g增加了一个新的参数force default值n,它的作用类似于创建表空间时的reuse功能,当同名文件存在时是否覆盖。
是否使用口令文件,是通过oracle提供的一个参数remote_login_passwordfile来控制的,remote_login_passwordfile有none,shared,exclusive3个值,none表示不使用口令文件,exclusive表示实例独占使用口令文件,也就是各自实例使用单独的口令文件,shared表示多个实例共享一个口令文件,缺省情况下,win下口令文件的格式是pwdsid.ora,unix下的格式是orapwSID(大小写敏感),unix下寻找口令文件的顺序是oracle_home\dbs\orapwSID,如果找不到,会在dbs目录想寻找orapw文件,如果找不到9i下会报错,数据库可以启动到mount状态,当然再次alter database open之后还是可以打开数据库。10g下open数据库时不在检查口令文件。win下如果在oracle_home/database/下找不到pwdsid.ora文件,不会寻找任何文件。这里所说的win下如果找不到PWDsid.ora文件之后不会寻找任何文件其实是相对unix下如果找不到orapwSID文件之后会寻找orapw文件而言的。其实win下寻找口令文件也是有顺序的。寻找顺序是这样的:首先寻找注册表中ora_sid_pwfile环境变量所指向的口令文件,其次寻找ora_pwfile执行的口令文件,最后才寻找$ORACLE_HOME/database/PWDsid.ora,下面做一个简单的测试:
开始存在一个口令文件PWDtsid.ora,之后又创建了两个口令文件pwd.ora和orapwd.ora
C:>orapwd file=E:\oracle\product\10.2.0\db_1\databasepwd.ora password=manager entries=5 force=y
C:>orapwd file=E:\oracle\product\10.2.0\db_1\databaseorapwd.ora password=manager_system entries=5
C:>e:
E:>cd E:\oracle\product\10.2.0\db_1\database
E:\oracle\product\10.2.0\db_1\database>dir *pwd*
驱动器 E 中的卷没有标签。
卷的序列号是 F6E5-4B31
E:\oracle\product\10.2.0\db_1\database 的目录
2007-12-07 21:30 2,048 orapwd.ora
2007-12-07 21:29 2,048 pwd.ora
2007-12-06 21:44 2,048 PWDtsid.ora
3个口令文件的口令分别是system, manager, system_manager没有什么特别的意义,都是随意指定的,其中在注册表中ora_tsid_pwfile指向了文件E:\oracle\product\10.2.0\db_1\databasepwd.ora,ora_pwfile指向了E:\oracle\product\10.2.0\db_1\databaseorapwd.ora,然后通过远程client端进行测试:
SQL> connect sys/system@testdb as sysdba
ERROR:
ORA-01017: 用户名/口令无效; 登录被拒绝
警告: 您不再连接到 ORACLE。
SQL> connect sys/manager@testdb as sysdba
已连接。
SQL> connect sys/manager_system@testdb as sysdba
ERROR:
ORA-01017: 用户名/口令无效; 登录被拒绝
警告: 您不再连接到 ORACLE。
SQL>
测试结果显示要求输入的口令是manager,而manager对应的口令文件是环境变量ora_tsid_pwfile所指向的pwd.ora,之后删除环境变量ora_tsid_pwfile再次连接:
SQL> connect sys/system@testdb as sysdba
ERROR:
ORA-01017: 用户名/口令无效; 登录被拒绝
警告: 您不再连接到 ORACLE。
SQL> connect sys/manager_system@testdb as sysdba
已连接。
SQL>
这次要求输入的口令是manager_system,而manager_system对应的口令文件是环境变量ora_pwfile所指向的orapwd.ora,之后删除环境变量ora_pwfile进行连接测试:
SQL> connect sys/system@testdb as sysdba
已连接。
SQL>
连接成功,system对应的口令文件正是$ORACLE_HOME/database/PWDtsid.ora
接着上面介绍共享口令文件,由于在unix下会寻找orapw文件(该文件不含sid的信息),因此各个实例可以shared口令文件,前提是需要把参数remote_login_passwordfile设置为shared,该参数是静态参数,修改之后需要重启实例,当然也可以通过连接的方式(unix下ls)实现口令文件共享,不过没感觉到共享口令文件有什么好处;win下可以通过在注册表中指定环境变量ora_sid_pwfile或者ora_pwfile来改变口令文件的位置和名称,从而也可以实现口令文件共享。
共享口令文件会有很多问题:
首先要求所有的sys口令相同,其次orcl库上的用户xys被授予了sysdba,结果在test1库上通过v$pwfile_users也可以看到xys用户。
SQL> connect sys/system as sysdba
ERROR:
ORA-01017: invalid username/password; logon denied
SQL> connect sys/manager as sysdba
已连接到空闲例程。
SQL> startup
ORACLE 例程已经启动。
Total System Global Area 167772160 bytes
Fixed Size 1247900 bytes
Variable Size 62915940 bytes
Database Buffers 100663296 bytes
Redo Buffers 2945024 bytes
数据库装载完毕。
数据库已经打开。
SQL> alter user sys identified by system;
用户已更改。
SQL> show user
USER 为 SYS;
SQL> show parameter db_name
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
db_name string test1
SQL> select * from v$pwfile_users;
USERNAME SYSDB SYSOP
------------------------------ ----- -----
SYS TRUE TRUE
XYS TRUE FALSE
SQL> select username from dba_users;
USERNAME
------------------------------
OUTLN
SYS
SYSTEM
TEST
DBSNMP
TSMSYS
DIP
已选择7行。
从上面查询结果看到数据库orcl和test1,准确的说是实例共享了口令文件之后,test1中根本不存在用户xys,但是通过v$pwfile_users还是查询出来了
还有一个问题是如果remote_login_passwordfile=shared则sys的口令通过
alter user...不能修改!
SQL> show parameter remote_log
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
remote_login_passwordfile string SHARED
SQL> alter user sys identified by manager;
alter user sys identified by manager
*
第 1 行出现错误:
ORA-28046: 不允许更改 SYS 口令
提到alter user...这个系统权限,我觉得oracle做的不是很安全,只要有了alter user权限,sys用户的口令可以随意修改
,另外凡是修改具有sysdba or sysoper权限的用户,如果通过alter user来修改口令,那么同时修改了口令文件和数据库中的口令。
简单的测试如下:
SQL> create user test11 identified by test11;
用户已创建。
SQL> grant connect , alter user to test11;
授权成功。
SQL> connect test11/test11
已连接。
SQL> CONNECT / as sysdba
已连接。
SQL> grant select on dba_users to test11;
授权成功。
SQL> connect test11/test11
已连接。
SQL> col username format a10
SQL> col password format a30
SQL> select password , username from dba_users where username ='SYS';
PASSWORD USERNAME
------------------------------ ----------
75800913E1B66343 SYS
SQL> show user
USER 为 TEST11;
SQL> alter user sys identified by manager;
用户已更改。
SQL> select password , username from dba_users where username ='SYS';
PASSWORD USERNAME
------------------------------ ----------
5638228DAF52805F SYS
SQL>
remote_login_passwordfile=shared时,也不能把sysdba or sysoper授予普通用户!
SQL> grant sysdba to test;
grant sysdba to test
*
第 1 行出现错误:
ORA-01999: 口令文件不能在 SHARED 模式下更新
SQL> grant sysoper to test;
grant sysoper to test
*
第 1 行出现错误:
ORA-01999: 口令文件不能在 SHARED 模式下更新
通过上面两部分内容的解释,了解了os认证和口令文件之后,如果为了安全不想让用户以sysdba or sysoper权限连接数据库,可以通过上面的方法屏蔽os认证的同时静止使用口令文件。
3、sysdba 和 sysoper
很多人可能不了解sysdba and sysoper到底是什么,其实他们是oracle的system privilege,通过查询系统权限表system_privilege_map可以清楚的知道:
SQL> select name from system_privilege_map where name like 'SYS%';
NAME
----------------------------------------------------------------------------
SYSOPER
SYSDBA
只不过这两个权限就是以这种方式发挥作用的!
值的一提的是win下尤其是home版的xp控制面板中没有组的可操作界面,而oracle默认安装之后也没有为我们创建ora_oper 这个组,因此在以sysoper权限连接数据库时提示没有权限:
SQL> connect / as sysoper
ERROR:
ORA-01031: 权限不足
为了能够以sysoper方式连接数据库,于是可以通过dos命令方式创建ora_oper组,同时把os用户加入到这个组中:
E:>net localgroup ora_oper /add
命令成功完成。
E:>net localgroup ora_oper wch /add
命令成功完成。
有关localgroup的详细说明可以通过命令net help localgroup获得更多的帮助,注意和group的区别,group用在domain中
再次尝试接连,连接成功:
SQL> connect / as sysoper
已连接。
SQL> show user
USER 为 PUBLIC;
SQL>
但是需要注意的是以sysoper权限连接数据库时显示的schema是public,而以sysdba连接时显示的schema是我们众所周知的sys,这也是sysdba和sysoper的区别之一。
同时需要注意的是在linux下默认是可以以sysoper 连接数据库的:
[oracle@xys oracle]$ sqlplus /nolog
SQL*Plus: Release 11.1.0.6.0 - Production on Fri Dec 7 23:52:49 2007
Copyright (c) 1982, 2007, Oracle. All rights reserved.
SQL> connect / as sysoper
Connected to an idle instance.
SQL> create user wch identified externally;
用户已创建。
SQL> grant create session to wch;
授权成功。
SQL> show parameter auth
NAME TYPE VALUE
------------------------------------ ----------- -------------------------
os_authent_prefix string OPS$
remote_os_authent boolean FALSE
SQL> col username format a10
SQL> col password format a30
SQL> select username , password from dba_users where username='WCH';
USERNAME PASSWORD
---------- ------------------------------
WCH EXTERNAL
SQL> connect /
ERROR:
ORA-01017: 用户名/口令无效; 登录被拒绝
警告: 您不再连接到 ORACLE。
SQL>
使用普通用户os认证的好处是可以在执行一些批处理脚本时屏蔽数据库连接用户的口令,如exp ,expdp . sqlldr等