Changeset 740 for vendor/current/source4/lib/ldb
- Timestamp:
- Nov 14, 2012, 12:59:34 PM (13 years ago)
- Location:
- vendor/current/source4/lib/ldb
- Files:
-
- 27 added
- 29 deleted
- 64 edited
Legend:
- Unmodified
- Added
- Removed
-
vendor/current/source4/lib/ldb/common/attrib_handlers.c
r414 r740 3 3 4 4 Copyright (C) Andrew Tridgell 2005 5 Copyright (C) Andrew Bartlett <abartlet@samba.org> 2006-2009 5 6 6 7 ** NOTE! The following LGPL license applies to the ldb … … 55 56 { 56 57 char *s, *t; 57 int l;58 size_t l; 58 59 59 60 if (!in || !out || !(in->data)) { … … 100 101 } 101 102 103 /* length limited conversion of a ldb_val to a int32_t */ 104 static int val_to_int64(const struct ldb_val *in, int64_t *v) 105 { 106 char *end; 107 char buf[64]; 108 109 /* make sure we don't read past the end of the data */ 110 if (in->length > sizeof(buf)-1) { 111 return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX; 112 } 113 strncpy(buf, (char *)in->data, in->length); 114 buf[in->length] = 0; 115 116 /* We've to use "strtoll" here to have the intended overflows. 117 * Otherwise we may get "LONG_MAX" and the conversion is wrong. */ 118 *v = (int64_t) strtoll(buf, &end, 0); 119 if (*end != 0) { 120 return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX; 121 } 122 return LDB_SUCCESS; 123 } 102 124 103 125 … … 109 131 const struct ldb_val *in, struct ldb_val *out) 110 132 { 111 char *end; 112 long long i = strtoll((char *)in->data, &end, 0); 113 if (*end != 0) { 114 return -1; 115 } 116 out->data = (uint8_t *)talloc_asprintf(mem_ctx, "%lld", i); 133 int64_t i; 134 int ret; 135 136 ret = val_to_int64(in, &i); 137 if (ret != LDB_SUCCESS) { 138 return ret; 139 } 140 out->data = (uint8_t *) talloc_asprintf(mem_ctx, "%lld", (long long)i); 117 141 if (out->data == NULL) { 118 return -1; 142 ldb_oom(ldb); 143 return LDB_ERR_OPERATIONS_ERROR; 119 144 } 120 145 out->length = strlen((char *)out->data); … … 128 153 const struct ldb_val *v1, const struct ldb_val *v2) 129 154 { 130 return strtoll((char *)v1->data, NULL, 0) - strtoll((char *)v2->data, NULL, 0); 155 int64_t i1=0, i2=0; 156 val_to_int64(v1, &i1); 157 val_to_int64(v2, &i2); 158 if (i1 == i2) return 0; 159 return i1 > i2? 1 : -1; 131 160 } 132 161 … … 241 270 talloc_free(b1); 242 271 talloc_free(b2); 243 if (memcmp(s1, s2, MIN(n1, n2)) == 0) { 272 ret = memcmp(s1, s2, MIN(n1, n2)); 273 if (ret == 0) { 244 274 if (n1 == n2) return 0; 245 275 if (n1 > n2) { … … 249 279 } 250 280 } 281 return ret; 251 282 } 252 283 … … 338 369 const struct ldb_val *v1, const struct ldb_val *v2) 339 370 { 340 time_t t1, t2; 341 t1 = ldb_string_to_time((char *)v1->data); 342 t2 = ldb_string_to_time((char *)v2->data); 343 return (int)t2 - (int)t1; 371 time_t t1=0, t2=0; 372 ldb_val_to_time(v1, &t1); 373 ldb_val_to_time(v2, &t2); 374 if (t1 == t2) return 0; 375 return t1 > t2? 1 : -1; 344 376 } 345 377 … … 350 382 const struct ldb_val *in, struct ldb_val *out) 351 383 { 352 time_t t = ldb_string_to_time((char *)in->data); 384 time_t t; 385 int ret; 386 ret = ldb_val_to_time(in, &t); 387 if (ret != LDB_SUCCESS) { 388 return ret; 389 } 353 390 out->data = (uint8_t *)ldb_timestring(mem_ctx, t); 354 391 if (out->data == NULL) { 355 return -1; 392 ldb_oom(ldb); 393 return LDB_ERR_OPERATIONS_ERROR; 356 394 } 357 395 out->length = strlen((char *)out->data); … … 421 459 const char *syntax) 422 460 { 423 int i;461 unsigned int i; 424 462 unsigned num_handlers = sizeof(ldb_standard_syntaxes)/sizeof(ldb_standard_syntaxes[0]); 425 463 /* TODO: should be replaced with a binary search */ … … 431 469 return NULL; 432 470 } 471 472 int ldb_any_comparison(struct ldb_context *ldb, void *mem_ctx, 473 ldb_attr_handler_t canonicalise_fn, 474 const struct ldb_val *v1, 475 const struct ldb_val *v2) 476 { 477 int ret, ret1, ret2; 478 struct ldb_val v1_canon, v2_canon; 479 TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx); 480 481 /* I could try and bail if tmp_ctx was NULL, but what return 482 * value would I use? 483 * 484 * It seems easier to continue on the NULL context 485 */ 486 ret1 = canonicalise_fn(ldb, tmp_ctx, v1, &v1_canon); 487 ret2 = canonicalise_fn(ldb, tmp_ctx, v2, &v2_canon); 488 489 if (ret1 == LDB_SUCCESS && ret2 == LDB_SUCCESS) { 490 ret = ldb_comparison_binary(ldb, mem_ctx, &v1_canon, &v2_canon); 491 } else { 492 ret = ldb_comparison_binary(ldb, mem_ctx, v1, v2); 493 } 494 talloc_free(tmp_ctx); 495 return ret; 496 } -
vendor/current/source4/lib/ldb/common/ldb.c
r414 r740 35 35 #define TEVENT_DEPRECATED 1 36 36 #include "ldb_private.h" 37 #include "ldb.h" 37 38 38 39 static int ldb_context_destructor(void *ptr) … … 92 93 struct ldb_context *ldb; 93 94 int ret; 95 const char *modules_path = getenv("LDB_MODULES_PATH"); 96 97 if (modules_path == NULL) { 98 modules_path = LDB_MODULESDIR; 99 } 100 101 ret = ldb_modules_load(modules_path, LDB_VERSION); 102 if (ret != LDB_SUCCESS) { 103 return NULL; 104 } 94 105 95 106 ldb = talloc_zero(mem_ctx, struct ldb_context); 96 /* FIXME: Hack a new event context so that CMD line utilities work 97 * until we have them all converted */ 107 /* A new event context so that callers who don't want ldb 108 * operating on thier global event context can work without 109 * having to provide their own private one explicitly */ 98 110 if (ev_ctx == NULL) { 99 ev_ctx = tevent_context_init( talloc_autofree_context());111 ev_ctx = tevent_context_init(ldb); 100 112 tevent_set_debug(ev_ctx, ldb_tevent_debug, ldb); 101 113 tevent_loop_allow_nesting(ev_ctx); … … 103 115 104 116 ret = ldb_setup_wellknown_attributes(ldb); 105 if (ret != 0) {117 if (ret != LDB_SUCCESS) { 106 118 talloc_free(ldb); 107 119 return NULL; … … 218 230 { 219 231 int ret; 220 c onst char *url2;232 char *url2; 221 233 /* We seem to need to do this here, or else some utilities don't 222 234 * get ldb backends */ … … 229 241 return LDB_ERR_OPERATIONS_ERROR; 230 242 } 231 ret = ldb_set_opaque(ldb, "ldb_url", talloc_strdup(ldb, url2));243 ret = ldb_set_opaque(ldb, "ldb_url", url2); 232 244 if (ret != LDB_SUCCESS) { 233 245 return ret; 234 246 } 235 247 236 ret = ldb_ connect_backend(ldb, url, options, &ldb->modules);248 ret = ldb_module_connect_backend(ldb, url, options, &ldb->modules); 237 249 if (ret != LDB_SUCCESS) { 238 250 return ret; … … 286 298 } 287 299 300 301 302 /* 303 set an ldb error based on file:line 304 */ 305 int ldb_error_at(struct ldb_context *ldb, int ecode, 306 const char *reason, const char *file, int line) 307 { 308 if (reason == NULL) { 309 reason = ldb_strerror(ecode); 310 } 311 ldb_asprintf_errstring(ldb, "%s at %s:%d", reason, file, line); 312 return ecode; 313 } 314 315 288 316 #define FIRST_OP_NOERR(ldb, op) do { \ 289 317 module = ldb->modules; \ 290 318 while (module && module->ops->op == NULL) module = module->next; \ 319 if ((ldb->flags & LDB_FLG_ENABLE_TRACING) && module) { \ 320 ldb_debug(ldb, LDB_DEBUG_TRACE, "ldb_trace_request: (%s)->" #op, \ 321 module->ops->name); \ 322 } \ 291 323 } while (0) 292 324 … … 336 368 } 337 369 } 370 if ((module && module->ldb->flags & LDB_FLG_ENABLE_TRACING)) { 371 ldb_debug(module->ldb, LDB_DEBUG_TRACE, "start ldb transaction error: %s", 372 ldb_errstring(module->ldb)); 373 } 338 374 return status; 339 375 } … … 375 411 /* if a module fails the prepare then we need 376 412 to call the end transaction for everyone */ 377 FIRST_OP(ldb, end_transaction);378 module->ops-> end_transaction(module);413 FIRST_OP(ldb, del_transaction); 414 module->ops->del_transaction(module); 379 415 if (ldb->err_string == NULL) { 380 416 /* no error string was setup by the backend */ … … 383 419 ldb_strerror(status), 384 420 status); 421 } 422 if ((module && module->ldb->flags & LDB_FLG_ENABLE_TRACING)) { 423 ldb_debug(module->ldb, LDB_DEBUG_TRACE, "prepare commit transaction error: %s", 424 ldb_errstring(module->ldb)); 385 425 } 386 426 } … … 433 473 status); 434 474 } 475 if ((module && module->ldb->flags & LDB_FLG_ENABLE_TRACING)) { 476 ldb_debug(module->ldb, LDB_DEBUG_TRACE, "commit ldb transaction error: %s", 477 ldb_errstring(module->ldb)); 478 } 435 479 /* cancel the transaction */ 436 480 FIRST_OP(ldb, del_transaction); … … 478 522 status); 479 523 } 524 if ((module && module->ldb->flags & LDB_FLG_ENABLE_TRACING)) { 525 ldb_debug(module->ldb, LDB_DEBUG_TRACE, "cancel ldb transaction error: %s", 526 ldb_errstring(module->ldb)); 527 } 480 528 } 481 529 return status; 482 530 } 531 532 /* 533 cancel a transaction with no error if no transaction is pending 534 used when we fork() to clear any parent transactions 535 */ 536 int ldb_transaction_cancel_noerr(struct ldb_context *ldb) 537 { 538 if (ldb->transaction_active > 0) { 539 return ldb_transaction_cancel(ldb); 540 } 541 return LDB_SUCCESS; 542 } 543 483 544 484 545 /* autostarts a transacion if none active */ … … 633 694 { 634 695 TALLOC_CTX *tmp_ctx = talloc_new(req); 635 int i;696 unsigned int i; 636 697 637 698 switch (req->operation) { … … 706 767 } else { 707 768 for (i=0; req->controls && req->controls[i]; i++) { 708 ldb_debug_add(ldb, " control: %s crit:%u data:%s\n", 709 req->controls[i]->oid, 710 req->controls[i]->critical, 711 req->controls[i]->data?"yes":"no"); 769 if (req->controls[i]->oid) { 770 ldb_debug_add(ldb, " control: %s crit:%u data:%s\n", 771 req->controls[i]->oid, 772 req->controls[i]->critical, 773 req->controls[i]->data?"yes":"no"); 774 } 712 775 } 713 776 } … … 716 779 717 780 talloc_free(tmp_ctx); 781 } 782 783 /* 784 check that the element flags don't have any internal bits set 785 */ 786 static int ldb_msg_check_element_flags(struct ldb_context *ldb, 787 const struct ldb_message *message) 788 { 789 unsigned i; 790 for (i=0; i<message->num_elements; i++) { 791 if (message->elements[i].flags & LDB_FLAG_INTERNAL_MASK) { 792 ldb_asprintf_errstring(ldb, "Invalid element flags 0x%08x on element %s in %s\n", 793 message->elements[i].flags, message->elements[i].name, 794 ldb_dn_get_linearized(message->dn)); 795 return LDB_ERR_UNSUPPORTED_CRITICAL_EXTENSION; 796 } 797 } 798 return LDB_SUCCESS; 718 799 } 719 800 … … 743 824 switch (req->operation) { 744 825 case LDB_SEARCH: 826 /* due to "ldb_build_search_req" base DN always != NULL */ 827 if (!ldb_dn_validate(req->op.search.base)) { 828 ldb_asprintf_errstring(ldb, "ldb_search: invalid basedn '%s'", 829 ldb_dn_get_linearized(req->op.search.base)); 830 return LDB_ERR_INVALID_DN_SYNTAX; 831 } 745 832 FIRST_OP(ldb, search); 746 833 ret = module->ops->search(module, req); 747 834 break; 748 835 case LDB_ADD: 836 if (!ldb_dn_validate(req->op.add.message->dn)) { 837 ldb_asprintf_errstring(ldb, "ldb_add: invalid dn '%s'", 838 ldb_dn_get_linearized(req->op.add.message->dn)); 839 return LDB_ERR_INVALID_DN_SYNTAX; 840 } 841 /* 842 * we have to normalize here, as so many places 843 * in modules and backends assume we don't have two 844 * elements with the same name 845 */ 846 ret = ldb_msg_normalize(ldb, req, req->op.add.message, 847 discard_const(&req->op.add.message)); 848 if (ret != LDB_SUCCESS) { 849 ldb_oom(ldb); 850 return LDB_ERR_OPERATIONS_ERROR; 851 } 749 852 FIRST_OP(ldb, add); 853 ret = ldb_msg_check_element_flags(ldb, req->op.add.message); 854 if (ret != LDB_SUCCESS) { 855 return ret; 856 } 750 857 ret = module->ops->add(module, req); 751 858 break; 752 859 case LDB_MODIFY: 860 if (!ldb_dn_validate(req->op.mod.message->dn)) { 861 ldb_asprintf_errstring(ldb, "ldb_modify: invalid dn '%s'", 862 ldb_dn_get_linearized(req->op.mod.message->dn)); 863 return LDB_ERR_INVALID_DN_SYNTAX; 864 } 753 865 FIRST_OP(ldb, modify); 866 ret = ldb_msg_check_element_flags(ldb, req->op.mod.message); 867 if (ret != LDB_SUCCESS) { 868 return ret; 869 } 754 870 ret = module->ops->modify(module, req); 755 871 break; 756 872 case LDB_DELETE: 873 if (!ldb_dn_validate(req->op.del.dn)) { 874 ldb_asprintf_errstring(ldb, "ldb_delete: invalid dn '%s'", 875 ldb_dn_get_linearized(req->op.del.dn)); 876 return LDB_ERR_INVALID_DN_SYNTAX; 877 } 757 878 FIRST_OP(ldb, del); 758 879 ret = module->ops->del(module, req); 759 880 break; 760 881 case LDB_RENAME: 882 if (!ldb_dn_validate(req->op.rename.olddn)) { 883 ldb_asprintf_errstring(ldb, "ldb_rename: invalid olddn '%s'", 884 ldb_dn_get_linearized(req->op.rename.olddn)); 885 return LDB_ERR_INVALID_DN_SYNTAX; 886 } 887 if (!ldb_dn_validate(req->op.rename.newdn)) { 888 ldb_asprintf_errstring(ldb, "ldb_rename: invalid newdn '%s'", 889 ldb_dn_get_linearized(req->op.rename.newdn)); 890 return LDB_ERR_INVALID_DN_SYNTAX; 891 } 761 892 FIRST_OP(ldb, rename); 762 893 ret = module->ops->rename(module, req); … … 794 925 { 795 926 struct ldb_result *res; 796 int n;927 unsigned int n; 797 928 798 929 res = talloc_get_type(req->context, struct ldb_result); … … 852 983 } 853 984 854 int ldb_op_default_callback(struct ldb_request *req, struct ldb_reply *ares) 855 { 985 int ldb_modify_default_callback(struct ldb_request *req, struct ldb_reply *ares) 986 { 987 struct ldb_result *res; 988 unsigned int n; 856 989 int ret; 990 991 res = talloc_get_type(req->context, struct ldb_result); 857 992 858 993 if (!ares) { … … 866 1001 } 867 1002 1003 switch (ares->type) { 1004 case LDB_REPLY_REFERRAL: 1005 if (res->refs) { 1006 for (n = 0; res->refs[n]; n++) /*noop*/ ; 1007 } else { 1008 n = 0; 1009 } 1010 1011 res->refs = talloc_realloc(res, res->refs, char *, n + 2); 1012 if (! res->refs) { 1013 return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR); 1014 } 1015 1016 res->refs[n] = talloc_move(res->refs, &ares->referral); 1017 res->refs[n + 1] = NULL; 1018 break; 1019 1020 case LDB_REPLY_DONE: 1021 talloc_free(ares); 1022 return ldb_request_done(req, LDB_SUCCESS); 1023 default: 1024 talloc_free(ares); 1025 ldb_set_errstring(req->handle->ldb, "Invalid reply type!"); 1026 return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR); 1027 } 1028 1029 talloc_free(ares); 1030 return ldb_request_done(req, LDB_SUCCESS); 1031 } 1032 1033 int ldb_op_default_callback(struct ldb_request *req, struct ldb_reply *ares) 1034 { 1035 int ret; 1036 1037 if (!ares) { 1038 return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR); 1039 } 1040 1041 if (ares->error != LDB_SUCCESS) { 1042 ret = ares->error; 1043 talloc_free(ares); 1044 return ldb_request_done(req, ret); 1045 } 1046 868 1047 if (ares->type != LDB_REPLY_DONE) { 869 1048 talloc_free(ares); … … 878 1057 int ldb_build_search_req_ex(struct ldb_request **ret_req, 879 1058 struct ldb_context *ldb, 880 void*mem_ctx,1059 TALLOC_CTX *mem_ctx, 881 1060 struct ldb_dn *base, 882 1061 enum ldb_scope scope, … … 928 1107 if (parent) { 929 1108 req->handle->nesting++; 1109 req->handle->parent = parent; 1110 req->handle->flags = parent->handle->flags; 930 1111 } 931 1112 … … 936 1117 int ldb_build_search_req(struct ldb_request **ret_req, 937 1118 struct ldb_context *ldb, 938 void*mem_ctx,1119 TALLOC_CTX *mem_ctx, 939 1120 struct ldb_dn *base, 940 1121 enum ldb_scope scope, … … 966 1147 int ldb_build_add_req(struct ldb_request **ret_req, 967 1148 struct ldb_context *ldb, 968 void*mem_ctx,1149 TALLOC_CTX *mem_ctx, 969 1150 const struct ldb_message *message, 970 1151 struct ldb_control **controls, … … 999 1180 if (parent) { 1000 1181 req->handle->nesting++; 1182 req->handle->parent = parent; 1183 req->handle->flags = parent->handle->flags; 1001 1184 } 1002 1185 … … 1008 1191 int ldb_build_mod_req(struct ldb_request **ret_req, 1009 1192 struct ldb_context *ldb, 1010 void*mem_ctx,1193 TALLOC_CTX *mem_ctx, 1011 1194 const struct ldb_message *message, 1012 1195 struct ldb_control **controls, … … 1041 1224 if (parent) { 1042 1225 req->handle->nesting++; 1226 req->handle->parent = parent; 1227 req->handle->flags = parent->handle->flags; 1043 1228 } 1044 1229 … … 1050 1235 int ldb_build_del_req(struct ldb_request **ret_req, 1051 1236 struct ldb_context *ldb, 1052 void*mem_ctx,1237 TALLOC_CTX *mem_ctx, 1053 1238 struct ldb_dn *dn, 1054 1239 struct ldb_control **controls, … … 1083 1268 if (parent) { 1084 1269 req->handle->nesting++; 1270 req->handle->parent = parent; 1271 req->handle->flags = parent->handle->flags; 1085 1272 } 1086 1273 … … 1092 1279 int ldb_build_rename_req(struct ldb_request **ret_req, 1093 1280 struct ldb_context *ldb, 1094 void*mem_ctx,1281 TALLOC_CTX *mem_ctx, 1095 1282 struct ldb_dn *olddn, 1096 1283 struct ldb_dn *newdn, … … 1127 1314 if (parent) { 1128 1315 req->handle->nesting++; 1316 req->handle->parent = parent; 1317 req->handle->flags = parent->handle->flags; 1129 1318 } 1130 1319 … … 1165 1354 int ldb_build_extended_req(struct ldb_request **ret_req, 1166 1355 struct ldb_context *ldb, 1167 void*mem_ctx,1356 TALLOC_CTX *mem_ctx, 1168 1357 const char *oid, 1169 1358 void *data, … … 1200 1389 if (parent) { 1201 1390 req->handle->nesting++; 1391 req->handle->parent = parent; 1392 req->handle->flags = parent->handle->flags; 1202 1393 } 1203 1394 … … 1292 1483 ldb_search_default_callback, 1293 1484 NULL); 1485 ldb_req_set_location(req, "ldb_search"); 1294 1486 1295 1487 if (ret != LDB_SUCCESS) goto done; … … 1335 1527 ldb_op_default_callback, 1336 1528 NULL); 1529 ldb_req_set_location(req, "ldb_add"); 1337 1530 1338 1531 if (ret != LDB_SUCCESS) return ret; … … 1365 1558 ldb_op_default_callback, 1366 1559 NULL); 1560 ldb_req_set_location(req, "ldb_modify"); 1367 1561 1368 1562 if (ret != LDB_SUCCESS) return ret; … … 1390 1584 ldb_op_default_callback, 1391 1585 NULL); 1586 ldb_req_set_location(req, "ldb_delete"); 1392 1587 1393 1588 if (ret != LDB_SUCCESS) return ret; … … 1416 1611 ldb_op_default_callback, 1417 1612 NULL); 1613 ldb_req_set_location(req, "ldb_rename"); 1418 1614 1419 1615 if (ret != LDB_SUCCESS) return ret; … … 1640 1836 ldb->flags = flags; 1641 1837 } 1838 1839 1840 /* 1841 set the location in a ldb request. Used for debugging 1842 */ 1843 void ldb_req_set_location(struct ldb_request *req, const char *location) 1844 { 1845 if (req && req->handle) { 1846 req->handle->location = location; 1847 } 1848 } 1849 1850 /* 1851 return the location set with dsdb_req_set_location 1852 */ 1853 const char *ldb_req_location(struct ldb_request *req) 1854 { 1855 return req->handle->location; 1856 } 1857 1858 /** 1859 mark a request as untrusted. This tells the rootdse module to remove 1860 unregistered controls 1861 */ 1862 void ldb_req_mark_untrusted(struct ldb_request *req) 1863 { 1864 req->handle->flags |= LDB_HANDLE_FLAG_UNTRUSTED; 1865 } 1866 1867 /** 1868 mark a request as trusted. 1869 */ 1870 void ldb_req_mark_trusted(struct ldb_request *req) 1871 { 1872 req->handle->flags &= ~LDB_HANDLE_FLAG_UNTRUSTED; 1873 } 1874 1875 /** 1876 return true is a request is untrusted 1877 */ 1878 bool ldb_req_is_untrusted(struct ldb_request *req) 1879 { 1880 return (req->handle->flags & LDB_HANDLE_FLAG_UNTRUSTED) != 0; 1881 } -
vendor/current/source4/lib/ldb/common/ldb_attributes.c
r414 r740 50 50 const struct ldb_schema_syntax *syntax) 51 51 { 52 int i, n;52 unsigned int i, n; 53 53 struct ldb_schema_attribute *a; 54 54 … … 123 123 const char *name) 124 124 { 125 int i, e, b = 0, r; 125 /* for binary search we need signed variables */ 126 unsigned int i, e, b = 0; 127 int r; 126 128 const struct ldb_schema_attribute *def = &ldb_attribute_default; 127 129 … … 135 137 e = ldb->schema.num_attributes - 1; 136 138 137 while (b <= e) { 138 139 while ((b <= e) && (e != (unsigned int) -1)) { 139 140 i = (b + e) / 2; 140 141 … … 148 149 b = i + 1; 149 150 } 150 151 151 } 152 152 … … 180 180 { 181 181 const struct ldb_schema_attribute *a; 182 int i;182 ptrdiff_t i; 183 183 184 184 a = ldb_schema_attribute_by_name_internal(ldb, name); … … 233 233 { "objectClass", LDB_SYNTAX_OBJECTCLASS } 234 234 }; 235 int i;235 unsigned int i; 236 236 int ret; 237 237 … … 255 255 const struct ldb_dn_extended_syntax *syntax) 256 256 { 257 int n;257 unsigned int n; 258 258 struct ldb_dn_extended_syntax *a; 259 259 … … 285 285 const char *name) 286 286 { 287 int i;287 unsigned int i; 288 288 for (i=0; i < ldb->schema.num_dn_extended_syntax; i++) { 289 289 if (ldb_attr_cmp(ldb->schema.dn_extended_syntax[i].name, name) == 0) { -
vendor/current/source4/lib/ldb/common/ldb_controls.c
r414 r740 38 38 struct ldb_control *ldb_request_get_control(struct ldb_request *req, const char *oid) 39 39 { 40 int i;40 unsigned int i; 41 41 42 42 if (req->controls != NULL) { 43 43 for (i = 0; req->controls[i]; i++) { 44 if ( strcmp(oid, req->controls[i]->oid) == 0) {44 if (req->controls[i]->oid && strcmp(oid, req->controls[i]->oid) == 0) { 45 45 break; 46 46 } … … 57 57 struct ldb_control *ldb_reply_get_control(struct ldb_reply *rep, const char *oid) 58 58 { 59 int i;59 unsigned int i; 60 60 61 61 if (rep->controls != NULL) { 62 62 for (i = 0; rep->controls[i]; i++) { 63 if ( strcmp(oid, rep->controls[i]->oid) == 0) {63 if (rep->controls[i]->oid && strcmp(oid, rep->controls[i]->oid) == 0) { 64 64 break; 65 65 } … … 72 72 } 73 73 74 /* saves the current controls list into the "saver" and replace the one in req with a new one excluding 75 the "exclude" control */ 76 /* returns 0 on error */ 77 int save_controls(struct ldb_control *exclude, struct ldb_request *req, struct ldb_control ***saver) 74 /* 75 * Saves the current controls list into the "saver" (can also be NULL) and 76 * replace the one in "req" with a new one excluding the "exclude" control 77 * (if it is NULL then the list remains the same) 78 * 79 * Returns 0 on error. 80 */ 81 int ldb_save_controls(struct ldb_control *exclude, struct ldb_request *req, struct ldb_control ***saver) 78 82 { 79 struct ldb_control **lcs; 80 int i, j; 81 82 *saver = req->controls; 83 for (i = 0; req->controls[i]; i++); 84 if (i == 1) { 83 struct ldb_control **lcs, **lcs_old; 84 unsigned int i, j; 85 86 lcs_old = req->controls; 87 if (saver != NULL) { 88 *saver = lcs_old; 89 } 90 91 for (i = 0; req->controls && req->controls[i]; i++); 92 if (i == 0) { 85 93 req->controls = NULL; 86 94 return 1; 87 95 } 88 96 89 lcs = talloc_array(req, struct ldb_control *, i );97 lcs = talloc_array(req, struct ldb_control *, i + 1); 90 98 if (!lcs) { 91 99 return 0; 92 100 } 93 101 94 for (i = 0, j = 0; (*saver)[i]; i++) {95 if (exclude == (*saver)[i]) continue;96 lcs[j] = (*saver)[i];102 for (i = 0, j = 0; lcs_old[i]; i++) { 103 if (exclude == lcs_old[i]) continue; 104 lcs[j] = lcs_old[i]; 97 105 j++; 98 106 } 99 107 lcs[j] = NULL; 100 108 101 req->controls = lcs; 109 req->controls = talloc_realloc(req, lcs, struct ldb_control *, j + 1); 110 if (req->controls == NULL) { 111 return 0; 112 } 102 113 return 1; 103 114 } 104 115 116 /* 117 * Returns a list of controls, except the one specified with "exclude" (can 118 * also be NULL). Included controls become a child of returned list if they 119 * were children of "controls_in". 120 * 121 * Returns NULL on error (OOM) or an empty control list. 122 */ 123 struct ldb_control **ldb_controls_except_specified(struct ldb_control **controls_in, 124 TALLOC_CTX *mem_ctx, 125 struct ldb_control *exclude) 126 { 127 struct ldb_control **lcs = NULL; 128 unsigned int i, j, n; 129 130 for (i = 0; controls_in && controls_in[i]; i++); 131 if (i == 0) { 132 return NULL; 133 } 134 n = i; 135 136 for (i = 0, j = 0; controls_in && controls_in[i]; i++) { 137 if (exclude == controls_in[i]) continue; 138 139 if (!lcs) { 140 /* Allocate here so if we remove the only 141 * control, or there were no controls, we 142 * don't allocate at all, and just return 143 * NULL */ 144 lcs = talloc_array(mem_ctx, struct ldb_control *, 145 n + 1); 146 if (!lcs) { 147 return NULL; 148 } 149 } 150 151 lcs[j] = controls_in[i]; 152 talloc_reparent(controls_in, lcs, lcs[j]); 153 j++; 154 } 155 if (lcs) { 156 lcs[j] = NULL; 157 158 lcs = talloc_realloc(mem_ctx, lcs, struct ldb_control *, j + 1); 159 } 160 161 return lcs; 162 } 163 105 164 /* check if there's any control marked as critical in the list */ 106 165 /* return True if any, False if none */ 107 int check_critical_controls(struct ldb_control **controls)166 int ldb_check_critical_controls(struct ldb_control **controls) 108 167 { 109 int i;168 unsigned int i; 110 169 111 170 if (controls == NULL) { … … 123 182 124 183 int ldb_request_add_control(struct ldb_request *req, const char *oid, bool critical, void *data) 184 { 185 unsigned int i, n; 186 struct ldb_control **ctrls; 187 struct ldb_control *ctrl; 188 189 for (n=0; req->controls && req->controls[n];n++) { 190 /* having two controls of the same OID makes no sense */ 191 if (req->controls[n]->oid && strcmp(oid, req->controls[n]->oid) == 0) { 192 return LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS; 193 } 194 } 195 196 ctrls = talloc_array(req, 197 struct ldb_control *, 198 n + 2); 199 if (!ctrls) return LDB_ERR_OPERATIONS_ERROR; 200 201 for (i=0; i<n; i++) { 202 ctrls[i] = req->controls[i]; 203 } 204 205 req->controls = ctrls; 206 ctrls[n] = NULL; 207 ctrls[n+1] = NULL; 208 209 ctrl = talloc(ctrls, struct ldb_control); 210 if (!ctrl) return LDB_ERR_OPERATIONS_ERROR; 211 212 ctrl->oid = talloc_strdup(ctrl, oid); 213 if (!ctrl->oid) return LDB_ERR_OPERATIONS_ERROR; 214 ctrl->critical = critical; 215 ctrl->data = data; 216 217 ctrls[n] = ctrl; 218 return LDB_SUCCESS; 219 } 220 221 int ldb_reply_add_control(struct ldb_reply *ares, const char *oid, bool critical, void *data) 125 222 { 126 223 unsigned n; … … 128 225 struct ldb_control *ctrl; 129 226 130 for (n=0; req->controls && req->controls[n];) {227 for (n=0; ares->controls && ares->controls[n];) { 131 228 /* having two controls of the same OID makes no sense */ 132 if ( strcmp(oid, req->controls[n]->oid) == 0) {229 if (ares->controls[n]->oid && strcmp(oid, ares->controls[n]->oid) == 0) { 133 230 return LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS; 134 231 } … … 136 233 } 137 234 138 ctrls = talloc_realloc( req, req->controls,235 ctrls = talloc_realloc(ares, ares->controls, 139 236 struct ldb_control *, 140 237 n + 2); 141 238 if (!ctrls) return LDB_ERR_OPERATIONS_ERROR; 142 req->controls = ctrls;239 ares->controls = ctrls; 143 240 ctrls[n] = NULL; 144 241 ctrls[n+1] = NULL; … … 156 253 } 157 254 158 /* Parse controls from the format used on the command line and in ejs */ 159 160 struct ldb_control **ldb_parse_control_strings(struct ldb_context *ldb, void *mem_ctx, const char **control_strings) 255 /* Add a control to the request, replacing the old one if it is already in the request */ 256 int ldb_request_replace_control(struct ldb_request *req, const char *oid, bool critical, void *data) 161 257 { 162 int i; 163 struct ldb_control **ctrl; 164 258 unsigned int n; 259 int ret; 260 261 ret = ldb_request_add_control(req, oid, critical, data); 262 if (ret != LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS) { 263 return ret; 264 } 265 266 for (n=0; req->controls[n];n++) { 267 if (req->controls[n]->oid && strcmp(oid, req->controls[n]->oid) == 0) { 268 req->controls[n]->critical = critical; 269 req->controls[n]->data = data; 270 return LDB_SUCCESS; 271 } 272 } 273 274 return LDB_ERR_OPERATIONS_ERROR; 275 } 276 277 /* 278 * Return a control as string 279 * the project (ie. name:value1:value2:...:valuen 280 * The string didn't include the criticity of the critical flag 281 */ 282 char *ldb_control_to_string(TALLOC_CTX *mem_ctx, const struct ldb_control *control) 283 { 284 char *res = NULL; 285 286 if (strcmp(control->oid, LDB_CONTROL_PAGED_RESULTS_OID) == 0) { 287 struct ldb_paged_control *rep_control = talloc_get_type(control->data, struct ldb_paged_control); 288 char *cookie; 289 290 cookie = ldb_base64_encode(mem_ctx, rep_control->cookie, rep_control->cookie_len); 291 if (cookie == NULL) { 292 return NULL; 293 } 294 if (cookie[0] != '\0') { 295 res = talloc_asprintf(mem_ctx, "%s:%d:%s", 296 LDB_CONTROL_PAGED_RESULTS_NAME, 297 control->critical, 298 cookie); 299 300 talloc_free(cookie); 301 } else { 302 res = talloc_asprintf(mem_ctx, "%s:%d", 303 LDB_CONTROL_PAGED_RESULTS_NAME, 304 control->critical); 305 } 306 return res; 307 } 308 309 if (strcmp(control->oid, LDB_CONTROL_VLV_RESP_OID) == 0) { 310 struct ldb_vlv_resp_control *rep_control = talloc_get_type(control->data, 311 struct ldb_vlv_resp_control); 312 313 res = talloc_asprintf(mem_ctx, "%s:%d:%d:%d:%d:%d:%s", 314 LDB_CONTROL_VLV_RESP_NAME, 315 control->critical, 316 rep_control->targetPosition, 317 rep_control->contentCount, 318 rep_control->vlv_result, 319 rep_control->ctxid_len, 320 rep_control->contextId); 321 322 return res; 323 } 324 325 if (strcmp(control->oid, LDB_CONTROL_SORT_RESP_OID) == 0) { 326 struct ldb_sort_resp_control *rep_control = talloc_get_type(control->data, 327 struct ldb_sort_resp_control); 328 329 res = talloc_asprintf(mem_ctx, "%s:%d:%d:%s", 330 LDB_CONTROL_SORT_RESP_NAME, 331 control->critical, 332 rep_control->result, 333 rep_control->attr_desc); 334 335 return res; 336 } 337 338 if (strcmp(control->oid, LDB_CONTROL_ASQ_OID) == 0) { 339 struct ldb_asq_control *rep_control = talloc_get_type(control->data, 340 struct ldb_asq_control); 341 342 res = talloc_asprintf(mem_ctx, "%s:%d:%d", 343 LDB_CONTROL_SORT_RESP_NAME, 344 control->critical, 345 rep_control->result); 346 347 return res; 348 } 349 350 if (strcmp(control->oid, LDB_CONTROL_DIRSYNC_OID) == 0) { 351 char *cookie; 352 struct ldb_dirsync_control *rep_control = talloc_get_type(control->data, 353 struct ldb_dirsync_control); 354 355 cookie = ldb_base64_encode(mem_ctx, rep_control->cookie, 356 rep_control->cookie_len); 357 if (cookie == NULL) { 358 return NULL; 359 } 360 res = talloc_asprintf(mem_ctx, "%s:%d:%d:%d:%s", 361 LDB_CONTROL_DIRSYNC_NAME, 362 control->critical, 363 rep_control->flags, 364 rep_control->max_attributes, 365 cookie); 366 367 talloc_free(cookie); 368 return res; 369 } 370 371 /* 372 * From here we don't know the control 373 */ 374 if (control->data == NULL) { 375 /* 376 * We don't know the control but there is no real data attached to it 377 * so we can represent it with local_oid:oid:criticity 378 */ 379 res = talloc_asprintf(mem_ctx, "local_oid:%s:%d", 380 control->oid, 381 control->critical); 382 return res; 383 } 384 385 res = talloc_asprintf(mem_ctx, "unknown oid:%s", 386 control->oid); 387 return res; 388 } 389 390 391 /* 392 * A little trick to allow to use constants defined in headers rather than 393 * hardwritten in the file hardwritten in the file 394 * sizeof will return the \0 char as well so it will take the place of ":" in the 395 * length of the string 396 */ 397 #define LDB_CONTROL_CMP(control, NAME) strncmp(control, NAME ":", sizeof(NAME)) 398 399 /* Parse one string and return associated control if parsing is successful*/ 400 struct ldb_control *ldb_parse_control_from_string(struct ldb_context *ldb, TALLOC_CTX *mem_ctx, const char *control_strings) 401 { 402 struct ldb_control *ctrl; 165 403 char *error_string = NULL; 166 404 167 if (control_strings == NULL || control_strings[0] == NULL) 405 if (!(ctrl = talloc(mem_ctx, struct ldb_control))) { 406 ldb_oom(ldb); 168 407 return NULL; 169 170 for (i = 0; control_strings[i]; i++); 171 172 ctrl = talloc_array(mem_ctx, struct ldb_control *, i + 1); 173 174 for (i = 0; control_strings[i]; i++) { 175 if (strncmp(control_strings[i], "vlv:", 4) == 0) { 176 struct ldb_vlv_req_control *control; 177 const char *p; 178 char attr[1024]; 179 char ctxid[1024]; 180 int crit, bc, ac, os, cc, ret; 181 182 attr[0] = '\0'; 183 ctxid[0] = '\0'; 184 p = &(control_strings[i][4]); 185 ret = sscanf(p, "%d:%d:%d:%d:%d:%1023[^$]", &crit, &bc, &ac, &os, &cc, ctxid); 186 if (ret < 5) { 187 ret = sscanf(p, "%d:%d:%d:%1023[^:]:%1023[^$]", &crit, &bc, &ac, attr, ctxid); 188 } 189 190 if ((ret < 4) || (crit < 0) || (crit > 1)) { 191 error_string = talloc_asprintf(mem_ctx, "invalid server_sort control syntax\n"); 192 error_string = talloc_asprintf_append(error_string, " syntax: crit(b):bc(n):ac(n):<os(n):cc(n)|attr(s)>[:ctxid(o)]\n"); 193 error_string = talloc_asprintf_append(error_string, " note: b = boolean, n = number, s = string, o = b64 binary blob"); 408 } 409 410 if (LDB_CONTROL_CMP(control_strings, 411 LDB_CONTROL_VLV_REQ_NAME) == 0) { 412 struct ldb_vlv_req_control *control; 413 const char *p; 414 char attr[1024]; 415 char ctxid[1024]; 416 int crit, bc, ac, os, cc, ret; 417 418 attr[0] = '\0'; 419 ctxid[0] = '\0'; 420 p = &(control_strings[sizeof(LDB_CONTROL_VLV_REQ_NAME)]); 421 ret = sscanf(p, "%d:%d:%d:%d:%d:%1023[^$]", &crit, &bc, &ac, &os, &cc, ctxid); 422 if (ret < 5) { 423 ret = sscanf(p, "%d:%d:%d:%1023[^:]:%1023[^$]", &crit, &bc, &ac, attr, ctxid); 424 } 425 426 if ((ret < 4) || (crit < 0) || (crit > 1)) { 427 error_string = talloc_asprintf(mem_ctx, "invalid server_sort control syntax\n"); 428 error_string = talloc_asprintf_append(error_string, " syntax: crit(b):bc(n):ac(n):<os(n):cc(n)|attr(s)>[:ctxid(o)]\n"); 429 error_string = talloc_asprintf_append(error_string, " note: b = boolean, n = number, s = string, o = b64 binary blob"); 430 ldb_set_errstring(ldb, error_string); 431 talloc_free(error_string); 432 return NULL; 433 } 434 ctrl->oid = LDB_CONTROL_VLV_REQ_OID; 435 ctrl->critical = crit; 436 if (!(control = talloc(ctrl, 437 struct ldb_vlv_req_control))) { 438 ldb_oom(ldb); 439 return NULL; 440 } 441 control->beforeCount = bc; 442 control->afterCount = ac; 443 if (attr[0]) { 444 control->type = 1; 445 control->match.gtOrEq.value = talloc_strdup(control, attr); 446 control->match.gtOrEq.value_len = strlen(attr); 447 } else { 448 control->type = 0; 449 control->match.byOffset.offset = os; 450 control->match.byOffset.contentCount = cc; 451 } 452 if (ctxid[0]) { 453 control->ctxid_len = ldb_base64_decode(ctxid); 454 control->contextId = (char *)talloc_memdup(control, ctxid, control->ctxid_len); 455 } else { 456 control->ctxid_len = 0; 457 control->contextId = NULL; 458 } 459 ctrl->data = control; 460 461 return ctrl; 462 } 463 464 if (LDB_CONTROL_CMP(control_strings, LDB_CONTROL_DIRSYNC_NAME) == 0) { 465 struct ldb_dirsync_control *control; 466 const char *p; 467 char cookie[1024]; 468 int crit, flags, max_attrs, ret; 469 470 cookie[0] = '\0'; 471 p = &(control_strings[sizeof(LDB_CONTROL_DIRSYNC_NAME)]); 472 ret = sscanf(p, "%d:%d:%d:%1023[^$]", &crit, &flags, &max_attrs, cookie); 473 474 if ((ret < 3) || (crit < 0) || (crit > 1) || (flags < 0) || (max_attrs < 0)) { 475 error_string = talloc_asprintf(mem_ctx, "invalid dirsync control syntax\n"); 476 error_string = talloc_asprintf_append(error_string, " syntax: crit(b):flags(n):max_attrs(n)[:cookie(o)]\n"); 477 error_string = talloc_asprintf_append(error_string, " note: b = boolean, n = number, o = b64 binary blob"); 478 ldb_set_errstring(ldb, error_string); 479 talloc_free(error_string); 480 return NULL; 481 } 482 483 /* w2k3 seems to ignore the parameter, 484 * but w2k sends a wrong cookie when this value is to small 485 * this would cause looping forever, while getting 486 * the same data and same cookie forever 487 */ 488 if (max_attrs == 0) max_attrs = 0x0FFFFFFF; 489 490 ctrl->oid = LDB_CONTROL_DIRSYNC_OID; 491 ctrl->critical = crit; 492 control = talloc(ctrl, struct ldb_dirsync_control); 493 control->flags = flags; 494 control->max_attributes = max_attrs; 495 if (*cookie) { 496 control->cookie_len = ldb_base64_decode(cookie); 497 control->cookie = (char *)talloc_memdup(control, cookie, control->cookie_len); 498 } else { 499 control->cookie = NULL; 500 control->cookie_len = 0; 501 } 502 ctrl->data = control; 503 504 return ctrl; 505 } 506 507 if (LDB_CONTROL_CMP(control_strings, LDB_CONTROL_ASQ_NAME) == 0) { 508 struct ldb_asq_control *control; 509 const char *p; 510 char attr[256]; 511 int crit, ret; 512 513 attr[0] = '\0'; 514 p = &(control_strings[sizeof(LDB_CONTROL_ASQ_NAME)]); 515 ret = sscanf(p, "%d:%255[^$]", &crit, attr); 516 if ((ret != 2) || (crit < 0) || (crit > 1) || (attr[0] == '\0')) { 517 error_string = talloc_asprintf(mem_ctx, "invalid asq control syntax\n"); 518 error_string = talloc_asprintf_append(error_string, " syntax: crit(b):attr(s)\n"); 519 error_string = talloc_asprintf_append(error_string, " note: b = boolean, s = string"); 520 ldb_set_errstring(ldb, error_string); 521 talloc_free(error_string); 522 return NULL; 523 } 524 525 ctrl->oid = LDB_CONTROL_ASQ_OID; 526 ctrl->critical = crit; 527 control = talloc(ctrl, struct ldb_asq_control); 528 control->request = 1; 529 control->source_attribute = talloc_strdup(control, attr); 530 control->src_attr_len = strlen(attr); 531 ctrl->data = control; 532 533 return ctrl; 534 } 535 536 if (LDB_CONTROL_CMP(control_strings, LDB_CONTROL_EXTENDED_DN_NAME) == 0) { 537 struct ldb_extended_dn_control *control; 538 const char *p; 539 int crit, type, ret; 540 541 p = &(control_strings[sizeof(LDB_CONTROL_EXTENDED_DN_NAME)]); 542 ret = sscanf(p, "%d:%d", &crit, &type); 543 if ((ret != 2) || (crit < 0) || (crit > 1) || (type < 0) || (type > 1)) { 544 ret = sscanf(p, "%d", &crit); 545 if ((ret != 1) || (crit < 0) || (crit > 1)) { 546 error_string = talloc_asprintf(mem_ctx, "invalid extended_dn control syntax\n"); 547 error_string = talloc_asprintf_append(error_string, " syntax: crit(b)[:type(i)]\n"); 548 error_string = talloc_asprintf_append(error_string, " note: b = boolean\n"); 549 error_string = talloc_asprintf_append(error_string, " i = integer\n"); 550 error_string = talloc_asprintf_append(error_string, " valid values are: 0 - hexadecimal representation\n"); 551 error_string = talloc_asprintf_append(error_string, " 1 - normal string representation"); 194 552 ldb_set_errstring(ldb, error_string); 195 553 talloc_free(error_string); 196 554 return NULL; 197 555 } 198 if (!(ctrl[i] = talloc(ctrl, struct ldb_control))) { 199 ldb_oom(ldb); 200 return NULL; 556 control = NULL; 557 } else { 558 control = talloc(ctrl, struct ldb_extended_dn_control); 559 control->type = type; 560 } 561 562 ctrl->oid = LDB_CONTROL_EXTENDED_DN_OID; 563 ctrl->critical = crit; 564 ctrl->data = talloc_steal(ctrl, control); 565 566 return ctrl; 567 } 568 569 if (LDB_CONTROL_CMP(control_strings, LDB_CONTROL_SD_FLAGS_NAME) == 0) { 570 struct ldb_sd_flags_control *control; 571 const char *p; 572 int crit, ret; 573 unsigned secinfo_flags; 574 575 p = &(control_strings[sizeof(LDB_CONTROL_SD_FLAGS_NAME)]); 576 ret = sscanf(p, "%d:%u", &crit, &secinfo_flags); 577 if ((ret != 2) || (crit < 0) || (crit > 1) || (secinfo_flags < 0) || (secinfo_flags > 0xF)) { 578 error_string = talloc_asprintf(mem_ctx, "invalid sd_flags control syntax\n"); 579 error_string = talloc_asprintf_append(error_string, " syntax: crit(b):secinfo_flags(n)\n"); 580 error_string = talloc_asprintf_append(error_string, " note: b = boolean, n = number"); 581 ldb_set_errstring(ldb, error_string); 582 talloc_free(error_string); 583 return NULL; 584 } 585 586 ctrl->oid = LDB_CONTROL_SD_FLAGS_OID; 587 ctrl->critical = crit; 588 control = talloc(ctrl, struct ldb_sd_flags_control); 589 control->secinfo_flags = secinfo_flags; 590 ctrl->data = control; 591 592 return ctrl; 593 } 594 595 if (LDB_CONTROL_CMP(control_strings, LDB_CONTROL_SEARCH_OPTIONS_NAME) == 0) { 596 struct ldb_search_options_control *control; 597 const char *p; 598 int crit, ret; 599 unsigned search_options; 600 601 p = &(control_strings[sizeof(LDB_CONTROL_SEARCH_OPTIONS_NAME)]); 602 ret = sscanf(p, "%d:%u", &crit, &search_options); 603 if ((ret != 2) || (crit < 0) || (crit > 1) || (search_options < 0) || (search_options > 0xF)) { 604 error_string = talloc_asprintf(mem_ctx, "invalid search_options control syntax\n"); 605 error_string = talloc_asprintf_append(error_string, " syntax: crit(b):search_options(n)\n"); 606 error_string = talloc_asprintf_append(error_string, " note: b = boolean, n = number"); 607 ldb_set_errstring(ldb, error_string); 608 talloc_free(error_string); 609 return NULL; 610 } 611 612 ctrl->oid = LDB_CONTROL_SEARCH_OPTIONS_OID; 613 ctrl->critical = crit; 614 control = talloc(ctrl, struct ldb_search_options_control); 615 control->search_options = search_options; 616 ctrl->data = control; 617 618 return ctrl; 619 } 620 621 if (LDB_CONTROL_CMP(control_strings, LDB_CONTROL_BYPASS_OPERATIONAL_NAME) == 0) { 622 const char *p; 623 int crit, ret; 624 625 p = &(control_strings[sizeof(LDB_CONTROL_BYPASS_OPERATIONAL_NAME)]); 626 ret = sscanf(p, "%d", &crit); 627 if ((ret != 1) || (crit < 0) || (crit > 1)) { 628 error_string = talloc_asprintf(mem_ctx, "invalid bypassopreational control syntax\n"); 629 error_string = talloc_asprintf_append(error_string, " syntax: crit(b)\n"); 630 error_string = talloc_asprintf_append(error_string, " note: b = boolean"); 631 ldb_set_errstring(ldb, error_string); 632 talloc_free(error_string); 633 return NULL; 634 } 635 636 ctrl->oid = LDB_CONTROL_BYPASS_OPERATIONAL_OID; 637 ctrl->critical = crit; 638 ctrl->data = NULL; 639 640 return ctrl; 641 } 642 643 if (LDB_CONTROL_CMP(control_strings, LDB_CONTROL_RELAX_NAME) == 0) { 644 const char *p; 645 int crit, ret; 646 647 p = &(control_strings[sizeof(LDB_CONTROL_RELAX_NAME)]); 648 ret = sscanf(p, "%d", &crit); 649 if ((ret != 1) || (crit < 0) || (crit > 1)) { 650 error_string = talloc_asprintf(mem_ctx, "invalid relax control syntax\n"); 651 error_string = talloc_asprintf_append(error_string, " syntax: crit(b)\n"); 652 error_string = talloc_asprintf_append(error_string, " note: b = boolean"); 653 ldb_set_errstring(ldb, error_string); 654 talloc_free(error_string); 655 return NULL; 656 } 657 658 ctrl->oid = LDB_CONTROL_RELAX_OID; 659 ctrl->critical = crit; 660 ctrl->data = NULL; 661 662 return ctrl; 663 } 664 665 if (LDB_CONTROL_CMP(control_strings, LDB_CONTROL_RECALCULATE_SD_NAME) == 0) { 666 const char *p; 667 int crit, ret; 668 669 p = &(control_strings[sizeof(LDB_CONTROL_RECALCULATE_SD_NAME)]); 670 ret = sscanf(p, "%d", &crit); 671 if ((ret != 1) || (crit < 0) || (crit > 1)) { 672 error_string = talloc_asprintf(mem_ctx, "invalid recalculate_sd control syntax\n"); 673 error_string = talloc_asprintf_append(error_string, " syntax: crit(b)\n"); 674 error_string = talloc_asprintf_append(error_string, " note: b = boolean"); 675 ldb_set_errstring(ldb, error_string); 676 talloc_free(error_string); 677 return NULL; 678 } 679 680 ctrl->oid = LDB_CONTROL_RECALCULATE_SD_OID; 681 ctrl->critical = crit; 682 ctrl->data = NULL; 683 684 return ctrl; 685 } 686 687 if (LDB_CONTROL_CMP(control_strings, LDB_CONTROL_DOMAIN_SCOPE_NAME) == 0) { 688 const char *p; 689 int crit, ret; 690 691 p = &(control_strings[sizeof(LDB_CONTROL_DOMAIN_SCOPE_NAME)]); 692 ret = sscanf(p, "%d", &crit); 693 if ((ret != 1) || (crit < 0) || (crit > 1)) { 694 error_string = talloc_asprintf(mem_ctx, "invalid domain_scope control syntax\n"); 695 error_string = talloc_asprintf_append(error_string, " syntax: crit(b)\n"); 696 error_string = talloc_asprintf_append(error_string, " note: b = boolean"); 697 ldb_set_errstring(ldb, error_string); 698 talloc_free(error_string); 699 return NULL; 700 } 701 702 ctrl->oid = LDB_CONTROL_DOMAIN_SCOPE_OID; 703 ctrl->critical = crit; 704 ctrl->data = NULL; 705 706 return ctrl; 707 } 708 709 if (LDB_CONTROL_CMP(control_strings, LDB_CONTROL_PAGED_RESULTS_NAME) == 0) { 710 struct ldb_paged_control *control; 711 const char *p; 712 int crit, size, ret; 713 714 p = &(control_strings[sizeof(LDB_CONTROL_PAGED_RESULTS_NAME)]); 715 ret = sscanf(p, "%d:%d", &crit, &size); 716 if ((ret != 2) || (crit < 0) || (crit > 1) || (size < 0)) { 717 error_string = talloc_asprintf(mem_ctx, "invalid paged_results control syntax\n"); 718 error_string = talloc_asprintf_append(error_string, " syntax: crit(b):size(n)\n"); 719 error_string = talloc_asprintf_append(error_string, " note: b = boolean, n = number"); 720 ldb_set_errstring(ldb, error_string); 721 talloc_free(error_string); 722 return NULL; 723 } 724 725 ctrl->oid = LDB_CONTROL_PAGED_RESULTS_OID; 726 ctrl->critical = crit; 727 control = talloc(ctrl, struct ldb_paged_control); 728 control->size = size; 729 control->cookie = NULL; 730 control->cookie_len = 0; 731 ctrl->data = control; 732 733 return ctrl; 734 } 735 736 if (LDB_CONTROL_CMP(control_strings, LDB_CONTROL_SERVER_SORT_NAME) == 0) { 737 struct ldb_server_sort_control **control; 738 const char *p; 739 char attr[256]; 740 char rule[128]; 741 int crit, rev, ret; 742 743 attr[0] = '\0'; 744 rule[0] = '\0'; 745 p = &(control_strings[sizeof(LDB_CONTROL_SERVER_SORT_NAME)]); 746 ret = sscanf(p, "%d:%d:%255[^:]:%127[^:]", &crit, &rev, attr, rule); 747 if ((ret < 3) || (crit < 0) || (crit > 1) || (rev < 0 ) || (rev > 1) ||attr[0] == '\0') { 748 error_string = talloc_asprintf(mem_ctx, "invalid server_sort control syntax\n"); 749 error_string = talloc_asprintf_append(error_string, " syntax: crit(b):rev(b):attr(s)[:rule(s)]\n"); 750 error_string = talloc_asprintf_append(error_string, " note: b = boolean, s = string"); 751 ldb_set_errstring(ldb, error_string); 752 talloc_free(error_string); 753 return NULL; 754 } 755 ctrl->oid = LDB_CONTROL_SERVER_SORT_OID; 756 ctrl->critical = crit; 757 control = talloc_array(ctrl, struct ldb_server_sort_control *, 2); 758 control[0] = talloc(control, struct ldb_server_sort_control); 759 control[0]->attributeName = talloc_strdup(control, attr); 760 if (rule[0]) 761 control[0]->orderingRule = talloc_strdup(control, rule); 762 else 763 control[0]->orderingRule = NULL; 764 control[0]->reverse = rev; 765 control[1] = NULL; 766 ctrl->data = control; 767 768 return ctrl; 769 } 770 771 if (LDB_CONTROL_CMP(control_strings, LDB_CONTROL_NOTIFICATION_NAME) == 0) { 772 const char *p; 773 int crit, ret; 774 775 p = &(control_strings[sizeof(LDB_CONTROL_NOTIFICATION_NAME)]); 776 ret = sscanf(p, "%d", &crit); 777 if ((ret != 1) || (crit < 0) || (crit > 1)) { 778 error_string = talloc_asprintf(mem_ctx, "invalid notification control syntax\n"); 779 error_string = talloc_asprintf_append(error_string, " syntax: crit(b)\n"); 780 error_string = talloc_asprintf_append(error_string, " note: b = boolean"); 781 ldb_set_errstring(ldb, error_string); 782 talloc_free(error_string); 783 return NULL; 784 } 785 786 ctrl->oid = LDB_CONTROL_NOTIFICATION_OID; 787 ctrl->critical = crit; 788 ctrl->data = NULL; 789 790 return ctrl; 791 } 792 793 if (LDB_CONTROL_CMP(control_strings, LDB_CONTROL_TREE_DELETE_NAME) == 0) { 794 const char *p; 795 int crit, ret; 796 797 p = &(control_strings[sizeof(LDB_CONTROL_TREE_DELETE_NAME)]); 798 ret = sscanf(p, "%d", &crit); 799 if ((ret != 1) || (crit < 0) || (crit > 1)) { 800 error_string = talloc_asprintf(mem_ctx, "invalid tree_delete control syntax\n"); 801 error_string = talloc_asprintf_append(error_string, " syntax: crit(b)\n"); 802 error_string = talloc_asprintf_append(error_string, " note: b = boolean"); 803 ldb_set_errstring(ldb, error_string); 804 talloc_free(error_string); 805 return NULL; 806 } 807 808 ctrl->oid = LDB_CONTROL_TREE_DELETE_OID; 809 ctrl->critical = crit; 810 ctrl->data = NULL; 811 812 return ctrl; 813 } 814 815 if (LDB_CONTROL_CMP(control_strings, LDB_CONTROL_SHOW_DELETED_NAME) == 0) { 816 const char *p; 817 int crit, ret; 818 819 p = &(control_strings[sizeof(LDB_CONTROL_SHOW_DELETED_NAME)]); 820 ret = sscanf(p, "%d", &crit); 821 if ((ret != 1) || (crit < 0) || (crit > 1)) { 822 error_string = talloc_asprintf(mem_ctx, "invalid show_deleted control syntax\n"); 823 error_string = talloc_asprintf_append(error_string, " syntax: crit(b)\n"); 824 error_string = talloc_asprintf_append(error_string, " note: b = boolean"); 825 ldb_set_errstring(ldb, error_string); 826 talloc_free(error_string); 827 return NULL; 828 } 829 830 ctrl->oid = LDB_CONTROL_SHOW_DELETED_OID; 831 ctrl->critical = crit; 832 ctrl->data = NULL; 833 834 return ctrl; 835 } 836 837 if (LDB_CONTROL_CMP(control_strings, LDB_CONTROL_SHOW_DEACTIVATED_LINK_NAME) == 0) { 838 const char *p; 839 int crit, ret; 840 841 p = &(control_strings[sizeof(LDB_CONTROL_SHOW_DEACTIVATED_LINK_NAME)]); 842 ret = sscanf(p, "%d", &crit); 843 if ((ret != 1) || (crit < 0) || (crit > 1)) { 844 error_string = talloc_asprintf(mem_ctx, "invalid show_deactivated_link control syntax\n"); 845 error_string = talloc_asprintf_append(error_string, " syntax: crit(b)\n"); 846 error_string = talloc_asprintf_append(error_string, " note: b = boolean"); 847 ldb_set_errstring(ldb, error_string); 848 talloc_free(error_string); 849 return NULL; 850 } 851 852 ctrl->oid = LDB_CONTROL_SHOW_DEACTIVATED_LINK_OID; 853 ctrl->critical = crit; 854 ctrl->data = NULL; 855 856 return ctrl; 857 } 858 859 if (LDB_CONTROL_CMP(control_strings, LDB_CONTROL_SHOW_RECYCLED_NAME) == 0) { 860 const char *p; 861 int crit, ret; 862 863 p = &(control_strings[sizeof(LDB_CONTROL_SHOW_RECYCLED_NAME)]); 864 ret = sscanf(p, "%d", &crit); 865 if ((ret != 1) || (crit < 0) || (crit > 1)) { 866 error_string = talloc_asprintf(mem_ctx, "invalid show_recycled control syntax\n"); 867 error_string = talloc_asprintf_append(error_string, " syntax: crit(b)\n"); 868 error_string = talloc_asprintf_append(error_string, " note: b = boolean"); 869 ldb_set_errstring(ldb, error_string); 870 talloc_free(error_string); 871 return NULL; 872 } 873 874 ctrl->oid = LDB_CONTROL_SHOW_RECYCLED_OID; 875 ctrl->critical = crit; 876 ctrl->data = NULL; 877 878 return ctrl; 879 } 880 881 if (LDB_CONTROL_CMP(control_strings, LDB_CONTROL_PERMISSIVE_MODIFY_NAME) == 0) { 882 const char *p; 883 int crit, ret; 884 885 p = &(control_strings[sizeof(LDB_CONTROL_PERMISSIVE_MODIFY_NAME)]); 886 ret = sscanf(p, "%d", &crit); 887 if ((ret != 1) || (crit < 0) || (crit > 1)) { 888 error_string = talloc_asprintf(mem_ctx, "invalid permissive_modify control syntax\n"); 889 error_string = talloc_asprintf_append(error_string, " syntax: crit(b)\n"); 890 error_string = talloc_asprintf_append(error_string, " note: b = boolean"); 891 ldb_set_errstring(ldb, error_string); 892 talloc_free(error_string); 893 return NULL; 894 } 895 896 ctrl->oid = LDB_CONTROL_PERMISSIVE_MODIFY_OID; 897 ctrl->critical = crit; 898 ctrl->data = NULL; 899 900 return ctrl; 901 } 902 903 if (LDB_CONTROL_CMP(control_strings, LDB_CONTROL_REVEAL_INTERNALS_NAME) == 0) { 904 const char *p; 905 int crit, ret; 906 907 p = &(control_strings[sizeof(LDB_CONTROL_REVEAL_INTERNALS_NAME)]); 908 ret = sscanf(p, "%d", &crit); 909 if ((ret != 1) || (crit < 0) || (crit > 1)) { 910 error_string = talloc_asprintf(mem_ctx, "invalid reveal_internals control syntax\n"); 911 error_string = talloc_asprintf_append(error_string, " syntax: crit(b)\n"); 912 error_string = talloc_asprintf_append(error_string, " note: b = boolean"); 913 ldb_set_errstring(ldb, error_string); 914 talloc_free(error_string); 915 return NULL; 916 } 917 918 ctrl->oid = LDB_CONTROL_REVEAL_INTERNALS; 919 ctrl->critical = crit; 920 ctrl->data = NULL; 921 922 return ctrl; 923 } 924 925 if (strncmp(control_strings, "local_oid:", 10) == 0) { 926 const char *p; 927 int crit = 0, ret = 0; 928 char oid[256]; 929 930 oid[0] = '\0'; 931 p = &(control_strings[10]); 932 ret = sscanf(p, "%64[^:]:%d", oid, &crit); 933 934 if ((ret != 2) || strlen(oid) == 0 || (crit < 0) || (crit > 1)) { 935 error_string = talloc_asprintf(mem_ctx, "invalid local_oid control syntax\n"); 936 error_string = talloc_asprintf_append(error_string, " syntax: oid(s):crit(b)\n"); 937 error_string = talloc_asprintf_append(error_string, " note: b = boolean, s = string"); 938 ldb_set_errstring(ldb, error_string); 939 talloc_free(error_string); 940 return NULL; 941 } 942 943 ctrl->oid = talloc_strdup(ctrl, oid); 944 if (!ctrl->oid) { 945 ldb_oom(ldb); 946 return NULL; 947 } 948 ctrl->critical = crit; 949 ctrl->data = NULL; 950 951 return ctrl; 952 } 953 954 if (LDB_CONTROL_CMP(control_strings, LDB_CONTROL_RODC_DCPROMO_NAME) == 0) { 955 const char *p; 956 int crit, ret; 957 958 p = &(control_strings[sizeof(LDB_CONTROL_RODC_DCPROMO_NAME)]); 959 ret = sscanf(p, "%d", &crit); 960 if ((ret != 1) || (crit < 0) || (crit > 1)) { 961 error_string = talloc_asprintf(mem_ctx, "invalid rodc_join control syntax\n"); 962 error_string = talloc_asprintf_append(error_string, " syntax: crit(b)\n"); 963 error_string = talloc_asprintf_append(error_string, " note: b = boolean"); 964 ldb_set_errstring(ldb, error_string); 965 talloc_free(error_string); 966 return NULL; 967 } 968 969 ctrl->oid = LDB_CONTROL_RODC_DCPROMO_OID; 970 ctrl->critical = crit; 971 ctrl->data = NULL; 972 973 return ctrl; 974 } 975 976 if (LDB_CONTROL_CMP(control_strings, LDB_CONTROL_PROVISION_NAME) == 0) { 977 const char *p; 978 int crit, ret; 979 980 p = &(control_strings[sizeof(LDB_CONTROL_PROVISION_NAME)]); 981 ret = sscanf(p, "%d", &crit); 982 if ((ret != 1) || (crit < 0) || (crit > 1)) { 983 error_string = talloc_asprintf(mem_ctx, "invalid provision control syntax\n"); 984 error_string = talloc_asprintf_append(error_string, " syntax: crit(b)\n"); 985 error_string = talloc_asprintf_append(error_string, " note: b = boolean"); 986 ldb_set_errstring(ldb, error_string); 987 talloc_free(error_string); 988 return NULL; 989 } 990 991 ctrl->oid = LDB_CONTROL_PROVISION_OID; 992 ctrl->critical = crit; 993 ctrl->data = NULL; 994 995 return ctrl; 996 } 997 /* 998 * When no matching control has been found. 999 */ 1000 return NULL; 1001 } 1002 1003 /* 1004 * A little trick to allow to use constants defined in headers rather than 1005 * hardwritten in the file hardwritten in the file 1006 * sizeof will return the \0 char as well so it will take the place of ":" in the 1007 * length of the string 1008 */ 1009 #define LDB_CONTROL_CMP(control, NAME) strncmp(control, NAME ":", sizeof(NAME)) 1010 1011 /* Parse controls from the format used on the command line and in ejs */ 1012 struct ldb_control **ldb_parse_control_strings(struct ldb_context *ldb, TALLOC_CTX *mem_ctx, const char **control_strings) 1013 { 1014 unsigned int i; 1015 struct ldb_control **ctrl; 1016 1017 if (control_strings == NULL || control_strings[0] == NULL) 1018 return NULL; 1019 1020 for (i = 0; control_strings[i]; i++); 1021 1022 ctrl = talloc_array(mem_ctx, struct ldb_control *, i + 1); 1023 1024 ldb_reset_err_string(ldb); 1025 for (i = 0; control_strings[i]; i++) { 1026 ctrl[i] = ldb_parse_control_from_string(ldb, ctrl, control_strings[i]); 1027 if (ctrl[i] == NULL) { 1028 if( ldb_errstring == NULL ) { 1029 /* no controls matched, throw an error */ 1030 ldb_asprintf_errstring(ldb, "Invalid control name: '%s'", control_strings[i]); 201 1031 } 202 ctrl[i]->oid = LDB_CONTROL_VLV_REQ_OID; 203 ctrl[i]->critical = crit; 204 if (!(control = talloc(ctrl[i], 205 struct ldb_vlv_req_control))) { 206 ldb_oom(ldb); 207 return NULL; 208 } 209 control->beforeCount = bc; 210 control->afterCount = ac; 211 if (attr[0]) { 212 control->type = 1; 213 control->match.gtOrEq.value = talloc_strdup(control, attr); 214 control->match.gtOrEq.value_len = strlen(attr); 215 } else { 216 control->type = 0; 217 control->match.byOffset.offset = os; 218 control->match.byOffset.contentCount = cc; 219 } 220 if (ctxid[0]) { 221 control->ctxid_len = ldb_base64_decode(ctxid); 222 control->contextId = (char *)talloc_memdup(control, ctxid, control->ctxid_len); 223 } else { 224 control->ctxid_len = 0; 225 control->contextId = NULL; 226 } 227 ctrl[i]->data = control; 228 229 continue; 230 } 231 232 if (strncmp(control_strings[i], "dirsync:", 8) == 0) { 233 struct ldb_dirsync_control *control; 234 const char *p; 235 char cookie[1024]; 236 int crit, flags, max_attrs, ret; 237 238 cookie[0] = '\0'; 239 p = &(control_strings[i][8]); 240 ret = sscanf(p, "%d:%d:%d:%1023[^$]", &crit, &flags, &max_attrs, cookie); 241 242 if ((ret < 3) || (crit < 0) || (crit > 1) || (flags < 0) || (max_attrs < 0)) { 243 error_string = talloc_asprintf(mem_ctx, "invalid dirsync control syntax\n"); 244 error_string = talloc_asprintf_append(error_string, " syntax: crit(b):flags(n):max_attrs(n)[:cookie(o)]\n"); 245 error_string = talloc_asprintf_append(error_string, " note: b = boolean, n = number, o = b64 binary blob"); 246 ldb_set_errstring(ldb, error_string); 247 talloc_free(error_string); 248 return NULL; 249 } 250 251 /* w2k3 seems to ignore the parameter, 252 * but w2k sends a wrong cookie when this value is to small 253 * this would cause looping forever, while getting 254 * the same data and same cookie forever 255 */ 256 if (max_attrs == 0) max_attrs = 0x0FFFFFFF; 257 258 ctrl[i] = talloc(ctrl, struct ldb_control); 259 ctrl[i]->oid = LDB_CONTROL_DIRSYNC_OID; 260 ctrl[i]->critical = crit; 261 control = talloc(ctrl[i], struct ldb_dirsync_control); 262 control->flags = flags; 263 control->max_attributes = max_attrs; 264 if (*cookie) { 265 control->cookie_len = ldb_base64_decode(cookie); 266 control->cookie = (char *)talloc_memdup(control, cookie, control->cookie_len); 267 } else { 268 control->cookie = NULL; 269 control->cookie_len = 0; 270 } 271 ctrl[i]->data = control; 272 273 continue; 274 } 275 276 if (strncmp(control_strings[i], "asq:", 4) == 0) { 277 struct ldb_asq_control *control; 278 const char *p; 279 char attr[256]; 280 int crit, ret; 281 282 attr[0] = '\0'; 283 p = &(control_strings[i][4]); 284 ret = sscanf(p, "%d:%255[^$]", &crit, attr); 285 if ((ret != 2) || (crit < 0) || (crit > 1) || (attr[0] == '\0')) { 286 error_string = talloc_asprintf(mem_ctx, "invalid asq control syntax\n"); 287 error_string = talloc_asprintf_append(error_string, " syntax: crit(b):attr(s)\n"); 288 error_string = talloc_asprintf_append(error_string, " note: b = boolean, s = string"); 289 ldb_set_errstring(ldb, error_string); 290 talloc_free(error_string); 291 return NULL; 292 } 293 294 ctrl[i] = talloc(ctrl, struct ldb_control); 295 if (!ctrl[i]) { 296 ldb_oom(ldb); 297 return NULL; 298 } 299 ctrl[i]->oid = LDB_CONTROL_ASQ_OID; 300 ctrl[i]->critical = crit; 301 control = talloc(ctrl[i], struct ldb_asq_control); 302 control->request = 1; 303 control->source_attribute = talloc_strdup(control, attr); 304 control->src_attr_len = strlen(attr); 305 ctrl[i]->data = control; 306 307 continue; 308 } 309 310 if (strncmp(control_strings[i], "extended_dn:", 12) == 0) { 311 struct ldb_extended_dn_control *control; 312 const char *p; 313 int crit, type, ret; 314 315 p = &(control_strings[i][12]); 316 ret = sscanf(p, "%d:%d", &crit, &type); 317 if ((ret != 2) || (crit < 0) || (crit > 1) || (type < 0) || (type > 1)) { 318 ret = sscanf(p, "%d", &crit); 319 if ((ret != 1) || (crit < 0) || (crit > 1)) { 320 error_string = talloc_asprintf(mem_ctx, "invalid extended_dn control syntax\n"); 321 error_string = talloc_asprintf_append(error_string, " syntax: crit(b)[:type(i)]\n"); 322 error_string = talloc_asprintf_append(error_string, " note: b = boolean\n"); 323 error_string = talloc_asprintf_append(error_string, " i = integer\n"); 324 error_string = talloc_asprintf_append(error_string, " valid values are: 0 - hexadecimal representation\n"); 325 error_string = talloc_asprintf_append(error_string, " 1 - normal string representation"); 326 ldb_set_errstring(ldb, error_string); 327 talloc_free(error_string); 328 return NULL; 329 } 330 control = NULL; 331 } else { 332 control = talloc(ctrl, struct ldb_extended_dn_control); 333 control->type = type; 334 } 335 336 ctrl[i] = talloc(ctrl, struct ldb_control); 337 if (!ctrl[i]) { 338 ldb_oom(ldb); 339 return NULL; 340 } 341 ctrl[i]->oid = LDB_CONTROL_EXTENDED_DN_OID; 342 ctrl[i]->critical = crit; 343 ctrl[i]->data = talloc_steal(ctrl[i], control); 344 345 continue; 346 } 347 348 if (strncmp(control_strings[i], "sd_flags:", 9) == 0) { 349 struct ldb_sd_flags_control *control; 350 const char *p; 351 int crit, ret; 352 unsigned secinfo_flags; 353 354 p = &(control_strings[i][9]); 355 ret = sscanf(p, "%d:%u", &crit, &secinfo_flags); 356 if ((ret != 2) || (crit < 0) || (crit > 1) || (secinfo_flags < 0) || (secinfo_flags > 0xF)) { 357 error_string = talloc_asprintf(mem_ctx, "invalid sd_flags control syntax\n"); 358 error_string = talloc_asprintf_append(error_string, " syntax: crit(b):secinfo_flags(n)\n"); 359 error_string = talloc_asprintf_append(error_string, " note: b = boolean, n = number"); 360 ldb_set_errstring(ldb, error_string); 361 talloc_free(error_string); 362 return NULL; 363 } 364 365 ctrl[i] = talloc(ctrl, struct ldb_control); 366 if (!ctrl[i]) { 367 ldb_oom(ldb); 368 return NULL; 369 } 370 ctrl[i]->oid = LDB_CONTROL_SD_FLAGS_OID; 371 ctrl[i]->critical = crit; 372 control = talloc(ctrl[i], struct ldb_sd_flags_control); 373 control->secinfo_flags = secinfo_flags; 374 ctrl[i]->data = control; 375 376 continue; 377 } 378 379 if (strncmp(control_strings[i], "search_options:", 15) == 0) { 380 struct ldb_search_options_control *control; 381 const char *p; 382 int crit, ret; 383 unsigned search_options; 384 385 p = &(control_strings[i][15]); 386 ret = sscanf(p, "%d:%u", &crit, &search_options); 387 if ((ret != 2) || (crit < 0) || (crit > 1) || (search_options < 0) || (search_options > 0xF)) { 388 error_string = talloc_asprintf(mem_ctx, "invalid search_options control syntax\n"); 389 error_string = talloc_asprintf_append(error_string, " syntax: crit(b):search_options(n)\n"); 390 error_string = talloc_asprintf_append(error_string, " note: b = boolean, n = number"); 391 ldb_set_errstring(ldb, error_string); 392 talloc_free(error_string); 393 return NULL; 394 } 395 396 ctrl[i] = talloc(ctrl, struct ldb_control); 397 if (!ctrl[i]) { 398 ldb_oom(ldb); 399 return NULL; 400 } 401 ctrl[i]->oid = LDB_CONTROL_SEARCH_OPTIONS_OID; 402 ctrl[i]->critical = crit; 403 control = talloc(ctrl[i], struct ldb_search_options_control); 404 control->search_options = search_options; 405 ctrl[i]->data = control; 406 407 continue; 408 } 409 410 if (strncmp(control_strings[i], "domain_scope:", 13) == 0) { 411 const char *p; 412 int crit, ret; 413 414 p = &(control_strings[i][13]); 415 ret = sscanf(p, "%d", &crit); 416 if ((ret != 1) || (crit < 0) || (crit > 1)) { 417 error_string = talloc_asprintf(mem_ctx, "invalid domain_scope control syntax\n"); 418 error_string = talloc_asprintf_append(error_string, " syntax: crit(b)\n"); 419 error_string = talloc_asprintf_append(error_string, " note: b = boolean"); 420 ldb_set_errstring(ldb, error_string); 421 talloc_free(error_string); 422 return NULL; 423 } 424 425 ctrl[i] = talloc(ctrl, struct ldb_control); 426 if (!ctrl[i]) { 427 ldb_oom(ldb); 428 return NULL; 429 } 430 ctrl[i]->oid = LDB_CONTROL_DOMAIN_SCOPE_OID; 431 ctrl[i]->critical = crit; 432 ctrl[i]->data = NULL; 433 434 continue; 435 } 436 437 if (strncmp(control_strings[i], "paged_results:", 14) == 0) { 438 struct ldb_paged_control *control; 439 const char *p; 440 int crit, size, ret; 441 442 p = &(control_strings[i][14]); 443 ret = sscanf(p, "%d:%d", &crit, &size); 444 445 if ((ret != 2) || (crit < 0) || (crit > 1) || (size < 0)) { 446 error_string = talloc_asprintf(mem_ctx, "invalid paged_results control syntax\n"); 447 error_string = talloc_asprintf_append(error_string, " syntax: crit(b):size(n)\n"); 448 error_string = talloc_asprintf_append(error_string, " note: b = boolean, n = number"); 449 ldb_set_errstring(ldb, error_string); 450 talloc_free(error_string); 451 return NULL; 452 } 453 454 ctrl[i] = talloc(ctrl, struct ldb_control); 455 if (!ctrl[i]) { 456 ldb_oom(ldb); 457 return NULL; 458 } 459 ctrl[i]->oid = LDB_CONTROL_PAGED_RESULTS_OID; 460 ctrl[i]->critical = crit; 461 control = talloc(ctrl[i], struct ldb_paged_control); 462 control->size = size; 463 control->cookie = NULL; 464 control->cookie_len = 0; 465 ctrl[i]->data = control; 466 467 continue; 468 } 469 470 if (strncmp(control_strings[i], "server_sort:", 12) == 0) { 471 struct ldb_server_sort_control **control; 472 const char *p; 473 char attr[256]; 474 char rule[128]; 475 int crit, rev, ret; 476 477 attr[0] = '\0'; 478 rule[0] = '\0'; 479 p = &(control_strings[i][12]); 480 ret = sscanf(p, "%d:%d:%255[^:]:%127[^:]", &crit, &rev, attr, rule); 481 if ((ret < 3) || (crit < 0) || (crit > 1) || (rev < 0 ) || (rev > 1) ||attr[0] == '\0') { 482 error_string = talloc_asprintf(mem_ctx, "invalid server_sort control syntax\n"); 483 error_string = talloc_asprintf_append(error_string, " syntax: crit(b):rev(b):attr(s)[:rule(s)]\n"); 484 error_string = talloc_asprintf_append(error_string, " note: b = boolean, s = string"); 485 ldb_set_errstring(ldb, error_string); 486 talloc_free(error_string); 487 return NULL; 488 } 489 ctrl[i] = talloc(ctrl, struct ldb_control); 490 if (!ctrl[i]) { 491 ldb_oom(ldb); 492 return NULL; 493 } 494 ctrl[i]->oid = LDB_CONTROL_SERVER_SORT_OID; 495 ctrl[i]->critical = crit; 496 control = talloc_array(ctrl[i], struct ldb_server_sort_control *, 2); 497 control[0] = talloc(control, struct ldb_server_sort_control); 498 control[0]->attributeName = talloc_strdup(control, attr); 499 if (rule[0]) 500 control[0]->orderingRule = talloc_strdup(control, rule); 501 else 502 control[0]->orderingRule = NULL; 503 control[0]->reverse = rev; 504 control[1] = NULL; 505 ctrl[i]->data = control; 506 507 continue; 508 } 509 510 if (strncmp(control_strings[i], "notification:", 13) == 0) { 511 const char *p; 512 int crit, ret; 513 514 p = &(control_strings[i][13]); 515 ret = sscanf(p, "%d", &crit); 516 if ((ret != 1) || (crit < 0) || (crit > 1)) { 517 error_string = talloc_asprintf(mem_ctx, "invalid notification control syntax\n"); 518 error_string = talloc_asprintf_append(error_string, " syntax: crit(b)\n"); 519 error_string = talloc_asprintf_append(error_string, " note: b = boolean"); 520 ldb_set_errstring(ldb, error_string); 521 talloc_free(error_string); 522 return NULL; 523 } 524 525 ctrl[i] = talloc(ctrl, struct ldb_control); 526 if (!ctrl[i]) { 527 ldb_oom(ldb); 528 return NULL; 529 } 530 ctrl[i]->oid = LDB_CONTROL_NOTIFICATION_OID; 531 ctrl[i]->critical = crit; 532 ctrl[i]->data = NULL; 533 534 continue; 535 } 536 537 if (strncmp(control_strings[i], "show_deleted:", 13) == 0) { 538 const char *p; 539 int crit, ret; 540 541 p = &(control_strings[i][13]); 542 ret = sscanf(p, "%d", &crit); 543 if ((ret != 1) || (crit < 0) || (crit > 1)) { 544 error_string = talloc_asprintf(mem_ctx, "invalid show_deleted control syntax\n"); 545 error_string = talloc_asprintf_append(error_string, " syntax: crit(b)\n"); 546 error_string = talloc_asprintf_append(error_string, " note: b = boolean"); 547 ldb_set_errstring(ldb, error_string); 548 talloc_free(error_string); 549 return NULL; 550 } 551 552 ctrl[i] = talloc(ctrl, struct ldb_control); 553 if (!ctrl[i]) { 554 ldb_oom(ldb); 555 return NULL; 556 } 557 ctrl[i]->oid = LDB_CONTROL_SHOW_DELETED_OID; 558 ctrl[i]->critical = crit; 559 ctrl[i]->data = NULL; 560 561 continue; 562 } 563 564 if (strncmp(control_strings[i], "show_deactivated_link:", 22) == 0) { 565 const char *p; 566 int crit, ret; 567 568 p = &(control_strings[i][22]); 569 ret = sscanf(p, "%d", &crit); 570 if ((ret != 1) || (crit < 0) || (crit > 1)) { 571 error_string = talloc_asprintf(mem_ctx, "invalid show_deactivated_link control syntax\n"); 572 error_string = talloc_asprintf_append(error_string, " syntax: crit(b)\n"); 573 error_string = talloc_asprintf_append(error_string, " note: b = boolean"); 574 ldb_set_errstring(ldb, error_string); 575 talloc_free(error_string); 576 return NULL; 577 } 578 579 ctrl[i] = talloc(ctrl, struct ldb_control); 580 if (!ctrl[i]) { 581 ldb_oom(ldb); 582 return NULL; 583 } 584 ctrl[i]->oid = LDB_CONTROL_SHOW_DEACTIVATED_LINK_OID; 585 ctrl[i]->critical = crit; 586 ctrl[i]->data = NULL; 587 588 continue; 589 } 590 591 if (strncmp(control_strings[i], "show_recycled:", 14) == 0) { 592 const char *p; 593 int crit, ret; 594 595 p = &(control_strings[i][14]); 596 ret = sscanf(p, "%d", &crit); 597 if ((ret != 1) || (crit < 0) || (crit > 1)) { 598 error_string = talloc_asprintf(mem_ctx, "invalid show_recycled control syntax\n"); 599 error_string = talloc_asprintf_append(error_string, " syntax: crit(b)\n"); 600 error_string = talloc_asprintf_append(error_string, " note: b = boolean"); 601 ldb_set_errstring(ldb, error_string); 602 talloc_free(error_string); 603 return NULL; 604 } 605 606 ctrl[i] = talloc(ctrl, struct ldb_control); 607 if (!ctrl[i]) { 608 ldb_oom(ldb); 609 return NULL; 610 } 611 ctrl[i]->oid = LDB_CONTROL_SHOW_RECYCLED_OID; 612 ctrl[i]->critical = crit; 613 ctrl[i]->data = NULL; 614 615 continue; 616 } 617 618 if (strncmp(control_strings[i], "permissive_modify:", 18) == 0) { 619 const char *p; 620 int crit, ret; 621 622 p = &(control_strings[i][18]); 623 ret = sscanf(p, "%d", &crit); 624 if ((ret != 1) || (crit < 0) || (crit > 1)) { 625 error_string = talloc_asprintf(mem_ctx, "invalid permissive_modify control syntax\n"); 626 error_string = talloc_asprintf_append(error_string, " syntax: crit(b)\n"); 627 error_string = talloc_asprintf_append(error_string, " note: b = boolean"); 628 ldb_set_errstring(ldb, error_string); 629 talloc_free(error_string); 630 return NULL; 631 } 632 633 ctrl[i] = talloc(ctrl, struct ldb_control); 634 if (!ctrl[i]) { 635 ldb_oom(ldb); 636 return NULL; 637 } 638 ctrl[i]->oid = LDB_CONTROL_PERMISSIVE_MODIFY_OID; 639 ctrl[i]->critical = crit; 640 ctrl[i]->data = NULL; 641 642 continue; 643 } 644 645 /* no controls matched, throw an error */ 646 ldb_asprintf_errstring(ldb, "Invalid control name: '%s'", control_strings[i]); 647 return NULL; 1032 talloc_free(ctrl); 1033 return NULL; 1034 } 648 1035 } 649 1036 -
vendor/current/source4/lib/ldb/common/ldb_dn.c
r414 r740 80 80 }; 81 81 82 /* it is helpful to be able to break on this in gdb */ 83 static void ldb_dn_mark_invalid(struct ldb_dn *dn) 84 { 85 dn->invalid = true; 86 } 87 82 88 /* strdn may be NULL */ 83 struct ldb_dn *ldb_dn_from_ldb_val( void*mem_ctx,89 struct ldb_dn *ldb_dn_from_ldb_val(TALLOC_CTX *mem_ctx, 84 90 struct ldb_context *ldb, 85 91 const struct ldb_val *strdn) … … 90 96 91 97 if (strdn && strdn->data 92 && (str len((const char*)strdn->data) != strdn->length)) {98 && (strnlen((const char*)strdn->data, strdn->length) != strdn->length)) { 93 99 /* The RDN must not contain a character with value 0x0 */ 94 100 return NULL; … … 98 104 LDB_DN_NULL_FAILED(dn); 99 105 100 dn->ldb = ldb; 106 dn->ldb = talloc_get_type(ldb, struct ldb_context); 107 if (dn->ldb == NULL) { 108 /* the caller probably got the arguments to 109 ldb_dn_new() mixed up */ 110 talloc_free(dn); 111 return NULL; 112 } 101 113 102 114 if (strdn->data && strdn->length) { … … 143 155 144 156 /* strdn may be NULL */ 145 struct ldb_dn *ldb_dn_new( void*mem_ctx,157 struct ldb_dn *ldb_dn_new(TALLOC_CTX *mem_ctx, 146 158 struct ldb_context *ldb, 147 159 const char *strdn) 148 160 { 149 161 struct ldb_val blob; 150 blob.data = strdn;162 blob.data = discard_const_p(uint8_t, strdn); 151 163 blob.length = strdn ? strlen(strdn) : 0; 152 164 return ldb_dn_from_ldb_val(mem_ctx, ldb, &blob); 153 165 } 154 166 155 struct ldb_dn *ldb_dn_new_fmt( void*mem_ctx,167 struct ldb_dn *ldb_dn_new_fmt(TALLOC_CTX *mem_ctx, 156 168 struct ldb_context *ldb, 157 169 const char *new_fmt, ...) … … 175 187 } 176 188 189 /* see RFC2253 section 2.4 */ 177 190 static int ldb_dn_escape_internal(char *dst, const char *src, int len) 178 191 { 179 192 const char *p, *s; 180 193 char *d; 181 int l;194 size_t l; 182 195 183 196 p = s = src; … … 185 198 186 199 while (p - src < len) { 187 188 p += strcspn(p, ",=\n+<>#;\\\""); 200 p += strcspn(p, ",=\n\r+<>#;\\\" "); 189 201 190 202 if (p - src == len) /* found no escapable chars */ … … 194 206 memcpy(d, s, p - s); 195 207 d += (p - s); /* move to current position */ 196 197 if (*p) { /* it is a normal escapable character */ 208 209 switch (*p) { 210 case ' ': 211 if (p == src || (p-src)==(len-1)) { 212 /* if at the beginning or end 213 * of the string then escape */ 214 *d++ = '\\'; 215 *d++ = *p++; 216 } else { 217 /* otherwise don't escape */ 218 *d++ = *p++; 219 } 220 break; 221 222 case '#': 223 /* despite the RFC, windows escapes a # 224 anywhere in the string */ 225 case ',': 226 case '+': 227 case '"': 228 case '\\': 229 case '<': 230 case '>': 231 case '?': 232 /* these must be escaped using \c form */ 198 233 *d++ = '\\'; 199 234 *d++ = *p++; 200 } else { /* we have a zero byte in the string */ 201 strncpy(d, "\00", 3); /* escape the zero */ 202 d += 3; 203 p++; /* skip the zero */ 235 break; 236 237 default: { 238 /* any others get \XX form */ 239 unsigned char v; 240 const char *hexbytes = "0123456789ABCDEF"; 241 v = *(const unsigned char *)p; 242 *d++ = '\\'; 243 *d++ = hexbytes[v>>4]; 244 *d++ = hexbytes[v&0xF]; 245 p++; 246 break; 247 } 204 248 } 205 249 s = p; /* move forward */ … … 214 258 } 215 259 216 char *ldb_dn_escape_value( void*mem_ctx, struct ldb_val value)260 char *ldb_dn_escape_value(TALLOC_CTX *mem_ctx, struct ldb_val value) 217 261 { 218 262 char *dst; … … 245 289 { 246 290 char *p, *ex_name, *ex_value, *data, *d, *dt, *t; 247 bool trim = false;248 bool in_extended = false;291 bool trim = true; 292 bool in_extended = true; 249 293 bool in_ex_name = false; 250 294 bool in_ex_value = false; … … 254 298 bool is_oid = false; 255 299 bool escape = false; 256 unsigned x; 257 int l, ret; 300 unsigned int x; 301 size_t l; 302 int ret; 258 303 char *parse_dn; 304 bool is_index; 259 305 260 306 if ( ! dn || dn->invalid) return false; … … 274 320 } 275 321 276 /* The RDN size must be less than 255 characters */ 277 if (strlen(parse_dn) > 255) { 278 return false; 279 } 322 is_index = (strncmp(parse_dn, "DN=@INDEX:", 10) == 0); 280 323 281 324 /* Empty DNs */ … … 289 332 } 290 333 291 /* make sure we free this if alloced previously before replacing */ 292 talloc_free(dn->components); 293 294 talloc_free(dn->ext_components); 295 dn->ext_components = NULL; 334 /* make sure we free this if allocated previously before replacing */ 335 LDB_FREE(dn->components); 336 dn->comp_num = 0; 337 338 LDB_FREE(dn->ext_components); 339 dn->ext_comp_num = 0; 296 340 297 341 /* in the common case we have 3 or more components */ … … 301 345 return false; 302 346 } 303 dn->comp_num = 0;304 347 305 348 /* Components data space is allocated here once */ … … 310 353 311 354 p = parse_dn; 312 in_extended = true;313 in_ex_name = false;314 in_ex_value = false;315 trim = true;316 355 t = NULL; 317 356 d = dt = data; … … 384 423 &ex_val, &dn->ext_components[dn->ext_comp_num].value); 385 424 if (ret != LDB_SUCCESS) { 386 dn->invalid = true;425 ldb_dn_mark_invalid(dn); 387 426 goto failed; 388 427 } … … 399 438 continue; 400 439 } else { 401 dn->invalid = true;440 ldb_dn_mark_invalid(dn); 402 441 goto failed; 403 442 } … … 419 458 if (!isascii(*p)) { 420 459 /* attr names must be ascii only */ 421 dn->invalid = true;460 ldb_dn_mark_invalid(dn); 422 461 goto failed; 423 462 } … … 429 468 /* not a digit nor an alpha, 430 469 * invalid attribute name */ 431 dn->invalid = true;470 ldb_dn_mark_invalid(dn); 432 471 goto failed; 433 472 } … … 448 487 if (trim && (*p != '=')) { 449 488 /* spaces/tabs are not allowed */ 450 dn->invalid = true;489 ldb_dn_mark_invalid(dn); 451 490 goto failed; 452 491 } … … 477 516 if (!isascii(*p)) { 478 517 /* attr names must be ascii only */ 479 dn->invalid = true;518 ldb_dn_mark_invalid(dn); 480 519 goto failed; 481 520 } … … 484 523 /* not a digit nor a dot, 485 524 * invalid attribute oid */ 486 dn->invalid = true;525 ldb_dn_mark_invalid(dn); 487 526 goto failed; 488 527 } else 489 528 if ( ! (isalpha(*p) || isdigit(*p) || (*p == '-'))) { 490 529 /* not ALPHA, DIGIT or HYPHEN */ 491 dn->invalid = true;530 ldb_dn_mark_invalid(dn); 492 531 goto failed; 493 532 } … … 579 618 continue; 580 619 620 case '+': 581 621 case '=': 582 case '\n': 583 case '+': 622 /* to main compatibility with earlier 623 versions of ldb indexing, we have to 624 accept the base64 encoded binary index 625 values, which contain a '+' or '=' 626 which should normally be escaped */ 627 if (is_index) { 628 if ( t ) t = NULL; 629 *d++ = *p++; 630 l++; 631 break; 632 } 633 /* fall through */ 634 case '\"': 584 635 case '<': 585 636 case '>': 586 case '#':587 637 case ';': 588 case '\"':589 638 /* a string with not escaped specials is invalid (tested) */ 590 639 if ( ! escape) { 591 dn->invalid = true;640 ldb_dn_mark_invalid(dn); 592 641 goto failed; 593 642 } … … 616 665 default: 617 666 if (escape) { 618 if (sscanf(p, "%02x", &x) != 1) { 619 /* invalid escaping sequence */ 620 dn->invalid = true; 621 goto failed; 667 if (isxdigit(p[0]) && isxdigit(p[1])) { 668 if (sscanf(p, "%02x", &x) != 1) { 669 /* invalid escaping sequence */ 670 ldb_dn_mark_invalid(dn); 671 goto failed; 672 } 673 p += 2; 674 *d++ = (unsigned char)x; 675 } else { 676 *d++ = *p++; 622 677 } 678 623 679 escape = false; 624 625 p += 2;626 *d++ = (unsigned char)x;627 680 l++; 628 629 681 if ( t ) t = NULL; 630 682 break; … … 648 700 if (in_attr || in_quote) { 649 701 /* invalid dn */ 650 dn->invalid = true;702 ldb_dn_mark_invalid(dn); 651 703 goto failed; 652 704 } … … 674 726 675 727 failed: 728 LDB_FREE(dn->components); /* "data" is implicitly free'd */ 676 729 dn->comp_num = 0; 677 talloc_free(dn->components); 730 LDB_FREE(dn->ext_components); 731 dn->ext_comp_num = 0; 732 678 733 return false; 679 734 } … … 686 741 const char *ldb_dn_get_linearized(struct ldb_dn *dn) 687 742 { 688 int i, len; 743 unsigned int i; 744 size_t len; 689 745 char *d, *n; 690 746 … … 694 750 695 751 if ( ! dn->components) { 696 dn->invalid = true;752 ldb_dn_mark_invalid(dn); 697 753 return NULL; 698 754 } … … 741 797 } 742 798 743 char *ldb_dn_get_extended_linearized(void *mem_ctx, struct ldb_dn *dn, int mode) 799 static int ldb_dn_extended_component_compare(const void *p1, const void *p2) 800 { 801 const struct ldb_dn_ext_component *ec1 = (const struct ldb_dn_ext_component *)p1; 802 const struct ldb_dn_ext_component *ec2 = (const struct ldb_dn_ext_component *)p2; 803 return strcmp(ec1->name, ec2->name); 804 } 805 806 char *ldb_dn_get_extended_linearized(TALLOC_CTX *mem_ctx, struct ldb_dn *dn, int mode) 744 807 { 745 808 const char *linearized = ldb_dn_get_linearized(dn); 746 char *p ;747 int i;809 char *p = NULL; 810 unsigned int i; 748 811 749 812 if (!linearized) { … … 758 821 return NULL; 759 822 } 823 824 /* sort the extended components by name. The idea is to make 825 * the resulting DNs consistent, plus to ensure that we put 826 * 'DELETED' first, so it can be very quickly recognised 827 */ 828 TYPESAFE_QSORT(dn->ext_components, dn->ext_comp_num, 829 ldb_dn_extended_component_compare); 760 830 761 831 for (i = 0; i < dn->ext_comp_num; i++) { … … 767 837 768 838 ext_syntax = ldb_dn_extended_syntax_by_name(dn->ldb, name); 839 if (!ext_syntax) { 840 return NULL; 841 } 769 842 770 843 if (mode == 1) { … … 783 856 784 857 if (i == 0) { 785 p = talloc_asprintf(mem_ctx, "<%s=%s>", 786 858 p = talloc_asprintf(mem_ctx, "<%s=%s>", 859 name, val.data); 787 860 } else { 788 p = talloc_asprintf_append (p, ";<%s=%s>",789 name, val.data);861 p = talloc_asprintf_append_buffer(p, ";<%s=%s>", 862 name, val.data); 790 863 } 791 864 … … 798 871 799 872 if (dn->ext_comp_num && *linearized) { 800 p = talloc_asprintf_append (p, ";%s", linearized);873 p = talloc_asprintf_append_buffer(p, ";%s", linearized); 801 874 } 802 875 … … 808 881 } 809 882 810 811 812 char *ldb_dn_alloc_linearized(void *mem_ctx, struct ldb_dn *dn) 883 /* 884 filter out all but an acceptable list of extended DN components 885 */ 886 void ldb_dn_extended_filter(struct ldb_dn *dn, const char * const *accept_list) 887 { 888 unsigned int i; 889 for (i=0; i<dn->ext_comp_num; i++) { 890 if (!ldb_attr_in_list(accept_list, dn->ext_components[i].name)) { 891 memmove(&dn->ext_components[i], 892 &dn->ext_components[i+1], 893 (dn->ext_comp_num-(i+1))*sizeof(dn->ext_components[0])); 894 dn->ext_comp_num--; 895 i--; 896 } 897 } 898 LDB_FREE(dn->ext_linearized); 899 } 900 901 902 char *ldb_dn_alloc_linearized(TALLOC_CTX *mem_ctx, struct ldb_dn *dn) 813 903 { 814 904 return talloc_strdup(mem_ctx, ldb_dn_get_linearized(dn)); … … 822 912 static bool ldb_dn_casefold_internal(struct ldb_dn *dn) 823 913 { 824 int i, ret; 914 unsigned int i; 915 int ret; 825 916 826 917 if ( ! dn || dn->invalid) return false; … … 867 958 const char *ldb_dn_get_casefold(struct ldb_dn *dn) 868 959 { 869 int i, len; 960 unsigned int i; 961 size_t len; 870 962 char *d, *n; 871 963 … … 924 1016 } 925 1017 926 char *ldb_dn_alloc_casefold( void*mem_ctx, struct ldb_dn *dn)1018 char *ldb_dn_alloc_casefold(TALLOC_CTX *mem_ctx, struct ldb_dn *dn) 927 1019 { 928 1020 return talloc_strdup(mem_ctx, ldb_dn_get_casefold(dn)); … … 937 1029 { 938 1030 int ret; 939 int n_base, n_dn;1031 unsigned int n_base, n_dn; 940 1032 941 1033 if ( ! base || base->invalid) return 1; … … 973 1065 } 974 1066 975 if ( dn->comp_num == 0) {1067 if ((dn->comp_num == 0) || (base->comp_num == 0)) { 976 1068 if (dn->special && base->special) { 977 1069 return strcmp(base->linearized, dn->linearized); … … 988 1080 n_dn = dn->comp_num - 1; 989 1081 990 while (n_base >= 0) {1082 while (n_base != (unsigned int) -1) { 991 1083 char *b_name = base->components[n_base].cf_name; 992 1084 char *dn_name = dn->components[n_dn].cf_name; … … 1023 1115 int ldb_dn_compare(struct ldb_dn *dn0, struct ldb_dn *dn1) 1024 1116 { 1025 int i, ret; 1117 unsigned int i; 1118 int ret; 1026 1119 1027 1120 if (( ! dn0) || dn0->invalid || ! dn1 || dn1->invalid) { … … 1094 1187 1095 1188 static struct ldb_dn_component ldb_dn_copy_component( 1096 void*mem_ctx,1189 TALLOC_CTX *mem_ctx, 1097 1190 struct ldb_dn_component *src) 1098 1191 { … … 1140 1233 1141 1234 static struct ldb_dn_ext_component ldb_dn_ext_copy_component( 1142 void*mem_ctx,1235 TALLOC_CTX *mem_ctx, 1143 1236 struct ldb_dn_ext_component *src) 1144 1237 { … … 1165 1258 } 1166 1259 1167 struct ldb_dn *ldb_dn_copy( void*mem_ctx, struct ldb_dn *dn)1260 struct ldb_dn *ldb_dn_copy(TALLOC_CTX *mem_ctx, struct ldb_dn *dn) 1168 1261 { 1169 1262 struct ldb_dn *new_dn; … … 1181 1274 1182 1275 if (dn->components) { 1183 int i;1276 unsigned int i; 1184 1277 1185 1278 new_dn->components = … … 1204 1297 1205 1298 if (dn->ext_components) { 1206 int i;1299 unsigned int i; 1207 1300 1208 1301 new_dn->ext_components = … … 1270 1363 1271 1364 if (dn->components) { 1272 int i;1365 unsigned int i; 1273 1366 1274 1367 if ( ! ldb_dn_validate(base)) { … … 1288 1381 dn->comp_num + base->comp_num); 1289 1382 if ( ! dn->components) { 1290 dn->invalid = true;1383 ldb_dn_mark_invalid(dn); 1291 1384 return false; 1292 1385 } … … 1297 1390 &base->components[i]); 1298 1391 if (dn->components[dn->comp_num].value.data == NULL) { 1299 dn->invalid = true;1392 ldb_dn_mark_invalid(dn); 1300 1393 return false; 1301 1394 } … … 1328 1421 } 1329 1422 if ( ! t) { 1330 dn->invalid = true;1423 ldb_dn_mark_invalid(dn); 1331 1424 return false; 1332 1425 } … … 1337 1430 /* Wipe the ext_linearized DN, 1338 1431 * the GUID and SID are almost certainly no longer valid */ 1339 if (dn->ext_linearized) { 1340 LDB_FREE(dn->ext_linearized); 1341 } 1342 1432 LDB_FREE(dn->ext_linearized); 1343 1433 LDB_FREE(dn->ext_components); 1344 1434 dn->ext_comp_num = 0; 1435 1345 1436 return true; 1346 1437 } … … 1394 1485 1395 1486 if (dn->components) { 1396 int n, i, j; 1487 unsigned int n; 1488 unsigned int i, j; 1489 1490 if (dn->comp_num == 0) { 1491 return false; 1492 } 1397 1493 1398 1494 if ( ! ldb_dn_validate(child)) { … … 1414 1510 n); 1415 1511 if ( ! dn->components) { 1416 dn->invalid = true;1512 ldb_dn_mark_invalid(dn); 1417 1513 return false; 1418 1514 } 1419 1515 1420 for (i = dn->comp_num - 1, j = n - 1; i >= 0; i--, j--) { 1516 for (i = dn->comp_num - 1, j = n - 1; i != (unsigned int) -1; 1517 i--, j--) { 1421 1518 dn->components[j] = dn->components[i]; 1422 1519 } … … 1427 1524 &child->components[i]); 1428 1525 if (dn->components[i].value.data == NULL) { 1429 dn->invalid = true;1526 ldb_dn_mark_invalid(dn); 1430 1527 return false; 1431 1528 } … … 1442 1539 1443 1540 if (dn->linearized) { 1541 if (dn->linearized[0] == '\0') { 1542 return false; 1543 } 1444 1544 1445 1545 s = ldb_dn_get_linearized(child); … … 1450 1550 t = talloc_asprintf(dn, "%s,%s", s, dn->linearized); 1451 1551 if ( ! t) { 1452 dn->invalid = true;1552 ldb_dn_mark_invalid(dn); 1453 1553 return false; 1454 1554 } … … 1460 1560 * the GUID and SID are almost certainly no longer valid */ 1461 1561 LDB_FREE(dn->ext_linearized); 1462 1463 1562 LDB_FREE(dn->ext_components); 1464 1563 dn->ext_comp_num = 0; … … 1502 1601 bool ldb_dn_remove_base_components(struct ldb_dn *dn, unsigned int num) 1503 1602 { 1504 int i;1603 unsigned int i; 1505 1604 1506 1605 if ( ! ldb_dn_validate(dn)) { … … 1513 1612 1514 1613 /* free components */ 1515 for (i = num; i > 0; i--) {1516 LDB_FREE(dn->components[ dn->comp_num -i].name);1517 LDB_FREE(dn->components[ dn->comp_num -i].value.data);1518 LDB_FREE(dn->components[ dn->comp_num -i].cf_name);1519 LDB_FREE(dn->components[ dn->comp_num -i].cf_value.data);1614 for (i = dn->comp_num - num; i < dn->comp_num; i++) { 1615 LDB_FREE(dn->components[i].name); 1616 LDB_FREE(dn->components[i].value.data); 1617 LDB_FREE(dn->components[i].cf_name); 1618 LDB_FREE(dn->components[i].cf_value.data); 1520 1619 } 1521 1620 … … 1536 1635 * the GUID and SID are almost certainly no longer valid */ 1537 1636 LDB_FREE(dn->ext_linearized); 1538 1539 1637 LDB_FREE(dn->ext_components); 1540 1638 dn->ext_comp_num = 0; … … 1545 1643 bool ldb_dn_remove_child_components(struct ldb_dn *dn, unsigned int num) 1546 1644 { 1547 int i, j;1645 unsigned int i, j; 1548 1646 1549 1647 if ( ! ldb_dn_validate(dn)) { … … 1581 1679 * the GUID and SID are almost certainly no longer valid */ 1582 1680 LDB_FREE(dn->ext_linearized); 1583 1584 1681 LDB_FREE(dn->ext_components); 1585 1682 dn->ext_comp_num = 0; 1683 1586 1684 return true; 1587 1685 } 1588 1686 1589 struct ldb_dn *ldb_dn_get_parent( void*mem_ctx, struct ldb_dn *dn)1687 struct ldb_dn *ldb_dn_get_parent(TALLOC_CTX *mem_ctx, struct ldb_dn *dn) 1590 1688 { 1591 1689 struct ldb_dn *new_dn; … … 1601 1699 } 1602 1700 1603 /* Wipe the ext_linearized DN,1604 * the GUID and SID are almost certainly no longer valid */1605 LDB_FREE(dn->ext_linearized);1606 1607 LDB_FREE(dn->ext_components);1608 dn->ext_comp_num = 0;1609 1701 return new_dn; 1610 1702 } … … 1619 1711 1620 1712 */ 1621 static char *ldb_dn_canonical( void*mem_ctx, struct ldb_dn *dn, int ex_format) {1622 int i;1713 static char *ldb_dn_canonical(TALLOC_CTX *mem_ctx, struct ldb_dn *dn, int ex_format) { 1714 unsigned int i; 1623 1715 TALLOC_CTX *tmpctx; 1624 1716 char *cracked = NULL; … … 1632 1724 1633 1725 /* Walk backwards down the DN, grabbing 'dc' components at first */ 1634 for (i = dn->comp_num - 1 ; i >= 0; i--) {1726 for (i = dn->comp_num - 1; i != (unsigned int) -1; i--) { 1635 1727 if (ldb_attr_cmp(dn->components[i].name, "dc") != 0) { 1636 1728 break; … … 1651 1743 1652 1744 /* Only domain components? Finish here */ 1653 if (i < 0) {1745 if (i == (unsigned int) -1) { 1654 1746 cracked = talloc_strdup_append_buffer(cracked, format); 1655 1747 talloc_steal(mem_ctx, cracked); … … 1679 1771 1680 1772 /* Wrapper functions for the above, for the two different string formats */ 1681 char *ldb_dn_canonical_string( void*mem_ctx, struct ldb_dn *dn) {1773 char *ldb_dn_canonical_string(TALLOC_CTX *mem_ctx, struct ldb_dn *dn) { 1682 1774 return ldb_dn_canonical(mem_ctx, dn, 0); 1683 1775 1684 1776 } 1685 1777 1686 char *ldb_dn_canonical_ex_string( void*mem_ctx, struct ldb_dn *dn) {1778 char *ldb_dn_canonical_ex_string(TALLOC_CTX *mem_ctx, struct ldb_dn *dn) { 1687 1779 return ldb_dn_canonical(mem_ctx, dn, 1); 1688 1780 } … … 1694 1786 } 1695 1787 return dn->comp_num; 1788 } 1789 1790 int ldb_dn_get_extended_comp_num(struct ldb_dn *dn) 1791 { 1792 if ( ! ldb_dn_validate(dn)) { 1793 return -1; 1794 } 1795 return dn->ext_comp_num; 1696 1796 } 1697 1797 … … 1765 1865 1766 1866 if (dn->valid_case) { 1767 int i;1867 unsigned int i; 1768 1868 for (i = 0; i < dn->comp_num; i++) { 1769 1869 LDB_FREE(dn->components[i].cf_name); … … 1778 1878 * the GUID and SID are almost certainly no longer valid */ 1779 1879 LDB_FREE(dn->ext_linearized); 1780 1880 LDB_FREE(dn->ext_components); 1781 1881 dn->ext_comp_num = 0; 1782 LDB_FREE(dn->ext_components); 1882 1783 1883 return LDB_SUCCESS; 1784 1884 } … … 1787 1887 const char *name) 1788 1888 { 1789 int i;1889 unsigned int i; 1790 1890 if ( ! ldb_dn_validate(dn)) { 1791 1891 return NULL; … … 1803 1903 { 1804 1904 struct ldb_dn_ext_component *p; 1805 int i; 1905 unsigned int i; 1906 struct ldb_val v2; 1806 1907 1807 1908 if ( ! ldb_dn_validate(dn)) { 1808 1909 return LDB_ERR_OTHER; 1910 } 1911 1912 if (!ldb_dn_extended_syntax_by_name(dn->ldb, name)) { 1913 /* We don't know how to handle this type of thing */ 1914 return LDB_ERR_INVALID_DN_SYNTAX; 1809 1915 } 1810 1916 … … 1819 1925 if (!dn->ext_components[i].name || 1820 1926 !dn->ext_components[i].value.data) { 1821 dn->invalid = true;1927 ldb_dn_mark_invalid(dn); 1822 1928 return LDB_ERR_OPERATIONS_ERROR; 1823 1929 } 1824 1825 1930 } else { 1826 1931 if (i != (dn->ext_comp_num - 1)) { … … 1837 1942 dn->ext_comp_num); 1838 1943 if (!dn->ext_components) { 1839 dn->invalid = true;1944 ldb_dn_mark_invalid(dn); 1840 1945 return LDB_ERR_OPERATIONS_ERROR; 1841 1946 } 1842 return LDB_SUCCESS; 1843 } 1844 } 1845 } 1947 } 1948 LDB_FREE(dn->ext_linearized); 1949 1950 return LDB_SUCCESS; 1951 } 1952 } 1953 1954 if (val == NULL) { 1955 /* removing a value that doesn't exist is not an error */ 1956 return LDB_SUCCESS; 1957 } 1958 1959 v2 = *val; 1846 1960 1847 1961 p = dn->ext_components … … 1851 1965 dn->ext_comp_num + 1); 1852 1966 if (!dn->ext_components) { 1853 dn->invalid = true;1967 ldb_dn_mark_invalid(dn); 1854 1968 return LDB_ERR_OPERATIONS_ERROR; 1855 1969 } 1856 1970 1857 p[dn->ext_comp_num].value = ldb_val_dup(dn->ext_components, val);1971 p[dn->ext_comp_num].value = ldb_val_dup(dn->ext_components, &v2); 1858 1972 p[dn->ext_comp_num].name = talloc_strdup(p, name); 1859 1973 1860 1974 if (!dn->ext_components[i].name || !dn->ext_components[i].value.data) { 1861 dn->invalid = true;1975 ldb_dn_mark_invalid(dn); 1862 1976 return LDB_ERR_OPERATIONS_ERROR; 1863 1977 } … … 1865 1979 dn->ext_comp_num++; 1866 1980 1981 LDB_FREE(dn->ext_linearized); 1982 1867 1983 return LDB_SUCCESS; 1868 1984 } … … 1870 1986 void ldb_dn_remove_extended_components(struct ldb_dn *dn) 1871 1987 { 1988 LDB_FREE(dn->ext_linearized); 1989 LDB_FREE(dn->ext_components); 1872 1990 dn->ext_comp_num = 0; 1873 LDB_FREE(dn->ext_components);1874 1991 } 1875 1992 … … 1906 2023 return false; 1907 2024 } 2025 2026 /* 2027 this updates dn->components, taking the components from ref_dn. 2028 This is used by code that wants to update the DN path of a DN 2029 while not impacting on the extended DN components 2030 */ 2031 int ldb_dn_update_components(struct ldb_dn *dn, const struct ldb_dn *ref_dn) 2032 { 2033 dn->components = talloc_realloc(dn, dn->components, 2034 struct ldb_dn_component, ref_dn->comp_num); 2035 if (!dn->components) { 2036 return LDB_ERR_OPERATIONS_ERROR; 2037 } 2038 memcpy(dn->components, ref_dn->components, 2039 sizeof(struct ldb_dn_component)*ref_dn->comp_num); 2040 dn->comp_num = ref_dn->comp_num; 2041 2042 LDB_FREE(dn->casefold); 2043 LDB_FREE(dn->linearized); 2044 LDB_FREE(dn->ext_linearized); 2045 2046 return LDB_SUCCESS; 2047 } 2048 2049 /* 2050 minimise a DN. The caller must pass in a validated DN. 2051 2052 If the DN has an extended component then only the first extended 2053 component is kept, the DN string is stripped. 2054 2055 The existing dn is modified 2056 */ 2057 bool ldb_dn_minimise(struct ldb_dn *dn) 2058 { 2059 unsigned int i; 2060 2061 if (!ldb_dn_validate(dn)) { 2062 return false; 2063 } 2064 if (dn->ext_comp_num == 0) { 2065 return true; 2066 } 2067 2068 /* free components */ 2069 for (i = 0; i < dn->comp_num; i++) { 2070 LDB_FREE(dn->components[i].name); 2071 LDB_FREE(dn->components[i].value.data); 2072 LDB_FREE(dn->components[i].cf_name); 2073 LDB_FREE(dn->components[i].cf_value.data); 2074 } 2075 dn->comp_num = 0; 2076 dn->valid_case = false; 2077 2078 LDB_FREE(dn->casefold); 2079 LDB_FREE(dn->linearized); 2080 2081 /* note that we don't free dn->components as this there are 2082 * several places in ldb_dn.c that rely on it being non-NULL 2083 * for an exploded DN 2084 */ 2085 2086 for (i = 1; i < dn->ext_comp_num; i++) { 2087 LDB_FREE(dn->ext_components[i].name); 2088 LDB_FREE(dn->ext_components[i].value.data); 2089 } 2090 dn->ext_comp_num = 1; 2091 2092 dn->ext_components = talloc_realloc(dn, dn->ext_components, struct ldb_dn_ext_component, 1); 2093 if (dn->ext_components == NULL) { 2094 ldb_dn_mark_invalid(dn); 2095 return false; 2096 } 2097 2098 LDB_FREE(dn->ext_linearized); 2099 2100 return true; 2101 } -
vendor/current/source4/lib/ldb/common/ldb_ldif.c
r414 r740 42 42 43 43 */ 44 static int ldb_read_data_file( void*mem_ctx, struct ldb_val *value)44 static int ldb_read_data_file(TALLOC_CTX *mem_ctx, struct ldb_val *value) 45 45 { 46 46 struct stat statbuf; … … 151 151 caller frees 152 152 */ 153 char *ldb_base64_encode( void*mem_ctx, const char *buf, int len)153 char *ldb_base64_encode(TALLOC_CTX *mem_ctx, const char *buf, int len) 154 154 { 155 155 const char *b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; … … 191 191 uint8_t *p = val->data; 192 192 193 if (ldb->flags & LDB_FLG_SHOW_BINARY) {194 return 0;195 }196 197 193 if (val->length == 0) { 198 194 return 0; … … 220 216 const char *buf, size_t length, int start_pos) 221 217 { 222 unsigned int i;218 size_t i; 223 219 int total=0, ret; 224 220 … … 334 330 for (j=0;j<msg->elements[i].num_values;j++) { 335 331 struct ldb_val v; 332 bool use_b64_encode; 336 333 ret = a->syntax->ldif_write_fn(ldb, mem_ctx, &msg->elements[i].values[j], &v); 337 334 if (ret != LDB_SUCCESS) { 338 335 v = msg->elements[i].values[j]; 339 336 } 340 if (ret != LDB_SUCCESS || ldb_should_b64_encode(ldb, &v)) { 337 use_b64_encode = !(ldb->flags & LDB_FLG_SHOW_BINARY) 338 && ldb_should_b64_encode(ldb, &v); 339 if (ret != LDB_SUCCESS || use_b64_encode) { 341 340 ret = fprintf_fn(private_data, "%s:: ", 342 341 msg->elements[i].name); … … 374 373 CHECK_RET; 375 374 375 talloc_free(mem_ctx); 376 376 377 return total; 377 378 } … … 448 449 449 450 /* simple ldif attribute parser */ 450 static int next_attr( void*mem_ctx, char **s, const char **attr, struct ldb_val *value)451 static int next_attr(TALLOC_CTX *mem_ctx, char **s, const char **attr, struct ldb_val *value) 451 452 { 452 453 char *p; … … 509 510 int len = ldb_read_data_file(mem_ctx, value); 510 511 if (len == -1) { 511 /* an error occur edhile trying to retrieve the file */512 /* an error occurred while trying to retrieve the file */ 512 513 return -1; 513 514 } -
vendor/current/source4/lib/ldb/common/ldb_match.c
r414 r740 82 82 const struct ldb_message *msg, 83 83 const struct ldb_parse_tree *tree, 84 enum ldb_scope scope) 85 { 84 enum ldb_scope scope, bool *matched) 85 { 86 const struct ldb_schema_attribute *a; 87 struct ldb_message_element *el; 88 86 89 if (ldb_attr_dn(tree->u.present.attr) == 0) { 87 return 1; 88 } 89 90 if (ldb_msg_find_element(msg, tree->u.present.attr)) { 91 return 1; 92 } 93 94 return 0; 90 *matched = true; 91 return LDB_SUCCESS; 92 } 93 94 el = ldb_msg_find_element(msg, tree->u.present.attr); 95 if (el == NULL) { 96 *matched = false; 97 return LDB_SUCCESS; 98 } 99 100 a = ldb_schema_attribute_by_name(ldb, el->name); 101 if (!a) { 102 return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX; 103 } 104 105 if (a->syntax->operator_fn) { 106 unsigned int i; 107 for (i = 0; i < el->num_values; i++) { 108 int ret = a->syntax->operator_fn(ldb, LDB_OP_PRESENT, a, &el->values[i], NULL, matched); 109 if (ret != LDB_SUCCESS) return ret; 110 if (*matched) return LDB_SUCCESS; 111 } 112 *matched = false; 113 return LDB_SUCCESS; 114 } 115 116 *matched = true; 117 return LDB_SUCCESS; 95 118 } 96 119 … … 99 122 const struct ldb_parse_tree *tree, 100 123 enum ldb_scope scope, 101 enum ldb_parse_op comp_op )124 enum ldb_parse_op comp_op, bool *matched) 102 125 { 103 126 unsigned int i; 104 127 struct ldb_message_element *el; 105 128 const struct ldb_schema_attribute *a; 106 int ret;107 129 108 130 /* FIXME: APPROX comparison not handled yet */ 109 if (comp_op == LDB_OP_APPROX) return 0; 131 if (comp_op == LDB_OP_APPROX) { 132 return LDB_ERR_INAPPROPRIATE_MATCHING; 133 } 110 134 111 135 el = ldb_msg_find_element(msg, tree->u.comparison.attr); 112 136 if (el == NULL) { 113 return 0; 137 *matched = false; 138 return LDB_SUCCESS; 114 139 } 115 140 116 141 a = ldb_schema_attribute_by_name(ldb, el->name); 142 if (!a) { 143 return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX; 144 } 117 145 118 146 for (i = 0; i < el->num_values; i++) { 119 ret = a->syntax->comparison_fn(ldb, ldb, &el->values[i], &tree->u.comparison.value); 120 121 if (ret == 0) { 122 return 1; 123 } 124 if (ret > 0 && comp_op == LDB_OP_GREATER) { 125 return 1; 126 } 127 if (ret < 0 && comp_op == LDB_OP_LESS) { 128 return 1; 129 } 130 } 131 132 return 0; 147 if (a->syntax->operator_fn) { 148 int ret; 149 ret = a->syntax->operator_fn(ldb, comp_op, a, &el->values[i], &tree->u.comparison.value, matched); 150 if (ret != LDB_SUCCESS) return ret; 151 if (*matched) return LDB_SUCCESS; 152 } else { 153 int ret = a->syntax->comparison_fn(ldb, ldb, &el->values[i], &tree->u.comparison.value); 154 155 if (ret == 0) { 156 *matched = true; 157 return LDB_SUCCESS; 158 } 159 if (ret > 0 && comp_op == LDB_OP_GREATER) { 160 *matched = true; 161 return LDB_SUCCESS; 162 } 163 if (ret < 0 && comp_op == LDB_OP_LESS) { 164 *matched = true; 165 return LDB_SUCCESS; 166 } 167 } 168 } 169 170 *matched = false; 171 return LDB_SUCCESS; 133 172 } 134 173 … … 139 178 const struct ldb_message *msg, 140 179 const struct ldb_parse_tree *tree, 141 enum ldb_scope scope) 180 enum ldb_scope scope, 181 bool *matched) 142 182 { 143 183 unsigned int i; … … 150 190 valuedn = ldb_dn_from_ldb_val(ldb, ldb, &tree->u.equality.value); 151 191 if (valuedn == NULL) { 152 return 0;192 return LDB_ERR_INVALID_DN_SYNTAX; 153 193 } 154 194 … … 157 197 talloc_free(valuedn); 158 198 159 if (ret == 0) return 1;160 return 0;199 *matched = (ret == 0); 200 return LDB_SUCCESS; 161 201 } 162 202 … … 165 205 el = ldb_msg_find_element(msg, tree->u.equality.attr); 166 206 if (el == NULL) { 167 return 0; 207 *matched = false; 208 return LDB_SUCCESS; 168 209 } 169 210 170 211 a = ldb_schema_attribute_by_name(ldb, el->name); 212 if (a == NULL) { 213 return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX; 214 } 171 215 172 216 for (i=0;i<el->num_values;i++) { 173 if (a->syntax->comparison_fn(ldb, ldb, &tree->u.equality.value, 174 &el->values[i]) == 0) { 175 return 1; 176 } 177 } 178 179 return 0; 217 if (a->syntax->operator_fn) { 218 ret = a->syntax->operator_fn(ldb, LDB_OP_EQUALITY, a, 219 &tree->u.equality.value, &el->values[i], matched); 220 if (ret != LDB_SUCCESS) return ret; 221 if (*matched) return LDB_SUCCESS; 222 } else { 223 if (a->syntax->comparison_fn(ldb, ldb, &tree->u.equality.value, 224 &el->values[i]) == 0) { 225 *matched = true; 226 return LDB_SUCCESS; 227 } 228 } 229 } 230 231 *matched = false; 232 return LDB_SUCCESS; 180 233 } 181 234 182 235 static int ldb_wildcard_compare(struct ldb_context *ldb, 183 236 const struct ldb_parse_tree *tree, 184 const struct ldb_val value )237 const struct ldb_val value, bool *matched) 185 238 { 186 239 const struct ldb_schema_attribute *a; … … 190 243 char *p, *g; 191 244 uint8_t *save_p = NULL; 192 int c = 0;245 unsigned int c = 0; 193 246 194 247 a = ldb_schema_attribute_by_name(ldb, tree->u.substring.attr); 195 196 if(a->syntax->canonicalise_fn(ldb, ldb, &value, &val) != 0) 197 return -1; 248 if (!a) { 249 return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX; 250 } 251 252 if (a->syntax->canonicalise_fn(ldb, ldb, &value, &val) != 0) { 253 return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX; 254 } 198 255 199 256 save_p = val.data; … … 203 260 204 261 chunk = tree->u.substring.chunks[c]; 205 if (a->syntax->canonicalise_fn(ldb, ldb, chunk, &cnk) != 0) goto failed;262 if (a->syntax->canonicalise_fn(ldb, ldb, chunk, &cnk) != 0) goto mismatch; 206 263 207 264 /* This deals with wildcard prefix searches on binary attributes (eg objectGUID) */ 208 265 if (cnk.length > val.length) { 209 goto failed;210 } 211 if (memcmp((char *)val.data, (char *)cnk.data, cnk.length) != 0) goto failed;266 goto mismatch; 267 } 268 if (memcmp((char *)val.data, (char *)cnk.data, cnk.length) != 0) goto mismatch; 212 269 val.length -= cnk.length; 213 270 val.data += cnk.length; … … 220 277 221 278 chunk = tree->u.substring.chunks[c]; 222 if(a->syntax->canonicalise_fn(ldb, ldb, chunk, &cnk) != 0) goto failed;279 if(a->syntax->canonicalise_fn(ldb, ldb, chunk, &cnk) != 0) goto mismatch; 223 280 224 281 /* FIXME: case of embedded nulls */ 225 282 p = strstr((char *)val.data, (char *)cnk.data); 226 if (p == NULL) goto failed;283 if (p == NULL) goto mismatch; 227 284 if ( (! tree->u.substring.chunks[c + 1]) && (! tree->u.substring.end_with_wildcard) ) { 228 285 do { /* greedy */ … … 238 295 } 239 296 240 if ( (! tree->u.substring.end_with_wildcard) && (*(val.data) != 0) ) goto failed; /* last chunk have not reached end of string */ 297 /* last chunk may not have reached end of string */ 298 if ( (! tree->u.substring.end_with_wildcard) && (*(val.data) != 0) ) goto mismatch; 241 299 talloc_free(save_p); 242 return 1; 243 244 failed: 300 *matched = true; 301 return LDB_SUCCESS; 302 303 mismatch: 304 *matched = false; 245 305 talloc_free(save_p); 246 306 talloc_free(cnk.data); 247 return 0;307 return LDB_SUCCESS; 248 308 } 249 309 … … 254 314 const struct ldb_message *msg, 255 315 const struct ldb_parse_tree *tree, 256 enum ldb_scope scope )316 enum ldb_scope scope, bool *matched) 257 317 { 258 318 unsigned int i; … … 261 321 el = ldb_msg_find_element(msg, tree->u.substring.attr); 262 322 if (el == NULL) { 263 return 0; 323 *matched = false; 324 return LDB_SUCCESS; 264 325 } 265 326 266 327 for (i = 0; i < el->num_values; i++) { 267 if (ldb_wildcard_compare(ldb, tree, el->values[i]) == 1) { 268 return 1; 269 } 270 } 271 272 return 0; 328 int ret; 329 ret = ldb_wildcard_compare(ldb, tree, el->values[i], matched); 330 if (ret != LDB_SUCCESS) return ret; 331 if (*matched) return LDB_SUCCESS; 332 } 333 334 *matched = false; 335 return LDB_SUCCESS; 273 336 } 274 337 … … 277 340 bitwise-and comparator 278 341 */ 279 static int ldb_comparator_and(const struct ldb_val *v1, const struct ldb_val *v2) 342 static int ldb_comparator_bitmask(const char *oid, const struct ldb_val *v1, const struct ldb_val *v2, 343 bool *matched) 280 344 { 281 345 uint64_t i1, i2; 282 i1 = strtoull((char *)v1->data, NULL, 0); 283 i2 = strtoull((char *)v2->data, NULL, 0); 284 return ((i1 & i2) == i2); 285 } 286 287 /* 288 bitwise-or comparator 289 */ 290 static int ldb_comparator_or(const struct ldb_val *v1, const struct ldb_val *v2) 291 { 292 uint64_t i1, i2; 293 i1 = strtoull((char *)v1->data, NULL, 0); 294 i2 = strtoull((char *)v2->data, NULL, 0); 295 return ((i1 & i2) != 0); 346 char ibuf[100]; 347 char *endptr = NULL; 348 349 if (v1->length >= sizeof(ibuf)-1) { 350 return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX; 351 } 352 memcpy(ibuf, (char *)v1->data, v1->length); 353 ibuf[v1->length] = 0; 354 i1 = strtoull(ibuf, &endptr, 0); 355 if (endptr != NULL) { 356 if (endptr == ibuf || *endptr != 0) { 357 return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX; 358 } 359 } 360 361 if (v2->length >= sizeof(ibuf)-1) { 362 return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX; 363 } 364 endptr = NULL; 365 memcpy(ibuf, (char *)v2->data, v2->length); 366 ibuf[v2->length] = 0; 367 i2 = strtoull(ibuf, &endptr, 0); 368 if (endptr != NULL) { 369 if (endptr == ibuf || *endptr != 0) { 370 return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX; 371 } 372 } 373 if (strcmp(LDB_OID_COMPARATOR_AND, oid) == 0) { 374 *matched = ((i1 & i2) == i2); 375 } else if (strcmp(LDB_OID_COMPARATOR_OR, oid) == 0) { 376 *matched = ((i1 & i2) != 0); 377 } else { 378 return LDB_ERR_INAPPROPRIATE_MATCHING; 379 } 380 return LDB_SUCCESS; 296 381 } 297 382 … … 303 388 const struct ldb_message *msg, 304 389 const struct ldb_parse_tree *tree, 305 enum ldb_scope scope )306 { 307 int i;390 enum ldb_scope scope, bool *matched) 391 { 392 unsigned int i; 308 393 const struct { 309 394 const char *oid; 310 int (*comparator)(const struct ldb_val *, const struct ldb_val *);395 int (*comparator)(const char *, const struct ldb_val *, const struct ldb_val *, bool *); 311 396 } rules[] = { 312 { LDB_OID_COMPARATOR_AND, ldb_comparator_ and},313 { LDB_OID_COMPARATOR_OR, ldb_comparator_ or}397 { LDB_OID_COMPARATOR_AND, ldb_comparator_bitmask}, 398 { LDB_OID_COMPARATOR_OR, ldb_comparator_bitmask} 314 399 }; 315 int (*comp)(const struct ldb_val *, const struct ldb_val *) = NULL;400 int (*comp)(const char *,const struct ldb_val *, const struct ldb_val *, bool *) = NULL; 316 401 struct ldb_message_element *el; 317 402 318 403 if (tree->u.extended.dnAttributes) { 319 ldb_debug(ldb, LDB_DEBUG_ERROR, "ldb: dnAttributes extended match not supported yet"); 320 return -1; 404 /* FIXME: We really need to find out what this ":dn" part in 405 * an extended match means and how to handle it. For now print 406 * only a warning to have s3 winbind and other tools working 407 * against us. - Matthias */ 408 ldb_debug(ldb, LDB_DEBUG_WARNING, "ldb: dnAttributes extended match not supported yet"); 321 409 } 322 410 if (tree->u.extended.rule_id == NULL) { 323 411 ldb_debug(ldb, LDB_DEBUG_ERROR, "ldb: no-rule extended matches not supported yet"); 324 return -1;412 return LDB_ERR_INAPPROPRIATE_MATCHING; 325 413 } 326 414 if (tree->u.extended.attr == NULL) { 327 415 ldb_debug(ldb, LDB_DEBUG_ERROR, "ldb: no-attribute extended matches not supported yet"); 328 return -1;416 return LDB_ERR_INAPPROPRIATE_MATCHING; 329 417 } 330 418 … … 338 426 ldb_debug(ldb, LDB_DEBUG_ERROR, "ldb: unknown extended rule_id %s", 339 427 tree->u.extended.rule_id); 340 return -1;428 return LDB_ERR_INAPPROPRIATE_MATCHING; 341 429 } 342 430 … … 344 432 el = ldb_msg_find_element(msg, tree->u.extended.attr); 345 433 if (el == NULL) { 346 return 0; 434 *matched = false; 435 return LDB_SUCCESS; 347 436 } 348 437 349 438 for (i=0;i<el->num_values;i++) { 350 int ret = comp(&el->values[i], &tree->u.extended.value); 351 if (ret == -1 || ret == 1) return ret; 352 } 353 354 return 0; 439 int ret = comp(tree->u.extended.rule_id, &el->values[i], &tree->u.extended.value, matched); 440 if (ret != LDB_SUCCESS) return ret; 441 if (*matched) return LDB_SUCCESS; 442 } 443 444 *matched = false; 445 return LDB_SUCCESS; 355 446 } 356 447 … … 366 457 const struct ldb_message *msg, 367 458 const struct ldb_parse_tree *tree, 368 enum ldb_scope scope )459 enum ldb_scope scope, bool *matched) 369 460 { 370 461 unsigned int i; 371 int v; 462 int ret; 463 464 *matched = false; 372 465 373 466 switch (tree->operation) { 374 467 case LDB_OP_AND: 375 468 for (i=0;i<tree->u.list.num_elements;i++) { 376 v = ldb_match_message(ldb, msg, tree->u.list.elements[i], scope); 377 if (!v) return 0; 378 } 379 return 1; 469 ret = ldb_match_message(ldb, msg, tree->u.list.elements[i], scope, matched); 470 if (ret != LDB_SUCCESS) return ret; 471 if (!*matched) return LDB_SUCCESS; 472 } 473 *matched = true; 474 return LDB_SUCCESS; 380 475 381 476 case LDB_OP_OR: 382 477 for (i=0;i<tree->u.list.num_elements;i++) { 383 v = ldb_match_message(ldb, msg, tree->u.list.elements[i], scope); 384 if (v) return 1; 385 } 386 return 0; 478 ret = ldb_match_message(ldb, msg, tree->u.list.elements[i], scope, matched); 479 if (ret != LDB_SUCCESS) return ret; 480 if (*matched) return LDB_SUCCESS; 481 } 482 *matched = false; 483 return LDB_SUCCESS; 387 484 388 485 case LDB_OP_NOT: 389 return ! ldb_match_message(ldb, msg, tree->u.isnot.child, scope); 486 ret = ldb_match_message(ldb, msg, tree->u.isnot.child, scope, matched); 487 if (ret != LDB_SUCCESS) return ret; 488 *matched = ! *matched; 489 return LDB_SUCCESS; 390 490 391 491 case LDB_OP_EQUALITY: 392 return ldb_match_equality(ldb, msg, tree, scope );492 return ldb_match_equality(ldb, msg, tree, scope, matched); 393 493 394 494 case LDB_OP_SUBSTRING: 395 return ldb_match_substring(ldb, msg, tree, scope );495 return ldb_match_substring(ldb, msg, tree, scope, matched); 396 496 397 497 case LDB_OP_GREATER: 398 return ldb_match_comparison(ldb, msg, tree, scope, LDB_OP_GREATER );498 return ldb_match_comparison(ldb, msg, tree, scope, LDB_OP_GREATER, matched); 399 499 400 500 case LDB_OP_LESS: 401 return ldb_match_comparison(ldb, msg, tree, scope, LDB_OP_LESS );501 return ldb_match_comparison(ldb, msg, tree, scope, LDB_OP_LESS, matched); 402 502 403 503 case LDB_OP_PRESENT: 404 return ldb_match_present(ldb, msg, tree, scope );504 return ldb_match_present(ldb, msg, tree, scope, matched); 405 505 406 506 case LDB_OP_APPROX: 407 return ldb_match_comparison(ldb, msg, tree, scope, LDB_OP_APPROX );507 return ldb_match_comparison(ldb, msg, tree, scope, LDB_OP_APPROX, matched); 408 508 409 509 case LDB_OP_EXTENDED: 410 return ldb_match_extended(ldb, msg, tree, scope); 411 412 } 413 414 return 0; 510 return ldb_match_extended(ldb, msg, tree, scope, matched); 511 } 512 513 return LDB_ERR_INAPPROPRIATE_MATCHING; 415 514 } 416 515 … … 421 520 enum ldb_scope scope) 422 521 { 522 bool matched; 523 int ret; 524 423 525 if ( ! ldb_match_scope(ldb, base, msg->dn, scope) ) { 424 526 return 0; 425 527 } 426 528 427 return ldb_match_message(ldb, msg, tree, scope); 428 } 529 ret = ldb_match_message(ldb, msg, tree, scope, &matched); 530 if (ret != LDB_SUCCESS) { 531 /* to match the old API, we need to consider this a 532 failure to match */ 533 return 0; 534 } 535 return matched?1:0; 536 } 537 538 int ldb_match_msg_error(struct ldb_context *ldb, 539 const struct ldb_message *msg, 540 const struct ldb_parse_tree *tree, 541 struct ldb_dn *base, 542 enum ldb_scope scope, 543 bool *matched) 544 { 545 if ( ! ldb_match_scope(ldb, base, msg->dn, scope) ) { 546 *matched = false; 547 return LDB_SUCCESS; 548 } 549 550 return ldb_match_message(ldb, msg, tree, scope, matched); 551 } 552 553 int ldb_match_msg_objectclass(const struct ldb_message *msg, 554 const char *objectclass) 555 { 556 unsigned int i; 557 struct ldb_message_element *el = ldb_msg_find_element(msg, "objectClass"); 558 if (!el) { 559 return 0; 560 } 561 for (i=0; i < el->num_values; i++) { 562 if (ldb_attr_cmp((const char *)el->values[i].data, objectclass) == 0) { 563 return 1; 564 } 565 } 566 return 0; 567 } 568 569 570 -
vendor/current/source4/lib/ldb/common/ldb_modules.c
r414 r740 34 34 #include "ldb_private.h" 35 35 #include "dlinklist.h" 36 37 #define LDB_MODULE_PREFIX "modules:" 38 #define LDB_MODULE_PREFIX_LEN 8 39 40 static void *ldb_dso_load_symbol(struct ldb_context *ldb, const char *name, 41 const char *symbol); 42 43 void ldb_set_modules_dir(struct ldb_context *ldb, const char *path) 44 { 45 talloc_free(ldb->modules_dir); 46 ldb->modules_dir = talloc_strdup(ldb, path); 47 } 36 #include "system/dir.h" 48 37 49 38 static char *ldb_modules_strdup_no_spaces(TALLOC_CTX *mem_ctx, const char *string) 50 39 { 51 int i, len;40 size_t i, len; 52 41 char *trimmed; 53 42 … … 80 69 const char **m; 81 70 char *modstr, *p; 82 int i;71 unsigned int i; 83 72 84 73 /* spaces not admitted */ … … 96 85 } 97 86 talloc_steal(modules, modstr); 87 88 if (modstr[0] == '\0') { 89 modules[0] = NULL; 90 m = (const char **)modules; 91 return m; 92 } 98 93 99 94 i = 0; … … 131 126 } *registered_modules = NULL; 132 127 133 static const struct ldb_builtins { 134 const struct ldb_backend_ops *backend_ops; 135 const struct ldb_module_ops *module_ops; 136 } builtins[]; 137 138 static ldb_connect_fn ldb_find_backend(const char *url) 128 static struct backends_list_entry *ldb_find_backend(const char *url_prefix) 139 129 { 140 130 struct backends_list_entry *backend; 141 int i;142 143 for (i = 0; builtins[i].backend_ops || builtins[i].module_ops; i++) {144 if (builtins[i].backend_ops == NULL) continue;145 146 if (strncmp(builtins[i].backend_ops->name, url,147 strlen(builtins[i].backend_ops->name)) == 0) {148 return builtins[i].backend_ops->connect_fn;149 }150 }151 131 152 132 for (backend = ldb_backends; backend; backend = backend->next) { 153 if (strncmp(backend->ops->name, url, 154 strlen(backend->ops->name)) == 0) { 155 return backend->ops->connect_fn; 133 if (strcmp(backend->ops->name, url_prefix) == 0) { 134 return backend; 156 135 } 157 136 } … … 161 140 162 141 /* 163 register a new ldb backend 142 register a new ldb backend 143 144 if override is true, then override any existing backend for this prefix 164 145 */ 165 int ldb_register_backend(const char *url_prefix, ldb_connect_fn connectfn )166 { 167 struct ldb_backend_ops *backend;168 struct backends_list_entry *entry; 169 170 backend = talloc(talloc_autofree_context(), struct ldb_backend_ops);171 if (!backend) return LDB_ERR_OPERATIONS_ERROR;172 173 entry = talloc(talloc_autofree_context(), struct backends_list_entry);174 if (!entry){175 talloc_free(backend);176 return LDB_ERR_OPERATIONS_ERROR;177 }178 179 if (ldb_find_backend(url_prefix)) {180 return LDB_SUCCESS;181 }182 183 /* Maybe check for duplicity here later on? */184 185 backend->name = talloc_strdup(backend, url_prefix);186 backend->connect_fn = connectfn; 187 entry->ops = backend;188 DLIST_ADD(ldb_backends, entry);146 int ldb_register_backend(const char *url_prefix, ldb_connect_fn connectfn, bool override) 147 { 148 struct backends_list_entry *be; 149 150 be = ldb_find_backend(url_prefix); 151 if (be) { 152 if (!override) { 153 return LDB_SUCCESS; 154 } 155 } else { 156 be = talloc_zero(ldb_backends, struct backends_list_entry); 157 if (!be) { 158 return LDB_ERR_OPERATIONS_ERROR; 159 } 160 be->ops = talloc_zero(be, struct ldb_backend_ops); 161 if (!be->ops) { 162 talloc_free(be); 163 return LDB_ERR_OPERATIONS_ERROR; 164 } 165 DLIST_ADD_END(ldb_backends, be, struct backends_list_entry); 166 } 167 168 be->ops->name = url_prefix; 169 be->ops->connect_fn = connectfn; 189 170 190 171 return LDB_SUCCESS; … … 205 186 module may wish to direct certain requests at a particular backend. 206 187 */ 207 int ldb_ connect_backend(struct ldb_context *ldb,208 const char *url,209 const char *options[],210 struct ldb_module **backend_module)188 int ldb_module_connect_backend(struct ldb_context *ldb, 189 const char *url, 190 const char *options[], 191 struct ldb_module **backend_module) 211 192 { 212 193 int ret; 213 194 char *backend; 214 ldb_connect_fn fn;195 struct backends_list_entry *be; 215 196 216 197 if (strchr(url, ':') != NULL) { … … 221 202 } 222 203 223 fn = ldb_find_backend(backend); 224 225 if (fn == NULL) { 226 struct ldb_backend_ops *ops; 227 char *symbol_name = talloc_asprintf(ldb, "ldb_%s_backend_ops", backend); 228 if (symbol_name == NULL) { 229 return LDB_ERR_OPERATIONS_ERROR; 230 } 231 ops = ldb_dso_load_symbol(ldb, backend, symbol_name); 232 if (ops != NULL) { 233 fn = ops->connect_fn; 234 } 235 talloc_free(symbol_name); 236 } 204 be = ldb_find_backend(backend); 237 205 238 206 talloc_free(backend); 239 207 240 if ( fn== NULL) {208 if (be == NULL) { 241 209 ldb_debug(ldb, LDB_DEBUG_FATAL, 242 "Unable to find backend for '%s' ", url);210 "Unable to find backend for '%s' - do you need to set LDB_MODULES_PATH?", url); 243 211 return LDB_ERR_OTHER; 244 212 } 245 213 246 ret = fn(ldb, url, ldb->flags, options, backend_module);214 ret = be->ops->connect_fn(ldb, url, ldb->flags, options, backend_module); 247 215 248 216 if (ret != LDB_SUCCESS) { 249 217 ldb_debug(ldb, LDB_DEBUG_ERROR, 250 "Failed to connect to '%s' ", url);218 "Failed to connect to '%s' with backend '%s'", url, be->ops->name); 251 219 return ret; 252 220 } … … 254 222 } 255 223 224 static struct ldb_hooks { 225 struct ldb_hooks *next, *prev; 226 ldb_hook_fn hook_fn; 227 } *ldb_hooks; 228 229 /* 230 register a ldb hook function 231 */ 232 int ldb_register_hook(ldb_hook_fn hook_fn) 233 { 234 struct ldb_hooks *lc; 235 lc = talloc_zero(ldb_hooks, struct ldb_hooks); 236 if (lc == NULL) { 237 return LDB_ERR_OPERATIONS_ERROR; 238 } 239 lc->hook_fn = hook_fn; 240 DLIST_ADD_END(ldb_hooks, lc, struct ldb_hooks); 241 return LDB_SUCCESS; 242 } 243 244 /* 245 call ldb hooks of a given type 246 */ 247 int ldb_modules_hook(struct ldb_context *ldb, enum ldb_module_hook_type t) 248 { 249 struct ldb_hooks *lc; 250 for (lc = ldb_hooks; lc; lc=lc->next) { 251 int ret = lc->hook_fn(ldb, t); 252 if (ret != LDB_SUCCESS) { 253 return ret; 254 } 255 } 256 return LDB_SUCCESS; 257 } 258 259 256 260 static const struct ldb_module_ops *ldb_find_module_ops(const char *name) 257 261 { 258 262 struct ops_list_entry *e; 259 int i;260 261 for (i = 0; builtins[i].backend_ops || builtins[i].module_ops; i++) {262 if (builtins[i].module_ops == NULL) continue;263 264 if (strcmp(builtins[i].module_ops->name, name) == 0)265 return builtins[i].module_ops;266 }267 263 268 264 for (e = registered_modules; e; e = e->next) { … … 277 273 int ldb_register_module(const struct ldb_module_ops *ops) 278 274 { 279 struct ops_list_entry *entry = talloc(talloc_autofree_context(), struct ops_list_entry);275 struct ops_list_entry *entry; 280 276 281 277 if (ldb_find_module_ops(ops->name) != NULL) 282 return -1; 283 278 return LDB_ERR_ENTRY_ALREADY_EXISTS; 279 280 entry = talloc(talloc_autofree_context(), struct ops_list_entry); 284 281 if (entry == NULL) 285 282 return -1; … … 292 289 } 293 290 294 static void *ldb_dso_load_symbol(struct ldb_context *ldb, const char *name, 295 const char *symbol) 296 { 297 char *path; 298 void *handle; 299 void *sym; 300 301 if (ldb->modules_dir == NULL) 302 return NULL; 303 304 path = talloc_asprintf(ldb, "%s/%s.%s", ldb->modules_dir, name, 305 SHLIBEXT); 306 307 ldb_debug(ldb, LDB_DEBUG_TRACE, "trying to load %s from %s", name, path); 308 309 handle = dlopen(path, RTLD_NOW); 310 if (handle == NULL) { 311 ldb_debug(ldb, LDB_DEBUG_WARNING, "unable to load %s from %s: %s", name, path, dlerror()); 312 return NULL; 313 } 314 315 sym = (int (*)(void))dlsym(handle, symbol); 316 317 if (sym == NULL) { 318 ldb_debug(ldb, LDB_DEBUG_ERROR, "no symbol `%s' found in %s: %s", symbol, path, dlerror()); 319 return NULL; 320 } 321 322 talloc_free(path); 323 324 return sym; 325 } 326 327 int ldb_load_modules_list(struct ldb_context *ldb, const char **module_list, struct ldb_module *backend, struct ldb_module **out) 291 /* 292 load a list of modules 293 */ 294 int ldb_module_load_list(struct ldb_context *ldb, const char **module_list, 295 struct ldb_module *backend, struct ldb_module **out) 328 296 { 329 297 struct ldb_module *module; 330 int i;298 unsigned int i; 331 299 332 300 module = backend; 333 301 334 for (i = 0; module_list [i] != NULL; i++) {302 for (i = 0; module_list && module_list[i] != NULL; i++) { 335 303 struct ldb_module *current; 336 304 const struct ldb_module_ops *ops; … … 341 309 342 310 ops = ldb_find_module_ops(module_list[i]); 311 343 312 if (ops == NULL) { 344 char *symbol_name = talloc_asprintf(ldb, "ldb_%s_module_ops", 345 module_list[i]); 346 if (symbol_name == NULL) { 347 return LDB_ERR_OPERATIONS_ERROR; 348 } 349 ops = ldb_dso_load_symbol(ldb, module_list[i], symbol_name); 350 talloc_free(symbol_name); 351 } 352 353 if (ops == NULL) { 354 ldb_debug(ldb, LDB_DEBUG_WARNING, "WARNING: Module [%s] not found", 313 ldb_debug(ldb, LDB_DEBUG_FATAL, "WARNING: Module [%s] not found - do you need to set LDB_MODULES_PATH?", 355 314 module_list[i]); 356 continue;315 return LDB_ERR_OPERATIONS_ERROR; 357 316 } 358 317 … … 372 331 } 373 332 374 int ldb_init_module_chain(struct ldb_context *ldb, struct ldb_module *module) 333 /* 334 initialise a chain of modules 335 */ 336 int ldb_module_init_chain(struct ldb_context *ldb, struct ldb_module *module) 375 337 { 376 338 while (module && module->ops->init_context == NULL) … … 383 345 int ret = module->ops->init_context(module); 384 346 if (ret != LDB_SUCCESS) { 385 ldb_debug(ldb, LDB_DEBUG_FATAL, "module %s initialization failed", module->ops->name); 347 ldb_debug(ldb, LDB_DEBUG_FATAL, "module %s initialization failed : %s", 348 module->ops->name, ldb_strerror(ret)); 386 349 return ret; 387 350 } … … 393 356 int ldb_load_modules(struct ldb_context *ldb, const char *options[]) 394 357 { 358 const char *modules_string; 395 359 const char **modules = NULL; 396 int i;397 360 int ret; 398 361 TALLOC_CTX *mem_ctx = talloc_new(ldb); … … 405 368 /* check if we have a custom module list passd as ldb option */ 406 369 if (options) { 407 for (i = 0; options[i] != NULL; i++) { 408 if (strncmp(options[i], LDB_MODULE_PREFIX, LDB_MODULE_PREFIX_LEN) == 0) { 409 modules = ldb_modules_list_from_string(ldb, mem_ctx, &options[i][LDB_MODULE_PREFIX_LEN]); 410 } 370 modules_string = ldb_options_find(ldb, options, "modules"); 371 if (modules_string) { 372 modules = ldb_modules_list_from_string(ldb, mem_ctx, modules_string); 411 373 } 412 374 } … … 454 416 455 417 if (modules != NULL) { 456 ret = ldb_ load_modules_list(ldb, modules, ldb->modules, &ldb->modules);418 ret = ldb_module_load_list(ldb, modules, ldb->modules, &ldb->modules); 457 419 if (ret != LDB_SUCCESS) { 458 420 talloc_free(mem_ctx); … … 463 425 } 464 426 465 ret = ldb_ init_module_chain(ldb, ldb->modules);427 ret = ldb_module_init_chain(ldb, ldb->modules); 466 428 talloc_free(mem_ctx); 467 429 return ret; … … 476 438 module = module->next; \ 477 439 while (module && module->ops->op == NULL) module = module->next; \ 440 if ((module && module->ldb->flags & LDB_FLG_ENABLE_TRACING)) { \ 441 ldb_debug(module->ldb, LDB_DEBUG_TRACE, "ldb_trace_next_request: (%s)->" #op, \ 442 module->ops->name); \ 443 } \ 478 444 } while (0) 479 445 … … 516 482 { 517 483 return module->ldb; 484 } 485 486 const struct ldb_module_ops *ldb_module_get_ops(struct ldb_module *module) 487 { 488 return module->ops; 518 489 } 519 490 … … 592 563 * corner for module developers to cut themselves on 593 564 */ 594 ldb_module_done(request, NULL, NULL, ret);565 ret = ldb_module_done(request, NULL, NULL, ret); 595 566 } 596 567 return ret; … … 601 572 module = module->next; 602 573 603 return ldb_ init_module_chain(module->ldb, module);574 return ldb_module_init_chain(module->ldb, module); 604 575 } 605 576 606 577 int ldb_next_start_trans(struct ldb_module *module) 607 578 { 579 int ret; 608 580 FIND_OP(module, start_transaction); 609 return module->ops->start_transaction(module); 581 ret = module->ops->start_transaction(module); 582 if (ret == LDB_SUCCESS) { 583 return ret; 584 } 585 if (!ldb_errstring(module->ldb)) { 586 /* Set a default error string, to place the blame somewhere */ 587 ldb_asprintf_errstring(module->ldb, "start_trans error in module %s: %s (%d)", module->ops->name, ldb_strerror(ret), ret); 588 } 589 if ((module && module->ldb->flags & LDB_FLG_ENABLE_TRACING)) { 590 ldb_debug(module->ldb, LDB_DEBUG_TRACE, "ldb_next_start_trans error: %s", 591 ldb_errstring(module->ldb)); 592 } 593 return ret; 610 594 } 611 595 612 596 int ldb_next_end_trans(struct ldb_module *module) 613 597 { 598 int ret; 614 599 FIND_OP(module, end_transaction); 615 return module->ops->end_transaction(module); 600 ret = module->ops->end_transaction(module); 601 if (ret == LDB_SUCCESS) { 602 return ret; 603 } 604 if (!ldb_errstring(module->ldb)) { 605 /* Set a default error string, to place the blame somewhere */ 606 ldb_asprintf_errstring(module->ldb, "end_trans error in module %s: %s (%d)", module->ops->name, ldb_strerror(ret), ret); 607 } 608 if ((module && module->ldb->flags & LDB_FLG_ENABLE_TRACING)) { 609 ldb_debug(module->ldb, LDB_DEBUG_TRACE, "ldb_next_end_trans error: %s", 610 ldb_errstring(module->ldb)); 611 } 612 return ret; 616 613 } 617 614 618 615 int ldb_next_prepare_commit(struct ldb_module *module) 619 616 { 617 int ret; 620 618 FIND_OP_NOERR(module, prepare_commit); 621 619 if (module == NULL) { … … 624 622 return LDB_SUCCESS; 625 623 } 626 return module->ops->prepare_commit(module); 624 ret = module->ops->prepare_commit(module); 625 if (ret == LDB_SUCCESS) { 626 return ret; 627 } 628 if (!ldb_errstring(module->ldb)) { 629 /* Set a default error string, to place the blame somewhere */ 630 ldb_asprintf_errstring(module->ldb, "prepare_commit error in module %s: %s (%d)", module->ops->name, ldb_strerror(ret), ret); 631 } 632 if ((module && module->ldb->flags & LDB_FLG_ENABLE_TRACING)) { 633 ldb_debug(module->ldb, LDB_DEBUG_TRACE, "ldb_next_prepare_commit error: %s", 634 ldb_errstring(module->ldb)); 635 } 636 return ret; 627 637 } 628 638 629 639 int ldb_next_del_trans(struct ldb_module *module) 630 640 { 641 int ret; 631 642 FIND_OP(module, del_transaction); 632 return module->ops->del_transaction(module); 643 ret = module->ops->del_transaction(module); 644 if (ret == LDB_SUCCESS) { 645 return ret; 646 } 647 if (!ldb_errstring(module->ldb)) { 648 /* Set a default error string, to place the blame somewhere */ 649 ldb_asprintf_errstring(module->ldb, "del_trans error in module %s: %s (%d)", module->ops->name, ldb_strerror(ret), ret); 650 } 651 if ((module && module->ldb->flags & LDB_FLG_ENABLE_TRACING)) { 652 ldb_debug(module->ldb, LDB_DEBUG_TRACE, "ldb_next_del_trans error: %s", 653 ldb_errstring(module->ldb)); 654 } 655 return ret; 633 656 } 634 657 … … 647 670 h->ldb = ldb; 648 671 h->flags = 0; 672 h->location = NULL; 673 h->parent = NULL; 649 674 650 675 return h; … … 729 754 * ctrls: controls to send in the reply (must be a talloc pointer, steal) 730 755 * response: results for extended request (steal) 731 * error: LDB_SUCCESS for a succes ful return756 * error: LDB_SUCCESS for a successful return 732 757 * any other ldb error otherwise 733 758 */ … … 763 788 } 764 789 765 req->callback(req, ares); 766 return error; 790 return req->callback(req, ares); 767 791 } 768 792 769 793 /* to be used *only* in modules init functions. 770 * this function i synchronous and will register794 * this function is synchronous and will register 771 795 * the requested OID in the rootdse module if present 772 796 * otherwise it will return an error */ … … 801 825 } 802 826 803 #ifndef STATIC_LIBLDB_MODULES 804 805 #ifdef HAVE_LDB_LDAP 806 #define LDAP_BACKEND LDB_BACKEND(ldap), LDB_BACKEND(ldapi), LDB_BACKEND(ldaps), 807 #else 808 #define LDAP_BACKEND 827 static int ldb_modules_load_dir(const char *modules_dir, const char *version); 828 829 830 /* 831 load one module. A static list of loaded module inode numbers is 832 used to prevent a module being loaded twice 833 834 dlopen() is used on the module, and dlsym() is then used to look for 835 a ldb_init_module() function. If present, that function is called 836 with the ldb version number as an argument. 837 838 The ldb_init_module() function will typically call 839 ldb_register_module() and ldb_register_backend() to register a 840 module or backend, but it may also be used to register command line 841 handling functions, ldif handlers or any other local 842 modififications. 843 844 The ldb_init_module() function does not get a ldb_context passed in, 845 as modules will be used for multiple ldb context handles. The call 846 from the first ldb_init() is just a convenient way to ensure it is 847 called early enough. 848 */ 849 static int ldb_modules_load_path(const char *path, const char *version) 850 { 851 void *handle; 852 int (*init_fn)(const char *); 853 int ret; 854 struct stat st; 855 static struct loaded { 856 struct loaded *next, *prev; 857 ino_t st_ino; 858 dev_t st_dev; 859 } *loaded; 860 struct loaded *le; 861 int dlopen_flags; 862 863 ret = stat(path, &st); 864 if (ret != 0) { 865 fprintf(stderr, "ldb: unable to stat module %s : %s\n", path, strerror(errno)); 866 return LDB_ERR_UNAVAILABLE; 867 } 868 869 for (le=loaded; le; le=le->next) { 870 if (le->st_ino == st.st_ino && 871 le->st_dev == st.st_dev) { 872 /* its already loaded */ 873 return LDB_SUCCESS; 874 } 875 } 876 877 le = talloc(loaded, struct loaded); 878 if (le == NULL) { 879 fprintf(stderr, "ldb: unable to allocated loaded entry\n"); 880 return LDB_ERR_UNAVAILABLE; 881 } 882 883 le->st_ino = st.st_ino; 884 le->st_dev = st.st_dev; 885 886 DLIST_ADD_END(loaded, le, struct loaded); 887 888 /* if it is a directory, recurse */ 889 if (S_ISDIR(st.st_mode)) { 890 return ldb_modules_load_dir(path, version); 891 } 892 893 dlopen_flags = RTLD_NOW; 894 #ifdef RTLD_DEEPBIND 895 /* use deepbind if possible, to avoid issues with different 896 system library varients, for example ldb modules may be linked 897 against Heimdal while the application may use MIT kerberos 898 899 See the dlopen manpage for details 900 */ 901 dlopen_flags |= RTLD_DEEPBIND; 809 902 #endif 810 903 811 #ifdef HAVE_LDB_SQLITE3 812 #define SQLITE3_BACKEND LDB_BACKEND(sqlite3), 813 #else 814 #define SQLITE3_BACKEND 815 #endif 816 817 #define STATIC_LIBLDB_MODULES \ 818 LDB_BACKEND(tdb), \ 819 LDAP_BACKEND \ 820 SQLITE3_BACKEND \ 821 LDB_MODULE(rdn_name), \ 822 LDB_MODULE(paged_results), \ 823 LDB_MODULE(server_sort), \ 824 LDB_MODULE(asq), \ 825 NULL 826 #endif 827 828 /* 829 * this is a bit hacked, as STATIC_LIBLDB_MODULES contains ',' 830 * between the elements and we want to autogenerate the 831 * extern struct declarations, so we do some hacks and let the 832 * ',' appear in an unused function prototype. 833 */ 834 #undef NULL 835 #define NULL LDB_MODULE(NULL), 836 837 #define LDB_BACKEND(name) \ 838 int); \ 839 extern const struct ldb_backend_ops ldb_ ## name ## _backend_ops;\ 840 extern void ldb_noop ## name (int 841 #define LDB_MODULE(name) \ 842 int); \ 843 extern const struct ldb_module_ops ldb_ ## name ## _module_ops;\ 844 extern void ldb_noop ## name (int 845 846 extern void ldb_start_noop(int, 847 STATIC_LIBLDB_MODULES 848 int); 849 850 #undef NULL 851 #define NULL { \ 852 .backend_ops = (void *)0, \ 853 .module_ops = (void *)0 \ 854 } 855 856 #undef LDB_BACKEND 857 #define LDB_BACKEND(name) { \ 858 .backend_ops = &ldb_ ## name ## _backend_ops, \ 859 .module_ops = (void *)0 \ 860 } 861 #undef LDB_MODULE 862 #define LDB_MODULE(name) { \ 863 .backend_ops = (void *)0, \ 864 .module_ops = &ldb_ ## name ## _module_ops \ 865 } 866 867 static const struct ldb_builtins builtins[] = { 868 STATIC_LIBLDB_MODULES 869 }; 904 handle = dlopen(path, dlopen_flags); 905 if (handle == NULL) { 906 fprintf(stderr, "ldb: unable to dlopen %s : %s\n", path, dlerror()); 907 return LDB_SUCCESS; 908 } 909 910 init_fn = dlsym(handle, "ldb_init_module"); 911 if (init_fn == NULL) { 912 /* ignore it, it could be an old-style 913 * module. Once we've converted all modules we 914 * could consider this an error */ 915 dlclose(handle); 916 return LDB_SUCCESS; 917 } 918 919 ret = init_fn(version); 920 if (ret == LDB_ERR_ENTRY_ALREADY_EXISTS) { 921 /* the module is already registered - ignore this, as 922 * it can happen if LDB_MODULES_PATH points at both 923 * the build and install directory 924 */ 925 ret = LDB_SUCCESS; 926 } 927 return ret; 928 } 929 930 static int qsort_string(const char **s1, const char **s2) 931 { 932 return strcmp(*s1, *s2); 933 } 934 935 936 /* 937 load all modules from the given ldb modules directory. This is run once 938 during the first ldb_init() call. 939 940 Modules are loaded in alphabetical order to ensure that any module 941 load ordering dependencies are reproducible. Modules should avoid 942 relying on load order 943 */ 944 static int ldb_modules_load_dir(const char *modules_dir, const char *version) 945 { 946 DIR *dir; 947 struct dirent *de; 948 const char **modlist = NULL; 949 TALLOC_CTX *tmp_ctx = talloc_new(NULL); 950 unsigned i, num_modules = 0; 951 952 dir = opendir(modules_dir); 953 if (dir == NULL) { 954 if (errno == ENOENT) { 955 talloc_free(tmp_ctx); 956 /* we don't have any modules */ 957 return LDB_SUCCESS; 958 } 959 talloc_free(tmp_ctx); 960 fprintf(stderr, "ldb: unable to open modules directory '%s' - %s\n", 961 modules_dir, strerror(errno)); 962 return LDB_ERR_UNAVAILABLE; 963 } 964 965 966 while ((de = readdir(dir))) { 967 if (ISDOT(de->d_name) || ISDOTDOT(de->d_name)) 968 continue; 969 970 modlist = talloc_realloc(tmp_ctx, modlist, const char *, num_modules+1); 971 if (modlist == NULL) { 972 talloc_free(tmp_ctx); 973 closedir(dir); 974 fprintf(stderr, "ldb: unable to allocate modules list\n"); 975 return LDB_ERR_UNAVAILABLE; 976 } 977 modlist[num_modules] = talloc_asprintf(modlist, "%s/%s", modules_dir, de->d_name); 978 if (modlist[num_modules] == NULL) { 979 talloc_free(tmp_ctx); 980 closedir(dir); 981 fprintf(stderr, "ldb: unable to allocate module list entry\n"); 982 return LDB_ERR_UNAVAILABLE; 983 } 984 num_modules++; 985 } 986 987 closedir(dir); 988 989 /* sort the directory, so we get consistent load ordering */ 990 TYPESAFE_QSORT(modlist, num_modules, qsort_string); 991 992 for (i=0; i<num_modules; i++) { 993 int ret = ldb_modules_load_path(modlist[i], version); 994 if (ret != LDB_SUCCESS) { 995 fprintf(stderr, "ldb: failed to initialise module %s : %s\n", 996 modlist[i], ldb_strerror(ret)); 997 talloc_free(tmp_ctx); 998 return ret; 999 } 1000 } 1001 1002 talloc_free(tmp_ctx); 1003 1004 return LDB_SUCCESS; 1005 } 1006 1007 /* 1008 load any additional modules from the given directory 1009 */ 1010 void ldb_set_modules_dir(struct ldb_context *ldb, const char *path) 1011 { 1012 int ret = ldb_modules_load_path(path, LDB_VERSION); 1013 if (ret != LDB_SUCCESS) { 1014 ldb_asprintf_errstring(ldb, "Failed to load modules from: %s\n", path); 1015 } 1016 } 1017 1018 1019 /* 1020 load all modules static (builtin) modules 1021 */ 1022 static int ldb_modules_load_static(const char *version) 1023 { 1024 static bool initialised; 1025 #define _MODULE_PROTO(init) extern int init(const char *); 1026 STATIC_ldb_MODULES_PROTO; 1027 const ldb_module_init_fn static_init_functions[] = { STATIC_ldb_MODULES }; 1028 unsigned i; 1029 1030 if (initialised) { 1031 return LDB_SUCCESS; 1032 } 1033 initialised = true; 1034 1035 for (i=0; static_init_functions[i]; i++) { 1036 int ret = static_init_functions[i](version); 1037 if (ret != LDB_SUCCESS) { 1038 return ret; 1039 } 1040 } 1041 return LDB_SUCCESS; 1042 } 1043 1044 /* 1045 load all modules from the given ldb modules path, colon 1046 separated. 1047 1048 modules are loaded recursively for all subdirectories in the paths 1049 */ 1050 int ldb_modules_load(const char *modules_path, const char *version) 1051 { 1052 char *tok, *path, *tok_ptr=NULL; 1053 int ret; 1054 1055 ret = ldb_modules_load_static(version); 1056 if (ret != LDB_SUCCESS) { 1057 return ret; 1058 } 1059 1060 path = talloc_strdup(NULL, modules_path); 1061 if (path == NULL) { 1062 fprintf(stderr, "ldb: failed to allocate modules_path\n"); 1063 return LDB_ERR_UNAVAILABLE; 1064 } 1065 1066 for (tok=strtok_r(path, ":", &tok_ptr); 1067 tok; 1068 tok=strtok_r(NULL, ":", &tok_ptr)) { 1069 ret = ldb_modules_load_path(tok, version); 1070 if (ret != LDB_SUCCESS) { 1071 talloc_free(path); 1072 return ret; 1073 } 1074 } 1075 talloc_free(path); 1076 1077 return LDB_SUCCESS; 1078 } 1079 1080 1081 /* 1082 return a string representation of the calling chain for the given 1083 ldb request 1084 */ 1085 char *ldb_module_call_chain(struct ldb_request *req, TALLOC_CTX *mem_ctx) 1086 { 1087 char *ret; 1088 int i=0; 1089 1090 ret = talloc_strdup(mem_ctx, ""); 1091 if (ret == NULL) { 1092 return NULL; 1093 } 1094 1095 while (req && req->handle) { 1096 char *s = talloc_asprintf_append_buffer(ret, "req[%u] %p : %s\n", 1097 i++, req, ldb_req_location(req)); 1098 if (s == NULL) { 1099 talloc_free(ret); 1100 return NULL; 1101 } 1102 ret = s; 1103 req = req->handle->parent; 1104 } 1105 return ret; 1106 } 1107 1108 1109 /* 1110 return the next module in the chain 1111 */ 1112 struct ldb_module *ldb_module_next(struct ldb_module *module) 1113 { 1114 return module->next; 1115 } 1116 1117 /* 1118 set the next module in the module chain 1119 */ 1120 void ldb_module_set_next(struct ldb_module *module, struct ldb_module *next) 1121 { 1122 module->next = next; 1123 } 1124 1125 1126 /* 1127 get the popt_options pointer in the ldb structure. This allows a ldb 1128 module to change the command line parsing 1129 */ 1130 struct poptOption **ldb_module_popt_options(struct ldb_context *ldb) 1131 { 1132 return &ldb->popt_options; 1133 } 1134 1135 1136 /* 1137 return the current ldb flags LDB_FLG_* 1138 */ 1139 uint32_t ldb_module_flags(struct ldb_context *ldb) 1140 { 1141 return ldb->flags; 1142 } -
vendor/current/source4/lib/ldb/common/ldb_msg.c
r414 r740 37 37 create a new ldb_message in a given memory context (NULL for top level) 38 38 */ 39 struct ldb_message *ldb_msg_new( void*mem_ctx)39 struct ldb_message *ldb_msg_new(TALLOC_CTX *mem_ctx) 40 40 { 41 41 return talloc_zero(mem_ctx, struct ldb_message); … … 64 64 { 65 65 if (v1->length != v2->length) return 0; 66 66 if (v1->data == v2->data) return 1; 67 67 if (v1->length == 0) return 1; 68 68 … … 93 93 duplicate a ldb_val structure 94 94 */ 95 struct ldb_val ldb_val_dup( void*mem_ctx, const struct ldb_val *v)95 struct ldb_val ldb_val_dup(TALLOC_CTX *mem_ctx, const struct ldb_val *v) 96 96 { 97 97 struct ldb_val v2; … … 115 115 } 116 116 117 /* 118 add an empty element to a message 119 */ 120 int ldb_msg_add_empty( struct ldb_message *msg, 121 const char *attr_name, 122 int flags, 123 struct ldb_message_element **return_el) 117 /** 118 * Adds new empty element to msg->elements 119 */ 120 static int _ldb_msg_add_el(struct ldb_message *msg, 121 struct ldb_message_element **return_el) 124 122 { 125 123 struct ldb_message_element *els; 126 124 127 els = talloc_realloc(msg, msg->elements, 128 struct ldb_message_element, msg->num_elements+1); 125 /* 126 * TODO: Find out a way to assert on input parameters. 127 * msg and return_el must be valid 128 */ 129 130 els = talloc_realloc(msg, msg->elements, 131 struct ldb_message_element, msg->num_elements + 1); 129 132 if (!els) { 130 133 errno = ENOMEM; … … 132 135 } 133 136 134 els[msg->num_elements].values = NULL; 135 els[msg->num_elements].num_values = 0; 136 els[msg->num_elements].flags = flags; 137 els[msg->num_elements].name = talloc_strdup(els, attr_name); 138 if (!els[msg->num_elements].name) { 137 ZERO_STRUCT(els[msg->num_elements]); 138 139 msg->elements = els; 140 msg->num_elements++; 141 142 *return_el = &els[msg->num_elements-1]; 143 144 return LDB_SUCCESS; 145 } 146 147 /** 148 * Add an empty element with a given name to a message 149 */ 150 int ldb_msg_add_empty(struct ldb_message *msg, 151 const char *attr_name, 152 int flags, 153 struct ldb_message_element **return_el) 154 { 155 int ret; 156 struct ldb_message_element *el; 157 158 ret = _ldb_msg_add_el(msg, &el); 159 if (ret != LDB_SUCCESS) { 160 return ret; 161 } 162 163 /* initialize newly added element */ 164 el->flags = flags; 165 el->name = talloc_strdup(msg->elements, attr_name); 166 if (!el->name) { 139 167 errno = ENOMEM; 140 168 return LDB_ERR_OPERATIONS_ERROR; 141 169 } 142 170 143 msg->elements = els;144 msg->num_elements++;145 146 171 if (return_el) { 147 *return_el = &els[msg->num_elements-1];172 *return_el = el; 148 173 } 149 174 … … 151 176 } 152 177 153 /* 154 add an empty element to a message 155 */ 178 /** 179 * Adds an element to a message. 180 * 181 * NOTE: Ownership of ldb_message_element fields 182 * is NOT transferred. Thus, if *el pointer 183 * is invalidated for some reason, this will 184 * corrupt *msg contents also 185 */ 156 186 int ldb_msg_add(struct ldb_message *msg, 157 187 const struct ldb_message_element *el, 158 188 int flags) 159 189 { 190 int ret; 191 struct ldb_message_element *el_new; 160 192 /* We have to copy this, just in case *el is a pointer into 161 193 * what ldb_msg_add_empty() is about to realloc() */ 162 194 struct ldb_message_element el_copy = *el; 163 if (ldb_msg_add_empty(msg, el->name, flags, NULL) != 0) { 164 return LDB_ERR_OPERATIONS_ERROR; 165 } 166 167 msg->elements[msg->num_elements-1] = el_copy; 168 msg->elements[msg->num_elements-1].flags = flags; 195 196 ret = _ldb_msg_add_el(msg, &el_new); 197 if (ret != LDB_SUCCESS) { 198 return ret; 199 } 200 201 el_new->flags = flags; 202 el_new->name = el_copy.name; 203 el_new->num_values = el_copy.num_values; 204 el_new->values = el_copy.values; 169 205 170 206 return LDB_SUCCESS; … … 191 227 } 192 228 193 vals = talloc_realloc(msg, el->values, struct ldb_val, el->num_values+1); 229 vals = talloc_realloc(msg->elements, el->values, struct ldb_val, 230 el->num_values+1); 194 231 if (!vals) { 195 232 errno = ENOMEM; … … 238 275 239 276 if (val.length == 0) { 240 /* allow empty strings as non-exist ant attributes */277 /* allow empty strings as non-existent attributes */ 241 278 return LDB_SUCCESS; 242 279 } … … 256 293 val.length = strlen(str); 257 294 295 if (val.length == 0) { 296 /* allow empty strings as non-existent attributes */ 297 return LDB_SUCCESS; 298 } 299 258 300 return ldb_msg_add_steal_value(msg, attr_name, &val); 301 } 302 303 /* 304 add a DN element to a message 305 WARNING: this uses the linearized string from the dn, and does not 306 copy the string. 307 */ 308 int ldb_msg_add_linearized_dn(struct ldb_message *msg, const char *attr_name, 309 struct ldb_dn *dn) 310 { 311 char *str = ldb_dn_alloc_linearized(msg, dn); 312 313 if (str == NULL) { 314 /* we don't want to have unknown DNs added */ 315 return LDB_ERR_OPERATIONS_ERROR; 316 } 317 318 return ldb_msg_add_steal_string(msg, attr_name, str); 259 319 } 260 320 … … 283 343 /* 284 344 compare two ldb_message_element structures 285 assumes case sen istive comparison345 assumes case sensitive comparison 286 346 */ 287 347 int ldb_msg_element_compare(struct ldb_message_element *el1, … … 342 402 unsigned int default_value) 343 403 { 404 unsigned int ret; 344 405 const struct ldb_val *v = ldb_msg_find_ldb_val(msg, attr_name); 345 406 if (!v || !v->data) { 346 407 return default_value; 347 408 } 409 410 /* in LDAP there're only int32_t values */ 411 errno = 0; 412 ret = strtol((const char *)v->data, NULL, 0); 413 if (errno == 0) { 414 return ret; 415 } 416 348 417 return strtoul((const char *)v->data, NULL, 0); 349 418 } … … 364 433 uint64_t default_value) 365 434 { 435 uint64_t ret; 366 436 const struct ldb_val *v = ldb_msg_find_ldb_val(msg, attr_name); 367 437 if (!v || !v->data) { 368 438 return default_value; 369 439 } 440 441 /* in LDAP there're only int64_t values */ 442 errno = 0; 443 ret = strtoll((const char *)v->data, NULL, 0); 444 if (errno == 0) { 445 return ret; 446 } 447 370 448 return strtoull((const char *)v->data, NULL, 0); 371 449 } … … 411 489 412 490 struct ldb_dn *ldb_msg_find_attr_as_dn(struct ldb_context *ldb, 413 void*mem_ctx,491 TALLOC_CTX *mem_ctx, 414 492 const struct ldb_message *msg, 415 493 const char *attr_name) … … 435 513 void ldb_msg_sort_elements(struct ldb_message *msg) 436 514 { 437 qsort(msg->elements, msg->num_elements, sizeof(struct ldb_message_element),438 (comparison_fn_t)ldb_msg_element_compare_name);515 TYPESAFE_QSORT(msg->elements, msg->num_elements, 516 ldb_msg_element_compare_name); 439 517 } 440 518 … … 447 525 { 448 526 struct ldb_message *msg2; 449 int i;527 unsigned int i; 450 528 451 529 msg2 = talloc(mem_ctx, struct ldb_message); … … 477 555 { 478 556 struct ldb_message *msg2; 479 int i, j;557 unsigned int i, j; 480 558 481 559 msg2 = ldb_msg_copy_shallow(mem_ctx, msg); … … 507 585 508 586 509 /* 510 canonicalise a message, merging elements of the same name511 */587 /** 588 * Canonicalize a message, merging elements of the same name 589 */ 512 590 struct ldb_message *ldb_msg_canonicalize(struct ldb_context *ldb, 513 591 const struct ldb_message *msg) 514 592 { 515 int i;593 int ret; 516 594 struct ldb_message *msg2; 517 595 518 msg2 = ldb_msg_copy(ldb, msg); 519 if (msg2 == NULL) return NULL; 596 /* 597 * Preserve previous behavior and allocate 598 * *msg2 into *ldb context 599 */ 600 ret = ldb_msg_normalize(ldb, ldb, msg, &msg2); 601 if (ret != LDB_SUCCESS) { 602 return NULL; 603 } 604 605 return msg2; 606 } 607 608 /** 609 * Canonicalize a message, merging elements of the same name 610 */ 611 int ldb_msg_normalize(struct ldb_context *ldb, 612 TALLOC_CTX *mem_ctx, 613 const struct ldb_message *msg, 614 struct ldb_message **_msg_out) 615 { 616 unsigned int i; 617 struct ldb_message *msg2; 618 619 msg2 = ldb_msg_copy(mem_ctx, msg); 620 if (msg2 == NULL) { 621 return LDB_ERR_OPERATIONS_ERROR; 622 } 520 623 521 624 ldb_msg_sort_elements(msg2); 522 625 523 for (i=1; i<msg2->num_elements;i++) {626 for (i=1; i < msg2->num_elements; i++) { 524 627 struct ldb_message_element *el1 = &msg2->elements[i-1]; 525 628 struct ldb_message_element *el2 = &msg2->elements[i]; 629 526 630 if (ldb_msg_element_compare_name(el1, el2) == 0) { 527 el1->values = talloc_realloc(msg2->elements, el1->values, struct ldb_val, 528 el1->num_values + el2->num_values); 529 if (el1->values == NULL) { 530 return NULL; 631 el1->values = talloc_realloc(msg2->elements, 632 el1->values, struct ldb_val, 633 el1->num_values + el2->num_values); 634 if (el1->num_values + el2->num_values > 0 && el1->values == NULL) { 635 talloc_free(msg2); 636 return LDB_ERR_OPERATIONS_ERROR; 531 637 } 532 638 memcpy(el1->values + el1->num_values, … … 535 641 el1->num_values += el2->num_values; 536 642 talloc_free(discard_const_p(char, el2->name)); 537 if ( i+1<msg2->num_elements) {538 memmove(el2, el2+1, sizeof(struct ldb_message_element) * 643 if ((i+1) < msg2->num_elements) { 644 memmove(el2, el2+1, sizeof(struct ldb_message_element) * 539 645 (msg2->num_elements - (i+1))); 540 646 } … … 544 650 } 545 651 546 return msg2; 547 } 548 549 550 /* 551 return a ldb_message representing the differences between msg1 and msg2. If you 552 then use this in a ldb_modify() call it can be used to save edits to a message 553 */ 652 *_msg_out = msg2; 653 return LDB_SUCCESS; 654 } 655 656 657 /** 658 * return a ldb_message representing the differences between msg1 and msg2. 659 * If you then use this in a ldb_modify() call, 660 * it can be used to save edits to a message 661 */ 554 662 struct ldb_message *ldb_msg_diff(struct ldb_context *ldb, 555 663 struct ldb_message *msg1, 556 664 struct ldb_message *msg2) 557 665 { 666 int ldb_ret; 667 struct ldb_message *mod; 668 669 ldb_ret = ldb_msg_difference(ldb, ldb, msg1, msg2, &mod); 670 if (ldb_ret != LDB_SUCCESS) { 671 return NULL; 672 } 673 674 return mod; 675 } 676 677 /** 678 * return a ldb_message representing the differences between msg1 and msg2. 679 * If you then use this in a ldb_modify() call it can be used to save edits to a message 680 * 681 * Result message is constructed as follows: 682 * - LDB_FLAG_MOD_ADD - elements found only in msg2 683 * - LDB_FLAG_MOD_REPLACE - elements in msg2 that have different value in msg1 684 * Value for msg2 element is used 685 * - LDB_FLAG_MOD_DELETE - elements found only in msg2 686 * 687 * @return LDB_SUCCESS or LDB_ERR_OPERATIONS_ERROR 688 */ 689 int ldb_msg_difference(struct ldb_context *ldb, 690 TALLOC_CTX *mem_ctx, 691 struct ldb_message *msg1, 692 struct ldb_message *msg2, 693 struct ldb_message **_msg_out) 694 { 695 int ldb_res; 696 unsigned int i; 558 697 struct ldb_message *mod; 559 698 struct ldb_message_element *el; 560 unsigned int i; 561 562 mod = ldb_msg_new(ldb); 699 TALLOC_CTX *temp_ctx; 700 701 temp_ctx = talloc_new(mem_ctx); 702 if (!temp_ctx) { 703 return LDB_ERR_OPERATIONS_ERROR; 704 } 705 706 mod = ldb_msg_new(temp_ctx); 707 if (mod == NULL) { 708 goto failed; 709 } 563 710 564 711 mod->dn = msg1->dn; … … 566 713 mod->elements = NULL; 567 714 568 msg2 = ldb_msg_canonicalize(ldb, msg2); 569 if (msg2 == NULL) { 570 return NULL; 571 } 572 573 /* look in msg2 to find elements that need to be added 574 or modified */ 715 /* 716 * Canonicalize *msg2 so we have no repeated elements 717 * Resulting message is allocated in *mod's mem context, 718 * as we are going to move some elements from *msg2 to 719 * *mod object later 720 */ 721 ldb_res = ldb_msg_normalize(ldb, mod, msg2, &msg2); 722 if (ldb_res != LDB_SUCCESS) { 723 goto failed; 724 } 725 726 /* look in msg2 to find elements that need to be added or modified */ 575 727 for (i=0;i<msg2->num_elements;i++) { 576 728 el = ldb_msg_find_element(msg1, msg2->elements[i].name); … … 580 732 } 581 733 582 if (ldb_msg_add(mod, 583 &msg2->elements[i], 584 el?LDB_FLAG_MOD_REPLACE:LDB_FLAG_MOD_ADD) != 0) { 585 return NULL; 734 ldb_res = ldb_msg_add(mod, 735 &msg2->elements[i], 736 el ? LDB_FLAG_MOD_REPLACE : LDB_FLAG_MOD_ADD); 737 if (ldb_res != LDB_SUCCESS) { 738 goto failed; 586 739 } 587 740 } … … 590 743 for (i=0;i<msg1->num_elements;i++) { 591 744 el = ldb_msg_find_element(msg2, msg1->elements[i].name); 592 if (!el) { 593 if (ldb_msg_add_empty(mod, 594 msg1->elements[i].name, 595 LDB_FLAG_MOD_DELETE, NULL) != 0) { 596 return NULL; 745 if (el == NULL) { 746 ldb_res = ldb_msg_add_empty(mod, 747 msg1->elements[i].name, 748 LDB_FLAG_MOD_DELETE, NULL); 749 if (ldb_res != LDB_SUCCESS) { 750 goto failed; 597 751 } 598 752 } 599 753 } 600 754 601 return mod; 602 } 755 /* steal resulting message into supplied context */ 756 talloc_steal(mem_ctx, mod); 757 *_msg_out = mod; 758 759 talloc_free(temp_ctx); 760 return LDB_SUCCESS; 761 762 failed: 763 talloc_free(temp_ctx); 764 return LDB_ERR_OPERATIONS_ERROR; 765 } 766 603 767 604 768 int ldb_msg_sanity_check(struct ldb_context *ldb, 605 769 const struct ldb_message *msg) 606 770 { 607 int i, j;771 unsigned int i, j; 608 772 609 773 /* basic check on DN */ … … 643 807 { 644 808 const char **ret; 645 int i; 809 unsigned int i; 810 646 811 for (i=0;attrs && attrs[i];i++) /* noop */ ; 647 812 ret = talloc_array(mem_ctx, const char *, i+1); … … 664 829 { 665 830 const char **ret; 666 int i;831 unsigned int i; 667 832 bool found = false; 833 668 834 for (i=0;attrs && attrs[i];i++) { 669 835 if (ldb_attr_cmp(attrs[i], new_attr) == 0) { … … 692 858 int ldb_attr_in_list(const char * const *attrs, const char *attr) 693 859 { 694 int i;860 unsigned int i; 695 861 for (i=0;attrs && attrs[i];i++) { 696 862 if (ldb_attr_cmp(attrs[i], attr) == 0) { … … 725 891 { 726 892 struct ldb_message_element *el = ldb_msg_find_element(msg, attr); 893 int ret; 894 727 895 if (el == NULL) { 728 896 return LDB_SUCCESS; 729 897 } 730 if (ldb_msg_add(msg, el, 0) != 0) { 731 return LDB_ERR_OPERATIONS_ERROR; 898 ret = ldb_msg_add(msg, el, 0); 899 if (ret != LDB_SUCCESS) { 900 return ret; 732 901 } 733 902 return ldb_msg_rename_attr(msg, attr, replace); … … 739 908 void ldb_msg_remove_element(struct ldb_message *msg, struct ldb_message_element *el) 740 909 { 741 int n = (el - msg->elements);910 ptrdiff_t n = (el - msg->elements); 742 911 if (n >= msg->num_elements) { 743 912 /* should we abort() here? */ … … 756 925 void ldb_msg_remove_attr(struct ldb_message *msg, const char *attr) 757 926 { 758 struct ldb_message_element *el = ldb_msg_find_element(msg, attr); 759 if (el) { 927 struct ldb_message_element *el; 928 929 while ((el = ldb_msg_find_element(msg, attr)) != NULL) { 760 930 ldb_msg_remove_element(msg, el); 761 931 } … … 803 973 804 974 memset(&tm, 0, sizeof(tm)); 805 if (sscanf(s, "%04u%02u%02u%02u%02u%02u ",975 if (sscanf(s, "%04u%02u%02u%02u%02u%02u.0Z", 806 976 &tm.tm_year, &tm.tm_mon, &tm.tm_mday, 807 977 &tm.tm_hour, &tm.tm_min, &tm.tm_sec) != 6) { … … 812 982 813 983 return timegm(&tm); 984 } 985 986 /* 987 convert a LDAP GeneralizedTime string in ldb_val format to a 988 time_t. 989 */ 990 int ldb_val_to_time(const struct ldb_val *v, time_t *t) 991 { 992 struct tm tm; 993 994 if (v == NULL || !v->data || v->length < 17) { 995 return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX; 996 } 997 998 memset(&tm, 0, sizeof(tm)); 999 1000 if (sscanf((char *)v->data, "%04u%02u%02u%02u%02u%02u.0Z", 1001 &tm.tm_year, &tm.tm_mon, &tm.tm_mday, 1002 &tm.tm_hour, &tm.tm_min, &tm.tm_sec) != 6) { 1003 return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX; 1004 } 1005 tm.tm_year -= 1900; 1006 tm.tm_mon -= 1; 1007 1008 *t = timegm(&tm); 1009 1010 return LDB_SUCCESS; 814 1011 } 815 1012 … … 855 1052 856 1053 memset(&tm, 0, sizeof(tm)); 857 if (sscanf(s, "%02u%02u%02u%02u%02u%02u ",1054 if (sscanf(s, "%02u%02u%02u%02u%02u%02uZ", 858 1055 &tm.tm_year, &tm.tm_mon, &tm.tm_mday, 859 1056 &tm.tm_hour, &tm.tm_min, &tm.tm_sec) != 6) { … … 874 1071 void ldb_dump_results(struct ldb_context *ldb, struct ldb_result *result, FILE *f) 875 1072 { 876 int i;1073 unsigned int i; 877 1074 878 1075 for (i = 0; i < result->count; i++) { … … 885 1082 } 886 1083 887 int ldb_msg_check_string_attribute(const struct ldb_message *msg, const char *name, const char *value) 1084 /* 1085 checks for a string attribute. Returns "1" on match and otherwise "0". 1086 */ 1087 int ldb_msg_check_string_attribute(const struct ldb_message *msg, 1088 const char *name, const char *value) 888 1089 { 889 1090 struct ldb_message_element *el; … … 891 1092 892 1093 el = ldb_msg_find_element(msg, name); 893 if (el == NULL) 1094 if (el == NULL) { 894 1095 return 0; 1096 } 895 1097 896 1098 val.data = discard_const_p(uint8_t, value); 897 1099 val.length = strlen(value); 898 1100 899 if (ldb_msg_find_val(el, &val)) 1101 if (ldb_msg_find_val(el, &val)) { 900 1102 return 1; 1103 } 901 1104 902 1105 return 0; 903 1106 } 1107 -
vendor/current/source4/lib/ldb/common/ldb_parse.c
r414 r740 43 43 #include "ldb_private.h" 44 44 #include "system/locale.h" 45 46 static int ldb_parse_hex2char(const char *x) 47 { 48 if (isxdigit(x[0]) && isxdigit(x[1])) { 49 const char h1 = x[0], h2 = x[1]; 50 int c = 0; 51 52 if (h1 >= 'a') c = h1 - (int)'a' + 10; 53 else if (h1 >= 'A') c = h1 - (int)'A' + 10; 54 else if (h1 >= '0') c = h1 - (int)'0'; 55 c = c << 4; 56 if (h2 >= 'a') c += h2 - (int)'a' + 10; 57 else if (h2 >= 'A') c += h2 - (int)'A' + 10; 58 else if (h2 >= '0') c += h2 - (int)'0'; 59 60 return c; 61 } 62 63 return -1; 64 } 45 65 46 66 /* … … 60 80 Used in LDAP filters. 61 81 */ 62 struct ldb_val ldb_binary_decode( void*mem_ctx, const char *str)63 { 64 int i, j;82 struct ldb_val ldb_binary_decode(TALLOC_CTX *mem_ctx, const char *str) 83 { 84 size_t i, j; 65 85 struct ldb_val ret; 66 int slen = str?strlen(str):0;86 size_t slen = str?strlen(str):0; 67 87 68 88 ret.data = (uint8_t *)talloc_size(mem_ctx, slen+1); … … 72 92 for (i=j=0;i<slen;i++) { 73 93 if (str[i] == '\\') { 74 unsigned c; 75 if (sscanf(&str[i+1], "%02X", &c) != 1) { 94 int c; 95 96 c = ldb_parse_hex2char(&str[i+1]); 97 if (c == -1) { 76 98 talloc_free(ret.data); 77 99 memset(&ret, 0, sizeof(ret)); … … 95 117 non-printable or '\' characters 96 118 */ 97 char *ldb_binary_encode( void*mem_ctx, struct ldb_val val)98 { 99 int i;119 char *ldb_binary_encode(TALLOC_CTX *mem_ctx, struct ldb_val val) 120 { 121 size_t i; 100 122 char *ret; 101 int len = val.length;123 size_t len = val.length; 102 124 unsigned char *buf = val.data; 103 125 … … 130 152 in escaping user data in ldap filters. 131 153 */ 132 char *ldb_binary_encode_string( void*mem_ctx, const char *string)154 char *ldb_binary_encode_string(TALLOC_CTX *mem_ctx, const char *string) 133 155 { 134 156 struct ldb_val val; 157 if (string == NULL) { 158 return NULL; 159 } 135 160 val.data = discard_const_p(uint8_t, string); 136 161 val.length = strlen(string); … … 160 185 chunks separated by wildcards that makes the value portion of the filter 161 186 */ 162 static struct ldb_val **ldb_wildcard_decode( void*mem_ctx, const char *string)187 static struct ldb_val **ldb_wildcard_decode(TALLOC_CTX *mem_ctx, const char *string) 163 188 { 164 189 struct ldb_val **ret = NULL; 165 int val = 0;190 unsigned int val = 0; 166 191 char *wc, *str; 167 192 … … 200 225 } 201 226 202 static struct ldb_parse_tree *ldb_parse_filter( void*mem_ctx, const char **s);227 static struct ldb_parse_tree *ldb_parse_filter(TALLOC_CTX *mem_ctx, const char **s); 203 228 204 229 … … 254 279 } 255 280 256 static enum ldb_parse_op ldb_parse_filtertype( void*mem_ctx, char **type, char **value, const char **s)281 static enum ldb_parse_op ldb_parse_filtertype(TALLOC_CTX *mem_ctx, char **type, char **value, const char **s) 257 282 { 258 283 enum ldb_parse_op filter = 0; … … 352 377 <simple> ::= <attributetype> <filtertype> <attributevalue> 353 378 */ 354 static struct ldb_parse_tree *ldb_parse_simple( void*mem_ctx, const char **s)379 static struct ldb_parse_tree *ldb_parse_simple(TALLOC_CTX *mem_ctx, const char **s) 355 380 { 356 381 char *attr, *value; … … 467 492 <filterlist> ::= <filter> | <filter> <filterlist> 468 493 */ 469 static struct ldb_parse_tree *ldb_parse_filterlist( void*mem_ctx, const char **s)494 static struct ldb_parse_tree *ldb_parse_filterlist(TALLOC_CTX *mem_ctx, const char **s) 470 495 { 471 496 struct ldb_parse_tree *ret, *next; … … 535 560 <not> ::= '!' <filter> 536 561 */ 537 static struct ldb_parse_tree *ldb_parse_not( void*mem_ctx, const char **s)562 static struct ldb_parse_tree *ldb_parse_not(TALLOC_CTX *mem_ctx, const char **s) 538 563 { 539 564 struct ldb_parse_tree *ret; … … 567 592 <filtercomp> ::= <and> | <or> | <not> | <simple> 568 593 */ 569 static struct ldb_parse_tree *ldb_parse_filtercomp( void*mem_ctx, const char **s)594 static struct ldb_parse_tree *ldb_parse_filtercomp(TALLOC_CTX *mem_ctx, const char **s) 570 595 { 571 596 struct ldb_parse_tree *ret; … … 604 629 <filter> ::= '(' <filtercomp> ')' 605 630 */ 606 static struct ldb_parse_tree *ldb_parse_filter( void*mem_ctx, const char **s)631 static struct ldb_parse_tree *ldb_parse_filter(TALLOC_CTX *mem_ctx, const char **s) 607 632 { 608 633 struct ldb_parse_tree *ret; … … 636 661 expression ::= <simple> | <filter> 637 662 */ 638 struct ldb_parse_tree *ldb_parse_tree( void*mem_ctx, const char *s)663 struct ldb_parse_tree *ldb_parse_tree(TALLOC_CTX *mem_ctx, const char *s) 639 664 { 640 665 if (s == NULL || *s == 0) { … … 655 680 construct a ldap parse filter given a parse tree 656 681 */ 657 char *ldb_filter_from_tree( void *mem_ctx,struct ldb_parse_tree *tree)682 char *ldb_filter_from_tree(TALLOC_CTX *mem_ctx, const struct ldb_parse_tree *tree) 658 683 { 659 684 char *s, *s2, *ret; 660 int i;685 unsigned int i; 661 686 662 687 if (tree == NULL) { … … 774 799 775 800 /* 776 replace any occur ances of an attribute name in the parse tree with a801 replace any occurrences of an attribute name in the parse tree with a 777 802 new name 778 803 */ … … 781 806 const char *replace) 782 807 { 783 int i;808 unsigned int i; 784 809 switch (tree->operation) { 785 810 case LDB_OP_AND: … … 827 852 const struct ldb_parse_tree *ot) 828 853 { 829 int i;854 unsigned int i; 830 855 struct ldb_parse_tree *nt; 831 856 -
vendor/current/source4/lib/ldb/common/ldb_utf8.c
r414 r740 54 54 NOTE: does not handle UTF8 55 55 */ 56 char *ldb_casefold_default(void *context, void*mem_ctx, const char *s, size_t n)56 char *ldb_casefold_default(void *context, TALLOC_CTX *mem_ctx, const char *s, size_t n) 57 57 { 58 int i;58 size_t i; 59 59 char *ret = talloc_strndup(mem_ctx, s, n); 60 60 if (!s) { … … 73 73 } 74 74 75 char *ldb_casefold(struct ldb_context *ldb, void*mem_ctx, const char *s, size_t n)75 char *ldb_casefold(struct ldb_context *ldb, TALLOC_CTX *mem_ctx, const char *s, size_t n) 76 76 { 77 77 return ldb->utf8_fns.casefold(ldb->utf8_fns.context, mem_ctx, s, n); … … 85 85 int ldb_valid_attr_name(const char *s) 86 86 { 87 int i;87 size_t i; 88 88 89 89 if (!s || !s[0]) … … 110 110 } 111 111 112 char *ldb_attr_casefold( void*mem_ctx, const char *s)112 char *ldb_attr_casefold(TALLOC_CTX *mem_ctx, const char *s) 113 113 { 114 int i;114 size_t i; 115 115 char *ret = talloc_strdup(mem_ctx, s); 116 116 if (!ret) { -
vendor/current/source4/lib/ldb/include/dlinklist.h
r414 r740 2 2 Unix SMB/CIFS implementation. 3 3 some simple double linked list macros 4 Copyright (C) Andrew Tridgell 1998 4 5 Copyright (C) Andrew Tridgell 1998-2010 6 7 ** NOTE! The following LGPL license applies to the ldb 8 ** library. This does NOT imply that all of Samba is released 9 ** under the LGPL 5 10 6 This program is free software; you can redistribute it and/or modify7 it under the terms of the GNU General Public License as published by8 the Free Software Foundation; either version 3 of the License, or9 (at your option) any later version.10 11 This programis distributed in the hope that it will be useful,11 This library is free software; you can redistribute it and/or 12 modify it under the terms of the GNU Lesser General Public 13 License as published by the Free Software Foundation; either 14 version 3 of the License, or (at your option) any later version. 15 16 This library is distributed in the hope that it will be useful, 12 17 but WITHOUT ANY WARRANTY; without even the implied warranty of 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 GNUGeneral Public License for more details.15 16 You should have received a copy of the GNU General Public License17 along with this program. If not, see <http://www.gnu.org/licenses/>.18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 19 Lesser General Public License for more details. 20 21 You should have received a copy of the GNU Lesser General Public 22 License along with this library; if not, see <http://www.gnu.org/licenses/>. 18 23 */ 19 24 … … 24 29 #define _DLINKLIST_H 25 30 31 /* 32 February 2010 - changed list format to have a prev pointer from the 33 list head. This makes DLIST_ADD_END() O(1) even though we only have 34 one list pointer. 26 35 27 /* hook into the front of the list */ 36 The scheme is as follows: 37 38 1) with no entries in the list: 39 list_head == NULL 40 41 2) with 1 entry in the list: 42 list_head->next == NULL 43 list_head->prev == list_head 44 45 3) with 2 entries in the list: 46 list_head->next == element2 47 list_head->prev == element2 48 element2->prev == list_head 49 element2->next == NULL 50 51 4) with N entries in the list: 52 list_head->next == element2 53 list_head->prev == elementN 54 elementN->prev == element{N-1} 55 elementN->next == NULL 56 57 This allows us to find the tail of the list by using 58 list_head->prev, which means we can add to the end of the list in 59 O(1) time 60 61 62 Note that the 'type' arguments below are no longer needed, but 63 are kept for now to prevent an incompatible argument change 64 */ 65 66 67 /* 68 add an element at the front of a list 69 */ 28 70 #define DLIST_ADD(list, p) \ 29 71 do { \ 30 72 if (!(list)) { \ 31 ( list) = (p);\32 (p)->next = (p)->prev =NULL; \73 (p)->prev = (list) = (p); \ 74 (p)->next = NULL; \ 33 75 } else { \ 76 (p)->prev = (list)->prev; \ 34 77 (list)->prev = (p); \ 35 78 (p)->next = (list); \ 36 (p)->prev = NULL; \37 79 (list) = (p); \ 38 } \80 } \ 39 81 } while (0) 40 82 41 /* remove an element from a list - element doesn't have to be in list. */ 83 /* 84 remove an element from a list 85 Note that the element doesn't have to be in the list. If it 86 isn't then this is a no-op 87 */ 42 88 #define DLIST_REMOVE(list, p) \ 43 89 do { \ 44 90 if ((p) == (list)) { \ 91 if ((p)->next) (p)->next->prev = (p)->prev; \ 45 92 (list) = (p)->next; \ 46 if (list) (list)->prev = NULL; \ 93 } else if ((list) && (p) == (list)->prev) { \ 94 (p)->prev->next = NULL; \ 95 (list)->prev = (p)->prev; \ 47 96 } else { \ 48 97 if ((p)->prev) (p)->prev->next = (p)->next; \ 49 98 if ((p)->next) (p)->next->prev = (p)->prev; \ 50 99 } \ 51 if ((p) && ((p) != (list))) (p)->next = (p)->prev = NULL;\100 if ((p) != (list)) (p)->next = (p)->prev = NULL; \ 52 101 } while (0) 53 102 54 /* promote an element to the top of the list */ 55 #define DLIST_PROMOTE(list, p) \ 103 /* 104 find the head of the list given any element in it. 105 Note that this costs O(N), so you should avoid this macro 106 if at all possible! 107 */ 108 #define DLIST_HEAD(p, result_head) \ 56 109 do { \ 57 DLIST_REMOVE(list,p); \58 DLIST_ADD(list, p); \59 } while 110 (result_head) = (p); \ 111 while (DLIST_PREV(result_head)) (result_head) = (result_head)->prev; \ 112 } while(0) 60 113 61 /* hook into the end of the list - needs the entry type */ 62 #define DLIST_ADD_END(list, p, type) \ 63 do { \ 64 if (!(list)) { \ 65 (list) = (p); \ 66 (p)->next = (p)->prev = NULL; \ 67 } else { \ 68 type tmp; \ 69 for (tmp = (list); tmp->next; tmp = tmp->next) ; \ 70 tmp->next = (p); \ 71 (p)->next = NULL; \ 72 (p)->prev = tmp; \ 73 } \ 74 } while (0) 114 /* return the last element in the list */ 115 #define DLIST_TAIL(list) ((list)?(list)->prev:NULL) 116 117 /* return the previous element in the list. */ 118 #define DLIST_PREV(p) (((p)->prev && (p)->prev->next != NULL)?(p)->prev:NULL) 75 119 76 120 /* insert 'p' after the given element 'el' in a list. If el is NULL then … … 81 125 DLIST_ADD(list, p); \ 82 126 } else { \ 83 p->prev = el; \ 84 p->next = el->next; \ 85 el->next = p; \ 86 if (p->next) p->next->prev = p; \ 127 (p)->prev = (el); \ 128 (p)->next = (el)->next; \ 129 (el)->next = (p); \ 130 if ((p)->next) (p)->next->prev = (p); \ 131 if ((list)->prev == (el)) (list)->prev = (p); \ 87 132 }\ 88 133 } while (0) 89 134 90 /* demote an element to the end of the list, needs the entry type */ 91 #define DLIST_DEMOTE(list, p, type) \ 135 136 /* 137 add to the end of a list. 138 Note that 'type' is ignored 139 */ 140 #define DLIST_ADD_END(list, p, type) \ 92 141 do { \ 93 DLIST_REMOVE(list, p); \ 94 DLIST_ADD_END(list, p, type); \ 142 if (!(list)) { \ 143 DLIST_ADD(list, p); \ 144 } else { \ 145 DLIST_ADD_AFTER(list, p, (list)->prev); \ 146 } \ 95 147 } while (0) 96 148 97 /* concatenate two lists - putting all elements of the 2nd list at the 98 end of the first list */ 99 #define DLIST_CONCATENATE(list1, list2, type) \ 149 /* promote an element to the from of a list */ 150 #define DLIST_PROMOTE(list, p) \ 100 151 do { \ 101 if (!(list1)) { \ 102 (list1) = (list2); \ 103 } else { \ 104 type tmp; \ 105 for (tmp = (list1); tmp->next; tmp = tmp->next) ; \ 106 tmp->next = (list2); \ 107 if (list2) { \ 108 (list2)->prev = tmp; \ 109 } \ 152 DLIST_REMOVE(list, p); \ 153 DLIST_ADD(list, p); \ 154 } while (0) 155 156 /* 157 demote an element to the end of a list. 158 Note that 'type' is ignored 159 */ 160 #define DLIST_DEMOTE(list, p, type) \ 161 do { \ 162 DLIST_REMOVE(list, p); \ 163 DLIST_ADD_END(list, p, NULL); \ 164 } while (0) 165 166 /* 167 concatenate two lists - putting all elements of the 2nd list at the 168 end of the first list. 169 Note that 'type' is ignored 170 */ 171 #define DLIST_CONCATENATE(list1, list2, type) \ 172 do { \ 173 if (!(list1)) { \ 174 (list1) = (list2); \ 175 } else { \ 176 (list1)->prev->next = (list2); \ 177 if (list2) { \ 178 void *_tmplist = (void *)(list1)->prev; \ 179 (list1)->prev = (list2)->prev; \ 180 (list2)->prev = _tmplist; \ 110 181 } \ 182 } \ 111 183 } while (0) 112 184 -
vendor/current/source4/lib/ldb/include/ldb.h
r414 r740 48 48 49 49 #include <stdbool.h> 50 #include "talloc.h" 51 #include "tevent.h" 52 #include "ldb_errors.h" 50 #include <talloc.h> 51 #include <tevent.h> 52 #include <ldb_version.h> 53 #include <ldb_errors.h> 53 54 54 55 /* … … 86 87 #ifndef PRINTF_ATTRIBUTE 87 88 #define PRINTF_ATTRIBUTE(a,b) 89 #endif 90 91 #ifndef _DEPRECATED_ 92 #if (__GNUC__ >= 3) && (__GNUC_MINOR__ >= 1 ) 93 #define _DEPRECATED_ __attribute__ ((deprecated)) 94 #else 95 #define _DEPRECATED_ 96 #endif 88 97 #endif 89 98 /*! \endcond */ … … 103 112 104 113 /** 114 use this to extract the mod type from the operation 115 */ 116 #define LDB_FLAG_MOD_TYPE(flags) ((flags) & LDB_FLAG_MOD_MASK) 117 118 /** 105 119 Flag value used in ldap_modify() to indicate that attributes are 106 120 being added. … … 125 139 */ 126 140 #define LDB_FLAG_MOD_DELETE 3 141 142 /** 143 flag bits on an element usable only by the internal implementation 144 */ 145 #define LDB_FLAG_INTERNAL_MASK 0xFFFFFFF0 127 146 128 147 /** … … 297 316 298 317 struct ldb_parse_tree *ldb_parse_tree(TALLOC_CTX *mem_ctx, const char *s); 299 char *ldb_filter_from_tree(TALLOC_CTX *mem_ctx, struct ldb_parse_tree *tree);318 char *ldb_filter_from_tree(TALLOC_CTX *mem_ctx, const struct ldb_parse_tree *tree); 300 319 301 320 /** … … 336 355 typedef int (*ldb_attr_handler_t)(struct ldb_context *, TALLOC_CTX *mem_ctx, const struct ldb_val *, struct ldb_val *); 337 356 typedef int (*ldb_attr_comparison_t)(struct ldb_context *, TALLOC_CTX *mem_ctx, const struct ldb_val *, const struct ldb_val *); 357 struct ldb_schema_attribute; 358 typedef int (*ldb_attr_operator_t)(struct ldb_context *, enum ldb_parse_op operation, 359 const struct ldb_schema_attribute *a, 360 const struct ldb_val *, const struct ldb_val *, bool *matched); 338 361 339 362 /* … … 353 376 ldb_attr_handler_t canonicalise_fn; 354 377 ldb_attr_comparison_t comparison_fn; 378 ldb_attr_operator_t operator_fn; 355 379 }; 356 380 … … 457 481 typedef int (*ldb_qsort_cmp_fn_t) (void *v1, void *v2, void *opaque); 458 482 483 /* Individual controls */ 484 485 /** 486 OID for getting and manipulating attributes from the ldb 487 without interception in the operational module. 488 It can be used to access attribute that used to be stored in the sam 489 and that are now calculated. 490 */ 491 #define LDB_CONTROL_BYPASS_OPERATIONAL_OID "1.3.6.1.4.1.7165.4.3.13" 492 #define LDB_CONTROL_BYPASS_OPERATIONAL_NAME "bypassoperational" 493 494 /** 495 OID for recalculate SD control. This control force the 496 dsdb code to recalculate the SD of the object as if the 497 object was just created. 498 499 */ 500 #define LDB_CONTROL_RECALCULATE_SD_OID "1.3.6.1.4.1.7165.4.3.5" 501 #define LDB_CONTROL_RECALCULATE_SD_NAME "recalculate_sd" 502 503 /** 504 REVEAL_INTERNALS is used to reveal internal attributes and DN 505 components which are not normally shown to the user 506 */ 507 #define LDB_CONTROL_REVEAL_INTERNALS "1.3.6.1.4.1.7165.4.3.6" 508 #define LDB_CONTROL_REVEAL_INTERNALS_NAME "reveal_internals" 509 510 /** 511 LDB_CONTROL_AS_SYSTEM is used to skip access checks on operations 512 that are performed by the system, but with a user's credentials, e.g. 513 updating prefix map 514 */ 515 #define LDB_CONTROL_AS_SYSTEM_OID "1.3.6.1.4.1.7165.4.3.7" 516 517 /** 518 LDB_CONTROL_PROVISION_OID is used to skip some constraint checks. It's is 519 mainly thought to be used for the provisioning. 520 */ 521 #define LDB_CONTROL_PROVISION_OID "1.3.6.1.4.1.7165.4.3.16" 522 #define LDB_CONTROL_PROVISION_NAME "provision" 523 524 /* AD controls */ 525 459 526 /** 460 527 OID for the paged results control. This control is included in the … … 466 533 */ 467 534 #define LDB_CONTROL_PAGED_RESULTS_OID "1.2.840.113556.1.4.319" 535 #define LDB_CONTROL_PAGED_RESULTS_NAME "paged_result" 468 536 469 537 /** … … 473 541 */ 474 542 #define LDB_CONTROL_SD_FLAGS_OID "1.2.840.113556.1.4.801" 543 #define LDB_CONTROL_SD_FLAGS_NAME "sd_flags" 475 544 476 545 /** … … 480 549 */ 481 550 #define LDB_CONTROL_DOMAIN_SCOPE_OID "1.2.840.113556.1.4.1339" 551 #define LDB_CONTROL_DOMAIN_SCOPE_NAME "domain_scope" 482 552 483 553 /** … … 487 557 */ 488 558 #define LDB_CONTROL_SEARCH_OPTIONS_OID "1.2.840.113556.1.4.1340" 559 #define LDB_CONTROL_SEARCH_OPTIONS_NAME "search_options" 489 560 490 561 /** … … 494 565 */ 495 566 #define LDB_CONTROL_NOTIFICATION_OID "1.2.840.113556.1.4.528" 567 #define LDB_CONTROL_NOTIFICATION_NAME "notification" 568 569 /** 570 OID for performing subtree deletes 571 572 \sa <a href="http://msdn.microsoft.com/en-us/library/aa366991(v=VS.85).aspx">Microsoft documentation of this OID</a> 573 */ 574 #define LDB_CONTROL_TREE_DELETE_OID "1.2.840.113556.1.4.805" 575 #define LDB_CONTROL_TREE_DELETE_NAME "tree_delete" 496 576 497 577 /** … … 501 581 */ 502 582 #define LDB_CONTROL_SHOW_DELETED_OID "1.2.840.113556.1.4.417" 583 #define LDB_CONTROL_SHOW_DELETED_NAME "show_deleted" 503 584 504 585 /** … … 508 589 */ 509 590 #define LDB_CONTROL_SHOW_RECYCLED_OID "1.2.840.113556.1.4.2064" 591 #define LDB_CONTROL_SHOW_RECYCLED_NAME "show_recycled" 510 592 511 593 /** … … 515 597 */ 516 598 #define LDB_CONTROL_SHOW_DEACTIVATED_LINK_OID "1.2.840.113556.1.4.2065" 599 #define LDB_CONTROL_SHOW_DEACTIVATED_LINK_NAME "show_deactivated_link" 517 600 518 601 /** … … 522 605 */ 523 606 #define LDB_CONTROL_EXTENDED_DN_OID "1.2.840.113556.1.4.529" 607 #define LDB_CONTROL_EXTENDED_DN_NAME "extended_dn" 524 608 525 609 /** … … 536 620 */ 537 621 #define LDB_CONTROL_SERVER_SORT_OID "1.2.840.113556.1.4.473" 622 #define LDB_CONTROL_SERVER_SORT_NAME "server_sort" 538 623 539 624 /** … … 547 632 */ 548 633 #define LDB_CONTROL_SORT_RESP_OID "1.2.840.113556.1.4.474" 634 #define LDB_CONTROL_SORT_RESP_NAME "server_sort_resp" 549 635 550 636 /** … … 555 641 */ 556 642 #define LDB_CONTROL_ASQ_OID "1.2.840.113556.1.4.1504" 643 #define LDB_CONTROL_ASQ_NAME "asq" 557 644 558 645 /** … … 563 650 */ 564 651 #define LDB_CONTROL_DIRSYNC_OID "1.2.840.113556.1.4.841" 652 #define LDB_CONTROL_DIRSYNC_NAME "dirsync" 565 653 566 654 … … 572 660 */ 573 661 #define LDB_CONTROL_VLV_REQ_OID "2.16.840.1.113730.3.4.9" 662 #define LDB_CONTROL_VLV_REQ_NAME "vlv" 574 663 575 664 /** … … 580 669 */ 581 670 #define LDB_CONTROL_VLV_RESP_OID "2.16.840.1.113730.3.4.10" 671 #define LDB_CONTROL_VLV_RESP_NAME "vlv_resp" 582 672 583 673 /** … … 588 678 */ 589 679 #define LDB_CONTROL_PERMISSIVE_MODIFY_OID "1.2.840.113556.1.4.1413" 680 #define LDB_CONTROL_PERMISSIVE_MODIFY_NAME "permissive_modify" 681 682 /** 683 OID to allow the server to be more 'fast and loose' with the data being added. 684 685 \sa <a href="http://msdn.microsoft.com/en-us/library/aa366982(v=VS.85).aspx">Microsoft documentation of this OID</a> 686 */ 687 #define LDB_CONTROL_SERVER_LAZY_COMMIT "1.2.840.113556.1.4.619" 688 689 /** 690 Control for RODC join -see [MS-ADTS] section 3.1.1.3.4.1.23 691 692 \sa <a href="">Microsoft documentation of this OID</a> 693 */ 694 #define LDB_CONTROL_RODC_DCPROMO_OID "1.2.840.113556.1.4.1341" 695 #define LDB_CONTROL_RODC_DCPROMO_NAME "rodc_join" 696 697 /* Other standardised controls */ 698 699 /** 700 OID for the allowing client to request temporary relaxed 701 enforcement of constraints of the x.500 model. 702 703 Mainly used for the OpenLDAP backend. 704 705 \sa <a href="http://opends.dev.java.net/public/standards/draft-zeilenga-ldap-managedit.txt">draft managedit</a>. 706 */ 707 #define LDB_CONTROL_RELAX_OID "1.3.6.1.4.1.4203.666.5.12" 708 #define LDB_CONTROL_RELAX_NAME "relax" 709 710 /* Extended operations */ 711 712 /** 713 OID for LDAP Extended Operation SEQUENCE_NUMBER 714 715 This extended operation is used to retrieve the extended sequence number. 716 */ 717 #define LDB_EXTENDED_SEQUENCE_NUMBER "1.3.6.1.4.1.7165.4.4.3" 718 719 /** 720 OID for LDAP Extended Operation PASSWORD_CHANGE. 721 722 This Extended operation is used to allow user password changes by the user 723 itself. 724 */ 725 #define LDB_EXTENDED_PASSWORD_CHANGE_OID "1.3.6.1.4.1.4203.1.11.1" 726 727 728 /** 729 OID for LDAP Extended Operation FAST_BIND 730 731 This Extended operations is used to perform a fast bind. 732 */ 733 #define LDB_EXTENDED_FAST_BIND_OID "1.2.840.113556.1.4.1781" 590 734 591 735 /** 592 736 OID for LDAP Extended Operation START_TLS. 593 737 594 This Extended operation is used to start a new TLS 595 channel on top of a cleartext channel.738 This Extended operation is used to start a new TLS channel on top of a clear 739 text channel. 596 740 */ 597 741 #define LDB_EXTENDED_START_TLS_OID "1.3.6.1.4.1.1466.20037" 598 742 599 743 /** 744 OID for LDAP Extended Operation DYNAMIC_REFRESH. 745 746 This Extended operation is used to create and maintain objects which exist 747 only a specific time, e.g. when a certain client or a certain person is 748 logged in. Data refreshes have to be periodically sent in a specific 749 interval. Otherwise the entry is going to be removed. 600 750 */ 601 751 #define LDB_EXTENDED_DYNAMIC_OID "1.3.6.1.4.1.1466.101.119.1" 602 603 /**604 */605 #define LDB_EXTENDED_FAST_BIND_OID "1.2.840.113556.1.4.1781"606 752 607 753 struct ldb_sd_flags_control { … … 736 882 }; 737 883 738 #define LDB_EXTENDED_SEQUENCE_NUMBER "1.3.6.1.4.1.7165.4.4.3"739 740 884 enum ldb_sequence_type { 741 885 LDB_SEQ_HIGHEST_SEQ, … … 964 1108 int ldb_op_default_callback(struct ldb_request *req, struct ldb_reply *ares); 965 1109 1110 int ldb_modify_default_callback(struct ldb_request *req, struct ldb_reply *ares); 966 1111 967 1112 /** … … 1118 1263 1119 1264 /** 1265 replace a ldb_control in a ldb_request 1266 1267 \param req the request struct where to add the control 1268 \param oid the object identifier of the control as string 1269 \param critical whether the control should be critical or not 1270 \param data a talloc pointer to the control specific data 1271 1272 \return result code (LDB_SUCCESS on success, or a failure code) 1273 */ 1274 int ldb_request_replace_control(struct ldb_request *req, const char *oid, bool critical, void *data); 1275 1276 /** 1120 1277 check if a control with the specified "oid" exist and return it 1121 1278 \param req the request struct where to add the control … … 1309 1466 int ldb_transaction_cancel(struct ldb_context *ldb); 1310 1467 1468 /* 1469 cancel a transaction with no error if no transaction is pending 1470 used when we fork() to clear any parent transactions 1471 */ 1472 int ldb_transaction_cancel_noerr(struct ldb_context *ldb); 1473 1311 1474 1312 1475 /** … … 1551 1714 \param mode Style of extended DN to return (0 is HEX representation of binary form, 1 is a string form) 1552 1715 */ 1553 char *ldb_dn_get_extended_linearized( void*mem_ctx, struct ldb_dn *dn, int mode);1716 char *ldb_dn_get_extended_linearized(TALLOC_CTX *mem_ctx, struct ldb_dn *dn, int mode); 1554 1717 const struct ldb_val *ldb_dn_get_extended_component(struct ldb_dn *dn, const char *name); 1555 1718 int ldb_dn_set_extended_component(struct ldb_dn *dn, const char *name, const struct ldb_val *val); 1556 1719 void ldb_dn_extended_filter(struct ldb_dn *dn, const char * const *accept_list); 1557 1720 void ldb_dn_remove_extended_components(struct ldb_dn *dn); 1558 1721 bool ldb_dn_has_extended(struct ldb_dn *dn); … … 1591 1754 */ 1592 1755 1593 struct ldb_dn *ldb_dn_from_ldb_val( void*mem_ctx, struct ldb_context *ldb, const struct ldb_val *strdn);1756 struct ldb_dn *ldb_dn_from_ldb_val(TALLOC_CTX *mem_ctx, struct ldb_context *ldb, const struct ldb_val *strdn); 1594 1757 1595 1758 /** … … 1620 1783 char *ldb_dn_canonical_ex_string(TALLOC_CTX *mem_ctx, struct ldb_dn *dn); 1621 1784 int ldb_dn_get_comp_num(struct ldb_dn *dn); 1785 int ldb_dn_get_extended_comp_num(struct ldb_dn *dn); 1622 1786 const char *ldb_dn_get_component_name(struct ldb_dn *dn, unsigned int num); 1623 1787 const struct ldb_val *ldb_dn_get_component_val(struct ldb_dn *dn, unsigned int num); … … 1630 1794 bool ldb_dn_check_special(struct ldb_dn *dn, const char *check); 1631 1795 bool ldb_dn_is_null(struct ldb_dn *dn); 1796 int ldb_dn_update_components(struct ldb_dn *dn, const struct ldb_dn *ref_dn); 1632 1797 1633 1798 … … 1713 1878 int ldb_msg_add_string(struct ldb_message *msg, 1714 1879 const char *attr_name, const char *str); 1880 int ldb_msg_add_linearized_dn(struct ldb_message *msg, const char *attr_name, 1881 struct ldb_dn *dn); 1715 1882 int ldb_msg_add_fmt(struct ldb_message *msg, 1716 1883 const char *attr_name, const char *fmt, ...) PRINTF_ATTRIBUTE(3,4); … … 1766 1933 const struct ldb_message *msg); 1767 1934 1935 /* 1936 * ldb_msg_canonicalize() is now depreciated 1937 * Please use ldb_msg_normalize() instead 1938 * 1939 * NOTE: Returned ldb_message object is allocated 1940 * into *ldb's context. Callers are recommended 1941 * to steal the returned object into a TALLOC_CTX 1942 * with short lifetime. 1943 */ 1768 1944 struct ldb_message *ldb_msg_canonicalize(struct ldb_context *ldb, 1769 const struct ldb_message *msg); 1770 1771 1945 const struct ldb_message *msg) _DEPRECATED_; 1946 1947 int ldb_msg_normalize(struct ldb_context *ldb, 1948 TALLOC_CTX *mem_ctx, 1949 const struct ldb_message *msg, 1950 struct ldb_message **_msg_out); 1951 1952 1953 /* 1954 * ldb_msg_diff() is now depreciated 1955 * Please use ldb_msg_difference() instead 1956 * 1957 * NOTE: Returned ldb_message object is allocated 1958 * into *ldb's context. Callers are recommended 1959 * to steal the returned object into a TALLOC_CTX 1960 * with short lifetime. 1961 */ 1772 1962 struct ldb_message *ldb_msg_diff(struct ldb_context *ldb, 1773 1963 struct ldb_message *msg1, 1774 struct ldb_message *msg2); 1775 1964 struct ldb_message *msg2) _DEPRECATED_; 1965 1966 /** 1967 * return a ldb_message representing the differences between msg1 and msg2. 1968 * If you then use this in a ldb_modify() call, 1969 * it can be used to save edits to a message 1970 * 1971 * Result message is constructed as follows: 1972 * - LDB_FLAG_MOD_ADD - elements found only in msg2 1973 * - LDB_FLAG_MOD_REPLACE - elements in msg2 that have 1974 * different value in msg1 1975 * Value for msg2 element is used 1976 * - LDB_FLAG_MOD_DELETE - elements found only in msg2 1977 * 1978 * @return LDB_SUCCESS or LDB_ERR_OPERATIONS_ERROR 1979 */ 1980 int ldb_msg_difference(struct ldb_context *ldb, 1981 TALLOC_CTX *mem_ctx, 1982 struct ldb_message *msg1, 1983 struct ldb_message *msg2, 1984 struct ldb_message **_msg_out); 1985 1986 /** 1987 Tries to find a certain string attribute in a message 1988 1989 \param msg the message to check 1990 \param name attribute name 1991 \param value attribute value 1992 1993 \return 1 on match and 0 otherwise. 1994 */ 1776 1995 int ldb_msg_check_string_attribute(const struct ldb_message *msg, 1777 1996 const char *name, … … 1880 2099 1881 2100 /** 2101 convert a LDAP GeneralizedTime string in ldb_val format to a 2102 time_t. 2103 */ 2104 int ldb_val_to_time(const struct ldb_val *v, time_t *t); 2105 2106 /** 1882 2107 Convert a time structure to a string 1883 2108 … … 1908 2133 void ldb_qsort (void *const pbase, size_t total_elems, size_t size, void *opaque, ldb_qsort_cmp_fn_t cmp); 1909 2134 1910 2135 #ifndef discard_const 2136 #define discard_const(ptr) ((void *)((uintptr_t)(ptr))) 2137 #endif 2138 2139 /* 2140 a wrapper around ldb_qsort() that ensures the comparison function is 2141 type safe. This will produce a compilation warning if the types 2142 don't match 2143 */ 2144 #define LDB_TYPESAFE_QSORT(base, numel, opaque, comparison) \ 2145 do { \ 2146 if (numel > 1) { \ 2147 ldb_qsort(base, numel, sizeof((base)[0]), discard_const(opaque), (ldb_qsort_cmp_fn_t)comparison); \ 2148 comparison(&((base)[0]), &((base)[1]), opaque); \ 2149 } \ 2150 } while (0) 2151 2152 /* allow ldb to also call TYPESAFE_QSORT() */ 2153 #ifndef TYPESAFE_QSORT 2154 #define TYPESAFE_QSORT(base, numel, comparison) \ 2155 do { \ 2156 if (numel > 1) { \ 2157 qsort(base, numel, sizeof((base)[0]), (int (*)(const void *, const void *))comparison); \ 2158 comparison(&((base)[0]), &((base)[1])); \ 2159 } \ 2160 } while (0) 2161 #endif 2162 2163 2164 2165 /** 2166 Convert a control into its string representation. 2167 2168 \param mem_ctx TALLOC context to return result on, and to allocate error_string on 2169 \param control A struct ldb_control to convert 2170 2171 \return string representation of the control 2172 */ 2173 char* ldb_control_to_string(TALLOC_CTX *mem_ctx, const struct ldb_control *control); 2174 /** 2175 Convert a string representing a control into a ldb_control structure 2176 2177 \param ldb LDB context 2178 \param mem_ctx TALLOC context to return result on, and to allocate error_string on 2179 \param control_strings A string-formatted control 2180 2181 \return a ldb_control element 2182 */ 2183 struct ldb_control *ldb_parse_control_from_string(struct ldb_context *ldb, TALLOC_CTX *mem_ctx, const char *control_strings); 1911 2184 /** 1912 2185 Convert an array of string represention of a control into an array of ldb_control structures … … 1929 2202 1930 2203 2204 struct ldb_dn *ldb_dn_binary_from_ldb_val(TALLOC_CTX *mem_ctx, 2205 struct ldb_context *ldb, 2206 const struct ldb_val *strdn); 2207 2208 int ldb_dn_get_binary(struct ldb_dn *dn, struct ldb_val *val); 2209 int ldb_dn_set_binary(struct ldb_dn *dn, struct ldb_val *val); 2210 2211 /* debugging functions for ldb requests */ 2212 void ldb_req_set_location(struct ldb_request *req, const char *location); 2213 const char *ldb_req_location(struct ldb_request *req); 2214 2215 /* set the location marker on a request handle - used for debugging */ 2216 #define LDB_REQ_SET_LOCATION(req) ldb_req_set_location(req, __location__) 2217 2218 /* 2219 minimise a DN. The caller must pass in a validated DN. 2220 2221 If the DN has an extended component then only the first extended 2222 component is kept, the DN string is stripped. 2223 2224 The existing dn is modified 2225 */ 2226 bool ldb_dn_minimise(struct ldb_dn *dn); 2227 1931 2228 #endif -
vendor/current/source4/lib/ldb/include/ldb_errors.h
r414 r740 198 198 199 199 /** 200 The function referred to an alias which points to a non-exist ant200 The function referred to an alias which points to a non-existent 201 201 object in the database. 202 202 */ -
vendor/current/source4/lib/ldb/include/ldb_handlers.h
r414 r740 36 36 int ldb_comparison_binary( struct ldb_context *ldb, void *mem_ctx, 37 37 const struct ldb_val *v1, const struct ldb_val *v2); 38 int db_handler_fold( struct ldb_context *ldb, void *mem_ctx,39 const struct ldb_val *in, struct ldb_val *out);40 38 int ldb_comparison_fold( struct ldb_context *ldb, void *mem_ctx, 41 39 const struct ldb_val *v1, const struct ldb_val *v2); -
vendor/current/source4/lib/ldb/include/ldb_module.h
r414 r740 34 34 #define _LDB_MODULE_H_ 35 35 36 #include "ldb.h"36 #include <ldb.h> 37 37 38 38 struct ldb_context; 39 39 struct ldb_module; 40 41 /** 42 internal flag bits on message elements. Must be within LDB_FLAG_INTERNAL_MASK 43 */ 44 #define LDB_FLAG_INTERNAL_DISABLE_VALIDATION 0x10 45 46 /* disable any single value checking on this attribute */ 47 #define LDB_FLAG_INTERNAL_DISABLE_SINGLE_VALUE_CHECK 0x20 48 49 /* attribute has failed access check and must not be exposed */ 50 #define LDB_FLAG_INTERNAL_INACCESSIBLE_ATTRIBUTE 0x40 51 52 /* force single value checking on this attribute */ 53 #define LDB_FLAG_INTERNAL_FORCE_SINGLE_VALUE_CHECK 0x80 54 40 55 41 56 /* … … 68 83 void ldb_debug_end(struct ldb_context *ldb, enum ldb_debug_level level); 69 84 70 #define ldb_oom(ldb) ldb_debug_set(ldb, LDB_DEBUG_FATAL, "ldb out of memory at %s:%d\n", __FILE__, __LINE__) 85 #define ldb_error(ldb, ecode, reason) ldb_error_at(ldb, ecode, reason, __FILE__, __LINE__) 86 87 #define ldb_oom(ldb) ldb_error(ldb, LDB_ERR_OPERATIONS_ERROR, "ldb out of memory") 88 #define ldb_module_oom(module) ldb_oom(ldb_module_get_ctx(module)) 89 #define ldb_operr(ldb) ldb_error(ldb, LDB_ERR_OPERATIONS_ERROR, "operations error") 71 90 72 91 /* The following definitions come from lib/ldb/common/ldb.c */ … … 99 118 void *private_data); 100 119 120 /* A useful function to build comparison functions with */ 121 int ldb_any_comparison(struct ldb_context *ldb, void *mem_ctx, 122 ldb_attr_handler_t canonicalise_fn, 123 const struct ldb_val *v1, 124 const struct ldb_val *v2); 125 101 126 /* The following definitions come from lib/ldb/common/ldb_controls.c */ 102 struct ldb_control *get_control_from_list(struct ldb_control **controls, const char *oid); 103 int save_controls(struct ldb_control *exclude, struct ldb_request *req, struct ldb_control ***saver); 104 int check_critical_controls(struct ldb_control **controls); 127 int ldb_save_controls(struct ldb_control *exclude, struct ldb_request *req, struct ldb_control ***saver); 128 /* Returns a list of controls, except the one specified. Included 129 * controls become a child of returned list if they were children of 130 * controls_in */ 131 struct ldb_control **ldb_controls_except_specified(struct ldb_control **controls_in, 132 TALLOC_CTX *mem_ctx, 133 struct ldb_control *exclude); 134 int ldb_check_critical_controls(struct ldb_control **controls); 105 135 106 136 /* The following definitions come from lib/ldb/common/ldb_ldif.c */ … … 114 144 enum ldb_scope scope); 115 145 146 int ldb_match_msg_error(struct ldb_context *ldb, 147 const struct ldb_message *msg, 148 const struct ldb_parse_tree *tree, 149 struct ldb_dn *base, 150 enum ldb_scope scope, 151 bool *matched); 152 153 int ldb_match_msg_objectclass(const struct ldb_message *msg, 154 const char *objectclass); 155 116 156 /* The following definitions come from lib/ldb/common/ldb_modules.c */ 117 157 … … 125 165 void *ldb_module_get_private(struct ldb_module *module); 126 166 void ldb_module_set_private(struct ldb_module *module, void *private_data); 167 const struct ldb_module_ops *ldb_module_get_ops(struct ldb_module *module); 127 168 128 169 int ldb_next_request(struct ldb_module *module, struct ldb_request *request); … … 136 177 void ldb_asprintf_errstring(struct ldb_context *ldb, const char *format, ...) PRINTF_ATTRIBUTE(2,3); 137 178 void ldb_reset_err_string(struct ldb_context *ldb); 179 int ldb_error_at(struct ldb_context *ldb, int ecode, const char *reason, const char *file, int line); 138 180 139 181 const char *ldb_default_modules_dir(void); … … 152 194 const char *ldb_default_modules_dir(void); 153 195 154 int ldb_register_backend(const char *url_prefix, ldb_connect_fn );196 int ldb_register_backend(const char *url_prefix, ldb_connect_fn, bool); 155 197 156 198 struct ldb_handle *ldb_handle_new(TALLOC_CTX *mem_ctx, struct ldb_context *ldb); … … 171 213 172 214 void ldb_set_default_dns(struct ldb_context *ldb); 215 /** 216 Add a ldb_control to a ldb_reply 217 218 \param ares the reply struct where to add the control 219 \param oid the object identifier of the control as string 220 \param critical whether the control should be critical or not 221 \param data a talloc pointer to the control specific data 222 223 \return result code (LDB_SUCCESS on success, or a failure code) 224 */ 225 int ldb_reply_add_control(struct ldb_reply *ares, const char *oid, bool critical, void *data); 226 227 /** 228 mark a request as untrusted. This tells the rootdse module to remove 229 unregistered controls 230 */ 231 void ldb_req_mark_untrusted(struct ldb_request *req); 232 233 /** 234 mark a request as trusted. 235 */ 236 void ldb_req_mark_trusted(struct ldb_request *req); 237 238 /** 239 return true is a request is untrusted 240 */ 241 bool ldb_req_is_untrusted(struct ldb_request *req); 242 243 /* load all modules from the given directory */ 244 int ldb_modules_load(const char *modules_path, const char *version); 245 246 /* init functions prototype */ 247 typedef int (*ldb_module_init_fn)(const char *); 248 249 /* 250 general ldb hook function 251 */ 252 enum ldb_module_hook_type { LDB_MODULE_HOOK_CMDLINE_OPTIONS = 1, 253 LDB_MODULE_HOOK_CMDLINE_PRECONNECT = 2, 254 LDB_MODULE_HOOK_CMDLINE_POSTCONNECT = 3 }; 255 256 typedef int (*ldb_hook_fn)(struct ldb_context *, enum ldb_module_hook_type ); 257 258 /* 259 register a ldb hook function 260 */ 261 int ldb_register_hook(ldb_hook_fn hook_fn); 262 263 /* 264 call ldb hooks of a given type 265 */ 266 int ldb_modules_hook(struct ldb_context *ldb, enum ldb_module_hook_type t); 267 268 #define LDB_MODULE_CHECK_VERSION(version) do { \ 269 if (strcmp(version, LDB_VERSION) != 0) { \ 270 fprintf(stderr, "ldb: module version mismatch in %s : ldb_version=%s module_version=%s\n", \ 271 __FILE__, version, LDB_VERSION); \ 272 return LDB_ERR_UNAVAILABLE; \ 273 }} while (0) 274 275 276 /* 277 return a string representation of the calling chain for the given 278 ldb request 279 */ 280 char *ldb_module_call_chain(struct ldb_request *req, TALLOC_CTX *mem_ctx); 281 282 /* 283 return the next module in the chain 284 */ 285 struct ldb_module *ldb_module_next(struct ldb_module *module); 286 287 /* 288 set the next module in the module chain 289 */ 290 void ldb_module_set_next(struct ldb_module *module, struct ldb_module *next); 291 292 /* 293 load a list of modules 294 */ 295 int ldb_module_load_list(struct ldb_context *ldb, const char **module_list, 296 struct ldb_module *backend, struct ldb_module **out); 297 298 /* 299 get the popt_options pointer in the ldb structure. This allows a ldb 300 module to change the command line parsing 301 */ 302 struct poptOption **ldb_module_popt_options(struct ldb_context *ldb); 303 304 /* modules are called in inverse order on the stack. 305 Lets place them as an admin would think the right order is. 306 Modules order is important */ 307 const char **ldb_modules_list_from_string(struct ldb_context *ldb, TALLOC_CTX *mem_ctx, const char *string); 308 309 /* 310 return the current ldb flags LDB_FLG_* 311 */ 312 uint32_t ldb_module_flags(struct ldb_context *ldb); 313 314 int ldb_module_connect_backend(struct ldb_context *ldb, 315 const char *url, 316 const char *options[], 317 struct ldb_module **backend_module); 318 319 /* 320 initialise a chain of modules 321 */ 322 int ldb_module_init_chain(struct ldb_context *ldb, struct ldb_module *module); 323 324 /* 325 * prototype for the init function defined by dynamically loaded modules 326 */ 327 int ldb_init_module(const char *version); 328 173 329 174 330 #endif -
vendor/current/source4/lib/ldb/include/ldb_private.h
r414 r740 38 38 #define _LDB_PRIVATE_H_ 1 39 39 40 #include "ldb_includes.h" 40 #include "replace.h" 41 #include "system/filesys.h" 42 #include "system/time.h" 41 43 #include "ldb.h" 42 44 #include "ldb_module.h" … … 49 51 50 52 #define LDB_HANDLE_FLAG_DONE_CALLED 1 53 /* call is from an untrusted source - eg. over ldap:// */ 54 #define LDB_HANDLE_FLAG_UNTRUSTED 2 51 55 52 56 struct ldb_handle { … … 56 60 unsigned flags; 57 61 unsigned nesting; 62 63 /* used for debugging */ 64 struct ldb_request *parent; 65 const char *location; 58 66 }; 59 67 … … 113 121 unsigned int create_perms; 114 122 115 char *modules_dir;116 117 123 struct tevent_context *ev_ctx; 118 124 … … 120 126 121 127 char *partial_debug; 128 129 struct poptOption *popt_options; 122 130 }; 123 131 124 132 /* The following definitions come from lib/ldb/common/ldb.c */ 125 126 int ldb_connect_backend(struct ldb_context *ldb, const char *url, const char *options[],127 struct ldb_module **backend_module);128 129 133 130 134 extern const struct ldb_module_ops ldb_objectclass_module_ops; … … 158 162 159 163 /* The following definitions come from lib/ldb/common/ldb_utf8.c */ 160 char *ldb_casefold_default(void *context, void*mem_ctx, const char *s, size_t n);164 char *ldb_casefold_default(void *context, TALLOC_CTX *mem_ctx, const char *s, size_t n); 161 165 162 166 void ldb_dump_results(struct ldb_context *ldb, struct ldb_result *result, FILE *f); … … 166 170 167 171 const char **ldb_modules_list_from_string(struct ldb_context *ldb, TALLOC_CTX *mem_ctx, const char *string); 168 int ldb_load_modules_list(struct ldb_context *ldb, const char **module_list, struct ldb_module *backend, struct ldb_module **out);169 172 int ldb_load_modules(struct ldb_context *ldb, const char *options[]); 170 int ldb_init_module_chain(struct ldb_context *ldb, struct ldb_module *module);171 173 172 struct ldb_val ldb_binary_decode(void *mem_ctx, const char *str); 174 struct ldb_val ldb_binary_decode(TALLOC_CTX *mem_ctx, const char *str); 175 176 177 /* The following definitions come from lib/ldb/common/ldb_options.c */ 178 179 const char *ldb_options_find(struct ldb_context *ldb, const char *options[], 180 const char *option_name); 173 181 174 182 #endif -
vendor/current/source4/lib/ldb/ldb.pc.in
r414 r740 10 10 Requires.private: tdb 11 11 Requires: talloc 12 Libs: -L${libdir} -lldb12 Libs: @LIB_RPATH@ -L${libdir} -lldb 13 13 Libs.private: @LDAP_LIBS@ 14 14 Cflags: -I${includedir} -
vendor/current/source4/lib/ldb/ldb_ldap/ldb_ldap.c
r414 r740 34 34 * Modifications: 35 35 * 36 * - description: make the module use async ronous calls36 * - description: make the module use asynchronous calls 37 37 * date: Feb 2006 38 38 * author: Simo Sorce 39 39 */ 40 40 41 #include "ldb_includes.h" 41 #include "replace.h" 42 #include "system/filesys.h" 43 #include "system/time.h" 42 44 #include "ldb_module.h" 45 #include "ldb_private.h" 43 46 44 47 #define LDAP_DEPRECATED 1 … … 118 121 goto failed; 119 122 } 120 mods[num_mods]->mod_vals.modv_bvals[j]->bv_val = el->values[j].data;123 mods[num_mods]->mod_vals.modv_bvals[j]->bv_val = (char *)el->values[j].data; 121 124 mods[num_mods]->mod_vals.modv_bvals[j]->bv_len = el->values[j].length; 122 125 } … … 254 257 255 258 ret = ldap_search_ext(lldb->ldap, search_base, ldap_scope, 256 expression,257 discard_const_p(char *, req->op.search.attrs),258 0,259 NULL,260 NULL,261 &tv,262 LDAP_NO_LIMIT,263 &lldb_ac->msgid);259 expression, 260 discard_const_p(char *, req->op.search.attrs), 261 0, 262 NULL, 263 NULL, 264 &tv, 265 LDAP_NO_LIMIT, 266 &lldb_ac->msgid); 264 267 265 268 if (ret != LDAP_SUCCESS) { … … 283 286 int ret; 284 287 285 ldb _module_get_ctx(module);288 ldb = ldb_module_get_ctx(module); 286 289 287 290 ldb_request_set_state(req, LDB_ASYNC_PENDING); … … 322 325 int ret; 323 326 324 ldb _module_get_ctx(module);327 ldb = ldb_module_get_ctx(module); 325 328 326 329 ldb_request_set_state(req, LDB_ASYNC_PENDING); … … 360 363 int ret; 361 364 362 ldb _module_get_ctx(module);365 ldb = ldb_module_get_ctx(module); 363 366 364 367 ldb_request_set_state(req, LDB_ASYNC_PENDING); … … 387 390 struct ldb_module *module = lldb_ac->module; 388 391 struct ldb_request *req = lldb_ac->req; 392 const char *rdn_name; 393 const struct ldb_val *rdn_val; 389 394 char *old_dn; 390 395 char *newrdn; 391 396 char *parentdn; 392 397 int ret; 393 398 394 ldb _module_get_ctx(module);399 ldb = ldb_module_get_ctx(module); 395 400 396 401 ldb_request_set_state(req, LDB_ASYNC_PENDING); … … 401 406 } 402 407 403 newrdn = talloc_asprintf(lldb_ac, "%s=%s", 404 ldb_dn_get_rdn_name(req->op.rename.newdn), 405 ldb_dn_escape_value(lldb, *(ldb_dn_get_rdn_val(req->op.rename.newdn)))); 408 rdn_name = ldb_dn_get_rdn_name(req->op.rename.newdn); 409 rdn_val = ldb_dn_get_rdn_val(req->op.rename.newdn); 410 411 if ((rdn_name != NULL) && (rdn_val != NULL)) { 412 newrdn = talloc_asprintf(lldb_ac, "%s=%s", rdn_name, 413 rdn_val->length > 0 ? ldb_dn_escape_value(lldb, *rdn_val) : ""); 414 } else { 415 newrdn = talloc_strdup(lldb_ac, ""); 416 } 406 417 if (!newrdn) { 407 418 return LDB_ERR_OPERATIONS_ERROR; … … 445 456 } 446 457 447 void lldb_request_done(struct lldb_context *ac,458 static void lldb_request_done(struct lldb_context *ac, 448 459 struct ldb_control **ctrls, int error) 449 460 { … … 484 495 bool request_done; 485 496 bool lret; 497 unsigned int i; 486 498 int ret; 487 int i;488 499 489 500 ldb = ldb_module_get_ctx(ac->module); … … 503 514 ldbmsg = ldb_msg_new(ac); 504 515 if (!ldbmsg) { 516 ldb_oom(ldb); 505 517 ret = LDB_ERR_OPERATIONS_ERROR; 506 518 break; … … 509 521 dn = ldap_get_dn(lldb->ldap, msg); 510 522 if (!dn) { 523 ldb_oom(ldb); 511 524 talloc_free(ldbmsg); 512 525 ret = LDB_ERR_OPERATIONS_ERROR; … … 515 528 ldbmsg->dn = ldb_dn_new(ldbmsg, ldb, dn); 516 529 if ( ! ldb_dn_validate(ldbmsg->dn)) { 530 ldb_asprintf_errstring(ldb, "Invalid DN '%s' in reply", dn); 517 531 talloc_free(ldbmsg); 518 532 ret = LDB_ERR_OPERATIONS_ERROR; 533 ldap_memfree(dn); 519 534 break; 520 535 } … … 540 555 ret = ldb_module_send_entry(ac->req, ldbmsg, NULL /* controls not yet supported */); 541 556 if (ret != LDB_SUCCESS) { 542 557 ldb_asprintf_errstring(ldb, "entry send failed: %s", 558 ldb_errstring(ldb)); 543 559 callback_failed = true; 544 560 } … … 550 566 case LDAP_RES_SEARCH_REFERENCE: 551 567 552 if (ldap_parse_result(lldb->ldap, result, &ret, 553 &matcheddnp, &errmsgp, 554 &referralsp, &serverctrlsp, 0) != LDAP_SUCCESS) { 568 ret = ldap_parse_reference(lldb->ldap, result, 569 &referralsp, &serverctrlsp, 0); 570 if (ret != LDAP_SUCCESS) { 571 ldb_asprintf_errstring(ldb, "ldap reference parse error: %s : %s", 572 ldap_err2string(ret), errmsgp); 555 573 ret = LDB_ERR_OPERATIONS_ERROR; 556 }557 if (ret != LDB_SUCCESS) {558 574 break; 559 575 } 560 576 if (referralsp == NULL) { 577 ldb_asprintf_errstring(ldb, "empty ldap referrals list"); 561 578 ret = LDB_ERR_PROTOCOL_ERROR; 562 579 break; … … 568 585 ret = ldb_module_send_referral(ac->req, referral); 569 586 if (ret != LDB_SUCCESS) { 587 ldb_asprintf_errstring(ldb, "referral send failed: %s", 588 ldb_errstring(ldb)); 570 589 callback_failed = true; 571 590 break; … … 586 605 } 587 606 if (ret != LDB_SUCCESS) { 607 ldb_asprintf_errstring(ldb, "ldap parse error for type %d: %s : %s", 608 type, ldap_err2string(ret), errmsgp); 588 609 break; 589 610 } … … 598 619 599 620 default: 621 ldb_asprintf_errstring(ldb, "unknown ldap return type: %d", type); 600 622 ret = LDB_ERR_PROTOCOL_ERROR; 601 623 break; … … 799 821 default: 800 822 /* no other op supported */ 801 ret = LDB_ERR_ OPERATIONS_ERROR;823 ret = LDB_ERR_PROTOCOL_ERROR; 802 824 break; 803 825 } … … 846 868 } 847 869 870 871 /* 872 optionally perform a bind 873 */ 874 static int lldb_bind(struct ldb_module *module, 875 const char *options[]) 876 { 877 const char *bind_mechanism; 878 struct lldb_private *lldb; 879 struct ldb_context *ldb = ldb_module_get_ctx(module); 880 int ret; 881 882 bind_mechanism = ldb_options_find(ldb, options, "bindMech"); 883 if (bind_mechanism == NULL) { 884 /* no bind wanted */ 885 return LDB_SUCCESS; 886 } 887 888 lldb = talloc_get_type(ldb_module_get_private(module), struct lldb_private); 889 890 if (strcmp(bind_mechanism, "simple") == 0) { 891 const char *bind_id, *bind_secret; 892 893 bind_id = ldb_options_find(ldb, options, "bindID"); 894 bind_secret = ldb_options_find(ldb, options, "bindSecret"); 895 if (bind_id == NULL || bind_secret == NULL) { 896 ldb_asprintf_errstring(ldb, "simple bind requires bindID and bindSecret"); 897 return LDB_ERR_OPERATIONS_ERROR; 898 } 899 900 ret = ldap_simple_bind_s(lldb->ldap, bind_id, bind_secret); 901 if (ret != LDAP_SUCCESS) { 902 ldb_asprintf_errstring(ldb, "bind failed: %s", ldap_err2string(ret)); 903 return ret; 904 } 905 return LDB_SUCCESS; 906 } 907 908 ldb_asprintf_errstring(ldb, "bind failed: unknown mechanism %s", bind_mechanism); 909 return LDB_ERR_INAPPROPRIATE_AUTHENTICATION; 910 } 911 848 912 /* 849 913 connect to the database … … 861 925 862 926 module = ldb_module_new(ldb, ldb, "ldb_ldap backend", &lldb_ops); 863 if (!module) return -1;927 if (!module) return LDB_ERR_OPERATIONS_ERROR; 864 928 865 929 lldb = talloc_zero(module, struct lldb_private); … … 887 951 888 952 *_module = module; 889 return 0; 953 954 ret = lldb_bind(module, options); 955 if (ret != LDB_SUCCESS) { 956 goto failed; 957 } 958 959 960 return LDB_SUCCESS; 890 961 891 962 failed: 892 963 talloc_free(module); 893 return -1; 894 } 895 896 const struct ldb_backend_ops ldb_ldap_backend_ops = { 897 .name = "ldap", 898 .connect_fn = lldb_connect 899 }; 900 901 const struct ldb_backend_ops ldb_ldapi_backend_ops = { 902 .name = "ldapi", 903 .connect_fn = lldb_connect 904 }; 905 906 const struct ldb_backend_ops ldb_ldaps_backend_ops = { 907 .name = "ldaps", 908 .connect_fn = lldb_connect 909 }; 964 return LDB_ERR_OPERATIONS_ERROR; 965 } 966 967 /* 968 initialise the module 969 */ 970 int ldb_ldap_init(const char *version) 971 { 972 int ret, i; 973 const char *names[] = { "ldap", "ldaps", "ldapi", NULL }; 974 LDB_MODULE_CHECK_VERSION(version); 975 for (i=0; names[i]; i++) { 976 ret = ldb_register_backend(names[i], lldb_connect, false); 977 if (ret != LDB_SUCCESS) { 978 return ret; 979 } 980 } 981 return LDB_SUCCESS; 982 } -
vendor/current/source4/lib/ldb/ldb_map/ldb_map.c
r414 r740 36 36 */ 37 37 38 #include "ldb_includes.h" 38 #include "replace.h" 39 #include "system/filesys.h" 40 #include "system/time.h" 39 41 #include "ldb_map.h" 40 42 #include "ldb_map_private.h" … … 257 259 static const struct ldb_map_objectclass *map_objectclass_find_local(const struct ldb_map_context *data, const char *name) 258 260 { 259 int i;261 unsigned int i; 260 262 261 263 for (i = 0; data->objectclass_maps && data->objectclass_maps[i].local_name; i++) { … … 271 273 static const struct ldb_map_objectclass *map_objectclass_find_remote(const struct ldb_map_context *data, const char *name) 272 274 { 273 int i;275 unsigned int i; 274 276 275 277 for (i = 0; data->objectclass_maps && data->objectclass_maps[i].remote_name; i++) { … … 285 287 const struct ldb_map_attribute *map_attr_find_local(const struct ldb_map_context *data, const char *name) 286 288 { 287 int i;289 unsigned int i; 288 290 289 291 for (i = 0; data->attribute_maps[i].local_name; i++) { … … 306 308 const struct ldb_map_attribute *map; 307 309 const struct ldb_map_attribute *wildcard = NULL; 308 int i, j;310 unsigned int i, j; 309 311 310 312 for (i = 0; data->attribute_maps[i].local_name; i++) { … … 315 317 316 318 switch (map->type) { 317 case MAP_IGNORE:319 case LDB_MAP_IGNORE: 318 320 break; 319 321 320 case MAP_KEEP:322 case LDB_MAP_KEEP: 321 323 if (ldb_attr_cmp(map->local_name, name) == 0) { 322 324 return map; … … 324 326 break; 325 327 326 case MAP_RENAME:327 case MAP_CONVERT:328 case LDB_MAP_RENAME: 329 case LDB_MAP_CONVERT: 328 330 if (ldb_attr_cmp(map->u.rename.remote_name, name) == 0) { 329 331 return map; … … 331 333 break; 332 334 333 case MAP_GENERATE:335 case LDB_MAP_GENERATE: 334 336 for (j = 0; map->u.generate.remote_names && map->u.generate.remote_names[j]; j++) { 335 337 if (ldb_attr_cmp(map->u.generate.remote_names[j], name) == 0) { … … 357 359 return false; 358 360 } 359 if (map->type == MAP_IGNORE) {361 if (map->type == LDB_MAP_IGNORE) { 360 362 return false; 361 363 } … … 372 374 373 375 switch (map->type) { 374 case MAP_KEEP:376 case LDB_MAP_KEEP: 375 377 return talloc_strdup(mem_ctx, attr); 376 378 377 case MAP_RENAME:378 case MAP_CONVERT:379 case LDB_MAP_RENAME: 380 case LDB_MAP_CONVERT: 379 381 return talloc_strdup(mem_ctx, map->u.rename.remote_name); 380 382 … … 391 393 } 392 394 393 if (map->type == MAP_KEEP) {395 if (map->type == LDB_MAP_KEEP) { 394 396 return talloc_strdup(mem_ctx, attr); 395 397 } … … 403 405 const char ***attrs, const char * const *more_attrs) 404 406 { 405 int i, j, k;407 unsigned int i, j, k; 406 408 407 409 for (i = 0; *attrs && (*attrs)[i]; i++) /* noop */ ; … … 430 432 const struct ldb_map_attribute *map, const struct ldb_val *val) 431 433 { 432 if (map && (map->type == MAP_CONVERT) && (map->u.convert.convert_local)) {434 if (map && (map->type == LDB_MAP_CONVERT) && (map->u.convert.convert_local)) { 433 435 return map->u.convert.convert_local(module, mem_ctx, val); 434 436 } … … 441 443 const struct ldb_map_attribute *map, const struct ldb_val *val) 442 444 { 443 if (map && (map->type == MAP_CONVERT) && (map->u.convert.convert_remote)) {445 if (map && (map->type == LDB_MAP_CONVERT) && (map->u.convert.convert_remote)) { 444 446 return map->u.convert.convert_remote(module, mem_ctx, val); 445 447 } … … 494 496 /* Unknown attribute - leave this RDN as is and hope the best... */ 495 497 if (map == NULL) { 496 map_type = MAP_KEEP;498 map_type = LDB_MAP_KEEP; 497 499 } else { 498 500 map_type = map->type; … … 500 502 501 503 switch (map_type) { 502 case MAP_IGNORE:503 case MAP_GENERATE:504 case LDB_MAP_IGNORE: 505 case LDB_MAP_GENERATE: 504 506 ldb_debug(ldb, LDB_DEBUG_ERROR, "ldb_map: " 505 " MAP_IGNORE/MAP_GENERATE attribute '%s' "507 "LDB_MAP_IGNORE/LDB_MAP_GENERATE attribute '%s' " 506 508 "used in DN!", ldb_dn_get_component_name(dn, i)); 507 509 goto failed; 508 510 509 case MAP_CONVERT:511 case LDB_MAP_CONVERT: 510 512 if (map->u.convert.convert_local == NULL) { 511 513 ldb_debug(ldb, LDB_DEBUG_ERROR, "ldb_map: " … … 515 517 } 516 518 /* fall through */ 517 case MAP_KEEP:518 case MAP_RENAME:519 case LDB_MAP_KEEP: 520 case LDB_MAP_RENAME: 519 521 name = map_attr_map_local(newdn, map, ldb_dn_get_component_name(dn, i)); 520 522 if (name == NULL) goto failed; … … 569 571 /* Unknown attribute - leave this RDN as is and hope the best... */ 570 572 if (map == NULL) { 571 map_type = MAP_KEEP;573 map_type = LDB_MAP_KEEP; 572 574 } else { 573 575 map_type = map->type; … … 575 577 576 578 switch (map_type) { 577 case MAP_IGNORE:578 case MAP_GENERATE:579 case LDB_MAP_IGNORE: 580 case LDB_MAP_GENERATE: 579 581 ldb_debug(ldb, LDB_DEBUG_ERROR, "ldb_map: " 580 " MAP_IGNORE/MAP_GENERATE attribute '%s' "582 "LDB_MAP_IGNORE/LDB_MAP_GENERATE attribute '%s' " 581 583 "used in DN!", ldb_dn_get_component_name(dn, i)); 582 584 goto failed; 583 585 584 case MAP_CONVERT:586 case LDB_MAP_CONVERT: 585 587 if (map->u.convert.convert_remote == NULL) { 586 588 ldb_debug(ldb, LDB_DEBUG_ERROR, "ldb_map: " … … 590 592 } 591 593 /* fall through */ 592 case MAP_KEEP:593 case MAP_RENAME:594 case LDB_MAP_KEEP: 595 case LDB_MAP_RENAME: 594 596 name = map_attr_map_remote(newdn, map, ldb_dn_get_component_name(dn, i)); 595 597 if (name == NULL) goto failed; … … 715 717 struct ldb_val val; 716 718 bool found_extensibleObject = false; 717 int i;719 unsigned int i; 718 720 719 721 ldb = ldb_module_get_ctx(module); … … 790 792 struct ldb_message_element *el, *oc; 791 793 struct ldb_val val; 792 int i;794 unsigned int i; 793 795 794 796 ldb = ldb_module_get_ctx(module); … … 843 845 static const struct ldb_map_attribute objectclass_convert_map = { 844 846 .local_name = "objectClass", 845 .type = MAP_CONVERT,847 .type = LDB_MAP_CONVERT, 846 848 .u = { 847 849 .convert = { … … 892 894 context, callback, 893 895 ac->req); 896 LDB_REQ_SET_LOCATION(req); 894 897 if (ret != LDB_SUCCESS) { 895 898 return NULL; … … 939 942 context, callback, 940 943 ac->req); 944 LDB_REQ_SET_LOCATION(req); 941 945 if (ret != LDB_SUCCESS) { 942 946 goto failed; … … 958 962 { 959 963 .local_name = "dn", 960 .type = MAP_CONVERT,964 .type = LDB_MAP_CONVERT, 961 965 .u = { 962 966 .convert = { … … 974 978 static const struct ldb_map_attribute objectclass_attribute_map = { 975 979 .local_name = "objectClass", 976 .type = MAP_GENERATE,980 .type = LDB_MAP_GENERATE, 977 981 .convert_operator = map_objectclass_convert_operator, 978 982 .u = { … … 1044 1048 const char * const *wildcard_attributes) 1045 1049 { 1046 int i, j, last;1050 unsigned int i, j, last; 1047 1051 last = 0; 1048 1052 -
vendor/current/source4/lib/ldb/ldb_map/ldb_map.h
r414 r740 60 60 61 61 enum ldb_map_attr_type { 62 MAP_IGNORE, /* Ignore this local attribute. Doesn't exist remotely. */63 MAP_KEEP, /* Keep as is. Same name locally and remotely. */64 MAP_RENAME, /* Simply rename the attribute. Name changes, data is the same */65 MAP_CONVERT, /* Rename + convert data */66 MAP_GENERATE /* Use generate function for generating new name/data.62 LDB_MAP_IGNORE, /* Ignore this local attribute. Doesn't exist remotely. */ 63 LDB_MAP_KEEP, /* Keep as is. Same name locally and remotely. */ 64 LDB_MAP_RENAME, /* Simply rename the attribute. Name changes, data is the same */ 65 LDB_MAP_CONVERT, /* Rename + convert data */ 66 LDB_MAP_GENERATE /* Use generate function for generating new name/data. 67 67 Used for generating attributes based on 68 68 multiple remote attributes. */ … … 158 158 const char *name); 159 159 160 int map_add(struct ldb_module *module, struct ldb_request *req);161 int map_search(struct ldb_module *module, struct ldb_request *req);162 int map_rename(struct ldb_module *module, struct ldb_request *req);163 int map_delete(struct ldb_module *module, struct ldb_request *req);164 int map_modify(struct ldb_module *module, struct ldb_request *req);160 int ldb_map_add(struct ldb_module *module, struct ldb_request *req); 161 int ldb_map_search(struct ldb_module *module, struct ldb_request *req); 162 int ldb_map_rename(struct ldb_module *module, struct ldb_request *req); 163 int ldb_map_delete(struct ldb_module *module, struct ldb_request *req); 164 int ldb_map_modify(struct ldb_module *module, struct ldb_request *req); 165 165 166 166 #define LDB_MAP_OPS \ 167 .add = map_add, \168 .modify = map_modify, \169 .del = map_delete, \170 .rename = map_rename, \171 .search = map_search,167 .add = ldb_map_add, \ 168 .modify = ldb_map_modify, \ 169 .del = ldb_map_delete, \ 170 .rename = ldb_map_rename, \ 171 .search = ldb_map_search, 172 172 173 173 #endif /* __LDB_MAP_H__ */ -
vendor/current/source4/lib/ldb/ldb_map/ldb_map_inbound.c
r414 r740 25 25 */ 26 26 27 #include "ldb_includes.h" 27 #include "replace.h" 28 #include "system/filesys.h" 29 #include "system/time.h" 28 30 #include "ldb_map.h" 29 31 #include "ldb_map_private.h" … … 37 39 { 38 40 struct ldb_message_element *el; 39 int i;41 unsigned int i; 40 42 41 43 el = talloc_zero(mem_ctx, struct ldb_message_element); … … 80 82 81 83 switch (map->type) { 82 case MAP_IGNORE:84 case LDB_MAP_IGNORE: 83 85 goto local; 84 86 85 case MAP_CONVERT:87 case LDB_MAP_CONVERT: 86 88 if (map->u.convert.convert_local == NULL) { 87 89 ldb_debug(ldb, LDB_DEBUG_WARNING, "ldb_map: " … … 92 94 } 93 95 /* fall through */ 94 case MAP_KEEP:95 case MAP_RENAME:96 case LDB_MAP_KEEP: 97 case LDB_MAP_RENAME: 96 98 el = ldb_msg_el_map_local(module, remote, map, old); 97 99 break; 98 100 99 case MAP_GENERATE:101 case LDB_MAP_GENERATE: 100 102 if (map->u.generate.generate_remote == NULL) { 101 103 ldb_debug(ldb, LDB_DEBUG_WARNING, "ldb_map: " … … 142 144 const struct ldb_map_context *data = map_get_context(module); 143 145 bool ret; 144 int i;146 unsigned int i; 145 147 146 148 for (i = 0; i < msg->num_elements; i++) { … … 160 162 /* const char * const names[]; */ 161 163 struct ldb_context *ldb; 162 int i, ret; 164 unsigned int i; 165 int ret; 163 166 164 167 ldb = ldb_module_get_ctx(module); … … 357 360 358 361 /* Add a record. */ 359 int map_add(struct ldb_module *module, struct ldb_request *req)362 int ldb_map_add(struct ldb_module *module, struct ldb_request *req) 360 363 { 361 364 const struct ldb_message *msg = req->op.add.message; … … 363 366 struct map_context *ac; 364 367 struct ldb_message *remote_msg; 365 const char *dn;366 368 int ret; 367 369 … … 415 417 ac, map_op_remote_callback, 416 418 req); 419 LDB_REQ_SET_LOCATION(ac->remote_req); 417 420 if (ret != LDB_SUCCESS) { 418 421 return LDB_ERR_OPERATIONS_ERROR; … … 427 430 /* Store remote DN in 'IS_MAPPED' */ 428 431 /* TODO: use GUIDs here instead */ 429 dn = ldb_dn_alloc_linearized(ac->local_msg, remote_msg->dn); 430 if (ldb_msg_add_string(ac->local_msg, IS_MAPPED, dn) != 0) { 432 ret = ldb_msg_add_linearized_dn(ac->local_msg, IS_MAPPED, 433 remote_msg->dn); 434 if (ret != LDB_SUCCESS) { 431 435 return LDB_ERR_OPERATIONS_ERROR; 432 436 } … … 451 455 map_op_local_callback, 452 456 ac->req); 457 LDB_REQ_SET_LOCATION(local_req); 453 458 if (ret != LDB_SUCCESS) { 454 459 return LDB_ERR_OPERATIONS_ERROR; … … 462 467 463 468 /* Modify a record. */ 464 int map_modify(struct ldb_module *module, struct ldb_request *req)469 int ldb_map_modify(struct ldb_module *module, struct ldb_request *req) 465 470 { 466 471 const struct ldb_message *msg = req->op.mod.message; … … 522 527 ac, map_op_remote_callback, 523 528 req); 529 LDB_REQ_SET_LOCATION(ac->remote_req); 524 530 if (ret != LDB_SUCCESS) { 525 531 return LDB_ERR_OPERATIONS_ERROR; … … 546 552 struct ldb_request *local_req; 547 553 struct ldb_context *ldb; 548 char *dn;549 554 int ret; 550 555 … … 559 564 return LDB_ERR_OPERATIONS_ERROR; 560 565 } 561 dn = ldb_dn_alloc_linearized(ac->local_msg,562 ac->remote_req->op.mod.message->dn);563 if ( ldb_msg_add_string(ac->local_msg, IS_MAPPED, dn)!= 0) {566 ret = ldb_msg_add_linearized_dn(ac->local_msg, IS_MAPPED, 567 ac->remote_req->op.mod.message->dn); 568 if (ret != 0) { 564 569 return LDB_ERR_OPERATIONS_ERROR; 565 570 } … … 572 577 map_op_local_callback, 573 578 ac->req); 579 LDB_REQ_SET_LOCATION(local_req); 574 580 if (ret != LDB_SUCCESS) { 575 581 return LDB_ERR_OPERATIONS_ERROR; … … 583 589 map_op_local_callback, 584 590 ac->req); 591 LDB_REQ_SET_LOCATION(local_req); 585 592 if (ret != LDB_SUCCESS) { 586 593 return LDB_ERR_OPERATIONS_ERROR; … … 596 603 597 604 /* Delete a record. */ 598 int map_delete(struct ldb_module *module, struct ldb_request *req)605 int ldb_map_delete(struct ldb_module *module, struct ldb_request *req) 599 606 { 600 607 struct ldb_request *search_req; … … 629 636 map_op_remote_callback, 630 637 req); 638 LDB_REQ_SET_LOCATION(ac->remote_req); 631 639 if (ret != LDB_SUCCESS) { 632 640 return LDB_ERR_OPERATIONS_ERROR; … … 671 679 map_op_local_callback, 672 680 ac->req); 681 LDB_REQ_SET_LOCATION(local_req); 673 682 if (ret != LDB_SUCCESS) { 674 683 return LDB_ERR_OPERATIONS_ERROR; … … 682 691 683 692 /* Rename a record. */ 684 int map_rename(struct ldb_module *module, struct ldb_request *req)693 int ldb_map_rename(struct ldb_module *module, struct ldb_request *req) 685 694 { 686 695 struct ldb_request *search_req; … … 722 731 ac, map_op_remote_callback, 723 732 req); 733 LDB_REQ_SET_LOCATION(ac->remote_req); 724 734 if (ret != LDB_SUCCESS) { 725 735 return LDB_ERR_OPERATIONS_ERROR; … … 765 775 map_rename_local_callback, 766 776 ac->req); 777 LDB_REQ_SET_LOCATION(local_req); 767 778 if (ret != LDB_SUCCESS) { 768 779 return LDB_ERR_OPERATIONS_ERROR; -
vendor/current/source4/lib/ldb/ldb_map/ldb_map_outbound.c
r414 r740 26 26 */ 27 27 28 #include "ldb_includes.h" 28 #include "replace.h" 29 #include "system/filesys.h" 30 #include "system/time.h" 29 31 #include "ldb_map.h" 30 32 #include "ldb_map_private.h" … … 39 41 const struct ldb_map_context *data = map_get_context(module); 40 42 const char **result; 41 int i, last;43 unsigned int i, last; 42 44 43 45 if (attrs == NULL) … … 82 84 const struct ldb_map_attribute *map; 83 85 const char *name=NULL; 84 int i, j, last;86 unsigned int i, j, last; 85 87 int ret; 86 88 … … 125 127 126 128 switch (map->type) { 127 case MAP_IGNORE:129 case LDB_MAP_IGNORE: 128 130 continue; 129 131 130 case MAP_KEEP:132 case LDB_MAP_KEEP: 131 133 name = attrs[i]; 132 134 goto named; 133 135 134 case MAP_RENAME:135 case MAP_CONVERT:136 case LDB_MAP_RENAME: 137 case LDB_MAP_CONVERT: 136 138 name = map->u.rename.remote_name; 137 139 goto named; 138 140 139 case MAP_GENERATE:141 case LDB_MAP_GENERATE: 140 142 /* Add all remote names of "generate" attrs */ 141 143 for (j = 0; map->u.generate.remote_names[j]; j++) { … … 220 222 const struct ldb_message_element *old) 221 223 { 224 const struct ldb_map_context *data = map_get_context(module); 225 const char *local_attr_name = attr_name; 222 226 struct ldb_message_element *el; 223 int i;227 unsigned int i; 224 228 225 229 el = talloc_zero(mem_ctx, struct ldb_message_element); … … 236 240 } 237 241 238 el->name = talloc_strdup(el, attr_name); 242 for (i = 0; data->attribute_maps[i].local_name; i++) { 243 struct ldb_map_attribute *am = &data->attribute_maps[i]; 244 if ((am->type == LDB_MAP_RENAME && 245 !strcmp(am->u.rename.remote_name, attr_name)) 246 || (am->type == LDB_MAP_CONVERT && 247 !strcmp(am->u.convert.remote_name, attr_name))) { 248 249 local_attr_name = am->local_name; 250 break; 251 } 252 } 253 254 el->name = talloc_strdup(el, local_attr_name); 239 255 if (el->name == NULL) { 240 256 talloc_free(el); … … 282 298 283 299 switch (map->type) { 284 case MAP_IGNORE:285 break; 286 case MAP_CONVERT:300 case LDB_MAP_IGNORE: 301 break; 302 case LDB_MAP_CONVERT: 287 303 remote_name = map->u.convert.remote_name; 288 304 break; 289 case MAP_KEEP:305 case LDB_MAP_KEEP: 290 306 remote_name = attr_name; 291 307 break; 292 case MAP_RENAME:308 case LDB_MAP_RENAME: 293 309 remote_name = map->u.rename.remote_name; 294 310 break; 295 case MAP_GENERATE:311 case LDB_MAP_GENERATE: 296 312 break; 297 313 } 298 314 299 315 switch (map->type) { 300 case MAP_IGNORE:316 case LDB_MAP_IGNORE: 301 317 return LDB_SUCCESS; 302 318 303 case MAP_CONVERT:319 case LDB_MAP_CONVERT: 304 320 if (map->u.convert.convert_remote == NULL) { 305 321 ldb_debug(ldb, LDB_DEBUG_ERROR, "ldb_map: " … … 310 326 } 311 327 /* fall through */ 312 case MAP_KEEP:313 case MAP_RENAME:328 case LDB_MAP_KEEP: 329 case LDB_MAP_RENAME: 314 330 old = ldb_msg_find_element(remote, remote_name); 315 331 if (old) { … … 320 336 break; 321 337 322 case MAP_GENERATE:338 case LDB_MAP_GENERATE: 323 339 if (map->u.generate.generate_local == NULL) { 324 340 ldb_debug(ldb, LDB_DEBUG_ERROR, "ldb_map: " … … 351 367 const struct ldb_map_attribute *map = map_attr_find_local(data, "*"); 352 368 struct ldb_message_element *el=NULL; 353 int i, ret; 369 unsigned int i; 370 int ret; 354 371 355 372 /* Perhaps we have a mapping for "*" */ 356 if (map && map->type == MAP_KEEP) {373 if (map && map->type == LDB_MAP_KEEP) { 357 374 /* We copy everything over, and hope that anything with a 358 375 more specific rule is overwritten */ … … 393 410 static int ldb_msg_merge_local(struct ldb_module *module, struct ldb_message *msg1, struct ldb_message *msg2) 394 411 { 395 int i, ret; 412 unsigned int i; 413 int ret; 396 414 397 415 for (i = 0; i < msg2->num_elements; i++) { … … 409 427 struct ldb_message *remote) 410 428 { 411 int i, ret; 429 unsigned int i; 430 int ret; 412 431 const char * const *attrs = ac->all_attrs; 413 432 if (!attrs) { … … 521 540 { 522 541 const char **new_attrs; 523 int i, ret; 542 unsigned int i; 543 int ret; 524 544 525 545 if (tree == NULL) { … … 548 568 return 0; 549 569 } 550 551 return -1;552 570 } 553 571 … … 589 607 static int map_subtree_select_local_list(struct ldb_module *module, void *mem_ctx, struct ldb_parse_tree **new, const struct ldb_parse_tree *tree) 590 608 { 591 int i, j, ret=0; 609 unsigned int i, j; 610 int ret=0; 592 611 593 612 /* Prepare new tree */ … … 712 731 static int map_subtree_collect_remote_list(struct ldb_module *module, void *mem_ctx, struct ldb_parse_tree **new, const struct ldb_parse_tree *tree) 713 732 { 714 int i, j, ret=0; 733 unsigned int i, j; 734 int ret=0; 715 735 716 736 /* Prepare new tree */ … … 773 793 **new = *tree; 774 794 775 if (map->type == MAP_KEEP) {795 if (map->type == LDB_MAP_KEEP) { 776 796 /* Nothing to do here */ 777 797 return 0; … … 815 835 } 816 836 817 if (map->type == MAP_RENAME) {837 if (map->type == LDB_MAP_RENAME) { 818 838 /* Nothing more to do here, the attribute has been renamed */ 819 839 return 0; … … 898 918 } 899 919 900 if (map->type == MAP_GENERATE) {920 if (map->type == LDB_MAP_GENERATE) { 901 921 ldb_debug(ldb, LDB_DEBUG_WARNING, "ldb_map: " 902 922 "Skipping attribute '%s': " … … 1052 1072 const char * const *attrs; 1053 1073 struct ldb_context *ldb; 1054 int i; 1074 unsigned int i; 1075 int ret; 1076 bool matched; 1055 1077 1056 1078 ldb = ldb_module_get_ctx(ac->module); 1057 1079 1058 1080 /* Merged result doesn't match original query, skip */ 1059 if (!ldb_match_msg(ldb, ares->message, 1060 ac->req->op.search.tree, 1061 ac->req->op.search.base, 1062 ac->req->op.search.scope)) { 1081 ret = ldb_match_msg_error(ldb, ares->message, 1082 ac->req->op.search.tree, 1083 ac->req->op.search.base, 1084 ac->req->op.search.scope, 1085 &matched); 1086 if (ret != LDB_SUCCESS) return ret; 1087 if (!matched) { 1063 1088 ldb_debug(ldb, LDB_DEBUG_TRACE, "ldb_map: " 1064 1089 "Skipping record '%s': " … … 1090 1115 1091 1116 /* Search a record. */ 1092 int map_search(struct ldb_module *module, struct ldb_request *req)1117 int ldb_map_search(struct ldb_module *module, struct ldb_request *req) 1093 1118 { 1094 1119 struct ldb_parse_tree *remote_tree; … … 1186 1211 ac, map_remote_search_callback, 1187 1212 req); 1213 LDB_REQ_SET_LOCATION(remote_req); 1188 1214 if (ret != LDB_SUCCESS) { 1189 1215 return LDB_ERR_OPERATIONS_ERROR; … … 1262 1288 } 1263 1289 1264 talloc_free(ares);1290 ac->remote_done_ares = talloc_steal(ac, ares); 1265 1291 1266 1292 ret = map_search_local(ac); … … 1334 1360 1335 1361 case LDB_REPLY_DONE: 1362 /* We don't need the local 'ares', but we will use the remote one from below */ 1336 1363 talloc_free(ares); 1337 1364 … … 1372 1399 * finish operations for this module */ 1373 1400 return ldb_module_done(ac->req, 1374 ac->r _current->remote->controls,1375 ac->r _current->remote->response,1376 ac->r _current->remote->error);1401 ac->remote_done_ares->controls, 1402 ac->remote_done_ares->response, 1403 ac->remote_done_ares->error); 1377 1404 } 1378 1405 -
vendor/current/source4/lib/ldb/ldb_map/ldb_map_private.h
r414 r740 1 #include "ldb_includes.h" 1 #include "replace.h" 2 #include "system/filesys.h" 3 #include "system/time.h" 2 4 3 5 /* A handy macro to report Out of Memory conditions */ … … 38 40 struct map_reply *r_list; 39 41 struct map_reply *r_current; 42 43 /* The response continaing any controls the remote server gave */ 44 struct ldb_reply *remote_done_ares; 40 45 }; 41 46 -
vendor/current/source4/lib/ldb/ldb_sqlite3/ldb_sqlite3.c
r414 r740 256 256 char *ret = NULL; 257 257 char *attr; 258 int i;258 unsigned int i; 259 259 260 260 ldb = ldb_module_get_ctx(module); … … 558 558 559 559 /* 560 * This is a bad hack to support ldap style comparisons w hithin sqlite.560 * This is a bad hack to support ldap style comparisons within sqlite. 561 561 * val is the attribute in the row currently under test 562 562 * func is the desired test "<=" ">=" "~" ":" … … 668 668 struct ldb_message *msg; 669 669 long long eid; 670 int i, ret; 670 unsigned int i; 671 int ret; 671 672 672 673 ac = talloc_get_type(result, struct lsql_context); … … 687 688 * except the first time */ 688 689 if (ac->current_eid != 0) { 689 msg = ldb_msg_canonicalize(ldb, msg); 690 if (!msg) return SQLITE_ABORT; 690 ret = ldb_msg_normalize(ldb, ac->req, msg, &msg); 691 if (ret != LDB_SUCCESS) { 692 return SQLITE_ABORT; 693 } 691 694 692 695 ret = ldb_module_send_entry(ac->req, msg, NULL); 693 696 if (ret != LDB_SUCCESS) { 694 697 ac->callback_failed = true; 698 /* free msg object */ 699 TALLOC_FREE(msg); 695 700 return SQLITE_ABORT; 696 701 } 702 703 /* free msg object */ 704 TALLOC_FREE(msg); 697 705 } 698 706 … … 960 968 /* complete the last message if any */ 961 969 if (ctx->ares) { 962 ctx->ares->message = ldb_msg_canonicalize(ldb, ctx->ares->message); 963 if (ctx->ares->message == NULL) { 970 ret = ldb_msg_normalize(ldb, ctx->ares, 971 ctx->ares->message, 972 &ctx->ares->message); 973 if (ret != LDB_SUCCESS) { 964 974 return LDB_ERR_OPERATIONS_ERROR; 965 975 } … … 987 997 char *errmsg; 988 998 char *query; 989 int i;999 unsigned int i; 990 1000 int ret; 991 1001 … … 1044 1054 const struct ldb_schema_attribute *a; 1045 1055 char *attr; 1046 int j;1056 unsigned int j; 1047 1057 1048 1058 /* Get a case-folded copy of the attribute name */ … … 1053 1063 1054 1064 a = ldb_schema_attribute_by_name(ldb, el->name); 1065 1066 if (el->num_value == 0) { 1067 ldb_asprintf_errstring(ldb, "attribute %s on %s specified, but with 0 values (illegal)", 1068 el->name, ldb_dn_get_linearized(msg->dn)); 1069 return LDB_ERR_CONSTRAINT_VIOLATION; 1070 } 1055 1071 1056 1072 /* For each value of the specified attribute name... */ … … 1098 1114 struct ldb_context *ldb; 1099 1115 struct ldb_message *msg = req->op.mod.message; 1100 1116 long long eid; 1101 1117 char *errmsg; 1102 int i;1118 unsigned int i; 1103 1119 int ret; 1104 1120 … … 1124 1140 char *attr; 1125 1141 char *mod; 1126 int j;1142 unsigned int j; 1127 1143 1128 1144 /* Get a case-folded copy of the attribute name */ … … 1137 1153 1138 1154 case LDB_FLAG_MOD_REPLACE: 1155 1156 for (j=0; j<el->num_values; j++) { 1157 if (ldb_msg_find_val(el, &el->values[j]) != &el->values[j]) { 1158 ldb_asprintf_errstring(ldb, "%s: value #%d provided more than once", el->name, j); 1159 return LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS; 1160 } 1161 } 1139 1162 1140 1163 /* remove all attributes before adding the replacements */ … … 1160 1183 1161 1184 case LDB_FLAG_MOD_ADD: 1162 #warning "We should throw an error if no value is provided!" 1185 1186 if (el->num_values == 0) { 1187 ldb_asprintf_errstring(ldb, "attribute %s on %s specified, but with 0 values (illigal)", 1188 el->name, ldb_dn_get_linearized(msg->dn)); 1189 return LDB_ERR_CONSTRAINT_VIOLATION; 1190 } 1191 1163 1192 /* For each value of the specified attribute name... */ 1164 1193 for (j = 0; j < el->num_values; j++) { … … 1492 1521 default: 1493 1522 /* no other op supported */ 1494 ret = LDB_ERR_ UNWILLING_TO_PERFORM;1523 ret = LDB_ERR_PROTOCOL_ERROR; 1495 1524 } 1496 1525 … … 1510 1539 struct timeval tv; 1511 1540 1512 if ( check_critical_controls(req->controls)) {1541 if (ldb_check_critical_controls(req->controls)) { 1513 1542 return LDB_ERR_UNSUPPORTED_CRITICAL_EXTENSION; 1514 1543 } … … 1846 1875 struct ldb_module *module; 1847 1876 struct lsqlite3_private *lsqlite3; 1848 int i, ret; 1877 unsigned int i; 1878 int ret; 1849 1879 1850 1880 module = ldb_module_new(ldb, ldb, "ldb_sqlite3 backend", &lsqlite3_ops); 1851 if (!module) return -1;1881 if (!module) return LDB_ERR_OPERATIONS_ERROR; 1852 1882 1853 1883 lsqlite3 = talloc(module, struct lsqlite3_private); … … 1893 1923 1894 1924 *_module = module; 1895 return 0;1925 return LDB_SUCCESS; 1896 1926 1897 1927 failed: … … 1900 1930 } 1901 1931 talloc_free(lsqlite3); 1902 return -1; 1903 } 1904 1905 const struct ldb_backend_ops ldb_sqlite3_backend_ops = { 1906 .name = "sqlite3", 1907 .connect_fn = lsqlite3_connect 1908 }; 1932 return LDB_ERR_OPERATIONS_ERROR; 1933 } 1934 1935 int ldb_sqlite3_init(const char *version) 1936 { 1937 LDB_MODULE_CHECK_VERSION(version); 1938 return ldb_register_backend("sqlite3", lsqlite3_connect, false); 1939 } -
vendor/current/source4/lib/ldb/ldb_tdb/ldb_cache.c
r414 r740 61 61 struct ltdb_private *ltdb = talloc_get_type(data, struct ltdb_private); 62 62 struct ldb_message *msg; 63 int i;63 unsigned int i; 64 64 65 65 ldb = ldb_module_get_ctx(module); … … 84 84 static int ltdb_attributes_flags(struct ldb_message_element *el, unsigned *v) 85 85 { 86 int i;86 unsigned int i; 87 87 unsigned value = 0; 88 88 for (i=0;i<el->num_values;i++) { 89 int j;89 unsigned int j; 90 90 for (j=0;ltdb_valid_attr_flags[j].name;j++) { 91 91 if (strcmp(ltdb_valid_attr_flags[j].name, … … 113 113 struct ldb_message *msg = ltdb->cache->attributes; 114 114 struct ldb_dn *dn; 115 int i, r; 115 unsigned int i; 116 int r; 116 117 117 118 ldb = ldb_module_get_ctx(module); … … 120 121 /* we skip loading the @ATTRIBUTES record when a module is supplying 121 122 its own attribute handling */ 122 return LDB_SUCCESS;123 return 0; 123 124 } 124 125 … … 203 204 ltdb->sequence_number = atof(initial_sequence_number); 204 205 205 msg = talloc(ltdb, struct ldb_message);206 msg = ldb_msg_new(ltdb); 206 207 if (msg == NULL) { 207 208 goto failed; … … 287 288 ltdb->cache = talloc_zero(ltdb, struct ltdb_cache); 288 289 if (ltdb->cache == NULL) goto failed; 289 ltdb->cache->indexlist = talloc_zero(ltdb->cache, struct ldb_message);290 ltdb->cache->attributes = talloc_zero(ltdb->cache, struct ldb_message);290 ltdb->cache->indexlist = ldb_msg_new(ltdb->cache); 291 ltdb->cache->attributes = ldb_msg_new(ltdb->cache); 291 292 if (ltdb->cache->indexlist == NULL || 292 293 ltdb->cache->attributes == NULL) { … … 295 296 } 296 297 297 baseinfo = talloc(ltdb->cache, struct ldb_message);298 baseinfo = ldb_msg_new(ltdb->cache); 298 299 if (baseinfo == NULL) goto failed; 299 300 300 baseinfo_dn = ldb_dn_new( module, ldb, LTDB_BASEINFO);301 baseinfo_dn = ldb_dn_new(baseinfo, ldb, LTDB_BASEINFO); 301 302 if (baseinfo_dn == NULL) goto failed; 302 303 … … 327 328 328 329 /* Read an interpret database options */ 329 options = talloc(ltdb->cache, struct ldb_message);330 options = ldb_msg_new(ltdb->cache); 330 331 if (options == NULL) goto failed; 331 332 … … 348 349 memset(<db->cache->last_attribute, 0, sizeof(ltdb->cache->last_attribute)); 349 350 350 ltdb_attributes_unload(module);351 352 351 talloc_free(ltdb->cache->indexlist); 353 354 ltdb->cache->indexlist = talloc_zero(ltdb->cache, struct ldb_message); 355 ltdb->cache->attributes = talloc_zero(ltdb->cache, struct ldb_message); 352 ltdb_attributes_unload(module); /* calls internally "talloc_free" */ 353 354 ltdb->cache->indexlist = ldb_msg_new(ltdb->cache); 355 ltdb->cache->attributes = ldb_msg_new(ltdb->cache); 356 356 if (ltdb->cache->indexlist == NULL || 357 357 ltdb->cache->attributes == NULL) { 358 358 goto failed; 359 359 } 360 ltdb->cache->one_level_indexes = false; 361 ltdb->cache->attribute_indexes = false; 360 362 361 363 indexlist_dn = ldb_dn_new(module, ldb, LTDB_INDEXLIST); … … 367 369 } 368 370 371 if (ldb_msg_find_element(ltdb->cache->indexlist, LTDB_IDXONE) != NULL) { 372 ltdb->cache->one_level_indexes = true; 373 } 374 if (ldb_msg_find_element(ltdb->cache->indexlist, LTDB_IDXATTR) != NULL) { 375 ltdb->cache->attribute_indexes = true; 376 } 377 369 378 if (ltdb_attributes_load(module) == -1) { 370 379 goto failed; … … 374 383 talloc_free(options); 375 384 talloc_free(baseinfo); 376 talloc_free(baseinfo_dn);377 385 talloc_free(indexlist_dn); 378 386 return 0; … … 381 389 talloc_free(options); 382 390 talloc_free(baseinfo); 383 talloc_free(baseinfo_dn);384 391 talloc_free(indexlist_dn); 385 392 return -1; … … 405 412 ldb = ldb_module_get_ctx(module); 406 413 407 msg = talloc(ltdb, struct ldb_message);414 msg = ldb_msg_new(ltdb); 408 415 if (msg == NULL) { 409 416 errno = ENOMEM; … … 413 420 s = talloc_asprintf(msg, "%llu", ltdb->sequence_number+1); 414 421 if (!s) { 422 talloc_free(msg); 415 423 errno = ENOMEM; 416 424 return LDB_ERR_OPERATIONS_ERROR; … … 449 457 s = ldb_timestring(msg, t); 450 458 if (s == NULL) { 459 talloc_free(msg); 451 460 return LDB_ERR_OPERATIONS_ERROR; 452 461 } … … 455 464 val_time.length = strlen(s); 456 465 457 ret = ltdb_modify_internal(module, msg );466 ret = ltdb_modify_internal(module, msg, NULL); 458 467 459 468 talloc_free(msg); … … 472 481 int ltdb_check_at_attributes_values(const struct ldb_val *value) 473 482 { 474 int i;483 unsigned int i; 475 484 476 485 for (i = 0; ltdb_valid_attr_flags[i].name != NULL; i++) { -
vendor/current/source4/lib/ldb/ldb_tdb/ldb_index.c
r414 r740 2 2 ldb database library 3 3 4 Copyright (C) Andrew Tridgell 2004 4 Copyright (C) Andrew Tridgell 2004-2009 5 5 6 6 ** NOTE! The following LGPL license applies to the ldb … … 33 33 34 34 #include "ldb_tdb.h" 35 #include "dlinklist.h" 36 37 /* 38 the idxptr code is a bit unusual. The way it works is to replace 39 @IDX elements in records during a transaction with @IDXPTR 40 elements. The @IDXPTR elements don't contain the actual index entry 41 values, but contain a pointer to a linked list of values. 42 43 This means we are storing pointers in a database, which is normally 44 not allowed, but in this case we are storing them only for the 45 duration of a transaction, and re-writing them into the normal @IDX 46 format at the end of the transaction. That means no other processes 47 are ever exposed to the @IDXPTR values. 48 49 The advantage is that the linked list doesn't cause huge 50 fragmentation during a transaction. Without the @IDXPTR method we 51 often ended up with a ldb that was between 10x and 100x larger then 52 it needs to be due to massive fragmentation caused by re-writing 53 @INDEX records many times during indexing. 54 */ 55 struct ldb_index_pointer { 56 struct ldb_index_pointer *next, *prev; 57 struct ldb_val value; 35 36 struct dn_list { 37 unsigned int count; 38 struct ldb_val *dn; 58 39 }; 59 40 60 41 struct ltdb_idxptr { 61 int num_dns; 62 const char **dn_list; 63 bool repack; 42 struct tdb_context *itdb; 43 int error; 64 44 }; 65 45 66 /* 67 add to the list of DNs that need to be fixed on transaction end 68 */ 69 static int ltdb_idxptr_add(struct ldb_module *module, const struct ldb_message *msg) 70 { 71 void *data = ldb_module_get_private(module); 72 struct ltdb_private *ltdb = talloc_get_type(data, struct ltdb_private); 73 ltdb->idxptr->dn_list = talloc_realloc(ltdb->idxptr, ltdb->idxptr->dn_list, 74 const char *, ltdb->idxptr->num_dns+1); 75 if (ltdb->idxptr->dn_list == NULL) { 76 ltdb->idxptr->num_dns = 0; 77 return LDB_ERR_OPERATIONS_ERROR; 78 } 79 ltdb->idxptr->dn_list[ltdb->idxptr->num_dns] = 80 talloc_strdup(ltdb->idxptr->dn_list, ldb_dn_get_linearized(msg->dn)); 81 if (ltdb->idxptr->dn_list[ltdb->idxptr->num_dns] == NULL) { 82 return LDB_ERR_OPERATIONS_ERROR; 83 } 84 ltdb->idxptr->num_dns++; 85 return LDB_SUCCESS; 86 } 87 88 /* free an idxptr record */ 89 static int ltdb_free_idxptr(struct ldb_module *module, struct ldb_message_element *el) 90 { 91 struct ldb_val val; 92 struct ldb_index_pointer *ptr; 93 94 if (el->num_values != 1) { 95 return LDB_ERR_OPERATIONS_ERROR; 96 } 97 98 val = el->values[0]; 99 if (val.length != sizeof(void *)) { 100 return LDB_ERR_OPERATIONS_ERROR; 101 } 102 103 ptr = *(struct ldb_index_pointer **)val.data; 104 if (talloc_get_type(ptr, struct ldb_index_pointer) != ptr) { 105 return LDB_ERR_OPERATIONS_ERROR; 106 } 107 108 while (ptr) { 109 struct ldb_index_pointer *tmp = ptr; 110 DLIST_REMOVE(ptr, ptr); 111 talloc_free(tmp); 112 } 113 114 return LDB_SUCCESS; 115 } 116 117 118 /* convert from the IDXPTR format to a ldb_message_element format */ 119 static int ltdb_convert_from_idxptr(struct ldb_module *module, struct ldb_message_element *el) 120 { 121 struct ldb_val val; 122 struct ldb_index_pointer *ptr, *tmp; 123 int i; 124 struct ldb_val *val2; 125 126 if (el->num_values != 1) { 127 return LDB_ERR_OPERATIONS_ERROR; 128 } 129 130 val = el->values[0]; 131 if (val.length != sizeof(void *)) { 132 return LDB_ERR_OPERATIONS_ERROR; 133 } 134 135 ptr = *(struct ldb_index_pointer **)val.data; 136 if (talloc_get_type(ptr, struct ldb_index_pointer) != ptr) { 137 return LDB_ERR_OPERATIONS_ERROR; 138 } 139 140 /* count the length of the list */ 141 for (i=0, tmp = ptr; tmp; tmp=tmp->next) { 142 i++; 143 } 144 145 /* allocate the new values array */ 146 val2 = talloc_realloc(NULL, el->values, struct ldb_val, i); 147 if (val2 == NULL) { 148 return LDB_ERR_OPERATIONS_ERROR; 149 } 150 el->values = val2; 151 el->num_values = i; 152 153 /* populate the values array */ 154 for (i=0, tmp = ptr; tmp; tmp=tmp->next, i++) { 155 el->values[i].length = tmp->value.length; 156 /* we need to over-allocate here as there are still some places 157 in ldb that rely on null termination. */ 158 el->values[i].data = talloc_size(el->values, tmp->value.length+1); 159 if (el->values[i].data == NULL) { 160 return LDB_ERR_OPERATIONS_ERROR; 161 } 162 memcpy(el->values[i].data, tmp->value.data, tmp->value.length); 163 el->values[i].data[tmp->value.length] = 0; 164 } 165 166 /* update the name */ 167 el->name = LTDB_IDX; 168 169 return LDB_SUCCESS; 170 } 171 172 173 /* convert to the IDXPTR format from a ldb_message_element format */ 174 static int ltdb_convert_to_idxptr(struct ldb_module *module, struct ldb_message_element *el) 175 { 176 struct ldb_index_pointer *ptr, *tmp; 177 int i; 178 struct ldb_val *val2; 179 void *data = ldb_module_get_private(module); 180 struct ltdb_private *ltdb = talloc_get_type(data, struct ltdb_private); 181 182 ptr = NULL; 183 184 for (i=0;i<el->num_values;i++) { 185 tmp = talloc(ltdb->idxptr, struct ldb_index_pointer); 186 if (tmp == NULL) { 187 return LDB_ERR_OPERATIONS_ERROR; 188 } 189 tmp->value = el->values[i]; 190 tmp->value.data = talloc_memdup(tmp, tmp->value.data, tmp->value.length); 191 if (tmp->value.data == NULL) { 192 return LDB_ERR_OPERATIONS_ERROR; 193 } 194 DLIST_ADD(ptr, tmp); 195 } 196 197 /* allocate the new values array */ 198 val2 = talloc_realloc(NULL, el->values, struct ldb_val, 1); 199 if (val2 == NULL) { 200 return LDB_ERR_OPERATIONS_ERROR; 201 } 202 el->values = val2; 203 el->num_values = 1; 204 205 el->values[0].data = talloc_memdup(el->values, &ptr, sizeof(ptr)); 206 el->values[0].length = sizeof(ptr); 207 208 /* update the name */ 209 el->name = LTDB_IDXPTR; 210 211 return LDB_SUCCESS; 212 } 213 46 /* we put a @IDXVERSION attribute on index entries. This 47 allows us to tell if it was written by an older version 48 */ 49 #define LTDB_INDEXING_VERSION 2 214 50 215 51 /* enable the idxptr mode when transactions start */ 216 52 int ltdb_index_transaction_start(struct ldb_module *module) 217 53 { 218 void *data = ldb_module_get_private(module); 219 struct ltdb_private *ltdb = talloc_get_type(data, struct ltdb_private); 220 ltdb->idxptr = talloc_zero(module, struct ltdb_idxptr); 54 struct ltdb_private *ltdb = talloc_get_type(ldb_module_get_private(module), struct ltdb_private); 55 ltdb->idxptr = talloc_zero(ltdb, struct ltdb_idxptr); 221 56 return LDB_SUCCESS; 222 57 } 223 58 224 /* 225 a wrapper around ltdb_search_dn1() which translates pointer based index records 226 and maps them into normal ldb message structures 227 */ 228 static int ltdb_search_dn1_index(struct ldb_module *module, 229 struct ldb_dn *dn, struct ldb_message *msg) 230 { 231 int ret, i; 59 /* compare two DN entries in a dn_list. Take account of possible 60 * differences in string termination */ 61 static int dn_list_cmp(const struct ldb_val *v1, const struct ldb_val *v2) 62 { 63 if (v1->length > v2->length && v1->data[v2->length] != 0) { 64 return -1; 65 } 66 if (v1->length < v2->length && v2->data[v1->length] != 0) { 67 return 1; 68 } 69 return strncmp((char *)v1->data, (char *)v2->data, v1->length); 70 } 71 72 73 /* 74 find a entry in a dn_list, using a ldb_val. Uses a case sensitive 75 comparison with the dn returns -1 if not found 76 */ 77 static int ltdb_dn_list_find_val(const struct dn_list *list, const struct ldb_val *v) 78 { 79 unsigned int i; 80 for (i=0; i<list->count; i++) { 81 if (dn_list_cmp(&list->dn[i], v) == 0) return i; 82 } 83 return -1; 84 } 85 86 /* 87 find a entry in a dn_list. Uses a case sensitive comparison with the dn 88 returns -1 if not found 89 */ 90 static int ltdb_dn_list_find_str(struct dn_list *list, const char *dn) 91 { 92 struct ldb_val v; 93 v.data = discard_const_p(unsigned char, dn); 94 v.length = strlen(dn); 95 return ltdb_dn_list_find_val(list, &v); 96 } 97 98 /* 99 this is effectively a cast function, but with lots of paranoia 100 checks and also copes with CPUs that are fussy about pointer 101 alignment 102 */ 103 static struct dn_list *ltdb_index_idxptr(struct ldb_module *module, TDB_DATA rec, bool check_parent) 104 { 105 struct dn_list *list; 106 if (rec.dsize != sizeof(void *)) { 107 ldb_asprintf_errstring(ldb_module_get_ctx(module), 108 "Bad data size for idxptr %u", (unsigned)rec.dsize); 109 return NULL; 110 } 111 /* note that we can't just use a cast here, as rec.dptr may 112 not be aligned sufficiently for a pointer. A cast would cause 113 platforms like some ARM CPUs to crash */ 114 memcpy(&list, rec.dptr, sizeof(void *)); 115 list = talloc_get_type(list, struct dn_list); 116 if (list == NULL) { 117 ldb_asprintf_errstring(ldb_module_get_ctx(module), 118 "Bad type '%s' for idxptr", 119 talloc_get_name(list)); 120 return NULL; 121 } 122 if (check_parent && list->dn && talloc_parent(list->dn) != list) { 123 ldb_asprintf_errstring(ldb_module_get_ctx(module), 124 "Bad parent '%s' for idxptr", 125 talloc_get_name(talloc_parent(list->dn))); 126 return NULL; 127 } 128 return list; 129 } 130 131 /* 132 return the @IDX list in an index entry for a dn as a 133 struct dn_list 134 */ 135 static int ltdb_dn_list_load(struct ldb_module *module, 136 struct ldb_dn *dn, struct dn_list *list) 137 { 138 struct ldb_message *msg; 139 int ret; 140 struct ldb_message_element *el; 141 struct ltdb_private *ltdb = talloc_get_type(ldb_module_get_private(module), struct ltdb_private); 142 TDB_DATA rec; 143 struct dn_list *list2; 144 TDB_DATA key; 145 146 list->dn = NULL; 147 list->count = 0; 148 149 /* see if we have any in-memory index entries */ 150 if (ltdb->idxptr == NULL || 151 ltdb->idxptr->itdb == NULL) { 152 goto normal_index; 153 } 154 155 key.dptr = discard_const_p(unsigned char, ldb_dn_get_linearized(dn)); 156 key.dsize = strlen((char *)key.dptr); 157 158 rec = tdb_fetch(ltdb->idxptr->itdb, key); 159 if (rec.dptr == NULL) { 160 goto normal_index; 161 } 162 163 /* we've found an in-memory index entry */ 164 list2 = ltdb_index_idxptr(module, rec, true); 165 if (list2 == NULL) { 166 free(rec.dptr); 167 return LDB_ERR_OPERATIONS_ERROR; 168 } 169 free(rec.dptr); 170 171 *list = *list2; 172 return LDB_SUCCESS; 173 174 normal_index: 175 msg = ldb_msg_new(list); 176 if (msg == NULL) { 177 return LDB_ERR_OPERATIONS_ERROR; 178 } 179 232 180 ret = ltdb_search_dn1(module, dn, msg); 233 181 if (ret != LDB_SUCCESS) { 182 talloc_free(msg); 234 183 return ret; 235 184 } 236 185 237 /* if this isn't a @INDEX record then don't munge it */ 238 if (strncmp(ldb_dn_get_linearized(msg->dn), LTDB_INDEX ":", strlen(LTDB_INDEX) + 1) != 0) { 239 return LDB_ERR_OPERATIONS_ERROR; 240 } 241 242 for (i=0;i<msg->num_elements;i++) { 243 struct ldb_message_element *el = &msg->elements[i]; 244 if (strcmp(el->name, LTDB_IDXPTR) == 0) { 245 ret = ltdb_convert_from_idxptr(module, el); 246 if (ret != LDB_SUCCESS) { 247 return ret; 248 } 249 } 250 } 251 252 return ret; 253 } 254 255 256 257 /* 258 fixup the idxptr for one DN 259 */ 260 static int ltdb_idxptr_fix_dn(struct ldb_module *module, const char *strdn) 261 { 262 struct ldb_context *ldb; 263 struct ldb_dn *dn; 264 struct ldb_message *msg = ldb_msg_new(module); 186 /* TODO: check indexing version number */ 187 188 el = ldb_msg_find_element(msg, LTDB_IDX); 189 if (!el) { 190 talloc_free(msg); 191 return LDB_SUCCESS; 192 } 193 194 /* we avoid copying the strings by stealing the list */ 195 list->dn = talloc_steal(list, el->values); 196 list->count = el->num_values; 197 198 return LDB_SUCCESS; 199 } 200 201 202 /* 203 save a dn_list into a full @IDX style record 204 */ 205 static int ltdb_dn_list_store_full(struct ldb_module *module, struct ldb_dn *dn, 206 struct dn_list *list) 207 { 208 struct ldb_message *msg; 265 209 int ret; 266 210 267 ldb = ldb_module_get_ctx(module); 268 269 dn = ldb_dn_new(msg, ldb, strdn); 270 if (ltdb_search_dn1_index(module, dn, msg) == LDB_SUCCESS) { 271 ret = ltdb_store(module, msg, TDB_REPLACE); 272 } 211 if (list->count == 0) { 212 ret = ltdb_delete_noindex(module, dn); 213 if (ret == LDB_ERR_NO_SUCH_OBJECT) { 214 return LDB_SUCCESS; 215 } 216 return ret; 217 } 218 219 msg = ldb_msg_new(module); 220 if (!msg) { 221 return ldb_module_oom(module); 222 } 223 224 ret = ldb_msg_add_fmt(msg, LTDB_IDXVERSION, "%u", LTDB_INDEXING_VERSION); 225 if (ret != LDB_SUCCESS) { 226 talloc_free(msg); 227 return ldb_module_oom(module); 228 } 229 230 msg->dn = dn; 231 if (list->count > 0) { 232 struct ldb_message_element *el; 233 234 ret = ldb_msg_add_empty(msg, LTDB_IDX, LDB_FLAG_MOD_ADD, &el); 235 if (ret != LDB_SUCCESS) { 236 talloc_free(msg); 237 return ldb_module_oom(module); 238 } 239 el->values = list->dn; 240 el->num_values = list->count; 241 } 242 243 ret = ltdb_store(module, msg, TDB_REPLACE); 273 244 talloc_free(msg); 274 245 return ret; 275 246 } 276 247 248 /* 249 save a dn_list into the database, in either @IDX or internal format 250 */ 251 static int ltdb_dn_list_store(struct ldb_module *module, struct ldb_dn *dn, 252 struct dn_list *list) 253 { 254 struct ltdb_private *ltdb = talloc_get_type(ldb_module_get_private(module), struct ltdb_private); 255 TDB_DATA rec, key; 256 int ret; 257 struct dn_list *list2; 258 259 if (ltdb->idxptr == NULL) { 260 return ltdb_dn_list_store_full(module, dn, list); 261 } 262 263 if (ltdb->idxptr->itdb == NULL) { 264 ltdb->idxptr->itdb = tdb_open(NULL, 1000, TDB_INTERNAL, O_RDWR, 0); 265 if (ltdb->idxptr->itdb == NULL) { 266 return LDB_ERR_OPERATIONS_ERROR; 267 } 268 } 269 270 key.dptr = discard_const_p(unsigned char, ldb_dn_get_linearized(dn)); 271 key.dsize = strlen((char *)key.dptr); 272 273 rec = tdb_fetch(ltdb->idxptr->itdb, key); 274 if (rec.dptr != NULL) { 275 list2 = ltdb_index_idxptr(module, rec, false); 276 if (list2 == NULL) { 277 free(rec.dptr); 278 return LDB_ERR_OPERATIONS_ERROR; 279 } 280 free(rec.dptr); 281 list2->dn = talloc_steal(list2, list->dn); 282 list2->count = list->count; 283 return LDB_SUCCESS; 284 } 285 286 list2 = talloc(ltdb->idxptr, struct dn_list); 287 if (list2 == NULL) { 288 return LDB_ERR_OPERATIONS_ERROR; 289 } 290 list2->dn = talloc_steal(list2, list->dn); 291 list2->count = list->count; 292 293 rec.dptr = (uint8_t *)&list2; 294 rec.dsize = sizeof(void *); 295 296 ret = tdb_store(ltdb->idxptr->itdb, key, rec, TDB_INSERT); 297 if (ret == -1) { 298 return ltdb_err_map(tdb_error(ltdb->idxptr->itdb)); 299 } 300 return LDB_SUCCESS; 301 } 302 303 /* 304 traverse function for storing the in-memory index entries on disk 305 */ 306 static int ltdb_index_traverse_store(struct tdb_context *tdb, TDB_DATA key, TDB_DATA data, void *state) 307 { 308 struct ldb_module *module = state; 309 struct ltdb_private *ltdb = talloc_get_type(ldb_module_get_private(module), struct ltdb_private); 310 struct ldb_dn *dn; 311 struct ldb_context *ldb = ldb_module_get_ctx(module); 312 struct ldb_val v; 313 struct dn_list *list; 314 315 list = ltdb_index_idxptr(module, data, true); 316 if (list == NULL) { 317 ltdb->idxptr->error = LDB_ERR_OPERATIONS_ERROR; 318 return -1; 319 } 320 321 v.data = key.dptr; 322 v.length = strnlen((char *)key.dptr, key.dsize); 323 324 dn = ldb_dn_from_ldb_val(module, ldb, &v); 325 if (dn == NULL) { 326 ldb_asprintf_errstring(ldb, "Failed to parse index key %*.*s as an LDB DN", (int)v.length, (int)v.length, (const char *)v.data); 327 ltdb->idxptr->error = LDB_ERR_OPERATIONS_ERROR; 328 return -1; 329 } 330 331 ltdb->idxptr->error = ltdb_dn_list_store_full(module, dn, list); 332 talloc_free(dn); 333 if (ltdb->idxptr->error != 0) { 334 return -1; 335 } 336 return 0; 337 } 338 277 339 /* cleanup the idxptr mode when transaction commits */ 278 340 int ltdb_index_transaction_commit(struct ldb_module *module) 279 341 { 280 int i; 281 void *data = ldb_module_get_private(module); 282 struct ltdb_private *ltdb = talloc_get_type(data, struct ltdb_private); 283 284 /* fix all the DNs that we have modified */ 285 if (ltdb->idxptr) { 286 for (i=0;i<ltdb->idxptr->num_dns;i++) { 287 ltdb_idxptr_fix_dn(module, ltdb->idxptr->dn_list[i]); 288 } 289 290 if (ltdb->idxptr->repack) { 291 tdb_repack(ltdb->tdb); 292 } 293 } 294 342 struct ltdb_private *ltdb = talloc_get_type(ldb_module_get_private(module), struct ltdb_private); 343 int ret; 344 345 struct ldb_context *ldb = ldb_module_get_ctx(module); 346 347 ldb_reset_err_string(ldb); 348 349 if (ltdb->idxptr->itdb) { 350 tdb_traverse(ltdb->idxptr->itdb, ltdb_index_traverse_store, module); 351 tdb_close(ltdb->idxptr->itdb); 352 } 353 354 ret = ltdb->idxptr->error; 355 if (ret != LDB_SUCCESS) { 356 if (!ldb_errstring(ldb)) { 357 ldb_set_errstring(ldb, ldb_strerror(ret)); 358 } 359 ldb_asprintf_errstring(ldb, "Failed to store index records in transaction commit: %s", ldb_errstring(ldb)); 360 } 361 362 talloc_free(ltdb->idxptr); 363 ltdb->idxptr = NULL; 364 return ret; 365 } 366 367 /* cleanup the idxptr mode when transaction cancels */ 368 int ltdb_index_transaction_cancel(struct ldb_module *module) 369 { 370 struct ltdb_private *ltdb = talloc_get_type(ldb_module_get_private(module), struct ltdb_private); 371 if (ltdb->idxptr && ltdb->idxptr->itdb) { 372 tdb_close(ltdb->idxptr->itdb); 373 } 295 374 talloc_free(ltdb->idxptr); 296 375 ltdb->idxptr = NULL; … … 298 377 } 299 378 300 /* cleanup the idxptr mode when transaction cancels */301 int ltdb_index_transaction_cancel(struct ldb_module *module)302 {303 void *data = ldb_module_get_private(module);304 struct ltdb_private *ltdb = talloc_get_type(data, struct ltdb_private);305 talloc_free(ltdb->idxptr);306 ltdb->idxptr = NULL;307 return LDB_SUCCESS;308 }309 310 311 312 /* a wrapper around ltdb_store() for the index code which313 stores in IDXPTR format when idxptr mode is enabled314 315 WARNING: This modifies the msg which is passed in316 */317 int ltdb_store_idxptr(struct ldb_module *module, const struct ldb_message *msg, int flgs)318 {319 void *data = ldb_module_get_private(module);320 struct ltdb_private *ltdb = talloc_get_type(data, struct ltdb_private);321 int ret;322 323 if (ltdb->idxptr) {324 int i;325 struct ldb_message *msg2 = ldb_msg_new(module);326 327 /* free any old pointer */328 ret = ltdb_search_dn1(module, msg->dn, msg2);329 if (ret == 0) {330 for (i=0;i<msg2->num_elements;i++) {331 struct ldb_message_element *el = &msg2->elements[i];332 if (strcmp(el->name, LTDB_IDXPTR) == 0) {333 ret = ltdb_free_idxptr(module, el);334 if (ret != LDB_SUCCESS) {335 return ret;336 }337 }338 }339 }340 talloc_free(msg2);341 342 for (i=0;i<msg->num_elements;i++) {343 struct ldb_message_element *el = &msg->elements[i];344 if (strcmp(el->name, LTDB_IDX) == 0) {345 ret = ltdb_convert_to_idxptr(module, el);346 if (ret != LDB_SUCCESS) {347 return ret;348 }349 }350 }351 352 if (ltdb_idxptr_add(module, msg) != 0) {353 return LDB_ERR_OPERATIONS_ERROR;354 }355 }356 357 ret = ltdb_store(module, msg, flgs);358 return ret;359 }360 361 362 /*363 find an element in a list, using the given comparison function and364 assuming that the list is already sorted using comp_fn365 366 return -1 if not found, or the index of the first occurance of needle if found367 */368 static int ldb_list_find(const void *needle,369 const void *base, size_t nmemb, size_t size,370 comparison_fn_t comp_fn)371 {372 const char *base_p = (const char *)base;373 size_t min_i, max_i, test_i;374 375 if (nmemb == 0) {376 return -1;377 }378 379 min_i = 0;380 max_i = nmemb-1;381 382 while (min_i < max_i) {383 int r;384 385 test_i = (min_i + max_i) / 2;386 /* the following cast looks strange, but is387 correct. The key to understanding it is that base_p388 is a pointer to an array of pointers, so we have to389 dereference it after casting to void **. The strange390 const in the middle gives us the right type of pointer391 after the dereference (tridge) */392 r = comp_fn(needle, *(void * const *)(base_p + (size * test_i)));393 if (r == 0) {394 /* scan back for first element */395 while (test_i > 0 &&396 comp_fn(needle, *(void * const *)(base_p + (size * (test_i-1)))) == 0) {397 test_i--;398 }399 return test_i;400 }401 if (r < 0) {402 if (test_i == 0) {403 return -1;404 }405 max_i = test_i - 1;406 }407 if (r > 0) {408 min_i = test_i + 1;409 }410 }411 412 if (comp_fn(needle, *(void * const *)(base_p + (size * min_i))) == 0) {413 return min_i;414 }415 416 return -1;417 }418 419 struct dn_list {420 unsigned int count;421 char **dn;422 };423 379 424 380 /* 425 381 return the dn key to be used for an index 426 caller frees382 the caller is responsible for freeing 427 383 */ 428 384 static struct ldb_dn *ltdb_index_key(struct ldb_context *ldb, … … 458 414 if (ldb_should_b64_encode(ldb, &v)) { 459 415 char *vstr = ldb_base64_encode(ldb, (char *)v.data, v.length); 460 if (!vstr) return NULL; 416 if (!vstr) { 417 talloc_free(attr_folded); 418 return NULL; 419 } 461 420 ret = ldb_dn_new_fmt(ldb, ldb, "%s:%s::%s", LTDB_INDEX, attr_folded, vstr); 462 421 talloc_free(vstr); … … 476 435 see if a attribute value is in the list of indexed attributes 477 436 */ 478 static int ldb_msg_find_idx(const struct ldb_message *msg, const char *attr, 479 unsigned int *v_idx, const char *key) 480 { 481 unsigned int i, j; 482 for (i=0;i<msg->num_elements;i++) { 483 if (ldb_attr_cmp(msg->elements[i].name, key) == 0) { 484 const struct ldb_message_element *el = &msg->elements[i]; 485 486 if (attr == NULL) { 487 /* in this case we are just looking to see if key is present, 488 we are not spearching for a specific index */ 489 return 0; 490 } 491 492 for (j=0;j<el->num_values;j++) { 493 if (ldb_attr_cmp((char *)el->values[j].data, attr) == 0) { 494 if (v_idx) { 495 *v_idx = j; 496 } 497 return i; 498 } 499 } 500 } 501 } 502 return -1; 503 } 504 505 /* used in sorting dn lists */ 506 static int list_cmp(const char **s1, const char **s2) 507 { 508 return strcmp(*s1, *s2); 509 } 510 511 /* 512 return a list of dn's that might match a simple indexed search or 437 static bool ltdb_is_indexed(const struct ldb_message *index_list, const char *attr) 438 { 439 unsigned int i; 440 struct ldb_message_element *el; 441 442 el = ldb_msg_find_element(index_list, LTDB_IDXATTR); 443 if (el == NULL) { 444 return false; 445 } 446 447 /* TODO: this is too expensive! At least use a binary search */ 448 for (i=0; i<el->num_values; i++) { 449 if (ldb_attr_cmp((char *)el->values[i].data, attr) == 0) { 450 return true; 451 } 452 } 453 return false; 454 } 455 456 /* 457 in the following logic functions, the return value is treated as 458 follows: 459 460 LDB_SUCCESS: we found some matching index values 461 462 LDB_ERR_NO_SUCH_OBJECT: we know for sure that no object matches 463 464 LDB_ERR_OPERATIONS_ERROR: indexing could not answer the call, 465 we'll need a full search 466 */ 467 468 /* 469 return a list of dn's that might match a simple indexed search (an 470 equality search only) 513 471 */ 514 472 static int ltdb_index_dn_simple(struct ldb_module *module, … … 520 478 struct ldb_dn *dn; 521 479 int ret; 522 unsigned int i, j;523 struct ldb_message *msg;524 480 525 481 ldb = ldb_module_get_ctx(module); … … 530 486 /* if the attribute isn't in the list of indexed attributes then 531 487 this node needs a full search */ 532 if ( ldb_msg_find_idx(index_list, tree->u.equality.attr, NULL, LTDB_IDXATTR) == -1) {488 if (!ltdb_is_indexed(index_list, tree->u.equality.attr)) { 533 489 return LDB_ERR_OPERATIONS_ERROR; 534 490 } … … 539 495 if (!dn) return LDB_ERR_OPERATIONS_ERROR; 540 496 541 msg = talloc(list, struct ldb_message); 542 if (msg == NULL) { 543 return LDB_ERR_OPERATIONS_ERROR; 544 } 545 546 ret = ltdb_search_dn1_index(module, dn, msg); 497 ret = ltdb_dn_list_load(module, dn, list); 547 498 talloc_free(dn); 548 if (ret != LDB_SUCCESS) { 549 return ret; 550 } 551 552 for (i=0;i<msg->num_elements;i++) { 553 struct ldb_message_element *el; 554 555 if (strcmp(msg->elements[i].name, LTDB_IDX) != 0) { 556 continue; 557 } 558 559 el = &msg->elements[i]; 560 561 list->dn = talloc_array(list, char *, el->num_values); 562 if (!list->dn) { 563 talloc_free(msg); 564 return LDB_ERR_OPERATIONS_ERROR; 565 } 566 567 for (j=0;j<el->num_values;j++) { 568 list->dn[list->count] = 569 talloc_strdup(list->dn, (char *)el->values[j].data); 570 if (!list->dn[list->count]) { 571 talloc_free(msg); 572 return LDB_ERR_OPERATIONS_ERROR; 573 } 574 list->count++; 575 } 576 } 577 578 talloc_free(msg); 579 580 if (list->count > 1) { 581 qsort(list->dn, list->count, sizeof(char *), (comparison_fn_t) list_cmp); 582 } 583 584 return LDB_SUCCESS; 585 } 586 587 588 static int list_union(struct ldb_context *, struct dn_list *, const struct dn_list *); 499 return ret; 500 } 501 502 503 static bool list_union(struct ldb_context *, struct dn_list *, const struct dn_list *); 589 504 590 505 /* … … 596 511 struct dn_list *list) 597 512 { 598 struct ldb_context *ldb;599 ldb = ldb_module_get_ctx(module);600 601 513 if (ldb_attr_dn(tree->u.equality.attr) == 0) { 602 list->dn = talloc_array(list, char *, 1);514 list->dn = talloc_array(list, struct ldb_val, 1); 603 515 if (list->dn == NULL) { 604 ldb_ oom(ldb);516 ldb_module_oom(module); 605 517 return LDB_ERR_OPERATIONS_ERROR; 606 518 } 607 list->dn[0] = talloc_strdup(list->dn, (char *)tree->u.equality.value.data); 608 if (list->dn[0] == NULL) { 609 ldb_oom(ldb); 610 return LDB_ERR_OPERATIONS_ERROR; 611 } 519 list->dn[0] = tree->u.equality.value; 612 520 list->count = 1; 613 521 return LDB_SUCCESS; … … 620 528 list intersection 621 529 list = list & list2 622 relies on the lists being sorted 623 */ 624 static int list_intersect(struct ldb_context *ldb, 625 struct dn_list *list, const struct dn_list *list2) 530 */ 531 static bool list_intersect(struct ldb_context *ldb, 532 struct dn_list *list, const struct dn_list *list2) 626 533 { 627 534 struct dn_list *list3; 628 535 unsigned int i; 629 536 630 if (list->count == 0 || list2->count == 0) {537 if (list->count == 0) { 631 538 /* 0 & X == 0 */ 632 return LDB_ERR_NO_SUCH_OBJECT; 633 } 634 635 list3 = talloc(ldb, struct dn_list); 539 return true; 540 } 541 if (list2->count == 0) { 542 /* X & 0 == 0 */ 543 list->count = 0; 544 list->dn = NULL; 545 return true; 546 } 547 548 /* the indexing code is allowed to return a longer list than 549 what really matches, as all results are filtered by the 550 full expression at the end - this shortcut avoids a lot of 551 work in some cases */ 552 if (list->count < 2 && list2->count > 10) { 553 return true; 554 } 555 if (list2->count < 2 && list->count > 10) { 556 list->count = list2->count; 557 list->dn = list2->dn; 558 /* note that list2 may not be the parent of list2->dn, 559 as list2->dn may be owned by ltdb->idxptr. In that 560 case we expect this reparent call to fail, which is 561 OK */ 562 talloc_reparent(list2, list, list2->dn); 563 return true; 564 } 565 566 list3 = talloc_zero(list, struct dn_list); 636 567 if (list3 == NULL) { 637 return LDB_ERR_OPERATIONS_ERROR;638 } 639 640 list3->dn = talloc_array(list3, char *, list->count);568 return false; 569 } 570 571 list3->dn = talloc_array(list3, struct ldb_val, list->count); 641 572 if (!list3->dn) { 642 573 talloc_free(list3); 643 return LDB_ERR_OPERATIONS_ERROR;574 return false; 644 575 } 645 576 list3->count = 0; 646 577 647 578 for (i=0;i<list->count;i++) { 648 if (ldb_list_find(list->dn[i], list2->dn, list2->count, 649 sizeof(char *), (comparison_fn_t)strcmp) != -1) { 650 list3->dn[list3->count] = talloc_move(list3->dn, &list->dn[i]); 579 if (ltdb_dn_list_find_val(list2, &list->dn[i]) != -1) { 580 list3->dn[list3->count] = list->dn[i]; 651 581 list3->count++; 652 } else { 653 talloc_free(list->dn[i]); 654 } 655 } 656 657 talloc_free(list->dn); 658 list->dn = talloc_move(list, &list3->dn); 582 } 583 } 584 585 list->dn = talloc_steal(list, list3->dn); 659 586 list->count = list3->count; 660 587 talloc_free(list3); 661 588 662 return LDB_ERR_NO_SUCH_OBJECT;589 return true; 663 590 } 664 591 … … 667 594 list union 668 595 list = list | list2 669 relies on the lists being sorted 670 */ 671 static int list_union(struct ldb_context *ldb, 672 struct dn_list *list, const struct dn_list *list2) 673 { 674 unsigned int i; 675 char **d; 676 unsigned int count = list->count; 677 678 if (list->count == 0 && list2->count == 0) { 679 /* 0 | 0 == 0 */ 680 return LDB_ERR_NO_SUCH_OBJECT; 681 } 682 683 d = talloc_realloc(list, list->dn, char *, list->count + list2->count); 684 if (!d) { 685 return LDB_ERR_OPERATIONS_ERROR; 686 } 687 list->dn = d; 688 689 for (i=0;i<list2->count;i++) { 690 if (ldb_list_find(list2->dn[i], list->dn, count, 691 sizeof(char *), (comparison_fn_t)strcmp) == -1) { 692 list->dn[list->count] = talloc_strdup(list->dn, list2->dn[i]); 693 if (!list->dn[list->count]) { 694 return LDB_ERR_OPERATIONS_ERROR; 695 } 696 list->count++; 697 } 698 } 699 700 if (list->count != count) { 701 qsort(list->dn, list->count, sizeof(char *), (comparison_fn_t)list_cmp); 702 } 703 704 return LDB_ERR_NO_SUCH_OBJECT; 596 */ 597 static bool list_union(struct ldb_context *ldb, 598 struct dn_list *list, const struct dn_list *list2) 599 { 600 struct ldb_val *dn3; 601 602 if (list2->count == 0) { 603 /* X | 0 == X */ 604 return true; 605 } 606 607 if (list->count == 0) { 608 /* 0 | X == X */ 609 list->count = list2->count; 610 list->dn = list2->dn; 611 /* note that list2 may not be the parent of list2->dn, 612 as list2->dn may be owned by ltdb->idxptr. In that 613 case we expect this reparent call to fail, which is 614 OK */ 615 talloc_reparent(list2, list, list2->dn); 616 return true; 617 } 618 619 dn3 = talloc_array(list, struct ldb_val, list->count + list2->count); 620 if (!dn3) { 621 ldb_oom(ldb); 622 return false; 623 } 624 625 /* we allow for duplicates here, and get rid of them later */ 626 memcpy(dn3, list->dn, sizeof(list->dn[0])*list->count); 627 memcpy(dn3+list->count, list2->dn, sizeof(list2->dn[0])*list2->count); 628 629 list->dn = dn3; 630 list->count += list2->count; 631 632 return true; 705 633 } 706 634 … … 712 640 713 641 /* 714 OR two index results642 process an OR list (a union) 715 643 */ 716 644 static int ltdb_index_dn_or(struct ldb_module *module, … … 721 649 struct ldb_context *ldb; 722 650 unsigned int i; 723 int ret;724 651 725 652 ldb = ldb_module_get_ctx(module); 726 653 727 ret = LDB_ERR_OPERATIONS_ERROR;728 654 list->dn = NULL; 729 655 list->count = 0; 730 656 731 for (i=0; i<tree->u.list.num_elements;i++) {657 for (i=0; i<tree->u.list.num_elements; i++) { 732 658 struct dn_list *list2; 733 int v;734 735 list2 = talloc (module, struct dn_list);659 int ret; 660 661 list2 = talloc_zero(list, struct dn_list); 736 662 if (list2 == NULL) { 737 663 return LDB_ERR_OPERATIONS_ERROR; 738 664 } 739 665 740 v = ltdb_index_dn(module, tree->u.list.elements[i], index_list, list2); 741 742 if (v == LDB_ERR_NO_SUCH_OBJECT) { 743 /* 0 || X == X */ 744 if (ret != LDB_SUCCESS && ret != LDB_ERR_NO_SUCH_OBJECT) { 745 ret = v; 746 } 666 ret = ltdb_index_dn(module, tree->u.list.elements[i], index_list, list2); 667 668 if (ret == LDB_ERR_NO_SUCH_OBJECT) { 669 /* X || 0 == X */ 747 670 talloc_free(list2); 748 671 continue; 749 672 } 750 673 751 if (v != LDB_SUCCESS && v != LDB_ERR_NO_SUCH_OBJECT) { 752 /* 1 || X == 1 */ 753 talloc_free(list->dn); 674 if (ret != LDB_SUCCESS) { 675 /* X || * == * */ 754 676 talloc_free(list2); 755 return v; 756 } 757 758 if (ret != LDB_SUCCESS && ret != LDB_ERR_NO_SUCH_OBJECT) { 759 ret = LDB_SUCCESS; 760 list->dn = talloc_move(list, &list2->dn); 761 list->count = list2->count; 762 } else { 763 if (list_union(ldb, list, list2) == -1) { 764 talloc_free(list2); 765 return LDB_ERR_OPERATIONS_ERROR; 766 } 767 ret = LDB_SUCCESS; 768 } 769 talloc_free(list2); 677 return ret; 678 } 679 680 if (!list_union(ldb, list, list2)) { 681 talloc_free(list2); 682 return LDB_ERR_OPERATIONS_ERROR; 683 } 770 684 } 771 685 … … 774 688 } 775 689 776 return ret;690 return LDB_SUCCESS; 777 691 } 778 692 … … 810 724 811 725 /* 812 AND two index results726 process an AND expression (intersection) 813 727 */ 814 728 static int ltdb_index_dn_and(struct ldb_module *module, … … 819 733 struct ldb_context *ldb; 820 734 unsigned int i; 821 int ret, pass;735 bool found; 822 736 823 737 ldb = ldb_module_get_ctx(module); 824 738 825 ret = LDB_ERR_OPERATIONS_ERROR;826 739 list->dn = NULL; 827 740 list->count = 0; 828 741 829 for (pass=0;pass<=1;pass++) { 830 /* in the first pass we only look for unique simple 831 equality tests, in the hope of avoiding having to look 832 at any others */ 833 bool only_unique = pass==0?true:false; 834 835 for (i=0;i<tree->u.list.num_elements;i++) { 836 struct dn_list *list2; 837 int v; 838 bool is_unique = false; 839 const struct ldb_parse_tree *subtree = tree->u.list.elements[i]; 840 841 if (subtree->operation == LDB_OP_EQUALITY && 842 ltdb_index_unique(ldb, subtree->u.equality.attr)) { 843 is_unique = true; 844 } 845 if (is_unique != only_unique) continue; 742 /* in the first pass we only look for unique simple 743 equality tests, in the hope of avoiding having to look 744 at any others */ 745 for (i=0; i<tree->u.list.num_elements; i++) { 746 const struct ldb_parse_tree *subtree = tree->u.list.elements[i]; 747 int ret; 748 749 if (subtree->operation != LDB_OP_EQUALITY || 750 !ltdb_index_unique(ldb, subtree->u.equality.attr)) { 751 continue; 752 } 753 754 ret = ltdb_index_dn(module, subtree, index_list, list); 755 if (ret == LDB_ERR_NO_SUCH_OBJECT) { 756 /* 0 && X == 0 */ 757 return LDB_ERR_NO_SUCH_OBJECT; 758 } 759 if (ret == LDB_SUCCESS) { 760 /* a unique index match means we can 761 * stop. Note that we don't care if we return 762 * a few too many objects, due to later 763 * filtering */ 764 return LDB_SUCCESS; 765 } 766 } 767 768 /* now do a full intersection */ 769 found = false; 770 771 for (i=0; i<tree->u.list.num_elements; i++) { 772 const struct ldb_parse_tree *subtree = tree->u.list.elements[i]; 773 struct dn_list *list2; 774 int ret; 775 776 list2 = talloc_zero(list, struct dn_list); 777 if (list2 == NULL) { 778 return ldb_module_oom(module); 779 } 846 780 847 list2 = talloc(module, struct dn_list); 848 if (list2 == NULL) { 849 return LDB_ERR_OPERATIONS_ERROR; 850 } 781 ret = ltdb_index_dn(module, subtree, index_list, list2); 782 783 if (ret == LDB_ERR_NO_SUCH_OBJECT) { 784 /* X && 0 == 0 */ 785 list->dn = NULL; 786 list->count = 0; 787 talloc_free(list2); 788 return LDB_ERR_NO_SUCH_OBJECT; 789 } 790 791 if (ret != LDB_SUCCESS) { 792 /* this didn't adding anything */ 793 talloc_free(list2); 794 continue; 795 } 796 797 if (!found) { 798 talloc_reparent(list2, list, list->dn); 799 list->dn = list2->dn; 800 list->count = list2->count; 801 found = true; 802 } else if (!list_intersect(ldb, list, list2)) { 803 talloc_free(list2); 804 return LDB_ERR_OPERATIONS_ERROR; 805 } 851 806 852 v = ltdb_index_dn(module, subtree, index_list, list2); 853 854 if (v == LDB_ERR_NO_SUCH_OBJECT) { 855 /* 0 && X == 0 */ 856 talloc_free(list->dn); 857 talloc_free(list2); 858 return LDB_ERR_NO_SUCH_OBJECT; 859 } 807 if (list->count == 0) { 808 list->dn = NULL; 809 return LDB_ERR_NO_SUCH_OBJECT; 810 } 860 811 861 if (v != LDB_SUCCESS && v != LDB_ERR_NO_SUCH_OBJECT) { 862 talloc_free(list2); 863 continue; 864 } 865 866 if (ret != LDB_SUCCESS && ret != LDB_ERR_NO_SUCH_OBJECT) { 867 ret = LDB_SUCCESS; 868 talloc_free(list->dn); 869 list->dn = talloc_move(list, &list2->dn); 870 list->count = list2->count; 871 } else { 872 if (list_intersect(ldb, list, list2) == -1) { 873 talloc_free(list2); 874 return LDB_ERR_OPERATIONS_ERROR; 875 } 876 } 877 878 talloc_free(list2); 879 880 if (list->count == 0) { 881 talloc_free(list->dn); 882 return LDB_ERR_NO_SUCH_OBJECT; 883 } 884 885 if (list->count == 1) { 886 /* it isn't worth loading the next part of the tree */ 887 return ret; 888 } 812 if (list->count < 2) { 813 /* it isn't worth loading the next part of the tree */ 814 return LDB_SUCCESS; 889 815 } 890 816 } 891 return ret; 817 818 if (!found) { 819 /* none of the attributes were indexed */ 820 return LDB_ERR_OPERATIONS_ERROR; 821 } 822 823 return LDB_SUCCESS; 892 824 } 893 825 894 826 /* 895 AND index results and ONE level special index827 return a list of matching objects using a one-level index 896 828 */ 897 829 static int ltdb_index_dn_one(struct ldb_module *module, … … 900 832 { 901 833 struct ldb_context *ldb; 902 struct dn_list *list2;903 struct ldb_message *msg;904 834 struct ldb_dn *key; 905 835 struct ldb_val val; 906 unsigned int i, j;907 836 int ret; 908 837 909 838 ldb = ldb_module_get_ctx(module); 910 839 911 list2 = talloc_zero(module, struct dn_list); 912 if (list2 == NULL) { 913 return LDB_ERR_OPERATIONS_ERROR; 914 } 915 916 /* the attribute is indexed. Pull the list of DNs that match the 917 search criterion */ 840 /* work out the index key from the parent DN */ 918 841 val.data = (uint8_t *)((uintptr_t)ldb_dn_get_casefold(parent_dn)); 919 842 val.length = strlen((char *)val.data); 920 843 key = ltdb_index_key(ldb, LTDB_IDXONE, &val, NULL); 921 844 if (!key) { 922 talloc_free(list2); 923 return LDB_ERR_OPERATIONS_ERROR; 924 } 925 926 msg = talloc(list2, struct ldb_message); 927 if (msg == NULL) { 928 talloc_free(list2); 929 return LDB_ERR_OPERATIONS_ERROR; 930 } 931 932 ret = ltdb_search_dn1_index(module, key, msg); 845 ldb_oom(ldb); 846 return LDB_ERR_OPERATIONS_ERROR; 847 } 848 849 ret = ltdb_dn_list_load(module, key, list); 933 850 talloc_free(key); 934 851 if (ret != LDB_SUCCESS) { … … 936 853 } 937 854 938 for (i = 0; i < msg->num_elements; i++) { 939 struct ldb_message_element *el; 940 941 if (strcmp(msg->elements[i].name, LTDB_IDX) != 0) { 942 continue; 943 } 944 945 el = &msg->elements[i]; 946 947 list2->dn = talloc_array(list2, char *, el->num_values); 948 if (!list2->dn) { 949 talloc_free(list2); 950 return LDB_ERR_OPERATIONS_ERROR; 951 } 952 953 for (j = 0; j < el->num_values; j++) { 954 list2->dn[list2->count] = talloc_strdup(list2->dn, (char *)el->values[j].data); 955 if (!list2->dn[list2->count]) { 956 talloc_free(list2); 957 return LDB_ERR_OPERATIONS_ERROR; 958 } 959 list2->count++; 960 } 961 } 962 963 if (list2->count == 0) { 964 talloc_free(list2); 855 if (list->count == 0) { 965 856 return LDB_ERR_NO_SUCH_OBJECT; 966 857 } 967 968 if (list2->count > 1) {969 qsort(list2->dn, list2->count, sizeof(char *), (comparison_fn_t) list_cmp);970 }971 972 if (list->count > 0) {973 if (list_intersect(ldb, list, list2) == -1) {974 talloc_free(list2);975 return LDB_ERR_OPERATIONS_ERROR;976 }977 978 if (list->count == 0) {979 talloc_free(list->dn);980 talloc_free(list2);981 return LDB_ERR_NO_SUCH_OBJECT;982 }983 } else {984 list->dn = talloc_move(list, &list2->dn);985 list->count = list2->count;986 }987 988 talloc_free(list2);989 858 990 859 return LDB_SUCCESS; … … 1050 919 struct ldb_dn *dn; 1051 920 int ret; 921 bool matched; 1052 922 1053 923 msg = ldb_msg_new(ac); … … 1056 926 } 1057 927 1058 dn = ldb_dn_ new(msg, ldb,dn_list->dn[i]);928 dn = ldb_dn_from_ldb_val(msg, ldb, &dn_list->dn[i]); 1059 929 if (dn == NULL) { 1060 930 talloc_free(msg); … … 1076 946 } 1077 947 1078 if (!ldb_match_msg(ldb, msg, 1079 ac->tree, ac->base, ac->scope)) { 948 ret = ldb_match_msg_error(ldb, msg, 949 ac->tree, ac->base, ac->scope, &matched); 950 if (ret != LDB_SUCCESS) { 951 talloc_free(msg); 952 return ret; 953 } 954 if (!matched) { 1080 955 talloc_free(msg); 1081 956 continue; … … 1092 967 ret = ldb_module_send_entry(ac->req, msg, NULL); 1093 968 if (ret != LDB_SUCCESS) { 969 /* Regardless of success or failure, the msg 970 * is the callbacks responsiblity, and should 971 * not be talloc_free()'ed */ 1094 972 ac->request_terminated = true; 1095 973 return ret; … … 1100 978 1101 979 return LDB_SUCCESS; 980 } 981 982 /* 983 remove any duplicated entries in a indexed result 984 */ 985 static void ltdb_dn_list_remove_duplicates(struct dn_list *list) 986 { 987 unsigned int i, new_count; 988 989 if (list->count < 2) { 990 return; 991 } 992 993 TYPESAFE_QSORT(list->dn, list->count, dn_list_cmp); 994 995 new_count = 1; 996 for (i=1; i<list->count; i++) { 997 if (dn_list_cmp(&list->dn[i], &list->dn[new_count-1]) != 0) { 998 if (new_count != i) { 999 list->dn[new_count] = list->dn[i]; 1000 } 1001 new_count++; 1002 } 1003 } 1004 1005 list->count = new_count; 1102 1006 } 1103 1007 … … 1109 1013 int ltdb_search_indexed(struct ltdb_context *ac, uint32_t *match_count) 1110 1014 { 1111 struct ldb_context *ldb; 1112 void *data = ldb_module_get_private(ac->module); 1113 struct ltdb_private *ltdb = talloc_get_type(data, struct ltdb_private); 1015 struct ltdb_private *ltdb = talloc_get_type(ldb_module_get_private(ac->module), struct ltdb_private); 1114 1016 struct dn_list *dn_list; 1115 int ret, idxattr, idxone; 1116 1117 ldb = ldb_module_get_ctx(ac->module); 1118 1119 idxattr = idxone = 0; 1120 ret = ldb_msg_find_idx(ltdb->cache->indexlist, NULL, NULL, LTDB_IDXATTR); 1121 if (ret == 0 ) { 1122 idxattr = 1; 1123 } 1124 1125 /* We do one level indexing only if requested */ 1126 ret = ldb_msg_find_idx(ltdb->cache->indexlist, NULL, NULL, LTDB_IDXONE); 1127 if (ret == 0 ) { 1128 idxone = 1; 1129 } 1130 1131 if ((ac->scope == LDB_SCOPE_ONELEVEL && (idxattr+idxone == 0)) || 1132 (ac->scope == LDB_SCOPE_SUBTREE && idxattr == 0)) { 1133 /* no indexes? must do full search */ 1134 return LDB_ERR_OPERATIONS_ERROR; 1135 } 1136 1137 ret = LDB_ERR_OPERATIONS_ERROR; 1017 int ret; 1018 1019 /* see if indexing is enabled */ 1020 if (!ltdb->cache->attribute_indexes && 1021 !ltdb->cache->one_level_indexes && 1022 ac->scope != LDB_SCOPE_BASE) { 1023 /* fallback to a full search */ 1024 return LDB_ERR_OPERATIONS_ERROR; 1025 } 1138 1026 1139 1027 dn_list = talloc_zero(ac, struct dn_list); 1140 1028 if (dn_list == NULL) { 1141 return LDB_ERR_OPERATIONS_ERROR;1142 } 1143 1144 if (ac->scope == LDB_SCOPE_BASE) {1145 /* with BASE searches only one DN can match */1146 dn_list->dn = talloc_array(dn_list, char *, 1);1029 return ldb_module_oom(ac->module); 1030 } 1031 1032 switch (ac->scope) { 1033 case LDB_SCOPE_BASE: 1034 dn_list->dn = talloc_array(dn_list, struct ldb_val, 1); 1147 1035 if (dn_list->dn == NULL) { 1148 ldb_oom(ldb); 1036 talloc_free(dn_list); 1037 return ldb_module_oom(ac->module); 1038 } 1039 dn_list->dn[0].data = discard_const_p(unsigned char, ldb_dn_get_linearized(ac->base)); 1040 if (dn_list->dn[0].data == NULL) { 1041 talloc_free(dn_list); 1042 return ldb_module_oom(ac->module); 1043 } 1044 dn_list->dn[0].length = strlen((char *)dn_list->dn[0].data); 1045 dn_list->count = 1; 1046 break; 1047 1048 case LDB_SCOPE_ONELEVEL: 1049 if (!ltdb->cache->one_level_indexes) { 1050 talloc_free(dn_list); 1149 1051 return LDB_ERR_OPERATIONS_ERROR; 1150 1052 } 1151 dn_list->dn[0] = ldb_dn_alloc_linearized(dn_list, ac->base); 1152 if (dn_list->dn[0] == NULL) { 1153 ldb_oom(ldb); 1053 ret = ltdb_index_dn_one(ac->module, ac->base, dn_list); 1054 if (ret != LDB_SUCCESS) { 1055 talloc_free(dn_list); 1056 return ret; 1057 } 1058 break; 1059 1060 case LDB_SCOPE_SUBTREE: 1061 case LDB_SCOPE_DEFAULT: 1062 if (!ltdb->cache->attribute_indexes) { 1063 talloc_free(dn_list); 1154 1064 return LDB_ERR_OPERATIONS_ERROR; 1155 1065 } 1156 dn_list->count = 1;1157 ret = LDB_SUCCESS;1158 }1159 1160 if (ac->scope != LDB_SCOPE_BASE && idxattr == 1) {1161 1066 ret = ltdb_index_dn(ac->module, ac->tree, ltdb->cache->indexlist, dn_list); 1162 } 1163 1164 if (ret == LDB_ERR_OPERATIONS_ERROR && 1165 ac->scope == LDB_SCOPE_ONELEVEL && idxone == 1) { 1166 ret = ltdb_index_dn_one(ac->module, ac->base, dn_list); 1167 } 1168 1169 if (ret == LDB_SUCCESS) { 1170 /* we've got a candidate list - now filter by the full tree 1171 and extract the needed attributes */ 1172 ret = ltdb_index_filter(dn_list, ac, match_count); 1173 } 1174 1067 if (ret != LDB_SUCCESS) { 1068 talloc_free(dn_list); 1069 return ret; 1070 } 1071 ltdb_dn_list_remove_duplicates(dn_list); 1072 break; 1073 } 1074 1075 ret = ltdb_index_filter(dn_list, ac, match_count); 1175 1076 talloc_free(dn_list); 1176 1177 1077 return ret; 1178 }1179 1180 /*1181 add a index element where this is the first indexed DN for this value1182 */1183 static int ltdb_index_add1_new(struct ldb_context *ldb,1184 struct ldb_message *msg,1185 const char *dn)1186 {1187 struct ldb_message_element *el;1188 1189 /* add another entry */1190 el = talloc_realloc(msg, msg->elements,1191 struct ldb_message_element, msg->num_elements+1);1192 if (!el) {1193 return LDB_ERR_OPERATIONS_ERROR;1194 }1195 1196 msg->elements = el;1197 msg->elements[msg->num_elements].name = talloc_strdup(msg->elements, LTDB_IDX);1198 if (!msg->elements[msg->num_elements].name) {1199 return LDB_ERR_OPERATIONS_ERROR;1200 }1201 msg->elements[msg->num_elements].num_values = 0;1202 msg->elements[msg->num_elements].values = talloc(msg->elements, struct ldb_val);1203 if (!msg->elements[msg->num_elements].values) {1204 return LDB_ERR_OPERATIONS_ERROR;1205 }1206 msg->elements[msg->num_elements].values[0].length = strlen(dn);1207 msg->elements[msg->num_elements].values[0].data = discard_const_p(uint8_t, dn);1208 msg->elements[msg->num_elements].num_values = 1;1209 msg->num_elements++;1210 1211 return LDB_SUCCESS;1212 }1213 1214 1215 /*1216 add a index element where this is not the first indexed DN for this1217 value1218 */1219 static int ltdb_index_add1_add(struct ldb_context *ldb,1220 struct ldb_message *msg,1221 int idx,1222 const char *dn,1223 const struct ldb_schema_attribute *a)1224 {1225 struct ldb_val *v2;1226 unsigned int i;1227 1228 /* for multi-valued attributes we can end up with repeats */1229 for (i=0;i<msg->elements[idx].num_values;i++) {1230 if (strcmp(dn, (char *)msg->elements[idx].values[i].data) == 0) {1231 return LDB_SUCCESS;1232 }1233 }1234 1235 if (a->flags & LDB_ATTR_FLAG_UNIQUE_INDEX) {1236 return LDB_ERR_ENTRY_ALREADY_EXISTS;1237 }1238 1239 v2 = talloc_realloc(msg->elements, msg->elements[idx].values,1240 struct ldb_val,1241 msg->elements[idx].num_values+1);1242 if (!v2) {1243 return LDB_ERR_OPERATIONS_ERROR;1244 }1245 msg->elements[idx].values = v2;1246 1247 msg->elements[idx].values[msg->elements[idx].num_values].length = strlen(dn);1248 msg->elements[idx].values[msg->elements[idx].num_values].data = discard_const_p(uint8_t, dn);1249 msg->elements[idx].num_values++;1250 1251 return LDB_SUCCESS;1252 1078 } 1253 1079 … … 1259 1085 { 1260 1086 struct ldb_context *ldb; 1261 struct ldb_message *msg;1262 1087 struct ldb_dn *dn_key; 1263 1088 int ret; 1264 unsigned int i;1265 1089 const struct ldb_schema_attribute *a; 1090 struct dn_list *list; 1091 unsigned alloc_len; 1266 1092 1267 1093 ldb = ldb_module_get_ctx(module); 1268 1094 1269 msg = talloc(module, struct ldb_message); 1270 if (msg == NULL) { 1271 errno = ENOMEM; 1095 list = talloc_zero(module, struct dn_list); 1096 if (list == NULL) { 1272 1097 return LDB_ERR_OPERATIONS_ERROR; 1273 1098 } … … 1275 1100 dn_key = ltdb_index_key(ldb, el->name, &el->values[v_idx], &a); 1276 1101 if (!dn_key) { 1277 talloc_free( msg);1278 return LDB_ERR_OPERATIONS_ERROR; 1279 } 1280 talloc_steal( msg, dn_key);1281 1282 ret = ltdb_ search_dn1_index(module, dn_key, msg);1102 talloc_free(list); 1103 return LDB_ERR_OPERATIONS_ERROR; 1104 } 1105 talloc_steal(list, dn_key); 1106 1107 ret = ltdb_dn_list_load(module, dn_key, list); 1283 1108 if (ret != LDB_SUCCESS && ret != LDB_ERR_NO_SUCH_OBJECT) { 1284 talloc_free( msg);1109 talloc_free(list); 1285 1110 return ret; 1286 1111 } 1287 1112 1288 if (ret == LDB_ERR_NO_SUCH_OBJECT) { 1289 msg->dn = dn_key; 1290 msg->num_elements = 0; 1291 msg->elements = NULL; 1292 } 1293 1294 for (i=0;i<msg->num_elements;i++) { 1295 if (strcmp(LTDB_IDX, msg->elements[i].name) == 0) { 1296 break; 1297 } 1298 } 1299 1300 if (i == msg->num_elements) { 1301 ret = ltdb_index_add1_new(ldb, msg, dn); 1302 } else { 1303 ret = ltdb_index_add1_add(ldb, msg, i, dn, a); 1304 } 1305 1306 if (ret == LDB_SUCCESS) { 1307 ret = ltdb_store_idxptr(module, msg, TDB_REPLACE); 1308 } 1309 1310 talloc_free(msg); 1113 if (ltdb_dn_list_find_str(list, dn) != -1) { 1114 talloc_free(list); 1115 return LDB_SUCCESS; 1116 } 1117 1118 if (list->count > 0 && 1119 a->flags & LDB_ATTR_FLAG_UNIQUE_INDEX) { 1120 talloc_free(list); 1121 ldb_asprintf_errstring(ldb, __location__ ": unique index violation on %s in %s", 1122 el->name, dn); 1123 return LDB_ERR_ENTRY_ALREADY_EXISTS; 1124 } 1125 1126 /* overallocate the list a bit, to reduce the number of 1127 * realloc trigered copies */ 1128 alloc_len = ((list->count+1)+7) & ~7; 1129 list->dn = talloc_realloc(list, list->dn, struct ldb_val, alloc_len); 1130 if (list->dn == NULL) { 1131 talloc_free(list); 1132 return LDB_ERR_OPERATIONS_ERROR; 1133 } 1134 list->dn[list->count].data = (uint8_t *)talloc_strdup(list->dn, dn); 1135 list->dn[list->count].length = strlen(dn); 1136 list->count++; 1137 1138 ret = ltdb_dn_list_store(module, dn_key, list); 1139 1140 talloc_free(list); 1311 1141 1312 1142 return ret; 1313 1143 } 1314 1144 1315 static int ltdb_index_add0(struct ldb_module *module, const char *dn, 1316 struct ldb_message_element *elements, int num_el) 1317 { 1318 void *data = ldb_module_get_private(module); 1319 struct ltdb_private *ltdb = talloc_get_type(data, struct ltdb_private); 1320 int ret; 1321 unsigned int i, j; 1145 /* 1146 add index entries for one elements in a message 1147 */ 1148 static int ltdb_index_add_el(struct ldb_module *module, const char *dn, 1149 struct ldb_message_element *el) 1150 { 1151 unsigned int i; 1152 for (i = 0; i < el->num_values; i++) { 1153 int ret = ltdb_index_add1(module, dn, el, i); 1154 if (ret != LDB_SUCCESS) { 1155 return ret; 1156 } 1157 } 1158 1159 return LDB_SUCCESS; 1160 } 1161 1162 /* 1163 add index entries for all elements in a message 1164 */ 1165 static int ltdb_index_add_all(struct ldb_module *module, const char *dn, 1166 struct ldb_message_element *elements, int num_el) 1167 { 1168 struct ltdb_private *ltdb = talloc_get_type(ldb_module_get_private(module), struct ltdb_private); 1169 unsigned int i; 1322 1170 1323 1171 if (dn[0] == '@') { … … 1331 1179 1332 1180 for (i = 0; i < num_el; i++) { 1333 ret = ldb_msg_find_idx(ltdb->cache->indexlist, elements[i].name, 1334 NULL, LTDB_IDXATTR); 1335 if (ret == -1) { 1181 int ret; 1182 if (!ltdb_is_indexed(ltdb->cache->indexlist, elements[i].name)) { 1336 1183 continue; 1337 1184 } 1338 for (j = 0; j < elements[i].num_values; j++) { 1339 ret = ltdb_index_add1(module, dn, &elements[i], j); 1340 if (ret != LDB_SUCCESS) { 1341 return ret; 1342 } 1185 ret = ltdb_index_add_el(module, dn, &elements[i]); 1186 if (ret != LDB_SUCCESS) { 1187 struct ldb_context *ldb = ldb_module_get_ctx(module); 1188 ldb_asprintf_errstring(ldb, 1189 __location__ ": Failed to re-index %s in %s - %s", 1190 elements[i].name, dn, ldb_errstring(ldb)); 1191 return ret; 1343 1192 } 1344 1193 } … … 1347 1196 } 1348 1197 1349 /* 1350 add the index entries for a new record 1351 */ 1352 int ltdb_index_add(struct ldb_module *module, const struct ldb_message *msg) 1353 { 1354 const char *dn; 1355 int ret; 1356 1357 dn = ldb_dn_get_linearized(msg->dn); 1358 if (dn == NULL) { 1359 return LDB_ERR_OPERATIONS_ERROR; 1360 } 1361 1362 ret = ltdb_index_add0(module, dn, msg->elements, msg->num_elements); 1363 1364 return ret; 1365 } 1366 1367 1368 /* 1369 delete an index entry for one message element 1370 */ 1371 int ltdb_index_del_value(struct ldb_module *module, const char *dn, 1372 struct ldb_message_element *el, int v_idx) 1373 { 1374 struct ldb_context *ldb; 1375 struct ldb_message *msg; 1376 struct ldb_dn *dn_key; 1377 int ret, i; 1378 unsigned int j; 1379 1380 ldb = ldb_module_get_ctx(module); 1381 1382 if (dn[0] == '@') { 1383 return LDB_SUCCESS; 1384 } 1385 1386 dn_key = ltdb_index_key(ldb, el->name, &el->values[v_idx], NULL); 1387 if (!dn_key) { 1388 return LDB_ERR_OPERATIONS_ERROR; 1389 } 1390 1391 msg = talloc(dn_key, struct ldb_message); 1392 if (msg == NULL) { 1393 talloc_free(dn_key); 1394 return LDB_ERR_OPERATIONS_ERROR; 1395 } 1396 1397 ret = ltdb_search_dn1_index(module, dn_key, msg); 1398 if (ret != LDB_SUCCESS && ret != LDB_ERR_NO_SUCH_OBJECT) { 1399 talloc_free(dn_key); 1400 return ret; 1401 } 1402 1403 if (ret == LDB_ERR_NO_SUCH_OBJECT) { 1404 /* it wasn't indexed. Did we have an earlier error? If we did then 1405 its gone now */ 1406 talloc_free(dn_key); 1407 return LDB_SUCCESS; 1408 } 1409 1410 i = ldb_msg_find_idx(msg, dn, &j, LTDB_IDX); 1411 if (i == -1) { 1412 struct ldb_ldif ldif; 1413 char *ldif_string; 1414 ldif.changetype = LDB_CHANGETYPE_NONE; 1415 ldif.msg = msg; 1416 ldif_string = ldb_ldif_write_string(ldb, NULL, &ldif); 1417 ldb_debug(ldb, LDB_DEBUG_ERROR, 1418 "ERROR: dn %s not found in %s", dn, 1419 ldif_string); 1420 talloc_free(ldif_string); 1421 /* it ain't there. hmmm */ 1422 talloc_free(dn_key); 1423 return LDB_SUCCESS; 1424 } 1425 1426 if (j != msg->elements[i].num_values - 1) { 1427 memmove(&msg->elements[i].values[j], 1428 &msg->elements[i].values[j+1], 1429 (msg->elements[i].num_values-(j+1)) * 1430 sizeof(msg->elements[i].values[0])); 1431 } 1432 msg->elements[i].num_values--; 1433 1434 if (msg->elements[i].num_values == 0) { 1435 ret = ltdb_delete_noindex(module, dn_key); 1436 } else { 1437 ret = ltdb_store_idxptr(module, msg, TDB_REPLACE); 1438 } 1439 1440 talloc_free(dn_key); 1441 1442 return ret; 1443 } 1444 1445 /* 1446 delete the index entries for a record 1447 return -1 on failure 1448 */ 1449 int ltdb_index_del(struct ldb_module *module, const struct ldb_message *msg) 1450 { 1451 void *data = ldb_module_get_private(module); 1452 struct ltdb_private *ltdb = talloc_get_type(data, struct ltdb_private); 1453 int ret; 1454 const char *dn; 1455 unsigned int i, j; 1456 1457 /* find the list of indexed fields */ 1458 if (ltdb->cache->indexlist->num_elements == 0) { 1459 /* no indexed fields */ 1460 return LDB_SUCCESS; 1461 } 1462 1463 if (ldb_dn_is_special(msg->dn)) { 1464 return LDB_SUCCESS; 1465 } 1466 1467 dn = ldb_dn_get_linearized(msg->dn); 1468 if (dn == NULL) { 1469 return LDB_ERR_OPERATIONS_ERROR; 1470 } 1471 1472 for (i = 0; i < msg->num_elements; i++) { 1473 ret = ldb_msg_find_idx(ltdb->cache->indexlist, msg->elements[i].name, 1474 NULL, LTDB_IDXATTR); 1475 if (ret == -1) { 1476 continue; 1477 } 1478 for (j = 0; j < msg->elements[i].num_values; j++) { 1479 ret = ltdb_index_del_value(module, dn, &msg->elements[i], j); 1480 if (ret != LDB_SUCCESS) { 1481 return ret; 1482 } 1483 } 1484 } 1485 1486 return LDB_SUCCESS; 1487 } 1488 1489 /* 1490 handle special index for one level searches 1491 */ 1492 int ltdb_index_one(struct ldb_module *module, const struct ldb_message *msg, int add) 1493 { 1494 void *data = ldb_module_get_private(module); 1495 struct ltdb_private *ltdb = talloc_get_type(data, struct ltdb_private); 1198 1199 /* 1200 insert a one level index for a message 1201 */ 1202 static int ltdb_index_onelevel(struct ldb_module *module, const struct ldb_message *msg, int add) 1203 { 1204 struct ltdb_private *ltdb = talloc_get_type(ldb_module_get_private(module), struct ltdb_private); 1496 1205 struct ldb_message_element el; 1497 1206 struct ldb_val val; … … 1500 1209 int ret; 1501 1210 1502 if (ldb_dn_is_special(msg->dn)) {1503 return LDB_SUCCESS;1504 }1505 1506 1211 /* We index for ONE Level only if requested */ 1507 ret = ldb_msg_find_idx(ltdb->cache->indexlist, NULL, NULL, LTDB_IDXONE); 1508 if (ret != 0) { 1212 if (!ltdb->cache->one_level_indexes) { 1509 1213 return LDB_SUCCESS; 1510 1214 } … … 1535 1239 ret = ltdb_index_add1(module, dn, &el, 0); 1536 1240 } else { /* delete */ 1537 ret = ltdb_index_del_value(module, dn, &el, 0);1241 ret = ltdb_index_del_value(module, msg->dn, &el, 0); 1538 1242 } 1539 1243 … … 1543 1247 } 1544 1248 1249 /* 1250 add the index entries for a new element in a record 1251 The caller guarantees that these element values are not yet indexed 1252 */ 1253 int ltdb_index_add_element(struct ldb_module *module, struct ldb_dn *dn, 1254 struct ldb_message_element *el) 1255 { 1256 struct ltdb_private *ltdb = talloc_get_type(ldb_module_get_private(module), struct ltdb_private); 1257 if (ldb_dn_is_special(dn)) { 1258 return LDB_SUCCESS; 1259 } 1260 if (!ltdb_is_indexed(ltdb->cache->indexlist, el->name)) { 1261 return LDB_SUCCESS; 1262 } 1263 return ltdb_index_add_el(module, ldb_dn_get_linearized(dn), el); 1264 } 1265 1266 /* 1267 add the index entries for a new record 1268 */ 1269 int ltdb_index_add_new(struct ldb_module *module, const struct ldb_message *msg) 1270 { 1271 const char *dn; 1272 int ret; 1273 1274 if (ldb_dn_is_special(msg->dn)) { 1275 return LDB_SUCCESS; 1276 } 1277 1278 dn = ldb_dn_get_linearized(msg->dn); 1279 if (dn == NULL) { 1280 return LDB_ERR_OPERATIONS_ERROR; 1281 } 1282 1283 ret = ltdb_index_add_all(module, dn, msg->elements, msg->num_elements); 1284 if (ret != LDB_SUCCESS) { 1285 return ret; 1286 } 1287 1288 return ltdb_index_onelevel(module, msg, 1); 1289 } 1290 1291 1292 /* 1293 delete an index entry for one message element 1294 */ 1295 int ltdb_index_del_value(struct ldb_module *module, struct ldb_dn *dn, 1296 struct ldb_message_element *el, unsigned int v_idx) 1297 { 1298 struct ldb_context *ldb; 1299 struct ldb_dn *dn_key; 1300 const char *dn_str; 1301 int ret, i; 1302 unsigned int j; 1303 struct dn_list *list; 1304 1305 ldb = ldb_module_get_ctx(module); 1306 1307 dn_str = ldb_dn_get_linearized(dn); 1308 if (dn_str == NULL) { 1309 return LDB_ERR_OPERATIONS_ERROR; 1310 } 1311 1312 if (dn_str[0] == '@') { 1313 return LDB_SUCCESS; 1314 } 1315 1316 dn_key = ltdb_index_key(ldb, el->name, &el->values[v_idx], NULL); 1317 if (!dn_key) { 1318 return LDB_ERR_OPERATIONS_ERROR; 1319 } 1320 1321 list = talloc_zero(dn_key, struct dn_list); 1322 if (list == NULL) { 1323 talloc_free(dn_key); 1324 return LDB_ERR_OPERATIONS_ERROR; 1325 } 1326 1327 ret = ltdb_dn_list_load(module, dn_key, list); 1328 if (ret == LDB_ERR_NO_SUCH_OBJECT) { 1329 /* it wasn't indexed. Did we have an earlier error? If we did then 1330 its gone now */ 1331 talloc_free(dn_key); 1332 return LDB_SUCCESS; 1333 } 1334 1335 if (ret != LDB_SUCCESS) { 1336 talloc_free(dn_key); 1337 return ret; 1338 } 1339 1340 i = ltdb_dn_list_find_str(list, dn_str); 1341 if (i == -1) { 1342 /* nothing to delete */ 1343 talloc_free(dn_key); 1344 return LDB_SUCCESS; 1345 } 1346 1347 j = (unsigned int) i; 1348 if (j != list->count - 1) { 1349 memmove(&list->dn[j], &list->dn[j+1], sizeof(list->dn[0])*(list->count - (j+1))); 1350 } 1351 list->count--; 1352 list->dn = talloc_realloc(list, list->dn, struct ldb_val, list->count); 1353 1354 ret = ltdb_dn_list_store(module, dn_key, list); 1355 1356 talloc_free(dn_key); 1357 1358 return ret; 1359 } 1360 1361 /* 1362 delete the index entries for a element 1363 return -1 on failure 1364 */ 1365 int ltdb_index_del_element(struct ldb_module *module, struct ldb_dn *dn, 1366 struct ldb_message_element *el) 1367 { 1368 struct ltdb_private *ltdb = talloc_get_type(ldb_module_get_private(module), struct ltdb_private); 1369 const char *dn_str; 1370 int ret; 1371 unsigned int i; 1372 1373 if (!ltdb->cache->attribute_indexes) { 1374 /* no indexed fields */ 1375 return LDB_SUCCESS; 1376 } 1377 1378 dn_str = ldb_dn_get_linearized(dn); 1379 if (dn_str == NULL) { 1380 return LDB_ERR_OPERATIONS_ERROR; 1381 } 1382 1383 if (dn_str[0] == '@') { 1384 return LDB_SUCCESS; 1385 } 1386 1387 if (!ltdb_is_indexed(ltdb->cache->indexlist, el->name)) { 1388 return LDB_SUCCESS; 1389 } 1390 for (i = 0; i < el->num_values; i++) { 1391 ret = ltdb_index_del_value(module, dn, el, i); 1392 if (ret != LDB_SUCCESS) { 1393 return ret; 1394 } 1395 } 1396 1397 return LDB_SUCCESS; 1398 } 1399 1400 /* 1401 delete the index entries for a record 1402 return -1 on failure 1403 */ 1404 int ltdb_index_delete(struct ldb_module *module, const struct ldb_message *msg) 1405 { 1406 struct ltdb_private *ltdb = talloc_get_type(ldb_module_get_private(module), struct ltdb_private); 1407 int ret; 1408 unsigned int i; 1409 1410 if (ldb_dn_is_special(msg->dn)) { 1411 return LDB_SUCCESS; 1412 } 1413 1414 ret = ltdb_index_onelevel(module, msg, 0); 1415 if (ret != LDB_SUCCESS) { 1416 return ret; 1417 } 1418 1419 if (!ltdb->cache->attribute_indexes) { 1420 /* no indexed fields */ 1421 return LDB_SUCCESS; 1422 } 1423 1424 for (i = 0; i < msg->num_elements; i++) { 1425 ret = ltdb_index_del_element(module, msg->dn, &msg->elements[i]); 1426 if (ret != LDB_SUCCESS) { 1427 return ret; 1428 } 1429 } 1430 1431 return LDB_SUCCESS; 1432 } 1433 1545 1434 1546 1435 /* … … 1549 1438 static int delete_index(struct tdb_context *tdb, TDB_DATA key, TDB_DATA data, void *state) 1550 1439 { 1551 const char *dn = "DN=" LTDB_INDEX ":"; 1552 if (strncmp((char *)key.dptr, dn, strlen(dn)) == 0) { 1553 return tdb_delete(tdb, key); 1554 } 1440 struct ldb_module *module = state; 1441 struct ltdb_private *ltdb = talloc_get_type(ldb_module_get_private(module), struct ltdb_private); 1442 const char *dnstr = "DN=" LTDB_INDEX ":"; 1443 struct dn_list list; 1444 struct ldb_dn *dn; 1445 struct ldb_val v; 1446 int ret; 1447 1448 if (strncmp((char *)key.dptr, dnstr, strlen(dnstr)) != 0) { 1449 return 0; 1450 } 1451 /* we need to put a empty list in the internal tdb for this 1452 * index entry */ 1453 list.dn = NULL; 1454 list.count = 0; 1455 1456 /* the offset of 3 is to remove the DN= prefix. */ 1457 v.data = key.dptr + 3; 1458 v.length = strnlen((char *)key.dptr, key.dsize) - 3; 1459 1460 dn = ldb_dn_from_ldb_val(ltdb, ldb_module_get_ctx(module), &v); 1461 ret = ltdb_dn_list_store(module, dn, &list); 1462 if (ret != LDB_SUCCESS) { 1463 ldb_asprintf_errstring(ldb_module_get_ctx(module), 1464 "Unable to store null index for %s\n", 1465 ldb_dn_get_linearized(dn)); 1466 talloc_free(dn); 1467 return -1; 1468 } 1469 talloc_free(dn); 1555 1470 return 0; 1556 1471 } 1557 1472 1473 struct ltdb_reindex_context { 1474 struct ldb_module *module; 1475 int error; 1476 }; 1477 1558 1478 /* 1559 1479 traversal function that adds @INDEX records during a re index … … 1562 1482 { 1563 1483 struct ldb_context *ldb; 1564 struct ldb_module *module = (struct ldb_module *)state; 1484 struct ltdb_reindex_context *ctx = (struct ltdb_reindex_context *)state; 1485 struct ldb_module *module = ctx->module; 1565 1486 struct ldb_message *msg; 1566 1487 const char *dn = NULL; … … 1575 1496 } 1576 1497 1577 msg = talloc(module, struct ldb_message);1498 msg = ldb_msg_new(module); 1578 1499 if (msg == NULL) { 1579 1500 return -1; … … 1583 1504 if (ret != 0) { 1584 1505 ldb_debug(ldb, LDB_DEBUG_ERROR, "Invalid data for index %s\n", 1585 1506 ldb_dn_get_linearized(msg->dn)); 1586 1507 talloc_free(msg); 1587 1508 return -1; … … 1594 1515 /* probably a corrupt record ... darn */ 1595 1516 ldb_debug(ldb, LDB_DEBUG_ERROR, "Invalid DN in re_index: %s", 1596 1517 ldb_dn_get_linearized(msg->dn)); 1597 1518 talloc_free(msg); 1598 1519 return 0; … … 1610 1531 } 1611 1532 1612 ret = ltdb_index_one(module, msg, 1); 1613 if (ret == LDB_SUCCESS) { 1614 ret = ltdb_index_add0(module, dn, msg->elements, msg->num_elements); 1615 } else { 1533 ret = ltdb_index_onelevel(module, msg, 1); 1534 if (ret != LDB_SUCCESS) { 1616 1535 ldb_debug(ldb, LDB_DEBUG_ERROR, 1617 "Adding special ONE LEVEL index failed (%s)!", 1618 ldb_dn_get_linearized(msg->dn)); 1536 "Adding special ONE LEVEL index failed (%s)!", 1537 ldb_dn_get_linearized(msg->dn)); 1538 talloc_free(msg); 1539 return -1; 1540 } 1541 1542 ret = ltdb_index_add_all(module, dn, msg->elements, msg->num_elements); 1543 1544 if (ret != LDB_SUCCESS) { 1545 ctx->error = ret; 1546 talloc_free(msg); 1547 return -1; 1619 1548 } 1620 1549 1621 1550 talloc_free(msg); 1622 1551 1623 if (ret != LDB_SUCCESS) return -1;1624 1625 1552 return 0; 1626 1553 } … … 1631 1558 int ltdb_reindex(struct ldb_module *module) 1632 1559 { 1633 void *data = ldb_module_get_private(module); 1634 struct ltdb_private *ltdb = talloc_get_type(data, struct ltdb_private); 1560 struct ltdb_private *ltdb = talloc_get_type(ldb_module_get_private(module), struct ltdb_private); 1635 1561 int ret; 1562 struct ltdb_reindex_context ctx; 1636 1563 1637 1564 if (ltdb_cache_reload(module) != 0) { … … 1639 1566 } 1640 1567 1641 /* first traverse the database deleting any @INDEX records */ 1642 ret = tdb_traverse(ltdb->tdb, delete_index, NULL); 1568 /* first traverse the database deleting any @INDEX records by 1569 * putting NULL entries in the in-memory tdb 1570 */ 1571 ret = tdb_traverse(ltdb->tdb, delete_index, module); 1643 1572 if (ret == -1) { 1644 1573 return LDB_ERR_OPERATIONS_ERROR; … … 1650 1579 } 1651 1580 1581 ctx.module = module; 1582 ctx.error = 0; 1583 1652 1584 /* now traverse adding any indexes for normal LDB records */ 1653 ret = tdb_traverse(ltdb->tdb, re_index, module);1585 ret = tdb_traverse(ltdb->tdb, re_index, &ctx); 1654 1586 if (ret == -1) { 1655 return LDB_ERR_OPERATIONS_ERROR; 1656 } 1657 1658 if (ltdb->idxptr) { 1659 ltdb->idxptr->repack = true; 1587 struct ldb_context *ldb = ldb_module_get_ctx(module); 1588 ldb_asprintf_errstring(ldb, "reindexing traverse failed: %s", ldb_errstring(ldb)); 1589 return LDB_ERR_OPERATIONS_ERROR; 1590 } 1591 1592 if (ctx.error != LDB_SUCCESS) { 1593 struct ldb_context *ldb = ldb_module_get_ctx(module); 1594 ldb_asprintf_errstring(ldb, "reindexing failed: %s", ldb_errstring(ldb)); 1595 return ctx.error; 1660 1596 } 1661 1597 -
vendor/current/source4/lib/ldb/ldb_tdb/ldb_pack.c
r414 r740 59 59 { 60 60 if (el->num_values == 0) return 0; 61 62 if (ldb_attr_cmp(el->name, "dn") == 0) return 0;63 61 64 62 if (ldb_attr_cmp(el->name, "distinguishedName") == 0) return 0; … … 209 207 210 208 if (message->num_elements == 0) { 211 message->elements = NULL;212 209 return 0; 213 210 } -
vendor/current/source4/lib/ldb/ldb_tdb/ldb_search.c
r414 r740 79 79 80 80 elnew->num_values = el->num_values; 81 elnew->flags = el->flags; 81 82 82 83 ret->num_elements++; … … 98 99 el.num_values = 1; 99 100 el.values = &val; 101 el.flags = 0; 100 102 val.data = (uint8_t *)ldb_dn_alloc_linearized(msg, msg->dn); 101 103 val.length = strlen((char *)val.data); … … 146 148 { 147 149 struct ldb_message *ret; 148 int i;150 unsigned int i; 149 151 150 152 ret = talloc(mem_ctx, struct ldb_message); … … 326 328 int ltdb_filter_attrs(struct ldb_message *msg, const char * const *attrs) 327 329 { 328 int i, keep_all = 0; 330 unsigned int i; 331 int keep_all = 0; 332 struct ldb_message_element *el2; 333 uint32_t num_elements; 329 334 330 335 if (attrs) { … … 353 358 } 354 359 360 el2 = talloc_array(msg, struct ldb_message_element, msg->num_elements); 361 if (el2 == NULL) { 362 return -1; 363 } 364 num_elements = 0; 365 355 366 for (i = 0; i < msg->num_elements; i++) { 356 int j, found; 367 unsigned int j; 368 int found = 0; 357 369 358 for (j = 0 , found = 0; attrs[j]; j++) {370 for (j = 0; attrs[j]; j++) { 359 371 if (ldb_attr_cmp(msg->elements[i].name, attrs[j]) == 0) { 360 372 found = 1; … … 363 375 } 364 376 365 if (!found) { 366 ldb_msg_remove_attr(msg, msg->elements[i].name); 367 i--; 368 } 369 } 377 if (found) { 378 el2[num_elements] = msg->elements[i]; 379 talloc_steal(el2, el2[num_elements].name); 380 talloc_steal(el2, el2[num_elements].values); 381 num_elements++; 382 } 383 } 384 385 talloc_free(msg->elements); 386 msg->elements = talloc_realloc(msg, el2, struct ldb_message_element, msg->num_elements); 387 if (msg->elements == NULL) { 388 return -1; 389 } 390 msg->num_elements = num_elements; 370 391 371 392 return 0; … … 381 402 struct ldb_message *msg; 382 403 int ret; 404 bool matched; 383 405 384 406 ac = talloc_get_type(state, struct ltdb_context); … … 412 434 413 435 /* see if it matches the given expression */ 414 if (!ldb_match_msg(ldb, msg, 415 ac->tree, ac->base, ac->scope)) { 436 ret = ldb_match_msg_error(ldb, msg, 437 ac->tree, ac->base, ac->scope, &matched); 438 if (ret != LDB_SUCCESS) { 439 talloc_free(msg); 440 return -1; 441 } 442 if (!matched) { 416 443 talloc_free(msg); 417 444 return 0; … … 552 579 if ( ! ctx->request_terminated && ret != LDB_SUCCESS) { 553 580 /* Not indexed, so we need to do a full scan */ 554 #if 0 555 /* useful for debugging when slow performance 556 * is caused by unindexed searches */ 557 char *expression = ldb_filter_from_tree(ctx, ctx->tree); 558 printf("FULL SEARCH: %s\n", expression); 559 talloc_free(expression); 560 #endif 581 if (ltdb->warn_unindexed) { 582 /* useful for debugging when slow performance 583 * is caused by unindexed searches */ 584 char *expression = ldb_filter_from_tree(ctx, ctx->tree); 585 ldb_debug(ldb, LDB_DEBUG_WARNING, "ldb FULL SEARCH: %s SCOPE: %s DN: %s\n", 586 expression, 587 req->op.search.scope==LDB_SCOPE_BASE?"base": 588 req->op.search.scope==LDB_SCOPE_ONELEVEL?"one": 589 req->op.search.scope==LDB_SCOPE_SUBTREE?"sub":"UNKNOWN", 590 ldb_dn_get_linearized(req->op.search.base)); 591 592 talloc_free(expression); 593 } 561 594 if (match_count != 0) { 562 595 /* the indexing code gave an error … … 568 601 * duplicate entries 569 602 */ 603 ltdb_unlock_read(module); 570 604 return LDB_ERR_OPERATIONS_ERROR; 571 605 } -
vendor/current/source4/lib/ldb/ldb_tdb/ldb_tdb.c
r414 r740 2 2 ldb database library 3 3 4 Copyright (C) Andrew Tridgell 5 Copyright (C) Stefan Metzmacher 6 Copyright (C) Simo Sorce 7 4 Copyright (C) Andrew Tridgell 2004 5 Copyright (C) Stefan Metzmacher 2004 6 Copyright (C) Simo Sorce 2006-2008 7 Copyright (C) Matthias Dieter Wallnöfer 2009-2010 8 8 9 9 ** NOTE! The following LGPL license applies to the ldb … … 37 37 * Modifications: 38 38 * 39 * - description: make the module use async ronous calls39 * - description: make the module use asynchronous calls 40 40 * date: Feb 2006 41 41 * Author: Simo Sorce … … 44 44 * date: Jan 2008 45 45 * Author: Simo Sorce 46 * 47 * - description: fix up memory leaks and small bugs 48 * date: Oct 2009 49 * Author: Matthias Dieter Wallnöfer 46 50 */ 47 51 … … 52 56 map a tdb error code to a ldb error code 53 57 */ 54 staticint ltdb_err_map(enum TDB_ERROR tdb_code)58 int ltdb_err_map(enum TDB_ERROR tdb_code) 55 59 { 56 60 switch (tdb_code) { … … 74 78 case TDB_ERR_RDONLY: 75 79 return LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS; 80 default: 81 break; 76 82 } 77 83 return LDB_ERR_OTHER; … … 85 91 void *data = ldb_module_get_private(module); 86 92 struct ltdb_private *ltdb = talloc_get_type(data, struct ltdb_private); 87 if (ltdb->in_transaction == 0) { 88 return tdb_lockall_read(ltdb->tdb); 89 } 90 return 0; 93 int ret = 0; 94 95 if (ltdb->in_transaction == 0 && 96 ltdb->read_lock_count == 0) { 97 ret = tdb_lockall_read(ltdb->tdb); 98 } 99 if (ret == 0) { 100 ltdb->read_lock_count++; 101 } 102 return ret; 91 103 } 92 104 … … 98 110 void *data = ldb_module_get_private(module); 99 111 struct ltdb_private *ltdb = talloc_get_type(data, struct ltdb_private); 100 if (ltdb->in_transaction == 0 ) {112 if (ltdb->in_transaction == 0 && ltdb->read_lock_count == 1) { 101 113 return tdb_unlockall_read(ltdb->tdb); 102 114 } 115 ltdb->read_lock_count--; 103 116 return 0; 104 117 } … … 163 176 */ 164 177 static int ltdb_check_special_dn(struct ldb_module *module, 165 178 const struct ldb_message *msg) 166 179 { 167 180 struct ldb_context *ldb = ldb_module_get_ctx(module); 168 int i, j;181 unsigned int i, j; 169 182 170 183 if (! ldb_dn_is_special(msg->dn) || 171 184 ! ldb_dn_check_special(msg->dn, LTDB_ATTRIBUTES)) { 172 return 0;185 return LDB_SUCCESS; 173 186 } 174 187 … … 176 189 /* should we check that we deny multivalued attributes ? */ 177 190 for (i = 0; i < msg->num_elements; i++) { 191 if (ldb_attr_cmp(msg->elements[i].name, "distinguishedName") == 0) continue; 192 178 193 for (j = 0; j < msg->elements[i].num_values; j++) { 179 194 if (ltdb_check_at_attributes_values(&msg->elements[i].values[j]) != 0) { … … 184 199 } 185 200 186 return 0;201 return LDB_SUCCESS; 187 202 } 188 203 … … 195 210 { 196 211 int ret = LDB_SUCCESS; 212 struct ltdb_private *ltdb = talloc_get_type(ldb_module_get_private(module), struct ltdb_private); 213 214 /* only allow modifies inside a transaction, otherwise the 215 * ldb is unsafe */ 216 if (ltdb->in_transaction == 0) { 217 ldb_set_errstring(ldb_module_get_ctx(module), "ltdb modify without transaction"); 218 return LDB_ERR_OPERATIONS_ERROR; 219 } 197 220 198 221 if (ldb_dn_is_special(dn) && … … 202 225 } 203 226 227 /* If the modify was to a normal record, or any special except @BASEINFO, update the seq number */ 204 228 if (ret == LDB_SUCCESS && 205 229 !(ldb_dn_is_special(dn) && … … 208 232 } 209 233 234 /* If the modify was to @OPTIONS, reload the cache */ 235 if (ret == LDB_SUCCESS && 236 ldb_dn_is_special(dn) && 237 (ldb_dn_check_special(dn, LTDB_OPTIONS)) ) { 238 ret = ltdb_cache_reload(module); 239 } 240 210 241 return ret; 211 242 } … … 219 250 struct ltdb_private *ltdb = talloc_get_type(data, struct ltdb_private); 220 251 TDB_DATA tdb_key, tdb_data; 221 int ret ;252 int ret = LDB_SUCCESS; 222 253 223 254 tdb_key = ltdb_key(module, msg->dn); 224 if ( !tdb_key.dptr) {255 if (tdb_key.dptr == NULL) { 225 256 return LDB_ERR_OTHER; 226 257 } … … 238 269 } 239 270 240 ret = ltdb_index_add(module, msg);241 if (ret != LDB_SUCCESS) {242 tdb_delete(ltdb->tdb, tdb_key);243 }244 245 271 done: 246 272 talloc_free(tdb_key.dptr); … … 251 277 252 278 279 /* 280 check if a attribute is a single valued, for a given element 281 */ 282 static bool ldb_tdb_single_valued(const struct ldb_schema_attribute *a, 283 struct ldb_message_element *el) 284 { 285 if (!a) return false; 286 if (el != NULL) { 287 if (el->flags & LDB_FLAG_INTERNAL_FORCE_SINGLE_VALUE_CHECK) { 288 /* override from a ldb module, for example 289 used for the description field, which is 290 marked multi-valued in the schema but which 291 should not actually accept multiple 292 values */ 293 return true; 294 } 295 if (el->flags & LDB_FLAG_INTERNAL_DISABLE_SINGLE_VALUE_CHECK) { 296 /* override from a ldb module, for example used for 297 deleted linked attribute entries */ 298 return false; 299 } 300 } 301 if (a->flags & LDB_ATTR_FLAG_SINGLE_VALUE) { 302 return true; 303 } 304 return false; 305 } 306 253 307 static int ltdb_add_internal(struct ldb_module *module, 254 308 const struct ldb_message *msg) 255 309 { 256 310 struct ldb_context *ldb = ldb_module_get_ctx(module); 257 int ret, i; 258 259 ret = ltdb_check_special_dn(module, msg); 260 if (ret != LDB_SUCCESS) { 261 return ret; 262 } 263 264 if (ltdb_cache_load(module) != 0) { 265 return LDB_ERR_OPERATIONS_ERROR; 266 } 311 int ret = LDB_SUCCESS; 312 unsigned int i; 267 313 268 314 for (i=0;i<msg->num_elements;i++) { … … 271 317 272 318 if (el->num_values == 0) { 273 ldb_asprintf_errstring(ldb, "attribute %s on %s specified, but with 0 values (illegal)",319 ldb_asprintf_errstring(ldb, "attribute '%s' on '%s' specified, but with 0 values (illegal)", 274 320 el->name, ldb_dn_get_linearized(msg->dn)); 275 321 return LDB_ERR_CONSTRAINT_VIOLATION; 276 322 } 277 if (a && a->flags & LDB_ATTR_FLAG_SINGLE_VALUE) { 278 if (el->num_values > 1) { 279 ldb_asprintf_errstring(ldb, "SINGLE-VALUE attribute %s on %s speicified more than once", 280 el->name, ldb_dn_get_linearized(msg->dn)); 281 return LDB_ERR_CONSTRAINT_VIOLATION; 282 } 323 if (el->num_values > 1 && ldb_tdb_single_valued(a, el)) { 324 ldb_asprintf_errstring(ldb, "SINGLE-VALUE attribute %s on %s specified more than once", 325 el->name, ldb_dn_get_linearized(msg->dn)); 326 return LDB_ERR_CONSTRAINT_VIOLATION; 283 327 } 284 328 } 285 329 286 330 ret = ltdb_store(module, msg, TDB_INSERT); 287 288 if (ret == LDB_ERR_ENTRY_ALREADY_EXISTS) { 289 ldb_asprintf_errstring(ldb, 290 "Entry %s already exists", 291 ldb_dn_get_linearized(msg->dn)); 331 if (ret != LDB_SUCCESS) { 332 if (ret == LDB_ERR_ENTRY_ALREADY_EXISTS) { 333 ldb_asprintf_errstring(ldb, 334 "Entry %s already exists", 335 ldb_dn_get_linearized(msg->dn)); 336 } 292 337 return ret; 293 338 } 294 339 295 if (ret == LDB_SUCCESS) { 296 ret = ltdb_index_one(module, msg, 1); 297 if (ret != LDB_SUCCESS) { 298 return ret; 299 } 300 301 ret = ltdb_modified(module, msg->dn); 302 if (ret != LDB_SUCCESS) { 303 return ret; 304 } 305 } 340 ret = ltdb_index_add_new(module, msg); 341 if (ret != LDB_SUCCESS) { 342 return ret; 343 } 344 345 ret = ltdb_modified(module, msg->dn); 306 346 307 347 return ret; … … 315 355 struct ldb_module *module = ctx->module; 316 356 struct ldb_request *req = ctx->req; 317 int tret; 357 int ret = LDB_SUCCESS; 358 359 ret = ltdb_check_special_dn(module, req->op.add.message); 360 if (ret != LDB_SUCCESS) { 361 return ret; 362 } 318 363 319 364 ldb_request_set_state(req, LDB_ASYNC_PENDING); 320 365 321 tret = ltdb_add_internal(module, req->op.add.message); 322 if (tret != LDB_SUCCESS) { 323 return tret; 324 } 325 326 return LDB_SUCCESS; 366 if (ltdb_cache_load(module) != 0) { 367 return LDB_ERR_OPERATIONS_ERROR; 368 } 369 370 ret = ltdb_add_internal(module, req->op.add.message); 371 372 return ret; 327 373 } 328 374 … … 356 402 { 357 403 struct ldb_message *msg; 358 int ret ;359 360 msg = talloc(module, struct ldb_message);404 int ret = LDB_SUCCESS; 405 406 msg = ldb_msg_new(module); 361 407 if (msg == NULL) { 362 408 return LDB_ERR_OPERATIONS_ERROR; … … 376 422 } 377 423 378 /* remove one level attribute */379 ret = ltdb_index_one(module, msg, 0);380 if (ret != LDB_SUCCESS) {381 goto done;382 }383 384 424 /* remove any indexed attributes */ 385 ret = ltdb_index_del (module, msg);425 ret = ltdb_index_delete(module, msg); 386 426 if (ret != LDB_SUCCESS) { 387 427 goto done; … … 405 445 struct ldb_module *module = ctx->module; 406 446 struct ldb_request *req = ctx->req; 407 int tret;447 int ret = LDB_SUCCESS; 408 448 409 449 ldb_request_set_state(req, LDB_ASYNC_PENDING); … … 413 453 } 414 454 415 tret = ltdb_delete_internal(module, req->op.del.dn); 416 if (tret != LDB_SUCCESS) { 417 return tret; 418 } 419 420 return LDB_SUCCESS; 455 ret = ltdb_delete_internal(module, req->op.del.dn); 456 457 return ret; 421 458 } 422 459 … … 447 484 returns 0 on success, -1 on failure (and sets errno) 448 485 */ 449 static int msg_add_element(struct ldb_context *ldb,450 451 486 static int ltdb_msg_add_element(struct ldb_context *ldb, 487 struct ldb_message *msg, 488 struct ldb_message_element *el) 452 489 { 453 490 struct ldb_message_element *e2; 454 491 unsigned int i; 492 493 if (el->num_values == 0) { 494 /* nothing to do here - we don't add empty elements */ 495 return 0; 496 } 455 497 456 498 e2 = talloc_realloc(msg, msg->elements, struct ldb_message_element, … … 467 509 e2->name = el->name; 468 510 e2->flags = el->flags; 469 e2->values = NULL; 470 if (el->num_values != 0) { 471 e2->values = talloc_array(msg->elements, 472 struct ldb_val, el->num_values); 473 if (!e2->values) { 474 errno = ENOMEM; 475 return -1; 476 } 511 e2->values = talloc_array(msg->elements, 512 struct ldb_val, el->num_values); 513 if (!e2->values) { 514 errno = ENOMEM; 515 return -1; 477 516 } 478 517 for (i=0;i<el->num_values;i++) { … … 481 520 e2->num_values = el->num_values; 482 521 483 msg->num_elements++;522 ++msg->num_elements; 484 523 485 524 return 0; … … 493 532 struct ldb_message *msg, const char *name) 494 533 { 495 const char *dn; 496 unsigned int i, j; 497 498 dn = ldb_dn_get_linearized(msg->dn); 499 if (dn == NULL) { 500 return -1; 501 } 502 503 for (i=0;i<msg->num_elements;i++) { 504 if (ldb_attr_cmp(msg->elements[i].name, name) == 0) { 505 for (j=0;j<msg->elements[i].num_values;j++) { 506 ltdb_index_del_value(module, dn, 507 &msg->elements[i], j); 508 } 509 talloc_free(msg->elements[i].values); 510 if (msg->num_elements > (i+1)) { 511 memmove(&msg->elements[i], 512 &msg->elements[i+1], 513 sizeof(struct ldb_message_element)* 514 (msg->num_elements - (i+1))); 515 } 516 msg->num_elements--; 517 i--; 518 msg->elements = talloc_realloc(msg, msg->elements, 519 struct ldb_message_element, 520 msg->num_elements); 521 } 522 } 523 524 return 0; 534 unsigned int i; 535 int ret; 536 struct ldb_message_element *el; 537 538 el = ldb_msg_find_element(msg, name); 539 if (el == NULL) { 540 return LDB_ERR_NO_SUCH_ATTRIBUTE; 541 } 542 i = el - msg->elements; 543 544 ret = ltdb_index_del_element(module, msg->dn, el); 545 if (ret != LDB_SUCCESS) { 546 return ret; 547 } 548 549 talloc_free(el->values); 550 if (msg->num_elements > (i+1)) { 551 memmove(el, el+1, sizeof(*el) * (msg->num_elements - (i+1))); 552 } 553 msg->num_elements--; 554 msg->elements = talloc_realloc(msg, msg->elements, 555 struct ldb_message_element, 556 msg->num_elements); 557 return LDB_SUCCESS; 525 558 } 526 559 … … 528 561 delete all elements matching an attribute name/value 529 562 530 return 0 on success, -1on failure563 return LDB Error on failure 531 564 */ 532 565 static int msg_delete_element(struct ldb_module *module, … … 537 570 struct ldb_context *ldb = ldb_module_get_ctx(module); 538 571 unsigned int i; 539 int found ;572 int found, ret; 540 573 struct ldb_message_element *el; 541 574 const struct ldb_schema_attribute *a; … … 543 576 found = find_element(msg, name); 544 577 if (found == -1) { 545 return -1; 546 } 547 548 el = &msg->elements[found]; 578 return LDB_ERR_NO_SUCH_ATTRIBUTE; 579 } 580 581 i = (unsigned int) found; 582 el = &(msg->elements[i]); 549 583 550 584 a = ldb_schema_attribute_by_name(ldb, el->name); 551 585 552 586 for (i=0;i<el->num_values;i++) { 553 if (a->syntax->comparison_fn(ldb, ldb, 554 &el->values[i], val) == 0) { 587 bool matched; 588 if (a->syntax->operator_fn) { 589 ret = a->syntax->operator_fn(ldb, LDB_OP_EQUALITY, a, 590 &el->values[i], val, &matched); 591 if (ret != LDB_SUCCESS) return ret; 592 } else { 593 matched = (a->syntax->comparison_fn(ldb, ldb, 594 &el->values[i], val) == 0); 595 } 596 if (matched) { 597 if (el->num_values == 1) { 598 return msg_delete_attribute(module, ldb, msg, name); 599 } 600 601 ret = ltdb_index_del_value(module, msg->dn, el, i); 602 if (ret != LDB_SUCCESS) { 603 return ret; 604 } 605 555 606 if (i<el->num_values-1) { 556 607 memmove(&el->values[i], &el->values[i+1], … … 559 610 } 560 611 el->num_values--; 561 if (el->num_values == 0) { 562 return msg_delete_attribute(module, ldb, 563 msg, name); 564 } 565 return 0; 612 613 /* per definition we find in a canonicalised message an 614 attribute value only once. So we are finished here */ 615 return LDB_SUCCESS; 566 616 } 567 617 } 568 618 569 return -1; 619 /* Not found */ 620 return LDB_ERR_NO_SUCH_ATTRIBUTE; 570 621 } 571 622 … … 577 628 get away with it, but if we ever have really large attribute lists 578 629 then we'll need to look at this again 630 631 'req' is optional, and is used to specify controls if supplied 579 632 */ 580 633 int ltdb_modify_internal(struct ldb_module *module, 581 const struct ldb_message *msg) 634 const struct ldb_message *msg, 635 struct ldb_request *req) 582 636 { 583 637 struct ldb_context *ldb = ldb_module_get_ctx(module); … … 586 640 TDB_DATA tdb_key, tdb_data; 587 641 struct ldb_message *msg2; 588 unsigned i, j; 589 int ret, idx; 642 unsigned int i, j, k; 643 int ret = LDB_SUCCESS, idx; 644 struct ldb_control *control_permissive = NULL; 645 646 if (req) { 647 control_permissive = ldb_request_get_control(req, 648 LDB_CONTROL_PERMISSIVE_MODIFY_OID); 649 } 590 650 591 651 tdb_key = ltdb_key(module, msg->dn); … … 600 660 } 601 661 602 msg2 = talloc(tdb_key.dptr, struct ldb_message);662 msg2 = ldb_msg_new(tdb_key.dptr); 603 663 if (msg2 == NULL) { 604 talloc_free(tdb_key.dptr); 605 return LDB_ERR_OTHER; 664 free(tdb_data.dptr); 665 ret = LDB_ERR_OTHER; 666 goto done; 606 667 } 607 668 608 669 ret = ltdb_unpack_data(module, &tdb_data, msg2); 670 free(tdb_data.dptr); 609 671 if (ret == -1) { 610 672 ret = LDB_ERR_OTHER; 611 goto failed;673 goto done; 612 674 } 613 675 … … 616 678 } 617 679 618 for (i=0;i<msg->num_elements;i++) { 619 struct ldb_message_element *el = &msg->elements[i]; 620 struct ldb_message_element *el2; 680 for (i=0; i<msg->num_elements; i++) { 681 struct ldb_message_element *el = &msg->elements[i], *el2; 621 682 struct ldb_val *vals; 683 const struct ldb_schema_attribute *a = ldb_schema_attribute_by_name(ldb, el->name); 622 684 const char *dn; 623 const struct ldb_schema_attribute *a = ldb_schema_attribute_by_name(ldb, el->name); 685 624 686 switch (msg->elements[i].flags & LDB_FLAG_MOD_MASK) { 625 626 687 case LDB_FLAG_MOD_ADD: 627 628 /* add this element to the message. fail if it 629 already exists */ 688 689 if (el->num_values == 0) { 690 ldb_asprintf_errstring(ldb, 691 "attribute '%s': attribute on '%s' specified, but with 0 values (illegal)", 692 el->name, ldb_dn_get_linearized(msg2->dn)); 693 ret = LDB_ERR_CONSTRAINT_VIOLATION; 694 goto done; 695 } 696 697 /* make a copy of the array so that a permissive 698 * control can remove duplicates without changing the 699 * original values, but do not copy data as we do not 700 * need to keep it around once the operation is 701 * finished */ 702 if (control_permissive) { 703 el = talloc(msg2, struct ldb_message_element); 704 if (!el) { 705 ret = LDB_ERR_OTHER; 706 goto done; 707 } 708 *el = msg->elements[i]; 709 el->values = talloc_array(el, struct ldb_val, el->num_values); 710 if (el->values == NULL) { 711 ret = LDB_ERR_OTHER; 712 goto done; 713 } 714 for (j = 0; j < el->num_values; j++) { 715 el->values[j] = msg->elements[i].values[j]; 716 } 717 } 718 719 if (el->num_values > 1 && ldb_tdb_single_valued(a, el)) { 720 ldb_asprintf_errstring(ldb, "SINGLE-VALUE attribute %s on %s specified more than once", 721 el->name, ldb_dn_get_linearized(msg2->dn)); 722 ret = LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS; 723 goto done; 724 } 725 726 /* Checks if element already exists */ 630 727 idx = find_element(msg2, el->name); 631 632 if (el->num_values == 0) {633 ldb_asprintf_errstring(ldb, "attribute %s on %s speicified, but with 0 values (illigal)",634 el->name, ldb_dn_get_linearized(msg->dn));635 return LDB_ERR_CONSTRAINT_VIOLATION;636 }637 728 if (idx == -1) { 638 if (a && a->flags & LDB_ATTR_FLAG_SINGLE_VALUE) { 639 if (el->num_values > 1) { 640 ldb_asprintf_errstring(ldb, "SINGLE-VALUE attribute %s on %s speicified more than once", 641 el->name, ldb_dn_get_linearized(msg->dn)); 642 return LDB_ERR_CONSTRAINT_VIOLATION; 729 if (ltdb_msg_add_element(ldb, msg2, el) != 0) { 730 ret = LDB_ERR_OTHER; 731 goto done; 732 } 733 ret = ltdb_index_add_element(module, msg2->dn, 734 el); 735 if (ret != LDB_SUCCESS) { 736 goto done; 737 } 738 } else { 739 j = (unsigned int) idx; 740 el2 = &(msg2->elements[j]); 741 742 /* We cannot add another value on a existing one 743 if the attribute is single-valued */ 744 if (ldb_tdb_single_valued(a, el)) { 745 ldb_asprintf_errstring(ldb, "SINGLE-VALUE attribute %s on %s specified more than once", 746 el->name, ldb_dn_get_linearized(msg2->dn)); 747 ret = LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS; 748 goto done; 749 } 750 751 /* Check that values don't exist yet on multi- 752 valued attributes or aren't provided twice */ 753 for (j = 0; j < el->num_values; j++) { 754 if (ldb_msg_find_val(el2, &el->values[j]) != NULL) { 755 if (control_permissive) { 756 /* remove this one as if it was never added */ 757 el->num_values--; 758 for (k = j; k < el->num_values; k++) { 759 el->values[k] = el->values[k + 1]; 760 } 761 j--; /* rewind */ 762 763 continue; 764 } 765 766 ldb_asprintf_errstring(ldb, 767 "attribute '%s': value #%u on '%s' already exists", 768 el->name, j, ldb_dn_get_linearized(msg2->dn)); 769 ret = LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS; 770 goto done; 771 } 772 if (ldb_msg_find_val(el, &el->values[j]) != &el->values[j]) { 773 ldb_asprintf_errstring(ldb, 774 "attribute '%s': value #%u on '%s' provided more than once", 775 el->name, j, ldb_dn_get_linearized(msg2->dn)); 776 ret = LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS; 777 goto done; 643 778 } 644 779 } 645 if (msg_add_element(ldb, msg2, el) != 0) { 780 781 /* Now combine existing and new values to a new 782 attribute record */ 783 vals = talloc_realloc(msg2->elements, 784 el2->values, struct ldb_val, 785 el2->num_values + el->num_values); 786 if (vals == NULL) { 787 ldb_oom(ldb); 646 788 ret = LDB_ERR_OTHER; 647 goto failed;789 goto done; 648 790 } 649 continue; 650 } 651 652 /* If this is an add, then if it already 653 * exists in the object, then we violoate the 654 * single-value rule */ 655 if (a && a->flags & LDB_ATTR_FLAG_SINGLE_VALUE) { 656 return LDB_ERR_CONSTRAINT_VIOLATION; 657 } 658 659 el2 = &msg2->elements[idx]; 660 661 /* An attribute with this name already exists, 662 * add all values if they don't already exist 663 * (check both the other elements to be added, 664 * and those already in the db). */ 665 666 for (j=0;j<el->num_values;j++) { 667 if (ldb_msg_find_val(el2, &el->values[j])) { 668 ldb_asprintf_errstring(ldb, "%s: value #%d already exists", el->name, j); 669 ret = LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS; 670 goto failed; 791 792 for (j=0; j<el->num_values; j++) { 793 vals[el2->num_values + j] = 794 ldb_val_dup(vals, &el->values[j]); 671 795 } 672 if (ldb_msg_find_val(el, &el->values[j]) != &el->values[j]) { 673 ldb_asprintf_errstring(ldb, "%s: value #%d provided more than once", el->name, j); 674 ret = LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS; 675 goto failed; 796 797 el2->values = vals; 798 el2->num_values += el->num_values; 799 800 ret = ltdb_index_add_element(module, msg2->dn, el); 801 if (ret != LDB_SUCCESS) { 802 goto done; 676 803 } 677 804 } 678 805 679 vals = talloc_realloc(msg2->elements, el2->values, struct ldb_val, 680 el2->num_values + el->num_values); 681 682 if (vals == NULL) { 683 ret = LDB_ERR_OTHER; 684 goto failed; 806 break; 807 808 case LDB_FLAG_MOD_REPLACE: 809 810 if (el->num_values > 1 && ldb_tdb_single_valued(a, el)) { 811 ldb_asprintf_errstring(ldb, "SINGLE-VALUE attribute %s on %s specified more than once", 812 el->name, ldb_dn_get_linearized(msg2->dn)); 813 ret = LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS; 814 goto done; 685 815 } 686 816 687 for (j=0;j<el->num_values;j++) { 688 vals[el2->num_values + j] = 689 ldb_val_dup(vals, &el->values[j]); 690 } 691 692 el2->values = vals; 693 el2->num_values += el->num_values; 694 695 break; 696 697 case LDB_FLAG_MOD_REPLACE: 698 if (a && a->flags & LDB_ATTR_FLAG_SINGLE_VALUE) { 699 if (el->num_values > 1) { 700 ldb_asprintf_errstring(ldb, "SINGLE-VALUE attribute %s on %s speicified more than once", 701 el->name, ldb_dn_get_linearized(msg->dn)); 702 return LDB_ERR_CONSTRAINT_VIOLATION; 817 /* TODO: This is O(n^2) - replace with more efficient check */ 818 for (j=0; j<el->num_values; j++) { 819 if (ldb_msg_find_val(el, &el->values[j]) != &el->values[j]) { 820 ldb_asprintf_errstring(ldb, 821 "attribute '%s': value #%u on '%s' provided more than once", 822 el->name, j, ldb_dn_get_linearized(msg2->dn)); 823 ret = LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS; 824 goto done; 703 825 } 704 826 } 705 /* replace all elements of this attribute name with the elements 706 listed. The attribute not existing is not an error */ 707 msg_delete_attribute(module, ldb, msg2, el->name); 708 709 for (j=0;j<el->num_values;j++) { 710 if (ldb_msg_find_val(el, &el->values[j]) != &el->values[j]) { 711 ldb_asprintf_errstring(ldb, "%s: value #%d provided more than once", el->name, j); 712 ret = LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS; 713 goto failed; 827 828 /* Checks if element already exists */ 829 idx = find_element(msg2, el->name); 830 if (idx != -1) { 831 j = (unsigned int) idx; 832 el2 = &(msg2->elements[j]); 833 if (ldb_msg_element_compare(el, el2) == 0) { 834 /* we are replacing with the same values */ 835 continue; 836 } 837 838 /* Delete the attribute if it exists in the DB */ 839 if (msg_delete_attribute(module, ldb, msg2, 840 el->name) != 0) { 841 ret = LDB_ERR_OTHER; 842 goto done; 714 843 } 715 844 } 716 845 717 /* add the replacement element, if not empty */ 718 if (el->num_values != 0 && 719 msg_add_element(ldb, msg2, el) != 0) { 846 /* Recreate it with the new values */ 847 if (ltdb_msg_add_element(ldb, msg2, el) != 0) { 720 848 ret = LDB_ERR_OTHER; 721 goto failed;849 goto done; 722 850 } 851 852 ret = ltdb_index_add_element(module, msg2->dn, el); 853 if (ret != LDB_SUCCESS) { 854 goto done; 855 } 856 723 857 break; 724 858 725 859 case LDB_FLAG_MOD_DELETE: 726 727 dn = ldb_dn_get_linearized(msg->dn); 860 dn = ldb_dn_get_linearized(msg2->dn); 728 861 if (dn == NULL) { 729 862 ret = LDB_ERR_OTHER; 730 goto failed;863 goto done; 731 864 } 732 865 733 /* we could be being asked to delete all734 values or just some values */735 866 if (msg->elements[i].num_values == 0) { 736 if (msg_delete_attribute(module, ldb, msg2, 737 msg->elements[i].name) != 0) { 738 ldb_asprintf_errstring(ldb, "No such attribute: %s for delete on %s", msg->elements[i].name, dn); 739 ret = LDB_ERR_NO_SUCH_ATTRIBUTE; 740 goto failed; 867 /* Delete the whole attribute */ 868 ret = msg_delete_attribute(module, ldb, msg2, 869 msg->elements[i].name); 870 if (ret == LDB_ERR_NO_SUCH_ATTRIBUTE && 871 control_permissive) { 872 ret = LDB_SUCCESS; 873 } else { 874 ldb_asprintf_errstring(ldb, 875 "attribute '%s': no such attribute for delete on '%s'", 876 msg->elements[i].name, dn); 741 877 } 742 break; 743 } 744 for (j=0;j<msg->elements[i].num_values;j++) { 745 if (msg_delete_element(module, 746 msg2, 747 msg->elements[i].name, 748 &msg->elements[i].values[j]) != 0) { 749 ldb_asprintf_errstring(ldb, "No matching attribute value when deleting attribute: %s on %s", msg->elements[i].name, dn); 750 ret = LDB_ERR_NO_SUCH_ATTRIBUTE; 751 goto failed; 878 if (ret != LDB_SUCCESS) { 879 goto done; 752 880 } 753 ret = ltdb_index_del_value(module, dn, &msg->elements[i], j); 754 if (ret != LDB_SUCCESS) { 755 goto failed; 881 } else { 882 /* Delete specified values from an attribute */ 883 for (j=0; j < msg->elements[i].num_values; j++) { 884 ret = msg_delete_element(module, 885 msg2, 886 msg->elements[i].name, 887 &msg->elements[i].values[j]); 888 if (ret == LDB_ERR_NO_SUCH_ATTRIBUTE && 889 control_permissive) { 890 ret = LDB_SUCCESS; 891 } else { 892 ldb_asprintf_errstring(ldb, 893 "attribute '%s': no matching attribute value while deleting attribute on '%s'", 894 msg->elements[i].name, dn); 895 } 896 if (ret != LDB_SUCCESS) { 897 goto done; 898 } 756 899 } 757 900 } … … 759 902 default: 760 903 ldb_asprintf_errstring(ldb, 761 "Invalid ldb_modify flags on %s: 0x%x",762 msg->elements[i].name,763 msg->elements[i].flags & LDB_FLAG_MOD_MASK);904 "attribute '%s': invalid modify flags on '%s': 0x%x", 905 msg->elements[i].name, ldb_dn_get_linearized(msg->dn), 906 msg->elements[i].flags & LDB_FLAG_MOD_MASK); 764 907 ret = LDB_ERR_PROTOCOL_ERROR; 765 goto failed;908 goto done; 766 909 } 767 910 } 768 911 769 /* we've made all the mods770 * save the modified record back into the database */771 912 ret = ltdb_store(module, msg2, TDB_MODIFY); 772 913 if (ret != LDB_SUCCESS) { 773 goto failed;774 } 775 776 ret = ltdb_modified(module, msg ->dn);914 goto done; 915 } 916 917 ret = ltdb_modified(module, msg2->dn); 777 918 if (ret != LDB_SUCCESS) { 778 goto failed; 779 } 780 919 goto done; 920 } 921 922 done: 781 923 talloc_free(tdb_key.dptr); 782 free(tdb_data.dptr);783 return ret;784 785 failed:786 talloc_free(tdb_key.dptr);787 free(tdb_data.dptr);788 924 return ret; 789 925 } … … 796 932 struct ldb_module *module = ctx->module; 797 933 struct ldb_request *req = ctx->req; 798 int tret; 934 int ret = LDB_SUCCESS; 935 936 ret = ltdb_check_special_dn(module, req->op.mod.message); 937 if (ret != LDB_SUCCESS) { 938 return ret; 939 } 799 940 800 941 ldb_request_set_state(req, LDB_ASYNC_PENDING); 801 942 802 tret = ltdb_check_special_dn(module, req->op.mod.message);803 if (tret != LDB_SUCCESS) {804 return tret;805 }806 807 943 if (ltdb_cache_load(module) != 0) { 808 944 return LDB_ERR_OPERATIONS_ERROR; 809 945 } 810 946 811 tret = ltdb_modify_internal(module, req->op.mod.message); 812 if (tret != LDB_SUCCESS) { 813 return tret; 814 } 815 816 return LDB_SUCCESS; 947 ret = ltdb_modify_internal(module, req->op.mod.message, req); 948 949 return ret; 817 950 } 818 951 … … 825 958 struct ldb_request *req = ctx->req; 826 959 struct ldb_message *msg; 827 int tret;960 int ret = LDB_SUCCESS; 828 961 829 962 ldb_request_set_state(req, LDB_ASYNC_PENDING); … … 833 966 } 834 967 835 msg = talloc(ctx, struct ldb_message);968 msg = ldb_msg_new(ctx); 836 969 if (msg == NULL) { 837 970 return LDB_ERR_OPERATIONS_ERROR; … … 840 973 /* in case any attribute of the message was indexed, we need 841 974 to fetch the old record */ 842 tret = ltdb_search_dn1(module, req->op.rename.olddn, msg);843 if ( tret != LDB_SUCCESS) {975 ret = ltdb_search_dn1(module, req->op.rename.olddn, msg); 976 if (ret != LDB_SUCCESS) { 844 977 /* not finding the old record is an error */ 845 return tret; 846 } 847 848 msg->dn = ldb_dn_copy(msg, req->op.rename.newdn); 849 if (!msg->dn) { 850 return LDB_ERR_OPERATIONS_ERROR; 978 return ret; 851 979 } 852 980 … … 855 983 * atomic 856 984 */ 857 tret = ltdb_delete_internal(module, req->op.rename.olddn); 858 if (tret != LDB_SUCCESS) { 859 return tret; 860 } 861 862 tret = ltdb_add_internal(module, msg); 863 if (tret != LDB_SUCCESS) { 864 return tret; 865 } 866 867 return LDB_SUCCESS; 985 ret = ltdb_delete_internal(module, msg->dn); 986 if (ret != LDB_SUCCESS) { 987 return ret; 988 } 989 990 msg->dn = ldb_dn_copy(msg, req->op.rename.newdn); 991 if (msg->dn == NULL) { 992 return LDB_ERR_OPERATIONS_ERROR; 993 } 994 995 ret = ltdb_add_internal(module, msg); 996 997 return ret; 868 998 } 869 999 … … 959 1089 struct ldb_module *module = ctx->module; 960 1090 struct ldb_request *req = ctx->req; 961 TALLOC_CTX *tmp_ctx ;1091 TALLOC_CTX *tmp_ctx = NULL; 962 1092 struct ldb_seqnum_request *seq; 963 1093 struct ldb_seqnum_result *res; … … 965 1095 struct ldb_dn *dn; 966 1096 const char *date; 967 int ret ;1097 int ret = LDB_SUCCESS; 968 1098 969 1099 ldb = ldb_module_get_ctx(module); … … 986 1116 goto done; 987 1117 } 1118 988 1119 tmp_ctx = talloc_new(req); 989 1120 if (tmp_ctx == NULL) { … … 993 1124 994 1125 dn = ldb_dn_new(tmp_ctx, ldb, LTDB_BASEINFO); 995 996 msg = talloc(tmp_ctx, struct ldb_message); 1126 if (dn == NULL) { 1127 ret = LDB_ERR_OPERATIONS_ERROR; 1128 goto done; 1129 } 1130 1131 msg = ldb_msg_new(tmp_ctx); 997 1132 if (msg == NULL) { 998 1133 ret = LDB_ERR_OPERATIONS_ERROR; … … 1031 1166 (*ext)->oid = LDB_EXTENDED_SEQUENCE_NUMBER; 1032 1167 (*ext)->data = talloc_steal(*ext, res); 1033 1034 ret = LDB_SUCCESS;1035 1168 1036 1169 done: … … 1167 1300 default: 1168 1301 /* no other op supported */ 1169 ret = LDB_ERR_ UNWILLING_TO_PERFORM;1302 ret = LDB_ERR_PROTOCOL_ERROR; 1170 1303 } 1171 1304 … … 1197 1330 struct ldb_request *req) 1198 1331 { 1332 struct ldb_control *control_permissive; 1199 1333 struct ldb_context *ldb; 1200 1334 struct tevent_context *ev; … … 1202 1336 struct tevent_timer *te; 1203 1337 struct timeval tv; 1204 1205 if (check_critical_controls(req->controls)) { 1206 return LDB_ERR_UNSUPPORTED_CRITICAL_EXTENSION; 1207 } 1338 unsigned int i; 1208 1339 1209 1340 ldb = ldb_module_get_ctx(module); 1341 1342 control_permissive = ldb_request_get_control(req, 1343 LDB_CONTROL_PERMISSIVE_MODIFY_OID); 1344 1345 for (i = 0; req->controls && req->controls[i]; i++) { 1346 if (req->controls[i]->critical && 1347 req->controls[i] != control_permissive) { 1348 ldb_asprintf_errstring(ldb, "Unsupported critical extension %s", 1349 req->controls[i]->oid); 1350 return LDB_ERR_UNSUPPORTED_CRITICAL_EXTENSION; 1351 } 1352 } 1210 1353 1211 1354 if (req->starttime == 0 || req->timeout == 0) { … … 1218 1361 ac = talloc_zero(ldb, struct ltdb_context); 1219 1362 if (ac == NULL) { 1220 ldb_ set_errstring(ldb, "Out of Memory");1363 ldb_oom(ldb); 1221 1364 return LDB_ERR_OPERATIONS_ERROR; 1222 1365 } … … 1254 1397 } 1255 1398 1399 static int ltdb_init_rootdse(struct ldb_module *module) 1400 { 1401 struct ldb_context *ldb; 1402 int ret; 1403 1404 ldb = ldb_module_get_ctx(module); 1405 1406 ret = ldb_mod_register_control(module, 1407 LDB_CONTROL_PERMISSIVE_MODIFY_OID); 1408 /* ignore errors on this - we expect it for non-sam databases */ 1409 1410 /* there can be no module beyond the backend, just return */ 1411 return LDB_SUCCESS; 1412 } 1413 1256 1414 static const struct ldb_module_ops ltdb_ops = { 1257 1415 .name = "tdb", 1416 .init_context = ltdb_init_rootdse, 1258 1417 .search = ltdb_handle_request, 1259 1418 .add = ltdb_handle_request, … … 1285 1444 ldb_debug(ldb, LDB_DEBUG_ERROR, 1286 1445 "Invalid tdb URL '%s'", url); 1287 return -1;1446 return LDB_ERR_OPERATIONS_ERROR; 1288 1447 } 1289 1448 path = url+6; … … 1313 1472 if (!ltdb) { 1314 1473 ldb_oom(ldb); 1315 return -1;1474 return LDB_ERR_OPERATIONS_ERROR; 1316 1475 } 1317 1476 … … 1324 1483 "Unable to open tdb '%s'", path); 1325 1484 talloc_free(ltdb); 1326 return -1; 1485 return LDB_ERR_OPERATIONS_ERROR; 1486 } 1487 1488 if (getenv("LDB_WARN_UNINDEXED")) { 1489 ltdb->warn_unindexed = true; 1327 1490 } 1328 1491 … … 1332 1495 if (!module) { 1333 1496 talloc_free(ltdb); 1334 return -1;1497 return LDB_ERR_OPERATIONS_ERROR; 1335 1498 } 1336 1499 ldb_module_set_private(module, ltdb); 1500 talloc_steal(module, ltdb); 1337 1501 1338 1502 if (ltdb_cache_load(module) != 0) { 1339 1503 talloc_free(module); 1340 1504 talloc_free(ltdb); 1341 return -1;1505 return LDB_ERR_OPERATIONS_ERROR; 1342 1506 } 1343 1507 1344 1508 *_module = module; 1345 return 0; 1346 } 1347 1348 const struct ldb_backend_ops ldb_tdb_backend_ops = { 1349 .name = "tdb", 1350 .connect_fn = ltdb_connect 1351 }; 1509 return LDB_SUCCESS; 1510 } 1511 1512 int ldb_tdb_init(const char *version) 1513 { 1514 LDB_MODULE_CHECK_VERSION(version); 1515 return ldb_register_backend("tdb", ltdb_connect, false); 1516 } -
vendor/current/source4/lib/ldb/ldb_tdb/ldb_tdb.h
r414 r740 1 #include "ldb_includes.h" 1 #include "replace.h" 2 #include "system/filesys.h" 3 #include "system/time.h" 2 4 #include "tdb.h" 3 5 #include "ldb_module.h" … … 18 20 struct ldb_message *indexlist; 19 21 struct ldb_message *attributes; 22 bool one_level_indexes; 23 bool attribute_indexes; 20 24 21 25 struct { … … 30 34 struct ltdb_idxptr *idxptr; 31 35 bool prepared_commit; 36 int read_lock_count; 37 38 bool warn_unindexed; 32 39 }; 33 40 … … 59 66 #define LTDB_INDEXLIST "@INDEXLIST" 60 67 #define LTDB_IDX "@IDX" 61 #define LTDB_IDX PTR "@IDXPTR"68 #define LTDB_IDXVERSION "@IDXVERSION" 62 69 #define LTDB_IDXATTR "@IDXATTR" 63 70 #define LTDB_IDXONE "@IDXONE" … … 84 91 85 92 int ltdb_search_indexed(struct ltdb_context *ctx, uint32_t *); 86 int ltdb_index_add(struct ldb_module *module, const struct ldb_message *msg); 87 int ltdb_index_del(struct ldb_module *module, const struct ldb_message *msg); 88 int ltdb_index_one(struct ldb_module *module, const struct ldb_message *msg, int add); 93 int ltdb_index_add_new(struct ldb_module *module, const struct ldb_message *msg); 94 int ltdb_index_delete(struct ldb_module *module, const struct ldb_message *msg); 95 int ltdb_index_del_element(struct ldb_module *module, struct ldb_dn *dn, 96 struct ldb_message_element *el); 97 int ltdb_index_add_element(struct ldb_module *module, struct ldb_dn *dn, 98 struct ldb_message_element *el); 99 int ltdb_index_del_value(struct ldb_module *module, struct ldb_dn *dn, 100 struct ldb_message_element *el, unsigned int v_idx); 89 101 int ltdb_reindex(struct ldb_module *module); 90 102 int ltdb_index_transaction_start(struct ldb_module *module); … … 123 135 struct TDB_DATA ltdb_key(struct ldb_module *module, struct ldb_dn *dn); 124 136 int ltdb_store(struct ldb_module *module, const struct ldb_message *msg, int flgs); 137 int ltdb_modify_internal(struct ldb_module *module, const struct ldb_message *msg, struct ldb_request *req); 125 138 int ltdb_delete_noindex(struct ldb_module *module, struct ldb_dn *dn); 126 int ltdb_modify_internal(struct ldb_module *module, const struct ldb_message *msg); 127 128 int ltdb_index_del_value(struct ldb_module *module, const char *dn, 129 struct ldb_message_element *el, int v_idx); 139 int ltdb_err_map(enum TDB_ERROR tdb_code); 130 140 131 141 struct tdb_context *ltdb_wrap_open(TALLOC_CTX *mem_ctx, -
vendor/current/source4/lib/ldb/ldb_tdb/ldb_tdb_wrap.c
r414 r740 23 23 24 24 #include "ldb_tdb.h" 25 #include "dlinklist.h" 25 26 26 27 /* … … 43 44 { 44 45 tdb_close(w->tdb); 45 if (w->next) { 46 w->next->prev = w->prev; 47 } 48 if (w->prev) { 49 w->prev->next = w->next; 50 } 51 if (w == tdb_list) { 52 tdb_list = w->next; 53 } 46 DLIST_REMOVE(tdb_list, w); 54 47 return 0; 55 48 } … … 144 137 talloc_set_destructor(w, ltdb_wrap_destructor); 145 138 146 w->next = tdb_list; 147 w->prev = NULL; 148 if (tdb_list) { 149 tdb_list->prev = w; 150 } 151 tdb_list = w; 139 DLIST_ADD(tdb_list, w); 152 140 153 141 return w->tdb; -
vendor/current/source4/lib/ldb/man/ldbadd.1.xml
r414 r740 28 28 <title>DESCRIPTION</title> 29 29 30 <para>ldbadd adds records to an ldb( 7) database. It reads30 <para>ldbadd adds records to an ldb(3) database. It reads 31 31 the ldif(5) files specified on the command line and adds 32 32 the records from these files to the LDB database, which is specified … … 53 53 <term>-H <ldb-url></term> 54 54 <listitem><para> 55 LDB URL to connect to. See ldb( 7) for details.55 LDB URL to connect to. See ldb(3) for details. 56 56 </para></listitem> 57 57 </varlistentry> … … 82 82 <title>SEE ALSO</title> 83 83 84 <para>ldb( 7), ldbmodify, ldbdel, ldif(5)</para>84 <para>ldb(3), ldbmodify, ldbdel, ldif(5)</para> 85 85 86 86 </refsect1> -
vendor/current/source4/lib/ldb/man/ldbdel.1.xml
r414 r740 27 27 <title>DESCRIPTION</title> 28 28 29 <para>ldbdel deletes records from an ldb( 7) database.29 <para>ldbdel deletes records from an ldb(3) database. 30 30 It deletes the records identified by the dn's specified 31 31 on the command-line. </para> … … 51 51 <term>-H <ldb-url></term> 52 52 <listitem><para> 53 LDB URL to connect to. See ldb( 7) for details.53 LDB URL to connect to. See ldb(3) for details. 54 54 </para></listitem> 55 55 </varlistentry> … … 80 80 <title>SEE ALSO</title> 81 81 82 <para>ldb( 7), ldbmodify, ldbadd, ldif(5)</para>82 <para>ldb(3), ldbmodify, ldbadd, ldif(5)</para> 83 83 84 84 </refsect1> -
vendor/current/source4/lib/ldb/man/ldbedit.1.xml
r414 r740 173 173 <title>SEE ALSO</title> 174 174 175 <para>ldb( 7), ldbmodify(1), ldbdel(1), ldif(5), vi(1)</para>175 <para>ldb(3), ldbmodify(1), ldbdel(1), ldif(5), vi(1)</para> 176 176 177 177 </refsect1> -
vendor/current/source4/lib/ldb/man/ldbmodify.1.xml
r414 r740 43 43 <term>-H <ldb-url></term> 44 44 <listitem><para> 45 LDB URL to connect to. See ldb( 7) for details.45 LDB URL to connect to. See ldb(3) for details. 46 46 </para></listitem> 47 47 </varlistentry> … … 70 70 <title>SEE ALSO</title> 71 71 72 <para>ldb( 7), ldbedit</para>72 <para>ldb(3), ldbedit</para> 73 73 74 74 </refsect1> -
vendor/current/source4/lib/ldb/man/ldbrename.1.xml
r414 r740 49 49 <term>-H <ldb-url></term> 50 50 <listitem><para> 51 LDB URL to connect to. See ldb( 7) for details.51 LDB URL to connect to. See ldb(3) for details. 52 52 </para></listitem> 53 53 </varlistentry> … … 84 84 <title>SEE ALSO</title> 85 85 86 <para>ldb( 7), ldbmodify, ldbdel, ldif(5)</para>86 <para>ldb(3), ldbmodify, ldbdel, ldif(5)</para> 87 87 88 88 </refsect1> -
vendor/current/source4/lib/ldb/man/ldbsearch.1.xml
r414 r740 52 52 <term>-H <ldb-url></term> 53 53 <listitem><para> 54 LDB URL to connect to. See ldb( 7) for details.54 LDB URL to connect to. See ldb(3) for details. 55 55 </para></listitem> 56 56 </varlistentry> … … 96 96 <title>SEE ALSO</title> 97 97 98 <para>ldb( 7), ldbedit(1)</para>98 <para>ldb(3), ldbedit(1)</para> 99 99 100 100 </refsect1> -
vendor/current/source4/lib/ldb/modules/asq.c
r414 r740 33 33 */ 34 34 35 #include "replace.h" 36 #include "system/filesys.h" 37 #include "system/time.h" 35 38 #include "ldb_module.h" 36 39 … … 56 59 57 60 struct ldb_request **reqs; 58 int num_reqs;59 int cur_req;61 unsigned int num_reqs; 62 unsigned int cur_req; 60 63 61 64 struct ldb_control **controls; … … 86 89 { 87 90 struct ldb_asq_control *asq; 88 int i;91 unsigned int i; 89 92 90 93 if (ac->controls) { … … 238 241 ac->req); 239 242 if (ret != LDB_SUCCESS) { 240 return LDB_ERR_OPERATIONS_ERROR;243 return ret; 241 244 } 242 245 … … 251 254 struct ldb_dn *dn; 252 255 struct ldb_message_element *el; 253 int ret, i; 256 unsigned int i; 257 int ret; 254 258 255 259 if (ac->base_res == NULL) { … … 293 297 ac->req); 294 298 if (ret != LDB_SUCCESS) { 295 return LDB_ERR_OPERATIONS_ERROR;299 return ret; 296 300 } 297 301 298 302 /* remove the ASQ control itself */ 299 303 control = ldb_request_get_control(ac->req, LDB_CONTROL_ASQ_OID); 300 if (! save_controls(control, ac->reqs[i], &saved_controls)) {304 if (!ldb_save_controls(control, ac->reqs[i], &saved_controls)) { 301 305 return LDB_ERR_OPERATIONS_ERROR; 302 306 } … … 400 404 } 401 405 402 const struct ldb_module_ops ldb_asq_module_ops = {406 static const struct ldb_module_ops ldb_asq_module_ops = { 403 407 .name = "asq", 404 408 .search = asq_search, 405 409 .init_context = asq_init 406 410 }; 411 412 int ldb_asq_init(const char *version) 413 { 414 LDB_MODULE_CHECK_VERSION(version); 415 return ldb_register_module(&ldb_asq_module_ops); 416 } -
vendor/current/source4/lib/ldb/modules/paged_results.c
r414 r740 33 33 */ 34 34 35 #include "ldb_includes.h" 35 #include "replace.h" 36 #include "system/filesys.h" 37 #include "system/time.h" 36 38 #include "ldb_module.h" 37 39 … … 66 68 67 69 struct private_data { 68 69 int next_free_id; 70 unsigned int next_free_id; 70 71 struct results_store *store; 71 72 … … 96 97 { 97 98 struct results_store *newr; 98 int new_id = priv->next_free_id++;99 unsigned int new_id = priv->next_free_id++; 99 100 100 101 /* TODO: we should have a limit on the number of … … 141 142 struct ldb_paged_control *paged; 142 143 struct message_store *msg; 143 int i, num_ctrls, ret; 144 unsigned int i, num_ctrls; 145 int ret; 144 146 145 147 if (ac->store == NULL) { … … 327 329 ac->req = req; 328 330 ac->size = paged_ctrl->size; 331 if (ac->size < 0) { 332 /* apparently some clients send more than 2^31. This 333 violates the ldap standard, but we need to cope */ 334 ac->size = 0x7FFFFFFF; 335 } 329 336 330 337 /* check if it is a continuation search the store */ … … 348 355 paged_search_callback, 349 356 req); 357 if (ret != LDB_SUCCESS) { 358 return ret; 359 } 350 360 351 361 /* save it locally and remove it from the list */ 352 362 /* we do not need to replace them later as we 353 363 * are keeping the original req intact */ 354 if (! save_controls(control, search_req, &saved_controls)) {364 if (!ldb_save_controls(control, search_req, &saved_controls)) { 355 365 return LDB_ERR_OPERATIONS_ERROR; 356 366 } … … 416 426 } 417 427 418 const struct ldb_module_ops ldb_paged_results_module_ops = {428 static const struct ldb_module_ops ldb_paged_results_module_ops = { 419 429 .name = "paged_results", 420 430 .search = paged_search, 421 431 .init_context = paged_request_init 422 432 }; 433 434 int ldb_paged_results_init(const char *version) 435 { 436 LDB_MODULE_CHECK_VERSION(version); 437 return ldb_register_module(&ldb_paged_results_module_ops); 438 } -
vendor/current/source4/lib/ldb/modules/paged_searches.c
r414 r740 34 34 */ 35 35 36 #include "includes.h" 36 #include "replace.h" 37 #include "system/filesys.h" 38 #include "system/time.h" 37 39 #include "ldb_module.h" 38 40 … … 53 55 54 56 char **saved_referrals; 55 int num_referrals;57 unsigned int num_referrals; 56 58 57 59 struct ldb_request *down_req; … … 79 81 return LDB_ERR_OPERATIONS_ERROR; 80 82 } else { 81 /* No cookie rec ived yet, valid to just return the full data set */83 /* No cookie received yet, valid to just return the full data set */ 82 84 83 85 /* we are done */ … … 133 135 struct ldb_reply *ares; 134 136 int ret; 135 int i;137 unsigned int i; 136 138 137 139 for (i = 0; i < ac->num_referrals; i++) { … … 271 273 ps_callback, 272 274 ac->req); 275 LDB_REQ_SET_LOCATION(ac->down_req); 273 276 if (ret != LDB_SUCCESS) { 274 277 return ret; … … 352 355 data, check_supported_paged, 353 356 NULL); 357 LDB_REQ_SET_LOCATION(req); 354 358 if (ret != LDB_SUCCESS) { 355 359 return ret; … … 370 374 } 371 375 372 _PUBLIC_const struct ldb_module_ops ldb_paged_searches_module_ops = {376 static const struct ldb_module_ops ldb_paged_searches_module_ops = { 373 377 .name = "paged_searches", 374 378 .search = ps_search, 375 379 .init_context = ps_init 376 380 }; 381 382 int ldb_paged_searches_init(const char *version) 383 { 384 LDB_MODULE_CHECK_VERSION(version); 385 return ldb_register_module(&ldb_paged_searches_module_ops); 386 } -
vendor/current/source4/lib/ldb/modules/rdn_name.c
r414 r740 2 2 ldb database library 3 3 4 Copyright (C) Andrew Bartlett 2005 4 Copyright (C) Andrew Bartlett 2005-2009 5 5 Copyright (C) Simo Sorce 2006-2008 6 6 … … 37 37 */ 38 38 39 #include "ldb_includes.h" 39 #include "replace.h" 40 #include "system/filesys.h" 41 #include "system/time.h" 40 42 #include "ldb_module.h" 41 43 42 44 struct rename_context { 43 44 45 struct ldb_module *module; 45 46 struct ldb_request *req; … … 47 48 struct ldb_reply *ares; 48 49 }; 49 50 static struct ldb_message_element *rdn_name_find_attribute(const struct ldb_message *msg, const char *name)51 {52 int i;53 54 for (i = 0; i < msg->num_elements; i++) {55 if (ldb_attr_cmp(name, msg->elements[i].name) == 0) {56 return &msg->elements[i];57 }58 }59 60 return NULL;61 }62 50 63 51 static int rdn_name_add_callback(struct ldb_request *req, … … 72 60 LDB_ERR_OPERATIONS_ERROR); 73 61 } 62 63 if (ares->type == LDB_REPLY_REFERRAL) { 64 return ldb_module_send_referral(ac->req, ares->referral); 65 } 66 74 67 if (ares->error != LDB_SUCCESS) { 75 68 return ldb_module_done(ac->req, ares->controls, … … 95 88 const struct ldb_schema_attribute *a; 96 89 const char *rdn_name; 90 const struct ldb_val *rdn_val_p; 97 91 struct ldb_val rdn_val; 98 int i, ret; 92 unsigned int i; 93 int ret; 99 94 100 95 ldb = ldb_module_get_ctx(module); 101 ldb_debug(ldb, LDB_DEBUG_TRACE, "rdn_name_add_record");102 96 103 97 /* do not manipulate our control entries */ … … 121 115 rdn_name = ldb_dn_get_rdn_name(msg->dn); 122 116 if (rdn_name == NULL) { 123 talloc_free(ac);124 117 return LDB_ERR_OPERATIONS_ERROR; 125 118 } 126 119 127 rdn_val = ldb_val_dup(msg, ldb_dn_get_rdn_val(msg->dn)); 128 129 /* Perhaps someone above us tried to set this? */ 130 if ((attribute = rdn_name_find_attribute(msg, "name")) != NULL ) { 131 attribute->num_values = 0; 132 } 133 134 if (ldb_msg_add_value(msg, "name", &rdn_val, NULL) != 0) { 135 talloc_free(ac); 136 return LDB_ERR_OPERATIONS_ERROR; 137 } 138 139 attribute = rdn_name_find_attribute(msg, rdn_name); 140 120 rdn_val_p = ldb_dn_get_rdn_val(msg->dn); 121 if (rdn_val_p == NULL) { 122 return LDB_ERR_OPERATIONS_ERROR; 123 } 124 if (rdn_val_p->length == 0) { 125 ldb_asprintf_errstring(ldb, "Empty RDN value on %s not permitted!", 126 ldb_dn_get_linearized(req->op.add.message->dn)); 127 return LDB_ERR_INVALID_DN_SYNTAX; 128 } 129 rdn_val = ldb_val_dup(msg, rdn_val_p); 130 131 /* Perhaps someone above us tried to set this? Then ignore it */ 132 ldb_msg_remove_attr(msg, "name"); 133 134 ret = ldb_msg_add_value(msg, "name", &rdn_val, NULL); 135 if (ret != LDB_SUCCESS) { 136 return ret; 137 } 138 139 a = ldb_schema_attribute_by_name(ldb, rdn_name); 140 if (a == NULL) { 141 return LDB_ERR_OPERATIONS_ERROR; 142 } 143 144 attribute = ldb_msg_find_element(msg, rdn_name); 141 145 if (!attribute) { 142 if (ldb_msg_add_value(msg, rdn_name, &rdn_val, NULL) != 0) { 143 talloc_free(ac); 144 return LDB_ERR_OPERATIONS_ERROR; 146 /* add entry with normalised RDN information if possible */ 147 if (a->name != NULL) { 148 ret = ldb_msg_add_value(msg, a->name, &rdn_val, NULL); 149 } else { 150 ret = ldb_msg_add_value(msg, rdn_name, &rdn_val, NULL); 151 } 152 if (ret != LDB_SUCCESS) { 153 return ret; 145 154 } 146 155 } else { 147 a = ldb_schema_attribute_by_name(ldb, rdn_name); 148 156 /* normalise attribute name if possible */ 157 if (a->name != NULL) { 158 attribute->name = a->name; 159 } 160 /* normalise attribute value */ 149 161 for (i = 0; i < attribute->num_values; i++) { 150 ret = a->syntax->comparison_fn(ldb, msg, 151 &rdn_val, &attribute->values[i]); 152 if (ret == 0) { 162 bool matched; 163 if (a->syntax->operator_fn) { 164 ret = a->syntax->operator_fn(ldb, LDB_OP_EQUALITY, a, 165 &rdn_val, &attribute->values[i], &matched); 166 if (ret != LDB_SUCCESS) return ret; 167 } else { 168 matched = (a->syntax->comparison_fn(ldb, msg, 169 &rdn_val, &attribute->values[i]) == 0); 170 } 171 if (matched) { 153 172 /* overwrite so it matches in case */ 154 173 attribute->values[i] = rdn_val; … … 157 176 } 158 177 if (i == attribute->num_values) { 159 char *rdn_errstring = talloc_asprintf(ac, "RDN mismatch on %s: %s (%.*s) should match one of:", 160 ldb_dn_get_linearized(msg->dn), rdn_name, 161 (int)rdn_val.length, (const char *)rdn_val.data); 178 char *rdn_errstring = talloc_asprintf(ac, 179 "RDN mismatch on %s: %s (%.*s) should match one of:", 180 ldb_dn_get_linearized(msg->dn), rdn_name, 181 (int)rdn_val.length, (const char *)rdn_val.data); 162 182 for (i = 0; i < attribute->num_values; i++) { 163 rdn_errstring = talloc_asprintf_append(rdn_errstring, " (%.*s)", 164 (int)attribute->values[i].length, 165 (const char *)attribute->values[i].data); 183 rdn_errstring = talloc_asprintf_append( 184 rdn_errstring, " (%.*s)", 185 (int)attribute->values[i].length, 186 (const char *)attribute->values[i].data); 166 187 } 167 ldb_debug_set(ldb, LDB_DEBUG_FATAL, "%s", rdn_errstring); 168 talloc_free(ac); 188 ldb_set_errstring(ldb, rdn_errstring); 169 189 /* Match AD's error here */ 170 190 return LDB_ERR_INVALID_DN_SYNTAX; … … 197 217 LDB_ERR_OPERATIONS_ERROR); 198 218 } 219 220 if (ares->type == LDB_REPLY_REFERRAL) { 221 return ldb_module_send_referral(ac->req, ares->referral); 222 } 223 199 224 if (ares->error != LDB_SUCCESS) { 200 225 return ldb_module_done(ac->req, ares->controls, … … 219 244 struct ldb_request *mod_req; 220 245 const char *rdn_name; 246 const struct ldb_val *rdn_val_p; 221 247 struct ldb_val rdn_val; 222 248 struct ldb_message *msg; … … 229 255 goto error; 230 256 } 257 258 if (ares->type == LDB_REPLY_REFERRAL) { 259 return ldb_module_send_referral(ac->req, ares->referral); 260 } 261 231 262 if (ares->error != LDB_SUCCESS) { 232 263 return ldb_module_done(ac->req, ares->controls, … … 250 281 goto error; 251 282 } 283 252 284 rdn_name = ldb_dn_get_rdn_name(ac->req->op.rename.newdn); 253 285 if (rdn_name == NULL) { 254 286 goto error; 255 287 } 256 257 rdn_val = ldb_val_dup(msg, ldb_dn_get_rdn_val(ac->req->op.rename.newdn)); 258 288 289 rdn_val_p = ldb_dn_get_rdn_val(msg->dn); 290 if (rdn_val_p == NULL) { 291 goto error; 292 } 293 if (rdn_val_p->length == 0) { 294 ldb_asprintf_errstring(ldb, "Empty RDN value on %s not permitted!", 295 ldb_dn_get_linearized(req->op.rename.olddn)); 296 return ldb_module_done(ac->req, NULL, NULL, 297 LDB_ERR_NAMING_VIOLATION); 298 } 299 rdn_val = ldb_val_dup(msg, rdn_val_p); 300 259 301 if (ldb_msg_add_empty(msg, rdn_name, LDB_FLAG_MOD_REPLACE, NULL) != 0) { 260 302 goto error; … … 279 321 talloc_steal(mod_req, msg); 280 322 281 /* do the mod call*/282 return ldb_ request(ldb, mod_req);323 /* go on with the call chain */ 324 return ldb_next_request(ac->module, mod_req); 283 325 284 326 error: 285 return ldb_module_done(ac->req, NULL, NULL, 286 LDB_ERR_OPERATIONS_ERROR); 327 return ldb_module_done(ac->req, NULL, NULL, LDB_ERR_OPERATIONS_ERROR); 287 328 } 288 329 … … 295 336 296 337 ldb = ldb_module_get_ctx(module); 297 ldb_debug(ldb, LDB_DEBUG_TRACE, "rdn_name_rename");298 338 299 339 /* do not manipulate our control entries */ … … 321 361 322 362 if (ret != LDB_SUCCESS) { 323 return LDB_ERR_OPERATIONS_ERROR;363 return ret; 324 364 } 325 365 … … 328 368 } 329 369 330 const struct ldb_module_ops ldb_rdn_name_module_ops = { 370 static int rdn_name_modify(struct ldb_module *module, struct ldb_request *req) 371 { 372 struct ldb_context *ldb; 373 const struct ldb_val *rdn_val_p; 374 375 ldb = ldb_module_get_ctx(module); 376 377 /* do not manipulate our control entries */ 378 if (ldb_dn_is_special(req->op.mod.message->dn)) { 379 return ldb_next_request(module, req); 380 } 381 382 rdn_val_p = ldb_dn_get_rdn_val(req->op.mod.message->dn); 383 if (rdn_val_p == NULL) { 384 return LDB_ERR_OPERATIONS_ERROR; 385 } 386 if (rdn_val_p->length == 0) { 387 ldb_asprintf_errstring(ldb, "Empty RDN value on %s not permitted!", 388 ldb_dn_get_linearized(req->op.mod.message->dn)); 389 return LDB_ERR_INVALID_DN_SYNTAX; 390 } 391 392 if (ldb_msg_find_element(req->op.mod.message, "distinguishedName")) { 393 ldb_asprintf_errstring(ldb, "Modify of 'distinguishedName' on %s not permitted, must use 'rename' operation instead", 394 ldb_dn_get_linearized(req->op.mod.message->dn)); 395 return LDB_ERR_CONSTRAINT_VIOLATION; 396 } 397 398 if (ldb_msg_find_element(req->op.mod.message, "name")) { 399 ldb_asprintf_errstring(ldb, "Modify of 'name' on %s not permitted, must use 'rename' operation instead", 400 ldb_dn_get_linearized(req->op.mod.message->dn)); 401 return LDB_ERR_NOT_ALLOWED_ON_RDN; 402 } 403 404 if (ldb_msg_find_element(req->op.mod.message, ldb_dn_get_rdn_name(req->op.mod.message->dn))) { 405 ldb_asprintf_errstring(ldb, "Modify of RDN '%s' on %s not permitted, must use 'rename' operation instead", 406 ldb_dn_get_rdn_name(req->op.mod.message->dn), ldb_dn_get_linearized(req->op.mod.message->dn)); 407 return LDB_ERR_NOT_ALLOWED_ON_RDN; 408 } 409 410 /* All OK, they kept their fingers out of the special attributes */ 411 return ldb_next_request(module, req); 412 } 413 414 static int rdn_name_search(struct ldb_module *module, struct ldb_request *req) 415 { 416 struct ldb_context *ldb; 417 const char *rdn_name; 418 const struct ldb_val *rdn_val_p; 419 420 ldb = ldb_module_get_ctx(module); 421 422 /* do not manipulate our control entries */ 423 if (ldb_dn_is_special(req->op.search.base)) { 424 return ldb_next_request(module, req); 425 } 426 427 rdn_name = ldb_dn_get_rdn_name(req->op.search.base); 428 rdn_val_p = ldb_dn_get_rdn_val(req->op.search.base); 429 if ((rdn_name != NULL) && (rdn_val_p == NULL)) { 430 return LDB_ERR_OPERATIONS_ERROR; 431 } 432 if ((rdn_val_p != NULL) && (rdn_val_p->length == 0)) { 433 ldb_asprintf_errstring(ldb, "Empty RDN value on %s not permitted!", 434 ldb_dn_get_linearized(req->op.search.base)); 435 return LDB_ERR_INVALID_DN_SYNTAX; 436 } 437 438 return ldb_next_request(module, req); 439 } 440 441 static const struct ldb_module_ops ldb_rdn_name_module_ops = { 331 442 .name = "rdn_name", 332 443 .add = rdn_name_add, 444 .modify = rdn_name_modify, 333 445 .rename = rdn_name_rename, 446 .search = rdn_name_search 334 447 }; 448 449 int ldb_rdn_name_init(const char *version) 450 { 451 LDB_MODULE_CHECK_VERSION(version); 452 return ldb_register_module(&ldb_rdn_name_module_ops); 453 } -
vendor/current/source4/lib/ldb/modules/skel.c
r414 r740 1 /* 1 /* 2 2 ldb database library 3 3 … … 7 7 ** library. This does NOT imply that all of Samba is released 8 8 ** under the LGPL 9 9 10 10 This library is free software; you can redistribute it and/or 11 11 modify it under the terms of the GNU Lesser General Public … … 32 32 */ 33 33 34 #include "replace.h" 35 #include "system/filesys.h" 36 #include "system/time.h" 34 37 #include "ldb_module.h" 35 38 … … 124 127 } 125 128 126 const struct ldb_module_ops ldb_skel_module_ops = {129 static const struct ldb_module_ops ldb_skel_module_ops = { 127 130 .name = "skel", 128 131 .init_context = skel_init, … … 137 140 .del_transaction = skel_del_trans, 138 141 }; 142 143 int ldb_skel_init(const char *version) 144 { 145 LDB_MODULE_CHECK_VERSION(version); 146 return ldb_register_module(&ldb_skel_module_ops); 147 } -
vendor/current/source4/lib/ldb/modules/sort.c
r414 r740 32 32 */ 33 33 34 #include "replace.h" 35 #include "system/filesys.h" 36 #include "system/time.h" 34 37 #include "ldb_module.h" 35 38 … … 45 48 struct ldb_module *module; 46 49 47 c har *attributeName;48 c har *orderingRule;50 const char *attributeName; 51 const char *orderingRule; 49 52 int reverse; 50 53 … … 52 55 struct ldb_message **msgs; 53 56 char **referrals; 54 int num_msgs;55 int num_refs;57 unsigned int num_msgs; 58 unsigned int num_refs; 56 59 57 60 const struct ldb_schema_attribute *a; … … 63 66 struct ldb_control **controls; 64 67 struct ldb_sort_resp_control *resp; 65 int i;68 unsigned int i; 66 69 67 70 if (*ctrls) { … … 138 141 struct ldb_context *ldb; 139 142 struct ldb_reply *ares; 140 int i, ret; 143 unsigned int i; 144 int ret; 141 145 142 146 ldb = ldb_module_get_ctx(ac->module); … … 145 149 ac->sort_result = 0; 146 150 147 ldb_qsort(ac->msgs, ac->num_msgs, 148 sizeof(struct ldb_message *), 149 ac, (ldb_qsort_cmp_fn_t)sort_compare); 151 LDB_TYPESAFE_QSORT(ac->msgs, ac->num_msgs, ac, sort_compare); 150 152 151 153 if (ac->sort_result != LDB_SUCCESS) { … … 316 318 req); 317 319 if (ret != LDB_SUCCESS) { 318 return LDB_ERR_OPERATIONS_ERROR;320 return ret; 319 321 } 320 322 … … 322 324 /* we do not need to replace them later as we 323 325 * are keeping the original req intact */ 324 if (! save_controls(control, down_req, &saved_controls)) {326 if (!ldb_save_controls(control, down_req, &saved_controls)) { 325 327 return LDB_ERR_OPERATIONS_ERROR; 326 328 } … … 346 348 } 347 349 348 const struct ldb_module_ops ldb_server_sort_module_ops = {350 static const struct ldb_module_ops ldb_server_sort_module_ops = { 349 351 .name = "server_sort", 350 352 .search = server_sort_search, 351 353 .init_context = server_sort_init 352 354 }; 355 356 int ldb_server_sort_init(const char *version) 357 { 358 LDB_MODULE_CHECK_VERSION(version); 359 return ldb_register_module(&ldb_server_sort_module_ops); 360 } -
vendor/current/source4/lib/ldb/nssldb/ldb-nss.c
r414 r740 192 192 size_t bufpos; 193 193 size_t lsize; 194 int i;194 unsigned int i; 195 195 196 196 bufpos = 0; … … 281 281 { 282 282 NSS_STATUS ret; 283 int i;283 unsigned int i; 284 284 285 285 for (i = 0; i < grlist->count; i++) { -
vendor/current/source4/lib/ldb/pyldb.c
r414 r740 6 6 Copyright (C) 2005,2006 Tim Potter <tpot@samba.org> 7 7 Copyright (C) 2006 Simo Sorce <idra@samba.org> 8 Copyright (C) 2007-20 09Jelmer Vernooij <jelmer@samba.org>9 Copyright (C) 2009 Matthias Dieter Wallnöfer10 11 12 13 8 Copyright (C) 2007-2010 Jelmer Vernooij <jelmer@samba.org> 9 Copyright (C) 2009-2010 Matthias Dieter Wallnöfer 10 11 ** NOTE! The following LGPL license applies to the ldb 12 ** library. This does NOT imply that all of Samba is released 13 ** under the LGPL 14 14 15 15 This library is free software; you can redistribute it and/or … … 27 27 */ 28 28 29 #include "replace.h" 29 #include <Python.h> 30 #include <pytalloc.h> 30 31 #include "ldb_private.h" 31 #include <Python.h>32 32 #include "pyldb.h" 33 34 void initldb(void); 35 static PyObject *PyLdbMessage_FromMessage(struct ldb_message *msg); 36 static PyObject *PyExc_LdbError; 37 38 staticforward PyTypeObject PyLdbControl; 39 staticforward PyTypeObject PyLdbResult; 40 staticforward PyTypeObject PyLdbMessage; 41 staticforward PyTypeObject PyLdbModule; 42 staticforward PyTypeObject PyLdbDn; 43 staticforward PyTypeObject PyLdb; 44 staticforward PyTypeObject PyLdbMessageElement; 45 staticforward PyTypeObject PyLdbTree; 46 static PyObject *PyLdb_FromLdbContext(struct ldb_context *ldb_ctx); 47 static PyObject *PyLdbModule_FromModule(struct ldb_module *mod); 48 static struct ldb_message_element *PyObject_AsMessageElement( 49 TALLOC_CTX *mem_ctx, 50 PyObject *set_obj, 51 int flags, 52 const char *attr_name); 33 53 34 54 /* There's no Py_ssize_t in 2.4, apparently */ … … 43 63 #endif 44 64 65 #define SIGN(a) (((a) == 0)?0:((a) < 0?-1:1)) 66 67 68 69 static PyObject *py_ldb_control_str(PyLdbControlObject *self) 70 { 71 if (self->data != NULL) { 72 char* control = ldb_control_to_string(self->mem_ctx, self->data); 73 if (control == NULL) { 74 PyErr_NoMemory(); 75 return NULL; 76 } 77 return PyString_FromString(control); 78 } else { 79 return PyString_FromFormat("ldb control"); 80 } 81 } 82 83 static void py_ldb_control_dealloc(PyLdbControlObject *self) 84 { 85 if (self->mem_ctx != NULL) { 86 talloc_free(self->mem_ctx); 87 } 88 self->ob_type->tp_free(self); 89 } 90 91 static PyObject *py_ldb_control_get_oid(PyLdbControlObject *self) 92 { 93 return PyString_FromString(self->data->oid); 94 } 95 96 static PyObject *py_ldb_control_get_critical(PyLdbControlObject *self) 97 { 98 return PyBool_FromLong(self->data->critical); 99 } 100 101 static PyObject *py_ldb_control_set_critical(PyLdbControlObject *self, PyObject *value, void *closure) 102 { 103 if (PyObject_IsTrue(value)) { 104 self->data->critical = true; 105 } else { 106 self->data->critical = false; 107 } 108 return 0; 109 } 110 111 static PyObject *py_ldb_control_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) 112 { 113 char *data = NULL; 114 const char *array[2]; 115 const char * const kwnames[] = { "ldb", "data", NULL }; 116 struct ldb_control *parsed_controls; 117 PyLdbControlObject *ret; 118 PyObject *py_ldb; 119 TALLOC_CTX *mem_ctx; 120 struct ldb_context *ldb_ctx; 121 122 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "Os", 123 discard_const_p(char *, kwnames), 124 &py_ldb, &data)) 125 return NULL; 126 127 mem_ctx = talloc_new(NULL); 128 if (mem_ctx == NULL) { 129 PyErr_NoMemory(); 130 return NULL; 131 } 132 133 ldb_ctx = PyLdb_AsLdbContext(py_ldb); 134 parsed_controls = ldb_parse_control_from_string(ldb_ctx, mem_ctx, data); 135 136 if (!parsed_controls) { 137 talloc_free(mem_ctx); 138 PyErr_SetString(PyExc_ValueError, "unable to parse control string"); 139 return NULL; 140 } 141 142 ret = PyObject_New(PyLdbControlObject, type); 143 if (ret == NULL) { 144 PyErr_NoMemory(); 145 talloc_free(mem_ctx); 146 return NULL; 147 } 148 149 ret->mem_ctx = mem_ctx; 150 151 ret->data = talloc_steal(mem_ctx, parsed_controls); 152 if (ret->data == NULL) { 153 Py_DECREF(ret); 154 PyErr_NoMemory(); 155 talloc_free(mem_ctx); 156 return NULL; 157 } 158 159 return (PyObject *)ret; 160 } 161 162 static PyGetSetDef py_ldb_control_getset[] = { 163 { discard_const_p(char, "oid"), (getter)py_ldb_control_get_oid, NULL, NULL }, 164 { discard_const_p(char, "critical"), (getter)py_ldb_control_get_critical, (setter)py_ldb_control_set_critical, NULL }, 165 { NULL } 166 }; 167 168 static PyTypeObject PyLdbControl = { 169 .tp_name = "ldb.control", 170 .tp_dealloc = (destructor)py_ldb_control_dealloc, 171 .tp_getattro = PyObject_GenericGetAttr, 172 .tp_basicsize = sizeof(PyLdbControlObject), 173 .tp_getset = py_ldb_control_getset, 174 .tp_doc = "LDB control.", 175 .tp_str = (reprfunc)py_ldb_control_str, 176 .tp_new = py_ldb_control_new, 177 .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, 178 }; 179 45 180 static void PyErr_SetLdbError(PyObject *error, int ret, struct ldb_context *ldb_ctx) 46 181 { … … 49 184 50 185 PyErr_SetObject(error, 51 Py_BuildValue(discard_const_p(char, "(i,s)"), ret, 52 ldb_ctx == NULL?ldb_strerror(ret):ldb_errstring(ldb_ctx))); 53 } 54 55 static PyObject *PyExc_LdbError; 56 57 PyAPI_DATA(PyTypeObject) PyLdbMessage; 58 PyAPI_DATA(PyTypeObject) PyLdbModule; 59 PyAPI_DATA(PyTypeObject) PyLdbDn; 60 PyAPI_DATA(PyTypeObject) PyLdb; 61 PyAPI_DATA(PyTypeObject) PyLdbMessageElement; 62 PyAPI_DATA(PyTypeObject) PyLdbTree; 63 64 static PyObject *PyObject_FromLdbValue(struct ldb_context *ldb_ctx, 65 struct ldb_message_element *el, 66 struct ldb_val *val) 67 { 68 struct ldb_val new_val; 69 TALLOC_CTX *mem_ctx = talloc_new(NULL); 70 PyObject *ret; 71 72 new_val = *val; 73 74 ret = PyString_FromStringAndSize((const char *)new_val.data, new_val.length); 75 76 talloc_free(mem_ctx); 77 78 return ret; 186 Py_BuildValue(discard_const_p(char, "(i,s)"), ret, 187 ldb_ctx == NULL?ldb_strerror(ret):ldb_errstring(ldb_ctx))); 188 } 189 190 static PyObject *PyObject_FromLdbValue(struct ldb_val *val) 191 { 192 return PyString_FromStringAndSize((const char *)val->data, val->length); 79 193 } 80 194 81 195 /** 82 * Obtain a ldb DN from a Python object.196 * Create a Python object from a ldb_result. 83 197 * 84 * @param mem_ctx Memory context 85 * @param object Python object 86 * @param ldb_ctx LDB context 87 * @return Whether or not the conversion succeeded 198 * @param result LDB result to convert 199 * @return Python object with converted result (a list object) 88 200 */ 89 bool PyObject_AsDn(TALLOC_CTX *mem_ctx, PyObject *object, 90 struct ldb_context *ldb_ctx, struct ldb_dn **dn) 91 { 92 struct ldb_dn *odn; 93 94 if (ldb_ctx != NULL && PyString_Check(object)) { 95 odn = ldb_dn_new(mem_ctx, ldb_ctx, PyString_AsString(object)); 96 *dn = odn; 97 return true; 98 } 99 100 if (PyLdbDn_Check(object)) { 101 *dn = PyLdbDn_AsDn(object); 102 return true; 103 } 104 105 PyErr_SetString(PyExc_TypeError, "Expected DN"); 106 return false; 201 static PyObject *PyLdbControl_FromControl(struct ldb_control *control) 202 { 203 TALLOC_CTX *ctl_ctx = talloc_new(NULL); 204 PyLdbControlObject *ctrl; 205 if (ctl_ctx == NULL) { 206 PyErr_NoMemory(); 207 return NULL; 208 } 209 210 ctrl = (PyLdbControlObject *)PyLdbControl.tp_alloc(&PyLdbControl, 0); 211 if (ctrl == NULL) { 212 PyErr_NoMemory(); 213 return NULL; 214 } 215 ctrl->mem_ctx = ctl_ctx; 216 ctrl->data = talloc_steal(ctrl->mem_ctx, control); 217 if (ctrl->data == NULL) { 218 Py_DECREF(ctrl); 219 PyErr_NoMemory(); 220 return NULL; 221 } 222 return (PyObject*) ctrl; 107 223 } 108 224 … … 115 231 static PyObject *PyLdbResult_FromResult(struct ldb_result *result) 116 232 { 117 PyObject *ret; 118 int i; 233 PyLdbResultObject *ret; 234 PyObject *list, *controls, *referals; 235 Py_ssize_t i; 236 119 237 if (result == NULL) { 120 238 Py_RETURN_NONE; 121 } 122 ret = PyList_New(result->count); 239 } 240 241 ret = (PyLdbResultObject *)PyLdbResult.tp_alloc(&PyLdbResult, 0); 242 if (ret == NULL) { 243 PyErr_NoMemory(); 244 return NULL; 245 } 246 247 list = PyList_New(result->count); 248 if (list == NULL) { 249 PyErr_NoMemory(); 250 Py_DECREF(ret); 251 return NULL; 252 } 253 123 254 for (i = 0; i < result->count; i++) { 124 PyList_SetItem(ret, i, PyLdbMessage_FromMessage(result->msgs[i]) 125 ); 126 } 127 return ret; 255 PyList_SetItem(list, i, PyLdbMessage_FromMessage(result->msgs[i])); 256 } 257 258 ret->mem_ctx = talloc_new(NULL); 259 if (ret->mem_ctx == NULL) { 260 Py_DECREF(list); 261 Py_DECREF(ret); 262 PyErr_NoMemory(); 263 return NULL; 264 } 265 266 ret->msgs = list; 267 268 if (result->controls) { 269 controls = PyList_New(1); 270 if (controls == NULL) { 271 Py_DECREF(ret); 272 PyErr_NoMemory(); 273 return NULL; 274 } 275 for (i=0; result->controls[i]; i++) { 276 PyObject *ctrl = (PyObject*) PyLdbControl_FromControl(result->controls[i]); 277 if (ctrl == NULL) { 278 Py_DECREF(ret); 279 Py_DECREF(controls); 280 PyErr_NoMemory(); 281 return NULL; 282 } 283 PyList_SetItem(controls, i, ctrl); 284 } 285 } else { 286 /* 287 * No controls so we keep an empty list 288 */ 289 controls = PyList_New(0); 290 if (controls == NULL) { 291 Py_DECREF(ret); 292 PyErr_NoMemory(); 293 return NULL; 294 } 295 } 296 297 ret->controls = controls; 298 299 i = 0; 300 301 while (result->refs && result->refs[i]) { 302 i++; 303 } 304 305 referals = PyList_New(i); 306 if (referals == NULL) { 307 Py_DECREF(ret); 308 PyErr_NoMemory(); 309 return NULL; 310 } 311 312 for (i = 0;result->refs && result->refs[i]; i++) { 313 PyList_SetItem(referals, i, PyString_FromString(result->refs[i])); 314 } 315 ret->referals = referals; 316 return (PyObject *)ret; 128 317 } 129 318 … … 137 326 */ 138 327 static struct ldb_result *PyLdbResult_AsResult(TALLOC_CTX *mem_ctx, 139 328 PyObject *obj) 140 329 { 141 330 struct ldb_result *res; 142 int i;331 Py_ssize_t i; 143 332 144 333 if (obj == Py_None) … … 296 485 "S.canonical_ex_str() -> string\n" 297 486 "Canonical version of this DN (like a posix path, with terminating newline)." }, 298 { "check_special", (PyCFunction)py_ldb_dn_is_special, METH_VARARGS,299 NULL },300 487 { "parent", (PyCFunction)py_ldb_dn_get_parent, METH_NOARGS, 301 488 "S.parent() -> dn\n" … … 308 495 "Add a base DN to this DN." }, 309 496 { "check_special", (PyCFunction)py_ldb_dn_check_special, METH_VARARGS, 310 NULL }, 497 "S.check_special(name) -> bool\n\n" 498 "Check if name is a special DN name"}, 311 499 { NULL } 312 500 }; … … 366 554 367 555 ret = ldb_dn_new(mem_ctx, ldb_ctx, str); 368 369 if (ret == NULL || !ldb_dn_validate(ret)) { 556 if (!ldb_dn_validate(ret)) { 370 557 talloc_free(mem_ctx); 371 558 PyErr_SetString(PyExc_ValueError, "unable to parse dn string"); … … 384 571 } 385 572 386 PyObject *PyLdbDn_FromDn(struct ldb_dn *dn)387 {388 PyLdbDnObject *py_ret;389 390 if (dn == NULL) {391 Py_RETURN_NONE;392 }393 394 py_ret = (PyLdbDnObject *)PyLdbDn.tp_alloc(&PyLdbDn, 0);395 if (py_ret == NULL) {396 PyErr_NoMemory();397 return NULL;398 }399 py_ret->mem_ctx = talloc_new(NULL);400 py_ret->dn = talloc_reference(py_ret->mem_ctx, dn);401 return (PyObject *)py_ret;402 }403 404 573 static void py_ldb_dn_dealloc(PyLdbDnObject *self) 405 574 { 406 575 talloc_free(self->mem_ctx); 407 self->ob_type->tp_free(self);408 } 409 410 PyTypeObject PyLdbDn = {411 .tp_name = " Dn",576 PyObject_Del(self); 577 } 578 579 static PyTypeObject PyLdbDn = { 580 .tp_name = "ldb.Dn", 412 581 .tp_methods = py_ldb_dn_methods, 413 582 .tp_str = (reprfunc)py_ldb_dn_get_linearized, … … 418 587 .tp_new = py_ldb_dn_new, 419 588 .tp_dealloc = (destructor)py_ldb_dn_dealloc, 420 .tp_basicsize = sizeof(PyLdb Object),589 .tp_basicsize = sizeof(PyLdbDnObject), 421 590 .tp_flags = Py_TPFLAGS_DEFAULT, 422 591 }; … … 475 644 { 476 645 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ldb_transaction_commit(PyLdb_AsLdbContext(self)), PyLdb_AsLdbContext(self)); 646 Py_RETURN_NONE; 647 } 648 649 static PyObject *py_ldb_transaction_prepare_commit(PyLdbObject *self) 650 { 651 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ldb_transaction_prepare_commit(PyLdb_AsLdbContext(self)), PyLdb_AsLdbContext(self)); 477 652 Py_RETURN_NONE; 478 653 } … … 529 704 530 705 static const char **PyList_AsStringList(TALLOC_CTX *mem_ctx, PyObject *list, 531 706 const char *paramname) 532 707 { 533 708 const char **ret; 534 int i;709 Py_ssize_t i; 535 710 if (!PyList_Check(list)) { 536 711 PyErr_Format(PyExc_TypeError, "%s is not a list", paramname); … … 538 713 } 539 714 ret = talloc_array(NULL, const char *, PyList_Size(list)+1); 715 if (ret == NULL) { 716 PyErr_NoMemory(); 717 return NULL; 718 } 719 540 720 for (i = 0; i < PyList_Size(list); i++) { 541 721 PyObject *item = PyList_GetItem(list, i); … … 545 725 } 546 726 ret[i] = talloc_strndup(ret, PyString_AsString(item), 547 727 PyString_Size(item)); 548 728 } 549 729 ret[i] = NULL; … … 642 822 { 643 823 PyObject *py_msg; 644 int ret; 645 if (!PyArg_ParseTuple(args, "O", &py_msg)) 646 return NULL; 647 648 if (!PyLdbMessage_Check(py_msg)) { 649 PyErr_SetString(PyExc_TypeError, "Expected Ldb Message"); 650 return NULL; 651 } 652 653 ret = ldb_modify(PyLdb_AsLdbContext(self), PyLdbMessage_AsMessage(py_msg)); 654 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, PyLdb_AsLdbContext(self)); 655 656 Py_RETURN_NONE; 657 } 658 659 static PyObject *py_ldb_add(PyLdbObject *self, PyObject *args) 660 { 661 PyObject *py_msg; 662 int ret; 663 Py_ssize_t dict_pos, msg_pos; 664 struct ldb_message_element *msgel; 665 struct ldb_message *msg; 824 PyObject *py_controls = Py_None; 666 825 struct ldb_context *ldb_ctx; 667 826 struct ldb_request *req; 668 PyObject *key, *value; 669 PyObject *py_controls = Py_None; 827 struct ldb_control **parsed_controls; 828 struct ldb_message *msg; 829 int ret; 670 830 TALLOC_CTX *mem_ctx; 671 struct ldb_control **parsed_controls; 672 673 if (!PyArg_ParseTuple(args, "O|O", &py_msg, &py_controls )) 674 return NULL; 831 832 if (!PyArg_ParseTuple(args, "O|O", &py_msg, &py_controls)) 833 return NULL; 834 835 mem_ctx = talloc_new(NULL); 836 if (mem_ctx == NULL) { 837 PyErr_NoMemory(); 838 return NULL; 839 } 675 840 ldb_ctx = PyLdb_AsLdbContext(self); 676 841 677 mem_ctx = talloc_new(NULL);678 842 if (py_controls == Py_None) { 679 843 parsed_controls = NULL; 680 844 } else { 681 const char **controls = PyList_AsStringList( ldb_ctx, py_controls, "controls");682 parsed_controls = ldb_parse_control_strings(ldb_ctx, ldb_ctx, controls);845 const char **controls = PyList_AsStringList(mem_ctx, py_controls, "controls"); 846 parsed_controls = ldb_parse_control_strings(ldb_ctx, mem_ctx, controls); 683 847 talloc_free(controls); 684 848 } 685 if (PyDict_Check(py_msg)) { 686 PyObject *dn_value = PyDict_GetItemString(py_msg, "dn"); 687 msg = ldb_msg_new(mem_ctx); 688 msg->elements = talloc_zero_array(msg, struct ldb_message_element, PyDict_Size(py_msg)); 689 msg_pos = dict_pos = 0; 690 if (dn_value) { 691 if (!PyObject_AsDn(msg, dn_value, ldb_ctx, &msg->dn)) { 692 PyErr_SetString(PyExc_TypeError, "unable to import dn object"); 693 talloc_free(mem_ctx); 694 return NULL; 695 } 696 if (msg->dn == NULL) { 697 PyErr_SetString(PyExc_TypeError, "dn set but not found"); 698 talloc_free(mem_ctx); 699 return NULL; 700 } 701 } 702 703 while (PyDict_Next(py_msg, &dict_pos, &key, &value)) { 704 char *key_str = PyString_AsString(key); 705 if (strcmp(key_str, "dn") != 0) { 706 msgel = PyObject_AsMessageElement(msg->elements, value, 0, key_str); 707 if (msgel == NULL) { 708 PyErr_SetString(PyExc_TypeError, "unable to import element"); 709 talloc_free(mem_ctx); 710 return NULL; 711 } 712 memcpy(&msg->elements[msg_pos], msgel, sizeof(*msgel)); 713 msg_pos++; 714 } 715 } 716 717 if (msg->dn == NULL) { 718 PyErr_SetString(PyExc_TypeError, "no dn set"); 719 talloc_free(mem_ctx); 720 return NULL; 721 } 722 723 msg->num_elements = msg_pos; 724 } else { 725 msg = PyLdbMessage_AsMessage(py_msg); 726 } 727 849 850 if (!PyLdbMessage_Check(py_msg)) { 851 PyErr_SetString(PyExc_TypeError, "Expected Ldb Message"); 852 talloc_free(mem_ctx); 853 return NULL; 854 } 855 msg = PyLdbMessage_AsMessage(py_msg); 856 728 857 ret = ldb_msg_sanity_check(ldb_ctx, msg); 729 730 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, PyLdb_AsLdbContext(self));858 if (ret != LDB_SUCCESS) { 859 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx); 731 860 talloc_free(mem_ctx); 732 861 return NULL; 733 } 734 735 ret = ldb_build_add_req(&req, ldb_ctx, ldb_ctx, 736 msg, 737 parsed_controls, 738 NULL, 739 ldb_op_default_callback, 740 NULL); 741 862 } 863 864 ret = ldb_build_mod_req(&req, ldb_ctx, mem_ctx, msg, parsed_controls, 865 NULL, ldb_op_default_callback, NULL); 742 866 if (ret != LDB_SUCCESS) { 743 867 PyErr_SetString(PyExc_TypeError, "failed to build request"); … … 746 870 } 747 871 748 872 /* do request and autostart a transaction */ 749 873 /* Then let's LDB handle the message error in case of pb as they are meaningful */ 750 874 751 ret = ldb_transaction_start(ldb_ctx); 752 if (ret != LDB_SUCCESS) { 753 talloc_free(req); 875 ret = ldb_transaction_start(ldb_ctx); 876 if (ret != LDB_SUCCESS) { 754 877 talloc_free(mem_ctx); 755 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, PyLdb_AsLdbContext(self)); 756 } 757 758 ret = ldb_request(ldb_ctx, req); 759 if (ret == LDB_SUCCESS) { 760 ret = ldb_wait(req->handle, LDB_WAIT_ALL); 761 } 762 878 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx); 879 } 880 881 ret = ldb_request(ldb_ctx, req); 763 882 if (ret == LDB_SUCCESS) { 764 ret = ldb_transaction_commit(ldb_ctx); 765 } else { 766 ldb_transaction_cancel(ldb_ctx); 883 ret = ldb_wait(req->handle, LDB_WAIT_ALL); 884 } 885 886 if (ret == LDB_SUCCESS) { 887 ret = ldb_transaction_commit(ldb_ctx); 888 } else { 889 ldb_transaction_cancel(ldb_ctx); 767 890 if (ldb_ctx->err_string == NULL) { 768 891 /* no error string was setup by the backend */ … … 770 893 } 771 894 } 772 talloc_free(req); 895 773 896 talloc_free(mem_ctx); 774 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, PyLdb_AsLdbContext(self)); 897 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx); 898 899 Py_RETURN_NONE; 900 } 901 902 903 /** 904 * Obtain a ldb message from a Python Dictionary object. 905 * 906 * @param mem_ctx Memory context 907 * @param py_obj Python Dictionary object 908 * @param ldb_ctx LDB context 909 * @param mod_flags Flags to be set on every message element 910 * @return ldb_message on success or NULL on failure 911 */ 912 static struct ldb_message *PyDict_AsMessage(TALLOC_CTX *mem_ctx, 913 PyObject *py_obj, 914 struct ldb_context *ldb_ctx, 915 unsigned int mod_flags) 916 { 917 struct ldb_message *msg; 918 unsigned int msg_pos = 0; 919 Py_ssize_t dict_pos = 0; 920 PyObject *key, *value; 921 struct ldb_message_element *msg_el; 922 PyObject *dn_value = PyDict_GetItemString(py_obj, "dn"); 923 924 msg = ldb_msg_new(mem_ctx); 925 msg->elements = talloc_zero_array(msg, struct ldb_message_element, PyDict_Size(py_obj)); 926 927 if (dn_value) { 928 if (!PyObject_AsDn(msg, dn_value, ldb_ctx, &msg->dn)) { 929 PyErr_SetString(PyExc_TypeError, "unable to import dn object"); 930 return NULL; 931 } 932 if (msg->dn == NULL) { 933 PyErr_SetString(PyExc_TypeError, "dn set but not found"); 934 return NULL; 935 } 936 } else { 937 PyErr_SetString(PyExc_TypeError, "no dn set"); 938 return NULL; 939 } 940 941 while (PyDict_Next(py_obj, &dict_pos, &key, &value)) { 942 char *key_str = PyString_AsString(key); 943 if (strcmp(key_str, "dn") != 0) { 944 msg_el = PyObject_AsMessageElement(msg->elements, value, 945 mod_flags, key_str); 946 if (msg_el == NULL) { 947 PyErr_SetString(PyExc_TypeError, "unable to import element"); 948 return NULL; 949 } 950 memcpy(&msg->elements[msg_pos], msg_el, sizeof(*msg_el)); 951 msg_pos++; 952 } 953 } 954 955 msg->num_elements = msg_pos; 956 957 return msg; 958 } 959 960 static PyObject *py_ldb_add(PyLdbObject *self, PyObject *args) 961 { 962 PyObject *py_obj; 963 int ret; 964 struct ldb_context *ldb_ctx; 965 struct ldb_request *req; 966 struct ldb_message *msg = NULL; 967 PyObject *py_controls = Py_None; 968 TALLOC_CTX *mem_ctx; 969 struct ldb_control **parsed_controls; 970 971 if (!PyArg_ParseTuple(args, "O|O", &py_obj, &py_controls )) 972 return NULL; 973 974 mem_ctx = talloc_new(NULL); 975 if (mem_ctx == NULL) { 976 PyErr_NoMemory(); 977 return NULL; 978 } 979 ldb_ctx = PyLdb_AsLdbContext(self); 980 981 if (py_controls == Py_None) { 982 parsed_controls = NULL; 983 } else { 984 const char **controls = PyList_AsStringList(mem_ctx, py_controls, "controls"); 985 parsed_controls = ldb_parse_control_strings(ldb_ctx, mem_ctx, controls); 986 talloc_free(controls); 987 } 988 989 if (PyLdbMessage_Check(py_obj)) { 990 msg = PyLdbMessage_AsMessage(py_obj); 991 } else if (PyDict_Check(py_obj)) { 992 msg = PyDict_AsMessage(mem_ctx, py_obj, ldb_ctx, LDB_FLAG_MOD_ADD); 993 } else { 994 PyErr_SetString(PyExc_TypeError, 995 "Dictionary or LdbMessage object expected!"); 996 } 997 998 if (!msg) { 999 /* we should have a PyErr already set */ 1000 talloc_free(mem_ctx); 1001 return NULL; 1002 } 1003 1004 ret = ldb_msg_sanity_check(ldb_ctx, msg); 1005 if (ret != LDB_SUCCESS) { 1006 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx); 1007 talloc_free(mem_ctx); 1008 return NULL; 1009 } 1010 1011 ret = ldb_build_add_req(&req, ldb_ctx, mem_ctx, msg, parsed_controls, 1012 NULL, ldb_op_default_callback, NULL); 1013 if (ret != LDB_SUCCESS) { 1014 PyErr_SetString(PyExc_TypeError, "failed to build request"); 1015 talloc_free(mem_ctx); 1016 return NULL; 1017 } 1018 1019 /* do request and autostart a transaction */ 1020 /* Then let's LDB handle the message error in case of pb as they are meaningful */ 1021 1022 ret = ldb_transaction_start(ldb_ctx); 1023 if (ret != LDB_SUCCESS) { 1024 talloc_free(mem_ctx); 1025 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx); 1026 } 1027 1028 ret = ldb_request(ldb_ctx, req); 1029 if (ret == LDB_SUCCESS) { 1030 ret = ldb_wait(req->handle, LDB_WAIT_ALL); 1031 } 1032 1033 if (ret == LDB_SUCCESS) { 1034 ret = ldb_transaction_commit(ldb_ctx); 1035 } else { 1036 ldb_transaction_cancel(ldb_ctx); 1037 if (ldb_ctx->err_string == NULL) { 1038 /* no error string was setup by the backend */ 1039 ldb_asprintf_errstring(ldb_ctx, "%s (%d)", ldb_strerror(ret), ret); 1040 } 1041 } 1042 1043 talloc_free(mem_ctx); 1044 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx); 775 1045 776 1046 Py_RETURN_NONE; … … 782 1052 struct ldb_dn *dn; 783 1053 int ret; 784 struct ldb_context *ldb; 785 if (!PyArg_ParseTuple(args, "O", &py_dn)) 786 return NULL; 787 788 ldb = PyLdb_AsLdbContext(self); 789 790 if (!PyObject_AsDn(NULL, py_dn, ldb, &dn)) 791 return NULL; 792 793 ret = ldb_delete(ldb, dn); 794 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb); 1054 struct ldb_context *ldb_ctx; 1055 struct ldb_request *req; 1056 PyObject *py_controls = Py_None; 1057 TALLOC_CTX *mem_ctx; 1058 struct ldb_control **parsed_controls; 1059 1060 if (!PyArg_ParseTuple(args, "O|O", &py_dn, &py_controls)) 1061 return NULL; 1062 1063 mem_ctx = talloc_new(NULL); 1064 if (mem_ctx == NULL) { 1065 PyErr_NoMemory(); 1066 return NULL; 1067 } 1068 ldb_ctx = PyLdb_AsLdbContext(self); 1069 1070 if (py_controls == Py_None) { 1071 parsed_controls = NULL; 1072 } else { 1073 const char **controls = PyList_AsStringList(mem_ctx, py_controls, "controls"); 1074 parsed_controls = ldb_parse_control_strings(ldb_ctx, mem_ctx, controls); 1075 talloc_free(controls); 1076 } 1077 1078 if (!PyObject_AsDn(mem_ctx, py_dn, ldb_ctx, &dn)) { 1079 talloc_free(mem_ctx); 1080 return NULL; 1081 } 1082 1083 ret = ldb_build_del_req(&req, ldb_ctx, mem_ctx, dn, parsed_controls, 1084 NULL, ldb_op_default_callback, NULL); 1085 if (ret != LDB_SUCCESS) { 1086 PyErr_SetString(PyExc_TypeError, "failed to build request"); 1087 talloc_free(mem_ctx); 1088 return NULL; 1089 } 1090 1091 /* do request and autostart a transaction */ 1092 /* Then let's LDB handle the message error in case of pb as they are meaningful */ 1093 1094 ret = ldb_transaction_start(ldb_ctx); 1095 if (ret != LDB_SUCCESS) { 1096 talloc_free(mem_ctx); 1097 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx); 1098 } 1099 1100 ret = ldb_request(ldb_ctx, req); 1101 if (ret == LDB_SUCCESS) { 1102 ret = ldb_wait(req->handle, LDB_WAIT_ALL); 1103 } 1104 1105 if (ret == LDB_SUCCESS) { 1106 ret = ldb_transaction_commit(ldb_ctx); 1107 } else { 1108 ldb_transaction_cancel(ldb_ctx); 1109 if (ldb_ctx->err_string == NULL) { 1110 /* no error string was setup by the backend */ 1111 ldb_asprintf_errstring(ldb_ctx, "%s (%d)", ldb_strerror(ret), ret); 1112 } 1113 } 1114 1115 talloc_free(mem_ctx); 1116 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx); 795 1117 796 1118 Py_RETURN_NONE; … … 804 1126 struct ldb_context *ldb; 805 1127 TALLOC_CTX *mem_ctx; 806 if (!PyArg_ParseTuple(args, "OO", &py_dn1, &py_dn2)) 807 return NULL; 1128 PyObject *py_controls = Py_None; 1129 struct ldb_control **parsed_controls; 1130 struct ldb_context *ldb_ctx; 1131 struct ldb_request *req; 1132 1133 ldb_ctx = PyLdb_AsLdbContext(self); 1134 1135 if (!PyArg_ParseTuple(args, "OO|O", &py_dn1, &py_dn2, &py_controls)) 1136 return NULL; 1137 808 1138 809 1139 mem_ctx = talloc_new(NULL); … … 813 1143 } 814 1144 ldb = PyLdb_AsLdbContext(self); 1145 1146 if (py_controls == Py_None) { 1147 parsed_controls = NULL; 1148 } else { 1149 const char **controls = PyList_AsStringList(mem_ctx, py_controls, "controls"); 1150 parsed_controls = ldb_parse_control_strings(ldb_ctx, mem_ctx, controls); 1151 talloc_free(controls); 1152 } 1153 1154 815 1155 if (!PyObject_AsDn(mem_ctx, py_dn1, ldb, &dn1)) { 816 1156 talloc_free(mem_ctx); … … 823 1163 } 824 1164 825 ret = ldb_rename(ldb, dn1, dn2); 1165 ret = ldb_build_rename_req(&req, ldb_ctx, mem_ctx, dn1, dn2, parsed_controls, 1166 NULL, ldb_op_default_callback, NULL); 1167 if (ret != LDB_SUCCESS) { 1168 PyErr_SetString(PyExc_TypeError, "failed to build request"); 1169 talloc_free(mem_ctx); 1170 return NULL; 1171 } 1172 1173 /* do request and autostart a transaction */ 1174 /* Then let's LDB handle the message error in case of pb as they are meaningful */ 1175 1176 ret = ldb_transaction_start(ldb_ctx); 1177 if (ret != LDB_SUCCESS) { 1178 talloc_free(mem_ctx); 1179 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx); 1180 } 1181 1182 ret = ldb_request(ldb_ctx, req); 1183 if (ret == LDB_SUCCESS) { 1184 ret = ldb_wait(req->handle, LDB_WAIT_ALL); 1185 } 1186 1187 if (ret == LDB_SUCCESS) { 1188 ret = ldb_transaction_commit(ldb_ctx); 1189 } else { 1190 ldb_transaction_cancel(ldb_ctx); 1191 if (ldb_ctx->err_string == NULL) { 1192 /* no error string was setup by the backend */ 1193 ldb_asprintf_errstring(ldb_ctx, "%s (%d)", ldb_strerror(ret), ret); 1194 } 1195 } 1196 826 1197 talloc_free(mem_ctx); 827 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb );1198 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx); 828 1199 829 1200 Py_RETURN_NONE; … … 869 1240 870 1241 871 static PyObject *py_ldb_write_ldif(PyLdb MessageObject *self, PyObject *args)1242 static PyObject *py_ldb_write_ldif(PyLdbObject *self, PyObject *args) 872 1243 { 873 1244 int changetype; … … 938 1309 static PyObject *py_ldb_msg_diff(PyLdbObject *self, PyObject *args) 939 1310 { 1311 int ldb_ret; 940 1312 PyObject *py_msg_old; 941 1313 PyObject *py_msg_new; 942 1314 struct ldb_message *diff; 1315 struct ldb_context *ldb; 943 1316 PyObject *py_ret; 944 1317 … … 956 1329 } 957 1330 958 diff = ldb_msg_diff(PyLdb_AsLdbContext(self), PyLdbMessage_AsMessage(py_msg_old), PyLdbMessage_AsMessage(py_msg_new)); 959 if (diff == NULL) 960 return NULL; 1331 ldb = PyLdb_AsLdbContext(self); 1332 ldb_ret = ldb_msg_difference(ldb, ldb, 1333 PyLdbMessage_AsMessage(py_msg_old), 1334 PyLdbMessage_AsMessage(py_msg_new), 1335 &diff); 1336 if (ldb_ret != LDB_SUCCESS) { 1337 PyErr_SetString(PyExc_RuntimeError, "Failed to generate the Ldb Message diff"); 1338 return NULL; 1339 } 961 1340 962 1341 py_ret = PyLdbMessage_FromMessage(diff); 1342 1343 talloc_unlink(ldb, diff); 963 1344 964 1345 return py_ret; … … 1004 1385 { 1005 1386 PyObject *py_base = Py_None; 1006 enum ldb_scopescope = LDB_SCOPE_DEFAULT;1387 int scope = LDB_SCOPE_DEFAULT; 1007 1388 char *expr = NULL; 1008 1389 PyObject *py_attrs = Py_None; … … 1017 1398 struct ldb_dn *base; 1018 1399 PyObject *py_ret; 1019 1400 TALLOC_CTX *mem_ctx; 1401 1402 /* type "int" rather than "enum" for "scope" is intentional */ 1020 1403 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|OizOO", 1021 1404 discard_const_p(char *, kwnames), … … 1023 1406 return NULL; 1024 1407 1408 1409 mem_ctx = talloc_new(NULL); 1410 if (mem_ctx == NULL) { 1411 PyErr_NoMemory(); 1412 return NULL; 1413 } 1025 1414 ldb_ctx = PyLdb_AsLdbContext(self); 1026 1415 … … 1028 1417 attrs = NULL; 1029 1418 } else { 1030 attrs = PyList_AsStringList(NULL, py_attrs, "attrs"); 1031 if (attrs == NULL) 1419 attrs = PyList_AsStringList(mem_ctx, py_attrs, "attrs"); 1420 if (attrs == NULL) { 1421 talloc_free(mem_ctx); 1032 1422 return NULL; 1423 } 1033 1424 } 1034 1425 … … 1045 1436 parsed_controls = NULL; 1046 1437 } else { 1047 const char **controls = PyList_AsStringList( ldb_ctx, py_controls, "controls");1048 parsed_controls = ldb_parse_control_strings(ldb_ctx, ldb_ctx, controls);1438 const char **controls = PyList_AsStringList(mem_ctx, py_controls, "controls"); 1439 parsed_controls = ldb_parse_control_strings(ldb_ctx, mem_ctx, controls); 1049 1440 talloc_free(controls); 1050 1441 } 1051 1442 1052 res = talloc_zero( ldb_ctx, struct ldb_result);1443 res = talloc_zero(mem_ctx, struct ldb_result); 1053 1444 if (res == NULL) { 1054 1445 PyErr_NoMemory(); 1055 talloc_free( attrs);1056 return NULL; 1057 } 1058 1059 ret = ldb_build_search_req(&req, ldb_ctx, ldb_ctx,1446 talloc_free(mem_ctx); 1447 return NULL; 1448 } 1449 1450 ret = ldb_build_search_req(&req, ldb_ctx, mem_ctx, 1060 1451 base, 1061 1452 scope, … … 1067 1458 NULL); 1068 1459 1460 if (ret != LDB_SUCCESS) { 1461 talloc_free(mem_ctx); 1462 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx); 1463 return NULL; 1464 } 1465 1069 1466 talloc_steal(req, attrs); 1070 1071 if (ret != LDB_SUCCESS) {1072 talloc_free(res);1073 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);1074 return NULL;1075 }1076 1467 1077 1468 ret = ldb_request(ldb_ctx, req); … … 1081 1472 } 1082 1473 1083 talloc_free(req);1084 1085 1474 if (ret != LDB_SUCCESS) { 1086 talloc_free( res);1475 talloc_free(mem_ctx); 1087 1476 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx); 1088 1477 return NULL; … … 1091 1480 py_ret = PyLdbResult_FromResult(res); 1092 1481 1093 talloc_free( res);1482 talloc_free(mem_ctx); 1094 1483 1095 1484 return py_ret; … … 1142 1531 } 1143 1532 1533 static PyObject *py_ldb_sequence_number(PyLdbObject *self, PyObject *args) 1534 { 1535 struct ldb_context *ldb = PyLdb_AsLdbContext(self); 1536 int type, ret; 1537 uint64_t value; 1538 1539 if (!PyArg_ParseTuple(args, "i", &type)) 1540 return NULL; 1541 1542 /* FIXME: More interpretation */ 1543 1544 ret = ldb_sequence_number(ldb, type, &value); 1545 1546 if (ret != LDB_SUCCESS) { 1547 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb); 1548 return NULL; 1549 } 1550 return PyLong_FromLongLong(value); 1551 } 1144 1552 static PyMethodDef py_ldb_methods[] = { 1145 1553 { "set_debug", (PyCFunction)py_ldb_set_debug, METH_VARARGS, … … 1156 1564 "S.transaction_start() -> None\n" 1157 1565 "Start a new transaction." }, 1566 { "transaction_prepare_commit", (PyCFunction)py_ldb_transaction_prepare_commit, METH_NOARGS, 1567 "S.transaction_prepare_commit() -> None\n" 1568 "prepare to commit a new transaction (2-stage commit)." }, 1158 1569 { "transaction_commit", (PyCFunction)py_ldb_transaction_commit, METH_NOARGS, 1159 1570 "S.transaction_commit() -> None\n" … … 1225 1636 "S.modules() -> list\n" 1226 1637 "Return the list of modules on this LDB connection " }, 1638 { "sequence_number", (PyCFunction)py_ldb_sequence_number, METH_VARARGS, 1639 "S.sequence_number(type) -> value\n" 1640 "Return the value of the sequence according to the requested type" }, 1227 1641 { NULL }, 1228 1642 }; 1229 1643 1230 PyObject *PyLdbModule_FromModule(struct ldb_module *mod)1644 static PyObject *PyLdbModule_FromModule(struct ldb_module *mod) 1231 1645 { 1232 1646 PyLdbModuleObject *ret; … … 1257 1671 struct ldb_dn *dn; 1258 1672 struct ldb_result *result; 1673 unsigned int count; 1259 1674 int ret; 1260 int count; 1261 1262 if (!PyObject_AsDn(ldb_ctx, obj, ldb_ctx, &dn)) 1675 1676 if (!PyObject_AsDn(ldb_ctx, obj, ldb_ctx, &dn)) { 1263 1677 return -1; 1264 1265 ret = ldb_search(ldb_ctx, ldb_ctx, &result, dn, LDB_SCOPE_BASE, NULL, NULL); 1678 } 1679 1680 ret = ldb_search(ldb_ctx, ldb_ctx, &result, dn, LDB_SCOPE_BASE, NULL, 1681 NULL); 1266 1682 if (ret != LDB_SUCCESS) { 1267 1683 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx); … … 1273 1689 talloc_free(result); 1274 1690 1691 if (count > 1) { 1692 PyErr_Format(PyExc_RuntimeError, 1693 "Searching for [%s] dn gave %u results!", 1694 ldb_dn_get_linearized(dn), 1695 count); 1696 return -1; 1697 } 1698 1275 1699 return count; 1276 1700 } … … 1280 1704 }; 1281 1705 1282 PyObject *PyLdb_FromLdbContext(struct ldb_context *ldb_ctx)1706 static PyObject *PyLdb_FromLdbContext(struct ldb_context *ldb_ctx) 1283 1707 { 1284 1708 PyLdbObject *ret; … … 1300 1724 } 1301 1725 1302 PyTypeObject PyLdb = {1303 .tp_name = " Ldb",1726 static PyTypeObject PyLdb = { 1727 .tp_name = "ldb.Ldb", 1304 1728 .tp_methods = py_ldb_methods, 1305 1729 .tp_repr = (reprfunc)py_ldb_repr, … … 1315 1739 }; 1316 1740 1741 static void py_ldb_result_dealloc(PyLdbResultObject *self) 1742 { 1743 talloc_free(self->mem_ctx); 1744 Py_DECREF(self->msgs); 1745 Py_DECREF(self->referals); 1746 Py_DECREF(self->controls); 1747 self->ob_type->tp_free(self); 1748 } 1749 1750 static PyObject *py_ldb_result_get_msgs(PyLdbResultObject *self, void *closure) 1751 { 1752 Py_INCREF(self->msgs); 1753 return self->msgs; 1754 } 1755 1756 static PyObject *py_ldb_result_get_controls(PyLdbResultObject *self, void *closure) 1757 { 1758 Py_INCREF(self->controls); 1759 return self->controls; 1760 } 1761 1762 static PyObject *py_ldb_result_get_referals(PyLdbResultObject *self, void *closure) 1763 { 1764 Py_INCREF(self->referals); 1765 return self->referals; 1766 } 1767 1768 static PyObject *py_ldb_result_get_count(PyLdbResultObject *self, void *closure) 1769 { 1770 Py_ssize_t size; 1771 if (self->msgs == NULL) { 1772 PyErr_SetString(PyExc_AttributeError, "Count attribute is meaningless in this context"); 1773 return NULL; 1774 } 1775 size = PyList_Size(self->msgs); 1776 return PyInt_FromLong(size); 1777 } 1778 1779 static PyGetSetDef py_ldb_result_getset[] = { 1780 { discard_const_p(char, "controls"), (getter)py_ldb_result_get_controls, NULL, NULL }, 1781 { discard_const_p(char, "msgs"), (getter)py_ldb_result_get_msgs, NULL, NULL }, 1782 { discard_const_p(char, "referals"), (getter)py_ldb_result_get_referals, NULL, NULL }, 1783 { discard_const_p(char, "count"), (getter)py_ldb_result_get_count, NULL, NULL }, 1784 { NULL } 1785 }; 1786 1787 static PyObject *py_ldb_result_iter(PyLdbResultObject *self) 1788 { 1789 return PyObject_GetIter(self->msgs); 1790 } 1791 1792 static Py_ssize_t py_ldb_result_len(PyLdbResultObject *self) 1793 { 1794 return PySequence_Size(self->msgs); 1795 } 1796 1797 static PyObject *py_ldb_result_find(PyLdbResultObject *self, Py_ssize_t idx) 1798 { 1799 return PySequence_GetItem(self->msgs, idx); 1800 } 1801 1802 static PySequenceMethods py_ldb_result_seq = { 1803 .sq_length = (lenfunc)py_ldb_result_len, 1804 .sq_item = (ssizeargfunc)py_ldb_result_find, 1805 }; 1806 1807 static PyObject *py_ldb_result_repr(PyLdbObject *self) 1808 { 1809 return PyString_FromFormat("<ldb result>"); 1810 } 1811 1812 1813 static PyTypeObject PyLdbResult = { 1814 .tp_name = "ldb.Result", 1815 .tp_repr = (reprfunc)py_ldb_result_repr, 1816 .tp_dealloc = (destructor)py_ldb_result_dealloc, 1817 .tp_iter = (getiterfunc)py_ldb_result_iter, 1818 .tp_getset = py_ldb_result_getset, 1819 .tp_getattro = PyObject_GenericGetAttr, 1820 .tp_basicsize = sizeof(PyLdbResultObject), 1821 .tp_as_sequence = &py_ldb_result_seq, 1822 .tp_doc = "LDB result.", 1823 .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, 1824 }; 1825 1317 1826 static PyObject *py_ldb_module_repr(PyLdbModuleObject *self) 1318 1827 { … … 1352 1861 const char * const*attrs; 1353 1862 1863 /* type "int" rather than "enum" for "scope" is intentional */ 1354 1864 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OiOO", 1355 1865 discard_const_p(char *, kwnames), … … 1490 2000 { 1491 2001 talloc_free(self->mem_ctx); 1492 self->ob_type->tp_free(self);1493 } 1494 1495 PyTypeObject PyLdbModule = {1496 .tp_name = " LdbModule",2002 PyObject_Del(self); 2003 } 2004 2005 static PyTypeObject PyLdbModule = { 2006 .tp_name = "ldb.LdbModule", 1497 2007 .tp_methods = py_ldb_module_methods, 1498 2008 .tp_repr = (reprfunc)py_ldb_module_repr, … … 1518 2028 * @return New ldb_message_element, allocated as child of mem_ctx 1519 2029 */ 1520 struct ldb_message_element *PyObject_AsMessageElement(TALLOC_CTX *mem_ctx, 1521 PyObject *set_obj, int flags, 1522 const char *attr_name) 2030 static struct ldb_message_element *PyObject_AsMessageElement( 2031 TALLOC_CTX *mem_ctx, 2032 PyObject *set_obj, 2033 int flags, 2034 const char *attr_name) 1523 2035 { 1524 2036 struct ldb_message_element *me; 1525 2037 1526 if (PyLdbMessageElement_Check(set_obj)) 1527 return talloc_reference(mem_ctx, 1528 PyLdbMessageElement_AsMessageElement(set_obj)); 2038 if (PyLdbMessageElement_Check(set_obj)) { 2039 PyLdbMessageElementObject *set_obj_as_me = (PyLdbMessageElementObject *)set_obj; 2040 /* We have to talloc_reference() the memory context, not the pointer 2041 * which may not actually be it's own context */ 2042 if (talloc_reference(mem_ctx, set_obj_as_me->mem_ctx)) { 2043 return PyLdbMessageElement_AsMessageElement(set_obj); 2044 } 2045 return NULL; 2046 } 1529 2047 1530 2048 me = talloc(mem_ctx, struct ldb_message_element); 2049 if (me == NULL) { 2050 PyErr_NoMemory(); 2051 return NULL; 2052 } 1531 2053 1532 2054 me->name = talloc_strdup(me, attr_name); … … 1537 2059 me->values[0].length = PyString_Size(set_obj); 1538 2060 me->values[0].data = talloc_memdup(me, 1539 (uint8_t *)PyString_AsString(set_obj), me->values[0].length );2061 (uint8_t *)PyString_AsString(set_obj), me->values[0].length+1); 1540 2062 } else if (PySequence_Check(set_obj)) { 1541 int i;2063 Py_ssize_t i; 1542 2064 me->num_values = PySequence_Size(set_obj); 1543 2065 me->values = talloc_array(me, struct ldb_val, me->num_values); 1544 2066 for (i = 0; i < me->num_values; i++) { 1545 2067 PyObject *obj = PySequence_GetItem(set_obj, i); 2068 if (!PyString_Check(obj)) { 2069 PyErr_Format(PyExc_TypeError, 2070 "Expected string as element %zd in list", i); 2071 talloc_free(me); 2072 return NULL; 2073 } 1546 2074 1547 2075 me->values[i].length = PyString_Size(obj); 1548 2076 me->values[i].data = talloc_memdup(me, 1549 (uint8_t *)PyString_AsString(obj), me->values[i].length );2077 (uint8_t *)PyString_AsString(obj), me->values[i].length+1); 1550 2078 } 1551 2079 } else { … … 1558 2086 1559 2087 1560 static PyObject *ldb_msg_element_to_set(struct ldb_context *ldb_ctx, 1561 1562 { 1563 int i;2088 static PyObject *ldb_msg_element_to_set(struct ldb_context *ldb_ctx, 2089 struct ldb_message_element *me) 2090 { 2091 Py_ssize_t i; 1564 2092 PyObject *result; 1565 2093 … … 1569 2097 for (i = 0; i < me->num_values; i++) { 1570 2098 PyList_SetItem(result, i, 1571 PyObject_FromLdbValue( ldb_ctx, me,&me->values[i]));2099 PyObject_FromLdbValue(&me->values[i])); 1572 2100 } 1573 2101 … … 1577 2105 static PyObject *py_ldb_msg_element_get(PyLdbMessageElementObject *self, PyObject *args) 1578 2106 { 1579 int i;1580 if (!PyArg_ParseTuple(args, " i", &i))1581 return NULL; 1582 if (i < 0 || i>= PyLdbMessageElement_AsMessageElement(self)->num_values)2107 unsigned int i; 2108 if (!PyArg_ParseTuple(args, "I", &i)) 2109 return NULL; 2110 if (i >= PyLdbMessageElement_AsMessageElement(self)->num_values) 1583 2111 Py_RETURN_NONE; 1584 2112 1585 return PyObject_FromLdbValue(NULL, PyLdbMessageElement_AsMessageElement(self), 1586 &(PyLdbMessageElement_AsMessageElement(self)->values[i])); 2113 return PyObject_FromLdbValue(&(PyLdbMessageElement_AsMessageElement(self)->values[i])); 1587 2114 } 1588 2115 1589 2116 static PyObject *py_ldb_msg_element_flags(PyLdbMessageElementObject *self, PyObject *args) 1590 2117 { 1591 struct ldb_message_element *el; 1592 1593 el = PyLdbMessageElement_AsMessageElement(self); 2118 struct ldb_message_element *el = PyLdbMessageElement_AsMessageElement(self); 1594 2119 return PyInt_FromLong(el->flags); 1595 2120 } … … 1636 2161 static int py_ldb_msg_element_cmp(PyLdbMessageElementObject *self, PyLdbMessageElementObject *other) 1637 2162 { 1638 return ldb_msg_element_compare(PyLdbMessageElement_AsMessageElement(self), 1639 PyLdbMessageElement_AsMessageElement(other)); 2163 int ret = ldb_msg_element_compare(PyLdbMessageElement_AsMessageElement(self), 2164 PyLdbMessageElement_AsMessageElement(other)); 2165 return SIGN(ret); 1640 2166 } 1641 2167 … … 1645 2171 } 1646 2172 1647 PyObject *PyLdbMessageElement_FromMessageElement(struct ldb_message_element *el, TALLOC_CTX *mem_ctx)2173 static PyObject *PyLdbMessageElement_FromMessageElement(struct ldb_message_element *el, TALLOC_CTX *mem_ctx) 1648 2174 { 1649 2175 PyLdbMessageElementObject *ret; 1650 ret = (PyLdbMessageElementObject *)PyLdbMessageElement.tp_alloc(&PyLdbMessageElement, 0);2176 ret = PyObject_New(PyLdbMessageElementObject, &PyLdbMessageElement); 1651 2177 if (ret == NULL) { 1652 2178 PyErr_NoMemory(); … … 1684 2210 1685 2211 el = talloc_zero(mem_ctx, struct ldb_message_element); 2212 if (el == NULL) { 2213 PyErr_NoMemory(); 2214 talloc_free(mem_ctx); 2215 return NULL; 2216 } 1686 2217 1687 2218 if (py_elements != NULL) { 1688 int i;2219 Py_ssize_t i; 1689 2220 if (PyString_Check(py_elements)) { 1690 2221 el->num_values = 1; 1691 2222 el->values = talloc_array(el, struct ldb_val, 1); 2223 if (el->values == NULL) { 2224 talloc_free(mem_ctx); 2225 PyErr_NoMemory(); 2226 return NULL; 2227 } 1692 2228 el->values[0].length = PyString_Size(py_elements); 1693 el->values[0].data = talloc_memdup(el ,1694 (uint8_t *)PyString_AsString(py_elements), el->values[0].length );2229 el->values[0].data = talloc_memdup(el->values, 2230 (uint8_t *)PyString_AsString(py_elements), el->values[0].length+1); 1695 2231 } else if (PySequence_Check(py_elements)) { 1696 2232 el->num_values = PySequence_Size(py_elements); 1697 2233 el->values = talloc_array(el, struct ldb_val, el->num_values); 2234 if (el->values == NULL) { 2235 talloc_free(mem_ctx); 2236 PyErr_NoMemory(); 2237 return NULL; 2238 } 1698 2239 for (i = 0; i < el->num_values; i++) { 1699 2240 PyObject *item = PySequence_GetItem(py_elements, i); 2241 if (item == NULL) { 2242 talloc_free(mem_ctx); 2243 return NULL; 2244 } 1700 2245 if (!PyString_Check(item)) { 1701 2246 PyErr_Format(PyExc_TypeError, 1702 "Expected string as element %d in list", 1703 i); 2247 "Expected string as element %zd in list", i); 1704 2248 talloc_free(mem_ctx); 1705 2249 return NULL; 1706 2250 } 1707 2251 el->values[i].length = PyString_Size(item); 1708 el->values[i].data = talloc_memdup(el, 1709 (uint8_t *)PyString_AsString(item), el->values[i].length );2252 el->values[i].data = talloc_memdup(el, 2253 (uint8_t *)PyString_AsString(item), el->values[i].length+1); 1710 2254 } 1711 2255 } else { … … 1720 2264 el->name = talloc_strdup(el, name); 1721 2265 1722 ret = (PyLdbMessageElementObject *)PyLdbMessageElement.tp_alloc(&PyLdbMessageElement, 0);2266 ret = PyObject_New(PyLdbMessageElementObject, type); 1723 2267 if (ret == NULL) { 1724 PyErr_NoMemory();1725 2268 talloc_free(mem_ctx); 1726 2269 return NULL; … … 1735 2278 { 1736 2279 char *element_str = NULL; 1737 int i;2280 Py_ssize_t i; 1738 2281 struct ldb_message_element *el = PyLdbMessageElement_AsMessageElement(self); 1739 2282 PyObject *ret; … … 1747 2290 } 1748 2291 1749 ret = PyString_FromFormat("MessageElement([%s])", element_str); 1750 1751 talloc_free(element_str); 2292 if (element_str != NULL) { 2293 ret = PyString_FromFormat("MessageElement([%s])", element_str); 2294 talloc_free(element_str); 2295 } else { 2296 ret = PyString_FromString("MessageElement([])"); 2297 } 1752 2298 1753 2299 return ret; … … 1760 2306 if (el->num_values == 1) 1761 2307 return PyString_FromStringAndSize((char *)el->values[0].data, el->values[0].length); 1762 else 2308 else 1763 2309 Py_RETURN_NONE; 1764 2310 } … … 1767 2313 { 1768 2314 talloc_free(self->mem_ctx); 1769 self->ob_type->tp_free(self);1770 } 1771 1772 PyTypeObject PyLdbMessageElement = {1773 .tp_name = " MessageElement",2315 PyObject_Del(self); 2316 } 2317 2318 static PyTypeObject PyLdbMessageElement = { 2319 .tp_name = "ldb.MessageElement", 1774 2320 .tp_basicsize = sizeof(PyLdbMessageElementObject), 1775 2321 .tp_dealloc = (destructor)py_ldb_msg_element_dealloc, … … 1784 2330 }; 1785 2331 2332 2333 static PyObject *py_ldb_msg_from_dict(PyTypeObject *type, PyObject *args) 2334 { 2335 PyObject *py_ldb; 2336 PyObject *py_dict; 2337 PyObject *py_ret; 2338 struct ldb_message *msg; 2339 struct ldb_context *ldb_ctx; 2340 unsigned int mod_flags = LDB_FLAG_MOD_REPLACE; 2341 2342 if (!PyArg_ParseTuple(args, "O!O!|I", 2343 &PyLdb, &py_ldb, &PyDict_Type, &py_dict, 2344 &mod_flags)) { 2345 return NULL; 2346 } 2347 2348 /* mask only flags we are going to use */ 2349 mod_flags = LDB_FLAG_MOD_TYPE(mod_flags); 2350 if (!mod_flags) { 2351 PyErr_SetString(PyExc_ValueError, 2352 "FLAG_MOD_ADD, FLAG_MOD_REPLACE or FLAG_MOD_DELETE" 2353 " expected as mod_flag value"); 2354 return NULL; 2355 } 2356 2357 ldb_ctx = PyLdb_AsLdbContext(py_ldb); 2358 2359 msg = PyDict_AsMessage(ldb_ctx, py_dict, ldb_ctx, mod_flags); 2360 if (!msg) { 2361 return NULL; 2362 } 2363 2364 py_ret = PyLdbMessage_FromMessage(msg); 2365 2366 talloc_unlink(ldb_ctx, msg); 2367 2368 return py_ret; 2369 } 2370 1786 2371 static PyObject *py_ldb_msg_remove_attr(PyLdbMessageObject *self, PyObject *args) 1787 2372 { … … 1798 2383 { 1799 2384 struct ldb_message *msg = PyLdbMessage_AsMessage(self); 1800 int i, j = 0;2385 Py_ssize_t i, j = 0; 1801 2386 PyObject *obj = PyList_New(msg->num_elements+(msg->dn != NULL?1:0)); 1802 2387 if (msg->dn != NULL) { … … 1827 2412 return NULL; 1828 2413 } 1829 return (PyObject *)PyLdbMessageElement_FromMessageElement(el, msg );2414 return (PyObject *)PyLdbMessageElement_FromMessageElement(el, msg->elements); 1830 2415 } 1831 2416 … … 1858 2443 { 1859 2444 struct ldb_message *msg = PyLdbMessage_AsMessage(self); 1860 int i, j;2445 Py_ssize_t i, j = 0; 1861 2446 PyObject *l = PyList_New(msg->num_elements + (msg->dn == NULL?0:1)); 1862 j = 0;1863 2447 if (msg->dn != NULL) { 1864 2448 PyList_SetItem(l, 0, Py_BuildValue("(sO)", "dn", PyLdbDn_FromDn(msg->dn))); … … 1866 2450 } 1867 2451 for (i = 0; i < msg->num_elements; i++, j++) { 1868 PyList_SetItem(l, j, Py_BuildValue("(sO)", msg->elements[i].name, PyLdbMessageElement_FromMessageElement(&msg->elements[i], self->msg))); 2452 PyObject *py_el = PyLdbMessageElement_FromMessageElement(&msg->elements[i], msg->elements); 2453 PyObject *value = Py_BuildValue("(sO)", msg->elements[i].name, py_el); 2454 PyList_SetItem(l, j, value); 1869 2455 } 1870 2456 return l; 1871 2457 } 1872 2458 1873 static PyMethodDef py_ldb_msg_methods[] = { 1874 { "keys", (PyCFunction)py_ldb_msg_keys, METH_NOARGS, NULL }, 1875 { "remove", (PyCFunction)py_ldb_msg_remove_attr, METH_VARARGS, NULL }, 2459 static PyObject *py_ldb_msg_elements(PyLdbMessageObject *self) 2460 { 2461 struct ldb_message *msg = PyLdbMessage_AsMessage(self); 2462 Py_ssize_t i = 0; 2463 PyObject *l = PyList_New(msg->num_elements); 2464 for (i = 0; i < msg->num_elements; i++) { 2465 PyList_SetItem(l, i, PyLdbMessageElement_FromMessageElement(&msg->elements[i], msg->elements)); 2466 } 2467 return l; 2468 } 2469 2470 static PyObject *py_ldb_msg_add(PyLdbMessageObject *self, PyObject *args) 2471 { 2472 struct ldb_message *msg = PyLdbMessage_AsMessage(self); 2473 PyLdbMessageElementObject *py_element; 2474 int ret; 2475 struct ldb_message_element *el; 2476 2477 if (!PyArg_ParseTuple(args, "O!", &PyLdbMessageElement, &py_element)) 2478 return NULL; 2479 2480 el = talloc_reference(msg, py_element->el); 2481 if (el == NULL) { 2482 PyErr_NoMemory(); 2483 return NULL; 2484 } 2485 2486 ret = ldb_msg_add(msg, el, el->flags); 2487 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, NULL); 2488 2489 Py_RETURN_NONE; 2490 } 2491 2492 static PyMethodDef py_ldb_msg_methods[] = { 2493 { "from_dict", (PyCFunction)py_ldb_msg_from_dict, METH_CLASS | METH_VARARGS, 2494 "Message.from_dict(ldb, dict, mod_flag=FLAG_MOD_REPLACE) -> ldb.Message\n" 2495 "Class method to create ldb.Message object from Dictionary.\n" 2496 "mod_flag is one of FLAG_MOD_ADD, FLAG_MOD_REPLACE or FLAG_MOD_DELETE."}, 2497 { "keys", (PyCFunction)py_ldb_msg_keys, METH_NOARGS, 2498 "S.keys() -> list\n\n" 2499 "Return sequence of all attribute names." }, 2500 { "remove", (PyCFunction)py_ldb_msg_remove_attr, METH_VARARGS, 2501 "S.remove(name)\n\n" 2502 "Remove all entries for attributes with the specified name."}, 1876 2503 { "get", (PyCFunction)py_ldb_msg_get, METH_VARARGS, NULL }, 1877 2504 { "items", (PyCFunction)py_ldb_msg_items, METH_NOARGS, NULL }, 2505 { "elements", (PyCFunction)py_ldb_msg_elements, METH_NOARGS, NULL }, 2506 { "add", (PyCFunction)py_ldb_msg_add, METH_VARARGS, 2507 "S.append(element)\n\n" 2508 "Add an element to this message." }, 1878 2509 { NULL }, 1879 2510 }; … … 1897 2528 return -1; 1898 2529 } 1899 2530 1900 2531 attr_name = PyString_AsString(name); 1901 2532 if (value == NULL) { … … 1904 2535 } else { 1905 2536 struct ldb_message_element *el = PyObject_AsMessageElement(self->msg, 1906 2537 value, 0, attr_name); 1907 2538 if (el == NULL) 1908 2539 return -1; … … 1971 2602 } 1972 2603 1973 PyObject *PyLdbMessage_FromMessage(struct ldb_message *msg)2604 static PyObject *PyLdbMessage_FromMessage(struct ldb_message *msg) 1974 2605 { 1975 2606 PyLdbMessageObject *ret; … … 2021 2652 { 2022 2653 talloc_free(self->mem_ctx); 2023 self->ob_type->tp_free(self); 2024 } 2025 2026 PyTypeObject PyLdbMessage = { 2027 .tp_name = "Message", 2654 PyObject_Del(self); 2655 } 2656 2657 static int py_ldb_msg_compare(PyLdbMessageObject *py_msg1, 2658 PyLdbMessageObject *py_msg2) 2659 { 2660 struct ldb_message *msg1 = PyLdbMessage_AsMessage(py_msg1), 2661 *msg2 = PyLdbMessage_AsMessage(py_msg2); 2662 unsigned int i; 2663 int ret; 2664 2665 if ((msg1->dn != NULL) || (msg2->dn != NULL)) { 2666 ret = ldb_dn_compare(msg1->dn, msg2->dn); 2667 if (ret != 0) { 2668 return SIGN(ret); 2669 } 2670 } 2671 2672 ret = msg1->num_elements - msg2->num_elements; 2673 if (ret != 0) { 2674 return SIGN(ret); 2675 } 2676 2677 for (i = 0; i < msg1->num_elements; i++) { 2678 ret = ldb_msg_element_compare_name(&msg1->elements[i], 2679 &msg2->elements[i]); 2680 if (ret != 0) { 2681 return SIGN(ret); 2682 } 2683 2684 ret = ldb_msg_element_compare(&msg1->elements[i], 2685 &msg2->elements[i]); 2686 if (ret != 0) { 2687 return SIGN(ret); 2688 } 2689 } 2690 2691 return 0; 2692 } 2693 2694 static PyTypeObject PyLdbMessage = { 2695 .tp_name = "ldb.Message", 2028 2696 .tp_methods = py_ldb_msg_methods, 2029 2697 .tp_getset = py_ldb_msg_getset, … … 2035 2703 .tp_flags = Py_TPFLAGS_DEFAULT, 2036 2704 .tp_iter = (getiterfunc)py_ldb_msg_iter, 2705 .tp_compare = (cmpfunc)py_ldb_msg_compare, 2037 2706 }; 2038 2707 2039 PyObject *PyLdbTree_FromTree(struct ldb_parse_tree *tree)2708 static PyObject *PyLdbTree_FromTree(struct ldb_parse_tree *tree) 2040 2709 { 2041 2710 PyLdbTreeObject *ret; … … 2055 2724 { 2056 2725 talloc_free(self->mem_ctx); 2057 self->ob_type->tp_free(self);2058 } 2059 2060 PyTypeObject PyLdbTree = {2061 .tp_name = " Tree",2726 PyObject_Del(self); 2727 } 2728 2729 static PyTypeObject PyLdbTree = { 2730 .tp_name = "ldb.Tree", 2062 2731 .tp_basicsize = sizeof(PyLdbTreeObject), 2063 2732 .tp_dealloc = (destructor)py_ldb_tree_dealloc, … … 2367 3036 static PyObject *py_timestring(PyObject *module, PyObject *args) 2368 3037 { 2369 time_t t; 3038 /* most times "time_t" is a signed integer type with 32 or 64 bit: 3039 * http://stackoverflow.com/questions/471248/what-is-ultimately-a-time-t-typedef-to */ 3040 long int t_val; 2370 3041 char *tresult; 2371 3042 PyObject *ret; 2372 if (!PyArg_ParseTuple(args, " L", &t))2373 return NULL; 2374 tresult = ldb_timestring(NULL, t);3043 if (!PyArg_ParseTuple(args, "l", &t_val)) 3044 return NULL; 3045 tresult = ldb_timestring(NULL, (time_t) t_val); 2375 3046 ret = PyString_FromString(tresult); 2376 3047 talloc_free(tresult); … … 2435 3106 return; 2436 3107 3108 if (PyType_Ready(&PyLdbResult) < 0) 3109 return; 3110 3111 if (PyType_Ready(&PyLdbControl) < 0) 3112 return; 3113 2437 3114 m = Py_InitModule3("ldb", py_ldb_global_methods, 2438 3115 "An interface to LDB, a LDAP-like API that can either to talk an embedded database (TDB-based) or a standards-compliant LDAP server."); … … 2440 3117 return; 2441 3118 3119 PyModule_AddObject(m, "SEQ_HIGHEST_SEQ", PyInt_FromLong(LDB_SEQ_HIGHEST_SEQ)); 3120 PyModule_AddObject(m, "SEQ_HIGHEST_TIMESTAMP", PyInt_FromLong(LDB_SEQ_HIGHEST_TIMESTAMP)); 3121 PyModule_AddObject(m, "SEQ_NEXT", PyInt_FromLong(LDB_SEQ_NEXT)); 2442 3122 PyModule_AddObject(m, "SCOPE_DEFAULT", PyInt_FromLong(LDB_SCOPE_DEFAULT)); 2443 3123 PyModule_AddObject(m, "SCOPE_BASE", PyInt_FromLong(LDB_SCOPE_BASE)); … … 2494 3174 PyModule_AddObject(m, "ERR_OTHER", PyInt_FromLong(LDB_ERR_OTHER)); 2495 3175 2496 PyModule_AddObject(m, "FLG_RDONLY", PyInt_FromLong(LDB_FLG_RDONLY)); 2497 PyModule_AddObject(m, "FLG_NOSYNC", PyInt_FromLong(LDB_FLG_NOSYNC)); 2498 PyModule_AddObject(m, "FLG_RECONNECT", PyInt_FromLong(LDB_FLG_RECONNECT)); 2499 PyModule_AddObject(m, "FLG_NOMMAP", PyInt_FromLong(LDB_FLG_NOMMAP)); 2500 3176 PyModule_AddObject(m, "FLG_RDONLY", PyInt_FromLong(LDB_FLG_RDONLY)); 3177 PyModule_AddObject(m, "FLG_NOSYNC", PyInt_FromLong(LDB_FLG_NOSYNC)); 3178 PyModule_AddObject(m, "FLG_RECONNECT", PyInt_FromLong(LDB_FLG_RECONNECT)); 3179 PyModule_AddObject(m, "FLG_NOMMAP", PyInt_FromLong(LDB_FLG_NOMMAP)); 2501 3180 2502 3181 PyModule_AddObject(m, "__docformat__", PyString_FromString("restructuredText")); … … 2511 3190 Py_INCREF(&PyLdbMessageElement); 2512 3191 Py_INCREF(&PyLdbTree); 3192 Py_INCREF(&PyLdbResult); 3193 Py_INCREF(&PyLdbControl); 2513 3194 2514 3195 PyModule_AddObject(m, "Ldb", (PyObject *)&PyLdb); … … 2518 3199 PyModule_AddObject(m, "Module", (PyObject *)&PyLdbModule); 2519 3200 PyModule_AddObject(m, "Tree", (PyObject *)&PyLdbTree); 2520 } 3201 PyModule_AddObject(m, "Control", (PyObject *)&PyLdbControl); 3202 3203 PyModule_AddObject(m, "__version__", PyString_FromString(PACKAGE_VERSION)); 3204 } -
vendor/current/source4/lib/ldb/pyldb.h
r414 r740 2 2 Unix SMB/CIFS implementation. 3 3 4 Swiginterface to ldb.4 Python interface to ldb. 5 5 6 6 Copyright (C) 2007-2008 Jelmer Vernooij <jelmer@samba.org> … … 27 27 #define _PYLDB_H_ 28 28 29 #include <Python.h>30 29 #include <talloc.h> 31 30 32 31 typedef struct { 33 32 PyObject_HEAD 33 TALLOC_CTX *mem_ctx; 34 34 struct ldb_context *ldb_ctx; 35 TALLOC_CTX *mem_ctx;36 35 } PyLdbObject; 37 36 38 PyObject *PyLdb_FromLdbContext(struct ldb_context *ldb_ctx);39 37 #define PyLdb_AsLdbContext(pyobj) ((PyLdbObject *)pyobj)->ldb_ctx 40 38 #define PyLdb_Check(ob) PyObject_TypeCheck(ob, &PyLdb) … … 42 40 typedef struct { 43 41 PyObject_HEAD 42 TALLOC_CTX *mem_ctx; 44 43 struct ldb_dn *dn; 45 TALLOC_CTX *mem_ctx;46 44 } PyLdbDnObject; 47 45 … … 53 51 typedef struct { 54 52 PyObject_HEAD 53 TALLOC_CTX *mem_ctx; 55 54 struct ldb_message *msg; 56 TALLOC_CTX *mem_ctx;57 55 } PyLdbMessageObject; 58 56 #define PyLdbMessage_Check(ob) PyObject_TypeCheck(ob, &PyLdbMessage) … … 61 59 typedef struct { 62 60 PyObject_HEAD 61 TALLOC_CTX *mem_ctx; 63 62 struct ldb_module *mod; 64 TALLOC_CTX *mem_ctx;65 63 } PyLdbModuleObject; 66 PyObject *PyLdbMessage_FromMessage(struct ldb_message *message);67 PyObject *PyLdbModule_FromModule(struct ldb_module *mod);68 64 #define PyLdbModule_AsModule(pyobj) ((PyLdbModuleObject *)pyobj)->mod 69 65 70 66 typedef struct { 71 PyObject_HEAD 67 PyObject_HEAD 68 TALLOC_CTX *mem_ctx; 72 69 struct ldb_message_element *el; 73 TALLOC_CTX *mem_ctx;74 70 } PyLdbMessageElementObject; 75 struct ldb_message_element *PyObject_AsMessageElement(TALLOC_CTX *mem_ctx, PyObject *obj, int flags, const char *name);76 PyObject *PyLdbMessageElement_FromMessageElement(struct ldb_message_element *, TALLOC_CTX *mem_ctx);77 71 #define PyLdbMessageElement_AsMessageElement(pyobj) ((PyLdbMessageElementObject *)pyobj)->el 78 72 #define PyLdbMessageElement_Check(ob) PyObject_TypeCheck(ob, &PyLdbMessageElement) … … 80 74 typedef struct { 81 75 PyObject_HEAD 76 TALLOC_CTX *mem_ctx; 82 77 struct ldb_parse_tree *tree; 78 } PyLdbTreeObject; 79 #define PyLdbTree_AsTree(pyobj) ((PyLdbTreeObject *)pyobj)->tree 80 81 typedef struct { 82 PyObject_HEAD 83 83 TALLOC_CTX *mem_ctx; 84 } PyLdbTreeObject; 85 PyObject *PyLdbTree_FromTree(struct ldb_parse_tree *); 86 #define PyLdbTree_AsTree(pyobj) ((PyLdbTreeObject *)pyobj)->tree 84 PyObject *msgs; 85 PyObject *referals; 86 PyObject *controls; 87 } PyLdbResultObject; 88 89 typedef struct { 90 PyObject_HEAD 91 TALLOC_CTX *mem_ctx; 92 struct ldb_control *data; 93 } PyLdbControlObject; 87 94 88 95 #define PyErr_LDB_ERROR_IS_ERR_RAISE(err,ret,ldb) \ -
vendor/current/source4/lib/ldb/tests/photo.ldif
r414 r740 2 2 changetype: modify 3 3 add: jpegPhoto 4 jpegPhoto:< file://tests/ tmp/samba4.png4 jpegPhoto:< file://tests/samba4.png 5 5 -
vendor/current/source4/lib/ldb/tests/python/api.py
r414 r740 1 #!/usr/bin/ python1 #!/usr/bin/env python 2 2 # Simple tests for the ldb python bindings. 3 3 # Copyright (C) 2007 Jelmer Vernooij <jelmer@samba.org> 4 4 5 import os , sys5 import os 6 6 import unittest 7 7 8 # Required for the standalone LDB build9 sys.path.append("build/lib.linux-i686-2.4")10 11 8 import ldb 12 9 10 13 11 def filename(): 14 return os.tempnam() 12 import tempfile 13 try: 14 dir_prefix = os.path.join(os.environ["SELFTEST_PREFIX"], "tmp") 15 except KeyError: 16 dir_prefix = None 17 return tempfile.mktemp(dir=dir_prefix) 15 18 16 19 class NoContextTests(unittest.TestCase): … … 58 61 59 62 def test_modules_tdb(self): 60 x = ldb.Ldb( "bar.ldb")63 x = ldb.Ldb(filename()) 61 64 self.assertEquals("[<ldb module 'tdb'>]", repr(x.modules())) 62 65 … … 78 81 79 82 def test_search_attr_string(self): 80 l = ldb.Ldb( "foo.tdb")83 l = ldb.Ldb(filename()) 81 84 self.assertRaises(TypeError, l.search, attrs="dc") 82 85 … … 96 99 self.assertRaises(ldb.LdbError, lambda: l.delete(ldb.Dn(l, "dc=foo2"))) 97 100 101 def test_delete_w_unhandled_ctrl(self): 102 l = ldb.Ldb(filename()) 103 m = ldb.Message() 104 m.dn = ldb.Dn(l, "dc=foo1") 105 m["b"] = ["a"] 106 l.add(m) 107 self.assertRaises(ldb.LdbError, lambda: l.delete(m.dn, ["search_options:1:2"])) 108 l.delete(m.dn) 109 98 110 def test_contains(self): 99 l = ldb.Ldb(filename()) 111 name = filename() 112 l = ldb.Ldb(name) 100 113 self.assertFalse(ldb.Dn(l, "dc=foo3") in l) 101 l = ldb.Ldb( filename())114 l = ldb.Ldb(name) 102 115 m = ldb.Message() 103 116 m.dn = ldb.Dn(l, "dc=foo3") … … 209 222 rm = l.search(m.dn)[0] 210 223 self.assertEquals(1, len(rm)) 211 rm = l.search(m.dn, attrs=["bla"]) [0]224 rm = l.search(m.dn, attrs=["bla"]) 212 225 self.assertEquals(0, len(rm)) 213 226 finally: … … 267 280 self.assertEquals(2, len(rm)) 268 281 self.assertEquals(["1234", "456"], list(rm["bla"])) 269 270 # Now create another modify, but switch the flags before we do it282 283 # Now create another modify, but switch the flags before we do it 271 284 m["bla"] = ldb.MessageElement(["456"], ldb.FLAG_MOD_ADD, "bla") 272 285 m["bla"].set_flags(ldb.FLAG_MOD_DELETE) … … 275 288 self.assertEquals(1, len(rm)) 276 289 self.assertEquals(["1234"], list(rm["bla"])) 277 278 290 finally: 279 291 l.delete(ldb.Dn(l, "dc=add")) … … 316 328 self.assertEquals("foo\0bar", res[0]["displayname"][0]) 317 329 330 def test_no_crash_broken_expr(self): 331 l = ldb.Ldb(filename()) 332 self.assertRaises(ldb.LdbError,lambda: l.search("", ldb.SCOPE_SUBTREE, "&(dc=*)(dn=*)", ["dc"])) 333 318 334 319 335 class DnTests(unittest.TestCase): … … 332 348 y = ldb.Dn(self.ldb, "dc=foo11,bar=bloe") 333 349 self.assertEquals(x, y) 350 y = ldb.Dn(self.ldb, "dc=foo11,bar=blie") 351 self.assertNotEquals(x, y) 334 352 335 353 def test_str(self): … … 356 374 x = ldb.Dn(self.ldb, "@BLA") 357 375 self.assertEquals(None, x.parent()) 358 359 def test_compare(self):360 x = ldb.Dn(self.ldb, "dc=foo17,bar=bloe")361 y = ldb.Dn(self.ldb, "dc=foo17,bar=bloe")362 self.assertEquals(x, y)363 z = ldb.Dn(self.ldb, "dc=foo17,bar=blie")364 self.assertNotEquals(z, y)365 376 366 377 def test_is_valid(self): … … 368 379 self.assertTrue(x.is_valid()) 369 380 x = ldb.Dn(self.ldb, "") 370 # is_valid()'s return values appears to be a side effect of 371 # some other ldb functions. yuck. 372 # self.assertFalse(x.is_valid()) 381 self.assertTrue(x.is_valid()) 373 382 374 383 def test_is_special(self): … … 413 422 ldif = self.ldb.write_ldif(msg[1], ldb.CHANGETYPE_NONE) 414 423 self.assertEquals("dn: foo=bar\n\n", ldif) 415 424 416 425 def test_parse_ldif_more(self): 417 426 msgs = self.ldb.parse_ldif("dn: foo=bar\n\n\ndn: bar=bar") … … 441 450 def test_iter_items(self): 442 451 self.assertEquals(0, len(self.msg.items())) 443 self.msg.dn = ldb.Dn(ldb.Ldb( "foo.tdb"), "dc=foo28")452 self.msg.dn = ldb.Dn(ldb.Ldb(filename()), "dc=foo28") 444 453 self.assertEquals(1, len(self.msg.items())) 445 454 446 455 def test_repr(self): 447 self.msg.dn = ldb.Dn(ldb.Ldb( "foo.tdb"), "dc=foo29")456 self.msg.dn = ldb.Dn(ldb.Ldb(filename()), "dc=foo29") 448 457 self.msg["dc"] = "foo" 449 458 self.assertEquals("Message({'dn': Dn('dc=foo29'), 'dc': MessageElement(['foo'])})", repr(self.msg)) … … 457 466 def test_del(self): 458 467 del self.msg["foo"] 468 469 def test_add(self): 470 self.msg.add(ldb.MessageElement(["456"], ldb.FLAG_MOD_ADD, "bla")) 471 472 def test_elements_empty(self): 473 self.assertEquals([], self.msg.elements()) 474 475 def test_elements(self): 476 el = ldb.MessageElement(["456"], ldb.FLAG_MOD_ADD, "bla") 477 self.msg.add(el) 478 self.assertEquals([el], self.msg.elements()) 459 479 460 480 def test_add_value(self): … … 476 496 477 497 def test_keys(self): 478 self.msg.dn = ldb.Dn(ldb.Ldb( "foo.tdb"), "@BASEINFO")498 self.msg.dn = ldb.Dn(ldb.Ldb(filename()), "@BASEINFO") 479 499 self.msg["foo"] = ["bla"] 480 500 self.msg["bar"] = ["bla"] … … 486 506 487 507 def test_get_dn(self): 488 self.msg.dn = ldb.Dn(ldb.Ldb( "foo.tdb"), "@BASEINFO")508 self.msg.dn = ldb.Dn(ldb.Ldb(filename()), "@BASEINFO") 489 509 self.assertEquals("@BASEINFO", self.msg.get("dn").__str__()) 490 510 491 511 def test_get_invalid(self): 492 self.msg.dn = ldb.Dn(ldb.Ldb( "foo.tdb"), "@BASEINFO")512 self.msg.dn = ldb.Dn(ldb.Ldb(filename()), "@BASEINFO") 493 513 self.assertRaises(TypeError, self.msg.get, 42) 494 514 … … 510 530 self.assertEquals(1, len(msgdiff)) 511 531 532 def test_equal_empty(self): 533 msg1 = ldb.Message() 534 msg2 = ldb.Message() 535 self.assertEquals(msg1, msg2) 536 537 def test_equal_simplel(self): 538 db = ldb.Ldb(filename()) 539 msg1 = ldb.Message() 540 msg1.dn = ldb.Dn(db, "foo=bar") 541 msg2 = ldb.Message() 542 msg2.dn = ldb.Dn(db, "foo=bar") 543 self.assertEquals(msg1, msg2) 544 msg1['foo'] = 'bar' 545 msg2['foo'] = 'bar' 546 self.assertEquals(msg1, msg2) 547 msg2['foo'] = 'blie' 548 self.assertNotEquals(msg1, msg2) 549 msg2['foo'] = 'blie' 550 551 def test_from_dict(self): 552 rec = {"dn": "dc=fromdict", 553 "a1": ["a1-val1", "a1-val1"]} 554 l = ldb.Ldb() 555 # check different types of input Flags 556 for flags in [ldb.FLAG_MOD_ADD, ldb.FLAG_MOD_REPLACE, ldb.FLAG_MOD_DELETE]: 557 m = ldb.Message.from_dict(l, rec, flags) 558 self.assertEquals(rec["a1"], list(m["a1"])) 559 self.assertEquals(flags, m["a1"].flags()) 560 # check input params 561 self.assertRaises(TypeError, ldb.Message.from_dict, dict(), rec, ldb.FLAG_MOD_REPLACE) 562 self.assertRaises(TypeError, ldb.Message.from_dict, l, list(), ldb.FLAG_MOD_REPLACE) 563 self.assertRaises(ValueError, ldb.Message.from_dict, l, rec, 0) 564 # Message.from_dict expects dictionary with 'dn' 565 err_rec = {"a1": ["a1-val1", "a1-val1"]} 566 self.assertRaises(TypeError, ldb.Message.from_dict, l, err_rec, ldb.FLAG_MOD_REPLACE) 567 512 568 513 569 … … 552 608 self.assertEquals(y, x) 553 609 610 def test_extended(self): 611 el = ldb.MessageElement(["456"], ldb.FLAG_MOD_ADD, "bla") 612 self.assertEquals("MessageElement(['456'])", repr(el)) 613 554 614 555 615 class ModuleTests(unittest.TestCase): … … 572 632 return self.next.search(*args, **kwargs) 573 633 634 def request(self, *args, **kwargs): 635 pass 636 637 name = filename() 574 638 ldb.register_module(ExampleModule) 575 if os.path.exists( "usemodule.ldb"):576 os.unlink( "usemodule.ldb")577 l = ldb.Ldb( "usemodule.ldb")639 if os.path.exists(name): 640 os.unlink(name) 641 l = ldb.Ldb(name) 578 642 l.add({"dn": "@MODULES", "@LIST": "bla"}) 579 643 self.assertEquals([], ops) 580 l = ldb.Ldb( "usemodule.ldb")644 l = ldb.Ldb(name) 581 645 self.assertEquals(["init"], ops) 646 647 class LdbResultTests(unittest.TestCase): 648 649 def setUp(self): 650 name = filename() 651 self.name = name 652 if os.path.exists(name): 653 os.unlink(name) 654 self.l = ldb.Ldb(name) 655 self.l.add({"dn": "DC=SAMBA,DC=ORG", "name": "samba.org"}) 656 self.l.add({"dn": "OU=ADMIN,DC=SAMBA,DC=ORG", "name": "Admins"}) 657 self.l.add({"dn": "OU=USERS,DC=SAMBA,DC=ORG", "name": "Users"}) 658 self.l.add({"dn": "OU=OU1,DC=SAMBA,DC=ORG", "name": "OU #1"}) 659 self.l.add({"dn": "OU=OU2,DC=SAMBA,DC=ORG", "name": "OU #2"}) 660 self.l.add({"dn": "OU=OU3,DC=SAMBA,DC=ORG", "name": "OU #3"}) 661 self.l.add({"dn": "OU=OU4,DC=SAMBA,DC=ORG", "name": "OU #4"}) 662 self.l.add({"dn": "OU=OU5,DC=SAMBA,DC=ORG", "name": "OU #5"}) 663 self.l.add({"dn": "OU=OU6,DC=SAMBA,DC=ORG", "name": "OU #6"}) 664 self.l.add({"dn": "OU=OU7,DC=SAMBA,DC=ORG", "name": "OU #7"}) 665 self.l.add({"dn": "OU=OU8,DC=SAMBA,DC=ORG", "name": "OU #8"}) 666 self.l.add({"dn": "OU=OU9,DC=SAMBA,DC=ORG", "name": "OU #9"}) 667 self.l.add({"dn": "OU=OU10,DC=SAMBA,DC=ORG", "name": "OU #10"}) 668 669 def tearDown(self): 670 if os.path.exists(self.name): 671 os.unlink(self.name) 672 673 def test_return_type(self): 674 res = self.l.search() 675 self.assertEquals(str(res), "<ldb result>") 676 677 def test_get_msgs(self): 678 res = self.l.search() 679 list = res.msgs 680 681 def test_get_controls(self): 682 res = self.l.search() 683 list = res.controls 684 685 def test_get_referals(self): 686 res = self.l.search() 687 list = res.referals 688 689 def test_iter_msgs(self): 690 found = False 691 for l in self.l.search().msgs: 692 if str(l.dn) == "OU=OU10,DC=SAMBA,DC=ORG": 693 found = True 694 self.assertTrue(found) 695 696 def test_iter_msgs_count(self): 697 self.assertTrue(self.l.search().count > 0) 698 # 13 objects has been added to the DC=SAMBA, DC=ORG 699 self.assertEqual(self.l.search(base="DC=SAMBA,DC=ORG").count, 13) 700 701 def test_iter_controls(self): 702 res = self.l.search().controls 703 it = iter(res) 704 705 def test_create_control(self): 706 self.assertRaises(ValueError, ldb.Control, self.l, "tatayoyo:0") 707 c = ldb.Control(self.l, "relax:1") 708 self.assertEquals(c.critical, True) 709 self.assertEquals(c.oid, "1.3.6.1.4.1.4203.666.5.12") 710 711 def test_iter_refs(self): 712 res = self.l.search().referals 713 it = iter(res) 714 715 def test_iter_as_sequence_msgs(self): 716 found = False 717 res = self.l.search().msgs 718 719 for i in range(0, len(res)): 720 l = res[i] 721 if str(l.dn) == "OU=OU10,DC=SAMBA,DC=ORG": 722 found = True 723 self.assertTrue(found) 724 725 def test_iter_as_sequence(self): 726 found = False 727 res = self.l.search() 728 729 for i in range(0, len(res)): 730 l = res[i] 731 if str(l.dn) == "OU=OU10,DC=SAMBA,DC=ORG": 732 found = True 733 self.assertTrue(found) 734 735 class VersionTests(unittest.TestCase): 736 737 def test_version(self): 738 self.assertTrue(isinstance(ldb.__version__, str)) 582 739 583 740 -
vendor/current/source4/lib/ldb/tests/sample_module.c
r414 r740 22 22 */ 23 23 24 #include "replace.h" 25 #include "system/filesys.h" 26 #include "system/time.h" 24 27 #include "ldb_module.h" 25 28 26 int sample_add(struct ldb_module *mod, struct ldb_request *req)29 static int sample_add(struct ldb_module *mod, struct ldb_request *req) 27 30 { 31 struct ldb_control *control; 32 28 33 ldb_msg_add_fmt(req->op.add.message, "touchedBy", "sample"); 29 34 30 return ldb_next_request(mod, req); 35 /* check if there's a relax control */ 36 control = ldb_request_get_control(req, LDB_CONTROL_RELAX_OID); 37 if (control == NULL) { 38 /* not found go on */ 39 return ldb_next_request(mod, req); 40 } else { 41 return LDB_ERR_UNWILLING_TO_PERFORM; 42 } 31 43 } 32 44 33 const struct ldb_module_ops ldb_sample_module_ops = { 45 static int sample_modify(struct ldb_module *mod, struct ldb_request *req) 46 { 47 struct ldb_control *control; 48 49 /* check if there's a relax control */ 50 control = ldb_request_get_control(req, LDB_CONTROL_RELAX_OID); 51 if (control == NULL) { 52 /* not found go on */ 53 return ldb_next_request(mod, req); 54 } else { 55 return LDB_ERR_UNWILLING_TO_PERFORM; 56 } 57 } 58 59 60 static struct ldb_module_ops ldb_sample_module_ops = { 34 61 .name = "sample", 35 62 .add = sample_add, 63 .del = sample_modify, 64 .modify = sample_modify, 36 65 }; 66 67 int ldb_sample_init(const char *version) 68 { 69 LDB_MODULE_CHECK_VERSION(version); 70 return ldb_register_module(&ldb_sample_module_ops); 71 } -
vendor/current/source4/lib/ldb/tests/test-generic.sh
r414 r740 45 45 } 46 46 47 echo " testing indexed search"47 echo "Testing indexed search" 48 48 $VALGRIND ldbsearch$EXEEXT '(uid=uham)' || exit 1 49 49 $VALGRIND ldbsearch$EXEEXT '(&(objectclass=person)(objectclass=person)(objectclass=top))' || exit 1 … … 82 82 83 83 echo "Testing binary file attribute value" 84 mkdir -p tests/tmp85 cp $LDBDIR/tests/samba4.png tests/tmp/samba4.png86 84 $VALGRIND ldbmodify$EXEEXT $LDBDIR/tests/photo.ldif || exit 1 87 85 count=`$VALGRIND ldbsearch$EXEEXT '(cn=Hampster Ursula)' jpegPhoto | grep '^dn' | wc -l` … … 90 88 exit 1 91 89 fi 92 rm -f tests/tmp/samba4.png93 90 94 91 echo "*TODO* Testing UTF8 upper lower case searches !!" -
vendor/current/source4/lib/ldb/tests/test-schema.sh
r414 r740 20 20 $VALGRIND bin/ldbmodify $LDBDIR/tests/schema-tests/schema-mod-test-3.ldif || exit 1 21 21 $VALGRIND bin/ldbmodify $LDBDIR/tests/schema-tests/schema-mod-test-4.ldif 22 if [ "$?" = ="0" ]; then22 if [ "$?" = "0" ]; then 23 23 echo "test failed!" 24 24 exit 1 25 25 fi 26 26 $VALGRIND bin/ldbmodify $LDBDIR/tests/schema-tests/schema-mod-test-5.ldif 27 if [ "$?" = ="0" ]; then27 if [ "$?" = "0" ]; then 28 28 echo "test failed!" 29 29 exit 1 -
vendor/current/source4/lib/ldb/tests/test-tdb.sh
r414 r740 30 30 31 31 . $LDBDIR/tests/test-tdb-features.sh 32 33 . $LDBDIR/tests/test-controls.sh -
vendor/current/source4/lib/ldb/tests/test.ldif
r414 r740 410 410 facsimiletelephonenumber: +1 313 555 9700 411 411 telephonenumber: +1 313 555 5331 412 413 dn: cn=Fred Bassett,ou=Alumni Association,ou=People,o=University of Michigan,c=TEST 414 objectclass: OpenLDAPperson 415 cn: Fred Bassett 416 sn: Bassett 417 uid: Bassett, Fred -
vendor/current/source4/lib/ldb/tools/cmdline.c
r414 r740 22 22 */ 23 23 24 #include "ldb_includes.h" 24 #include "replace.h" 25 #include "system/filesys.h" 26 #include "system/time.h" 25 27 #include "ldb.h" 28 #include "ldb_module.h" 26 29 #include "tools/cmdline.h" 27 30 28 #if (_SAMBA_BUILD_ >= 4)29 #include "includes.h"30 #include "lib/cmdline/popt_common.h"31 #include "lib/ldb-samba/ldif_handlers.h"32 #include "auth/gensec/gensec.h"33 #include "auth/auth.h"34 #include "ldb_wrap.h"35 #include "param/param.h"36 #endif37 38 31 static struct ldb_cmdline options; /* needs to be static for older compilers */ 39 32 40 static struct poptOption popt_options[] = { 33 enum ldb_cmdline_options { CMDLINE_RELAX=1 }; 34 35 static struct poptOption builtin_popt_options[] = { 41 36 POPT_AUTOHELP 42 37 { "url", 'H', POPT_ARG_STRING, &options.url, 0, "database URL", "URL" }, … … 54 49 { "nosync", 0, POPT_ARG_NONE, &options.nosync, 0, "non-synchronous transactions", NULL }, 55 50 { "sorted", 'S', POPT_ARG_NONE, &options.sorted, 0, "sort attributes", NULL }, 56 { "input", 'I', POPT_ARG_STRING, &options.input, 0, "Input File", "Input" },57 { "output", 'O', POPT_ARG_STRING, &options.output, 0, "Output File", "Output" },58 51 { NULL, 'o', POPT_ARG_STRING, NULL, 'o', "ldb_connect option", "OPTION" }, 59 52 { "controls", 0, POPT_ARG_STRING, NULL, 'c', "controls", NULL }, 60 53 { "show-binary", 0, POPT_ARG_NONE, &options.show_binary, 0, "display binary LDIF", NULL }, 61 #if (_SAMBA_BUILD_ >= 4) 62 POPT_COMMON_SAMBA 63 POPT_COMMON_CREDENTIALS 64 POPT_COMMON_CONNECTION 65 POPT_COMMON_VERSION 66 #endif 54 { "paged", 0, POPT_ARG_NONE, NULL, 'P', "use a paged search", NULL }, 55 { "show-deleted", 0, POPT_ARG_NONE, NULL, 'D', "show deleted objects", NULL }, 56 { "show-recycled", 0, POPT_ARG_NONE, NULL, 'R', "show recycled objects", NULL }, 57 { "show-deactivated-link", 0, POPT_ARG_NONE, NULL, 'd', "show deactivated links", NULL }, 58 { "reveal", 0, POPT_ARG_NONE, NULL, 'r', "reveal ldb internals", NULL }, 59 { "relax", 0, POPT_ARG_NONE, NULL, CMDLINE_RELAX, "pass relax control", NULL }, 60 { "cross-ncs", 0, POPT_ARG_NONE, NULL, 'N', "search across NC boundaries", NULL }, 61 { "extended-dn", 0, POPT_ARG_NONE, NULL, 'E', "show extended DNs", NULL }, 67 62 { NULL } 68 63 }; 69 64 70 void ldb_cmdline_help( const char *cmdname, FILE *f)65 void ldb_cmdline_help(struct ldb_context *ldb, const char *cmdname, FILE *f) 71 66 { 72 67 poptContext pc; 73 pc = poptGetContext(cmdname, 0, NULL, popt_options, 68 struct poptOption **popt_options = ldb_module_popt_options(ldb); 69 pc = poptGetContext(cmdname, 0, NULL, *popt_options, 74 70 POPT_CONTEXT_KEEP_FIRST); 75 71 poptPrintHelp(pc, f, 0); 72 } 73 74 /* 75 add a control to the options structure 76 */ 77 static bool add_control(TALLOC_CTX *mem_ctx, const char *control) 78 { 79 unsigned int i; 80 81 /* count how many controls we already have */ 82 for (i=0; options.controls && options.controls[i]; i++) ; 83 84 options.controls = talloc_realloc(mem_ctx, options.controls, const char *, i + 2); 85 if (options.controls == NULL) { 86 return false; 87 } 88 options.controls[i] = control; 89 options.controls[i+1] = NULL; 90 return true; 76 91 } 77 92 … … 81 96 struct ldb_cmdline *ldb_cmdline_process(struct ldb_context *ldb, 82 97 int argc, const char **argv, 83 void (*usage)( void))98 void (*usage)(struct ldb_context *)) 84 99 { 85 100 struct ldb_cmdline *ret=NULL; 86 101 poptContext pc; 87 #if (_SAMBA_BUILD_ >= 4)88 int r;89 #endif90 102 int num_options = 0; 91 103 int opt; 92 104 int flags = 0; 93 94 #if (_SAMBA_BUILD_ >= 4) 95 r = ldb_register_samba_handlers(ldb); 96 if (r != 0) { 97 goto failed; 98 } 99 100 #endif 105 int rc; 106 struct poptOption **popt_options; 107 108 /* make the ldb utilities line buffered */ 109 setlinebuf(stdout); 101 110 102 111 ret = talloc_zero(ldb, struct ldb_cmdline); … … 122 131 options.scope = LDB_SCOPE_DEFAULT; 123 132 124 pc = poptGetContext(argv[0], argc, argv, popt_options, 133 popt_options = ldb_module_popt_options(ldb); 134 (*popt_options) = builtin_popt_options; 135 136 rc = ldb_modules_hook(ldb, LDB_MODULE_HOOK_CMDLINE_OPTIONS); 137 if (rc != LDB_SUCCESS) { 138 fprintf(stderr, "ldb: failed to run command line hooks : %s\n", ldb_strerror(rc)); 139 goto failed; 140 } 141 142 pc = poptGetContext(argv[0], argc, argv, *popt_options, 125 143 POPT_CONTEXT_KEEP_FIRST); 126 144 … … 160 178 case 'c': { 161 179 const char *cs = poptGetOptArg(pc); 162 const char *p, *q; 163 int cc; 164 165 for (p = cs, cc = 1; (q = strchr(p, ',')); cc++, p = q + 1) ; 166 167 options.controls = talloc_array(ret, char *, cc + 1); 168 if (options.controls == NULL) { 169 fprintf(stderr, "Out of memory!\n"); 170 goto failed; 171 } 172 for (p = cs, cc = 0; p != NULL; cc++) { 173 const char *t; 180 const char *p; 181 182 for (p = cs; p != NULL; ) { 183 const char *t, *c; 174 184 175 185 t = strchr(p, ','); 176 186 if (t == NULL) { 177 options.controls[cc]= talloc_strdup(options.controls, p);187 c = talloc_strdup(options.controls, p); 178 188 p = NULL; 179 189 } else { 180 options.controls[cc]= talloc_strndup(options.controls, p, t-p);190 c = talloc_strndup(options.controls, p, t-p); 181 191 p = t + 1; 182 192 } 183 } 184 options.controls[cc] = NULL; 193 if (c == NULL || !add_control(ret, c)) { 194 fprintf(stderr, __location__ ": out of memory\n"); 195 goto failed; 196 } 197 } 185 198 186 199 break; 187 200 } 201 case 'P': 202 if (!add_control(ret, "paged_results:1:1024")) { 203 fprintf(stderr, __location__ ": out of memory\n"); 204 goto failed; 205 } 206 break; 207 case 'D': 208 if (!add_control(ret, "show_deleted:1")) { 209 fprintf(stderr, __location__ ": out of memory\n"); 210 goto failed; 211 } 212 break; 213 case 'R': 214 if (!add_control(ret, "show_recycled:0")) { 215 fprintf(stderr, __location__ ": out of memory\n"); 216 goto failed; 217 } 218 break; 219 case 'd': 220 if (!add_control(ret, "show_deactivated_link:0")) { 221 fprintf(stderr, __location__ ": out of memory\n"); 222 goto failed; 223 } 224 break; 225 case 'r': 226 if (!add_control(ret, "reveal_internals:0")) { 227 fprintf(stderr, __location__ ": out of memory\n"); 228 goto failed; 229 } 230 break; 231 case CMDLINE_RELAX: 232 if (!add_control(ret, "relax:0")) { 233 fprintf(stderr, __location__ ": out of memory\n"); 234 goto failed; 235 } 236 break; 237 case 'N': 238 if (!add_control(ret, "search_options:1:2")) { 239 fprintf(stderr, __location__ ": out of memory\n"); 240 goto failed; 241 } 242 break; 243 case 'E': 244 if (!add_control(ret, "extended_dn:1:1")) { 245 fprintf(stderr, __location__ ": out of memory\n"); 246 goto failed; 247 } 248 break; 188 249 default: 189 250 fprintf(stderr, "Invalid option %s: %s\n", 190 251 poptBadOption(pc, 0), poptStrerror(opt)); 191 if (usage) usage( );252 if (usage) usage(ldb); 192 253 goto failed; 193 254 } … … 206 267 if (ret->url == NULL) { 207 268 fprintf(stderr, "You must supply a url with -H or with $LDB_URL\n"); 208 if (usage) usage( );269 if (usage) usage(ldb); 209 270 goto failed; 210 271 } … … 226 287 } 227 288 228 #if (_SAMBA_BUILD_ >= 4)229 /* Must be after we have processed command line options */230 gensec_init(cmdline_lp_ctx);231 232 if (ldb_set_opaque(ldb, "sessionInfo", system_session(ldb, cmdline_lp_ctx))) {233 goto failed;234 }235 if (ldb_set_opaque(ldb, "credentials", cmdline_credentials)) {236 goto failed;237 }238 if (ldb_set_opaque(ldb, "loadparm", cmdline_lp_ctx)) {239 goto failed;240 }241 242 ldb_set_utf8_fns(ldb, NULL, wrap_casefold);243 #endif244 245 289 if (options.modules_path != NULL) { 246 290 ldb_set_modules_dir(ldb, options.modules_path); 247 } else if (getenv("LDB_MODULES_PATH") != NULL) { 248 ldb_set_modules_dir(ldb, getenv("LDB_MODULES_PATH")); 291 } 292 293 rc = ldb_modules_hook(ldb, LDB_MODULE_HOOK_CMDLINE_PRECONNECT); 294 if (rc != LDB_SUCCESS) { 295 fprintf(stderr, "ldb: failed to run preconnect hooks : %s\n", ldb_strerror(rc)); 296 goto failed; 249 297 } 250 298 … … 256 304 } 257 305 306 rc = ldb_modules_hook(ldb, LDB_MODULE_HOOK_CMDLINE_POSTCONNECT); 307 if (rc != LDB_SUCCESS) { 308 fprintf(stderr, "ldb: failed to run post connect hooks : %s\n", ldb_strerror(rc)); 309 goto failed; 310 } 311 258 312 return ret; 259 313 260 314 failed: 261 315 talloc_free(ret); 262 exit( 1);316 exit(LDB_ERR_OPERATIONS_ERROR); 263 317 return NULL; 264 318 } … … 274 328 int handle_controls_reply(struct ldb_control **reply, struct ldb_control **request) 275 329 { 276 int i, j;277 330 unsigned int i, j; 331 int ret = 0; 278 332 279 333 if (reply == NULL || request == NULL) return -1; -
vendor/current/source4/lib/ldb/tools/cmdline.h
r414 r740 42 42 int num_searches; 43 43 const char *sasl_mechanism; 44 const char *input; 45 const char *output; 46 char **controls; 44 const char **controls; 47 45 int show_binary; 48 46 int tracing; 49 47 }; 50 48 51 struct ldb_cmdline *ldb_cmdline_process(struct ldb_context *ldb, int argc, const char **argv, 52 void (*usage)(void)); 49 struct ldb_cmdline *ldb_cmdline_process(struct ldb_context *ldb, int argc, 50 const char **argv, 51 void (*usage)(struct ldb_context *)); 53 52 54 53 55 54 int handle_controls_reply(struct ldb_control **reply, struct ldb_control **request); 56 void ldb_cmdline_help( const char *cmdname, FILE *f);55 void ldb_cmdline_help(struct ldb_context *ldb, const char *cmdname, FILE *f); 57 56 -
vendor/current/source4/lib/ldb/tools/ldbadd.c
r414 r740 1 /* 1 /* 2 2 ldb database library 3 3 … … 7 7 ** library. This does NOT imply that all of Samba is released 8 8 ** under the LGPL 9 9 10 10 This library is free software; you can redistribute it and/or 11 11 modify it under the terms of the GNU Lesser General Public … … 34 34 #include "ldb.h" 35 35 #include "tools/cmdline.h" 36 #include "ldbutil.h" 36 37 37 static int failures; 38 static unsigned int failures; 39 static struct ldb_cmdline *options; 38 40 39 static void usage( void)41 static void usage(struct ldb_context *ldb) 40 42 { 41 printf("Usage: ldbadd <options> <ldif...>\n"); 43 printf("Usage: ldbadd <options> <ldif...>\n"); 42 44 printf("Adds records to a ldb, reading ldif the specified list of files\n\n"); 43 ldb_cmdline_help( "ldbadd", stdout);44 exit( 1);45 ldb_cmdline_help(ldb, "ldbadd", stdout); 46 exit(LDB_ERR_OPERATIONS_ERROR); 45 47 } 46 48 … … 49 51 add records from an opened file 50 52 */ 51 static int process_file(struct ldb_context *ldb, FILE *f, int *count)53 static int process_file(struct ldb_context *ldb, FILE *f, unsigned int *count) 52 54 { 53 55 struct ldb_ldif *ldif; 54 56 int ret = LDB_SUCCESS; 57 struct ldb_control **req_ctrls = ldb_parse_control_strings(ldb, ldb, (const char **)options->controls); 58 if (options->controls != NULL && req_ctrls== NULL) { 59 printf("parsing controls failed: %s\n", ldb_errstring(ldb)); 60 return LDB_ERR_OPERATIONS_ERROR; 61 } 62 55 63 56 64 while ((ldif = ldb_ldif_read_file(ldb, f))) { … … 61 69 } 62 70 63 ldif->msg = ldb_msg_canonicalize(ldb, ldif->msg); 71 ret = ldb_msg_normalize(ldb, ldif, ldif->msg, &ldif->msg); 72 if (ret != LDB_SUCCESS) { 73 fprintf(stderr, 74 "ERR: Message canonicalize failed - %s\n", 75 ldb_strerror(ret)); 76 failures++; 77 ldb_ldif_read_free(ldb, ldif); 78 continue; 79 } 64 80 65 ret = ldb_add (ldb, ldif->msg);81 ret = ldb_add_ctrl(ldb, ldif->msg,req_ctrls); 66 82 if (ret != LDB_SUCCESS) { 67 fprintf(stderr, "ERR: \"%s\" on DN %s\n", 68 ldb_errstring(ldb), ldb_dn_get_linearized(ldif->msg->dn)); 83 fprintf(stderr, "ERR: %s : \"%s\" on DN %s\n", 84 ldb_strerror(ret), ldb_errstring(ldb), 85 ldb_dn_get_linearized(ldif->msg->dn)); 69 86 failures++; 70 87 } else { 71 88 (*count)++; 89 if (options->verbose) { 90 printf("Added %s\n", ldb_dn_get_linearized(ldif->msg->dn)); 91 } 72 92 } 73 93 ldb_ldif_read_free(ldb, ldif); … … 82 102 { 83 103 struct ldb_context *ldb; 84 int i, ret=0, count=0; 85 struct ldb_cmdline *options; 104 unsigned int i, count = 0; 105 int ret = LDB_SUCCESS; 106 TALLOC_CTX *mem_ctx = talloc_new(NULL); 86 107 87 ldb = ldb_init(NULL, NULL); 108 ldb = ldb_init(mem_ctx, NULL); 109 if (ldb == NULL) { 110 return LDB_ERR_OPERATIONS_ERROR; 111 } 88 112 89 113 options = ldb_cmdline_process(ldb, argc, argv, usage); 90 114 91 if (ldb_transaction_start(ldb) != 0) { 115 ret = ldb_transaction_start(ldb); 116 if (ret != LDB_SUCCESS) { 92 117 printf("Failed to start transaction: %s\n", ldb_errstring(ldb)); 93 exit(1);118 return ret; 94 119 } 95 120 … … 103 128 if (!f) { 104 129 perror(fname); 105 exit(1);130 return LDB_ERR_OPERATIONS_ERROR; 106 131 } 107 132 ret = process_file(ldb, f, &count); … … 111 136 112 137 if (count != 0) { 113 if (ldb_transaction_commit(ldb) != 0) { 138 ret = ldb_transaction_commit(ldb); 139 if (ret != LDB_SUCCESS) { 114 140 printf("Failed to commit transaction: %s\n", ldb_errstring(ldb)); 115 exit(1);141 return ret; 116 142 } 117 143 } else { … … 119 145 } 120 146 121 talloc_free( ldb);147 talloc_free(mem_ctx); 122 148 123 printf("Added % d records with %dfailures\n", count, failures);124 149 printf("Added %u records with %u failures\n", count, failures); 150 125 151 return ret; 126 152 } -
vendor/current/source4/lib/ldb/tools/ldbdel.c
r414 r740 32 32 */ 33 33 34 #include "replace.h" 34 35 #include "ldb.h" 35 36 #include "tools/cmdline.h" 37 #include "ldbutil.h" 36 38 37 static int ldb_delete_recursive(struct ldb_context *ldb, struct ldb_dn *dn)39 static int dn_cmp(struct ldb_message **msg1, struct ldb_message **msg2) 38 40 { 39 int ret, i, total=0; 41 return ldb_dn_compare((*msg1)->dn, (*msg2)->dn); 42 } 43 44 static int ldb_delete_recursive(struct ldb_context *ldb, struct ldb_dn *dn,struct ldb_control **req_ctrls) 45 { 46 int ret; 47 unsigned int i, total=0; 40 48 const char *attrs[] = { NULL }; 41 49 struct ldb_result *res; 42 50 43 51 ret = ldb_search(ldb, ldb, &res, dn, LDB_SCOPE_SUBTREE, attrs, "distinguishedName=*"); 44 if (ret != LDB_SUCCESS) return -1; 52 if (ret != LDB_SUCCESS) return ret; 53 54 /* sort the DNs, deepest first */ 55 TYPESAFE_QSORT(res->msgs, res->count, dn_cmp); 45 56 46 57 for (i = 0; i < res->count; i++) { 47 if (ldb_delete (ldb, res->msgs[i]->dn) == 0) {58 if (ldb_delete_ctrl(ldb, res->msgs[i]->dn,req_ctrls) == LDB_SUCCESS) { 48 59 total++; 60 } else { 61 printf("Failed to delete '%s' - %s\n", 62 ldb_dn_get_linearized(res->msgs[i]->dn), 63 ldb_errstring(ldb)); 49 64 } 50 65 } … … 53 68 54 69 if (total == 0) { 55 return -1;70 return LDB_ERR_OPERATIONS_ERROR; 56 71 } 57 printf("Deleted % drecords\n", total);58 return 0;72 printf("Deleted %u records\n", total); 73 return LDB_SUCCESS; 59 74 } 60 75 61 static void usage( void)76 static void usage(struct ldb_context *ldb) 62 77 { 63 78 printf("Usage: ldbdel <options> <DN...>\n"); 64 79 printf("Deletes records from a ldb\n\n"); 65 ldb_cmdline_help( "ldbdel", stdout);66 exit( 1);80 ldb_cmdline_help(ldb, "ldbdel", stdout); 81 exit(LDB_ERR_OPERATIONS_ERROR); 67 82 } 68 83 69 84 int main(int argc, const char **argv) 70 85 { 86 struct ldb_control **req_ctrls; 87 struct ldb_cmdline *options; 71 88 struct ldb_context *ldb; 72 89 int ret = 0, i; 73 struct ldb_cmdline *options;90 TALLOC_CTX *mem_ctx = talloc_new(NULL); 74 91 75 ldb = ldb_init(NULL, NULL); 92 ldb = ldb_init(mem_ctx, NULL); 93 if (ldb == NULL) { 94 return LDB_ERR_OPERATIONS_ERROR; 95 } 76 96 77 97 options = ldb_cmdline_process(ldb, argc, argv, usage); 78 98 79 99 if (options->argc < 1) { 80 usage(); 81 exit(1); 100 usage(ldb); 101 } 102 103 req_ctrls = ldb_parse_control_strings(ldb, ldb, (const char **)options->controls); 104 if (options->controls != NULL && req_ctrls== NULL) { 105 printf("parsing controls failed: %s\n", ldb_errstring(ldb)); 106 return LDB_ERR_OPERATIONS_ERROR; 82 107 } 83 108 … … 86 111 87 112 dn = ldb_dn_new(ldb, ldb, options->argv[i]); 88 if ( ! ldb_dn_validate(dn)) { 89 printf("Invalid DN format\n"); 90 exit(1); 113 if (dn == NULL) { 114 return LDB_ERR_OPERATIONS_ERROR; 91 115 } 92 116 if (options->recursive) { 93 ret = ldb_delete_recursive(ldb, dn );117 ret = ldb_delete_recursive(ldb, dn,req_ctrls); 94 118 } else { 95 ret = ldb_delete (ldb, dn);96 if (ret == 0) {119 ret = ldb_delete_ctrl(ldb, dn,req_ctrls); 120 if (ret == LDB_SUCCESS) { 97 121 printf("Deleted 1 record\n"); 98 122 } 99 123 } 100 if (ret != 0) { 101 printf("delete of '%s' failed - %s\n", 102 ldb_dn_get_linearized(dn), 103 ldb_errstring(ldb)); 124 if (ret != LDB_SUCCESS) { 125 printf("delete of '%s' failed - (%s) %s\n", 126 ldb_dn_get_linearized(dn), 127 ldb_strerror(ret), 128 ldb_errstring(ldb)); 104 129 } 105 130 } 106 131 107 talloc_free( ldb);132 talloc_free(mem_ctx); 108 133 109 134 return ret; -
vendor/current/source4/lib/ldb/tools/ldbedit.c
r414 r740 1 /* 1 /* 2 2 ldb database library 3 3 … … 7 7 ** library. This does NOT imply that all of Samba is released 8 8 ** under the LGPL 9 9 10 10 This library is free software; you can redistribute it and/or 11 11 modify it under the terms of the GNU Lesser General Public … … 31 31 * Author: Andrew Tridgell 32 32 */ 33 #include "ldb_includes.h" 33 34 #include "replace.h" 35 #include "system/filesys.h" 36 #include "system/time.h" 37 #include "system/filesys.h" 34 38 #include "ldb.h" 35 39 #include "tools/cmdline.h" 40 #include "tools/ldbutil.h" 36 41 37 42 static struct ldb_cmdline *options; 38 43 39 44 /* 40 debug routine 41 */ 42 static void ldif_write_msg(struct ldb_context *ldb, 43 FILE *f, 45 debug routine 46 */ 47 static void ldif_write_msg(struct ldb_context *ldb, 48 FILE *f, 44 49 enum ldb_changetype changetype, 45 50 struct ldb_message *msg) … … 55 60 returns the number of modified elements 56 61 */ 57 static int modify_record(struct ldb_context *ldb, 62 static int modify_record(struct ldb_context *ldb, 58 63 struct ldb_message *msg1, 59 struct ldb_message *msg2) 60 { 64 struct ldb_message *msg2, 65 struct ldb_control **req_ctrls) 66 { 67 int ret; 61 68 struct ldb_message *mod; 62 69 63 mod = ldb_msg_diff(ldb, msg1, msg2); 64 if (mod == NULL) { 70 if (ldb_msg_difference(ldb, ldb, msg1, msg2, &mod) != LDB_SUCCESS) { 65 71 fprintf(stderr, "Failed to calculate message differences\n"); 66 72 return -1; 67 73 } 68 74 69 if (mod->num_elements == 0) { 70 return 0; 75 ret = mod->num_elements; 76 if (ret == 0) { 77 goto done; 71 78 } 72 79 … … 75 82 } 76 83 77 if (ldb_modify (ldb, mod) != 0) {78 fprintf(stderr, "failed to modify %s - %s\n", 84 if (ldb_modify_ctrl(ldb, mod, req_ctrls) != LDB_SUCCESS) { 85 fprintf(stderr, "failed to modify %s - %s\n", 79 86 ldb_dn_get_linearized(msg1->dn), ldb_errstring(ldb)); 80 return -1; 81 } 82 83 return mod->num_elements; 87 ret = -1; 88 goto done; 89 } 90 91 done: 92 talloc_free(mod); 93 return ret; 84 94 } 85 95 … … 89 99 static struct ldb_message *msg_find(struct ldb_context *ldb, 90 100 struct ldb_message **msgs, 91 int count,101 unsigned int count, 92 102 struct ldb_dn *dn) 93 103 { 94 int i;104 unsigned int i; 95 105 for (i=0;i<count;i++) { 96 106 if (ldb_dn_compare(dn, msgs[i]->dn) == 0) { … … 105 115 */ 106 116 static int merge_edits(struct ldb_context *ldb, 107 struct ldb_message **msgs1, int count1,108 struct ldb_message **msgs2, int count2)109 { 110 int i;117 struct ldb_message **msgs1, unsigned int count1, 118 struct ldb_message **msgs2, unsigned int count2) 119 { 120 unsigned int i; 111 121 struct ldb_message *msg; 112 int ret = 0; 113 int adds=0, modifies=0, deletes=0; 114 115 if (ldb_transaction_start(ldb) != 0) { 122 int ret; 123 unsigned int adds=0, modifies=0, deletes=0; 124 struct ldb_control **req_ctrls = ldb_parse_control_strings(ldb, ldb, (const char **)options->controls); 125 if (options->controls != NULL && req_ctrls == NULL) { 126 fprintf(stderr, "parsing controls failed: %s\n", ldb_errstring(ldb)); 127 return -1; 128 } 129 130 if (ldb_transaction_start(ldb) != LDB_SUCCESS) { 116 131 fprintf(stderr, "Failed to start transaction: %s\n", ldb_errstring(ldb)); 117 132 return -1; … … 125 140 ldif_write_msg(ldb, stdout, LDB_CHANGETYPE_ADD, msgs2[i]); 126 141 } 127 if (ldb_add (ldb, msgs2[i]) != 0) {142 if (ldb_add_ctrl(ldb, msgs2[i], req_ctrls) != LDB_SUCCESS) { 128 143 fprintf(stderr, "failed to add %s - %s\n", 129 144 ldb_dn_get_linearized(msgs2[i]->dn), … … 134 149 adds++; 135 150 } else { 136 if (modify_record(ldb, msg, msgs2[i]) > 0) { 137 modifies++; 151 ret = modify_record(ldb, msg, msgs2[i], req_ctrls); 152 if (ret != -1) { 153 modifies += (unsigned int) ret; 154 } else { 155 return -1; 138 156 } 139 157 } … … 147 165 ldif_write_msg(ldb, stdout, LDB_CHANGETYPE_DELETE, msgs1[i]); 148 166 } 149 if (ldb_delete (ldb, msgs1[i]->dn) != 0) {167 if (ldb_delete_ctrl(ldb, msgs1[i]->dn, req_ctrls) != LDB_SUCCESS) { 150 168 fprintf(stderr, "failed to delete %s - %s\n", 151 169 ldb_dn_get_linearized(msgs1[i]->dn), … … 158 176 } 159 177 160 if (ldb_transaction_commit(ldb) != 0) {178 if (ldb_transaction_commit(ldb) != LDB_SUCCESS) { 161 179 fprintf(stderr, "Failed to commit transaction: %s\n", ldb_errstring(ldb)); 162 180 return -1; 163 181 } 164 182 165 printf("# % d adds %d modifies %ddeletes\n", adds, modifies, deletes);166 167 return ret;183 printf("# %u adds %u modifies %u deletes\n", adds, modifies, deletes); 184 185 return 0; 168 186 } 169 187 … … 171 189 save a set of messages as ldif to a file 172 190 */ 173 static int save_ldif(struct ldb_context *ldb, 174 FILE *f, struct ldb_message **msgs, int count)175 { 176 int i;177 178 fprintf(f, "# editing % drecords\n", count);191 static int save_ldif(struct ldb_context *ldb, 192 FILE *f, struct ldb_message **msgs, unsigned int count) 193 { 194 unsigned int i; 195 196 fprintf(f, "# editing %u records\n", count); 179 197 180 198 for (i=0;i<count;i++) { 181 199 struct ldb_ldif ldif; 182 fprintf(f, "# record % d\n", i+1);200 fprintf(f, "# record %u\n", i+1); 183 201 184 202 ldif.changetype = LDB_CHANGETYPE_NONE; … … 195 213 edit the ldb search results in msgs using the user selected editor 196 214 */ 197 static int do_edit(struct ldb_context *ldb, struct ldb_message **msgs1, int count1,198 const char *editor)215 static int do_edit(struct ldb_context *ldb, struct ldb_message **msgs1, 216 unsigned int count1, const char *editor) 199 217 { 200 218 int fd, ret; … … 204 222 struct ldb_ldif *ldif; 205 223 struct ldb_message **msgs2 = NULL; 206 int count2 = 0;224 unsigned int count2 = 0; 207 225 208 226 /* write out the original set of messages to a temporary … … 270 288 } 271 289 272 static void usage( void)290 static void usage(struct ldb_context *ldb) 273 291 { 274 292 printf("Usage: ldbedit <options> <expression> <attributes ...>\n"); 275 ldb_cmdline_help( "ldbedit", stdout);276 exit( 1);293 ldb_cmdline_help(ldb, "ldbedit", stdout); 294 exit(LDB_ERR_OPERATIONS_ERROR); 277 295 } 278 296 … … 285 303 const char *expression = "(|(objectClass=*)(distinguishedName=*))"; 286 304 const char * const * attrs = NULL; 287 288 ldb = ldb_init(NULL, NULL); 305 TALLOC_CTX *mem_ctx = talloc_new(NULL); 306 struct ldb_control **req_ctrls; 307 308 ldb = ldb_init(mem_ctx, NULL); 309 if (ldb == NULL) { 310 return LDB_ERR_OPERATIONS_ERROR; 311 } 289 312 290 313 options = ldb_cmdline_process(ldb, argc, argv, usage); 291 314 292 315 /* the check for '=' is for compatibility with ldapsearch */ 293 if (options->argc > 0 && 316 if (options->argc > 0 && 294 317 strchr(options->argv[0], '=')) { 295 318 expression = options->argv[0]; … … 304 327 if (options->basedn != NULL) { 305 328 basedn = ldb_dn_new(ldb, ldb, options->basedn); 306 if ( ! ldb_dn_validate(basedn)) { 307 printf("Invalid Base DN format\n"); 308 exit(1); 309 } 310 } 311 312 ret = ldb_search(ldb, ldb, &result, basedn, options->scope, attrs, "%s", expression); 329 if (basedn == NULL) { 330 return LDB_ERR_OPERATIONS_ERROR; 331 } 332 } 333 334 req_ctrls = ldb_parse_control_strings(ldb, ldb, (const char **)options->controls); 335 if (options->controls != NULL && req_ctrls== NULL) { 336 printf("parsing controls failed: %s\n", ldb_errstring(ldb)); 337 return LDB_ERR_OPERATIONS_ERROR; 338 } 339 340 ret = ldb_search_ctrl(ldb, ldb, &result, basedn, options->scope, attrs, req_ctrls, "%s", expression); 313 341 if (ret != LDB_SUCCESS) { 314 342 printf("search failed - %s\n", ldb_errstring(ldb)); 315 exit(1);343 return ret; 316 344 } 317 345 318 346 if (result->count == 0) { 319 347 printf("no matching records - cannot edit\n"); 320 return 0; 321 } 322 323 do_edit(ldb, result->msgs, result->count, options->editor); 324 325 if (result) { 326 ret = talloc_free(result); 327 if (ret == -1) { 328 fprintf(stderr, "talloc_free failed\n"); 329 exit(1); 330 } 331 } 332 333 talloc_free(ldb); 334 return 0; 335 } 348 talloc_free(mem_ctx); 349 return LDB_SUCCESS; 350 } 351 352 ret = do_edit(ldb, result->msgs, result->count, options->editor); 353 354 talloc_free(mem_ctx); 355 356 return ret == 0 ? LDB_SUCCESS : LDB_ERR_OPERATIONS_ERROR; 357 } -
vendor/current/source4/lib/ldb/tools/ldbmodify.c
r414 r740 34 34 #include "ldb.h" 35 35 #include "tools/cmdline.h" 36 #include "ldbutil.h" 36 37 37 static int failures; 38 static unsigned int failures; 39 static struct ldb_cmdline *options; 38 40 39 static void usage( void)41 static void usage(struct ldb_context *ldb) 40 42 { 41 43 printf("Usage: ldbmodify <options> <ldif...>\n"); 42 44 printf("Modifies a ldb based upon ldif change records\n\n"); 43 ldb_cmdline_help( "ldbmodify", stdout);44 exit( 1);45 ldb_cmdline_help(ldb, "ldbmodify", stdout); 46 exit(LDB_ERR_OPERATIONS_ERROR); 45 47 } 46 48 … … 48 50 process modifies for one file 49 51 */ 50 static int process_file(struct ldb_context *ldb, FILE *f, int *count)52 static int process_file(struct ldb_context *ldb, FILE *f, unsigned int *count) 51 53 { 52 54 struct ldb_ldif *ldif; 53 55 int ret = LDB_SUCCESS; 54 56 struct ldb_control **req_ctrls = ldb_parse_control_strings(ldb, ldb, (const char **)options->controls); 57 58 if (options->controls != NULL && req_ctrls== NULL) { 59 printf("parsing controls failed: %s\n", ldb_errstring(ldb)); 60 exit(LDB_ERR_OPERATIONS_ERROR); 61 } 62 55 63 while ((ldif = ldb_ldif_read_file(ldb, f))) { 56 64 switch (ldif->changetype) { 57 65 case LDB_CHANGETYPE_NONE: 58 66 case LDB_CHANGETYPE_ADD: 59 ret = ldb_add (ldb, ldif->msg);67 ret = ldb_add_ctrl(ldb, ldif->msg,req_ctrls); 60 68 break; 61 69 case LDB_CHANGETYPE_DELETE: 62 ret = ldb_delete (ldb, ldif->msg->dn);70 ret = ldb_delete_ctrl(ldb, ldif->msg->dn,req_ctrls); 63 71 break; 64 72 case LDB_CHANGETYPE_MODIFY: 65 ret = ldb_modify (ldb, ldif->msg);73 ret = ldb_modify_ctrl(ldb, ldif->msg,req_ctrls); 66 74 break; 67 75 } 68 76 if (ret != LDB_SUCCESS) { 69 fprintf(stderr, "ERR: \"%s\" on DN %s\n", 77 fprintf(stderr, "ERR: (%s) \"%s\" on DN %s\n", 78 ldb_strerror(ret), 70 79 ldb_errstring(ldb), ldb_dn_get_linearized(ldif->msg->dn)); 71 80 failures++; 72 81 } else { 73 82 (*count)++; 83 if (options->verbose) { 84 printf("Modified %s\n", ldb_dn_get_linearized(ldif->msg->dn)); 85 } 74 86 } 75 87 ldb_ldif_read_free(ldb, ldif); … … 82 94 { 83 95 struct ldb_context *ldb; 84 int count=0;85 int i, ret=LDB_SUCCESS;86 struct ldb_cmdline *options;96 unsigned int i, count = 0; 97 int ret = LDB_SUCCESS; 98 TALLOC_CTX *mem_ctx = talloc_new(NULL); 87 99 88 ldb = ldb_init(NULL, NULL); 100 ldb = ldb_init(mem_ctx, NULL); 101 if (ldb == NULL) { 102 return LDB_ERR_OPERATIONS_ERROR; 103 } 89 104 90 105 options = ldb_cmdline_process(ldb, argc, argv, usage); … … 99 114 if (!f) { 100 115 perror(fname); 101 exit(1);116 return LDB_ERR_OPERATIONS_ERROR; 102 117 } 103 118 ret = process_file(ldb, f, &count); … … 106 121 } 107 122 108 talloc_free( ldb);123 talloc_free(mem_ctx); 109 124 110 printf("Modified % d records with %dfailures\n", count, failures);125 printf("Modified %u records with %u failures\n", count, failures); 111 126 112 127 return ret; -
vendor/current/source4/lib/ldb/tools/ldbrename.c
r414 r740 37 37 #include "tools/cmdline.h" 38 38 39 static void usage( void)39 static void usage(struct ldb_context *ldb) 40 40 { 41 41 printf("Usage: ldbrename [<options>] <olddn> <newdn>\n"); 42 42 printf("Renames records in a ldb\n\n"); 43 ldb_cmdline_help( "ldbmodify", stdout);44 exit( 1);43 ldb_cmdline_help(ldb, "ldbmodify", stdout); 44 exit(LDB_ERR_OPERATIONS_ERROR); 45 45 } 46 46 … … 52 52 struct ldb_cmdline *options; 53 53 struct ldb_dn *dn1, *dn2; 54 TALLOC_CTX *mem_ctx = talloc_new(NULL); 54 55 55 ldb = ldb_init(NULL, NULL); 56 ldb = ldb_init(mem_ctx, NULL); 57 if (ldb == NULL) { 58 return LDB_ERR_OPERATIONS_ERROR; 59 } 56 60 57 61 options = ldb_cmdline_process(ldb, argc, argv, usage); 58 62 59 63 if (options->argc < 2) { 60 usage( );64 usage(ldb); 61 65 } 62 66 63 67 dn1 = ldb_dn_new(ldb, ldb, options->argv[0]); 64 68 dn2 = ldb_dn_new(ldb, ldb, options->argv[1]); 65 66 if ( ! ldb_dn_validate(dn1)) { 67 printf("Invalid DN1: %s\n", options->argv[0]); 68 return -1; 69 } 70 if ( ! ldb_dn_validate(dn2)) { 71 printf("Invalid DN2: %s\n", options->argv[1]); 72 return -1; 69 if ((dn1 == NULL) || (dn2 == NULL)) { 70 return LDB_ERR_OPERATIONS_ERROR; 73 71 } 74 72 75 73 ret = ldb_rename(ldb, dn1, dn2); 76 if (ret == 0) {74 if (ret == LDB_SUCCESS) { 77 75 printf("Renamed 1 record\n"); 78 76 } else { … … 81 79 } 82 80 83 talloc_free( ldb);81 talloc_free(mem_ctx); 84 82 85 83 return ret; -
vendor/current/source4/lib/ldb/tools/ldbsearch.c
r414 r740 32 32 */ 33 33 34 #include "ldb_includes.h" 34 #include "replace.h" 35 #include "system/filesys.h" 36 #include "system/time.h" 35 37 #include "ldb.h" 36 38 #include "tools/cmdline.h" 37 39 38 static void usage( void)40 static void usage(struct ldb_context *ldb) 39 41 { 40 42 printf("Usage: ldbsearch <options> <expression> <attrs...>\n"); 41 ldb_cmdline_help( "ldbsearch", stdout);42 exit( 1);43 ldb_cmdline_help(ldb, "ldbsearch", stdout); 44 exit(LDB_ERR_OPERATIONS_ERROR); 43 45 } 44 46 … … 55 57 56 58 int sort; 57 int num_stored;59 unsigned int num_stored; 58 60 struct ldb_message **store; 59 int refs_stored;61 unsigned int refs_stored; 60 62 char **refs_store; 61 63 62 int entries;63 int refs;64 65 int pending;64 unsigned int entries; 65 unsigned int refs; 66 67 unsigned int pending; 66 68 int status; 67 69 }; … … 132 134 { 133 135 struct search_context *sctx; 134 int ret ;136 int ret = LDB_SUCCESS; 135 137 136 138 sctx = talloc_get_type(req->context, struct search_context); … … 173 175 174 176 talloc_free(ares); 175 if (ret ) {177 if (ret != LDB_SUCCESS) { 176 178 return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR); 177 179 } … … 192 194 req = NULL; 193 195 194 sctx = talloc (ldb, struct search_context);195 if (!sctx) return -1;196 sctx = talloc_zero(ldb, struct search_context); 197 if (!sctx) return LDB_ERR_OPERATIONS_ERROR; 196 198 197 199 sctx->ldb = ldb; 198 200 sctx->sort = options->sorted; 199 sctx->num_stored = 0;200 sctx->refs_stored = 0;201 sctx->store = NULL;202 201 sctx->req_ctrls = ldb_parse_control_strings(ldb, sctx, (const char **)options->controls); 203 202 if (options->controls != NULL && sctx->req_ctrls== NULL) { 204 203 printf("parsing controls failed: %s\n", ldb_errstring(ldb)); 205 return -1; 206 } 207 sctx->entries = 0; 208 sctx->refs = 0; 204 return LDB_ERR_OPERATIONS_ERROR; 205 } 209 206 210 207 if (basedn == NULL) { … … 225 222 talloc_free(sctx); 226 223 printf("allocating request failed: %s\n", ldb_errstring(ldb)); 227 return -1;224 return ret; 228 225 } 229 226 … … 233 230 if (ret != LDB_SUCCESS) { 234 231 printf("search failed - %s\n", ldb_errstring(ldb)); 235 return -1;232 return ret; 236 233 } 237 234 238 235 ret = ldb_wait(req->handle, LDB_WAIT_ALL); 239 236 if (ret != LDB_SUCCESS) { 240 237 printf("search error - %s\n", ldb_errstring(ldb)); 241 return -1;238 return ret; 242 239 } 243 240 … … 246 243 247 244 if (sctx->sort && (sctx->num_stored != 0 || sctx->refs != 0)) { 248 int i;245 unsigned int i; 249 246 250 247 if (sctx->num_stored) { 251 ldb_qsort(sctx->store, sctx->num_stored, sizeof(struct ldb_message *), 252 ldb, (ldb_qsort_cmp_fn_t)do_compare_msg); 248 LDB_TYPESAFE_QSORT(sctx->store, sctx->num_stored, ldb, do_compare_msg); 253 249 } 254 250 for (i = 0; i < sctx->num_stored; i++) { … … 261 257 } 262 258 263 printf("# returned % d records\n# %d entries\n# %dreferrals\n",259 printf("# returned %u records\n# %u entries\n# %u referrals\n", 264 260 sctx->entries + sctx->refs, sctx->entries, sctx->refs); 265 261 … … 267 263 talloc_free(req); 268 264 269 return 0;265 return LDB_SUCCESS; 270 266 } 271 267 … … 278 274 int ret = -1; 279 275 const char *expression = "(|(objectClass=*)(distinguishedName=*))"; 280 281 ldb = ldb_init(NULL, NULL); 276 TALLOC_CTX *mem_ctx = talloc_new(NULL); 277 278 ldb = ldb_init(mem_ctx, NULL); 282 279 if (ldb == NULL) { 283 return -1;280 return LDB_ERR_OPERATIONS_ERROR; 284 281 } 285 282 … … 301 298 if (options->basedn != NULL) { 302 299 basedn = ldb_dn_new(ldb, ldb, options->basedn); 303 if ( ! ldb_dn_validate(basedn)) { 304 fprintf(stderr, "Invalid Base DN format\n"); 305 exit(1); 300 if (basedn == NULL) { 301 return LDB_ERR_OPERATIONS_ERROR; 306 302 } 307 303 } … … 310 306 char line[1024]; 311 307 while (fgets(line, sizeof(line), stdin)) { 312 if (do_search(ldb, basedn, options, line, attrs) == -1) { 313 ret = -1; 314 } 308 ret = do_search(ldb, basedn, options, line, attrs); 315 309 } 316 310 } else { … … 318 312 } 319 313 320 talloc_free(ldb); 314 talloc_free(mem_ctx); 315 321 316 return ret; 322 317 } -
vendor/current/source4/lib/ldb/tools/ldbtest.c
r414 r740 32 32 */ 33 33 34 #include "ldb_includes.h" 34 #include "replace.h" 35 #include "system/filesys.h" 36 #include "system/time.h" 35 37 #include "ldb.h" 36 38 #include "tools/cmdline.h" 37 39 38 static struct time valtp1,tp2;40 static struct timespec tp1,tp2; 39 41 static struct ldb_cmdline *options; 40 42 41 43 static void _start_timer(void) 42 44 { 43 gettimeofday(&tp1,NULL); 45 if (clock_gettime(CUSTOM_CLOCK_MONOTONIC, &tp1) != 0) { 46 clock_gettime(CLOCK_REALTIME, &tp1); 47 } 44 48 } 45 49 46 50 static double _end_timer(void) 47 51 { 48 gettimeofday(&tp2,NULL); 52 if (clock_gettime(CUSTOM_CLOCK_MONOTONIC, &tp2) != 0) { 53 clock_gettime(CLOCK_REALTIME, &tp2); 54 } 49 55 return((tp2.tv_sec - tp1.tv_sec) + 50 (tp2.tv_ usec - tp1.tv_usec)*1.0e-6);56 (tp2.tv_nsec - tp1.tv_nsec)*1.0e-9); 51 57 } 52 58 53 59 static void add_records(struct ldb_context *ldb, 54 60 struct ldb_dn *basedn, 55 int count)61 unsigned int count) 56 62 { 57 63 struct ldb_message msg; 58 int i;64 unsigned int i; 59 65 60 66 #if 0 61 67 if (ldb_lock(ldb, "transaction") != 0) { 62 68 printf("transaction lock failed\n"); 63 exit( 1);69 exit(LDB_ERR_OPERATIONS_ERROR); 64 70 } 65 71 #endif … … 123 129 if (ldb_add(ldb, &msg) != 0) { 124 130 printf("Add of %s failed - %s\n", name, ldb_errstring(ldb)); 125 exit( 1);131 exit(LDB_ERR_OPERATIONS_ERROR); 126 132 } 127 133 … … 134 140 if (ldb_unlock(ldb, "transaction") != 0) { 135 141 printf("transaction unlock failed\n"); 136 exit( 1);142 exit(LDB_ERR_OPERATIONS_ERROR); 137 143 } 138 144 #endif … … 142 148 static void modify_records(struct ldb_context *ldb, 143 149 struct ldb_dn *basedn, 144 int count)150 unsigned int count) 145 151 { 146 152 struct ldb_message msg; 147 int i;153 unsigned int i; 148 154 149 155 for (i=0;i<count;i++) { … … 180 186 if (ldb_modify(ldb, &msg) != 0) { 181 187 printf("Modify of %s failed - %s\n", name, ldb_errstring(ldb)); 182 exit( 1);188 exit(LDB_ERR_OPERATIONS_ERROR); 183 189 } 184 190 … … 195 201 static void delete_records(struct ldb_context *ldb, 196 202 struct ldb_dn *basedn, 197 int count)198 { 199 int i;203 unsigned int count) 204 { 205 unsigned int i; 200 206 201 207 for (i=0;i<count;i++) { … … 210 216 if (ldb_delete(ldb, dn) != 0) { 211 217 printf("Delete of %s failed - %s\n", ldb_dn_get_linearized(dn), ldb_errstring(ldb)); 212 exit( 1);218 exit(LDB_ERR_OPERATIONS_ERROR); 213 219 } 214 220 talloc_free(name); … … 218 224 } 219 225 220 static void search_uid(struct ldb_context *ldb, struct ldb_dn *basedn, int nrecords, int nsearches) 221 { 222 int i; 226 static void search_uid(struct ldb_context *ldb, struct ldb_dn *basedn, 227 unsigned int nrecords, unsigned int nsearches) 228 { 229 unsigned int i; 223 230 224 231 for (i=0;i<nsearches;i++) { … … 233 240 if (ret != LDB_SUCCESS || (uid < nrecords && res->count != 1)) { 234 241 printf("Failed to find %s - %s\n", expr, ldb_errstring(ldb)); 235 exit( 1);242 exit(LDB_ERR_OPERATIONS_ERROR); 236 243 } 237 244 238 245 if (uid >= nrecords && res->count > 0) { 239 246 printf("Found %s !? - %d\n", expr, ret); 240 exit( 1);247 exit(LDB_ERR_OPERATIONS_ERROR); 241 248 } 242 249 243 printf(" testing uid %d/%d - %d \r", i, uid, res->count);250 printf("Testing uid %d/%d - %d \r", i, uid, res->count); 244 251 fflush(stdout); 245 252 … … 251 258 } 252 259 253 static void start_test(struct ldb_context *ldb, int nrecords, int nsearches) 260 static void start_test(struct ldb_context *ldb, unsigned int nrecords, 261 unsigned int nsearches) 254 262 { 255 263 struct ldb_dn *basedn; … … 257 265 basedn = ldb_dn_new(ldb, ldb, options->basedn); 258 266 if ( ! ldb_dn_validate(basedn)) { 259 printf("Invalid base DN \n");260 exit( 1);267 printf("Invalid base DN format\n"); 268 exit(LDB_ERR_INVALID_DN_SYNTAX); 261 269 } 262 270 … … 323 331 if (ldb_add(*ldb, msg) != 0) { 324 332 printf("Add of %s failed - %s\n", ldb_dn_get_linearized(msg->dn), ldb_errstring(*ldb)); 325 exit( 1);333 exit(LDB_ERR_OPERATIONS_ERROR); 326 334 } 327 335 … … 338 346 if (ldb_add(*ldb, msg) != 0) { 339 347 printf("Add of %s failed - %s\n", ldb_dn_get_linearized(msg->dn), ldb_errstring(*ldb)); 340 exit( 1);348 exit(LDB_ERR_OPERATIONS_ERROR); 341 349 } 342 350 343 351 if (talloc_free(*ldb) != 0) { 344 352 printf("failed to free/close ldb database"); 345 exit( 1);353 exit(LDB_ERR_OPERATIONS_ERROR); 346 354 } 347 355 … … 351 359 if (ret != 0) { 352 360 printf("failed to connect to %s\n", options->url); 353 exit( 1);361 exit(LDB_ERR_OPERATIONS_ERROR); 354 362 } 355 363 356 364 basedn = ldb_dn_new(*ldb, *ldb, options->basedn); 365 msg->dn = basedn; 366 ldb_dn_add_child_fmt(msg->dn, "cn=test"); 357 367 358 368 ret = ldb_search(*ldb, *ldb, &res, basedn, LDB_SCOPE_SUBTREE, NULL, "uid=test"); 359 369 if (ret != LDB_SUCCESS) { 360 370 printf("Search with (uid=test) filter failed!\n"); 361 exit( 1);371 exit(LDB_ERR_OPERATIONS_ERROR); 362 372 } 363 373 if(res->count != 1) { 364 374 printf("Should have found 1 record - found %d\n", res->count); 365 exit( 1);375 exit(LDB_ERR_OPERATIONS_ERROR); 366 376 } 367 377 … … 371 381 ldb_delete(*ldb, indexlist) != 0) { 372 382 printf("cleanup failed - %s\n", ldb_errstring(*ldb)); 373 exit( 1);383 exit(LDB_ERR_OPERATIONS_ERROR); 374 384 } 375 385 … … 378 388 379 389 380 static void usage( void)390 static void usage(struct ldb_context *ldb) 381 391 { 382 392 printf("Usage: ldbtest <options>\n"); … … 387 397 printf("\n"); 388 398 printf("tests ldb API\n\n"); 389 exit( 1);399 exit(LDB_ERR_OPERATIONS_ERROR); 390 400 } 391 401 … … 396 406 397 407 ldb = ldb_init(mem_ctx, NULL); 408 if (ldb == NULL) { 409 return LDB_ERR_OPERATIONS_ERROR; 410 } 398 411 399 412 options = ldb_cmdline_process(ldb, argc, argv, usage); … … 410 423 options->num_records, options->num_searches); 411 424 412 start_test(ldb, options->num_records, options->num_searches); 425 start_test(ldb, 426 (unsigned int) options->num_records, 427 (unsigned int) options->num_searches); 413 428 414 429 start_test_index(&ldb); … … 416 431 talloc_free(mem_ctx); 417 432 418 return 0;419 } 433 return LDB_SUCCESS; 434 } -
vendor/current/source4/lib/ldb/web/index.html
r414 r740 51 51 <h2>Discussion and bug reports</h2> 52 52 53 ldb does not currently have its own mailing list or bug tracking54 system. For now, please use the <a 55 href="https://lists.samba.org/mailman/listinfo/samba-technical">samba-technical</a>56 mailing list or the <a href="https://lists.samba.org/mailman/listinfo/ldb">ldb</a>57 mailing list, and the <a href="http://bugzilla.samba.org/">Sambabugzilla</a> bug tracking system.53 ldb does not have its own mailing list or bug tracking system. Please 54 use 55 the <a href="https://lists.samba.org/mailman/listinfo/samba-technical">samba-technical</a> 56 mailing list, and the <a href="http://bugzilla.samba.org/">Samba 57 bugzilla</a> bug tracking system. 58 58 59 59 <h2>Download</h2> 60 60 61 You can download the latest release either via rsync or thtough git.<br> 62 <br> 63 To fetch via git see the following guide:<br> 61 You can download the latest release here:<br> 62 <a href="http://samba.org/ftp/pub/ldb">http://samba.org/ftp/pub/ldb</a> 63 64 Alternatively, you can fetch via git. See the following guide:<br> 64 65 <a href="http://wiki.samba.org/index.php/Using_Git_for_Samba_Development">Using Git for Samba Development</a><br> 65 Once you have cloned the tree switch to the v4-0-test branch and cd into the source/lib/ldb directory.<br>66 <br>67 To fetch via rsync use these commands:68 69 <pre>70 rsync -Pavz samba.org::ftp/unpacked/ldb .71 rsync -Pavz samba.org::ftp/unpacked/tdb .72 rsync -Pavz samba.org::ftp/unpacked/talloc .73 rsync -Pavz samba.org::ftp/unpacked/libreplace .74 </pre>75 76 and build in ldb. It will find the other libraries in the directory77 above automatically.78 66 79 67 <hr>
Note:
See TracChangeset
for help on using the changeset viewer.