be3bac11337edb63bde1550694e23baf9da3d7a7
[freeradius.git] / src / modules / rlm_sql / drivers / rlm_sql_iodbc / sql_iodbc.c
1 /***************************************************************************
2 *  iODBC support for FreeRadius
3 *  www.iodbc.org   - iODBC info
4 *  Jeff Carneal    - Author
5 ***************************************************************************/
6 #include <stdio.h>
7 #include <sys/stat.h>
8 #include <stdlib.h>
9 #include <string.h>
10
11 #include        "radiusd.h"
12 #include        "rlm_sql.h"
13
14 /*************************************************************************
15  *
16  *      Function: sql_create_socket
17  *
18  *      Purpose: Establish connection to the db
19  *
20  *************************************************************************/
21 SQLSOCK *sql_create_socket(SQL_INST *inst)
22 {
23         SQLSOCK *socket;
24
25         if((socket = malloc(sizeof(SQLSOCK))) == NULL) {
26                 radlog(L_CONS|L_ERR, "sql_create_socket: no memory");
27                 exit(1);
28         }
29
30         if(SQLAllocEnv(&socket->env_handle) != SQL_SUCCESS) {
31                 radlog(L_CONS|L_ERR, "sql_create_socket: SQLAllocEnv failed:  %s", 
32                                 sql_error(socket));
33                 exit(1);
34         }
35
36         if(SQLAllocConnect(socket->env_handle, &socket->dbc_handle) != SQL_SUCCESS) {
37                 radlog(L_CONS|L_ERR, "sql_create_socket: SQLAllocConnect failed:  %s", 
38                                 sql_error(socket));
39                 exit(1);
40         }
41
42         if (SQLConnect(socket->dbc_handle, inst->config->sql_db, SQL_NTS, 
43                                 inst->config->sql_login, SQL_NTS, inst->config->sql_password, 
44                                 SQL_NTS) != SQL_SUCCESS) {
45                 radlog(L_CONS|L_ERR, "sql_create_socket: SQLConnectfailed:  %s", 
46                                 sql_error(socket));
47                 exit(1);
48         }
49
50         if(SQLAllocStmt(socket->dbc_handle, &socket->stmt_handle) != SQL_SUCCESS) {
51                 radlog(L_CONS|L_ERR, "sql_create_socket: SQLAllocStmt failed:  %s", 
52                                 sql_error(socket));
53                 exit(1);
54         }
55
56         return socket;
57 }
58
59 /*************************************************************************
60  *
61  *      Function: sql_query
62  *
63  *      Purpose: Issue a non-SELECT query (ie: update/delete/insert) to
64  *               the database.
65  *
66  *************************************************************************/
67 int sql_query(SQL_INST *inst, SQLSOCK *socket, char *querystr)
68 {
69         if (inst->config->sqltrace)
70                 DEBUG(querystr);
71         if (socket->dbc_handle == NULL) {
72                 radlog(L_ERR, "sql_query:  Socket not connected");
73                 return 0;
74         }
75
76         if(SQLExecDirect(socket->stmt_handle, querystr, SQL_NTS) != SQL_SUCCESS) {
77                 radlog(L_CONS|L_ERR, "sql_query: failed:  %s", 
78                                 sql_error(socket));
79                 return -1;
80         }
81
82         return 0;
83 }
84
85
86 /*************************************************************************
87  *
88  *      Function: sql_select_query
89  *
90  *      Purpose: Issue a select query to the database
91  *
92  *************************************************************************/
93 int sql_select_query(SQL_INST *inst, SQLSOCK *socket, char *querystr)
94 {
95         return 0;
96 }
97
98
99 /*************************************************************************
100  *
101  *      Function: sql_store_result
102  *
103  *      Purpose: database specific store_result function. Returns a result
104  *               set for the query.
105  *
106  *************************************************************************/
107 int sql_store_result(SQLSOCK *socket) {
108         return 0;
109 }
110
111
112 /*************************************************************************
113  *
114  *      Function: sql_num_fields
115  *
116  *      Purpose: database specific num_fields function. Returns number
117  *               of columns from query
118  *
119  *************************************************************************/
120 int sql_num_fields(SQLSOCK *socket) {
121         return 0;
122 }
123
124 /*************************************************************************
125  *
126  *      Function: sql_num_rows
127  *
128  *      Purpose: database specific num_rows. Returns number of rows in
129  *               query
130  *
131  *************************************************************************/
132 int sql_num_rows(SQLSOCK *socket) {
133         return 0;
134 }
135
136
137 /*************************************************************************
138  *
139  *      Function: sql_fetch_row
140  *
141  *      Purpose: database specific fetch_row. Returns a SQL_ROW struct
142  *               with all the data for the query
143  *
144  *************************************************************************/
145 SQL_ROW sql_fetch_row(SQLSOCK *socket)
146 {
147         return 0;
148 }
149
150
151
152 /*************************************************************************
153  *
154  *      Function: sql_free_result
155  *
156  *      Purpose: database specific free_result. Frees memory allocated
157  *               for a result set
158  *
159  *************************************************************************/
160 void sql_free_result(SQLSOCK *socket) {
161 }
162
163
164
165 /*************************************************************************
166  *
167  *      Function: sql_error
168  *
169  *      Purpose: database specific error. Returns error associated with
170  *               connection
171  *
172  *************************************************************************/
173 char *sql_error(SQLSOCK *socket)
174 {
175         SQLINTEGER errornum = 0;
176         SQLSMALLINT length = 0;
177         SQLCHAR state[256] = "";
178         static SQLCHAR error[256] = "";
179
180         SQLError(socket->env_handle, socket->dbc_handle, socket->stmt_handle, 
181                 state, &errornum, error, 256, &length);
182         return error;
183 }
184
185
186 /*************************************************************************
187  *
188  *      Function: sql_close
189  *
190  *      Purpose: database specific close. Closes an open database
191  *               connection and cleans up any open handles.
192  *
193  *************************************************************************/
194 void sql_close(SQLSOCK *socket)
195 {
196
197         SQLFreeStmt(socket->stmt_handle, SQL_DROP);
198         SQLDisconnect(socket->dbc_handle);
199         SQLFreeConnect(socket->dbc_handle);
200         SQLFreeEnv(socket->env_handle);
201
202         socket->stmt_handle = NULL;
203         socket->dbc_handle = NULL;
204         socket->env_handle = NULL;
205 }
206
207
208 /*************************************************************************
209  *
210  *      Function: sql_finish_query
211  *
212  *      Purpose: End the query, such as freeing memory
213  *
214  *************************************************************************/
215 void sql_finish_query(SQLSOCK *socket)
216 {
217 }
218
219
220
221 /*************************************************************************
222  *
223  *      Function: sql_finish_select_query
224  *
225  *      Purpose: End the select query, such as freeing memory or result
226  *
227  *************************************************************************/
228 void sql_finish_select_query(SQLSOCK *socket)
229 {
230 }
231
232
233 /*************************************************************************
234  *
235  *      Function: sql_affected_rows
236  *
237  *      Purpose: Return the number of rows affected by the query (update,
238  *               or insert)
239  *
240  *************************************************************************/
241 int sql_affected_rows(SQLSOCK *socket) {
242         SQLINTEGER count;
243
244         SQLRowCount(socket->stmt_handle, &count);
245         return (int)count;
246 }
247
248
249 /*************************************************************************
250  *
251  *      Function: sql_escape_string
252  *
253  *      Purpose: Esacpe "'" and any other wierd charactors
254  *
255  *************************************************************************/
256 int sql_escape_string(char *to, char *from, int length)
257 {
258         int x, y;
259
260         for(x=0, y=0; (x < length) && (from[x]!='\0'); x++) {
261     switch (from[x]) {
262     case 0:                             
263       to[y++]= '\\';
264       to[y++]= '0';
265       break;
266     case '\n':                          
267       to[y++]= '\\';
268       to[y++]= 'n';
269       break;
270     case '\r':
271       to[y++]= '\\';
272       to[y++]= 'r';
273       break;
274     case '\\':
275       to[y++]= '\\';
276       to[y++]= '\\';
277       break;
278     case '\'':
279       to[y++]= '\\';
280       to[y++]= '\'';
281       break;
282     case '"':                           
283       to[y++]= '\\';
284       to[y++]= '"';
285       break;
286     case '\032':                        
287       to[y++]= '\\';
288       to[y++]= 'Z';
289       break;
290     default:
291       to[y++]= from[x];
292     }
293   }
294         to[y]=0;
295
296         return 1;
297 }
298