Line data Source code
1 : /*
2 : ldb database library
3 :
4 : Copyright (C) Stefan Metzmacher <metze@samba.org> 2009
5 :
6 : This program is free software; you can redistribute it and/or modify
7 : it under the terms of the GNU General Public License as published by
8 : the Free Software Foundation; either version 3 of the License, or
9 : (at your option) any later version.
10 :
11 : This program is distributed in the hope that it will be useful,
12 : but WITHOUT ANY WARRANTY; without even the implied warranty of
13 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 : GNU General Public License for more details.
15 :
16 : You should have received a copy of the GNU General Public License
17 : along with this program. If not, see <http://www.gnu.org/licenses/>.
18 : */
19 :
20 : #include "includes.h"
21 : #include "ldb_module.h"
22 : #include "dsdb/samdb/samdb.h"
23 :
24 8272677 : static int resolve_oids_need_value(struct ldb_context *ldb,
25 : struct dsdb_schema *schema,
26 : const struct dsdb_attribute *a,
27 : const struct ldb_val *valp)
28 : {
29 8272677 : const struct dsdb_attribute *va = NULL;
30 8272677 : const struct dsdb_class *vo = NULL;
31 1283268 : const void *p2;
32 8272677 : char *str = NULL;
33 :
34 8272677 : if (a->syntax->oMSyntax != 6) {
35 5487474 : return LDB_ERR_COMPARE_FALSE;
36 : }
37 :
38 1809750 : if (valp) {
39 1809750 : p2 = memchr(valp->data, '.', valp->length);
40 : } else {
41 0 : p2 = NULL;
42 : }
43 :
44 1809750 : if (!p2) {
45 1169080 : return LDB_ERR_COMPARE_FALSE;
46 : }
47 :
48 404729 : switch (a->attributeID_id) {
49 11 : case DRSUAPI_ATTID_objectClass:
50 : case DRSUAPI_ATTID_subClassOf:
51 : case DRSUAPI_ATTID_auxiliaryClass:
52 : case DRSUAPI_ATTID_systemPossSuperiors:
53 : case DRSUAPI_ATTID_possSuperiors:
54 11 : str = talloc_strndup(ldb, (char *)valp->data, valp->length);
55 11 : if (!str) {
56 0 : return ldb_oom(ldb);
57 : }
58 11 : vo = dsdb_class_by_governsID_oid(schema, str);
59 11 : talloc_free(str);
60 11 : if (!vo) {
61 0 : return LDB_ERR_COMPARE_FALSE;
62 : }
63 11 : return LDB_ERR_COMPARE_TRUE;
64 178 : case DRSUAPI_ATTID_systemMustContain:
65 : case DRSUAPI_ATTID_systemMayContain:
66 : case DRSUAPI_ATTID_mustContain:
67 : case DRSUAPI_ATTID_mayContain:
68 178 : str = talloc_strndup(ldb, (char *)valp->data, valp->length);
69 178 : if (!str) {
70 0 : return ldb_oom(ldb);
71 : }
72 178 : va = dsdb_attribute_by_attributeID_oid(schema, str);
73 178 : talloc_free(str);
74 178 : if (!va) {
75 96 : return LDB_ERR_COMPARE_FALSE;
76 : }
77 82 : return LDB_ERR_COMPARE_TRUE;
78 332666 : case DRSUAPI_ATTID_governsID:
79 : case DRSUAPI_ATTID_attributeID:
80 : case DRSUAPI_ATTID_attributeSyntax:
81 332666 : return LDB_ERR_COMPARE_FALSE;
82 : }
83 :
84 0 : return LDB_ERR_COMPARE_FALSE;
85 : }
86 :
87 55924155 : static int resolve_oids_parse_tree_need(struct ldb_context *ldb,
88 : struct dsdb_schema *schema,
89 : const struct ldb_parse_tree *tree)
90 : {
91 3359735 : unsigned int i;
92 55976954 : const struct dsdb_attribute *a = NULL;
93 3359735 : const char *attr;
94 3359735 : const char *p1;
95 3359735 : const void *p2;
96 55976954 : const struct ldb_val *valp = NULL;
97 3359735 : int ret;
98 :
99 55976954 : switch (tree->operation) {
100 16291348 : case LDB_OP_AND:
101 : case LDB_OP_OR:
102 53666340 : for (i=0;i<tree->u.list.num_elements;i++) {
103 38507912 : ret = resolve_oids_parse_tree_need(ldb, schema,
104 36308447 : tree->u.list.elements[i]);
105 36308447 : if (ret != LDB_ERR_COMPARE_FALSE) {
106 0 : return ret;
107 : }
108 : }
109 16291348 : return LDB_ERR_COMPARE_FALSE;
110 1129259 : case LDB_OP_NOT:
111 1129259 : return resolve_oids_parse_tree_need(ldb, schema,
112 1129259 : tree->u.isnot.child);
113 4875579 : case LDB_OP_EQUALITY:
114 4875579 : attr = tree->u.equality.attr;
115 4875579 : valp = &tree->u.equality.value;
116 4875579 : break;
117 6763 : case LDB_OP_GREATER:
118 : case LDB_OP_LESS:
119 : case LDB_OP_APPROX:
120 6763 : attr = tree->u.comparison.attr;
121 6763 : valp = &tree->u.comparison.value;
122 6763 : break;
123 16262 : case LDB_OP_SUBSTRING:
124 16262 : attr = tree->u.substring.attr;
125 16262 : break;
126 29425315 : case LDB_OP_PRESENT:
127 29425315 : attr = tree->u.present.attr;
128 29425315 : break;
129 3165883 : case LDB_OP_EXTENDED:
130 3165883 : attr = tree->u.extended.attr;
131 3165883 : valp = &tree->u.extended.value;
132 3165883 : break;
133 0 : default:
134 0 : return LDB_ERR_COMPARE_FALSE;
135 : }
136 :
137 37489802 : p1 = strchr(attr, '.');
138 :
139 37489802 : if (valp) {
140 8048225 : p2 = memchr(valp->data, '.', valp->length);
141 : } else {
142 27508793 : p2 = NULL;
143 : }
144 :
145 37489802 : if (!p1 && !p2) {
146 34713763 : return LDB_ERR_COMPARE_FALSE;
147 : }
148 :
149 559318 : if (p1) {
150 11 : a = dsdb_attribute_by_attributeID_oid(schema, attr);
151 : } else {
152 559307 : a = dsdb_attribute_by_lDAPDisplayName(schema, attr);
153 : }
154 559318 : if (!a) {
155 2298 : return LDB_ERR_COMPARE_FALSE;
156 : }
157 :
158 557020 : if (!p2) {
159 0 : return LDB_ERR_COMPARE_FALSE;
160 : }
161 :
162 557020 : return resolve_oids_need_value(ldb, schema, a, valp);
163 : }
164 :
165 5469929 : static int resolve_oids_element_need(struct ldb_context *ldb,
166 : struct dsdb_schema *schema,
167 : const struct ldb_message_element *el)
168 : {
169 873090 : unsigned int i;
170 5469929 : const struct dsdb_attribute *a = NULL;
171 873090 : const char *p1;
172 :
173 5469929 : p1 = strchr(el->name, '.');
174 :
175 5469929 : if (p1) {
176 0 : a = dsdb_attribute_by_attributeID_oid(schema, el->name);
177 : } else {
178 5469929 : a = dsdb_attribute_by_lDAPDisplayName(schema, el->name);
179 : }
180 5469929 : if (!a) {
181 3063 : return LDB_ERR_COMPARE_FALSE;
182 : }
183 :
184 13182274 : for (i=0; i < el->num_values; i++) {
185 1259598 : int ret;
186 8975255 : ret = resolve_oids_need_value(ldb, schema, a,
187 7715657 : &el->values[i]);
188 7715657 : if (ret != LDB_ERR_COMPARE_FALSE) {
189 82 : return ret;
190 : }
191 : }
192 :
193 4593694 : return LDB_ERR_COMPARE_FALSE;
194 : }
195 :
196 864620 : static int resolve_oids_message_need(struct ldb_context *ldb,
197 : struct dsdb_schema *schema,
198 : const struct ldb_message *msg)
199 : {
200 100754 : unsigned int i;
201 :
202 6334467 : for (i=0; i < msg->num_elements; i++) {
203 873090 : int ret;
204 6343019 : ret = resolve_oids_element_need(ldb, schema,
205 5469929 : &msg->elements[i]);
206 5469929 : if (ret != LDB_ERR_COMPARE_FALSE) {
207 82 : return ret;
208 : }
209 : }
210 :
211 763784 : return LDB_ERR_COMPARE_FALSE;
212 : }
213 :
214 1109 : static int resolve_oids_replace_value(struct ldb_context *ldb,
215 : struct dsdb_schema *schema,
216 : const struct dsdb_attribute *a,
217 : struct ldb_val *valp)
218 : {
219 1109 : const struct dsdb_attribute *va = NULL;
220 1109 : const struct dsdb_class *vo = NULL;
221 0 : const void *p2;
222 1109 : char *str = NULL;
223 :
224 1109 : if (a->syntax->oMSyntax != 6) {
225 486 : return LDB_SUCCESS;
226 : }
227 :
228 623 : if (valp) {
229 623 : p2 = memchr(valp->data, '.', valp->length);
230 : } else {
231 0 : p2 = NULL;
232 : }
233 :
234 623 : if (!p2) {
235 318 : return LDB_SUCCESS;
236 : }
237 :
238 305 : switch (a->attributeID_id) {
239 11 : case DRSUAPI_ATTID_objectClass:
240 : case DRSUAPI_ATTID_subClassOf:
241 : case DRSUAPI_ATTID_auxiliaryClass:
242 : case DRSUAPI_ATTID_systemPossSuperiors:
243 : case DRSUAPI_ATTID_possSuperiors:
244 11 : str = talloc_strndup(schema, (char *)valp->data, valp->length);
245 11 : if (!str) {
246 0 : return ldb_oom(ldb);
247 : }
248 11 : vo = dsdb_class_by_governsID_oid(schema, str);
249 11 : talloc_free(str);
250 11 : if (!vo) {
251 0 : return LDB_SUCCESS;
252 : }
253 11 : *valp = data_blob_string_const(vo->lDAPDisplayName);
254 11 : return LDB_SUCCESS;
255 250 : case DRSUAPI_ATTID_systemMustContain:
256 : case DRSUAPI_ATTID_systemMayContain:
257 : case DRSUAPI_ATTID_mustContain:
258 : case DRSUAPI_ATTID_mayContain:
259 250 : str = talloc_strndup(schema, (char *)valp->data, valp->length);
260 250 : if (!str) {
261 0 : return ldb_oom(ldb);
262 : }
263 250 : va = dsdb_attribute_by_attributeID_oid(schema, str);
264 250 : talloc_free(str);
265 250 : if (!va) {
266 0 : return LDB_SUCCESS;
267 : }
268 250 : *valp = data_blob_string_const(va->lDAPDisplayName);
269 250 : return LDB_SUCCESS;
270 44 : case DRSUAPI_ATTID_governsID:
271 : case DRSUAPI_ATTID_attributeID:
272 : case DRSUAPI_ATTID_attributeSyntax:
273 44 : return LDB_SUCCESS;
274 : }
275 :
276 0 : return LDB_SUCCESS;
277 : }
278 :
279 11 : static int resolve_oids_parse_tree_replace(struct ldb_context *ldb,
280 : struct dsdb_schema *schema,
281 : struct ldb_parse_tree *tree)
282 : {
283 0 : unsigned int i;
284 11 : const struct dsdb_attribute *a = NULL;
285 0 : const char **attrp;
286 0 : const char *p1;
287 0 : const void *p2;
288 11 : struct ldb_val *valp = NULL;
289 0 : int ret;
290 :
291 11 : switch (tree->operation) {
292 0 : case LDB_OP_AND:
293 : case LDB_OP_OR:
294 0 : for (i=0;i<tree->u.list.num_elements;i++) {
295 0 : ret = resolve_oids_parse_tree_replace(ldb, schema,
296 0 : tree->u.list.elements[i]);
297 0 : if (ret != LDB_SUCCESS) {
298 0 : return ret;
299 : }
300 : }
301 0 : return LDB_SUCCESS;
302 0 : case LDB_OP_NOT:
303 0 : return resolve_oids_parse_tree_replace(ldb, schema,
304 : tree->u.isnot.child);
305 11 : case LDB_OP_EQUALITY:
306 11 : attrp = &tree->u.equality.attr;
307 11 : valp = &tree->u.equality.value;
308 11 : break;
309 0 : case LDB_OP_GREATER:
310 : case LDB_OP_LESS:
311 : case LDB_OP_APPROX:
312 0 : attrp = &tree->u.comparison.attr;
313 0 : valp = &tree->u.comparison.value;
314 0 : break;
315 0 : case LDB_OP_SUBSTRING:
316 0 : attrp = &tree->u.substring.attr;
317 0 : break;
318 0 : case LDB_OP_PRESENT:
319 0 : attrp = &tree->u.present.attr;
320 0 : break;
321 0 : case LDB_OP_EXTENDED:
322 0 : attrp = &tree->u.extended.attr;
323 0 : valp = &tree->u.extended.value;
324 0 : break;
325 0 : default:
326 0 : return LDB_SUCCESS;
327 : }
328 :
329 11 : p1 = strchr(*attrp, '.');
330 :
331 11 : if (valp) {
332 11 : p2 = memchr(valp->data, '.', valp->length);
333 : } else {
334 0 : p2 = NULL;
335 : }
336 :
337 11 : if (!p1 && !p2) {
338 0 : return LDB_SUCCESS;
339 : }
340 :
341 11 : if (p1) {
342 11 : a = dsdb_attribute_by_attributeID_oid(schema, *attrp);
343 : } else {
344 0 : a = dsdb_attribute_by_lDAPDisplayName(schema, *attrp);
345 : }
346 11 : if (!a) {
347 0 : return LDB_SUCCESS;
348 : }
349 :
350 11 : *attrp = a->lDAPDisplayName;
351 :
352 11 : if (!p2) {
353 0 : return LDB_SUCCESS;
354 : }
355 :
356 11 : if (a->syntax->oMSyntax != 6) {
357 0 : return LDB_SUCCESS;
358 : }
359 :
360 11 : return resolve_oids_replace_value(ldb, schema, a, valp);
361 : }
362 :
363 816 : static int resolve_oids_element_replace(struct ldb_context *ldb,
364 : struct dsdb_schema *schema,
365 : struct ldb_message_element *el)
366 : {
367 0 : unsigned int i;
368 816 : const struct dsdb_attribute *a = NULL;
369 0 : const char *p1;
370 :
371 816 : p1 = strchr(el->name, '.');
372 :
373 816 : if (p1) {
374 0 : a = dsdb_attribute_by_attributeID_oid(schema, el->name);
375 : } else {
376 816 : a = dsdb_attribute_by_lDAPDisplayName(schema, el->name);
377 : }
378 816 : if (!a) {
379 0 : return LDB_SUCCESS;
380 : }
381 :
382 816 : el->name = a->lDAPDisplayName;
383 :
384 1914 : for (i=0; i < el->num_values; i++) {
385 0 : int ret;
386 1098 : ret = resolve_oids_replace_value(ldb, schema, a,
387 1098 : &el->values[i]);
388 1098 : if (ret != LDB_SUCCESS) {
389 0 : return ret;
390 : }
391 : }
392 :
393 816 : return LDB_SUCCESS;
394 : }
395 :
396 82 : static int resolve_oids_message_replace(struct ldb_context *ldb,
397 : struct dsdb_schema *schema,
398 : struct ldb_message *msg)
399 : {
400 0 : unsigned int i;
401 :
402 898 : for (i=0; i < msg->num_elements; i++) {
403 0 : int ret;
404 816 : ret = resolve_oids_element_replace(ldb, schema,
405 816 : &msg->elements[i]);
406 816 : if (ret != LDB_SUCCESS) {
407 0 : return ret;
408 : }
409 : }
410 :
411 82 : return LDB_SUCCESS;
412 : }
413 :
414 : struct resolve_oids_context {
415 : struct ldb_module *module;
416 : struct ldb_request *req;
417 : };
418 :
419 266 : static int resolve_oids_callback(struct ldb_request *req, struct ldb_reply *ares)
420 : {
421 0 : struct resolve_oids_context *ac;
422 :
423 266 : ac = talloc_get_type_abort(req->context, struct resolve_oids_context);
424 :
425 266 : if (!ares) {
426 0 : return ldb_module_done(ac->req, NULL, NULL,
427 : LDB_ERR_OPERATIONS_ERROR);
428 : }
429 266 : if (ares->error != LDB_SUCCESS) {
430 16 : return ldb_module_done(ac->req, ares->controls,
431 : ares->response, ares->error);
432 : }
433 :
434 250 : switch (ares->type) {
435 132 : case LDB_REPLY_ENTRY:
436 132 : return ldb_module_send_entry(ac->req, ares->message, ares->controls);
437 :
438 33 : case LDB_REPLY_REFERRAL:
439 33 : return ldb_module_send_referral(ac->req, ares->referral);
440 :
441 85 : case LDB_REPLY_DONE:
442 85 : return ldb_module_done(ac->req, ares->controls,
443 : ares->response, LDB_SUCCESS);
444 :
445 : }
446 0 : return LDB_SUCCESS;
447 : }
448 :
449 18641380 : static int resolve_oids_search(struct ldb_module *module, struct ldb_request *req)
450 : {
451 1109266 : struct ldb_context *ldb;
452 1109266 : struct dsdb_schema *schema;
453 1109266 : struct ldb_parse_tree *tree;
454 1109266 : struct ldb_request *down_req;
455 1109266 : struct resolve_oids_context *ac;
456 1109266 : int ret;
457 18641380 : bool needed = false;
458 1109266 : const char * const *attrs1;
459 1109266 : const char **attrs2;
460 1109266 : unsigned int i;
461 :
462 18641380 : ldb = ldb_module_get_ctx(module);
463 18641380 : schema = dsdb_get_schema(ldb, NULL);
464 :
465 18641380 : if (!schema) {
466 25780 : return ldb_next_request(module, req);
467 : }
468 :
469 : /* do not manipulate our control entries */
470 18615600 : if (ldb_dn_is_special(req->op.search.base)) {
471 76352 : return ldb_next_request(module, req);
472 : }
473 :
474 19646719 : ret = resolve_oids_parse_tree_need(ldb, schema,
475 18539248 : req->op.search.tree);
476 18539248 : if (ret == LDB_ERR_COMPARE_TRUE) {
477 11 : needed = true;
478 18539237 : } else if (ret != LDB_ERR_COMPARE_FALSE) {
479 0 : return ret;
480 : }
481 :
482 18539248 : attrs1 = req->op.search.attrs;
483 :
484 61908510 : for (i=0; attrs1 && attrs1[i]; i++) {
485 1339578 : const char *p;
486 1339578 : const struct dsdb_attribute *a;
487 :
488 43369262 : p = strchr(attrs1[i], '.');
489 43369262 : if (p == NULL) {
490 43369240 : continue;
491 : }
492 :
493 22 : a = dsdb_attribute_by_attributeID_oid(schema, attrs1[i]);
494 22 : if (a == NULL) {
495 22 : continue;
496 : }
497 :
498 0 : needed = true;
499 0 : break;
500 : }
501 :
502 18539248 : if (!needed) {
503 18539237 : return ldb_next_request(module, req);
504 : }
505 :
506 11 : ac = talloc(req, struct resolve_oids_context);
507 11 : if (ac == NULL) {
508 0 : return ldb_oom(ldb);
509 : }
510 11 : ac->module = module;
511 11 : ac->req = req;
512 :
513 11 : tree = ldb_parse_tree_copy_shallow(ac, req->op.search.tree);
514 11 : if (!tree) {
515 0 : return ldb_oom(ldb);
516 : }
517 :
518 11 : schema = talloc_reference(tree, schema);
519 11 : if (!schema) {
520 0 : return ldb_oom(ldb);
521 : }
522 :
523 11 : ret = resolve_oids_parse_tree_replace(ldb, schema,
524 : tree);
525 11 : if (ret != LDB_SUCCESS) {
526 0 : return ret;
527 : }
528 :
529 11 : attrs2 = str_list_copy_const(ac,
530 11 : discard_const_p(const char *, req->op.search.attrs));
531 11 : if (req->op.search.attrs && !attrs2) {
532 0 : return ldb_oom(ldb);
533 : }
534 :
535 22 : for (i=0; attrs2 && attrs2[i]; i++) {
536 0 : const char *p;
537 0 : const struct dsdb_attribute *a;
538 :
539 11 : p = strchr(attrs2[i], '.');
540 11 : if (p == NULL) {
541 11 : continue;
542 : }
543 :
544 0 : a = dsdb_attribute_by_attributeID_oid(schema, attrs2[i]);
545 0 : if (a == NULL) {
546 0 : continue;
547 : }
548 :
549 0 : attrs2[i] = a->lDAPDisplayName;
550 : }
551 :
552 11 : ret = ldb_build_search_req_ex(&down_req, ldb, ac,
553 : req->op.search.base,
554 : req->op.search.scope,
555 : tree,
556 : attrs2,
557 : req->controls,
558 : ac, resolve_oids_callback,
559 : req);
560 11 : LDB_REQ_SET_LOCATION(down_req);
561 11 : if (ret != LDB_SUCCESS) {
562 0 : return ret;
563 : }
564 :
565 : /* go on with the call chain */
566 11 : return ldb_next_request(module, down_req);
567 : }
568 :
569 543720 : static int resolve_oids_add(struct ldb_module *module, struct ldb_request *req)
570 : {
571 83679 : struct ldb_context *ldb;
572 83679 : struct dsdb_schema *schema;
573 83679 : int ret;
574 83679 : struct ldb_message *msg;
575 83679 : struct ldb_request *down_req;
576 83679 : struct resolve_oids_context *ac;
577 :
578 543720 : ldb = ldb_module_get_ctx(module);
579 543720 : schema = dsdb_get_schema(ldb, NULL);
580 :
581 543720 : if (!schema) {
582 0 : return ldb_next_request(module, req);
583 : }
584 :
585 : /* do not manipulate our control entries */
586 543720 : if (ldb_dn_is_special(req->op.add.message->dn)) {
587 538 : return ldb_next_request(module, req);
588 : }
589 :
590 543182 : ret = resolve_oids_message_need(ldb, schema,
591 : req->op.add.message);
592 543182 : if (ret == LDB_ERR_COMPARE_FALSE) {
593 543138 : return ldb_next_request(module, req);
594 44 : } else if (ret != LDB_ERR_COMPARE_TRUE) {
595 0 : return ret;
596 : }
597 :
598 44 : ac = talloc(req, struct resolve_oids_context);
599 44 : if (ac == NULL) {
600 0 : return ldb_oom(ldb);
601 : }
602 44 : ac->module = module;
603 44 : ac->req = req;
604 :
605 44 : msg = ldb_msg_copy_shallow(ac, ac->req->op.add.message);
606 44 : if (!msg) {
607 0 : return ldb_oom(ldb);
608 : }
609 :
610 44 : if (!talloc_reference(msg, schema)) {
611 0 : return ldb_oom(ldb);
612 : }
613 :
614 44 : ret = resolve_oids_message_replace(ldb, schema, msg);
615 44 : if (ret != LDB_SUCCESS) {
616 0 : return ret;
617 : }
618 :
619 44 : ret = ldb_build_add_req(&down_req, ldb, ac,
620 : msg,
621 : req->controls,
622 : ac, resolve_oids_callback,
623 : req);
624 44 : LDB_REQ_SET_LOCATION(down_req);
625 44 : if (ret != LDB_SUCCESS) {
626 0 : return ret;
627 : }
628 :
629 : /* go on with the call chain */
630 44 : return ldb_next_request(module, down_req);
631 : }
632 :
633 322153 : static int resolve_oids_modify(struct ldb_module *module, struct ldb_request *req)
634 : {
635 17201 : struct ldb_context *ldb;
636 17201 : struct dsdb_schema *schema;
637 17201 : int ret;
638 17201 : struct ldb_message *msg;
639 17201 : struct ldb_request *down_req;
640 17201 : struct resolve_oids_context *ac;
641 :
642 322153 : ldb = ldb_module_get_ctx(module);
643 322153 : schema = dsdb_get_schema(ldb, NULL);
644 :
645 322153 : if (!schema) {
646 0 : return ldb_next_request(module, req);
647 : }
648 :
649 : /* do not manipulate our control entries */
650 322153 : if (ldb_dn_is_special(req->op.mod.message->dn)) {
651 715 : return ldb_next_request(module, req);
652 : }
653 :
654 321438 : ret = resolve_oids_message_need(ldb, schema,
655 : req->op.mod.message);
656 321438 : if (ret == LDB_ERR_COMPARE_FALSE) {
657 321400 : return ldb_next_request(module, req);
658 38 : } else if (ret != LDB_ERR_COMPARE_TRUE) {
659 0 : return ret;
660 : }
661 :
662 38 : ac = talloc(req, struct resolve_oids_context);
663 38 : if (ac == NULL) {
664 0 : return ldb_oom(ldb);
665 : }
666 38 : ac->module = module;
667 38 : ac->req = req;
668 :
669 : /* we have to copy the message as the caller might have it as a const */
670 38 : msg = ldb_msg_copy_shallow(ac, req->op.mod.message);
671 38 : if (msg == NULL) {
672 0 : return ldb_oom(ldb);
673 : }
674 :
675 38 : if (!talloc_reference(msg, schema)) {
676 0 : return ldb_oom(ldb);
677 : }
678 :
679 38 : ret = resolve_oids_message_replace(ldb, schema, msg);
680 38 : if (ret != LDB_SUCCESS) {
681 0 : return ret;
682 : }
683 :
684 38 : ret = ldb_build_mod_req(&down_req, ldb, ac,
685 : msg,
686 : req->controls,
687 : ac, resolve_oids_callback,
688 : req);
689 38 : LDB_REQ_SET_LOCATION(down_req);
690 38 : if (ret != LDB_SUCCESS) {
691 0 : return ret;
692 : }
693 :
694 : /* go on with the call chain */
695 38 : return ldb_next_request(module, down_req);
696 : }
697 :
698 : static const struct ldb_module_ops ldb_resolve_oids_module_ops = {
699 : .name = "resolve_oids",
700 : .search = resolve_oids_search,
701 : .add = resolve_oids_add,
702 : .modify = resolve_oids_modify,
703 : };
704 :
705 :
706 6040 : int ldb_resolve_oids_module_init(const char *version)
707 : {
708 6040 : LDB_MODULE_CHECK_VERSION(version);
709 6040 : return ldb_register_module(&ldb_resolve_oids_module_ops);
710 : }
|