00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00033 #define _XOPEN_SOURCE 4
00034 #define _XOPEN_SOURCE_EXTENDED 1
00035 #define _SVID_SOURCE 1
00036
00037 #define _BSD_SOURCE
00038
00039 #include "ld_fld.h"
00040
00041 #include "../../lib/srdb2/db_drv.h"
00042 #include "../../mem/mem.h"
00043 #include "../../dprint.h"
00044 #include "../../ut.h"
00045
00046 #include <stdlib.h>
00047 #include <stdio.h>
00048 #include <strings.h>
00049 #include <stdint.h>
00050 #include <string.h>
00051 #include <time.h>
00052
00053
00057 struct sbuf {
00058 char *s;
00059 int len;
00060 int size;
00061 int increment;
00062 };
00063
00064
00065 #define TEST_RESIZE \
00066 if (rsize > sb->size) { \
00067 asize = rsize - sb->size; \
00068 new_size = sb->size + (asize / sb->increment + \
00069 (asize % sb->increment > 0)) * sb->increment; \
00070 newp = pkg_malloc(new_size); \
00071 if (!newp) { \
00072 ERR("ldap: No memory left\n"); \
00073 return -1; \
00074 } \
00075 if (sb->s) { \
00076 memcpy(newp, sb->s, sb->len); \
00077 pkg_free(sb->s); \
00078 } \
00079 sb->s = newp; \
00080 sb->size = new_size; \
00081 }
00082
00083
00084 static inline int sb_add(struct sbuf *sb, char* str, int len)
00085 {
00086 int new_size = 0, asize;
00087 int rsize = sb->len + len;
00088 char *newp;
00089
00090 TEST_RESIZE;
00091
00092 memcpy(sb->s + sb->len, str, len);
00093 sb->len += len;
00094 return 0;
00095 }
00096
00097
00098 static inline int sb_add_esc(struct sbuf *sb, char* str, int len)
00099 {
00100 int new_size = 0, asize, i;
00101 int rsize = sb->len + len * 3;
00102 char *newp, *w;
00103
00104 TEST_RESIZE;
00105
00106 w = sb->s + sb->len;
00107 for(i = 0; i < len; i++) {
00108 switch(str[i]) {
00109 case '*':
00110 *w++ = '\\'; *w++ = '2'; *w++ = 'A';
00111 sb->len += 3;
00112 break;
00113
00114 case '(':
00115 *w++ = '\\'; *w++ = '2'; *w++ = '8';
00116 sb->len += 3;
00117 break;
00118
00119 case ')':
00120 *w++ = '\\'; *w++ = '2'; *w++ = '9';
00121 sb->len += 3;
00122 break;
00123
00124 case '\\':
00125 *w++ = '\\'; *w++ = '5'; *w++ = 'C';
00126 sb->len += 3;
00127 break;
00128
00129 case '\0':
00130 *w++ = '\\'; *w++ = '0'; *w++ = '0';
00131 sb->len += 3;
00132 break;
00133
00134 default:
00135 *w++ = str[i];
00136 sb->len++;
00137 break;
00138 }
00139 }
00140
00141 return 0;
00142 }
00143
00144
00150 static void ld_fld_free(db_fld_t* fld, struct ld_fld* payload)
00151 {
00152 db_drv_free(&payload->gen);
00153 if (payload->values) ldap_value_free_len(payload->values);
00154 payload->values = NULL;
00155 if (payload->filter) pkg_free(payload->filter);
00156 payload->filter = NULL;
00157 pkg_free(payload);
00158 }
00159
00160
00161 int ld_fld(db_fld_t* fld, char* table)
00162 {
00163 struct ld_fld* res;
00164
00165 res = (struct ld_fld*)pkg_malloc(sizeof(struct ld_fld));
00166 if (res == NULL) {
00167 ERR("ldap: No memory left\n");
00168 return -1;
00169 }
00170 memset(res, '\0', sizeof(struct ld_fld));
00171 if (db_drv_init(&res->gen, ld_fld_free) < 0) goto error;
00172
00173 DB_SET_PAYLOAD(fld, res);
00174 return 0;
00175
00176 error:
00177 if (res) pkg_free(res);
00178 return -1;
00179 }
00180
00181
00182 int ld_resolve_fld(db_fld_t* fld, struct ld_cfg* cfg)
00183 {
00184 int i;
00185 struct ld_fld* lfld;
00186
00187 if (fld == NULL || cfg == NULL) return 0;
00188
00189 for(i = 0; !DB_FLD_EMPTY(fld) && !DB_FLD_LAST(fld[i]); i++) {
00190 lfld = DB_GET_PAYLOAD(fld + i);
00191 lfld->attr.s = ld_find_attr_name(&lfld->syntax, cfg, fld[i].name);
00192 if (lfld->attr.s == NULL) lfld->attr.s = fld[i].name;
00193 if (lfld->attr.s) lfld->attr.len = strlen(lfld->attr.s);
00194 }
00195 return 0;
00196 }
00197
00198
00199 static inline int ldap_int2db_int(int* dst, str* src)
00200 {
00201 if (str2sint(src, dst) != 0) {
00202 ERR("ldap: Error while converting value '%.*s' to integer\n",
00203 src->len, ZSW(src->s));
00204 return -1;
00205 }
00206 return 0;
00207 }
00208
00209
00210 static inline int ldap_bit2db_int(int* dst, str* src)
00211 {
00212 int i, v;
00213
00214 if (src->len > 32) {
00215 WARN("ldap: bitString '%.*s'B is longer than 32 bits, truncating\n",
00216 src->len, ZSW(src->s));
00217 }
00218 v = 0;
00219 for(i = 0; i < src->len; i++) {
00220 v <<= 1;
00221 v += src->s[i] - '0';
00222 }
00223 *dst = v;
00224 return 0;
00225 }
00226
00227
00228 static inline int ldap_gentime2db_datetime(time_t* dst, str* src)
00229 {
00230 struct tm time;
00231
00232 if (src->len < 12) return -1;
00233
00234
00235 memset(&time, '\0', sizeof(struct tm));
00236
00237 strptime(src->s, "%Y%m%d%H%M%S", &time);
00238
00239 if (src->s[src->len-1] == 'Z' || src->s[src->len-5] == '-' || src->s[src->len-5] == '+') {
00240
00241 #ifdef HAVE_TIMEGM
00242 *dst = timegm(&time);
00243 #else
00244 *dst = _timegm(&time);
00245 #endif
00246
00247 if (src->s[src->len-1] != 'Z') {
00248
00249 memset(&time, '\0', sizeof(struct tm));
00250 strptime(src->s + src->len - 4, "%H%M", &time);
00251 switch (src->s[src->len-5]) {
00252 case '-':
00253 *dst -= time.tm_hour*3600+time.tm_min*60;
00254 break;
00255 case '+':
00256 *dst += time.tm_hour*3600+time.tm_min*60;
00257 break;
00258 default:
00259 ;
00260 }
00261 }
00262 }
00263 else {
00264
00265
00266
00267
00268
00269
00270
00271 time.tm_isdst = -1;
00272 *dst = timelocal(&time);
00273 }
00274
00275 return 0;
00276 }
00277
00278
00279 static inline int ldap_str2db_double(double* dst, char* src)
00280 {
00281 *dst = atof(src);
00282 return 0;
00283 }
00284
00285
00286 static inline int ldap_str2db_float(float* dst, char* src)
00287 {
00288 *dst = (float)atof(src);
00289 return 0;
00290 }
00291
00292 static inline int ldap_fld2db_fld(db_fld_t* fld, str v) {
00293
00294 switch(fld->type) {
00295 case DB_CSTR:
00296 fld->v.cstr = v.s;
00297 break;
00298
00299 case DB_STR:
00300 case DB_BLOB:
00301 fld->v.lstr.s = v.s;
00302 fld->v.lstr.len = v.len;
00303 break;
00304
00305 case DB_INT:
00306 case DB_BITMAP:
00307 if (v.s[0] == '\'' && v.s[v.len - 1] == 'B' &&
00308 v.s[v.len - 2] == '\'') {
00309 v.s++;
00310 v.len -= 3;
00311 if (ldap_bit2db_int(&fld->v.int4, &v) != 0) {
00312 ERR("ldap: Error while converting bit string '%.*s'\n",
00313 v.len, ZSW(v.s));
00314 return -1;
00315 }
00316 break;
00317 }
00318
00319 if (v.len == 4 && !strncasecmp("TRUE", v.s, v.len)) {
00320 fld->v.int4 = 1;
00321 break;
00322 }
00323
00324 if (v.len == 5 && !strncasecmp("FALSE", v.s, v.len)) {
00325 fld->v.int4 = 0;
00326 break;
00327 }
00328
00329 if (ldap_int2db_int(&fld->v.int4, &v) != 0) {
00330 ERR("ldap: Error while converting %.*s to integer\n",
00331 v.len, ZSW(v.s));
00332 return -1;
00333 }
00334 break;
00335
00336 case DB_DATETIME:
00337 if (ldap_gentime2db_datetime(&fld->v.time, &v) != 0) {
00338 ERR("ldap: Error while converting LDAP time value '%.*s'\n",
00339 v.len, ZSW(v.s));
00340 return -1;
00341 }
00342 break;
00343
00344 case DB_FLOAT:
00345
00346 if (ldap_str2db_float(&fld->v.flt, v.s) != 0) {
00347 ERR("ldap: Error while converting '%.*s' to float\n",
00348 v.len, ZSW(v.s));
00349 return -1;
00350 }
00351 break;
00352
00353 case DB_DOUBLE:
00354
00355 if (ldap_str2db_double(&fld->v.dbl, v.s) != 0) {
00356 ERR("ldap: Error while converting '%.*s' to double\n",
00357 v.len, ZSW(v.s));
00358 return -1;
00359 }
00360 break;
00361
00362 default:
00363 ERR("ldap: Unsupported field type: %d\n", fld->type);
00364 return -1;
00365 }
00366 return 0;
00367 }
00368
00369 int ld_ldap2fldinit(db_fld_t* fld, LDAP* ldap, LDAPMessage* msg)
00370 {
00371 return ld_ldap2fldex(fld, ldap, msg, 1);
00372 }
00373
00374 int ld_ldap2fld(db_fld_t* fld, LDAP* ldap, LDAPMessage* msg)
00375 {
00376 return ld_ldap2fldex(fld, ldap, msg, 0);
00377 }
00378
00379 int ld_incindex(db_fld_t* fld) {
00380 int i;
00381 struct ld_fld* lfld;
00382
00383
00384 if (fld == NULL) return 0;
00385
00386 i = 0;
00387 while (!DB_FLD_EMPTY(fld) && !DB_FLD_LAST(fld[i])) {
00388 lfld = DB_GET_PAYLOAD(fld + i);
00389 lfld->index++;
00390
00391 if (lfld->index >= lfld->valuesnum) {
00392 lfld->index = 0;
00393 } else {
00394 return 0;
00395 }
00396 i++;
00397 }
00398
00399
00400 return 1;
00401 }
00402
00403 #define CMP_NUM(fld_v,match_v,fld) \
00404 if (fld_v.fld == match_v.fld) \
00405 op = 0x02; \
00406 else if (fld_v.fld < match_v.fld) \
00407 op = 0x01; \
00408 else if (fld_v.fld > match_v.fld) \
00409 op = 0x04;
00410
00411 int ld_ldap2fldex(db_fld_t* fld, LDAP* ldap, LDAPMessage* msg, int init)
00412 {
00413 int i;
00414 struct ld_fld* lfld;
00415 str v;
00416
00417 if (fld == NULL || msg == NULL) return 0;
00418 for(i = 0; !DB_FLD_EMPTY(fld) && !DB_FLD_LAST(fld[i]); i++) {
00419 lfld = DB_GET_PAYLOAD(fld + i);
00420 if (init) {
00421 if (fld[i].type == DB_NONE) {
00422 switch (lfld->syntax) {
00423 case LD_SYNTAX_STRING:
00424 fld[i].type = DB_STR;
00425 break;
00426 case LD_SYNTAX_INT:
00427 case LD_SYNTAX_BOOL:
00428 case LD_SYNTAX_BIT:
00429 fld[i].type = DB_INT;
00430 break;
00431 case LD_SYNTAX_FLOAT:
00432 fld[i].type = DB_FLOAT;
00433 break;
00434
00435 case LD_SYNTAX_GENTIME:
00436 fld[i].type = DB_DATETIME;
00437 break;
00438 case LD_SYNTAX_BIN:
00439 fld[i].type = DB_BITMAP;
00440 break;
00441 }
00442
00443 }
00444
00445
00446 if (lfld->values) ldap_value_free_len(lfld->values);
00447 lfld->values = ldap_get_values_len(ldap, msg, lfld->attr.s);
00448 lfld->index = 0;
00449
00450 if (lfld->values == NULL || lfld->values[0] == NULL) {
00451 fld[i].flags |= DB_NULL;
00452
00453 lfld->valuesnum = 0;
00454 if (lfld->client_side_filtering && lfld->filter) {
00455 int j;
00456
00457 for (j=0; lfld->filter[j]; j++) {
00458 if (lfld->filter[j]->flags & DB_NULL && lfld->filter[j]->op == DB_EQ) {
00459 continue;
00460 }
00461 return 1;
00462 }
00463 }
00464 } else {
00465
00466 fld[i].flags &= ~DB_NULL;
00467 lfld->valuesnum = ldap_count_values_len(lfld->values);
00468
00469 if ((lfld->valuesnum > 1 || lfld->client_side_filtering) && lfld->filter) {
00470
00471
00472
00473
00474
00475
00476
00477
00478
00479
00480
00481
00482
00483
00484 do {
00485 int passed, j;
00486 for (j=0, passed = 1; lfld->filter[j] && passed; j++) {
00487 int op;
00488 op = 0x00;
00489 if (lfld->filter[j]->flags & DB_NULL) {
00490
00491 }
00492 else {
00493
00494 v.s = lfld->values[lfld->index]->bv_val;
00495 v.len = lfld->values[lfld->index]->bv_len;
00496
00497 if (ldap_fld2db_fld(fld + i, v) < 0) {
00498 passed = 0;
00499 break;
00500 }
00501 else {
00502 db_fld_val_t v;
00503 int t;
00504 static char buf[30];
00505 t = lfld->filter[j]->type;
00506
00507
00508
00509
00510 v = lfld->filter[j]->v;
00511 if (t == DB_CSTR) {
00512 v.lstr.s = v.cstr;
00513 v.lstr.len = strlen(v.lstr.s);
00514 t = DB_STR;
00515 }
00516 switch (fld[i].type) {
00517 case DB_CSTR:
00518 fld[i].v.lstr.s = fld[i].v.cstr;
00519 fld[i].v.lstr.len = strlen(fld[i].v.lstr.s);
00520 fld[i].type = DB_STR;
00521
00522 case DB_STR:
00523
00524 switch (t) {
00525 case DB_INT:
00526 v.lstr.len = snprintf(buf, sizeof(buf)-1, "%d", v.int4);
00527 v.lstr.s = buf;
00528 break;
00529
00530 default:
00531 goto skip_conv;
00532 }
00533 break;
00534 case DB_INT:
00535 switch (t) {
00536 case DB_DOUBLE:
00537 if ((double)(int)v.dbl != (double)v.dbl)
00538 goto skip_conv;
00539 v.int4 = v.dbl;
00540 break;
00541 case DB_FLOAT:
00542 if ((float)(int)v.flt != (float)v.flt)
00543 goto skip_conv;
00544 v.int4 = v.flt;
00545 break;
00546 case DB_STR:
00547 if (v.lstr.len > 0) {
00548 char c, *p;
00549 int n;
00550 c = v.lstr.s[v.lstr.len];
00551 v.lstr.s[v.lstr.len] = '\0';
00552 n = strtol(v.lstr.s, &p, 10);
00553 v.lstr.s[v.lstr.len] = c;
00554 if ((*p) != '\0') {
00555 goto skip_conv;
00556 }
00557 v.int4 = n;
00558 }
00559 break;
00560 default:
00561 goto skip_conv;
00562 }
00563 break;
00564 case DB_FLOAT:
00565 switch (t) {
00566 case DB_DOUBLE:
00567 v.flt = v.dbl;
00568 break;
00569 case DB_INT:
00570 v.flt = v.int4;
00571 break;
00572 #ifdef __USE_ISOC99
00573 case DB_STR:
00574 if (v.lstr.len > 0) {
00575 char c, *p;
00576 float n;
00577 c = v.lstr.s[v.lstr.len];
00578 v.lstr.s[v.lstr.len] = '\0';
00579 n = strtof(v.lstr.s, &p);
00580 v.lstr.s[v.lstr.len] = c;
00581 if ((*p) != '\0') {
00582 goto skip_conv;
00583 }
00584 v.flt = n;
00585 }
00586 break;
00587 #endif
00588 default:
00589 goto skip_conv;
00590 }
00591 break;
00592 case DB_DOUBLE:
00593 switch (t) {
00594 case DB_FLOAT:
00595 v.dbl = v.flt;
00596 break;
00597 case DB_INT:
00598 v.dbl = v.int4;
00599 break;
00600 case DB_STR:
00601 if (v.lstr.len > 0) {
00602 char c, *p;
00603 double n;
00604 c = v.lstr.s[v.lstr.len];
00605 v.lstr.s[v.lstr.len] = '\0';
00606 n = strtod(v.lstr.s, &p);
00607 v.lstr.s[v.lstr.len] = c;
00608 if ((*p) != '\0') {
00609 goto skip_conv;
00610 }
00611 v.dbl = n;
00612 }
00613 break;
00614 default:
00615 goto skip_conv;
00616 }
00617 break;
00618 case DB_BLOB:
00619 case DB_BITMAP:
00620 case DB_DATETIME:
00621 default:
00622 goto skip_conv;
00623 }
00624 t = fld[i].type;
00625 skip_conv:
00626 if (t == fld[i].type) {
00627
00628 switch (fld[i].type) {
00629 case DB_CSTR:
00630 case DB_STR:
00631 if (fld[i].v.lstr.len == v.lstr.len) {
00632 op = strncmp(fld[i].v.lstr.s, v.lstr.s, v.lstr.len);
00633 if (op < 0)
00634 op = 0x01;
00635 else if (op > 0)
00636 op = 0x04;
00637 else
00638 op = 0x02;
00639 }
00640 else if (fld[i].v.lstr.len < v.lstr.len) {
00641 op = strncmp(fld[i].v.lstr.s, v.lstr.s, fld[i].v.lstr.len);
00642 if (op < 0)
00643 op = 0x01;
00644 else
00645 op = 0x04;
00646 }
00647 else {
00648 op = strncmp(fld[i].v.lstr.s, v.lstr.s, v.lstr.len);
00649 if (op > 0)
00650 op = 0x04;
00651 else
00652 op = 0x01;
00653 }
00654 break;
00655 case DB_BLOB:
00656 if (fld[i].v.blob.len == v.blob.len && memcmp(fld[i].v.blob.s, v.blob.s, v.blob.len) == 0)
00657 op = 0x02;
00658 break;
00659 case DB_INT:
00660 CMP_NUM(fld[i].v, v, int4);
00661 break;
00662 case DB_BITMAP:
00663 CMP_NUM(fld[i].v, v, bitmap);
00664 break;
00665 case DB_DATETIME:
00666 CMP_NUM(fld[i].v, v, time);
00667 break;
00668 case DB_FLOAT:
00669 CMP_NUM(fld[i].v, v, flt);
00670 break;
00671 case DB_DOUBLE:
00672 CMP_NUM(fld[i].v, v, dbl);
00673 break;
00674 default:
00675 ;
00676 }
00677 }
00678
00679 }
00680 }
00681 switch (lfld->filter[j]->op) {
00682 case DB_EQ:
00683 passed = op == 0x02;
00684 break;
00685 case DB_NE:
00686 passed = (op & 0x02) == 0;
00687 break;
00688 case DB_LT:
00689 passed = op == 0x01;
00690 break;
00691 case DB_LEQ:
00692 passed = op == 0x01 || op == 0x02;
00693 break;
00694 case DB_GT:
00695 passed = op == 0x04;
00696 break;
00697 case DB_GEQ:
00698 passed = op == 0x04 || op == 0x02;
00699 break;
00700 default:
00701 ;
00702 }
00703 }
00704
00705 if (passed) {
00706 lfld->index++;
00707 }
00708 else {
00709 char *save_bvval;
00710 int save_bvlen;
00711 int i;
00712
00713
00714 save_bvval = lfld->values[lfld->index]->bv_val;
00715 save_bvlen = lfld->values[lfld->index]->bv_len;
00716 for (i=lfld->index+1; i < lfld->valuesnum; i++) {
00717 lfld->values[i-1]->bv_val = lfld->values[i]->bv_val;
00718 lfld->values[i-1]->bv_len = lfld->values[i]->bv_len;
00719 }
00720 lfld->values[lfld->valuesnum-1]->bv_val = save_bvval;
00721 lfld->values[lfld->valuesnum-1]->bv_len = save_bvlen;
00722 lfld->valuesnum--;
00723 }
00724
00725 } while (lfld->index < lfld->valuesnum);
00726
00727 if (lfld->valuesnum == 0) {
00728 return 1;
00729 }
00730 }
00731 }
00732
00733 lfld->index = 0;
00734 }
00735
00736
00737 if (!lfld->valuesnum)
00738 continue;
00739
00740 v.s = lfld->values[lfld->index]->bv_val;
00741 v.len = lfld->values[lfld->index]->bv_len;
00742
00743 if (ldap_fld2db_fld(fld + i, v) < 0)
00744 return -1;
00745
00746 }
00747 return 0;
00748 }
00749
00750
00751 static inline int db_int2ldap_str(struct sbuf* buf, db_fld_t* fld)
00752 {
00753 int len;
00754 char tmp[INT2STR_MAX_LEN + 1];
00755
00756 len = snprintf(tmp, INT2STR_MAX_LEN + 1, "%-d", fld->v.int4);
00757 if (len < 0 || len >= INT2STR_MAX_LEN + 1) {
00758 BUG("ldap: Error while converting integer to string\n");
00759 return -1;
00760 }
00761 return sb_add(buf, tmp, len);
00762 }
00763
00764
00765 static inline int db_datetime2ldap_gentime(struct sbuf* buf, db_fld_t* fld)
00766 {
00767 char tmp[16];
00768 struct tm* t;
00769
00770 t = gmtime(&fld->v.time);
00771 if (strftime(tmp, sizeof(tmp), "%Y%m%d%H%M%SZ", t) != sizeof(tmp)-1) {
00772 ERR("ldap: Error while converting time_t value to LDAP format\n");
00773 return -1;
00774 }
00775 return sb_add(buf, tmp, sizeof(tmp)-1);
00776 }
00777
00778
00779 static inline int db_int2ldap_bool(struct sbuf* buf, db_fld_t* fld)
00780 {
00781 if (fld->v.int4)
00782 return sb_add(buf, "TRUE", 4);
00783 else
00784 return sb_add(buf, "FALSE", 5);
00785 }
00786
00787
00788 static inline int db_uint2ldap_int(struct sbuf* buf, db_fld_t* fld)
00789 {
00790 char* num;
00791 int len, v;
00792
00793 v = fld->v.int4;
00794 num = int2str(v, &len);
00795 return sb_add(buf, num, len);
00796 }
00797
00798
00799 static inline int db_bit2ldap_bitstr(struct sbuf* buf, db_fld_t* fld)
00800 {
00801 int rv, i;
00802
00803 rv = 0;
00804 rv |= sb_add(buf, "'", 1);
00805
00806 i = 1 << (sizeof(fld->v.int4) * 8 - 1);
00807 while(i) {
00808 rv |= sb_add(buf, (fld->v.int4 & i)?"1":"0", 1);
00809 i = i >> 1;
00810 }
00811 rv |= sb_add(buf, "'B", 2);
00812 return rv;
00813 }
00814
00815
00816 static inline int db_float2ldap_str(struct sbuf* buf, db_fld_t* fld)
00817 {
00818 char tmp[16];
00819 int len;
00820
00821 len = snprintf(tmp, 16, "%-10.2f", fld->v.flt);
00822 if (len < 0 || len >= 16) {
00823 BUG("ldap: Error while converting float to string\n");
00824 return -1;
00825 }
00826 return sb_add(buf, tmp, len);
00827 }
00828
00829
00830 static inline int db_double2ldap_str(struct sbuf* buf, db_fld_t* fld)
00831 {
00832 char tmp[16];
00833 int len;
00834
00835 len = snprintf(tmp, 16, "%-10.2f", fld->v.dbl);
00836 if (len < 0 || len >= 16) {
00837 BUG("ldap: Error while converting double to string\n");
00838 return -1;
00839 }
00840 return sb_add(buf, tmp, len);
00841 }
00842
00843 static inline int ld_db2ldap(struct sbuf* buf, db_fld_t* fld) {
00844 struct ld_fld* lfld;
00845
00846 lfld = DB_GET_PAYLOAD(fld);
00847
00848 switch(fld->type) {
00849 case DB_CSTR:
00850 if (sb_add_esc(buf, fld->v.cstr,
00851 fld->v.cstr ? strlen(fld->v.cstr) : 0) != 0) goto error;
00852 break;
00853
00854 case DB_STR:
00855 if (sb_add_esc(buf, fld->v.lstr.s, fld->v.lstr.len) != 0) goto error;
00856 break;
00857
00858 case DB_INT:
00859 switch(lfld->syntax) {
00860 case LD_SYNTAX_STRING:
00861 case LD_SYNTAX_INT:
00862 case LD_SYNTAX_FLOAT:
00863 if (db_int2ldap_str(buf, fld))
00864 goto error;
00865 break;
00866
00867 case LD_SYNTAX_GENTIME:
00868 if (db_datetime2ldap_gentime(buf, fld))
00869 goto error;
00870 break;
00871
00872 case LD_SYNTAX_BIT:
00873 if (db_bit2ldap_bitstr(buf, fld))
00874 goto error;
00875 break;
00876
00877 case LD_SYNTAX_BOOL:
00878 if (db_int2ldap_bool(buf, fld))
00879 goto error;
00880 break;
00881
00882 default:
00883 ERR("ldap: Cannot convert integer field %s "
00884 "to LDAP attribute %.*s\n",
00885 fld->name, lfld->attr.len, ZSW(lfld->attr.s));
00886 goto error;
00887 }
00888 break;
00889
00890 case DB_BITMAP:
00891 switch(lfld->syntax) {
00892 case LD_SYNTAX_INT:
00893 if (db_uint2ldap_int(buf, fld))
00894 goto error;
00895 break;
00896
00897 case LD_SYNTAX_BIT:
00898 case LD_SYNTAX_STRING:
00899 if (db_bit2ldap_bitstr(buf, fld))
00900 goto error;
00901 break;
00902
00903 default:
00904 ERR("ldap: Cannot convert bitmap field %s "
00905 "to LDAP attribute %.*s\n",
00906 fld->name, lfld->attr.len, ZSW(lfld->attr.s));
00907 goto error;
00908 }
00909 break;
00910
00911 case DB_DATETIME:
00912 switch(lfld->syntax) {
00913 case LD_SYNTAX_STRING:
00914 case LD_SYNTAX_GENTIME:
00915 if (db_datetime2ldap_gentime(buf, fld))
00916 goto error;
00917 break;
00918
00919 case LD_SYNTAX_INT:
00920 if (db_uint2ldap_int(buf, fld))
00921 goto error;
00922 break;
00923
00924 default:
00925 ERR("ldap: Cannot convert datetime field %s "
00926 "to LDAP attribute %.*s\n",
00927 fld->name, lfld->attr.len, ZSW(lfld->attr.s));
00928 goto error;
00929 }
00930 break;
00931
00932 case DB_FLOAT:
00933 switch(lfld->syntax) {
00934 case LD_SYNTAX_STRING:
00935 case LD_SYNTAX_FLOAT:
00936 if (db_float2ldap_str(buf, fld))
00937 goto error;
00938 break;
00939
00940 default:
00941 ERR("ldap: Cannot convert float field %s "
00942 "to LDAP attribute %.*s\n",
00943 fld->name, lfld->attr.len, ZSW(lfld->attr.s));
00944 goto error;
00945 }
00946
00947 case DB_DOUBLE:
00948 switch(lfld->syntax) {
00949 case LD_SYNTAX_STRING:
00950 case LD_SYNTAX_FLOAT:
00951 if (db_float2ldap_str(buf, fld))
00952 goto error;
00953 break;
00954
00955 default:
00956 ERR("ldap: Cannot convert double field %s "
00957 "to LDAP attribute %.*s\n",
00958 fld->name, lfld->attr.len, ZSW(lfld->attr.s));
00959 goto error;
00960 break;
00961 }
00962 break;
00963
00964 case DB_BLOB:
00965 switch(lfld->syntax) {
00966 case LD_SYNTAX_STRING:
00967 case LD_SYNTAX_BIN:
00968 if (sb_add_esc(buf, fld->v.lstr.s, fld->v.lstr.len) < 0)
00969 goto error;
00970 break;
00971
00972 default:
00973 ERR("ldap: Cannot convert binary field %s "
00974 "to LDAP attribute %.*s\n",
00975 fld->name, lfld->attr.len, ZSW(lfld->attr.s));
00976 goto error;
00977 }
00978 break;
00979
00980 default:
00981 BUG("ldap: Unsupported field type encountered: %d\n", fld->type);
00982 goto error;
00983 }
00984 return 0;
00985 error:
00986 return -1;
00987 }
00988
00989
00990 inline static void skip_client_side_filtering_fields(db_cmd_t* cmd, db_fld_t **fld) {
00991 struct ld_fld* lfld;
00992 db_fld_t *f;
00993 try_next:
00994 if (DB_FLD_EMPTY(*fld) || DB_FLD_LAST(**fld)) return;
00995 for (f=cmd->result; !DB_FLD_EMPTY(f) && !DB_FLD_LAST(*f); f++) {
00996 lfld = DB_GET_PAYLOAD(f);
00997 if (lfld->client_side_filtering && lfld->filter) {
00998 int j;
00999 for (j = 0; lfld->filter[j]; j++) {
01000 if (lfld->filter[j] == *fld) {
01001 (*fld)++;
01002 goto try_next;
01003 }
01004 }
01005 }
01006 }
01007 }
01008
01009 int ld_prepare_ldap_filter(char** filter, db_cmd_t* cmd, str* add)
01010 {
01011 db_fld_t* fld;
01012 struct ld_fld* lfld;
01013 int rv = 0;
01014 struct sbuf buf = {
01015 .s = NULL, .len = 0,
01016 .size = 0, .increment = 128
01017 };
01018
01019 fld = cmd->match;
01020 skip_client_side_filtering_fields(cmd, &fld);
01021
01022
01023
01024
01025 if ((DB_FLD_EMPTY(fld) || DB_FLD_LAST(*fld)) && ((add->s == NULL) || !add->len)) {
01026 *filter = NULL;
01027 return 0;
01028 }
01029
01030 rv = sb_add(&buf, "(&", 2);
01031 if (add->s && add->len) {
01032
01033 rv |= sb_add(&buf, add->s, add->len);
01034 }
01035
01036 for(; !DB_FLD_EMPTY(fld) && !DB_FLD_LAST(*fld); fld++, skip_client_side_filtering_fields(cmd, &fld)) {
01037 int op;
01038 lfld = DB_GET_PAYLOAD(fld);
01039
01040 op = fld->op;
01041
01042 if (fld->flags & DB_NULL) {
01043 switch (op) {
01044 case DB_EQ:
01045
01046 op = DB_NE;
01047
01048 case DB_NE:
01049
01050 op = DB_EQ;
01051 break;
01052 default:
01053 ERR("ldap: Cannot compare null value field %s\n", fld->name);
01054 goto error;
01055 }
01056 }
01057
01058
01059
01060
01061
01062 switch (op) {
01063 case DB_LT:
01064 case DB_GT:
01065 case DB_NE:
01066 rv |= sb_add(&buf, "(!(", 3);
01067 rv |= sb_add(&buf, lfld->attr.s, lfld->attr.len);
01068 rv |= sb_add(&buf, "=", 1);
01069 if (fld->flags & DB_NULL) {
01070 rv |= sb_add(&buf, "*", 1);
01071 }
01072 else {
01073 if (ld_db2ldap(&buf, fld) < 0) {
01074 goto error;
01075 }
01076 }
01077 rv |= sb_add(&buf, "))", 2);
01078 break;
01079 default:
01080 ;
01081 }
01082 if (op != DB_NE) {
01083 rv |= sb_add(&buf, "(", 1);
01084 rv |= sb_add(&buf, lfld->attr.s, lfld->attr.len);
01085 switch (op) {
01086 case DB_LEQ:
01087 case DB_LT:
01088 rv |= sb_add(&buf, "<=", 2);
01089 break;
01090 case DB_GEQ:
01091 case DB_GT:
01092 rv |= sb_add(&buf, ">=", 2);
01093 break;
01094 case DB_EQ:
01095 rv |= sb_add(&buf, "=", 1);
01096 break;
01097 default:
01098 ;
01099 }
01100 if (fld->flags & DB_NULL) {
01101 rv |= sb_add(&buf, "*", 1);
01102 }
01103 else {
01104 if (ld_db2ldap(&buf, fld) < 0) {
01105 goto error;
01106 }
01107 }
01108 rv |= sb_add(&buf, ")", 1);
01109 }
01110 }
01111
01112 rv |= sb_add(&buf, ")", 1);
01113 rv |= sb_add(&buf, "", 1);
01114 if (rv) goto error;
01115
01116 *filter = buf.s;
01117 return 0;
01118
01119 error:
01120 if (buf.s) pkg_free(buf.s);
01121 return -1;
01122 }
01123
01124