Changeset 745 for trunk/server/source4/lib/ldb/common
- Timestamp:
- Nov 27, 2012, 4:43:17 PM (13 years ago)
- Location:
- trunk/server
- Files:
-
- 12 edited
- 1 copied
Legend:
- Unmodified
- Added
- Removed
-
trunk/server
- Property svn:mergeinfo changed
/vendor/current merged: 581,587,591,594,597,600,615,618,740
- Property svn:mergeinfo changed
-
trunk/server/source4/lib/ldb/common/attrib_handlers.c
r414 r745 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 } -
trunk/server/source4/lib/ldb/common/ldb.c
r414 r745 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 } -
trunk/server/source4/lib/ldb/common/ldb_attributes.c
r414 r745 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) { -
trunk/server/source4/lib/ldb/common/ldb_controls.c
r414 r745 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 -
trunk/server/source4/lib/ldb/common/ldb_dn.c
r414 r745 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 } -
trunk/server/source4/lib/ldb/common/ldb_ldif.c
r414 r745 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 } -
trunk/server/source4/lib/ldb/common/ldb_match.c
r414 r745 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 -
trunk/server/source4/lib/ldb/common/ldb_modules.c
r414 r745 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 } -
trunk/server/source4/lib/ldb/common/ldb_msg.c
r414 r745 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 -
trunk/server/source4/lib/ldb/common/ldb_parse.c
r414 r745 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 -
trunk/server/source4/lib/ldb/common/ldb_utf8.c
r414 r745 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) {
Note:
See TracChangeset
for help on using the changeset viewer.