/[Development]/mod_auth_ibmdb2/mod_authnz_ibmdb2/caching.h
ViewVC logotype

Contents of /mod_auth_ibmdb2/mod_authnz_ibmdb2/caching.h

Parent Directory Parent Directory | Revision Log Revision Log | View Revision Graph Revision Graph


Revision 1.5 - (show annotations)
Wed Mar 21 21:39:22 2007 UTC (3 years, 5 months ago) by tessus
Branch: MAIN
CVS Tags: RELEASE_1_26, HEAD
Changes since 1.4: +1 -2 lines
File MIME type: text/x-chdr
removed gdbm.h, since APR handles this
1 /*
2 +----------------------------------------------------------------------+
3 | caching: functions for caching mechanism |
4 +----------------------------------------------------------------------+
5 | Copyright (c) 2006-2007 Helmut K. C. Tessarek |
6 +----------------------------------------------------------------------+
7 | Licensed under the Apache License, Version 2.0 (the "License"); you |
8 | may not use this file except in compliance with the License. You may |
9 | obtain a copy of the License at |
10 | http://www.apache.org/licenses/LICENSE-2.0 |
11 | |
12 | Unless required by applicable law or agreed to in writing, software |
13 | distributed under the License is distributed on an "AS IS" BASIS, |
14 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or |
15 | implied. See the License for the specific language governing |
16 | permissions and limitations under the License. |
17 +----------------------------------------------------------------------+
18 | Author: Helmut K. C. Tessarek |
19 +----------------------------------------------------------------------+
20 | Website: http://mod-auth-ibmdb2.sourceforge.net |
21 +----------------------------------------------------------------------+
22 */
23
24 /* $Id: caching.h,v 1.5 2007/03/21 21:39:22 tessus Exp $ */
25
26 #ifndef CACHING_H
27 #define CACHING_H
28
29 #include "apr_general.h"
30 #include "apr_dbm.h"
31 #include "apr_time.h"
32
33 typedef struct {
34 char password[MAX_PWD_LENGTH];
35 apr_time_t timestamp;
36 } cached_password_timestamp;
37
38 typedef struct {
39 int numgrps;
40 apr_time_t timestamp;
41 } cached_group_timestamp;
42
43 static int write_cache( request_rec *r, const char *user, const char *password, authn_ibmdb2_config_t *m );
44 static char *read_cache( request_rec *r, const char *user, authn_ibmdb2_config_t *m );
45 static int write_group_cache( request_rec *r, const char *user, const char **grplist, authn_ibmdb2_config_t *m );
46 static char **read_group_cache( request_rec *r, const char *user, authn_ibmdb2_config_t *m );
47
48 /*
49 function to store the user credentials in the local cache, so that subsequent
50 http requests can validate the user directly from local cache without the need
51 to query the backend db2 database.
52 */
53
54 /* {{{ static int write_cache( request_rec *r, const char *user, const char *password, authn_ibmdb2_config_t *m )
55 */
56 static int write_cache( request_rec *r, const char *user, const char *password, authn_ibmdb2_config_t *m )
57 {
58 apr_status_t rc;
59 apr_pool_t *pool;
60 apr_dbm_t *db;
61 char errmsg[MAXERRLEN];
62 int rc_write_cache = 0;
63
64 char *my_user = (char *)user;
65 apr_datum_t datum_user = { my_user, (strlen( my_user )+1) };
66
67 cached_password_timestamp cpt;
68
69 apr_datum_t datum_value;
70
71 char *my_password = (char *)password;
72 strcpy(cpt.password, my_password);
73
74 if( !(cpt.timestamp = apr_time_now()) )
75 {
76 errmsg[0] = '\0';
77 sprintf( errmsg, "unable to determine current time (write cache)");
78 LOG_ERROR( errmsg );
79 return( 1 );
80 }
81
82 datum_value.dptr = (void *)&cpt;
83 datum_value.dsize = sizeof(cpt);
84
85 apr_pool_create( &pool, NULL );
86
87 rc = apr_dbm_open(&db, m->ibmdb2cachefile, APR_DBM_RWCREATE, APR_FPROT_UREAD | APR_FPROT_UWRITE, pool);
88
89 if ( rc == APR_SUCCESS )
90 {
91 errmsg[0] = '\0';
92 sprintf( errmsg, "storing user [%s] and pass [%s] in cache", my_user, my_password);
93 LOG_DBG( errmsg );
94
95 if( (rc = apr_dbm_store(db, datum_user, datum_value)) != APR_SUCCESS )
96 {
97 errmsg[0] = '\0';
98 sprintf( errmsg, "unable to store user [%s] in cache", my_user);
99 LOG_DBG( errmsg );
100 errmsg[0] = '\0';
101 apr_strerror( rc, errmsg, sizeof(errmsg) );
102 LOG_DBG( errmsg );
103
104 rc_write_cache = 1;
105 }
106
107 apr_dbm_close( db );
108 }
109 else
110 {
111 errmsg[0] = '\0';
112 sprintf( errmsg, "could not open cachefile [%s] for writing", m->ibmdb2cachefile );
113 LOG_ERROR( errmsg );
114 errmsg[0] = '\0';
115 apr_strerror( rc, errmsg, sizeof(errmsg) );
116 LOG_DBG( errmsg );
117
118 rc_write_cache = 1;
119 }
120
121 apr_pool_destroy( pool );
122
123 return( rc_write_cache );
124 }
125 /* }}} */
126
127 /*
128 function to check in the local cache to validate user, otherwise
129 we need to query the backend db2 database.
130 */
131
132 /* {{{ static char *read_cache( request_rec *r, const char *user, authn_ibmdb2_config_t *m )
133 */
134 static char *read_cache( request_rec *r, const char *user, authn_ibmdb2_config_t *m )
135 {
136 apr_status_t rc;
137 apr_pool_t *pool;
138 apr_dbm_t *db;
139 char errmsg[MAXERRLEN];
140
141 char *my_user = (char *)user;
142 apr_datum_t datum_user = { my_user, (strlen( my_user )+1) };
143
144 cached_password_timestamp cpt;
145 apr_time_t current_time;
146
147 apr_datum_t datum_value;
148
149 char *pw = NULL;
150
151 int MAXAGE = atoi( m->ibmdb2cachelifetime );
152
153 apr_time_t time_diff;
154
155 apr_pool_create( &pool, NULL );
156
157 rc = apr_dbm_open(&db, m->ibmdb2cachefile, APR_DBM_RWCREATE, APR_FPROT_UREAD | APR_FPROT_UWRITE, pool);
158
159 if( rc == APR_SUCCESS )
160 {
161 rc = apr_dbm_fetch( db, datum_user, &datum_value );
162
163 if( rc == APR_SUCCESS )
164 {
165 if( datum_value.dsize != sizeof(cpt) )
166 {
167 errmsg[0] = '\0';
168 sprintf( errmsg, "we found our user in the cache but with corrupted record: %s \n", my_user);
169 LOG_ERROR( errmsg );
170
171 apr_dbm_close( db );
172 apr_pool_destroy( pool );
173
174 return NULL;
175 }
176 else
177 {
178 memcpy((void *)&cpt, datum_value.dptr, datum_value.dsize);
179
180 if( !(current_time = apr_time_now()) )
181 {
182 errmsg[0] = '\0';
183 sprintf( errmsg, "unable to determine current time (read cache)");
184 LOG_ERROR( errmsg );
185
186 apr_dbm_close( db );
187 apr_pool_destroy( pool );
188
189 return NULL;
190 }
191
192 time_diff = current_time - cpt.timestamp;
193
194 if( apr_time_sec(time_diff) > MAXAGE )
195 {
196 errmsg[0] = '\0';
197 sprintf( errmsg, "cached password for user [%s] is toooo old", my_user);
198 LOG_DBG( errmsg );
199
200 apr_dbm_close( db );
201 apr_pool_destroy( pool );
202
203 return NULL;
204 }
205
206 pw = cpt.password;
207
208 /* Congratulations, we have a fresh cached entry */
209 errmsg[0] = '\0';
210 sprintf( errmsg, "user [%s] - [%s] found in cache", my_user, pw);
211 LOG_DBG( errmsg );
212
213 apr_dbm_close( db );
214 apr_pool_destroy( pool );
215
216 return pw;
217 }
218 }
219 else
220 {
221 /* Did not find user in the cache */
222 errmsg[0] = '\0';
223 sprintf( errmsg, "user [%s] not found in cache", my_user);
224 LOG_DBG( errmsg );
225
226 apr_dbm_close( db );
227 apr_pool_destroy( pool );
228
229 return NULL;
230 }
231 }
232 else
233 {
234 errmsg[0] = '\0';
235 sprintf( errmsg, "could not open cachefile [%s] for reading", m->ibmdb2cachefile );
236 LOG_ERROR( errmsg );
237 errmsg[0] = '\0';
238 apr_strerror( rc, errmsg, sizeof(errmsg) );
239 LOG_DBG( errmsg );
240
241 apr_pool_destroy( pool );
242 return NULL;
243 }
244 }
245 /* }}} */
246
247 /*
248 function to store the group information in the local cache, so that subsequent
249 http requests can validate the groups directly from local cache without the need
250 to query the backend db2 database.
251 */
252
253 /* {{{ static int write_group_cache( request_rec *r, const char *user, const char **grplist, authn_ibmdb2_config_t *m )
254 */
255 static int write_group_cache( request_rec *r, const char *user, const char **grplist, authn_ibmdb2_config_t *m )
256 {
257 apr_status_t rc;
258 apr_pool_t *pool;
259 apr_dbm_t *db;
260 char errmsg[MAXERRLEN];
261 int rc_write_group_cache = 0;
262
263 char ibmdb2grpcachefile[512];
264 char username[MAX_UID_LENGTH+4];
265 char groupname[MAX_GRP_LENGTH];
266
267 int i = 0;
268
269 char *my_user = (char *)user;
270 apr_datum_t datum_user = { my_user, (strlen( my_user )+1) };
271
272 cached_group_timestamp cgt;
273
274 apr_datum_t datum_value;
275 apr_datum_t key_data;
276 apr_datum_t data_data;
277
278 sprintf( ibmdb2grpcachefile, "%s.grp", m->ibmdb2cachefile );
279
280 if( !(cgt.timestamp = apr_time_now()) )
281 {
282 errmsg[0] = '\0';
283 sprintf( errmsg, "unable to determine current time (write group cache)");
284 LOG_ERROR( errmsg );
285 return( 1 );
286 }
287
288 while( grplist[i] )
289 {
290 ++i;
291 }
292
293 cgt.numgrps = i;
294
295 datum_value.dptr = (void *)&cgt;
296 datum_value.dsize = sizeof(cgt);
297
298 apr_pool_create( &pool, NULL );
299
300 rc = apr_dbm_open(&db, ibmdb2grpcachefile, APR_DBM_RWCREATE, APR_FPROT_UREAD | APR_FPROT_UWRITE, pool);
301
302 if( rc == APR_SUCCESS )
303 {
304 if( (rc = apr_dbm_store(db, datum_user, datum_value)) != APR_SUCCESS )
305 {
306 errmsg[0] = '\0';
307 sprintf( errmsg, "unable to store group info for user [%s] in cache", my_user);
308 LOG_DBG( errmsg );
309 errmsg[0] = '\0';
310 apr_strerror( rc, errmsg, sizeof(errmsg) );
311 LOG_DBG( errmsg );
312
313 apr_dbm_close( db );
314 apr_pool_destroy( pool );
315 return( 1 );
316 }
317
318 i = 0;
319
320 while( grplist[i] )
321 {
322 key_data.dptr = NULL;
323 data_data.dptr = NULL;
324
325 username[0] = '\0';
326 sprintf( username, "%s_%d", my_user, i );
327
328 groupname[0] = '\0';
329 strcpy( groupname, grplist[i] );
330
331 key_data.dptr = username;
332 key_data.dsize = strlen(username) + 1;
333
334 data_data.dptr = groupname;
335 data_data.dsize = strlen(groupname) + 1;
336
337 if( (rc = apr_dbm_store(db, key_data, data_data)) != APR_SUCCESS )
338 {
339 errmsg[0] = '\0';
340 sprintf( errmsg, "unable to store group [%s] for user [%s] in cache", grplist[i], my_user );
341 LOG_DBG( errmsg );
342 errmsg[0] = '\0';
343 apr_strerror( rc, errmsg, sizeof(errmsg) );
344 LOG_DBG( errmsg );
345
346 apr_dbm_close( db );
347 apr_pool_destroy( pool );
348 return( 1 );
349 }
350 else
351 {
352 errmsg[0] = '\0';
353 sprintf( errmsg, "storing user [%s] and group [%s] in cache", my_user, grplist[i] );
354 LOG_DBG( errmsg );
355 }
356
357 ++i;
358 }
359
360 apr_dbm_close( db );
361 }
362 else
363 {
364 errmsg[0] = '\0';
365 sprintf( errmsg, "could not open group cachefile [%s] for writing", ibmdb2grpcachefile );
366 LOG_ERROR( errmsg );
367 errmsg[0] = '\0';
368 apr_strerror( rc, errmsg, sizeof(errmsg) );
369 LOG_DBG( errmsg );
370
371 rc_write_group_cache = 1;
372 }
373
374 apr_pool_destroy( pool );
375
376 return( rc_write_group_cache );
377 }
378 /* }}} */
379
380 /*
381 function to check in the local cache to check if user is in a group, otherwise
382 we need to query the backend db2 database.
383 */
384
385 /* {{{ static char **read_group_cache( request_rec *r, const char *user, authn_ibmdb2_config_t *m )
386 */
387 static char **read_group_cache( request_rec *r, const char *user, authn_ibmdb2_config_t *m )
388 {
389 apr_status_t rc;
390 apr_pool_t *pool;
391 apr_dbm_t *db;
392 char errmsg[MAXERRLEN];
393
394 char ibmdb2grpcachefile[512];
395 char username[MAX_UID_LENGTH+4];
396
397 int i = 0;
398
399 int numgrps;
400
401 char *my_user = (char *)user;
402 apr_datum_t datum_user = { my_user, (strlen( my_user )+1) };
403
404 cached_group_timestamp cgt;
405 apr_time_t current_time;
406
407 apr_datum_t datum_value;
408 apr_datum_t key_data;
409 apr_datum_t return_data;
410
411 char **list = NULL;
412
413 int MAXAGE = atoi( m->ibmdb2cachelifetime );
414
415 apr_time_t time_diff;
416
417 sprintf( ibmdb2grpcachefile, "%s.grp", m->ibmdb2cachefile );
418
419 apr_pool_create( &pool, NULL );
420
421 rc = apr_dbm_open(&db, ibmdb2grpcachefile, APR_DBM_RWCREATE, APR_FPROT_UREAD | APR_FPROT_UWRITE, pool);
422
423 if( rc == APR_SUCCESS )
424 {
425 rc = apr_dbm_fetch( db, datum_user, &datum_value );
426
427 if( rc == APR_SUCCESS )
428 {
429 if( datum_value.dsize != sizeof(cgt) )
430 {
431 errmsg[0] = '\0';
432 sprintf( errmsg, "we found our user in the cache but with corrupted record: %s \n", my_user);
433 LOG_ERROR( errmsg );
434
435 apr_dbm_close( db );
436 apr_pool_destroy( pool );
437
438 return NULL;
439 }
440 else
441 {
442 memcpy((void *)&cgt, datum_value.dptr, datum_value.dsize);
443
444 if( !(current_time = apr_time_now()) )
445 {
446 errmsg[0] = '\0';
447 sprintf( errmsg, "unable to determine current time (read group cache)");
448 LOG_ERROR( errmsg );
449
450 apr_dbm_close( db );
451 apr_pool_destroy( pool );
452
453 return NULL;
454 }
455
456 time_diff = current_time - cgt.timestamp;
457
458 i = 0;
459
460 numgrps = cgt.numgrps;
461
462 if( apr_time_sec(time_diff) > MAXAGE )
463 {
464 errmsg[0] = '\0';
465 sprintf( errmsg, "cached group information for user [%s] toooo old", my_user);
466 LOG_DBG( errmsg );
467
468 apr_dbm_close( db );
469 apr_pool_destroy( pool );
470
471 return NULL;
472 }
473
474 /* Build the list to return */
475
476 list = (char **) malloc(sizeof(char *) * (numgrps+1));
477
478 for( i = 0; i < numgrps; i++ )
479 {
480 key_data.dptr = NULL;
481 return_data.dptr = NULL;
482
483 username[0] = '\0';
484 sprintf( username, "%s_%d", my_user, i );
485
486 key_data.dptr = username;
487 key_data.dsize = strlen(username) + 1;
488
489 rc = apr_dbm_fetch( db, key_data, &return_data );
490
491 if( rc == APR_SUCCESS )
492 {
493 list[i] = return_data.dptr;
494 }
495 }
496
497 list[i] = NULL;
498
499 /* Congratulations, we have a fresh cached entry */
500 errmsg[0] = '\0';
501 sprintf( errmsg, "groups for user [%s] found in cache", my_user);
502 LOG_DBG( errmsg );
503
504 apr_dbm_close( db );
505 apr_pool_destroy( pool );
506
507 return list;
508 }
509 }
510 else
511 {
512 /* Did not find user in the group cache */
513 errmsg[0] = '\0';
514 sprintf( errmsg, "groups for user [%s] not found in cache", my_user);
515 LOG_DBG( errmsg );
516
517 apr_dbm_close( db );
518 apr_pool_destroy( pool );
519
520 return NULL;
521 }
522 }
523 else
524 {
525 errmsg[0] = '\0';
526 sprintf( errmsg, "could not open group cachefile [%s] for reading", ibmdb2grpcachefile );
527 LOG_ERROR( errmsg );
528 errmsg[0] = '\0';
529 apr_strerror( rc, errmsg, sizeof(errmsg) );
530 LOG_DBG( errmsg );
531
532 apr_pool_destroy( pool );
533 return NULL;
534 }
535 }
536 /* }}} */
537
538 #endif
539
540 /*
541 * Local variables:
542 * tab-width: 4
543 * c-basic-offset: 4
544 * End:
545 * vim600: noet sw=4 ts=4 fdm=marker
546 * vim<600: noet sw=4 ts=4
547 */

CVS admin
ViewVC Help
Powered by ViewVC 1.1.5