ld_mod.c

Go to the documentation of this file.
00001 /*
00002  * $Id$
00003  *
00004  * LDAP Database Driver for SER
00005  *
00006  * Copyright (C) 2008 iptelorg GmbH
00007  *
00008  * This file is part of SER, a free SIP server.
00009  *
00010  * SER is free software; you can redistribute it and/or modify it under the
00011  * terms of the GNU General Public License as published by the Free Software
00012  * Foundation; either version 2 of the License, or (at your option) any later
00013  * version.
00014  *
00015  * SER is distributed in the hope that it will be useful, but WITHOUT ANY
00016  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
00017  * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
00018  * details.
00019  *
00020  * You should have received a copy of the GNU General Public License along
00021  * with this program; if not, write to the Free Software Foundation, Inc.,
00022  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
00023  */
00024 
00033 #include "ld_mod.h"
00034 #include "ld_uri.h"
00035 #include "ld_cfg.h"
00036 #include "ld_con.h"
00037 #include "ld_cmd.h"
00038 #include "ld_fld.h"
00039 #include "ld_res.h"
00040 
00041 #include "../../sr_module.h"
00042 
00043 #ifdef LD_TEST
00044 #include "../../lib/srdb2/db_cmd.h"
00045 #include <limits.h>
00046 #include <float.h>
00047 #endif
00048 
00049 #include <ldap.h>
00050 
00051 str ld_cfg_file = STR_STATIC_INIT("ldap.cfg");
00052 int ld_reconnect_attempt = 3;
00053 
00054 static int ld_mod_init(void);
00055 static void ld_mod_destroy(void);
00056 
00057 MODULE_VERSION
00058 
00059 /*
00060  * LDAP module interface
00061  */
00062 static cmd_export_t cmds[] = {
00063         {"db_ctx",    (cmd_function)NULL, 0, 0, 0},
00064         {"db_con",    (cmd_function)ld_con, 0, 0, 0},
00065         {"db_uri",    (cmd_function)ld_uri, 0, 0, 0},
00066         {"db_cmd",    (cmd_function)ld_cmd, 0, 0, 0},
00067         {"db_put",    (cmd_function)ld_cmd_exec, 0, 0, 0},
00068         {"db_del",    (cmd_function)ld_cmd_exec, 0, 0, 0},
00069         {"db_get",    (cmd_function)ld_cmd_exec, 0, 0, 0},
00070         {"db_upd",    (cmd_function)ld_cmd_exec, 0, 0, 0},
00071         {"db_sql",    (cmd_function)ld_cmd_exec, 0, 0, 0},
00072         {"db_res",    (cmd_function)ld_res, 0, 0, 0},
00073         {"db_fld",    (cmd_function)ld_fld, 0, 0, 0},
00074         {"db_first",  (cmd_function)ld_cmd_first, 0, 0, 0},
00075         {"db_next",   (cmd_function)ld_cmd_next, 0, 0, 0},
00076         {"db_setopt", (cmd_function)ld_cmd_setopt, 0, 0, 0},
00077         {"db_getopt", (cmd_function)NULL, 0, 0, 0},
00078         {0, 0, 0, 0, 0}
00079 };
00080 
00081 
00082 /*
00083  * Exported parameters
00084  */
00085 static param_export_t params[] = {
00086         {"config", PARAM_STR, &ld_cfg_file},
00087         {"reconnect_attempt", PARAM_INT, &ld_reconnect_attempt},
00088         {0, 0, 0}
00089 };
00090 
00091 
00092 struct module_exports exports = {
00093         "ldap",
00094         cmds,
00095         0,              /* RPC method */
00096         params,         /* module parameters */
00097         ld_mod_init,    /* module initialization function */
00098         0,              /* response function*/
00099         ld_mod_destroy, /* destroy function */
00100         0,              /* oncancel function */
00101         0               /* per-child init function */
00102 };
00103 
00104 
00105 #ifdef LD_TEST
00106 int ldap_test(void)
00107 {
00108         int i, row;
00109         db_ctx_t* db;
00110         db_cmd_t* put, *del, *get;
00111         db_res_t* result;
00112         db_rec_t* rec;
00113         char* times;
00114 
00115         db_fld_t int_vals[] = {
00116                 {.name = "col_bool",      .type = DB_INT},
00117                 {.name = "col_int8",      .type = DB_INT},
00118                 {.name = "col_int4",      .type = DB_INT},
00119                 {.name = "col_inet",      .type = DB_INT},
00120                 {.name = "col_timestamp", .type = DB_INT},
00121                 {.name = "col_bit",       .type = DB_INT},
00122                 {.name = "col_varbit",    .type = DB_INT},
00123                 {.name = NULL}
00124         };
00125 
00126         db_fld_t datetime_vals[] = {
00127                 {.name = "col_int8",      .type = DB_INT},
00128                 {.name = "col_int4",      .type = DB_INT},
00129                 {.name = "col_timestamp", .type = DB_INT},
00130                 {.name = NULL}
00131         };
00132 
00133 
00134         db_fld_t bitmap_vals[] = {
00135                 {.name = "col_int8",      .type = DB_INT},
00136                 {.name = "col_int4",      .type = DB_INT},
00137                 {.name = "col_bit",       .type = DB_INT},
00138                 {.name = "col_varbit",    .type = DB_INT},
00139                 {.name = NULL}
00140         };
00141 
00142         db_fld_t float_vals[] = {
00143                 {.name = "col_float4", .type = DB_FLOAT},
00144                 {.name = "col_float8", .type = DB_FLOAT},
00145                 {.name = NULL}
00146         };
00147 
00148         db_fld_t double_vals[] = {
00149                 {.name = "col_float8", .type = DB_DOUBLE},
00150                 {.name = NULL}
00151         };
00152 
00153         db_fld_t str_vals[] = {
00154                 {.name = "col_varchar", .type = DB_STR},
00155                 {.name = "col_bytea",   .type = DB_STR},
00156                 {.name = "col_text",    .type = DB_STR},
00157                 {.name = "col_bpchar",  .type = DB_STR},
00158                 {.name = "col_char",    .type = DB_STR},
00159                 {.name = NULL}
00160         };
00161 
00162         db_fld_t cstr_vals[] = {
00163                 {.name = "col_varchar", .type = DB_CSTR},
00164                 {.name = "col_bytea",   .type = DB_CSTR},
00165                 {.name = "col_text",    .type = DB_CSTR},
00166                 {.name = "col_bpchar",  .type = DB_CSTR},
00167                 {.name = "col_char",    .type = DB_CSTR},
00168                 {.name = NULL}
00169         };
00170 
00171         db_fld_t blob_vals[] = {
00172                 {.name = "col_bytea",   .type = DB_BLOB},
00173                 {.name = NULL}
00174         };
00175 
00176 
00177         db_fld_t res[] = {
00178                 {.name = "col_bool",      .type = DB_INT},
00179                 {.name = "col_bytea",     .type = DB_BLOB},
00180                 {.name = "col_char",      .type = DB_STR},
00181                 {.name = "col_int8",      .type = DB_INT},
00182                 {.name = "col_int4",      .type = DB_INT},
00183                 {.name = "col_int2",      .type = DB_INT},
00184                 {.name = "col_text",      .type = DB_STR},
00185                 {.name = "col_float4",    .type = DB_FLOAT},
00186                 {.name = "col_float8",    .type = DB_DOUBLE},
00187                 {.name = "col_inet",      .type = DB_INT},
00188                 {.name = "col_bpchar",    .type = DB_STR},
00189                 {.name = "col_varchar",   .type = DB_STR},
00190                 {.name = "col_timestamp", .type = DB_DATETIME},
00191                 {.name = "col_bit",       .type = DB_BITMAP},
00192                 {.name = "col_varbit",    .type = DB_BITMAP},
00193                 {.name = NULL}
00194         };
00195 
00196         db_fld_t cred[] = {
00197                 {.name = "auth_username", .type = DB_CSTR},
00198                 {.name = "realm", .type = DB_CSTR},
00199                 {.name = NULL}
00200         };
00201 
00202 
00203         db = db_ctx("ldap");
00204         if (db == NULL) {
00205                 ERR("Error while initializing database layer\n");
00206                 goto error;
00207         }
00208         if (db_add_db(db, "ldap://127.0.0.1") < 0) goto error;
00209 
00210         if (db_connect(db) < 0) goto error;
00211 
00212         /*
00213         del = db_cmd(DB_DEL, db, "test", NULL, NULL, NULL);
00214         if (del == NULL) {
00215                 ERR("Error while building delete * query\n");
00216                 goto error;
00217         }
00218 
00219     put = db_cmd(DB_PUT, db, "test", NULL, NULL, int_vals);
00220         if (put == NULL) {
00221                 ERR("Error while building test query\n");
00222                 goto error;
00223         }
00224 
00225         if (db_exec(NULL, del)) {
00226                 ERR("Error while deleting rows from test table\n");
00227                 goto error;
00228         }
00229 
00230         put->vals[0].v.int4 = 0xffffffff;
00231         put->vals[1].v.int4 = 0xffffffff;
00232         put->vals[2].v.int4 = 0xffffffff;
00233         put->vals[3].v.int4 = 0xffffffff;
00234         put->vals[4].v.int4 = 0xffffffff;
00235         put->vals[5].v.int4 = 0xffffffff;
00236         put->vals[6].v.int4 = 0xffffffff;
00237 
00238         if (db_exec(NULL, put)) {
00239                 ERR("Error while executing database command\n");
00240                 goto error;
00241         }
00242 
00243         put->vals[0].v.int4 = 0;
00244         put->vals[1].v.int4 = 0;
00245         put->vals[2].v.int4 = 0;
00246         put->vals[3].v.int4 = 0;
00247         put->vals[4].v.int4 = 0;
00248         put->vals[5].v.int4 = 0;
00249         put->vals[6].v.int4 = 0;
00250 
00251         if (db_exec(NULL, put)) {
00252                 ERR("Error while executing database command\n");
00253                 goto error;
00254         }
00255 
00256         db_cmd_free(put);
00257 
00258         put = db_cmd(DB_PUT, db, "test", NULL, NULL, bitmap_vals);
00259         if (put == NULL) {
00260                 ERR("Error while building bitmap test query\n");
00261                 goto error;
00262         }
00263 
00264         put->vals[0].v.int4 = 0xffffffff;
00265         put->vals[1].v.int4 = 0xffffffff;
00266         put->vals[2].v.int4 = 0xffffffff;
00267         put->vals[3].v.int4 = 0xffffffff;
00268         if (db_exec(NULL, put)) {
00269                 ERR("Error while executing database command\n");
00270                 goto error;
00271         }
00272 
00273         put->vals[0].v.int4 = 0;
00274         put->vals[1].v.int4 = 0;
00275         put->vals[2].v.int4 = 0;
00276         put->vals[3].v.int4 = 0;
00277         if (db_exec(NULL, put)) {
00278                 ERR("Error while executing database command\n");
00279                 goto error;
00280         }
00281 
00282         db_cmd_free(put);
00283 
00284         put = db_cmd(DB_PUT, db, "test", NULL, NULL, float_vals);
00285         if (put == NULL) {
00286                 ERR("Error while building float test query\n");
00287                 goto error;
00288         }
00289 
00290         put->vals[0].v.flt = FLT_MAX;
00291         put->vals[1].v.flt = FLT_MAX;
00292         if (db_exec(NULL, put)) {
00293                 ERR("Error while executing database command\n");
00294                 goto error;
00295         }
00296 
00297         put->vals[0].v.flt = FLT_MIN;
00298         put->vals[1].v.flt = FLT_MIN;
00299         if (db_exec(NULL, put)) {
00300                 ERR("Error while executing database command\n");
00301                 goto error;
00302         }
00303 
00304         db_cmd_free(put);
00305 
00306         put = db_cmd(DB_PUT, db, "test", NULL, NULL, double_vals);
00307         if (put == NULL) {
00308                 ERR("Error while building double test query\n");
00309                 goto error;
00310         }
00311 
00312         put->vals[0].v.dbl = DBL_MAX;
00313         if (db_exec(NULL, put)) {
00314                 ERR("Error while executing database command\n");
00315                 goto error;
00316         }
00317 
00318         put->vals[0].v.dbl = DBL_MIN;
00319         if (db_exec(NULL, put)) {
00320                 ERR("Error while executing database command\n");
00321                 goto error;
00322         }
00323 
00324 
00325         db_cmd_free(put);
00326 
00327         put = db_cmd(DB_PUT, db, "test", NULL, NULL, str_vals);
00328         if (put == NULL) {
00329                 ERR("Error while building str test query\n");
00330                 goto error;
00331         }
00332 
00333         put->vals[0].v.lstr.s = "";
00334         put->vals[0].v.lstr.len = 0;
00335         put->vals[1].v.lstr.s = "";
00336         put->vals[1].v.lstr.len = 0;
00337         put->vals[2].v.lstr.s = "";
00338         put->vals[2].v.lstr.len = 0;
00339         put->vals[3].v.lstr.s = "";
00340         put->vals[3].v.lstr.len = 0;
00341         put->vals[4].v.lstr.s = "";
00342         put->vals[4].v.lstr.len = 0;
00343         if (db_exec(NULL, put)) {
00344                 ERR("Error while executing database command\n");
00345                 goto error;
00346         }
00347 
00348         put->vals[0].v.lstr.s = "abc should not be there";
00349         put->vals[0].v.lstr.len = 3;
00350         put->vals[1].v.lstr.s = "abc should not be there";
00351         put->vals[1].v.lstr.len = 3;
00352         put->vals[2].v.lstr.s = "abc should not be there";
00353         put->vals[2].v.lstr.len = 3;
00354         put->vals[3].v.lstr.s = "abc should not be there";
00355         put->vals[3].v.lstr.len = 3;
00356         put->vals[4].v.lstr.s = "a should not be there";
00357         put->vals[4].v.lstr.len = 1;
00358         if (db_exec(NULL, put)) {
00359                 ERR("Error while executing database command\n");
00360                 goto error;
00361         }
00362 
00363         db_cmd_free(put);
00364 
00365         put = db_cmd(DB_PUT, db, "test", NULL, NULL, cstr_vals);
00366         if (put == NULL) {
00367                 ERR("Error while building cstr test query\n");
00368                 goto error;
00369         }
00370 
00371         put->vals[0].v.cstr = "";
00372         put->vals[1].v.cstr = "";
00373         put->vals[2].v.cstr = "";
00374         put->vals[3].v.cstr = "";
00375         put->vals[4].v.cstr = "";
00376         if (db_exec(NULL, put)) {
00377                 ERR("Error while executing database command\n");
00378                 goto error;
00379         }
00380 
00381         put->vals[0].v.cstr = "def";
00382         put->vals[1].v.cstr = "def";
00383         put->vals[2].v.cstr = "def";
00384         put->vals[3].v.cstr = "def";
00385         put->vals[4].v.cstr = "d";
00386         if (db_exec(NULL, put)) {
00387                 ERR("Error while executing database command\n");
00388                 goto error;
00389         }
00390 
00391         db_cmd_free(put);
00392 
00393         put = db_cmd(DB_PUT, db, "test", NULL, NULL, blob_vals);
00394         if (put == NULL) {
00395                 ERR("Error while building blob test query\n");
00396                 goto error;
00397         }
00398 
00399         put->vals[0].v.blob.s = "\0\0\0\0";
00400         put->vals[0].v.blob.len = 4;
00401         if (db_exec(NULL, put)) {
00402                 ERR("Error while executing database command\n");
00403                 goto error;
00404         }
00405 
00406 
00407         db_cmd_free(put);
00408 
00409         put = db_cmd(DB_PUT, db, "test", NULL, NULL, datetime_vals);
00410         if (put == NULL) {
00411                 ERR("Error while building datetime test query\n");
00412                 goto error;
00413         }
00414 
00415         put->vals[0].v.time = 0xffffffff;
00416         put->vals[1].v.time = 0xffffffff;
00417         put->vals[2].v.time = 0xffffffff;
00418         if (db_exec(NULL, put)) {
00419                 ERR("Error while executing database command\n");
00420                 goto error;
00421         }
00422 
00423         put->vals[0].v.time = 0;
00424         put->vals[1].v.time = 0;
00425         put->vals[2].v.time = 0;
00426         if (db_exec(NULL, put)) {
00427                 ERR("Error while executing database command\n");
00428                 goto error;
00429         }
00430 
00431         if (put) db_cmd_free(put);
00432         if (del) db_cmd_free(del);
00433         put = NULL;
00434         del = NULL;
00435 
00436         */
00437 
00438         get = db_cmd(DB_GET, db, "credentials", res, cred, NULL);
00439         if (get == NULL) {
00440                 ERR("Error while building select query\n");
00441                 goto error;
00442         }
00443 
00444         get->match[0].v.cstr = "jan";
00445         get->match[1].v.cstr = "iptel.org";
00446 
00447         if (db_exec(&result, get)) {
00448                 ERR("Error while executing select query\n");
00449                 goto error;
00450         }
00451 
00452         rec = db_first(result);
00453         while(rec) {
00454                 rec = db_next(result);
00455         }
00456 
00457         return 0;
00458 
00459         rec = db_first(result);
00460         row = 1;
00461         while(rec) {
00462                 ERR("row: %d\n", row);
00463                 for(i = 0; !DB_FLD_LAST(rec->fld[i]); i++) {
00464                         if (rec->fld[i].flags & DB_NULL) {
00465                                 ERR("%s: NULL\n", rec->fld[i].name);
00466                         } else {
00467                                 switch(rec->fld[i].type) {
00468                                 case DB_INT:
00469                                 case DB_BITMAP:
00470                                         ERR("%s: %d\n", rec->fld[i].name, rec->fld[i].v.int4);
00471                                         break;
00472 
00473                                 case DB_DATETIME:
00474                                         times = ctime(&rec->fld[i].v.time);
00475                                         ERR("%s: %d:%.*s\n", rec->fld[i].name, rec->fld[i].v.time, strlen(times) - 1, times);
00476                                         break;
00477 
00478                                 case DB_DOUBLE:
00479                                         ERR("%s: %f\n", rec->fld[i].name, rec->fld[i].v.dbl);
00480                                         break;
00481 
00482                                 case DB_FLOAT:
00483                                         ERR("%s: %f\n", rec->fld[i].name, rec->fld[i].v.flt);
00484                                         break;
00485 
00486                                 case DB_STR:
00487                                 case DB_BLOB:
00488                                         ERR("%s: %.*s\n", rec->fld[i].name, rec->fld[i].v.lstr.len, rec->fld[i].v.lstr.s);
00489                                         break;
00490 
00491                                 case DB_CSTR:
00492                                         ERR("%s: %s\n", rec->fld[i].name, rec->fld[i].v.cstr);
00493                                         break;
00494                                 }
00495                         }
00496                 }
00497                 ERR("\n");
00498                 rec = db_next(result);
00499                 row++;
00500         }
00501 
00502         db_res_free(result);
00503 
00504         db_cmd_free(get);
00505         db_disconnect(db);
00506         db_ctx_free(db);
00507         return 0;
00508 
00509  error:
00510         if (get) db_cmd_free(get);
00511         if (put) db_cmd_free(put);
00512         if (del) db_cmd_free(del);
00513         db_disconnect(db);
00514         db_ctx_free(db);
00515         return -1;
00516 }
00517 #endif /* LDAP_TEST */
00518 
00519 
00520 static void ld_mod_destroy(void)
00521 {
00522         ld_cfg_free();
00523 }
00524 
00525 
00526 static int ld_mod_init(void)
00527 {
00528         if (ld_load_cfg(&ld_cfg_file)) {
00529                         ERR("ldap: Error while loading configuration file\n");
00530                         return -1;
00531         }
00532 
00533 #ifdef LD_TEST
00534         if (ldap_test() == 0) {
00535                 ERR("ldap: Testing successful\n");
00536         } else {
00537                 ERR("ldap: Testing failed\n");
00538         }
00539         return -1;
00540 #endif /* LDAP_TEST */
00541         return 0;
00542 }
00543