Ticket #129: authreg_oracle.c

File authreg_oracle.c, 24.5 KB (added by fundy, 16 months ago)

oracle认证模块(完全支持9i,其他版本未测试,哈哈)

Line 
1/*
2 * jabberd - Jabber Open Source Server
3 * Copyright (c) 2007 liulw
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA02111-1307USA
18 */
19
20/* this module talks to a Oracle server via libmysqlclient */
21
22#include "c2s.h"
23#include <string.h>
24#include <oci.h>
25
26//#define ORACLE_LU     1024   /* maximum length of username - should correspond to field length */
27//#define MYSQL_LR   256   /* maximum length of realm - should correspond to field length */
28//#define MYSQL_LP   256   /* maximum length of password - should correspond to field length */
29
30#define BLOCKSIZE (1024)
31
32typedef struct Oracle_context_st
33{
34        OCIEnv*         ociEnvironment;
35        OCIError*       ociError;
36        OCISvcCtx*      ociService;
37        OCIStmt*        ociStatement;
38        OCIDefine*      ociDefine;
39//      OCIBind*        ociBind;
40//      xht                      filters;
41//      char *prefix;
42//      char *svUser;
43//      char *svPass;
44        char*   sql_create;
45        char*   sql_select;
46        char*   sql_delete;
47        char*   sql_setpassword;
48        char*   sql_getzerok;
49        char*   sql_setzerok;
50} *Oracle_context_t;
51
52/** internal: do and return the math and ensure it gets realloc'd */
53static int _st_oracle_realloc(void **oblocks, int len)
54{
55        void *nblocks;
56        int nlen;
57
58        /* round up to standard block sizes */
59        nlen = (((len-1)/BLOCKSIZE)+1)*BLOCKSIZE;
60
61        /* keep trying till we get it */
62        while((nblocks = realloc(*oblocks, nlen)) == NULL) sleep(1);
63        *oblocks = nblocks;
64        return nlen;
65}
66
67#define ORACLE_SAFE(blocks, size, len) if((size) > len){ len = _st_oracle_realloc((void**)&(blocks),(size)); }
68
69int checkOCIError( authreg_t ar, char *szDoing, OCIError *m_ociError, sword nStatus )
70{
71        text txtErrorBuffer[512];
72        ub4 nErrorCode;
73
74        switch (nStatus)
75        {
76                case OCI_SUCCESS:
77                                break;
78                case OCI_SUCCESS_WITH_INFO:
79                                log_write(ar->c2s->log, LOG_ERR, "(%s) Error - OCI_SUCCESS_WITH_INFO\n", szDoing);
80                                break;
81                case OCI_NEED_DATA:
82                                log_write(ar->c2s->log, LOG_ERR, "(%s) Error - OCI_NEED_DATA\n", szDoing);
83                                break;
84                case OCI_NO_DATA:
85                                log_write(ar->c2s->log, LOG_ERR, "(%s) Error - OCI_NODATA\n", szDoing);
86                                break;
87                case OCI_ERROR:
88                                OCIErrorGet(m_ociError, (ub4) 1, (text *) NULL, &nErrorCode, txtErrorBuffer, (ub4) sizeof(txtErrorBuffer), OCI_HTYPE_ERROR);
89                                log_write(ar->c2s->log, LOG_ERR, "(%s) Error - %s\n", szDoing, txtErrorBuffer);
90                                break;
91                case OCI_INVALID_HANDLE:
92                                log_write(ar->c2s->log, LOG_ERR, "(%s) Error - OCI_INVALID_HANDLE\n", szDoing);
93                                break;
94                case OCI_STILL_EXECUTING:
95                                log_write(ar->c2s->log, LOG_ERR, "(%s) Error - OCI_STILL_EXECUTE\n", szDoing);
96                                break;
97                default:
98                                break;
99        }
100
101        return nStatus;
102}
103
104static int oracle_ping( authreg_t ar )
105{
106        Oracle_context_t odpOracleDriver = (Oracle_context_t)ar->private;
107
108        // Prepare the check statement
109        int nResultCode = OCIStmtPrepare(odpOracleDriver->ociStatement, odpOracleDriver->ociError,
110                                        "select sysdate from dual", (ub4) 24, OCI_NTV_SYNTAX,
111                                        OCI_DEFAULT);
112
113        // This is the real check
114        nResultCode = OCIStmtExecute(odpOracleDriver->ociService, odpOracleDriver->ociStatement, odpOracleDriver->ociError,
115                                        (ub4) 0, (ub4) 0,
116                                        (CONST OCISnapshot *) NULL, (OCISnapshot *) NULL,
117                                        OCI_DESCRIBE_ONLY );
118
119
120        // If there was an error...
121        if (nResultCode != 0)
122        {
123                char szErrorBuffer[250];
124                char *svHost, *svUser, *svPass;
125
126                OCIErrorGet((dvoid *)odpOracleDriver->ociError, (ub4) 1, (text *) NULL, &nResultCode, szErrorBuffer, (ub4) sizeof(szErrorBuffer), OCI_HTYPE_ERROR);
127                log_write(ar->c2s->log, LOG_ERR, "storage_oracle.c (oracle_ping): %s", szErrorBuffer);
128
129                // Obtain user configuration
130                svHost = config_get_one(ar->c2s->config, "storage.oracle.host", 0);
131                svUser = config_get_one(ar->c2s->config, "storage.oracle.user", 0);
132                svPass = config_get_one(ar->c2s->config, "storage.oracle.pass", 0);
133
134                // Logon to the database
135                nResultCode = OCILogon((dvoid *)odpOracleDriver->ociEnvironment, (dvoid *)odpOracleDriver->ociError, &(odpOracleDriver->ociService), svUser, strlen(svUser), svPass, strlen(svPass), svHost, strlen(svHost));
136
137                if (nResultCode != 0)
138                {
139                        OCIErrorGet((dvoid *)odpOracleDriver->ociError, (ub4) 1, (text *) NULL, &nResultCode, szErrorBuffer, (ub4) sizeof(szErrorBuffer), OCI_HTYPE_ERROR);
140                        log_write(ar->c2s->log, LOG_ERR, "storage_oracle.c (oracle_ping): %s", szErrorBuffer);
141                }
142        }
143
144        return nResultCode;
145}
146
147static int _sql_length( char* sql )
148{
149        const char* _pt = sql;
150        int _num = 0;
151       
152        while( *_pt != '\0' )
153        {
154                if( *_pt == '"' )++_num;
155                ++_pt;
156        }
157
158        return (strlen(sql) - _num);
159}
160
161static int _ar_oracle_get_user_tuple( authreg_t ar, char* username, char* realm )
162{
163    Oracle_context_t _ctx = (Oracle_context_t)ar->private;
164        char* _sqlbuf = NULL;
165        int _nNumberOfFields = 0;
166        int _nResultCode = 0;
167        int _len = 0;
168        char _password[64] = { '\0' };
169        char _hash[41] = { '\0' };
170        char _token[11] = { '\0' };
171        int _sequence = 0;
172
173        ORACLE_SAFE( _sqlbuf, strlen(username) + strlen(realm) + _sql_length(_ctx->sql_select), _len );
174        sprintf( _sqlbuf, _ctx->sql_select, username, realm );
175//      fprintf( stdout, "_sqlbuf = %s\n", _sqlbuf );
176        _nResultCode = checkOCIError( ar, "_ar_oracle_get_user_tuple: prepare statement", _ctx->ociError, OCIStmtPrepare( _ctx->ociStatement, \
177                                                                                                                                _ctx->ociError, _sqlbuf, strlen(_sqlbuf), OCI_NTV_SYNTAX, OCI_DEFAULT ) );
178        if( _nResultCode != 0 )
179        {
180                fprintf( stdout, "OCIStmtPrepare\n" );
181                free( _sqlbuf );
182                return 1;
183        }
184
185        _nResultCode = checkOCIError(ar, "_ar_oracle_get_user_tuple:define pos", _ctx->ociError, OCIDefineByPos( _ctx->ociStatement, \
186                                                        &_ctx->ociDefine, _ctx->ociError, 1, &_password, 65, SQLT_STR, 0, 0, 0, OCI_DEFAULT ) );
187        _nResultCode = checkOCIError(ar, "_ar_oracle_get_user_tuple:define pos", _ctx->ociError, OCIDefineByPos( _ctx->ociStatement, \
188                                                        &_ctx->ociDefine, _ctx->ociError, 2, &_hash, 42, SQLT_STR, 0, 0, 0, OCI_DEFAULT ) );
189        _nResultCode = checkOCIError(ar, "_ar_oracle_get_user_tuple:define pos", _ctx->ociError, OCIDefineByPos( _ctx->ociStatement, \
190                                                        &_ctx->ociDefine, _ctx->ociError, 3, &_token, 12, SQLT_STR, 0, 0, 0, OCI_DEFAULT ) );
191        _nResultCode = checkOCIError(ar, "_ar_oracle_get_user_tuple:define pos", _ctx->ociError, OCIDefineByPos( _ctx->ociStatement, \
192                                                        &_ctx->ociDefine, _ctx->ociError, 4, &_sequence, sizeof(int), SQLT_INT, 0, 0, 0, OCI_DEFAULT ) );
193
194        if( _nResultCode != 0 )
195        {
196                fprintf( stdout, "OCIDefineByPos\n" );
197                free( _sqlbuf );
198                return 1;
199        }
200       
201        _nResultCode = checkOCIError( ar, "_ar_oracle_get_user_tuple:execse", _ctx->ociError, OCIStmtExecute( _ctx->ociService, \
202                                                                                                                        _ctx->ociStatement, _ctx->ociError, 0, 0, 0, 0, OCI_STMT_SCROLLABLE_READONLY ) );
203        if( _nResultCode != 0 )
204        {
205                fprintf( stdout, "OCIStmtExecute\n" );
206                free( _sqlbuf );
207                return 1;
208        }
209
210        OCIStmtFetch2( _ctx->ociStatement, _ctx->ociError, 1, OCI_FETCH_FIRST, 0, OCI_DEFAULT);
211        free( _sqlbuf );
212
213        if( strlen(_password) != 0 )return 1;
214        else return 0;
215}
216
217static int _ar_oracle_user_exists(authreg_t ar, char *username, char *realm)
218{
219    if( _ar_oracle_get_user_tuple(ar, username, realm ) > 0 )
220        {
221                return 1;
222        }
223
224    return 0;
225}
226
227static int _ar_oracle_create_user( authreg_t ar, char *username, char *realm )
228{
229    Oracle_context_t _ctx = (Oracle_context_t)ar->private;
230        char* _sqlbuf = NULL;
231        int _len = 0;
232        int _nResultCode = 0;
233        int errcode;
234        char errbuf[512];
235
236        ORACLE_SAFE( _sqlbuf, strlen(username) + strlen(realm) + _sql_length(_ctx->sql_create), _len );
237        sprintf( _sqlbuf, _ctx->sql_create, username, realm );
238        _nResultCode = checkOCIError( ar, "_ar_oracle_create_user:prepare", _ctx->ociError, OCIStmtPrepare( _ctx->ociStatement, _ctx->ociError,\
239                                                        _sqlbuf, (ub4)strlen(_sqlbuf), OCI_NTV_SYNTAX, OCI_DEFAULT ) );
240        if( _nResultCode != 0 )
241        {
242                return -1;
243        }
244
245        _nResultCode = checkOCIError( ar, "_ar_oracle_create_user:execute", _ctx->ociError, OCIStmtExecute( _ctx->ociService, _ctx->ociStatement, _ctx->ociError, 1, 0, 0, 0, OCI_DEFAULT ) );
246        if( _nResultCode != 0 )
247        {
248                  OCIErrorGet((dvoid *)_ctx->ociError, (ub4)1, (text *)NULL, &errcode, 
249                                                  errbuf, (ub4)sizeof(errbuf), OCI_HTYPE_ERROR);
250                  fprintf(stdout, "%.*s\n", 512, errbuf);
251                fprintf( stdout, "eaarror..\n" );
252                return -1;
253        }
254
255        return 0;
256}
257
258int _ar_oracle_get_authreg_user( authreg_t ar )
259{
260    Oracle_context_t _ctx = (Oracle_context_t)ar->private;
261        char _sql[] = { "select count(*) from \"authreg\"" };
262        int _nNumberOfFields = 0;
263        int _nResultCode = 0;
264
265        /*start action via oracle*/
266        _nResultCode = checkOCIError( ar, "_st_oracle_get: prepare statement", _ctx->ociError, OCIStmtPrepare( _ctx->ociStatement, _ctx->ociError,\
267                                                        _sql, (ub4)strlen(_sql), OCI_NTV_SYNTAX, OCI_DEFAULT ) );
268        if( _nResultCode != 0 )
269        {
270                return -1;
271        }
272
273        _nResultCode = checkOCIError( ar, "_st_oracle_get: Define pos", _ctx->ociError, OCIDefineByPos( _ctx->ociStatement, &_ctx->ociDefine, \
274                                                        _ctx->ociError, 1, (dvoid*)&_nNumberOfFields, sizeof(_nNumberOfFields), SQLT_INT, 0, 0, 0, OCI_DEFAULT ) );
275        if( _nResultCode != 0 )
276        {
277                return -1;
278        }
279
280        _nResultCode = checkOCIError( ar, "_st_oracle_get: Statement descript", _ctx->ociError, OCIStmtExecute( _ctx->ociService, \
281                                                        _ctx->ociStatement, _ctx->ociError, 0, 0, 0, 0, OCI_STMT_SCROLLABLE_READONLY ) );
282        if( _nResultCode != 0 )
283        {
284                return -1;
285        }
286
287        _nResultCode = checkOCIError( ar, "", _ctx->ociError, OCIStmtFetch2( _ctx->ociStatement, _ctx->ociError, 1, OCI_FETCH_FIRST, 0, \
288                                                                                                                                                                                                                                        OCI_DEFAULT ) );
289        if( _nResultCode != 0 )
290        {
291                return -1;
292        }
293
294        return _nNumberOfFields;
295}
296
297
298static int _ar_oracle_get_password( authreg_t ar, char *username, char *realm, char password[257] )
299{
300    Oracle_context_t _ctx = (Oracle_context_t)ar->private;
301        char* _sqlbuf = NULL;
302        int _nNumberOfFields = 0;
303        int _nResultCode = 0;
304        int _len = 0;
305        char _password[257];
306        memset( _password, '\0', sizeof(_password) );
307        ORACLE_SAFE( _sqlbuf, strlen(username) + strlen(realm) + _sql_length(_ctx->sql_select), _len );
308        sprintf( _sqlbuf, _ctx->sql_select, username, realm );
309
310        _nResultCode = checkOCIError( ar, "_ar_oracle_get_user_tuple: prepare statement", _ctx->ociError, OCIStmtPrepare( _ctx->ociStatement, \
311                                                                                                                                _ctx->ociError, _sqlbuf, strlen(_sqlbuf), OCI_NTV_SYNTAX, OCI_DEFAULT ) );
312        if( _nResultCode != 0 )
313        {
314                free( _sqlbuf );
315                return -1;
316        }
317
318        _nResultCode = checkOCIError(ar, "_ar_oracle_get_user_tuple:define pos", _ctx->ociError, OCIDefineByPos( _ctx->ociStatement, \
319                                                                        &_ctx->ociDefine, _ctx->ociError, 1, &_password, 257, SQLT_STR, 0, 0, 0, OCI_DEFAULT ) );
320        if( _nResultCode != 0 )
321        {
322                free( _sqlbuf );
323                return -1;
324        }
325       
326        _nResultCode = checkOCIError( ar, "_ar_oracle_get_user_tuple:execse", _ctx->ociError, OCIStmtExecute( _ctx->ociService, \
327                                                                                                                        _ctx->ociStatement, _ctx->ociError, 0, 0, 0, 0, OCI_STMT_SCROLLABLE_READONLY ) );
328        if( _nResultCode != 0 )
329        {
330                free( _sqlbuf );
331                return -1;
332        }
333
334        OCIStmtFetch2( _ctx->ociStatement, _ctx->ociError, 1, OCI_FETCH_FIRST, 0, OCI_DEFAULT ); 
335        free( _sqlbuf );
336       
337        if( strlen(_password)  != 0 )strncpy( password, _password, strlen(_password) );
338
339        return 0;
340}
341
342static int _ar_oracle_set_password(authreg_t ar, char *username, char *realm, char password[257])
343{
344        Oracle_context_t _ctx = (Oracle_context_t)ar->private;
345        char* _sqlbuf = NULL;
346        int _len = 0;
347        int _nResultCode = 0;
348
349        ORACLE_SAFE( _sqlbuf, strlen(username) + strlen(realm) + strlen(password) + _sql_length(_ctx->sql_setpassword), _len );
350        sprintf( _sqlbuf, _ctx->sql_setpassword, password, username, realm );
351
352        _nResultCode = checkOCIError( ar, "_ar_oracle_set_password:prepare", _ctx->ociError, OCIStmtPrepare( _ctx->ociStatement, _ctx->ociError,\
353                                                        _sqlbuf, (ub4)strlen(_sqlbuf), OCI_NTV_SYNTAX, OCI_DEFAULT ) );
354        if( _nResultCode != 0 )
355        {
356                return -1;
357        }
358
359        _nResultCode = checkOCIError( ar, "_ar_oracle_set_password:execute", _ctx->ociError, OCIStmtExecute( _ctx->ociService, \
360                                                        _ctx->ociStatement, _ctx->ociError, 1, 0, 0, 0, OCI_DEFAULT ) );
361        if( _nResultCode != 0 )
362        {
363                fprintf( stdout, "error \n" );
364                return -1;
365        }
366
367        return 0;
368}
369
370static int _ar_oracle_get_zerok(authreg_t ar, char *username, char *realm, char hash[41], char token[11], int *sequence)
371{
372        Oracle_context_t _ctx = (Oracle_context_t)ar->private;
373        char* _sqlbuf = NULL;
374        int _len = 0;
375        int _nResultCode = 0;
376        char _hash[41]; char _token[11]; int _sequence = 0;
377       
378        memset( _hash, '\0', sizeof(_hash) );
379        memset( _token, '\0', sizeof(_token) );
380       
381        ORACLE_SAFE( _sqlbuf, strlen(username) + strlen(realm) + _sql_length(_ctx->sql_getzerok), _len );
382        sprintf( _sqlbuf, _ctx->sql_getzerok, username, realm );
383
384        _nResultCode = checkOCIError( ar, "_ar_oracle_get_zerok:prepare", _ctx->ociError, OCIStmtPrepare( _ctx->ociStatement, _ctx->ociError, \
385                                                        _sqlbuf, (ub4)strlen(_sqlbuf), OCI_NTV_SYNTAX, OCI_DEFAULT ) );
386        if( _nResultCode != 0 )
387        {
388                return -1;
389        }
390        //definebypos
391        _nResultCode = checkOCIError( ar, "_ar_oracle_get_zerok:definebypos-hash", _ctx->ociError, OCIDefineByPos( _ctx->ociStatement, \
392                                                        &_ctx->ociDefine, _ctx->ociError, 1, &_hash, 41, SQLT_STR, 0, 0, 0, OCI_DEFAULT ) );
393        _nResultCode = checkOCIError( ar, "_ar_oracle_get_zerok:definebypos-token", _ctx->ociError, OCIDefineByPos( _ctx->ociStatement, \
394                                                        &_ctx->ociDefine, _ctx->ociError, 2, &_token, 11, SQLT_STR, 0, 0, 0, OCI_DEFAULT ) );
395        _nResultCode = checkOCIError( ar, "_ar_oracle_get_zerok:definebypos-sequence", _ctx->ociError, OCIDefineByPos( _ctx->ociStatement, \
396                                                        &_ctx->ociDefine, _ctx->ociError, 3, &_sequence, sizeof(int), SQLT_INT, 0, 0, 0, OCI_DEFAULT ) );
397
398        //execute
399        _nResultCode = checkOCIError( ar, "_ar_oracle_get_zerok:execute", _ctx->ociError, OCIStmtExecute( _ctx->ociService, \
400                                                        _ctx->ociStatement, _ctx->ociError, 1, 0, 0, 0, OCI_STMT_SCROLLABLE_READONLY ) );
401        if( _nResultCode != 0 )
402        {
403                return -1;
404        }
405       
406        OCIStmtFetch2( _ctx->ociStatement, _ctx->ociError, 1, OCI_FETCH_FIRST, 0, OCI_DEFAULT ); 
407        if( strlen(_hash) != 0 ) strncpy( hash, _hash, strlen(_hash) );
408        if( strlen(_token) != 0 ) strncpy( token, _token, strlen(_token) );
409        *sequence = _sequence;
410
411        return 0;
412}
413
414static int _ar_oracle_set_zerok(authreg_t ar, char *username, char *realm, char hash[41], char token[11], int sequence)
415{
416        Oracle_context_t _ctx = (Oracle_context_t)ar->private;
417        char* _sqlbuf = NULL;
418        int _len = 0;
419        int _nResultCode = 0;
420
421        ORACLE_SAFE( _sqlbuf, strlen(username) + strlen(realm) + strlen(hash) + strlen(token) + 10 + _sql_length(_ctx->sql_setzerok), _len );
422        sprintf( _sqlbuf, _ctx->sql_setzerok, hash, token, sequence, username, realm );
423
424        _nResultCode = checkOCIError( ar, "_ar_oracle_set_zerok:prepare", _ctx->ociError, OCIStmtPrepare( _ctx->ociStatement, _ctx->ociError,\
425                                                        _sqlbuf, (ub4)strlen(_sqlbuf), OCI_NTV_SYNTAX, OCI_DEFAULT ) );
426        if( _nResultCode != 0 )
427        {
428                return -1;
429        }
430
431        _nResultCode = checkOCIError( ar, "_ar_oracle_set_zerok:execute", _ctx->ociError, OCIStmtExecute( _ctx->ociService, \
432                                                        _ctx->ociStatement, _ctx->ociError, 1, 0, 0, 0, OCI_COMMIT_ON_SUCCESS ) );
433        if( _nResultCode != 0 )
434        {
435                return -1;
436        }
437
438        return 0;
439}
440
441static int _ar_oracle_delete_user(authreg_t ar, char *username, char *realm)
442{
443        if( _ar_oracle_get_user_tuple(ar, username, realm ) == 0 )return 0;
444
445    Oracle_context_t _ctx = (Oracle_context_t)ar->private;
446        char* _sqlbuf = NULL;
447        int _len = 0;
448        int _nResultCode = 0;
449
450        ORACLE_SAFE( _sqlbuf, strlen(username) + strlen(realm) + _sql_length(_ctx->sql_delete), _len );
451        sprintf( _sqlbuf, _ctx->sql_delete, username, realm );
452
453        _nResultCode = checkOCIError( ar, "_ar_oracle_delete_user:prepare", _ctx->ociError, OCIStmtPrepare( _ctx->ociStatement, _ctx->ociError,\
454                                                                                                                                                _sqlbuf, (ub4)strlen(_sqlbuf), OCI_NTV_SYNTAX, OCI_DEFAULT ) );
455        if( _nResultCode != 0 )
456        {
457                return -1;
458        }
459
460        _nResultCode = checkOCIError( ar, "_ar_oracle_delete_user:execute", _ctx->ociError, OCIStmtExecute( _ctx->ociService, \
461                                                                                                                        _ctx->ociStatement, _ctx->ociError, 1, 0, 0, 0, OCI_COMMIT_ON_SUCCESS ) );
462        if( _nResultCode != 0 )
463        {
464                return -1;
465        }
466
467        return 0;
468}
469
470static void _ar_oracle_free( authreg_t ar )
471{
472    Oracle_context_t ctx = (Oracle_context_t)ar->private;
473
474        OCILogoff(      ctx->ociService, ctx->ociError );
475        OCIHandleFree( (dvoid *)ctx->ociStatement, OCI_HTYPE_STMT );
476        OCIHandleFree( (dvoid *)ctx->ociService, OCI_HTYPE_SVCCTX );
477        OCIHandleFree( (dvoid *)ctx->ociError, OCI_HTYPE_ERROR );
478        OCIHandleFree( (dvoid *)ctx->ociEnvironment, OCI_HTYPE_ENV );
479
480        free(ctx);
481}
482
483/** Provide a configuration parameter or default value. */
484static char * _ar_oracle_param( config_t c, char * key, char * def ) {
485    char * value = config_get_one( c, key, 0 );
486    if( value == NULL )
487      return def;
488    else
489      return value;
490}
491
492/** start me up */
493int ar_init(authreg_t ar) {
494    char *host, *port, *dbname, *user, *pass, *oracle_server_host = NULL;
495    char *create, *select, *setpassword, *setzerok, *getzerok, *delete;
496    char table[] = { "\"authreg\"" };
497        char username[] = { "\"username\"" };
498        char realm[] = { "\"realm\"" };
499        char password[] = { "\"password\"" };
500        char token[] = { "\"token\"" };
501        char sequence[] = { "\"sequence\"" };
502        char hash[] = { "\"hash\"" };
503        int nResultCode = 0, _len = 0;
504        static char* oracle_server_parameters = "(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=\"%s\")(PORT=\"%s\"))(CONNECT_DATA=(SID=\"%s\")))";
505        Oracle_context_t oraclecontext;
506
507        OCIEnv     *ociEnvironment;
508        OCIError   *ociError;
509        OCISvcCtx  *ociService;
510        OCIStmt    *ociStatement;
511
512        /* configure the database context with field names and SQL statements */
513        oraclecontext = (Oracle_context_t)malloc( sizeof( struct Oracle_context_st ) );
514        ar->private = oraclecontext;
515        ar->free = _ar_oracle_free;
516
517        /* craft the default SQL statements */
518        /* we leave unused statements allocated to simplify code - a small price to pay */
519        /* bounds checking and parameter format verification will be perfomed if the statement is used (see next section) */
520        /* For malloc(), there is no +1 for trailing 0 as parameter substitution will net us several extra characters */
521
522        create = strdup( "INSERT INTO \"authreg\" ( \"username\", \"realm\" ) VALUES ( '%s', '%s' )" );
523
524        select = strdup( "SELECT \"password\",\"hash\",\"token\",\"sequence\" FROM \"authreg\" WHERE \"username\" = '%s' AND \"realm\" = '%s'" );
525
526        setpassword = strdup( "UPDATE \"authreg\" SET \"password\" = '%s' WHERE \"username\" = '%s' AND \"realm\" = '%s'" );
527
528        getzerok = strdup( "select \"\", \"\", \"\" FROM \"authreg\" WHERE \"username\" = '%s' AND \"realm\" = '%s'" );
529
530        setzerok = strdup( "UPDATE \"authreg\" SET \"hash\" = '%s', \"token\" = '%s', \"sequence\" = '%d'  WHERE \"username\" = '%s' AND \"realm\" = '%s'" );
531
532        delete = strdup( "DELETE FROM \"authreg\" WHERE \"username\" = '%s' AND \"realm\" = '%s'" );
533
534        /* allow the default SQL statements to be overridden; also verify the statements format and length */
535        oraclecontext->sql_create = strdup(_ar_oracle_param( ar->c2s->config
536                                                        , "authreg.oracle.sql.create"
537                                                        , create ));
538
539        oraclecontext->sql_select = strdup(_ar_oracle_param( ar->c2s->config
540                                                        , "authreg.oracle.sql.select"
541                                                        , select ));
542
543        oraclecontext->sql_setpassword = strdup(_ar_oracle_param( ar->c2s->config
544                                                        , "authreg.oracle.sql.setpassword"
545                                                        , setpassword ));
546
547        oraclecontext->sql_getzerok = strdup(_ar_oracle_param( ar->c2s->config
548                                                        , "authreg.oracle.sql.getzerok"
549                                                        , getzerok ));
550
551        oraclecontext->sql_setzerok = strdup(_ar_oracle_param( ar->c2s->config
552                                                        , "authreg.oracle.sql.setzerok"
553                                                        , setzerok ));
554
555        oraclecontext->sql_delete = strdup(_ar_oracle_param( ar->c2s->config
556                                                        , "authreg.oracle.sql.delete"
557                                                        , delete ));
558
559        /* echo our configuration to debug */
560        log_debug( ZONE, "SQL to create account: %s", oraclecontext->sql_create );
561        log_debug( ZONE, "SQL to query user information: %s", oraclecontext->sql_select );
562        log_debug( ZONE, "SQL to set password: %s", oraclecontext->sql_setpassword );
563        log_debug( ZONE, "SQL to set zero K: %s", oraclecontext->sql_setzerok );
564        log_debug( ZONE, "SQL to delete account: %s", oraclecontext->sql_delete );
565
566        free(create);
567        free(select);
568        free(setpassword);
569        free(getzerok);
570        free(setzerok);
571        free(delete);
572
573        host = config_get_one(ar->c2s->config, "authreg.oracle.host", 0);
574        port = config_get_one(ar->c2s->config, "authreg.oracle.port", 0);
575        dbname = config_get_one(ar->c2s->config, "authreg.oracle.dbname", 0);
576        user = config_get_one(ar->c2s->config, "authreg.oracle.user", 0);
577        pass = config_get_one(ar->c2s->config, "authreg.oracle.pass", 0);
578
579        if(host == NULL || port == NULL || dbname == NULL || user == NULL || pass == NULL) {
580                        log_write(ar->c2s->log