root/trunk/pdns/modules/opendbxbackend/odbxprivate.cc @ 977

Revision 977, 6.0 KB (checked in by ahu, 6 years ago)

ldap, opendbx updates

Line 
1#include "odbxbackend.hh"
2
3
4
5unsigned int odbx_host_index[2] = { 0, 0 };
6
7
8
9bool OdbxBackend::connectTo( const vector<string>& hosts, QueryType type )
10{
11        int err;
12        unsigned int h, i;
13        int idx = odbx_host_index[type]++ % hosts.size();
14
15
16        if( m_handle[type] != NULL )
17        {
18                odbx_unbind( m_handle[type] );
19                odbx_finish( m_handle[type] );
20                m_handle[type] = NULL;
21        }
22
23        for( i = 0; i < hosts.size(); i++ )
24        {
25                h = ( idx + i ) % hosts.size();
26
27                if( ( err = odbx_init( &(m_handle[type]), getArg( "backend" ).c_str(), hosts[h].c_str(), getArg( "port" ).c_str() ) ) == ODBX_ERR_SUCCESS )
28                {
29                        if( ( err = odbx_bind( m_handle[type], getArg( "database" ).c_str(), getArg( "username" ).c_str(), getArg( "password" ).c_str(), ODBX_BIND_SIMPLE ) ) == ODBX_ERR_SUCCESS )
30                        {
31                                L.log( m_myname + " Database connection (" + (type ? "write" : "read") + ") to '" + hosts[h] + "' succeeded", Logger::Notice );
32                                return true;
33                        }
34
35                        L.log( m_myname + " Unable to bind to database on host " + hosts[h] + " - " + string( odbx_error( m_handle[type], err ) ),  Logger::Error );
36                        continue;
37                }
38
39                L.log( m_myname + " Unable to connect to server on host " + hosts[h] + " - " + string( odbx_error( m_handle[type], err ) ),  Logger::Error );
40        }
41
42        m_handle[type] = NULL;
43        return false;
44}
45
46
47
48bool OdbxBackend::execStmt( const char* stmt, unsigned long length, QueryType type )
49{
50        int err;
51
52
53        DLOG( L.log( m_myname + " execStmt()", Logger::Debug ) );
54
55        if( m_qlog ) { L.log( m_myname + " Query: " + stmt, Logger::Info ); }
56
57        if( ( err = odbx_query( m_handle[type], stmt, length ) ) < 0 )
58        {
59                L.log( m_myname + " execStmt: Unable to execute query - " + string( odbx_error( m_handle[type], err ) ),  Logger::Error );
60
61                if( err != -ODBX_ERR_PARAM && odbx_error_type( m_handle[type], err ) > 0 ) { return false; }   // ODBX_ERR_PARAM workaround
62                if( !connectTo( m_hosts[type], type ) ) { return false; }
63                if( odbx_query( m_handle[type], stmt, length ) < 0 ) { return false; }
64        }
65
66        if( type == WRITE ) { while( getRecord( type ) ); }
67
68        return true;
69}
70
71
72
73bool OdbxBackend::getRecord( QueryType type )
74{
75        int err = 3;
76
77
78        DLOG( L.log( m_myname + " getRecord()", Logger::Debug ) );
79
80        do
81        {
82                if( err < 0 )
83                {
84                        L.log( m_myname + " getRecord: Unable to get next result - " + string( odbx_error( m_handle[type], err ) ),  Logger::Error );
85                        throw( AhuException( "Error: odbx_result() failed" ) );
86                }
87
88                if( m_result != NULL )
89                {
90                        if( err == 3 )
91                        {
92                                if( ( err = odbx_row_fetch( m_result ) ) < 0 )
93                                {
94                                        L.log( m_myname + " getRecord: Unable to get next row - " + string( odbx_error( m_handle[type], err ) ),  Logger::Error );
95                                        throw( AhuException( "Error: odbx_row_fetch() failed" ) );
96                                }
97
98                                if( err > 0 )
99                                {
100#ifdef VERBOSELOG
101                                        unsigned int i;
102                                        string fields;
103
104                                        for( i = 0; i < odbx_column_count( m_result ); i++ )
105                                        {
106                                                fields += string( odbx_column_name( m_result, i ) );
107
108                                                if( odbx_field_value( m_result, i ) != NULL )
109                                                {
110                                                        fields += "=" + string( odbx_field_value( m_result, i ) ) + ", ";
111                                                }
112                                                else
113                                                {
114                                                        fields += "=NULL, ";
115                                                }
116                                        }
117
118                                        L.log( m_myname + " Values: " + fields,  Logger::Error );
119#endif
120                                        return true;
121                                }
122
123                        }
124
125                        odbx_result_free( m_result );
126                        m_result = NULL;
127                }
128        }
129        while( ( err =  odbx_result( m_handle[type], &m_result, NULL, 0 ) ) != 0 );
130
131        m_result = NULL;
132        return false;
133}
134
135
136
137string OdbxBackend::escape( const string& str, QueryType type )
138{
139        int err;
140        unsigned long len = sizeof( m_escbuf );
141
142
143        DLOG( L.log( m_myname + " escape(string)", Logger::Debug ) );
144
145        if( ( err = odbx_escape( m_handle[type], str.c_str(), str.size(), m_escbuf, &len ) ) < 0 )
146        {
147                L.log( m_myname + " escape(string): Unable to escape string - " + string( odbx_error( m_handle[type], err ) ),  Logger::Error );
148
149                if( err != -ODBX_ERR_PARAM && odbx_error_type( m_handle[type], err ) > 0 ) { throw( runtime_error( "odbx_escape() failed" ) ); }   // ODBX_ERR_PARAM workaround
150                if( !connectTo( m_hosts[type], type ) ) { throw( runtime_error( "odbx_escape() failed" ) ); }
151                if( odbx_escape( m_handle[type], str.c_str(), str.size(), m_escbuf, &len ) < 0 ) { throw( runtime_error( "odbx_escape() failed" ) ); }
152        }
153
154        return string( m_escbuf, len );
155}
156
157
158
159bool OdbxBackend::getDomainList( const string& stmt, vector<DomainInfo>* list, bool (*check_fcn)(u_int32_t,u_int32_t,SOAData*,DomainInfo*) )
160{
161        const char* tmp;
162        u_int32_t nlast, nserial;
163        DomainInfo di;
164        SOAData sd;
165
166
167        DLOG( L.log( m_myname + " getDomainList()", Logger::Debug ) );
168
169        if( !execStmt( stmt.c_str(), stmt.size(), READ ) ) { return false; }
170        if( !getRecord( READ ) ) { return false; }
171
172        do
173        {
174                nlast = 0;
175                nserial = 0;
176                sd.serial = 0;
177                sd.refresh = 0;
178
179                if( ( tmp = odbx_field_value( m_result, 6 ) ) != NULL )
180                {
181                        fillSOAData( string( tmp, odbx_field_length( m_result, 6 ) ), sd );
182                }
183
184                if( !sd.serial && ( tmp = odbx_field_value( m_result, 5 ) ) != NULL )
185                {
186                        sd.serial = strtol( tmp, NULL, 10 );
187                }
188
189                if( ( tmp = odbx_field_value( m_result, 4 ) ) != NULL )
190                {
191                        nlast = strtol( tmp, NULL, 10 );
192                }
193
194                if( ( tmp = odbx_field_value( m_result, 3 ) ) != NULL )
195                {
196                        nserial = strtol( tmp, NULL, 10 );
197                }
198
199                if( (*check_fcn)( nlast, nserial, &sd, &di ) )
200                {
201                        if( ( tmp = odbx_field_value( m_result, 2 ) ) != NULL )
202                        {
203                                di.master = string( tmp, odbx_field_length( m_result, 2 ) );
204                        }
205
206                        if( ( tmp = odbx_field_value( m_result, 1 ) ) != NULL )
207                        {
208                                di.zone = string( tmp, odbx_field_length( m_result, 1 ) );
209                        }
210
211                        if( ( tmp = odbx_field_value( m_result, 0 ) ) != NULL )
212                        {
213                                di.id = strtol( tmp, NULL, 10 );
214                        }
215
216                        di.last_check = nlast;
217                        di.notified_serial = nserial;
218                        di.serial = sd.serial;
219                        di.backend = this;
220
221                        list->push_back( di );
222                }
223        }
224        while( getRecord( READ ) );
225
226        return true;
227}
228
229
230
231bool checkSlave( u_int32_t nlast, u_int32_t nserial, SOAData* sd, DomainInfo* di )
232{
233        if( nlast + sd->refresh < (u_int32_t) time( 0 ) )
234        {
235                di->kind = DomainInfo::Slave;
236                return true;
237        }
238
239        return false;
240}
241
242
243
244bool checkMaster( u_int32_t nlast, u_int32_t nserial, SOAData* sd, DomainInfo* di )
245{
246        if( nserial != sd->serial )
247        {
248                di->kind = DomainInfo::Master;
249                return true;
250        }
251
252        return false;
253}
Note: See TracBrowser for help on using the browser.