今天遇到此错误,解决后不太清楚其中原理,上网查询后明白一些,转载网上的文章作为记录,也供大家参考。主要是 sqlnet.ora 文件和 remote_login_passwordfile 参数影响。
一直以来,我记住的一个知识点就是:SQLNET.AUTHENTICATION_SERVICES=(NTS)是使用OS认证的必须条件之一。
今天一个偶然的机会,才知道这个结论是不完全准确的。
在本文的测试中,remote_login_passwordfile的值都为EXCLUSIVE,相关用户所属组也设置正确。先看windows下的测试:
--设置为NTS,OS验证成功
E:oracleora92in>cat .. etworkadminSQLNET.ORA
SQLNET.AUTHENTICATION_SERVICES= (NTS)
E:oracleora92in>sqlplus "/as sysdba"SQL*Plus: Release 9.2.0.1.0 - Production on 星期三 8月 15 22:34:56 2007Copyright (c) 1982, 2002, Oracle Corporation. All rights reserved.
连接到:
Oracle9i Enterprise Edition Release 9.2.0.1.0 - Production
With the Partitioning, OLAP and Oracle Data Mining options
JServer Release 9.2.0.1.0 - Productionsys@ORACLE9I> --下面把SQLNET.ORA的内容注释掉,OS验证成功
E:oracleora92in>cat .. etworkadminSQLNET.ORA
#SQLNET.AUTHENTICATION_SERVICES= (NTS)再次登录:
E:oracleora92in>sqlplus "/as sysdba"SQL*Plus: Release 9.2.0.1.0 - Production on 星期三 8月 15 22:36:09 2007Copyright (c) 1982, 2002, Oracle Corporation. All rights reserved.ERROR:
ORA-01031: insufficient privileges--设置为 NONE,OS验证失败
E:oracleora92in>cat .. etworkadminSQLNET.ORA
SQLNET.AUTHENTICATION_SERVICES= (NONE)
E:oracleora92in>sqlplus "/as sysdba"SQL*Plus: Release 9.2.0.1.0 - Production on 星期三 8月 15 22:50:33 2007Copyright (c) 1982, 2002, Oracle Corporation. All rights reserved.ERROR:
ORA-01031: insufficient privileges--设置为ALL,OS验证成功
E:oracleora92in>cat .. etworkadminSQLNET.ORA
SQLNET.AUTHENTICATION_SERVICES= (ALL)
E:oracleora92in>sqlplus "/as sysdba"SQL*Plus: Release 9.2.0.1.0 - Production on 星期三 8月 15 22:51:21 2007Copyright (c) 1982, 2002, Oracle Corporation. All rights reserved.
连接到:
Oracle9i Enterprise Edition Release 9.2.0.1.0 - Production
With the Partitioning, OLAP and Oracle Data Mining options
JServer Release 9.2.0.1.0 - Productionsys@ORACLE9I>登录失败,说明当前设置不允许操作系统认证。
这个例子也说明了:在windows下,SQLNET.AUTHENTICATION_SERVICES必须设置为NTS或者ALL才能使用OS认证。接着再看看在linux下的情况:--设置为NTS,OS验证失败
[oracle@primary admin]$ cat sqlnet.ora 
SQLNET.AUTHENTICATION_SERVICES= (NTS)
[oracle@primary admin]$ sqlplus "/as sysdba"SQL*Plus: Release 10.2.0.3.0 - Production on Wed Aug 15 23:08:53 2007Copyright (c) 1982, 2006, Oracle. All Rights Reserved.ERROR:
ORA-01031: insufficient privileges--注释掉,相当于什么都不设置,OS验证成功
[oracle@primary admin]$ cat sqlnet.ora 
#SQLNET.AUTHENTICATION_SERVICES= (NTS)
[oracle@primary admin]$ sqlplus "/as sysdba"SQL*Plus: Release 10.2.0.3.0 - Production on Wed Aug 15 23:06:17 2007Copyright (c) 1982, 2006, Oracle. All Rights Reserved.
Connected to:
Oracle Database 10g Enterprise Edition Release 10.2.0.3.0 - Production
With the Partitioning and Data Mining optionsSQL> --设置为NONE,OS验证失败
[oracle@primary admin]$ cat sqlnet.ora 
SQLNET.AUTHENTICATION_SERVICES= (NONE)
[oracle@primary admin]$ sqlplus "/as sysdba"SQL*Plus: Release 10.2.0.3.0 - Production on Wed Aug 15 23:07:07 2007Copyright (c) 1982, 2006, Oracle. All Rights Reserved.ERROR:
ORA-01031: insufficient privileges--随便设置一个值,OS验证失败
[oracle@primary admin]$ cat sqlnet.ora 
SQLNET.AUTHENTICATION_SERVICES= (aaa)
[oracle@primary admin]$ sqlplus "/as sysdba"SQL*Plus: Release 10.2.0.3.0 - Production on Wed Aug 15 23:14:45 2007Copyright (c) 1982, 2006, Oracle. All Rights Reserved.ERROR:
ORA-01031: insufficient privileges--设置为ALL,OS验证成功
[oracle@primary admin]$ cat sqlnet.ora 
SQLNET.AUTHENTICATION_SERVICES= (ALL)
[oracle@primary admin]$ sqlplus "/as sysdba"SQL*Plus: Release 10.2.0.3.0 - Production on Wed Aug 15 23:07:54 2007Copyright (c) 1982, 2006, Oracle. All Rights Reserved.
Connected to:
Oracle Database 10g Enterprise Edition Release 10.2.0.3.0 - Production
With the Partitioning and Data Mining optionsSQL> 从以上测试知道:在linux下,在SQLNET.AUTHENTICATION_SERVICES的值设置为ALL,或者不设置的情况下,OS验证才能成功。从测试可以看出,windows和linux下要实现OS验证,SQLNET.AUTHENTICATION_SERVICES的设置要求是不一样的,甚至是相反的,为什么呢?我们看看ORACLE对这个设置是怎么解释的:
SQLNET.AUTHENTICATION_SERVICES
PurposeUse the parameter SQLNET.AUTHENTICATION_SERVICES to enable one or more authentication services. If authentication has been installed, it is recommended that this parameter be set to either none or to one of the authentication methods.
Default
NoneValues
Authentication Methods Available with Oracle Net Services:* none for no authentication methods. A valid username and password can be used to access the database.
* all for all authentication methods
* nts for Windows NT native authenticationWindows NT native authenticationAn authentication method that enables a client single login access to a Windows NT server and a database running on the server.从oracle的解释可以知道,SQLNET.AUTHENTICATION_SERVICES=(NTS)是WINDOWS系统专用的,对linux/UNIX是不适用的。最后做一个简单的总结:
1、在windows下,SQLNET.AUTHENTICATION_SERVICES必须设置为NTS或者ALL才能使用OS认证;不设置或者设置为其他任何值都不能使用OS认证。
2、在linux下,在SQLNET.AUTHENTICATION_SERVICES的值设置为ALL,或者不设置的情况下,OS验证才能成功;设置为其他任何值都不能使用OS认证。
===============
1.OS认证
Oracle安装之后默认情况下是启用了OS认证的,这里提到的os认证是指服务器端os认证。OS认证的意思把登录数据库的用户和口令校验放在了操作系统一级。如果以安装Oracle时的用户登录OS,那么此时在登录Oracle数据库时不需要任何验证,如:
SQL> connect /as sysdba
已连接。
SQL> connect sys/aaa@test as sysdba
已连接。
SQL> connect sys/bbb as sysdba
已连接。
SQL> connect aaa/bbb as sysdba
已连接。
SQL> show user
SYS
SQL>
不论输入什么用户(哪怕这个用户如aaa在数据库中根本不存在),只要以sysdba权限连接数据库,都可以连接上,并且连接用户是sys,这样很方便,有时候,如果忘记了数据库的密码,而又想登录数据库,可以通过这种方式,前提是在数据库服务器上.但是方便的同时也带来了一些安全隐患,于是很多人想屏蔽os认证,在win下只要把oracle_home/NETWORK/admin/sqlnet.ora中的SQLNET.AUTHENTICATION_SERVICES= (nts)nts改成none或者注释掉这句话(在前面加上#),就可以屏蔽os功能,要想以sys用户连上数据库必须输入正确的sys口令,或者可以把oracle的安装用户从组ora_dba中删除掉,当然也可以直接把ora_dba这个组也删除,都可以屏蔽os功能.如:
SQL> connect /as sysdba
ERROR:
ORA-01031: 权限不足
SQL> connect sys/aaa as sysdba
ERROR:
ORA-01017: 用户名/口令无效; 登录被拒绝
SQL> connect aaa/bbb as sysdba
ERROR:
ORA-01031: 权限不足
SQL> connect sys/system as sysdba
已连接。
SQL>在unix/linux下也可以在文件sqlnet.ora中增加SQLNET.AUTHENTICATION_SERVICES=(none)以及删除dba(groupdel dba)组或者把oracle用户从dba组中删除都可以屏蔽os认证。利用这两种方法屏蔽os功能似乎总有些让人不放心,或者说不能让人完全信服,因为毕竟系统管理员还是可以创建ora_dba or dba组以及修改sqlnet.ora文件......
2. 口令文件
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的信息就是源于口令文件的.SQL> select * from v$pwfile_users;
USERNAME SYSDB SYSOP
------------------------------ ----- -----
SYS TRUE TRUE
TEST TRUE FALSE
到底可以有几个用户被授予sysdba或者sysoper权限,是由创建口令文件时指定的entries数决定的,准确的说还不完全是,最终还和os block的大小有关,如果entries指定了5,一个os block可以存放8个用户的口令,那么可以由8个用户被授予sysdba或者sysoper。还有一个问题修改了口令,口令长度增加了,按说占用的空间多了,事实是不论我们的口令多长,加密之后的长度几乎都是相同的,也就是说口令文件占用的大小和口令指定的长度几乎关系不大!C:>orapwd file=databasepwd.ora password=system entries=5
OPW-00005: 存在相同名称的文件 - 请删除或重命名
C:>orapwd file=databasepwd.ora password=system entries=5   force=y创建口令文件需要注意的是=前后没有空格!另外值得一提的是10g增加了一个新的参数force default值n,它的作用类似于创建表空间时的reuse功能,当同名文件存在时是否覆盖。是否使用口令文件,是通过oracle提供的一个参数remote_login_passwordfile来控制的,remote_login_passwordfile有none,shared,exclusive3个值,
none表示不使用口令文件,停用口令文件验证,Oracle数据库不允许远程SYSDBA/SYSOPER身份登录
exclusive表示实例独占使用口令文件,也就是各自实例使用单独的口令文件,
shared表示多个实例共享一个口令文件,缺省情况下,win下口令文件的格式是pwdsid.ora,unix下的格式是orapwSID(大小写敏感), Oracle数据库在启动时,首先查找的是orapw<sid>的口令文件,如果该文件不存在,则开始查找,orapw的口令文件,如果口令文件命名为orapw,多个数据库就可以共享.SQL> alter system set remote_login_passwordfile=exclusive scope=spfile;  3. 修改用户密码//查看用户
SQL> select username,password from dba_users;SQL> alter user system identified by manager;4. sys/system 密码丢失的处理方法:1).查询视图V$PWFILE_USERS,select * from V$PWFILE_USERS;
 记录下拥有 SYSOPER/SYSDBA 系统权限的用户 信息
2).关闭数据库 shutdown immediate
3).删除密码文件,文件路径一般为:ORACLE_HOME\DATABASE,文件名为  PWD<SID>.ORA
4).创建密码文件 
        ORAPWD FILE=< FILENAME > PASSWORD =< PASSWORD >
5).向密码文件中增加用户
       CONNECT SYS/internal_user_passsword  AS SYSDBA;
       启动数据库实例并打开数据库; 创建相应用户帐号,对其授权 
       授予 权限:GRANT SYSDBA TO user_name(如果先前数据库 只有sys具有sysdba权限,可不做这步)
6).修改密码文件状态,默认密码文件的状态shared,要将初始化参数里的 
        REMOTE_LOGIN_PASSWORDFILE 设置成EXCLUSIVE  SQL> alter system set remote_login_passwordfile=exclusive scope=spfile;