📄 sql_oracle.c
字号:
/* * sql_oracle.c Oracle (OCI) routines for rlm_sql * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * Copyright 2000 The FreeRADIUS server project * Copyright 2000 David Kerry <davidk@snti.com> */#include <stdio.h>#include <sys/stat.h>#include <sys/time.h>#include <stdlib.h>#include <string.h>#include "radiusd.h"#include <oci.h>#include "rlm_sql.h"typedef struct rlm_sql_oracle_sock { OCIEnv *env; OCIError *errHandle; OCISvcCtx *conn; OCIStmt *queryHandle; sb2 *indicators; char **results; int id; int in_use; struct timeval tv;} rlm_sql_oracle_sock;#define MAX_DATASTR_LEN 64/************************************************************************* * * Function: sql_error * * Purpose: database specific error. Returns error associated with * connection * *************************************************************************/static char *sql_error(SQLSOCK *sqlsocket, SQL_CONFIG *config) { static char msgbuf[512]; sb4 errcode = 0; rlm_sql_oracle_sock *oracle_sock = sqlsocket->conn; if (!oracle_sock) return "rlm_sql_oracle: no connection to db"; memset((void *) msgbuf, (int)'\0', sizeof(msgbuf)); OCIErrorGet((dvoid *) oracle_sock->errHandle, (ub4) 1, (text *) NULL, &errcode, msgbuf, (ub4) sizeof(msgbuf), (ub4) OCI_HTYPE_ERROR); if (errcode) { return msgbuf; } else { return NULL; }}/************************************************************************* * * Function: sql_close * * Purpose: database specific close. Closes an open database * connection and cleans up any open handles. * *************************************************************************/static int sql_close(SQLSOCK *sqlsocket, SQL_CONFIG *config) { rlm_sql_oracle_sock *oracle_sock = sqlsocket->conn; if (oracle_sock->conn) { OCILogoff (oracle_sock->conn, oracle_sock->errHandle); } if (oracle_sock->queryHandle) { OCIHandleFree((dvoid *)oracle_sock->queryHandle, (ub4) OCI_HTYPE_STMT); } if (oracle_sock->errHandle) { OCIHandleFree((dvoid *)oracle_sock->errHandle, (ub4) OCI_HTYPE_ERROR); } if (oracle_sock->env) { OCIHandleFree((dvoid *)oracle_sock->env, (ub4) OCI_HTYPE_ENV); } oracle_sock->conn = NULL; free(oracle_sock); sqlsocket->conn = NULL; return 0;}/************************************************************************* * * Function: sql_init_socket * * Purpose: Establish connection to the db * *************************************************************************/static int sql_init_socket(SQLSOCK *sqlsocket, SQL_CONFIG *config) { rlm_sql_oracle_sock *oracle_sock; if (!sqlsocket->conn) { sqlsocket->conn = (rlm_sql_oracle_sock *)rad_malloc(sizeof(rlm_sql_oracle_sock)); if (!sqlsocket->conn) { return -1; } } memset(sqlsocket->conn,0,sizeof(rlm_sql_oracle_sock)); oracle_sock = sqlsocket->conn; if (OCIEnvCreate(&oracle_sock->env, OCI_DEFAULT|OCI_THREADED, (dvoid *)0, (dvoid * (*)(dvoid *, size_t)) 0, (dvoid * (*)(dvoid *, dvoid *, size_t))0, (void (*)(dvoid *, dvoid *)) 0, 0, (dvoid **)0 )) { radlog(L_ERR,"rlm_sql_oracle: Couldn't init Oracle OCI environment (OCIEnvCreate())"); return -1; } if (OCIHandleAlloc((dvoid *) oracle_sock->env, (dvoid **) &oracle_sock->errHandle, (ub4) OCI_HTYPE_ERROR, (size_t) 0, (dvoid **) 0)) { radlog(L_ERR,"rlm_sql_oracle: Couldn't init Oracle ERROR handle (OCIHandleAlloc())"); return -1; } /* Allocate handles for select and update queries */ if (OCIHandleAlloc((dvoid *)oracle_sock->env, (dvoid **) &oracle_sock->queryHandle, (ub4)OCI_HTYPE_STMT, (CONST size_t) 0, (dvoid **) 0)) { radlog(L_ERR,"rlm_sql_oracle: Couldn't init Oracle query handles: %s", sql_error(sqlsocket, config)); return -1; } if (OCILogon(oracle_sock->env, oracle_sock->errHandle, &oracle_sock->conn, config->sql_login, strlen(config->sql_login), config->sql_password, strlen(config->sql_password), config->sql_db, strlen(config->sql_db))) { radlog(L_ERR,"rlm_sql_oracle: Oracle logon failed: '%s'", sql_error(sqlsocket, config)); sql_close(sqlsocket,config); return -1; } return 0;}/************************************************************************* * * Function: sql_destroy_socket * * Purpose: Free socket and private connection data * *************************************************************************/static int sql_destroy_socket(SQLSOCK *sqlsocket, SQL_CONFIG *config){ free(sqlsocket->conn); sqlsocket->conn = NULL; return 0;}/************************************************************************* * * Function: sql_num_fields * * Purpose: database specific num_fields function. Returns number * of columns from query * *************************************************************************/static int sql_num_fields(SQLSOCK *sqlsocket, SQL_CONFIG *config) { ub4 count; rlm_sql_oracle_sock *oracle_sock = sqlsocket->conn; /* get the number of columns in the select list */ if (OCIAttrGet ((dvoid *)oracle_sock->queryHandle, (ub4)OCI_HTYPE_STMT, (dvoid *) &count, (ub4 *) 0, (ub4)OCI_ATTR_PARAM_COUNT, oracle_sock->errHandle)) { radlog(L_ERR,"rlm_sql_oracle: Error retrieving column count in sql_num_fields: %s", sql_error(sqlsocket, config)); return -1; } return count;}/************************************************************************* * * Function: sql_query * * Purpose: Issue a non-SELECT query (ie: update/delete/insert) to * the database. * *************************************************************************/static int sql_query(SQLSOCK *sqlsocket, SQL_CONFIG *config, char *querystr) { int x; rlm_sql_oracle_sock *oracle_sock = sqlsocket->conn; if (config->sqltrace) DEBUG(querystr); if (oracle_sock->conn == NULL) { radlog(L_ERR, "rlm_sql_oracle: Socket not connected"); return SQL_DOWN; } if (OCIStmtPrepare (oracle_sock->queryHandle, oracle_sock->errHandle, querystr, strlen(querystr), OCI_NTV_SYNTAX, OCI_DEFAULT)) { radlog(L_ERR,"rlm_sql_oracle: prepare failed in sql_query: %s",sql_error(sqlsocket, config)); return -1; } x = OCIStmtExecute(oracle_sock->conn, oracle_sock->queryHandle, oracle_sock->errHandle, (ub4) 1, (ub4) 0, (OCISnapshot *) NULL, (OCISnapshot *) NULL, (ub4) OCI_DEFAULT); if ((x != OCI_NO_DATA) && (x != OCI_SUCCESS)) { radlog(L_ERR,"rlm_sql_oracle: execute query failed in sql_query: %s", sql_error(sqlsocket, config)); return SQL_DOWN; } x = OCITransCommit(oracle_sock->conn, oracle_sock->errHandle, (ub4) 0); if (x != OCI_SUCCESS) { radlog(L_ERR,"rlm_sql_oracle: commit failed in sql_query: %s", sql_error(sqlsocket, config)); return SQL_DOWN; } return 0;}/************************************************************************* * * Function: sql_select_query * * Purpose: Issue a select query to the database * *************************************************************************/static int sql_select_query(SQLSOCK *sqlsocket, SQL_CONFIG *config, char *querystr) { int x; int y; int colcount; OCIParam *param; OCIDefine *define; ub2 dtype; ub2 dsize; char **rowdata=NULL; sb2 *indicators; rlm_sql_oracle_sock *oracle_sock = sqlsocket->conn; if (config->sqltrace) DEBUG(querystr); if (oracle_sock->conn == NULL) { radlog(L_ERR, "rlm_sql_oracle: Socket not connected"); return SQL_DOWN; } if (OCIStmtPrepare (oracle_sock->queryHandle, oracle_sock->errHandle, querystr, strlen(querystr), OCI_NTV_SYNTAX, OCI_DEFAULT)) { radlog(L_ERR,"rlm_sql_oracle: prepare failed in sql_select_query: %s",sql_error(sqlsocket, config)); return -1; } /* Query only one row by default (for now) */ x = OCIStmtExecute(oracle_sock->conn, oracle_sock->queryHandle, oracle_sock->errHandle, (ub4) 0, (ub4) 0, (OCISnapshot *) NULL, (OCISnapshot *) NULL, (ub4) OCI_DEFAULT);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -