/************************************************************************* * * Function: sql_store_result * * Purpose: database specific store_result function. Returns a result * set for the query. In case of multiple results, get the * first non-empty one. * *************************************************************************/ static sql_rcode_t sql_store_result(rlm_sql_handle_t * handle, UNUSED rlm_sql_config_t *config) { rlm_sql_mysql_conn_t *conn = handle->conn; int status; if (!conn->sock) { ERROR("rlm_sql_mysql: Socket not connected"); return RLM_SQL_RECONNECT; } retry_store_result: if (!(conn->result = mysql_store_result(conn->sock))) { status = sql_check_error(mysql_errno(conn->sock)); if (status != 0) { ERROR("rlm_sql_mysql: Cannot store result"); ERROR("rlm_sql_mysql: MySQL error '%s'", mysql_error(conn->sock)); return status; } #if (MYSQL_VERSION_ID >= 40100) status = mysql_next_result(conn->sock); if (status == 0) { /* there are more results */ goto retry_store_result; } else if (status > 0) { ERROR("rlm_sql_mysql: Cannot get next result"); ERROR("rlm_sql_mysql: MySQL error '%s'", mysql_error(conn->sock)); return sql_check_error(status); } #endif } return 0; }
/************************************************************************* * * Function: sql_store_result * * Purpose: database specific store_result function. Returns a result * set for the query. In case of multiple results, get the * first non-empty one. * *************************************************************************/ static int sql_store_result(SQLSOCK * sqlsocket, UNUSED SQL_CONFIG *config) { rlm_sql_mysql_sock *mysql_sock = sqlsocket->conn; int status; if (mysql_sock->sock == NULL) { radlog(L_ERR, "rlm_sql_mysql: Socket not connected"); return SQL_DOWN; } retry_store_result: if (!(mysql_sock->result = mysql_store_result(mysql_sock->sock))) { status = sql_check_error(mysql_errno(mysql_sock->sock)); if (status != 0) { radlog(L_ERR, "rlm_sql_mysql: Cannot store result"); radlog(L_ERR, "rlm_sql_mysql: MySQL error '%s'", mysql_error(mysql_sock->sock)); return status; } #if (MYSQL_VERSION_ID >= 40100) status = mysql_next_result(mysql_sock->sock); if (status == 0) { /* there are more results */ goto retry_store_result; } else if (status > 0) { radlog(L_ERR, "rlm_sql_mysql: Cannot get next result"); radlog(L_ERR, "rlm_sql_mysql: MySQL error '%s'", mysql_error(mysql_sock->sock)); return sql_check_error(status); } #endif } return 0; }
static sql_rcode_t sql_socket_init(rlm_sql_handle_t *handle, rlm_sql_config_t *config) { rlm_sql_unixodbc_conn_t *conn; long err_handle; MEM(conn = handle->conn = talloc_zero(handle, rlm_sql_unixodbc_conn_t)); talloc_set_destructor(conn, _sql_socket_destructor); /* 1. Allocate environment handle and register version */ err_handle = SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &conn->env); if (sql_check_error(err_handle, handle, config)) { ERROR("rlm_sql_unixodbc: Can't allocate environment handle"); return RLM_SQL_ERROR; } err_handle = SQLSetEnvAttr(conn->env, SQL_ATTR_ODBC_VERSION, (void*)SQL_OV_ODBC3, 0); if (sql_check_error(err_handle, handle, config)) { ERROR("rlm_sql_unixodbc: Can't register ODBC version"); return RLM_SQL_ERROR; } /* 2. Allocate connection handle */ err_handle = SQLAllocHandle(SQL_HANDLE_DBC, conn->env, &conn->dbc); if (sql_check_error(err_handle, handle, config)) { ERROR("rlm_sql_unixodbc: Can't allocate connection handle"); return RLM_SQL_ERROR; } /* 3. Connect to the datasource */ { SQLCHAR *odbc_server, *odbc_login, *odbc_password; memcpy(&odbc_server, &config->sql_server, sizeof(odbc_server)); memcpy(&odbc_login, &config->sql_login, sizeof(odbc_login)); memcpy(&odbc_password, &config->sql_password, sizeof(odbc_password)); err_handle = SQLConnect(conn->dbc, odbc_server, strlen(config->sql_server), odbc_login, strlen(config->sql_login), odbc_password, strlen(config->sql_password)); } if (sql_check_error(err_handle, handle, config)) { ERROR("rlm_sql_unixodbc: Connection failed"); return RLM_SQL_ERROR; } /* 4. Allocate the stmt */ err_handle = SQLAllocHandle(SQL_HANDLE_STMT, conn->dbc, &conn->stmt); if (sql_check_error(err_handle, handle, config)) { ERROR("rlm_sql_unixodbc: Can't allocate the stmt"); return RLM_SQL_ERROR; } return RLM_SQL_OK; }
/************************************************************************* * * Function: sql_fetch_row * * Purpose: database specific fetch_row. Returns a rlm_sql_row_t struct * with all the data for the query in 'handle->row'. Returns * 0 on success, -1 on failure, SQL_DOWN if database is down. * *************************************************************************/ static int sql_fetch_row(rlm_sql_handle_t *handle, rlm_sql_config_t *config) { int x; rlm_sql_oracle_conn_t *conn = handle->conn; if (conn->ctx == NULL) { radlog(L_ERR, "rlm_sql_oracle: Socket not connected"); return SQL_DOWN; } handle->row = NULL; x=OCIStmtFetch(conn->queryHandle, conn->errHandle, 1, OCI_FETCH_NEXT, OCI_DEFAULT); if (x == OCI_SUCCESS) { handle->row = conn->results; return 0; } if (x == OCI_ERROR) { radlog(L_ERR,"rlm_sql_oracle: fetch failed in sql_fetch_row: %s", sql_error(handle, config)); return sql_check_error(handle, config); } else { return -1; } }
/************************************************************************* * * Function: sql_finish_query * * Purpose: As a single SQL statement may return multiple results * sets, (for example stored procedures) it is necessary to check * whether more results exist and process them in turn if so. * *************************************************************************/ static int sql_finish_query(rlm_sql_handle_t * handle, UNUSED rlm_sql_config_t *config) { #if (MYSQL_VERSION_ID >= 40100) rlm_sql_mysql_conn_t *conn = handle->conn; int status; skip_next_result: status = sql_store_result(handle, config); if (status != 0) { return status; } else if (conn->result != NULL) { radlog(L_DBG, "rlm_sql_mysql: SQL statement returned unexpected result"); sql_free_result(handle, config); } status = mysql_next_result(conn->sock); if (status == 0) { /* there are more results */ goto skip_next_result; } else if (status > 0) { radlog(L_ERR, "rlm_sql_mysql: Cannot get next result"); radlog(L_ERR, "rlm_sql_mysql: MySQL error '%s'", mysql_error(conn->sock)); return sql_check_error(status); } #endif return 0; }
/************************************************************************* * * Function: sql_finish_query * * Purpose: As a single SQL statement may return multiple results * sets, (for example stored procedures) it is necessary to check * whether more results exist and process them in turn if so. * *************************************************************************/ static int sql_finish_query(SQLSOCK * sqlsocket, UNUSED SQL_CONFIG *config) { #if (MYSQL_VERSION_ID >= 40100) rlm_sql_mysql_sock *mysql_sock = sqlsocket->conn; int status; skip_next_result: status = sql_store_result(sqlsocket, config); if (status != 0) { return status; } else if (mysql_sock->result != NULL) { radlog(L_DBG, "rlm_sql_mysql: SQL statement returned unexpected result"); sql_free_result(sqlsocket, config); } status = mysql_next_result(mysql_sock->sock); if (status == 0) { /* there are more results */ goto skip_next_result; } else if (status > 0) { radlog(L_ERR, "rlm_sql_mysql: Cannot get next result"); radlog(L_ERR, "rlm_sql_mysql: MySQL error '%s'", mysql_error(mysql_sock->sock)); return sql_check_error(status); } #endif return 0; }
/************************************************************************* * * Function: sql_fetch_row * * Purpose: database specific fetch_row. Returns a SQL_ROW struct * with all the data for the query in 'sqlsocket->row'. Returns * 0 on success, -1 on failure, SQL_DOWN if database is down. * *************************************************************************/ static int sql_fetch_row(SQLSOCK *sqlsocket, SQL_CONFIG *config) { int x; rlm_sql_oracle_sock *oracle_sock = sqlsocket->conn; if (oracle_sock->conn == NULL) { radlog(L_ERR, "rlm_sql_oracle: Socket not connected"); return SQL_DOWN; } sqlsocket->row = NULL; x=OCIStmtFetch(oracle_sock->queryHandle, oracle_sock->errHandle, 1, OCI_FETCH_NEXT, OCI_DEFAULT); if (x == OCI_SUCCESS) { sqlsocket->row = oracle_sock->results; return 0; } if (x == OCI_ERROR) { radlog(L_ERR,"rlm_sql_oracle: fetch failed in sql_fetch_row: %s", sql_error(sqlsocket, config)); return sql_check_error(sqlsocket, config); } else { return -1; } }
static int sql_num_fields(rlm_sql_handle_t *handle, rlm_sql_config_t *config) { rlm_sql_unixodbc_conn_t *conn = handle->conn; long err_handle; SQLSMALLINT num_fields = 0; err_handle = SQLNumResultCols(conn->stmt,&num_fields); if (sql_check_error(err_handle, handle, config)) return -1; return num_fields; }
/************************************************************************* * * Function: sql_affected_rows * * Purpose: Return the number of rows affected by the query (update, * or insert) * *************************************************************************/ static int sql_affected_rows(rlm_sql_handle_t *handle, rlm_sql_config_t *config) { rlm_sql_unixodbc_conn_t *conn = handle->conn; long error_handle; SQLLEN affected_rows; error_handle = SQLRowCount(conn->stmt, &affected_rows); if (sql_check_error(error_handle, handle, config)) return -1; return affected_rows; }
/************************************************************************* * * Function: sql_fetch_row * * Purpose: database specific fetch_row. Returns a rlm_sql_row_t struct * with all the data for the query in 'handle->row'. Returns * 0 on success, -1 on failure, SQL_DOWN if database is down. * *************************************************************************/ static int sql_fetch_row(rlm_sql_handle_t * handle, UNUSED rlm_sql_config_t *config) { rlm_sql_mysql_conn_t *conn = handle->conn; int status; /* * Check pointer before de-referencing it. */ if (!conn->result) { return SQL_DOWN; } retry_fetch_row: handle->row = mysql_fetch_row(conn->result); if (handle->row == NULL) { status = sql_check_error(mysql_errno(conn->sock)); if (status != 0) { radlog(L_ERR, "rlm_sql_mysql: Cannot fetch row"); radlog(L_ERR, "rlm_sql_mysql: MySQL error '%s'", mysql_error(conn->sock)); return status; } #if (MYSQL_VERSION_ID >= 40100) sql_free_result(handle, config); status = mysql_next_result(conn->sock); if (status == 0) { /* there are more results */ if ((sql_store_result(handle, config) == 0) && (conn->result != NULL)) goto retry_fetch_row; } else if (status > 0) { radlog(L_ERR, "rlm_sql_mysql: Cannot get next result"); radlog(L_ERR, "rlm_sql_mysql: MySQL error '%s'", mysql_error(conn->sock)); return sql_check_error(status); } #endif } return 0; }
/************************************************************************* * * Function: sql_fetch_row * * Purpose: database specific fetch_row. Returns a SQL_ROW struct * with all the data for the query in 'sqlsocket->row'. Returns * 0 on success, -1 on failure, SQL_DOWN if database is down. * *************************************************************************/ static int sql_fetch_row(SQLSOCK * sqlsocket, UNUSED SQL_CONFIG *config) { rlm_sql_mysql_sock *mysql_sock = sqlsocket->conn; int status; /* * Check pointer before de-referencing it. */ if (!mysql_sock->result) { return SQL_DOWN; } retry_fetch_row: sqlsocket->row = mysql_fetch_row(mysql_sock->result); if (sqlsocket->row == NULL) { status = sql_check_error(mysql_errno(mysql_sock->sock)); if (status != 0) { radlog(L_ERR, "rlm_sql_mysql: Cannot fetch row"); radlog(L_ERR, "rlm_sql_mysql: MySQL error '%s'", mysql_error(mysql_sock->sock)); return status; } #if (MYSQL_VERSION_ID >= 40100) sql_free_result(sqlsocket, config); status = mysql_next_result(mysql_sock->sock); if (status == 0) { /* there are more results */ if ((sql_store_result(sqlsocket, config) == 0) && (mysql_sock->result != NULL)) goto retry_fetch_row; } else if (status > 0) { radlog(L_ERR, "rlm_sql_mysql: Cannot get next result"); radlog(L_ERR, "rlm_sql_mysql: MySQL error '%s'", mysql_error(mysql_sock->sock)); return sql_check_error(status); } #endif } return 0; }
/************************************************************************* * * Function: sql_query * * Purpose: Issue a query to the database * *************************************************************************/ static sql_rcode_t sql_query(rlm_sql_handle_t * handle, UNUSED rlm_sql_config_t *config, char const *query) { rlm_sql_mysql_conn_t *conn = handle->conn; if (!conn->sock) { ERROR("rlm_sql_mysql: Socket not connected"); return RLM_SQL_RECONNECT; } mysql_query(conn->sock, query); return sql_check_error(mysql_errno(conn->sock)); }
/************************************************************************* * * Function: sql_query * * Purpose: Issue a query to the database * *************************************************************************/ static int sql_query(rlm_sql_handle_t * handle, UNUSED rlm_sql_config_t *config, char *querystr) { rlm_sql_mysql_conn_t *conn = handle->conn; if (conn->sock == NULL) { radlog(L_ERR, "rlm_sql_mysql: Socket not connected"); return SQL_DOWN; } mysql_query(conn->sock, querystr); return sql_check_error(mysql_errno(conn->sock)); }
/************************************************************************* * * Function: sql_query * * Purpose: Issue a query to the database * *************************************************************************/ static int sql_query(SQLSOCK * sqlsocket, UNUSED SQL_CONFIG *config, char *querystr) { rlm_sql_mysql_sock *mysql_sock = sqlsocket->conn; if (mysql_sock->sock == NULL) { radlog(L_ERR, "rlm_sql_mysql: Socket not connected"); return SQL_DOWN; } mysql_query(mysql_sock->sock, querystr); return sql_check_error(mysql_errno(mysql_sock->sock)); }
/************************************************************************* * * Function: sql_query * * Purpose: Issue a query to the database * *************************************************************************/ static int sql_query(SQLSOCK * sqlsocket, SQL_CONFIG *config, char *querystr) { rlm_sql_postgres_sock *pg_sock = sqlsocket->conn; if (config->sqltrace) radlog(L_DBG,"rlm_sql_postgresql: query:\n%s", querystr); if (pg_sock->conn == NULL) { radlog(L_ERR, "rlm_sql_postgresql: Socket not connected"); return SQL_DOWN; } pg_sock->result = PQexec(pg_sock->conn, querystr); /* Returns a result pointer or possibly a NULL pointer. * A non-NULL pointer will generally be returned except in * out-of-memory conditions or serious errors such as inability * to send the command to the backend. If a NULL is returned, * it should be treated like a PGRES_FATAL_ERROR result. * Use PQerrorMessage to get more information about the error. */ if (!pg_sock->result) { radlog(L_ERR, "rlm_sql_postgresql: PostgreSQL Query failed Error: %s", PQerrorMessage(pg_sock->conn)); return SQL_DOWN; } else { ExecStatusType status = PQresultStatus(pg_sock->result); radlog(L_DBG, "rlm_sql_postgresql: Status: %s", PQresStatus(status)); radlog(L_DBG, "rlm_sql_postgresql: affected rows = %s", PQcmdTuples(pg_sock->result)); if (!status_is_ok(status)) return sql_check_error(status); if (strncasecmp("select", querystr, 6) != 0) { /* store the number of affected rows because the sql module * calls finish_query before it retrieves the number of affected * rows from the driver */ pg_sock->affected_rows = affected_rows(pg_sock->result); return 0; } else { if ((sql_store_result(sqlsocket, config) == 0) && (sql_num_fields(sqlsocket, config) >= 0)) return 0; else return -1; } } }
static sql_rcode_t sql_fetch_row(rlm_sql_handle_t *handle, rlm_sql_config_t *config) { rlm_sql_unixodbc_conn_t *conn = handle->conn; long err_handle; int state; handle->row = NULL; err_handle = SQLFetch(conn->stmt); if (err_handle == SQL_NO_DATA_FOUND) return RLM_SQL_NO_MORE_ROWS; if ((state = sql_check_error(err_handle, handle, config))) return state; handle->row = conn->row; return RLM_SQL_OK; }
/************************************************************************* * * 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_COMMIT_ON_SUCCESS); if (x == OCI_SUCCESS) { return 0; } if (x == OCI_ERROR) { radlog(L_ERR,"rlm_sql_oracle: execute query failed in sql_query: %s", sql_error(sqlsocket, config)); return sql_check_error(sqlsocket, config); } else { return -1; } }
static sql_rcode_t sql_query(rlm_sql_handle_t *handle, rlm_sql_config_t *config, char const *query) { rlm_sql_unixodbc_conn_t *conn = handle->conn; long err_handle; int state; /* Executing query */ { SQLCHAR *odbc_query; memcpy(&odbc_query, &query, sizeof(odbc_query)); err_handle = SQLExecDirect(conn->stmt, odbc_query, strlen(query)); } if ((state = sql_check_error(err_handle, handle, config))) { if(state == RLM_SQL_RECONNECT) { DEBUG("rlm_sql_unixodbc: rlm_sql will attempt to reconnect"); } return state; } return 0; }
/************************************************************************* * * Function: sql_finish_select_query * * Purpose: End the select query, such as freeing memory or result * *************************************************************************/ static int sql_finish_select_query(SQLSOCK * sqlsocket, SQL_CONFIG *config) { #if (MYSQL_VERSION_ID >= 40100) int status; rlm_sql_mysql_sock *mysql_sock = sqlsocket->conn; #endif sql_free_result(sqlsocket, config); #if (MYSQL_VERSION_ID >= 40100) status = mysql_next_result(mysql_sock->sock); if (status == 0) { /* there are more results */ sql_finish_query(sqlsocket, config); } else if (status > 0) { radlog(L_ERR, "rlm_sql_mysql: Cannot get next result"); radlog(L_ERR, "rlm_sql_mysql: MySQL error '%s'", mysql_error(mysql_sock->sock)); return sql_check_error(status); } #endif return 0; }
/************************************************************************* * * Function: sql_finish_select_query * * Purpose: End the select query, such as freeing memory or result * *************************************************************************/ static int sql_finish_select_query(rlm_sql_handle_t * handle, rlm_sql_config_t *config) { #if (MYSQL_VERSION_ID >= 40100) int status; rlm_sql_mysql_conn_t *conn = handle->conn; #endif sql_free_result(handle, config); #if (MYSQL_VERSION_ID >= 40100) status = mysql_next_result(conn->sock); if (status == 0) { /* there are more results */ sql_finish_query(handle, config); } else if (status > 0) { radlog(L_ERR, "rlm_sql_mysql: Cannot get next result"); radlog(L_ERR, "rlm_sql_mysql: MySQL error '%s'", mysql_error(conn->sock)); return sql_check_error(status); } #endif return 0; }
/************************************************************************* * * Function: sql_query * * Purpose: Issue a non-SELECT query (ie: update/delete/insert) to * the database. * *************************************************************************/ static int sql_query(rlm_sql_handle_t *handle, rlm_sql_config_t *config, char *querystr) { int x; rlm_sql_oracle_conn_t *conn = handle->conn; if (conn->ctx == NULL) { radlog(L_ERR, "rlm_sql_oracle: Socket not connected"); return SQL_DOWN; } if (OCIStmtPrepare (conn->queryHandle, conn->errHandle, querystr, strlen(querystr), OCI_NTV_SYNTAX, OCI_DEFAULT)) { radlog(L_ERR,"rlm_sql_oracle: prepare failed in sql_query: %s",sql_error(handle, config)); return -1; } x = OCIStmtExecute(conn->ctx, conn->queryHandle, conn->errHandle, (ub4) 1, (ub4) 0, (OCISnapshot *) NULL, (OCISnapshot *) NULL, (ub4) OCI_COMMIT_ON_SUCCESS); if (x == OCI_SUCCESS) { return 0; } if (x == OCI_ERROR) { radlog(L_ERR,"rlm_sql_oracle: execute query failed in sql_query: %s", sql_error(handle, config)); return sql_check_error(handle, config); } else { return -1; } }
/************************************************************************* * * 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); if (x == OCI_NO_DATA) { /* Nothing to fetch */ return 0; } if (x != OCI_SUCCESS) { radlog(L_ERR,"rlm_sql_oracle: query failed in sql_select_query: %s", sql_error(sqlsocket, config)); return sql_check_error(sqlsocket, config); } /* * Define where the output from fetch calls will go * * This is a gross hack, but it works - we convert * all data to strings for ease of use. Fortunately, most * of the data we deal with is already in string format. */ colcount = sql_num_fields(sqlsocket, config); /* DEBUG2("sql_select_query(): colcount=%d",colcount); */ /* * FIXME: These malloc's can probably go, as the schema * is fixed... */ rowdata=(char **)rad_malloc(sizeof(char *) * (colcount+1) ); memset(rowdata, 0, (sizeof(char *) * (colcount+1) )); indicators = (sb2 *) rad_malloc(sizeof(sb2) * (colcount+1) ); memset(indicators, 0, sizeof(sb2) * (colcount+1)); for (y=1; y <= colcount; y++) { x=OCIParamGet(oracle_sock->queryHandle, OCI_HTYPE_STMT, oracle_sock->errHandle, (dvoid **)¶m, (ub4) y); if (x != OCI_SUCCESS) { radlog(L_ERR,"rlm_sql_oracle: OCIParamGet() failed in sql_select_query: %s", sql_error(sqlsocket, config)); return -1; } x=OCIAttrGet((dvoid*)param, OCI_DTYPE_PARAM, (dvoid*)&dtype, (ub4*)0, OCI_ATTR_DATA_TYPE, oracle_sock->errHandle); if (x != OCI_SUCCESS) { radlog(L_ERR,"rlm_sql_oracle: OCIAttrGet() failed in sql_select_query: %s", sql_error(sqlsocket, config)); return -1; } dsize=MAX_DATASTR_LEN; /* * Use the retrieved length of dname to allocate an output * buffer, and then define the output variable (but only * for char/string type columns). */ switch(dtype) { #ifdef SQLT_AFC case SQLT_AFC: /* ansii fixed char */ #endif #ifdef SQLT_AFV case SQLT_AFV: /* ansii var char */ #endif case SQLT_VCS: /* var char */ case SQLT_CHR: /* char */ case SQLT_STR: /* string */ x=OCIAttrGet((dvoid*)param, (ub4) OCI_DTYPE_PARAM, (dvoid*) &dsize, (ub4 *)0, (ub4) OCI_ATTR_DATA_SIZE, oracle_sock->errHandle); if (x != OCI_SUCCESS) { radlog(L_ERR,"rlm_sql_oracle: OCIAttrGet() failed in sql_select_query: %s", sql_error(sqlsocket, config)); return -1; } rowdata[y-1]=rad_malloc(dsize+1); memset(rowdata[y-1], 0, dsize+1); break; case SQLT_DAT: case SQLT_INT: case SQLT_UIN: case SQLT_FLT: case SQLT_PDN: case SQLT_BIN: case SQLT_NUM: rowdata[y-1]=rad_malloc(dsize+1); memset(rowdata[y-1], 0, dsize+1); break; default: dsize=0; rowdata[y-1]=NULL; break; } indicators[y-1] = 0; x=OCIDefineByPos(oracle_sock->queryHandle, &define, oracle_sock->errHandle, y, (ub1 *) rowdata[y-1], dsize+1, SQLT_STR, &indicators[y-1], (dvoid *) 0, (dvoid *) 0, OCI_DEFAULT); /* * FIXME: memory leaks of indicators & rowdata? */ if (x != OCI_SUCCESS) { radlog(L_ERR,"rlm_sql_oracle: OCIDefineByPos() failed in sql_select_query: %s", sql_error(sqlsocket, config)); return -1; } } oracle_sock->results=rowdata; oracle_sock->indicators=indicators; return 0; }