sys用户需要以sysdba身份登录
我们知道,oracle数据库的用户是分权限的,其中sys用户权限最高,在登录时需要以sysdba的身份才可以成功登陆,否则会报错:ORA-28009: connection as SYS should be as SYSDBA or SYSOPER.(如图)
hydra登录oracle的代码
hydra登录oracle的代码在源文件hydra-oracle.c中的start_oracle函数中,使用的是OCI接口,登录时调用的接口是OCILogon,如图。
OCILogon接口原型
查询OCI官方文档,得知OCILogon接口原型如下:
sword OCILogon (
OCIEnv *envhp, //环境句柄
OCIError *errhp, //错误句柄
OCISvcCtx **svchp, //服务上下文句柄
CONST text *username, //用户名
ub4 uname_len, //用户名长度
CONST text *password, //密码
ub4 passwd_len, //密码长度
CONST text *dbname, //数据库名
ub4 dbname_len //数据库名长度
);
sword OCILogoff (
OCISvcCtx *svchp, //服务上下文句柄
OCIError *errhp //错误句柄
);
可以看出,OCILogon接口中并不存在指定用户角色的参数,所以当调用此函数以sys用户登录时,就会报权限不足的错误。
使用其他接口替代OCILogon
既然问题出在OCILogon没有指定用户身份的参数,那么我们找个有指定身份参数的接口去代替。查询OCI官方文档可知,OCISessionBegin符合要求(如图)。这个接口是为某用户开始一个会话,既然能开始会话,当然也就表明该用户登录成功了。
hydra-oracle.c源码修正
经过上述讨论,决定改用OCISessionBegin接口来代替OCILogon接口。在调用时对sysdba类用户做判断(这里默认只处理sys用户),如图:
修正后的hydra-oracle.c在:
关于OCILogon和OCISessionBegin的接口测试代码如下:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <oci.h>
/*user name and password*/
#if 1
static text* username=(text *)"sys";
static text* password=(text *)"oracle11g";
#else
static text* username=(text *)"system";
static text* password=(text *)"oracle11g";
#endif
static text* oracle=(text *)"//172.16.7.30:1521/ORCL";
/*handle define*/
static OCIEnv *p_env; //OCI environment handle
static OCIError *p_err; //OCI error handle
static OCISvcCtx *p_svc; //OCI service context handel
static OCIServer *p_ser; //OCI server handle
static OCISession *p_usr; //OCI user session handle
static OCIStmt *p_sql; //OCI statement handle
static OCIDefine *p_dfn = (OCIDefine *)NULL; //OCI define handle
static OCIBind *p_bnd = (OCIBind *)NULL; //OCI bind handle
text o_errormsg[512];
sb4 o_errorcode;
/*create OCI environment*/
int create_env()
{
int swResult; //Return value
if(swResult = OCIEnvCreate(&p_env,OCI_DEFAULT,NULL,NULL,NULL,NULL,0,NULL)) {
printf("environment create error!\n\n");
return -1;