2 * sql_db2.c IBM DB2 rlm_sql driver
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20 * Copyright 2000 The FreeRADIUS server project
21 * Copyright 2000 Mike Machado <mike@innercite.com>
22 * Copyright 2000 Alan DeKok <aland@ox.org>
23 * Copyright 2001 Joerg Wendland <wendland@scan-plus.de>
27 * Modification of rlm_sql_db2 to handle IBM DB2 UDB V7
28 * by Joerg Wendland <wendland@scan-plus.de>
31 #include <freeradius-devel/autoconf.h>
38 #include <freeradius-devel/radiusd.h>
43 typedef struct rlm_sql_db2_sock {
49 /*************************************************************************
51 * Function: sql_create_socket
53 * Purpose: Establish connection to the db
55 *************************************************************************/
56 static int sql_init_socket(SQLSOCK *sqlsocket, SQL_CONFIG *config)
59 rlm_sql_db2_sock *sock;
62 if (!sqlsocket->conn) {
63 sqlsocket->conn = (rlm_sql_db2_sock*)rad_malloc(sizeof(rlm_sql_db2_sock));
64 if (!sqlsocket->conn) {
68 sock = sqlsocket->conn;
69 memset(sock, 0, sizeof(*sock));
71 /* allocate handles */
72 SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &(sock->henv));
73 SQLAllocHandle(SQL_HANDLE_DBC, sock->henv, &(sock->hdbc));
75 /* connect to database */
76 retval = SQLConnect(sock->hdbc,
77 config->sql_server, SQL_NTS,
78 config->sql_login, SQL_NTS,
79 config->sql_password, SQL_NTS);
80 if(retval != SQL_SUCCESS) {
81 radlog(L_ERR, "could not connect to DB2 server %s\n", config->sql_server);
82 SQLDisconnect(sock->hdbc);
83 SQLFreeHandle(SQL_HANDLE_DBC, sock->hdbc);
84 SQLFreeHandle(SQL_HANDLE_ENV, sock->henv);
92 /*************************************************************************
94 * Function: sql_destroy_socket
96 * Purpose: Free socket and private connection data
98 *************************************************************************/
99 static int sql_destroy_socket(SQLSOCK *sqlsocket, SQL_CONFIG *config)
101 free(sqlsocket->conn);
102 sqlsocket->conn = NULL;
106 /*************************************************************************
108 * Function: sql_query
110 * Purpose: Issue a query to the database
112 *************************************************************************/
113 static int sql_query(SQLSOCK * sqlsocket, SQL_CONFIG *config, char *querystr)
116 rlm_sql_db2_sock *sock;
118 sock = sqlsocket->conn;
120 if (config->sqltrace)
121 radlog(L_DBG,"query:\n%s", querystr);
123 /* allocate handle for statement */
124 SQLAllocHandle(SQL_HANDLE_STMT, sock->hdbc,
128 retval = SQLExecDirect(sock->stmt, querystr, SQL_NTS);
129 if(retval != SQL_SUCCESS) {
130 /* XXX Check if retval means we should return SQL_DOWN */
131 radlog(L_ERR, "could not execute statement \"%s\"\n", querystr);
139 /*************************************************************************
141 * Function: sql_select_query
143 * Purpose: Issue a select query to the database
145 *************************************************************************/
146 static int sql_select_query(SQLSOCK * sqlsocket, SQL_CONFIG *config, char *querystr)
148 return sql_query(sqlsocket, config, querystr);
152 /*************************************************************************
154 * Function: sql_store_result
156 * Purpose: database specific store_result function. Returns a result
159 *************************************************************************/
160 static int sql_store_result(SQLSOCK * sqlsocket, SQL_CONFIG *config)
166 /*************************************************************************
168 * Function: sql_num_fields
170 * Purpose: database specific num_fields function. Returns number
171 * of columns from query
173 *************************************************************************/
174 static int sql_num_fields(SQLSOCK * sqlsocket, SQL_CONFIG *config)
177 rlm_sql_db2_sock *sock;
179 sock = sqlsocket->conn;
180 SQLNumResultCols(sock->stmt, &c);
185 /*************************************************************************
187 * Function: sql_fetch_row
189 * Purpose: database specific fetch_row. Returns a SQL_ROW struct
190 * with all the data for the query in 'sqlsocket->row'. Returns
191 * 0 on success, -1 on failure, SQL_DOWN if 'database is down'
193 *************************************************************************/
194 static int sql_fetch_row(SQLSOCK * sqlsocket, SQL_CONFIG *config)
197 SQLINTEGER len, slen;
199 rlm_sql_db2_sock *sock;
201 sock = sqlsocket->conn;
203 c = sql_num_fields(sqlsocket, config);
204 retval = (SQL_ROW)rad_malloc(c*sizeof(char*)+1);
206 if(SQLFetch(sock->stmt) == SQL_NO_DATA_FOUND) {
207 sqlsocket->row = NULL;
211 for(i = 0; i < c; i++) {
212 /* get column length */
213 SQLColAttribute(sock->stmt,
214 i+1, SQL_DESC_DISPLAY_SIZE,
215 NULL, 0, NULL, &len);
216 retval[i] = (char*)rad_malloc(len+1);
217 /* get the actual column */
218 SQLGetData(sock->stmt,
219 i+1, SQL_C_CHAR, retval[i], len+1, &slen);
220 if(slen == SQL_NULL_DATA)
224 sqlsocket->row = retval;
228 /*************************************************************************
230 * Function: sql_free_result
232 * Purpose: database specific free_result. Frees memory allocated
235 *************************************************************************/
236 static int sql_free_result(SQLSOCK * sqlsocket, SQL_CONFIG *config)
238 rlm_sql_db2_sock *sock;
239 sock = sqlsocket->conn;
240 SQLFreeHandle(SQL_HANDLE_STMT, sock->stmt);
246 /*************************************************************************
248 * Function: sql_error
250 * Purpose: database specific error. Returns error associated with
253 *************************************************************************/
254 static char *sql_error(SQLSOCK * sqlsocket, SQL_CONFIG *config)
256 /* this should really be enough, if not, you still got the sqlstate */
263 rlm_sql_db2_sock *sock;
265 sock = sqlsocket->conn;
267 SQLGetDiagRec(SQL_HANDLE_STMT, sock->stmt,
268 1, sqlstate, &err, msg, MSGLEN, &rl);
269 retval = (char*)rad_malloc(strlen(msg)+20);
270 sprintf(retval, "SQLSTATE %s: %s", sqlstate, msg);
275 /*************************************************************************
277 * Function: sql_close
279 * Purpose: database specific close. Closes an open database
282 *************************************************************************/
283 static int sql_close(SQLSOCK * sqlsocket, SQL_CONFIG *config)
285 rlm_sql_db2_sock *sock;
287 sock = sqlsocket->conn;
289 SQLFreeHandle(SQL_HANDLE_DBC, sock->hdbc);
290 SQLFreeHandle(SQL_HANDLE_ENV, sock->henv);
295 /*************************************************************************
297 * Function: sql_finish_query
299 * Purpose: End the query, such as freeing memory
301 *************************************************************************/
302 static int sql_finish_query(SQLSOCK * sqlsocket, SQL_CONFIG *config)
309 /*************************************************************************
311 * Function: sql_finish_select_query
313 * Purpose: End the select query, such as freeing memory or result
315 *************************************************************************/
316 static int sql_finish_select_query(SQLSOCK * sqlsocket, SQL_CONFIG *config)
318 return sql_finish_query(sqlsocket, config);
322 /*************************************************************************
324 * Function: sql_affected_rows
326 * Purpose: Return the number of rows affected by the last query.
328 *************************************************************************/
329 static int sql_affected_rows(SQLSOCK * sqlsocket, SQL_CONFIG *config)
332 rlm_sql_db2_sock *sock;
334 sock = sqlsocket->conn;
336 SQLRowCount(sock->stmt, &c);
342 not_implemented(SQLSOCK * sqlsocket, SQL_CONFIG *config)
344 radlog(L_ERR, "sql_db2: calling unimplemented function");
349 /* Exported to rlm_sql */
350 rlm_sql_module_t rlm_sql_db2 = {
353 sql_destroy_socket, /* sql_destroy_socket*/
356 not_implemented, /* sql_store_result */
358 not_implemented, /* sql_num_rows */
364 sql_finish_select_query,